Add more G-line length tests. Resolves SF#2985922.
[ircu2.10.12-pk.git] / ircd / gline.c
index d2b2b9b7b68190a70f876aa31cf68137e8e4b3c5..9c3d2970e24df6a078e4c976cb94c64a2b7d8d36 100644 (file)
@@ -24,6 +24,7 @@
 #include "config.h"
 
 #include "gline.h"
+#include "channel.h"
 #include "client.h"
 #include "ircd.h"
 #include "ircd_alloc.h"
@@ -371,7 +372,7 @@ count_users(char *mask, int flags)
       continue;
 
     ircd_snprintf(0, namebuf, sizeof(namebuf), "%s@%s",
-                 cli_user(acptr)->username, cli_user(acptr)->host);
+                 cli_user(acptr)->username, cli_user(acptr)->realhost);
     ircd_snprintf(0, ipbuf, sizeof(ipbuf), "%s@%s", cli_user(acptr)->username,
                  ircd_ntoa(&cli_ip(acptr)));
 
@@ -448,13 +449,21 @@ gline_add(struct Client *cptr, struct Client *sptr, char *userhost,
   if (*userhost == '#' || *userhost == '&') {
     if ((flags & GLINE_LOCAL) && !HasPriv(sptr, PRIV_LOCAL_BADCHAN))
       return send_reply(sptr, ERR_NOPRIVILEGES);
+    /* Allow maximum channel name length, plus margin for wildcards. */
+    if (strlen(userhost+1) >= CHANNELLEN + 6)
+      return send_reply(sptr, ERR_LONGMASK);
 
     flags |= GLINE_BADCHAN;
     user = userhost;
     host = NULL;
   } else if (*userhost == '$') {
     switch (userhost[1]) {
-      case 'R': flags |= GLINE_REALNAME; break;
+      case 'R':
+        /* Allow REALLEN for the real name, plus margin for wildcards. */
+        if (strlen(userhost+2) >= REALLEN + 6)
+          return send_reply(sptr, ERR_LONGMASK);
+        flags |= GLINE_REALNAME;
+        break;
       default:
         /* uh, what to do here? */
         /* The answer, my dear Watson, is we throw a protocol_violation()
@@ -697,7 +706,7 @@ gline_modify(struct Client *cptr, struct Client *sptr, struct Gline *gline,
             time_t lastmod, time_t lifetime, unsigned int flags)
 {
   char buf[BUFSIZE], *op = "";
-  int pos = 0;
+  int pos = 0, non_auto = 0;
 
   assert(gline);
   assert(!GlineIsLocal(gline));
@@ -841,6 +850,7 @@ gline_modify(struct Client *cptr, struct Client *sptr, struct Gline *gline,
 
   /* Now, handle reason changes... */
   if (flags & GLINE_REASON) {
+    non_auto = non_auto || ircd_strncmp(gline->gl_reason, "AUTO", 4);
     MyFree(gline->gl_reason); /* release old reason */
     DupString(gline->gl_reason, reason); /* store new reason */
     if (pos < BUFSIZE)
@@ -850,7 +860,9 @@ gline_modify(struct Client *cptr, struct Client *sptr, struct Gline *gline,
   }
 
   /* All right, inform ops... */
-  sendto_opmask_butone(0, SNO_GLINE, "%s modifying global %s for %s%s%s:%s",
+  non_auto = non_auto || ircd_strncmp(gline->gl_reason, "AUTO", 4);
+  sendto_opmask_butone(0, non_auto ? SNO_GLINE : SNO_AUTO,
+                      "%s modifying global %s for %s%s%s:%s",
                       (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
                       cli_name(sptr) : cli_name((cli_user(sptr))->server),
                       GlineIsBadChan(gline) ? "BADCHAN" : "GLINE",