]> jfr.im git - irc/rqf/shadowircd.git/commitdiff
Remote d:lines implementation (based on ircd-seven's r230 by spb, Stephen Bennett...
authorValery Yatsko <redacted>
Sun, 20 Apr 2008 07:26:37 +0000 (11:26 +0400)
committerValery Yatsko <redacted>
Sun, 20 Apr 2008 07:26:37 +0000 (11:26 +0400)
include/s_newconf.h
modules/m_dline.c
modules/m_stats.c
src/newconf.c

index 083a90c01f8284fbc2d8cb1f0788a79d5bc49953..9c6dbdb130e2a4bab9501f2baa1e8e8c92dd3d87 100644 (file)
@@ -95,10 +95,14 @@ struct remote_conf
 #define SHARED_PRESV   0x0100
 #define SHARED_UNRESV  0x0200
 #define SHARED_REHASH  0x0400
+#define SHARED_TDLINE  0x0800
+#define SHARED_PDLINE  0x1000
+#define SHARED_UNDLINE 0x2000
 
 #define SHARED_ALL     (SHARED_TKLINE | SHARED_PKLINE | SHARED_UNKLINE |\
                        SHARED_PXLINE | SHARED_TXLINE | SHARED_UNXLINE |\
-                       SHARED_TRESV | SHARED_PRESV | SHARED_UNRESV)
+                       SHARED_TRESV | SHARED_PRESV | SHARED_UNRESV |\
+                       SHARED_TDLINE | SHARED_PDLINE | SHARED_UNDLINE)
 #define CLUSTER_ALL    (SHARED_ALL | SHARED_LOCOPS)
 
 /* flags used in hub/leaf */
index 97e0aa65733dde61e70855c47bdbaf1573e12f69..13b0701a60840db50f4b8bbd68d507563800ecfb 100644 (file)
 #include "modules.h"
 
 static int mo_dline(struct Client *, struct Client *, int, const char **);
+static int me_dline(struct Client *, struct Client *, int, const char **);
 static int mo_undline(struct Client *, struct Client *, int, const char **);
+static int me_undline(struct Client *, struct Client *, int, const char **);
 
 struct Message dline_msgtab = {
        "DLINE", 0, 0, 0, MFLG_SLOW,
-       {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_dline, 2}}
+       {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_dline, 3}, {mo_dline, 2}}
 };
 struct Message undline_msgtab = {
        "UNDLINE", 0, 0, 0, MFLG_SLOW,
-       {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_undline, 2}}
+       {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_undline, 1}, {mo_undline, 2}}
 };
 
 mapi_clist_av1 dline_clist[] = { &dline_msgtab, &undline_msgtab, NULL };
