Add more G-line length tests. Resolves SF#2985922.
[ircu2.10.12-pk.git] / ircd / gline.c
index adb745cad8e280ffe90193967e284e7b9480160f..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"
@@ -86,11 +87,11 @@ struct Gline* BadChanGlineList = 0;
     /* Figure out the next pointer in list... */       \
     if ((((next) = (gl)->gl_next) || 1) &&             \
        /* Then see if it's expired */                  \
-       (gl)->gl_lifetime <= CurrentTime)               \
+       (gl)->gl_lifetime <= TStime())                  \
       /* Record has expired, so free the G-line */     \
       gline_free((gl));                                        \
     /* See if we need to expire the G-line */          \
-    else if ((((gl)->gl_expire > CurrentTime) ||        \
+    else if ((((gl)->gl_expire > TStime()) ||          \
              (((gl)->gl_flags &= ~GLINE_ACTIVE) && 0) ||       \
              ((gl)->gl_state = GLOCAL_GLOBAL)) && 0)   \
       ; /* empty statement */                          \
@@ -341,7 +342,7 @@ gline_propagate(struct Client *cptr, struct Client *sptr, struct Gline *gline)
                        GlineIsRemActive(gline) ? '+' : '-', gline->gl_user,
                        gline->gl_host ? "@" : "",
                        gline->gl_host ? gline->gl_host : "",
-                       gline->gl_expire - CurrentTime, gline->gl_lastmod,
+                       gline->gl_expire - TStime(), gline->gl_lastmod,
                        gline->gl_lifetime, gline->gl_reason);
 
   return 0;
@@ -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()
@@ -499,10 +508,13 @@ gline_add(struct Client *cptr, struct Client *sptr, char *userhost,
    * expiration time for greater than GLINE_MAX_EXPIRE.
    */
   if (!(flags & GLINE_FORCE) &&
-      (expire <= CurrentTime || expire > CurrentTime + GLINE_MAX_EXPIRE)) {
+      (expire <= TStime() || expire > TStime() + GLINE_MAX_EXPIRE)) {
     if (!IsServer(sptr) && MyConnect(sptr))
       send_reply(sptr, ERR_BADEXPIRE, expire);
     return 0;
+  } else if (expire <= TStime()) {
+    /* This expired G-line was forced to be added, so mark it inactive. */
+    flags &= ~GLINE_ACTIVE;
   }
 
   if (!lifetime) /* no lifetime set, use expiration time */
@@ -512,16 +524,17 @@ gline_add(struct Client *cptr, struct Client *sptr, char *userhost,
 
   /* Inform ops... */
   sendto_opmask_butone(0, ircd_strncmp(reason, "AUTO", 4) ? SNO_GLINE :
-                       SNO_AUTO, "%s adding %s %s for %s%s%s, expiring at "
+                       SNO_AUTO, "%s adding %s%s %s for %s%s%s, expiring at "
                        "%Tu: %s",
                        (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
                          cli_name(sptr) :
                          cli_name((cli_user(sptr))->server),
+                       (flags & GLINE_ACTIVE) ? "" : "deactivated ",
                       (flags & GLINE_LOCAL) ? "local" : "global",
                       (flags & GLINE_BADCHAN) ? "BADCHAN" : "GLINE", user,
                       (flags & (GLINE_BADCHAN|GLINE_REALNAME)) ? "" : "@",
                       (flags & (GLINE_BADCHAN|GLINE_REALNAME)) ? "" : host,
-                      expire + TSoffset, reason);
+                      expire, reason);
 
   /* and log it */
   log_write(LS_GLINE, L_INFO, LOG_NOSNOTICE,
@@ -530,7 +543,7 @@ gline_add(struct Client *cptr, struct Client *sptr, char *userhost,
            flags & GLINE_BADCHAN ? "BADCHAN" : "GLINE", user,
            flags & (GLINE_BADCHAN|GLINE_REALNAME) ? "" : "@",
            flags & (GLINE_BADCHAN|GLINE_REALNAME) ? "" : host,
-           expire + TSoffset, reason);
+           expire, reason);
 
   /* make the gline */
   agline = make_gline(user, host, reason, expire, lastmod, lifetime, flags);
@@ -588,14 +601,14 @@ gline_activate(struct Client *cptr, struct Client *sptr, struct Gline *gline,
                        GlineIsBadChan(gline) ? "BADCHAN" : "GLINE",
                        gline->gl_user, gline->gl_host ? "@" : "",
                        gline->gl_host ? gline->gl_host : "",
-                       gline->gl_expire + TSoffset, gline->gl_reason);
-  
+                       gline->gl_expire, gline->gl_reason);
+
   log_write(LS_GLINE, L_INFO, LOG_NOSNOTICE,
            "%#C activating global %s for %s%s%s, expiring at %Tu: %s", sptr,
            GlineIsBadChan(gline) ? "BADCHAN" : "GLINE", gline->gl_user,
            gline->gl_host ? "@" : "",
            gline->gl_host ? gline->gl_host : "",
-           gline->gl_expire + TSoffset, gline->gl_reason);
+           gline->gl_expire, gline->gl_reason);
 
   if (!(flags & GLINE_LOCAL)) /* don't propagate local changes */
     gline_propagate(cptr, sptr, gline);
@@ -656,14 +669,14 @@ gline_deactivate(struct Client *cptr, struct Client *sptr, struct Gline *gline,
                       msg, GlineIsBadChan(gline) ? "BADCHAN" : "GLINE",
                       gline->gl_user, gline->gl_host ? "@" : "",
                        gline->gl_host ? gline->gl_host : "",
-                      gline->gl_expire + TSoffset, gline->gl_reason);
+                      gline->gl_expire, gline->gl_reason);
 
   log_write(LS_GLINE, L_INFO, LOG_NOSNOTICE,
            "%#C %s %s for %s%s%s, expiring at %Tu: %s", sptr, msg,
            GlineIsBadChan(gline) ? "BADCHAN" : "GLINE", gline->gl_user,
            gline->gl_host ? "@" : "",
            gline->gl_host ? gline->gl_host : "",
-           gline->gl_expire + TSoffset, gline->gl_reason);
+           gline->gl_expire, gline->gl_reason);
 
   if (!(flags & GLINE_LOCAL)) /* don't propagate local changes */
     gline_propagate(cptr, sptr, gline);
