]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
4580. [bug] 4578 introduced a regression when handling CNAME to
authorMark Andrews <marka@isc.org>
Tue, 14 Mar 2017 04:07:00 +0000 (15:07 +1100)
committerMark Andrews <marka@isc.org>
Tue, 14 Mar 2017 04:07:00 +0000 (15:07 +1100)
                        referral below the current domain. [RT #44850]

CHANGES
lib/dns/resolver.c

diff --git a/CHANGES b/CHANGES
index a6e60e0cffcc98a355c780d07bd79ce622cc8fc4..51dd906cbd5e452b0bd8131ebb5e2aa01468c5a7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+4580.  [bug]           4578 introduced a regression when handling CNAME to
+                       referral below the current domain. [RT #44850]
+
 4579.  [func]          Logging channels and dnstap output files can now
                        be configured with a "suffix" option, set to
                        either "increment" or "timestamp", indicating
index f298d8a7657ca4f8eceff1e0b9c167b511ba4b66..60541c5abde718146dce3bb0dc034258fcf3136b 100644 (file)
@@ -6256,7 +6256,7 @@ is_answeraddress_allowed(dns_view_t *view, dns_name_t *name,
 
 static isc_boolean_t
 is_answertarget_allowed(fetchctx_t *fctx, dns_name_t *qname, dns_name_t *rname,
-                       dns_rdataset_t *rdataset)
+                       dns_rdataset_t *rdataset, isc_boolean_t *chainingp)
 {
        isc_result_t result;
        dns_rbtnode_t *node = NULL;
@@ -6277,8 +6277,11 @@ is_answertarget_allowed(fetchctx_t *fctx, dns_name_t *qname, dns_name_t *rname,
        REQUIRE(rdataset->type == dns_rdatatype_cname ||
                rdataset->type == dns_rdatatype_dname);
 
-       /* By default, we allow any target name. */
-       if (view->denyanswernames == NULL)
+       /*
+        * By default, we allow any target name.
+        * If newqname != NULL we also need to extract the newqname.
+        */
+       if (chainingp == NULL && view->denyanswernames == NULL)
                return (ISC_TRUE);
 
        result = dns_rdataset_first(rdataset);
@@ -6301,7 +6304,7 @@ is_answertarget_allowed(fetchctx_t *fctx, dns_name_t *qname, dns_name_t *rname,
                dns_name_split(qname, nlabels, &prefix, NULL);
                result = dns_name_concatenate(&prefix, &dname.dname, tname,
                                              NULL);
-               if (result == ISC_R_NOSPACE)
+               if (result == DNS_R_NAMETOOLONG)
                        return (ISC_TRUE);
                RUNTIME_CHECK(result == ISC_R_SUCCESS);
                break;
@@ -6309,6 +6312,12 @@ is_answertarget_allowed(fetchctx_t *fctx, dns_name_t *qname, dns_name_t *rname,
                INSIST(0);
        }
 
+       if (chainingp != NULL)
+               *chainingp = ISC_TRUE;
+
+       if (view->denyanswernames == NULL)
+               return (ISC_TRUE);
+
        /*
         * If the owner name matches one in the exclusion list, either exactly
         * or partially, allow it.
@@ -6994,7 +7003,7 @@ answer_response(fetchctx_t *fctx) {
                        if ((rdataset->type == dns_rdatatype_cname ||
                             rdataset->type == dns_rdatatype_dname) &&
                             !is_answertarget_allowed(fctx, qname, aname,
-                                                     rdataset))
+                                                     rdataset, NULL))
                        {
                                return (DNS_R_SERVFAIL);
                        }
@@ -7017,7 +7026,9 @@ answer_response(fetchctx_t *fctx) {
                }
                if ((ardataset->type == dns_rdatatype_cname ||
                     ardataset->type == dns_rdatatype_dname) &&
-                    !is_answertarget_allowed(fctx, qname, aname, ardataset)) {
+                    !is_answertarget_allowed(fctx, qname, aname, ardataset,
+                                             NULL))
+               {
                        return (DNS_R_SERVFAIL);
                }
                aname->attributes |= DNS_NAMEATTR_CACHE;
@@ -7052,7 +7063,9 @@ answer_response(fetchctx_t *fctx) {
                        log_formerr(fctx, "CNAME response for %s RR", buf);
                        return (DNS_R_FORMERR);
                }
-               if (!is_answertarget_allowed(fctx, qname, cname, crdataset)) {
+               if (!is_answertarget_allowed(fctx, qname, cname, crdataset,
+                                            NULL))
+               {
                        return (DNS_R_SERVFAIL);
                }
                cname->attributes |= DNS_NAMEATTR_CACHE;
@@ -7084,7 +7097,8 @@ answer_response(fetchctx_t *fctx) {
                if (!validinanswer(drdataset, fctx)) {
                        return (DNS_R_FORMERR);
                }
-               if (!is_answertarget_allowed(fctx, qname, dname, drdataset)) {
+               if (!is_answertarget_allowed(fctx, qname, dname, drdataset,
+                                            &chaining)) {
                        return (DNS_R_SERVFAIL);
                }
                dname->attributes |= DNS_NAMEATTR_CACHE;
@@ -7111,7 +7125,6 @@ answer_response(fetchctx_t *fctx) {
                        sigrdataset->trust = trust;
                        break;
                }
-               chaining = ISC_TRUE;
        } else {
                log_formerr(fctx, "reply has no answer");
                return (DNS_R_FORMERR);
@@ -7126,13 +7139,7 @@ answer_response(fetchctx_t *fctx) {
         * Did chaining end before we got the final answer?
         */
        if (chaining) {
-               /*
-                * Yes.  This may be a negative reply, so hand off
-                * authority section processing to the noanswer code.
-                * If it isn't a noanswer response, no harm will be
-                * done.
-                */
-               return (noanswer_response(fctx, qname, 0));
+               return (ISC_R_SUCCESS);
        }
 
        /*