]> jfr.im git - irc/quakenet/newserv.git/blobdiff - glines/glines_commands.c
CHANSERV: remove accidental sendemail from SETEMAIL command.
[irc/quakenet/newserv.git] / glines / glines_commands.c
index c372140709ae007adefe8af57dc13d29a7c8255e..6a68484f3fdbd382f4aab206162d5a7247725064 100644 (file)
 #include "glines.h"
 #include "../trusts/trusts.h"
 
+#define BLOCK_CHASE_MIN 5 /* seconds to chase nicknames in block without -c */
+#define BLOCK_CHASE_MAX 1800 /* seconds to chase nicknames in block with -c */
+
 MODULE_VERSION("");
 
 static void registercommands(int, void *);
 static void deregistercommands(int, void *);
 
-static int parse_gline_flags(nick *sender, const char *flagparam, int *overridesanity, int *overridelimit, int *simulate, int *coff) {
+static int parse_gline_flags(nick *sender, const char *flagparam, int *overridesanity, int *overridelimit, int *simulate, int *chase, int *coff) {
   const char *pos;
 
   *coff = 0;
@@ -26,6 +29,9 @@ static int parse_gline_flags(nick *sender, const char *flagparam, int *overrides
   *overridelimit = 0;
   *simulate = 0;
 
+  if (chase)
+    *chase = 0;
+
   if (flagparam[0] == '-') {
     *coff = 1;
 
@@ -40,70 +46,101 @@ static int parse_gline_flags(nick *sender, const char *flagparam, int *overrides
        case 'S':
          *simulate = 1;
          break;
+        case 'c':
+          if (!chase)
+            goto invalid;
+
+          *chase = 1;
+          break;
        default:
-         controlreply(sender, "Invalid flag specified: %c", *pos);
-         return 0;
+          goto invalid;
       }
     }
   }
 
   return 1;
+
+invalid:
+  controlreply(sender, "Invalid flag specified: %c", *pos);
+  return 0;
 }
 
 static int glines_cmdblock(void *source, int cargc, char **cargv) {
   nick *sender = source;
-  nick *target;
+  nick *target, *wnp;
+  whowas *ww;
   int hits, duration, id;
-  int coff, overridesanity, overridelimit, simulate;
+  int coff, overridesanity, overridelimit, simulate, chase;
   char *reason;
   char creator[128];
   glinebuf gbuf;
+  int ownww;
 
   if (cargc < 1)
     return CMD_USAGE;
 
-  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, &coff))
+  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, &chase, &coff))
     return CMD_ERROR;
 
   if (cargc < 3 + coff)
     return CMD_USAGE;
 
+  duration = durationtolong(cargv[coff + 1]);
+
+  if (duration <= 0) {
+    controlreply(sender, "Invalid duration specified.");
+    return CMD_ERROR;
+  }
+
   target = getnickbynick(cargv[coff]);
 
   if (!target) {
-    controlreply(sender, "Sorry, couldn't find that user.");
-    return CMD_ERROR;
+    ww = whowas_chase(cargv[coff], chase ? BLOCK_CHASE_MAX : BLOCK_CHASE_MIN);
+   
+    if (!ww) {
+      controlreply(sender, "Sorry, couldn't find that user.%s", chase ? "" : " Use -c to chase whowas entries.");
+      return CMD_ERROR;
+    }
+   
+    ownww = 0;
+
+    controlreply(sender, "Found matching whowas record:");
+    controlreply(sender, "%s", whowas_format(ww));
+  } else {
+    ww = whowas_fromnick(target, 1);
+    ownww = 1;
   }
 
-  duration = durationtolong(cargv[coff + 1]);
+  wnp = &ww->nick;
 
