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