From f5695ad0e1a6cc8e19bfec7b71476e138de6cb6c Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 21 Aug 2014 18:05:55 +1000 Subject: [PATCH] 3917. [bug] dig, nslookup and host now continue on names that are too long after applying a search list elements. [RT #36892] --- CHANGES | 4 ++ bin/dig/dighost.c | 81 +++++++++++++++--------- bin/dig/include/dig/dig.h | 2 +- bin/tests/system/conf.sh.in | 7 +- bin/tests/system/nslookup/clean.sh | 2 + bin/tests/system/nslookup/ns1/named.conf | 33 ++++++++++ bin/tests/system/nslookup/setup.sh | 20 ++++++ bin/tests/system/nslookup/tests.sh | 36 +++++++++++ 8 files changed, 152 insertions(+), 33 deletions(-) create mode 100644 bin/tests/system/nslookup/clean.sh create mode 100644 bin/tests/system/nslookup/ns1/named.conf create mode 100644 bin/tests/system/nslookup/setup.sh create mode 100644 bin/tests/system/nslookup/tests.sh diff --git a/CHANGES b/CHANGES index b4ad105701..141ca61443 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +3917. [bug] dig, nslookup and host now continue on names that are + too long after applying a search list elements. + [RT #36892] + 3916. [contrib] zone2sqlite checked wrong result code. Address compiler warnings. [RT #36931] diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 85ca6e4158..1a0202b9d6 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -369,6 +369,11 @@ connect_timeout(isc_task_t *task, isc_event_t *event); static void launch_next_query(dig_query_t *query, isc_boolean_t include_question); +static void +check_next_lookup(dig_lookup_t *lookup); + +static isc_boolean_t +next_origin(dig_lookup_t *oldlookup); static void * mem_alloc(void *arg, size_t size) { @@ -1819,8 +1824,10 @@ start_lookup(void) { } novalidation: #endif - setup_lookup(current_lookup); - do_lookup(current_lookup); + if (setup_lookup(current_lookup)) + do_lookup(current_lookup); + else if (next_origin(current_lookup)) + check_next_lookup(current_lookup); } else { check_if_done(); } @@ -2021,8 +2028,8 @@ followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) * Return ISC_TRUE iff there was another searchlist entry. */ static isc_boolean_t -next_origin(dig_query_t *query) { - dig_lookup_t *lookup; +next_origin(dig_lookup_t *oldlookup) { + dig_lookup_t *newlookup; dig_searchlist_t *search; dns_fixedname_t fixed; dns_name_t *name; @@ -2031,7 +2038,7 @@ next_origin(dig_query_t *query) { INSIST(!free_now); debug("next_origin()"); - debug("following up %s", query->lookup->textname); + debug("following up %s", oldlookup->textname); if (!usesearch) /* @@ -2045,30 +2052,30 @@ next_origin(dig_query_t *query) { */ dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); - result = dns_name_fromstring2(name, query->lookup->textname, NULL, + result = dns_name_fromstring2(name, oldlookup->textname, NULL, 0, NULL); if (result == ISC_R_SUCCESS && (dns_name_isabsolute(name) || (int)dns_name_countlabels(name) > ndots)) return (ISC_FALSE); - if (query->lookup->origin == NULL && !query->lookup->need_search) + if (oldlookup->origin == NULL && !oldlookup->need_search) /* * Then we just did rootorg; there's nothing left. */ return (ISC_FALSE); - if (query->lookup->origin == NULL && query->lookup->need_search) { - lookup = requeue_lookup(query->lookup, ISC_TRUE); - lookup->origin = ISC_LIST_HEAD(search_list); - lookup->need_search = ISC_FALSE; + if (oldlookup->origin == NULL && oldlookup->need_search) { + newlookup = requeue_lookup(oldlookup, ISC_TRUE); + newlookup->origin = ISC_LIST_HEAD(search_list); + newlookup->need_search = ISC_FALSE; } else { - search = ISC_LIST_NEXT(query->lookup->origin, link); - if (search == NULL && query->lookup->done_as_is) + search = ISC_LIST_NEXT(oldlookup->origin, link); + if (search == NULL && oldlookup->done_as_is) return (ISC_FALSE); - lookup = requeue_lookup(query->lookup, ISC_TRUE); - lookup->origin = search; + newlookup = requeue_lookup(oldlookup, ISC_TRUE); + newlookup->origin = search; } - cancel_lookup(query->lookup); + cancel_lookup(oldlookup); return (ISC_TRUE); } @@ -2153,7 +2160,7 @@ compute_cookie(unsigned char *cookie, size_t len) { * well as the query structures and buffer space for the replies. If the * server list is empty, clone it from the system default list. */ -void +isc_boolean_t setup_lookup(dig_lookup_t *lookup) { isc_result_t result; isc_uint32_t id; @@ -2283,20 +2290,35 @@ setup_lookup(dig_lookup_t *lookup) { if (lookup->trace && lookup->trace_root) { dns_name_clone(dns_rootname, lookup->name); } else { + dns_fixedname_t fixed; + dns_name_t *name; + + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); len = strlen(lookup->textname); isc_buffer_init(&b, lookup->textname, len); isc_buffer_add(&b, len); - result = dns_name_fromtext(lookup->name, &b, - lookup->oname, 0, - &lookup->namebuf); - } - if (result != ISC_R_SUCCESS) { - dns_message_puttempname(lookup->sendmsg, - &lookup->name); - dns_message_puttempname(lookup->sendmsg, - &lookup->oname); - fatal("'%s' is not in legal name syntax (%s)", - lookup->textname, isc_result_totext(result)); + result = dns_name_fromtext(name, &b, NULL, 0, NULL); + if (result == ISC_R_SUCCESS && + !dns_name_isabsolute(name)) + result = dns_name_concatenate(name, + lookup->oname, + lookup->name, + &lookup->namebuf); + else if (result == ISC_R_SUCCESS) + result = dns_name_copy(name, lookup->name, + &lookup->namebuf); + if (result != ISC_R_SUCCESS) { + dns_message_puttempname(lookup->sendmsg, + &lookup->name); + dns_message_puttempname(lookup->sendmsg, + &lookup->oname); + if (result == DNS_R_NAMETOOLONG) + return (ISC_FALSE); + fatal("'%s' is not in legal name syntax (%s)", + lookup->textname, + isc_result_totext(result)); + } } dns_message_puttempname(lookup->sendmsg, &lookup->oname); } else @@ -2591,6 +2613,7 @@ setup_lookup(dig_lookup_t *lookup) { printf(";; QUERY SIZE: %u\n\n", isc_buffer_usedlength(&lookup->renderbuf)); } + return (ISC_TRUE); } /*% @@ -3794,7 +3817,7 @@ recv_done(isc_task_t *task, isc_event_t *event) { if (!l->doing_xfr || l->xfr_q == query) { if (msg->rcode == dns_rcode_nxdomain && (l->origin != NULL || l->need_search)) { - if (!next_origin(query) || showsearch) { + if (!next_origin(query->lookup) || showsearch) { printmessage(query, msg, ISC_TRUE); received(b->used, &sevent->address, query); } diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h index 8c2c9dbea5..ba99428bf5 100644 --- a/bin/dig/include/dig/dig.h +++ b/bin/dig/include/dig/dig.h @@ -323,7 +323,7 @@ debug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); void check_result(isc_result_t result, const char *msg); -void +isc_boolean_t setup_lookup(dig_lookup_t *lookup); void diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in index a0c6f8826b..37786696a0 100644 --- a/bin/tests/system/conf.sh.in +++ b/bin/tests/system/conf.sh.in @@ -57,6 +57,7 @@ ARPANAME=$TOP/bin/tools/arpaname RESOLVE=$TOP/lib/samples/resolve RRCHECKER=$TOP/bin/tools/named-rrchecker GENRANDOM=$TOP/bin/tools/genrandom +NSLOOKUP=$TOP/bin/dig/nslookup RANDFILE=$TOP/bin/tests/system/random.data @@ -68,8 +69,8 @@ SUBDIRS="acl additional allow_query addzone autosign builtin @COVERAGE@ database dlv dlvauto dlz dlzexternal dname dns64 dnssec dsdigest dscp ecdsa emptyzones filter-aaaa formerr forward geoip glue gost ixfr inline limits logfileconfig - lwresd masterfile masterformat metadata notify nsupdate pending - @PKCS11_TEST@ redirect resolver rndc rpz rrl rrchecker + lwresd masterfile masterformat metadata notify nslookup nsupdate + pending @PKCS11_TEST@ redirect resolver rndc rpz rrl rrchecker rrsetorder rsabigexponent sit smartsign sortlist spf staticstub statistics stub tkey tsig tsiggss unknown upforwd verify views wildcard xfer xferquota zero zonechecks" @@ -93,4 +94,4 @@ fi export NAMED LWRESD DIG NSUPDATE KEYGEN KEYFRLAB SIGNER KEYSIGNER KEYSETTOOL \ PERL SUBDIRS RNDC CHECKZONE PK11GEN PK11LIST PK11DEL TESTSOCK6 \ - JOURNALPRINT ARPANAME RESOLVE RRCHECKER + JOURNALPRINT ARPANAME RESOLVE RRCHECKER NSLOOKUP diff --git a/bin/tests/system/nslookup/clean.sh b/bin/tests/system/nslookup/clean.sh new file mode 100644 index 0000000000..c43d9b86c8 --- /dev/null +++ b/bin/tests/system/nslookup/clean.sh @@ -0,0 +1,2 @@ +rm -f ns1/example.db +rm -f nslookup.out* diff --git a/bin/tests/system/nslookup/ns1/named.conf b/bin/tests/system/nslookup/ns1/named.conf new file mode 100644 index 0000000000..fc1fb510ff --- /dev/null +++ b/bin/tests/system/nslookup/ns1/named.conf @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +controls { /* empty */ }; + +options { + query-source address 10.53.0.1; + notify-source 10.53.0.1; + transfer-source 10.53.0.1; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.1; }; + listen-on-v6 { none; }; + recursion no; +}; + +zone "example" { + type master; + file "example.db"; +}; diff --git a/bin/tests/system/nslookup/setup.sh b/bin/tests/system/nslookup/setup.sh new file mode 100644 index 0000000000..092e5800c8 --- /dev/null +++ b/bin/tests/system/nslookup/setup.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# +# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +SYSTEMTESTTOP=.. +. $SYSTEMTESTTOP/conf.sh + +$SHELL ../genzone.sh 1 >ns1/example.db diff --git a/bin/tests/system/nslookup/tests.sh b/bin/tests/system/nslookup/tests.sh new file mode 100644 index 0000000000..d77afd9fec --- /dev/null +++ b/bin/tests/system/nslookup/tests.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# +# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +SYSTEMTESTTOP=.. +. $SYSTEMTESTTOP/conf.sh + +status=0 +n=0 + +n=`expr $n + 1` +echo "Check that domain names that are too big when applying a search list entry are handled cleanly ($n)" +ret=0 +l=012345678901234567890123456789012345678901234567890123456789012 +t=0123456789012345678901234567890123456789012345678901234567890 +d=$l.$l.$l.$t +$NSLOOKUP -port=5300 -domain=$d -type=soa example 10.53.0.1 > nslookup.out${n} || ret=1 +grep "origin = ns1.example" nslookup.out${n} > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:exit status: $status" +exit $status +