-  if (duration <= 0) {
-    controlreply(sender, "Invalid duration specified.");
+  if (sender != target && (IsService(wnp) || IsOper(wnp) || NickOnServiceServer(wnp))) {
+    controlreply(sender, "Target user '%s' is an oper or a service. Not setting G-Lines.", wnp->nick);
     return CMD_ERROR;
   }
 
   rejoinline(cargv[coff + 2], cargc - coff - 2);
   reason = cargv[coff + 2];
 
-  if (sender->auth)
-    snprintf(creator, sizeof(creator), "#%s", sender->authname);
-  else
-    strncpy(creator, controlid(sender), sizeof(creator));
+  snprintf(creator, sizeof(creator), "#%s", sender->authname);
 
   glinebufinit(&gbuf, 0);
   glinebufcommentv(&gbuf, "BLOCK", cargc + coff - 1, cargv);
-  glinebufaddbynick(&gbuf, target, 0, creator, reason, getnettime() + duration, getnettime(), getnettime() + duration);
+  glinebufaddbywhowas(&gbuf, ww, 0, creator, reason, getnettime() + duration, getnettime(), getnettime() + duration);
 
   glinebufspew(&gbuf, sender);
 
   if (!glinebufchecksane(&gbuf, sender, overridesanity, overridelimit)) {
     glinebufabort(&gbuf);
+    if (ownww)
+      whowas_free(ww);
     controlreply(sender, "G-Lines failed sanity checks. Not setting G-Lines.");
     return CMD_ERROR;
   }
 
   if (simulate) {
     glinebufabort(&gbuf);
+    if (ownww)
+      whowas_free(ww);
     controlreply(sender, "Simulation complete. Not setting G-Lines.");
     return CMD_ERROR;
   }
@@ -111,7 +148,12 @@ static int glines_cmdblock(void *source, int cargc, char **cargv) {
   glinebufcounthits(&gbuf, &hits, NULL);
   id = glinebufcommit(&gbuf, 1);
 
-  controlwall(NO_OPER, NL_GLINES, "%s BLOCK'ed user '%s!%s@%s' for %s with reason '%s' (%d hits)", controlid(sender), target->nick, target->ident, target->host->name->content, longtoduration(duration, 0), reason, hits);
+  controlwall(NO_OPER, NL_GLINES, "%s BLOCK'ed user '%s!%s@%s' for %s with reason '%s' (%d hits)", controlid(sender),
+              wnp->nick, wnp->ident, wnp->host->name->content,
+              longtoduration(duration, 0), reason, hits);
+
+  if (ownww)
+    whowas_free(ww);
 
   controlreply(sender, "Done. G-Line transaction ID: %d", id);
 
@@ -132,7 +174,7 @@ static int glines_cmdgline(void *source, int cargc, char **cargv) {
   if (cargc < 1)
     return CMD_USAGE;
 
-  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, &coff))
+  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, NULL, &coff))
     return CMD_ERROR;
 
   if (cargc < 3 + coff)
@@ -164,10 +206,7 @@ static int glines_cmdgline(void *source, int cargc, char **cargv) {
   }
 #endif /* SNIRCD_VERSION */
 
-  if (sender->auth)
-    snprintf(creator, sizeof(creator), "#%s", sender->authname);
-  else
-    strncpy(creator, controlid(sender), sizeof(creator));
+  snprintf(creator, sizeof(creator), "#%s", sender->authname);
 
   glinebufinit(&gbuf, 0);
   glinebufcommentv(&gbuf, "GLINE", cargc + coff - 1, cargv);
@@ -218,7 +257,7 @@ static int glines_cmdsmartgline(void *source, int cargc, char **cargv) {
   if (cargc < 1)
     return CMD_USAGE;
 
-  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, &coff))
+  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, NULL, &coff))
     return CMD_ERROR;
 
   if (cargc < 3 + coff)
@@ -269,10 +308,7 @@ static int glines_cmdsmartgline(void *source, int cargc, char **cargv) {
     return CMD_ERROR;
   }
 
