]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] DLZ fixes
authorEvan Hunt <each@isc.org>
Tue, 22 Jan 2013 23:13:08 +0000 (15:13 -0800)
committerEvan Hunt <each@isc.org>
Tue, 22 Jan 2013 23:13:08 +0000 (15:13 -0800)
 - handle malformed answers from DLZ better:
 - handle dlz_lookup errors better:
   when the first lookup of a name returns an unexpected failure code,
   we return it to the caller rather than continuing on to look up
   the wildcard. we now only continue processing if the return from
   the first lookup was either ISC_R_SUCCESS or ISC_R_NOTFOUND.

 - improved backward-compatibility for dlz_version:
   added a DLZ_DLOPEN_AGE value indicating how many versions
   back from the current DLZ_DLOPEN_VERSION named will support

bin/named/unix/dlz_dlopen_driver.c
bin/named/win32/dlz_dlopen_driver.c
bin/tests/system/dlzexternal/driver.c
bin/tests/system/dlzexternal/tests.sh
contrib/dlz/example/dlz_example.c
contrib/dlz/example/dlz_minimal.h
lib/dns/include/dns/dlz_dlopen.h
lib/dns/sdlz.c

index fc5ab8669f62405653790686069427d828aa8d96..552f69833242b8656c9f352cf3fb86c299d69385 100644 (file)
@@ -326,11 +326,13 @@ dlopen_dlz_create(const char *dlzname, unsigned int argc, char *argv[],
 
        /* Check the version of the API is the same */
        cd->version = cd->dlz_version(&cd->flags);
-       if (cd->version != DLZ_DLOPEN_VERSION) {
+       if (cd->version < (DLZ_DLOPEN_VERSION - DLZ_DLOPEN_AGE) ||
+           cd->version > DLZ_DLOPEN_VERSION)
+       {
                dlopen_log(ISC_LOG_ERROR,
-                          "dlz_dlopen: incorrect version %d "
-                          "should be %d in '%s'",
-                          cd->version, DLZ_DLOPEN_VERSION, cd->dl_path);
+                          "dlz_dlopen: %s: incorrect driver API version %d, "
+                          "requires %d",
+                          cd->dl_path, cd->version, DLZ_DLOPEN_VERSION);
                goto failed;
        }
 
index 6c9ecb811665ca06f508ce0354a93c33969f5de9..a73c65f5747bc8a754a57c6a8c495e663265dbfe 100644 (file)
@@ -310,11 +310,13 @@ dlopen_dlz_create(const char *dlzname, unsigned int argc, char *argv[],
 
        /* Check the version of the API is the same */
        cd->version = cd->dlz_version(&cd->flags);
-       if (cd->version != DLZ_DLOPEN_VERSION) {
+       if (cd->version < (DLZ_DLOPEN_VERSION - DLZ_DLOPEN_AGE) ||
+           cd->version > DLZ_DLOPEN_VERSION)
+       {
                dlopen_log(ISC_LOG_ERROR,
-                          "dlz_dlopen: incorrect version %d "
-                          "should be %d in '%s'",
-                          cd->version, DLZ_DLOPEN_VERSION, cd->dl_path);
+                          "dlz_dlopen: %s: incorrect driver API version %d, "
+                          "requires %d",
+                          cd->dl_path, cd->version, DLZ_DLOPEN_VERSION);
                goto failed;
        }
 
index ee208d8c76bf06cc5e8e4f33e18bededd75f2695..765f32fad111d4223e6a4b45082a2237c5693fa8 100644 (file)
@@ -368,8 +368,11 @@ dlz_findzonedb(void *dbdata, const char *name,
 /*
  * Look up one record in the sample database.
  *
- * If the queryname is "source-addr", we add a TXT record containing
+ * If the queryname is "source-addr", send back a TXT record containing
  * the address of the client, to test the use of 'methods' and 'clientinfo'
+ *
+ * If the queryname is "too-long", send back a TXT record that's too long
+ * to process; this should result in a SERVFAIL when queried.
  */
 isc_result_t
 dlz_lookup(const char *zone, const char *name, void *dbdata,
@@ -381,6 +384,7 @@ dlz_lookup(const char *zone, const char *name, void *dbdata,
        isc_boolean_t found = ISC_FALSE;
        isc_sockaddr_t *src;
        char full_name[256];
+       char buf[512];
        int i;
 
        UNUSED(zone);
@@ -395,7 +399,6 @@ dlz_lookup(const char *zone, const char *name, void *dbdata,
                snprintf(full_name, 255, "%s.%s", name, state->zone_name);
 
        if (strcmp(name, "source-addr") == 0) {
-               char buf[100];
                strcpy(buf, "unknown");
                if (methods != NULL &&
                    methods->sourceip != NULL &&
@@ -415,6 +418,16 @@ dlz_lookup(const char *zone, const char *name, void *dbdata,
                        return (result);
        }
 
+       if (strcmp(name, "too-long") == 0) {
+               for (i = 0; i < 511; i++)
+                       buf[i] = 'x';
+               buf[i] = '\0';
+               found = ISC_TRUE;
+               result = state->putrr(lookup, "TXT", 0, buf);
+               if (result != ISC_R_SUCCESS)
+                       return (result);
+       }
+
        for (i = 0; i < MAX_RECORDS; i++) {
                if (strcasecmp(state->current[i].name, full_name) == 0) {
                        found = ISC_TRUE;
index 34311128eb527a976929e06c9c93d422ab9554db..c8beb537ffc084df727ef986baf3b8738d0cca96 100644 (file)
@@ -136,4 +136,11 @@ lines=`grep "dlz_findzonedb.*example\.net.*alternate.nil" ns1/named.run | wc -l`
 [ "$ret" -eq 0 ] || echo "I:failed"
 status=`expr $status + $ret`
 
+ret=0
+echo "I:testing zone returning oversized data"
+$DIG $DIGOPTS txt too-long.example.nil > dig.out.ns1.6 2>&1 || ret=1
+grep "status: SERVFAIL" dig.out.ns1.6 > /dev/null || ret=1
+[ "$ret" -eq 0 ] || echo "I:failed"
+status=`expr $status + $ret`
+
 exit $status
index 0212f884f3b84cf619185e813b5ef019c1db9886..0f381ba5c956190168df4afd0d7ce5970026e4ba 100644 (file)
@@ -357,9 +357,12 @@ dlz_findzonedb(void *dbdata, const char *name,
 /*
  * Look up one record in the sample database.
  *
- * If the queryname is "source-addr", we add a TXT record containing
+ * If the queryname is "source-addr", send back a TXT record containing
  * the address of the client; this demonstrates the use of 'methods'
  * and 'clientinfo'.
+ *
+ * If the queryname is "too-long", send back a TXT record that's too long
+ * to process; this should result in a SERVFAIL when queried.
  */
 isc_result_t
 dlz_lookup(const char *zone, const char *name, void *dbdata,
@@ -371,6 +374,7 @@ dlz_lookup(const char *zone, const char *name, void *dbdata,
        isc_boolean_t found = ISC_FALSE;
        isc_sockaddr_t *src;
        char full_name[256];
+       char buf[512];
        int i;
 
        UNUSED(zone);
@@ -385,7 +389,6 @@ dlz_lookup(const char *zone, const char *name, void *dbdata,
                snprintf(full_name, 255, "%s.%s", name, state->zone_name);
 
        if (strcmp(name, "source-addr") == 0) {
-               char buf[100];
                strcpy(buf, "unknown");
                if (methods != NULL &&
                    methods->sourceip != NULL &&
@@ -406,6 +409,16 @@ dlz_lookup(const char *zone, const char *name, void *dbdata,
                        return (result);
        }
 
+       if (strcmp(name, "too-long") == 0) {
+               for (i = 0; i < 511; i++)
+                       buf[i] = 'x';
+               buf[i] = '\0';
+               found = ISC_TRUE;
+               result = state->putrr(lookup, "TXT", 0, buf);
+               if (result != ISC_R_SUCCESS)
+                       return (result);
+       }
+
        for (i = 0; i < MAX_RECORDS; i++) {
                if (strcasecmp(state->current[i].name, full_name) == 0) {
                        found = ISC_TRUE;
index 3972094ad811e99b3ffa67e465d3f9dc0687ca35..50eb99eff5589e0c9678bb371b6f9b83f669ad0b 100644 (file)
@@ -37,6 +37,7 @@ typedef int isc_boolean_t;
 typedef uint32_t dns_ttl_t;
 
 #define DLZ_DLOPEN_VERSION 3
+#define DLZ_DLOPEN_AGE 0
 
 /* return this in flags to dlz_version() if thread safe */
 #define DNS_SDLZFLAG_THREADSAFE                0x00000001U
index 6d47b2b7ff0d4cda0c4daaa8b8f520dff8224ef3..738b5e921a8b3409dca66f5caa632e9738d3ca8d 100644 (file)
@@ -31,6 +31,7 @@ ISC_LANG_BEGINDECLS
  */
 
 #define DLZ_DLOPEN_VERSION 3
+#define DLZ_DLOPEN_AGE 0
 
 /*
  * dlz_dlopen_version() is required for all DLZ external drivers. It
index 7ff4ee72640108dd8d38abfd32f1f4878dce1e38..db129d062e05bc6fec273a03f9bab18ffca121ff 100644 (file)
@@ -605,7 +605,7 @@ findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
         * if the host (namestr) was not found, try to lookup a
         * "wildcard" host.
         */
-       if (result != ISC_R_SUCCESS && !create)
+       if (result == ISC_R_NOTFOUND && !create)
                result = sdlz->dlzimp->methods->lookup(zonestr, "*",
                                                       sdlz->dlzimp->driverarg,
                                                       sdlz->dbdata, node,
@@ -878,10 +878,11 @@ findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
                dns_name_getlabelsequence(name, nlabels - i, i, xname);
                result = findnodeext(db, xname, ISC_FALSE,
                                     methods, clientinfo, &node);
-               if (result != ISC_R_SUCCESS) {
+               if (result == ISC_R_NOTFOUND) {
                        result = DNS_R_NXDOMAIN;
                        continue;
-               }
+               } else if (result != ISC_R_SUCCESS)
+                       break;
 
                /*
                 * Look for a DNAME at the current label, unless this is