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); } }
static acl_options_t* copy_acl_list(nsd_options_t* opt, acl_options_t* a) { acl_options_t* b, *blast = NULL, *blist = NULL; while(a) { b = copy_acl(opt->region, a); /* fixup key_options */ if(b->key_name) b->key_options = key_options_find(opt, b->key_name); else b->key_options = NULL; /* link as last into list */ b->next = NULL; if(!blist) blist = b; else blast->next = b; blast = b; a = a->next; } return blist; }
void key_options_remove(nsd_options_t* opt, const char* name) { key_options_t* k = key_options_find(opt, name); if(!k) return; (void)rbtree_delete(opt->keys, name); if(k->name) region_recycle(opt->region, k->name, strlen(k->name)+1); if(k->algorithm) region_recycle(opt->region, k->algorithm, strlen(k->algorithm)+1); if(k->secret) { memset(k->secret, 0xdd, strlen(k->secret)); /* wipe secret! */ region_recycle(opt->region, k->secret, strlen(k->secret)+1); } if(k->tsig_key) { tsig_del_key(k->tsig_key); if(k->tsig_key->name) region_recycle(opt->region, (void*)k->tsig_key->name, dname_total_size(k->tsig_key->name)); key_options_desetup(opt->region, k); region_recycle(opt->region, k->tsig_key, sizeof(tsig_key_type)); } region_recycle(opt->region, k, sizeof(key_options_t)); }
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; }
int parse_options_file(nsd_options_t* opt, const char* file) { FILE *in = 0; zone_options_t* zone; acl_options_t* acl; if(!cfg_parser) cfg_parser = (config_parser_state_t*)region_alloc( opt->region, sizeof(config_parser_state_t)); cfg_parser->filename = file; cfg_parser->line = 1; cfg_parser->errors = 0; cfg_parser->opt = opt; cfg_parser->current_zone = 0; cfg_parser->current_key = opt->keys; while(cfg_parser->current_key && cfg_parser->current_key->next) cfg_parser->current_key = cfg_parser->current_key->next; 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) { fprintf(stderr, "Could not open %s: %s\n", file, strerror(errno)); return 0; } c_in = in; c_parse(); fclose(in); 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->zonefile) c_error("last zone has no zonefile"); } if(opt->keys) { if(!opt->keys->name) c_error("last key has no name"); if(!opt->keys->algorithm) c_error("last key has no algorithm"); if(!opt->keys->secret) c_error("last key has no secret blob"); } RBTREE_FOR(zone, zone_options_t*, opt->zone_options) { if(!zone->name) continue; if(!zone->zonefile) continue; /* lookup keys for acls */ for(acl=zone->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 zone %s could not be found", acl->key_name, zone->name); } for(acl=zone->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 zone %s could not be found", acl->key_name, zone->name); } for(acl=zone->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 zone %s could not be found", acl->key_name, zone->name); } for(acl=zone->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 zone %s could not be found", acl->key_name, zone->name); } } if(cfg_parser->errors > 0) { fprintf(stderr, "read %s failed: %d errors in configuration file\n", cfg_parser->filename, cfg_parser->errors); return 0; } return 1; }