]> jfr.im git - solanum.git/commitdiff
authd: fix crash/restart breaking DNSBL lookups (#394)
authorAaron Jones <redacted>
Wed, 11 Jan 2023 01:28:32 +0000 (01:28 +0000)
committerGitHub <redacted>
Wed, 11 Jan 2023 01:28:32 +0000 (01:28 +0000)
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
include/authproc.h
ircd/authproc.c
ircd/s_user.c
modules/m_stats.c

index 311cf948e54e4b0dddfa9a6fadc5c36d0e88759d..66ad3964aaa0f39eb6df337c691ff7e36c6d223c 100644 (file)
 #include "rb_dictionary.h"
 #include "client.h"
 
-struct DNSBLEntryStats
+struct DNSBLEntry
 {
        char *host;
+       char *reason;
+       char *filters;
        uint8_t iptype;
        unsigned int hits;
 };
index 9d2521972359df0a4f371c1bb2dd7a36e96e9d07..79fa4cb704d97f83f27c52220217d8c8102eda7d 100644 (file)
@@ -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. */
index 8a6646247294cbeb9faec84ffed77006dc793253..48acff5ba75f150e608336dcd560865a8e1d9c50 100644 (file)
@@ -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))
                        {
index 9530b26d23c963e939451df68b258d246822a996..751c9446be2693e3c0afcbb721a2771e80e8b678 100644 (file)
@@ -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);
        }
 }