X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ircd%2Fclient.c;h=e978f77fbaa417c3df17223e6a4687263c4e4558;hb=79035436c61e2b58004b47f250ab1e54744a88d6;hp=4f416fb184f975db9aab1c689f242ae25ddaa8ab;hpb=3f41f9d9261ceca571ecdf3f8f075c94b21281de;p=ircu2.10.12-pk.git diff --git a/ircd/client.c b/ircd/client.c index 4f416fb..e978f77 100644 --- a/ircd/client.c +++ b/ircd/client.c @@ -49,6 +49,8 @@ int client_get_ping(const struct Client* acptr) struct ConfItem* aconf; struct SLink* link; + assert(cli_verify(acptr)); + for (link = cli_confs(acptr); link; link = link->next) { aconf = link->value.aconf; if (aconf->status & (CONF_CLIENT | CONF_SERVER)) { @@ -61,9 +63,29 @@ int client_get_ping(const struct Client* acptr) ping = feature_int(FEAT_PINGFREQUENCY); Debug((DEBUG_DEBUG, "Client %s Ping %d", cli_name(acptr), ping)); + return ping; } +/* + * client_get_default_umode + * returns default usermode in attached client connection class + */ +const char* client_get_default_umode(const struct Client* sptr) +{ + struct ConfItem* aconf; + struct SLink* link; + + assert(cli_verify(sptr)); + + for (link = cli_confs(sptr); link; link = link->next) { + aconf = link->value.aconf; + if ((aconf->status & CONF_CLIENT) && ConfUmode(aconf)) + return ConfUmode(aconf); + } + return NULL; +} + /* * client_drop_sendq * removes the client's connection from the list of connections with @@ -98,118 +120,97 @@ void client_add_sendq(struct Connection* con, struct Connection** con_p) } } -static struct { - unsigned int priv; - enum Feature feat; - unsigned int flag; -} feattab[] = { - { PRIV_WHOX, FEAT_LAST_F, (FLAGS_OPER | FLAGS_LOCOP) }, - { PRIV_DISPLAY, FEAT_LAST_F, (FLAGS_OPER | FLAGS_LOCOP) }, - { PRIV_CHAN_LIMIT, FEAT_OPER_NO_CHAN_LIMIT, (FLAGS_OPER | FLAGS_LOCOP) }, - { PRIV_MODE_LCHAN, FEAT_OPER_MODE_LCHAN, (FLAGS_OPER | FLAGS_LOCOP) }, - { PRIV_LOCAL_OPMODE, FEAT_OPER_MODE_LCHAN, (FLAGS_OPER | FLAGS_LOCOP) }, - { PRIV_WALK_LCHAN, FEAT_OPER_WALK_THROUGH_LMODES, - (FLAGS_OPER | FLAGS_LOCOP) }, - { PRIV_DEOP_LCHAN, FEAT_NO_OPER_DEOP_LCHAN, (FLAGS_OPER | FLAGS_LOCOP) }, - { PRIV_SHOW_INVIS, FEAT_SHOW_INVISIBLE_USERS, (FLAGS_OPER | FLAGS_LOCOP) }, - { PRIV_SHOW_ALL_INVIS, FEAT_SHOW_ALL_INVISIBLE_USERS, - (FLAGS_OPER | FLAGS_LOCOP) }, - { PRIV_UNLIMIT_QUERY, FEAT_UNLIMIT_OPER_QUERY, (FLAGS_OPER | FLAGS_LOCOP) }, - - { PRIV_KILL, FEAT_LOCAL_KILL_ONLY, 0 }, - { PRIV_GLINE, FEAT_CONFIG_OPERCMDS, ~0 }, - { PRIV_JUPE, FEAT_CONFIG_OPERCMDS, ~0 }, - { PRIV_OPMODE, FEAT_CONFIG_OPERCMDS, ~0 }, - { PRIV_BADCHAN, FEAT_CONFIG_OPERCMDS, ~0 }, - - { PRIV_PROPAGATE, FEAT_LAST_F, FLAGS_OPER }, - { PRIV_SEE_OPERS, FEAT_LAST_F, FLAGS_OPER }, - { PRIV_KILL, FEAT_OPER_KILL, FLAGS_OPER }, - { PRIV_LOCAL_KILL, FEAT_OPER_KILL, FLAGS_OPER }, - { PRIV_REHASH, FEAT_OPER_REHASH, FLAGS_OPER }, - { PRIV_RESTART, FEAT_OPER_RESTART, FLAGS_OPER }, - { PRIV_DIE, FEAT_OPER_DIE, FLAGS_OPER }, - { PRIV_GLINE, FEAT_OPER_GLINE, FLAGS_OPER }, - { PRIV_LOCAL_GLINE, FEAT_OPER_LGLINE, FLAGS_OPER }, - { PRIV_JUPE, FEAT_OPER_JUPE, FLAGS_OPER }, - { PRIV_LOCAL_JUPE, FEAT_OPER_LJUPE, FLAGS_OPER }, - { PRIV_OPMODE, FEAT_OPER_OPMODE, FLAGS_OPER }, - { PRIV_LOCAL_OPMODE, FEAT_OPER_LOPMODE, FLAGS_OPER }, - { PRIV_BADCHAN, FEAT_OPER_BADCHAN, FLAGS_OPER }, - { PRIV_LOCAL_BADCHAN, FEAT_OPER_LBADCHAN, FLAGS_OPER }, - { PRIV_SET, FEAT_OPER_SET, FLAGS_OPER }, - { PRIV_SEE_CHAN, FEAT_OPERS_SEE_IN_SECRET_CHANNELS, FLAGS_OPER }, - { PRIV_WIDE_GLINE, FEAT_OPER_WIDE_GLINE, FLAGS_OPER }, - - { PRIV_LOCAL_KILL, FEAT_LOCOP_KILL, FLAGS_LOCOP }, - { PRIV_REHASH, FEAT_LOCOP_REHASH, FLAGS_LOCOP }, - { PRIV_RESTART, FEAT_LOCOP_RESTART, FLAGS_LOCOP }, - { PRIV_DIE, FEAT_LOCOP_DIE, FLAGS_LOCOP }, - { PRIV_LOCAL_GLINE, FEAT_LOCOP_LGLINE, FLAGS_LOCOP }, - { PRIV_LOCAL_JUPE, FEAT_LOCOP_LJUPE, FLAGS_LOCOP }, - { PRIV_LOCAL_OPMODE, FEAT_LOCOP_LOPMODE, FLAGS_LOCOP }, - { PRIV_LOCAL_BADCHAN, FEAT_LOCOP_LBADCHAN, FLAGS_LOCOP }, - { PRIV_SET, FEAT_LOCOP_SET, FLAGS_LOCOP }, - { PRIV_SEE_CHAN, FEAT_LOCOP_SEE_IN_SECRET_CHANNELS, FLAGS_LOCOP }, - { PRIV_WIDE_GLINE, FEAT_LOCOP_WIDE_GLINE, FLAGS_LOCOP }, - { 0, FEAT_LAST_F, 0 } -}; +static struct Privs privs_global; +static struct Privs privs_local; +static int privs_defaults_set; /* client_set_privs(struct Client* client) * * Sets the privileges for opers. */ void -client_set_privs(struct Client* client) +client_set_privs(struct Client *client, struct ConfItem *oper) { - struct Privs privs; - struct Privs antiprivs; - int i; - - memset(&privs, 0, sizeof(struct Privs)); - memset(&antiprivs, 0, sizeof(struct Privs)); + struct Privs *source, *defaults; + enum Priv priv; + + if (!privs_defaults_set) + { + memset(&privs_global, -1, sizeof(privs_global)); + memset(&privs_local, 0, sizeof(privs_local)); + PrivSet(&privs_local, PRIV_CHAN_LIMIT); + PrivSet(&privs_local, PRIV_MODE_LCHAN); + PrivSet(&privs_local, PRIV_SHOW_INVIS); + PrivSet(&privs_local, PRIV_SHOW_ALL_INVIS); + PrivSet(&privs_local, PRIV_LOCAL_KILL); + PrivSet(&privs_local, PRIV_REHASH); + PrivSet(&privs_local, PRIV_LOCAL_GLINE); + PrivSet(&privs_local, PRIV_LOCAL_JUPE); + PrivSet(&privs_local, PRIV_LOCAL_OPMODE); + PrivSet(&privs_local, PRIV_WHOX); + PrivSet(&privs_local, PRIV_DISPLAY); + PrivSet(&privs_local, PRIV_FORCE_LOCAL_OPMODE); + privs_defaults_set = 1; + } + memset(&(cli_privs(client)), 0, sizeof(struct Privs)); - if (!IsAnOper(client)) { /* clear privilege mask */ - memset(&(cli_privs(client)), 0, sizeof(struct Privs)); + if (!IsAnOper(client)) return; - } else if (!MyConnect(client)) { + else if (!MyConnect(client)) + { memset(&(cli_privs(client)), 255, sizeof(struct Privs)); PrivClr(&(cli_privs(client)), PRIV_SET); return; } + else if (oper == NULL) + return; - /* This sequence is temporary until the .conf is carefully rewritten */ - - for (i = 0; feattab[i].priv; i++) { - if (feattab[i].flag == 0) { - if (feature_bool(feattab[i].feat)) - PrivSet(&antiprivs, feattab[i].priv); - } else if (feattab[i].flag == ~0) { - if (!feature_bool(feattab[i].feat)) - PrivSet(&antiprivs, feattab[i].priv); - } else if (cli_flags(client) & feattab[i].flag) { - if (feattab[i].feat == FEAT_LAST_F || - feature_bool(feattab[i].feat)) - PrivSet(&privs, feattab[i].priv); - } - } - - /* This is the end of the gross section */ + /* Clear out client's privileges. */ + memset(&cli_privs(client), 0, sizeof(struct Privs)); - if (PrivHas(&privs, PRIV_PROPAGATE)) - PrivSet(&privs, PRIV_DISPLAY); /* force propagating opers to display */ - else { /* if they don't propagate oper status, prevent desyncs */ - PrivSet(&antiprivs, PRIV_KILL); - PrivSet(&antiprivs, PRIV_GLINE); - PrivSet(&antiprivs, PRIV_JUPE); - PrivSet(&antiprivs, PRIV_OPMODE); - PrivSet(&antiprivs, PRIV_BADCHAN); + /* Decide whether to use global or local oper defaults. */ + if (PrivHas(&oper->privs_dirty, PRIV_PROPAGATE)) + defaults = PrivHas(&oper->privs, PRIV_PROPAGATE) ? &privs_global : &privs_local; + else if (PrivHas(&oper->conn_class->privs_dirty, PRIV_PROPAGATE)) + defaults = PrivHas(&oper->conn_class->privs, PRIV_PROPAGATE) ? &privs_global : &privs_local; + else { + assert(0 && "Oper has no propagation and neither does connection class"); + return; } - for (i = 0; i <= _PRIV_IDX(PRIV_LAST_PRIV); i++) - privs.priv_mask[i] &= ~antiprivs.priv_mask[i]; + /* For each feature, figure out whether it comes from the operator + * conf, the connection class conf, or the defaults, then apply it. + */ + for (priv = 0; priv < PRIV_LAST_PRIV; ++priv) + { + /* Figure out most applicable definition for the privilege. */ + if (PrivHas(&oper->privs_dirty, priv)) + source = &oper->privs; + else if (PrivHas(&oper->conn_class->privs_dirty, priv)) + source = &oper->conn_class->privs; + else + source = defaults; + + /* Set it if necessary (privileges were already cleared). */ + if (PrivHas(source, priv)) + PrivSet(&cli_privs(client), priv); + } - cli_privs(client) = privs; + /* This should be handled in the config, but lets be sure... */ + if (PrivHas(&cli_privs(client), PRIV_PROPAGATE)) + { + /* force propagating opers to display */ + PrivSet(&cli_privs(client), PRIV_DISPLAY); + } + else + { + /* if they don't propagate oper status, prevent desyncs */ + PrivClr(&cli_privs(client), PRIV_KILL); + PrivClr(&cli_privs(client), PRIV_GLINE); + PrivClr(&cli_privs(client), PRIV_JUPE); + PrivClr(&cli_privs(client), PRIV_OPMODE); + PrivClr(&cli_privs(client), PRIV_BADCHAN); + } } static struct { @@ -223,7 +224,8 @@ static struct { P(GLINE), P(LOCAL_GLINE), P(JUPE), P(LOCAL_JUPE), P(OPMODE), P(LOCAL_OPMODE), P(SET), P(WHOX), P(BADCHAN), P(LOCAL_BADCHAN), P(SEE_CHAN), P(PROPAGATE), - P(DISPLAY), P(SEE_OPERS), P(WIDE_GLINE), + P(DISPLAY), P(SEE_OPERS), P(FORCE_OPMODE), P(FORCE_LOCAL_OPMODE), + P(WIDE_GLINE), #undef P { 0, 0 } };