@@ -61,6 +63,8 @@ DECLARE_MODULE_AV1(dline, NULL, NULL, dline_clist, NULL, NULL, "$Revision: 3225
 static int valid_comment(char *comment);
 static int flush_write(struct Client *, FILE *, char *, char *);
 static int remove_temp_dline(struct ConfItem *);
+static int apply_dline(struct Client *, const char *, int, char *);\r
+static int apply_undline(struct Client *, const char *);
 
 /* mo_dline()
  * 
@@ -73,15 +77,10 @@ mo_dline(struct Client *client_p, struct Client *source_p,
 {
        char def[] = "No Reason";
        const char *dlhost;
-       char *oper_reason;
        char *reason = def;
-       struct rb_sockaddr_storage daddr;
        char cidr_form_host[HOSTLEN + 1];
-       struct ConfItem *aconf;
-       int bits;
-       char dlbuffer[IRCD_BUFSIZE];
-       const char *current_date;
        int tdline_time = 0;
+       const char *target_server = NULL;
        int loc = 1;
 
        if(!IsOperK(source_p))
@@ -94,72 +93,178 @@ mo_dline(struct Client *client_p, struct Client *source_p,
        if((tdline_time = valid_temp_time(parv[loc])) >= 0)
                loc++;
 
-       if(parc < loc + 1)
-       {
-               sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
-                          me.name, source_p->name, "DLINE");
-               return 0;
-       }
-
        dlhost = parv[loc];
        rb_strlcpy(cidr_form_host, dlhost, sizeof(cidr_form_host));
 
-       if(!parse_netmask(dlhost, NULL, &bits))
+       loc++;
+
+       if(parc >= loc+2 && !irccmp(parv[loc], "ON"))
+       {
+               target_server = parv[loc+1];
+               loc += 2;
+       }
+
+       if(parc >= loc + 1 && !EmptyString(parv[loc]))
+               reason = LOCAL_COPY(parv[loc]);
+
+       if(target_server != NULL)
        {
-               sendto_one(source_p, ":%s NOTICE %s :Invalid D-Line",
-                          me.name, source_p->name);
-               return 0;
+               sendto_match_servs(source_p, target_server,
+                               CAP_ENCAP, NOCAPS,
+                               "ENCAP %s DLINE %d %s :%s",
+                               target_server, tdline_time, dlhost, reason);
+
+               if(!match(target_server, me.name))
+                       return 0;
        }
 
-       loc++;
+       apply_dline(source_p, dlhost, tdline_time, reason);
+
+       check_dlines();
+       return 0;
+}
 
-       if(parc >= loc + 1)     /* host :reason */
+/* mo_undline()
+ *
+ *      parv[1] = dline to remove
+ */
+static int
+mo_undline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+       const char *cidr;
+       const char *target_server = NULL;
+
+       if(!IsOperK(source_p))
+       {
+               sendto_one(source_p, form_str(ERR_NOPRIVS),
+                          me.name, source_p->name, "unkline");
+               return 0;
+       }
+       cidr = parv[1];
+
+       if(parc >= 4 && !irccmp(parv[2], "ON"))
        {
-               if(!EmptyString(parv[loc]))
-                       reason = LOCAL_COPY(parv[loc]);
+               target_server = parv[3];
+               sendto_match_servs(source_p, target_server,
+                               CAP_ENCAP, NOCAPS,
+                               "ENCAP %s UNDLINE %s",
+                               target_server, cidr);
 
-               if(!valid_comment(reason))
-               {
-                       sendto_one(source_p,
-                                  ":%s NOTICE %s :Invalid character '\"' in comment",
-                                  me.name, source_p->name);
+               if(!match(target_server, me.name))
                        return 0;
-               }
        }
 
+       apply_undline(source_p, cidr);
+
+       return 0;
+}
+
+static int\r
+me_dline(struct Client *client_p, struct Client *source_p, int parc, const char **parv)\r
+{\r
+       int tdline_time = atoi(parv[1]);\r
+       /* Since this is coming over a server link, assume that the originating\r
+        * server did the relevant permission/sanity checks...\r
+        */\r
+\r
+       if(!IsPerson(source_p))\r
+               return 0;\r
+\r
+       if(!find_shared_conf(source_p->username, source_p->host,\r
+                               source_p->servptr->name, tdline_time > 0 ? SHARED_TDLINE : SHARED_PDLINE))\r
+       {\r
+               sendto_realops_snomask(SNO_DEBUG, L_NETWIDE, "undline failed %s %s %s",\r
+                               source_p->name, parv[1], parv[2]);\r
+               return 0;\r
+       }\r
+\r
+       apply_dline(source_p, parv[2], tdline_time, LOCAL_COPY(parv[3]));\r
+\r
+       check_dlines();\r
+       return 0;\r
+}\r
+\r
+static int\r
+me_undline(struct Client *client_p, struct Client *source_p, int parc, const char **parv)\r
+{\r
+       if(!IsPerson(source_p))\r
+               return 0;\r
+\r
+       if(!find_shared_conf(source_p->username, source_p->host,\r
+                               source_p->servptr->name, SHARED_UNDLINE))\r
+               return 0;\r
+\r
+       apply_undline(source_p, parv[1]);\r
+\r
+       return 0;\r
+}
+
+static int
+apply_dline(struct Client *source_p, const char *dlhost, int tdline_time, char *reason)
+{
+       struct ConfItem *aconf;
+       char *oper_reason;
+       char dlbuffer[IRCD_BUFSIZE];
+       const char *current_date;
+       struct rb_sockaddr_storage daddr;
+       int t = AF_INET, ty, b;
+       const char *creason;
+
+       ty = parse_netmask(dlhost, (struct sockaddr *)&daddr, &b);
+       if(ty == HM_HOST)
+       {
+               sendto_one(source_p, ":%s NOTICE %s :Invalid D-Line",
+                          me.name, source_p->name);
+               return 0;
+       }
+#ifdef RB_IPV6
+       if(ty == HM_IPV6)
+               t = AF_INET6;
+       else
+#endif
+               t = AF_INET;
+
+       /* This means dlines wider than /16 cannot be set remotely */
        if(IsOperAdmin(source_p))
        {
-               if(bits < 8)
+               if(b < 8)
                {
-                       sendto_one(source_p,
-                                  ":%s NOTICE %s :For safety, bitmasks less than 8 require conf access.",
-                                  me.name, parv[0]);
+                       sendto_one_notice(source_p,
+                                  ":For safety, bitmasks less than 8 require conf access.");
                        return 0;
                }
        }
        else
        {
-               if(bits < 16)
+               if(b < 16)
                {
-                       sendto_one(source_p,
-                                  ":%s NOTICE %s :Dline bitmasks less than 16 are for admins only.",
-                                  me.name, parv[0]);
+                       sendto_one_notice(source_p,
+                                  ":Dline bitmasks less than 16 are for admins only.");
                        return 0;
                }
        }
 
+       if(!valid_comment(reason))
+       {
+               sendto_one(source_p,
+                          ":%s NOTICE %s :Invalid character '\"' in comment",
+                          me.name, source_p->name);
+               return 0;
+       }
+
+       /* Look for an oper reason */
+       if((oper_reason = strchr(reason, '|')) != NULL)
+       {
+               *oper_reason = '\0';
+               oper_reason++;
+
+               if(!EmptyString(oper_reason))
+                       aconf->spasswd = rb_strdup(oper_reason);
+       }
+
        if(ConfigFileEntry.non_redundant_klines)
        {
-               const char *creason;
-               int t = AF_INET, ty, b;
-               ty = parse_netmask(dlhost, (struct sockaddr *)&daddr, &b);
-#ifdef RB_IPV6
-               if(ty == HM_IPV6)
-                       t = AF_INET6;
-                else
-#endif
-                       t = AF_INET;
-                                               
                if((aconf = find_dline((struct sockaddr *)&daddr, t)) != NULL)
                {
                        int bx;
@@ -170,11 +275,11 @@ mo_dline(struct Client *client_p, struct Client *source_p,
                                if(IsConfExemptKline(aconf))
                                        sendto_one(source_p,
                                                   ":%s NOTICE %s :[%s] is (E)d-lined by [%s] - %s",
-                                                  me.name, parv[0], dlhost, aconf->host, creason);
+                                                  me.name, source_p->name, dlhost, aconf->host, creason);
                                else
                                        sendto_one(source_p,
                                                   ":%s NOTICE %s :[%s] already D-lined by [%s] - %s",
-                                                  me.name, parv[0], dlhost, aconf->host, creason);
+                                                  me.name, source_p->name, dlhost, aconf->host, creason);
                                return 0;
                        }
                }
