/* * Puts resource record data on 'db'. */ isc_result_t bdb_putrdata(DB *db, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { static DBT key, data; isc_buffer_t keybuf, databuf; char nametext[DNS_NAME_MAXTEXT]; char rdatatext[MAX_RDATATEXT]; isc_buffer_init(&keybuf, nametext, DNS_NAME_MAXTEXT); dns_name_totext(name, ISC_TRUE, &keybuf); key.data = isc_buffer_base(&keybuf); key.size = isc_buffer_usedlength(&keybuf); isc_buffer_init(&databuf, rdatatext, MAX_RDATATEXT); dns_ttl_totext(ttl, ISC_FALSE, &databuf); *(char *)isc_buffer_used(&databuf) = ' '; isc_buffer_add(&databuf, 1); dns_rdatatype_totext(rdata->type, &databuf); /* XXX private data */ *(char *)isc_buffer_used(&databuf) = ' '; isc_buffer_add(&databuf, 1); dns_rdata_totext(rdata, NULL, &databuf); data.data = isc_buffer_base(&databuf); data.size = isc_buffer_usedlength(&databuf); REQUIRE(db->put(db, NULL, &key, &data, 0) == 0); return ISC_R_SUCCESS; }
/*% * Internal print routine used to print short form replies. */ static isc_result_t say_message(dns_rdata_t *rdata, dig_query_t *query, isc_buffer_t *buf) { isc_result_t result; isc_uint64_t diff; isc_time_t now; char store[sizeof("12345678901234567890")]; if (query->lookup->trace || query->lookup->ns_search_only) { result = dns_rdatatype_totext(rdata->type, buf); if (result != ISC_R_SUCCESS) return (result); ADD_STRING(buf, " "); } result = dns_rdata_totext(rdata, NULL, buf); if (result == ISC_R_NOSPACE) return (result); check_result(result, "dns_rdata_totext"); if (query->lookup->identify) { TIME_NOW(&now); diff = isc_time_microdiff(&now, &query->time_sent); ADD_STRING(buf, " from server "); ADD_STRING(buf, query->servname); snprintf(store, 19, " in %d ms.", (int)diff/1000); ADD_STRING(buf, store); } ADD_STRING(buf, "\n"); return (ISC_R_SUCCESS); }
void type_format(const dns_rdatatype_t type, char *cp, unsigned int size) { isc_buffer_t b; isc_region_t r; isc_result_t result; isc_buffer_init(&b, cp, size - 1); result = dns_rdatatype_totext(type, &b); check_result(result, "dns_rdatatype_totext()"); isc_buffer_usedregion(&b, &r); r.base[r.length] = 0; }
void addrdata(dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { unsigned char namearray[DNS_NAME_MAXTEXT + 1]; unsigned char canonnamearray[2 * DNS_NAME_MAXTEXT + 1]; unsigned char typearray[20]; unsigned char canontypearray[40]; unsigned char dataarray[2048]; unsigned char canondataarray[4096]; isc_buffer_t b; isc_result_t result; PGresult *res; isc_buffer_init(&b, namearray, sizeof(namearray) - 1); result = dns_name_totext(name, ISC_TRUE, &b); check_result(result, "dns_name_totext"); namearray[isc_buffer_usedlength(&b)] = 0; quotestring(namearray, canonnamearray); isc_buffer_init(&b, typearray, sizeof(typearray) - 1); result = dns_rdatatype_totext(rdata->type, &b); check_result(result, "dns_rdatatype_totext"); typearray[isc_buffer_usedlength(&b)] = 0; quotestring(typearray, canontypearray); isc_buffer_init(&b, dataarray, sizeof(dataarray) - 1); result = dns_rdata_totext(rdata, NULL, &b); check_result(result, "dns_rdata_totext"); dataarray[isc_buffer_usedlength(&b)] = 0; quotestring(dataarray, canondataarray); snprintf(str, sizeof(str), "INSERT INTO %s (NAME, TTL, RDTYPE, RDATA)" " VALUES ('%s', %d, '%s', '%s')", dbtable, canonnamearray, ttl, canontypearray, canondataarray); printf("%s\n", str); res = PQexec(conn, str); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "INSERT INTO command failed: %s\n", PQresultErrorMessage(res)); PQclear(res); closeandexit(1); } PQclear(res); }
static void addrdata(dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { unsigned char namearray[DNS_NAME_MAXTEXT + 1]; unsigned char typearray[20]; unsigned char dataarray[2048]; isc_buffer_t b; isc_result_t result; char *sql; char *errmsg = NULL; int res; isc_buffer_init(&b, namearray, sizeof(namearray) - 1); result = dns_name_totext(name, ISC_TRUE, &b); check_result(result, "dns_name_totext"); namearray[isc_buffer_usedlength(&b)] = 0; isc_buffer_init(&b, typearray, sizeof(typearray) - 1); result = dns_rdatatype_totext(rdata->type, &b); check_result(result, "dns_rdatatype_totext"); typearray[isc_buffer_usedlength(&b)] = 0; isc_buffer_init(&b, dataarray, sizeof(dataarray) - 1); result = dns_rdata_totext(rdata, NULL, &b); check_result(result, "dns_rdata_totext"); dataarray[isc_buffer_usedlength(&b)] = 0; sql = sqlite3_mprintf( "INSERT INTO %q (NAME, TTL, RDTYPE, RDATA)" " VALUES ('%q', %d, '%q', '%q') ", dbi.table, namearray, ttl, typearray, dataarray); printf("%s\n", sql); res = sqlite3_exec(dbi.db, sql, add_rdata_cb, NULL, &errmsg); sqlite3_free(sql); if (result != SQLITE_OK) { fprintf(stderr, "INSERT failed: %s\n", errmsg); closeandexit(1); } }
/* Takes DNS information, in bind data structure format, and adds textual * zone information to the LDAP run queue. */ void generate_ldap (dns_name_t * dnsname, dns_rdata_t * rdata, unsigned int ttl) { unsigned char name[DNS_NAME_MAXTEXT + 1]; unsigned int len; unsigned char type[20]; unsigned char data[2048]; char **dc_list; char *dn; isc_buffer_t buff; isc_result_t result; isc_buffer_init (&buff, name, sizeof (name)); result = dns_name_totext (dnsname, ISC_TRUE, &buff); isc_result_check (result, "dns_name_totext"); name[isc_buffer_usedlength (&buff)] = 0; isc_buffer_init (&buff, type, sizeof (type)); result = dns_rdatatype_totext (rdata->type, &buff); isc_result_check (result, "dns_rdatatype_totext"); type[isc_buffer_usedlength (&buff)] = 0; isc_buffer_init (&buff, data, sizeof (data)); result = dns_rdata_totext (rdata, NULL, &buff); isc_result_check (result, "dns_rdata_totext"); data[isc_buffer_usedlength (&buff)] = 0; dc_list = hostname_to_dn_list (name, argzone, DNS_OBJECT); len = (get_attr_list_size (dc_list) - 2); dn = build_dn_from_dc_list (dc_list, ttl, WI_SPEC); if (debug) printf ("Adding %s (%s %s) to run queue list.\n", dn, type, data); add_to_rr_list (dn, dc_list[len], type, data, ttl, DNS_OBJECT); }
int main(int argc, char *argv[]) { isc_token_t token; isc_result_t result; int c; unsigned int options = 0; dns_rdatatype_t rdtype; dns_rdataclass_t rdclass; char text[256*1024]; char data[64*1024]; isc_buffer_t tbuf; isc_buffer_t dbuf; dns_rdata_t rdata = DNS_RDATA_INIT; isc_boolean_t doexit = ISC_FALSE; isc_boolean_t once = ISC_FALSE; isc_boolean_t print = ISC_FALSE; isc_boolean_t unknown = ISC_FALSE; unsigned int t; char *origin = NULL; dns_fixedname_t fixed; dns_name_t *name = NULL; while ((c = isc_commandline_parse(argc, argv, "ho:puCPT")) != -1) { switch (c) { case 'o': origin = isc_commandline_argument; break; case 'p': print = ISC_TRUE; break; case 'u': unknown = ISC_TRUE; break; case 'C': for (t = 1; t <= 0xfeffu; t++) { if (dns_rdataclass_ismeta(t)) continue; dns_rdataclass_format(t, text, sizeof(text)); if (strncmp(text, "CLASS", 4) != 0) fprintf(stdout, "%s\n", text); } exit(0); case 'P': for (t = 0xff00; t <= 0xfffeu; t++) { if (dns_rdatatype_ismeta(t)) continue; dns_rdatatype_format(t, text, sizeof(text)); if (strncmp(text, "TYPE", 4) != 0) fprintf(stdout, "%s\n", text); } doexit = ISC_TRUE; break; case 'T': for (t = 1; t <= 0xfeffu; t++) { if (dns_rdatatype_ismeta(t)) continue; dns_rdatatype_format(t, text, sizeof(text)); if (strncmp(text, "TYPE", 4) != 0) fprintf(stdout, "%s\n", text); } doexit = ISC_TRUE; break; case '?': case 'h': /* Does not return. */ usage(); default: fprintf(stderr, "%s: unhandled option -%c\n", argv[0], isc_commandline_option); exit(1); } } if (doexit) exit(0); RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_lex_create(mctx, 256, &lex) == ISC_R_SUCCESS); /* * Set up to lex DNS master file. */ specials['('] = 1; specials[')'] = 1; specials['"'] = 1; isc_lex_setspecials(lex, specials); options = ISC_LEXOPT_EOL; isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE); RUNTIME_CHECK(isc_lex_openstream(lex, stdin) == ISC_R_SUCCESS); if (origin != NULL) { dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); result = dns_name_fromstring(name, origin, 0, NULL); if (result != ISC_R_SUCCESS) { fatal("dns_name_fromstring: %s", dns_result_totext(result)); } } while ((result = isc_lex_gettoken(lex, options | ISC_LEXOPT_NUMBER, &token)) == ISC_R_SUCCESS) { if (token.type == isc_tokentype_eof) break; if (token.type == isc_tokentype_eol) continue; if (once) { fatal("extra data"); } /* * Get class. */ if (token.type == isc_tokentype_number) { rdclass = (dns_rdataclass_t) token.value.as_ulong; if (token.value.as_ulong > 0xffffu) { fatal("class value too big %lu", token.value.as_ulong); } if (dns_rdataclass_ismeta(rdclass)) { fatal("class %lu is a meta value", token.value.as_ulong); } } else if (token.type == isc_tokentype_string) { result = dns_rdataclass_fromtext(&rdclass, &token.value.as_textregion); if (result != ISC_R_SUCCESS) { fatal("dns_rdataclass_fromtext: %s", dns_result_totext(result)); } if (dns_rdataclass_ismeta(rdclass)) { fatal("class %.*s(%d) is a meta value", (int)token.value.as_textregion.length, token.value.as_textregion.base, rdclass); } } else { fatal("unexpected token %u", token.type); } result = isc_lex_gettoken(lex, options | ISC_LEXOPT_NUMBER, &token); if (result != ISC_R_SUCCESS) break; if (token.type == isc_tokentype_eol) continue; if (token.type == isc_tokentype_eof) break; /* * Get type. */ if (token.type == isc_tokentype_number) { rdtype = (dns_rdatatype_t) token.value.as_ulong; if (token.value.as_ulong > 0xffffu) { fatal("type value too big %lu", token.value.as_ulong); } if (dns_rdatatype_ismeta(rdtype)) { fatal("type %lu is a meta value", token.value.as_ulong); } } else if (token.type == isc_tokentype_string) { result = dns_rdatatype_fromtext(&rdtype, &token.value.as_textregion); if (result != ISC_R_SUCCESS) { fatal("dns_rdatatype_fromtext: %s", dns_result_totext(result)); } if (dns_rdatatype_ismeta(rdtype)) { fatal("type %.*s(%d) is a meta value", (int)token.value.as_textregion.length, token.value.as_textregion.base, rdtype); } } else { fatal("unexpected token %u", token.type); } isc_buffer_init(&dbuf, data, sizeof(data)); result = dns_rdata_fromtext(&rdata, rdclass, rdtype, lex, name, 0, mctx, &dbuf, NULL); if (result != ISC_R_SUCCESS) { fatal("dns_rdata_fromtext: %s", dns_result_totext(result)); } once = ISC_TRUE; } if (result != ISC_R_EOF) { fatal("eof not found"); } if (!once) { fatal("no records found"); } if (print) { isc_buffer_init(&tbuf, text, sizeof(text)); result = dns_rdataclass_totext(rdclass, &tbuf); if (result != ISC_R_SUCCESS) { fatal("dns_rdataclass_totext: %s", dns_result_totext(result)); } isc_buffer_putstr(&tbuf, "\t"); result = dns_rdatatype_totext(rdtype, &tbuf); if (result != ISC_R_SUCCESS) { fatal("dns_rdatatype_totext: %s", dns_result_totext(result)); } isc_buffer_putstr(&tbuf, "\t"); result = dns_rdata_totext(&rdata, NULL, &tbuf); if (result != ISC_R_SUCCESS) { fatal("dns_rdata_totext: %s", dns_result_totext(result)); } printf("%.*s\n", (int)tbuf.used, (char*)tbuf.base); fflush(stdout); } if (unknown) { isc_buffer_init(&tbuf, text, sizeof(text)); result = dns_rdataclass_tounknowntext(rdclass, &tbuf); if (result != ISC_R_SUCCESS) { fatal("dns_rdataclass_tounknowntext: %s", dns_result_totext(result)); } isc_buffer_putstr(&tbuf, "\t"); result = dns_rdatatype_tounknowntext(rdtype, &tbuf); if (result != ISC_R_SUCCESS) { fatal("dns_rdatatype_tounknowntext: %s", dns_result_totext(result)); } isc_buffer_putstr(&tbuf, "\t"); result = dns_rdata_tofmttext(&rdata, NULL, DNS_STYLEFLAG_UNKNOWNFORMAT, 0, 0, "", &tbuf); if (result != ISC_R_SUCCESS) { fatal("dns_rdata_tofmttext: %sn", dns_result_totext(result)); } printf("%.*s\n", (int)tbuf.used, (char*)tbuf.base); fflush(stdout); } isc_lex_close(lex); isc_lex_destroy(&lex); isc_mem_destroy(&mctx); return (0); }
int main(int argc, char *argv[]) { isc_token_t token; isc_result_t result; int quiet = 0; int c; int stats = 0; unsigned int options = 0; dns_rdatatype_t type; dns_rdataclass_t class; dns_rdatatype_t lasttype = 0; char outbuf[16*1024]; char inbuf[16*1024]; char wirebuf[16*1024]; char viabuf[16*1024]; isc_buffer_t dbuf; isc_buffer_t tbuf; isc_buffer_t wbuf; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_t last = DNS_RDATA_INIT; int need_eol = 0; int wire = 0; dns_compress_t cctx; dns_decompress_t dctx; int trunc = 0; int add = 0; int len; int zero = 0; int debug = 0; isc_region_t region; int first = 1; int raw = 0; int tostruct = 0; while ((c = isc_commandline_parse(argc, argv, "dqswtarzS")) != -1) { switch (c) { case 'd': debug = 1; quiet = 0; break; case 'q': quiet = 1; debug = 0; break; case 's': stats = 1; break; case 'w': wire = 1; break; case 't': trunc = 1; break; case 'a': add = 1; break; case 'z': zero = 1; break; case 'r': raw++; break; case 'S': tostruct++; break; } } memset(&dctx, 0, sizeof(dctx)); dctx.allowed = DNS_COMPRESS_ALL; RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_lex_create(mctx, 256, &lex) == ISC_R_SUCCESS); /* * Set up to lex DNS master file. */ specials['('] = 1; specials[')'] = 1; specials['"'] = 1; isc_lex_setspecials(lex, specials); options = ISC_LEXOPT_EOL; isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE); RUNTIME_CHECK(isc_lex_openstream(lex, stdin) == ISC_R_SUCCESS); dns_rdata_init(&last); while ((result = isc_lex_gettoken(lex, options | ISC_LEXOPT_NUMBER, &token)) == ISC_R_SUCCESS) { if (debug) fprintf(stdout, "token.type = %d\n", token.type); if (need_eol) { if (token.type == isc_tokentype_eol) need_eol = 0; continue; } if (token.type == isc_tokentype_eof) break; /* * Get type. */ if (token.type == isc_tokentype_number) { type = token.value.as_ulong; isc_buffer_init(&tbuf, outbuf, sizeof(outbuf)); result = dns_rdatatype_totext(type, &tbuf); if (result != ISC_R_SUCCESS) { fprintf(stdout, "dns_rdatatype_totext " "returned %s(%d)\n", dns_result_totext(result), result); fflush(stdout); need_eol = 1; continue; } fprintf(stdout, "type = %.*s(%d)\n", (int)tbuf.used, (char*)tbuf.base, type); } else if (token.type == isc_tokentype_string) { result = dns_rdatatype_fromtext(&type, &token.value.as_textregion); if (result != ISC_R_SUCCESS) { fprintf(stdout, "dns_rdatatype_fromtext " "returned %s(%d)\n", dns_result_totext(result), result); fflush(stdout); need_eol = 1; continue; } fprintf(stdout, "type = %.*s(%d)\n", (int)token.value.as_textregion.length, token.value.as_textregion.base, type); } else continue; result = isc_lex_gettoken(lex, options | ISC_LEXOPT_NUMBER, &token); if (result != ISC_R_SUCCESS) break; if (token.type == isc_tokentype_eol) continue; if (token.type == isc_tokentype_eof) break; if (token.type == isc_tokentype_number) { class = token.value.as_ulong; isc_buffer_init(&tbuf, outbuf, sizeof(outbuf)); result = dns_rdatatype_totext(class, &tbuf); if (result != ISC_R_SUCCESS) { fprintf(stdout, "dns_rdatatype_totext " "returned %s(%d)\n", dns_result_totext(result), result); fflush(stdout); need_eol = 1; continue; } fprintf(stdout, "class = %.*s(%d)\n", (int)tbuf.used, (char*)tbuf.base, class); } else if (token.type == isc_tokentype_string) { result = dns_rdataclass_fromtext(&class, &token.value.as_textregion); if (result != ISC_R_SUCCESS) { fprintf(stdout, "dns_rdataclass_fromtext " "returned %s(%d)\n", dns_result_totext(result), result); fflush(stdout); need_eol = 1; continue; } fprintf(stdout, "class = %.*s(%d)\n", (int)token.value.as_textregion.length, token.value.as_textregion.base, class); } else
static inline isc_result_t totext_sig(ARGS_TOTEXT) { isc_region_t sr; char buf[sizeof("4294967295")]; dns_rdatatype_t covered; unsigned long ttl; unsigned long when; unsigned long exp; unsigned long foot; dns_name_t name; dns_name_t prefix; isc_boolean_t sub; REQUIRE(rdata->type == dns_rdatatype_sig); REQUIRE(rdata->length != 0); dns_rdata_toregion(rdata, &sr); /* * Type covered. */ covered = uint16_fromregion(&sr); isc_region_consume(&sr, 2); /* * XXXAG We should have something like dns_rdatatype_isknown() * that does the right thing with type 0. */ if (dns_rdatatype_isknown(covered) && covered != 0) { RETERR(dns_rdatatype_totext(covered, target)); } else { sprintf(buf, "%u", covered); RETERR(str_totext(buf, target)); } RETERR(str_totext(" ", target)); /* * Algorithm. */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Labels. */ sprintf(buf, "%u", sr.base[0]); isc_region_consume(&sr, 1); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Ttl. */ ttl = uint32_fromregion(&sr); isc_region_consume(&sr, 4); sprintf(buf, "%lu", ttl); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Sig exp. */ exp = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(exp, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); /* * Time signed. */ when = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(when, target)); RETERR(str_totext(" ", target)); /* * Footprint. */ foot = uint16_fromregion(&sr); isc_region_consume(&sr, 2); sprintf(buf, "%lu", foot); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); /* * Signer. */ dns_name_init(&name, NULL); dns_name_init(&prefix, NULL); dns_name_fromregion(&name, &sr); isc_region_consume(&sr, name_length(&name)); sub = name_prefix(&name, tctx->origin, &prefix); RETERR(dns_name_totext(&prefix, sub, target)); /* * Sig. */ RETERR(str_totext(tctx->linebreak, target)); if (tctx->width == 0) /* No splitting */ RETERR(isc_base64_totext(&sr, 60, "", target)); else RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); }
/*% scan the zone for oversize TTLs */ static isc_result_t check_ttls(dns_zone_t *zone, dns_ttl_t maxttl) { isc_result_t result; dns_db_t *db = NULL; dns_dbversion_t *version = NULL; dns_dbnode_t *node = NULL; dns_dbiterator_t *dbiter = NULL; dns_rdatasetiter_t *rdsiter = NULL; dns_rdataset_t rdataset; dns_fixedname_t fname; dns_name_t *name; dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_rdataset_init(&rdataset); CHECK(dns_zone_getdb(zone, &db)); INSIST(db != NULL); CHECK(dns_db_newversion(db, &version)); CHECK(dns_db_createiterator(db, 0, &dbiter)); for (result = dns_dbiterator_first(dbiter); result == ISC_R_SUCCESS; result = dns_dbiterator_next(dbiter)) { result = dns_dbiterator_current(dbiter, &node, name); if (result == DNS_R_NEWORIGIN) result = ISC_R_SUCCESS; CHECK(result); CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsiter)); for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &rdataset); if (rdataset.ttl > maxttl) { char nbuf[DNS_NAME_FORMATSIZE]; char tbuf[255]; isc_buffer_t b; isc_region_t r; dns_name_format(name, nbuf, sizeof(nbuf)); isc_buffer_init(&b, tbuf, sizeof(tbuf) - 1); CHECK(dns_rdatatype_totext(rdataset.type, &b)); isc_buffer_usedregion(&b, &r); r.base[r.length] = 0; dns_zone_log(zone, ISC_LOG_ERROR, "%s/%s TTL %d exceeds " "maximum TTL %d", nbuf, tbuf, rdataset.ttl, maxttl); dns_rdataset_disassociate(&rdataset); CHECK(ISC_R_RANGE); } dns_rdataset_disassociate(&rdataset); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; CHECK(result); dns_rdatasetiter_destroy(&rdsiter); dns_db_detachnode(db, &node); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; cleanup: if (node != NULL) dns_db_detachnode(db, &node); if (rdsiter != NULL) dns_rdatasetiter_destroy(&rdsiter); if (dbiter != NULL) dns_dbiterator_destroy(&dbiter); if (version != NULL) dns_db_closeversion(db, &version, ISC_FALSE); if (db != NULL) dns_db_detach(&db); return (result); }