static void levent_destroy(isc_event_t *event) { dns_lookupevent_t *levent; isc_mem_t *mctx; REQUIRE(event->ev_type == DNS_EVENT_LOOKUPDONE); mctx = event->ev_destroy_arg; levent = (dns_lookupevent_t *)event; if (levent->name != NULL) { if (dns_name_dynamic(levent->name)) dns_name_free(levent->name, mctx); isc_mem_put(mctx, levent->name, sizeof(dns_name_t)); } if (levent->rdataset != NULL) { dns_rdataset_disassociate(levent->rdataset); isc_mem_put(mctx, levent->rdataset, sizeof(dns_rdataset_t)); } if (levent->sigrdataset != NULL) { dns_rdataset_disassociate(levent->sigrdataset); isc_mem_put(mctx, levent->sigrdataset, sizeof(dns_rdataset_t)); } if (levent->node != NULL) dns_db_detachnode(levent->db, &levent->node); if (levent->db != NULL) dns_db_detach(&levent->db); isc_mem_put(mctx, event, event->ev_size); }
/* * seek_emty: walk database starting at an empty nonterminal node * (should fail) */ static void test_seek_nx(const atf_tc_t *tc) { isc_result_t result; dns_db_t *db = NULL; dns_dbiterator_t *iter = NULL; dns_name_t *seekname; dns_fixedname_t f1; UNUSED(tc); dns_fixedname_init(&f1); seekname = dns_fixedname_name(&f1); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, atf_tc_get_md_var(tc, "X-filename")); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_createiterator(db, 0, &iter); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = make_name("nonexistent." TEST_ORIGIN, seekname); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_dbiterator_seek(iter, seekname); ATF_CHECK_EQ(result, ISC_R_NOTFOUND); dns_dbiterator_destroy(&iter); dns_db_detach(&db); dns_test_end(); }
ATF_TC_BODY(getoriginnode, tc) { dns_db_t *db = NULL; dns_dbnode_t *node = NULL; isc_mem_t *mymctx = NULL; isc_result_t result; result = isc_mem_create(0, 0, &mymctx); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = isc_hash_create(mymctx, NULL, 256); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_create(mymctx, "rbt", dns_rootname, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_getoriginnode(db, &node); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_db_detachnode(db, &node); result = dns_db_getoriginnode(db, &node); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_db_detachnode(db, &node); dns_db_detach(&db); isc_mem_detach(&mymctx); }
static void xfrout_ctx_destroy(xfrout_ctx_t **xfrp) { xfrout_ctx_t *xfr = *xfrp; INSIST(xfr->sends == 0); xfr->client->shutdown = NULL; xfr->client->shutdown_arg = NULL; if (xfr->stream != NULL) xfr->stream->methods->destroy(&xfr->stream); if (xfr->buf.base != NULL) isc_mem_put(xfr->mctx, xfr->buf.base, xfr->buf.length); if (xfr->txmem != NULL) isc_mem_put(xfr->mctx, xfr->txmem, xfr->txmemlen); if (xfr->lasttsig != NULL) isc_buffer_free(&xfr->lasttsig); if (xfr->quota != NULL) isc_quota_detach(&xfr->quota); if (xfr->ver != NULL) dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE); if (xfr->zone != NULL) dns_zone_detach(&xfr->zone); if (xfr->db != NULL) dns_db_detach(&xfr->db); ns_client_detach(&xfr->client); isc_mem_put(xfr->mctx, xfr, sizeof(*xfr)); *xfrp = NULL; }
/* !!! Verify that internal RBTDB cannot leak somehow. */ static void ATTR_NONNULLS free_ldapdb(ldapdb_t *ldapdb) { #ifdef RBTDB_DEBUG isc_result_t result; dns_dbversion_t *version = NULL; dns_name_t *zone_name = dns_db_origin(&ldapdb->common); ld_string_t *file_name = NULL; CHECK(zr_get_zone_path(ldapdb->common.mctx, ldap_instance_getsettings_local(ldapdb->ldap_inst), zone_name, "ldapdb.dump", &file_name)); dns_db_currentversion(ldapdb->rbtdb, &version); log_info("dump to '%s' started", str_buf(file_name)); result = dns_db_dump2(ldapdb->rbtdb, version, str_buf(file_name), dns_masterformat_text); log_info("dump to '%s' finished: %s", str_buf(file_name), isc_result_totext(result)); dns_db_closeversion(ldapdb->rbtdb, &version, ISC_FALSE); cleanup: if (result != ISC_R_SUCCESS) { log_error_r("dump to '%s' failed", (file_name && str_buf(file_name)) ? str_buf(file_name) : "<NULL>"); } str_destroy(&file_name); #endif dns_db_detach(&ldapdb->rbtdb); dns_name_free(&ldapdb->common.origin, ldapdb->common.mctx); RUNTIME_CHECK(isc_mutex_destroy(&ldapdb->newversion_lock) == ISC_R_SUCCESS); isc_mem_putanddetach(&ldapdb->common.mctx, ldapdb, sizeof(*ldapdb)); }
static void dbdetach(void *data, void *arg) { dns_db_t *db = data; UNUSED(arg); dns_db_detach(&db); }
static void free_sampledb(sampledb_t *sampledb) { REQUIRE(VALID_SAMPLEDB(sampledb)); dns_db_detach(&sampledb->rbtdb); dns_name_free(&sampledb->common.origin, sampledb->common.mctx); isc_mem_putanddetach(&sampledb->common.mctx, sampledb, sizeof(*sampledb)); }
void dns_dbtable_removedefault(dns_dbtable_t *dbtable) { REQUIRE(VALID_DBTABLE(dbtable)); RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); dns_db_detach(&dbtable->default_db); RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); }
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); } }
/* seek: walk database starting at a particular node */ static void test_seek(const atf_tc_t *tc) { isc_result_t result; dns_db_t *db = NULL; dns_dbiterator_t *iter = NULL; dns_dbnode_t *node = NULL; dns_name_t *name, *seekname; dns_fixedname_t f1, f2; int i = 0; UNUSED(tc); dns_fixedname_init(&f1); name = dns_fixedname_name(&f1); dns_fixedname_init(&f2); seekname = dns_fixedname_name(&f2); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, atf_tc_get_md_var(tc, "X-filename")); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_createiterator(db, 0, &iter); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = make_name("c." TEST_ORIGIN, seekname); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_dbiterator_seek(iter, seekname); ATF_CHECK_EQ(result, ISC_R_SUCCESS); while (result == ISC_R_SUCCESS) { result = dns_dbiterator_current(iter, &node, name); if (result == DNS_R_NEWORIGIN) result = ISC_R_SUCCESS; ATF_CHECK_EQ(result, ISC_R_SUCCESS); dns_db_detachnode(db, &node); result = dns_dbiterator_next(iter); i++; } ATF_CHECK_EQ(i, atoi(atf_tc_get_md_var(tc, "X-nodes"))); dns_dbiterator_destroy(&iter); dns_db_detach(&db); dns_test_end(); }
static void iteration_test(const char* file, unsigned int expected) { isc_result_t result; dns_db_t *db = NULL; unsigned int iterations; result = dns_test_loaddb(&db, dns_dbtype_zone, "test", file); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_nsec3_maxiterations(db, NULL, mctx, &iterations); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); ATF_CHECK_EQ(iterations, expected); dns_db_detach(&db); }
static void unload_all(void) { dbinfo *dbi, *dbi_next; for (dbi = ISC_LIST_HEAD(dbs); dbi != NULL; dbi = dbi_next) { dbi_next = ISC_LIST_NEXT(dbi, link); if (dns_db_iszone(dbi->db)) dns_dbtable_remove(dbtable, dbi->db); else { INSIST(dbi == cache_dbi); dns_dbtable_removedefault(dbtable); cache_dbi = NULL; } dns_db_detach(&dbi->db); ISC_LIST_UNLINK(dbs, dbi, link); isc_mem_put(mctx, dbi, sizeof(*dbi)); } }
/* * Set up a DLZ zone as writeable */ isc_result_t ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone, dns_rdataclass_t rdclass, dns_name_t *name) { dns_db_t *db = NULL; isc_time_t now; isc_result_t result; TIME_NOW(&now); dns_zone_settype(zone, dns_zone_dlz); result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db); if (result != ISC_R_SUCCESS) return result; result = dns_zone_dlzpostload(zone, db); dns_db_detach(&db); return result; }
static isc_result_t loadset(const char *filename, dns_rdataset_t *rdataset) { isc_result_t result; dns_db_t *db = NULL; dns_dbnode_t *node = NULL; char setname[DNS_NAME_FORMATSIZE]; dns_name_format(name, setname, sizeof(setname)); result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, rdclass, 0, NULL, &db); if (result != ISC_R_SUCCESS) fatal("can't create database"); if (strcmp(filename, "-") == 0) { db_load_from_stream(db, stdin); filename = "input"; } else { result = dns_db_load(db, filename); if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) fatal("can't load %s: %s", filename, isc_result_totext(result)); } result = dns_db_findnode(db, name, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) fatal("can't find %s node in %s", setname, filename); result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0, rdataset, NULL); if (result == ISC_R_NOTFOUND) fatal("no DNSKEY RR for %s in %s", setname, filename); else if (result != ISC_R_SUCCESS) fatal("dns_db_findrdataset"); if (node != NULL) dns_db_detachnode(db, &node); if (db != NULL) dns_db_detach(&db); return (result); }
/* create: make sure we can create a dbiterator */ static void test_create(const atf_tc_t *tc) { isc_result_t result; dns_db_t *db = NULL; dns_dbiterator_t *iter = NULL; result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, atf_tc_get_md_var(tc, "X-filename")); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_createiterator(db, 0, &iter); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_dbiterator_destroy(&iter); dns_db_detach(&db); dns_test_end(); }
/* reverse: walk database backwards */ static void test_reverse(const atf_tc_t *tc) { isc_result_t result; dns_db_t *db = NULL; dns_dbiterator_t *iter = NULL; dns_dbnode_t *node = NULL; dns_name_t *name; dns_fixedname_t f; int i = 0; UNUSED(tc); dns_fixedname_init(&f); name = dns_fixedname_name(&f); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN, atf_tc_get_md_var(tc, "X-filename")); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_createiterator(db, 0, &iter); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); for (result = dns_dbiterator_last(iter); result == ISC_R_SUCCESS; result = dns_dbiterator_prev(iter)) { result = dns_dbiterator_current(iter, &node, name); if (result == DNS_R_NEWORIGIN) result = ISC_R_SUCCESS; ATF_CHECK_EQ(result, ISC_R_SUCCESS); dns_db_detachnode(db, &node); i++; } ATF_CHECK_EQ(i, 12); dns_dbiterator_destroy(&iter); dns_db_detach(&db); dns_test_end(); }
static inline void dbtable_free(dns_dbtable_t *dbtable) { /* * Caller must ensure that it is safe to call. */ RWLOCK(&dbtable->tree_lock, isc_rwlocktype_write); if (dbtable->default_db != NULL) dns_db_detach(&dbtable->default_db); dns_rbt_destroy(&dbtable->rbt); RWUNLOCK(&dbtable->tree_lock, isc_rwlocktype_write); isc_rwlock_destroy(&dbtable->tree_lock); dbtable->magic = 0; isc_mem_putanddetach(&dbtable->mctx, dbtable, sizeof(*dbtable)); }
static void xfrout_ctx_destroy(xfrout_ctx_t **xfrp) { xfrout_ctx_t *xfr = *xfrp; ns_client_t *client = NULL; INSIST(xfr->sends == 0); xfr->client->shutdown = NULL; xfr->client->shutdown_arg = NULL; if (xfr->stream != NULL) xfr->stream->methods->destroy(&xfr->stream); if (xfr->buf.base != NULL) isc_mem_put(xfr->mctx, xfr->buf.base, xfr->buf.length); if (xfr->txmem != NULL) isc_mem_put(xfr->mctx, xfr->txmem, xfr->txmemlen); if (xfr->lasttsig != NULL) isc_buffer_free(&xfr->lasttsig); if (xfr->quota != NULL) isc_quota_detach(&xfr->quota); if (xfr->ver != NULL) dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE); if (xfr->zone != NULL) dns_zone_detach(&xfr->zone); if (xfr->db != NULL) dns_db_detach(&xfr->db); /* * We want to detch the client after we have released the memory * context as ns_client_detach checks the memory reference count. */ ns_client_attach(xfr->client, &client); ns_client_detach(&xfr->client); isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); ns_client_detach(&client); *xfrp = NULL; }
static isc_result_t configure_hint(const char *zfile, const char *zclass, isc_mem_t *mctx) { isc_result_t result; dns_db_t *db = NULL; dns_rdataclass_t rdclass; isc_textregion_t r; if (zfile == NULL) return (ISC_R_FAILURE); DE_CONST(zclass, r.base); r.length = strlen(zclass); result = dns_rdataclass_fromtext(&rdclass, &r); if (result != ISC_R_SUCCESS) return (result); result = dns_rootns_create(mctx, rdclass, zfile, &db); if (result != ISC_R_SUCCESS) return (result); dns_db_detach(&db); return (ISC_R_SUCCESS); }
static void create_view(void) { dns_cache_t *cache; isc_result_t result; /* * View. */ view = NULL; result = dns_view_create(mctx, dns_rdataclass_in, "_default", &view); check_result(result, "dns_view_create"); /* * Cache. */ cache = NULL; result = dns_cache_create(mctx, taskmgr, timermgr, dns_rdataclass_in, "rbt", 0, NULL, &cache); check_result(result, "dns_cache_create"); dns_view_setcache(view, cache); dns_cache_detach(&cache); { unsigned int attrs; isc_sockaddr_t any4, any6; dns_dispatch_t *disp4 = NULL; dns_dispatch_t *disp6 = NULL; isc_sockaddr_any(&any4); isc_sockaddr_any6(&any6); attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP; RUNTIME_CHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &any4, 512, 6, 1024, 17, 19, attrs, attrs, &disp4) == ISC_R_SUCCESS); INSIST(disp4 != NULL); attrs = DNS_DISPATCHATTR_IPV6 | DNS_DISPATCHATTR_UDP; RUNTIME_CHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &any6, 512, 6, 1024, 17, 19, attrs, attrs, &disp6) == ISC_R_SUCCESS); INSIST(disp6 != NULL); RUNTIME_CHECK(dns_view_createresolver(view, taskmgr, 10, 1, socketmgr, timermgr, 0, dispatchmgr, disp4, disp6) == ISC_R_SUCCESS); } rootdb = NULL; result = dns_rootns_create(mctx, dns_rdataclass_in, NULL, &rootdb); check_result(result, "dns_rootns_create()"); dns_view_sethints(view, rootdb); dns_db_detach(&rootdb); dns_view_freeze(view); }
void ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) { isc_result_t result; dns_name_t *question_name; dns_rdataset_t *question_rdataset; dns_zone_t *zone = NULL, *raw = NULL, *mayberaw; dns_db_t *db = NULL; dns_dbversion_t *ver = NULL; dns_rdataclass_t question_class; rrstream_t *soa_stream = NULL; rrstream_t *data_stream = NULL; rrstream_t *stream = NULL; dns_difftuple_t *current_soa_tuple = NULL; dns_name_t *soa_name; dns_rdataset_t *soa_rdataset; dns_rdata_t soa_rdata = DNS_RDATA_INIT; isc_boolean_t have_soa = ISC_FALSE; const char *mnemonic = NULL; isc_mem_t *mctx = client->mctx; dns_message_t *request = client->message; xfrout_ctx_t *xfr = NULL; isc_quota_t *quota = NULL; dns_transfer_format_t format = client->view->transfer_format; isc_netaddr_t na; dns_peer_t *peer = NULL; isc_buffer_t *tsigbuf = NULL; char *journalfile; char msg[NS_CLIENT_ACLMSGSIZE("zone transfer")]; char keyname[DNS_NAME_FORMATSIZE]; isc_boolean_t is_poll = ISC_FALSE; isc_boolean_t is_dlz = ISC_FALSE; isc_boolean_t is_ixfr = ISC_FALSE; isc_uint32_t begin_serial = 0, current_serial; switch (reqtype) { case dns_rdatatype_axfr: mnemonic = "AXFR"; break; case dns_rdatatype_ixfr: mnemonic = "IXFR"; break; default: INSIST(0); break; } ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT, ISC_LOG_DEBUG(6), "%s request", mnemonic); /* * Apply quota. */ result = isc_quota_attach(&ns_g_server->xfroutquota, "a); if (result != ISC_R_SUCCESS) { isc_log_write(XFROUT_COMMON_LOGARGS, ISC_LOG_WARNING, "%s request denied: %s", mnemonic, isc_result_totext(result)); goto failure; } /* * Interpret the question section. */ result = dns_message_firstname(request, DNS_SECTION_QUESTION); INSIST(result == ISC_R_SUCCESS); /* * The question section must contain exactly one question, and * it must be for AXFR/IXFR as appropriate. */ question_name = NULL; dns_message_currentname(request, DNS_SECTION_QUESTION, &question_name); question_rdataset = ISC_LIST_HEAD(question_name->list); question_class = question_rdataset->rdclass; INSIST(question_rdataset->type == reqtype); if (ISC_LIST_NEXT(question_rdataset, link) != NULL) FAILC(DNS_R_FORMERR, "multiple questions"); result = dns_message_nextname(request, DNS_SECTION_QUESTION); if (result != ISC_R_NOMORE) FAILC(DNS_R_FORMERR, "multiple questions"); result = dns_zt_find(client->view->zonetable, question_name, 0, NULL, &zone); if (result != ISC_R_SUCCESS) { /* * Normal zone table does not have a match. * Try the DLZ database */ // Temporary: only searching the first DLZ database if (! ISC_LIST_EMPTY(client->view->dlz_searched)) { result = dns_dlzallowzonexfr(client->view, question_name, &client->peeraddr, &db); pfilter_notify(result, client, "zonexfr"); if (result == ISC_R_NOPERM) { char _buf1[DNS_NAME_FORMATSIZE]; char _buf2[DNS_RDATACLASS_FORMATSIZE]; result = DNS_R_REFUSED; dns_name_format(question_name, _buf1, sizeof(_buf1)); dns_rdataclass_format(question_class, _buf2, sizeof(_buf2)); ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_XFER_OUT, ISC_LOG_ERROR, "zone transfer '%s/%s' denied", _buf1, _buf2); goto failure; } if (result != ISC_R_SUCCESS) FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", question_name, question_class); is_dlz = ISC_TRUE; } else { /* * not DLZ and not in normal zone table, we are * not authoritative */ FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", question_name, question_class); } } else { /* zone table has a match */ switch(dns_zone_gettype(zone)) { /* Master and slave zones are OK for transfer. */ case dns_zone_master: case dns_zone_slave: case dns_zone_dlz: break; default: FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", question_name, question_class); } CHECK(dns_zone_getdb(zone, &db)); dns_db_currentversion(db, &ver); } xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), "%s question section OK", mnemonic); /* * Check the authority section. Look for a SOA record with * the same name and class as the question. */ for (result = dns_message_firstname(request, DNS_SECTION_AUTHORITY); result == ISC_R_SUCCESS; result = dns_message_nextname(request, DNS_SECTION_AUTHORITY)) { soa_name = NULL; dns_message_currentname(request, DNS_SECTION_AUTHORITY, &soa_name); /* * Ignore data whose owner name is not the zone apex. */ if (! dns_name_equal(soa_name, question_name)) continue; for (soa_rdataset = ISC_LIST_HEAD(soa_name->list); soa_rdataset != NULL; soa_rdataset = ISC_LIST_NEXT(soa_rdataset, link)) { /* * Ignore non-SOA data. */ if (soa_rdataset->type != dns_rdatatype_soa) continue; if (soa_rdataset->rdclass != question_class) continue; CHECK(dns_rdataset_first(soa_rdataset)); dns_rdataset_current(soa_rdataset, &soa_rdata); result = dns_rdataset_next(soa_rdataset); if (result == ISC_R_SUCCESS) FAILC(DNS_R_FORMERR, "IXFR authority section " "has multiple SOAs"); have_soa = ISC_TRUE; goto got_soa; } } got_soa: if (result != ISC_R_NOMORE) CHECK(result); xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), "%s authority section OK", mnemonic); /* * If not a DLZ zone, decide whether to allow this transfer. */ if (!is_dlz) { ns_client_aclmsg("zone transfer", question_name, reqtype, client->view->rdclass, msg, sizeof(msg)); CHECK(ns_client_checkacl(client, NULL, msg, dns_zone_getxfracl(zone), ISC_TRUE, ISC_LOG_ERROR)); } /* * AXFR over UDP is not possible. */ if (reqtype == dns_rdatatype_axfr && (client->attributes & NS_CLIENTATTR_TCP) == 0) FAILC(DNS_R_FORMERR, "attempted AXFR over UDP"); /* * Look up the requesting server in the peer table. */ isc_netaddr_fromsockaddr(&na, &client->peeraddr); (void)dns_peerlist_peerbyaddr(client->view->peers, &na, &peer); /* * Decide on the transfer format (one-answer or many-answers). */ if (peer != NULL) (void)dns_peer_gettransferformat(peer, &format); /* * Get a dynamically allocated copy of the current SOA. */ if (is_dlz) dns_db_currentversion(db, &ver); CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, ¤t_soa_tuple)); current_serial = dns_soa_getserial(¤t_soa_tuple->rdata); if (reqtype == dns_rdatatype_ixfr) { isc_boolean_t provide_ixfr; /* * Outgoing IXFR may have been disabled for this peer * or globally. */ provide_ixfr = client->view->provideixfr; if (peer != NULL) (void) dns_peer_getprovideixfr(peer, &provide_ixfr); if (provide_ixfr == ISC_FALSE) goto axfr_fallback; if (! have_soa) FAILC(DNS_R_FORMERR, "IXFR request missing SOA"); begin_serial = dns_soa_getserial(&soa_rdata); /* * RFC1995 says "If an IXFR query with the same or * newer version number than that of the server * is received, it is replied to with a single SOA * record of the server's current version, just as * in AXFR". The claim about AXFR is incorrect, * but other than that, we do as the RFC says. * * Sending a single SOA record is also how we refuse * IXFR over UDP (currently, we always do). */ if (DNS_SERIAL_GE(begin_serial, current_serial) || (client->attributes & NS_CLIENTATTR_TCP) == 0) { CHECK(soa_rrstream_create(mctx, db, ver, &stream)); is_poll = ISC_TRUE; goto have_stream; } journalfile = is_dlz ? NULL : dns_zone_getjournal(zone); if (journalfile != NULL) result = ixfr_rrstream_create(mctx, journalfile, begin_serial, current_serial, &data_stream); else result = ISC_R_NOTFOUND; if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) { xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(4), "IXFR version not in journal, " "falling back to AXFR"); mnemonic = "AXFR-style IXFR"; goto axfr_fallback; } CHECK(result); is_ixfr = ISC_TRUE; } else { axfr_fallback: CHECK(axfr_rrstream_create(mctx, db, ver, &data_stream)); } /* * Bracket the data stream with SOAs. */ CHECK(soa_rrstream_create(mctx, db, ver, &soa_stream)); CHECK(compound_rrstream_create(mctx, &soa_stream, &data_stream, &stream)); soa_stream = NULL; data_stream = NULL; have_stream: CHECK(dns_message_getquerytsig(request, mctx, &tsigbuf)); /* * Create the xfrout context object. This transfers the ownership * of "stream", "db", "ver", and "quota" to the xfrout context object. */ if (is_dlz) CHECK(xfrout_ctx_create(mctx, client, request->id, question_name, reqtype, question_class, zone, db, ver, quota, stream, dns_message_gettsigkey(request), tsigbuf, 3600, 3600, (format == dns_many_answers) ? ISC_TRUE : ISC_FALSE, &xfr)); else CHECK(xfrout_ctx_create(mctx, client, request->id, question_name, reqtype, question_class, zone, db, ver, quota, stream, dns_message_gettsigkey(request), tsigbuf, dns_zone_getmaxxfrout(zone), dns_zone_getidleout(zone), (format == dns_many_answers) ? ISC_TRUE : ISC_FALSE, &xfr)); xfr->mnemonic = mnemonic; stream = NULL; quota = NULL; CHECK(xfr->stream->methods->first(xfr->stream)); if (xfr->tsigkey != NULL) dns_name_format(&xfr->tsigkey->name, keyname, sizeof(keyname)); else keyname[0] = '\0'; if (is_poll) xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(1), "IXFR poll up to date%s%s", (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); else if (is_ixfr) xfrout_log1(client, question_name, question_class, ISC_LOG_INFO, "%s started%s%s (serial %u -> %u)", mnemonic, (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname, begin_serial, current_serial); else xfrout_log1(client, question_name, question_class, ISC_LOG_INFO, "%s started%s%s (serial %u)", mnemonic, (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname, current_serial); if (zone != NULL) { dns_zone_getraw(zone, &raw); mayberaw = (raw != NULL) ? raw : zone; if ((client->attributes & NS_CLIENTATTR_WANTEXPIRE) != 0 && dns_zone_gettype(mayberaw) == dns_zone_slave) { isc_time_t expiretime; isc_uint32_t secs; dns_zone_getexpiretime(zone, &expiretime); secs = isc_time_seconds(&expiretime); if (secs >= client->now && result == ISC_R_SUCCESS) { client->attributes |= NS_CLIENTATTR_HAVEEXPIRE; client->expire = secs - client->now; } } if (raw != NULL) dns_zone_detach(&raw); } /* * Hand the context over to sendstream(). Set xfr to NULL; * sendstream() is responsible for either passing the * context on to a later event handler or destroying it. */ sendstream(xfr); xfr = NULL; result = ISC_R_SUCCESS; failure: if (result == DNS_R_REFUSED) inc_stats(zone, dns_nsstatscounter_xfrrej); if (quota != NULL) isc_quota_detach("a); if (current_soa_tuple != NULL) dns_difftuple_free(¤t_soa_tuple); if (stream != NULL) stream->methods->destroy(&stream); if (soa_stream != NULL) soa_stream->methods->destroy(&soa_stream); if (data_stream != NULL) data_stream->methods->destroy(&data_stream); if (ver != NULL) dns_db_closeversion(db, &ver, ISC_FALSE); if (db != NULL) dns_db_detach(&db); if (zone != NULL) dns_zone_detach(&zone); /* XXX kludge */ if (xfr != NULL) { xfrout_fail(xfr, result, "setting up zone transfer"); } else if (result != ISC_R_SUCCESS) { ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT, ISC_LOG_DEBUG(3), "zone transfer setup failed"); ns_client_error(client, result); } }
isc_result_t dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *filename, dns_db_t **target) { isc_result_t result, eresult; isc_buffer_t source; unsigned int len; dns_rdatacallbacks_t callbacks; dns_db_t *db = NULL; REQUIRE(target != NULL && *target == NULL); result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, rdclass, 0, NULL, &db); if (result != ISC_R_SUCCESS) goto failure; len = strlen(root_ns); isc_buffer_init(&source, root_ns, len); isc_buffer_add(&source, len); dns_rdatacallbacks_init(&callbacks); result = dns_db_beginload(db, &callbacks); if (result != ISC_R_SUCCESS) goto failure; if (filename != NULL) { /* * Load the hints from the specified filename. */ result = dns_master_loadfile(filename, &db->origin, &db->origin, db->rdclass, DNS_MASTER_HINT, &callbacks, db->mctx); } else if (rdclass == dns_rdataclass_in) { /* * Default to using the Internet root servers. */ result = dns_master_loadbuffer(&source, &db->origin, &db->origin, db->rdclass, DNS_MASTER_HINT, &callbacks, db->mctx); } else result = ISC_R_NOTFOUND; eresult = dns_db_endload(db, &callbacks); if (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) result = eresult; if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) goto failure; if (check_hints(db) != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, "extra data in root hints '%s'", (filename != NULL) ? filename : "<BUILT-IN>"); *target = db; return (ISC_R_SUCCESS); failure: isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_HINTS, ISC_LOG_ERROR, "could not configure root hints from " "'%s': %s", (filename != NULL) ? filename : "<BUILT-IN>", isc_result_totext(result)); if (db != NULL) dns_db_detach(&db); return (result); }
static void query(void) { char buf[1024]; dns_fixedname_t name; dns_fixedname_t found; dns_db_t *db; char *s; isc_buffer_t buffer; isc_result_t result; dns_rdataset_t rdataset; dns_rdataset_t sigset; fd_set rfdset; db = NULL; result = dns_zone_getdb(zone, &db); if (result != ISC_R_SUCCESS) { fprintf(stderr, "%s() returned %s\n", "dns_zone_getdb", dns_result_totext(result)); return; } dns_fixedname_init(&found); dns_rdataset_init(&rdataset); dns_rdataset_init(&sigset); do { fprintf(stdout, "zone_test "); fflush(stdout); FD_ZERO(&rfdset); FD_SET(0, &rfdset); select(1, &rfdset, NULL, NULL, NULL); if (fgets(buf, sizeof(buf), stdin) == NULL) { fprintf(stdout, "\n"); break; } buf[sizeof(buf) - 1] = '\0'; s = strchr(buf, '\n'); if (s != NULL) *s = '\0'; s = strchr(buf, '\r'); if (s != NULL) *s = '\0'; if (strcmp(buf, "dump") == 0) { dns_zone_dumptostream(zone, stdout); continue; } if (strlen(buf) == 0U) continue; dns_fixedname_init(&name); isc_buffer_init(&buffer, buf, strlen(buf)); isc_buffer_add(&buffer, strlen(buf)); result = dns_name_fromtext(dns_fixedname_name(&name), &buffer, dns_rootname, 0, NULL); ERRCONT(result, "dns_name_fromtext"); result = dns_db_find(db, dns_fixedname_name(&name), NULL /*vesion*/, dns_rdatatype_a, 0 /*options*/, 0 /*time*/, NULL /*nodep*/, dns_fixedname_name(&found), &rdataset, &sigset); fprintf(stderr, "%s() returned %s\n", "dns_db_find", dns_result_totext(result)); switch (result) { case DNS_R_DELEGATION: print_rdataset(dns_fixedname_name(&found), &rdataset); break; case ISC_R_SUCCESS: print_rdataset(dns_fixedname_name(&name), &rdataset); break; default: break; } if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (dns_rdataset_isassociated(&sigset)) dns_rdataset_disassociate(&sigset); } while (1); dns_rdataset_invalidate(&rdataset); dns_db_detach(&db); }
int main(int argc, char *argv[]) { dns_db_t *db; dns_dbnode_t *node; isc_result_t result; dns_name_t name; dns_offsets_t offsets; size_t len; isc_buffer_t source, target; char s[1000]; char b[255]; dns_rdataset_t rdataset, sigrdataset; int ch; dns_rdatatype_t type = 1; isc_boolean_t printnode = ISC_FALSE; isc_boolean_t addmode = ISC_FALSE; isc_boolean_t delmode = ISC_FALSE; isc_boolean_t holdmode = ISC_FALSE; isc_boolean_t verbose = ISC_FALSE; isc_boolean_t done = ISC_FALSE; isc_boolean_t quiet = ISC_FALSE; isc_boolean_t time_lookups = ISC_FALSE; isc_boolean_t found_as; isc_boolean_t find_zonecut = ISC_FALSE; isc_boolean_t noexact_zonecut = ISC_FALSE; int i, v; dns_rdatasetiter_t *rdsiter; char t1[256]; char t2[256]; isc_buffer_t tb1, tb2; isc_region_t r1, r2; dns_fixedname_t foundname; dns_name_t *fname; unsigned int options = 0, zcoptions; isc_time_t start, finish; char *origintext; dbinfo *dbi; dns_dbversion_t *version; dns_name_t *origin; size_t memory_quota = 0; dns_trust_t trust = 0; unsigned int addopts; isc_log_t *lctx = NULL; size_t n; dns_result_register(); RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); RUNTIME_CHECK(dns_dbtable_create(mctx, dns_rdataclass_in, &dbtable) == ISC_R_SUCCESS); strcpy(dbtype, "rbt"); while ((ch = isc_commandline_parse(argc, argv, "c:d:t:z:P:Q:glpqvT")) != -1) { switch (ch) { case 'c': result = load(isc_commandline_argument, ".", ISC_TRUE); if (result != ISC_R_SUCCESS) printf("cache load(%s) %08x: %s\n", isc_commandline_argument, result, isc_result_totext(result)); break; case 'd': n = strlcpy(dbtype, isc_commandline_argument, sizeof(dbtype)); if (n >= sizeof(dbtype)) { fprintf(stderr, "bad db type '%s'\n", isc_commandline_argument); exit(1); } break; case 'g': options |= (DNS_DBFIND_GLUEOK|DNS_DBFIND_VALIDATEGLUE); break; case 'l': RUNTIME_CHECK(isc_log_create(mctx, &lctx, NULL) == ISC_R_SUCCESS); isc_log_setcontext(lctx); dns_log_init(lctx); dns_log_setcontext(lctx); break; case 'q': quiet = ISC_TRUE; verbose = ISC_FALSE; break; case 'p': printnode = ISC_TRUE; break; case 'P': pause_every = atoi(isc_commandline_argument); break; case 'Q': memory_quota = atoi(isc_commandline_argument); isc_mem_setquota(mctx, memory_quota); break; case 't': type = atoi(isc_commandline_argument); break; case 'T': time_lookups = ISC_TRUE; break; case 'v': verbose = ISC_TRUE; break; case 'z': origintext = strrchr(isc_commandline_argument, '/'); if (origintext == NULL) origintext = isc_commandline_argument; else origintext++; /* Skip '/'. */ result = load(isc_commandline_argument, origintext, ISC_FALSE); if (result != ISC_R_SUCCESS) printf("zone load(%s) %08x: %s\n", isc_commandline_argument, result, isc_result_totext(result)); break; } } argc -= isc_commandline_index; argv += isc_commandline_index; POST(argv); if (argc != 0) printf("ignoring trailing arguments\n"); /* * Some final initialization... */ dns_fixedname_init(&foundname); fname = dns_fixedname_name(&foundname); dbi = NULL; origin = dns_rootname; version = NULL; if (time_lookups) { TIME_NOW(&start); } while (!done) { if (!quiet) printf("\n"); if (fgets(s, sizeof(s), stdin) == NULL) { done = ISC_TRUE; continue; } len = strlen(s); if (len > 0U && s[len - 1] == '\n') { s[len - 1] = '\0'; len--; } if (verbose && dbi != NULL) { if (dbi->wversion != NULL) printf("future version (%p)\n", dbi->wversion); for (i = 0; i < dbi->rcount; i++) if (dbi->rversions[i] != NULL) printf("open version %d (%p)\n", i, dbi->rversions[i]); } dns_name_init(&name, offsets); if (strcmp(s, "!R") == 0) { DBI_CHECK(dbi); if (dbi->rcount == MAXVERSIONS) { printf("too many open versions\n"); continue; } dns_db_currentversion(dbi->db, &dbi->rversions[dbi->rcount]); printf("opened version %d\n", dbi->rcount); dbi->version = dbi->rversions[dbi->rcount]; version = dbi->version; dbi->rcount++; continue; } else if (strcmp(s, "!W") == 0) { DBI_CHECK(dbi); if (dbi->wversion != NULL) { printf("using existing future version\n"); dbi->version = dbi->wversion; version = dbi->version; continue; } result = dns_db_newversion(dbi->db, &dbi->wversion); if (result != ISC_R_SUCCESS) print_result("", result); else printf("newversion\n"); dbi->version = dbi->wversion; version = dbi->version; continue; } else if (strcmp(s, "!C") == 0) { DBI_CHECK(dbi); addmode = ISC_FALSE; delmode = ISC_FALSE; if (dbi->version == NULL) continue; if (dbi->version == dbi->wversion) { printf("closing future version\n"); dbi->wversion = NULL; } else { for (i = 0; i < dbi->rcount; i++) { if (dbi->version == dbi->rversions[i]) { dbi->rversions[i] = NULL; printf("closing open version %d\n", i); break; } } } dns_db_closeversion(dbi->db, &dbi->version, ISC_TRUE); version = NULL; continue; } else if (strcmp(s, "!X") == 0) { DBI_CHECK(dbi); addmode = ISC_FALSE; delmode = ISC_FALSE; if (dbi->version == NULL) continue; if (dbi->version == dbi->wversion) { printf("aborting future version\n"); dbi->wversion = NULL; } else { for (i = 0; i < dbi->rcount; i++) { if (dbi->version == dbi->rversions[i]) { dbi->rversions[i] = NULL; printf("closing open version %d\n", i); break; } } } dns_db_closeversion(dbi->db, &dbi->version, ISC_FALSE); version = NULL; continue; } else if (strcmp(s, "!A") == 0) { DBI_CHECK(dbi); delmode = ISC_FALSE; if (addmode) addmode = ISC_FALSE; else addmode = ISC_TRUE; printf("addmode = %s\n", addmode ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!D") == 0) { DBI_CHECK(dbi); addmode = ISC_FALSE; if (delmode) delmode = ISC_FALSE; else delmode = ISC_TRUE; printf("delmode = %s\n", delmode ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!H") == 0) { DBI_CHECK(dbi); if (holdmode) holdmode = ISC_FALSE; else holdmode = ISC_TRUE; printf("holdmode = %s\n", holdmode ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!HR") == 0) { DBI_CHECK(dbi); for (i = 0; i < dbi->hold_count; i++) dns_db_detachnode(dbi->db, &dbi->hold_nodes[i]); dbi->hold_count = 0; holdmode = ISC_FALSE; printf("held nodes have been detached\n"); continue; } else if (strcmp(s, "!VC") == 0) { DBI_CHECK(dbi); printf("switching to current version\n"); dbi->version = NULL; version = NULL; continue; } else if (strstr(s, "!V") == s) { DBI_CHECK(dbi); v = atoi(&s[2]); if (v >= dbi->rcount || v < 0) { printf("unknown open version %d\n", v); continue; } if (dbi->rversions[v] == NULL) { printf("version %d is not open\n", v); continue; } printf("switching to open version %d\n", v); dbi->version = dbi->rversions[v]; version = dbi->version; continue; } else if (strstr(s, "!TR") == s) { trust = (unsigned int)atoi(&s[3]); printf("trust level is now %u\n", (unsigned int)trust); continue; } else if (strstr(s, "!T") == s) { type = (unsigned int)atoi(&s[2]); printf("now searching for type %u\n", type); continue; } else if (strcmp(s, "!G") == 0) { if ((options & DNS_DBFIND_GLUEOK) != 0) options &= ~DNS_DBFIND_GLUEOK; else options |= DNS_DBFIND_GLUEOK; printf("glue ok = %s\n", ((options & DNS_DBFIND_GLUEOK) != 0) ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!GV") == 0) { if ((options & DNS_DBFIND_VALIDATEGLUE) != 0) options &= ~DNS_DBFIND_VALIDATEGLUE; else options |= DNS_DBFIND_VALIDATEGLUE; printf("validate glue = %s\n", ((options & DNS_DBFIND_VALIDATEGLUE) != 0) ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!WC") == 0) { if ((options & DNS_DBFIND_NOWILD) != 0) options &= ~DNS_DBFIND_NOWILD; else options |= DNS_DBFIND_NOWILD; printf("wildcard matching = %s\n", ((options & DNS_DBFIND_NOWILD) == 0) ? "TRUE" : "FALSE"); continue; } else if (strstr(s, "!LS ") == s) { DBI_CHECK(dbi); list(dbi, &s[4]); continue; } else if (strcmp(s, "!LS") == 0) { DBI_CHECK(dbi); list(dbi, NULL); continue; } else if (strstr(s, "!DU ") == s) { DBI_CHECK(dbi); result = dns_db_dump(dbi->db, dbi->version, s+4); if (result != ISC_R_SUCCESS) { printf("\n"); print_result("", result); } continue; } else if (strcmp(s, "!PN") == 0) { if (printnode) printnode = ISC_FALSE; else printnode = ISC_TRUE; printf("printnode = %s\n", printnode ? "TRUE" : "FALSE"); continue; } else if (strstr(s, "!P") == s) { DBI_CHECK(dbi); v = atoi(&s[2]); dbi->pause_every = v; continue; } else if (strcmp(s, "!+") == 0) { DBI_CHECK(dbi); dbi->ascending = ISC_TRUE; continue; } else if (strcmp(s, "!-") == 0) { DBI_CHECK(dbi); dbi->ascending = ISC_FALSE; continue; } else if (strcmp(s, "!DB") == 0) { dbi = NULL; origin = dns_rootname; version = NULL; printf("now searching all databases\n"); continue; } else if (strncmp(s, "!DB ", 4) == 0) { dbi = select_db(s+4); if (dbi != NULL) { db = dbi->db; origin = dns_db_origin(dbi->db); version = dbi->version; addmode = ISC_FALSE; delmode = ISC_FALSE; holdmode = ISC_FALSE; } else { db = NULL; version = NULL; origin = dns_rootname; printf("database not found; " "now searching all databases\n"); } continue; } else if (strcmp(s, "!ZC") == 0) { if (find_zonecut) find_zonecut = ISC_FALSE; else find_zonecut = ISC_TRUE; printf("find_zonecut = %s\n", find_zonecut ? "TRUE" : "FALSE"); continue; } else if (strcmp(s, "!NZ") == 0) { if (noexact_zonecut) noexact_zonecut = ISC_FALSE; else noexact_zonecut = ISC_TRUE; printf("noexact_zonecut = %s\n", noexact_zonecut ? "TRUE" : "FALSE"); continue; } isc_buffer_init(&source, s, len); isc_buffer_add(&source, len); isc_buffer_init(&target, b, sizeof(b)); result = dns_name_fromtext(&name, &source, origin, 0, &target); if (result != ISC_R_SUCCESS) { print_result("bad name: ", result); continue; } if (dbi == NULL) { zcoptions = 0; if (noexact_zonecut) zcoptions |= DNS_DBTABLEFIND_NOEXACT; db = NULL; result = dns_dbtable_find(dbtable, &name, zcoptions, &db); if (result != ISC_R_SUCCESS && result != DNS_R_PARTIALMATCH) { if (!quiet) { printf("\n"); print_result("", result); } continue; } isc_buffer_init(&tb1, t1, sizeof(t1)); result = dns_name_totext(dns_db_origin(db), ISC_FALSE, &tb1); if (result != ISC_R_SUCCESS) { printf("\n"); print_result("", result); dns_db_detach(&db); continue; } isc_buffer_usedregion(&tb1, &r1); printf("\ndatabase = %.*s (%s)\n", (int)r1.length, r1.base, (dns_db_iszone(db)) ? "zone" : "cache"); } node = NULL; dns_rdataset_init(&rdataset); dns_rdataset_init(&sigrdataset); if (find_zonecut && dns_db_iscache(db)) { zcoptions = options; if (noexact_zonecut) zcoptions |= DNS_DBFIND_NOEXACT; result = dns_db_findzonecut(db, &name, zcoptions, 0, &node, fname, &rdataset, &sigrdataset); } else { result = dns_db_find(db, &name, version, type, options, 0, &node, fname, &rdataset, &sigrdataset); } if (!quiet) { if (dbi != NULL) printf("\n"); print_result("", result); } found_as = ISC_FALSE; switch (result) { case ISC_R_SUCCESS: case DNS_R_GLUE: case DNS_R_CNAME: case DNS_R_ZONECUT: break; case DNS_R_DNAME: case DNS_R_DELEGATION: found_as = ISC_TRUE; break; case DNS_R_NXRRSET: if (dns_rdataset_isassociated(&rdataset)) break; if (dbi != NULL) { if (holdmode) { RUNTIME_CHECK(dbi->hold_count < MAXHOLD); dbi->hold_nodes[dbi->hold_count++] = node; node = NULL; } else dns_db_detachnode(db, &node); } else { dns_db_detachnode(db, &node); dns_db_detach(&db); } continue; case DNS_R_NXDOMAIN: if (dns_rdataset_isassociated(&rdataset)) break; /* FALLTHROUGH */ default: if (dbi == NULL) dns_db_detach(&db); if (quiet) print_result("", result); continue; } if (found_as && !quiet) { isc_buffer_init(&tb1, t1, sizeof(t1)); isc_buffer_init(&tb2, t2, sizeof(t2)); result = dns_name_totext(&name, ISC_FALSE, &tb1); if (result != ISC_R_SUCCESS) { print_result("", result); dns_db_detachnode(db, &node); if (dbi == NULL) dns_db_detach(&db); continue; } result = dns_name_totext(fname, ISC_FALSE, &tb2); if (result != ISC_R_SUCCESS) { print_result("", result); dns_db_detachnode(db, &node); if (dbi == NULL) dns_db_detach(&db); continue; } isc_buffer_usedregion(&tb1, &r1); isc_buffer_usedregion(&tb2, &r2); printf("found %.*s as %.*s\n", (int)r1.length, r1.base, (int)r2.length, r2.base); } if (printnode) dns_db_printnode(db, node, stdout); if (!found_as && type == dns_rdatatype_any) { rdsiter = NULL; result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); if (result == ISC_R_SUCCESS) { if (!quiet) print_rdatasets(fname, rdsiter); dns_rdatasetiter_destroy(&rdsiter); } else print_result("", result); } else { if (!quiet) print_rdataset(fname, &rdataset); if (dns_rdataset_isassociated(&sigrdataset)) { if (!quiet) print_rdataset(fname, &sigrdataset); dns_rdataset_disassociate(&sigrdataset); } if (dbi != NULL && addmode && !found_as) { rdataset.ttl++; rdataset.trust = trust; if (dns_db_iszone(db)) addopts = DNS_DBADD_MERGE; else addopts = 0; result = dns_db_addrdataset(db, node, version, 0, &rdataset, addopts, NULL); if (result != ISC_R_SUCCESS) print_result("", result); if (printnode) dns_db_printnode(db, node, stdout); } else if (dbi != NULL && delmode && !found_as) { result = dns_db_deleterdataset(db, node, version, type, 0); if (result != ISC_R_SUCCESS) print_result("", result); if (printnode) dns_db_printnode(db, node, stdout); } dns_rdataset_disassociate(&rdataset); } if (dbi != NULL) { if (holdmode) { RUNTIME_CHECK(dbi->hold_count < MAXHOLD); dbi->hold_nodes[dbi->hold_count++] = node; node = NULL; } else dns_db_detachnode(db, &node); } else { dns_db_detachnode(db, &node); dns_db_detach(&db); } } if (time_lookups) { isc_uint64_t usec; TIME_NOW(&finish); usec = isc_time_microdiff(&finish, &start); printf("elapsed time: %lu.%06lu seconds\n", (unsigned long)(usec / 1000000), (unsigned long)(usec % 1000000)); } unload_all(); dns_dbtable_detach(&dbtable); if (lctx != NULL) isc_log_destroy(&lctx); if (!quiet) isc_mem_stats(mctx, stdout); return (0); }
/*% * Configure static-stub zone. */ static isc_result_t configure_staticstub(const cfg_obj_t *zconfig, dns_zone_t *zone, const char *zname, const char *dbtype) { int i = 0; const cfg_obj_t *obj; isc_mem_t *mctx = dns_zone_getmctx(zone); dns_db_t *db = NULL; dns_dbversion_t *dbversion = NULL; dns_dbnode_t *apexnode = NULL; dns_name_t apexname; isc_result_t result; dns_rdataset_t rdataset; dns_rdatalist_t rdatalist_ns, rdatalist_a, rdatalist_aaaa; dns_rdatalist_t* rdatalists[] = { &rdatalist_ns, &rdatalist_a, &rdatalist_aaaa, NULL }; dns_rdata_t *rdata; isc_region_t region; /* Create the DB beforehand */ RETERR(dns_db_create(mctx, dbtype, dns_zone_getorigin(zone), dns_dbtype_stub, dns_zone_getclass(zone), 0, NULL, &db)); dns_zone_setdb(zone, db); dns_rdatalist_init(&rdatalist_ns); rdatalist_ns.rdclass = dns_zone_getclass(zone); rdatalist_ns.type = dns_rdatatype_ns; rdatalist_ns.ttl = STATICSTUB_SERVER_TTL; dns_rdatalist_init(&rdatalist_a); rdatalist_a.rdclass = dns_zone_getclass(zone); rdatalist_a.type = dns_rdatatype_a; rdatalist_a.ttl = STATICSTUB_SERVER_TTL; dns_rdatalist_init(&rdatalist_aaaa); rdatalist_aaaa.rdclass = dns_zone_getclass(zone); rdatalist_aaaa.type = dns_rdatatype_aaaa; rdatalist_aaaa.ttl = STATICSTUB_SERVER_TTL; /* Prepare zone RRs from the configuration */ obj = NULL; result = cfg_map_get(zconfig, "server-addresses", &obj); if (result == ISC_R_SUCCESS) { INSIST(obj != NULL); result = configure_staticstub_serveraddrs(obj, zone, &rdatalist_ns, &rdatalist_a, &rdatalist_aaaa); if (result != ISC_R_SUCCESS) goto cleanup; } obj = NULL; result = cfg_map_get(zconfig, "server-names", &obj); if (result == ISC_R_SUCCESS) { INSIST(obj != NULL); result = configure_staticstub_servernames(obj, zone, &rdatalist_ns, zname); if (result != ISC_R_SUCCESS) goto cleanup; } /* * Sanity check: there should be at least one NS RR at the zone apex * to trigger delegation. */ if (ISC_LIST_EMPTY(rdatalist_ns.rdata)) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "No NS record is configured for a " "static-stub zone '%s'", zname); result = ISC_R_FAILURE; goto cleanup; } /* * Now add NS and glue A/AAAA RRsets to the zone DB. * First open a new version for the add operation and get a pointer * to the apex node (all RRs are of the apex name). */ result = dns_db_newversion(db, &dbversion); if (result != ISC_R_SUCCESS) goto cleanup; dns_name_init(&apexname, NULL); dns_name_clone(dns_zone_getorigin(zone), &apexname); result = dns_db_findnode(db, &apexname, ISC_FALSE, &apexnode); if (result != ISC_R_SUCCESS) goto cleanup; /* Add NS RRset */ dns_rdataset_init(&rdataset); RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_ns, &rdataset) == ISC_R_SUCCESS); result = dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset, 0, NULL); dns_rdataset_disassociate(&rdataset); if (result != ISC_R_SUCCESS) goto cleanup; /* Add glue A RRset, if any */ if (!ISC_LIST_EMPTY(rdatalist_a.rdata)) { RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_a, &rdataset) == ISC_R_SUCCESS); result = dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset, 0, NULL); dns_rdataset_disassociate(&rdataset); if (result != ISC_R_SUCCESS) goto cleanup; } /* Add glue AAAA RRset, if any */ if (!ISC_LIST_EMPTY(rdatalist_aaaa.rdata)) { RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_aaaa, &rdataset) == ISC_R_SUCCESS); result = dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset, 0, NULL); dns_rdataset_disassociate(&rdataset); if (result != ISC_R_SUCCESS) goto cleanup; } result = ISC_R_SUCCESS; cleanup: if (apexnode != NULL) dns_db_detachnode(db, &apexnode); if (dbversion != NULL) dns_db_closeversion(db, &dbversion, ISC_TRUE); if (db != NULL) dns_db_detach(&db); for (i = 0; rdatalists[i] != NULL; i++) { while ((rdata = ISC_LIST_HEAD(rdatalists[i]->rdata)) != NULL) { ISC_LIST_UNLINK(rdatalists[i]->rdata, rdata, link); dns_rdata_toregion(rdata, ®ion); isc_mem_put(mctx, rdata, sizeof(*rdata) + region.length); } } return (result); }
static isc_result_t load(const char *filename, const char *origintext, isc_boolean_t cache) { dns_fixedname_t forigin; dns_name_t *origin; isc_result_t result; isc_buffer_t source; size_t len; dbinfo *dbi; unsigned int i; dbi = isc_mem_get(mctx, sizeof(*dbi)); if (dbi == NULL) return (ISC_R_NOMEMORY); dbi->db = NULL; dbi->version = NULL; dbi->wversion = NULL; for (i = 0; i < MAXVERSIONS; i++) dbi->rversions[i] = NULL; dbi->hold_count = 0; for (i = 0; i < MAXHOLD; i++) dbi->hold_nodes[i] = NULL; dbi->dbiterator = NULL; dbi->iversion = NULL; dbi->pause_every = pause_every; dbi->ascending = ascending; ISC_LINK_INIT(dbi, link); len = strlen(origintext); isc_buffer_constinit(&source, origintext, len); isc_buffer_add(&source, len); dns_fixedname_init(&forigin); origin = dns_fixedname_name(&forigin); result = dns_name_fromtext(origin, &source, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) return (result); result = dns_db_create(mctx, dbtype, origin, cache ? dns_dbtype_cache : dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &dbi->db); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, dbi, sizeof(*dbi)); return (result); } printf("loading %s (%s)\n", filename, origintext); result = dns_db_load(dbi->db, filename); if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { dns_db_detach(&dbi->db); isc_mem_put(mctx, dbi, sizeof(*dbi)); return (result); } printf("loaded\n"); if (cache) { INSIST(cache_dbi == NULL); dns_dbtable_adddefault(dbtable, dbi->db); cache_dbi = dbi; } else { if (dns_dbtable_add(dbtable, dbi->db) != ISC_R_SUCCESS) { dns_db_detach(&dbi->db); isc_mem_put(mctx, dbi, sizeof(*dbi)); return (result); } } ISC_LIST_APPEND(dbs, dbi, link); return (ISC_R_SUCCESS); }
ATF_TC_BODY(dumpraw, tc) { isc_result_t result; dns_db_t *db = NULL; dns_dbversion_t *version = NULL; char origin[sizeof(TEST_ORIGIN)]; dns_name_t dns_origin; isc_buffer_t source, target; unsigned char name_buf[BUFLEN]; int len; UNUSED(tc); strcpy(origin, TEST_ORIGIN); len = strlen(origin); isc_buffer_init(&source, origin, len); isc_buffer_add(&source, len); isc_buffer_setactive(&source, len); isc_buffer_init(&target, name_buf, BUFLEN); dns_name_init(&dns_origin, NULL); result = dns_name_fromtext(&dns_origin, &source, dns_rootname, 0, &target); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_test_begin(NULL, ISC_FALSE); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_create(mctx, "rbt", &dns_origin, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = dns_db_load(db, "testdata/master/master1.data"); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_db_currentversion(db, &version); result = dns_master_dump2(mctx, db, version, &dns_master_style_default, "test.dump", dns_masterformat_raw); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("test.dump", dns_masterformat_raw, NULL, NULL); ATF_CHECK_STREQ(isc_result_totext(result), "success"); ATF_CHECK(headerset); ATF_CHECK_EQ(header.flags, 0); dns_master_initrawheader(&header); header.sourceserial = 12345; header.flags |= DNS_MASTERRAW_SOURCESERIALSET; unlink("test.dump"); result = dns_master_dump3(mctx, db, version, &dns_master_style_default, "test.dump", dns_masterformat_raw, &header); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); result = test_master("test.dump", dns_masterformat_raw, NULL, NULL); ATF_CHECK_STREQ(isc_result_totext(result), "success"); ATF_CHECK(headerset); ATF_CHECK((header.flags & DNS_MASTERRAW_SOURCESERIALSET) != 0); ATF_CHECK_EQ(header.sourceserial, 12345); unlink("test.dump"); dns_db_closeversion(db, &version, ISC_FALSE); dns_db_detach(&db); dns_test_end(); }
static void nsecify (char *filename) { isc_result_t result; dns_db_t *db; dns_dbversion_t *wversion; dns_dbnode_t *node, *nextnode; char *origintext; dns_fixedname_t fname, fnextname; dns_name_t *name, *nextname, *target; isc_buffer_t b; size_t len; dns_dbiterator_t *dbiter; char newfilename[1024]; dns_fixedname_init (&fname); name = dns_fixedname_name (&fname); dns_fixedname_init (&fnextname); nextname = dns_fixedname_name (&fnextname); origintext = strrchr (filename, '/'); if (origintext == NULL) origintext = filename; else origintext++; /* Skip '/'. */ len = strlen (origintext); isc_buffer_init (&b, origintext, len); isc_buffer_add (&b, len); result = dns_name_fromtext (name, &b, dns_rootname, 0, NULL); check_result (result, "dns_name_fromtext()"); db = NULL; result = dns_db_create (mctx, "rbt", name, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db); check_result (result, "dns_db_create()"); result = dns_db_load (db, filename); if (result == DNS_R_SEENINCLUDE) result = ISC_R_SUCCESS; check_result (result, "dns_db_load()"); wversion = NULL; result = dns_db_newversion (db, &wversion); check_result (result, "dns_db_newversion()"); dbiter = NULL; result = dns_db_createiterator (db, 0, &dbiter); check_result (result, "dns_db_createiterator()"); result = dns_dbiterator_first (dbiter); check_result (result, "dns_dbiterator_first()"); node = NULL; result = next_active (db, wversion, dbiter, name, &node); while (result == ISC_R_SUCCESS) { nextnode = NULL; result = dns_dbiterator_next (dbiter); if (result == ISC_R_SUCCESS) result = next_active (db, wversion, dbiter, nextname, &nextnode); if (result == ISC_R_SUCCESS) target = nextname; else if (result == ISC_R_NOMORE) target = dns_db_origin (db); else { target = NULL; /* Make compiler happy. */ fatal ("db iteration failed"); } dns_nsec_build (db, wversion, node, target, 3600); /* XXX BEW */ dns_db_detachnode (db, &node); node = nextnode; } if (result != ISC_R_NOMORE) fatal ("db iteration failed"); dns_dbiterator_destroy (&dbiter); /* * XXXRTH For now, we don't increment the SOA serial. */ dns_db_closeversion (db, &wversion, ISC_TRUE); len = strlen (filename); if (len + 4 + 1 > sizeof (newfilename)) fatal ("filename too long"); sprintf (newfilename, "%s.new", filename); result = dns_db_dump (db, NULL, newfilename); check_result (result, "dns_db_dump"); dns_db_detach (&db); }
int main(int argc, char *argv[]) { char *origin = NULL, *file = NULL; char *inputformatstr = NULL; isc_result_t result; isc_log_t *log = NULL; #ifdef USE_PKCS11 const char *engine = "pkcs11"; #else const char *engine = NULL; #endif char *classname = NULL; dns_rdataclass_t rdclass; char *endp; int ch; #define CMDLINE_FLAGS \ "hm:o:I:c:E:v:Vxz" /* * Process memory debugging argument first. */ while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { case 'm': if (strcasecmp(isc_commandline_argument, "record") == 0) isc_mem_debugging |= ISC_MEM_DEBUGRECORD; if (strcasecmp(isc_commandline_argument, "trace") == 0) isc_mem_debugging |= ISC_MEM_DEBUGTRACE; if (strcasecmp(isc_commandline_argument, "usage") == 0) isc_mem_debugging |= ISC_MEM_DEBUGUSAGE; if (strcasecmp(isc_commandline_argument, "size") == 0) isc_mem_debugging |= ISC_MEM_DEBUGSIZE; if (strcasecmp(isc_commandline_argument, "mctx") == 0) isc_mem_debugging |= ISC_MEM_DEBUGCTX; break; default: break; } } isc_commandline_reset = ISC_TRUE; check_result(isc_app_start(), "isc_app_start"); result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) fatal("out of memory"); dns_result_register(); isc_commandline_errprint = ISC_FALSE; while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { case 'c': classname = isc_commandline_argument; break; case 'E': engine = isc_commandline_argument; break; case 'I': inputformatstr = isc_commandline_argument; break; case 'm': break; case 'o': origin = isc_commandline_argument; break; case 'v': endp = NULL; verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("verbose level must be numeric"); break; case 'x': keyset_kskonly = ISC_TRUE; break; case 'z': ignore_kskflag = ISC_TRUE; break; case '?': if (isc_commandline_option != '?') fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); /* FALLTHROUGH */ case 'h': /* Does not return. */ usage(); case 'V': /* Does not return. */ version(program); default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); if (result != ISC_R_SUCCESS) fatal("could not create hash context"); result = dst_lib_init2(mctx, ectx, engine, ISC_ENTROPY_BLOCKING); if (result != ISC_R_SUCCESS) fatal("could not initialize dst: %s", isc_result_totext(result)); isc_stdtime_get(&now); rdclass = strtoclass(classname); setup_logging(verbose, mctx, &log); argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 1) usage(); file = argv[0]; argc -= 1; argv += 1; POST(argc); POST(argv); if (origin == NULL) origin = file; if (inputformatstr != NULL) { if (strcasecmp(inputformatstr, "text") == 0) inputformat = dns_masterformat_text; else if (strcasecmp(inputformatstr, "raw") == 0) inputformat = dns_masterformat_raw; else fatal("unknown file format: %s\n", inputformatstr); } gdb = NULL; fprintf(stderr, "Loading zone '%s' from file '%s'\n", origin, file); loadzone(file, origin, rdclass, &gdb); gorigin = dns_db_origin(gdb); gclass = dns_db_class(gdb); gversion = NULL; result = dns_db_newversion(gdb, &gversion); check_result(result, "dns_db_newversion()"); verifyzone(gdb, gversion, gorigin, mctx, ignore_kskflag, keyset_kskonly); dns_db_closeversion(gdb, &gversion, ISC_FALSE); dns_db_detach(&gdb); cleanup_logging(&log); dst_lib_destroy(); isc_hash_destroy(); cleanup_entropy(&ectx); dns_name_destroy(); if (verbose > 10) isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); (void) isc_app_finish(); return (0); }
int main(int argc, char **argv) { char *porigin, *zonefile; dns_fixedname_t forigin, fname; dns_name_t *origin, *name; dns_db_t *db = NULL; dns_dbiterator_t *dbiter; dns_dbnode_t *node; dns_rdatasetiter_t *rdsiter; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; isc_mem_t *mctx = NULL; isc_entropy_t *ectx = NULL; isc_buffer_t b; isc_result_t result; PGresult *res; if (argc != 5) { printf("usage: %s origin file dbname dbtable\n", argv[0]); printf("Note that dbname must be an existing database.\n"); exit(1); } porigin = argv[1]; zonefile = argv[2]; dbname = argv[3]; dbtable = argv[4]; dns_result_register(); mctx = NULL; result = isc_mem_create(0, 0, &mctx); check_result(result, "isc_mem_create"); result = isc_entropy_create(mctx, &ectx); result_check (result, "isc_entropy_create"); result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE); check_result (result, "isc_hash_create"); isc_buffer_init(&b, porigin, strlen(porigin)); isc_buffer_add(&b, strlen(porigin)); dns_fixedname_init(&forigin); origin = dns_fixedname_name(&forigin); result = dns_name_fromtext(origin, &b, dns_rootname, ISC_FALSE, NULL); check_result(result, "dns_name_fromtext"); db = NULL; result = dns_db_create(mctx, "rbt", origin, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db); check_result(result, "dns_db_create"); result = dns_db_load(db, zonefile); if (result == DNS_R_SEENINCLUDE) result = ISC_R_SUCCESS; check_result(result, "dns_db_load"); printf("Connecting to '%s'\n", dbname); conn = PQsetdb(NULL, NULL, NULL, NULL, dbname); if (PQstatus(conn) == CONNECTION_BAD) { fprintf(stderr, "Connection to database '%s' failed: %s\n", dbname, PQerrorMessage(conn)); closeandexit(1); } snprintf(str, sizeof(str), "DROP TABLE %s", dbtable); printf("%s\n", str); res = PQexec(conn, str); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) fprintf(stderr, "DROP TABLE command failed: %s\n", PQresultErrorMessage(res)); PQclear(res); snprintf(str, sizeof(str), "BEGIN"); printf("%s\n", str); res = PQexec(conn, str); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "BEGIN command failed: %s\n", PQresultErrorMessage(res)); PQclear(res); closeandexit(1); } PQclear(res); snprintf(str, sizeof(str), "CREATE TABLE %s " "(NAME TEXT, TTL INTEGER, RDTYPE TEXT, RDATA TEXT)", dbtable); printf("%s\n", str); res = PQexec(conn, str); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "CREATE TABLE command failed: %s\n", PQresultErrorMessage(res)); PQclear(res); closeandexit(1); } PQclear(res); dbiter = NULL; result = dns_db_createiterator(db, ISC_FALSE, &dbiter); check_result(result, "dns_db_createiterator()"); result = dns_dbiterator_first(dbiter); check_result(result, "dns_dbiterator_first"); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_rdataset_init(&rdataset); dns_rdata_init(&rdata); while (result == ISC_R_SUCCESS) { node = NULL; result = dns_dbiterator_current(dbiter, &node, name); if (result == ISC_R_NOMORE) break; check_result(result, "dns_dbiterator_current"); rdsiter = NULL; result = dns_db_allrdatasets(db, node, NULL, 0, &rdsiter); check_result(result, "dns_db_allrdatasets"); result = dns_rdatasetiter_first(rdsiter); while (result == ISC_R_SUCCESS) { dns_rdatasetiter_current(rdsiter, &rdataset); result = dns_rdataset_first(&rdataset); check_result(result, "dns_rdataset_first"); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&rdataset, &rdata); addrdata(name, rdataset.ttl, &rdata); dns_rdata_reset(&rdata); result = dns_rdataset_next(&rdataset); } dns_rdataset_disassociate(&rdataset); result = dns_rdatasetiter_next(rdsiter); } dns_rdatasetiter_destroy(&rdsiter); dns_db_detachnode(db, &node); result = dns_dbiterator_next(dbiter); } snprintf(str, sizeof(str), "COMMIT TRANSACTION"); printf("%s\n", str); res = PQexec(conn, str); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "COMMIT command failed: %s\n", PQresultErrorMessage(res)); PQclear(res); closeandexit(1); } PQclear(res); dns_dbiterator_destroy(&dbiter); dns_db_detach(&db); isc_hash_destroy(); isc_entropy_detach(&ectx); isc_mem_destroy(&mctx); closeandexit(0); exit(0); }