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