static void setup_db() { isc_result_t result; result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db1); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_db_newversion(db1, &v1); result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &db2); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); dns_db_newversion(db2, &v2); }
static isc_result_t newversion(dns_db_t *db, dns_dbversion_t **versionp) { sampledb_t *sampledb = (sampledb_t *)db; REQUIRE(VALID_SAMPLEDB(sampledb)); return (dns_db_newversion(sampledb->rbtdb, versionp)); }
/** * @brief Allocate and open new RBTDB version. * * New version is compatible with LDAPDB and RBTDB. * Only one new version can be open at any time. This limitation is enforced * by ldapdb->newversion_lock. * * @warning This function has to be used for all newversion() calls for LDAPDB * AND also internal RBTDB (ldapdb->rbtdb). This ensures proper * serialization and prevents assertion failures in newversion(). * * How to work with internal RBTDB versions in safe way (note ldapdb vs. rbtdb): * @verbatim CHECK(dns_db_newversion(ldapdb, &newversion)); // do whatevent you need with the newversion, e.g.: CHECK(dns_diff_apply(diff, rbtdb, newversion)); cleanup: if (newversion != NULL) dns_db_closeversion(ldapdb, &newversion, ISC_TRUE); @endverbatim */ static isc_result_t newversion(dns_db_t *db, dns_dbversion_t **versionp) { ldapdb_t *ldapdb = (ldapdb_t *)db; isc_result_t result; REQUIRE(VALID_LDAPDB(ldapdb)); LOCK(&ldapdb->newversion_lock); result = dns_db_newversion(ldapdb->rbtdb, versionp); if (result == ISC_R_SUCCESS) { INSIST(*versionp != NULL); ldapdb->newversion = *versionp; } else { INSIST(*versionp == NULL); UNLOCK(&ldapdb->newversion_lock); } return result; }
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); }
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); }
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); }
/*% * 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); }
/* * Driver-specific implementation of dns_db_create(). * * @param[in] argv Database-specific parameters from dns_db_create(). * @param[in] driverarg Driver-specific parameter from dns_db_register(). */ isc_result_t create_db(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], void *driverarg, dns_db_t **dbp) { sampledb_t *sampledb = NULL; isc_result_t result; dns_dbversion_t *version = NULL; struct in_addr a_addr; REQUIRE(type == dns_dbtype_zone); REQUIRE(rdclass == dns_rdataclass_in); REQUIRE(argc == 0); REQUIRE(argv != NULL); REQUIRE(driverarg != NULL); /* pointer to driver instance */ REQUIRE(dbp != NULL && *dbp == NULL); UNUSED(driverarg); /* no driver-specific configuration */ a_addr.s_addr = 0x0100007fU; CHECKED_MEM_GET_PTR(mctx, sampledb); ZERO_PTR(sampledb); isc_mem_attach(mctx, &sampledb->common.mctx); dns_name_init(&sampledb->common.origin, NULL); isc_ondestroy_init(&sampledb->common.ondest); sampledb->common.magic = DNS_DB_MAGIC; sampledb->common.impmagic = SAMPLEDB_MAGIC; sampledb->common.methods = &sampledb_methods; sampledb->common.attributes = 0; sampledb->common.rdclass = rdclass; CHECK(dns_name_dupwithoffsets(origin, mctx, &sampledb->common.origin)); CHECK(isc_refcount_init(&sampledb->refs, 1)); /* Translate instance name to instance pointer. */ sampledb->inst = driverarg; /* Create internal instance of RBT DB implementation from BIND. */ CHECK(dns_db_create(mctx, "rbt", origin, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &sampledb->rbtdb)); /* Create fake SOA, NS, and A records to make database loadable. */ CHECK(dns_db_newversion(sampledb->rbtdb, &version)); CHECK(add_soa(sampledb->rbtdb, version, origin, origin, origin)); CHECK(add_ns(sampledb->rbtdb, version, origin, origin)); CHECK(add_a(sampledb->rbtdb, version, origin, a_addr)); dns_db_closeversion(sampledb->rbtdb, &version, ISC_TRUE); *dbp = (dns_db_t *)sampledb; return (ISC_R_SUCCESS); cleanup: if (sampledb != NULL) { if (dns_name_dynamic(&sampledb->common.origin)) dns_name_free(&sampledb->common.origin, mctx); isc_mem_putanddetach(&sampledb->common.mctx, sampledb, sizeof(*sampledb)); } return (result); }
/*% 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); }
int main(int argc, char *argv[]) { int i, ch; char *startstr = NULL, *endstr = NULL; dns_fixedname_t fdomain; dns_name_t *domain = NULL; char *output = NULL; char *endp; unsigned char data[65536]; dns_db_t *db; dns_dbversion_t *version; dns_diff_t diff; dns_difftuple_t *tuple; dns_fixedname_t tname; dst_key_t *key = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t rdataset; dns_rdataclass_t rdclass; isc_result_t result; isc_buffer_t b; isc_region_t r; isc_log_t *log = NULL; keynode_t *keynode; unsigned int eflags; isc_boolean_t pseudorandom = ISC_FALSE; isc_boolean_t tryverify = ISC_FALSE; result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) fatal("failed to create memory context: %s", isc_result_totext(result)); dns_result_register(); while ((ch = isc_commandline_parse(argc, argv, "as:e:t:r:v:ph")) != -1) { switch (ch) { case 'a': tryverify = ISC_TRUE; break; case 's': startstr = isc_commandline_argument; break; case 'e': endstr = isc_commandline_argument; break; case 't': endp = NULL; ttl = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("TTL must be numeric"); break; case 'r': setup_entropy(mctx, isc_commandline_argument, &ectx); break; case 'v': endp = NULL; verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') fatal("verbose level must be numeric"); break; case 'p': pseudorandom = ISC_TRUE; break; case 'h': default: usage(); } } argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 1) usage(); if (ectx == NULL) setup_entropy(mctx, NULL, &ectx); eflags = ISC_ENTROPY_BLOCKING; if (!pseudorandom) eflags |= ISC_ENTROPY_GOODONLY; result = dst_lib_init(mctx, ectx, eflags); if (result != ISC_R_SUCCESS) fatal("could not initialize dst: %s", isc_result_totext(result)); isc_stdtime_get(&now); if (startstr != NULL) starttime = strtotime(startstr, now, now); else starttime = now; if (endstr != NULL) endtime = strtotime(endstr, now, starttime); else endtime = starttime + (30 * 24 * 60 * 60); if (ttl == -1) { ttl = 3600; fprintf(stderr, "%s: TTL not specified, assuming 3600\n", program); } setup_logging(verbose, mctx, &log); dns_diff_init(mctx, &diff); rdclass = 0; ISC_LIST_INIT(keylist); for (i = 0; i < argc; i++) { char namestr[DNS_NAME_FORMATSIZE]; isc_buffer_t namebuf; key = NULL; result = dst_key_fromnamedfile(argv[i], DST_TYPE_PUBLIC, mctx, &key); if (result != ISC_R_SUCCESS) fatal("error loading key from %s: %s", argv[i], isc_result_totext(result)); if (rdclass == 0) rdclass = dst_key_class(key); isc_buffer_init(&namebuf, namestr, sizeof(namestr)); result = dns_name_tofilenametext(dst_key_name(key), ISC_FALSE, &namebuf); check_result(result, "dns_name_tofilenametext"); isc_buffer_putuint8(&namebuf, 0); if (domain == NULL) { dns_fixedname_init(&fdomain); domain = dns_fixedname_name(&fdomain); dns_name_copy(dst_key_name(key), domain, NULL); } else if (!dns_name_equal(domain, dst_key_name(key))) { char str[DNS_NAME_FORMATSIZE]; dns_name_format(domain, str, sizeof(str)); fatal("all keys must have the same owner - %s " "and %s do not match", str, namestr); } if (output == NULL) { output = isc_mem_allocate(mctx, strlen("keyset-") + strlen(namestr) + 1); if (output == NULL) fatal("out of memory"); sprintf(output, "keyset-%s", namestr); } if (dst_key_iszonekey(key)) { dst_key_t *zonekey = NULL; result = dst_key_fromnamedfile(argv[i], DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, mctx, &zonekey); if (result != ISC_R_SUCCESS) fatal("failed to read private key %s: %s", argv[i], isc_result_totext(result)); if (!zonekey_on_list(zonekey)) { keynode = isc_mem_get(mctx, sizeof(keynode_t)); if (keynode == NULL) fatal("out of memory"); keynode->key = zonekey; ISC_LIST_INITANDAPPEND(keylist, keynode, link); } else dst_key_free(&zonekey); } dns_rdata_reset(&rdata); isc_buffer_init(&b, data, sizeof(data)); result = dst_key_todns(key, &b); dst_key_free(&key); if (result != ISC_R_SUCCESS) fatal("failed to convert key %s to a DNS KEY: %s", argv[i], isc_result_totext(result)); isc_buffer_usedregion(&b, &r); dns_rdata_fromregion(&rdata, rdclass, dns_rdatatype_dnskey, &r); tuple = NULL; result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, domain, ttl, &rdata, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(&diff, &tuple); } db = NULL; result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, rdclass, 0, NULL, &db); if (result != ISC_R_SUCCESS) fatal("failed to create a database"); version = NULL; dns_db_newversion(db, &version); result = dns_diff_apply(&diff, db, version); check_result(result, "dns_diff_apply"); dns_diff_clear(&diff); dns_fixedname_init(&tname); dns_rdataset_init(&rdataset); result = dns_db_find(db, domain, version, dns_rdatatype_dnskey, 0, 0, NULL, dns_fixedname_name(&tname), &rdataset, NULL); check_result(result, "dns_db_find"); if (ISC_LIST_EMPTY(keylist)) fprintf(stderr, "%s: no private zone key found; not self-signing\n", program); for (keynode = ISC_LIST_HEAD(keylist); keynode != NULL; keynode = ISC_LIST_NEXT(keynode, link)) { dns_rdata_reset(&rdata); isc_buffer_init(&b, data, sizeof(data)); result = dns_dnssec_sign(domain, &rdataset, keynode->key, &starttime, &endtime, mctx, &b, &rdata); isc_entropy_stopcallbacksources(ectx); if (result != ISC_R_SUCCESS) { char keystr[KEY_FORMATSIZE]; key_format(keynode->key, keystr, sizeof(keystr)); fatal("failed to sign keyset with key %s: %s", keystr, isc_result_totext(result)); } if (tryverify) { result = dns_dnssec_verify(domain, &rdataset, keynode->key, ISC_TRUE, mctx, &rdata); if (result != ISC_R_SUCCESS) { char keystr[KEY_FORMATSIZE]; key_format(keynode->key, keystr, sizeof(keystr)); fatal("signature from key '%s' failed to " "verify: %s", keystr, isc_result_totext(result)); } } tuple = NULL; result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, domain, ttl, &rdata, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(&diff, &tuple); } result = dns_diff_apply(&diff, db, version); check_result(result, "dns_diff_apply"); dns_diff_clear(&diff); dns_rdataset_disassociate(&rdataset); dns_db_closeversion(db, &version, ISC_TRUE); result = dns_db_dump(db, version, output); if (result != ISC_R_SUCCESS) { char domainstr[DNS_NAME_FORMATSIZE]; dns_name_format(domain, domainstr, sizeof(domainstr)); fatal("failed to write database for %s to %s", domainstr, output); } printf("%s\n", output); dns_db_detach(&db); while (!ISC_LIST_EMPTY(keylist)) { keynode = ISC_LIST_HEAD(keylist); ISC_LIST_UNLINK(keylist, keynode, link); dst_key_free(&keynode->key); isc_mem_put(mctx, keynode, sizeof(keynode_t)); } cleanup_logging(&log); cleanup_entropy(&ectx); isc_mem_free(mctx, output); dst_lib_destroy(); if (verbose > 10) isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); return (0); }