/* * m_sethost - generic message handler * * mimic old lain syntax: * * (Oper) /SETHOST ident host.cc [quit-message] * (User) /SETHOST host.cc password * (Both) /SETHOST undo * * check for undo, prepend parv w. <nick> -h or +h */ int m_sethost(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { char hostmask[512]; struct Flags setflags; /* Back up the flags first */ setflags = cli_flags(sptr); if (parc < 2) return need_more_params(sptr, "SETHOST"); if (0 == ircd_strcmp("undo", parv[1])) { set_hostmask(sptr, sptr, NULL, NULL); } else { if (parc<3) return need_more_params(sptr, "SETHOST"); if (IsAnOper(sptr)) { ircd_snprintf(0, hostmask, USERLEN + HOSTLEN + 1, "%s@%s", parv[1], parv[2]); if (!is_hostmask(hostmask)) { send_reply(sptr, ERR_BADHOSTMASK, hostmask); return 0; } if (set_hostmask(sptr, sptr, hostmask, NULL)) FlagClr(&setflags, FLAG_SETHOST); } else { if (!is_hostmask(parv[1])) { send_reply(sptr, ERR_BADHOSTMASK, parv[1]); return 0; } if (set_hostmask(sptr, sptr, parv[1], parv[2])) FlagClr(&setflags, FLAG_SETHOST); } } send_umode_out(cptr, sptr, &setflags, 0); return 0; }
/** Set the privileges for a client. * @param[in] client Client who has become an operator. * @param[in] oper Configuration item describing oper's privileges. */ void client_set_privs(struct Client *client, struct ConfItem *oper) { struct Privs *source, *defaults; enum Priv priv; if (!MyConnect(client)) return; /* Clear out client's privileges. */ memset(cli_privs(client), 0, sizeof(struct Privs)); if (!IsAnOper(client) || !oper) return; if (!privs_defaults_set) { memset(&privs_global, -1, sizeof(privs_global)); FlagClr(&privs_global, PRIV_WALK_LCHAN); FlagClr(&privs_global, PRIV_UNLIMIT_QUERY); FlagClr(&privs_global, PRIV_SET); FlagClr(&privs_global, PRIV_BADCHAN); FlagClr(&privs_global, PRIV_LOCAL_BADCHAN); #if defined(UNDERNET) FlagClr(&privs_global, PRIV_APASS_OPMODE); #endif memset(&privs_local, 0, sizeof(privs_local)); FlagSet(&privs_local, PRIV_CHAN_LIMIT); FlagSet(&privs_local, PRIV_MODE_LCHAN); FlagSet(&privs_local, PRIV_SHOW_INVIS); FlagSet(&privs_local, PRIV_SHOW_ALL_INVIS); FlagSet(&privs_local, PRIV_LOCAL_KILL); FlagSet(&privs_local, PRIV_REHASH); FlagSet(&privs_local, PRIV_LOCAL_GLINE); FlagSet(&privs_local, PRIV_LOCAL_JUPE); FlagSet(&privs_local, PRIV_LOCAL_OPMODE); FlagSet(&privs_local, PRIV_WHOX); FlagSet(&privs_local, PRIV_DISPLAY); FlagSet(&privs_local, PRIV_FORCE_LOCAL_OPMODE); privs_defaults_set = 1; } /* Decide whether to use global or local oper defaults. */ if (FlagHas(&oper->privs_dirty, PRIV_PROPAGATE)) defaults = FlagHas(&oper->privs, PRIV_PROPAGATE) ? &privs_global : &privs_local; else if (FlagHas(&oper->conn_class->privs_dirty, PRIV_PROPAGATE)) defaults = FlagHas(&oper->conn_class->privs, PRIV_PROPAGATE) ? &privs_global : &privs_local; else { assert(0 && "Oper has no propagation and neither does connection class"); return; } /* 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 (FlagHas(&oper->privs_dirty, priv)) source = &oper->privs; else if (FlagHas(&oper->conn_class->privs_dirty, priv)) source = &oper->conn_class->privs; else source = defaults; /* Set it if necessary (privileges were already cleared). */ if (FlagHas(source, priv)) SetPriv(client, priv); } /* This should be handled in the config, but lets be sure... */ if (HasPriv(client, PRIV_PROPAGATE)) { /* force propagating opers to display */ SetPriv(client, PRIV_DISPLAY); } else { /* if they don't propagate oper status, prevent desyncs */ ClrPriv(client, PRIV_KILL); ClrPriv(client, PRIV_GLINE); ClrPriv(client, PRIV_JUPE); ClrPriv(client, PRIV_OPMODE); ClrPriv(client, PRIV_BADCHAN); } }