@@ -675,42 +688,6 @@ gline_deactivate(struct Client *cptr, struct Client *sptr, struct Gline *gline,
   return 0;
 }
 
-/** Send a deactivation request for a locally unknown G-line.
- * @param[in] cptr Client that sent us the G-line modification.
- * @param[in] sptr Client that originated the G-line modification.
- * @param[in] userhost Text representation of G-line target.
- * @param[in] expire Expiration time of G-line.
- * @param[in] lastmod Last modification time of G-line.
- * @param[in] lifetime Lifetime of G-line.
- * @param[in] flags Bitwise combination of GLINE_* flags.
- * @return Zero.
- */
-int
-gline_forward_deactivation(struct Client *cptr, struct Client *sptr,
-                           char *userhost, time_t expire, time_t lastmod,
-                           time_t lifetime, unsigned int flags)
-{
-  char *msg = "deactivating unknown global";
-
-  if (!lifetime)
-    lifetime = expire;
-
-  /* Inform ops and log it */
-  sendto_opmask_butone(0, SNO_GLINE, "%s %s GLINE for %s, expiring at %Tu",
-                       (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
-                         cli_name(sptr) : cli_name((cli_user(sptr))->server),
-                      msg, userhost, expire + TSoffset);
-
-  log_write(LS_GLINE, L_INFO, LOG_NOSNOTICE,
-           "%#C %s GLINE for %s, expiring at %Tu", sptr, msg, userhost,
-           expire);
-
-  sendcmdto_serv_butone(sptr, CMD_GLINE, cptr, "* -%s %Tu %Tu %Tu",
-                        userhost, expire, lastmod, lifetime);
-
-  return 0;
-}
-
 /** Modify a global G-line.
  * @param[in] cptr Client that sent us the G-line modification.
  * @param[in] sptr Client that originated the G-line modification.
@@ -729,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));
@@ -759,7 +736,7 @@ gline_modify(struct Client *cptr, struct Client *sptr, struct Gline *gline,
   /* first, check out the expiration time... */
   if ((flags & GLINE_EXPIRE) && expire) {
     if (!(flags & GLINE_FORCE) &&
-       (expire <= CurrentTime || expire > CurrentTime + GLINE_MAX_EXPIRE)) {
+       (expire <= TStime() || expire > TStime() + GLINE_MAX_EXPIRE)) {
       if (!IsServer(sptr) && MyConnect(sptr)) /* bad expiration time */
        send_reply(sptr, ERR_BADEXPIRE, expire);
       return 0;
@@ -800,7 +777,7 @@ gline_modify(struct Client *cptr, struct Client *sptr, struct Gline *gline,
       (action == GLINE_LOCAL_DEACTIVATE &&
        (gline->gl_state == GLOCAL_DEACTIVATED)) ||
       /* can't activate an expired G-line */
-      IRCD_MAX(gline->gl_expire, expire) <= CurrentTime)
+      IRCD_MAX(gline->gl_expire, expire) <= TStime())
     action = GLINE_MODIFY; /* no activity state modifications */
 
   Debug((DEBUG_DEBUG,  "About to perform changes; flags 0x%04x, action %s",
@@ -873,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)
@@ -882,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",
@@ -905,7 +885,7 @@ gline_modify(struct Client *cptr, struct Client *sptr, struct Gline *gline,
                          flags & GLINE_OPERFORCE ? "!" : "", op,
                          gline->gl_user, gline->gl_host ? "@" : "",
                          gline->gl_host ? gline->gl_host : "",
-                         gline->gl_expire - CurrentTime, gline->gl_lastmod,
+                         gline->gl_expire - TStime(), gline->gl_lastmod,
                          gline->gl_lifetime, gline->gl_reason);
 
   /* OK, let's do the G-line... */
@@ -1081,7 +1061,7 @@ gline_burst(struct Client *cptr)
                    GlineIsRemActive(gline) ? '+' : '-', gline->gl_user,
                     gline->gl_host ? "@" : "",
                     gline->gl_host ? gline->gl_host : "",
-                   gline->gl_expire - CurrentTime, gline->gl_lastmod,
+                   gline->gl_expire - TStime(), gline->gl_lastmod,
                     gline->gl_lifetime, gline->gl_reason);
   }
 
@@ -1089,7 +1069,7 @@ gline_burst(struct Client *cptr)
     if (!GlineIsLocal(gline) && gline->gl_lastmod)
       sendcmdto_one(&me, CMD_GLINE, cptr, "* %c%s %Tu %Tu %Tu :%s",
                    GlineIsRemActive(gline) ? '+' : '-', gline->gl_user,
-                   gline->gl_expire - CurrentTime, gline->gl_lastmod,
+                   gline->gl_expire - TStime(), gline->gl_lastmod,
                    gline->gl_lifetime, gline->gl_reason);
   }
 }
