]> jfr.im git - irc/quakenet/newserv.git/blobdiff - trusts/trusts_slave.c
CHANSERV: remove accidental sendemail from SETEMAIL command.
[irc/quakenet/newserv.git] / trusts / trusts_slave.c
index 262c101eb35ff2314234856086723bb63a00aa22..3986c3e05a7cc91e9ae25c2eaa49c1a6141a4b3b 100644 (file)
@@ -7,6 +7,7 @@
 #include "../core/config.h"
 #include "../core/error.h"
 #include "../control/control.h"
+#include "../lib/version.h"
 #include "../lib/sha1.h"
 #include "../lib/hmac.h"
 #include "../lib/irc_string.h"
 #include "../xsb/xsb.h"
 #include "trusts.h"
 
+MODULE_VERSION("");
+
 static int syncing, synced;
-static sstring *masterserver;
+static sstring *smasterserver;
 
 static unsigned int curlineno, totallines;
 static SHA1_CTX s;
@@ -25,21 +28,23 @@ void trusts_replication_createtables(void);
 void trusts_replication_swap(void);
 void trusts_replication_complete(int);
 
+static int masterserver(void *source);
+
 static void __abandonreplication(const char *fn, int line, char *error, ...) {
   va_list ap;
   char buf[512], buf2[600];
 
   va_start(ap, error);
-  vsnprintf(buf, sizeof(buf), "%s", ap);
+  vsnprintf(buf, sizeof(buf), error, ap);
   va_end(ap);
 
   snprintf(buf2, sizeof(buf2), "Error replicating (function: %s, line: %d): %s", fn, line, buf);
 
   Error("trusts_slave", ERR_ERROR, "%s", buf2);
 
-  syncing = 0;
+  syncing = synced = 0;
 
-  /* TODO: warn IRC */
+  controlwall(NO_DEVELOPER, NL_TRUSTS, "Warning: %s", buf2);
 }
 
 #define abandonreplication(x, ...) __abandonreplication(__FUNCTION__, __LINE__, x , # __VA_ARGS__)
