2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-02 15:45:25 +00:00

[master] DLZ fixes

- 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
This commit is contained in:
Evan Hunt
2013-01-22 15:13:08 -08:00
parent 0a8a14d513
commit cbd1fa092e
8 changed files with 55 additions and 15 deletions

View 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 */ /* Check the version of the API is the same */
cd->version = cd->dlz_version(&cd->flags); 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, dlopen_log(ISC_LOG_ERROR,
"dlz_dlopen: incorrect version %d " "dlz_dlopen: %s: incorrect driver API version %d, "
"should be %d in '%s'", "requires %d",
cd->version, DLZ_DLOPEN_VERSION, cd->dl_path); cd->dl_path, cd->version, DLZ_DLOPEN_VERSION);
goto failed; goto failed;
} }

View 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 */ /* Check the version of the API is the same */
cd->version = cd->dlz_version(&cd->flags); 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, dlopen_log(ISC_LOG_ERROR,
"dlz_dlopen: incorrect version %d " "dlz_dlopen: %s: incorrect driver API version %d, "
"should be %d in '%s'", "requires %d",
cd->version, DLZ_DLOPEN_VERSION, cd->dl_path); cd->dl_path, cd->version, DLZ_DLOPEN_VERSION);
goto failed; goto failed;
} }

View File

@@ -368,8 +368,11 @@ dlz_findzonedb(void *dbdata, const char *name,
/* /*
* Look up one record in the sample database. * 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' * 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 isc_result_t
dlz_lookup(const char *zone, const char *name, void *dbdata, 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_boolean_t found = ISC_FALSE;
isc_sockaddr_t *src; isc_sockaddr_t *src;
char full_name[256]; char full_name[256];
char buf[512];
int i; int i;
UNUSED(zone); 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); snprintf(full_name, 255, "%s.%s", name, state->zone_name);
if (strcmp(name, "source-addr") == 0) { if (strcmp(name, "source-addr") == 0) {
char buf[100];
strcpy(buf, "unknown"); strcpy(buf, "unknown");
if (methods != NULL && if (methods != NULL &&
methods->sourceip != NULL && methods->sourceip != NULL &&
@@ -415,6 +418,16 @@ dlz_lookup(const char *zone, const char *name, void *dbdata,
return (result); 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++) { for (i = 0; i < MAX_RECORDS; i++) {
if (strcasecmp(state->current[i].name, full_name) == 0) { if (strcasecmp(state->current[i].name, full_name) == 0) {
found = ISC_TRUE; found = ISC_TRUE;

View File

@@ -136,4 +136,11 @@ lines=`grep "dlz_findzonedb.*example\.net.*alternate.nil" ns1/named.run | wc -l`
[ "$ret" -eq 0 ] || echo "I:failed" [ "$ret" -eq 0 ] || echo "I:failed"
status=`expr $status + $ret` 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 exit $status

View File

@@ -357,9 +357,12 @@ dlz_findzonedb(void *dbdata, const char *name,
/* /*
* Look up one record in the sample database. * 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' * the address of the client; this demonstrates the use of 'methods'
* and 'clientinfo'. * 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 isc_result_t
dlz_lookup(const char *zone, const char *name, void *dbdata, 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_boolean_t found = ISC_FALSE;
isc_sockaddr_t *src; isc_sockaddr_t *src;
char full_name[256]; char full_name[256];
char buf[512];
int i; int i;
UNUSED(zone); 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); snprintf(full_name, 255, "%s.%s", name, state->zone_name);
if (strcmp(name, "source-addr") == 0) { if (strcmp(name, "source-addr") == 0) {
char buf[100];
strcpy(buf, "unknown"); strcpy(buf, "unknown");
if (methods != NULL && if (methods != NULL &&
methods->sourceip != NULL && methods->sourceip != NULL &&
@@ -406,6 +409,16 @@ dlz_lookup(const char *zone, const char *name, void *dbdata,
return (result); 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++) { for (i = 0; i < MAX_RECORDS; i++) {
if (strcasecmp(state->current[i].name, full_name) == 0) { if (strcasecmp(state->current[i].name, full_name) == 0) {
found = ISC_TRUE; found = ISC_TRUE;

View File

@@ -37,6 +37,7 @@ typedef int isc_boolean_t;
typedef uint32_t dns_ttl_t; typedef uint32_t dns_ttl_t;
#define DLZ_DLOPEN_VERSION 3 #define DLZ_DLOPEN_VERSION 3
#define DLZ_DLOPEN_AGE 0
/* return this in flags to dlz_version() if thread safe */ /* return this in flags to dlz_version() if thread safe */
#define DNS_SDLZFLAG_THREADSAFE 0x00000001U #define DNS_SDLZFLAG_THREADSAFE 0x00000001U

View File

@@ -31,6 +31,7 @@ ISC_LANG_BEGINDECLS
*/ */
#define DLZ_DLOPEN_VERSION 3 #define DLZ_DLOPEN_VERSION 3
#define DLZ_DLOPEN_AGE 0
/* /*
* dlz_dlopen_version() is required for all DLZ external drivers. It * dlz_dlopen_version() is required for all DLZ external drivers. It

View 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 * if the host (namestr) was not found, try to lookup a
* "wildcard" host. * "wildcard" host.
*/ */
if (result != ISC_R_SUCCESS && !create) if (result == ISC_R_NOTFOUND && !create)
result = sdlz->dlzimp->methods->lookup(zonestr, "*", result = sdlz->dlzimp->methods->lookup(zonestr, "*",
sdlz->dlzimp->driverarg, sdlz->dlzimp->driverarg,
sdlz->dbdata, node, 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); dns_name_getlabelsequence(name, nlabels - i, i, xname);
result = findnodeext(db, xname, ISC_FALSE, result = findnodeext(db, xname, ISC_FALSE,
methods, clientinfo, &node); methods, clientinfo, &node);
if (result != ISC_R_SUCCESS) { if (result == ISC_R_NOTFOUND) {
result = DNS_R_NXDOMAIN; result = DNS_R_NXDOMAIN;
continue; continue;
} } else if (result != ISC_R_SUCCESS)
break;
/* /*
* Look for a DNAME at the current label, unless this is * Look for a DNAME at the current label, unless this is