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 rb_snprintf(fullpath
, sizeof(fullpath
), "%s/bandb%s", PKGLIBEXECDIR
, suffix
);
90 if(access(fullpath
, X_OK
) == -1)
92 rb_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 rb_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
, (struct sockaddr
*)&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
;
263 /* struct ConfItem *dconf; */
266 if(!parse_netmask(aconf
->host
, (struct sockaddr
*)&daddr
, &bits
))
273 bandb_check_xline(struct ConfItem
*aconf
)
275 struct ConfItem
*xconf
;
276 /* XXX perhaps convert spaces to \s? -- jilles */
278 xconf
= find_xline_mask(aconf
->host
);
279 if(xconf
!= NULL
&& !(xconf
->flags
& CONF_FLAGS_TEMPORARY
))
286 bandb_check_resv_channel(struct ConfItem
*aconf
)
290 if(hash_find_resv(aconf
->host
) || strlen(aconf
->host
) > CHANNELLEN
)
293 for(p
= aconf
->host
; *p
; p
++)
303 bandb_check_resv_nick(struct ConfItem
*aconf
)
305 if(!clean_resv_nick(aconf
->host
))
308 if(find_nick_resv(aconf
->host
))
315 bandb_handle_clear(void)
317 rb_dlink_node
*ptr
, *next_ptr
;
319 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, bandb_pending
.head
)
321 free_conf(ptr
->data
);
322 rb_dlinkDestroy(ptr
, &bandb_pending
);
327 bandb_handle_finish(void)
329 struct ConfItem
*aconf
;
330 rb_dlink_node
*ptr
, *next_ptr
;
332 clear_out_address_conf_bans();
333 clear_s_newconf_bans();
335 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, bandb_pending
.head
)
339 rb_dlinkDestroy(ptr
, &bandb_pending
);
341 switch (aconf
->status
)
344 if(bandb_check_kline(aconf
))
345 add_conf_by_address(aconf
->host
, CONF_KILL
, aconf
->user
, NULL
, aconf
);
352 if(bandb_check_dline(aconf
))
353 add_conf_by_address(aconf
->host
, CONF_DLINE
, aconf
->user
, NULL
, aconf
);
360 if(bandb_check_xline(aconf
))
361 rb_dlinkAddAlloc(aconf
, &xline_conf_list
);
367 case CONF_RESV_CHANNEL
:
368 if(bandb_check_resv_channel(aconf
))
369 add_to_resv_hash(aconf
->host
, aconf
);
376 if(bandb_check_resv_nick(aconf
))
377 rb_dlinkAddAlloc(aconf
, &resv_conf_list
);
385 check_banned_lines();
389 bandb_handle_failure(rb_helper
*helper
, char **parv
, int parc
)
391 if(server_state_foreground
)
392 fprintf(stderr
, "bandb - bandb failure: %s\n", parv
[1]);
394 ilog(L_MAIN
, "bandb - bandb failure: %s", parv
[1]);
395 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "bandb - bandb failure: %s", parv
[1]);
400 bandb_parse(rb_helper
*helper
)
402 static char buf
[READBUF_SIZE
];
403 char *parv
[MAXPARA
+ 1];
406 while((len
= rb_helper_read(helper
, buf
, sizeof(buf
))))
408 parc
= rb_string_to_array(buf
, parv
, MAXPARA
);
416 bandb_handle_failure(helper
, parv
, parc
);
422 bandb_handle_ban(parv
, parc
);
426 bandb_handle_clear();
429 bandb_handle_finish();
436 bandb_rehash_bans(void)
438 if(bandb_helper
!= NULL
)
439 rb_helper_write(bandb_helper
, "L");
443 bandb_restart_cb(rb_helper
*helper
)
445 ilog(L_MAIN
, "bandb - bandb_restart_cb called, bandb helper died?");
446 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
447 "bandb - bandb_restart_cb called, bandb helper died?");
450 rb_helper_close(helper
);