]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/rules: fix RPZ if SOA is repated, as usual in AXFR output
authorVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 25 Mar 2024 12:28:23 +0000 (13:28 +0100)
committerOto Šťáva <oto.stava@nic.cz>
Wed, 27 Mar 2024 08:59:22 +0000 (09:59 +0100)
The check for name equality didn't cover the case of repeated SOA.

NEWS
lib/rules/zonefile.c

diff --git a/NEWS b/NEWS
index 6d108713e56cbc714db6468584a7aaf21850768f..27c209a22e6b5d35b384e79b7c12eef0e08fe605 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ Bugfixes
 - fix listening by interface name containing dashes (#900, !1500)
 - fix kresctl http request timeout (!1505)
 - fix RPZ if it contains apex NS record (!1516)
+- fix RPZ if SOA is repated, as usual in AXFR output (!1521)
 - fix on 32-bit systems with 64-bit time_t (!1510)
 - fix paths to knot-dns libs if exec_prefix != prefix (!1503)
 
index d5163e2af80f54f38ca28c316a628276c65ccdc6..6c260d7710b9d277c9b15b1e59629be460c526ef 100644 (file)
@@ -118,30 +118,33 @@ static bool owner_relativize(zs_scanner_t *s)
        if (!d->c->is_rpz)
                return true;
 
+       // $ORIGIN as fallback if SOA is missing
+       const knot_dname_t *apex = d->origin_soa;
+       if (!apex)
+               apex = s->zone_origin;
+
        // SOA determines the zone apex, but lots of error/warn cases
        if (s->r_type == KNOT_RRTYPE_SOA) {
-               if (d->seen_record && !knot_dname_is_equal(s->zone_origin, s->r_owner)) {
+               if (d->seen_record && !knot_dname_is_equal(apex, s->r_owner)) {
                        // We most likely inserted some rules wrong already, so abort.
                        kr_log_error(RULES,
                                "SOA encountered late, with unexpected owner; aborting\n");
                        s->state = ZS_STATE_STOP;
                        return false;
                }
-               if (!d->warned_soa && (d->seen_record || d->origin_soa)) {
+               if (!d->warned_soa && d->origin_soa) {
+                       d->warned_soa = true;
+                       kr_log_warning(RULES, "ignoring repeated SOA record in a RPZ\n");
+               } else if (!d->warned_soa && d->seen_record) {
                        d->warned_soa = true;
                        kr_log_warning(RULES,
                                "SOA should come as the first record in a RPZ\n");
                }
                if (!d->origin_soa) // sticking with the first encountered SOA
-                       d->origin_soa = knot_dname_copy(s->r_owner, d->pool);
+                       apex = d->origin_soa = knot_dname_copy(s->r_owner, d->pool);
        }
        d->seen_record = true;
 
-       // $ORIGIN as fallback if SOA is missing
-       const knot_dname_t *apex = d->origin_soa;
-       if (!apex)
-               apex = s->zone_origin;
-
        const int labels = knot_dname_in_bailiwick(s->r_owner, apex);
        if (labels < 0) {
                if (!d->warned_bailiwick) {