]> jfr.im git - solanum.git/blame - ircd/bandbi.c
authproc: don't shadow variable decls, avoid reserved name
[solanum.git] / ircd / bandbi.c
CommitLineData
83595e60
AC
1/* src/bandbi.c
2 * An interface to the ban db.
3 *
4 * Copyright (C) 2006 Lee Hardy <lee -at- leeh.co.uk>
5 * Copyright (C) 2006 ircd-ratbox development team
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * 1.Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * 2.Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3.The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
28 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
83595e60
AC
30 */
31#include "stdinc.h"
fe037171 32#include "rb_lib.h"
83595e60
AC
33#include "client.h"
34#include "s_conf.h"
35#include "logger.h"
36#include "match.h"
37#include "bandbi.h"
38#include "parse.h"
39#include "channel.h"
40#include "hostmask.h"
41#include "hash.h"
42#include "s_newconf.h"
43#include "reject.h"
44#include "send.h"
45#include "ircd.h"
46#include "msg.h" /* XXX: MAXPARA */
27f616dd 47#include "operhash.h"
83595e60
AC
48
49static char bandb_add_letter[LAST_BANDB_TYPE] = {
50 'K', 'D', 'X', 'R'
51};
52
53rb_dlink_list bandb_pending;
54
55static rb_helper *bandb_helper;
56static int start_bandb(void);
57
58static void bandb_parse(rb_helper *);
59static void bandb_restart_cb(rb_helper *);
60static char *bandb_path;
61
62void
63init_bandb(void)
64{
65 if(start_bandb())
66 {
67 ilog(L_MAIN, "Unable to start bandb helper: %s", strerror(errno));
68 exit(0);
69 }
70}
71
72
73static int
74start_bandb(void)
75{
76 char fullpath[PATH_MAX + 1];
77#ifdef _WIN32
78 const char *suffix = ".exe";
79#else
80 const char *suffix = "";
81#endif
82
4d8cfacd 83 rb_setenv("BANDB_DBPATH", ircd_paths[IRCD_PATH_BANDB], 1);
83595e60
AC
84 if(bandb_path == NULL)
85 {
4d8cfacd 86 snprintf(fullpath, sizeof(fullpath), "%s%cbandb%s", ircd_paths[IRCD_PATH_LIBEXEC], RB_PATH_SEPARATOR, suffix);
83595e60
AC
87
88 if(access(fullpath, X_OK) == -1)
89 {
4d8cfacd
AC
90 snprintf(fullpath, sizeof(fullpath), "%s%cbin%cbandb%s",
91 ConfigFileEntry.dpath, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR, suffix);
83595e60
AC
92
93 if(access(fullpath, X_OK) == -1)
94 {
95 ilog(L_MAIN,
c74836dc 96 "Unable to execute bandb%s in %s or %s/bin",
4d8cfacd 97 suffix, ircd_paths[IRCD_PATH_LIBEXEC], ConfigFileEntry.dpath);
83595e60
AC
98 return 0;
99 }
100 }
101 bandb_path = rb_strdup(fullpath);
102 }
103
104
105 bandb_helper = rb_helper_start("bandb", bandb_path, bandb_parse, bandb_restart_cb);
106
107 if(bandb_helper == NULL)
108 {
109 ilog(L_MAIN, "Unable to start bandb: %s", strerror(errno));
110 sendto_realops_snomask(SNO_GENERAL, L_ALL, "Unable to start bandb: %s",
111 strerror(errno));
112 return 1;
113 }
114
115 rb_helper_run(bandb_helper);
116 return 0;
117}
118
119void
120bandb_add(bandb_type type, struct Client *source_p, const char *mask1,
121 const char *mask2, const char *reason, const char *oper_reason, int perm)
122{
c8729b08
KB
123 if(bandb_helper == NULL)
124 return;
125
83595e60
AC
126 static char buf[BUFSIZE];
127
5203cba5 128 snprintf(buf, sizeof(buf), "%c %s ", bandb_add_letter[type], mask1);
83595e60
AC
129
130 if(!EmptyString(mask2))
131 rb_snprintf_append(buf, sizeof(buf), "%s ", mask2);
132
133 rb_snprintf_append(buf, sizeof(buf), "%s %ld %d :%s",
134 get_oper_name(source_p), (long int)rb_current_time(), perm, reason);
135
136 if(!EmptyString(oper_reason))
137 rb_snprintf_append(buf, sizeof(buf), "|%s", oper_reason);
138
139 rb_helper_write(bandb_helper, "%s", buf);
140}
141
142static char bandb_del_letter[LAST_BANDB_TYPE] = {
143 'k', 'd', 'x', 'r'
144};
145
146void
147bandb_del(bandb_type type, const char *mask1, const char *mask2)
148{
c8729b08
KB
149 if(bandb_helper == NULL)
150 return;
151
83595e60
AC
152 static char buf[BUFSIZE];
153
154 buf[0] = '\0';
155
156 rb_snprintf_append(buf, sizeof(buf), "%c %s", bandb_del_letter[type], mask1);
157
158 if(!EmptyString(mask2))
159 rb_snprintf_append(buf, sizeof(buf), " %s", mask2);
160
161 rb_helper_write(bandb_helper, "%s", buf);
162}
163
164static void
165bandb_handle_ban(char *parv[], int parc)
166{
167 struct ConfItem *aconf;
168 char *p;
169 int para = 1;
170
171 aconf = make_conf();
172 aconf->port = 0;
173
174 if(parv[0][0] == 'K')
175 aconf->user = rb_strdup(parv[para++]);
176
177 aconf->host = rb_strdup(parv[para++]);
27f616dd 178 aconf->info.oper = operhash_add(parv[para++]);
83595e60
AC
179
180 switch (parv[0][0])
181 {
182 case 'K':
183 aconf->status = CONF_KILL;
184 break;
185
186 case 'D':
187 aconf->status = CONF_DLINE;
188 break;
189
190 case 'X':
191 aconf->status = CONF_XLINE;
192 break;
193
194 case 'R':
195 if(IsChannelName(aconf->host))
196 aconf->status = CONF_RESV_CHANNEL;
197 else
198 aconf->status = CONF_RESV_NICK;
199
200 break;
201 }
202
203 if((p = strchr(parv[para], '|')))
204 {
205 *p++ = '\0';
206 aconf->spasswd = rb_strdup(p);
207 }
208
209 aconf->passwd = rb_strdup(parv[para]);
210
211 rb_dlinkAddAlloc(aconf, &bandb_pending);
212}
213
214static int
215bandb_check_kline(struct ConfItem *aconf)
216{
217 struct rb_sockaddr_storage daddr;
218 struct ConfItem *kconf = NULL;
219 int aftype;
220 const char *p;
221
29c92cf9 222 aftype = parse_netmask(aconf->host, &daddr, NULL);
83595e60
AC
223
224 if(aftype != HM_HOST)
225 {
226#ifdef RB_IPV6
227 if(aftype == HM_IPV6)
228 aftype = AF_INET6;
229 else
230#endif
231 aftype = AF_INET;
232
233 kconf = find_conf_by_address(aconf->host, NULL, NULL, (struct sockaddr *)&daddr,
234 CONF_KILL, aftype, aconf->user, NULL);
235 }
236 else
237 kconf = find_conf_by_address(aconf->host, NULL, NULL, NULL, CONF_KILL, 0, aconf->user, NULL);
238
239 if(kconf && ((kconf->flags & CONF_FLAGS_TEMPORARY) == 0))
240 return 0;
241
242 for(p = aconf->user; *p; p++)
243 {
244 if(!IsUserChar(*p) && !IsKWildChar(*p))
245 return 0;
246 }
247
248 for(p = aconf->host; *p; p++)
249 {
250 if(!IsHostChar(*p) && !IsKWildChar(*p))
251 return 0;
252 }
253
254 return 1;
255}
256
257static int
258bandb_check_dline(struct ConfItem *aconf)
259{
260 struct rb_sockaddr_storage daddr;
83595e60
AC
261 int bits;
262
29c92cf9 263 if(!parse_netmask(aconf->host, &daddr, &bits))
83595e60
AC
264 return 0;
265
266 return 1;
267}
268
269static int
270bandb_check_xline(struct ConfItem *aconf)
271{
272 struct ConfItem *xconf;
273 /* XXX perhaps convert spaces to \s? -- jilles */
274
275 xconf = find_xline_mask(aconf->host);
276 if(xconf != NULL && !(xconf->flags & CONF_FLAGS_TEMPORARY))
277 return 0;
278
279 return 1;
280}
281
282static int
283bandb_check_resv_channel(struct ConfItem *aconf)
284{
285 const char *p;
286
287 if(hash_find_resv(aconf->host) || strlen(aconf->host) > CHANNELLEN)
288 return 0;
289
290 for(p = aconf->host; *p; p++)
291 {
292 if(!IsChanChar(*p))
293 return 0;
294 }
295
296 return 1;
297}
298
299static int
300bandb_check_resv_nick(struct ConfItem *aconf)
301{
302 if(!clean_resv_nick(aconf->host))
303 return 0;
304
305 if(find_nick_resv(aconf->host))
306 return 0;
307
308 return 1;
309}
310
311static void
312bandb_handle_clear(void)
313{
314 rb_dlink_node *ptr, *next_ptr;
315
316 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, bandb_pending.head)
317 {
318 free_conf(ptr->data);
319 rb_dlinkDestroy(ptr, &bandb_pending);
320 }
321}
322
323static void
324bandb_handle_finish(void)
325{
326 struct ConfItem *aconf;
327 rb_dlink_node *ptr, *next_ptr;
328
329 clear_out_address_conf_bans();
330 clear_s_newconf_bans();
331
332 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, bandb_pending.head)
333 {
334 aconf = ptr->data;
335
336 rb_dlinkDestroy(ptr, &bandb_pending);
337
338 switch (aconf->status)
339 {
340 case CONF_KILL:
341 if(bandb_check_kline(aconf))
342 add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf);
343 else
344 free_conf(aconf);
345
346 break;
347
348 case CONF_DLINE:
349 if(bandb_check_dline(aconf))
350 add_conf_by_address(aconf->host, CONF_DLINE, aconf->user, NULL, aconf);
351 else
352 free_conf(aconf);
353
354 break;
355
356 case CONF_XLINE:
357 if(bandb_check_xline(aconf))
358 rb_dlinkAddAlloc(aconf, &xline_conf_list);
359 else
360 free_conf(aconf);
361
362 break;
363
364 case CONF_RESV_CHANNEL:
365 if(bandb_check_resv_channel(aconf))
366 add_to_resv_hash(aconf->host, aconf);
367 else
368 free_conf(aconf);
369
370 break;
371
372 case CONF_RESV_NICK:
373 if(bandb_check_resv_nick(aconf))
374 rb_dlinkAddAlloc(aconf, &resv_conf_list);
375 else
376 free_conf(aconf);
377
378 break;
379 }
380 }
381
382 check_banned_lines();
383}
384
385static void
386bandb_handle_failure(rb_helper *helper, char **parv, int parc)
387{
388 if(server_state_foreground)
389 fprintf(stderr, "bandb - bandb failure: %s\n", parv[1]);
55abcbb2 390
83595e60
AC
391 ilog(L_MAIN, "bandb - bandb failure: %s", parv[1]);
392 sendto_realops_snomask(SNO_GENERAL, L_ALL, "bandb - bandb failure: %s", parv[1]);
393 exit(1);
394}
395
396static void
397bandb_parse(rb_helper *helper)
398{
399 static char buf[READBUF_SIZE];
400 char *parv[MAXPARA + 1];
401 int len, parc;
402
403 while((len = rb_helper_read(helper, buf, sizeof(buf))))
404 {
405 parc = rb_string_to_array(buf, parv, MAXPARA);
406
407 if(parc < 1)
408 continue;
409
410 switch (parv[0][0])
411 {
412 case '!':
413 bandb_handle_failure(helper, parv, parc);
414 break;
415 case 'K':
416 case 'D':
417 case 'X':
418 case 'R':
419 bandb_handle_ban(parv, parc);
420 break;
421
422 case 'C':
423 bandb_handle_clear();
624d7791 424 break;
83595e60
AC
425 case 'F':
426 bandb_handle_finish();
427 break;
428 }
429 }
430}
431
432void
433bandb_rehash_bans(void)
434{
435 if(bandb_helper != NULL)
436 rb_helper_write(bandb_helper, "L");
437}
438
439static void
440bandb_restart_cb(rb_helper *helper)
441{
442 ilog(L_MAIN, "bandb - bandb_restart_cb called, bandb helper died?");
443 sendto_realops_snomask(SNO_GENERAL, L_ALL,
444 "bandb - bandb_restart_cb called, bandb helper died?");
445 if(helper != NULL)
446 {
447 rb_helper_close(helper);
448 bandb_helper = NULL;
449 }
450 start_bandb();
451 return;
452}