]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Implement protected trust groups and limit access to some of the other functionality...
authorGunnar Beutner <redacted>
Sun, 23 Jun 2013 09:26:16 +0000 (11:26 +0200)
committerGunnar Beutner <redacted>
Sun, 23 Jun 2013 09:26:16 +0000 (11:26 +0200)
--HG--
branch : shroudtrusts

trusts/trusts.h
trusts/trusts_commands.c
trusts/trusts_db.c
trusts/trusts_management.c

index fbfad72c98db984f12790d0ad69613960daa0f2a..7576ba0363d358e7be16d9148c5b1a125064e675 100644 (file)
@@ -18,7 +18,7 @@
 
 #define MAXTGEXTS 5
 
-#define MAXTRUSTEDFOR 50000
+#define MAXTRUSTEDFOR 5000
 #define MAXDURATION 365 * 86400 * 20
 #define MAXPERIDENT 1000
 #define MAXPERNODE 1000
 
 #define TRUST_ENFORCE_IDENT 1 /* This must be 1 for compatibility with O. */
 #define TRUST_NO_CLEANUP 2
+#define TRUST_PROTECTED 4
+
+#define TRUST_MIN_UNPRIVILEGED_BITS_IPV4 (96 + 32)
+#define TRUST_MIN_UNPRIVILEGED_BITS_IPV6 32
+
+#define TRUST_MIN_UNPRIVILEGED_NODEBITS_IPV4 (96 + 24)
+#define TRUST_MIN_UNPRIVILEGED_NODEBITS_IPV6 48
 
 struct trustmigration;
 
index eca134eb9249489976390283ee55d30e13ff578d..d9d21d7b836c8707f2ce71a4ada9fb3e9f05ed46 100644 (file)
@@ -121,7 +121,8 @@ static void displaygroup(nick *sender, trustgroup *tg) {
   controlreply(sender, "Clients per user : %d (%senforcing ident)", tg->maxperident, (tg->flags & TRUST_ENFORCE_IDENT)?"":"not ");
   controlreply(sender, "Contact:         : %s", tg->contact->content);
   controlreply(sender, "Expires in       : %s", (tg->expires)?((tg->expires>t)?longtoduration(tg->expires - t, 2):"the past (will be removed during next cleanup)"):"never");
-  controlreply(sender, "CIDR clean-up    : %s", (tg->flags & TRUST_NO_CLEANUP)?"disabled":"enabled");
+  controlreply(sender, "CIDR cleanup     : %s", (tg->flags & TRUST_NO_CLEANUP)?"disabled":"enabled");
+  controlreply(sender, "Protected        : %s", (tg->flags & TRUST_PROTECTED)?"protected":"not protected");
   controlreply(sender, "Last changed by  : %s", tg->createdby->content);
   controlreply(sender, "Comment:         : %s", tg->comment->content);
   controlreply(sender, "ID:              : %u", tg->id);
index 63e128d472167475d68d745265cd1b19e090ced8..49c7fa65e664ab38599f72ce7809f22d11a50ae7 100644 (file)
@@ -332,7 +332,7 @@ void trustsdb_inserttg(char *table, trustgroup *tg) {
 
 void tg_update(trustgroup *tg) {
   trustsdb->squery(trustsdb,
-    "UPDATE ? SET name = ?, trustedfor = ?, maxperident = ?, maxusage = ?, expires = ?, lastseen = ?, lastmaxusereset = ?, createdby = ?, contact = ?, comment = ? WHERE id = ?",
+    "UPDATE ? SET name = ?, trustedfor = ?, flags = ?, maxperident = ?, maxusage = ?, expires = ?, lastseen = ?, lastmaxusereset = ?, createdby = ?, contact = ?, comment = ? WHERE id = ?",
     "Tsuuuutttsssu", "groups", tg->name->content, tg->trustedfor, tg->flags, tg->maxperident, tg->maxusage, tg->expires, tg->lastseen, tg->lastmaxusereset, tg->createdby->content, tg->contact->content, tg->comment->content, tg->id
   );
 }
index 12a3bd59b53b0f39a1aee8c5081857616ff1ceb9..52bc35abf11220ad7e44dc2b99f5f85ff7d27d49 100644 (file)
@@ -14,7 +14,7 @@
 static void registercommands(int, void *);
 static void deregistercommands(int, void *);
 
-typedef int (*trustmodificationfn)(void *, char *arg, int);
+typedef int (*trustmodificationfn)(void *, char *arg, nick *, int);
 
 struct trustmodification {
   char name[50];
@@ -44,6 +44,20 @@ static int trusts_cmdtrustadd(void *source, int cargc, char **cargv) {
     return CMD_ERROR;
   }
 
+  /* Don't allow non-developers to add trusts for large subnets or modify protected groups. */
+  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);
+      return CMD_ERROR;
+    }
+
+    if(tg->flags & TRUST_PROTECTED) {
+      controlreply(sender, "You don't have the necessary privileges to modify a protected trust group.");
+      return CMD_ERROR;
+    }
+  }
+
   /* OKAY! Lots of checking here!
    *
    * Need to check:
@@ -154,7 +168,7 @@ static int trusts_cmdtrustgroupadd(void *source, int cargc, char **cargv) {
 
   tg = tg_strtotg(name);
   if(tg) {
-    controlreply(sender, "A group with that name already exists");
+    controlreply(sender, "A group with that name already exists.");
     return CMD_ERROR;
   }
 
@@ -209,6 +223,14 @@ static int trusts_cmdtrustgroupdel(void *source, int cargc, char **cargv) {
     return CMD_ERROR;
   }
 
+  /* Don't allow non-developers to delete protected groups. */
+  if (!noperserv_policy_command_permitted(NO_DEVELOPER, sender)) {
+    if(tg->flags & TRUST_PROTECTED) {
+      controlreply(sender, "You don't have the necessary privileges to modify a protected trust group.");
+      return CMD_ERROR;
+    }
+  }
+
   if(tg->hosts) {
     controlreply(sender, "Delete all hosts before deleting the group.");
     return CMD_ERROR;
@@ -247,6 +269,20 @@ static int trusts_cmdtrustdel(void *source, int cargc, char **cargv) {
     return CMD_ERROR;
   }
 
+  /* Don't allow non-developers to remove trusts for large subnets or modify protected groups. */
+  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);
+      return CMD_ERROR;
+    }
+
+    if(tg->flags & TRUST_PROTECTED) {
+      controlreply(sender, "You don't have the necessary privileges to modify a protected trust group.");
+      return CMD_ERROR;
+    }
+  }
+
   for(th=tg->hosts;th;th=th->next)
     if(ipmask_check(&ip, &th->ip, th->bits) && th->bits == bits)
       break;