@@ -91,13 +96,11 @@ static char *extractline(char *buf, int reset, int update, int final) {
         return NULL;
 
       if(lineno != curlineno) {
-        abandonreplication("unexpected line number");
-        Error("trusts_slave", ERR_ERROR, "Didn't get expected line number (%u vs. %u).", lineno, curlineno);
+        abandonreplication("unexpected line number (%u vs. %u)", lineno, curlineno);
         return NULL;
       }
       if(lineno > totallines) {
         abandonreplication("too many lines");
-        Error("trusts_slave", ERR_ERROR, "Too many lines received!");
         return NULL;
       }
 
@@ -119,6 +122,9 @@ static int xsb_trinit(void *source, int argc, char **argv) {
   char *buf;
   unsigned int forced;
 
+  if(!masterserver(source))
+    return CMD_ERROR;
+
   if(argc < 1) {
     abandonreplication("bad number of args");
     return CMD_ERROR;
@@ -138,7 +144,7 @@ static int xsb_trinit(void *source, int argc, char **argv) {
     return CMD_ERROR;
   }
 
-  if(!forced || synced)
+  if(!forced && synced)
     return CMD_OK;
 
   if(!extractline(argv[0], 1, 1, 0))
@@ -159,6 +165,9 @@ static int xsb_trdata(void *source, int argc, char **argv) {
   if(!syncing)
     return CMD_OK;
 
+  if(!masterserver(source))
+    return CMD_ERROR;
+
   if(argc < 1) {
     abandonreplication("bad number of args");
     return CMD_ERROR;
@@ -172,8 +181,7 @@ static int xsb_trdata(void *source, int argc, char **argv) {
     if(buf[0] == 'G') {
       trustgroup tg;
       if(!parsetg(&buf[2], &tg, 0)) {
-        abandonreplication("bad trustgroup line");
-        Error("trusts_slave", ERR_ERROR, "Bad trustgroup line: %s", buf);
+        abandonreplication("bad trustgroup line: %s", buf);
         return CMD_ERROR;
       }
       trustsdb_inserttg("replication_groups", &tg);
@@ -188,21 +196,17 @@ static int xsb_trdata(void *source, int argc, char **argv) {
       trusthost th;
 
       if(!parseth(&buf[2], &th, &tgid, 0)) {
-        abandonreplication("bad trusthost line");
-        Error("trusts_slave", ERR_ERROR, "Bad trusthost line: %s", buf);
+        abandonreplication("bad trusthost line: %s", buf);
         return CMD_ERROR;
       }
       trustsdb_insertth("replication_hosts", &th, tgid);
     } else {
-      abandonreplication("bad trust type");
+      abandonreplication("bad trust type: %c", buf[0]);
 
-      Error("trusts_slave", ERR_ERROR, "Bad trust type: %c", buf[0]);
       return CMD_ERROR;
     }
   } else {
-    abandonreplication("malformed line");
-
-    Error("trusts_slave", ERR_ERROR, "Malformed data line: %s", buf);
+    abandonreplication("malformed line: %s", buf);
   }
 
   return CMD_OK;
@@ -216,6 +220,9 @@ static int xsb_trfini(void *source, int argc, char **argv) {
   if(!syncing)
     return CMD_OK;
 
+  if(!masterserver(source))
+    return CMD_ERROR;
+
   if(argc < 1) {
     abandonreplication("bad number of args");
     return CMD_ERROR;
@@ -226,15 +233,13 @@ static int xsb_trfini(void *source, int argc, char **argv) {
     return CMD_ERROR;
 
   if((totallines + 1) != curlineno) {
-    abandonreplication("wrong number of lines received");
-    Error("trusts_slave", ERR_ERROR, "Wrong number of lines received (%u vs. %u).", totallines, curlineno - 1);
+    abandonreplication("wrong number of lines received: %u vs. %u", totallines, curlineno - 1);
     return CMD_ERROR;
   }
 
   SHA1Final(digest, &s);
-  if(strcasecmp(hmac_printhex(digest, digestbuf, SHA1_DIGESTSIZE), buf)) {
+  if(hmac_strcmp(hmac_printhex(digest, digestbuf, SHA1_DIGESTSIZE), buf)) {
     abandonreplication("digest mismatch");
-    Error("trusts_slave", ERR_ERROR, "Digest mismatch.");
     return CMD_ERROR;
   }
 
@@ -243,6 +248,7 @@ static int xsb_trfini(void *source, int argc, char **argv) {
   trusts_replication_swap();
 
   synced = 1;
+  syncing = 0;
 
   return CMD_OK;
 }
@@ -253,14 +259,16 @@ static int xsb_traddgroup(void *source, int argc, char **argv) {
   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");
-    Error("trusts_slave", ERR_ERROR, "Bad trustgroup line: %s", argv[0]);
+    abandonreplication("bad trustgroup line: %s", argv[0]);
     return CMD_ERROR;
   }
 
@@ -286,18 +294,20 @@ static int xsb_traddhost(void *source, int argc, char **argv) {
   if(!synced)
     return CMD_OK;
 
+  if(!masterserver(source))
+    return CMD_ERROR;
+
   if(argc < 1) {
     abandonreplication("bad number of arguments");
     return CMD_ERROR;
   }
 
   if(!parseth(argv[0], &th, &tgid, 0)) {
-    abandonreplication("bad trusthost line");
-    Error("trusts_slave", ERR_ERROR, "Bad trusthost line: %s", argv[0]);
+    abandonreplication("bad trusthost line: %s", argv[0]);
     return CMD_ERROR;
   }
 
-  th.group = tg_inttotg(tgid);
+  th.group = tg_getbyid(tgid);
   if(!th.group) {
     abandonreplication("unable to lookup trustgroup");
     return CMD_ERROR;
@@ -312,46 +322,181 @@ 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;
 
+  if(!masterserver(source))
+    return CMD_ERROR;
+
   if(argc < 1) {
     abandonreplication("bad number of arguments");
     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;
 
+  if(!masterserver(source))
+    return CMD_ERROR;
+
   if(argc < 1) {
     abandonreplication("bad number of arguments");
     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 loaded;
+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;
+}
+
+static int xsb_trmodifyhost(void *source, int argc, char **argv) {
+  trustgroup *tg;
+  trusthost th, *oth;
+  unsigned int groupid;
+
+  if(!synced)
+    return CMD_OK;
+
+  if(!masterserver(source))
+    return CMD_ERROR;
+
+  if(argc < 1) {
+    abandonreplication("bad number of arguments");
+    return CMD_ERROR;
+  }
+
+  if(!parseth(argv[0], &th, &groupid, 0)) {
+    abandonreplication("bad trusthost line: %s", argv[0]);
+    return CMD_ERROR;
+  }
+
+  tg = tg_getbyid(groupid);
+
+  for(oth=tg->hosts;oth;oth=oth->next) {
+    if(ipmask_check(&oth->ip, &th.ip, th.bits) && th.bits == oth->bits)
+      break;
+  }
+
+  if(oth && !th_modify(oth, &th)) {
+    abandonreplication("unable to modify database");
+    return CMD_ERROR;
+  }
+
+  if(!oth) {
+    abandonreplication("unable to lookup host");
+    return CMD_ERROR;
+  }
+
+  th_update(oth);
+
+  return CMD_OK;
+}
+
+static int loaded, masternumeric = -1;
 static void *syncsched;
 
+static int masterserver(void *source) {
+  nick *np = source;
+  int home = homeserver(np->numeric);
+
+  if(home < 0)
+    return 0;
+
+  if(home != masternumeric) {
+    Error("trusts_slave", ERR_WARNING, "Command from server that isn't a master: %s", serverlist[home].name->content);
+    return 0;
+  }
+
+  return 1;
+}
+
 static void checksynced(void *arg) {
-  if(!synced || !syncing)
-    xsb_broadcast("trrequestsync", NULL, "%s", "");
+  if(!synced && !syncing)
+    xsb_broadcast("trrequeststart", NULL, "%s", "");
 }
 
 static int trusts_cmdtrustresync(void *source, int argc, char **argv) {
   nick *np = source;
 
-  if(syncing) {
-    controlreply(np, "Synchronisation is already in progress.");
-    return CMD_ERROR;
-  }
+  syncing = synced = 0;
 
-  synced = 0;
   checksynced(NULL);
   controlreply(np, "Synchronisation request sent.");
 
@@ -359,9 +504,10 @@ static int trusts_cmdtrustresync(void *source, int argc, char **argv) {
 }
 
 static void __serverlinked(int hooknum, void *arg) {
-  int servernum = (int)arg;
+  int servernum = (int)(long)arg;
 
-  if(!ircd_strcmp(serverlist[servernum].name->content, masterserver->content)) {
+  if(!ircd_strcmp(serverlist[servernum].name->content, smasterserver->content)) {
+    masternumeric = servernum;
     syncing = synced = 0;
     checksynced(NULL);
   }
@@ -376,13 +522,15 @@ void _init(void) {
     return;
   }
 
-  masterserver = getcopyconfigitem("trusts", "masterserver", "", 255);
-  if(!masterserver || !masterserver->content || !masterserver->content[0]) {
+  smasterserver = getcopyconfigitem("trusts", "masterserver", "", 255);
+  if(!smasterserver || !smasterserver->content || !smasterserver->content[0]) {
     Error("trusts_slave", ERR_ERROR, "No master server defined.");
-    freesstring(masterserver);
+    freesstring(smasterserver);
     return;
   }
 
+  masternumeric = findserver(smasterserver->content);
+
   loaded = 1;
 
   registercontrolhelpcmd("trustresync", NO_DEVELOPER, 0, trusts_cmdtrustresync, "Usage: trustresync");
@@ -394,6 +542,8 @@ 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);
+  xsb_addcommand("trmodifyhost", 1, xsb_trmodifyhost);
 
   registerhook(HOOK_SERVER_LINKED, __serverlinked);
   syncsched = schedulerecurring(time(NULL)+5, 0, 60, checksynced, NULL);
@@ -406,7 +556,7 @@ void _fini(void) {
   if(!loaded)
     return;
 
-  freesstring(masterserver);
+  freesstring(smasterserver);
 
   deregistercontrolcmd("trustresync", trusts_cmdtrustresync);
 
@@ -417,6 +567,8 @@ void _fini(void) {
   xsb_delcommand("traddgroup", xsb_traddgroup);
   xsb_delcommand("trdelhost", xsb_trdelhost);
   xsb_delcommand("trdelgroup", xsb_trdelgroup);
+  xsb_delcommand("trmodifygroup", xsb_trmodifygroup);
+  xsb_delcommand("trmodifyhost", xsb_trmodifyhost);
 
   deregisterhook(HOOK_SERVER_LINKED, __serverlinked);