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.
42 #include "s_newconf.h"
46 #include "msg.h" /* XXX: MAXPARA */
50 bandb_handle_failure(rb_helper
*helper
, char **parv
, int parc
) __attribute__((noreturn
));
52 static char bandb_add_letter
[LAST_BANDB_TYPE
] = {
56 rb_dlink_list bandb_pending
;
58 static rb_helper
*bandb_helper
;
59 static int start_bandb(void);
61 static void bandb_parse(rb_helper
*);
62 static void bandb_restart_cb(rb_helper
*);
63 static char *bandb_path
;
70 ilog(L_MAIN
, "Unable to start bandb helper: %s", strerror(errno
));
79 char fullpath
[PATH_MAX
+ 1];
81 const char *suffix
= ".exe";
83 const char *suffix
= "";
86 rb_setenv("BANDB_DBPATH", ircd_paths
[IRCD_PATH_BANDB
], 1);
87 if(bandb_path
== NULL
)
89 snprintf(fullpath
, sizeof(fullpath
), "%s%cbandb%s", ircd_paths
[IRCD_PATH_LIBEXEC
], RB_PATH_SEPARATOR
, suffix
);
91 if(access(fullpath
, X_OK
) == -1)
93 snprintf(fullpath
, sizeof(fullpath
), "%s%cbin%cbandb%s",
94 ConfigFileEntry
.dpath
, RB_PATH_SEPARATOR
, RB_PATH_SEPARATOR
, suffix
);
96 if(access(fullpath
, X_OK
) == -1)
99 "Unable to execute bandb%s in %s or %s/bin",
100 suffix
, ircd_paths
[IRCD_PATH_LIBEXEC
], ConfigFileEntry
.dpath
);
104 bandb_path
= rb_strdup(fullpath
);
108 bandb_helper
= rb_helper_start("bandb", bandb_path
, bandb_parse
, bandb_restart_cb
);
110 if(bandb_helper
== NULL
)
112 ilog(L_MAIN
, "Unable to start bandb: %s", strerror(errno
));
113 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "Unable to start bandb: %s",
118 rb_helper_run(bandb_helper
);
123 bandb_add(bandb_type type
, struct Client
*source_p
, const char *mask1
,
124 const char *mask2
, const char *reason
, const char *oper_reason
, int perm
)
126 if(bandb_helper
== NULL
)
129 static char buf
[BUFSIZE
];
131 snprintf(buf
, sizeof(buf
), "%c %s ", bandb_add_letter
[type
], mask1
);
133 if(!EmptyString(mask2
))
134 rb_snprintf_append(buf
, sizeof(buf
), "%s ", mask2
);
136 rb_snprintf_append(buf
, sizeof(buf
), "%s %ld %d :%s",
137 get_oper_name(source_p
), (long int)rb_current_time(), perm
, reason
);
139 if(!EmptyString(oper_reason
))
140 rb_snprintf_append(buf
, sizeof(buf
), "|%s", oper_reason
);
142 rb_helper_write(bandb_helper
, "%s", buf
);
145 static char bandb_del_letter
[LAST_BANDB_TYPE
] = {
150 bandb_del(bandb_type type
, const char *mask1
, const char *mask2
)
152 if(bandb_helper
== NULL
)
155 static char buf
[BUFSIZE
];
159 rb_snprintf_append(buf
, sizeof(buf
), "%c %s", bandb_del_letter
[type
], mask1
);
161 if(!EmptyString(mask2
))
162 rb_snprintf_append(buf
, sizeof(buf
), " %s", mask2
);
164 rb_helper_write(bandb_helper
, "%s", buf
);
168 bandb_handle_ban(char *parv
[], int parc
)
170 struct ConfItem
*aconf
;
177 if(parv
[0][0] == 'K')
178 aconf
->user
= rb_strdup(parv
[para
++]);
180 aconf
->host
= rb_strdup(parv
[para
++]);
181 aconf
->info
.oper
= operhash_add(parv
[para
++]);
186 aconf
->status
= CONF_KILL
;
190 aconf
->status
= CONF_DLINE
;
194 aconf
->status
= CONF_XLINE
;
198 if(IsChannelName(aconf
->host
))
199 aconf
->status
= CONF_RESV_CHANNEL
;
201 aconf
->status
= CONF_RESV_NICK
;
206 if((p
= strchr(parv
[para
], '|')))
209 aconf
->spasswd
= rb_strdup(p
);
212 aconf
->passwd
= rb_strdup(parv
[para
]);
214 rb_dlinkAddAlloc(aconf
, &bandb_pending
);
218 bandb_check_kline(struct ConfItem
*aconf
)
220 struct rb_sockaddr_storage daddr
;
221 struct ConfItem
*kconf
= NULL
;
225 aftype
= parse_netmask(aconf
->host
, &daddr
, NULL
);
227 if(aftype
!= HM_HOST
)
229 if(aftype
== HM_IPV6
)
234 kconf
= find_conf_by_address(aconf
->host
, NULL
, NULL
, (struct sockaddr
*)&daddr
,
235 CONF_KILL
, aftype
, aconf
->user
, NULL
);
238 kconf
= find_conf_by_address(aconf
->host
, NULL
, NULL
, NULL
, CONF_KILL
, 0, aconf
->user
, NULL
);
240 if(kconf
&& ((kconf
->flags
& CONF_FLAGS_TEMPORARY
) == 0))
243 for(p
= aconf
->user
; *p
; p
++)
245 if(!IsUserChar(*p
) && !IsKWildChar(*p
))
249 for(p
= aconf
->host
; *p
; p
++)
251 if(!IsHostChar(*p
) && !IsKWildChar(*p
))
259 bandb_check_dline(struct ConfItem
*aconf
)
261 struct rb_sockaddr_storage daddr
;
264 if(!parse_netmask(aconf
->host
, &daddr
, &bits
))
271 bandb_check_xline(struct ConfItem
*aconf
)
273 struct ConfItem
*xconf
;
274 /* XXX perhaps convert spaces to \s? -- jilles */
276 xconf
= find_xline_mask(aconf
->host
);
277 if(xconf
!= NULL
&& !(xconf
->flags
& CONF_FLAGS_TEMPORARY
))
284 bandb_check_resv_channel(struct ConfItem
*aconf
)
288 if(hash_find_resv(aconf
->host
) || strlen(aconf
->host
) > CHANNELLEN
)
291 for(p
= aconf
->host
; *p
; p
++)
301 bandb_check_resv_nick(struct ConfItem
*aconf
)
303 if(!clean_resv_nick(aconf
->host
))
306 if(find_nick_resv(aconf
->host
))
313 bandb_handle_clear(void)
315 rb_dlink_node
*ptr
, *next_ptr
;
317 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, bandb_pending
.head
)
319 free_conf(ptr
->data
);
320 rb_dlinkDestroy(ptr
, &bandb_pending
);
325 bandb_handle_finish(void)
327 struct ConfItem
*aconf
;
328 rb_dlink_node
*ptr
, *next_ptr
;
330 clear_out_address_conf_bans();
331 clear_s_newconf_bans();
333 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, bandb_pending
.head
)
337 rb_dlinkDestroy(ptr
, &bandb_pending
);
339 switch (aconf
->status
)
342 if(bandb_check_kline(aconf
))
343 add_conf_by_address(aconf
->host
, CONF_KILL
, aconf
->user
, NULL
, aconf
);
350 if(bandb_check_dline(aconf
))
351 add_conf_by_address(aconf
->host
, CONF_DLINE
, aconf
->user
, NULL
, aconf
);
358 if(bandb_check_xline(aconf
))
359 rb_dlinkAddAlloc(aconf
, &xline_conf_list
);
365 case CONF_RESV_CHANNEL
:
366 if(bandb_check_resv_channel(aconf
))
367 add_to_resv_hash(aconf
->host
, aconf
);
374 if(bandb_check_resv_nick(aconf
))
375 rb_dlinkAddAlloc(aconf
, &resv_conf_list
);
383 check_banned_lines();
387 bandb_handle_failure(rb_helper
*helper
, char **parv
, int parc
)
389 if(server_state_foreground
)
390 fprintf(stderr
, "bandb - bandb failure: %s\n", parv
[1]);
392 ilog(L_MAIN
, "bandb - bandb failure: %s", parv
[1]);
393 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "bandb - bandb failure: %s", parv
[1]);
398 bandb_parse(rb_helper
*helper
)
400 static char buf
[READBUF_SIZE
];
404 while((len
= rb_helper_read(helper
, buf
, sizeof(buf
))))
406 parc
= rb_string_to_array(buf
, parv
, sizeof(parv
));
414 bandb_handle_failure(helper
, parv
, parc
);
420 bandb_handle_ban(parv
, parc
);
424 bandb_handle_clear();
427 bandb_handle_finish();
434 bandb_rehash_bans(void)
436 if(bandb_helper
!= NULL
)
437 rb_helper_write(bandb_helper
, "L");
441 bandb_restart_cb(rb_helper
*helper
)
443 ilog(L_MAIN
, "bandb - bandb_restart_cb called, bandb helper died?");
444 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
445 "bandb - bandb_restart_cb called, bandb helper died?");
448 rb_helper_close(helper
);