]> jfr.im git - irc/quakenet/newserv.git/blobdiff - trusts/trusts_management.c
Merge chanserv-live into default.
[irc/quakenet/newserv.git] / trusts / trusts_management.c
index d6400ecdd8f5f81c0a772a364fb0472a88f112e7..8f72f4d6d501e339cc1e083b33e3af31fc1641fc 100644 (file)
@@ -8,8 +8,8 @@
 #include "../core/schedule.h"
 #include "../irc/irc.h"
 #include "../lib/stringbuf.h"
-#include "../noperserv/noperserv.h"
-#include "../noperserv/noperserv_policy.h"
+#include "../control/control.h"
+#include "../control/control_policy.h"
 #include "trusts.h"
 
 MODULE_VERSION("");
@@ -56,7 +56,7 @@ static int trusts_cmdtrustadd(void *source, int cargc, char **cargv) {
   if (!noperserv_policy_command_permitted(NO_DEVELOPER, sender)) {
     int minbits = irc_in_addr_is_ipv4(&ip)?TRUST_MIN_UNPRIVILEGED_BITS_IPV4:TRUST_MIN_UNPRIVILEGED_BITS_IPV6;
     if(bits < minbits) {
-      controlreply(sender, "You don't have the necessary privileges to add a subnet larger than /%d.", irc_in_addr_is_ipv4(&ip)?(minbits-96):minbits);
+      controlreply(sender, "You don't have the necessary privileges to add a subnet larger than /%d.", irc_bitlen(&ip, minbits));
       return CMD_ERROR;
     }
 
@@ -69,14 +69,14 @@ static int trusts_cmdtrustadd(void *source, int cargc, char **cargv) {
   /* OKAY! Lots of checking here!
    *
    * Need to check:
-   *   - host isn't already covered by given group (reject if it is)
+   *   - exact same host isn't already covered by given group (reject if it is)
    *   - host doesn't already exist exactly already (reject if it does)
    *   - host is more specific than an existing one (warn if it is, fix up later)
    *   - host is less specific than an existing one (warn if it is, don't need to do anything special)
    */
 
   for(th=tg->hosts;th;th=th->next) {
-    if(ipmask_check(&ip, &th->ip, th->bits)) {
+    if(ipmask_check(&ip, &th->ip, th->bits) && th->bits == bits) {
       controlreply(sender, "This host (or part of it) is already covered in the given group.");
       return CMD_ERROR;
     }
@@ -118,7 +118,7 @@ static int trusts_cmdtrustadd(void *source, int cargc, char **cargv) {
 static int trusts_cmdtrustgroupadd(void *source, int cargc, char **cargv) {
   nick *sender = source;
   char *name, *contact, *comment, createdby[ACCOUNTLEN + 2];
-  unsigned int howmany, maxperident, enforceident;
+  long howmany, maxperident, enforceident;
   trustgroup *tg, itg;
   int override, flags;
 
@@ -128,13 +128,13 @@ static int trusts_cmdtrustgroupadd(void *source, int cargc, char **cargv) {
   override = noperserv_policy_command_permitted(NO_DEVELOPER, sender);
 
   name = cargv[0];
-  howmany = strtoul(cargv[1], NULL, 10);
+  howmany = strtol(cargv[1], NULL, 10);
   if(!override && (!howmany || (howmany > MAXTRUSTEDFOR))) {
     controlreply(sender, "Bad value maximum number of clients.");
     return CMD_ERROR;
   }
 
-  maxperident = strtoul(cargv[2], NULL, 10);
+  maxperident = strtol(cargv[2], NULL, 10);
   if(maxperident < 0 || (maxperident > MAXPERIDENT)) {
     controlreply(sender, "Bad value for max per ident.");
     return CMD_ERROR;
@@ -155,7 +155,7 @@ static int trusts_cmdtrustgroupadd(void *source, int cargc, char **cargv) {
   }
 
   /* don't allow #id or id forms */
-  if((name[0] == '#') || strtoul(name, NULL, 10)) {
+  if((name[0] == '#') || strtol(name, NULL, 10)) {
     controlreply(sender, "Invalid trustgroup name.");
     return CMD_ERROR;
   }
@@ -275,7 +275,7 @@ static int trusts_cmdtrustdel(void *source, int cargc, char **cargv) {
   if (!noperserv_policy_command_permitted(NO_DEVELOPER, sender)) {
     int minbits = irc_in_addr_is_ipv4(&ip)?TRUST_MIN_UNPRIVILEGED_BITS_IPV4:TRUST_MIN_UNPRIVILEGED_BITS_IPV6;
     if(bits < minbits) {
-      controlreply(sender, "You don't have the necessary privileges to remove a subnet larger than /%d.", irc_in_addr_is_ipv4(&ip)?(minbits-96):minbits);
+      controlreply(sender, "You don't have the necessary privileges to remove a subnet larger than /%d.", irc_bitlen(&ip, minbits));
       return CMD_ERROR;
     }
 
@@ -330,7 +330,7 @@ static int modifycontact(void *arg, char *contact, nick *source, int override) {
 
 static int modifytrustedfor(void *arg, char *num, nick *source, int override) {
   trustgroup *tg = arg;
-  unsigned int trustedfor = strtoul(num, NULL, 10);
+  long trustedfor = strtol(num, NULL, 10);
 
   if(trustedfor < 0) {
     controlreply(source, "The clone limit must not be negative.");
@@ -356,7 +356,7 @@ static int modifytrustedfor(void *arg, char *num, nick *source, int override) {
 
 static int modifymaxperident(void *arg, char *num, nick *source, int override) {
   trustgroup *tg = arg;
-  unsigned int maxperident = strtoul(num, NULL, 10);
+  long maxperident = strtol(num, NULL, 10);
 
   if(maxperident < 0) {
     controlreply(source, "Ident limit must not be negative.");
@@ -401,6 +401,20 @@ static int modifyreliableusername(void *arg, char *num, nick *source, int overri
   return 1;
 }
 
+static int modifyunthrottle(void *arg, char *num, nick *source, int override) {
+  trustgroup *tg = arg;
+
+  if(num[0] == '1') {
+    tg->flags |= TRUST_UNTHROTTLE;
+  } else if(num[0] == '0') {
+    tg->flags &= ~TRUST_UNTHROTTLE;
+  } else {
+    return 0;
+  }
+
+  return 1;
+}
+
 static int modifyexpires(void *arg, char *expires, nick *source, int override) {
   trustgroup *tg = arg;
   int howlong = durationtolong(expires);
@@ -487,11 +501,16 @@ static int modifynodebits(void *arg, char *num, nick *source, int override) {
   if(irc_in_addr_is_ipv4(&th->ip))
     nodebits += 96;
 
+  if(nodebits > 128) {
+    controlreply(source, "Node bits is invalid.");
+    return 0;
+  }
+
   if(!override) {
     int minbits = irc_in_addr_is_ipv4(&th->ip)?TRUST_MIN_UNPRIVILEGED_NODEBITS_IPV4:TRUST_MIN_UNPRIVILEGED_NODEBITS_IPV6;
 
     if(nodebits < minbits) {
-      controlreply(source, "You don't have the necessary privileges to set node bits to a subnet larger than /%d.", irc_in_addr_is_ipv4(&th->ip)?(minbits-96):minbits);
+      controlreply(source, "You don't have the necessary privileges to set node bits to a subnet larger than /%d.", irc_bitlen(&th->ip, minbits));
       return 0;
     }
   }
@@ -514,9 +533,8 @@ static struct trustmodification *trusthostmods;
 static int trusts_cmdtrustgroupmodify(void *source, int cargc, char **cargv) {
   trustgroup *tg;
   nick *sender = source;
-  char *what, *to, validfields[512];
+  char *what, *to;
   int i, override;
-  StringBuf b;
 
   if(cargc < 3)
     return CMD_USAGE;
@@ -538,7 +556,6 @@ static int trusts_cmdtrustgroupmodify(void *source, int cargc, char **cargv) {
     return CMD_ERROR;
   }
 
-  sbinit(&b, validfields, sizeof(validfields));
   for(i=0;i<trustgroupmods_a.cursi;i++) {
     if(!strcmp(what, trustgroupmods[i].name)) {
       if(!(trustgroupmods[i].fn)(tg, to, sender, override)) {
@@ -547,17 +564,10 @@ static int trusts_cmdtrustgroupmodify(void *source, int cargc, char **cargv) {
       }
       break;
     }
-
-    if(i > 0)
-      sbaddstr(&b, ", ");
-    sbaddstr(&b, trustgroupmods[i].name);
   }
 
-  if(i == trustgroupmods_a.cursi) {
-    sbterminate(&b);
-    controlreply(sender, "No such field, valid fields are: %s", validfields);
-    return CMD_ERROR;
-  }
+  if(i == trustgroupmods_a.cursi)
+    return CMD_USAGE;
 
   triggerhook(HOOK_TRUSTS_MODIFYGROUP, tg);
   tg_update(tg);
@@ -573,9 +583,8 @@ static int trusts_cmdtrusthostmodify(void *source, int cargc, char **cargv) {
   trustgroup *tg;
   trusthost *th;
   nick *sender = source;
-  char *what, *to, validfields[512];
+  char *what, *to;
   int i, override;
-  StringBuf b;
   struct irc_in_addr ip;
   unsigned char bits;
 
@@ -597,7 +606,7 @@ static int trusts_cmdtrusthostmodify(void *source, int cargc, char **cargv) {
   if (!noperserv_policy_command_permitted(NO_DEVELOPER, sender)) {
     int minbits = irc_in_addr_is_ipv4(&ip)?TRUST_MIN_UNPRIVILEGED_BITS_IPV4:TRUST_MIN_UNPRIVILEGED_BITS_IPV6;
     if(bits < minbits) {
-      controlreply(sender, "You don't have the necessary privileges to modify a subnet larger than /%d.", irc_in_addr_is_ipv4(&ip)?(minbits-96):minbits);
+      controlreply(sender, "You don't have the necessary privileges to modify a subnet larger than /%d.", irc_bitlen(&ip, minbits));
       return CMD_ERROR;
     }
 
@@ -619,7 +628,6 @@ static int trusts_cmdtrusthostmodify(void *source, int cargc, char **cargv) {
 
   override = noperserv_policy_command_permitted(NO_DEVELOPER, sender);
 
-  sbinit(&b, validfields, sizeof(validfields));
   for(i=0;i<trusthostmods_a.cursi;i++) {
     if(!strcmp(what, trusthostmods[i].name)) {
       if(!(trusthostmods[i].fn)(th, to, sender, override)) {
@@ -628,24 +636,17 @@ static int trusts_cmdtrusthostmodify(void *source, int cargc, char **cargv) {
       }
       break;
     }
-
-    if(i > 0)
-      sbaddstr(&b, ", ");
-    sbaddstr(&b, trusthostmods[i].name);
   }
 
-  if(i == trusthostmods_a.cursi) {
-    sbterminate(&b);
-    controlreply(sender, "No such field, valid fields are: %s", validfields);
-    return CMD_ERROR;
-  }
+  if(i == trusthostmods_a.cursi)
+    return CMD_USAGE;
 
   triggerhook(HOOK_TRUSTS_MODIFYHOST, th);
   th_update(th);
   controlreply(sender, "Host modified.");
 
-  controlwall(NO_OPER, NL_TRUSTS, "%s TRUSTMODIFIED'ed host '%s' in group '%s' (field: %s, value: %s)", controlid(sender), trusts_cidr2str(&ip, bits), tg->name->content, what, to);
-  trustlog(tg, sender->authname, "Modified %s for host '%s': %s", what, trusts_cidr2str(&ip, bits), to);
+  controlwall(NO_OPER, NL_TRUSTS, "%s TRUSTMODIFIED'ed host '%s' in group '%s' (field: %s, value: %s)", controlid(sender), CIDRtostr(ip, bits), tg->name->content, what, to);
+  trustlog(tg, sender->authname, "Modified %s for host '%s': %s", what, CIDRtostr(ip, bits), to);
 
   return CMD_OK;
 }
@@ -654,13 +655,13 @@ static int trusts_cmdtrustlog(void *source, int cargc, char **cargv) {
   nick *sender = source;
   char *name;
   int groupid;
-  int limit = 0;
+  long limit = 0;
 
   if(cargc < 1)
     return CMD_USAGE;
 
   if(cargc>1)
-    limit = strtoul(cargv[1], NULL, 10);
+    limit = strtol(cargv[1], NULL, 10);
 
   if(limit==0)
     limit = 100;
@@ -668,7 +669,7 @@ static int trusts_cmdtrustlog(void *source, int cargc, char **cargv) {
   name = cargv[0];
 
   if (name[0] == '#') {
-    groupid = strtoul(name + 1, NULL, 10);
+    groupid = strtol(name + 1, NULL, 10);
     trustlogspewid(sender, groupid, limit);
   } else {
     trustlogspewname(sender, name, limit);
@@ -680,7 +681,7 @@ static int trusts_cmdtrustlog(void *source, int cargc, char **cargv) {
 static int trusts_cmdtrustloggrep(void *source, int cargc, char **cargv) {
   nick *sender = source;
   char *pattern;
-  int limit = 0;
+  long limit = 0;
 
   if(cargc < 1)
     return CMD_USAGE;
@@ -688,7 +689,7 @@ static int trusts_cmdtrustloggrep(void *source, int cargc, char **cargv) {
   pattern = cargv[0];
 
   if(cargc>1)
-    limit = strtoul(cargv[1], NULL, 10);
+    limit = strtol(cargv[1], NULL, 10);
 
   if(limit==0)
     limit = 100;
@@ -741,16 +742,42 @@ static int trusts_cmdtrustcleanup(void *source, int cargc, char **cargv) {
 static int commandsregistered;
 
 static void registercommands(int hooknum, void *arg) {
+  static char tgmhelp[512], thmhelp[512];
+  char validfields[512];
+  StringBuf b;
+  int i;
+
   if(commandsregistered)
     return;
   commandsregistered = 1;
 
-  registercontrolhelpcmd("trustgroupadd", NO_OPER, 7, trusts_cmdtrustgroupadd, "Usage: trustgroupadd <name> <howmany> <maxperident> <enforceident> <contact> ?comment?");
+  registercontrolhelpcmd("trustgroupadd", NO_OPER, 6, trusts_cmdtrustgroupadd, "Usage: trustgroupadd <name> <howmany> <maxperident> <enforceident> <contact> ?comment?");
   registercontrolhelpcmd("trustadd", NO_OPER, 2, trusts_cmdtrustadd, "Usage: trustadd <#id|name|id> <host>");
   registercontrolhelpcmd("trustgroupdel", NO_OPER, 1, trusts_cmdtrustgroupdel, "Usage: trustgroupdel <#id|name|id>");
   registercontrolhelpcmd("trustdel", NO_OPER, 2, trusts_cmdtrustdel, "Usage: trustdel <#id|name|id> <ip/mask>");
-  registercontrolhelpcmd("trustgroupmodify", NO_OPER, 3, trusts_cmdtrustgroupmodify, "Usage: trustgroupmodify <#id|name|id> <field> <new value>");
-  registercontrolhelpcmd("trusthostmodify", NO_OPER, 4, trusts_cmdtrusthostmodify, "Usage: trusthostmodify <#id|name|id> <host> <field> <new value>");
+
+  sbinit(&b, validfields, sizeof(validfields));
+  for(i=0;i<trustgroupmods_a.cursi;i++) {
+    if(i > 0)
+      sbaddstr(&b, ", ");
+    sbaddstr(&b, trustgroupmods[i].name);
+  }
+  sbterminate(&b);
+
+  snprintf(tgmhelp, sizeof(tgmhelp), "Usage: trustgroupmodify <#id|name|id> <field> <new value>\nModifies a trust group.\nValid fields: %s", validfields);
+  registercontrolhelpcmd("trustgroupmodify", NO_OPER, 3, trusts_cmdtrustgroupmodify, tgmhelp);
+
+  sbinit(&b, validfields, sizeof(validfields));
+  for(i=0;i<trusthostmods_a.cursi;i++) {
+    if(i > 0)
+      sbaddstr(&b, ", ");
+    sbaddstr(&b, trusthostmods[i].name);
+  }
+  sbterminate(&b);
+
+  snprintf(thmhelp, sizeof(thmhelp), "Usage: trusthostmodify <#id|name|id> <host> <field> <new value>\nModifies a trust host\nValid fields: %s", validfields);
+  registercontrolhelpcmd("trusthostmodify", NO_OPER, 4, trusts_cmdtrusthostmodify, thmhelp);
+
   registercontrolhelpcmd("trustlog", NO_OPER, 2, trusts_cmdtrustlog, "Usage: trustlog <#id|name> ?limit?\nShows log for the specified trust group.");
   registercontrolhelpcmd("trustloggrep", NO_OPER, 2, trusts_cmdtrustloggrep, "Usage trustloggrep <pattern> ?limit?\nShows maching log entries.");
   registercontrolhelpcmd("trustcomment", NO_OPER, 2, trusts_cmdtrustcomment, "Usage: trustcomment <#id|name> <comment>\nLogs a comment for a trust.");
@@ -790,6 +817,7 @@ static void setupmods(void) {
   MSGROUP(trustedfor);
   MSGROUP(cleanup);
   MSGROUP(protected);
+  MSGROUP(unthrottle);
 
   MSHOST(maxpernode);
   MSHOST(nodebits);
@@ -804,15 +832,18 @@ static void cleanuptrusts(void *arg) {
   trusthost *th;
   int thcount = 0, tgcount = 0;
   int i;
+  flag_t noticelevel;
   array expiredths, expiredtgs;
 
   now = getnettime();
   to_age = now - (CLEANUP_TH_INACTIVE * 3600 * 24);
 
   if(np) {
-    controlwall(NO_OPER, NL_TRUSTS, "CLEANUPTRUSTS: Manually started by %s.", np->nick);
+    noticelevel = NL_TRUSTS;
+    controlwall(NO_OPER, noticelevel, "CLEANUPTRUSTS: Manually started by %s.", np->nick);
   } else {
-    controlwall(NO_OPER, NL_TRUSTS, "CLEANUPTRUSTS: Automatically started.");
+    noticelevel = NL_CLEANUP;
+    controlwall(NO_OPER, noticelevel, "CLEANUPTRUSTS: Automatically started.");
   }
 
   if (cleanuptrusts_active) {
@@ -838,15 +869,16 @@ static void cleanuptrusts(void *arg) {
     }
 
     for(i=0;i<expiredths.cursi;i++) {
-      char *cidrstr;
+      const char *cidrstr;
 
       th = ((trusthost **)(expiredths.content))[i];
       triggerhook(HOOK_TRUSTS_DELHOST, th);
-      th_delete(th);
 
-      cidrstr = trusts_cidr2str(&th->ip, th->bits);
+      cidrstr = CIDRtostr(th->ip, th->bits);
       trustlog(tg, "cleanuptrusts", "Removed host '%s' because it was unused for %d days.", cidrstr, CLEANUP_TH_INACTIVE);
 
+      th_delete(th);
+
       thcount++;
     }
 
@@ -864,7 +896,7 @@ static void cleanuptrusts(void *arg) {
     tgcount++;
   }
 
-  controlwall(NO_OPER, NL_TRUSTS, "CLEANUPTRUSTS: Removed %d trust hosts (inactive for %d days) and %d empty trust groups.", thcount, CLEANUP_TH_INACTIVE, tgcount);
+  controlwall(NO_OPER, noticelevel, "CLEANUPTRUSTS: Removed %d trust hosts (inactive for %d days) and %d empty trust groups.", thcount, CLEANUP_TH_INACTIVE, tgcount);
 
   cleanuptrusts_active=0;
 }