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 rb_setenv("BANDB_DBPATH", ircd_paths
[IRCD_PATH_BANDB
], 1);
82 if(bandb_path
== NULL
)
84 snprintf(fullpath
, sizeof(fullpath
), "%s/bandb", ircd_paths
[IRCD_PATH_LIBEXEC
]);
86 if(access(fullpath
, X_OK
) == -1)
88 snprintf(fullpath
, sizeof(fullpath
), "%s/bin/bandb", ConfigFileEntry
.dpath
);
90 if(access(fullpath
, X_OK
) == -1)
93 "Unable to execute bandb in %s or %s/bin",
94 ircd_paths
[IRCD_PATH_LIBEXEC
], ConfigFileEntry
.dpath
);
98 bandb_path
= rb_strdup(fullpath
);
102 bandb_helper
= rb_helper_start("bandb", bandb_path
, bandb_parse
, bandb_restart_cb
);
104 if(bandb_helper
== NULL
)
106 ilog(L_MAIN
, "Unable to start bandb: %s", strerror(errno
));
107 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
, "Unable to start bandb: %s",
112 rb_helper_run(bandb_helper
);
117 bandb_add(bandb_type type
, struct Client
*source_p
, const char *mask1
,
118 const char *mask2
, const char *reason
, const char *oper_reason
, int perm
)
120 if(bandb_helper
== NULL
)
123 static char buf
[BUFSIZE
];
125 snprintf(buf
, sizeof(buf
), "%c %s ", bandb_add_letter
[type
], mask1
);
127 if(!EmptyString(mask2
))
128 rb_snprintf_append(buf
, sizeof(buf
), "%s ", mask2
);
130 rb_snprintf_append(buf
, sizeof(buf
), "%s %ld %d :%s",
131 get_oper_name(source_p
), (long int)rb_current_time(), perm
, reason
);
133 if(!EmptyString(oper_reason
))
134 rb_snprintf_append(buf
, sizeof(buf
), "|%s", oper_reason
);
136 rb_helper_write(bandb_helper
, "%s", buf
);
139 static char bandb_del_letter
[LAST_BANDB_TYPE
] = {
144 bandb_del(bandb_type type
, const char *mask1
, const char *mask2
)
146 if(bandb_helper
== NULL
)
149 static char buf
[BUFSIZE
];
153 rb_snprintf_append(buf
, sizeof(buf
), "%c %s", bandb_del_letter
[type
], mask1
);
155 if(!EmptyString(mask2
))
156 rb_snprintf_append(buf
, sizeof(buf
), " %s", mask2
);
158 rb_helper_write(bandb_helper
, "%s", buf
);
162 bandb_handle_ban(char *parv
[], int parc
)
164 struct ConfItem
*aconf
;
171 if(parv
[0][0] == 'K')
172 aconf
->user
= rb_strdup(parv
[para
++]);
174 aconf
->host
= rb_strdup(parv
[para
++]);
175 aconf
->info
.oper
= operhash_add(parv
[para
++]);
180 aconf
->status
= CONF_KILL
;
184 aconf
->status
= CONF_DLINE
;
188 aconf
->status
= CONF_XLINE
;
192 if(IsChannelName(aconf
->host
))
193 aconf
->status
= CONF_RESV_CHANNEL
;
195 aconf
->status
= CONF_RESV_NICK
;
200 if((p
= strchr(parv
[para
], '|')))
203 aconf
->spasswd
= rb_strdup(p
);
206 aconf
->passwd
= rb_strdup(parv
[para
]);
208 rb_dlinkAddAlloc(aconf
, &bandb_pending
);
212 bandb_check_kline(struct ConfItem
*aconf
)
214 struct rb_sockaddr_storage daddr
;
215 struct ConfItem
*kconf
= NULL
;
219 aftype
= parse_netmask(aconf
->host
, &daddr
, NULL
);
221 if(aftype
!= HM_HOST
)
223 if(aftype
== HM_IPV6
)
228 kconf
= find_conf_by_address(aconf
->host
, NULL
, NULL
, (struct sockaddr
*)&daddr
,
229 CONF_KILL
, aftype
, aconf
->user
, NULL
);
232 kconf
= find_conf_by_address(aconf
->host
, NULL
, NULL
, NULL
, CONF_KILL
, 0, aconf
->user
, NULL
);
234 if(kconf
&& ((kconf
->flags
& CONF_FLAGS_TEMPORARY
) == 0))
237 for(p
= aconf
->user
; *p
; p
++)
239 if(!IsUserChar(*p
) && !IsKWildChar(*p
))
243 for(p
= aconf
->host
; *p
; p
++)
245 if(!IsHostChar(*p
) && !IsKWildChar(*p
))
253 bandb_check_dline(struct ConfItem
*aconf
)
255 struct rb_sockaddr_storage daddr
;
258 if(!parse_netmask(aconf
->host
, &daddr
, &bits
))
265 bandb_check_xline(struct ConfItem
*aconf
)
267 struct ConfItem
*xconf
;
268 /* XXX perhaps convert spaces to \s? -- jilles */
270 xconf
= find_xline_mask(aconf
->host
);
271 if(xconf
!= NULL
&& !(xconf
->flags
& CONF_FLAGS_TEMPORARY
))
278 bandb_check_resv_channel(struct ConfItem
*aconf
)
282 if(hash_find_resv(aconf
->host
) || strlen(aconf
->host
) > CHANNELLEN
)
285 for(p
= aconf
->host
; *p
; p
++)
295 bandb_check_resv_nick(struct ConfItem
*aconf
)
297 if(!clean_resv_nick(aconf
->host
))
300 if(find_nick_resv(aconf
->host
))
307 bandb_handle_clear(void)
309 rb_dlink_node
*ptr
, *next_ptr
;
311 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, bandb_pending
.head
)
313 free_conf(ptr
->data
);
314 rb_dlinkDestroy(ptr
, &bandb_pending
);
319 bandb_handle_finish(void)
321 struct ConfItem
*aconf
;
322 rb_dlink_node
*ptr
, *next_ptr
;
324 clear_out_address_conf(AC_BANDB
);
325 clear_s_newconf_bans();
327 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, bandb_pending
.head
)
331 rb_dlinkDestroy(ptr
, &bandb_pending
);
333 switch (aconf
->status
)
336 if(bandb_check_kline(aconf
))
337 add_conf_by_address(aconf
->host
, CONF_KILL
, aconf
->user
, NULL
, aconf
);
344 if(bandb_check_dline(aconf
))
345 add_conf_by_address(aconf
->host
, CONF_DLINE
, aconf
->user
, NULL
, aconf
);
352 if(bandb_check_xline(aconf
))
353 rb_dlinkAddAlloc(aconf
, &xline_conf_list
);
359 case CONF_RESV_CHANNEL
:
360 if(bandb_check_resv_channel(aconf
))
361 add_to_resv_hash(aconf
->host
, aconf
);
368 if(bandb_check_resv_nick(aconf
))
369 rb_dlinkAddAlloc(aconf
, &resv_conf_list
);
377 check_banned_lines();
381 bandb_handle_failure(rb_helper
*helper
, char **parv
, int parc
)
383 if(server_state_foreground
)
384 fprintf(stderr
, "bandb - bandb failure: %s\n", parv
[1]);
386 ilog(L_MAIN
, "bandb - bandb failure: %s", parv
[1]);
387 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
, "bandb - bandb failure: %s", parv
[1]);
392 bandb_parse(rb_helper
*helper
)
394 static char buf
[READBUF_SIZE
];
398 while((len
= rb_helper_read(helper
, buf
, sizeof(buf
))))
400 parc
= rb_string_to_array(buf
, parv
, sizeof(parv
));
408 bandb_handle_failure(helper
, parv
, parc
);
414 bandb_handle_ban(parv
, parc
);
418 bandb_handle_clear();
421 bandb_handle_finish();
428 bandb_rehash_bans(void)
430 if(bandb_helper
!= NULL
)
431 rb_helper_write(bandb_helper
, "L");
435 bandb_restart_cb(rb_helper
*helper
)
437 ilog(L_MAIN
, "bandb - bandb_restart_cb called, bandb helper died?");
438 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
,
439 "bandb - bandb_restart_cb called, bandb helper died?");
442 rb_helper_close(helper
);