From af850c4120c5bee9462de4def85d0b4c1b583963 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 12 Oct 2011 23:09:35 +0000 Subject: [PATCH] 3168. [bug] Nxdomain redirection could trigger a assert with a ANY query. [RT #26017] --- CHANGES | 3 + bin/named/query.c | 29 +- lib/dns/rbtdb.c | 32 +- lib/dns/tests/Makefile.in | 10 +- lib/dns/tests/dbversion_test.c | 738 +++++++++++++++++++++++++++++++++ lib/dns/tests/update_test.c | 4 +- 6 files changed, 797 insertions(+), 19 deletions(-) create mode 100644 lib/dns/tests/dbversion_test.c diff --git a/CHANGES b/CHANGES index cdf72adaf9..6bf46bfd5c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3168. [bug] Nxdomain redirection could trigger a assert with + a ANY query. [RT #26017] + 3167. [bug] Negative answers from forwarders were not being correctly tagged making them appear to not be cached. [RT #25380] diff --git a/bin/named/query.c b/bin/named/query.c index b52f9cb271..b6d79048fb 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: query.c,v 1.371 2011/10/11 23:46:44 tbox Exp $ */ +/* $Id: query.c,v 1.372 2011/10/12 23:09:35 marka Exp $ */ /*! \file */ @@ -5005,7 +5005,8 @@ dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset, */ static isc_boolean_t redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, - dns_dbnode_t **nodep, dns_db_t **dbp, dns_rdatatype_t qtype) + dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp, + dns_rdatatype_t qtype) { dns_db_t *db = NULL; dns_dbnode_t *node = NULL; @@ -5016,6 +5017,7 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, dns_rdatatype_t type; dns_clientinfomethods_t cm; dns_clientinfo_t ci; + ns_dbversion_t *dbversion; CTRACE("redirect"); @@ -5064,11 +5066,17 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, if (result != ISC_R_SUCCESS) return (ISC_FALSE); - /* - * Lookup the requested data in the redirect zone. - */ - result = dns_db_findext(db, client->query.qname, NULL, qtype, 0, - client->now, &node, found, &cm, &ci, + dbversion = query_findversion(client, db); + if (dbversion == NULL) { + dns_db_detach(&db); + return (ISC_FALSE); + } + + /* + * Lookup the requested data in the redirect zone. + */ + result = dns_db_findext(db, client->query.qname, dbversion->version, + qtype, 0, client->now, &node, found, &cm, &ci, &trdataset, NULL); if (result != ISC_R_SUCCESS) { if (dns_rdataset_isassociated(&trdataset)) @@ -5094,6 +5102,7 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, dns_db_attach(db, dbp); dns_db_detachnode(db, &node); dns_db_detach(&db); + *versionp = dbversion->version; client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | NS_QUERYATTR_NOADDITIONAL); @@ -6020,7 +6029,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) case DNS_R_NXDOMAIN: INSIST(is_zone); if (!empty_wild && - redirect(client, fname, rdataset, &node, &db, type)) + redirect(client, fname, rdataset, &node, &db, &version, + type)) break; if (dns_rdataset_isassociated(rdataset)) { /* @@ -6081,7 +6091,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) goto cleanup; case DNS_R_NCACHENXDOMAIN: - if (redirect(client, fname, rdataset, &node, &db, type)) + if (redirect(client, fname, rdataset, &node, &db, &version, + type)) break; case DNS_R_NCACHENXRRSET: ncache_nxrrset: diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 96a8bbf4d9..d95c2b4c88 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.c,v 1.317 2011/10/11 00:09:03 each Exp $ */ +/* $Id: rbtdb.c,v 1.318 2011/10/12 23:09:35 marka Exp $ */ /*! \file */ @@ -365,9 +365,12 @@ typedef enum { dns_db_secure } dns_db_secure_t; +typedef struct dns_rbtdb dns_rbtdb_t; + typedef struct rbtdb_version { /* Not locked */ rbtdb_serial_t serial; + dns_rbtdb_t * rbtdb; /* * Protected in the refcount routines. * XXXJT: should we change the lock policy based on the refcount @@ -392,7 +395,7 @@ typedef struct rbtdb_version { typedef ISC_LIST(rbtdb_version_t) rbtdb_versionlist_t; -typedef struct { +struct dns_rbtdb { /* Unlocked. */ dns_db_t common; /* Locks the data in this struct */ @@ -452,7 +455,7 @@ typedef struct { /* Unlocked */ unsigned int quantum; -} dns_rbtdb_t; +}; #define RBTDB_ATTR_LOADED 0x01 #define RBTDB_ATTR_LOADING 0x02 @@ -1105,6 +1108,7 @@ newversion(dns_db_t *db, dns_dbversion_t **versionp) { version = allocate_version(rbtdb->common.mctx, rbtdb->next_serial, 1, ISC_TRUE); if (version != NULL) { + version->rbtdb = rbtdb; version->commit_ok = ISC_TRUE; version->secure = rbtdb->current_version->secure; version->havensec3 = rbtdb->current_version->havensec3; @@ -1146,6 +1150,7 @@ attachversion(dns_db_t *db, dns_dbversion_t *source, unsigned int refs; REQUIRE(VALID_RBTDB(rbtdb)); + INSIST(rbtversion != NULL && rbtversion->rbtdb == rbtdb); isc_refcount_increment(&rbtversion->references, &refs); INSIST(refs > 1); @@ -2182,6 +2187,7 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { REQUIRE(VALID_RBTDB(rbtdb)); version = (rbtdb_version_t *)*versionp; + INSIST(version->rbtdb == rbtdb); cleanup_version = NULL; ISC_LIST_INIT(cleanup_list); @@ -3649,6 +3655,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, search.rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(search.rbtdb)); + INSIST(version == NULL || + ((rbtdb_version_t *)version)->rbtdb == (dns_rbtdb_t *)db); /* * We don't care about 'now'. @@ -5544,6 +5552,7 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(type != dns_rdatatype_any); + INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); if (rbtversion == NULL) { currentversion(db, (dns_dbversion_t **) (void *)(&rbtversion)); @@ -5732,6 +5741,8 @@ allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, else { unsigned int refs; + INSIST(rbtversion->rbtdb == rbtdb); + isc_refcount_increment(&rbtversion->references, &refs); INSIST(refs > 1); @@ -6401,6 +6412,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_boolean_t cache_is_overmem = ISC_FALSE; REQUIRE(VALID_RBTDB(rbtdb)); + INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); if (rbtdb->common.methods == &zone_methods) REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 && @@ -6417,8 +6429,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, now = 0; result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx, - ®ion, - sizeof(rdatasetheader_t)); + ®ion, sizeof(rdatasetheader_t)); if (result != ISC_R_SUCCESS) return (result); @@ -6591,6 +6602,7 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, rbtdb_changed_t *changed; REQUIRE(VALID_RBTDB(rbtdb)); + REQUIRE(rbtversion != NULL && rbtversion->rbtdb == rbtdb); if (rbtdb->common.methods == &zone_methods) REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 && @@ -6771,6 +6783,7 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, rdatasetheader_t *newheader; REQUIRE(VALID_RBTDB(rbtdb)); + INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); if (type == dns_rdatatype_any) return (ISC_R_NOTIMPLEMENTED); @@ -7064,10 +7077,12 @@ static isc_result_t dump(dns_db_t *db, dns_dbversion_t *version, const char *filename, dns_masterformat_t masterformat) { dns_rbtdb_t *rbtdb; + rbtdb_version_t *rbtversion = version; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); + INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); #ifdef BIND9 return (dns_master_dump2(rbtdb->common.mctx, db, version, @@ -7206,6 +7221,7 @@ getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash, rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); + INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb); RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); @@ -7335,11 +7351,16 @@ resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version) REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(rdataset != NULL); + REQUIRE(rdataset->methods == &rdataset_methods); REQUIRE(rbtdb->future_version == rbtversion); + REQUIRE(rbtversion != NULL); REQUIRE(rbtversion->writer); + REQUIRE(rbtversion->rbtdb == rbtdb); node = rdataset->private2; + INSIST(node != NULL); header = rdataset->private3; + INSIST(header != NULL); header--; RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); @@ -7754,6 +7775,7 @@ dns_rbtdb_create free_rbtdb(rbtdb, ISC_FALSE, NULL); return (ISC_R_NOMEMORY); } + rbtdb->current_version->rbtdb = rbtdb; rbtdb->current_version->secure = dns_db_insecure; rbtdb->current_version->havensec3 = ISC_FALSE; rbtdb->current_version->flags = 0; diff --git a/lib/dns/tests/Makefile.in b/lib/dns/tests/Makefile.in index 420457db98..1a3b80947d 100644 --- a/lib/dns/tests/Makefile.in +++ b/lib/dns/tests/Makefile.in @@ -12,7 +12,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.in,v 1.8 2011/09/02 21:15:37 each Exp $ +# $Id: Makefile.in,v 1.9 2011/10/12 23:09:35 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -42,7 +42,8 @@ SRCS = dnstest.c master_test.c dbiterator_test.c time_test.c \ SUBDIRS = TARGETS = master_test@EXEEXT@ dbiterator_test@EXEEXT@ time_test@EXEEXT@ \ - update_test@EXEEXT@ zonemgr_test@EXEEXT@ zt_test@EXEEXT@ + update_test@EXEEXT@ zonemgr_test@EXEEXT@ zt_test@EXEEXT@ \ + dbversion_test@EXEEXT@ @BIND9_MAKE_RULES@ @@ -71,6 +72,11 @@ dbiterator_test@EXEEXT@: dbiterator_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPL dbiterator_test.@O@ dnstest.@O@ ${DNSLIBS} \ ${ISCLIBS} ${LIBS} +dbversion_test@EXEEXT@: dbversion_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + dbversion_test.@O@ dnstest.@O@ ${DNSLIBS} \ + ${ISCLIBS} ${LIBS} + zt_test@EXEEXT@: zt_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ zt_test.@O@ dnstest.@O@ ${DNSLIBS} \ diff --git a/lib/dns/tests/dbversion_test.c b/lib/dns/tests/dbversion_test.c new file mode 100644 index 0000000000..0210ff4ab4 --- /dev/null +++ b/lib/dns/tests/dbversion_test.c @@ -0,0 +1,738 @@ +/* + * Copyright (C) 2011 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. + */ + +/* $Id: dbversion_test.c,v 1.2 2011/10/12 23:09:35 marka Exp $ */ + +/*! \file */ + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "dnstest.h" + +static char tempname[11] = "dtXXXXXXXX"; + +static void +callback(const char *file, int line, isc_assertiontype_t type, + const char *cond) +{ + UNUSED(file); UNUSED(line); UNUSED(type); UNUSED(cond); + if (strcmp(tempname, "dtXXXXXXXX")) + unlink(tempname); + atf_tc_pass(); + exit(0); +} + +static dns_db_t *db1 = NULL, *db2 = NULL; +static dns_dbversion_t *v1 = NULL, *v2 = NULL; + +static void +setup_db() { + isc_result_t result; + result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, + dns_rdataclass_in, 0, NULL, &db1); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + dns_db_newversion(db1, &v1); + + result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, + dns_rdataclass_in, 0, NULL, &db2); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + dns_db_newversion(db2, &v2); +} + +static void +close_db() { + if (v1 != NULL) { + dns_db_closeversion(db1, &v1, ISC_FALSE); + ATF_REQUIRE_EQ(v1, NULL); + } + if (db1 != NULL) { + dns_db_detach(&db1); + ATF_REQUIRE_EQ(db1, NULL); + } + + if (v2 != NULL) { + dns_db_closeversion(db2, &v2, ISC_FALSE); + ATF_REQUIRE_EQ(v2, NULL); + } + if (db2 != NULL) { + dns_db_detach(&db2); + ATF_REQUIRE_EQ(db2, NULL); + } +} + +#define VERSION(callback) ((callback == NULL) ? v1 : v2) +#define VERSIONP(callback) ((callback == NULL) ? &v1 : &v2) +/* + * Individual unit tests + */ +static void +attachversion(isc_assertioncallback_t callback) { + isc_result_t result; + dns_dbversion_t *v = NULL; + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + setup_db(); + + isc_assertion_setcallback(callback); + dns_db_attachversion(db1, VERSION(callback), &v); + if (callback != NULL) + atf_tc_fail("dns_db_attachversion did not assert"); + + ATF_REQUIRE_EQ(v, v1); + dns_db_closeversion(db1, &v, ISC_FALSE); + ATF_REQUIRE_EQ(v, NULL); + + close_db(); + dns_test_end(); +} + +ATF_TC(attachversion); +ATF_TC_HEAD(attachversion, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_attachversion passes with matching db/verison"); +} +ATF_TC_BODY(attachversion, tc) { + + UNUSED(tc); + + attachversion(NULL); +} + +ATF_TC(attachversion_bad); +ATF_TC_HEAD(attachversion_bad, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_attachversion aborts with mis-matching db/verison"); +} +ATF_TC_BODY(attachversion_bad, tc) { + + UNUSED(tc); + + attachversion(callback); +} + +static void +closeversion(isc_assertioncallback_t callback) { + isc_result_t result; + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + setup_db(); + + isc_assertion_setcallback(callback); + dns_db_closeversion(db1, VERSIONP(callback), ISC_FALSE); + if (callback != NULL) + atf_tc_fail("dns_db_closeversion did not assert"); + ATF_REQUIRE_EQ(v1, NULL); + + close_db(); + dns_test_end(); +} + +ATF_TC(closeversion); +ATF_TC_HEAD(closeversion, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_closeversion passes with matching db/verison"); +} +ATF_TC_BODY(closeversion, tc) { + + UNUSED(tc); + + closeversion(NULL); +} + +ATF_TC(closeversion_bad); +ATF_TC_HEAD(closeversion_bad, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_closeversion asserts with mis-matching db/verison"); +} +ATF_TC_BODY(closeversion_bad, tc) { + + UNUSED(tc); + + closeversion(callback); +} + +static void +find(isc_assertioncallback_t callback) { + isc_result_t result; + dns_rdataset_t rdataset; + dns_fixedname_t fixed; + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + setup_db(); + + dns_rdataset_init(&rdataset); + dns_fixedname_init(&fixed); + + isc_assertion_setcallback(callback); + result = dns_db_find(db1, dns_rootname, VERSION(callback), + dns_rdatatype_soa, 0, 0, NULL, + dns_fixedname_name(&fixed), &rdataset, NULL); + if (callback != NULL) + atf_tc_fail("dns_db_find did not assert"); + ATF_REQUIRE_EQ(result, DNS_R_NXDOMAIN); + + close_db(); + + dns_test_end(); +} +ATF_TC(find); +ATF_TC_HEAD(find, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_find passes with matching db/version"); +} +ATF_TC_BODY(find, tc) { + + UNUSED(tc); + + find(NULL); +} + +ATF_TC(find_bad); +ATF_TC_HEAD(find_bad, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_find asserts with mis-matching db/version"); +} +ATF_TC_BODY(find_bad, tc) { + + UNUSED(tc); + + find(callback); +} + +static void +allrdatasets(isc_assertioncallback_t callback) { + isc_result_t result; + dns_dbnode_t *node = NULL; + dns_rdatasetiter_t *iterator = NULL; + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + setup_db(); + + result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + isc_assertion_setcallback(callback); + result = dns_db_allrdatasets(db1, node, VERSION(callback), 0, + &iterator); + if (callback != NULL) + atf_tc_fail("dns_db_allrdatasets did not assert"); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + dns_rdatasetiter_destroy(&iterator); + ATF_REQUIRE_EQ(iterator, NULL); + + dns_db_detachnode(db1, &node); + ATF_REQUIRE_EQ(node, NULL); + + close_db(); + + dns_test_end(); +} + +ATF_TC(allrdatasets); +ATF_TC_HEAD(allrdatasets, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_allrdatasets passes with matching db/version"); +} +ATF_TC_BODY(allrdatasets, tc) { + + UNUSED(tc); + + allrdatasets(NULL); +} + +ATF_TC(allrdatasets_bad); +ATF_TC_HEAD(allrdatasets_bad, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_allrdatasets aborts with mis-matching db/version"); +} +ATF_TC_BODY(allrdatasets_bad, tc) { + + UNUSED(tc); + + allrdatasets(callback); +} + +static void +findrdataset(isc_assertioncallback_t callback) { + isc_result_t result; + dns_rdataset_t rdataset; + dns_fixedname_t fixed; + dns_dbnode_t *node = NULL; + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + setup_db(); + + dns_rdataset_init(&rdataset); + dns_fixedname_init(&fixed); + + result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + isc_assertion_setcallback(callback); + result = dns_db_findrdataset(db1, node, VERSION(callback), + dns_rdatatype_soa, 0, 0, &rdataset, NULL); + if (callback != NULL) + atf_tc_fail("dns_db_findrdataset did not assert"); + ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND); + + dns_db_detachnode(db1, &node); + ATF_REQUIRE_EQ(node, NULL); + + close_db(); + + dns_test_end(); +} + +ATF_TC(findrdataset); +ATF_TC_HEAD(findrdataset, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_findrdataset passes with matching db/version"); +} +ATF_TC_BODY(findrdataset, tc) { + + UNUSED(tc); + + findrdataset(NULL); +} + +ATF_TC(findrdataset_bad); +ATF_TC_HEAD(findrdataset_bad, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_findrdataset aborts with mis-matching db/version"); +} +ATF_TC_BODY(findrdataset_bad, tc) { + + UNUSED(tc); + + findrdataset(callback); +} + +static void +deleterdataset(isc_assertioncallback_t callback) { + isc_result_t result; + dns_rdataset_t rdataset; + dns_fixedname_t fixed; + dns_dbnode_t *node = NULL; + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + setup_db(); + + dns_rdataset_init(&rdataset); + dns_fixedname_init(&fixed); + + result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + isc_assertion_setcallback(callback); + result = dns_db_deleterdataset(db1, node, VERSION(callback), + dns_rdatatype_soa, 0); + if (callback != NULL) + atf_tc_fail("dns_db_deleterdataset did not assert"); + ATF_REQUIRE_EQ(result, DNS_R_UNCHANGED); + + dns_db_detachnode(db1, &node); + ATF_REQUIRE_EQ(node, NULL); + + close_db(); + + dns_test_end(); +} + +ATF_TC(deleterdataset); +ATF_TC_HEAD(deleterdataset, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_deleterdataset passes with matching db/version"); +} +ATF_TC_BODY(deleterdataset, tc) { + + UNUSED(tc); + + deleterdataset(NULL); +} + +ATF_TC(deleterdataset_bad); +ATF_TC_HEAD(deleterdataset_bad, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_deleterdataset aborts with mis-matching db/version"); +} +ATF_TC_BODY(deleterdataset_bad, tc) { + + UNUSED(tc); + + deleterdataset(callback); +} + +static void +subtract(isc_assertioncallback_t callback) { + isc_result_t result; + dns_rdataset_t rdataset; + dns_fixedname_t fixed; + dns_dbnode_t *node = NULL; + dns_rdatalist_t rdatalist; + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + setup_db(); + + dns_rdataset_init(&rdataset); + dns_rdatalist_init(&rdatalist); + dns_fixedname_init(&fixed); + + rdatalist.rdclass = dns_rdataclass_in; + + result = dns_rdatalist_tordataset(&rdatalist, &rdataset); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + isc_assertion_setcallback(callback); + result = dns_db_subtractrdataset(db1, node, VERSION(callback), + &rdataset, 0, NULL); + if (callback != NULL) + atf_tc_fail("dns_db_dns_db_subtractrdataset did not assert"); + ATF_REQUIRE_EQ(result, DNS_R_UNCHANGED); + + dns_db_detachnode(db1, &node); + ATF_REQUIRE_EQ(node, NULL); + + close_db(); + + dns_test_end(); +} + +ATF_TC(subtractrdataset); +ATF_TC_HEAD(subtractrdataset, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_subtractrdataset passes with matching db/version"); +} +ATF_TC_BODY(subtractrdataset, tc) { + + UNUSED(tc); + + subtract(NULL); +} + +ATF_TC(subtractrdataset_bad); +ATF_TC_HEAD(subtractrdataset_bad, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_subtractrdataset aborts with mis-matching db/version"); +} +ATF_TC_BODY(subtractrdataset_bad, tc) { + + UNUSED(tc); + + subtract(callback); +} + +static void +dump(isc_assertioncallback_t callback) { + isc_result_t result; + FILE *f = NULL; + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + setup_db(); + + result = isc_file_openunique(tempname, &f); + fclose(f); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + isc_assertion_setcallback(callback); + result = dns_db_dump(db1, VERSION(callback), tempname); + (void)unlink(tempname); + if (callback != NULL) + atf_tc_fail("dns_db_dump did not assert"); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + close_db(); + + dns_test_end(); +} + +ATF_TC(dump); +ATF_TC_HEAD(dump, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_dump passes with matching db/version"); +} +ATF_TC_BODY(dump, tc) { + + UNUSED(tc); + + dump(NULL); +} + +ATF_TC(dump_bad); +ATF_TC_HEAD(dump_bad, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_dump aborts with mis-matching db/version"); +} +ATF_TC_BODY(dump_bad, tc) { + + UNUSED(tc); + + dump(callback); +} + +static void +addrdataset(isc_assertioncallback_t callback) { + isc_result_t result; + dns_rdataset_t rdataset; + dns_fixedname_t fixed; + dns_dbnode_t *node = NULL; + dns_rdatalist_t rdatalist; + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + setup_db(); + + dns_rdataset_init(&rdataset); + dns_rdatalist_init(&rdatalist); + dns_fixedname_init(&fixed); + + rdatalist.rdclass = dns_rdataclass_in; + + result = dns_rdatalist_tordataset(&rdatalist, &rdataset); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + isc_assertion_setcallback(callback); + result = dns_db_addrdataset(db1, node, VERSION(callback), 0, &rdataset, + 0, NULL); + if (callback != NULL) + atf_tc_fail("dns_db_adddataset did not assert"); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + dns_db_detachnode(db1, &node); + ATF_REQUIRE_EQ(node, NULL); + + close_db(); + + dns_test_end(); +} + +ATF_TC(addrdataset); +ATF_TC_HEAD(addrdataset, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_addrdataset passes with matching db/version"); +} +ATF_TC_BODY(addrdataset, tc) { + + UNUSED(tc); + + addrdataset(NULL); +} + +ATF_TC(addrdataset_bad); +ATF_TC_HEAD(addrdataset_bad, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_addrdataset aborts with mis-matching db/version"); +} +ATF_TC_BODY(addrdataset_bad, tc) { + + UNUSED(tc); + + addrdataset(callback); +} + +static void +getnsec3parameters(isc_assertioncallback_t callback) { + isc_result_t result; + dns_hash_t hash; + isc_uint8_t flags; + isc_uint16_t iterations; + unsigned char salt[DNS_NSEC3_SALTSIZE]; + size_t salt_length = sizeof(salt); + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + setup_db(); + + isc_assertion_setcallback(callback); + result = dns_db_getnsec3parameters(db1, VERSION(callback), &hash, + &flags, &iterations, salt, + &salt_length); + if (callback != NULL) + atf_tc_fail("dns_db_dump did not assert"); + ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND); + + close_db(); + + dns_test_end(); +} + +ATF_TC(getnsec3parameters); +ATF_TC_HEAD(getnsec3parameters, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_getnsec3parameters passes with matching db/version"); +} +ATF_TC_BODY(getnsec3parameters, tc) { + + UNUSED(tc); + + getnsec3parameters(NULL); +} + +ATF_TC(getnsec3parameters_bad); +ATF_TC_HEAD(getnsec3parameters_bad, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_db_getnsec3parameters aborts with mis-matching db/version"); +} +ATF_TC_BODY(getnsec3parameters_bad, tc) { + + UNUSED(tc); + + getnsec3parameters(callback); +} + +static void +resigned(isc_assertioncallback_t callback) { + isc_result_t result; + dns_rdataset_t rdataset, added; + dns_dbnode_t *node = NULL; + dns_rdatalist_t rdatalist; + dns_rdata_rrsig_t rrsig; + dns_rdata_t rdata = DNS_RDATA_INIT; + isc_buffer_t b; + unsigned char buf[1024]; + + result = dns_test_begin(NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + setup_db(); + + /* + * Create a dummy RRSIG record and set a resigning time. + */ + dns_rdataset_init(&added); + dns_rdataset_init(&rdataset); + dns_rdatalist_init(&rdatalist); + isc_buffer_init(&b, buf, sizeof(buf)); + + DNS_RDATACOMMON_INIT(&rrsig, dns_rdatatype_rrsig, dns_rdataclass_in); + rrsig.covered = dns_rdatatype_a; + rrsig.algorithm = 100; + rrsig.labels = 0; + rrsig.originalttl = 0; + rrsig.timeexpire = 3600; + rrsig.timesigned = 0; + rrsig.keyid = 0; + dns_name_init(&rrsig.signer, NULL); + dns_name_clone(dns_rootname, &rrsig.signer); + rrsig.siglen = 0; + rrsig.signature = NULL; + + result = dns_rdata_fromstruct(&rdata, dns_rdataclass_in, + dns_rdatatype_rrsig, &rrsig, &b); + + rdatalist.rdclass = dns_rdataclass_in; + rdatalist.type = dns_rdatatype_rrsig; + ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); + + result = dns_rdatalist_tordataset(&rdatalist, &rdataset); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + rdataset.attributes |= DNS_RDATASETATTR_RESIGN; + rdataset.resign = 7200; + + result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + result = dns_db_addrdataset(db1, node, v1, 0, &rdataset, 0, &added); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + dns_db_detachnode(db1, &node); + ATF_REQUIRE_EQ(node, NULL); + + isc_assertion_setcallback(callback); + dns_db_resigned(db1, &added, VERSION(callback)); + if (callback != NULL) + atf_tc_fail("dns_db_resigned did not assert"); + + dns_rdataset_disassociate(&added); + + close_db(); + + dns_test_end(); +} + +ATF_TC(resigned); +ATF_TC_HEAD(resigned, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_rdataset_resigned passes with matching db/version"); +} +ATF_TC_BODY(resigned, tc) { + + UNUSED(tc); + + resigned(NULL); +} + +ATF_TC(resigned_bad); +ATF_TC_HEAD(resigned_bad, tc) { + atf_tc_set_md_var(tc, "descr", "check dns_rdataset_resigned aborts with mis-matching db/version"); +} +ATF_TC_BODY(resigned_bad, tc) { + + UNUSED(tc); + + resigned(callback); +} + +/* + * Main + */ +ATF_TP_ADD_TCS(tp) { + ATF_TP_ADD_TC(tp, dump); + ATF_TP_ADD_TC(tp, dump_bad); + ATF_TP_ADD_TC(tp, find); + ATF_TP_ADD_TC(tp, find_bad); + ATF_TP_ADD_TC(tp, allrdatasets); + ATF_TP_ADD_TC(tp, allrdatasets_bad); + ATF_TP_ADD_TC(tp, findrdataset); + ATF_TP_ADD_TC(tp, findrdataset_bad); + ATF_TP_ADD_TC(tp, addrdataset); + ATF_TP_ADD_TC(tp, addrdataset_bad); + ATF_TP_ADD_TC(tp, deleterdataset); + ATF_TP_ADD_TC(tp, deleterdataset_bad); + ATF_TP_ADD_TC(tp, subtractrdataset); + ATF_TP_ADD_TC(tp, subtractrdataset_bad); + ATF_TP_ADD_TC(tp, attachversion); + ATF_TP_ADD_TC(tp, attachversion_bad); + ATF_TP_ADD_TC(tp, closeversion); + ATF_TP_ADD_TC(tp, closeversion_bad); + ATF_TP_ADD_TC(tp, getnsec3parameters); + ATF_TP_ADD_TC(tp, getnsec3parameters_bad); + ATF_TP_ADD_TC(tp, resigned); + ATF_TP_ADD_TC(tp, resigned_bad); + + return (atf_no_error()); +} diff --git a/lib/dns/tests/update_test.c b/lib/dns/tests/update_test.c index 934a4696b2..270c2b7bc3 100644 --- a/lib/dns/tests/update_test.c +++ b/lib/dns/tests/update_test.c @@ -14,9 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: update_test.c,v 1.5 2011/08/23 01:29:38 each Exp $ */ - -/* $Id: */ +/* $Id: update_test.c,v 1.6 2011/10/12 23:09:35 marka Exp $ */ /*! \file */