]> jfr.im git - irc/quakenet/newserv.git/blame - glines/glines_buf.c
Disable glines for test deployment.
[irc/quakenet/newserv.git] / glines / glines_buf.c
CommitLineData
cb581522
GB
1#include <stdio.h>
2#include <string.h>
a86fc0c4
GB
3#include "../lib/irc_string.h"
4#include "../irc/irc.h"
cb581522
GB
5#include "../control/control.h"
6#include "../trusts/trusts.h"
7#include "glines.h"
8
9void glinebufinit(glinebuf *gbuf, int merge) {
10 gbuf->head = NULL;
11 gbuf->merge = merge;
12}
13
14gline *glinebufadd(glinebuf *gbuf, const char *mask, const char *creator, const char *reason, time_t expire, time_t lastmod, time_t lifetime) {
15 gline *gl, *sgl, **pnext;
16
17 gl = makegline(mask); /* sets up nick,user,host,node and flags */
18
19 if (!gl) {
20 /* couldn't process gline mask */
21 Error("gline", ERR_WARNING, "Tried to add malformed G-Line %s!", mask);
22 return 0;
23 }
24
25 if (gbuf->merge) {
26 /* Check if an existing gline supercedes this mask */
27 for (sgl = gbuf->head; sgl; sgl = sgl->next) {
28 if (gline_match_mask(sgl, gl)) {
29 freegline(gl);
30 return sgl;
31 }
32 }
33
34 /* Remove older glines this gline matches */
35 for (pnext = &gbuf->head; *pnext; pnext = &((*pnext)->next)) {
36 sgl = *pnext;
37
38 if (gline_match_mask(gl, sgl)) {
39 *pnext = sgl->next;
40 freegline(sgl);
a86fc0c4
GB
41
42 if (!*pnext)
43 break;
cb581522
GB
44 }
45 }
46 }
47
48 gl->creator = getsstring(creator, 255);
49
50 /* it's not unreasonable to assume gline is active, if we're adding a deactivated gline, we can remove this later */
51 gl->flags |= GLINE_ACTIVE;
52
53 gl->reason = getsstring(reason, 255);
54 gl->expire = expire;
55 gl->lastmod = lastmod;
56 gl->lifetime = lifetime;
57
58 gl->next = gbuf->head;
59 gbuf->head = gl;
60
61 return gl;
62}
63
64void glinebufaddbyip(glinebuf *gbuf, const char *user, struct irc_in_addr *ip, unsigned char bits, int flags, const char *creator, const char *reason, time_t expire, time_t lastmod, time_t lifetime) {
65 trusthost *th, *oth;
66 char mask[512];
67 unsigned char nodebits;
68
69 nodebits = getnodebits(ip);
70
71 if (!(flags & GLINE_IGNORE_TRUST)) {
72 th = th_getbyhost(ip);
73
74 if (th && (th->group->flags & TRUST_RELIABLE_USERNAME)) { /* Trust with reliable usernames */
a86fc0c4 75 for (oth = th->group->hosts; oth; oth = oth->next)
cb581522 76 glinebufaddbyip(gbuf, user, &oth->ip, oth->bits, flags | GLINE_ALWAYS_USER | GLINE_IGNORE_TRUST, creator, reason, expire, lastmod, lifetime);
a86fc0c4
GB
77
78 return;
cb581522
GB
79 }
80 }
81
82 if (!(flags & GLINE_ALWAYS_USER))
83 user = "*";
84
85 /* Widen gline to match the node mask. */
86 if (nodebits < bits)
87 bits = nodebits;
88
89 snprintf(mask, sizeof(mask), "%s@%s", user, trusts_cidr2str(ip, bits));
90
91 glinebufadd(gbuf, mask, creator, reason, expire, lastmod, lifetime);
92}
93
94void glinebufaddbynick(glinebuf *gbuf, nick *np, int flags, const char *creator, const char *reason, time_t expire, time_t lastmod, time_t lifetime) {
95 if (flags & GLINE_ALWAYS_NICK) {
96 char mask[512];
97 snprintf(mask, sizeof(mask), "%s!*@*", np->nick);
98 glinebufadd(gbuf, mask, creator, reason, expire, lastmod, lifetime);
99 } else {
100 glinebufaddbyip(gbuf, np->ident, &np->p_ipaddr, 128, flags, creator, reason, expire, lastmod, lifetime);
101 }
102}
103
104void glinebufcounthits(glinebuf *gbuf, int *users, int *channels) {
105 gline *gl;
106 int i, hit;
107 chanindex *cip;
108 channel *cp;
109 nick *np;
110
111 if (users)
112 *users = 0;
113
114 if (channels)
115 *channels = 0;
116
117 if (channels) {
118 for (i = 0; i<CHANNELHASHSIZE; i++) {
119 for (cip = chantable[i]; cip; cip = cip->next) {
120 cp = cip->channel;
121
122 if (!cp)
123 continue;
124
125 hit = 0;
126
127 for (gl = gbuf->head; gl; gl = gl->next) {
128 if (gline_match_channel(gl, cp)) {
129 hit = 1;
130 break;
131 }
132 }
133
134 if (hit)
135 (*channels)++;
136 }
137 }
138 }
139
140 if (users) {
141 for (i = 0; i < NICKHASHSIZE; i++) {
142 for (np = nicktable[i]; np; np = np->next) {
143 hit = 0;
144
145 for (gl = gbuf->head; gl; gl = gl->next) {
146 if (gline_match_nick(gl, np)) {
147 hit = 1;
148 break;
149 }
150 }
151
152 if (hit)
153 (*users)++;
154 }
155 }
156 }
157}
158
a86fc0c4
GB
159int glinebufsanitize(glinebuf *gbuf) {
160 gline *gl, **pnext;
161 int skipped;
162 const char *hint;
163
164 skipped = 0;
165
166 /* Remove glines that fail the sanity check */
167 for (pnext = &gbuf->head; *pnext; pnext = &((*pnext)->next)) {
168 gl = *pnext;
169
170 if (!isglinesane(gl, &hint)) {
d892838f 171 controlwall(NO_OPER, NL_GLINES, "Sanity check failed for G-Line on '%s' lasting %s created by %s with reason '%s' - Skipping: %s",
a86fc0c4
GB
172 glinetostring(gl), longtoduration(gl->expire-getnettime(), 0),
173 gl->reason->content, gl->creator->content, hint);
174
175 *pnext = gl->next;
176 freegline(gl);
177
178 skipped++;
179
180 if (!*pnext)
181 break;
182 }
183 }
184
185 return skipped;
186}
187
188void glinebufspew(glinebuf *gbuf, nick *np) {
189 gline *gl;
190
191 for (gl = gbuf->head; gl; gl = gl->next)
192 controlreply(np, "mask: %s", glinetostring(gl));
193}
194
cb581522
GB
195void glinebufflush(glinebuf *gbuf, int propagate) {
196 gline *gl, *next, *sgl;
197 int users, channels;
198
199 /* Sanity check */
200 glinebufcounthits(gbuf, &users, &channels);
201
202 if (propagate && (users > MAXGLINEUSERHITS || channels > MAXGLINECHANNELHITS)) {
203 controlwall(NO_OPER, NL_GLINES, "G-Line buffer would hit %d users/%d channels. Not setting G-Lines.");
204 glinebufabandon(gbuf);
205 return;
206 }
207
208 for (gl = gbuf->head; gl; gl = next) {
209 next = gl->next;
210
211 sgl = findgline(glinetostring(gl));
212
213 if (sgl) {
214 /* existing gline
215 * in 1.4, can update expire, reason etc
216 * in 1.3 can only activate/deactivate an existing gline */
217
218 if (gl->flags & GLINE_ACTIVE && !(sgl->flags & GLINE_ACTIVE))
219 gline_activate(sgl, 0, 0);
220 else if (!(gl->flags & GLINE_ACTIVE) && sgl->flags & GLINE_ACTIVE)
221 gline_deactivate(sgl, 0, 0);
222
223 freegline(gl);
224 gl = sgl;
225 } else {
226 gl->next = glinelist;
227 glinelist = gl;
228 }
229
230 if (propagate)
231 gline_propagate(gl);
232 }
233}
234
235void glinebufabandon(glinebuf *gbuf) {
236 gline *gl, *next;
237
238 for (gl = gbuf->head; gl; gl = next) {
239 next = gl->next;
240
241 freegline(gl);
242 }
243}