]> jfr.im git - irc/quakenet/newserv.git/blob - trusts/trusts_policy.c
trusts_policy: Fix per-node user count.
[irc/quakenet/newserv.git] / trusts / trusts_policy.c
1 #include "../core/hooks.h"
2 #include "../control/control.h"
3 #include "../lib/irc_string.h"
4 #include "trusts.h"
5
6 static int countext;
7
8 static void policycheck(int hooknum, void *arg) {
9 void **args = arg;
10 nick *np = args[0];
11 long moving = (long)args[1];
12 trusthost *th = gettrusthost(np);
13 trustgroup *tg;
14 patricia_node_t *head, *node;
15 int nodecount = 0;
16
17 if(moving)
18 return;
19
20 if(!th)
21 return;
22
23 tg = th->group;
24
25 head = refnode(iptree, &np->p_ipaddr, th->nodebits);
26 PATRICIA_WALK(head, node)
27 {
28 nodecount += node->usercount;
29 }
30 PATRICIA_WALK_END;
31 derefnode(iptree, head);
32
33 if(th->maxpernode && nodecount > th->maxpernode) {
34 controlwall(NO_OPER, NL_TRUSTS, "Hard connection limit exceeded on IP: %s (group: %s) %d connected, %d max.", IPtostr(np->p_ipaddr), tg->name->content, np->ipnode->usercount, th->maxpernode);
35 return;
36 }
37
38 /*
39 * the purpose of this logic is to avoid spam like this:
40 * WARNING: tgX exceeded limit: 11 connected vs 10 max
41 * (goes back down to 10)
42 * WARNING: tgX exceeded limit: 11 connected vs 10 max
43 */
44
45 if(hooknum == HOOK_TRUSTS_NEWNICK) {
46 if(tg->trustedfor && tg->count > tg->trustedfor) {
47 /*
48 if(tg->count > (long)tg->exts[countext]) {
49
50 tg->exts[countext] = (void *)(long)tg->count;
51 */
52 controlwall(NO_OPER, NL_TRUSTS, "Hard connection limit exceeded: '%s', %d connected, %d max.", tg->name->content, tg->count, tg->trustedfor);
53 }
54 /*
55 }
56 */
57 if((tg->mode == 1) && (np->ident[0] == '~'))
58 controlwall(NO_OPER, NL_TRUSTS, "Ident required: '%s' %s!%s@%s.", tg->name->content, np->nick, np->ident, np->host->name->content);
59
60 if(tg->maxperident > 0) {
61 int identcount = 0;
62 trusthost *th2;
63 nick *tnp;
64
65 for(th2=tg->hosts;th2;th2=th2->next) {
66 for(tnp=th2->users;tnp;tnp=nextbytrust(tnp)) {
67 if(!ircd_strcmp(tnp->ident, np->ident))
68 identcount++;
69 }
70 }
71
72 if(identcount > tg->maxperident)
73 controlwall(NO_OPER, NL_TRUSTS, "Hard ident limit exceeded: '%s' %s!%s@%s, %d connected, %d max.", tg->name->content, np->nick, np->ident, np->host->name->content, identcount, tg->maxperident);
74 }
75 } else {
76 if(tg->count < tg->maxusage)
77 tg->exts[countext] = (void *)(long)tg->count;
78 }
79 }
80
81 void _init(void) {
82 countext = registertgext("count");
83 if(countext == -1)
84 return;
85
86 registerhook(HOOK_TRUSTS_NEWNICK, policycheck);
87 registerhook(HOOK_TRUSTS_LOSTNICK, policycheck);
88 }
89
90 void _fini(void) {
91 if(countext == -1)
92 return;
93
94 releasetgext(countext);
95
96 deregisterhook(HOOK_TRUSTS_NEWNICK, policycheck);
97 deregisterhook(HOOK_TRUSTS_LOSTNICK, policycheck);
98 }