1 /* $NetBSD: zoneconf.c,v 1.6 2019/11/27 05:48:40 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * This Source Code Form is subject to the terms of the Mozilla Public 7 * License, v. 2.0. If a copy of the MPL was not distributed with this 8 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * See the COPYRIGHT file distributed with this work for additional 11 * information regarding copyright ownership. 12 */ 13 14 #include <config.h> 15 16 #include <inttypes.h> 17 #include <stdbool.h> 18 19 #include <isc/buffer.h> 20 #include <isc/file.h> 21 #include <isc/mem.h> 22 #include <isc/print.h> 23 #include <isc/stats.h> 24 #include <isc/string.h> /* Required for HP/UX (and others?) */ 25 #include <isc/util.h> 26 27 #include <dns/acl.h> 28 #include <dns/db.h> 29 #include <dns/ipkeylist.h> 30 #include <dns/fixedname.h> 31 #include <dns/journal.h> 32 #include <dns/log.h> 33 #include <dns/name.h> 34 #include <dns/masterdump.h> 35 #include <dns/rdata.h> 36 #include <dns/rdatatype.h> 37 #include <dns/rdataset.h> 38 #include <dns/rdatalist.h> 39 #include <dns/result.h> 40 #include <dns/sdlz.h> 41 #include <dns/ssu.h> 42 #include <dns/stats.h> 43 #include <dns/tsig.h> 44 #include <dns/view.h> 45 #include <dns/zone.h> 46 47 #include <ns/client.h> 48 49 #include <named/config.h> 50 #include <named/globals.h> 51 #include <named/log.h> 52 #include <named/server.h> 53 #include <named/zoneconf.h> 54 55 /* ACLs associated with zone */ 56 typedef enum { 57 allow_notify, 58 allow_query, 59 allow_query_on, 60 allow_transfer, 61 allow_update, 62 allow_update_forwarding 63 } acl_type_t; 64 65 #define RETERR(x) do { \ 66 isc_result_t _r = (x); \ 67 if (_r != ISC_R_SUCCESS) \ 68 return (_r); \ 69 } while (/*CONSTCOND*/0) 70 71 #define CHECK(x) do { \ 72 result = (x); \ 73 if (result != ISC_R_SUCCESS) \ 74 goto cleanup; \ 75 } while (/*CONSTCOND*/0) 76 77 /*% 78 * Convenience function for configuring a single zone ACL. 79 */ 80 static isc_result_t 81 configure_zone_acl(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig, 82 const cfg_obj_t *config, acl_type_t acltype, 83 cfg_aclconfctx_t *actx, dns_zone_t *zone, 84 void (*setzacl)(dns_zone_t *, dns_acl_t *), 85 void (*clearzacl)(dns_zone_t *)) 86 { 87 isc_result_t result; 88 const cfg_obj_t *maps[5] = {NULL, NULL, NULL, NULL, NULL}; 89 const cfg_obj_t *aclobj = NULL; 90 int i = 0; 91 dns_acl_t **aclp = NULL, *acl = NULL; 92 const char *aclname; 93 dns_view_t *view; 94 95 view = dns_zone_getview(zone); 96 97 switch (acltype) { 98 case allow_notify: 99 if (view != NULL) 100 aclp = &view->notifyacl; 101 aclname = "allow-notify"; 102 break; 103 case allow_query: 104 if (view != NULL) 105 aclp = &view->queryacl; 106 aclname = "allow-query"; 107 break; 108 case allow_query_on: 109 if (view != NULL) 110 aclp = &view->queryonacl; 111 aclname = "allow-query-on"; 112 break; 113 case allow_transfer: 114 if (view != NULL) 115 aclp = &view->transferacl; 116 aclname = "allow-transfer"; 117 break; 118 case allow_update: 119 if (view != NULL) 120 aclp = &view->updateacl; 121 aclname = "allow-update"; 122 break; 123 case allow_update_forwarding: 124 if (view != NULL) 125 aclp = &view->upfwdacl; 126 aclname = "allow-update-forwarding"; 127 break; 128 default: 129 INSIST(0); 130 ISC_UNREACHABLE(); 131 } 132 133 /* First check to see if ACL is defined within the zone */ 134 if (zconfig != NULL) { 135 maps[0] = cfg_tuple_get(zconfig, "options"); 136 (void)named_config_get(maps, aclname, &aclobj); 137 if (aclobj != NULL) { 138 aclp = NULL; 139 goto parse_acl; 140 } 141 } 142 143 /* Failing that, see if there's a default ACL already in the view */ 144 if (aclp != NULL && *aclp != NULL) { 145 (*setzacl)(zone, *aclp); 146 return (ISC_R_SUCCESS); 147 } 148 149 /* Check for default ACLs that haven't been parsed yet */ 150 if (vconfig != NULL) { 151 const cfg_obj_t *options = cfg_tuple_get(vconfig, "options"); 152 if (options != NULL) 153 maps[i++] = options; 154 } 155 if (config != NULL) { 156 const cfg_obj_t *options = NULL; 157 (void)cfg_map_get(config, "options", &options); 158 if (options != NULL) 159 maps[i++] = options; 160 } 161 maps[i++] = named_g_defaults; 162 maps[i] = NULL; 163 164 (void)named_config_get(maps, aclname, &aclobj); 165 if (aclobj == NULL) { 166 (*clearzacl)(zone); 167 return (ISC_R_SUCCESS); 168 } 169 170 parse_acl: 171 result = cfg_acl_fromconfig(aclobj, config, named_g_lctx, actx, 172 dns_zone_getmctx(zone), 0, &acl); 173 if (result != ISC_R_SUCCESS) 174 return (result); 175 (*setzacl)(zone, acl); 176 177 /* Set the view default now */ 178 if (aclp != NULL) 179 dns_acl_attach(acl, aclp); 180 181 dns_acl_detach(&acl); 182 return (ISC_R_SUCCESS); 183 } 184 185 /*% 186 * Parse the zone update-policy statement. 187 */ 188 static isc_result_t 189 configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone, 190 const char *zname) 191 { 192 const cfg_obj_t *updatepolicy = NULL; 193 const cfg_listelt_t *element, *element2; 194 dns_ssutable_t *table = NULL; 195 isc_mem_t *mctx = dns_zone_getmctx(zone); 196 bool autoddns = false; 197 isc_result_t result; 198 199 (void)cfg_map_get(zconfig, "update-policy", &updatepolicy); 200 201 if (updatepolicy == NULL) { 202 dns_zone_setssutable(zone, NULL); 203 return (ISC_R_SUCCESS); 204 } 205 206 if (cfg_obj_isstring(updatepolicy) && 207 strcmp("local", cfg_obj_asstring(updatepolicy)) == 0) { 208 autoddns = true; 209 updatepolicy = NULL; 210 } 211 212 result = dns_ssutable_create(mctx, &table); 213 if (result != ISC_R_SUCCESS) 214 return (result); 215 216 for (element = cfg_list_first(updatepolicy); 217 element != NULL; 218 element = cfg_list_next(element)) 219 { 220 const cfg_obj_t *stmt = cfg_listelt_value(element); 221 const cfg_obj_t *mode = cfg_tuple_get(stmt, "mode"); 222 const cfg_obj_t *identity = cfg_tuple_get(stmt, "identity"); 223 const cfg_obj_t *matchtype = cfg_tuple_get(stmt, "matchtype"); 224 const cfg_obj_t *dname = cfg_tuple_get(stmt, "name"); 225 const cfg_obj_t *typelist = cfg_tuple_get(stmt, "types"); 226 const char *str; 227 bool grant = false; 228 bool usezone = false; 229 dns_ssumatchtype_t mtype = dns_ssumatchtype_name; 230 dns_fixedname_t fname, fident; 231 isc_buffer_t b; 232 dns_rdatatype_t *types; 233 unsigned int i, n; 234 235 str = cfg_obj_asstring(mode); 236 if (strcasecmp(str, "grant") == 0) { 237 grant = true; 238 } else if (strcasecmp(str, "deny") == 0) { 239 grant = false; 240 } else { 241 INSIST(0); 242 ISC_UNREACHABLE(); 243 } 244 245 str = cfg_obj_asstring(matchtype); 246 CHECK(dns_ssu_mtypefromstring(str, &mtype)); 247 if (mtype == dns_ssumatchtype_subdomain) { 248 usezone = true; 249 } 250 251 dns_fixedname_init(&fident); 252 str = cfg_obj_asstring(identity); 253 isc_buffer_constinit(&b, str, strlen(str)); 254 isc_buffer_add(&b, strlen(str)); 255 result = dns_name_fromtext(dns_fixedname_name(&fident), &b, 256 dns_rootname, 0, NULL); 257 if (result != ISC_R_SUCCESS) { 258 cfg_obj_log(identity, named_g_lctx, ISC_LOG_ERROR, 259 "'%s' is not a valid name", str); 260 goto cleanup; 261 } 262 263 dns_fixedname_init(&fname); 264 if (usezone) { 265 dns_name_copynf(dns_zone_getorigin(zone), 266 dns_fixedname_name(&fname)); 267 } else { 268 str = cfg_obj_asstring(dname); 269 isc_buffer_constinit(&b, str, strlen(str)); 270 isc_buffer_add(&b, strlen(str)); 271 result = dns_name_fromtext(dns_fixedname_name(&fname), 272 &b, dns_rootname, 0, NULL); 273 if (result != ISC_R_SUCCESS) { 274 cfg_obj_log(identity, named_g_lctx, 275 ISC_LOG_ERROR, 276 "'%s' is not a valid name", str); 277 goto cleanup; 278 } 279 } 280 281 n = named_config_listcount(typelist); 282 if (n == 0) 283 types = NULL; 284 else { 285 types = isc_mem_get(mctx, n * sizeof(dns_rdatatype_t)); 286 if (types == NULL) { 287 result = ISC_R_NOMEMORY; 288 goto cleanup; 289 } 290 } 291 292 i = 0; 293 for (element2 = cfg_list_first(typelist); 294 element2 != NULL; 295 element2 = cfg_list_next(element2)) 296 { 297 const cfg_obj_t *typeobj; 298 isc_textregion_t r; 299 300 INSIST(i < n); 301 302 typeobj = cfg_listelt_value(element2); 303 str = cfg_obj_asstring(typeobj); 304 DE_CONST(str, r.base); 305 r.length = strlen(str); 306 307 result = dns_rdatatype_fromtext(&types[i++], &r); 308 if (result != ISC_R_SUCCESS) { 309 cfg_obj_log(identity, named_g_lctx, 310 ISC_LOG_ERROR, 311 "'%s' is not a valid type", str); 312 isc_mem_put(mctx, types, 313 n * sizeof(dns_rdatatype_t)); 314 goto cleanup; 315 } 316 } 317 INSIST(i == n); 318 319 result = dns_ssutable_addrule(table, grant, 320 dns_fixedname_name(&fident), 321 mtype, 322 dns_fixedname_name(&fname), 323 n, types); 324 if (types != NULL) 325 isc_mem_put(mctx, types, n * sizeof(dns_rdatatype_t)); 326 if (result != ISC_R_SUCCESS) { 327 goto cleanup; 328 } 329 } 330 331 /* 332 * If "update-policy local;" and a session key exists, 333 * then use the default policy, which is equivalent to: 334 * update-policy { grant <session-keyname> zonesub any; }; 335 */ 336 if (autoddns) { 337 dns_rdatatype_t any = dns_rdatatype_any; 338 339 if (named_g_server->session_keyname == NULL) { 340 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, 341 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, 342 "failed to enable auto DDNS policy " 343 "for zone %s: session key not found", 344 zname); 345 result = ISC_R_NOTFOUND; 346 goto cleanup; 347 } 348 349 result = dns_ssutable_addrule(table, true, 350 named_g_server->session_keyname, 351 dns_ssumatchtype_local, 352 dns_zone_getorigin(zone), 353 1, &any); 354 355 if (result != ISC_R_SUCCESS) 356 goto cleanup; 357 } 358 359 result = ISC_R_SUCCESS; 360 dns_zone_setssutable(zone, table); 361 362 cleanup: 363 dns_ssutable_detach(&table); 364 return (result); 365 } 366 367 /* 368 * This is the TTL used for internally generated RRsets for static-stub zones. 369 * The value doesn't matter because the mapping is static, but needs to be 370 * defined for the sake of implementation. 371 */ 372 #define STATICSTUB_SERVER_TTL 86400 373 374 /*% 375 * Configure an apex NS with glues for a static-stub zone. 376 * For example, for the zone named "example.com", the following RRs will be 377 * added to the zone DB: 378 * example.com. NS example.com. 379 * example.com. A 192.0.2.1 380 * example.com. AAAA 2001:db8::1 381 */ 382 static isc_result_t 383 configure_staticstub_serveraddrs(const cfg_obj_t *zconfig, dns_zone_t *zone, 384 dns_rdatalist_t *rdatalist_ns, 385 dns_rdatalist_t *rdatalist_a, 386 dns_rdatalist_t *rdatalist_aaaa) 387 { 388 const cfg_listelt_t *element; 389 isc_mem_t *mctx = dns_zone_getmctx(zone); 390 isc_region_t region, sregion; 391 dns_rdata_t *rdata; 392 isc_result_t result = ISC_R_SUCCESS; 393 394 for (element = cfg_list_first(zconfig); 395 element != NULL; 396 element = cfg_list_next(element)) 397 { 398 const isc_sockaddr_t* sa; 399 isc_netaddr_t na; 400 const cfg_obj_t *address = cfg_listelt_value(element); 401 dns_rdatalist_t *rdatalist; 402 403 sa = cfg_obj_assockaddr(address); 404 if (isc_sockaddr_getport(sa) != 0) { 405 cfg_obj_log(zconfig, named_g_lctx, ISC_LOG_ERROR, 406 "port is not configurable for " 407 "static stub server-addresses"); 408 return (ISC_R_FAILURE); 409 } 410 isc_netaddr_fromsockaddr(&na, sa); 411 if (isc_netaddr_getzone(&na) != 0) { 412 cfg_obj_log(zconfig, named_g_lctx, ISC_LOG_ERROR, 413 "scoped address is not allowed " 414 "for static stub " 415 "server-addresses"); 416 return (ISC_R_FAILURE); 417 } 418 419 switch (na.family) { 420 case AF_INET: 421 region.length = sizeof(na.type.in); 422 rdatalist = rdatalist_a; 423 break; 424 default: 425 INSIST(na.family == AF_INET6); 426 region.length = sizeof(na.type.in6); 427 rdatalist = rdatalist_aaaa; 428 break; 429 } 430 431 rdata = isc_mem_get(mctx, sizeof(*rdata) + region.length); 432 if (rdata == NULL) 433 return (ISC_R_NOMEMORY); 434 region.base = (unsigned char *)(rdata + 1); 435 memmove(region.base, &na.type, region.length); 436 dns_rdata_init(rdata); 437 dns_rdata_fromregion(rdata, dns_zone_getclass(zone), 438 rdatalist->type, ®ion); 439 ISC_LIST_APPEND(rdatalist->rdata, rdata, link); 440 } 441 442 /* 443 * If no address is specified (unlikely in this context, but possible), 444 * there's nothing to do anymore. 445 */ 446 if (ISC_LIST_EMPTY(rdatalist_a->rdata) && 447 ISC_LIST_EMPTY(rdatalist_aaaa->rdata)) { 448 return (ISC_R_SUCCESS); 449 } 450 451 /* Add to the list an apex NS with the ns name being the origin name */ 452 dns_name_toregion(dns_zone_getorigin(zone), &sregion); 453 rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length); 454 if (rdata == NULL) { 455 /* 456 * Already allocated data will be freed in the caller, so 457 * we can simply return here. 458 */ 459 return (ISC_R_NOMEMORY); 460 } 461 region.length = sregion.length; 462 region.base = (unsigned char *)(rdata + 1); 463 memmove(region.base, sregion.base, region.length); 464 dns_rdata_init(rdata); 465 dns_rdata_fromregion(rdata, dns_zone_getclass(zone), 466 dns_rdatatype_ns, ®ion); 467 ISC_LIST_APPEND(rdatalist_ns->rdata, rdata, link); 468 469 return (result); 470 } 471 472 /*% 473 * Configure an apex NS with an out-of-zone NS names for a static-stub zone. 474 * For example, for the zone named "example.com", something like the following 475 * RRs will be added to the zone DB: 476 * example.com. NS ns.example.net. 477 */ 478 static isc_result_t 479 configure_staticstub_servernames(const cfg_obj_t *zconfig, dns_zone_t *zone, 480 dns_rdatalist_t *rdatalist, const char *zname) 481 { 482 const cfg_listelt_t *element; 483 isc_mem_t *mctx = dns_zone_getmctx(zone); 484 dns_rdata_t *rdata; 485 isc_region_t sregion, region; 486 isc_result_t result = ISC_R_SUCCESS; 487 488 for (element = cfg_list_first(zconfig); 489 element != NULL; 490 element = cfg_list_next(element)) 491 { 492 const cfg_obj_t *obj; 493 const char *str; 494 dns_fixedname_t fixed_name; 495 dns_name_t *nsname; 496 isc_buffer_t b; 497 498 obj = cfg_listelt_value(element); 499 str = cfg_obj_asstring(obj); 500 501 nsname = dns_fixedname_initname(&fixed_name); 502 503 isc_buffer_constinit(&b, str, strlen(str)); 504 isc_buffer_add(&b, strlen(str)); 505 result = dns_name_fromtext(nsname, &b, dns_rootname, 0, NULL); 506 if (result != ISC_R_SUCCESS) { 507 cfg_obj_log(zconfig, named_g_lctx, ISC_LOG_ERROR, 508 "server-name '%s' is not a valid " 509 "name", str); 510 return (result); 511 } 512 if (dns_name_issubdomain(nsname, dns_zone_getorigin(zone))) { 513 cfg_obj_log(zconfig, named_g_lctx, ISC_LOG_ERROR, 514 "server-name '%s' must not be a " 515 "subdomain of zone name '%s'", 516 str, zname); 517 return (ISC_R_FAILURE); 518 } 519 520 dns_name_toregion(nsname, &sregion); 521 rdata = isc_mem_get(mctx, sizeof(*rdata) + sregion.length); 522 if (rdata == NULL) 523 return (ISC_R_NOMEMORY); 524 region.length = sregion.length; 525 region.base = (unsigned char *)(rdata + 1); 526 memmove(region.base, sregion.base, region.length); 527 dns_rdata_init(rdata); 528 dns_rdata_fromregion(rdata, dns_zone_getclass(zone), 529 dns_rdatatype_ns, ®ion); 530 ISC_LIST_APPEND(rdatalist->rdata, rdata, link); 531 } 532 533 return (result); 534 } 535 536 /*% 537 * Configure static-stub zone. 538 */ 539 static isc_result_t 540 configure_staticstub(const cfg_obj_t *zconfig, dns_zone_t *zone, 541 const char *zname, const char *dbtype) 542 { 543 int i = 0; 544 const cfg_obj_t *obj; 545 isc_mem_t *mctx = dns_zone_getmctx(zone); 546 dns_db_t *db = NULL; 547 dns_dbversion_t *dbversion = NULL; 548 dns_dbnode_t *apexnode = NULL; 549 dns_name_t apexname; 550 isc_result_t result; 551 dns_rdataset_t rdataset; 552 dns_rdatalist_t rdatalist_ns, rdatalist_a, rdatalist_aaaa; 553 dns_rdatalist_t* rdatalists[] = { 554 &rdatalist_ns, &rdatalist_a, &rdatalist_aaaa, NULL 555 }; 556 dns_rdata_t *rdata; 557 isc_region_t region; 558 559 /* Create the DB beforehand */ 560 RETERR(dns_db_create(mctx, dbtype, dns_zone_getorigin(zone), 561 dns_dbtype_stub, dns_zone_getclass(zone), 562 0, NULL, &db)); 563 564 dns_rdataset_init(&rdataset); 565 566 dns_rdatalist_init(&rdatalist_ns); 567 rdatalist_ns.rdclass = dns_zone_getclass(zone); 568 rdatalist_ns.type = dns_rdatatype_ns; 569 rdatalist_ns.ttl = STATICSTUB_SERVER_TTL; 570 571 dns_rdatalist_init(&rdatalist_a); 572 rdatalist_a.rdclass = dns_zone_getclass(zone); 573 rdatalist_a.type = dns_rdatatype_a; 574 rdatalist_a.ttl = STATICSTUB_SERVER_TTL; 575 576 dns_rdatalist_init(&rdatalist_aaaa); 577 rdatalist_aaaa.rdclass = dns_zone_getclass(zone); 578 rdatalist_aaaa.type = dns_rdatatype_aaaa; 579 rdatalist_aaaa.ttl = STATICSTUB_SERVER_TTL; 580 581 /* Prepare zone RRs from the configuration */ 582 obj = NULL; 583 result = cfg_map_get(zconfig, "server-addresses", &obj); 584 if (result == ISC_R_SUCCESS) { 585 INSIST(obj != NULL); 586 CHECK(configure_staticstub_serveraddrs(obj, zone, 587 &rdatalist_ns, 588 &rdatalist_a, 589 &rdatalist_aaaa)); 590 } 591 592 obj = NULL; 593 result = cfg_map_get(zconfig, "server-names", &obj); 594 if (result == ISC_R_SUCCESS) { 595 INSIST(obj != NULL); 596 CHECK(configure_staticstub_servernames(obj, zone, 597 &rdatalist_ns, 598 zname)); 599 } 600 601 /* 602 * Sanity check: there should be at least one NS RR at the zone apex 603 * to trigger delegation. 604 */ 605 if (ISC_LIST_EMPTY(rdatalist_ns.rdata)) { 606 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, 607 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, 608 "No NS record is configured for a " 609 "static-stub zone '%s'", zname); 610 result = ISC_R_FAILURE; 611 goto cleanup; 612 } 613 614 /* 615 * Now add NS and glue A/AAAA RRsets to the zone DB. 616 * First open a new version for the add operation and get a pointer 617 * to the apex node (all RRs are of the apex name). 618 */ 619 CHECK(dns_db_newversion(db, &dbversion)); 620 621 dns_name_init(&apexname, NULL); 622 dns_name_clone(dns_zone_getorigin(zone), &apexname); 623 CHECK(dns_db_findnode(db, &apexname, false, &apexnode)); 624 625 /* Add NS RRset */ 626 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_ns, &rdataset) 627 == ISC_R_SUCCESS); 628 CHECK(dns_db_addrdataset(db, apexnode, dbversion, 0, &rdataset, 629 0, NULL)); 630 dns_rdataset_disassociate(&rdataset); 631 632 /* Add glue A RRset, if any */ 633 if (!ISC_LIST_EMPTY(rdatalist_a.rdata)) { 634 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_a, &rdataset) 635 == ISC_R_SUCCESS); 636 CHECK(dns_db_addrdataset(db, apexnode, dbversion, 0, 637 &rdataset, 0, NULL)); 638 dns_rdataset_disassociate(&rdataset); 639 } 640 641 /* Add glue AAAA RRset, if any */ 642 if (!ISC_LIST_EMPTY(rdatalist_aaaa.rdata)) { 643 RUNTIME_CHECK(dns_rdatalist_tordataset(&rdatalist_aaaa, 644 &rdataset) 645 == ISC_R_SUCCESS); 646 CHECK(dns_db_addrdataset(db, apexnode, dbversion, 0, 647 &rdataset, 0, NULL)); 648 dns_rdataset_disassociate(&rdataset); 649 } 650 651 dns_db_closeversion(db, &dbversion, true); 652 dns_zone_setdb(zone, db); 653 654 result = ISC_R_SUCCESS; 655 656 cleanup: 657 if (dns_rdataset_isassociated(&rdataset)) { 658 dns_rdataset_disassociate(&rdataset); 659 } 660 if (apexnode != NULL) { 661 dns_db_detachnode(db, &apexnode); 662 } 663 if (dbversion != NULL) { 664 dns_db_closeversion(db, &dbversion, false); 665 } 666 if (db != NULL) { 667 dns_db_detach(&db); 668 } 669 for (i = 0; rdatalists[i] != NULL; i++) { 670 while ((rdata = ISC_LIST_HEAD(rdatalists[i]->rdata)) != NULL) { 671 ISC_LIST_UNLINK(rdatalists[i]->rdata, rdata, link); 672 dns_rdata_toregion(rdata, ®ion); 673 isc_mem_put(mctx, rdata, 674 sizeof(*rdata) + region.length); 675 } 676 } 677 678 INSIST(dbversion == NULL); 679 680 return (result); 681 } 682 683 /*% 684 * Convert a config file zone type into a server zone type. 685 */ 686 static inline dns_zonetype_t 687 zonetype_fromconfig(const cfg_obj_t *map) { 688 const cfg_obj_t *obj = NULL; 689 isc_result_t result; 690 691 result = cfg_map_get(map, "type", &obj); 692 INSIST(result == ISC_R_SUCCESS && obj != NULL); 693 return (named_config_getzonetype(obj)); 694 } 695 696 /*% 697 * Helper function for strtoargv(). Pardon the gratuitous recursion. 698 */ 699 static isc_result_t 700 strtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp, 701 char ***argvp, unsigned int n) 702 { 703 isc_result_t result; 704 705 /* Discard leading whitespace. */ 706 while (*s == ' ' || *s == '\t') 707 s++; 708 709 if (*s == '\0') { 710 /* We have reached the end of the string. */ 711 *argcp = n; 712 *argvp = isc_mem_get(mctx, n * sizeof(char *)); 713 if (*argvp == NULL) 714 return (ISC_R_NOMEMORY); 715 } else { 716 char *p = s; 717 while (*p != ' ' && *p != '\t' && *p != '\0') 718 p++; 719 if (*p != '\0') 720 *p++ = '\0'; 721 722 result = strtoargvsub(mctx, p, argcp, argvp, n + 1); 723 if (result != ISC_R_SUCCESS) 724 return (result); 725 (*argvp)[n] = s; 726 } 727 return (ISC_R_SUCCESS); 728 } 729 730 /*% 731 * Tokenize the string "s" into whitespace-separated words, 732 * return the number of words in '*argcp' and an array 733 * of pointers to the words in '*argvp'. The caller 734 * must free the array using isc_mem_put(). The string 735 * is modified in-place. 736 */ 737 static isc_result_t 738 strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp) { 739 return (strtoargvsub(mctx, s, argcp, argvp, 0)); 740 } 741 742 static void 743 checknames(dns_zonetype_t ztype, const cfg_obj_t **maps, 744 const cfg_obj_t **objp) 745 { 746 const char *zone = NULL; 747 isc_result_t result; 748 749 switch (ztype) { 750 case dns_zone_slave: 751 case dns_zone_mirror: 752 zone = "slave"; 753 break; 754 case dns_zone_master: 755 zone = "master"; 756 break; 757 default: 758 INSIST(0); 759 ISC_UNREACHABLE(); 760 } 761 result = named_checknames_get(maps, zone, objp); 762 INSIST(result == ISC_R_SUCCESS && objp != NULL && *objp != NULL); 763 } 764 765 /* 766 * Callback to see if a non-recursive query coming from 'srcaddr' to 767 * 'destaddr', with optional key 'mykey' for class 'rdclass' would be 768 * delivered to 'myview'. 769 * 770 * We run this unlocked as both the view list and the interface list 771 * are updated when the appropriate task has exclusivity. 772 */ 773 static bool 774 isself(dns_view_t *myview, dns_tsigkey_t *mykey, 775 const isc_sockaddr_t *srcaddr, const isc_sockaddr_t *dstaddr, 776 dns_rdataclass_t rdclass, void *arg) 777 { 778 ns_interfacemgr_t *interfacemgr = (ns_interfacemgr_t *) arg; 779 dns_aclenv_t *env = ns_interfacemgr_getaclenv(interfacemgr); 780 dns_view_t *view; 781 dns_tsigkey_t *key = NULL; 782 isc_netaddr_t netsrc; 783 isc_netaddr_t netdst; 784 785 if (interfacemgr == NULL) 786 return (true); 787 788 if (!ns_interfacemgr_listeningon(interfacemgr, dstaddr)) 789 return (false); 790 791 isc_netaddr_fromsockaddr(&netsrc, srcaddr); 792 isc_netaddr_fromsockaddr(&netdst, dstaddr); 793 794 for (view = ISC_LIST_HEAD(named_g_server->viewlist); 795 view != NULL; 796 view = ISC_LIST_NEXT(view, link)) 797 { 798 const dns_name_t *tsig = NULL; 799 800 if (view->matchrecursiveonly) 801 continue; 802 803 if (rdclass != view->rdclass) 804 continue; 805 806 if (mykey != NULL) { 807 bool match; 808 isc_result_t result; 809 810 result = dns_view_gettsig(view, &mykey->name, &key); 811 if (result != ISC_R_SUCCESS) 812 continue; 813 match = dst_key_compare(mykey->key, key->key); 814 dns_tsigkey_detach(&key); 815 if (!match) 816 continue; 817 tsig = dns_tsigkey_identity(mykey); 818 } 819 820 if (dns_acl_allowed(&netsrc, tsig, view->matchclients, env) && 821 dns_acl_allowed(&netdst, tsig, view->matchdestinations, 822 env)) 823 { 824 break; 825 } 826 } 827 return (view == myview); 828 } 829 830 /*% 831 * For mirror zones, change "notify yes;" to "notify explicit;", informing the 832 * user only if "notify" was explicitly configured rather than inherited from 833 * default configuration. 834 */ 835 static dns_notifytype_t 836 process_notifytype(dns_notifytype_t ntype, dns_zonetype_t ztype, 837 const char *zname, const cfg_obj_t **maps) 838 { 839 const cfg_obj_t *obj = NULL; 840 841 /* 842 * Return the original setting if this is not a mirror zone or if the 843 * zone is configured with something else than "notify yes;". 844 */ 845 if (ztype != dns_zone_mirror || ntype != dns_notifytype_yes) { 846 return (ntype); 847 } 848 849 /* 850 * Only log a message if "notify" was set in the configuration 851 * hierarchy supplied in 'maps'. 852 */ 853 if (named_config_get(maps, "notify", &obj) == ISC_R_SUCCESS) { 854 cfg_obj_log(obj, named_g_lctx, ISC_LOG_INFO, 855 "'notify explicit;' will be used for mirror zone " 856 "'%s'", zname); 857 } 858 859 return (dns_notifytype_explicit); 860 } 861 862 isc_result_t 863 named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, 864 const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac, 865 dns_zone_t *zone, dns_zone_t *raw) 866 { 867 isc_result_t result; 868 const char *zname; 869 dns_rdataclass_t zclass; 870 dns_rdataclass_t vclass; 871 const cfg_obj_t *maps[5]; 872 const cfg_obj_t *nodefault[4]; 873 const cfg_obj_t *zoptions = NULL; 874 const cfg_obj_t *options = NULL; 875 const cfg_obj_t *obj; 876 const char *filename = NULL; 877 const char *dupcheck; 878 dns_notifytype_t notifytype = dns_notifytype_yes; 879 uint32_t count; 880 unsigned int dbargc; 881 char **dbargv; 882 static char default_dbtype[] = "rbt"; 883 static char dlz_dbtype[] = "dlz"; 884 char *cpval = default_dbtype; 885 isc_mem_t *mctx = dns_zone_getmctx(zone); 886 dns_dialuptype_t dialup = dns_dialuptype_no; 887 dns_zonetype_t ztype; 888 int i; 889 int32_t journal_size; 890 bool multi; 891 bool alt; 892 dns_view_t *view; 893 bool check = false, fail = false; 894 bool warn = false, ignore = false; 895 bool ixfrdiff; 896 dns_masterformat_t masterformat; 897 const dns_master_style_t *masterstyle = &dns_master_style_default; 898 isc_stats_t *zoneqrystats; 899 dns_stats_t *rcvquerystats; 900 dns_stats_t *dnssecsignstats; 901 dns_stats_t *dnssecrefreshstats; 902 dns_zonestat_level_t statlevel = dns_zonestat_none; 903 int seconds; 904 dns_zone_t *mayberaw = (raw != NULL) ? raw : zone; 905 isc_dscp_t dscp; 906 907 i = 0; 908 if (zconfig != NULL) { 909 zoptions = cfg_tuple_get(zconfig, "options"); 910 nodefault[i] = maps[i] = zoptions; 911 i++; 912 } 913 if (vconfig != NULL) { 914 nodefault[i] = maps[i] = cfg_tuple_get(vconfig, "options"); 915 i++; 916 } 917 if (config != NULL) { 918 (void)cfg_map_get(config, "options", &options); 919 if (options != NULL) { 920 nodefault[i] = maps[i] = options; 921 i++; 922 } 923 } 924 nodefault[i] = NULL; 925 maps[i++] = named_g_defaults; 926 maps[i] = NULL; 927 928 if (vconfig != NULL) 929 RETERR(named_config_getclass(cfg_tuple_get(vconfig, "class"), 930 dns_rdataclass_in, &vclass)); 931 else 932 vclass = dns_rdataclass_in; 933 934 /* 935 * Configure values common to all zone types. 936 */ 937 938 zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); 939 940 RETERR(named_config_getclass(cfg_tuple_get(zconfig, "class"), 941 vclass, &zclass)); 942 dns_zone_setclass(zone, zclass); 943 if (raw != NULL) 944 dns_zone_setclass(raw, zclass); 945 946 ztype = zonetype_fromconfig(zoptions); 947 if (raw != NULL) { 948 dns_zone_settype(raw, ztype); 949 dns_zone_settype(zone, dns_zone_master); 950 } else 951 dns_zone_settype(zone, ztype); 952 953 obj = NULL; 954 result = cfg_map_get(zoptions, "database", &obj); 955 if (result == ISC_R_SUCCESS) 956 cpval = isc_mem_strdup(mctx, cfg_obj_asstring(obj)); 957 if (cpval == NULL) 958 return(ISC_R_NOMEMORY); 959 960 obj = NULL; 961 result = cfg_map_get(zoptions, "dlz", &obj); 962 if (result == ISC_R_SUCCESS) { 963 const char *dlzname = cfg_obj_asstring(obj); 964 size_t len; 965 966 if (cpval != default_dbtype) { 967 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, 968 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, 969 "zone '%s': both 'database' and 'dlz' " 970 "specified", zname); 971 return (ISC_R_FAILURE); 972 } 973 974 len = strlen(dlzname) + 5; 975 cpval = isc_mem_allocate(mctx, len); 976 if (cpval == NULL) 977 return (ISC_R_NOMEMORY); 978 snprintf(cpval, len, "dlz %s", dlzname); 979 } 980 981 result = strtoargv(mctx, cpval, &dbargc, &dbargv); 982 if (result != ISC_R_SUCCESS && cpval != default_dbtype) { 983 isc_mem_free(mctx, cpval); 984 return (result); 985 } 986 987 /* 988 * ANSI C is strange here. There is no logical reason why (char **) 989 * cannot be promoted automatically to (const char * const *) by the 990 * compiler w/o generating a warning. 991 */ 992 result = dns_zone_setdbtype(zone, dbargc, (const char * const *)dbargv); 993 isc_mem_put(mctx, dbargv, dbargc * sizeof(*dbargv)); 994 if (cpval != default_dbtype && cpval != dlz_dbtype) 995 isc_mem_free(mctx, cpval); 996 if (result != ISC_R_SUCCESS) 997 return (result); 998 999 obj = NULL; 1000 result = cfg_map_get(zoptions, "file", &obj); 1001 if (result == ISC_R_SUCCESS) 1002 filename = cfg_obj_asstring(obj); 1003 1004 /* 1005 * Unless we're using some alternative database, a master zone 1006 * will be needing a master file. 1007 */ 1008 if (ztype == dns_zone_master && cpval == default_dbtype && 1009 filename == NULL) { 1010 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, 1011 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, 1012 "zone '%s': 'file' not specified", 1013 zname); 1014 return (ISC_R_FAILURE); 1015 } 1016 1017 if (ztype == dns_zone_slave || ztype == dns_zone_mirror) 1018 masterformat = dns_masterformat_raw; 1019 else 1020 masterformat = dns_masterformat_text; 1021 obj = NULL; 1022 result = named_config_get(maps, "masterfile-format", &obj); 1023 if (result == ISC_R_SUCCESS) { 1024 const char *masterformatstr = cfg_obj_asstring(obj); 1025 1026 if (strcasecmp(masterformatstr, "text") == 0) { 1027 masterformat = dns_masterformat_text; 1028 } else if (strcasecmp(masterformatstr, "raw") == 0) { 1029 masterformat = dns_masterformat_raw; 1030 } else if (strcasecmp(masterformatstr, "map") == 0) { 1031 masterformat = dns_masterformat_map; 1032 } else { 1033 INSIST(0); 1034 ISC_UNREACHABLE(); 1035 } 1036 } 1037 1038 obj = NULL; 1039 result = named_config_get(maps, "masterfile-style", &obj); 1040 if (result == ISC_R_SUCCESS) { 1041 const char *masterstylestr = cfg_obj_asstring(obj); 1042 1043 if (masterformat != dns_masterformat_text) { 1044 cfg_obj_log(obj, named_g_lctx, ISC_LOG_ERROR, 1045 "zone '%s': 'masterfile-style' " 1046 "can only be used with " 1047 "'masterfile-format text'", zname); 1048 return (ISC_R_FAILURE); 1049 } 1050 1051 if (strcasecmp(masterstylestr, "full") == 0) { 1052 masterstyle = &dns_master_style_full; 1053 } else if (strcasecmp(masterstylestr, "relative") == 0) { 1054 masterstyle = &dns_master_style_default; 1055 } else { 1056 INSIST(0); 1057 ISC_UNREACHABLE(); 1058 } 1059 } 1060 1061 obj = NULL; 1062 result = named_config_get(maps, "max-zone-ttl", &obj); 1063 if (result == ISC_R_SUCCESS && masterformat == dns_masterformat_map) { 1064 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, 1065 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, 1066 "zone '%s': 'max-zone-ttl' is not compatible " 1067 "with 'masterfile-format map'", zname); 1068 return (ISC_R_FAILURE); 1069 } else if (result == ISC_R_SUCCESS) { 1070 dns_ttl_t maxttl = 0; /* unlimited */ 1071 1072 if (cfg_obj_isuint32(obj)) 1073 maxttl = cfg_obj_asuint32(obj); 1074 dns_zone_setmaxttl(zone, maxttl); 1075 if (raw != NULL) 1076 dns_zone_setmaxttl(raw, maxttl); 1077 } 1078 1079 obj = NULL; 1080 result = named_config_get(maps, "max-records", &obj); 1081 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1082 dns_zone_setmaxrecords(mayberaw, cfg_obj_asuint32(obj)); 1083 if (zone != mayberaw) 1084 dns_zone_setmaxrecords(zone, 0); 1085 1086 if (raw != NULL && filename != NULL) { 1087 #define SIGNED ".signed" 1088 size_t signedlen = strlen(filename) + sizeof(SIGNED); 1089 char *signedname; 1090 1091 RETERR(dns_zone_setfile(raw, filename, 1092 masterformat, masterstyle)); 1093 signedname = isc_mem_get(mctx, signedlen); 1094 if (signedname == NULL) 1095 return (ISC_R_NOMEMORY); 1096 1097 (void)snprintf(signedname, signedlen, "%s" SIGNED, filename); 1098 result = dns_zone_setfile(zone, signedname, 1099 dns_masterformat_raw, NULL); 1100 isc_mem_put(mctx, signedname, signedlen); 1101 if (result != ISC_R_SUCCESS) 1102 return (result); 1103 } else 1104 RETERR(dns_zone_setfile(zone, filename, 1105 masterformat, masterstyle)); 1106 1107 obj = NULL; 1108 result = cfg_map_get(zoptions, "journal", &obj); 1109 if (result == ISC_R_SUCCESS) 1110 RETERR(dns_zone_setjournal(mayberaw, cfg_obj_asstring(obj))); 1111 1112 /* 1113 * Notify messages are processed by the raw zone if it exists. 1114 */ 1115 if (ztype == dns_zone_slave || ztype == dns_zone_mirror) 1116 RETERR(configure_zone_acl(zconfig, vconfig, config, 1117 allow_notify, ac, mayberaw, 1118 dns_zone_setnotifyacl, 1119 dns_zone_clearnotifyacl)); 1120 1121 /* 1122 * XXXAG This probably does not make sense for stubs. 1123 */ 1124 RETERR(configure_zone_acl(zconfig, vconfig, config, 1125 allow_query, ac, zone, 1126 dns_zone_setqueryacl, 1127 dns_zone_clearqueryacl)); 1128 1129 RETERR(configure_zone_acl(zconfig, vconfig, config, 1130 allow_query_on, ac, zone, 1131 dns_zone_setqueryonacl, 1132 dns_zone_clearqueryonacl)); 1133 1134 obj = NULL; 1135 result = named_config_get(maps, "dialup", &obj); 1136 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1137 if (cfg_obj_isboolean(obj)) { 1138 if (cfg_obj_asboolean(obj)) 1139 dialup = dns_dialuptype_yes; 1140 else 1141 dialup = dns_dialuptype_no; 1142 } else { 1143 const char *dialupstr = cfg_obj_asstring(obj); 1144 if (strcasecmp(dialupstr, "notify") == 0) { 1145 dialup = dns_dialuptype_notify; 1146 } else if (strcasecmp(dialupstr, "notify-passive") == 0) { 1147 dialup = dns_dialuptype_notifypassive; 1148 } else if (strcasecmp(dialupstr, "refresh") == 0) { 1149 dialup = dns_dialuptype_refresh; 1150 } else if (strcasecmp(dialupstr, "passive") == 0) { 1151 dialup = dns_dialuptype_passive; 1152 } else { 1153 INSIST(0); 1154 ISC_UNREACHABLE(); 1155 } 1156 } 1157 if (raw != NULL) 1158 dns_zone_setdialup(raw, dialup); 1159 dns_zone_setdialup(zone, dialup); 1160 1161 obj = NULL; 1162 result = named_config_get(maps, "zone-statistics", &obj); 1163 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1164 if (cfg_obj_isboolean(obj)) { 1165 if (cfg_obj_asboolean(obj)) 1166 statlevel = dns_zonestat_full; 1167 else 1168 statlevel = dns_zonestat_none; 1169 } else { 1170 const char *levelstr = cfg_obj_asstring(obj); 1171 if (strcasecmp(levelstr, "full") == 0) { 1172 statlevel = dns_zonestat_full; 1173 } else if (strcasecmp(levelstr, "terse") == 0) { 1174 statlevel = dns_zonestat_terse; 1175 } else if (strcasecmp(levelstr, "none") == 0) { 1176 statlevel = dns_zonestat_none; 1177 } else { 1178 INSIST(0); 1179 ISC_UNREACHABLE(); 1180 } 1181 } 1182 dns_zone_setstatlevel(zone, statlevel); 1183 1184 zoneqrystats = NULL; 1185 rcvquerystats = NULL; 1186 dnssecsignstats = NULL; 1187 dnssecrefreshstats = NULL; 1188 if (statlevel == dns_zonestat_full) { 1189 RETERR(isc_stats_create(mctx, &zoneqrystats, 1190 ns_statscounter_max)); 1191 RETERR(dns_rdatatypestats_create(mctx, &rcvquerystats)); 1192 RETERR(dns_dnssecsignstats_create(mctx, &dnssecsignstats)); 1193 RETERR(dns_dnssecsignstats_create(mctx, &dnssecrefreshstats)); 1194 } 1195 dns_zone_setrequeststats(zone, zoneqrystats); 1196 dns_zone_setrcvquerystats(zone, rcvquerystats); 1197 dns_zone_setdnssecsignstats(zone, dnssecsignstats); 1198 dns_zone_setdnssecrefreshstats(zone, dnssecrefreshstats); 1199 1200 if (zoneqrystats != NULL) 1201 isc_stats_detach(&zoneqrystats); 1202 1203 if(rcvquerystats != NULL) 1204 dns_stats_detach(&rcvquerystats); 1205 1206 if(dnssecsignstats != NULL) { 1207 dns_stats_detach(&dnssecsignstats); 1208 } 1209 1210 if(dnssecrefreshstats != NULL) { 1211 dns_stats_detach(&dnssecrefreshstats); 1212 } 1213 1214 /* 1215 * Configure master functionality. This applies 1216 * to primary masters (type "master") and slaves 1217 * acting as masters (type "slave"), but not to stubs. 1218 */ 1219 if (ztype != dns_zone_stub && ztype != dns_zone_staticstub && 1220 ztype != dns_zone_redirect) { 1221 obj = NULL; 1222 result = named_config_get(maps, "notify", &obj); 1223 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1224 if (cfg_obj_isboolean(obj)) { 1225 if (cfg_obj_asboolean(obj)) 1226 notifytype = dns_notifytype_yes; 1227 else 1228 notifytype = dns_notifytype_no; 1229 } else { 1230 const char *notifystr = cfg_obj_asstring(obj); 1231 if (strcasecmp(notifystr, "explicit") == 0) { 1232 notifytype = dns_notifytype_explicit; 1233 } else if (strcasecmp(notifystr, "master-only") == 0) { 1234 notifytype = dns_notifytype_masteronly; 1235 } else { 1236 INSIST(0); 1237 ISC_UNREACHABLE(); 1238 } 1239 } 1240 notifytype = process_notifytype(notifytype, ztype, zname, 1241 nodefault); 1242 if (raw != NULL) 1243 dns_zone_setnotifytype(raw, dns_notifytype_no); 1244 dns_zone_setnotifytype(zone, notifytype); 1245 1246 obj = NULL; 1247 result = named_config_get(maps, "also-notify", &obj); 1248 if (result == ISC_R_SUCCESS && 1249 (notifytype == dns_notifytype_yes || 1250 notifytype == dns_notifytype_explicit || 1251 (notifytype == dns_notifytype_masteronly && 1252 ztype == dns_zone_master))) 1253 { 1254 dns_ipkeylist_t ipkl; 1255 dns_ipkeylist_init(&ipkl); 1256 1257 RETERR(named_config_getipandkeylist(config, obj, mctx, 1258 &ipkl)); 1259 result = dns_zone_setalsonotifydscpkeys(zone, 1260 ipkl.addrs, 1261 ipkl.dscps, 1262 ipkl.keys, 1263 ipkl.count); 1264 dns_ipkeylist_clear(mctx, &ipkl); 1265 RETERR(result); 1266 } else 1267 RETERR(dns_zone_setalsonotify(zone, NULL, 0)); 1268 1269 obj = NULL; 1270 result = named_config_get(maps, "notify-source", &obj); 1271 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1272 RETERR(dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj))); 1273 dscp = cfg_obj_getdscp(obj); 1274 if (dscp == -1) 1275 dscp = named_g_dscp; 1276 RETERR(dns_zone_setnotifysrc4dscp(zone, dscp)); 1277 named_add_reserved_dispatch(named_g_server, 1278 cfg_obj_assockaddr(obj)); 1279 1280 obj = NULL; 1281 result = named_config_get(maps, "notify-source-v6", &obj); 1282 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1283 RETERR(dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj))); 1284 dscp = cfg_obj_getdscp(obj); 1285 if (dscp == -1) 1286 dscp = named_g_dscp; 1287 RETERR(dns_zone_setnotifysrc6dscp(zone, dscp)); 1288 named_add_reserved_dispatch(named_g_server, 1289 cfg_obj_assockaddr(obj)); 1290 1291 obj = NULL; 1292 result = named_config_get(maps, "notify-to-soa", &obj); 1293 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1294 dns_zone_setoption(zone, DNS_ZONEOPT_NOTIFYTOSOA, 1295 cfg_obj_asboolean(obj)); 1296 1297 dns_zone_setisself(zone, isself, named_g_server->interfacemgr); 1298 1299 RETERR(configure_zone_acl(zconfig, vconfig, config, 1300 allow_transfer, ac, zone, 1301 dns_zone_setxfracl, 1302 dns_zone_clearxfracl)); 1303 1304 obj = NULL; 1305 result = named_config_get(maps, "max-transfer-time-out", &obj); 1306 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1307 dns_zone_setmaxxfrout(zone, cfg_obj_asuint32(obj) * 60); 1308 1309 obj = NULL; 1310 result = named_config_get(maps, "max-transfer-idle-out", &obj); 1311 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1312 dns_zone_setidleout(zone, cfg_obj_asuint32(obj) * 60); 1313 1314 obj = NULL; 1315 result = named_config_get(maps, "max-journal-size", &obj); 1316 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1317 if (raw != NULL) 1318 dns_zone_setjournalsize(raw, -1); 1319 dns_zone_setjournalsize(zone, -1); 1320 if (cfg_obj_isstring(obj)) { 1321 const char *str = cfg_obj_asstring(obj); 1322 if (strcasecmp(str, "unlimited") == 0) { 1323 journal_size = DNS_JOURNAL_SIZE_MAX; 1324 } else { 1325 INSIST(strcasecmp(str, "default") == 0); 1326 journal_size = -1; 1327 } 1328 } else { 1329 isc_resourcevalue_t value; 1330 value = cfg_obj_asuint64(obj); 1331 if (value > DNS_JOURNAL_SIZE_MAX) { 1332 cfg_obj_log(obj, named_g_lctx, 1333 ISC_LOG_ERROR, 1334 "'max-journal-size " 1335 "%" PRId64 "' " 1336 "is too large", 1337 value); 1338 RETERR(ISC_R_RANGE); 1339 } 1340 journal_size = (uint32_t)value; 1341 } 1342 if (raw != NULL) 1343 dns_zone_setjournalsize(raw, journal_size); 1344 dns_zone_setjournalsize(zone, journal_size); 1345 1346 obj = NULL; 1347 result = named_config_get(maps, "ixfr-from-differences", &obj); 1348 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1349 if (cfg_obj_isboolean(obj)) { 1350 ixfrdiff = cfg_obj_asboolean(obj); 1351 } else if ((strcasecmp(cfg_obj_asstring(obj), 1352 "primary") == 0 || 1353 strcasecmp(cfg_obj_asstring(obj), 1354 "master") == 0) && 1355 ztype == dns_zone_master) 1356 { 1357 ixfrdiff = true; 1358 } else if ((strcasecmp(cfg_obj_asstring(obj), 1359 "secondary") == 0 || 1360 strcasecmp(cfg_obj_asstring(obj), 1361 "slave") == 0) && 1362 ztype == dns_zone_slave) 1363 { 1364 ixfrdiff = true; 1365 } else { 1366 ixfrdiff = false; 1367 } 1368 if (raw != NULL) { 1369 dns_zone_setoption(raw, DNS_ZONEOPT_IXFRFROMDIFFS, 1370 true); 1371 dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS, 1372 false); 1373 } else 1374 dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS, 1375 ixfrdiff); 1376 1377 obj = NULL; 1378 result = named_config_get(maps, "request-expire", &obj); 1379 INSIST(result == ISC_R_SUCCESS); 1380 dns_zone_setrequestexpire(zone, cfg_obj_asboolean(obj)); 1381 1382 obj = NULL; 1383 result = named_config_get(maps, "request-ixfr", &obj); 1384 INSIST(result == ISC_R_SUCCESS); 1385 dns_zone_setrequestixfr(zone, cfg_obj_asboolean(obj)); 1386 1387 checknames(ztype, maps, &obj); 1388 INSIST(obj != NULL); 1389 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { 1390 fail = false; 1391 check = true; 1392 } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { 1393 fail = check = true; 1394 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { 1395 fail = check = false; 1396 } else { 1397 INSIST(0); 1398 ISC_UNREACHABLE(); 1399 } 1400 if (raw != NULL) { 1401 dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMES, 1402 check); 1403 dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMESFAIL, 1404 fail); 1405 dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES, 1406 false); 1407 dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL, 1408 false); 1409 } else { 1410 dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES, 1411 check); 1412 dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL, 1413 fail); 1414 } 1415 1416 obj = NULL; 1417 result = named_config_get(maps, "notify-delay", &obj); 1418 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1419 dns_zone_setnotifydelay(zone, cfg_obj_asuint32(obj)); 1420 1421 obj = NULL; 1422 result = named_config_get(maps, "check-sibling", &obj); 1423 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1424 dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSIBLING, 1425 cfg_obj_asboolean(obj)); 1426 1427 obj = NULL; 1428 result = named_config_get(maps, "check-spf", &obj); 1429 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1430 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { 1431 check = true; 1432 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { 1433 check = false; 1434 } else { 1435 INSIST(0); 1436 ISC_UNREACHABLE(); 1437 } 1438 dns_zone_setoption(zone, DNS_ZONEOPT_CHECKSPF, check); 1439 1440 obj = NULL; 1441 result = named_config_get(maps, "zero-no-soa-ttl", &obj); 1442 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1443 dns_zone_setzeronosoattl(zone, cfg_obj_asboolean(obj)); 1444 1445 obj = NULL; 1446 result = named_config_get(maps, "nsec3-test-zone", &obj); 1447 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1448 dns_zone_setoption(zone, DNS_ZONEOPT_NSEC3TESTZONE, 1449 cfg_obj_asboolean(obj)); 1450 } else if (ztype == dns_zone_redirect) { 1451 dns_zone_setnotifytype(zone, dns_notifytype_no); 1452 1453 obj = NULL; 1454 result = named_config_get(maps, "max-journal-size", &obj); 1455 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1456 dns_zone_setjournalsize(zone, -1); 1457 if (cfg_obj_isstring(obj)) { 1458 const char *str = cfg_obj_asstring(obj); 1459 if (strcasecmp(str, "unlimited") == 0) { 1460 journal_size = DNS_JOURNAL_SIZE_MAX; 1461 } else { 1462 INSIST(strcasecmp(str, "default") == 0); 1463 journal_size = -1; 1464 } 1465 } else { 1466 isc_resourcevalue_t value; 1467 value = cfg_obj_asuint64(obj); 1468 if (value > DNS_JOURNAL_SIZE_MAX) { 1469 cfg_obj_log(obj, named_g_lctx, 1470 ISC_LOG_ERROR, 1471 "'max-journal-size " 1472 "%" PRId64 "' " 1473 "is too large", 1474 value); 1475 RETERR(ISC_R_RANGE); 1476 } 1477 journal_size = (uint32_t)value; 1478 } 1479 dns_zone_setjournalsize(zone, journal_size); 1480 } 1481 1482 /* 1483 * Configure update-related options. These apply to 1484 * primary masters only. 1485 */ 1486 if (ztype == dns_zone_master) { 1487 dns_acl_t *updateacl; 1488 1489 RETERR(configure_zone_acl(zconfig, vconfig, config, 1490 allow_update, ac, mayberaw, 1491 dns_zone_setupdateacl, 1492 dns_zone_clearupdateacl)); 1493 1494 updateacl = dns_zone_getupdateacl(mayberaw); 1495 if (updateacl != NULL && dns_acl_isinsecure(updateacl)) 1496 isc_log_write(named_g_lctx, DNS_LOGCATEGORY_SECURITY, 1497 NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING, 1498 "zone '%s' allows unsigned updates " 1499 "from remote hosts, which is insecure", 1500 zname); 1501 1502 RETERR(configure_zone_ssutable(zoptions, mayberaw, zname)); 1503 } 1504 1505 if (ztype == dns_zone_master || raw != NULL) { 1506 const cfg_obj_t *validity, *resign; 1507 bool allow = false, maint = false; 1508 bool sigvalinsecs; 1509 1510 obj = NULL; 1511 result = named_config_get(maps, "dnskey-sig-validity", &obj); 1512 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1513 seconds = cfg_obj_asuint32(obj) * 86400; 1514 dns_zone_setkeyvalidityinterval(zone, seconds); 1515 1516 obj = NULL; 1517 result = named_config_get(maps, "sig-validity-interval", &obj); 1518 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1519 1520 sigvalinsecs = ns_server_getoption(named_g_server->sctx, 1521 NS_SERVER_SIGVALINSECS); 1522 validity = cfg_tuple_get(obj, "validity"); 1523 seconds = cfg_obj_asuint32(validity); 1524 if (!sigvalinsecs) { 1525 seconds *= 86400; 1526 } 1527 dns_zone_setsigvalidityinterval(zone, seconds); 1528 1529 resign = cfg_tuple_get(obj, "re-sign"); 1530 if (cfg_obj_isvoid(resign)) { 1531 seconds /= 4; 1532 } else if (!sigvalinsecs) { 1533 if (seconds > 7 * 86400) { 1534 seconds = cfg_obj_asuint32(resign) * 86400; 1535 } else { 1536 seconds = cfg_obj_asuint32(resign) * 3600; 1537 } 1538 } else { 1539 seconds = cfg_obj_asuint32(resign); 1540 } 1541 dns_zone_setsigresigninginterval(zone, seconds); 1542 1543 obj = NULL; 1544 result = named_config_get(maps, "key-directory", &obj); 1545 if (result == ISC_R_SUCCESS) { 1546 filename = cfg_obj_asstring(obj); 1547 RETERR(dns_zone_setkeydirectory(zone, filename)); 1548 } 1549 1550 obj = NULL; 1551 result = named_config_get(maps, "sig-signing-signatures", &obj); 1552 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1553 dns_zone_setsignatures(zone, cfg_obj_asuint32(obj)); 1554 1555 obj = NULL; 1556 result = named_config_get(maps, "sig-signing-nodes", &obj); 1557 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1558 dns_zone_setnodes(zone, cfg_obj_asuint32(obj)); 1559 1560 obj = NULL; 1561 result = named_config_get(maps, "sig-signing-type", &obj); 1562 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1563 dns_zone_setprivatetype(zone, cfg_obj_asuint32(obj)); 1564 1565 obj = NULL; 1566 result = named_config_get(maps, "update-check-ksk", &obj); 1567 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1568 dns_zone_setoption(zone, DNS_ZONEOPT_UPDATECHECKKSK, 1569 cfg_obj_asboolean(obj)); 1570 1571 obj = NULL; 1572 result = named_config_get(maps, "dnssec-dnskey-kskonly", &obj); 1573 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1574 dns_zone_setoption(zone, DNS_ZONEOPT_DNSKEYKSKONLY, 1575 cfg_obj_asboolean(obj)); 1576 1577 obj = NULL; 1578 result = named_config_get(maps, "dnssec-loadkeys-interval", 1579 &obj); 1580 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1581 RETERR(dns_zone_setrefreshkeyinterval(zone, 1582 cfg_obj_asuint32(obj))); 1583 1584 obj = NULL; 1585 result = cfg_map_get(zoptions, "auto-dnssec", &obj); 1586 if (result == ISC_R_SUCCESS) { 1587 const char *arg = cfg_obj_asstring(obj); 1588 if (strcasecmp(arg, "allow") == 0) { 1589 allow = true; 1590 } else if (strcasecmp(arg, "maintain") == 0) { 1591 allow = maint = true; 1592 } else if (strcasecmp(arg, "off") == 0) { 1593 ; 1594 } else { 1595 INSIST(0); 1596 ISC_UNREACHABLE(); 1597 } 1598 dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, allow); 1599 dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, maint); 1600 } 1601 } 1602 1603 if (ztype == dns_zone_slave || ztype == dns_zone_mirror) { 1604 RETERR(configure_zone_acl(zconfig, vconfig, config, 1605 allow_update_forwarding, ac, 1606 mayberaw, dns_zone_setforwardacl, 1607 dns_zone_clearforwardacl)); 1608 } 1609 1610 /*% 1611 * Primary master functionality. 1612 */ 1613 if (ztype == dns_zone_master) { 1614 obj = NULL; 1615 result = named_config_get(maps, "check-wildcard", &obj); 1616 if (result == ISC_R_SUCCESS) 1617 check = cfg_obj_asboolean(obj); 1618 else 1619 check = false; 1620 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKWILDCARD, check); 1621 1622 /* 1623 * With map files, the default is ignore duplicate 1624 * records. With other master formats, the default is 1625 * taken from the global configuration. 1626 */ 1627 obj = NULL; 1628 if (masterformat != dns_masterformat_map) { 1629 result = named_config_get(maps, "check-dup-records", 1630 &obj); 1631 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1632 dupcheck = cfg_obj_asstring(obj); 1633 } else { 1634 result = named_config_get(nodefault, 1635 "check-dup-records", 1636 &obj); 1637 if (result == ISC_R_SUCCESS) 1638 dupcheck = cfg_obj_asstring(obj); 1639 else 1640 dupcheck = "ignore"; 1641 1642 } 1643 if (strcasecmp(dupcheck, "warn") == 0) { 1644 fail = false; 1645 check = true; 1646 } else if (strcasecmp(dupcheck, "fail") == 0) { 1647 fail = check = true; 1648 } else if (strcasecmp(dupcheck, "ignore") == 0) { 1649 fail = check = false; 1650 } else { 1651 INSIST(0); 1652 ISC_UNREACHABLE(); 1653 } 1654 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRR, check); 1655 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRRFAIL, fail); 1656 1657 obj = NULL; 1658 result = named_config_get(maps, "check-mx", &obj); 1659 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1660 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { 1661 fail = false; 1662 check = true; 1663 } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { 1664 fail = check = true; 1665 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { 1666 fail = check = false; 1667 } else { 1668 INSIST(0); 1669 ISC_UNREACHABLE(); 1670 } 1671 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMX, check); 1672 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMXFAIL, fail); 1673 1674 /* 1675 * With map files, the default is *not* to check 1676 * integrity. With other master formats, the default is 1677 * taken from the global configuration. 1678 */ 1679 obj = NULL; 1680 if (masterformat != dns_masterformat_map) { 1681 result = named_config_get(maps, "check-integrity", 1682 &obj); 1683 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1684 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKINTEGRITY, 1685 cfg_obj_asboolean(obj)); 1686 } else { 1687 check = false; 1688 result = named_config_get(nodefault, "check-integrity", 1689 &obj); 1690 if (result == ISC_R_SUCCESS) 1691 check = cfg_obj_asboolean(obj); 1692 dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKINTEGRITY, 1693 check); 1694 } 1695 1696 obj = NULL; 1697 result = named_config_get(maps, "check-mx-cname", &obj); 1698 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1699 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { 1700 warn = true; 1701 ignore = false; 1702 } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { 1703 warn = ignore = false; 1704 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { 1705 warn = ignore = true; 1706 } else { 1707 INSIST(0); 1708 ISC_UNREACHABLE(); 1709 } 1710 dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNMXCNAME, warn); 1711 dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNOREMXCNAME, ignore); 1712 1713 obj = NULL; 1714 result = named_config_get(maps, "check-srv-cname", &obj); 1715 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1716 if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { 1717 warn = true; 1718 ignore = false; 1719 } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { 1720 warn = ignore = false; 1721 } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { 1722 warn = ignore = true; 1723 } else { 1724 INSIST(0); 1725 ISC_UNREACHABLE(); 1726 } 1727 dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNSRVCNAME, warn); 1728 dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNORESRVCNAME, 1729 ignore); 1730 1731 obj = NULL; 1732 result = named_config_get(maps, "dnssec-secure-to-insecure", 1733 &obj); 1734 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1735 dns_zone_setoption(mayberaw, DNS_ZONEOPT_SECURETOINSECURE, 1736 cfg_obj_asboolean(obj)); 1737 1738 obj = NULL; 1739 result = cfg_map_get(zoptions, "dnssec-update-mode", &obj); 1740 if (result == ISC_R_SUCCESS) { 1741 const char *arg = cfg_obj_asstring(obj); 1742 if (strcasecmp(arg, "no-resign") == 0) { 1743 dns_zone_setkeyopt(zone, DNS_ZONEKEY_NORESIGN, 1744 true); 1745 } else if (strcasecmp(arg, "maintain") == 0) { 1746 ; 1747 } else { 1748 INSIST(0); 1749 ISC_UNREACHABLE(); 1750 } 1751 } 1752 1753 obj = NULL; 1754 result = named_config_get(maps, "serial-update-method", &obj); 1755 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1756 if (strcasecmp(cfg_obj_asstring(obj), "unixtime") == 0) 1757 dns_zone_setserialupdatemethod(zone, 1758 dns_updatemethod_unixtime); 1759 else if (strcasecmp(cfg_obj_asstring(obj), "date") == 0) 1760 dns_zone_setserialupdatemethod(zone, 1761 dns_updatemethod_date); 1762 else 1763 dns_zone_setserialupdatemethod(zone, 1764 dns_updatemethod_increment); 1765 } 1766 1767 /* 1768 * Configure slave functionality. 1769 */ 1770 switch (ztype) { 1771 case dns_zone_mirror: 1772 /* 1773 * Disable outgoing zone transfers for mirror zones unless they 1774 * are explicitly enabled by zone configuration. 1775 */ 1776 obj = NULL; 1777 (void)cfg_map_get(zoptions, "allow-transfer", &obj); 1778 if (obj == NULL) { 1779 dns_acl_t *none; 1780 RETERR(dns_acl_none(mctx, &none)); 1781 dns_zone_setxfracl(zone, none); 1782 dns_acl_detach(&none); 1783 } 1784 /* FALLTHROUGH */ 1785 case dns_zone_slave: 1786 case dns_zone_stub: 1787 case dns_zone_redirect: 1788 count = 0; 1789 obj = NULL; 1790 (void)cfg_map_get(zoptions, "masters", &obj); 1791 /* 1792 * Use the built-in master server list if one was not 1793 * explicitly specified and this is a root zone mirror. 1794 */ 1795 if (obj == NULL && ztype == dns_zone_mirror && 1796 dns_name_equal(dns_zone_getorigin(zone), dns_rootname)) 1797 { 1798 result = named_config_getmastersdef(named_g_config, 1799 DEFAULT_IANA_ROOT_ZONE_MASTERS, 1800 &obj); 1801 RETERR(result); 1802 } 1803 if (obj != NULL) { 1804 dns_ipkeylist_t ipkl; 1805 dns_ipkeylist_init(&ipkl); 1806 1807 RETERR(named_config_getipandkeylist(config, obj, mctx, 1808 &ipkl)); 1809 result = dns_zone_setmasterswithkeys(mayberaw, 1810 ipkl.addrs, 1811 ipkl.keys, 1812 ipkl.count); 1813 count = ipkl.count; 1814 dns_ipkeylist_clear(mctx, &ipkl); 1815 RETERR(result); 1816 } else 1817 result = dns_zone_setmasters(mayberaw, NULL, 0); 1818 RETERR(result); 1819 1820 multi = false; 1821 if (count > 1) { 1822 obj = NULL; 1823 result = named_config_get(maps, "multi-master", &obj); 1824 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1825 multi = cfg_obj_asboolean(obj); 1826 } 1827 dns_zone_setoption(mayberaw, DNS_ZONEOPT_MULTIMASTER, multi); 1828 1829 obj = NULL; 1830 result = named_config_get(maps, "max-transfer-time-in", &obj); 1831 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1832 dns_zone_setmaxxfrin(mayberaw, cfg_obj_asuint32(obj) * 60); 1833 1834 obj = NULL; 1835 result = named_config_get(maps, "max-transfer-idle-in", &obj); 1836 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1837 dns_zone_setidlein(mayberaw, cfg_obj_asuint32(obj) * 60); 1838 1839 obj = NULL; 1840 result = named_config_get(maps, "max-refresh-time", &obj); 1841 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1842 dns_zone_setmaxrefreshtime(mayberaw, cfg_obj_asuint32(obj)); 1843 1844 obj = NULL; 1845 result = named_config_get(maps, "min-refresh-time", &obj); 1846 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1847 dns_zone_setminrefreshtime(mayberaw, cfg_obj_asuint32(obj)); 1848 1849 obj = NULL; 1850 result = named_config_get(maps, "max-retry-time", &obj); 1851 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1852 dns_zone_setmaxretrytime(mayberaw, cfg_obj_asuint32(obj)); 1853 1854 obj = NULL; 1855 result = named_config_get(maps, "min-retry-time", &obj); 1856 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1857 dns_zone_setminretrytime(mayberaw, cfg_obj_asuint32(obj)); 1858 1859 obj = NULL; 1860 result = named_config_get(maps, "transfer-source", &obj); 1861 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1862 RETERR(dns_zone_setxfrsource4(mayberaw, 1863 cfg_obj_assockaddr(obj))); 1864 dscp = cfg_obj_getdscp(obj); 1865 if (dscp == -1) 1866 dscp = named_g_dscp; 1867 RETERR(dns_zone_setxfrsource4dscp(mayberaw, dscp)); 1868 named_add_reserved_dispatch(named_g_server, 1869 cfg_obj_assockaddr(obj)); 1870 1871 obj = NULL; 1872 result = named_config_get(maps, "transfer-source-v6", &obj); 1873 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1874 RETERR(dns_zone_setxfrsource6(mayberaw, 1875 cfg_obj_assockaddr(obj))); 1876 dscp = cfg_obj_getdscp(obj); 1877 if (dscp == -1) 1878 dscp = named_g_dscp; 1879 RETERR(dns_zone_setxfrsource6dscp(mayberaw, dscp)); 1880 named_add_reserved_dispatch(named_g_server, 1881 cfg_obj_assockaddr(obj)); 1882 1883 obj = NULL; 1884 result = named_config_get(maps, "alt-transfer-source", &obj); 1885 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1886 RETERR(dns_zone_setaltxfrsource4(mayberaw, 1887 cfg_obj_assockaddr(obj))); 1888 dscp = cfg_obj_getdscp(obj); 1889 if (dscp == -1) 1890 dscp = named_g_dscp; 1891 RETERR(dns_zone_setaltxfrsource4dscp(mayberaw, dscp)); 1892 1893 obj = NULL; 1894 result = named_config_get(maps, "alt-transfer-source-v6", &obj); 1895 INSIST(result == ISC_R_SUCCESS && obj != NULL); 1896 RETERR(dns_zone_setaltxfrsource6(mayberaw, 1897 cfg_obj_assockaddr(obj))); 1898 dscp = cfg_obj_getdscp(obj); 1899 if (dscp == -1) 1900 dscp = named_g_dscp; 1901 RETERR(dns_zone_setaltxfrsource6dscp(mayberaw, dscp)); 1902 1903 obj = NULL; 1904 (void)named_config_get(maps, "use-alt-transfer-source", &obj); 1905 if (obj == NULL) { 1906 /* 1907 * Default off when views are in use otherwise 1908 * on for BIND 8 compatibility. 1909 */ 1910 view = dns_zone_getview(zone); 1911 if (view != NULL && strcmp(view->name, "_default") == 0) 1912 alt = true; 1913 else 1914 alt = false; 1915 } else 1916 alt = cfg_obj_asboolean(obj); 1917 dns_zone_setoption(mayberaw, DNS_ZONEOPT_USEALTXFRSRC, alt); 1918 1919 obj = NULL; 1920 (void)named_config_get(maps, "try-tcp-refresh", &obj); 1921 dns_zone_setoption(mayberaw, DNS_ZONEOPT_TRYTCPREFRESH, 1922 cfg_obj_asboolean(obj)); 1923 break; 1924 1925 case dns_zone_staticstub: 1926 RETERR(configure_staticstub(zoptions, zone, zname, 1927 default_dbtype)); 1928 break; 1929 1930 default: 1931 break; 1932 } 1933 1934 return (ISC_R_SUCCESS); 1935 } 1936 1937 /* 1938 * Set up a DLZ zone as writeable 1939 */ 1940 isc_result_t 1941 named_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, 1942 dns_zone_t *zone, 1943 dns_rdataclass_t rdclass, 1944 dns_name_t *name) 1945 { 1946 dns_db_t *db = NULL; 1947 isc_time_t now; 1948 isc_result_t result; 1949 1950 TIME_NOW(&now); 1951 1952 dns_zone_settype(zone, dns_zone_dlz); 1953 result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db); 1954 if (result != ISC_R_SUCCESS) 1955 return (result); 1956 result = dns_zone_dlzpostload(zone, db); 1957 dns_db_detach(&db); 1958 return (result); 1959 } 1960 1961 bool 1962 named_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) { 1963 const cfg_obj_t *zoptions = NULL; 1964 const cfg_obj_t *obj = NULL; 1965 const char *cfilename; 1966 const char *zfilename; 1967 dns_zone_t *raw = NULL; 1968 bool has_raw; 1969 dns_zonetype_t ztype; 1970 1971 zoptions = cfg_tuple_get(zconfig, "options"); 1972 1973 /* 1974 * We always reconfigure a static-stub zone for simplicity, assuming 1975 * the amount of data to be loaded is small. 1976 */ 1977 if (zonetype_fromconfig(zoptions) == dns_zone_staticstub) { 1978 dns_zone_log(zone, ISC_LOG_DEBUG(1), 1979 "not reusable: staticstub"); 1980 return (false); 1981 } 1982 1983 /* If there's a raw zone, use that for filename and type comparison */ 1984 dns_zone_getraw(zone, &raw); 1985 if (raw != NULL) { 1986 zfilename = dns_zone_getfile(raw); 1987 ztype = dns_zone_gettype(raw); 1988 dns_zone_detach(&raw); 1989 has_raw = true; 1990 } else { 1991 zfilename = dns_zone_getfile(zone); 1992 ztype = dns_zone_gettype(zone); 1993 has_raw = false; 1994 } 1995 1996 obj = NULL; 1997 (void)cfg_map_get(zoptions, "inline-signing", &obj); 1998 if ((obj == NULL || !cfg_obj_asboolean(obj)) && has_raw) { 1999 dns_zone_log(zone, ISC_LOG_DEBUG(1), 2000 "not reusable: old zone was inline-signing"); 2001 return (false); 2002 } else if ((obj != NULL && cfg_obj_asboolean(obj)) && !has_raw) { 2003 dns_zone_log(zone, ISC_LOG_DEBUG(1), 2004 "not reusable: old zone was not inline-signing"); 2005 return (false); 2006 } 2007 2008 if (zonetype_fromconfig(zoptions) != ztype) { 2009 dns_zone_log(zone, ISC_LOG_DEBUG(1), 2010 "not reusable: type mismatch"); 2011 return (false); 2012 } 2013 2014 obj = NULL; 2015 (void)cfg_map_get(zoptions, "file", &obj); 2016 if (obj != NULL) 2017 cfilename = cfg_obj_asstring(obj); 2018 else 2019 cfilename = NULL; 2020 if (!((cfilename == NULL && zfilename == NULL) || 2021 (cfilename != NULL && zfilename != NULL && 2022 strcmp(cfilename, zfilename) == 0))) 2023 { 2024 dns_zone_log(zone, ISC_LOG_DEBUG(1), 2025 "not reusable: filename mismatch"); 2026 return (false); 2027 } 2028 2029 return (true); 2030 } 2031