From 1986c6920654c8db692c2586abef393792e8fa52 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 16 Sep 2004 05:00:39 +0000 Subject: [PATCH] 1720. [bug] 'dig +chase' did not terminate on a RFC 2308 Type 1 negative response. [RT #12506] 1719. [bug] named was not correctly caching a RFC 2308 Type 1 negative response. [RT #12506] 1718. [bug] nsupdate was not handling RFC 2308 Type 3 negative responses when looking for the zone / master server. [RT #12506] --- CHANGES | 10 ++++++ bin/dig/dighost.c | 9 ++++- bin/nsupdate/nsupdate.c | 59 ++++++++++++++++---------------- lib/dns/resolver.c | 75 ++++++++++++++++++++++++++--------------- 4 files changed, 96 insertions(+), 57 deletions(-) diff --git a/CHANGES b/CHANGES index 2b162db025..57c26789bf 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,16 @@ 1721. [bug] Error message from the journal processing were not always identifing the relevent journal. [RT #12519] +1720. [bug] 'dig +chase' did not terminate on a RFC 2308 Type 1 + negative response. [RT #12506] + +1719. [bug] named was not correctly caching a RFC 2308 Type 1 + negative response. [RT #12506] + +1718. [bug] nsupdate was not handling RFC 2308 Type 3 negative + responses when looking for the zone / master server. + [RT #12506] + 1717. [port] solaris: ifconfig.sh did not support Solaris 10. "ifconfig.sh down" didn't work for Solaris 9. diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 87b774354f..21972a44f7 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.221.2.23 2004/09/16 02:19:37 marka Exp $ */ +/* $Id: dighost.c,v 1.221.2.24 2004/09/16 05:00:38 marka Exp $ */ /* * Notice to programmers: Do not use this code as an example of how to @@ -1068,6 +1068,13 @@ followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) name = NULL; dns_message_currentname(msg, section, &name); + if (section == DNS_SECTION_AUTHORITY) { + rdataset = NULL; + result = dns_message_findtype(name, dns_rdatatype_soa, + 0, &rdataset); + if (result == ISC_R_SUCCESS) + return (0); + } rdataset = NULL; result = dns_message_findtype(name, dns_rdatatype_ns, 0, &rdataset); diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index 710418d0eb..b7423a768d 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nsupdate.c,v 1.103.2.23 2004/05/12 04:46:17 marka Exp $ */ +/* $Id: nsupdate.c,v 1.103.2.24 2004/09/16 05:00:39 marka Exp $ */ #include @@ -1592,6 +1592,8 @@ recvsoa(isc_task_t *task, isc_event_t *event) { dns_message_t *soaquery = NULL; isc_sockaddr_t *addr; isc_boolean_t seencname = ISC_FALSE; + dns_name_t tname; + unsigned int nlabels; UNUSED(task); @@ -1698,9 +1700,8 @@ recvsoa(isc_task_t *task, isc_event_t *event) { section = DNS_SECTION_ANSWER; else if (pass == 1) section = DNS_SECTION_AUTHORITY; - else - fatal("response to SOA query didn't contain an SOA"); - + else + goto droplabel; result = dns_message_firstname(rcvmsg, section); if (result != ISC_R_SUCCESS) { @@ -1737,29 +1738,8 @@ recvsoa(isc_task_t *task, isc_event_t *event) { goto lookforsoa; } - if (seencname) { - dns_name_t tname; - unsigned int nlabels; - - result = dns_message_firstname(soaquery, DNS_SECTION_QUESTION); - INSIST(result == ISC_R_SUCCESS); - name = NULL; - dns_message_currentname(soaquery, DNS_SECTION_QUESTION, &name); - nlabels = dns_name_countlabels(name); - if (nlabels == 1) - fatal("could not find enclosing zone"); - dns_name_init(&tname, NULL); - dns_name_getlabelsequence(name, 1, nlabels - 1, &tname); - dns_name_clone(&tname, name); - dns_request_destroy(&request); - dns_message_renderreset(soaquery); - if (userserver != NULL) - sendrequest(localaddr, userserver, soaquery, &request); - else - sendrequest(localaddr, &servers[ns_inuse], soaquery, - &request); - goto out; - } + if (seencname) + goto droplabel; if (debugging) { char namestr[DNS_NAME_FORMATSIZE]; @@ -1802,17 +1782,38 @@ recvsoa(isc_task_t *task, isc_event_t *event) { get_address(serverstr, DNSDEFAULTPORT, &tempaddr); serveraddr = &tempaddr; } + dns_rdata_freestruct(&soa); send_update(zonename, serveraddr, localaddr); + setzoneclass(dns_rdataclass_none); dns_message_destroy(&soaquery); dns_request_destroy(&request); out: - setzoneclass(dns_rdataclass_none); - dns_rdata_freestruct(&soa); dns_message_destroy(&rcvmsg); ddebug("Out of recvsoa"); + return; + + droplabel: + result = dns_message_firstname(soaquery, DNS_SECTION_QUESTION); + INSIST(result == ISC_R_SUCCESS); + name = NULL; + dns_message_currentname(soaquery, DNS_SECTION_QUESTION, &name); + nlabels = dns_name_countlabels(name); + if (nlabels == 1) + fatal("could not find enclosing zone"); + dns_name_init(&tname, NULL); + dns_name_getlabelsequence(name, 1, nlabels - 1, &tname); + dns_name_clone(&tname, name); + dns_request_destroy(&request); + dns_message_renderreset(soaquery); + if (userserver != NULL) + sendrequest(localaddr, userserver, soaquery, &request); + else + sendrequest(localaddr, &servers[ns_inuse], soaquery, + &request); + goto out; } static void diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 2c519eb8ef..80b67fbb9e 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.218.2.34 2004/07/03 00:56:55 marka Exp $ */ +/* $Id: resolver.c,v 1.218.2.35 2004/09/16 05:00:39 marka Exp $ */ #include @@ -3577,6 +3577,9 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname) { name = NULL; dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); if (dns_name_issubdomain(name, &fctx->domain)) { + /* + * Look for NS/SOA RRset first. + */ for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { @@ -3603,17 +3606,9 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname) { rdataset->trust = dns_trust_glue; ns_rdataset = rdataset; } - } - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) { - type = rdataset->type; - if (type == dns_rdatatype_sig) - type = rdataset->covers; - if (type == dns_rdatatype_soa || - type == dns_rdatatype_nxt) { + if (type == dns_rdatatype_soa) { /* - * SOA, SIG SOA, NXT, or SIG NXT. + * SOA or SIG SOA. * * Only one SOA is allowed. */ @@ -3624,30 +3619,56 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname) { return (DNS_R_FORMERR); soa_name = name; } - if (ns_name == NULL) { - negative_response = ISC_TRUE; - name->attributes |= - DNS_NAMEATTR_NCACHE; - rdataset->attributes |= - DNS_RDATASETATTR_NCACHE; - } else { - name->attributes |= - DNS_NAMEATTR_CACHE; - rdataset->attributes |= - DNS_RDATASETATTR_CACHE; - } + name->attributes |= + DNS_NAMEATTR_NCACHE; + rdataset->attributes |= + DNS_RDATASETATTR_NCACHE; if (aa) rdataset->trust = dns_trust_authauthority; else rdataset->trust = dns_trust_additional; - /* - * No additional data needs to be - * marked. - */ } } + /* + * A negative response has a SOA record (Type 2) + * and a optional NS RRset (Type 1) or it has neither + * a SOA or a NS RRset (Type 3) or rcode is NXDOMAIN + * (handled above) in which case the NS RRset is + * allowed (Type 4). + */ + if (soa_name != NULL || ns_name == NULL) + negative_response = ISC_TRUE; + for (rdataset = ISC_LIST_HEAD(name->list); + rdataset != NULL; + rdataset = ISC_LIST_NEXT(rdataset, link)) { + type = rdataset->type; + if (type == dns_rdatatype_sig) + type = rdataset->covers; + if (type != dns_rdatatype_nxt) + continue; + /* + * NXT or SIG NXT. + */ + + if (negative_response) { + name->attributes |= + DNS_NAMEATTR_NCACHE; + rdataset->attributes |= + DNS_RDATASETATTR_NCACHE; + } else { + name->attributes |= + DNS_NAMEATTR_CACHE; + rdataset->attributes |= + DNS_RDATASETATTR_CACHE; + } + if (aa) + rdataset->trust = + dns_trust_authauthority; + else + rdataset->trust = dns_trust_additional; + } } result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); if (result == ISC_R_NOMORE)