mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
[master] fix nxrrset in nxdomain redirection
4000. [bug] NXDOMAIN redirection incorrectly handled NXRRSET from the redirect zone. [RT #37722]
This commit is contained in:
parent
ad9645512c
commit
3cc8c7d630
4 changed files with 72 additions and 21 deletions
3
CHANGES
3
CHANGES
|
|
@ -1,3 +1,6 @@
|
|||
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">
|
||||
|
|
|
|||
Loading…
Reference in a new issue