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