]> 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:52:29 +0000 (10:52 +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.

(cherry picked from commit e980affba0ed40476d977d284d142988633b6a7d)

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 69dc66cca05fde51019fa573550492baa9511857..cc8ffc33f3592fbdbecbdce28cb9d89f19c363f3 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 3b6f3f375bb5dbf54aa2eebc20338670b93f58eb..ea9e14d32addfd632f0ed76716828188d229d5b4 100644 (file)
@@ -128,6 +128,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 81ecc772cbfa4388948d345a8e09ab249b8453ef..c9aa97d1a6e5c192032b68bb982d8c276aeb1a8d 100644 (file)
@@ -46,3 +46,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 8e26ff5762fe9276987a9e193d4f7336274e90fa..159122488d98f95159e29738059618f109aa5278 100644 (file)
@@ -9890,13 +9890,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);