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