void key_options_add_modify(nsd_options_t* opt, key_options_t* key) { key_options_t* orig = key_options_find(opt, key->name); if(!orig) { /* needs to be copied to opt region */ orig = key_options_create(opt->region); orig->name = region_strdup(opt->region, key->name); orig->algorithm = region_strdup(opt->region, key->algorithm); orig->secret = region_strdup(opt->region, key->secret); key_options_setup(opt->region, orig); tsig_add_key(orig->tsig_key); key_options_insert(opt, orig); } else { /* modify entries in existing key, and copy to opt region */ key_options_desetup(opt->region, orig); region_recycle(opt->region, orig->algorithm, strlen(orig->algorithm)+1); orig->algorithm = region_strdup(opt->region, key->algorithm); region_recycle(opt->region, orig->secret, strlen(orig->secret)+1); orig->secret = region_strdup(opt->region, key->secret); key_options_setup(opt->region, orig); } }
void pattern_options_add_modify(nsd_options_t* opt, pattern_options_t* p) { pattern_options_t* orig = pattern_options_find(opt, p->pname); if(!orig) { /* needs to be copied to opt region */ orig = pattern_options_create(opt->region); orig->pname = region_strdup(opt->region, p->pname); copy_pat_fixed(opt->region, orig, p); orig->allow_notify = copy_acl_list(opt, p->allow_notify); orig->request_xfr = copy_acl_list(opt, p->request_xfr); orig->notify = copy_acl_list(opt, p->notify); orig->provide_xfr = copy_acl_list(opt, p->provide_xfr); orig->outgoing_interface = copy_acl_list(opt, p->outgoing_interface); nsd_options_insert_pattern(opt, orig); } else { /* modify in place so pointers stay valid (and copy into region). Do not touch unchanged acls. */ if(orig->zonefile) region_recycle(opt->region, (char*)orig->zonefile, strlen(orig->zonefile)+1); if(orig->zonestats) region_recycle(opt->region, (char*)orig->zonestats, strlen(orig->zonestats)+1); copy_pat_fixed(opt->region, orig, p); copy_changed_acl(opt, &orig->allow_notify, p->allow_notify); copy_changed_acl(opt, &orig->request_xfr, p->request_xfr); copy_changed_acl(opt, &orig->notify, p->notify); copy_changed_acl(opt, &orig->provide_xfr, p->provide_xfr); copy_changed_acl(opt, &orig->outgoing_interface, p->outgoing_interface); } }
zone_options_t* zone_list_zone_insert(nsd_options_t* opt, const char* nm, const char* patnm, int linesize, off_t off) { pattern_options_t* pat = pattern_options_find(opt, patnm); zone_options_t* zone; if(!pat) { log_msg(LOG_ERR, "pattern does not exist for zone %s " "pattern %s", nm, patnm); return NULL; } zone = zone_options_create(opt->region); zone->part_of_config = 0; zone->name = region_strdup(opt->region, nm); zone->linesize = linesize; zone->off = off; zone->pattern = pat; if(!nsd_options_insert_zone(opt, zone)) { log_msg(LOG_ERR, "bad domain name or duplicate zone '%s' " "pattern %s", nm, patnm); region_recycle(opt->region, (void*)zone->name, strlen(nm)+1); region_recycle(opt->region, zone, sizeof(*zone)); return NULL; } return zone; }
static acl_options_t* copy_acl(region_type* region, acl_options_t* a) { acl_options_t* b; if(!a) return NULL; b = (acl_options_t*)region_alloc(region, sizeof(*b)); /* copy the whole lot */ *b = *a; /* fix the pointers */ if(a->ip_address_spec) b->ip_address_spec = region_strdup(region, a->ip_address_spec); if(a->key_name) b->key_name = region_strdup(region, a->key_name); b->next = NULL; b->key_options = NULL; return b; }
static void copy_pat_fixed(region_type* region, pattern_options_t* orig, pattern_options_t* p) { orig->allow_axfr_fallback = p->allow_axfr_fallback; orig->allow_axfr_fallback_is_default = p->allow_axfr_fallback_is_default; orig->notify_retry = p->notify_retry; orig->notify_retry_is_default = p->notify_retry_is_default; orig->implicit = p->implicit; if(p->zonefile) orig->zonefile = region_strdup(region, p->zonefile); else orig->zonefile = NULL; if(p->zonestats) orig->zonestats = region_strdup(region, p->zonestats); else orig->zonestats = NULL; #ifdef RATELIMIT orig->rrl_whitelist = p->rrl_whitelist; #endif }
static char* unmarshal_str(region_type* r, struct buffer* b) { uint8_t nonnull = unmarshal_u8(b); if(nonnull) { char* result = region_strdup(r, (char*)buffer_current(b)); size_t len = strlen((char*)buffer_current(b)); buffer_skip(b, len+1); return result; } else return NULL; }
void config_apply_pattern(const char* name) { /* find the pattern */ pattern_options_t* pat = pattern_options_find(cfg_parser->opt, name); pattern_options_t* a = cfg_parser->current_pattern; if(!pat) { c_error_msg("could not find pattern %s", name); return; } /* apply settings */ if(pat->zonefile) a->zonefile = region_strdup(cfg_parser->opt->region, pat->zonefile); if(pat->zonestats) a->zonestats = region_strdup(cfg_parser->opt->region, pat->zonestats); if(!pat->allow_axfr_fallback_is_default) { a->allow_axfr_fallback = pat->allow_axfr_fallback; a->allow_axfr_fallback_is_default = 0; } if(!pat->notify_retry_is_default) { a->notify_retry = pat->notify_retry; a->notify_retry_is_default = 0; } #ifdef RATELIMIT a->rrl_whitelist |= pat->rrl_whitelist; #endif /* append acl items */ append_acl(&a->allow_notify, &cfg_parser->current_allow_notify, pat->allow_notify); append_acl(&a->request_xfr, &cfg_parser->current_request_xfr, pat->request_xfr); append_acl(&a->notify, &cfg_parser->current_notify, pat->notify); append_acl(&a->provide_xfr, &cfg_parser->current_provide_xfr, pat->provide_xfr); append_acl(&a->outgoing_interface, &cfg_parser-> current_outgoing_interface, pat->outgoing_interface); }
void namedb_write_zonefile(struct nsd* nsd, struct zone_options* zopt) { const char* zfile; int notexist = 0; zone_type* zone; /* if no zone exists, it has no contents or it has no zonefile * configured, then no need to write data to disk */ if(!zopt->pattern->zonefile) return; zone = namedb_find_zone(nsd->db, (const dname_type*)zopt->node.key); if(!zone || !zone->apex || !zone->soa_rrset) return; /* write if file does not exist, or if changed */ /* so, determine filename, create directory components, check exist*/ zfile = config_make_zonefile(zopt, nsd); if(!create_path_components(zfile, ¬exist)) { log_msg(LOG_ERR, "could not write zone %s to file %s because " "the path could not be created", zopt->name, zfile); return; } /* if not changed, do not write. */ if(notexist || zone->is_changed) { char logs[4096]; char bakfile[4096]; struct timespec mtime; udb_ptr zudb; if(nsd->db->udb) { if(!udb_zone_search(nsd->db->udb, &zudb, dname_name(domain_dname(zone->apex)), domain_dname(zone->apex)->name_size)) return; /* zone does not exist in db */ } /* write to zfile~ first, then rename if that works */ snprintf(bakfile, sizeof(bakfile), "%s~", zfile); if(nsd->db->udb && ZONE(&zudb)->log_str.data) { udb_ptr s; udb_ptr_new(&s, nsd->db->udb, &ZONE(&zudb)->log_str); strlcpy(logs, (char*)udb_ptr_data(&s), sizeof(logs)); udb_ptr_unlink(&s, nsd->db->udb); } else if(zone->logstr) { strlcpy(logs, zone->logstr, sizeof(logs)); } else logs[0] = 0; VERBOSITY(1, (LOG_INFO, "writing zone %s to file %s", zone->opts->name, zfile)); if(!write_to_zonefile(zone, bakfile, logs)) { if(nsd->db->udb) udb_ptr_unlink(&zudb, nsd->db->udb); (void)unlink(bakfile); /* delete failed file */ return; /* error already printed */ } if(rename(bakfile, zfile) == -1) { log_msg(LOG_ERR, "rename(%s to %s) failed: %s", bakfile, zfile, strerror(errno)); if(nsd->db->udb) udb_ptr_unlink(&zudb, nsd->db->udb); (void)unlink(bakfile); /* delete failed file */ return; } zone->is_changed = 0; /* fetch the mtime of the just created zonefile so we * do not waste effort reading it back in */ if(!file_get_mtime(zfile, &mtime, ¬exist)) { get_time(&mtime); } if(nsd->db->udb) { ZONE(&zudb)->mtime = (uint64_t)mtime.tv_sec; ZONE(&zudb)->mtime_nsec = (uint64_t)mtime.tv_nsec; ZONE(&zudb)->is_changed = 0; udb_zone_set_log_str(nsd->db->udb, &zudb, NULL); udb_ptr_unlink(&zudb, nsd->db->udb); } else { zone->mtime = mtime; if(zone->filename) region_recycle(nsd->db->region, zone->filename, strlen(zone->filename)+1); zone->filename = region_strdup(nsd->db->region, zfile); if(zone->logstr) region_recycle(nsd->db->region, zone->logstr, strlen(zone->logstr)+1); zone->logstr = NULL; } } }
static int read_sure_part(namedb_type* db, FILE *in, nsd_options_t* opt, struct diff_read_data* data, struct diff_log** log, size_t child_count) { char zone_buf[3072]; char log_buf[5120]; uint32_t old_serial, new_serial, num_parts; uint16_t id; uint8_t committed; struct diff_zone *zp; uint32_t i; int have_all_parts = 1; struct diff_log* thislog = 0; off_t commitpos; /* read zone name and serial */ if(!diff_read_str(in, zone_buf, sizeof(zone_buf)) || !diff_read_32(in, &old_serial) || !diff_read_32(in, &new_serial) || !diff_read_16(in, &id) || !diff_read_32(in, &num_parts)) { log_msg(LOG_ERR, "diff file bad commit part"); return 0; } commitpos = ftello(in); /* position of commit byte */ if(commitpos == -1) { log_msg(LOG_INFO, "could not ftello: %s.", strerror(errno)); return 0; } if(!diff_read_8(in, &committed) || !diff_read_str(in, log_buf, sizeof(log_buf)) ) { log_msg(LOG_ERR, "diff file bad commit part"); return 0; } if(log) { thislog = (struct diff_log*)region_alloc(db->region, sizeof(struct diff_log)); if(!thislog) { log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__); exit(1); } thislog->zone_name = region_strdup(db->region, zone_buf); thislog->comment = region_strdup(db->region, log_buf); thislog->error = 0; thislog->next = *log; *log = thislog; } /* has been read in completely */ zp = diff_read_find_zone(data, zone_buf); if(!zp) { log_msg(LOG_ERR, "diff file commit without IXFR"); if(thislog) thislog->error = "error no IXFR parts"; return 1; } if(committed && check_for_bad_serial(db, zone_buf, old_serial)) { DEBUG(DEBUG_XFRD,1, (LOG_ERR, "skipping diff file commit with bad serial")); zp->parts->root = RBTREE_NULL; zp->parts->count = 0; if(thislog) thislog->error = "error bad serial"; return 1; } for(i=0; i<num_parts; i++) { struct diff_xfrpart *xp = diff_read_find_part(zp, i); if(!xp || xp->id != id || xp->new_serial != new_serial) { have_all_parts = 0; } } if(!have_all_parts) { DEBUG(DEBUG_XFRD,1, (LOG_ERR, "skipping diff file commit without all parts")); if(thislog) thislog->error = "error missing parts"; } if(committed && have_all_parts) { int is_axfr=0, delete_mode=0, rr_count=0; off_t resume_pos; #ifdef NSEC3 #ifndef FULL_PREHASH struct region *region; dname_type const *zone_dname; struct zone *zone; region = region_create(xalloc, free); if (region == NULL) { log_msg(LOG_ERR, "out of memory"); return 0; } zone_dname = dname_parse(region, zone_buf); if (zone_dname == NULL) { log_msg(LOG_ERR, "out of memory"); region_destroy(region); return 0; } zone = find_zone(db, zone_dname, opt, child_count); region_destroy(region); if (zone == NULL) { log_msg(LOG_ERR, "no zone exists"); /* just stop trying applying ixfr */ return 1; } if (0 != namedb_nsec3_mod_domains_create(db)) { log_msg(LOG_ERR, "unable to allocate space " "for modified NSEC3 domains"); return 0; } #endif /* !FULL_PREHASH */ #endif /* NSEC3 */ DEBUG(DEBUG_XFRD,1, (LOG_INFO, "processing xfr: %s", log_buf)); resume_pos = ftello(in); if(resume_pos == -1) { log_msg(LOG_INFO, "could not ftello: %s.", strerror(errno)); return 0; } for(i=0; i<num_parts; i++) { struct diff_xfrpart *xp = diff_read_find_part(zp, i); int ret; DEBUG(DEBUG_XFRD,2, (LOG_INFO, "processing xfr: apply part %d", (int)i)); ret = apply_ixfr(db, in, &xp->file_pos, zone_buf, new_serial, opt, id, xp->seq_nr, num_parts, &is_axfr, &delete_mode, &rr_count, child_count); if(ret == 0) { log_msg(LOG_ERR, "bad ixfr packet part %d in %s", (int)i, opt->difffile); mark_and_exit(opt, in, commitpos, log_buf); } else if(ret == 2) { break; } } #ifdef NSEC3 #ifndef FULL_PREHASH if (is_axfr != 0) prehash_zone(db, zone); else prehash_zone_incremental(db, zone); #endif /* !FULL_PREHASH */ #endif /* NSEC3 */ if(fseeko(in, resume_pos, SEEK_SET) == -1) { log_msg(LOG_INFO, "could not fseeko: %s.", strerror(errno)); return 0; } } else { DEBUG(DEBUG_XFRD,1, (LOG_INFO, "skipping xfr: %s", log_buf)); } /* clean out the parts for the zone after the commit/rollback */ zp->parts->root = RBTREE_NULL; zp->parts->count = 0; return 1; }
acl_options_t* parse_acl_info(region_type* region, char* ip, const char* key) { char* p; acl_options_t* acl = (acl_options_t*)region_alloc(region, sizeof(acl_options_t)); acl->next = 0; /* ip */ acl->ip_address_spec = region_strdup(region, ip); acl->use_axfr_only = 0; acl->allow_udp = 0; acl->ixfr_disabled = 0; acl->bad_xfr_count = 0; acl->key_options = 0; acl->is_ipv6 = 0; acl->port = 0; memset(&acl->addr, 0, sizeof(union acl_addr_storage)); memset(&acl->range_mask, 0, sizeof(union acl_addr_storage)); if((p=strrchr(ip, '@'))!=0) { if(atoi(p+1) == 0) c_error("expected port number after '@'"); else acl->port = atoi(p+1); *p=0; } acl->rangetype = parse_acl_range_type(ip, &p); if(parse_acl_is_ipv6(ip)) { acl->is_ipv6 = 1; #ifdef INET6 if(inet_pton(AF_INET6, ip, &acl->addr.addr6) != 1) c_error_msg("Bad ip6 address '%s'", ip); if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) if(inet_pton(AF_INET6, p, &acl->range_mask.addr6) != 1) c_error_msg("Bad ip6 address mask '%s'", p); if(acl->rangetype==acl_range_subnet) parse_acl_range_subnet(p, &acl->range_mask.addr6, 128); #else c_error_msg("encountered IPv6 address '%s'.", ip); #endif /* INET6 */ } else { acl->is_ipv6 = 0; if(inet_pton(AF_INET, ip, &acl->addr.addr) != 1) c_error_msg("Bad ip4 address '%s'", ip); if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) if(inet_pton(AF_INET, p, &acl->range_mask.addr) != 1) c_error_msg("Bad ip4 address mask '%s'", p); if(acl->rangetype==acl_range_subnet) parse_acl_range_subnet(p, &acl->range_mask.addr, 32); } /* key */ if(strcmp(key, "NOKEY")==0) { acl->nokey = 1; acl->blocked = 0; acl->key_name = 0; } else if(strcmp(key, "BLOCKED")==0) { acl->nokey = 0; acl->blocked = 1; acl->key_name = 0; } else { acl->nokey = 0; acl->blocked = 0; acl->key_name = region_strdup(region, key); } return acl; }
int parse_options_file(nsd_options_t* opt, const char* file, void (*err)(void*,const char*), void* err_arg) { FILE *in = 0; pattern_options_t* pat; acl_options_t* acl; if(!cfg_parser) { cfg_parser = (config_parser_state_t*)region_alloc( opt->region, sizeof(config_parser_state_t)); cfg_parser->chroot = 0; } cfg_parser->err = err; cfg_parser->err_arg = err_arg; cfg_parser->filename = (char*)file; cfg_parser->line = 1; cfg_parser->errors = 0; cfg_parser->server_settings_seen = 0; cfg_parser->opt = opt; cfg_parser->current_pattern = 0; cfg_parser->current_zone = 0; cfg_parser->current_key = 0; cfg_parser->current_ip_address_option = opt->ip_addresses; while(cfg_parser->current_ip_address_option && cfg_parser->current_ip_address_option->next) cfg_parser->current_ip_address_option = cfg_parser->current_ip_address_option->next; cfg_parser->current_allow_notify = 0; cfg_parser->current_request_xfr = 0; cfg_parser->current_notify = 0; cfg_parser->current_provide_xfr = 0; in = fopen(cfg_parser->filename, "r"); if(!in) { if(err) { char m[MAXSYSLOGMSGLEN]; snprintf(m, sizeof(m), "Could not open %s: %s\n", file, strerror(errno)); err(err_arg, m); } else { fprintf(stderr, "Could not open %s: %s\n", file, strerror(errno)); } return 0; } c_in = in; c_parse(); fclose(in); opt->configfile = region_strdup(opt->region, file); if(cfg_parser->current_pattern) { if(!cfg_parser->current_pattern->pname) c_error("last pattern has no name"); else { if(!nsd_options_insert_pattern(cfg_parser->opt, cfg_parser->current_pattern)) c_error("duplicate pattern"); } } if(cfg_parser->current_zone) { if(!cfg_parser->current_zone->name) c_error("last zone has no name"); else { if(!nsd_options_insert_zone(opt, cfg_parser->current_zone)) c_error("duplicate zone"); } if(!cfg_parser->current_zone->pattern) c_error("last zone has no pattern"); } if(cfg_parser->current_key) { if(!cfg_parser->current_key->name) c_error("last key has no name"); if(!cfg_parser->current_key->algorithm) c_error("last key has no algorithm"); if(!cfg_parser->current_key->secret) c_error("last key has no secret blob"); key_options_insert(opt, cfg_parser->current_key); } RBTREE_FOR(pat, pattern_options_t*, opt->patterns) { /* lookup keys for acls */ for(acl=pat->allow_notify; acl; acl=acl->next) { if(acl->nokey || acl->blocked) continue; acl->key_options = key_options_find(opt, acl->key_name); if(!acl->key_options) c_error_msg("key %s in pattern %s could not be found", acl->key_name, pat->pname); } for(acl=pat->notify; acl; acl=acl->next) { if(acl->nokey || acl->blocked) continue; acl->key_options = key_options_find(opt, acl->key_name); if(!acl->key_options) c_error_msg("key %s in pattern %s could not be found", acl->key_name, pat->pname); } for(acl=pat->request_xfr; acl; acl=acl->next) { if(acl->nokey || acl->blocked) continue; acl->key_options = key_options_find(opt, acl->key_name); if(!acl->key_options) c_error_msg("key %s in pattern %s could not be found", acl->key_name, pat->pname); } for(acl=pat->provide_xfr; acl; acl=acl->next) { if(acl->nokey || acl->blocked) continue; acl->key_options = key_options_find(opt, acl->key_name); if(!acl->key_options) c_error_msg("key %s in pattern %s could not be found", acl->key_name, pat->pname); } } if(cfg_parser->errors > 0) { if(err) { char m[MAXSYSLOGMSGLEN]; snprintf(m, sizeof(m), "read %s failed: %d errors in " "configuration file\n", file, cfg_parser->errors); err(err_arg, m); } else { fprintf(stderr, "read %s failed: %d errors in " "configuration file\n", file, cfg_parser->errors); } return 0; } return 1; }
struct namedb * namedb_open (const char *filename, nsd_options_t* opt, size_t num_children) { namedb_type *db; /* * Temporary region used while loading domain names from the * database. The region is freed after each time a dname is * read from the database. */ region_type *dname_region; /* * Temporary region used to store array of domains and zones * while loading the database. The region is freed before * returning. */ region_type *temp_region; uint32_t dname_count; domain_type **domains; /* Indexed by domain number. */ uint32_t zone_count; zone_type **zones; /* Indexed by zone number. */ uint32_t i; uint32_t rrset_count = 0; uint32_t rr_count = 0; rrset_type *rrset; DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(namedb_type) = %lu\n", (unsigned long) sizeof(namedb_type))); DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(zone_type) = %lu\n", (unsigned long) sizeof(zone_type))); DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(domain_type) = %lu\n", (unsigned long) sizeof(domain_type))); DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(rrset_type) = %lu\n", (unsigned long) sizeof(rrset_type))); DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(rr_type) = %lu\n", (unsigned long) sizeof(rr_type))); DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(rdata_atom_type) = %lu\n", (unsigned long) sizeof(rdata_atom_type))); DEBUG(DEBUG_DBACCESS, 2, (LOG_INFO, "sizeof(rbnode_t) = %lu\n", (unsigned long) sizeof(rbnode_t))); if ((db = namedb_create()) == NULL) { log_msg(LOG_ERR, "insufficient memory to create database"); return NULL; } db->filename = region_strdup(db->region, filename); if (gettimeofday(&(db->diff_timestamp), NULL) != 0) { log_msg(LOG_ERR, "unable to load %s: cannot initialize" "timestamp", db->filename); namedb_destroy(db); return NULL; } /* Open it... */ db->fd = fopen(db->filename, "r"); if (db->fd == NULL) { log_msg(LOG_ERR, "unable to load %s: %s", db->filename, strerror(errno)); namedb_destroy(db); return NULL; } if (!read_magic(db)) { log_msg(LOG_ERR, "corrupted database (read magic): %s", db->filename); log_msg(LOG_ERR, "cannot load database, incompatible version " "number. Please rebuild database and " "start again."); namedb_close(db); return NULL; } if (!read_size(db, &zone_count)) { log_msg(LOG_ERR, "corrupted database (read size): %s", db->filename); namedb_close(db); return NULL; } DEBUG(DEBUG_DBACCESS, 1, (LOG_INFO, "Retrieving %lu zones\n", (unsigned long) zone_count)); temp_region = region_create(xalloc, free); dname_region = region_create(xalloc, free); db->zone_count = zone_count; zones = (zone_type **) region_alloc(temp_region, zone_count * sizeof(zone_type *)); for (i = 0; i < zone_count; ++i) { const dname_type *dname = read_dname(db->fd, dname_region); if (!dname) { log_msg(LOG_ERR, "corrupted database (read dname): %s", db->filename); region_destroy(dname_region); region_destroy(temp_region); namedb_close(db); return NULL; } zones[i] = (zone_type *) region_alloc(db->region, sizeof(zone_type)); zones[i]->next = db->zones; db->zones = zones[i]; zones[i]->apex = domain_table_insert(db->domains, dname); zones[i]->soa_rrset = NULL; zones[i]->soa_nx_rrset = NULL; zones[i]->ns_rrset = NULL; #ifdef NSEC3 zones[i]->nsec3_soa_rr = NULL; zones[i]->nsec3_last = NULL; #endif zones[i]->opts = zone_options_find(opt, domain_dname(zones[i]->apex)); zones[i]->number = i + 1; zones[i]->is_secure = 0; zones[i]->updated = 1; zones[i]->is_ok = 0; zones[i]->dirty = region_alloc(db->region, sizeof(uint8_t)*num_children); memset(zones[i]->dirty, 0, sizeof(uint8_t)*num_children); if(!zones[i]->opts) { log_msg(LOG_ERR, "cannot load database. Zone %s in db " "%s, but not in config file (might " "happen if you edited the config " "file). Please rebuild database and " "start again.", dname_to_string(dname, NULL), db->filename); region_destroy(dname_region); region_destroy(temp_region); namedb_close(db); return NULL; } #ifdef NSEC3 #ifndef FULL_PREHASH zones[i]->nsec3_domains = NULL; if (0 != zone_nsec3_domains_create(db, zones[i])) { log_msg(LOG_ERR, "insufficient memory for NSEC3 tree, " "unable to read database"); region_destroy(dname_region); region_destroy(temp_region); namedb_close(db); return NULL; } #endif /* !FULL_PREHASH */ #endif /* NSEC3 */ region_free_all(dname_region); } if (!read_size(db, &dname_count)) { log_msg(LOG_ERR, "corrupted database (read size): %s", db->filename); region_destroy(dname_region); region_destroy(temp_region); namedb_close(db); return NULL; } DEBUG(DEBUG_DBACCESS, 1, (LOG_INFO, "Retrieving %lu domain names\n", (unsigned long) dname_count)); domains = (domain_type **) region_alloc( temp_region, dname_count * sizeof(domain_type *)); for (i = 0; i < dname_count; ++i) { const dname_type *dname = read_dname(db->fd, dname_region); if (!dname) { log_msg(LOG_ERR, "corrupted database (read dname): %s", db->filename); region_destroy(dname_region); region_destroy(temp_region); namedb_close(db); return NULL; } domains[i] = domain_table_insert(db->domains, dname); region_free_all(dname_region); } region_destroy(dname_region); #ifndef NDEBUG fprintf(stderr, "database region after loading domain names: "); region_dump_stats(db->region, stderr); fprintf(stderr, "\n"); #endif while ((rrset = read_rrset(db, dname_count, domains, zone_count, zones))) { ++rrset_count; rr_count += rrset->rr_count; } DEBUG(DEBUG_DBACCESS, 1, (LOG_INFO, "Retrieved %lu RRs in %lu RRsets\n", (unsigned long) rr_count, (unsigned long) rrset_count)); region_destroy(temp_region); if ((db->crc_pos = ftello(db->fd)) == -1) { log_msg(LOG_ERR, "ftello %s failed: %s", db->filename, strerror(errno)); namedb_close(db); return NULL; } if (!read_size(db, &db->crc)) { log_msg(LOG_ERR, "corrupted database (read size): %s", db->filename); namedb_close(db); return NULL; } if (!read_magic(db)) { log_msg(LOG_ERR, "corrupted database (read magic): %s", db->filename); log_msg(LOG_ERR, "cannot load database, incompatible version " "number. Please rebuild database and " "start again."); namedb_close(db); return NULL; } fclose(db->fd); db->fd = NULL; #ifndef NDEBUG fprintf(stderr, "database region after loading database: "); region_dump_stats(db->region, stderr); fprintf(stderr, "\n"); #endif return db; }