mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 13:38:26 +00:00
Check cached names for possible "forward only" clause
When caching additional and glue data *not* from a forwarder, we must check that there is no "forward only" clause covering the owner name that would take precedence. Such names would normally be allowed by baliwick rules, but a "forward only" zone introduces a new baliwick scope.
This commit is contained in:
parent
7e37b5e379
commit
c289913e5c
@ -6762,37 +6762,74 @@ mark_related(dns_name_t *name, dns_rdataset_t *rdataset, bool external,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns true if 'name' is external to the namespace for which
|
||||||
|
* the server being queried can answer, either because it's not a
|
||||||
|
* subdomain or because it's below a forward declaration.
|
||||||
|
*/
|
||||||
static inline bool
|
static inline bool
|
||||||
name_external(const dns_name_t *name, fetchctx_t *fctx) {
|
name_external(const dns_name_t *name, dns_rdatatype_t type, fetchctx_t *fctx) {
|
||||||
|
isc_result_t result;
|
||||||
|
dns_forwarders_t *forwarders = NULL;
|
||||||
|
dns_fixedname_t fixed;
|
||||||
|
dns_name_t *fname = dns_fixedname_initname(&fixed);
|
||||||
|
dns_name_t suffix;
|
||||||
|
unsigned int labels;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The name is outside the queried namespace.
|
||||||
|
*/
|
||||||
|
if (!dns_name_issubdomain(name, ISFORWARDER(fctx->addrinfo)
|
||||||
|
? fctx->fwdname
|
||||||
|
: fctx->domain))
|
||||||
|
{
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the record lives in the parent zone, adjust the name so we
|
||||||
|
* look for the correct forward clause.
|
||||||
|
*/
|
||||||
|
labels = dns_name_countlabels(name);
|
||||||
|
if (dns_rdatatype_atparent(type) && labels > 1U) {
|
||||||
|
dns_name_init(&suffix, NULL);
|
||||||
|
dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
|
||||||
|
name = &suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look for a forward declaration below 'name'.
|
||||||
|
*/
|
||||||
|
result = dns_fwdtable_find(fctx->res->view->fwdtable, name, fname,
|
||||||
|
&forwarders);
|
||||||
|
|
||||||
if (ISFORWARDER(fctx->addrinfo)) {
|
if (ISFORWARDER(fctx->addrinfo)) {
|
||||||
isc_result_t result;
|
|
||||||
dns_fixedname_t fixed;
|
|
||||||
dns_forwarders_t *forwarders = NULL;
|
|
||||||
dns_name_t *fname;
|
|
||||||
|
|
||||||
if (!dns_name_issubdomain(name, fctx->fwdname)) {
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Is there a child forwarder declaration that is better?
|
* See if the forwarder declaration is better.
|
||||||
* This lookup should always succeed if the configuration
|
|
||||||
* has not changed.
|
|
||||||
*/
|
*/
|
||||||
fname = dns_fixedname_initname(&fixed);
|
|
||||||
result = dns_fwdtable_find(fctx->res->view->fwdtable, name, fname,
|
|
||||||
&forwarders);
|
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
return (!dns_name_equal(fname, fctx->fwdname));
|
return (!dns_name_equal(fname, fctx->fwdname));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Play it safe if the configuration has changed.
|
* If the lookup failed, the configuration must have
|
||||||
|
* changed: play it safe and don't cache.
|
||||||
*/
|
*/
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (!dns_name_issubdomain(name, fctx->domain));
|
/*
|
||||||
|
* If name is covered by 'forward only' then we can't
|
||||||
|
* cache this repsonse.
|
||||||
|
*/
|
||||||
|
if (result == ISC_R_SUCCESS &&
|
||||||
|
forwarders->fwdpolicy == dns_fwdpolicy_only &&
|
||||||
|
!ISC_LIST_EMPTY(forwarders->fwdrs))
|
||||||
|
{
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
@ -6821,7 +6858,7 @@ check_section(void *arg, const dns_name_t *addname, dns_rdatatype_t type,
|
|||||||
result = dns_message_findname(rctx->query->rmessage, section, addname,
|
result = dns_message_findname(rctx->query->rmessage, section, addname,
|
||||||
dns_rdatatype_any, 0, &name, NULL);
|
dns_rdatatype_any, 0, &name, NULL);
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
external = name_external(name, fctx);
|
external = name_external(name, type, fctx);
|
||||||
if (type == dns_rdatatype_a) {
|
if (type == dns_rdatatype_a) {
|
||||||
for (rdataset = ISC_LIST_HEAD(name->list);
|
for (rdataset = ISC_LIST_HEAD(name->list);
|
||||||
rdataset != NULL;
|
rdataset != NULL;
|
||||||
@ -8491,7 +8528,7 @@ rctx_answer_scan(respctx_t *rctx) {
|
|||||||
/*
|
/*
|
||||||
* Don't accept DNAME from parent namespace.
|
* Don't accept DNAME from parent namespace.
|
||||||
*/
|
*/
|
||||||
if (name_external(name, fctx)) {
|
if (name_external(name, dns_rdatatype_dname, fctx)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8814,7 +8851,7 @@ rctx_authority_positive(respctx_t *rctx) {
|
|||||||
dns_message_currentname(rctx->query->rmessage,
|
dns_message_currentname(rctx->query->rmessage,
|
||||||
DNS_SECTION_AUTHORITY, &name);
|
DNS_SECTION_AUTHORITY, &name);
|
||||||
|
|
||||||
if (!name_external(name, fctx)) {
|
if (!name_external(name, dns_rdatatype_ns, fctx)) {
|
||||||
dns_rdataset_t *rdataset = NULL;
|
dns_rdataset_t *rdataset = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user