X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/5366977b4f3c7a50d170bf7a1e29b14c74944db7..08d11e34cc17e3045231729d87025a0cfa598f54:/modules/m_kline.c diff --git a/modules/m_kline.c b/modules/m_kline.c index 3c1c40f..376e7eb 100644 --- a/modules/m_kline.c +++ b/modules/m_kline.c @@ -21,7 +21,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: m_kline.c 3161 2007-01-25 07:23:01Z nenolod $ + * $Id: m_kline.c 3466 2007-05-19 23:36:51Z jilles $ */ #include "stdinc.h" @@ -46,6 +46,7 @@ #include "parse.h" #include "modules.h" #include "event.h" +#include "reject.h" static int mo_kline(struct Client *, struct Client *, int, const char **); static int ms_kline(struct Client *, struct Client *, int, const char **); @@ -65,7 +66,7 @@ struct Message unkline_msgtab = { }; mapi_clist_av1 kline_clist[] = { &kline_msgtab, &unkline_msgtab, NULL }; -DECLARE_MODULE_AV1(kline, NULL, NULL, kline_clist, NULL, NULL, "$Revision: 3161 $"); +DECLARE_MODULE_AV1(kline, NULL, NULL, kline_clist, NULL, NULL, "$Revision: 3466 $"); /* Local function prototypes */ static int find_user_host(struct Client *source_p, const char *userhost, char *user, char *host); @@ -83,9 +84,9 @@ static int already_placed_kline(struct Client *, const char *, const char *, int static void handle_remote_unkline(struct Client *source_p, const char *user, const char *host); -static void remove_permkline_match(struct Client *, const char *, const char *); +static void remove_permkline_match(struct Client *, struct ConfItem *); static int flush_write(struct Client *, FILE *, const char *, const char *); -static int remove_temp_kline(const char *, const char *); +static int remove_temp_kline(struct Client *, struct ConfItem *); /* mo_kline() * @@ -162,7 +163,7 @@ mo_kline(struct Client *client_p, struct Client *source_p, return 0; } /* if we have cluster servers, send it to them.. */ - else if(dlink_list_length(&cluster_conf_list) > 0) + else if(rb_dlink_list_length(&cluster_conf_list) > 0) cluster_generic(source_p, "KLINE", (tkline_time > 0) ? SHARED_TKLINE : SHARED_PKLINE, CAP_KLN, "%lu %s %s :%s", @@ -280,7 +281,7 @@ handle_remote_kline(struct Client *source_p, int tkline_time, char *oper_reason; if(!find_shared_conf(source_p->username, source_p->host, - source_p->user->server, + source_p->servptr->name, (tkline_time > 0) ? SHARED_TKLINE : SHARED_PKLINE)) return; @@ -353,6 +354,7 @@ mo_unkline(struct Client *client_p, struct Client *source_p, int parc, const cha char *host; char splat[] = "*"; char *h = LOCAL_COPY(parv[1]); + struct ConfItem *aconf; if(!IsOperUnkline(source_p)) { @@ -407,22 +409,21 @@ mo_unkline(struct Client *client_p, struct Client *source_p, int parc, const cha if(match(parv[3], me.name) == 0) return 0; } - else if(dlink_list_length(&cluster_conf_list) > 0) + else if(rb_dlink_list_length(&cluster_conf_list) > 0) cluster_generic(source_p, "UNKLINE", SHARED_UNKLINE, CAP_UNKLN, "%s %s", user, host); - if(remove_temp_kline(user, host)) + aconf = find_exact_conf_by_address(host, CONF_KILL, user); + if(aconf == NULL) { - sendto_one_notice(source_p, ":Un-klined [%s@%s] from temporary k-lines", user, host); - sendto_realops_snomask(SNO_GENERAL, L_ALL, - "%s has removed the temporary K-Line for: [%s@%s]", - get_oper_name(source_p), user, host); - ilog(L_KLINE, "UK %s %s %s", - get_oper_name(source_p), user, host); + sendto_one_notice(source_p, ":No K-Line for %s@%s", user, host); return 0; } - remove_permkline_match(source_p, host, user); + if(remove_temp_kline(source_p, aconf)) + return 0; + + remove_permkline_match(source_p, aconf); return 0; } @@ -465,26 +466,23 @@ me_unkline(struct Client *client_p, struct Client *source_p, int parc, const cha static void handle_remote_unkline(struct Client *source_p, const char *user, const char *host) { + struct ConfItem *aconf; + if(!find_shared_conf(source_p->username, source_p->host, - source_p->user->server, SHARED_UNKLINE)) + source_p->servptr->name, SHARED_UNKLINE)) return; - if(remove_temp_kline(user, host)) + aconf = find_exact_conf_by_address(host, CONF_KILL, user); + if(aconf == NULL) { - sendto_one_notice(source_p, - ":Un-klined [%s@%s] from temporary k-lines", - user, host); - - sendto_realops_snomask(SNO_GENERAL, L_ALL, - "%s has removed the temporary K-Line for: [%s@%s]", - get_oper_name(source_p), user, host); - - ilog(L_KLINE, "UK %s %s %s", - get_oper_name(source_p), user, host); + sendto_one_notice(source_p, ":No K-Line for %s@%s", user, host); return; } - remove_permkline_match(source_p, host, user); + if(remove_temp_kline(source_p, aconf)) + return; + + remove_permkline_match(source_p, aconf); } /* apply_kline() @@ -614,6 +612,11 @@ valid_wild_card(struct Client *source_p, const char *luser, const char *lhost) const char *p; char tmpch; int nonwild = 0; + int bitlen; + + /* user has no wildcards, always accept -- jilles */ + if (!strchr(luser, '?') && !strchr(luser, '*')) + return 1; /* check there are enough non wildcard chars */ p = luser; @@ -628,12 +631,23 @@ valid_wild_card(struct Client *source_p, const char *luser, const char *lhost) } /* try host, as user didnt contain enough */ - p = lhost; - while ((tmpch = *p++)) + /* special case for cidr masks -- jilles */ + if ((p = strrchr(lhost, '/')) != NULL && IsDigit(p[1])) { - if(!IsKWildChar(tmpch)) - if(++nonwild >= ConfigFileEntry.min_nonwildcard) - return 1; + bitlen = atoi(p + 1); + /* much like non-cidr for ipv6, rather arbitrary for ipv4 */ + if (bitlen > 0 && bitlen >= (strchr(lhost, ':') ? 4 * (ConfigFileEntry.min_nonwildcard - nonwild) : 6 - 2 * nonwild)) + return 1; + } + else + { + p = lhost; + while ((tmpch = *p++)) + { + if(!IsKWildChar(tmpch)) + if(++nonwild >= ConfigFileEntry.min_nonwildcard) + return 1; + } } sendto_one_notice(source_p, @@ -659,8 +673,8 @@ valid_comment(struct Client *source_p, char *comment) return 0; } - if(strlen(comment) > REASONLEN) - comment[REASONLEN] = '\0'; + if(strlen(comment) > BANREASONLEN) + comment[BANREASONLEN] = '\0'; return 1; } @@ -679,13 +693,16 @@ valid_comment(struct Client *source_p, char *comment) static int already_placed_kline(struct Client *source_p, const char *luser, const char *lhost, int tkline) { - const char *reason; + const char *reason, *p; struct irc_sockaddr_storage iphost, *piphost; struct ConfItem *aconf; - int t; - if(ConfigFileEntry.non_redundant_klines) + int t, bits; + + aconf = find_exact_conf_by_address(lhost, CONF_KILL, luser); + if (aconf == NULL && ConfigFileEntry.non_redundant_klines) { - if((t = parse_netmask(lhost, (struct sockaddr *)&iphost, NULL)) != HM_HOST) + bits = 0; + if((t = parse_netmask(lhost, (struct sockaddr *)&iphost, &bits)) != HM_HOST) { #ifdef IPV6 if(t == HM_IPV6) @@ -699,19 +716,31 @@ already_placed_kline(struct Client *source_p, const char *luser, const char *lho else piphost = NULL; - if((aconf = find_conf_by_address(lhost, NULL, NULL, (struct sockaddr *)piphost, CONF_KILL, t, luser))) + aconf = find_conf_by_address(lhost, NULL, NULL, (struct sockaddr *)piphost, CONF_KILL, t, luser); + if (aconf != NULL) { - /* setting a tkline, or existing one is perm */ - if(tkline || ((aconf->flags & CONF_FLAGS_TEMPORARY) == 0)) - { - reason = aconf->passwd ? aconf->passwd : ""; + /* The above was really a lookup of a single IP, + * so check if the new kline is wider than the + * existing one. + * -- jilles + */ + p = strchr(aconf->host, '/'); + if (bits > 0 && (p == NULL || bits < atoi(p + 1))) + aconf = NULL; + } + } + if (aconf != NULL) + { + /* setting a tkline, or existing one is perm */ + if(tkline || ((aconf->flags & CONF_FLAGS_TEMPORARY) == 0)) + { + reason = aconf->passwd ? aconf->passwd : ""; - sendto_one_notice(source_p, - ":[%s@%s] already K-Lined by [%s@%s] - %s", - luser, lhost, aconf->user, - aconf->host, reason); - return 1; - } + sendto_one_notice(source_p, + ":[%s@%s] already K-Lined by [%s@%s] - %s", + luser, lhost, aconf->user, + aconf->host, reason); + return 1; } } @@ -723,7 +752,7 @@ already_placed_kline(struct Client *source_p, const char *luser, const char *lho * hunts for a permanent kline, and removes it. */ static void -remove_permkline_match(struct Client *source_p, const char *host, const char *user) +remove_permkline_match(struct Client *source_p, struct ConfItem *aconf) { FILE *in, *out; int pairme = 0; @@ -732,9 +761,13 @@ remove_permkline_match(struct Client *source_p, const char *host, const char *us char matchbuf[BUFSIZE]; char temppath[BUFSIZE]; const char *filename; + const char *host, *user; mode_t oldumask; int matchlen; + host = aconf->host; + user = aconf->user; + ircsnprintf(temppath, sizeof(temppath), "%s.tmp", ConfigFileEntry.klinefile); @@ -804,7 +837,7 @@ remove_permkline_match(struct Client *source_p, const char *host, const char *us } else if(!pairme) { - sendto_one_notice(source_p, ":No K-Line for %s@%s", + sendto_one_notice(source_p, ":Cannot find K-Line for %s@%s in file", user, host); if(temppath != NULL) @@ -818,7 +851,6 @@ remove_permkline_match(struct Client *source_p, const char *host, const char *us sendto_one_notice(source_p, ":Couldn't rename temp file, aborted"); return; } - rehash_bans(0); sendto_one_notice(source_p, ":K-Line for [%s@%s] is removed", user, host); @@ -829,6 +861,10 @@ remove_permkline_match(struct Client *source_p, const char *host, const char *us ilog(L_KLINE, "UK %s %s %s", get_oper_name(source_p), user, host); + + remove_reject_mask(aconf->user, aconf->host); + delete_one_address_conf(aconf->host, aconf); + return; } @@ -874,41 +910,32 @@ flush_write(struct Client *source_p, FILE * out, const char *buf, const char *te * side effects - tries to unkline anything that matches */ static int -remove_temp_kline(const char *user, const char *host) +remove_temp_kline(struct Client *source_p, struct ConfItem *aconf) { - struct ConfItem *aconf; - dlink_node *ptr; - struct irc_sockaddr_storage addr, caddr; - int bits, cbits; - int mtype, ktype; + rb_dlink_node *ptr; int i; - mtype = parse_netmask(host, (struct sockaddr *)&addr, &bits); - for (i = 0; i < LAST_TEMP_TYPE; i++) { - DLINK_FOREACH(ptr, temp_klines[i].head) + RB_DLINK_FOREACH(ptr, temp_klines[i].head) { - aconf = ptr->data; - - ktype = parse_netmask(aconf->host, (struct sockaddr *)&caddr, &cbits); - - if(ktype != mtype || (user && irccmp(user, aconf->user))) - continue; - - if(ktype == HM_HOST) + if (aconf == ptr->data) { - if(irccmp(aconf->host, host)) - continue; + sendto_one_notice(source_p, + ":Un-klined [%s@%s] from temporary k-lines", + aconf->user, aconf->host); + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "%s has removed the temporary K-Line for: [%s@%s]", + get_oper_name(source_p), aconf->user, aconf->host); + + ilog(L_KLINE, "UK %s %s %s", + get_oper_name(source_p), + aconf->user, aconf->host); + dlinkDestroy(ptr, &temp_klines[i]); + remove_reject_mask(aconf->user, aconf->host); + delete_one_address_conf(aconf->host, aconf); + return YES; } - else if(bits != cbits || - !comp_with_mask_sock((struct sockaddr *)&addr, - (struct sockaddr *)&caddr, bits)) - continue; - - dlinkDestroy(ptr, &temp_klines[i]); - delete_one_address_conf(aconf->host, aconf); - return YES; } }