1 /* 2 * options.c -- options functions. 3 * 4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 */ 9 #include "config.h" 10 #include <string.h> 11 #include <stdio.h> 12 #include <errno.h> 13 #include "options.h" 14 #include "query.h" 15 #include "tsig.h" 16 #include "difffile.h" 17 #include "rrl.h" 18 19 #include "configyyrename.h" 20 #include "configparser.h" 21 config_parser_state_t* cfg_parser = 0; 22 extern FILE* c_in, *c_out; 23 int c_parse(void); 24 int c_lex(void); 25 int c_wrap(void); 26 void c_error(const char *message); 27 extern char* c_text; 28 29 static int 30 rbtree_strcmp(const void* p1, const void* p2) 31 { 32 if(p1 == NULL && p2 == NULL) return 0; 33 if(p1 == NULL) return -1; 34 if(p2 == NULL) return 1; 35 return strcmp((const char*)p1, (const char*)p2); 36 } 37 38 nsd_options_t* 39 nsd_options_create(region_type* region) 40 { 41 nsd_options_t* opt; 42 opt = (nsd_options_t*)region_alloc(region, sizeof(nsd_options_t)); 43 opt->region = region; 44 opt->zone_options = rbtree_create(region, 45 (int (*)(const void *, const void *)) dname_compare); 46 opt->configfile = NULL; 47 opt->zonestatnames = rbtree_create(opt->region, rbtree_strcmp); 48 opt->patterns = rbtree_create(region, rbtree_strcmp); 49 opt->keys = rbtree_create(region, rbtree_strcmp); 50 opt->ip_addresses = NULL; 51 opt->ip_transparent = 0; 52 opt->ip_freebind = 0; 53 opt->debug_mode = 0; 54 opt->verbosity = 0; 55 opt->hide_version = 0; 56 opt->do_ip4 = 1; 57 opt->do_ip6 = 1; 58 opt->database = DBFILE; 59 opt->identity = 0; 60 opt->version = 0; 61 opt->nsid = 0; 62 opt->logfile = 0; 63 opt->log_time_ascii = 1; 64 opt->round_robin = 0; /* also packet.h::round_robin */ 65 opt->server_count = 1; 66 opt->tcp_count = 100; 67 opt->tcp_query_count = 0; 68 opt->tcp_timeout = TCP_TIMEOUT; 69 opt->tcp_mss = 0; 70 opt->outgoing_tcp_mss = 0; 71 opt->ipv4_edns_size = EDNS_MAX_MESSAGE_LEN; 72 opt->ipv6_edns_size = EDNS_MAX_MESSAGE_LEN; 73 opt->pidfile = PIDFILE; 74 opt->port = UDP_PORT; 75 /* deprecated? opt->port = TCP_PORT; */ 76 opt->reuseport = 0; 77 opt->statistics = 0; 78 opt->chroot = 0; 79 opt->username = USER; 80 opt->zonesdir = ZONESDIR; 81 opt->xfrdfile = XFRDFILE; 82 opt->xfrdir = XFRDIR; 83 opt->zonelistfile = ZONELISTFILE; 84 #ifdef RATELIMIT 85 opt->rrl_size = RRL_BUCKETS; 86 opt->rrl_slip = RRL_SLIP; 87 opt->rrl_ipv4_prefix_length = RRL_IPV4_PREFIX_LENGTH; 88 opt->rrl_ipv6_prefix_length = RRL_IPV6_PREFIX_LENGTH; 89 # ifdef RATELIMIT_DEFAULT_OFF 90 opt->rrl_ratelimit = 0; 91 opt->rrl_whitelist_ratelimit = 0; 92 # else 93 opt->rrl_ratelimit = RRL_LIMIT/2; 94 opt->rrl_whitelist_ratelimit = RRL_WLIST_LIMIT/2; 95 # endif 96 #endif 97 opt->zonefiles_check = 1; 98 if(opt->database == NULL || opt->database[0] == 0) 99 opt->zonefiles_write = ZONEFILES_WRITE_INTERVAL; 100 else opt->zonefiles_write = 0; 101 opt->xfrd_reload_timeout = 1; 102 opt->control_enable = 0; 103 opt->control_interface = NULL; 104 opt->control_port = NSD_CONTROL_PORT; 105 opt->server_key_file = CONFIGDIR"/nsd_server.key"; 106 opt->server_cert_file = CONFIGDIR"/nsd_server.pem"; 107 opt->control_key_file = CONFIGDIR"/nsd_control.key"; 108 opt->control_cert_file = CONFIGDIR"/nsd_control.pem"; 109 return opt; 110 } 111 112 int 113 nsd_options_insert_zone(nsd_options_t* opt, zone_options_t* zone) 114 { 115 /* create dname for lookup */ 116 const dname_type* dname = dname_parse(opt->region, zone->name); 117 if(!dname) 118 return 0; 119 zone->node.key = dname; 120 if(!rbtree_insert(opt->zone_options, (rbnode_t*)zone)) 121 return 0; 122 return 1; 123 } 124 125 int 126 nsd_options_insert_pattern(nsd_options_t* opt, pattern_options_t* pat) 127 { 128 if(!pat->pname) 129 return 0; 130 pat->node.key = pat->pname; 131 if(!rbtree_insert(opt->patterns, (rbnode_t*)pat)) 132 return 0; 133 return 1; 134 } 135 136 int 137 parse_options_file(nsd_options_t* opt, const char* file, 138 void (*err)(void*,const char*), void* err_arg) 139 { 140 FILE *in = 0; 141 pattern_options_t* pat; 142 acl_options_t* acl; 143 144 if(!cfg_parser) { 145 cfg_parser = (config_parser_state_t*)region_alloc( 146 opt->region, sizeof(config_parser_state_t)); 147 cfg_parser->chroot = 0; 148 } 149 cfg_parser->err = err; 150 cfg_parser->err_arg = err_arg; 151 cfg_parser->filename = (char*)file; 152 cfg_parser->line = 1; 153 cfg_parser->errors = 0; 154 cfg_parser->server_settings_seen = 0; 155 cfg_parser->opt = opt; 156 cfg_parser->current_pattern = 0; 157 cfg_parser->current_zone = 0; 158 cfg_parser->current_key = 0; 159 cfg_parser->current_ip_address_option = opt->ip_addresses; 160 while(cfg_parser->current_ip_address_option && cfg_parser->current_ip_address_option->next) 161 cfg_parser->current_ip_address_option = cfg_parser->current_ip_address_option->next; 162 cfg_parser->current_allow_notify = 0; 163 cfg_parser->current_request_xfr = 0; 164 cfg_parser->current_notify = 0; 165 cfg_parser->current_provide_xfr = 0; 166 167 in = fopen(cfg_parser->filename, "r"); 168 if(!in) { 169 if(err) { 170 char m[MAXSYSLOGMSGLEN]; 171 snprintf(m, sizeof(m), "Could not open %s: %s\n", 172 file, strerror(errno)); 173 err(err_arg, m); 174 } else { 175 fprintf(stderr, "Could not open %s: %s\n", 176 file, strerror(errno)); 177 } 178 return 0; 179 } 180 c_in = in; 181 c_parse(); 182 fclose(in); 183 184 opt->configfile = region_strdup(opt->region, file); 185 if(cfg_parser->current_pattern) { 186 if(!cfg_parser->current_pattern->pname) 187 c_error("last pattern has no name"); 188 else { 189 if(!nsd_options_insert_pattern(cfg_parser->opt, 190 cfg_parser->current_pattern)) 191 c_error("duplicate pattern"); 192 } 193 } 194 if(cfg_parser->current_zone) { 195 if(!cfg_parser->current_zone->name) 196 c_error("last zone has no name"); 197 else { 198 if(!nsd_options_insert_zone(opt, 199 cfg_parser->current_zone)) 200 c_error("duplicate zone"); 201 } 202 if(!cfg_parser->current_zone->pattern) 203 c_error("last zone has no pattern"); 204 } 205 if(cfg_parser->current_key) 206 { 207 if(!cfg_parser->current_key->name) 208 c_error("last key has no name"); 209 if(!cfg_parser->current_key->algorithm) 210 c_error("last key has no algorithm"); 211 if(!cfg_parser->current_key->secret) 212 c_error("last key has no secret blob"); 213 key_options_insert(opt, cfg_parser->current_key); 214 } 215 RBTREE_FOR(pat, pattern_options_t*, opt->patterns) 216 { 217 /* lookup keys for acls */ 218 for(acl=pat->allow_notify; acl; acl=acl->next) 219 { 220 if(acl->nokey || acl->blocked) 221 continue; 222 acl->key_options = key_options_find(opt, acl->key_name); 223 if(!acl->key_options) 224 c_error_msg("key %s in pattern %s could not be found", 225 acl->key_name, pat->pname); 226 } 227 for(acl=pat->notify; acl; acl=acl->next) 228 { 229 if(acl->nokey || acl->blocked) 230 continue; 231 acl->key_options = key_options_find(opt, acl->key_name); 232 if(!acl->key_options) 233 c_error_msg("key %s in pattern %s could not be found", 234 acl->key_name, pat->pname); 235 } 236 for(acl=pat->request_xfr; acl; acl=acl->next) 237 { 238 if(acl->nokey || acl->blocked) 239 continue; 240 acl->key_options = key_options_find(opt, acl->key_name); 241 if(!acl->key_options) 242 c_error_msg("key %s in pattern %s could not be found", 243 acl->key_name, pat->pname); 244 } 245 for(acl=pat->provide_xfr; acl; acl=acl->next) 246 { 247 if(acl->nokey || acl->blocked) 248 continue; 249 acl->key_options = key_options_find(opt, acl->key_name); 250 if(!acl->key_options) 251 c_error_msg("key %s in pattern %s could not be found", 252 acl->key_name, pat->pname); 253 } 254 } 255 256 if(cfg_parser->errors > 0) 257 { 258 if(err) { 259 char m[MAXSYSLOGMSGLEN]; 260 snprintf(m, sizeof(m), "read %s failed: %d errors in " 261 "configuration file\n", file, 262 cfg_parser->errors); 263 err(err_arg, m); 264 } else { 265 fprintf(stderr, "read %s failed: %d errors in " 266 "configuration file\n", file, 267 cfg_parser->errors); 268 } 269 return 0; 270 } 271 return 1; 272 } 273 274 void options_zonestatnames_create(nsd_options_t* opt) 275 { 276 zone_options_t* zopt; 277 /* allocate "" as zonestat 0, for zones without a zonestat */ 278 if(!rbtree_search(opt->zonestatnames, "")) { 279 struct zonestatname* n; 280 n = (struct zonestatname*)xalloc(sizeof(*n)); 281 memset(n, 0, sizeof(*n)); 282 n->node.key = strdup(""); 283 if(!n->node.key) { 284 log_msg(LOG_ERR, "malloc failed: %s", strerror(errno)); 285 exit(1); 286 } 287 n->id = (unsigned)(opt->zonestatnames->count); 288 rbtree_insert(opt->zonestatnames, (rbnode_t*)n); 289 } 290 RBTREE_FOR(zopt, zone_options_t*, opt->zone_options) { 291 /* insert into tree, so that when read in later id exists */ 292 (void)getzonestatid(opt, zopt); 293 } 294 } 295 296 #define ZONELIST_HEADER "# NSD zone list\n# name pattern\n" 297 static int 298 comp_zonebucket(const void* a, const void* b) 299 { 300 /* the line size is much smaller than max-int, and positive, 301 * so the subtraction works */ 302 return *(const int*)b - *(const int*)a; 303 } 304 305 /* insert free entry into zonelist free buckets */ 306 static void 307 zone_list_free_insert(nsd_options_t* opt, int linesize, off_t off) 308 { 309 struct zonelist_free* e; 310 struct zonelist_bucket* b = (struct zonelist_bucket*)rbtree_search( 311 opt->zonefree, &linesize); 312 if(!b) { 313 b = region_alloc_zero(opt->region, sizeof(*b)); 314 b->linesize = linesize; 315 b->node = *RBTREE_NULL; 316 b->node.key = &b->linesize; 317 rbtree_insert(opt->zonefree, &b->node); 318 } 319 e = (struct zonelist_free*)region_alloc_zero(opt->region, sizeof(*e)); 320 e->next = b->list; 321 b->list = e; 322 e->off = off; 323 opt->zonefree_number++; 324 } 325 326 zone_options_t* 327 zone_list_zone_insert(nsd_options_t* opt, const char* nm, const char* patnm, 328 int linesize, off_t off) 329 { 330 pattern_options_t* pat = pattern_options_find(opt, patnm); 331 zone_options_t* zone; 332 if(!pat) { 333 log_msg(LOG_ERR, "pattern does not exist for zone %s " 334 "pattern %s", nm, patnm); 335 return NULL; 336 } 337 zone = zone_options_create(opt->region); 338 zone->part_of_config = 0; 339 zone->name = region_strdup(opt->region, nm); 340 zone->linesize = linesize; 341 zone->off = off; 342 zone->pattern = pat; 343 if(!nsd_options_insert_zone(opt, zone)) { 344 log_msg(LOG_ERR, "bad domain name or duplicate zone '%s' " 345 "pattern %s", nm, patnm); 346 region_recycle(opt->region, (void*)zone->name, strlen(nm)+1); 347 region_recycle(opt->region, zone, sizeof(*zone)); 348 return NULL; 349 } 350 return zone; 351 } 352 353 int 354 parse_zone_list_file(nsd_options_t* opt) 355 { 356 /* zonelist looks like this: 357 # name pattern 358 add example.com master 359 del example.net slave 360 add foo.bar.nl slave 361 add rutabaga.uk config 362 */ 363 char buf[1024]; 364 365 /* create empty data structures */ 366 opt->zonefree = rbtree_create(opt->region, comp_zonebucket); 367 opt->zonelist = NULL; 368 opt->zonefree_number = 0; 369 opt->zonelist_off = 0; 370 371 /* try to open the zonelist file, an empty or nonexist file is OK */ 372 opt->zonelist = fopen(opt->zonelistfile, "r+"); 373 if(!opt->zonelist) { 374 if(errno == ENOENT) 375 return 1; /* file does not exist, it is created later */ 376 log_msg(LOG_ERR, "could not open zone list %s: %s", opt->zonelistfile, 377 strerror(errno)); 378 return 0; 379 } 380 /* read header */ 381 buf[strlen(ZONELIST_HEADER)] = 0; 382 if(fread(buf, 1, strlen(ZONELIST_HEADER), opt->zonelist) != 383 strlen(ZONELIST_HEADER) || strncmp(buf, ZONELIST_HEADER, 384 strlen(ZONELIST_HEADER)) != 0) { 385 log_msg(LOG_ERR, "zone list %s contains bad header\n", opt->zonelistfile); 386 fclose(opt->zonelist); 387 opt->zonelist = NULL; 388 return 0; 389 } 390 391 /* read entries in file */ 392 while(fgets(buf, sizeof(buf), opt->zonelist)) { 393 /* skip comments and empty lines */ 394 if(buf[0] == 0 || buf[0] == '\n' || buf[0] == '#') 395 continue; 396 if(strncmp(buf, "add ", 4) == 0) { 397 int linesize = strlen(buf); 398 /* parse the 'add' line */ 399 /* pick last space on the line, so that the domain 400 * name can have a space in it (but not the pattern)*/ 401 char* space = strrchr(buf+4, ' '); 402 char* nm, *patnm; 403 if(!space) { 404 /* parse error */ 405 log_msg(LOG_ERR, "parse error in %s: '%s'", 406 opt->zonelistfile, buf); 407 continue; 408 } 409 nm = buf+4; 410 *space = 0; 411 patnm = space+1; 412 if(linesize && buf[linesize-1] == '\n') 413 buf[linesize-1] = 0; 414 415 /* store offset and line size for zone entry */ 416 /* and create zone entry in zonetree */ 417 (void)zone_list_zone_insert(opt, nm, patnm, linesize, 418 ftello(opt->zonelist)-linesize); 419 } else if(strncmp(buf, "del ", 4) == 0) { 420 /* store offset and line size for deleted entry */ 421 int linesize = strlen(buf); 422 zone_list_free_insert(opt, linesize, 423 ftello(opt->zonelist)-linesize); 424 } else { 425 log_msg(LOG_WARNING, "bad data in %s, '%s'", opt->zonelistfile, 426 buf); 427 } 428 } 429 /* store EOF offset */ 430 opt->zonelist_off = ftello(opt->zonelist); 431 return 1; 432 } 433 434 void 435 zone_options_delete(nsd_options_t* opt, zone_options_t* zone) 436 { 437 rbtree_delete(opt->zone_options, zone->node.key); 438 region_recycle(opt->region, (void*)zone->node.key, dname_total_size( 439 (dname_type*)zone->node.key)); 440 region_recycle(opt->region, zone, sizeof(*zone)); 441 } 442 443 /* add a new zone to the zonelist */ 444 zone_options_t* 445 zone_list_add(nsd_options_t* opt, const char* zname, const char* pname) 446 { 447 int r; 448 struct zonelist_free* e; 449 struct zonelist_bucket* b; 450 int linesize = 6 + strlen(zname) + strlen(pname); 451 /* create zone entry */ 452 zone_options_t* zone = zone_list_zone_insert(opt, zname, pname, 453 linesize, 0); 454 if(!zone) 455 return NULL; 456 457 /* use free entry or append to file or create new file */ 458 if(!opt->zonelist || opt->zonelist_off == 0) { 459 /* create new file */ 460 if(opt->zonelist) fclose(opt->zonelist); 461 opt->zonelist = fopen(opt->zonelistfile, "w+"); 462 if(!opt->zonelist) { 463 log_msg(LOG_ERR, "could not create zone list %s: %s", 464 opt->zonelistfile, strerror(errno)); 465 log_msg(LOG_ERR, "zone %s could not be added", zname); 466 zone_options_delete(opt, zone); 467 return NULL; 468 } 469 r = fprintf(opt->zonelist, ZONELIST_HEADER); 470 if(r != strlen(ZONELIST_HEADER)) { 471 if(r == -1) 472 log_msg(LOG_ERR, "could not write to %s: %s", 473 opt->zonelistfile, strerror(errno)); 474 else log_msg(LOG_ERR, "partial write to %s: disk full", 475 opt->zonelistfile); 476 log_msg(LOG_ERR, "zone %s could not be added", zname); 477 zone_options_delete(opt, zone); 478 return NULL; 479 } 480 zone->off = ftello(opt->zonelist); 481 if(zone->off == -1) 482 log_msg(LOG_ERR, "ftello(%s): %s", opt->zonelistfile, strerror(errno)); 483 r = fprintf(opt->zonelist, "add %s %s\n", zname, pname); 484 if(r != zone->linesize) { 485 if(r == -1) 486 log_msg(LOG_ERR, "could not write to %s: %s", 487 opt->zonelistfile, strerror(errno)); 488 else log_msg(LOG_ERR, "partial write to %s: disk full", 489 opt->zonelistfile); 490 log_msg(LOG_ERR, "zone %s could not be added", zname); 491 zone_options_delete(opt, zone); 492 return NULL; 493 } 494 opt->zonelist_off = ftello(opt->zonelist); 495 if(opt->zonelist_off == -1) 496 log_msg(LOG_ERR, "ftello(%s): %s", opt->zonelistfile, strerror(errno)); 497 if(fflush(opt->zonelist) != 0) { 498 log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno)); 499 } 500 return zone; 501 } 502 b = (struct zonelist_bucket*)rbtree_search(opt->zonefree, 503 &zone->linesize); 504 if(!b || b->list == NULL) { 505 /* no empty place, append to file */ 506 zone->off = opt->zonelist_off; 507 if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) { 508 log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno)); 509 log_msg(LOG_ERR, "zone %s could not be added", zname); 510 zone_options_delete(opt, zone); 511 return NULL; 512 } 513 r = fprintf(opt->zonelist, "add %s %s\n", zname, pname); 514 if(r != zone->linesize) { 515 if(r == -1) 516 log_msg(LOG_ERR, "could not write to %s: %s", 517 opt->zonelistfile, strerror(errno)); 518 else log_msg(LOG_ERR, "partial write to %s: disk full", 519 opt->zonelistfile); 520 log_msg(LOG_ERR, "zone %s could not be added", zname); 521 zone_options_delete(opt, zone); 522 return NULL; 523 } 524 opt->zonelist_off += linesize; 525 if(fflush(opt->zonelist) != 0) { 526 log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno)); 527 } 528 return zone; 529 } 530 /* reuse empty spot */ 531 e = b->list; 532 zone->off = e->off; 533 if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) { 534 log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno)); 535 log_msg(LOG_ERR, "zone %s could not be added", zname); 536 zone_options_delete(opt, zone); 537 return NULL; 538 } 539 r = fprintf(opt->zonelist, "add %s %s\n", zname, pname); 540 if(r != zone->linesize) { 541 if(r == -1) 542 log_msg(LOG_ERR, "could not write to %s: %s", 543 opt->zonelistfile, strerror(errno)); 544 else log_msg(LOG_ERR, "partial write to %s: disk full", 545 opt->zonelistfile); 546 log_msg(LOG_ERR, "zone %s could not be added", zname); 547 zone_options_delete(opt, zone); 548 return NULL; 549 } 550 if(fflush(opt->zonelist) != 0) { 551 log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno)); 552 } 553 554 /* snip off and recycle element */ 555 b->list = e->next; 556 region_recycle(opt->region, e, sizeof(*e)); 557 if(b->list == NULL) { 558 rbtree_delete(opt->zonefree, &b->linesize); 559 region_recycle(opt->region, b, sizeof(*b)); 560 } 561 opt->zonefree_number--; 562 return zone; 563 } 564 565 /* remove a zone on the zonelist */ 566 void 567 zone_list_del(nsd_options_t* opt, zone_options_t* zone) 568 { 569 /* put its space onto the free entry */ 570 if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) { 571 log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno)); 572 return; 573 } 574 fprintf(opt->zonelist, "del"); 575 zone_list_free_insert(opt, zone->linesize, zone->off); 576 577 /* remove zone_options_t */ 578 zone_options_delete(opt, zone); 579 580 /* see if we need to compact: it is going to halve the zonelist */ 581 if(opt->zonefree_number > opt->zone_options->count) { 582 zone_list_compact(opt); 583 } else { 584 if(fflush(opt->zonelist) != 0) { 585 log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno)); 586 } 587 } 588 } 589 /* postorder delete of zonelist free space tree */ 590 static void 591 delbucket(region_type* region, struct zonelist_bucket* b) 592 { 593 struct zonelist_free* e, *f; 594 if(!b || (rbnode_t*)b==RBTREE_NULL) 595 return; 596 delbucket(region, (struct zonelist_bucket*)b->node.left); 597 delbucket(region, (struct zonelist_bucket*)b->node.right); 598 e = b->list; 599 while(e) { 600 f = e->next; 601 region_recycle(region, e, sizeof(*e)); 602 e = f; 603 } 604 region_recycle(region, b, sizeof(*b)); 605 } 606 607 /* compact zonelist file */ 608 void 609 zone_list_compact(nsd_options_t* opt) 610 { 611 char outname[1024]; 612 FILE* out; 613 zone_options_t* zone; 614 off_t off; 615 int r; 616 snprintf(outname, sizeof(outname), "%s~", opt->zonelistfile); 617 /* useful, when : count-of-free > count-of-used */ 618 /* write zonelist to zonelist~ */ 619 out = fopen(outname, "w+"); 620 if(!out) { 621 log_msg(LOG_ERR, "could not open %s: %s", outname, strerror(errno)); 622 return; 623 } 624 r = fprintf(out, ZONELIST_HEADER); 625 if(r == -1) { 626 log_msg(LOG_ERR, "write %s failed: %s", outname, 627 strerror(errno)); 628 fclose(out); 629 return; 630 } else if(r != strlen(ZONELIST_HEADER)) { 631 log_msg(LOG_ERR, "write %s was partial: disk full", 632 outname); 633 fclose(out); 634 return; 635 } 636 off = ftello(out); 637 if(off == -1) { 638 log_msg(LOG_ERR, "ftello(%s): %s", outname, strerror(errno)); 639 fclose(out); 640 return; 641 } 642 RBTREE_FOR(zone, zone_options_t*, opt->zone_options) { 643 if(zone->part_of_config) 644 continue; 645 r = fprintf(out, "add %s %s\n", zone->name, 646 zone->pattern->pname); 647 if(r < 0) { 648 log_msg(LOG_ERR, "write %s failed: %s", outname, 649 strerror(errno)); 650 fclose(out); 651 return; 652 } else if(r != zone->linesize) { 653 log_msg(LOG_ERR, "write %s was partial: disk full", 654 outname); 655 fclose(out); 656 return; 657 } 658 } 659 if(fflush(out) != 0) { 660 log_msg(LOG_ERR, "fflush %s: %s", outname, strerror(errno)); 661 } 662 663 /* rename zonelist~ onto zonelist */ 664 if(rename(outname, opt->zonelistfile) == -1) { 665 log_msg(LOG_ERR, "rename(%s to %s) failed: %s", 666 outname, opt->zonelistfile, strerror(errno)); 667 fclose(out); 668 return; 669 } 670 fclose(opt->zonelist); 671 /* set offsets */ 672 RBTREE_FOR(zone, zone_options_t*, opt->zone_options) { 673 if(zone->part_of_config) 674 continue; 675 zone->off = off; 676 off += zone->linesize; 677 } 678 /* empty the free tree */ 679 delbucket(opt->region, (struct zonelist_bucket*)opt->zonefree->root); 680 opt->zonefree->root = RBTREE_NULL; 681 opt->zonefree->count = 0; 682 opt->zonefree_number = 0; 683 /* finish */ 684 opt->zonelist = out; 685 opt->zonelist_off = off; 686 } 687 688 /* close zonelist file */ 689 void 690 zone_list_close(nsd_options_t* opt) 691 { 692 fclose(opt->zonelist); 693 opt->zonelist = NULL; 694 } 695 696 void 697 c_error_va_list_pos(int showpos, const char* fmt, va_list args) 698 { 699 char* at = NULL; 700 cfg_parser->errors++; 701 if(showpos && c_text && c_text[0]!=0) { 702 at = c_text; 703 } 704 if(cfg_parser->err) { 705 char m[MAXSYSLOGMSGLEN]; 706 snprintf(m, sizeof(m), "%s:%d: ", cfg_parser->filename, 707 cfg_parser->line); 708 (*cfg_parser->err)(cfg_parser->err_arg, m); 709 if(at) { 710 snprintf(m, sizeof(m), "at '%s': ", at); 711 (*cfg_parser->err)(cfg_parser->err_arg, m); 712 } 713 (*cfg_parser->err)(cfg_parser->err_arg, "error: "); 714 vsnprintf(m, sizeof(m), fmt, args); 715 (*cfg_parser->err)(cfg_parser->err_arg, m); 716 (*cfg_parser->err)(cfg_parser->err_arg, "\n"); 717 return; 718 } 719 fprintf(stderr, "%s:%d: ", cfg_parser->filename, cfg_parser->line); 720 if(at) fprintf(stderr, "at '%s': ", at); 721 fprintf(stderr, "error: "); 722 vfprintf(stderr, fmt, args); 723 fprintf(stderr, "\n"); 724 } 725 726 void 727 c_error_msg_pos(int showpos, const char* fmt, ...) 728 { 729 va_list args; 730 va_start(args, fmt); 731 c_error_va_list_pos(showpos, fmt, args); 732 va_end(args); 733 } 734 735 void 736 c_error_msg(const char* fmt, ...) 737 { 738 va_list args; 739 va_start(args, fmt); 740 c_error_va_list_pos(0, fmt, args); 741 va_end(args); 742 } 743 744 void 745 c_error(const char* str) 746 { 747 if((strcmp(str, "syntax error")==0 || strcmp(str, "parse error")==0)) 748 c_error_msg_pos(1, "%s", str); 749 else c_error_msg("%s", str); 750 } 751 752 int 753 c_wrap() 754 { 755 return 1; 756 } 757 758 zone_options_t* 759 zone_options_create(region_type* region) 760 { 761 zone_options_t* zone; 762 zone = (zone_options_t*)region_alloc(region, sizeof(zone_options_t)); 763 zone->node = *RBTREE_NULL; 764 zone->name = 0; 765 zone->pattern = 0; 766 zone->part_of_config = 0; 767 return zone; 768 } 769 770 /* true is booleans are the same truth value */ 771 #define booleq(x,y) ( ((x) && (y)) || (!(x) && !(y)) ) 772 773 int 774 acl_equal(acl_options_t* p, acl_options_t* q) 775 { 776 if(!booleq(p->use_axfr_only, q->use_axfr_only)) return 0; 777 if(!booleq(p->allow_udp, q->allow_udp)) return 0; 778 if(strcmp(p->ip_address_spec, q->ip_address_spec)!=0) return 0; 779 /* the ip6, port, addr, mask, type: are derived from the ip_address_spec */ 780 if(!booleq(p->nokey, q->nokey)) return 0; 781 if(!booleq(p->blocked, q->blocked)) return 0; 782 if(p->key_name && q->key_name) { 783 if(strcmp(p->key_name, q->key_name)!=0) return 0; 784 } else if(p->key_name && !q->key_name) return 0; 785 else if(!p->key_name && q->key_name) return 0; 786 /* key_options is derived from key_name */ 787 return 1; 788 } 789 790 int 791 acl_list_equal(acl_options_t* p, acl_options_t* q) 792 { 793 /* must be same and in same order */ 794 while(p && q) { 795 if(!acl_equal(p, q)) 796 return 0; 797 p = p->next; 798 q = q->next; 799 } 800 if(!p && !q) return 1; 801 /* different lengths */ 802 return 0; 803 } 804 805 pattern_options_t* 806 pattern_options_create(region_type* region) 807 { 808 pattern_options_t* p; 809 p = (pattern_options_t*)region_alloc(region, sizeof(pattern_options_t)); 810 p->node = *RBTREE_NULL; 811 p->pname = 0; 812 p->zonefile = 0; 813 p->zonestats = 0; 814 p->allow_notify = 0; 815 p->request_xfr = 0; 816 p->size_limit_xfr = 0; 817 p->notify = 0; 818 p->provide_xfr = 0; 819 p->outgoing_interface = 0; 820 p->notify_retry = 5; 821 p->notify_retry_is_default = 1; 822 p->allow_axfr_fallback = 1; 823 p->allow_axfr_fallback_is_default = 1; 824 p->implicit = 0; 825 p->xfrd_flags = 0; 826 p->max_refresh_time = 2419200; /* 4 weeks */ 827 p->max_refresh_time_is_default = 1; 828 p->min_refresh_time = 0; 829 p->min_refresh_time_is_default = 1; 830 p->max_retry_time = 1209600; /* 2 weeks */ 831 p->max_retry_time_is_default = 1; 832 p->min_retry_time = 0; 833 p->min_retry_time_is_default = 1; 834 #ifdef RATELIMIT 835 p->rrl_whitelist = 0; 836 #endif 837 p->multi_master_check = 0; 838 return p; 839 } 840 841 static void 842 acl_delete(region_type* region, acl_options_t* acl) 843 { 844 if(acl->ip_address_spec) 845 region_recycle(region, (void*)acl->ip_address_spec, 846 strlen(acl->ip_address_spec)+1); 847 if(acl->key_name) 848 region_recycle(region, (void*)acl->key_name, 849 strlen(acl->key_name)+1); 850 /* key_options is a convenience pointer, not owned by the acl */ 851 region_recycle(region, acl, sizeof(*acl)); 852 } 853 854 static void 855 acl_list_delete(region_type* region, acl_options_t* list) 856 { 857 acl_options_t* n; 858 while(list) { 859 n = list->next; 860 acl_delete(region, list); 861 list = n; 862 } 863 } 864 865 void 866 pattern_options_remove(nsd_options_t* opt, const char* name) 867 { 868 pattern_options_t* p = (pattern_options_t*)rbtree_delete( 869 opt->patterns, name); 870 /* delete p and its contents */ 871 if (!p) 872 return; 873 if(p->pname) 874 region_recycle(opt->region, (void*)p->pname, 875 strlen(p->pname)+1); 876 if(p->zonefile) 877 region_recycle(opt->region, (void*)p->zonefile, 878 strlen(p->zonefile)+1); 879 if(p->zonestats) 880 region_recycle(opt->region, (void*)p->zonestats, 881 strlen(p->zonestats)+1); 882 acl_list_delete(opt->region, p->allow_notify); 883 acl_list_delete(opt->region, p->request_xfr); 884 acl_list_delete(opt->region, p->notify); 885 acl_list_delete(opt->region, p->provide_xfr); 886 acl_list_delete(opt->region, p->outgoing_interface); 887 888 region_recycle(opt->region, p, sizeof(pattern_options_t)); 889 } 890 891 static acl_options_t* 892 copy_acl(region_type* region, acl_options_t* a) 893 { 894 acl_options_t* b; 895 if(!a) return NULL; 896 b = (acl_options_t*)region_alloc(region, sizeof(*b)); 897 /* copy the whole lot */ 898 *b = *a; 899 /* fix the pointers */ 900 if(a->ip_address_spec) 901 b->ip_address_spec = region_strdup(region, a->ip_address_spec); 902 if(a->key_name) 903 b->key_name = region_strdup(region, a->key_name); 904 b->next = NULL; 905 b->key_options = NULL; 906 return b; 907 } 908 909 static acl_options_t* 910 copy_acl_list(nsd_options_t* opt, acl_options_t* a) 911 { 912 acl_options_t* b, *blast = NULL, *blist = NULL; 913 while(a) { 914 b = copy_acl(opt->region, a); 915 /* fixup key_options */ 916 if(b->key_name) 917 b->key_options = key_options_find(opt, b->key_name); 918 else b->key_options = NULL; 919 920 /* link as last into list */ 921 b->next = NULL; 922 if(!blist) blist = b; 923 else blast->next = b; 924 blast = b; 925 926 a = a->next; 927 } 928 return blist; 929 } 930 931 static void 932 copy_changed_acl(nsd_options_t* opt, acl_options_t** orig, 933 acl_options_t* anew) 934 { 935 if(!acl_list_equal(*orig, anew)) { 936 acl_list_delete(opt->region, *orig); 937 *orig = copy_acl_list(opt, anew); 938 } 939 } 940 941 static void 942 copy_pat_fixed(region_type* region, pattern_options_t* orig, 943 pattern_options_t* p) 944 { 945 orig->allow_axfr_fallback = p->allow_axfr_fallback; 946 orig->allow_axfr_fallback_is_default = 947 p->allow_axfr_fallback_is_default; 948 orig->notify_retry = p->notify_retry; 949 orig->notify_retry_is_default = p->notify_retry_is_default; 950 orig->implicit = p->implicit; 951 if(p->zonefile) 952 orig->zonefile = region_strdup(region, p->zonefile); 953 else orig->zonefile = NULL; 954 if(p->zonestats) 955 orig->zonestats = region_strdup(region, p->zonestats); 956 else orig->zonestats = NULL; 957 orig->max_refresh_time = p->max_refresh_time; 958 orig->max_refresh_time_is_default = p->max_refresh_time_is_default; 959 orig->min_refresh_time = p->min_refresh_time; 960 orig->min_refresh_time_is_default = p->min_refresh_time_is_default; 961 orig->max_retry_time = p->max_retry_time; 962 orig->max_retry_time_is_default = p->max_retry_time_is_default; 963 orig->min_retry_time = p->min_retry_time; 964 orig->min_retry_time_is_default = p->min_retry_time_is_default; 965 #ifdef RATELIMIT 966 orig->rrl_whitelist = p->rrl_whitelist; 967 #endif 968 orig->multi_master_check = p->multi_master_check; 969 } 970 971 void 972 pattern_options_add_modify(nsd_options_t* opt, pattern_options_t* p) 973 { 974 pattern_options_t* orig = pattern_options_find(opt, p->pname); 975 if(!orig) { 976 /* needs to be copied to opt region */ 977 orig = pattern_options_create(opt->region); 978 orig->pname = region_strdup(opt->region, p->pname); 979 copy_pat_fixed(opt->region, orig, p); 980 orig->allow_notify = copy_acl_list(opt, p->allow_notify); 981 orig->request_xfr = copy_acl_list(opt, p->request_xfr); 982 orig->notify = copy_acl_list(opt, p->notify); 983 orig->provide_xfr = copy_acl_list(opt, p->provide_xfr); 984 orig->outgoing_interface = copy_acl_list(opt, 985 p->outgoing_interface); 986 nsd_options_insert_pattern(opt, orig); 987 } else { 988 /* modify in place so pointers stay valid (and copy 989 into region). Do not touch unchanged acls. */ 990 if(orig->zonefile) 991 region_recycle(opt->region, (char*)orig->zonefile, 992 strlen(orig->zonefile)+1); 993 if(orig->zonestats) 994 region_recycle(opt->region, (char*)orig->zonestats, 995 strlen(orig->zonestats)+1); 996 copy_pat_fixed(opt->region, orig, p); 997 copy_changed_acl(opt, &orig->allow_notify, p->allow_notify); 998 copy_changed_acl(opt, &orig->request_xfr, p->request_xfr); 999 copy_changed_acl(opt, &orig->notify, p->notify); 1000 copy_changed_acl(opt, &orig->provide_xfr, p->provide_xfr); 1001 copy_changed_acl(opt, &orig->outgoing_interface, 1002 p->outgoing_interface); 1003 } 1004 } 1005 1006 pattern_options_t* 1007 pattern_options_find(nsd_options_t* opt, const char* name) 1008 { 1009 return (pattern_options_t*)rbtree_search(opt->patterns, name); 1010 } 1011 1012 int 1013 pattern_options_equal(pattern_options_t* p, pattern_options_t* q) 1014 { 1015 if(strcmp(p->pname, q->pname) != 0) return 0; 1016 if(!p->zonefile && q->zonefile) return 0; 1017 else if(p->zonefile && !q->zonefile) return 0; 1018 else if(p->zonefile && q->zonefile) { 1019 if(strcmp(p->zonefile, q->zonefile) != 0) return 0; 1020 } 1021 if(!p->zonestats && q->zonestats) return 0; 1022 else if(p->zonestats && !q->zonestats) return 0; 1023 else if(p->zonestats && q->zonestats) { 1024 if(strcmp(p->zonestats, q->zonestats) != 0) return 0; 1025 } 1026 if(!booleq(p->allow_axfr_fallback, q->allow_axfr_fallback)) return 0; 1027 if(!booleq(p->allow_axfr_fallback_is_default, 1028 q->allow_axfr_fallback_is_default)) return 0; 1029 if(p->notify_retry != q->notify_retry) return 0; 1030 if(!booleq(p->notify_retry_is_default, 1031 q->notify_retry_is_default)) return 0; 1032 if(!booleq(p->implicit, q->implicit)) return 0; 1033 if(!acl_list_equal(p->allow_notify, q->allow_notify)) return 0; 1034 if(!acl_list_equal(p->request_xfr, q->request_xfr)) return 0; 1035 if(!acl_list_equal(p->notify, q->notify)) return 0; 1036 if(!acl_list_equal(p->provide_xfr, q->provide_xfr)) return 0; 1037 if(!acl_list_equal(p->outgoing_interface, q->outgoing_interface)) 1038 return 0; 1039 if(p->max_refresh_time != q->max_refresh_time) return 0; 1040 if(!booleq(p->max_refresh_time_is_default, 1041 q->max_refresh_time_is_default)) return 0; 1042 if(p->min_refresh_time != q->min_refresh_time) return 0; 1043 if(!booleq(p->min_refresh_time_is_default, 1044 q->min_refresh_time_is_default)) return 0; 1045 if(p->max_retry_time != q->max_retry_time) return 0; 1046 if(!booleq(p->max_retry_time_is_default, 1047 q->max_retry_time_is_default)) return 0; 1048 if(p->min_retry_time != q->min_retry_time) return 0; 1049 if(!booleq(p->min_retry_time_is_default, 1050 q->min_retry_time_is_default)) return 0; 1051 #ifdef RATELIMIT 1052 if(p->rrl_whitelist != q->rrl_whitelist) return 0; 1053 #endif 1054 if(!booleq(p->multi_master_check,q->multi_master_check)) return 0; 1055 if(p->size_limit_xfr != q->size_limit_xfr) return 0; 1056 return 1; 1057 } 1058 1059 static void 1060 marshal_u8(struct buffer* b, uint8_t v) 1061 { 1062 buffer_reserve(b, 1); 1063 buffer_write_u8(b, v); 1064 } 1065 1066 static uint8_t 1067 unmarshal_u8(struct buffer* b) 1068 { 1069 return buffer_read_u8(b); 1070 } 1071 1072 static void 1073 marshal_u64(struct buffer* b, uint64_t v) 1074 { 1075 buffer_reserve(b, 8); 1076 buffer_write_u64(b, v); 1077 } 1078 1079 static uint64_t 1080 unmarshal_u64(struct buffer* b) 1081 { 1082 return buffer_read_u64(b); 1083 } 1084 1085 #ifdef RATELIMIT 1086 static void 1087 marshal_u16(struct buffer* b, uint16_t v) 1088 { 1089 buffer_reserve(b, 2); 1090 buffer_write_u16(b, v); 1091 } 1092 #endif 1093 1094 #ifdef RATELIMIT 1095 static uint16_t 1096 unmarshal_u16(struct buffer* b) 1097 { 1098 return buffer_read_u16(b); 1099 } 1100 #endif 1101 1102 static void 1103 marshal_u32(struct buffer* b, uint32_t v) 1104 { 1105 buffer_reserve(b, 4); 1106 buffer_write_u32(b, v); 1107 } 1108 1109 static uint32_t 1110 unmarshal_u32(struct buffer* b) 1111 { 1112 return buffer_read_u32(b); 1113 } 1114 1115 static void 1116 marshal_str(struct buffer* b, const char* s) 1117 { 1118 if(!s) marshal_u8(b, 0); 1119 else { 1120 size_t len = strlen(s); 1121 marshal_u8(b, 1); 1122 buffer_reserve(b, len+1); 1123 buffer_write(b, s, len+1); 1124 } 1125 } 1126 1127 static char* 1128 unmarshal_str(region_type* r, struct buffer* b) 1129 { 1130 uint8_t nonnull = unmarshal_u8(b); 1131 if(nonnull) { 1132 char* result = region_strdup(r, (char*)buffer_current(b)); 1133 size_t len = strlen((char*)buffer_current(b)); 1134 buffer_skip(b, len+1); 1135 return result; 1136 } else return NULL; 1137 } 1138 1139 static void 1140 marshal_acl(struct buffer* b, acl_options_t* acl) 1141 { 1142 buffer_reserve(b, sizeof(*acl)); 1143 buffer_write(b, acl, sizeof(*acl)); 1144 marshal_str(b, acl->ip_address_spec); 1145 marshal_str(b, acl->key_name); 1146 } 1147 1148 static acl_options_t* 1149 unmarshal_acl(region_type* r, struct buffer* b) 1150 { 1151 acl_options_t* acl = (acl_options_t*)region_alloc(r, sizeof(*acl)); 1152 buffer_read(b, acl, sizeof(*acl)); 1153 acl->next = NULL; 1154 acl->key_options = NULL; 1155 acl->ip_address_spec = unmarshal_str(r, b); 1156 acl->key_name = unmarshal_str(r, b); 1157 return acl; 1158 } 1159 1160 static void 1161 marshal_acl_list(struct buffer* b, acl_options_t* list) 1162 { 1163 while(list) { 1164 marshal_u8(b, 1); /* is there a next one marker */ 1165 marshal_acl(b, list); 1166 list = list->next; 1167 } 1168 marshal_u8(b, 0); /* end of list marker */ 1169 } 1170 1171 static acl_options_t* 1172 unmarshal_acl_list(region_type* r, struct buffer* b) 1173 { 1174 acl_options_t* a, *last=NULL, *list=NULL; 1175 while(unmarshal_u8(b)) { 1176 a = unmarshal_acl(r, b); 1177 /* link in */ 1178 a->next = NULL; 1179 if(!list) list = a; 1180 else last->next = a; 1181 last = a; 1182 } 1183 return list; 1184 } 1185 1186 void 1187 pattern_options_marshal(struct buffer* b, pattern_options_t* p) 1188 { 1189 marshal_str(b, p->pname); 1190 marshal_str(b, p->zonefile); 1191 marshal_str(b, p->zonestats); 1192 #ifdef RATELIMIT 1193 marshal_u16(b, p->rrl_whitelist); 1194 #endif 1195 marshal_u8(b, p->allow_axfr_fallback); 1196 marshal_u8(b, p->allow_axfr_fallback_is_default); 1197 marshal_u8(b, p->notify_retry); 1198 marshal_u8(b, p->notify_retry_is_default); 1199 marshal_u8(b, p->implicit); 1200 marshal_u64(b, p->size_limit_xfr); 1201 marshal_acl_list(b, p->allow_notify); 1202 marshal_acl_list(b, p->request_xfr); 1203 marshal_acl_list(b, p->notify); 1204 marshal_acl_list(b, p->provide_xfr); 1205 marshal_acl_list(b, p->outgoing_interface); 1206 marshal_u32(b, p->max_refresh_time); 1207 marshal_u8(b, p->max_refresh_time_is_default); 1208 marshal_u32(b, p->min_refresh_time); 1209 marshal_u8(b, p->min_refresh_time_is_default); 1210 marshal_u32(b, p->max_retry_time); 1211 marshal_u8(b, p->max_retry_time_is_default); 1212 marshal_u32(b, p->min_retry_time); 1213 marshal_u8(b, p->min_retry_time_is_default); 1214 marshal_u8(b, p->multi_master_check); 1215 } 1216 1217 pattern_options_t* 1218 pattern_options_unmarshal(region_type* r, struct buffer* b) 1219 { 1220 pattern_options_t* p = pattern_options_create(r); 1221 p->pname = unmarshal_str(r, b); 1222 p->zonefile = unmarshal_str(r, b); 1223 p->zonestats = unmarshal_str(r, b); 1224 #ifdef RATELIMIT 1225 p->rrl_whitelist = unmarshal_u16(b); 1226 #endif 1227 p->allow_axfr_fallback = unmarshal_u8(b); 1228 p->allow_axfr_fallback_is_default = unmarshal_u8(b); 1229 p->notify_retry = unmarshal_u8(b); 1230 p->notify_retry_is_default = unmarshal_u8(b); 1231 p->implicit = unmarshal_u8(b); 1232 p->size_limit_xfr = unmarshal_u64(b); 1233 p->allow_notify = unmarshal_acl_list(r, b); 1234 p->request_xfr = unmarshal_acl_list(r, b); 1235 p->notify = unmarshal_acl_list(r, b); 1236 p->provide_xfr = unmarshal_acl_list(r, b); 1237 p->outgoing_interface = unmarshal_acl_list(r, b); 1238 p->max_refresh_time = unmarshal_u32(b); 1239 p->max_refresh_time_is_default = unmarshal_u8(b); 1240 p->min_refresh_time = unmarshal_u32(b); 1241 p->min_refresh_time_is_default = unmarshal_u8(b); 1242 p->max_retry_time = unmarshal_u32(b); 1243 p->max_retry_time_is_default = unmarshal_u8(b); 1244 p->min_retry_time = unmarshal_u32(b); 1245 p->min_retry_time_is_default = unmarshal_u8(b); 1246 p->multi_master_check = unmarshal_u8(b); 1247 return p; 1248 } 1249 1250 key_options_t* 1251 key_options_create(region_type* region) 1252 { 1253 key_options_t* key; 1254 key = (key_options_t*)region_alloc_zero(region, sizeof(key_options_t)); 1255 return key; 1256 } 1257 1258 void 1259 key_options_insert(nsd_options_t* opt, key_options_t* key) 1260 { 1261 if(!key->name) return; 1262 key->node.key = key->name; 1263 (void)rbtree_insert(opt->keys, &key->node); 1264 } 1265 1266 key_options_t* 1267 key_options_find(nsd_options_t* opt, const char* name) 1268 { 1269 return (key_options_t*)rbtree_search(opt->keys, name); 1270 } 1271 1272 /** remove tsig_key contents */ 1273 void 1274 key_options_desetup(region_type* region, key_options_t* key) 1275 { 1276 /* keep tsig_key pointer so that existing references keep valid */ 1277 if(!key->tsig_key) 1278 return; 1279 /* name stays the same */ 1280 if(key->tsig_key->data) { 1281 /* wipe secret! */ 1282 memset(key->tsig_key->data, 0xdd, key->tsig_key->size); 1283 region_recycle(region, key->tsig_key->data, 1284 key->tsig_key->size); 1285 key->tsig_key->data = NULL; 1286 key->tsig_key->size = 0; 1287 } 1288 } 1289 1290 /** add tsig_key contents */ 1291 void 1292 key_options_setup(region_type* region, key_options_t* key) 1293 { 1294 uint8_t data[16384]; /* 16KB */ 1295 int size; 1296 if(!key->tsig_key) { 1297 /* create it */ 1298 key->tsig_key = (tsig_key_type *) region_alloc(region, 1299 sizeof(tsig_key_type)); 1300 /* create name */ 1301 key->tsig_key->name = dname_parse(region, key->name); 1302 if(!key->tsig_key->name) { 1303 log_msg(LOG_ERR, "Failed to parse tsig key name %s", 1304 key->name); 1305 /* key and base64 were checked during syntax parse */ 1306 exit(1); 1307 } 1308 key->tsig_key->size = 0; 1309 key->tsig_key->data = NULL; 1310 } 1311 size = __b64_pton(key->secret, data, sizeof(data)); 1312 if(size == -1) { 1313 log_msg(LOG_ERR, "Failed to parse tsig key data %s", 1314 key->name); 1315 /* key and base64 were checked during syntax parse */ 1316 exit(1); 1317 } 1318 key->tsig_key->size = size; 1319 key->tsig_key->data = (uint8_t *)region_alloc_init(region, data, size); 1320 } 1321 1322 void 1323 key_options_remove(nsd_options_t* opt, const char* name) 1324 { 1325 key_options_t* k = key_options_find(opt, name); 1326 if(!k) return; 1327 (void)rbtree_delete(opt->keys, name); 1328 if(k->name) 1329 region_recycle(opt->region, k->name, strlen(k->name)+1); 1330 if(k->algorithm) 1331 region_recycle(opt->region, k->algorithm, strlen(k->algorithm)+1); 1332 if(k->secret) { 1333 memset(k->secret, 0xdd, strlen(k->secret)); /* wipe secret! */ 1334 region_recycle(opt->region, k->secret, strlen(k->secret)+1); 1335 } 1336 if(k->tsig_key) { 1337 tsig_del_key(k->tsig_key); 1338 if(k->tsig_key->name) 1339 region_recycle(opt->region, (void*)k->tsig_key->name, 1340 dname_total_size(k->tsig_key->name)); 1341 key_options_desetup(opt->region, k); 1342 region_recycle(opt->region, k->tsig_key, sizeof(tsig_key_type)); 1343 } 1344 region_recycle(opt->region, k, sizeof(key_options_t)); 1345 } 1346 1347 int 1348 key_options_equal(key_options_t* p, key_options_t* q) 1349 { 1350 return strcmp(p->name, q->name)==0 && strcmp(p->algorithm, 1351 q->algorithm)==0 && strcmp(p->secret, q->secret)==0; 1352 } 1353 1354 void 1355 key_options_add_modify(nsd_options_t* opt, key_options_t* key) 1356 { 1357 key_options_t* orig = key_options_find(opt, key->name); 1358 if(!orig) { 1359 /* needs to be copied to opt region */ 1360 orig = key_options_create(opt->region); 1361 orig->name = region_strdup(opt->region, key->name); 1362 orig->algorithm = region_strdup(opt->region, key->algorithm); 1363 orig->secret = region_strdup(opt->region, key->secret); 1364 key_options_setup(opt->region, orig); 1365 tsig_add_key(orig->tsig_key); 1366 key_options_insert(opt, orig); 1367 } else { 1368 /* modify entries in existing key, and copy to opt region */ 1369 key_options_desetup(opt->region, orig); 1370 region_recycle(opt->region, orig->algorithm, 1371 strlen(orig->algorithm)+1); 1372 orig->algorithm = region_strdup(opt->region, key->algorithm); 1373 region_recycle(opt->region, orig->secret, 1374 strlen(orig->secret)+1); 1375 orig->secret = region_strdup(opt->region, key->secret); 1376 key_options_setup(opt->region, orig); 1377 } 1378 } 1379 1380 int 1381 acl_check_incoming(acl_options_t* acl, struct query* q, 1382 acl_options_t** reason) 1383 { 1384 /* check each acl element. 1385 if 1 blocked element matches - return -1. 1386 if any element matches - return number. 1387 else return -1. */ 1388 int found_match = -1; 1389 int number = 0; 1390 acl_options_t* match = 0; 1391 1392 if(reason) 1393 *reason = NULL; 1394 1395 while(acl) 1396 { 1397 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "testing acl %s %s", 1398 acl->ip_address_spec, acl->nokey?"NOKEY": 1399 (acl->blocked?"BLOCKED":acl->key_name))); 1400 if(acl_addr_matches(acl, q) && acl_key_matches(acl, q)) { 1401 if(!match) 1402 { 1403 match = acl; /* remember first match */ 1404 found_match=number; 1405 } 1406 if(acl->blocked) { 1407 if(reason) 1408 *reason = acl; 1409 return -1; 1410 } 1411 } 1412 number++; 1413 acl = acl->next; 1414 } 1415 1416 if(reason) 1417 *reason = match; 1418 return found_match; 1419 } 1420 1421 #ifdef INET6 1422 int 1423 acl_addr_matches_ipv6host(acl_options_t* acl, struct sockaddr_storage* addr_storage, unsigned int port) 1424 { 1425 struct sockaddr_in6* addr = (struct sockaddr_in6*)addr_storage; 1426 if(acl->port != 0 && acl->port != port) 1427 return 0; 1428 switch(acl->rangetype) { 1429 case acl_range_mask: 1430 case acl_range_subnet: 1431 if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr, 1432 (uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr))) 1433 return 0; 1434 break; 1435 case acl_range_minmax: 1436 if(!acl_addr_match_range((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr, 1437 (uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr))) 1438 return 0; 1439 break; 1440 case acl_range_single: 1441 default: 1442 if(memcmp(&addr->sin6_addr, &acl->addr.addr6, 1443 sizeof(struct in6_addr)) != 0) 1444 return 0; 1445 break; 1446 } 1447 return 1; 1448 } 1449 #endif 1450 1451 int 1452 acl_addr_matches_ipv4host(acl_options_t* acl, struct sockaddr_in* addr, unsigned int port) 1453 { 1454 if(acl->port != 0 && acl->port != port) 1455 return 0; 1456 switch(acl->rangetype) { 1457 case acl_range_mask: 1458 case acl_range_subnet: 1459 if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr, 1460 (uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr))) 1461 return 0; 1462 break; 1463 case acl_range_minmax: 1464 if(!acl_addr_match_range((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr, 1465 (uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr))) 1466 return 0; 1467 break; 1468 case acl_range_single: 1469 default: 1470 if(memcmp(&addr->sin_addr, &acl->addr.addr, 1471 sizeof(struct in_addr)) != 0) 1472 return 0; 1473 break; 1474 } 1475 return 1; 1476 } 1477 1478 int 1479 acl_addr_matches_host(acl_options_t* acl, acl_options_t* host) 1480 { 1481 if(acl->is_ipv6) 1482 { 1483 #ifdef INET6 1484 struct sockaddr_storage* addr = (struct sockaddr_storage*)&host->addr; 1485 if(!host->is_ipv6) return 0; 1486 return acl_addr_matches_ipv6host(acl, addr, host->port); 1487 #else 1488 return 0; /* no inet6, no match */ 1489 #endif 1490 } 1491 else 1492 { 1493 struct sockaddr_in* addr = (struct sockaddr_in*)&host->addr; 1494 if(host->is_ipv6) return 0; 1495 return acl_addr_matches_ipv4host(acl, addr, host->port); 1496 } 1497 /* ENOTREACH */ 1498 return 0; 1499 } 1500 1501 int 1502 acl_addr_matches(acl_options_t* acl, struct query* q) 1503 { 1504 if(acl->is_ipv6) 1505 { 1506 #ifdef INET6 1507 struct sockaddr_storage* addr = (struct sockaddr_storage*)&q->addr; 1508 if(addr->ss_family != AF_INET6) 1509 return 0; 1510 return acl_addr_matches_ipv6host(acl, addr, ntohs(((struct sockaddr_in6*)addr)->sin6_port)); 1511 #else 1512 return 0; /* no inet6, no match */ 1513 #endif 1514 } 1515 else 1516 { 1517 struct sockaddr_in* addr = (struct sockaddr_in*)&q->addr; 1518 if(addr->sin_family != AF_INET) 1519 return 0; 1520 return acl_addr_matches_ipv4host(acl, addr, ntohs(addr->sin_port)); 1521 } 1522 /* ENOTREACH */ 1523 return 0; 1524 } 1525 1526 int 1527 acl_addr_match_mask(uint32_t* a, uint32_t* b, uint32_t* mask, size_t sz) 1528 { 1529 size_t i; 1530 #ifndef NDEBUG 1531 assert(sz % 4 == 0); 1532 #endif 1533 sz /= 4; 1534 for(i=0; i<sz; ++i) 1535 { 1536 if(((*a++)&*mask) != ((*b++)&*mask)) 1537 return 0; 1538 ++mask; 1539 } 1540 return 1; 1541 } 1542 1543 int 1544 acl_addr_match_range(uint32_t* minval, uint32_t* x, uint32_t* maxval, size_t sz) 1545 { 1546 size_t i; 1547 uint8_t checkmin = 1, checkmax = 1; 1548 #ifndef NDEBUG 1549 assert(sz % 4 == 0); 1550 #endif 1551 /* check treats x as one huge number */ 1552 sz /= 4; 1553 for(i=0; i<sz; ++i) 1554 { 1555 /* if outside bounds, we are done */ 1556 if(checkmin) 1557 if(minval[i] > x[i]) 1558 return 0; 1559 if(checkmax) 1560 if(maxval[i] < x[i]) 1561 return 0; 1562 /* if x is equal to a bound, that bound needs further checks */ 1563 if(checkmin && minval[i]!=x[i]) 1564 checkmin = 0; 1565 if(checkmax && maxval[i]!=x[i]) 1566 checkmax = 0; 1567 if(!checkmin && !checkmax) 1568 return 1; /* will always match */ 1569 } 1570 return 1; 1571 } 1572 1573 int 1574 acl_key_matches(acl_options_t* acl, struct query* q) 1575 { 1576 if(acl->blocked) 1577 return 1; 1578 if(acl->nokey) { 1579 if(q->tsig.status == TSIG_NOT_PRESENT) 1580 return 1; 1581 return 0; 1582 } 1583 /* check name of tsig key */ 1584 if(q->tsig.status != TSIG_OK) { 1585 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail query has no TSIG")); 1586 return 0; /* query has no TSIG */ 1587 } 1588 if(q->tsig.error_code != TSIG_ERROR_NOERROR) { 1589 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail, tsig has error")); 1590 return 0; /* some tsig error */ 1591 } 1592 if(!acl->key_options->tsig_key) { 1593 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail no config")); 1594 return 0; /* key not properly configured */ 1595 } 1596 if(dname_compare(q->tsig.key_name, 1597 acl->key_options->tsig_key->name) != 0) { 1598 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail wrong key name")); 1599 return 0; /* wrong key name */ 1600 } 1601 if(tsig_strlowercmp(q->tsig.algorithm->short_name, 1602 acl->key_options->algorithm) != 0 && ( 1603 strncmp("hmac-", q->tsig.algorithm->short_name, 5) != 0 || 1604 tsig_strlowercmp(q->tsig.algorithm->short_name+5, 1605 acl->key_options->algorithm) != 0) ) { 1606 DEBUG(DEBUG_XFRD,2, (LOG_ERR, "query tsig wrong algorithm")); 1607 return 0; /* no such algo */ 1608 } 1609 return 1; 1610 } 1611 1612 int 1613 acl_same_host(acl_options_t* a, acl_options_t* b) 1614 { 1615 if(a->is_ipv6 && !b->is_ipv6) 1616 return 0; 1617 if(!a->is_ipv6 && b->is_ipv6) 1618 return 0; 1619 if(a->port != b->port) 1620 return 0; 1621 if(a->rangetype != b->rangetype) 1622 return 0; 1623 if(!a->is_ipv6) { 1624 if(memcmp(&a->addr.addr, &b->addr.addr, 1625 sizeof(struct in_addr)) != 0) 1626 return 0; 1627 if(a->rangetype != acl_range_single && 1628 memcmp(&a->range_mask.addr, &b->range_mask.addr, 1629 sizeof(struct in_addr)) != 0) 1630 return 0; 1631 } else { 1632 #ifdef INET6 1633 if(memcmp(&a->addr.addr6, &b->addr.addr6, 1634 sizeof(struct in6_addr)) != 0) 1635 return 0; 1636 if(a->rangetype != acl_range_single && 1637 memcmp(&a->range_mask.addr6, &b->range_mask.addr6, 1638 sizeof(struct in6_addr)) != 0) 1639 return 0; 1640 #else 1641 return 0; 1642 #endif 1643 } 1644 return 1; 1645 } 1646 1647 #if defined(HAVE_SSL) 1648 void 1649 key_options_tsig_add(nsd_options_t* opt) 1650 { 1651 key_options_t* optkey; 1652 RBTREE_FOR(optkey, key_options_t*, opt->keys) { 1653 key_options_setup(opt->region, optkey); 1654 tsig_add_key(optkey->tsig_key); 1655 } 1656 } 1657 #endif 1658 1659 int 1660 zone_is_slave(zone_options_t* opt) 1661 { 1662 return opt && opt->pattern && opt->pattern->request_xfr != 0; 1663 } 1664 1665 /* get a character in string (or replacement char if not long enough) */ 1666 static const char* 1667 get_char(const char* str, size_t i) 1668 { 1669 static char res[2]; 1670 if(i >= strlen(str)) 1671 return "."; 1672 res[0] = str[i]; 1673 res[1] = 0; 1674 return res; 1675 } 1676 /* get end label of the zone name (or .) */ 1677 static const char* 1678 get_end_label(zone_options_t* zone, int i) 1679 { 1680 const dname_type* d = (const dname_type*)zone->node.key; 1681 if(i >= d->label_count) { 1682 return "."; 1683 } 1684 return wirelabel2str(dname_label(d, i)); 1685 } 1686 /* replace occurrences of one with two */ 1687 void 1688 replace_str(char* str, size_t len, const char* one, const char* two) 1689 { 1690 char* pos; 1691 char* at = str; 1692 while( (pos=strstr(at, one)) ) { 1693 if(strlen(str)+strlen(two)-strlen(one) >= len) 1694 return; /* no more space to replace */ 1695 /* stuff before pos is fine */ 1696 /* move the stuff after pos to make space for two, add 1697 * one to length of remainder to also copy the 0 byte end */ 1698 memmove(pos+strlen(two), pos+strlen(one), 1699 strlen(pos+strlen(one))+1); 1700 /* copy in two */ 1701 memmove(pos, two, strlen(two)); 1702 /* at is end of the newly inserted two (avoids recursion if 1703 * two contains one) */ 1704 at = pos+strlen(two); 1705 } 1706 } 1707 1708 const char* 1709 config_cook_string(zone_options_t* zone, const char* input) 1710 { 1711 static char f[1024]; 1712 /* if not a template, return as-is */ 1713 if(!strchr(input, '%')) { 1714 return input; 1715 } 1716 strlcpy(f, input, sizeof(f)); 1717 if(strstr(f, "%1")) 1718 replace_str(f, sizeof(f), "%1", get_char(zone->name, 0)); 1719 if(strstr(f, "%2")) 1720 replace_str(f, sizeof(f), "%2", get_char(zone->name, 1)); 1721 if(strstr(f, "%3")) 1722 replace_str(f, sizeof(f), "%3", get_char(zone->name, 2)); 1723 if(strstr(f, "%z")) 1724 replace_str(f, sizeof(f), "%z", get_end_label(zone, 1)); 1725 if(strstr(f, "%y")) 1726 replace_str(f, sizeof(f), "%y", get_end_label(zone, 2)); 1727 if(strstr(f, "%x")) 1728 replace_str(f, sizeof(f), "%x", get_end_label(zone, 3)); 1729 if(strstr(f, "%s")) 1730 replace_str(f, sizeof(f), "%s", zone->name); 1731 return f; 1732 } 1733 1734 const char* 1735 config_make_zonefile(zone_options_t* zone, struct nsd* nsd) 1736 { 1737 static char f[1024]; 1738 /* if not a template, return as-is */ 1739 if(!strchr(zone->pattern->zonefile, '%')) { 1740 if (nsd->chrootdir && nsd->chrootdir[0] && 1741 zone->pattern->zonefile && 1742 zone->pattern->zonefile[0] == '/' && 1743 strncmp(zone->pattern->zonefile, nsd->chrootdir, 1744 strlen(nsd->chrootdir)) == 0) 1745 /* -1 because chrootdir ends in trailing slash */ 1746 return zone->pattern->zonefile + strlen(nsd->chrootdir) - 1; 1747 return zone->pattern->zonefile; 1748 } 1749 strlcpy(f, zone->pattern->zonefile, sizeof(f)); 1750 if(strstr(f, "%1")) 1751 replace_str(f, sizeof(f), "%1", get_char(zone->name, 0)); 1752 if(strstr(f, "%2")) 1753 replace_str(f, sizeof(f), "%2", get_char(zone->name, 1)); 1754 if(strstr(f, "%3")) 1755 replace_str(f, sizeof(f), "%3", get_char(zone->name, 2)); 1756 if(strstr(f, "%z")) 1757 replace_str(f, sizeof(f), "%z", get_end_label(zone, 1)); 1758 if(strstr(f, "%y")) 1759 replace_str(f, sizeof(f), "%y", get_end_label(zone, 2)); 1760 if(strstr(f, "%x")) 1761 replace_str(f, sizeof(f), "%x", get_end_label(zone, 3)); 1762 if(strstr(f, "%s")) 1763 replace_str(f, sizeof(f), "%s", zone->name); 1764 if (nsd->chrootdir && nsd->chrootdir[0] && f[0] == '/' && 1765 strncmp(f, nsd->chrootdir, strlen(nsd->chrootdir)) == 0) 1766 /* -1 because chrootdir ends in trailing slash */ 1767 return f + strlen(nsd->chrootdir) - 1; 1768 return f; 1769 } 1770 1771 zone_options_t* 1772 zone_options_find(nsd_options_t* opt, const struct dname* apex) 1773 { 1774 return (zone_options_t*) rbtree_search(opt->zone_options, apex); 1775 } 1776 1777 acl_options_t* 1778 acl_find_num(acl_options_t* acl, int num) 1779 { 1780 int count = num; 1781 if(num < 0) 1782 return 0; 1783 while(acl && count > 0) { 1784 acl = acl->next; 1785 count--; 1786 } 1787 if(count == 0) 1788 return acl; 1789 return 0; 1790 } 1791 1792 /* true if ipv6 address, false if ipv4 */ 1793 int 1794 parse_acl_is_ipv6(const char* p) 1795 { 1796 /* see if addr is ipv6 or ipv4 -- by : and . */ 1797 while(*p) { 1798 if(*p == '.') return 0; 1799 if(*p == ':') return 1; 1800 ++p; 1801 } 1802 return 0; 1803 } 1804 1805 /* returns range type. mask is the 2nd part of the range */ 1806 int 1807 parse_acl_range_type(char* ip, char** mask) 1808 { 1809 char *p; 1810 if((p=strchr(ip, '&'))!=0) { 1811 *p = 0; 1812 *mask = p+1; 1813 return acl_range_mask; 1814 } 1815 if((p=strchr(ip, '/'))!=0) { 1816 *p = 0; 1817 *mask = p+1; 1818 return acl_range_subnet; 1819 } 1820 if((p=strchr(ip, '-'))!=0) { 1821 *p = 0; 1822 *mask = p+1; 1823 return acl_range_minmax; 1824 } 1825 *mask = 0; 1826 return acl_range_single; 1827 } 1828 1829 /* parses subnet mask, fills 0 mask as well */ 1830 void 1831 parse_acl_range_subnet(char* p, void* addr, int maxbits) 1832 { 1833 int subnet_bits = atoi(p); 1834 uint8_t* addr_bytes = (uint8_t*)addr; 1835 if(subnet_bits == 0 && strcmp(p, "0")!=0) { 1836 c_error_msg("bad subnet range '%s'", p); 1837 return; 1838 } 1839 if(subnet_bits < 0 || subnet_bits > maxbits) { 1840 c_error_msg("subnet of %d bits out of range [0..%d]", subnet_bits, maxbits); 1841 return; 1842 } 1843 /* fill addr with n bits of 1s (struct has been zeroed) */ 1844 while(subnet_bits >= 8) { 1845 *addr_bytes++ = 0xff; 1846 subnet_bits -= 8; 1847 } 1848 if(subnet_bits > 0) { 1849 uint8_t shifts[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; 1850 *addr_bytes = shifts[subnet_bits]; 1851 } 1852 } 1853 1854 acl_options_t* 1855 parse_acl_info(region_type* region, char* ip, const char* key) 1856 { 1857 char* p; 1858 acl_options_t* acl = (acl_options_t*)region_alloc(region, sizeof(acl_options_t)); 1859 acl->next = 0; 1860 /* ip */ 1861 acl->ip_address_spec = region_strdup(region, ip); 1862 acl->use_axfr_only = 0; 1863 acl->allow_udp = 0; 1864 acl->ixfr_disabled = 0; 1865 acl->bad_xfr_count = 0; 1866 acl->key_options = 0; 1867 acl->is_ipv6 = 0; 1868 acl->port = 0; 1869 memset(&acl->addr, 0, sizeof(union acl_addr_storage)); 1870 memset(&acl->range_mask, 0, sizeof(union acl_addr_storage)); 1871 if((p=strrchr(ip, '@'))!=0) { 1872 if(atoi(p+1) == 0) c_error("expected port number after '@'"); 1873 else acl->port = atoi(p+1); 1874 *p=0; 1875 } 1876 acl->rangetype = parse_acl_range_type(ip, &p); 1877 if(parse_acl_is_ipv6(ip)) { 1878 acl->is_ipv6 = 1; 1879 #ifdef INET6 1880 if(inet_pton(AF_INET6, ip, &acl->addr.addr6) != 1) 1881 c_error_msg("Bad ip6 address '%s'", ip); 1882 if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) 1883 if(inet_pton(AF_INET6, p, &acl->range_mask.addr6) != 1) 1884 c_error_msg("Bad ip6 address mask '%s'", p); 1885 if(acl->rangetype==acl_range_subnet) 1886 parse_acl_range_subnet(p, &acl->range_mask.addr6, 128); 1887 #else 1888 c_error_msg("encountered IPv6 address '%s'.", ip); 1889 #endif /* INET6 */ 1890 } else { 1891 acl->is_ipv6 = 0; 1892 if(inet_pton(AF_INET, ip, &acl->addr.addr) != 1) 1893 c_error_msg("Bad ip4 address '%s'", ip); 1894 if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) 1895 if(inet_pton(AF_INET, p, &acl->range_mask.addr) != 1) 1896 c_error_msg("Bad ip4 address mask '%s'", p); 1897 if(acl->rangetype==acl_range_subnet) 1898 parse_acl_range_subnet(p, &acl->range_mask.addr, 32); 1899 } 1900 1901 /* key */ 1902 if(strcmp(key, "NOKEY")==0) { 1903 acl->nokey = 1; 1904 acl->blocked = 0; 1905 acl->key_name = 0; 1906 } else if(strcmp(key, "BLOCKED")==0) { 1907 acl->nokey = 0; 1908 acl->blocked = 1; 1909 acl->key_name = 0; 1910 } else { 1911 acl->nokey = 0; 1912 acl->blocked = 0; 1913 acl->key_name = region_strdup(region, key); 1914 } 1915 return acl; 1916 } 1917 1918 /* copy acl list at end of parser start, update current */ 1919 static 1920 void append_acl(acl_options_t** start, acl_options_t** cur, 1921 acl_options_t* list) 1922 { 1923 while(list) { 1924 acl_options_t* acl = copy_acl(cfg_parser->opt->region, list); 1925 acl->next = NULL; 1926 if(*cur) 1927 (*cur)->next = acl; 1928 else *start = acl; 1929 *cur = acl; 1930 list = list->next; 1931 } 1932 } 1933 1934 void 1935 config_apply_pattern(const char* name) 1936 { 1937 /* find the pattern */ 1938 pattern_options_t* pat = pattern_options_find(cfg_parser->opt, name); 1939 pattern_options_t* a = cfg_parser->current_pattern; 1940 if(!pat) { 1941 c_error_msg("could not find pattern %s", name); 1942 return; 1943 } 1944 1945 /* apply settings */ 1946 if(pat->zonefile) 1947 a->zonefile = region_strdup(cfg_parser->opt->region, 1948 pat->zonefile); 1949 if(pat->zonestats) 1950 a->zonestats = region_strdup(cfg_parser->opt->region, 1951 pat->zonestats); 1952 if(!pat->allow_axfr_fallback_is_default) { 1953 a->allow_axfr_fallback = pat->allow_axfr_fallback; 1954 a->allow_axfr_fallback_is_default = 0; 1955 } 1956 if(!pat->notify_retry_is_default) { 1957 a->notify_retry = pat->notify_retry; 1958 a->notify_retry_is_default = 0; 1959 } 1960 if(!pat->max_refresh_time_is_default) { 1961 a->max_refresh_time = pat->max_refresh_time; 1962 a->max_refresh_time_is_default = 0; 1963 } 1964 if(!pat->min_refresh_time_is_default) { 1965 a->min_refresh_time = pat->min_refresh_time; 1966 a->min_refresh_time_is_default = 0; 1967 } 1968 if(!pat->max_retry_time_is_default) { 1969 a->max_retry_time = pat->max_retry_time; 1970 a->max_retry_time_is_default = 0; 1971 } 1972 if(!pat->min_retry_time_is_default) { 1973 a->min_retry_time = pat->min_retry_time; 1974 a->min_retry_time_is_default = 0; 1975 } 1976 a->size_limit_xfr = pat->size_limit_xfr; 1977 #ifdef RATELIMIT 1978 a->rrl_whitelist |= pat->rrl_whitelist; 1979 #endif 1980 /* append acl items */ 1981 append_acl(&a->allow_notify, &cfg_parser->current_allow_notify, 1982 pat->allow_notify); 1983 append_acl(&a->request_xfr, &cfg_parser->current_request_xfr, 1984 pat->request_xfr); 1985 append_acl(&a->notify, &cfg_parser->current_notify, pat->notify); 1986 append_acl(&a->provide_xfr, &cfg_parser->current_provide_xfr, 1987 pat->provide_xfr); 1988 append_acl(&a->outgoing_interface, &cfg_parser-> 1989 current_outgoing_interface, pat->outgoing_interface); 1990 if(pat->multi_master_check) 1991 a->multi_master_check = pat->multi_master_check; 1992 } 1993 1994 void 1995 nsd_options_destroy(nsd_options_t* opt) 1996 { 1997 region_destroy(opt->region); 1998 } 1999 2000 unsigned getzonestatid(nsd_options_t* opt, zone_options_t* zopt) 2001 { 2002 #ifdef USE_ZONE_STATS 2003 const char* statname; 2004 struct zonestatname* n; 2005 rbnode_t* res; 2006 /* try to find the instantiated zonestat name */ 2007 if(!zopt->pattern->zonestats || zopt->pattern->zonestats[0]==0) 2008 return 0; /* no zone stats */ 2009 statname = config_cook_string(zopt, zopt->pattern->zonestats); 2010 res = rbtree_search(opt->zonestatnames, statname); 2011 if(res) 2012 return ((struct zonestatname*)res)->id; 2013 /* create it */ 2014 n = (struct zonestatname*)xalloc(sizeof(*n)); 2015 memset(n, 0, sizeof(*n)); 2016 n->node.key = strdup(statname); 2017 if(!n->node.key) { 2018 log_msg(LOG_ERR, "malloc failed: %s", strerror(errno)); 2019 exit(1); 2020 } 2021 n->id = (unsigned)(opt->zonestatnames->count); 2022 rbtree_insert(opt->zonestatnames, (rbnode_t*)n); 2023 return n->id; 2024 #else /* USE_ZONE_STATS */ 2025 (void)opt; (void)zopt; 2026 return 0; 2027 #endif /* USE_ZONE_STATS */ 2028 } 2029