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