PageRenderTime 86ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/contrib/bind9/bin/named/query.c

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