Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / lib / dns / nsec3.c
blob1eb83b6b245a0ccd40c90884457ad24285f87be1
1 /* $NetBSD: nsec3.c,v 1.11 2015/07/08 17:28:58 christos Exp $ */
3 /*
4 * Copyright (C) 2006, 2008-2015 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
19 /* Id */
21 #include <config.h>
23 #include <isc/base32.h>
24 #include <isc/buffer.h>
25 #include <isc/hex.h>
26 #include <isc/iterated_hash.h>
27 #include <isc/log.h>
28 #include <isc/string.h>
29 #include <isc/util.h>
31 #include <dst/dst.h>
33 #include <dns/db.h>
34 #include <dns/zone.h>
35 #include <dns/compress.h>
36 #include <dns/dbiterator.h>
37 #include <dns/diff.h>
38 #include <dns/fixedname.h>
39 #include <dns/nsec.h>
40 #include <dns/nsec3.h>
41 #include <dns/rdata.h>
42 #include <dns/rdatalist.h>
43 #include <dns/rdataset.h>
44 #include <dns/rdatasetiter.h>
45 #include <dns/rdatastruct.h>
46 #include <dns/result.h>
48 #define CHECK(x) do { \
49 result = (x); \
50 if (result != ISC_R_SUCCESS) \
51 goto failure; \
52 } while (/*CONSTCOND*/0)
54 #define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
55 #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
56 #define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0)
57 #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
59 isc_result_t
60 dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
61 dns_dbnode_t *node, unsigned int hashalg,
62 unsigned int flags, unsigned int iterations,
63 const unsigned char *salt, size_t salt_length,
64 const unsigned char *nexthash, size_t hash_length,
65 unsigned char *buffer, dns_rdata_t *rdata)
67 isc_result_t result;
68 dns_rdataset_t rdataset;
69 isc_region_t r;
70 unsigned int i;
71 isc_boolean_t found;
72 isc_boolean_t found_ns;
73 isc_boolean_t need_rrsig;
75 unsigned char *nsec_bits, *bm;
76 unsigned int max_type;
77 dns_rdatasetiter_t *rdsiter;
78 unsigned char *p;
80 REQUIRE(salt_length < 256U);
81 REQUIRE(hash_length < 256U);
82 REQUIRE(flags <= 0xffU);
83 REQUIRE(hashalg <= 0xffU);
84 REQUIRE(iterations <= 0xffffU);
86 switch (hashalg) {
87 case dns_hash_sha1:
88 REQUIRE(hash_length == ISC_SHA1_DIGESTLENGTH);
89 break;
92 memset(buffer, 0, DNS_NSEC3_BUFFERSIZE);
94 p = buffer;
96 *p++ = hashalg;
97 *p++ = flags;
99 *p++ = iterations >> 8;
100 *p++ = iterations;
102 *p++ = (unsigned char)salt_length;
103 memmove(p, salt, salt_length);
104 p += salt_length;
106 *p++ = (unsigned char)hash_length;
107 memmove(p, nexthash, hash_length);
108 p += hash_length;
110 r.length = (unsigned int)(p - buffer);
111 r.base = buffer;
114 * Use the end of the space for a raw bitmap leaving enough
115 * space for the window identifiers and length octets.
117 bm = r.base + r.length + 512;
118 nsec_bits = r.base + r.length;
119 max_type = 0;
120 if (node == NULL)
121 goto collapse_bitmap;
122 dns_rdataset_init(&rdataset);
123 rdsiter = NULL;
124 result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
125 if (result != ISC_R_SUCCESS)
126 return (result);
127 found = found_ns = need_rrsig = ISC_FALSE;
128 for (result = dns_rdatasetiter_first(rdsiter);
129 result == ISC_R_SUCCESS;
130 result = dns_rdatasetiter_next(rdsiter))
132 dns_rdatasetiter_current(rdsiter, &rdataset);
133 if (rdataset.type != dns_rdatatype_nsec &&
134 rdataset.type != dns_rdatatype_nsec3 &&
135 rdataset.type != dns_rdatatype_rrsig) {
136 if (rdataset.type > max_type)
137 max_type = rdataset.type;
138 dns_nsec_setbit(bm, rdataset.type, 1);
140 * Work out if we need to set the RRSIG bit for
141 * this node. We set the RRSIG bit if either of
142 * the following conditions are met:
143 * 1) We have a SOA or DS then we need to set
144 * the RRSIG bit as both always will be signed.
145 * 2) We set the RRSIG bit if we don't have
146 * a NS record but do have other data.
148 if (rdataset.type == dns_rdatatype_soa ||
149 rdataset.type == dns_rdatatype_ds)
150 need_rrsig = ISC_TRUE;
151 else if (rdataset.type == dns_rdatatype_ns)
152 found_ns = ISC_TRUE;
153 else
154 found = ISC_TRUE;
156 dns_rdataset_disassociate(&rdataset);
158 if ((found && !found_ns) || need_rrsig) {
159 if (dns_rdatatype_rrsig > max_type)
160 max_type = dns_rdatatype_rrsig;
161 dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1);
165 * At zone cuts, deny the existence of glue in the parent zone.
167 if (dns_nsec_isset(bm, dns_rdatatype_ns) &&
168 ! dns_nsec_isset(bm, dns_rdatatype_soa)) {
169 for (i = 0; i <= max_type; i++) {
170 if (dns_nsec_isset(bm, i) &&
171 ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
172 dns_nsec_setbit(bm, i, 0);
176 dns_rdatasetiter_destroy(&rdsiter);
177 if (result != ISC_R_NOMORE)
178 return (result);
180 collapse_bitmap:
181 nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type);
182 r.length = (unsigned int)(nsec_bits - r.base);
183 INSIST(r.length <= DNS_NSEC3_BUFFERSIZE);
184 dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r);
186 return (ISC_R_SUCCESS);
189 isc_boolean_t
190 dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) {
191 dns_rdata_nsec3_t nsec3;
192 isc_result_t result;
193 isc_boolean_t present;
194 unsigned int i, len, window;
196 REQUIRE(rdata != NULL);
197 REQUIRE(rdata->type == dns_rdatatype_nsec3);
199 /* This should never fail */
200 result = dns_rdata_tostruct(rdata, &nsec3, NULL);
201 INSIST(result == ISC_R_SUCCESS);
203 present = ISC_FALSE;
204 for (i = 0; i < nsec3.len; i += len) {
205 INSIST(i + 2 <= nsec3.len);
206 window = nsec3.typebits[i];
207 len = nsec3.typebits[i + 1];
208 INSIST(len > 0 && len <= 32);
209 i += 2;
210 INSIST(i + len <= nsec3.len);
211 if (window * 256 > type)
212 break;
213 if ((window + 1) * 256 <= type)
214 continue;
215 if (type < (window * 256) + len * 8)
216 present = ISC_TF(dns_nsec_isset(&nsec3.typebits[i],
217 type % 256));
218 break;
220 dns_rdata_freestruct(&nsec3);
221 return (present);
224 isc_result_t
225 dns_nsec3_hashname(dns_fixedname_t *result,
226 unsigned char rethash[NSEC3_MAX_HASH_LENGTH],
227 size_t *hash_length, dns_name_t *name, dns_name_t *origin,
228 dns_hash_t hashalg, unsigned int iterations,
229 const unsigned char *salt, size_t saltlength)
231 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
232 unsigned char nametext[DNS_NAME_FORMATSIZE];
233 dns_fixedname_t fixed;
234 dns_name_t *downcased;
235 isc_buffer_t namebuffer;
236 isc_region_t region;
237 size_t len;
239 if (rethash == NULL)
240 rethash = hash;
242 memset(rethash, 0, NSEC3_MAX_HASH_LENGTH);
244 dns_fixedname_init(&fixed);
245 downcased = dns_fixedname_name(&fixed);
246 dns_name_downcase(name, downcased, NULL);
248 /* hash the node name */
249 len = isc_iterated_hash(rethash, hashalg, iterations,
250 salt, (int)saltlength,
251 downcased->ndata, downcased->length);
252 if (len == 0U)
253 return (DNS_R_BADALG);
255 if (hash_length != NULL)
256 *hash_length = len;
258 /* convert the hash to base32hex non-padded */
259 region.base = rethash;
260 region.length = (unsigned int)len;
261 isc_buffer_init(&namebuffer, nametext, sizeof nametext);
262 isc_base32hexnp_totext(&region, 1, "", &namebuffer);
264 /* convert the hex to a domain name */
265 dns_fixedname_init(result);
266 return (dns_name_fromtext(dns_fixedname_name(result), &namebuffer,
267 origin, 0, NULL));
270 unsigned int
271 dns_nsec3_hashlength(dns_hash_t hash) {
273 switch (hash) {
274 case dns_hash_sha1:
275 return(ISC_SHA1_DIGESTLENGTH);
277 return (0);
280 isc_boolean_t
281 dns_nsec3_supportedhash(dns_hash_t hash) {
282 switch (hash) {
283 case dns_hash_sha1:
284 return (ISC_TRUE);
286 return (ISC_FALSE);
290 * Update a single RR in version 'ver' of 'db' and log the
291 * update in 'diff'.
293 * Ensures:
294 * \li '*tuple' == NULL. Either the tuple is freed, or its
295 * ownership has been transferred to the diff.
297 static isc_result_t
298 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
299 dns_diff_t *diff)
301 dns_diff_t temp_diff;
302 isc_result_t result;
305 * Create a singleton diff.
307 dns_diff_init(diff->mctx, &temp_diff);
308 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
311 * Apply it to the database.
313 result = dns_diff_apply(&temp_diff, db, ver);
314 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
315 if (result != ISC_R_SUCCESS) {
316 dns_difftuple_free(tuple);
317 return (result);
321 * Merge it into the current pending journal entry.
323 dns_diff_appendminimal(diff, tuple);
326 * Do not clear temp_diff.
328 return (ISC_R_SUCCESS);
332 * Set '*exists' to true iff the given name exists, to false otherwise.
334 static isc_result_t
335 name_exists(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
336 isc_boolean_t *exists)
338 isc_result_t result;
339 dns_dbnode_t *node = NULL;
340 dns_rdatasetiter_t *iter = NULL;
342 result = dns_db_findnode(db, name, ISC_FALSE, &node);
343 if (result == ISC_R_NOTFOUND) {
344 *exists = ISC_FALSE;
345 return (ISC_R_SUCCESS);
347 if (result != ISC_R_SUCCESS)
348 return (result);
350 result = dns_db_allrdatasets(db, node, version,
351 (isc_stdtime_t) 0, &iter);
352 if (result != ISC_R_SUCCESS)
353 goto cleanup_node;
355 result = dns_rdatasetiter_first(iter);
356 if (result == ISC_R_SUCCESS) {
357 *exists = ISC_TRUE;
358 } else if (result == ISC_R_NOMORE) {
359 *exists = ISC_FALSE;
360 result = ISC_R_SUCCESS;
361 } else
362 *exists = ISC_FALSE;
363 dns_rdatasetiter_destroy(&iter);
365 cleanup_node:
366 dns_db_detachnode(db, &node);
367 return (result);
370 static isc_boolean_t
371 match_nsec3param(const dns_rdata_nsec3_t *nsec3,
372 const dns_rdata_nsec3param_t *nsec3param)
374 if (nsec3->hash == nsec3param->hash &&
375 nsec3->iterations == nsec3param->iterations &&
376 nsec3->salt_length == nsec3param->salt_length &&
377 !memcmp(nsec3->salt, nsec3param->salt, nsec3->salt_length))
378 return (ISC_TRUE);
379 return (ISC_FALSE);
383 * Delete NSEC3 records at "name" which match "param", recording the
384 * change in "diff".
386 static isc_result_t
387 delete(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
388 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
390 dns_dbnode_t *node = NULL ;
391 dns_difftuple_t *tuple = NULL;
392 dns_rdata_nsec3_t nsec3;
393 dns_rdataset_t rdataset;
394 isc_result_t result;
396 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
397 if (result == ISC_R_NOTFOUND)
398 return (ISC_R_SUCCESS);
399 if (result != ISC_R_SUCCESS)
400 return (result);
402 dns_rdataset_init(&rdataset);
403 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0,
404 (isc_stdtime_t) 0, &rdataset, NULL);
406 if (result == ISC_R_NOTFOUND) {
407 result = ISC_R_SUCCESS;
408 goto cleanup_node;
410 if (result != ISC_R_SUCCESS)
411 goto cleanup_node;
413 for (result = dns_rdataset_first(&rdataset);
414 result == ISC_R_SUCCESS;
415 result = dns_rdataset_next(&rdataset))
417 dns_rdata_t rdata = DNS_RDATA_INIT;
418 dns_rdataset_current(&rdataset, &rdata);
419 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
421 if (!match_nsec3param(&nsec3, nsec3param))
422 continue;
424 result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name,
425 rdataset.ttl, &rdata, &tuple);
426 if (result != ISC_R_SUCCESS)
427 goto failure;
428 result = do_one_tuple(&tuple, db, version, diff);
429 if (result != ISC_R_SUCCESS)
430 goto failure;
432 if (result != ISC_R_NOMORE)
433 goto failure;
434 result = ISC_R_SUCCESS;
436 failure:
437 dns_rdataset_disassociate(&rdataset);
438 cleanup_node:
439 dns_db_detachnode(db, &node);
441 return (result);
444 static isc_boolean_t
445 better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
446 dns_rdataset_t rdataset;
447 isc_result_t result;
449 if (REMOVE(param->data[1]))
450 return (ISC_TRUE);
452 dns_rdataset_init(&rdataset);
453 dns_rdataset_clone(nsec3paramset, &rdataset);
454 for (result = dns_rdataset_first(&rdataset);
455 result == ISC_R_SUCCESS;
456 result = dns_rdataset_next(&rdataset)) {
457 dns_rdata_t rdata = DNS_RDATA_INIT;
458 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
460 if (rdataset.type != dns_rdatatype_nsec3param) {
461 dns_rdata_t tmprdata = DNS_RDATA_INIT;
462 dns_rdataset_current(&rdataset, &tmprdata);
463 if (!dns_nsec3param_fromprivate(&tmprdata, &rdata,
464 buf, sizeof(buf)))
465 continue;
466 } else
467 dns_rdataset_current(&rdataset, &rdata);
469 if (rdata.length != param->length)
470 continue;
471 if (rdata.data[0] != param->data[0] ||
472 REMOVE(rdata.data[1]) ||
473 rdata.data[2] != param->data[2] ||
474 rdata.data[3] != param->data[3] ||
475 rdata.data[4] != param->data[4] ||
476 memcmp(&rdata.data[5], &param->data[5], param->data[4]))
477 continue;
478 if (CREATE(rdata.data[1]) && !CREATE(param->data[1])) {
479 dns_rdataset_disassociate(&rdataset);
480 return (ISC_TRUE);
483 dns_rdataset_disassociate(&rdataset);
484 return (ISC_FALSE);
487 static isc_result_t
488 find_nsec3(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *rdataset,
489 const dns_rdata_nsec3param_t *nsec3param)
491 isc_result_t result;
492 for (result = dns_rdataset_first(rdataset);
493 result == ISC_R_SUCCESS;
494 result = dns_rdataset_next(rdataset)) {
495 dns_rdata_t rdata = DNS_RDATA_INIT;
497 dns_rdataset_current(rdataset, &rdata);
498 CHECK(dns_rdata_tostruct(&rdata, nsec3, NULL));
499 dns_rdata_reset(&rdata);
500 if (match_nsec3param(nsec3, nsec3param))
501 break;
503 failure:
504 return (result);
507 isc_result_t
508 dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
509 dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param,
510 dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_diff_t *diff)
512 dns_dbiterator_t *dbit = NULL;
513 dns_dbnode_t *node = NULL;
514 dns_dbnode_t *newnode = NULL;
515 dns_difftuple_t *tuple = NULL;
516 dns_fixedname_t fixed;
517 dns_fixedname_t fprev;
518 dns_hash_t hash;
519 dns_name_t *hashname;
520 dns_name_t *origin;
521 dns_name_t *prev;
522 dns_name_t empty;
523 dns_rdata_nsec3_t nsec3;
524 dns_rdata_t rdata = DNS_RDATA_INIT;
525 dns_rdataset_t rdataset;
526 int pass;
527 isc_boolean_t exists = ISC_FALSE;
528 isc_boolean_t maybe_remove_unsecure = ISC_FALSE;
529 isc_uint8_t flags;
530 isc_buffer_t buffer;
531 isc_result_t result;
532 unsigned char *old_next;
533 unsigned char *salt;
534 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
535 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
536 unsigned int iterations;
537 unsigned int labels;
538 size_t next_length;
539 unsigned int old_length;
540 unsigned int salt_length;
542 dns_fixedname_init(&fixed);
543 hashname = dns_fixedname_name(&fixed);
544 dns_fixedname_init(&fprev);
545 prev = dns_fixedname_name(&fprev);
547 dns_rdataset_init(&rdataset);
549 origin = dns_db_origin(db);
552 * Chain parameters.
554 hash = nsec3param->hash;
555 iterations = nsec3param->iterations;
556 salt_length = nsec3param->salt_length;
557 salt = nsec3param->salt;
560 * Default flags for a new chain.
562 flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
565 * If this is the first NSEC3 in the chain nexthash will
566 * remain pointing to itself.
568 next_length = sizeof(nexthash);
569 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
570 name, origin, hash, iterations,
571 salt, salt_length));
572 INSIST(next_length <= sizeof(nexthash));
575 * Create the node if it doesn't exist and hold
576 * a reference to it until we have added the NSEC3.
578 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
581 * Seek the iterator to the 'newnode'.
583 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
584 CHECK(dns_dbiterator_seek(dbit, hashname));
585 CHECK(dns_dbiterator_pause(dbit));
586 result = dns_db_findrdataset(db, newnode, version, dns_rdatatype_nsec3,
587 0, (isc_stdtime_t) 0, &rdataset, NULL);
589 * If we updating a existing NSEC3 then find its
590 * next field.
592 if (result == ISC_R_SUCCESS) {
593 result = find_nsec3(&nsec3, &rdataset, nsec3param);
594 if (result == ISC_R_SUCCESS) {
595 if (!CREATE(nsec3param->flags))
596 flags = nsec3.flags;
597 next_length = nsec3.next_length;
598 INSIST(next_length <= sizeof(nexthash));
599 memmove(nexthash, nsec3.next, next_length);
600 dns_rdataset_disassociate(&rdataset);
602 * If the NSEC3 is not for a unsecure delegation then
603 * we are just updating it. If it is for a unsecure
604 * delegation then we need find out if we need to
605 * remove the NSEC3 record or not by examining the
606 * previous NSEC3 record.
608 if (!unsecure)
609 goto addnsec3;
610 else if (CREATE(nsec3param->flags) && OPTOUT(flags)) {
611 result = dns_nsec3_delnsec3(db, version, name,
612 nsec3param, diff);
613 goto failure;
614 } else
615 maybe_remove_unsecure = ISC_TRUE;
616 } else {
617 dns_rdataset_disassociate(&rdataset);
618 if (result != ISC_R_NOMORE)
619 goto failure;
624 * Find the previous NSEC3 (if any) and update it if required.
626 pass = 0;
627 do {
628 result = dns_dbiterator_prev(dbit);
629 if (result == ISC_R_NOMORE) {
630 pass++;
631 CHECK(dns_dbiterator_last(dbit));
633 CHECK(dns_dbiterator_current(dbit, &node, prev));
634 CHECK(dns_dbiterator_pause(dbit));
635 result = dns_db_findrdataset(db, node, version,
636 dns_rdatatype_nsec3, 0,
637 (isc_stdtime_t) 0, &rdataset,
638 NULL);
639 dns_db_detachnode(db, &node);
640 if (result != ISC_R_SUCCESS)
641 continue;
643 result = find_nsec3(&nsec3, &rdataset, nsec3param);
644 if (result == ISC_R_NOMORE) {
645 dns_rdataset_disassociate(&rdataset);
646 continue;
648 if (result != ISC_R_SUCCESS)
649 goto failure;
651 if (maybe_remove_unsecure) {
652 dns_rdataset_disassociate(&rdataset);
654 * If we have OPTOUT set in the previous NSEC3 record
655 * we actually need to delete the NSEC3 record.
656 * Otherwise we just need to replace the NSEC3 record.
658 if (OPTOUT(nsec3.flags)) {
659 result = dns_nsec3_delnsec3(db, version, name,
660 nsec3param, diff);
661 goto failure;
663 goto addnsec3;
664 } else {
666 * Is this is a unsecure delegation we are adding?
667 * If so no change is required.
669 if (OPTOUT(nsec3.flags) && unsecure) {
670 dns_rdataset_disassociate(&rdataset);
671 goto failure;
675 old_next = nsec3.next;
676 old_length = nsec3.next_length;
679 * Delete the old previous NSEC3.
681 CHECK(delete(db, version, prev, nsec3param, diff));
684 * Fixup the previous NSEC3.
686 nsec3.next = nexthash;
687 nsec3.next_length = (unsigned char)next_length;
688 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
689 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
690 dns_rdatatype_nsec3, &nsec3,
691 &buffer));
692 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
693 rdataset.ttl, &rdata, &tuple));
694 CHECK(do_one_tuple(&tuple, db, version, diff));
695 INSIST(old_length <= sizeof(nexthash));
696 memmove(nexthash, old_next, old_length);
697 if (!CREATE(nsec3param->flags))
698 flags = nsec3.flags;
699 dns_rdata_reset(&rdata);
700 dns_rdataset_disassociate(&rdataset);
701 break;
702 } while (pass < 2);
704 addnsec3:
706 * Create the NSEC3 RDATA.
708 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
709 CHECK(dns_nsec3_buildrdata(db, version, node, hash, flags, iterations,
710 salt, salt_length, nexthash, next_length,
711 nsec3buf, &rdata));
712 dns_db_detachnode(db, &node);
715 * Delete the old NSEC3 and record the change.
717 CHECK(delete(db, version, hashname, nsec3param, diff));
719 * Add the new NSEC3 and record the change.
721 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
722 hashname, nsecttl, &rdata, &tuple));
723 CHECK(do_one_tuple(&tuple, db, version, diff));
724 INSIST(tuple == NULL);
725 dns_rdata_reset(&rdata);
726 dns_db_detachnode(db, &newnode);
729 * Add missing NSEC3 records for empty nodes
731 dns_name_init(&empty, NULL);
732 dns_name_clone(name, &empty);
733 do {
734 labels = dns_name_countlabels(&empty) - 1;
735 if (labels <= dns_name_countlabels(origin))
736 break;
737 dns_name_getlabelsequence(&empty, 1, labels, &empty);
738 CHECK(name_exists(db, version, &empty, &exists));
739 if (exists)
740 break;
741 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
742 &empty, origin, hash, iterations,
743 salt, salt_length));
746 * Create the node if it doesn't exist and hold
747 * a reference to it until we have added the NSEC3
748 * or we discover we don't need to add make a change.
750 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
751 result = dns_db_findrdataset(db, newnode, version,
752 dns_rdatatype_nsec3, 0,
753 (isc_stdtime_t) 0, &rdataset,
754 NULL);
755 if (result == ISC_R_SUCCESS) {
756 result = find_nsec3(&nsec3, &rdataset, nsec3param);
757 dns_rdataset_disassociate(&rdataset);
758 if (result == ISC_R_SUCCESS) {
759 dns_db_detachnode(db, &newnode);
760 break;
762 if (result != ISC_R_NOMORE)
763 goto failure;
767 * Find the previous NSEC3 and update it.
769 CHECK(dns_dbiterator_seek(dbit, hashname));
770 pass = 0;
771 do {
772 result = dns_dbiterator_prev(dbit);
773 if (result == ISC_R_NOMORE) {
774 pass++;
775 CHECK(dns_dbiterator_last(dbit));
777 CHECK(dns_dbiterator_current(dbit, &node, prev));
778 CHECK(dns_dbiterator_pause(dbit));
779 result = dns_db_findrdataset(db, node, version,
780 dns_rdatatype_nsec3, 0,
781 (isc_stdtime_t) 0,
782 &rdataset, NULL);
783 dns_db_detachnode(db, &node);
784 if (result != ISC_R_SUCCESS)
785 continue;
786 result = find_nsec3(&nsec3, &rdataset, nsec3param);
787 if (result == ISC_R_NOMORE) {
788 dns_rdataset_disassociate(&rdataset);
789 continue;
791 if (result != ISC_R_SUCCESS)
792 goto failure;
794 old_next = nsec3.next;
795 old_length = nsec3.next_length;
798 * Delete the old previous NSEC3.
800 CHECK(delete(db, version, prev, nsec3param, diff));
803 * Fixup the previous NSEC3.
805 nsec3.next = nexthash;
806 nsec3.next_length = (unsigned char)next_length;
807 isc_buffer_init(&buffer, nsec3buf,
808 sizeof(nsec3buf));
809 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
810 dns_rdatatype_nsec3, &nsec3,
811 &buffer));
812 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
813 prev, rdataset.ttl, &rdata,
814 &tuple));
815 CHECK(do_one_tuple(&tuple, db, version, diff));
816 INSIST(old_length <= sizeof(nexthash));
817 memmove(nexthash, old_next, old_length);
818 if (!CREATE(nsec3param->flags))
819 flags = nsec3.flags;
820 dns_rdata_reset(&rdata);
821 dns_rdataset_disassociate(&rdataset);
822 break;
823 } while (pass < 2);
825 INSIST(pass < 2);
828 * Create the NSEC3 RDATA for the empty node.
830 CHECK(dns_nsec3_buildrdata(db, version, NULL, hash, flags,
831 iterations, salt, salt_length,
832 nexthash, next_length, nsec3buf,
833 &rdata));
835 * Delete the old NSEC3 and record the change.
837 CHECK(delete(db, version, hashname, nsec3param, diff));
840 * Add the new NSEC3 and record the change.
842 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
843 hashname, nsecttl, &rdata, &tuple));
844 CHECK(do_one_tuple(&tuple, db, version, diff));
845 INSIST(tuple == NULL);
846 dns_rdata_reset(&rdata);
847 dns_db_detachnode(db, &newnode);
848 } while (1);
850 /* result cannot be ISC_R_NOMORE here */
851 INSIST(result != ISC_R_NOMORE);
853 failure:
854 if (dbit != NULL)
855 dns_dbiterator_destroy(&dbit);
856 if (dns_rdataset_isassociated(&rdataset))
857 dns_rdataset_disassociate(&rdataset);
858 if (node != NULL)
859 dns_db_detachnode(db, &node);
860 if (newnode != NULL)
861 dns_db_detachnode(db, &newnode);
862 return (result);
866 * Add NSEC3 records for "name", recording the change in "diff".
867 * The existing NSEC3 records are removed.
869 isc_result_t
870 dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
871 dns_name_t *name, dns_ttl_t nsecttl,
872 isc_boolean_t unsecure, dns_diff_t *diff)
874 dns_dbnode_t *node = NULL;
875 dns_rdata_nsec3param_t nsec3param;
876 dns_rdataset_t rdataset;
877 isc_result_t result;
879 dns_rdataset_init(&rdataset);
882 * Find the NSEC3 parameters for this zone.
884 result = dns_db_getoriginnode(db, &node);
885 if (result != ISC_R_SUCCESS)
886 return (result);
888 result = dns_db_findrdataset(db, node, version,
889 dns_rdatatype_nsec3param, 0, 0,
890 &rdataset, NULL);
891 dns_db_detachnode(db, &node);
892 if (result == ISC_R_NOTFOUND)
893 return (ISC_R_SUCCESS);
894 if (result != ISC_R_SUCCESS)
895 return (result);
898 * Update each active NSEC3 chain.
900 for (result = dns_rdataset_first(&rdataset);
901 result == ISC_R_SUCCESS;
902 result = dns_rdataset_next(&rdataset)) {
903 dns_rdata_t rdata = DNS_RDATA_INIT;
905 dns_rdataset_current(&rdataset, &rdata);
906 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
908 if (nsec3param.flags != 0)
909 continue;
911 * We have a active chain. Update it.
913 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
914 nsecttl, unsecure, diff));
916 if (result == ISC_R_NOMORE)
917 result = ISC_R_SUCCESS;
919 failure:
920 if (dns_rdataset_isassociated(&rdataset))
921 dns_rdataset_disassociate(&rdataset);
922 if (node != NULL)
923 dns_db_detachnode(db, &node);
925 return (result);
928 isc_boolean_t
929 dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target,
930 unsigned char *buf, size_t buflen)
932 dns_decompress_t dctx;
933 isc_result_t result;
934 isc_buffer_t buf1;
935 isc_buffer_t buf2;
938 * Algorithm 0 (reserved by RFC 4034) is used to identify
939 * NSEC3PARAM records from DNSKEY pointers.
941 if (src->length < 1 || src->data[0] != 0)
942 return (ISC_FALSE);
944 isc_buffer_init(&buf1, src->data + 1, src->length - 1);
945 isc_buffer_add(&buf1, src->length - 1);
946 isc_buffer_setactive(&buf1, src->length - 1);
947 isc_buffer_init(&buf2, buf, (unsigned int)buflen);
948 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
949 result = dns_rdata_fromwire(target, src->rdclass,
950 dns_rdatatype_nsec3param,
951 &buf1, &dctx, 0, &buf2);
952 dns_decompress_invalidate(&dctx);
954 return (ISC_TF(result == ISC_R_SUCCESS));
957 void
958 dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target,
959 dns_rdatatype_t privatetype,
960 unsigned char *buf, size_t buflen)
962 REQUIRE(buflen >= src->length + 1);
964 REQUIRE(DNS_RDATA_INITIALIZED(target));
966 memmove(buf + 1, src->data, src->length);
967 buf[0] = 0;
968 target->data = buf;
969 target->length = src->length + 1;
970 target->type = privatetype;
971 target->rdclass = src->rdclass;
972 target->flags = 0;
973 ISC_LINK_INIT(target, link);
976 static isc_result_t
977 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
978 const dns_rdata_t *rdata, isc_boolean_t *flag)
980 dns_rdataset_t rdataset;
981 dns_dbnode_t *node = NULL;
982 isc_result_t result;
984 dns_rdataset_init(&rdataset);
985 if (rdata->type == dns_rdatatype_nsec3)
986 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
987 else
988 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
989 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
990 (isc_stdtime_t) 0, &rdataset, NULL);
991 if (result == ISC_R_NOTFOUND) {
992 *flag = ISC_FALSE;
993 result = ISC_R_SUCCESS;
994 goto failure;
997 for (result = dns_rdataset_first(&rdataset);
998 result == ISC_R_SUCCESS;
999 result = dns_rdataset_next(&rdataset)) {
1000 dns_rdata_t myrdata = DNS_RDATA_INIT;
1001 dns_rdataset_current(&rdataset, &myrdata);
1002 if (!dns_rdata_casecompare(&myrdata, rdata))
1003 break;
1005 dns_rdataset_disassociate(&rdataset);
1006 if (result == ISC_R_SUCCESS) {
1007 *flag = ISC_TRUE;
1008 } else if (result == ISC_R_NOMORE) {
1009 *flag = ISC_FALSE;
1010 result = ISC_R_SUCCESS;
1013 failure:
1014 if (node != NULL)
1015 dns_db_detachnode(db, &node);
1016 return (result);
1019 isc_result_t
1020 dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
1021 dns_zone_t *zone, isc_boolean_t nonsec,
1022 dns_diff_t *diff)
1024 dns_dbnode_t *node = NULL;
1025 dns_difftuple_t *tuple = NULL;
1026 dns_name_t next;
1027 dns_rdata_t rdata = DNS_RDATA_INIT;
1028 dns_rdataset_t rdataset;
1029 isc_boolean_t flag;
1030 isc_result_t result = ISC_R_SUCCESS;
1031 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1];
1032 dns_name_t *origin = dns_zone_getorigin(zone);
1033 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
1035 dns_name_init(&next, NULL);
1036 dns_rdataset_init(&rdataset);
1038 result = dns_db_getoriginnode(db, &node);
1039 if (result != ISC_R_SUCCESS)
1040 return (result);
1043 * Cause all NSEC3 chains to be deleted.
1045 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
1046 0, (isc_stdtime_t) 0, &rdataset, NULL);
1047 if (result == ISC_R_NOTFOUND)
1048 goto try_private;
1049 if (result != ISC_R_SUCCESS)
1050 goto failure;
1052 for (result = dns_rdataset_first(&rdataset);
1053 result == ISC_R_SUCCESS;
1054 result = dns_rdataset_next(&rdataset)) {
1055 dns_rdata_t private = DNS_RDATA_INIT;
1057 dns_rdataset_current(&rdataset, &rdata);
1059 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1060 rdataset.ttl, &rdata, &tuple));
1061 CHECK(do_one_tuple(&tuple, db, ver, diff));
1062 INSIST(tuple == NULL);
1064 dns_nsec3param_toprivate(&rdata, &private, privatetype,
1065 buf, sizeof(buf));
1066 buf[2] = DNS_NSEC3FLAG_REMOVE;
1067 if (nonsec)
1068 buf[2] |= DNS_NSEC3FLAG_NONSEC;
1070 CHECK(rr_exists(db, ver, origin, &private, &flag));
1072 if (!flag) {
1073 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1074 origin, 0, &private,
1075 &tuple));
1076 CHECK(do_one_tuple(&tuple, db, ver, diff));
1077 INSIST(tuple == NULL);
1079 dns_rdata_reset(&rdata);
1081 if (result != ISC_R_NOMORE)
1082 goto failure;
1084 dns_rdataset_disassociate(&rdataset);
1086 try_private:
1087 if (privatetype == 0)
1088 goto success;
1089 result = dns_db_findrdataset(db, node, ver, privatetype, 0,
1090 (isc_stdtime_t) 0, &rdataset, NULL);
1091 if (result == ISC_R_NOTFOUND)
1092 goto success;
1093 if (result != ISC_R_SUCCESS)
1094 goto failure;
1096 for (result = dns_rdataset_first(&rdataset);
1097 result == ISC_R_SUCCESS;
1098 result = dns_rdataset_next(&rdataset)) {
1099 dns_rdata_reset(&rdata);
1100 dns_rdataset_current(&rdataset, &rdata);
1101 INSIST(rdata.length <= sizeof(buf));
1102 memmove(buf, rdata.data, rdata.length);
1105 * Private NSEC3 record length >= 6.
1106 * <0(1), hash(1), flags(1), iterations(2), saltlen(1)>
1108 if (rdata.length < 6 || buf[0] != 0 ||
1109 (buf[2] & DNS_NSEC3FLAG_REMOVE) != 0 ||
1110 (nonsec && (buf[2] & DNS_NSEC3FLAG_NONSEC) != 0))
1111 continue;
1113 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1114 0, &rdata, &tuple));
1115 CHECK(do_one_tuple(&tuple, db, ver, diff));
1116 INSIST(tuple == NULL);
1118 rdata.data = buf;
1119 buf[2] = DNS_NSEC3FLAG_REMOVE;
1120 if (nonsec)
1121 buf[2] |= DNS_NSEC3FLAG_NONSEC;
1123 CHECK(rr_exists(db, ver, origin, &rdata, &flag));
1125 if (!flag) {
1126 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1127 origin, 0, &rdata, &tuple));
1128 CHECK(do_one_tuple(&tuple, db, ver, diff));
1129 INSIST(tuple == NULL);
1132 if (result != ISC_R_NOMORE)
1133 goto failure;
1134 success:
1135 result = ISC_R_SUCCESS;
1137 failure:
1138 if (dns_rdataset_isassociated(&rdataset))
1139 dns_rdataset_disassociate(&rdataset);
1140 dns_db_detachnode(db, &node);
1141 return (result);
1144 isc_result_t
1145 dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version,
1146 dns_name_t *name, dns_ttl_t nsecttl,
1147 isc_boolean_t unsecure, dns_rdatatype_t type,
1148 dns_diff_t *diff)
1150 dns_dbnode_t *node = NULL;
1151 dns_rdata_nsec3param_t nsec3param;
1152 dns_rdataset_t rdataset;
1153 dns_rdataset_t prdataset;
1154 isc_result_t result;
1156 dns_rdataset_init(&rdataset);
1157 dns_rdataset_init(&prdataset);
1160 * Find the NSEC3 parameters for this zone.
1162 result = dns_db_getoriginnode(db, &node);
1163 if (result != ISC_R_SUCCESS)
1164 return (result);
1166 result = dns_db_findrdataset(db, node, version, type, 0, 0,
1167 &prdataset, NULL);
1168 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
1169 goto failure;
1171 result = dns_db_findrdataset(db, node, version,
1172 dns_rdatatype_nsec3param, 0, 0,
1173 &rdataset, NULL);
1174 if (result == ISC_R_NOTFOUND)
1175 goto try_private;
1176 if (result != ISC_R_SUCCESS)
1177 goto failure;
1180 * Update each active NSEC3 chain.
1182 for (result = dns_rdataset_first(&rdataset);
1183 result == ISC_R_SUCCESS;
1184 result = dns_rdataset_next(&rdataset)) {
1185 dns_rdata_t rdata = DNS_RDATA_INIT;
1187 dns_rdataset_current(&rdataset, &rdata);
1188 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1190 if (nsec3param.flags != 0)
1191 continue;
1194 * We have a active chain. Update it.
1196 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1197 nsecttl, unsecure, diff));
1199 if (result != ISC_R_NOMORE)
1200 goto failure;
1202 dns_rdataset_disassociate(&rdataset);
1204 try_private:
1205 if (!dns_rdataset_isassociated(&prdataset))
1206 goto success;
1208 * Update each active NSEC3 chain.
1210 for (result = dns_rdataset_first(&prdataset);
1211 result == ISC_R_SUCCESS;
1212 result = dns_rdataset_next(&prdataset)) {
1213 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1214 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1215 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1217 dns_rdataset_current(&prdataset, &rdata1);
1218 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1219 buf, sizeof(buf)))
1220 continue;
1221 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1223 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
1224 continue;
1225 if (better_param(&prdataset, &rdata2))
1226 continue;
1229 * We have a active chain. Update it.
1231 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1232 nsecttl, unsecure, diff));
1234 if (result == ISC_R_NOMORE)
1235 success:
1236 result = ISC_R_SUCCESS;
1237 failure:
1238 if (dns_rdataset_isassociated(&rdataset))
1239 dns_rdataset_disassociate(&rdataset);
1240 if (dns_rdataset_isassociated(&prdataset))
1241 dns_rdataset_disassociate(&prdataset);
1242 if (node != NULL)
1243 dns_db_detachnode(db, &node);
1245 return (result);
1249 * Determine whether any NSEC3 records that were associated with
1250 * 'name' should be deleted or if they should continue to exist.
1251 * ISC_TRUE indicates they should be deleted.
1252 * ISC_FALSE indicates they should be retained.
1254 static isc_result_t
1255 deleteit(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
1256 isc_boolean_t *yesno)
1258 isc_result_t result;
1259 dns_fixedname_t foundname;
1260 dns_fixedname_init(&foundname);
1262 result = dns_db_find(db, name, ver, dns_rdatatype_any,
1263 DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
1264 (isc_stdtime_t) 0, NULL,
1265 dns_fixedname_name(&foundname),
1266 NULL, NULL);
1267 if (result == DNS_R_EMPTYNAME || result == ISC_R_SUCCESS ||
1268 result == DNS_R_ZONECUT) {
1269 *yesno = ISC_FALSE;
1270 return (ISC_R_SUCCESS);
1272 if (result == DNS_R_GLUE || result == DNS_R_DNAME ||
1273 result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) {
1274 *yesno = ISC_TRUE;
1275 return (ISC_R_SUCCESS);
1278 * Silence compiler.
1280 *yesno = ISC_TRUE;
1281 return (result);
1284 isc_result_t
1285 dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1286 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
1288 dns_dbiterator_t *dbit = NULL;
1289 dns_dbnode_t *node = NULL;
1290 dns_difftuple_t *tuple = NULL;
1291 dns_fixedname_t fixed;
1292 dns_fixedname_t fprev;
1293 dns_hash_t hash;
1294 dns_name_t *hashname;
1295 dns_name_t *origin;
1296 dns_name_t *prev;
1297 dns_name_t empty;
1298 dns_rdata_nsec3_t nsec3;
1299 dns_rdata_t rdata = DNS_RDATA_INIT;
1300 dns_rdataset_t rdataset;
1301 int pass;
1302 isc_boolean_t yesno;
1303 isc_buffer_t buffer;
1304 isc_result_t result;
1305 unsigned char *salt;
1306 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
1307 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
1308 unsigned int iterations;
1309 unsigned int labels;
1310 size_t next_length;
1311 unsigned int salt_length;
1313 dns_fixedname_init(&fixed);
1314 hashname = dns_fixedname_name(&fixed);
1315 dns_fixedname_init(&fprev);
1316 prev = dns_fixedname_name(&fprev);
1318 dns_rdataset_init(&rdataset);
1320 origin = dns_db_origin(db);
1323 * Chain parameters.
1325 hash = nsec3param->hash;
1326 iterations = nsec3param->iterations;
1327 salt_length = nsec3param->salt_length;
1328 salt = nsec3param->salt;
1331 * If this is the first NSEC3 in the chain nexthash will
1332 * remain pointing to itself.
1334 next_length = sizeof(nexthash);
1335 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
1336 name, origin, hash, iterations,
1337 salt, salt_length));
1339 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
1341 result = dns_dbiterator_seek(dbit, hashname);
1342 if (result == ISC_R_NOTFOUND)
1343 goto success;
1344 if (result != ISC_R_SUCCESS)
1345 goto failure;
1347 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1348 CHECK(dns_dbiterator_pause(dbit));
1349 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3,
1350 0, (isc_stdtime_t) 0, &rdataset, NULL);
1351 dns_db_detachnode(db, &node);
1352 if (result == ISC_R_NOTFOUND)
1353 goto success;
1354 if (result != ISC_R_SUCCESS)
1355 goto failure;
1358 * If we find a existing NSEC3 for this chain then save the
1359 * next field.
1361 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1362 if (result == ISC_R_SUCCESS) {
1363 next_length = nsec3.next_length;
1364 INSIST(next_length <= sizeof(nexthash));
1365 memmove(nexthash, nsec3.next, next_length);
1367 dns_rdataset_disassociate(&rdataset);
1368 if (result == ISC_R_NOMORE)
1369 goto success;
1370 if (result != ISC_R_SUCCESS)
1371 goto failure;
1374 * Find the previous NSEC3 and update it.
1376 pass = 0;
1377 do {
1378 result = dns_dbiterator_prev(dbit);
1379 if (result == ISC_R_NOMORE) {
1380 pass++;
1381 CHECK(dns_dbiterator_last(dbit));
1383 CHECK(dns_dbiterator_current(dbit, &node, prev));
1384 CHECK(dns_dbiterator_pause(dbit));
1385 result = dns_db_findrdataset(db, node, version,
1386 dns_rdatatype_nsec3, 0,
1387 (isc_stdtime_t) 0, &rdataset,
1388 NULL);
1389 dns_db_detachnode(db, &node);
1390 if (result != ISC_R_SUCCESS)
1391 continue;
1392 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1393 if (result == ISC_R_NOMORE) {
1394 dns_rdataset_disassociate(&rdataset);
1395 continue;
1397 if (result != ISC_R_SUCCESS)
1398 goto failure;
1401 * Delete the old previous NSEC3.
1403 CHECK(delete(db, version, prev, nsec3param, diff));
1406 * Fixup the previous NSEC3.
1408 nsec3.next = nexthash;
1409 nsec3.next_length = (unsigned char)next_length;
1410 if (CREATE(nsec3param->flags))
1411 nsec3.flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
1412 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
1413 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1414 dns_rdatatype_nsec3, &nsec3,
1415 &buffer));
1416 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
1417 rdataset.ttl, &rdata, &tuple));
1418 CHECK(do_one_tuple(&tuple, db, version, diff));
1419 dns_rdata_reset(&rdata);
1420 dns_rdataset_disassociate(&rdataset);
1421 break;
1422 } while (pass < 2);
1425 * Delete the old NSEC3 and record the change.
1427 CHECK(delete(db, version, hashname, nsec3param, diff));
1430 * Delete NSEC3 records for now non active nodes.
1432 dns_name_init(&empty, NULL);
1433 dns_name_clone(name, &empty);
1434 do {
1435 labels = dns_name_countlabels(&empty) - 1;
1436 if (labels <= dns_name_countlabels(origin))
1437 break;
1438 dns_name_getlabelsequence(&empty, 1, labels, &empty);
1439 CHECK(deleteit(db, version, &empty, &yesno));
1440 if (!yesno)
1441 break;
1443 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
1444 &empty, origin, hash, iterations,
1445 salt, salt_length));
1446 result = dns_dbiterator_seek(dbit, hashname);
1447 if (result == ISC_R_NOTFOUND)
1448 goto success;
1449 if (result != ISC_R_SUCCESS)
1450 goto failure;
1452 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1453 CHECK(dns_dbiterator_pause(dbit));
1454 result = dns_db_findrdataset(db, node, version,
1455 dns_rdatatype_nsec3, 0,
1456 (isc_stdtime_t) 0, &rdataset,
1457 NULL);
1458 dns_db_detachnode(db, &node);
1459 if (result == ISC_R_NOTFOUND)
1460 goto success;
1461 if (result != ISC_R_SUCCESS)
1462 goto failure;
1464 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1465 if (result == ISC_R_SUCCESS) {
1466 next_length = nsec3.next_length;
1467 INSIST(next_length <= sizeof(nexthash));
1468 memmove(nexthash, nsec3.next, next_length);
1470 dns_rdataset_disassociate(&rdataset);
1471 if (result == ISC_R_NOMORE)
1472 goto success;
1473 if (result != ISC_R_SUCCESS)
1474 goto failure;
1476 pass = 0;
1477 do {
1478 result = dns_dbiterator_prev(dbit);
1479 if (result == ISC_R_NOMORE) {
1480 pass++;
1481 CHECK(dns_dbiterator_last(dbit));
1483 CHECK(dns_dbiterator_current(dbit, &node, prev));
1484 CHECK(dns_dbiterator_pause(dbit));
1485 result = dns_db_findrdataset(db, node, version,
1486 dns_rdatatype_nsec3, 0,
1487 (isc_stdtime_t) 0,
1488 &rdataset, NULL);
1489 dns_db_detachnode(db, &node);
1490 if (result != ISC_R_SUCCESS)
1491 continue;
1492 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1493 if (result == ISC_R_NOMORE) {
1494 dns_rdataset_disassociate(&rdataset);
1495 continue;
1497 if (result != ISC_R_SUCCESS)
1498 goto failure;
1501 * Delete the old previous NSEC3.
1503 CHECK(delete(db, version, prev, nsec3param, diff));
1506 * Fixup the previous NSEC3.
1508 nsec3.next = nexthash;
1509 nsec3.next_length = (unsigned char)next_length;
1510 isc_buffer_init(&buffer, nsec3buf,
1511 sizeof(nsec3buf));
1512 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1513 dns_rdatatype_nsec3, &nsec3,
1514 &buffer));
1515 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1516 prev, rdataset.ttl, &rdata,
1517 &tuple));
1518 CHECK(do_one_tuple(&tuple, db, version, diff));
1519 dns_rdata_reset(&rdata);
1520 dns_rdataset_disassociate(&rdataset);
1521 break;
1522 } while (pass < 2);
1524 INSIST(pass < 2);
1527 * Delete the old NSEC3 and record the change.
1529 CHECK(delete(db, version, hashname, nsec3param, diff));
1530 } while (1);
1532 success:
1533 result = ISC_R_SUCCESS;
1535 failure:
1536 if (dbit != NULL)
1537 dns_dbiterator_destroy(&dbit);
1538 if (dns_rdataset_isassociated(&rdataset))
1539 dns_rdataset_disassociate(&rdataset);
1540 if (node != NULL)
1541 dns_db_detachnode(db, &node);
1542 return (result);
1545 isc_result_t
1546 dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1547 dns_diff_t *diff)
1549 return (dns_nsec3_delnsec3sx(db, version, name, 0, diff));
1552 isc_result_t
1553 dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1554 dns_rdatatype_t privatetype, dns_diff_t *diff)
1556 dns_dbnode_t *node = NULL;
1557 dns_rdata_nsec3param_t nsec3param;
1558 dns_rdataset_t rdataset;
1559 isc_result_t result;
1561 dns_rdataset_init(&rdataset);
1564 * Find the NSEC3 parameters for this zone.
1566 result = dns_db_getoriginnode(db, &node);
1567 if (result != ISC_R_SUCCESS)
1568 return (result);
1570 result = dns_db_findrdataset(db, node, version,
1571 dns_rdatatype_nsec3param, 0, 0,
1572 &rdataset, NULL);
1573 if (result == ISC_R_NOTFOUND)
1574 goto try_private;
1575 if (result != ISC_R_SUCCESS)
1576 goto failure;
1579 * Update each active NSEC3 chain.
1581 for (result = dns_rdataset_first(&rdataset);
1582 result == ISC_R_SUCCESS;
1583 result = dns_rdataset_next(&rdataset)) {
1584 dns_rdata_t rdata = DNS_RDATA_INIT;
1586 dns_rdataset_current(&rdataset, &rdata);
1587 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1589 if (nsec3param.flags != 0)
1590 continue;
1592 * We have a active chain. Update it.
1594 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1596 dns_rdataset_disassociate(&rdataset);
1598 try_private:
1599 if (privatetype == 0)
1600 goto success;
1601 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1602 &rdataset, NULL);
1603 if (result == ISC_R_NOTFOUND)
1604 goto success;
1605 if (result != ISC_R_SUCCESS)
1606 goto failure;
1609 * Update each NSEC3 chain being built.
1611 for (result = dns_rdataset_first(&rdataset);
1612 result == ISC_R_SUCCESS;
1613 result = dns_rdataset_next(&rdataset)) {
1614 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1615 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1616 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1618 dns_rdataset_current(&rdataset, &rdata1);
1619 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1620 buf, sizeof(buf)))
1621 continue;
1622 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1624 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
1625 continue;
1626 if (better_param(&rdataset, &rdata2))
1627 continue;
1630 * We have a active chain. Update it.
1632 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1634 if (result == ISC_R_NOMORE)
1635 success:
1636 result = ISC_R_SUCCESS;
1638 failure:
1639 if (dns_rdataset_isassociated(&rdataset))
1640 dns_rdataset_disassociate(&rdataset);
1641 if (node != NULL)
1642 dns_db_detachnode(db, &node);
1644 return (result);
1647 isc_result_t
1648 dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version,
1649 isc_boolean_t complete, isc_boolean_t *answer)
1651 return (dns_nsec3_activex(db, version, complete, 0, answer));
1654 isc_result_t
1655 dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version,
1656 isc_boolean_t complete, dns_rdatatype_t privatetype,
1657 isc_boolean_t *answer)
1659 dns_dbnode_t *node = NULL;
1660 dns_rdataset_t rdataset;
1661 dns_rdata_nsec3param_t nsec3param;
1662 isc_result_t result;
1664 REQUIRE(answer != NULL);
1666 dns_rdataset_init(&rdataset);
1668 result = dns_db_getoriginnode(db, &node);
1669 if (result != ISC_R_SUCCESS)
1670 return (result);
1672 result = dns_db_findrdataset(db, node, version,
1673 dns_rdatatype_nsec3param, 0, 0,
1674 &rdataset, NULL);
1676 if (result == ISC_R_NOTFOUND)
1677 goto try_private;
1679 if (result != ISC_R_SUCCESS) {
1680 dns_db_detachnode(db, &node);
1681 return (result);
1683 for (result = dns_rdataset_first(&rdataset);
1684 result == ISC_R_SUCCESS;
1685 result = dns_rdataset_next(&rdataset)) {
1686 dns_rdata_t rdata = DNS_RDATA_INIT;
1688 dns_rdataset_current(&rdataset, &rdata);
1689 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
1690 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1692 if (nsec3param.flags == 0)
1693 break;
1695 dns_rdataset_disassociate(&rdataset);
1696 if (result == ISC_R_SUCCESS) {
1697 dns_db_detachnode(db, &node);
1698 *answer = ISC_TRUE;
1699 return (ISC_R_SUCCESS);
1701 if (result == ISC_R_NOMORE)
1702 *answer = ISC_FALSE;
1704 try_private:
1705 if (privatetype == 0 || complete) {
1706 *answer = ISC_FALSE;
1707 return (ISC_R_SUCCESS);
1709 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1710 &rdataset, NULL);
1712 dns_db_detachnode(db, &node);
1713 if (result == ISC_R_NOTFOUND) {
1714 *answer = ISC_FALSE;
1715 return (ISC_R_SUCCESS);
1717 if (result != ISC_R_SUCCESS)
1718 return (result);
1720 for (result = dns_rdataset_first(&rdataset);
1721 result == ISC_R_SUCCESS;
1722 result = dns_rdataset_next(&rdataset)) {
1723 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1724 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1725 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1727 dns_rdataset_current(&rdataset, &rdata1);
1728 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1729 buf, sizeof(buf)))
1730 continue;
1731 result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL);
1732 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1734 if (!complete && CREATE(nsec3param.flags))
1735 break;
1737 dns_rdataset_disassociate(&rdataset);
1738 if (result == ISC_R_SUCCESS) {
1739 *answer = ISC_TRUE;
1740 result = ISC_R_SUCCESS;
1742 if (result == ISC_R_NOMORE) {
1743 *answer = ISC_FALSE;
1744 result = ISC_R_SUCCESS;
1747 return (result);
1750 isc_result_t
1751 dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version,
1752 isc_mem_t *mctx, unsigned int *iterationsp)
1754 dns_dbnode_t *node = NULL;
1755 dns_rdataset_t rdataset;
1756 dst_key_t *key = NULL;
1757 isc_buffer_t buffer;
1758 isc_result_t result;
1759 unsigned int bits, minbits = 4096;
1761 result = dns_db_getoriginnode(db, &node);
1762 if (result != ISC_R_SUCCESS)
1763 return (result);
1765 dns_rdataset_init(&rdataset);
1766 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
1767 0, 0, &rdataset, NULL);
1768 dns_db_detachnode(db, &node);
1769 if (result == ISC_R_NOTFOUND) {
1770 *iterationsp = 0;
1771 return (ISC_R_SUCCESS);
1773 if (result != ISC_R_SUCCESS)
1774 goto failure;
1776 for (result = dns_rdataset_first(&rdataset);
1777 result == ISC_R_SUCCESS;
1778 result = dns_rdataset_next(&rdataset)) {
1779 dns_rdata_t rdata = DNS_RDATA_INIT;
1781 dns_rdataset_current(&rdataset, &rdata);
1782 isc_buffer_init(&buffer, rdata.data, rdata.length);
1783 isc_buffer_add(&buffer, rdata.length);
1784 CHECK(dst_key_fromdns(dns_db_origin(db), rdataset.rdclass,
1785 &buffer, mctx, &key));
1786 bits = dst_key_size(key);
1787 dst_key_free(&key);
1788 if (minbits > bits)
1789 minbits = bits;
1791 if (result != ISC_R_NOMORE)
1792 goto failure;
1794 if (minbits <= 1024)
1795 *iterationsp = 150;
1796 else if (minbits <= 2048)
1797 *iterationsp = 500;
1798 else
1799 *iterationsp = 2500;
1800 result = ISC_R_SUCCESS;
1802 failure:
1803 if (dns_rdataset_isassociated(&rdataset))
1804 dns_rdataset_disassociate(&rdataset);
1805 return (result);
1808 isc_result_t
1809 dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name,
1810 dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
1811 dns_name_t *zonename, isc_boolean_t *exists,
1812 isc_boolean_t *data, isc_boolean_t *optout,
1813 isc_boolean_t *unknown, isc_boolean_t *setclosest,
1814 isc_boolean_t *setnearest, dns_name_t *closest,
1815 dns_name_t *nearest, dns_nseclog_t logit, void *arg)
1817 char namebuf[DNS_NAME_FORMATSIZE];
1818 dns_fixedname_t fzone;
1819 dns_fixedname_t qfixed;
1820 dns_label_t hashlabel;
1821 dns_name_t *qname;
1822 dns_name_t *zone;
1823 dns_rdata_nsec3_t nsec3;
1824 dns_rdata_t rdata = DNS_RDATA_INIT;
1825 int order;
1826 int scope;
1827 isc_boolean_t atparent;
1828 isc_boolean_t first;
1829 isc_boolean_t ns;
1830 isc_boolean_t soa;
1831 isc_buffer_t buffer;
1832 isc_result_t answer = ISC_R_IGNORE;
1833 isc_result_t result;
1834 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
1835 unsigned char owner[NSEC3_MAX_HASH_LENGTH];
1836 unsigned int length;
1837 unsigned int qlabels;
1838 unsigned int zlabels;
1840 REQUIRE((exists == NULL && data == NULL) ||
1841 (exists != NULL && data != NULL));
1842 REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3);
1843 REQUIRE((setclosest == NULL && closest == NULL) ||
1844 (setclosest != NULL && closest != NULL));
1845 REQUIRE((setnearest == NULL && nearest == NULL) ||
1846 (setnearest != NULL && nearest != NULL));
1848 result = dns_rdataset_first(nsec3set);
1849 if (result != ISC_R_SUCCESS) {
1850 (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC3 set");
1851 return (result);
1854 dns_rdataset_current(nsec3set, &rdata);
1856 result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
1857 if (result != ISC_R_SUCCESS)
1858 return (result);
1860 (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC3");
1862 dns_fixedname_init(&fzone);
1863 zone = dns_fixedname_name(&fzone);
1864 zlabels = dns_name_countlabels(nsec3name);
1867 * NSEC3 records must have two or more labels to be valid.
1869 if (zlabels < 2)
1870 return (ISC_R_IGNORE);
1873 * Strip off the NSEC3 hash to get the zone.
1875 zlabels--;
1876 dns_name_split(nsec3name, zlabels, NULL, zone);
1879 * If not below the zone name we can ignore this record.
1881 if (!dns_name_issubdomain(name, zone))
1882 return (ISC_R_IGNORE);
1885 * Is this zone the same or deeper than the current zone?
1887 if (dns_name_countlabels(zonename) == 0 ||
1888 dns_name_issubdomain(zone, zonename))
1889 dns_name_copy(zone, zonename, NULL);
1891 if (!dns_name_equal(zone, zonename))
1892 return (ISC_R_IGNORE);
1895 * Are we only looking for the most enclosing zone?
1897 if (exists == NULL || data == NULL)
1898 return (ISC_R_SUCCESS);
1901 * Only set unknown once we are sure that this NSEC3 is from
1902 * the deepest covering zone.
1904 if (!dns_nsec3_supportedhash(nsec3.hash)) {
1905 if (unknown != NULL)
1906 *unknown = ISC_TRUE;
1907 return (ISC_R_IGNORE);
1911 * Recover the hash from the first label.
1913 dns_name_getlabel(nsec3name, 0, &hashlabel);
1914 isc_region_consume(&hashlabel, 1);
1915 isc_buffer_init(&buffer, owner, sizeof(owner));
1916 result = isc_base32hex_decoderegion(&hashlabel, &buffer);
1917 if (result != ISC_R_SUCCESS)
1918 return (result);
1921 * The hash lengths should match. If not ignore the record.
1923 if (isc_buffer_usedlength(&buffer) != nsec3.next_length)
1924 return (ISC_R_IGNORE);
1927 * Work out what this NSEC3 covers.
1928 * Inside (<0) or outside (>=0).
1930 scope = memcmp(owner, nsec3.next, nsec3.next_length);
1933 * Prepare to compute all the hashes.
1935 dns_fixedname_init(&qfixed);
1936 qname = dns_fixedname_name(&qfixed);
1937 dns_name_downcase(name, qname, NULL);
1938 qlabels = dns_name_countlabels(qname);
1939 first = ISC_TRUE;
1941 while (qlabels >= zlabels) {
1942 length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
1943 nsec3.salt, nsec3.salt_length,
1944 qname->ndata, qname->length);
1946 * The computed hash length should match.
1948 if (length != nsec3.next_length) {
1949 (*logit)(arg, ISC_LOG_DEBUG(3),
1950 "ignoring NSEC bad length %u vs %u",
1951 length, nsec3.next_length);
1952 return (ISC_R_IGNORE);
1955 order = memcmp(hash, owner, length);
1956 if (first && order == 0) {
1958 * The hashes are the same.
1960 atparent = dns_rdatatype_atparent(type);
1961 ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns);
1962 soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa);
1963 if (ns && !soa) {
1964 if (!atparent) {
1966 * This NSEC3 record is from somewhere
1967 * higher in the DNS, and at the
1968 * parent of a delegation. It can not
1969 * be legitimately used here.
1971 (*logit)(arg, ISC_LOG_DEBUG(3),
1972 "ignoring parent NSEC3");
1973 return (ISC_R_IGNORE);
1975 } else if (atparent && ns && soa) {
1977 * This NSEC3 record is from the child.
1978 * It can not be legitimately used here.
1980 (*logit)(arg, ISC_LOG_DEBUG(3),
1981 "ignoring child NSEC3");
1982 return (ISC_R_IGNORE);
1984 if (type == dns_rdatatype_cname ||
1985 type == dns_rdatatype_nxt ||
1986 type == dns_rdatatype_nsec ||
1987 type == dns_rdatatype_key ||
1988 !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) {
1989 *exists = ISC_TRUE;
1990 *data = dns_nsec3_typepresent(&rdata, type);
1991 (*logit)(arg, ISC_LOG_DEBUG(3),
1992 "NSEC3 proves name exists (owner) "
1993 "data=%d", *data);
1994 return (ISC_R_SUCCESS);
1996 (*logit)(arg, ISC_LOG_DEBUG(3),
1997 "NSEC3 proves CNAME exists");
1998 return (ISC_R_IGNORE);
2001 if (order == 0 &&
2002 dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) &&
2003 !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa))
2006 * This NSEC3 record is from somewhere higher in
2007 * the DNS, and at the parent of a delegation.
2008 * It can not be legitimately used here.
2010 (*logit)(arg, ISC_LOG_DEBUG(3),
2011 "ignoring parent NSEC3");
2012 return (ISC_R_IGNORE);
2016 * Potential closest encloser.
2018 if (order == 0) {
2019 if (closest != NULL &&
2020 (dns_name_countlabels(closest) == 0 ||
2021 dns_name_issubdomain(qname, closest)) &&
2022 !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) &&
2023 !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) &&
2024 (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) ||
2025 !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns)))
2028 dns_name_format(qname, namebuf,
2029 sizeof(namebuf));
2030 (*logit)(arg, ISC_LOG_DEBUG(3),
2031 "NSEC3 indicates potential closest "
2032 "encloser: '%s'", namebuf);
2033 dns_name_copy(qname, closest, NULL);
2034 *setclosest = ISC_TRUE;
2036 dns_name_format(qname, namebuf, sizeof(namebuf));
2037 (*logit)(arg, ISC_LOG_DEBUG(3),
2038 "NSEC3 at super-domain %s", namebuf);
2039 return (answer);
2043 * Find if the name does not exist.
2045 * We continue as we need to find the name closest to the
2046 * closest encloser that doesn't exist.
2048 * We also need to continue to ensure that we are not
2049 * proving the non-existence of a record in a sub-zone.
2050 * If that would be the case we will return ISC_R_IGNORE
2051 * above.
2053 if ((scope < 0 && order > 0 &&
2054 memcmp(hash, nsec3.next, length) < 0) ||
2055 (scope >= 0 && (order > 0 ||
2056 memcmp(hash, nsec3.next, length) < 0)))
2058 dns_name_format(qname, namebuf, sizeof(namebuf));
2059 (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves "
2060 "name does not exist: '%s'", namebuf);
2061 if (nearest != NULL &&
2062 (dns_name_countlabels(nearest) == 0 ||
2063 dns_name_issubdomain(nearest, qname))) {
2064 dns_name_copy(qname, nearest, NULL);
2065 *setnearest = ISC_TRUE;
2068 *exists = ISC_FALSE;
2069 *data = ISC_FALSE;
2070 if (optout != NULL) {
2071 if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0)
2072 (*logit)(arg, ISC_LOG_DEBUG(3),
2073 "NSEC3 indicates optout");
2074 else
2075 (*logit)(arg, ISC_LOG_DEBUG(3),
2076 "NSEC3 indicates secure range");
2077 *optout =
2078 ISC_TF(nsec3.flags & DNS_NSEC3FLAG_OPTOUT);
2080 answer = ISC_R_SUCCESS;
2083 qlabels--;
2084 if (qlabels > 0)
2085 dns_name_split(qname, qlabels, NULL, qname);
2086 first = ISC_FALSE;
2088 return (answer);