@@ -1109,7 +1089,7 @@ gline_resend(struct Client *cptr, struct Gline *gline)
                GlineIsRemActive(gline) ? '+' : '-', gline->gl_user,
                gline->gl_host ? "@" : "",
                 gline->gl_host ? gline->gl_host : "",
-               gline->gl_expire - CurrentTime, gline->gl_lastmod,
+               gline->gl_expire - TStime(), gline->gl_lastmod,
                gline->gl_lifetime, gline->gl_reason);
 
   return 0;
@@ -1136,8 +1116,8 @@ gline_list(struct Client *sptr, char *userhost)
     send_reply(sptr, RPL_GLIST, gline->gl_user,
                gline->gl_host ? "@" : "",
                gline->gl_host ? gline->gl_host : "",
-              gline->gl_expire + TSoffset, gline->gl_lastmod,
-              gline->gl_lifetime + TSoffset,
+              gline->gl_expire, gline->gl_lastmod,
+              gline->gl_lifetime,
               GlineIsLocal(gline) ? cli_name(&me) : "*",
               gline->gl_state == GLOCAL_ACTIVATED ? ">" :
               (gline->gl_state == GLOCAL_DEACTIVATED ? "<" : ""),
@@ -1147,8 +1127,8 @@ gline_list(struct Client *sptr, char *userhost)
       send_reply(sptr, RPL_GLIST, gline->gl_user,
                 gline->gl_host ? "@" : "",
                 gline->gl_host ? gline->gl_host : "",
-                gline->gl_expire + TSoffset, gline->gl_lastmod,
-                gline->gl_lifetime + TSoffset,
+                gline->gl_expire, gline->gl_lastmod,
+                gline->gl_lifetime,
                 GlineIsLocal(gline) ? cli_name(&me) : "*",
                 gline->gl_state == GLOCAL_ACTIVATED ? ">" :
                 (gline->gl_state == GLOCAL_DEACTIVATED ? "<" : ""),
@@ -1157,8 +1137,8 @@ gline_list(struct Client *sptr, char *userhost)
 
     gliter(BadChanGlineList, gline, sgline) {
       send_reply(sptr, RPL_GLIST, gline->gl_user, "", "",
-                gline->gl_expire + TSoffset, gline->gl_lastmod,
-                gline->gl_lifetime + TSoffset,
+                gline->gl_expire, gline->gl_lastmod,
+                gline->gl_lifetime,
                 GlineIsLocal(gline) ? cli_name(&me) : "*",
                 gline->gl_state == GLOCAL_ACTIVATED ? ">" :
                 (gline->gl_state == GLOCAL_DEACTIVATED ? "<" : ""),
@@ -1186,8 +1166,8 @@ gline_stats(struct Client *sptr, const struct StatDesc *sd,
     send_reply(sptr, RPL_STATSGLINE, 'G', gline->gl_user,
               gline->gl_host ? "@" : "",
               gline->gl_host ? gline->gl_host : "",
-              gline->gl_expire + TSoffset, gline->gl_lastmod,
-              gline->gl_lifetime + TSoffset,
+              gline->gl_expire, gline->gl_lastmod,
+              gline->gl_lifetime,
               gline->gl_state == GLOCAL_ACTIVATED ? ">" :
               (gline->gl_state == GLOCAL_DEACTIVATED ? "<" : ""),
               GlineIsRemActive(gline) ? '+' : '-',