X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/c177d078ea560e07276f94948f5287a8feb1b5fe..01b2be6fe1fb93d3c5c547035d9dd360afbc5b15:/modules/core/m_ban.c diff --git a/modules/core/m_ban.c b/modules/core/m_ban.c index 8d4f269..ebc5152 100644 --- a/modules/core/m_ban.c +++ b/modules/core/m_ban.c @@ -29,12 +29,14 @@ #include "stdinc.h" #include "send.h" +#include "channel.h" #include "client.h" #include "common.h" #include "config.h" #include "ircd.h" #include "match.h" #include "s_conf.h" +#include "s_newconf.h" #include "msg.h" #include "modules.h" #include "hash.h" @@ -43,16 +45,27 @@ #include "reject.h" #include "hostmask.h" +static int m_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]); static int ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]); struct Message ban_msgtab = { "BAN", 0, 0, 0, MFLG_SLOW, - {mg_unreg, mg_ignore, {ms_ban, 9}, {ms_ban, 9}, mg_ignore, mg_ignore} + {mg_unreg, {m_ban, 0}, {ms_ban, 9}, {ms_ban, 9}, mg_ignore, {m_ban, 0}} }; mapi_clist_av1 ban_clist[] = { &ban_msgtab, NULL }; DECLARE_MODULE_AV1(ban, NULL, NULL, ban_clist, NULL, NULL, "$Revision: 1349 $"); +static int +m_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) +{ + sendto_one_notice(source_p, ":The BAN command is not user-accessible."); + sendto_one_notice(source_p, ":To ban a user from a channel, see /QUOTE HELP CMODE"); + if (IsOper(source_p)) + sendto_one_notice(source_p, ":To ban a user from a server or from the network, see /QUOTE HELP KLINE"); + return 0; +} + /* ms_ban() * * parv[1] - type @@ -74,6 +87,7 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p time_t created, hold, lifetime; char *p; int act; + int valid; if (strlen(parv[1]) != 1) { @@ -88,6 +102,15 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p ntype = CONF_KILL; stype = "K-Line"; break; + case 'X': + ntype = CONF_XLINE; + stype = "X-Line"; + break; + case 'R': + ntype = IsChannelName(parv[3]) ? CONF_RESV_CHANNEL : + CONF_RESV_NICK; + stype = "RESV"; + break; default: sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Unknown BAN type %s from %s", @@ -104,6 +127,7 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p ptr = find_prop_ban(ntype, parv[2], parv[3]); if (ptr != NULL) { + /* We already know about this ban mask. */ aconf = ptr->data; if (aconf->created > created || (aconf->created == created && @@ -118,6 +142,11 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p aconf->host); return 0; } + /* act indicates if something happened (from the oper's + * point of view). This is the case if the ban was + * previously active (not deleted) or if the new ban + * is not a removal and not already expired. + */ act = !(aconf->status & CONF_ILLEGAL) || (hold != created && hold > rb_current_time()); if (lifetime > aconf->lifetime) @@ -125,6 +154,7 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p /* already expired, hmm */ if (aconf->lifetime <= rb_current_time()) return 0; + /* Deactivate, it will be reactivated later if appropriate. */ deactivate_conf(aconf, ptr); rb_free(aconf->user); aconf->user = NULL; @@ -139,6 +169,7 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p } else { + /* New ban mask. */ aconf = make_conf(); aconf->status = CONF_ILLEGAL | ntype; aconf->lifetime = lifetime; @@ -152,21 +183,60 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p aconf->info.oper = operhash_add(oper); aconf->created = created; aconf->hold = hold; - p = strchr(parv[parc - 1], '|'); - if (p == NULL) + if (ntype != CONF_KILL || (p = strchr(parv[parc - 1], '|')) == NULL) aconf->passwd = rb_strdup(parv[parc - 1]); else { aconf->passwd = rb_strndup(parv[parc - 1], p - parv[parc - 1] + 1); aconf->spasswd = rb_strdup(p + 1); } - if (act && hold != created) + /* The ban is fully filled in and in the prop_bans list + * but still deactivated. Now determine if it should be activated + * and send the server notices. + */ + /* We only reject *@* and the like here. + * Otherwise malformed bans are fairly harmless and can be removed. + */ + switch (ntype) + { + case CONF_KILL: + valid = valid_wild_card(aconf->user, aconf->host); + break; + case CONF_RESV_CHANNEL: + valid = 1; + break; + default: + valid = valid_wild_card_simple(aconf->host); + break; + } + if (act && hold != created && !valid) + { + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "Ignoring global %d min. %s from %s%s%s for [%s%s%s]: too few non-wildcard characters", + (int)((hold - rb_current_time()) / 60), + stype, + IsServer(source_p) ? source_p->name : get_oper_name(source_p), + strcmp(parv[7], "*") ? " on behalf of " : "", + strcmp(parv[7], "*") ? parv[7] : "", + aconf->user ? aconf->user : "", + aconf->user ? "@" : "", + aconf->host); + if(IsPerson(source_p)) + sendto_one_notice(source_p, + ":Your %s [%s%s%s] has too few non-wildcard characters", + stype, + aconf->user ? aconf->user : "", + aconf->user ? "@" : "", + aconf->host); + /* Propagate it, but do not apply it locally. */ + } + else if (act && hold != created) { /* Keep the notices in sync with modules/m_kline.c etc. */ sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s added global %d min. %s%s%s for [%s%s%s] [%s]", IsServer(source_p) ? source_p->name : get_oper_name(source_p), - (hold - rb_current_time()) / 60, + (int)((hold - rb_current_time()) / 60), stype, strcmp(parv[7], "*") ? " from " : "", strcmp(parv[7], "*") ? parv[7] : "", @@ -174,10 +244,12 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p aconf->user ? "@" : "", aconf->host, parv[parc - 1]); - ilog(L_KLINE, "%s %s %d %s %s %s", parv[1], + ilog(L_KLINE, "%s %s %d %s%s%s %s", parv[1], IsServer(source_p) ? source_p->name : get_oper_name(source_p), - (hold - rb_current_time()) / 60, - aconf->user, aconf->host, + (int)((hold - rb_current_time()) / 60), + aconf->user ? aconf->user : "", + aconf->user ? " " : "", + aconf->host, parv[parc - 1]); aconf->status &= ~CONF_ILLEGAL; } @@ -192,10 +264,17 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p aconf->host, strcmp(parv[7], "*") ? " on behalf of " : "", strcmp(parv[7], "*") ? parv[7] : ""); - ilog(L_KLINE, "U%s %s %s %s", parv[1], + ilog(L_KLINE, "U%s %s %s%s %s", parv[1], IsServer(source_p) ? source_p->name : get_oper_name(source_p), - aconf->user, aconf->host); + aconf->user ? aconf->user : "", + aconf->user ? " " : "", + aconf->host); } + /* If CONF_ILLEGAL is still set at this point, remove entries from the + * reject cache (for klines and xlines). + * If CONF_ILLEGAL is not set, add the ban to the type-specific data + * structure and take action on matched clients/channels. + */ switch (ntype) { case CONF_KILL: @@ -219,6 +298,26 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p check_klines(); } break; + case CONF_XLINE: + if (aconf->status & CONF_ILLEGAL) + remove_reject_mask(aconf->host, NULL); + else + { + rb_dlinkAddAlloc(aconf, &xline_conf_list); + check_xlines(); + } + break; + case CONF_RESV_CHANNEL: + if (!(aconf->status & CONF_ILLEGAL)) + { + add_to_resv_hash(aconf->host, aconf); + resv_chan_forcepart(aconf->host, aconf->passwd, hold - rb_current_time()); + } + break; + case CONF_RESV_NICK: + if (!(aconf->status & CONF_ILLEGAL)) + rb_dlinkAddAlloc(aconf, &resv_conf_list); + break; } sendto_server(client_p, NULL, CAP_BAN|CAP_TS6, NOCAPS, ":%s BAN %s %s %s %s %s %s %s :%s",