]> jfr.im git - irc/quakenet/newserv.git/blob - trusts/trusts_policy.c
Merge default.
[irc/quakenet/newserv.git] / trusts / trusts_policy.c
1 #include "../core/hooks.h"
2 #include "../core/config.h"
3 #include "../control/control.h"
4 #include "../lib/irc_string.h"
5 #include "../irc/irc.h"
6 #include "../glines/glines.h"
7 #include "trusts.h"
8
9 static int countext, enforcepolicy;
10
11 static void policycheck(int hooknum, void *arg) {
12 void **args = arg;
13 nick *np = args[0];
14 long moving = (long)args[1];
15 trusthost *th = gettrusthost(np);
16 trustgroup *tg;
17 patricia_node_t *head, *node;
18 int nodecount = 0;
19
20 if(moving)
21 return;
22
23 if(!th)
24 return;
25
26 tg = th->group;
27
28 head = refnode(iptree, &np->p_nodeaddr, th->nodebits);
29 PATRICIA_WALK(head, node)
30 {
31 nodecount += node->usercount;
32 }
33 PATRICIA_WALK_END;
34 derefnode(iptree, head);
35
36 if(th->maxpernode && nodecount > th->maxpernode) {
37 controlwall(NO_OPER, NL_TRUSTS, "Hard connection limit exceeded on subnet: %s (group: %s) %d connected, %d max.", trusts_cidr2str(&np->p_nodeaddr, th->nodebits), tg->name->content, nodecount, th->maxpernode);
38
39 if(enforcepolicy)
40 glinebynick(np, POLICY_GLINE_DURATION, "Too many connections from your host.", GLINE_IGNORE_TRUST);
41
42 return;
43 }
44
45 /*
46 * the purpose of this logic is to avoid spam like this:
47 * WARNING: tgX exceeded limit: 11 connected vs 10 max
48 * (goes back down to 10)
49 * WARNING: tgX exceeded limit: 11 connected vs 10 max
50 */
51
52 if(hooknum == HOOK_TRUSTS_NEWNICK) {
53 if(tg->trustedfor && tg->count > tg->trustedfor) {
54 /*
55 if(tg->count > (long)tg->exts[countext]) {
56
57 tg->exts[countext] = (void *)(long)tg->count;
58 */
59 controlwall(NO_OPER, NL_TRUSTS, "Hard connection limit exceeded: '%s', %d connected, %d max.", tg->name->content, tg->count, tg->trustedfor);
60 }
61 /*
62 }
63 */
64 if((tg->mode == 1) && (np->ident[0] == '~')) {
65 controlwall(NO_OPER, NL_TRUSTS, "Ident required: '%s' %s!%s@%s.", tg->name->content, np->nick, np->ident, np->host->name->content);
66
67 if (enforcepolicy)
68 glinebynick(np, POLICY_GLINE_DURATION, "IDENTD required from your host.", GLINE_ALWAYS_USER|GLINE_IGNORE_TRUST);
69 }
70
71 if(tg->maxperident > 0) {
72 int identcount = 0;
73 trusthost *th2;
74 nick *tnp;
75
76 for(th2=tg->hosts;th2;th2=th2->next) {
77 for(tnp=th2->users;tnp;tnp=nextbytrust(tnp)) {
78 if(!ircd_strcmp(tnp->ident, np->ident))
79 identcount++;
80 }
81 }
82
83 if(identcount > tg->maxperident) {
84 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);
85
86 if (enforcepolicy)
87 glinebynick(np, POLICY_GLINE_DURATION, "Too many connections from your user.", GLINE_ALWAYS_USER|GLINE_IGNORE_TRUST);
88 }
89 }
90 } else {
91 if(tg->count < tg->maxusage)
92 tg->exts[countext] = (void *)(long)tg->count;
93 }
94 }
95
96 static int trusts_cmdtrustpolicy(void *source, int cargc, char **cargv) {
97 nick *sender = source;
98
99 if(cargc < 1) {
100 controlreply(sender, "Trust policy enforcement is currently %s.", enforcepolicy?"enabled":"disabled");
101 return CMD_OK;
102 }
103
104 enforcepolicy = atoi(cargv[0]);
105 controlwall(NO_OPER, NL_TRUSTS, "%s %s trust policy enforcement.", controlid(sender), enforcepolicy?"enabled":"disabled");
106 controlreply(sender, "Trust policy enforcement is now %s.", enforcepolicy?"enabled":"disabled");
107
108 return CMD_OK;
109 }
110
111 void _init(void) {
112 countext = registertgext("count");
113 if(countext == -1)
114 return;
115
116 sstring *m;
117
118 m = getconfigitem("trusts_policy", "enforcepolicy");
119 if(m)
120 enforcepolicy = atoi(m->content);
121
122 registerhook(HOOK_TRUSTS_NEWNICK, policycheck);
123 registerhook(HOOK_TRUSTS_LOSTNICK, policycheck);
124
125 registercontrolhelpcmd("trustpolicy", NO_DEVELOPER, 1, trusts_cmdtrustpolicy, "Usage: trustpolicy ?1|0?\nEnables or disables policy enforcement. Shows current status when no parameter is specified.");
126 }
127
128 void _fini(void) {
129 if(countext == -1)
130 return;
131
132 releasetgext(countext);
133
134 deregisterhook(HOOK_TRUSTS_NEWNICK, policycheck);
135 deregisterhook(HOOK_TRUSTS_LOSTNICK, policycheck);
136
137 deregistercontrolcmd("trustpolicy", trusts_cmdtrustpolicy);
138 }