@@ -187,16 +292,6 @@ mo_dline(struct Client *client_p, struct Client *source_p,
        aconf->status = CONF_DLINE;
        aconf->host = rb_strdup(dlhost);
 
-       /* Look for an oper reason */
-       if((oper_reason = strchr(reason, '|')) != NULL)
-       {
-               *oper_reason = '\0';
-               oper_reason++;
-
-               if(!EmptyString(oper_reason))
-                       aconf->spasswd = rb_strdup(oper_reason);
-       }
-
        if(tdline_time > 0)
        {
                rb_snprintf(dlbuffer, sizeof(dlbuffer), 
@@ -208,7 +303,7 @@ mo_dline(struct Client *client_p, struct Client *source_p,
 
                if(EmptyString(oper_reason))
                {
-                       sendto_realops_snomask(SNO_GENERAL, L_ALL,
+                       sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
                                             "%s added temporary %d min. D-Line for [%s] [%s]",
                                             get_oper_name(source_p), tdline_time / 60,
                                             aconf->host, reason);
@@ -218,7 +313,7 @@ mo_dline(struct Client *client_p, struct Client *source_p,
                }
                else
                {
-                       sendto_realops_snomask(SNO_GENERAL, L_ALL,
+                       sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
                                             "%s added temporary %d min. D-Line for [%s] [%s|%s]",
                                             get_oper_name(source_p), tdline_time / 60,
                                             aconf->host, reason, oper_reason);
@@ -239,36 +334,19 @@ mo_dline(struct Client *client_p, struct Client *source_p,
                               oper_reason, current_date, 0);
        }
 
-       check_dlines();
        return 0;
 }
 
-/* mo_undline()
- *
- *      parv[1] = dline to remove
- */
 static int
-mo_undline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+apply_undline(struct Client *source_p, const char *cidr)
 {
        FILE *in;
        FILE *out;
        char buf[BUFSIZE], buff[BUFSIZE], temppath[BUFSIZE], *p;
        const char *filename, *found_cidr;
-       const char *cidr;
-       struct ConfItem *aconf;
        int pairme = NO, error_on_write = NO;
        mode_t oldumask;
-
-       rb_snprintf(temppath, sizeof(temppath), "%s.tmp", ConfigFileEntry.dlinefile);
-
-       if(!IsOperUnkline(source_p))
-       {
-               sendto_one(source_p, form_str(ERR_NOPRIVS),
-                          me.name, source_p->name, "unkline");
-               return 0;
-       }
-
-       cidr = parv[1];
+       struct ConfItem *aconf;
 
        if(parse_netmask(cidr, NULL, NULL) == HM_HOST)
        {
@@ -276,6 +354,8 @@ mo_undline(struct Client *client_p, struct Client *source_p, int parc, const cha
                return 0;
        }
 
+       rb_snprintf(temppath, sizeof(temppath), "%s.tmp", ConfigFileEntry.dlinefile);
+
        aconf = find_exact_conf_by_address(cidr, CONF_DLINE, NULL);
        if(aconf == NULL)
        {
@@ -288,7 +368,7 @@ mo_undline(struct Client *client_p, struct Client *source_p, int parc, const cha
        {
                sendto_one(source_p,
                           ":%s NOTICE %s :Un-dlined [%s] from temporary D-lines",
-                          me.name, parv[0], buf);
+                          me.name, source_p->name, buf);
                sendto_realops_snomask(SNO_GENERAL, L_ALL,
                                     "%s has removed the temporary D-Line for: [%s]",
                                     get_oper_name(source_p), buf);
@@ -300,14 +380,14 @@ mo_undline(struct Client *client_p, struct Client *source_p, int parc, const cha
 
        if((in = fopen(filename, "r")) == 0)
        {
-               sendto_one(source_p, ":%s NOTICE %s :Cannot open %s", me.name, parv[0], filename);
+               sendto_one(source_p, ":%s NOTICE %s :Cannot open %s", me.name, source_p->name, filename);
                return 0;
        }
 
        oldumask = umask(0);
        if((out = fopen(temppath, "w")) == 0)
        {
-               sendto_one(source_p, ":%s NOTICE %s :Cannot open %s", me.name, parv[0], temppath);
+               sendto_one(source_p, ":%s NOTICE %s :Cannot open %s", me.name, source_p->name, temppath);
                fclose(in);
                umask(oldumask);
                return 0;
@@ -336,7 +416,7 @@ mo_undline(struct Client *client_p, struct Client *source_p, int parc, const cha
                        continue;
                }
 
-               if(irccmp(found_cidr, aconf->host) == 0)
+               if(irccmp(found_cidr, cidr) == 0)
                {
                        pairme++;
                }
@@ -356,13 +436,13 @@ mo_undline(struct Client *client_p, struct Client *source_p, int parc, const cha
        {
                sendto_one(source_p,
                           ":%s NOTICE %s :Couldn't write D-line file, aborted", 
-                          me.name, parv[0]);
+                          me.name, source_p->name);
                return 0;
        }
        else if(!pairme)
        {
-               sendto_one_notice(source_p, ":Cannot find D-Line for %s in file",
-                          aconf->host);
+               sendto_one(source_p, ":%s NOTICE %s :No D-Line for %s",
+                          me.name, source_p->name, cidr);
 
                if(temppath != NULL)
                        (void) unlink(temppath);
@@ -375,13 +455,13 @@ mo_undline(struct Client *client_p, struct Client *source_p, int parc, const cha
                sendto_one_notice(source_p, ":Couldn't rename temp file, aborted");
                return 0;
        }
+       rehash_bans(0);
 
-       sendto_one(source_p, ":%s NOTICE %s :D-Line for [%s] is removed", me.name, parv[0], aconf->host);
-       sendto_realops_snomask(SNO_GENERAL, L_ALL,
-                            "%s has removed the D-Line for: [%s]", get_oper_name(source_p), aconf->host);
-       ilog(L_KLINE, "UD %s %s", get_oper_name(source_p), aconf->host);
 
-       delete_one_address_conf(aconf->host, aconf);
+       sendto_one(source_p, ":%s NOTICE %s :D-Line for [%s] is removed", me.name, source_p->name, cidr);
+       sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+                            "%s has removed the D-Line for: [%s]", get_oper_name(source_p), cidr);
+       ilog(L_KLINE, "UD %s %s", get_oper_name(source_p), cidr);
 
        return 0;
 }
index 8e3d1d29bee87910a28f8a3aba1e5bd091510724..45b9b38462e064ece8cdfca9efd7750dd261ae0a 100644 (file)
@@ -951,6 +951,9 @@ static struct shared_flags shared_flagtable[] =
        { SHARED_UNRESV,        'R' },
        { SHARED_LOCOPS,        'L' },
        { SHARED_REHASH,        'H' },
+       { SHARED_TDLINE,    'd' },
+       { SHARED_PDLINE,    'D' },
+       { SHARED_UNDLINE,   'E' },
        { 0,                    '\0'}
 };
 
index 52c3ec7e6eae016d36c701e0c24dfe8b2dd52319..5e72684601584b8cf4571f9a0e9ec478f0c928ad 100644 (file)
@@ -373,6 +373,10 @@ static struct mode_table shared_table[] =
        { "kline",      SHARED_PKLINE|SHARED_TKLINE     },
        { "xline",      SHARED_PXLINE|SHARED_TXLINE     },
        { "resv",       SHARED_PRESV|SHARED_TRESV       },
+       { "dline",  SHARED_PDLINE|SHARED_TDLINE },
+       { "tdline", SHARED_TDLINE       },
+       { "pdline", SHARED_PDLINE   },
+       { "undline",    SHARED_UNDLINE  },
        { "tkline",     SHARED_TKLINE   },
        { "unkline",    SHARED_UNKLINE  },
        { "txline",     SHARED_TXLINE   },