]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix DNAME when QTYPE is CNAME or ANY
authorMark Andrews <marka@isc.org>
Tue, 17 Nov 2020 00:03:21 +0000 (11:03 +1100)
committerMark Andrews <marka@isc.org>
Wed, 18 Nov 2020 23:18:01 +0000 (10:18 +1100)
The synthesised CNAME is not supposed to be followed when the
QTYPE is CNAME or ANY as the lookup is satisfied by the CNAME
record.

CHANGES
bin/tests/system/auth/ns1/example.com.db
bin/tests/system/auth/tests.sh
doc/notes/notes-current.rst
lib/ns/query.c

diff --git a/CHANGES b/CHANGES
index 8aa352925c2d18cd7993faee88ba81e692c91250..90a7585b92ebbbb2fe931ba436fff20793a10966 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+5534.  [bug]           The synthesised CNAME from a DNAME was incorrectly
+                       followed when the QTYPE was CNAME or ANY. [GL #2280]
+
 5533.  [func]          Add "stale-refresh-time" option, a time window that
                        starts after a failed lookup, during which stale rrset
                        will be served directly from cache before a new
index a6c98de41c2c2af8cd3090d065823138347ddb88..a61c88229e0d566133cae29027b3dc16b4d212af 100644 (file)
@@ -20,3 +20,4 @@ ns                      A       10.53.0.1
 www                    CNAME   server.example.net.
 inzone                 CNAME   a.example.com.
 a                      A       10.53.0.1
+dname                  DNAME   @
index f9daf4342644e311e9681e050106d6f2bb2e8c4d..ecfd451ad5989e802399722cf4800ca06afefe45 100644 (file)
@@ -127,6 +127,54 @@ grep "a.example.com.*A.*10.53.0.1" dig.out.test$n > /dev/null || ret=1
 [ $ret -eq 0 ] || echo_i "failed"
 status=`expr $status + $ret`
 
+n=`expr $n + 1`
+echo_i "check that in-zone CNAME records does not return target data when QTYPE is CNAME (rd=1/ra=1) ($n)"
+ret=0
+$DIG $DIGOPTS @10.53.0.2 -t cname inzone.example.com > dig.out.test$n || ret=1
+grep 'ANSWER: 1,' dig.out.test$n > /dev/null || ret=1
+grep 'flags: qr aa rd ra;' dig.out.test$n > /dev/null || ret=1
+grep 'inzone\.example\.com\..*CNAME.a\.example\.com\.' dig.out.test$n > /dev/null || ret=1
+grep 'a\.example\.com\..*A.10\.53\.0\.1' dig.out.test$n > /dev/null && ret=1
+[ $ret -eq 0 ] || echo_i "failed"
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "check that in-zone CNAME records does not return target data when QTYPE is ANY (rd=1/ra=1) ($n)"
+ret=0
+$DIG $DIGOPTS @10.53.0.2 -t any inzone.example.com > dig.out.test$n || ret=1
+grep 'ANSWER: 1,' dig.out.test$n > /dev/null || ret=1
+grep 'flags: qr aa rd ra;' dig.out.test$n > /dev/null || ret=1
+grep 'inzone\.example\.com\..*CNAME.a\.example\.com\.' dig.out.test$n > /dev/null || ret=1
+grep 'a\.example\.com\..*A.10\.53\.0\.1' dig.out.test$n > /dev/null && ret=1
+[ $ret -eq 0 ] || echo_i "failed"
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "check that in-zone DNAME records does not return target data when QTYPE is CNAME (rd=1/ra=1) ($n)"
+ret=0
+$DIG $DIGOPTS @10.53.0.2 -t cname inzone.dname.example.com > dig.out.test$n || ret=1
+grep 'ANSWER: 2,' dig.out.test$n > /dev/null || ret=1
+grep 'flags: qr aa rd ra;' dig.out.test$n > /dev/null || ret=1
+grep 'dname\.example\.com\..*DNAME.example\.com\.' dig.out.test$n > /dev/null || ret=1
+grep 'inzone\.dname\.example\.com\..*CNAME.inzone\.example\.com\.' dig.out.test$n > /dev/null || ret=1
+grep 'inzone\.example\.com\..*CNAME.a\.example\.com\.' dig.out.test$n > /dev/null && ret=1
+grep 'a\.example\.com\..*A.10\.53\.0\.1' dig.out.test$n > /dev/null && ret=1
+[ $ret -eq 0 ] || echo_i "failed"
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo_i "check that in-zone DNAME records does not return target data when QTYPE is ANY (rd=1/ra=1) ($n)"
+ret=0
+$DIG $DIGOPTS @10.53.0.2 -t any inzone.dname.example.com > dig.out.test$n || ret=1
+grep 'ANSWER: 2,' dig.out.test$n > /dev/null || ret=1
+grep 'flags: qr aa rd ra;' dig.out.test$n > /dev/null || ret=1
+grep 'dname\.example\.com\..*DNAME.example\.com\.' dig.out.test$n > /dev/null || ret=1
+grep 'inzone\.dname\.example\.com\..*CNAME.inzone\.example\.com\.' dig.out.test$n > /dev/null || ret=1
+grep 'inzone\.example\.com.*CNAME.a\.example\.com\.' dig.out.test$n > /dev/null && ret=1
+grep 'a\.example\.com.*A.10\.53\.0\.1' dig.out.test$n > /dev/null && ret=1
+[ $ret -eq 0 ] || echo_i "failed"
+status=`expr $status + $ret`
+
 n=`expr $n + 1`
 echo_i "check that CHAOS addresses are compared correctly ($n)"
 ret=0
index 2a784e95fdf78e67ca4f81de2b8e70ad445b3cd5..412993e09f462771e879304258308f63053f915f 100644 (file)
@@ -65,3 +65,6 @@ Bug Fixes
 
 - ``named`` could crash with an assertion failure if a TCP connection is closed
   while the request is still processing. [GL #2227]
+
+- The synthesised CNAME from a DNAME was incorrectly followed when the QTYPE
+  was CNAME or ANY. [GL #2280]
index 33c7b6a2db2d103b4db4235c2d65b1bcea548117..e329b55e4cf69fb8c36adf20c11588539903d013 100644 (file)
@@ -9897,13 +9897,20 @@ query_dname(query_ctx_t *qctx) {
        }
 
        /*
-        * Switch to the new qname and restart.
+        * If the original query was not for a CNAME or ANY then follow the
+        * CNAME.
         */
-       ns_client_qnamereplace(qctx->client, qctx->fname);
-       qctx->fname = NULL;
-       qctx->want_restart = true;
-       if (!WANTRECURSION(qctx->client)) {
-               qctx->options |= DNS_GETDB_NOLOG;
+       if (qctx->qtype != dns_rdatatype_cname &&
+           qctx->qtype != dns_rdatatype_any) {
+               /*
+                * Switch to the new qname and restart.
+                */
+               ns_client_qnamereplace(qctx->client, qctx->fname);
+               qctx->fname = NULL;
+               qctx->want_restart = true;
+               if (!WANTRECURSION(qctx->client)) {
+                       qctx->options |= DNS_GETDB_NOLOG;
+               }
        }
 
        query_addauth(qctx);