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 int minbits
= irc_in_addr_is_ipv4(&th
->ip
)?TRUST_MIN_UNPRIVILEGED_NODEBITS_IPV4
:TRUST_MIN_UNPRIVILEGED_NODEBITS_IPV6
;
493 if(nodebits
< minbits
) {
494 controlreply(source
, "You don't have the necessary privileges to set node bits to a subnet larger than /%d.", irc_bitlen(&th
->ip
, minbits
));
499 if(nodebits
<th
->bits
) {
500 controlreply(source
, "Node bits must be smaller or equal to the trusted CIDR's subnet size.");
504 th
->nodebits
= nodebits
;
509 static array trustgroupmods_a
;
510 static struct trustmodification
*trustgroupmods
;
511 static array trusthostmods_a
;
512 static struct trustmodification
*trusthostmods
;
514 static int trusts_cmdtrustgroupmodify(void *source
, int cargc
, char **cargv
) {
516 nick
*sender
= source
;
523 tg
= tg_strtotg(cargv
[0]);
525 controlreply(sender
, "Couldn't look up trustgroup.");
532 override
= noperserv_policy_command_permitted(NO_DEVELOPER
, sender
);
534 /* Don't allow non-developers to modify protected groups. */
535 if (!override
&& tg
->flags
& TRUST_PROTECTED
) {
536 controlreply(sender
, "You don't have the necessary privileges to modify a protected trust group.");
540 for(i
=0;i
<trustgroupmods_a
.cursi
;i
++) {
541 if(!strcmp(what
, trustgroupmods
[i
].name
)) {
542 if(!(trustgroupmods
[i
].fn
)(tg
, to
, sender
, override
)) {
543 controlreply(sender
, "An error occured changing that property, check the syntax.");
550 if(i
== trustgroupmods_a
.cursi
)
553 triggerhook(HOOK_TRUSTS_MODIFYGROUP
, tg
);
555 controlreply(sender
, "Group modified.");
557 controlwall(NO_OPER
, NL_TRUSTS
, "%s TRUSTMODIFIED'ed group '%s' (field: %s, value: %s)", controlid(sender
), tg
->name
->content
, what
, to
);
558 trustlog(tg
, sender
->authname
, "Modified %s: %s", what
, to
);
563 static int trusts_cmdtrusthostmodify(void *source
, int cargc
, char **cargv
) {
566 nick
*sender
= source
;
569 struct irc_in_addr ip
;
575 tg
= tg_strtotg(cargv
[0]);
577 controlreply(sender
, "Couldn't look up trustgroup.");
581 if(!ipmask_parse(cargv
[1], &ip
, &bits
)) {
582 controlreply(sender
, "Invalid host.");
586 /* Don't allow non-developers to modify trusts for large subnets or modify protected groups. */
587 if (!noperserv_policy_command_permitted(NO_DEVELOPER
, sender
)) {
588 int minbits
= irc_in_addr_is_ipv4(&ip
)?TRUST_MIN_UNPRIVILEGED_BITS_IPV4
:TRUST_MIN_UNPRIVILEGED_BITS_IPV6
;
590 controlreply(sender
, "You don't have the necessary privileges to modify a subnet larger than /%d.", irc_bitlen(&ip
, minbits
));
594 if(tg
->flags
& TRUST_PROTECTED
) {
595 controlreply(sender
, "You don't have the necessary privileges to modify a protected trust group.");
600 th
= th_getbyhostandmask(&ip
, bits
);
602 if(!th
|| th
->group
!= tg
) {
603 controlreply(sender
, "Host does not belong to the specified group.");
610 override
= noperserv_policy_command_permitted(NO_DEVELOPER
, sender
);
612 for(i
=0;i
<trusthostmods_a
.cursi
;i
++) {
613 if(!strcmp(what
, trusthostmods
[i
].name
)) {
614 if(!(trusthostmods
[i
].fn
)(th
, to
, sender
, override
)) {
615 controlreply(sender
, "An error occured changing that property, check the syntax.");
622 if(i
== trusthostmods_a
.cursi
)
625 triggerhook(HOOK_TRUSTS_MODIFYHOST
, th
);
627 controlreply(sender
, "Host modified.");
629 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
);
630 trustlog(tg
, sender
->authname
, "Modified %s for host '%s': %s", what
, CIDRtostr(ip
, bits
), to
);
635 static int trusts_cmdtrustlog(void *source
, int cargc
, char **cargv
) {
636 nick
*sender
= source
;
645 limit
= strtol(cargv
[1], NULL
, 10);
652 if (name
[0] == '#') {
653 groupid
= strtol(name
+ 1, NULL
, 10);
654 trustlogspewid(sender
, groupid
, limit
);
656 trustlogspewname(sender
, name
, limit
);
662 static int trusts_cmdtrustloggrep(void *source
, int cargc
, char **cargv
) {
663 nick
*sender
= source
;
673 limit
= strtol(cargv
[1], NULL
, 10);
678 trustloggrep(sender
, pattern
, limit
);
683 static int trusts_cmdtrustcomment(void *source
, int cargc
, char **cargv
) {
684 nick
*sender
= source
;
685 trustgroup
*tg
= NULL
;
686 char *name
, *comment
;
694 if(strlen(comment
)>TRUSTLOGLEN
) {
695 controlreply(sender
, "Your comment is too long (max: %d characters).", TRUSTLOGLEN
);
699 tg
= tg_strtotg(name
);
702 controlreply(sender
, "Invalid trust group name or ID.");
706 controlwall(NO_OPER
, NL_TRUSTS
, "%s TRUSTCOMMENT'ed group '%s': %s", controlid(sender
), tg
->name
->content
, comment
);
707 trustlog(tg
, sender
->authname
, "Comment: %s", comment
);
712 static void cleanuptrusts(void *arg
);
714 static int trusts_cmdtrustcleanup(void *source
, int cargc
, char **cargv
) {
715 cleanuptrusts(source
);
717 controlreply(source
, "Done.");
723 static int commandsregistered
;
725 static void registercommands(int hooknum
, void *arg
) {
726 static char tgmhelp
[512], thmhelp
[512];
727 char validfields
[512];
731 if(commandsregistered
)
733 commandsregistered
= 1;
735 registercontrolhelpcmd("trustgroupadd", NO_OPER
, 6, trusts_cmdtrustgroupadd
, "Usage: trustgroupadd <name> <howmany> <maxperident> <enforceident> <contact> ?comment?");
736 registercontrolhelpcmd("trustadd", NO_OPER
, 2, trusts_cmdtrustadd
, "Usage: trustadd <#id|name|id> <host>");
737 registercontrolhelpcmd("trustgroupdel", NO_OPER
, 1, trusts_cmdtrustgroupdel
, "Usage: trustgroupdel <#id|name|id>");
738 registercontrolhelpcmd("trustdel", NO_OPER
, 2, trusts_cmdtrustdel
, "Usage: trustdel <#id|name|id> <ip/mask>");
740 sbinit(&b
, validfields
, sizeof(validfields
));
741 for(i
=0;i
<trustgroupmods_a
.cursi
;i
++) {
744 sbaddstr(&b
, trustgroupmods
[i
].name
);
748 snprintf(tgmhelp
, sizeof(tgmhelp
), "Usage: trustgroupmodify <#id|name|id> <field> <new value>\nModifies a trust group.\nValid fields: %s", validfields
);
749 registercontrolhelpcmd("trustgroupmodify", NO_OPER
, 3, trusts_cmdtrustgroupmodify
, tgmhelp
);
751 sbinit(&b
, validfields
, sizeof(validfields
));
752 for(i
=0;i
<trusthostmods_a
.cursi
;i
++) {
755 sbaddstr(&b
, trusthostmods
[i
].name
);
759 snprintf(thmhelp
, sizeof(thmhelp
), "Usage: trusthostmodify <#id|name|id> <host> <field> <new value>\nModifies a trust host\nValid fields: %s", validfields
);
760 registercontrolhelpcmd("trusthostmodify", NO_OPER
, 4, trusts_cmdtrusthostmodify
, thmhelp
);
762 registercontrolhelpcmd("trustlog", NO_OPER
, 2, trusts_cmdtrustlog
, "Usage: trustlog <#id|name> ?limit?\nShows log for the specified trust group.");
763 registercontrolhelpcmd("trustloggrep", NO_OPER
, 2, trusts_cmdtrustloggrep
, "Usage trustloggrep <pattern> ?limit?\nShows maching log entries.");
764 registercontrolhelpcmd("trustcomment", NO_OPER
, 2, trusts_cmdtrustcomment
, "Usage: trustcomment <#id|name> <comment>\nLogs a comment for a trust.");
765 registercontrolhelpcmd("trustcleanup", NO_DEVELOPER
, 0, trusts_cmdtrustcleanup
, "Usage: trustcleanup\nCleans up unused trusts.");
768 static void deregistercommands(int hooknum
, void *arg
) {
769 if(!commandsregistered
)
771 commandsregistered
= 0;
773 deregistercontrolcmd("trustgroupadd", trusts_cmdtrustgroupadd
);
774 deregistercontrolcmd("trustadd", trusts_cmdtrustadd
);
775 deregistercontrolcmd("trustgroupdel", trusts_cmdtrustgroupdel
);
776 deregistercontrolcmd("trustdel", trusts_cmdtrustdel
);
777 deregistercontrolcmd("trustgroupmodify", trusts_cmdtrustgroupmodify
);
778 deregistercontrolcmd("trusthostmodify", trusts_cmdtrusthostmodify
);
779 deregistercontrolcmd("trustlog", trusts_cmdtrustlog
);
780 deregistercontrolcmd("trustloggrep", trusts_cmdtrustloggrep
);
781 deregistercontrolcmd("trustcomment", trusts_cmdtrustcomment
);
782 deregistercontrolcmd("trustcleanup", trusts_cmdtrustcleanup
);
787 #define _ms_(x) (struct trustmodification){ .name = # x, .fn = modify ## x }
788 #define MSGROUP(x) { int slot = array_getfreeslot(&trustgroupmods_a); trustgroupmods = (struct trustmodification *)trustgroupmods_a.content; memcpy(&trustgroupmods[slot], &_ms_(x), sizeof(struct trustmodification)); }
789 #define MSHOST(x) { int slot = array_getfreeslot(&trusthostmods_a); trusthostmods = (struct trustmodification *)trusthostmods_a.content; memcpy(&trusthostmods[slot], &_ms_(x), sizeof(struct trustmodification)); }
791 static void setupmods(void) {
793 MSGROUP(enforceident
);
794 MSGROUP(reliableusername
);
795 MSGROUP(maxperident
);
806 static int cleanuptrusts_active
;
808 static void cleanuptrusts(void *arg
) {
809 unsigned int now
, to_age
;
810 nick
*np
= (nick
*)arg
;
813 int thcount
= 0, tgcount
= 0;
815 array expiredths
, expiredtgs
;
818 to_age
= now
- (CLEANUP_TH_INACTIVE
* 3600 * 24);
821 controlwall(NO_OPER
, NL_TRUSTS
, "CLEANUPTRUSTS: Manually started by %s.", np
->nick
);
823 controlwall(NO_OPER
, NL_TRUSTS
, "CLEANUPTRUSTS: Automatically started.");
826 if (cleanuptrusts_active
) {
827 controlwall(NO_OPER
, NL_TRUSTS
, "CLEANUPTRUSTS: ABORTED! Cleanup already in progress! BUG BUG BUG!");
831 cleanuptrusts_active
=1;
833 array_init(&expiredtgs
, sizeof(trustgroup
*));
835 for(tg
=tglist
;tg
;tg
=tg
->next
) {
836 array_init(&expiredths
, sizeof(trusthost
*));
838 if(tg
->flags
& TRUST_NO_CLEANUP
)
841 for(th
=tg
->hosts
;th
;th
=th
->next
) {
842 if((th
->count
== 0 && th
->created
< to_age
&& th
->lastseen
< to_age
) || (tg
->expires
&& tg
->expires
< now
)) {
843 int pos
= array_getfreeslot(&expiredths
);
844 ((trusthost
**)(expiredths
.content
))[pos
] = th
;
848 for(i
=0;i
<expiredths
.cursi
;i
++) {
851 th
= ((trusthost
**)(expiredths
.content
))[i
];
852 triggerhook(HOOK_TRUSTS_DELHOST
, th
);
854 cidrstr
= CIDRtostr(th
->ip
, th
->bits
);
855 trustlog(tg
, "cleanuptrusts", "Removed host '%s' because it was unused for %d days.", cidrstr
, CLEANUP_TH_INACTIVE
);
863 int pos
= array_getfreeslot(&expiredtgs
);
864 ((trustgroup
**)(expiredtgs
.content
))[pos
] = tg
;
868 for(i
=0;i
<expiredtgs
.cursi
;i
++) {
869 tg
= ((trustgroup
**)(expiredtgs
.content
))[i
];
870 triggerhook(HOOK_TRUSTS_DELGROUP
, tg
);
871 trustlog(tg
, "cleanuptrusts", "Deleted group '%s' because it had no hosts left.", tg
->name
->content
);
876 controlwall(NO_OPER
, NL_TRUSTS
, "CLEANUPTRUSTS: Removed %d trust hosts (inactive for %d days) and %d empty trust groups.", thcount
, CLEANUP_TH_INACTIVE
, tgcount
);
878 cleanuptrusts_active
=0;
881 static void schedulecleanup(int hooknum
, void *arg
) {
882 /* run at 1am but only if we're more than 15m away from it, otherwise run tomorrow */
884 time_t t
= time(NULL
);
885 time_t next_run
= ((t
/ 86400) * 86400 + 86400) + 3600;
886 if(next_run
- t
< 900)
889 schedulerecurring(next_run
,0,86400,cleanuptrusts
,NULL
);
895 array_init(&trustgroupmods_a
, sizeof(struct trustmodification
));
896 array_init(&trusthostmods_a
, sizeof(struct trustmodification
));
899 m
= getconfigitem("trusts", "master");
900 if(!m
|| (atoi(m
->content
) != 1)) {
901 Error("trusts_management", ERR_ERROR
, "Not a master server, not loaded.");
907 registerhook(HOOK_TRUSTS_DB_LOADED
, registercommands
);
908 registerhook(HOOK_TRUSTS_DB_LOADED
, schedulecleanup
);
909 registerhook(HOOK_TRUSTS_DB_CLOSED
, deregistercommands
);
912 registercommands(0, NULL
);
916 array_free(&trustgroupmods_a
);
917 array_free(&trusthostmods_a
);
922 deregisterhook(HOOK_TRUSTS_DB_LOADED
, registercommands
);
923 deregisterhook(HOOK_TRUSTS_DB_CLOSED
, deregistercommands
);
925 deregistercommands(0, NULL
);
927 deleteallschedules(cleanuptrusts
);