diff options
Diffstat (limited to 'lib/dns/view.c')
-rw-r--r-- | lib/dns/view.c | 421 |
1 files changed, 365 insertions, 56 deletions
diff --git a/lib/dns/view.c b/lib/dns/view.c index 809cc15..24f925a 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,13 +15,16 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.c,v 1.150.84.6 2010-09-24 08:09:08 marka Exp $ */ +/* $Id: view.c,v 1.178 2011-01-13 09:53:04 marka Exp $ */ /*! \file */ #include <config.h> +#include <isc/file.h> #include <isc/hash.h> +#include <isc/print.h> +#include <isc/sha2.h> #include <isc/stats.h> #include <isc/string.h> /* Required for HP/UX (and others?) */ #include <isc/task.h> @@ -33,17 +36,24 @@ #include <dns/cache.h> #include <dns/db.h> #include <dns/dlz.h> +#ifdef BIND9 +#include <dns/dns64.h> +#endif +#include <dns/dnssec.h> #include <dns/events.h> #include <dns/forward.h> #include <dns/keytable.h> +#include <dns/keyvalues.h> #include <dns/master.h> #include <dns/masterdump.h> #include <dns/order.h> #include <dns/peer.h> +#include <dns/rbt.h> #include <dns/rdataset.h> #include <dns/request.h> #include <dns/resolver.h> #include <dns/result.h> +#include <dns/rpz.h> #include <dns/stats.h> #include <dns/tsig.h> #include <dns/zone.h> @@ -85,6 +95,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, if (result != ISC_R_SUCCESS) goto cleanup_name; +#ifdef BIND9 view->zonetable = NULL; result = dns_zt_create(mctx, rdclass, &view->zonetable); if (result != ISC_R_SUCCESS) { @@ -94,24 +105,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, result = ISC_R_UNEXPECTED; goto cleanup_mutex; } - view->secroots = NULL; - result = dns_keytable_create(mctx, &view->secroots); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "dns_keytable_create() failed: %s", - isc_result_totext(result)); - result = ISC_R_UNEXPECTED; - goto cleanup_zt; - } - view->trustedkeys = NULL; - result = dns_keytable_create(mctx, &view->trustedkeys); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "dns_keytable_create() failed: %s", - isc_result_totext(result)); - result = ISC_R_UNEXPECTED; - goto cleanup_secroots; - } +#endif + view->secroots_priv = NULL; view->fwdtable = NULL; result = dns_fwdtable_create(mctx, &view->fwdtable); if (result != ISC_R_SUCCESS) { @@ -119,7 +114,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, "dns_fwdtable_create() failed: %s", isc_result_totext(result)); result = ISC_R_UNEXPECTED; - goto cleanup_trustedkeys; + goto cleanup_zt; } view->acache = NULL; @@ -155,6 +150,9 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->rootexclude = NULL; view->resstats = NULL; view->resquerystats = NULL; + view->cacheshared = ISC_FALSE; + ISC_LIST_INIT(view->dns64); + view->dns64cnt = 0; /* * Initialize configuration data with default values. @@ -179,6 +177,10 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->notifyacl = NULL; view->updateacl = NULL; view->upfwdacl = NULL; + view->denyansweracl = NULL; + view->answeracl_exclude = NULL; + view->denyanswernames = NULL; + view->answernames_exclude = NULL; view->requestixfr = ISC_TRUE; view->provideixfr = ISC_TRUE; view->maxcachettl = 7 * 24 * 3600; @@ -188,11 +190,20 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->flush = ISC_FALSE; view->dlv = NULL; view->maxudp = 0; + view->v4_aaaa = dns_v4_aaaa_ok; + view->v4_aaaa_acl = NULL; + ISC_LIST_INIT(view->rpz_zones); dns_fixedname_init(&view->dlv_fixed); + view->managed_keys = NULL; +#ifdef BIND9 + view->new_zone_file = NULL; + view->new_zone_config = NULL; + view->cfg_destroy = NULL; result = dns_order_create(view->mctx, &view->order); if (result != ISC_R_SUCCESS) goto cleanup_dynkeys; +#endif result = dns_peerlist_new(view->mctx, &view->peers); if (result != ISC_R_SUCCESS) @@ -222,10 +233,12 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_peerlist_detach(&view->peers); cleanup_order: +#ifdef BIND9 dns_order_detach(&view->order); cleanup_dynkeys: - dns_tsigkeyring_destroy(&view->dynamickeys); +#endif + dns_tsigkeyring_detach(&view->dynamickeys); cleanup_references: isc_refcount_destroy(&view->references); @@ -233,16 +246,12 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, cleanup_fwdtable: dns_fwdtable_destroy(&view->fwdtable); - cleanup_trustedkeys: - dns_keytable_detach(&view->trustedkeys); - - cleanup_secroots: - dns_keytable_detach(&view->secroots); - cleanup_zt: +#ifdef BIND9 dns_zt_detach(&view->zonetable); cleanup_mutex: +#endif DESTROYLOCK(&view->lock); cleanup_name: @@ -256,6 +265,10 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, static inline void destroy(dns_view_t *view) { +#ifdef BIND9 + dns_dns64_t *dns64; +#endif + REQUIRE(!ISC_LINK_LINKED(view, link)); REQUIRE(isc_refcount_current(&view->references) == 0); REQUIRE(view->weakrefs == 0); @@ -263,23 +276,62 @@ destroy(dns_view_t *view) { REQUIRE(ADBSHUTDOWN(view)); REQUIRE(REQSHUTDOWN(view)); +#ifdef BIND9 if (view->order != NULL) dns_order_detach(&view->order); +#endif if (view->peers != NULL) dns_peerlist_detach(&view->peers); - if (view->dynamickeys != NULL) - dns_tsigkeyring_destroy(&view->dynamickeys); + + if (view->dynamickeys != NULL) { + isc_result_t result; + char template[20]; + char keyfile[20]; + FILE *fp = NULL; + int n; + + n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys", + view->name); + if (n > 0 && (size_t)n < sizeof(keyfile)) { + result = isc_file_mktemplate(keyfile, template, + sizeof(template)); + if (result == ISC_R_SUCCESS) + (void)isc_file_openuniqueprivate(template, &fp); + } + if (fp == NULL) + dns_tsigkeyring_detach(&view->dynamickeys); + else { + result = dns_tsigkeyring_dumpanddetach( + &view->dynamickeys, fp); + if (result == ISC_R_SUCCESS) { + if (fclose(fp) == 0) + result = isc_file_rename(template, + keyfile); + if (result != ISC_R_SUCCESS) + (void)remove(template); + } else { + (void)fclose(fp); + (void)remove(template); + } + } + } if (view->statickeys != NULL) - dns_tsigkeyring_destroy(&view->statickeys); + dns_tsigkeyring_detach(&view->statickeys); if (view->adb != NULL) dns_adb_detach(&view->adb); if (view->resolver != NULL) dns_resolver_detach(&view->resolver); +#ifdef BIND9 if (view->acache != NULL) { if (view->cachedb != NULL) dns_acache_putdb(view->acache, view->cachedb); dns_acache_detach(&view->acache); } + dns_rpz_view_destroy(view); +#else + INSIST(view->acache == NULL); + INSIST(ISC_LIST_EMPTY(view->rpz_zones)); +#endif if (view->requestmgr != NULL) dns_requestmgr_detach(&view->requestmgr); if (view->task != NULL) @@ -318,6 +370,16 @@ destroy(dns_view_t *view) { dns_acl_detach(&view->updateacl); if (view->upfwdacl != NULL) dns_acl_detach(&view->upfwdacl); + if (view->denyansweracl != NULL) + dns_acl_detach(&view->denyansweracl); + if (view->v4_aaaa_acl != NULL) + dns_acl_detach(&view->v4_aaaa_acl); + if (view->answeracl_exclude != NULL) + dns_rbt_destroy(&view->answeracl_exclude); + if (view->denyanswernames != NULL) + dns_rbt_destroy(&view->denyanswernames); + if (view->answernames_exclude != NULL) + dns_rbt_destroy(&view->answernames_exclude); if (view->delonly != NULL) { dns_name_t *name; int i; @@ -357,8 +419,19 @@ destroy(dns_view_t *view) { isc_stats_detach(&view->resstats); if (view->resquerystats != NULL) dns_stats_detach(&view->resquerystats); - dns_keytable_detach(&view->trustedkeys); - dns_keytable_detach(&view->secroots); + if (view->secroots_priv != NULL) + dns_keytable_detach(&view->secroots_priv); +#ifdef BIND9 + for (dns64 = ISC_LIST_HEAD(view->dns64); + dns64 != NULL; + dns64 = ISC_LIST_HEAD(view->dns64)) { + dns_dns64_unlink(&view->dns64, dns64); + dns_dns64_destroy(&dns64); + } + if (view->managed_keys != NULL) + dns_zone_detach(&view->managed_keys); + dns_view_setnewzones(view, ISC_FALSE, NULL, NULL); +#endif dns_fwdtable_destroy(&view->fwdtable); dns_aclenv_destroy(&view->aclenv); DESTROYLOCK(&view->lock); @@ -414,12 +487,19 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { dns_adb_shutdown(view->adb); if (!REQSHUTDOWN(view)) dns_requestmgr_shutdown(view->requestmgr); +#ifdef BIND9 if (view->acache != NULL) dns_acache_shutdown(view->acache); if (view->flush) dns_zt_flushanddetach(&view->zonetable); else dns_zt_detach(&view->zonetable); + if (view->managed_keys != NULL) { + if (view->flush) + dns_zone_flush(view->managed_keys); + dns_zone_detach(&view->managed_keys); + } +#endif done = all_done(view); UNLOCK(&view->lock); } @@ -440,6 +520,7 @@ dns_view_detach(dns_view_t **viewp) { view_flushanddetach(viewp, ISC_FALSE); } +#ifdef BIND9 static isc_result_t dialup(dns_zone_t *zone, void *dummy) { UNUSED(dummy); @@ -452,6 +533,7 @@ dns_view_dialup(dns_view_t *view) { REQUIRE(DNS_VIEW_VALID(view)); (void)dns_zt_apply(view->zonetable, ISC_FALSE, dialup, NULL); } +#endif void dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) { @@ -633,12 +715,20 @@ dns_view_createresolver(dns_view_t *view, void dns_view_setcache(dns_view_t *view, dns_cache_t *cache) { + dns_view_setcache2(view, cache, ISC_FALSE); +} + +void +dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(!view->frozen); + view->cacheshared = shared; if (view->cache != NULL) { +#ifdef BIND9 if (view->acache != NULL) dns_acache_putdb(view->acache, view->cachedb); +#endif dns_db_detach(&view->cachedb); dns_cache_detach(&view->cache); } @@ -646,8 +736,17 @@ dns_view_setcache(dns_view_t *view, dns_cache_t *cache) { dns_cache_attachdb(cache, &view->cachedb); INSIST(DNS_DB_VALID(view->cachedb)); +#ifdef BIND9 if (view->acache != NULL) dns_acache_setdb(view->acache, view->cachedb); +#endif +} + +isc_boolean_t +dns_view_iscacheshared(dns_view_t *view) { + REQUIRE(DNS_VIEW_VALID(view)); + + return (view->cacheshared); } void @@ -665,26 +764,52 @@ dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) { REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(ring != NULL); if (view->statickeys != NULL) - dns_tsigkeyring_destroy(&view->statickeys); - view->statickeys = ring; + dns_tsigkeyring_detach(&view->statickeys); + dns_tsigkeyring_attach(ring, &view->statickeys); } void -dns_view_setdstport(dns_view_t *view, in_port_t dstport) { +dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring) { REQUIRE(DNS_VIEW_VALID(view)); - view->dstport = dstport; + REQUIRE(ring != NULL); + if (view->dynamickeys != NULL) + dns_tsigkeyring_detach(&view->dynamickeys); + dns_tsigkeyring_attach(ring, &view->dynamickeys); } -isc_result_t -dns_view_addzone(dns_view_t *view, dns_zone_t *zone) { - isc_result_t result; +void +dns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp) { + REQUIRE(DNS_VIEW_VALID(view)); + REQUIRE(ringp != NULL && *ringp == NULL); + if (view->dynamickeys != NULL) + dns_tsigkeyring_attach(view->dynamickeys, ringp); +} + +void +dns_view_restorekeyring(dns_view_t *view) { + FILE *fp; + char keyfile[20]; + int n; REQUIRE(DNS_VIEW_VALID(view)); - REQUIRE(!view->frozen); - result = dns_zt_mount(view->zonetable, zone); + if (view->dynamickeys != NULL) { + n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys", + view->name); + if (n > 0 && (size_t)n < sizeof(keyfile)) { + fp = fopen(keyfile, "r"); + if (fp != NULL) { + dns_keyring_restore(view->dynamickeys, fp); + (void)fclose(fp); + } + } + } +} - return (result); +void +dns_view_setdstport(dns_view_t *view, in_port_t dstport) { + REQUIRE(DNS_VIEW_VALID(view)); + view->dstport = dstport; } void @@ -699,6 +824,29 @@ dns_view_freeze(dns_view_t *view) { view->frozen = ISC_TRUE; } +#ifdef BIND9 +void +dns_view_thaw(dns_view_t *view) { + REQUIRE(DNS_VIEW_VALID(view)); + REQUIRE(view->frozen); + + view->frozen = ISC_FALSE; +} + +isc_result_t +dns_view_addzone(dns_view_t *view, dns_zone_t *zone) { + isc_result_t result; + + REQUIRE(DNS_VIEW_VALID(view)); + REQUIRE(!view->frozen); + + result = dns_zt_mount(view->zonetable, zone); + + return (result); +} +#endif + +#ifdef BIND9 isc_result_t dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) { isc_result_t result; @@ -713,20 +861,37 @@ dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) { return (result); } +#endif isc_result_t dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { + return (dns_view_find2(view, name, type, now, options, use_hints, + ISC_FALSE, dbp, nodep, foundname, rdataset, + sigrdataset)); +} + +isc_result_t +dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, + isc_stdtime_t now, unsigned int options, + isc_boolean_t use_hints, isc_boolean_t use_static_stub, + dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { isc_result_t result; dns_db_t *db, *zdb; dns_dbnode_t *node, *znode; - isc_boolean_t is_cache; + isc_boolean_t is_cache, is_staticstub_zone; dns_rdataset_t zrdataset, zsigrdataset; dns_zone_t *zone; +#ifndef BIND9 + UNUSED(use_hints); + UNUSED(use_static_stub); +#endif + /* * Find an rdataset whose owner name is 'name', and whose type is * 'type'. @@ -752,15 +917,30 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, zone = NULL; db = NULL; node = NULL; + is_staticstub_zone = ISC_FALSE; +#ifdef BIND9 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); + if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub && + !use_static_stub) { + result = ISC_R_NOTFOUND; + } if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { result = dns_zone_getdb(zone, &db); if (result != ISC_R_SUCCESS && view->cachedb != NULL) dns_db_attach(view->cachedb, &db); else if (result != ISC_R_SUCCESS) goto cleanup; + if (dns_zone_gettype(zone) == dns_zone_staticstub && + dns_name_equal(name, dns_zone_getorigin(zone))) { + is_staticstub_zone = ISC_TRUE; + } } else if (result == ISC_R_NOTFOUND && view->cachedb != NULL) dns_db_attach(view->cachedb, &db); +#else + result = ISC_R_NOTFOUND; + if (view->cachedb != NULL) + dns_db_attach(view->cachedb, &db); +#endif /* BIND9 */ else goto cleanup; @@ -773,8 +953,7 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, result = dns_db_find(db, name, NULL, type, options, now, &node, foundname, rdataset, sigrdataset); - if (result == DNS_R_DELEGATION || - result == ISC_R_NOTFOUND) { + if (result == DNS_R_DELEGATION || result == ISC_R_NOTFOUND) { if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); if (sigrdataset != NULL && @@ -784,10 +963,13 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, dns_db_detachnode(db, &node); if (!is_cache) { dns_db_detach(&db); - if (view->cachedb != NULL) { + if (view->cachedb != NULL && !is_staticstub_zone) { /* * Either the answer is in the cache, or we * don't know it. + * Note that if the result comes from a + * static-stub zone we stop the search here + * (see the function description in view.h). */ is_cache = ISC_TRUE; dns_db_attach(view->cachedb, &db); @@ -817,7 +999,7 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, */ result = ISC_R_NOTFOUND; } else if (result == DNS_R_GLUE) { - if (view->cachedb != NULL) { + if (view->cachedb != NULL && !is_staticstub_zone) { /* * We found an answer, but the cache may be better. * Remember what we've got and go look in the cache. @@ -843,6 +1025,7 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, result = ISC_R_SUCCESS; } +#ifdef BIND9 if (result == ISC_R_NOTFOUND && use_hints && view->hints != NULL) { if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); @@ -877,6 +1060,7 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, if (db == NULL && node != NULL) dns_db_detachnode(view->hints, &node); } +#endif /* BIND9 */ cleanup: if (dns_rdataset_isassociated(&zrdataset)) { @@ -905,8 +1089,10 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, } else INSIST(node == NULL); +#ifdef BIND9 if (zone != NULL) dns_zone_detach(&zone); +#endif return (result); } @@ -969,12 +1155,12 @@ dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname, isc_result_t dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, isc_stdtime_t now, unsigned int options, - isc_boolean_t use_hints, isc_boolean_t use_cache, + isc_boolean_t use_hints, isc_boolean_t use_cache, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { isc_result_t result; dns_db_t *db; - isc_boolean_t is_cache, use_zone, try_hints; + isc_boolean_t is_cache, use_zone, try_hints, is_staticstub_zone; dns_zone_t *zone; dns_name_t *zfname; dns_rdataset_t zrdataset, zsigrdataset; @@ -986,6 +1172,7 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, db = NULL; zone = NULL; use_zone = ISC_FALSE; + is_staticstub_zone = ISC_FALSE; try_hints = ISC_FALSE; zfname = NULL; @@ -999,9 +1186,16 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, /* * Find the right database. */ +#ifdef BIND9 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); - if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) + if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { result = dns_zone_getdb(zone, &db); + if (dns_zone_gettype(zone) == dns_zone_staticstub) + is_staticstub_zone = ISC_TRUE; + } +#else + result = ISC_R_NOTFOUND; +#endif if (result == ISC_R_NOTFOUND) { /* * We're not directly authoritative for this query name, nor @@ -1064,7 +1258,9 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, fname, rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { if (zfname != NULL && - !dns_name_issubdomain(fname, zfname)) { + (!dns_name_issubdomain(fname, zfname) || + (dns_zone_staticstub && + dns_name_equal(fname, zfname)))) { /* * We found a zonecut in the cache, but our * zone delegation is better. @@ -1133,8 +1329,10 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, } if (db != NULL) dns_db_detach(&db); +#ifdef BIND9 if (zone != NULL) dns_zone_detach(&zone); +#endif return (result); } @@ -1161,6 +1359,7 @@ dns_viewlist_find(dns_viewlist_t *list, const char *name, return (ISC_R_SUCCESS); } +#ifdef BIND9 isc_result_t dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name, isc_boolean_t allclasses, dns_rdataclass_t rdclass, @@ -1225,6 +1424,7 @@ dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) { return (dns_zt_loadnew(view->zonetable, stop)); } +#endif /* BIND9 */ isc_result_t dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp) @@ -1269,6 +1469,7 @@ dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) { view->dynamickeys)); } +#ifdef BIND9 isc_result_t dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) { isc_result_t result; @@ -1284,26 +1485,38 @@ dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) { dns_resolver_printbadcache(view->resolver, fp); return (ISC_R_SUCCESS); } +#endif isc_result_t dns_view_flushcache(dns_view_t *view) { + return (dns_view_flushcache2(view, ISC_FALSE)); +} + +isc_result_t +dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) { isc_result_t result; REQUIRE(DNS_VIEW_VALID(view)); if (view->cachedb == NULL) return (ISC_R_SUCCESS); - result = dns_cache_flush(view->cache); - if (result != ISC_R_SUCCESS) - return (result); + if (!fixuponly) { + result = dns_cache_flush(view->cache); + if (result != ISC_R_SUCCESS) + return (result); + } +#ifdef BIND9 if (view->acache != NULL) dns_acache_putdb(view->acache, view->cachedb); +#endif dns_db_detach(&view->cachedb); dns_cache_attachdb(view->cache, &view->cachedb); +#ifdef BIND9 if (view->acache != NULL) dns_acache_setdb(view->acache, view->cachedb); if (view->resolver != NULL) dns_resolver_flushbadcache(view->resolver, NULL); +#endif dns_adb_flush(view->adb); return (ISC_R_SUCCESS); @@ -1437,11 +1650,13 @@ dns_view_getrootdelonly(dns_view_t *view) { return (view->rootdelonly); } +#ifdef BIND9 isc_result_t dns_view_freezezones(dns_view_t *view, isc_boolean_t value) { REQUIRE(DNS_VIEW_VALID(view)); return (dns_zt_freezezones(view->zonetable, value)); } +#endif void dns_view_setresstats(dns_view_t *view, isc_stats_t *stats) { @@ -1478,3 +1693,97 @@ dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp) { if (view->resquerystats != NULL) dns_stats_attach(view->resquerystats, statsp); } + +isc_result_t +dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx) { + REQUIRE(DNS_VIEW_VALID(view)); + if (view->secroots_priv != NULL) + dns_keytable_detach(&view->secroots_priv); + return (dns_keytable_create(mctx, &view->secroots_priv)); +} + +isc_result_t +dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp) { + REQUIRE(DNS_VIEW_VALID(view)); + REQUIRE(ktp != NULL && *ktp == NULL); + if (view->secroots_priv == NULL) + return (ISC_R_NOTFOUND); + dns_keytable_attach(view->secroots_priv, ktp); + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_view_issecuredomain(dns_view_t *view, dns_name_t *name, + isc_boolean_t *secure_domain) { + REQUIRE(DNS_VIEW_VALID(view)); + return (dns_keytable_issecuredomain(view->secroots_priv, name, + secure_domain)); +} + +void +dns_view_untrust(dns_view_t *view, dns_name_t *keyname, + dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) +{ + isc_result_t result; + unsigned char data[4096]; + dns_rdata_t rdata = DNS_RDATA_INIT; + isc_buffer_t buffer; + dst_key_t *key = NULL; + dns_keytable_t *sr = NULL; + + /* + * Clear the revoke bit, if set, so that the key will match what's + * in secroots now. + */ + dnskey->flags &= ~DNS_KEYFLAG_REVOKE; + + /* Convert dnskey to DST key. */ + isc_buffer_init(&buffer, data, sizeof(data)); + dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, + dns_rdatatype_dnskey, dnskey, &buffer); + result = dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &key); + if (result != ISC_R_SUCCESS) + return; + result = dns_view_getsecroots(view, &sr); + if (result == ISC_R_SUCCESS) { + dns_keytable_deletekeynode(sr, key); + dns_keytable_detach(&sr); + } + dst_key_free(&key); +} + +#define NZF ".nzf" + +void +dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx, + void (*cfg_destroy)(void **)) +{ + REQUIRE(DNS_VIEW_VALID(view)); + REQUIRE((cfgctx != NULL && cfg_destroy != NULL) || !allow); + +#ifdef BIND9 + if (view->new_zone_file != NULL) { + isc_mem_free(view->mctx, view->new_zone_file); + view->new_zone_file = NULL; + } + + if (view->new_zone_config != NULL) { + view->cfg_destroy(&view->new_zone_config); + view->cfg_destroy = NULL; + } + + if (allow) { + char buffer[ISC_SHA256_DIGESTSTRINGLENGTH + sizeof(NZF)]; + isc_sha256_data((void *)view->name, strlen(view->name), buffer); + /* Truncate the hash at 16 chars; full length is overkill */ + isc_string_printf(buffer + 16, sizeof(NZF), "%s", NZF); + view->new_zone_file = isc_mem_strdup(view->mctx, buffer); + view->new_zone_config = cfgctx; + view->cfg_destroy = cfg_destroy; + } +#else + UNUSED(allow); + UNUSED(cfgctx); + UNUSED(cfg_destroy); +#endif +} |