2 * An interface to the ban db.
4 * Copyright (C) 2006 Lee Hardy <lee -at- leeh.co.uk>
5 * Copyright (C) 2006 ircd-ratbox development team
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
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.
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.
34 #include "ratbox_lib.h"
44 #include "s_newconf.h"
48 #include "msg.h" /* XXX: MAXPARA */
51 static char bandb_add_letter
[LAST_BANDB_TYPE
] = {
55 rb_dlink_list bandb_pending
;
57 static rb_helper
*bandb_helper
;
58 static int start_bandb(void);
60 static void bandb_parse(rb_helper
*);
61 static void bandb_restart_cb(rb_helper
*);
62 static char *bandb_path
;
69 ilog(L_MAIN
, "Unable to start bandb helper: %s", strerror(errno
));
78 char fullpath
[PATH_MAX
+ 1];
80 const char *suffix
= ".exe";
82 const char *suffix
= "";
85 rb_setenv("BANDB_DBPATH", PKGLOCALSTATEDIR
"/ban.db", 1);
86 if(bandb_path
== NULL
)
88 snprintf(fullpath
, sizeof(fullpath
), "%s/bandb%s", PKGLIBEXECDIR
, suffix
);
90 if(access(fullpath
, X_OK
) == -1)
92 snprintf(fullpath
, sizeof(fullpath
), "%s/bin/bandb%s",
93 ConfigFileEntry
.dpath
, suffix
);
95 if(access(fullpath
, X_OK
) == -1)
98 "Unable to execute bandb%s in %s or %s/bin",
99 suffix
, PKGLIBEXECDIR
, ConfigFileEntry
.dpath
);
103 bandb_path
= rb_strdup(fullpath
);
107 bandb_helper
= rb_helper_start("bandb", bandb_path
, bandb_parse
, bandb_restart_cb
);
109 if(bandb_helper
== NULL
)
111 ilog(L_MAIN
, "Unable to start bandb: %s", strerror(errno
));
112 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "Unable to start bandb: %s",
117 rb_helper_run(bandb_helper
);
122 bandb_add(bandb_type type
, struct Client
*source_p
, const char *mask1
,
123 const char *mask2
, const char *reason
, const char *oper_reason
, int perm
)
125 if(bandb_helper
== NULL
)
128 static char buf
[BUFSIZE
];
130 snprintf(buf
, sizeof(buf
), "%c %s ", bandb_add_letter
[type
], mask1
);
132 if(!EmptyString(mask2
))
133 rb_snprintf_append(buf
, sizeof(buf
), "%s ", mask2
);
135 rb_snprintf_append(buf
, sizeof(buf
), "%s %ld %d :%s",
136 get_oper_name(source_p
), (long int)rb_current_time(), perm
, reason
);
138 if(!EmptyString(oper_reason
))
139 rb_snprintf_append(buf
, sizeof(buf
), "|%s", oper_reason
);
141 rb_helper_write(bandb_helper
, "%s", buf
);
144 static char bandb_del_letter
[LAST_BANDB_TYPE
] = {
149 bandb_del(bandb_type type
, const char *mask1
, const char *mask2
)
151 if(bandb_helper
== NULL
)
154 static char buf
[BUFSIZE
];
158 rb_snprintf_append(buf
, sizeof(buf
), "%c %s", bandb_del_letter
[type
], mask1
);
160 if(!EmptyString(mask2
))
161 rb_snprintf_append(buf
, sizeof(buf
), " %s", mask2
);
163 rb_helper_write(bandb_helper
, "%s", buf
);
167 bandb_handle_ban(char *parv
[], int parc
)
169 struct ConfItem
*aconf
;
176 if(parv
[0][0] == 'K')
177 aconf
->user
= rb_strdup(parv
[para
++]);
179 aconf
->host
= rb_strdup(parv
[para
++]);
180 aconf
->info
.oper
= operhash_add(parv
[para
++]);
185 aconf
->status
= CONF_KILL
;
189 aconf
->status
= CONF_DLINE
;
193 aconf
->status
= CONF_XLINE
;
197 if(IsChannelName(aconf
->host
))
198 aconf
->status
= CONF_RESV_CHANNEL
;
200 aconf
->status
= CONF_RESV_NICK
;
205 if((p
= strchr(parv
[para
], '|')))
208 aconf
->spasswd
= rb_strdup(p
);
211 aconf
->passwd
= rb_strdup(parv
[para
]);
213 rb_dlinkAddAlloc(aconf
, &bandb_pending
);
217 bandb_check_kline(struct ConfItem
*aconf
)
219 struct rb_sockaddr_storage daddr
;
220 struct ConfItem
*kconf
= NULL
;
224 aftype
= parse_netmask(aconf
->host
, &daddr
, NULL
);
226 if(aftype
!= HM_HOST
)
229 if(aftype
== HM_IPV6
)
235 kconf
= find_conf_by_address(aconf
->host
, NULL
, NULL
, (struct sockaddr
*)&daddr
,
236 CONF_KILL
, aftype
, aconf
->user
, NULL
);
239 kconf
= find_conf_by_address(aconf
->host
, NULL
, NULL
, NULL
, CONF_KILL
, 0, aconf
->user
, NULL
);
241 if(kconf
&& ((kconf
->flags
& CONF_FLAGS_TEMPORARY
) == 0))
244 for(p
= aconf
->user
; *p
; p
++)
246 if(!IsUserChar(*p
) && !IsKWildChar(*p
))
250 for(p
= aconf
->host
; *p
; p
++)
252 if(!IsHostChar(*p
) && !IsKWildChar(*p
))
260 bandb_check_dline(struct ConfItem
*aconf
)
262 struct rb_sockaddr_storage daddr
;
265 if(!parse_netmask(aconf
->host
, &daddr
, &bits
))
272 bandb_check_xline(struct ConfItem
*aconf
)
274 struct ConfItem
*xconf
;
275 /* XXX perhaps convert spaces to \s? -- jilles */
277 xconf
= find_xline_mask(aconf
->host
);
278 if(xconf
!= NULL
&& !(xconf
->flags
& CONF_FLAGS_TEMPORARY
))
285 bandb_check_resv_channel(struct ConfItem
*aconf
)
289 if(hash_find_resv(aconf
->host
) || strlen(aconf
->host
) > CHANNELLEN
)
292 for(p
= aconf
->host
; *p
; p
++)
302 bandb_check_resv_nick(struct ConfItem
*aconf
)
304 if(!clean_resv_nick(aconf
->host
))
307 if(find_nick_resv(aconf
->host
))
314 bandb_handle_clear(void)
316 rb_dlink_node
*ptr
, *next_ptr
;
318 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, bandb_pending
.head
)
320 free_conf(ptr
->data
);
321 rb_dlinkDestroy(ptr
, &bandb_pending
);
326 bandb_handle_finish(void)
328 struct ConfItem
*aconf
;
329 rb_dlink_node
*ptr
, *next_ptr
;
331 clear_out_address_conf_bans();
332 clear_s_newconf_bans();
334 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, bandb_pending
.head
)
338 rb_dlinkDestroy(ptr
, &bandb_pending
);
340 switch (aconf
->status
)
343 if(bandb_check_kline(aconf
))
344 add_conf_by_address(aconf
->host
, CONF_KILL
, aconf
->user
, NULL
, aconf
);
351 if(bandb_check_dline(aconf
))
352 add_conf_by_address(aconf
->host
, CONF_DLINE
, aconf
->user
, NULL
, aconf
);
359 if(bandb_check_xline(aconf
))
360 rb_dlinkAddAlloc(aconf
, &xline_conf_list
);
366 case CONF_RESV_CHANNEL
:
367 if(bandb_check_resv_channel(aconf
))
368 add_to_resv_hash(aconf
->host
, aconf
);
375 if(bandb_check_resv_nick(aconf
))
376 rb_dlinkAddAlloc(aconf
, &resv_conf_list
);
384 check_banned_lines();
388 bandb_handle_failure(rb_helper
*helper
, char **parv
, int parc
)
390 if(server_state_foreground
)
391 fprintf(stderr
, "bandb - bandb failure: %s\n", parv
[1]);
393 ilog(L_MAIN
, "bandb - bandb failure: %s", parv
[1]);
394 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "bandb - bandb failure: %s", parv
[1]);
399 bandb_parse(rb_helper
*helper
)
401 static char buf
[READBUF_SIZE
];
402 char *parv
[MAXPARA
+ 1];
405 while((len
= rb_helper_read(helper
, buf
, sizeof(buf
))))
407 parc
= rb_string_to_array(buf
, parv
, MAXPARA
);
415 bandb_handle_failure(helper
, parv
, parc
);
421 bandb_handle_ban(parv
, parc
);
425 bandb_handle_clear();
428 bandb_handle_finish();
435 bandb_rehash_bans(void)
437 if(bandb_helper
!= NULL
)
438 rb_helper_write(bandb_helper
, "L");
442 bandb_restart_cb(rb_helper
*helper
)
444 ilog(L_MAIN
, "bandb - bandb_restart_cb called, bandb helper died?");
445 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
446 "bandb - bandb_restart_cb called, bandb helper died?");
449 rb_helper_close(helper
);