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