]> jfr.im git - irc/quakenet/newserv.git/blob - trusts2/trusts_commands.c
Merge.
[irc/quakenet/newserv.git] / trusts2 / trusts_commands.c
1 #include "../core/schedule.h"
2 #include "../lib/irc_string.h"
3 #include "../localuser/localuserchannel.h"
4 #include "../control/control.h"
5 #include "trusts.h"
6 #include <string.h>
7 #include <stdlib.h>
8 #include <stdarg.h>
9 #include "../lib/version.h"
10
11 MODULE_VERSION("");
12
13 static int commandsregistered;
14
15 void _init(void) {
16 registerhook(HOOK_TRUSTS_DBLOADED, trusts_cmdinit);
17
18 /* Now that the database is in a separate module it might be loaded already. */
19 if (trusts_loaded)
20 trusts_cmdinit(HOOK_TRUSTS_DBLOADED, NULL);
21
22 }
23
24 void _fini(void) {
25 deregisterhook(HOOK_TRUSTS_DBLOADED, trusts_cmdinit);
26 trusts_cmdfini(0, NULL);
27 }
28
29 void trusts_cmdinit(int hooknum, void *arg) {
30 if(commandsregistered)
31 return;
32 registercontrolcmd("trustgroupadd",10,7,trust_groupadd);
33 registercontrolcmd("trustgroupmodify",10,4,trust_groupmodify);
34 registercontrolcmd("trustgroupdel",10,2,trust_groupdel);
35
36 registercontrolcmd("trustcomment",10,2,trust_comment);
37
38 registercontrolcmd("trustadd",10,3,trust_add);
39 registercontrolcmd("trustdel",10,2,trust_del);
40
41 registercontrolcmd("trustdenyadd",10,2,trust_denyadd);
42 registercontrolcmd("trustdenycomment",10,2,trust_denycomment);
43 registercontrolcmd("trustdenydel",10,2,trust_denydel);
44
45 registercontrolcmd("truststats",10,2,trust_stats);
46 registercontrolcmd("trustdump",10,2,trust_dump);
47
48 registercontrolcmd("trustlog", 10,2, trust_dotrustlog);
49
50 commandsregistered = 1;
51 removeusers = 0;
52 }
53
54 void trusts_cmdfini() {
55 if(!commandsregistered)
56 return;
57
58 deregistercontrolcmd("trustgroupadd",trust_groupadd);
59 deregistercontrolcmd("trustgroupmodify",trust_groupmodify);
60 deregistercontrolcmd("trustgroupdel",trust_groupdel);
61
62 deregistercontrolcmd("trustcomment",trust_comment);
63
64 deregistercontrolcmd("trustadd",trust_add);
65 deregistercontrolcmd("trustdel",trust_del);
66
67 deregistercontrolcmd("trustdenyadd",trust_denyadd);
68 deregistercontrolcmd("trustdenycomment",trust_denycomment);
69 deregistercontrolcmd("trustdenydel",trust_denydel);
70
71 deregistercontrolcmd("truststats",trust_stats);
72 deregistercontrolcmd("trustdump",trust_dump);
73
74 deregistercontrolcmd("trustlog", trust_dotrustlog);
75
76 commandsregistered = 0;
77 removeusers = 0;
78 }
79
80 /*TODO*/
81 /* tgh - should this have a 'maxclones limit'? */
82
83 int trust_groupadd(void *source, int cargc, char **cargv) {
84 nick *sender=(nick *)source;
85 int expiry;
86 unsigned long maxclones;
87 unsigned short maxperip;
88 unsigned long maxperident;
89 int enforceident;
90 int type;
91 unsigned long ownerid;
92 trustgroup_t *t;
93
94 if (cargc < 7) {
95 controlreply(sender,"Usage: trustgroupadd howmany howlong maxperident maxperip enforceident type ownerid");
96 return CMD_ERROR;
97 }
98
99 maxclones = strtoul(cargv[0],NULL,10);
100 if ( maxclones > 10000 ) {
101 /* we allow 0 for unlimited trusts, and only warn on this */
102 controlreply(sender, "WARNING: large maximum number of clients - %lu", maxclones);
103 }
104 expiry = durationtolong(cargv[1]);
105 if (expiry > (365 * 86400) ) {
106 controlreply(sender,"ERROR: Invalid duration given - temporary trusts must be less than 1 year");
107 return CMD_ERROR;
108 }
109 ownerid = strtoul(cargv[6],NULL,10);
110 maxperip = strtoul(cargv[3],NULL,10);
111 if (maxperip > 500) {
112 controlreply(sender, "ERROR: MaxPerIP value should be less then 500 (if set)");
113 return CMD_ERROR;
114 }
115 maxperident = strtoul(cargv[2],NULL,10);
116 if (maxperident > 50) {
117 controlreply(sender, "ERROR: MaxPerIdent value should be less then 50 (if set)");
118 return CMD_ERROR;
119 }
120 if (((cargv[4][0]!='0') && (cargv[4][0]!='1')) || (cargv[4][1]!='\0')) {
121 controlreply(sender,"ERROR: enforceident is a boolean setting, that means it can only be 0 or 1");
122 return CMD_ERROR;
123 }
124 enforceident = cargv[4][0] == '1';
125
126 if ( findtrustgroupbyownerid(ownerid) ) {
127 controlreply(sender, "ERROR: Q User ID %d already has a trustgroup", ownerid);
128 return CMD_ERROR;
129 }
130 if (ownerid > 2147483646 ) {
131 controlreply(sender, "ERROR: Invalid Q User ID: %d", ownerid);
132 return CMD_ERROR;
133 }
134
135 type = strtoul(cargv[5],NULL,10);
136
137 /* check rules */
138 switch (type ) {
139 case 0:
140 break;
141 default:
142 controlreply(sender, "Invalid Type (%d)", type);
143 return CMD_ERROR;
144 }
145
146 t = createtrustgroup( ++trusts_lasttrustgroupid, maxclones, maxperident, maxperip, enforceident, getnettime() + expiry, ownerid, type);
147
148 if(!t) {
149 controlreply(sender,"ERROR: An error occured adding trustgroup");
150 return CMD_ERROR;
151 }
152
153 trustsdb_addtrustgroup(t);
154
155 controlreply(sender,"Adding trustgroup with ID %lu", t->id);
156 controlreply(sender,"Connections: %d, Enforceident %d, Per ident: %d, Per IP %d",maxclones,enforceident,maxperident,maxperip);
157 controlreply(sender,"Expires: %d, User ID: %d", expiry, ownerid);
158 controlwall(NO_OPER, NL_TRUSTS, "NewTrust: ID: %lu, Connections: %d, Enforceident %d, Per ident: %d, Per IP %d, Owner %d", t->id,maxclones,enforceident,maxperident,maxperip, ownerid);
159 return CMD_OK;
160 }
161
162 int trust_del(void *source, int cargc, char **cargv) {
163 nick *sender=(nick *)source;
164 struct irc_in_addr sin;
165 unsigned char bits;
166 patricia_node_t *node;
167 trustgroup_t *tg;
168
169 if (cargc<1) {
170 controlreply(sender,"Syntax: trustdel IP[/mask]");
171 return CMD_OK;
172 }
173
174 if (ipmask_parse(cargv[0], &sin, &bits) == 0) {
175 controlreply(sender, "ERROR: Invalid mask.");
176 return CMD_ERROR;
177 }
178
179 if (!is_normalized_ipmask(&sin,bits)) {
180 controlreply(sender, "ERROR: non-normalized mask.");
181 return CMD_ERROR;
182 }
183
184 node = refnode(iptree, &sin, bits);
185 if(!node->exts[tgh_ext]) {
186 controlreply(sender,"ERROR: That CIDR was not trusted.");
187 return CMD_ERROR;
188 } else {
189 /*TODO: only allow a host to be removed if <X users? subnets? bah */
190 tg = ((trusthost_t *)node->exts[tgh_ext])->trustgroup;
191 controlreply(sender,"%s removed from trustgroup #%lu",cargv[0],tg->id);
192 controlwall(NO_OPER, NL_TRUSTS, "%s removed from trustgroup #%lu",cargv[0],tg->id);
193 trustsdb_deletetrusthost(node->exts[tgh_ext]);
194 trusthost_free(node->exts[tgh_ext]);
195 node->exts[tgh_ext] = NULL;
196 }
197 return CMD_OK;
198 }
199
200 int trust_add(void *source, int cargc, char **cargv) {
201 nick *sender=(nick *)source;
202 trustgroup_t *tg;
203 struct irc_in_addr sin;
204 unsigned char bits;
205 patricia_node_t *node, *inode, *parent;
206 int expiry = 0;
207 trusthost_t *th;
208
209 if (cargc<2) {
210 controlreply(sender,"Syntax: trustadd <#groupid> IP[/mask] <duration>");
211 return CMD_OK;
212 }
213
214 if(cargv[0][0]== '#'){
215 /* find group by id */
216 tg=findtrustgroupbyid(strtol(&cargv[0][1],NULL,10));
217 } else {
218 /* find group by id */
219 tg=findtrustgroupbyid(strtol(cargv[0],NULL,10));
220 }
221
222 if(tg == NULL) {
223 controlreply(sender,"ERROR: A trustgroup with that ID does not exist.");
224 return CMD_ERROR;
225 }
226
227 if (tg->id==0) {
228 controlreply(sender,"INTERNAL ERROR: Trustgroup has ID 0");
229 return CMD_ERROR;
230 }
231
232 if (ipmask_parse(cargv[1], &sin, &bits) == 0) {
233 controlreply(sender, "ERROR: Invalid mask.");
234 return CMD_ERROR;
235 }
236
237 if (!is_normalized_ipmask(&sin,bits)) {
238 controlreply(sender, "ERROR: non-normalized mask.");
239 return CMD_ERROR;
240 }
241
242 if ( irc_in_addr_is_ipv4(&sin) ) {
243 if (bits>128 || bits<112) {
244 controlreply(sender,"ERROR: Not a valid netmask (needs to be between 16 and 32)");
245 return CMD_ERROR;
246 }
247 } else {
248 if ( bits<64) {
249 controlreply(sender,"ERROR: Not a valid ipv6 netmask ");
250 return CMD_ERROR;
251 }
252 }
253
254 if (cargc == 3) {
255 expiry = getnettime() + durationtolong(cargv[2]);
256 if (expiry<1) {
257 controlreply(sender,"ERROR: Invalid duration given");
258 return CMD_ERROR;
259 }
260 }
261
262 node = refnode(iptree, &sin, bits);
263 if(node->exts[tgh_ext]) {
264 /* this mask is already trusted */
265 controlreply(sender,"ERROR: This mask is already trusted by trustgroup %lu.", ((trusthost_t *)node->exts[tgh_ext])->trustgroup->id);
266 return CMD_ERROR;
267 }
268 if ( node->exts[tgb_ext] ) {
269 controlreply(sender,"ERROR: A trustblock exists on this subnet, as follows: ID: %lu, public reason: %s", ((trustblock_t *)node->exts[tgb_ext])->id, (((trustblock_t *)node->exts[tgb_ext])->reason_public ? ((trustblock_t *)node->exts[tgb_ext])->reason_public->content : "<none>"));
270 return CMD_ERROR;
271 }
272
273 /* check child status */
274 PATRICIA_WALK(node, inode)
275 {
276 th = inode->exts[tgh_ext];
277 if (th) {
278 /* we have a child trustgroup */
279 /* Criteria 1: we can't add two hosts into the same group */
280 if (th->trustgroup == tg) {
281 controlreply(sender,"ERROR: A child subnet is already in this trustgroup, remove that subnet first (%s/%d)", IPtostr(inode->prefix->sin),irc_bitlen(&(inode->prefix->sin),inode->prefix->bitlen));
282 return CMD_ERROR;
283 }
284 /* Criteria 2: we can't trust a subnet containing a trustblock (unless you have +d flag, then warn) */
285 if ( inode->exts[tgb_ext] ) {
286 controlreply(sender,"ERROR: A trustblock exists on a child subnet, as follows: ID: %lu, public reason: %s", ((trustblock_t *)inode->exts[tgb_ext])->id, (((trustblock_t *)inode->exts[tgb_ext])->reason_public ? ((trustblock_t *)inode->exts[tgb_ext])->reason_public->content : "<none>"));
287 return CMD_ERROR;
288 }
289 }
290 }
291 PATRICIA_WALK_END;
292
293 /* check parents too */
294 parent = node->parent;
295 while (parent) {
296 if( parent->exts[tgh_ext]) {
297 th = parent->exts[tgh_ext];
298 /* we have a parent trustgroup */
299 /* Criteria 1: we can't add two hosts into the same group */
300 if (th->trustgroup == tg) {
301 controlreply(sender,"ERROR: A parent subnet is already in this trustgroup (%s/%d)", IPtostr(parent->prefix->sin),irc_bitlen(&(parent->prefix->sin),parent->prefix->bitlen));
302 return CMD_ERROR;
303 }
304 /* even if we find 1 parent, we continue to the top */
305 /* Criteria 2: we can't trust a subnet containing a trustblock (unless you have +d flag, then warn) */
306 if ( parent->exts[tgb_ext] ) {
307 controlreply(sender,"ERROR: A trustblock exists on a parent subnet, as follows: ID: %lu, public reason: %s", ((trustblock_t *)parent->exts[tgb_ext])->id, (((trustblock_t *)parent->exts[tgb_ext])->reason_public ? ((trustblock_t *)parent->exts[tgb_ext])->reason_public->content : "<none>"));
308 return CMD_ERROR;
309 }
310 }
311 parent = parent->parent;
312 }
313
314 th = trusthostadd(node, tg, expiry );
315 if ( !th ) {
316 controlreply(sender,"ERROR: Unable to add trusted host");
317 return CMD_ERROR;
318 }
319
320 trustsdb_addtrusthost(th);
321 controlreply(sender,"Added %s to trustgroup #%lu",cargv[1],tg->id);
322 controlwall(NO_OPER, NL_TRUSTS, "Added %s to trustgroup #%lu",cargv[1],tg->id);
323 return CMD_OK;
324 }
325
326 int trust_dump(void *source, int cargc, char **cargv) {
327 nick *sender=(nick *)source;
328
329 char tmps3[512];
330 trustgroup_t *g;
331 unsigned long startid=0;
332 long num=0, count=0, lines=0;
333
334 if (cargc<2) {
335 controlreply(sender, "Syntax: trustdump <start #id> <number>");
336 controlreply(sender, "Dumps <number> trustgroups starting from <start #id>.");
337 controlreply(sender, "This allows to dump very large numbers of groups,");
338 controlreply(sender, "so use with care.");
339 return CMD_ERROR;
340 }
341 strncpy(tmps3,cargv[0],20);
342 tmps3[20]='\0';
343 num = atoi(cargv[1]);
344
345 if (tmps3[0] != '#') {
346 controlreply(sender, "First parameter has to be a trust ID (prefixed with #).");
347 return CMD_ERROR;
348 }
349
350 startid=strtoul(&tmps3[1], NULL, 10);
351 if (num < 1) {
352 controlreply(sender, "Cannot return fewer than 1 group.");
353 return CMD_ERROR;
354 }
355 if (num >= 500) {
356 controlreply(sender, "Will not list more than 500 groups in one go.");
357 return CMD_ERROR;
358 }
359
360 if (startid > trusts_lasttrustgroupid) {
361 controlreply(sender, "Start ID cannot exceed maximum group ID (#%ld).", trusts_lasttrustgroupid);
362 return CMD_ERROR;
363 }
364
365 do {
366 g=findtrustgroupbyid(startid);
367 startid++;
368 } while ((g == NULL) && (startid <= (trusts_lasttrustgroupid+1)));
369 if (g == NULL) {
370 controlreply(sender, "Failed to find nearest start group.");
371 return CMD_ERROR;
372 }
373
374 while (startid <= (trusts_lasttrustgroupid+1)) {
375 if (g == NULL) {
376 g=findtrustgroupbyid(startid);
377 startid++;
378 continue;
379 }
380 controlreply(sender, "G,#%lu,%lu,%lu,%d,%lu,%lu,%lu,%lu",
381 g->id, g->currenton, g->maxclones, g->enforceident, g->maxperident,
382 g->maxusage, g->expire, g->lastused);
383 lines++;
384
385 trusthost_t* thptr;
386
387 int hash = trusts_gettrusthostgroupidhash(g->id);
388 for (thptr = trusthostgroupidtable[hash]; thptr; thptr = thptr->nextbygroupid ) {
389 if ( thptr->trustgroup->id == g->id ) {
390 /* TODO: expire here - trusthost_free(thptr);*/
391 controlreply(sender, "H,#%lu,%s/%d,%lu,%lu,%lu", g->id,
392 IPtostr(((patricia_node_t *)thptr->node)->prefix->sin),
393 irc_bitlen(&(((patricia_node_t *)thptr->node)->prefix->sin),((patricia_node_t *)thptr->node)->prefix->bitlen),
394 0 /*a->currentlyon*/,
395 0 /*a->maxused*/,
396 0 /* a->lastused*/);
397 lines++;
398 }
399 }
400
401 count++;
402 if (count >= num) {
403 break;
404 }
405 g=findtrustgroupbyid(startid);
406 startid++;
407 }
408 controlreply(sender, "End of list, %ld groups and %ld lines returned.", count, lines);
409 return CMD_OK;
410 }
411
412 int trust_denyadd(void *source, int cargc, char **cargv) {
413 nick *sender=(nick *)source;
414 struct irc_in_addr sin;
415 unsigned char bits;
416 trustblock_t *tb;
417 patricia_node_t *node;
418 int expiry;
419
420 if (cargc<2) {
421 controlreply(sender,"Syntax: trustdenyadd IP[/mask] <expiry> <public reason>");
422 return CMD_OK;
423 }
424
425 if (ipmask_parse(cargv[0], &sin, &bits) == 0) {
426 controlreply(sender, "ERROR: Invalid mask.");
427 return CMD_ERROR;
428 }
429
430 if (!is_normalized_ipmask(&sin,bits)) {
431 controlreply(sender, "ERROR: non-normalized mask.");
432 return CMD_ERROR;
433 }
434
435 if ( irc_in_addr_is_ipv4(&sin) ) {
436 if (bits>128 || bits<112) {
437 controlreply(sender,"ERROR: Not a valid netmask (needs to be between 8 and 32)");
438 return CMD_ERROR;
439 }
440 } else {
441 if ( bits<64) {
442 controlreply(sender,"ERROR: Not a valid ipv6 netmask ");
443 return CMD_ERROR;
444 }
445 }
446
447 expiry = getnettime() + durationtolong(cargv[1]);
448 if (expiry<1) {
449 controlreply(sender,"ERROR: Invalid duration given");
450 return CMD_ERROR;
451 }
452
453 node = refnode(iptree, &sin, bits);
454 if(node->exts[tgb_ext]) {
455 /* this mask is already blocked */
456 controlreply(sender,"ERROR: This mask is already blocked", ((trustblock_t *)node->exts[tgb_ext])->id);
457 return CMD_ERROR;
458 }
459
460 tb = createtrustblock( ++trusts_lasttrustblockid, node, 0 /*TODO*/, expiry, NULL,cargv[2]);
461 if (!tb) {
462 controlreply(sender,"ERROR: An error occured adding the trustblock");
463 }
464 node->exts[tgb_ext] = tb;
465
466 trustsdb_addtrustblock(tb);
467 controlreply(sender,"Added %s to trustblock list",cargv[0]);
468 controlwall(NO_OPER, NL_TRUSTS, "Added %s to trustblock list",cargv[0]);
469 return CMD_OK;
470 }
471
472 int trust_denycomment(void *source, int cargc, char **cargv) {
473 nick *sender=(nick *)source;
474 struct irc_in_addr sin;
475 unsigned char bits;
476 patricia_node_t *node;
477 trustblock_t *tb;
478
479 if (cargc<2) {
480 controlreply(sender,"Syntax: trustdenycomment IP[/mask] <private reason>");
481 return CMD_OK;
482 }
483
484 if (ipmask_parse(cargv[0], &sin, &bits) == 0) {
485 controlreply(sender, "ERROR: Invalid mask.");
486 return CMD_ERROR;
487 }
488
489 if (!is_normalized_ipmask(&sin,bits)) {
490 controlreply(sender, "ERROR: non-normalized mask.");
491 return CMD_ERROR;
492 }
493
494 if ( irc_in_addr_is_ipv4(&sin) ) {
495 if (bits>128 || bits<112) {
496 controlreply(sender,"ERROR: Not a valid netmask (needs to be between 8 and 32)");
497 return CMD_ERROR;
498 }
499 } else {
500 if ( bits<64) {
501 controlreply(sender,"ERROR: Not a valid ipv6 netmask ");
502 return CMD_ERROR;
503 }
504 }
505
506 node = refnode(iptree, &sin, bits);
507 if(!node->exts[tgb_ext]) {
508 /* this mask is already blocked */
509 controlreply(sender,"ERROR: This mask is not blocked. Use trustdenyadd to add a new block");
510 return CMD_ERROR;
511 }
512 derefnode(iptree,node);
513 tb = node->exts[tgb_ext];
514
515 tb->reason_private = getsstring(cargv[1],512);
516 trustsdb_updatetrustblock(tb);
517 controlreply(sender,"Private Comment added to trustblock %s",cargv[0]);
518 controlwall(NO_OPER, NL_TRUSTS, "Private Comment added to trustblock %s",cargv[0]);
519 return CMD_OK;
520 }
521
522 int trust_denydel(void *source, int cargc, char **cargv) {
523 nick *sender=(nick *)source;
524 struct irc_in_addr sin;
525 unsigned char bits;
526 patricia_node_t *node;
527
528 if (cargc<1) {
529 controlreply(sender,"Syntax: trustdenydel IP[/mask]");
530 return CMD_OK;
531 }
532
533 if (ipmask_parse(cargv[0], &sin, &bits) == 0) {
534 controlreply(sender, "ERROR: Invalid mask.");
535 return CMD_ERROR;
536 }
537
538 if (!is_normalized_ipmask(&sin,bits)) {
539 controlreply(sender, "ERROR: non-normalized mask.");
540 return CMD_ERROR;
541 }
542
543 node = refnode(iptree, &sin, bits);
544 if(!node->exts[tgb_ext]) {
545 controlreply(sender,"ERROR: That CIDR was not blocked.");
546 return CMD_ERROR;
547 } else {
548 controlreply(sender,"trustblock removed on %s",cargv[0]);
549 controlwall(NO_OPER, NL_TRUSTS, "trustblock removed on %s", cargv[0]);
550 trustsdb_deletetrustblock( node->exts[tgb_ext]);
551 trustblock_free( node->exts[tgb_ext] );
552 node->exts[tgb_ext] = NULL;
553 }
554 controlreply(sender,"Not Implemented");
555 return CMD_OK;
556 }
557
558 int trust_groupmodify(void *source, int cargc, char **cargv) {
559 nick *sender=(nick *)source;
560 unsigned long oldvalue, newvalue;
561 char *mod;
562 int expiry;
563 trustgroup_t *tg;
564
565 if (cargc<3 || cargc==4) {
566 controlreply(sender,"Syntax: trustgroupmodify <#groupid> <what> [+|-|=]number");
567 controlreply(sender," +20 means add 20, =20 replaces current value, -20 means subtract");
568 controlreply(sender," what: maxclones, maxperident, maxperip, expire, enforceident, ownerid");
569 return CMD_OK;
570 }
571
572 if(cargv[0][0]== '#'){
573 /* find group by id */
574 tg=findtrustgroupbyid(strtol(&cargv[0][1],NULL,10));
575 } else {
576 /* find group by id */
577 tg=findtrustgroupbyid(strtol(cargv[0],NULL,10));
578 }
579
580 if(tg == NULL) {
581 controlreply(sender,"ERROR: A trustgroup with that ID does not exist.");
582 return CMD_ERROR;
583 }
584
585 if (tg->id==0) {
586 controlreply(sender,"INTERNAL ERROR: Trustgroup has ID 0");
587 return CMD_ERROR;
588 }
589
590 switch ( cargv[2][0] ) {
591 case '+':
592 case '-':
593 case '=':
594 mod = cargv[2];
595 break;
596 default:
597 controlreply(sender,"ERROR: invalid modifier specified (values values are +,-,=)");
598 return CMD_ERROR;
599 }
600 newvalue = strtoul(&cargv[2][1],NULL,10);
601
602 if (ircd_strcmp(cargv[1], "maxclones")==0) {
603 oldvalue = tg->maxclones;
604 switch (*mod) {
605 case '+':
606 newvalue = oldvalue + newvalue;
607 break;
608 case '-':
609 if (newvalue > oldvalue) {
610 controlreply(sender, "ERROR: maxclones cannot be less than 0");
611 return CMD_ERROR;
612 }
613 newvalue = oldvalue - newvalue;
614 if (newvalue == 0) {
615 controlreply(sender, "ERROR: maxclones limit would be 0 - unlimited maxclones can only be set with '='");
616 return CMD_ERROR;
617 }
618 break;
619 }
620
621 if (newvalue > 1000000) {
622 controlreply(sender, "ERROR: large maximum number of clients - %lu", newvalue);
623 return CMD_ERROR;
624 }
625 if (newvalue > 10000) {
626 controlreply(sender, "WARNING: large maximum number of clients - %lu", newvalue);
627 }
628
629 tg->maxclones = newvalue;
630 } else if (ircd_strcmp(cargv[1], "maxperident")==0) {
631 oldvalue = tg->maxperident;
632 switch (*mod) {
633 case '+':
634 newvalue = oldvalue + newvalue;
635 break;
636 case '-':
637 if (newvalue > oldvalue) {
638 controlreply(sender, "ERROR: maxperident cannot be less than 0");
639 return CMD_ERROR;
640 }
641 newvalue = oldvalue - newvalue;
642 if (newvalue == 0) {
643 controlreply(sender, "ERROR: maxperident limit would be 0 - unlimited maxclones can only be set with '='");
644 return CMD_ERROR;
645 }
646 break;
647 }
648
649 if (newvalue > 50) {
650 controlreply(sender, "ERROR: MaxPerIdent value should be less then 50 (if set)");
651 return CMD_ERROR;
652 }
653 tg->maxperident=newvalue;
654 } else if (ircd_strcmp(cargv[1], "maxperip")==0) {
655 oldvalue = tg->maxperip;
656 switch (*mod) {
657 case '+':
658 newvalue = oldvalue + newvalue;
659 break;
660 case '-':
661 if (newvalue > oldvalue) {
662 controlreply(sender, "ERROR: maxperip cannot be less than 0");
663 return CMD_ERROR;
664 }
665 newvalue = oldvalue - newvalue;
666 if (newvalue == 0) {
667 controlreply(sender, "ERROR: maxperip limit would be 0 - unlimited maxclones can only be set with '='");
668 return CMD_ERROR;
669 }
670 break;
671 }
672
673 if (newvalue > 500) {
674 controlreply(sender, "ERROR: MaxPerIP value should be less then 500 (if set)");
675 return CMD_ERROR;
676 }
677 tg->maxperip = newvalue;
678 } else if (ircd_strcmp(cargv[1], "expire")==0) {
679 oldvalue = tg->expire;
680 expiry = durationtolong(&cargv[2][1]);
681
682 if (expiry > (365 * 86400) ) {
683 controlreply(sender,"ERROR: Invalid duration given - temporary trusts can not be longer then 1 year");
684 return CMD_ERROR;
685 }
686
687 switch (*mod) {
688 case '+':
689 newvalue = oldvalue + expiry;
690 break;
691 case '-':
692 newvalue = oldvalue - expiry;
693 if (newvalue < getnettime() ) {
694 controlreply(sender, "ERROR: Can't set expiry before current nettime - use trustgroupdel to delete trust groups");
695 return CMD_ERROR;
696 }
697 break;
698 case '=':
699 if ( expiry > 0) {
700 newvalue = getnettime() + expiry;
701 }
702 break;
703 }
704 tg->expire = newvalue;
705 } else if (ircd_strcmp(cargv[1], "enforceident")==0) {
706 oldvalue = tg->enforceident;
707 if ( (newvalue != 0 && newvalue != 1) || *mod != '=' ) {
708 controlreply(sender,"ERROR: enforceident is a boolean setting, that means it can only be 0 or 1, and can only be set by '='");
709 return CMD_ERROR;
710 }
711 tg->enforceident = newvalue;
712 } else if (ircd_strcmp(cargv[1], "ownerid")==0) {
713 oldvalue = tg->ownerid;
714 if ( *mod != '=' ) {
715 controlreply(sender,"ERROR: Q user ID can only be set by '='");
716 return CMD_ERROR;
717 }
718 if ( findtrustgroupbyownerid(newvalue) ) {
719 controlreply(sender, "ERROR: Q User ID %d already has a trustgroup", newvalue);
720 return CMD_ERROR;
721 }
722
723 if (newvalue > 2147483646 ) {
724 controlreply(sender, "ERROR: Invalid Q User ID: %d", newvalue);
725 return CMD_ERROR;
726 }
727
728 tg->ownerid = newvalue;
729 }
730 controlreply(sender, "Modification: %s changed to %lu from %lu for trustgroup %lu", cargv[1], newvalue, oldvalue, tg->id);
731 controlwall(NO_OPER, NL_TRUSTS, "Modification: %s changed to %lu from %lu for trustgroup %lu", cargv[1], newvalue, oldvalue, tg->id);
732
733 trustsdb_updatetrustgroup(tg);
734 return CMD_OK;
735 }
736
737 int trust_groupdel(void *source, int cargc, char **cargv) {
738 nick *sender=(nick *)source;
739 trusthost_t *thptr, *nthptr;
740 trustgroup_t *tg;
741 patricia_node_t *node;
742
743 if (cargc<1) {
744 controlreply(sender,"Syntax: trustgroupdel <#id|id>");
745 return CMD_OK;
746 }
747
748 if(cargv[0][0]== '#'){
749 /* find group by id */
750 tg=findtrustgroupbyid(strtol(&cargv[0][1],NULL,10));
751 } else {
752 /* find group by id */
753 tg=findtrustgroupbyid(strtol(cargv[0],NULL,10));
754 }
755
756 if(tg == NULL) {
757 controlreply(sender,"ERROR: A trustgroup with that ID does not exist.");
758 return CMD_ERROR;
759 }
760
761 if (tg->id==0) {
762 controlreply(sender,"INTERNAL ERROR: Trustgroup has ID 0");
763 return CMD_ERROR;
764 }
765
766 /* we have a trustgroup to remove */
767 int hash = trusts_gettrusthostgroupidhash(tg->id);
768 for (thptr = trusthostgroupidtable[hash]; thptr; thptr = nthptr ) {
769 nthptr = thptr->nextbygroupid;
770 if(thptr->trustgroup == tg) {
771 node = thptr->node;
772 controlwall(NO_OPER, NL_TRUSTS, "%s/%d removed from trustgroup #%lu",IPtostr(thptr->node->prefix->sin),irc_bitlen(&(thptr->node->prefix->sin),thptr->node->prefix->bitlen),tg->id);
773 controlreply(sender,"%s/%d removed from trustgroup #%lu",IPtostr(thptr->node->prefix->sin),irc_bitlen(&(thptr->node->prefix->sin),thptr->node->prefix->bitlen),tg->id);
774 trustsdb_deletetrusthost(thptr);
775 trusthost_free(thptr);
776 node->exts[tgh_ext] = NULL;
777 }
778 }
779 controlwall(NO_OPER, NL_TRUSTS, "removed trustgroup #%lu",tg->id);
780 controlreply(sender,"removed trustgroup #%lu",tg->id);
781 trustsdb_deletetrustgroup(tg);
782 trustgroup_free(tg);
783 return CMD_OK;
784
785 }
786
787 int trust_stats(void *source, int cargc, char **cargv) {
788 nick *sender=(nick *)source;
789 trustgroup_t *tg; trusthost_t* thptr; int i;
790 unsigned long thcount=0, ucount=0, mcount=0, tgcount=0;
791 unsigned long hentries=0;
792 unsigned long netcount4[33];
793 unsigned long netucount4[33];
794 unsigned long netmcount4[33];
795 unsigned long netcount6[129];
796 unsigned long netucount6[129];
797 unsigned long netmcount6[129];
798
799 int maxthmask4 = 32;
800 int maxthmask6 = 128;
801
802 for (i=0; i<33; i++) {
803 netcount4[i]=0;
804 netucount4[i]=0;
805 netmcount4[i]=0;
806 }
807
808 for (i=0; i<129; i++) {
809 netcount6[i]=0;
810 netucount6[i]=0;
811 netmcount6[i]=0;
812 }
813
814 for ( i = 0; i < TRUSTS_HASH_GROUPSIZE ; i++ ) {
815 for ( tg = trustgroupidtable[i]; tg; tg = tg -> nextbyid ) {
816 /*check active*/
817 tgcount++;
818 }
819 }
820
821 for ( i = 0; i < TRUSTS_HASH_HOSTSIZE ; i++ ) {
822 for ( thptr = trusthostidtable[i]; thptr; thptr = thptr-> nextbyid ) {
823 /*check active*/
824 hentries++;
825 thcount++;
826 ucount+=thptr->node->usercount;
827 mcount+=thptr->maxused;
828 if(irc_in_addr_is_ipv4(&((patricia_node_t *)thptr->node)->prefix->sin)) {
829 netcount4[((patricia_node_t *)thptr->node)->prefix->bitlen-96]++;
830 netucount4[((patricia_node_t *)thptr->node)->prefix->bitlen-96]+=thptr->node->usercount;
831 netmcount4[((patricia_node_t *)thptr->node)->prefix->bitlen-96]+=thptr->maxused;
832 if( (((patricia_node_t *)thptr->node)->prefix->bitlen-96) < maxthmask4 ) {
833 maxthmask4 = (((patricia_node_t *)thptr->node)->prefix->bitlen-96);
834 }
835 } else {
836 controlreply(sender, "%s", IPtostr(((patricia_node_t *)thptr->node)->prefix->sin));
837 netcount6[((patricia_node_t *)thptr->node)->prefix->bitlen]++;
838 netucount6[((patricia_node_t *)thptr->node)->prefix->bitlen]+=thptr->node->usercount;
839 netmcount6[((patricia_node_t *)thptr->node)->prefix->bitlen]+=thptr->maxused;
840 if( ((patricia_node_t *)thptr->node)->prefix->bitlen < maxthmask6 ) {
841 maxthmask6 = ((patricia_node_t *)thptr->node)->prefix->bitlen;
842 }
843 }
844 }
845 }
846 controlreply(sender, "Online trust users: %lu", ucount);
847 controlreply(sender, "Maximum online users: %lu", mcount);
848 controlreply(sender, "Trust groups: %lu", tgcount);
849 controlreply(sender, "Maximum group ID: #%lu", trusts_lasttrustgroupid);
850 controlreply(sender, "Trusted hosts/nets: %lu", thcount);
851 controlreply(sender, "Largest subnet (v4): /%d", maxthmask4);
852 controlreply(sender, "Largest subnet (v6): /%d", maxthmask6);
853 controlreply(sender, "IPv4 Subnets:");
854 for (i=0; i<32; i++) {
855 if (netcount4[i]==0) continue;
856 controlreply(sender, "|-*/%d (Netcount: %lu Cur: %lu Max: %lu)", i, netcount4[i], netucount4[i], netmcount4[i]);
857 }
858 controlreply(sender, "`-*/32 (Netcount: %lu Cur: %lu Max: %lu)", netcount4[32], netucount4[32], netmcount4[32]);
859 controlreply(sender, "IPv6 Subnets:");
860 for (i=0; i<128; i++) {
861 if (netcount6[i]==0) continue;
862 controlreply(sender, "|-*/%d (Netcount: %lu Cur: %lu Max: %lu)", i, netcount6[i], netucount6[i], netmcount6[i]);
863 }
864 controlreply(sender, "`-*/128 (Netcount: %lu Cur: %lu Max: %lu)", netcount6[128], netucount6[128], netmcount6[128]);
865
866 return CMD_OK;
867 }
868
869
870 int trust_comment(void *source, int cargc, char **cargv) {
871 nick *sender=(nick *)source;
872 trustgroup_t *tg;
873
874 if (cargc<2) {
875 controlreply(sender,"Syntax: trustcomment <#groupid> <comment>");
876 return CMD_OK;
877 }
878
879 if(cargv[0][0]== '#'){
880 /* find group by id */
881 tg=findtrustgroupbyid(strtol(&cargv[0][1],NULL,10));
882 } else {
883 /* find group by id */
884 tg=findtrustgroupbyid(strtol(cargv[0],NULL,10));
885 }
886
887 if(tg == NULL) {
888 controlreply(sender,"A trustgroup with that ID does not exist.");
889 return CMD_ERROR;
890 }
891
892 if (tg->id==0) {
893 controlreply(sender,"Internal error: Trustgroup has ID 0");
894 return CMD_ERROR;
895 }
896
897 trustsdb_logmessage(tg, 0, 1, cargv[1]);
898
899 controlreply(sender, "Comment: %s for trustgroup %lu", cargv[1], tg->id);
900 controlwall(NO_OPER, NL_TRUSTS, "Comment: %s for trustgroup %lu", cargv[1], tg->id);
901
902 return CMD_OK;
903 }
904
905 int trust_dotrustlog(void *source, int cargc, char **cargv) {
906 nick *np=source;
907 unsigned long interval;
908 int trustid;
909
910 if (cargc < 1) {
911 controlreply(np,"Syntax: trustlog <#groupid> [duration]");
912 return CMD_ERROR;
913 }
914
915 if(cargv[0][0]== '#'){
916 trustid = strtol(&cargv[0][1],NULL,10);
917 } else {
918 trustid = strtol(cargv[0],NULL,10);
919 }
920
921 if (cargc > 1)
922 interval=getnettime() - durationtolong(cargv[1]);
923 else
924 interval=0;
925
926 trustsdb_retrievetrustlog(np, trustid, interval);
927 return CMD_OK;
928 }