]>
jfr.im git - irc/quakenet/newserv.git/blob - trusts/trusts_slave.c
6 #include "../core/hooks.h"
7 #include "../core/config.h"
8 #include "../core/error.h"
9 #include "../control/control.h"
10 #include "../lib/sha1.h"
11 #include "../lib/hmac.h"
12 #include "../lib/irc_string.h"
13 #include "../core/schedule.h"
14 #include "../server/server.h"
15 #include "../xsb/xsb.h"
18 static int syncing
, synced
;
19 static sstring
*smasterserver
;
21 static unsigned int curlineno
, totallines
;
24 void trusts_replication_createtables(void);
25 void trusts_replication_swap(void);
26 void trusts_replication_complete(int);
28 static int masterserver(void *source
);
30 static void __abandonreplication(const char *fn
, int line
, char *error
, ...) {
32 char buf
[512], buf2
[600];
35 vsnprintf(buf
, sizeof(buf
), error
, ap
);
38 snprintf(buf2
, sizeof(buf2
), "Error replicating (function: %s, line: %d): %s", fn
, line
, buf
);
40 Error("trusts_slave", ERR_ERROR
, "%s", buf2
);
44 controlwall(NO_DEVELOPER
, NL_TRUSTS
, "Warning: %s", buf2
);
47 #define abandonreplication(x, ...) __abandonreplication(__FUNCTION__, __LINE__, x , # __VA_ARGS__)
49 void trusts_replication_complete(int error
) {
51 abandonreplication("final replication stage: error %d", error
);
54 Error("trusts_slave", ERR_INFO
, "Replication complete!");
56 if(!trusts_loaddb()) {
57 abandonreplication("couldn't load database");
64 static char *extractline(char *buf
, int reset
, int update
, int final
) {
65 unsigned char n
= '\n';
67 unsigned int lineno
, id
;
68 static unsigned int curid
;
70 if(sscanf(buf
, "%u %u %n", &id
, &lineno
, &chars
) != 2) {
71 abandonreplication("bad number for sscanf result");
76 abandonreplication("bad number of characters");
80 if(reset
&& (lineno
!= 1)) {
81 abandonreplication("bad initial line number");
91 /* will happen if two are sent at once, but that's ok */
95 if(lineno
!= curlineno
) {
96 abandonreplication("unexpected line number (%u vs. %u)", lineno
, curlineno
);
99 if(lineno
> totallines
) {
100 abandonreplication("too many lines");
109 SHA1Update(&s
, (unsigned char *)buf
, strlen(buf
));
110 SHA1Update(&s
, &n
, 1);
117 /* trinit id lineno force totallines */
118 static int xsb_trinit(void *source
, int argc
, char **argv
) {
122 if(!masterserver(source
))
126 abandonreplication("bad number of args");
130 buf
= extractline(argv
[0], 1, 0, 1);
134 if((sscanf(buf
, "%u %u", &forced
, &totallines
) != 2)) {
135 abandonreplication("bad number for sscanf result");
140 abandonreplication("bad number of lines");
144 if(!forced
&& synced
)
147 if(!extractline(argv
[0], 1, 1, 0))
150 trusts_replication_createtables();
154 Error("trusts_slave", ERR_INFO
, "Replication in progress. . .");
158 /* trdata id lines type data */
159 static int xsb_trdata(void *source
, int argc
, char **argv
) {
165 if(!masterserver(source
))
169 abandonreplication("bad number of args");
173 buf
= extractline(argv
[0], 0, 1, 0);
177 if(buf
[0] && (buf
[1] == ' ')) {
180 if(!parsetg(&buf
[2], &tg
, 0)) {
181 abandonreplication("bad trustgroup line: %s", buf
);
184 trustsdb_inserttg("replication_groups", &tg
);
186 freesstring(tg
.name
);
187 freesstring(tg
.createdby
);
188 freesstring(tg
.contact
);
189 freesstring(tg
.comment
);
191 } else if(buf
[0] == 'H') {
195 if(!parseth(&buf
[2], &th
, &tgid
, 0)) {
196 abandonreplication("bad trusthost line: %s", buf
);
199 trustsdb_insertth("replication_hosts", &th
, tgid
);
201 abandonreplication("bad trust type: %c", buf
[0]);
206 abandonreplication("malformed line: %s", buf
);
212 /* trfini id lines sha */
213 static int xsb_trfini(void *source
, int argc
, char **argv
) {
214 char *buf
, digestbuf
[SHA1_DIGESTSIZE
* 2 + 1];
215 unsigned char digest
[SHA1_DIGESTSIZE
];
220 if(!masterserver(source
))
224 abandonreplication("bad number of args");
228 buf
= extractline(argv
[0], 0, 1, 1);
232 if((totallines
+ 1) != curlineno
) {
233 abandonreplication("wrong number of lines received: %u vs. %u", totallines
, curlineno
- 1);
237 SHA1Final(digest
, &s
);
238 if(strcasecmp(hmac_printhex(digest
, digestbuf
, SHA1_DIGESTSIZE
), buf
)) {
239 abandonreplication("digest mismatch");
243 Error("trusts_slave", ERR_INFO
, "Data verification successful.");
245 trusts_replication_swap();
253 static int xsb_traddgroup(void *source
, int argc
, char **argv
) {
259 if(!masterserver(source
))
263 abandonreplication("bad number of arguments");
267 if(!parsetg(argv
[0], &tg
, 0)) {
268 abandonreplication("bad trustgroup line: %s", argv
[0]);
274 freesstring(tg
.name
);
275 freesstring(tg
.createdby
);
276 freesstring(tg
.contact
);
277 freesstring(tg
.comment
);
280 abandonreplication("unable to add trustgroup");
287 static int xsb_traddhost(void *source
, int argc
, char **argv
) {
294 if(!masterserver(source
))
298 abandonreplication("bad number of arguments");
302 if(!parseth(argv
[0], &th
, &tgid
, 0)) {
303 abandonreplication("bad trusthost line: %s", argv
[0]);
307 th
.group
= tg_getbyid(tgid
);
309 abandonreplication("unable to lookup trustgroup");
314 abandonreplication("unable to add trusthost");
321 static int xsb_trdelhost(void *source
, int argc
, char **argv
) {
328 if(!masterserver(source
))
332 abandonreplication("bad number of arguments");
336 id
= strtoul(argv
[0], NULL
, 10);
338 abandonreplication("unable to convert id to integer");
344 abandonreplication("unable to lookup id");
353 static int xsb_trdelgroup(void *source
, int argc
, char **argv
) {
360 if(!masterserver(source
))
364 abandonreplication("bad number of arguments");
368 id
= strtoul(argv
[0], NULL
, 10);
370 abandonreplication("unable to convert id to integer");
376 abandonreplication("unable to lookup id");
385 static int xsb_trmodifygroup(void *source
, int argc
, char **argv
) {
391 if(!masterserver(source
))
395 abandonreplication("bad number of arguments");
399 if(!parsetg(argv
[0], &tg
, 0)) {
400 abandonreplication("bad trustgroup line: %s", argv
[0]);
404 otg
= tg_getbyid(tg
.id
);
406 if(otg
&& !tg_modify(otg
, &tg
)) {
407 abandonreplication("unable to modify database");
411 freesstring(tg
.name
);
412 freesstring(tg
.createdby
);
413 freesstring(tg
.contact
);
414 freesstring(tg
.comment
);
417 abandonreplication("unable to lookup id");
426 static int loaded
, masternumeric
= -1;
427 static void *syncsched
;
429 static int masterserver(void *source
) {
431 int home
= homeserver(np
->numeric
);
436 if(home
!= masternumeric
) {
437 Error("trusts_slave", ERR_WARNING
, "Command from server that isn't a master: %s", serverlist
[home
].name
->content
);
444 static void checksynced(void *arg
) {
445 if(!synced
&& !syncing
)
446 xsb_broadcast("trrequeststart", NULL
, "%s", "");
449 static int trusts_cmdtrustresync(void *source
, int argc
, char **argv
) {
452 syncing
= synced
= 0;
455 controlreply(np
, "Synchronisation request sent.");
460 static void __serverlinked(int hooknum
, void *arg
) {
461 int servernum
= (int)(long)arg
;
463 if(!ircd_strcmp(serverlist
[servernum
].name
->content
, smasterserver
->content
)) {
464 masternumeric
= servernum
;
465 syncing
= synced
= 0;
473 m
= getconfigitem("trusts", "master");
474 if(m
&& (atoi(m
->content
) != 0)) {
475 Error("trusts_slave", ERR_ERROR
, "Not a slave server, not loaded.");
479 smasterserver
= getcopyconfigitem("trusts", "masterserver", "", 255);
480 if(!smasterserver
|| !smasterserver
->content
|| !smasterserver
->content
[0]) {
481 Error("trusts_slave", ERR_ERROR
, "No master server defined.");
482 freesstring(smasterserver
);
486 masternumeric
= findserver(smasterserver
->content
);
490 registercontrolhelpcmd("trustresync", NO_DEVELOPER
, 0, trusts_cmdtrustresync
, "Usage: trustresync");
492 xsb_addcommand("trinit", 1, xsb_trinit
);
493 xsb_addcommand("trdata", 1, xsb_trdata
);
494 xsb_addcommand("trfini", 1, xsb_trfini
);
495 xsb_addcommand("traddhost", 1, xsb_traddhost
);
496 xsb_addcommand("traddgroup", 1, xsb_traddgroup
);
497 xsb_addcommand("trdelhost", 1, xsb_trdelhost
);
498 xsb_addcommand("trdelgroup", 1, xsb_trdelgroup
);
499 xsb_addcommand("trmodifygroup", 1, xsb_trmodifygroup
);
501 registerhook(HOOK_SERVER_LINKED
, __serverlinked
);
502 syncsched
= schedulerecurring(time(NULL
)+5, 0, 60, checksynced
, NULL
);
504 if(trusts_fullyonline())
512 freesstring(smasterserver
);
514 deregistercontrolcmd("trustresync", trusts_cmdtrustresync
);
516 xsb_delcommand("trinit", xsb_trinit
);
517 xsb_delcommand("trdata", xsb_trdata
);
518 xsb_delcommand("trfini", xsb_trfini
);
519 xsb_delcommand("traddhost", xsb_traddhost
);
520 xsb_delcommand("traddgroup", xsb_traddgroup
);
521 xsb_delcommand("trdelhost", xsb_trdelhost
);
522 xsb_delcommand("trdelgroup", xsb_trdelgroup
);
523 xsb_delcommand("trmodifygroup", xsb_trmodifygroup
);
525 deregisterhook(HOOK_SERVER_LINKED
, __serverlinked
);
527 deleteschedule(syncsched
, checksynced
, NULL
);