]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Add trustmodify, trustdel, trustgroupdel commands and replication actions.
authorChris Porter <redacted>
Mon, 13 Oct 2008 04:36:46 +0000 (05:36 +0100)
committerChris Porter <redacted>
Mon, 13 Oct 2008 04:36:46 +0000 (05:36 +0100)
Haven't added functionality for del/groupdel yet though.

core/hooks.h
trusts/data.c
trusts/trusts.h
trusts/trusts_db.c
trusts/trusts_management.c
trusts/trusts_master.c
trusts/trusts_slave.c

index 78fdf51ca9afcc25a817290e8220723ff933b616..ced5f689f7507c8451a42b6417645f3e80445047 100644 (file)
@@ -85,6 +85,8 @@
 #define HOOK_TRUSTS_DELGROUP       907 /* Argument is trustgroup* */
 #define HOOK_TRUSTS_ADDHOST        908 /* Argument is trusthost* */
 #define HOOK_TRUSTS_DELHOST        909 /* Argument is trusthost* */
+#define HOOK_TRUSTS_MODIFYGROUP    910 /* Argument is trustgroup* */
+#define HOOK_TRUSTS_LOSTHOST       911 /* Argument is trusthost* */
 
 #define PRIORITY_DEFAULT           0
 
index 23aaaa76a91138b13f013665641954888873eab8..5c30046b262616114047a62a5cb4da4f7ac7d26c 100644 (file)
@@ -27,7 +27,7 @@ void trusts_freeall(void) {
       th_free(th);
     }
 
-    tg_free(tg);
+    tg_free(tg, 1);
   }
 
   tglist = NULL;
@@ -44,6 +44,8 @@ trustgroup *tg_getbyid(unsigned int id) {
 }
 
 void th_free(trusthost *th) {
+  triggerhook(HOOK_TRUSTS_LOSTHOST, th);
+
   nsfree(POOL_TRUSTS, th);
 }
 
@@ -100,8 +102,9 @@ trusthost *th_add(trusthost *ith) {
   return th;
 }
 
