static int canBanUser(Channel * c, User * u, User * u2) { ChannelInfo *ci; int ok = 0; if (!(ci = c->ci)) { notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, c->name); } else if (ci->flags & CI_VERBOTEN) { notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, c->name); } else if (!check_access(u, ci, CA_BAN)) { notice_lang(s_ChanServ, u, ACCESS_DENIED); } else if (ircd->except && is_excepted(ci, u2)) { notice_lang(s_ChanServ, u, CHAN_EXCEPTED, u2->nick, ci->name); } else if (ircd->protectedumode && is_protected(u2)) { notice_lang(s_ChanServ, u, PERMISSION_DENIED); } else { ok = 1; } return ok; }
/** * The /cs ban command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_ban(User * u) { char *chan = strtok(NULL, " "); char *params = strtok(NULL, " "); char *reason = strtok(NULL, ""); Channel *c; ChannelInfo *ci; User *u2; int is_same; if (!reason) { reason = "Requested"; } else { if (strlen(reason) > 200) reason[200] = '\0'; } if (!chan) { struct u_chanlist *uc, *next; /* Bans the user on every channels he is on. */ for (uc = u->chans; uc; uc = next) { next = uc->next; if ((ci = uc->chan->ci) && !(ci->flags & CI_VERBOTEN) && check_access(u, ci, CA_BANME)) { char *av[3]; char mask[BUFSIZE]; /* * Dont ban/kick the user on channels where he is excepted * to prevent services <-> server wars. */ if (ircd->except) { if (is_excepted(ci, u)) notice_lang(s_ChanServ, u, CHAN_EXCEPTED, u->nick, ci->name); continue; } if (is_protected(u)) { notice_lang(s_ChanServ, u, PERMISSION_DENIED); continue; } av[0] = sstrdup("+b"); get_idealban(ci, u, mask, sizeof(mask)); av[1] = mask; xanadu_cmd_mode(whosends(ci), uc->chan->name, "+b %s", av[1]); chan_set_modes(s_ChanServ, uc->chan, 2, av, 1); free(av[0]); if ((ci->flags & CI_SIGNKICK) || ((ci->flags & CI_SIGNKICK_LEVEL) && !check_access(u, ci, CA_SIGNKICK))) xanadu_cmd_kick(whosends(ci), ci->name, u->nick, "%s (%s)", reason, u->nick); else xanadu_cmd_kick(whosends(ci), ci->name, u->nick, "%s", reason); av[0] = ci->name; av[1] = u->nick; av[2] = reason; do_kick(s_ChanServ, 3, av); } } return MOD_CONT; } else if (!params) { params = u->nick; } is_same = (params == u->nick) ? 1 : (stricmp(params, u->nick) == 0); if (!(c = findchan(chan))) { notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan); } else if (!(ci = c->ci)) { notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan); } else if (ci->flags & CI_VERBOTEN) { notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan); } else if (is_same ? !(u2 = u) : !(u2 = finduser(params))) { notice_lang(s_ChanServ, u, NICK_X_NOT_IN_USE, params); } else if (!is_same ? !check_access(u, ci, CA_BAN) : !check_access(u, ci, CA_BANME)) { notice_lang(s_ChanServ, u, ACCESS_DENIED); } else if (!is_same && (ci->flags & CI_PEACE) && (get_access(u2, ci) >= get_access(u, ci))) { notice_lang(s_ChanServ, u, PERMISSION_DENIED); /* * Dont ban/kick the user on channels where he is excepted * to prevent services <-> server wars. */ } else if (ircd->except && is_excepted(ci, u2)) { notice_lang(s_ChanServ, u, CHAN_EXCEPTED, u2->nick, ci->name); } else if (ircd->protectedumode && is_protected(u2)) { notice_lang(s_ChanServ, u, PERMISSION_DENIED); } else { char *av[3]; char mask[BUFSIZE]; av[0] = sstrdup("+b"); get_idealban(ci, u2, mask, sizeof(mask)); av[1] = mask; xanadu_cmd_mode(whosends(ci), c->name, "+b %s", av[1]); chan_set_modes(s_ChanServ, c, 2, av, 1); free(av[0]); /* We still allow host banning while not allowing to kick */ if (!is_on_chan(c, u2)) return MOD_CONT; if ((ci->flags & CI_SIGNKICK) || ((ci->flags & CI_SIGNKICK_LEVEL) && !check_access(u, ci, CA_SIGNKICK))) xanadu_cmd_kick(whosends(ci), ci->name, params, "%s (%s)", reason, u->nick); else xanadu_cmd_kick(whosends(ci), ci->name, params, "%s", reason); av[0] = ci->name; av[1] = params; av[2] = reason; do_kick(s_ChanServ, 3, av); } return MOD_CONT; }
int do_core_kickban(User * u, Channel *c, char *target, char *reason) { ChannelInfo *ci = c->ci; User *u2; int is_same, exists; char *av[2]; if (!target) target = u->nick; is_same = (target == u->nick) ? 1 : (stricmp(target, u->nick) == 0); if (is_same) { u2 = u; exists = 1; } else exists = ((u2 = finduser(target)) ? 1 : 0); if (!is_same ? !check_access(u, ci, CA_BAN) : !check_access(u, ci, CA_BANME)) { notice_lang(ci->bi->nick, u, ACCESS_DENIED); } else if (!is_same && exists && (ci->flags & CI_PEACE) && (get_access(u2, ci) >= get_access(u, ci))) { notice_lang(ci->bi->nick, u, PERMISSION_DENIED); } else if (exists && ((ircd->protectedumode && is_protected(u2)) && !is_founder(u, ci))) { notice_lang(ci->bi->nick, u, PERMISSION_DENIED); /** * Dont ban the user on channels where he is excepted * to prevent services <-> server wars. **/ } else if (exists && (ircd->except && is_excepted(ci, u2))) { notice_lang(ci->bi->nick, u, CHAN_EXCEPTED, u2->nick, ci->name); } else if (!exists && (ircd->except && is_excepted_mask(ci, target))) { notice_lang(ci->bi->nick, u, CHAN_EXCEPTED, target, ci->name); } else if (exists && RestrictKB && ((!is_founder(u, ci) && is_services_oper(u2)) || (is_founder(u, ci) && is_services_admin(u2)))) { notice_lang(ci->bi->nick, u, PERMISSION_DENIED); } else if (stricmp(target, ci->bi->nick) == 0) { bot_raw_ban(u, ci, u->nick, "Oops!"); } else { if (exists) { if (is_on_chan(ci->c, u2)) { if (!reason) bot_raw_ban(u, ci, target, "Requested"); else bot_raw_ban(u, ci, target, reason); } } else if (my_match_wild_nocase("*@*", target)) { char mask[BUFSIZE]; /* If we get a *@* target we need to add the *!... */ if (!my_match_wild_nocase("*!*@*", target)) snprintf(mask, BUFSIZE, "*!%s", target); else snprintf(mask, BUFSIZE, "%s", target); /* Only continue if the mask doesn't match an exception or is otherwise prohibited.. */ if (check_banmask(u, c, mask)) { struct c_userlist *cu = NULL, *next = NULL; av[0] = "+b"; av[1] = mask; anope_cmd_mode(ci->bi->nick, c->name, "+b %s", av[1]); chan_set_modes(ci->bi->nick, c, 2, av, 1); cu = c->users; while (cu) { next = cu->next; /* This only checks against the cloacked host & vhost for normal users. * IPs are only checked when triggered by an oper.. */ if (is_oper(u) ? match_usermask_full(mask, cu->user, true) : match_usermask(mask, cu->user)) { if (!reason) bot_raw_kick(u, ci, cu->user->nick, "Requested"); else bot_raw_kick(u, ci, cu->user->nick, reason); } cu = next; } } } else noticeLang(ci->bi->nick, u, LANG_REQ_NICK_OR_MASK); } return MOD_CONT; }