1 /* $NetBSD: view.c,v 1.2 2018/08/12 13:02:35 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 /*! \file */ 15 16 #include <config.h> 17 18 #include <limits.h> 19 20 #ifdef HAVE_LMDB 21 #include <lmdb.h> 22 #endif 23 24 #include <isc/file.h> 25 #include <isc/hash.h> 26 #include <isc/lex.h> 27 #include <isc/print.h> 28 #include <isc/sha2.h> 29 #include <isc/stats.h> 30 #include <isc/string.h> /* Required for HP/UX (and others?) */ 31 #include <isc/task.h> 32 #include <isc/util.h> 33 34 #include <dns/acl.h> 35 #include <dns/adb.h> 36 #include <dns/badcache.h> 37 #include <dns/cache.h> 38 #include <dns/db.h> 39 #include <dns/dispatch.h> 40 #include <dns/dlz.h> 41 #include <dns/dns64.h> 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/nta.h> 50 #include <dns/order.h> 51 #include <dns/peer.h> 52 #include <dns/rbt.h> 53 #include <dns/rdataset.h> 54 #include <dns/request.h> 55 #include <dns/resolver.h> 56 #include <dns/result.h> 57 #include <dns/rpz.h> 58 #include <dns/rrl.h> 59 #include <dns/stats.h> 60 #include <dns/time.h> 61 #include <dns/tsig.h> 62 #include <dns/zone.h> 63 #include <dns/zt.h> 64 65 #define CHECK(op) \ 66 do { result = (op); \ 67 if (result != ISC_R_SUCCESS) goto cleanup; \ 68 } while (0) 69 70 #define RESSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_RESSHUTDOWN) != 0) 71 #define ADBSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_ADBSHUTDOWN) != 0) 72 #define REQSHUTDOWN(v) (((v)->attributes & DNS_VIEWATTR_REQSHUTDOWN) != 0) 73 74 #define DNS_VIEW_DELONLYHASH 111 75 #define DNS_VIEW_FAILCACHESIZE 1021 76 77 static void resolver_shutdown(isc_task_t *task, isc_event_t *event); 78 static void adb_shutdown(isc_task_t *task, isc_event_t *event); 79 static void req_shutdown(isc_task_t *task, isc_event_t *event); 80 81 isc_result_t 82 dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, 83 const char *name, dns_view_t **viewp) 84 { 85 dns_view_t *view; 86 isc_result_t result; 87 char buffer[1024]; 88 89 /* 90 * Create a view. 91 */ 92 93 REQUIRE(name != NULL); 94 REQUIRE(viewp != NULL && *viewp == NULL); 95 96 view = isc_mem_get(mctx, sizeof(*view)); 97 if (view == NULL) 98 return (ISC_R_NOMEMORY); 99 100 view->nta_file = NULL; 101 view->mctx = NULL; 102 isc_mem_attach(mctx, &view->mctx); 103 view->name = isc_mem_strdup(mctx, name); 104 if (view->name == NULL) { 105 result = ISC_R_NOMEMORY; 106 goto cleanup_view; 107 } 108 109 result = isc_file_sanitize(NULL, view->name, "nta", 110 buffer, sizeof(buffer)); 111 if (result != ISC_R_SUCCESS) 112 goto cleanup_name; 113 view->nta_file = isc_mem_strdup(mctx, buffer); 114 if (view->nta_file == NULL) { 115 result = ISC_R_NOMEMORY; 116 goto cleanup_name; 117 } 118 119 result = isc_mutex_init(&view->lock); 120 if (result != ISC_R_SUCCESS) 121 goto cleanup_name; 122 123 view->zonetable = NULL; 124 if (isc_bind9) { 125 result = dns_zt_create(mctx, rdclass, &view->zonetable); 126 if (result != ISC_R_SUCCESS) { 127 UNEXPECTED_ERROR(__FILE__, __LINE__, 128 "dns_zt_create() failed: %s", 129 isc_result_totext(result)); 130 result = ISC_R_UNEXPECTED; 131 goto cleanup_mutex; 132 } 133 } 134 view->secroots_priv = NULL; 135 view->ntatable_priv = NULL; 136 view->fwdtable = NULL; 137 result = dns_fwdtable_create(mctx, &view->fwdtable); 138 if (result != ISC_R_SUCCESS) { 139 UNEXPECTED_ERROR(__FILE__, __LINE__, 140 "dns_fwdtable_create() failed: %s", 141 isc_result_totext(result)); 142 result = ISC_R_UNEXPECTED; 143 goto cleanup_zt; 144 } 145 146 view->cache = NULL; 147 view->cachedb = NULL; 148 ISC_LIST_INIT(view->dlz_searched); 149 ISC_LIST_INIT(view->dlz_unsearched); 150 view->hints = NULL; 151 view->resolver = NULL; 152 view->adb = NULL; 153 view->requestmgr = NULL; 154 view->rdclass = rdclass; 155 view->frozen = ISC_FALSE; 156 view->task = NULL; 157 result = isc_refcount_init(&view->references, 1); 158 if (result != ISC_R_SUCCESS) 159 goto cleanup_fwdtable; 160 view->weakrefs = 0; 161 view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN| 162 DNS_VIEWATTR_REQSHUTDOWN); 163 view->statickeys = NULL; 164 view->dynamickeys = NULL; 165 view->matchclients = NULL; 166 view->matchdestinations = NULL; 167 view->matchrecursiveonly = ISC_FALSE; 168 result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys); 169 if (result != ISC_R_SUCCESS) 170 goto cleanup_references; 171 view->peers = NULL; 172 view->order = NULL; 173 view->delonly = NULL; 174 view->rootdelonly = ISC_FALSE; 175 view->rootexclude = NULL; 176 view->adbstats = NULL; 177 view->resstats = NULL; 178 view->resquerystats = NULL; 179 view->cacheshared = ISC_FALSE; 180 ISC_LIST_INIT(view->dns64); 181 view->dns64cnt = 0; 182 183 /* 184 * Initialize configuration data with default values. 185 */ 186 view->recursion = ISC_TRUE; 187 view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */ 188 view->enablednssec = ISC_TRUE; 189 view->enablevalidation = ISC_TRUE; 190 view->acceptexpired = ISC_FALSE; 191 view->use_glue_cache = ISC_FALSE; 192 view->minimal_any = ISC_FALSE; 193 view->minimalresponses = dns_minimal_no; 194 view->transfer_format = dns_one_answer; 195 view->cacheacl = NULL; 196 view->cacheonacl = NULL; 197 view->queryacl = NULL; 198 view->queryonacl = NULL; 199 view->recursionacl = NULL; 200 view->recursiononacl = NULL; 201 view->sortlist = NULL; 202 view->transferacl = NULL; 203 view->notifyacl = NULL; 204 view->updateacl = NULL; 205 view->upfwdacl = NULL; 206 view->denyansweracl = NULL; 207 view->nocasecompress = NULL; 208 view->msgcompression = ISC_TRUE; 209 view->answeracl_exclude = NULL; 210 view->denyanswernames = NULL; 211 view->answernames_exclude = NULL; 212 view->rrl = NULL; 213 view->provideixfr = ISC_TRUE; 214 view->maxcachettl = 7 * 24 * 3600; 215 view->maxncachettl = 3 * 3600; 216 view->nta_lifetime = 0; 217 view->nta_recheck = 0; 218 view->prefetch_eligible = 0; 219 view->prefetch_trigger = 0; 220 view->dstport = 53; 221 view->preferred_glue = 0; 222 view->flush = ISC_FALSE; 223 view->dlv = NULL; 224 view->maxudp = 0; 225 view->staleanswerttl = 1; 226 view->staleanswersok = dns_stale_answer_conf; 227 view->staleanswersenable = ISC_FALSE; 228 view->nocookieudp = 0; 229 view->padding = 0; 230 view->pad_acl = NULL; 231 view->maxbits = 0; 232 view->v4_aaaa = dns_aaaa_ok; 233 view->v6_aaaa = dns_aaaa_ok; 234 view->aaaa_acl = NULL; 235 view->rpzs = NULL; 236 view->catzs = NULL; 237 dns_fixedname_init(&view->dlv_fixed); 238 view->managed_keys = NULL; 239 view->redirect = NULL; 240 view->redirectzone = NULL; 241 dns_fixedname_init(&view->redirectfixed); 242 view->requestnsid = ISC_FALSE; 243 view->sendcookie = ISC_TRUE; 244 view->requireservercookie = ISC_FALSE; 245 view->synthfromdnssec = ISC_TRUE; 246 view->trust_anchor_telemetry = ISC_TRUE; 247 view->root_key_sentinel = ISC_TRUE; 248 view->new_zone_dir = NULL; 249 view->new_zone_file = NULL; 250 view->new_zone_db = NULL; 251 view->new_zone_dbenv = NULL; 252 view->new_zone_mapsize = 0ULL; 253 view->new_zone_config = NULL; 254 view->cfg_destroy = NULL; 255 view->fail_ttl = 0; 256 view->failcache = NULL; 257 (void)dns_badcache_init(view->mctx, DNS_VIEW_FAILCACHESIZE, 258 &view->failcache); 259 view->v6bias = 0; 260 view->dtenv = NULL; 261 view->dttypes = 0; 262 263 result = isc_mutex_init(&view->new_zone_lock); 264 if (result != ISC_R_SUCCESS) 265 goto cleanup_dynkeys; 266 267 if (isc_bind9) { 268 result = dns_order_create(view->mctx, &view->order); 269 if (result != ISC_R_SUCCESS) 270 goto cleanup_new_zone_lock; 271 } 272 273 result = dns_peerlist_new(view->mctx, &view->peers); 274 if (result != ISC_R_SUCCESS) 275 goto cleanup_order; 276 277 result = dns_aclenv_init(view->mctx, &view->aclenv); 278 if (result != ISC_R_SUCCESS) 279 goto cleanup_peerlist; 280 281 ISC_LINK_INIT(view, link); 282 ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL, 283 DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown, 284 view, NULL, NULL, NULL); 285 ISC_EVENT_INIT(&view->adbevent, sizeof(view->adbevent), 0, NULL, 286 DNS_EVENT_VIEWADBSHUTDOWN, adb_shutdown, 287 view, NULL, NULL, NULL); 288 ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL, 289 DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown, 290 view, NULL, NULL, NULL); 291 view->viewlist = NULL; 292 view->magic = DNS_VIEW_MAGIC; 293 294 *viewp = view; 295 296 return (ISC_R_SUCCESS); 297 298 cleanup_peerlist: 299 if (view->peers != NULL) 300 dns_peerlist_detach(&view->peers); 301 302 cleanup_order: 303 if (view->order != NULL) 304 dns_order_detach(&view->order); 305 306 cleanup_new_zone_lock: 307 DESTROYLOCK(&view->new_zone_lock); 308 309 cleanup_dynkeys: 310 if (view->dynamickeys != NULL) 311 dns_tsigkeyring_detach(&view->dynamickeys); 312 313 cleanup_references: 314 isc_refcount_destroy(&view->references); 315 316 cleanup_fwdtable: 317 if (view->fwdtable != NULL) 318 dns_fwdtable_destroy(&view->fwdtable); 319 320 cleanup_zt: 321 if (view->zonetable != NULL) 322 dns_zt_detach(&view->zonetable); 323 324 cleanup_mutex: 325 DESTROYLOCK(&view->lock); 326 327 if (view->nta_file != NULL) 328 isc_mem_free(mctx, view->nta_file); 329 330 cleanup_name: 331 isc_mem_free(mctx, view->name); 332 333 cleanup_view: 334 isc_mem_putanddetach(&view->mctx, view, sizeof(*view)); 335 336 return (result); 337 } 338 339 static inline void 340 destroy(dns_view_t *view) { 341 dns_dns64_t *dns64; 342 dns_dlzdb_t *dlzdb; 343 344 REQUIRE(!ISC_LINK_LINKED(view, link)); 345 REQUIRE(isc_refcount_current(&view->references) == 0); 346 REQUIRE(view->weakrefs == 0); 347 REQUIRE(RESSHUTDOWN(view)); 348 REQUIRE(ADBSHUTDOWN(view)); 349 REQUIRE(REQSHUTDOWN(view)); 350 351 if (view->order != NULL) 352 dns_order_detach(&view->order); 353 if (view->peers != NULL) 354 dns_peerlist_detach(&view->peers); 355 356 if (view->dynamickeys != NULL) { 357 isc_result_t result; 358 char template[PATH_MAX]; 359 char keyfile[PATH_MAX]; 360 FILE *fp = NULL; 361 362 result = isc_file_mktemplate(NULL, template, sizeof(template)); 363 if (result == ISC_R_SUCCESS) { 364 (void)isc_file_openuniqueprivate(template, &fp); 365 } 366 if (fp == NULL) { 367 dns_tsigkeyring_detach(&view->dynamickeys); 368 } else { 369 result = dns_tsigkeyring_dumpanddetach 370 (&view->dynamickeys, fp); 371 if (result == ISC_R_SUCCESS) { 372 if (fclose(fp) == 0) { 373 result = isc_file_sanitize 374 (NULL, view->name, "tsigkeys", 375 keyfile, sizeof(keyfile)); 376 if (result == ISC_R_SUCCESS) 377 result = isc_file_rename 378 (template, keyfile); 379 } 380 if (result != ISC_R_SUCCESS) 381 (void)remove(template); 382 } else { 383 (void)fclose(fp); 384 (void)remove(template); 385 } 386 } 387 } 388 if (view->statickeys != NULL) 389 dns_tsigkeyring_detach(&view->statickeys); 390 if (view->adb != NULL) 391 dns_adb_detach(&view->adb); 392 if (view->resolver != NULL) 393 dns_resolver_detach(&view->resolver); 394 dns_rrl_view_destroy(view); 395 if (view->rpzs != NULL) 396 dns_rpz_detach_rpzs(&view->rpzs); 397 if (view->catzs != NULL) 398 dns_catz_catzs_detach(&view->catzs); 399 for (dlzdb = ISC_LIST_HEAD(view->dlz_searched); 400 dlzdb != NULL; 401 dlzdb = ISC_LIST_HEAD(view->dlz_searched)) { 402 ISC_LIST_UNLINK(view->dlz_searched, dlzdb, link); 403 dns_dlzdestroy(&dlzdb); 404 } 405 for (dlzdb = ISC_LIST_HEAD(view->dlz_unsearched); 406 dlzdb != NULL; 407 dlzdb = ISC_LIST_HEAD(view->dlz_unsearched)) { 408 ISC_LIST_UNLINK(view->dlz_unsearched, dlzdb, link); 409 dns_dlzdestroy(&dlzdb); 410 } 411 if (view->requestmgr != NULL) 412 dns_requestmgr_detach(&view->requestmgr); 413 if (view->task != NULL) 414 isc_task_detach(&view->task); 415 if (view->hints != NULL) 416 dns_db_detach(&view->hints); 417 if (view->cachedb != NULL) 418 dns_db_detach(&view->cachedb); 419 if (view->cache != NULL) 420 dns_cache_detach(&view->cache); 421 if (view->nocasecompress != NULL) 422 dns_acl_detach(&view->nocasecompress); 423 if (view->matchclients != NULL) 424 dns_acl_detach(&view->matchclients); 425 if (view->matchdestinations != NULL) 426 dns_acl_detach(&view->matchdestinations); 427 if (view->cacheacl != NULL) 428 dns_acl_detach(&view->cacheacl); 429 if (view->cacheonacl != NULL) 430 dns_acl_detach(&view->cacheonacl); 431 if (view->queryacl != NULL) 432 dns_acl_detach(&view->queryacl); 433 if (view->queryonacl != NULL) 434 dns_acl_detach(&view->queryonacl); 435 if (view->recursionacl != NULL) 436 dns_acl_detach(&view->recursionacl); 437 if (view->recursiononacl != NULL) 438 dns_acl_detach(&view->recursiononacl); 439 if (view->sortlist != NULL) 440 dns_acl_detach(&view->sortlist); 441 if (view->transferacl != NULL) 442 dns_acl_detach(&view->transferacl); 443 if (view->notifyacl != NULL) 444 dns_acl_detach(&view->notifyacl); 445 if (view->updateacl != NULL) 446 dns_acl_detach(&view->updateacl); 447 if (view->upfwdacl != NULL) 448 dns_acl_detach(&view->upfwdacl); 449 if (view->denyansweracl != NULL) 450 dns_acl_detach(&view->denyansweracl); 451 if (view->aaaa_acl != NULL) 452 dns_acl_detach(&view->aaaa_acl); 453 if (view->pad_acl != NULL) 454 dns_acl_detach(&view->pad_acl); 455 if (view->answeracl_exclude != NULL) 456 dns_rbt_destroy(&view->answeracl_exclude); 457 if (view->denyanswernames != NULL) 458 dns_rbt_destroy(&view->denyanswernames); 459 if (view->answernames_exclude != NULL) 460 dns_rbt_destroy(&view->answernames_exclude); 461 if (view->delonly != NULL) { 462 dns_name_t *name; 463 int i; 464 465 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) { 466 name = ISC_LIST_HEAD(view->delonly[i]); 467 while (name != NULL) { 468 ISC_LIST_UNLINK(view->delonly[i], name, link); 469 dns_name_free(name, view->mctx); 470 isc_mem_put(view->mctx, name, sizeof(*name)); 471 name = ISC_LIST_HEAD(view->delonly[i]); 472 } 473 } 474 isc_mem_put(view->mctx, view->delonly, sizeof(dns_namelist_t) * 475 DNS_VIEW_DELONLYHASH); 476 view->delonly = NULL; 477 } 478 if (view->rootexclude != NULL) { 479 dns_name_t *name; 480 int i; 481 482 for (i = 0; i < DNS_VIEW_DELONLYHASH; i++) { 483 name = ISC_LIST_HEAD(view->rootexclude[i]); 484 while (name != NULL) { 485 ISC_LIST_UNLINK(view->rootexclude[i], 486 name, link); 487 dns_name_free(name, view->mctx); 488 isc_mem_put(view->mctx, name, sizeof(*name)); 489 name = ISC_LIST_HEAD(view->rootexclude[i]); 490 } 491 } 492 isc_mem_put(view->mctx, view->rootexclude, 493 sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH); 494 view->rootexclude = NULL; 495 } 496 if (view->adbstats != NULL) 497 isc_stats_detach(&view->adbstats); 498 if (view->resstats != NULL) 499 isc_stats_detach(&view->resstats); 500 if (view->resquerystats != NULL) 501 dns_stats_detach(&view->resquerystats); 502 if (view->secroots_priv != NULL) 503 dns_keytable_detach(&view->secroots_priv); 504 if (view->ntatable_priv != NULL) 505 dns_ntatable_detach(&view->ntatable_priv); 506 for (dns64 = ISC_LIST_HEAD(view->dns64); 507 dns64 != NULL; 508 dns64 = ISC_LIST_HEAD(view->dns64)) { 509 dns_dns64_unlink(&view->dns64, dns64); 510 dns_dns64_destroy(&dns64); 511 } 512 if (view->managed_keys != NULL) 513 dns_zone_detach(&view->managed_keys); 514 if (view->redirect != NULL) 515 dns_zone_detach(&view->redirect); 516 #ifdef HAVE_DNSTAP 517 if (view->dtenv != NULL) 518 dns_dt_detach(&view->dtenv); 519 #endif /* HAVE_DNSTAP */ 520 dns_view_setnewzones(view, ISC_FALSE, NULL, NULL, 0ULL); 521 if (view->new_zone_file != NULL) { 522 isc_mem_free(view->mctx, view->new_zone_file); 523 view->new_zone_file = NULL; 524 } 525 if (view->new_zone_dir != NULL) { 526 isc_mem_free(view->mctx, view->new_zone_dir); 527 view->new_zone_dir = NULL; 528 } 529 #ifdef HAVE_LMDB 530 if (view->new_zone_dbenv != NULL) { 531 mdb_env_close((MDB_env *) view->new_zone_dbenv); 532 view->new_zone_dbenv = NULL; 533 } 534 if (view->new_zone_db != NULL) { 535 isc_mem_free(view->mctx, view->new_zone_db); 536 view->new_zone_db = NULL; 537 } 538 #endif /* HAVE_LMDB */ 539 dns_fwdtable_destroy(&view->fwdtable); 540 dns_aclenv_destroy(&view->aclenv); 541 if (view->failcache != NULL) 542 dns_badcache_destroy(&view->failcache); 543 DESTROYLOCK(&view->new_zone_lock); 544 DESTROYLOCK(&view->lock); 545 isc_refcount_destroy(&view->references); 546 isc_mem_free(view->mctx, view->nta_file); 547 isc_mem_free(view->mctx, view->name); 548 isc_mem_putanddetach(&view->mctx, view, sizeof(*view)); 549 } 550 551 /* 552 * Return true iff 'view' may be freed. 553 * The caller must be holding the view lock. 554 */ 555 static isc_boolean_t 556 all_done(dns_view_t *view) { 557 558 if (isc_refcount_current(&view->references) == 0 && 559 view->weakrefs == 0 && 560 RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view)) 561 return (ISC_TRUE); 562 563 return (ISC_FALSE); 564 } 565 566 void 567 dns_view_attach(dns_view_t *source, dns_view_t **targetp) { 568 569 REQUIRE(DNS_VIEW_VALID(source)); 570 REQUIRE(targetp != NULL && *targetp == NULL); 571 572 isc_refcount_increment(&source->references, NULL); 573 574 *targetp = source; 575 } 576 577 static void 578 view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { 579 dns_view_t *view; 580 unsigned int refs; 581 isc_boolean_t done = ISC_FALSE; 582 583 REQUIRE(viewp != NULL); 584 view = *viewp; 585 REQUIRE(DNS_VIEW_VALID(view)); 586 587 if (flush) 588 view->flush = ISC_TRUE; 589 isc_refcount_decrement(&view->references, &refs); 590 if (refs == 0) { 591 dns_zone_t *mkzone = NULL, *rdzone = NULL; 592 593 LOCK(&view->lock); 594 if (!RESSHUTDOWN(view)) 595 dns_resolver_shutdown(view->resolver); 596 if (!ADBSHUTDOWN(view)) 597 dns_adb_shutdown(view->adb); 598 if (!REQSHUTDOWN(view)) 599 dns_requestmgr_shutdown(view->requestmgr); 600 if (view->zonetable != NULL) { 601 if (view->flush) 602 dns_zt_flushanddetach(&view->zonetable); 603 else 604 dns_zt_detach(&view->zonetable); 605 } 606 if (view->managed_keys != NULL) { 607 mkzone = view->managed_keys; 608 view->managed_keys = NULL; 609 if (view->flush) 610 dns_zone_flush(mkzone); 611 } 612 if (view->redirect != NULL) { 613 rdzone = view->redirect; 614 view->redirect = NULL; 615 if (view->flush) 616 dns_zone_flush(rdzone); 617 } 618 if (view->catzs != NULL) { 619 dns_catz_catzs_detach(&view->catzs); 620 } 621 done = all_done(view); 622 UNLOCK(&view->lock); 623 624 /* Need to detach zones outside view lock */ 625 if (mkzone != NULL) 626 dns_zone_detach(&mkzone); 627 628 if (rdzone != NULL) 629 dns_zone_detach(&rdzone); 630 } 631 632 *viewp = NULL; 633 634 if (done) 635 destroy(view); 636 } 637 638 void 639 dns_view_flushanddetach(dns_view_t **viewp) { 640 view_flushanddetach(viewp, ISC_TRUE); 641 } 642 643 void 644 dns_view_detach(dns_view_t **viewp) { 645 view_flushanddetach(viewp, ISC_FALSE); 646 } 647 648 static isc_result_t 649 dialup(dns_zone_t *zone, void *dummy) { 650 UNUSED(dummy); 651 dns_zone_dialup(zone); 652 return (ISC_R_SUCCESS); 653 } 654 655 void 656 dns_view_dialup(dns_view_t *view) { 657 REQUIRE(DNS_VIEW_VALID(view)); 658 REQUIRE(view->zonetable != NULL); 659 660 (void)dns_zt_apply(view->zonetable, ISC_FALSE, dialup, NULL); 661 } 662 663 void 664 dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) { 665 666 REQUIRE(DNS_VIEW_VALID(source)); 667 REQUIRE(targetp != NULL && *targetp == NULL); 668 669 LOCK(&source->lock); 670 source->weakrefs++; 671 UNLOCK(&source->lock); 672 673 *targetp = source; 674 } 675 676 void 677 dns_view_weakdetach(dns_view_t **viewp) { 678 dns_view_t *view; 679 isc_boolean_t done = ISC_FALSE; 680 681 REQUIRE(viewp != NULL); 682 view = *viewp; 683 REQUIRE(DNS_VIEW_VALID(view)); 684 685 LOCK(&view->lock); 686 687 INSIST(view->weakrefs > 0); 688 view->weakrefs--; 689 done = all_done(view); 690 691 UNLOCK(&view->lock); 692 693 *viewp = NULL; 694 695 if (done) 696 destroy(view); 697 } 698 699 static void 700 resolver_shutdown(isc_task_t *task, isc_event_t *event) { 701 dns_view_t *view = event->ev_arg; 702 isc_boolean_t done; 703 704 REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN); 705 REQUIRE(DNS_VIEW_VALID(view)); 706 REQUIRE(view->task == task); 707 708 UNUSED(task); 709 710 isc_event_free(&event); 711 712 LOCK(&view->lock); 713 714 view->attributes |= DNS_VIEWATTR_RESSHUTDOWN; 715 done = all_done(view); 716 717 UNLOCK(&view->lock); 718 719 if (done) 720 destroy(view); 721 } 722 723 static void 724 adb_shutdown(isc_task_t *task, isc_event_t *event) { 725 dns_view_t *view = event->ev_arg; 726 isc_boolean_t done; 727 728 REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN); 729 REQUIRE(DNS_VIEW_VALID(view)); 730 REQUIRE(view->task == task); 731 732 UNUSED(task); 733 734 isc_event_free(&event); 735 736 LOCK(&view->lock); 737 738 view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN; 739 done = all_done(view); 740 741 UNLOCK(&view->lock); 742 743 if (done) 744 destroy(view); 745 } 746 747 static void 748 req_shutdown(isc_task_t *task, isc_event_t *event) { 749 dns_view_t *view = event->ev_arg; 750 isc_boolean_t done; 751 752 REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN); 753 REQUIRE(DNS_VIEW_VALID(view)); 754 REQUIRE(view->task == task); 755 756 UNUSED(task); 757 758 isc_event_free(&event); 759 760 LOCK(&view->lock); 761 762 view->attributes |= DNS_VIEWATTR_REQSHUTDOWN; 763 done = all_done(view); 764 765 UNLOCK(&view->lock); 766 767 if (done) 768 destroy(view); 769 } 770 771 isc_result_t 772 dns_view_createzonetable(dns_view_t *view) { 773 774 REQUIRE(DNS_VIEW_VALID(view)); 775 REQUIRE(!view->frozen); 776 REQUIRE(view->zonetable == NULL); 777 778 return (dns_zt_create(view->mctx, view->rdclass, &view->zonetable)); 779 } 780 781 isc_result_t 782 dns_view_createresolver(dns_view_t *view, 783 isc_taskmgr_t *taskmgr, 784 unsigned int ntasks, 785 unsigned int ndisp, 786 isc_socketmgr_t *socketmgr, 787 isc_timermgr_t *timermgr, 788 unsigned int options, 789 dns_dispatchmgr_t *dispatchmgr, 790 dns_dispatch_t *dispatchv4, 791 dns_dispatch_t *dispatchv6) 792 { 793 isc_result_t result; 794 isc_event_t *event; 795 isc_mem_t *mctx = NULL; 796 797 REQUIRE(DNS_VIEW_VALID(view)); 798 REQUIRE(!view->frozen); 799 REQUIRE(view->resolver == NULL); 800 801 result = isc_task_create(taskmgr, 0, &view->task); 802 if (result != ISC_R_SUCCESS) 803 return (result); 804 isc_task_setname(view->task, "view", view); 805 806 result = dns_resolver_create(view, taskmgr, ntasks, ndisp, socketmgr, 807 timermgr, options, dispatchmgr, 808 dispatchv4, dispatchv6, 809 &view->resolver); 810 if (result != ISC_R_SUCCESS) { 811 isc_task_detach(&view->task); 812 return (result); 813 } 814 event = &view->resevent; 815 dns_resolver_whenshutdown(view->resolver, view->task, &event); 816 view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN; 817 818 result = isc_mem_create(0, 0, &mctx); 819 if (result != ISC_R_SUCCESS) { 820 dns_resolver_shutdown(view->resolver); 821 return (result); 822 } 823 824 result = dns_adb_create(mctx, view, timermgr, taskmgr, &view->adb); 825 isc_mem_setname(mctx, "ADB", NULL); 826 isc_mem_detach(&mctx); 827 if (result != ISC_R_SUCCESS) { 828 dns_resolver_shutdown(view->resolver); 829 return (result); 830 } 831 event = &view->adbevent; 832 dns_adb_whenshutdown(view->adb, view->task, &event); 833 view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN; 834 835 result = dns_requestmgr_create(view->mctx, timermgr, socketmgr, 836 dns_resolver_taskmgr(view->resolver), 837 dns_resolver_dispatchmgr(view->resolver), 838 dispatchv4, dispatchv6, 839 &view->requestmgr); 840 if (result != ISC_R_SUCCESS) { 841 dns_adb_shutdown(view->adb); 842 dns_resolver_shutdown(view->resolver); 843 return (result); 844 } 845 event = &view->reqevent; 846 dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event); 847 view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN; 848 849 return (ISC_R_SUCCESS); 850 } 851 852 void 853 dns_view_setcache(dns_view_t *view, dns_cache_t *cache) { 854 dns_view_setcache2(view, cache, ISC_FALSE); 855 } 856 857 void 858 dns_view_setcache2(dns_view_t *view, dns_cache_t *cache, isc_boolean_t shared) { 859 REQUIRE(DNS_VIEW_VALID(view)); 860 REQUIRE(!view->frozen); 861 862 view->cacheshared = shared; 863 if (view->cache != NULL) { 864 dns_db_detach(&view->cachedb); 865 dns_cache_detach(&view->cache); 866 } 867 dns_cache_attach(cache, &view->cache); 868 dns_cache_attachdb(cache, &view->cachedb); 869 INSIST(DNS_DB_VALID(view->cachedb)); 870 } 871 872 isc_boolean_t 873 dns_view_iscacheshared(dns_view_t *view) { 874 REQUIRE(DNS_VIEW_VALID(view)); 875 876 return (view->cacheshared); 877 } 878 879 void 880 dns_view_sethints(dns_view_t *view, dns_db_t *hints) { 881 REQUIRE(DNS_VIEW_VALID(view)); 882 REQUIRE(!view->frozen); 883 REQUIRE(view->hints == NULL); 884 REQUIRE(dns_db_iszone(hints)); 885 886 dns_db_attach(hints, &view->hints); 887 } 888 889 void 890 dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring) { 891 REQUIRE(DNS_VIEW_VALID(view)); 892 REQUIRE(ring != NULL); 893 if (view->statickeys != NULL) 894 dns_tsigkeyring_detach(&view->statickeys); 895 dns_tsigkeyring_attach(ring, &view->statickeys); 896 } 897 898 void 899 dns_view_setdynamickeyring(dns_view_t *view, dns_tsig_keyring_t *ring) { 900 REQUIRE(DNS_VIEW_VALID(view)); 901 REQUIRE(ring != NULL); 902 if (view->dynamickeys != NULL) 903 dns_tsigkeyring_detach(&view->dynamickeys); 904 dns_tsigkeyring_attach(ring, &view->dynamickeys); 905 } 906 907 void 908 dns_view_getdynamickeyring(dns_view_t *view, dns_tsig_keyring_t **ringp) { 909 REQUIRE(DNS_VIEW_VALID(view)); 910 REQUIRE(ringp != NULL && *ringp == NULL); 911 if (view->dynamickeys != NULL) 912 dns_tsigkeyring_attach(view->dynamickeys, ringp); 913 } 914 915 void 916 dns_view_restorekeyring(dns_view_t *view) { 917 FILE *fp; 918 char keyfile[PATH_MAX]; 919 isc_result_t result; 920 921 REQUIRE(DNS_VIEW_VALID(view)); 922 923 if (view->dynamickeys != NULL) { 924 result = isc_file_sanitize(NULL, view->name, "tsigkeys", 925 keyfile, sizeof(keyfile)); 926 if (result == ISC_R_SUCCESS) { 927 fp = fopen(keyfile, "r"); 928 if (fp != NULL) { 929 dns_keyring_restore(view->dynamickeys, fp); 930 (void)fclose(fp); 931 } 932 } 933 } 934 } 935 936 void 937 dns_view_setdstport(dns_view_t *view, in_port_t dstport) { 938 REQUIRE(DNS_VIEW_VALID(view)); 939 view->dstport = dstport; 940 } 941 942 void 943 dns_view_freeze(dns_view_t *view) { 944 REQUIRE(DNS_VIEW_VALID(view)); 945 REQUIRE(!view->frozen); 946 947 if (view->resolver != NULL) { 948 INSIST(view->cachedb != NULL); 949 dns_resolver_freeze(view->resolver); 950 } 951 view->frozen = ISC_TRUE; 952 } 953 954 void 955 dns_view_thaw(dns_view_t *view) { 956 REQUIRE(DNS_VIEW_VALID(view)); 957 REQUIRE(view->frozen); 958 959 view->frozen = ISC_FALSE; 960 } 961 962 isc_result_t 963 dns_view_addzone(dns_view_t *view, dns_zone_t *zone) { 964 isc_result_t result; 965 966 REQUIRE(DNS_VIEW_VALID(view)); 967 REQUIRE(!view->frozen); 968 REQUIRE(view->zonetable != NULL); 969 970 result = dns_zt_mount(view->zonetable, zone); 971 972 return (result); 973 } 974 975 isc_result_t 976 dns_view_findzone(dns_view_t *view, const dns_name_t *name, 977 dns_zone_t **zonep) 978 { 979 isc_result_t result; 980 981 REQUIRE(DNS_VIEW_VALID(view)); 982 983 LOCK(&view->lock); 984 if (view->zonetable != NULL) { 985 result = dns_zt_find(view->zonetable, name, 0, NULL, zonep); 986 if (result == DNS_R_PARTIALMATCH) { 987 dns_zone_detach(zonep); 988 result = ISC_R_NOTFOUND; 989 } 990 } else 991 result = ISC_R_NOTFOUND; 992 UNLOCK(&view->lock); 993 994 return (result); 995 } 996 997 isc_result_t 998 dns_view_find(dns_view_t *view, const dns_name_t *name, dns_rdatatype_t type, 999 isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, 1000 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, 1001 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { 1002 return (dns_view_find2(view, name, type, now, options, use_hints, 1003 ISC_FALSE, dbp, nodep, foundname, rdataset, 1004 sigrdataset)); 1005 } 1006 1007 isc_result_t 1008 dns_view_find2(dns_view_t *view, const dns_name_t *name, dns_rdatatype_t type, 1009 isc_stdtime_t now, unsigned int options, 1010 isc_boolean_t use_hints, isc_boolean_t use_static_stub, 1011 dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, 1012 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 1013 { 1014 isc_result_t result; 1015 dns_db_t *db, *zdb; 1016 dns_dbnode_t *node, *znode; 1017 isc_boolean_t is_cache, is_staticstub_zone; 1018 dns_rdataset_t zrdataset, zsigrdataset; 1019 dns_zone_t *zone; 1020 1021 /* 1022 * Find an rdataset whose owner name is 'name', and whose type is 1023 * 'type'. 1024 */ 1025 1026 REQUIRE(DNS_VIEW_VALID(view)); 1027 REQUIRE(view->frozen); 1028 REQUIRE(type != dns_rdatatype_rrsig); 1029 REQUIRE(rdataset != NULL); /* XXXBEW - remove this */ 1030 REQUIRE(nodep == NULL || *nodep == NULL); 1031 1032 /* 1033 * Initialize. 1034 */ 1035 dns_rdataset_init(&zrdataset); 1036 dns_rdataset_init(&zsigrdataset); 1037 zdb = NULL; 1038 znode = NULL; 1039 1040 /* 1041 * Find a database to answer the query. 1042 */ 1043 db = NULL; 1044 node = NULL; 1045 is_staticstub_zone = ISC_FALSE; 1046 zone = NULL; 1047 LOCK(&view->lock); 1048 if (view->zonetable != NULL) 1049 result = dns_zt_find(view->zonetable, name, 0, NULL, &zone); 1050 else 1051 result = ISC_R_NOTFOUND; 1052 UNLOCK(&view->lock); 1053 if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub && 1054 !use_static_stub) 1055 result = ISC_R_NOTFOUND; 1056 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { 1057 result = dns_zone_getdb(zone, &db); 1058 if (result != ISC_R_SUCCESS && view->cachedb != NULL) 1059 dns_db_attach(view->cachedb, &db); 1060 else if (result != ISC_R_SUCCESS) 1061 goto cleanup; 1062 if (dns_zone_gettype(zone) == dns_zone_staticstub && 1063 dns_name_equal(name, dns_zone_getorigin(zone))) { 1064 is_staticstub_zone = ISC_TRUE; 1065 } 1066 } else if (result == ISC_R_NOTFOUND && view->cachedb != NULL) 1067 dns_db_attach(view->cachedb, &db); 1068 else 1069 goto cleanup; 1070 1071 is_cache = dns_db_iscache(db); 1072 1073 db_find: 1074 /* 1075 * Now look for an answer in the database. 1076 */ 1077 result = dns_db_find(db, name, NULL, type, options, 1078 now, &node, foundname, rdataset, sigrdataset); 1079 1080 if (result == DNS_R_DELEGATION || result == ISC_R_NOTFOUND) { 1081 if (dns_rdataset_isassociated(rdataset)) 1082 dns_rdataset_disassociate(rdataset); 1083 if (sigrdataset != NULL && 1084 dns_rdataset_isassociated(sigrdataset)) 1085 dns_rdataset_disassociate(sigrdataset); 1086 if (node != NULL) 1087 dns_db_detachnode(db, &node); 1088 if (!is_cache) { 1089 dns_db_detach(&db); 1090 if (view->cachedb != NULL && !is_staticstub_zone) { 1091 /* 1092 * Either the answer is in the cache, or we 1093 * don't know it. 1094 * Note that if the result comes from a 1095 * static-stub zone we stop the search here 1096 * (see the function description in view.h). 1097 */ 1098 is_cache = ISC_TRUE; 1099 dns_db_attach(view->cachedb, &db); 1100 goto db_find; 1101 } 1102 } else { 1103 /* 1104 * We don't have the data in the cache. If we've got 1105 * glue from the zone, use it. 1106 */ 1107 if (dns_rdataset_isassociated(&zrdataset)) { 1108 dns_rdataset_clone(&zrdataset, rdataset); 1109 if (sigrdataset != NULL && 1110 dns_rdataset_isassociated(&zsigrdataset)) 1111 dns_rdataset_clone(&zsigrdataset, 1112 sigrdataset); 1113 result = DNS_R_GLUE; 1114 if (db != NULL) 1115 dns_db_detach(&db); 1116 dns_db_attach(zdb, &db); 1117 dns_db_attachnode(db, znode, &node); 1118 goto cleanup; 1119 } 1120 } 1121 /* 1122 * We don't know the answer. 1123 */ 1124 result = ISC_R_NOTFOUND; 1125 } else if (result == DNS_R_GLUE) { 1126 if (view->cachedb != NULL && !is_staticstub_zone) { 1127 /* 1128 * We found an answer, but the cache may be better. 1129 * Remember what we've got and go look in the cache. 1130 */ 1131 is_cache = ISC_TRUE; 1132 dns_rdataset_clone(rdataset, &zrdataset); 1133 dns_rdataset_disassociate(rdataset); 1134 if (sigrdataset != NULL && 1135 dns_rdataset_isassociated(sigrdataset)) { 1136 dns_rdataset_clone(sigrdataset, &zsigrdataset); 1137 dns_rdataset_disassociate(sigrdataset); 1138 } 1139 dns_db_attach(db, &zdb); 1140 dns_db_attachnode(zdb, node, &znode); 1141 dns_db_detachnode(db, &node); 1142 dns_db_detach(&db); 1143 dns_db_attach(view->cachedb, &db); 1144 goto db_find; 1145 } 1146 /* 1147 * Otherwise, the glue is the best answer. 1148 */ 1149 result = ISC_R_SUCCESS; 1150 } 1151 1152 if (result == ISC_R_NOTFOUND && use_hints && view->hints != NULL) { 1153 if (dns_rdataset_isassociated(rdataset)) 1154 dns_rdataset_disassociate(rdataset); 1155 if (sigrdataset != NULL && 1156 dns_rdataset_isassociated(sigrdataset)) 1157 dns_rdataset_disassociate(sigrdataset); 1158 if (db != NULL) { 1159 if (node != NULL) 1160 dns_db_detachnode(db, &node); 1161 dns_db_detach(&db); 1162 } 1163 result = dns_db_find(view->hints, name, NULL, type, options, 1164 now, &node, foundname, 1165 rdataset, sigrdataset); 1166 if (result == ISC_R_SUCCESS || result == DNS_R_GLUE) { 1167 /* 1168 * We just used a hint. Let the resolver know it 1169 * should consider priming. 1170 */ 1171 dns_resolver_prime(view->resolver); 1172 dns_db_attach(view->hints, &db); 1173 result = DNS_R_HINT; 1174 } else if (result == DNS_R_NXRRSET) { 1175 dns_db_attach(view->hints, &db); 1176 result = DNS_R_HINTNXRRSET; 1177 } else if (result == DNS_R_NXDOMAIN) 1178 result = ISC_R_NOTFOUND; 1179 1180 /* 1181 * Cleanup if non-standard hints are used. 1182 */ 1183 if (db == NULL && node != NULL) 1184 dns_db_detachnode(view->hints, &node); 1185 } 1186 1187 cleanup: 1188 if (dns_rdataset_isassociated(&zrdataset)) { 1189 dns_rdataset_disassociate(&zrdataset); 1190 if (dns_rdataset_isassociated(&zsigrdataset)) 1191 dns_rdataset_disassociate(&zsigrdataset); 1192 } 1193 1194 if (zdb != NULL) { 1195 if (znode != NULL) 1196 dns_db_detachnode(zdb, &znode); 1197 dns_db_detach(&zdb); 1198 } 1199 1200 if (db != NULL) { 1201 if (node != NULL) { 1202 if (nodep != NULL) 1203 *nodep = node; 1204 else 1205 dns_db_detachnode(db, &node); 1206 } 1207 if (dbp != NULL) 1208 *dbp = db; 1209 else 1210 dns_db_detach(&db); 1211 } else 1212 INSIST(node == NULL); 1213 1214 if (zone != NULL) 1215 dns_zone_detach(&zone); 1216 1217 return (result); 1218 } 1219 1220 isc_result_t 1221 dns_view_simplefind(dns_view_t *view, const dns_name_t *name, 1222 dns_rdatatype_t type, isc_stdtime_t now, 1223 unsigned int options, isc_boolean_t use_hints, 1224 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 1225 { 1226 isc_result_t result; 1227 dns_fixedname_t foundname; 1228 1229 dns_fixedname_init(&foundname); 1230 result = dns_view_find(view, name, type, now, options, use_hints, 1231 NULL, NULL, dns_fixedname_name(&foundname), 1232 rdataset, sigrdataset); 1233 if (result == DNS_R_NXDOMAIN) { 1234 /* 1235 * The rdataset and sigrdataset of the relevant NSEC record 1236 * may be returned, but the caller cannot use them because 1237 * foundname is not returned by this simplified API. We 1238 * disassociate them here to prevent any misuse by the caller. 1239 */ 1240 if (dns_rdataset_isassociated(rdataset)) 1241 dns_rdataset_disassociate(rdataset); 1242 if (sigrdataset != NULL && 1243 dns_rdataset_isassociated(sigrdataset)) 1244 dns_rdataset_disassociate(sigrdataset); 1245 } else if (result != ISC_R_SUCCESS && 1246 result != DNS_R_GLUE && 1247 result != DNS_R_HINT && 1248 result != DNS_R_NCACHENXDOMAIN && 1249 result != DNS_R_NCACHENXRRSET && 1250 result != DNS_R_NXRRSET && 1251 result != DNS_R_HINTNXRRSET && 1252 result != ISC_R_NOTFOUND) { 1253 if (dns_rdataset_isassociated(rdataset)) 1254 dns_rdataset_disassociate(rdataset); 1255 if (sigrdataset != NULL && 1256 dns_rdataset_isassociated(sigrdataset)) 1257 dns_rdataset_disassociate(sigrdataset); 1258 result = ISC_R_NOTFOUND; 1259 } 1260 1261 return (result); 1262 } 1263 1264 isc_result_t 1265 dns_view_findzonecut(dns_view_t *view, const dns_name_t *name, 1266 dns_name_t *fname, isc_stdtime_t now, unsigned int options, 1267 isc_boolean_t use_hints, 1268 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 1269 { 1270 return(dns_view_findzonecut2(view, name, fname, now, options, 1271 use_hints, ISC_TRUE, 1272 rdataset, sigrdataset)); 1273 } 1274 1275 isc_result_t 1276 dns_view_findzonecut2(dns_view_t *view, const dns_name_t *name, 1277 dns_name_t *fname, isc_stdtime_t now, 1278 unsigned int options, isc_boolean_t use_hints, 1279 isc_boolean_t use_cache, dns_rdataset_t *rdataset, 1280 dns_rdataset_t *sigrdataset) 1281 { 1282 isc_result_t result; 1283 dns_db_t *db; 1284 isc_boolean_t is_cache, use_zone, try_hints; 1285 dns_zone_t *zone; 1286 dns_name_t *zfname; 1287 dns_rdataset_t zrdataset, zsigrdataset; 1288 dns_fixedname_t zfixedname; 1289 unsigned int ztoptions = 0; 1290 1291 REQUIRE(DNS_VIEW_VALID(view)); 1292 REQUIRE(view->frozen); 1293 1294 db = NULL; 1295 use_zone = ISC_FALSE; 1296 try_hints = ISC_FALSE; 1297 zfname = NULL; 1298 1299 /* 1300 * Initialize. 1301 */ 1302 dns_fixedname_init(&zfixedname); 1303 dns_rdataset_init(&zrdataset); 1304 dns_rdataset_init(&zsigrdataset); 1305 1306 /* 1307 * Find the right database. 1308 */ 1309 zone = NULL; 1310 LOCK(&view->lock); 1311 if (view->zonetable != NULL) { 1312 if ((options & DNS_DBFIND_NOEXACT) != 0) 1313 ztoptions |= DNS_ZTFIND_NOEXACT; 1314 result = dns_zt_find(view->zonetable, name, ztoptions, 1315 NULL, &zone); 1316 } else 1317 result = ISC_R_NOTFOUND; 1318 UNLOCK(&view->lock); 1319 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) 1320 result = dns_zone_getdb(zone, &db); 1321 if (result == ISC_R_NOTFOUND) { 1322 /* 1323 * We're not directly authoritative for this query name, nor 1324 * is it a subdomain of any zone for which we're 1325 * authoritative. 1326 */ 1327 if (use_cache && view->cachedb != NULL) { 1328 /* 1329 * We have a cache; try it. 1330 */ 1331 dns_db_attach(view->cachedb, &db); 1332 } else { 1333 /* 1334 * Maybe we have hints... 1335 */ 1336 try_hints = ISC_TRUE; 1337 goto finish; 1338 } 1339 } else if (result != ISC_R_SUCCESS) { 1340 /* 1341 * Something is broken. 1342 */ 1343 goto cleanup; 1344 } 1345 is_cache = dns_db_iscache(db); 1346 1347 db_find: 1348 /* 1349 * Look for the zonecut. 1350 */ 1351 if (!is_cache) { 1352 result = dns_db_find(db, name, NULL, dns_rdatatype_ns, options, 1353 now, NULL, fname, rdataset, sigrdataset); 1354 if (result == DNS_R_DELEGATION) 1355 result = ISC_R_SUCCESS; 1356 else if (result != ISC_R_SUCCESS) 1357 goto cleanup; 1358 if (use_cache && view->cachedb != NULL && db != view->hints) { 1359 /* 1360 * We found an answer, but the cache may be better. 1361 */ 1362 zfname = dns_fixedname_name(&zfixedname); 1363 result = dns_name_copy(fname, zfname, NULL); 1364 if (result != ISC_R_SUCCESS) 1365 goto cleanup; 1366 dns_rdataset_clone(rdataset, &zrdataset); 1367 dns_rdataset_disassociate(rdataset); 1368 if (sigrdataset != NULL && 1369 dns_rdataset_isassociated(sigrdataset)) { 1370 dns_rdataset_clone(sigrdataset, &zsigrdataset); 1371 dns_rdataset_disassociate(sigrdataset); 1372 } 1373 dns_db_detach(&db); 1374 dns_db_attach(view->cachedb, &db); 1375 is_cache = ISC_TRUE; 1376 goto db_find; 1377 } 1378 } else { 1379 result = dns_db_findzonecut(db, name, options, now, NULL, 1380 fname, rdataset, sigrdataset); 1381 if (result == ISC_R_SUCCESS) { 1382 if (zfname != NULL && 1383 (!dns_name_issubdomain(fname, zfname) || 1384 (dns_zone_gettype(zone) == dns_zone_staticstub && 1385 dns_name_equal(fname, zfname)))) { 1386 /* 1387 * We found a zonecut in the cache, but our 1388 * zone delegation is better. 1389 */ 1390 use_zone = ISC_TRUE; 1391 } 1392 } else if (result == ISC_R_NOTFOUND) { 1393 if (zfname != NULL) { 1394 /* 1395 * We didn't find anything in the cache, but we 1396 * have a zone delegation, so use it. 1397 */ 1398 use_zone = ISC_TRUE; 1399 } else { 1400 /* 1401 * Maybe we have hints... 1402 */ 1403 try_hints = ISC_TRUE; 1404 } 1405 } else { 1406 /* 1407 * Something bad happened. 1408 */ 1409 goto cleanup; 1410 } 1411 } 1412 1413 finish: 1414 if (use_zone) { 1415 if (dns_rdataset_isassociated(rdataset)) { 1416 dns_rdataset_disassociate(rdataset); 1417 if (sigrdataset != NULL && 1418 dns_rdataset_isassociated(sigrdataset)) 1419 dns_rdataset_disassociate(sigrdataset); 1420 } 1421 result = dns_name_copy(zfname, fname, NULL); 1422 if (result != ISC_R_SUCCESS) 1423 goto cleanup; 1424 dns_rdataset_clone(&zrdataset, rdataset); 1425 if (sigrdataset != NULL && 1426 dns_rdataset_isassociated(&zrdataset)) 1427 dns_rdataset_clone(&zsigrdataset, sigrdataset); 1428 } else if (try_hints && use_hints && view->hints != NULL) { 1429 /* 1430 * We've found nothing so far, but we have hints. 1431 */ 1432 result = dns_db_find(view->hints, dns_rootname, NULL, 1433 dns_rdatatype_ns, 0, now, NULL, fname, 1434 rdataset, NULL); 1435 if (result != ISC_R_SUCCESS) { 1436 /* 1437 * We can't even find the hints for the root 1438 * nameservers! 1439 */ 1440 if (dns_rdataset_isassociated(rdataset)) 1441 dns_rdataset_disassociate(rdataset); 1442 result = ISC_R_NOTFOUND; 1443 } 1444 } 1445 1446 cleanup: 1447 if (dns_rdataset_isassociated(&zrdataset)) { 1448 dns_rdataset_disassociate(&zrdataset); 1449 if (dns_rdataset_isassociated(&zsigrdataset)) 1450 dns_rdataset_disassociate(&zsigrdataset); 1451 } 1452 if (db != NULL) 1453 dns_db_detach(&db); 1454 if (zone != NULL) 1455 dns_zone_detach(&zone); 1456 1457 return (result); 1458 } 1459 1460 isc_result_t 1461 dns_viewlist_find(dns_viewlist_t *list, const char *name, 1462 dns_rdataclass_t rdclass, dns_view_t **viewp) 1463 { 1464 dns_view_t *view; 1465 1466 REQUIRE(list != NULL); 1467 1468 for (view = ISC_LIST_HEAD(*list); 1469 view != NULL; 1470 view = ISC_LIST_NEXT(view, link)) { 1471 if (strcmp(view->name, name) == 0 && view->rdclass == rdclass) 1472 break; 1473 } 1474 if (view == NULL) 1475 return (ISC_R_NOTFOUND); 1476 1477 dns_view_attach(view, viewp); 1478 1479 return (ISC_R_SUCCESS); 1480 } 1481 1482 isc_result_t 1483 dns_viewlist_findzone(dns_viewlist_t *list, const dns_name_t *name, 1484 isc_boolean_t allclasses, dns_rdataclass_t rdclass, 1485 dns_zone_t **zonep) 1486 { 1487 dns_view_t *view; 1488 isc_result_t result; 1489 dns_zone_t *zone1 = NULL, *zone2 = NULL; 1490 dns_zone_t **zp = NULL; 1491 1492 REQUIRE(list != NULL); 1493 REQUIRE(zonep != NULL && *zonep == NULL); 1494 1495 for (view = ISC_LIST_HEAD(*list); 1496 view != NULL; 1497 view = ISC_LIST_NEXT(view, link)) { 1498 if (allclasses == ISC_FALSE && view->rdclass != rdclass) 1499 continue; 1500 1501 /* 1502 * If the zone is defined in more than one view, 1503 * treat it as not found. 1504 */ 1505 zp = (zone1 == NULL) ? &zone1 : &zone2; 1506 LOCK(&view->lock); 1507 if (view->zonetable != NULL) 1508 result = dns_zt_find(view->zonetable, name, 0, 1509 NULL, zp); 1510 else 1511 result = ISC_R_NOTFOUND; 1512 UNLOCK(&view->lock); 1513 INSIST(result == ISC_R_SUCCESS || 1514 result == ISC_R_NOTFOUND || 1515 result == DNS_R_PARTIALMATCH); 1516 1517 /* Treat a partial match as no match */ 1518 if (result == DNS_R_PARTIALMATCH) { 1519 dns_zone_detach(zp); 1520 result = ISC_R_NOTFOUND; 1521 POST(result); 1522 } 1523 1524 if (zone2 != NULL) { 1525 dns_zone_detach(&zone1); 1526 dns_zone_detach(&zone2); 1527 return (ISC_R_MULTIPLE); 1528 } 1529 } 1530 1531 if (zone1 != NULL) { 1532 dns_zone_attach(zone1, zonep); 1533 dns_zone_detach(&zone1); 1534 return (ISC_R_SUCCESS); 1535 } 1536 1537 return (ISC_R_NOTFOUND); 1538 } 1539 1540 isc_result_t 1541 dns_view_load(dns_view_t *view, isc_boolean_t stop) { 1542 1543 REQUIRE(DNS_VIEW_VALID(view)); 1544 REQUIRE(view->zonetable != NULL); 1545 1546 return (dns_zt_load(view->zonetable, stop)); 1547 } 1548 1549 isc_result_t 1550 dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) { 1551 1552 REQUIRE(DNS_VIEW_VALID(view)); 1553 REQUIRE(view->zonetable != NULL); 1554 1555 return (dns_zt_loadnew(view->zonetable, stop)); 1556 } 1557 1558 isc_result_t 1559 dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg) { 1560 REQUIRE(DNS_VIEW_VALID(view)); 1561 REQUIRE(view->zonetable != NULL); 1562 1563 return (dns_zt_asyncload(view->zonetable, callback, arg)); 1564 } 1565 1566 isc_result_t 1567 dns_view_gettsig(dns_view_t *view, const dns_name_t *keyname, 1568 dns_tsigkey_t **keyp) 1569 { 1570 isc_result_t result; 1571 REQUIRE(keyp != NULL && *keyp == NULL); 1572 1573 result = dns_tsigkey_find(keyp, keyname, NULL, 1574 view->statickeys); 1575 if (result == ISC_R_NOTFOUND) 1576 result = dns_tsigkey_find(keyp, keyname, NULL, 1577 view->dynamickeys); 1578 return (result); 1579 } 1580 1581 isc_result_t 1582 dns_view_getpeertsig(dns_view_t *view, const isc_netaddr_t *peeraddr, 1583 dns_tsigkey_t **keyp) 1584 { 1585 isc_result_t result; 1586 dns_name_t *keyname = NULL; 1587 dns_peer_t *peer = NULL; 1588 1589 result = dns_peerlist_peerbyaddr(view->peers, peeraddr, &peer); 1590 if (result != ISC_R_SUCCESS) 1591 return (result); 1592 1593 result = dns_peer_getkey(peer, &keyname); 1594 if (result != ISC_R_SUCCESS) 1595 return (result); 1596 1597 result = dns_view_gettsig(view, keyname, keyp); 1598 return ((result == ISC_R_NOTFOUND) ? ISC_R_FAILURE : result); 1599 } 1600 1601 isc_result_t 1602 dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg) { 1603 REQUIRE(DNS_VIEW_VALID(view)); 1604 REQUIRE(source != NULL); 1605 1606 return (dns_tsig_verify(source, msg, view->statickeys, 1607 view->dynamickeys)); 1608 } 1609 1610 isc_result_t 1611 dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) { 1612 isc_result_t result; 1613 1614 REQUIRE(DNS_VIEW_VALID(view)); 1615 1616 (void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name); 1617 result = dns_master_dumptostream(view->mctx, view->cachedb, NULL, 1618 &dns_master_style_cache, fp); 1619 if (result != ISC_R_SUCCESS) 1620 return (result); 1621 dns_adb_dump(view->adb, fp); 1622 dns_resolver_printbadcache(view->resolver, fp); 1623 dns_badcache_print(view->failcache, "SERVFAIL cache", fp); 1624 return (ISC_R_SUCCESS); 1625 } 1626 1627 isc_result_t 1628 dns_view_flushcache(dns_view_t *view) { 1629 return (dns_view_flushcache2(view, ISC_FALSE)); 1630 } 1631 1632 isc_result_t 1633 dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) { 1634 isc_result_t result; 1635 1636 REQUIRE(DNS_VIEW_VALID(view)); 1637 1638 if (view->cachedb == NULL) 1639 return (ISC_R_SUCCESS); 1640 if (!fixuponly) { 1641 result = dns_cache_flush(view->cache); 1642 if (result != ISC_R_SUCCESS) 1643 return (result); 1644 } 1645 dns_db_detach(&view->cachedb); 1646 dns_cache_attachdb(view->cache, &view->cachedb); 1647 if (view->resolver != NULL) 1648 dns_resolver_flushbadcache(view->resolver, NULL); 1649 if (view->failcache != NULL) 1650 dns_badcache_flush(view->failcache); 1651 1652 dns_adb_flush(view->adb); 1653 return (ISC_R_SUCCESS); 1654 } 1655 1656 isc_result_t 1657 dns_view_flushname(dns_view_t *view, const dns_name_t *name) { 1658 return (dns_view_flushnode(view, name, ISC_FALSE)); 1659 } 1660 1661 isc_result_t 1662 dns_view_flushnode(dns_view_t *view, const dns_name_t *name, 1663 isc_boolean_t tree) 1664 { 1665 isc_result_t result = ISC_R_SUCCESS; 1666 1667 REQUIRE(DNS_VIEW_VALID(view)); 1668 1669 if (tree) { 1670 if (view->adb != NULL) 1671 dns_adb_flushnames(view->adb, name); 1672 if (view->resolver != NULL) 1673 dns_resolver_flushbadnames(view->resolver, name); 1674 if (view->failcache != NULL) 1675 dns_badcache_flushtree(view->failcache, name); 1676 } else { 1677 if (view->adb != NULL) 1678 dns_adb_flushname(view->adb, name); 1679 if (view->resolver != NULL) 1680 dns_resolver_flushbadcache(view->resolver, name); 1681 if (view->failcache != NULL) 1682 dns_badcache_flushname(view->failcache, name); 1683 } 1684 1685 if (view->cache != NULL) 1686 result = dns_cache_flushnode(view->cache, name, tree); 1687 1688 return (result); 1689 } 1690 1691 isc_result_t 1692 dns_view_adddelegationonly(dns_view_t *view, const dns_name_t *name) { 1693 isc_result_t result; 1694 dns_name_t *item; 1695 isc_uint32_t hash; 1696 1697 REQUIRE(DNS_VIEW_VALID(view)); 1698 1699 if (view->delonly == NULL) { 1700 view->delonly = isc_mem_get(view->mctx, 1701 sizeof(dns_namelist_t) * 1702 DNS_VIEW_DELONLYHASH); 1703 if (view->delonly == NULL) 1704 return (ISC_R_NOMEMORY); 1705 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++) 1706 ISC_LIST_INIT(view->delonly[hash]); 1707 } 1708 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1709 item = ISC_LIST_HEAD(view->delonly[hash]); 1710 while (item != NULL && !dns_name_equal(item, name)) 1711 item = ISC_LIST_NEXT(item, link); 1712 if (item != NULL) 1713 return (ISC_R_SUCCESS); 1714 item = isc_mem_get(view->mctx, sizeof(*item)); 1715 if (item == NULL) 1716 return (ISC_R_NOMEMORY); 1717 dns_name_init(item, NULL); 1718 result = dns_name_dup(name, view->mctx, item); 1719 if (result == ISC_R_SUCCESS) 1720 ISC_LIST_APPEND(view->delonly[hash], item, link); 1721 else 1722 isc_mem_put(view->mctx, item, sizeof(*item)); 1723 return (result); 1724 } 1725 1726 isc_result_t 1727 dns_view_excludedelegationonly(dns_view_t *view, const dns_name_t *name) { 1728 isc_result_t result; 1729 dns_name_t *item; 1730 isc_uint32_t hash; 1731 1732 REQUIRE(DNS_VIEW_VALID(view)); 1733 1734 if (view->rootexclude == NULL) { 1735 view->rootexclude = isc_mem_get(view->mctx, 1736 sizeof(dns_namelist_t) * 1737 DNS_VIEW_DELONLYHASH); 1738 if (view->rootexclude == NULL) 1739 return (ISC_R_NOMEMORY); 1740 for (hash = 0; hash < DNS_VIEW_DELONLYHASH; hash++) 1741 ISC_LIST_INIT(view->rootexclude[hash]); 1742 } 1743 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1744 item = ISC_LIST_HEAD(view->rootexclude[hash]); 1745 while (item != NULL && !dns_name_equal(item, name)) 1746 item = ISC_LIST_NEXT(item, link); 1747 if (item != NULL) 1748 return (ISC_R_SUCCESS); 1749 item = isc_mem_get(view->mctx, sizeof(*item)); 1750 if (item == NULL) 1751 return (ISC_R_NOMEMORY); 1752 dns_name_init(item, NULL); 1753 result = dns_name_dup(name, view->mctx, item); 1754 if (result == ISC_R_SUCCESS) 1755 ISC_LIST_APPEND(view->rootexclude[hash], item, link); 1756 else 1757 isc_mem_put(view->mctx, item, sizeof(*item)); 1758 return (result); 1759 } 1760 1761 isc_boolean_t 1762 dns_view_isdelegationonly(dns_view_t *view, const dns_name_t *name) { 1763 dns_name_t *item; 1764 isc_uint32_t hash; 1765 1766 REQUIRE(DNS_VIEW_VALID(view)); 1767 1768 if (!view->rootdelonly && view->delonly == NULL) 1769 return (ISC_FALSE); 1770 1771 hash = dns_name_hash(name, ISC_FALSE) % DNS_VIEW_DELONLYHASH; 1772 if (view->rootdelonly && dns_name_countlabels(name) <= 2) { 1773 if (view->rootexclude == NULL) 1774 return (ISC_TRUE); 1775 item = ISC_LIST_HEAD(view->rootexclude[hash]); 1776 while (item != NULL && !dns_name_equal(item, name)) 1777 item = ISC_LIST_NEXT(item, link); 1778 if (item == NULL) 1779 return (ISC_TRUE); 1780 } 1781 1782 if (view->delonly == NULL) 1783 return (ISC_FALSE); 1784 1785 item = ISC_LIST_HEAD(view->delonly[hash]); 1786 while (item != NULL && !dns_name_equal(item, name)) 1787 item = ISC_LIST_NEXT(item, link); 1788 if (item == NULL) 1789 return (ISC_FALSE); 1790 return (ISC_TRUE); 1791 } 1792 1793 void 1794 dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value) { 1795 REQUIRE(DNS_VIEW_VALID(view)); 1796 view->rootdelonly = value; 1797 } 1798 1799 isc_boolean_t 1800 dns_view_getrootdelonly(dns_view_t *view) { 1801 REQUIRE(DNS_VIEW_VALID(view)); 1802 return (view->rootdelonly); 1803 } 1804 1805 isc_result_t 1806 dns_view_freezezones(dns_view_t *view, isc_boolean_t value) { 1807 1808 REQUIRE(DNS_VIEW_VALID(view)); 1809 REQUIRE(view->zonetable != NULL); 1810 1811 return (dns_zt_freezezones(view->zonetable, value)); 1812 } 1813 1814 void 1815 dns_view_setadbstats(dns_view_t *view, isc_stats_t *stats) { 1816 REQUIRE(DNS_VIEW_VALID(view)); 1817 REQUIRE(!view->frozen); 1818 REQUIRE(view->adbstats == NULL); 1819 1820 isc_stats_attach(stats, &view->adbstats); 1821 } 1822 1823 void 1824 dns_view_getadbstats(dns_view_t *view, isc_stats_t **statsp) { 1825 REQUIRE(DNS_VIEW_VALID(view)); 1826 REQUIRE(statsp != NULL && *statsp == NULL); 1827 1828 if (view->adbstats != NULL) 1829 isc_stats_attach(view->adbstats, statsp); 1830 } 1831 1832 void 1833 dns_view_setresstats(dns_view_t *view, isc_stats_t *stats) { 1834 1835 REQUIRE(DNS_VIEW_VALID(view)); 1836 REQUIRE(!view->frozen); 1837 REQUIRE(view->resstats == NULL); 1838 1839 isc_stats_attach(stats, &view->resstats); 1840 } 1841 1842 void 1843 dns_view_getresstats(dns_view_t *view, isc_stats_t **statsp) { 1844 REQUIRE(DNS_VIEW_VALID(view)); 1845 REQUIRE(statsp != NULL && *statsp == NULL); 1846 1847 if (view->resstats != NULL) 1848 isc_stats_attach(view->resstats, statsp); 1849 } 1850 1851 void 1852 dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats) { 1853 REQUIRE(DNS_VIEW_VALID(view)); 1854 REQUIRE(!view->frozen); 1855 REQUIRE(view->resquerystats == NULL); 1856 1857 dns_stats_attach(stats, &view->resquerystats); 1858 } 1859 1860 void 1861 dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp) { 1862 REQUIRE(DNS_VIEW_VALID(view)); 1863 REQUIRE(statsp != NULL && *statsp == NULL); 1864 1865 if (view->resquerystats != NULL) 1866 dns_stats_attach(view->resquerystats, statsp); 1867 } 1868 1869 isc_result_t 1870 dns_view_initntatable(dns_view_t *view, 1871 isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr) 1872 { 1873 REQUIRE(DNS_VIEW_VALID(view)); 1874 if (view->ntatable_priv != NULL) 1875 dns_ntatable_detach(&view->ntatable_priv); 1876 return (dns_ntatable_create(view, taskmgr, timermgr, 1877 &view->ntatable_priv)); 1878 } 1879 1880 isc_result_t 1881 dns_view_getntatable(dns_view_t *view, dns_ntatable_t **ntp) { 1882 REQUIRE(DNS_VIEW_VALID(view)); 1883 REQUIRE(ntp != NULL && *ntp == NULL); 1884 if (view->ntatable_priv == NULL) 1885 return (ISC_R_NOTFOUND); 1886 dns_ntatable_attach(view->ntatable_priv, ntp); 1887 return (ISC_R_SUCCESS); 1888 } 1889 1890 isc_result_t 1891 dns_view_initsecroots(dns_view_t *view, isc_mem_t *mctx) { 1892 REQUIRE(DNS_VIEW_VALID(view)); 1893 if (view->secroots_priv != NULL) 1894 dns_keytable_detach(&view->secroots_priv); 1895 return (dns_keytable_create(mctx, &view->secroots_priv)); 1896 } 1897 1898 isc_result_t 1899 dns_view_getsecroots(dns_view_t *view, dns_keytable_t **ktp) { 1900 REQUIRE(DNS_VIEW_VALID(view)); 1901 REQUIRE(ktp != NULL && *ktp == NULL); 1902 if (view->secroots_priv == NULL) 1903 return (ISC_R_NOTFOUND); 1904 dns_keytable_attach(view->secroots_priv, ktp); 1905 return (ISC_R_SUCCESS); 1906 } 1907 1908 isc_boolean_t 1909 dns_view_ntacovers(dns_view_t *view, isc_stdtime_t now, 1910 const dns_name_t *name, const dns_name_t *anchor) 1911 { 1912 REQUIRE(DNS_VIEW_VALID(view)); 1913 1914 if (view->ntatable_priv == NULL) 1915 return (ISC_FALSE); 1916 1917 return (dns_ntatable_covered(view->ntatable_priv, now, name, anchor)); 1918 } 1919 1920 isc_result_t 1921 dns_view_issecuredomain(dns_view_t *view, const dns_name_t *name, 1922 isc_stdtime_t now, isc_boolean_t checknta, 1923 isc_boolean_t *secure_domain) 1924 { 1925 isc_result_t result; 1926 isc_boolean_t secure = ISC_FALSE; 1927 dns_fixedname_t fn; 1928 dns_name_t *anchor; 1929 1930 REQUIRE(DNS_VIEW_VALID(view)); 1931 1932 if (view->secroots_priv == NULL) 1933 return (ISC_R_NOTFOUND); 1934 1935 anchor = dns_fixedname_initname(&fn); 1936 1937 result = dns_keytable_issecuredomain(view->secroots_priv, name, 1938 anchor, &secure); 1939 if (result != ISC_R_SUCCESS) 1940 return (result); 1941 1942 if (checknta && secure && view->ntatable_priv != NULL && 1943 dns_ntatable_covered(view->ntatable_priv, now, name, anchor)) 1944 secure = ISC_FALSE; 1945 1946 *secure_domain = secure; 1947 return (ISC_R_SUCCESS); 1948 } 1949 1950 void 1951 dns_view_untrust(dns_view_t *view, const dns_name_t *keyname, 1952 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) 1953 { 1954 isc_result_t result; 1955 unsigned char data[4096]; 1956 dns_rdata_t rdata = DNS_RDATA_INIT; 1957 isc_buffer_t buffer; 1958 dst_key_t *key = NULL; 1959 dns_keytable_t *sr = NULL; 1960 1961 /* 1962 * Clear the revoke bit, if set, so that the key will match what's 1963 * in secroots now. 1964 */ 1965 dnskey->flags &= ~DNS_KEYFLAG_REVOKE; 1966 1967 /* Convert dnskey to DST key. */ 1968 isc_buffer_init(&buffer, data, sizeof(data)); 1969 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 1970 dns_rdatatype_dnskey, dnskey, &buffer); 1971 1972 result = dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &key); 1973 if (result != ISC_R_SUCCESS) 1974 return; 1975 1976 result = dns_view_getsecroots(view, &sr); 1977 if (result == ISC_R_SUCCESS) { 1978 result = dns_keytable_deletekeynode(sr, key); 1979 1980 /* 1981 * If key was found in secroots, then it was a 1982 * configured trust anchor, and we want to fail 1983 * secure. If there are no other configured keys, 1984 * then leave a null key so that we can't validate 1985 * anymore. 1986 */ 1987 1988 if (result == ISC_R_SUCCESS) 1989 dns_keytable_marksecure(sr, keyname); 1990 1991 dns_keytable_detach(&sr); 1992 } 1993 1994 dst_key_free(&key); 1995 } 1996 1997 /* 1998 * Create path to a directory and a filename contructed from viewname. 1999 * This is a front-end to isc_file_sanitize(), allowing backward 2000 * compatibility to older versions when a file couldn't be expected 2001 * to be in the specified directory but might be in the current working 2002 * directory instead. 2003 * 2004 * It first tests for the existence of a file <viewname>.<suffix> in 2005 * 'directory'. If the file does not exist, it checks again in the 2006 * current working directory. If it does not exist there either, 2007 * return the path inside the directory. 2008 * 2009 * Returns ISC_R_SUCCESS if a path to an existing file is found or 2010 * a new path is created; returns ISC_R_NOSPACE if the path won't 2011 * fit in 'buflen'. 2012 */ 2013 2014 #ifndef PATH_MAX 2015 #define PATH_MAX 1024 2016 #endif 2017 2018 static isc_result_t 2019 nz_legacy(const char *directory, const char *viewname, 2020 const char *suffix, char *buffer, size_t buflen) 2021 { 2022 isc_result_t result; 2023 char newbuf[PATH_MAX]; 2024 2025 result = isc_file_sanitize(directory, viewname, suffix, 2026 buffer, buflen); 2027 if (result != ISC_R_SUCCESS) { 2028 return (result); 2029 } else if (directory == NULL || isc_file_exists(buffer)) { 2030 return (ISC_R_SUCCESS); 2031 } else { 2032 /* Save buffer */ 2033 strlcpy(newbuf, buffer, sizeof(newbuf)); 2034 } 2035 2036 /* 2037 * It isn't in the specified directory; check CWD. 2038 */ 2039 result = isc_file_sanitize(NULL, viewname, suffix, buffer, buflen); 2040 if (result != ISC_R_SUCCESS || isc_file_exists(buffer)) { 2041 return (result); 2042 } 2043 2044 /* 2045 * File does not exist in either 'directory' or CWD, 2046 * so use the path in 'directory'. 2047 */ 2048 strlcpy(buffer, newbuf, buflen); 2049 return (ISC_R_SUCCESS); 2050 } 2051 2052 isc_result_t 2053 dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx, 2054 void (*cfg_destroy)(void **), isc_uint64_t mapsize) 2055 { 2056 isc_result_t result = ISC_R_SUCCESS; 2057 char buffer[1024]; 2058 #ifdef HAVE_LMDB 2059 MDB_env *env = NULL; 2060 int status; 2061 #endif 2062 2063 #ifndef HAVE_LMDB 2064 UNUSED(mapsize); 2065 #endif 2066 2067 REQUIRE(DNS_VIEW_VALID(view)); 2068 REQUIRE((cfgctx != NULL && cfg_destroy != NULL) || !allow); 2069 2070 if (view->new_zone_file != NULL) { 2071 isc_mem_free(view->mctx, view->new_zone_file); 2072 view->new_zone_file = NULL; 2073 } 2074 2075 #ifdef HAVE_LMDB 2076 if (view->new_zone_dbenv != NULL) { 2077 mdb_env_close((MDB_env *) view->new_zone_dbenv); 2078 view->new_zone_dbenv = NULL; 2079 } 2080 2081 if (view->new_zone_db != NULL) { 2082 isc_mem_free(view->mctx, view->new_zone_db); 2083 view->new_zone_db = NULL; 2084 } 2085 #endif /* HAVE_LMDB */ 2086 2087 if (view->new_zone_config != NULL) { 2088 view->cfg_destroy(&view->new_zone_config); 2089 view->cfg_destroy = NULL; 2090 } 2091 2092 if (!allow) { 2093 return (ISC_R_SUCCESS); 2094 } 2095 2096 CHECK(nz_legacy(view->new_zone_dir, view->name, "nzf", 2097 buffer, sizeof(buffer))); 2098 2099 view->new_zone_file = isc_mem_strdup(view->mctx, buffer); 2100 if (view->new_zone_file == NULL) { 2101 CHECK(ISC_R_NOMEMORY); 2102 } 2103 2104 #ifdef HAVE_LMDB 2105 CHECK(nz_legacy(view->new_zone_dir, view->name, "nzd", 2106 buffer, sizeof(buffer))); 2107 2108 view->new_zone_db = isc_mem_strdup(view->mctx, buffer); 2109 if (view->new_zone_db == NULL) { 2110 CHECK(ISC_R_NOMEMORY); 2111 } 2112 2113 status = mdb_env_create(&env); 2114 if (status != MDB_SUCCESS) { 2115 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 2116 ISC_LOGMODULE_OTHER, ISC_LOG_ERROR, 2117 "mdb_env_create failed: %s", 2118 mdb_strerror(status)); 2119 CHECK(ISC_R_FAILURE); 2120 } 2121 2122 if (mapsize != 0ULL) { 2123 status = mdb_env_set_mapsize(env, mapsize); 2124 if (status != MDB_SUCCESS) { 2125 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 2126 ISC_LOGMODULE_OTHER, ISC_LOG_ERROR, 2127 "mdb_env_set_mapsize failed: %s", 2128 mdb_strerror(status)); 2129 CHECK(ISC_R_FAILURE); 2130 } 2131 view->new_zone_mapsize = mapsize; 2132 } 2133 2134 status = mdb_env_open(env, view->new_zone_db, DNS_LMDB_FLAGS, 0600); 2135 if (status != MDB_SUCCESS) { 2136 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 2137 ISC_LOGMODULE_OTHER, ISC_LOG_ERROR, 2138 "mdb_env_open of '%s' failed: %s", 2139 view->new_zone_db, mdb_strerror(status)); 2140 CHECK(ISC_R_FAILURE); 2141 } 2142 2143 view->new_zone_dbenv = env; 2144 env = NULL; 2145 #endif /* HAVE_LMDB */ 2146 2147 view->new_zone_config = cfgctx; 2148 view->cfg_destroy = cfg_destroy; 2149 2150 cleanup: 2151 if (result != ISC_R_SUCCESS) { 2152 if (view->new_zone_file != NULL) { 2153 isc_mem_free(view->mctx, view->new_zone_file); 2154 view->new_zone_file = NULL; 2155 } 2156 2157 #ifdef HAVE_LMDB 2158 if (view->new_zone_db != NULL) { 2159 isc_mem_free(view->mctx, view->new_zone_db); 2160 view->new_zone_db = NULL; 2161 } 2162 if (env != NULL) { 2163 mdb_env_close(env); 2164 } 2165 #endif /* HAVE_LMDB */ 2166 view->new_zone_config = NULL; 2167 view->cfg_destroy = NULL; 2168 } 2169 2170 return (result); 2171 } 2172 2173 void 2174 dns_view_setnewzonedir(dns_view_t *view, const char *dir) { 2175 REQUIRE(DNS_VIEW_VALID(view)); 2176 2177 if (view->new_zone_dir != NULL) { 2178 isc_mem_free(view->mctx, view->new_zone_dir); 2179 view->new_zone_dir = NULL; 2180 } 2181 2182 if (dir == NULL) { 2183 return; 2184 } 2185 2186 view->new_zone_dir = isc_mem_strdup(view->mctx, dir); 2187 } 2188 2189 const char * 2190 dns_view_getnewzonedir(dns_view_t *view) { 2191 REQUIRE(DNS_VIEW_VALID(view)); 2192 2193 return (view->new_zone_dir); 2194 } 2195 2196 isc_result_t 2197 dns_view_searchdlz(dns_view_t *view, const dns_name_t *name, 2198 unsigned int minlabels, dns_clientinfomethods_t *methods, 2199 dns_clientinfo_t *clientinfo, dns_db_t **dbp) 2200 { 2201 dns_fixedname_t fname; 2202 dns_name_t *zonename; 2203 unsigned int namelabels; 2204 unsigned int i; 2205 isc_result_t result; 2206 dns_dlzfindzone_t findzone; 2207 dns_dlzdb_t *dlzdb; 2208 dns_db_t *db, *best = NULL; 2209 2210 /* 2211 * Performs checks to make sure data is as we expect it to be. 2212 */ 2213 REQUIRE(DNS_VIEW_VALID(view)); 2214 REQUIRE(name != NULL); 2215 REQUIRE(dbp != NULL && *dbp == NULL); 2216 2217 /* setup a "fixed" dns name */ 2218 zonename = dns_fixedname_initname(&fname); 2219 2220 /* count the number of labels in the name */ 2221 namelabels = dns_name_countlabels(name); 2222 2223 for (dlzdb = ISC_LIST_HEAD(view->dlz_searched); 2224 dlzdb != NULL; 2225 dlzdb = ISC_LIST_NEXT(dlzdb, link)) 2226 { 2227 REQUIRE(DNS_DLZ_VALID(dlzdb)); 2228 2229 /* 2230 * loop through starting with the longest domain name and 2231 * trying shorter names portions of the name until we find a 2232 * match, have an error, or are below the 'minlabels' 2233 * threshold. minlabels is 0, if neither the standard 2234 * database nor any previous DLZ database had a zone name 2235 * match. Otherwise minlabels is the number of labels 2236 * in that name. We need to beat that for a "better" 2237 * match for this DLZ database to be authoritative. 2238 */ 2239 for (i = namelabels; i > minlabels && i > 1; i--) { 2240 if (i == namelabels) { 2241 result = dns_name_copy(name, zonename, NULL); 2242 if (result != ISC_R_SUCCESS) 2243 return (result); 2244 } else 2245 dns_name_split(name, i, NULL, zonename); 2246 2247 /* ask SDLZ driver if the zone is supported */ 2248 db = NULL; 2249 findzone = dlzdb->implementation->methods->findzone; 2250 result = (*findzone)(dlzdb->implementation->driverarg, 2251 dlzdb->dbdata, dlzdb->mctx, 2252 view->rdclass, zonename, 2253 methods, clientinfo, &db); 2254 2255 if (result != ISC_R_NOTFOUND) { 2256 if (best != NULL) 2257 dns_db_detach(&best); 2258 if (result == ISC_R_SUCCESS) { 2259 INSIST(db != NULL); 2260 dns_db_attach(db, &best); 2261 dns_db_detach(&db); 2262 minlabels = i; 2263 } else { 2264 if (db != NULL) 2265 dns_db_detach(&db); 2266 break; 2267 } 2268 } else if (db != NULL) 2269 dns_db_detach(&db); 2270 } 2271 } 2272 2273 if (best != NULL) { 2274 dns_db_attach(best, dbp); 2275 dns_db_detach(&best); 2276 return (ISC_R_SUCCESS); 2277 } 2278 2279 return (ISC_R_NOTFOUND); 2280 } 2281 2282 isc_uint32_t 2283 dns_view_getfailttl(dns_view_t *view) { 2284 REQUIRE(DNS_VIEW_VALID(view)); 2285 return (view->fail_ttl); 2286 } 2287 2288 void 2289 dns_view_setfailttl(dns_view_t *view, isc_uint32_t fail_ttl) { 2290 REQUIRE(DNS_VIEW_VALID(view)); 2291 view->fail_ttl = fail_ttl; 2292 } 2293 2294 isc_result_t 2295 dns_view_saventa(dns_view_t *view) { 2296 isc_result_t result; 2297 isc_boolean_t removefile = ISC_FALSE; 2298 dns_ntatable_t *ntatable = NULL; 2299 FILE *fp = NULL; 2300 2301 REQUIRE(DNS_VIEW_VALID(view)); 2302 2303 if (view->nta_lifetime == 0) 2304 return (ISC_R_SUCCESS); 2305 2306 /* Open NTA save file for overwrite. */ 2307 CHECK(isc_stdio_open(view->nta_file, "w", &fp)); 2308 2309 result = dns_view_getntatable(view, &ntatable); 2310 if (result == ISC_R_NOTFOUND) { 2311 removefile = ISC_TRUE; 2312 result = ISC_R_SUCCESS; 2313 goto cleanup; 2314 } else 2315 CHECK(result); 2316 2317 result = dns_ntatable_save(ntatable, fp); 2318 if (result == ISC_R_NOTFOUND) { 2319 removefile = ISC_TRUE; 2320 result = ISC_R_SUCCESS; 2321 } else if (result == ISC_R_SUCCESS) { 2322 result = isc_stdio_close(fp); 2323 fp = NULL; 2324 } 2325 2326 cleanup: 2327 if (ntatable != NULL) 2328 dns_ntatable_detach(&ntatable); 2329 2330 if (fp != NULL) 2331 (void)isc_stdio_close(fp); 2332 2333 /* Don't leave half-baked NTA save files lying around. */ 2334 if (result != ISC_R_SUCCESS || removefile) 2335 (void) isc_file_remove(view->nta_file); 2336 2337 return (result); 2338 } 2339 2340 #define TSTR(t) ((t).value.as_textregion.base) 2341 #define TLEN(t) ((t).value.as_textregion.length) 2342 2343 isc_result_t 2344 dns_view_loadnta(dns_view_t *view) { 2345 isc_result_t result; 2346 dns_ntatable_t *ntatable = NULL; 2347 isc_lex_t *lex = NULL; 2348 isc_token_t token; 2349 isc_stdtime_t now; 2350 2351 REQUIRE(DNS_VIEW_VALID(view)); 2352 2353 if (view->nta_lifetime == 0) 2354 return (ISC_R_SUCCESS); 2355 2356 CHECK(isc_lex_create(view->mctx, 1025, &lex)); 2357 CHECK(isc_lex_openfile(lex, view->nta_file)); 2358 CHECK(dns_view_getntatable(view, &ntatable)); 2359 isc_stdtime_get(&now); 2360 2361 for (;;) { 2362 int options = (ISC_LEXOPT_EOL | ISC_LEXOPT_EOF); 2363 char *name, *type, *timestamp; 2364 size_t len; 2365 dns_fixedname_t fn; 2366 const dns_name_t *ntaname; 2367 isc_buffer_t b; 2368 isc_stdtime_t t; 2369 isc_boolean_t forced; 2370 2371 CHECK(isc_lex_gettoken(lex, options, &token)); 2372 if (token.type == isc_tokentype_eof) 2373 break; 2374 else if (token.type != isc_tokentype_string) 2375 CHECK(ISC_R_UNEXPECTEDTOKEN); 2376 name = TSTR(token); 2377 len = TLEN(token); 2378 2379 if (strcmp(name, ".") == 0) 2380 ntaname = dns_rootname; 2381 else { 2382 dns_name_t *fname; 2383 fname = dns_fixedname_initname(&fn); 2384 2385 isc_buffer_init(&b, name, (unsigned int)len); 2386 isc_buffer_add(&b, (unsigned int)len); 2387 CHECK(dns_name_fromtext(fname, &b, dns_rootname, 2388 0, NULL)); 2389 ntaname = fname; 2390 } 2391 2392 CHECK(isc_lex_gettoken(lex, options, &token)); 2393 if (token.type != isc_tokentype_string) 2394 CHECK(ISC_R_UNEXPECTEDTOKEN); 2395 type = TSTR(token); 2396 2397 if (strcmp(type, "regular") == 0) 2398 forced = ISC_FALSE; 2399 else if (strcmp(type, "forced") == 0) 2400 forced = ISC_TRUE; 2401 else 2402 CHECK(ISC_R_UNEXPECTEDTOKEN); 2403 2404 CHECK(isc_lex_gettoken(lex, options, &token)); 2405 if (token.type != isc_tokentype_string) 2406 CHECK(ISC_R_UNEXPECTEDTOKEN); 2407 timestamp = TSTR(token); 2408 CHECK(dns_time32_fromtext(timestamp, &t)); 2409 2410 CHECK(isc_lex_gettoken(lex, options, &token)); 2411 if (token.type != isc_tokentype_eol && 2412 token.type != isc_tokentype_eof) 2413 CHECK(ISC_R_UNEXPECTEDTOKEN); 2414 2415 if (now <= t) { 2416 if (t > (now + 604800)) 2417 t = now + 604800; 2418 2419 (void) dns_ntatable_add(ntatable, ntaname, 2420 forced, 0, t); 2421 } else { 2422 char nb[DNS_NAME_FORMATSIZE]; 2423 dns_name_format(ntaname, nb, sizeof(nb)); 2424 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, 2425 DNS_LOGMODULE_NTA, ISC_LOG_INFO, 2426 "ignoring expired NTA at %s", nb); 2427 } 2428 }; 2429 2430 cleanup: 2431 if (ntatable != NULL) 2432 dns_ntatable_detach(&ntatable); 2433 2434 if (lex != NULL) { 2435 isc_lex_close(lex); 2436 isc_lex_destroy(&lex); 2437 } 2438 2439 return (result); 2440 } 2441 2442 void 2443 dns_view_setviewcommit(dns_view_t *view) { 2444 REQUIRE(DNS_VIEW_VALID(view)); 2445 2446 LOCK(&view->lock); 2447 2448 if (view->redirect != NULL) { 2449 dns_zone_setviewcommit(view->redirect); 2450 } 2451 if (view->managed_keys != NULL) { 2452 dns_zone_setviewcommit(view->managed_keys); 2453 } 2454 if (view->zonetable != NULL) { 2455 dns_zt_setviewcommit(view->zonetable); 2456 } 2457 2458 UNLOCK(&view->lock); 2459 } 2460 2461 void 2462 dns_view_setviewrevert(dns_view_t *view) { 2463 dns_zt_t *zonetable; 2464 2465 REQUIRE(DNS_VIEW_VALID(view)); 2466 2467 /* 2468 * dns_zt_setviewrevert() attempts to lock this view, so we must 2469 * release the lock. 2470 */ 2471 LOCK(&view->lock); 2472 if (view->redirect != NULL) { 2473 dns_zone_setviewrevert(view->redirect); 2474 } 2475 if (view->managed_keys != NULL) { 2476 dns_zone_setviewrevert(view->managed_keys); 2477 } 2478 zonetable = view->zonetable; 2479 UNLOCK(&view->lock); 2480 2481 if (zonetable != NULL) { 2482 dns_zt_setviewrevert(zonetable); 2483 } 2484 } 2485