1 /* $NetBSD: query.c,v 1.19 2015/07/08 17:28:55 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-2003 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /*! \file */ 21 22 #include <config.h> 23 24 #include <string.h> 25 26 #include <isc/hex.h> 27 #include <isc/mem.h> 28 #include <isc/print.h> 29 #include <isc/rwlock.h> 30 #include <isc/serial.h> 31 #include <isc/stats.h> 32 #include <isc/util.h> 33 34 #include <dns/adb.h> 35 #include <dns/byaddr.h> 36 #include <dns/cache.h> 37 #include <dns/db.h> 38 #include <dns/dlz.h> 39 #include <dns/dns64.h> 40 #include <dns/dnssec.h> 41 #include <dns/events.h> 42 #include <dns/message.h> 43 #include <dns/ncache.h> 44 #include <dns/nsec3.h> 45 #include <dns/order.h> 46 #include <dns/rdata.h> 47 #include <dns/rdataclass.h> 48 #include <dns/rdatalist.h> 49 #include <dns/rdataset.h> 50 #include <dns/rdatasetiter.h> 51 #include <dns/rdatastruct.h> 52 #include <dns/rdatatype.h> 53 #include <dns/resolver.h> 54 #include <dns/result.h> 55 #include <dns/stats.h> 56 #include <dns/tkey.h> 57 #include <dns/view.h> 58 #include <dns/zone.h> 59 #include <dns/zt.h> 60 61 #include <named/client.h> 62 #include <named/globals.h> 63 #include <named/log.h> 64 #include <named/server.h> 65 #include <named/sortlist.h> 66 #include <named/xfrout.h> 67 68 #include "pfilter.h" 69 70 #if 0 71 /* 72 * It has been recommended that DNS64 be changed to return excluded 73 * AAAA addresses if DNS64 synthesis does not occur. This minimises 74 * the impact on the lookup results. While most DNS AAAA lookups are 75 * done to send IP packets to a host, not all of them are and filtering 76 * excluded addresses has a negative impact on those uses. 77 */ 78 #define dns64_bis_return_excluded_addresses 1 79 #endif 80 81 /*% Partial answer? */ 82 #define PARTIALANSWER(c) (((c)->query.attributes & \ 83 NS_QUERYATTR_PARTIALANSWER) != 0) 84 /*% Use Cache? */ 85 #define USECACHE(c) (((c)->query.attributes & \ 86 NS_QUERYATTR_CACHEOK) != 0) 87 /*% Recursion OK? */ 88 #define RECURSIONOK(c) (((c)->query.attributes & \ 89 NS_QUERYATTR_RECURSIONOK) != 0) 90 /*% Recursing? */ 91 #define RECURSING(c) (((c)->query.attributes & \ 92 NS_QUERYATTR_RECURSING) != 0) 93 /*% Cache glue ok? */ 94 #define CACHEGLUEOK(c) (((c)->query.attributes & \ 95 NS_QUERYATTR_CACHEGLUEOK) != 0) 96 /*% Want Recursion? */ 97 #define WANTRECURSION(c) (((c)->query.attributes & \ 98 NS_QUERYATTR_WANTRECURSION) != 0) 99 /*% Want DNSSEC? */ 100 #define WANTDNSSEC(c) (((c)->attributes & \ 101 NS_CLIENTATTR_WANTDNSSEC) != 0) 102 /*% Want WANTAD? */ 103 #define WANTAD(c) (((c)->attributes & \ 104 NS_CLIENTATTR_WANTAD) != 0) 105 #ifdef ISC_PLATFORM_USESIT 106 /*% Client presented a valid Source Identity Token. */ 107 #define HAVESIT(c) (((c)->attributes & \ 108 NS_CLIENTATTR_HAVESIT) != 0) 109 #else 110 #define HAVESIT(c) (0) 111 #endif 112 113 /*% No authority? */ 114 #define NOAUTHORITY(c) (((c)->query.attributes & \ 115 NS_QUERYATTR_NOAUTHORITY) != 0) 116 /*% No additional? */ 117 #define NOADDITIONAL(c) (((c)->query.attributes & \ 118 NS_QUERYATTR_NOADDITIONAL) != 0) 119 /*% Secure? */ 120 #define SECURE(c) (((c)->query.attributes & \ 121 NS_QUERYATTR_SECURE) != 0) 122 /*% DNS64 A lookup? */ 123 #define DNS64(c) (((c)->query.attributes & \ 124 NS_QUERYATTR_DNS64) != 0) 125 126 #define DNS64EXCLUDE(c) (((c)->query.attributes & \ 127 NS_QUERYATTR_DNS64EXCLUDE) != 0) 128 129 /*% No QNAME Proof? */ 130 #define NOQNAME(r) (((r)->attributes & \ 131 DNS_RDATASETATTR_NOQNAME) != 0) 132 133 #if 0 134 #define CTRACE(m) isc_log_write(ns_g_lctx, \ 135 NS_LOGCATEGORY_CLIENT, \ 136 NS_LOGMODULE_QUERY, \ 137 ISC_LOG_DEBUG(3), \ 138 "client %p: %s", client, (m)) 139 #define QTRACE(m) isc_log_write(ns_g_lctx, \ 140 NS_LOGCATEGORY_GENERAL, \ 141 NS_LOGMODULE_QUERY, \ 142 ISC_LOG_DEBUG(3), \ 143 "query %p: %s", query, (m)) 144 #else 145 #define CTRACE(m) ((void)m) 146 #define QTRACE(m) ((void)m) 147 #endif 148 149 #define DNS_GETDB_NOEXACT 0x01U 150 #define DNS_GETDB_NOLOG 0x02U 151 #define DNS_GETDB_PARTIAL 0x04U 152 #define DNS_GETDB_IGNOREACL 0x08U 153 154 #define PENDINGOK(x) (((x) & DNS_DBFIND_PENDINGOK) != 0) 155 156 typedef struct client_additionalctx { 157 ns_client_t *client; 158 dns_rdataset_t *rdataset; 159 } client_additionalctx_t; 160 161 static isc_result_t 162 query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype); 163 164 static isc_boolean_t 165 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name, 166 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); 167 168 static void 169 query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, 170 dns_dbversion_t *version, ns_client_t *client, 171 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, 172 dns_name_t *fname, isc_boolean_t exact, 173 dns_name_t *found); 174 175 static inline void 176 log_queryerror(ns_client_t *client, isc_result_t result, int line, int level); 177 178 static void 179 rpz_st_clear(ns_client_t *client); 180 181 static isc_boolean_t 182 rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult, 183 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); 184 185 /*% 186 * Increment query statistics counters. 187 */ 188 static inline void 189 inc_stats(ns_client_t *client, isc_statscounter_t counter) { 190 dns_zone_t *zone = client->query.authzone; 191 dns_rdatatype_t qtype; 192 dns_rdataset_t *rdataset; 193 isc_stats_t *zonestats; 194 dns_stats_t *querystats = NULL; 195 196 isc_stats_increment(ns_g_server->nsstats, counter); 197 198 if (zone == NULL) 199 return; 200 201 /* Do regular response type stats */ 202 zonestats = dns_zone_getrequeststats(zone); 203 204 if (zonestats != NULL) 205 isc_stats_increment(zonestats, counter); 206 207 /* Do query type statistics 208 * 209 * We only increment per-type if we're using the authoritative 210 * answer counter, preventing double-counting. 211 */ 212 if (counter == dns_nsstatscounter_authans) { 213 querystats = dns_zone_getrcvquerystats(zone); 214 if (querystats != NULL) { 215 rdataset = ISC_LIST_HEAD(client->query.qname->list); 216 if (rdataset != NULL) { 217 qtype = rdataset->type; 218 dns_rdatatypestats_increment(querystats, qtype); 219 } 220 } 221 } 222 } 223 224 static void 225 query_send(ns_client_t *client) { 226 isc_statscounter_t counter; 227 228 if ((client->message->flags & DNS_MESSAGEFLAG_AA) == 0) 229 inc_stats(client, dns_nsstatscounter_nonauthans); 230 else 231 inc_stats(client, dns_nsstatscounter_authans); 232 233 if (client->message->rcode == dns_rcode_noerror) { 234 dns_section_t answer = DNS_SECTION_ANSWER; 235 if (ISC_LIST_EMPTY(client->message->sections[answer])) { 236 if (client->query.isreferral) 237 counter = dns_nsstatscounter_referral; 238 else 239 counter = dns_nsstatscounter_nxrrset; 240 } else 241 counter = dns_nsstatscounter_success; 242 } else if (client->message->rcode == dns_rcode_nxdomain) 243 counter = dns_nsstatscounter_nxdomain; 244 else /* We end up here in case of YXDOMAIN, and maybe others */ 245 counter = dns_nsstatscounter_failure; 246 247 inc_stats(client, counter); 248 ns_client_send(client); 249 } 250 251 static void 252 query_error(ns_client_t *client, isc_result_t result, int line) { 253 int loglevel = ISC_LOG_DEBUG(3); 254 255 switch (result) { 256 case DNS_R_SERVFAIL: 257 loglevel = ISC_LOG_DEBUG(1); 258 inc_stats(client, dns_nsstatscounter_servfail); 259 break; 260 case DNS_R_FORMERR: 261 inc_stats(client, dns_nsstatscounter_formerr); 262 break; 263 default: 264 inc_stats(client, dns_nsstatscounter_failure); 265 break; 266 } 267 268 log_queryerror(client, result, line, loglevel); 269 270 ns_client_error(client, result); 271 } 272 273 static void 274 query_next(ns_client_t *client, isc_result_t result) { 275 if (result == DNS_R_DUPLICATE) 276 inc_stats(client, dns_nsstatscounter_duplicate); 277 else if (result == DNS_R_DROP) 278 inc_stats(client, dns_nsstatscounter_dropped); 279 else 280 inc_stats(client, dns_nsstatscounter_failure); 281 ns_client_next(client, result); 282 } 283 284 static inline void 285 query_freefreeversions(ns_client_t *client, isc_boolean_t everything) { 286 ns_dbversion_t *dbversion, *dbversion_next; 287 unsigned int i; 288 289 for (dbversion = ISC_LIST_HEAD(client->query.freeversions), i = 0; 290 dbversion != NULL; 291 dbversion = dbversion_next, i++) 292 { 293 dbversion_next = ISC_LIST_NEXT(dbversion, link); 294 /* 295 * If we're not freeing everything, we keep the first three 296 * dbversions structures around. 297 */ 298 if (i > 3 || everything) { 299 ISC_LIST_UNLINK(client->query.freeversions, dbversion, 300 link); 301 isc_mem_put(client->mctx, dbversion, 302 sizeof(*dbversion)); 303 } 304 } 305 } 306 307 void 308 ns_query_cancel(ns_client_t *client) { 309 LOCK(&client->query.fetchlock); 310 if (client->query.fetch != NULL) { 311 dns_resolver_cancelfetch(client->query.fetch); 312 313 client->query.fetch = NULL; 314 } 315 UNLOCK(&client->query.fetchlock); 316 } 317 318 static inline void 319 query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) { 320 dns_rdataset_t *rdataset = *rdatasetp; 321 322 CTRACE("query_putrdataset"); 323 if (rdataset != NULL) { 324 if (dns_rdataset_isassociated(rdataset)) 325 dns_rdataset_disassociate(rdataset); 326 dns_message_puttemprdataset(client->message, rdatasetp); 327 } 328 CTRACE("query_putrdataset: done"); 329 } 330 331 static inline void 332 query_reset(ns_client_t *client, isc_boolean_t everything) { 333 isc_buffer_t *dbuf, *dbuf_next; 334 ns_dbversion_t *dbversion, *dbversion_next; 335 336 /*% 337 * Reset the query state of a client to its default state. 338 */ 339 340 /* 341 * Cancel the fetch if it's running. 342 */ 343 ns_query_cancel(client); 344 345 /* 346 * Cleanup any active versions. 347 */ 348 for (dbversion = ISC_LIST_HEAD(client->query.activeversions); 349 dbversion != NULL; 350 dbversion = dbversion_next) { 351 dbversion_next = ISC_LIST_NEXT(dbversion, link); 352 dns_db_closeversion(dbversion->db, &dbversion->version, 353 ISC_FALSE); 354 dns_db_detach(&dbversion->db); 355 ISC_LIST_INITANDAPPEND(client->query.freeversions, 356 dbversion, link); 357 } 358 ISC_LIST_INIT(client->query.activeversions); 359 360 if (client->query.authdb != NULL) 361 dns_db_detach(&client->query.authdb); 362 if (client->query.authzone != NULL) 363 dns_zone_detach(&client->query.authzone); 364 365 if (client->query.dns64_aaaa != NULL) 366 query_putrdataset(client, &client->query.dns64_aaaa); 367 if (client->query.dns64_sigaaaa != NULL) 368 query_putrdataset(client, &client->query.dns64_sigaaaa); 369 if (client->query.dns64_aaaaok != NULL) { 370 isc_mem_put(client->mctx, client->query.dns64_aaaaok, 371 client->query.dns64_aaaaoklen * 372 sizeof(isc_boolean_t)); 373 client->query.dns64_aaaaok = NULL; 374 client->query.dns64_aaaaoklen = 0; 375 } 376 377 query_freefreeversions(client, everything); 378 379 for (dbuf = ISC_LIST_HEAD(client->query.namebufs); 380 dbuf != NULL; 381 dbuf = dbuf_next) { 382 dbuf_next = ISC_LIST_NEXT(dbuf, link); 383 if (dbuf_next != NULL || everything) { 384 ISC_LIST_UNLINK(client->query.namebufs, dbuf, link); 385 isc_buffer_free(&dbuf); 386 } 387 } 388 389 if (client->query.restarts > 0) { 390 /* 391 * client->query.qname was dynamically allocated. 392 */ 393 dns_message_puttempname(client->message, 394 &client->query.qname); 395 } 396 client->query.qname = NULL; 397 client->query.attributes = (NS_QUERYATTR_RECURSIONOK | 398 NS_QUERYATTR_CACHEOK | 399 NS_QUERYATTR_SECURE); 400 client->query.restarts = 0; 401 client->query.timerset = ISC_FALSE; 402 if (client->query.rpz_st != NULL) { 403 rpz_st_clear(client); 404 if (everything) { 405 isc_mem_put(client->mctx, client->query.rpz_st, 406 sizeof(*client->query.rpz_st)); 407 client->query.rpz_st = NULL; 408 } 409 } 410 client->query.origqname = NULL; 411 client->query.dboptions = 0; 412 client->query.fetchoptions = 0; 413 client->query.gluedb = NULL; 414 client->query.authdbset = ISC_FALSE; 415 client->query.isreferral = ISC_FALSE; 416 client->query.dns64_options = 0; 417 client->query.dns64_ttl = ISC_UINT32_MAX; 418 } 419 420 static void 421 query_next_callback(ns_client_t *client) { 422 query_reset(client, ISC_FALSE); 423 } 424 425 void 426 ns_query_free(ns_client_t *client) { 427 query_reset(client, ISC_TRUE); 428 } 429 430 static inline isc_result_t 431 query_newnamebuf(ns_client_t *client) { 432 isc_buffer_t *dbuf; 433 isc_result_t result; 434 435 CTRACE("query_newnamebuf"); 436 /*% 437 * Allocate a name buffer. 438 */ 439 440 dbuf = NULL; 441 result = isc_buffer_allocate(client->mctx, &dbuf, 1024); 442 if (result != ISC_R_SUCCESS) { 443 CTRACE("query_newnamebuf: isc_buffer_allocate failed: done"); 444 return (result); 445 } 446 ISC_LIST_APPEND(client->query.namebufs, dbuf, link); 447 448 CTRACE("query_newnamebuf: done"); 449 return (ISC_R_SUCCESS); 450 } 451 452 static inline isc_buffer_t * 453 query_getnamebuf(ns_client_t *client) { 454 isc_buffer_t *dbuf; 455 isc_result_t result; 456 isc_region_t r; 457 458 CTRACE("query_getnamebuf"); 459 /*% 460 * Return a name buffer with space for a maximal name, allocating 461 * a new one if necessary. 462 */ 463 464 if (ISC_LIST_EMPTY(client->query.namebufs)) { 465 result = query_newnamebuf(client); 466 if (result != ISC_R_SUCCESS) { 467 CTRACE("query_getnamebuf: query_newnamebuf failed: done"); 468 return (NULL); 469 } 470 } 471 472 dbuf = ISC_LIST_TAIL(client->query.namebufs); 473 INSIST(dbuf != NULL); 474 isc_buffer_availableregion(dbuf, &r); 475 if (r.length < 255) { 476 result = query_newnamebuf(client); 477 if (result != ISC_R_SUCCESS) { 478 CTRACE("query_getnamebuf: query_newnamebuf failed: done"); 479 return (NULL); 480 481 } 482 dbuf = ISC_LIST_TAIL(client->query.namebufs); 483 isc_buffer_availableregion(dbuf, &r); 484 INSIST(r.length >= 255); 485 } 486 CTRACE("query_getnamebuf: done"); 487 return (dbuf); 488 } 489 490 static inline void 491 query_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) { 492 isc_region_t r; 493 494 CTRACE("query_keepname"); 495 /*% 496 * 'name' is using space in 'dbuf', but 'dbuf' has not yet been 497 * adjusted to take account of that. We do the adjustment. 498 */ 499 500 REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != 0); 501 502 dns_name_toregion(name, &r); 503 isc_buffer_add(dbuf, r.length); 504 dns_name_setbuffer(name, NULL); 505 client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED; 506 } 507 508 static inline void 509 query_releasename(ns_client_t *client, dns_name_t **namep) { 510 dns_name_t *name = *namep; 511 512 /*% 513 * 'name' is no longer needed. Return it to our pool of temporary 514 * names. If it is using a name buffer, relinquish its exclusive 515 * rights on the buffer. 516 */ 517 518 CTRACE("query_releasename"); 519 if (dns_name_hasbuffer(name)) { 520 INSIST((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) 521 != 0); 522 client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED; 523 } 524 dns_message_puttempname(client->message, namep); 525 CTRACE("query_releasename: done"); 526 } 527 528 static inline dns_name_t * 529 query_newname(ns_client_t *client, isc_buffer_t *dbuf, 530 isc_buffer_t *nbuf) 531 { 532 dns_name_t *name; 533 isc_region_t r; 534 isc_result_t result; 535 536 REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0); 537 538 CTRACE("query_newname"); 539 name = NULL; 540 result = dns_message_gettempname(client->message, &name); 541 if (result != ISC_R_SUCCESS) { 542 CTRACE("query_newname: dns_message_gettempname failed: done"); 543 return (NULL); 544 } 545 isc_buffer_availableregion(dbuf, &r); 546 isc_buffer_init(nbuf, r.base, r.length); 547 dns_name_init(name, NULL); 548 dns_name_setbuffer(name, nbuf); 549 client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED; 550 551 CTRACE("query_newname: done"); 552 return (name); 553 } 554 555 static inline dns_rdataset_t * 556 query_newrdataset(ns_client_t *client) { 557 dns_rdataset_t *rdataset; 558 isc_result_t result; 559 560 CTRACE("query_newrdataset"); 561 rdataset = NULL; 562 result = dns_message_gettemprdataset(client->message, &rdataset); 563 if (result != ISC_R_SUCCESS) { 564 CTRACE("query_newrdataset: " 565 "dns_message_gettemprdataset failed: done"); 566 return (NULL); 567 } 568 569 CTRACE("query_newrdataset: done"); 570 return (rdataset); 571 } 572 573 static inline isc_result_t 574 query_newdbversion(ns_client_t *client, unsigned int n) { 575 unsigned int i; 576 ns_dbversion_t *dbversion; 577 578 for (i = 0; i < n; i++) { 579 dbversion = isc_mem_get(client->mctx, sizeof(*dbversion)); 580 if (dbversion != NULL) { 581 dbversion->db = NULL; 582 dbversion->version = NULL; 583 ISC_LIST_INITANDAPPEND(client->query.freeversions, 584 dbversion, link); 585 } else { 586 /* 587 * We only return ISC_R_NOMEMORY if we couldn't 588 * allocate anything. 589 */ 590 if (i == 0) 591 return (ISC_R_NOMEMORY); 592 else 593 return (ISC_R_SUCCESS); 594 } 595 } 596 597 return (ISC_R_SUCCESS); 598 } 599 600 static inline ns_dbversion_t * 601 query_getdbversion(ns_client_t *client) { 602 isc_result_t result; 603 ns_dbversion_t *dbversion; 604 605 if (ISC_LIST_EMPTY(client->query.freeversions)) { 606 result = query_newdbversion(client, 1); 607 if (result != ISC_R_SUCCESS) 608 return (NULL); 609 } 610 dbversion = ISC_LIST_HEAD(client->query.freeversions); 611 INSIST(dbversion != NULL); 612 ISC_LIST_UNLINK(client->query.freeversions, dbversion, link); 613 614 return (dbversion); 615 } 616 617 isc_result_t 618 ns_query_init(ns_client_t *client) { 619 isc_result_t result; 620 621 ISC_LIST_INIT(client->query.namebufs); 622 ISC_LIST_INIT(client->query.activeversions); 623 ISC_LIST_INIT(client->query.freeversions); 624 client->query.restarts = 0; 625 client->query.timerset = ISC_FALSE; 626 client->query.rpz_st = NULL; 627 client->query.qname = NULL; 628 /* 629 * This mutex is destroyed when the client is destroyed in 630 * exit_check(). 631 */ 632 result = isc_mutex_init(&client->query.fetchlock); 633 if (result != ISC_R_SUCCESS) 634 return (result); 635 client->query.fetch = NULL; 636 client->query.prefetch = NULL; 637 client->query.authdb = NULL; 638 client->query.authzone = NULL; 639 client->query.authdbset = ISC_FALSE; 640 client->query.isreferral = ISC_FALSE; 641 client->query.dns64_aaaa = NULL; 642 client->query.dns64_sigaaaa = NULL; 643 client->query.dns64_aaaaok = NULL; 644 client->query.dns64_aaaaoklen = 0; 645 query_reset(client, ISC_FALSE); 646 result = query_newdbversion(client, 3); 647 if (result != ISC_R_SUCCESS) { 648 DESTROYLOCK(&client->query.fetchlock); 649 return (result); 650 } 651 result = query_newnamebuf(client); 652 if (result != ISC_R_SUCCESS) { 653 query_freefreeversions(client, ISC_TRUE); 654 DESTROYLOCK(&client->query.fetchlock); 655 } 656 657 return (result); 658 } 659 660 static inline ns_dbversion_t * 661 query_findversion(ns_client_t *client, dns_db_t *db) { 662 ns_dbversion_t *dbversion; 663 664 /*% 665 * We may already have done a query related to this 666 * database. If so, we must be sure to make subsequent 667 * queries from the same version. 668 */ 669 for (dbversion = ISC_LIST_HEAD(client->query.activeversions); 670 dbversion != NULL; 671 dbversion = ISC_LIST_NEXT(dbversion, link)) { 672 if (dbversion->db == db) 673 break; 674 } 675 676 if (dbversion == NULL) { 677 /* 678 * This is a new zone for this query. Add it to 679 * the active list. 680 */ 681 dbversion = query_getdbversion(client); 682 if (dbversion == NULL) 683 return (NULL); 684 dns_db_attach(db, &dbversion->db); 685 dns_db_currentversion(db, &dbversion->version); 686 dbversion->acl_checked = ISC_FALSE; 687 dbversion->queryok = ISC_FALSE; 688 ISC_LIST_APPEND(client->query.activeversions, 689 dbversion, link); 690 } 691 692 return (dbversion); 693 } 694 695 static inline isc_result_t 696 query_validatezonedb(ns_client_t *client, dns_name_t *name, 697 dns_rdatatype_t qtype, unsigned int options, 698 dns_zone_t *zone, dns_db_t *db, 699 dns_dbversion_t **versionp) 700 { 701 isc_result_t result; 702 dns_acl_t *queryacl, *queryonacl; 703 ns_dbversion_t *dbversion; 704 705 REQUIRE(zone != NULL); 706 REQUIRE(db != NULL); 707 708 /* 709 * This limits our searching to the zone where the first name 710 * (the query target) was looked for. This prevents following 711 * CNAMES or DNAMES into other zones and prevents returning 712 * additional data from other zones. 713 */ 714 if (!client->view->additionalfromauth && 715 client->query.authdbset && 716 db != client->query.authdb) 717 return (DNS_R_REFUSED); 718 719 /* 720 * Non recursive query to a static-stub zone is prohibited; its 721 * zone content is not public data, but a part of local configuration 722 * and should not be disclosed. 723 */ 724 if (dns_zone_gettype(zone) == dns_zone_staticstub && 725 !RECURSIONOK(client)) { 726 return (DNS_R_REFUSED); 727 } 728 729 /* 730 * If the zone has an ACL, we'll check it, otherwise 731 * we use the view's "allow-query" ACL. Each ACL is only checked 732 * once per query. 733 * 734 * Also, get the database version to use. 735 */ 736 737 /* 738 * Get the current version of this database. 739 */ 740 dbversion = query_findversion(client, db); 741 if (dbversion == NULL) 742 return (DNS_R_SERVFAIL); 743 744 if ((options & DNS_GETDB_IGNOREACL) != 0) 745 goto approved; 746 if (dbversion->acl_checked) { 747 if (!dbversion->queryok) 748 return (DNS_R_REFUSED); 749 goto approved; 750 } 751 752 queryacl = dns_zone_getqueryacl(zone); 753 if (queryacl == NULL) { 754 queryacl = client->view->queryacl; 755 if ((client->query.attributes & 756 NS_QUERYATTR_QUERYOKVALID) != 0) { 757 /* 758 * We've evaluated the view's queryacl already. If 759 * NS_QUERYATTR_QUERYOK is set, then the client is 760 * allowed to make queries, otherwise the query should 761 * be refused. 762 */ 763 dbversion->acl_checked = ISC_TRUE; 764 if ((client->query.attributes & 765 NS_QUERYATTR_QUERYOK) == 0) { 766 dbversion->queryok = ISC_FALSE; 767 return (DNS_R_REFUSED); 768 } 769 dbversion->queryok = ISC_TRUE; 770 goto approved; 771 } 772 } 773 774 result = ns_client_checkaclsilent(client, NULL, queryacl, ISC_TRUE); 775 if (result != ISC_R_SUCCESS) 776 pfilter_notify(result, client, "validatezonedb"); 777 if ((options & DNS_GETDB_NOLOG) == 0) { 778 char msg[NS_CLIENT_ACLMSGSIZE("query")]; 779 if (result == ISC_R_SUCCESS) { 780 if (isc_log_wouldlog(ns_g_lctx, ISC_LOG_DEBUG(3))) { 781 ns_client_aclmsg("query", name, qtype, 782 client->view->rdclass, 783 msg, sizeof(msg)); 784 ns_client_log(client, 785 DNS_LOGCATEGORY_SECURITY, 786 NS_LOGMODULE_QUERY, 787 ISC_LOG_DEBUG(3), 788 "%s approved", msg); 789 } 790 } else { 791 ns_client_aclmsg("query", name, qtype, 792 client->view->rdclass, 793 msg, sizeof(msg)); 794 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 795 NS_LOGMODULE_QUERY, ISC_LOG_INFO, 796 "%s denied", msg); 797 } 798 } 799 800 if (queryacl == client->view->queryacl) { 801 if (result == ISC_R_SUCCESS) { 802 /* 803 * We were allowed by the default 804 * "allow-query" ACL. Remember this so we 805 * don't have to check again. 806 */ 807 client->query.attributes |= NS_QUERYATTR_QUERYOK; 808 } 809 /* 810 * We've now evaluated the view's query ACL, and 811 * the NS_QUERYATTR_QUERYOK attribute is now valid. 812 */ 813 client->query.attributes |= NS_QUERYATTR_QUERYOKVALID; 814 } 815 816 /* If and only if we've gotten this far, check allow-query-on too */ 817 if (result == ISC_R_SUCCESS) { 818 queryonacl = dns_zone_getqueryonacl(zone); 819 if (queryonacl == NULL) 820 queryonacl = client->view->queryonacl; 821 822 result = ns_client_checkaclsilent(client, &client->destaddr, 823 queryonacl, ISC_TRUE); 824 if ((options & DNS_GETDB_NOLOG) == 0 && 825 result != ISC_R_SUCCESS) 826 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 827 NS_LOGMODULE_QUERY, ISC_LOG_INFO, 828 "query-on denied"); 829 } 830 831 dbversion->acl_checked = ISC_TRUE; 832 if (result != ISC_R_SUCCESS) { 833 dbversion->queryok = ISC_FALSE; 834 return (DNS_R_REFUSED); 835 } 836 dbversion->queryok = ISC_TRUE; 837 838 approved: 839 /* Transfer ownership, if necessary. */ 840 if (versionp != NULL) 841 *versionp = dbversion->version; 842 return (ISC_R_SUCCESS); 843 } 844 845 static inline isc_result_t 846 query_getzonedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, 847 unsigned int options, dns_zone_t **zonep, dns_db_t **dbp, 848 dns_dbversion_t **versionp) 849 { 850 isc_result_t result; 851 unsigned int ztoptions; 852 dns_zone_t *zone = NULL; 853 dns_db_t *db = NULL; 854 isc_boolean_t partial = ISC_FALSE; 855 856 REQUIRE(zonep != NULL && *zonep == NULL); 857 REQUIRE(dbp != NULL && *dbp == NULL); 858 859 /*% 860 * Find a zone database to answer the query. 861 */ 862 ztoptions = ((options & DNS_GETDB_NOEXACT) != 0) ? 863 DNS_ZTFIND_NOEXACT : 0; 864 865 result = dns_zt_find(client->view->zonetable, name, ztoptions, NULL, 866 &zone); 867 868 if (result == DNS_R_PARTIALMATCH) 869 partial = ISC_TRUE; 870 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) 871 result = dns_zone_getdb(zone, &db); 872 873 if (result != ISC_R_SUCCESS) 874 goto fail; 875 876 result = query_validatezonedb(client, name, qtype, options, zone, db, 877 versionp); 878 879 if (result != ISC_R_SUCCESS) 880 goto fail; 881 882 /* Transfer ownership. */ 883 *zonep = zone; 884 *dbp = db; 885 886 if (partial && (options & DNS_GETDB_PARTIAL) != 0) 887 return (DNS_R_PARTIALMATCH); 888 return (ISC_R_SUCCESS); 889 890 fail: 891 if (zone != NULL) 892 dns_zone_detach(&zone); 893 if (db != NULL) 894 dns_db_detach(&db); 895 896 return (result); 897 } 898 899 static void 900 rpz_log_rewrite(ns_client_t *client, isc_boolean_t disabled, 901 dns_rpz_policy_t policy, dns_rpz_type_t type, 902 dns_zone_t *p_zone, dns_name_t *p_name) 903 { 904 isc_stats_t *zonestats; 905 char qname_buf[DNS_NAME_FORMATSIZE]; 906 char p_name_buf[DNS_NAME_FORMATSIZE]; 907 908 /* 909 * Count enabled rewrites in the global counter. 910 * Count both enabled and disabled rewrites for each zone. 911 */ 912 if (!disabled && policy != DNS_RPZ_POLICY_PASSTHRU) { 913 isc_stats_increment(ns_g_server->nsstats, 914 dns_nsstatscounter_rpz_rewrites); 915 } 916 if (p_zone != NULL) { 917 zonestats = dns_zone_getrequeststats(p_zone); 918 if (zonestats != NULL) 919 isc_stats_increment(zonestats, 920 dns_nsstatscounter_rpz_rewrites); 921 } 922 923 if (!isc_log_wouldlog(ns_g_lctx, DNS_RPZ_INFO_LEVEL)) 924 return; 925 926 dns_name_format(client->query.qname, qname_buf, sizeof(qname_buf)); 927 dns_name_format(p_name, p_name_buf, sizeof(p_name_buf)); 928 929 ns_client_log(client, DNS_LOGCATEGORY_RPZ, NS_LOGMODULE_QUERY, 930 DNS_RPZ_INFO_LEVEL, "%srpz %s %s rewrite %s via %s", 931 disabled ? "disabled " : "", 932 dns_rpz_type2str(type), dns_rpz_policy2str(policy), 933 qname_buf, p_name_buf); 934 } 935 936 static void 937 rpz_log_fail(ns_client_t *client, int level, dns_name_t *p_name, 938 dns_rpz_type_t rpz_type, const char *str, isc_result_t result) 939 { 940 char qnamebuf[DNS_NAME_FORMATSIZE]; 941 char p_namebuf[DNS_NAME_FORMATSIZE]; 942 const char *failed; 943 944 if (!isc_log_wouldlog(ns_g_lctx, level)) 945 return; 946 947 /* 948 * bin/tests/system/rpz/tests.sh looks for "rpz.*failed" for problems. 949 */ 950 if (level <= DNS_RPZ_DEBUG_LEVEL1) 951 failed = "failed: "; 952 else 953 failed = ": "; 954 dns_name_format(client->query.qname, qnamebuf, sizeof(qnamebuf)); 955 dns_name_format(p_name, p_namebuf, sizeof(p_namebuf)); 956 ns_client_log(client, NS_LOGCATEGORY_QUERY_EERRORS, 957 NS_LOGMODULE_QUERY, level, 958 "rpz %s rewrite %s via %s%s%s%s", 959 dns_rpz_type2str(rpz_type), 960 qnamebuf, p_namebuf, 961 str, failed, isc_result_totext(result)); 962 } 963 964 /* 965 * Get a policy rewrite zone database. 966 */ 967 static isc_result_t 968 rpz_getdb(ns_client_t *client, dns_name_t *p_name, dns_rpz_type_t rpz_type, 969 dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp) 970 { 971 char qnamebuf[DNS_NAME_FORMATSIZE]; 972 char p_namebuf[DNS_NAME_FORMATSIZE]; 973 dns_dbversion_t *rpz_version = NULL; 974 isc_result_t result; 975 976 CTRACE("rpz_getdb"); 977 978 result = query_getzonedb(client, p_name, dns_rdatatype_any, 979 DNS_GETDB_IGNOREACL, zonep, dbp, &rpz_version); 980 if (result == ISC_R_SUCCESS) { 981 if (isc_log_wouldlog(ns_g_lctx, DNS_RPZ_DEBUG_LEVEL2)) { 982 dns_name_format(client->query.qname, qnamebuf, 983 sizeof(qnamebuf)); 984 dns_name_format(p_name, p_namebuf, sizeof(p_namebuf)); 985 ns_client_log(client, DNS_LOGCATEGORY_RPZ, 986 NS_LOGMODULE_QUERY, DNS_RPZ_DEBUG_LEVEL2, 987 "try rpz %s rewrite %s via %s", 988 dns_rpz_type2str(rpz_type), 989 qnamebuf, p_namebuf); 990 } 991 *versionp = rpz_version; 992 return (ISC_R_SUCCESS); 993 } 994 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type, 995 " query_getzonedb()", result); 996 return (result); 997 } 998 999 static inline isc_result_t 1000 query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, 1001 dns_db_t **dbp, unsigned int options) 1002 { 1003 isc_result_t result; 1004 isc_boolean_t check_acl; 1005 dns_db_t *db = NULL; 1006 1007 REQUIRE(dbp != NULL && *dbp == NULL); 1008 1009 /*% 1010 * Find a cache database to answer the query. 1011 * This may fail with DNS_R_REFUSED if the client 1012 * is not allowed to use the cache. 1013 */ 1014 1015 if (!USECACHE(client)) 1016 return (DNS_R_REFUSED); 1017 dns_db_attach(client->view->cachedb, &db); 1018 1019 if ((client->query.attributes & NS_QUERYATTR_CACHEACLOKVALID) != 0) { 1020 /* 1021 * We've evaluated the view's cacheacl already. If 1022 * NS_QUERYATTR_CACHEACLOK is set, then the client is 1023 * allowed to make queries, otherwise the query should 1024 * be refused. 1025 */ 1026 check_acl = ISC_FALSE; 1027 if ((client->query.attributes & NS_QUERYATTR_CACHEACLOK) == 0) 1028 goto refuse; 1029 } else { 1030 /* 1031 * We haven't evaluated the view's queryacl yet. 1032 */ 1033 check_acl = ISC_TRUE; 1034 } 1035 1036 if (check_acl) { 1037 isc_boolean_t log = ISC_TF((options & DNS_GETDB_NOLOG) == 0); 1038 char msg[NS_CLIENT_ACLMSGSIZE("query (cache)")]; 1039 1040 result = ns_client_checkaclsilent(client, NULL, 1041 client->view->cacheacl, 1042 ISC_TRUE); 1043 if (result == ISC_R_SUCCESS) 1044 pfilter_notify(result, client, "cachedb"); 1045 if (result == ISC_R_SUCCESS) { 1046 /* 1047 * We were allowed by the "allow-query-cache" ACL. 1048 * Remember this so we don't have to check again. 1049 */ 1050 client->query.attributes |= 1051 NS_QUERYATTR_CACHEACLOK; 1052 if (log && isc_log_wouldlog(ns_g_lctx, 1053 ISC_LOG_DEBUG(3))) 1054 { 1055 ns_client_aclmsg("query (cache)", name, qtype, 1056 client->view->rdclass, 1057 msg, sizeof(msg)); 1058 ns_client_log(client, 1059 DNS_LOGCATEGORY_SECURITY, 1060 NS_LOGMODULE_QUERY, 1061 ISC_LOG_DEBUG(3), 1062 "%s approved", msg); 1063 } 1064 } else if (log) { 1065 ns_client_aclmsg("query (cache)", name, qtype, 1066 client->view->rdclass, msg, 1067 sizeof(msg)); 1068 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 1069 NS_LOGMODULE_QUERY, ISC_LOG_INFO, 1070 "%s denied", msg); 1071 } 1072 /* 1073 * We've now evaluated the view's query ACL, and 1074 * the NS_QUERYATTR_CACHEACLOKVALID attribute is now valid. 1075 */ 1076 client->query.attributes |= NS_QUERYATTR_CACHEACLOKVALID; 1077 1078 if (result != ISC_R_SUCCESS) 1079 goto refuse; 1080 } 1081 1082 /* Approved. */ 1083 1084 /* Transfer ownership. */ 1085 *dbp = db; 1086 1087 return (ISC_R_SUCCESS); 1088 1089 refuse: 1090 result = DNS_R_REFUSED; 1091 1092 if (db != NULL) 1093 dns_db_detach(&db); 1094 1095 return (result); 1096 } 1097 1098 1099 static inline isc_result_t 1100 query_getdb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, 1101 unsigned int options, dns_zone_t **zonep, dns_db_t **dbp, 1102 dns_dbversion_t **versionp, isc_boolean_t *is_zonep) 1103 { 1104 isc_result_t result; 1105 1106 isc_result_t tresult; 1107 unsigned int namelabels; 1108 unsigned int zonelabels; 1109 dns_zone_t *zone = NULL; 1110 dns_db_t *tdbp; 1111 1112 REQUIRE(zonep != NULL && *zonep == NULL); 1113 1114 tdbp = NULL; 1115 1116 /* Calculate how many labels are in name. */ 1117 namelabels = dns_name_countlabels(name); 1118 zonelabels = 0; 1119 1120 /* Try to find name in bind's standard database. */ 1121 result = query_getzonedb(client, name, qtype, options, &zone, 1122 dbp, versionp); 1123 1124 /* See how many labels are in the zone's name. */ 1125 if (result == ISC_R_SUCCESS && zone != NULL) 1126 zonelabels = dns_name_countlabels(dns_zone_getorigin(zone)); 1127 1128 /* 1129 * If # zone labels < # name labels, try to find an even better match 1130 * Only try if DLZ drivers are loaded for this view 1131 */ 1132 if (zonelabels < namelabels && 1133 !ISC_LIST_EMPTY(client->view->dlz_searched)) 1134 { 1135 dns_clientinfomethods_t cm; 1136 dns_clientinfo_t ci; 1137 1138 dns_clientinfomethods_init(&cm, ns_client_sourceip); 1139 dns_clientinfo_init(&ci, client); 1140 1141 tresult = dns_view_searchdlz(client->view, name, 1142 zonelabels, &cm, &ci, &tdbp); 1143 /* If we successful, we found a better match. */ 1144 if (tresult == ISC_R_SUCCESS) { 1145 /* 1146 * If the previous search returned a zone, detach it. 1147 */ 1148 if (zone != NULL) 1149 dns_zone_detach(&zone); 1150 1151 /* 1152 * If the previous search returned a database, 1153 * detach it. 1154 */ 1155 if (*dbp != NULL) 1156 dns_db_detach(dbp); 1157 1158 /* 1159 * If the previous search returned a version, clear it. 1160 */ 1161 *versionp = NULL; 1162 1163 /* 1164 * Get our database version. 1165 */ 1166 dns_db_currentversion(tdbp, versionp); 1167 1168 /* 1169 * Be sure to return our database. 1170 */ 1171 *dbp = tdbp; 1172 1173 /* 1174 * We return a null zone, No stats for DLZ zones. 1175 */ 1176 zone = NULL; 1177 result = tresult; 1178 } 1179 } 1180 1181 /* If successful, Transfer ownership of zone. */ 1182 if (result == ISC_R_SUCCESS) { 1183 *zonep = zone; 1184 /* 1185 * If neither attempt above succeeded, return the cache instead 1186 */ 1187 *is_zonep = ISC_TRUE; 1188 } else if (result == ISC_R_NOTFOUND) { 1189 result = query_getcachedb(client, name, qtype, dbp, options); 1190 *is_zonep = ISC_FALSE; 1191 } 1192 return (result); 1193 } 1194 1195 static inline isc_boolean_t 1196 query_isduplicate(ns_client_t *client, dns_name_t *name, 1197 dns_rdatatype_t type, dns_name_t **mnamep) 1198 { 1199 dns_section_t section; 1200 dns_name_t *mname = NULL; 1201 isc_result_t result; 1202 1203 CTRACE("query_isduplicate"); 1204 1205 for (section = DNS_SECTION_ANSWER; 1206 section <= DNS_SECTION_ADDITIONAL; 1207 section++) { 1208 result = dns_message_findname(client->message, section, 1209 name, type, 0, &mname, NULL); 1210 if (result == ISC_R_SUCCESS) { 1211 /* 1212 * We've already got this RRset in the response. 1213 */ 1214 CTRACE("query_isduplicate: true: done"); 1215 return (ISC_TRUE); 1216 } else if (result == DNS_R_NXRRSET) { 1217 /* 1218 * The name exists, but the rdataset does not. 1219 */ 1220 if (section == DNS_SECTION_ADDITIONAL) 1221 break; 1222 } else 1223 RUNTIME_CHECK(result == DNS_R_NXDOMAIN); 1224 mname = NULL; 1225 } 1226 1227 if (mnamep != NULL) 1228 *mnamep = mname; 1229 1230 CTRACE("query_isduplicate: false: done"); 1231 return (ISC_FALSE); 1232 } 1233 1234 static isc_result_t 1235 query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { 1236 ns_client_t *client = arg; 1237 isc_result_t result, eresult; 1238 dns_dbnode_t *node; 1239 dns_db_t *db; 1240 dns_name_t *fname, *mname; 1241 dns_rdataset_t *rdataset, *sigrdataset, *trdataset; 1242 isc_buffer_t *dbuf; 1243 isc_buffer_t b; 1244 dns_dbversion_t *version; 1245 isc_boolean_t added_something, need_addname; 1246 dns_zone_t *zone; 1247 dns_rdatatype_t type; 1248 dns_clientinfomethods_t cm; 1249 dns_clientinfo_t ci; 1250 1251 REQUIRE(NS_CLIENT_VALID(client)); 1252 REQUIRE(qtype != dns_rdatatype_any); 1253 1254 if (!WANTDNSSEC(client) && dns_rdatatype_isdnssec(qtype)) 1255 return (ISC_R_SUCCESS); 1256 1257 CTRACE("query_addadditional"); 1258 1259 /* 1260 * Initialization. 1261 */ 1262 eresult = ISC_R_SUCCESS; 1263 fname = NULL; 1264 rdataset = NULL; 1265 sigrdataset = NULL; 1266 trdataset = NULL; 1267 db = NULL; 1268 version = NULL; 1269 node = NULL; 1270 added_something = ISC_FALSE; 1271 need_addname = ISC_FALSE; 1272 zone = NULL; 1273 1274 dns_clientinfomethods_init(&cm, ns_client_sourceip); 1275 dns_clientinfo_init(&ci, client); 1276 1277 /* 1278 * We treat type A additional section processing as if it 1279 * were "any address type" additional section processing. 1280 * To avoid multiple lookups, we do an 'any' database 1281 * lookup and iterate over the node. 1282 */ 1283 if (qtype == dns_rdatatype_a) 1284 type = dns_rdatatype_any; 1285 else 1286 type = qtype; 1287 1288 /* 1289 * Get some resources. 1290 */ 1291 dbuf = query_getnamebuf(client); 1292 if (dbuf == NULL) 1293 goto cleanup; 1294 fname = query_newname(client, dbuf, &b); 1295 rdataset = query_newrdataset(client); 1296 if (fname == NULL || rdataset == NULL) 1297 goto cleanup; 1298 if (WANTDNSSEC(client)) { 1299 sigrdataset = query_newrdataset(client); 1300 if (sigrdataset == NULL) 1301 goto cleanup; 1302 } 1303 1304 /* 1305 * Look for a zone database that might contain authoritative 1306 * additional data. 1307 */ 1308 result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG, 1309 &zone, &db, &version); 1310 if (result != ISC_R_SUCCESS) 1311 goto try_cache; 1312 1313 CTRACE("query_addadditional: db_find"); 1314 1315 /* 1316 * Since we are looking for authoritative data, we do not set 1317 * the GLUEOK flag. Glue will be looked for later, but not 1318 * necessarily in the same database. 1319 */ 1320 node = NULL; 1321 result = dns_db_findext(db, name, version, type, 1322 client->query.dboptions, 1323 client->now, &node, fname, &cm, &ci, 1324 rdataset, sigrdataset); 1325 if (result == ISC_R_SUCCESS) { 1326 if (sigrdataset != NULL && !dns_db_issecure(db) && 1327 dns_rdataset_isassociated(sigrdataset)) 1328 dns_rdataset_disassociate(sigrdataset); 1329 goto found; 1330 } 1331 1332 if (dns_rdataset_isassociated(rdataset)) 1333 dns_rdataset_disassociate(rdataset); 1334 if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) 1335 dns_rdataset_disassociate(sigrdataset); 1336 if (node != NULL) 1337 dns_db_detachnode(db, &node); 1338 version = NULL; 1339 dns_db_detach(&db); 1340 1341 /* 1342 * No authoritative data was found. The cache is our next best bet. 1343 */ 1344 1345 try_cache: 1346 result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG); 1347 if (result != ISC_R_SUCCESS) 1348 /* 1349 * Most likely the client isn't allowed to query the cache. 1350 */ 1351 goto try_glue; 1352 /* 1353 * Attempt to validate glue. 1354 */ 1355 if (sigrdataset == NULL) { 1356 sigrdataset = query_newrdataset(client); 1357 if (sigrdataset == NULL) 1358 goto cleanup; 1359 } 1360 result = dns_db_findext(db, name, version, type, 1361 client->query.dboptions | 1362 DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, 1363 client->now, &node, fname, &cm, &ci, 1364 rdataset, sigrdataset); 1365 1366 dns_cache_updatestats(client->view->cache, result); 1367 if (result == DNS_R_GLUE && 1368 validate(client, db, fname, rdataset, sigrdataset)) 1369 result = ISC_R_SUCCESS; 1370 if (!WANTDNSSEC(client)) 1371 query_putrdataset(client, &sigrdataset); 1372 if (result == ISC_R_SUCCESS) 1373 goto found; 1374 1375 1376 if (dns_rdataset_isassociated(rdataset)) 1377 dns_rdataset_disassociate(rdataset); 1378 if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) 1379 dns_rdataset_disassociate(sigrdataset); 1380 if (node != NULL) 1381 dns_db_detachnode(db, &node); 1382 dns_db_detach(&db); 1383 1384 try_glue: 1385 /* 1386 * No cached data was found. Glue is our last chance. 1387 * RFC1035 sayeth: 1388 * 1389 * NS records cause both the usual additional section 1390 * processing to locate a type A record, and, when used 1391 * in a referral, a special search of the zone in which 1392 * they reside for glue information. 1393 * 1394 * This is the "special search". Note that we must search 1395 * the zone where the NS record resides, not the zone it 1396 * points to, and that we only do the search in the delegation 1397 * case (identified by client->query.gluedb being set). 1398 */ 1399 1400 if (client->query.gluedb == NULL) 1401 goto cleanup; 1402 1403 /* 1404 * Don't poison caches using the bailiwick protection model. 1405 */ 1406 if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb))) 1407 goto cleanup; 1408 1409 dns_db_attach(client->query.gluedb, &db); 1410 result = dns_db_findext(db, name, version, type, 1411 client->query.dboptions | DNS_DBFIND_GLUEOK, 1412 client->now, &node, fname, &cm, &ci, 1413 rdataset, sigrdataset); 1414 if (!(result == ISC_R_SUCCESS || 1415 result == DNS_R_ZONECUT || 1416 result == DNS_R_GLUE)) 1417 goto cleanup; 1418 1419 found: 1420 /* 1421 * We have found a potential additional data rdataset, or 1422 * at least a node to iterate over. 1423 */ 1424 query_keepname(client, fname, dbuf); 1425 1426 /* 1427 * If we have an rdataset, add it to the additional data 1428 * section. 1429 */ 1430 mname = NULL; 1431 if (dns_rdataset_isassociated(rdataset) && 1432 !query_isduplicate(client, fname, type, &mname)) { 1433 if (mname != NULL) { 1434 INSIST(mname != fname); 1435 query_releasename(client, &fname); 1436 fname = mname; 1437 } else 1438 need_addname = ISC_TRUE; 1439 ISC_LIST_APPEND(fname->list, rdataset, link); 1440 trdataset = rdataset; 1441 rdataset = NULL; 1442 added_something = ISC_TRUE; 1443 /* 1444 * Note: we only add SIGs if we've added the type they cover, 1445 * so we do not need to check if the SIG rdataset is already 1446 * in the response. 1447 */ 1448 if (sigrdataset != NULL && 1449 dns_rdataset_isassociated(sigrdataset)) 1450 { 1451 ISC_LIST_APPEND(fname->list, sigrdataset, link); 1452 sigrdataset = NULL; 1453 } 1454 } 1455 1456 if (qtype == dns_rdatatype_a) { 1457 #ifdef ALLOW_FILTER_AAAA 1458 isc_boolean_t have_a = ISC_FALSE; 1459 #endif 1460 1461 /* 1462 * We now go looking for A and AAAA records, along with 1463 * their signatures. 1464 * 1465 * XXXRTH This code could be more efficient. 1466 */ 1467 if (rdataset != NULL) { 1468 if (dns_rdataset_isassociated(rdataset)) 1469 dns_rdataset_disassociate(rdataset); 1470 } else { 1471 rdataset = query_newrdataset(client); 1472 if (rdataset == NULL) 1473 goto addname; 1474 } 1475 if (sigrdataset != NULL) { 1476 if (dns_rdataset_isassociated(sigrdataset)) 1477 dns_rdataset_disassociate(sigrdataset); 1478 } else if (WANTDNSSEC(client)) { 1479 sigrdataset = query_newrdataset(client); 1480 if (sigrdataset == NULL) 1481 goto addname; 1482 } 1483 if (query_isduplicate(client, fname, dns_rdatatype_a, NULL)) 1484 goto aaaa_lookup; 1485 result = dns_db_findrdataset(db, node, version, 1486 dns_rdatatype_a, 0, 1487 client->now, 1488 rdataset, sigrdataset); 1489 if (result == DNS_R_NCACHENXDOMAIN) 1490 goto addname; 1491 if (result == DNS_R_NCACHENXRRSET) { 1492 dns_rdataset_disassociate(rdataset); 1493 if (sigrdataset != NULL && 1494 dns_rdataset_isassociated(sigrdataset)) 1495 dns_rdataset_disassociate(sigrdataset); 1496 } 1497 if (result == ISC_R_SUCCESS) { 1498 mname = NULL; 1499 #ifdef ALLOW_FILTER_AAAA 1500 have_a = ISC_TRUE; 1501 #endif 1502 if (!query_isduplicate(client, fname, 1503 dns_rdatatype_a, &mname)) { 1504 if (mname != fname) { 1505 if (mname != NULL) { 1506 query_releasename(client, &fname); 1507 fname = mname; 1508 } else 1509 need_addname = ISC_TRUE; 1510 } 1511 ISC_LIST_APPEND(fname->list, rdataset, link); 1512 added_something = ISC_TRUE; 1513 if (sigrdataset != NULL && 1514 dns_rdataset_isassociated(sigrdataset)) 1515 { 1516 ISC_LIST_APPEND(fname->list, 1517 sigrdataset, link); 1518 sigrdataset = 1519 query_newrdataset(client); 1520 } 1521 rdataset = query_newrdataset(client); 1522 if (rdataset == NULL) 1523 goto addname; 1524 if (WANTDNSSEC(client) && sigrdataset == NULL) 1525 goto addname; 1526 } else { 1527 dns_rdataset_disassociate(rdataset); 1528 if (sigrdataset != NULL && 1529 dns_rdataset_isassociated(sigrdataset)) 1530 dns_rdataset_disassociate(sigrdataset); 1531 } 1532 } 1533 aaaa_lookup: 1534 if (query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL)) 1535 goto addname; 1536 result = dns_db_findrdataset(db, node, version, 1537 dns_rdatatype_aaaa, 0, 1538 client->now, 1539 rdataset, sigrdataset); 1540 if (result == DNS_R_NCACHENXDOMAIN) 1541 goto addname; 1542 if (result == DNS_R_NCACHENXRRSET) { 1543 dns_rdataset_disassociate(rdataset); 1544 if (sigrdataset != NULL && 1545 dns_rdataset_isassociated(sigrdataset)) 1546 dns_rdataset_disassociate(sigrdataset); 1547 } 1548 if (result == ISC_R_SUCCESS) { 1549 mname = NULL; 1550 /* 1551 * There's an A; check whether we're filtering AAAA 1552 */ 1553 #ifdef ALLOW_FILTER_AAAA 1554 if (have_a && 1555 (client->filter_aaaa == dns_aaaa_break_dnssec || 1556 (client->filter_aaaa == dns_aaaa_filter && 1557 (!WANTDNSSEC(client) || sigrdataset == NULL || 1558 !dns_rdataset_isassociated(sigrdataset))))) 1559 goto addname; 1560 #endif 1561 if (!query_isduplicate(client, fname, 1562 dns_rdatatype_aaaa, &mname)) { 1563 if (mname != fname) { 1564 if (mname != NULL) { 1565 query_releasename(client, &fname); 1566 fname = mname; 1567 } else 1568 need_addname = ISC_TRUE; 1569 } 1570 ISC_LIST_APPEND(fname->list, rdataset, link); 1571 added_something = ISC_TRUE; 1572 if (sigrdataset != NULL && 1573 dns_rdataset_isassociated(sigrdataset)) 1574 { 1575 ISC_LIST_APPEND(fname->list, 1576 sigrdataset, link); 1577 sigrdataset = NULL; 1578 } 1579 rdataset = NULL; 1580 } 1581 } 1582 } 1583 1584 addname: 1585 CTRACE("query_addadditional: addname"); 1586 /* 1587 * If we haven't added anything, then we're done. 1588 */ 1589 if (!added_something) 1590 goto cleanup; 1591 1592 /* 1593 * We may have added our rdatasets to an existing name, if so, then 1594 * need_addname will be ISC_FALSE. Whether we used an existing name 1595 * or a new one, we must set fname to NULL to prevent cleanup. 1596 */ 1597 if (need_addname) 1598 dns_message_addname(client->message, fname, 1599 DNS_SECTION_ADDITIONAL); 1600 fname = NULL; 1601 1602 /* 1603 * In a few cases, we want to add additional data for additional 1604 * data. It's simpler to just deal with special cases here than 1605 * to try to create a general purpose mechanism and allow the 1606 * rdata implementations to do it themselves. 1607 * 1608 * This involves recursion, but the depth is limited. The 1609 * most complex case is adding a SRV rdataset, which involves 1610 * recursing to add address records, which in turn can cause 1611 * recursion to add KEYs. 1612 */ 1613 if (type == dns_rdatatype_srv && trdataset != NULL) { 1614 /* 1615 * If we're adding SRV records to the additional data 1616 * section, it's helpful if we add the SRV additional data 1617 * as well. 1618 */ 1619 eresult = dns_rdataset_additionaldata(trdataset, 1620 query_addadditional, 1621 client); 1622 } 1623 1624 cleanup: 1625 CTRACE("query_addadditional: cleanup"); 1626 query_putrdataset(client, &rdataset); 1627 if (sigrdataset != NULL) 1628 query_putrdataset(client, &sigrdataset); 1629 if (fname != NULL) 1630 query_releasename(client, &fname); 1631 if (node != NULL) 1632 dns_db_detachnode(db, &node); 1633 if (db != NULL) 1634 dns_db_detach(&db); 1635 if (zone != NULL) 1636 dns_zone_detach(&zone); 1637 1638 CTRACE("query_addadditional: done"); 1639 return (eresult); 1640 } 1641 1642 static inline void 1643 query_discardcache(ns_client_t *client, dns_rdataset_t *rdataset_base, 1644 dns_rdatasetadditional_t additionaltype, 1645 dns_rdatatype_t type, dns_zone_t **zonep, dns_db_t **dbp, 1646 dns_dbversion_t **versionp, dns_dbnode_t **nodep, 1647 dns_name_t *fname) 1648 { 1649 dns_rdataset_t *rdataset; 1650 1651 while ((rdataset = ISC_LIST_HEAD(fname->list)) != NULL) { 1652 ISC_LIST_UNLINK(fname->list, rdataset, link); 1653 query_putrdataset(client, &rdataset); 1654 } 1655 if (*versionp != NULL) 1656 dns_db_closeversion(*dbp, versionp, ISC_FALSE); 1657 if (*nodep != NULL) 1658 dns_db_detachnode(*dbp, nodep); 1659 if (*dbp != NULL) 1660 dns_db_detach(dbp); 1661 if (*zonep != NULL) 1662 dns_zone_detach(zonep); 1663 (void)dns_rdataset_putadditional(client->view->acache, rdataset_base, 1664 additionaltype, type); 1665 } 1666 1667 static inline isc_result_t 1668 query_iscachevalid(dns_zone_t *zone, dns_db_t *db, dns_db_t *db0, 1669 dns_dbversion_t *version) 1670 { 1671 isc_result_t result = ISC_R_SUCCESS; 1672 dns_dbversion_t *version_current = NULL; 1673 dns_db_t *db_current = db0; 1674 1675 if (db_current == NULL) { 1676 result = dns_zone_getdb(zone, &db_current); 1677 if (result != ISC_R_SUCCESS) 1678 return (result); 1679 } 1680 dns_db_currentversion(db_current, &version_current); 1681 if (db_current != db || version_current != version) { 1682 result = ISC_R_FAILURE; 1683 goto cleanup; 1684 } 1685 1686 cleanup: 1687 dns_db_closeversion(db_current, &version_current, ISC_FALSE); 1688 if (db0 == NULL && db_current != NULL) 1689 dns_db_detach(&db_current); 1690 1691 return (result); 1692 } 1693 1694 static isc_result_t 1695 query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { 1696 client_additionalctx_t *additionalctx = arg; 1697 dns_rdataset_t *rdataset_base; 1698 ns_client_t *client; 1699 isc_result_t result, eresult; 1700 dns_dbnode_t *node, *cnode; 1701 dns_db_t *db, *cdb; 1702 dns_name_t *fname, *mname0, cfname; 1703 dns_rdataset_t *rdataset, *sigrdataset; 1704 dns_rdataset_t *crdataset, *crdataset_next; 1705 isc_buffer_t *dbuf; 1706 isc_buffer_t b; 1707 dns_dbversion_t *version, *cversion; 1708 isc_boolean_t added_something, need_addname, needadditionalcache; 1709 isc_boolean_t need_sigrrset; 1710 dns_zone_t *zone; 1711 dns_rdatatype_t type; 1712 dns_rdatasetadditional_t additionaltype; 1713 dns_clientinfomethods_t cm; 1714 dns_clientinfo_t ci; 1715 1716 /* 1717 * If we don't have an additional cache call query_addadditional. 1718 */ 1719 client = additionalctx->client; 1720 REQUIRE(NS_CLIENT_VALID(client)); 1721 1722 if (qtype != dns_rdatatype_a || client->view->acache == NULL) { 1723 /* 1724 * This function is optimized for "address" types. For other 1725 * types, use a generic routine. 1726 * XXX: ideally, this function should be generic enough. 1727 */ 1728 return (query_addadditional(additionalctx->client, 1729 name, qtype)); 1730 } 1731 1732 /* 1733 * Initialization. 1734 */ 1735 rdataset_base = additionalctx->rdataset; 1736 eresult = ISC_R_SUCCESS; 1737 fname = NULL; 1738 rdataset = NULL; 1739 sigrdataset = NULL; 1740 db = NULL; 1741 cdb = NULL; 1742 version = NULL; 1743 cversion = NULL; 1744 node = NULL; 1745 cnode = NULL; 1746 added_something = ISC_FALSE; 1747 need_addname = ISC_FALSE; 1748 zone = NULL; 1749 needadditionalcache = ISC_FALSE; 1750 POST(needadditionalcache); 1751 additionaltype = dns_rdatasetadditional_fromauth; 1752 dns_name_init(&cfname, NULL); 1753 dns_clientinfomethods_init(&cm, ns_client_sourceip); 1754 dns_clientinfo_init(&ci, client); 1755 1756 CTRACE("query_addadditional2"); 1757 1758 /* 1759 * We treat type A additional section processing as if it 1760 * were "any address type" additional section processing. 1761 * To avoid multiple lookups, we do an 'any' database 1762 * lookup and iterate over the node. 1763 * XXXJT: this approach can cause a suboptimal result when the cache 1764 * DB only has partial address types and the glue DB has remaining 1765 * ones. 1766 */ 1767 type = dns_rdatatype_any; 1768 1769 /* 1770 * Get some resources. 1771 */ 1772 dbuf = query_getnamebuf(client); 1773 if (dbuf == NULL) 1774 goto cleanup; 1775 fname = query_newname(client, dbuf, &b); 1776 if (fname == NULL) 1777 goto cleanup; 1778 dns_name_setbuffer(&cfname, &b); /* share the buffer */ 1779 1780 /* Check additional cache */ 1781 result = dns_rdataset_getadditional(rdataset_base, additionaltype, 1782 type, client->view->acache, &zone, 1783 &cdb, &cversion, &cnode, &cfname, 1784 client->message, client->now); 1785 if (result != ISC_R_SUCCESS) 1786 goto findauthdb; 1787 if (zone == NULL) { 1788 CTRACE("query_addadditional2: auth zone not found"); 1789 goto try_cache; 1790 } 1791 1792 /* Is the cached DB up-to-date? */ 1793 result = query_iscachevalid(zone, cdb, NULL, cversion); 1794 if (result != ISC_R_SUCCESS) { 1795 CTRACE("query_addadditional2: old auth additional cache"); 1796 query_discardcache(client, rdataset_base, additionaltype, 1797 type, &zone, &cdb, &cversion, &cnode, 1798 &cfname); 1799 goto findauthdb; 1800 } 1801 1802 if (cnode == NULL) { 1803 /* 1804 * We have a negative cache. We don't have to check the zone 1805 * ACL, since the result (not using this zone) would be same 1806 * regardless of the result. 1807 */ 1808 CTRACE("query_addadditional2: negative auth additional cache"); 1809 dns_db_closeversion(cdb, &cversion, ISC_FALSE); 1810 dns_db_detach(&cdb); 1811 dns_zone_detach(&zone); 1812 goto try_cache; 1813 } 1814 1815 result = query_validatezonedb(client, name, qtype, DNS_GETDB_NOLOG, 1816 zone, cdb, NULL); 1817 if (result != ISC_R_SUCCESS) { 1818 query_discardcache(client, rdataset_base, additionaltype, 1819 type, &zone, &cdb, &cversion, &cnode, 1820 &cfname); 1821 goto try_cache; 1822 } 1823 1824 /* We've got an active cache. */ 1825 CTRACE("query_addadditional2: auth additional cache"); 1826 dns_db_closeversion(cdb, &cversion, ISC_FALSE); 1827 db = cdb; 1828 node = cnode; 1829 dns_name_clone(&cfname, fname); 1830 query_keepname(client, fname, dbuf); 1831 goto foundcache; 1832 1833 /* 1834 * Look for a zone database that might contain authoritative 1835 * additional data. 1836 */ 1837 findauthdb: 1838 result = query_getzonedb(client, name, qtype, DNS_GETDB_NOLOG, 1839 &zone, &db, &version); 1840 if (result != ISC_R_SUCCESS) { 1841 /* Cache the negative result */ 1842 (void)dns_rdataset_setadditional(rdataset_base, additionaltype, 1843 type, client->view->acache, 1844 NULL, NULL, NULL, NULL, 1845 NULL); 1846 goto try_cache; 1847 } 1848 1849 CTRACE("query_addadditional2: db_find"); 1850 1851 /* 1852 * Since we are looking for authoritative data, we do not set 1853 * the GLUEOK flag. Glue will be looked for later, but not 1854 * necessarily in the same database. 1855 */ 1856 node = NULL; 1857 result = dns_db_findext(db, name, version, type, 1858 client->query.dboptions, 1859 client->now, &node, fname, &cm, &ci, 1860 NULL, NULL); 1861 if (result == ISC_R_SUCCESS) 1862 goto found; 1863 1864 /* Cache the negative result */ 1865 (void)dns_rdataset_setadditional(rdataset_base, additionaltype, 1866 type, client->view->acache, zone, db, 1867 version, NULL, fname); 1868 1869 if (node != NULL) 1870 dns_db_detachnode(db, &node); 1871 version = NULL; 1872 dns_db_detach(&db); 1873 1874 /* 1875 * No authoritative data was found. The cache is our next best bet. 1876 */ 1877 1878 try_cache: 1879 additionaltype = dns_rdatasetadditional_fromcache; 1880 result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG); 1881 if (result != ISC_R_SUCCESS) 1882 /* 1883 * Most likely the client isn't allowed to query the cache. 1884 */ 1885 goto try_glue; 1886 1887 result = dns_db_findext(db, name, version, type, 1888 client->query.dboptions | 1889 DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, 1890 client->now, &node, fname, &cm, &ci, 1891 NULL, NULL); 1892 if (result == ISC_R_SUCCESS) 1893 goto found; 1894 1895 if (node != NULL) 1896 dns_db_detachnode(db, &node); 1897 dns_db_detach(&db); 1898 1899 try_glue: 1900 /* 1901 * No cached data was found. Glue is our last chance. 1902 * RFC1035 sayeth: 1903 * 1904 * NS records cause both the usual additional section 1905 * processing to locate a type A record, and, when used 1906 * in a referral, a special search of the zone in which 1907 * they reside for glue information. 1908 * 1909 * This is the "special search". Note that we must search 1910 * the zone where the NS record resides, not the zone it 1911 * points to, and that we only do the search in the delegation 1912 * case (identified by client->query.gluedb being set). 1913 */ 1914 if (client->query.gluedb == NULL) 1915 goto cleanup; 1916 1917 /* 1918 * Don't poison caches using the bailiwick protection model. 1919 */ 1920 if (!dns_name_issubdomain(name, dns_db_origin(client->query.gluedb))) 1921 goto cleanup; 1922 1923 /* Check additional cache */ 1924 additionaltype = dns_rdatasetadditional_fromglue; 1925 result = dns_rdataset_getadditional(rdataset_base, additionaltype, 1926 type, client->view->acache, NULL, 1927 &cdb, &cversion, &cnode, &cfname, 1928 client->message, client->now); 1929 if (result != ISC_R_SUCCESS) 1930 goto findglue; 1931 1932 result = query_iscachevalid(zone, cdb, client->query.gluedb, cversion); 1933 if (result != ISC_R_SUCCESS) { 1934 CTRACE("query_addadditional2: old glue additional cache"); 1935 query_discardcache(client, rdataset_base, additionaltype, 1936 type, &zone, &cdb, &cversion, &cnode, 1937 &cfname); 1938 goto findglue; 1939 } 1940 1941 if (cnode == NULL) { 1942 /* We have a negative cache. */ 1943 CTRACE("query_addadditional2: negative glue additional cache"); 1944 dns_db_closeversion(cdb, &cversion, ISC_FALSE); 1945 dns_db_detach(&cdb); 1946 goto cleanup; 1947 } 1948 1949 /* Cache hit. */ 1950 CTRACE("query_addadditional2: glue additional cache"); 1951 dns_db_closeversion(cdb, &cversion, ISC_FALSE); 1952 db = cdb; 1953 node = cnode; 1954 dns_name_clone(&cfname, fname); 1955 query_keepname(client, fname, dbuf); 1956 goto foundcache; 1957 1958 findglue: 1959 dns_db_attach(client->query.gluedb, &db); 1960 result = dns_db_findext(db, name, version, type, 1961 client->query.dboptions | DNS_DBFIND_GLUEOK, 1962 client->now, &node, fname, &cm, &ci, 1963 NULL, NULL); 1964 if (!(result == ISC_R_SUCCESS || 1965 result == DNS_R_ZONECUT || 1966 result == DNS_R_GLUE)) { 1967 /* cache the negative result */ 1968 (void)dns_rdataset_setadditional(rdataset_base, additionaltype, 1969 type, client->view->acache, 1970 NULL, db, version, NULL, 1971 fname); 1972 goto cleanup; 1973 } 1974 1975 found: 1976 /* 1977 * We have found a DB node to iterate over from a DB. 1978 * We are going to look for address RRsets (i.e., A and AAAA) in the DB 1979 * node we've just found. We'll then store the complete information 1980 * in the additional data cache. 1981 */ 1982 dns_name_clone(fname, &cfname); 1983 query_keepname(client, fname, dbuf); 1984 needadditionalcache = ISC_TRUE; 1985 1986 rdataset = query_newrdataset(client); 1987 if (rdataset == NULL) 1988 goto cleanup; 1989 1990 sigrdataset = query_newrdataset(client); 1991 if (sigrdataset == NULL) 1992 goto cleanup; 1993 1994 if (additionaltype == dns_rdatasetadditional_fromcache && 1995 query_isduplicate(client, fname, dns_rdatatype_a, NULL)) 1996 goto aaaa_lookup; 1997 /* 1998 * Find A RRset with sig RRset. Even if we don't find a sig RRset 1999 * for a client using DNSSEC, we'll continue the process to make a 2000 * complete list to be cached. However, we need to cancel the 2001 * caching when something unexpected happens, in order to avoid 2002 * caching incomplete information. 2003 */ 2004 result = dns_db_findrdataset(db, node, version, dns_rdatatype_a, 0, 2005 client->now, rdataset, sigrdataset); 2006 /* 2007 * If we can't promote glue/pending from the cache to secure 2008 * then drop it. 2009 */ 2010 if (result == ISC_R_SUCCESS && 2011 additionaltype == dns_rdatasetadditional_fromcache && 2012 (DNS_TRUST_PENDING(rdataset->trust) || 2013 DNS_TRUST_GLUE(rdataset->trust)) && 2014 !validate(client, db, fname, rdataset, sigrdataset)) { 2015 dns_rdataset_disassociate(rdataset); 2016 if (dns_rdataset_isassociated(sigrdataset)) 2017 dns_rdataset_disassociate(sigrdataset); 2018 result = ISC_R_NOTFOUND; 2019 } 2020 if (result == DNS_R_NCACHENXDOMAIN) 2021 goto setcache; 2022 if (result == DNS_R_NCACHENXRRSET) { 2023 dns_rdataset_disassociate(rdataset); 2024 if (dns_rdataset_isassociated(sigrdataset)) 2025 dns_rdataset_disassociate(sigrdataset); 2026 } 2027 if (result == ISC_R_SUCCESS) { 2028 /* Remember the result as a cache */ 2029 ISC_LIST_APPEND(cfname.list, rdataset, link); 2030 if (dns_rdataset_isassociated(sigrdataset)) { 2031 ISC_LIST_APPEND(cfname.list, sigrdataset, link); 2032 sigrdataset = query_newrdataset(client); 2033 } 2034 rdataset = query_newrdataset(client); 2035 if (sigrdataset == NULL || rdataset == NULL) { 2036 /* do not cache incomplete information */ 2037 goto foundcache; 2038 } 2039 } 2040 2041 aaaa_lookup: 2042 if (additionaltype == dns_rdatasetadditional_fromcache && 2043 query_isduplicate(client, fname, dns_rdatatype_aaaa, NULL)) 2044 goto foundcache; 2045 /* Find AAAA RRset with sig RRset */ 2046 result = dns_db_findrdataset(db, node, version, dns_rdatatype_aaaa, 2047 0, client->now, rdataset, sigrdataset); 2048 /* 2049 * If we can't promote glue/pending from the cache to secure 2050 * then drop it. 2051 */ 2052 if (result == ISC_R_SUCCESS && 2053 additionaltype == dns_rdatasetadditional_fromcache && 2054 (DNS_TRUST_PENDING(rdataset->trust) || 2055 DNS_TRUST_GLUE(rdataset->trust)) && 2056 !validate(client, db, fname, rdataset, sigrdataset)) { 2057 dns_rdataset_disassociate(rdataset); 2058 if (dns_rdataset_isassociated(sigrdataset)) 2059 dns_rdataset_disassociate(sigrdataset); 2060 result = ISC_R_NOTFOUND; 2061 } 2062 if (result == ISC_R_SUCCESS) { 2063 ISC_LIST_APPEND(cfname.list, rdataset, link); 2064 rdataset = NULL; 2065 if (dns_rdataset_isassociated(sigrdataset)) { 2066 ISC_LIST_APPEND(cfname.list, sigrdataset, link); 2067 sigrdataset = NULL; 2068 } 2069 } 2070 2071 setcache: 2072 /* 2073 * Set the new result in the cache if required. We do not support 2074 * caching additional data from a cache DB. 2075 */ 2076 if (needadditionalcache == ISC_TRUE && 2077 (additionaltype == dns_rdatasetadditional_fromauth || 2078 additionaltype == dns_rdatasetadditional_fromglue)) { 2079 (void)dns_rdataset_setadditional(rdataset_base, additionaltype, 2080 type, client->view->acache, 2081 zone, db, version, node, 2082 &cfname); 2083 } 2084 2085 foundcache: 2086 need_sigrrset = ISC_FALSE; 2087 mname0 = NULL; 2088 for (crdataset = ISC_LIST_HEAD(cfname.list); 2089 crdataset != NULL; 2090 crdataset = crdataset_next) { 2091 dns_name_t *mname; 2092 2093 crdataset_next = ISC_LIST_NEXT(crdataset, link); 2094 2095 mname = NULL; 2096 if (crdataset->type == dns_rdatatype_a || 2097 crdataset->type == dns_rdatatype_aaaa) { 2098 if (!query_isduplicate(client, fname, crdataset->type, 2099 &mname)) { 2100 if (mname != fname) { 2101 if (mname != NULL) { 2102 /* 2103 * A different type of this name is 2104 * already stored in the additional 2105 * section. We'll reuse the name. 2106 * Note that this should happen at most 2107 * once. Otherwise, fname->link could 2108 * leak below. 2109 */ 2110 INSIST(mname0 == NULL); 2111 2112 query_releasename(client, &fname); 2113 fname = mname; 2114 mname0 = mname; 2115 } else 2116 need_addname = ISC_TRUE; 2117 } 2118 ISC_LIST_UNLINK(cfname.list, crdataset, link); 2119 ISC_LIST_APPEND(fname->list, crdataset, link); 2120 added_something = ISC_TRUE; 2121 need_sigrrset = ISC_TRUE; 2122 } else 2123 need_sigrrset = ISC_FALSE; 2124 } else if (crdataset->type == dns_rdatatype_rrsig && 2125 need_sigrrset && WANTDNSSEC(client)) { 2126 ISC_LIST_UNLINK(cfname.list, crdataset, link); 2127 ISC_LIST_APPEND(fname->list, crdataset, link); 2128 added_something = ISC_TRUE; /* just in case */ 2129 need_sigrrset = ISC_FALSE; 2130 } 2131 } 2132 2133 CTRACE("query_addadditional2: addname"); 2134 2135 /* 2136 * If we haven't added anything, then we're done. 2137 */ 2138 if (!added_something) 2139 goto cleanup; 2140 2141 /* 2142 * We may have added our rdatasets to an existing name, if so, then 2143 * need_addname will be ISC_FALSE. Whether we used an existing name 2144 * or a new one, we must set fname to NULL to prevent cleanup. 2145 */ 2146 if (need_addname) 2147 dns_message_addname(client->message, fname, 2148 DNS_SECTION_ADDITIONAL); 2149 fname = NULL; 2150 2151 cleanup: 2152 CTRACE("query_addadditional2: cleanup"); 2153 2154 if (rdataset != NULL) 2155 query_putrdataset(client, &rdataset); 2156 if (sigrdataset != NULL) 2157 query_putrdataset(client, &sigrdataset); 2158 while ((crdataset = ISC_LIST_HEAD(cfname.list)) != NULL) { 2159 ISC_LIST_UNLINK(cfname.list, crdataset, link); 2160 query_putrdataset(client, &crdataset); 2161 } 2162 if (fname != NULL) 2163 query_releasename(client, &fname); 2164 if (node != NULL) 2165 dns_db_detachnode(db, &node); 2166 if (db != NULL) 2167 dns_db_detach(&db); 2168 if (zone != NULL) 2169 dns_zone_detach(&zone); 2170 2171 CTRACE("query_addadditional2: done"); 2172 return (eresult); 2173 } 2174 2175 static inline void 2176 query_addrdataset(ns_client_t *client, dns_name_t *fname, 2177 dns_rdataset_t *rdataset) 2178 { 2179 client_additionalctx_t additionalctx; 2180 2181 /* 2182 * Add 'rdataset' and any pertinent additional data to 2183 * 'fname', a name in the response message for 'client'. 2184 */ 2185 2186 CTRACE("query_addrdataset"); 2187 2188 ISC_LIST_APPEND(fname->list, rdataset, link); 2189 2190 if (client->view->order != NULL) 2191 rdataset->attributes |= dns_order_find(client->view->order, 2192 fname, rdataset->type, 2193 rdataset->rdclass); 2194 rdataset->attributes |= DNS_RDATASETATTR_LOADORDER; 2195 2196 if (NOADDITIONAL(client)) 2197 return; 2198 2199 /* 2200 * Add additional data. 2201 * 2202 * We don't care if dns_rdataset_additionaldata() fails. 2203 */ 2204 additionalctx.client = client; 2205 additionalctx.rdataset = rdataset; 2206 (void)dns_rdataset_additionaldata(rdataset, query_addadditional2, 2207 &additionalctx); 2208 CTRACE("query_addrdataset: done"); 2209 } 2210 2211 static isc_result_t 2212 query_dns64(ns_client_t *client, dns_name_t **namep, dns_rdataset_t *rdataset, 2213 dns_rdataset_t *sigrdataset, isc_buffer_t *dbuf, 2214 dns_section_t section) 2215 { 2216 dns_name_t *name, *mname; 2217 dns_rdata_t *dns64_rdata; 2218 dns_rdata_t rdata = DNS_RDATA_INIT; 2219 dns_rdatalist_t *dns64_rdatalist; 2220 dns_rdataset_t *dns64_rdataset; 2221 dns_rdataset_t *mrdataset; 2222 isc_buffer_t *buffer; 2223 isc_region_t r; 2224 isc_result_t result; 2225 dns_view_t *view = client->view; 2226 isc_netaddr_t netaddr; 2227 dns_dns64_t *dns64; 2228 unsigned int flags = 0; 2229 2230 /*% 2231 * To the current response for 'client', add the answer RRset 2232 * '*rdatasetp' and an optional signature set '*sigrdatasetp', with 2233 * owner name '*namep', to section 'section', unless they are 2234 * already there. Also add any pertinent additional data. 2235 * 2236 * If 'dbuf' is not NULL, then '*namep' is the name whose data is 2237 * stored in 'dbuf'. In this case, query_addrrset() guarantees that 2238 * when it returns the name will either have been kept or released. 2239 */ 2240 CTRACE("query_dns64"); 2241 name = *namep; 2242 mname = NULL; 2243 mrdataset = NULL; 2244 buffer = NULL; 2245 dns64_rdata = NULL; 2246 dns64_rdataset = NULL; 2247 dns64_rdatalist = NULL; 2248 result = dns_message_findname(client->message, section, 2249 name, dns_rdatatype_aaaa, 2250 rdataset->covers, 2251 &mname, &mrdataset); 2252 if (result == ISC_R_SUCCESS) { 2253 /* 2254 * We've already got an RRset of the given name and type. 2255 * There's nothing else to do; 2256 */ 2257 CTRACE("query_dns64: dns_message_findname succeeded: done"); 2258 if (dbuf != NULL) 2259 query_releasename(client, namep); 2260 return (ISC_R_SUCCESS); 2261 } else if (result == DNS_R_NXDOMAIN) { 2262 /* 2263 * The name doesn't exist. 2264 */ 2265 if (dbuf != NULL) 2266 query_keepname(client, name, dbuf); 2267 dns_message_addname(client->message, name, section); 2268 *namep = NULL; 2269 mname = name; 2270 } else { 2271 RUNTIME_CHECK(result == DNS_R_NXRRSET); 2272 if (dbuf != NULL) 2273 query_releasename(client, namep); 2274 } 2275 2276 if (rdataset->trust != dns_trust_secure && 2277 (section == DNS_SECTION_ANSWER || 2278 section == DNS_SECTION_AUTHORITY)) 2279 client->query.attributes &= ~NS_QUERYATTR_SECURE; 2280 2281 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); 2282 2283 result = isc_buffer_allocate(client->mctx, &buffer, view->dns64cnt * 2284 16 * dns_rdataset_count(rdataset)); 2285 if (result != ISC_R_SUCCESS) 2286 goto cleanup; 2287 result = dns_message_gettemprdataset(client->message, &dns64_rdataset); 2288 if (result != ISC_R_SUCCESS) 2289 goto cleanup; 2290 result = dns_message_gettemprdatalist(client->message, 2291 &dns64_rdatalist); 2292 if (result != ISC_R_SUCCESS) 2293 goto cleanup; 2294 2295 dns_rdatalist_init(dns64_rdatalist); 2296 dns64_rdatalist->rdclass = dns_rdataclass_in; 2297 dns64_rdatalist->type = dns_rdatatype_aaaa; 2298 if (client->query.dns64_ttl != ISC_UINT32_MAX) 2299 dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl, 2300 client->query.dns64_ttl); 2301 else 2302 dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl, 600); 2303 2304 if (RECURSIONOK(client)) 2305 flags |= DNS_DNS64_RECURSIVE; 2306 2307 /* 2308 * We use the signatures from the A lookup to set DNS_DNS64_DNSSEC 2309 * as this provides a easy way to see if the answer was signed. 2310 */ 2311 if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) 2312 flags |= DNS_DNS64_DNSSEC; 2313 2314 for (result = dns_rdataset_first(rdataset); 2315 result == ISC_R_SUCCESS; 2316 result = dns_rdataset_next(rdataset)) { 2317 for (dns64 = ISC_LIST_HEAD(client->view->dns64); 2318 dns64 != NULL; dns64 = dns_dns64_next(dns64)) { 2319 2320 dns_rdataset_current(rdataset, &rdata); 2321 isc_buffer_availableregion(buffer, &r); 2322 INSIST(r.length >= 16); 2323 result = dns_dns64_aaaafroma(dns64, &netaddr, 2324 client->signer, 2325 &ns_g_server->aclenv, 2326 flags, rdata.data, r.base); 2327 if (result != ISC_R_SUCCESS) { 2328 dns_rdata_reset(&rdata); 2329 continue; 2330 } 2331 isc_buffer_add(buffer, 16); 2332 isc_buffer_remainingregion(buffer, &r); 2333 isc_buffer_forward(buffer, 16); 2334 result = dns_message_gettemprdata(client->message, 2335 &dns64_rdata); 2336 if (result != ISC_R_SUCCESS) 2337 goto cleanup; 2338 dns_rdata_init(dns64_rdata); 2339 dns_rdata_fromregion(dns64_rdata, dns_rdataclass_in, 2340 dns_rdatatype_aaaa, &r); 2341 ISC_LIST_APPEND(dns64_rdatalist->rdata, dns64_rdata, 2342 link); 2343 dns64_rdata = NULL; 2344 dns_rdata_reset(&rdata); 2345 } 2346 } 2347 if (result != ISC_R_NOMORE) 2348 goto cleanup; 2349 2350 if (ISC_LIST_EMPTY(dns64_rdatalist->rdata)) 2351 goto cleanup; 2352 2353 result = dns_rdatalist_tordataset(dns64_rdatalist, dns64_rdataset); 2354 if (result != ISC_R_SUCCESS) 2355 goto cleanup; 2356 client->query.attributes |= NS_QUERYATTR_NOADDITIONAL; 2357 dns64_rdataset->trust = rdataset->trust; 2358 query_addrdataset(client, mname, dns64_rdataset); 2359 dns64_rdataset = NULL; 2360 dns64_rdatalist = NULL; 2361 dns_message_takebuffer(client->message, &buffer); 2362 inc_stats(client, dns_nsstatscounter_dns64); 2363 result = ISC_R_SUCCESS; 2364 2365 cleanup: 2366 if (buffer != NULL) 2367 isc_buffer_free(&buffer); 2368 2369 if (dns64_rdata != NULL) 2370 dns_message_puttemprdata(client->message, &dns64_rdata); 2371 2372 if (dns64_rdataset != NULL) 2373 dns_message_puttemprdataset(client->message, &dns64_rdataset); 2374 2375 if (dns64_rdatalist != NULL) { 2376 for (dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata); 2377 dns64_rdata != NULL; 2378 dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata)) 2379 { 2380 ISC_LIST_UNLINK(dns64_rdatalist->rdata, 2381 dns64_rdata, link); 2382 dns_message_puttemprdata(client->message, &dns64_rdata); 2383 } 2384 dns_message_puttemprdatalist(client->message, &dns64_rdatalist); 2385 } 2386 2387 CTRACE("query_dns64: done"); 2388 return (result); 2389 } 2390 2391 static void 2392 query_filter64(ns_client_t *client, dns_name_t **namep, 2393 dns_rdataset_t *rdataset, isc_buffer_t *dbuf, 2394 dns_section_t section) 2395 { 2396 dns_name_t *name, *mname; 2397 dns_rdata_t *myrdata; 2398 dns_rdata_t rdata = DNS_RDATA_INIT; 2399 dns_rdatalist_t *myrdatalist; 2400 dns_rdataset_t *myrdataset; 2401 isc_buffer_t *buffer; 2402 isc_region_t r; 2403 isc_result_t result; 2404 unsigned int i; 2405 2406 CTRACE("query_filter64"); 2407 2408 INSIST(client->query.dns64_aaaaok != NULL); 2409 INSIST(client->query.dns64_aaaaoklen == dns_rdataset_count(rdataset)); 2410 2411 name = *namep; 2412 mname = NULL; 2413 buffer = NULL; 2414 myrdata = NULL; 2415 myrdataset = NULL; 2416 myrdatalist = NULL; 2417 result = dns_message_findname(client->message, section, 2418 name, dns_rdatatype_aaaa, 2419 rdataset->covers, 2420 &mname, &myrdataset); 2421 if (result == ISC_R_SUCCESS) { 2422 /* 2423 * We've already got an RRset of the given name and type. 2424 * There's nothing else to do; 2425 */ 2426 CTRACE("query_filter64: dns_message_findname succeeded: done"); 2427 if (dbuf != NULL) 2428 query_releasename(client, namep); 2429 return; 2430 } else if (result == DNS_R_NXDOMAIN) { 2431 mname = name; 2432 *namep = NULL; 2433 } else { 2434 RUNTIME_CHECK(result == DNS_R_NXRRSET); 2435 if (dbuf != NULL) 2436 query_releasename(client, namep); 2437 dbuf = NULL; 2438 } 2439 2440 if (rdataset->trust != dns_trust_secure && 2441 (section == DNS_SECTION_ANSWER || 2442 section == DNS_SECTION_AUTHORITY)) 2443 client->query.attributes &= ~NS_QUERYATTR_SECURE; 2444 2445 result = isc_buffer_allocate(client->mctx, &buffer, 2446 16 * dns_rdataset_count(rdataset)); 2447 if (result != ISC_R_SUCCESS) 2448 goto cleanup; 2449 result = dns_message_gettemprdataset(client->message, &myrdataset); 2450 if (result != ISC_R_SUCCESS) 2451 goto cleanup; 2452 result = dns_message_gettemprdatalist(client->message, &myrdatalist); 2453 if (result != ISC_R_SUCCESS) 2454 goto cleanup; 2455 2456 dns_rdatalist_init(myrdatalist); 2457 myrdatalist->rdclass = dns_rdataclass_in; 2458 myrdatalist->type = dns_rdatatype_aaaa; 2459 myrdatalist->ttl = rdataset->ttl; 2460 2461 i = 0; 2462 for (result = dns_rdataset_first(rdataset); 2463 result == ISC_R_SUCCESS; 2464 result = dns_rdataset_next(rdataset)) { 2465 if (!client->query.dns64_aaaaok[i++]) 2466 continue; 2467 dns_rdataset_current(rdataset, &rdata); 2468 INSIST(rdata.length == 16); 2469 isc_buffer_putmem(buffer, rdata.data, rdata.length); 2470 isc_buffer_remainingregion(buffer, &r); 2471 isc_buffer_forward(buffer, rdata.length); 2472 result = dns_message_gettemprdata(client->message, &myrdata); 2473 if (result != ISC_R_SUCCESS) 2474 goto cleanup; 2475 dns_rdata_init(myrdata); 2476 dns_rdata_fromregion(myrdata, dns_rdataclass_in, 2477 dns_rdatatype_aaaa, &r); 2478 ISC_LIST_APPEND(myrdatalist->rdata, myrdata, link); 2479 myrdata = NULL; 2480 dns_rdata_reset(&rdata); 2481 } 2482 if (result != ISC_R_NOMORE) 2483 goto cleanup; 2484 2485 result = dns_rdatalist_tordataset(myrdatalist, myrdataset); 2486 if (result != ISC_R_SUCCESS) 2487 goto cleanup; 2488 client->query.attributes |= NS_QUERYATTR_NOADDITIONAL; 2489 if (mname == name) { 2490 if (dbuf != NULL) 2491 query_keepname(client, name, dbuf); 2492 dns_message_addname(client->message, name, section); 2493 dbuf = NULL; 2494 } 2495 myrdataset->trust = rdataset->trust; 2496 query_addrdataset(client, mname, myrdataset); 2497 myrdataset = NULL; 2498 myrdatalist = NULL; 2499 dns_message_takebuffer(client->message, &buffer); 2500 2501 cleanup: 2502 if (buffer != NULL) 2503 isc_buffer_free(&buffer); 2504 2505 if (myrdata != NULL) 2506 dns_message_puttemprdata(client->message, &myrdata); 2507 2508 if (myrdataset != NULL) 2509 dns_message_puttemprdataset(client->message, &myrdataset); 2510 2511 if (myrdatalist != NULL) { 2512 for (myrdata = ISC_LIST_HEAD(myrdatalist->rdata); 2513 myrdata != NULL; 2514 myrdata = ISC_LIST_HEAD(myrdatalist->rdata)) 2515 { 2516 ISC_LIST_UNLINK(myrdatalist->rdata, myrdata, link); 2517 dns_message_puttemprdata(client->message, &myrdata); 2518 } 2519 dns_message_puttemprdatalist(client->message, &myrdatalist); 2520 } 2521 if (dbuf != NULL) 2522 query_releasename(client, &name); 2523 2524 CTRACE("query_filter64: done"); 2525 } 2526 2527 static void 2528 query_addrrset(ns_client_t *client, dns_name_t **namep, 2529 dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp, 2530 isc_buffer_t *dbuf, dns_section_t section) 2531 { 2532 dns_name_t *name, *mname; 2533 dns_rdataset_t *rdataset, *mrdataset, *sigrdataset; 2534 isc_result_t result; 2535 2536 /*% 2537 * To the current response for 'client', add the answer RRset 2538 * '*rdatasetp' and an optional signature set '*sigrdatasetp', with 2539 * owner name '*namep', to section 'section', unless they are 2540 * already there. Also add any pertinent additional data. 2541 * 2542 * If 'dbuf' is not NULL, then '*namep' is the name whose data is 2543 * stored in 'dbuf'. In this case, query_addrrset() guarantees that 2544 * when it returns the name will either have been kept or released. 2545 */ 2546 CTRACE("query_addrrset"); 2547 name = *namep; 2548 rdataset = *rdatasetp; 2549 if (sigrdatasetp != NULL) 2550 sigrdataset = *sigrdatasetp; 2551 else 2552 sigrdataset = NULL; 2553 mname = NULL; 2554 mrdataset = NULL; 2555 result = dns_message_findname(client->message, section, 2556 name, rdataset->type, rdataset->covers, 2557 &mname, &mrdataset); 2558 if (result == ISC_R_SUCCESS) { 2559 /* 2560 * We've already got an RRset of the given name and type. 2561 */ 2562 CTRACE("query_addrrset: dns_message_findname succeeded: done"); 2563 if (dbuf != NULL) 2564 query_releasename(client, namep); 2565 if ((rdataset->attributes & DNS_RDATASETATTR_REQUIRED) != 0) 2566 mrdataset->attributes |= DNS_RDATASETATTR_REQUIRED; 2567 return; 2568 } else if (result == DNS_R_NXDOMAIN) { 2569 /* 2570 * The name doesn't exist. 2571 */ 2572 if (dbuf != NULL) 2573 query_keepname(client, name, dbuf); 2574 dns_message_addname(client->message, name, section); 2575 *namep = NULL; 2576 mname = name; 2577 } else { 2578 RUNTIME_CHECK(result == DNS_R_NXRRSET); 2579 if (dbuf != NULL) 2580 query_releasename(client, namep); 2581 } 2582 2583 if (rdataset->trust != dns_trust_secure && 2584 (section == DNS_SECTION_ANSWER || 2585 section == DNS_SECTION_AUTHORITY)) 2586 client->query.attributes &= ~NS_QUERYATTR_SECURE; 2587 /* 2588 * Note: we only add SIGs if we've added the type they cover, so 2589 * we do not need to check if the SIG rdataset is already in the 2590 * response. 2591 */ 2592 query_addrdataset(client, mname, rdataset); 2593 *rdatasetp = NULL; 2594 if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) { 2595 /* 2596 * We have a signature. Add it to the response. 2597 */ 2598 ISC_LIST_APPEND(mname->list, sigrdataset, link); 2599 *sigrdatasetp = NULL; 2600 } 2601 CTRACE("query_addrrset: done"); 2602 } 2603 2604 static inline isc_result_t 2605 query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, 2606 unsigned int override_ttl, isc_boolean_t isassociated, 2607 dns_section_t section) 2608 { 2609 dns_name_t *name; 2610 dns_dbnode_t *node; 2611 isc_result_t result, eresult; 2612 dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; 2613 dns_rdataset_t **sigrdatasetp = NULL; 2614 dns_clientinfomethods_t cm; 2615 dns_clientinfo_t ci; 2616 2617 CTRACE("query_addsoa"); 2618 /* 2619 * Initialization. 2620 */ 2621 eresult = ISC_R_SUCCESS; 2622 name = NULL; 2623 rdataset = NULL; 2624 node = NULL; 2625 2626 dns_clientinfomethods_init(&cm, ns_client_sourceip); 2627 dns_clientinfo_init(&ci, client); 2628 2629 /* 2630 * Don't add the SOA record for test which set "-T nosoa". 2631 */ 2632 if (ns_g_nosoa && (!WANTDNSSEC(client) || !isassociated)) 2633 return (ISC_R_SUCCESS); 2634 2635 /* 2636 * Get resources and make 'name' be the database origin. 2637 */ 2638 result = dns_message_gettempname(client->message, &name); 2639 if (result != ISC_R_SUCCESS) 2640 return (result); 2641 dns_name_init(name, NULL); 2642 dns_name_clone(dns_db_origin(db), name); 2643 rdataset = query_newrdataset(client); 2644 if (rdataset == NULL) { 2645 eresult = DNS_R_SERVFAIL; 2646 goto cleanup; 2647 } 2648 if (WANTDNSSEC(client) && dns_db_issecure(db)) { 2649 sigrdataset = query_newrdataset(client); 2650 if (sigrdataset == NULL) { 2651 eresult = DNS_R_SERVFAIL; 2652 goto cleanup; 2653 } 2654 } 2655 2656 /* 2657 * Find the SOA. 2658 */ 2659 result = dns_db_getoriginnode(db, &node); 2660 if (result == ISC_R_SUCCESS) { 2661 result = dns_db_findrdataset(db, node, version, 2662 dns_rdatatype_soa, 0, client->now, 2663 rdataset, sigrdataset); 2664 } else { 2665 dns_fixedname_t foundname; 2666 dns_name_t *fname; 2667 2668 dns_fixedname_init(&foundname); 2669 fname = dns_fixedname_name(&foundname); 2670 2671 result = dns_db_findext(db, name, version, dns_rdatatype_soa, 2672 client->query.dboptions, 0, &node, 2673 fname, &cm, &ci, rdataset, sigrdataset); 2674 } 2675 if (result != ISC_R_SUCCESS) { 2676 /* 2677 * This is bad. We tried to get the SOA RR at the zone top 2678 * and it didn't work! 2679 */ 2680 eresult = DNS_R_SERVFAIL; 2681 } else { 2682 /* 2683 * Extract the SOA MINIMUM. 2684 */ 2685 dns_rdata_soa_t soa; 2686 dns_rdata_t rdata = DNS_RDATA_INIT; 2687 result = dns_rdataset_first(rdataset); 2688 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2689 dns_rdataset_current(rdataset, &rdata); 2690 result = dns_rdata_tostruct(&rdata, &soa, NULL); 2691 if (result != ISC_R_SUCCESS) 2692 goto cleanup; 2693 2694 if (override_ttl != ISC_UINT32_MAX && 2695 override_ttl < rdataset->ttl) { 2696 rdataset->ttl = override_ttl; 2697 if (sigrdataset != NULL) 2698 sigrdataset->ttl = override_ttl; 2699 } 2700 2701 /* 2702 * Add the SOA and its SIG to the response, with the 2703 * TTLs adjusted per RFC2308 section 3. 2704 */ 2705 if (rdataset->ttl > soa.minimum) 2706 rdataset->ttl = soa.minimum; 2707 if (sigrdataset != NULL && sigrdataset->ttl > soa.minimum) 2708 sigrdataset->ttl = soa.minimum; 2709 2710 if (sigrdataset != NULL) 2711 sigrdatasetp = &sigrdataset; 2712 else 2713 sigrdatasetp = NULL; 2714 2715 if (section == DNS_SECTION_ADDITIONAL) 2716 rdataset->attributes |= DNS_RDATASETATTR_REQUIRED; 2717 query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL, 2718 section); 2719 } 2720 2721 cleanup: 2722 query_putrdataset(client, &rdataset); 2723 if (sigrdataset != NULL) 2724 query_putrdataset(client, &sigrdataset); 2725 if (name != NULL) 2726 query_releasename(client, &name); 2727 if (node != NULL) 2728 dns_db_detachnode(db, &node); 2729 2730 return (eresult); 2731 } 2732 2733 static inline isc_result_t 2734 query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) { 2735 dns_name_t *name, *fname; 2736 dns_dbnode_t *node; 2737 isc_result_t result, eresult; 2738 dns_fixedname_t foundname; 2739 dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; 2740 dns_rdataset_t **sigrdatasetp = NULL; 2741 dns_clientinfomethods_t cm; 2742 dns_clientinfo_t ci; 2743 2744 CTRACE("query_addns"); 2745 /* 2746 * Initialization. 2747 */ 2748 eresult = ISC_R_SUCCESS; 2749 name = NULL; 2750 rdataset = NULL; 2751 node = NULL; 2752 dns_fixedname_init(&foundname); 2753 fname = dns_fixedname_name(&foundname); 2754 dns_clientinfomethods_init(&cm, ns_client_sourceip); 2755 dns_clientinfo_init(&ci, client); 2756 2757 /* 2758 * Get resources and make 'name' be the database origin. 2759 */ 2760 result = dns_message_gettempname(client->message, &name); 2761 if (result != ISC_R_SUCCESS) { 2762 CTRACE("query_addns: dns_message_gettempname failed: done"); 2763 return (result); 2764 } 2765 dns_name_init(name, NULL); 2766 dns_name_clone(dns_db_origin(db), name); 2767 rdataset = query_newrdataset(client); 2768 if (rdataset == NULL) { 2769 CTRACE("query_addns: query_newrdataset failed"); 2770 eresult = DNS_R_SERVFAIL; 2771 goto cleanup; 2772 } 2773 if (WANTDNSSEC(client) && dns_db_issecure(db)) { 2774 sigrdataset = query_newrdataset(client); 2775 if (sigrdataset == NULL) { 2776 CTRACE("query_addns: query_newrdataset failed"); 2777 eresult = DNS_R_SERVFAIL; 2778 goto cleanup; 2779 } 2780 } 2781 2782 /* 2783 * Find the NS rdataset. 2784 */ 2785 result = dns_db_getoriginnode(db, &node); 2786 if (result == ISC_R_SUCCESS) { 2787 result = dns_db_findrdataset(db, node, version, 2788 dns_rdatatype_ns, 0, client->now, 2789 rdataset, sigrdataset); 2790 } else { 2791 CTRACE("query_addns: calling dns_db_find"); 2792 result = dns_db_findext(db, name, NULL, dns_rdatatype_ns, 2793 client->query.dboptions, 0, &node, 2794 fname, &cm, &ci, rdataset, sigrdataset); 2795 CTRACE("query_addns: dns_db_find complete"); 2796 } 2797 if (result != ISC_R_SUCCESS) { 2798 CTRACE("query_addns: " 2799 "dns_db_findrdataset or dns_db_find failed"); 2800 /* 2801 * This is bad. We tried to get the NS rdataset at the zone 2802 * top and it didn't work! 2803 */ 2804 eresult = DNS_R_SERVFAIL; 2805 } else { 2806 if (sigrdataset != NULL) 2807 sigrdatasetp = &sigrdataset; 2808 else 2809 sigrdatasetp = NULL; 2810 query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL, 2811 DNS_SECTION_AUTHORITY); 2812 } 2813 2814 cleanup: 2815 CTRACE("query_addns: cleanup"); 2816 query_putrdataset(client, &rdataset); 2817 if (sigrdataset != NULL) 2818 query_putrdataset(client, &sigrdataset); 2819 if (name != NULL) 2820 query_releasename(client, &name); 2821 if (node != NULL) 2822 dns_db_detachnode(db, &node); 2823 2824 CTRACE("query_addns: done"); 2825 return (eresult); 2826 } 2827 2828 static isc_result_t 2829 query_add_cname(ns_client_t *client, dns_name_t *qname, dns_name_t *tname, 2830 dns_trust_t trust, dns_ttl_t ttl) 2831 { 2832 dns_rdataset_t *rdataset; 2833 dns_rdatalist_t *rdatalist; 2834 dns_rdata_t *rdata; 2835 isc_region_t r; 2836 dns_name_t *aname; 2837 isc_result_t result; 2838 2839 /* 2840 * We assume the name data referred to by tname won't go away. 2841 */ 2842 2843 aname = NULL; 2844 result = dns_message_gettempname(client->message, &aname); 2845 if (result != ISC_R_SUCCESS) 2846 return (result); 2847 result = dns_name_dup(qname, client->mctx, aname); 2848 if (result != ISC_R_SUCCESS) { 2849 dns_message_puttempname(client->message, &aname); 2850 return (result); 2851 } 2852 2853 rdatalist = NULL; 2854 result = dns_message_gettemprdatalist(client->message, &rdatalist); 2855 if (result != ISC_R_SUCCESS) { 2856 dns_message_puttempname(client->message, &aname); 2857 return (result); 2858 } 2859 rdata = NULL; 2860 result = dns_message_gettemprdata(client->message, &rdata); 2861 if (result != ISC_R_SUCCESS) { 2862 dns_message_puttempname(client->message, &aname); 2863 dns_message_puttemprdatalist(client->message, &rdatalist); 2864 return (result); 2865 } 2866 rdataset = NULL; 2867 result = dns_message_gettemprdataset(client->message, &rdataset); 2868 if (result != ISC_R_SUCCESS) { 2869 dns_message_puttempname(client->message, &aname); 2870 dns_message_puttemprdatalist(client->message, &rdatalist); 2871 dns_message_puttemprdata(client->message, &rdata); 2872 return (result); 2873 } 2874 rdatalist->type = dns_rdatatype_cname; 2875 rdatalist->covers = 0; 2876 rdatalist->rdclass = client->message->rdclass; 2877 rdatalist->ttl = ttl; 2878 2879 dns_name_toregion(tname, &r); 2880 rdata->data = r.base; 2881 rdata->length = r.length; 2882 rdata->rdclass = client->message->rdclass; 2883 rdata->type = dns_rdatatype_cname; 2884 2885 ISC_LIST_INIT(rdatalist->rdata); 2886 ISC_LIST_APPEND(rdatalist->rdata, rdata, link); 2887 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) 2888 == ISC_R_SUCCESS); 2889 rdataset->trust = trust; 2890 2891 query_addrrset(client, &aname, &rdataset, NULL, NULL, 2892 DNS_SECTION_ANSWER); 2893 if (rdataset != NULL) { 2894 if (dns_rdataset_isassociated(rdataset)) 2895 dns_rdataset_disassociate(rdataset); 2896 dns_message_puttemprdataset(client->message, &rdataset); 2897 } 2898 if (aname != NULL) 2899 dns_message_puttempname(client->message, &aname); 2900 2901 return (ISC_R_SUCCESS); 2902 } 2903 2904 /* 2905 * Mark the RRsets as secure. Update the cache (db) to reflect the 2906 * change in trust level. 2907 */ 2908 static void 2909 mark_secure(ns_client_t *client, dns_db_t *db, dns_name_t *name, 2910 dns_rdata_rrsig_t *rrsig, dns_rdataset_t *rdataset, 2911 dns_rdataset_t *sigrdataset) 2912 { 2913 isc_result_t result; 2914 dns_dbnode_t *node = NULL; 2915 dns_clientinfomethods_t cm; 2916 dns_clientinfo_t ci; 2917 isc_stdtime_t now; 2918 2919 rdataset->trust = dns_trust_secure; 2920 sigrdataset->trust = dns_trust_secure; 2921 dns_clientinfomethods_init(&cm, ns_client_sourceip); 2922 dns_clientinfo_init(&ci, client); 2923 2924 /* 2925 * Save the updated secure state. Ignore failures. 2926 */ 2927 result = dns_db_findnodeext(db, name, ISC_TRUE, &cm, &ci, &node); 2928 if (result != ISC_R_SUCCESS) 2929 return; 2930 2931 isc_stdtime_get(&now); 2932 dns_rdataset_trimttl(rdataset, sigrdataset, rrsig, now, 2933 client->view->acceptexpired); 2934 2935 (void)dns_db_addrdataset(db, node, NULL, client->now, rdataset, 2936 0, NULL); 2937 (void)dns_db_addrdataset(db, node, NULL, client->now, sigrdataset, 2938 0, NULL); 2939 dns_db_detachnode(db, &node); 2940 } 2941 2942 /* 2943 * Find the secure key that corresponds to rrsig. 2944 * Note: 'keyrdataset' maintains state between successive calls, 2945 * there may be multiple keys with the same keyid. 2946 * Return ISC_FALSE if we have exhausted all the possible keys. 2947 */ 2948 static isc_boolean_t 2949 get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig, 2950 dns_rdataset_t *keyrdataset, dst_key_t **keyp) 2951 { 2952 isc_result_t result; 2953 dns_dbnode_t *node = NULL; 2954 isc_boolean_t secure = ISC_FALSE; 2955 dns_clientinfomethods_t cm; 2956 dns_clientinfo_t ci; 2957 2958 dns_clientinfomethods_init(&cm, ns_client_sourceip); 2959 dns_clientinfo_init(&ci, client); 2960 2961 if (!dns_rdataset_isassociated(keyrdataset)) { 2962 result = dns_db_findnodeext(db, &rrsig->signer, ISC_FALSE, 2963 &cm, &ci, &node); 2964 if (result != ISC_R_SUCCESS) 2965 return (ISC_FALSE); 2966 2967 result = dns_db_findrdataset(db, node, NULL, 2968 dns_rdatatype_dnskey, 0, 2969 client->now, keyrdataset, NULL); 2970 dns_db_detachnode(db, &node); 2971 if (result != ISC_R_SUCCESS) 2972 return (ISC_FALSE); 2973 2974 if (keyrdataset->trust != dns_trust_secure) 2975 return (ISC_FALSE); 2976 2977 result = dns_rdataset_first(keyrdataset); 2978 } else 2979 result = dns_rdataset_next(keyrdataset); 2980 2981 for ( ; result == ISC_R_SUCCESS; 2982 result = dns_rdataset_next(keyrdataset)) { 2983 dns_rdata_t rdata = DNS_RDATA_INIT; 2984 isc_buffer_t b; 2985 2986 dns_rdataset_current(keyrdataset, &rdata); 2987 isc_buffer_init(&b, rdata.data, rdata.length); 2988 isc_buffer_add(&b, rdata.length); 2989 result = dst_key_fromdns(&rrsig->signer, rdata.rdclass, &b, 2990 client->mctx, keyp); 2991 if (result != ISC_R_SUCCESS) 2992 continue; 2993 if (rrsig->algorithm == (dns_secalg_t)dst_key_alg(*keyp) && 2994 rrsig->keyid == (dns_keytag_t)dst_key_id(*keyp) && 2995 dst_key_iszonekey(*keyp)) { 2996 secure = ISC_TRUE; 2997 break; 2998 } 2999 dst_key_free(keyp); 3000 } 3001 return (secure); 3002 } 3003 3004 static isc_boolean_t 3005 verify(dst_key_t *key, dns_name_t *name, dns_rdataset_t *rdataset, 3006 dns_rdata_t *rdata, ns_client_t *client) 3007 { 3008 isc_result_t result; 3009 dns_fixedname_t fixed; 3010 isc_boolean_t ignore = ISC_FALSE; 3011 3012 dns_fixedname_init(&fixed); 3013 3014 again: 3015 result = dns_dnssec_verify3(name, rdataset, key, ignore, 3016 client->view->maxbits, client->mctx, 3017 rdata, NULL); 3018 if (result == DNS_R_SIGEXPIRED && client->view->acceptexpired) { 3019 ignore = ISC_TRUE; 3020 goto again; 3021 } 3022 if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) 3023 return (ISC_TRUE); 3024 return (ISC_FALSE); 3025 } 3026 3027 /* 3028 * Validate the rdataset if possible with available records. 3029 */ 3030 static isc_boolean_t 3031 validate(ns_client_t *client, dns_db_t *db, dns_name_t *name, 3032 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 3033 { 3034 isc_result_t result; 3035 dns_rdata_t rdata = DNS_RDATA_INIT; 3036 dns_rdata_rrsig_t rrsig; 3037 dst_key_t *key = NULL; 3038 dns_rdataset_t keyrdataset; 3039 3040 if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset)) 3041 return (ISC_FALSE); 3042 3043 for (result = dns_rdataset_first(sigrdataset); 3044 result == ISC_R_SUCCESS; 3045 result = dns_rdataset_next(sigrdataset)) { 3046 3047 dns_rdata_reset(&rdata); 3048 dns_rdataset_current(sigrdataset, &rdata); 3049 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 3050 if (result != ISC_R_SUCCESS) 3051 return (ISC_FALSE); 3052 if (!dns_resolver_algorithm_supported(client->view->resolver, 3053 name, rrsig.algorithm)) 3054 continue; 3055 if (!dns_name_issubdomain(name, &rrsig.signer)) 3056 continue; 3057 dns_rdataset_init(&keyrdataset); 3058 do { 3059 if (!get_key(client, db, &rrsig, &keyrdataset, &key)) 3060 break; 3061 if (verify(key, name, rdataset, &rdata, client)) { 3062 dst_key_free(&key); 3063 dns_rdataset_disassociate(&keyrdataset); 3064 mark_secure(client, db, name, &rrsig, 3065 rdataset, sigrdataset); 3066 return (ISC_TRUE); 3067 } 3068 dst_key_free(&key); 3069 } while (1); 3070 if (dns_rdataset_isassociated(&keyrdataset)) 3071 dns_rdataset_disassociate(&keyrdataset); 3072 } 3073 return (ISC_FALSE); 3074 } 3075 3076 static void 3077 query_addbestns(ns_client_t *client) { 3078 dns_db_t *db, *zdb; 3079 dns_dbnode_t *node; 3080 dns_name_t *fname, *zfname; 3081 dns_rdataset_t *rdataset, *sigrdataset, *zrdataset, *zsigrdataset; 3082 isc_boolean_t is_zone, use_zone; 3083 isc_buffer_t *dbuf; 3084 isc_result_t result; 3085 dns_dbversion_t *version; 3086 dns_zone_t *zone; 3087 isc_buffer_t b; 3088 dns_clientinfomethods_t cm; 3089 dns_clientinfo_t ci; 3090 3091 CTRACE("query_addbestns"); 3092 fname = NULL; 3093 zfname = NULL; 3094 rdataset = NULL; 3095 zrdataset = NULL; 3096 sigrdataset = NULL; 3097 zsigrdataset = NULL; 3098 node = NULL; 3099 db = NULL; 3100 zdb = NULL; 3101 version = NULL; 3102 zone = NULL; 3103 is_zone = ISC_FALSE; 3104 use_zone = ISC_FALSE; 3105 3106 dns_clientinfomethods_init(&cm, ns_client_sourceip); 3107 dns_clientinfo_init(&ci, client); 3108 3109 /* 3110 * Find the right database. 3111 */ 3112 result = query_getdb(client, client->query.qname, dns_rdatatype_ns, 0, 3113 &zone, &db, &version, &is_zone); 3114 if (result != ISC_R_SUCCESS) 3115 goto cleanup; 3116 3117 db_find: 3118 /* 3119 * We'll need some resources... 3120 */ 3121 dbuf = query_getnamebuf(client); 3122 if (dbuf == NULL) 3123 goto cleanup; 3124 fname = query_newname(client, dbuf, &b); 3125 rdataset = query_newrdataset(client); 3126 if (fname == NULL || rdataset == NULL) 3127 goto cleanup; 3128 /* 3129 * Get the RRSIGs if the client requested them or if we may 3130 * need to validate answers from the cache. 3131 */ 3132 if (WANTDNSSEC(client) || !is_zone) { 3133 sigrdataset = query_newrdataset(client); 3134 if (sigrdataset == NULL) 3135 goto cleanup; 3136 } 3137 3138 /* 3139 * Now look for the zonecut. 3140 */ 3141 if (is_zone) { 3142 result = dns_db_findext(db, client->query.qname, version, 3143 dns_rdatatype_ns, 3144 client->query.dboptions, 3145 client->now, &node, fname, 3146 &cm, &ci, rdataset, sigrdataset); 3147 if (result != DNS_R_DELEGATION) 3148 goto cleanup; 3149 if (USECACHE(client)) { 3150 query_keepname(client, fname, dbuf); 3151 zdb = db; 3152 zfname = fname; 3153 fname = NULL; 3154 zrdataset = rdataset; 3155 rdataset = NULL; 3156 zsigrdataset = sigrdataset; 3157 sigrdataset = NULL; 3158 dns_db_detachnode(db, &node); 3159 version = NULL; 3160 db = NULL; 3161 dns_db_attach(client->view->cachedb, &db); 3162 is_zone = ISC_FALSE; 3163 goto db_find; 3164 } 3165 } else { 3166 result = dns_db_findzonecut(db, client->query.qname, 3167 client->query.dboptions, 3168 client->now, &node, fname, 3169 rdataset, sigrdataset); 3170 if (result == ISC_R_SUCCESS) { 3171 if (zfname != NULL && 3172 !dns_name_issubdomain(fname, zfname)) { 3173 /* 3174 * We found a zonecut in the cache, but our 3175 * zone delegation is better. 3176 */ 3177 use_zone = ISC_TRUE; 3178 } 3179 } else if (result == ISC_R_NOTFOUND && zfname != NULL) { 3180 /* 3181 * We didn't find anything in the cache, but we 3182 * have a zone delegation, so use it. 3183 */ 3184 use_zone = ISC_TRUE; 3185 } else 3186 goto cleanup; 3187 } 3188 3189 if (use_zone) { 3190 query_releasename(client, &fname); 3191 fname = zfname; 3192 zfname = NULL; 3193 /* 3194 * We've already done query_keepname() on 3195 * zfname, so we must set dbuf to NULL to 3196 * prevent query_addrrset() from trying to 3197 * call query_keepname() again. 3198 */ 3199 dbuf = NULL; 3200 query_putrdataset(client, &rdataset); 3201 if (sigrdataset != NULL) 3202 query_putrdataset(client, &sigrdataset); 3203 rdataset = zrdataset; 3204 zrdataset = NULL; 3205 sigrdataset = zsigrdataset; 3206 zsigrdataset = NULL; 3207 } 3208 3209 /* 3210 * Attempt to validate RRsets that are pending or that are glue. 3211 */ 3212 if ((DNS_TRUST_PENDING(rdataset->trust) || 3213 (sigrdataset != NULL && DNS_TRUST_PENDING(sigrdataset->trust))) 3214 && !validate(client, db, fname, rdataset, sigrdataset) && 3215 !PENDINGOK(client->query.dboptions)) 3216 goto cleanup; 3217 3218 if ((DNS_TRUST_GLUE(rdataset->trust) || 3219 (sigrdataset != NULL && DNS_TRUST_GLUE(sigrdataset->trust))) && 3220 !validate(client, db, fname, rdataset, sigrdataset) && 3221 SECURE(client) && WANTDNSSEC(client)) 3222 goto cleanup; 3223 3224 /* 3225 * If the answer is secure only add NS records if they are secure * when the client may be looking for AD in the response. 3226 */ 3227 if (SECURE(client) && (WANTDNSSEC(client) || WANTAD(client)) && 3228 ((rdataset->trust != dns_trust_secure) || 3229 (sigrdataset != NULL && sigrdataset->trust != dns_trust_secure))) 3230 goto cleanup; 3231 3232 /* 3233 * If the client doesn't want DNSSEC we can discard the sigrdataset 3234 * now. 3235 */ 3236 if (!WANTDNSSEC(client)) 3237 query_putrdataset(client, &sigrdataset); 3238 query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf, 3239 DNS_SECTION_AUTHORITY); 3240 3241 cleanup: 3242 if (rdataset != NULL) 3243 query_putrdataset(client, &rdataset); 3244 if (sigrdataset != NULL) 3245 query_putrdataset(client, &sigrdataset); 3246 if (fname != NULL) 3247 query_releasename(client, &fname); 3248 if (node != NULL) 3249 dns_db_detachnode(db, &node); 3250 if (db != NULL) 3251 dns_db_detach(&db); 3252 if (zone != NULL) 3253 dns_zone_detach(&zone); 3254 if (zdb != NULL) { 3255 query_putrdataset(client, &zrdataset); 3256 if (zsigrdataset != NULL) 3257 query_putrdataset(client, &zsigrdataset); 3258 if (zfname != NULL) 3259 query_releasename(client, &zfname); 3260 dns_db_detach(&zdb); 3261 } 3262 } 3263 3264 static void 3265 fixrdataset(ns_client_t *client, dns_rdataset_t **rdataset) { 3266 if (*rdataset == NULL) 3267 *rdataset = query_newrdataset(client); 3268 else if (dns_rdataset_isassociated(*rdataset)) 3269 dns_rdataset_disassociate(*rdataset); 3270 } 3271 3272 static void 3273 fixfname(ns_client_t *client, dns_name_t **fname, isc_buffer_t **dbuf, 3274 isc_buffer_t *nbuf) 3275 { 3276 if (*fname == NULL) { 3277 *dbuf = query_getnamebuf(client); 3278 if (*dbuf == NULL) 3279 return; 3280 *fname = query_newname(client, *dbuf, nbuf); 3281 } 3282 } 3283 3284 static void 3285 query_addds(ns_client_t *client, dns_db_t *db, dns_dbnode_t *node, 3286 dns_dbversion_t *version, dns_name_t *name) 3287 { 3288 dns_fixedname_t fixed; 3289 dns_name_t *fname = NULL; 3290 dns_name_t *rname; 3291 dns_rdataset_t *rdataset, *sigrdataset; 3292 isc_buffer_t *dbuf, b; 3293 isc_result_t result; 3294 unsigned int count; 3295 3296 CTRACE("query_addds"); 3297 rname = NULL; 3298 rdataset = NULL; 3299 sigrdataset = NULL; 3300 3301 /* 3302 * We'll need some resources... 3303 */ 3304 rdataset = query_newrdataset(client); 3305 sigrdataset = query_newrdataset(client); 3306 if (rdataset == NULL || sigrdataset == NULL) 3307 goto cleanup; 3308 3309 /* 3310 * Look for the DS record, which may or may not be present. 3311 */ 3312 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ds, 0, 3313 client->now, rdataset, sigrdataset); 3314 /* 3315 * If we didn't find it, look for an NSEC. 3316 */ 3317 if (result == ISC_R_NOTFOUND) 3318 result = dns_db_findrdataset(db, node, version, 3319 dns_rdatatype_nsec, 0, client->now, 3320 rdataset, sigrdataset); 3321 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) 3322 goto addnsec3; 3323 if (!dns_rdataset_isassociated(rdataset) || 3324 !dns_rdataset_isassociated(sigrdataset)) 3325 goto addnsec3; 3326 3327 /* 3328 * We've already added the NS record, so if the name's not there, 3329 * we have other problems. Use this name rather than calling 3330 * query_addrrset(). 3331 */ 3332 result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY); 3333 if (result != ISC_R_SUCCESS) 3334 goto cleanup; 3335 3336 rname = NULL; 3337 dns_message_currentname(client->message, DNS_SECTION_AUTHORITY, 3338 &rname); 3339 result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL); 3340 if (result != ISC_R_SUCCESS) 3341 goto cleanup; 3342 3343 ISC_LIST_APPEND(rname->list, rdataset, link); 3344 ISC_LIST_APPEND(rname->list, sigrdataset, link); 3345 rdataset = NULL; 3346 sigrdataset = NULL; 3347 return; 3348 3349 addnsec3: 3350 if (!dns_db_iszone(db)) 3351 goto cleanup; 3352 /* 3353 * Add the NSEC3 which proves the DS does not exist. 3354 */ 3355 dbuf = query_getnamebuf(client); 3356 if (dbuf == NULL) 3357 goto cleanup; 3358 fname = query_newname(client, dbuf, &b); 3359 dns_fixedname_init(&fixed); 3360 if (dns_rdataset_isassociated(rdataset)) 3361 dns_rdataset_disassociate(rdataset); 3362 if (dns_rdataset_isassociated(sigrdataset)) 3363 dns_rdataset_disassociate(sigrdataset); 3364 query_findclosestnsec3(name, db, version, client, rdataset, 3365 sigrdataset, fname, ISC_TRUE, 3366 dns_fixedname_name(&fixed)); 3367 if (!dns_rdataset_isassociated(rdataset)) 3368 goto cleanup; 3369 query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf, 3370 DNS_SECTION_AUTHORITY); 3371 /* 3372 * Did we find the closest provable encloser instead? 3373 * If so add the nearest to the closest provable encloser. 3374 */ 3375 if (!dns_name_equal(name, dns_fixedname_name(&fixed))) { 3376 count = dns_name_countlabels(dns_fixedname_name(&fixed)) + 1; 3377 dns_name_getlabelsequence(name, 3378 dns_name_countlabels(name) - count, 3379 count, dns_fixedname_name(&fixed)); 3380 fixfname(client, &fname, &dbuf, &b); 3381 fixrdataset(client, &rdataset); 3382 fixrdataset(client, &sigrdataset); 3383 if (fname == NULL || rdataset == NULL || sigrdataset == NULL) 3384 goto cleanup; 3385 query_findclosestnsec3(dns_fixedname_name(&fixed), db, version, 3386 client, rdataset, sigrdataset, fname, 3387 ISC_FALSE, NULL); 3388 if (!dns_rdataset_isassociated(rdataset)) 3389 goto cleanup; 3390 query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf, 3391 DNS_SECTION_AUTHORITY); 3392 } 3393 3394 cleanup: 3395 if (rdataset != NULL) 3396 query_putrdataset(client, &rdataset); 3397 if (sigrdataset != NULL) 3398 query_putrdataset(client, &sigrdataset); 3399 if (fname != NULL) 3400 query_releasename(client, &fname); 3401 } 3402 3403 static void 3404 query_addwildcardproof(ns_client_t *client, dns_db_t *db, 3405 dns_dbversion_t *version, dns_name_t *name, 3406 isc_boolean_t ispositive, isc_boolean_t nodata) 3407 { 3408 isc_buffer_t *dbuf, b; 3409 dns_name_t *fname; 3410 dns_rdataset_t *rdataset, *sigrdataset; 3411 dns_fixedname_t wfixed; 3412 dns_name_t *wname; 3413 dns_dbnode_t *node; 3414 unsigned int options; 3415 unsigned int olabels, nlabels, labels; 3416 isc_result_t result; 3417 dns_rdata_t rdata = DNS_RDATA_INIT; 3418 dns_rdata_nsec_t nsec; 3419 isc_boolean_t have_wname; 3420 int order; 3421 dns_fixedname_t cfixed; 3422 dns_name_t *cname; 3423 dns_clientinfomethods_t cm; 3424 dns_clientinfo_t ci; 3425 3426 CTRACE("query_addwildcardproof"); 3427 fname = NULL; 3428 rdataset = NULL; 3429 sigrdataset = NULL; 3430 node = NULL; 3431 3432 dns_clientinfomethods_init(&cm, ns_client_sourceip); 3433 dns_clientinfo_init(&ci, client); 3434 3435 /* 3436 * Get the NOQNAME proof then if !ispositive 3437 * get the NOWILDCARD proof. 3438 * 3439 * DNS_DBFIND_NOWILD finds the NSEC records that covers the 3440 * name ignoring any wildcard. From the owner and next names 3441 * of this record you can compute which wildcard (if it exists) 3442 * will match by finding the longest common suffix of the 3443 * owner name and next names with the qname and prefixing that 3444 * with the wildcard label. 3445 * 3446 * e.g. 3447 * Given: 3448 * example SOA 3449 * example NSEC b.example 3450 * b.example A 3451 * b.example NSEC a.d.example 3452 * a.d.example A 3453 * a.d.example NSEC g.f.example 3454 * g.f.example A 3455 * g.f.example NSEC z.i.example 3456 * z.i.example A 3457 * z.i.example NSEC example 3458 * 3459 * QNAME: 3460 * a.example -> example NSEC b.example 3461 * owner common example 3462 * next common example 3463 * wild *.example 3464 * d.b.example -> b.example NSEC a.d.example 3465 * owner common b.example 3466 * next common example 3467 * wild *.b.example 3468 * a.f.example -> a.d.example NSEC g.f.example 3469 * owner common example 3470 * next common f.example 3471 * wild *.f.example 3472 * j.example -> z.i.example NSEC example 3473 * owner common example 3474 * next common example 3475 * wild *.example 3476 */ 3477 options = client->query.dboptions | DNS_DBFIND_NOWILD; 3478 dns_fixedname_init(&wfixed); 3479 wname = dns_fixedname_name(&wfixed); 3480 again: 3481 have_wname = ISC_FALSE; 3482 /* 3483 * We'll need some resources... 3484 */ 3485 dbuf = query_getnamebuf(client); 3486 if (dbuf == NULL) 3487 goto cleanup; 3488 fname = query_newname(client, dbuf, &b); 3489 rdataset = query_newrdataset(client); 3490 sigrdataset = query_newrdataset(client); 3491 if (fname == NULL || rdataset == NULL || sigrdataset == NULL) 3492 goto cleanup; 3493 3494 result = dns_db_findext(db, name, version, dns_rdatatype_nsec, 3495 options, 0, &node, fname, &cm, &ci, 3496 rdataset, sigrdataset); 3497 if (node != NULL) 3498 dns_db_detachnode(db, &node); 3499 3500 if (!dns_rdataset_isassociated(rdataset)) { 3501 /* 3502 * No NSEC proof available, return NSEC3 proofs instead. 3503 */ 3504 dns_fixedname_init(&cfixed); 3505 cname = dns_fixedname_name(&cfixed); 3506 /* 3507 * Find the closest encloser. 3508 */ 3509 dns_name_copy(name, cname, NULL); 3510 while (result == DNS_R_NXDOMAIN) { 3511 labels = dns_name_countlabels(cname) - 1; 3512 /* 3513 * Sanity check. 3514 */ 3515 if (labels == 0U) 3516 goto cleanup; 3517 dns_name_split(cname, labels, NULL, cname); 3518 result = dns_db_findext(db, cname, version, 3519 dns_rdatatype_nsec, 3520 options, 0, NULL, fname, 3521 &cm, &ci, NULL, NULL); 3522 } 3523 /* 3524 * Add closest (provable) encloser NSEC3. 3525 */ 3526 query_findclosestnsec3(cname, db, NULL, client, rdataset, 3527 sigrdataset, fname, ISC_TRUE, cname); 3528 if (!dns_rdataset_isassociated(rdataset)) 3529 goto cleanup; 3530 if (!ispositive) 3531 query_addrrset(client, &fname, &rdataset, &sigrdataset, 3532 dbuf, DNS_SECTION_AUTHORITY); 3533 3534 /* 3535 * Replace resources which were consumed by query_addrrset. 3536 */ 3537 if (fname == NULL) { 3538 dbuf = query_getnamebuf(client); 3539 if (dbuf == NULL) 3540 goto cleanup; 3541 fname = query_newname(client, dbuf, &b); 3542 } 3543 3544 if (rdataset == NULL) 3545 rdataset = query_newrdataset(client); 3546 else if (dns_rdataset_isassociated(rdataset)) 3547 dns_rdataset_disassociate(rdataset); 3548 3549 if (sigrdataset == NULL) 3550 sigrdataset = query_newrdataset(client); 3551 else if (dns_rdataset_isassociated(sigrdataset)) 3552 dns_rdataset_disassociate(sigrdataset); 3553 3554 if (fname == NULL || rdataset == NULL || sigrdataset == NULL) 3555 goto cleanup; 3556 /* 3557 * Add no qname proof. 3558 */ 3559 labels = dns_name_countlabels(cname) + 1; 3560 if (dns_name_countlabels(name) == labels) 3561 dns_name_copy(name, wname, NULL); 3562 else 3563 dns_name_split(name, labels, NULL, wname); 3564 3565 query_findclosestnsec3(wname, db, NULL, client, rdataset, 3566 sigrdataset, fname, ISC_FALSE, NULL); 3567 if (!dns_rdataset_isassociated(rdataset)) 3568 goto cleanup; 3569 query_addrrset(client, &fname, &rdataset, &sigrdataset, 3570 dbuf, DNS_SECTION_AUTHORITY); 3571 3572 if (ispositive) 3573 goto cleanup; 3574 3575 /* 3576 * Replace resources which were consumed by query_addrrset. 3577 */ 3578 if (fname == NULL) { 3579 dbuf = query_getnamebuf(client); 3580 if (dbuf == NULL) 3581 goto cleanup; 3582 fname = query_newname(client, dbuf, &b); 3583 } 3584 3585 if (rdataset == NULL) 3586 rdataset = query_newrdataset(client); 3587 else if (dns_rdataset_isassociated(rdataset)) 3588 dns_rdataset_disassociate(rdataset); 3589 3590 if (sigrdataset == NULL) 3591 sigrdataset = query_newrdataset(client); 3592 else if (dns_rdataset_isassociated(sigrdataset)) 3593 dns_rdataset_disassociate(sigrdataset); 3594 3595 if (fname == NULL || rdataset == NULL || sigrdataset == NULL) 3596 goto cleanup; 3597 /* 3598 * Add the no wildcard proof. 3599 */ 3600 result = dns_name_concatenate(dns_wildcardname, 3601 cname, wname, NULL); 3602 if (result != ISC_R_SUCCESS) 3603 goto cleanup; 3604 3605 query_findclosestnsec3(wname, db, NULL, client, rdataset, 3606 sigrdataset, fname, nodata, NULL); 3607 if (!dns_rdataset_isassociated(rdataset)) 3608 goto cleanup; 3609 query_addrrset(client, &fname, &rdataset, &sigrdataset, 3610 dbuf, DNS_SECTION_AUTHORITY); 3611 3612 goto cleanup; 3613 } else if (result == DNS_R_NXDOMAIN) { 3614 if (!ispositive) 3615 result = dns_rdataset_first(rdataset); 3616 if (result == ISC_R_SUCCESS) { 3617 dns_rdataset_current(rdataset, &rdata); 3618 result = dns_rdata_tostruct(&rdata, &nsec, NULL); 3619 } 3620 if (result == ISC_R_SUCCESS) { 3621 (void)dns_name_fullcompare(name, fname, &order, 3622 &olabels); 3623 (void)dns_name_fullcompare(name, &nsec.next, &order, 3624 &nlabels); 3625 /* 3626 * Check for a pathological condition created when 3627 * serving some malformed signed zones and bail out. 3628 */ 3629 if (dns_name_countlabels(name) == nlabels) 3630 goto cleanup; 3631 3632 if (olabels > nlabels) 3633 dns_name_split(name, olabels, NULL, wname); 3634 else 3635 dns_name_split(name, nlabels, NULL, wname); 3636 result = dns_name_concatenate(dns_wildcardname, 3637 wname, wname, NULL); 3638 if (result == ISC_R_SUCCESS) 3639 have_wname = ISC_TRUE; 3640 dns_rdata_freestruct(&nsec); 3641 } 3642 query_addrrset(client, &fname, &rdataset, &sigrdataset, 3643 dbuf, DNS_SECTION_AUTHORITY); 3644 } 3645 if (rdataset != NULL) 3646 query_putrdataset(client, &rdataset); 3647 if (sigrdataset != NULL) 3648 query_putrdataset(client, &sigrdataset); 3649 if (fname != NULL) 3650 query_releasename(client, &fname); 3651 if (have_wname) { 3652 ispositive = ISC_TRUE; /* prevent loop */ 3653 if (!dns_name_equal(name, wname)) { 3654 name = wname; 3655 goto again; 3656 } 3657 } 3658 cleanup: 3659 if (rdataset != NULL) 3660 query_putrdataset(client, &rdataset); 3661 if (sigrdataset != NULL) 3662 query_putrdataset(client, &sigrdataset); 3663 if (fname != NULL) 3664 query_releasename(client, &fname); 3665 } 3666 3667 static void 3668 query_addnxrrsetnsec(ns_client_t *client, dns_db_t *db, 3669 dns_dbversion_t *version, dns_name_t **namep, 3670 dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp) 3671 { 3672 dns_name_t *name; 3673 dns_rdataset_t *sigrdataset; 3674 dns_rdata_t sigrdata; 3675 dns_rdata_rrsig_t sig; 3676 unsigned int labels; 3677 isc_buffer_t *dbuf, b; 3678 dns_name_t *fname; 3679 isc_result_t result; 3680 3681 name = *namep; 3682 if ((name->attributes & DNS_NAMEATTR_WILDCARD) == 0) { 3683 query_addrrset(client, namep, rdatasetp, sigrdatasetp, 3684 NULL, DNS_SECTION_AUTHORITY); 3685 return; 3686 } 3687 3688 if (sigrdatasetp == NULL) 3689 return; 3690 3691 sigrdataset = *sigrdatasetp; 3692 if (sigrdataset == NULL || !dns_rdataset_isassociated(sigrdataset)) 3693 return; 3694 result = dns_rdataset_first(sigrdataset); 3695 if (result != ISC_R_SUCCESS) 3696 return; 3697 dns_rdata_init(&sigrdata); 3698 dns_rdataset_current(sigrdataset, &sigrdata); 3699 result = dns_rdata_tostruct(&sigrdata, &sig, NULL); 3700 if (result != ISC_R_SUCCESS) 3701 return; 3702 3703 labels = dns_name_countlabels(name); 3704 if ((unsigned int)sig.labels + 1 >= labels) 3705 return; 3706 3707 /* XXX */ 3708 query_addwildcardproof(client, db, version, client->query.qname, 3709 ISC_TRUE, ISC_FALSE); 3710 3711 /* 3712 * We'll need some resources... 3713 */ 3714 dbuf = query_getnamebuf(client); 3715 if (dbuf == NULL) 3716 return; 3717 fname = query_newname(client, dbuf, &b); 3718 if (fname == NULL) 3719 return; 3720 dns_name_split(name, sig.labels + 1, NULL, fname); 3721 /* This will succeed, since we've stripped labels. */ 3722 RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname, fname, fname, 3723 NULL) == ISC_R_SUCCESS); 3724 query_addrrset(client, &fname, rdatasetp, sigrdatasetp, 3725 dbuf, DNS_SECTION_AUTHORITY); 3726 } 3727 3728 static void 3729 query_resume(isc_task_t *task, isc_event_t *event) { 3730 dns_fetchevent_t *devent = (dns_fetchevent_t *)event; 3731 dns_fetch_t *fetch; 3732 ns_client_t *client; 3733 isc_boolean_t fetch_canceled, client_shuttingdown; 3734 isc_result_t result; 3735 isc_logcategory_t *logcategory = NS_LOGCATEGORY_QUERY_EERRORS; 3736 int errorloglevel; 3737 3738 /* 3739 * Resume a query after recursion. 3740 */ 3741 3742 UNUSED(task); 3743 3744 REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); 3745 client = devent->ev_arg; 3746 REQUIRE(NS_CLIENT_VALID(client)); 3747 REQUIRE(task == client->task); 3748 REQUIRE(RECURSING(client)); 3749 3750 LOCK(&client->query.fetchlock); 3751 if (client->query.fetch != NULL) { 3752 /* 3753 * This is the fetch we've been waiting for. 3754 */ 3755 INSIST(devent->fetch == client->query.fetch); 3756 client->query.fetch = NULL; 3757 fetch_canceled = ISC_FALSE; 3758 /* 3759 * Update client->now. 3760 */ 3761 isc_stdtime_get(&client->now); 3762 } else { 3763 /* 3764 * This is a fetch completion event for a canceled fetch. 3765 * Clean up and don't resume the find. 3766 */ 3767 fetch_canceled = ISC_TRUE; 3768 } 3769 UNLOCK(&client->query.fetchlock); 3770 INSIST(client->query.fetch == NULL); 3771 3772 client->query.attributes &= ~NS_QUERYATTR_RECURSING; 3773 fetch = devent->fetch; 3774 devent->fetch = NULL; 3775 3776 /* 3777 * If this client is shutting down, or this transaction 3778 * has timed out, do not resume the find. 3779 */ 3780 client_shuttingdown = ns_client_shuttingdown(client); 3781 if (fetch_canceled || client_shuttingdown) { 3782 if (devent->node != NULL) 3783 dns_db_detachnode(devent->db, &devent->node); 3784 if (devent->db != NULL) 3785 dns_db_detach(&devent->db); 3786 query_putrdataset(client, &devent->rdataset); 3787 if (devent->sigrdataset != NULL) 3788 query_putrdataset(client, &devent->sigrdataset); 3789 isc_event_free(&event); 3790 if (fetch_canceled) 3791 query_error(client, DNS_R_SERVFAIL, __LINE__); 3792 else 3793 query_next(client, ISC_R_CANCELED); 3794 /* 3795 * This may destroy the client. 3796 */ 3797 ns_client_detach(&client); 3798 } else { 3799 result = query_find(client, devent, 0); 3800 if (result != ISC_R_SUCCESS) { 3801 if (result == DNS_R_SERVFAIL) 3802 errorloglevel = ISC_LOG_DEBUG(2); 3803 else 3804 errorloglevel = ISC_LOG_DEBUG(4); 3805 if (isc_log_wouldlog(ns_g_lctx, errorloglevel)) { 3806 dns_resolver_logfetch(fetch, ns_g_lctx, 3807 logcategory, 3808 NS_LOGMODULE_QUERY, 3809 errorloglevel, ISC_FALSE); 3810 } 3811 } 3812 } 3813 3814 dns_resolver_destroyfetch(&fetch); 3815 } 3816 3817 static void 3818 prefetch_done(isc_task_t *task, isc_event_t *event) { 3819 dns_fetchevent_t *devent = (dns_fetchevent_t *)event; 3820 ns_client_t *client; 3821 3822 UNUSED(task); 3823 3824 REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); 3825 client = devent->ev_arg; 3826 REQUIRE(NS_CLIENT_VALID(client)); 3827 REQUIRE(task == client->task); 3828 3829 LOCK(&client->query.fetchlock); 3830 if (client->query.prefetch != NULL) { 3831 INSIST(devent->fetch == client->query.prefetch); 3832 client->query.prefetch = NULL; 3833 } 3834 UNLOCK(&client->query.fetchlock); 3835 if (devent->fetch != NULL) 3836 dns_resolver_destroyfetch(&devent->fetch); 3837 if (devent->node != NULL) 3838 dns_db_detachnode(devent->db, &devent->node); 3839 if (devent->db != NULL) 3840 dns_db_detach(&devent->db); 3841 query_putrdataset(client, &devent->rdataset); 3842 isc_event_free(&event); 3843 ns_client_detach(&client); 3844 } 3845 3846 static void 3847 query_prefetch(ns_client_t *client, dns_name_t *qname, 3848 dns_rdataset_t *rdataset) 3849 { 3850 isc_result_t result; 3851 isc_sockaddr_t *peeraddr; 3852 dns_rdataset_t *tmprdataset; 3853 ns_client_t *dummy = NULL; 3854 unsigned int options; 3855 3856 if (client->query.prefetch != NULL || 3857 client->view->prefetch_trigger == 0U || 3858 rdataset->ttl > client->view->prefetch_trigger || 3859 (rdataset->attributes & DNS_RDATASETATTR_PREFETCH) == 0) 3860 return; 3861 3862 if (client->recursionquota == NULL) { 3863 result = isc_quota_attach(&ns_g_server->recursionquota, 3864 &client->recursionquota); 3865 if (result != ISC_R_SUCCESS) 3866 return; 3867 isc_stats_increment(ns_g_server->nsstats, 3868 dns_nsstatscounter_recursclients); 3869 } 3870 3871 tmprdataset = query_newrdataset(client); 3872 if (tmprdataset == NULL) 3873 return; 3874 if ((client->attributes & NS_CLIENTATTR_TCP) == 0) 3875 peeraddr = &client->peeraddr; 3876 else 3877 peeraddr = NULL; 3878 ns_client_attach(client, &dummy); 3879 options = client->query.fetchoptions | DNS_FETCHOPT_PREFETCH; 3880 result = dns_resolver_createfetch3(client->view->resolver, 3881 qname, rdataset->type, NULL, NULL, 3882 NULL, peeraddr, client->message->id, 3883 options, 0, NULL, client->task, 3884 prefetch_done, client, 3885 tmprdataset, NULL, 3886 &client->query.prefetch); 3887 if (result != ISC_R_SUCCESS) { 3888 query_putrdataset(client, &tmprdataset); 3889 ns_client_detach(&dummy); 3890 } 3891 dns_rdataset_clearprefetch(rdataset); 3892 } 3893 3894 static isc_result_t 3895 query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, 3896 dns_name_t *qdomain, dns_rdataset_t *nameservers, 3897 isc_boolean_t resuming) 3898 { 3899 isc_result_t result; 3900 dns_rdataset_t *rdataset, *sigrdataset; 3901 isc_sockaddr_t *peeraddr; 3902 3903 if (!resuming) 3904 inc_stats(client, dns_nsstatscounter_recursion); 3905 3906 /* 3907 * We are about to recurse, which means that this client will 3908 * be unavailable for serving new requests for an indeterminate 3909 * amount of time. If this client is currently responsible 3910 * for handling incoming queries, set up a new client 3911 * object to handle them while we are waiting for a 3912 * response. There is no need to replace TCP clients 3913 * because those have already been replaced when the 3914 * connection was accepted (if allowed by the TCP quota). 3915 */ 3916 if (client->recursionquota == NULL) { 3917 result = isc_quota_attach(&ns_g_server->recursionquota, 3918 &client->recursionquota); 3919 3920 isc_stats_increment(ns_g_server->nsstats, 3921 dns_nsstatscounter_recursclients); 3922 3923 if (result == ISC_R_SOFTQUOTA) { 3924 static isc_stdtime_t last = 0; 3925 isc_stdtime_t now; 3926 isc_stdtime_get(&now); 3927 if (now != last) { 3928 last = now; 3929 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 3930 NS_LOGMODULE_QUERY, 3931 ISC_LOG_WARNING, 3932 "recursive-clients soft limit " 3933 "exceeded (%d/%d/%d), " 3934 "aborting oldest query", 3935 client->recursionquota->used, 3936 client->recursionquota->soft, 3937 client->recursionquota->max); 3938 } 3939 ns_client_killoldestquery(client); 3940 result = ISC_R_SUCCESS; 3941 } else if (result == ISC_R_QUOTA) { 3942 static isc_stdtime_t last = 0; 3943 isc_stdtime_t now; 3944 isc_stdtime_get(&now); 3945 if (now != last) { 3946 last = now; 3947 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 3948 NS_LOGMODULE_QUERY, 3949 ISC_LOG_WARNING, 3950 "no more recursive clients " 3951 "(%d/%d/%d): %s", 3952 ns_g_server->recursionquota.used, 3953 ns_g_server->recursionquota.soft, 3954 ns_g_server->recursionquota.max, 3955 isc_result_totext(result)); 3956 } 3957 ns_client_killoldestquery(client); 3958 } 3959 if (result == ISC_R_SUCCESS && !client->mortal && 3960 (client->attributes & NS_CLIENTATTR_TCP) == 0) { 3961 result = ns_client_replace(client); 3962 if (result != ISC_R_SUCCESS) { 3963 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 3964 NS_LOGMODULE_QUERY, 3965 ISC_LOG_WARNING, 3966 "ns_client_replace() failed: %s", 3967 isc_result_totext(result)); 3968 isc_quota_detach(&client->recursionquota); 3969 isc_stats_decrement(ns_g_server->nsstats, 3970 dns_nsstatscounter_recursclients); 3971 } 3972 } 3973 if (result != ISC_R_SUCCESS) 3974 return (result); 3975 ns_client_recursing(client); 3976 } 3977 3978 /* 3979 * Invoke the resolver. 3980 */ 3981 REQUIRE(nameservers == NULL || nameservers->type == dns_rdatatype_ns); 3982 REQUIRE(client->query.fetch == NULL); 3983 3984 rdataset = query_newrdataset(client); 3985 if (rdataset == NULL) 3986 return (ISC_R_NOMEMORY); 3987 if (WANTDNSSEC(client)) { 3988 sigrdataset = query_newrdataset(client); 3989 if (sigrdataset == NULL) { 3990 query_putrdataset(client, &rdataset); 3991 return (ISC_R_NOMEMORY); 3992 } 3993 } else 3994 sigrdataset = NULL; 3995 3996 if (client->query.timerset == ISC_FALSE) 3997 ns_client_settimeout(client, 60); 3998 if ((client->attributes & NS_CLIENTATTR_TCP) == 0) 3999 peeraddr = &client->peeraddr; 4000 else 4001 peeraddr = NULL; 4002 result = dns_resolver_createfetch3(client->view->resolver, 4003 qname, qtype, qdomain, nameservers, 4004 NULL, peeraddr, client->message->id, 4005 client->query.fetchoptions, 0, NULL, 4006 client->task, query_resume, client, 4007 rdataset, sigrdataset, 4008 &client->query.fetch); 4009 4010 if (result == ISC_R_SUCCESS) { 4011 /* 4012 * Record that we're waiting for an event. A client which 4013 * is shutting down will not be destroyed until all the 4014 * events have been received. 4015 */ 4016 } else { 4017 query_putrdataset(client, &rdataset); 4018 if (sigrdataset != NULL) 4019 query_putrdataset(client, &sigrdataset); 4020 } 4021 4022 return (result); 4023 } 4024 4025 static inline void 4026 rpz_clean(dns_zone_t **zonep, dns_db_t **dbp, dns_dbnode_t **nodep, 4027 dns_rdataset_t **rdatasetp) 4028 { 4029 if (nodep != NULL && *nodep != NULL) { 4030 REQUIRE(dbp != NULL && *dbp != NULL); 4031 dns_db_detachnode(*dbp, nodep); 4032 } 4033 if (dbp != NULL && *dbp != NULL) 4034 dns_db_detach(dbp); 4035 if (zonep != NULL && *zonep != NULL) 4036 dns_zone_detach(zonep); 4037 if (rdatasetp != NULL && *rdatasetp != NULL && 4038 dns_rdataset_isassociated(*rdatasetp)) 4039 dns_rdataset_disassociate(*rdatasetp); 4040 } 4041 4042 static inline void 4043 rpz_match_clear(dns_rpz_st_t *st) { 4044 rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset); 4045 st->m.version = NULL; 4046 } 4047 4048 static inline isc_result_t 4049 rpz_ready(ns_client_t *client, dns_rdataset_t **rdatasetp) { 4050 REQUIRE(rdatasetp != NULL); 4051 4052 CTRACE("rpz_ready"); 4053 4054 if (*rdatasetp == NULL) { 4055 *rdatasetp = query_newrdataset(client); 4056 if (*rdatasetp == NULL) 4057 return (DNS_R_SERVFAIL); 4058 } else if (dns_rdataset_isassociated(*rdatasetp)) { 4059 dns_rdataset_disassociate(*rdatasetp); 4060 } 4061 return (ISC_R_SUCCESS); 4062 } 4063 4064 static void 4065 rpz_st_clear(ns_client_t *client) { 4066 dns_rpz_st_t *st = client->query.rpz_st; 4067 4068 CTRACE("rpz_st_clear"); 4069 4070 if (st->m.rdataset != NULL) 4071 query_putrdataset(client, &st->m.rdataset); 4072 rpz_match_clear(st); 4073 4074 rpz_clean(NULL, &st->r.db, NULL, NULL); 4075 if (st->r.ns_rdataset != NULL) 4076 query_putrdataset(client, &st->r.ns_rdataset); 4077 if (st->r.r_rdataset != NULL) 4078 query_putrdataset(client, &st->r.r_rdataset); 4079 4080 rpz_clean(&st->q.zone, &st->q.db, &st->q.node, NULL); 4081 if (st->q.rdataset != NULL) 4082 query_putrdataset(client, &st->q.rdataset); 4083 if (st->q.sigrdataset != NULL) 4084 query_putrdataset(client, &st->q.sigrdataset); 4085 st->state = 0; 4086 st->m.type = DNS_RPZ_TYPE_BAD; 4087 st->m.policy = DNS_RPZ_POLICY_MISS; 4088 } 4089 4090 static dns_rpz_zbits_t 4091 rpz_get_zbits(ns_client_t *client, 4092 dns_rdatatype_t ip_type, dns_rpz_type_t rpz_type) 4093 { 4094 dns_rpz_st_t *st; 4095 dns_rpz_zbits_t zbits; 4096 4097 REQUIRE(client != NULL); 4098 REQUIRE(client->query.rpz_st != NULL); 4099 4100 st = client->query.rpz_st; 4101 4102 switch (rpz_type) { 4103 case DNS_RPZ_TYPE_CLIENT_IP: 4104 zbits = st->have.client_ip; 4105 break; 4106 case DNS_RPZ_TYPE_QNAME: 4107 zbits = st->have.qname; 4108 break; 4109 case DNS_RPZ_TYPE_IP: 4110 if (ip_type == dns_rdatatype_a) { 4111 zbits = st->have.ipv4; 4112 } else if (ip_type == dns_rdatatype_aaaa) { 4113 zbits = st->have.ipv6; 4114 } else { 4115 zbits = st->have.ip; 4116 } 4117 break; 4118 case DNS_RPZ_TYPE_NSDNAME: 4119 zbits = st->have.nsdname; 4120 break; 4121 case DNS_RPZ_TYPE_NSIP: 4122 if (ip_type == dns_rdatatype_a) { 4123 zbits = st->have.nsipv4; 4124 } else if (ip_type == dns_rdatatype_aaaa) { 4125 zbits = st->have.nsipv6; 4126 } else { 4127 zbits = st->have.nsip; 4128 } 4129 break; 4130 default: 4131 INSIST(0); 4132 break; 4133 } 4134 4135 /* 4136 * Choose 4137 * the earliest configured policy zone (rpz->num) 4138 * QNAME over IP over NSDNAME over NSIP (rpz_type) 4139 * the smallest name, 4140 * the longest IP address prefix, 4141 * the lexically smallest address. 4142 */ 4143 if (st->m.policy != DNS_RPZ_POLICY_MISS) { 4144 if (st->m.type >= rpz_type) { 4145 zbits &= DNS_RPZ_ZMASK(st->m.rpz->num); 4146 } else{ 4147 zbits &= DNS_RPZ_ZMASK(st->m.rpz->num) >> 1; 4148 } 4149 } 4150 4151 /* 4152 * If the client wants recursion, allow only compatible policies. 4153 */ 4154 if (!RECURSIONOK(client)) 4155 zbits &= st->popt.no_rd_ok; 4156 4157 return (zbits); 4158 } 4159 4160 /* 4161 * Get an NS, A, or AAAA rrset related to the response for the client 4162 * to check the contents of that rrset for hits by eligible policy zones. 4163 */ 4164 static isc_result_t 4165 rpz_rrset_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, 4166 dns_rpz_type_t rpz_type, dns_db_t **dbp, dns_dbversion_t *version, 4167 dns_rdataset_t **rdatasetp, isc_boolean_t resuming) 4168 { 4169 dns_rpz_st_t *st; 4170 isc_boolean_t is_zone; 4171 dns_dbnode_t *node; 4172 dns_fixedname_t fixed; 4173 dns_name_t *found; 4174 isc_result_t result; 4175 dns_clientinfomethods_t cm; 4176 dns_clientinfo_t ci; 4177 4178 CTRACE("rpz_rrset_find"); 4179 4180 st = client->query.rpz_st; 4181 if ((st->state & DNS_RPZ_RECURSING) != 0) { 4182 INSIST(st->r.r_type == type); 4183 INSIST(dns_name_equal(name, st->r_name)); 4184 INSIST(*rdatasetp == NULL || 4185 !dns_rdataset_isassociated(*rdatasetp)); 4186 INSIST(*dbp == NULL); 4187 st->state &= ~DNS_RPZ_RECURSING; 4188 *dbp = st->r.db; 4189 st->r.db = NULL; 4190 if (*rdatasetp != NULL) 4191 query_putrdataset(client, rdatasetp); 4192 *rdatasetp = st->r.r_rdataset; 4193 st->r.r_rdataset = NULL; 4194 result = st->r.r_result; 4195 if (result == DNS_R_DELEGATION) { 4196 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name, 4197 rpz_type, " rpz_rrset_find(1)", result); 4198 st->m.policy = DNS_RPZ_POLICY_ERROR; 4199 result = DNS_R_SERVFAIL; 4200 } 4201 return (result); 4202 } 4203 4204 result = rpz_ready(client, rdatasetp); 4205 if (result != ISC_R_SUCCESS) { 4206 st->m.policy = DNS_RPZ_POLICY_ERROR; 4207 return (result); 4208 } 4209 if (*dbp != NULL) { 4210 is_zone = ISC_FALSE; 4211 } else { 4212 dns_zone_t *zone; 4213 4214 version = NULL; 4215 zone = NULL; 4216 result = query_getdb(client, name, type, 0, &zone, dbp, 4217 &version, &is_zone); 4218 if (result != ISC_R_SUCCESS) { 4219 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name, 4220 rpz_type, " rpz_rrset_find(2)", result); 4221 st->m.policy = DNS_RPZ_POLICY_ERROR; 4222 if (zone != NULL) 4223 dns_zone_detach(&zone); 4224 return (result); 4225 } 4226 if (zone != NULL) 4227 dns_zone_detach(&zone); 4228 } 4229 4230 node = NULL; 4231 dns_fixedname_init(&fixed); 4232 found = dns_fixedname_name(&fixed); 4233 dns_clientinfomethods_init(&cm, ns_client_sourceip); 4234 dns_clientinfo_init(&ci, client); 4235 result = dns_db_findext(*dbp, name, version, type, DNS_DBFIND_GLUEOK, 4236 client->now, &node, found, 4237 &cm, &ci, *rdatasetp, NULL); 4238 if (result == DNS_R_DELEGATION && is_zone && USECACHE(client)) { 4239 /* 4240 * Try the cache if we're authoritative for an 4241 * ancestor but not the domain itself. 4242 */ 4243 rpz_clean(NULL, dbp, &node, rdatasetp); 4244 version = NULL; 4245 dns_db_attach(client->view->cachedb, dbp); 4246 result = dns_db_findext(*dbp, name, version, dns_rdatatype_ns, 4247 0, client->now, &node, found, 4248 &cm, &ci, *rdatasetp, NULL); 4249 } 4250 rpz_clean(NULL, dbp, &node, NULL); 4251 if (result == DNS_R_DELEGATION) { 4252 rpz_clean(NULL, NULL, NULL, rdatasetp); 4253 /* 4254 * Recurse for NS rrset or A or AAAA rrset for an NS. 4255 * Do not recurse for addresses for the query name. 4256 */ 4257 if (rpz_type == DNS_RPZ_TYPE_IP) { 4258 result = DNS_R_NXRRSET; 4259 } else { 4260 dns_name_copy(name, st->r_name, NULL); 4261 result = query_recurse(client, type, st->r_name, 4262 NULL, NULL, resuming); 4263 if (result == ISC_R_SUCCESS) { 4264 st->state |= DNS_RPZ_RECURSING; 4265 result = DNS_R_DELEGATION; 4266 } 4267 } 4268 } 4269 return (result); 4270 } 4271 4272 /* 4273 * Compute a policy owner name, p_name, in a policy zone given the needed 4274 * policy type and the trigger name. 4275 */ 4276 static isc_result_t 4277 rpz_get_p_name(ns_client_t *client, dns_name_t *p_name, 4278 dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, 4279 dns_name_t *trig_name) 4280 { 4281 dns_offsets_t prefix_offsets; 4282 dns_name_t prefix, *suffix; 4283 unsigned int first, labels; 4284 isc_result_t result; 4285 4286 CTRACE("rpz_get_p_name"); 4287 4288 /* 4289 * The policy owner name consists of a suffix depending on the type 4290 * and policy zone and a prefix that is the longest possible string 4291 * from the trigger name that keesp the resulting policy owner name 4292 * from being too long. 4293 */ 4294 switch (rpz_type) { 4295 case DNS_RPZ_TYPE_CLIENT_IP: 4296 suffix = &rpz->client_ip; 4297 break; 4298 case DNS_RPZ_TYPE_QNAME: 4299 suffix = &rpz->origin; 4300 break; 4301 case DNS_RPZ_TYPE_IP: 4302 suffix = &rpz->ip; 4303 break; 4304 case DNS_RPZ_TYPE_NSDNAME: 4305 suffix = &rpz->nsdname; 4306 break; 4307 case DNS_RPZ_TYPE_NSIP: 4308 suffix = &rpz->nsip; 4309 break; 4310 default: 4311 INSIST(0); 4312 } 4313 4314 /* 4315 * Start with relative version of the full trigger name, 4316 * and trim enough allow the addition of the suffix. 4317 */ 4318 dns_name_init(&prefix, prefix_offsets); 4319 labels = dns_name_countlabels(trig_name); 4320 first = 0; 4321 for (;;) { 4322 dns_name_getlabelsequence(trig_name, first, labels-first-1, 4323 &prefix); 4324 result = dns_name_concatenate(&prefix, suffix, p_name, NULL); 4325 if (result == ISC_R_SUCCESS) 4326 break; 4327 INSIST(result == DNS_R_NAMETOOLONG); 4328 /* 4329 * Trim the trigger name until the combination is not too long. 4330 */ 4331 if (labels-first < 2) { 4332 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, suffix, 4333 rpz_type, " concatentate()", result); 4334 return (ISC_R_FAILURE); 4335 } 4336 /* 4337 * Complain once about trimming the trigger name. 4338 */ 4339 if (first == 0) { 4340 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, suffix, 4341 rpz_type, " concatentate()", result); 4342 } 4343 ++first; 4344 } 4345 return (ISC_R_SUCCESS); 4346 } 4347 4348 /* 4349 * Look in policy zone rpz for a policy of rpz_type by p_name. 4350 * The self-name (usually the client qname or an NS name) is compared with 4351 * the target of a CNAME policy for the old style passthru encoding. 4352 * If found, the policy is recorded in *zonep, *dbp, *versionp, *nodep, 4353 * *rdatasetp, and *policyp. 4354 * The target DNS type, qtype, chooses the best rdataset for *rdatasetp. 4355 * The caller must decide if the found policy is most suitable, including 4356 * better than a previously found policy. 4357 * If it is best, the caller records it in client->query.rpz_st->m. 4358 */ 4359 static isc_result_t 4360 rpz_find_p(ns_client_t *client, dns_name_t *self_name, dns_rdatatype_t qtype, 4361 dns_name_t *p_name, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, 4362 dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp, 4363 dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp, 4364 dns_rpz_policy_t *policyp) 4365 { 4366 dns_fixedname_t foundf; 4367 dns_name_t *found; 4368 isc_result_t result; 4369 dns_clientinfomethods_t cm; 4370 dns_clientinfo_t ci; 4371 4372 REQUIRE(nodep != NULL); 4373 4374 CTRACE("rpz_find_p"); 4375 4376 /* 4377 * Try to find either a CNAME or the type of record demanded by the 4378 * request from the policy zone. 4379 */ 4380 rpz_clean(zonep, dbp, nodep, rdatasetp); 4381 result = rpz_ready(client, rdatasetp); 4382 if (result != ISC_R_SUCCESS) 4383 return (DNS_R_SERVFAIL); 4384 *versionp = NULL; 4385 result = rpz_getdb(client, p_name, rpz_type, zonep, dbp, versionp); 4386 if (result != ISC_R_SUCCESS) 4387 return (DNS_R_NXDOMAIN); 4388 dns_fixedname_init(&foundf); 4389 found = dns_fixedname_name(&foundf); 4390 dns_clientinfomethods_init(&cm, ns_client_sourceip); 4391 dns_clientinfo_init(&ci, client); 4392 result = dns_db_findext(*dbp, p_name, *versionp, dns_rdatatype_any, 0, 4393 client->now, nodep, found, &cm, &ci, 4394 *rdatasetp, NULL); 4395 /* 4396 * Choose the best rdataset if we found something. 4397 */ 4398 if (result == ISC_R_SUCCESS) { 4399 dns_rdatasetiter_t *rdsiter; 4400 4401 rdsiter = NULL; 4402 result = dns_db_allrdatasets(*dbp, *nodep, *versionp, 0, 4403 &rdsiter); 4404 if (result != ISC_R_SUCCESS) { 4405 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, 4406 rpz_type, " allrdatasets()", result); 4407 return (DNS_R_SERVFAIL); 4408 } 4409 for (result = dns_rdatasetiter_first(rdsiter); 4410 result == ISC_R_SUCCESS; 4411 result = dns_rdatasetiter_next(rdsiter)) { 4412 dns_rdatasetiter_current(rdsiter, *rdatasetp); 4413 if ((*rdatasetp)->type == dns_rdatatype_cname || 4414 (*rdatasetp)->type == qtype) 4415 break; 4416 dns_rdataset_disassociate(*rdatasetp); 4417 } 4418 dns_rdatasetiter_destroy(&rdsiter); 4419 if (result != ISC_R_SUCCESS) { 4420 if (result != ISC_R_NOMORE) { 4421 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, 4422 p_name, rpz_type, 4423 " rdatasetiter", result); 4424 return (DNS_R_SERVFAIL); 4425 } 4426 /* 4427 * Ask again to get the right DNS_R_DNAME/NXRRSET/... 4428 * result if there is neither a CNAME nor target type. 4429 */ 4430 if (dns_rdataset_isassociated(*rdatasetp)) 4431 dns_rdataset_disassociate(*rdatasetp); 4432 dns_db_detachnode(*dbp, nodep); 4433 4434 if (qtype == dns_rdatatype_rrsig || 4435 qtype == dns_rdatatype_sig) 4436 result = DNS_R_NXRRSET; 4437 else 4438 result = dns_db_findext(*dbp, p_name, *versionp, 4439 qtype, 0, client->now, 4440 nodep, found, &cm, &ci, 4441 *rdatasetp, NULL); 4442 } 4443 } 4444 switch (result) { 4445 case ISC_R_SUCCESS: 4446 if ((*rdatasetp)->type != dns_rdatatype_cname) { 4447 *policyp = DNS_RPZ_POLICY_RECORD; 4448 } else { 4449 *policyp = dns_rpz_decode_cname(rpz, *rdatasetp, 4450 self_name); 4451 if ((*policyp == DNS_RPZ_POLICY_RECORD || 4452 *policyp == DNS_RPZ_POLICY_WILDCNAME) && 4453 qtype != dns_rdatatype_cname && 4454 qtype != dns_rdatatype_any) 4455 return (DNS_R_CNAME); 4456 } 4457 return (ISC_R_SUCCESS); 4458 case DNS_R_NXRRSET: 4459 *policyp = DNS_RPZ_POLICY_NODATA; 4460 return (result); 4461 case DNS_R_DNAME: 4462 /* 4463 * DNAME policy RRs have very few if any uses that are not 4464 * better served with simple wildcards. Making them work would 4465 * require complications to get the number of labels matched 4466 * in the name or the found name to the main DNS_R_DNAME case 4467 * in query_find(). The domain also does not appear in the 4468 * summary database at the right level, so this happens only 4469 * with a single policy zone when we have no summary database. 4470 * Treat it as a miss. 4471 */ 4472 case DNS_R_NXDOMAIN: 4473 case DNS_R_EMPTYNAME: 4474 return (DNS_R_NXDOMAIN); 4475 default: 4476 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, p_name, rpz_type, 4477 "", result); 4478 return (DNS_R_SERVFAIL); 4479 } 4480 } 4481 4482 static void 4483 rpz_save_p(dns_rpz_st_t *st, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, 4484 dns_rpz_policy_t policy, dns_name_t *p_name, dns_rpz_prefix_t prefix, 4485 isc_result_t result, dns_zone_t **zonep, dns_db_t **dbp, 4486 dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp, 4487 dns_dbversion_t *version) 4488 { 4489 dns_rdataset_t *trdataset; 4490 4491 rpz_match_clear(st); 4492 st->m.rpz = rpz; 4493 st->m.type = rpz_type; 4494 st->m.policy = policy; 4495 dns_name_copy(p_name, st->p_name, NULL); 4496 st->m.prefix = prefix; 4497 st->m.result = result; 4498 st->m.zone = *zonep; 4499 *zonep = NULL; 4500 st->m.db = *dbp; 4501 *dbp = NULL; 4502 st->m.node = *nodep; 4503 *nodep = NULL; 4504 if (*rdatasetp != NULL && dns_rdataset_isassociated(*rdatasetp)) { 4505 /* 4506 * Save the replacement rdataset from the policy 4507 * and make the previous replacement rdataset scratch. 4508 */ 4509 trdataset = st->m.rdataset; 4510 st->m.rdataset = *rdatasetp; 4511 *rdatasetp = trdataset; 4512 st->m.ttl = ISC_MIN(st->m.rdataset->ttl, rpz->max_policy_ttl); 4513 } else { 4514 st->m.ttl = ISC_MIN(DNS_RPZ_TTL_DEFAULT, rpz->max_policy_ttl); 4515 } 4516 st->m.version = version; 4517 } 4518 4519 /* 4520 * Check this address in every eligible policy zone. 4521 */ 4522 static isc_result_t 4523 rpz_rewrite_ip(ns_client_t *client, const isc_netaddr_t *netaddr, 4524 dns_rdatatype_t qtype, dns_rpz_type_t rpz_type, 4525 dns_rpz_zbits_t zbits, dns_rdataset_t **p_rdatasetp) 4526 { 4527 dns_rpz_zones_t *rpzs; 4528 dns_rpz_st_t *st; 4529 dns_rpz_zone_t *rpz; 4530 dns_rpz_prefix_t prefix; 4531 dns_rpz_num_t rpz_num; 4532 dns_fixedname_t ip_namef, p_namef; 4533 dns_name_t *ip_name, *p_name; 4534 dns_zone_t *p_zone; 4535 dns_db_t *p_db; 4536 dns_dbversion_t *p_version; 4537 dns_dbnode_t *p_node; 4538 dns_rpz_policy_t policy; 4539 isc_result_t result; 4540 4541 CTRACE("rpz_rewrite_ip"); 4542 4543 dns_fixedname_init(&ip_namef); 4544 ip_name = dns_fixedname_name(&ip_namef); 4545 4546 p_zone = NULL; 4547 p_db = NULL; 4548 p_node = NULL; 4549 4550 rpzs = client->view->rpzs; 4551 st = client->query.rpz_st; 4552 while (zbits != 0) { 4553 rpz_num = dns_rpz_find_ip(rpzs, rpz_type, zbits, netaddr, 4554 ip_name, &prefix); 4555 if (rpz_num == DNS_RPZ_INVALID_NUM) 4556 break; 4557 zbits &= (DNS_RPZ_ZMASK(rpz_num) >> 1); 4558 4559 /* 4560 * Do not try applying policy zones that cannot replace a 4561 * previously found policy zone. 4562 * Stop looking if the next best choice cannot 4563 * replace what we already have. 4564 */ 4565 rpz = rpzs->zones[rpz_num]; 4566 if (st->m.policy != DNS_RPZ_POLICY_MISS) { 4567 if (st->m.rpz->num < rpz->num) 4568 break; 4569 if (st->m.rpz->num == rpz->num && 4570 (st->m.type < rpz_type || 4571 st->m.prefix > prefix)) 4572 break; 4573 } 4574 4575 /* 4576 * Get the policy for a prefix at least as long 4577 * as the prefix of the entry we had before. 4578 */ 4579 dns_fixedname_init(&p_namef); 4580 p_name = dns_fixedname_name(&p_namef); 4581 result = rpz_get_p_name(client, p_name, rpz, rpz_type, ip_name); 4582 if (result != ISC_R_SUCCESS) 4583 continue; 4584 result = rpz_find_p(client, ip_name, qtype, 4585 p_name, rpz, rpz_type, 4586 &p_zone, &p_db, &p_version, &p_node, 4587 p_rdatasetp, &policy); 4588 switch (result) { 4589 case DNS_R_NXDOMAIN: 4590 /* 4591 * Continue after a policy record that is missing 4592 * contrary to the summary data. The summary 4593 * data can out of date during races with and among 4594 * policy zone updates. 4595 */ 4596 CTRACE("rpz_rewrite_ip: mismatched summary data; " 4597 "continuing"); 4598 continue; 4599 case DNS_R_SERVFAIL: 4600 rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp); 4601 st->m.policy = DNS_RPZ_POLICY_ERROR; 4602 return (DNS_R_SERVFAIL); 4603 default: 4604 /* 4605 * Forget this policy if it is not preferable 4606 * to the previously found policy. 4607 * If this policy is not good, then stop looking 4608 * because none of the later policy zones would work. 4609 * 4610 * With more than one applicable policy, prefer 4611 * the earliest configured policy, 4612 * client-IP over QNAME over IP over NSDNAME over NSIP, 4613 * the longest prefix 4614 * the lexically smallest address. 4615 * dns_rpz_find_ip() ensures st->m.rpz->num >= rpz->num. 4616 * We can compare new and current p_name because 4617 * both are of the same type and in the same zone. 4618 * The tests above eliminate other reasons to 4619 * reject this policy. If this policy can't work, 4620 * then neither can later zones. 4621 */ 4622 if (st->m.policy != DNS_RPZ_POLICY_MISS && 4623 rpz->num == st->m.rpz->num && 4624 (st->m.type == rpz_type && 4625 st->m.prefix == prefix && 4626 0 > dns_name_rdatacompare(st->p_name, p_name))) 4627 break; 4628 4629 /* 4630 * Stop checking after saving an enabled hit in this 4631 * policy zone. The radix tree in the policy zone 4632 * ensures that we found the longest match. 4633 */ 4634 if (rpz->policy != DNS_RPZ_POLICY_DISABLED) { 4635 CTRACE("rpz_rewrite_ip: rpz_save_p"); 4636 rpz_save_p(st, rpz, rpz_type, 4637 policy, p_name, prefix, result, 4638 &p_zone, &p_db, &p_node, 4639 p_rdatasetp, p_version); 4640 break; 4641 } 4642 4643 /* 4644 * Log DNS_RPZ_POLICY_DISABLED zones 4645 * and try the next eligible policy zone. 4646 */ 4647 rpz_log_rewrite(client, ISC_TRUE, policy, rpz_type, 4648 p_zone, p_name); 4649 } 4650 } 4651 4652 rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp); 4653 return (ISC_R_SUCCESS); 4654 } 4655 4656 /* 4657 * Check the IP addresses in the A or AAAA rrsets for name against 4658 * all eligible rpz_type (IP or NSIP) response policy rewrite rules. 4659 */ 4660 static isc_result_t 4661 rpz_rewrite_ip_rrset(ns_client_t *client, 4662 dns_name_t *name, dns_rdatatype_t qtype, 4663 dns_rpz_type_t rpz_type, dns_rdatatype_t ip_type, 4664 dns_db_t **ip_dbp, dns_dbversion_t *ip_version, 4665 dns_rdataset_t **ip_rdatasetp, 4666 dns_rdataset_t **p_rdatasetp, isc_boolean_t resuming) 4667 { 4668 dns_rpz_zbits_t zbits; 4669 isc_netaddr_t netaddr; 4670 struct in_addr ina; 4671 struct in6_addr in6a; 4672 isc_result_t result; 4673 4674 CTRACE("rpz_rewrite_ip_rrset"); 4675 4676 zbits = rpz_get_zbits(client, ip_type, rpz_type); 4677 if (zbits == 0) 4678 return (ISC_R_SUCCESS); 4679 4680 /* 4681 * Get the A or AAAA rdataset. 4682 */ 4683 result = rpz_rrset_find(client, name, ip_type, rpz_type, ip_dbp, 4684 ip_version, ip_rdatasetp, resuming); 4685 switch (result) { 4686 case ISC_R_SUCCESS: 4687 case DNS_R_GLUE: 4688 case DNS_R_ZONECUT: 4689 break; 4690 case DNS_R_EMPTYNAME: 4691 case DNS_R_EMPTYWILD: 4692 case DNS_R_NXDOMAIN: 4693 case DNS_R_NCACHENXDOMAIN: 4694 case DNS_R_NXRRSET: 4695 case DNS_R_NCACHENXRRSET: 4696 case ISC_R_NOTFOUND: 4697 return (ISC_R_SUCCESS); 4698 case DNS_R_DELEGATION: 4699 case DNS_R_DUPLICATE: 4700 case DNS_R_DROP: 4701 return (result); 4702 case DNS_R_CNAME: 4703 case DNS_R_DNAME: 4704 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, name, rpz_type, 4705 " NS address rewrite rrset", result); 4706 return (ISC_R_SUCCESS); 4707 default: 4708 if (client->query.rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) { 4709 client->query.rpz_st->m.policy = DNS_RPZ_POLICY_ERROR; 4710 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, name, 4711 rpz_type, " NS address rewrite rrset", 4712 result); 4713 } 4714 return (DNS_R_SERVFAIL); 4715 } 4716 4717 /* 4718 * Check all of the IP addresses in the rdataset. 4719 */ 4720 for (result = dns_rdataset_first(*ip_rdatasetp); 4721 result == ISC_R_SUCCESS; 4722 result = dns_rdataset_next(*ip_rdatasetp)) { 4723 4724 dns_rdata_t rdata = DNS_RDATA_INIT; 4725 dns_rdataset_current(*ip_rdatasetp, &rdata); 4726 switch (rdata.type) { 4727 case dns_rdatatype_a: 4728 INSIST(rdata.length == 4); 4729 memmove(&ina.s_addr, rdata.data, 4); 4730 isc_netaddr_fromin(&netaddr, &ina); 4731 break; 4732 case dns_rdatatype_aaaa: 4733 INSIST(rdata.length == 16); 4734 memmove(in6a.s6_addr, rdata.data, 16); 4735 isc_netaddr_fromin6(&netaddr, &in6a); 4736 break; 4737 default: 4738 continue; 4739 } 4740 4741 result = rpz_rewrite_ip(client, &netaddr, qtype, rpz_type, 4742 zbits, p_rdatasetp); 4743 if (result != ISC_R_SUCCESS) 4744 return (result); 4745 } 4746 4747 return (ISC_R_SUCCESS); 4748 } 4749 4750 /* 4751 * Look for IP addresses in A and AAAA rdatasets 4752 * that trigger all eligible IP or NSIP policy rules. 4753 */ 4754 static isc_result_t 4755 rpz_rewrite_ip_rrsets(ns_client_t *client, dns_name_t *name, 4756 dns_rdatatype_t qtype, dns_rpz_type_t rpz_type, 4757 dns_rdataset_t **ip_rdatasetp, isc_boolean_t resuming) 4758 { 4759 dns_rpz_st_t *st; 4760 dns_dbversion_t *ip_version; 4761 dns_db_t *ip_db; 4762 dns_rdataset_t *p_rdataset; 4763 isc_result_t result; 4764 4765 CTRACE("rpz_rewrite_ip_rrsets"); 4766 4767 st = client->query.rpz_st; 4768 ip_version = NULL; 4769 ip_db = NULL; 4770 p_rdataset = NULL; 4771 if ((st->state & DNS_RPZ_DONE_IPv4) == 0 && 4772 (qtype == dns_rdatatype_a || 4773 qtype == dns_rdatatype_any || 4774 rpz_type == DNS_RPZ_TYPE_NSIP)) { 4775 /* 4776 * Rewrite based on an IPv4 address that will appear 4777 * in the ANSWER section or if we are checking IP addresses. 4778 */ 4779 result = rpz_rewrite_ip_rrset(client, name, qtype, 4780 rpz_type, dns_rdatatype_a, 4781 &ip_db, ip_version, ip_rdatasetp, 4782 &p_rdataset, resuming); 4783 if (result == ISC_R_SUCCESS) 4784 st->state |= DNS_RPZ_DONE_IPv4; 4785 } else { 4786 result = ISC_R_SUCCESS; 4787 } 4788 if (result == ISC_R_SUCCESS && 4789 (qtype == dns_rdatatype_aaaa || 4790 qtype == dns_rdatatype_any || 4791 rpz_type == DNS_RPZ_TYPE_NSIP)) { 4792 /* 4793 * Rewrite based on IPv6 addresses that will appear 4794 * in the ANSWER section or if we are checking IP addresses. 4795 */ 4796 result = rpz_rewrite_ip_rrset(client, name, qtype, 4797 rpz_type, dns_rdatatype_aaaa, 4798 &ip_db, ip_version, ip_rdatasetp, 4799 &p_rdataset, resuming); 4800 } 4801 if (ip_db != NULL) 4802 dns_db_detach(&ip_db); 4803 query_putrdataset(client, &p_rdataset); 4804 return (result); 4805 } 4806 4807 /* 4808 * Try to rewrite a request for a qtype rdataset based on the trigger name 4809 * trig_name and rpz_type (DNS_RPZ_TYPE_QNAME or DNS_RPZ_TYPE_NSDNAME). 4810 * Record the results including the replacement rdataset if any 4811 * in client->query.rpz_st. 4812 * *rdatasetp is a scratch rdataset. 4813 */ 4814 static isc_result_t 4815 rpz_rewrite_name(ns_client_t *client, dns_name_t *trig_name, 4816 dns_rdatatype_t qtype, dns_rpz_type_t rpz_type, 4817 dns_rpz_zbits_t allowed_zbits, dns_rdataset_t **rdatasetp) 4818 { 4819 dns_rpz_zones_t *rpzs; 4820 dns_rpz_zone_t *rpz; 4821 dns_rpz_st_t *st; 4822 dns_fixedname_t p_namef; 4823 dns_name_t *p_name; 4824 dns_rpz_zbits_t zbits; 4825 dns_rpz_num_t rpz_num; 4826 dns_zone_t *p_zone; 4827 dns_db_t *p_db; 4828 dns_dbversion_t *p_version; 4829 dns_dbnode_t *p_node; 4830 dns_rpz_policy_t policy; 4831 isc_result_t result; 4832 4833 CTRACE("rpz_rewrite_name"); 4834 4835 zbits = rpz_get_zbits(client, qtype, rpz_type); 4836 zbits &= allowed_zbits; 4837 if (zbits == 0) 4838 return (ISC_R_SUCCESS); 4839 4840 rpzs = client->view->rpzs; 4841 4842 /* 4843 * If there is only one eligible policy zone, just check it. 4844 * If more than one, then use the summary database to find 4845 * the bit mask of policy zones with policies for this trigger name. 4846 * x&(~x+1) is the least significant bit set in x 4847 */ 4848 if (zbits != (zbits & (~zbits + 1))) { 4849 zbits = dns_rpz_find_name(rpzs, rpz_type, zbits, trig_name); 4850 if (zbits == 0) 4851 return (ISC_R_SUCCESS); 4852 } 4853 4854 dns_fixedname_init(&p_namef); 4855 p_name = dns_fixedname_name(&p_namef); 4856 4857 p_zone = NULL; 4858 p_db = NULL; 4859 p_node = NULL; 4860 4861 st = client->query.rpz_st; 4862 4863 /* 4864 * Check the trigger name in every policy zone that the summary data 4865 * says has a hit for the trigger name. 4866 * Most of the time there are no eligible zones and the summary data 4867 * keeps us from getting this far. 4868 * We check the most eligible zone first and so usually check only 4869 * one policy zone. 4870 */ 4871 for (rpz_num = 0; zbits != 0; ++rpz_num, zbits >>= 1) { 4872 if ((zbits & 1) == 0) 4873 continue; 4874 4875 /* 4876 * Do not check policy zones that cannot replace a previously 4877 * found policy. 4878 */ 4879 rpz = rpzs->zones[rpz_num]; 4880 if (st->m.policy != DNS_RPZ_POLICY_MISS) { 4881 if (st->m.rpz->num < rpz->num) 4882 break; 4883 if (st->m.rpz->num == rpz->num && 4884 st->m.type < rpz_type) 4885 break; 4886 } 4887 4888 /* 4889 * Get the next policy zone's record for this trigger name. 4890 */ 4891 result = rpz_get_p_name(client, p_name, rpz, rpz_type, 4892 trig_name); 4893 if (result != ISC_R_SUCCESS) 4894 continue; 4895 result = rpz_find_p(client, trig_name, qtype, p_name, 4896 rpz, rpz_type, 4897 &p_zone, &p_db, &p_version, &p_node, 4898 rdatasetp, &policy); 4899 switch (result) { 4900 case DNS_R_NXDOMAIN: 4901 /* 4902 * Continue after a missing policy record 4903 * contrary to the summary data. The summary 4904 * data can out of date during races with and among 4905 * policy zone updates. 4906 */ 4907 CTRACE("rpz_rewrite_name: mismatched summary data; " 4908 "continuing"); 4909 continue; 4910 case DNS_R_SERVFAIL: 4911 rpz_clean(&p_zone, &p_db, &p_node, rdatasetp); 4912 st->m.policy = DNS_RPZ_POLICY_ERROR; 4913 return (DNS_R_SERVFAIL); 4914 default: 4915 /* 4916 * With more than one applicable policy, prefer 4917 * the earliest configured policy, 4918 * client-IP over QNAME over IP over NSDNAME over NSIP, 4919 * and the smallest name. 4920 * We known st->m.rpz->num >= rpz->num and either 4921 * st->m.rpz->num > rpz->num or st->m.type >= rpz_type 4922 */ 4923 if (st->m.policy != DNS_RPZ_POLICY_MISS && 4924 rpz->num == st->m.rpz->num && 4925 (st->m.type < rpz_type || 4926 (st->m.type == rpz_type && 4927 0 >= dns_name_compare(p_name, st->p_name)))) 4928 continue; 4929 #if 0 4930 /* 4931 * This code would block a customer reported information 4932 * leak of rpz rules by rewriting requests in the 4933 * rpz-ip, rpz-nsip, rpz-nsdname,and rpz-passthru TLDs. 4934 * Without this code, a bad guy could request 4935 * 24.0.3.2.10.rpz-ip. to find the policy rule for 4936 * 10.2.3.0/14. It is an insignificant leak and this 4937 * code is not worth its cost, because the bad guy 4938 * could publish "evil.com A 10.2.3.4" and request 4939 * evil.com to get the same information. 4940 * Keep code with "#if 0" in case customer demand 4941 * is irresistible. 4942 * 4943 * We have the less frequent case of a triggered 4944 * policy. Check that we have not trigger on one 4945 * of the pretend RPZ TLDs. 4946 * This test would make it impossible to rewrite 4947 * names in TLDs that start with "rpz-" should 4948 * ICANN ever allow such TLDs. 4949 */ 4950 unsigned int labels; 4951 labels = dns_name_countlabels(trig_name); 4952 if (labels >= 2) { 4953 dns_label_t label; 4954 4955 dns_name_getlabel(trig_name, labels-2, &label); 4956 if (label.length >= sizeof(DNS_RPZ_PREFIX)-1 && 4957 strncasecmp((const char *)label.base+1, 4958 DNS_RPZ_PREFIX, 4959 sizeof(DNS_RPZ_PREFIX)-1) == 0) 4960 continue; 4961 } 4962 #endif 4963 if (rpz->policy != DNS_RPZ_POLICY_DISABLED) { 4964 CTRACE("rpz_rewrite_name: rpz_save_p"); 4965 rpz_save_p(st, rpz, rpz_type, 4966 policy, p_name, 0, result, 4967 &p_zone, &p_db, &p_node, 4968 rdatasetp, p_version); 4969 /* 4970 * After a hit, higher numbered policy zones 4971 * are irrelevant 4972 */ 4973 rpz_clean(&p_zone, &p_db, &p_node, rdatasetp); 4974 return (ISC_R_SUCCESS); 4975 } 4976 /* 4977 * Log DNS_RPZ_POLICY_DISABLED zones 4978 * and try the next eligible policy zone. 4979 */ 4980 rpz_log_rewrite(client, ISC_TRUE, policy, rpz_type, 4981 p_zone, p_name); 4982 break; 4983 } 4984 } 4985 4986 rpz_clean(&p_zone, &p_db, &p_node, rdatasetp); 4987 return (ISC_R_SUCCESS); 4988 } 4989 4990 static void 4991 rpz_rewrite_ns_skip(ns_client_t *client, dns_name_t *nsname, 4992 isc_result_t result, int level, const char *str) 4993 { 4994 dns_rpz_st_t *st; 4995 4996 CTRACE("rpz_rewrite_ns_skip"); 4997 4998 st = client->query.rpz_st; 4999 5000 if (str != NULL) 5001 rpz_log_fail(client, level, nsname, DNS_RPZ_TYPE_NSIP, 5002 str, result); 5003 if (st->r.ns_rdataset != NULL && 5004 dns_rdataset_isassociated(st->r.ns_rdataset)) 5005 dns_rdataset_disassociate(st->r.ns_rdataset); 5006 5007 st->r.label--; 5008 } 5009 5010 /* 5011 * Look for response policy zone QNAME, NSIP, and NSDNAME rewriting. 5012 */ 5013 static isc_result_t 5014 rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, 5015 isc_result_t qresult, isc_boolean_t resuming, 5016 dns_rdataset_t *ordataset, dns_rdataset_t *osigset) 5017 { 5018 dns_rpz_zones_t *rpzs; 5019 dns_rpz_st_t *st; 5020 dns_rdataset_t *rdataset; 5021 dns_fixedname_t nsnamef; 5022 dns_name_t *nsname; 5023 int qresult_type; 5024 dns_rpz_zbits_t zbits; 5025 isc_result_t result = ISC_R_SUCCESS; 5026 dns_rpz_have_t have; 5027 dns_rpz_popt_t popt; 5028 int rpz_ver; 5029 5030 CTRACE("rpz_rewrite"); 5031 5032 rpzs = client->view->rpzs; 5033 st = client->query.rpz_st; 5034 5035 if (rpzs == NULL || 5036 (st != NULL && (st->state & DNS_RPZ_REWRITTEN) != 0)) 5037 return (DNS_R_DISALLOWED); 5038 5039 RWLOCK(&rpzs->search_lock, isc_rwlocktype_read); 5040 if (rpzs->p.num_zones == 0 || 5041 (!RECURSIONOK(client) && rpzs->p.no_rd_ok == 0) || 5042 !rpz_ck_dnssec(client, qresult, ordataset, osigset)) 5043 { 5044 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); 5045 return (DNS_R_DISALLOWED); 5046 } 5047 have = rpzs->have; 5048 popt = rpzs->p; 5049 rpz_ver = rpzs->rpz_ver; 5050 RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); 5051 5052 if (st == NULL) { 5053 st = isc_mem_get(client->mctx, sizeof(*st)); 5054 if (st == NULL) 5055 return (ISC_R_NOMEMORY); 5056 st->state = 0; 5057 } 5058 if (st->state == 0) { 5059 st->state |= DNS_RPZ_ACTIVE; 5060 memset(&st->m, 0, sizeof(st->m)); 5061 st->m.type = DNS_RPZ_TYPE_BAD; 5062 st->m.policy = DNS_RPZ_POLICY_MISS; 5063 st->m.ttl = ~0; 5064 memset(&st->r, 0, sizeof(st->r)); 5065 memset(&st->q, 0, sizeof(st->q)); 5066 dns_fixedname_init(&st->_p_namef); 5067 dns_fixedname_init(&st->_r_namef); 5068 dns_fixedname_init(&st->_fnamef); 5069 st->p_name = dns_fixedname_name(&st->_p_namef); 5070 st->r_name = dns_fixedname_name(&st->_r_namef); 5071 st->fname = dns_fixedname_name(&st->_fnamef); 5072 st->have = have; 5073 st->popt = popt; 5074 st->rpz_ver = rpz_ver; 5075 client->query.rpz_st = st; 5076 } 5077 5078 /* 5079 * There is nothing to rewrite if the main query failed. 5080 */ 5081 switch (qresult) { 5082 case ISC_R_SUCCESS: 5083 case DNS_R_GLUE: 5084 case DNS_R_ZONECUT: 5085 qresult_type = 0; 5086 break; 5087 case DNS_R_EMPTYNAME: 5088 case DNS_R_NXRRSET: 5089 case DNS_R_NXDOMAIN: 5090 case DNS_R_EMPTYWILD: 5091 case DNS_R_NCACHENXDOMAIN: 5092 case DNS_R_NCACHENXRRSET: 5093 case DNS_R_CNAME: 5094 case DNS_R_DNAME: 5095 qresult_type = 1; 5096 break; 5097 case DNS_R_DELEGATION: 5098 case ISC_R_NOTFOUND: 5099 /* 5100 * If recursion is on, do only tentative rewriting. 5101 * If recursion is off, this the normal and only time we 5102 * can rewrite. 5103 */ 5104 if (RECURSIONOK(client)) 5105 qresult_type = 2; 5106 else 5107 qresult_type = 1; 5108 break; 5109 case ISC_R_FAILURE: 5110 case ISC_R_TIMEDOUT: 5111 case DNS_R_BROKENCHAIN: 5112 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL3, client->query.qname, 5113 DNS_RPZ_TYPE_QNAME, 5114 " stop on qresult in rpz_rewrite()", qresult); 5115 return (ISC_R_SUCCESS); 5116 default: 5117 rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, client->query.qname, 5118 DNS_RPZ_TYPE_QNAME, 5119 " stop on unrecognized qresult in rpz_rewrite()", 5120 qresult); 5121 return (ISC_R_SUCCESS); 5122 } 5123 5124 rdataset = NULL; 5125 5126 if ((st->state & (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) != 5127 (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) { 5128 isc_netaddr_t netaddr; 5129 dns_rpz_zbits_t allowed; 5130 5131 if (qresult_type == 2) { 5132 /* 5133 * This request needs recursion that has not been done. 5134 * Get bits for the policy zones that do not need 5135 * to wait for the results of recursion. 5136 */ 5137 allowed = st->have.qname_skip_recurse; 5138 if (allowed == 0) 5139 return (ISC_R_SUCCESS); 5140 } else { 5141 allowed = DNS_RPZ_ALL_ZBITS; 5142 } 5143 5144 /* 5145 * Check once for triggers for the client IP address. 5146 */ 5147 if ((st->state & DNS_RPZ_DONE_CLIENT_IP) == 0) { 5148 zbits = rpz_get_zbits(client, dns_rdatatype_none, 5149 DNS_RPZ_TYPE_CLIENT_IP); 5150 zbits &= allowed; 5151 if (zbits != 0) { 5152 isc_netaddr_fromsockaddr(&netaddr, 5153 &client->peeraddr); 5154 result = rpz_rewrite_ip(client, &netaddr, qtype, 5155 DNS_RPZ_TYPE_CLIENT_IP, 5156 zbits, &rdataset); 5157 if (result != ISC_R_SUCCESS) 5158 goto cleanup; 5159 } 5160 } 5161 5162 /* 5163 * Check triggers for the query name if this is the first time 5164 * for the current qname. 5165 * There is a first time for each name in a CNAME chain 5166 */ 5167 if ((st->state & DNS_RPZ_DONE_QNAME) == 0) { 5168 result = rpz_rewrite_name(client, client->query.qname, 5169 qtype, DNS_RPZ_TYPE_QNAME, 5170 allowed, &rdataset); 5171 if (result != ISC_R_SUCCESS) 5172 goto cleanup; 5173 5174 /* 5175 * Check IPv4 addresses in A RRs next. 5176 * Reset to the start of the NS names. 5177 */ 5178 st->r.label = dns_name_countlabels(client->query.qname); 5179 st->state &= ~(DNS_RPZ_DONE_QNAME_IP | 5180 DNS_RPZ_DONE_IPv4); 5181 5182 } 5183 5184 /* 5185 * Quit if this was an attempt to find a qname or 5186 * client-IP trigger before recursion. 5187 * We will be back if no pre-recursion triggers hit. 5188 * For example, consider 2 policy zones, both with qname and 5189 * IP address triggers. If the qname misses the 1st zone, 5190 * then we cannot know whether a hit for the qname in the 5191 * 2nd zone matters until after recursing to get the A RRs and 5192 * testing them in the first zone. 5193 * Do not bother saving the work from this attempt, 5194 * because recusion is so slow. 5195 */ 5196 if (qresult_type == 2) 5197 goto cleanup; 5198 5199 /* 5200 * DNS_RPZ_DONE_QNAME but not DNS_RPZ_DONE_CLIENT_IP 5201 * is reset at the end of dealing with each CNAME. 5202 */ 5203 st->state |= (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME); 5204 } 5205 5206 /* 5207 * Check known IP addresses for the query name if the database 5208 * lookup resulted in some addresses (qresult_type == 0) 5209 * and if we have not already checked them. 5210 * Any recursion required for the query has already happened. 5211 * Do not check addresses that will not be in the ANSWER section. 5212 */ 5213 if ((st->state & DNS_RPZ_DONE_QNAME_IP) == 0 && qresult_type == 0 && 5214 rpz_get_zbits(client, qtype, DNS_RPZ_TYPE_IP) != 0) { 5215 result = rpz_rewrite_ip_rrsets(client, 5216 client->query.qname, qtype, 5217 DNS_RPZ_TYPE_IP, 5218 &rdataset, resuming); 5219 if (result != ISC_R_SUCCESS) 5220 goto cleanup; 5221 /* 5222 * We are finished checking the IP addresses for the qname. 5223 * Start with IPv4 if we will check NS IP addesses. 5224 */ 5225 st->state |= DNS_RPZ_DONE_QNAME_IP; 5226 st->state &= ~DNS_RPZ_DONE_IPv4; 5227 } 5228 5229 /* 5230 * Stop looking for rules if there are none of the other kinds 5231 * that could override what we already have. 5232 */ 5233 if (rpz_get_zbits(client, dns_rdatatype_any, 5234 DNS_RPZ_TYPE_NSDNAME) == 0 && 5235 rpz_get_zbits(client, dns_rdatatype_any, 5236 DNS_RPZ_TYPE_NSIP) == 0) { 5237 result = ISC_R_SUCCESS; 5238 goto cleanup; 5239 } 5240 5241 dns_fixedname_init(&nsnamef); 5242 dns_name_clone(client->query.qname, dns_fixedname_name(&nsnamef)); 5243 while (st->r.label > st->popt.min_ns_labels) { 5244 /* 5245 * Get NS rrset for each domain in the current qname. 5246 */ 5247 if (st->r.label == dns_name_countlabels(client->query.qname)) { 5248 nsname = client->query.qname; 5249 } else { 5250 nsname = dns_fixedname_name(&nsnamef); 5251 dns_name_split(client->query.qname, st->r.label, 5252 NULL, nsname); 5253 } 5254 if (st->r.ns_rdataset == NULL || 5255 !dns_rdataset_isassociated(st->r.ns_rdataset)) 5256 { 5257 dns_db_t *db = NULL; 5258 result = rpz_rrset_find(client, nsname, 5259 dns_rdatatype_ns, 5260 DNS_RPZ_TYPE_NSDNAME, 5261 &db, NULL, &st->r.ns_rdataset, 5262 resuming); 5263 if (db != NULL) 5264 dns_db_detach(&db); 5265 if (st->m.policy == DNS_RPZ_POLICY_ERROR) 5266 goto cleanup; 5267 switch (result) { 5268 case ISC_R_SUCCESS: 5269 result = dns_rdataset_first(st->r.ns_rdataset); 5270 if (result != ISC_R_SUCCESS) 5271 goto cleanup; 5272 st->state &= ~(DNS_RPZ_DONE_NSDNAME | 5273 DNS_RPZ_DONE_IPv4); 5274 break; 5275 case DNS_R_DELEGATION: 5276 case DNS_R_DUPLICATE: 5277 case DNS_R_DROP: 5278 goto cleanup; 5279 case DNS_R_EMPTYNAME: 5280 case DNS_R_NXRRSET: 5281 case DNS_R_EMPTYWILD: 5282 case DNS_R_NXDOMAIN: 5283 case DNS_R_NCACHENXDOMAIN: 5284 case DNS_R_NCACHENXRRSET: 5285 case ISC_R_NOTFOUND: 5286 case DNS_R_CNAME: 5287 case DNS_R_DNAME: 5288 rpz_rewrite_ns_skip(client, nsname, result, 5289 0, NULL); 5290 continue; 5291 case ISC_R_TIMEDOUT: 5292 case DNS_R_BROKENCHAIN: 5293 case ISC_R_FAILURE: 5294 rpz_rewrite_ns_skip(client, nsname, result, 5295 DNS_RPZ_DEBUG_LEVEL3, 5296 " NS rpz_rrset_find() "); 5297 continue; 5298 default: 5299 rpz_rewrite_ns_skip(client, nsname, result, 5300 DNS_RPZ_INFO_LEVEL, 5301 " unrecognized NS" 5302 " rpz_rrset_find() "); 5303 continue; 5304 } 5305 } 5306 /* 5307 * Check all NS names. 5308 */ 5309 do { 5310 dns_rdata_ns_t ns; 5311 dns_rdata_t nsrdata = DNS_RDATA_INIT; 5312 5313 dns_rdataset_current(st->r.ns_rdataset, &nsrdata); 5314 result = dns_rdata_tostruct(&nsrdata, &ns, NULL); 5315 dns_rdata_reset(&nsrdata); 5316 if (result != ISC_R_SUCCESS) { 5317 rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, 5318 nsname, DNS_RPZ_TYPE_NSIP, 5319 " rdata_tostruct()", result); 5320 st->m.policy = DNS_RPZ_POLICY_ERROR; 5321 goto cleanup; 5322 } 5323 /* 5324 * Do nothing about "NS ." 5325 */ 5326 if (dns_name_equal(&ns.name, dns_rootname)) { 5327 dns_rdata_freestruct(&ns); 5328 result = dns_rdataset_next(st->r.ns_rdataset); 5329 continue; 5330 } 5331 /* 5332 * Check this NS name if we did not handle it 5333 * during a previous recursion. 5334 */ 5335 if ((st->state & DNS_RPZ_DONE_NSDNAME) == 0) { 5336 result = rpz_rewrite_name(client, &ns.name, 5337 qtype, 5338 DNS_RPZ_TYPE_NSDNAME, 5339 DNS_RPZ_ALL_ZBITS, 5340 &rdataset); 5341 if (result != ISC_R_SUCCESS) { 5342 dns_rdata_freestruct(&ns); 5343 goto cleanup; 5344 } 5345 st->state |= DNS_RPZ_DONE_NSDNAME; 5346 } 5347 /* 5348 * Check all IP addresses for this NS name. 5349 */ 5350 result = rpz_rewrite_ip_rrsets(client, &ns.name, qtype, 5351 DNS_RPZ_TYPE_NSIP, 5352 &rdataset, resuming); 5353 dns_rdata_freestruct(&ns); 5354 if (result != ISC_R_SUCCESS) 5355 goto cleanup; 5356 st->state &= ~(DNS_RPZ_DONE_NSDNAME | 5357 DNS_RPZ_DONE_IPv4); 5358 result = dns_rdataset_next(st->r.ns_rdataset); 5359 } while (result == ISC_R_SUCCESS); 5360 dns_rdataset_disassociate(st->r.ns_rdataset); 5361 st->r.label--; 5362 5363 if (rpz_get_zbits(client, dns_rdatatype_any, 5364 DNS_RPZ_TYPE_NSDNAME) == 0 && 5365 rpz_get_zbits(client, dns_rdatatype_any, 5366 DNS_RPZ_TYPE_NSIP) == 0) 5367 break; 5368 } 5369 5370 /* 5371 * Use the best hit, if any. 5372 */ 5373 result = ISC_R_SUCCESS; 5374 5375 cleanup: 5376 if (st->m.policy != DNS_RPZ_POLICY_MISS && 5377 st->m.policy != DNS_RPZ_POLICY_ERROR && 5378 st->m.rpz->policy != DNS_RPZ_POLICY_GIVEN) 5379 st->m.policy = st->m.rpz->policy; 5380 if (st->m.policy == DNS_RPZ_POLICY_MISS || 5381 st->m.policy == DNS_RPZ_POLICY_PASSTHRU || 5382 st->m.policy == DNS_RPZ_POLICY_ERROR) { 5383 if (st->m.policy == DNS_RPZ_POLICY_PASSTHRU && 5384 result != DNS_R_DELEGATION) 5385 rpz_log_rewrite(client, ISC_FALSE, st->m.policy, 5386 st->m.type, st->m.zone, st->p_name); 5387 rpz_match_clear(st); 5388 } 5389 if (st->m.policy == DNS_RPZ_POLICY_ERROR) { 5390 st->m.type = DNS_RPZ_TYPE_BAD; 5391 result = DNS_R_SERVFAIL; 5392 } 5393 query_putrdataset(client, &rdataset); 5394 if ((st->state & DNS_RPZ_RECURSING) == 0) 5395 rpz_clean(NULL, &st->r.db, NULL, &st->r.ns_rdataset); 5396 5397 return (result); 5398 } 5399 5400 /* 5401 * See if response policy zone rewriting is allowed by a lack of interest 5402 * by the client in DNSSEC or a lack of signatures. 5403 */ 5404 static isc_boolean_t 5405 rpz_ck_dnssec(ns_client_t *client, isc_result_t qresult, 5406 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) 5407 { 5408 dns_fixedname_t fixed; 5409 dns_name_t *found; 5410 dns_rdataset_t trdataset; 5411 dns_rdatatype_t type; 5412 isc_result_t result; 5413 5414 CTRACE("rpz_ck_dnssec"); 5415 5416 if (client->view->rpzs->p.break_dnssec || !WANTDNSSEC(client)) 5417 return (ISC_TRUE); 5418 5419 /* 5420 * We do not know if there are signatures if we have not recursed 5421 * for them. 5422 */ 5423 if (qresult == DNS_R_DELEGATION || qresult == ISC_R_NOTFOUND) 5424 return (ISC_FALSE); 5425 5426 if (sigrdataset == NULL) 5427 return (ISC_TRUE); 5428 if (dns_rdataset_isassociated(sigrdataset)) 5429 return (ISC_FALSE); 5430 5431 /* 5432 * We are happy to rewrite nothing. 5433 */ 5434 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) 5435 return (ISC_TRUE); 5436 /* 5437 * Do not rewrite if there is any sign of signatures. 5438 */ 5439 if (rdataset->type == dns_rdatatype_nsec || 5440 rdataset->type == dns_rdatatype_nsec3 || 5441 rdataset->type == dns_rdatatype_rrsig) 5442 return (ISC_FALSE); 5443 5444 /* 5445 * Look for a signature in a negative cache rdataset. 5446 */ 5447 if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) == 0) 5448 return (ISC_TRUE); 5449 dns_fixedname_init(&fixed); 5450 found = dns_fixedname_name(&fixed); 5451 dns_rdataset_init(&trdataset); 5452 for (result = dns_rdataset_first(rdataset); 5453 result == ISC_R_SUCCESS; 5454 result = dns_rdataset_next(rdataset)) { 5455 dns_ncache_current(rdataset, found, &trdataset); 5456 type = trdataset.type; 5457 dns_rdataset_disassociate(&trdataset); 5458 if (type == dns_rdatatype_nsec || 5459 type == dns_rdatatype_nsec3 || 5460 type == dns_rdatatype_rrsig) 5461 return (ISC_FALSE); 5462 } 5463 return (ISC_TRUE); 5464 } 5465 5466 /* 5467 * Add a CNAME to the query response, including translating foo.evil.com and 5468 * *.evil.com CNAME *.example.com 5469 * to 5470 * foo.evil.com CNAME foo.evil.com.example.com 5471 */ 5472 static isc_result_t 5473 rpz_add_cname(ns_client_t *client, dns_rpz_st_t *st, 5474 dns_name_t *cname, dns_name_t *fname, isc_buffer_t *dbuf) 5475 { 5476 dns_fixedname_t prefix, suffix; 5477 unsigned int labels; 5478 isc_result_t result; 5479 5480 CTRACE("rpz_add_cname"); 5481 5482 labels = dns_name_countlabels(cname); 5483 if (labels > 2 && dns_name_iswildcard(cname)) { 5484 dns_fixedname_init(&prefix); 5485 dns_name_split(client->query.qname, 1, 5486 dns_fixedname_name(&prefix), NULL); 5487 dns_fixedname_init(&suffix); 5488 dns_name_split(cname, labels-1, 5489 NULL, dns_fixedname_name(&suffix)); 5490 result = dns_name_concatenate(dns_fixedname_name(&prefix), 5491 dns_fixedname_name(&suffix), 5492 fname, NULL); 5493 if (result == DNS_R_NAMETOOLONG) 5494 client->message->rcode = dns_rcode_yxdomain; 5495 } else { 5496 result = dns_name_copy(cname, fname, NULL); 5497 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5498 } 5499 if (result != ISC_R_SUCCESS) 5500 return (result); 5501 query_keepname(client, fname, dbuf); 5502 result = query_add_cname(client, client->query.qname, 5503 fname, dns_trust_authanswer, st->m.ttl); 5504 if (result != ISC_R_SUCCESS) 5505 return (result); 5506 rpz_log_rewrite(client, ISC_FALSE, st->m.policy, 5507 st->m.type, st->m.zone, st->p_name); 5508 ns_client_qnamereplace(client, fname); 5509 /* 5510 * Turn off DNSSEC because the results of a 5511 * response policy zone cannot verify. 5512 */ 5513 client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC | 5514 NS_CLIENTATTR_WANTAD); 5515 return (ISC_R_SUCCESS); 5516 } 5517 5518 #define MAX_RESTARTS 16 5519 5520 #define QUERY_ERROR(r) \ 5521 do { \ 5522 eresult = r; \ 5523 want_restart = ISC_FALSE; \ 5524 line = __LINE__; \ 5525 } while (/*CONSTCOND*/0) 5526 5527 #define RECURSE_ERROR(r) \ 5528 do { \ 5529 if ((r) == DNS_R_DUPLICATE || (r) == DNS_R_DROP) \ 5530 QUERY_ERROR(r); \ 5531 else \ 5532 QUERY_ERROR(DNS_R_SERVFAIL); \ 5533 } while (/*CONSTCOND*/0) 5534 5535 /* 5536 * Extract a network address from the RDATA of an A or AAAA 5537 * record. 5538 * 5539 * Returns: 5540 * ISC_R_SUCCESS 5541 * ISC_R_NOTIMPLEMENTED The rdata is not a known address type. 5542 */ 5543 static isc_result_t 5544 rdata_tonetaddr(const dns_rdata_t *rdata, isc_netaddr_t *netaddr) { 5545 struct in_addr ina; 5546 struct in6_addr in6a; 5547 5548 switch (rdata->type) { 5549 case dns_rdatatype_a: 5550 INSIST(rdata->length == 4); 5551 memmove(&ina.s_addr, rdata->data, 4); 5552 isc_netaddr_fromin(netaddr, &ina); 5553 return (ISC_R_SUCCESS); 5554 case dns_rdatatype_aaaa: 5555 INSIST(rdata->length == 16); 5556 memmove(in6a.s6_addr, rdata->data, 16); 5557 isc_netaddr_fromin6(netaddr, &in6a); 5558 return (ISC_R_SUCCESS); 5559 default: 5560 return (ISC_R_NOTIMPLEMENTED); 5561 } 5562 } 5563 5564 /* 5565 * Find the sort order of 'rdata' in the topology-like 5566 * ACL forming the second element in a 2-element top-level 5567 * sortlist statement. 5568 */ 5569 static int 5570 query_sortlist_order_2element(const dns_rdata_t *rdata, const void *arg) { 5571 isc_netaddr_t netaddr; 5572 5573 if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS) 5574 return (INT_MAX); 5575 return (ns_sortlist_addrorder2(&netaddr, arg)); 5576 } 5577 5578 /* 5579 * Find the sort order of 'rdata' in the matching element 5580 * of a 1-element top-level sortlist statement. 5581 */ 5582 static int 5583 query_sortlist_order_1element(const dns_rdata_t *rdata, const void *arg) { 5584 isc_netaddr_t netaddr; 5585 5586 if (rdata_tonetaddr(rdata, &netaddr) != ISC_R_SUCCESS) 5587 return (INT_MAX); 5588 return (ns_sortlist_addrorder1(&netaddr, arg)); 5589 } 5590 5591 /* 5592 * Find the sortlist statement that applies to 'client' and set up 5593 * the sortlist info in in client->message appropriately. 5594 */ 5595 static void 5596 setup_query_sortlist(ns_client_t *client) { 5597 isc_netaddr_t netaddr; 5598 dns_rdatasetorderfunc_t order = NULL; 5599 const void *order_arg = NULL; 5600 5601 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); 5602 switch (ns_sortlist_setup(client->view->sortlist, 5603 &netaddr, &order_arg)) { 5604 case NS_SORTLISTTYPE_1ELEMENT: 5605 order = query_sortlist_order_1element; 5606 break; 5607 case NS_SORTLISTTYPE_2ELEMENT: 5608 order = query_sortlist_order_2element; 5609 break; 5610 case NS_SORTLISTTYPE_NONE: 5611 order = NULL; 5612 break; 5613 default: 5614 INSIST(0); 5615 break; 5616 } 5617 dns_message_setsortorder(client->message, order, order_arg); 5618 } 5619 5620 static void 5621 query_addnoqnameproof(ns_client_t *client, dns_rdataset_t *rdataset) { 5622 isc_buffer_t *dbuf, b; 5623 dns_name_t *fname; 5624 dns_rdataset_t *neg, *negsig; 5625 isc_result_t result = ISC_R_NOMEMORY; 5626 5627 CTRACE("query_addnoqnameproof"); 5628 5629 fname = NULL; 5630 neg = NULL; 5631 negsig = NULL; 5632 5633 dbuf = query_getnamebuf(client); 5634 if (dbuf == NULL) 5635 goto cleanup; 5636 fname = query_newname(client, dbuf, &b); 5637 neg = query_newrdataset(client); 5638 negsig = query_newrdataset(client); 5639 if (fname == NULL || neg == NULL || negsig == NULL) 5640 goto cleanup; 5641 5642 result = dns_rdataset_getnoqname(rdataset, fname, neg, negsig); 5643 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5644 5645 query_addrrset(client, &fname, &neg, &negsig, dbuf, 5646 DNS_SECTION_AUTHORITY); 5647 5648 if ((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) == 0) 5649 goto cleanup; 5650 5651 if (fname == NULL) { 5652 dbuf = query_getnamebuf(client); 5653 if (dbuf == NULL) 5654 goto cleanup; 5655 fname = query_newname(client, dbuf, &b); 5656 } 5657 if (neg == NULL) 5658 neg = query_newrdataset(client); 5659 else if (dns_rdataset_isassociated(neg)) 5660 dns_rdataset_disassociate(neg); 5661 if (negsig == NULL) 5662 negsig = query_newrdataset(client); 5663 else if (dns_rdataset_isassociated(negsig)) 5664 dns_rdataset_disassociate(negsig); 5665 if (fname == NULL || neg == NULL || negsig == NULL) 5666 goto cleanup; 5667 result = dns_rdataset_getclosest(rdataset, fname, neg, negsig); 5668 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5669 5670 query_addrrset(client, &fname, &neg, &negsig, dbuf, 5671 DNS_SECTION_AUTHORITY); 5672 5673 cleanup: 5674 if (neg != NULL) 5675 query_putrdataset(client, &neg); 5676 if (negsig != NULL) 5677 query_putrdataset(client, &negsig); 5678 if (fname != NULL) 5679 query_releasename(client, &fname); 5680 } 5681 5682 static inline void 5683 answer_in_glue(ns_client_t *client, dns_rdatatype_t qtype) { 5684 dns_name_t *name; 5685 dns_message_t *msg; 5686 dns_section_t section = DNS_SECTION_ADDITIONAL; 5687 dns_rdataset_t *rdataset = NULL; 5688 5689 msg = client->message; 5690 for (name = ISC_LIST_HEAD(msg->sections[section]); 5691 name != NULL; 5692 name = ISC_LIST_NEXT(name, link)) 5693 if (dns_name_equal(name, client->query.qname)) { 5694 for (rdataset = ISC_LIST_HEAD(name->list); 5695 rdataset != NULL; 5696 rdataset = ISC_LIST_NEXT(rdataset, link)) 5697 if (rdataset->type == qtype) 5698 break; 5699 break; 5700 } 5701 if (rdataset != NULL) { 5702 ISC_LIST_UNLINK(msg->sections[section], name, link); 5703 ISC_LIST_PREPEND(msg->sections[section], name, link); 5704 ISC_LIST_UNLINK(name->list, rdataset, link); 5705 ISC_LIST_PREPEND(name->list, rdataset, link); 5706 rdataset->attributes |= DNS_RDATASETATTR_REQUIRED; 5707 } 5708 } 5709 5710 #define NS_NAME_INIT(A,B) \ 5711 { \ 5712 DNS_NAME_MAGIC, \ 5713 A, sizeof(A), sizeof(B), \ 5714 DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, \ 5715 B, NULL, { (void *)-1, (void *)-1}, \ 5716 {NULL, NULL} \ 5717 } 5718 5719 static unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 }; 5720 static unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 }; 5721 static unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 }; 5722 5723 static unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA"; 5724 5725 static unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA"; 5726 static unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA"; 5727 static unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA"; 5728 static unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA"; 5729 static unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA"; 5730 static unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA"; 5731 static unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA"; 5732 static unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA"; 5733 static unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA"; 5734 static unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA"; 5735 static unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA"; 5736 static unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA"; 5737 static unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA"; 5738 static unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA"; 5739 static unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA"; 5740 static unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA"; 5741 5742 static unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA"; 5743 5744 static dns_name_t rfc1918names[] = { 5745 NS_NAME_INIT(inaddr10, inaddr10_offsets), 5746 NS_NAME_INIT(inaddr16172, inaddr172_offsets), 5747 NS_NAME_INIT(inaddr17172, inaddr172_offsets), 5748 NS_NAME_INIT(inaddr18172, inaddr172_offsets), 5749 NS_NAME_INIT(inaddr19172, inaddr172_offsets), 5750 NS_NAME_INIT(inaddr20172, inaddr172_offsets), 5751 NS_NAME_INIT(inaddr21172, inaddr172_offsets), 5752 NS_NAME_INIT(inaddr22172, inaddr172_offsets), 5753 NS_NAME_INIT(inaddr23172, inaddr172_offsets), 5754 NS_NAME_INIT(inaddr24172, inaddr172_offsets), 5755 NS_NAME_INIT(inaddr25172, inaddr172_offsets), 5756 NS_NAME_INIT(inaddr26172, inaddr172_offsets), 5757 NS_NAME_INIT(inaddr27172, inaddr172_offsets), 5758 NS_NAME_INIT(inaddr28172, inaddr172_offsets), 5759 NS_NAME_INIT(inaddr29172, inaddr172_offsets), 5760 NS_NAME_INIT(inaddr30172, inaddr172_offsets), 5761 NS_NAME_INIT(inaddr31172, inaddr172_offsets), 5762 NS_NAME_INIT(inaddr168192, inaddr192_offsets) 5763 }; 5764 5765 5766 static unsigned char prisoner_data[] = "\010prisoner\004iana\003org"; 5767 static unsigned char hostmaster_data[] = "\012hostmaster\014root-servers\003org"; 5768 5769 static unsigned char prisoner_offsets[] = { 0, 9, 14, 18 }; 5770 static unsigned char hostmaster_offsets[] = { 0, 11, 24, 28 }; 5771 5772 static dns_name_t prisoner = NS_NAME_INIT(prisoner_data, prisoner_offsets); 5773 static dns_name_t hostmaster = NS_NAME_INIT(hostmaster_data, hostmaster_offsets); 5774 5775 static void 5776 warn_rfc1918(ns_client_t *client, dns_name_t *fname, dns_rdataset_t *rdataset) { 5777 unsigned int i; 5778 dns_rdata_t rdata = DNS_RDATA_INIT; 5779 dns_rdata_soa_t soa; 5780 dns_rdataset_t found; 5781 isc_result_t result; 5782 5783 for (i = 0; i < (sizeof(rfc1918names)/sizeof(*rfc1918names)); i++) { 5784 if (dns_name_issubdomain(fname, &rfc1918names[i])) { 5785 dns_rdataset_init(&found); 5786 result = dns_ncache_getrdataset(rdataset, 5787 &rfc1918names[i], 5788 dns_rdatatype_soa, 5789 &found); 5790 if (result != ISC_R_SUCCESS) 5791 return; 5792 5793 result = dns_rdataset_first(&found); 5794 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5795 dns_rdataset_current(&found, &rdata); 5796 result = dns_rdata_tostruct(&rdata, &soa, NULL); 5797 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5798 if (dns_name_equal(&soa.origin, &prisoner) && 5799 dns_name_equal(&soa.contact, &hostmaster)) { 5800 char buf[DNS_NAME_FORMATSIZE]; 5801 dns_name_format(fname, buf, sizeof(buf)); 5802 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 5803 NS_LOGMODULE_QUERY, 5804 ISC_LOG_WARNING, 5805 "RFC 1918 response from " 5806 "Internet for %s", buf); 5807 } 5808 dns_rdataset_disassociate(&found); 5809 return; 5810 } 5811 } 5812 } 5813 5814 static void 5815 query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, 5816 dns_dbversion_t *version, ns_client_t *client, 5817 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, 5818 dns_name_t *fname, isc_boolean_t exact, 5819 dns_name_t *found) 5820 { 5821 unsigned char salt[256]; 5822 size_t salt_length; 5823 isc_uint16_t iterations; 5824 isc_result_t result; 5825 unsigned int dboptions; 5826 dns_fixedname_t fixed; 5827 dns_hash_t hash; 5828 dns_name_t name; 5829 unsigned int skip = 0, labels; 5830 dns_rdata_nsec3_t nsec3; 5831 dns_rdata_t rdata = DNS_RDATA_INIT; 5832 isc_boolean_t optout; 5833 dns_clientinfomethods_t cm; 5834 dns_clientinfo_t ci; 5835 5836 salt_length = sizeof(salt); 5837 result = dns_db_getnsec3parameters(db, version, &hash, NULL, 5838 &iterations, salt, &salt_length); 5839 if (result != ISC_R_SUCCESS) 5840 return; 5841 5842 dns_name_init(&name, NULL); 5843 dns_name_clone(qname, &name); 5844 labels = dns_name_countlabels(&name); 5845 dns_clientinfomethods_init(&cm, ns_client_sourceip); 5846 dns_clientinfo_init(&ci, client); 5847 5848 /* 5849 * Map unknown algorithm to known value. 5850 */ 5851 if (hash == DNS_NSEC3_UNKNOWNALG) 5852 hash = 1; 5853 5854 again: 5855 dns_fixedname_init(&fixed); 5856 result = dns_nsec3_hashname(&fixed, NULL, NULL, &name, 5857 dns_db_origin(db), hash, 5858 iterations, salt, salt_length); 5859 if (result != ISC_R_SUCCESS) 5860 return; 5861 5862 dboptions = client->query.dboptions | DNS_DBFIND_FORCENSEC3; 5863 result = dns_db_findext(db, dns_fixedname_name(&fixed), version, 5864 dns_rdatatype_nsec3, dboptions, client->now, 5865 NULL, fname, &cm, &ci, rdataset, sigrdataset); 5866 5867 if (result == DNS_R_NXDOMAIN) { 5868 if (!dns_rdataset_isassociated(rdataset)) { 5869 return; 5870 } 5871 result = dns_rdataset_first(rdataset); 5872 INSIST(result == ISC_R_SUCCESS); 5873 dns_rdataset_current(rdataset, &rdata); 5874 dns_rdata_tostruct(&rdata, &nsec3, NULL); 5875 dns_rdata_reset(&rdata); 5876 optout = ISC_TF((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0); 5877 if (found != NULL && optout && 5878 dns_name_issubdomain(&name, dns_db_origin(db))) 5879 { 5880 dns_rdataset_disassociate(rdataset); 5881 if (dns_rdataset_isassociated(sigrdataset)) 5882 dns_rdataset_disassociate(sigrdataset); 5883 skip++; 5884 dns_name_getlabelsequence(qname, skip, labels - skip, 5885 &name); 5886 ns_client_log(client, DNS_LOGCATEGORY_DNSSEC, 5887 NS_LOGMODULE_QUERY, ISC_LOG_DEBUG(3), 5888 "looking for closest provable encloser"); 5889 goto again; 5890 } 5891 if (exact) 5892 ns_client_log(client, DNS_LOGCATEGORY_DNSSEC, 5893 NS_LOGMODULE_QUERY, ISC_LOG_WARNING, 5894 "expected a exact match NSEC3, got " 5895 "a covering record"); 5896 5897 } else if (result != ISC_R_SUCCESS) { 5898 return; 5899 } else if (!exact) 5900 ns_client_log(client, DNS_LOGCATEGORY_DNSSEC, 5901 NS_LOGMODULE_QUERY, ISC_LOG_WARNING, 5902 "expected covering NSEC3, got an exact match"); 5903 if (found == qname) { 5904 if (skip != 0U) 5905 dns_name_getlabelsequence(qname, skip, labels - skip, 5906 found); 5907 } else if (found != NULL) 5908 dns_name_copy(&name, found, NULL); 5909 return; 5910 } 5911 5912 #ifdef ALLOW_FILTER_AAAA 5913 static isc_boolean_t 5914 is_v4_client(ns_client_t *client) { 5915 if (isc_sockaddr_pf(&client->peeraddr) == AF_INET) 5916 return (ISC_TRUE); 5917 if (isc_sockaddr_pf(&client->peeraddr) == AF_INET6 && 5918 IN6_IS_ADDR_V4MAPPED(&client->peeraddr.type.sin6.sin6_addr)) 5919 return (ISC_TRUE); 5920 return (ISC_FALSE); 5921 } 5922 5923 static isc_boolean_t 5924 is_v6_client(ns_client_t *client) { 5925 if (isc_sockaddr_pf(&client->peeraddr) == AF_INET6 && 5926 !IN6_IS_ADDR_V4MAPPED(&client->peeraddr.type.sin6.sin6_addr)) 5927 return (ISC_TRUE); 5928 return (ISC_FALSE); 5929 } 5930 #endif 5931 5932 static isc_uint32_t 5933 dns64_ttl(dns_db_t *db, dns_dbversion_t *version) { 5934 dns_dbnode_t *node = NULL; 5935 dns_rdata_soa_t soa; 5936 dns_rdata_t rdata = DNS_RDATA_INIT; 5937 dns_rdataset_t rdataset; 5938 isc_result_t result; 5939 isc_uint32_t ttl = ISC_UINT32_MAX; 5940 5941 dns_rdataset_init(&rdataset); 5942 5943 result = dns_db_getoriginnode(db, &node); 5944 if (result != ISC_R_SUCCESS) 5945 goto cleanup; 5946 5947 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, 5948 0, 0, &rdataset, NULL); 5949 if (result != ISC_R_SUCCESS) 5950 goto cleanup; 5951 result = dns_rdataset_first(&rdataset); 5952 if (result != ISC_R_SUCCESS) 5953 goto cleanup; 5954 5955 dns_rdataset_current(&rdataset, &rdata); 5956 result = dns_rdata_tostruct(&rdata, &soa, NULL); 5957 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5958 ttl = ISC_MIN(rdataset.ttl, soa.minimum); 5959 5960 cleanup: 5961 if (dns_rdataset_isassociated(&rdataset)) 5962 dns_rdataset_disassociate(&rdataset); 5963 if (node != NULL) 5964 dns_db_detachnode(db, &node); 5965 return (ttl); 5966 } 5967 5968 static isc_boolean_t 5969 dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset, 5970 dns_rdataset_t *sigrdataset) 5971 { 5972 isc_netaddr_t netaddr; 5973 dns_dns64_t *dns64 = ISC_LIST_HEAD(client->view->dns64); 5974 unsigned int flags = 0; 5975 unsigned int i, count; 5976 isc_boolean_t *aaaaok; 5977 5978 INSIST(client->query.dns64_aaaaok == NULL); 5979 INSIST(client->query.dns64_aaaaoklen == 0); 5980 INSIST(client->query.dns64_aaaa == NULL); 5981 INSIST(client->query.dns64_sigaaaa == NULL); 5982 5983 if (dns64 == NULL) 5984 return (ISC_TRUE); 5985 5986 if (RECURSIONOK(client)) 5987 flags |= DNS_DNS64_RECURSIVE; 5988 5989 if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) 5990 flags |= DNS_DNS64_DNSSEC; 5991 5992 count = dns_rdataset_count(rdataset); 5993 aaaaok = isc_mem_get(client->mctx, sizeof(isc_boolean_t) * count); 5994 5995 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); 5996 if (dns_dns64_aaaaok(dns64, &netaddr, client->signer, 5997 &ns_g_server->aclenv, flags, rdataset, 5998 aaaaok, count)) { 5999 for (i = 0; i < count; i++) { 6000 if (aaaaok != NULL && !aaaaok[i]) { 6001 client->query.dns64_aaaaok = aaaaok; 6002 client->query.dns64_aaaaoklen = count; 6003 break; 6004 } 6005 } 6006 if (i == count && aaaaok != NULL) 6007 isc_mem_put(client->mctx, aaaaok, 6008 sizeof(isc_boolean_t) * count); 6009 return (ISC_TRUE); 6010 } 6011 if (aaaaok != NULL) 6012 isc_mem_put(client->mctx, aaaaok, 6013 sizeof(isc_boolean_t) * count); 6014 return (ISC_FALSE); 6015 } 6016 6017 /* 6018 * Look for the name and type in the redirection zone. If found update 6019 * the arguments as appropriate. Return ISC_TRUE if a update was 6020 * performed. 6021 * 6022 * Only perform the update if the client is in the allow query acl and 6023 * returning the update would not cause a DNSSEC validation failure. 6024 */ 6025 static isc_result_t 6026 redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, 6027 dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp, 6028 dns_rdatatype_t qtype) 6029 { 6030 dns_db_t *db = NULL; 6031 dns_dbnode_t *node = NULL; 6032 dns_fixedname_t fixed; 6033 dns_name_t *found; 6034 dns_rdataset_t trdataset; 6035 isc_result_t result; 6036 dns_rdatatype_t type; 6037 dns_clientinfomethods_t cm; 6038 dns_clientinfo_t ci; 6039 ns_dbversion_t *dbversion; 6040 6041 CTRACE("redirect"); 6042 6043 if (client->view->redirect == NULL) 6044 return (ISC_R_NOTFOUND); 6045 6046 dns_fixedname_init(&fixed); 6047 found = dns_fixedname_name(&fixed); 6048 dns_rdataset_init(&trdataset); 6049 6050 dns_clientinfomethods_init(&cm, ns_client_sourceip); 6051 dns_clientinfo_init(&ci, client); 6052 6053 if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp)) 6054 return (ISC_R_NOTFOUND); 6055 6056 if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) { 6057 if (rdataset->trust == dns_trust_secure) 6058 return (ISC_R_NOTFOUND); 6059 if (rdataset->trust == dns_trust_ultimate && 6060 (rdataset->type == dns_rdatatype_nsec || 6061 rdataset->type == dns_rdatatype_nsec3)) 6062 return (ISC_R_NOTFOUND); 6063 if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) { 6064 for (result = dns_rdataset_first(rdataset); 6065 result == ISC_R_SUCCESS; 6066 result = dns_rdataset_next(rdataset)) { 6067 dns_ncache_current(rdataset, found, &trdataset); 6068 type = trdataset.type; 6069 dns_rdataset_disassociate(&trdataset); 6070 if (type == dns_rdatatype_nsec || 6071 type == dns_rdatatype_nsec3 || 6072 type == dns_rdatatype_rrsig) 6073 return (ISC_R_NOTFOUND); 6074 } 6075 } 6076 } 6077 6078 result = ns_client_checkaclsilent(client, NULL, 6079 dns_zone_getqueryacl(client->view->redirect), 6080 ISC_TRUE); 6081 if (result != ISC_R_SUCCESS) 6082 return (ISC_R_NOTFOUND); 6083 6084 result = dns_zone_getdb(client->view->redirect, &db); 6085 if (result != ISC_R_SUCCESS) 6086 return (ISC_R_NOTFOUND); 6087 6088 dbversion = query_findversion(client, db); 6089 if (dbversion == NULL) { 6090 dns_db_detach(&db); 6091 return (ISC_R_NOTFOUND); 6092 } 6093 6094 /* 6095 * Lookup the requested data in the redirect zone. 6096 */ 6097 result = dns_db_findext(db, client->query.qname, dbversion->version, 6098 qtype, 0, client->now, &node, found, &cm, &ci, 6099 &trdataset, NULL); 6100 if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) { 6101 if (dns_rdataset_isassociated(rdataset)) 6102 dns_rdataset_disassociate(rdataset); 6103 if (dns_rdataset_isassociated(&trdataset)) 6104 dns_rdataset_disassociate(&trdataset); 6105 goto nxrrset; 6106 } else if (result != ISC_R_SUCCESS) { 6107 if (dns_rdataset_isassociated(&trdataset)) 6108 dns_rdataset_disassociate(&trdataset); 6109 if (node != NULL) 6110 dns_db_detachnode(db, &node); 6111 dns_db_detach(&db); 6112 return (ISC_R_NOTFOUND); 6113 } 6114 6115 CTRACE("redirect: found data: done"); 6116 dns_name_copy(found, name, NULL); 6117 if (dns_rdataset_isassociated(rdataset)) 6118 dns_rdataset_disassociate(rdataset); 6119 if (dns_rdataset_isassociated(&trdataset)) { 6120 dns_rdataset_clone(&trdataset, rdataset); 6121 dns_rdataset_disassociate(&trdataset); 6122 } 6123 nxrrset: 6124 if (*nodep != NULL) 6125 dns_db_detachnode(*dbp, nodep); 6126 dns_db_detach(dbp); 6127 dns_db_attachnode(db, node, nodep); 6128 dns_db_attach(db, dbp); 6129 dns_db_detachnode(db, &node); 6130 dns_db_detach(&db); 6131 *versionp = dbversion->version; 6132 6133 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | 6134 NS_QUERYATTR_NOADDITIONAL); 6135 6136 return (result); 6137 } 6138 6139 /* 6140 * Do the bulk of query processing for the current query of 'client'. 6141 * If 'event' is non-NULL, we are returning from recursion and 'qtype' 6142 * is ignored. Otherwise, 'qtype' is the query type. 6143 */ 6144 static isc_result_t 6145 query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) 6146 { 6147 dns_db_t *db, *zdb; 6148 dns_dbnode_t *node; 6149 dns_rdatatype_t type = qtype; 6150 dns_name_t *fname, *zfname, *tname, *prefix; 6151 dns_rdataset_t *rdataset, *trdataset; 6152 dns_rdataset_t *sigrdataset, *zrdataset, *zsigrdataset; 6153 dns_rdataset_t **sigrdatasetp; 6154 dns_rdata_t rdata = DNS_RDATA_INIT; 6155 dns_rdatasetiter_t *rdsiter; 6156 isc_boolean_t want_restart, is_zone, need_wildcardproof; 6157 isc_boolean_t is_staticstub_zone; 6158 isc_boolean_t authoritative = ISC_FALSE; 6159 unsigned int n, nlabels; 6160 dns_namereln_t namereln; 6161 int order; 6162 isc_buffer_t *dbuf; 6163 isc_buffer_t b; 6164 isc_result_t result, eresult, tresult; 6165 dns_fixedname_t fixed; 6166 dns_fixedname_t wildcardname; 6167 dns_dbversion_t *version, *zversion; 6168 dns_zone_t *zone; 6169 dns_rdata_cname_t cname; 6170 dns_rdata_dname_t dname; 6171 unsigned int options; 6172 isc_boolean_t empty_wild; 6173 dns_rdataset_t *noqname; 6174 dns_rpz_st_t *rpz_st; 6175 isc_boolean_t resuming; 6176 int line = -1; 6177 isc_boolean_t dns64_exclude, dns64; 6178 isc_boolean_t nxrewrite = ISC_FALSE; 6179 isc_boolean_t redirected = ISC_FALSE; 6180 dns_clientinfomethods_t cm; 6181 dns_clientinfo_t ci; 6182 isc_boolean_t associated; 6183 dns_section_t section; 6184 dns_ttl_t ttl; 6185 6186 CTRACE("query_find"); 6187 6188 /* 6189 * One-time initialization. 6190 * 6191 * It's especially important to initialize anything that the cleanup 6192 * code might cleanup. 6193 */ 6194 6195 eresult = ISC_R_SUCCESS; 6196 fname = NULL; 6197 zfname = NULL; 6198 rdataset = NULL; 6199 zrdataset = NULL; 6200 sigrdataset = NULL; 6201 zsigrdataset = NULL; 6202 zversion = NULL; 6203 node = NULL; 6204 db = NULL; 6205 zdb = NULL; 6206 version = NULL; 6207 zone = NULL; 6208 need_wildcardproof = ISC_FALSE; 6209 empty_wild = ISC_FALSE; 6210 dns64_exclude = dns64 = ISC_FALSE; 6211 options = 0; 6212 resuming = ISC_FALSE; 6213 is_zone = ISC_FALSE; 6214 is_staticstub_zone = ISC_FALSE; 6215 6216 dns_clientinfomethods_init(&cm, ns_client_sourceip); 6217 dns_clientinfo_init(&ci, client); 6218 6219 if (event != NULL) { 6220 /* 6221 * We're returning from recursion. Restore the query context 6222 * and resume. 6223 */ 6224 want_restart = ISC_FALSE; 6225 6226 rpz_st = client->query.rpz_st; 6227 if (rpz_st != NULL && 6228 (rpz_st->state & DNS_RPZ_RECURSING) != 0) 6229 { 6230 CTRACE("resume from RPZ recursion"); 6231 6232 is_zone = rpz_st->q.is_zone; 6233 authoritative = rpz_st->q.authoritative; 6234 zone = rpz_st->q.zone; 6235 rpz_st->q.zone = NULL; 6236 node = rpz_st->q.node; 6237 rpz_st->q.node = NULL; 6238 db = rpz_st->q.db; 6239 rpz_st->q.db = NULL; 6240 rdataset = rpz_st->q.rdataset; 6241 rpz_st->q.rdataset = NULL; 6242 sigrdataset = rpz_st->q.sigrdataset; 6243 rpz_st->q.sigrdataset = NULL; 6244 qtype = rpz_st->q.qtype; 6245 6246 rpz_st->r.db = event->db; 6247 if (event->node != NULL) 6248 dns_db_detachnode(event->db, &event->node); 6249 rpz_st->r.r_type = event->qtype; 6250 rpz_st->r.r_rdataset = event->rdataset; 6251 query_putrdataset(client, &event->sigrdataset); 6252 } else { 6253 CTRACE("resume from normal recursion"); 6254 authoritative = ISC_FALSE; 6255 6256 qtype = event->qtype; 6257 db = event->db; 6258 node = event->node; 6259 rdataset = event->rdataset; 6260 sigrdataset = event->sigrdataset; 6261 } 6262 6263 if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig) 6264 type = dns_rdatatype_any; 6265 else 6266 type = qtype; 6267 6268 if (DNS64(client)) { 6269 client->query.attributes &= ~NS_QUERYATTR_DNS64; 6270 dns64 = ISC_TRUE; 6271 } 6272 if (DNS64EXCLUDE(client)) { 6273 client->query.attributes &= ~NS_QUERYATTR_DNS64EXCLUDE; 6274 dns64_exclude = ISC_TRUE; 6275 } 6276 6277 if (rpz_st != NULL && 6278 (rpz_st->state & DNS_RPZ_RECURSING) != 0) 6279 { 6280 /* 6281 * Has response policy changed out from under us? 6282 */ 6283 if (rpz_st->rpz_ver != client->view->rpzs->rpz_ver) { 6284 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 6285 NS_LOGMODULE_QUERY, ISC_LOG_INFO, 6286 "query_find: RPZ settings " 6287 "out of date " 6288 "(rpz_ver %d, expected %d)", 6289 client->view->rpzs->rpz_ver, 6290 rpz_st->rpz_ver); 6291 QUERY_ERROR(DNS_R_SERVFAIL); 6292 goto cleanup; 6293 } 6294 } 6295 6296 /* 6297 * We'll need some resources... 6298 */ 6299 dbuf = query_getnamebuf(client); 6300 if (dbuf == NULL) { 6301 QUERY_ERROR(DNS_R_SERVFAIL); 6302 goto cleanup; 6303 } 6304 fname = query_newname(client, dbuf, &b); 6305 if (fname == NULL) { 6306 QUERY_ERROR(DNS_R_SERVFAIL); 6307 goto cleanup; 6308 } 6309 if (rpz_st != NULL && 6310 (rpz_st->state & DNS_RPZ_RECURSING) != 0) { 6311 tname = rpz_st->fname; 6312 } else { 6313 tname = dns_fixedname_name(&event->foundname); 6314 } 6315 result = dns_name_copy(tname, fname, NULL); 6316 if (result != ISC_R_SUCCESS) { 6317 QUERY_ERROR(DNS_R_SERVFAIL); 6318 goto cleanup; 6319 } 6320 if (rpz_st != NULL && 6321 (rpz_st->state & DNS_RPZ_RECURSING) != 0) { 6322 rpz_st->r.r_result = event->result; 6323 result = rpz_st->q.result; 6324 isc_event_free(ISC_EVENT_PTR(&event)); 6325 } else { 6326 result = event->result; 6327 } 6328 resuming = ISC_TRUE; 6329 goto resume; 6330 } 6331 6332 /* 6333 * Not returning from recursion. 6334 */ 6335 6336 /* 6337 * If it's a SIG query, we'll iterate the node. 6338 */ 6339 if (qtype == dns_rdatatype_rrsig || qtype == dns_rdatatype_sig) 6340 type = dns_rdatatype_any; 6341 else 6342 type = qtype; 6343 6344 restart: 6345 CTRACE("query_find: restart"); 6346 want_restart = ISC_FALSE; 6347 authoritative = ISC_FALSE; 6348 version = NULL; 6349 need_wildcardproof = ISC_FALSE; 6350 6351 if (client->view->checknames && 6352 !dns_rdata_checkowner(client->query.qname, 6353 client->message->rdclass, 6354 qtype, ISC_FALSE)) { 6355 char namebuf[DNS_NAME_FORMATSIZE]; 6356 char typename[DNS_RDATATYPE_FORMATSIZE]; 6357 char classname[DNS_RDATACLASS_FORMATSIZE]; 6358 6359 dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); 6360 dns_rdatatype_format(qtype, typename, sizeof(typename)); 6361 dns_rdataclass_format(client->message->rdclass, classname, 6362 sizeof(classname)); 6363 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 6364 NS_LOGMODULE_QUERY, ISC_LOG_ERROR, 6365 "check-names failure %s/%s/%s", namebuf, 6366 typename, classname); 6367 QUERY_ERROR(DNS_R_REFUSED); 6368 goto cleanup; 6369 } 6370 6371 /* 6372 * First we must find the right database. 6373 */ 6374 options &= DNS_GETDB_NOLOG; /* Preserve DNS_GETDB_NOLOG. */ 6375 if (dns_rdatatype_atparent(qtype) && 6376 !dns_name_equal(client->query.qname, dns_rootname)) 6377 options |= DNS_GETDB_NOEXACT; 6378 result = query_getdb(client, client->query.qname, qtype, options, 6379 &zone, &db, &version, &is_zone); 6380 if ((result != ISC_R_SUCCESS || !is_zone) && !RECURSIONOK(client) && 6381 (options & DNS_GETDB_NOEXACT) != 0 && qtype == dns_rdatatype_ds) { 6382 /* 6383 * Look to see if we are authoritative for the 6384 * child zone if the query type is DS. 6385 */ 6386 dns_db_t *tdb = NULL; 6387 dns_zone_t *tzone = NULL; 6388 dns_dbversion_t *tversion = NULL; 6389 6390 tresult = query_getzonedb(client, client->query.qname, qtype, 6391 DNS_GETDB_PARTIAL, &tzone, &tdb, 6392 &tversion); 6393 if (tresult == ISC_R_SUCCESS) { 6394 options &= ~DNS_GETDB_NOEXACT; 6395 query_putrdataset(client, &rdataset); 6396 if (db != NULL) 6397 dns_db_detach(&db); 6398 if (zone != NULL) 6399 dns_zone_detach(&zone); 6400 version = tversion; 6401 db = tdb; 6402 zone = tzone; 6403 is_zone = ISC_TRUE; 6404 result = ISC_R_SUCCESS; 6405 } else { 6406 if (tdb != NULL) 6407 dns_db_detach(&tdb); 6408 if (tzone != NULL) 6409 dns_zone_detach(&tzone); 6410 } 6411 } 6412 if (result != ISC_R_SUCCESS) { 6413 if (result == DNS_R_REFUSED) { 6414 if (WANTRECURSION(client)) { 6415 inc_stats(client, 6416 dns_nsstatscounter_recurserej); 6417 } else 6418 inc_stats(client, dns_nsstatscounter_authrej); 6419 if (!PARTIALANSWER(client)) 6420 QUERY_ERROR(DNS_R_REFUSED); 6421 } else 6422 QUERY_ERROR(DNS_R_SERVFAIL); 6423 goto cleanup; 6424 } 6425 6426 is_staticstub_zone = ISC_FALSE; 6427 if (is_zone) { 6428 authoritative = ISC_TRUE; 6429 if (zone != NULL && 6430 dns_zone_gettype(zone) == dns_zone_staticstub) 6431 is_staticstub_zone = ISC_TRUE; 6432 } 6433 6434 if (event == NULL && client->query.restarts == 0) { 6435 if (is_zone) { 6436 if (zone != NULL) { 6437 /* 6438 * if is_zone = true, zone = NULL then this is 6439 * a DLZ zone. Don't attempt to attach zone. 6440 */ 6441 dns_zone_attach(zone, &client->query.authzone); 6442 } 6443 dns_db_attach(db, &client->query.authdb); 6444 } 6445 client->query.authdbset = ISC_TRUE; 6446 6447 /* Track TCP vs UDP stats per zone */ 6448 if ((client->attributes & NS_CLIENTATTR_TCP) != 0) 6449 inc_stats(client, dns_nsstatscounter_tcp); 6450 else 6451 inc_stats(client, dns_nsstatscounter_udp); 6452 } 6453 6454 db_find: 6455 CTRACE("query_find: db_find"); 6456 /* 6457 * We'll need some resources... 6458 */ 6459 dbuf = query_getnamebuf(client); 6460 if (dbuf == NULL) { 6461 QUERY_ERROR(DNS_R_SERVFAIL); 6462 goto cleanup; 6463 } 6464 fname = query_newname(client, dbuf, &b); 6465 rdataset = query_newrdataset(client); 6466 if (fname == NULL || rdataset == NULL) { 6467 QUERY_ERROR(DNS_R_SERVFAIL); 6468 goto cleanup; 6469 } 6470 if (WANTDNSSEC(client) && (!is_zone || dns_db_issecure(db))) { 6471 sigrdataset = query_newrdataset(client); 6472 if (sigrdataset == NULL) { 6473 QUERY_ERROR(DNS_R_SERVFAIL); 6474 goto cleanup; 6475 } 6476 } 6477 6478 /* 6479 * Now look for an answer in the database. 6480 */ 6481 result = dns_db_findext(db, client->query.qname, version, type, 6482 client->query.dboptions, client->now, 6483 &node, fname, &cm, &ci, rdataset, sigrdataset); 6484 6485 if (db == client->view->cachedb) 6486 dns_cache_updatestats(client->view->cache, result); 6487 6488 resume: 6489 CTRACE("query_find: resume"); 6490 6491 /* 6492 * Rate limit these responses to this client. 6493 * Do not delay counting and handling obvious referrals, 6494 * since those won't come here again. 6495 * Delay handling delegations for which we are certain to recurse and 6496 * return here (DNS_R_DELEGATION, not a child of one of our 6497 * own zones, and recursion enabled) 6498 * Don't mess with responses rewritten by RPZ 6499 * Count each response at most once. 6500 */ 6501 if (client->view->rrl != NULL && !HAVESIT(client) && 6502 ((fname != NULL && dns_name_isabsolute(fname)) || 6503 (result == ISC_R_NOTFOUND && !RECURSIONOK(client))) && 6504 !(result == DNS_R_DELEGATION && !is_zone && RECURSIONOK(client)) && 6505 (client->query.rpz_st == NULL || 6506 (client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0)&& 6507 (client->query.attributes & NS_QUERYATTR_RRL_CHECKED) == 0) 6508 { 6509 dns_rdataset_t nc_rdataset; 6510 isc_boolean_t wouldlog; 6511 char log_buf[DNS_RRL_LOG_BUF_LEN]; 6512 isc_result_t nc_result, resp_result; 6513 dns_rrl_result_t rrl_result; 6514 6515 client->query.attributes |= NS_QUERYATTR_RRL_CHECKED; 6516 6517 wouldlog = isc_log_wouldlog(ns_g_lctx, DNS_RRL_LOG_DROP); 6518 tname = fname; 6519 if (result == DNS_R_NXDOMAIN) { 6520 /* 6521 * Use the database origin name to rate limit NXDOMAIN 6522 */ 6523 if (db != NULL) 6524 tname = dns_db_origin(db); 6525 resp_result = result; 6526 } else if (result == DNS_R_NCACHENXDOMAIN && 6527 rdataset != NULL && 6528 dns_rdataset_isassociated(rdataset) && 6529 (rdataset->attributes & 6530 DNS_RDATASETATTR_NEGATIVE) != 0) { 6531 /* 6532 * Try to use owner name in the negative cache SOA. 6533 */ 6534 dns_fixedname_init(&fixed); 6535 dns_rdataset_init(&nc_rdataset); 6536 for (nc_result = dns_rdataset_first(rdataset); 6537 nc_result == ISC_R_SUCCESS; 6538 nc_result = dns_rdataset_next(rdataset)) { 6539 dns_ncache_current(rdataset, 6540 dns_fixedname_name(&fixed), 6541 &nc_rdataset); 6542 if (nc_rdataset.type == dns_rdatatype_soa) { 6543 dns_rdataset_disassociate(&nc_rdataset); 6544 tname = dns_fixedname_name(&fixed); 6545 break; 6546 } 6547 dns_rdataset_disassociate(&nc_rdataset); 6548 } 6549 resp_result = DNS_R_NXDOMAIN; 6550 } else if (result == DNS_R_NXRRSET || 6551 result == DNS_R_EMPTYNAME) { 6552 resp_result = DNS_R_NXRRSET; 6553 } else if (result == DNS_R_DELEGATION) { 6554 resp_result = result; 6555 } else if (result == ISC_R_NOTFOUND) { 6556 /* 6557 * Handle referral to ".", including when recursion 6558 * is off or not requested and the hints have not 6559 * been loaded or we have "additional-from-cache no". 6560 */ 6561 tname = dns_rootname; 6562 resp_result = DNS_R_DELEGATION; 6563 } else { 6564 resp_result = ISC_R_SUCCESS; 6565 } 6566 rrl_result = dns_rrl(client->view, &client->peeraddr, 6567 ISC_TF((client->attributes 6568 & NS_CLIENTATTR_TCP) != 0), 6569 client->message->rdclass, qtype, tname, 6570 resp_result, client->now, 6571 wouldlog, log_buf, sizeof(log_buf)); 6572 if (rrl_result != DNS_RRL_RESULT_OK) { 6573 /* 6574 * Log dropped or slipped responses in the query 6575 * category so that requests are not silently lost. 6576 * Starts of rate-limited bursts are logged in 6577 * DNS_LOGCATEGORY_RRL. 6578 * 6579 * Dropped responses are counted with dropped queries 6580 * in QryDropped while slipped responses are counted 6581 * with other truncated responses in RespTruncated. 6582 */ 6583 if (wouldlog) { 6584 ns_client_log(client, DNS_LOGCATEGORY_RRL, 6585 NS_LOGMODULE_QUERY, 6586 DNS_RRL_LOG_DROP, 6587 "%s", log_buf); 6588 } 6589 if (!client->view->rrl->log_only) { 6590 if (rrl_result == DNS_RRL_RESULT_DROP) { 6591 /* 6592 * These will also be counted in 6593 * dns_nsstatscounter_dropped 6594 */ 6595 inc_stats(client, 6596 dns_nsstatscounter_ratedropped); 6597 QUERY_ERROR(DNS_R_DROP); 6598 } else { 6599 /* 6600 * These will also be counted in 6601 * dns_nsstatscounter_truncatedresp 6602 */ 6603 inc_stats(client, 6604 dns_nsstatscounter_rateslipped); 6605 client->message->flags |= 6606 DNS_MESSAGEFLAG_TC; 6607 if (resp_result == DNS_R_NXDOMAIN) 6608 client->message->rcode = 6609 dns_rcode_nxdomain; 6610 } 6611 goto cleanup; 6612 } 6613 } 6614 } 6615 6616 if (!RECURSING(client) && 6617 !dns_name_equal(client->query.qname, dns_rootname)) 6618 { 6619 isc_result_t rresult; 6620 6621 rresult = rpz_rewrite(client, qtype, result, resuming, 6622 rdataset, sigrdataset); 6623 rpz_st = client->query.rpz_st; 6624 switch (rresult) { 6625 case ISC_R_SUCCESS: 6626 break; 6627 case DNS_R_DISALLOWED: 6628 goto norpz; 6629 case DNS_R_DELEGATION: 6630 /* 6631 * recursing for NS names or addresses, 6632 * so save the main query state 6633 */ 6634 rpz_st->q.qtype = qtype; 6635 rpz_st->q.is_zone = is_zone; 6636 rpz_st->q.authoritative = authoritative; 6637 rpz_st->q.zone = zone; 6638 zone = NULL; 6639 rpz_st->q.db = db; 6640 db = NULL; 6641 rpz_st->q.node = node; 6642 node = NULL; 6643 rpz_st->q.rdataset = rdataset; 6644 rdataset = NULL; 6645 rpz_st->q.sigrdataset = sigrdataset; 6646 sigrdataset = NULL; 6647 dns_name_copy(fname, rpz_st->fname, NULL); 6648 rpz_st->q.result = result; 6649 client->query.attributes |= NS_QUERYATTR_RECURSING; 6650 goto cleanup; 6651 default: 6652 RECURSE_ERROR(rresult); 6653 goto cleanup; 6654 } 6655 6656 if (rpz_st->m.policy != DNS_RPZ_POLICY_MISS) 6657 rpz_st->state |= DNS_RPZ_REWRITTEN; 6658 if (rpz_st->m.policy != DNS_RPZ_POLICY_MISS && 6659 rpz_st->m.policy != DNS_RPZ_POLICY_PASSTHRU && 6660 (rpz_st->m.policy != DNS_RPZ_POLICY_TCP_ONLY || 6661 (client->attributes & NS_CLIENTATTR_TCP) == 0) && 6662 rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) 6663 { 6664 /* 6665 * We got a hit and are going to answer with our 6666 * fiction. Ensure that we answer with the name 6667 * we looked up even if we were stopped short 6668 * in recursion or for a deferral. 6669 */ 6670 rresult = dns_name_copy(client->query.qname, 6671 fname, NULL); 6672 RUNTIME_CHECK(rresult == ISC_R_SUCCESS); 6673 rpz_clean(&zone, &db, &node, NULL); 6674 if (rpz_st->m.rdataset != NULL) { 6675 query_putrdataset(client, &rdataset); 6676 rdataset = rpz_st->m.rdataset; 6677 rpz_st->m.rdataset = NULL; 6678 } else if (rdataset != NULL && 6679 dns_rdataset_isassociated(rdataset)) { 6680 dns_rdataset_disassociate(rdataset); 6681 } 6682 node = rpz_st->m.node; 6683 rpz_st->m.node = NULL; 6684 db = rpz_st->m.db; 6685 rpz_st->m.db = NULL; 6686 version = rpz_st->m.version; 6687 rpz_st->m.version = NULL; 6688 zone = rpz_st->m.zone; 6689 rpz_st->m.zone = NULL; 6690 6691 switch (rpz_st->m.policy) { 6692 case DNS_RPZ_POLICY_TCP_ONLY: 6693 client->message->flags |= DNS_MESSAGEFLAG_TC; 6694 if (result == DNS_R_NXDOMAIN || 6695 result == DNS_R_NCACHENXDOMAIN) 6696 client->message->rcode = 6697 dns_rcode_nxdomain; 6698 rpz_log_rewrite(client, ISC_FALSE, 6699 rpz_st->m.policy, 6700 rpz_st->m.type, zone, 6701 rpz_st->p_name); 6702 goto cleanup; 6703 case DNS_RPZ_POLICY_DROP: 6704 QUERY_ERROR(DNS_R_DROP); 6705 rpz_log_rewrite(client, ISC_FALSE, 6706 rpz_st->m.policy, 6707 rpz_st->m.type, zone, 6708 rpz_st->p_name); 6709 goto cleanup; 6710 case DNS_RPZ_POLICY_NXDOMAIN: 6711 result = DNS_R_NXDOMAIN; 6712 nxrewrite = ISC_TRUE; 6713 break; 6714 case DNS_RPZ_POLICY_NODATA: 6715 result = DNS_R_NXRRSET; 6716 nxrewrite = ISC_TRUE; 6717 break; 6718 case DNS_RPZ_POLICY_RECORD: 6719 result = rpz_st->m.result; 6720 if (qtype == dns_rdatatype_any && 6721 result != DNS_R_CNAME) { 6722 /* 6723 * We will add all of the rdatasets of 6724 * the node by iterating later, 6725 * and set the TTL then. 6726 */ 6727 if (dns_rdataset_isassociated(rdataset)) 6728 dns_rdataset_disassociate(rdataset); 6729 } else { 6730 /* 6731 * We will add this rdataset. 6732 */ 6733 rdataset->ttl = ISC_MIN(rdataset->ttl, 6734 rpz_st->m.ttl); 6735 } 6736 break; 6737 case DNS_RPZ_POLICY_WILDCNAME: 6738 result = dns_rdataset_first(rdataset); 6739 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6740 dns_rdataset_current(rdataset, &rdata); 6741 result = dns_rdata_tostruct(&rdata, &cname, 6742 NULL); 6743 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6744 dns_rdata_reset(&rdata); 6745 result = rpz_add_cname(client, rpz_st, 6746 &cname.cname, 6747 fname, dbuf); 6748 if (result != ISC_R_SUCCESS) 6749 goto cleanup; 6750 fname = NULL; 6751 want_restart = ISC_TRUE; 6752 goto cleanup; 6753 case DNS_RPZ_POLICY_CNAME: 6754 /* 6755 * Add overridding CNAME from a named.conf 6756 * response-policy statement 6757 */ 6758 result = rpz_add_cname(client, rpz_st, 6759 &rpz_st->m.rpz->cname, 6760 fname, dbuf); 6761 if (result != ISC_R_SUCCESS) 6762 goto cleanup; 6763 fname = NULL; 6764 want_restart = ISC_TRUE; 6765 goto cleanup; 6766 default: 6767 INSIST(0); 6768 } 6769 6770 /* 6771 * Turn off DNSSEC because the results of a 6772 * response policy zone cannot verify. 6773 */ 6774 client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC | 6775 NS_CLIENTATTR_WANTAD); 6776 client->message->flags &= ~DNS_MESSAGEFLAG_AD; 6777 query_putrdataset(client, &sigrdataset); 6778 rpz_st->q.is_zone = is_zone; 6779 is_zone = ISC_TRUE; 6780 rpz_log_rewrite(client, ISC_FALSE, rpz_st->m.policy, 6781 rpz_st->m.type, zone, rpz_st->p_name); 6782 } 6783 } 6784 6785 norpz: 6786 switch (result) { 6787 case ISC_R_SUCCESS: 6788 /* 6789 * This case is handled in the main line below. 6790 */ 6791 break; 6792 case DNS_R_GLUE: 6793 case DNS_R_ZONECUT: 6794 /* 6795 * These cases are handled in the main line below. 6796 */ 6797 INSIST(is_zone); 6798 authoritative = ISC_FALSE; 6799 break; 6800 case ISC_R_NOTFOUND: 6801 /* 6802 * The cache doesn't even have the root NS. Get them from 6803 * the hints DB. 6804 */ 6805 INSIST(!is_zone); 6806 if (db != NULL) 6807 dns_db_detach(&db); 6808 6809 if (client->view->hints == NULL) { 6810 /* We have no hints. */ 6811 result = ISC_R_FAILURE; 6812 } else { 6813 dns_db_attach(client->view->hints, &db); 6814 result = dns_db_findext(db, dns_rootname, 6815 NULL, dns_rdatatype_ns, 6816 0, client->now, &node, 6817 fname, &cm, &ci, 6818 rdataset, sigrdataset); 6819 } 6820 if (result != ISC_R_SUCCESS) { 6821 /* 6822 * Nonsensical root hints may require cleanup. 6823 */ 6824 if (dns_rdataset_isassociated(rdataset)) 6825 dns_rdataset_disassociate(rdataset); 6826 if (sigrdataset != NULL && 6827 dns_rdataset_isassociated(sigrdataset)) 6828 dns_rdataset_disassociate(sigrdataset); 6829 if (node != NULL) 6830 dns_db_detachnode(db, &node); 6831 6832 /* 6833 * We don't have any root server hints, but 6834 * we may have working forwarders, so try to 6835 * recurse anyway. 6836 */ 6837 if (RECURSIONOK(client)) { 6838 result = query_recurse(client, qtype, 6839 client->query.qname, 6840 NULL, NULL, resuming); 6841 if (result == ISC_R_SUCCESS) { 6842 client->query.attributes |= 6843 NS_QUERYATTR_RECURSING; 6844 if (dns64) 6845 client->query.attributes |= 6846 NS_QUERYATTR_DNS64; 6847 if (dns64_exclude) 6848 client->query.attributes |= 6849 NS_QUERYATTR_DNS64EXCLUDE; 6850 } else 6851 RECURSE_ERROR(result); 6852 goto cleanup; 6853 } else { 6854 /* Unable to give root server referral. */ 6855 QUERY_ERROR(DNS_R_SERVFAIL); 6856 goto cleanup; 6857 } 6858 } 6859 /* 6860 * XXXRTH We should trigger root server priming here. 6861 */ 6862 /* FALLTHROUGH */ 6863 case DNS_R_DELEGATION: 6864 authoritative = ISC_FALSE; 6865 if (is_zone) { 6866 /* 6867 * Look to see if we are authoritative for the 6868 * child zone if the query type is DS. 6869 */ 6870 if (!RECURSIONOK(client) && 6871 (options & DNS_GETDB_NOEXACT) != 0 && 6872 qtype == dns_rdatatype_ds) { 6873 dns_db_t *tdb = NULL; 6874 dns_zone_t *tzone = NULL; 6875 dns_dbversion_t *tversion = NULL; 6876 result = query_getzonedb(client, 6877 client->query.qname, 6878 qtype, 6879 DNS_GETDB_PARTIAL, 6880 &tzone, &tdb, 6881 &tversion); 6882 if (result == ISC_R_SUCCESS) { 6883 options &= ~DNS_GETDB_NOEXACT; 6884 query_putrdataset(client, &rdataset); 6885 if (sigrdataset != NULL) 6886 query_putrdataset(client, 6887 &sigrdataset); 6888 if (fname != NULL) 6889 query_releasename(client, 6890 &fname); 6891 if (node != NULL) 6892 dns_db_detachnode(db, &node); 6893 if (db != NULL) 6894 dns_db_detach(&db); 6895 if (zone != NULL) 6896 dns_zone_detach(&zone); 6897 version = tversion; 6898 db = tdb; 6899 zone = tzone; 6900 authoritative = ISC_TRUE; 6901 goto db_find; 6902 } 6903 if (tdb != NULL) 6904 dns_db_detach(&tdb); 6905 if (tzone != NULL) 6906 dns_zone_detach(&tzone); 6907 } 6908 /* 6909 * We're authoritative for an ancestor of QNAME. 6910 */ 6911 if (!USECACHE(client) || !RECURSIONOK(client)) { 6912 dns_fixedname_init(&fixed); 6913 dns_name_copy(fname, 6914 dns_fixedname_name(&fixed), NULL); 6915 6916 /* 6917 * If we don't have a cache, this is the best 6918 * answer. 6919 * 6920 * If the client is making a nonrecursive 6921 * query we always give out the authoritative 6922 * delegation. This way even if we get 6923 * junk in our cache, we won't fail in our 6924 * role as the delegating authority if another 6925 * nameserver asks us about a delegated 6926 * subzone. 6927 * 6928 * We enable the retrieval of glue for this 6929 * database by setting client->query.gluedb. 6930 */ 6931 client->query.gluedb = db; 6932 client->query.isreferral = ISC_TRUE; 6933 /* 6934 * We must ensure NOADDITIONAL is off, 6935 * because the generation of 6936 * additional data is required in 6937 * delegations. 6938 */ 6939 client->query.attributes &= 6940 ~NS_QUERYATTR_NOADDITIONAL; 6941 if (sigrdataset != NULL) 6942 sigrdatasetp = &sigrdataset; 6943 else 6944 sigrdatasetp = NULL; 6945 query_addrrset(client, &fname, 6946 &rdataset, sigrdatasetp, 6947 dbuf, DNS_SECTION_AUTHORITY); 6948 client->query.gluedb = NULL; 6949 if (WANTDNSSEC(client)) 6950 query_addds(client, db, node, version, 6951 dns_fixedname_name(&fixed)); 6952 } else { 6953 /* 6954 * We might have a better answer or delegation 6955 * in the cache. We'll remember the current 6956 * values of fname, rdataset, and sigrdataset. 6957 * We'll then go looking for QNAME in the 6958 * cache. If we find something better, we'll 6959 * use it instead. 6960 */ 6961 query_keepname(client, fname, dbuf); 6962 zdb = db; 6963 zfname = fname; 6964 fname = NULL; 6965 zrdataset = rdataset; 6966 rdataset = NULL; 6967 zsigrdataset = sigrdataset; 6968 sigrdataset = NULL; 6969 dns_db_detachnode(db, &node); 6970 zversion = version; 6971 version = NULL; 6972 db = NULL; 6973 dns_db_attach(client->view->cachedb, &db); 6974 is_zone = ISC_FALSE; 6975 goto db_find; 6976 } 6977 } else { 6978 if (zfname != NULL && 6979 (!dns_name_issubdomain(fname, zfname) || 6980 (is_staticstub_zone && 6981 dns_name_equal(fname, zfname)))) { 6982 /* 6983 * In the following cases use "authoritative" 6984 * data instead of the cache delegation: 6985 * 1. We've already got a delegation from 6986 * authoritative data, and it is better 6987 * than what we found in the cache. 6988 * 2. The query name matches the origin name 6989 * of a static-stub zone. This needs to be 6990 * considered for the case where the NS of 6991 * the static-stub zone and the cached NS 6992 * are different. We still need to contact 6993 * the nameservers configured in the 6994 * static-stub zone. 6995 */ 6996 query_releasename(client, &fname); 6997 fname = zfname; 6998 zfname = NULL; 6999 /* 7000 * We've already done query_keepname() on 7001 * zfname, so we must set dbuf to NULL to 7002 * prevent query_addrrset() from trying to 7003 * call query_keepname() again. 7004 */ 7005 dbuf = NULL; 7006 query_putrdataset(client, &rdataset); 7007 if (sigrdataset != NULL) 7008 query_putrdataset(client, 7009 &sigrdataset); 7010 rdataset = zrdataset; 7011 zrdataset = NULL; 7012 sigrdataset = zsigrdataset; 7013 zsigrdataset = NULL; 7014 version = zversion; 7015 zversion = NULL; 7016 /* 7017 * We don't clean up zdb here because we 7018 * may still need it. It will get cleaned 7019 * up by the main cleanup code. 7020 */ 7021 } 7022 7023 if (RECURSIONOK(client)) { 7024 /* 7025 * Recurse! 7026 */ 7027 if (dns_rdatatype_atparent(type)) 7028 result = query_recurse(client, qtype, 7029 client->query.qname, 7030 NULL, NULL, resuming); 7031 else if (dns64) 7032 result = query_recurse(client, 7033 dns_rdatatype_a, 7034 client->query.qname, 7035 NULL, NULL, resuming); 7036 else 7037 result = query_recurse(client, qtype, 7038 client->query.qname, 7039 fname, rdataset, 7040 resuming); 7041 7042 if (result == ISC_R_SUCCESS) { 7043 client->query.attributes |= 7044 NS_QUERYATTR_RECURSING; 7045 if (dns64) 7046 client->query.attributes |= 7047 NS_QUERYATTR_DNS64; 7048 if (dns64_exclude) 7049 client->query.attributes |= 7050 NS_QUERYATTR_DNS64EXCLUDE; 7051 } else if (result == DNS_R_DUPLICATE || 7052 result == DNS_R_DROP) 7053 QUERY_ERROR(result); 7054 else 7055 RECURSE_ERROR(result); 7056 } else { 7057 dns_fixedname_init(&fixed); 7058 dns_name_copy(fname, 7059 dns_fixedname_name(&fixed), NULL); 7060 /* 7061 * This is the best answer. 7062 */ 7063 client->query.attributes |= 7064 NS_QUERYATTR_CACHEGLUEOK; 7065 client->query.gluedb = zdb; 7066 client->query.isreferral = ISC_TRUE; 7067 /* 7068 * We must ensure NOADDITIONAL is off, 7069 * because the generation of 7070 * additional data is required in 7071 * delegations. 7072 */ 7073 client->query.attributes &= 7074 ~NS_QUERYATTR_NOADDITIONAL; 7075 if (sigrdataset != NULL) 7076 sigrdatasetp = &sigrdataset; 7077 else 7078 sigrdatasetp = NULL; 7079 query_addrrset(client, &fname, 7080 &rdataset, sigrdatasetp, 7081 dbuf, DNS_SECTION_AUTHORITY); 7082 client->query.gluedb = NULL; 7083 client->query.attributes &= 7084 ~NS_QUERYATTR_CACHEGLUEOK; 7085 if (WANTDNSSEC(client)) 7086 query_addds(client, db, node, version, 7087 dns_fixedname_name(&fixed)); 7088 } 7089 } 7090 goto cleanup; 7091 7092 case DNS_R_EMPTYNAME: 7093 case DNS_R_NXRRSET: 7094 iszone_nxrrset: 7095 INSIST(is_zone); 7096 7097 #ifdef dns64_bis_return_excluded_addresses 7098 if (dns64) 7099 #else 7100 if (dns64 && !dns64_exclude) 7101 #endif 7102 { 7103 /* 7104 * Restore the answers from the previous AAAA lookup. 7105 */ 7106 if (rdataset != NULL) 7107 query_putrdataset(client, &rdataset); 7108 if (sigrdataset != NULL) 7109 query_putrdataset(client, &sigrdataset); 7110 rdataset = client->query.dns64_aaaa; 7111 sigrdataset = client->query.dns64_sigaaaa; 7112 client->query.dns64_aaaa = NULL; 7113 client->query.dns64_sigaaaa = NULL; 7114 if (fname == NULL) { 7115 dbuf = query_getnamebuf(client); 7116 if (dbuf == NULL) { 7117 QUERY_ERROR(DNS_R_SERVFAIL); 7118 goto cleanup; 7119 } 7120 fname = query_newname(client, dbuf, &b); 7121 if (fname == NULL) { 7122 QUERY_ERROR(DNS_R_SERVFAIL); 7123 goto cleanup; 7124 } 7125 } 7126 dns_name_copy(client->query.qname, fname, NULL); 7127 dns64 = ISC_FALSE; 7128 #ifdef dns64_bis_return_excluded_addresses 7129 /* 7130 * Resume the diverted processing of the AAAA response? 7131 */ 7132 if (dns64_excluded) 7133 break; 7134 #endif 7135 } else if (result == DNS_R_NXRRSET && 7136 !ISC_LIST_EMPTY(client->view->dns64) && 7137 client->message->rdclass == dns_rdataclass_in && 7138 qtype == dns_rdatatype_aaaa) 7139 { 7140 /* 7141 * Look to see if there are A records for this 7142 * name. 7143 */ 7144 INSIST(client->query.dns64_aaaa == NULL); 7145 INSIST(client->query.dns64_sigaaaa == NULL); 7146 client->query.dns64_aaaa = rdataset; 7147 client->query.dns64_sigaaaa = sigrdataset; 7148 client->query.dns64_ttl = dns64_ttl(db, version); 7149 query_releasename(client, &fname); 7150 dns_db_detachnode(db, &node); 7151 rdataset = NULL; 7152 sigrdataset = NULL; 7153 type = qtype = dns_rdatatype_a; 7154 rpz_st = client->query.rpz_st; 7155 if (rpz_st != NULL) { 7156 /* 7157 * Arrange for RPZ rewriting of any A records. 7158 */ 7159 if ((rpz_st->state & DNS_RPZ_REWRITTEN) != 0) 7160 is_zone = rpz_st->q.is_zone; 7161 rpz_st_clear(client); 7162 } 7163 dns64 = ISC_TRUE; 7164 goto db_find; 7165 } 7166 7167 /* 7168 * Look for a NSEC3 record if we don't have a NSEC record. 7169 */ 7170 nxrrset_rrsig: 7171 if (redirected) 7172 goto cleanup; 7173 if (!dns_rdataset_isassociated(rdataset) && 7174 WANTDNSSEC(client)) { 7175 if ((fname->attributes & DNS_NAMEATTR_WILDCARD) == 0) { 7176 dns_name_t *found; 7177 dns_name_t *qname; 7178 7179 dns_fixedname_init(&fixed); 7180 found = dns_fixedname_name(&fixed); 7181 qname = client->query.qname; 7182 7183 query_findclosestnsec3(qname, db, version, 7184 client, rdataset, 7185 sigrdataset, fname, 7186 ISC_TRUE, found); 7187 /* 7188 * Did we find the closest provable encloser 7189 * instead? If so add the nearest to the 7190 * closest provable encloser. 7191 */ 7192 if (dns_rdataset_isassociated(rdataset) && 7193 !dns_name_equal(qname, found) && 7194 !(ns_g_nonearest && 7195 qtype != dns_rdatatype_ds)) 7196 { 7197 unsigned int count; 7198 unsigned int skip; 7199 7200 /* 7201 * Add the closest provable encloser. 7202 */ 7203 query_addrrset(client, &fname, 7204 &rdataset, &sigrdataset, 7205 dbuf, 7206 DNS_SECTION_AUTHORITY); 7207 7208 count = dns_name_countlabels(found) 7209 + 1; 7210 skip = dns_name_countlabels(qname) - 7211 count; 7212 dns_name_getlabelsequence(qname, skip, 7213 count, 7214 found); 7215 7216 fixfname(client, &fname, &dbuf, &b); 7217 fixrdataset(client, &rdataset); 7218 fixrdataset(client, &sigrdataset); 7219 if (fname == NULL || 7220 rdataset == NULL || 7221 sigrdataset == NULL) { 7222 QUERY_ERROR(DNS_R_SERVFAIL); 7223 goto cleanup; 7224 } 7225 /* 7226 * 'nearest' doesn't exist so 7227 * 'exist' is set to ISC_FALSE. 7228 */ 7229 query_findclosestnsec3(found, db, 7230 version, 7231 client, 7232 rdataset, 7233 sigrdataset, 7234 fname, 7235 ISC_FALSE, 7236 NULL); 7237 } 7238 } else { 7239 query_releasename(client, &fname); 7240 query_addwildcardproof(client, db, version, 7241 client->query.qname, 7242 ISC_FALSE, ISC_TRUE); 7243 } 7244 } 7245 if (dns_rdataset_isassociated(rdataset)) { 7246 /* 7247 * If we've got a NSEC record, we need to save the 7248 * name now because we're going call query_addsoa() 7249 * below, and it needs to use the name buffer. 7250 */ 7251 query_keepname(client, fname, dbuf); 7252 } else if (fname != NULL) { 7253 /* 7254 * We're not going to use fname, and need to release 7255 * our hold on the name buffer so query_addsoa() 7256 * may use it. 7257 */ 7258 query_releasename(client, &fname); 7259 } 7260 7261 /* 7262 * Add SOA to the additional section if generated by a RPZ 7263 * rewrite. 7264 */ 7265 associated = dns_rdataset_isassociated(rdataset); 7266 section = nxrewrite ? DNS_SECTION_ADDITIONAL : 7267 DNS_SECTION_AUTHORITY; 7268 7269 result = query_addsoa(client, db, version, ISC_UINT32_MAX, 7270 associated, section); 7271 if (result != ISC_R_SUCCESS) { 7272 QUERY_ERROR(result); 7273 goto cleanup; 7274 } 7275 7276 /* 7277 * Add NSEC record if we found one. 7278 */ 7279 if (WANTDNSSEC(client)) { 7280 if (dns_rdataset_isassociated(rdataset)) 7281 query_addnxrrsetnsec(client, db, version, 7282 &fname, &rdataset, 7283 &sigrdataset); 7284 } 7285 goto cleanup; 7286 7287 case DNS_R_EMPTYWILD: 7288 empty_wild = ISC_TRUE; 7289 /* FALLTHROUGH */ 7290 7291 case DNS_R_NXDOMAIN: 7292 INSIST(is_zone); 7293 if (!empty_wild) { 7294 tresult = redirect(client, fname, rdataset, &node, 7295 &db, &version, type); 7296 if (tresult == ISC_R_SUCCESS) 7297 break; 7298 if (tresult == DNS_R_NXRRSET) { 7299 redirected = ISC_TRUE; 7300 goto iszone_nxrrset; 7301 } 7302 if (tresult == DNS_R_NCACHENXRRSET) { 7303 redirected = ISC_TRUE; 7304 is_zone = ISC_FALSE; 7305 goto ncache_nxrrset; 7306 } 7307 } 7308 if (dns_rdataset_isassociated(rdataset)) { 7309 /* 7310 * If we've got a NSEC record, we need to save the 7311 * name now because we're going call query_addsoa() 7312 * below, and it needs to use the name buffer. 7313 */ 7314 query_keepname(client, fname, dbuf); 7315 } else if (fname != NULL) { 7316 /* 7317 * We're not going to use fname, and need to release 7318 * our hold on the name buffer so query_addsoa() 7319 * may use it. 7320 */ 7321 query_releasename(client, &fname); 7322 } 7323 7324 /* 7325 * Add SOA to the additional section if generated by a 7326 * RPZ rewrite. 7327 * 7328 * If the query was for a SOA record force the 7329 * ttl to zero so that it is possible for clients to find 7330 * the containing zone of an arbitrary name with a stub 7331 * resolver and not have it cached. 7332 */ 7333 associated = dns_rdataset_isassociated(rdataset); 7334 section = nxrewrite ? DNS_SECTION_ADDITIONAL : 7335 DNS_SECTION_AUTHORITY; 7336 ttl = ISC_UINT32_MAX; 7337 if (!nxrewrite && qtype == dns_rdatatype_soa && 7338 zone != NULL && dns_zone_getzeronosoattl(zone)) 7339 ttl = 0; 7340 result = query_addsoa(client, db, version, ttl, associated, 7341 section); 7342 if (result != ISC_R_SUCCESS) { 7343 QUERY_ERROR(result); 7344 goto cleanup; 7345 } 7346 7347 if (WANTDNSSEC(client)) { 7348 /* 7349 * Add NSEC record if we found one. 7350 */ 7351 if (dns_rdataset_isassociated(rdataset)) 7352 query_addrrset(client, &fname, &rdataset, 7353 &sigrdataset, 7354 NULL, DNS_SECTION_AUTHORITY); 7355 query_addwildcardproof(client, db, version, 7356 client->query.qname, ISC_FALSE, 7357 ISC_FALSE); 7358 } 7359 7360 /* 7361 * Set message rcode. 7362 */ 7363 if (empty_wild) 7364 client->message->rcode = dns_rcode_noerror; 7365 else 7366 client->message->rcode = dns_rcode_nxdomain; 7367 goto cleanup; 7368 7369 case DNS_R_NCACHENXDOMAIN: 7370 tresult = redirect(client, fname, rdataset, &node, 7371 &db, &version, type); 7372 if (tresult == ISC_R_SUCCESS) 7373 break; 7374 if (tresult == DNS_R_NXRRSET) { 7375 redirected = ISC_TRUE; 7376 is_zone = ISC_TRUE; 7377 goto iszone_nxrrset; 7378 } 7379 if (tresult == DNS_R_NCACHENXRRSET) { 7380 redirected = ISC_TRUE; 7381 result = tresult; 7382 goto ncache_nxrrset; 7383 } 7384 /* FALLTHROUGH */ 7385 7386 case DNS_R_NCACHENXRRSET: 7387 ncache_nxrrset: 7388 INSIST(!is_zone); 7389 authoritative = ISC_FALSE; 7390 /* 7391 * Set message rcode, if required. 7392 */ 7393 if (result == DNS_R_NCACHENXDOMAIN) 7394 client->message->rcode = dns_rcode_nxdomain; 7395 /* 7396 * Look for RFC 1918 leakage from Internet. 7397 */ 7398 if (result == DNS_R_NCACHENXDOMAIN && 7399 qtype == dns_rdatatype_ptr && 7400 client->message->rdclass == dns_rdataclass_in && 7401 dns_name_countlabels(fname) == 7) 7402 warn_rfc1918(client, fname, rdataset); 7403 7404 #ifdef dns64_bis_return_excluded_addresses 7405 if (dns64) 7406 #else 7407 if (dns64 && !dns64_exclude) 7408 #endif 7409 { 7410 /* 7411 * Restore the answers from the previous AAAA lookup. 7412 */ 7413 if (rdataset != NULL) 7414 query_putrdataset(client, &rdataset); 7415 if (sigrdataset != NULL) 7416 query_putrdataset(client, &sigrdataset); 7417 rdataset = client->query.dns64_aaaa; 7418 sigrdataset = client->query.dns64_sigaaaa; 7419 client->query.dns64_aaaa = NULL; 7420 client->query.dns64_sigaaaa = NULL; 7421 if (fname == NULL) { 7422 dbuf = query_getnamebuf(client); 7423 if (dbuf == NULL) { 7424 QUERY_ERROR(DNS_R_SERVFAIL); 7425 goto cleanup; 7426 } 7427 fname = query_newname(client, dbuf, &b); 7428 if (fname == NULL) { 7429 QUERY_ERROR(DNS_R_SERVFAIL); 7430 goto cleanup; 7431 } 7432 } 7433 dns_name_copy(client->query.qname, fname, NULL); 7434 dns64 = ISC_FALSE; 7435 #ifdef dns64_bis_return_excluded_addresses 7436 if (dns64_excluded) 7437 break; 7438 #endif 7439 } else if (result == DNS_R_NCACHENXRRSET && 7440 !ISC_LIST_EMPTY(client->view->dns64) && 7441 client->message->rdclass == dns_rdataclass_in && 7442 qtype == dns_rdatatype_aaaa) 7443 { 7444 /* 7445 * Look to see if there are A records for this 7446 * name. 7447 */ 7448 INSIST(client->query.dns64_aaaa == NULL); 7449 INSIST(client->query.dns64_sigaaaa == NULL); 7450 client->query.dns64_aaaa = rdataset; 7451 client->query.dns64_sigaaaa = sigrdataset; 7452 /* 7453 * If the ttl is zero we need to workout if we have just 7454 * decremented to zero or if there was no negative cache 7455 * ttl in the answer. 7456 */ 7457 if (rdataset->ttl != 0) 7458 client->query.dns64_ttl = rdataset->ttl; 7459 else if (dns_rdataset_first(rdataset) == ISC_R_SUCCESS) 7460 client->query.dns64_ttl = 0; 7461 query_releasename(client, &fname); 7462 dns_db_detachnode(db, &node); 7463 rdataset = NULL; 7464 sigrdataset = NULL; 7465 fname = NULL; 7466 type = qtype = dns_rdatatype_a; 7467 rpz_st = client->query.rpz_st; 7468 if (rpz_st != NULL) { 7469 /* 7470 * Arrange for RPZ rewriting of any A records. 7471 */ 7472 if ((rpz_st->state & DNS_RPZ_REWRITTEN) != 0) 7473 is_zone = rpz_st->q.is_zone; 7474 rpz_st_clear(client); 7475 } 7476 dns64 = ISC_TRUE; 7477 goto db_find; 7478 } 7479 7480 /* 7481 * We don't call query_addrrset() because we don't need any 7482 * of its extra features (and things would probably break!). 7483 */ 7484 query_keepname(client, fname, dbuf); 7485 dns_message_addname(client->message, fname, 7486 DNS_SECTION_AUTHORITY); 7487 ISC_LIST_APPEND(fname->list, rdataset, link); 7488 fname = NULL; 7489 rdataset = NULL; 7490 goto cleanup; 7491 7492 case DNS_R_CNAME: 7493 /* 7494 * Keep a copy of the rdataset. We have to do this because 7495 * query_addrrset may clear 'rdataset' (to prevent the 7496 * cleanup code from cleaning it up). 7497 */ 7498 trdataset = rdataset; 7499 /* 7500 * Add the CNAME to the answer section. 7501 */ 7502 if (sigrdataset != NULL) 7503 sigrdatasetp = &sigrdataset; 7504 else 7505 sigrdatasetp = NULL; 7506 if (WANTDNSSEC(client) && 7507 (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) 7508 { 7509 dns_fixedname_init(&wildcardname); 7510 dns_name_copy(fname, dns_fixedname_name(&wildcardname), 7511 NULL); 7512 need_wildcardproof = ISC_TRUE; 7513 } 7514 if (NOQNAME(rdataset) && WANTDNSSEC(client)) 7515 noqname = rdataset; 7516 else 7517 noqname = NULL; 7518 if (!is_zone && RECURSIONOK(client)) 7519 query_prefetch(client, fname, rdataset); 7520 query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf, 7521 DNS_SECTION_ANSWER); 7522 if (noqname != NULL) 7523 query_addnoqnameproof(client, noqname); 7524 /* 7525 * We set the PARTIALANSWER attribute so that if anything goes 7526 * wrong later on, we'll return what we've got so far. 7527 */ 7528 client->query.attributes |= NS_QUERYATTR_PARTIALANSWER; 7529 /* 7530 * Reset qname to be the target name of the CNAME and restart 7531 * the query. 7532 */ 7533 tname = NULL; 7534 result = dns_message_gettempname(client->message, &tname); 7535 if (result != ISC_R_SUCCESS) 7536 goto cleanup; 7537 result = dns_rdataset_first(trdataset); 7538 if (result != ISC_R_SUCCESS) { 7539 dns_message_puttempname(client->message, &tname); 7540 goto cleanup; 7541 } 7542 dns_rdataset_current(trdataset, &rdata); 7543 result = dns_rdata_tostruct(&rdata, &cname, NULL); 7544 dns_rdata_reset(&rdata); 7545 if (result != ISC_R_SUCCESS) { 7546 dns_message_puttempname(client->message, &tname); 7547 goto cleanup; 7548 } 7549 dns_name_init(tname, NULL); 7550 result = dns_name_dup(&cname.cname, client->mctx, tname); 7551 if (result != ISC_R_SUCCESS) { 7552 dns_message_puttempname(client->message, &tname); 7553 dns_rdata_freestruct(&cname); 7554 goto cleanup; 7555 } 7556 dns_rdata_freestruct(&cname); 7557 ns_client_qnamereplace(client, tname); 7558 want_restart = ISC_TRUE; 7559 if (!WANTRECURSION(client)) 7560 options |= DNS_GETDB_NOLOG; 7561 goto addauth; 7562 case DNS_R_DNAME: 7563 /* 7564 * Compare the current qname to the found name. We need 7565 * to know how many labels and bits are in common because 7566 * we're going to have to split qname later on. 7567 */ 7568 namereln = dns_name_fullcompare(client->query.qname, fname, 7569 &order, &nlabels); 7570 INSIST(namereln == dns_namereln_subdomain); 7571 /* 7572 * Keep a copy of the rdataset. We have to do this because 7573 * query_addrrset may clear 'rdataset' (to prevent the 7574 * cleanup code from cleaning it up). 7575 */ 7576 trdataset = rdataset; 7577 /* 7578 * Add the DNAME to the answer section. 7579 */ 7580 if (sigrdataset != NULL) 7581 sigrdatasetp = &sigrdataset; 7582 else 7583 sigrdatasetp = NULL; 7584 if (WANTDNSSEC(client) && 7585 (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) 7586 { 7587 dns_fixedname_init(&wildcardname); 7588 dns_name_copy(fname, dns_fixedname_name(&wildcardname), 7589 NULL); 7590 need_wildcardproof = ISC_TRUE; 7591 } 7592 if (!is_zone && RECURSIONOK(client)) 7593 query_prefetch(client, fname, rdataset); 7594 query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf, 7595 DNS_SECTION_ANSWER); 7596 /* 7597 * We set the PARTIALANSWER attribute so that if anything goes 7598 * wrong later on, we'll return what we've got so far. 7599 */ 7600 client->query.attributes |= NS_QUERYATTR_PARTIALANSWER; 7601 /* 7602 * Get the target name of the DNAME. 7603 */ 7604 tname = NULL; 7605 result = dns_message_gettempname(client->message, &tname); 7606 if (result != ISC_R_SUCCESS) 7607 goto cleanup; 7608 result = dns_rdataset_first(trdataset); 7609 if (result != ISC_R_SUCCESS) { 7610 dns_message_puttempname(client->message, &tname); 7611 goto cleanup; 7612 } 7613 dns_rdataset_current(trdataset, &rdata); 7614 result = dns_rdata_tostruct(&rdata, &dname, NULL); 7615 dns_rdata_reset(&rdata); 7616 if (result != ISC_R_SUCCESS) { 7617 dns_message_puttempname(client->message, &tname); 7618 goto cleanup; 7619 } 7620 dns_name_clone(&dname.dname, tname); 7621 dns_rdata_freestruct(&dname); 7622 /* 7623 * Construct the new qname consisting of 7624 * <found name prefix>.<dname target> 7625 */ 7626 dns_fixedname_init(&fixed); 7627 prefix = dns_fixedname_name(&fixed); 7628 dns_name_split(client->query.qname, nlabels, prefix, NULL); 7629 INSIST(fname == NULL); 7630 dbuf = query_getnamebuf(client); 7631 if (dbuf == NULL) { 7632 dns_message_puttempname(client->message, &tname); 7633 goto cleanup; 7634 } 7635 fname = query_newname(client, dbuf, &b); 7636 if (fname == NULL) { 7637 dns_message_puttempname(client->message, &tname); 7638 goto cleanup; 7639 } 7640 result = dns_name_concatenate(prefix, tname, fname, NULL); 7641 dns_message_puttempname(client->message, &tname); 7642 7643 /* 7644 * RFC2672, section 4.1, subsection 3c says 7645 * we should return YXDOMAIN if the constructed 7646 * name would be too long. 7647 */ 7648 if (result == DNS_R_NAMETOOLONG) 7649 client->message->rcode = dns_rcode_yxdomain; 7650 if (result != ISC_R_SUCCESS) 7651 goto cleanup; 7652 7653 query_keepname(client, fname, dbuf); 7654 /* 7655 * Synthesize a CNAME consisting of 7656 * <old qname> <dname ttl> CNAME <new qname> 7657 * with <dname trust value> 7658 * 7659 * Synthesize a CNAME so old old clients that don't understand 7660 * DNAME can chain. 7661 * 7662 * We do not try to synthesize a signature because we hope 7663 * that security aware servers will understand DNAME. Also, 7664 * even if we had an online key, making a signature 7665 * on-the-fly is costly, and not really legitimate anyway 7666 * since the synthesized CNAME is NOT in the zone. 7667 */ 7668 result = query_add_cname(client, client->query.qname, fname, 7669 trdataset->trust, trdataset->ttl); 7670 if (result != ISC_R_SUCCESS) 7671 goto cleanup; 7672 /* 7673 * Switch to the new qname and restart. 7674 */ 7675 ns_client_qnamereplace(client, fname); 7676 fname = NULL; 7677 want_restart = ISC_TRUE; 7678 if (!WANTRECURSION(client)) 7679 options |= DNS_GETDB_NOLOG; 7680 goto addauth; 7681 default: 7682 /* 7683 * Something has gone wrong. 7684 */ 7685 QUERY_ERROR(DNS_R_SERVFAIL); 7686 goto cleanup; 7687 } 7688 7689 if (WANTDNSSEC(client) && 7690 (fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) 7691 { 7692 dns_fixedname_init(&wildcardname); 7693 dns_name_copy(fname, dns_fixedname_name(&wildcardname), NULL); 7694 need_wildcardproof = ISC_TRUE; 7695 } 7696 7697 #ifdef ALLOW_FILTER_AAAA 7698 /* 7699 * The filter-aaaa-on-v4 option should suppress AAAAs for IPv4 7700 * clients if there is an A; filter-aaaa-on-v6 option does the same 7701 * for IPv6 clients. 7702 */ 7703 client->filter_aaaa = dns_aaaa_ok; 7704 if (client->view->v4_aaaa != dns_aaaa_ok || 7705 client->view->v6_aaaa != dns_aaaa_ok) 7706 { 7707 result = ns_client_checkaclsilent(client, NULL, 7708 client->view->aaaa_acl, 7709 ISC_TRUE); 7710 if (result == ISC_R_SUCCESS && 7711 client->view->v4_aaaa != dns_aaaa_ok && 7712 is_v4_client(client)) 7713 client->filter_aaaa = client->view->v4_aaaa; 7714 else if (result == ISC_R_SUCCESS && 7715 client->view->v6_aaaa != dns_aaaa_ok && 7716 is_v6_client(client)) 7717 client->filter_aaaa = client->view->v6_aaaa; 7718 } 7719 7720 #endif 7721 7722 if (type == dns_rdatatype_any) { 7723 #ifdef ALLOW_FILTER_AAAA 7724 isc_boolean_t have_aaaa, have_a, have_sig; 7725 7726 /* 7727 * If we are not authoritative, assume there is a A 7728 * even in if it is not in our cache. This assumption could 7729 * be wrong but it is a good bet. 7730 */ 7731 have_aaaa = ISC_FALSE; 7732 have_a = !authoritative; 7733 have_sig = ISC_FALSE; 7734 #endif 7735 /* 7736 * XXXRTH Need to handle zonecuts with special case 7737 * code. 7738 */ 7739 n = 0; 7740 rdsiter = NULL; 7741 result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); 7742 if (result != ISC_R_SUCCESS) { 7743 QUERY_ERROR(DNS_R_SERVFAIL); 7744 goto cleanup; 7745 } 7746 7747 /* 7748 * Calling query_addrrset() with a non-NULL dbuf is going 7749 * to either keep or release the name. We don't want it to 7750 * release fname, since we may have to call query_addrrset() 7751 * more than once. That means we have to call query_keepname() 7752 * now, and pass a NULL dbuf to query_addrrset(). 7753 * 7754 * If we do a query_addrrset() below, we must set fname to 7755 * NULL before leaving this block, otherwise we might try to 7756 * cleanup fname even though we're using it! 7757 */ 7758 query_keepname(client, fname, dbuf); 7759 tname = fname; 7760 result = dns_rdatasetiter_first(rdsiter); 7761 while (result == ISC_R_SUCCESS) { 7762 dns_rdatasetiter_current(rdsiter, rdataset); 7763 #ifdef ALLOW_FILTER_AAAA 7764 /* 7765 * Notice the presence of A and AAAAs so 7766 * that AAAAs can be hidden from IPv4 clients. 7767 */ 7768 if (client->filter_aaaa != dns_aaaa_ok) { 7769 if (rdataset->type == dns_rdatatype_aaaa) 7770 have_aaaa = ISC_TRUE; 7771 else if (rdataset->type == dns_rdatatype_a) 7772 have_a = ISC_TRUE; 7773 } 7774 #endif 7775 if (is_zone && qtype == dns_rdatatype_any && 7776 !dns_db_issecure(db) && 7777 dns_rdatatype_isdnssec(rdataset->type)) { 7778 /* 7779 * The zone is transitioning from insecure 7780 * to secure. Hide the dnssec records from 7781 * ANY queries. 7782 */ 7783 dns_rdataset_disassociate(rdataset); 7784 } else if ((qtype == dns_rdatatype_any || 7785 rdataset->type == qtype) && rdataset->type != 0) { 7786 #ifdef ALLOW_FILTER_AAAA 7787 if (dns_rdatatype_isdnssec(rdataset->type)) 7788 have_sig = ISC_TRUE; 7789 #endif 7790 if (NOQNAME(rdataset) && WANTDNSSEC(client)) 7791 noqname = rdataset; 7792 else 7793 noqname = NULL; 7794 rpz_st = client->query.rpz_st; 7795 if (rpz_st != NULL) 7796 rdataset->ttl = ISC_MIN(rdataset->ttl, 7797 rpz_st->m.ttl); 7798 if (!is_zone && RECURSIONOK(client)) { 7799 dns_name_t *name; 7800 name = (fname != NULL) ? fname : tname; 7801 query_prefetch(client, name, rdataset); 7802 } 7803 query_addrrset(client, 7804 fname != NULL ? &fname : &tname, 7805 &rdataset, NULL, 7806 NULL, DNS_SECTION_ANSWER); 7807 if (noqname != NULL) 7808 query_addnoqnameproof(client, noqname); 7809 n++; 7810 INSIST(tname != NULL); 7811 /* 7812 * rdataset is non-NULL only in certain 7813 * pathological cases involving DNAMEs. 7814 */ 7815 if (rdataset != NULL) 7816 query_putrdataset(client, &rdataset); 7817 rdataset = query_newrdataset(client); 7818 if (rdataset == NULL) 7819 break; 7820 } else { 7821 /* 7822 * We're not interested in this rdataset. 7823 */ 7824 dns_rdataset_disassociate(rdataset); 7825 } 7826 result = dns_rdatasetiter_next(rdsiter); 7827 } 7828 7829 #ifdef ALLOW_FILTER_AAAA 7830 /* 7831 * Filter AAAAs if there is an A and there is no signature 7832 * or we are supposed to break DNSSEC. 7833 */ 7834 if (client->filter_aaaa == dns_aaaa_break_dnssec) 7835 client->attributes |= NS_CLIENTATTR_FILTER_AAAA; 7836 else if (client->filter_aaaa != dns_aaaa_ok && 7837 have_aaaa && have_a && 7838 (!have_sig || !WANTDNSSEC(client))) 7839 client->attributes |= NS_CLIENTATTR_FILTER_AAAA; 7840 #endif 7841 if (fname != NULL) 7842 dns_message_puttempname(client->message, &fname); 7843 7844 if (n == 0) { 7845 /* 7846 * No matching rdatasets found in cache. If we were 7847 * searching for RRSIG/SIG, that's probably okay; 7848 * otherwise this is an error condition. 7849 */ 7850 if ((qtype == dns_rdatatype_rrsig || 7851 qtype == dns_rdatatype_sig) && 7852 result == ISC_R_NOMORE) { 7853 if (!is_zone) { 7854 authoritative = ISC_FALSE; 7855 dns_rdatasetiter_destroy(&rdsiter); 7856 client->attributes &= ~NS_CLIENTATTR_RA; 7857 goto addauth; 7858 } 7859 7860 if (qtype == dns_rdatatype_rrsig && 7861 dns_db_issecure(db)) { 7862 char namebuf[DNS_NAME_FORMATSIZE]; 7863 dns_name_format(client->query.qname, 7864 namebuf, 7865 sizeof(namebuf)); 7866 ns_client_log(client, 7867 DNS_LOGCATEGORY_DNSSEC, 7868 NS_LOGMODULE_QUERY, 7869 ISC_LOG_WARNING, 7870 "missing signature " 7871 "for %s", namebuf); 7872 } 7873 7874 dns_rdatasetiter_destroy(&rdsiter); 7875 fname = query_newname(client, dbuf, &b); 7876 goto nxrrset_rrsig; 7877 } else 7878 result = DNS_R_SERVFAIL; 7879 } 7880 7881 dns_rdatasetiter_destroy(&rdsiter); 7882 if (result != ISC_R_NOMORE) { 7883 QUERY_ERROR(DNS_R_SERVFAIL); 7884 goto cleanup; 7885 } 7886 } else { 7887 /* 7888 * This is the "normal" case -- an ordinary question to which 7889 * we know the answer. 7890 */ 7891 7892 #ifdef ALLOW_FILTER_AAAA 7893 /* 7894 * Optionally hide AAAAs from IPv4 clients if there is an A. 7895 * We add the AAAAs now, but might refuse to render them later 7896 * after DNSSEC is figured out. 7897 * This could be more efficient, but the whole idea is 7898 * so fundamentally wrong, unavoidably inaccurate, and 7899 * unneeded that it is best to keep it as short as possible. 7900 */ 7901 if (client->filter_aaaa == dns_aaaa_break_dnssec || 7902 (client->filter_aaaa == dns_aaaa_filter && 7903 (!WANTDNSSEC(client) || sigrdataset == NULL || 7904 !dns_rdataset_isassociated(sigrdataset)))) 7905 { 7906 if (qtype == dns_rdatatype_aaaa) { 7907 trdataset = query_newrdataset(client); 7908 result = dns_db_findrdataset(db, node, version, 7909 dns_rdatatype_a, 0, 7910 client->now, 7911 trdataset, NULL); 7912 if (dns_rdataset_isassociated(trdataset)) 7913 dns_rdataset_disassociate(trdataset); 7914 query_putrdataset(client, &trdataset); 7915 7916 /* 7917 * We have an AAAA but the A is not in our cache. 7918 * Assume any result other than DNS_R_DELEGATION 7919 * or ISC_R_NOTFOUND means there is no A and 7920 * so AAAAs are ok. 7921 * Assume there is no A if we can't recurse 7922 * for this client, although that could be 7923 * the wrong answer. What else can we do? 7924 * Besides, that we have the AAAA and are using 7925 * this mechanism suggests that we care more 7926 * about As than AAAAs and would have cached 7927 * the A if it existed. 7928 */ 7929 if (result == ISC_R_SUCCESS) { 7930 client->attributes |= 7931 NS_CLIENTATTR_FILTER_AAAA; 7932 7933 } else if (authoritative || 7934 !RECURSIONOK(client) || 7935 (result != DNS_R_DELEGATION && 7936 result != ISC_R_NOTFOUND)) { 7937 client->attributes &= 7938 ~NS_CLIENTATTR_FILTER_AAAA; 7939 } else { 7940 /* 7941 * This is an ugly kludge to recurse 7942 * for the A and discard the result. 7943 * 7944 * Continue to add the AAAA now. 7945 * We'll make a note to not render it 7946 * if the recursion for the A succeeds. 7947 */ 7948 result = query_recurse(client, 7949 dns_rdatatype_a, 7950 client->query.qname, 7951 NULL, NULL, resuming); 7952 if (result == ISC_R_SUCCESS) { 7953 client->attributes |= 7954 NS_CLIENTATTR_FILTER_AAAA_RC; 7955 client->query.attributes |= 7956 NS_QUERYATTR_RECURSING; 7957 } 7958 } 7959 7960 } else if (qtype == dns_rdatatype_a && 7961 (client->attributes & 7962 NS_CLIENTATTR_FILTER_AAAA_RC) != 0) { 7963 client->attributes &= 7964 ~NS_CLIENTATTR_FILTER_AAAA_RC; 7965 client->attributes |= 7966 NS_CLIENTATTR_FILTER_AAAA; 7967 dns_rdataset_disassociate(rdataset); 7968 if (sigrdataset != NULL && 7969 dns_rdataset_isassociated(sigrdataset)) 7970 dns_rdataset_disassociate(sigrdataset); 7971 goto cleanup; 7972 } 7973 } 7974 #endif 7975 /* 7976 * Check to see if the AAAA RRset has non-excluded addresses 7977 * in it. If not look for a A RRset. 7978 */ 7979 INSIST(client->query.dns64_aaaaok == NULL); 7980 7981 if (qtype == dns_rdatatype_aaaa && !dns64_exclude && 7982 !ISC_LIST_EMPTY(client->view->dns64) && 7983 client->message->rdclass == dns_rdataclass_in && 7984 !dns64_aaaaok(client, rdataset, sigrdataset)) { 7985 /* 7986 * Look to see if there are A records for this 7987 * name. 7988 */ 7989 client->query.dns64_aaaa = rdataset; 7990 client->query.dns64_sigaaaa = sigrdataset; 7991 client->query.dns64_ttl = rdataset->ttl; 7992 query_releasename(client, &fname); 7993 dns_db_detachnode(db, &node); 7994 rdataset = NULL; 7995 sigrdataset = NULL; 7996 type = qtype = dns_rdatatype_a; 7997 rpz_st = client->query.rpz_st; 7998 if (rpz_st != NULL) { 7999 /* 8000 * Arrange for RPZ rewriting of any A records. 8001 */ 8002 if ((rpz_st->state & DNS_RPZ_REWRITTEN) != 0) 8003 is_zone = rpz_st->q.is_zone; 8004 rpz_st_clear(client); 8005 } 8006 dns64_exclude = dns64 = ISC_TRUE; 8007 goto db_find; 8008 } 8009 8010 if (sigrdataset != NULL) 8011 sigrdatasetp = &sigrdataset; 8012 else 8013 sigrdatasetp = NULL; 8014 if (NOQNAME(rdataset) && WANTDNSSEC(client)) 8015 noqname = rdataset; 8016 else 8017 noqname = NULL; 8018 /* 8019 * BIND 8 priming queries need the additional section. 8020 */ 8021 if (is_zone && qtype == dns_rdatatype_ns && 8022 dns_name_equal(client->query.qname, dns_rootname)) 8023 client->query.attributes &= ~NS_QUERYATTR_NOADDITIONAL; 8024 8025 /* 8026 * Return the time to expire for slave zones. 8027 */ 8028 if (zone != NULL) { 8029 dns_zone_t *raw = NULL, *mayberaw; 8030 8031 if (is_zone) 8032 dns_zone_getraw(zone, &raw); 8033 mayberaw = (raw != NULL) ? raw : zone; 8034 8035 if (is_zone && qtype == dns_rdatatype_soa && 8036 ((client->attributes & 8037 NS_CLIENTATTR_WANTEXPIRE) != 0) && 8038 client->query.restarts == 0 && 8039 dns_zone_gettype(mayberaw) == dns_zone_slave) 8040 { 8041 isc_time_t expiretime; 8042 isc_uint32_t secs; 8043 dns_zone_getexpiretime(zone, &expiretime); 8044 secs = isc_time_seconds(&expiretime); 8045 if (secs >= client->now && 8046 result == ISC_R_SUCCESS) { 8047 client->attributes |= 8048 NS_CLIENTATTR_HAVEEXPIRE; 8049 client->expire = secs - client->now; 8050 } 8051 } 8052 if (raw != NULL) 8053 dns_zone_detach(&raw); 8054 } 8055 8056 if (dns64) { 8057 qtype = type = dns_rdatatype_aaaa; 8058 result = query_dns64(client, &fname, rdataset, 8059 sigrdataset, dbuf, 8060 DNS_SECTION_ANSWER); 8061 dns_rdataset_disassociate(rdataset); 8062 dns_message_puttemprdataset(client->message, &rdataset); 8063 if (result == ISC_R_NOMORE) { 8064 #ifndef dns64_bis_return_excluded_addresses 8065 if (dns64_exclude) { 8066 if (!is_zone) 8067 goto cleanup; 8068 /* 8069 * Add a fake SOA record. 8070 */ 8071 (void)query_addsoa(client, db, version, 8072 600, ISC_FALSE, 8073 DNS_SECTION_AUTHORITY); 8074 goto cleanup; 8075 } 8076 #endif 8077 if (is_zone) 8078 goto iszone_nxrrset; 8079 else 8080 goto ncache_nxrrset; 8081 } else if (result != ISC_R_SUCCESS) { 8082 eresult = result; 8083 goto cleanup; 8084 } 8085 } else if (client->query.dns64_aaaaok != NULL) { 8086 query_filter64(client, &fname, rdataset, dbuf, 8087 DNS_SECTION_ANSWER); 8088 query_putrdataset(client, &rdataset); 8089 } else { 8090 if (!is_zone && RECURSIONOK(client)) 8091 query_prefetch(client, fname, rdataset); 8092 query_addrrset(client, &fname, &rdataset, 8093 sigrdatasetp, dbuf, DNS_SECTION_ANSWER); 8094 } 8095 8096 if (noqname != NULL) 8097 query_addnoqnameproof(client, noqname); 8098 /* 8099 * We shouldn't ever fail to add 'rdataset' 8100 * because it's already in the answer. 8101 */ 8102 INSIST(rdataset == NULL); 8103 } 8104 8105 addauth: 8106 CTRACE("query_find: addauth"); 8107 /* 8108 * Add NS records to the authority section (if we haven't already 8109 * added them to the answer section). 8110 */ 8111 if (!want_restart && !NOAUTHORITY(client)) { 8112 if (is_zone) { 8113 if (!((qtype == dns_rdatatype_ns || 8114 qtype == dns_rdatatype_any) && 8115 dns_name_equal(client->query.qname, 8116 dns_db_origin(db)))) 8117 (void)query_addns(client, db, version); 8118 } else if (qtype != dns_rdatatype_ns) { 8119 if (fname != NULL) 8120 query_releasename(client, &fname); 8121 query_addbestns(client); 8122 } 8123 } 8124 8125 /* 8126 * Add NSEC records to the authority section if they're needed for 8127 * DNSSEC wildcard proofs. 8128 */ 8129 if (need_wildcardproof && dns_db_issecure(db)) 8130 query_addwildcardproof(client, db, version, 8131 dns_fixedname_name(&wildcardname), 8132 ISC_TRUE, ISC_FALSE); 8133 cleanup: 8134 CTRACE("query_find: cleanup"); 8135 /* 8136 * General cleanup. 8137 */ 8138 rpz_st = client->query.rpz_st; 8139 if (rpz_st != NULL && (rpz_st->state & DNS_RPZ_RECURSING) == 0) { 8140 rpz_match_clear(rpz_st); 8141 rpz_st->state &= ~DNS_RPZ_DONE_QNAME; 8142 } 8143 if (rdataset != NULL) 8144 query_putrdataset(client, &rdataset); 8145 if (sigrdataset != NULL) 8146 query_putrdataset(client, &sigrdataset); 8147 if (fname != NULL) 8148 query_releasename(client, &fname); 8149 if (node != NULL) 8150 dns_db_detachnode(db, &node); 8151 if (db != NULL) 8152 dns_db_detach(&db); 8153 if (zone != NULL) 8154 dns_zone_detach(&zone); 8155 if (zdb != NULL) { 8156 query_putrdataset(client, &zrdataset); 8157 if (zsigrdataset != NULL) 8158 query_putrdataset(client, &zsigrdataset); 8159 if (zfname != NULL) 8160 query_releasename(client, &zfname); 8161 dns_db_detach(&zdb); 8162 } 8163 if (event != NULL) 8164 isc_event_free(ISC_EVENT_PTR(&event)); 8165 8166 /* 8167 * AA bit. 8168 */ 8169 if (client->query.restarts == 0 && !authoritative) { 8170 /* 8171 * We're not authoritative, so we must ensure the AA bit 8172 * isn't set. 8173 */ 8174 client->message->flags &= ~DNS_MESSAGEFLAG_AA; 8175 } 8176 8177 /* 8178 * Restart the query? 8179 */ 8180 if (want_restart && client->query.restarts < MAX_RESTARTS) { 8181 client->query.restarts++; 8182 goto restart; 8183 } 8184 8185 if (eresult != ISC_R_SUCCESS && 8186 (!PARTIALANSWER(client) || WANTRECURSION(client) 8187 || eresult == DNS_R_DROP)) { 8188 if (eresult == DNS_R_DUPLICATE || eresult == DNS_R_DROP) { 8189 /* 8190 * This was a duplicate query that we are 8191 * recursing on or the result of rate limiting. 8192 * Don't send a response now for a duplicate query, 8193 * because the original will still cause a response. 8194 */ 8195 query_next(client, eresult); 8196 } else { 8197 /* 8198 * If we don't have any answer to give the client, 8199 * or if the client requested recursion and thus wanted 8200 * the complete answer, send an error response. 8201 */ 8202 INSIST(line >= 0); 8203 query_error(client, eresult, line); 8204 } 8205 ns_client_detach(&client); 8206 } else if (!RECURSING(client)) { 8207 /* 8208 * We are done. Set up sortlist data for the message 8209 * rendering code, make a final tweak to the AA bit if the 8210 * auth-nxdomain config option says so, then render and 8211 * send the response. 8212 */ 8213 setup_query_sortlist(client); 8214 8215 /* 8216 * If this is a referral and the answer to the question 8217 * is in the glue sort it to the start of the additional 8218 * section. 8219 */ 8220 if (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER]) && 8221 client->message->rcode == dns_rcode_noerror && 8222 (qtype == dns_rdatatype_a || qtype == dns_rdatatype_aaaa)) 8223 answer_in_glue(client, qtype); 8224 8225 if (client->message->rcode == dns_rcode_nxdomain && 8226 client->view->auth_nxdomain == ISC_TRUE) 8227 client->message->flags |= DNS_MESSAGEFLAG_AA; 8228 8229 /* 8230 * If the response is somehow unexpected for the client and this 8231 * is a result of recursion, return an error to the caller 8232 * to indicate it may need to be logged. 8233 */ 8234 if (resuming && 8235 (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER]) || 8236 client->message->rcode != dns_rcode_noerror)) 8237 eresult = ISC_R_FAILURE; 8238 8239 query_send(client); 8240 ns_client_detach(&client); 8241 } 8242 CTRACE("query_find: done"); 8243 8244 return (eresult); 8245 } 8246 8247 static inline void 8248 log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) { 8249 char namebuf[DNS_NAME_FORMATSIZE]; 8250 char typename[DNS_RDATATYPE_FORMATSIZE]; 8251 char classname[DNS_RDATACLASS_FORMATSIZE]; 8252 char onbuf[ISC_NETADDR_FORMATSIZE]; 8253 dns_rdataset_t *rdataset; 8254 int level = ISC_LOG_INFO; 8255 8256 if (! isc_log_wouldlog(ns_g_lctx, level)) 8257 return; 8258 8259 rdataset = ISC_LIST_HEAD(client->query.qname->list); 8260 INSIST(rdataset != NULL); 8261 dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); 8262 dns_rdataclass_format(rdataset->rdclass, classname, sizeof(classname)); 8263 dns_rdatatype_format(rdataset->type, typename, sizeof(typename)); 8264 isc_netaddr_format(&client->destaddr, onbuf, sizeof(onbuf)); 8265 8266 ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY, 8267 level, "query: %s %s %s %s%s%s%s%s%s (%s)", namebuf, 8268 classname, typename, WANTRECURSION(client) ? "+" : "-", 8269 (client->signer != NULL) ? "S" : "", 8270 (client->ednsversion >= 0) ? "E" : "", 8271 ((client->attributes & NS_CLIENTATTR_TCP) != 0) ? 8272 "T" : "", 8273 ((extflags & DNS_MESSAGEEXTFLAG_DO) != 0) ? "D" : "", 8274 ((flags & DNS_MESSAGEFLAG_CD) != 0) ? "C" : "", 8275 onbuf); 8276 } 8277 8278 static inline void 8279 log_queryerror(ns_client_t *client, isc_result_t result, int line, int level) { 8280 char namebuf[DNS_NAME_FORMATSIZE]; 8281 char typename[DNS_RDATATYPE_FORMATSIZE]; 8282 char classname[DNS_RDATACLASS_FORMATSIZE]; 8283 const char *namep, *typep, *classp, *sep1, *sep2; 8284 dns_rdataset_t *rdataset; 8285 8286 if (!isc_log_wouldlog(ns_g_lctx, level)) 8287 return; 8288 8289 namep = typep = classp = sep1 = sep2 = ""; 8290 8291 /* 8292 * Query errors can happen for various reasons. In some cases we cannot 8293 * even assume the query contains a valid question section, so we should 8294 * expect exceptional cases. 8295 */ 8296 if (client->query.origqname != NULL) { 8297 dns_name_format(client->query.origqname, namebuf, 8298 sizeof(namebuf)); 8299 namep = namebuf; 8300 sep1 = " for "; 8301 8302 rdataset = ISC_LIST_HEAD(client->query.origqname->list); 8303 if (rdataset != NULL) { 8304 dns_rdataclass_format(rdataset->rdclass, classname, 8305 sizeof(classname)); 8306 classp = classname; 8307 dns_rdatatype_format(rdataset->type, typename, 8308 sizeof(typename)); 8309 typep = typename; 8310 sep2 = "/"; 8311 } 8312 } 8313 8314 ns_client_log(client, NS_LOGCATEGORY_QUERY_EERRORS, NS_LOGMODULE_QUERY, 8315 level, "query failed (%s)%s%s%s%s%s%s at %s:%d", 8316 isc_result_totext(result), sep1, namep, sep2, 8317 classp, sep2, typep, __FILE__, line); 8318 } 8319 8320 void 8321 ns_query_start(ns_client_t *client) { 8322 isc_result_t result; 8323 dns_message_t *message = client->message; 8324 dns_rdataset_t *rdataset; 8325 ns_client_t *qclient; 8326 dns_rdatatype_t qtype; 8327 unsigned int saved_extflags = client->extflags; 8328 unsigned int saved_flags = client->message->flags; 8329 8330 CTRACE("ns_query_start"); 8331 8332 /* 8333 * Test only. 8334 */ 8335 if (ns_g_clienttest && (client->attributes & NS_CLIENTATTR_TCP) == 0) 8336 RUNTIME_CHECK(ns_client_replace(client) == ISC_R_SUCCESS); 8337 8338 /* 8339 * Ensure that appropriate cleanups occur. 8340 */ 8341 client->next = query_next_callback; 8342 8343 /* 8344 * Behave as if we don't support DNSSEC if not enabled. 8345 */ 8346 if (!client->view->enablednssec) { 8347 message->flags &= ~DNS_MESSAGEFLAG_CD; 8348 client->extflags &= ~DNS_MESSAGEEXTFLAG_DO; 8349 } 8350 8351 if ((message->flags & DNS_MESSAGEFLAG_RD) != 0) 8352 client->query.attributes |= NS_QUERYATTR_WANTRECURSION; 8353 8354 if ((client->extflags & DNS_MESSAGEEXTFLAG_DO) != 0) 8355 client->attributes |= NS_CLIENTATTR_WANTDNSSEC; 8356 8357 if (client->view->minimalresponses) 8358 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | 8359 NS_QUERYATTR_NOADDITIONAL); 8360 8361 if ((client->view->cachedb == NULL) 8362 || (!client->view->additionalfromcache)) { 8363 /* 8364 * We don't have a cache. Turn off cache support and 8365 * recursion. 8366 */ 8367 client->query.attributes &= 8368 ~(NS_QUERYATTR_RECURSIONOK|NS_QUERYATTR_CACHEOK); 8369 } else if ((client->attributes & NS_CLIENTATTR_RA) == 0 || 8370 (message->flags & DNS_MESSAGEFLAG_RD) == 0) { 8371 /* 8372 * If the client isn't allowed to recurse (due to 8373 * "recursion no", the allow-recursion ACL, or the 8374 * lack of a resolver in this view), or if it 8375 * doesn't want recursion, turn recursion off. 8376 */ 8377 client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK; 8378 } 8379 8380 /* 8381 * Get the question name. 8382 */ 8383 result = dns_message_firstname(message, DNS_SECTION_QUESTION); 8384 if (result != ISC_R_SUCCESS) { 8385 query_error(client, result, __LINE__); 8386 return; 8387 } 8388 dns_message_currentname(message, DNS_SECTION_QUESTION, 8389 &client->query.qname); 8390 client->query.origqname = client->query.qname; 8391 result = dns_message_nextname(message, DNS_SECTION_QUESTION); 8392 if (result != ISC_R_NOMORE) { 8393 if (result == ISC_R_SUCCESS) { 8394 /* 8395 * There's more than one QNAME in the question 8396 * section. 8397 */ 8398 query_error(client, DNS_R_FORMERR, __LINE__); 8399 } else 8400 query_error(client, result, __LINE__); 8401 return; 8402 } 8403 8404 if (ns_g_server->log_queries) 8405 log_query(client, saved_flags, saved_extflags); 8406 8407 /* 8408 * Check for multiple question queries, since edns1 is dead. 8409 */ 8410 if (message->counts[DNS_SECTION_QUESTION] > 1) { 8411 query_error(client, DNS_R_FORMERR, __LINE__); 8412 return; 8413 } 8414 8415 /* 8416 * Check for meta-queries like IXFR and AXFR. 8417 */ 8418 rdataset = ISC_LIST_HEAD(client->query.qname->list); 8419 INSIST(rdataset != NULL); 8420 qtype = rdataset->type; 8421 dns_rdatatypestats_increment(ns_g_server->rcvquerystats, qtype); 8422 8423 if (dns_rdatatype_ismeta(qtype)) { 8424 switch (qtype) { 8425 case dns_rdatatype_any: 8426 break; /* Let query_find handle it. */ 8427 case dns_rdatatype_ixfr: 8428 case dns_rdatatype_axfr: 8429 ns_xfr_start(client, rdataset->type); 8430 return; 8431 case dns_rdatatype_maila: 8432 case dns_rdatatype_mailb: 8433 query_error(client, DNS_R_NOTIMP, __LINE__); 8434 return; 8435 case dns_rdatatype_tkey: 8436 result = dns_tkey_processquery(client->message, 8437 ns_g_server->tkeyctx, 8438 client->view->dynamickeys); 8439 if (result == ISC_R_SUCCESS) 8440 query_send(client); 8441 else 8442 query_error(client, result, __LINE__); 8443 return; 8444 default: /* TSIG, etc. */ 8445 query_error(client, DNS_R_FORMERR, __LINE__); 8446 return; 8447 } 8448 } 8449 8450 /* 8451 * Turn on minimal response for DNSKEY and DS queries. 8452 */ 8453 if (qtype == dns_rdatatype_dnskey || qtype == dns_rdatatype_ds) 8454 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | 8455 NS_QUERYATTR_NOADDITIONAL); 8456 8457 /* 8458 * Turn on minimal responses for EDNS/UDP bufsize 512 queries. 8459 */ 8460 if (client->ednsversion >= 0 && client->udpsize <= 512U && 8461 (client->attributes & NS_CLIENTATTR_TCP) == 0) 8462 client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | 8463 NS_QUERYATTR_NOADDITIONAL); 8464 8465 /* 8466 * If the client has requested that DNSSEC checking be disabled, 8467 * allow lookups to return pending data and instruct the resolver 8468 * to return data before validation has completed. 8469 * 8470 * We don't need to set DNS_DBFIND_PENDINGOK when validation is 8471 * disabled as there will be no pending data. 8472 */ 8473 if (message->flags & DNS_MESSAGEFLAG_CD || 8474 qtype == dns_rdatatype_rrsig) 8475 { 8476 client->query.dboptions |= DNS_DBFIND_PENDINGOK; 8477 client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE; 8478 } else if (!client->view->enablevalidation) 8479 client->query.fetchoptions |= DNS_FETCHOPT_NOVALIDATE; 8480 8481 /* 8482 * Allow glue NS records to be added to the authority section 8483 * if the answer is secure. 8484 */ 8485 if (message->flags & DNS_MESSAGEFLAG_CD) 8486 client->query.attributes &= ~NS_QUERYATTR_SECURE; 8487 8488 /* 8489 * Set NS_CLIENTATTR_WANTDNSSEC if the client has set AD in the query. 8490 * This allows AD to be returned on queries without DO set. 8491 */ 8492 if ((message->flags & DNS_MESSAGEFLAG_AD) != 0) 8493 client->attributes |= NS_CLIENTATTR_WANTAD; 8494 8495 /* 8496 * This is an ordinary query. 8497 */ 8498 result = dns_message_reply(message, ISC_TRUE); 8499 if (result != ISC_R_SUCCESS) { 8500 query_next(client, result); 8501 return; 8502 } 8503 8504 /* 8505 * Assume authoritative response until it is known to be 8506 * otherwise. 8507 * 8508 * If "-T noaa" has been set on the command line don't set 8509 * AA on authoritative answers. 8510 */ 8511 if (!ns_g_noaa) 8512 message->flags |= DNS_MESSAGEFLAG_AA; 8513 8514 /* 8515 * Set AD. We must clear it if we add non-validated data to a 8516 * response. 8517 */ 8518 if (WANTDNSSEC(client) || WANTAD(client)) 8519 message->flags |= DNS_MESSAGEFLAG_AD; 8520 8521 qclient = NULL; 8522 ns_client_attach(client, &qclient); 8523 (void)query_find(qclient, NULL, qtype); 8524 } 8525