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