1 /* $NetBSD: query.c,v 1.10 2020/08/03 17:23:43 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 <inttypes.h> 17 #include <stdbool.h> 18 #include <string.h> 19 20 #include <isc/hex.h> 21 #include <isc/mem.h> 22 #include <isc/once.h> 23 #include <isc/print.h> 24 #include <isc/random.h> 25 #include <isc/rwlock.h> 26 #include <isc/serial.h> 27 #include <isc/stats.h> 28 #include <isc/string.h> 29 #include <isc/thread.h> 30 #include <isc/util.h> 31 32 #include <dns/adb.h> 33 #include <dns/badcache.h> 34 #include <dns/byaddr.h> 35 #include <dns/cache.h> 36 #include <dns/db.h> 37 #include <dns/dlz.h> 38 #include <dns/dns64.h> 39 #include <dns/dnsrps.h> 40 #include <dns/dnssec.h> 41 #include <dns/events.h> 42 #include <dns/keytable.h> 43 #include <dns/message.h> 44 #include <dns/ncache.h> 45 #include <dns/nsec.h> 46 #include <dns/nsec3.h> 47 #include <dns/order.h> 48 #include <dns/rdata.h> 49 #include <dns/rdataclass.h> 50 #include <dns/rdatalist.h> 51 #include <dns/rdataset.h> 52 #include <dns/rdatasetiter.h> 53 #include <dns/rdatastruct.h> 54 #include <dns/rdatatype.h> 55 #include <dns/resolver.h> 56 #include <dns/result.h> 57 #include <dns/stats.h> 58 #include <dns/tkey.h> 59 #include <dns/types.h> 60 #include <dns/view.h> 61 #include <dns/zone.h> 62 #include <dns/zt.h> 63 64 #include <ns/client.h> 65 #include <ns/hooks.h> 66 #include <ns/interfacemgr.h> 67 #include <ns/log.h> 68 #include <ns/server.h> 69 #include <ns/sortlist.h> 70 #include <ns/stats.h> 71 #include <ns/xfrout.h> 72 73 #include <ns/pfilter.h> 74 75 #if 0 76 /* 77 * It has been recommended that DNS64 be changed to return excluded 78 * AAAA addresses if DNS64 synthesis does not occur. This minimises 79 * the impact on the lookup results. While most DNS AAAA lookups are 80 * done to send IP packets to a host, not all of them are and filtering 81 * excluded addresses has a negative impact on those uses. 82 */ 83 #define dns64_bis_return_excluded_addresses 1 84 #endif /* if 0 */ 85 86 /*% 87 * Maximum number of chained queries before we give up 88 * to prevent CNAME loops. 89 */ 90 #define MAX_RESTARTS 16 91 92 #define QUERY_ERROR(qctx, r) \ 93 do { \ 94 qctx->result = r; \ 95 qctx->want_restart = false; \ 96 qctx->line = __LINE__; \ 97 } while (/*CONSTCOND*/0) 98 99 /*% Partial answer? */ 100 #define PARTIALANSWER(c) \ 101 (((c)->query.attributes & NS_QUERYATTR_PARTIALANSWER) != 0) 102 /*% Use Cache? */ 103 #define USECACHE(c) (((c)->query.attributes & NS_QUERYATTR_CACHEOK) != 0) 104 /*% Recursion OK? */ 105 #define RECURSIONOK(c) (((c)->query.attributes & NS_QUERYATTR_RECURSIONOK) != 0) 106 /*% Recursing? */ 107 #define RECURSING(c) (((c)->query.attributes & NS_QUERYATTR_RECURSING) != 0) 108 /*% Want Recursion? */ 109 #define WANTRECURSION(c) \ 110 (((c)->query.attributes & NS_QUERYATTR_WANTRECURSION) != 0) 111 /*% Is TCP? */ 112 #define TCP(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0) 113 114 /*% Want DNSSEC? */ 115 #define WANTDNSSEC(c) (((c)->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0) 116 /*% Want WANTAD? */ 117 #define WANTAD(c) (((c)->attributes & NS_CLIENTATTR_WANTAD) != 0) 118 /*% Client presented a valid COOKIE. */ 119 #define HAVECOOKIE(c) (((c)->attributes & NS_CLIENTATTR_HAVECOOKIE) != 0) 120 /*% Client presented a COOKIE. */ 121 #define WANTCOOKIE(c) (((c)->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0) 122 /*% Client presented a CLIENT-SUBNET option. */ 123 #define HAVEECS(c) (((c)->attributes & NS_CLIENTATTR_HAVEECS) != 0) 124 /*% No authority? */ 125 #define NOAUTHORITY(c) (((c)->query.attributes & NS_QUERYATTR_NOAUTHORITY) != 0) 126 /*% No additional? */ 127 #define NOADDITIONAL(c) \ 128 (((c)->query.attributes & NS_QUERYATTR_NOADDITIONAL) != 0) 129 /*% Secure? */ 130 #define SECURE(c) (((c)->query.attributes & NS_QUERYATTR_SECURE) != 0) 131 /*% DNS64 A lookup? */ 132 #define DNS64(c) (((c)->query.attributes & NS_QUERYATTR_DNS64) != 0) 133 134 #define DNS64EXCLUDE(c) \ 135 (((c)->query.attributes & NS_QUERYATTR_DNS64EXCLUDE) != 0) 136 137 #define REDIRECT(c) (((c)->query.attributes & NS_QUERYATTR_REDIRECT) != 0) 138 139 /*% Does the rdataset 'r' have an attached 'No QNAME Proof'? */ 140 #define NOQNAME(r) (((r)->attributes & DNS_RDATASETATTR_NOQNAME) != 0) 141 142 /*% Does the rdataset 'r' contain a stale answer? */ 143 #define STALE(r) (((r)->attributes & DNS_RDATASETATTR_STALE) != 0) 144 145 #ifdef WANT_QUERYTRACE 146 static inline void 147 client_trace(ns_client_t *client, int level, const char *message) { 148 if (client != NULL && client->query.qname != NULL) { 149 if (isc_log_wouldlog(ns_lctx, level)) { 150 char qbuf[DNS_NAME_FORMATSIZE]; 151 char tbuf[DNS_RDATATYPE_FORMATSIZE]; 152 dns_name_format(client->query.qname, qbuf, 153 sizeof(qbuf)); 154 dns_rdatatype_format(client->query.qtype, tbuf, 155 sizeof(tbuf)); 156 isc_log_write(ns_lctx, NS_LOGCATEGORY_CLIENT, 157 NS_LOGMODULE_QUERY, level, 158 "query client=%p thread=0x%lx " 159 "(%s/%s): %s", 160 client, (unsigned long)isc_thread_self(), 161 qbuf, tbuf, message); 162 } 163 } else { 164 isc_log_write(ns_lctx, NS_LOGCATEGORY_CLIENT, 165 NS_LOGMODULE_QUERY, level, 166 "query client=%p thread=0x%lx " 167 "(<unknown-query>): %s", 168 client, (unsigned long)isc_thread_self(), 169 message); 170 } 171 } 172 #define CTRACE(l, m) client_trace(client, l, m) 173 #define CCTRACE(l, m) client_trace(qctx->client, l, m) 174 #else /* ifdef WANT_QUERYTRACE */ 175 #define CTRACE(l, m) ((void)m) 176 #define CCTRACE(l, m) ((void)m) 177 #endif /* WANT_QUERYTRACE */ 178 179 #define DNS_GETDB_NOEXACT 0x01U 180 #define DNS_GETDB_NOLOG 0x02U 181 #define DNS_GETDB_PARTIAL 0x04U 182 #define DNS_GETDB_IGNOREACL 0x08U 183 184 #define PENDINGOK(x) (((x)&DNS_DBFIND_PENDINGOK) != 0) 185 186 #define SFCACHE_CDFLAG 0x1 187 188 /* 189 * These have the same semantics as: 190 * 191 * foo_attach(b, a); 192 * foo_detach(&a); 193 * 194 * without the locking and magic testing. 195 * 196 * We use SAVE and RESTORE as that shows the operation being performed. 197 */ 198 #define SAVE(a, b) \ 199 do { \ 200 INSIST(a == NULL); \ 201 a = b; \ 202 b = NULL; \ 203 } while (/*CONSTCOND*/0) 204 #define RESTORE(a, b) SAVE(a, b) 205 206 static bool 207 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name, 208 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); 209 210 static void 211 query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, 212 dns_dbversion_t *version, ns_client_t *client, 213 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, 214 dns_name_t *fname, bool exact, dns_name_t *found); 215 216 static inline void 217 log_queryerror(ns_client_t *client, isc_result_t result, int line, int level); 218 219 static void 220 rpz_st_clear(ns_client_t *client); 221 222 static bool 223 rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult, 224 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); 225 226 static void 227 log_noexistnodata(void *val, int level, const char *fmt, ...) 228 ISC_FORMAT_PRINTF(3, 4); 229 230 /* 231 * Return the hooktable in use with 'qctx', or if there isn't one 232 * set, return the default hooktable. 233 */ 234 static inline ns_hooktable_t * 235 get_hooktab(query_ctx_t *qctx) { 236 if (qctx == NULL || qctx->view == NULL || qctx->view->hooktable == NULL) 237 { 238 return (ns__hook_table); 239 } 240 241 return (qctx->view->hooktable); 242 } 243 244 /* 245 * Call the specified hook function in every configured module that implements 246 * that function. If any hook function returns NS_HOOK_RETURN, we 247 * set 'result' and terminate processing by jumping to the 'cleanup' tag. 248 * 249 * (Note that a hook function may set the 'result' to ISC_R_SUCCESS but 250 * still terminate processing within the calling function. That's why this 251 * is a macro instead of an inline function; it needs to be able to use 252 * 'goto cleanup' regardless of the return value.) 253 */ 254 #define CALL_HOOK(_id, _qctx) \ 255 do { \ 256 isc_result_t _res; \ 257 ns_hooktable_t *_tab = get_hooktab(_qctx); \ 258 ns_hook_t *_hook; \ 259 _hook = ISC_LIST_HEAD((*_tab)[_id]); \ 260 while (_hook != NULL) { \ 261 ns_hook_action_t _func = _hook->action; \ 262 void *_data = _hook->action_data; \ 263 INSIST(_func != NULL); \ 264 switch (_func(_qctx, _data, &_res)) { \ 265 case NS_HOOK_CONTINUE: \ 266 _hook = ISC_LIST_NEXT(_hook, link); \ 267 break; \ 268 case NS_HOOK_RETURN: \ 269 result = _res; \ 270 goto cleanup; \ 271 default: \ 272 INSIST(0); \ 273 } \ 274 } \ 275 } while (false) 276 277 /* 278 * Call the specified hook function in every configured module that 279 * implements that function. All modules are called; hook function return 280 * codes are ignored. This is intended for use with initialization and 281 * destruction calls which *must* run in every configured module. 282 * 283 * (This could be implemented as an inline void function, but is left as a 284 * macro for symmetry with CALL_HOOK above.) 285 */ 286 #define CALL_HOOK_NORETURN(_id, _qctx) \ 287 do { \ 288 isc_result_t _res; \ 289 ns_hooktable_t *_tab = get_hooktab(_qctx); \ 290 ns_hook_t *_hook; \ 291 _hook = ISC_LIST_HEAD((*_tab)[_id]); \ 292 while (_hook != NULL) { \ 293 ns_hook_action_t _func = _hook->action; \ 294 void *_data = _hook->action_data; \ 295 INSIST(_func != NULL); \ 296 _func(_qctx, _data, &_res); \ 297 _hook = ISC_LIST_NEXT(_hook, link); \ 298 } \ 299 } while (false) 300 301 /* 302 * The functions defined below implement the query logic that previously lived 303 * in the single very complex function query_find(). The query_ctx_t structure 304 * defined in <ns/query.h> maintains state from function to function. The call 305 * flow for the general query processing algorithm is described below: 306 * 307 * 1. Set up query context and other resources for a client 308 * query (query_setup()) 309 * 310 * 2. Start the search (ns__query_start()) 311 * 312 * 3. Identify authoritative data sources which may have an answer; 313 * search them (query_lookup()). If an answer is found, go to 7. 314 * 315 * 4. If recursion or cache access are allowed, search the cache 316 * (query_lookup() again, using the cache database) to find a better 317 * answer. If an answer is found, go to 7. 318 * 319 * 5. If recursion is allowed, begin recursion (ns_query_recurse()). 320 * Go to 15 to clean up this phase of the query. When recursion 321 * is complete, processing will resume at 6. 322 * 323 * 6. Resume from recursion; set up query context for resumed processing. 324 * 325 * 7. Determine what sort of answer we've found (query_gotanswer()) 326 * and call other functions accordingly: 327 * - not found (auth or cache), go to 8 328 * - delegation, go to 9 329 * - no such domain (auth), go to 10 330 * - empty answer (auth), go to 11 331 * - negative response (cache), go to 12 332 * - answer found, go to 13 333 * 334 * 8. The answer was not found in the database (query_notfound(). 335 * Set up a referral and go to 9. 336 * 337 * 9. Handle a delegation response (query_delegation()). If we need 338 * to and are allowed to recurse (query_delegation_recurse()), go to 5, 339 * otherwise go to 15 to clean up and return the delegation to the client. 340 * 341 * 10. No such domain (query_nxdomain()). Attempt redirection; if 342 * unsuccessful, add authority section records (query_addsoa(), 343 * query_addauth()), then go to 15 to return NXDOMAIN to client. 344 * 345 * 11. Empty answer (query_nodata()). Add authority section records 346 * (query_addsoa(), query_addauth()) and signatures if authoritative 347 * (query_sign_nodata()) then go to 15 and return 348 * NOERROR/ANCOUNT=0 to client. 349 * 350 * 12. No such domain or empty answer returned from cache (query_ncache()). 351 * Set response code appropriately, go to 11. 352 * 353 * 13. Prepare a response (query_prepresponse()) and then fill it 354 * appropriately (query_respond(), or for type ANY, 355 * query_respond_any()). 356 * 357 * 14. If a restart is needed due to CNAME/DNAME chaining, go to 2. 358 * 359 * 15. Clean up resources. If recursing, stop and wait for the event 360 * handler to be called back (step 6). If an answer is ready, 361 * return it to the client. 362 * 363 * (XXX: This description omits several special cases including 364 * DNS64, RPZ, RRL, and the SERVFAIL cache. It also doesn't discuss 365 * plugins.) 366 */ 367 368 static void 369 query_trace(query_ctx_t *qctx); 370 371 static void 372 qctx_init(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype, 373 query_ctx_t *qctx); 374 375 static isc_result_t 376 query_setup(ns_client_t *client, dns_rdatatype_t qtype); 377 378 static isc_result_t 379 query_lookup(query_ctx_t *qctx); 380 381 static void 382 fetch_callback(isc_task_t *task, isc_event_t *event); 383 384 static void 385 recparam_update(ns_query_recparam_t *param, dns_rdatatype_t qtype, 386 const dns_name_t *qname, const dns_name_t *qdomain); 387 388 static isc_result_t 389 query_resume(query_ctx_t *qctx); 390 391 static isc_result_t 392 query_checkrrl(query_ctx_t *qctx, isc_result_t result); 393 394 static isc_result_t 395 query_checkrpz(query_ctx_t *qctx, isc_result_t result); 396 397 static isc_result_t 398 query_rpzcname(query_ctx_t *qctx, dns_name_t *cname); 399 400 static isc_result_t 401 query_gotanswer(query_ctx_t *qctx, isc_result_t result); 402 403 static void 404 query_addnoqnameproof(query_ctx_t *qctx); 405 406 static isc_result_t 407 query_respond_any(query_ctx_t *qctx); 408 409 static isc_result_t 410 query_respond(query_ctx_t *qctx); 411 412 static isc_result_t 413 query_dns64(query_ctx_t *qctx); 414 415 static void 416 query_filter64(query_ctx_t *qctx); 417 418 static isc_result_t 419 query_notfound(query_ctx_t *qctx); 420 421 static isc_result_t 422 query_zone_delegation(query_ctx_t *qctx); 423 424 static isc_result_t 425 query_delegation(query_ctx_t *qctx); 426 427 static isc_result_t 428 query_delegation_recurse(query_ctx_t *qctx); 429 430 static void 431 query_addds(query_ctx_t *qctx); 432 433 static isc_result_t 434 query_nodata(query_ctx_t *qctx, isc_result_t result); 435 436 static isc_result_t 437 query_sign_nodata(query_ctx_t *qctx); 438 439 static void 440 query_addnxrrsetnsec(query_ctx_t *qctx); 441 442 static isc_result_t 443 query_nxdomain(query_ctx_t *qctx, bool empty_wild); 444 445 static isc_result_t 446 query_redirect(query_ctx_t *qctx); 447 448 static isc_result_t 449 query_ncache(query_ctx_t *qctx, isc_result_t result); 450 451 static isc_result_t 452 query_coveringnsec(query_ctx_t *qctx); 453 454 static isc_result_t 455 query_zerottl_refetch(query_ctx_t *qctx); 456 457 static isc_result_t 458 query_cname(query_ctx_t *qctx); 459 460 static isc_result_t 461 query_dname(query_ctx_t *qctx); 462 463 static isc_result_t 464 query_addcname(query_ctx_t *qctx, dns_trust_t trust, dns_ttl_t ttl); 465 466 static isc_result_t 467 query_prepresponse(query_ctx_t *qctx); 468 469 static isc_result_t 470 query_addsoa(query_ctx_t *qctx, unsigned int override_ttl, 471 dns_section_t section); 472 473 static isc_result_t 474 query_addns(query_ctx_t *qctx); 475 476 static void 477 query_addbestns(query_ctx_t *qctx); 478 479 static void 480 query_addwildcardproof(query_ctx_t *qctx, bool ispositive, bool nodata); 481 482 static void 483 query_addauth(query_ctx_t *qctx); 484 485 /* 486 * Increment query statistics counters. 487 */ 488 static inline void 489 inc_stats(ns_client_t *client, isc_statscounter_t counter) { 490 dns_zone_t *zone = client->query.authzone; 491 dns_rdatatype_t qtype; 492 dns_rdataset_t *rdataset; 493 isc_stats_t *zonestats; 494 dns_stats_t *querystats = NULL; 495 496 ns_stats_increment(client->sctx->nsstats, counter); 497 498 if (zone == NULL) { 499 return; 500 } 501 502 /* Do regular response type stats */ 503 zonestats = dns_zone_getrequeststats(zone); 504 505 if (zonestats != NULL) { 506 isc_stats_increment(zonestats, counter); 507 } 508 509 /* Do query type statistics 510 * 511 * We only increment per-type if we're using the authoritative 512 * answer counter, preventing double-counting. 513 */ 514 if (counter == ns_statscounter_authans) { 515 querystats = dns_zone_getrcvquerystats(zone); 516 if (querystats != NULL) { 517 rdataset = ISC_LIST_HEAD(client->query.qname->list); 518 if (rdataset != NULL) { 519 qtype = rdataset->type; 520 dns_rdatatypestats_increment(querystats, qtype); 521 } 522 } 523 } 524 } 525 526 static void 527 query_send(ns_client_t *client) { 528 isc_statscounter_t counter; 529 530 if ((client->message->flags & DNS_MESSAGEFLAG_AA) == 0) { 531 inc_stats(client, ns_statscounter_nonauthans); 532 } else { 533 inc_stats(client, ns_statscounter_authans); 534 } 535 536 if (client->message->rcode == dns_rcode_noerror) { 537 dns_section_t answer = DNS_SECTION_ANSWER; 538 if (ISC_LIST_EMPTY(client->message->sections[answer])) { 539 if (client->query.isreferral) { 540 counter = ns_statscounter_referral; 541 } else { 542 counter = ns_statscounter_nxrrset; 543 } 544 } else { 545 counter = ns_statscounter_success; 546 } 547 } else if (client->message->rcode == dns_rcode_nxdomain) { 548 counter = ns_statscounter_nxdomain; 549 } else if (client->message->rcode == dns_rcode_badcookie) { 550 counter = ns_statscounter_badcookie; 551 } else { /* We end up here in case of YXDOMAIN, and maybe others */ 552 counter = ns_statscounter_failure; 553 } 554 555 inc_stats(client, counter); 556 ns_client_send(client); 557 isc_nmhandle_unref(client->handle); 558 } 559 560 static void 561 query_error(ns_client_t *client, isc_result_t result, int line) { 562 int loglevel = ISC_LOG_DEBUG(3); 563 564 switch (dns_result_torcode(result)) { 565 case dns_rcode_servfail: 566 loglevel = ISC_LOG_DEBUG(1); 567 inc_stats(client, ns_statscounter_servfail); 568 break; 569 case dns_rcode_formerr: 570 inc_stats(client, ns_statscounter_formerr); 571 break; 572 default: 573 inc_stats(client, ns_statscounter_failure); 574 break; 575 } 576 577 if ((client->sctx->options & NS_SERVER_LOGQUERIES) != 0) { 578 loglevel = ISC_LOG_INFO; 579 } 580 581 log_queryerror(client, result, line, loglevel); 582 583 ns_client_error(client, result); 584 isc_nmhandle_unref(client->handle); 585 } 586 587 static void 588 query_next(ns_client_t *client, isc_result_t result) { 589 if (result == DNS_R_DUPLICATE) { 590 inc_stats(client, ns_statscounter_duplicate); 591 } else if (result == DNS_R_DROP) { 592 inc_stats(client, ns_statscounter_dropped); 593 } else { 594 inc_stats(client, ns_statscounter_failure); 595 } 596 ns_client_drop(client, result); 597 isc_nmhandle_unref(client->handle); 598 } 599 600 static inline void 601 query_freefreeversions(ns_client_t *client, bool everything) { 602 ns_dbversion_t *dbversion, *dbversion_next; 603 unsigned int i; 604 605 for (dbversion = ISC_LIST_HEAD(client->query.freeversions), i = 0; 606 dbversion != NULL; dbversion = dbversion_next, i++) 607 { 608 dbversion_next = ISC_LIST_NEXT(dbversion, link); 609 /* 610 * If we're not freeing everything, we keep the first three 611 * dbversions structures around. 612 */ 613 if (i > 3 || everything) { 614 ISC_LIST_UNLINK(client->query.freeversions, dbversion, 615 link); 616 isc_mem_put(client->mctx, dbversion, 617 sizeof(*dbversion)); 618 } 619 } 620 } 621 622 void 623 ns_query_cancel(ns_client_t *client) { 624 REQUIRE(NS_CLIENT_VALID(client)); 625 626 LOCK(&client->query.fetchlock); 627 if (client->query.fetch != NULL) { 628 dns_resolver_cancelfetch(client->query.fetch); 629 630 client->query.fetch = NULL; 631 } 632 UNLOCK(&client->query.fetchlock); 633 } 634 635 static inline void 636 query_reset(ns_client_t *client, bool everything) { 637 isc_buffer_t *dbuf, *dbuf_next; 638 ns_dbversion_t *dbversion, *dbversion_next; 639 640 CTRACE(ISC_LOG_DEBUG(3), "query_reset"); 641 642 /*% 643 * Reset the query state of a client to its default state. 644 */ 645 646 /* 647 * Cancel the fetch if it's running. 648 */ 649 ns_query_cancel(client); 650 651 /* 652 * Cleanup any active versions. 653 */ 654 for (dbversion = ISC_LIST_HEAD(client->query.activeversions); 655 dbversion != NULL; dbversion = dbversion_next) 656 { 657 dbversion_next = ISC_LIST_NEXT(dbversion, link); 658 dns_db_closeversion(dbversion->db, &dbversion->version, false); 659 dns_db_detach(&dbversion->db); 660 ISC_LIST_INITANDAPPEND(client->query.freeversions, dbversion, 661 link); 662 } 663 ISC_LIST_INIT(client->query.activeversions); 664 665 if (client->query.authdb != NULL) { 666 dns_db_detach(&client->query.authdb); 667 } 668 if (client->query.authzone != NULL) { 669 dns_zone_detach(&client->query.authzone); 670 } 671 672 if (client->query.dns64_aaaa != NULL) { 673 ns_client_putrdataset(client, &client->query.dns64_aaaa); 674 } 675 if (client->query.dns64_sigaaaa != NULL) { 676 ns_client_putrdataset(client, &client->query.dns64_sigaaaa); 677 } 678 if (client->query.dns64_aaaaok != NULL) { 679 isc_mem_put(client->mctx, client->query.dns64_aaaaok, 680 client->query.dns64_aaaaoklen * sizeof(bool)); 681 client->query.dns64_aaaaok = NULL; 682 client->query.dns64_aaaaoklen = 0; 683 } 684 685 ns_client_putrdataset(client, &client->query.redirect.rdataset); 686 ns_client_putrdataset(client, &client->query.redirect.sigrdataset); 687 if (client->query.redirect.db != NULL) { 688 if (client->query.redirect.node != NULL) { 689 dns_db_detachnode(client->query.redirect.db, 690 &client->query.redirect.node); 691 } 692 dns_db_detach(&client->query.redirect.db); 693 } 694 if (client->query.redirect.zone != NULL) { 695 dns_zone_detach(&client->query.redirect.zone); 696 } 697 698 query_freefreeversions(client, everything); 699 700 for (dbuf = ISC_LIST_HEAD(client->query.namebufs); dbuf != NULL; 701 dbuf = dbuf_next) 702 { 703 dbuf_next = ISC_LIST_NEXT(dbuf, link); 704 if (dbuf_next != NULL || everything) { 705 ISC_LIST_UNLINK(client->query.namebufs, dbuf, link); 706 isc_buffer_free(&dbuf); 707 } 708 } 709 710 if (client->query.restarts > 0) { 711 /* 712 * client->query.qname was dynamically allocated. 713 */ 714 dns_message_puttempname(client->message, &client->query.qname); 715 } 716 client->query.qname = NULL; 717 client->query.attributes = (NS_QUERYATTR_RECURSIONOK | 718 NS_QUERYATTR_CACHEOK | NS_QUERYATTR_SECURE); 719 client->query.restarts = 0; 720 client->query.timerset = false; 721 if (client->query.rpz_st != NULL) { 722 rpz_st_clear(client); 723 if (everything) { 724 INSIST(client->query.rpz_st->rpsdb == NULL); 725 isc_mem_put(client->mctx, client->query.rpz_st, 726 sizeof(*client->query.rpz_st)); 727 client->query.rpz_st = NULL; 728 } 729 } 730 client->query.origqname = NULL; 731 client->query.dboptions = 0; 732 client->query.fetchoptions = 0; 733 client->query.gluedb = NULL; 734 client->query.authdbset = false; 735 client->query.isreferral = false; 736 client->query.dns64_options = 0; 737 client->query.dns64_ttl = UINT32_MAX; 738 recparam_update(&client->query.recparam, 0, NULL, NULL); 739 client->query.root_key_sentinel_keyid = 0; 740 client->query.root_key_sentinel_is_ta = false; 741 client->query.root_key_sentinel_not_ta = false; 742 } 743 744 static void 745 query_cleanup(ns_client_t *client) { 746 query_reset(client, false); 747 } 748 749 void 750 ns_query_free(ns_client_t *client) { 751 REQUIRE(NS_CLIENT_VALID(client)); 752 753 query_reset(client, true); 754 } 755 756 isc_result_t 757 ns_query_init(ns_client_t *client) { 758 isc_result_t result; 759 760 REQUIRE(NS_CLIENT_VALID(client)); 761 762 ISC_LIST_INIT(client->query.namebufs); 763 ISC_LIST_INIT(client->query.activeversions); 764 ISC_LIST_INIT(client->query.freeversions); 765 client->query.restarts = 0; 766 client->query.timerset = false; 767 client->query.rpz_st = NULL; 768 client->query.qname = NULL; 769 /* 770 * This mutex is destroyed when the client is destroyed in 771 * exit_check(). 772 */ 773 isc_mutex_init(&client->query.fetchlock); 774 775 client->query.fetch = NULL; 776 client->query.prefetch = NULL; 777 client->query.authdb = NULL; 778 client->query.authzone = NULL; 779 client->query.authdbset = false; 780 client->query.isreferral = false; 781 client->query.dns64_aaaa = NULL; 782 client->query.dns64_sigaaaa = NULL; 783 client->query.dns64_aaaaok = NULL; 784 client->query.dns64_aaaaoklen = 0; 785 client->query.redirect.db = NULL; 786 client->query.redirect.node = NULL; 787 client->query.redirect.zone = NULL; 788 client->query.redirect.qtype = dns_rdatatype_none; 789 client->query.redirect.result = ISC_R_SUCCESS; 790 client->query.redirect.rdataset = NULL; 791 client->query.redirect.sigrdataset = NULL; 792 client->query.redirect.authoritative = false; 793 client->query.redirect.is_zone = false; 794 client->query.redirect.fname = 795 dns_fixedname_initname(&client->query.redirect.fixed); 796 query_reset(client, false); 797 result = ns_client_newdbversion(client, 3); 798 if (result != ISC_R_SUCCESS) { 799 isc_mutex_destroy(&client->query.fetchlock); 800 return (result); 801 } 802 result = ns_client_newnamebuf(client); 803 if (result != ISC_R_SUCCESS) { 804 query_freefreeversions(client, true); 805 isc_mutex_destroy(&client->query.fetchlock); 806 } 807 808 return (result); 809 } 810 811 /*% 812 * Check if 'client' is allowed to query the cache of its associated view. 813 * Unless 'options' has DNS_GETDB_NOLOG set, log the result of cache ACL 814 * evaluation using the appropriate level, along with 'name' and 'qtype'. 815 * 816 * The cache ACL is only evaluated once for each client and then the result is 817 * cached: if NS_QUERYATTR_CACHEACLOKVALID is set in client->query.attributes, 818 * cache ACL evaluation has already been performed. The evaluation result is 819 * also stored in client->query.attributes: if NS_QUERYATTR_CACHEACLOK is set, 820 * the client is allowed cache access. 821 * 822 * Returns: 823 * 824 *\li #ISC_R_SUCCESS 'client' is allowed to access cache 825 *\li #DNS_R_REFUSED 'client' is not allowed to access cache 826 */ 827 static isc_result_t 828 query_checkcacheaccess(ns_client_t *client, const dns_name_t *name, 829 dns_rdatatype_t qtype, unsigned int options) { 830 isc_result_t result; 831 832 if ((client->query.attributes & NS_QUERYATTR_CACHEACLOKVALID) == 0) { 833 /* 834 * The view's cache ACLs have not yet been evaluated. 835 * Do it now. Both allow-query-cache and 836 * allow-query-cache-on must be satsified. 837 */ 838 bool log = ((options & DNS_GETDB_NOLOG) == 0); 839 char msg[NS_CLIENT_ACLMSGSIZE("query (cache)")]; 840 841 result = ns_client_checkaclsilent(client, NULL, 842 client->view->cacheacl, true); 843 if (result == ISC_R_SUCCESS) { 844 result = ns_client_checkaclsilent( 845 client, &client->destaddr, 846 client->view->cacheonacl, true); 847 } 848 if (result == ISC_R_SUCCESS) { 849 /* 850 * We were allowed by the "allow-query-cache" ACL. 851 */ 852 client->query.attributes |= NS_QUERYATTR_CACHEACLOK; 853 if (log && isc_log_wouldlog(ns_lctx, ISC_LOG_DEBUG(3))) 854 { 855 ns_client_aclmsg("query (cache)", name, qtype, 856 client->view->rdclass, msg, 857 sizeof(msg)); 858 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 859 NS_LOGMODULE_QUERY, 860 ISC_LOG_DEBUG(3), "%s approved", 861 msg); 862 } 863 } else if (log) { 864 pfilter_notify(result, client, "checkcacheaccess"); 865 866 /* 867 * We were denied by the "allow-query-cache" ACL. 868 * There is no need to clear NS_QUERYATTR_CACHEACLOK 869 * since it is cleared by query_reset(), before query 870 * processing starts. 871 */ 872 ns_client_aclmsg("query (cache)", name, qtype, 873 client->view->rdclass, msg, 874 sizeof(msg)); 875 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 876 NS_LOGMODULE_QUERY, ISC_LOG_INFO, 877 "%s denied", msg); 878 } 879 880 /* 881 * Evaluation has been finished; make sure we will just consult 882 * NS_QUERYATTR_CACHEACLOK for this client from now on. 883 */ 884 client->query.attributes |= NS_QUERYATTR_CACHEACLOKVALID; 885 } 886 887 return ((client->query.attributes & NS_QUERYATTR_CACHEACLOK) != 0 888 ? ISC_R_SUCCESS 889 : DNS_R_REFUSED); 890 } 891 892 static inline isc_result_t 893 query_validatezonedb(ns_client_t *client, const dns_name_t *name, 894 dns_rdatatype_t qtype, unsigned int options, 895 dns_zone_t *zone, dns_db_t *db, 896 dns_dbversion_t **versionp) { 897 isc_result_t result; 898 dns_acl_t *queryacl, *queryonacl; 899 ns_dbversion_t *dbversion; 900 901 REQUIRE(zone != NULL); 902 REQUIRE(db != NULL); 903 904 /* 905 * Mirror zone data is treated as cache data. 906 */ 907 if (dns_zone_gettype(zone) == dns_zone_mirror) { 908 return (query_checkcacheaccess(client, name, qtype, options)); 909 } 910 911 /* 912 * This limits our searching to the zone where the first name 913 * (the query target) was looked for. This prevents following 914 * CNAMES or DNAMES into other zones and prevents returning 915 * additional data from other zones. This does not apply if we're 916 * answering a query where recursion is requested and allowed. 917 */ 918 if (client->query.rpz_st == NULL && 919 !(WANTRECURSION(client) && RECURSIONOK(client)) && 920 client->query.authdbset && db != client->query.authdb) 921 { 922 return (DNS_R_REFUSED); 923 } 924 925 /* 926 * Non recursive query to a static-stub zone is prohibited; its 927 * zone content is not public data, but a part of local configuration 928 * and should not be disclosed. 929 */ 930 if (dns_zone_gettype(zone) == dns_zone_staticstub && 931 !RECURSIONOK(client)) { 932 return (DNS_R_REFUSED); 933 } 934 935 /* 936 * If the zone has an ACL, we'll check it, otherwise 937 * we use the view's "allow-query" ACL. Each ACL is only checked 938 * once per query. 939 * 940 * Also, get the database version to use. 941 */ 942 943 /* 944 * Get the current version of this database. 945 */ 946 dbversion = ns_client_findversion(client, db); 947 if (dbversion == NULL) { 948 CTRACE(ISC_LOG_ERROR, "unable to get db version"); 949 return (DNS_R_SERVFAIL); 950 } 951 952 if ((options & DNS_GETDB_IGNOREACL) != 0) { 953 goto approved; 954 } 955 if (dbversion->acl_checked) { 956 if (!dbversion->queryok) { 957 return (DNS_R_REFUSED); 958 } 959 goto approved; 960 } 961 962 queryacl = dns_zone_getqueryacl(zone); 963 if (queryacl == NULL) { 964 queryacl = client->view->queryacl; 965 if ((client->query.attributes & NS_QUERYATTR_QUERYOKVALID) != 0) 966 { 967 /* 968 * We've evaluated the view's queryacl already. If 969 * NS_QUERYATTR_QUERYOK is set, then the client is 970 * allowed to make queries, otherwise the query should 971 * be refused. 972 */ 973 dbversion->acl_checked = true; 974 if ((client->query.attributes & NS_QUERYATTR_QUERYOK) == 975 0) { 976 dbversion->queryok = false; 977 return (DNS_R_REFUSED); 978 } 979 dbversion->queryok = true; 980 goto approved; 981 } 982 } 983 984 result = ns_client_checkaclsilent(client, NULL, queryacl, true); 985 if ((options & DNS_GETDB_NOLOG) == 0) { 986 char msg[NS_CLIENT_ACLMSGSIZE("query")]; 987 if (result == ISC_R_SUCCESS) { 988 if (isc_log_wouldlog(ns_lctx, ISC_LOG_DEBUG(3))) { 989 ns_client_aclmsg("query", name, qtype, 990 client->view->rdclass, msg, 991 sizeof(msg)); 992 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 993 NS_LOGMODULE_QUERY, 994 ISC_LOG_DEBUG(3), "%s approved", 995 msg); 996 } 997 } else { 998 pfilter_notify(result, client, "validatezonedb"); 999 ns_client_aclmsg("query", name, qtype, 1000 client->view->rdclass, msg, 1001 sizeof(msg)); 1002 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 1003 NS_LOGMODULE_QUERY, ISC_LOG_INFO, 1004 "%s denied", msg); 1005 } 1006 } 1007 1008 if (queryacl == client->view->queryacl) { 1009 if (result == ISC_R_SUCCESS) { 1010 /* 1011 * We were allowed by the default 1012 * "allow-query" ACL. Remember this so we 1013 * don't have to check again. 1014 */ 1015 client->query.attributes |= NS_QUERYATTR_QUERYOK; 1016 } 1017 /* 1018 * We've now evaluated the view's query ACL, and 1019 * the NS_QUERYATTR_QUERYOK attribute is now valid. 1020 */ 1021 client->query.attributes |= NS_QUERYATTR_QUERYOKVALID; 1022 } 1023 1024 /* If and only if we've gotten this far, check allow-query-on too */ 1025 if (result == ISC_R_SUCCESS) { 1026 queryonacl = dns_zone_getqueryonacl(zone); 1027 if (queryonacl == NULL) { 1028 queryonacl = client->view->queryonacl; 1029 } 1030 1031 result = ns_client_checkaclsilent(client, &client->destaddr, 1032 queryonacl, true); 1033 if ((options & DNS_GETDB_NOLOG) == 0 && result != ISC_R_SUCCESS) 1034 { 1035 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 1036 NS_LOGMODULE_QUERY, ISC_LOG_INFO, 1037 "query-on denied"); 1038 } 1039 } 1040 1041 dbversion->acl_checked = true; 1042 if (result != ISC_R_SUCCESS) { 1043 dbversion->queryok = false; 1044 return (DNS_R_REFUSED); 1045 } 1046 dbversion->queryok = true; 1047 1048 approved: 1049 /* Transfer ownership, if necessary. */ 1050 if (versionp != NULL) { 1051 *versionp = dbversion->version; 1052 } 1053 return (ISC_R_SUCCESS); 1054 } 1055 1056 static inline isc_result_t 1057 query_getzonedb(ns_client_t *client, const dns_name_t *name, 1058 dns_rdatatype_t qtype, unsigned int options, dns_zone_t **zonep, 1059 dns_db_t **dbp, dns_dbversion_t **versionp) { 1060 isc_result_t result; 1061 unsigned int ztoptions; 1062 dns_zone_t *zone = NULL; 1063 dns_db_t *db = NULL; 1064 bool partial = false; 1065 1066 REQUIRE(zonep != NULL && *zonep == NULL); 1067 REQUIRE(dbp != NULL && *dbp == NULL); 1068 1069 /*% 1070 * Find a zone database to answer the query. 1071 */ 1072 ztoptions = DNS_ZTFIND_MIRROR; 1073 if ((options & DNS_GETDB_NOEXACT) != 0) { 1074 ztoptions |= DNS_ZTFIND_NOEXACT; 1075 } 1076 1077 result = dns_zt_find(client->view->zonetable, name, ztoptions, NULL, 1078 &zone); 1079 1080 if (result == DNS_R_PARTIALMATCH) { 1081 partial = true; 1082 } 1083 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) { 1084 result = dns_zone_getdb(zone, &db); 1085 } 1086 1087 if (result != ISC_R_SUCCESS) { 1088 goto fail; 1089 } 1090 1091 result = query_validatezonedb(client, name, qtype, options, zone, db, 1092 versionp); 1093 1094 if (result != ISC_R_SUCCESS) { 1095 goto fail; 1096 } 1097 1098 /* Transfer ownership. */ 1099 *zonep = zone; 1100 *dbp = db; 1101 1102 if (partial && (options & DNS_GETDB_PARTIAL) != 0) { 1103 return (DNS_R_PARTIALMATCH); 1104 } 1105 return (ISC_R_SUCCESS); 1106 1107 fail: 1108 if (zone != NULL) { 1109 dns_zone_detach(&zone); 1110 } 1111 if (db != NULL) { 1112 dns_db_detach(&db); 1113 } 1114 1115 return (result); 1116 } 1117 1118 static void 1119 rpz_log_rewrite(ns_client_t *client, bool disabled, dns_rpz_policy_t policy, 1120 dns_rpz_type_t type, dns_zone_t *p_zone, dns_name_t *p_name, 1121 dns_name_t *cname, dns_rpz_num_t rpz_num) { 1122 char cname_buf[DNS_NAME_FORMATSIZE] = { 0 }; 1123 char p_name_buf[DNS_NAME_FORMATSIZE]; 1124 char qname_buf[DNS_NAME_FORMATSIZE]; 1125 char classbuf[DNS_RDATACLASS_FORMATSIZE]; 1126 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 1127 const char *s1 = cname_buf, *s2 = cname_buf; 1128 dns_rdataset_t *rdataset; 1129 dns_rpz_st_t *st; 1130 isc_stats_t *zonestats; 1131 1132 /* 1133 * Count enabled rewrites in the global counter. 1134 * Count both enabled and disabled rewrites for each zone. 1135 */ 1136 if (!disabled && policy != DNS_RPZ_POLICY_PASSTHRU) { 1137 ns_stats_increment(client->sctx->nsstats, 1138 ns_statscounter_rpz_rewrites); 1139 } 1140 if (p_zone != NULL) { 1141 zonestats = dns_zone_getrequeststats(p_zone); 1142 if (zonestats != NULL) { 1143 isc_stats_increment(zonestats, 1144 ns_statscounter_rpz_rewrites); 1145 } 1146 } 1147 1148 if (!isc_log_wouldlog(ns_lctx, DNS_RPZ_INFO_LEVEL)) { 1149 return; 1150 } 1151 1152 st = client->query.rpz_st; 1153 if ((st->popt.no_log & DNS_RPZ_ZBIT(rpz_num)) != 0) { 1154 return; 1155 } 1156 1157 dns_name_format(client->query.qname, qname_buf, sizeof(qname_buf)); 1158 dns_name_format(p_name, p_name_buf, sizeof(p_name_buf)); 1159 if (cname != NULL) { 1160 s1 = " (CNAME to: "; 1161 dns_name_format(cname, cname_buf, sizeof(cname_buf)); 1162 s2 = ")"; 1163 } 1164 1165 /* 1166 * Log Qclass and Qtype in addition to existing 1167 * fields. 1168 */ 1169 rdataset = ISC_LIST_HEAD(client->query.origqname->list); 1170 INSIST(rdataset != NULL); 1171 dns_rdataclass_format(rdataset->rdclass, classbuf, sizeof(classbuf)); 1172 dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf)); 1173 1174 ns_client_log(client, DNS_LOGCATEGORY_RPZ, NS_LOGMODULE_QUERY, 1175 DNS_RPZ_INFO_LEVEL, 1176 "%srpz %s %s rewrite %s/%s/%s via %s%s%s%s", 1177 disabled ? "disabled " : "", dns_rpz_type2str(type), 1178 dns_rpz_policy2str(policy), qname_buf, typebuf, classbuf, 1179 p_name_buf, s1, cname_buf, s2); 1180 } 1181 1182 static void 1183 rpz_log_fail_helper(ns_client_t *client, int level, dns_name_t *p_name, 1184 dns_rpz_type_t rpz_type1, dns_rpz_type_t rpz_type2, 1185 const char *str, isc_result_t result) { 1186 char qnamebuf[DNS_NAME_FORMATSIZE]; 1187 char p_namebuf[DNS_NAME_FORMATSIZE]; 1188 const char *failed, *via, *slash, *str_blank; 1189 const char *rpztypestr1; 1190 const char *rpztypestr2; 1191 1192 if (!isc_log_wouldlog(ns_lctx, level)) { 1193 return; 1194 } 1195 1196 /* 1197 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed" for problems. 1198 */ 1199 if (level <= DNS_RPZ_DEBUG_LEVEL1) { 1200 failed = " failed: "; 1201 } else { 1202 failed = ": "; 1203 } 1204 1205 rpztypestr1 = dns_rpz_type2str(rpz_type1); 1206 if (rpz_type2 != DNS_RPZ_TYPE_BAD) { 1207 slash = "/"; 1208 rpztypestr2 = dns_rpz_type2str(rpz_type2); 1209 } else { 1210 slash = ""; 1211 rpztypestr2 = ""; 1212 } 1213 1214 str_blank = (*str != ' ' && *str != '\0') ? " " : ""; 1215 1216 dns_name_format(client->query.qname, qnamebuf, sizeof(qnamebuf)); 1217 1218 if (p_name != NULL) { 1219 via = " via "; 1220 dns_name_format(p_name, p_namebuf, sizeof(p_namebuf)); 1221 } else { 1222 via = ""; 1223 p_namebuf[0] = '\0'; 1224 } 1225 1226 ns_client_log(client, NS_LOGCATEGORY_QUERY_ERRORS, NS_LOGMODULE_QUERY, 1227 level, "rpz %s%s%s rewrite %s%s%s%s%s%s%s", rpztypestr1, 1228 slash, rpztypestr2, qnamebuf, via, p_namebuf, str_blank, 1229 str, failed, isc_result_totext(result)); 1230 } 1231 1232 static void 1233 rpz_log_fail(ns_client_t *client, int level, dns_name_t *p_name, 1234 dns_rpz_type_t rpz_type, const char *str, isc_result_t result) { 1235 rpz_log_fail_helper(client, level, p_name, rpz_type, DNS_RPZ_TYPE_BAD, 1236 str, result); 1237 } 1238 1239 /* 1240 * Get a policy rewrite zone database. 1241 */ 1242 static isc_result_t 1243 rpz_getdb(ns_client_t *client, dns_name_t *p_name, dns_rpz_type_t rpz_type, 1244 dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp) { 1245 char qnamebuf[DNS_NAME_FORMATSIZE]; 1246 char p_namebuf[DNS_NAME_FORMATSIZE]; 1247 dns_dbversion_t *rpz_version = NULL; 1248 isc_result_t result; 1249 1250 CTRACE(ISC_LOG_DEBUG(3), "rpz_getdb"); 1251 1252 result = query_getzonedb(client, p_name, dns_rdatatype_any, 1253 DNS_GETDB_IGNOREACL, zonep, dbp, &rpz_version); 1254 if (result == ISC_R_SUCCESS) { 1255 dns_rpz_st_t *st = client->query.rpz_st; 1256 1257 /* 1258 * It isn't meaningful to log this message when 1259 * logging is disabled for some policy zones. 1260 */ 1261 if (st->popt.no_log == 0 && 1262 isc_log_wouldlog(ns_lctx, DNS_RPZ_DEBUG_LEVEL2)) { 1263 dns_name_format(client->query.qname, qnamebuf, 1264 sizeof(qnamebuf)); 1265 dns_name_format(p_name, p_namebuf, sizeof(p_namebuf)); 1266 ns_client_log(client, DNS_LOGCATEGORY_RPZ, 1267 NS_LOGMODULE_QUERY, DNS_RPZ_DEBUG_LEVEL2, 1268 "try rpz %s rewrite %s via %s", 1269 dns_rpz_type2str(rpz_type), qnamebuf, 1270 p_namebuf); 1271 } 1272 *versionp = rpz_version; 1273 return (ISC_R_SUCCESS); 1274 } 1275 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type, 1276 "query_getzonedb()", result); 1277 return (result); 1278 } 1279 1280 /*% 1281 * Find a cache database to answer the query. This may fail with DNS_R_REFUSED 1282 * if the client is not allowed to use the cache. 1283 */ 1284 static inline isc_result_t 1285 query_getcachedb(ns_client_t *client, const dns_name_t *name, 1286 dns_rdatatype_t qtype, dns_db_t **dbp, unsigned int options) { 1287 isc_result_t result; 1288 dns_db_t *db = NULL; 1289 1290 REQUIRE(dbp != NULL && *dbp == NULL); 1291 1292 if (!USECACHE(client)) { 1293 return (DNS_R_REFUSED); 1294 } 1295 1296 dns_db_attach(client->view->cachedb, &db); 1297 1298 result = query_checkcacheaccess(client, name, qtype, options); 1299 if (result != ISC_R_SUCCESS) { 1300 dns_db_detach(&db); 1301 } 1302 1303 /* 1304 * If query_checkcacheaccess() succeeded, transfer ownership of 'db'. 1305 * Otherwise, 'db' will be NULL due to the dns_db_detach() call above. 1306 */ 1307 *dbp = db; 1308 1309 return (result); 1310 } 1311 1312 static inline isc_result_t 1313 query_getdb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, 1314 unsigned int options, dns_zone_t **zonep, dns_db_t **dbp, 1315 dns_dbversion_t **versionp, bool *is_zonep) { 1316 isc_result_t result; 1317 isc_result_t tresult; 1318 unsigned int namelabels; 1319 unsigned int zonelabels; 1320 dns_zone_t *zone = NULL; 1321 1322 REQUIRE(zonep != NULL && *zonep == NULL); 1323 1324 /* Calculate how many labels are in name. */ 1325 namelabels = dns_name_countlabels(name); 1326 zonelabels = 0; 1327 1328 /* Try to find name in bind's standard database. */ 1329 result = query_getzonedb(client, name, qtype, options, &zone, dbp, 1330 versionp); 1331 1332 /* See how many labels are in the zone's name. */ 1333 if (result == ISC_R_SUCCESS && zone != NULL) { 1334 zonelabels = dns_name_countlabels(dns_zone_getorigin(zone)); 1335 } 1336 1337 /* 1338 * If # zone labels < # name labels, try to find an even better match 1339 * Only try if DLZ drivers are loaded for this view 1340 */ 1341 if (ISC_UNLIKELY(zonelabels < namelabels && 1342 !ISC_LIST_EMPTY(client->view->dlz_searched))) 1343 { 1344 dns_clientinfomethods_t cm; 1345 dns_clientinfo_t ci; 1346 dns_db_t *tdbp; 1347 1348 dns_clientinfomethods_init(&cm, ns_client_sourceip); 1349 dns_clientinfo_init(&ci, client, NULL); 1350 1351 tdbp = NULL; 1352 tresult = dns_view_searchdlz(client->view, name, zonelabels, 1353 &cm, &ci, &tdbp); 1354 /* If we successful, we found a better match. */ 1355 if (tresult == ISC_R_SUCCESS) { 1356 ns_dbversion_t *dbversion; 1357 1358 /* 1359 * If the previous search returned a zone, detach it. 1360 */ 1361 if (zone != NULL) { 1362 dns_zone_detach(&zone); 1363 } 1364 1365 /* 1366 * If the previous search returned a database, 1367 * detach it. 1368 */ 1369 if (*dbp != NULL) { 1370 dns_db_detach(dbp); 1371 } 1372 1373 /* 1374 * If the previous search returned a version, clear it. 1375 */ 1376 *versionp = NULL; 1377 1378 dbversion = ns_client_findversion(client, tdbp); 1379 if (dbversion == NULL) { 1380 tresult = ISC_R_NOMEMORY; 1381 } else { 1382 /* 1383 * Be sure to return our database. 1384 */ 1385 *dbp = tdbp; 1386 *versionp = dbversion->version; 1387 } 1388 1389 /* 1390 * We return a null zone, No stats for DLZ zones. 1391 */ 1392 zone = NULL; 1393 result = tresult; 1394 } 1395 } 1396 1397 /* If successful, Transfer ownership of zone. */ 1398 if (result == ISC_R_SUCCESS) { 1399 *zonep = zone; 1400 /* 1401 * If neither attempt above succeeded, return the cache instead 1402 */ 1403 *is_zonep = true; 1404 } else { 1405 if (result == ISC_R_NOTFOUND) { 1406 result = query_getcachedb(client, name, qtype, dbp, 1407 options); 1408 } 1409 *is_zonep = false; 1410 } 1411 return (result); 1412 } 1413 1414 static inline bool 1415 query_isduplicate(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, 1416 dns_name_t **mnamep) { 1417 dns_section_t section; 1418 dns_name_t *mname = NULL; 1419 isc_result_t result; 1420 1421 CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate"); 1422 1423 for (section = DNS_SECTION_ANSWER; section <= DNS_SECTION_ADDITIONAL; 1424 section++) { 1425 result = dns_message_findname(client->message, section, name, 1426 type, 0, &mname, NULL); 1427 if (result == ISC_R_SUCCESS) { 1428 /* 1429 * We've already got this RRset in the response. 1430 */ 1431 CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate: true: " 1432 "done"); 1433 return (true); 1434 } else if (result == DNS_R_NXRRSET) { 1435 /* 1436 * The name exists, but the rdataset does not. 1437 */ 1438 if (section == DNS_SECTION_ADDITIONAL) { 1439 break; 1440 } 1441 } else { 1442 RUNTIME_CHECK(result == DNS_R_NXDOMAIN); 1443 } 1444 mname = NULL; 1445 } 1446 1447 if (mnamep != NULL) { 1448 *mnamep = mname; 1449 } 1450 1451 CTRACE(ISC_LOG_DEBUG(3), "query_isduplicate: false: done"); 1452 return (false); 1453 } 1454 1455 /* 1456 * Look up data for given 'name' and 'type' in given 'version' of 'db' for 1457 * 'client'. Called from query_additionalauth(). 1458 * 1459 * If the lookup is successful: 1460 * 1461 * - store the node containing the result at 'nodep', 1462 * 1463 * - store the owner name of the returned node in 'fname', 1464 * 1465 * - if 'type' is not ANY, dns_db_findext() will put the exact rdataset being 1466 * looked for in 'rdataset' and its signatures (if any) in 'sigrdataset', 1467 * 1468 * - if 'type' is ANY, dns_db_findext() will leave 'rdataset' and 1469 * 'sigrdataset' disassociated and the returned node will be iterated in 1470 * query_additional_cb(). 1471 * 1472 * If the lookup is not successful: 1473 * 1474 * - 'nodep' will not be written to, 1475 * - 'fname' may still be modified as it is passed to dns_db_findext(), 1476 * - 'rdataset' and 'sigrdataset' will remain disassociated. 1477 */ 1478 static isc_result_t 1479 query_additionalauthfind(dns_db_t *db, dns_dbversion_t *version, 1480 const dns_name_t *name, dns_rdatatype_t type, 1481 ns_client_t *client, dns_dbnode_t **nodep, 1482 dns_name_t *fname, dns_rdataset_t *rdataset, 1483 dns_rdataset_t *sigrdataset) { 1484 dns_clientinfomethods_t cm; 1485 dns_dbnode_t *node = NULL; 1486 dns_clientinfo_t ci; 1487 isc_result_t result; 1488 1489 dns_clientinfomethods_init(&cm, ns_client_sourceip); 1490 dns_clientinfo_init(&ci, client, NULL); 1491 1492 /* 1493 * Since we are looking for authoritative data, we do not set 1494 * the GLUEOK flag. Glue will be looked for later, but not 1495 * necessarily in the same database. 1496 */ 1497 result = dns_db_findext(db, name, version, type, 1498 client->query.dboptions, client->now, &node, 1499 fname, &cm, &ci, rdataset, sigrdataset); 1500 if (result != ISC_R_SUCCESS) { 1501 if (dns_rdataset_isassociated(rdataset)) { 1502 dns_rdataset_disassociate(rdataset); 1503 } 1504 1505 if (sigrdataset != NULL && 1506 dns_rdataset_isassociated(sigrdataset)) { 1507 dns_rdataset_disassociate(sigrdataset); 1508 } 1509 1510 if (node != NULL) { 1511 dns_db_detachnode(db, &node); 1512 } 1513 1514 return (result); 1515 } 1516 1517 /* 1518 * Do not return signatures if the zone is not fully signed. 1519 */ 1520 if (sigrdataset != NULL && !dns_db_issecure(db) && 1521 dns_rdataset_isassociated(sigrdataset)) 1522 { 1523 dns_rdataset_disassociate(sigrdataset); 1524 } 1525 1526 *nodep = node; 1527 1528 return (ISC_R_SUCCESS); 1529 } 1530 1531 /* 1532 * For query context 'qctx', try finding authoritative additional data for 1533 * given 'name' and 'type'. Called from query_additional_cb(). 1534 * 1535 * If successful: 1536 * 1537 * - store pointers to the database and node which contain the result in 1538 * 'dbp' and 'nodep', respectively, 1539 * 1540 * - store the owner name of the returned node in 'fname', 1541 * 1542 * - potentially bind 'rdataset' and 'sigrdataset', as explained in the 1543 * comment for query_additionalauthfind(). 1544 * 1545 * If unsuccessful: 1546 * 1547 * - 'dbp' and 'nodep' will not be written to, 1548 * - 'fname' may still be modified as it is passed to dns_db_findext(), 1549 * - 'rdataset' and 'sigrdataset' will remain disassociated. 1550 */ 1551 static isc_result_t 1552 query_additionalauth(query_ctx_t *qctx, const dns_name_t *name, 1553 dns_rdatatype_t type, dns_db_t **dbp, dns_dbnode_t **nodep, 1554 dns_name_t *fname, dns_rdataset_t *rdataset, 1555 dns_rdataset_t *sigrdataset) { 1556 ns_client_t *client = qctx->client; 1557 ns_dbversion_t *dbversion = NULL; 1558 dns_dbversion_t *version = NULL; 1559 dns_dbnode_t *node = NULL; 1560 dns_zone_t *zone = NULL; 1561 dns_db_t *db = NULL; 1562 isc_result_t result; 1563 1564 /* 1565 * First, look within the same zone database for authoritative 1566 * additional data. 1567 */ 1568 if (!client->query.authdbset || client->query.authdb == NULL) { 1569 return (ISC_R_NOTFOUND); 1570 } 1571 1572 dbversion = ns_client_findversion(client, client->query.authdb); 1573 if (dbversion == NULL) { 1574 return (ISC_R_NOTFOUND); 1575 } 1576 1577 dns_db_attach(client->query.authdb, &db); 1578 version = dbversion->version; 1579 1580 CTRACE(ISC_LOG_DEBUG(3), "query_additionalauth: same zone"); 1581 1582 result = query_additionalauthfind(db, version, name, type, client, 1583 &node, fname, rdataset, sigrdataset); 1584 if (result != ISC_R_SUCCESS && 1585 qctx->view->minimalresponses == dns_minimal_no && 1586 RECURSIONOK(client)) 1587 { 1588 /* 1589 * If we aren't doing response minimization and recursion is 1590 * allowed, we can try and see if any other zone matches. 1591 */ 1592 version = NULL; 1593 dns_db_detach(&db); 1594 result = query_getzonedb(client, name, type, DNS_GETDB_NOLOG, 1595 &zone, &db, &version); 1596 if (result != ISC_R_SUCCESS) { 1597 return (result); 1598 } 1599 dns_zone_detach(&zone); 1600 1601 CTRACE(ISC_LOG_DEBUG(3), "query_additionalauth: other zone"); 1602 1603 result = query_additionalauthfind(db, version, name, type, 1604 client, &node, fname, 1605 rdataset, sigrdataset); 1606 } 1607 1608 if (result != ISC_R_SUCCESS) { 1609 dns_db_detach(&db); 1610 } else { 1611 *nodep = node; 1612 node = NULL; 1613 1614 *dbp = db; 1615 db = NULL; 1616 } 1617 1618 return (result); 1619 } 1620 1621 static isc_result_t 1622 query_additional_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) { 1623 query_ctx_t *qctx = arg; 1624 ns_client_t *client = qctx->client; 1625 isc_result_t result, eresult = ISC_R_SUCCESS; 1626 dns_dbnode_t *node = NULL; 1627 dns_db_t *db = NULL; 1628 dns_name_t *fname = NULL, *mname = NULL; 1629 dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; 1630 dns_rdataset_t *trdataset = NULL; 1631 isc_buffer_t *dbuf = NULL; 1632 isc_buffer_t b; 1633 ns_dbversion_t *dbversion = NULL; 1634 dns_dbversion_t *version = NULL; 1635 bool added_something = false, need_addname = false; 1636 dns_rdatatype_t type; 1637 dns_clientinfomethods_t cm; 1638 dns_clientinfo_t ci; 1639 dns_rdatasetadditional_t additionaltype = 1640 dns_rdatasetadditional_fromauth; 1641 1642 REQUIRE(NS_CLIENT_VALID(client)); 1643 REQUIRE(qtype != dns_rdatatype_any); 1644 1645 if (!WANTDNSSEC(client) && dns_rdatatype_isdnssec(qtype)) { 1646 return (ISC_R_SUCCESS); 1647 } 1648 1649 CTRACE(ISC_LOG_DEBUG(3), "query_additional_cb"); 1650 1651 dns_clientinfomethods_init(&cm, ns_client_sourceip); 1652 dns_clientinfo_init(&ci, client, NULL); 1653 1654 /* 1655 * We treat type A additional section processing as if it 1656 * were "any address type" additional section processing. 1657 * To avoid multiple lookups, we do an 'any' database 1658 * lookup and iterate over the node. 1659 */ 1660 if (qtype == dns_rdatatype_a) { 1661 type = dns_rdatatype_any; 1662 } else { 1663 type = qtype; 1664 } 1665 1666 /* 1667 * Get some resources. 1668 */ 1669 dbuf = ns_client_getnamebuf(client); 1670 if (dbuf == NULL) { 1671 goto cleanup; 1672 } 1673 fname = ns_client_newname(client, dbuf, &b); 1674 rdataset = ns_client_newrdataset(client); 1675 if (fname == NULL || rdataset == NULL) { 1676 goto cleanup; 1677 } 1678 if (WANTDNSSEC(client)) { 1679 sigrdataset = ns_client_newrdataset(client); 1680 if (sigrdataset == NULL) { 1681 goto cleanup; 1682 } 1683 } 1684 1685 /* 1686 * If we want only minimal responses and are here, then it must 1687 * be for glue. 1688 */ 1689 if (qctx->view->minimalresponses == dns_minimal_yes) { 1690 goto try_glue; 1691 } 1692 1693 /* 1694 * First, look for authoritative additional data. 1695 */ 1696 result = query_additionalauth(qctx, name, type, &db, &node, fname, 1697 rdataset, sigrdataset); 1698 if (result == ISC_R_SUCCESS) { 1699 goto found; 1700 } 1701 1702 /* 1703 * No authoritative data was found. The cache is our next best bet. 1704 */ 1705 if (!qctx->view->recursion) { 1706 goto try_glue; 1707 } 1708 1709 additionaltype = dns_rdatasetadditional_fromcache; 1710 result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG); 1711 if (result != ISC_R_SUCCESS) { 1712 /* 1713 * Most likely the client isn't allowed to query the cache. 1714 */ 1715 goto try_glue; 1716 } 1717 /* 1718 * Attempt to validate glue. 1719 */ 1720 if (sigrdataset == NULL) { 1721 sigrdataset = ns_client_newrdataset(client); 1722 if (sigrdataset == NULL) { 1723 goto cleanup; 1724 } 1725 } 1726 1727 version = NULL; 1728 result = dns_db_findext(db, name, version, type, 1729 client->query.dboptions | DNS_DBFIND_GLUEOK | 1730 DNS_DBFIND_ADDITIONALOK, 1731 client->now, &node, fname, &cm, &ci, rdataset, 1732 sigrdataset); 1733 1734 dns_cache_updatestats(qctx->view->cache, result); 1735 if (!WANTDNSSEC(client)) { 1736 ns_client_putrdataset(client, &sigrdataset); 1737 } 1738 if (result == ISC_R_SUCCESS) { 1739 goto found; 1740 } 1741 1742 if (dns_rdataset_isassociated(rdataset)) { 1743 dns_rdataset_disassociate(rdataset); 1744 } 1745 if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) { 1746 dns_rdataset_disassociate(sigrdataset); 1747 } 1748 if (node != NULL) { 1749 dns_db_detachnode(db, &node); 1750 } 1751 dns_db_detach(&db); 1752 1753 try_glue: 1754 /* 1755 * No cached data was found. Glue is our last chance. 1756 * RFC1035 sayeth: 1757 * 1758 * NS records cause both the usual additional section 1759 * processing to locate a type A record, and, when used 1760 * in a referral, a special search of the zone in which 1761 * they reside for glue information. 1762 * 1763 * This is the "special search". Note that we must search 1764 * the zone where the NS record resides, not the zone it 1765 * points to, and that we only do the search in the delegation 1766 * case (identified by client->query.gluedb being set). 1767 */ 1768 1769 if (client->query.gluedb == NULL) { 1770 goto cleanup; 1771 } 1772 1773 /* 1774 * Don't poison caches using the bailiwick protection model. 1775 */ 1776 if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb))) { 1777 goto cleanup; 1778 } 1779 1780 dbversion = ns_client_findversion(client, client->query.gluedb); 1781 if (dbversion == NULL) { 1782 goto cleanup; 1783 } 1784 1785 dns_db_attach(client->query.gluedb, &db); 1786 version = dbversion->version; 1787 additionaltype = dns_rdatasetadditional_fromglue; 1788 result = dns_db_findext(db, name, version, type, 1789 client->query.dboptions | DNS_DBFIND_GLUEOK, 1790 client->now, &node, fname, &cm, &ci, rdataset, 1791 sigrdataset); 1792 if (result != ISC_R_SUCCESS && result != DNS_R_ZONECUT && 1793 result != DNS_R_GLUE) { 1794 goto cleanup; 1795 } 1796 1797 found: 1798 /* 1799 * We have found a potential additional data rdataset, or 1800 * at least a node to iterate over. 1801 */ 1802 ns_client_keepname(client, fname, dbuf); 1803 1804 /* 1805 * If we have an rdataset, add it to the additional data 1806 * section. 1807 */ 1808 mname = NULL; 1809 if (dns_rdataset_isassociated(rdataset) && 1810 !query_isduplicate(client, fname, type, &mname)) 1811 { 1812 if (mname != NULL) { 1813 INSIST(mname != fname); 1814 ns_client_releasename(client, &fname); 1815 fname = mname; 1816 } else { 1817 need_addname = true; 1818 } 1819 ISC_LIST_APPEND(fname->list, rdataset, link); 1820 trdataset = rdataset; 1821 rdataset = NULL; 1822 added_something = true; 1823 /* 1824 * Note: we only add SIGs if we've added the type they cover, 1825 * so we do not need to check if the SIG rdataset is already 1826 * in the response. 1827 */ 1828 if (sigrdataset != NULL && 1829 dns_rdataset_isassociated(sigrdataset)) { 1830 ISC_LIST_APPEND(fname->list, sigrdataset, link); 1831 sigrdataset = NULL; 1832 } 1833 } 1834 1835 if (qtype == dns_rdatatype_a) { 1836 /* 1837 * We now go looking for A and AAAA records, along with 1838 * their signatures. 1839 * 1840 * XXXRTH This code could be more efficient. 1841 */ 1842 if (rdataset != NULL) { 1843 if (dns_rdataset_isassociated(rdataset)) { 1844 dns_rdataset_disassociate(rdataset); 1845 } 1846 } else { 1847 rdataset = ns_client_newrdataset(client); 1848 if (rdataset == NULL) { 1849 goto addname; 1850 } 1851 } 1852 if (sigrdataset != NULL) { 1853 if (dns_rdataset_isassociated(sigrdataset)) { 1854 dns_rdataset_disassociate(sigrdataset); 1855 } 1856 } else if (WANTDNSSEC(client)) { 1857 sigrdataset = ns_client_newrdataset(client); 1858 if (sigrdataset == NULL) { 1859 goto addname; 1860 } 1861 } 1862 if (query_isduplicate(client, fname, dns_rdatatype_a, NULL)) { 1863 goto aaaa_lookup; 1864 } 1865 result = dns_db_findrdataset(db, node, version, dns_rdatatype_a, 1866 0, client->now, rdataset, 1867 sigrdataset); 1868 if (result == DNS_R_NCACHENXDOMAIN) { 1869 goto addname; 1870 } else if (result == DNS_R_NCACHENXRRSET) { 1871 dns_rdataset_disassociate(rdataset); 1872 if (sigrdataset != NULL && 1873 dns_rdataset_isassociated(sigrdataset)) { 1874 dns_rdataset_disassociate(sigrdataset); 1875 } 1876 } else if (result == ISC_R_SUCCESS) { 1877 bool invalid = false; 1878 mname = NULL; 1879 if (additionaltype == 1880 dns_rdatasetadditional_fromcache && 1881 (DNS_TRUST_PENDING(rdataset->trust) || 1882 DNS_TRUST_GLUE(rdataset->trust))) 1883 { 1884 /* validate() may change rdataset->trust */ 1885 invalid = !validate(client, db, fname, rdataset, 1886 sigrdataset); 1887 } 1888 if (invalid && DNS_TRUST_PENDING(rdataset->trust)) { 1889 dns_rdataset_disassociate(rdataset); 1890 if (sigrdataset != NULL && 1891 dns_rdataset_isassociated(sigrdataset)) { 1892 dns_rdataset_disassociate(sigrdataset); 1893 } 1894 } else if (!query_isduplicate(client, fname, 1895 dns_rdatatype_a, &mname)) 1896 { 1897 if (mname != fname) { 1898 if (mname != NULL) { 1899 ns_client_releasename(client, 1900 &fname); 1901 fname = mname; 1902 } else { 1903 need_addname = true; 1904 } 1905 } 1906 ISC_LIST_APPEND(fname->list, rdataset, link); 1907 added_something = true; 1908 if (sigrdataset != NULL && 1909 dns_rdataset_isassociated(sigrdataset)) { 1910 ISC_LIST_APPEND(fname->list, 1911 sigrdataset, link); 1912 sigrdataset = 1913 ns_client_newrdataset(client); 1914 } 1915 rdataset = ns_client_newrdataset(client); 1916 if (rdataset == NULL) { 1917 goto addname; 1918 } 1919 if (WANTDNSSEC(client) && sigrdataset == NULL) { 1920 goto addname; 1921 } 1922 } else { 1923 dns_rdataset_disassociate(rdataset); 1924 if (sigrdataset != NULL && 1925 dns_rdataset_isassociated(sigrdataset)) { 1926 dns_rdataset_disassociate(sigrdataset); 1927 } 1928 } 1929 } 1930 aaaa_lookup: 1931 if (query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL)) 1932 { 1933 goto addname; 1934 } 1935 result = dns_db_findrdataset(db, node, version, 1936 dns_rdatatype_aaaa, 0, client->now, 1937 rdataset, sigrdataset); 1938 if (result == DNS_R_NCACHENXDOMAIN) { 1939 goto addname; 1940 } else if (result == DNS_R_NCACHENXRRSET) { 1941 dns_rdataset_disassociate(rdataset); 1942 if (sigrdataset != NULL && 1943 dns_rdataset_isassociated(sigrdataset)) { 1944 dns_rdataset_disassociate(sigrdataset); 1945 } 1946 } else if (result == ISC_R_SUCCESS) { 1947 bool invalid = false; 1948 mname = NULL; 1949 1950 if (additionaltype == 1951 dns_rdatasetadditional_fromcache && 1952 (DNS_TRUST_PENDING(rdataset->trust) || 1953 DNS_TRUST_GLUE(rdataset->trust))) 1954 { 1955 /* validate() may change rdataset->trust */ 1956 invalid = !validate(client, db, fname, rdataset, 1957 sigrdataset); 1958 } 1959 1960 if (invalid && DNS_TRUST_PENDING(rdataset->trust)) { 1961 dns_rdataset_disassociate(rdataset); 1962 if (sigrdataset != NULL && 1963 dns_rdataset_isassociated(sigrdataset)) { 1964 dns_rdataset_disassociate(sigrdataset); 1965 } 1966 } else if (!query_isduplicate(client, fname, 1967 dns_rdatatype_aaaa, 1968 &mname)) { 1969 if (mname != fname) { 1970 if (mname != NULL) { 1971 ns_client_releasename(client, 1972 &fname); 1973 fname = mname; 1974 } else { 1975 need_addname = true; 1976 } 1977 } 1978 ISC_LIST_APPEND(fname->list, rdataset, link); 1979 added_something = true; 1980 if (sigrdataset != NULL && 1981 dns_rdataset_isassociated(sigrdataset)) { 1982 ISC_LIST_APPEND(fname->list, 1983 sigrdataset, link); 1984 sigrdataset = NULL; 1985 } 1986 rdataset = NULL; 1987 } 1988 } 1989 } 1990 1991 addname: 1992 CTRACE(ISC_LOG_DEBUG(3), "query_additional_cb: addname"); 1993 /* 1994 * If we haven't added anything, then we're done. 1995 */ 1996 if (!added_something) { 1997 goto cleanup; 1998 } 1999 2000 /* 2001 * We may have added our rdatasets to an existing name, if so, then 2002 * need_addname will be false. Whether we used an existing name 2003 * or a new one, we must set fname to NULL to prevent cleanup. 2004 */ 2005 if (need_addname) { 2006 dns_message_addname(client->message, fname, 2007 DNS_SECTION_ADDITIONAL); 2008 } 2009 fname = NULL; 2010 2011 /* 2012 * In a few cases, we want to add additional data for additional 2013 * data. It's simpler to just deal with special cases here than 2014 * to try to create a general purpose mechanism and allow the 2015 * rdata implementations to do it themselves. 2016 * 2017 * This involves recursion, but the depth is limited. The 2018 * most complex case is adding a SRV rdataset, which involves 2019 * recursing to add address records, which in turn can cause 2020 * recursion to add KEYs. 2021 */ 2022 if (type == dns_rdatatype_srv && trdataset != NULL) { 2023 /* 2024 * If we're adding SRV records to the additional data 2025 * section, it's helpful if we add the SRV additional data 2026 * as well. 2027 */ 2028 eresult = dns_rdataset_additionaldata( 2029 trdataset, query_additional_cb, qctx); 2030 } 2031 2032 cleanup: 2033 CTRACE(ISC_LOG_DEBUG(3), "query_additional_cb: cleanup"); 2034 ns_client_putrdataset(client, &rdataset); 2035 if (sigrdataset != NULL) { 2036 ns_client_putrdataset(client, &sigrdataset); 2037 } 2038 if (fname != NULL) { 2039 ns_client_releasename(client, &fname); 2040 } 2041 if (node != NULL) { 2042 dns_db_detachnode(db, &node); 2043 } 2044 if (db != NULL) { 2045 dns_db_detach(&db); 2046 } 2047 2048 CTRACE(ISC_LOG_DEBUG(3), "query_additional_cb: done"); 2049 return (eresult); 2050 } 2051 2052 /* 2053 * Add 'rdataset' to 'name'. 2054 */ 2055 static inline void 2056 query_addtoname(dns_name_t *name, dns_rdataset_t *rdataset) { 2057 ISC_LIST_APPEND(name->list, rdataset, link); 2058 } 2059 2060 /* 2061 * Set the ordering for 'rdataset'. 2062 */ 2063 static void 2064 query_setorder(query_ctx_t *qctx, dns_name_t *name, dns_rdataset_t *rdataset) { 2065 ns_client_t *client = qctx->client; 2066 dns_order_t *order = client->view->order; 2067 2068 CTRACE(ISC_LOG_DEBUG(3), "query_setorder"); 2069 2070 UNUSED(client); 2071 2072 if (order != NULL) { 2073 rdataset->attributes |= dns_order_find( 2074 order, name, rdataset->type, rdataset->rdclass); 2075 } 2076 rdataset->attributes |= DNS_RDATASETATTR_LOADORDER; 2077 } 2078 2079 /* 2080 * Handle glue and fetch any other needed additional data for 'rdataset'. 2081 */ 2082 static void 2083 query_additional(query_ctx_t *qctx, dns_rdataset_t *rdataset) { 2084 ns_client_t *client = qctx->client; 2085 isc_result_t result; 2086 2087 CTRACE(ISC_LOG_DEBUG(3), "query_additional"); 2088 2089 if (NOADDITIONAL(client)) { 2090 return; 2091 } 2092 2093 /* 2094 * Try to process glue directly. 2095 */ 2096 if (qctx->view->use_glue_cache && 2097 (rdataset->type == dns_rdatatype_ns) && 2098 (client->query.gluedb != NULL) && 2099 dns_db_iszone(client->query.gluedb)) 2100 { 2101 ns_dbversion_t *dbversion; 2102 2103 dbversion = ns_client_findversion(client, client->query.gluedb); 2104 if (dbversion == NULL) { 2105 goto regular; 2106 } 2107 2108 result = dns_rdataset_addglue(rdataset, dbversion->version, 2109 client->message); 2110 if (result == ISC_R_SUCCESS) { 2111 return; 2112 } 2113 } 2114 2115 regular: 2116 /* 2117 * Add other additional data if needed. 2118 * We don't care if dns_rdataset_additionaldata() fails. 2119 */ 2120 (void)dns_rdataset_additionaldata(rdataset, query_additional_cb, qctx); 2121 CTRACE(ISC_LOG_DEBUG(3), "query_additional: done"); 2122 } 2123 2124 static void 2125 query_addrrset(query_ctx_t *qctx, dns_name_t **namep, 2126 dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp, 2127 isc_buffer_t *dbuf, dns_section_t section) { 2128 isc_result_t result; 2129 ns_client_t *client = qctx->client; 2130 dns_name_t *name = *namep, *mname = NULL; 2131 dns_rdataset_t *rdataset = *rdatasetp, *mrdataset = NULL; 2132 dns_rdataset_t *sigrdataset = NULL; 2133 2134 CTRACE(ISC_LOG_DEBUG(3), "query_addrrset"); 2135 2136 REQUIRE(name != NULL); 2137 2138 if (sigrdatasetp != NULL) { 2139 sigrdataset = *sigrdatasetp; 2140 } 2141 2142 /*% 2143 * To the current response for 'client', add the answer RRset 2144 * '*rdatasetp' and an optional signature set '*sigrdatasetp', with 2145 * owner name '*namep', to section 'section', unless they are 2146 * already there. Also add any pertinent additional data. 2147 * 2148 * If 'dbuf' is not NULL, then '*namep' is the name whose data is 2149 * stored in 'dbuf'. In this case, query_addrrset() guarantees that 2150 * when it returns the name will either have been kept or released. 2151 */ 2152 result = dns_message_findname(client->message, section, name, 2153 rdataset->type, rdataset->covers, &mname, 2154 &mrdataset); 2155 if (result == ISC_R_SUCCESS) { 2156 /* 2157 * We've already got an RRset of the given name and type. 2158 */ 2159 CTRACE(ISC_LOG_DEBUG(3), "query_addrrset: dns_message_findname " 2160 "succeeded: done"); 2161 if (dbuf != NULL) { 2162 ns_client_releasename(client, namep); 2163 } 2164 if ((rdataset->attributes & DNS_RDATASETATTR_REQUIRED) != 0) { 2165 mrdataset->attributes |= DNS_RDATASETATTR_REQUIRED; 2166 } 2167 return; 2168 } else if (result == DNS_R_NXDOMAIN) { 2169 /* 2170 * The name doesn't exist. 2171 */ 2172 if (dbuf != NULL) { 2173 ns_client_keepname(client, name, dbuf); 2174 } 2175 dns_message_addname(client->message, name, section); 2176 *namep = NULL; 2177 mname = name; 2178 } else { 2179 RUNTIME_CHECK(result == DNS_R_NXRRSET); 2180 if (dbuf != NULL) { 2181 ns_client_releasename(client, namep); 2182 } 2183 } 2184 2185 if (rdataset->trust != dns_trust_secure && 2186 (section == DNS_SECTION_ANSWER || section == DNS_SECTION_AUTHORITY)) 2187 { 2188 client->query.attributes &= ~NS_QUERYATTR_SECURE; 2189 } 2190 2191 /* 2192 * Update message name, set rdataset order, and do additional 2193 * section processing if needed. 2194 */ 2195 query_addtoname(mname, rdataset); 2196 query_setorder(qctx, mname, rdataset); 2197 query_additional(qctx, rdataset); 2198 2199 /* 2200 * Note: we only add SIGs if we've added the type they cover, so 2201 * we do not need to check if the SIG rdataset is already in the 2202 * response. 2203 */ 2204 *rdatasetp = NULL; 2205 if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) { 2206 /* 2207 * We have a signature. Add it to the response. 2208 */ 2209 ISC_LIST_APPEND(mname->list, sigrdataset, link); 2210 *sigrdatasetp = NULL; 2211 } 2212 2213 CTRACE(ISC_LOG_DEBUG(3), "query_addrrset: done"); 2214 } 2215 2216 /* 2217 * Mark the RRsets as secure. Update the cache (db) to reflect the 2218 * change in trust level. 2219 */ 2220 static void 2221 mark_secure(ns_client_t *client, dns_db_t *db, dns_name_t *name, 2222 dns_rdata_rrsig_t *rrsig, dns_rdataset_t *rdataset, 2223 dns_rdataset_t *sigrdataset) { 2224 isc_result_t result; 2225 dns_dbnode_t *node = NULL; 2226 dns_clientinfomethods_t cm; 2227 dns_clientinfo_t ci; 2228 isc_stdtime_t now; 2229 2230 rdataset->trust = dns_trust_secure; 2231 sigrdataset->trust = dns_trust_secure; 2232 dns_clientinfomethods_init(&cm, ns_client_sourceip); 2233 dns_clientinfo_init(&ci, client, NULL); 2234 2235 /* 2236 * Save the updated secure state. Ignore failures. 2237 */ 2238 result = dns_db_findnodeext(db, name, true, &cm, &ci, &node); 2239 if (result != ISC_R_SUCCESS) { 2240 return; 2241 } 2242 2243 isc_stdtime_get(&now); 2244 dns_rdataset_trimttl(rdataset, sigrdataset, rrsig, now, 2245 client->view->acceptexpired); 2246 2247 (void)dns_db_addrdataset(db, node, NULL, client->now, rdataset, 0, 2248 NULL); 2249 (void)dns_db_addrdataset(db, node, NULL, client->now, sigrdataset, 0, 2250 NULL); 2251 dns_db_detachnode(db, &node); 2252 } 2253 2254 /* 2255 * Find the secure key that corresponds to rrsig. 2256 * Note: 'keyrdataset' maintains state between successive calls, 2257 * there may be multiple keys with the same keyid. 2258 * Return false if we have exhausted all the possible keys. 2259 */ 2260 static bool 2261 get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig, 2262 dns_rdataset_t *keyrdataset, dst_key_t **keyp) { 2263 isc_result_t result; 2264 dns_dbnode_t *node = NULL; 2265 bool secure = false; 2266 dns_clientinfomethods_t cm; 2267 dns_clientinfo_t ci; 2268 2269 dns_clientinfomethods_init(&cm, ns_client_sourceip); 2270 dns_clientinfo_init(&ci, client, NULL); 2271 2272 if (!dns_rdataset_isassociated(keyrdataset)) { 2273 result = dns_db_findnodeext(db, &rrsig->signer, false, &cm, &ci, 2274 &node); 2275 if (result != ISC_R_SUCCESS) { 2276 return (false); 2277 } 2278 2279 result = dns_db_findrdataset(db, node, NULL, 2280 dns_rdatatype_dnskey, 0, 2281 client->now, keyrdataset, NULL); 2282 dns_db_detachnode(db, &node); 2283 if (result != ISC_R_SUCCESS) { 2284 return (false); 2285 } 2286 2287 if (keyrdataset->trust != dns_trust_secure) { 2288 return (false); 2289 } 2290 2291 result = dns_rdataset_first(keyrdataset); 2292 } else { 2293 result = dns_rdataset_next(keyrdataset); 2294 } 2295 2296 for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(keyrdataset)) 2297 { 2298 dns_rdata_t rdata = DNS_RDATA_INIT; 2299 isc_buffer_t b; 2300 2301 dns_rdataset_current(keyrdataset, &rdata); 2302 isc_buffer_init(&b, rdata.data, rdata.length); 2303 isc_buffer_add(&b, rdata.length); 2304 result = dst_key_fromdns(&rrsig->signer, rdata.rdclass, &b, 2305 client->mctx, keyp); 2306 if (result != ISC_R_SUCCESS) { 2307 continue; 2308 } 2309 if (rrsig->algorithm == (dns_secalg_t)dst_key_alg(*keyp) && 2310 rrsig->keyid == (dns_keytag_t)dst_key_id(*keyp) && 2311 dst_key_iszonekey(*keyp)) 2312 { 2313 secure = true; 2314 break; 2315 } 2316 dst_key_free(keyp); 2317 } 2318 return (secure); 2319 } 2320 2321 static bool 2322 verify(dst_key_t *key, dns_name_t *name, dns_rdataset_t *rdataset, 2323 dns_rdata_t *rdata, ns_client_t *client) { 2324 isc_result_t result; 2325 dns_fixedname_t fixed; 2326 bool ignore = false; 2327 2328 dns_fixedname_init(&fixed); 2329 2330 again: 2331 result = dns_dnssec_verify(name, rdataset, key, ignore, 2332 client->view->maxbits, client->mctx, rdata, 2333 NULL); 2334 if (result == DNS_R_SIGEXPIRED && client->view->acceptexpired) { 2335 ignore = true; 2336 goto again; 2337 } 2338 if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) { 2339 return (true); 2340 } 2341 return (false); 2342 } 2343 2344 /* 2345 * Validate the rdataset if possible with available records. 2346 */ 2347 static bool 2348 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name, 2349 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { 2350 isc_result_t result; 2351 dns_rdata_t rdata = DNS_RDATA_INIT; 2352 dns_rdata_rrsig_t rrsig; 2353 dst_key_t *key = NULL; 2354 dns_rdataset_t keyrdataset; 2355 2356 if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset)) { 2357 return (false); 2358 } 2359 2360 for (result = dns_rdataset_first(sigrdataset); result == ISC_R_SUCCESS; 2361 result = dns_rdataset_next(sigrdataset)) 2362 { 2363 dns_rdata_reset(&rdata); 2364 dns_rdataset_current(sigrdataset, &rdata); 2365 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 2366 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2367 if (!dns_resolver_algorithm_supported(client->view->resolver, 2368 name, rrsig.algorithm)) 2369 { 2370 continue; 2371 } 2372 if (!dns_name_issubdomain(name, &rrsig.signer)) { 2373 continue; 2374 } 2375 dns_rdataset_init(&keyrdataset); 2376 do { 2377 if (!get_key(client, db, &rrsig, &keyrdataset, &key)) { 2378 break; 2379 } 2380 if (verify(key, name, rdataset, &rdata, client)) { 2381 dst_key_free(&key); 2382 dns_rdataset_disassociate(&keyrdataset); 2383 mark_secure(client, db, name, &rrsig, rdataset, 2384 sigrdataset); 2385 return (true); 2386 } 2387 dst_key_free(&key); 2388 } while (1); 2389 if (dns_rdataset_isassociated(&keyrdataset)) { 2390 dns_rdataset_disassociate(&keyrdataset); 2391 } 2392 } 2393 return (false); 2394 } 2395 2396 static void 2397 fixrdataset(ns_client_t *client, dns_rdataset_t **rdataset) { 2398 if (*rdataset == NULL) { 2399 *rdataset = ns_client_newrdataset(client); 2400 } else if (dns_rdataset_isassociated(*rdataset)) { 2401 dns_rdataset_disassociate(*rdataset); 2402 } 2403 } 2404 2405 static void 2406 fixfname(ns_client_t *client, dns_name_t **fname, isc_buffer_t **dbuf, 2407 isc_buffer_t *nbuf) { 2408 if (*fname == NULL) { 2409 *dbuf = ns_client_getnamebuf(client); 2410 if (*dbuf == NULL) { 2411 return; 2412 } 2413 *fname = ns_client_newname(client, *dbuf, nbuf); 2414 } 2415 } 2416 2417 static void 2418 free_devent(ns_client_t *client, isc_event_t **eventp, 2419 dns_fetchevent_t **deventp) { 2420 dns_fetchevent_t *devent = *deventp; 2421 2422 REQUIRE((void *)(*eventp) == (void *)(*deventp)); 2423 2424 CTRACE(ISC_LOG_DEBUG(3), "free_devent"); 2425 2426 if (devent->fetch != NULL) { 2427 dns_resolver_destroyfetch(&devent->fetch); 2428 } 2429 if (devent->node != NULL) { 2430 dns_db_detachnode(devent->db, &devent->node); 2431 } 2432 if (devent->db != NULL) { 2433 dns_db_detach(&devent->db); 2434 } 2435 if (devent->rdataset != NULL) { 2436 ns_client_putrdataset(client, &devent->rdataset); 2437 } 2438 if (devent->sigrdataset != NULL) { 2439 ns_client_putrdataset(client, &devent->sigrdataset); 2440 } 2441 2442 /* 2443 * If the two pointers are the same then leave the setting of 2444 * (*deventp) to NULL to isc_event_free. 2445 */ 2446 if ((void *)eventp != (void *)deventp) { 2447 (*deventp) = NULL; 2448 } 2449 isc_event_free(eventp); 2450 } 2451 2452 static void 2453 prefetch_done(isc_task_t *task, isc_event_t *event) { 2454 dns_fetchevent_t *devent = (dns_fetchevent_t *)event; 2455 ns_client_t *client; 2456 2457 UNUSED(task); 2458 2459 REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); 2460 client = devent->ev_arg; 2461 REQUIRE(NS_CLIENT_VALID(client)); 2462 REQUIRE(task == client->task); 2463 2464 CTRACE(ISC_LOG_DEBUG(3), "prefetch_done"); 2465 2466 LOCK(&client->query.fetchlock); 2467 if (client->query.prefetch != NULL) { 2468 INSIST(devent->fetch == client->query.prefetch); 2469 client->query.prefetch = NULL; 2470 } 2471 UNLOCK(&client->query.fetchlock); 2472 2473 /* 2474 * We're done prefetching, detach from quota. 2475 */ 2476 if (client->recursionquota != NULL) { 2477 isc_quota_detach(&client->recursionquota); 2478 } 2479 2480 free_devent(client, &event, &devent); 2481 isc_nmhandle_unref(client->handle); 2482 } 2483 2484 static void 2485 query_prefetch(ns_client_t *client, dns_name_t *qname, 2486 dns_rdataset_t *rdataset) { 2487 isc_result_t result; 2488 isc_sockaddr_t *peeraddr; 2489 dns_rdataset_t *tmprdataset; 2490 unsigned int options; 2491 2492 CTRACE(ISC_LOG_DEBUG(3), "query_prefetch"); 2493 2494 if (client->query.prefetch != NULL || 2495 client->view->prefetch_trigger == 0U || 2496 rdataset->ttl > client->view->prefetch_trigger || 2497 (rdataset->attributes & DNS_RDATASETATTR_PREFETCH) == 0) 2498 { 2499 return; 2500 } 2501 2502 if (client->recursionquota == NULL) { 2503 result = isc_quota_attach(&client->sctx->recursionquota, 2504 &client->recursionquota); 2505 if (result == ISC_R_SOFTQUOTA) { 2506 isc_quota_detach(&client->recursionquota); 2507 } 2508 if (result != ISC_R_SUCCESS) { 2509 return; 2510 } 2511 } 2512 2513 tmprdataset = ns_client_newrdataset(client); 2514 if (tmprdataset == NULL) { 2515 return; 2516 } 2517 2518 if (!TCP(client)) { 2519 peeraddr = &client->peeraddr; 2520 } else { 2521 peeraddr = NULL; 2522 } 2523 2524 isc_nmhandle_ref(client->handle); 2525 options = client->query.fetchoptions | DNS_FETCHOPT_PREFETCH; 2526 result = dns_resolver_createfetch( 2527 client->view->resolver, qname, rdataset->type, NULL, NULL, NULL, 2528 peeraddr, client->message->id, options, 0, NULL, client->task, 2529 prefetch_done, client, tmprdataset, NULL, 2530 &client->query.prefetch); 2531 if (result != ISC_R_SUCCESS) { 2532 ns_client_putrdataset(client, &tmprdataset); 2533 isc_nmhandle_unref(client->handle); 2534 } 2535 2536 dns_rdataset_clearprefetch(rdataset); 2537 ns_stats_increment(client->sctx->nsstats, ns_statscounter_prefetch); 2538 } 2539 2540 static inline void 2541 rpz_clean(dns_zone_t **zonep, dns_db_t **dbp, dns_dbnode_t **nodep, 2542 dns_rdataset_t **rdatasetp) { 2543 if (nodep != NULL && *nodep != NULL) { 2544 REQUIRE(dbp != NULL && *dbp != NULL); 2545 dns_db_detachnode(*dbp, nodep); 2546 } 2547 if (dbp != NULL && *dbp != NULL) { 2548 dns_db_detach(dbp); 2549 } 2550 if (zonep != NULL && *zonep != NULL) { 2551 dns_zone_detach(zonep); 2552 } 2553 if (rdatasetp != NULL && *rdatasetp != NULL && 2554 dns_rdataset_isassociated(*rdatasetp)) 2555 { 2556 dns_rdataset_disassociate(*rdatasetp); 2557 } 2558 } 2559 2560 static inline void 2561 rpz_match_clear(dns_rpz_st_t *st) { 2562 rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset); 2563 st->m.version = NULL; 2564 } 2565 2566 static inline isc_result_t 2567 rpz_ready(ns_client_t *client, dns_rdataset_t **rdatasetp) { 2568 REQUIRE(rdatasetp != NULL); 2569 2570 CTRACE(ISC_LOG_DEBUG(3), "rpz_ready"); 2571 2572 if (*rdatasetp == NULL) { 2573 *rdatasetp = ns_client_newrdataset(client); 2574 if (*rdatasetp == NULL) { 2575 CTRACE(ISC_LOG_ERROR, "rpz_ready: " 2576 "ns_client_newrdataset failed"); 2577 return (DNS_R_SERVFAIL); 2578 } 2579 } else if (dns_rdataset_isassociated(*rdatasetp)) { 2580 dns_rdataset_disassociate(*rdatasetp); 2581 } 2582 return (ISC_R_SUCCESS); 2583 } 2584 2585 static void 2586 rpz_st_clear(ns_client_t *client) { 2587 dns_rpz_st_t *st = client->query.rpz_st; 2588 2589 CTRACE(ISC_LOG_DEBUG(3), "rpz_st_clear"); 2590 2591 if (st->m.rdataset != NULL) { 2592 ns_client_putrdataset(client, &st->m.rdataset); 2593 } 2594 rpz_match_clear(st); 2595 2596 rpz_clean(NULL, &st->r.db, NULL, NULL); 2597 if (st->r.ns_rdataset != NULL) { 2598 ns_client_putrdataset(client, &st->r.ns_rdataset); 2599 } 2600 if (st->r.r_rdataset != NULL) { 2601 ns_client_putrdataset(client, &st->r.r_rdataset); 2602 } 2603 2604 rpz_clean(&st->q.zone, &st->q.db, &st->q.node, NULL); 2605 if (st->q.rdataset != NULL) { 2606 ns_client_putrdataset(client, &st->q.rdataset); 2607 } 2608 if (st->q.sigrdataset != NULL) { 2609 ns_client_putrdataset(client, &st->q.sigrdataset); 2610 } 2611 st->state = 0; 2612 st->m.type = DNS_RPZ_TYPE_BAD; 2613 st->m.policy = DNS_RPZ_POLICY_MISS; 2614 if (st->rpsdb != NULL) { 2615 dns_db_detach(&st->rpsdb); 2616 } 2617 } 2618 2619 static dns_rpz_zbits_t 2620 rpz_get_zbits(ns_client_t *client, dns_rdatatype_t ip_type, 2621 dns_rpz_type_t rpz_type) { 2622 dns_rpz_st_t *st; 2623 dns_rpz_zbits_t zbits = 0; 2624 2625 REQUIRE(client != NULL); 2626 REQUIRE(client->query.rpz_st != NULL); 2627 2628 st = client->query.rpz_st; 2629 2630 #ifdef USE_DNSRPS 2631 if (st->popt.dnsrps_enabled) { 2632 if (st->rpsdb == NULL || 2633 librpz->have_trig(dns_dnsrps_type2trig(rpz_type), 2634 ip_type == dns_rdatatype_aaaa, 2635 ((rpsdb_t *)st->rpsdb)->rsp)) 2636 { 2637 return (DNS_RPZ_ALL_ZBITS); 2638 } 2639 return (0); 2640 } 2641 #endif /* ifdef USE_DNSRPS */ 2642 2643 switch (rpz_type) { 2644 case DNS_RPZ_TYPE_CLIENT_IP: 2645 zbits = st->have.client_ip; 2646 break; 2647 case DNS_RPZ_TYPE_QNAME: 2648 zbits = st->have.qname; 2649 break; 2650 case DNS_RPZ_TYPE_IP: 2651 if (ip_type == dns_rdatatype_a) { 2652 zbits = st->have.ipv4; 2653 } else if (ip_type == dns_rdatatype_aaaa) { 2654 zbits = st->have.ipv6; 2655 } else { 2656 zbits = st->have.ip; 2657 } 2658 break; 2659 case DNS_RPZ_TYPE_NSDNAME: 2660 zbits = st->have.nsdname; 2661 break; 2662 case DNS_RPZ_TYPE_NSIP: 2663 if (ip_type == dns_rdatatype_a) { 2664 zbits = st->have.nsipv4; 2665 } else if (ip_type == dns_rdatatype_aaaa) { 2666 zbits = st->have.nsipv6; 2667 } else { 2668 zbits = st->have.nsip; 2669 } 2670 break; 2671 default: 2672 INSIST(0); 2673 ISC_UNREACHABLE(); 2674 } 2675 2676 /* 2677 * Choose 2678 * the earliest configured policy zone (rpz->num) 2679 * QNAME over IP over NSDNAME over NSIP (rpz_type) 2680 * the smallest name, 2681 * the longest IP address prefix, 2682 * the lexically smallest address. 2683 */ 2684 if (st->m.policy != DNS_RPZ_POLICY_MISS) { 2685 if (st->m.type >= rpz_type) { 2686 zbits &= DNS_RPZ_ZMASK(st->m.rpz->num); 2687 } else { 2688 zbits &= DNS_RPZ_ZMASK(st->m.rpz->num) >> 1; 2689 } 2690 } 2691 2692 /* 2693 * If the client wants recursion, allow only compatible policies. 2694 */ 2695 if (!RECURSIONOK(client)) { 2696 zbits &= st->popt.no_rd_ok; 2697 } 2698 2699 return (zbits); 2700 } 2701 2702 static void 2703 query_rpzfetch(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t type) { 2704 isc_result_t result; 2705 isc_sockaddr_t *peeraddr; 2706 dns_rdataset_t *tmprdataset; 2707 unsigned int options; 2708 2709 CTRACE(ISC_LOG_DEBUG(3), "query_rpzfetch"); 2710 2711 if (client->query.prefetch != NULL) { 2712 return; 2713 } 2714 2715 if (client->recursionquota == NULL) { 2716 result = isc_quota_attach(&client->sctx->recursionquota, 2717 &client->recursionquota); 2718 if (result == ISC_R_SOFTQUOTA) { 2719 isc_quota_detach(&client->recursionquota); 2720 } 2721 if (result != ISC_R_SUCCESS) { 2722 return; 2723 } 2724 } 2725 2726 tmprdataset = ns_client_newrdataset(client); 2727 if (tmprdataset == NULL) { 2728 return; 2729 } 2730 2731 if (!TCP(client)) { 2732 peeraddr = &client->peeraddr; 2733 } else { 2734 peeraddr = NULL; 2735 } 2736 2737 options = client->query.fetchoptions; 2738 isc_nmhandle_ref(client->handle); 2739 result = dns_resolver_createfetch( 2740 client->view->resolver, qname, type, NULL, NULL, NULL, peeraddr, 2741 client->message->id, options, 0, NULL, client->task, 2742 prefetch_done, client, tmprdataset, NULL, 2743 &client->query.prefetch); 2744 if (result != ISC_R_SUCCESS) { 2745 ns_client_putrdataset(client, &tmprdataset); 2746 isc_nmhandle_unref(client->handle); 2747 } 2748 } 2749 2750 /* 2751 * Get an NS, A, or AAAA rrset related to the response for the client 2752 * to check the contents of that rrset for hits by eligible policy zones. 2753 */ 2754 static isc_result_t 2755 rpz_rrset_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, 2756 dns_rpz_type_t rpz_type, dns_db_t **dbp, 2757 dns_dbversion_t *version, dns_rdataset_t **rdatasetp, 2758 bool resuming) { 2759 dns_rpz_st_t *st; 2760 bool is_zone; 2761 dns_dbnode_t *node; 2762 dns_fixedname_t fixed; 2763 dns_name_t *found; 2764 isc_result_t result; 2765 dns_clientinfomethods_t cm; 2766 dns_clientinfo_t ci; 2767 2768 CTRACE(ISC_LOG_DEBUG(3), "rpz_rrset_find"); 2769 2770 st = client->query.rpz_st; 2771 if ((st->state & DNS_RPZ_RECURSING) != 0) { 2772 INSIST(st->r.r_type == type); 2773 INSIST(dns_name_equal(name, st->r_name)); 2774 INSIST(*rdatasetp == NULL || 2775 !dns_rdataset_isassociated(*rdatasetp)); 2776 st->state &= ~DNS_RPZ_RECURSING; 2777 RESTORE(*dbp, st->r.db); 2778 if (*rdatasetp != NULL) { 2779 ns_client_putrdataset(client, rdatasetp); 2780 } 2781 RESTORE(*rdatasetp, st->r.r_rdataset); 2782 result = st->r.r_result; 2783 if (result == DNS_R_DELEGATION) { 2784 CTRACE(ISC_LOG_ERROR, "RPZ recursing"); 2785 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name, 2786 rpz_type, "rpz_rrset_find(1)", result); 2787 st->m.policy = DNS_RPZ_POLICY_ERROR; 2788 result = DNS_R_SERVFAIL; 2789 } 2790 return (result); 2791 } 2792 2793 result = rpz_ready(client, rdatasetp); 2794 if (result != ISC_R_SUCCESS) { 2795 st->m.policy = DNS_RPZ_POLICY_ERROR; 2796 return (result); 2797 } 2798 if (*dbp != NULL) { 2799 is_zone = false; 2800 } else { 2801 dns_zone_t *zone; 2802 2803 version = NULL; 2804 zone = NULL; 2805 result = query_getdb(client, name, type, 0, &zone, dbp, 2806 &version, &is_zone); 2807 if (result != ISC_R_SUCCESS) { 2808 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name, 2809 rpz_type, "rpz_rrset_find(2)", result); 2810 st->m.policy = DNS_RPZ_POLICY_ERROR; 2811 if (zone != NULL) { 2812 dns_zone_detach(&zone); 2813 } 2814 return (result); 2815 } 2816 if (zone != NULL) { 2817 dns_zone_detach(&zone); 2818 } 2819 } 2820 2821 node = NULL; 2822 found = dns_fixedname_initname(&fixed); 2823 dns_clientinfomethods_init(&cm, ns_client_sourceip); 2824 dns_clientinfo_init(&ci, client, NULL); 2825 result = dns_db_findext(*dbp, name, version, type, DNS_DBFIND_GLUEOK, 2826 client->now, &node, found, &cm, &ci, *rdatasetp, 2827 NULL); 2828 if (result == DNS_R_DELEGATION && is_zone && USECACHE(client)) { 2829 /* 2830 * Try the cache if we're authoritative for an 2831 * ancestor but not the domain itself. 2832 */ 2833 rpz_clean(NULL, dbp, &node, rdatasetp); 2834 version = NULL; 2835 dns_db_attach(client->view->cachedb, dbp); 2836 result = dns_db_findext(*dbp, name, version, type, 0, 2837 client->now, &node, found, &cm, &ci, 2838 *rdatasetp, NULL); 2839 } 2840 rpz_clean(NULL, dbp, &node, NULL); 2841 if (result == DNS_R_DELEGATION) { 2842 rpz_clean(NULL, NULL, NULL, rdatasetp); 2843 /* 2844 * Recurse for NS rrset or A or AAAA rrset for an NS. 2845 * Do not recurse for addresses for the query name. 2846 */ 2847 if (rpz_type == DNS_RPZ_TYPE_IP) { 2848 result = DNS_R_NXRRSET; 2849 } else if (!client->view->rpzs->p.nsip_wait_recurse) { 2850 query_rpzfetch(client, name, type); 2851 result = DNS_R_NXRRSET; 2852 } else { 2853 dns_name_copynf(name, st->r_name); 2854 result = ns_query_recurse(client, type, st->r_name, 2855 NULL, NULL, resuming); 2856 if (result == ISC_R_SUCCESS) { 2857 st->state |= DNS_RPZ_RECURSING; 2858 result = DNS_R_DELEGATION; 2859 } 2860 } 2861 } 2862 return (result); 2863 } 2864 2865 /* 2866 * Compute a policy owner name, p_name, in a policy zone given the needed 2867 * policy type and the trigger name. 2868 */ 2869 static isc_result_t 2870 rpz_get_p_name(ns_client_t *client, dns_name_t *p_name, dns_rpz_zone_t *rpz, 2871 dns_rpz_type_t rpz_type, dns_name_t *trig_name) { 2872 dns_offsets_t prefix_offsets; 2873 dns_name_t prefix, *suffix; 2874 unsigned int first, labels; 2875 isc_result_t result; 2876 2877 CTRACE(ISC_LOG_DEBUG(3), "rpz_get_p_name"); 2878 2879 /* 2880 * The policy owner name consists of a suffix depending on the type 2881 * and policy zone and a prefix that is the longest possible string 2882 * from the trigger name that keesp the resulting policy owner name 2883 * from being too long. 2884 */ 2885 switch (rpz_type) { 2886 case DNS_RPZ_TYPE_CLIENT_IP: 2887 suffix = &rpz->client_ip; 2888 break; 2889 case DNS_RPZ_TYPE_QNAME: 2890 suffix = &rpz->origin; 2891 break; 2892 case DNS_RPZ_TYPE_IP: 2893 suffix = &rpz->ip; 2894 break; 2895 case DNS_RPZ_TYPE_NSDNAME: 2896 suffix = &rpz->nsdname; 2897 break; 2898 case DNS_RPZ_TYPE_NSIP: 2899 suffix = &rpz->nsip; 2900 break; 2901 default: 2902 INSIST(0); 2903 ISC_UNREACHABLE(); 2904 } 2905 2906 /* 2907 * Start with relative version of the full trigger name, 2908 * and trim enough allow the addition of the suffix. 2909 */ 2910 dns_name_init(&prefix, prefix_offsets); 2911 labels = dns_name_countlabels(trig_name); 2912 first = 0; 2913 for (;;) { 2914 dns_name_getlabelsequence(trig_name, first, labels - first - 1, 2915 &prefix); 2916 result = dns_name_concatenate(&prefix, suffix, p_name, NULL); 2917 if (result == ISC_R_SUCCESS) { 2918 break; 2919 } 2920 INSIST(result == DNS_R_NAMETOOLONG); 2921 /* 2922 * Trim the trigger name until the combination is not too long. 2923 */ 2924 if (labels - first < 2) { 2925 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, suffix, 2926 rpz_type, "concatenate()", result); 2927 return (ISC_R_FAILURE); 2928 } 2929 /* 2930 * Complain once about trimming the trigger name. 2931 */ 2932 if (first == 0) { 2933 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, suffix, 2934 rpz_type, "concatenate()", result); 2935 } 2936 ++first; 2937 } 2938 return (ISC_R_SUCCESS); 2939 } 2940 2941 /* 2942 * Look in policy zone rpz for a policy of rpz_type by p_name. 2943 * The self-name (usually the client qname or an NS name) is compared with 2944 * the target of a CNAME policy for the old style passthru encoding. 2945 * If found, the policy is recorded in *zonep, *dbp, *versionp, *nodep, 2946 * *rdatasetp, and *policyp. 2947 * The target DNS type, qtype, chooses the best rdataset for *rdatasetp. 2948 * The caller must decide if the found policy is most suitable, including 2949 * better than a previously found policy. 2950 * If it is best, the caller records it in client->query.rpz_st->m. 2951 */ 2952 static isc_result_t 2953 rpz_find_p(ns_client_t *client, dns_name_t *self_name, dns_rdatatype_t qtype, 2954 dns_name_t *p_name, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, 2955 dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp, 2956 dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp, 2957 dns_rpz_policy_t *policyp) { 2958 dns_fixedname_t foundf; 2959 dns_name_t *found; 2960 isc_result_t result; 2961 dns_clientinfomethods_t cm; 2962 dns_clientinfo_t ci; 2963 bool found_a = false; 2964 2965 REQUIRE(nodep != NULL); 2966 2967 CTRACE(ISC_LOG_DEBUG(3), "rpz_find_p"); 2968 2969 dns_clientinfomethods_init(&cm, ns_client_sourceip); 2970 dns_clientinfo_init(&ci, client, NULL); 2971 2972 /* 2973 * Try to find either a CNAME or the type of record demanded by the 2974 * request from the policy zone. 2975 */ 2976 rpz_clean(zonep, dbp, nodep, rdatasetp); 2977 result = rpz_ready(client, rdatasetp); 2978 if (result != ISC_R_SUCCESS) { 2979 CTRACE(ISC_LOG_ERROR, "rpz_ready() failed"); 2980 return (DNS_R_SERVFAIL); 2981 } 2982 *versionp = NULL; 2983 result = rpz_getdb(client, p_name, rpz_type, zonep, dbp, versionp); 2984 if (result != ISC_R_SUCCESS) { 2985 return (DNS_R_NXDOMAIN); 2986 } 2987 found = dns_fixedname_initname(&foundf); 2988 2989 result = dns_db_findext(*dbp, p_name, *versionp, dns_rdatatype_any, 0, 2990 client->now, nodep, found, &cm, &ci, *rdatasetp, 2991 NULL); 2992 /* 2993 * Choose the best rdataset if we found something. 2994 */ 2995 if (result == ISC_R_SUCCESS) { 2996 dns_rdatasetiter_t *rdsiter; 2997 2998 rdsiter = NULL; 2999 result = dns_db_allrdatasets(*dbp, *nodep, *versionp, 0, 3000 &rdsiter); 3001 if (result != ISC_R_SUCCESS) { 3002 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, 3003 rpz_type, "allrdatasets()", result); 3004 CTRACE(ISC_LOG_ERROR, 3005 "rpz_find_p: allrdatasets failed"); 3006 return (DNS_R_SERVFAIL); 3007 } 3008 if (qtype == dns_rdatatype_aaaa && 3009 !ISC_LIST_EMPTY(client->view->dns64)) { 3010 for (result = dns_rdatasetiter_first(rdsiter); 3011 result == ISC_R_SUCCESS; 3012 result = dns_rdatasetiter_next(rdsiter)) 3013 { 3014 dns_rdatasetiter_current(rdsiter, *rdatasetp); 3015 if ((*rdatasetp)->type == dns_rdatatype_a) { 3016 found_a = true; 3017 } 3018 dns_rdataset_disassociate(*rdatasetp); 3019 } 3020 } 3021 for (result = dns_rdatasetiter_first(rdsiter); 3022 result == ISC_R_SUCCESS; 3023 result = dns_rdatasetiter_next(rdsiter)) 3024 { 3025 dns_rdatasetiter_current(rdsiter, *rdatasetp); 3026 if ((*rdatasetp)->type == dns_rdatatype_cname || 3027 (*rdatasetp)->type == qtype) { 3028 break; 3029 } 3030 dns_rdataset_disassociate(*rdatasetp); 3031 } 3032 dns_rdatasetiter_destroy(&rdsiter); 3033 if (result != ISC_R_SUCCESS) { 3034 if (result != ISC_R_NOMORE) { 3035 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, 3036 p_name, rpz_type, "rdatasetiter", 3037 result); 3038 CTRACE(ISC_LOG_ERROR, "rpz_find_p: " 3039 "rdatasetiter failed"); 3040 return (DNS_R_SERVFAIL); 3041 } 3042 /* 3043 * Ask again to get the right DNS_R_DNAME/NXRRSET/... 3044 * result if there is neither a CNAME nor target type. 3045 */ 3046 if (dns_rdataset_isassociated(*rdatasetp)) { 3047 dns_rdataset_disassociate(*rdatasetp); 3048 } 3049 dns_db_detachnode(*dbp, nodep); 3050 3051 if (qtype == dns_rdatatype_rrsig || 3052 qtype == dns_rdatatype_sig) { 3053 result = DNS_R_NXRRSET; 3054 } else { 3055 result = dns_db_findext(*dbp, p_name, *versionp, 3056 qtype, 0, client->now, 3057 nodep, found, &cm, &ci, 3058 *rdatasetp, NULL); 3059 } 3060 } 3061 } 3062 switch (result) { 3063 case ISC_R_SUCCESS: 3064 if ((*rdatasetp)->type != dns_rdatatype_cname) { 3065 *policyp = DNS_RPZ_POLICY_RECORD; 3066 } else { 3067 *policyp = dns_rpz_decode_cname(rpz, *rdatasetp, 3068 self_name); 3069 if ((*policyp == DNS_RPZ_POLICY_RECORD || 3070 *policyp == DNS_RPZ_POLICY_WILDCNAME) && 3071 qtype != dns_rdatatype_cname && 3072 qtype != dns_rdatatype_any) 3073 { 3074 return (DNS_R_CNAME); 3075 } 3076 } 3077 return (ISC_R_SUCCESS); 3078 case DNS_R_NXRRSET: 3079 if (found_a) { 3080 *policyp = DNS_RPZ_POLICY_DNS64; 3081 } else { 3082 *policyp = DNS_RPZ_POLICY_NODATA; 3083 } 3084 return (result); 3085 case DNS_R_DNAME: 3086 /* 3087 * DNAME policy RRs have very few if any uses that are not 3088 * better served with simple wildcards. Making them work would 3089 * require complications to get the number of labels matched 3090 * in the name or the found name to the main DNS_R_DNAME case 3091 * in query_dname(). The domain also does not appear in the 3092 * summary database at the right level, so this happens only 3093 * with a single policy zone when we have no summary database. 3094 * Treat it as a miss. 3095 */ 3096 case DNS_R_NXDOMAIN: 3097 case DNS_R_EMPTYNAME: 3098 return (DNS_R_NXDOMAIN); 3099 default: 3100 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type, "", 3101 result); 3102 CTRACE(ISC_LOG_ERROR, "rpz_find_p: unexpected result"); 3103 return (DNS_R_SERVFAIL); 3104 } 3105 } 3106 3107 static void 3108 rpz_save_p(dns_rpz_st_t *st, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, 3109 dns_rpz_policy_t policy, dns_name_t *p_name, dns_rpz_prefix_t prefix, 3110 isc_result_t result, dns_zone_t **zonep, dns_db_t **dbp, 3111 dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp, 3112 dns_dbversion_t *version) { 3113 dns_rdataset_t *trdataset = NULL; 3114 3115 rpz_match_clear(st); 3116 st->m.rpz = rpz; 3117 st->m.type = rpz_type; 3118 st->m.policy = policy; 3119 dns_name_copynf(p_name, st->p_name); 3120 st->m.prefix = prefix; 3121 st->m.result = result; 3122 SAVE(st->m.zone, *zonep); 3123 SAVE(st->m.db, *dbp); 3124 SAVE(st->m.node, *nodep); 3125 if (*rdatasetp != NULL && dns_rdataset_isassociated(*rdatasetp)) { 3126 /* 3127 * Save the replacement rdataset from the policy 3128 * and make the previous replacement rdataset scratch. 3129 */ 3130 SAVE(trdataset, st->m.rdataset); 3131 SAVE(st->m.rdataset, *rdatasetp); 3132 SAVE(*rdatasetp, trdataset); 3133 st->m.ttl = ISC_MIN(st->m.rdataset->ttl, rpz->max_policy_ttl); 3134 } else { 3135 st->m.ttl = ISC_MIN(DNS_RPZ_TTL_DEFAULT, rpz->max_policy_ttl); 3136 } 3137 SAVE(st->m.version, version); 3138 } 3139 3140 #ifdef USE_DNSRPS 3141 /* 3142 * Check the results of a RPZ service interface lookup. 3143 * Stop after an error (<0) or not a hit on a disabled zone (0). 3144 * Continue after a hit on a disabled zone (>0). 3145 */ 3146 static int 3147 dnsrps_ck(librpz_emsg_t *emsg, ns_client_t *client, rpsdb_t *rpsdb, 3148 bool recursed) { 3149 isc_region_t region; 3150 librpz_domain_buf_t pname_buf; 3151 3152 if (!librpz->rsp_result(emsg, &rpsdb->result, recursed, rpsdb->rsp)) { 3153 return (-1); 3154 } 3155 3156 /* 3157 * Forget the state from before the IP address or domain check 3158 * if the lookup hit nothing. 3159 */ 3160 if (rpsdb->result.policy == LIBRPZ_POLICY_UNDEFINED || 3161 rpsdb->result.hit_id != rpsdb->hit_id || 3162 rpsdb->result.policy != LIBRPZ_POLICY_DISABLED) 3163 { 3164 if (!librpz->rsp_pop_discard(emsg, rpsdb->rsp)) { 3165 return (-1); 3166 } 3167 return (0); 3168 } 3169 3170 /* 3171 * Log a hit on a disabled zone. 3172 * Forget the zone to not try it again, and restore the pre-hit state. 3173 */ 3174 if (!librpz->rsp_domain(emsg, &pname_buf, rpsdb->rsp)) { 3175 return (-1); 3176 } 3177 region.base = pname_buf.d; 3178 region.length = pname_buf.size; 3179 dns_name_fromregion(client->query.rpz_st->p_name, ®ion); 3180 rpz_log_rewrite(client, true, dns_dnsrps_2policy(rpsdb->result.zpolicy), 3181 dns_dnsrps_trig2type(rpsdb->result.trig), NULL, 3182 client->query.rpz_st->p_name, NULL, 3183 rpsdb->result.cznum); 3184 3185 if (!librpz->rsp_forget_zone(emsg, rpsdb->result.cznum, rpsdb->rsp) || 3186 !librpz->rsp_pop(emsg, &rpsdb->result, rpsdb->rsp)) 3187 { 3188 return (-1); 3189 } 3190 return (1); 3191 } 3192 3193 /* 3194 * Ready the shim database and rdataset for a DNSRPS hit. 3195 */ 3196 static bool 3197 dnsrps_set_p(librpz_emsg_t *emsg, ns_client_t *client, dns_rpz_st_t *st, 3198 dns_rdatatype_t qtype, dns_rdataset_t **p_rdatasetp, 3199 bool recursed) { 3200 rpsdb_t *rpsdb; 3201 librpz_domain_buf_t pname_buf; 3202 isc_region_t region; 3203 dns_zone_t *p_zone; 3204 dns_db_t *p_db; 3205 dns_dbnode_t *p_node; 3206 dns_rpz_policy_t policy; 3207 dns_fixedname_t foundf; 3208 dns_name_t *found; 3209 dns_rdatatype_t foundtype, searchtype; 3210 isc_result_t result; 3211 3212 rpsdb = (rpsdb_t *)st->rpsdb; 3213 3214 if (!librpz->rsp_result(emsg, &rpsdb->result, recursed, rpsdb->rsp)) { 3215 return (false); 3216 } 3217 3218 if (rpsdb->result.policy == LIBRPZ_POLICY_UNDEFINED) { 3219 return (true); 3220 } 3221 3222 /* 3223 * Give the fake or shim DNSRPS database its new origin. 3224 */ 3225 if (!librpz->rsp_soa(emsg, NULL, NULL, &rpsdb->origin_buf, 3226 &rpsdb->result, rpsdb->rsp)) 3227 { 3228 return (false); 3229 } 3230 region.base = rpsdb->origin_buf.d; 3231 region.length = rpsdb->origin_buf.size; 3232 dns_name_fromregion(&rpsdb->common.origin, ®ion); 3233 3234 if (!librpz->rsp_domain(emsg, &pname_buf, rpsdb->rsp)) { 3235 return (false); 3236 } 3237 region.base = pname_buf.d; 3238 region.length = pname_buf.size; 3239 dns_name_fromregion(st->p_name, ®ion); 3240 3241 p_zone = NULL; 3242 p_db = NULL; 3243 p_node = NULL; 3244 rpz_ready(client, p_rdatasetp); 3245 dns_db_attach(st->rpsdb, &p_db); 3246 policy = dns_dnsrps_2policy(rpsdb->result.policy); 3247 if (policy != DNS_RPZ_POLICY_RECORD) { 3248 result = ISC_R_SUCCESS; 3249 } else if (qtype == dns_rdatatype_rrsig) { 3250 /* 3251 * dns_find_db() refuses to look for and fail to 3252 * find dns_rdatatype_rrsig. 3253 */ 3254 result = DNS_R_NXRRSET; 3255 policy = DNS_RPZ_POLICY_NODATA; 3256 } else { 3257 /* 3258 * Get the next (and so first) RR from the policy node. 3259 * If it is a CNAME, then look for it regardless of the 3260 * query type. 3261 */ 3262 if (!librpz->rsp_rr(emsg, &foundtype, NULL, NULL, NULL, 3263 &rpsdb->result, rpsdb->qname->ndata, 3264 rpsdb->qname->length, rpsdb->rsp)) 3265 { 3266 return (false); 3267 } 3268 if (foundtype == dns_rdatatype_cname) { 3269 searchtype = dns_rdatatype_cname; 3270 } else { 3271 searchtype = qtype; 3272 } 3273 /* 3274 * Get the DNSPRS imitation rdataset. 3275 */ 3276 found = dns_fixedname_initname(&foundf); 3277 result = dns_db_find(p_db, st->p_name, NULL, searchtype, 0, 0, 3278 &p_node, found, *p_rdatasetp, NULL); 3279 3280 if (result == ISC_R_SUCCESS) { 3281 if (searchtype == dns_rdatatype_cname && 3282 qtype != dns_rdatatype_cname) { 3283 result = DNS_R_CNAME; 3284 } 3285 } else if (result == DNS_R_NXRRSET) { 3286 policy = DNS_RPZ_POLICY_NODATA; 3287 } else { 3288 snprintf(emsg->c, sizeof(emsg->c), "dns_db_find(): %s", 3289 isc_result_totext(result)); 3290 return (false); 3291 } 3292 } 3293 3294 rpz_save_p(st, client->view->rpzs->zones[rpsdb->result.cznum], 3295 dns_dnsrps_trig2type(rpsdb->result.trig), policy, st->p_name, 3296 0, result, &p_zone, &p_db, &p_node, p_rdatasetp, NULL); 3297 3298 rpz_clean(NULL, NULL, NULL, p_rdatasetp); 3299 3300 return (true); 3301 } 3302 3303 static isc_result_t 3304 dnsrps_rewrite_ip(ns_client_t *client, const isc_netaddr_t *netaddr, 3305 dns_rpz_type_t rpz_type, dns_rdataset_t **p_rdatasetp) { 3306 dns_rpz_st_t *st; 3307 rpsdb_t *rpsdb; 3308 librpz_trig_t trig = LIBRPZ_TRIG_CLIENT_IP; 3309 bool recursed = false; 3310 int res; 3311 librpz_emsg_t emsg; 3312 isc_result_t result; 3313 3314 st = client->query.rpz_st; 3315 rpsdb = (rpsdb_t *)st->rpsdb; 3316 3317 result = rpz_ready(client, p_rdatasetp); 3318 if (result != ISC_R_SUCCESS) { 3319 st->m.policy = DNS_RPZ_POLICY_ERROR; 3320 return (result); 3321 } 3322 3323 switch (rpz_type) { 3324 case DNS_RPZ_TYPE_CLIENT_IP: 3325 trig = LIBRPZ_TRIG_CLIENT_IP; 3326 recursed = false; 3327 break; 3328 case DNS_RPZ_TYPE_IP: 3329 trig = LIBRPZ_TRIG_IP; 3330 recursed = true; 3331 break; 3332 case DNS_RPZ_TYPE_NSIP: 3333 trig = LIBRPZ_TRIG_NSIP; 3334 recursed = true; 3335 break; 3336 default: 3337 INSIST(0); 3338 ISC_UNREACHABLE(); 3339 } 3340 3341 do { 3342 if (!librpz->rsp_push(&emsg, rpsdb->rsp) || 3343 !librpz->ck_ip(&emsg, 3344 netaddr->family == AF_INET 3345 ? (const void *)&netaddr->type.in 3346 : (const void *)&netaddr->type.in6, 3347 netaddr->family, trig, ++rpsdb->hit_id, 3348 recursed, rpsdb->rsp) || 3349 (res = dnsrps_ck(&emsg, client, rpsdb, recursed)) < 0) 3350 { 3351 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL, 3352 rpz_type, emsg.c, DNS_R_SERVFAIL); 3353 st->m.policy = DNS_RPZ_POLICY_ERROR; 3354 return (DNS_R_SERVFAIL); 3355 } 3356 } while (res != 0); 3357 return (ISC_R_SUCCESS); 3358 } 3359 3360 static isc_result_t 3361 dnsrps_rewrite_name(ns_client_t *client, dns_name_t *trig_name, bool recursed, 3362 dns_rpz_type_t rpz_type, dns_rdataset_t **p_rdatasetp) { 3363 dns_rpz_st_t *st; 3364 rpsdb_t *rpsdb; 3365 librpz_trig_t trig = LIBRPZ_TRIG_CLIENT_IP; 3366 isc_region_t r; 3367 int res; 3368 librpz_emsg_t emsg; 3369 isc_result_t result; 3370 3371 st = client->query.rpz_st; 3372 rpsdb = (rpsdb_t *)st->rpsdb; 3373 3374 result = rpz_ready(client, p_rdatasetp); 3375 if (result != ISC_R_SUCCESS) { 3376 st->m.policy = DNS_RPZ_POLICY_ERROR; 3377 return (result); 3378 } 3379 3380 switch (rpz_type) { 3381 case DNS_RPZ_TYPE_QNAME: 3382 trig = LIBRPZ_TRIG_QNAME; 3383 break; 3384 case DNS_RPZ_TYPE_NSDNAME: 3385 trig = LIBRPZ_TRIG_NSDNAME; 3386 break; 3387 default: 3388 INSIST(0); 3389 ISC_UNREACHABLE(); 3390 } 3391 3392 dns_name_toregion(trig_name, &r); 3393 do { 3394 if (!librpz->rsp_push(&emsg, rpsdb->rsp) || 3395 !librpz->ck_domain(&emsg, r.base, r.length, trig, 3396 ++rpsdb->hit_id, recursed, rpsdb->rsp) || 3397 (res = dnsrps_ck(&emsg, client, rpsdb, recursed)) < 0) 3398 { 3399 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL, 3400 rpz_type, emsg.c, DNS_R_SERVFAIL); 3401 st->m.policy = DNS_RPZ_POLICY_ERROR; 3402 return (DNS_R_SERVFAIL); 3403 } 3404 } while (res != 0); 3405 return (ISC_R_SUCCESS); 3406 } 3407 #endif /* USE_DNSRPS */ 3408 3409 /* 3410 * Check this address in every eligible policy zone. 3411 */ 3412 static isc_result_t 3413 rpz_rewrite_ip(ns_client_t *client, const isc_netaddr_t *netaddr, 3414 dns_rdatatype_t qtype, dns_rpz_type_t rpz_type, 3415 dns_rpz_zbits_t zbits, dns_rdataset_t **p_rdatasetp) { 3416 dns_rpz_zones_t *rpzs; 3417 dns_rpz_st_t *st; 3418 dns_rpz_zone_t *rpz; 3419 dns_rpz_prefix_t prefix; 3420 dns_rpz_num_t rpz_num; 3421 dns_fixedname_t ip_namef, p_namef; 3422 dns_name_t *ip_name, *p_name; 3423 dns_zone_t *p_zone; 3424 dns_db_t *p_db; 3425 dns_dbversion_t *p_version; 3426 dns_dbnode_t *p_node; 3427 dns_rpz_policy_t policy; 3428 isc_result_t result; 3429 3430 CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip"); 3431 3432 rpzs = client->view->rpzs; 3433 st = client->query.rpz_st; 3434 #ifdef USE_DNSRPS 3435 if (st->popt.dnsrps_enabled) { 3436 return (dnsrps_rewrite_ip(client, netaddr, rpz_type, 3437 p_rdatasetp)); 3438 } 3439 #endif /* ifdef USE_DNSRPS */ 3440 3441 ip_name = dns_fixedname_initname(&ip_namef); 3442 3443 p_zone = NULL; 3444 p_db = NULL; 3445 p_node = NULL; 3446 3447 while (zbits != 0) { 3448 rpz_num = dns_rpz_find_ip(rpzs, rpz_type, zbits, netaddr, 3449 ip_name, &prefix); 3450 if (rpz_num == DNS_RPZ_INVALID_NUM) { 3451 break; 3452 } 3453 zbits &= (DNS_RPZ_ZMASK(rpz_num) >> 1); 3454 3455 /* 3456 * Do not try applying policy zones that cannot replace a 3457 * previously found policy zone. 3458 * Stop looking if the next best choice cannot 3459 * replace what we already have. 3460 */ 3461 rpz = rpzs->zones[rpz_num]; 3462 if (st->m.policy != DNS_RPZ_POLICY_MISS) { 3463 if (st->m.rpz->num < rpz->num) { 3464 break; 3465 } 3466 if (st->m.rpz->num == rpz->num && 3467 (st->m.type < rpz_type || st->m.prefix > prefix)) 3468 { 3469 break; 3470 } 3471 } 3472 3473 /* 3474 * Get the policy for a prefix at least as long 3475 * as the prefix of the entry we had before. 3476 */ 3477 p_name = dns_fixedname_initname(&p_namef); 3478 result = rpz_get_p_name(client, p_name, rpz, rpz_type, ip_name); 3479 if (result != ISC_R_SUCCESS) { 3480 continue; 3481 } 3482 result = rpz_find_p(client, ip_name, qtype, p_name, rpz, 3483 rpz_type, &p_zone, &p_db, &p_version, 3484 &p_node, p_rdatasetp, &policy); 3485 switch (result) { 3486 case DNS_R_NXDOMAIN: 3487 /* 3488 * Continue after a policy record that is missing 3489 * contrary to the summary data. The summary 3490 * data can out of date during races with and among 3491 * policy zone updates. 3492 */ 3493 CTRACE(ISC_LOG_ERROR, "rpz_rewrite_ip: mismatched " 3494 "summary data; " 3495 "continuing"); 3496 continue; 3497 case DNS_R_SERVFAIL: 3498 rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp); 3499 st->m.policy = DNS_RPZ_POLICY_ERROR; 3500 return (DNS_R_SERVFAIL); 3501 default: 3502 /* 3503 * Forget this policy if it is not preferable 3504 * to the previously found policy. 3505 * If this policy is not good, then stop looking 3506 * because none of the later policy zones would work. 3507 * 3508 * With more than one applicable policy, prefer 3509 * the earliest configured policy, 3510 * client-IP over QNAME over IP over NSDNAME over NSIP, 3511 * the longest prefix 3512 * the lexically smallest address. 3513 * dns_rpz_find_ip() ensures st->m.rpz->num >= rpz->num. 3514 * We can compare new and current p_name because 3515 * both are of the same type and in the same zone. 3516 * The tests above eliminate other reasons to 3517 * reject this policy. If this policy can't work, 3518 * then neither can later zones. 3519 */ 3520 if (st->m.policy != DNS_RPZ_POLICY_MISS && 3521 rpz->num == st->m.rpz->num && 3522 (st->m.type == rpz_type && st->m.prefix == prefix && 3523 0 > dns_name_rdatacompare(st->p_name, p_name))) 3524 { 3525 break; 3526 } 3527 3528 /* 3529 * Stop checking after saving an enabled hit in this 3530 * policy zone. The radix tree in the policy zone 3531 * ensures that we found the longest match. 3532 */ 3533 if (rpz->policy != DNS_RPZ_POLICY_DISABLED) { 3534 CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip: " 3535 "rpz_save_p"); 3536 rpz_save_p(st, rpz, rpz_type, policy, p_name, 3537 prefix, result, &p_zone, &p_db, 3538 &p_node, p_rdatasetp, p_version); 3539 break; 3540 } 3541 3542 /* 3543 * Log DNS_RPZ_POLICY_DISABLED zones 3544 * and try the next eligible policy zone. 3545 */ 3546 rpz_log_rewrite(client, true, policy, rpz_type, p_zone, 3547 p_name, NULL, rpz_num); 3548 } 3549 } 3550 3551 rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp); 3552 return (ISC_R_SUCCESS); 3553 } 3554 3555 /* 3556 * Check the IP addresses in the A or AAAA rrsets for name against 3557 * all eligible rpz_type (IP or NSIP) response policy rewrite rules. 3558 */ 3559 static isc_result_t 3560 rpz_rewrite_ip_rrset(ns_client_t *client, dns_name_t *name, 3561 dns_rdatatype_t qtype, dns_rpz_type_t rpz_type, 3562 dns_rdatatype_t ip_type, dns_db_t **ip_dbp, 3563 dns_dbversion_t *ip_version, dns_rdataset_t **ip_rdatasetp, 3564 dns_rdataset_t **p_rdatasetp, bool resuming) { 3565 dns_rpz_zbits_t zbits; 3566 isc_netaddr_t netaddr; 3567 struct in_addr ina; 3568 struct in6_addr in6a; 3569 isc_result_t result; 3570 3571 CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip_rrset"); 3572 3573 zbits = rpz_get_zbits(client, ip_type, rpz_type); 3574 if (zbits == 0) { 3575 return (ISC_R_SUCCESS); 3576 } 3577 3578 /* 3579 * Get the A or AAAA rdataset. 3580 */ 3581 result = rpz_rrset_find(client, name, ip_type, rpz_type, ip_dbp, 3582 ip_version, ip_rdatasetp, resuming); 3583 switch (result) { 3584 case ISC_R_SUCCESS: 3585 case DNS_R_GLUE: 3586 case DNS_R_ZONECUT: 3587 break; 3588 case DNS_R_EMPTYNAME: 3589 case DNS_R_EMPTYWILD: 3590 case DNS_R_NXDOMAIN: 3591 case DNS_R_NCACHENXDOMAIN: 3592 case DNS_R_NXRRSET: 3593 case DNS_R_NCACHENXRRSET: 3594 case ISC_R_NOTFOUND: 3595 return (ISC_R_SUCCESS); 3596 case DNS_R_DELEGATION: 3597 case DNS_R_DUPLICATE: 3598 case DNS_R_DROP: 3599 return (result); 3600 case DNS_R_CNAME: 3601 case DNS_R_DNAME: 3602 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, name, rpz_type, 3603 "NS address rewrite rrset", result); 3604 return (ISC_R_SUCCESS); 3605 default: 3606 if (client->query.rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) { 3607 client->query.rpz_st->m.policy = DNS_RPZ_POLICY_ERROR; 3608 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name, 3609 rpz_type, "NS address rewrite rrset", 3610 result); 3611 } 3612 CTRACE(ISC_LOG_ERROR, "rpz_rewrite_ip_rrset: unexpected " 3613 "result"); 3614 return (DNS_R_SERVFAIL); 3615 } 3616 3617 /* 3618 * Check all of the IP addresses in the rdataset. 3619 */ 3620 for (result = dns_rdataset_first(*ip_rdatasetp); 3621 result == ISC_R_SUCCESS; result = dns_rdataset_next(*ip_rdatasetp)) 3622 { 3623 dns_rdata_t rdata = DNS_RDATA_INIT; 3624 dns_rdataset_current(*ip_rdatasetp, &rdata); 3625 switch (rdata.type) { 3626 case dns_rdatatype_a: 3627 INSIST(rdata.length == 4); 3628 memmove(&ina.s_addr, rdata.data, 4); 3629 isc_netaddr_fromin(&netaddr, &ina); 3630 break; 3631 case dns_rdatatype_aaaa: 3632 INSIST(rdata.length == 16); 3633 memmove(in6a.s6_addr, rdata.data, 16); 3634 isc_netaddr_fromin6(&netaddr, &in6a); 3635 break; 3636 default: 3637 continue; 3638 } 3639 3640 result = rpz_rewrite_ip(client, &netaddr, qtype, rpz_type, 3641 zbits, p_rdatasetp); 3642 if (result != ISC_R_SUCCESS) { 3643 return (result); 3644 } 3645 } 3646 3647 return (ISC_R_SUCCESS); 3648 } 3649 3650 /* 3651 * Look for IP addresses in A and AAAA rdatasets 3652 * that trigger all eligible IP or NSIP policy rules. 3653 */ 3654 static isc_result_t 3655 rpz_rewrite_ip_rrsets(ns_client_t *client, dns_name_t *name, 3656 dns_rdatatype_t qtype, dns_rpz_type_t rpz_type, 3657 dns_rdataset_t **ip_rdatasetp, bool resuming) { 3658 dns_rpz_st_t *st; 3659 dns_dbversion_t *ip_version; 3660 dns_db_t *ip_db; 3661 dns_rdataset_t *p_rdataset; 3662 isc_result_t result; 3663 3664 CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ip_rrsets"); 3665 3666 st = client->query.rpz_st; 3667 ip_version = NULL; 3668 ip_db = NULL; 3669 p_rdataset = NULL; 3670 if ((st->state & DNS_RPZ_DONE_IPv4) == 0 && 3671 (qtype == dns_rdatatype_a || qtype == dns_rdatatype_any || 3672 rpz_type == DNS_RPZ_TYPE_NSIP)) 3673 { 3674 /* 3675 * Rewrite based on an IPv4 address that will appear 3676 * in the ANSWER section or if we are checking IP addresses. 3677 */ 3678 result = rpz_rewrite_ip_rrset( 3679 client, name, qtype, rpz_type, dns_rdatatype_a, &ip_db, 3680 ip_version, ip_rdatasetp, &p_rdataset, resuming); 3681 if (result == ISC_R_SUCCESS) { 3682 st->state |= DNS_RPZ_DONE_IPv4; 3683 } 3684 } else { 3685 result = ISC_R_SUCCESS; 3686 } 3687 if (result == ISC_R_SUCCESS && 3688 (qtype == dns_rdatatype_aaaa || qtype == dns_rdatatype_any || 3689 rpz_type == DNS_RPZ_TYPE_NSIP)) 3690 { 3691 /* 3692 * Rewrite based on IPv6 addresses that will appear 3693 * in the ANSWER section or if we are checking IP addresses. 3694 */ 3695 result = rpz_rewrite_ip_rrset(client, name, qtype, rpz_type, 3696 dns_rdatatype_aaaa, &ip_db, 3697 ip_version, ip_rdatasetp, 3698 &p_rdataset, resuming); 3699 } 3700 if (ip_db != NULL) { 3701 dns_db_detach(&ip_db); 3702 } 3703 ns_client_putrdataset(client, &p_rdataset); 3704 return (result); 3705 } 3706 3707 /* 3708 * Try to rewrite a request for a qtype rdataset based on the trigger name 3709 * trig_name and rpz_type (DNS_RPZ_TYPE_QNAME or DNS_RPZ_TYPE_NSDNAME). 3710 * Record the results including the replacement rdataset if any 3711 * in client->query.rpz_st. 3712 * *rdatasetp is a scratch rdataset. 3713 */ 3714 static isc_result_t 3715 rpz_rewrite_name(ns_client_t *client, dns_name_t *trig_name, 3716 dns_rdatatype_t qtype, dns_rpz_type_t rpz_type, 3717 dns_rpz_zbits_t allowed_zbits, bool recursed, 3718 dns_rdataset_t **rdatasetp) { 3719 dns_rpz_zones_t *rpzs; 3720 dns_rpz_zone_t *rpz; 3721 dns_rpz_st_t *st; 3722 dns_fixedname_t p_namef; 3723 dns_name_t *p_name; 3724 dns_rpz_zbits_t zbits; 3725 dns_rpz_num_t rpz_num; 3726 dns_zone_t *p_zone; 3727 dns_db_t *p_db; 3728 dns_dbversion_t *p_version; 3729 dns_dbnode_t *p_node; 3730 dns_rpz_policy_t policy; 3731 isc_result_t result; 3732 3733 #ifndef USE_DNSRPS 3734 UNUSED(recursed); 3735 #endif /* ifndef USE_DNSRPS */ 3736 3737 CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_name"); 3738 3739 rpzs = client->view->rpzs; 3740 st = client->query.rpz_st; 3741 3742 #ifdef USE_DNSRPS 3743 if (st->popt.dnsrps_enabled) { 3744 return (dnsrps_rewrite_name(client, trig_name, recursed, 3745 rpz_type, rdatasetp)); 3746 } 3747 #endif /* ifdef USE_DNSRPS */ 3748 3749 zbits = rpz_get_zbits(client, qtype, rpz_type); 3750 zbits &= allowed_zbits; 3751 if (zbits == 0) { 3752 return (ISC_R_SUCCESS); 3753 } 3754 3755 /* 3756 * Use the summary database to find the bit mask of policy zones 3757 * with policies for this trigger name. We do this even if there 3758 * is only one eligible policy zone so that wildcard triggers 3759 * are matched correctly, and not into their parent. 3760 */ 3761 zbits = dns_rpz_find_name(rpzs, rpz_type, zbits, trig_name); 3762 if (zbits == 0) { 3763 return (ISC_R_SUCCESS); 3764 } 3765 3766 p_name = dns_fixedname_initname(&p_namef); 3767 3768 p_zone = NULL; 3769 p_db = NULL; 3770 p_node = NULL; 3771 3772 /* 3773 * Check the trigger name in every policy zone that the summary data 3774 * says has a hit for the trigger name. 3775 * Most of the time there are no eligible zones and the summary data 3776 * keeps us from getting this far. 3777 * We check the most eligible zone first and so usually check only 3778 * one policy zone. 3779 */ 3780 for (rpz_num = 0; zbits != 0; ++rpz_num, zbits >>= 1) { 3781 if ((zbits & 1) == 0) { 3782 continue; 3783 } 3784 3785 /* 3786 * Do not check policy zones that cannot replace a previously 3787 * found policy. 3788 */ 3789 rpz = rpzs->zones[rpz_num]; 3790 if (st->m.policy != DNS_RPZ_POLICY_MISS) { 3791 if (st->m.rpz->num < rpz->num) { 3792 break; 3793 } 3794 if (st->m.rpz->num == rpz->num && st->m.type < rpz_type) 3795 { 3796 break; 3797 } 3798 } 3799 3800 /* 3801 * Get the next policy zone's record for this trigger name. 3802 */ 3803 result = rpz_get_p_name(client, p_name, rpz, rpz_type, 3804 trig_name); 3805 if (result != ISC_R_SUCCESS) { 3806 continue; 3807 } 3808 result = rpz_find_p(client, trig_name, qtype, p_name, rpz, 3809 rpz_type, &p_zone, &p_db, &p_version, 3810 &p_node, rdatasetp, &policy); 3811 switch (result) { 3812 case DNS_R_NXDOMAIN: 3813 /* 3814 * Continue after a missing policy record 3815 * contrary to the summary data. The summary 3816 * data can out of date during races with and among 3817 * policy zone updates. 3818 */ 3819 CTRACE(ISC_LOG_ERROR, "rpz_rewrite_name: mismatched " 3820 "summary data; " 3821 "continuing"); 3822 continue; 3823 case DNS_R_SERVFAIL: 3824 rpz_clean(&p_zone, &p_db, &p_node, rdatasetp); 3825 st->m.policy = DNS_RPZ_POLICY_ERROR; 3826 return (DNS_R_SERVFAIL); 3827 default: 3828 /* 3829 * With more than one applicable policy, prefer 3830 * the earliest configured policy, 3831 * client-IP over QNAME over IP over NSDNAME over NSIP, 3832 * and the smallest name. 3833 * We known st->m.rpz->num >= rpz->num and either 3834 * st->m.rpz->num > rpz->num or st->m.type >= rpz_type 3835 */ 3836 if (st->m.policy != DNS_RPZ_POLICY_MISS && 3837 rpz->num == st->m.rpz->num && 3838 (st->m.type < rpz_type || 3839 (st->m.type == rpz_type && 3840 0 >= dns_name_compare(p_name, st->p_name)))) 3841 { 3842 continue; 3843 } 3844 3845 if (rpz->policy != DNS_RPZ_POLICY_DISABLED) { 3846 CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_name: " 3847 "rpz_save_p"); 3848 rpz_save_p(st, rpz, rpz_type, policy, p_name, 0, 3849 result, &p_zone, &p_db, &p_node, 3850 rdatasetp, p_version); 3851 /* 3852 * After a hit, higher numbered policy zones 3853 * are irrelevant 3854 */ 3855 rpz_clean(&p_zone, &p_db, &p_node, rdatasetp); 3856 return (ISC_R_SUCCESS); 3857 } 3858 /* 3859 * Log DNS_RPZ_POLICY_DISABLED zones 3860 * and try the next eligible policy zone. 3861 */ 3862 rpz_log_rewrite(client, true, policy, rpz_type, p_zone, 3863 p_name, NULL, rpz_num); 3864 break; 3865 } 3866 } 3867 3868 rpz_clean(&p_zone, &p_db, &p_node, rdatasetp); 3869 return (ISC_R_SUCCESS); 3870 } 3871 3872 static void 3873 rpz_rewrite_ns_skip(ns_client_t *client, dns_name_t *nsname, 3874 isc_result_t result, int level, const char *str) { 3875 dns_rpz_st_t *st; 3876 3877 CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite_ns_skip"); 3878 3879 st = client->query.rpz_st; 3880 3881 if (str != NULL) { 3882 rpz_log_fail_helper(client, level, nsname, DNS_RPZ_TYPE_NSIP, 3883 DNS_RPZ_TYPE_NSDNAME, str, result); 3884 } 3885 if (st->r.ns_rdataset != NULL && 3886 dns_rdataset_isassociated(st->r.ns_rdataset)) { 3887 dns_rdataset_disassociate(st->r.ns_rdataset); 3888 } 3889 3890 st->r.label--; 3891 } 3892 3893 /* 3894 * RPZ query result types 3895 */ 3896 typedef enum { 3897 qresult_type_done = 0, 3898 qresult_type_restart = 1, 3899 qresult_type_recurse = 2 3900 } qresult_type_t; 3901 3902 /* 3903 * Look for response policy zone QNAME, NSIP, and NSDNAME rewriting. 3904 */ 3905 static isc_result_t 3906 rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, isc_result_t qresult, 3907 bool resuming, dns_rdataset_t *ordataset, dns_rdataset_t *osigset) { 3908 dns_rpz_zones_t *rpzs; 3909 dns_rpz_st_t *st; 3910 dns_rdataset_t *rdataset; 3911 dns_fixedname_t nsnamef; 3912 dns_name_t *nsname; 3913 qresult_type_t qresult_type; 3914 dns_rpz_zbits_t zbits; 3915 isc_result_t result = ISC_R_SUCCESS; 3916 dns_rpz_have_t have; 3917 dns_rpz_popt_t popt; 3918 int rpz_ver; 3919 #ifdef USE_DNSRPS 3920 librpz_emsg_t emsg; 3921 #endif /* ifdef USE_DNSRPS */ 3922 3923 CTRACE(ISC_LOG_DEBUG(3), "rpz_rewrite"); 3924 3925 rpzs = client->view->rpzs; 3926 st = client->query.rpz_st; 3927 3928 if (rpzs == NULL || 3929 (st != NULL && (st->state & DNS_RPZ_REWRITTEN) != 0)) { 3930 return (DNS_R_DISALLOWED); 3931 } 3932 3933 RWLOCK(&rpzs->search_lock, isc_rwlocktype_read); 3934 if ((rpzs->p.num_zones == 0 && !rpzs->p.dnsrps_enabled) || 3935 (!RECURSIONOK(client) && rpzs->p.no_rd_ok == 0) || 3936 !rpz_ck_dnssec(client, qresult, ordataset, osigset)) 3937 { 3938 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); 3939 return (DNS_R_DISALLOWED); 3940 } 3941 have = rpzs->have; 3942 popt = rpzs->p; 3943 rpz_ver = rpzs->rpz_ver; 3944 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); 3945 3946 #ifndef USE_DNSRPS 3947 INSIST(!popt.dnsrps_enabled); 3948 #endif /* ifndef USE_DNSRPS */ 3949 3950 if (st == NULL) { 3951 st = isc_mem_get(client->mctx, sizeof(*st)); 3952 st->state = 0; 3953 st->rpsdb = NULL; 3954 } 3955 if (st->state == 0) { 3956 st->state |= DNS_RPZ_ACTIVE; 3957 memset(&st->m, 0, sizeof(st->m)); 3958 st->m.type = DNS_RPZ_TYPE_BAD; 3959 st->m.policy = DNS_RPZ_POLICY_MISS; 3960 st->m.ttl = ~0; 3961 memset(&st->r, 0, sizeof(st->r)); 3962 memset(&st->q, 0, sizeof(st->q)); 3963 st->p_name = dns_fixedname_initname(&st->_p_namef); 3964 st->r_name = dns_fixedname_initname(&st->_r_namef); 3965 st->fname = dns_fixedname_initname(&st->_fnamef); 3966 st->have = have; 3967 st->popt = popt; 3968 st->rpz_ver = rpz_ver; 3969 client->query.rpz_st = st; 3970 #ifdef USE_DNSRPS 3971 if (popt.dnsrps_enabled) { 3972 if (st->rpsdb != NULL) { 3973 dns_db_detach(&st->rpsdb); 3974 } 3975 result = dns_dnsrps_rewrite_init( 3976 &emsg, st, rpzs, client->query.qname, 3977 client->mctx, RECURSIONOK(client)); 3978 if (result != ISC_R_SUCCESS) { 3979 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL, 3980 DNS_RPZ_TYPE_QNAME, emsg.c, 3981 result); 3982 st->m.policy = DNS_RPZ_POLICY_ERROR; 3983 return (ISC_R_SUCCESS); 3984 } 3985 } 3986 #endif /* ifdef USE_DNSRPS */ 3987 } 3988 3989 /* 3990 * There is nothing to rewrite if the main query failed. 3991 */ 3992 switch (qresult) { 3993 case ISC_R_SUCCESS: 3994 case DNS_R_GLUE: 3995 case DNS_R_ZONECUT: 3996 qresult_type = qresult_type_done; 3997 break; 3998 case DNS_R_EMPTYNAME: 3999 case DNS_R_NXRRSET: 4000 case DNS_R_NXDOMAIN: 4001 case DNS_R_EMPTYWILD: 4002 case DNS_R_NCACHENXDOMAIN: 4003 case DNS_R_NCACHENXRRSET: 4004 case DNS_R_COVERINGNSEC: 4005 case DNS_R_CNAME: 4006 case DNS_R_DNAME: 4007 qresult_type = qresult_type_restart; 4008 break; 4009 case DNS_R_DELEGATION: 4010 case ISC_R_NOTFOUND: 4011 /* 4012 * If recursion is on, do only tentative rewriting. 4013 * If recursion is off, this the normal and only time we 4014 * can rewrite. 4015 */ 4016 if (RECURSIONOK(client)) { 4017 qresult_type = qresult_type_recurse; 4018 } else { 4019 qresult_type = qresult_type_restart; 4020 } 4021 break; 4022 case ISC_R_FAILURE: 4023 case ISC_R_TIMEDOUT: 4024 case DNS_R_BROKENCHAIN: 4025 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL3, NULL, 4026 DNS_RPZ_TYPE_QNAME, 4027 "stop on qresult in rpz_rewrite()", qresult); 4028 return (ISC_R_SUCCESS); 4029 default: 4030 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, NULL, 4031 DNS_RPZ_TYPE_QNAME, 4032 "stop on unrecognized qresult in rpz_rewrite()", 4033 qresult); 4034 return (ISC_R_SUCCESS); 4035 } 4036 4037 rdataset = NULL; 4038 4039 if ((st->state & (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) != 4040 (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) 4041 { 4042 isc_netaddr_t netaddr; 4043 dns_rpz_zbits_t allowed; 4044 4045 if (!st->popt.dnsrps_enabled && 4046 qresult_type == qresult_type_recurse) { 4047 /* 4048 * This request needs recursion that has not been done. 4049 * Get bits for the policy zones that do not need 4050 * to wait for the results of recursion. 4051 */ 4052 allowed = st->have.qname_skip_recurse; 4053 if (allowed == 0) { 4054 return (ISC_R_SUCCESS); 4055 } 4056 } else { 4057 allowed = DNS_RPZ_ALL_ZBITS; 4058 } 4059 4060 /* 4061 * Check once for triggers for the client IP address. 4062 */ 4063 if ((st->state & DNS_RPZ_DONE_CLIENT_IP) == 0) { 4064 zbits = rpz_get_zbits(client, dns_rdatatype_none, 4065 DNS_RPZ_TYPE_CLIENT_IP); 4066 zbits &= allowed; 4067 if (zbits != 0) { 4068 isc_netaddr_fromsockaddr(&netaddr, 4069 &client->peeraddr); 4070 result = rpz_rewrite_ip(client, &netaddr, qtype, 4071 DNS_RPZ_TYPE_CLIENT_IP, 4072 zbits, &rdataset); 4073 if (result != ISC_R_SUCCESS) { 4074 goto cleanup; 4075 } 4076 } 4077 } 4078 4079 /* 4080 * Check triggers for the query name if this is the first time 4081 * for the current qname. 4082 * There is a first time for each name in a CNAME chain 4083 */ 4084 if ((st->state & DNS_RPZ_DONE_QNAME) == 0) { 4085 bool norec = (qresult_type != qresult_type_recurse); 4086 result = rpz_rewrite_name(client, client->query.qname, 4087 qtype, DNS_RPZ_TYPE_QNAME, 4088 allowed, norec, &rdataset); 4089 if (result != ISC_R_SUCCESS) { 4090 goto cleanup; 4091 } 4092 4093 /* 4094 * Check IPv4 addresses in A RRs next. 4095 * Reset to the start of the NS names. 4096 */ 4097 st->r.label = dns_name_countlabels(client->query.qname); 4098 st->state &= ~(DNS_RPZ_DONE_QNAME_IP | 4099 DNS_RPZ_DONE_IPv4); 4100 } 4101 4102 /* 4103 * Quit if this was an attempt to find a qname or 4104 * client-IP trigger before recursion. 4105 * We will be back if no pre-recursion triggers hit. 4106 * For example, consider 2 policy zones, both with qname and 4107 * IP address triggers. If the qname misses the 1st zone, 4108 * then we cannot know whether a hit for the qname in the 4109 * 2nd zone matters until after recursing to get the A RRs and 4110 * testing them in the first zone. 4111 * Do not bother saving the work from this attempt, 4112 * because recursion is so slow. 4113 */ 4114 if (qresult_type == qresult_type_recurse) { 4115 goto cleanup; 4116 } 4117 4118 /* 4119 * DNS_RPZ_DONE_QNAME but not DNS_RPZ_DONE_CLIENT_IP 4120 * is reset at the end of dealing with each CNAME. 4121 */ 4122 st->state |= (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME); 4123 } 4124 4125 /* 4126 * Check known IP addresses for the query name if the database lookup 4127 * resulted in some addresses (qresult_type == qresult_type_done) 4128 * and if we have not already checked them. 4129 * Any recursion required for the query has already happened. 4130 * Do not check addresses that will not be in the ANSWER section. 4131 */ 4132 if ((st->state & DNS_RPZ_DONE_QNAME_IP) == 0 && 4133 qresult_type == qresult_type_done && 4134 rpz_get_zbits(client, qtype, DNS_RPZ_TYPE_IP) != 0) 4135 { 4136 result = rpz_rewrite_ip_rrsets(client, client->query.qname, 4137 qtype, DNS_RPZ_TYPE_IP, 4138 &rdataset, resuming); 4139 if (result != ISC_R_SUCCESS) { 4140 goto cleanup; 4141 } 4142 /* 4143 * We are finished checking the IP addresses for the qname. 4144 * Start with IPv4 if we will check NS IP addresses. 4145 */ 4146 st->state |= DNS_RPZ_DONE_QNAME_IP; 4147 st->state &= ~DNS_RPZ_DONE_IPv4; 4148 } 4149 4150 /* 4151 * Stop looking for rules if there are none of the other kinds 4152 * that could override what we already have. 4153 */ 4154 if (rpz_get_zbits(client, dns_rdatatype_any, DNS_RPZ_TYPE_NSDNAME) == 4155 0 && 4156 rpz_get_zbits(client, dns_rdatatype_any, DNS_RPZ_TYPE_NSIP) == 0) 4157 { 4158 result = ISC_R_SUCCESS; 4159 goto cleanup; 4160 } 4161 4162 dns_fixedname_init(&nsnamef); 4163 dns_name_clone(client->query.qname, dns_fixedname_name(&nsnamef)); 4164 while (st->r.label > st->popt.min_ns_labels) { 4165 /* 4166 * Get NS rrset for each domain in the current qname. 4167 */ 4168 if (st->r.label == dns_name_countlabels(client->query.qname)) { 4169 nsname = client->query.qname; 4170 } else { 4171 nsname = dns_fixedname_name(&nsnamef); 4172 dns_name_split(client->query.qname, st->r.label, NULL, 4173 nsname); 4174 } 4175 if (st->r.ns_rdataset == NULL || 4176 !dns_rdataset_isassociated(st->r.ns_rdataset)) { 4177 dns_db_t *db = NULL; 4178 result = rpz_rrset_find(client, nsname, 4179 dns_rdatatype_ns, 4180 DNS_RPZ_TYPE_NSDNAME, &db, NULL, 4181 &st->r.ns_rdataset, resuming); 4182 if (db != NULL) { 4183 dns_db_detach(&db); 4184 } 4185 if (st->m.policy == DNS_RPZ_POLICY_ERROR) { 4186 goto cleanup; 4187 } 4188 switch (result) { 4189 case ISC_R_SUCCESS: 4190 result = dns_rdataset_first(st->r.ns_rdataset); 4191 if (result != ISC_R_SUCCESS) { 4192 goto cleanup; 4193 } 4194 st->state &= ~(DNS_RPZ_DONE_NSDNAME | 4195 DNS_RPZ_DONE_IPv4); 4196 break; 4197 case DNS_R_DELEGATION: 4198 case DNS_R_DUPLICATE: 4199 case DNS_R_DROP: 4200 goto cleanup; 4201 case DNS_R_EMPTYNAME: 4202 case DNS_R_NXRRSET: 4203 case DNS_R_EMPTYWILD: 4204 case DNS_R_NXDOMAIN: 4205 case DNS_R_NCACHENXDOMAIN: 4206 case DNS_R_NCACHENXRRSET: 4207 case ISC_R_NOTFOUND: 4208 case DNS_R_CNAME: 4209 case DNS_R_DNAME: 4210 rpz_rewrite_ns_skip(client, nsname, result, 0, 4211 NULL); 4212 continue; 4213 case ISC_R_TIMEDOUT: 4214 case DNS_R_BROKENCHAIN: 4215 case ISC_R_FAILURE: 4216 rpz_rewrite_ns_skip(client, nsname, result, 4217 DNS_RPZ_DEBUG_LEVEL3, 4218 " NS rpz_rrset_find()"); 4219 continue; 4220 default: 4221 rpz_rewrite_ns_skip(client, nsname, result, 4222 DNS_RPZ_INFO_LEVEL, 4223 " unrecognized NS" 4224 " rpz_rrset_find()"); 4225 continue; 4226 } 4227 } 4228 /* 4229 * Check all NS names. 4230 */ 4231 do { 4232 dns_rdata_ns_t ns; 4233 dns_rdata_t nsrdata = DNS_RDATA_INIT; 4234 4235 dns_rdataset_current(st->r.ns_rdataset, &nsrdata); 4236 result = dns_rdata_tostruct(&nsrdata, &ns, NULL); 4237 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4238 dns_rdata_reset(&nsrdata); 4239 4240 /* 4241 * Do nothing about "NS ." 4242 */ 4243 if (dns_name_equal(&ns.name, dns_rootname)) { 4244 dns_rdata_freestruct(&ns); 4245 result = dns_rdataset_next(st->r.ns_rdataset); 4246 continue; 4247 } 4248 /* 4249 * Check this NS name if we did not handle it 4250 * during a previous recursion. 4251 */ 4252 if ((st->state & DNS_RPZ_DONE_NSDNAME) == 0) { 4253 result = rpz_rewrite_name( 4254 client, &ns.name, qtype, 4255 DNS_RPZ_TYPE_NSDNAME, DNS_RPZ_ALL_ZBITS, 4256 true, &rdataset); 4257 if (result != ISC_R_SUCCESS) { 4258 dns_rdata_freestruct(&ns); 4259 goto cleanup; 4260 } 4261 st->state |= DNS_RPZ_DONE_NSDNAME; 4262 } 4263 /* 4264 * Check all IP addresses for this NS name. 4265 */ 4266 result = rpz_rewrite_ip_rrsets(client, &ns.name, qtype, 4267 DNS_RPZ_TYPE_NSIP, 4268 &rdataset, resuming); 4269 dns_rdata_freestruct(&ns); 4270 if (result != ISC_R_SUCCESS) { 4271 goto cleanup; 4272 } 4273 st->state &= ~(DNS_RPZ_DONE_NSDNAME | 4274 DNS_RPZ_DONE_IPv4); 4275 result = dns_rdataset_next(st->r.ns_rdataset); 4276 } while (result == ISC_R_SUCCESS); 4277 dns_rdataset_disassociate(st->r.ns_rdataset); 4278 st->r.label--; 4279 4280 if (rpz_get_zbits(client, dns_rdatatype_any, 4281 DNS_RPZ_TYPE_NSDNAME) == 0 && 4282 rpz_get_zbits(client, dns_rdatatype_any, 4283 DNS_RPZ_TYPE_NSIP) == 0) 4284 { 4285 break; 4286 } 4287 } 4288 4289 /* 4290 * Use the best hit, if any. 4291 */ 4292 result = ISC_R_SUCCESS; 4293 4294 cleanup: 4295 #ifdef USE_DNSRPS 4296 if (st->popt.dnsrps_enabled && st->m.policy != DNS_RPZ_POLICY_ERROR && 4297 !dnsrps_set_p(&emsg, client, st, qtype, &rdataset, 4298 (qresult_type != qresult_type_recurse))) 4299 { 4300 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, NULL, 4301 DNS_RPZ_TYPE_BAD, emsg.c, DNS_R_SERVFAIL); 4302 st->m.policy = DNS_RPZ_POLICY_ERROR; 4303 } 4304 #endif /* ifdef USE_DNSRPS */ 4305 if (st->m.policy != DNS_RPZ_POLICY_MISS && 4306 st->m.policy != DNS_RPZ_POLICY_ERROR && 4307 st->m.rpz->policy != DNS_RPZ_POLICY_GIVEN) 4308 { 4309 st->m.policy = st->m.rpz->policy; 4310 } 4311 if (st->m.policy == DNS_RPZ_POLICY_MISS || 4312 st->m.policy == DNS_RPZ_POLICY_PASSTHRU || 4313 st->m.policy == DNS_RPZ_POLICY_ERROR) 4314 { 4315 if (st->m.policy == DNS_RPZ_POLICY_PASSTHRU && 4316 result != DNS_R_DELEGATION) { 4317 rpz_log_rewrite(client, false, st->m.policy, st->m.type, 4318 st->m.zone, st->p_name, NULL, 4319 st->m.rpz->num); 4320 } 4321 rpz_match_clear(st); 4322 } 4323 if (st->m.policy == DNS_RPZ_POLICY_ERROR) { 4324 CTRACE(ISC_LOG_ERROR, "SERVFAIL due to RPZ policy"); 4325 st->m.type = DNS_RPZ_TYPE_BAD; 4326 result = DNS_R_SERVFAIL; 4327 } 4328 ns_client_putrdataset(client, &rdataset); 4329 if ((st->state & DNS_RPZ_RECURSING) == 0) { 4330 rpz_clean(NULL, &st->r.db, NULL, &st->r.ns_rdataset); 4331 } 4332 4333 return (result); 4334 } 4335 4336 /* 4337 * See if response policy zone rewriting is allowed by a lack of interest 4338 * by the client in DNSSEC or a lack of signatures. 4339 */ 4340 static bool 4341 rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult, 4342 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { 4343 dns_fixedname_t fixed; 4344 dns_name_t *found; 4345 dns_rdataset_t trdataset; 4346 dns_rdatatype_t type; 4347 isc_result_t result; 4348 4349 CTRACE(ISC_LOG_DEBUG(3), "rpz_ck_dnssec"); 4350 4351 if (client->view->rpzs->p.break_dnssec || !WANTDNSSEC(client)) { 4352 return (true); 4353 } 4354 4355 /* 4356 * We do not know if there are signatures if we have not recursed 4357 * for them. 4358 */ 4359 if (qresult == DNS_R_DELEGATION || qresult == ISC_R_NOTFOUND) { 4360 return (false); 4361 } 4362 4363 if (sigrdataset == NULL) { 4364 return (true); 4365 } 4366 if (dns_rdataset_isassociated(sigrdataset)) { 4367 return (false); 4368 } 4369 4370 /* 4371 * We are happy to rewrite nothing. 4372 */ 4373 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) { 4374 return (true); 4375 } 4376 /* 4377 * Do not rewrite if there is any sign of signatures. 4378 */ 4379 if (rdataset->type == dns_rdatatype_nsec || 4380 rdataset->type == dns_rdatatype_nsec3 || 4381 rdataset->type == dns_rdatatype_rrsig) 4382 { 4383 return (false); 4384 } 4385 4386 /* 4387 * Look for a signature in a negative cache rdataset. 4388 */ 4389 if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) == 0) { 4390 return (true); 4391 } 4392 found = dns_fixedname_initname(&fixed); 4393 dns_rdataset_init(&trdataset); 4394 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 4395 result = dns_rdataset_next(rdataset)) 4396 { 4397 dns_ncache_current(rdataset, found, &trdataset); 4398 type = trdataset.type; 4399 dns_rdataset_disassociate(&trdataset); 4400 if (type == dns_rdatatype_nsec || type == dns_rdatatype_nsec3 || 4401 type == dns_rdatatype_rrsig) 4402 { 4403 return (false); 4404 } 4405 } 4406 return (true); 4407 } 4408 4409 /* 4410 * Extract a network address from the RDATA of an A or AAAA 4411 * record. 4412 * 4413 * Returns: 4414 * ISC_R_SUCCESS 4415 * ISC_R_NOTIMPLEMENTED The rdata is not a known address type. 4416 */ 4417 static isc_result_t 4418 rdata_tonetaddr(const dns_rdata_t *rdata, isc_netaddr_t *netaddr) { 4419 struct in_addr ina; 4420 struct in6_addr in6a; 4421 4422 switch (rdata->type) { 4423 case dns_rdatatype_a: 4424 INSIST(rdata->length == 4); 4425 memmove(&ina.s_addr, rdata->data, 4); 4426 isc_netaddr_fromin(netaddr, &ina); 4427 return (ISC_R_SUCCESS); 4428 case dns_rdatatype_aaaa: 4429 INSIST(rdata->length == 16); 4430 memmove(in6a.s6_addr, rdata->data, 16); 4431 isc_netaddr_fromin6(netaddr, &in6a); 4432 return (ISC_R_SUCCESS); 4433 default: 4434 return (ISC_R_NOTIMPLEMENTED); 4435 } 4436 } 4437 4438 static unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 }; 4439 static unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 }; 4440 static unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 }; 4441 4442 static unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA"; 4443 4444 static unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA"; 4445 static unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA"; 4446 static unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA"; 4447 static unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA"; 4448 static unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA"; 4449 static unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA"; 4450 static unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA"; 4451 static unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA"; 4452 static unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA"; 4453 static unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA"; 4454 static unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA"; 4455 static unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA"; 4456 static unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA"; 4457 static unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA"; 4458 static unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA"; 4459 static unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA"; 4460 4461 static unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA"; 4462 4463 static dns_name_t rfc1918names[] = { 4464 DNS_NAME_INITABSOLUTE(inaddr10, inaddr10_offsets), 4465 DNS_NAME_INITABSOLUTE(inaddr16172, inaddr172_offsets), 4466 DNS_NAME_INITABSOLUTE(inaddr17172, inaddr172_offsets), 4467 DNS_NAME_INITABSOLUTE(inaddr18172, inaddr172_offsets), 4468 DNS_NAME_INITABSOLUTE(inaddr19172, inaddr172_offsets), 4469 DNS_NAME_INITABSOLUTE(inaddr20172, inaddr172_offsets), 4470 DNS_NAME_INITABSOLUTE(inaddr21172, inaddr172_offsets), 4471 DNS_NAME_INITABSOLUTE(inaddr22172, inaddr172_offsets), 4472 DNS_NAME_INITABSOLUTE(inaddr23172, inaddr172_offsets), 4473 DNS_NAME_INITABSOLUTE(inaddr24172, inaddr172_offsets), 4474 DNS_NAME_INITABSOLUTE(inaddr25172, inaddr172_offsets), 4475 DNS_NAME_INITABSOLUTE(inaddr26172, inaddr172_offsets), 4476 DNS_NAME_INITABSOLUTE(inaddr27172, inaddr172_offsets), 4477 DNS_NAME_INITABSOLUTE(inaddr28172, inaddr172_offsets), 4478 DNS_NAME_INITABSOLUTE(inaddr29172, inaddr172_offsets), 4479 DNS_NAME_INITABSOLUTE(inaddr30172, inaddr172_offsets), 4480 DNS_NAME_INITABSOLUTE(inaddr31172, inaddr172_offsets), 4481 DNS_NAME_INITABSOLUTE(inaddr168192, inaddr192_offsets) 4482 }; 4483 4484 static unsigned char prisoner_data[] = "\010prisoner\004iana\003org"; 4485 static unsigned char hostmaster_data[] = "\012hostmaster\014root-" 4486 "servers\003org"; 4487 4488 static unsigned char prisoner_offsets[] = { 0, 9, 14, 18 }; 4489 static unsigned char hostmaster_offsets[] = { 0, 11, 24, 28 }; 4490 4491 static dns_name_t const prisoner = DNS_NAME_INITABSOLUTE(prisoner_data, 4492 prisoner_offsets); 4493 static dns_name_t const hostmaster = DNS_NAME_INITABSOLUTE(hostmaster_data, 4494 hostmaster_offsets); 4495 4496 static void 4497 warn_rfc1918(ns_client_t *client, dns_name_t *fname, dns_rdataset_t *rdataset) { 4498 unsigned int i; 4499 dns_rdata_t rdata = DNS_RDATA_INIT; 4500 dns_rdata_soa_t soa; 4501 dns_rdataset_t found; 4502 isc_result_t result; 4503 4504 for (i = 0; i < (sizeof(rfc1918names) / sizeof(*rfc1918names)); i++) { 4505 if (dns_name_issubdomain(fname, &rfc1918names[i])) { 4506 dns_rdataset_init(&found); 4507 result = dns_ncache_getrdataset( 4508 rdataset, &rfc1918names[i], dns_rdatatype_soa, 4509 &found); 4510 if (result != ISC_R_SUCCESS) { 4511 return; 4512 } 4513 4514 result = dns_rdataset_first(&found); 4515 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4516 dns_rdataset_current(&found, &rdata); 4517 result = dns_rdata_tostruct(&rdata, &soa, NULL); 4518 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4519 if (dns_name_equal(&soa.origin, &prisoner) && 4520 dns_name_equal(&soa.contact, &hostmaster)) 4521 { 4522 char buf[DNS_NAME_FORMATSIZE]; 4523 dns_name_format(fname, buf, sizeof(buf)); 4524 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 4525 NS_LOGMODULE_QUERY, 4526 ISC_LOG_WARNING, 4527 "RFC 1918 response from " 4528 "Internet for %s", 4529 buf); 4530 } 4531 dns_rdataset_disassociate(&found); 4532 return; 4533 } 4534 } 4535 } 4536 4537 static void 4538 query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, 4539 dns_dbversion_t *version, ns_client_t *client, 4540 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, 4541 dns_name_t *fname, bool exact, dns_name_t *found) { 4542 unsigned char salt[256]; 4543 size_t salt_length; 4544 uint16_t iterations; 4545 isc_result_t result; 4546 unsigned int dboptions; 4547 dns_fixedname_t fixed; 4548 dns_hash_t hash; 4549 dns_name_t name; 4550 unsigned int skip = 0, labels; 4551 dns_rdata_nsec3_t nsec3; 4552 dns_rdata_t rdata = DNS_RDATA_INIT; 4553 bool optout; 4554 dns_clientinfomethods_t cm; 4555 dns_clientinfo_t ci; 4556 4557 salt_length = sizeof(salt); 4558 result = dns_db_getnsec3parameters(db, version, &hash, NULL, 4559 &iterations, salt, &salt_length); 4560 if (result != ISC_R_SUCCESS) { 4561 return; 4562 } 4563 4564 dns_name_init(&name, NULL); 4565 dns_name_clone(qname, &name); 4566 labels = dns_name_countlabels(&name); 4567 dns_clientinfomethods_init(&cm, ns_client_sourceip); 4568 dns_clientinfo_init(&ci, client, NULL); 4569 4570 /* 4571 * Map unknown algorithm to known value. 4572 */ 4573 if (hash == DNS_NSEC3_UNKNOWNALG) { 4574 hash = 1; 4575 } 4576 4577 again: 4578 dns_fixedname_init(&fixed); 4579 result = dns_nsec3_hashname(&fixed, NULL, NULL, &name, 4580 dns_db_origin(db), hash, iterations, salt, 4581 salt_length); 4582 if (result != ISC_R_SUCCESS) { 4583 return; 4584 } 4585 4586 dboptions = client->query.dboptions | DNS_DBFIND_FORCENSEC3; 4587 result = dns_db_findext(db, dns_fixedname_name(&fixed), version, 4588 dns_rdatatype_nsec3, dboptions, client->now, 4589 NULL, fname, &cm, &ci, rdataset, sigrdataset); 4590 4591 if (result == DNS_R_NXDOMAIN) { 4592 if (!dns_rdataset_isassociated(rdataset)) { 4593 return; 4594 } 4595 result = dns_rdataset_first(rdataset); 4596 INSIST(result == ISC_R_SUCCESS); 4597 dns_rdataset_current(rdataset, &rdata); 4598 result = dns_rdata_tostruct(&rdata, &nsec3, NULL); 4599 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4600 dns_rdata_reset(&rdata); 4601 optout = ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0); 4602 if (found != NULL && optout && 4603 dns_name_issubdomain(&name, dns_db_origin(db))) { 4604 dns_rdataset_disassociate(rdataset); 4605 if (dns_rdataset_isassociated(sigrdataset)) { 4606 dns_rdataset_disassociate(sigrdataset); 4607 } 4608 skip++; 4609 dns_name_getlabelsequence(qname, skip, labels - skip, 4610 &name); 4611 ns_client_log(client, DNS_LOGCATEGORY_DNSSEC, 4612 NS_LOGMODULE_QUERY, ISC_LOG_DEBUG(3), 4613 "looking for closest provable encloser"); 4614 goto again; 4615 } 4616 if (exact) { 4617 ns_client_log(client, DNS_LOGCATEGORY_DNSSEC, 4618 NS_LOGMODULE_QUERY, ISC_LOG_WARNING, 4619 "expected a exact match NSEC3, got " 4620 "a covering record"); 4621 } 4622 } else if (result != ISC_R_SUCCESS) { 4623 return; 4624 } else if (!exact) { 4625 ns_client_log(client, DNS_LOGCATEGORY_DNSSEC, 4626 NS_LOGMODULE_QUERY, ISC_LOG_WARNING, 4627 "expected covering NSEC3, got an exact match"); 4628 } 4629 if (found == qname) { 4630 if (skip != 0U) { 4631 dns_name_getlabelsequence(qname, skip, labels - skip, 4632 found); 4633 } 4634 } else if (found != NULL) { 4635 dns_name_copynf(&name, found); 4636 } 4637 return; 4638 } 4639 4640 static uint32_t 4641 dns64_ttl(dns_db_t *db, dns_dbversion_t *version) { 4642 dns_dbnode_t *node = NULL; 4643 dns_rdata_soa_t soa; 4644 dns_rdata_t rdata = DNS_RDATA_INIT; 4645 dns_rdataset_t rdataset; 4646 isc_result_t result; 4647 uint32_t ttl = UINT32_MAX; 4648 4649 dns_rdataset_init(&rdataset); 4650 4651 result = dns_db_getoriginnode(db, &node); 4652 if (result != ISC_R_SUCCESS) { 4653 goto cleanup; 4654 } 4655 4656 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, 0, 0, 4657 &rdataset, NULL); 4658 if (result != ISC_R_SUCCESS) { 4659 goto cleanup; 4660 } 4661 result = dns_rdataset_first(&rdataset); 4662 if (result != ISC_R_SUCCESS) { 4663 goto cleanup; 4664 } 4665 4666 dns_rdataset_current(&rdataset, &rdata); 4667 result = dns_rdata_tostruct(&rdata, &soa, NULL); 4668 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4669 ttl = ISC_MIN(rdataset.ttl, soa.minimum); 4670 4671 cleanup: 4672 if (dns_rdataset_isassociated(&rdataset)) { 4673 dns_rdataset_disassociate(&rdataset); 4674 } 4675 if (node != NULL) { 4676 dns_db_detachnode(db, &node); 4677 } 4678 return (ttl); 4679 } 4680 4681 static bool 4682 dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset, 4683 dns_rdataset_t *sigrdataset) { 4684 isc_netaddr_t netaddr; 4685 dns_aclenv_t *env = 4686 ns_interfacemgr_getaclenv(client->manager->interface->mgr); 4687 dns_dns64_t *dns64 = ISC_LIST_HEAD(client->view->dns64); 4688 unsigned int flags = 0; 4689 unsigned int i, count; 4690 bool *aaaaok; 4691 4692 INSIST(client->query.dns64_aaaaok == NULL); 4693 INSIST(client->query.dns64_aaaaoklen == 0); 4694 INSIST(client->query.dns64_aaaa == NULL); 4695 INSIST(client->query.dns64_sigaaaa == NULL); 4696 4697 if (dns64 == NULL) { 4698 return (true); 4699 } 4700 4701 if (RECURSIONOK(client)) { 4702 flags |= DNS_DNS64_RECURSIVE; 4703 } 4704 4705 if (WANTDNSSEC(client) && sigrdataset != NULL && 4706 dns_rdataset_isassociated(sigrdataset)) 4707 { 4708 flags |= DNS_DNS64_DNSSEC; 4709 } 4710 4711 count = dns_rdataset_count(rdataset); 4712 aaaaok = isc_mem_get(client->mctx, sizeof(bool) * count); 4713 4714 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); 4715 if (dns_dns64_aaaaok(dns64, &netaddr, client->signer, env, flags, 4716 rdataset, aaaaok, count)) 4717 { 4718 for (i = 0; i < count; i++) { 4719 if (aaaaok != NULL && !aaaaok[i]) { 4720 SAVE(client->query.dns64_aaaaok, aaaaok); 4721 client->query.dns64_aaaaoklen = count; 4722 break; 4723 } 4724 } 4725 if (aaaaok != NULL) { 4726 isc_mem_put(client->mctx, aaaaok, sizeof(bool) * count); 4727 } 4728 return (true); 4729 } 4730 if (aaaaok != NULL) { 4731 isc_mem_put(client->mctx, aaaaok, sizeof(bool) * count); 4732 } 4733 return (false); 4734 } 4735 4736 /* 4737 * Look for the name and type in the redirection zone. If found update 4738 * the arguments as appropriate. Return true if a update was 4739 * performed. 4740 * 4741 * Only perform the update if the client is in the allow query acl and 4742 * returning the update would not cause a DNSSEC validation failure. 4743 */ 4744 static isc_result_t 4745 redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, 4746 dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp, 4747 dns_rdatatype_t qtype) { 4748 dns_db_t *db = NULL; 4749 dns_dbnode_t *node = NULL; 4750 dns_fixedname_t fixed; 4751 dns_name_t *found; 4752 dns_rdataset_t trdataset; 4753 isc_result_t result; 4754 dns_rdatatype_t type; 4755 dns_clientinfomethods_t cm; 4756 dns_clientinfo_t ci; 4757 ns_dbversion_t *dbversion; 4758 4759 CTRACE(ISC_LOG_DEBUG(3), "redirect"); 4760 4761 if (client->view->redirect == NULL) { 4762 return (ISC_R_NOTFOUND); 4763 } 4764 4765 found = dns_fixedname_initname(&fixed); 4766 dns_rdataset_init(&trdataset); 4767 4768 dns_clientinfomethods_init(&cm, ns_client_sourceip); 4769 dns_clientinfo_init(&ci, client, NULL); 4770 4771 if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp)) 4772 { 4773 return (ISC_R_NOTFOUND); 4774 } 4775 4776 if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) { 4777 if (rdataset->trust == dns_trust_secure) { 4778 return (ISC_R_NOTFOUND); 4779 } 4780 if (rdataset->trust == dns_trust_ultimate && 4781 (rdataset->type == dns_rdatatype_nsec || 4782 rdataset->type == dns_rdatatype_nsec3)) 4783 { 4784 return (ISC_R_NOTFOUND); 4785 } 4786 if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) { 4787 for (result = dns_rdataset_first(rdataset); 4788 result == ISC_R_SUCCESS; 4789 result = dns_rdataset_next(rdataset)) 4790 { 4791 dns_ncache_current(rdataset, found, &trdataset); 4792 type = trdataset.type; 4793 dns_rdataset_disassociate(&trdataset); 4794 if (type == dns_rdatatype_nsec || 4795 type == dns_rdatatype_nsec3 || 4796 type == dns_rdatatype_rrsig) 4797 { 4798 return (ISC_R_NOTFOUND); 4799 } 4800 } 4801 } 4802 } 4803 4804 result = ns_client_checkaclsilent( 4805 client, NULL, dns_zone_getqueryacl(client->view->redirect), 4806 true); 4807 if (result != ISC_R_SUCCESS) { 4808 return (ISC_R_NOTFOUND); 4809 } 4810 4811 result = dns_zone_getdb(client->view->redirect, &db); 4812 if (result != ISC_R_SUCCESS) { 4813 return (ISC_R_NOTFOUND); 4814 } 4815 4816 dbversion = ns_client_findversion(client, db); 4817 if (dbversion == NULL) { 4818 dns_db_detach(&db); 4819 return (ISC_R_NOTFOUND); 4820 } 4821 4822 /* 4823 * Lookup the requested data in the redirect zone. 4824 */ 4825 result = dns_db_findext(db, client->query.qname, dbversion->version, 4826 qtype, DNS_DBFIND_NOZONECUT, client->now, &node, 4827 found, &cm, &ci, &trdataset, NULL); 4828 if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) { 4829 if (dns_rdataset_isassociated(rdataset)) { 4830 dns_rdataset_disassociate(rdataset); 4831 } 4832 if (dns_rdataset_isassociated(&trdataset)) { 4833 dns_rdataset_disassociate(&trdataset); 4834 } 4835 goto nxrrset; 4836 } else if (result != ISC_R_SUCCESS) { 4837 if (dns_rdataset_isassociated(&trdataset)) { 4838 dns_rdataset_disassociate(&trdataset); 4839 } 4840 if (node != NULL) { 4841 dns_db_detachnode(db, &node); 4842 } 4843 dns_db_detach(&db); 4844 return (ISC_R_NOTFOUND); 4845 } 4846 4847 CTRACE(ISC_LOG_DEBUG(3), "redirect: found data: done"); 4848 dns_name_copynf(found, name); 4849 if (dns_rdataset_isassociated(rdataset)) { 4850 dns_rdataset_disassociate(rdataset); 4851 } 4852 if (dns_rdataset_isassociated(&trdataset)) { 4853 dns_rdataset_clone(&trdataset, rdataset); 4854 dns_rdataset_disassociate(&trdataset); 4855 } 4856 nxrrset: 4857 if (*nodep != NULL) { 4858 dns_db_detachnode(*dbp, nodep); 4859 } 4860 dns_db_detach(dbp); 4861 dns_db_attachnode(db, node, nodep); 4862 dns_db_attach(db, dbp); 4863 dns_db_detachnode(db, &node); 4864 dns_db_detach(&db); 4865 *versionp = dbversion->version; 4866 4867 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | 4868 NS_QUERYATTR_NOADDITIONAL); 4869 4870 return (result); 4871 } 4872 4873 static isc_result_t 4874 redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, 4875 dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp, 4876 dns_rdatatype_t qtype, bool *is_zonep) { 4877 dns_db_t *db = NULL; 4878 dns_dbnode_t *node = NULL; 4879 dns_fixedname_t fixed; 4880 dns_fixedname_t fixedredirect; 4881 dns_name_t *found, *redirectname; 4882 dns_rdataset_t trdataset; 4883 isc_result_t result; 4884 dns_rdatatype_t type; 4885 dns_clientinfomethods_t cm; 4886 dns_clientinfo_t ci; 4887 dns_dbversion_t *version = NULL; 4888 dns_zone_t *zone = NULL; 4889 bool is_zone; 4890 unsigned int labels; 4891 unsigned int options; 4892 4893 CTRACE(ISC_LOG_DEBUG(3), "redirect2"); 4894 4895 if (client->view->redirectzone == NULL) { 4896 return (ISC_R_NOTFOUND); 4897 } 4898 4899 if (dns_name_issubdomain(name, client->view->redirectzone)) { 4900 return (ISC_R_NOTFOUND); 4901 } 4902 4903 found = dns_fixedname_initname(&fixed); 4904 dns_rdataset_init(&trdataset); 4905 4906 dns_clientinfomethods_init(&cm, ns_client_sourceip); 4907 dns_clientinfo_init(&ci, client, NULL); 4908 4909 if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp)) 4910 { 4911 return (ISC_R_NOTFOUND); 4912 } 4913 4914 if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) { 4915 if (rdataset->trust == dns_trust_secure) { 4916 return (ISC_R_NOTFOUND); 4917 } 4918 if (rdataset->trust == dns_trust_ultimate && 4919 (rdataset->type == dns_rdatatype_nsec || 4920 rdataset->type == dns_rdatatype_nsec3)) 4921 { 4922 return (ISC_R_NOTFOUND); 4923 } 4924 if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) { 4925 for (result = dns_rdataset_first(rdataset); 4926 result == ISC_R_SUCCESS; 4927 result = dns_rdataset_next(rdataset)) 4928 { 4929 dns_ncache_current(rdataset, found, &trdataset); 4930 type = trdataset.type; 4931 dns_rdataset_disassociate(&trdataset); 4932 if (type == dns_rdatatype_nsec || 4933 type == dns_rdatatype_nsec3 || 4934 type == dns_rdatatype_rrsig) 4935 { 4936 return (ISC_R_NOTFOUND); 4937 } 4938 } 4939 } 4940 } 4941 4942 redirectname = dns_fixedname_initname(&fixedredirect); 4943 labels = dns_name_countlabels(client->query.qname); 4944 if (labels > 1U) { 4945 dns_name_t prefix; 4946 4947 dns_name_init(&prefix, NULL); 4948 dns_name_getlabelsequence(client->query.qname, 0, labels - 1, 4949 &prefix); 4950 result = dns_name_concatenate(&prefix, 4951 client->view->redirectzone, 4952 redirectname, NULL); 4953 if (result != ISC_R_SUCCESS) { 4954 return (ISC_R_NOTFOUND); 4955 } 4956 } else { 4957 dns_name_copynf(redirectname, client->view->redirectzone); 4958 } 4959 4960 options = 0; 4961 result = query_getdb(client, redirectname, qtype, options, &zone, &db, 4962 &version, &is_zone); 4963 if (result != ISC_R_SUCCESS) { 4964 return (ISC_R_NOTFOUND); 4965 } 4966 if (zone != NULL) { 4967 dns_zone_detach(&zone); 4968 } 4969 4970 /* 4971 * Lookup the requested data in the redirect zone. 4972 */ 4973 result = dns_db_findext(db, redirectname, version, qtype, 0, 4974 client->now, &node, found, &cm, &ci, &trdataset, 4975 NULL); 4976 if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) { 4977 if (dns_rdataset_isassociated(rdataset)) { 4978 dns_rdataset_disassociate(rdataset); 4979 } 4980 if (dns_rdataset_isassociated(&trdataset)) { 4981 dns_rdataset_disassociate(&trdataset); 4982 } 4983 goto nxrrset; 4984 } else if (result == ISC_R_NOTFOUND || result == DNS_R_DELEGATION) { 4985 /* 4986 * Cleanup. 4987 */ 4988 if (dns_rdataset_isassociated(&trdataset)) { 4989 dns_rdataset_disassociate(&trdataset); 4990 } 4991 if (node != NULL) { 4992 dns_db_detachnode(db, &node); 4993 } 4994 dns_db_detach(&db); 4995 /* 4996 * Don't loop forever if the lookup failed last time. 4997 */ 4998 if (!REDIRECT(client)) { 4999 result = ns_query_recurse(client, qtype, redirectname, 5000 NULL, NULL, true); 5001 if (result == ISC_R_SUCCESS) { 5002 client->query.attributes |= 5003 NS_QUERYATTR_RECURSING; 5004 client->query.attributes |= 5005 NS_QUERYATTR_REDIRECT; 5006 return (DNS_R_CONTINUE); 5007 } 5008 } 5009 return (ISC_R_NOTFOUND); 5010 } else if (result != ISC_R_SUCCESS) { 5011 if (dns_rdataset_isassociated(&trdataset)) { 5012 dns_rdataset_disassociate(&trdataset); 5013 } 5014 if (node != NULL) { 5015 dns_db_detachnode(db, &node); 5016 } 5017 dns_db_detach(&db); 5018 return (ISC_R_NOTFOUND); 5019 } 5020 5021 CTRACE(ISC_LOG_DEBUG(3), "redirect2: found data: done"); 5022 /* 5023 * Adjust the found name to not include the redirectzone suffix. 5024 */ 5025 dns_name_split(found, dns_name_countlabels(client->view->redirectzone), 5026 found, NULL); 5027 /* 5028 * Make the name absolute. 5029 */ 5030 result = dns_name_concatenate(found, dns_rootname, found, NULL); 5031 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5032 5033 dns_name_copynf(found, name); 5034 if (dns_rdataset_isassociated(rdataset)) { 5035 dns_rdataset_disassociate(rdataset); 5036 } 5037 if (dns_rdataset_isassociated(&trdataset)) { 5038 dns_rdataset_clone(&trdataset, rdataset); 5039 dns_rdataset_disassociate(&trdataset); 5040 } 5041 nxrrset: 5042 if (*nodep != NULL) { 5043 dns_db_detachnode(*dbp, nodep); 5044 } 5045 dns_db_detach(dbp); 5046 dns_db_attachnode(db, node, nodep); 5047 dns_db_attach(db, dbp); 5048 dns_db_detachnode(db, &node); 5049 dns_db_detach(&db); 5050 *is_zonep = is_zone; 5051 *versionp = version; 5052 5053 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | 5054 NS_QUERYATTR_NOADDITIONAL); 5055 5056 return (result); 5057 } 5058 5059 /*% 5060 * Initialize query context 'qctx'. Run by query_setup() when 5061 * first handling a client query, and by query_resume() when 5062 * returning from recursion. 5063 * 5064 * Whenever this function is called, qctx_destroy() must be called 5065 * when leaving the scope or freeing the qctx. 5066 */ 5067 static void 5068 qctx_init(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype, 5069 query_ctx_t *qctx) { 5070 REQUIRE(qctx != NULL); 5071 REQUIRE(client != NULL); 5072 5073 memset(qctx, 0, sizeof(*qctx)); 5074 5075 /* Set this first so CCTRACE will work */ 5076 qctx->client = client; 5077 5078 dns_view_attach(client->view, &qctx->view); 5079 5080 CCTRACE(ISC_LOG_DEBUG(3), "qctx_init"); 5081 5082 qctx->event = event; 5083 qctx->qtype = qctx->type = qtype; 5084 qctx->result = ISC_R_SUCCESS; 5085 qctx->findcoveringnsec = qctx->view->synthfromdnssec; 5086 5087 CALL_HOOK_NORETURN(NS_QUERY_QCTX_INITIALIZED, qctx); 5088 } 5089 5090 /*% 5091 * Clean up and disassociate the rdataset and node pointers in qctx. 5092 */ 5093 static void 5094 qctx_clean(query_ctx_t *qctx) { 5095 if (qctx->rdataset != NULL && dns_rdataset_isassociated(qctx->rdataset)) 5096 { 5097 dns_rdataset_disassociate(qctx->rdataset); 5098 } 5099 if (qctx->sigrdataset != NULL && 5100 dns_rdataset_isassociated(qctx->sigrdataset)) { 5101 dns_rdataset_disassociate(qctx->sigrdataset); 5102 } 5103 if (qctx->db != NULL && qctx->node != NULL) { 5104 dns_db_detachnode(qctx->db, &qctx->node); 5105 } 5106 } 5107 5108 /*% 5109 * Free any allocated memory associated with qctx. 5110 */ 5111 static void 5112 qctx_freedata(query_ctx_t *qctx) { 5113 if (qctx->rdataset != NULL) { 5114 ns_client_putrdataset(qctx->client, &qctx->rdataset); 5115 } 5116 5117 if (qctx->sigrdataset != NULL) { 5118 ns_client_putrdataset(qctx->client, &qctx->sigrdataset); 5119 } 5120 5121 if (qctx->fname != NULL) { 5122 ns_client_releasename(qctx->client, &qctx->fname); 5123 } 5124 5125 if (qctx->db != NULL) { 5126 INSIST(qctx->node == NULL); 5127 dns_db_detach(&qctx->db); 5128 } 5129 5130 if (qctx->zone != NULL) { 5131 dns_zone_detach(&qctx->zone); 5132 } 5133 5134 if (qctx->zdb != NULL) { 5135 ns_client_putrdataset(qctx->client, &qctx->zsigrdataset); 5136 ns_client_putrdataset(qctx->client, &qctx->zrdataset); 5137 ns_client_releasename(qctx->client, &qctx->zfname); 5138 dns_db_detachnode(qctx->zdb, &qctx->znode); 5139 dns_db_detach(&qctx->zdb); 5140 } 5141 5142 if (qctx->event != NULL) { 5143 free_devent(qctx->client, ISC_EVENT_PTR(&qctx->event), 5144 &qctx->event); 5145 } 5146 } 5147 5148 static void 5149 qctx_destroy(query_ctx_t *qctx) { 5150 CALL_HOOK_NORETURN(NS_QUERY_QCTX_DESTROYED, qctx); 5151 5152 dns_view_detach(&qctx->view); 5153 } 5154 5155 /*% 5156 * Log detailed information about the query immediately after 5157 * the client request or a return from recursion. 5158 */ 5159 static void 5160 query_trace(query_ctx_t *qctx) { 5161 #ifdef WANT_QUERYTRACE 5162 char mbuf[2 * DNS_NAME_FORMATSIZE]; 5163 char qbuf[DNS_NAME_FORMATSIZE]; 5164 5165 if (qctx->client->query.origqname != NULL) { 5166 dns_name_format(qctx->client->query.origqname, qbuf, 5167 sizeof(qbuf)); 5168 } else { 5169 snprintf(qbuf, sizeof(qbuf), "<unset>"); 5170 } 5171 5172 snprintf(mbuf, sizeof(mbuf) - 1, 5173 "client attr:0x%x, query attr:0x%X, restarts:%u, " 5174 "origqname:%s, timer:%d, authdb:%d, referral:%d", 5175 qctx->client->attributes, qctx->client->query.attributes, 5176 qctx->client->query.restarts, qbuf, 5177 (int)qctx->client->query.timerset, 5178 (int)qctx->client->query.authdbset, 5179 (int)qctx->client->query.isreferral); 5180 CCTRACE(ISC_LOG_DEBUG(3), mbuf); 5181 #else /* ifdef WANT_QUERYTRACE */ 5182 UNUSED(qctx); 5183 #endif /* ifdef WANT_QUERYTRACE */ 5184 } 5185 5186 /* 5187 * Set up query processing for the current query of 'client'. 5188 * Calls qctx_init() to initialize a query context, checks 5189 * the SERVFAIL cache, then hands off processing to ns__query_start(). 5190 * 5191 * This is called only from ns_query_start(), to begin a query 5192 * for the first time. Restarting an existing query (for 5193 * instance, to handle CNAME lookups), is done by calling 5194 * ns__query_start() again with the same query context. Resuming from 5195 * recursion is handled by query_resume(). 5196 */ 5197 static isc_result_t 5198 query_setup(ns_client_t *client, dns_rdatatype_t qtype) { 5199 isc_result_t result; 5200 query_ctx_t qctx; 5201 5202 qctx_init(client, NULL, qtype, &qctx); 5203 query_trace(&qctx); 5204 5205 CALL_HOOK(NS_QUERY_SETUP, &qctx); 5206 5207 /* 5208 * If it's a SIG query, we'll iterate the node. 5209 */ 5210 if (qctx.qtype == dns_rdatatype_rrsig || 5211 qctx.qtype == dns_rdatatype_sig) { 5212 qctx.type = dns_rdatatype_any; 5213 } 5214 5215 /* 5216 * Check SERVFAIL cache 5217 */ 5218 result = ns__query_sfcache(&qctx); 5219 if (result != ISC_R_COMPLETE) { 5220 qctx_destroy(&qctx); 5221 return (result); 5222 } 5223 5224 result = ns__query_start(&qctx); 5225 5226 cleanup: 5227 qctx_destroy(&qctx); 5228 return (result); 5229 } 5230 5231 static bool 5232 get_root_key_sentinel_id(query_ctx_t *qctx, const char *ndata) { 5233 unsigned int v = 0; 5234 int i; 5235 5236 for (i = 0; i < 5; i++) { 5237 if (ndata[i] < '0' || ndata[i] > '9') { 5238 return (false); 5239 } 5240 v *= 10; 5241 v += ndata[i] - '0'; 5242 } 5243 if (v > 65535U) { 5244 return (false); 5245 } 5246 qctx->client->query.root_key_sentinel_keyid = v; 5247 return (true); 5248 } 5249 5250 /*% 5251 * Find out if the query is for a root key sentinel and if so, record the type 5252 * of root key sentinel query and the key id that is being checked for. 5253 * 5254 * The code is assuming a zero padded decimal field of width 5. 5255 */ 5256 static void 5257 root_key_sentinel_detect(query_ctx_t *qctx) { 5258 const char *ndata = (const char *)qctx->client->query.qname->ndata; 5259 5260 if (qctx->client->query.qname->length > 30 && ndata[0] == 29 && 5261 strncasecmp(ndata + 1, "root-key-sentinel-is-ta-", 24) == 0) 5262 { 5263 if (!get_root_key_sentinel_id(qctx, ndata + 25)) { 5264 return; 5265 } 5266 qctx->client->query.root_key_sentinel_is_ta = true; 5267 /* 5268 * Simplify processing by disabling aggressive 5269 * negative caching. 5270 */ 5271 qctx->findcoveringnsec = false; 5272 ns_client_log(qctx->client, NS_LOGCATEGORY_TAT, 5273 NS_LOGMODULE_QUERY, ISC_LOG_INFO, 5274 "root-key-sentinel-is-ta query label found"); 5275 } else if (qctx->client->query.qname->length > 31 && ndata[0] == 30 && 5276 strncasecmp(ndata + 1, "root-key-sentinel-not-ta-", 25) == 0) 5277 { 5278 if (!get_root_key_sentinel_id(qctx, ndata + 26)) { 5279 return; 5280 } 5281 qctx->client->query.root_key_sentinel_not_ta = true; 5282 /* 5283 * Simplify processing by disabling aggressive 5284 * negative caching. 5285 */ 5286 qctx->findcoveringnsec = false; 5287 ns_client_log(qctx->client, NS_LOGCATEGORY_TAT, 5288 NS_LOGMODULE_QUERY, ISC_LOG_INFO, 5289 "root-key-sentinel-not-ta query label found"); 5290 } 5291 } 5292 5293 /*% 5294 * Starting point for a client query or a chaining query. 5295 * 5296 * Called first by query_setup(), and then again as often as needed to 5297 * follow a CNAME chain. Determines which authoritative database to 5298 * search, then hands off processing to query_lookup(). 5299 */ 5300 isc_result_t 5301 ns__query_start(query_ctx_t *qctx) { 5302 isc_result_t result; 5303 CCTRACE(ISC_LOG_DEBUG(3), "ns__query_start"); 5304 qctx->want_restart = false; 5305 qctx->authoritative = false; 5306 qctx->version = NULL; 5307 qctx->zversion = NULL; 5308 qctx->need_wildcardproof = false; 5309 qctx->rpz = false; 5310 5311 CALL_HOOK(NS_QUERY_START_BEGIN, qctx); 5312 5313 /* 5314 * If we require a server cookie then send back BADCOOKIE 5315 * before we have done too much work. 5316 */ 5317 if (!TCP(qctx->client) && qctx->view->requireservercookie && 5318 WANTCOOKIE(qctx->client) && !HAVECOOKIE(qctx->client)) 5319 { 5320 qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AA; 5321 qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD; 5322 qctx->client->message->rcode = dns_rcode_badcookie; 5323 return (ns_query_done(qctx)); 5324 } 5325 5326 if (qctx->view->checknames && 5327 !dns_rdata_checkowner(qctx->client->query.qname, 5328 qctx->client->message->rdclass, qctx->qtype, 5329 false)) 5330 { 5331 char namebuf[DNS_NAME_FORMATSIZE]; 5332 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 5333 char classbuf[DNS_RDATACLASS_FORMATSIZE]; 5334 5335 dns_name_format(qctx->client->query.qname, namebuf, 5336 sizeof(namebuf)); 5337 dns_rdatatype_format(qctx->qtype, typebuf, sizeof(typebuf)); 5338 dns_rdataclass_format(qctx->client->message->rdclass, classbuf, 5339 sizeof(classbuf)); 5340 ns_client_log(qctx->client, DNS_LOGCATEGORY_SECURITY, 5341 NS_LOGMODULE_QUERY, ISC_LOG_ERROR, 5342 "check-names failure %s/%s/%s", namebuf, typebuf, 5343 classbuf); 5344 QUERY_ERROR(qctx, DNS_R_REFUSED); 5345 return (ns_query_done(qctx)); 5346 } 5347 5348 /* 5349 * Setup for root key sentinel processing. 5350 */ 5351 if (qctx->view->root_key_sentinel && 5352 qctx->client->query.restarts == 0 && 5353 (qctx->qtype == dns_rdatatype_a || 5354 qctx->qtype == dns_rdatatype_aaaa) && 5355 (qctx->client->message->flags & DNS_MESSAGEFLAG_CD) == 0) 5356 { 5357 root_key_sentinel_detect(qctx); 5358 } 5359 5360 /* 5361 * First we must find the right database. 5362 */ 5363 qctx->options &= DNS_GETDB_NOLOG; /* Preserve DNS_GETDB_NOLOG. */ 5364 if (dns_rdatatype_atparent(qctx->qtype) && 5365 !dns_name_equal(qctx->client->query.qname, dns_rootname)) 5366 { 5367 /* 5368 * If authoritative data for this QTYPE is supposed to live in 5369 * the parent zone, do not look for an exact match for QNAME, 5370 * but rather for its containing zone (unless the QNAME is 5371 * root). 5372 */ 5373 qctx->options |= DNS_GETDB_NOEXACT; 5374 } 5375 5376 result = query_getdb(qctx->client, qctx->client->query.qname, 5377 qctx->qtype, qctx->options, &qctx->zone, &qctx->db, 5378 &qctx->version, &qctx->is_zone); 5379 if (ISC_UNLIKELY((result != ISC_R_SUCCESS || !qctx->is_zone) && 5380 qctx->qtype == dns_rdatatype_ds && 5381 !RECURSIONOK(qctx->client) && 5382 (qctx->options & DNS_GETDB_NOEXACT) != 0)) 5383 { 5384 /* 5385 * This is a non-recursive QTYPE=DS query with QNAME whose 5386 * parent we are not authoritative for. Check whether we are 5387 * authoritative for QNAME, because if so, we need to send a 5388 * "no data" response as required by RFC 4035, section 3.1.4.1. 5389 */ 5390 dns_db_t *tdb = NULL; 5391 dns_zone_t *tzone = NULL; 5392 dns_dbversion_t *tversion = NULL; 5393 isc_result_t tresult; 5394 5395 tresult = query_getzonedb( 5396 qctx->client, qctx->client->query.qname, qctx->qtype, 5397 DNS_GETDB_PARTIAL, &tzone, &tdb, &tversion); 5398 if (tresult == ISC_R_SUCCESS) { 5399 /* 5400 * We are authoritative for QNAME. Attach the relevant 5401 * zone to query context, set result to ISC_R_SUCCESS. 5402 */ 5403 qctx->options &= ~DNS_GETDB_NOEXACT; 5404 ns_client_putrdataset(qctx->client, &qctx->rdataset); 5405 if (qctx->db != NULL) { 5406 dns_db_detach(&qctx->db); 5407 } 5408 if (qctx->zone != NULL) { 5409 dns_zone_detach(&qctx->zone); 5410 } 5411 qctx->version = NULL; 5412 RESTORE(qctx->version, tversion); 5413 RESTORE(qctx->db, tdb); 5414 RESTORE(qctx->zone, tzone); 5415 qctx->is_zone = true; 5416 result = ISC_R_SUCCESS; 5417 } else { 5418 /* 5419 * We are not authoritative for QNAME. Clean up and 5420 * leave result as it was. 5421 */ 5422 if (tdb != NULL) { 5423 dns_db_detach(&tdb); 5424 } 5425 if (tzone != NULL) { 5426 dns_zone_detach(&tzone); 5427 } 5428 } 5429 } 5430 /* 5431 * If we did not find a database from which we can answer the query, 5432 * respond with either REFUSED or SERVFAIL, depending on what the 5433 * result of query_getdb() was. 5434 */ 5435 if (result != ISC_R_SUCCESS) { 5436 if (result == DNS_R_REFUSED) { 5437 if (WANTRECURSION(qctx->client)) { 5438 inc_stats(qctx->client, 5439 ns_statscounter_recurserej); 5440 } else { 5441 inc_stats(qctx->client, 5442 ns_statscounter_authrej); 5443 } 5444 if (!PARTIALANSWER(qctx->client)) { 5445 QUERY_ERROR(qctx, DNS_R_REFUSED); 5446 } 5447 } else { 5448 CCTRACE(ISC_LOG_ERROR, "ns__query_start: query_getdb " 5449 "failed"); 5450 QUERY_ERROR(qctx, result); 5451 } 5452 return (ns_query_done(qctx)); 5453 } 5454 5455 /* 5456 * We found a database from which we can answer the query. Update 5457 * relevant query context flags if the answer is to be prepared using 5458 * authoritative data. 5459 */ 5460 qctx->is_staticstub_zone = false; 5461 if (qctx->is_zone) { 5462 qctx->authoritative = true; 5463 if (qctx->zone != NULL) { 5464 if (dns_zone_gettype(qctx->zone) == dns_zone_mirror) { 5465 qctx->authoritative = false; 5466 } 5467 if (dns_zone_gettype(qctx->zone) == dns_zone_staticstub) 5468 { 5469 qctx->is_staticstub_zone = true; 5470 } 5471 } 5472 } 5473 5474 /* 5475 * Attach to the database which will be used to prepare the answer. 5476 * Update query statistics. 5477 */ 5478 if (qctx->event == NULL && qctx->client->query.restarts == 0) { 5479 if (qctx->is_zone) { 5480 if (qctx->zone != NULL) { 5481 /* 5482 * if is_zone = true, zone = NULL then this is 5483 * a DLZ zone. Don't attempt to attach zone. 5484 */ 5485 dns_zone_attach(qctx->zone, 5486 &qctx->client->query.authzone); 5487 } 5488 dns_db_attach(qctx->db, &qctx->client->query.authdb); 5489 } 5490 qctx->client->query.authdbset = true; 5491 5492 /* Track TCP vs UDP stats per zone */ 5493 if (TCP(qctx->client)) { 5494 inc_stats(qctx->client, ns_statscounter_tcp); 5495 } else { 5496 inc_stats(qctx->client, ns_statscounter_udp); 5497 } 5498 } 5499 5500 return (query_lookup(qctx)); 5501 5502 cleanup: 5503 return (result); 5504 } 5505 5506 /*% 5507 * Perform a local database lookup, in either an authoritative or 5508 * cache database. If unable to answer, call ns_query_done(); otherwise 5509 * hand off processing to query_gotanswer(). 5510 */ 5511 static isc_result_t 5512 query_lookup(query_ctx_t *qctx) { 5513 isc_buffer_t b; 5514 isc_result_t result; 5515 dns_clientinfomethods_t cm; 5516 dns_clientinfo_t ci; 5517 dns_name_t *rpzqname = NULL; 5518 unsigned int dboptions; 5519 5520 CCTRACE(ISC_LOG_DEBUG(3), "query_lookup"); 5521 5522 CALL_HOOK(NS_QUERY_LOOKUP_BEGIN, qctx); 5523 5524 dns_clientinfomethods_init(&cm, ns_client_sourceip); 5525 dns_clientinfo_init(&ci, qctx->client, NULL); 5526 5527 /* 5528 * We'll need some resources... 5529 */ 5530 qctx->dbuf = ns_client_getnamebuf(qctx->client); 5531 if (ISC_UNLIKELY(qctx->dbuf == NULL)) { 5532 CCTRACE(ISC_LOG_ERROR, "query_lookup: ns_client_getnamebuf " 5533 "failed (2)"); 5534 QUERY_ERROR(qctx, ISC_R_NOMEMORY); 5535 return (ns_query_done(qctx)); 5536 } 5537 5538 qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b); 5539 qctx->rdataset = ns_client_newrdataset(qctx->client); 5540 5541 if (ISC_UNLIKELY(qctx->fname == NULL || qctx->rdataset == NULL)) { 5542 CCTRACE(ISC_LOG_ERROR, "query_lookup: ns_client_newname failed " 5543 "(2)"); 5544 QUERY_ERROR(qctx, ISC_R_NOMEMORY); 5545 return (ns_query_done(qctx)); 5546 } 5547 5548 if ((WANTDNSSEC(qctx->client) || qctx->findcoveringnsec) && 5549 (!qctx->is_zone || dns_db_issecure(qctx->db))) 5550 { 5551 qctx->sigrdataset = ns_client_newrdataset(qctx->client); 5552 if (qctx->sigrdataset == NULL) { 5553 CCTRACE(ISC_LOG_ERROR, "query_lookup: " 5554 "ns_client_newrdataset failed " 5555 "(2)"); 5556 QUERY_ERROR(qctx, ISC_R_NOMEMORY); 5557 return (ns_query_done(qctx)); 5558 } 5559 } 5560 5561 /* 5562 * Now look for an answer in the database. 5563 */ 5564 if (qctx->dns64 && qctx->rpz) { 5565 rpzqname = qctx->client->query.rpz_st->p_name; 5566 } else { 5567 rpzqname = qctx->client->query.qname; 5568 } 5569 5570 dboptions = qctx->client->query.dboptions; 5571 if (!qctx->is_zone && qctx->findcoveringnsec && 5572 (qctx->type != dns_rdatatype_null || !dns_name_istat(rpzqname))) 5573 { 5574 dboptions |= DNS_DBFIND_COVERINGNSEC; 5575 } 5576 5577 result = dns_db_findext(qctx->db, rpzqname, qctx->version, qctx->type, 5578 dboptions, qctx->client->now, &qctx->node, 5579 qctx->fname, &cm, &ci, qctx->rdataset, 5580 qctx->sigrdataset); 5581 5582 /* 5583 * Fixup fname and sigrdataset. 5584 */ 5585 if (qctx->dns64 && qctx->rpz) { 5586 dns_name_copynf(qctx->client->query.qname, qctx->fname); 5587 if (qctx->sigrdataset != NULL && 5588 dns_rdataset_isassociated(qctx->sigrdataset)) { 5589 dns_rdataset_disassociate(qctx->sigrdataset); 5590 } 5591 } 5592 5593 if (!qctx->is_zone) { 5594 dns_cache_updatestats(qctx->view->cache, result); 5595 } 5596 5597 if ((qctx->client->query.dboptions & DNS_DBFIND_STALEOK) != 0) { 5598 char namebuf[DNS_NAME_FORMATSIZE]; 5599 bool success; 5600 5601 qctx->client->query.dboptions &= ~DNS_DBFIND_STALEOK; 5602 if (dns_rdataset_isassociated(qctx->rdataset) && 5603 dns_rdataset_count(qctx->rdataset) > 0 && 5604 STALE(qctx->rdataset)) 5605 { 5606 qctx->rdataset->ttl = qctx->view->staleanswerttl; 5607 success = true; 5608 } else { 5609 success = false; 5610 } 5611 5612 dns_name_format(qctx->client->query.qname, namebuf, 5613 sizeof(namebuf)); 5614 isc_log_write(ns_lctx, NS_LOGCATEGORY_SERVE_STALE, 5615 NS_LOGMODULE_QUERY, ISC_LOG_INFO, 5616 "%s resolver failure, stale answer %s", namebuf, 5617 success ? "used" : "unavailable"); 5618 5619 if (!success) { 5620 QUERY_ERROR(qctx, DNS_R_SERVFAIL); 5621 return (ns_query_done(qctx)); 5622 } 5623 } 5624 return (query_gotanswer(qctx, result)); 5625 5626 cleanup: 5627 return (result); 5628 } 5629 5630 /* 5631 * Event handler to resume processing a query after recursion. 5632 * If the query has timed out or been canceled or the system 5633 * is shutting down, clean up and exit; otherwise, call 5634 * query_resume() to continue the ongoing work. 5635 */ 5636 static void 5637 fetch_callback(isc_task_t *task, isc_event_t *event) { 5638 dns_fetchevent_t *devent = (dns_fetchevent_t *)event; 5639 dns_fetch_t *fetch = NULL; 5640 ns_client_t *client; 5641 bool fetch_canceled, client_shuttingdown; 5642 isc_result_t result; 5643 isc_logcategory_t *logcategory = NS_LOGCATEGORY_QUERY_ERRORS; 5644 int errorloglevel; 5645 5646 UNUSED(task); 5647 5648 REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); 5649 client = devent->ev_arg; 5650 REQUIRE(NS_CLIENT_VALID(client)); 5651 REQUIRE(task == client->task); 5652 REQUIRE(RECURSING(client)); 5653 5654 CTRACE(ISC_LOG_DEBUG(3), "fetch_callback"); 5655 5656 LOCK(&client->query.fetchlock); 5657 if (client->query.fetch != NULL) { 5658 /* 5659 * This is the fetch we've been waiting for. 5660 */ 5661 INSIST(devent->fetch == client->query.fetch); 5662 client->query.fetch = NULL; 5663 fetch_canceled = false; 5664 /* 5665 * Update client->now. 5666 */ 5667 isc_stdtime_get(&client->now); 5668 } else { 5669 /* 5670 * This is a fetch completion event for a canceled fetch. 5671 * Clean up and don't resume the find. 5672 */ 5673 fetch_canceled = true; 5674 } 5675 UNLOCK(&client->query.fetchlock); 5676 INSIST(client->query.fetch == NULL); 5677 5678 SAVE(fetch, devent->fetch); 5679 5680 /* 5681 * We're done recursing, detach from quota and unlink from 5682 * the manager's recursing-clients list. 5683 */ 5684 5685 if (client->recursionquota != NULL) { 5686 isc_quota_detach(&client->recursionquota); 5687 ns_stats_decrement(client->sctx->nsstats, 5688 ns_statscounter_recursclients); 5689 } 5690 5691 LOCK(&client->manager->reclock); 5692 if (ISC_LINK_LINKED(client, rlink)) { 5693 ISC_LIST_UNLINK(client->manager->recursing, client, rlink); 5694 } 5695 UNLOCK(&client->manager->reclock); 5696 5697 client->query.attributes &= ~NS_QUERYATTR_RECURSING; 5698 client->state = NS_CLIENTSTATE_WORKING; 5699 5700 /* 5701 * If this client is shutting down, or this transaction 5702 * has timed out, do not resume the find. 5703 */ 5704 client_shuttingdown = ns_client_shuttingdown(client); 5705 if (fetch_canceled || client_shuttingdown) { 5706 free_devent(client, &event, &devent); 5707 if (fetch_canceled) { 5708 CTRACE(ISC_LOG_ERROR, "fetch cancelled"); 5709 query_error(client, DNS_R_SERVFAIL, __LINE__); 5710 } else { 5711 query_next(client, ISC_R_CANCELED); 5712 } 5713 } else { 5714 query_ctx_t qctx; 5715 5716 /* 5717 * Initialize a new qctx and use it to resume 5718 * from recursion. 5719 */ 5720 qctx_init(client, devent, 0, &qctx); 5721 query_trace(&qctx); 5722 5723 result = query_resume(&qctx); 5724 if (result != ISC_R_SUCCESS) { 5725 if (result == DNS_R_SERVFAIL) { 5726 errorloglevel = ISC_LOG_DEBUG(2); 5727 } else { 5728 errorloglevel = ISC_LOG_DEBUG(4); 5729 } 5730 if (isc_log_wouldlog(ns_lctx, errorloglevel)) { 5731 dns_resolver_logfetch(fetch, ns_lctx, 5732 logcategory, 5733 NS_LOGMODULE_QUERY, 5734 errorloglevel, false); 5735 } 5736 } 5737 5738 qctx_destroy(&qctx); 5739 } 5740 5741 dns_resolver_destroyfetch(&fetch); 5742 isc_nmhandle_unref(client->handle); 5743 } 5744 5745 /*% 5746 * Check whether the recursion parameters in 'param' match the current query's 5747 * recursion parameters provided in 'qtype', 'qname', and 'qdomain'. 5748 */ 5749 static bool 5750 recparam_match(const ns_query_recparam_t *param, dns_rdatatype_t qtype, 5751 const dns_name_t *qname, const dns_name_t *qdomain) { 5752 REQUIRE(param != NULL); 5753 5754 return (param->qtype == qtype && param->qname != NULL && 5755 qname != NULL && param->qdomain != NULL && qdomain != NULL && 5756 dns_name_equal(param->qname, qname) && 5757 dns_name_equal(param->qdomain, qdomain)); 5758 } 5759 5760 /*% 5761 * Update 'param' with current query's recursion parameters provided in 5762 * 'qtype', 'qname', and 'qdomain'. 5763 */ 5764 static void 5765 recparam_update(ns_query_recparam_t *param, dns_rdatatype_t qtype, 5766 const dns_name_t *qname, const dns_name_t *qdomain) { 5767 REQUIRE(param != NULL); 5768 5769 param->qtype = qtype; 5770 5771 if (qname == NULL) { 5772 param->qname = NULL; 5773 } else { 5774 param->qname = dns_fixedname_initname(¶m->fqname); 5775 dns_name_copynf(qname, param->qname); 5776 } 5777 5778 if (qdomain == NULL) { 5779 param->qdomain = NULL; 5780 } else { 5781 param->qdomain = dns_fixedname_initname(¶m->fqdomain); 5782 dns_name_copynf(qdomain, param->qdomain); 5783 } 5784 } 5785 static atomic_uint_fast32_t last_soft, last_hard; 5786 #ifdef ISC_MUTEX_ATOMICS 5787 static isc_once_t last_once = ISC_ONCE_INIT; 5788 static void 5789 last_init() { 5790 atomic_init(&last_soft, 0); 5791 atomic_init(&last_hard, 0); 5792 } 5793 #endif /* ifdef ISC_MUTEX_ATOMICS */ 5794 5795 isc_result_t 5796 ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, 5797 dns_name_t *qdomain, dns_rdataset_t *nameservers, 5798 bool resuming) { 5799 isc_result_t result; 5800 dns_rdataset_t *rdataset, *sigrdataset; 5801 isc_sockaddr_t *peeraddr = NULL; 5802 5803 CTRACE(ISC_LOG_DEBUG(3), "ns_query_recurse"); 5804 5805 /* 5806 * Check recursion parameters from the previous query to see if they 5807 * match. If not, update recursion parameters and proceed. 5808 */ 5809 if (recparam_match(&client->query.recparam, qtype, qname, qdomain)) { 5810 ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_QUERY, 5811 ISC_LOG_INFO, "recursion loop detected"); 5812 return (ISC_R_FAILURE); 5813 } 5814 5815 recparam_update(&client->query.recparam, qtype, qname, qdomain); 5816 5817 if (!resuming) { 5818 inc_stats(client, ns_statscounter_recursion); 5819 } 5820 5821 /* 5822 * We are about to recurse, which means that this client will 5823 * be unavailable for serving new requests for an indeterminate 5824 * amount of time. If this client is currently responsible 5825 * for handling incoming queries, set up a new client 5826 * object to handle them while we are waiting for a 5827 * response. There is no need to replace TCP clients 5828 * because those have already been replaced when the 5829 * connection was accepted (if allowed by the TCP quota). 5830 */ 5831 if (client->recursionquota == NULL) { 5832 result = isc_quota_attach(&client->sctx->recursionquota, 5833 &client->recursionquota); 5834 if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) { 5835 ns_stats_increment(client->sctx->nsstats, 5836 ns_statscounter_recursclients); 5837 } 5838 5839 if (result == ISC_R_SOFTQUOTA) { 5840 #ifdef ISC_MUTEX_ATOMICS 5841 isc_once_do(&last_once, last_init); 5842 #endif /* ifdef ISC_MUTEX_ATOMICS */ 5843 isc_stdtime_t now; 5844 isc_stdtime_get(&now); 5845 if (now != atomic_load_relaxed(&last_soft)) { 5846 atomic_store_relaxed(&last_soft, now); 5847 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 5848 NS_LOGMODULE_QUERY, 5849 ISC_LOG_WARNING, 5850 "recursive-clients soft limit " 5851 "exceeded (%u/%u/%u), " 5852 "aborting oldest query", 5853 isc_quota_getused( 5854 client->recursionquota), 5855 isc_quota_getsoft( 5856 client->recursionquota), 5857 isc_quota_getmax( 5858 client->recursionquota)); 5859 } 5860 ns_client_killoldestquery(client); 5861 result = ISC_R_SUCCESS; 5862 } else if (result == ISC_R_QUOTA) { 5863 #ifdef ISC_MUTEX_ATOMICS 5864 isc_once_do(&last_once, last_init); 5865 #endif /* ifdef ISC_MUTEX_ATOMICS */ 5866 isc_stdtime_t now; 5867 isc_stdtime_get(&now); 5868 if (now != atomic_load_relaxed(&last_hard)) { 5869 ns_server_t *sctx = client->sctx; 5870 atomic_store_relaxed(&last_hard, now); 5871 ns_client_log( 5872 client, NS_LOGCATEGORY_CLIENT, 5873 NS_LOGMODULE_QUERY, ISC_LOG_WARNING, 5874 "no more recursive clients " 5875 "(%u/%u/%u): %s", 5876 isc_quota_getused( 5877 &sctx->recursionquota), 5878 isc_quota_getsoft( 5879 &sctx->recursionquota), 5880 isc_quota_getmax(&sctx->recursionquota), 5881 isc_result_totext(result)); 5882 } 5883 ns_client_killoldestquery(client); 5884 } 5885 if (result != ISC_R_SUCCESS) { 5886 return (result); 5887 } 5888 5889 ns_client_recursing(client); 5890 } 5891 5892 /* 5893 * Invoke the resolver. 5894 */ 5895 REQUIRE(nameservers == NULL || nameservers->type == dns_rdatatype_ns); 5896 REQUIRE(client->query.fetch == NULL); 5897 5898 rdataset = ns_client_newrdataset(client); 5899 if (rdataset == NULL) { 5900 return (ISC_R_NOMEMORY); 5901 } 5902 5903 if (WANTDNSSEC(client)) { 5904 sigrdataset = ns_client_newrdataset(client); 5905 if (sigrdataset == NULL) { 5906 ns_client_putrdataset(client, &rdataset); 5907 return (ISC_R_NOMEMORY); 5908 } 5909 } else { 5910 sigrdataset = NULL; 5911 } 5912 5913 if (!client->query.timerset) { 5914 ns_client_settimeout(client, 60); 5915 } 5916 5917 if (!TCP(client)) { 5918 peeraddr = &client->peeraddr; 5919 } 5920 5921 isc_nmhandle_ref(client->handle); 5922 result = dns_resolver_createfetch( 5923 client->view->resolver, qname, qtype, qdomain, nameservers, 5924 NULL, peeraddr, client->message->id, client->query.fetchoptions, 5925 0, NULL, client->task, fetch_callback, client, rdataset, 5926 sigrdataset, &client->query.fetch); 5927 if (result != ISC_R_SUCCESS) { 5928 isc_nmhandle_unref(client->handle); 5929 ns_client_putrdataset(client, &rdataset); 5930 if (sigrdataset != NULL) { 5931 ns_client_putrdataset(client, &sigrdataset); 5932 } 5933 } 5934 5935 /* 5936 * We're now waiting for a fetch event. A client which is 5937 * shutting down will not be destroyed until all the events 5938 * have been received. 5939 */ 5940 5941 return (result); 5942 } 5943 5944 /*% 5945 * Restores the query context after resuming from recursion, and 5946 * continues the query processing if needed. 5947 */ 5948 static isc_result_t 5949 query_resume(query_ctx_t *qctx) { 5950 isc_result_t result; 5951 dns_name_t *tname; 5952 isc_buffer_t b; 5953 #ifdef WANT_QUERYTRACE 5954 char mbuf[4 * DNS_NAME_FORMATSIZE]; 5955 char qbuf[DNS_NAME_FORMATSIZE]; 5956 char tbuf[DNS_RDATATYPE_FORMATSIZE]; 5957 #endif /* ifdef WANT_QUERYTRACE */ 5958 5959 CCTRACE(ISC_LOG_DEBUG(3), "query_resume"); 5960 5961 CALL_HOOK(NS_QUERY_RESUME_BEGIN, qctx); 5962 5963 qctx->want_restart = false; 5964 5965 qctx->rpz_st = qctx->client->query.rpz_st; 5966 if (qctx->rpz_st != NULL && 5967 (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0) { 5968 CCTRACE(ISC_LOG_DEBUG(3), "resume from RPZ recursion"); 5969 #ifdef WANT_QUERYTRACE 5970 { 5971 char pbuf[DNS_NAME_FORMATSIZE] = "<unset>"; 5972 char fbuf[DNS_NAME_FORMATSIZE] = "<unset>"; 5973 if (qctx->rpz_st->r_name != NULL) { 5974 dns_name_format(qctx->rpz_st->r_name, qbuf, 5975 sizeof(qbuf)); 5976 } else { 5977 snprintf(qbuf, sizeof(qbuf), "<unset>"); 5978 } 5979 if (qctx->rpz_st->p_name != NULL) { 5980 dns_name_format(qctx->rpz_st->p_name, pbuf, 5981 sizeof(pbuf)); 5982 } 5983 if (qctx->rpz_st->fname != NULL) { 5984 dns_name_format(qctx->rpz_st->fname, fbuf, 5985 sizeof(fbuf)); 5986 } 5987 5988 snprintf(mbuf, sizeof(mbuf) - 1, 5989 "rpz rname:%s, pname:%s, qctx->fname:%s", qbuf, 5990 pbuf, fbuf); 5991 CCTRACE(ISC_LOG_DEBUG(3), mbuf); 5992 } 5993 #endif /* ifdef WANT_QUERYTRACE */ 5994 5995 qctx->is_zone = qctx->rpz_st->q.is_zone; 5996 qctx->authoritative = qctx->rpz_st->q.authoritative; 5997 RESTORE(qctx->zone, qctx->rpz_st->q.zone); 5998 RESTORE(qctx->node, qctx->rpz_st->q.node); 5999 RESTORE(qctx->db, qctx->rpz_st->q.db); 6000 RESTORE(qctx->rdataset, qctx->rpz_st->q.rdataset); 6001 RESTORE(qctx->sigrdataset, qctx->rpz_st->q.sigrdataset); 6002 qctx->qtype = qctx->rpz_st->q.qtype; 6003 6004 if (qctx->event->node != NULL) { 6005 dns_db_detachnode(qctx->event->db, &qctx->event->node); 6006 } 6007 SAVE(qctx->rpz_st->r.db, qctx->event->db); 6008 qctx->rpz_st->r.r_type = qctx->event->qtype; 6009 SAVE(qctx->rpz_st->r.r_rdataset, qctx->event->rdataset); 6010 ns_client_putrdataset(qctx->client, &qctx->event->sigrdataset); 6011 } else if (REDIRECT(qctx->client)) { 6012 /* 6013 * Restore saved state. 6014 */ 6015 CCTRACE(ISC_LOG_DEBUG(3), "resume from redirect recursion"); 6016 #ifdef WANT_QUERYTRACE 6017 dns_name_format(qctx->client->query.redirect.fname, qbuf, 6018 sizeof(qbuf)); 6019 dns_rdatatype_format(qctx->client->query.redirect.qtype, tbuf, 6020 sizeof(tbuf)); 6021 snprintf(mbuf, sizeof(mbuf) - 1, 6022 "redirect qctx->fname:%s, qtype:%s, auth:%d", qbuf, 6023 tbuf, qctx->client->query.redirect.authoritative); 6024 CCTRACE(ISC_LOG_DEBUG(3), mbuf); 6025 #endif /* ifdef WANT_QUERYTRACE */ 6026 qctx->qtype = qctx->client->query.redirect.qtype; 6027 INSIST(qctx->client->query.redirect.rdataset != NULL); 6028 RESTORE(qctx->rdataset, qctx->client->query.redirect.rdataset); 6029 RESTORE(qctx->sigrdataset, 6030 qctx->client->query.redirect.sigrdataset); 6031 RESTORE(qctx->db, qctx->client->query.redirect.db); 6032 RESTORE(qctx->node, qctx->client->query.redirect.node); 6033 RESTORE(qctx->zone, qctx->client->query.redirect.zone); 6034 qctx->authoritative = 6035 qctx->client->query.redirect.authoritative; 6036 6037 /* 6038 * Free resources used while recursing. 6039 */ 6040 ns_client_putrdataset(qctx->client, &qctx->event->rdataset); 6041 ns_client_putrdataset(qctx->client, &qctx->event->sigrdataset); 6042 if (qctx->event->node != NULL) { 6043 dns_db_detachnode(qctx->event->db, &qctx->event->node); 6044 } 6045 if (qctx->event->db != NULL) { 6046 dns_db_detach(&qctx->event->db); 6047 } 6048 } else { 6049 CCTRACE(ISC_LOG_DEBUG(3), "resume from normal recursion"); 6050 qctx->authoritative = false; 6051 6052 qctx->qtype = qctx->event->qtype; 6053 SAVE(qctx->db, qctx->event->db); 6054 SAVE(qctx->node, qctx->event->node); 6055 SAVE(qctx->rdataset, qctx->event->rdataset); 6056 SAVE(qctx->sigrdataset, qctx->event->sigrdataset); 6057 } 6058 INSIST(qctx->rdataset != NULL); 6059 6060 if (qctx->qtype == dns_rdatatype_rrsig || 6061 qctx->qtype == dns_rdatatype_sig) { 6062 qctx->type = dns_rdatatype_any; 6063 } else { 6064 qctx->type = qctx->qtype; 6065 } 6066 6067 CALL_HOOK(NS_QUERY_RESUME_RESTORED, qctx); 6068 6069 if (DNS64(qctx->client)) { 6070 qctx->client->query.attributes &= ~NS_QUERYATTR_DNS64; 6071 qctx->dns64 = true; 6072 } 6073 6074 if (DNS64EXCLUDE(qctx->client)) { 6075 qctx->client->query.attributes &= ~NS_QUERYATTR_DNS64EXCLUDE; 6076 qctx->dns64_exclude = true; 6077 } 6078 6079 if (qctx->rpz_st != NULL && 6080 (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0) { 6081 /* 6082 * Has response policy changed out from under us? 6083 */ 6084 if (qctx->rpz_st->rpz_ver != qctx->view->rpzs->rpz_ver) { 6085 ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT, 6086 NS_LOGMODULE_QUERY, DNS_RPZ_INFO_LEVEL, 6087 "query_resume: RPZ settings " 6088 "out of date " 6089 "(rpz_ver %d, expected %d)", 6090 qctx->view->rpzs->rpz_ver, 6091 qctx->rpz_st->rpz_ver); 6092 QUERY_ERROR(qctx, DNS_R_SERVFAIL); 6093 return (ns_query_done(qctx)); 6094 } 6095 } 6096 6097 /* 6098 * We'll need some resources... 6099 */ 6100 qctx->dbuf = ns_client_getnamebuf(qctx->client); 6101 if (qctx->dbuf == NULL) { 6102 CCTRACE(ISC_LOG_ERROR, "query_resume: ns_client_getnamebuf " 6103 "failed (1)"); 6104 QUERY_ERROR(qctx, ISC_R_NOMEMORY); 6105 return (ns_query_done(qctx)); 6106 } 6107 6108 qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b); 6109 if (qctx->fname == NULL) { 6110 CCTRACE(ISC_LOG_ERROR, "query_resume: ns_client_newname failed " 6111 "(1)"); 6112 QUERY_ERROR(qctx, ISC_R_NOMEMORY); 6113 return (ns_query_done(qctx)); 6114 } 6115 6116 if (qctx->rpz_st != NULL && 6117 (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0) { 6118 tname = qctx->rpz_st->fname; 6119 } else if (REDIRECT(qctx->client)) { 6120 tname = qctx->client->query.redirect.fname; 6121 } else { 6122 tname = dns_fixedname_name(&qctx->event->foundname); 6123 } 6124 6125 dns_name_copynf(tname, qctx->fname); 6126 6127 if (qctx->rpz_st != NULL && 6128 (qctx->rpz_st->state & DNS_RPZ_RECURSING) != 0) { 6129 qctx->rpz_st->r.r_result = qctx->event->result; 6130 result = qctx->rpz_st->q.result; 6131 free_devent(qctx->client, ISC_EVENT_PTR(&qctx->event), 6132 &qctx->event); 6133 } else if (REDIRECT(qctx->client)) { 6134 result = qctx->client->query.redirect.result; 6135 } else { 6136 result = qctx->event->result; 6137 } 6138 6139 qctx->resuming = true; 6140 6141 return (query_gotanswer(qctx, result)); 6142 6143 cleanup: 6144 return (result); 6145 } 6146 6147 /*% 6148 * If the query is recursive, check the SERVFAIL cache to see whether 6149 * identical queries have failed recently. If we find a match, and it was 6150 * from a query with CD=1, *or* if the current query has CD=0, then we just 6151 * return SERVFAIL again. This prevents a validation failure from eliciting a 6152 * SERVFAIL response to a CD=1 query. 6153 */ 6154 isc_result_t 6155 ns__query_sfcache(query_ctx_t *qctx) { 6156 bool failcache; 6157 uint32_t flags; 6158 6159 /* 6160 * The SERVFAIL cache doesn't apply to authoritative queries. 6161 */ 6162 if (!RECURSIONOK(qctx->client)) { 6163 return (ISC_R_COMPLETE); 6164 } 6165 6166 flags = 0; 6167 #ifdef ENABLE_AFL 6168 if (qctx->client->sctx->fuzztype == isc_fuzz_resolver) { 6169 failcache = false; 6170 } else { 6171 failcache = dns_badcache_find( 6172 qctx->view->failcache, qctx->client->query.qname, 6173 qctx->qtype, &flags, &qctx->client->tnow); 6174 } 6175 #else /* ifdef ENABLE_AFL */ 6176 failcache = dns_badcache_find(qctx->view->failcache, 6177 qctx->client->query.qname, qctx->qtype, 6178 &flags, &qctx->client->tnow); 6179 #endif /* ifdef ENABLE_AFL */ 6180 if (failcache && 6181 (((flags & NS_FAILCACHE_CD) != 0) || 6182 ((qctx->client->message->flags & DNS_MESSAGEFLAG_CD) == 0))) 6183 { 6184 if (isc_log_wouldlog(ns_lctx, ISC_LOG_DEBUG(1))) { 6185 char namebuf[DNS_NAME_FORMATSIZE]; 6186 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 6187 6188 dns_name_format(qctx->client->query.qname, namebuf, 6189 sizeof(namebuf)); 6190 dns_rdatatype_format(qctx->qtype, typebuf, 6191 sizeof(typebuf)); 6192 ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT, 6193 NS_LOGMODULE_QUERY, ISC_LOG_DEBUG(1), 6194 "servfail cache hit %s/%s (%s)", namebuf, 6195 typebuf, 6196 ((flags & NS_FAILCACHE_CD) != 0) ? "CD=1" 6197 : "CD=" 6198 "0"); 6199 } 6200 6201 qctx->client->attributes |= NS_CLIENTATTR_NOSETFC; 6202 QUERY_ERROR(qctx, DNS_R_SERVFAIL); 6203 return (ns_query_done(qctx)); 6204 } 6205 6206 return (ISC_R_COMPLETE); 6207 } 6208 6209 /*% 6210 * Handle response rate limiting (RRL). 6211 */ 6212 static isc_result_t 6213 query_checkrrl(query_ctx_t *qctx, isc_result_t result) { 6214 /* 6215 * Rate limit these responses to this client. 6216 * Do not delay counting and handling obvious referrals, 6217 * since those won't come here again. 6218 * Delay handling delegations for which we are certain to recurse and 6219 * return here (DNS_R_DELEGATION, not a child of one of our 6220 * own zones, and recursion enabled) 6221 * Don't mess with responses rewritten by RPZ 6222 * Count each response at most once. 6223 */ 6224 6225 /* 6226 * XXXMPA the rrl system tests fails sometimes and RRL_CHECKED 6227 * is set when we are called the second time preventing the 6228 * response being dropped. 6229 */ 6230 ns_client_log( 6231 qctx->client, DNS_LOGCATEGORY_RRL, NS_LOGMODULE_QUERY, 6232 ISC_LOG_DEBUG(99), 6233 "rrl=%p, HAVECOOKIE=%u, result=%s, " 6234 "fname=%p(%u), is_zone=%u, RECURSIONOK=%u, " 6235 "query.rpz_st=%p(%u), RRL_CHECKED=%u\n", 6236 qctx->client->view->rrl, HAVECOOKIE(qctx->client), 6237 isc_result_toid(result), qctx->fname, 6238 qctx->fname != NULL ? dns_name_isabsolute(qctx->fname) : 0, 6239 qctx->is_zone, RECURSIONOK(qctx->client), 6240 qctx->client->query.rpz_st, 6241 qctx->client->query.rpz_st != NULL 6242 ? ((qctx->client->query.rpz_st->state & 6243 DNS_RPZ_REWRITTEN) != 0) 6244 : 0, 6245 (qctx->client->query.attributes & NS_QUERYATTR_RRL_CHECKED) != 6246 0); 6247 6248 if (qctx->view->rrl != NULL && !HAVECOOKIE(qctx->client) && 6249 ((qctx->fname != NULL && dns_name_isabsolute(qctx->fname)) || 6250 (result == ISC_R_NOTFOUND && !RECURSIONOK(qctx->client))) && 6251 !(result == DNS_R_DELEGATION && !qctx->is_zone && 6252 RECURSIONOK(qctx->client)) && 6253 (qctx->client->query.rpz_st == NULL || 6254 (qctx->client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0) && 6255 (qctx->client->query.attributes & NS_QUERYATTR_RRL_CHECKED) == 0) 6256 { 6257 dns_rdataset_t nc_rdataset; 6258 bool wouldlog; 6259 dns_fixedname_t fixed; 6260 const dns_name_t *constname; 6261 char log_buf[DNS_RRL_LOG_BUF_LEN]; 6262 isc_result_t nc_result, resp_result; 6263 dns_rrl_result_t rrl_result; 6264 6265 qctx->client->query.attributes |= NS_QUERYATTR_RRL_CHECKED; 6266 6267 wouldlog = isc_log_wouldlog(ns_lctx, DNS_RRL_LOG_DROP); 6268 constname = qctx->fname; 6269 if (result == DNS_R_NXDOMAIN) { 6270 /* 6271 * Use the database origin name to rate limit NXDOMAIN 6272 */ 6273 if (qctx->db != NULL) { 6274 constname = dns_db_origin(qctx->db); 6275 } 6276 resp_result = result; 6277 } else if (result == DNS_R_NCACHENXDOMAIN && 6278 qctx->rdataset != NULL && 6279 dns_rdataset_isassociated(qctx->rdataset) && 6280 (qctx->rdataset->attributes & 6281 DNS_RDATASETATTR_NEGATIVE) != 0) 6282 { 6283 /* 6284 * Try to use owner name in the negative cache SOA. 6285 */ 6286 dns_fixedname_init(&fixed); 6287 dns_rdataset_init(&nc_rdataset); 6288 for (nc_result = dns_rdataset_first(qctx->rdataset); 6289 nc_result == ISC_R_SUCCESS; 6290 nc_result = dns_rdataset_next(qctx->rdataset)) 6291 { 6292 dns_ncache_current(qctx->rdataset, 6293 dns_fixedname_name(&fixed), 6294 &nc_rdataset); 6295 if (nc_rdataset.type == dns_rdatatype_soa) { 6296 dns_rdataset_disassociate(&nc_rdataset); 6297 constname = dns_fixedname_name(&fixed); 6298 break; 6299 } 6300 dns_rdataset_disassociate(&nc_rdataset); 6301 } 6302 resp_result = DNS_R_NXDOMAIN; 6303 } else if (result == DNS_R_NXRRSET || result == DNS_R_EMPTYNAME) 6304 { 6305 resp_result = DNS_R_NXRRSET; 6306 } else if (result == DNS_R_DELEGATION) { 6307 resp_result = result; 6308 } else if (result == ISC_R_NOTFOUND) { 6309 /* 6310 * Handle referral to ".", including when recursion 6311 * is off or not requested and the hints have not 6312 * been loaded or we have "additional-from-cache no". 6313 */ 6314 constname = dns_rootname; 6315 resp_result = DNS_R_DELEGATION; 6316 } else { 6317 resp_result = ISC_R_SUCCESS; 6318 } 6319 6320 rrl_result = dns_rrl( 6321 qctx->view, &qctx->client->peeraddr, TCP(qctx->client), 6322 qctx->client->message->rdclass, qctx->qtype, constname, 6323 resp_result, qctx->client->now, wouldlog, log_buf, 6324 sizeof(log_buf)); 6325 if (rrl_result != DNS_RRL_RESULT_OK) { 6326 /* 6327 * Log dropped or slipped responses in the query 6328 * category so that requests are not silently lost. 6329 * Starts of rate-limited bursts are logged in 6330 * DNS_LOGCATEGORY_RRL. 6331 * 6332 * Dropped responses are counted with dropped queries 6333 * in QryDropped while slipped responses are counted 6334 * with other truncated responses in RespTruncated. 6335 */ 6336 if (wouldlog) { 6337 ns_client_log(qctx->client, DNS_LOGCATEGORY_RRL, 6338 NS_LOGMODULE_QUERY, 6339 DNS_RRL_LOG_DROP, "%s", log_buf); 6340 } 6341 6342 if (!qctx->view->rrl->log_only) { 6343 if (rrl_result == DNS_RRL_RESULT_DROP) { 6344 /* 6345 * These will also be counted in 6346 * ns_statscounter_dropped 6347 */ 6348 inc_stats(qctx->client, 6349 ns_statscounter_ratedropped); 6350 QUERY_ERROR(qctx, DNS_R_DROP); 6351 } else { 6352 /* 6353 * These will also be counted in 6354 * ns_statscounter_truncatedresp 6355 */ 6356 inc_stats(qctx->client, 6357 ns_statscounter_rateslipped); 6358 if (WANTCOOKIE(qctx->client)) { 6359 qctx->client->message->flags &= 6360 ~DNS_MESSAGEFLAG_AA; 6361 qctx->client->message->flags &= 6362 ~DNS_MESSAGEFLAG_AD; 6363 qctx->client->message->rcode = 6364 dns_rcode_badcookie; 6365 } else { 6366 qctx->client->message->flags |= 6367 DNS_MESSAGEFLAG_TC; 6368 if (resp_result == 6369 DNS_R_NXDOMAIN) { 6370 qctx->client->message 6371 ->rcode = 6372 dns_rcode_nxdomain; 6373 } 6374 } 6375 } 6376 return (DNS_R_DROP); 6377 } 6378 } 6379 } 6380 6381 return (ISC_R_SUCCESS); 6382 } 6383 6384 /*% 6385 * Do any RPZ rewriting that may be needed for this query. 6386 */ 6387 static isc_result_t 6388 query_checkrpz(query_ctx_t *qctx, isc_result_t result) { 6389 isc_result_t rresult; 6390 6391 CCTRACE(ISC_LOG_DEBUG(3), "query_checkrpz"); 6392 6393 rresult = rpz_rewrite(qctx->client, qctx->qtype, result, qctx->resuming, 6394 qctx->rdataset, qctx->sigrdataset); 6395 qctx->rpz_st = qctx->client->query.rpz_st; 6396 switch (rresult) { 6397 case ISC_R_SUCCESS: 6398 break; 6399 case DNS_R_DISALLOWED: 6400 return (result); 6401 case DNS_R_DELEGATION: 6402 /* 6403 * recursing for NS names or addresses, 6404 * so save the main query state 6405 */ 6406 qctx->rpz_st->q.qtype = qctx->qtype; 6407 qctx->rpz_st->q.is_zone = qctx->is_zone; 6408 qctx->rpz_st->q.authoritative = qctx->authoritative; 6409 SAVE(qctx->rpz_st->q.zone, qctx->zone); 6410 SAVE(qctx->rpz_st->q.db, qctx->db); 6411 SAVE(qctx->rpz_st->q.node, qctx->node); 6412 SAVE(qctx->rpz_st->q.rdataset, qctx->rdataset); 6413 SAVE(qctx->rpz_st->q.sigrdataset, qctx->sigrdataset); 6414 dns_name_copynf(qctx->fname, qctx->rpz_st->fname); 6415 qctx->rpz_st->q.result = result; 6416 qctx->client->query.attributes |= NS_QUERYATTR_RECURSING; 6417 return (ISC_R_COMPLETE); 6418 default: 6419 QUERY_ERROR(qctx, rresult); 6420 return (ISC_R_COMPLETE); 6421 } 6422 6423 if (qctx->rpz_st->m.policy != DNS_RPZ_POLICY_MISS) { 6424 qctx->rpz_st->state |= DNS_RPZ_REWRITTEN; 6425 } 6426 6427 if (qctx->rpz_st->m.policy != DNS_RPZ_POLICY_MISS && 6428 qctx->rpz_st->m.policy != DNS_RPZ_POLICY_PASSTHRU && 6429 (qctx->rpz_st->m.policy != DNS_RPZ_POLICY_TCP_ONLY || 6430 !TCP(qctx->client)) && 6431 qctx->rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) 6432 { 6433 /* 6434 * We got a hit and are going to answer with our 6435 * fiction. Ensure that we answer with the name 6436 * we looked up even if we were stopped short 6437 * in recursion or for a deferral. 6438 */ 6439 dns_name_copynf(qctx->client->query.qname, qctx->fname); 6440 rpz_clean(&qctx->zone, &qctx->db, &qctx->node, NULL); 6441 if (qctx->rpz_st->m.rdataset != NULL) { 6442 ns_client_putrdataset(qctx->client, &qctx->rdataset); 6443 RESTORE(qctx->rdataset, qctx->rpz_st->m.rdataset); 6444 } else { 6445 qctx_clean(qctx); 6446 } 6447 qctx->version = NULL; 6448 6449 RESTORE(qctx->node, qctx->rpz_st->m.node); 6450 RESTORE(qctx->db, qctx->rpz_st->m.db); 6451 RESTORE(qctx->version, qctx->rpz_st->m.version); 6452 RESTORE(qctx->zone, qctx->rpz_st->m.zone); 6453 6454 /* 6455 * Add SOA record to additional section 6456 */ 6457 if (qctx->rpz_st->m.rpz->addsoa) { 6458 bool override_ttl = 6459 dns_rdataset_isassociated(qctx->rdataset); 6460 rresult = query_addsoa(qctx, override_ttl, 6461 DNS_SECTION_ADDITIONAL); 6462 if (rresult != ISC_R_SUCCESS) { 6463 QUERY_ERROR(qctx, result); 6464 return (ISC_R_COMPLETE); 6465 } 6466 } 6467 6468 switch (qctx->rpz_st->m.policy) { 6469 case DNS_RPZ_POLICY_TCP_ONLY: 6470 qctx->client->message->flags |= DNS_MESSAGEFLAG_TC; 6471 if (result == DNS_R_NXDOMAIN || 6472 result == DNS_R_NCACHENXDOMAIN) { 6473 qctx->client->message->rcode = 6474 dns_rcode_nxdomain; 6475 } 6476 rpz_log_rewrite(qctx->client, false, 6477 qctx->rpz_st->m.policy, 6478 qctx->rpz_st->m.type, qctx->zone, 6479 qctx->rpz_st->p_name, NULL, 6480 qctx->rpz_st->m.rpz->num); 6481 return (ISC_R_COMPLETE); 6482 case DNS_RPZ_POLICY_DROP: 6483 QUERY_ERROR(qctx, DNS_R_DROP); 6484 rpz_log_rewrite(qctx->client, false, 6485 qctx->rpz_st->m.policy, 6486 qctx->rpz_st->m.type, qctx->zone, 6487 qctx->rpz_st->p_name, NULL, 6488 qctx->rpz_st->m.rpz->num); 6489 return (ISC_R_COMPLETE); 6490 case DNS_RPZ_POLICY_NXDOMAIN: 6491 result = DNS_R_NXDOMAIN; 6492 qctx->nxrewrite = true; 6493 qctx->rpz = true; 6494 break; 6495 case DNS_RPZ_POLICY_NODATA: 6496 qctx->nxrewrite = true; 6497 /* FALLTHROUGH */ 6498 case DNS_RPZ_POLICY_DNS64: 6499 result = DNS_R_NXRRSET; 6500 qctx->rpz = true; 6501 break; 6502 case DNS_RPZ_POLICY_RECORD: 6503 result = qctx->rpz_st->m.result; 6504 if (qctx->qtype == dns_rdatatype_any && 6505 result != DNS_R_CNAME) { 6506 /* 6507 * We will add all of the rdatasets of 6508 * the node by iterating later, 6509 * and set the TTL then. 6510 */ 6511 if (dns_rdataset_isassociated(qctx->rdataset)) { 6512 dns_rdataset_disassociate( 6513 qctx->rdataset); 6514 } 6515 } else { 6516 /* 6517 * We will add this rdataset. 6518 */ 6519 qctx->rdataset->ttl = 6520 ISC_MIN(qctx->rdataset->ttl, 6521 qctx->rpz_st->m.ttl); 6522 } 6523 qctx->rpz = true; 6524 break; 6525 case DNS_RPZ_POLICY_WILDCNAME: { 6526 dns_rdata_t rdata = DNS_RDATA_INIT; 6527 dns_rdata_cname_t cname; 6528 result = dns_rdataset_first(qctx->rdataset); 6529 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6530 dns_rdataset_current(qctx->rdataset, &rdata); 6531 result = dns_rdata_tostruct(&rdata, &cname, NULL); 6532 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6533 dns_rdata_reset(&rdata); 6534 result = query_rpzcname(qctx, &cname.cname); 6535 if (result != ISC_R_SUCCESS) { 6536 return (ISC_R_COMPLETE); 6537 } 6538 qctx->fname = NULL; 6539 qctx->want_restart = true; 6540 return (ISC_R_COMPLETE); 6541 } 6542 case DNS_RPZ_POLICY_CNAME: 6543 /* 6544 * Add overriding CNAME from a named.conf 6545 * response-policy statement 6546 */ 6547 result = query_rpzcname(qctx, 6548 &qctx->rpz_st->m.rpz->cname); 6549 if (result != ISC_R_SUCCESS) { 6550 return (ISC_R_COMPLETE); 6551 } 6552 qctx->fname = NULL; 6553 qctx->want_restart = true; 6554 return (ISC_R_COMPLETE); 6555 default: 6556 INSIST(0); 6557 ISC_UNREACHABLE(); 6558 } 6559 6560 /* 6561 * Turn off DNSSEC because the results of a 6562 * response policy zone cannot verify. 6563 */ 6564 qctx->client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC | 6565 NS_CLIENTATTR_WANTAD); 6566 qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD; 6567 ns_client_putrdataset(qctx->client, &qctx->sigrdataset); 6568 qctx->rpz_st->q.is_zone = qctx->is_zone; 6569 qctx->is_zone = true; 6570 rpz_log_rewrite(qctx->client, false, qctx->rpz_st->m.policy, 6571 qctx->rpz_st->m.type, qctx->zone, 6572 qctx->rpz_st->p_name, NULL, 6573 qctx->rpz_st->m.rpz->num); 6574 } 6575 6576 return (result); 6577 } 6578 6579 /*% 6580 * Add a CNAME to a query response, including translating foo.evil.com and 6581 * *.evil.com CNAME *.example.com 6582 * to 6583 * foo.evil.com CNAME foo.evil.com.example.com 6584 */ 6585 static isc_result_t 6586 query_rpzcname(query_ctx_t *qctx, dns_name_t *cname) { 6587 ns_client_t *client; 6588 dns_fixedname_t prefix, suffix; 6589 unsigned int labels; 6590 isc_result_t result; 6591 6592 REQUIRE(qctx != NULL && qctx->client != NULL); 6593 6594 client = qctx->client; 6595 6596 CTRACE(ISC_LOG_DEBUG(3), "query_rpzcname"); 6597 6598 labels = dns_name_countlabels(cname); 6599 if (labels > 2 && dns_name_iswildcard(cname)) { 6600 dns_fixedname_init(&prefix); 6601 dns_name_split(client->query.qname, 1, 6602 dns_fixedname_name(&prefix), NULL); 6603 dns_fixedname_init(&suffix); 6604 dns_name_split(cname, labels - 1, NULL, 6605 dns_fixedname_name(&suffix)); 6606 result = dns_name_concatenate(dns_fixedname_name(&prefix), 6607 dns_fixedname_name(&suffix), 6608 qctx->fname, NULL); 6609 if (result == DNS_R_NAMETOOLONG) { 6610 client->message->rcode = dns_rcode_yxdomain; 6611 } else if (result != ISC_R_SUCCESS) { 6612 return (result); 6613 } 6614 } else { 6615 dns_name_copynf(cname, qctx->fname); 6616 } 6617 6618 ns_client_keepname(client, qctx->fname, qctx->dbuf); 6619 result = query_addcname(qctx, dns_trust_authanswer, 6620 qctx->rpz_st->m.ttl); 6621 if (result != ISC_R_SUCCESS) { 6622 return (result); 6623 } 6624 6625 rpz_log_rewrite(client, false, qctx->rpz_st->m.policy, 6626 qctx->rpz_st->m.type, qctx->rpz_st->m.zone, 6627 qctx->rpz_st->p_name, qctx->fname, 6628 qctx->rpz_st->m.rpz->num); 6629 6630 ns_client_qnamereplace(client, qctx->fname); 6631 6632 /* 6633 * Turn off DNSSEC because the results of a 6634 * response policy zone cannot verify. 6635 */ 6636 client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC | 6637 NS_CLIENTATTR_WANTAD); 6638 6639 return (ISC_R_SUCCESS); 6640 } 6641 6642 /*% 6643 * Check the configured trust anchors for a root zone trust anchor 6644 * with a key id that matches qctx->client->query.root_key_sentinel_keyid. 6645 * 6646 * Return true when found, otherwise return false. 6647 */ 6648 static bool 6649 has_ta(query_ctx_t *qctx) { 6650 dns_keytable_t *keytable = NULL; 6651 dns_keynode_t *keynode = NULL; 6652 dns_rdataset_t dsset; 6653 dns_keytag_t sentinel = qctx->client->query.root_key_sentinel_keyid; 6654 isc_result_t result; 6655 6656 result = dns_view_getsecroots(qctx->view, &keytable); 6657 if (result != ISC_R_SUCCESS) { 6658 return (false); 6659 } 6660 6661 result = dns_keytable_find(keytable, dns_rootname, &keynode); 6662 if (result != ISC_R_SUCCESS) { 6663 if (keynode != NULL) { 6664 dns_keytable_detachkeynode(keytable, &keynode); 6665 } 6666 dns_keytable_detach(&keytable); 6667 return (false); 6668 } 6669 6670 dns_rdataset_init(&dsset); 6671 if (dns_keynode_dsset(keynode, &dsset)) { 6672 for (result = dns_rdataset_first(&dsset); 6673 result == ISC_R_SUCCESS; 6674 result = dns_rdataset_next(&dsset)) 6675 { 6676 dns_rdata_t rdata = DNS_RDATA_INIT; 6677 dns_rdata_ds_t ds; 6678 6679 dns_rdata_reset(&rdata); 6680 dns_rdataset_current(&dsset, &rdata); 6681 result = dns_rdata_tostruct(&rdata, &ds, NULL); 6682 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6683 if (ds.key_tag == sentinel) { 6684 dns_keytable_detachkeynode(keytable, &keynode); 6685 dns_keytable_detach(&keytable); 6686 dns_rdataset_disassociate(&dsset); 6687 return (true); 6688 } 6689 } 6690 dns_rdataset_disassociate(&dsset); 6691 } 6692 6693 if (keynode != NULL) { 6694 dns_keytable_detachkeynode(keytable, &keynode); 6695 } 6696 6697 dns_keytable_detach(&keytable); 6698 6699 return (false); 6700 } 6701 6702 /*% 6703 * Check if a root key sentinel SERVFAIL should be returned. 6704 */ 6705 static bool 6706 root_key_sentinel_return_servfail(query_ctx_t *qctx, isc_result_t result) { 6707 /* 6708 * Are we looking at a "root-key-sentinel" query? 6709 */ 6710 if (!qctx->client->query.root_key_sentinel_is_ta && 6711 !qctx->client->query.root_key_sentinel_not_ta) 6712 { 6713 return (false); 6714 } 6715 6716 /* 6717 * We only care about the query if 'result' indicates we have a cached 6718 * answer. 6719 */ 6720 switch (result) { 6721 case ISC_R_SUCCESS: 6722 case DNS_R_CNAME: 6723 case DNS_R_DNAME: 6724 case DNS_R_NCACHENXDOMAIN: 6725 case DNS_R_NCACHENXRRSET: 6726 break; 6727 default: 6728 return (false); 6729 } 6730 6731 /* 6732 * Do we meet the specified conditions to return SERVFAIL? 6733 */ 6734 if (!qctx->is_zone && qctx->rdataset->trust == dns_trust_secure && 6735 ((qctx->client->query.root_key_sentinel_is_ta && !has_ta(qctx)) || 6736 (qctx->client->query.root_key_sentinel_not_ta && has_ta(qctx)))) 6737 { 6738 return (true); 6739 } 6740 6741 /* 6742 * As special processing may only be triggered by the original QNAME, 6743 * disable it after following a CNAME/DNAME. 6744 */ 6745 qctx->client->query.root_key_sentinel_is_ta = false; 6746 qctx->client->query.root_key_sentinel_not_ta = false; 6747 6748 return (false); 6749 } 6750 6751 /*% 6752 * If serving stale answers is allowed, set up 'qctx' to look for one and 6753 * return true; otherwise, return false. 6754 */ 6755 static bool 6756 query_usestale(query_ctx_t *qctx) { 6757 bool staleanswersok = false; 6758 dns_ttl_t stale_ttl = 0; 6759 isc_result_t result; 6760 6761 qctx_clean(qctx); 6762 qctx_freedata(qctx); 6763 6764 /* 6765 * Stale answers only make sense if stale_ttl > 0 but we want rndc to 6766 * be able to control returning stale answers if they are configured. 6767 */ 6768 dns_db_attach(qctx->client->view->cachedb, &qctx->db); 6769 result = dns_db_getservestalettl(qctx->db, &stale_ttl); 6770 if (result == ISC_R_SUCCESS && stale_ttl > 0) { 6771 switch (qctx->client->view->staleanswersok) { 6772 case dns_stale_answer_yes: 6773 staleanswersok = true; 6774 break; 6775 case dns_stale_answer_conf: 6776 staleanswersok = qctx->client->view->staleanswersenable; 6777 break; 6778 case dns_stale_answer_no: 6779 staleanswersok = false; 6780 break; 6781 } 6782 } else { 6783 staleanswersok = false; 6784 } 6785 6786 if (staleanswersok) { 6787 qctx->client->query.dboptions |= DNS_DBFIND_STALEOK; 6788 inc_stats(qctx->client, ns_statscounter_trystale); 6789 if (qctx->client->query.fetch != NULL) { 6790 dns_resolver_destroyfetch(&qctx->client->query.fetch); 6791 } 6792 } else { 6793 dns_db_detach(&qctx->db); 6794 } 6795 6796 return (staleanswersok); 6797 } 6798 6799 /*% 6800 * Continue after doing a database lookup or returning from 6801 * recursion, and call out to the next function depending on the 6802 * result from the search. 6803 */ 6804 static isc_result_t 6805 query_gotanswer(query_ctx_t *qctx, isc_result_t res) { 6806 isc_result_t result = res; 6807 char errmsg[256]; 6808 6809 CCTRACE(ISC_LOG_DEBUG(3), "query_gotanswer"); 6810 6811 CALL_HOOK(NS_QUERY_GOT_ANSWER_BEGIN, qctx); 6812 6813 if (query_checkrrl(qctx, result) != ISC_R_SUCCESS) { 6814 return (ns_query_done(qctx)); 6815 } 6816 6817 if (!RECURSING(qctx->client) && 6818 !dns_name_equal(qctx->client->query.qname, dns_rootname)) 6819 { 6820 result = query_checkrpz(qctx, result); 6821 if (result == ISC_R_COMPLETE) { 6822 return (ns_query_done(qctx)); 6823 } 6824 } 6825 6826 /* 6827 * If required, handle special "root-key-sentinel-is-ta-<keyid>" and 6828 * "root-key-sentinel-not-ta-<keyid>" labels by returning SERVFAIL. 6829 */ 6830 if (root_key_sentinel_return_servfail(qctx, result)) { 6831 /* 6832 * Don't record this response in the SERVFAIL cache. 6833 */ 6834 qctx->client->attributes |= NS_CLIENTATTR_NOSETFC; 6835 QUERY_ERROR(qctx, DNS_R_SERVFAIL); 6836 return (ns_query_done(qctx)); 6837 } 6838 6839 switch (result) { 6840 case ISC_R_SUCCESS: 6841 return (query_prepresponse(qctx)); 6842 6843 case DNS_R_GLUE: 6844 case DNS_R_ZONECUT: 6845 INSIST(qctx->is_zone); 6846 qctx->authoritative = false; 6847 return (query_prepresponse(qctx)); 6848 6849 case ISC_R_NOTFOUND: 6850 return (query_notfound(qctx)); 6851 6852 case DNS_R_DELEGATION: 6853 return (query_delegation(qctx)); 6854 6855 case DNS_R_EMPTYNAME: 6856 return (query_nodata(qctx, DNS_R_EMPTYNAME)); 6857 case DNS_R_NXRRSET: 6858 return (query_nodata(qctx, DNS_R_NXRRSET)); 6859 6860 case DNS_R_EMPTYWILD: 6861 return (query_nxdomain(qctx, true)); 6862 6863 case DNS_R_NXDOMAIN: 6864 return (query_nxdomain(qctx, false)); 6865 6866 case DNS_R_COVERINGNSEC: 6867 return (query_coveringnsec(qctx)); 6868 6869 case DNS_R_NCACHENXDOMAIN: 6870 result = query_redirect(qctx); 6871 if (result != ISC_R_COMPLETE) { 6872 return (result); 6873 } 6874 return (query_ncache(qctx, DNS_R_NCACHENXDOMAIN)); 6875 6876 case DNS_R_NCACHENXRRSET: 6877 return (query_ncache(qctx, DNS_R_NCACHENXRRSET)); 6878 6879 case DNS_R_CNAME: 6880 return (query_cname(qctx)); 6881 6882 case DNS_R_DNAME: 6883 return (query_dname(qctx)); 6884 6885 default: 6886 /* 6887 * Something has gone wrong. 6888 */ 6889 snprintf(errmsg, sizeof(errmsg) - 1, 6890 "query_gotanswer: unexpected error: %s", 6891 isc_result_totext(result)); 6892 CCTRACE(ISC_LOG_ERROR, errmsg); 6893 if (qctx->resuming && query_usestale(qctx)) { 6894 /* 6895 * If serve-stale is enabled, query_usestale() already 6896 * set up 'qctx' for looking up a stale response. 6897 */ 6898 return (query_lookup(qctx)); 6899 } 6900 6901 /* 6902 * Regardless of the triggering result, we definitely 6903 * want to return SERVFAIL from here. 6904 */ 6905 qctx->client->rcode_override = dns_rcode_servfail; 6906 6907 QUERY_ERROR(qctx, result); 6908 return (ns_query_done(qctx)); 6909 } 6910 6911 cleanup: 6912 return (result); 6913 } 6914 6915 static void 6916 query_addnoqnameproof(query_ctx_t *qctx) { 6917 ns_client_t *client = qctx->client; 6918 isc_buffer_t *dbuf, b; 6919 dns_name_t *fname = NULL; 6920 dns_rdataset_t *neg = NULL, *negsig = NULL; 6921 isc_result_t result = ISC_R_NOMEMORY; 6922 6923 CTRACE(ISC_LOG_DEBUG(3), "query_addnoqnameproof"); 6924 6925 if (qctx->noqname == NULL) { 6926 return; 6927 } 6928 6929 dbuf = ns_client_getnamebuf(client); 6930 if (dbuf == NULL) { 6931 goto cleanup; 6932 } 6933 6934 fname = ns_client_newname(client, dbuf, &b); 6935 neg = ns_client_newrdataset(client); 6936 negsig = ns_client_newrdataset(client); 6937 if (fname == NULL || neg == NULL || negsig == NULL) { 6938 goto cleanup; 6939 } 6940 6941 result = dns_rdataset_getnoqname(qctx->noqname, fname, neg, negsig); 6942 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6943 6944 query_addrrset(qctx, &fname, &neg, &negsig, dbuf, 6945 DNS_SECTION_AUTHORITY); 6946 6947 if ((qctx->noqname->attributes & DNS_RDATASETATTR_CLOSEST) == 0) { 6948 goto cleanup; 6949 } 6950 6951 if (fname == NULL) { 6952 dbuf = ns_client_getnamebuf(client); 6953 if (dbuf == NULL) { 6954 goto cleanup; 6955 } 6956 fname = ns_client_newname(client, dbuf, &b); 6957 } 6958 6959 if (neg == NULL) { 6960 neg = ns_client_newrdataset(client); 6961 } else if (dns_rdataset_isassociated(neg)) { 6962 dns_rdataset_disassociate(neg); 6963 } 6964 6965 if (negsig == NULL) { 6966 negsig = ns_client_newrdataset(client); 6967 } else if (dns_rdataset_isassociated(negsig)) { 6968 dns_rdataset_disassociate(negsig); 6969 } 6970 6971 if (fname == NULL || neg == NULL || negsig == NULL) { 6972 goto cleanup; 6973 } 6974 result = dns_rdataset_getclosest(qctx->noqname, fname, neg, negsig); 6975 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6976 6977 query_addrrset(qctx, &fname, &neg, &negsig, dbuf, 6978 DNS_SECTION_AUTHORITY); 6979 6980 cleanup: 6981 if (neg != NULL) { 6982 ns_client_putrdataset(client, &neg); 6983 } 6984 if (negsig != NULL) { 6985 ns_client_putrdataset(client, &negsig); 6986 } 6987 if (fname != NULL) { 6988 ns_client_releasename(client, &fname); 6989 } 6990 } 6991 6992 /*% 6993 * Build the response for a query for type ANY. 6994 */ 6995 static isc_result_t 6996 query_respond_any(query_ctx_t *qctx) { 6997 bool found = false, hidden = false; 6998 dns_rdatasetiter_t *rdsiter = NULL; 6999 isc_result_t result; 7000 dns_rdatatype_t onetype = 0; /* type to use for minimal-any */ 7001 isc_buffer_t b; 7002 7003 CCTRACE(ISC_LOG_DEBUG(3), "query_respond_any"); 7004 7005 CALL_HOOK(NS_QUERY_RESPOND_ANY_BEGIN, qctx); 7006 7007 result = dns_db_allrdatasets(qctx->db, qctx->node, qctx->version, 0, 7008 &rdsiter); 7009 if (result != ISC_R_SUCCESS) { 7010 CCTRACE(ISC_LOG_ERROR, "query_respond_any: allrdatasets " 7011 "failed"); 7012 QUERY_ERROR(qctx, result); 7013 return (ns_query_done(qctx)); 7014 } 7015 7016 /* 7017 * Calling query_addrrset() with a non-NULL dbuf is going 7018 * to either keep or release the name. We don't want it to 7019 * release fname, since we may have to call query_addrrset() 7020 * more than once. That means we have to call ns_client_keepname() 7021 * now, and pass a NULL dbuf to query_addrrset(). 7022 * 7023 * If we do a query_addrrset() below, we must set qctx->fname to 7024 * NULL before leaving this block, otherwise we might try to 7025 * cleanup qctx->fname even though we're using it! 7026 */ 7027 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf); 7028 qctx->tname = qctx->fname; 7029 7030 result = dns_rdatasetiter_first(rdsiter); 7031 while (result == ISC_R_SUCCESS) { 7032 dns_rdatasetiter_current(rdsiter, qctx->rdataset); 7033 7034 /* 7035 * We found an NS RRset; no need to add one later. 7036 */ 7037 if (qctx->qtype == dns_rdatatype_any && 7038 qctx->rdataset->type == dns_rdatatype_ns) 7039 { 7040 qctx->answer_has_ns = true; 7041 } 7042 7043 /* 7044 * Note: if we're in this function, then qctx->type 7045 * is guaranteed to be ANY, but qctx->qtype (i.e. the 7046 * original type requested) might have been RRSIG or 7047 * SIG; we need to check for that. 7048 */ 7049 if (qctx->is_zone && qctx->qtype == dns_rdatatype_any && 7050 !dns_db_issecure(qctx->db) && 7051 dns_rdatatype_isdnssec(qctx->rdataset->type)) 7052 { 7053 /* 7054 * The zone may be transitioning from insecure 7055 * to secure. Hide DNSSEC records from ANY queries. 7056 */ 7057 dns_rdataset_disassociate(qctx->rdataset); 7058 hidden = true; 7059 } else if (qctx->view->minimal_any && !TCP(qctx->client) && 7060 !WANTDNSSEC(qctx->client) && 7061 qctx->qtype == dns_rdatatype_any && 7062 (qctx->rdataset->type == dns_rdatatype_sig || 7063 qctx->rdataset->type == dns_rdatatype_rrsig)) 7064 { 7065 CCTRACE(ISC_LOG_DEBUG(5), "query_respond_any: " 7066 "minimal-any skip signature"); 7067 dns_rdataset_disassociate(qctx->rdataset); 7068 } else if (qctx->view->minimal_any && !TCP(qctx->client) && 7069 onetype != 0 && qctx->rdataset->type != onetype && 7070 qctx->rdataset->covers != onetype) 7071 { 7072 CCTRACE(ISC_LOG_DEBUG(5), "query_respond_any: " 7073 "minimal-any skip rdataset"); 7074 dns_rdataset_disassociate(qctx->rdataset); 7075 } else if ((qctx->qtype == dns_rdatatype_any || 7076 qctx->rdataset->type == qctx->qtype) && 7077 qctx->rdataset->type != 0) 7078 { 7079 if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client)) 7080 { 7081 qctx->noqname = qctx->rdataset; 7082 } else { 7083 qctx->noqname = NULL; 7084 } 7085 7086 qctx->rpz_st = qctx->client->query.rpz_st; 7087 if (qctx->rpz_st != NULL) { 7088 qctx->rdataset->ttl = 7089 ISC_MIN(qctx->rdataset->ttl, 7090 qctx->rpz_st->m.ttl); 7091 } 7092 7093 if (!qctx->is_zone && RECURSIONOK(qctx->client)) { 7094 dns_name_t *name; 7095 name = (qctx->fname != NULL) ? qctx->fname 7096 : qctx->tname; 7097 query_prefetch(qctx->client, name, 7098 qctx->rdataset); 7099 } 7100 7101 /* 7102 * Remember the first RRtype we find so we 7103 * can skip others with minimal-any. 7104 */ 7105 if (qctx->rdataset->type == dns_rdatatype_sig || 7106 qctx->rdataset->type == dns_rdatatype_rrsig) 7107 { 7108 onetype = qctx->rdataset->covers; 7109 } else { 7110 onetype = qctx->rdataset->type; 7111 } 7112 7113 query_addrrset(qctx, 7114 (qctx->fname != NULL) ? &qctx->fname 7115 : &qctx->tname, 7116 &qctx->rdataset, NULL, NULL, 7117 DNS_SECTION_ANSWER); 7118 7119 query_addnoqnameproof(qctx); 7120 7121 found = true; 7122 INSIST(qctx->tname != NULL); 7123 7124 /* 7125 * rdataset is non-NULL only in certain 7126 * pathological cases involving DNAMEs. 7127 */ 7128 if (qctx->rdataset != NULL) { 7129 ns_client_putrdataset(qctx->client, 7130 &qctx->rdataset); 7131 } 7132 7133 qctx->rdataset = ns_client_newrdataset(qctx->client); 7134 if (qctx->rdataset == NULL) { 7135 break; 7136 } 7137 } else { 7138 /* 7139 * We're not interested in this rdataset. 7140 */ 7141 dns_rdataset_disassociate(qctx->rdataset); 7142 } 7143 7144 result = dns_rdatasetiter_next(rdsiter); 7145 } 7146 7147 dns_rdatasetiter_destroy(&rdsiter); 7148 7149 if (result != ISC_R_NOMORE) { 7150 CCTRACE(ISC_LOG_ERROR, "query_respond_any: rdataset iterator " 7151 "failed"); 7152 QUERY_ERROR(qctx, DNS_R_SERVFAIL); 7153 return (ns_query_done(qctx)); 7154 } 7155 7156 if (found) { 7157 /* 7158 * Call hook if any answers were found. 7159 * Do this before releasing qctx->fname, in case 7160 * the hook function needs it. 7161 */ 7162 CALL_HOOK(NS_QUERY_RESPOND_ANY_FOUND, qctx); 7163 } 7164 7165 if (qctx->fname != NULL) { 7166 dns_message_puttempname(qctx->client->message, &qctx->fname); 7167 } 7168 7169 if (found) { 7170 /* 7171 * At least one matching rdataset was found 7172 */ 7173 query_addauth(qctx); 7174 } else if (qctx->qtype == dns_rdatatype_rrsig || 7175 qctx->qtype == dns_rdatatype_sig) 7176 { 7177 /* 7178 * No matching rdatasets were found, but we got 7179 * here on a search for RRSIG/SIG, so that's okay. 7180 */ 7181 if (!qctx->is_zone) { 7182 qctx->authoritative = false; 7183 qctx->client->attributes &= ~NS_CLIENTATTR_RA; 7184 query_addauth(qctx); 7185 return (ns_query_done(qctx)); 7186 } 7187 7188 if (qctx->qtype == dns_rdatatype_rrsig && 7189 dns_db_issecure(qctx->db)) { 7190 char namebuf[DNS_NAME_FORMATSIZE]; 7191 dns_name_format(qctx->client->query.qname, namebuf, 7192 sizeof(namebuf)); 7193 ns_client_log(qctx->client, DNS_LOGCATEGORY_DNSSEC, 7194 NS_LOGMODULE_QUERY, ISC_LOG_WARNING, 7195 "missing signature for %s", namebuf); 7196 } 7197 7198 qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b); 7199 return (query_sign_nodata(qctx)); 7200 } else if (!hidden) { 7201 /* 7202 * No matching rdatasets were found and nothing was 7203 * deliberately hidden: something must have gone wrong. 7204 */ 7205 QUERY_ERROR(qctx, DNS_R_SERVFAIL); 7206 } 7207 7208 return (ns_query_done(qctx)); 7209 7210 cleanup: 7211 return (result); 7212 } 7213 7214 /* 7215 * Set the expire time, if requested, when answering from a slave, mirror, or 7216 * master zone. 7217 */ 7218 static void 7219 query_getexpire(query_ctx_t *qctx) { 7220 dns_zone_t *raw = NULL, *mayberaw; 7221 7222 CCTRACE(ISC_LOG_DEBUG(3), "query_getexpire"); 7223 7224 if (qctx->zone == NULL || !qctx->is_zone || 7225 qctx->qtype != dns_rdatatype_soa || 7226 qctx->client->query.restarts != 0 || 7227 (qctx->client->attributes & NS_CLIENTATTR_WANTEXPIRE) == 0) 7228 { 7229 return; 7230 } 7231 7232 dns_zone_getraw(qctx->zone, &raw); 7233 mayberaw = (raw != NULL) ? raw : qctx->zone; 7234 7235 if (dns_zone_gettype(mayberaw) == dns_zone_slave || 7236 dns_zone_gettype(mayberaw) == dns_zone_mirror) 7237 { 7238 isc_time_t expiretime; 7239 uint32_t secs; 7240 dns_zone_getexpiretime(qctx->zone, &expiretime); 7241 secs = isc_time_seconds(&expiretime); 7242 if (secs >= qctx->client->now && qctx->result == ISC_R_SUCCESS) 7243 { 7244 qctx->client->attributes |= NS_CLIENTATTR_HAVEEXPIRE; 7245 qctx->client->expire = secs - qctx->client->now; 7246 } 7247 } else if (dns_zone_gettype(mayberaw) == dns_zone_master) { 7248 isc_result_t result; 7249 dns_rdata_t rdata = DNS_RDATA_INIT; 7250 dns_rdata_soa_t soa; 7251 7252 result = dns_rdataset_first(qctx->rdataset); 7253 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7254 7255 dns_rdataset_current(qctx->rdataset, &rdata); 7256 result = dns_rdata_tostruct(&rdata, &soa, NULL); 7257 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7258 7259 qctx->client->expire = soa.expire; 7260 qctx->client->attributes |= NS_CLIENTATTR_HAVEEXPIRE; 7261 } 7262 7263 if (raw != NULL) { 7264 dns_zone_detach(&raw); 7265 } 7266 } 7267 7268 /*% 7269 * Fill the ANSWER section of a positive response. 7270 */ 7271 static isc_result_t 7272 query_addanswer(query_ctx_t *qctx) { 7273 dns_rdataset_t **sigrdatasetp = NULL; 7274 isc_result_t result; 7275 7276 CCTRACE(ISC_LOG_DEBUG(3), "query_addanswer"); 7277 7278 CALL_HOOK(NS_QUERY_ADDANSWER_BEGIN, qctx); 7279 7280 if (qctx->dns64) { 7281 result = query_dns64(qctx); 7282 qctx->noqname = NULL; 7283 dns_rdataset_disassociate(qctx->rdataset); 7284 dns_message_puttemprdataset(qctx->client->message, 7285 &qctx->rdataset); 7286 if (result == ISC_R_NOMORE) { 7287 #ifndef dns64_bis_return_excluded_addresses 7288 if (qctx->dns64_exclude) { 7289 if (!qctx->is_zone) { 7290 return (ns_query_done(qctx)); 7291 } 7292 /* 7293 * Add a fake SOA record. 7294 */ 7295 (void)query_addsoa(qctx, 600, 7296 DNS_SECTION_AUTHORITY); 7297 return (ns_query_done(qctx)); 7298 } 7299 #endif /* ifndef dns64_bis_return_excluded_addresses */ 7300 if (qctx->is_zone) { 7301 return (query_nodata(qctx, DNS_R_NXDOMAIN)); 7302 } else { 7303 return (query_ncache(qctx, DNS_R_NXDOMAIN)); 7304 } 7305 } else if (result != ISC_R_SUCCESS) { 7306 qctx->result = result; 7307 return (ns_query_done(qctx)); 7308 } 7309 } else if (qctx->client->query.dns64_aaaaok != NULL) { 7310 query_filter64(qctx); 7311 ns_client_putrdataset(qctx->client, &qctx->rdataset); 7312 } else { 7313 if (!qctx->is_zone && RECURSIONOK(qctx->client)) { 7314 query_prefetch(qctx->client, qctx->fname, 7315 qctx->rdataset); 7316 } 7317 if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) { 7318 sigrdatasetp = &qctx->sigrdataset; 7319 } 7320 query_addrrset(qctx, &qctx->fname, &qctx->rdataset, 7321 sigrdatasetp, qctx->dbuf, DNS_SECTION_ANSWER); 7322 } 7323 7324 return (ISC_R_COMPLETE); 7325 7326 cleanup: 7327 return (result); 7328 } 7329 7330 /*% 7331 * Build a response for a "normal" query, for a type other than ANY, 7332 * for which we have an answer (either positive or negative). 7333 */ 7334 static isc_result_t 7335 query_respond(query_ctx_t *qctx) { 7336 isc_result_t result; 7337 7338 CCTRACE(ISC_LOG_DEBUG(3), "query_respond"); 7339 7340 /* 7341 * Check to see if the AAAA RRset has non-excluded addresses 7342 * in it. If not look for a A RRset. 7343 */ 7344 INSIST(qctx->client->query.dns64_aaaaok == NULL); 7345 7346 if (qctx->qtype == dns_rdatatype_aaaa && !qctx->dns64_exclude && 7347 !ISC_LIST_EMPTY(qctx->view->dns64) && 7348 qctx->client->message->rdclass == dns_rdataclass_in && 7349 !dns64_aaaaok(qctx->client, qctx->rdataset, qctx->sigrdataset)) 7350 { 7351 /* 7352 * Look to see if there are A records for this name. 7353 */ 7354 qctx->client->query.dns64_ttl = qctx->rdataset->ttl; 7355 SAVE(qctx->client->query.dns64_aaaa, qctx->rdataset); 7356 SAVE(qctx->client->query.dns64_sigaaaa, qctx->sigrdataset); 7357 ns_client_releasename(qctx->client, &qctx->fname); 7358 dns_db_detachnode(qctx->db, &qctx->node); 7359 qctx->type = qctx->qtype = dns_rdatatype_a; 7360 qctx->dns64_exclude = qctx->dns64 = true; 7361 7362 return (query_lookup(qctx)); 7363 } 7364 7365 /* 7366 * XXX: This hook is meant to be at the top of this function, 7367 * but is postponed until after DNS64 in order to avoid an 7368 * assertion if the hook causes recursion. (When DNS64 also 7369 * becomes a plugin, it will be necessary to find some 7370 * other way to prevent that assertion, since the order in 7371 * which plugins are configured can't be enforced.) 7372 */ 7373 CALL_HOOK(NS_QUERY_RESPOND_BEGIN, qctx); 7374 7375 if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client)) { 7376 qctx->noqname = qctx->rdataset; 7377 } else { 7378 qctx->noqname = NULL; 7379 } 7380 7381 /* 7382 * Special case NS handling 7383 */ 7384 if (qctx->is_zone && qctx->qtype == dns_rdatatype_ns) { 7385 /* 7386 * We've already got an NS, no need to add one in 7387 * the authority section 7388 */ 7389 if (dns_name_equal(qctx->client->query.qname, 7390 dns_db_origin(qctx->db))) { 7391 qctx->answer_has_ns = true; 7392 } 7393 7394 /* 7395 * Always add glue for root priming queries, regardless 7396 * of "minimal-responses" setting. 7397 */ 7398 if (dns_name_equal(qctx->client->query.qname, dns_rootname)) { 7399 qctx->client->query.attributes &= 7400 ~NS_QUERYATTR_NOADDITIONAL; 7401 dns_db_attach(qctx->db, &qctx->client->query.gluedb); 7402 } 7403 } 7404 7405 /* 7406 * Set expire time 7407 */ 7408 query_getexpire(qctx); 7409 7410 result = query_addanswer(qctx); 7411 if (result != ISC_R_COMPLETE) { 7412 return (result); 7413 } 7414 7415 query_addnoqnameproof(qctx); 7416 7417 /* 7418 * We shouldn't ever fail to add 'rdataset' 7419 * because it's already in the answer. 7420 */ 7421 INSIST(qctx->rdataset == NULL); 7422 7423 query_addauth(qctx); 7424 7425 return (ns_query_done(qctx)); 7426 7427 cleanup: 7428 return (result); 7429 } 7430 7431 static isc_result_t 7432 query_dns64(query_ctx_t *qctx) { 7433 ns_client_t *client = qctx->client; 7434 dns_aclenv_t *env = 7435 ns_interfacemgr_getaclenv(client->manager->interface->mgr); 7436 dns_name_t *name, *mname; 7437 dns_rdata_t *dns64_rdata; 7438 dns_rdata_t rdata = DNS_RDATA_INIT; 7439 dns_rdatalist_t *dns64_rdatalist; 7440 dns_rdataset_t *dns64_rdataset; 7441 dns_rdataset_t *mrdataset; 7442 isc_buffer_t *buffer; 7443 isc_region_t r; 7444 isc_result_t result; 7445 dns_view_t *view = client->view; 7446 isc_netaddr_t netaddr; 7447 dns_dns64_t *dns64; 7448 unsigned int flags = 0; 7449 const dns_section_t section = DNS_SECTION_ANSWER; 7450 7451 /*% 7452 * To the current response for 'qctx->client', add the answer RRset 7453 * '*rdatasetp' and an optional signature set '*sigrdatasetp', with 7454 * owner name '*namep', to the answer section, unless they are 7455 * already there. Also add any pertinent additional data. 7456 * 7457 * If 'qctx->dbuf' is not NULL, then 'qctx->fname' is the name 7458 * whose data is stored 'qctx->dbuf'. In this case, 7459 * query_addrrset() guarantees that when it returns the name 7460 * will either have been kept or released. 7461 */ 7462 CTRACE(ISC_LOG_DEBUG(3), "query_dns64"); 7463 7464 qctx->qtype = qctx->type = dns_rdatatype_aaaa; 7465 7466 name = qctx->fname; 7467 mname = NULL; 7468 mrdataset = NULL; 7469 buffer = NULL; 7470 dns64_rdata = NULL; 7471 dns64_rdataset = NULL; 7472 dns64_rdatalist = NULL; 7473 result = dns_message_findname( 7474 client->message, section, name, dns_rdatatype_aaaa, 7475 qctx->rdataset->covers, &mname, &mrdataset); 7476 if (result == ISC_R_SUCCESS) { 7477 /* 7478 * We've already got an RRset of the given name and type. 7479 * There's nothing else to do; 7480 */ 7481 CTRACE(ISC_LOG_DEBUG(3), "query_dns64: dns_message_findname " 7482 "succeeded: done"); 7483 if (qctx->dbuf != NULL) { 7484 ns_client_releasename(client, &qctx->fname); 7485 } 7486 return (ISC_R_SUCCESS); 7487 } else if (result == DNS_R_NXDOMAIN) { 7488 /* 7489 * The name doesn't exist. 7490 */ 7491 if (qctx->dbuf != NULL) { 7492 ns_client_keepname(client, name, qctx->dbuf); 7493 } 7494 dns_message_addname(client->message, name, section); 7495 qctx->fname = NULL; 7496 mname = name; 7497 } else { 7498 RUNTIME_CHECK(result == DNS_R_NXRRSET); 7499 if (qctx->dbuf != NULL) { 7500 ns_client_releasename(client, &qctx->fname); 7501 } 7502 } 7503 7504 if (qctx->rdataset->trust != dns_trust_secure) { 7505 client->query.attributes &= ~NS_QUERYATTR_SECURE; 7506 } 7507 7508 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); 7509 7510 isc_buffer_allocate(client->mctx, &buffer, 7511 view->dns64cnt * 16 * 7512 dns_rdataset_count(qctx->rdataset)); 7513 result = dns_message_gettemprdataset(client->message, &dns64_rdataset); 7514 if (result != ISC_R_SUCCESS) { 7515 goto cleanup; 7516 } 7517 result = dns_message_gettemprdatalist(client->message, 7518 &dns64_rdatalist); 7519 if (result != ISC_R_SUCCESS) { 7520 goto cleanup; 7521 } 7522 7523 dns_rdatalist_init(dns64_rdatalist); 7524 dns64_rdatalist->rdclass = dns_rdataclass_in; 7525 dns64_rdatalist->type = dns_rdatatype_aaaa; 7526 if (client->query.dns64_ttl != UINT32_MAX) { 7527 dns64_rdatalist->ttl = ISC_MIN(qctx->rdataset->ttl, 7528 client->query.dns64_ttl); 7529 } else { 7530 dns64_rdatalist->ttl = ISC_MIN(qctx->rdataset->ttl, 600); 7531 } 7532 7533 if (RECURSIONOK(client)) { 7534 flags |= DNS_DNS64_RECURSIVE; 7535 } 7536 7537 /* 7538 * We use the signatures from the A lookup to set DNS_DNS64_DNSSEC 7539 * as this provides a easy way to see if the answer was signed. 7540 */ 7541 if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL && 7542 dns_rdataset_isassociated(qctx->sigrdataset)) 7543 { 7544 flags |= DNS_DNS64_DNSSEC; 7545 } 7546 7547 for (result = dns_rdataset_first(qctx->rdataset); 7548 result == ISC_R_SUCCESS; 7549 result = dns_rdataset_next(qctx->rdataset)) 7550 { 7551 for (dns64 = ISC_LIST_HEAD(client->view->dns64); dns64 != NULL; 7552 dns64 = dns_dns64_next(dns64)) 7553 { 7554 dns_rdataset_current(qctx->rdataset, &rdata); 7555 isc_buffer_availableregion(buffer, &r); 7556 INSIST(r.length >= 16); 7557 result = dns_dns64_aaaafroma(dns64, &netaddr, 7558 client->signer, env, flags, 7559 rdata.data, r.base); 7560 if (result != ISC_R_SUCCESS) { 7561 dns_rdata_reset(&rdata); 7562 continue; 7563 } 7564 isc_buffer_add(buffer, 16); 7565 isc_buffer_remainingregion(buffer, &r); 7566 isc_buffer_forward(buffer, 16); 7567 result = dns_message_gettemprdata(client->message, 7568 &dns64_rdata); 7569 if (result != ISC_R_SUCCESS) { 7570 goto cleanup; 7571 } 7572 dns_rdata_init(dns64_rdata); 7573 dns_rdata_fromregion(dns64_rdata, dns_rdataclass_in, 7574 dns_rdatatype_aaaa, &r); 7575 ISC_LIST_APPEND(dns64_rdatalist->rdata, dns64_rdata, 7576 link); 7577 dns64_rdata = NULL; 7578 dns_rdata_reset(&rdata); 7579 } 7580 } 7581 if (result != ISC_R_NOMORE) { 7582 goto cleanup; 7583 } 7584 7585 if (ISC_LIST_EMPTY(dns64_rdatalist->rdata)) { 7586 goto cleanup; 7587 } 7588 7589 result = dns_rdatalist_tordataset(dns64_rdatalist, dns64_rdataset); 7590 if (result != ISC_R_SUCCESS) { 7591 goto cleanup; 7592 } 7593 dns_rdataset_setownercase(dns64_rdataset, mname); 7594 client->query.attributes |= NS_QUERYATTR_NOADDITIONAL; 7595 dns64_rdataset->trust = qctx->rdataset->trust; 7596 7597 query_addtoname(mname, dns64_rdataset); 7598 query_setorder(qctx, mname, dns64_rdataset); 7599 7600 dns64_rdataset = NULL; 7601 dns64_rdatalist = NULL; 7602 dns_message_takebuffer(client->message, &buffer); 7603 inc_stats(client, ns_statscounter_dns64); 7604 result = ISC_R_SUCCESS; 7605 7606 cleanup: 7607 if (buffer != NULL) { 7608 isc_buffer_free(&buffer); 7609 } 7610 7611 if (dns64_rdata != NULL) { 7612 dns_message_puttemprdata(client->message, &dns64_rdata); 7613 } 7614 7615 if (dns64_rdataset != NULL) { 7616 dns_message_puttemprdataset(client->message, &dns64_rdataset); 7617 } 7618 7619 if (dns64_rdatalist != NULL) { 7620 for (dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata); 7621 dns64_rdata != NULL; 7622 dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata)) 7623 { 7624 ISC_LIST_UNLINK(dns64_rdatalist->rdata, dns64_rdata, 7625 link); 7626 dns_message_puttemprdata(client->message, &dns64_rdata); 7627 } 7628 dns_message_puttemprdatalist(client->message, &dns64_rdatalist); 7629 } 7630 7631 CTRACE(ISC_LOG_DEBUG(3), "query_dns64: done"); 7632 return (result); 7633 } 7634 7635 static void 7636 query_filter64(query_ctx_t *qctx) { 7637 ns_client_t *client = qctx->client; 7638 dns_name_t *name, *mname; 7639 dns_rdata_t *myrdata; 7640 dns_rdata_t rdata = DNS_RDATA_INIT; 7641 dns_rdatalist_t *myrdatalist; 7642 dns_rdataset_t *myrdataset; 7643 isc_buffer_t *buffer; 7644 isc_region_t r; 7645 isc_result_t result; 7646 unsigned int i; 7647 const dns_section_t section = DNS_SECTION_ANSWER; 7648 7649 CTRACE(ISC_LOG_DEBUG(3), "query_filter64"); 7650 7651 INSIST(client->query.dns64_aaaaok != NULL); 7652 INSIST(client->query.dns64_aaaaoklen == 7653 dns_rdataset_count(qctx->rdataset)); 7654 7655 name = qctx->fname; 7656 mname = NULL; 7657 buffer = NULL; 7658 myrdata = NULL; 7659 myrdataset = NULL; 7660 myrdatalist = NULL; 7661 result = dns_message_findname( 7662 client->message, section, name, dns_rdatatype_aaaa, 7663 qctx->rdataset->covers, &mname, &myrdataset); 7664 if (result == ISC_R_SUCCESS) { 7665 /* 7666 * We've already got an RRset of the given name and type. 7667 * There's nothing else to do; 7668 */ 7669 CTRACE(ISC_LOG_DEBUG(3), "query_filter64: dns_message_findname " 7670 "succeeded: done"); 7671 if (qctx->dbuf != NULL) { 7672 ns_client_releasename(client, &qctx->fname); 7673 } 7674 return; 7675 } else if (result == DNS_R_NXDOMAIN) { 7676 mname = name; 7677 qctx->fname = NULL; 7678 } else { 7679 RUNTIME_CHECK(result == DNS_R_NXRRSET); 7680 if (qctx->dbuf != NULL) { 7681 ns_client_releasename(client, &qctx->fname); 7682 } 7683 qctx->dbuf = NULL; 7684 } 7685 7686 if (qctx->rdataset->trust != dns_trust_secure) { 7687 client->query.attributes &= ~NS_QUERYATTR_SECURE; 7688 } 7689 7690 isc_buffer_allocate(client->mctx, &buffer, 7691 16 * dns_rdataset_count(qctx->rdataset)); 7692 result = dns_message_gettemprdataset(client->message, &myrdataset); 7693 if (result != ISC_R_SUCCESS) { 7694 goto cleanup; 7695 } 7696 result = dns_message_gettemprdatalist(client->message, &myrdatalist); 7697 if (result != ISC_R_SUCCESS) { 7698 goto cleanup; 7699 } 7700 7701 dns_rdatalist_init(myrdatalist); 7702 myrdatalist->rdclass = dns_rdataclass_in; 7703 myrdatalist->type = dns_rdatatype_aaaa; 7704 myrdatalist->ttl = qctx->rdataset->ttl; 7705 7706 i = 0; 7707 for (result = dns_rdataset_first(qctx->rdataset); 7708 result == ISC_R_SUCCESS; 7709 result = dns_rdataset_next(qctx->rdataset)) 7710 { 7711 if (!client->query.dns64_aaaaok[i++]) { 7712 continue; 7713 } 7714 dns_rdataset_current(qctx->rdataset, &rdata); 7715 INSIST(rdata.length == 16); 7716 isc_buffer_putmem(buffer, rdata.data, rdata.length); 7717 isc_buffer_remainingregion(buffer, &r); 7718 isc_buffer_forward(buffer, rdata.length); 7719 result = dns_message_gettemprdata(client->message, &myrdata); 7720 if (result != ISC_R_SUCCESS) { 7721 goto cleanup; 7722 } 7723 dns_rdata_init(myrdata); 7724 dns_rdata_fromregion(myrdata, dns_rdataclass_in, 7725 dns_rdatatype_aaaa, &r); 7726 ISC_LIST_APPEND(myrdatalist->rdata, myrdata, link); 7727 myrdata = NULL; 7728 dns_rdata_reset(&rdata); 7729 } 7730 if (result != ISC_R_NOMORE) { 7731 goto cleanup; 7732 } 7733 7734 result = dns_rdatalist_tordataset(myrdatalist, myrdataset); 7735 if (result != ISC_R_SUCCESS) { 7736 goto cleanup; 7737 } 7738 dns_rdataset_setownercase(myrdataset, name); 7739 client->query.attributes |= NS_QUERYATTR_NOADDITIONAL; 7740 if (mname == name) { 7741 if (qctx->dbuf != NULL) { 7742 ns_client_keepname(client, name, qctx->dbuf); 7743 } 7744 dns_message_addname(client->message, name, section); 7745 qctx->dbuf = NULL; 7746 } 7747 myrdataset->trust = qctx->rdataset->trust; 7748 7749 query_addtoname(mname, myrdataset); 7750 query_setorder(qctx, mname, myrdataset); 7751 7752 myrdataset = NULL; 7753 myrdatalist = NULL; 7754 dns_message_takebuffer(client->message, &buffer); 7755 7756 cleanup: 7757 if (buffer != NULL) { 7758 isc_buffer_free(&buffer); 7759 } 7760 7761 if (myrdata != NULL) { 7762 dns_message_puttemprdata(client->message, &myrdata); 7763 } 7764 7765 if (myrdataset != NULL) { 7766 dns_message_puttemprdataset(client->message, &myrdataset); 7767 } 7768 7769 if (myrdatalist != NULL) { 7770 for (myrdata = ISC_LIST_HEAD(myrdatalist->rdata); 7771 myrdata != NULL; 7772 myrdata = ISC_LIST_HEAD(myrdatalist->rdata)) 7773 { 7774 ISC_LIST_UNLINK(myrdatalist->rdata, myrdata, link); 7775 dns_message_puttemprdata(client->message, &myrdata); 7776 } 7777 dns_message_puttemprdatalist(client->message, &myrdatalist); 7778 } 7779 if (qctx->dbuf != NULL) { 7780 ns_client_releasename(client, &name); 7781 } 7782 7783 CTRACE(ISC_LOG_DEBUG(3), "query_filter64: done"); 7784 } 7785 7786 /*% 7787 * Handle the case of a name not being found in a database lookup. 7788 * Called from query_gotanswer(). Passes off processing to 7789 * query_delegation() for a root referral if appropriate. 7790 */ 7791 static isc_result_t 7792 query_notfound(query_ctx_t *qctx) { 7793 isc_result_t result; 7794 7795 CCTRACE(ISC_LOG_DEBUG(3), "query_notfound"); 7796 7797 CALL_HOOK(NS_QUERY_NOTFOUND_BEGIN, qctx); 7798 7799 INSIST(!qctx->is_zone); 7800 7801 if (qctx->db != NULL) { 7802 dns_db_detach(&qctx->db); 7803 } 7804 7805 /* 7806 * If the cache doesn't even have the root NS, 7807 * try to get that from the hints DB. 7808 */ 7809 if (qctx->view->hints != NULL) { 7810 dns_clientinfomethods_t cm; 7811 dns_clientinfo_t ci; 7812 7813 dns_clientinfomethods_init(&cm, ns_client_sourceip); 7814 dns_clientinfo_init(&ci, qctx->client, NULL); 7815 7816 dns_db_attach(qctx->view->hints, &qctx->db); 7817 result = dns_db_findext(qctx->db, dns_rootname, NULL, 7818 dns_rdatatype_ns, 0, qctx->client->now, 7819 &qctx->node, qctx->fname, &cm, &ci, 7820 qctx->rdataset, qctx->sigrdataset); 7821 } else { 7822 /* We have no hints. */ 7823 result = ISC_R_FAILURE; 7824 } 7825 if (result != ISC_R_SUCCESS) { 7826 /* 7827 * Nonsensical root hints may require cleanup. 7828 */ 7829 qctx_clean(qctx); 7830 7831 /* 7832 * We don't have any root server hints, but 7833 * we may have working forwarders, so try to 7834 * recurse anyway. 7835 */ 7836 if (RECURSIONOK(qctx->client)) { 7837 INSIST(!REDIRECT(qctx->client)); 7838 result = ns_query_recurse(qctx->client, qctx->qtype, 7839 qctx->client->query.qname, 7840 NULL, NULL, qctx->resuming); 7841 if (result == ISC_R_SUCCESS) { 7842 CALL_HOOK(NS_QUERY_NOTFOUND_RECURSE, qctx); 7843 qctx->client->query.attributes |= 7844 NS_QUERYATTR_RECURSING; 7845 7846 if (qctx->dns64) { 7847 qctx->client->query.attributes |= 7848 NS_QUERYATTR_DNS64; 7849 } 7850 if (qctx->dns64_exclude) { 7851 qctx->client->query.attributes |= 7852 NS_QUERYATTR_DNS64EXCLUDE; 7853 } 7854 } else { 7855 QUERY_ERROR(qctx, result); 7856 } 7857 return (ns_query_done(qctx)); 7858 } else { 7859 /* Unable to give root server referral. */ 7860 CCTRACE(ISC_LOG_ERROR, "unable to give root server " 7861 "referral"); 7862 QUERY_ERROR(qctx, result); 7863 return (ns_query_done(qctx)); 7864 } 7865 } 7866 7867 return (query_delegation(qctx)); 7868 7869 cleanup: 7870 return (result); 7871 } 7872 7873 /*% 7874 * We have a delegation but recursion is not allowed, so return the delegation 7875 * to the client. 7876 */ 7877 static isc_result_t 7878 query_prepare_delegation_response(query_ctx_t *qctx) { 7879 isc_result_t result; 7880 dns_rdataset_t **sigrdatasetp = NULL; 7881 bool detach = false; 7882 7883 CALL_HOOK(NS_QUERY_PREP_DELEGATION_BEGIN, qctx); 7884 7885 /* 7886 * qctx->fname could be released in query_addrrset(), so save a copy of 7887 * it here in case we need it. 7888 */ 7889 dns_fixedname_init(&qctx->dsname); 7890 dns_name_copynf(qctx->fname, dns_fixedname_name(&qctx->dsname)); 7891 7892 /* 7893 * This is the best answer. 7894 */ 7895 qctx->client->query.isreferral = true; 7896 7897 if (!dns_db_iscache(qctx->db) && qctx->client->query.gluedb == NULL) { 7898 dns_db_attach(qctx->db, &qctx->client->query.gluedb); 7899 detach = true; 7900 } 7901 7902 /* 7903 * We must ensure NOADDITIONAL is off, because the generation of 7904 * additional data is required in delegations. 7905 */ 7906 qctx->client->query.attributes &= ~NS_QUERYATTR_NOADDITIONAL; 7907 if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) { 7908 sigrdatasetp = &qctx->sigrdataset; 7909 } 7910 query_addrrset(qctx, &qctx->fname, &qctx->rdataset, sigrdatasetp, 7911 qctx->dbuf, DNS_SECTION_AUTHORITY); 7912 if (detach) { 7913 dns_db_detach(&qctx->client->query.gluedb); 7914 } 7915 7916 /* 7917 * Add a DS if needed. 7918 */ 7919 query_addds(qctx); 7920 7921 return (ns_query_done(qctx)); 7922 7923 cleanup: 7924 return (result); 7925 } 7926 7927 /*% 7928 * Handle a delegation response from an authoritative lookup. This 7929 * may trigger additional lookups, e.g. from the cache database to 7930 * see if we have a better answer; if that is not allowed, return the 7931 * delegation to the client and call ns_query_done(). 7932 */ 7933 static isc_result_t 7934 query_zone_delegation(query_ctx_t *qctx) { 7935 isc_result_t result; 7936 7937 CALL_HOOK(NS_QUERY_ZONE_DELEGATION_BEGIN, qctx); 7938 7939 /* 7940 * If the query type is DS, look to see if we are 7941 * authoritative for the child zone 7942 */ 7943 if (!RECURSIONOK(qctx->client) && 7944 (qctx->options & DNS_GETDB_NOEXACT) != 0 && 7945 qctx->qtype == dns_rdatatype_ds) 7946 { 7947 dns_db_t *tdb = NULL; 7948 dns_zone_t *tzone = NULL; 7949 dns_dbversion_t *tversion = NULL; 7950 result = query_getzonedb( 7951 qctx->client, qctx->client->query.qname, qctx->qtype, 7952 DNS_GETDB_PARTIAL, &tzone, &tdb, &tversion); 7953 if (result != ISC_R_SUCCESS) { 7954 if (tdb != NULL) { 7955 dns_db_detach(&tdb); 7956 } 7957 if (tzone != NULL) { 7958 dns_zone_detach(&tzone); 7959 } 7960 } else { 7961 qctx->options &= ~DNS_GETDB_NOEXACT; 7962 ns_client_putrdataset(qctx->client, &qctx->rdataset); 7963 if (qctx->sigrdataset != NULL) { 7964 ns_client_putrdataset(qctx->client, 7965 &qctx->sigrdataset); 7966 } 7967 if (qctx->fname != NULL) { 7968 ns_client_releasename(qctx->client, 7969 &qctx->fname); 7970 } 7971 if (qctx->node != NULL) { 7972 dns_db_detachnode(qctx->db, &qctx->node); 7973 } 7974 if (qctx->db != NULL) { 7975 dns_db_detach(&qctx->db); 7976 } 7977 if (qctx->zone != NULL) { 7978 dns_zone_detach(&qctx->zone); 7979 } 7980 qctx->version = NULL; 7981 RESTORE(qctx->version, tversion); 7982 RESTORE(qctx->db, tdb); 7983 RESTORE(qctx->zone, tzone); 7984 qctx->authoritative = true; 7985 7986 return (query_lookup(qctx)); 7987 } 7988 } 7989 7990 if (USECACHE(qctx->client) && 7991 (RECURSIONOK(qctx->client) || 7992 (qctx->zone != NULL && 7993 dns_zone_gettype(qctx->zone) == dns_zone_mirror))) 7994 { 7995 /* 7996 * We might have a better answer or delegation in the 7997 * cache. We'll remember the current values of fname, 7998 * rdataset, and sigrdataset. We'll then go looking for 7999 * QNAME in the cache. If we find something better, we'll 8000 * use it instead. If not, then query_lookup() calls 8001 * query_notfound() which calls query_delegation(), and 8002 * we'll restore these values there. 8003 */ 8004 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf); 8005 SAVE(qctx->zdb, qctx->db); 8006 SAVE(qctx->znode, qctx->node); 8007 SAVE(qctx->zfname, qctx->fname); 8008 SAVE(qctx->zversion, qctx->version); 8009 SAVE(qctx->zrdataset, qctx->rdataset); 8010 SAVE(qctx->zsigrdataset, qctx->sigrdataset); 8011 dns_db_attach(qctx->view->cachedb, &qctx->db); 8012 qctx->is_zone = false; 8013 8014 return (query_lookup(qctx)); 8015 } 8016 8017 return (query_prepare_delegation_response(qctx)); 8018 8019 cleanup: 8020 return (result); 8021 } 8022 8023 /*% 8024 * Handle delegation responses, including root referrals. 8025 * 8026 * If the delegation was returned from authoritative data, 8027 * call query_zone_delgation(). Otherwise, we can start 8028 * recursion if allowed; or else return the delegation to the 8029 * client and call ns_query_done(). 8030 */ 8031 static isc_result_t 8032 query_delegation(query_ctx_t *qctx) { 8033 isc_result_t result; 8034 8035 CCTRACE(ISC_LOG_DEBUG(3), "query_delegation"); 8036 8037 CALL_HOOK(NS_QUERY_DELEGATION_BEGIN, qctx); 8038 8039 qctx->authoritative = false; 8040 8041 if (qctx->is_zone) { 8042 return (query_zone_delegation(qctx)); 8043 } 8044 8045 if (qctx->zfname != NULL && 8046 (!dns_name_issubdomain(qctx->fname, qctx->zfname) || 8047 (qctx->is_staticstub_zone && 8048 dns_name_equal(qctx->fname, qctx->zfname)))) 8049 { 8050 /* 8051 * In the following cases use "authoritative" 8052 * data instead of the cache delegation: 8053 * 1. We've already got a delegation from 8054 * authoritative data, and it is better 8055 * than what we found in the cache. 8056 * (See the comment above.) 8057 * 2. The query name matches the origin name 8058 * of a static-stub zone. This needs to be 8059 * considered for the case where the NS of 8060 * the static-stub zone and the cached NS 8061 * are different. We still need to contact 8062 * the nameservers configured in the 8063 * static-stub zone. 8064 */ 8065 ns_client_releasename(qctx->client, &qctx->fname); 8066 8067 /* 8068 * We've already done ns_client_keepname() on 8069 * qctx->zfname, so we must set dbuf to NULL to 8070 * prevent query_addrrset() from trying to 8071 * call ns_client_keepname() again. 8072 */ 8073 qctx->dbuf = NULL; 8074 ns_client_putrdataset(qctx->client, &qctx->rdataset); 8075 if (qctx->sigrdataset != NULL) { 8076 ns_client_putrdataset(qctx->client, &qctx->sigrdataset); 8077 } 8078 qctx->version = NULL; 8079 8080 dns_db_detachnode(qctx->db, &qctx->node); 8081 dns_db_detach(&qctx->db); 8082 RESTORE(qctx->db, qctx->zdb); 8083 RESTORE(qctx->node, qctx->znode); 8084 RESTORE(qctx->fname, qctx->zfname); 8085 RESTORE(qctx->version, qctx->zversion); 8086 RESTORE(qctx->rdataset, qctx->zrdataset); 8087 RESTORE(qctx->sigrdataset, qctx->zsigrdataset); 8088 } 8089 8090 result = query_delegation_recurse(qctx); 8091 if (result != ISC_R_COMPLETE) { 8092 return (result); 8093 } 8094 8095 return (query_prepare_delegation_response(qctx)); 8096 8097 cleanup: 8098 return (result); 8099 } 8100 8101 /*% 8102 * Handle recursive queries that are triggered as part of the 8103 * delegation process. 8104 */ 8105 static isc_result_t 8106 query_delegation_recurse(query_ctx_t *qctx) { 8107 isc_result_t result; 8108 dns_name_t *qname = qctx->client->query.qname; 8109 8110 CCTRACE(ISC_LOG_DEBUG(3), "query_delegation_recurse"); 8111 8112 if (!RECURSIONOK(qctx->client)) { 8113 return (ISC_R_COMPLETE); 8114 } 8115 8116 CALL_HOOK(NS_QUERY_DELEGATION_RECURSE_BEGIN, qctx); 8117 8118 /* 8119 * We have a delegation and recursion is allowed, 8120 * so we call ns_query_recurse() to follow it. 8121 * This phase of the query processing is done; 8122 * we'll resume via fetch_callback() and 8123 * query_resume() when the recursion is complete. 8124 */ 8125 8126 INSIST(!REDIRECT(qctx->client)); 8127 8128 if (dns_rdatatype_atparent(qctx->type)) { 8129 /* 8130 * Parent is authoritative for this RDATA type (i.e. DS). 8131 */ 8132 result = ns_query_recurse(qctx->client, qctx->qtype, qname, 8133 NULL, NULL, qctx->resuming); 8134 } else if (qctx->dns64) { 8135 /* 8136 * Look up an A record so we can synthesize DNS64. 8137 */ 8138 result = ns_query_recurse(qctx->client, dns_rdatatype_a, qname, 8139 NULL, NULL, qctx->resuming); 8140 } else { 8141 /* 8142 * Any other recursion. 8143 */ 8144 result = ns_query_recurse(qctx->client, qctx->qtype, qname, 8145 qctx->fname, qctx->rdataset, 8146 qctx->resuming); 8147 } 8148 8149 if (result == ISC_R_SUCCESS) { 8150 qctx->client->query.attributes |= NS_QUERYATTR_RECURSING; 8151 if (qctx->dns64) { 8152 qctx->client->query.attributes |= NS_QUERYATTR_DNS64; 8153 } 8154 if (qctx->dns64_exclude) { 8155 qctx->client->query.attributes |= 8156 NS_QUERYATTR_DNS64EXCLUDE; 8157 } 8158 } else { 8159 QUERY_ERROR(qctx, result); 8160 } 8161 8162 return (ns_query_done(qctx)); 8163 8164 cleanup: 8165 return (result); 8166 } 8167 8168 /*% 8169 * Add a DS record if needed. 8170 */ 8171 static void 8172 query_addds(query_ctx_t *qctx) { 8173 ns_client_t *client = qctx->client; 8174 dns_fixedname_t fixed; 8175 dns_name_t *fname = NULL; 8176 dns_name_t *rname = NULL; 8177 dns_name_t *name; 8178 dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; 8179 isc_buffer_t *dbuf, b; 8180 isc_result_t result; 8181 unsigned int count; 8182 8183 CTRACE(ISC_LOG_DEBUG(3), "query_addds"); 8184 8185 /* 8186 * DS not needed. 8187 */ 8188 if (!WANTDNSSEC(client)) { 8189 return; 8190 } 8191 8192 /* 8193 * We'll need some resources... 8194 */ 8195 rdataset = ns_client_newrdataset(client); 8196 sigrdataset = ns_client_newrdataset(client); 8197 if (rdataset == NULL || sigrdataset == NULL) { 8198 goto cleanup; 8199 } 8200 8201 /* 8202 * Look for the DS record, which may or may not be present. 8203 */ 8204 result = dns_db_findrdataset(qctx->db, qctx->node, qctx->version, 8205 dns_rdatatype_ds, 0, client->now, rdataset, 8206 sigrdataset); 8207 /* 8208 * If we didn't find it, look for an NSEC. 8209 */ 8210 if (result == ISC_R_NOTFOUND) { 8211 result = dns_db_findrdataset( 8212 qctx->db, qctx->node, qctx->version, dns_rdatatype_nsec, 8213 0, client->now, rdataset, sigrdataset); 8214 } 8215 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 8216 goto addnsec3; 8217 } 8218 if (!dns_rdataset_isassociated(rdataset) || 8219 !dns_rdataset_isassociated(sigrdataset)) 8220 { 8221 goto addnsec3; 8222 } 8223 8224 /* 8225 * We've already added the NS record, so if the name's not there, 8226 * we have other problems. Use this name rather than calling 8227 * query_addrrset(). 8228 */ 8229 result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY); 8230 if (result != ISC_R_SUCCESS) { 8231 goto cleanup; 8232 } 8233 8234 rname = NULL; 8235 dns_message_currentname(client->message, DNS_SECTION_AUTHORITY, &rname); 8236 result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL); 8237 if (result != ISC_R_SUCCESS) { 8238 goto cleanup; 8239 } 8240 8241 ISC_LIST_APPEND(rname->list, rdataset, link); 8242 ISC_LIST_APPEND(rname->list, sigrdataset, link); 8243 rdataset = NULL; 8244 sigrdataset = NULL; 8245 return; 8246 8247 addnsec3: 8248 if (!dns_db_iszone(qctx->db)) { 8249 goto cleanup; 8250 } 8251 /* 8252 * Add the NSEC3 which proves the DS does not exist. 8253 */ 8254 dbuf = ns_client_getnamebuf(client); 8255 if (dbuf == NULL) { 8256 goto cleanup; 8257 } 8258 fname = ns_client_newname(client, dbuf, &b); 8259 dns_fixedname_init(&fixed); 8260 if (dns_rdataset_isassociated(rdataset)) { 8261 dns_rdataset_disassociate(rdataset); 8262 } 8263 if (dns_rdataset_isassociated(sigrdataset)) { 8264 dns_rdataset_disassociate(sigrdataset); 8265 } 8266 name = dns_fixedname_name(&qctx->dsname); 8267 query_findclosestnsec3(name, qctx->db, qctx->version, client, rdataset, 8268 sigrdataset, fname, true, 8269 dns_fixedname_name(&fixed)); 8270 if (!dns_rdataset_isassociated(rdataset)) { 8271 goto cleanup; 8272 } 8273 query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf, 8274 DNS_SECTION_AUTHORITY); 8275 /* 8276 * Did we find the closest provable encloser instead? 8277 * If so add the nearest to the closest provable encloser. 8278 */ 8279 if (!dns_name_equal(name, dns_fixedname_name(&fixed))) { 8280 count = dns_name_countlabels(dns_fixedname_name(&fixed)) + 1; 8281 dns_name_getlabelsequence(name, 8282 dns_name_countlabels(name) - count, 8283 count, dns_fixedname_name(&fixed)); 8284 fixfname(client, &fname, &dbuf, &b); 8285 fixrdataset(client, &rdataset); 8286 fixrdataset(client, &sigrdataset); 8287 if (fname == NULL || rdataset == NULL || sigrdataset == NULL) { 8288 goto cleanup; 8289 } 8290 query_findclosestnsec3(dns_fixedname_name(&fixed), qctx->db, 8291 qctx->version, client, rdataset, 8292 sigrdataset, fname, false, NULL); 8293 if (!dns_rdataset_isassociated(rdataset)) { 8294 goto cleanup; 8295 } 8296 query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf, 8297 DNS_SECTION_AUTHORITY); 8298 } 8299 8300 cleanup: 8301 if (rdataset != NULL) { 8302 ns_client_putrdataset(client, &rdataset); 8303 } 8304 if (sigrdataset != NULL) { 8305 ns_client_putrdataset(client, &sigrdataset); 8306 } 8307 if (fname != NULL) { 8308 ns_client_releasename(client, &fname); 8309 } 8310 } 8311 8312 /*% 8313 * Handle authoritative NOERROR/NODATA responses. 8314 */ 8315 static isc_result_t 8316 query_nodata(query_ctx_t *qctx, isc_result_t res) { 8317 isc_result_t result = res; 8318 8319 CCTRACE(ISC_LOG_DEBUG(3), "query_nodata"); 8320 8321 CALL_HOOK(NS_QUERY_NODATA_BEGIN, qctx); 8322 8323 #ifdef dns64_bis_return_excluded_addresses 8324 if (qctx->dns64) 8325 #else /* ifdef dns64_bis_return_excluded_addresses */ 8326 if (qctx->dns64 && !qctx->dns64_exclude) 8327 #endif /* ifdef dns64_bis_return_excluded_addresses */ 8328 { 8329 isc_buffer_t b; 8330 /* 8331 * Restore the answers from the previous AAAA lookup. 8332 */ 8333 if (qctx->rdataset != NULL) { 8334 ns_client_putrdataset(qctx->client, &qctx->rdataset); 8335 } 8336 if (qctx->sigrdataset != NULL) { 8337 ns_client_putrdataset(qctx->client, &qctx->sigrdataset); 8338 } 8339 RESTORE(qctx->rdataset, qctx->client->query.dns64_aaaa); 8340 RESTORE(qctx->sigrdataset, qctx->client->query.dns64_sigaaaa); 8341 if (qctx->fname == NULL) { 8342 qctx->dbuf = ns_client_getnamebuf(qctx->client); 8343 if (qctx->dbuf == NULL) { 8344 CCTRACE(ISC_LOG_ERROR, "query_nodata: " 8345 "ns_client_getnamebuf " 8346 "failed (3)"); 8347 QUERY_ERROR(qctx, ISC_R_NOMEMORY); 8348 return (ns_query_done(qctx)); 8349 } 8350 qctx->fname = ns_client_newname(qctx->client, 8351 qctx->dbuf, &b); 8352 if (qctx->fname == NULL) { 8353 CCTRACE(ISC_LOG_ERROR, "query_nodata: " 8354 "ns_client_newname " 8355 "failed (3)"); 8356 QUERY_ERROR(qctx, ISC_R_NOMEMORY); 8357 return (ns_query_done(qctx)); 8358 } 8359 } 8360 dns_name_copynf(qctx->client->query.qname, qctx->fname); 8361 qctx->dns64 = false; 8362 #ifdef dns64_bis_return_excluded_addresses 8363 /* 8364 * Resume the diverted processing of the AAAA response? 8365 */ 8366 if (qctx->dns64_exclude) { 8367 return (query_prepresponse(qctx)); 8368 } 8369 #endif /* ifdef dns64_bis_return_excluded_addresses */ 8370 } else if ((result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) && 8371 !ISC_LIST_EMPTY(qctx->view->dns64) && !qctx->nxrewrite && 8372 qctx->client->message->rdclass == dns_rdataclass_in && 8373 qctx->qtype == dns_rdatatype_aaaa) 8374 { 8375 /* 8376 * Look to see if there are A records for this name. 8377 */ 8378 switch (result) { 8379 case DNS_R_NCACHENXRRSET: 8380 /* 8381 * This is from the negative cache; if the ttl is 8382 * zero, we need to work out whether we have just 8383 * decremented to zero or there was no negative 8384 * cache ttl in the answer. 8385 */ 8386 if (qctx->rdataset->ttl != 0) { 8387 qctx->client->query.dns64_ttl = 8388 qctx->rdataset->ttl; 8389 break; 8390 } 8391 if (dns_rdataset_first(qctx->rdataset) == ISC_R_SUCCESS) 8392 { 8393 qctx->client->query.dns64_ttl = 0; 8394 } 8395 break; 8396 case DNS_R_NXRRSET: 8397 qctx->client->query.dns64_ttl = 8398 dns64_ttl(qctx->db, qctx->version); 8399 break; 8400 default: 8401 INSIST(0); 8402 ISC_UNREACHABLE(); 8403 } 8404 8405 SAVE(qctx->client->query.dns64_aaaa, qctx->rdataset); 8406 SAVE(qctx->client->query.dns64_sigaaaa, qctx->sigrdataset); 8407 ns_client_releasename(qctx->client, &qctx->fname); 8408 dns_db_detachnode(qctx->db, &qctx->node); 8409 qctx->type = qctx->qtype = dns_rdatatype_a; 8410 qctx->dns64 = true; 8411 return (query_lookup(qctx)); 8412 } 8413 8414 if (qctx->is_zone) { 8415 return (query_sign_nodata(qctx)); 8416 } else { 8417 /* 8418 * We don't call query_addrrset() because we don't need any 8419 * of its extra features (and things would probably break!). 8420 */ 8421 if (dns_rdataset_isassociated(qctx->rdataset)) { 8422 ns_client_keepname(qctx->client, qctx->fname, 8423 qctx->dbuf); 8424 dns_message_addname(qctx->client->message, qctx->fname, 8425 DNS_SECTION_AUTHORITY); 8426 ISC_LIST_APPEND(qctx->fname->list, qctx->rdataset, 8427 link); 8428 qctx->fname = NULL; 8429 qctx->rdataset = NULL; 8430 } 8431 } 8432 8433 return (ns_query_done(qctx)); 8434 8435 cleanup: 8436 return (result); 8437 } 8438 8439 /*% 8440 * Add RRSIGs for NOERROR/NODATA responses when answering authoritatively. 8441 */ 8442 isc_result_t 8443 query_sign_nodata(query_ctx_t *qctx) { 8444 isc_result_t result; 8445 8446 CCTRACE(ISC_LOG_DEBUG(3), "query_sign_nodata"); 8447 8448 /* 8449 * Look for a NSEC3 record if we don't have a NSEC record. 8450 */ 8451 if (qctx->redirected) { 8452 return (ns_query_done(qctx)); 8453 } 8454 if (!dns_rdataset_isassociated(qctx->rdataset) && 8455 WANTDNSSEC(qctx->client)) { 8456 if ((qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) == 0) { 8457 dns_name_t *found; 8458 dns_name_t *qname; 8459 dns_fixedname_t fixed; 8460 isc_buffer_t b; 8461 8462 found = dns_fixedname_initname(&fixed); 8463 qname = qctx->client->query.qname; 8464 8465 query_findclosestnsec3(qname, qctx->db, qctx->version, 8466 qctx->client, qctx->rdataset, 8467 qctx->sigrdataset, qctx->fname, 8468 true, found); 8469 /* 8470 * Did we find the closest provable encloser 8471 * instead? If so add the nearest to the 8472 * closest provable encloser. 8473 */ 8474 if (dns_rdataset_isassociated(qctx->rdataset) && 8475 !dns_name_equal(qname, found) && 8476 (((qctx->client->sctx->options & 8477 NS_SERVER_NONEAREST) == 0) || 8478 qctx->qtype == dns_rdatatype_ds)) 8479 { 8480 unsigned int count; 8481 unsigned int skip; 8482 8483 /* 8484 * Add the closest provable encloser. 8485 */ 8486 query_addrrset(qctx, &qctx->fname, 8487 &qctx->rdataset, 8488 &qctx->sigrdataset, qctx->dbuf, 8489 DNS_SECTION_AUTHORITY); 8490 8491 count = dns_name_countlabels(found) + 1; 8492 skip = dns_name_countlabels(qname) - count; 8493 dns_name_getlabelsequence(qname, skip, count, 8494 found); 8495 8496 fixfname(qctx->client, &qctx->fname, 8497 &qctx->dbuf, &b); 8498 fixrdataset(qctx->client, &qctx->rdataset); 8499 fixrdataset(qctx->client, &qctx->sigrdataset); 8500 if (qctx->fname == NULL || 8501 qctx->rdataset == NULL || 8502 qctx->sigrdataset == NULL) { 8503 CCTRACE(ISC_LOG_ERROR, "query_sign_" 8504 "nodata: " 8505 "failure " 8506 "getting " 8507 "closest " 8508 "encloser"); 8509 QUERY_ERROR(qctx, ISC_R_NOMEMORY); 8510 return (ns_query_done(qctx)); 8511 } 8512 /* 8513 * 'nearest' doesn't exist so 8514 * 'exist' is set to false. 8515 */ 8516 query_findclosestnsec3( 8517 found, qctx->db, qctx->version, 8518 qctx->client, qctx->rdataset, 8519 qctx->sigrdataset, qctx->fname, false, 8520 NULL); 8521 } 8522 } else { 8523 ns_client_releasename(qctx->client, &qctx->fname); 8524 query_addwildcardproof(qctx, false, true); 8525 } 8526 } 8527 if (dns_rdataset_isassociated(qctx->rdataset)) { 8528 /* 8529 * If we've got a NSEC record, we need to save the 8530 * name now because we're going call query_addsoa() 8531 * below, and it needs to use the name buffer. 8532 */ 8533 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf); 8534 } else if (qctx->fname != NULL) { 8535 /* 8536 * We're not going to use fname, and need to release 8537 * our hold on the name buffer so query_addsoa() 8538 * may use it. 8539 */ 8540 ns_client_releasename(qctx->client, &qctx->fname); 8541 } 8542 8543 /* 8544 * The RPZ SOA has already been added to the additional section 8545 * if this was an RPZ rewrite, but if it wasn't, add it now. 8546 */ 8547 if (!qctx->nxrewrite) { 8548 result = query_addsoa(qctx, UINT32_MAX, DNS_SECTION_AUTHORITY); 8549 if (result != ISC_R_SUCCESS) { 8550 QUERY_ERROR(qctx, result); 8551 return (ns_query_done(qctx)); 8552 } 8553 } 8554 8555 /* 8556 * Add NSEC record if we found one. 8557 */ 8558 if (WANTDNSSEC(qctx->client) && 8559 dns_rdataset_isassociated(qctx->rdataset)) { 8560 query_addnxrrsetnsec(qctx); 8561 } 8562 8563 return (ns_query_done(qctx)); 8564 } 8565 8566 static void 8567 query_addnxrrsetnsec(query_ctx_t *qctx) { 8568 ns_client_t *client = qctx->client; 8569 dns_rdata_t sigrdata; 8570 dns_rdata_rrsig_t sig; 8571 unsigned int labels; 8572 isc_buffer_t *dbuf, b; 8573 dns_name_t *fname; 8574 isc_result_t result; 8575 8576 INSIST(qctx->fname != NULL); 8577 8578 if ((qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) == 0) { 8579 query_addrrset(qctx, &qctx->fname, &qctx->rdataset, 8580 &qctx->sigrdataset, NULL, DNS_SECTION_AUTHORITY); 8581 return; 8582 } 8583 8584 if (qctx->sigrdataset == NULL || 8585 !dns_rdataset_isassociated(qctx->sigrdataset)) { 8586 return; 8587 } 8588 8589 if (dns_rdataset_first(qctx->sigrdataset) != ISC_R_SUCCESS) { 8590 return; 8591 } 8592 8593 dns_rdata_init(&sigrdata); 8594 dns_rdataset_current(qctx->sigrdataset, &sigrdata); 8595 result = dns_rdata_tostruct(&sigrdata, &sig, NULL); 8596 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8597 8598 labels = dns_name_countlabels(qctx->fname); 8599 if ((unsigned int)sig.labels + 1 >= labels) { 8600 return; 8601 } 8602 8603 query_addwildcardproof(qctx, true, false); 8604 8605 /* 8606 * We'll need some resources... 8607 */ 8608 dbuf = ns_client_getnamebuf(client); 8609 if (dbuf == NULL) { 8610 return; 8611 } 8612 8613 fname = ns_client_newname(client, dbuf, &b); 8614 if (fname == NULL) { 8615 return; 8616 } 8617 8618 dns_name_split(qctx->fname, sig.labels + 1, NULL, fname); 8619 /* This will succeed, since we've stripped labels. */ 8620 RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname, fname, fname, 8621 NULL) == ISC_R_SUCCESS); 8622 query_addrrset(qctx, &fname, &qctx->rdataset, &qctx->sigrdataset, dbuf, 8623 DNS_SECTION_AUTHORITY); 8624 } 8625 8626 /*% 8627 * Handle NXDOMAIN and empty wildcard responses. 8628 */ 8629 static isc_result_t 8630 query_nxdomain(query_ctx_t *qctx, bool empty_wild) { 8631 dns_section_t section; 8632 uint32_t ttl; 8633 isc_result_t result; 8634 8635 CCTRACE(ISC_LOG_DEBUG(3), "query_nxdomain"); 8636 8637 CALL_HOOK(NS_QUERY_NXDOMAIN_BEGIN, qctx); 8638 8639 INSIST(qctx->is_zone || REDIRECT(qctx->client)); 8640 8641 if (!empty_wild) { 8642 result = query_redirect(qctx); 8643 if (result != ISC_R_COMPLETE) { 8644 return (result); 8645 } 8646 } 8647 8648 if (dns_rdataset_isassociated(qctx->rdataset)) { 8649 /* 8650 * If we've got a NSEC record, we need to save the 8651 * name now because we're going call query_addsoa() 8652 * below, and it needs to use the name buffer. 8653 */ 8654 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf); 8655 } else if (qctx->fname != NULL) { 8656 /* 8657 * We're not going to use fname, and need to release 8658 * our hold on the name buffer so query_addsoa() 8659 * may use it. 8660 */ 8661 ns_client_releasename(qctx->client, &qctx->fname); 8662 } 8663 8664 /* 8665 * Add SOA to the additional section if generated by a 8666 * RPZ rewrite. 8667 * 8668 * If the query was for a SOA record force the 8669 * ttl to zero so that it is possible for clients to find 8670 * the containing zone of an arbitrary name with a stub 8671 * resolver and not have it cached. 8672 */ 8673 section = qctx->nxrewrite ? DNS_SECTION_ADDITIONAL 8674 : DNS_SECTION_AUTHORITY; 8675 ttl = UINT32_MAX; 8676 if (!qctx->nxrewrite && qctx->qtype == dns_rdatatype_soa && 8677 qctx->zone != NULL && dns_zone_getzeronosoattl(qctx->zone)) 8678 { 8679 ttl = 0; 8680 } 8681 if (!qctx->nxrewrite || qctx->rpz_st->m.rpz->addsoa) { 8682 result = query_addsoa(qctx, ttl, section); 8683 if (result != ISC_R_SUCCESS) { 8684 QUERY_ERROR(qctx, result); 8685 return (ns_query_done(qctx)); 8686 } 8687 } 8688 8689 if (WANTDNSSEC(qctx->client)) { 8690 /* 8691 * Add NSEC record if we found one. 8692 */ 8693 if (dns_rdataset_isassociated(qctx->rdataset)) { 8694 query_addrrset(qctx, &qctx->fname, &qctx->rdataset, 8695 &qctx->sigrdataset, NULL, 8696 DNS_SECTION_AUTHORITY); 8697 } 8698 query_addwildcardproof(qctx, false, false); 8699 } 8700 8701 /* 8702 * Set message rcode. 8703 */ 8704 if (empty_wild) { 8705 qctx->client->message->rcode = dns_rcode_noerror; 8706 } else { 8707 qctx->client->message->rcode = dns_rcode_nxdomain; 8708 } 8709 8710 return (ns_query_done(qctx)); 8711 8712 cleanup: 8713 return (result); 8714 } 8715 8716 /* 8717 * Handle both types of NXDOMAIN redirection, calling redirect() 8718 * (which implements type redirect zones) and redirect2() (which 8719 * implements recursive nxdomain-redirect lookups). 8720 * 8721 * Any result code other than ISC_R_COMPLETE means redirection was 8722 * successful and the result code should be returned up the call stack. 8723 * 8724 * ISC_R_COMPLETE means we reached the end of this function without 8725 * redirecting, so query processing should continue past it. 8726 */ 8727 static isc_result_t 8728 query_redirect(query_ctx_t *qctx) { 8729 isc_result_t result; 8730 8731 CCTRACE(ISC_LOG_DEBUG(3), "query_redirect"); 8732 8733 result = redirect(qctx->client, qctx->fname, qctx->rdataset, 8734 &qctx->node, &qctx->db, &qctx->version, qctx->type); 8735 switch (result) { 8736 case ISC_R_SUCCESS: 8737 inc_stats(qctx->client, ns_statscounter_nxdomainredirect); 8738 return (query_prepresponse(qctx)); 8739 case DNS_R_NXRRSET: 8740 qctx->redirected = true; 8741 qctx->is_zone = true; 8742 return (query_nodata(qctx, DNS_R_NXRRSET)); 8743 case DNS_R_NCACHENXRRSET: 8744 qctx->redirected = true; 8745 qctx->is_zone = false; 8746 return (query_ncache(qctx, DNS_R_NCACHENXRRSET)); 8747 default: 8748 break; 8749 } 8750 8751 result = redirect2(qctx->client, qctx->fname, qctx->rdataset, 8752 &qctx->node, &qctx->db, &qctx->version, qctx->type, 8753 &qctx->is_zone); 8754 switch (result) { 8755 case ISC_R_SUCCESS: 8756 inc_stats(qctx->client, ns_statscounter_nxdomainredirect); 8757 return (query_prepresponse(qctx)); 8758 case DNS_R_CONTINUE: 8759 inc_stats(qctx->client, 8760 ns_statscounter_nxdomainredirect_rlookup); 8761 SAVE(qctx->client->query.redirect.db, qctx->db); 8762 SAVE(qctx->client->query.redirect.node, qctx->node); 8763 SAVE(qctx->client->query.redirect.zone, qctx->zone); 8764 qctx->client->query.redirect.qtype = qctx->qtype; 8765 INSIST(qctx->rdataset != NULL); 8766 SAVE(qctx->client->query.redirect.rdataset, qctx->rdataset); 8767 SAVE(qctx->client->query.redirect.sigrdataset, 8768 qctx->sigrdataset); 8769 qctx->client->query.redirect.result = DNS_R_NCACHENXDOMAIN; 8770 dns_name_copynf(qctx->fname, 8771 qctx->client->query.redirect.fname); 8772 qctx->client->query.redirect.authoritative = 8773 qctx->authoritative; 8774 qctx->client->query.redirect.is_zone = qctx->is_zone; 8775 return (ns_query_done(qctx)); 8776 case DNS_R_NXRRSET: 8777 qctx->redirected = true; 8778 qctx->is_zone = true; 8779 return (query_nodata(qctx, DNS_R_NXRRSET)); 8780 case DNS_R_NCACHENXRRSET: 8781 qctx->redirected = true; 8782 qctx->is_zone = false; 8783 return (query_ncache(qctx, DNS_R_NCACHENXRRSET)); 8784 default: 8785 break; 8786 } 8787 8788 return (ISC_R_COMPLETE); 8789 } 8790 8791 /*% 8792 * Logging function to be passed to dns_nsec_noexistnodata. 8793 */ 8794 static void 8795 log_noexistnodata(void *val, int level, const char *fmt, ...) { 8796 query_ctx_t *qctx = val; 8797 va_list ap; 8798 8799 va_start(ap, fmt); 8800 ns_client_logv(qctx->client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY, 8801 level, fmt, ap); 8802 va_end(ap); 8803 } 8804 8805 static dns_ttl_t 8806 query_synthttl(dns_rdataset_t *soardataset, dns_rdataset_t *sigsoardataset, 8807 dns_rdataset_t *p1rdataset, dns_rdataset_t *sigp1rdataset, 8808 dns_rdataset_t *p2rdataset, dns_rdataset_t *sigp2rdataset) { 8809 dns_rdata_soa_t soa; 8810 dns_rdata_t rdata = DNS_RDATA_INIT; 8811 dns_ttl_t ttl; 8812 isc_result_t result; 8813 8814 REQUIRE(soardataset != NULL); 8815 REQUIRE(sigsoardataset != NULL); 8816 REQUIRE(p1rdataset != NULL); 8817 REQUIRE(sigp1rdataset != NULL); 8818 8819 result = dns_rdataset_first(soardataset); 8820 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8821 dns_rdataset_current(soardataset, &rdata); 8822 result = dns_rdata_tostruct(&rdata, &soa, NULL); 8823 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8824 8825 ttl = ISC_MIN(soa.minimum, soardataset->ttl); 8826 ttl = ISC_MIN(ttl, sigsoardataset->ttl); 8827 ttl = ISC_MIN(ttl, p1rdataset->ttl); 8828 ttl = ISC_MIN(ttl, sigp1rdataset->ttl); 8829 if (p2rdataset != NULL) { 8830 ttl = ISC_MIN(ttl, p2rdataset->ttl); 8831 } 8832 if (sigp2rdataset != NULL) { 8833 ttl = ISC_MIN(ttl, sigp2rdataset->ttl); 8834 } 8835 8836 return (ttl); 8837 } 8838 8839 /* 8840 * Synthesize a NODATA response from the SOA and covering NSEC in cache. 8841 */ 8842 static isc_result_t 8843 query_synthnodata(query_ctx_t *qctx, const dns_name_t *signer, 8844 dns_rdataset_t **soardatasetp, 8845 dns_rdataset_t **sigsoardatasetp) { 8846 dns_name_t *name = NULL; 8847 dns_ttl_t ttl; 8848 isc_buffer_t *dbuf, b; 8849 isc_result_t result; 8850 8851 /* 8852 * Determine the correct TTL to use for the SOA and RRSIG 8853 */ 8854 ttl = query_synthttl(*soardatasetp, *sigsoardatasetp, qctx->rdataset, 8855 qctx->sigrdataset, NULL, NULL); 8856 (*soardatasetp)->ttl = (*sigsoardatasetp)->ttl = ttl; 8857 8858 /* 8859 * We want the SOA record to be first, so save the 8860 * NODATA proof's name now or else discard it. 8861 */ 8862 if (WANTDNSSEC(qctx->client)) { 8863 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf); 8864 } else { 8865 ns_client_releasename(qctx->client, &qctx->fname); 8866 } 8867 8868 dbuf = ns_client_getnamebuf(qctx->client); 8869 if (dbuf == NULL) { 8870 result = ISC_R_NOMEMORY; 8871 goto cleanup; 8872 } 8873 8874 name = ns_client_newname(qctx->client, dbuf, &b); 8875 if (name == NULL) { 8876 result = ISC_R_NOMEMORY; 8877 goto cleanup; 8878 } 8879 8880 dns_name_copynf(signer, name); 8881 8882 /* 8883 * Add SOA record. Omit the RRSIG if DNSSEC was not requested. 8884 */ 8885 if (!WANTDNSSEC(qctx->client)) { 8886 sigsoardatasetp = NULL; 8887 } 8888 query_addrrset(qctx, &name, soardatasetp, sigsoardatasetp, dbuf, 8889 DNS_SECTION_AUTHORITY); 8890 8891 if (WANTDNSSEC(qctx->client)) { 8892 /* 8893 * Add NODATA proof. 8894 */ 8895 query_addrrset(qctx, &qctx->fname, &qctx->rdataset, 8896 &qctx->sigrdataset, NULL, DNS_SECTION_AUTHORITY); 8897 } 8898 8899 result = ISC_R_SUCCESS; 8900 inc_stats(qctx->client, ns_statscounter_nodatasynth); 8901 8902 cleanup: 8903 if (name != NULL) { 8904 ns_client_releasename(qctx->client, &name); 8905 } 8906 return (result); 8907 } 8908 8909 /* 8910 * Synthesize a wildcard answer using the contents of 'rdataset'. 8911 * qctx contains the NODATA proof. 8912 */ 8913 static isc_result_t 8914 query_synthwildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset, 8915 dns_rdataset_t *sigrdataset) { 8916 dns_name_t *name = NULL; 8917 isc_buffer_t *dbuf, b; 8918 isc_result_t result; 8919 dns_rdataset_t *cloneset = NULL, *clonesigset = NULL; 8920 dns_rdataset_t **sigrdatasetp; 8921 8922 CCTRACE(ISC_LOG_DEBUG(3), "query_synthwildcard"); 8923 8924 /* 8925 * We want the answer to be first, so save the 8926 * NOQNAME proof's name now or else discard it. 8927 */ 8928 if (WANTDNSSEC(qctx->client)) { 8929 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf); 8930 } else { 8931 ns_client_releasename(qctx->client, &qctx->fname); 8932 } 8933 8934 dbuf = ns_client_getnamebuf(qctx->client); 8935 if (dbuf == NULL) { 8936 result = ISC_R_NOMEMORY; 8937 goto cleanup; 8938 } 8939 8940 name = ns_client_newname(qctx->client, dbuf, &b); 8941 if (name == NULL) { 8942 result = ISC_R_NOMEMORY; 8943 goto cleanup; 8944 } 8945 dns_name_copynf(qctx->client->query.qname, name); 8946 8947 cloneset = ns_client_newrdataset(qctx->client); 8948 if (cloneset == NULL) { 8949 result = ISC_R_NOMEMORY; 8950 goto cleanup; 8951 } 8952 dns_rdataset_clone(rdataset, cloneset); 8953 8954 /* 8955 * Add answer RRset. Omit the RRSIG if DNSSEC was not requested. 8956 */ 8957 if (WANTDNSSEC(qctx->client)) { 8958 clonesigset = ns_client_newrdataset(qctx->client); 8959 if (clonesigset == NULL) { 8960 result = ISC_R_NOMEMORY; 8961 goto cleanup; 8962 } 8963 dns_rdataset_clone(sigrdataset, clonesigset); 8964 sigrdatasetp = &clonesigset; 8965 } else { 8966 sigrdatasetp = NULL; 8967 } 8968 8969 query_addrrset(qctx, &name, &cloneset, sigrdatasetp, dbuf, 8970 DNS_SECTION_ANSWER); 8971 8972 if (WANTDNSSEC(qctx->client)) { 8973 /* 8974 * Add NOQNAME proof. 8975 */ 8976 query_addrrset(qctx, &qctx->fname, &qctx->rdataset, 8977 &qctx->sigrdataset, NULL, DNS_SECTION_AUTHORITY); 8978 } 8979 8980 result = ISC_R_SUCCESS; 8981 inc_stats(qctx->client, ns_statscounter_wildcardsynth); 8982 8983 cleanup: 8984 if (name != NULL) { 8985 ns_client_releasename(qctx->client, &name); 8986 } 8987 if (cloneset != NULL) { 8988 ns_client_putrdataset(qctx->client, &cloneset); 8989 } 8990 if (clonesigset != NULL) { 8991 ns_client_putrdataset(qctx->client, &clonesigset); 8992 } 8993 return (result); 8994 } 8995 8996 /* 8997 * Add a synthesized CNAME record from the wildard RRset (rdataset) 8998 * and NODATA proof by calling query_synthwildcard then setup to 8999 * follow the CNAME. 9000 */ 9001 static isc_result_t 9002 query_synthcnamewildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset, 9003 dns_rdataset_t *sigrdataset) { 9004 isc_result_t result; 9005 dns_name_t *tname = NULL; 9006 dns_rdata_t rdata = DNS_RDATA_INIT; 9007 dns_rdata_cname_t cname; 9008 9009 result = query_synthwildcard(qctx, rdataset, sigrdataset); 9010 if (result != ISC_R_SUCCESS) { 9011 return (result); 9012 } 9013 9014 qctx->client->query.attributes |= NS_QUERYATTR_PARTIALANSWER; 9015 9016 /* 9017 * Reset qname to be the target name of the CNAME and restart 9018 * the query. 9019 */ 9020 result = dns_message_gettempname(qctx->client->message, &tname); 9021 if (result != ISC_R_SUCCESS) { 9022 return (result); 9023 } 9024 9025 result = dns_rdataset_first(rdataset); 9026 if (result != ISC_R_SUCCESS) { 9027 dns_message_puttempname(qctx->client->message, &tname); 9028 return (result); 9029 } 9030 9031 dns_rdataset_current(rdataset, &rdata); 9032 result = dns_rdata_tostruct(&rdata, &cname, NULL); 9033 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9034 dns_rdata_reset(&rdata); 9035 9036 dns_name_init(tname, NULL); 9037 dns_name_dup(&cname.cname, qctx->client->mctx, tname); 9038 9039 dns_rdata_freestruct(&cname); 9040 ns_client_qnamereplace(qctx->client, tname); 9041 qctx->want_restart = true; 9042 if (!WANTRECURSION(qctx->client)) { 9043 qctx->options |= DNS_GETDB_NOLOG; 9044 } 9045 9046 return (result); 9047 } 9048 9049 /* 9050 * Synthesize a NXDOMAIN response from qctx (which contains the 9051 * NODATA proof), nowild + nowildrdataset + signowildrdataset (which 9052 * contains the NOWILDCARD proof) and signer + soardatasetp + sigsoardatasetp 9053 * which contain the SOA record + RRSIG for the negative answer. 9054 */ 9055 static isc_result_t 9056 query_synthnxdomain(query_ctx_t *qctx, dns_name_t *nowild, 9057 dns_rdataset_t *nowildrdataset, 9058 dns_rdataset_t *signowildrdataset, dns_name_t *signer, 9059 dns_rdataset_t **soardatasetp, 9060 dns_rdataset_t **sigsoardatasetp) { 9061 dns_name_t *name = NULL; 9062 dns_ttl_t ttl; 9063 isc_buffer_t *dbuf, b; 9064 isc_result_t result; 9065 dns_rdataset_t *cloneset = NULL, *clonesigset = NULL; 9066 9067 CCTRACE(ISC_LOG_DEBUG(3), "query_synthnxdomain"); 9068 9069 /* 9070 * Determine the correct TTL to use for the SOA and RRSIG 9071 */ 9072 ttl = query_synthttl(*soardatasetp, *sigsoardatasetp, qctx->rdataset, 9073 qctx->sigrdataset, nowildrdataset, 9074 signowildrdataset); 9075 (*soardatasetp)->ttl = (*sigsoardatasetp)->ttl = ttl; 9076 9077 /* 9078 * We want the SOA record to be first, so save the 9079 * NOQNAME proof's name now or else discard it. 9080 */ 9081 if (WANTDNSSEC(qctx->client)) { 9082 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf); 9083 } else { 9084 ns_client_releasename(qctx->client, &qctx->fname); 9085 } 9086 9087 dbuf = ns_client_getnamebuf(qctx->client); 9088 if (dbuf == NULL) { 9089 result = ISC_R_NOMEMORY; 9090 goto cleanup; 9091 } 9092 9093 name = ns_client_newname(qctx->client, dbuf, &b); 9094 if (name == NULL) { 9095 result = ISC_R_NOMEMORY; 9096 goto cleanup; 9097 } 9098 9099 dns_name_copynf(signer, name); 9100 9101 /* 9102 * Add SOA record. Omit the RRSIG if DNSSEC was not requested. 9103 */ 9104 if (!WANTDNSSEC(qctx->client)) { 9105 sigsoardatasetp = NULL; 9106 } 9107 query_addrrset(qctx, &name, soardatasetp, sigsoardatasetp, dbuf, 9108 DNS_SECTION_AUTHORITY); 9109 9110 if (WANTDNSSEC(qctx->client)) { 9111 /* 9112 * Add NOQNAME proof. 9113 */ 9114 query_addrrset(qctx, &qctx->fname, &qctx->rdataset, 9115 &qctx->sigrdataset, NULL, DNS_SECTION_AUTHORITY); 9116 9117 dbuf = ns_client_getnamebuf(qctx->client); 9118 if (dbuf == NULL) { 9119 result = ISC_R_NOMEMORY; 9120 goto cleanup; 9121 } 9122 9123 name = ns_client_newname(qctx->client, dbuf, &b); 9124 if (name == NULL) { 9125 result = ISC_R_NOMEMORY; 9126 goto cleanup; 9127 } 9128 9129 dns_name_copynf(nowild, name); 9130 9131 cloneset = ns_client_newrdataset(qctx->client); 9132 clonesigset = ns_client_newrdataset(qctx->client); 9133 if (cloneset == NULL || clonesigset == NULL) { 9134 result = ISC_R_NOMEMORY; 9135 goto cleanup; 9136 } 9137 9138 dns_rdataset_clone(nowildrdataset, cloneset); 9139 dns_rdataset_clone(signowildrdataset, clonesigset); 9140 9141 /* 9142 * Add NOWILDCARD proof. 9143 */ 9144 query_addrrset(qctx, &name, &cloneset, &clonesigset, dbuf, 9145 DNS_SECTION_AUTHORITY); 9146 } 9147 9148 qctx->client->message->rcode = dns_rcode_nxdomain; 9149 result = ISC_R_SUCCESS; 9150 inc_stats(qctx->client, ns_statscounter_nxdomainsynth); 9151 9152 cleanup: 9153 if (name != NULL) { 9154 ns_client_releasename(qctx->client, &name); 9155 } 9156 if (cloneset != NULL) { 9157 ns_client_putrdataset(qctx->client, &cloneset); 9158 } 9159 if (clonesigset != NULL) { 9160 ns_client_putrdataset(qctx->client, &clonesigset); 9161 } 9162 return (result); 9163 } 9164 9165 /* 9166 * Check that all signer names in sigrdataset match the expected signer. 9167 */ 9168 static isc_result_t 9169 checksignames(dns_name_t *signer, dns_rdataset_t *sigrdataset) { 9170 isc_result_t result; 9171 9172 for (result = dns_rdataset_first(sigrdataset); result == ISC_R_SUCCESS; 9173 result = dns_rdataset_next(sigrdataset)) 9174 { 9175 dns_rdata_t rdata = DNS_RDATA_INIT; 9176 dns_rdata_rrsig_t rrsig; 9177 9178 dns_rdataset_current(sigrdataset, &rdata); 9179 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 9180 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9181 if (dns_name_countlabels(signer) == 0) { 9182 dns_name_copynf(&rrsig.signer, signer); 9183 } else if (!dns_name_equal(signer, &rrsig.signer)) { 9184 return (ISC_R_FAILURE); 9185 } 9186 } 9187 9188 return (ISC_R_SUCCESS); 9189 } 9190 9191 /*% 9192 * Handle covering NSEC responses. 9193 * 9194 * Verify the NSEC record is appropriate for the QNAME; if not, 9195 * redo the initial query without DNS_DBFIND_COVERINGNSEC. 9196 * 9197 * If the covering NSEC proves that the name exists but not the type, 9198 * synthesize a NODATA response. 9199 * 9200 * If the name doesn't exist, compute the wildcard record and check whether 9201 * the wildcard name exists or not. If we can't determine this, redo the 9202 * initial query without DNS_DBFIND_COVERINGNSEC. 9203 * 9204 * If the wildcard name does not exist, compute the SOA name and look that 9205 * up. If the SOA record does not exist, redo the initial query without 9206 * DNS_DBFIND_COVERINGNSEC. If the SOA record exists, synthesize an 9207 * NXDOMAIN response from the found records. 9208 * 9209 * If the wildcard name does exist, perform a lookup for the requested 9210 * type at the wildcard name. 9211 */ 9212 static isc_result_t 9213 query_coveringnsec(query_ctx_t *qctx) { 9214 dns_db_t *db = NULL; 9215 dns_clientinfo_t ci; 9216 dns_clientinfomethods_t cm; 9217 dns_dbnode_t *node = NULL; 9218 dns_fixedname_t fixed; 9219 dns_fixedname_t fnowild; 9220 dns_fixedname_t fsigner; 9221 dns_fixedname_t fwild; 9222 dns_name_t *fname = NULL; 9223 dns_name_t *nowild = NULL; 9224 dns_name_t *signer = NULL; 9225 dns_name_t *wild = NULL; 9226 dns_rdataset_t *soardataset = NULL, *sigsoardataset = NULL; 9227 dns_rdataset_t rdataset, sigrdataset; 9228 bool done = false; 9229 bool exists = true, data = true; 9230 bool redirected = false; 9231 isc_result_t result = ISC_R_SUCCESS; 9232 unsigned int dboptions = qctx->client->query.dboptions; 9233 9234 CCTRACE(ISC_LOG_DEBUG(3), "query_coveringnsec"); 9235 9236 dns_rdataset_init(&rdataset); 9237 dns_rdataset_init(&sigrdataset); 9238 9239 /* 9240 * If we have no signer name, stop immediately. 9241 */ 9242 if (!dns_rdataset_isassociated(qctx->sigrdataset)) { 9243 goto cleanup; 9244 } 9245 9246 wild = dns_fixedname_initname(&fwild); 9247 fname = dns_fixedname_initname(&fixed); 9248 signer = dns_fixedname_initname(&fsigner); 9249 nowild = dns_fixedname_initname(&fnowild); 9250 9251 dns_clientinfomethods_init(&cm, ns_client_sourceip); 9252 dns_clientinfo_init(&ci, qctx->client, NULL); 9253 9254 /* 9255 * All signer names must be the same to accept. 9256 */ 9257 result = checksignames(signer, qctx->sigrdataset); 9258 if (result != ISC_R_SUCCESS) { 9259 result = ISC_R_SUCCESS; 9260 goto cleanup; 9261 } 9262 9263 /* 9264 * Check that we have the correct NOQNAME NSEC record. 9265 */ 9266 result = dns_nsec_noexistnodata(qctx->qtype, qctx->client->query.qname, 9267 qctx->fname, qctx->rdataset, &exists, 9268 &data, wild, log_noexistnodata, qctx); 9269 9270 if (result != ISC_R_SUCCESS || (exists && data)) { 9271 goto cleanup; 9272 } 9273 9274 if (exists) { 9275 if (qctx->type == dns_rdatatype_any) { /* XXX not yet */ 9276 goto cleanup; 9277 } 9278 if (!ISC_LIST_EMPTY(qctx->view->dns64) && 9279 (qctx->type == dns_rdatatype_a || 9280 qctx->type == dns_rdatatype_aaaa)) /* XXX not yet */ 9281 { 9282 goto cleanup; 9283 } 9284 if (!qctx->resuming && !STALE(qctx->rdataset) && 9285 qctx->rdataset->ttl == 0 && RECURSIONOK(qctx->client)) 9286 { 9287 goto cleanup; 9288 } 9289 9290 soardataset = ns_client_newrdataset(qctx->client); 9291 sigsoardataset = ns_client_newrdataset(qctx->client); 9292 if (soardataset == NULL || sigsoardataset == NULL) { 9293 goto cleanup; 9294 } 9295 9296 /* 9297 * Look for SOA record to construct NODATA response. 9298 */ 9299 dns_db_attach(qctx->db, &db); 9300 result = dns_db_findext(db, signer, qctx->version, 9301 dns_rdatatype_soa, dboptions, 9302 qctx->client->now, &node, fname, &cm, 9303 &ci, soardataset, sigsoardataset); 9304 9305 if (result != ISC_R_SUCCESS) { 9306 goto cleanup; 9307 } 9308 (void)query_synthnodata(qctx, signer, &soardataset, 9309 &sigsoardataset); 9310 done = true; 9311 goto cleanup; 9312 } 9313 9314 /* 9315 * Look up the no-wildcard proof. 9316 */ 9317 dns_db_attach(qctx->db, &db); 9318 result = dns_db_findext(db, wild, qctx->version, qctx->type, 9319 dboptions | DNS_DBFIND_COVERINGNSEC, 9320 qctx->client->now, &node, nowild, &cm, &ci, 9321 &rdataset, &sigrdataset); 9322 9323 if (rdataset.trust != dns_trust_secure || 9324 sigrdataset.trust != dns_trust_secure) { 9325 goto cleanup; 9326 } 9327 9328 /* 9329 * Zero TTL handling of wildcard record. 9330 * 9331 * We don't yet have code to handle synthesis and type ANY or dns64 9332 * processing so we abort the synthesis here if there would be a 9333 * interaction. 9334 */ 9335 switch (result) { 9336 case ISC_R_SUCCESS: 9337 if (qctx->type == dns_rdatatype_any) { /* XXX not yet */ 9338 goto cleanup; 9339 } 9340 if (!ISC_LIST_EMPTY(qctx->view->dns64) && 9341 (qctx->type == dns_rdatatype_a || 9342 qctx->type == dns_rdatatype_aaaa)) /* XXX not yet */ 9343 { 9344 goto cleanup; 9345 } 9346 /* FALLTHROUGH */ 9347 case DNS_R_CNAME: 9348 if (!qctx->resuming && !STALE(&rdataset) && rdataset.ttl == 0 && 9349 RECURSIONOK(qctx->client)) 9350 { 9351 goto cleanup; 9352 } 9353 default: 9354 break; 9355 } 9356 9357 switch (result) { 9358 case DNS_R_COVERINGNSEC: 9359 result = dns_nsec_noexistnodata(qctx->qtype, wild, nowild, 9360 &rdataset, &exists, &data, NULL, 9361 log_noexistnodata, qctx); 9362 if (result != ISC_R_SUCCESS || exists) { 9363 goto cleanup; 9364 } 9365 break; 9366 case ISC_R_SUCCESS: /* wild card match */ 9367 (void)query_synthwildcard(qctx, &rdataset, &sigrdataset); 9368 done = true; 9369 goto cleanup; 9370 case DNS_R_CNAME: /* wild card cname */ 9371 (void)query_synthcnamewildcard(qctx, &rdataset, &sigrdataset); 9372 done = true; 9373 goto cleanup; 9374 case DNS_R_NCACHENXRRSET: /* wild card nodata */ 9375 case DNS_R_NCACHENXDOMAIN: /* direct nxdomain */ 9376 default: 9377 goto cleanup; 9378 } 9379 9380 /* 9381 * We now have the proof that we have an NXDOMAIN. Apply 9382 * NXDOMAIN redirection if configured. 9383 */ 9384 result = query_redirect(qctx); 9385 if (result != ISC_R_COMPLETE) { 9386 redirected = true; 9387 goto cleanup; 9388 } 9389 9390 /* 9391 * Must be signed to accept. 9392 */ 9393 if (!dns_rdataset_isassociated(&sigrdataset)) { 9394 goto cleanup; 9395 } 9396 9397 /* 9398 * Check signer signer names again. 9399 */ 9400 result = checksignames(signer, &sigrdataset); 9401 if (result != ISC_R_SUCCESS) { 9402 result = ISC_R_SUCCESS; 9403 goto cleanup; 9404 } 9405 9406 if (node != NULL) { 9407 dns_db_detachnode(db, &node); 9408 } 9409 9410 soardataset = ns_client_newrdataset(qctx->client); 9411 sigsoardataset = ns_client_newrdataset(qctx->client); 9412 if (soardataset == NULL || sigsoardataset == NULL) { 9413 goto cleanup; 9414 } 9415 9416 /* 9417 * Look for SOA record to construct NXDOMAIN response. 9418 */ 9419 result = dns_db_findext(db, signer, qctx->version, dns_rdatatype_soa, 9420 dboptions, qctx->client->now, &node, fname, &cm, 9421 &ci, soardataset, sigsoardataset); 9422 9423 if (result != ISC_R_SUCCESS) { 9424 goto cleanup; 9425 } 9426 9427 (void)query_synthnxdomain(qctx, nowild, &rdataset, &sigrdataset, signer, 9428 &soardataset, &sigsoardataset); 9429 done = true; 9430 9431 cleanup: 9432 if (dns_rdataset_isassociated(&rdataset)) { 9433 dns_rdataset_disassociate(&rdataset); 9434 } 9435 if (dns_rdataset_isassociated(&sigrdataset)) { 9436 dns_rdataset_disassociate(&sigrdataset); 9437 } 9438 if (soardataset != NULL) { 9439 ns_client_putrdataset(qctx->client, &soardataset); 9440 } 9441 if (sigsoardataset != NULL) { 9442 ns_client_putrdataset(qctx->client, &sigsoardataset); 9443 } 9444 if (db != NULL) { 9445 if (node != NULL) { 9446 dns_db_detachnode(db, &node); 9447 } 9448 dns_db_detach(&db); 9449 } 9450 9451 if (redirected) { 9452 return (result); 9453 } 9454 9455 if (!done) { 9456 /* 9457 * No covering NSEC was found; proceed with recursion. 9458 */ 9459 qctx->findcoveringnsec = false; 9460 if (qctx->fname != NULL) { 9461 ns_client_releasename(qctx->client, &qctx->fname); 9462 } 9463 if (qctx->node != NULL) { 9464 dns_db_detachnode(qctx->db, &qctx->node); 9465 } 9466 ns_client_putrdataset(qctx->client, &qctx->rdataset); 9467 if (qctx->sigrdataset != NULL) { 9468 ns_client_putrdataset(qctx->client, &qctx->sigrdataset); 9469 } 9470 return (query_lookup(qctx)); 9471 } 9472 9473 return (ns_query_done(qctx)); 9474 } 9475 9476 /*% 9477 * Handle negative cache responses, DNS_R_NCACHENXRRSET or 9478 * DNS_R_NCACHENXDOMAIN. (Note: may also be called with result 9479 * set to DNS_R_NXDOMAIN when handling DNS64 lookups.) 9480 */ 9481 static isc_result_t 9482 query_ncache(query_ctx_t *qctx, isc_result_t result) { 9483 INSIST(!qctx->is_zone); 9484 INSIST(result == DNS_R_NCACHENXDOMAIN || 9485 result == DNS_R_NCACHENXRRSET || result == DNS_R_NXDOMAIN); 9486 9487 CCTRACE(ISC_LOG_DEBUG(3), "query_ncache"); 9488 9489 CALL_HOOK(NS_QUERY_NCACHE_BEGIN, qctx); 9490 9491 qctx->authoritative = false; 9492 9493 if (result == DNS_R_NCACHENXDOMAIN) { 9494 /* 9495 * Set message rcode. (This is not done when 9496 * result == DNS_R_NXDOMAIN because that means we're 9497 * being called after a DNS64 lookup and don't want 9498 * to update the rcode now.) 9499 */ 9500 qctx->client->message->rcode = dns_rcode_nxdomain; 9501 9502 /* Look for RFC 1918 leakage from Internet. */ 9503 if (qctx->qtype == dns_rdatatype_ptr && 9504 qctx->client->message->rdclass == dns_rdataclass_in && 9505 dns_name_countlabels(qctx->fname) == 7) 9506 { 9507 warn_rfc1918(qctx->client, qctx->fname, qctx->rdataset); 9508 } 9509 } 9510 9511 return (query_nodata(qctx, result)); 9512 9513 cleanup: 9514 return (result); 9515 } 9516 9517 /* 9518 * If we have a zero ttl from the cache, refetch. 9519 */ 9520 static isc_result_t 9521 query_zerottl_refetch(query_ctx_t *qctx) { 9522 isc_result_t result; 9523 9524 CCTRACE(ISC_LOG_DEBUG(3), "query_zerottl_refetch"); 9525 9526 if (qctx->is_zone || qctx->resuming || STALE(qctx->rdataset) || 9527 qctx->rdataset->ttl != 0 || !RECURSIONOK(qctx->client)) 9528 { 9529 return (ISC_R_COMPLETE); 9530 } 9531 9532 qctx_clean(qctx); 9533 9534 INSIST(!REDIRECT(qctx->client)); 9535 9536 result = ns_query_recurse(qctx->client, qctx->qtype, 9537 qctx->client->query.qname, NULL, NULL, 9538 qctx->resuming); 9539 if (result == ISC_R_SUCCESS) { 9540 CALL_HOOK(NS_QUERY_ZEROTTL_RECURSE, qctx); 9541 qctx->client->query.attributes |= NS_QUERYATTR_RECURSING; 9542 9543 if (qctx->dns64) { 9544 qctx->client->query.attributes |= NS_QUERYATTR_DNS64; 9545 } 9546 if (qctx->dns64_exclude) { 9547 qctx->client->query.attributes |= 9548 NS_QUERYATTR_DNS64EXCLUDE; 9549 } 9550 } else { 9551 QUERY_ERROR(qctx, result); 9552 } 9553 9554 return (ns_query_done(qctx)); 9555 9556 cleanup: 9557 return (result); 9558 } 9559 9560 /* 9561 * Handle CNAME responses. 9562 */ 9563 static isc_result_t 9564 query_cname(query_ctx_t *qctx) { 9565 isc_result_t result; 9566 dns_name_t *tname; 9567 dns_rdataset_t *trdataset; 9568 dns_rdataset_t **sigrdatasetp = NULL; 9569 dns_rdata_t rdata = DNS_RDATA_INIT; 9570 dns_rdata_cname_t cname; 9571 9572 CCTRACE(ISC_LOG_DEBUG(3), "query_cname"); 9573 9574 CALL_HOOK(NS_QUERY_CNAME_BEGIN, qctx); 9575 9576 result = query_zerottl_refetch(qctx); 9577 if (result != ISC_R_COMPLETE) { 9578 return (result); 9579 } 9580 9581 /* 9582 * Keep a copy of the rdataset. We have to do this because 9583 * query_addrrset may clear 'rdataset' (to prevent the 9584 * cleanup code from cleaning it up). 9585 */ 9586 trdataset = qctx->rdataset; 9587 9588 /* 9589 * Add the CNAME to the answer section. 9590 */ 9591 if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) { 9592 sigrdatasetp = &qctx->sigrdataset; 9593 } 9594 9595 if (WANTDNSSEC(qctx->client) && 9596 (qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) 9597 { 9598 dns_fixedname_init(&qctx->wildcardname); 9599 dns_name_copynf(qctx->fname, 9600 dns_fixedname_name(&qctx->wildcardname)); 9601 qctx->need_wildcardproof = true; 9602 } 9603 9604 if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client)) { 9605 qctx->noqname = qctx->rdataset; 9606 } else { 9607 qctx->noqname = NULL; 9608 } 9609 9610 if (!qctx->is_zone && RECURSIONOK(qctx->client)) { 9611 query_prefetch(qctx->client, qctx->fname, qctx->rdataset); 9612 } 9613 9614 query_addrrset(qctx, &qctx->fname, &qctx->rdataset, sigrdatasetp, 9615 qctx->dbuf, DNS_SECTION_ANSWER); 9616 9617 query_addnoqnameproof(qctx); 9618 9619 /* 9620 * We set the PARTIALANSWER attribute so that if anything goes 9621 * wrong later on, we'll return what we've got so far. 9622 */ 9623 qctx->client->query.attributes |= NS_QUERYATTR_PARTIALANSWER; 9624 9625 /* 9626 * Reset qname to be the target name of the CNAME and restart 9627 * the query. 9628 */ 9629 tname = NULL; 9630 result = dns_message_gettempname(qctx->client->message, &tname); 9631 if (result != ISC_R_SUCCESS) { 9632 return (ns_query_done(qctx)); 9633 } 9634 9635 result = dns_rdataset_first(trdataset); 9636 if (result != ISC_R_SUCCESS) { 9637 dns_message_puttempname(qctx->client->message, &tname); 9638 return (ns_query_done(qctx)); 9639 } 9640 9641 dns_rdataset_current(trdataset, &rdata); 9642 result = dns_rdata_tostruct(&rdata, &cname, NULL); 9643 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9644 dns_rdata_reset(&rdata); 9645 9646 dns_name_init(tname, NULL); 9647 dns_name_dup(&cname.cname, qctx->client->mctx, tname); 9648 9649 dns_rdata_freestruct(&cname); 9650 ns_client_qnamereplace(qctx->client, tname); 9651 qctx->want_restart = true; 9652 if (!WANTRECURSION(qctx->client)) { 9653 qctx->options |= DNS_GETDB_NOLOG; 9654 } 9655 9656 query_addauth(qctx); 9657 9658 return (ns_query_done(qctx)); 9659 9660 cleanup: 9661 return (result); 9662 } 9663 9664 /* 9665 * Handle DNAME responses. 9666 */ 9667 static isc_result_t 9668 query_dname(query_ctx_t *qctx) { 9669 dns_name_t *tname, *prefix; 9670 dns_rdata_t rdata = DNS_RDATA_INIT; 9671 dns_rdata_dname_t dname; 9672 dns_fixedname_t fixed; 9673 dns_rdataset_t *trdataset; 9674 dns_rdataset_t **sigrdatasetp = NULL; 9675 dns_namereln_t namereln; 9676 isc_buffer_t b; 9677 int order; 9678 isc_result_t result; 9679 unsigned int nlabels; 9680 9681 CCTRACE(ISC_LOG_DEBUG(3), "query_dname"); 9682 9683 CALL_HOOK(NS_QUERY_DNAME_BEGIN, qctx); 9684 9685 /* 9686 * Compare the current qname to the found name. We need 9687 * to know how many labels and bits are in common because 9688 * we're going to have to split qname later on. 9689 */ 9690 namereln = dns_name_fullcompare(qctx->client->query.qname, qctx->fname, 9691 &order, &nlabels); 9692 INSIST(namereln == dns_namereln_subdomain); 9693 9694 /* 9695 * Keep a copy of the rdataset. We have to do this because 9696 * query_addrrset may clear 'rdataset' (to prevent the 9697 * cleanup code from cleaning it up). 9698 */ 9699 trdataset = qctx->rdataset; 9700 9701 /* 9702 * Add the DNAME to the answer section. 9703 */ 9704 if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) { 9705 sigrdatasetp = &qctx->sigrdataset; 9706 } 9707 9708 if (WANTDNSSEC(qctx->client) && 9709 (qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) 9710 { 9711 dns_fixedname_init(&qctx->wildcardname); 9712 dns_name_copynf(qctx->fname, 9713 dns_fixedname_name(&qctx->wildcardname)); 9714 qctx->need_wildcardproof = true; 9715 } 9716 9717 if (!qctx->is_zone && RECURSIONOK(qctx->client)) { 9718 query_prefetch(qctx->client, qctx->fname, qctx->rdataset); 9719 } 9720 query_addrrset(qctx, &qctx->fname, &qctx->rdataset, sigrdatasetp, 9721 qctx->dbuf, DNS_SECTION_ANSWER); 9722 9723 /* 9724 * We set the PARTIALANSWER attribute so that if anything goes 9725 * wrong later on, we'll return what we've got so far. 9726 */ 9727 qctx->client->query.attributes |= NS_QUERYATTR_PARTIALANSWER; 9728 9729 /* 9730 * Get the target name of the DNAME. 9731 */ 9732 tname = NULL; 9733 result = dns_message_gettempname(qctx->client->message, &tname); 9734 if (result != ISC_R_SUCCESS) { 9735 return (ns_query_done(qctx)); 9736 } 9737 9738 result = dns_rdataset_first(trdataset); 9739 if (result != ISC_R_SUCCESS) { 9740 dns_message_puttempname(qctx->client->message, &tname); 9741 return (ns_query_done(qctx)); 9742 } 9743 9744 dns_rdataset_current(trdataset, &rdata); 9745 result = dns_rdata_tostruct(&rdata, &dname, NULL); 9746 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9747 dns_rdata_reset(&rdata); 9748 9749 dns_name_clone(&dname.dname, tname); 9750 dns_rdata_freestruct(&dname); 9751 9752 /* 9753 * Construct the new qname consisting of 9754 * <found name prefix>.<dname target> 9755 */ 9756 prefix = dns_fixedname_initname(&fixed); 9757 dns_name_split(qctx->client->query.qname, nlabels, prefix, NULL); 9758 INSIST(qctx->fname == NULL); 9759 qctx->dbuf = ns_client_getnamebuf(qctx->client); 9760 if (qctx->dbuf == NULL) { 9761 dns_message_puttempname(qctx->client->message, &tname); 9762 return (ns_query_done(qctx)); 9763 } 9764 qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b); 9765 if (qctx->fname == NULL) { 9766 dns_message_puttempname(qctx->client->message, &tname); 9767 return (ns_query_done(qctx)); 9768 } 9769 result = dns_name_concatenate(prefix, tname, qctx->fname, NULL); 9770 dns_message_puttempname(qctx->client->message, &tname); 9771 9772 /* 9773 * RFC2672, section 4.1, subsection 3c says 9774 * we should return YXDOMAIN if the constructed 9775 * name would be too long. 9776 */ 9777 if (result == DNS_R_NAMETOOLONG) { 9778 qctx->client->message->rcode = dns_rcode_yxdomain; 9779 } 9780 if (result != ISC_R_SUCCESS) { 9781 return (ns_query_done(qctx)); 9782 } 9783 9784 ns_client_keepname(qctx->client, qctx->fname, qctx->dbuf); 9785 9786 /* 9787 * Synthesize a CNAME consisting of 9788 * <old qname> <dname ttl> CNAME <new qname> 9789 * with <dname trust value> 9790 * 9791 * Synthesize a CNAME so old old clients that don't understand 9792 * DNAME can chain. 9793 * 9794 * We do not try to synthesize a signature because we hope 9795 * that security aware servers will understand DNAME. Also, 9796 * even if we had an online key, making a signature 9797 * on-the-fly is costly, and not really legitimate anyway 9798 * since the synthesized CNAME is NOT in the zone. 9799 */ 9800 result = query_addcname(qctx, trdataset->trust, trdataset->ttl); 9801 if (result != ISC_R_SUCCESS) { 9802 return (ns_query_done(qctx)); 9803 } 9804 9805 /* 9806 * Switch to the new qname and restart. 9807 */ 9808 ns_client_qnamereplace(qctx->client, qctx->fname); 9809 qctx->fname = NULL; 9810 qctx->want_restart = true; 9811 if (!WANTRECURSION(qctx->client)) { 9812 qctx->options |= DNS_GETDB_NOLOG; 9813 } 9814 9815 query_addauth(qctx); 9816 9817 return (ns_query_done(qctx)); 9818 9819 cleanup: 9820 return (result); 9821 } 9822 9823 /*% 9824 * Add CNAME to response. 9825 */ 9826 static isc_result_t 9827 query_addcname(query_ctx_t *qctx, dns_trust_t trust, dns_ttl_t ttl) { 9828 ns_client_t *client = qctx->client; 9829 dns_rdataset_t *rdataset = NULL; 9830 dns_rdatalist_t *rdatalist = NULL; 9831 dns_rdata_t *rdata = NULL; 9832 isc_region_t r; 9833 dns_name_t *aname = NULL; 9834 isc_result_t result; 9835 9836 result = dns_message_gettempname(client->message, &aname); 9837 if (result != ISC_R_SUCCESS) { 9838 return (result); 9839 } 9840 dns_name_dup(client->query.qname, client->mctx, aname); 9841 9842 result = dns_message_gettemprdatalist(client->message, &rdatalist); 9843 if (result != ISC_R_SUCCESS) { 9844 dns_message_puttempname(client->message, &aname); 9845 return (result); 9846 } 9847 9848 result = dns_message_gettemprdata(client->message, &rdata); 9849 if (result != ISC_R_SUCCESS) { 9850 dns_message_puttempname(client->message, &aname); 9851 dns_message_puttemprdatalist(client->message, &rdatalist); 9852 return (result); 9853 } 9854 9855 result = dns_message_gettemprdataset(client->message, &rdataset); 9856 if (result != ISC_R_SUCCESS) { 9857 dns_message_puttempname(client->message, &aname); 9858 dns_message_puttemprdatalist(client->message, &rdatalist); 9859 dns_message_puttemprdata(client->message, &rdata); 9860 return (result); 9861 } 9862 9863 rdatalist->type = dns_rdatatype_cname; 9864 rdatalist->rdclass = client->message->rdclass; 9865 rdatalist->ttl = ttl; 9866 9867 dns_name_toregion(qctx->fname, &r); 9868 rdata->data = r.base; 9869 rdata->length = r.length; 9870 rdata->rdclass = client->message->rdclass; 9871 rdata->type = dns_rdatatype_cname; 9872 9873 ISC_LIST_APPEND(rdatalist->rdata, rdata, link); 9874 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == 9875 ISC_R_SUCCESS); 9876 rdataset->trust = trust; 9877 dns_rdataset_setownercase(rdataset, aname); 9878 9879 query_addrrset(qctx, &aname, &rdataset, NULL, NULL, DNS_SECTION_ANSWER); 9880 if (rdataset != NULL) { 9881 if (dns_rdataset_isassociated(rdataset)) { 9882 dns_rdataset_disassociate(rdataset); 9883 } 9884 dns_message_puttemprdataset(client->message, &rdataset); 9885 } 9886 if (aname != NULL) { 9887 dns_message_puttempname(client->message, &aname); 9888 } 9889 9890 return (ISC_R_SUCCESS); 9891 } 9892 9893 /*% 9894 * Prepare to respond: determine whether a wildcard proof is needed, 9895 * then hand off to query_respond() or (for type ANY queries) 9896 * query_respond_any(). 9897 */ 9898 static isc_result_t 9899 query_prepresponse(query_ctx_t *qctx) { 9900 isc_result_t result; 9901 9902 CCTRACE(ISC_LOG_DEBUG(3), "query_prepresponse"); 9903 9904 CALL_HOOK(NS_QUERY_PREP_RESPONSE_BEGIN, qctx); 9905 9906 if (WANTDNSSEC(qctx->client) && 9907 (qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) 9908 { 9909 dns_fixedname_init(&qctx->wildcardname); 9910 dns_name_copynf(qctx->fname, 9911 dns_fixedname_name(&qctx->wildcardname)); 9912 qctx->need_wildcardproof = true; 9913 } 9914 9915 if (qctx->type == dns_rdatatype_any) { 9916 return (query_respond_any(qctx)); 9917 } 9918 9919 result = query_zerottl_refetch(qctx); 9920 if (result != ISC_R_COMPLETE) { 9921 return (result); 9922 } 9923 9924 return (query_respond(qctx)); 9925 9926 cleanup: 9927 return (result); 9928 } 9929 9930 /*% 9931 * Add SOA to the authority section when sending negative responses 9932 * (or to the additional section if sending negative responses triggered 9933 * by RPZ rewriting.) 9934 */ 9935 static isc_result_t 9936 query_addsoa(query_ctx_t *qctx, unsigned int override_ttl, 9937 dns_section_t section) { 9938 ns_client_t *client = qctx->client; 9939 dns_name_t *name; 9940 dns_dbnode_t *node; 9941 isc_result_t result, eresult; 9942 dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; 9943 dns_rdataset_t **sigrdatasetp = NULL; 9944 dns_clientinfomethods_t cm; 9945 dns_clientinfo_t ci; 9946 9947 CTRACE(ISC_LOG_DEBUG(3), "query_addsoa"); 9948 /* 9949 * Initialization. 9950 */ 9951 eresult = ISC_R_SUCCESS; 9952 name = NULL; 9953 rdataset = NULL; 9954 node = NULL; 9955 9956 dns_clientinfomethods_init(&cm, ns_client_sourceip); 9957 dns_clientinfo_init(&ci, client, NULL); 9958 9959 /* 9960 * Don't add the SOA record for test which set "-T nosoa". 9961 */ 9962 if (((client->sctx->options & NS_SERVER_NOSOA) != 0) && 9963 (!WANTDNSSEC(client) || !dns_rdataset_isassociated(qctx->rdataset))) 9964 { 9965 return (ISC_R_SUCCESS); 9966 } 9967 9968 /* 9969 * Get resources and make 'name' be the database origin. 9970 */ 9971 result = dns_message_gettempname(client->message, &name); 9972 if (result != ISC_R_SUCCESS) { 9973 return (result); 9974 } 9975 dns_name_init(name, NULL); 9976 dns_name_clone(dns_db_origin(qctx->db), name); 9977 rdataset = ns_client_newrdataset(client); 9978 if (rdataset == NULL) { 9979 CTRACE(ISC_LOG_ERROR, "unable to allocate rdataset"); 9980 eresult = DNS_R_SERVFAIL; 9981 goto cleanup; 9982 } 9983 if (WANTDNSSEC(client) && dns_db_issecure(qctx->db)) { 9984 sigrdataset = ns_client_newrdataset(client); 9985 if (sigrdataset == NULL) { 9986 CTRACE(ISC_LOG_ERROR, "unable to allocate sigrdataset"); 9987 eresult = DNS_R_SERVFAIL; 9988 goto cleanup; 9989 } 9990 } 9991 9992 /* 9993 * Find the SOA. 9994 */ 9995 result = dns_db_getoriginnode(qctx->db, &node); 9996 if (result == ISC_R_SUCCESS) { 9997 result = dns_db_findrdataset(qctx->db, node, qctx->version, 9998 dns_rdatatype_soa, 0, client->now, 9999 rdataset, sigrdataset); 10000 } else { 10001 dns_fixedname_t foundname; 10002 dns_name_t *fname; 10003 10004 fname = dns_fixedname_initname(&foundname); 10005 10006 result = dns_db_findext(qctx->db, name, qctx->version, 10007 dns_rdatatype_soa, 10008 client->query.dboptions, 0, &node, 10009 fname, &cm, &ci, rdataset, sigrdataset); 10010 } 10011 if (result != ISC_R_SUCCESS) { 10012 /* 10013 * This is bad. We tried to get the SOA RR at the zone top 10014 * and it didn't work! 10015 */ 10016 CTRACE(ISC_LOG_ERROR, "unable to find SOA RR at zone apex"); 10017 eresult = DNS_R_SERVFAIL; 10018 } else { 10019 /* 10020 * Extract the SOA MINIMUM. 10021 */ 10022 dns_rdata_soa_t soa; 10023 dns_rdata_t rdata = DNS_RDATA_INIT; 10024 result = dns_rdataset_first(rdataset); 10025 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10026 dns_rdataset_current(rdataset, &rdata); 10027 result = dns_rdata_tostruct(&rdata, &soa, NULL); 10028 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10029 10030 if (override_ttl != UINT32_MAX && override_ttl < rdataset->ttl) 10031 { 10032 rdataset->ttl = override_ttl; 10033 if (sigrdataset != NULL) { 10034 sigrdataset->ttl = override_ttl; 10035 } 10036 } 10037 10038 /* 10039 * Add the SOA and its SIG to the response, with the 10040 * TTLs adjusted per RFC2308 section 3. 10041 */ 10042 if (rdataset->ttl > soa.minimum) { 10043 rdataset->ttl = soa.minimum; 10044 } 10045 if (sigrdataset != NULL && sigrdataset->ttl > soa.minimum) { 10046 sigrdataset->ttl = soa.minimum; 10047 } 10048 10049 if (sigrdataset != NULL) { 10050 sigrdatasetp = &sigrdataset; 10051 } else { 10052 sigrdatasetp = NULL; 10053 } 10054 10055 if (section == DNS_SECTION_ADDITIONAL) { 10056 rdataset->attributes |= DNS_RDATASETATTR_REQUIRED; 10057 } 10058 query_addrrset(qctx, &name, &rdataset, sigrdatasetp, NULL, 10059 section); 10060 } 10061 10062 cleanup: 10063 ns_client_putrdataset(client, &rdataset); 10064 if (sigrdataset != NULL) { 10065 ns_client_putrdataset(client, &sigrdataset); 10066 } 10067 if (name != NULL) { 10068 ns_client_releasename(client, &name); 10069 } 10070 if (node != NULL) { 10071 dns_db_detachnode(qctx->db, &node); 10072 } 10073 10074 return (eresult); 10075 } 10076 10077 /*% 10078 * Add NS to authority section (used when the zone apex is already known). 10079 */ 10080 static isc_result_t 10081 query_addns(query_ctx_t *qctx) { 10082 ns_client_t *client = qctx->client; 10083 isc_result_t result, eresult; 10084 dns_name_t *name = NULL, *fname; 10085 dns_dbnode_t *node = NULL; 10086 dns_fixedname_t foundname; 10087 dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; 10088 dns_rdataset_t **sigrdatasetp = NULL; 10089 dns_clientinfomethods_t cm; 10090 dns_clientinfo_t ci; 10091 10092 CTRACE(ISC_LOG_DEBUG(3), "query_addns"); 10093 10094 /* 10095 * Initialization. 10096 */ 10097 eresult = ISC_R_SUCCESS; 10098 fname = dns_fixedname_initname(&foundname); 10099 10100 dns_clientinfomethods_init(&cm, ns_client_sourceip); 10101 dns_clientinfo_init(&ci, client, NULL); 10102 10103 /* 10104 * Get resources and make 'name' be the database origin. 10105 */ 10106 result = dns_message_gettempname(client->message, &name); 10107 if (result != ISC_R_SUCCESS) { 10108 CTRACE(ISC_LOG_DEBUG(3), "query_addns: dns_message_gettempname " 10109 "failed: done"); 10110 return (result); 10111 } 10112 dns_name_init(name, NULL); 10113 dns_name_clone(dns_db_origin(qctx->db), name); 10114 rdataset = ns_client_newrdataset(client); 10115 if (rdataset == NULL) { 10116 CTRACE(ISC_LOG_ERROR, "query_addns: ns_client_newrdataset " 10117 "failed"); 10118 eresult = DNS_R_SERVFAIL; 10119 goto cleanup; 10120 } 10121 10122 if (WANTDNSSEC(client) && dns_db_issecure(qctx->db)) { 10123 sigrdataset = ns_client_newrdataset(client); 10124 if (sigrdataset == NULL) { 10125 CTRACE(ISC_LOG_ERROR, "query_addns: " 10126 "ns_client_newrdataset failed"); 10127 eresult = DNS_R_SERVFAIL; 10128 goto cleanup; 10129 } 10130 } 10131 10132 /* 10133 * Find the NS rdataset. 10134 */ 10135 result = dns_db_getoriginnode(qctx->db, &node); 10136 if (result == ISC_R_SUCCESS) { 10137 result = dns_db_findrdataset(qctx->db, node, qctx->version, 10138 dns_rdatatype_ns, 0, client->now, 10139 rdataset, sigrdataset); 10140 } else { 10141 CTRACE(ISC_LOG_DEBUG(3), "query_addns: calling dns_db_find"); 10142 result = dns_db_findext(qctx->db, name, NULL, dns_rdatatype_ns, 10143 client->query.dboptions, 0, &node, 10144 fname, &cm, &ci, rdataset, sigrdataset); 10145 CTRACE(ISC_LOG_DEBUG(3), "query_addns: dns_db_find complete"); 10146 } 10147 if (result != ISC_R_SUCCESS) { 10148 CTRACE(ISC_LOG_ERROR, "query_addns: " 10149 "dns_db_findrdataset or dns_db_find " 10150 "failed"); 10151 /* 10152 * This is bad. We tried to get the NS rdataset at the zone 10153 * top and it didn't work! 10154 */ 10155 eresult = DNS_R_SERVFAIL; 10156 } else { 10157 if (sigrdataset != NULL) { 10158 sigrdatasetp = &sigrdataset; 10159 } 10160 query_addrrset(qctx, &name, &rdataset, sigrdatasetp, NULL, 10161 DNS_SECTION_AUTHORITY); 10162 } 10163 10164 cleanup: 10165 CTRACE(ISC_LOG_DEBUG(3), "query_addns: cleanup"); 10166 ns_client_putrdataset(client, &rdataset); 10167 if (sigrdataset != NULL) { 10168 ns_client_putrdataset(client, &sigrdataset); 10169 } 10170 if (name != NULL) { 10171 ns_client_releasename(client, &name); 10172 } 10173 if (node != NULL) { 10174 dns_db_detachnode(qctx->db, &node); 10175 } 10176 10177 CTRACE(ISC_LOG_DEBUG(3), "query_addns: done"); 10178 return (eresult); 10179 } 10180 10181 /*% 10182 * Find the zone cut and add the best NS rrset to the authority section. 10183 */ 10184 static void 10185 query_addbestns(query_ctx_t *qctx) { 10186 ns_client_t *client = qctx->client; 10187 dns_db_t *db = NULL, *zdb = NULL; 10188 dns_dbnode_t *node = NULL; 10189 dns_name_t *fname = NULL, *zfname = NULL; 10190 dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; 10191 dns_rdataset_t *zrdataset = NULL, *zsigrdataset = NULL; 10192 bool is_zone = false, use_zone = false; 10193 isc_buffer_t *dbuf = NULL; 10194 isc_result_t result; 10195 dns_dbversion_t *version = NULL; 10196 dns_zone_t *zone = NULL; 10197 isc_buffer_t b; 10198 dns_clientinfomethods_t cm; 10199 dns_clientinfo_t ci; 10200 10201 CTRACE(ISC_LOG_DEBUG(3), "query_addbestns"); 10202 10203 dns_clientinfomethods_init(&cm, ns_client_sourceip); 10204 dns_clientinfo_init(&ci, client, NULL); 10205 10206 /* 10207 * Find the right database. 10208 */ 10209 result = query_getdb(client, client->query.qname, dns_rdatatype_ns, 0, 10210 &zone, &db, &version, &is_zone); 10211 if (result != ISC_R_SUCCESS) { 10212 goto cleanup; 10213 } 10214 10215 db_find: 10216 /* 10217 * We'll need some resources... 10218 */ 10219 dbuf = ns_client_getnamebuf(client); 10220 if (dbuf == NULL) { 10221 goto cleanup; 10222 } 10223 fname = ns_client_newname(client, dbuf, &b); 10224 rdataset = ns_client_newrdataset(client); 10225 if (fname == NULL || rdataset == NULL) { 10226 goto cleanup; 10227 } 10228 10229 /* 10230 * Get the RRSIGs if the client requested them or if we may 10231 * need to validate answers from the cache. 10232 */ 10233 if (WANTDNSSEC(client) || !is_zone) { 10234 sigrdataset = ns_client_newrdataset(client); 10235 if (sigrdataset == NULL) { 10236 goto cleanup; 10237 } 10238 } 10239 10240 /* 10241 * Now look for the zonecut. 10242 */ 10243 if (is_zone) { 10244 result = dns_db_findext( 10245 db, client->query.qname, version, dns_rdatatype_ns, 10246 client->query.dboptions, client->now, &node, fname, &cm, 10247 &ci, rdataset, sigrdataset); 10248 if (result != DNS_R_DELEGATION) { 10249 goto cleanup; 10250 } 10251 if (USECACHE(client)) { 10252 ns_client_keepname(client, fname, dbuf); 10253 dns_db_detachnode(db, &node); 10254 SAVE(zdb, db); 10255 SAVE(zfname, fname); 10256 SAVE(zrdataset, rdataset); 10257 SAVE(zsigrdataset, sigrdataset); 10258 version = NULL; 10259 dns_db_attach(client->view->cachedb, &db); 10260 is_zone = false; 10261 goto db_find; 10262 } 10263 } else { 10264 result = dns_db_findzonecut( 10265 db, client->query.qname, client->query.dboptions, 10266 client->now, &node, fname, NULL, rdataset, sigrdataset); 10267 if (result == ISC_R_SUCCESS) { 10268 if (zfname != NULL && 10269 !dns_name_issubdomain(fname, zfname)) { 10270 /* 10271 * We found a zonecut in the cache, but our 10272 * zone delegation is better. 10273 */ 10274 use_zone = true; 10275 } 10276 } else if (result == ISC_R_NOTFOUND && zfname != NULL) { 10277 /* 10278 * We didn't find anything in the cache, but we 10279 * have a zone delegation, so use it. 10280 */ 10281 use_zone = true; 10282 } else { 10283 goto cleanup; 10284 } 10285 } 10286 10287 if (use_zone) { 10288 ns_client_releasename(client, &fname); 10289 /* 10290 * We've already done ns_client_keepname() on 10291 * zfname, so we must set dbuf to NULL to 10292 * prevent query_addrrset() from trying to 10293 * call ns_client_keepname() again. 10294 */ 10295 dbuf = NULL; 10296 ns_client_putrdataset(client, &rdataset); 10297 if (sigrdataset != NULL) { 10298 ns_client_putrdataset(client, &sigrdataset); 10299 } 10300 10301 if (node != NULL) { 10302 dns_db_detachnode(db, &node); 10303 } 10304 dns_db_detach(&db); 10305 10306 RESTORE(db, zdb); 10307 RESTORE(fname, zfname); 10308 RESTORE(rdataset, zrdataset); 10309 RESTORE(sigrdataset, zsigrdataset); 10310 } 10311 10312 /* 10313 * Attempt to validate RRsets that are pending or that are glue. 10314 */ 10315 if ((DNS_TRUST_PENDING(rdataset->trust) || 10316 (sigrdataset != NULL && DNS_TRUST_PENDING(sigrdataset->trust))) && 10317 !validate(client, db, fname, rdataset, sigrdataset) && 10318 !PENDINGOK(client->query.dboptions)) 10319 { 10320 goto cleanup; 10321 } 10322 10323 if ((DNS_TRUST_GLUE(rdataset->trust) || 10324 (sigrdataset != NULL && DNS_TRUST_GLUE(sigrdataset->trust))) && 10325 !validate(client, db, fname, rdataset, sigrdataset) && 10326 SECURE(client) && WANTDNSSEC(client)) 10327 { 10328 goto cleanup; 10329 } 10330 10331 /* 10332 * If the answer is secure only add NS records if they are secure 10333 * when the client may be looking for AD in the response. 10334 */ 10335 if (SECURE(client) && (WANTDNSSEC(client) || WANTAD(client)) && 10336 ((rdataset->trust != dns_trust_secure) || 10337 (sigrdataset != NULL && sigrdataset->trust != dns_trust_secure))) 10338 { 10339 goto cleanup; 10340 } 10341 10342 /* 10343 * If the client doesn't want DNSSEC we can discard the sigrdataset 10344 * now. 10345 */ 10346 if (!WANTDNSSEC(client)) { 10347 ns_client_putrdataset(client, &sigrdataset); 10348 } 10349 10350 query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf, 10351 DNS_SECTION_AUTHORITY); 10352 10353 cleanup: 10354 if (rdataset != NULL) { 10355 ns_client_putrdataset(client, &rdataset); 10356 } 10357 if (sigrdataset != NULL) { 10358 ns_client_putrdataset(client, &sigrdataset); 10359 } 10360 if (fname != NULL) { 10361 ns_client_releasename(client, &fname); 10362 } 10363 if (node != NULL) { 10364 dns_db_detachnode(db, &node); 10365 } 10366 if (db != NULL) { 10367 dns_db_detach(&db); 10368 } 10369 if (zone != NULL) { 10370 dns_zone_detach(&zone); 10371 } 10372 if (zdb != NULL) { 10373 ns_client_putrdataset(client, &zrdataset); 10374 if (zsigrdataset != NULL) { 10375 ns_client_putrdataset(client, &zsigrdataset); 10376 } 10377 if (zfname != NULL) { 10378 ns_client_releasename(client, &zfname); 10379 } 10380 dns_db_detach(&zdb); 10381 } 10382 } 10383 10384 static void 10385 query_addwildcardproof(query_ctx_t *qctx, bool ispositive, bool nodata) { 10386 ns_client_t *client = qctx->client; 10387 isc_buffer_t *dbuf, b; 10388 dns_name_t *name; 10389 dns_name_t *fname = NULL; 10390 dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; 10391 dns_fixedname_t wfixed; 10392 dns_name_t *wname; 10393 dns_dbnode_t *node = NULL; 10394 unsigned int options; 10395 unsigned int olabels, nlabels, labels; 10396 isc_result_t result; 10397 dns_rdata_t rdata = DNS_RDATA_INIT; 10398 dns_rdata_nsec_t nsec; 10399 bool have_wname; 10400 int order; 10401 dns_fixedname_t cfixed; 10402 dns_name_t *cname; 10403 dns_clientinfomethods_t cm; 10404 dns_clientinfo_t ci; 10405 10406 CTRACE(ISC_LOG_DEBUG(3), "query_addwildcardproof"); 10407 10408 dns_clientinfomethods_init(&cm, ns_client_sourceip); 10409 dns_clientinfo_init(&ci, client, NULL); 10410 10411 /* 10412 * If a name has been specifically flagged as needing 10413 * a wildcard proof then it will have been copied to 10414 * qctx->wildcardname. Otherwise we just use the client 10415 * QNAME. 10416 */ 10417 if (qctx->need_wildcardproof) { 10418 name = dns_fixedname_name(&qctx->wildcardname); 10419 } else { 10420 name = client->query.qname; 10421 } 10422 10423 /* 10424 * Get the NOQNAME proof then if !ispositive 10425 * get the NOWILDCARD proof. 10426 * 10427 * DNS_DBFIND_NOWILD finds the NSEC records that covers the 10428 * name ignoring any wildcard. From the owner and next names 10429 * of this record you can compute which wildcard (if it exists) 10430 * will match by finding the longest common suffix of the 10431 * owner name and next names with the qname and prefixing that 10432 * with the wildcard label. 10433 * 10434 * e.g. 10435 * Given: 10436 * example SOA 10437 * example NSEC b.example 10438 * b.example A 10439 * b.example NSEC a.d.example 10440 * a.d.example A 10441 * a.d.example NSEC g.f.example 10442 * g.f.example A 10443 * g.f.example NSEC z.i.example 10444 * z.i.example A 10445 * z.i.example NSEC example 10446 * 10447 * QNAME: 10448 * a.example -> example NSEC b.example 10449 * owner common example 10450 * next common example 10451 * wild *.example 10452 * d.b.example -> b.example NSEC a.d.example 10453 * owner common b.example 10454 * next common example 10455 * wild *.b.example 10456 * a.f.example -> a.d.example NSEC g.f.example 10457 * owner common example 10458 * next common f.example 10459 * wild *.f.example 10460 * j.example -> z.i.example NSEC example 10461 * owner common example 10462 * next common example 10463 * wild *.example 10464 */ 10465 options = client->query.dboptions | DNS_DBFIND_NOWILD; 10466 wname = dns_fixedname_initname(&wfixed); 10467 again: 10468 have_wname = false; 10469 /* 10470 * We'll need some resources... 10471 */ 10472 dbuf = ns_client_getnamebuf(client); 10473 if (dbuf == NULL) { 10474 goto cleanup; 10475 } 10476 fname = ns_client_newname(client, dbuf, &b); 10477 rdataset = ns_client_newrdataset(client); 10478 sigrdataset = ns_client_newrdataset(client); 10479 if (fname == NULL || rdataset == NULL || sigrdataset == NULL) { 10480 goto cleanup; 10481 } 10482 10483 result = dns_db_findext(qctx->db, name, qctx->version, 10484 dns_rdatatype_nsec, options, 0, &node, fname, 10485 &cm, &ci, rdataset, sigrdataset); 10486 if (node != NULL) { 10487 dns_db_detachnode(qctx->db, &node); 10488 } 10489 10490 if (!dns_rdataset_isassociated(rdataset)) { 10491 /* 10492 * No NSEC proof available, return NSEC3 proofs instead. 10493 */ 10494 cname = dns_fixedname_initname(&cfixed); 10495 /* 10496 * Find the closest encloser. 10497 */ 10498 dns_name_copynf(name, cname); 10499 while (result == DNS_R_NXDOMAIN) { 10500 labels = dns_name_countlabels(cname) - 1; 10501 /* 10502 * Sanity check. 10503 */ 10504 if (labels == 0U) { 10505 goto cleanup; 10506 } 10507 dns_name_split(cname, labels, NULL, cname); 10508 result = dns_db_findext(qctx->db, cname, qctx->version, 10509 dns_rdatatype_nsec, options, 0, 10510 NULL, fname, &cm, &ci, NULL, 10511 NULL); 10512 } 10513 /* 10514 * Add closest (provable) encloser NSEC3. 10515 */ 10516 query_findclosestnsec3(cname, qctx->db, qctx->version, client, 10517 rdataset, sigrdataset, fname, true, 10518 cname); 10519 if (!dns_rdataset_isassociated(rdataset)) { 10520 goto cleanup; 10521 } 10522 if (!ispositive) { 10523 query_addrrset(qctx, &fname, &rdataset, &sigrdataset, 10524 dbuf, DNS_SECTION_AUTHORITY); 10525 } 10526 10527 /* 10528 * Replace resources which were consumed by query_addrrset. 10529 */ 10530 if (fname == NULL) { 10531 dbuf = ns_client_getnamebuf(client); 10532 if (dbuf == NULL) { 10533 goto cleanup; 10534 } 10535 fname = ns_client_newname(client, dbuf, &b); 10536 } 10537 10538 if (rdataset == NULL) { 10539 rdataset = ns_client_newrdataset(client); 10540 } else if (dns_rdataset_isassociated(rdataset)) { 10541 dns_rdataset_disassociate(rdataset); 10542 } 10543 10544 if (sigrdataset == NULL) { 10545 sigrdataset = ns_client_newrdataset(client); 10546 } else if (dns_rdataset_isassociated(sigrdataset)) { 10547 dns_rdataset_disassociate(sigrdataset); 10548 } 10549 10550 if (fname == NULL || rdataset == NULL || sigrdataset == NULL) { 10551 goto cleanup; 10552 } 10553 /* 10554 * Add no qname proof. 10555 */ 10556 labels = dns_name_countlabels(cname) + 1; 10557 if (dns_name_countlabels(name) == labels) { 10558 dns_name_copynf(name, wname); 10559 } else { 10560 dns_name_split(name, labels, NULL, wname); 10561 } 10562 10563 query_findclosestnsec3(wname, qctx->db, qctx->version, client, 10564 rdataset, sigrdataset, fname, false, 10565 NULL); 10566 if (!dns_rdataset_isassociated(rdataset)) { 10567 goto cleanup; 10568 } 10569 query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf, 10570 DNS_SECTION_AUTHORITY); 10571 10572 if (ispositive) { 10573 goto cleanup; 10574 } 10575 10576 /* 10577 * Replace resources which were consumed by query_addrrset. 10578 */ 10579 if (fname == NULL) { 10580 dbuf = ns_client_getnamebuf(client); 10581 if (dbuf == NULL) { 10582 goto cleanup; 10583 } 10584 fname = ns_client_newname(client, dbuf, &b); 10585 } 10586 10587 if (rdataset == NULL) { 10588 rdataset = ns_client_newrdataset(client); 10589 } else if (dns_rdataset_isassociated(rdataset)) { 10590 dns_rdataset_disassociate(rdataset); 10591 } 10592 10593 if (sigrdataset == NULL) { 10594 sigrdataset = ns_client_newrdataset(client); 10595 } else if (dns_rdataset_isassociated(sigrdataset)) { 10596 dns_rdataset_disassociate(sigrdataset); 10597 } 10598 10599 if (fname == NULL || rdataset == NULL || sigrdataset == NULL) { 10600 goto cleanup; 10601 } 10602 /* 10603 * Add the no wildcard proof. 10604 */ 10605 result = dns_name_concatenate(dns_wildcardname, cname, wname, 10606 NULL); 10607 if (result != ISC_R_SUCCESS) { 10608 goto cleanup; 10609 } 10610 10611 query_findclosestnsec3(wname, qctx->db, qctx->version, client, 10612 rdataset, sigrdataset, fname, nodata, 10613 NULL); 10614 if (!dns_rdataset_isassociated(rdataset)) { 10615 goto cleanup; 10616 } 10617 query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf, 10618 DNS_SECTION_AUTHORITY); 10619 10620 goto cleanup; 10621 } else if (result == DNS_R_NXDOMAIN) { 10622 if (!ispositive) { 10623 result = dns_rdataset_first(rdataset); 10624 } 10625 if (result == ISC_R_SUCCESS) { 10626 dns_rdataset_current(rdataset, &rdata); 10627 result = dns_rdata_tostruct(&rdata, &nsec, NULL); 10628 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10629 (void)dns_name_fullcompare(name, fname, &order, 10630 &olabels); 10631 (void)dns_name_fullcompare(name, &nsec.next, &order, 10632 &nlabels); 10633 /* 10634 * Check for a pathological condition created when 10635 * serving some malformed signed zones and bail out. 10636 */ 10637 if (dns_name_countlabels(name) == nlabels) { 10638 goto cleanup; 10639 } 10640 10641 if (olabels > nlabels) { 10642 dns_name_split(name, olabels, NULL, wname); 10643 } else { 10644 dns_name_split(name, nlabels, NULL, wname); 10645 } 10646 result = dns_name_concatenate(dns_wildcardname, wname, 10647 wname, NULL); 10648 if (result == ISC_R_SUCCESS) { 10649 have_wname = true; 10650 } 10651 dns_rdata_freestruct(&nsec); 10652 } 10653 query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf, 10654 DNS_SECTION_AUTHORITY); 10655 } 10656 if (rdataset != NULL) { 10657 ns_client_putrdataset(client, &rdataset); 10658 } 10659 if (sigrdataset != NULL) { 10660 ns_client_putrdataset(client, &sigrdataset); 10661 } 10662 if (fname != NULL) { 10663 ns_client_releasename(client, &fname); 10664 } 10665 if (have_wname) { 10666 ispositive = true; /* prevent loop */ 10667 if (!dns_name_equal(name, wname)) { 10668 name = wname; 10669 goto again; 10670 } 10671 } 10672 cleanup: 10673 if (rdataset != NULL) { 10674 ns_client_putrdataset(client, &rdataset); 10675 } 10676 if (sigrdataset != NULL) { 10677 ns_client_putrdataset(client, &sigrdataset); 10678 } 10679 if (fname != NULL) { 10680 ns_client_releasename(client, &fname); 10681 } 10682 } 10683 10684 /*% 10685 * Add NS records, and NSEC/NSEC3 wildcard proof records if needed, 10686 * to the authority section. 10687 */ 10688 static void 10689 query_addauth(query_ctx_t *qctx) { 10690 CCTRACE(ISC_LOG_DEBUG(3), "query_addauth"); 10691 /* 10692 * Add NS records to the authority section (if we haven't already 10693 * added them to the answer section). 10694 */ 10695 if (!qctx->want_restart && !NOAUTHORITY(qctx->client)) { 10696 if (qctx->is_zone) { 10697 if (!qctx->answer_has_ns) { 10698 (void)query_addns(qctx); 10699 } 10700 } else if (!qctx->answer_has_ns && 10701 qctx->qtype != dns_rdatatype_ns) { 10702 if (qctx->fname != NULL) { 10703 ns_client_releasename(qctx->client, 10704 &qctx->fname); 10705 } 10706 query_addbestns(qctx); 10707 } 10708 } 10709 10710 /* 10711 * Add NSEC records to the authority section if they're needed for 10712 * DNSSEC wildcard proofs. 10713 */ 10714 if (qctx->need_wildcardproof && dns_db_issecure(qctx->db)) { 10715 query_addwildcardproof(qctx, true, false); 10716 } 10717 } 10718 10719 /* 10720 * Find the sort order of 'rdata' in the topology-like 10721 * ACL forming the second element in a 2-element top-level 10722 * sortlist statement. 10723 */ 10724 static int 10725 query_sortlist_order_2element(const dns_rdata_t *rdata, const void *arg) { 10726 isc_netaddr_t netaddr; 10727 10728 if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS) { 10729 return (INT_MAX); 10730 } 10731 return (ns_sortlist_addrorder2(&netaddr, arg)); 10732 } 10733 10734 /* 10735 * Find the sort order of 'rdata' in the matching element 10736 * of a 1-element top-level sortlist statement. 10737 */ 10738 static int 10739 query_sortlist_order_1element(const dns_rdata_t *rdata, const void *arg) { 10740 isc_netaddr_t netaddr; 10741 10742 if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS) { 10743 return (INT_MAX); 10744 } 10745 return (ns_sortlist_addrorder1(&netaddr, arg)); 10746 } 10747 10748 /* 10749 * Find the sortlist statement that applies to 'client' and set up 10750 * the sortlist info in in client->message appropriately. 10751 */ 10752 static void 10753 query_setup_sortlist(query_ctx_t *qctx) { 10754 isc_netaddr_t netaddr; 10755 ns_client_t *client = qctx->client; 10756 dns_aclenv_t *env = 10757 ns_interfacemgr_getaclenv(client->manager->interface->mgr); 10758 const void *order_arg = NULL; 10759 10760 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); 10761 switch (ns_sortlist_setup(client->view->sortlist, env, &netaddr, 10762 &order_arg)) { 10763 case NS_SORTLISTTYPE_1ELEMENT: 10764 dns_message_setsortorder(client->message, 10765 query_sortlist_order_1element, env, 10766 NULL, order_arg); 10767 break; 10768 case NS_SORTLISTTYPE_2ELEMENT: 10769 dns_message_setsortorder(client->message, 10770 query_sortlist_order_2element, env, 10771 order_arg, NULL); 10772 break; 10773 case NS_SORTLISTTYPE_NONE: 10774 break; 10775 default: 10776 INSIST(0); 10777 ISC_UNREACHABLE(); 10778 } 10779 } 10780 10781 /* 10782 * When sending a referral, if the answer to the question is 10783 * in the glue, sort it to the start of the additional section. 10784 */ 10785 static inline void 10786 query_glueanswer(query_ctx_t *qctx) { 10787 const dns_namelist_t *secs = qctx->client->message->sections; 10788 const dns_section_t section = DNS_SECTION_ADDITIONAL; 10789 dns_name_t *name; 10790 dns_message_t *msg; 10791 dns_rdataset_t *rdataset = NULL; 10792 10793 if (!ISC_LIST_EMPTY(secs[DNS_SECTION_ANSWER]) || 10794 qctx->client->message->rcode != dns_rcode_noerror || 10795 (qctx->qtype != dns_rdatatype_a && 10796 qctx->qtype != dns_rdatatype_aaaa)) 10797 { 10798 return; 10799 } 10800 10801 msg = qctx->client->message; 10802 for (name = ISC_LIST_HEAD(msg->sections[section]); name != NULL; 10803 name = ISC_LIST_NEXT(name, link)) 10804 { 10805 if (dns_name_equal(name, qctx->client->query.qname)) { 10806 for (rdataset = ISC_LIST_HEAD(name->list); 10807 rdataset != NULL; 10808 rdataset = ISC_LIST_NEXT(rdataset, link)) 10809 { 10810 if (rdataset->type == qctx->qtype) { 10811 break; 10812 } 10813 } 10814 break; 10815 } 10816 } 10817 if (rdataset != NULL) { 10818 ISC_LIST_UNLINK(msg->sections[section], name, link); 10819 ISC_LIST_PREPEND(msg->sections[section], name, link); 10820 ISC_LIST_UNLINK(name->list, rdataset, link); 10821 ISC_LIST_PREPEND(name->list, rdataset, link); 10822 rdataset->attributes |= DNS_RDATASETATTR_REQUIRED; 10823 } 10824 } 10825 10826 isc_result_t 10827 ns_query_done(query_ctx_t *qctx) { 10828 isc_result_t result; 10829 const dns_namelist_t *secs = qctx->client->message->sections; 10830 10831 CCTRACE(ISC_LOG_DEBUG(3), "ns_query_done"); 10832 10833 CALL_HOOK(NS_QUERY_DONE_BEGIN, qctx); 10834 10835 /* 10836 * General cleanup. 10837 */ 10838 qctx->rpz_st = qctx->client->query.rpz_st; 10839 if (qctx->rpz_st != NULL && 10840 (qctx->rpz_st->state & DNS_RPZ_RECURSING) == 0) { 10841 rpz_match_clear(qctx->rpz_st); 10842 qctx->rpz_st->state &= ~DNS_RPZ_DONE_QNAME; 10843 } 10844 10845 qctx_clean(qctx); 10846 qctx_freedata(qctx); 10847 10848 if (qctx->client->query.gluedb != NULL) { 10849 dns_db_detach(&qctx->client->query.gluedb); 10850 } 10851 10852 /* 10853 * Clear the AA bit if we're not authoritative. 10854 */ 10855 if (qctx->client->query.restarts == 0 && !qctx->authoritative) { 10856 qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AA; 10857 } 10858 10859 /* 10860 * Do we need to restart the query (e.g. for CNAME chaining)? 10861 */ 10862 if (qctx->want_restart && qctx->client->query.restarts < MAX_RESTARTS) { 10863 qctx->client->query.restarts++; 10864 return (ns__query_start(qctx)); 10865 } 10866 10867 if (qctx->result != ISC_R_SUCCESS && 10868 (!PARTIALANSWER(qctx->client) || WANTRECURSION(qctx->client) || 10869 qctx->result == DNS_R_DROP)) 10870 { 10871 if (qctx->result == DNS_R_DUPLICATE || 10872 qctx->result == DNS_R_DROP) { 10873 /* 10874 * This was a duplicate query that we are 10875 * recursing on or the result of rate limiting. 10876 * Don't send a response now for a duplicate query, 10877 * because the original will still cause a response. 10878 */ 10879 query_next(qctx->client, qctx->result); 10880 } else { 10881 /* 10882 * If we don't have any answer to give the client, 10883 * or if the client requested recursion and thus wanted 10884 * the complete answer, send an error response. 10885 */ 10886 INSIST(qctx->line >= 0); 10887 query_error(qctx->client, qctx->result, qctx->line); 10888 } 10889 10890 qctx->detach_client = true; 10891 return (qctx->result); 10892 } 10893 10894 /* 10895 * If we're recursing then just return; the query will 10896 * resume when recursion ends. 10897 */ 10898 if (RECURSING(qctx->client)) { 10899 return (qctx->result); 10900 } 10901 10902 /* 10903 * We are done. Set up sortlist data for the message 10904 * rendering code, sort the answer to the front of the 10905 * additional section if necessary, make a final tweak 10906 * to the AA bit if the auth-nxdomain config option 10907 * says so, then render and send the response. 10908 */ 10909 query_setup_sortlist(qctx); 10910 query_glueanswer(qctx); 10911 10912 if (qctx->client->message->rcode == dns_rcode_nxdomain && 10913 qctx->view->auth_nxdomain) 10914 { 10915 qctx->client->message->flags |= DNS_MESSAGEFLAG_AA; 10916 } 10917 10918 /* 10919 * If the response is somehow unexpected for the client and this 10920 * is a result of recursion, return an error to the caller 10921 * to indicate it may need to be logged. 10922 */ 10923 if (qctx->resuming && 10924 (ISC_LIST_EMPTY(secs[DNS_SECTION_ANSWER]) || 10925 qctx->client->message->rcode != dns_rcode_noerror)) 10926 { 10927 qctx->result = ISC_R_FAILURE; 10928 } 10929 10930 CALL_HOOK(NS_QUERY_DONE_SEND, qctx); 10931 10932 query_send(qctx->client); 10933 10934 qctx->detach_client = true; 10935 return (qctx->result); 10936 10937 cleanup: 10938 return (result); 10939 } 10940 10941 static inline void 10942 log_tat(ns_client_t *client) { 10943 char namebuf[DNS_NAME_FORMATSIZE]; 10944 char clientbuf[ISC_NETADDR_FORMATSIZE]; 10945 char classbuf[DNS_RDATACLASS_FORMATSIZE]; 10946 isc_netaddr_t netaddr; 10947 char *tags = NULL; 10948 size_t taglen = 0; 10949 10950 if (!isc_log_wouldlog(ns_lctx, ISC_LOG_INFO)) { 10951 return; 10952 } 10953 10954 if ((client->query.qtype != dns_rdatatype_null || 10955 !dns_name_istat(client->query.qname)) && 10956 (client->keytag == NULL || 10957 client->query.qtype != dns_rdatatype_dnskey)) 10958 { 10959 return; 10960 } 10961 10962 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); 10963 dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); 10964 isc_netaddr_format(&netaddr, clientbuf, sizeof(clientbuf)); 10965 dns_rdataclass_format(client->view->rdclass, classbuf, 10966 sizeof(classbuf)); 10967 10968 if (client->query.qtype == dns_rdatatype_dnskey) { 10969 uint16_t keytags = client->keytag_len / 2; 10970 size_t len = taglen = sizeof("65000") * keytags + 1; 10971 char *cp = tags = isc_mem_get(client->mctx, taglen); 10972 int i = 0; 10973 10974 INSIST(client->keytag != NULL); 10975 if (tags != NULL) { 10976 while (keytags-- > 0U) { 10977 int n; 10978 uint16_t keytag; 10979 keytag = (client->keytag[i * 2] << 8) | 10980 client->keytag[i * 2 + 1]; 10981 n = snprintf(cp, len, " %u", keytag); 10982 if (n > 0 && (size_t)n <= len) { 10983 cp += n; 10984 len -= n; 10985 i++; 10986 } else { 10987 break; 10988 } 10989 } 10990 } 10991 } 10992 10993 isc_log_write(ns_lctx, NS_LOGCATEGORY_TAT, NS_LOGMODULE_QUERY, 10994 ISC_LOG_INFO, "trust-anchor-telemetry '%s/%s' from %s%s", 10995 namebuf, classbuf, clientbuf, tags != NULL ? tags : ""); 10996 if (tags != NULL) { 10997 isc_mem_put(client->mctx, tags, taglen); 10998 } 10999 } 11000 11001 static inline void 11002 log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) { 11003 char namebuf[DNS_NAME_FORMATSIZE]; 11004 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 11005 char classbuf[DNS_RDATACLASS_FORMATSIZE]; 11006 char onbuf[ISC_NETADDR_FORMATSIZE]; 11007 char ecsbuf[DNS_ECS_FORMATSIZE + sizeof(" [ECS ]") - 1] = { 0 }; 11008 char ednsbuf[sizeof("E(65535)")] = { 0 }; 11009 dns_rdataset_t *rdataset; 11010 int level = ISC_LOG_INFO; 11011 11012 if (!isc_log_wouldlog(ns_lctx, level)) { 11013 return; 11014 } 11015 11016 rdataset = ISC_LIST_HEAD(client->query.qname->list); 11017 INSIST(rdataset != NULL); 11018 dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); 11019 dns_rdataclass_format(rdataset->rdclass, classbuf, sizeof(classbuf)); 11020 dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf)); 11021 isc_netaddr_format(&client->destaddr, onbuf, sizeof(onbuf)); 11022 11023 if (client->ednsversion >= 0) { 11024 snprintf(ednsbuf, sizeof(ednsbuf), "E(%hd)", 11025 client->ednsversion); 11026 } 11027 11028 if (HAVEECS(client)) { 11029 strlcpy(ecsbuf, " [ECS ", sizeof(ecsbuf)); 11030 dns_ecs_format(&client->ecs, ecsbuf + 6, sizeof(ecsbuf) - 6); 11031 strlcat(ecsbuf, "]", sizeof(ecsbuf)); 11032 } 11033 11034 ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY, level, 11035 "query: %s %s %s %s%s%s%s%s%s%s (%s)%s", namebuf, 11036 classbuf, typebuf, WANTRECURSION(client) ? "+" : "-", 11037 (client->signer != NULL) ? "S" : "", ednsbuf, 11038 TCP(client) ? "T" : "", 11039 ((extflags & DNS_MESSAGEEXTFLAG_DO) != 0) ? "D" : "", 11040 ((flags & DNS_MESSAGEFLAG_CD) != 0) ? "C" : "", 11041 HAVECOOKIE(client) ? "V" : WANTCOOKIE(client) ? "K" : "", 11042 onbuf, ecsbuf); 11043 } 11044 11045 static inline void 11046 log_queryerror(ns_client_t *client, isc_result_t result, int line, int level) { 11047 char namebuf[DNS_NAME_FORMATSIZE]; 11048 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 11049 char classbuf[DNS_RDATACLASS_FORMATSIZE]; 11050 const char *namep, *typep, *classp, *sep1, *sep2; 11051 dns_rdataset_t *rdataset; 11052 11053 if (!isc_log_wouldlog(ns_lctx, level)) { 11054 return; 11055 } 11056 11057 namep = typep = classp = sep1 = sep2 = ""; 11058 11059 /* 11060 * Query errors can happen for various reasons. In some cases we cannot 11061 * even assume the query contains a valid question section, so we should 11062 * expect exceptional cases. 11063 */ 11064 if (client->query.origqname != NULL) { 11065 dns_name_format(client->query.origqname, namebuf, 11066 sizeof(namebuf)); 11067 namep = namebuf; 11068 sep1 = " for "; 11069 11070 rdataset = ISC_LIST_HEAD(client->query.origqname->list); 11071 if (rdataset != NULL) { 11072 dns_rdataclass_format(rdataset->rdclass, classbuf, 11073 sizeof(classbuf)); 11074 classp = classbuf; 11075 dns_rdatatype_format(rdataset->type, typebuf, 11076 sizeof(typebuf)); 11077 typep = typebuf; 11078 sep2 = "/"; 11079 } 11080 } 11081 11082 ns_client_log(client, NS_LOGCATEGORY_QUERY_ERRORS, NS_LOGMODULE_QUERY, 11083 level, "query failed (%s)%s%s%s%s%s%s at %s:%d", 11084 isc_result_totext(result), sep1, namep, sep2, classp, 11085 sep2, typep, __FILE__, line); 11086 } 11087 11088 void 11089 ns_query_start(ns_client_t *client) { 11090 isc_result_t result; 11091 dns_message_t *message; 11092 dns_rdataset_t *rdataset; 11093 dns_rdatatype_t qtype; 11094 unsigned int saved_extflags; 11095 unsigned int saved_flags; 11096 11097 REQUIRE(NS_CLIENT_VALID(client)); 11098 11099 message = client->message; 11100 saved_extflags = client->extflags; 11101 saved_flags = client->message->flags; 11102 11103 CTRACE(ISC_LOG_DEBUG(3), "ns_query_start"); 11104 11105 /* 11106 * Ensure that appropriate cleanups occur. 11107 */ 11108 client->cleanup = query_cleanup; 11109 11110 if ((message->flags & DNS_MESSAGEFLAG_RD) != 0) { 11111 client->query.attributes |= NS_QUERYATTR_WANTRECURSION; 11112 } 11113 11114 if ((client->extflags & DNS_MESSAGEEXTFLAG_DO) != 0) { 11115 client->attributes |= NS_CLIENTATTR_WANTDNSSEC; 11116 } 11117 11118 switch (client->view->minimalresponses) { 11119 case dns_minimal_no: 11120 break; 11121 case dns_minimal_yes: 11122 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | 11123 NS_QUERYATTR_NOADDITIONAL); 11124 break; 11125 case dns_minimal_noauth: 11126 client->query.attributes |= NS_QUERYATTR_NOAUTHORITY; 11127 break; 11128 case dns_minimal_noauthrec: 11129 if ((message->flags & DNS_MESSAGEFLAG_RD) != 0) { 11130 client->query.attributes |= NS_QUERYATTR_NOAUTHORITY; 11131 } 11132 break; 11133 } 11134 11135 if (client->view->cachedb == NULL || !client->view->recursion) { 11136 /* 11137 * We don't have a cache. Turn off cache support and 11138 * recursion. 11139 */ 11140 client->query.attributes &= ~(NS_QUERYATTR_RECURSIONOK | 11141 NS_QUERYATTR_CACHEOK); 11142 client->attributes |= NS_CLIENTATTR_NOSETFC; 11143 } else if ((client->attributes & NS_CLIENTATTR_RA) == 0 || 11144 (message->flags & DNS_MESSAGEFLAG_RD) == 0) 11145 { 11146 /* 11147 * If the client isn't allowed to recurse (due to 11148 * "recursion no", the allow-recursion ACL, or the 11149 * lack of a resolver in this view), or if it 11150 * doesn't want recursion, turn recursion off. 11151 */ 11152 client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK; 11153 client->attributes |= NS_CLIENTATTR_NOSETFC; 11154 } 11155 11156 /* 11157 * Check for multiple question queries, since edns1 is dead. 11158 */ 11159 if (message->counts[DNS_SECTION_QUESTION] > 1) { 11160 query_error(client, DNS_R_FORMERR, __LINE__); 11161 return; 11162 } 11163 11164 /* 11165 * Get the question name. 11166 */ 11167 result = dns_message_firstname(message, DNS_SECTION_QUESTION); 11168 if (result != ISC_R_SUCCESS) { 11169 query_error(client, result, __LINE__); 11170 return; 11171 } 11172 dns_message_currentname(message, DNS_SECTION_QUESTION, 11173 &client->query.qname); 11174 client->query.origqname = client->query.qname; 11175 result = dns_message_nextname(message, DNS_SECTION_QUESTION); 11176 if (result != ISC_R_NOMORE) { 11177 if (result == ISC_R_SUCCESS) { 11178 /* 11179 * There's more than one QNAME in the question 11180 * section. 11181 */ 11182 query_error(client, DNS_R_FORMERR, __LINE__); 11183 } else { 11184 query_error(client, result, __LINE__); 11185 } 11186 return; 11187 } 11188 11189 if ((client->sctx->options & NS_SERVER_LOGQUERIES) != 0) { 11190 log_query(client, saved_flags, saved_extflags); 11191 } 11192 11193 /* 11194 * Check for meta-queries like IXFR and AXFR. 11195 */ 11196 rdataset = ISC_LIST_HEAD(client->query.qname->list); 11197 INSIST(rdataset != NULL); 11198 client->query.qtype = qtype = rdataset->type; 11199 dns_rdatatypestats_increment(client->sctx->rcvquerystats, qtype); 11200 11201 log_tat(client); 11202 11203 if (dns_rdatatype_ismeta(qtype)) { 11204 switch (qtype) { 11205 case dns_rdatatype_any: 11206 break; /* Let the query logic handle it. */ 11207 case dns_rdatatype_ixfr: 11208 case dns_rdatatype_axfr: 11209 ns_xfr_start(client, rdataset->type); 11210 return; 11211 case dns_rdatatype_maila: 11212 case dns_rdatatype_mailb: 11213 query_error(client, DNS_R_NOTIMP, __LINE__); 11214 return; 11215 case dns_rdatatype_tkey: 11216 result = dns_tkey_processquery( 11217 client->message, client->sctx->tkeyctx, 11218 client->view->dynamickeys); 11219 if (result == ISC_R_SUCCESS) { 11220 query_send(client); 11221 } else { 11222 query_error(client, result, __LINE__); 11223 } 11224 return; 11225 default: /* TSIG, etc. */ 11226 query_error(client, DNS_R_FORMERR, __LINE__); 11227 return; 11228 } 11229 } 11230 11231 /* 11232 * Turn on minimal response for (C)DNSKEY and (C)DS queries. 11233 */ 11234 if (qtype == dns_rdatatype_dnskey || qtype == dns_rdatatype_ds || 11235 qtype == dns_rdatatype_cdnskey || qtype == dns_rdatatype_cds) 11236 { 11237 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | 11238 NS_QUERYATTR_NOADDITIONAL); 11239 } 11240 11241 /* 11242 * Maybe turn on minimal responses for ANY queries. 11243 */ 11244 if (qtype == dns_rdatatype_any && client->view->minimal_any && 11245 !TCP(client)) { 11246 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | 11247 NS_QUERYATTR_NOADDITIONAL); 11248 } 11249 11250 /* 11251 * Turn on minimal responses for EDNS/UDP bufsize 512 queries. 11252 */ 11253 if (client->ednsversion >= 0 && client->udpsize <= 512U && !TCP(client)) 11254 { 11255 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | 11256 NS_QUERYATTR_NOADDITIONAL); 11257 } 11258 11259 /* 11260 * If the client has requested that DNSSEC checking be disabled, 11261 * allow lookups to return pending data and instruct the resolver 11262 * to return data before validation has completed. 11263 * 11264 * We don't need to set DNS_DBFIND_PENDINGOK when validation is 11265 * disabled as there will be no pending data. 11266 */ 11267 if ((message->flags & DNS_MESSAGEFLAG_CD) != 0 || 11268 qtype == dns_rdatatype_rrsig) { 11269 client->query.dboptions |= DNS_DBFIND_PENDINGOK; 11270 client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE; 11271 } else if (!client->view->enablevalidation) { 11272 client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE; 11273 } 11274 11275 if (client->view->qminimization) { 11276 client->query.fetchoptions |= DNS_FETCHOPT_QMINIMIZE | 11277 DNS_FETCHOPT_QMIN_SKIP_IP6A; 11278 if (client->view->qmin_strict) { 11279 client->query.fetchoptions |= DNS_FETCHOPT_QMIN_STRICT; 11280 } else { 11281 client->query.fetchoptions |= DNS_FETCHOPT_QMIN_USE_A; 11282 } 11283 } 11284 11285 /* 11286 * Allow glue NS records to be added to the authority section 11287 * if the answer is secure. 11288 */ 11289 if ((message->flags & DNS_MESSAGEFLAG_CD) != 0) { 11290 client->query.attributes &= ~NS_QUERYATTR_SECURE; 11291 } 11292 11293 /* 11294 * Set NS_CLIENTATTR_WANTAD if the client has set AD in the query. 11295 * This allows AD to be returned on queries without DO set. 11296 */ 11297 if ((message->flags & DNS_MESSAGEFLAG_AD) != 0) { 11298 client->attributes |= NS_CLIENTATTR_WANTAD; 11299 } 11300 11301 /* 11302 * This is an ordinary query. 11303 */ 11304 result = dns_message_reply(message, true); 11305 if (result != ISC_R_SUCCESS) { 11306 query_next(client, result); 11307 return; 11308 } 11309 11310 /* 11311 * Assume authoritative response until it is known to be 11312 * otherwise. 11313 * 11314 * If "-T noaa" has been set on the command line don't set 11315 * AA on authoritative answers. 11316 */ 11317 if ((client->sctx->options & NS_SERVER_NOAA) == 0) { 11318 message->flags |= DNS_MESSAGEFLAG_AA; 11319 } 11320 11321 /* 11322 * Set AD. We must clear it if we add non-validated data to a 11323 * response. 11324 */ 11325 if (WANTDNSSEC(client) || WANTAD(client)) { 11326 message->flags |= DNS_MESSAGEFLAG_AD; 11327 } 11328 11329 (void)query_setup(client, qtype); 11330 } 11331