00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <config.h>
00020
00021 #include <isc/base32.h>
00022 #include <isc/buffer.h>
00023 #include <isc/hex.h>
00024 #include <isc/iterated_hash.h>
00025 #include <isc/log.h>
00026 #include <isc/string.h>
00027 #include <isc/util.h>
00028
00029 #include <dst/dst.h>
00030
00031 #include <dns/db.h>
00032 #include <dns/zone.h>
00033 #include <dns/compress.h>
00034 #include <dns/dbiterator.h>
00035 #include <dns/diff.h>
00036 #include <dns/fixedname.h>
00037 #include <dns/nsec.h>
00038 #include <dns/nsec3.h>
00039 #include <dns/rdata.h>
00040 #include <dns/rdatalist.h>
00041 #include <dns/rdataset.h>
00042 #include <dns/rdatasetiter.h>
00043 #include <dns/rdatastruct.h>
00044 #include <dns/result.h>
00045
00046 #define CHECK(x) do { \
00047 result = (x); \
00048 if (result != ISC_R_SUCCESS) \
00049 goto failure; \
00050 } while (0)
00051
00052 #define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
00053 #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
00054 #define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0)
00055 #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
00056
00057 isc_result_t
00058 dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
00059 dns_dbnode_t *node, unsigned int hashalg,
00060 unsigned int flags, unsigned int iterations,
00061 const unsigned char *salt, size_t salt_length,
00062 const unsigned char *nexthash, size_t hash_length,
00063 unsigned char *buffer, dns_rdata_t *rdata)
00064 {
00065 isc_result_t result;
00066 dns_rdataset_t rdataset;
00067 isc_region_t r;
00068 unsigned int i;
00069 isc_boolean_t found;
00070 isc_boolean_t found_ns;
00071 isc_boolean_t need_rrsig;
00072
00073 unsigned char *nsec_bits, *bm;
00074 unsigned int max_type;
00075 dns_rdatasetiter_t *rdsiter;
00076 unsigned char *p;
00077
00078 REQUIRE(salt_length < 256U);
00079 REQUIRE(hash_length < 256U);
00080 REQUIRE(flags <= 0xffU);
00081 REQUIRE(hashalg <= 0xffU);
00082 REQUIRE(iterations <= 0xffffU);
00083
00084 switch (hashalg) {
00085 case dns_hash_sha1:
00086 REQUIRE(hash_length == ISC_SHA1_DIGESTLENGTH);
00087 break;
00088 }
00089
00090 memset(buffer, 0, DNS_NSEC3_BUFFERSIZE);
00091
00092 p = buffer;
00093
00094 *p++ = hashalg;
00095 *p++ = flags;
00096
00097 *p++ = iterations >> 8;
00098 *p++ = iterations;
00099
00100 *p++ = (unsigned char)salt_length;
00101 memmove(p, salt, salt_length);
00102 p += salt_length;
00103
00104 *p++ = (unsigned char)hash_length;
00105 memmove(p, nexthash, hash_length);
00106 p += hash_length;
00107
00108 r.length = (unsigned int)(p - buffer);
00109 r.base = buffer;
00110
00111
00112
00113
00114
00115 bm = r.base + r.length + 512;
00116 nsec_bits = r.base + r.length;
00117 max_type = 0;
00118 if (node == NULL)
00119 goto collapse_bitmap;
00120 dns_rdataset_init(&rdataset);
00121 rdsiter = NULL;
00122 result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
00123 if (result != ISC_R_SUCCESS)
00124 return (result);
00125 found = found_ns = need_rrsig = ISC_FALSE;
00126 for (result = dns_rdatasetiter_first(rdsiter);
00127 result == ISC_R_SUCCESS;
00128 result = dns_rdatasetiter_next(rdsiter))
00129 {
00130 dns_rdatasetiter_current(rdsiter, &rdataset);
00131 if (rdataset.type != dns_rdatatype_nsec &&
00132 rdataset.type != dns_rdatatype_nsec3 &&
00133 rdataset.type != dns_rdatatype_rrsig) {
00134 if (rdataset.type > max_type)
00135 max_type = rdataset.type;
00136 dns_nsec_setbit(bm, rdataset.type, 1);
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 if (rdataset.type == dns_rdatatype_soa ||
00147 rdataset.type == dns_rdatatype_ds)
00148 need_rrsig = ISC_TRUE;
00149 else if (rdataset.type == dns_rdatatype_ns)
00150 found_ns = ISC_TRUE;
00151 else
00152 found = ISC_TRUE;
00153 }
00154 dns_rdataset_disassociate(&rdataset);
00155 }
00156 if ((found && !found_ns) || need_rrsig) {
00157 if (dns_rdatatype_rrsig > max_type)
00158 max_type = dns_rdatatype_rrsig;
00159 dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1);
00160 }
00161
00162
00163
00164
00165 if (dns_nsec_isset(bm, dns_rdatatype_ns) &&
00166 ! dns_nsec_isset(bm, dns_rdatatype_soa)) {
00167 for (i = 0; i <= max_type; i++) {
00168 if (dns_nsec_isset(bm, i) &&
00169 ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
00170 dns_nsec_setbit(bm, i, 0);
00171 }
00172 }
00173
00174 dns_rdatasetiter_destroy(&rdsiter);
00175 if (result != ISC_R_NOMORE)
00176 return (result);
00177
00178 collapse_bitmap:
00179 nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type);
00180 r.length = (unsigned int)(nsec_bits - r.base);
00181 INSIST(r.length <= DNS_NSEC3_BUFFERSIZE);
00182 dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r);
00183
00184 return (ISC_R_SUCCESS);
00185 }
00186
00187 isc_boolean_t
00188 dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) {
00189 dns_rdata_nsec3_t nsec3;
00190 isc_result_t result;
00191 isc_boolean_t present;
00192 unsigned int i, len, window;
00193
00194 REQUIRE(rdata != NULL);
00195 REQUIRE(rdata->type == dns_rdatatype_nsec3);
00196
00197
00198 result = dns_rdata_tostruct(rdata, &nsec3, NULL);
00199 INSIST(result == ISC_R_SUCCESS);
00200
00201 present = ISC_FALSE;
00202 for (i = 0; i < nsec3.len; i += len) {
00203 INSIST(i + 2 <= nsec3.len);
00204 window = nsec3.typebits[i];
00205 len = nsec3.typebits[i + 1];
00206 INSIST(len > 0 && len <= 32);
00207 i += 2;
00208 INSIST(i + len <= nsec3.len);
00209 if (window * 256 > type)
00210 break;
00211 if ((window + 1) * 256 <= type)
00212 continue;
00213 if (type < (window * 256) + len * 8)
00214 present = ISC_TF(dns_nsec_isset(&nsec3.typebits[i],
00215 type % 256));
00216 break;
00217 }
00218 dns_rdata_freestruct(&nsec3);
00219 return (present);
00220 }
00221
00222 isc_result_t
00223 dns_nsec3_hashname(dns_fixedname_t *result,
00224 unsigned char rethash[NSEC3_MAX_HASH_LENGTH],
00225 size_t *hash_length, dns_name_t *name, dns_name_t *origin,
00226 dns_hash_t hashalg, unsigned int iterations,
00227 const unsigned char *salt, size_t saltlength)
00228 {
00229 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
00230 unsigned char nametext[DNS_NAME_FORMATSIZE];
00231 dns_fixedname_t fixed;
00232 dns_name_t *downcased;
00233 isc_buffer_t namebuffer;
00234 isc_region_t region;
00235 size_t len;
00236
00237 if (rethash == NULL)
00238 rethash = hash;
00239
00240 memset(rethash, 0, NSEC3_MAX_HASH_LENGTH);
00241
00242 dns_fixedname_init(&fixed);
00243 downcased = dns_fixedname_name(&fixed);
00244 dns_name_downcase(name, downcased, NULL);
00245
00246
00247 len = isc_iterated_hash(rethash, hashalg, iterations,
00248 salt, (int)saltlength,
00249 downcased->ndata, downcased->length);
00250 if (len == 0U)
00251 return (DNS_R_BADALG);
00252
00253 if (hash_length != NULL)
00254 *hash_length = len;
00255
00256
00257 region.base = rethash;
00258 region.length = (unsigned int)len;
00259 isc_buffer_init(&namebuffer, nametext, sizeof nametext);
00260 isc_base32hexnp_totext(®ion, 1, "", &namebuffer);
00261
00262
00263 dns_fixedname_init(result);
00264 return (dns_name_fromtext(dns_fixedname_name(result), &namebuffer,
00265 origin, 0, NULL));
00266 }
00267
00268 unsigned int
00269 dns_nsec3_hashlength(dns_hash_t hash) {
00270
00271 switch (hash) {
00272 case dns_hash_sha1:
00273 return(ISC_SHA1_DIGESTLENGTH);
00274 }
00275 return (0);
00276 }
00277
00278 isc_boolean_t
00279 dns_nsec3_supportedhash(dns_hash_t hash) {
00280 switch (hash) {
00281 case dns_hash_sha1:
00282 return (ISC_TRUE);
00283 }
00284 return (ISC_FALSE);
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 static isc_result_t
00296 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
00297 dns_diff_t *diff)
00298 {
00299 dns_diff_t temp_diff;
00300 isc_result_t result;
00301
00302
00303
00304
00305 dns_diff_init(diff->mctx, &temp_diff);
00306 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
00307
00308
00309
00310
00311 result = dns_diff_apply(&temp_diff, db, ver);
00312 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
00313 if (result != ISC_R_SUCCESS) {
00314 dns_difftuple_free(tuple);
00315 return (result);
00316 }
00317
00318
00319
00320
00321 dns_diff_appendminimal(diff, tuple);
00322
00323
00324
00325
00326 return (ISC_R_SUCCESS);
00327 }
00328
00329
00330
00331
00332 static isc_result_t
00333 name_exists(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
00334 isc_boolean_t *exists)
00335 {
00336 isc_result_t result;
00337 dns_dbnode_t *node = NULL;
00338 dns_rdatasetiter_t *iter = NULL;
00339
00340 result = dns_db_findnode(db, name, ISC_FALSE, &node);
00341 if (result == ISC_R_NOTFOUND) {
00342 *exists = ISC_FALSE;
00343 return (ISC_R_SUCCESS);
00344 }
00345 if (result != ISC_R_SUCCESS)
00346 return (result);
00347
00348 result = dns_db_allrdatasets(db, node, version,
00349 (isc_stdtime_t) 0, &iter);
00350 if (result != ISC_R_SUCCESS)
00351 goto cleanup_node;
00352
00353 result = dns_rdatasetiter_first(iter);
00354 if (result == ISC_R_SUCCESS) {
00355 *exists = ISC_TRUE;
00356 } else if (result == ISC_R_NOMORE) {
00357 *exists = ISC_FALSE;
00358 result = ISC_R_SUCCESS;
00359 } else
00360 *exists = ISC_FALSE;
00361 dns_rdatasetiter_destroy(&iter);
00362
00363 cleanup_node:
00364 dns_db_detachnode(db, &node);
00365 return (result);
00366 }
00367
00368 static isc_boolean_t
00369 match_nsec3param(const dns_rdata_nsec3_t *nsec3,
00370 const dns_rdata_nsec3param_t *nsec3param)
00371 {
00372 if (nsec3->hash == nsec3param->hash &&
00373 nsec3->iterations == nsec3param->iterations &&
00374 nsec3->salt_length == nsec3param->salt_length &&
00375 !memcmp(nsec3->salt, nsec3param->salt, nsec3->salt_length))
00376 return (ISC_TRUE);
00377 return (ISC_FALSE);
00378 }
00379
00380
00381
00382
00383
00384 static isc_result_t
00385 delete(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
00386 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
00387 {
00388 dns_dbnode_t *node = NULL ;
00389 dns_difftuple_t *tuple = NULL;
00390 dns_rdata_nsec3_t nsec3;
00391 dns_rdataset_t rdataset;
00392 isc_result_t result;
00393
00394 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
00395 if (result == ISC_R_NOTFOUND)
00396 return (ISC_R_SUCCESS);
00397 if (result != ISC_R_SUCCESS)
00398 return (result);
00399
00400 dns_rdataset_init(&rdataset);
00401 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0,
00402 (isc_stdtime_t) 0, &rdataset, NULL);
00403
00404 if (result == ISC_R_NOTFOUND) {
00405 result = ISC_R_SUCCESS;
00406 goto cleanup_node;
00407 }
00408 if (result != ISC_R_SUCCESS)
00409 goto cleanup_node;
00410
00411 for (result = dns_rdataset_first(&rdataset);
00412 result == ISC_R_SUCCESS;
00413 result = dns_rdataset_next(&rdataset))
00414 {
00415 dns_rdata_t rdata = DNS_RDATA_INIT;
00416 dns_rdataset_current(&rdataset, &rdata);
00417 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
00418
00419 if (!match_nsec3param(&nsec3, nsec3param))
00420 continue;
00421
00422 result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name,
00423 rdataset.ttl, &rdata, &tuple);
00424 if (result != ISC_R_SUCCESS)
00425 goto failure;
00426 result = do_one_tuple(&tuple, db, version, diff);
00427 if (result != ISC_R_SUCCESS)
00428 goto failure;
00429 }
00430 if (result != ISC_R_NOMORE)
00431 goto failure;
00432 result = ISC_R_SUCCESS;
00433
00434 failure:
00435 dns_rdataset_disassociate(&rdataset);
00436 cleanup_node:
00437 dns_db_detachnode(db, &node);
00438
00439 return (result);
00440 }
00441
00442 static isc_boolean_t
00443 better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
00444 dns_rdataset_t rdataset;
00445 isc_result_t result;
00446
00447 if (REMOVE(param->data[1]))
00448 return (ISC_TRUE);
00449
00450 dns_rdataset_init(&rdataset);
00451 dns_rdataset_clone(nsec3paramset, &rdataset);
00452 for (result = dns_rdataset_first(&rdataset);
00453 result == ISC_R_SUCCESS;
00454 result = dns_rdataset_next(&rdataset)) {
00455 dns_rdata_t rdata = DNS_RDATA_INIT;
00456 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
00457
00458 if (rdataset.type != dns_rdatatype_nsec3param) {
00459 dns_rdata_t tmprdata = DNS_RDATA_INIT;
00460 dns_rdataset_current(&rdataset, &tmprdata);
00461 if (!dns_nsec3param_fromprivate(&tmprdata, &rdata,
00462 buf, sizeof(buf)))
00463 continue;
00464 } else
00465 dns_rdataset_current(&rdataset, &rdata);
00466
00467 if (rdata.length != param->length)
00468 continue;
00469 if (rdata.data[0] != param->data[0] ||
00470 REMOVE(rdata.data[1]) ||
00471 rdata.data[2] != param->data[2] ||
00472 rdata.data[3] != param->data[3] ||
00473 rdata.data[4] != param->data[4] ||
00474 memcmp(&rdata.data[5], ¶m->data[5], param->data[4]))
00475 continue;
00476 if (CREATE(rdata.data[1]) && !CREATE(param->data[1])) {
00477 dns_rdataset_disassociate(&rdataset);
00478 return (ISC_TRUE);
00479 }
00480 }
00481 dns_rdataset_disassociate(&rdataset);
00482 return (ISC_FALSE);
00483 }
00484
00485 static isc_result_t
00486 find_nsec3(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *rdataset,
00487 const dns_rdata_nsec3param_t *nsec3param)
00488 {
00489 isc_result_t result;
00490 for (result = dns_rdataset_first(rdataset);
00491 result == ISC_R_SUCCESS;
00492 result = dns_rdataset_next(rdataset)) {
00493 dns_rdata_t rdata = DNS_RDATA_INIT;
00494
00495 dns_rdataset_current(rdataset, &rdata);
00496 CHECK(dns_rdata_tostruct(&rdata, nsec3, NULL));
00497 dns_rdata_reset(&rdata);
00498 if (match_nsec3param(nsec3, nsec3param))
00499 break;
00500 }
00501 failure:
00502 return (result);
00503 }
00504
00505 isc_result_t
00506 dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
00507 dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param,
00508 dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_diff_t *diff)
00509 {
00510 dns_dbiterator_t *dbit = NULL;
00511 dns_dbnode_t *node = NULL;
00512 dns_dbnode_t *newnode = NULL;
00513 dns_difftuple_t *tuple = NULL;
00514 dns_fixedname_t fixed;
00515 dns_fixedname_t fprev;
00516 dns_hash_t hash;
00517 dns_name_t *hashname;
00518 dns_name_t *origin;
00519 dns_name_t *prev;
00520 dns_name_t empty;
00521 dns_rdata_nsec3_t nsec3;
00522 dns_rdata_t rdata = DNS_RDATA_INIT;
00523 dns_rdataset_t rdataset;
00524 int pass;
00525 isc_boolean_t exists = ISC_FALSE;
00526 isc_boolean_t maybe_remove_unsecure = ISC_FALSE;
00527 isc_uint8_t flags;
00528 isc_buffer_t buffer;
00529 isc_result_t result;
00530 unsigned char *old_next;
00531 unsigned char *salt;
00532 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
00533 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
00534 unsigned int iterations;
00535 unsigned int labels;
00536 size_t next_length;
00537 unsigned int old_length;
00538 unsigned int salt_length;
00539
00540 dns_fixedname_init(&fixed);
00541 hashname = dns_fixedname_name(&fixed);
00542 dns_fixedname_init(&fprev);
00543 prev = dns_fixedname_name(&fprev);
00544
00545 dns_rdataset_init(&rdataset);
00546
00547 origin = dns_db_origin(db);
00548
00549
00550
00551
00552 hash = nsec3param->hash;
00553 iterations = nsec3param->iterations;
00554 salt_length = nsec3param->salt_length;
00555 salt = nsec3param->salt;
00556
00557
00558
00559
00560 flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
00561
00562
00563
00564
00565
00566 next_length = sizeof(nexthash);
00567 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
00568 name, origin, hash, iterations,
00569 salt, salt_length));
00570 INSIST(next_length <= sizeof(nexthash));
00571
00572
00573
00574
00575
00576 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
00577
00578
00579
00580
00581 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
00582 CHECK(dns_dbiterator_seek(dbit, hashname));
00583 CHECK(dns_dbiterator_pause(dbit));
00584 result = dns_db_findrdataset(db, newnode, version, dns_rdatatype_nsec3,
00585 0, (isc_stdtime_t) 0, &rdataset, NULL);
00586
00587
00588
00589
00590 if (result == ISC_R_SUCCESS) {
00591 result = find_nsec3(&nsec3, &rdataset, nsec3param);
00592 if (result == ISC_R_SUCCESS) {
00593 if (!CREATE(nsec3param->flags))
00594 flags = nsec3.flags;
00595 next_length = nsec3.next_length;
00596 INSIST(next_length <= sizeof(nexthash));
00597 memmove(nexthash, nsec3.next, next_length);
00598 dns_rdataset_disassociate(&rdataset);
00599
00600
00601
00602
00603
00604
00605
00606 if (!unsecure)
00607 goto addnsec3;
00608 else if (CREATE(nsec3param->flags) && OPTOUT(flags)) {
00609 result = dns_nsec3_delnsec3(db, version, name,
00610 nsec3param, diff);
00611 goto failure;
00612 } else
00613 maybe_remove_unsecure = ISC_TRUE;
00614 } else {
00615 dns_rdataset_disassociate(&rdataset);
00616 if (result != ISC_R_NOMORE)
00617 goto failure;
00618 }
00619 }
00620
00621
00622
00623
00624 pass = 0;
00625 do {
00626 result = dns_dbiterator_prev(dbit);
00627 if (result == ISC_R_NOMORE) {
00628 pass++;
00629 CHECK(dns_dbiterator_last(dbit));
00630 }
00631 CHECK(dns_dbiterator_current(dbit, &node, prev));
00632 CHECK(dns_dbiterator_pause(dbit));
00633 result = dns_db_findrdataset(db, node, version,
00634 dns_rdatatype_nsec3, 0,
00635 (isc_stdtime_t) 0, &rdataset,
00636 NULL);
00637 dns_db_detachnode(db, &node);
00638 if (result != ISC_R_SUCCESS)
00639 continue;
00640
00641 result = find_nsec3(&nsec3, &rdataset, nsec3param);
00642 if (result == ISC_R_NOMORE) {
00643 dns_rdataset_disassociate(&rdataset);
00644 continue;
00645 }
00646 if (result != ISC_R_SUCCESS)
00647 goto failure;
00648
00649 if (maybe_remove_unsecure) {
00650 dns_rdataset_disassociate(&rdataset);
00651
00652
00653
00654
00655
00656 if (OPTOUT(nsec3.flags)) {
00657 result = dns_nsec3_delnsec3(db, version, name,
00658 nsec3param, diff);
00659 goto failure;
00660 }
00661 goto addnsec3;
00662 } else {
00663
00664
00665
00666
00667 if (OPTOUT(nsec3.flags) && unsecure) {
00668 dns_rdataset_disassociate(&rdataset);
00669 goto failure;
00670 }
00671 }
00672
00673 old_next = nsec3.next;
00674 old_length = nsec3.next_length;
00675
00676
00677
00678
00679 CHECK(delete(db, version, prev, nsec3param, diff));
00680
00681
00682
00683
00684 nsec3.next = nexthash;
00685 nsec3.next_length = (unsigned char)next_length;
00686 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
00687 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
00688 dns_rdatatype_nsec3, &nsec3,
00689 &buffer));
00690 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
00691 rdataset.ttl, &rdata, &tuple));
00692 CHECK(do_one_tuple(&tuple, db, version, diff));
00693 INSIST(old_length <= sizeof(nexthash));
00694 memmove(nexthash, old_next, old_length);
00695 if (!CREATE(nsec3param->flags))
00696 flags = nsec3.flags;
00697 dns_rdata_reset(&rdata);
00698 dns_rdataset_disassociate(&rdataset);
00699 break;
00700 } while (pass < 2);
00701
00702 addnsec3:
00703
00704
00705
00706 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
00707 CHECK(dns_nsec3_buildrdata(db, version, node, hash, flags, iterations,
00708 salt, salt_length, nexthash, next_length,
00709 nsec3buf, &rdata));
00710 dns_db_detachnode(db, &node);
00711
00712
00713
00714
00715 CHECK(delete(db, version, hashname, nsec3param, diff));
00716
00717
00718
00719 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
00720 hashname, nsecttl, &rdata, &tuple));
00721 CHECK(do_one_tuple(&tuple, db, version, diff));
00722 INSIST(tuple == NULL);
00723 dns_rdata_reset(&rdata);
00724 dns_db_detachnode(db, &newnode);
00725
00726
00727
00728
00729 dns_name_init(&empty, NULL);
00730 dns_name_clone(name, &empty);
00731 do {
00732 labels = dns_name_countlabels(&empty) - 1;
00733 if (labels <= dns_name_countlabels(origin))
00734 break;
00735 dns_name_getlabelsequence(&empty, 1, labels, &empty);
00736 CHECK(name_exists(db, version, &empty, &exists));
00737 if (exists)
00738 break;
00739 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
00740 &empty, origin, hash, iterations,
00741 salt, salt_length));
00742
00743
00744
00745
00746
00747
00748 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
00749 result = dns_db_findrdataset(db, newnode, version,
00750 dns_rdatatype_nsec3, 0,
00751 (isc_stdtime_t) 0, &rdataset,
00752 NULL);
00753 if (result == ISC_R_SUCCESS) {
00754 result = find_nsec3(&nsec3, &rdataset, nsec3param);
00755 dns_rdataset_disassociate(&rdataset);
00756 if (result == ISC_R_SUCCESS) {
00757 dns_db_detachnode(db, &newnode);
00758 break;
00759 }
00760 if (result != ISC_R_NOMORE)
00761 goto failure;
00762 }
00763
00764
00765
00766
00767 CHECK(dns_dbiterator_seek(dbit, hashname));
00768 pass = 0;
00769 do {
00770 result = dns_dbiterator_prev(dbit);
00771 if (result == ISC_R_NOMORE) {
00772 pass++;
00773 CHECK(dns_dbiterator_last(dbit));
00774 }
00775 CHECK(dns_dbiterator_current(dbit, &node, prev));
00776 CHECK(dns_dbiterator_pause(dbit));
00777 result = dns_db_findrdataset(db, node, version,
00778 dns_rdatatype_nsec3, 0,
00779 (isc_stdtime_t) 0,
00780 &rdataset, NULL);
00781 dns_db_detachnode(db, &node);
00782 if (result != ISC_R_SUCCESS)
00783 continue;
00784 result = find_nsec3(&nsec3, &rdataset, nsec3param);
00785 if (result == ISC_R_NOMORE) {
00786 dns_rdataset_disassociate(&rdataset);
00787 continue;
00788 }
00789 if (result != ISC_R_SUCCESS)
00790 goto failure;
00791
00792 old_next = nsec3.next;
00793 old_length = nsec3.next_length;
00794
00795
00796
00797
00798 CHECK(delete(db, version, prev, nsec3param, diff));
00799
00800
00801
00802
00803 nsec3.next = nexthash;
00804 nsec3.next_length = (unsigned char)next_length;
00805 isc_buffer_init(&buffer, nsec3buf,
00806 sizeof(nsec3buf));
00807 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
00808 dns_rdatatype_nsec3, &nsec3,
00809 &buffer));
00810 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
00811 prev, rdataset.ttl, &rdata,
00812 &tuple));
00813 CHECK(do_one_tuple(&tuple, db, version, diff));
00814 INSIST(old_length <= sizeof(nexthash));
00815 memmove(nexthash, old_next, old_length);
00816 if (!CREATE(nsec3param->flags))
00817 flags = nsec3.flags;
00818 dns_rdata_reset(&rdata);
00819 dns_rdataset_disassociate(&rdataset);
00820 break;
00821 } while (pass < 2);
00822
00823 INSIST(pass < 2);
00824
00825
00826
00827
00828 CHECK(dns_nsec3_buildrdata(db, version, NULL, hash, flags,
00829 iterations, salt, salt_length,
00830 nexthash, next_length, nsec3buf,
00831 &rdata));
00832
00833
00834
00835 CHECK(delete(db, version, hashname, nsec3param, diff));
00836
00837
00838
00839
00840 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
00841 hashname, nsecttl, &rdata, &tuple));
00842 CHECK(do_one_tuple(&tuple, db, version, diff));
00843 INSIST(tuple == NULL);
00844 dns_rdata_reset(&rdata);
00845 dns_db_detachnode(db, &newnode);
00846 } while (1);
00847
00848
00849 INSIST(result != ISC_R_NOMORE);
00850
00851 failure:
00852 if (dbit != NULL)
00853 dns_dbiterator_destroy(&dbit);
00854 if (dns_rdataset_isassociated(&rdataset))
00855 dns_rdataset_disassociate(&rdataset);
00856 if (node != NULL)
00857 dns_db_detachnode(db, &node);
00858 if (newnode != NULL)
00859 dns_db_detachnode(db, &newnode);
00860 return (result);
00861 }
00862
00863
00864
00865
00866
00867 isc_result_t
00868 dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
00869 dns_name_t *name, dns_ttl_t nsecttl,
00870 isc_boolean_t unsecure, dns_diff_t *diff)
00871 {
00872 dns_dbnode_t *node = NULL;
00873 dns_rdata_nsec3param_t nsec3param;
00874 dns_rdataset_t rdataset;
00875 isc_result_t result;
00876
00877 dns_rdataset_init(&rdataset);
00878
00879
00880
00881
00882 result = dns_db_getoriginnode(db, &node);
00883 if (result != ISC_R_SUCCESS)
00884 return (result);
00885
00886 result = dns_db_findrdataset(db, node, version,
00887 dns_rdatatype_nsec3param, 0, 0,
00888 &rdataset, NULL);
00889 dns_db_detachnode(db, &node);
00890 if (result == ISC_R_NOTFOUND)
00891 return (ISC_R_SUCCESS);
00892 if (result != ISC_R_SUCCESS)
00893 return (result);
00894
00895
00896
00897
00898 for (result = dns_rdataset_first(&rdataset);
00899 result == ISC_R_SUCCESS;
00900 result = dns_rdataset_next(&rdataset)) {
00901 dns_rdata_t rdata = DNS_RDATA_INIT;
00902
00903 dns_rdataset_current(&rdataset, &rdata);
00904 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
00905
00906 if (nsec3param.flags != 0)
00907 continue;
00908
00909
00910
00911 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
00912 nsecttl, unsecure, diff));
00913 }
00914 if (result == ISC_R_NOMORE)
00915 result = ISC_R_SUCCESS;
00916
00917 failure:
00918 if (dns_rdataset_isassociated(&rdataset))
00919 dns_rdataset_disassociate(&rdataset);
00920 if (node != NULL)
00921 dns_db_detachnode(db, &node);
00922
00923 return (result);
00924 }
00925
00926 isc_boolean_t
00927 dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target,
00928 unsigned char *buf, size_t buflen)
00929 {
00930 dns_decompress_t dctx;
00931 isc_result_t result;
00932 isc_buffer_t buf1;
00933 isc_buffer_t buf2;
00934
00935
00936
00937
00938
00939 if (src->length < 1 || src->data[0] != 0)
00940 return (ISC_FALSE);
00941
00942 isc_buffer_init(&buf1, src->data + 1, src->length - 1);
00943 isc_buffer_add(&buf1, src->length - 1);
00944 isc_buffer_setactive(&buf1, src->length - 1);
00945 isc_buffer_init(&buf2, buf, (unsigned int)buflen);
00946 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
00947 result = dns_rdata_fromwire(target, src->rdclass,
00948 dns_rdatatype_nsec3param,
00949 &buf1, &dctx, 0, &buf2);
00950 dns_decompress_invalidate(&dctx);
00951
00952 return (ISC_TF(result == ISC_R_SUCCESS));
00953 }
00954
00955 void
00956 dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target,
00957 dns_rdatatype_t privatetype,
00958 unsigned char *buf, size_t buflen)
00959 {
00960 REQUIRE(buflen >= src->length + 1);
00961
00962 REQUIRE(DNS_RDATA_INITIALIZED(target));
00963
00964 memmove(buf + 1, src->data, src->length);
00965 buf[0] = 0;
00966 target->data = buf;
00967 target->length = src->length + 1;
00968 target->type = privatetype;
00969 target->rdclass = src->rdclass;
00970 target->flags = 0;
00971 ISC_LINK_INIT(target, link);
00972 }
00973
00974 static isc_result_t
00975 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
00976 const dns_rdata_t *rdata, isc_boolean_t *flag)
00977 {
00978 dns_rdataset_t rdataset;
00979 dns_dbnode_t *node = NULL;
00980 isc_result_t result;
00981
00982 dns_rdataset_init(&rdataset);
00983 if (rdata->type == dns_rdatatype_nsec3)
00984 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
00985 else
00986 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
00987 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
00988 (isc_stdtime_t) 0, &rdataset, NULL);
00989 if (result == ISC_R_NOTFOUND) {
00990 *flag = ISC_FALSE;
00991 result = ISC_R_SUCCESS;
00992 goto failure;
00993 }
00994
00995 for (result = dns_rdataset_first(&rdataset);
00996 result == ISC_R_SUCCESS;
00997 result = dns_rdataset_next(&rdataset)) {
00998 dns_rdata_t myrdata = DNS_RDATA_INIT;
00999 dns_rdataset_current(&rdataset, &myrdata);
01000 if (!dns_rdata_casecompare(&myrdata, rdata))
01001 break;
01002 }
01003 dns_rdataset_disassociate(&rdataset);
01004 if (result == ISC_R_SUCCESS) {
01005 *flag = ISC_TRUE;
01006 } else if (result == ISC_R_NOMORE) {
01007 *flag = ISC_FALSE;
01008 result = ISC_R_SUCCESS;
01009 }
01010
01011 failure:
01012 if (node != NULL)
01013 dns_db_detachnode(db, &node);
01014 return (result);
01015 }
01016
01017 isc_result_t
01018 dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
01019 dns_zone_t *zone, isc_boolean_t nonsec,
01020 dns_diff_t *diff)
01021 {
01022 dns_dbnode_t *node = NULL;
01023 dns_difftuple_t *tuple = NULL;
01024 dns_name_t next;
01025 dns_rdata_t rdata = DNS_RDATA_INIT;
01026 dns_rdataset_t rdataset;
01027 isc_boolean_t flag;
01028 isc_result_t result = ISC_R_SUCCESS;
01029 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1];
01030 dns_name_t *origin = dns_zone_getorigin(zone);
01031 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
01032
01033 dns_name_init(&next, NULL);
01034 dns_rdataset_init(&rdataset);
01035
01036 result = dns_db_getoriginnode(db, &node);
01037 if (result != ISC_R_SUCCESS)
01038 return (result);
01039
01040
01041
01042
01043 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
01044 0, (isc_stdtime_t) 0, &rdataset, NULL);
01045 if (result == ISC_R_NOTFOUND)
01046 goto try_private;
01047 if (result != ISC_R_SUCCESS)
01048 goto failure;
01049
01050 for (result = dns_rdataset_first(&rdataset);
01051 result == ISC_R_SUCCESS;
01052 result = dns_rdataset_next(&rdataset)) {
01053 dns_rdata_t private = DNS_RDATA_INIT;
01054
01055 dns_rdataset_current(&rdataset, &rdata);
01056
01057 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
01058 rdataset.ttl, &rdata, &tuple));
01059 CHECK(do_one_tuple(&tuple, db, ver, diff));
01060 INSIST(tuple == NULL);
01061
01062 dns_nsec3param_toprivate(&rdata, &private, privatetype,
01063 buf, sizeof(buf));
01064 buf[2] = DNS_NSEC3FLAG_REMOVE;
01065 if (nonsec)
01066 buf[2] |= DNS_NSEC3FLAG_NONSEC;
01067
01068 CHECK(rr_exists(db, ver, origin, &private, &flag));
01069
01070 if (!flag) {
01071 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
01072 origin, 0, &private,
01073 &tuple));
01074 CHECK(do_one_tuple(&tuple, db, ver, diff));
01075 INSIST(tuple == NULL);
01076 }
01077 dns_rdata_reset(&rdata);
01078 }
01079 if (result != ISC_R_NOMORE)
01080 goto failure;
01081
01082 dns_rdataset_disassociate(&rdataset);
01083
01084 try_private:
01085 if (privatetype == 0)
01086 goto success;
01087 result = dns_db_findrdataset(db, node, ver, privatetype, 0,
01088 (isc_stdtime_t) 0, &rdataset, NULL);
01089 if (result == ISC_R_NOTFOUND)
01090 goto success;
01091 if (result != ISC_R_SUCCESS)
01092 goto failure;
01093
01094 for (result = dns_rdataset_first(&rdataset);
01095 result == ISC_R_SUCCESS;
01096 result = dns_rdataset_next(&rdataset)) {
01097 dns_rdata_reset(&rdata);
01098 dns_rdataset_current(&rdataset, &rdata);
01099 INSIST(rdata.length <= sizeof(buf));
01100 memmove(buf, rdata.data, rdata.length);
01101
01102
01103
01104
01105
01106 if (rdata.length < 6 || buf[0] != 0 ||
01107 (buf[2] & DNS_NSEC3FLAG_REMOVE) != 0 ||
01108 (nonsec && (buf[2] & DNS_NSEC3FLAG_NONSEC) != 0))
01109 continue;
01110
01111 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
01112 0, &rdata, &tuple));
01113 CHECK(do_one_tuple(&tuple, db, ver, diff));
01114 INSIST(tuple == NULL);
01115
01116 rdata.data = buf;
01117 buf[2] = DNS_NSEC3FLAG_REMOVE;
01118 if (nonsec)
01119 buf[2] |= DNS_NSEC3FLAG_NONSEC;
01120
01121 CHECK(rr_exists(db, ver, origin, &rdata, &flag));
01122
01123 if (!flag) {
01124 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
01125 origin, 0, &rdata, &tuple));
01126 CHECK(do_one_tuple(&tuple, db, ver, diff));
01127 INSIST(tuple == NULL);
01128 }
01129 }
01130 if (result != ISC_R_NOMORE)
01131 goto failure;
01132 success:
01133 result = ISC_R_SUCCESS;
01134
01135 failure:
01136 if (dns_rdataset_isassociated(&rdataset))
01137 dns_rdataset_disassociate(&rdataset);
01138 dns_db_detachnode(db, &node);
01139 return (result);
01140 }
01141
01142 isc_result_t
01143 dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version,
01144 dns_name_t *name, dns_ttl_t nsecttl,
01145 isc_boolean_t unsecure, dns_rdatatype_t type,
01146 dns_diff_t *diff)
01147 {
01148 dns_dbnode_t *node = NULL;
01149 dns_rdata_nsec3param_t nsec3param;
01150 dns_rdataset_t rdataset;
01151 dns_rdataset_t prdataset;
01152 isc_result_t result;
01153
01154 dns_rdataset_init(&rdataset);
01155 dns_rdataset_init(&prdataset);
01156
01157
01158
01159
01160 result = dns_db_getoriginnode(db, &node);
01161 if (result != ISC_R_SUCCESS)
01162 return (result);
01163
01164 result = dns_db_findrdataset(db, node, version, type, 0, 0,
01165 &prdataset, NULL);
01166 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
01167 goto failure;
01168
01169 result = dns_db_findrdataset(db, node, version,
01170 dns_rdatatype_nsec3param, 0, 0,
01171 &rdataset, NULL);
01172 if (result == ISC_R_NOTFOUND)
01173 goto try_private;
01174 if (result != ISC_R_SUCCESS)
01175 goto failure;
01176
01177
01178
01179
01180 for (result = dns_rdataset_first(&rdataset);
01181 result == ISC_R_SUCCESS;
01182 result = dns_rdataset_next(&rdataset)) {
01183 dns_rdata_t rdata = DNS_RDATA_INIT;
01184
01185 dns_rdataset_current(&rdataset, &rdata);
01186 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
01187
01188 if (nsec3param.flags != 0)
01189 continue;
01190
01191
01192
01193
01194 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
01195 nsecttl, unsecure, diff));
01196 }
01197 if (result != ISC_R_NOMORE)
01198 goto failure;
01199
01200 dns_rdataset_disassociate(&rdataset);
01201
01202 try_private:
01203 if (!dns_rdataset_isassociated(&prdataset))
01204 goto success;
01205
01206
01207
01208 for (result = dns_rdataset_first(&prdataset);
01209 result == ISC_R_SUCCESS;
01210 result = dns_rdataset_next(&prdataset)) {
01211 dns_rdata_t rdata1 = DNS_RDATA_INIT;
01212 dns_rdata_t rdata2 = DNS_RDATA_INIT;
01213 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
01214
01215 dns_rdataset_current(&prdataset, &rdata1);
01216 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
01217 buf, sizeof(buf)))
01218 continue;
01219 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
01220
01221 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
01222 continue;
01223 if (better_param(&prdataset, &rdata2))
01224 continue;
01225
01226
01227
01228
01229 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
01230 nsecttl, unsecure, diff));
01231 }
01232 if (result == ISC_R_NOMORE)
01233 success:
01234 result = ISC_R_SUCCESS;
01235 failure:
01236 if (dns_rdataset_isassociated(&rdataset))
01237 dns_rdataset_disassociate(&rdataset);
01238 if (dns_rdataset_isassociated(&prdataset))
01239 dns_rdataset_disassociate(&prdataset);
01240 if (node != NULL)
01241 dns_db_detachnode(db, &node);
01242
01243 return (result);
01244 }
01245
01246
01247
01248
01249
01250
01251
01252 static isc_result_t
01253 deleteit(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
01254 isc_boolean_t *yesno)
01255 {
01256 isc_result_t result;
01257 dns_fixedname_t foundname;
01258 dns_fixedname_init(&foundname);
01259
01260 result = dns_db_find(db, name, ver, dns_rdatatype_any,
01261 DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
01262 (isc_stdtime_t) 0, NULL,
01263 dns_fixedname_name(&foundname),
01264 NULL, NULL);
01265 if (result == DNS_R_EMPTYNAME || result == ISC_R_SUCCESS ||
01266 result == DNS_R_ZONECUT) {
01267 *yesno = ISC_FALSE;
01268 return (ISC_R_SUCCESS);
01269 }
01270 if (result == DNS_R_GLUE || result == DNS_R_DNAME ||
01271 result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) {
01272 *yesno = ISC_TRUE;
01273 return (ISC_R_SUCCESS);
01274 }
01275
01276
01277
01278 *yesno = ISC_TRUE;
01279 return (result);
01280 }
01281
01282 isc_result_t
01283 dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
01284 const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
01285 {
01286 dns_dbiterator_t *dbit = NULL;
01287 dns_dbnode_t *node = NULL;
01288 dns_difftuple_t *tuple = NULL;
01289 dns_fixedname_t fixed;
01290 dns_fixedname_t fprev;
01291 dns_hash_t hash;
01292 dns_name_t *hashname;
01293 dns_name_t *origin;
01294 dns_name_t *prev;
01295 dns_name_t empty;
01296 dns_rdata_nsec3_t nsec3;
01297 dns_rdata_t rdata = DNS_RDATA_INIT;
01298 dns_rdataset_t rdataset;
01299 int pass;
01300 isc_boolean_t yesno;
01301 isc_buffer_t buffer;
01302 isc_result_t result;
01303 unsigned char *salt;
01304 unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
01305 unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
01306 unsigned int iterations;
01307 unsigned int labels;
01308 size_t next_length;
01309 unsigned int salt_length;
01310
01311 dns_fixedname_init(&fixed);
01312 hashname = dns_fixedname_name(&fixed);
01313 dns_fixedname_init(&fprev);
01314 prev = dns_fixedname_name(&fprev);
01315
01316 dns_rdataset_init(&rdataset);
01317
01318 origin = dns_db_origin(db);
01319
01320
01321
01322
01323 hash = nsec3param->hash;
01324 iterations = nsec3param->iterations;
01325 salt_length = nsec3param->salt_length;
01326 salt = nsec3param->salt;
01327
01328
01329
01330
01331
01332 next_length = sizeof(nexthash);
01333 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
01334 name, origin, hash, iterations,
01335 salt, salt_length));
01336
01337 CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
01338
01339 result = dns_dbiterator_seek(dbit, hashname);
01340 if (result == ISC_R_NOTFOUND)
01341 goto success;
01342 if (result != ISC_R_SUCCESS)
01343 goto failure;
01344
01345 CHECK(dns_dbiterator_current(dbit, &node, NULL));
01346 CHECK(dns_dbiterator_pause(dbit));
01347 result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3,
01348 0, (isc_stdtime_t) 0, &rdataset, NULL);
01349 dns_db_detachnode(db, &node);
01350 if (result == ISC_R_NOTFOUND)
01351 goto success;
01352 if (result != ISC_R_SUCCESS)
01353 goto failure;
01354
01355
01356
01357
01358
01359 result = find_nsec3(&nsec3, &rdataset, nsec3param);
01360 if (result == ISC_R_SUCCESS) {
01361 next_length = nsec3.next_length;
01362 INSIST(next_length <= sizeof(nexthash));
01363 memmove(nexthash, nsec3.next, next_length);
01364 }
01365 dns_rdataset_disassociate(&rdataset);
01366 if (result == ISC_R_NOMORE)
01367 goto success;
01368 if (result != ISC_R_SUCCESS)
01369 goto failure;
01370
01371
01372
01373
01374 pass = 0;
01375 do {
01376 result = dns_dbiterator_prev(dbit);
01377 if (result == ISC_R_NOMORE) {
01378 pass++;
01379 CHECK(dns_dbiterator_last(dbit));
01380 }
01381 CHECK(dns_dbiterator_current(dbit, &node, prev));
01382 CHECK(dns_dbiterator_pause(dbit));
01383 result = dns_db_findrdataset(db, node, version,
01384 dns_rdatatype_nsec3, 0,
01385 (isc_stdtime_t) 0, &rdataset,
01386 NULL);
01387 dns_db_detachnode(db, &node);
01388 if (result != ISC_R_SUCCESS)
01389 continue;
01390 result = find_nsec3(&nsec3, &rdataset, nsec3param);
01391 if (result == ISC_R_NOMORE) {
01392 dns_rdataset_disassociate(&rdataset);
01393 continue;
01394 }
01395 if (result != ISC_R_SUCCESS)
01396 goto failure;
01397
01398
01399
01400
01401 CHECK(delete(db, version, prev, nsec3param, diff));
01402
01403
01404
01405
01406 nsec3.next = nexthash;
01407 nsec3.next_length = (unsigned char)next_length;
01408 if (CREATE(nsec3param->flags))
01409 nsec3.flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
01410 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
01411 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
01412 dns_rdatatype_nsec3, &nsec3,
01413 &buffer));
01414 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
01415 rdataset.ttl, &rdata, &tuple));
01416 CHECK(do_one_tuple(&tuple, db, version, diff));
01417 dns_rdata_reset(&rdata);
01418 dns_rdataset_disassociate(&rdataset);
01419 break;
01420 } while (pass < 2);
01421
01422
01423
01424
01425 CHECK(delete(db, version, hashname, nsec3param, diff));
01426
01427
01428
01429
01430 dns_name_init(&empty, NULL);
01431 dns_name_clone(name, &empty);
01432 do {
01433 labels = dns_name_countlabels(&empty) - 1;
01434 if (labels <= dns_name_countlabels(origin))
01435 break;
01436 dns_name_getlabelsequence(&empty, 1, labels, &empty);
01437 CHECK(deleteit(db, version, &empty, &yesno));
01438 if (!yesno)
01439 break;
01440
01441 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
01442 &empty, origin, hash, iterations,
01443 salt, salt_length));
01444 result = dns_dbiterator_seek(dbit, hashname);
01445 if (result == ISC_R_NOTFOUND)
01446 goto success;
01447 if (result != ISC_R_SUCCESS)
01448 goto failure;
01449
01450 CHECK(dns_dbiterator_current(dbit, &node, NULL));
01451 CHECK(dns_dbiterator_pause(dbit));
01452 result = dns_db_findrdataset(db, node, version,
01453 dns_rdatatype_nsec3, 0,
01454 (isc_stdtime_t) 0, &rdataset,
01455 NULL);
01456 dns_db_detachnode(db, &node);
01457 if (result == ISC_R_NOTFOUND)
01458 goto success;
01459 if (result != ISC_R_SUCCESS)
01460 goto failure;
01461
01462 result = find_nsec3(&nsec3, &rdataset, nsec3param);
01463 if (result == ISC_R_SUCCESS) {
01464 next_length = nsec3.next_length;
01465 INSIST(next_length <= sizeof(nexthash));
01466 memmove(nexthash, nsec3.next, next_length);
01467 }
01468 dns_rdataset_disassociate(&rdataset);
01469 if (result == ISC_R_NOMORE)
01470 goto success;
01471 if (result != ISC_R_SUCCESS)
01472 goto failure;
01473
01474 pass = 0;
01475 do {
01476 result = dns_dbiterator_prev(dbit);
01477 if (result == ISC_R_NOMORE) {
01478 pass++;
01479 CHECK(dns_dbiterator_last(dbit));
01480 }
01481 CHECK(dns_dbiterator_current(dbit, &node, prev));
01482 CHECK(dns_dbiterator_pause(dbit));
01483 result = dns_db_findrdataset(db, node, version,
01484 dns_rdatatype_nsec3, 0,
01485 (isc_stdtime_t) 0,
01486 &rdataset, NULL);
01487 dns_db_detachnode(db, &node);
01488 if (result != ISC_R_SUCCESS)
01489 continue;
01490 result = find_nsec3(&nsec3, &rdataset, nsec3param);
01491 if (result == ISC_R_NOMORE) {
01492 dns_rdataset_disassociate(&rdataset);
01493 continue;
01494 }
01495 if (result != ISC_R_SUCCESS)
01496 goto failure;
01497
01498
01499
01500
01501 CHECK(delete(db, version, prev, nsec3param, diff));
01502
01503
01504
01505
01506 nsec3.next = nexthash;
01507 nsec3.next_length = (unsigned char)next_length;
01508 isc_buffer_init(&buffer, nsec3buf,
01509 sizeof(nsec3buf));
01510 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
01511 dns_rdatatype_nsec3, &nsec3,
01512 &buffer));
01513 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
01514 prev, rdataset.ttl, &rdata,
01515 &tuple));
01516 CHECK(do_one_tuple(&tuple, db, version, diff));
01517 dns_rdata_reset(&rdata);
01518 dns_rdataset_disassociate(&rdataset);
01519 break;
01520 } while (pass < 2);
01521
01522 INSIST(pass < 2);
01523
01524
01525
01526
01527 CHECK(delete(db, version, hashname, nsec3param, diff));
01528 } while (1);
01529
01530 success:
01531 result = ISC_R_SUCCESS;
01532
01533 failure:
01534 if (dbit != NULL)
01535 dns_dbiterator_destroy(&dbit);
01536 if (dns_rdataset_isassociated(&rdataset))
01537 dns_rdataset_disassociate(&rdataset);
01538 if (node != NULL)
01539 dns_db_detachnode(db, &node);
01540 return (result);
01541 }
01542
01543 isc_result_t
01544 dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
01545 dns_diff_t *diff)
01546 {
01547 return (dns_nsec3_delnsec3sx(db, version, name, 0, diff));
01548 }
01549
01550 isc_result_t
01551 dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
01552 dns_rdatatype_t privatetype, dns_diff_t *diff)
01553 {
01554 dns_dbnode_t *node = NULL;
01555 dns_rdata_nsec3param_t nsec3param;
01556 dns_rdataset_t rdataset;
01557 isc_result_t result;
01558
01559 dns_rdataset_init(&rdataset);
01560
01561
01562
01563
01564 result = dns_db_getoriginnode(db, &node);
01565 if (result != ISC_R_SUCCESS)
01566 return (result);
01567
01568 result = dns_db_findrdataset(db, node, version,
01569 dns_rdatatype_nsec3param, 0, 0,
01570 &rdataset, NULL);
01571 if (result == ISC_R_NOTFOUND)
01572 goto try_private;
01573 if (result != ISC_R_SUCCESS)
01574 goto failure;
01575
01576
01577
01578
01579 for (result = dns_rdataset_first(&rdataset);
01580 result == ISC_R_SUCCESS;
01581 result = dns_rdataset_next(&rdataset)) {
01582 dns_rdata_t rdata = DNS_RDATA_INIT;
01583
01584 dns_rdataset_current(&rdataset, &rdata);
01585 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
01586
01587 if (nsec3param.flags != 0)
01588 continue;
01589
01590
01591
01592 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
01593 }
01594 dns_rdataset_disassociate(&rdataset);
01595
01596 try_private:
01597 if (privatetype == 0)
01598 goto success;
01599 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
01600 &rdataset, NULL);
01601 if (result == ISC_R_NOTFOUND)
01602 goto success;
01603 if (result != ISC_R_SUCCESS)
01604 goto failure;
01605
01606
01607
01608
01609 for (result = dns_rdataset_first(&rdataset);
01610 result == ISC_R_SUCCESS;
01611 result = dns_rdataset_next(&rdataset)) {
01612 dns_rdata_t rdata1 = DNS_RDATA_INIT;
01613 dns_rdata_t rdata2 = DNS_RDATA_INIT;
01614 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
01615
01616 dns_rdataset_current(&rdataset, &rdata1);
01617 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
01618 buf, sizeof(buf)))
01619 continue;
01620 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
01621
01622 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
01623 continue;
01624 if (better_param(&rdataset, &rdata2))
01625 continue;
01626
01627
01628
01629
01630 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
01631 }
01632 if (result == ISC_R_NOMORE)
01633 success:
01634 result = ISC_R_SUCCESS;
01635
01636 failure:
01637 if (dns_rdataset_isassociated(&rdataset))
01638 dns_rdataset_disassociate(&rdataset);
01639 if (node != NULL)
01640 dns_db_detachnode(db, &node);
01641
01642 return (result);
01643 }
01644
01645 isc_result_t
01646 dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version,
01647 isc_boolean_t complete, isc_boolean_t *answer)
01648 {
01649 return (dns_nsec3_activex(db, version, complete, 0, answer));
01650 }
01651
01652 isc_result_t
01653 dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version,
01654 isc_boolean_t complete, dns_rdatatype_t privatetype,
01655 isc_boolean_t *answer)
01656 {
01657 dns_dbnode_t *node = NULL;
01658 dns_rdataset_t rdataset;
01659 dns_rdata_nsec3param_t nsec3param;
01660 isc_result_t result;
01661
01662 REQUIRE(answer != NULL);
01663
01664 dns_rdataset_init(&rdataset);
01665
01666 result = dns_db_getoriginnode(db, &node);
01667 if (result != ISC_R_SUCCESS)
01668 return (result);
01669
01670 result = dns_db_findrdataset(db, node, version,
01671 dns_rdatatype_nsec3param, 0, 0,
01672 &rdataset, NULL);
01673
01674 if (result == ISC_R_NOTFOUND)
01675 goto try_private;
01676
01677 if (result != ISC_R_SUCCESS) {
01678 dns_db_detachnode(db, &node);
01679 return (result);
01680 }
01681 for (result = dns_rdataset_first(&rdataset);
01682 result == ISC_R_SUCCESS;
01683 result = dns_rdataset_next(&rdataset)) {
01684 dns_rdata_t rdata = DNS_RDATA_INIT;
01685
01686 dns_rdataset_current(&rdataset, &rdata);
01687 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
01688 RUNTIME_CHECK(result == ISC_R_SUCCESS);
01689
01690 if (nsec3param.flags == 0)
01691 break;
01692 }
01693 dns_rdataset_disassociate(&rdataset);
01694 if (result == ISC_R_SUCCESS) {
01695 dns_db_detachnode(db, &node);
01696 *answer = ISC_TRUE;
01697 return (ISC_R_SUCCESS);
01698 }
01699 if (result == ISC_R_NOMORE)
01700 *answer = ISC_FALSE;
01701
01702 try_private:
01703 if (privatetype == 0 || complete) {
01704 *answer = ISC_FALSE;
01705 return (ISC_R_SUCCESS);
01706 }
01707 result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
01708 &rdataset, NULL);
01709
01710 dns_db_detachnode(db, &node);
01711 if (result == ISC_R_NOTFOUND) {
01712 *answer = ISC_FALSE;
01713 return (ISC_R_SUCCESS);
01714 }
01715 if (result != ISC_R_SUCCESS)
01716 return (result);
01717
01718 for (result = dns_rdataset_first(&rdataset);
01719 result == ISC_R_SUCCESS;
01720 result = dns_rdataset_next(&rdataset)) {
01721 dns_rdata_t rdata1 = DNS_RDATA_INIT;
01722 dns_rdata_t rdata2 = DNS_RDATA_INIT;
01723 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
01724
01725 dns_rdataset_current(&rdataset, &rdata1);
01726 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
01727 buf, sizeof(buf)))
01728 continue;
01729 result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL);
01730 RUNTIME_CHECK(result == ISC_R_SUCCESS);
01731
01732 if (!complete && CREATE(nsec3param.flags))
01733 break;
01734 }
01735 dns_rdataset_disassociate(&rdataset);
01736 if (result == ISC_R_SUCCESS) {
01737 *answer = ISC_TRUE;
01738 result = ISC_R_SUCCESS;
01739 }
01740 if (result == ISC_R_NOMORE) {
01741 *answer = ISC_FALSE;
01742 result = ISC_R_SUCCESS;
01743 }
01744
01745 return (result);
01746 }
01747
01748 isc_result_t
01749 dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version,
01750 isc_mem_t *mctx, unsigned int *iterationsp)
01751 {
01752 dns_dbnode_t *node = NULL;
01753 dns_rdataset_t rdataset;
01754 dst_key_t *key = NULL;
01755 isc_buffer_t buffer;
01756 isc_result_t result;
01757 unsigned int bits, minbits = 4096;
01758
01759 result = dns_db_getoriginnode(db, &node);
01760 if (result != ISC_R_SUCCESS)
01761 return (result);
01762
01763 dns_rdataset_init(&rdataset);
01764 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
01765 0, 0, &rdataset, NULL);
01766 dns_db_detachnode(db, &node);
01767 if (result == ISC_R_NOTFOUND) {
01768 *iterationsp = 0;
01769 return (ISC_R_SUCCESS);
01770 }
01771 if (result != ISC_R_SUCCESS)
01772 goto failure;
01773
01774 for (result = dns_rdataset_first(&rdataset);
01775 result == ISC_R_SUCCESS;
01776 result = dns_rdataset_next(&rdataset)) {
01777 dns_rdata_t rdata = DNS_RDATA_INIT;
01778
01779 dns_rdataset_current(&rdataset, &rdata);
01780 isc_buffer_init(&buffer, rdata.data, rdata.length);
01781 isc_buffer_add(&buffer, rdata.length);
01782 CHECK(dst_key_fromdns(dns_db_origin(db), rdataset.rdclass,
01783 &buffer, mctx, &key));
01784 bits = dst_key_size(key);
01785 dst_key_free(&key);
01786 if (minbits > bits)
01787 minbits = bits;
01788 }
01789 if (result != ISC_R_NOMORE)
01790 goto failure;
01791
01792 if (minbits <= 1024)
01793 *iterationsp = 150;
01794 else if (minbits <= 2048)
01795 *iterationsp = 500;
01796 else
01797 *iterationsp = 2500;
01798 result = ISC_R_SUCCESS;
01799
01800 failure:
01801 if (dns_rdataset_isassociated(&rdataset))
01802 dns_rdataset_disassociate(&rdataset);
01803 return (result);
01804 }
01805
01806 isc_result_t
01807 dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name,
01808 dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
01809 dns_name_t *zonename, isc_boolean_t *exists,
01810 isc_boolean_t *data, isc_boolean_t *optout,
01811 isc_boolean_t *unknown, isc_boolean_t *setclosest,
01812 isc_boolean_t *setnearest, dns_name_t *closest,
01813 dns_name_t *nearest, dns_nseclog_t logit, void *arg)
01814 {
01815 char namebuf[DNS_NAME_FORMATSIZE];
01816 dns_fixedname_t fzone;
01817 dns_fixedname_t qfixed;
01818 dns_label_t hashlabel;
01819 dns_name_t *qname;
01820 dns_name_t *zone;
01821 dns_rdata_nsec3_t nsec3;
01822 dns_rdata_t rdata = DNS_RDATA_INIT;
01823 int order;
01824 int scope;
01825 isc_boolean_t atparent;
01826 isc_boolean_t first;
01827 isc_boolean_t ns;
01828 isc_boolean_t soa;
01829 isc_buffer_t buffer;
01830 isc_result_t answer = ISC_R_IGNORE;
01831 isc_result_t result;
01832 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
01833 unsigned char owner[NSEC3_MAX_HASH_LENGTH];
01834 unsigned int length;
01835 unsigned int qlabels;
01836 unsigned int zlabels;
01837
01838 REQUIRE((exists == NULL && data == NULL) ||
01839 (exists != NULL && data != NULL));
01840 REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3);
01841 REQUIRE((setclosest == NULL && closest == NULL) ||
01842 (setclosest != NULL && closest != NULL));
01843 REQUIRE((setnearest == NULL && nearest == NULL) ||
01844 (setnearest != NULL && nearest != NULL));
01845
01846 result = dns_rdataset_first(nsec3set);
01847 if (result != ISC_R_SUCCESS) {
01848 (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC3 set");
01849 return (result);
01850 }
01851
01852 dns_rdataset_current(nsec3set, &rdata);
01853
01854 result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
01855 if (result != ISC_R_SUCCESS)
01856 return (result);
01857
01858 (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC3");
01859
01860 dns_fixedname_init(&fzone);
01861 zone = dns_fixedname_name(&fzone);
01862 zlabels = dns_name_countlabels(nsec3name);
01863
01864
01865
01866
01867 if (zlabels < 2)
01868 return (ISC_R_IGNORE);
01869
01870
01871
01872
01873 zlabels--;
01874 dns_name_split(nsec3name, zlabels, NULL, zone);
01875
01876
01877
01878
01879 if (!dns_name_issubdomain(name, zone))
01880 return (ISC_R_IGNORE);
01881
01882
01883
01884
01885 if (dns_name_countlabels(zonename) == 0 ||
01886 dns_name_issubdomain(zone, zonename))
01887 dns_name_copy(zone, zonename, NULL);
01888
01889 if (!dns_name_equal(zone, zonename))
01890 return (ISC_R_IGNORE);
01891
01892
01893
01894
01895 if (exists == NULL || data == NULL)
01896 return (ISC_R_SUCCESS);
01897
01898
01899
01900
01901
01902 if (!dns_nsec3_supportedhash(nsec3.hash)) {
01903 if (unknown != NULL)
01904 *unknown = ISC_TRUE;
01905 return (ISC_R_IGNORE);
01906 }
01907
01908
01909
01910
01911 dns_name_getlabel(nsec3name, 0, &hashlabel);
01912 isc_region_consume(&hashlabel, 1);
01913 isc_buffer_init(&buffer, owner, sizeof(owner));
01914 result = isc_base32hex_decoderegion(&hashlabel, &buffer);
01915 if (result != ISC_R_SUCCESS)
01916 return (result);
01917
01918
01919
01920
01921 if (isc_buffer_usedlength(&buffer) != nsec3.next_length)
01922 return (ISC_R_IGNORE);
01923
01924
01925
01926
01927
01928 scope = memcmp(owner, nsec3.next, nsec3.next_length);
01929
01930
01931
01932
01933 dns_fixedname_init(&qfixed);
01934 qname = dns_fixedname_name(&qfixed);
01935 dns_name_downcase(name, qname, NULL);
01936 qlabels = dns_name_countlabels(qname);
01937 first = ISC_TRUE;
01938
01939 while (qlabels >= zlabels) {
01940 length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
01941 nsec3.salt, nsec3.salt_length,
01942 qname->ndata, qname->length);
01943
01944
01945
01946 if (length != nsec3.next_length) {
01947 (*logit)(arg, ISC_LOG_DEBUG(3),
01948 "ignoring NSEC bad length %u vs %u",
01949 length, nsec3.next_length);
01950 return (ISC_R_IGNORE);
01951 }
01952
01953 order = memcmp(hash, owner, length);
01954 if (first && order == 0) {
01955
01956
01957
01958 atparent = dns_rdatatype_atparent(type);
01959 ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns);
01960 soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa);
01961 if (ns && !soa) {
01962 if (!atparent) {
01963
01964
01965
01966
01967
01968
01969 (*logit)(arg, ISC_LOG_DEBUG(3),
01970 "ignoring parent NSEC3");
01971 return (ISC_R_IGNORE);
01972 }
01973 } else if (atparent && ns && soa) {
01974
01975
01976
01977
01978 (*logit)(arg, ISC_LOG_DEBUG(3),
01979 "ignoring child NSEC3");
01980 return (ISC_R_IGNORE);
01981 }
01982 if (type == dns_rdatatype_cname ||
01983 type == dns_rdatatype_nxt ||
01984 type == dns_rdatatype_nsec ||
01985 type == dns_rdatatype_key ||
01986 !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) {
01987 *exists = ISC_TRUE;
01988 *data = dns_nsec3_typepresent(&rdata, type);
01989 (*logit)(arg, ISC_LOG_DEBUG(3),
01990 "NSEC3 proves name exists (owner) "
01991 "data=%d", *data);
01992 return (ISC_R_SUCCESS);
01993 }
01994 (*logit)(arg, ISC_LOG_DEBUG(3),
01995 "NSEC3 proves CNAME exists");
01996 return (ISC_R_IGNORE);
01997 }
01998
01999 if (order == 0 &&
02000 dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) &&
02001 !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa))
02002 {
02003
02004
02005
02006
02007
02008 (*logit)(arg, ISC_LOG_DEBUG(3),
02009 "ignoring parent NSEC3");
02010 return (ISC_R_IGNORE);
02011 }
02012
02013
02014
02015
02016 if (order == 0) {
02017 if (closest != NULL &&
02018 (dns_name_countlabels(closest) == 0 ||
02019 dns_name_issubdomain(qname, closest)) &&
02020 !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) &&
02021 !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) &&
02022 (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) ||
02023 !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns)))
02024 {
02025
02026 dns_name_format(qname, namebuf,
02027 sizeof(namebuf));
02028 (*logit)(arg, ISC_LOG_DEBUG(3),
02029 "NSEC3 indicates potential closest "
02030 "encloser: '%s'", namebuf);
02031 dns_name_copy(qname, closest, NULL);
02032 *setclosest = ISC_TRUE;
02033 }
02034 dns_name_format(qname, namebuf, sizeof(namebuf));
02035 (*logit)(arg, ISC_LOG_DEBUG(3),
02036 "NSEC3 at super-domain %s", namebuf);
02037 return (answer);
02038 }
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051 if ((scope < 0 && order > 0 &&
02052 memcmp(hash, nsec3.next, length) < 0) ||
02053 (scope >= 0 && (order > 0 ||
02054 memcmp(hash, nsec3.next, length) < 0)))
02055 {
02056 dns_name_format(qname, namebuf, sizeof(namebuf));
02057 (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves "
02058 "name does not exist: '%s'", namebuf);
02059 if (nearest != NULL &&
02060 (dns_name_countlabels(nearest) == 0 ||
02061 dns_name_issubdomain(nearest, qname))) {
02062 dns_name_copy(qname, nearest, NULL);
02063 *setnearest = ISC_TRUE;
02064 }
02065
02066 *exists = ISC_FALSE;
02067 *data = ISC_FALSE;
02068 if (optout != NULL) {
02069 if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0)
02070 (*logit)(arg, ISC_LOG_DEBUG(3),
02071 "NSEC3 indicates optout");
02072 else
02073 (*logit)(arg, ISC_LOG_DEBUG(3),
02074 "NSEC3 indicates secure range");
02075 *optout =
02076 ISC_TF(nsec3.flags & DNS_NSEC3FLAG_OPTOUT);
02077 }
02078 answer = ISC_R_SUCCESS;
02079 }
02080
02081 qlabels--;
02082 if (qlabels > 0)
02083 dns_name_split(qname, qlabels, NULL, qname);
02084 first = ISC_FALSE;
02085 }
02086 return (answer);
02087 }