-  if (sender->auth)
-    snprintf(creator, sizeof(creator), "#%s", sender->authname);
-  else
-    strncpy(creator, controlid(sender), sizeof(creator));
+  snprintf(creator, sizeof(creator), "#%s", sender->authname);
 
   glinebufinit(&gbuf, 0);
   glinebufcommentv(&gbuf, "SMARTGLINE", cargc + coff - 1, cargv);
@@ -368,7 +404,7 @@ static int glines_cmdclearchan(void *source, int cargc, char **cargv) {
   if (cargc < 1)
     return CMD_USAGE;
 
-  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, &coff))
+  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, NULL, &coff))
     return CMD_ERROR;
 
   if (cargc < 2 + coff)
@@ -435,10 +471,7 @@ static int glines_cmdclearchan(void *source, int cargc, char **cargv) {
     (((nick **)victims.content)[slot]) = np;
   }
 
-  if (sender->auth)
-    snprintf(creator, sizeof(creator), "#%s", sender->authname);
-  else
-    strncpy(creator, controlid(sender), sizeof(creator));
+  snprintf(creator, sizeof(creator), "#%s", sender->authname);
 
   glinebufinit(&gbuf, 0);
   glinebufcommentv(&gbuf, "CLEARCHAN", cargc + coff - 1, cargv);
@@ -522,7 +555,7 @@ static int glines_cmdtrustgline(void *source, int cargc, char **cargv) {
   if (cargc < 1)
     return CMD_USAGE;
 
-  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, &coff))
+  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, NULL, &coff))
     return CMD_ERROR;
 
   if (cargc < 4 + coff)
