1 /* $NetBSD: update.c,v 1.7 2020/08/03 17:23:41 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * This Source Code Form is subject to the terms of the Mozilla Public 7 * License, v. 2.0. If a copy of the MPL was not distributed with this 8 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * See the COPYRIGHT file distributed with this work for additional 11 * information regarding copyright ownership. 12 */ 13 14 #include <inttypes.h> 15 #include <stdbool.h> 16 #include <time.h> 17 18 #include <isc/log.h> 19 #include <isc/magic.h> 20 #include <isc/mem.h> 21 #include <isc/netaddr.h> 22 #include <isc/platform.h> 23 #include <isc/print.h> 24 #include <isc/random.h> 25 #include <isc/serial.h> 26 #include <isc/stats.h> 27 #include <isc/stdtime.h> 28 #include <isc/string.h> 29 #include <isc/taskpool.h> 30 #include <isc/time.h> 31 #include <isc/util.h> 32 33 #include <dns/db.h> 34 #include <dns/dbiterator.h> 35 #include <dns/diff.h> 36 #include <dns/dnssec.h> 37 #include <dns/events.h> 38 #include <dns/fixedname.h> 39 #include <dns/journal.h> 40 #include <dns/kasp.h> 41 #include <dns/keyvalues.h> 42 #include <dns/log.h> 43 #include <dns/message.h> 44 #include <dns/nsec.h> 45 #include <dns/nsec3.h> 46 #include <dns/private.h> 47 #include <dns/rdataclass.h> 48 #include <dns/rdataset.h> 49 #include <dns/rdatasetiter.h> 50 #include <dns/rdatastruct.h> 51 #include <dns/rdatatype.h> 52 #include <dns/result.h> 53 #include <dns/soa.h> 54 #include <dns/ssu.h> 55 #include <dns/stats.h> 56 #include <dns/tsig.h> 57 #include <dns/update.h> 58 #include <dns/view.h> 59 #include <dns/zone.h> 60 #include <dns/zt.h> 61 62 /**************************************************************************/ 63 64 #define STATE_MAGIC ISC_MAGIC('S', 'T', 'T', 'E') 65 #define DNS_STATE_VALID(state) ISC_MAGIC_VALID(state, STATE_MAGIC) 66 67 /*% 68 * Log level for tracing dynamic update protocol requests. 69 */ 70 #define LOGLEVEL_PROTOCOL ISC_LOG_INFO 71 72 /*% 73 * Log level for low-level debug tracing. 74 */ 75 #define LOGLEVEL_DEBUG ISC_LOG_DEBUG(8) 76 77 /*% 78 * Check an operation for failure. These macros all assume that 79 * the function using them has a 'result' variable and a 'failure' 80 * label. 81 */ 82 #define CHECK(op) \ 83 do { \ 84 result = (op); \ 85 if (result != ISC_R_SUCCESS) \ 86 goto failure; \ 87 } while (/*CONSTCOND*/0) 88 89 /*% 90 * Fail unconditionally with result 'code', which must not 91 * be ISC_R_SUCCESS. The reason for failure presumably has 92 * been logged already. 93 * 94 * The test against ISC_R_SUCCESS is there to keep the Solaris compiler 95 * from complaining about "end-of-loop code not reached". 96 */ 97 98 #define FAIL(code) \ 99 do { \ 100 result = (code); \ 101 if (result != ISC_R_SUCCESS) \ 102 goto failure; \ 103 } while (/*CONSTCOND*/0) 104 105 /*% 106 * Fail unconditionally and log as a client error. 107 * The test against ISC_R_SUCCESS is there to keep the Solaris compiler 108 * from complaining about "end-of-loop code not reached". 109 */ 110 #define FAILC(code, msg) \ 111 do { \ 112 const char *_what = "failed"; \ 113 result = (code); \ 114 switch (result) { \ 115 case DNS_R_NXDOMAIN: \ 116 case DNS_R_YXDOMAIN: \ 117 case DNS_R_YXRRSET: \ 118 case DNS_R_NXRRSET: \ 119 _what = "unsuccessful"; \ 120 } \ 121 update_log(log, zone, LOGLEVEL_PROTOCOL, "update %s: %s (%s)", \ 122 _what, msg, isc_result_totext(result)); \ 123 if (result != ISC_R_SUCCESS) \ 124 goto failure; \ 125 } while (/*CONSTCOND*/0) 126 127 #define FAILN(code, name, msg) \ 128 do { \ 129 const char *_what = "failed"; \ 130 result = (code); \ 131 switch (result) { \ 132 case DNS_R_NXDOMAIN: \ 133 case DNS_R_YXDOMAIN: \ 134 case DNS_R_YXRRSET: \ 135 case DNS_R_NXRRSET: \ 136 _what = "unsuccessful"; \ 137 } \ 138 if (isc_log_wouldlog(dns_lctx, LOGLEVEL_PROTOCOL)) { \ 139 char _nbuf[DNS_NAME_FORMATSIZE]; \ 140 dns_name_format(name, _nbuf, sizeof(_nbuf)); \ 141 update_log(log, zone, LOGLEVEL_PROTOCOL, \ 142 "update %s: %s: %s (%s)", _what, _nbuf, \ 143 msg, isc_result_totext(result)); \ 144 } \ 145 if (result != ISC_R_SUCCESS) \ 146 goto failure; \ 147 } while (/*CONSTCOND*/0) 148 149 #define FAILNT(code, name, type, msg) \ 150 do { \ 151 const char *_what = "failed"; \ 152 result = (code); \ 153 switch (result) { \ 154 case DNS_R_NXDOMAIN: \ 155 case DNS_R_YXDOMAIN: \ 156 case DNS_R_YXRRSET: \ 157 case DNS_R_NXRRSET: \ 158 _what = "unsuccessful"; \ 159 } \ 160 if (isc_log_wouldlog(dns_lctx, LOGLEVEL_PROTOCOL)) { \ 161 char _nbuf[DNS_NAME_FORMATSIZE]; \ 162 char _tbuf[DNS_RDATATYPE_FORMATSIZE]; \ 163 dns_name_format(name, _nbuf, sizeof(_nbuf)); \ 164 dns_rdatatype_format(type, _tbuf, sizeof(_tbuf)); \ 165 update_log(log, zone, LOGLEVEL_PROTOCOL, \ 166 "update %s: %s/%s: %s (%s)", _what, _nbuf, \ 167 _tbuf, msg, isc_result_totext(result)); \ 168 } \ 169 if (result != ISC_R_SUCCESS) \ 170 goto failure; \ 171 } while (/*CONSTCOND*/0) 172 173 /*% 174 * Fail unconditionally and log as a server error. 175 * The test against ISC_R_SUCCESS is there to keep the Solaris compiler 176 * from complaining about "end-of-loop code not reached". 177 */ 178 #define FAILS(code, msg) \ 179 do { \ 180 result = (code); \ 181 update_log(log, zone, LOGLEVEL_PROTOCOL, "error: %s: %s", msg, \ 182 isc_result_totext(result)); \ 183 if (result != ISC_R_SUCCESS) \ 184 goto failure; \ 185 } while (/*CONSTCOND*/0) 186 187 /**************************************************************************/ 188 189 typedef struct rr rr_t; 190 191 struct rr { 192 /* dns_name_t name; */ 193 uint32_t ttl; 194 dns_rdata_t rdata; 195 }; 196 197 typedef struct update_event update_event_t; 198 199 /**************************************************************************/ 200 201 static void 202 update_log(dns_update_log_t *callback, dns_zone_t *zone, int level, 203 const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5); 204 205 static void 206 update_log(dns_update_log_t *callback, dns_zone_t *zone, int level, 207 const char *fmt, ...) { 208 va_list ap; 209 char message[4096]; 210 211 if (callback == NULL) { 212 return; 213 } 214 215 if (!isc_log_wouldlog(dns_lctx, level)) { 216 return; 217 } 218 219 va_start(ap, fmt); 220 vsnprintf(message, sizeof(message), fmt, ap); 221 va_end(ap); 222 223 (callback->func)(callback->arg, zone, level, message); 224 } 225 226 /*% 227 * Update a single RR in version 'ver' of 'db' and log the 228 * update in 'diff'. 229 * 230 * Ensures: 231 * \li '*tuple' == NULL. Either the tuple is freed, or its 232 * ownership has been transferred to the diff. 233 */ 234 static isc_result_t 235 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, 236 dns_diff_t *diff) { 237 dns_diff_t temp_diff; 238 isc_result_t result; 239 240 /* 241 * Create a singleton diff. 242 */ 243 dns_diff_init(diff->mctx, &temp_diff); 244 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); 245 246 /* 247 * Apply it to the database. 248 */ 249 result = dns_diff_apply(&temp_diff, db, ver); 250 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); 251 if (result != ISC_R_SUCCESS) { 252 dns_difftuple_free(tuple); 253 return (result); 254 } 255 256 /* 257 * Merge it into the current pending journal entry. 258 */ 259 dns_diff_appendminimal(diff, tuple); 260 261 /* 262 * Do not clear temp_diff. 263 */ 264 return (ISC_R_SUCCESS); 265 } 266 267 static isc_result_t 268 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 269 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, 270 dns_rdata_t *rdata) { 271 dns_difftuple_t *tuple = NULL; 272 isc_result_t result; 273 result = dns_difftuple_create(diff->mctx, op, name, ttl, rdata, &tuple); 274 if (result != ISC_R_SUCCESS) { 275 return (result); 276 } 277 return (do_one_tuple(&tuple, db, ver, diff)); 278 } 279 280 /**************************************************************************/ 281 /* 282 * Callback-style iteration over rdatasets and rdatas. 283 * 284 * foreach_rrset() can be used to iterate over the RRsets 285 * of a name and call a callback function with each 286 * one. Similarly, foreach_rr() can be used to iterate 287 * over the individual RRs at name, optionally restricted 288 * to RRs of a given type. 289 * 290 * The callback functions are called "actions" and take 291 * two arguments: a void pointer for passing arbitrary 292 * context information, and a pointer to the current RRset 293 * or RR. By convention, their names end in "_action". 294 */ 295 296 /* 297 * XXXRTH We might want to make this public somewhere in libdns. 298 */ 299 300 /*% 301 * Function type for foreach_rrset() iterator actions. 302 */ 303 typedef isc_result_t 304 rrset_func(void *data, dns_rdataset_t *rrset); 305 306 /*% 307 * Function type for foreach_rr() iterator actions. 308 */ 309 typedef isc_result_t 310 rr_func(void *data, rr_t *rr); 311 312 /*% 313 * Internal context struct for foreach_node_rr(). 314 */ 315 typedef struct { 316 rr_func *rr_action; 317 void *rr_action_data; 318 } foreach_node_rr_ctx_t; 319 320 /*% 321 * Internal helper function for foreach_node_rr(). 322 */ 323 static isc_result_t 324 foreach_node_rr_action(void *data, dns_rdataset_t *rdataset) { 325 isc_result_t result; 326 foreach_node_rr_ctx_t *ctx = data; 327 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 328 result = dns_rdataset_next(rdataset)) 329 { 330 rr_t rr = { 0, DNS_RDATA_INIT }; 331 332 dns_rdataset_current(rdataset, &rr.rdata); 333 rr.ttl = rdataset->ttl; 334 result = (*ctx->rr_action)(ctx->rr_action_data, &rr); 335 if (result != ISC_R_SUCCESS) { 336 return (result); 337 } 338 } 339 if (result != ISC_R_NOMORE) { 340 return (result); 341 } 342 return (ISC_R_SUCCESS); 343 } 344 345 /*% 346 * For each rdataset of 'name' in 'ver' of 'db', call 'action' 347 * with the rdataset and 'action_data' as arguments. If the name 348 * does not exist, do nothing. 349 * 350 * If 'action' returns an error, abort iteration and return the error. 351 */ 352 static isc_result_t 353 foreach_rrset(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 354 rrset_func *action, void *action_data) { 355 isc_result_t result; 356 dns_dbnode_t *node; 357 dns_rdatasetiter_t *iter; 358 359 node = NULL; 360 result = dns_db_findnode(db, name, false, &node); 361 if (result == ISC_R_NOTFOUND) { 362 return (ISC_R_SUCCESS); 363 } 364 if (result != ISC_R_SUCCESS) { 365 return (result); 366 } 367 368 iter = NULL; 369 result = dns_db_allrdatasets(db, node, ver, (isc_stdtime_t)0, &iter); 370 if (result != ISC_R_SUCCESS) { 371 goto cleanup_node; 372 } 373 374 for (result = dns_rdatasetiter_first(iter); result == ISC_R_SUCCESS; 375 result = dns_rdatasetiter_next(iter)) 376 { 377 dns_rdataset_t rdataset; 378 379 dns_rdataset_init(&rdataset); 380 dns_rdatasetiter_current(iter, &rdataset); 381 382 result = (*action)(action_data, &rdataset); 383 384 dns_rdataset_disassociate(&rdataset); 385 if (result != ISC_R_SUCCESS) { 386 goto cleanup_iterator; 387 } 388 } 389 if (result == ISC_R_NOMORE) { 390 result = ISC_R_SUCCESS; 391 } 392 393 cleanup_iterator: 394 dns_rdatasetiter_destroy(&iter); 395 396 cleanup_node: 397 dns_db_detachnode(db, &node); 398 399 return (result); 400 } 401 402 /*% 403 * For each RR of 'name' in 'ver' of 'db', call 'action' 404 * with the RR and 'action_data' as arguments. If the name 405 * does not exist, do nothing. 406 * 407 * If 'action' returns an error, abort iteration 408 * and return the error. 409 */ 410 static isc_result_t 411 foreach_node_rr(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 412 rr_func *rr_action, void *rr_action_data) { 413 foreach_node_rr_ctx_t ctx; 414 ctx.rr_action = rr_action; 415 ctx.rr_action_data = rr_action_data; 416 return (foreach_rrset(db, ver, name, foreach_node_rr_action, &ctx)); 417 } 418 419 /*% 420 * For each of the RRs specified by 'db', 'ver', 'name', 'type', 421 * (which can be dns_rdatatype_any to match any type), and 'covers', call 422 * 'action' with the RR and 'action_data' as arguments. If the name 423 * does not exist, or if no RRset of the given type exists at the name, 424 * do nothing. 425 * 426 * If 'action' returns an error, abort iteration and return the error. 427 */ 428 static isc_result_t 429 foreach_rr(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 430 dns_rdatatype_t type, dns_rdatatype_t covers, rr_func *rr_action, 431 void *rr_action_data) { 432 isc_result_t result; 433 dns_dbnode_t *node; 434 dns_rdataset_t rdataset; 435 436 if (type == dns_rdatatype_any) { 437 return (foreach_node_rr(db, ver, name, rr_action, 438 rr_action_data)); 439 } 440 441 node = NULL; 442 if (type == dns_rdatatype_nsec3 || 443 (type == dns_rdatatype_rrsig && covers == dns_rdatatype_nsec3)) 444 { 445 result = dns_db_findnsec3node(db, name, false, &node); 446 } else { 447 result = dns_db_findnode(db, name, false, &node); 448 } 449 if (result == ISC_R_NOTFOUND) { 450 return (ISC_R_SUCCESS); 451 } 452 if (result != ISC_R_SUCCESS) { 453 return (result); 454 } 455 456 dns_rdataset_init(&rdataset); 457 result = dns_db_findrdataset(db, node, ver, type, covers, 458 (isc_stdtime_t)0, &rdataset, NULL); 459 if (result == ISC_R_NOTFOUND) { 460 result = ISC_R_SUCCESS; 461 goto cleanup_node; 462 } 463 if (result != ISC_R_SUCCESS) { 464 goto cleanup_node; 465 } 466 467 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 468 result = dns_rdataset_next(&rdataset)) 469 { 470 rr_t rr = { 0, DNS_RDATA_INIT }; 471 dns_rdataset_current(&rdataset, &rr.rdata); 472 rr.ttl = rdataset.ttl; 473 result = (*rr_action)(rr_action_data, &rr); 474 if (result != ISC_R_SUCCESS) { 475 goto cleanup_rdataset; 476 } 477 } 478 if (result != ISC_R_NOMORE) { 479 goto cleanup_rdataset; 480 } 481 result = ISC_R_SUCCESS; 482 483 cleanup_rdataset: 484 dns_rdataset_disassociate(&rdataset); 485 cleanup_node: 486 dns_db_detachnode(db, &node); 487 488 return (result); 489 } 490 491 /**************************************************************************/ 492 /* 493 * Various tests on the database contents (for prerequisites, etc). 494 */ 495 496 /*% 497 * Function type for predicate functions that compare a database RR 'db_rr' 498 * against an update RR 'update_rr'. 499 */ 500 typedef bool 501 rr_predicate(dns_rdata_t *update_rr, dns_rdata_t *db_rr); 502 503 /*% 504 * Helper function for rrset_exists(). 505 */ 506 static isc_result_t 507 rrset_exists_action(void *data, rr_t *rr) { 508 UNUSED(data); 509 UNUSED(rr); 510 return (ISC_R_EXISTS); 511 } 512 513 /*% 514 * Utility macro for RR existence checking functions. 515 * 516 * If the variable 'result' has the value ISC_R_EXISTS or 517 * ISC_R_SUCCESS, set *exists to true or false, 518 * respectively, and return success. 519 * 520 * If 'result' has any other value, there was a failure. 521 * Return the failure result code and do not set *exists. 522 * 523 * This would be more readable as "do { if ... } while(0)", 524 * but that form generates tons of warnings on Solaris 2.6. 525 */ 526 #define RETURN_EXISTENCE_FLAG \ 527 return ((result == ISC_R_EXISTS) \ 528 ? (*exists = true, ISC_R_SUCCESS) \ 529 : ((result == ISC_R_SUCCESS) \ 530 ? (*exists = false, ISC_R_SUCCESS) \ 531 : result)) 532 533 /*% 534 * Set '*exists' to true iff an rrset of the given type exists, 535 * to false otherwise. 536 */ 537 static isc_result_t 538 rrset_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 539 dns_rdatatype_t type, dns_rdatatype_t covers, bool *exists) { 540 isc_result_t result; 541 result = foreach_rr(db, ver, name, type, covers, rrset_exists_action, 542 NULL); 543 RETURN_EXISTENCE_FLAG; 544 } 545 546 /*% 547 * Set '*visible' to true if the RRset exists and is part of the 548 * visible zone. Otherwise '*visible' is set to false unless a 549 * error occurs. 550 */ 551 static isc_result_t 552 rrset_visible(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 553 dns_rdatatype_t type, bool *visible) { 554 isc_result_t result; 555 dns_fixedname_t fixed; 556 557 dns_fixedname_init(&fixed); 558 result = dns_db_find(db, name, ver, type, DNS_DBFIND_NOWILD, 559 (isc_stdtime_t)0, NULL, dns_fixedname_name(&fixed), 560 NULL, NULL); 561 switch (result) { 562 case ISC_R_SUCCESS: 563 *visible = true; 564 break; 565 /* 566 * Glue, obscured, deleted or replaced records. 567 */ 568 case DNS_R_DELEGATION: 569 case DNS_R_DNAME: 570 case DNS_R_CNAME: 571 case DNS_R_NXDOMAIN: 572 case DNS_R_NXRRSET: 573 case DNS_R_EMPTYNAME: 574 case DNS_R_COVERINGNSEC: 575 *visible = false; 576 result = ISC_R_SUCCESS; 577 break; 578 default: 579 *visible = false; /* silence false compiler warning */ 580 break; 581 } 582 return (result); 583 } 584 585 /*% 586 * Context struct and helper function for name_exists(). 587 */ 588 589 static isc_result_t 590 name_exists_action(void *data, dns_rdataset_t *rrset) { 591 UNUSED(data); 592 UNUSED(rrset); 593 return (ISC_R_EXISTS); 594 } 595 596 /*% 597 * Set '*exists' to true iff the given name exists, to false otherwise. 598 */ 599 static isc_result_t 600 name_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 601 bool *exists) { 602 isc_result_t result; 603 result = foreach_rrset(db, ver, name, name_exists_action, NULL); 604 RETURN_EXISTENCE_FLAG; 605 } 606 607 /**************************************************************************/ 608 /* 609 * Checking of "RRset exists (value dependent)" prerequisites. 610 * 611 * In the RFC2136 section 3.2.5, this is the pseudocode involving 612 * a variable called "temp", a mapping of <name, type> tuples to rrsets. 613 * 614 * Here, we represent the "temp" data structure as (non-minimal) "dns_diff_t" 615 * where each tuple has op==DNS_DIFFOP_EXISTS. 616 */ 617 618 /*% 619 * A comparison function defining the sorting order for the entries 620 * in the "temp" data structure. The major sort key is the owner name, 621 * followed by the type and rdata. 622 */ 623 static int 624 temp_order(const void *av, const void *bv) { 625 dns_difftuple_t const *const *ap = av; 626 dns_difftuple_t const *const *bp = bv; 627 dns_difftuple_t const *a = *ap; 628 dns_difftuple_t const *b = *bp; 629 int r; 630 r = dns_name_compare(&a->name, &b->name); 631 if (r != 0) { 632 return (r); 633 } 634 r = (b->rdata.type - a->rdata.type); 635 if (r != 0) { 636 return (r); 637 } 638 r = dns_rdata_casecompare(&a->rdata, &b->rdata); 639 return (r); 640 } 641 642 /**************************************************************************/ 643 /* 644 * Conditional deletion of RRs. 645 */ 646 647 /*% 648 * Context structure for delete_if(). 649 */ 650 651 typedef struct { 652 rr_predicate *predicate; 653 dns_db_t *db; 654 dns_dbversion_t *ver; 655 dns_diff_t *diff; 656 dns_name_t *name; 657 dns_rdata_t *update_rr; 658 } conditional_delete_ctx_t; 659 660 /*% 661 * Predicate functions for delete_if(). 662 */ 663 664 /*% 665 * Return true always. 666 */ 667 static bool 668 true_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { 669 UNUSED(update_rr); 670 UNUSED(db_rr); 671 return (true); 672 } 673 674 /*% 675 * Return true if the record is a RRSIG. 676 */ 677 static bool 678 rrsig_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { 679 UNUSED(update_rr); 680 return ((db_rr->type == dns_rdatatype_rrsig) ? true : false); 681 } 682 683 /*% 684 * Internal helper function for delete_if(). 685 */ 686 static isc_result_t 687 delete_if_action(void *data, rr_t *rr) { 688 conditional_delete_ctx_t *ctx = data; 689 if ((*ctx->predicate)(ctx->update_rr, &rr->rdata)) { 690 isc_result_t result; 691 result = update_one_rr(ctx->db, ctx->ver, ctx->diff, 692 DNS_DIFFOP_DEL, ctx->name, rr->ttl, 693 &rr->rdata); 694 return (result); 695 } else { 696 return (ISC_R_SUCCESS); 697 } 698 } 699 700 /*% 701 * Conditionally delete RRs. Apply 'predicate' to the RRs 702 * specified by 'db', 'ver', 'name', and 'type' (which can 703 * be dns_rdatatype_any to match any type). Delete those 704 * RRs for which the predicate returns true, and log the 705 * deletions in 'diff'. 706 */ 707 static isc_result_t 708 delete_if(rr_predicate *predicate, dns_db_t *db, dns_dbversion_t *ver, 709 dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, 710 dns_rdata_t *update_rr, dns_diff_t *diff) { 711 conditional_delete_ctx_t ctx; 712 ctx.predicate = predicate; 713 ctx.db = db; 714 ctx.ver = ver; 715 ctx.diff = diff; 716 ctx.name = name; 717 ctx.update_rr = update_rr; 718 return (foreach_rr(db, ver, name, type, covers, delete_if_action, 719 &ctx)); 720 } 721 722 /**************************************************************************/ 723 /* 724 * Incremental updating of NSECs and RRSIGs. 725 */ 726 727 /*% 728 * We abuse the dns_diff_t type to represent a set of domain names 729 * affected by the update. 730 */ 731 static isc_result_t 732 namelist_append_name(dns_diff_t *list, dns_name_t *name) { 733 isc_result_t result; 734 dns_difftuple_t *tuple = NULL; 735 static dns_rdata_t dummy_rdata = DNS_RDATA_INIT; 736 737 CHECK(dns_difftuple_create(list->mctx, DNS_DIFFOP_EXISTS, name, 0, 738 &dummy_rdata, &tuple)); 739 dns_diff_append(list, &tuple); 740 failure: 741 return (result); 742 } 743 744 static isc_result_t 745 namelist_append_subdomain(dns_db_t *db, dns_name_t *name, 746 dns_diff_t *affected) { 747 isc_result_t result; 748 dns_fixedname_t fixedname; 749 dns_name_t *child; 750 dns_dbiterator_t *dbit = NULL; 751 752 child = dns_fixedname_initname(&fixedname); 753 754 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit)); 755 756 for (result = dns_dbiterator_seek(dbit, name); result == ISC_R_SUCCESS; 757 result = dns_dbiterator_next(dbit)) 758 { 759 dns_dbnode_t *node = NULL; 760 CHECK(dns_dbiterator_current(dbit, &node, child)); 761 dns_db_detachnode(db, &node); 762 if (!dns_name_issubdomain(child, name)) { 763 break; 764 } 765 CHECK(namelist_append_name(affected, child)); 766 } 767 if (result == ISC_R_NOMORE) { 768 result = ISC_R_SUCCESS; 769 } 770 failure: 771 if (dbit != NULL) { 772 dns_dbiterator_destroy(&dbit); 773 } 774 return (result); 775 } 776 777 /*% 778 * Helper function for non_nsec_rrset_exists(). 779 */ 780 static isc_result_t 781 is_non_nsec_action(void *data, dns_rdataset_t *rrset) { 782 UNUSED(data); 783 if (!(rrset->type == dns_rdatatype_nsec || 784 rrset->type == dns_rdatatype_nsec3 || 785 (rrset->type == dns_rdatatype_rrsig && 786 (rrset->covers == dns_rdatatype_nsec || 787 rrset->covers == dns_rdatatype_nsec3)))) 788 { 789 return (ISC_R_EXISTS); 790 } 791 return (ISC_R_SUCCESS); 792 } 793 794 /*% 795 * Check whether there is an rrset other than a NSEC or RRSIG NSEC, 796 * i.e., anything that justifies the continued existence of a name 797 * after a secure update. 798 * 799 * If such an rrset exists, set '*exists' to true. 800 * Otherwise, set it to false. 801 */ 802 static isc_result_t 803 non_nsec_rrset_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 804 bool *exists) { 805 isc_result_t result; 806 result = foreach_rrset(db, ver, name, is_non_nsec_action, NULL); 807 RETURN_EXISTENCE_FLAG; 808 } 809 810 /*% 811 * A comparison function for sorting dns_diff_t:s by name. 812 */ 813 static int 814 name_order(const void *av, const void *bv) { 815 dns_difftuple_t const *const *ap = av; 816 dns_difftuple_t const *const *bp = bv; 817 dns_difftuple_t const *a = *ap; 818 dns_difftuple_t const *b = *bp; 819 return (dns_name_compare(&a->name, &b->name)); 820 } 821 822 static isc_result_t 823 uniqify_name_list(dns_diff_t *list) { 824 isc_result_t result; 825 dns_difftuple_t *p, *q; 826 827 CHECK(dns_diff_sort(list, name_order)); 828 829 p = ISC_LIST_HEAD(list->tuples); 830 while (p != NULL) { 831 do { 832 q = ISC_LIST_NEXT(p, link); 833 if (q == NULL || !dns_name_equal(&p->name, &q->name)) { 834 break; 835 } 836 ISC_LIST_UNLINK(list->tuples, q, link); 837 dns_difftuple_free(&q); 838 } while (1); 839 p = ISC_LIST_NEXT(p, link); 840 } 841 failure: 842 return (result); 843 } 844 845 static isc_result_t 846 is_active(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, bool *flag, 847 bool *cut, bool *unsecure) { 848 isc_result_t result; 849 dns_fixedname_t foundname; 850 dns_fixedname_init(&foundname); 851 result = dns_db_find(db, name, ver, dns_rdatatype_any, 852 DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD, 853 (isc_stdtime_t)0, NULL, 854 dns_fixedname_name(&foundname), NULL, NULL); 855 if (result == ISC_R_SUCCESS || result == DNS_R_EMPTYNAME) { 856 *flag = true; 857 *cut = false; 858 if (unsecure != NULL) { 859 *unsecure = false; 860 } 861 return (ISC_R_SUCCESS); 862 } else if (result == DNS_R_ZONECUT) { 863 *flag = true; 864 *cut = true; 865 if (unsecure != NULL) { 866 /* 867 * We are at the zonecut. Check to see if there 868 * is a DS RRset. 869 */ 870 if (dns_db_find(db, name, ver, dns_rdatatype_ds, 0, 871 (isc_stdtime_t)0, NULL, 872 dns_fixedname_name(&foundname), NULL, 873 NULL) == DNS_R_NXRRSET) 874 { 875 *unsecure = true; 876 } else { 877 *unsecure = false; 878 } 879 } 880 return (ISC_R_SUCCESS); 881 } else if (result == DNS_R_GLUE || result == DNS_R_DNAME || 882 result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) 883 { 884 *flag = false; 885 *cut = false; 886 if (unsecure != NULL) { 887 *unsecure = false; 888 } 889 return (ISC_R_SUCCESS); 890 } else { 891 /* 892 * Silence compiler. 893 */ 894 *flag = false; 895 *cut = false; 896 if (unsecure != NULL) { 897 *unsecure = false; 898 } 899 return (result); 900 } 901 } 902 903 /*% 904 * Find the next/previous name that has a NSEC record. 905 * In other words, skip empty database nodes and names that 906 * have had their NSECs removed because they are obscured by 907 * a zone cut. 908 */ 909 static isc_result_t 910 next_active(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, 911 dns_dbversion_t *ver, dns_name_t *oldname, dns_name_t *newname, 912 bool forward) { 913 isc_result_t result; 914 dns_dbiterator_t *dbit = NULL; 915 bool has_nsec = false; 916 unsigned int wraps = 0; 917 bool secure = dns_db_issecure(db); 918 919 CHECK(dns_db_createiterator(db, 0, &dbit)); 920 921 CHECK(dns_dbiterator_seek(dbit, oldname)); 922 do { 923 dns_dbnode_t *node = NULL; 924 925 if (forward) { 926 result = dns_dbiterator_next(dbit); 927 } else { 928 result = dns_dbiterator_prev(dbit); 929 } 930 if (result == ISC_R_NOMORE) { 931 /* 932 * Wrap around. 933 */ 934 if (forward) { 935 CHECK(dns_dbiterator_first(dbit)); 936 } else { 937 CHECK(dns_dbiterator_last(dbit)); 938 } 939 wraps++; 940 if (wraps == 2) { 941 update_log(log, zone, ISC_LOG_ERROR, 942 "secure zone with no NSECs"); 943 result = DNS_R_BADZONE; 944 goto failure; 945 } 946 } 947 CHECK(dns_dbiterator_current(dbit, &node, newname)); 948 dns_db_detachnode(db, &node); 949 950 /* 951 * The iterator may hold the tree lock, and 952 * rrset_exists() calls dns_db_findnode() which 953 * may try to reacquire it. To avoid deadlock 954 * we must pause the iterator first. 955 */ 956 CHECK(dns_dbiterator_pause(dbit)); 957 if (secure) { 958 CHECK(rrset_exists(db, ver, newname, dns_rdatatype_nsec, 959 0, &has_nsec)); 960 } else { 961 dns_fixedname_t ffound; 962 dns_name_t *found; 963 found = dns_fixedname_initname(&ffound); 964 result = dns_db_find( 965 db, newname, ver, dns_rdatatype_soa, 966 DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); 967 if (result == ISC_R_SUCCESS || 968 result == DNS_R_EMPTYNAME || 969 result == DNS_R_NXRRSET || result == DNS_R_CNAME || 970 (result == DNS_R_DELEGATION && 971 dns_name_equal(newname, found))) 972 { 973 has_nsec = true; 974 result = ISC_R_SUCCESS; 975 } else if (result != DNS_R_NXDOMAIN) { 976 break; 977 } 978 } 979 } while (!has_nsec); 980 failure: 981 if (dbit != NULL) { 982 dns_dbiterator_destroy(&dbit); 983 } 984 985 return (result); 986 } 987 988 /*% 989 * Add a NSEC record for "name", recording the change in "diff". 990 * The existing NSEC is removed. 991 */ 992 static isc_result_t 993 add_nsec(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, 994 dns_dbversion_t *ver, dns_name_t *name, dns_ttl_t nsecttl, 995 dns_diff_t *diff) { 996 isc_result_t result; 997 dns_dbnode_t *node = NULL; 998 unsigned char buffer[DNS_NSEC_BUFFERSIZE]; 999 dns_rdata_t rdata = DNS_RDATA_INIT; 1000 dns_difftuple_t *tuple = NULL; 1001 dns_fixedname_t fixedname; 1002 dns_name_t *target; 1003 1004 target = dns_fixedname_initname(&fixedname); 1005 1006 /* 1007 * Find the successor name, aka NSEC target. 1008 */ 1009 CHECK(next_active(log, zone, db, ver, name, target, true)); 1010 1011 /* 1012 * Create the NSEC RDATA. 1013 */ 1014 CHECK(dns_db_findnode(db, name, false, &node)); 1015 dns_rdata_init(&rdata); 1016 CHECK(dns_nsec_buildrdata(db, ver, node, target, buffer, &rdata)); 1017 dns_db_detachnode(db, &node); 1018 1019 /* 1020 * Delete the old NSEC and record the change. 1021 */ 1022 CHECK(delete_if(true_p, db, ver, name, dns_rdatatype_nsec, 0, NULL, 1023 diff)); 1024 /* 1025 * Add the new NSEC and record the change. 1026 */ 1027 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, nsecttl, 1028 &rdata, &tuple)); 1029 CHECK(do_one_tuple(&tuple, db, ver, diff)); 1030 INSIST(tuple == NULL); 1031 1032 failure: 1033 if (node != NULL) { 1034 dns_db_detachnode(db, &node); 1035 } 1036 return (result); 1037 } 1038 1039 /*% 1040 * Add a placeholder NSEC record for "name", recording the change in "diff". 1041 */ 1042 static isc_result_t 1043 add_placeholder_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 1044 dns_diff_t *diff) { 1045 isc_result_t result; 1046 dns_difftuple_t *tuple = NULL; 1047 isc_region_t r; 1048 unsigned char data[1] = { 0 }; /* The root domain, no bits. */ 1049 dns_rdata_t rdata = DNS_RDATA_INIT; 1050 1051 r.base = data; 1052 r.length = sizeof(data); 1053 dns_rdata_fromregion(&rdata, dns_db_class(db), dns_rdatatype_nsec, &r); 1054 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, 0, &rdata, 1055 &tuple)); 1056 CHECK(do_one_tuple(&tuple, db, ver, diff)); 1057 failure: 1058 return (result); 1059 } 1060 1061 static isc_result_t 1062 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 1063 isc_mem_t *mctx, unsigned int maxkeys, dst_key_t **keys, 1064 unsigned int *nkeys) { 1065 isc_result_t result; 1066 isc_stdtime_t now; 1067 dns_dbnode_t *node = NULL; 1068 const char *directory = dns_zone_getkeydirectory(zone); 1069 CHECK(dns_db_findnode(db, dns_db_origin(db), false, &node)); 1070 isc_stdtime_get(&now); 1071 CHECK(dns_dnssec_findzonekeys(db, ver, node, dns_db_origin(db), 1072 directory, now, mctx, maxkeys, keys, 1073 nkeys)); 1074 failure: 1075 if (node != NULL) { 1076 dns_db_detachnode(db, &node); 1077 } 1078 return (result); 1079 } 1080 1081 /*% 1082 * Add RRSIG records for an RRset, recording the change in "diff". 1083 */ 1084 static isc_result_t 1085 add_sigs(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, 1086 dns_dbversion_t *ver, dns_name_t *name, dns_rdatatype_t type, 1087 dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys, 1088 isc_stdtime_t inception, isc_stdtime_t expire, bool check_ksk, 1089 bool keyset_kskonly) { 1090 isc_result_t result; 1091 dns_dbnode_t *node = NULL; 1092 dns_kasp_t *kasp = dns_zone_getkasp(zone); 1093 dns_rdataset_t rdataset; 1094 dns_rdata_t sig_rdata = DNS_RDATA_INIT; 1095 dns_stats_t *dnssecsignstats = dns_zone_getdnssecsignstats(zone); 1096 isc_buffer_t buffer; 1097 unsigned char data[1024]; /* XXX */ 1098 unsigned int i, j; 1099 bool added_sig = false; 1100 isc_mem_t *mctx = diff->mctx; 1101 1102 if (kasp != NULL) { 1103 check_ksk = false; 1104 keyset_kskonly = true; 1105 } 1106 1107 dns_rdataset_init(&rdataset); 1108 isc_buffer_init(&buffer, data, sizeof(data)); 1109 1110 /* Get the rdataset to sign. */ 1111 if (type == dns_rdatatype_nsec3) { 1112 CHECK(dns_db_findnsec3node(db, name, false, &node)); 1113 } else { 1114 CHECK(dns_db_findnode(db, name, false, &node)); 1115 } 1116 CHECK(dns_db_findrdataset(db, node, ver, type, 0, (isc_stdtime_t)0, 1117 &rdataset, NULL)); 1118 dns_db_detachnode(db, &node); 1119 1120 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0) 1121 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0) 1122 #define ID(x) dst_key_id(x) 1123 #define ALG(x) dst_key_alg(x) 1124 1125 /* 1126 * If we are honoring KSK flags then we need to check that we 1127 * have both KSK and non-KSK keys that are not revoked per 1128 * algorithm. 1129 */ 1130 for (i = 0; i < nkeys; i++) { 1131 bool both = false; 1132 1133 /* Don't add signatures for offline or inactive keys */ 1134 if (!dst_key_isprivate(keys[i])) { 1135 continue; 1136 } 1137 if (dst_key_inactive(keys[i])) { 1138 continue; 1139 } 1140 1141 if (check_ksk && !REVOKE(keys[i])) { 1142 bool have_ksk, have_nonksk; 1143 if (KSK(keys[i])) { 1144 have_ksk = true; 1145 have_nonksk = false; 1146 } else { 1147 have_ksk = false; 1148 have_nonksk = true; 1149 } 1150 for (j = 0; j < nkeys; j++) { 1151 if (j == i || ALG(keys[i]) != ALG(keys[j])) { 1152 continue; 1153 } 1154 1155 /* Don't consider inactive keys, however 1156 * the key may be temporary offline, so do 1157 * consider keys which private key files are 1158 * unavailable. 1159 */ 1160 if (dst_key_inactive(keys[j])) { 1161 continue; 1162 } 1163 1164 if (REVOKE(keys[j])) { 1165 continue; 1166 } 1167 if (KSK(keys[j])) { 1168 have_ksk = true; 1169 } else { 1170 have_nonksk = true; 1171 } 1172 both = have_ksk && have_nonksk; 1173 if (both) { 1174 break; 1175 } 1176 } 1177 } 1178 1179 if (kasp != NULL) { 1180 /* 1181 * A dnssec-policy is found. Check what RRsets this 1182 * key should sign. 1183 */ 1184 isc_stdtime_t when; 1185 isc_result_t kresult; 1186 bool ksk = false; 1187 bool zsk = false; 1188 1189 kresult = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk); 1190 if (kresult != ISC_R_SUCCESS) { 1191 if (KSK(keys[i])) { 1192 ksk = true; 1193 } 1194 } 1195 kresult = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk); 1196 if (kresult != ISC_R_SUCCESS) { 1197 if (!KSK(keys[i])) { 1198 zsk = true; 1199 } 1200 } 1201 1202 if (type == dns_rdatatype_dnskey || 1203 type == dns_rdatatype_cdnskey || 1204 type == dns_rdatatype_cds) 1205 { 1206 /* 1207 * DNSKEY RRset is signed with KSK. 1208 * CDS and CDNSKEY RRsets too (RFC 7344, 4.1). 1209 */ 1210 if (!ksk) { 1211 continue; 1212 } 1213 } else if (!zsk) { 1214 /* 1215 * Other RRsets are signed with ZSK. 1216 */ 1217 continue; 1218 } else if (zsk && 1219 !dst_key_is_signing(keys[i], DST_BOOL_ZSK, 1220 inception, &when)) { 1221 /* 1222 * This key is not active for zone-signing. 1223 */ 1224 continue; 1225 } 1226 1227 /* 1228 * If this key is revoked, it may only sign the 1229 * DNSKEY RRset. 1230 */ 1231 if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) { 1232 continue; 1233 } 1234 } else if (both) { 1235 /* 1236 * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1). 1237 */ 1238 if (type == dns_rdatatype_dnskey || 1239 type == dns_rdatatype_cdnskey || 1240 type == dns_rdatatype_cds) 1241 { 1242 if (!KSK(keys[i]) && keyset_kskonly) { 1243 continue; 1244 } 1245 } else if (KSK(keys[i])) { 1246 continue; 1247 } 1248 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) { 1249 continue; 1250 } 1251 1252 /* Calculate the signature, creating a RRSIG RDATA. */ 1253 CHECK(dns_dnssec_sign(name, &rdataset, keys[i], &inception, 1254 &expire, mctx, &buffer, &sig_rdata)); 1255 1256 /* Update the database and journal with the RRSIG. */ 1257 /* XXX inefficient - will cause dataset merging */ 1258 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, name, 1259 rdataset.ttl, &sig_rdata)); 1260 dns_rdata_reset(&sig_rdata); 1261 isc_buffer_init(&buffer, data, sizeof(data)); 1262 added_sig = true; 1263 /* Update DNSSEC sign statistics. */ 1264 if (dnssecsignstats != NULL) { 1265 dns_dnssecsignstats_increment(dnssecsignstats, 1266 ID(keys[i]), 1267 (uint8_t)ALG(keys[i]), 1268 dns_dnssecsignstats_sign); 1269 } 1270 } 1271 if (!added_sig) { 1272 update_log(log, zone, ISC_LOG_ERROR, 1273 "found no active private keys, " 1274 "unable to generate any signatures"); 1275 result = ISC_R_NOTFOUND; 1276 } 1277 1278 failure: 1279 if (dns_rdataset_isassociated(&rdataset)) { 1280 dns_rdataset_disassociate(&rdataset); 1281 } 1282 if (node != NULL) { 1283 dns_db_detachnode(db, &node); 1284 } 1285 return (result); 1286 } 1287 1288 /* 1289 * Delete expired RRsigs and any RRsigs we are about to re-sign. 1290 * See also zone.c:del_sigs(). 1291 */ 1292 static isc_result_t 1293 del_keysigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 1294 dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys) { 1295 isc_result_t result; 1296 dns_dbnode_t *node = NULL; 1297 dns_rdataset_t rdataset; 1298 dns_rdata_t rdata = DNS_RDATA_INIT; 1299 unsigned int i; 1300 dns_rdata_rrsig_t rrsig; 1301 bool found; 1302 1303 dns_rdataset_init(&rdataset); 1304 1305 result = dns_db_findnode(db, name, false, &node); 1306 if (result == ISC_R_NOTFOUND) { 1307 return (ISC_R_SUCCESS); 1308 } 1309 if (result != ISC_R_SUCCESS) { 1310 goto failure; 1311 } 1312 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, 1313 dns_rdatatype_dnskey, (isc_stdtime_t)0, 1314 &rdataset, NULL); 1315 dns_db_detachnode(db, &node); 1316 1317 if (result == ISC_R_NOTFOUND) { 1318 return (ISC_R_SUCCESS); 1319 } 1320 if (result != ISC_R_SUCCESS) { 1321 goto failure; 1322 } 1323 1324 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 1325 result = dns_rdataset_next(&rdataset)) 1326 { 1327 dns_rdataset_current(&rdataset, &rdata); 1328 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 1329 RUNTIME_CHECK(result == ISC_R_SUCCESS); 1330 found = false; 1331 for (i = 0; i < nkeys; i++) { 1332 if (rrsig.keyid == dst_key_id(keys[i])) { 1333 found = true; 1334 if (!dst_key_isprivate(keys[i]) && 1335 !dst_key_inactive(keys[i])) { 1336 /* 1337 * The re-signing code in zone.c 1338 * will mark this as offline. 1339 * Just skip the record for now. 1340 */ 1341 break; 1342 } 1343 result = update_one_rr(db, ver, diff, 1344 DNS_DIFFOP_DEL, name, 1345 rdataset.ttl, &rdata); 1346 break; 1347 } 1348 } 1349 /* 1350 * If there is not a matching DNSKEY then delete the RRSIG. 1351 */ 1352 if (!found) { 1353 result = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, 1354 name, rdataset.ttl, &rdata); 1355 } 1356 dns_rdata_reset(&rdata); 1357 if (result != ISC_R_SUCCESS) { 1358 break; 1359 } 1360 } 1361 dns_rdataset_disassociate(&rdataset); 1362 if (result == ISC_R_NOMORE) { 1363 result = ISC_R_SUCCESS; 1364 } 1365 failure: 1366 if (node != NULL) { 1367 dns_db_detachnode(db, &node); 1368 } 1369 return (result); 1370 } 1371 1372 static isc_result_t 1373 add_exposed_sigs(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, 1374 dns_dbversion_t *ver, dns_name_t *name, bool cut, 1375 dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys, 1376 isc_stdtime_t inception, isc_stdtime_t expire, bool check_ksk, 1377 bool keyset_kskonly, unsigned int *sigs) { 1378 isc_result_t result; 1379 dns_dbnode_t *node; 1380 dns_rdatasetiter_t *iter; 1381 1382 node = NULL; 1383 result = dns_db_findnode(db, name, false, &node); 1384 if (result == ISC_R_NOTFOUND) { 1385 return (ISC_R_SUCCESS); 1386 } 1387 if (result != ISC_R_SUCCESS) { 1388 return (result); 1389 } 1390 1391 iter = NULL; 1392 result = dns_db_allrdatasets(db, node, ver, (isc_stdtime_t)0, &iter); 1393 if (result != ISC_R_SUCCESS) { 1394 goto cleanup_node; 1395 } 1396 1397 for (result = dns_rdatasetiter_first(iter); result == ISC_R_SUCCESS; 1398 result = dns_rdatasetiter_next(iter)) 1399 { 1400 dns_rdataset_t rdataset; 1401 dns_rdatatype_t type; 1402 bool flag; 1403 1404 dns_rdataset_init(&rdataset); 1405 dns_rdatasetiter_current(iter, &rdataset); 1406 type = rdataset.type; 1407 dns_rdataset_disassociate(&rdataset); 1408 1409 /* 1410 * We don't need to sign unsigned NSEC records at the cut 1411 * as they are handled elsewhere. 1412 */ 1413 if ((type == dns_rdatatype_rrsig) || 1414 (cut && type != dns_rdatatype_ds)) { 1415 continue; 1416 } 1417 result = rrset_exists(db, ver, name, dns_rdatatype_rrsig, type, 1418 &flag); 1419 if (result != ISC_R_SUCCESS) { 1420 goto cleanup_iterator; 1421 } 1422 if (flag) { 1423 continue; 1424 } 1425 result = add_sigs(log, zone, db, ver, name, type, diff, keys, 1426 nkeys, inception, expire, check_ksk, 1427 keyset_kskonly); 1428 if (result != ISC_R_SUCCESS) { 1429 goto cleanup_iterator; 1430 } 1431 (*sigs)++; 1432 } 1433 if (result == ISC_R_NOMORE) { 1434 result = ISC_R_SUCCESS; 1435 } 1436 1437 cleanup_iterator: 1438 dns_rdatasetiter_destroy(&iter); 1439 1440 cleanup_node: 1441 dns_db_detachnode(db, &node); 1442 1443 return (result); 1444 } 1445 1446 /*% 1447 * Update RRSIG, NSEC and NSEC3 records affected by an update. The original 1448 * update, including the SOA serial update but excluding the RRSIG & NSEC 1449 * changes, is in "diff" and has already been applied to "newver" of "db". 1450 * The database version prior to the update is "oldver". 1451 * 1452 * The necessary RRSIG, NSEC and NSEC3 changes will be applied to "newver" 1453 * and added (as a minimal diff) to "diff". 1454 * 1455 * The RRSIGs generated will be valid for 'sigvalidityinterval' seconds. 1456 */ 1457 isc_result_t 1458 dns_update_signatures(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, 1459 dns_dbversion_t *oldver, dns_dbversion_t *newver, 1460 dns_diff_t *diff, uint32_t sigvalidityinterval) { 1461 return (dns_update_signaturesinc(log, zone, db, oldver, newver, diff, 1462 sigvalidityinterval, NULL)); 1463 } 1464 1465 struct dns_update_state { 1466 unsigned int magic; 1467 dns_diff_t diffnames; 1468 dns_diff_t affected; 1469 dns_diff_t sig_diff; 1470 dns_diff_t nsec_diff; 1471 dns_diff_t nsec_mindiff; 1472 dns_diff_t work; 1473 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 1474 unsigned int nkeys; 1475 isc_stdtime_t inception, expire, soaexpire, keyexpire; 1476 dns_ttl_t nsecttl; 1477 bool check_ksk, keyset_kskonly, build_nsec3; 1478 enum { sign_updates, 1479 remove_orphaned, 1480 build_chain, 1481 process_nsec, 1482 sign_nsec, 1483 update_nsec3, 1484 process_nsec3, 1485 sign_nsec3 } state; 1486 }; 1487 1488 static uint32_t 1489 dns__jitter_expire(dns_zone_t *zone, uint32_t sigvalidityinterval) { 1490 /* Spread out signatures over time */ 1491 if (sigvalidityinterval >= 3600U) { 1492 uint32_t expiryinterval = 1493 dns_zone_getsigresigninginterval(zone); 1494 1495 if (sigvalidityinterval < 7200U) { 1496 expiryinterval = 1200; 1497 } else if (expiryinterval > sigvalidityinterval) { 1498 expiryinterval = sigvalidityinterval; 1499 } else { 1500 expiryinterval = sigvalidityinterval - expiryinterval; 1501 } 1502 uint32_t jitter = isc_random_uniform(expiryinterval); 1503 sigvalidityinterval -= jitter; 1504 } 1505 return (sigvalidityinterval); 1506 } 1507 1508 isc_result_t 1509 dns_update_signaturesinc(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, 1510 dns_dbversion_t *oldver, dns_dbversion_t *newver, 1511 dns_diff_t *diff, uint32_t sigvalidityinterval, 1512 dns_update_state_t **statep) { 1513 isc_result_t result = ISC_R_SUCCESS; 1514 dns_update_state_t mystate, *state; 1515 1516 dns_difftuple_t *t, *next; 1517 bool flag, build_nsec; 1518 unsigned int i; 1519 isc_stdtime_t now; 1520 dns_rdata_soa_t soa; 1521 dns_rdata_t rdata = DNS_RDATA_INIT; 1522 dns_rdataset_t rdataset; 1523 dns_dbnode_t *node = NULL; 1524 bool unsecure; 1525 bool cut; 1526 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); 1527 unsigned int sigs = 0; 1528 unsigned int maxsigs = dns_zone_getsignatures(zone); 1529 1530 if (statep == NULL || *statep == NULL) { 1531 if (statep == NULL) { 1532 state = &mystate; 1533 } else { 1534 state = isc_mem_get(diff->mctx, sizeof(*state)); 1535 } 1536 1537 dns_diff_init(diff->mctx, &state->diffnames); 1538 dns_diff_init(diff->mctx, &state->affected); 1539 dns_diff_init(diff->mctx, &state->sig_diff); 1540 dns_diff_init(diff->mctx, &state->nsec_diff); 1541 dns_diff_init(diff->mctx, &state->nsec_mindiff); 1542 dns_diff_init(diff->mctx, &state->work); 1543 state->nkeys = 0; 1544 state->build_nsec3 = false; 1545 1546 result = find_zone_keys(zone, db, newver, diff->mctx, 1547 DNS_MAXZONEKEYS, state->zone_keys, 1548 &state->nkeys); 1549 if (result != ISC_R_SUCCESS) { 1550 update_log(log, zone, ISC_LOG_ERROR, 1551 "could not get zone keys for secure " 1552 "dynamic update"); 1553 goto failure; 1554 } 1555 1556 isc_stdtime_get(&now); 1557 state->inception = now - 3600; /* Allow for some clock skew. */ 1558 state->expire = now + 1559 dns__jitter_expire(zone, sigvalidityinterval); 1560 state->soaexpire = now + sigvalidityinterval; 1561 state->keyexpire = dns_zone_getkeyvalidityinterval(zone); 1562 if (state->keyexpire == 0) { 1563 state->keyexpire = state->expire; 1564 } else { 1565 state->keyexpire += now; 1566 } 1567 1568 /* 1569 * Do we look at the KSK flag on the DNSKEY to determining which 1570 * keys sign which RRsets? First check the zone option then 1571 * check the keys flags to make sure at least one has a ksk set 1572 * and one doesn't. 1573 */ 1574 state->check_ksk = ((dns_zone_getoptions(zone) & 1575 DNS_ZONEOPT_UPDATECHECKKSK) != 0); 1576 state->keyset_kskonly = ((dns_zone_getoptions(zone) & 1577 DNS_ZONEOPT_DNSKEYKSKONLY) != 0); 1578 1579 /* 1580 * Get the NSEC/NSEC3 TTL from the SOA MINIMUM field. 1581 */ 1582 CHECK(dns_db_findnode(db, dns_db_origin(db), false, &node)); 1583 dns_rdataset_init(&rdataset); 1584 CHECK(dns_db_findrdataset(db, node, newver, dns_rdatatype_soa, 1585 0, (isc_stdtime_t)0, &rdataset, 1586 NULL)); 1587 CHECK(dns_rdataset_first(&rdataset)); 1588 dns_rdataset_current(&rdataset, &rdata); 1589 CHECK(dns_rdata_tostruct(&rdata, &soa, NULL)); 1590 state->nsecttl = soa.minimum; 1591 dns_rdataset_disassociate(&rdataset); 1592 dns_db_detachnode(db, &node); 1593 1594 /* 1595 * Find all RRsets directly affected by the update, and 1596 * update their RRSIGs. Also build a list of names affected 1597 * by the update in "diffnames". 1598 */ 1599 CHECK(dns_diff_sort(diff, temp_order)); 1600 state->state = sign_updates; 1601 state->magic = STATE_MAGIC; 1602 if (statep != NULL) { 1603 *statep = state; 1604 } 1605 } else { 1606 REQUIRE(DNS_STATE_VALID(*statep)); 1607 state = *statep; 1608 } 1609 1610 next_state: 1611 switch (state->state) { 1612 case sign_updates: 1613 t = ISC_LIST_HEAD(diff->tuples); 1614 while (t != NULL) { 1615 dns_name_t *name = &t->name; 1616 /* 1617 * Now "name" is a new, unique name affected by the 1618 * update. 1619 */ 1620 1621 CHECK(namelist_append_name(&state->diffnames, name)); 1622 1623 while (t != NULL && dns_name_equal(&t->name, name)) { 1624 dns_rdatatype_t type; 1625 type = t->rdata.type; 1626 1627 /* 1628 * Now "name" and "type" denote a new unique 1629 * RRset affected by the update. 1630 */ 1631 1632 /* Don't sign RRSIGs. */ 1633 if (type == dns_rdatatype_rrsig) { 1634 goto skip; 1635 } 1636 1637 /* 1638 * Delete all old RRSIGs covering this type, 1639 * since they are all invalid when the signed 1640 * RRset has changed. We may not be able to 1641 * recreate all of them - tough. 1642 * Special case changes to the zone's DNSKEY 1643 * records to support offline KSKs. 1644 */ 1645 if (type == dns_rdatatype_dnskey) { 1646 del_keysigs(db, newver, name, 1647 &state->sig_diff, 1648 state->zone_keys, 1649 state->nkeys); 1650 } else { 1651 CHECK(delete_if( 1652 true_p, db, newver, name, 1653 dns_rdatatype_rrsig, type, NULL, 1654 &state->sig_diff)); 1655 } 1656 1657 /* 1658 * If this RRset is still visible after the 1659 * update, add a new signature for it. 1660 */ 1661 CHECK(rrset_visible(db, newver, name, type, 1662 &flag)); 1663 if (flag) { 1664 isc_stdtime_t exp; 1665 if (type == dns_rdatatype_dnskey || 1666 type == dns_rdatatype_cdnskey || 1667 type == dns_rdatatype_cds) 1668 { 1669 exp = state->keyexpire; 1670 } else if (type == dns_rdatatype_soa) { 1671 exp = state->soaexpire; 1672 } else { 1673 exp = state->expire; 1674 } 1675 1676 CHECK(add_sigs( 1677 log, zone, db, newver, name, 1678 type, &state->sig_diff, 1679 state->zone_keys, state->nkeys, 1680 state->inception, exp, 1681 state->check_ksk, 1682 state->keyset_kskonly)); 1683 sigs++; 1684 } 1685 skip: 1686 /* Skip any other updates to the same RRset. */ 1687 while (t != NULL && 1688 dns_name_equal(&t->name, name) && 1689 t->rdata.type == type) { 1690 next = ISC_LIST_NEXT(t, link); 1691 ISC_LIST_UNLINK(diff->tuples, t, link); 1692 ISC_LIST_APPEND(state->work.tuples, t, 1693 link); 1694 t = next; 1695 } 1696 } 1697 if (state != &mystate && sigs > maxsigs) { 1698 return (DNS_R_CONTINUE); 1699 } 1700 } 1701 ISC_LIST_APPENDLIST(diff->tuples, state->work.tuples, link); 1702 1703 update_log(log, zone, ISC_LOG_DEBUG(3), 1704 "updated data signatures"); 1705 /* FALLTHROUGH */ 1706 case remove_orphaned: 1707 state->state = remove_orphaned; 1708 1709 /* Remove orphaned NSECs and RRSIG NSECs. */ 1710 for (t = ISC_LIST_HEAD(state->diffnames.tuples); t != NULL; 1711 t = ISC_LIST_NEXT(t, link)) 1712 { 1713 CHECK(non_nsec_rrset_exists(db, newver, &t->name, 1714 &flag)); 1715 if (!flag) { 1716 CHECK(delete_if(true_p, db, newver, &t->name, 1717 dns_rdatatype_any, 0, NULL, 1718 &state->sig_diff)); 1719 } 1720 } 1721 update_log(log, zone, ISC_LOG_DEBUG(3), 1722 "removed any orphaned NSEC records"); 1723 1724 /* 1725 * See if we need to build NSEC or NSEC3 chains. 1726 */ 1727 CHECK(dns_private_chains(db, newver, privatetype, &build_nsec, 1728 &state->build_nsec3)); 1729 if (!build_nsec) { 1730 state->state = update_nsec3; 1731 goto next_state; 1732 } 1733 1734 update_log(log, zone, ISC_LOG_DEBUG(3), 1735 "rebuilding NSEC chain"); 1736 1737 /* FALLTHROUGH */ 1738 case build_chain: 1739 state->state = build_chain; 1740 /* 1741 * When a name is created or deleted, its predecessor needs to 1742 * have its NSEC updated. 1743 */ 1744 for (t = ISC_LIST_HEAD(state->diffnames.tuples); t != NULL; 1745 t = ISC_LIST_NEXT(t, link)) 1746 { 1747 bool existed, exists; 1748 dns_fixedname_t fixedname; 1749 dns_name_t *prevname; 1750 1751 prevname = dns_fixedname_initname(&fixedname); 1752 1753 if (oldver != NULL) { 1754 CHECK(name_exists(db, oldver, &t->name, 1755 &existed)); 1756 } else { 1757 existed = false; 1758 } 1759 CHECK(name_exists(db, newver, &t->name, &exists)); 1760 if (exists == existed) { 1761 continue; 1762 } 1763 1764 /* 1765 * Find the predecessor. 1766 * When names become obscured or unobscured in this 1767 * update transaction, we may find the wrong 1768 * predecessor because the NSECs have not yet been 1769 * updated to reflect the delegation change. This 1770 * should not matter because in this case, the correct 1771 * predecessor is either the delegation node or a 1772 * newly unobscured node, and those nodes are on the 1773 * "affected" list in any case. 1774 */ 1775 CHECK(next_active(log, zone, db, newver, &t->name, 1776 prevname, false)); 1777 CHECK(namelist_append_name(&state->affected, prevname)); 1778 } 1779 1780 /* 1781 * Find names potentially affected by delegation changes 1782 * (obscured by adding an NS or DNAME, or unobscured by 1783 * removing one). 1784 */ 1785 for (t = ISC_LIST_HEAD(state->diffnames.tuples); t != NULL; 1786 t = ISC_LIST_NEXT(t, link)) 1787 { 1788 bool ns_existed, dname_existed; 1789 bool ns_exists, dname_exists; 1790 1791 if (oldver != NULL) { 1792 CHECK(rrset_exists(db, oldver, &t->name, 1793 dns_rdatatype_ns, 0, 1794 &ns_existed)); 1795 } else { 1796 ns_existed = false; 1797 } 1798 if (oldver != NULL) { 1799 CHECK(rrset_exists(db, oldver, &t->name, 1800 dns_rdatatype_dname, 0, 1801 &dname_existed)); 1802 } else { 1803 dname_existed = false; 1804 } 1805 CHECK(rrset_exists(db, newver, &t->name, 1806 dns_rdatatype_ns, 0, &ns_exists)); 1807 CHECK(rrset_exists(db, newver, &t->name, 1808 dns_rdatatype_dname, 0, 1809 &dname_exists)); 1810 if ((ns_exists || dname_exists) == 1811 (ns_existed || dname_existed)) { 1812 continue; 1813 } 1814 /* 1815 * There was a delegation change. Mark all subdomains 1816 * of t->name as potentially needing a NSEC update. 1817 */ 1818 CHECK(namelist_append_subdomain(db, &t->name, 1819 &state->affected)); 1820 } 1821 ISC_LIST_APPENDLIST(state->affected.tuples, 1822 state->diffnames.tuples, link); 1823 INSIST(ISC_LIST_EMPTY(state->diffnames.tuples)); 1824 1825 CHECK(uniqify_name_list(&state->affected)); 1826 1827 /* FALLTHROUGH */ 1828 case process_nsec: 1829 state->state = process_nsec; 1830 1831 /* 1832 * Determine which names should have NSECs, and delete/create 1833 * NSECs to make it so. We don't know the final NSEC targets 1834 * yet, so we just create placeholder NSECs with arbitrary 1835 * contents to indicate that their respective owner names 1836 * should be part of the NSEC chain. 1837 */ 1838 while ((t = ISC_LIST_HEAD(state->affected.tuples)) != NULL) { 1839 bool exists; 1840 dns_name_t *name = &t->name; 1841 1842 CHECK(name_exists(db, newver, name, &exists)); 1843 if (!exists) { 1844 goto unlink; 1845 } 1846 CHECK(is_active(db, newver, name, &flag, &cut, NULL)); 1847 if (!flag) { 1848 /* 1849 * This name is obscured. Delete any 1850 * existing NSEC record. 1851 */ 1852 CHECK(delete_if(true_p, db, newver, name, 1853 dns_rdatatype_nsec, 0, NULL, 1854 &state->nsec_diff)); 1855 CHECK(delete_if(rrsig_p, db, newver, name, 1856 dns_rdatatype_any, 0, NULL, 1857 diff)); 1858 } else { 1859 /* 1860 * This name is not obscured. It needs to have 1861 * a NSEC unless it is the at the origin, in 1862 * which case it should already exist if there 1863 * is a complete NSEC chain and if there isn't 1864 * a complete NSEC chain we don't want to add 1865 * one as that would signal that there is a 1866 * complete NSEC chain. 1867 */ 1868 if (!dns_name_equal(name, dns_db_origin(db))) { 1869 CHECK(rrset_exists(db, newver, name, 1870 dns_rdatatype_nsec, 1871 0, &flag)); 1872 if (!flag) { 1873 CHECK(add_placeholder_nsec( 1874 db, newver, name, 1875 diff)); 1876 } 1877 } 1878 CHECK(add_exposed_sigs( 1879 log, zone, db, newver, name, cut, 1880 &state->sig_diff, state->zone_keys, 1881 state->nkeys, state->inception, 1882 state->expire, state->check_ksk, 1883 state->keyset_kskonly, &sigs)); 1884 } 1885 unlink: 1886 ISC_LIST_UNLINK(state->affected.tuples, t, link); 1887 ISC_LIST_APPEND(state->work.tuples, t, link); 1888 if (state != &mystate && sigs > maxsigs) { 1889 return (DNS_R_CONTINUE); 1890 } 1891 } 1892 ISC_LIST_APPENDLIST(state->affected.tuples, state->work.tuples, 1893 link); 1894 1895 /* 1896 * Now we know which names are part of the NSEC chain. 1897 * Make them all point at their correct targets. 1898 */ 1899 for (t = ISC_LIST_HEAD(state->affected.tuples); t != NULL; 1900 t = ISC_LIST_NEXT(t, link)) 1901 { 1902 CHECK(rrset_exists(db, newver, &t->name, 1903 dns_rdatatype_nsec, 0, &flag)); 1904 if (flag) { 1905 /* 1906 * There is a NSEC, but we don't know if it 1907 * is correct. Delete it and create a correct 1908 * one to be sure. If the update was 1909 * unnecessary, the diff minimization 1910 * will take care of eliminating it from the 1911 * journal, IXFRs, etc. 1912 * 1913 * The RRSIG bit should always be set in the 1914 * NSECs we generate, because they will all 1915 * get RRSIG NSECs. 1916 * (XXX what if the zone keys are missing?). 1917 * Because the RRSIG NSECs have not necessarily 1918 * been created yet, the correctness of the 1919 * bit mask relies on the assumption that NSECs 1920 * are only created if there is other data, and 1921 * if there is other data, there are other 1922 * RRSIGs. 1923 */ 1924 CHECK(add_nsec(log, zone, db, newver, &t->name, 1925 state->nsecttl, 1926 &state->nsec_diff)); 1927 } 1928 } 1929 1930 /* 1931 * Minimize the set of NSEC updates so that we don't 1932 * have to regenerate the RRSIG NSECs for NSECs that were 1933 * replaced with identical ones. 1934 */ 1935 while ((t = ISC_LIST_HEAD(state->nsec_diff.tuples)) != NULL) { 1936 ISC_LIST_UNLINK(state->nsec_diff.tuples, t, link); 1937 dns_diff_appendminimal(&state->nsec_mindiff, &t); 1938 } 1939 1940 update_log(log, zone, ISC_LOG_DEBUG(3), 1941 "signing rebuilt NSEC chain"); 1942 1943 /* FALLTHROUGH */ 1944 case sign_nsec: 1945 state->state = sign_nsec; 1946 /* Update RRSIG NSECs. */ 1947 while ((t = ISC_LIST_HEAD(state->nsec_mindiff.tuples)) != NULL) 1948 { 1949 if (t->op == DNS_DIFFOP_DEL) { 1950 CHECK(delete_if(true_p, db, newver, &t->name, 1951 dns_rdatatype_rrsig, 1952 dns_rdatatype_nsec, NULL, 1953 &state->sig_diff)); 1954 } else if (t->op == DNS_DIFFOP_ADD) { 1955 CHECK(add_sigs(log, zone, db, newver, &t->name, 1956 dns_rdatatype_nsec, 1957 &state->sig_diff, 1958 state->zone_keys, state->nkeys, 1959 state->inception, state->expire, 1960 state->check_ksk, 1961 state->keyset_kskonly)); 1962 sigs++; 1963 } else { 1964 INSIST(0); 1965 ISC_UNREACHABLE(); 1966 } 1967 ISC_LIST_UNLINK(state->nsec_mindiff.tuples, t, link); 1968 ISC_LIST_APPEND(state->work.tuples, t, link); 1969 if (state != &mystate && sigs > maxsigs) { 1970 return (DNS_R_CONTINUE); 1971 } 1972 } 1973 ISC_LIST_APPENDLIST(state->nsec_mindiff.tuples, 1974 state->work.tuples, link); 1975 /* FALLTHROUGH */ 1976 case update_nsec3: 1977 state->state = update_nsec3; 1978 1979 /* Record our changes for the journal. */ 1980 while ((t = ISC_LIST_HEAD(state->sig_diff.tuples)) != NULL) { 1981 ISC_LIST_UNLINK(state->sig_diff.tuples, t, link); 1982 dns_diff_appendminimal(diff, &t); 1983 } 1984 while ((t = ISC_LIST_HEAD(state->nsec_mindiff.tuples)) != NULL) 1985 { 1986 ISC_LIST_UNLINK(state->nsec_mindiff.tuples, t, link); 1987 dns_diff_appendminimal(diff, &t); 1988 } 1989 1990 INSIST(ISC_LIST_EMPTY(state->sig_diff.tuples)); 1991 INSIST(ISC_LIST_EMPTY(state->nsec_diff.tuples)); 1992 INSIST(ISC_LIST_EMPTY(state->nsec_mindiff.tuples)); 1993 1994 if (!state->build_nsec3) { 1995 update_log(log, zone, ISC_LOG_DEBUG(3), 1996 "no NSEC3 chains to rebuild"); 1997 goto failure; 1998 } 1999 2000 update_log(log, zone, ISC_LOG_DEBUG(3), 2001 "rebuilding NSEC3 chains"); 2002 2003 dns_diff_clear(&state->diffnames); 2004 dns_diff_clear(&state->affected); 2005 2006 CHECK(dns_diff_sort(diff, temp_order)); 2007 2008 /* 2009 * Find names potentially affected by delegation changes 2010 * (obscured by adding an NS or DNAME, or unobscured by 2011 * removing one). 2012 */ 2013 t = ISC_LIST_HEAD(diff->tuples); 2014 while (t != NULL) { 2015 dns_name_t *name = &t->name; 2016 2017 bool ns_existed, dname_existed; 2018 bool ns_exists, dname_exists; 2019 bool exists, existed; 2020 2021 if (t->rdata.type == dns_rdatatype_nsec || 2022 t->rdata.type == dns_rdatatype_rrsig) { 2023 t = ISC_LIST_NEXT(t, link); 2024 continue; 2025 } 2026 2027 CHECK(namelist_append_name(&state->affected, name)); 2028 2029 if (oldver != NULL) { 2030 CHECK(rrset_exists(db, oldver, name, 2031 dns_rdatatype_ns, 0, 2032 &ns_existed)); 2033 } else { 2034 ns_existed = false; 2035 } 2036 if (oldver != NULL) { 2037 CHECK(rrset_exists(db, oldver, name, 2038 dns_rdatatype_dname, 0, 2039 &dname_existed)); 2040 } else { 2041 dname_existed = false; 2042 } 2043 CHECK(rrset_exists(db, newver, name, dns_rdatatype_ns, 2044 0, &ns_exists)); 2045 CHECK(rrset_exists(db, newver, name, 2046 dns_rdatatype_dname, 0, 2047 &dname_exists)); 2048 2049 exists = ns_exists || dname_exists; 2050 existed = ns_existed || dname_existed; 2051 if (exists == existed) { 2052 goto nextname; 2053 } 2054 /* 2055 * There was a delegation change. Mark all subdomains 2056 * of t->name as potentially needing a NSEC3 update. 2057 */ 2058 CHECK(namelist_append_subdomain(db, name, 2059 &state->affected)); 2060 2061 nextname: 2062 while (t != NULL && dns_name_equal(&t->name, name)) { 2063 t = ISC_LIST_NEXT(t, link); 2064 } 2065 } 2066 2067 /* FALLTHROUGH */ 2068 case process_nsec3: 2069 state->state = process_nsec3; 2070 while ((t = ISC_LIST_HEAD(state->affected.tuples)) != NULL) { 2071 dns_name_t *name = &t->name; 2072 2073 unsecure = false; /* Silence compiler warning. */ 2074 CHECK(is_active(db, newver, name, &flag, &cut, 2075 &unsecure)); 2076 2077 if (!flag) { 2078 CHECK(delete_if(rrsig_p, db, newver, name, 2079 dns_rdatatype_any, 0, NULL, 2080 diff)); 2081 CHECK(dns_nsec3_delnsec3sx(db, newver, name, 2082 privatetype, 2083 &state->nsec_diff)); 2084 } else { 2085 CHECK(add_exposed_sigs( 2086 log, zone, db, newver, name, cut, 2087 &state->sig_diff, state->zone_keys, 2088 state->nkeys, state->inception, 2089 state->expire, state->check_ksk, 2090 state->keyset_kskonly, &sigs)); 2091 CHECK(dns_nsec3_addnsec3sx( 2092 db, newver, name, state->nsecttl, 2093 unsecure, privatetype, 2094 &state->nsec_diff)); 2095 } 2096 ISC_LIST_UNLINK(state->affected.tuples, t, link); 2097 ISC_LIST_APPEND(state->work.tuples, t, link); 2098 if (state != &mystate && sigs > maxsigs) { 2099 return (DNS_R_CONTINUE); 2100 } 2101 } 2102 ISC_LIST_APPENDLIST(state->affected.tuples, state->work.tuples, 2103 link); 2104 2105 /* 2106 * Minimize the set of NSEC3 updates so that we don't 2107 * have to regenerate the RRSIG NSEC3s for NSEC3s that were 2108 * replaced with identical ones. 2109 */ 2110 while ((t = ISC_LIST_HEAD(state->nsec_diff.tuples)) != NULL) { 2111 ISC_LIST_UNLINK(state->nsec_diff.tuples, t, link); 2112 dns_diff_appendminimal(&state->nsec_mindiff, &t); 2113 } 2114 2115 update_log(log, zone, ISC_LOG_DEBUG(3), 2116 "signing rebuilt NSEC3 chain"); 2117 2118 /* FALLTHROUGH */ 2119 case sign_nsec3: 2120 state->state = sign_nsec3; 2121 /* Update RRSIG NSEC3s. */ 2122 while ((t = ISC_LIST_HEAD(state->nsec_mindiff.tuples)) != NULL) 2123 { 2124 if (t->op == DNS_DIFFOP_DEL) { 2125 CHECK(delete_if(true_p, db, newver, &t->name, 2126 dns_rdatatype_rrsig, 2127 dns_rdatatype_nsec3, NULL, 2128 &state->sig_diff)); 2129 } else if (t->op == DNS_DIFFOP_ADD) { 2130 CHECK(add_sigs(log, zone, db, newver, &t->name, 2131 dns_rdatatype_nsec3, 2132 &state->sig_diff, 2133 state->zone_keys, state->nkeys, 2134 state->inception, state->expire, 2135 state->check_ksk, 2136 state->keyset_kskonly)); 2137 sigs++; 2138 } else { 2139 INSIST(0); 2140 ISC_UNREACHABLE(); 2141 } 2142 ISC_LIST_UNLINK(state->nsec_mindiff.tuples, t, link); 2143 ISC_LIST_APPEND(state->work.tuples, t, link); 2144 if (state != &mystate && sigs > maxsigs) { 2145 return (DNS_R_CONTINUE); 2146 } 2147 } 2148 ISC_LIST_APPENDLIST(state->nsec_mindiff.tuples, 2149 state->work.tuples, link); 2150 2151 /* Record our changes for the journal. */ 2152 while ((t = ISC_LIST_HEAD(state->sig_diff.tuples)) != NULL) { 2153 ISC_LIST_UNLINK(state->sig_diff.tuples, t, link); 2154 dns_diff_appendminimal(diff, &t); 2155 } 2156 while ((t = ISC_LIST_HEAD(state->nsec_mindiff.tuples)) != NULL) 2157 { 2158 ISC_LIST_UNLINK(state->nsec_mindiff.tuples, t, link); 2159 dns_diff_appendminimal(diff, &t); 2160 } 2161 2162 INSIST(ISC_LIST_EMPTY(state->sig_diff.tuples)); 2163 INSIST(ISC_LIST_EMPTY(state->nsec_diff.tuples)); 2164 INSIST(ISC_LIST_EMPTY(state->nsec_mindiff.tuples)); 2165 break; 2166 default: 2167 INSIST(0); 2168 ISC_UNREACHABLE(); 2169 } 2170 2171 failure: 2172 if (node != NULL) { 2173 dns_db_detachnode(db, &node); 2174 } 2175 2176 dns_diff_clear(&state->sig_diff); 2177 dns_diff_clear(&state->nsec_diff); 2178 dns_diff_clear(&state->nsec_mindiff); 2179 2180 dns_diff_clear(&state->affected); 2181 dns_diff_clear(&state->diffnames); 2182 dns_diff_clear(&state->work); 2183 2184 for (i = 0; i < state->nkeys; i++) { 2185 dst_key_free(&state->zone_keys[i]); 2186 } 2187 2188 if (state != &mystate && state != NULL) { 2189 *statep = NULL; 2190 state->magic = 0; 2191 isc_mem_put(diff->mctx, state, sizeof(*state)); 2192 } 2193 2194 return (result); 2195 } 2196 2197 static isc_stdtime_t 2198 epoch_to_yyyymmdd(time_t when) { 2199 struct tm t, *tm = localtime_r(&when, &t); 2200 if (tm == NULL) { 2201 return (0); 2202 } 2203 return (((tm->tm_year + 1900) * 10000) + ((tm->tm_mon + 1) * 100) + 2204 tm->tm_mday); 2205 } 2206 2207 uint32_t 2208 dns_update_soaserial(uint32_t serial, dns_updatemethod_t method) { 2209 isc_stdtime_t now; 2210 uint32_t new_serial; 2211 2212 switch (method) { 2213 case dns_updatemethod_none: 2214 return (serial); 2215 case dns_updatemethod_unixtime: 2216 isc_stdtime_get(&now); 2217 if (now != 0 && isc_serial_gt(now, serial)) { 2218 return (now); 2219 } 2220 break; 2221 case dns_updatemethod_date: 2222 isc_stdtime_get(&now); 2223 new_serial = epoch_to_yyyymmdd((time_t)now) * 100; 2224 if (new_serial != 0 && isc_serial_gt(new_serial, serial)) { 2225 return (new_serial); 2226 } 2227 case dns_updatemethod_increment: 2228 break; 2229 } 2230 2231 /* RFC1982 */ 2232 serial = (serial + 1) & 0xFFFFFFFF; 2233 if (serial == 0) { 2234 serial = 1; 2235 } 2236 2237 return (serial); 2238 } 2239