@@ -266,7 +302,7 @@ static int trusts_cmdtrustdel(void *source, int cargc, char **cargv) {
   return CMD_OK;
 }
 
-static int modifycomment(void *arg, char *comment, int override) {
+static int modifycomment(void *arg, char *comment, nick *source, int override) {
   trustgroup *tg = arg;
   sstring *n = getsstring(comment, COMMENTLEN);
   if(!n)
@@ -278,7 +314,7 @@ static int modifycomment(void *arg, char *comment, int override) {
   return 1;
 }
 
-static int modifycontact(void *arg, char *contact, int override) {
+static int modifycontact(void *arg, char *contact, nick *source, int override) {
   trustgroup *tg = arg;
   sstring *n = getsstring(contact, CONTACTLEN);
   if(!n)
@@ -290,31 +326,52 @@ static int modifycontact(void *arg, char *contact, int override) {
   return 1;
 }
 
-static int modifytrustedfor(void *arg, char *num, int override) {
+static int modifytrustedfor(void *arg, char *num, nick *source, int override) {
   trustgroup *tg = arg;
   unsigned int trustedfor = strtoul(num, NULL, 10);
 
-  if(!override && (trustedfor <= 0 || trustedfor > MAXTRUSTEDFOR))
+  if(trustedfor < 0) {
+    controlreply(source, "The clone limit must not be negative.");
     return 0;
+  }
+
+  if(!override) {
+    if (trustedfor == 0) {
+      controlreply(source, "You don't have the necessary privileges to set an unlimited clone limit.");
+      return 0;
+    }
+
+    if (trustedfor > MAXTRUSTEDFOR) {
+      controlreply(source, "You don't have the necessary privileges to set the clone limit to a value higher than %d.", MAXTRUSTEDFOR);
+      return 0;
+    }
+  }
 
   tg->trustedfor = trustedfor;
 
   return 1;
 }
 
-static int modifymaxperident(void *arg, char *num, int override) {
+static int modifymaxperident(void *arg, char *num, nick *source, int override) {
   trustgroup *tg = arg;
   unsigned int maxperident = strtoul(num, NULL, 10);
 
-  if(!override && (maxperident <= 0 || maxperident > MAXPERIDENT))
+  if(maxperident < 0) {
+    controlreply(source, "Ident limit must not be negative.");
     return 0;
+  }
+
+  if(maxperident > MAXPERIDENT) {
+    controlreply(source, "Ident limit must not be higher than %d. Consider setting it to 0 (unlimited) instead.", MAXPERIDENT);
+    return 0;
+  }
 
   tg->maxperident = maxperident;
 
   return 1;
 }
 
-static int modifyenforceident(void *arg, char *num, int override) {
+static int modifyenforceident(void *arg, char *num, nick *source, int override) {
   trustgroup *tg = arg;
 
   if(num[0] == '1') {
@@ -328,7 +385,7 @@ static int modifyenforceident(void *arg, char *num, int override) {
   return 1;
 }
 
-static int modifyexpires(void *arg, char *expires, int override) {
+static int modifyexpires(void *arg, char *expires, nick *source, int override) {
   trustgroup *tg = arg;
   int howlong = durationtolong(expires);
 
@@ -343,9 +400,12 @@ static int modifyexpires(void *arg, char *expires, int override) {
   return 1;
 }
 
-static int modifycleanup(void *arg, char *num, int override) {
+static int modifycleanup(void *arg, char *num, nick *source, int override) {
   trustgroup *tg = arg;
 
+  if(!override)
+    return 0;
+
   if(num[0] == '1') {
     tg->flags &= ~TRUST_NO_CLEANUP;
   } else if(num[0] == '0') {
@@ -357,30 +417,69 @@ static int modifycleanup(void *arg, char *num, int override) {
   return 1;
 }
 
-static int modifymaxpernode(void *arg, char *num, int override) {
+static int modifyprotected(void *arg, char *num, nick *source, int override) {
+  trustgroup *tg = arg;
+
+  if(!override) {
+    controlreply(source, "You don't have the necessary privileges to modify this attribute.");
+    return 0;
+  }
+
+  if(num[0] == '1') {
+    tg->flags |= TRUST_PROTECTED;
+  } else if(num[0] == '0') {
+    tg->flags &= ~TRUST_PROTECTED;
+  } else {
+    return 0;
+  }
+
+  return 1;
+}
+
+static int modifymaxpernode(void *arg, char *num, nick *source, int override) {
   trusthost *th = arg;
   int maxpernode = strtol(num, NULL, 10);
-  
-  if((maxpernode < 0) || (maxpernode > MAXPERNODE))
+
+  if(maxpernode < 0) {
+    controlreply(source, "Node limit must not be negative.");
+    return 0;
+  }
+
+  if(maxpernode>MAXPERNODE) {
+    controlreply(source, "Node limit must not be higher than %d. Consider setting it to 0 (unlimited) instead.", MAXPERNODE);
     return 0;
-  
+  } 
   th->maxpernode = maxpernode;
 
   return 1;
 }
 
-static int modifynodebits(void *arg, char *num, int override) {
+static int modifynodebits(void *arg, char *num, nick *source, int override) {
   trusthost *th = arg;
   int nodebits = strtol(num, NULL, 10);
 
-  if((nodebits < 0) || (nodebits > ((irc_in_addr_is_ipv4(&th->ip))?32:128)))
+  if(nodebits < 0) {
+    controlreply(source, "Node bits must not be negative.");
     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);
+      return 0;
+    }
+  }
 
   if(irc_in_addr_is_ipv4(&th->ip))
     nodebits += 96;
 
-  if(nodebits<th->bits)
+  if(nodebits<th->bits) {
+    controlreply(source, "Node bits must be smaller than the trusted CIDR's subnet size.");
     return 0;
+  }
 
   th->nodebits = nodebits;
 
@@ -413,10 +512,16 @@ static int trusts_cmdtrustgroupmodify(void *source, int cargc, char **cargv) {
 
   override = noperserv_policy_command_permitted(NO_DEVELOPER, sender);
 
+  /* Don't allow non-developers to modify protected groups. */
+  if (!override && tg->flags & TRUST_PROTECTED) {
+    controlreply(sender, "You don't have the necessary privileges to modify a protected trust group.");
+    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, override)) {
+      if(!(trustgroupmods[i].fn)(tg, to, sender, override)) {
         controlreply(sender, "An error occured changing that property, check the syntax.");
         return CMD_ERROR;
       }
@@ -468,6 +573,20 @@ static int trusts_cmdtrusthostmodify(void *source, int cargc, char **cargv) {
     return CMD_ERROR;
   }
 
+  /* Don't allow non-developers to modify trusts for large subnets or modify protected groups. */
+  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);
+      return CMD_ERROR;
+    }
+
+    if(tg->flags & TRUST_PROTECTED) {
+      controlreply(sender, "You don't have the necessary privileges to modify a protected trust group.");
+      return CMD_ERROR;
+    }
+  }
+
   th = th_getbyhostandmask(&ip, bits);
 
   if(!th || th->group != tg) {
@@ -483,7 +602,7 @@ static int trusts_cmdtrusthostmodify(void *source, int cargc, char **cargv) {
   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, override)) {
+      if(!(trusthostmods[i].fn)(th, to, sender, override)) {
         controlreply(sender, "An error occured changing that property, check the syntax.");
         return CMD_ERROR;
       }
@@ -644,6 +763,7 @@ static void setupmods(void) {
   MSGROUP(comment);
   MSGROUP(trustedfor);
   MSGROUP(cleanup);
+  MSGROUP(protected);
 
   MSHOST(maxpernode);
   MSHOST(nodebits);