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