3 #include "../control/control.h"
4 #include "../lib/version.h"
5 #include "../lib/irc_string.h"
6 #include "../lib/strlfunc.h"
7 #include "../core/config.h"
8 #include "../core/schedule.h"
9 #include "../irc/irc.h"
10 #include "../lib/stringbuf.h"
11 #include "../noperserv/noperserv.h"
12 #include "../noperserv/noperserv_policy.h"
17 static void registercommands(int, void *);
18 static void deregistercommands(int, void *);
20 typedef int (*trustmodificationfn
)(void *, char *arg
, nick
*, int);
22 struct trustmodification
{
24 trustmodificationfn fn
;
27 static int trusts_cmdtrustadd(void *source
, int cargc
, char **cargv
) {
29 nick
*sender
= source
;
31 struct irc_in_addr ip
;
33 trusthost
*th
, *superset
, *subset
;
38 tg
= tg_strtotg(cargv
[0]);
40 controlreply(sender
, "Couldn't look up trustgroup.");
45 if(!ipmask_parse(host
, &ip
, &bits
)) {
46 controlreply(sender
, "Invalid host.");
50 if(!is_normalized_ipmask(&ip
, bits
)) {
51 controlreply(sender
, "Invalid IP Mask.");
55 /* Don't allow non-developers to add trusts for large subnets or modify protected groups. */
56 if (!noperserv_policy_command_permitted(NO_DEVELOPER
, sender
)) {
57 int minbits
= irc_in_addr_is_ipv4(&ip
)?TRUST_MIN_UNPRIVILEGED_BITS_IPV4
:TRUST_MIN_UNPRIVILEGED_BITS_IPV6
;
59 controlreply(sender
, "You don't have the necessary privileges to add a subnet larger than /%d.", irc_bitlen(&ip
, minbits
));
63 if(tg
->flags
& TRUST_PROTECTED
) {
64 controlreply(sender
, "You don't have the necessary privileges to modify a protected trust group.");
69 /* OKAY! Lots of checking here!
72 * - host isn't already covered by given group (reject if it is)
73 * - host doesn't already exist exactly already (reject if it does)
74 * - host is more specific than an existing one (warn if it is, fix up later)
75 * - host is less specific than an existing one (warn if it is, don't need to do anything special)
78 for(th
=tg
->hosts
;th
;th
=th
->next
) {
79 if(ipmask_check(&ip
, &th
->ip
, th
->bits
)) {
80 controlreply(sender
, "This host (or part of it) is already covered in the given group.");
85 if(th_getbyhostandmask(&ip
, bits
)) {
86 controlreply(sender
, "This host already exists in another group with the same mask.");
90 /* this function will set both to NULL if it's equal, hence the check above */
91 th_getsuperandsubsets(&ip
, bits
, &superset
, &subset
);
93 /* a superset exists for us, we will be more specific than one existing host */
95 controlreply(sender
, "Note: This host already exists in another group, but this new host will override it as it has a smaller prefix.");
98 /* a subset of us exists, we will be less specific than some existing hosts */
100 controlreply(sender
, "Note: This host already exists in at least one other group, the new host has a larger prefix and therefore will not override those hosts.");
103 th
= th_new(tg
, host
);
105 controlreply(sender
, "An error occured adding the host to the group.");
109 controlreply(sender
, "Host added.");
110 triggerhook(HOOK_TRUSTS_ADDHOST
, th
);
112 controlwall(NO_OPER
, NL_TRUSTS
, "%s TRUSTADD'ed host %s to group '%s'", controlid(sender
), host
, th
->group
->name
->content
);
113 trustlog(tg
, sender
->authname
, "Added host '%s'.", host
);
118 static int trusts_cmdtrustgroupadd(void *source
, int cargc
, char **cargv
) {
119 nick
*sender
= source
;
120 char *name
, *contact
, *comment
, createdby
[ACCOUNTLEN
+ 2];
121 long howmany
, maxperident
, enforceident
;
128 override
= noperserv_policy_command_permitted(NO_DEVELOPER
, sender
);
131 howmany
= strtol(cargv
[1], NULL
, 10);
132 if(!override
&& (!howmany
|| (howmany
> MAXTRUSTEDFOR
))) {
133 controlreply(sender
, "Bad value maximum number of clients.");
137 maxperident
= strtol(cargv
[2], NULL
, 10);
138 if(maxperident
< 0 || (maxperident
> MAXPERIDENT
)) {
139 controlreply(sender
, "Bad value for max per ident.");
143 if(cargv
[3][0] != '1' && cargv
[3][0] != '0') {
144 controlreply(sender
, "Bad value for enforce ident (use 0 or 1).");
147 enforceident
= cargv
[3][0] == '1';
152 comment
= "(no comment)";
157 /* don't allow #id or id forms */
158 if((name
[0] == '#') || strtol(name
, NULL
, 10)) {
159 controlreply(sender
, "Invalid trustgroup name.");
163 tg
= tg_strtotg(name
);
165 controlreply(sender
, "A group with that name already exists.");
169 snprintf(createdby
, sizeof(createdby
), "#%s", sender
->authname
);
174 flags
|= TRUST_RELIABLE_USERNAME
;
177 flags
|= TRUST_ENFORCE_IDENT
;
179 itg
.trustedfor
= howmany
;
181 itg
.maxperident
= maxperident
;
183 itg
.createdby
= getsstring(createdby
, CREATEDBYLEN
);
184 itg
.contact
= getsstring(contact
, CONTACTLEN
);
185 itg
.comment
= getsstring(comment
, COMMENTLEN
);
186 itg
.name
= getsstring(name
, TRUSTNAMELEN
);
188 if(itg
.createdby
&& itg
.contact
&& itg
.comment
&& itg
.name
) {
194 freesstring(itg
.createdby
);
195 freesstring(itg
.comment
);
196 freesstring(itg
.name
);
197 freesstring(itg
.contact
);
200 controlreply(sender
, "An error occured adding the trustgroup.");
204 controlreply(sender
, "Group added.");
205 triggerhook(HOOK_TRUSTS_ADDGROUP
, tg
);
207 controlwall(NO_OPER
, NL_TRUSTS
, "%s TRUSTGROUPADD'ed '%s'", controlid(sender
), tg
->name
->content
);
208 trustlog(tg
, sender
->authname
, "Created trust group '%s' (ID #%d): howmany=%d, enforceident=%d, maxperident=%d, "
209 "createdby=%s, contact=%s, comment=%s",
210 tg
->name
->content
, howmany
, tg
->id
, enforceident
, maxperident
, createdby
, contact
, comment
);
215 static int trusts_cmdtrustgroupdel(void *source
, int cargc
, char **cargv
) {
217 nick
*sender
= source
;
222 tg
= tg_strtotg(cargv
[0]);
224 controlreply(sender
, "Couldn't look up trustgroup.");
228 /* Don't allow non-developers to delete protected groups. */
229 if (!noperserv_policy_command_permitted(NO_DEVELOPER
, sender
)) {
230 if(tg
->flags
& TRUST_PROTECTED
) {
231 controlreply(sender
, "You don't have the necessary privileges to modify a protected trust group.");
237 controlreply(sender
, "Delete all hosts before deleting the group.");
241 controlwall(NO_OPER
, NL_TRUSTS
, "%s TRUSTGROUPDEL'ed '%s'.", controlid(sender
), tg
->name
->content
);
242 trustlog(tg
, sender
->authname
, "Deleted group '%s'.", tg
->name
->content
);
244 triggerhook(HOOK_TRUSTS_DELGROUP
, tg
);
246 controlreply(sender
, "Group deleted.");
251 static int trusts_cmdtrustdel(void *source
, int cargc
, char **cargv
) {
254 struct irc_in_addr ip
;
256 nick
*sender
= source
;
262 tg
= tg_strtotg(cargv
[0]);
264 controlreply(sender
, "Couldn't look up trustgroup.");
269 if(!ipmask_parse(host
, &ip
, &bits
)) {
270 controlreply(sender
, "Invalid IP/mask.");
274 /* Don't allow non-developers to remove trusts for large subnets or modify protected groups. */
275 if (!noperserv_policy_command_permitted(NO_DEVELOPER
, sender
)) {
276 int minbits
= irc_in_addr_is_ipv4(&ip
)?TRUST_MIN_UNPRIVILEGED_BITS_IPV4
:TRUST_MIN_UNPRIVILEGED_BITS_IPV6
;
278 controlreply(sender
, "You don't have the necessary privileges to remove a subnet larger than /%d.", irc_bitlen(&ip
, minbits
));
282 if(tg
->flags
& TRUST_PROTECTED
) {
283 controlreply(sender
, "You don't have the necessary privileges to modify a protected trust group.");
288 for(th
=tg
->hosts
;th
;th
=th
->next
)
289 if(ipmask_check(&ip
, &th
->ip
, th
->bits
) && th
->bits
== bits
)
293 controlreply(sender
, "Couldn't find that host in that group.");
297 triggerhook(HOOK_TRUSTS_DELHOST
, th
);
299 controlreply(sender
, "Host deleted.");
301 controlwall(NO_OPER
, NL_TRUSTS
, "%s TRUSTDEL'ed %s from group '%s'.", controlid(sender
), host
, tg
->name
->content
);
302 trustlog(tg
, sender
->authname
, "Removed host '%s'.", host
);
307 static int modifycomment(void *arg
, char *comment
, nick
*source
, int override
) {
308 trustgroup
*tg
= arg
;
309 sstring
*n
= getsstring(comment
, COMMENTLEN
);
313 freesstring(tg
->comment
);
319 static int modifycontact(void *arg
, char *contact
, nick
*source
, int override
) {
320 trustgroup
*tg
= arg
;
321 sstring
*n
= getsstring(contact
, CONTACTLEN
);
325 freesstring(tg
->contact
);
331 static int modifytrustedfor(void *arg
, char *num
, nick
*source
, int override
) {
332 trustgroup
*tg
= arg
;
333 long trustedfor
= strtol(num
, NULL
, 10);
336 controlreply(source
, "The clone limit must not be negative.");
341 if (trustedfor
== 0) {
342 controlreply(source
, "You don't have the necessary privileges to set an unlimited clone limit.");
346 if (trustedfor
> MAXTRUSTEDFOR
) {
347 controlreply(source
, "You don't have the necessary privileges to set the clone limit to a value higher than %d.", MAXTRUSTEDFOR
);
352 tg
->trustedfor
= trustedfor
;
357 static int modifymaxperident(void *arg
, char *num
, nick
*source
, int override
) {
358 trustgroup
*tg
= arg
;
359 long maxperident
= strtol(num
, NULL
, 10);
361 if(maxperident
< 0) {
362 controlreply(source
, "Ident limit must not be negative.");
366 if(maxperident
> MAXPERIDENT
) {
367 controlreply(source
, "Ident limit must not be higher than %d. Consider setting it to 0 (unlimited) instead.", MAXPERIDENT
);
371 tg
->maxperident
= maxperident
;
376 static int modifyenforceident(void *arg
, char *num
, nick
*source
, int override
) {
377 trustgroup
*tg
= arg
;
380 tg
->flags
|= TRUST_ENFORCE_IDENT
;
381 } else if(num
[0] == '0') {
382 tg
->flags
&= ~TRUST_ENFORCE_IDENT
;
390 static int modifyreliableusername(void *arg
, char *num
, nick
*source
, int override
) {
391 trustgroup
*tg
= arg
;
394 tg
->flags
|= TRUST_RELIABLE_USERNAME
;
395 } else if(num
[0] == '0') {
396 tg
->flags
&= ~TRUST_RELIABLE_USERNAME
;
404 static int modifyexpires(void *arg
, char *expires
, nick
*source
, int override
) {
405 trustgroup
*tg
= arg
;
406 int howlong
= durationtolong(expires
);
408 if((howlong
< 0) || (howlong
> MAXDURATION
)) {
409 controlreply(source
, "Duration cannot be negative or greater than %s (use 0 instead if you don't want the group to expire).", longtoduration(MAXDURATION
, 0));
414 tg
->expires
= getnettime() + howlong
;
416 tg
->expires
= 0; /* never */
421 static int modifycleanup(void *arg
, char *num
, nick
*source
, int override
) {
422 trustgroup
*tg
= arg
;
425 controlreply(source
, "You don't have the necessary privileges to modify this attribute.");
430 tg
->flags
&= ~TRUST_NO_CLEANUP
;
431 } else if(num
[0] == '0') {
432 tg
->flags
|= TRUST_NO_CLEANUP
;
440 static int modifyprotected(void *arg
, char *num
, nick
*source
, int override
) {
441 trustgroup
*tg
= arg
;
444 controlreply(source
, "You don't have the necessary privileges to modify this attribute.");
449 tg
->flags
|= TRUST_PROTECTED
;
450 } else if(num
[0] == '0') {
451 tg
->flags
&= ~TRUST_PROTECTED
;
459 static int modifymaxpernode(void *arg
, char *num
, nick
*source
, int override
) {
461 int maxpernode
= strtol(num
, NULL
, 10);
464 controlreply(source
, "Node limit must not be negative.");
468 if(maxpernode
>MAXPERNODE
) {
469 controlreply(source
, "Node limit must not be higher than %d. Consider setting it to 0 (unlimited) instead.", MAXPERNODE
);
473 th
->maxpernode
= maxpernode
;
478 static int modifynodebits(void *arg
, char *num
, nick
*source
, int override
) {
480 int nodebits
= strtol(num
, NULL
, 10);
483 controlreply(source
, "Node bits must not be negative.");
487 if(irc_in_addr_is_ipv4(&th
->ip
))
491 controlreply(source
, "Node bits is invalid.");
496 int minbits
= irc_in_addr_is_ipv4(&th
->ip
)?TRUST_MIN_UNPRIVILEGED_NODEBITS_IPV4
:TRUST_MIN_UNPRIVILEGED_NODEBITS_IPV6
;
498 if(nodebits
< minbits
) {
499 controlreply(source
, "You don't have the necessary privileges to set node bits to a subnet larger than /%d.", irc_bitlen(&th
->ip
, minbits
));
504 if(nodebits
<th
->bits
) {
505 controlreply(source
, "Node bits must be smaller or equal to the trusted CIDR's subnet size.");
509 th
->nodebits
= nodebits
;
514 static array trustgroupmods_a
;
515 static struct trustmodification
*trustgroupmods
;
516 static array trusthostmods_a
;
517 static struct trustmodification
*trusthostmods
;
519 static int trusts_cmdtrustgroupmodify(void *source
, int cargc
, char **cargv
) {
521 nick
*sender
= source
;
528 tg
= tg_strtotg(cargv
[0]);
530 controlreply(sender
, "Couldn't look up trustgroup.");
537 override
= noperserv_policy_command_permitted(NO_DEVELOPER
, sender
);
539 /* Don't allow non-developers to modify protected groups. */
540 if (!override
&& tg
->flags
& TRUST_PROTECTED
) {
541 controlreply(sender
, "You don't have the necessary privileges to modify a protected trust group.");
545 for(i
=0;i
<trustgroupmods_a
.cursi
;i
++) {
546 if(!strcmp(what
, trustgroupmods
[i
].name
)) {
547 if(!(trustgroupmods
[i
].fn
)(tg
, to
, sender
, override
)) {
548 controlreply(sender
, "An error occured changing that property, check the syntax.");
555 if(i
== trustgroupmods_a
.cursi
)
558 triggerhook(HOOK_TRUSTS_MODIFYGROUP
, tg
);
560 controlreply(sender
, "Group modified.");
562 controlwall(NO_OPER
, NL_TRUSTS
, "%s TRUSTMODIFIED'ed group '%s' (field: %s, value: %s)", controlid(sender
), tg
->name
->content
, what
, to
);
563 trustlog(tg
, sender
->authname
, "Modified %s: %s", what
, to
);
568 static int trusts_cmdtrusthostmodify(void *source
, int cargc
, char **cargv
) {
571 nick
*sender
= source
;
574 struct irc_in_addr ip
;
580 tg
= tg_strtotg(cargv
[0]);
582 controlreply(sender
, "Couldn't look up trustgroup.");
586 if(!ipmask_parse(cargv
[1], &ip
, &bits
)) {
587 controlreply(sender
, "Invalid host.");
591 /* Don't allow non-developers to modify trusts for large subnets or modify protected groups. */
592 if (!noperserv_policy_command_permitted(NO_DEVELOPER
, sender
)) {
593 int minbits
= irc_in_addr_is_ipv4(&ip
)?TRUST_MIN_UNPRIVILEGED_BITS_IPV4
:TRUST_MIN_UNPRIVILEGED_BITS_IPV6
;
595 controlreply(sender
, "You don't have the necessary privileges to modify a subnet larger than /%d.", irc_bitlen(&ip
, minbits
));
599 if(tg
->flags
& TRUST_PROTECTED
) {
600 controlreply(sender
, "You don't have the necessary privileges to modify a protected trust group.");
605 th
= th_getbyhostandmask(&ip
, bits
);
607 if(!th
|| th
->group
!= tg
) {
608 controlreply(sender
, "Host does not belong to the specified group.");
615 override
= noperserv_policy_command_permitted(NO_DEVELOPER
, sender
);
617 for(i
=0;i
<trusthostmods_a
.cursi
;i
++) {
618 if(!strcmp(what
, trusthostmods
[i
].name
)) {
619 if(!(trusthostmods
[i
].fn
)(th
, to
, sender
, override
)) {
620 controlreply(sender
, "An error occured changing that property, check the syntax.");
627 if(i
== trusthostmods_a
.cursi
)
630 triggerhook(HOOK_TRUSTS_MODIFYHOST
, th
);
632 controlreply(sender
, "Host modified.");
634 controlwall(NO_OPER
, NL_TRUSTS
, "%s TRUSTMODIFIED'ed host '%s' in group '%s' (field: %s, value: %s)", controlid(sender
), CIDRtostr(ip
, bits
), tg
->name
->content
, what
, to
);
635 trustlog(tg
, sender
->authname
, "Modified %s for host '%s': %s", what
, CIDRtostr(ip
, bits
), to
);
640 static int trusts_cmdtrustlog(void *source
, int cargc
, char **cargv
) {
641 nick
*sender
= source
;
650 limit
= strtol(cargv
[1], NULL
, 10);
657 if (name
[0] == '#') {
658 groupid
= strtol(name
+ 1, NULL
, 10);
659 trustlogspewid(sender
, groupid
, limit
);
661 trustlogspewname(sender
, name
, limit
);
667 static int trusts_cmdtrustloggrep(void *source
, int cargc
, char **cargv
) {
668 nick
*sender
= source
;
678 limit
= strtol(cargv
[1], NULL
, 10);
683 trustloggrep(sender
, pattern
, limit
);
688 static int trusts_cmdtrustcomment(void *source
, int cargc
, char **cargv
) {
689 nick
*sender
= source
;
690 trustgroup
*tg
= NULL
;
691 char *name
, *comment
;
699 if(strlen(comment
)>TRUSTLOGLEN
) {
700 controlreply(sender
, "Your comment is too long (max: %d characters).", TRUSTLOGLEN
);
704 tg
= tg_strtotg(name
);
707 controlreply(sender
, "Invalid trust group name or ID.");
711 controlwall(NO_OPER
, NL_TRUSTS
, "%s TRUSTCOMMENT'ed group '%s': %s", controlid(sender
), tg
->name
->content
, comment
);
712 trustlog(tg
, sender
->authname
, "Comment: %s", comment
);
717 static void cleanuptrusts(void *arg
);
719 static int trusts_cmdtrustcleanup(void *source
, int cargc
, char **cargv
) {
720 cleanuptrusts(source
);
722 controlreply(source
, "Done.");
728 static int commandsregistered
;
730 static void registercommands(int hooknum
, void *arg
) {
731 static char tgmhelp
[512], thmhelp
[512];
732 char validfields
[512];
736 if(commandsregistered
)
738 commandsregistered
= 1;
740 registercontrolhelpcmd("trustgroupadd", NO_OPER
, 6, trusts_cmdtrustgroupadd
, "Usage: trustgroupadd <name> <howmany> <maxperident> <enforceident> <contact> ?comment?");
741 registercontrolhelpcmd("trustadd", NO_OPER
, 2, trusts_cmdtrustadd
, "Usage: trustadd <#id|name|id> <host>");
742 registercontrolhelpcmd("trustgroupdel", NO_OPER
, 1, trusts_cmdtrustgroupdel
, "Usage: trustgroupdel <#id|name|id>");
743 registercontrolhelpcmd("trustdel", NO_OPER
, 2, trusts_cmdtrustdel
, "Usage: trustdel <#id|name|id> <ip/mask>");
745 sbinit(&b
, validfields
, sizeof(validfields
));
746 for(i
=0;i
<trustgroupmods_a
.cursi
;i
++) {
749 sbaddstr(&b
, trustgroupmods
[i
].name
);
753 snprintf(tgmhelp
, sizeof(tgmhelp
), "Usage: trustgroupmodify <#id|name|id> <field> <new value>\nModifies a trust group.\nValid fields: %s", validfields
);
754 registercontrolhelpcmd("trustgroupmodify", NO_OPER
, 3, trusts_cmdtrustgroupmodify
, tgmhelp
);
756 sbinit(&b
, validfields
, sizeof(validfields
));
757 for(i
=0;i
<trusthostmods_a
.cursi
;i
++) {
760 sbaddstr(&b
, trusthostmods
[i
].name
);
764 snprintf(thmhelp
, sizeof(thmhelp
), "Usage: trusthostmodify <#id|name|id> <host> <field> <new value>\nModifies a trust host\nValid fields: %s", validfields
);
765 registercontrolhelpcmd("trusthostmodify", NO_OPER
, 4, trusts_cmdtrusthostmodify
, thmhelp
);
767 registercontrolhelpcmd("trustlog", NO_OPER
, 2, trusts_cmdtrustlog
, "Usage: trustlog <#id|name> ?limit?\nShows log for the specified trust group.");
768 registercontrolhelpcmd("trustloggrep", NO_OPER
, 2, trusts_cmdtrustloggrep
, "Usage trustloggrep <pattern> ?limit?\nShows maching log entries.");
769 registercontrolhelpcmd("trustcomment", NO_OPER
, 2, trusts_cmdtrustcomment
, "Usage: trustcomment <#id|name> <comment>\nLogs a comment for a trust.");
770 registercontrolhelpcmd("trustcleanup", NO_DEVELOPER
, 0, trusts_cmdtrustcleanup
, "Usage: trustcleanup\nCleans up unused trusts.");
773 static void deregistercommands(int hooknum
, void *arg
) {
774 if(!commandsregistered
)
776 commandsregistered
= 0;
778 deregistercontrolcmd("trustgroupadd", trusts_cmdtrustgroupadd
);
779 deregistercontrolcmd("trustadd", trusts_cmdtrustadd
);
780 deregistercontrolcmd("trustgroupdel", trusts_cmdtrustgroupdel
);
781 deregistercontrolcmd("trustdel", trusts_cmdtrustdel
);
782 deregistercontrolcmd("trustgroupmodify", trusts_cmdtrustgroupmodify
);
783 deregistercontrolcmd("trusthostmodify", trusts_cmdtrusthostmodify
);
784 deregistercontrolcmd("trustlog", trusts_cmdtrustlog
);
785 deregistercontrolcmd("trustloggrep", trusts_cmdtrustloggrep
);
786 deregistercontrolcmd("trustcomment", trusts_cmdtrustcomment
);
787 deregistercontrolcmd("trustcleanup", trusts_cmdtrustcleanup
);
792 #define _ms_(x) (struct trustmodification){ .name = # x, .fn = modify ## x }
793 #define MSGROUP(x) { int slot = array_getfreeslot(&trustgroupmods_a); trustgroupmods = (struct trustmodification *)trustgroupmods_a.content; memcpy(&trustgroupmods[slot], &_ms_(x), sizeof(struct trustmodification)); }
794 #define MSHOST(x) { int slot = array_getfreeslot(&trusthostmods_a); trusthostmods = (struct trustmodification *)trusthostmods_a.content; memcpy(&trusthostmods[slot], &_ms_(x), sizeof(struct trustmodification)); }
796 static void setupmods(void) {
798 MSGROUP(enforceident
);
799 MSGROUP(reliableusername
);
800 MSGROUP(maxperident
);
811 static int cleanuptrusts_active
;
813 static void cleanuptrusts(void *arg
) {
814 unsigned int now
, to_age
;
815 nick
*np
= (nick
*)arg
;
818 int thcount
= 0, tgcount
= 0;
820 array expiredths
, expiredtgs
;
823 to_age
= now
- (CLEANUP_TH_INACTIVE
* 3600 * 24);
826 controlwall(NO_OPER
, NL_TRUSTS
, "CLEANUPTRUSTS: Manually started by %s.", np
->nick
);
828 controlwall(NO_OPER
, NL_TRUSTS
, "CLEANUPTRUSTS: Automatically started.");
831 if (cleanuptrusts_active
) {
832 controlwall(NO_OPER
, NL_TRUSTS
, "CLEANUPTRUSTS: ABORTED! Cleanup already in progress! BUG BUG BUG!");
836 cleanuptrusts_active
=1;
838 array_init(&expiredtgs
, sizeof(trustgroup
*));
840 for(tg
=tglist
;tg
;tg
=tg
->next
) {
841 array_init(&expiredths
, sizeof(trusthost
*));
843 if(tg
->flags
& TRUST_NO_CLEANUP
)
846 for(th
=tg
->hosts
;th
;th
=th
->next
) {
847 if((th
->count
== 0 && th
->created
< to_age
&& th
->lastseen
< to_age
) || (tg
->expires
&& tg
->expires
< now
)) {
848 int pos
= array_getfreeslot(&expiredths
);
849 ((trusthost
**)(expiredths
.content
))[pos
] = th
;
853 for(i
=0;i
<expiredths
.cursi
;i
++) {
856 th
= ((trusthost
**)(expiredths
.content
))[i
];
857 triggerhook(HOOK_TRUSTS_DELHOST
, th
);
859 cidrstr
= CIDRtostr(th
->ip
, th
->bits
);
860 trustlog(tg
, "cleanuptrusts", "Removed host '%s' because it was unused for %d days.", cidrstr
, CLEANUP_TH_INACTIVE
);
868 int pos
= array_getfreeslot(&expiredtgs
);
869 ((trustgroup
**)(expiredtgs
.content
))[pos
] = tg
;
873 for(i
=0;i
<expiredtgs
.cursi
;i
++) {
874 tg
= ((trustgroup
**)(expiredtgs
.content
))[i
];
875 triggerhook(HOOK_TRUSTS_DELGROUP
, tg
);
876 trustlog(tg
, "cleanuptrusts", "Deleted group '%s' because it had no hosts left.", tg
->name
->content
);
881 controlwall(NO_OPER
, NL_TRUSTS
, "CLEANUPTRUSTS: Removed %d trust hosts (inactive for %d days) and %d empty trust groups.", thcount
, CLEANUP_TH_INACTIVE
, tgcount
);
883 cleanuptrusts_active
=0;
886 static void schedulecleanup(int hooknum
, void *arg
) {
887 /* run at 1am but only if we're more than 15m away from it, otherwise run tomorrow */
889 time_t t
= time(NULL
);
890 time_t next_run
= ((t
/ 86400) * 86400 + 86400) + 3600;
891 if(next_run
- t
< 900)
894 schedulerecurring(next_run
,0,86400,cleanuptrusts
,NULL
);
900 array_init(&trustgroupmods_a
, sizeof(struct trustmodification
));
901 array_init(&trusthostmods_a
, sizeof(struct trustmodification
));
904 m
= getconfigitem("trusts", "master");
905 if(!m
|| (atoi(m
->content
) != 1)) {
906 Error("trusts_management", ERR_ERROR
, "Not a master server, not loaded.");
912 registerhook(HOOK_TRUSTS_DB_LOADED
, registercommands
);
913 registerhook(HOOK_TRUSTS_DB_LOADED
, schedulecleanup
);
914 registerhook(HOOK_TRUSTS_DB_CLOSED
, deregistercommands
);
917 registercommands(0, NULL
);
921 array_free(&trustgroupmods_a
);
922 array_free(&trusthostmods_a
);
927 deregisterhook(HOOK_TRUSTS_DB_LOADED
, registercommands
);
928 deregisterhook(HOOK_TRUSTS_DB_CLOSED
, deregistercommands
);
930 deregistercommands(0, NULL
);
932 deleteallschedules(cleanuptrusts
);