-void tg_free(trustgroup *tg) {
-  triggerhook(HOOK_TRUSTS_LOSTGROUP, tg);
+void tg_free(trustgroup *tg, int created) {
+  if(created)
+    triggerhook(HOOK_TRUSTS_LOSTGROUP, tg);
 
   freesstring(tg->name);
   freesstring(tg->createdby);
@@ -122,7 +125,7 @@ trustgroup *tg_add(trustgroup *itg) {
   tg->contact = getsstring(tg->contact->content, CONTACTLEN);
   tg->comment = getsstring(tg->comment->content, COMMENTLEN);
   if(!tg->name || !tg->createdby || !tg->contact || !tg->comment) {
-    tg_free(tg);
+    tg_free(tg, 0);
     return NULL;
   }
 
@@ -413,13 +416,47 @@ unsigned int nextthmarker(void) {
   return thmarker;
 }
 
-trustgroup *tg_inttotg(unsigned int id) {
+trusthost *th_getbyid(unsigned int id) {
   trustgroup *tg;
+  trusthost *th;
 
   for(tg=tglist;tg;tg=tg->next)
-    if(tg->id == id)
-      return tg;
+    for(th=tg->hosts;th;th=th->next)
+      if(th->id == id)
+        return th;
 
   return NULL;
 }
 
+int tg_modify(trustgroup *oldtg, trustgroup *newtg) {
+  trustgroup vnewtg;
+
+  memcpy(&vnewtg, oldtg, sizeof(trustgroup));
+
+  /* unfortunately we can't just memcpy the new one over */
+
+  vnewtg.name = getsstring(newtg->name->content, TRUSTNAMELEN);
+  vnewtg.createdby = getsstring(newtg->createdby->content, NICKLEN);
+  vnewtg.contact = getsstring(newtg->contact->content, CONTACTLEN);
+  vnewtg.comment = getsstring(newtg->comment->content, COMMENTLEN);
+  if(!vnewtg.name || !vnewtg.createdby || !vnewtg.contact || vnewtg.comment) {
+    freesstring(vnewtg.name);
+    freesstring(vnewtg.createdby);
+    freesstring(vnewtg.contact);
+    freesstring(vnewtg.comment);
+    return 0;
+  }
+
+  /* id remains the same, count/hosts/marker/next/exts are ignored */
+  vnewtg.trustedfor = newtg->trustedfor;
+  vnewtg.mode = newtg->mode;
+  vnewtg.maxperident = newtg->maxperident;
+  vnewtg.maxusage = newtg->maxusage;
+  vnewtg.expires = newtg->expires;
+  vnewtg.lastseen = newtg->lastseen;
+  vnewtg.lastmaxuserreset = newtg->lastmaxuserreset;
+
+  memcpy(oldtg, &vnewtg, sizeof(trustgroup));
+
+  return 1;
+}
index 2d2060e03b3432b8c06b654c0c3b4a56b954e2d9..de5523d5ea5b6097971b55b7480e9db62c84edc5 100644 (file)
 #define TRUSTHOSTLEN 100
 #define MAXTGEXTS 5
 
+#define MAXTRUSTEDFOR 50000
+#define MAXDURATION 365 * 86400 * 20
+#define MAXPERIDENT 1000
+
 #define TABLES_REGULAR 0
 #define TABLES_MIGRATION 1
 #define TABLES_REPLICATION 2
@@ -78,17 +82,6 @@ int registertgext(const char *);
 void releasetgext(int);
 int trusts_fullyonline(void);
 
-/* db.c */
-extern int trustsdbloaded;
-int trusts_loaddb(void);
-void trusts_closedb(int);
-trustgroup *tg_new(trustgroup *);
-trusthost *th_new(trustgroup *, char *);
-void trustsdb_insertth(char *, trusthost *, unsigned int);
-void trustsdb_inserttg(char *, trustgroup *);
-trustgroup *tg_copy(trustgroup *);
-trusthost *th_copy(trusthost *);
-
 /* formats.c */
 char *trusts_timetostr(time_t);
 int trusts_parsecidr(const char *, uint32_t *, short *);
@@ -105,7 +98,7 @@ extern trustgroup *tglist;
 trustgroup *tg_getbyid(unsigned int);
 void th_free(trusthost *);
 trusthost *th_add(trusthost *);
-void tg_free(trustgroup *);
+void tg_free(trustgroup *, int);
 trustgroup *tg_add(trustgroup *);
 trusthost *th_getbyhost(uint32_t);
 trusthost *th_getbyhostandmask(uint32_t, uint32_t);
@@ -118,13 +111,28 @@ trusthost *th_getnextsubsetbyhost(trusthost *th, uint32_t ip, uint32_t mask);
 void th_linktree(void);
 unsigned int nexttgmarker(void);
 unsigned int nextthmarker(void);
-trustgroup *tg_inttotg(unsigned int);
+trusthost *th_getbyid(unsigned int);
+int tg_modify(trustgroup *, trustgroup *);
 
 /* migration.c */
 typedef void (*TrustMigrationGroup)(void *, trustgroup *);
 typedef void (*TrustMigrationHost)(void *, trusthost *, unsigned int);
 typedef void (*TrustMigrationFini)(void *, int);
 
+/* trusts_db.c */
+extern int trustsdbloaded;
+int trusts_loaddb(void);
+void trusts_closedb(int);
+trustgroup *tg_new(trustgroup *);
+trusthost *th_new(trustgroup *, char *);
+void trustsdb_insertth(char *, trusthost *, unsigned int);
+void trustsdb_inserttg(char *, trustgroup *);
+trustgroup *tg_copy(trustgroup *);
+trusthost *th_copy(trusthost *);
+void tg_update(trustgroup *);
+void tg_delete(trustgroup *);
+void th_delete(trusthost *);
+
 typedef struct trustmigration {
   int count, cur;
   void *schedule;
index 35be76bbd2e399df420f9efe0a6256eb5e3308e7..a24958ea21fa3994b0a1995e98d87e862599336e 100644 (file)
@@ -314,6 +314,21 @@ void trustsdb_inserttg(char *table, trustgroup *tg) {
   );
 }
 
+void tg_update(trustgroup *tg) {
+  trustsdb->squery(trustsdb,
+    "UPDATE ? SET name = ?, trustedfor = ?, maxperident = ?, maxusage = ?, expires = ?, lastseen = ?, lastmaxuserreset = ?, createdby = ?, contact = ?, comment = ? WHERE id = ?",
+    "Tsuuuutttsssu", "groups", tg->name->content, tg->trustedfor, tg->mode, tg->maxperident, tg->maxusage, tg->expires, tg->lastseen, tg->lastmaxuserreset, tg->createdby->content, tg->contact->content, tg->comment->content, tg->id
+  );
+}
+
+void tg_delete(trustgroup *tg) {
+  /* TODO */
+}
+
+void th_delete(trusthost *th) {
+  /* TODO */
+}
+
 void _init(void) {
   trusts_connectdb();
 }
index 7a31f46ffd62bd79d708ba784e29559305ce996a..1bf5b1bd55120901fdf36598fb458ad75a754a5b 100644 (file)
@@ -4,11 +4,19 @@
 #include "../lib/irc_string.h"
 #include "../lib/strlfunc.h"
 #include "../core/config.h"
+#include "../lib/stringbuf.h"
 #include "trusts.h"
 
 static void registercommands(int, void *);
 static void deregistercommands(int, void *);
 
+typedef int (*trustmodificationfn)(trustgroup *, char *arg);
+
+struct trustmodification {
+  char *name;
+  trustmodificationfn fn;
+};
+
 static int trusts_cmdtrustadd(void *source, int cargc, char **cargv) {
   trustgroup *tg;
   nick *sender = source;
@@ -93,19 +101,19 @@ static int trusts_cmdtrustgroupadd(void *source, int cargc, char **cargv) {
 
   name = cargv[0];
   howmany = strtoul(cargv[1], NULL, 10);
-  if(!howmany || (howmany > 50000)) {
+  if(!howmany || (howmany > MAXTRUSTEDFOR)) {
     controlreply(sender, "Bad value maximum number of clients.");
     return CMD_ERROR;
   }
 
   howlong = durationtolong(cargv[2]);
-  if((howlong <= 0) || (howlong > 365 * 86400 * 20)) {
+  if((howlong <= 0) || (howlong > MAXDURATION)) {
     controlreply(sender, "Invalid duration supplied.");
     return CMD_ERROR;
   }
 
   maxperident = strtoul(cargv[3], NULL, 10);
-  if(!howmany || (maxperident > 1000)) {
+  if(!howmany || (maxperident > MAXPERIDENT)) {
     controlreply(sender, "Bad value for max per ident.");
     return CMD_ERROR;
   }
@@ -171,6 +179,200 @@ static int trusts_cmdtrustgroupadd(void *source, int cargc, char **cargv) {
   return CMD_OK;
 }
 
+static int trusts_cmdtrustgroupdel(void *source, int cargc, char **cargv) {
+  trustgroup *tg;
+  nick *sender = source;
+
+  if(cargc < 1)
+    return CMD_USAGE;
+
+  tg = tg_strtotg(cargv[0]);
+  if(!tg) {
+    controlreply(sender, "Couldn't look up trustgroup.");
+    return CMD_ERROR;
+  }
+
+  if(tg->hosts) {
+    controlreply(sender, "Delete all hosts before deleting the group.");
+    return CMD_ERROR;
+  }
+
+  triggerhook(HOOK_TRUSTS_DELGROUP, tg);
+  tg_delete(tg);
+  controlreply(sender, "Group deleted.");
+
+  /* TODO: controlwall */
+  return CMD_OK;
+}
+
+static int trusts_cmdtrustdel(void *source, int cargc, char **cargv) {
+  trustgroup *tg;
+  trusthost *th;
+  uint32_t ip, mask;
+  nick *sender = source;
+
+  if(cargc < 2)
+    return CMD_USAGE;
+
+  tg = tg_strtotg(cargv[0]);
+  if(!tg) {
+    controlreply(sender, "Couldn't look up trustgroup.");
+    return CMD_ERROR;
+  }
+
+  if(!trusts_str2cidr(cargv[1], &ip, &mask)) {
+    controlreply(sender, "Invalid IP/mask.");
+    return CMD_ERROR;
+  }
+
+  for(th=tg->hosts;th;th=th->next)
+    if((th->ip == ip) && (th->mask == mask))
+      break;
+
+  if(!th) {
+    controlreply(sender, "Couldn't find that host in that group.");
+    return CMD_ERROR;
+  }
+
+  triggerhook(HOOK_TRUSTS_DELHOST, th);
+  th_delete(th);
+  controlreply(sender, "Host deleted.");
+
+  /* TODO: controlwall */
+  return CMD_OK;
+}
+
+static int modifyname(trustgroup *tg, char *name) {
+  sstring *n = getsstring(name, TRUSTNAMELEN);
+  if(!n)
+    return 0;
+
+  freesstring(tg->name);
+  tg->name = n;
+
+  return 1;
+}
+
+static int modifycomment(trustgroup *tg, char *comment) {
+  sstring *n = getsstring(comment, COMMENTLEN);
+  if(!n)
+    return 0;
+
+  freesstring(tg->comment);
+  tg->comment = n;
+
+  return 1;
+}
+
+static int modifycontact(trustgroup *tg, char *contact) {
+  sstring *n = getsstring(contact, CONTACTLEN);
+  if(!n)
+    return 0;
+
+  freesstring(tg->contact);
+  tg->contact = n;
+
+  return 1;
+}
+
+static int modifytrustedfor(trustgroup *tg, char *num) {
+  unsigned int trustedfor = strtoul(num, NULL, 10);
+
+  if(trustedfor > MAXTRUSTEDFOR)
+    return 0;
+
+  tg->trustedfor = trustedfor;
+
+  return 1;
+}
+
+static int modifymaxperuser(trustgroup *tg, char *num) {
+  unsigned int maxperuser = strtoul(num, NULL, 10);
+
+  if(maxperuser > MAXPERIDENT)
+    return 0;
+
+  tg->maxperident = maxperuser;
+
+  return 1;
+}
+
+static int modifyenforceident(trustgroup *tg, char *num) {
+  if(num[0] == '1') {
+    tg->mode = 1;
+  } else if(num[0] == '0') {
+    tg->mode = 0;
+  } else {
+    return 0;
+  }
+
+  return 1;
+}
+
+static int modifyexpires(trustgroup *tg, char *expires) {
+  int howlong = durationtolong(expires);
+
+  if((howlong <= 0) || (howlong > MAXDURATION))
+    return 0;
+
+  tg->expires = time(NULL) + howlong;
+
+  return 1;
+}
+
+#define MS(x) (struct trustmodification){ .name = # x, .fn = modify ## x }
+
+static int trusts_cmdtrustgroupmodify(void *source, int cargc, char **cargv) {
+  trustgroup *tg;
+  nick *sender = source;
+  char *what, *to, validfields[512];
+  struct trustmodification *mods = (struct trustmodification []){ MS(expires), MS(enforceident), MS(maxperuser), MS(name), MS(contact), MS(comment), MS(trustedfor) };
+  int modcount = sizeof(mods) / sizeof(struct trustmodification);
+  int i;
+  StringBuf b;
+#undef MS
+
+  if(cargc < 3)
+    return CMD_USAGE;
+
+  tg = tg_strtotg(cargv[0]);
+  if(!tg) {
+    controlreply(sender, "Couldn't look up trustgroup.");
+    return CMD_ERROR;
+  }
+
+  what = cargv[1];
+  to = cargv[2];
+
+  sbinit(&b, validfields, sizeof(validfields));
+  for(i=0;i<modcount;i++) {
+    if(!strcmp(what, mods[i].name)) {
+      if(!(mods[i].fn)(tg, to)) {
+        controlreply(sender, "An error occured changing that property, check the syntax.");
+        return CMD_ERROR;
+      }
+      break;
+    }
+
+    if(i > 0)
+      sbaddstr(&b, ", ");
+    sbaddstr(&b, mods[i].name);
+  }
+
+  if(i == modcount) {
+    sbterminate(&b);
+    controlreply(sender, "No such field, valid fields are: %s", validfields);
+    return CMD_ERROR;
+  }
+
+  triggerhook(HOOK_TRUSTS_MODIFYGROUP, tg);
+  tg_update(tg);
+  controlreply(sender, "Group modified.");
+
+  /* TODO: controlwall */
+  return CMD_OK;
+}
+
 static int commandsregistered;
 
 static void registercommands(int hooknum, void *arg) {
@@ -180,6 +382,9 @@ static void registercommands(int hooknum, void *arg) {
 
   registercontrolhelpcmd("trustgroupadd", NO_OPER, 6, trusts_cmdtrustgroupadd, "Usage: trustgroupadd <name> <howmany> <howlong> <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>");
 }
 
 static void deregistercommands(int hooknum, void *arg) {
@@ -189,6 +394,9 @@ static void deregistercommands(int hooknum, void *arg) {
 
   deregistercontrolcmd("trustgroupadd", trusts_cmdtrustgroupadd);
   deregistercontrolcmd("trustadd", trusts_cmdtrustadd);
+  deregistercontrolcmd("trustgroupdel", trusts_cmdtrustgroupdel);
+  deregistercontrolcmd("trustdel", trusts_cmdtrustdel);
+  deregistercontrolcmd("trustgroupmodify", trusts_cmdtrustgroupmodify);
 }
 
 static int loaded;
index e992e3bca25eece5c8443890dafd10646f4cd9fe..6c3372c104605acf5aaadc6b617a26fef8203246 100644 (file)
@@ -103,6 +103,12 @@ static void hostremoved(int hooknum, void *arg) {
   xsb_broadcast("trdelhost", NULL, "%u", th->id);
 }
 
+static void groupmodified(int hooknum, void *arg) {
+  trustgroup *tg = arg;
+
+  xsb_broadcast("trmodifygroup", NULL, "%s", dumptg(tg, 0));
+}
+
 static int trusts_cmdtrustforceresync(void *source, int argc, char **argv) {
   nick *np = source;
 
@@ -126,6 +132,7 @@ static void __dbloaded(int hooknum, void *arg) {
   registerhook(HOOK_TRUSTS_DELGROUP, groupremoved);
   registerhook(HOOK_TRUSTS_ADDHOST, hostadded);
   registerhook(HOOK_TRUSTS_DELGROUP, hostremoved);
+  registerhook(HOOK_TRUSTS_MODIFYGROUP, groupmodified);
 
   /* we've just reloaded */
   /* if we're not online, no problem, other nodes will ask us individually */
@@ -146,6 +153,7 @@ static void __dbclosed(int hooknum, void *arg) {
   registerhook(HOOK_TRUSTS_DELGROUP, groupremoved);
   registerhook(HOOK_TRUSTS_ADDHOST, hostadded);
   registerhook(HOOK_TRUSTS_DELGROUP, hostremoved);
+  registerhook(HOOK_TRUSTS_MODIFYGROUP, groupmodified);
 
   deregistercontrolcmd("trustforceresync", trusts_cmdtrustforceresync);
 }
index 9b5dc4e1f44387c946d878c1332508c0aec08f1e..fef2171cae9c42da5b11b3fa299c1502e85855a3 100644 (file)
@@ -41,7 +41,7 @@ static void __abandonreplication(const char *fn, int line, char *error, ...) {
 
   syncing = 0;
 
-  /* TODO: warn IRC */
+  controlwall(NO_DEVELOPER, NL_TRUSTS, "Warning: %s", buf2);
 }
 
 #define abandonreplication(x, ...) __abandonreplication(__FUNCTION__, __LINE__, x , # __VA_ARGS__)
@@ -304,7 +304,7 @@ static int xsb_traddhost(void *source, int argc, char **argv) {
     return CMD_ERROR;
   }
 
-  th.group = tg_inttotg(tgid);
+  th.group = tg_getbyid(tgid);
   if(!th.group) {
     abandonreplication("unable to lookup trustgroup");
     return CMD_ERROR;
@@ -319,6 +319,9 @@ static int xsb_traddhost(void *source, int argc, char **argv) {
 }
 
 static int xsb_trdelhost(void *source, int argc, char **argv) {
+  unsigned int id;
+  trusthost *th;
+
   if(!synced)
     return CMD_OK;
 
@@ -330,10 +333,27 @@ static int xsb_trdelhost(void *source, int argc, char **argv) {
     return CMD_ERROR;
   }
 
+  id = strtoul(argv[0], NULL, 10);
+  if(!id) {
+    abandonreplication("unable to convert id to integer");
+    return CMD_ERROR;
+  }
+
+  th = th_getbyid(id);
+  if(!th) {
+    abandonreplication("unable to lookup id");
+    return CMD_ERROR;
+  }
+
+  th_delete(th);
+
   return CMD_OK;
 }
 
 static int xsb_trdelgroup(void *source, int argc, char **argv) {
+  unsigned int id;
+  trustgroup *tg;
+
   if(!synced)
     return CMD_OK;
 
@@ -345,6 +365,61 @@ static int xsb_trdelgroup(void *source, int argc, char **argv) {
     return CMD_ERROR;
   }
 
+  id = strtoul(argv[0], NULL, 10);
+  if(!id) {
+    abandonreplication("unable to convert id to integer");
+    return CMD_ERROR;
+  }
+
+  tg = tg_getbyid(id);
+  if(!tg) {
+    abandonreplication("unable to lookup id");
+    return CMD_ERROR;
+  }
+
+  tg_delete(tg);
+
+  return CMD_OK;
+}
+
+static int xsb_trmodifygroup(void *source, int argc, char **argv) {
+  trustgroup tg, *otg;
+
+  if(!synced)
+    return CMD_OK;
+
+  if(!masterserver(source))
+    return CMD_ERROR;
+
+  if(argc < 1) {
+    abandonreplication("bad number of arguments");
+    return CMD_ERROR;
+  }
+
+  if(!parsetg(argv[0], &tg, 0)) {
+    abandonreplication("bad trustgroup line: %s", argv[0]);
+    return CMD_ERROR;
+  }
+
+  otg = tg_getbyid(tg.id);
+
+  if(otg && !tg_modify(otg, &tg)) {
+    abandonreplication("unable to modify database");
+    return CMD_ERROR;
+  }
+
+  freesstring(tg.name);
+  freesstring(tg.createdby);
+  freesstring(tg.contact);
+  freesstring(tg.comment);
+
+  if(!otg) {
+    abandonreplication("unable to lookup id");
+    return CMD_ERROR;
+  }
+
+  tg_update(otg);
+
   return CMD_OK;
 }
 
@@ -421,6 +496,7 @@ void _init(void) {
   xsb_addcommand("traddgroup", 1, xsb_traddgroup);
   xsb_addcommand("trdelhost", 1, xsb_trdelhost);
   xsb_addcommand("trdelgroup", 1, xsb_trdelgroup);
+  xsb_addcommand("trmodifygroup", 1, xsb_trmodifygroup);
 
   registerhook(HOOK_SERVER_LINKED, __serverlinked);
   syncsched = schedulerecurring(time(NULL)+5, 0, 60, checksynced, NULL);
@@ -444,6 +520,7 @@ void _fini(void) {
   xsb_delcommand("traddgroup", xsb_traddgroup);
   xsb_delcommand("trdelhost", xsb_trdelhost);
   xsb_delcommand("trdelgroup", xsb_trdelgroup);
+  xsb_delcommand("trmodifygroup", xsb_trmodifygroup);
 
   deregisterhook(HOOK_SERVER_LINKED, __serverlinked);