]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] handle ISC_R_NOMORE correctly
authorEvan Hunt <each@isc.org>
Thu, 6 Dec 2012 20:41:58 +0000 (12:41 -0800)
committerEvan Hunt <each@isc.org>
Thu, 6 Dec 2012 20:41:58 +0000 (12:41 -0800)
3433. [bug] dlz_findzone() did not correctly handle
ISC_R_NOMORE. [RT #31172]

CHANGES
bin/tests/system/dlzexternal/driver.c
bin/tests/system/dlzexternal/tests.sh
lib/dns/dlz.c

diff --git a/CHANGES b/CHANGES
index 67cf262c4afb440a14e173c8ba64da648f939b97..0a88c20f1fd2d04c98d8fdae5b9f340a1f032748 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+3433.  [bug]           dlz_findzone() did not correctly handle
+                       ISC_R_NOMORE. [RT #31172]
+
 3432.  [func]          Multiple DLZ databases can now be configured.
                        DLZ databases are searched in the order configured,
                        unless set to "search no", in which case a
index 1faf07f149b34325bf1fe8895aaa32cc67be611e..cdda7c406e280b91f93d6b57f7b87ac8fbd9555e 100644 (file)
@@ -321,6 +321,20 @@ isc_result_t
 dlz_findzonedb(void *dbdata, const char *name) {
        struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
 
+       state->log(ISC_LOG_INFO,
+                  "dlz_example: dlz_findzonedb called with name '%s'"
+                  "in zone DB '%s'", name, state->zone_name);
+
+       /*
+        * Returning ISC_R_NOTFOUND will cause the query logic to
+        * check the database for parent names, looking for zone cuts.
+        *
+        * Returning ISC_R_NOMORE prevents the query logic from doing
+        * this; it will move onto the next database after a single query.
+        */
+       if (strcasecmp(name, "test.example.com") == 0)
+               return (ISC_R_NOMORE);
+
        if (strcasecmp(state->zone_name, name) == 0)
                return (ISC_R_SUCCESS);
 
index 04d9196ddc85585e71b6c98e73204962884094ed..38327d4dab205c53c1ce2bafa410bcd8d88827e0 100644 (file)
@@ -101,4 +101,22 @@ grep "3600.IN.NS.zone.nil." dig.out.ns1.4 > /dev/null || ret=1
 [ "$ret" -eq 0 ] || echo "I:failed"
 status=`expr $status + $ret`
 
+ret=0
+echo "I:testing unsearched/registered DLZ zone is found"
+$DIG $DIGOPTS +noall +answer ns zone.nil > dig.out.ns1.5
+grep "3600.IN.NS.zone.nil." dig.out.ns1.5 > /dev/null || ret=1
+[ "$ret" -eq 0 ] || echo "I:failed"
+status=`expr $status + $ret`
+
+ret=0
+echo "I:testing correct behavior with findzone returning ISC_R_NOMORE"
+$DIG $DIGOPTS +noall a test.example.com > /dev/null 2>&1 || ret=1
+# we should only find one logged lookup per searched DLZ database
+lines=`grep "dlz_findzonedb.*example\.com.*example.nil" ns1/named.run | wc -l`
+[ $lines -eq 1 ] || ret=1
+lines=`grep "dlz_findzonedb.*example\.com.*alternate.nil" ns1/named.run | wc -l`
+[ $lines -eq 1 ] || ret=1
+[ "$ret" -eq 0 ] || echo "I:failed"
+status=`expr $status + $ret`
+
 exit $status
index 482f484a1a9b6411965a8b279277432fc7e99e8f..f8066baac6e05417b4d6a7ac065e6039b4926b6e 100644 (file)
@@ -335,9 +335,16 @@ dns_dlzfindzone(dns_view_t *view, dns_name_t *name,
                        if (result != ISC_R_NOTFOUND) {
                                if (best != NULL)
                                        dns_db_detach(&best);
-                               dns_db_attach(db, &best);
-                               dns_db_detach(&db);
-                               minlabels = i;
+                               if (result == ISC_R_SUCCESS) {
+                                       INSIST(db != NULL);
+                                       dns_db_attach(db, &best);
+                                       dns_db_detach(&db);
+                                       minlabels = i;
+                               } else {
+                                       if (db != NULL)
+                                               dns_db_detach(&db);
+                                       break;
+                               }
                        } else if (db != NULL)
                                dns_db_detach(&db);
                }