@@ -545,16 +578,13 @@ static int glines_cmdtrustgline(void *source, int cargc, char **cargv) {
   rejoinline(cargv[coff + 3], cargc - coff - 3);
   reason = cargv[coff + 3];
 
-  if (sender->auth)
-    snprintf(creator, sizeof(creator), "#%s", sender->authname);
-  else
-    strncpy(creator, controlid(sender), sizeof(creator));
+  snprintf(creator, sizeof(creator), "#%s", sender->authname);
 
   glinebufinit(&gbuf, 0);
   glinebufcommentv(&gbuf, "TRUSTGLINE", cargc + coff - 1, cargv);
 
   for(th = tg->hosts; th; th = th->next) {
-    snprintf(mask, sizeof(mask), "*!%s@%s", cargv[1], trusts_cidr2str(&th->ip, th->bits));
+    snprintf(mask, sizeof(mask), "*!%s@%s", cargv[1], CIDRtostr(th->ip, th->bits));
     glinebufadd(&gbuf, mask, creator, reason, getnettime() + duration, getnettime(), getnettime() + duration);
   }
 
@@ -604,7 +634,7 @@ static int glines_cmdtrustungline(void *source, int cargc, char **cargv) {
   count = 0;
 
   for (th = tg->hosts; th; th = th->next) {
-    snprintf(mask, sizeof(mask), "*!%s@%s", cargv[1], trusts_cidr2str(&th->ip, th->bits));
+    snprintf(mask, sizeof(mask), "*!%s@%s", cargv[1], CIDRtostr(th->ip, th->bits));
 
     gl = findgline(mask);
 
@@ -694,8 +724,6 @@ static int glines_cmdglist(void *source, int cargc, char **cargv) {
     return CMD_ERROR;
   }
 
-  mask = cargv[0];
-
   if (cargc > 1) {
     char* ch = cargv[0];
 
@@ -751,6 +779,11 @@ static int glines_cmdglist(void *source, int cargc, char **cargv) {
 
   gline *searchgl = makegline(mask);
 
+  if (!searchgl) {
+    controlreply(sender, "Invalid G-line mask specified.");
+    return CMD_ERROR;
+  }
+
   for (gl = glinelist; gl; gl = next) {
     next = gl->next;
 
@@ -771,13 +804,14 @@ static int glines_cmdglist(void *source, int cargc, char **cargv) {
       if (!(gl->flags & GLINE_REALNAME))
         continue;
       if (flags & GLIST_EXACT) {
-        if (!glineequal(searchgl, gl)) {
+        if (!glineequal(searchgl, gl))
           continue;
-        }
       } else if (flags & GLIST_FIND) {
-        if (!gline_match_mask(searchgl, gl)) {
+        if (!gline_match_mask(gl, searchgl))
+          continue;
+      } else {
+        if (!match2strings(mask, glinetostring(gl)))
           continue;
-        }
       }
     } else {
       if (gl->flags & GLINE_REALNAME)
@@ -788,28 +822,29 @@ static int glines_cmdglist(void *source, int cargc, char **cargv) {
           if (!gl->reason || ircd_strcmp(mask, gl->reason->content) != 0)
             continue;
         } else if (flags & GLIST_FIND) {
-          if (!gl->reason || match(gl->reason->content, mask))
+          if (!gl->reason || !match2strings(gl->reason->content, mask))
             continue;
-        } else if (!gl->reason || match(mask, gl->reason->content))
+        } else if (!gl->reason || !match2strings(mask, gl->reason->content))
             continue;
       } else if (flags & GLIST_OWNER) {
         if (flags & GLIST_EXACT) {
           if (!gl->creator || ircd_strcmp(mask, gl->creator->content) != 0)
             continue;
         } else if (flags & GLIST_FIND) {
-          if (!gl->creator || match(gl->creator->content, mask))
+          if (!gl->creator || !match2strings(gl->creator->content, mask))
             continue;
-        } else if (!gl->creator || match(mask, gl->creator->content))
+        } else if (!gl->creator || !match2strings(mask, gl->creator->content))
           continue;
       } else {
         if (flags & GLIST_EXACT) {
-          if (!glineequal(searchgl, gl)) {
+          if (!glineequal(searchgl, gl))
             continue;
-          }
         } else if (flags & GLIST_FIND) {
-          if (!gline_match_mask(searchgl, gl)) {
+          if (!gline_match_mask(gl, searchgl))
+            continue;
+        } else {
+          if (!match2strings(mask, glinetostring(gl)))
             continue;
-          }
         }
       }
     }
@@ -968,7 +1003,7 @@ static void registercommands(int hooknum, void *arg) {
     return;
   commandsregistered = 1;
 
-  registercontrolhelpcmd("block", NO_OPER, 4, glines_cmdblock, "Usage: block ?flags? <nick> <duration> <reason>\nSets a gline using an appropriate mask given the user's nickname.\nFlags can be one or more of:\n-f - bypass sanity checks\n-l - bypass hit limits\n-S - simulate who the glines would hit");
+  registercontrolhelpcmd("block", NO_OPER, 4, glines_cmdblock, "Usage: block ?flags? <nick> <duration> <reason>\nSets a gline using an appropriate mask given the user's nickname.\nFlags can be one or more of:\n-f - bypass sanity checks\n-l - bypass hit limits\n-S - simulate who the glines would hit\n-c - chase nick across quits/kills/nick changes");
   registercontrolhelpcmd("gline", NO_OPER, 4, glines_cmdgline, "Usage: gline ?flags? <mask> <duration> <reason>\nSets a gline.\nFlags can be one or more of:\n-f - bypass sanity checks\n-l - bypass hit limits\n-S - simulate who the glines would hit");
   registercontrolhelpcmd("smartgline", NO_OPER, 4, glines_cmdsmartgline, "Usage: smartgline ?flags? <user@host> <duration> <reason>\nSets a gline. Automatically adjusts the mask depending on whether the specified mask is trusted.\nFlags can be one or more of:\n-f - bypass sanity checks\n-l - bypass hit limits\n-S - simulate who the glines would hit");
   registercontrolhelpcmd("ungline", NO_OPER, 1, glines_cmdungline, "Usage: ungline <mask>\nDeactivates a gline.");