mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
if recursion is allowed and minimal-responses is no, search other databases
this restores functionality that was removed in commit 03be5a6b4e,
allowing named to search in authoritative zone databases outside the
current zone for additional data, if and only if recursion is allowed
and minimal-responses is disabled.
This commit is contained in:
parent
d134dd9c8c
commit
7fff3295f5
10 changed files with 235 additions and 50 deletions
|
|
@ -10,7 +10,7 @@
|
|||
$TTL 86400
|
||||
@ IN SOA ns1 hostmaster ( 2 8H 2H 4W 1D );
|
||||
NS ns1
|
||||
ns1 A 127.0.0.0
|
||||
ns1 A 10.53.0.1
|
||||
|
||||
nap IN NAPTR 50 50 "S" "SIPS+D2T" "" server
|
||||
server SRV 0 0 5061 server
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
$TTL 86400
|
||||
@ IN SOA ns1 hostmaster ( 2 8H 2H 4W 1D );
|
||||
NS ns1
|
||||
ns1 A 127.0.0.0
|
||||
ns1 A 10.53.0.1
|
||||
|
||||
nap IN NAPTR 50 50 "S" "SIPS+D2T" "" server.hang3a.zone.
|
||||
www AAAA 192::99
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
$TTL 86400
|
||||
@ IN SOA ns1 hostmaster ( 2 8H 2H 4W 1D );
|
||||
NS ns1
|
||||
ns1 A 127.0.0.0
|
||||
ns1 A 10.53.0.1
|
||||
|
||||
ns1 NID 2 0:0:0:0
|
||||
ns1 L64 2 0:0:0:0
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@
|
|||
$TTL 86400
|
||||
@ IN SOA ns1 hostmaster ( 2 8H 2H 4W 1D );
|
||||
NS ns1
|
||||
ns1 A 127.0.0.0
|
||||
NS ns1.rt2.example.
|
||||
ns1 A 10.53.0.1
|
||||
|
||||
rt RT 2 www
|
||||
www AAAA 192::99
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
$TTL 86400
|
||||
@ IN SOA ns1 hostmaster ( 2 8H 2H 4W 1D );
|
||||
NS ns1
|
||||
ns1 A 127.0.0.0
|
||||
ns1 A 10.53.0.1
|
||||
|
||||
rt RT 2 www.hang3b.zone.
|
||||
server SRV 0 0 5061 server
|
||||
|
|
|
|||
14
bin/tests/system/additional/ns3/ex.db
Normal file
14
bin/tests/system/additional/ns3/ex.db
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$TTL 86400
|
||||
@ IN SOA ns1 hostmaster ( 2 8H 2H 4W 1D );
|
||||
NS ns1
|
||||
NS ns1.ex2.
|
||||
ns1 A 10.53.0.1
|
||||
13
bin/tests/system/additional/ns3/ex2.db
Normal file
13
bin/tests/system/additional/ns3/ex2.db
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$TTL 86400
|
||||
@ IN SOA ns1 hostmaster ( 2 8H 2H 4W 1D );
|
||||
NS ns1
|
||||
ns1 A 10.53.0.1
|
||||
|
|
@ -21,9 +21,20 @@ options {
|
|||
listen-on-v6 { none; };
|
||||
recursion yes;
|
||||
dnssec-validation yes;
|
||||
minimal-responses no;
|
||||
};
|
||||
|
||||
zone "." {
|
||||
type hint;
|
||||
file "root.hint";
|
||||
};
|
||||
|
||||
zone "ex" {
|
||||
type master;
|
||||
file "ex.db";
|
||||
};
|
||||
|
||||
zone "ex2" {
|
||||
type master;
|
||||
file "ex2.db";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ n=`expr $n + 1`
|
|||
echo_i "testing with 'minimal-any no;' ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS -t ANY www.rt.example @10.53.0.1 > dig.out.$n || ret=1
|
||||
grep "ANSWER: 3, AUTHORITY: 1, ADDITIONAL: 2" dig.out.$n > /dev/null || ret=1
|
||||
grep "ANSWER: 3, AUTHORITY: 2, ADDITIONAL: 2" dig.out.$n > /dev/null || ret=1
|
||||
if [ $ret -eq 1 ] ; then
|
||||
echo_i " failed"; status=1
|
||||
fi
|
||||
|
|
@ -322,5 +322,23 @@ if [ $ret -eq 1 ] ; then
|
|||
echo_i " failed"; status=1
|
||||
fi
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "testing out-of-zone additional data from auth zones (authoritative) ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS -t NS rt.example @10.53.0.1 > dig.out.$n || ret=1
|
||||
grep "ADDITIONAL: 2" dig.out.$n > /dev/null || ret=1
|
||||
if [ $ret -eq 1 ] ; then
|
||||
echo_i " failed"; status=1
|
||||
fi
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "testing out-of-zone additional data from auth zones (recursive) ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS -t NS ex @10.53.0.3 > dig.out.$n || ret=1
|
||||
grep "ADDITIONAL: 3" dig.out.$n > /dev/null || ret=1
|
||||
if [ $ret -eq 1 ] ; then
|
||||
echo_i " failed"; status=1
|
||||
fi
|
||||
|
||||
echo_i "exit status: $status"
|
||||
[ $status -eq 0 ] || exit 1
|
||||
|
|
|
|||
216
lib/ns/query.c
216
lib/ns/query.c
|
|
@ -1442,6 +1442,175 @@ query_isduplicate(ns_client_t *client, dns_name_t *name,
|
|||
return (false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up data for given 'name' and 'type' in given 'version' of 'db' for
|
||||
* 'client'. Called from query_additionalauth().
|
||||
*
|
||||
* If the lookup is successful:
|
||||
*
|
||||
* - store the node containing the result at 'nodep',
|
||||
*
|
||||
* - store the owner name of the returned node in 'fname',
|
||||
*
|
||||
* - if 'type' is not ANY, dns_db_findext() will put the exact rdataset being
|
||||
* looked for in 'rdataset' and its signatures (if any) in 'sigrdataset',
|
||||
*
|
||||
* - if 'type' is ANY, dns_db_findext() will leave 'rdataset' and
|
||||
* 'sigrdataset' disassociated and the returned node will be iterated in
|
||||
* query_additional_cb().
|
||||
*
|
||||
* If the lookup is not successful:
|
||||
*
|
||||
* - 'nodep' will not be written to,
|
||||
* - 'fname' may still be modified as it is passed to dns_db_findext(),
|
||||
* - 'rdataset' and 'sigrdataset' will remain disassociated.
|
||||
*/
|
||||
static isc_result_t
|
||||
query_additionalauthfind(dns_db_t *db, dns_dbversion_t *version,
|
||||
const dns_name_t *name, dns_rdatatype_t type,
|
||||
ns_client_t *client, dns_dbnode_t **nodep,
|
||||
dns_name_t *fname, dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
dns_clientinfomethods_t cm;
|
||||
dns_dbnode_t *node = NULL;
|
||||
dns_clientinfo_t ci;
|
||||
isc_result_t result;
|
||||
|
||||
dns_clientinfomethods_init(&cm, ns_client_sourceip);
|
||||
dns_clientinfo_init(&ci, client, NULL);
|
||||
|
||||
/*
|
||||
* Since we are looking for authoritative data, we do not set
|
||||
* the GLUEOK flag. Glue will be looked for later, but not
|
||||
* necessarily in the same database.
|
||||
*/
|
||||
result = dns_db_findext(db, name, version, type,
|
||||
client->query.dboptions, client->now, &node,
|
||||
fname, &cm, &ci, rdataset, sigrdataset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (dns_rdataset_isassociated(rdataset)) {
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
}
|
||||
|
||||
if (sigrdataset != NULL &&
|
||||
dns_rdataset_isassociated(sigrdataset))
|
||||
{
|
||||
dns_rdataset_disassociate(sigrdataset);
|
||||
}
|
||||
|
||||
if (node != NULL) {
|
||||
dns_db_detachnode(db, &node);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not return signatures if the zone is not fully signed.
|
||||
*/
|
||||
if (sigrdataset != NULL && !dns_db_issecure(db) &&
|
||||
dns_rdataset_isassociated(sigrdataset))
|
||||
{
|
||||
dns_rdataset_disassociate(sigrdataset);
|
||||
}
|
||||
|
||||
*nodep = node;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* For query context 'qctx', try finding authoritative additional data for
|
||||
* given 'name' and 'type'. Called from query_additional_cb().
|
||||
*
|
||||
* If successful:
|
||||
*
|
||||
* - store pointers to the database and node which contain the result in
|
||||
* 'dbp' and 'nodep', respectively,
|
||||
*
|
||||
* - store the owner name of the returned node in 'fname',
|
||||
*
|
||||
* - potentially bind 'rdataset' and 'sigrdataset', as explained in the
|
||||
* comment for query_additionalauthfind().
|
||||
*
|
||||
* If unsuccessful:
|
||||
*
|
||||
* - 'dbp' and 'nodep' will not be written to,
|
||||
* - 'fname' may still be modified as it is passed to dns_db_findext(),
|
||||
* - 'rdataset' and 'sigrdataset' will remain disassociated.
|
||||
*/
|
||||
static isc_result_t
|
||||
query_additionalauth(query_ctx_t *qctx, const dns_name_t *name,
|
||||
dns_rdatatype_t type, dns_db_t **dbp,
|
||||
dns_dbnode_t **nodep, dns_name_t *fname,
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
ns_client_t *client = qctx->client;
|
||||
ns_dbversion_t *dbversion = NULL;
|
||||
dns_dbversion_t *version = NULL;
|
||||
dns_dbnode_t *node = NULL;
|
||||
dns_zone_t *zone = NULL;
|
||||
dns_db_t *db = NULL;
|
||||
isc_result_t result;
|
||||
|
||||
/*
|
||||
* First, look within the same zone database for authoritative
|
||||
* additional data.
|
||||
*/
|
||||
if (!client->query.authdbset || client->query.authdb == NULL) {
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
|
||||
dbversion = ns_client_findversion(client, client->query.authdb);
|
||||
if (dbversion == NULL) {
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
|
||||
dns_db_attach(client->query.authdb, &db);
|
||||
version = dbversion->version;
|
||||
|
||||
CTRACE(ISC_LOG_DEBUG(3), "query_additionalauth: same zone");
|
||||
|
||||
result = query_additionalauthfind(db, version, name, type, client,
|
||||
&node, fname, rdataset, sigrdataset);
|
||||
if (result != ISC_R_SUCCESS &&
|
||||
qctx->view->minimalresponses == dns_minimal_no &&
|
||||
RECURSIONOK(client))
|
||||
{
|
||||
/*
|
||||
* If we aren't doing response minimization and recursion is
|
||||
* allowed, we can try and see if any other zone matches.
|
||||
*/
|
||||
version = NULL;
|
||||
dns_db_detach(&db);
|
||||
result = query_getzonedb(client, name, type, DNS_GETDB_NOLOG,
|
||||
&zone, &db, &version);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
dns_zone_detach(&zone);
|
||||
|
||||
CTRACE(ISC_LOG_DEBUG(3), "query_additionalauth: other zone");
|
||||
|
||||
result = query_additionalauthfind(db, version, name, type,
|
||||
client, &node, fname,
|
||||
rdataset, sigrdataset);
|
||||
}
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_db_detach(&db);
|
||||
} else {
|
||||
*nodep = node;
|
||||
node = NULL;
|
||||
|
||||
*dbp = db;
|
||||
db = NULL;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
query_additional_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
|
||||
query_ctx_t *qctx = arg;
|
||||
|
|
@ -1515,58 +1684,17 @@ query_additional_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
|
|||
}
|
||||
|
||||
/*
|
||||
* Look within the same zone database for authoritative
|
||||
* additional data.
|
||||
* First, look for authoritative additional data.
|
||||
*/
|
||||
if (!client->query.authdbset || client->query.authdb == NULL) {
|
||||
goto try_cache;
|
||||
}
|
||||
|
||||
dbversion = ns_client_findversion(client, client->query.authdb);
|
||||
if (dbversion == NULL) {
|
||||
goto try_cache;
|
||||
}
|
||||
|
||||
dns_db_attach(client->query.authdb, &db);
|
||||
version = dbversion->version;
|
||||
|
||||
CTRACE(ISC_LOG_DEBUG(3), "query_additional_cb: db_find");
|
||||
|
||||
/*
|
||||
* Since we are looking for authoritative data, we do not set
|
||||
* the GLUEOK flag. Glue will be looked for later, but not
|
||||
* necessarily in the same database.
|
||||
*/
|
||||
result = dns_db_findext(db, name, version, type,
|
||||
client->query.dboptions,
|
||||
client->now, &node, fname, &cm, &ci,
|
||||
rdataset, sigrdataset);
|
||||
result = query_additionalauth(qctx, name, type, &db, &node, fname,
|
||||
rdataset, sigrdataset);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (sigrdataset != NULL && !dns_db_issecure(db) &&
|
||||
dns_rdataset_isassociated(sigrdataset))
|
||||
{
|
||||
dns_rdataset_disassociate(sigrdataset);
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
|
||||
if (dns_rdataset_isassociated(rdataset)) {
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
}
|
||||
if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) {
|
||||
dns_rdataset_disassociate(sigrdataset);
|
||||
}
|
||||
if (node != NULL) {
|
||||
dns_db_detachnode(db, &node);
|
||||
}
|
||||
version = NULL;
|
||||
dns_db_detach(&db);
|
||||
|
||||
/*
|
||||
* No authoritative data was found. The cache is our next best bet.
|
||||
*/
|
||||
|
||||
try_cache:
|
||||
if (!qctx->view->recursion) {
|
||||
goto try_glue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue