static void ajoin_on_identify(user_t *u) { myuser_t *mu = u->myuser; metadata_t *md; char buf[512]; char *chan; if (!(md = metadata_find(mu, "private:autojoin"))) return; mowgli_strlcpy(buf, md->value, sizeof buf); chan = strtok(buf, " ,"); while (chan != NULL) { if(ircd->type == PROTOCOL_SHADOWIRCD) { sts(":%s ENCAP * SVSJOIN %s %s", ME, CLIENT_NAME(u), chan); } else { sts(":%s SVSJOIN %s %s", CLIENT_NAME(nicksvs.me->me), CLIENT_NAME(u), chan); } chan = strtok(NULL, ","); } }
static bool chatd_on_logout(user_t *u, const char *account) { return_val_if_fail(u != NULL, false); sts(":%s ENCAP * SU %s", ME, CLIENT_NAME(u)); sts(":%s ENCAP * IDENTIFIED %s %s OFF", ME, CLIENT_NAME(u), u->nick); return false; }
/* protocol-specific stuff to do on login */ static void chatd_on_login(user_t *u, myuser_t *mu, const char *wantedhost) { return_if_fail(u != NULL); sts(":%s ENCAP * SU %s %s", ME, CLIENT_NAME(u), entity(mu)->name); if (should_reg_umode(u)) sts(":%s ENCAP * IDENTIFIED %s %s", ME, CLIENT_NAME(u), u->nick); }
static void plexus_sethost_sts(user_t *source, user_t *target, const char *host) { if (!me.connected) return; if (irccasecmp(target->host, host)) numeric_sts(me.me, 396, target, "%s :is now your hidden host (set by %s)", host, source->nick); else { numeric_sts(me.me, 396, target, "%s :hostname reset by %s", host, source->nick); sts(":%s ENCAP * SVSMODE %s %lu -x", CLIENT_NAME(source), CLIENT_NAME(target), (unsigned long)target->ts); } sts(":%s ENCAP * CHGHOST %s :%s", ME, CLIENT_NAME(target), host); }
static void cs_cmd_devoice(sourceinfo_t *si, int parc, char *parv[]) { char *chan = parv[0]; char *nick = parv[1]; mychan_t *mc; user_t *tu; chanuser_t *cu; if (!chan) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "DEVOICE"); command_fail(si, fault_needmoreparams, _("Syntax: DEVOICE <#channel> [nickname]")); return; } mc = mychan_find(chan); if (!mc) { command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), chan); return; } if (!chanacs_source_has_flag(mc, si, CA_VOICE)) { command_fail(si, fault_noprivs, _("You are not authorized to perform this operation.")); return; } /* figure out who we're going to devoice */ if (!nick) tu = si->su; else { if (!(tu = user_find_named(nick))) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not online."), nick); return; } } if (is_internal_client(tu)) return; cu = chanuser_find(mc->chan, tu); if (!cu) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not on \2%s\2."), tu->nick, mc->name); return; } modestack_mode_param(chansvs.nick, mc->chan, MTYPE_DEL, 'v', CLIENT_NAME(tu)); cu->modes &= ~CSTATUS_VOICE; if (si->c == NULL && tu != si->su) change_notify(chansvs.nick, tu, "You have been devoiced on %s by %s", mc->name, get_source_name(si)); logcommand(si, CMDLOG_DO, "DEVOICE: \2%s!%s@%s\2 on \2%s\2", tu->nick, tu->user, tu->vhost, mc->name); if (!chanuser_find(mc->chan, si->su)) command_success_nodata(si, _("\2%s\2 has been devoiced on \2%s\2."), tu->nick, mc->name); }
static void nick_ungroup(hook_user_req_t *hdata) { user_t *u; u = hdata->si->su != NULL && !irccasecmp(hdata->si->su->nick, hdata->mn->nick) ? hdata->si->su : user_find_named(hdata->mn->nick); if (u != NULL && !nicksvs.no_nick_ownership) sts(":%s ENCAP * IDENTIFIED %s %s OFF", ME, CLIENT_NAME(u), u->nick); }
static void nick_group(hook_user_req_t *hdata) { user_t *u; u = hdata->si->su != NULL && !irccasecmp(hdata->si->su->nick, hdata->mn->nick) ? hdata->si->su : user_find_named(hdata->mn->nick); if (u != NULL && should_reg_umode(u)) sts(":%s ENCAP * IDENTIFIED %s %s", ME, CLIENT_NAME(u), u->nick); }
static void m_euid(sourceinfo_t *si, int parc, char *parv[]) { server_t *s; user_t *u; /* got the right number of args for an introduction? */ if (parc >= 11) { s = si->s; slog(LG_DEBUG, "m_euid(): new user on `%s': %s", s->name, parv[0]); u = user_add(parv[0], /* nick */ parv[4], /* user */ *parv[8] != '*' ? parv[8] : parv[5], /* hostname */ parv[5], /* hostname (visible) */ parv[6], /* ip */ parv[7], /* uid */ parv[parc - 1], /* gecos */ s, /* object parent (server) */ atoi(parv[2])); /* hopcount */ if (u == NULL) return; user_mode(u, parv[3]); if (*parv[9] != '*') { handle_burstlogin(u, parv[9], 0); /* If an account is given in burst, then either they logged in with sasl, * or they logged in before a split and are now returning. Either way we need * to check for identified-to-nick status and update the ircd state accordingly. * For sasl they should be marked identified, and when returning from a split * their nick may have been ungrouped, they may have changed nicks, or their account * may have been dropped. */ if (authservice_loaded) sts(":%s ENCAP * IDENTIFIED %s %s %s", ME, CLIENT_NAME(u), u->nick, should_reg_umode(u) ? "" : "OFF"); } /* server_eob() cannot know if a user was introduced * with NICK/UID or EUID and handle_nickchange() must * be called exactly once for each new user -- jilles */ if (s->flags & SF_EOB) handle_nickchange(u); } else { int i; slog(LG_DEBUG, "m_euid(): got EUID with wrong number of params"); for (i = 0; i < parc; i++) slog(LG_DEBUG, "m_euid(): parv[%d] = %s", i, parv[i]); } }
static void cs_cmd_voice(sourceinfo_t *si, int parc, char *parv[]) { char *chan = parv[0]; char *nick = parv[1]; mychan_t *mc; user_t *tu; chanuser_t *cu; char *nicklist; char *strtokctx; if (!chan) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "VOICE"); command_fail(si, fault_needmoreparams, _("Syntax: VOICE <#channel> [nickname] [...]")); return; } mc = mychan_find(chan); if (!mc) { command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), chan); return; } if (metadata_find(mc, "private:close:closer")) { command_fail(si, fault_noprivs, _("\2%s\2 is closed."), chan); return; } nicklist = (!nick ? strdup(si->su->nick) : strdup(nick)); nick = strtok_r(nicklist, " ", &strtokctx); do { if (invert_purpose(si, parc, chan, &nick, '-', &cs_cmd_devoice)) continue; /* figure out who we're going to voice */ if (!(tu = user_find_named(nick))) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not online."), nick); continue; } if (!chanacs_source_has_flag(mc, si, CA_VOICE) && (tu != si->su || !chanacs_source_has_flag(mc, si, CA_AUTOVOICE))) { command_fail(si, fault_noprivs, _("You are not authorized to perform this operation.")); continue; } if (is_internal_client(tu)) continue; cu = chanuser_find(mc->chan, tu); if (!cu) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not on \2%s\2."), tu->nick, mc->name); continue; } modestack_mode_param(chansvs.nick, mc->chan, MTYPE_ADD, 'v', CLIENT_NAME(tu)); cu->modes |= CSTATUS_VOICE; if (si->c == NULL && tu != si->su) change_notify(chansvs.nick, tu, "You have been voiced on %s by %s", mc->name, get_source_name(si)); logcommand(si, CMDLOG_DO, "VOICE: \2%s!%s@%s\2 on \2%s\2", tu->nick, tu->user, tu->vhost, mc->name); if (si->su == NULL || !chanuser_find(mc->chan, si->su)) command_success_nodata(si, _("\2%s\2 has been voiced on \2%s\2."), tu->nick, mc->name); } while ((nick = strtok_r(NULL, " ", &strtokctx)) != NULL); free(nicklist); }
static void cs_cmd_down(sourceinfo_t *si, int parc, char *parv[]) { chanuser_t *cu; mychan_t *mc; char *name = parv[0]; if (!name) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "DOWN"); command_fail(si, fault_needmoreparams, "Syntax: DOWN <#channel>"); return; } if (!(mc = mychan_find(name))) { command_fail(si, fault_nosuch_target, "\2%s\2 is not registered.", name); return; } if (metadata_find(mc, "private:close:closer")) { command_fail(si, fault_noprivs, "\2%s\2 is closed.", name); return; } if (!mc->chan) { command_fail(si, fault_nosuch_target, "\2%s\2 does not exist.", name); return; } if (!si->su) return; // needs to be done over IRC cu = chanuser_find(mc->chan, si->su); if (!cu) { command_fail(si, fault_nosuch_target, "You are not on \2%s\2.", mc->name); return; } chanacs_user_flags(mc, cu->user); // Don't check NOOP, because they are explicitly requesting status if (ircd->uses_owner) { if (ircd->owner_mode & cu->modes) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_DEL, ircd->owner_mchar[1], CLIENT_NAME(cu->user)); cu->modes &= ~ircd->owner_mode; } } if (ircd->uses_protect) { if (ircd->protect_mode & cu->modes) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_DEL, ircd->protect_mchar[1], CLIENT_NAME(cu->user)); cu->modes &= ~ircd->protect_mode; } } if ((CSTATUS_OP & cu->modes)) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_DEL, 'o', CLIENT_NAME(cu->user)); cu->modes &= ~CSTATUS_OP; } if (ircd->uses_halfops) { if (ircd->halfops_mode & cu->modes) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_DEL, ircd->halfops_mchar[1], CLIENT_NAME(cu->user)); cu->modes &= ~ircd->halfops_mode; } } if ((CSTATUS_VOICE & cu->modes)) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_DEL, 'v', CLIENT_NAME(cu->user)); cu->modes &= ~CSTATUS_VOICE; } command_success_nodata(si, "Downed successfully on \2%s\2.", mc->name); }
/* *INDENT-ON* */ static void hybrid_quarantine_sts(user_t *source, user_t *victim, long duration, const char *reason) { sts(":%s CAPTURE %s", CLIENT_NAME(source), CLIENT_NAME(victim)); }
static void m_nick(sourceinfo_t *si, int parc, char *parv[]) { server_t *s; user_t *u; /* got the right number of args for an introduction? */ if (parc == 8) { s = server_find(parv[6]); if (!s) { slog(LG_DEBUG, "m_nick(): new user on nonexistant server: %s", parv[6]); return; } slog(LG_DEBUG, "m_nick(): new user on `%s': %s", s->name, parv[0]); u = user_add(parv[0], parv[4], parv[5], NULL, NULL, NULL, parv[7], s, atoi(parv[2])); if (u == NULL) return; user_mode(u, parv[3]); /* If server is not yet EOB we will do this later. * This avoids useless "please identify" -- jilles */ if (s->flags & SF_EOB) handle_nickchange(user_find(parv[0])); } /* if it's only 2 then it's a nickname change */ else if (parc == 2) { bool realchange; if (!si->su) { slog(LG_DEBUG, "m_nick(): server trying to change nick: %s", si->s != NULL ? si->s->name : "<none>"); return; } slog(LG_DEBUG, "m_nick(): nickname change from `%s': %s", si->su->nick, parv[0]); realchange = irccasecmp(si->su->nick, parv[0]); if (user_changenick(si->su, parv[0], atoi(parv[1]))) return; /* fix up +e if necessary -- jilles */ if (realchange && should_reg_umode(si->su)) /* changed nick to registered one, reset +e */ sts(":%s ENCAP * IDENTIFIED %s %s", ME, CLIENT_NAME(si->su), si->su->nick); /* It could happen that our PING arrived late and the * server didn't acknowledge EOB yet even though it is * EOB; don't send double notices in that case -- jilles */ if (si->su->server->flags & SF_EOB) handle_nickchange(si->su); } else { int i; slog(LG_DEBUG, "m_nick(): got NICK with wrong number of params"); for (i = 0; i < parc; i++) slog(LG_DEBUG, "m_nick(): parv[%d] = %s", i, parv[i]); } }
static void cs_cmd_owner(sourceinfo_t *si, int parc, char *parv[]) { char *chan = parv[0]; char *nick = parv[1]; mychan_t *mc; user_t *tu; chanuser_t *cu; char *nicklist; char *strtokctx; if (ircd->uses_owner == false) { command_fail(si, fault_noprivs, _("The IRCd software you are running does not support this feature.")); return; } if (!chan) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "OWNER"); command_fail(si, fault_needmoreparams, _("Syntax: OWNER <#channel> [nickname] [...]")); return; } mc = mychan_find(chan); if (!mc) { command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), chan); return; } if (!chanacs_source_has_flag(mc, si, CA_USEOWNER)) { command_fail(si, fault_noprivs, _("You are not authorized to perform this operation.")); return; } if (metadata_find(mc, "private:close:closer")) { command_fail(si, fault_noprivs, _("\2%s\2 is closed."), chan); return; } nicklist = (!nick ? strdup(si->su->nick) : strdup(nick)); nick = strtok_r(nicklist, " ", &strtokctx); do { if (invert_purpose(si, parc, chan, &nick, '-', &cs_cmd_deowner)) continue; /* figure out who we're going to op */ if (!(tu = user_find_named(nick))) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not online."), nick); continue; } if (is_internal_client(tu)) continue; /* SECURE check; we can skip this if sender == target, because we already verified */ if ((si->su != tu) && (mc->flags & MC_SECURE) && !chanacs_user_has_flag(mc, tu, CA_OP) && !chanacs_user_has_flag(mc, tu, CA_AUTOOP)) { command_fail(si, fault_noprivs, _("You are not authorized to perform this operation.")); command_fail(si, fault_noprivs, _("\2%s\2 has the SECURE option enabled, and \2%s\2 does not have appropriate access."), mc->name, tu->nick); continue; } cu = chanuser_find(mc->chan, tu); if (!cu) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not on \2%s\2."), tu->nick, mc->name); continue; } modestack_mode_param(chansvs.nick, mc->chan, MTYPE_ADD, ircd->owner_mchar[1], CLIENT_NAME(tu)); cu->modes |= CSTATUS_OWNER; if (si->c == NULL && tu != si->su) change_notify(chansvs.nick, tu, "You have been set as owner on %s by %s", mc->name, get_source_name(si)); logcommand(si, CMDLOG_DO, "OWNER: \2%s!%s@%s\2 on \2%s\2", tu->nick, tu->user, tu->vhost, mc->name); if (si->su == NULL || !chanuser_find(mc->chan, si->su)) command_success_nodata(si, _("\2%s\2 has been set as owner on \2%s\2."), tu->nick, mc->name); } while ((nick = strtok_r(NULL, " ", &strtokctx)) != NULL); free(nicklist); }
static void cs_cmd_register(struct sourceinfo *si, int parc, char *parv[]) { struct channel *c; struct chanuser *cu; struct mychan *mc; char *name = parv[0]; char str[21]; hook_channel_register_check_t hdatac; hook_channel_req_t hdata; unsigned int fl; /* This command is not useful on registered channels, ignore it if * it is a fantasy command so users can program bots to react on * it without interference from ChanServ. */ if (si->c != NULL) return; if (!name) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "REGISTER"); command_fail(si, fault_needmoreparams, _("To register a channel: REGISTER <#channel>")); return; } if (*name != '#') { command_fail(si, fault_badparams, STR_INVALID_PARAMS, "REGISTER"); command_fail(si, fault_badparams, _("Syntax: REGISTER <#channel>")); return; } if (si->smu->flags & MU_WAITAUTH) { command_fail(si, fault_notverified, _("You need to verify your email address before you may register channels.")); return; } // make sure it isn't already registered if ((mc = mychan_find(name))) { if (! (mc->flags & MC_PRIVATE)) command_fail(si, fault_alreadyexists, _("\2%s\2 is already registered to \2%s\2."), mc->name, mychan_founder_names(mc)); else command_fail(si, fault_alreadyexists, _("\2%s\2 is already registered."), mc->name); return; } // make sure the channel exists if (!(c = channel_find(name))) { command_fail(si, fault_nosuch_target, _("The channel \2%s\2 must exist in order to register it."), name); return; } // make sure they're in it if (!(cu = chanuser_find(c, si->su))) { command_fail(si, fault_noprivs, _("You must be in \2%s\2 in order to register it."), name); return; } // make sure they're opped (or protected/owner on unreal/inspircd) if (!((CSTATUS_OP | CSTATUS_PROTECT | CSTATUS_OWNER) & cu->modes)) { command_fail(si, fault_noprivs, _("You must be a channel operator in \2%s\2 in order to register it."), name); return; } if (metadata_find(si->smu, "private:restrict:setter")) { command_fail(si, fault_noprivs, _("You have been restricted from registering channels by network staff.")); return; } if ((unsigned int)(CURRTIME - ratelimit_firsttime) > config_options.ratelimit_period) { ratelimit_count = 0; ratelimit_firsttime = CURRTIME; } if (ratelimit_count > config_options.ratelimit_uses && !has_priv(si, PRIV_FLOOD)) { command_fail(si, fault_toomany, _("The system is currently too busy to process your registration, please try again later.")); slog(LG_INFO, "CHANSERV:REGISTER:THROTTLED: \2%s\2 by \2%s\2", name, entity(si->smu)->name); return; } hdatac.si = si; hdatac.name = name; hdatac.chan = c; hdatac.approved = 0; hook_call_channel_can_register(&hdatac); if (hdatac.approved != 0) return; if (!myentity_can_register_channel(entity(si->smu))) { command_fail(si, fault_toomany, _("You have too many channels registered.")); return; } if (config_options.ratelimit_uses && config_options.ratelimit_period) ratelimit_count++; logcommand(si, CMDLOG_REGISTER, "REGISTER: \2%s\2", name); mc = mychan_add(name); mc->registered = CURRTIME; mc->used = CURRTIME; mc->mlock_on |= (CMODE_NOEXT | CMODE_TOPIC); if (c->limit == 0) mc->mlock_off |= CMODE_LIMIT; if (c->key == NULL) mc->mlock_off |= CMODE_KEY; mc->flags |= config_options.defcflags; chanacs_add(mc, entity(si->smu), custom_founder_check(), CURRTIME, entity(si->smu)); if (c->ts > 0) { snprintf(str, sizeof str, "%lu", (unsigned long)c->ts); metadata_add(mc, "private:channelts", str); } if (chansvs.deftemplates != NULL && *chansvs.deftemplates != '\0') metadata_add(mc, "private:templates", chansvs.deftemplates); command_success_nodata(si, _("\2%s\2 is now registered to \2%s\2."), mc->name, entity(si->smu)->name); hdata.si = si; hdata.mc = mc; hook_call_channel_register(&hdata); // Allow the hook to override this. fl = chanacs_source_flags(mc, si); cu = chanuser_find(mc->chan, si->su); if (cu == NULL) ; else if (ircd->uses_owner && fl & CA_USEOWNER && fl & CA_AUTOOP && !(cu->modes & CSTATUS_OWNER)) { modestack_mode_param(si->service->nick, mc->chan, MTYPE_ADD, ircd->owner_mchar[1], CLIENT_NAME(si->su)); cu->modes |= CSTATUS_OWNER; } else if (ircd->uses_protect && fl & CA_USEPROTECT && fl & CA_AUTOOP && !(cu->modes & CSTATUS_PROTECT)) { modestack_mode_param(si->service->nick, mc->chan, MTYPE_ADD, ircd->protect_mchar[1], CLIENT_NAME(si->su)); cu->modes |= CSTATUS_PROTECT; } }
static void cs_cmd_halfop(sourceinfo_t *si, int parc, char *parv[]) { char *chan = parv[0]; char *nick = parv[1]; mychan_t *mc; user_t *tu; chanuser_t *cu; if (!ircd->uses_halfops) { command_fail(si, fault_noprivs, _("Your IRC server does not support halfops.")); return; } if (!chan) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "HALFOP"); command_fail(si, fault_needmoreparams, _("Syntax: HALFOP <#channel> [nickname]")); return; } mc = mychan_find(chan); if (!mc) { command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), chan); return; } if (!chanacs_source_has_flag(mc, si, CA_HALFOP)) { command_fail(si, fault_noprivs, _("You are not authorized to perform this operation.")); return; } if (metadata_find(mc, "private:close:closer")) { command_fail(si, fault_noprivs, _("\2%s\2 is closed."), chan); return; } /* figure out who we're going to halfop */ if (!nick) tu = si->su; else { if (!(tu = user_find_named(nick))) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not online."), nick); return; } } if (is_internal_client(tu)) return; /* SECURE check; we can skip this if sender == target, because we already verified */ if ((si->su != tu) && (mc->flags & MC_SECURE) && !chanacs_user_has_flag(mc, tu, CA_HALFOP) && !chanacs_user_has_flag(mc, tu, CA_AUTOHALFOP)) { command_fail(si, fault_noprivs, _("You are not authorized to perform this operation.")); command_fail(si, fault_noprivs, _("\2%s\2 has the SECURE option enabled, and \2%s\2 does not have appropriate access."), mc->name, tu->nick); return; } cu = chanuser_find(mc->chan, tu); if (!cu) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not on \2%s\2."), tu->nick, mc->name); return; } modestack_mode_param(chansvs.nick, mc->chan, MTYPE_ADD, 'h', CLIENT_NAME(tu)); cu->modes |= ircd->halfops_mode; if (si->c == NULL && tu != si->su) change_notify(chansvs.nick, tu, "You have been halfopped on %s by %s", mc->name, get_source_name(si)); logcommand(si, CMDLOG_DO, "HALFOP: \2%s!%s@%s\2 on \2%s\2", tu->nick, tu->user, tu->vhost, mc->name); if (!chanuser_find(mc->chan, si->su)) command_success_nodata(si, _("\2%s\2 has been halfopped on \2%s\2."), tu->nick, mc->name); }
static void cs_fcmd_dehalfop(char *origin, char *chan) { char *nick; mychan_t *mc; user_t *u, *tu; chanuser_t *cu; if (!ircd->uses_halfops) { notice(chansvs.nick, origin, "Your IRC server does not support halfops."); return; } mc = mychan_find(chan); if (!mc) { notice(chansvs.nick, origin, "\2%s\2 is not registered.", chan); return; } u = user_find_named(origin); if (!chanacs_user_has_flag(mc, u, CA_HALFOP)) { notice(chansvs.nick, origin, "You are not authorized to perform this operation."); return; } if (metadata_find(mc, METADATA_CHANNEL, "private:close:closer")) { notice(chansvs.nick, origin, "\2%s\2 is closed.", chan); return; } /* figure out who we're going to dehalfop */ nick = strtok(NULL, " "); do { if (!nick) tu = u; else { if (!(tu = user_find_named(nick))) { notice(chansvs.nick, origin, "\2%s\2 is not online.", nick); continue; } } if (is_internal_client(tu)) continue; cu = chanuser_find(mc->chan, tu); if (!cu) { notice(chansvs.nick, origin, "\2%s\2 is not on \2%s\2.", tu->nick, mc->name); continue; } modestack_mode_param(chansvs.nick, chan, MTYPE_DEL, 'h', CLIENT_NAME(tu)); cu->modes &= ~ircd->halfops_mode; logcommand(chansvs.me, u, CMDLOG_SET, "%s DEHALFOP %s!%s@%s", mc->name, tu->nick, tu->user, tu->vhost); } while ((nick = strtok(NULL, " ")) != NULL); }
static void cs_cmd_deowner(sourceinfo_t *si, int parc, char *parv[]) { char *chan = parv[0]; char *nick = parv[1]; mychan_t *mc; user_t *tu; chanuser_t *cu; if (ircd->uses_owner == false) { command_fail(si, fault_noprivs, _("The IRCd software you are running does not support this feature.")); return; } if (!chan) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "DEOWNER"); command_fail(si, fault_needmoreparams, _("Syntax: DEOWNER <#channel> [nickname]")); return; } mc = mychan_find(chan); if (!mc) { command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), chan); return; } if (!chanacs_source_has_flag(mc, si, CA_USEOWNER)) { command_fail(si, fault_noprivs, _("You are not authorized to perform this operation.")); return; } if (metadata_find(mc, "private:close:closer")) { command_fail(si, fault_noprivs, _("\2%s\2 is closed."), chan); return; } /* figure out who we're going to deop */ if (!nick) tu = si->su; else { if (!(tu = user_find_named(nick))) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not online."), nick); return; } } if (is_internal_client(tu)) return; cu = chanuser_find(mc->chan, tu); if (!cu) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not on \2%s\2."), tu->nick, mc->name); return; } modestack_mode_param(chansvs.nick, mc->chan, MTYPE_DEL, ircd->owner_mchar[1], CLIENT_NAME(tu)); cu->modes &= ~CSTATUS_OWNER; if (si->c == NULL && tu != si->su) change_notify(chansvs.nick, tu, "You have been unset as owner on %s by %s", mc->name, get_source_name(si)); logcommand(si, CMDLOG_DO, "DEOWNER: \2%s!%s@%s\2 on \2%s\2", tu->nick, tu->user, tu->vhost, mc->name); if (si->su == NULL || !chanuser_find(mc->chan, si->su)) command_success_nodata(si, _("\2%s\2 has been unset as owner on \2%s\2."), tu->nick, mc->name); }
static void cs_cmd_up(sourceinfo_t *si, int parc, char *parv[]) { chanuser_t *cu; mychan_t *mc; char *name = parv[0]; char *chan = parv[0]; int fl; if (!name) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "UP"); command_fail(si, fault_needmoreparams, "Syntax: UP <#channel>"); return; } if (!(mc = mychan_find(name))) { command_fail(si, fault_nosuch_target, "\2%s\2 is not registered.", name); return; } if (metadata_find(mc, "private:close:closer")) { command_fail(si, fault_noprivs, "\2%s\2 is closed.", name); return; } if (metadata_find(mc, "private:frozen:freezer")) { command_fail(si, fault_noprivs, _("\2%s\2 is frozen."), chan); return; } if (!mc->chan) { command_fail(si, fault_nosuch_target, "\2%s\2 does not exist.", name); return; } if (!si->su) return; // needs to be done over IRC if (chanacs_source_has_flag(mc, si, CA_SUSPENDED)) { command_fail(si, fault_noprivs, _("Your access in %s is \2suspended\2."), chan); return; } cu = chanuser_find(mc->chan, si->su); if (!cu) { command_fail(si, fault_nosuch_target, "You are not on \2%s\2.", mc->name); return; } fl = chanacs_user_flags(mc, cu->user); // Don't check NOOP, because they are explicitly requesting status if (ircd->uses_owner) { if (fl & CA_USEOWNER) { if (fl & CA_AUTOOP && !(ircd->owner_mode & cu->modes)) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_ADD, ircd->owner_mchar[1], CLIENT_NAME(cu->user)); cu->modes |= ircd->owner_mode; } } } if (ircd->uses_protect) { if (fl & CA_USEPROTECT) { if (fl & CA_AUTOOP && !(ircd->protect_mode & cu->modes) && !(ircd->uses_owner && cu->modes & ircd->owner_mode)) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_ADD, ircd->protect_mchar[1], CLIENT_NAME(cu->user)); cu->modes |= ircd->protect_mode; } } } if (fl & (CA_AUTOOP | CA_OP)) { if (fl & CA_AUTOOP && !(CSTATUS_OP & cu->modes)) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_ADD, 'o', CLIENT_NAME(cu->user)); cu->modes |= CSTATUS_OP; } } if (ircd->uses_halfops) { if (fl & (CA_AUTOHALFOP | CA_HALFOP)) { if (fl & CA_AUTOHALFOP && !(ircd->halfops_mode & cu->modes)) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_ADD, ircd->halfops_mchar[1], CLIENT_NAME(cu->user)); cu->modes |= ircd->halfops_mode; } } } if (fl & (CA_AUTOVOICE | CA_VOICE)) { if (fl & CA_AUTOVOICE && !(CSTATUS_VOICE & cu->modes)) { modestack_mode_param(chansvs.nick, mc->chan, MTYPE_ADD, 'v', CLIENT_NAME(cu->user)); cu->modes |= CSTATUS_VOICE; } } command_success_nodata(si, "Upped successfully on \2%s\2.", mc->name); }
static void cs_cmd_halfop(char *origin) { char *chan = strtok(NULL, " "); char *nick = strtok(NULL, " "); mychan_t *mc; user_t *u, *tu; chanuser_t *cu; if (!ircd->uses_halfops) { notice(chansvs.nick, origin, "Your IRC server does not support halfops."); return; } if (!chan) { notice(chansvs.nick, origin, STR_INSUFFICIENT_PARAMS, "HALFOP"); notice(chansvs.nick, origin, "Syntax: HALFOP <#channel> [nickname]"); return; } mc = mychan_find(chan); if (!mc) { notice(chansvs.nick, origin, "\2%s\2 is not registered.", chan); return; } u = user_find_named(origin); if (!chanacs_user_has_flag(mc, u, CA_HALFOP)) { notice(chansvs.nick, origin, "You are not authorized to perform this operation."); return; } if (metadata_find(mc, METADATA_CHANNEL, "private:close:closer")) { notice(chansvs.nick, origin, "\2%s\2 is closed.", chan); return; } /* figure out who we're going to halfop */ if (!nick) tu = u; else { if (!(tu = user_find_named(nick))) { notice(chansvs.nick, origin, "\2%s\2 is not online.", nick); return; } } if (is_internal_client(tu)) return; /* SECURE check; we can skip this if sender == target, because we already verified */ if ((u != tu) && (mc->flags & MC_SECURE) && !chanacs_user_has_flag(mc, tu, CA_HALFOP) && !chanacs_user_has_flag(mc, tu, CA_AUTOHALFOP)) { notice(chansvs.nick, origin, "You are not authorized to perform this operation.", mc->name); notice(chansvs.nick, origin, "\2%s\2 has the SECURE option enabled, and \2%s\2 does not have appropriate access.", mc->name, tu->nick); return; } cu = chanuser_find(mc->chan, tu); if (!cu) { notice(chansvs.nick, origin, "\2%s\2 is not on \2%s\2.", tu->nick, mc->name); return; } modestack_mode_param(chansvs.nick, chan, MTYPE_ADD, 'h', CLIENT_NAME(tu)); cu->modes |= ircd->halfops_mode; /* TODO: Add which username had access to perform the command */ if (tu != u) notice(chansvs.nick, tu->nick, "You have been halfopped on %s by %s", mc->name, origin); logcommand(chansvs.me, u, CMDLOG_SET, "%s HALFOP %s!%s@%s", mc->name, tu->nick, tu->user, tu->vhost); if (!chanuser_find(mc->chan, u)) notice(chansvs.nick, origin, "\2%s\2 has been halfopped on \2%s\2.", tu->nick, mc->name); }