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