1/* 2 * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1999-2003 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id$ */ 19 20/*! \file */ 21 22#include <config.h> 23 24#include <isc/file.h> 25#include <isc/hash.h> 26#include <isc/print.h> 27#include <isc/sha2.h> 28#include <isc/stats.h> 29#include <isc/string.h> /* Required for HP/UX (and others?) */ 30#include <isc/task.h> 31#include <isc/util.h> 32 33#include <dns/acache.h> 34#include <dns/acl.h> 35#include <dns/adb.h> 36#include <dns/cache.h> 37#include <dns/db.h> 38#include <dns/dlz.h> 39#ifdef BIND9 40#include <dns/dns64.h> 41#endif 42#include <dns/dnssec.h> 43#include <dns/events.h> 44#include <dns/forward.h> 45#include <dns/keytable.h> 46#include <dns/keyvalues.h> 47#include <dns/master.h> 48#include <dns/masterdump.h> 49#include <dns/order.h> 50#include <dns/peer.h> 51#include <dns/rbt.h> 52#include <dns/rdataset.h> 53#include <dns/request.h> 54#include <dns/resolver.h> 55#include <dns/result.h> 56#include <dns/rpz.h> 57#include <dns/stats.h> 58#include <dns/tsig.h> 59#include <dns/zone.h> 60#include <dns/zt.h> 61 62#define RESSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_RESSHUTDOWN) != 0) 63#define ADBSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_ADBSHUTDOWN) != 0) 64#define REQSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_REQSHUTDOWN) != 0) 65 66#define DNS_VIEW_DELONLYHASH 111 67 68static void resolver_shutdown(isc_task_t *task, isc_event_t *event); 69static void adb_shutdown(isc_task_t *task, isc_event_t *event); 70static void req_shutdown(isc_task_t *task, isc_event_t *event); 71 72isc_result_t 73dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, 74 const char *name, dns_view_t **viewp) 75{ 76 dns_view_t *view; 77 isc_result_t result; 78 79 /* 80 * Create a view. 81 */ 82 83 REQUIRE(name != NULL); 84 REQUIRE(viewp != NULL && *viewp == NULL); 85 86 view = isc_mem_get(mctx, sizeof(*view)); 87 if (view == NULL) 88 return (ISC_R_NOMEMORY); 89 view->name = isc_mem_strdup(mctx, name); 90 if (view->name == NULL) { 91 result = ISC_R_NOMEMORY; 92 goto cleanup_view; 93 } 94 result = isc_mutex_init(&view->lock); 95 if (result != ISC_R_SUCCESS) 96 goto cleanup_name; 97 98#ifdef BIND9 99 view->zonetable = NULL; 100 result = dns_zt_create(mctx, rdclass, &view->zonetable); 101 if (result != ISC_R_SUCCESS) { 102 UNEXPECTED_ERROR(__FILE__, __LINE__, 103 "dns_zt_create() failed: %s", 104 isc_result_totext(result)); 105 result = ISC_R_UNEXPECTED; 106 goto cleanup_mutex; 107 } 108#endif 109 view->secroots_priv = NULL; 110 view->fwdtable = NULL; 111 result = dns_fwdtable_create(mctx, &view->fwdtable); 112 if (result != ISC_R_SUCCESS) { 113 UNEXPECTED_ERROR(__FILE__, __LINE__, 114 "dns_fwdtable_create() failed: %s", 115 isc_result_totext(result)); 116 result = ISC_R_UNEXPECTED; 117 goto cleanup_zt; 118 } 119 120 view->acache = NULL; 121 view->cache = NULL; 122 view->cachedb = NULL; 123 view->dlzdatabase = NULL; 124 view->hints = NULL; 125 view->resolver = NULL; 126 view->adb = NULL; 127 view->requestmgr = NULL; 128 view->mctx = mctx; 129 view->rdclass = rdclass; 130 view->frozen = ISC_FALSE; 131 view->task = NULL; 132 result = isc_refcount_init(&view->references, 1); 133 if (result != ISC_R_SUCCESS) 134 goto cleanup_fwdtable; 135 view->weakrefs = 0; 136 view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN| 137 DNS_VIEWATTR_REQSHUTDOWN); 138 view->statickeys = NULL; 139 view->dynamickeys = NULL; 140 view->matchclients = NULL; 141 view->matchdestinations = NULL; 142 view->matchrecursiveonly = ISC_FALSE; 143 result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys); 144 if (result != ISC_R_SUCCESS) 145 goto cleanup_references; 146 view->peers = NULL; 147 view->order = NULL; 148 view->delonly = NULL; 149 view->rootdelonly = ISC_FALSE; 150 view->rootexclude = NULL; 151 view->resstats = NULL; 152 view->resquerystats = NULL; 153 view->cacheshared = ISC_FALSE; 154 ISC_LIST_INIT(view->dns64); 155 view->dns64cnt = 0; 156 157 /* 158 * Initialize configuration data with default values. 159 */ 160 view->recursion = ISC_TRUE; 161 view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */ 162 view->additionalfromcache = ISC_TRUE; 163 view->additionalfromauth = ISC_TRUE; 164 view->enablednssec = ISC_TRUE; 165 view->enablevalidation = ISC_TRUE; 166 view->acceptexpired = ISC_FALSE; 167 view->minimalresponses = ISC_FALSE; 168 view->transfer_format = dns_one_answer; 169 view->cacheacl = NULL; 170 view->cacheonacl = NULL; 171 view->queryacl = NULL; 172 view->queryonacl = NULL; 173 view->recursionacl = NULL; 174 view->recursiononacl = NULL; 175 view->sortlist = NULL; 176 view->transferacl = NULL; 177 view->notifyacl = NULL; 178 view->updateacl = NULL; 179 view->upfwdacl = NULL; 180 view->denyansweracl = NULL; 181 view->answeracl_exclude = NULL; 182 view->denyanswernames = NULL; 183 view->answernames_exclude = NULL; 184 view->requestixfr = ISC_TRUE; 185 view->provideixfr = ISC_TRUE; 186 view->maxcachettl = 7 * 24 * 3600; 187 view->maxncachettl = 3 * 3600; 188 view->dstport = 53; 189 view->preferred_glue = 0; 190 view->flush = ISC_FALSE; 191 view->dlv = NULL; 192 view->maxudp = 0; 193 view->v4_aaaa = dns_v4_aaaa_ok; 194 view->v4_aaaa_acl = NULL; 195 ISC_LIST_INIT(view->rpz_zones); 196 dns_fixedname_init(&view->dlv_fixed); 197 view->managed_keys = NULL; 198#ifdef BIND9 199 view->new_zone_file = NULL; 200 view->new_zone_config = NULL; 201 view->cfg_destroy = NULL; 202 203 result = dns_order_create(view->mctx, &view->order); 204 if (result != ISC_R_SUCCESS) 205 goto cleanup_dynkeys; 206#endif 207 208 result = dns_peerlist_new(view->mctx, &view->peers); 209 if (result != ISC_R_SUCCESS) 210 goto cleanup_order; 211 212 result = dns_aclenv_init(view->mctx, &view->aclenv); 213 if (result != ISC_R_SUCCESS) 214 goto cleanup_peerlist; 215 216 ISC_LINK_INIT(view, link); 217 ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL, 218 DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown, 219 view, NULL, NULL, NULL); 220 ISC_EVENT_INIT(&view->adbevent, sizeof(view->adbevent), 0, NULL, 221 DNS_EVENT_VIEWADBSHUTDOWN, adb_shutdown, 222 view, NULL, NULL, NULL); 223 ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL, 224 DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown, 225 view, NULL, NULL, NULL); 226 view->magic = DNS_VIEW_MAGIC; 227 228 *viewp = view; 229 230 return (ISC_R_SUCCESS); 231 232 cleanup_peerlist: 233 dns_peerlist_detach(&view->peers); 234 235 cleanup_order: 236#ifdef BIND9 237 dns_order_detach(&view->order); 238 239 cleanup_dynkeys: 240#endif 241 dns_tsigkeyring_detach(&view->dynamickeys); 242 243 cleanup_references: 244 isc_refcount_destroy(&view->references); 245 246 cleanup_fwdtable: 247 dns_fwdtable_destroy(&view->fwdtable); 248 249 cleanup_zt: 250#ifdef BIND9 251 dns_zt_detach(&view->zonetable); 252 253 cleanup_mutex: 254#endif 255 DESTROYLOCK(&view->lock); 256 257 cleanup_name: 258 isc_mem_free(mctx, view->name); 259 260 cleanup_view: 261 isc_mem_put(mctx, view, sizeof(*view)); 262 263 return (result); 264} 265 266static inline void 267destroy(dns_view_t *view) { 268#ifdef BIND9 269 dns_dns64_t *dns64; 270#endif 271 272 REQUIRE(!ISC_LINK_LINKED(view, link)); 273 REQUIRE(isc_refcount_current(&view->references) == 0); 274 REQUIRE(view->weakrefs == 0); 275 REQUIRE(RESSHUTDOWN(view)); 276 REQUIRE(ADBSHUTDOWN(view)); 277 REQUIRE(REQSHUTDOWN(view)); 278 279#ifdef BIND9 280 if (view->order != NULL) 281 dns_order_detach(&view->order); 282#endif 283 if (view->peers != NULL) 284 dns_peerlist_detach(&view->peers); 285 286 if (view->dynamickeys != NULL) { 287 isc_result_t result; 288 char template[20]; 289 char keyfile[20]; 290 FILE *fp = NULL; 291 int n; 292 293 n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys", 294 view->name); 295 if (n > 0 && (size_t)n < sizeof(keyfile)) { 296 result = isc_file_mktemplate(keyfile, template, 297 sizeof(template)); 298 if (result == ISC_R_SUCCESS) 299 (void)isc_file_openuniqueprivate(template, &fp); 300 } 301 if (fp == NULL) 302 dns_tsigkeyring_detach(&view->dynamickeys); 303 else { 304 result = dns_tsigkeyring_dumpanddetach( 305 &view->dynamickeys, fp); 306 if (result == ISC_R_SUCCESS) { 307 if (fclose(fp) == 0) 308 result = isc_file_rename(template, 309 keyfile); 310 if (result != ISC_R_SUCCESS) 311 (void)remove(template); 312 } else { 313 (void)fclose(fp); 314 (void)remove(template); 315 } 316 } 317 } 318 if (view->statickeys != NULL) 319 dns_tsigkeyring_detach(&view->statickeys); 320 if (view->adb != NULL) 321 dns_adb_detach(&view->adb); 322 if (view->resolver != NULL) 323 dns_resolver_detach(&view->resolver); 324#ifdef BIND9 325 if (view->acache != NULL) { 326 if (view->cachedb != NULL) 327 dns_acache_putdb(view->acache, view->cachedb); 328 dns_acache_detach(&view->acache); 329 } 330 dns_rpz_view_destroy(view); 331#else 332 INSIST(view->acache == NULL); 333 INSIST(ISC_LIST_EMPTY(view->rpz_zones)); 334#endif 335 if (view->requestmgr != NULL) 336 dns_requestmgr_detach(&view->requestmgr); 337 if (view->task != NULL) 338 isc_task_detach(&view->task); 339 if (view->hints != NULL) 340 dns_db_detach(&view->hints); 341 if (view->dlzdatabase != NULL) 342 dns_dlzdestroy(&view->dlzdatabase); 343 if (view->cachedb != NULL) 344 dns_db_detach(&view->cachedb); 345 if (view->cache != NULL) 346 dns_cache_detach(&view->cache); 347 if (view->matchclients != NULL) 348 dns_acl_detach(&view->matchclients); 349 if (view->matchdestinations != NULL) 350 dns_acl_detach(&view->matchdestinations); 351 if (view->cacheacl != NULL) 352 dns_acl_detach(&view->cacheacl); 353 if (view->cacheonacl != NULL) 354 dns_acl_detach(&view->cacheonacl); 355 if (view->queryacl != NULL) 356 dns_acl_detach(&view->queryacl); 357 if (view->queryonacl != NULL) 358 dns_acl_detach(&view->queryonacl); 359 if (view->recursionacl != NULL) 360 dns_acl_detach(&view->recursionacl); 361 if (view->recursiononacl != NULL) 362 dns_acl_detach(&view->recursiononacl); 363 if (view->sortlist != NULL) 364 dns_acl_detach(&view->sortlist); 365 if (view->transferacl != NULL) 366 dns_acl_detach(&view->transferacl); 367 if (view->notifyacl != NULL) 368 dns_acl_detach(&view->notifyacl); 369 if (view->updateacl != NULL) 370 dns_acl_detach(&view->updateacl); 371 if (view->upfwdacl != NULL) 372 dns_acl_detach(&view->upfwdacl); 373 if (view->denyansweracl != NULL) 374 dns_acl_detach(&view->denyansweracl); 375 if (view->v4_aaaa_acl != NULL) 376 dns_acl_detach(&view->v4_aaaa_acl); 377 if (view->answeracl_exclude != NULL) 378 dns_rbt_destroy(&view->answeracl_exclude); 379 if (view->denyanswernames != NULL) 380 dns_rbt_destroy(&view->denyanswernames); 381 if (view->answernames_exclude != NULL) 382 dns_rbt_destroy(&view->answernames_exclude); 383 if (view->delonly != NULL) { 384 dns_name_t *name; 385 int i; 386 387 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) { 388 name = ISC_LIST_HEAD(view->delonly[i]); 389 while (name != NULL) { 390 ISC_LIST_UNLINK(view->delonly[i], name, link); 391 dns_name_free(name, view->mctx); 392 isc_mem_put(view->mctx, name, sizeof(*name)); 393 name = ISC_LIST_HEAD(view->delonly[i]); 394 } 395 } 396 isc_mem_put(view->mctx, view->delonly, sizeof(dns_namelist_t) * 397 DNS_VIEW_DELONLYHASH); 398 view->delonly = NULL; 399 } 400 if (view->rootexclude != NULL) { 401 dns_name_t *name; 402 int i; 403 404 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) { 405 name = ISC_LIST_HEAD(view->rootexclude[i]); 406 while (name != NULL) { 407 ISC_LIST_UNLINK(view->rootexclude[i], 408 name, link); 409 dns_name_free(name, view->mctx); 410 isc_mem_put(view->mctx, name, sizeof(*name)); 411 name = ISC_LIST_HEAD(view->rootexclude[i]); 412 } 413 } 414 isc_mem_put(view->mctx, view->rootexclude, 415 sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH); 416 view->rootexclude = NULL; 417 } 418 if (view->resstats != NULL) 419 isc_stats_detach(&view->resstats); 420 if (view->resquerystats != NULL) 421 dns_stats_detach(&view->resquerystats); 422 if (view->secroots_priv != NULL) 423 dns_keytable_detach(&view->secroots_priv); 424#ifdef BIND9 425 for (dns64 = ISC_LIST_HEAD(view->dns64); 426 dns64 != NULL; 427 dns64 = ISC_LIST_HEAD(view->dns64)) { 428 dns_dns64_unlink(&view->dns64, dns64); 429 dns_dns64_destroy(&dns64); 430 } 431 if (view->managed_keys != NULL) 432 dns_zone_detach(&view->managed_keys); 433 dns_view_setnewzones(view, ISC_FALSE, NULL, NULL); 434#endif 435 dns_fwdtable_destroy(&view->fwdtable); 436 dns_aclenv_destroy(&view->aclenv); 437 DESTROYLOCK(&view->lock); 438 isc_refcount_destroy(&view->references); 439 isc_mem_free(view->mctx, view->name); 440 isc_mem_put(view->mctx, view, sizeof(*view)); 441} 442 443/* 444 * Return true iff 'view' may be freed. 445 * The caller must be holding the view lock. 446 */ 447static isc_boolean_t 448all_done(dns_view_t *view) { 449 450 if (isc_refcount_current(&view->references) == 0 && 451 view->weakrefs == 0 && 452 RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view)) 453 return (ISC_TRUE); 454 455 return (ISC_FALSE); 456} 457 458void 459dns_view_attach(dns_view_t *source, dns_view_t **targetp) { 460 461 REQUIRE(DNS_VIEW_VALID(source)); 462 REQUIRE(targetp != NULL && *targetp == NULL); 463 464 isc_refcount_increment(&source->references, NULL); 465 466 *targetp = source; 467} 468 469static void 470view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { 471 dns_view_t *view; 472 unsigned int refs; 473 isc_boolean_t done = ISC_FALSE; 474 475 REQUIRE(viewp != NULL); 476 view = *viewp; 477 REQUIRE(DNS_VIEW_VALID(view)); 478 479 if (flush) 480 view->flush = ISC_TRUE; 481 isc_refcount_decrement(&view->references, &refs); 482 if (refs == 0) { 483 LOCK(&view->lock); 484 if (!RESSHUTDOWN(view)) 485 dns_resolver_shutdown(view->resolver); 486 if (!ADBSHUTDOWN(view)) 487 dns_adb_shutdown(view->adb); 488 if (!REQSHUTDOWN(view)) 489 dns_requestmgr_shutdown(view->requestmgr); 490#ifdef BIND9 491 if (view->acache != NULL) 492 dns_acache_shutdown(view->acache); 493 if (view->flush) 494 dns_zt_flushanddetach(&view->zonetable); 495 else 496 dns_zt_detach(&view->zonetable); 497 if (view->managed_keys != NULL) { 498 if (view->flush) 499 dns_zone_flush(view->managed_keys); 500 dns_zone_detach(&view->managed_keys); 501 } 502#endif 503 done = all_done(view); 504 UNLOCK(&view->lock); 505 } 506 507 *viewp = NULL; 508 509 if (done) 510 destroy(view); 511} 512 513void 514dns_view_flushanddetach(dns_view_t **viewp) { 515 view_flushanddetach(viewp, ISC_TRUE); 516} 517 518void 519dns_view_detach(dns_view_t **viewp) { 520 view_flushanddetach(viewp, ISC_FALSE); 521} 522 523#ifdef BIND9 524static isc_result_t 525dialup(dns_zone_t *zone, void *dummy) { 526 UNUSED(dummy); 527 dns_zone_dialup(zone); 528 return (ISC_R_SUCCESS); 529} 530 531void 532dns_view_dialup(dns_view_t *view) { 533 REQUIRE(DNS_VIEW_VALID(view)); 534 (void)dns_zt_apply(view->zonetable, ISC_FALSE, dialup, NULL); 535} 536#endif 537 538void 539dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) { 540 541 REQUIRE(DNS_VIEW_VALID(source)); 542 REQUIRE(targetp != NULL && *targetp == NULL); 543 544 LOCK(&source->lock); 545 source->weakrefs++; 546 UNLOCK(&source->lock); 547 548 *targetp = source; 549} 550 551void 552dns_view_weakdetach(dns_view_t **viewp) { 553 dns_view_t *view; 554 isc_boolean_t done = ISC_FALSE; 555 556 REQUIRE(viewp != NULL); 557 view = *viewp; 558 REQUIRE(DNS_VIEW_VALID(view)); 559 560 LOCK(&view->lock); 561 562 INSIST(view->weakrefs > 0); 563 view->weakrefs--; 564 done = all_done(view); 565 566 UNLOCK(&view->lock); 567 568 *viewp = NULL; 569 570 if (done) 571 destroy(view); 572} 573 574static void 575resolver_shutdown(isc_task_t *task, isc_event_t *event) { 576 dns_view_t *view = event->ev_arg; 577 isc_boolean_t done; 578 579 REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN); 580 REQUIRE(DNS_VIEW_VALID(view)); 581 REQUIRE(view->task == task); 582 583 UNUSED(task); 584 585 LOCK(&view->lock); 586 587 view->attributes |= DNS_VIEWATTR_RESSHUTDOWN; 588 done = all_done(view); 589 590 UNLOCK(&view->lock); 591 592 isc_event_free(&event); 593 594 if (done) 595 destroy(view); 596} 597 598static void 599adb_shutdown(isc_task_t *task, isc_event_t *event) { 600 dns_view_t *view = event->ev_arg; 601 isc_boolean_t done; 602 603 REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN); 604 REQUIRE(DNS_VIEW_VALID(view)); 605 REQUIRE(view->task == task); 606 607 UNUSED(task); 608 609 LOCK(&view->lock); 610 611 view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN; 612 done = all_done(view); 613 614 UNLOCK(&view->lock); 615 616 isc_event_free(&event); 617 618 if (done) 619 destroy(view); 620} 621 622static void 623req_shutdown(isc_task_t *task, isc_event_t *event) { 624 dns_view_t *view = event->ev_arg; 625 isc_boolean_t done; 626 627 REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN); 628 REQUIRE(DNS_VIEW_VALID(view)); 629 REQUIRE(view->task == task); 630 631 UNUSED(task); 632 633 LOCK(&view->lock); 634 635 view->attributes |= DNS_VIEWATTR_REQSHUTDOWN; 636 done = all_done(view); 637 638 UNLOCK(&view->lock); 639 640 isc_event_free(&event); 641 642 if (done) 643 destroy(view); 644} 645 646isc_result_t 647dns_view_createresolver(dns_view_t *view, 648 isc_taskmgr_t *taskmgr, unsigned int ntasks, 649 isc_socketmgr_t *socketmgr, 650 isc_timermgr_t *timermgr, 651 unsigned int options, 652 dns_dispatchmgr_t *dispatchmgr, 653 dns_dispatch_t *dispatchv4, 654 dns_dispatch_t *dispatchv6) 655{ 656 isc_result_t result; 657 isc_event_t *event; 658 isc_mem_t *mctx = NULL; 659 660 REQUIRE(DNS_VIEW_VALID(view)); 661 REQUIRE(!view->frozen); 662 REQUIRE(view->resolver == NULL); 663 664 result = isc_task_create(taskmgr, 0, &view->task); 665 if (result != ISC_R_SUCCESS) 666 return (result); 667 isc_task_setname(view->task, "view", view); 668 669 result = dns_resolver_create(view, taskmgr, ntasks, socketmgr, 670 timermgr, options, dispatchmgr, 671 dispatchv4, dispatchv6, 672 &view->resolver); 673 if (result != ISC_R_SUCCESS) { 674 isc_task_detach(&view->task); 675 return (result); 676 } 677 event = &view->resevent; 678 dns_resolver_whenshutdown(view->resolver, view->task, &event); 679 view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN; 680 681 result = isc_mem_create(0, 0, &mctx); 682 if (result != ISC_R_SUCCESS) { 683 dns_resolver_shutdown(view->resolver); 684 return (result); 685 } 686 687 result = dns_adb_create(mctx, view, timermgr, taskmgr, &view->adb); 688 isc_mem_setname(mctx, "ADB", NULL); 689 isc_mem_detach(&mctx); 690 if (result != ISC_R_SUCCESS) { 691 dns_resolver_shutdown(view->resolver); 692 return (result); 693 } 694 event = &view->adbevent; 695 dns_adb_whenshutdown(view->adb, view->task, &event); 696 view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN; 697 698 result = dns_requestmgr_create(view->mctx, timermgr, socketmgr, 699 dns_resolver_taskmgr(view->resolver), 700 dns_resolver_dispatchmgr(view->resolver), 701 dns_resolver_dispatchv4(view->resolver), 702 dns_resolver_dispatchv6(view->resolver), 703 &view->requestmgr); 704 if (result != ISC_R_SUCCESS) { 705 dns_adb_shutdown(view->adb); 706 dns_resolver_shutdown(view->resolver); 707 return (result); 708 } 709 event = &view->reqevent; 710 dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event); 711 view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN; 712 713 return (ISC_R_SUCCESS); 714} 715 716void 717dns_view_setcache(dns_view_t *view, dns_cache_t *cache) { 718 dns_view_setcache2(view, cache, ISC_FALSE); 719} 720 721void 722dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) { 723 REQUIRE(DNS_VIEW_VALID(view)); 724 REQUIRE(!view->frozen); 725 726 view->cacheshared = shared; 727 if (view->cache != NULL) { 728#ifdef BIND9 729 if (view->acache != NULL) 730 dns_acache_putdb(view->acache, view->cachedb); 731#endif 732 dns_db_detach(&view->cachedb); 733 dns_cache_detach(&view->cache); 734 } 735 dns_cache_attach(cache, &view->cache); 736 dns_cache_attachdb(cache, &view->cachedb); 737 INSIST(DNS_DB_VALID(view->cachedb)); 738 739#ifdef BIND9 740 if (view->acache != NULL) 741 dns_acache_setdb(view->acache, view->cachedb); 742#endif 743} 744 745isc_boolean_t 746dns_view_iscacheshared(dns_view_t *view) { 747 REQUIRE(DNS_VIEW_VALID(view)); 748 749 return (view->cacheshared); 750} 751 752void 753dns_view_sethints(dns_view_t *view, dns_db_t *hints) { 754 REQUIRE(DNS_VIEW_VALID(view)); 755 REQUIRE(!view->frozen); 756 REQUIRE(view->hints == NULL); 757 REQUIRE(dns_db_iszone(hints)); 758 759 dns_db_attach(hints, &view->hints); 760} 761 762void 763dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) { 764 REQUIRE(DNS_VIEW_VALID(view)); 765 REQUIRE(ring != NULL); 766 if (view->statickeys != NULL) 767 dns_tsigkeyring_detach(&view->statickeys); 768 dns_tsigkeyring_attach(ring, &view->statickeys); 769} 770 771void 772dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring) { 773 REQUIRE(DNS_VIEW_VALID(view)); 774 REQUIRE(ring != NULL); 775 if (view->dynamickeys != NULL) 776 dns_tsigkeyring_detach(&view->dynamickeys); 777 dns_tsigkeyring_attach(ring, &view->dynamickeys); 778} 779 780void 781dns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp) { 782 REQUIRE(DNS_VIEW_VALID(view)); 783 REQUIRE(ringp != NULL && *ringp == NULL); 784 if (view->dynamickeys != NULL) 785 dns_tsigkeyring_attach(view->dynamickeys, ringp); 786} 787 788void 789dns_view_restorekeyring(dns_view_t *view) { 790 FILE *fp; 791 char keyfile[20]; 792 int n; 793 794 REQUIRE(DNS_VIEW_VALID(view)); 795 796 if (view->dynamickeys != NULL) { 797 n = snprintf(keyfile, sizeof(keyfile), "%s.tsigkeys", 798 view->name); 799 if (n > 0 && (size_t)n < sizeof(keyfile)) { 800 fp = fopen(keyfile, "r"); 801 if (fp != NULL) { 802 dns_keyring_restore(view->dynamickeys, fp); 803 (void)fclose(fp); 804 } 805 } 806 } 807} 808 809void 810dns_view_setdstport(dns_view_t *view, in_port_t dstport) { 811 REQUIRE(DNS_VIEW_VALID(view)); 812 view->dstport = dstport; 813} 814 815void 816dns_view_freeze(dns_view_t *view) { 817 REQUIRE(DNS_VIEW_VALID(view)); 818 REQUIRE(!view->frozen); 819 820 if (view->resolver != NULL) { 821 INSIST(view->cachedb != NULL); 822 dns_resolver_freeze(view->resolver); 823 } 824 view->frozen = ISC_TRUE; 825} 826 827#ifdef BIND9 828void 829dns_view_thaw(dns_view_t *view) { 830 REQUIRE(DNS_VIEW_VALID(view)); 831 REQUIRE(view->frozen); 832 833 view->frozen = ISC_FALSE; 834} 835 836isc_result_t 837dns_view_addzone(dns_view_t *view, dns_zone_t *zone) { 838 isc_result_t result; 839 840 REQUIRE(DNS_VIEW_VALID(view)); 841 REQUIRE(!view->frozen); 842 843 result = dns_zt_mount(view->zonetable, zone); 844 845 return (result); 846} 847#endif 848 849#ifdef BIND9 850isc_result_t 851dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) { 852 isc_result_t result; 853 854 REQUIRE(DNS_VIEW_VALID(view)); 855 856 result = dns_zt_find(view->zonetable, name, 0, NULL, zonep); 857 if (result == DNS_R_PARTIALMATCH) { 858 dns_zone_detach(zonep); 859 result = ISC_R_NOTFOUND; 860 } 861 862 return (result); 863} 864#endif 865 866isc_result_t 867dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, 868 isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, 869 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, 870 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { 871 return (dns_view_find2(view, name, type, now, options, use_hints, 872 ISC_FALSE, dbp, nodep, foundname, rdataset, 873 sigrdataset)); 874} 875 876isc_result_t 877dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, 878 isc_stdtime_t now, unsigned int options, 879 isc_boolean_t use_hints, isc_boolean_t use_static_stub, 880 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, 881 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 882{ 883 isc_result_t result; 884 dns_db_t *db, *zdb; 885 dns_dbnode_t *node, *znode; 886 isc_boolean_t is_cache, is_staticstub_zone; 887 dns_rdataset_t zrdataset, zsigrdataset; 888 dns_zone_t *zone; 889 890#ifndef BIND9 891 UNUSED(use_hints); 892 UNUSED(use_static_stub); 893#endif 894 895 /* 896 * Find an rdataset whose owner name is 'name', and whose type is 897 * 'type'. 898 */ 899 900 REQUIRE(DNS_VIEW_VALID(view)); 901 REQUIRE(view->frozen); 902 REQUIRE(type != dns_rdatatype_rrsig); 903 REQUIRE(rdataset != NULL); /* XXXBEW - remove this */ 904 REQUIRE(nodep == NULL || *nodep == NULL); 905 906 /* 907 * Initialize. 908 */ 909 dns_rdataset_init(&zrdataset); 910 dns_rdataset_init(&zsigrdataset); 911 zdb = NULL; 912 znode = NULL; 913 914 /* 915 * Find a database to answer the query. 916 */ 917 zone = NULL; 918 db = NULL; 919 node = NULL; 920 is_staticstub_zone = ISC_FALSE; 921#ifdef BIND9 922 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); 923 if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub && 924 !use_static_stub) { 925 result = ISC_R_NOTFOUND; 926 } 927 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { 928 result = dns_zone_getdb(zone, &db); 929 if (result != ISC_R_SUCCESS && view->cachedb != NULL) 930 dns_db_attach(view->cachedb, &db); 931 else if (result != ISC_R_SUCCESS) 932 goto cleanup; 933 if (dns_zone_gettype(zone) == dns_zone_staticstub && 934 dns_name_equal(name, dns_zone_getorigin(zone))) { 935 is_staticstub_zone = ISC_TRUE; 936 } 937 } else if (result == ISC_R_NOTFOUND && view->cachedb != NULL) 938 dns_db_attach(view->cachedb, &db); 939#else 940 result = ISC_R_NOTFOUND; 941 if (view->cachedb != NULL) 942 dns_db_attach(view->cachedb, &db); 943#endif /* BIND9 */ 944 else 945 goto cleanup; 946 947 is_cache = dns_db_iscache(db); 948 949 db_find: 950 /* 951 * Now look for an answer in the database. 952 */ 953 result = dns_db_find(db, name, NULL, type, options, 954 now, &node, foundname, rdataset, sigrdataset); 955 956 if (result == DNS_R_DELEGATION || result == ISC_R_NOTFOUND) { 957 if (dns_rdataset_isassociated(rdataset)) 958 dns_rdataset_disassociate(rdataset); 959 if (sigrdataset != NULL && 960 dns_rdataset_isassociated(sigrdataset)) 961 dns_rdataset_disassociate(sigrdataset); 962 if (node != NULL) 963 dns_db_detachnode(db, &node); 964 if (!is_cache) { 965 dns_db_detach(&db); 966 if (view->cachedb != NULL && !is_staticstub_zone) { 967 /* 968 * Either the answer is in the cache, or we 969 * don't know it. 970 * Note that if the result comes from a 971 * static-stub zone we stop the search here 972 * (see the function description in view.h). 973 */ 974 is_cache = ISC_TRUE; 975 dns_db_attach(view->cachedb, &db); 976 goto db_find; 977 } 978 } else { 979 /* 980 * We don't have the data in the cache. If we've got 981 * glue from the zone, use it. 982 */ 983 if (dns_rdataset_isassociated(&zrdataset)) { 984 dns_rdataset_clone(&zrdataset, rdataset); 985 if (sigrdataset != NULL && 986 dns_rdataset_isassociated(&zsigrdataset)) 987 dns_rdataset_clone(&zsigrdataset, 988 sigrdataset); 989 result = DNS_R_GLUE; 990 if (db != NULL) 991 dns_db_detach(&db); 992 dns_db_attach(zdb, &db); 993 dns_db_attachnode(db, znode, &node); 994 goto cleanup; 995 } 996 } 997 /* 998 * We don't know the answer. 999 */ 1000 result = ISC_R_NOTFOUND; 1001 } else if (result == DNS_R_GLUE) { 1002 if (view->cachedb != NULL && !is_staticstub_zone) { 1003 /* 1004 * We found an answer, but the cache may be better. 1005 * Remember what we've got and go look in the cache. 1006 */ 1007 is_cache = ISC_TRUE; 1008 dns_rdataset_clone(rdataset, &zrdataset); 1009 dns_rdataset_disassociate(rdataset); 1010 if (sigrdataset != NULL && 1011 dns_rdataset_isassociated(sigrdataset)) { 1012 dns_rdataset_clone(sigrdataset, &zsigrdataset); 1013 dns_rdataset_disassociate(sigrdataset); 1014 } 1015 dns_db_attach(db, &zdb); 1016 dns_db_attachnode(zdb, node, &znode); 1017 dns_db_detachnode(db, &node); 1018 dns_db_detach(&db); 1019 dns_db_attach(view->cachedb, &db); 1020 goto db_find; 1021 } 1022 /* 1023 * Otherwise, the glue is the best answer. 1024 */ 1025 result = ISC_R_SUCCESS; 1026 } 1027 1028#ifdef BIND9 1029 if (result == ISC_R_NOTFOUND && use_hints && view->hints != NULL) { 1030 if (dns_rdataset_isassociated(rdataset)) 1031 dns_rdataset_disassociate(rdataset); 1032 if (sigrdataset != NULL && 1033 dns_rdataset_isassociated(sigrdataset)) 1034 dns_rdataset_disassociate(sigrdataset); 1035 if (db != NULL) { 1036 if (node != NULL) 1037 dns_db_detachnode(db, &node); 1038 dns_db_detach(&db); 1039 } 1040 result = dns_db_find(view->hints, name, NULL, type, options, 1041 now, &node, foundname, 1042 rdataset, sigrdataset); 1043 if (result == ISC_R_SUCCESS || result == DNS_R_GLUE) { 1044 /* 1045 * We just used a hint. Let the resolver know it 1046 * should consider priming. 1047 */ 1048 dns_resolver_prime(view->resolver); 1049 dns_db_attach(view->hints, &db); 1050 result = DNS_R_HINT; 1051 } else if (result == DNS_R_NXRRSET) { 1052 dns_db_attach(view->hints, &db); 1053 result = DNS_R_HINTNXRRSET; 1054 } else if (result == DNS_R_NXDOMAIN) 1055 result = ISC_R_NOTFOUND; 1056 1057 /* 1058 * Cleanup if non-standard hints are used. 1059 */ 1060 if (db == NULL && node != NULL) 1061 dns_db_detachnode(view->hints, &node); 1062 } 1063#endif /* BIND9 */ 1064 1065 cleanup: 1066 if (dns_rdataset_isassociated(&zrdataset)) { 1067 dns_rdataset_disassociate(&zrdataset); 1068 if (dns_rdataset_isassociated(&zsigrdataset)) 1069 dns_rdataset_disassociate(&zsigrdataset); 1070 } 1071 1072 if (zdb != NULL) { 1073 if (znode != NULL) 1074 dns_db_detachnode(zdb, &znode); 1075 dns_db_detach(&zdb); 1076 } 1077 1078 if (db != NULL) { 1079 if (node != NULL) { 1080 if (nodep != NULL) 1081 *nodep = node; 1082 else 1083 dns_db_detachnode(db, &node); 1084 } 1085 if (dbp != NULL) 1086 *dbp = db; 1087 else 1088 dns_db_detach(&db); 1089 } else 1090 INSIST(node == NULL); 1091 1092#ifdef BIND9 1093 if (zone != NULL) 1094 dns_zone_detach(&zone); 1095#endif 1096 1097 return (result); 1098} 1099 1100isc_result_t 1101dns_view_simplefind(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, 1102 isc_stdtime_t now, unsigned int options, 1103 isc_boolean_t use_hints, 1104 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 1105{ 1106 isc_result_t result; 1107 dns_fixedname_t foundname; 1108 1109 dns_fixedname_init(&foundname); 1110 result = dns_view_find(view, name, type, now, options, use_hints, 1111 NULL, NULL, dns_fixedname_name(&foundname), 1112 rdataset, sigrdataset); 1113 if (result == DNS_R_NXDOMAIN) { 1114 /* 1115 * The rdataset and sigrdataset of the relevant NSEC record 1116 * may be returned, but the caller cannot use them because 1117 * foundname is not returned by this simplified API. We 1118 * disassociate them here to prevent any misuse by the caller. 1119 */ 1120 if (dns_rdataset_isassociated(rdataset)) 1121 dns_rdataset_disassociate(rdataset); 1122 if (sigrdataset != NULL && 1123 dns_rdataset_isassociated(sigrdataset)) 1124 dns_rdataset_disassociate(sigrdataset); 1125 } else if (result != ISC_R_SUCCESS && 1126 result != DNS_R_GLUE && 1127 result != DNS_R_HINT && 1128 result != DNS_R_NCACHENXDOMAIN && 1129 result != DNS_R_NCACHENXRRSET && 1130 result != DNS_R_NXRRSET && 1131 result != DNS_R_HINTNXRRSET && 1132 result != ISC_R_NOTFOUND) { 1133 if (dns_rdataset_isassociated(rdataset)) 1134 dns_rdataset_disassociate(rdataset); 1135 if (sigrdataset != NULL && 1136 dns_rdataset_isassociated(sigrdataset)) 1137 dns_rdataset_disassociate(sigrdataset); 1138 result = ISC_R_NOTFOUND; 1139 } 1140 1141 return (result); 1142} 1143 1144isc_result_t 1145dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname, 1146 isc_stdtime_t now, unsigned int options, 1147 isc_boolean_t use_hints, 1148 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 1149{ 1150 return(dns_view_findzonecut2(view, name, fname, now, options, 1151 use_hints, ISC_TRUE, 1152 rdataset, sigrdataset)); 1153} 1154 1155isc_result_t 1156dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, 1157 isc_stdtime_t now, unsigned int options, 1158 isc_boolean_t use_hints, isc_boolean_t use_cache, 1159 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 1160{ 1161 isc_result_t result; 1162 dns_db_t *db; 1163 isc_boolean_t is_cache, use_zone, try_hints; 1164 dns_zone_t *zone; 1165 dns_name_t *zfname; 1166 dns_rdataset_t zrdataset, zsigrdataset; 1167 dns_fixedname_t zfixedname; 1168 1169 REQUIRE(DNS_VIEW_VALID(view)); 1170 REQUIRE(view->frozen); 1171 1172 db = NULL; 1173 zone = NULL; 1174 use_zone = ISC_FALSE; 1175 try_hints = ISC_FALSE; 1176 zfname = NULL; 1177 1178 /* 1179 * Initialize. 1180 */ 1181 dns_fixedname_init(&zfixedname); 1182 dns_rdataset_init(&zrdataset); 1183 dns_rdataset_init(&zsigrdataset); 1184 1185 /* 1186 * Find the right database. 1187 */ 1188#ifdef BIND9 1189 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); 1190 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) 1191 result = dns_zone_getdb(zone, &db); 1192#else 1193 result = ISC_R_NOTFOUND; 1194#endif 1195 if (result == ISC_R_NOTFOUND) { 1196 /* 1197 * We're not directly authoritative for this query name, nor 1198 * is it a subdomain of any zone for which we're 1199 * authoritative. 1200 */ 1201 if (use_cache && view->cachedb != NULL) { 1202 /* 1203 * We have a cache; try it. 1204 */ 1205 dns_db_attach(view->cachedb, &db); 1206 } else { 1207 /* 1208 * Maybe we have hints... 1209 */ 1210 try_hints = ISC_TRUE; 1211 goto finish; 1212 } 1213 } else if (result != ISC_R_SUCCESS) { 1214 /* 1215 * Something is broken. 1216 */ 1217 goto cleanup; 1218 } 1219 is_cache = dns_db_iscache(db); 1220 1221 db_find: 1222 /* 1223 * Look for the zonecut. 1224 */ 1225 if (!is_cache) { 1226 result = dns_db_find(db, name, NULL, dns_rdatatype_ns, options, 1227 now, NULL, fname, rdataset, sigrdataset); 1228 if (result == DNS_R_DELEGATION) 1229 result = ISC_R_SUCCESS; 1230 else if (result != ISC_R_SUCCESS) 1231 goto cleanup; 1232 if (use_cache && view->cachedb != NULL && db != view->hints) { 1233 /* 1234 * We found an answer, but the cache may be better. 1235 */ 1236 zfname = dns_fixedname_name(&zfixedname); 1237 result = dns_name_copy(fname, zfname, NULL); 1238 if (result != ISC_R_SUCCESS) 1239 goto cleanup; 1240 dns_rdataset_clone(rdataset, &zrdataset); 1241 dns_rdataset_disassociate(rdataset); 1242 if (sigrdataset != NULL && 1243 dns_rdataset_isassociated(sigrdataset)) { 1244 dns_rdataset_clone(sigrdataset, &zsigrdataset); 1245 dns_rdataset_disassociate(sigrdataset); 1246 } 1247 dns_db_detach(&db); 1248 dns_db_attach(view->cachedb, &db); 1249 is_cache = ISC_TRUE; 1250 goto db_find; 1251 } 1252 } else { 1253 result = dns_db_findzonecut(db, name, options, now, NULL, 1254 fname, rdataset, sigrdataset); 1255 if (result == ISC_R_SUCCESS) { 1256 if (zfname != NULL && 1257 (!dns_name_issubdomain(fname, zfname) || 1258 (dns_zone_staticstub && 1259 dns_name_equal(fname, zfname)))) { 1260 /* 1261 * We found a zonecut in the cache, but our 1262 * zone delegation is better. 1263 */ 1264 use_zone = ISC_TRUE; 1265 } 1266 } else if (result == ISC_R_NOTFOUND) { 1267 if (zfname != NULL) { 1268 /* 1269 * We didn't find anything in the cache, but we 1270 * have a zone delegation, so use it. 1271 */ 1272 use_zone = ISC_TRUE; 1273 } else { 1274 /* 1275 * Maybe we have hints... 1276 */ 1277 try_hints = ISC_TRUE; 1278 } 1279 } else { 1280 /* 1281 * Something bad happened. 1282 */ 1283 goto cleanup; 1284 } 1285 } 1286 1287 finish: 1288 if (use_zone) { 1289 if (dns_rdataset_isassociated(rdataset)) { 1290 dns_rdataset_disassociate(rdataset); 1291 if (sigrdataset != NULL && 1292 dns_rdataset_isassociated(sigrdataset)) 1293 dns_rdataset_disassociate(sigrdataset); 1294 } 1295 result = dns_name_copy(zfname, fname, NULL); 1296 if (result != ISC_R_SUCCESS) 1297 goto cleanup; 1298 dns_rdataset_clone(&zrdataset, rdataset); 1299 if (sigrdataset != NULL && 1300 dns_rdataset_isassociated(&zrdataset)) 1301 dns_rdataset_clone(&zsigrdataset, sigrdataset); 1302 } else if (try_hints && use_hints && view->hints != NULL) { 1303 /* 1304 * We've found nothing so far, but we have hints. 1305 */ 1306 result = dns_db_find(view->hints, dns_rootname, NULL, 1307 dns_rdatatype_ns, 0, now, NULL, fname, 1308 rdataset, NULL); 1309 if (result != ISC_R_SUCCESS) { 1310 /* 1311 * We can't even find the hints for the root 1312 * nameservers! 1313 */ 1314 if (dns_rdataset_isassociated(rdataset)) 1315 dns_rdataset_disassociate(rdataset); 1316 result = ISC_R_NOTFOUND; 1317 } 1318 } 1319 1320 cleanup: 1321 if (dns_rdataset_isassociated(&zrdataset)) { 1322 dns_rdataset_disassociate(&zrdataset); 1323 if (dns_rdataset_isassociated(&zsigrdataset)) 1324 dns_rdataset_disassociate(&zsigrdataset); 1325 } 1326 if (db != NULL) 1327 dns_db_detach(&db); 1328#ifdef BIND9 1329 if (zone != NULL) 1330 dns_zone_detach(&zone); 1331#endif 1332 1333 return (result); 1334} 1335 1336isc_result_t 1337dns_viewlist_find(dns_viewlist_t *list, const char *name, 1338 dns_rdataclass_t rdclass, dns_view_t **viewp) 1339{ 1340 dns_view_t *view; 1341 1342 REQUIRE(list != NULL); 1343 1344 for (view = ISC_LIST_HEAD(*list); 1345 view != NULL; 1346 view = ISC_LIST_NEXT(view, link)) { 1347 if (strcmp(view->name, name) == 0 && view->rdclass == rdclass) 1348 break; 1349 } 1350 if (view == NULL) 1351 return (ISC_R_NOTFOUND); 1352 1353 dns_view_attach(view, viewp); 1354 1355 return (ISC_R_SUCCESS); 1356} 1357 1358#ifdef BIND9 1359isc_result_t 1360dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name, 1361 isc_boolean_t allclasses, dns_rdataclass_t rdclass, 1362 dns_zone_t **zonep) 1363{ 1364 dns_view_t *view; 1365 isc_result_t result; 1366 dns_zone_t *zone1 = NULL, *zone2 = NULL; 1367 dns_zone_t **zp = NULL;; 1368 1369 REQUIRE(list != NULL); 1370 for (view = ISC_LIST_HEAD(*list); 1371 view != NULL; 1372 view = ISC_LIST_NEXT(view, link)) { 1373 if (allclasses == ISC_FALSE && view->rdclass != rdclass) 1374 continue; 1375 1376 /* 1377 * If the zone is defined in more than one view, 1378 * treat it as not found. 1379 */ 1380 zp = (zone1 == NULL) ? &zone1 : &zone2; 1381 result = dns_zt_find(view->zonetable, name, 0, NULL, zp); 1382 INSIST(result == ISC_R_SUCCESS || 1383 result == ISC_R_NOTFOUND || 1384 result == DNS_R_PARTIALMATCH); 1385 1386 /* Treat a partial match as no match */ 1387 if (result == DNS_R_PARTIALMATCH) { 1388 dns_zone_detach(zp); 1389 result = ISC_R_NOTFOUND; 1390 POST(result); 1391 } 1392 1393 if (zone2 != NULL) { 1394 dns_zone_detach(&zone1); 1395 dns_zone_detach(&zone2); 1396 return (ISC_R_NOTFOUND); 1397 } 1398 } 1399 1400 if (zone1 != NULL) { 1401 dns_zone_attach(zone1, zonep); 1402 dns_zone_detach(&zone1); 1403 return (ISC_R_SUCCESS); 1404 } 1405 1406 return (ISC_R_NOTFOUND); 1407} 1408 1409isc_result_t 1410dns_view_load(dns_view_t *view, isc_boolean_t stop) { 1411 1412 REQUIRE(DNS_VIEW_VALID(view)); 1413 1414 return (dns_zt_load(view->zonetable, stop)); 1415} 1416 1417isc_result_t 1418dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) { 1419 1420 REQUIRE(DNS_VIEW_VALID(view)); 1421 1422 return (dns_zt_loadnew(view->zonetable, stop)); 1423} 1424#endif /* BIND9 */ 1425 1426isc_result_t 1427dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp) 1428{ 1429 isc_result_t result; 1430 REQUIRE(keyp != NULL && *keyp == NULL); 1431 1432 result = dns_tsigkey_find(keyp, keyname, NULL, 1433 view->statickeys); 1434 if (result == ISC_R_NOTFOUND) 1435 result = dns_tsigkey_find(keyp, keyname, NULL, 1436 view->dynamickeys); 1437 return (result); 1438} 1439 1440isc_result_t 1441dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr, 1442 dns_tsigkey_t **keyp) 1443{ 1444 isc_result_t result; 1445 dns_name_t *keyname = NULL; 1446 dns_peer_t *peer = NULL; 1447 1448 result = dns_peerlist_peerbyaddr(view->peers, peeraddr, &peer); 1449 if (result != ISC_R_SUCCESS) 1450 return (result); 1451 1452 result = dns_peer_getkey(peer, &keyname); 1453 if (result != ISC_R_SUCCESS) 1454 return (result); 1455 1456 result = dns_view_gettsig(view, keyname, keyp); 1457 return ((result == ISC_R_NOTFOUND) ? ISC_R_FAILURE : result); 1458} 1459 1460isc_result_t 1461dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) { 1462 REQUIRE(DNS_VIEW_VALID(view)); 1463 REQUIRE(source != NULL); 1464 1465 return (dns_tsig_verify(source, msg, view->statickeys, 1466 view->dynamickeys)); 1467} 1468 1469#ifdef BIND9 1470isc_result_t 1471dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) { 1472 isc_result_t result; 1473 1474 REQUIRE(DNS_VIEW_VALID(view)); 1475 1476 (void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name); 1477 result = dns_master_dumptostream(view->mctx, view->cachedb, NULL, 1478 &dns_master_style_cache, fp); 1479 if (result != ISC_R_SUCCESS) 1480 return (result); 1481 dns_adb_dump(view->adb, fp); 1482 dns_resolver_printbadcache(view->resolver, fp); 1483 return (ISC_R_SUCCESS); 1484} 1485#endif 1486 1487isc_result_t 1488dns_view_flushcache(dns_view_t *view) { 1489 return (dns_view_flushcache2(view, ISC_FALSE)); 1490} 1491 1492isc_result_t 1493dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) { 1494 isc_result_t result; 1495 1496 REQUIRE(DNS_VIEW_VALID(view)); 1497 1498 if (view->cachedb == NULL) 1499 return (ISC_R_SUCCESS); 1500 if (!fixuponly) { 1501 result = dns_cache_flush(view->cache); 1502 if (result != ISC_R_SUCCESS) 1503 return (result); 1504 } 1505#ifdef BIND9 1506 if (view->acache != NULL) 1507 dns_acache_putdb(view->acache, view->cachedb); 1508#endif 1509 dns_db_detach(&view->cachedb); 1510 dns_cache_attachdb(view->cache, &view->cachedb); 1511#ifdef BIND9 1512 if (view->acache != NULL) 1513 dns_acache_setdb(view->acache, view->cachedb); 1514 if (view->resolver != NULL) 1515 dns_resolver_flushbadcache(view->resolver, NULL); 1516#endif 1517 1518 dns_adb_flush(view->adb); 1519 return (ISC_R_SUCCESS); 1520} 1521 1522isc_result_t 1523dns_view_flushname(dns_view_t *view, dns_name_t *name) { 1524 1525 REQUIRE(DNS_VIEW_VALID(view)); 1526 1527 if (view->adb != NULL) 1528 dns_adb_flushname(view->adb, name); 1529 if (view->cache == NULL) 1530 return (ISC_R_SUCCESS); 1531 if (view->resolver != NULL) 1532 dns_resolver_flushbadcache(view->resolver, name); 1533 return (dns_cache_flushname(view->cache, name)); 1534} 1535 1536isc_result_t 1537dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name) { 1538 isc_result_t result; 1539 dns_name_t *new; 1540 isc_uint32_t hash; 1541 1542 REQUIRE(DNS_VIEW_VALID(view)); 1543 1544 if (view->delonly == NULL) { 1545 view->delonly = isc_mem_get(view->mctx, 1546 sizeof(dns_namelist_t) * 1547 DNS_VIEW_DELONLYHASH); 1548 if (view->delonly == NULL) 1549 return (ISC_R_NOMEMORY); 1550 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++) 1551 ISC_LIST_INIT(view->delonly[hash]); 1552 } 1553 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1554 new = ISC_LIST_HEAD(view->delonly[hash]); 1555 while (new != NULL && !dns_name_equal(new, name)) 1556 new = ISC_LIST_NEXT(new, link); 1557 if (new != NULL) 1558 return (ISC_R_SUCCESS); 1559 new = isc_mem_get(view->mctx, sizeof(*new)); 1560 if (new == NULL) 1561 return (ISC_R_NOMEMORY); 1562 dns_name_init(new, NULL); 1563 result = dns_name_dup(name, view->mctx, new); 1564 if (result == ISC_R_SUCCESS) 1565 ISC_LIST_APPEND(view->delonly[hash], new, link); 1566 else 1567 isc_mem_put(view->mctx, new, sizeof(*new)); 1568 return (result); 1569} 1570 1571isc_result_t 1572dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name) { 1573 isc_result_t result; 1574 dns_name_t *new; 1575 isc_uint32_t hash; 1576 1577 REQUIRE(DNS_VIEW_VALID(view)); 1578 1579 if (view->rootexclude == NULL) { 1580 view->rootexclude = isc_mem_get(view->mctx, 1581 sizeof(dns_namelist_t) * 1582 DNS_VIEW_DELONLYHASH); 1583 if (view->rootexclude == NULL) 1584 return (ISC_R_NOMEMORY); 1585 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++) 1586 ISC_LIST_INIT(view->rootexclude[hash]); 1587 } 1588 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1589 new = ISC_LIST_HEAD(view->rootexclude[hash]); 1590 while (new != NULL && !dns_name_equal(new, name)) 1591 new = ISC_LIST_NEXT(new, link); 1592 if (new != NULL) 1593 return (ISC_R_SUCCESS); 1594 new = isc_mem_get(view->mctx, sizeof(*new)); 1595 if (new == NULL) 1596 return (ISC_R_NOMEMORY); 1597 dns_name_init(new, NULL); 1598 result = dns_name_dup(name, view->mctx, new); 1599 if (result == ISC_R_SUCCESS) 1600 ISC_LIST_APPEND(view->rootexclude[hash], new, link); 1601 else 1602 isc_mem_put(view->mctx, new, sizeof(*new)); 1603 return (result); 1604} 1605 1606isc_boolean_t 1607dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name) { 1608 dns_name_t *new; 1609 isc_uint32_t hash; 1610 1611 REQUIRE(DNS_VIEW_VALID(view)); 1612 1613 if (!view->rootdelonly && view->delonly == NULL) 1614 return (ISC_FALSE); 1615 1616 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1617 if (view->rootdelonly && dns_name_countlabels(name) <= 2) { 1618 if (view->rootexclude == NULL) 1619 return (ISC_TRUE); 1620 new = ISC_LIST_HEAD(view->rootexclude[hash]); 1621 while (new != NULL && !dns_name_equal(new, name)) 1622 new = ISC_LIST_NEXT(new, link); 1623 if (new == NULL) 1624 return (ISC_TRUE); 1625 } 1626 1627 if (view->delonly == NULL) 1628 return (ISC_FALSE); 1629 1630 new = ISC_LIST_HEAD(view->delonly[hash]); 1631 while (new != NULL && !dns_name_equal(new, name)) 1632 new = ISC_LIST_NEXT(new, link); 1633 if (new == NULL) 1634 return (ISC_FALSE); 1635 return (ISC_TRUE); 1636} 1637 1638void 1639dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value) { 1640 REQUIRE(DNS_VIEW_VALID(view)); 1641 view->rootdelonly = value; 1642} 1643 1644isc_boolean_t 1645dns_view_getrootdelonly(dns_view_t *view) { 1646 REQUIRE(DNS_VIEW_VALID(view)); 1647 return (view->rootdelonly); 1648} 1649 1650#ifdef BIND9 1651isc_result_t 1652dns_view_freezezones(dns_view_t *view, isc_boolean_t value) { 1653 REQUIRE(DNS_VIEW_VALID(view)); 1654 return (dns_zt_freezezones(view->zonetable, value)); 1655} 1656#endif 1657 1658void 1659dns_view_setresstats(dns_view_t *view, isc_stats_t *stats) { 1660 REQUIRE(DNS_VIEW_VALID(view)); 1661 REQUIRE(!view->frozen); 1662 REQUIRE(view->resstats == NULL); 1663 1664 isc_stats_attach(stats, &view->resstats); 1665} 1666 1667void 1668dns_view_getresstats(dns_view_t *view, isc_stats_t **statsp) { 1669 REQUIRE(DNS_VIEW_VALID(view)); 1670 REQUIRE(statsp != NULL && *statsp == NULL); 1671 1672 if (view->resstats != NULL) 1673 isc_stats_attach(view->resstats, statsp); 1674} 1675 1676void 1677dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats) { 1678 REQUIRE(DNS_VIEW_VALID(view)); 1679 REQUIRE(!view->frozen); 1680 REQUIRE(view->resquerystats == NULL); 1681 1682 dns_stats_attach(stats, &view->resquerystats); 1683} 1684 1685void 1686dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp) { 1687 REQUIRE(DNS_VIEW_VALID(view)); 1688 REQUIRE(statsp != NULL && *statsp == NULL); 1689 1690 if (view->resquerystats != NULL) 1691 dns_stats_attach(view->resquerystats, statsp); 1692} 1693 1694isc_result_t 1695dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx) { 1696 REQUIRE(DNS_VIEW_VALID(view)); 1697 if (view->secroots_priv != NULL) 1698 dns_keytable_detach(&view->secroots_priv); 1699 return (dns_keytable_create(mctx, &view->secroots_priv)); 1700} 1701 1702isc_result_t 1703dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp) { 1704 REQUIRE(DNS_VIEW_VALID(view)); 1705 REQUIRE(ktp != NULL && *ktp == NULL); 1706 if (view->secroots_priv == NULL) 1707 return (ISC_R_NOTFOUND); 1708 dns_keytable_attach(view->secroots_priv, ktp); 1709 return (ISC_R_SUCCESS); 1710} 1711 1712isc_result_t 1713dns_view_issecuredomain(dns_view_t *view, dns_name_t *name, 1714 isc_boolean_t *secure_domain) { 1715 REQUIRE(DNS_VIEW_VALID(view)); 1716 1717 if (view->secroots_priv == NULL) 1718 return (ISC_R_NOTFOUND); 1719 return (dns_keytable_issecuredomain(view->secroots_priv, name, 1720 secure_domain)); 1721} 1722 1723void 1724dns_view_untrust(dns_view_t *view, dns_name_t *keyname, 1725 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) 1726{ 1727 isc_result_t result; 1728 unsigned char data[4096]; 1729 dns_rdata_t rdata = DNS_RDATA_INIT; 1730 isc_buffer_t buffer; 1731 dst_key_t *key = NULL; 1732 dns_keytable_t *sr = NULL; 1733 1734 /* 1735 * Clear the revoke bit, if set, so that the key will match what's 1736 * in secroots now. 1737 */ 1738 dnskey->flags &= ~DNS_KEYFLAG_REVOKE; 1739 1740 /* Convert dnskey to DST key. */ 1741 isc_buffer_init(&buffer, data, sizeof(data)); 1742 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 1743 dns_rdatatype_dnskey, dnskey, &buffer); 1744 result = dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &key); 1745 if (result != ISC_R_SUCCESS) 1746 return; 1747 result = dns_view_getsecroots(view, &sr); 1748 if (result == ISC_R_SUCCESS) { 1749 dns_keytable_deletekeynode(sr, key); 1750 dns_keytable_detach(&sr); 1751 } 1752 dst_key_free(&key); 1753} 1754 1755#define NZF ".nzf" 1756 1757void 1758dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx, 1759 void (*cfg_destroy)(void **)) 1760{ 1761 REQUIRE(DNS_VIEW_VALID(view)); 1762 REQUIRE((cfgctx != NULL && cfg_destroy != NULL) || !allow); 1763 1764#ifdef BIND9 1765 if (view->new_zone_file != NULL) { 1766 isc_mem_free(view->mctx, view->new_zone_file); 1767 view->new_zone_file = NULL; 1768 } 1769 1770 if (view->new_zone_config != NULL) { 1771 view->cfg_destroy(&view->new_zone_config); 1772 view->cfg_destroy = NULL; 1773 } 1774 1775 if (allow) { 1776 char buffer[ISC_SHA256_DIGESTSTRINGLENGTH + sizeof(NZF)]; 1777 isc_sha256_data((void *)view->name, strlen(view->name), buffer); 1778 /* Truncate the hash at 16 chars; full length is overkill */ 1779 isc_string_printf(buffer + 16, sizeof(NZF), "%s", NZF); 1780 view->new_zone_file = isc_mem_strdup(view->mctx, buffer); 1781 view->new_zone_config = cfgctx; 1782 view->cfg_destroy = cfg_destroy; 1783 } 1784#else 1785 UNUSED(allow); 1786 UNUSED(cfgctx); 1787 UNUSED(cfg_destroy); 1788#endif 1789} 1790