Commit 3cc8c7d6 authored by Evan Hunt's avatar Evan Hunt
Browse files

[master] fix nxrrset in nxdomain redirection

4000.	[bug]		NXDOMAIN redirection incorrectly handled NXRRSET
			from the redirect zone. [RT #37722]
parent ad964551
4000. [bug] NXDOMAIN redirection incorrectly handled NXRRSET
from the redirect zone. [RT #37722]
3999. [func] "mkeys" and "nzf" files are now named after
their corresponding views, unless the view name
contains characters that would be incompatible
......
......@@ -6010,7 +6010,7 @@ dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset,
* Only perform the update if the client is in the allow query acl and
* returning the update would not cause a DNSSEC validation failure.
*/
static isc_boolean_t
static isc_result_t
redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp,
dns_rdatatype_t qtype)
......@@ -6029,7 +6029,7 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
CTRACE(ISC_LOG_DEBUG(3), "redirect");
if (client->view->redirect == NULL)
return (ISC_FALSE);
return (ISC_R_NOTFOUND);
dns_fixedname_init(&fixed);
found = dns_fixedname_name(&fixed);
......@@ -6039,15 +6039,15 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
dns_clientinfo_init(&ci, client, NULL);
if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp))
return (ISC_FALSE);
return (ISC_R_NOTFOUND);
if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) {
if (rdataset->trust == dns_trust_secure)
return (ISC_FALSE);
return (ISC_R_NOTFOUND);
if (rdataset->trust == dns_trust_ultimate &&
(rdataset->type == dns_rdatatype_nsec ||
rdataset->type == dns_rdatatype_nsec3))
return (ISC_FALSE);
return (ISC_R_NOTFOUND);
if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
for (result = dns_rdataset_first(rdataset);
result == ISC_R_SUCCESS;
......@@ -6058,7 +6058,7 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
if (type == dns_rdatatype_nsec ||
type == dns_rdatatype_nsec3 ||
type == dns_rdatatype_rrsig)
return (ISC_FALSE);
return (ISC_R_NOTFOUND);
}
}
}
......@@ -6067,16 +6067,16 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
dns_zone_getqueryacl(client->view->redirect),
ISC_TRUE);
if (result != ISC_R_SUCCESS)
return (ISC_FALSE);
return (ISC_R_NOTFOUND);
result = dns_zone_getdb(client->view->redirect, &db);
if (result != ISC_R_SUCCESS)
return (ISC_FALSE);
return (ISC_R_NOTFOUND);
dbversion = query_findversion(client, db);
if (dbversion == NULL) {
dns_db_detach(&db);
return (ISC_FALSE);
return (ISC_R_NOTFOUND);
}
/*
......@@ -6085,16 +6085,22 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
result = dns_db_findext(db, client->query.qname, dbversion->version,
qtype, DNS_DBFIND_NOZONECUT, client->now,
&node, found, &cm, &ci, &trdataset, NULL);
if (result != ISC_R_SUCCESS) {
if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(rdataset);
if (dns_rdataset_isassociated(&trdataset))
dns_rdataset_disassociate(&trdataset);
goto nxrrset;
} else if (result != ISC_R_SUCCESS) {
if (dns_rdataset_isassociated(&trdataset))
dns_rdataset_disassociate(&trdataset);
if (node != NULL)
dns_db_detachnode(db, &node);
dns_db_detach(&db);
return (ISC_FALSE);
return (ISC_R_NOTFOUND);
}
CTRACE(ISC_LOG_DEBUG(3), "redirect: found data: done");
CTRACE(ISC_LOG_DEBUG(3), "redirect: found data: done");
dns_name_copy(found, name, NULL);
if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(rdataset);
......@@ -6102,6 +6108,7 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
dns_rdataset_clone(&trdataset, rdataset);
dns_rdataset_disassociate(&trdataset);
}
nxrrset:
if (*nodep != NULL)
dns_db_detachnode(*dbp, nodep);
dns_db_detach(dbp);
......@@ -6114,7 +6121,7 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
NS_QUERYATTR_NOADDITIONAL);
return (ISC_TRUE);
return (result);
}
/*
......@@ -6142,7 +6149,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
int order;
isc_buffer_t *dbuf;
isc_buffer_t b;
isc_result_t result, eresult;
isc_result_t result, eresult, tresult;
dns_fixedname_t fixed;
dns_fixedname_t wildcardname;
dns_dbversion_t *version, *zversion;
......@@ -6157,6 +6164,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
int line = -1;
isc_boolean_t dns64_exclude, dns64;
isc_boolean_t nxrewrite = ISC_FALSE;
isc_boolean_t redirected = ISC_FALSE;
dns_clientinfomethods_t cm;
dns_clientinfo_t ci;
char errmsg[256];
......@@ -6388,7 +6396,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
dns_db_t *tdb = NULL;
dns_zone_t *tzone = NULL;
dns_dbversion_t *tversion = NULL;
isc_result_t tresult;
tresult = query_getzonedb(client, client->query.qname, qtype,
DNS_GETDB_PARTIAL, &tzone, &tdb,
......@@ -7191,6 +7198,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
* Look for a NSEC3 record if we don't have a NSEC record.
*/
nxrrset_rrsig:
if (redirected)
goto cleanup;
if (!dns_rdataset_isassociated(rdataset) &&
WANTDNSSEC(client)) {
if ((fname->attributes & DNS_NAMEATTR_WILDCARD) == 0) {
......@@ -7315,10 +7324,21 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
case DNS_R_NXDOMAIN:
INSIST(is_zone);
if (!empty_wild &&
redirect(client, fname, rdataset, &node, &db, &version,
type))
break;
if (!empty_wild) {
tresult = redirect(client, fname, rdataset, &node,
&db, &version, type);
if (tresult == ISC_R_SUCCESS)
break;
if (tresult == DNS_R_NXRRSET) {
redirected = ISC_TRUE;
goto iszone_nxrrset;
}
if (tresult == DNS_R_NCACHENXRRSET) {
redirected = ISC_TRUE;
is_zone = ISC_FALSE;
goto ncache_nxrrset;
}
}
if (dns_rdataset_isassociated(rdataset)) {
/*
* If we've got a NSEC record, we need to save the
......@@ -7381,9 +7401,22 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
goto cleanup;
case DNS_R_NCACHENXDOMAIN:
if (redirect(client, fname, rdataset, &node, &db, &version,
type))
tresult = redirect(client, fname, rdataset, &node,
&db, &version, type);
if (tresult == ISC_R_SUCCESS)
break;
if (tresult == DNS_R_NXRRSET) {
redirected = ISC_TRUE;
is_zone = ISC_TRUE;
goto iszone_nxrrset;
}
if (tresult == DNS_R_NCACHENXRRSET) {
redirected = ISC_TRUE;
result = tresult;
goto ncache_nxrrset;
}
/* FALLTHROUGH */
case DNS_R_NCACHENXRRSET:
ncache_nxrrset:
INSIST(!is_zone);
......
......@@ -332,6 +332,14 @@ n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:checking redirect works (with noerror) when qtype is not found ($n)"
ret=0
$DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.2 txt > dig.out.ns2.test$n || ret=1
grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1
n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:checking that redirect zones reload correctly"
ret=0
sleep 1 # ensure file mtime will have changed
......
......@@ -334,6 +334,13 @@
corrected at run time. [RT #37187]
</para>
</listitem>
<listitem>
<para>
When NXDOMAIN redirection is in use, queries for a name
that is present in the redirection zone but a type that
is not present will now return NOERROR instead of NXDOMAIN.
</para>
</listitem>
</itemizedlist>
</sect2>
<sect2 id="end_of_life">
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment