mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
1675. [bug] named would sometimes add extra NSEC records to
the authority section.
This commit is contained in:
5
CHANGES
5
CHANGES
@@ -10,8 +10,9 @@
|
||||
|
||||
1676. [placeholder] rt10864
|
||||
|
||||
1675. [placeholder] rt10847
|
||||
|
||||
1675. [bug] named would sometimes add extra NSEC records to
|
||||
the authority section.
|
||||
|
||||
1674. [port] linux: increase buffer size used to scan
|
||||
/proc/net/if_inet6.
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: query.c,v 1.259 2004/05/14 00:10:52 marka Exp $ */
|
||||
/* $Id: query.c,v 1.260 2004/06/29 00:51:50 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -1839,13 +1839,15 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
|
||||
isc_buffer_t *dbuf, b;
|
||||
dns_name_t *fname;
|
||||
dns_rdataset_t *rdataset, *sigrdataset;
|
||||
dns_fixedname_t tfixed;
|
||||
dns_name_t *tname;
|
||||
dns_fixedname_t wfixed;
|
||||
dns_name_t *wname;
|
||||
dns_dbnode_t *node;
|
||||
unsigned int options;
|
||||
unsigned int olabels, nlabels, i;
|
||||
isc_boolean_t done;
|
||||
unsigned int options, order;
|
||||
unsigned int olabels, nlabels;
|
||||
isc_result_t result;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_nsec_t nsec;
|
||||
isc_boolean_t have_wname;
|
||||
|
||||
CTRACE("query_addwildcardproof");
|
||||
fname = NULL;
|
||||
@@ -1853,87 +1855,107 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
|
||||
sigrdataset = NULL;
|
||||
node = NULL;
|
||||
|
||||
/*
|
||||
* Get the NOQNAME proof then if !ispositve
|
||||
* get the NOWILDCARD proof.
|
||||
*
|
||||
* DNS_DBFIND_NOWILD finds the NSEC records that covers the
|
||||
* name ignoring any wildcard. From the owner and next names
|
||||
* of this record you can compute which wildcard (if it exists)
|
||||
* will match by finding the longest common suffix of the
|
||||
* owner name and next names with the qname and prefixing that
|
||||
* with the wildcard label.
|
||||
*
|
||||
* e.g.
|
||||
* Given:
|
||||
* example SOA
|
||||
* example NSEC b.example
|
||||
* b.example A
|
||||
* b.example NSEC a.d.example
|
||||
* a.d.example A
|
||||
* a.d.example NSEC g.f.example
|
||||
* g.f.example A
|
||||
* g.f.example NSEC z.i.example
|
||||
* z.i.example A
|
||||
* z.i.example NSEC example
|
||||
*
|
||||
* QNAME:
|
||||
* a.example -> example NSEC b.example
|
||||
* owner common example
|
||||
* next common example
|
||||
* wild *.example
|
||||
* d.b.example -> b.example NSEC a.d.example
|
||||
* owner common b.example
|
||||
* next common example
|
||||
* wild *.b.example
|
||||
* a.f.example -> a.d.example NSEC g.f.example
|
||||
* owner common example
|
||||
* next common f.example
|
||||
* wild *.f.example
|
||||
* j.example -> z.i.example NSEC example
|
||||
* owner common example
|
||||
* next common example
|
||||
* wild *.f.example
|
||||
*/
|
||||
options = client->query.dboptions | DNS_DBFIND_NOWILD;
|
||||
dns_fixedname_init(&wfixed);
|
||||
wname = dns_fixedname_name(&wfixed);
|
||||
again:
|
||||
have_wname = ISC_FALSE;
|
||||
/*
|
||||
* We'll need some resources...
|
||||
*/
|
||||
dbuf = query_getnamebuf(client);
|
||||
if (dbuf == NULL)
|
||||
goto cleanup;
|
||||
fname = query_newname(client, dbuf, &b);
|
||||
rdataset = query_newrdataset(client);
|
||||
sigrdataset = query_newrdataset(client);
|
||||
if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
|
||||
goto cleanup;
|
||||
|
||||
if (ispositive) {
|
||||
/*
|
||||
* We'll need some resources...
|
||||
*/
|
||||
dbuf = query_getnamebuf(client);
|
||||
if (dbuf == NULL)
|
||||
goto cleanup;
|
||||
fname = query_newname(client, dbuf, &b);
|
||||
rdataset = query_newrdataset(client);
|
||||
sigrdataset = query_newrdataset(client);
|
||||
if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
|
||||
goto cleanup;
|
||||
|
||||
result = dns_db_find(db, name, NULL,
|
||||
dns_rdatatype_nsec, options, 0, &node,
|
||||
fname, rdataset, sigrdataset);
|
||||
if (node != NULL)
|
||||
dns_db_detachnode(db, &node);
|
||||
if (result == DNS_R_NXDOMAIN)
|
||||
query_addrrset(client, &fname, &rdataset, &sigrdataset,
|
||||
dbuf, DNS_SECTION_AUTHORITY);
|
||||
if (rdataset != NULL)
|
||||
query_putrdataset(client, &rdataset);
|
||||
if (sigrdataset != NULL)
|
||||
query_putrdataset(client, &sigrdataset);
|
||||
if (fname != NULL)
|
||||
query_releasename(client, &fname);
|
||||
}
|
||||
|
||||
olabels = dns_name_countlabels(dns_db_origin(db));
|
||||
nlabels = dns_name_countlabels(name);
|
||||
done = ISC_FALSE;
|
||||
|
||||
for (i = nlabels - 1; i >= olabels && !done; i--) {
|
||||
/*
|
||||
* We'll need some resources...
|
||||
*/
|
||||
dbuf = query_getnamebuf(client);
|
||||
if (dbuf == NULL)
|
||||
goto cleanup;
|
||||
fname = query_newname(client, dbuf, &b);
|
||||
rdataset = query_newrdataset(client);
|
||||
sigrdataset = query_newrdataset(client);
|
||||
if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
|
||||
goto cleanup;
|
||||
|
||||
dns_fixedname_init(&tfixed);
|
||||
tname = dns_fixedname_name(&tfixed);
|
||||
dns_name_split(name, i, NULL, tname);
|
||||
result = dns_name_concatenate(dns_wildcardname, tname, tname,
|
||||
NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
continue;
|
||||
|
||||
result = dns_db_find(db, tname, NULL, dns_rdatatype_nsec,
|
||||
client->query.dboptions, 0, &node,
|
||||
fname, rdataset, sigrdataset);
|
||||
if (node != NULL)
|
||||
dns_db_detachnode(db, &node);
|
||||
/*
|
||||
* If this returns success, we've found the wildcard for a
|
||||
* successful answer, so we're done.
|
||||
*/
|
||||
if (result == ISC_R_SUCCESS && ispositive)
|
||||
break;
|
||||
if (result == DNS_R_NXDOMAIN || result == DNS_R_EMPTYNAME) {
|
||||
if (!ispositive &&
|
||||
dns_name_issubdomain(name, fname))
|
||||
done = ISC_TRUE;
|
||||
query_addrrset(client, &fname, &rdataset, &sigrdataset,
|
||||
dbuf, DNS_SECTION_AUTHORITY);
|
||||
result = dns_db_find(db, name, NULL, dns_rdatatype_nsec, options,
|
||||
0, &node, fname, rdataset, sigrdataset);
|
||||
if (node != NULL)
|
||||
dns_db_detachnode(db, &node);
|
||||
if (result == DNS_R_NXDOMAIN) {
|
||||
if (!ispositive)
|
||||
result = dns_rdataset_first(rdataset);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
dns_rdataset_current(rdataset, &rdata);
|
||||
result = dns_rdata_tostruct(&rdata, &nsec, NULL);
|
||||
}
|
||||
if (rdataset != NULL)
|
||||
query_putrdataset(client, &rdataset);
|
||||
if (sigrdataset != NULL)
|
||||
query_putrdataset(client, &sigrdataset);
|
||||
if (fname != NULL)
|
||||
query_releasename(client, &fname);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
(void)dns_name_fullcompare(name, fname, &order,
|
||||
&olabels);
|
||||
(void)dns_name_fullcompare(name, &nsec.next, &order,
|
||||
&nlabels);
|
||||
if (olabels > nlabels)
|
||||
dns_name_split(name, olabels, NULL, wname);
|
||||
else
|
||||
dns_name_split(name, nlabels, NULL, wname);
|
||||
result = dns_name_concatenate(dns_wildcardname,
|
||||
wname, wname, NULL);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
have_wname = ISC_TRUE;
|
||||
dns_rdata_freestruct(&nsec);
|
||||
}
|
||||
query_addrrset(client, &fname, &rdataset, &sigrdataset,
|
||||
dbuf, DNS_SECTION_AUTHORITY);
|
||||
}
|
||||
if (rdataset != NULL)
|
||||
query_putrdataset(client, &rdataset);
|
||||
if (sigrdataset != NULL)
|
||||
query_putrdataset(client, &sigrdataset);
|
||||
if (fname != NULL)
|
||||
query_releasename(client, &fname);
|
||||
if (have_wname) {
|
||||
ispositive = ISC_TRUE; /* prevent loop */
|
||||
if (!dns_name_equal(name, wname)) {
|
||||
name = wname;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
cleanup:
|
||||
if (rdataset != NULL)
|
||||
query_putrdataset(client, &rdataset);
|
||||
|
Reference in New Issue
Block a user