authd: fix crash/restart breaking DNSBL lookups (#394)
authd child processes are only told about configured DNSBLs when the configuration is being parsed. This is bad, because when authd crashes or is killed, IRCd will restart it, but will not tell it about any configured DNSBLs until IRCd is next rehashed. We already have a dictionary that stores configured DNSBLs (for hit statistics for `STATS n'), so store the additional needed fields in that structure, and loop over that dictionary's entries when authd is restarted, sending the fields just as if the configuration were being reloaded. Reported-By: @Unit193
This commit is contained in:
parent
32d37a1660
commit
fbc97166a6
4 changed files with 38 additions and 20 deletions
|
@ -30,9 +30,11 @@
|
|||
#include "rb_dictionary.h"
|
||||
#include "client.h"
|
||||
|
||||
struct DNSBLEntryStats
|
||||
struct DNSBLEntry
|
||||
{
|
||||
char *host;
|
||||
char *reason;
|
||||
char *filters;
|
||||
uint8_t iptype;
|
||||
unsigned int hits;
|
||||
};
|
||||
|
|
|
@ -348,6 +348,15 @@ configure_authd(void)
|
|||
}
|
||||
else
|
||||
opm_check_enable(false);
|
||||
|
||||
/* Configure DNSBLs */
|
||||
rb_dictionary_iter iter;
|
||||
struct DNSBLEntry *entry;
|
||||
RB_DICTIONARY_FOREACH(entry, &iter, dnsbl_stats)
|
||||
{
|
||||
rb_helper_write(authd_helper, "O rbl %s %hhu %s :%s", entry->host,
|
||||
entry->iptype, entry->filters, entry->reason);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -584,7 +593,7 @@ void
|
|||
add_dnsbl_entry(const char *host, const char *reason, uint8_t iptype, rb_dlink_list *filters)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
struct DNSBLEntryStats *stats = rb_malloc(sizeof(*stats));
|
||||
struct DNSBLEntry *entry = rb_malloc(sizeof(*entry));
|
||||
char filterbuf[BUFSIZE] = "*";
|
||||
size_t s = 0;
|
||||
|
||||
|
@ -610,11 +619,13 @@ add_dnsbl_entry(const char *host, const char *reason, uint8_t iptype, rb_dlink_l
|
|||
if(s)
|
||||
filterbuf[s - 1] = '\0';
|
||||
|
||||
stats->host = rb_strdup(host);
|
||||
stats->iptype = iptype;
|
||||
stats->hits = 0;
|
||||
rb_dictionary_add(dnsbl_stats, stats->host, stats);
|
||||
entry->host = rb_strdup(host);
|
||||
entry->reason = rb_strdup(reason);
|
||||
entry->filters = rb_strdup(filterbuf);
|
||||
entry->iptype = iptype;
|
||||
entry->hits = 0;
|
||||
|
||||
rb_dictionary_add(dnsbl_stats, entry->host, entry);
|
||||
rb_helper_write(authd_helper, "O rbl %s %hhu %s :%s", host, iptype, filterbuf, reason);
|
||||
}
|
||||
|
||||
|
@ -622,12 +633,15 @@ add_dnsbl_entry(const char *host, const char *reason, uint8_t iptype, rb_dlink_l
|
|||
void
|
||||
del_dnsbl_entry(const char *host)
|
||||
{
|
||||
struct DNSBLEntryStats *stats = rb_dictionary_retrieve(dnsbl_stats, host);
|
||||
if(stats != NULL)
|
||||
struct DNSBLEntry *entry = rb_dictionary_retrieve(dnsbl_stats, host);
|
||||
|
||||
if(entry != NULL)
|
||||
{
|
||||
rb_dictionary_delete(dnsbl_stats, host);
|
||||
rb_free(stats->host);
|
||||
rb_free(stats);
|
||||
rb_dictionary_delete(dnsbl_stats, entry->host);
|
||||
rb_free(entry->host);
|
||||
rb_free(entry->reason);
|
||||
rb_free(entry->filters);
|
||||
rb_free(entry);
|
||||
}
|
||||
|
||||
rb_helper_write(authd_helper, "O rbl_del %s", host);
|
||||
|
@ -636,10 +650,12 @@ del_dnsbl_entry(const char *host)
|
|||
static void
|
||||
dnsbl_delete_elem(rb_dictionary_element *delem, void *unused)
|
||||
{
|
||||
struct DNSBLEntryStats *stats = delem->data;
|
||||
struct DNSBLEntry *entry = delem->data;
|
||||
|
||||
rb_free(stats->host);
|
||||
rb_free(stats);
|
||||
rb_free(entry->host);
|
||||
rb_free(entry->reason);
|
||||
rb_free(entry->filters);
|
||||
rb_free(entry);
|
||||
}
|
||||
|
||||
/* Delete all the DNSBL entries. */
|
||||
|
|
|
@ -215,12 +215,12 @@ authd_check(struct Client *client_p, struct Client *source_p)
|
|||
{
|
||||
case 'B': /* DNSBL */
|
||||
{
|
||||
struct DNSBLEntryStats *stats;
|
||||
struct DNSBLEntry *entry;
|
||||
char *dnsbl_name = source_p->preClient->auth.data;
|
||||
|
||||
if(dnsbl_stats != NULL)
|
||||
if((stats = rb_dictionary_retrieve(dnsbl_stats, dnsbl_name)) != NULL)
|
||||
stats->hits++;
|
||||
if((entry = rb_dictionary_retrieve(dnsbl_stats, dnsbl_name)) != NULL)
|
||||
entry->hits++;
|
||||
|
||||
if(IsExemptKline(source_p) || IsConfExemptDNSBL(aconf))
|
||||
{
|
||||
|
|
|
@ -727,16 +727,16 @@ static void
|
|||
stats_dnsbl(struct Client *source_p)
|
||||
{
|
||||
rb_dictionary_iter iter;
|
||||
struct DNSBLEntryStats *stats;
|
||||
struct DNSBLEntry *entry;
|
||||
|
||||
if(dnsbl_stats == NULL)
|
||||
return;
|
||||
|
||||
RB_DICTIONARY_FOREACH(stats, &iter, dnsbl_stats)
|
||||
RB_DICTIONARY_FOREACH(entry, &iter, dnsbl_stats)
|
||||
{
|
||||
/* use RPL_STATSDEBUG for now -- jilles */
|
||||
sendto_one_numeric(source_p, RPL_STATSDEBUG, "n :%d %s",
|
||||
stats->hits, (const char *)iter.cur->key);
|
||||
entry->hits, entry->host);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue