]> jfr.im git - solanum.git/blame - ircd/bandbi.c
ircd/authproc.c: avoid crash on lack of any configured DNSBLs
[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 48
2ce25d94
AJ
49static void
50bandb_handle_failure(rb_helper *helper, char **parv, int parc) __attribute__((noreturn));
51
83595e60
AC
52static char bandb_add_letter[LAST_BANDB_TYPE] = {
53 'K', 'D', 'X', 'R'
54};
55
56rb_dlink_list bandb_pending;
57
58static rb_helper *bandb_helper;
59static int start_bandb(void);
60
61static void bandb_parse(rb_helper *);
62static void bandb_restart_cb(rb_helper *);
63static char *bandb_path;
64
65void
66init_bandb(void)
67{
68 if(start_bandb())
69 {
70 ilog(L_MAIN, "Unable to start bandb helper: %s", strerror(errno));
71 exit(0);
72 }
73}
74
75
76static int
77start_bandb(void)
78{
79 char fullpath[PATH_MAX + 1];
83595e60 80
4d8cfacd 81 rb_setenv("BANDB_DBPATH", ircd_paths[IRCD_PATH_BANDB], 1);
83595e60
AC
82 if(bandb_path == NULL)
83 {
8f0c3422 84 snprintf(fullpath, sizeof(fullpath), "%s/bandb", ircd_paths[IRCD_PATH_LIBEXEC]);
83595e60
AC
85
86 if(access(fullpath, X_OK) == -1)
87 {
8f0c3422 88 snprintf(fullpath, sizeof(fullpath), "%s/bin/bandb", ConfigFileEntry.dpath);
83595e60
AC
89
90 if(access(fullpath, X_OK) == -1)
91 {
92 ilog(L_MAIN,
8f0c3422 93 "Unable to execute bandb in %s or %s/bin",
94 ircd_paths[IRCD_PATH_LIBEXEC], ConfigFileEntry.dpath);
83595e60
AC
95 return 0;
96 }
97 }
98 bandb_path = rb_strdup(fullpath);
99 }
100
101
102 bandb_helper = rb_helper_start("bandb", bandb_path, bandb_parse, bandb_restart_cb);
103
104 if(bandb_helper == NULL)
105 {
106 ilog(L_MAIN, "Unable to start bandb: %s", strerror(errno));
f085388a 107 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Unable to start bandb helper: %s",
83595e60
AC
108 strerror(errno));
109 return 1;
110 }
111
f085388a
U
112 ilog(L_MAIN, "bandb helper started");
113 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "bandb helper started");
83595e60
AC
114 rb_helper_run(bandb_helper);
115 return 0;
116}
117
118void
119bandb_add(bandb_type type, struct Client *source_p, const char *mask1,
120 const char *mask2, const char *reason, const char *oper_reason, int perm)
121{
c8729b08
KB
122 if(bandb_helper == NULL)
123 return;
124
83595e60
AC
125 static char buf[BUFSIZE];
126
5203cba5 127 snprintf(buf, sizeof(buf), "%c %s ", bandb_add_letter[type], mask1);
83595e60
AC
128
129 if(!EmptyString(mask2))
130 rb_snprintf_append(buf, sizeof(buf), "%s ", mask2);
131
132 rb_snprintf_append(buf, sizeof(buf), "%s %ld %d :%s",
133 get_oper_name(source_p), (long int)rb_current_time(), perm, reason);
134
135 if(!EmptyString(oper_reason))
136 rb_snprintf_append(buf, sizeof(buf), "|%s", oper_reason);
137
138 rb_helper_write(bandb_helper, "%s", buf);
139}
140
141static char bandb_del_letter[LAST_BANDB_TYPE] = {
142 'k', 'd', 'x', 'r'
143};
144
145void
146bandb_del(bandb_type type, const char *mask1, const char *mask2)
147{
c8729b08
KB
148 if(bandb_helper == NULL)
149 return;
150
83595e60
AC
151 static char buf[BUFSIZE];
152
153 buf[0] = '\0';
154
155 rb_snprintf_append(buf, sizeof(buf), "%c %s", bandb_del_letter[type], mask1);
156
157 if(!EmptyString(mask2))
158 rb_snprintf_append(buf, sizeof(buf), " %s", mask2);
159
160 rb_helper_write(bandb_helper, "%s", buf);
161}
162
163static void
164bandb_handle_ban(char *parv[], int parc)
165{
166 struct ConfItem *aconf;
167 char *p;
168 int para = 1;
169
170 aconf = make_conf();
171 aconf->port = 0;
172
173 if(parv[0][0] == 'K')
174 aconf->user = rb_strdup(parv[para++]);
175
176 aconf->host = rb_strdup(parv[para++]);
27f616dd 177 aconf->info.oper = operhash_add(parv[para++]);
83595e60
AC
178
179 switch (parv[0][0])
180 {
181 case 'K':
182 aconf->status = CONF_KILL;
183 break;
184
185 case 'D':
186 aconf->status = CONF_DLINE;
187 break;
188
189 case 'X':
190 aconf->status = CONF_XLINE;
191 break;
192
193 case 'R':
194 if(IsChannelName(aconf->host))
195 aconf->status = CONF_RESV_CHANNEL;
196 else
197 aconf->status = CONF_RESV_NICK;
198
199 break;
200 }
201
202 if((p = strchr(parv[para], '|')))
203 {
204 *p++ = '\0';
205 aconf->spasswd = rb_strdup(p);
206 }
207
208 aconf->passwd = rb_strdup(parv[para]);
209
210 rb_dlinkAddAlloc(aconf, &bandb_pending);
211}
212
213static int
214bandb_check_kline(struct ConfItem *aconf)
215{
216 struct rb_sockaddr_storage daddr;
217 struct ConfItem *kconf = NULL;
218 int aftype;
219 const char *p;
220
29c92cf9 221 aftype = parse_netmask(aconf->host, &daddr, NULL);
83595e60
AC
222
223 if(aftype != HM_HOST)
224 {
83595e60
AC
225 if(aftype == HM_IPV6)
226 aftype = AF_INET6;
227 else
83595e60
AC
228 aftype = AF_INET;
229
230 kconf = find_conf_by_address(aconf->host, NULL, NULL, (struct sockaddr *)&daddr,
231 CONF_KILL, aftype, aconf->user, NULL);
232 }
233 else
234 kconf = find_conf_by_address(aconf->host, NULL, NULL, NULL, CONF_KILL, 0, aconf->user, NULL);
235
236 if(kconf && ((kconf->flags & CONF_FLAGS_TEMPORARY) == 0))
237 return 0;
238
239 for(p = aconf->user; *p; p++)
240 {
241 if(!IsUserChar(*p) && !IsKWildChar(*p))
242 return 0;
243 }
244
245 for(p = aconf->host; *p; p++)
246 {
247 if(!IsHostChar(*p) && !IsKWildChar(*p))
248 return 0;
249 }
250
251 return 1;
252}
253
254static int
255bandb_check_dline(struct ConfItem *aconf)
256{
257 struct rb_sockaddr_storage daddr;
83595e60
AC
258 int bits;
259
29c92cf9 260 if(!parse_netmask(aconf->host, &daddr, &bits))
83595e60
AC
261 return 0;
262
263 return 1;
264}
265
266static int
267bandb_check_xline(struct ConfItem *aconf)
268{
269 struct ConfItem *xconf;
270 /* XXX perhaps convert spaces to \s? -- jilles */
271
272 xconf = find_xline_mask(aconf->host);
273 if(xconf != NULL && !(xconf->flags & CONF_FLAGS_TEMPORARY))
274 return 0;
275
276 return 1;
277}
278
279static int
280bandb_check_resv_channel(struct ConfItem *aconf)
281{
282 const char *p;
283
284 if(hash_find_resv(aconf->host) || strlen(aconf->host) > CHANNELLEN)
285 return 0;
286
287 for(p = aconf->host; *p; p++)
288 {
289 if(!IsChanChar(*p))
290 return 0;
291 }
292
293 return 1;
294}
295
296static int
297bandb_check_resv_nick(struct ConfItem *aconf)
298{
299 if(!clean_resv_nick(aconf->host))
300 return 0;
301
302 if(find_nick_resv(aconf->host))
303 return 0;
304
305 return 1;
306}
307
308static void
309bandb_handle_clear(void)
310{
311 rb_dlink_node *ptr, *next_ptr;
312
313 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, bandb_pending.head)
314 {
315 free_conf(ptr->data);
316 rb_dlinkDestroy(ptr, &bandb_pending);
317 }
318}
319
320static void
321bandb_handle_finish(void)
322{
323 struct ConfItem *aconf;
324 rb_dlink_node *ptr, *next_ptr;
325
625cbb19 326 clear_out_address_conf(AC_BANDB);
83595e60
AC
327 clear_s_newconf_bans();
328
329 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, bandb_pending.head)
330 {
331 aconf = ptr->data;
332
333 rb_dlinkDestroy(ptr, &bandb_pending);
334
335 switch (aconf->status)
336 {
337 case CONF_KILL:
338 if(bandb_check_kline(aconf))
339 add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf);
340 else
341 free_conf(aconf);
342
343 break;
344
345 case CONF_DLINE:
346 if(bandb_check_dline(aconf))
347 add_conf_by_address(aconf->host, CONF_DLINE, aconf->user, NULL, aconf);
348 else
349 free_conf(aconf);
350
351 break;
352
353 case CONF_XLINE:
354 if(bandb_check_xline(aconf))
355 rb_dlinkAddAlloc(aconf, &xline_conf_list);
356 else
357 free_conf(aconf);
358
359 break;
360
361 case CONF_RESV_CHANNEL:
362 if(bandb_check_resv_channel(aconf))
363 add_to_resv_hash(aconf->host, aconf);
364 else
365 free_conf(aconf);
366
367 break;
368
369 case CONF_RESV_NICK:
370 if(bandb_check_resv_nick(aconf))
371 rb_dlinkAddAlloc(aconf, &resv_conf_list);
372 else
373 free_conf(aconf);
374
375 break;
376 }
377 }
378
379 check_banned_lines();
380}
381
382static void
383bandb_handle_failure(rb_helper *helper, char **parv, int parc)
384{
385 if(server_state_foreground)
386 fprintf(stderr, "bandb - bandb failure: %s\n", parv[1]);
55abcbb2 387
83595e60 388 ilog(L_MAIN, "bandb - bandb failure: %s", parv[1]);
a9227555 389 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "bandb - bandb failure: %s", parv[1]);
83595e60
AC
390 exit(1);
391}
392
393static void
394bandb_parse(rb_helper *helper)
395{
396 static char buf[READBUF_SIZE];
33ded5fc 397 char *parv[MAXPARA];
83595e60
AC
398 int len, parc;
399
400 while((len = rb_helper_read(helper, buf, sizeof(buf))))
401 {
33ded5fc 402 parc = rb_string_to_array(buf, parv, sizeof(parv));
83595e60
AC
403
404 if(parc < 1)
405 continue;
406
407 switch (parv[0][0])
408 {
409 case '!':
410 bandb_handle_failure(helper, parv, parc);
411 break;
412 case 'K':
413 case 'D':
414 case 'X':
415 case 'R':
416 bandb_handle_ban(parv, parc);
417 break;
418
419 case 'C':
420 bandb_handle_clear();
624d7791 421 break;
83595e60
AC
422 case 'F':
423 bandb_handle_finish();
424 break;
425 }
426 }
427}
428
429void
430bandb_rehash_bans(void)
431{
432 if(bandb_helper != NULL)
433 rb_helper_write(bandb_helper, "L");
434}
435
436static void
437bandb_restart_cb(rb_helper *helper)
438{
f085388a 439 ilog(L_MAIN, "bandb helper died - attempting to restart");
a9227555 440 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
f085388a 441 "bandb helper died - attempting to restart");
83595e60
AC
442 if(helper != NULL)
443 {
444 rb_helper_close(helper);
445 bandb_helper = NULL;
446 }
447 start_bandb();
448 return;
449}