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->notify = 0; 817 p->provide_xfr = 0; 818 p->outgoing_interface = 0; 819 p->notify_retry = 5; 820 p->notify_retry_is_default = 1; 821 p->allow_axfr_fallback = 1; 822 p->allow_axfr_fallback_is_default = 1; 823 p->implicit = 0; 824 p->xfrd_flags = 0; 825 #ifdef RATELIMIT 826 p->rrl_whitelist = 0; 827 #endif 828 return p; 829 } 830 831 static void 832 acl_delete(region_type* region, acl_options_t* acl) 833 { 834 if(acl->ip_address_spec) 835 region_recycle(region, (void*)acl->ip_address_spec, 836 strlen(acl->ip_address_spec)+1); 837 if(acl->key_name) 838 region_recycle(region, (void*)acl->key_name, 839 strlen(acl->key_name)+1); 840 /* key_options is a convenience pointer, not owned by the acl */ 841 region_recycle(region, acl, sizeof(*acl)); 842 } 843 844 static void 845 acl_list_delete(region_type* region, acl_options_t* list) 846 { 847 acl_options_t* n; 848 while(list) { 849 n = list->next; 850 acl_delete(region, list); 851 list = n; 852 } 853 } 854 855 void 856 pattern_options_remove(nsd_options_t* opt, const char* name) 857 { 858 pattern_options_t* p = (pattern_options_t*)rbtree_delete( 859 opt->patterns, name); 860 /* delete p and its contents */ 861 if (!p) 862 return; 863 if(p->pname) 864 region_recycle(opt->region, (void*)p->pname, 865 strlen(p->pname)+1); 866 if(p->zonefile) 867 region_recycle(opt->region, (void*)p->zonefile, 868 strlen(p->zonefile)+1); 869 if(p->zonestats) 870 region_recycle(opt->region, (void*)p->zonestats, 871 strlen(p->zonestats)+1); 872 acl_list_delete(opt->region, p->allow_notify); 873 acl_list_delete(opt->region, p->request_xfr); 874 acl_list_delete(opt->region, p->notify); 875 acl_list_delete(opt->region, p->provide_xfr); 876 acl_list_delete(opt->region, p->outgoing_interface); 877 878 region_recycle(opt->region, p, sizeof(pattern_options_t)); 879 } 880 881 static acl_options_t* 882 copy_acl(region_type* region, acl_options_t* a) 883 { 884 acl_options_t* b; 885 if(!a) return NULL; 886 b = (acl_options_t*)region_alloc(region, sizeof(*b)); 887 /* copy the whole lot */ 888 *b = *a; 889 /* fix the pointers */ 890 if(a->ip_address_spec) 891 b->ip_address_spec = region_strdup(region, a->ip_address_spec); 892 if(a->key_name) 893 b->key_name = region_strdup(region, a->key_name); 894 b->next = NULL; 895 b->key_options = NULL; 896 return b; 897 } 898 899 static acl_options_t* 900 copy_acl_list(nsd_options_t* opt, acl_options_t* a) 901 { 902 acl_options_t* b, *blast = NULL, *blist = NULL; 903 while(a) { 904 b = copy_acl(opt->region, a); 905 /* fixup key_options */ 906 if(b->key_name) 907 b->key_options = key_options_find(opt, b->key_name); 908 else b->key_options = NULL; 909 910 /* link as last into list */ 911 b->next = NULL; 912 if(!blist) blist = b; 913 else blast->next = b; 914 blast = b; 915 916 a = a->next; 917 } 918 return blist; 919 } 920 921 static void 922 copy_changed_acl(nsd_options_t* opt, acl_options_t** orig, 923 acl_options_t* anew) 924 { 925 if(!acl_list_equal(*orig, anew)) { 926 acl_list_delete(opt->region, *orig); 927 *orig = copy_acl_list(opt, anew); 928 } 929 } 930 931 static void 932 copy_pat_fixed(region_type* region, pattern_options_t* orig, 933 pattern_options_t* p) 934 { 935 orig->allow_axfr_fallback = p->allow_axfr_fallback; 936 orig->allow_axfr_fallback_is_default = 937 p->allow_axfr_fallback_is_default; 938 orig->notify_retry = p->notify_retry; 939 orig->notify_retry_is_default = p->notify_retry_is_default; 940 orig->implicit = p->implicit; 941 if(p->zonefile) 942 orig->zonefile = region_strdup(region, p->zonefile); 943 else orig->zonefile = NULL; 944 if(p->zonestats) 945 orig->zonestats = region_strdup(region, p->zonestats); 946 else orig->zonestats = NULL; 947 #ifdef RATELIMIT 948 orig->rrl_whitelist = p->rrl_whitelist; 949 #endif 950 } 951 952 void 953 pattern_options_add_modify(nsd_options_t* opt, pattern_options_t* p) 954 { 955 pattern_options_t* orig = pattern_options_find(opt, p->pname); 956 if(!orig) { 957 /* needs to be copied to opt region */ 958 orig = pattern_options_create(opt->region); 959 orig->pname = region_strdup(opt->region, p->pname); 960 copy_pat_fixed(opt->region, orig, p); 961 orig->allow_notify = copy_acl_list(opt, p->allow_notify); 962 orig->request_xfr = copy_acl_list(opt, p->request_xfr); 963 orig->notify = copy_acl_list(opt, p->notify); 964 orig->provide_xfr = copy_acl_list(opt, p->provide_xfr); 965 orig->outgoing_interface = copy_acl_list(opt, 966 p->outgoing_interface); 967 nsd_options_insert_pattern(opt, orig); 968 } else { 969 /* modify in place so pointers stay valid (and copy 970 into region). Do not touch unchanged acls. */ 971 if(orig->zonefile) 972 region_recycle(opt->region, (char*)orig->zonefile, 973 strlen(orig->zonefile)+1); 974 if(orig->zonestats) 975 region_recycle(opt->region, (char*)orig->zonestats, 976 strlen(orig->zonestats)+1); 977 copy_pat_fixed(opt->region, orig, p); 978 copy_changed_acl(opt, &orig->allow_notify, p->allow_notify); 979 copy_changed_acl(opt, &orig->request_xfr, p->request_xfr); 980 copy_changed_acl(opt, &orig->notify, p->notify); 981 copy_changed_acl(opt, &orig->provide_xfr, p->provide_xfr); 982 copy_changed_acl(opt, &orig->outgoing_interface, 983 p->outgoing_interface); 984 } 985 } 986 987 pattern_options_t* 988 pattern_options_find(nsd_options_t* opt, const char* name) 989 { 990 return (pattern_options_t*)rbtree_search(opt->patterns, name); 991 } 992 993 int 994 pattern_options_equal(pattern_options_t* p, pattern_options_t* q) 995 { 996 if(strcmp(p->pname, q->pname) != 0) return 0; 997 if(!p->zonefile && q->zonefile) return 0; 998 else if(p->zonefile && !q->zonefile) return 0; 999 else if(p->zonefile && q->zonefile) { 1000 if(strcmp(p->zonefile, q->zonefile) != 0) return 0; 1001 } 1002 if(!p->zonestats && q->zonestats) return 0; 1003 else if(p->zonestats && !q->zonestats) return 0; 1004 else if(p->zonestats && q->zonestats) { 1005 if(strcmp(p->zonestats, q->zonestats) != 0) return 0; 1006 } 1007 if(!booleq(p->allow_axfr_fallback, q->allow_axfr_fallback)) return 0; 1008 if(!booleq(p->allow_axfr_fallback_is_default, 1009 q->allow_axfr_fallback_is_default)) return 0; 1010 if(p->notify_retry != q->notify_retry) return 0; 1011 if(!booleq(p->notify_retry_is_default, 1012 q->notify_retry_is_default)) return 0; 1013 if(!booleq(p->implicit, q->implicit)) return 0; 1014 if(!acl_list_equal(p->allow_notify, q->allow_notify)) return 0; 1015 if(!acl_list_equal(p->request_xfr, q->request_xfr)) return 0; 1016 if(!acl_list_equal(p->notify, q->notify)) return 0; 1017 if(!acl_list_equal(p->provide_xfr, q->provide_xfr)) return 0; 1018 if(!acl_list_equal(p->outgoing_interface, q->outgoing_interface)) 1019 return 0; 1020 #ifdef RATELIMIT 1021 if(p->rrl_whitelist != q->rrl_whitelist) return 0; 1022 #endif 1023 return 1; 1024 } 1025 1026 static void 1027 marshal_u8(struct buffer* b, uint8_t v) 1028 { 1029 buffer_reserve(b, 1); 1030 buffer_write_u8(b, v); 1031 } 1032 1033 static uint8_t 1034 unmarshal_u8(struct buffer* b) 1035 { 1036 return buffer_read_u8(b); 1037 } 1038 1039 #ifdef RATELIMIT 1040 static void 1041 marshal_u16(struct buffer* b, uint16_t v) 1042 { 1043 buffer_reserve(b, 2); 1044 buffer_write_u16(b, v); 1045 } 1046 #endif 1047 1048 #ifdef RATELIMIT 1049 static uint16_t 1050 unmarshal_u16(struct buffer* b) 1051 { 1052 return buffer_read_u16(b); 1053 } 1054 #endif 1055 1056 static void 1057 marshal_str(struct buffer* b, const char* s) 1058 { 1059 if(!s) marshal_u8(b, 0); 1060 else { 1061 size_t len = strlen(s); 1062 marshal_u8(b, 1); 1063 buffer_reserve(b, len+1); 1064 buffer_write(b, s, len+1); 1065 } 1066 } 1067 1068 static char* 1069 unmarshal_str(region_type* r, struct buffer* b) 1070 { 1071 uint8_t nonnull = unmarshal_u8(b); 1072 if(nonnull) { 1073 char* result = region_strdup(r, (char*)buffer_current(b)); 1074 size_t len = strlen((char*)buffer_current(b)); 1075 buffer_skip(b, len+1); 1076 return result; 1077 } else return NULL; 1078 } 1079 1080 static void 1081 marshal_acl(struct buffer* b, acl_options_t* acl) 1082 { 1083 buffer_reserve(b, sizeof(*acl)); 1084 buffer_write(b, acl, sizeof(*acl)); 1085 marshal_str(b, acl->ip_address_spec); 1086 marshal_str(b, acl->key_name); 1087 } 1088 1089 static acl_options_t* 1090 unmarshal_acl(region_type* r, struct buffer* b) 1091 { 1092 acl_options_t* acl = (acl_options_t*)region_alloc(r, sizeof(*acl)); 1093 buffer_read(b, acl, sizeof(*acl)); 1094 acl->next = NULL; 1095 acl->key_options = NULL; 1096 acl->ip_address_spec = unmarshal_str(r, b); 1097 acl->key_name = unmarshal_str(r, b); 1098 return acl; 1099 } 1100 1101 static void 1102 marshal_acl_list(struct buffer* b, acl_options_t* list) 1103 { 1104 while(list) { 1105 marshal_u8(b, 1); /* is there a next one marker */ 1106 marshal_acl(b, list); 1107 list = list->next; 1108 } 1109 marshal_u8(b, 0); /* end of list marker */ 1110 } 1111 1112 static acl_options_t* 1113 unmarshal_acl_list(region_type* r, struct buffer* b) 1114 { 1115 acl_options_t* a, *last=NULL, *list=NULL; 1116 while(unmarshal_u8(b)) { 1117 a = unmarshal_acl(r, b); 1118 /* link in */ 1119 a->next = NULL; 1120 if(!list) list = a; 1121 else last->next = a; 1122 last = a; 1123 } 1124 return list; 1125 } 1126 1127 void 1128 pattern_options_marshal(struct buffer* b, pattern_options_t* p) 1129 { 1130 marshal_str(b, p->pname); 1131 marshal_str(b, p->zonefile); 1132 marshal_str(b, p->zonestats); 1133 #ifdef RATELIMIT 1134 marshal_u16(b, p->rrl_whitelist); 1135 #endif 1136 marshal_u8(b, p->allow_axfr_fallback); 1137 marshal_u8(b, p->allow_axfr_fallback_is_default); 1138 marshal_u8(b, p->notify_retry); 1139 marshal_u8(b, p->notify_retry_is_default); 1140 marshal_u8(b, p->implicit); 1141 marshal_acl_list(b, p->allow_notify); 1142 marshal_acl_list(b, p->request_xfr); 1143 marshal_acl_list(b, p->notify); 1144 marshal_acl_list(b, p->provide_xfr); 1145 marshal_acl_list(b, p->outgoing_interface); 1146 } 1147 1148 pattern_options_t* 1149 pattern_options_unmarshal(region_type* r, struct buffer* b) 1150 { 1151 pattern_options_t* p = pattern_options_create(r); 1152 p->pname = unmarshal_str(r, b); 1153 p->zonefile = unmarshal_str(r, b); 1154 p->zonestats = unmarshal_str(r, b); 1155 #ifdef RATELIMIT 1156 p->rrl_whitelist = unmarshal_u16(b); 1157 #endif 1158 p->allow_axfr_fallback = unmarshal_u8(b); 1159 p->allow_axfr_fallback_is_default = unmarshal_u8(b); 1160 p->notify_retry = unmarshal_u8(b); 1161 p->notify_retry_is_default = unmarshal_u8(b); 1162 p->implicit = unmarshal_u8(b); 1163 p->allow_notify = unmarshal_acl_list(r, b); 1164 p->request_xfr = unmarshal_acl_list(r, b); 1165 p->notify = unmarshal_acl_list(r, b); 1166 p->provide_xfr = unmarshal_acl_list(r, b); 1167 p->outgoing_interface = unmarshal_acl_list(r, b); 1168 return p; 1169 } 1170 1171 key_options_t* 1172 key_options_create(region_type* region) 1173 { 1174 key_options_t* key; 1175 key = (key_options_t*)region_alloc_zero(region, sizeof(key_options_t)); 1176 return key; 1177 } 1178 1179 void 1180 key_options_insert(nsd_options_t* opt, key_options_t* key) 1181 { 1182 if(!key->name) return; 1183 key->node.key = key->name; 1184 (void)rbtree_insert(opt->keys, &key->node); 1185 } 1186 1187 key_options_t* 1188 key_options_find(nsd_options_t* opt, const char* name) 1189 { 1190 return (key_options_t*)rbtree_search(opt->keys, name); 1191 } 1192 1193 /** remove tsig_key contents */ 1194 void 1195 key_options_desetup(region_type* region, key_options_t* key) 1196 { 1197 /* keep tsig_key pointer so that existing references keep valid */ 1198 if(!key->tsig_key) 1199 return; 1200 /* name stays the same */ 1201 if(key->tsig_key->data) { 1202 /* wipe secret! */ 1203 memset(key->tsig_key->data, 0xdd, key->tsig_key->size); 1204 region_recycle(region, key->tsig_key->data, 1205 key->tsig_key->size); 1206 key->tsig_key->data = NULL; 1207 key->tsig_key->size = 0; 1208 } 1209 } 1210 1211 /** add tsig_key contents */ 1212 void 1213 key_options_setup(region_type* region, key_options_t* key) 1214 { 1215 uint8_t data[16384]; /* 16KB */ 1216 int size; 1217 if(!key->tsig_key) { 1218 /* create it */ 1219 key->tsig_key = (tsig_key_type *) region_alloc(region, 1220 sizeof(tsig_key_type)); 1221 /* create name */ 1222 key->tsig_key->name = dname_parse(region, key->name); 1223 if(!key->tsig_key->name) { 1224 log_msg(LOG_ERR, "Failed to parse tsig key name %s", 1225 key->name); 1226 /* key and base64 were checked during syntax parse */ 1227 exit(1); 1228 } 1229 key->tsig_key->size = 0; 1230 key->tsig_key->data = NULL; 1231 } 1232 size = __b64_pton(key->secret, data, sizeof(data)); 1233 if(size == -1) { 1234 log_msg(LOG_ERR, "Failed to parse tsig key data %s", 1235 key->name); 1236 /* key and base64 were checked during syntax parse */ 1237 exit(1); 1238 } 1239 key->tsig_key->size = size; 1240 key->tsig_key->data = (uint8_t *)region_alloc_init(region, data, size); 1241 } 1242 1243 void 1244 key_options_remove(nsd_options_t* opt, const char* name) 1245 { 1246 key_options_t* k = key_options_find(opt, name); 1247 if(!k) return; 1248 (void)rbtree_delete(opt->keys, name); 1249 if(k->name) 1250 region_recycle(opt->region, k->name, strlen(k->name)+1); 1251 if(k->algorithm) 1252 region_recycle(opt->region, k->algorithm, strlen(k->algorithm)+1); 1253 if(k->secret) { 1254 memset(k->secret, 0xdd, strlen(k->secret)); /* wipe secret! */ 1255 region_recycle(opt->region, k->secret, strlen(k->secret)+1); 1256 } 1257 if(k->tsig_key) { 1258 tsig_del_key(k->tsig_key); 1259 if(k->tsig_key->name) 1260 region_recycle(opt->region, (void*)k->tsig_key->name, 1261 dname_total_size(k->tsig_key->name)); 1262 key_options_desetup(opt->region, k); 1263 region_recycle(opt->region, k->tsig_key, sizeof(tsig_key_type)); 1264 } 1265 region_recycle(opt->region, k, sizeof(key_options_t)); 1266 } 1267 1268 int 1269 key_options_equal(key_options_t* p, key_options_t* q) 1270 { 1271 return strcmp(p->name, q->name)==0 && strcmp(p->algorithm, 1272 q->algorithm)==0 && strcmp(p->secret, q->secret)==0; 1273 } 1274 1275 void 1276 key_options_add_modify(nsd_options_t* opt, key_options_t* key) 1277 { 1278 key_options_t* orig = key_options_find(opt, key->name); 1279 if(!orig) { 1280 /* needs to be copied to opt region */ 1281 orig = key_options_create(opt->region); 1282 orig->name = region_strdup(opt->region, key->name); 1283 orig->algorithm = region_strdup(opt->region, key->algorithm); 1284 orig->secret = region_strdup(opt->region, key->secret); 1285 key_options_setup(opt->region, orig); 1286 tsig_add_key(orig->tsig_key); 1287 key_options_insert(opt, orig); 1288 } else { 1289 /* modify entries in existing key, and copy to opt region */ 1290 key_options_desetup(opt->region, orig); 1291 region_recycle(opt->region, orig->algorithm, 1292 strlen(orig->algorithm)+1); 1293 orig->algorithm = region_strdup(opt->region, key->algorithm); 1294 region_recycle(opt->region, orig->secret, 1295 strlen(orig->secret)+1); 1296 orig->secret = region_strdup(opt->region, key->secret); 1297 key_options_setup(opt->region, orig); 1298 } 1299 } 1300 1301 int 1302 acl_check_incoming(acl_options_t* acl, struct query* q, 1303 acl_options_t** reason) 1304 { 1305 /* check each acl element. 1306 if 1 blocked element matches - return -1. 1307 if any element matches - return number. 1308 else return -1. */ 1309 int found_match = -1; 1310 int number = 0; 1311 acl_options_t* match = 0; 1312 1313 if(reason) 1314 *reason = NULL; 1315 1316 while(acl) 1317 { 1318 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "testing acl %s %s", 1319 acl->ip_address_spec, acl->nokey?"NOKEY": 1320 (acl->blocked?"BLOCKED":acl->key_name))); 1321 if(acl_addr_matches(acl, q) && acl_key_matches(acl, q)) { 1322 if(!match) 1323 { 1324 match = acl; /* remember first match */ 1325 found_match=number; 1326 } 1327 if(acl->blocked) { 1328 if(reason) 1329 *reason = acl; 1330 return -1; 1331 } 1332 } 1333 number++; 1334 acl = acl->next; 1335 } 1336 1337 if(reason) 1338 *reason = match; 1339 return found_match; 1340 } 1341 1342 #ifdef INET6 1343 int 1344 acl_addr_matches_ipv6host(acl_options_t* acl, struct sockaddr_storage* addr_storage, unsigned int port) 1345 { 1346 struct sockaddr_in6* addr = (struct sockaddr_in6*)addr_storage; 1347 if(acl->port != 0 && acl->port != port) 1348 return 0; 1349 switch(acl->rangetype) { 1350 case acl_range_mask: 1351 case acl_range_subnet: 1352 if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr, 1353 (uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr))) 1354 return 0; 1355 break; 1356 case acl_range_minmax: 1357 if(!acl_addr_match_range((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr, 1358 (uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr))) 1359 return 0; 1360 break; 1361 case acl_range_single: 1362 default: 1363 if(memcmp(&addr->sin6_addr, &acl->addr.addr6, 1364 sizeof(struct in6_addr)) != 0) 1365 return 0; 1366 break; 1367 } 1368 return 1; 1369 } 1370 #endif 1371 1372 int 1373 acl_addr_matches_ipv4host(acl_options_t* acl, struct sockaddr_in* addr, unsigned int port) 1374 { 1375 if(acl->port != 0 && acl->port != port) 1376 return 0; 1377 switch(acl->rangetype) { 1378 case acl_range_mask: 1379 case acl_range_subnet: 1380 if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr, 1381 (uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr))) 1382 return 0; 1383 break; 1384 case acl_range_minmax: 1385 if(!acl_addr_match_range((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr, 1386 (uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr))) 1387 return 0; 1388 break; 1389 case acl_range_single: 1390 default: 1391 if(memcmp(&addr->sin_addr, &acl->addr.addr, 1392 sizeof(struct in_addr)) != 0) 1393 return 0; 1394 break; 1395 } 1396 return 1; 1397 } 1398 1399 int 1400 acl_addr_matches_host(acl_options_t* acl, acl_options_t* host) 1401 { 1402 if(acl->is_ipv6) 1403 { 1404 #ifdef INET6 1405 struct sockaddr_storage* addr = (struct sockaddr_storage*)&host->addr; 1406 if(!host->is_ipv6) return 0; 1407 return acl_addr_matches_ipv6host(acl, addr, host->port); 1408 #else 1409 return 0; /* no inet6, no match */ 1410 #endif 1411 } 1412 else 1413 { 1414 struct sockaddr_in* addr = (struct sockaddr_in*)&host->addr; 1415 if(host->is_ipv6) return 0; 1416 return acl_addr_matches_ipv4host(acl, addr, host->port); 1417 } 1418 /* ENOTREACH */ 1419 return 0; 1420 } 1421 1422 int 1423 acl_addr_matches(acl_options_t* acl, struct query* q) 1424 { 1425 if(acl->is_ipv6) 1426 { 1427 #ifdef INET6 1428 struct sockaddr_storage* addr = (struct sockaddr_storage*)&q->addr; 1429 if(addr->ss_family != AF_INET6) 1430 return 0; 1431 return acl_addr_matches_ipv6host(acl, addr, ntohs(((struct sockaddr_in6*)addr)->sin6_port)); 1432 #else 1433 return 0; /* no inet6, no match */ 1434 #endif 1435 } 1436 else 1437 { 1438 struct sockaddr_in* addr = (struct sockaddr_in*)&q->addr; 1439 if(addr->sin_family != AF_INET) 1440 return 0; 1441 return acl_addr_matches_ipv4host(acl, addr, ntohs(addr->sin_port)); 1442 } 1443 /* ENOTREACH */ 1444 return 0; 1445 } 1446 1447 int 1448 acl_addr_match_mask(uint32_t* a, uint32_t* b, uint32_t* mask, size_t sz) 1449 { 1450 size_t i; 1451 #ifndef NDEBUG 1452 assert(sz % 4 == 0); 1453 #endif 1454 sz /= 4; 1455 for(i=0; i<sz; ++i) 1456 { 1457 if(((*a++)&*mask) != ((*b++)&*mask)) 1458 return 0; 1459 ++mask; 1460 } 1461 return 1; 1462 } 1463 1464 int 1465 acl_addr_match_range(uint32_t* minval, uint32_t* x, uint32_t* maxval, size_t sz) 1466 { 1467 size_t i; 1468 uint8_t checkmin = 1, checkmax = 1; 1469 #ifndef NDEBUG 1470 assert(sz % 4 == 0); 1471 #endif 1472 /* check treats x as one huge number */ 1473 sz /= 4; 1474 for(i=0; i<sz; ++i) 1475 { 1476 /* if outside bounds, we are done */ 1477 if(checkmin) 1478 if(minval[i] > x[i]) 1479 return 0; 1480 if(checkmax) 1481 if(maxval[i] < x[i]) 1482 return 0; 1483 /* if x is equal to a bound, that bound needs further checks */ 1484 if(checkmin && minval[i]!=x[i]) 1485 checkmin = 0; 1486 if(checkmax && maxval[i]!=x[i]) 1487 checkmax = 0; 1488 if(!checkmin && !checkmax) 1489 return 1; /* will always match */ 1490 } 1491 return 1; 1492 } 1493 1494 int 1495 acl_key_matches(acl_options_t* acl, struct query* q) 1496 { 1497 if(acl->blocked) 1498 return 1; 1499 if(acl->nokey) { 1500 if(q->tsig.status == TSIG_NOT_PRESENT) 1501 return 1; 1502 return 0; 1503 } 1504 /* check name of tsig key */ 1505 if(q->tsig.status != TSIG_OK) { 1506 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail query has no TSIG")); 1507 return 0; /* query has no TSIG */ 1508 } 1509 if(q->tsig.error_code != TSIG_ERROR_NOERROR) { 1510 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail, tsig has error")); 1511 return 0; /* some tsig error */ 1512 } 1513 if(!acl->key_options->tsig_key) { 1514 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail no config")); 1515 return 0; /* key not properly configured */ 1516 } 1517 if(dname_compare(q->tsig.key_name, 1518 acl->key_options->tsig_key->name) != 0) { 1519 DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail wrong key name")); 1520 return 0; /* wrong key name */ 1521 } 1522 if(tsig_strlowercmp(q->tsig.algorithm->short_name, 1523 acl->key_options->algorithm) != 0) { 1524 DEBUG(DEBUG_XFRD,2, (LOG_ERR, "query tsig wrong algorithm")); 1525 return 0; /* no such algo */ 1526 } 1527 return 1; 1528 } 1529 1530 int 1531 acl_same_host(acl_options_t* a, acl_options_t* b) 1532 { 1533 if(a->is_ipv6 && !b->is_ipv6) 1534 return 0; 1535 if(!a->is_ipv6 && b->is_ipv6) 1536 return 0; 1537 if(a->port != b->port) 1538 return 0; 1539 if(a->rangetype != b->rangetype) 1540 return 0; 1541 if(!a->is_ipv6) { 1542 if(memcmp(&a->addr.addr, &b->addr.addr, 1543 sizeof(struct in_addr)) != 0) 1544 return 0; 1545 if(a->rangetype != acl_range_single && 1546 memcmp(&a->range_mask.addr, &b->range_mask.addr, 1547 sizeof(struct in_addr)) != 0) 1548 return 0; 1549 } else { 1550 #ifdef INET6 1551 if(memcmp(&a->addr.addr6, &b->addr.addr6, 1552 sizeof(struct in6_addr)) != 0) 1553 return 0; 1554 if(a->rangetype != acl_range_single && 1555 memcmp(&a->range_mask.addr6, &b->range_mask.addr6, 1556 sizeof(struct in6_addr)) != 0) 1557 return 0; 1558 #else 1559 return 0; 1560 #endif 1561 } 1562 return 1; 1563 } 1564 1565 #if defined(HAVE_SSL) 1566 void 1567 key_options_tsig_add(nsd_options_t* opt) 1568 { 1569 key_options_t* optkey; 1570 RBTREE_FOR(optkey, key_options_t*, opt->keys) { 1571 key_options_setup(opt->region, optkey); 1572 tsig_add_key(optkey->tsig_key); 1573 } 1574 } 1575 #endif 1576 1577 int 1578 zone_is_slave(zone_options_t* opt) 1579 { 1580 return opt && opt->pattern && opt->pattern->request_xfr != 0; 1581 } 1582 1583 /* get a character in string (or replacement char if not long enough) */ 1584 static const char* 1585 get_char(const char* str, size_t i) 1586 { 1587 static char res[2]; 1588 if(i >= strlen(str)) 1589 return "."; 1590 res[0] = str[i]; 1591 res[1] = 0; 1592 return res; 1593 } 1594 /* get end label of the zone name (or .) */ 1595 static const char* 1596 get_end_label(zone_options_t* zone, int i) 1597 { 1598 const dname_type* d = (const dname_type*)zone->node.key; 1599 if(i >= d->label_count) { 1600 return "."; 1601 } 1602 return wirelabel2str(dname_label(d, i)); 1603 } 1604 /* replace occurrences of one with two */ 1605 void 1606 replace_str(char* str, size_t len, const char* one, const char* two) 1607 { 1608 char* pos; 1609 char* at = str; 1610 while( (pos=strstr(at, one)) ) { 1611 if(strlen(str)+strlen(two)-strlen(one) >= len) 1612 return; /* no more space to replace */ 1613 /* stuff before pos is fine */ 1614 /* move the stuff after pos to make space for two, add 1615 * one to length of remainder to also copy the 0 byte end */ 1616 memmove(pos+strlen(two), pos+strlen(one), 1617 strlen(pos+strlen(one))+1); 1618 /* copy in two */ 1619 memmove(pos, two, strlen(two)); 1620 /* at is end of the newly inserted two (avoids recursion if 1621 * two contains one) */ 1622 at = pos+strlen(two); 1623 } 1624 } 1625 1626 const char* 1627 config_cook_string(zone_options_t* zone, const char* input) 1628 { 1629 static char f[1024]; 1630 /* if not a template, return as-is */ 1631 if(!strchr(input, '%')) { 1632 return input; 1633 } 1634 strlcpy(f, input, sizeof(f)); 1635 if(strstr(f, "%1")) 1636 replace_str(f, sizeof(f), "%1", get_char(zone->name, 0)); 1637 if(strstr(f, "%2")) 1638 replace_str(f, sizeof(f), "%2", get_char(zone->name, 1)); 1639 if(strstr(f, "%3")) 1640 replace_str(f, sizeof(f), "%3", get_char(zone->name, 2)); 1641 if(strstr(f, "%z")) 1642 replace_str(f, sizeof(f), "%z", get_end_label(zone, 1)); 1643 if(strstr(f, "%y")) 1644 replace_str(f, sizeof(f), "%y", get_end_label(zone, 2)); 1645 if(strstr(f, "%x")) 1646 replace_str(f, sizeof(f), "%x", get_end_label(zone, 3)); 1647 if(strstr(f, "%s")) 1648 replace_str(f, sizeof(f), "%s", zone->name); 1649 return f; 1650 } 1651 1652 const char* 1653 config_make_zonefile(zone_options_t* zone, struct nsd* nsd) 1654 { 1655 static char f[1024]; 1656 /* if not a template, return as-is */ 1657 if(!strchr(zone->pattern->zonefile, '%')) { 1658 if (nsd->chrootdir && nsd->chrootdir[0] && 1659 zone->pattern->zonefile && 1660 zone->pattern->zonefile[0] == '/' && 1661 strncmp(zone->pattern->zonefile, nsd->chrootdir, 1662 strlen(nsd->chrootdir)) == 0) 1663 /* -1 because chrootdir ends in trailing slash */ 1664 return zone->pattern->zonefile + strlen(nsd->chrootdir) - 1; 1665 return zone->pattern->zonefile; 1666 } 1667 strlcpy(f, zone->pattern->zonefile, sizeof(f)); 1668 if(strstr(f, "%1")) 1669 replace_str(f, sizeof(f), "%1", get_char(zone->name, 0)); 1670 if(strstr(f, "%2")) 1671 replace_str(f, sizeof(f), "%2", get_char(zone->name, 1)); 1672 if(strstr(f, "%3")) 1673 replace_str(f, sizeof(f), "%3", get_char(zone->name, 2)); 1674 if(strstr(f, "%z")) 1675 replace_str(f, sizeof(f), "%z", get_end_label(zone, 1)); 1676 if(strstr(f, "%y")) 1677 replace_str(f, sizeof(f), "%y", get_end_label(zone, 2)); 1678 if(strstr(f, "%x")) 1679 replace_str(f, sizeof(f), "%x", get_end_label(zone, 3)); 1680 if(strstr(f, "%s")) 1681 replace_str(f, sizeof(f), "%s", zone->name); 1682 if (nsd->chrootdir && nsd->chrootdir[0] && f[0] == '/' && 1683 strncmp(f, nsd->chrootdir, strlen(nsd->chrootdir)) == 0) 1684 /* -1 because chrootdir ends in trailing slash */ 1685 return f + strlen(nsd->chrootdir) - 1; 1686 return f; 1687 } 1688 1689 zone_options_t* 1690 zone_options_find(nsd_options_t* opt, const struct dname* apex) 1691 { 1692 return (zone_options_t*) rbtree_search(opt->zone_options, apex); 1693 } 1694 1695 acl_options_t* 1696 acl_find_num(acl_options_t* acl, int num) 1697 { 1698 int count = num; 1699 if(num < 0) 1700 return 0; 1701 while(acl && count > 0) { 1702 acl = acl->next; 1703 count--; 1704 } 1705 if(count == 0) 1706 return acl; 1707 return 0; 1708 } 1709 1710 /* true if ipv6 address, false if ipv4 */ 1711 int 1712 parse_acl_is_ipv6(const char* p) 1713 { 1714 /* see if addr is ipv6 or ipv4 -- by : and . */ 1715 while(*p) { 1716 if(*p == '.') return 0; 1717 if(*p == ':') return 1; 1718 ++p; 1719 } 1720 return 0; 1721 } 1722 1723 /* returns range type. mask is the 2nd part of the range */ 1724 int 1725 parse_acl_range_type(char* ip, char** mask) 1726 { 1727 char *p; 1728 if((p=strchr(ip, '&'))!=0) { 1729 *p = 0; 1730 *mask = p+1; 1731 return acl_range_mask; 1732 } 1733 if((p=strchr(ip, '/'))!=0) { 1734 *p = 0; 1735 *mask = p+1; 1736 return acl_range_subnet; 1737 } 1738 if((p=strchr(ip, '-'))!=0) { 1739 *p = 0; 1740 *mask = p+1; 1741 return acl_range_minmax; 1742 } 1743 *mask = 0; 1744 return acl_range_single; 1745 } 1746 1747 /* parses subnet mask, fills 0 mask as well */ 1748 void 1749 parse_acl_range_subnet(char* p, void* addr, int maxbits) 1750 { 1751 int subnet_bits = atoi(p); 1752 uint8_t* addr_bytes = (uint8_t*)addr; 1753 if(subnet_bits == 0 && strcmp(p, "0")!=0) { 1754 c_error_msg("bad subnet range '%s'", p); 1755 return; 1756 } 1757 if(subnet_bits < 0 || subnet_bits > maxbits) { 1758 c_error_msg("subnet of %d bits out of range [0..%d]", subnet_bits, maxbits); 1759 return; 1760 } 1761 /* fill addr with n bits of 1s (struct has been zeroed) */ 1762 while(subnet_bits >= 8) { 1763 *addr_bytes++ = 0xff; 1764 subnet_bits -= 8; 1765 } 1766 if(subnet_bits > 0) { 1767 uint8_t shifts[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; 1768 *addr_bytes = shifts[subnet_bits]; 1769 } 1770 } 1771 1772 acl_options_t* 1773 parse_acl_info(region_type* region, char* ip, const char* key) 1774 { 1775 char* p; 1776 acl_options_t* acl = (acl_options_t*)region_alloc(region, sizeof(acl_options_t)); 1777 acl->next = 0; 1778 /* ip */ 1779 acl->ip_address_spec = region_strdup(region, ip); 1780 acl->use_axfr_only = 0; 1781 acl->allow_udp = 0; 1782 acl->ixfr_disabled = 0; 1783 acl->bad_xfr_count = 0; 1784 acl->key_options = 0; 1785 acl->is_ipv6 = 0; 1786 acl->port = 0; 1787 memset(&acl->addr, 0, sizeof(union acl_addr_storage)); 1788 memset(&acl->range_mask, 0, sizeof(union acl_addr_storage)); 1789 if((p=strrchr(ip, '@'))!=0) { 1790 if(atoi(p+1) == 0) c_error("expected port number after '@'"); 1791 else acl->port = atoi(p+1); 1792 *p=0; 1793 } 1794 acl->rangetype = parse_acl_range_type(ip, &p); 1795 if(parse_acl_is_ipv6(ip)) { 1796 acl->is_ipv6 = 1; 1797 #ifdef INET6 1798 if(inet_pton(AF_INET6, ip, &acl->addr.addr6) != 1) 1799 c_error_msg("Bad ip6 address '%s'", ip); 1800 if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) 1801 if(inet_pton(AF_INET6, p, &acl->range_mask.addr6) != 1) 1802 c_error_msg("Bad ip6 address mask '%s'", p); 1803 if(acl->rangetype==acl_range_subnet) 1804 parse_acl_range_subnet(p, &acl->range_mask.addr6, 128); 1805 #else 1806 c_error_msg("encountered IPv6 address '%s'.", ip); 1807 #endif /* INET6 */ 1808 } else { 1809 acl->is_ipv6 = 0; 1810 if(inet_pton(AF_INET, ip, &acl->addr.addr) != 1) 1811 c_error_msg("Bad ip4 address '%s'", ip); 1812 if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) 1813 if(inet_pton(AF_INET, p, &acl->range_mask.addr) != 1) 1814 c_error_msg("Bad ip4 address mask '%s'", p); 1815 if(acl->rangetype==acl_range_subnet) 1816 parse_acl_range_subnet(p, &acl->range_mask.addr, 32); 1817 } 1818 1819 /* key */ 1820 if(strcmp(key, "NOKEY")==0) { 1821 acl->nokey = 1; 1822 acl->blocked = 0; 1823 acl->key_name = 0; 1824 } else if(strcmp(key, "BLOCKED")==0) { 1825 acl->nokey = 0; 1826 acl->blocked = 1; 1827 acl->key_name = 0; 1828 } else { 1829 acl->nokey = 0; 1830 acl->blocked = 0; 1831 acl->key_name = region_strdup(region, key); 1832 } 1833 return acl; 1834 } 1835 1836 /* copy acl list at end of parser start, update current */ 1837 static 1838 void append_acl(acl_options_t** start, acl_options_t** cur, 1839 acl_options_t* list) 1840 { 1841 while(list) { 1842 acl_options_t* acl = copy_acl(cfg_parser->opt->region, list); 1843 acl->next = NULL; 1844 if(*cur) 1845 (*cur)->next = acl; 1846 else *start = acl; 1847 *cur = acl; 1848 list = list->next; 1849 } 1850 } 1851 1852 void 1853 config_apply_pattern(const char* name) 1854 { 1855 /* find the pattern */ 1856 pattern_options_t* pat = pattern_options_find(cfg_parser->opt, name); 1857 pattern_options_t* a = cfg_parser->current_pattern; 1858 if(!pat) { 1859 c_error_msg("could not find pattern %s", name); 1860 return; 1861 } 1862 1863 /* apply settings */ 1864 if(pat->zonefile) 1865 a->zonefile = region_strdup(cfg_parser->opt->region, 1866 pat->zonefile); 1867 if(pat->zonestats) 1868 a->zonestats = region_strdup(cfg_parser->opt->region, 1869 pat->zonestats); 1870 if(!pat->allow_axfr_fallback_is_default) { 1871 a->allow_axfr_fallback = pat->allow_axfr_fallback; 1872 a->allow_axfr_fallback_is_default = 0; 1873 } 1874 if(!pat->notify_retry_is_default) { 1875 a->notify_retry = pat->notify_retry; 1876 a->notify_retry_is_default = 0; 1877 } 1878 #ifdef RATELIMIT 1879 a->rrl_whitelist |= pat->rrl_whitelist; 1880 #endif 1881 /* append acl items */ 1882 append_acl(&a->allow_notify, &cfg_parser->current_allow_notify, 1883 pat->allow_notify); 1884 append_acl(&a->request_xfr, &cfg_parser->current_request_xfr, 1885 pat->request_xfr); 1886 append_acl(&a->notify, &cfg_parser->current_notify, pat->notify); 1887 append_acl(&a->provide_xfr, &cfg_parser->current_provide_xfr, 1888 pat->provide_xfr); 1889 append_acl(&a->outgoing_interface, &cfg_parser-> 1890 current_outgoing_interface, pat->outgoing_interface); 1891 } 1892 1893 void 1894 nsd_options_destroy(nsd_options_t* opt) 1895 { 1896 region_destroy(opt->region); 1897 } 1898 1899 unsigned getzonestatid(nsd_options_t* opt, zone_options_t* zopt) 1900 { 1901 #ifdef USE_ZONE_STATS 1902 const char* statname; 1903 struct zonestatname* n; 1904 rbnode_t* res; 1905 /* try to find the instantiated zonestat name */ 1906 if(!zopt->pattern->zonestats || zopt->pattern->zonestats[0]==0) 1907 return 0; /* no zone stats */ 1908 statname = config_cook_string(zopt, zopt->pattern->zonestats); 1909 res = rbtree_search(opt->zonestatnames, statname); 1910 if(res) 1911 return ((struct zonestatname*)res)->id; 1912 /* create it */ 1913 n = (struct zonestatname*)xalloc(sizeof(*n)); 1914 memset(n, 0, sizeof(*n)); 1915 n->node.key = strdup(statname); 1916 if(!n->node.key) { 1917 log_msg(LOG_ERR, "malloc failed: %s", strerror(errno)); 1918 exit(1); 1919 } 1920 n->id = (unsigned)(opt->zonestatnames->count); 1921 rbtree_insert(opt->zonestatnames, (rbnode_t*)n); 1922 return n->id; 1923 #else /* USE_ZONE_STATS */ 1924 (void)opt; (void)zopt; 1925 return 0; 1926 #endif /* USE_ZONE_STATS */ 1927 } 1928