]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - modules/m_kline.c
burst_TS6(): assume users have a UID
[irc/rqf/shadowircd.git] / modules / m_kline.c
index 0b31f409cf57ae83c4c97aefb2b4d60ce38f3f8a..2f888237325da5dfc3bfca6d780f42ba25133624 100644 (file)
  */
 
 #include "stdinc.h"
-#include "tools.h"
 #include "channel.h"
 #include "class.h"
 #include "client.h"
 #include "common.h"
-#include "irc_string.h"
-#include "sprintf_irc.h"
+#include "match.h"
 #include "ircd.h"
 #include "hostmask.h"
 #include "numeric.h"
-#include "commio.h"
 #include "s_conf.h"
 #include "s_newconf.h"
-#include "s_log.h"
+#include "logger.h"
 #include "send.h"
 #include "hash.h"
 #include "s_serv.h"
 #include "msg.h"
 #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 **);
@@ -83,9 +80,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 +159,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",
@@ -176,12 +173,12 @@ mo_kline(struct Client *client_p, struct Client *source_p,
        if(already_placed_kline(source_p, user, host, tkline_time))
                return 0;
 
-       set_time();
+       rb_set_time();
        current_date = smalldate();
        aconf = make_conf();
        aconf->status = CONF_KILL;
-       DupString(aconf->host, host);
-       DupString(aconf->user, user);
+       aconf->host = rb_strdup(host);
+       aconf->user = rb_strdup(user);
        aconf->port = 0;
 
        /* Look for an oper reason */
@@ -191,21 +188,21 @@ mo_kline(struct Client *client_p, struct Client *source_p,
                oper_reason++;
 
                if(!EmptyString(oper_reason))
-                       DupString(aconf->spasswd, oper_reason);
+                       aconf->spasswd = rb_strdup(oper_reason);
        }
 
        if(tkline_time > 0)
        {
-               ircsnprintf(buffer, sizeof(buffer),
+               rb_snprintf(buffer, sizeof(buffer),
                           "Temporary K-line %d min. - %s (%s)",
                           (int) (tkline_time / 60), reason, current_date);
-               DupString(aconf->passwd, buffer);
+               aconf->passwd = rb_strdup(buffer);
                apply_tkline(source_p, aconf, reason, oper_reason, current_date, tkline_time);
        }
        else
        {
-               ircsnprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
-               DupString(aconf->passwd, buffer);
+               rb_snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
+               aconf->passwd = rb_strdup(buffer);
                apply_kline(source_p, aconf, reason, oper_reason, current_date);
        }
 
@@ -213,7 +210,7 @@ mo_kline(struct Client *client_p, struct Client *source_p,
        {
                if(kline_queued == 0)
                {
-                       eventAddOnce("check_klines", check_klines_event, NULL,
+                       rb_event_addonce("check_klines", check_klines_event, NULL,
                                     ConfigFileEntry.kline_delay);
                        kline_queued = 1;
                }
@@ -280,7 +277,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;
 
@@ -295,8 +292,8 @@ handle_remote_kline(struct Client *source_p, int tkline_time,
        aconf = make_conf();
 
        aconf->status = CONF_KILL;
-       DupString(aconf->user, user);
-       DupString(aconf->host, host);
+       aconf->user = rb_strdup(user);
+       aconf->host = rb_strdup(host);
 
        /* Look for an oper reason */
        if((oper_reason = strchr(reason, '|')) != NULL)
@@ -305,23 +302,23 @@ handle_remote_kline(struct Client *source_p, int tkline_time,
                oper_reason++;
 
                if(!EmptyString(oper_reason))
-                       DupString(aconf->spasswd, oper_reason);
+                       aconf->spasswd = rb_strdup(oper_reason);
        }
 
        current_date = smalldate();
 
        if(tkline_time > 0)
        {
-               ircsnprintf(buffer, sizeof(buffer),
+               rb_snprintf(buffer, sizeof(buffer),
                           "Temporary K-line %d min. - %s (%s)",
                           (int) (tkline_time / 60), reason, current_date);
-               DupString(aconf->passwd, buffer);
+               aconf->passwd = rb_strdup(buffer);
                apply_tkline(source_p, aconf, reason, oper_reason, current_date, tkline_time);
        }
        else
        {
-               ircsnprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
-               DupString(aconf->passwd, buffer);
+               rb_snprintf(buffer, sizeof(buffer), "%s (%s)", reason, current_date);
+               aconf->passwd = rb_strdup(buffer);
                apply_kline(source_p, aconf, reason, oper_reason, current_date);
        }
 
@@ -329,7 +326,7 @@ handle_remote_kline(struct Client *source_p, int tkline_time,
        {
                if(kline_queued == 0)
                {
-                       eventAddOnce("check_klines", check_klines_event, NULL,
+                       rb_event_addonce("check_klines", check_klines_event, NULL,
                                     ConfigFileEntry.kline_delay);
                        kline_queued = 1;
                }
@@ -353,6 +350,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 +405,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 +462,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()
@@ -498,7 +492,7 @@ static void
 apply_kline(struct Client *source_p, struct ConfItem *aconf,
            const char *reason, const char *oper_reason, const char *current_date)
 {
-       add_conf_by_address(aconf->host, CONF_KILL, aconf->user, aconf);
+       add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf);
        write_confitem(KLINE_TYPE, source_p, aconf->user, aconf->host,
                       reason, oper_reason, current_date, 0);
 }
@@ -513,7 +507,7 @@ static void
 apply_tkline(struct Client *source_p, struct ConfItem *aconf,
             const char *reason, const char *oper_reason, const char *current_date, int tkline_time)
 {
-       aconf->hold = CurrentTime + tkline_time;
+       aconf->hold = rb_current_time() + tkline_time;
        add_temp_kline(aconf);
 
        /* no oper reason.. */
@@ -559,11 +553,11 @@ find_user_host(struct Client *source_p, const char *userhost, char *luser, char
        {
                *(hostp++) = '\0';      /* short and squat */
                if(*userhost)
-                       strlcpy(luser, userhost, USERLEN + 1);  /* here is my user */
+                       rb_strlcpy(luser, userhost, USERLEN + 1);       /* here is my user */
                else
                        strcpy(luser, "*");
                if(*hostp)
-                       strlcpy(lhost, hostp, HOSTLEN + 1);     /* here is my host */
+                       rb_strlcpy(lhost, hostp, HOSTLEN + 1);  /* here is my host */
                else
                        strcpy(lhost, "*");
                }
@@ -573,11 +567,14 @@ find_user_host(struct Client *source_p, const char *userhost, char *luser, char
                 * its a nick, which support was removed for.
                 */
                if(strchr(userhost, '.') == NULL && strchr(userhost, ':') == NULL)
+               {
+                       sendto_one_notice(source_p, ":K-Line must be a user@host or host");
                        return 0;
+               }
 
                luser[0] = '*'; /* no @ found, assume its *@somehost */
                luser[1] = '\0';
-               strlcpy(lhost, userhost, HOSTLEN + 1);
+               rb_strlcpy(lhost, userhost, HOSTLEN + 1);
        }
 
        return 1;
@@ -592,8 +589,9 @@ find_user_host(struct Client *source_p, const char *userhost, char *luser, char
 static int
 valid_user_host(struct Client *source_p, const char *luser, const char *lhost)
 {
-       /* # is invalid, as is '!' (n!u@h kline) */
-       if(strchr(lhost, '#') || strchr(luser, '#') || strchr(luser, '!'))
+       /* # is invalid, as are '!' (n!u@h kline) and '@' (u@@h kline) */
+       if(strchr(lhost, '#') || strchr(luser, '#') || strchr(luser, '!') ||
+                       strchr(lhost, '@'))
        {
                sendto_one_notice(source_p, ":Invalid K-Line");
                return 0;
@@ -695,15 +693,18 @@ 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;
-       struct irc_sockaddr_storage iphost, *piphost;
+       const char *reason, *p;
+       struct rb_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
+#ifdef RB_IPV6
                        if(t == HM_IPV6)
                                t = AF_INET6;
                        else
@@ -715,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, 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 : "<No Reason>";
+                       /* 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 : "<No Reason>";
 
-                               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;
                }
        }
 
@@ -739,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;
@@ -748,10 +761,14 @@ 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;
 
-       ircsnprintf(temppath, sizeof(temppath),
+       host = aconf->host;
+       user = aconf->user;
+
+       rb_snprintf(temppath, sizeof(temppath),
                 "%s.tmp", ConfigFileEntry.klinefile);
 
        filename = get_conf_name(KLINE_TYPE);
@@ -820,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)
@@ -834,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);
@@ -845,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;
 }
 
@@ -890,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);
+                               rb_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;
                }
        }