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;
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);
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;
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.
if ((rdataset->type == dns_rdatatype_cname ||
rdataset->type == dns_rdatatype_dname) &&
!is_answertarget_allowed(fctx, qname, aname,
- rdataset))
+ rdataset, NULL))
{
return (DNS_R_SERVFAIL);
}
}
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;
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;
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;
sigrdataset->trust = trust;
break;
}
- chaining = ISC_TRUE;
} else {
log_formerr(fctx, "reply has no answer");
return (DNS_R_FORMERR);
* 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);
}
/*