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