1 /* $NetBSD: zone.c,v 1.23 2025/01/27 15:40:36 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /*! \file */ 17 18 #include <errno.h> 19 #include <inttypes.h> 20 #include <stdbool.h> 21 22 #include <isc/async.h> 23 #include <isc/atomic.h> 24 #include <isc/file.h> 25 #include <isc/hash.h> 26 #include <isc/hashmap.h> 27 #include <isc/hex.h> 28 #include <isc/loop.h> 29 #include <isc/md.h> 30 #include <isc/mutex.h> 31 #include <isc/overflow.h> 32 #include <isc/random.h> 33 #include <isc/ratelimiter.h> 34 #include <isc/refcount.h> 35 #include <isc/result.h> 36 #include <isc/rwlock.h> 37 #include <isc/serial.h> 38 #include <isc/stats.h> 39 #include <isc/stdtime.h> 40 #include <isc/strerr.h> 41 #include <isc/string.h> 42 #include <isc/thread.h> 43 #include <isc/tid.h> 44 #include <isc/timer.h> 45 #include <isc/tls.h> 46 #include <isc/util.h> 47 48 #include <dns/acl.h> 49 #include <dns/adb.h> 50 #include <dns/callbacks.h> 51 #include <dns/catz.h> 52 #include <dns/db.h> 53 #include <dns/dbiterator.h> 54 #include <dns/dlz.h> 55 #include <dns/dnssec.h> 56 #include <dns/journal.h> 57 #include <dns/kasp.h> 58 #include <dns/keydata.h> 59 #include <dns/keymgr.h> 60 #include <dns/keytable.h> 61 #include <dns/keyvalues.h> 62 #include <dns/log.h> 63 #include <dns/master.h> 64 #include <dns/masterdump.h> 65 #include <dns/message.h> 66 #include <dns/name.h> 67 #include <dns/nsec.h> 68 #include <dns/nsec3.h> 69 #include <dns/opcode.h> 70 #include <dns/peer.h> 71 #include <dns/private.h> 72 #include <dns/rcode.h> 73 #include <dns/rdata.h> 74 #include <dns/rdataclass.h> 75 #include <dns/rdatalist.h> 76 #include <dns/rdataset.h> 77 #include <dns/rdatasetiter.h> 78 #include <dns/rdatastruct.h> 79 #include <dns/rdatatype.h> 80 #include <dns/remote.h> 81 #include <dns/request.h> 82 #include <dns/resolver.h> 83 #include <dns/rriterator.h> 84 #include <dns/skr.h> 85 #include <dns/soa.h> 86 #include <dns/ssu.h> 87 #include <dns/stats.h> 88 #include <dns/time.h> 89 #include <dns/tsig.h> 90 #include <dns/ttl.h> 91 #include <dns/update.h> 92 #include <dns/xfrin.h> 93 #include <dns/zone.h> 94 #include <dns/zoneverify.h> 95 #include <dns/zt.h> 96 97 #include <dst/dst.h> 98 99 #include "zone_p.h" 100 101 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E') 102 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC) 103 104 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y') 105 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC) 106 107 #define CHECKDS_MAGIC ISC_MAGIC('C', 'h', 'D', 'S') 108 #define DNS_CHECKDS_VALID(checkds) ISC_MAGIC_VALID(checkds, CHECKDS_MAGIC) 109 110 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b') 111 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC) 112 113 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r') 114 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC) 115 116 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w') 117 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC) 118 119 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O') 120 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC) 121 122 #define KEYMGMT_MAGIC ISC_MAGIC('M', 'g', 'm', 't') 123 #define DNS_KEYMGMT_VALID(load) ISC_MAGIC_VALID(load, KEYMGMT_MAGIC) 124 125 #define KEYFILEIO_MAGIC ISC_MAGIC('K', 'y', 'I', 'O') 126 #define DNS_KEYFILEIO_VALID(kfio) ISC_MAGIC_VALID(kfio, KEYFILEIO_MAGIC) 127 128 /*% 129 * Ensure 'a' is at least 'min' but not more than 'max'. 130 */ 131 #define RANGE(a, min, max) (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max))) 132 133 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) 134 135 /*% 136 * Key flags 137 */ 138 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0) 139 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0) 140 #define ID(x) dst_key_id(x) 141 #define ALG(x) dst_key_alg(x) 142 143 /*% 144 * KASP flags 145 */ 146 #define KASP_LOCK(k) \ 147 if ((k) != NULL) { \ 148 LOCK((&((k)->lock))); \ 149 } 150 151 #define KASP_UNLOCK(k) \ 152 if ((k) != NULL) { \ 153 UNLOCK((&((k)->lock))); \ 154 } 155 156 /* 157 * Default values. 158 */ 159 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */ 160 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */ 161 #define MAX_XFER_TIME (2 * 3600) /*%< Documented default is 2 hours */ 162 #define RESIGN_DELAY 3600 /*%< 1 hour */ 163 164 #ifndef DNS_MAX_EXPIRE 165 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */ 166 #endif /* ifndef DNS_MAX_EXPIRE */ 167 168 #ifndef DNS_DUMP_DELAY 169 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */ 170 #endif /* ifndef DNS_DUMP_DELAY */ 171 172 typedef struct dns_notify dns_notify_t; 173 typedef struct dns_checkds dns_checkds_t; 174 typedef struct dns_stub dns_stub_t; 175 typedef struct dns_load dns_load_t; 176 typedef struct dns_forward dns_forward_t; 177 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t; 178 typedef struct dns_keymgmt dns_keymgmt_t; 179 typedef struct dns_signing dns_signing_t; 180 typedef ISC_LIST(dns_signing_t) dns_signinglist_t; 181 typedef struct dns_nsec3chain dns_nsec3chain_t; 182 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t; 183 typedef struct dns_nsfetch dns_nsfetch_t; 184 typedef struct dns_keyfetch dns_keyfetch_t; 185 typedef struct dns_asyncload dns_asyncload_t; 186 typedef struct dns_include dns_include_t; 187 188 #define DNS_ZONE_CHECKLOCK 189 #ifdef DNS_ZONE_CHECKLOCK 190 #define LOCK_ZONE(z) \ 191 do { \ 192 LOCK(&(z)->lock); \ 193 INSIST(!(z)->locked); \ 194 (z)->locked = true; \ 195 } while (0) 196 #define UNLOCK_ZONE(z) \ 197 do { \ 198 (z)->locked = false; \ 199 UNLOCK(&(z)->lock); \ 200 } while (0) 201 #define LOCKED_ZONE(z) ((z)->locked) 202 #define TRYLOCK_ZONE(result, z) \ 203 do { \ 204 result = isc_mutex_trylock(&(z)->lock); \ 205 if (result == ISC_R_SUCCESS) { \ 206 INSIST(!(z)->locked); \ 207 (z)->locked = true; \ 208 } \ 209 } while (0) 210 #else /* ifdef DNS_ZONE_CHECKLOCK */ 211 #define LOCK_ZONE(z) LOCK(&(z)->lock) 212 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock) 213 #define LOCKED_ZONE(z) true 214 #define TRYLOCK_ZONE(result, z) \ 215 do { \ 216 result = isc_mutex_trylock(&(z)->lock); \ 217 } while (0) 218 #endif /* ifdef DNS_ZONE_CHECKLOCK */ 219 220 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l)) 221 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l) 222 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t)) 223 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t)) 224 225 #define RETERR(x) \ 226 do { \ 227 result = (x); \ 228 if (result != ISC_R_SUCCESS) \ 229 goto failure; \ 230 } while (0) 231 232 #ifdef ENABLE_AFL 233 extern bool dns_fuzzing_resolver; 234 #endif /* ifdef ENABLE_AFL */ 235 236 /*% 237 * Hold key file IO locks. 238 */ 239 typedef struct dns_keyfileio { 240 unsigned int magic; 241 isc_mutex_t lock; 242 isc_refcount_t references; 243 dns_name_t *name; 244 dns_fixedname_t fname; 245 } dns_keyfileio_t; 246 247 struct dns_keymgmt { 248 unsigned int magic; 249 isc_rwlock_t lock; 250 isc_mem_t *mctx; 251 isc_hashmap_t *table; 252 }; 253 254 /* 255 * Initial size of the keymgmt hash table. 256 */ 257 #define DNS_KEYMGMT_HASH_BITS 12 258 259 struct dns_zone { 260 /* Unlocked */ 261 unsigned int magic; 262 isc_mutex_t lock; 263 #ifndef _LP64 264 isc_mutex_t atomic_lock; 265 #endif 266 #ifdef DNS_ZONE_CHECKLOCK 267 bool locked; 268 #endif /* ifdef DNS_ZONE_CHECKLOCK */ 269 isc_mem_t *mctx; 270 isc_refcount_t references; 271 272 isc_rwlock_t dblock; 273 dns_db_t *db; /* Locked by dblock */ 274 275 unsigned int tid; 276 277 /* Locked */ 278 dns_zonemgr_t *zmgr; 279 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */ 280 isc_loop_t *loop; 281 isc_timer_t *timer; 282 isc_refcount_t irefs; 283 dns_name_t origin; 284 char *masterfile; 285 const FILE *stream; /* loading from a stream? */ 286 ISC_LIST(dns_include_t) includes; /* Include files */ 287 ISC_LIST(dns_include_t) newincludes; /* Loading */ 288 unsigned int nincludes; 289 dns_masterformat_t masterformat; 290 const dns_master_style_t *masterstyle; 291 char *journal; 292 int32_t journalsize; 293 dns_rdataclass_t rdclass; 294 dns_zonetype_t type; 295 #ifdef _LP64 296 atomic_uint_fast64_t flags; 297 atomic_uint_fast64_t options; 298 #else 299 uint64_t flags; 300 uint64_t options; 301 #endif 302 unsigned int db_argc; 303 char **db_argv; 304 isc_time_t expiretime; 305 isc_time_t refreshtime; 306 isc_time_t dumptime; 307 isc_time_t loadtime; 308 isc_time_t notifytime; 309 isc_time_t resigntime; 310 isc_time_t keywarntime; 311 isc_time_t signingtime; 312 isc_time_t nsec3chaintime; 313 isc_time_t refreshkeytime; 314 isc_time_t xfrintime; 315 uint32_t refreshkeyinterval; 316 uint32_t refreshkeycount; 317 uint32_t refresh; 318 uint32_t retry; 319 uint32_t expire; 320 uint32_t minimum; 321 isc_stdtime_t key_expiry; 322 isc_stdtime_t log_key_expired_timer; 323 char *keydirectory; 324 dns_keyfileio_t *kfio; 325 dns_keystorelist_t *keystores; 326 dns_xfrin_t *xfr; 327 328 uint32_t maxrefresh; 329 uint32_t minrefresh; 330 uint32_t maxretry; 331 uint32_t minretry; 332 333 uint32_t maxrecords; 334 uint32_t maxrrperset; 335 uint32_t maxtypepername; 336 337 dns_remote_t primaries; 338 339 dns_remote_t parentals; 340 dns_dnsseckeylist_t checkds_ok; 341 dns_checkdstype_t checkdstype; 342 uint32_t nsfetchcount; 343 uint32_t parent_nscount; 344 345 dns_remote_t notify; 346 dns_notifytype_t notifytype; 347 isc_sockaddr_t notifyfrom; 348 isc_sockaddr_t notifysrc4; 349 isc_sockaddr_t notifysrc6; 350 isc_sockaddr_t parentalsrc4; 351 isc_sockaddr_t parentalsrc6; 352 isc_sockaddr_t xfrsource4; 353 isc_sockaddr_t xfrsource6; 354 isc_sockaddr_t sourceaddr; 355 dns_tsigkey_t *tsigkey; /* key used for xfr */ 356 dns_transport_t *transport; /* transport used for xfr */ 357 /* Access Control Lists */ 358 dns_acl_t *update_acl; 359 dns_acl_t *forward_acl; 360 dns_acl_t *notify_acl; 361 dns_acl_t *query_acl; 362 dns_acl_t *queryon_acl; 363 dns_acl_t *xfr_acl; 364 bool update_disabled; 365 bool zero_no_soa_ttl; 366 dns_severity_t check_names; 367 ISC_LIST(dns_notify_t) notifies; 368 ISC_LIST(dns_checkds_t) checkds_requests; 369 dns_request_t *request; 370 dns_loadctx_t *loadctx; 371 dns_dumpctx_t *dumpctx; 372 uint32_t maxxfrin; 373 uint32_t maxxfrout; 374 uint32_t idlein; 375 uint32_t idleout; 376 dns_ssutable_t *ssutable; 377 uint32_t sigvalidityinterval; 378 uint32_t keyvalidityinterval; 379 uint32_t sigresigninginterval; 380 dns_view_t *view; 381 dns_view_t *prev_view; 382 dns_kasp_t *kasp; 383 dns_kasp_t *defaultkasp; 384 dns_dnsseckeylist_t keyring; 385 dns_checkmxfunc_t checkmx; 386 dns_checksrvfunc_t checksrv; 387 dns_checknsfunc_t checkns; 388 /*% 389 * Zones in certain states such as "waiting for zone transfer" 390 * or "zone transfer in progress" are kept on per-state linked lists 391 * in the zone manager using the 'statelink' field. The 'statelist' 392 * field points at the list the zone is currently on. It the zone 393 * is not on any such list, statelist is NULL. 394 */ 395 ISC_LINK(dns_zone_t) statelink; 396 dns_zonelist_t *statelist; 397 /*% 398 * Statistics counters about zone management. 399 */ 400 isc_stats_t *stats; 401 /*% 402 * Optional per-zone statistics counters. Counted outside of this 403 * module. 404 */ 405 dns_zonestat_level_t statlevel; 406 bool requeststats_on; 407 isc_stats_t *requeststats; 408 dns_stats_t *rcvquerystats; 409 dns_stats_t *dnssecsignstats; 410 uint32_t notifydelay; 411 dns_isselffunc_t isself; 412 void *isselfarg; 413 414 char *strnamerd; 415 char *strname; 416 char *strrdclass; 417 char *strviewname; 418 419 /*% 420 * Serial number for deferred journal compaction. 421 */ 422 uint32_t compact_serial; 423 /*% 424 * Keys that are signing the zone for the first time. 425 */ 426 dns_signinglist_t signing; 427 dns_nsec3chainlist_t nsec3chain; 428 /*% 429 * List of outstanding NSEC3PARAM change requests. 430 */ 431 ISC_LIST(struct np3) setnsec3param_queue; 432 /*% 433 * Signing / re-signing quantum stopping parameters. 434 */ 435 uint32_t signatures; 436 uint32_t nodes; 437 dns_rdatatype_t privatetype; 438 439 /*% 440 * Autosigning/key-maintenance options 441 */ 442 #ifdef _LP64 443 atomic_uint_fast64_t keyopts; 444 #else 445 uint64_t keyopts; 446 #endif 447 448 /*% 449 * True if added by "rndc addzone" 450 */ 451 bool added; 452 453 /*% 454 * True if added by automatically by named. 455 */ 456 bool automatic; 457 458 /*% 459 * response policy data to be relayed to the database 460 */ 461 dns_rpz_zones_t *rpzs; 462 dns_rpz_num_t rpz_num; 463 464 /*% 465 * catalog zone data 466 */ 467 dns_catz_zones_t *catzs; 468 469 /*% 470 * parent catalog zone 471 */ 472 dns_catz_zone_t *parentcatz; 473 474 /*% 475 * Serial number update method. 476 */ 477 dns_updatemethod_t updatemethod; 478 479 /*% 480 * whether ixfr is requested 481 */ 482 bool requestixfr; 483 uint32_t ixfr_ratio; 484 485 /*% 486 * whether EDNS EXPIRE is requested 487 */ 488 bool requestexpire; 489 490 /*% 491 * Outstanding forwarded UPDATE requests. 492 */ 493 dns_forwardlist_t forwards; 494 495 dns_zone_t *raw; 496 dns_zone_t *secure; 497 498 bool sourceserialset; 499 uint32_t sourceserial; 500 501 /*% 502 * soa and maximum zone ttl 503 */ 504 dns_ttl_t soattl; 505 dns_ttl_t maxttl; 506 507 /* 508 * Inline zone signing state. 509 */ 510 dns_diff_t rss_diff; 511 dns_dbversion_t *rss_newver; 512 dns_dbversion_t *rss_oldver; 513 dns_db_t *rss_db; 514 dns_zone_t *rss_raw; 515 struct rss *rss; 516 dns_update_state_t *rss_state; 517 518 isc_stats_t *gluecachestats; 519 520 /*% 521 * Offline KSK signed key responses. 522 */ 523 dns_skr_t *skr; 524 dns_skrbundle_t *skrbundle; 525 }; 526 527 #define zonediff_init(z, d) \ 528 do { \ 529 dns__zonediff_t *_z = (z); \ 530 (_z)->diff = (d); \ 531 (_z)->offline = false; \ 532 } while (0) 533 #ifdef _LP64 534 #define ISC_ZONE_GET(z, f) atomic_load_relaxed(&(z)->f) 535 #define ISC_ZONE_SET(z, f, o) atomic_fetch_or(&(z)->f, (o)) 536 #define ISC_ZONE_CLR(z, f, o) atomic_fetch_and(&(z)->f, ~(o)) 537 #else 538 #define ISC_ZONE_GET(z, f) \ 539 ({ \ 540 isc_mutex_lock(&(z)->atomic_lock); \ 541 uint64_t x = (z)->f; \ 542 isc_mutex_unlock(&(z)->atomic_lock); \ 543 x; \ 544 }) 545 #define ISC_ZONE_SET(z, f, o) \ 546 ({ \ 547 isc_mutex_lock(&(z)->atomic_lock); \ 548 uint64_t x = ((z)->f | (o)); \ 549 isc_mutex_unlock(&(z)->atomic_lock); \ 550 x; \ 551 }) 552 #define ISC_ZONE_CLR(z, f, o) \ 553 ({ \ 554 isc_mutex_lock(&(z)->atomic_lock); \ 555 uint64_t x = ((z)->f & ~(o)); \ 556 isc_mutex_unlock(&(z)->atomic_lock); \ 557 x; \ 558 }) 559 #endif 560 #define ISC_ZONE_TEST(z, f, o) ((ISC_ZONE_GET(z, f) & (o)) != 0) 561 562 #define DNS_ZONE_FLAG(z, f) ISC_ZONE_TEST(z, flags, f) 563 #define DNS_ZONE_SETFLAG(z, f) ISC_ZONE_SET(z, flags, f) 564 #define DNS_ZONE_CLRFLAG(z, f) ISC_ZONE_CLR(z, flags, f) 565 typedef enum { 566 DNS_ZONEFLG_REFRESH = 0x00000001U, /*%< refresh check in progress */ 567 DNS_ZONEFLG_NEEDDUMP = 0x00000002U, /*%< zone need consolidation */ 568 DNS_ZONEFLG_USEVC = 0x00000004U, /*%< use tcp for refresh query */ 569 DNS_ZONEFLG_DUMPING = 0x00000008U, /*%< a dump is in progress */ 570 DNS_ZONEFLG_HASINCLUDE = 0x00000010U, /*%< $INCLUDE in zone file */ 571 DNS_ZONEFLG_LOADED = 0x00000020U, /*%< database has loaded */ 572 DNS_ZONEFLG_EXITING = 0x00000040U, /*%< zone is being destroyed */ 573 DNS_ZONEFLG_EXPIRED = 0x00000080U, /*%< zone has expired */ 574 DNS_ZONEFLG_NEEDREFRESH = 0x00000100U, /*%< refresh check needed */ 575 DNS_ZONEFLG_UPTODATE = 0x00000200U, /*%< zone contents are 576 * up-to-date */ 577 DNS_ZONEFLG_NEEDNOTIFY = 0x00000400U, /*%< need to send out notify 578 * messages */ 579 DNS_ZONEFLG_FIXJOURNAL = 0x00000800U, /*%< journal file had 580 * recoverable error, 581 * needs rewriting */ 582 DNS_ZONEFLG_NOPRIMARIES = 0x00001000U, /*%< an attempt to refresh a 583 * zone with no primaries 584 * occurred */ 585 DNS_ZONEFLG_LOADING = 0x00002000U, /*%< load from disk in progress*/ 586 DNS_ZONEFLG_HAVETIMERS = 0x00004000U, /*%< timer values have been set 587 * from SOA (if not set, we 588 * are still using 589 * default timer values) */ 590 DNS_ZONEFLG_FORCEXFER = 0x00008000U, /*%< Force a zone xfer */ 591 DNS_ZONEFLG_NOREFRESH = 0x00010000U, 592 DNS_ZONEFLG_DIALNOTIFY = 0x00020000U, 593 DNS_ZONEFLG_DIALREFRESH = 0x00040000U, 594 DNS_ZONEFLG_SHUTDOWN = 0x00080000U, 595 DNS_ZONEFLG_NOIXFR = 0x00100000U, /*%< IXFR failed, force AXFR */ 596 DNS_ZONEFLG_FLUSH = 0x00200000U, 597 DNS_ZONEFLG_NOEDNS = 0x00400000U, 598 DNS_ZONEFLG_USEALTXFRSRC = 0x00800000U, /*%< Obsoleted. */ 599 DNS_ZONEFLG_SOABEFOREAXFR = 0x01000000U, 600 DNS_ZONEFLG_NEEDCOMPACT = 0x02000000U, 601 DNS_ZONEFLG_REFRESHING = 0x04000000U, /*%< Refreshing keydata */ 602 DNS_ZONEFLG_THAW = 0x08000000U, 603 DNS_ZONEFLG_LOADPENDING = 0x10000000U, /*%< Loading scheduled */ 604 DNS_ZONEFLG_NODELAY = 0x20000000U, 605 DNS_ZONEFLG_SENDSECURE = 0x40000000U, 606 DNS_ZONEFLG_NEEDSTARTUPNOTIFY = 0x80000000U, /*%< need to send out 607 * notify due to the zone 608 * just being loaded for 609 * the first time. */ 610 DNS_ZONEFLG_FIRSTREFRESH = 0x100000000U, /*%< First refresh pending */ 611 DNS_ZONEFLG___MAX = UINT64_MAX, /* trick to make the ENUM 64-bit wide */ 612 } dns_zoneflg_t; 613 614 615 #define DNS_ZONE_OPTION(z, o) ISC_ZONE_TEST(z, options, o) 616 #define DNS_ZONE_SETOPTION(z, o) ISC_ZONE_SET(z, options, o) 617 #define DNS_ZONE_CLROPTION(z, o) ISC_ZONE_CLR(z, options, o) 618 #define DNS_ZONEKEY_OPTION(z, o) ISC_ZONE_TEST(z, keyopts, o) 619 #define DNS_ZONEKEY_SETOPTION(z, o) ISC_ZONE_SET(z, keyopts, o) 620 #define DNS_ZONEKEY_CLROPTION(z, o) ISC_ZONE_CLR(z, keyopts, o) 621 622 623 /* Flags for zone_load() */ 624 typedef enum { 625 DNS_ZONELOADFLAG_NOSTAT = 0x00000001U, /* Do not stat() master files */ 626 DNS_ZONELOADFLAG_THAW = 0x00000002U, /* Thaw the zone on successful 627 * load. */ 628 } dns_zoneloadflag_t; 629 630 #define UNREACH_CACHE_SIZE 10U 631 #define UNREACH_HOLD_TIME 600 /* 10 minutes */ 632 633 #define CHECK(op) \ 634 do { \ 635 result = (op); \ 636 if (result != ISC_R_SUCCESS) \ 637 goto failure; \ 638 } while (0) 639 640 struct dns_unreachable { 641 isc_sockaddr_t remote; 642 isc_sockaddr_t local; 643 atomic_uint_fast32_t expire; 644 atomic_uint_fast32_t last; 645 uint32_t count; 646 }; 647 648 struct dns_zonemgr { 649 unsigned int magic; 650 isc_mem_t *mctx; 651 isc_refcount_t refs; 652 isc_loopmgr_t *loopmgr; 653 isc_nm_t *netmgr; 654 uint32_t workers; 655 isc_mem_t **mctxpool; 656 isc_ratelimiter_t *checkdsrl; 657 isc_ratelimiter_t *notifyrl; 658 isc_ratelimiter_t *refreshrl; 659 isc_ratelimiter_t *startupnotifyrl; 660 isc_ratelimiter_t *startuprefreshrl; 661 isc_rwlock_t rwlock; 662 isc_rwlock_t urlock; 663 664 /* Locked by rwlock. */ 665 dns_zonelist_t zones; 666 dns_zonelist_t waiting_for_xfrin; 667 dns_zonelist_t xfrin_in_progress; 668 669 /* Configuration data. */ 670 uint32_t transfersin; 671 uint32_t transfersperns; 672 unsigned int checkdsrate; 673 unsigned int notifyrate; 674 unsigned int startupnotifyrate; 675 unsigned int serialqueryrate; 676 unsigned int startupserialqueryrate; 677 678 /* Locked by urlock. */ 679 /* LRU cache */ 680 struct dns_unreachable unreachable[UNREACH_CACHE_SIZE]; 681 682 dns_keymgmt_t *keymgmt; 683 684 isc_tlsctx_cache_t *tlsctx_cache; 685 isc_rwlock_t tlsctx_cache_rwlock; 686 }; 687 688 /*% 689 * Hold notify state. 690 */ 691 struct dns_notify { 692 unsigned int magic; 693 unsigned int flags; 694 isc_mem_t *mctx; 695 dns_zone_t *zone; 696 dns_adbfind_t *find; 697 dns_request_t *request; 698 dns_name_t ns; 699 isc_sockaddr_t src; 700 isc_sockaddr_t dst; 701 dns_tsigkey_t *key; 702 dns_transport_t *transport; 703 ISC_LINK(dns_notify_t) link; 704 isc_rlevent_t *rlevent; 705 }; 706 707 typedef enum dns_notify_flags { 708 DNS_NOTIFY_NOSOA = 1 << 0, 709 DNS_NOTIFY_STARTUP = 1 << 1, 710 DNS_NOTIFY_TCP = 1 << 2, 711 } dns_notify_flags_t; 712 713 /*% 714 * Hold checkds state. 715 */ 716 struct dns_checkds { 717 unsigned int magic; 718 dns_notify_flags_t flags; 719 isc_mem_t *mctx; 720 dns_zone_t *zone; 721 dns_adbfind_t *find; 722 dns_request_t *request; 723 dns_name_t ns; 724 isc_sockaddr_t src; 725 isc_sockaddr_t dst; 726 dns_tsigkey_t *key; 727 dns_transport_t *transport; 728 ISC_LINK(dns_checkds_t) link; 729 isc_rlevent_t *rlevent; 730 }; 731 732 /*% 733 * dns_stub holds state while performing a 'stub' transfer. 734 * 'db' is the zone's 'db' or a new one if this is the initial 735 * transfer. 736 */ 737 738 struct dns_stub { 739 unsigned int magic; 740 isc_mem_t *mctx; 741 dns_zone_t *zone; 742 dns_db_t *db; 743 dns_dbversion_t *version; 744 atomic_uint_fast32_t pending_requests; 745 }; 746 747 /*% 748 * Hold load state. 749 */ 750 struct dns_load { 751 dns_zone_t *zone; 752 dns_db_t *db; 753 isc_time_t loadtime; 754 dns_rdatacallbacks_t callbacks; 755 }; 756 757 /*% 758 * Hold forward state. 759 */ 760 struct dns_forward { 761 unsigned int magic; 762 isc_mem_t *mctx; 763 dns_zone_t *zone; 764 isc_buffer_t *msgbuf; 765 dns_request_t *request; 766 uint32_t which; 767 isc_sockaddr_t addr; 768 dns_transport_t *transport; 769 dns_updatecallback_t callback; 770 void *callback_arg; 771 unsigned int options; 772 ISC_LINK(dns_forward_t) link; 773 }; 774 775 /*% 776 * Hold state for when we are signing a zone with a new 777 * DNSKEY as result of an update. 778 */ 779 struct dns_signing { 780 unsigned int magic; 781 dns_db_t *db; 782 dns_dbiterator_t *dbiterator; 783 dns_secalg_t algorithm; 784 uint16_t keyid; 785 bool deleteit; 786 bool done; 787 ISC_LINK(dns_signing_t) link; 788 }; 789 790 struct dns_nsec3chain { 791 unsigned int magic; 792 dns_db_t *db; 793 dns_dbiterator_t *dbiterator; 794 dns_rdata_nsec3param_t nsec3param; 795 unsigned char salt[255]; 796 bool done; 797 bool seen_nsec; 798 bool delete_nsec; 799 bool save_delete_nsec; 800 ISC_LINK(dns_nsec3chain_t) link; 801 }; 802 803 /*%< 804 * 'dbiterator' contains a iterator for the database. If we are creating 805 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are 806 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be 807 * iterated. 808 * 809 * 'nsec3param' contains the parameters of the NSEC3 chain being created 810 * or removed. 811 * 812 * 'salt' is buffer space and is referenced via 'nsec3param.salt'. 813 * 814 * 'seen_nsec' will be set to true if, while iterating the zone to create a 815 * NSEC3 chain, a NSEC record is seen. 816 * 817 * 'delete_nsec' will be set to true if, at the completion of the creation 818 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we 819 * are in the process of deleting the NSEC chain. 820 * 821 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec' 822 * so it can be recovered in the event of a error. 823 */ 824 825 struct dns_keyfetch { 826 isc_mem_t *mctx; 827 dns_fixedname_t name; 828 dns_rdataset_t keydataset; 829 dns_rdataset_t dnskeyset; 830 dns_rdataset_t dnskeysigset; 831 dns_zone_t *zone; 832 dns_db_t *db; 833 dns_fetch_t *fetch; 834 }; 835 836 struct dns_nsfetch { 837 isc_mem_t *mctx; 838 dns_fixedname_t name; 839 dns_name_t pname; 840 dns_rdataset_t nsrrset; 841 dns_rdataset_t nssigset; 842 dns_zone_t *zone; 843 dns_fetch_t *fetch; 844 }; 845 846 /*% 847 * Hold state for an asynchronous load 848 */ 849 struct dns_asyncload { 850 dns_zone_t *zone; 851 unsigned int flags; 852 dns_zt_callback_t *loaded; 853 void *loaded_arg; 854 }; 855 856 /*% 857 * Reference to an include file encountered during loading 858 */ 859 struct dns_include { 860 char *name; 861 isc_time_t filetime; 862 ISC_LINK(dns_include_t) link; 863 }; 864 865 /* 866 * These can be overridden by the -T mkeytimers option on the command 867 * line, so that we can test with shorter periods than specified in 868 * RFC 5011. 869 */ 870 #define HOUR 3600 871 #define DAY (24 * HOUR) 872 #define MONTH (30 * DAY) 873 unsigned int dns_zone_mkey_hour = HOUR; 874 unsigned int dns_zone_mkey_day = DAY; 875 unsigned int dns_zone_mkey_month = MONTH; 876 877 #define SEND_BUFFER_SIZE 2048 878 879 static void 880 zone_timer_set(dns_zone_t *zone, isc_time_t *next, isc_time_t *now); 881 882 typedef struct zone_settimer { 883 dns_zone_t *zone; 884 isc_time_t now; 885 } zone_settimer_t; 886 887 static void 888 zone_settimer(dns_zone_t *, isc_time_t *); 889 static void 890 cancel_refresh(dns_zone_t *); 891 static void 892 zone_debuglogc(dns_zone_t *zone, isc_logcategory_t *category, const char *me, 893 int debuglevel, const char *fmt, ...); 894 static void 895 zone_debuglog(dns_zone_t *zone, const char *, int debuglevel, const char *msg, 896 ...) ISC_FORMAT_PRINTF(4, 5); 897 static void 898 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) 899 ISC_FORMAT_PRINTF(3, 4); 900 static void 901 dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...) 902 ISC_FORMAT_PRINTF(3, 4); 903 static void 904 queue_xfrin(dns_zone_t *zone); 905 static isc_result_t 906 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 907 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, 908 dns_rdata_t *rdata); 909 static void 910 zone_unload(dns_zone_t *zone); 911 static void 912 zone_expire(dns_zone_t *zone); 913 static void 914 zone_refresh(dns_zone_t *zone); 915 static void 916 zone_iattach(dns_zone_t *source, dns_zone_t **target); 917 static void 918 zone_idetach(dns_zone_t **zonep); 919 static isc_result_t 920 zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump); 921 static void 922 zone_attachdb(dns_zone_t *zone, dns_db_t *db); 923 static void 924 zone_detachdb(dns_zone_t *zone); 925 static void 926 zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs); 927 static void 928 zone_catz_disable(dns_zone_t *zone); 929 static isc_result_t 930 default_journal(dns_zone_t *zone); 931 static void 932 zone_xfrdone(dns_zone_t *zone, uint32_t *expireopt, isc_result_t result); 933 static isc_result_t 934 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, 935 isc_result_t result); 936 static void 937 zone_needdump(dns_zone_t *zone, unsigned int delay); 938 static void 939 zone_shutdown(void *arg); 940 static void 941 zone_loaddone(void *arg, isc_result_t result); 942 static isc_result_t 943 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime); 944 static void 945 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length); 946 static void 947 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length); 948 static void 949 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length); 950 static void 951 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length); 952 static isc_result_t 953 zone_send_secureserial(dns_zone_t *zone, uint32_t serial); 954 static void 955 refresh_callback(void *arg); 956 static void 957 stub_callback(void *arg); 958 static void 959 queue_soa_query(dns_zone_t *zone); 960 static void 961 soa_query(void *arg); 962 static void 963 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub); 964 static int 965 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type); 966 static void 967 checkds_cancel(dns_zone_t *zone); 968 static void 969 checkds_find_address(dns_checkds_t *checkds); 970 static void 971 checkds_send(dns_zone_t *zone); 972 static void 973 checkds_createmessage(dns_zone_t *zone, dns_message_t **messagep); 974 static void 975 checkds_done(void *arg); 976 static void 977 checkds_send_tons(dns_checkds_t *checkds); 978 static void 979 checkds_send_toaddr(void *arg); 980 static void 981 nsfetch_levelup(dns_nsfetch_t *nsfetch); 982 static void 983 notify_cancel(dns_zone_t *zone); 984 static void 985 notify_find_address(dns_notify_t *notify); 986 static void 987 notify_send(dns_notify_t *notify); 988 static isc_result_t 989 notify_createmessage(dns_zone_t *zone, unsigned int flags, 990 dns_message_t **messagep); 991 static void 992 notify_done(void *arg); 993 static void 994 notify_send_toaddr(void *arg); 995 static isc_result_t 996 zone_dump(dns_zone_t *, bool); 997 static void 998 got_transfer_quota(void *arg); 999 static isc_result_t 1000 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone); 1001 static void 1002 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi); 1003 static void 1004 zonemgr_free(dns_zonemgr_t *zmgr); 1005 static void 1006 rss_post(void *arg); 1007 1008 static isc_result_t 1009 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 1010 unsigned int *soacount, uint32_t *soattl, uint32_t *serial, 1011 uint32_t *refresh, uint32_t *retry, uint32_t *expire, 1012 uint32_t *minimum, unsigned int *errors); 1013 1014 static void 1015 zone_freedbargs(dns_zone_t *zone); 1016 static void 1017 forward_callback(void *arg); 1018 static void 1019 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat); 1020 static void 1021 zone_maintenance(dns_zone_t *zone); 1022 static void 1023 zone_notify(dns_zone_t *zone, isc_time_t *now); 1024 static void 1025 dump_done(void *arg, isc_result_t result); 1026 static isc_result_t 1027 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid, 1028 bool deleteit); 1029 static isc_result_t 1030 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 1031 dns_name_t *name, dns_diff_t *diff); 1032 static void 1033 zone_rekey(dns_zone_t *zone); 1034 static isc_result_t 1035 zone_send_securedb(dns_zone_t *zone, dns_db_t *db); 1036 static dns_ttl_t 1037 zone_nsecttl(dns_zone_t *zone); 1038 static void 1039 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value); 1040 static void 1041 zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial); 1042 static isc_result_t 1043 zone_journal_rollforward(dns_zone_t *zone, dns_db_t *db, bool *needdump, 1044 bool *fixjournal); 1045 static void 1046 setnsec3param(void *arg); 1047 1048 static void 1049 zmgr_tlsctx_attach(dns_zonemgr_t *zmgr, isc_tlsctx_cache_t **ptlsctx_cache); 1050 /*%< 1051 * Attach to TLS client context cache used for zone transfers via 1052 * encrypted transports (e.g. XoT). 1053 * 1054 * The obtained reference needs to be detached by a call to 1055 * 'isc_tlsctx_cache_detach()' when not needed anymore. 1056 * 1057 * Requires: 1058 *\li 'zmgr' is a valid zone manager. 1059 *\li 'ptlsctx_cache' is not 'NULL' and points to 'NULL'. 1060 */ 1061 1062 #define ENTER zone_debuglog(zone, __func__, 1, "enter") 1063 1064 static const unsigned int dbargc_default = 1; 1065 static const char *dbargv_default[] = { ZONEDB_DEFAULT }; 1066 1067 #define DNS_ZONE_JITTER_ADD(a, b, c) \ 1068 do { \ 1069 isc_interval_t _i; \ 1070 uint32_t _j; \ 1071 _j = (b) - isc_random_uniform((b) / 4); \ 1072 isc_interval_set(&_i, _j, 0); \ 1073 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 1074 dns_zone_log(zone, ISC_LOG_WARNING, \ 1075 "epoch approaching: upgrade required: " \ 1076 "now + %s failed", \ 1077 #b); \ 1078 isc_interval_set(&_i, _j / 2, 0); \ 1079 (void)isc_time_add((a), &_i, (c)); \ 1080 } \ 1081 } while (0) 1082 1083 #define DNS_ZONE_TIME_ADD(a, b, c) \ 1084 do { \ 1085 isc_interval_t _i; \ 1086 isc_interval_set(&_i, (b), 0); \ 1087 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 1088 dns_zone_log(zone, ISC_LOG_WARNING, \ 1089 "epoch approaching: upgrade required: " \ 1090 "now + %s failed", \ 1091 #b); \ 1092 isc_interval_set(&_i, (b) / 2, 0); \ 1093 (void)isc_time_add((a), &_i, (c)); \ 1094 } \ 1095 } while (0) 1096 1097 typedef struct nsec3param nsec3param_t; 1098 struct nsec3param { 1099 dns_rdata_nsec3param_t rdata; 1100 unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1]; 1101 unsigned int length; 1102 bool nsec; 1103 bool replace; 1104 bool resalt; 1105 bool lookup; 1106 ISC_LINK(nsec3param_t) link; 1107 }; 1108 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t; 1109 1110 struct np3 { 1111 dns_zone_t *zone; 1112 nsec3param_t params; 1113 ISC_LINK(struct np3) link; 1114 }; 1115 1116 struct setserial { 1117 dns_zone_t *zone; 1118 uint32_t serial; 1119 }; 1120 1121 struct stub_cb_args { 1122 dns_stub_t *stub; 1123 dns_tsigkey_t *tsig_key; 1124 uint16_t udpsize; 1125 int timeout; 1126 bool reqnsid; 1127 }; 1128 1129 struct stub_glue_request { 1130 dns_request_t *request; 1131 dns_name_t name; 1132 struct stub_cb_args *args; 1133 bool ipv4; 1134 }; 1135 1136 /*% 1137 * Increment resolver-related statistics counters. Zone must be locked. 1138 */ 1139 static void 1140 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { 1141 if (zone->stats != NULL) { 1142 isc_stats_increment(zone->stats, counter); 1143 } 1144 } 1145 1146 /*** 1147 *** Public functions. 1148 ***/ 1149 1150 void 1151 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx, unsigned int tid) { 1152 isc_time_t now; 1153 dns_zone_t *zone = NULL; 1154 1155 REQUIRE(zonep != NULL && *zonep == NULL); 1156 REQUIRE(mctx != NULL); 1157 1158 now = isc_time_now(); 1159 zone = isc_mem_get(mctx, sizeof(*zone)); 1160 *zone = (dns_zone_t){ 1161 .masterformat = dns_masterformat_none, 1162 .journalsize = -1, 1163 .rdclass = dns_rdataclass_none, 1164 .type = dns_zone_none, 1165 .refresh = DNS_ZONE_DEFAULTREFRESH, 1166 .retry = DNS_ZONE_DEFAULTRETRY, 1167 .maxrefresh = DNS_ZONE_MAXREFRESH, 1168 .minrefresh = DNS_ZONE_MINREFRESH, 1169 .maxretry = DNS_ZONE_MAXRETRY, 1170 .minretry = DNS_ZONE_MINRETRY, 1171 .checkdstype = dns_checkdstype_yes, 1172 .notifytype = dns_notifytype_yes, 1173 .zero_no_soa_ttl = true, 1174 .check_names = dns_severity_ignore, 1175 .idlein = DNS_DEFAULT_IDLEIN, 1176 .idleout = DNS_DEFAULT_IDLEOUT, 1177 .maxxfrin = MAX_XFER_TIME, 1178 .maxxfrout = MAX_XFER_TIME, 1179 .sigvalidityinterval = 30 * 24 * 3600, 1180 .sigresigninginterval = 7 * 24 * 3600, 1181 .statlevel = dns_zonestat_none, 1182 .notifydelay = 5, 1183 .signatures = 10, 1184 .nodes = 100, 1185 .privatetype = (dns_rdatatype_t)0xffffU, 1186 .rpz_num = DNS_RPZ_INVALID_NUM, 1187 .requestixfr = true, 1188 .ixfr_ratio = 100, 1189 .requestexpire = true, 1190 .updatemethod = dns_updatemethod_increment, 1191 .tid = tid, 1192 .notifytime = now, 1193 .newincludes = ISC_LIST_INITIALIZER, 1194 .notifies = ISC_LIST_INITIALIZER, 1195 .checkds_requests = ISC_LIST_INITIALIZER, 1196 .signing = ISC_LIST_INITIALIZER, 1197 .nsec3chain = ISC_LIST_INITIALIZER, 1198 .setnsec3param_queue = ISC_LIST_INITIALIZER, 1199 .forwards = ISC_LIST_INITIALIZER, 1200 .link = ISC_LINK_INITIALIZER, 1201 .statelink = ISC_LINK_INITIALIZER, 1202 }; 1203 dns_remote_t r = { 1204 .magic = DNS_REMOTE_MAGIC, 1205 }; 1206 1207 isc_mem_attach(mctx, &zone->mctx); 1208 isc_mutex_init(&zone->lock); 1209 #ifndef _LP64 1210 isc_mutex_init(&zone->atomic_lock); 1211 #endif 1212 ZONEDB_INITLOCK(&zone->dblock); 1213 1214 isc_refcount_init(&zone->references, 1); 1215 isc_refcount_init(&zone->irefs, 0); 1216 dns_name_init(&zone->origin, NULL); 1217 isc_sockaddr_any(&zone->notifysrc4); 1218 isc_sockaddr_any6(&zone->notifysrc6); 1219 isc_sockaddr_any(&zone->parentalsrc4); 1220 isc_sockaddr_any6(&zone->parentalsrc6); 1221 isc_sockaddr_any(&zone->xfrsource4); 1222 isc_sockaddr_any6(&zone->xfrsource6); 1223 1224 zone->primaries = r; 1225 zone->parentals = r; 1226 zone->notify = r; 1227 zone->defaultkasp = NULL; 1228 ISC_LIST_INIT(zone->keyring); 1229 1230 isc_stats_create(mctx, &zone->gluecachestats, 1231 dns_gluecachestatscounter_max); 1232 1233 zone->magic = ZONE_MAGIC; 1234 1235 /* Must be after magic is set. */ 1236 dns_zone_setdbtype(zone, dbargc_default, dbargv_default); 1237 1238 *zonep = zone; 1239 } 1240 1241 static void 1242 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) { 1243 dns_dnsseckey_t *key; 1244 while (!ISC_LIST_EMPTY(*list)) { 1245 key = ISC_LIST_HEAD(*list); 1246 ISC_LIST_UNLINK(*list, key, link); 1247 dns_dnsseckey_destroy(mctx, &key); 1248 } 1249 } 1250 1251 /* 1252 * Free a zone. Because we require that there be no more 1253 * outstanding events or references, no locking is necessary. 1254 */ 1255 static void 1256 zone_free(dns_zone_t *zone) { 1257 dns_signing_t *signing = NULL; 1258 dns_nsec3chain_t *nsec3chain = NULL; 1259 dns_include_t *include = NULL; 1260 1261 REQUIRE(DNS_ZONE_VALID(zone)); 1262 REQUIRE(!LOCKED_ZONE(zone)); 1263 REQUIRE(zone->timer == NULL); 1264 REQUIRE(zone->zmgr == NULL); 1265 1266 isc_refcount_destroy(&zone->references); 1267 isc_refcount_destroy(&zone->irefs); 1268 1269 /* 1270 * Managed objects. Order is important. 1271 */ 1272 if (zone->request != NULL) { 1273 dns_request_destroy(&zone->request); /* XXXMPA */ 1274 } 1275 INSIST(zone->statelist == NULL); 1276 INSIST(zone->view == NULL); 1277 INSIST(zone->prev_view == NULL); 1278 1279 /* Unmanaged objects */ 1280 for (struct np3 *npe = ISC_LIST_HEAD(zone->setnsec3param_queue); 1281 npe != NULL; npe = ISC_LIST_HEAD(zone->setnsec3param_queue)) 1282 { 1283 ISC_LIST_UNLINK(zone->setnsec3param_queue, npe, link); 1284 isc_mem_put(zone->mctx, npe, sizeof(*npe)); 1285 } 1286 1287 for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; 1288 signing = ISC_LIST_HEAD(zone->signing)) 1289 { 1290 ISC_LIST_UNLINK(zone->signing, signing, link); 1291 dns_db_detach(&signing->db); 1292 dns_dbiterator_destroy(&signing->dbiterator); 1293 isc_mem_put(zone->mctx, signing, sizeof *signing); 1294 } 1295 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL; 1296 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) 1297 { 1298 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 1299 dns_db_detach(&nsec3chain->db); 1300 dns_dbiterator_destroy(&nsec3chain->dbiterator); 1301 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 1302 } 1303 for (include = ISC_LIST_HEAD(zone->includes); include != NULL; 1304 include = ISC_LIST_HEAD(zone->includes)) 1305 { 1306 ISC_LIST_UNLINK(zone->includes, include, link); 1307 isc_mem_free(zone->mctx, include->name); 1308 isc_mem_put(zone->mctx, include, sizeof *include); 1309 } 1310 for (include = ISC_LIST_HEAD(zone->newincludes); include != NULL; 1311 include = ISC_LIST_HEAD(zone->newincludes)) 1312 { 1313 ISC_LIST_UNLINK(zone->newincludes, include, link); 1314 isc_mem_free(zone->mctx, include->name); 1315 isc_mem_put(zone->mctx, include, sizeof *include); 1316 } 1317 if (zone->masterfile != NULL) { 1318 isc_mem_free(zone->mctx, zone->masterfile); 1319 } 1320 zone->masterfile = NULL; 1321 if (zone->keydirectory != NULL) { 1322 isc_mem_free(zone->mctx, zone->keydirectory); 1323 } 1324 zone->keydirectory = NULL; 1325 if (zone->kasp != NULL) { 1326 dns_kasp_detach(&zone->kasp); 1327 } 1328 if (zone->defaultkasp != NULL) { 1329 dns_kasp_detach(&zone->defaultkasp); 1330 } 1331 if (!ISC_LIST_EMPTY(zone->keyring)) { 1332 clear_keylist(&zone->keyring, zone->mctx); 1333 } 1334 if (!ISC_LIST_EMPTY(zone->checkds_ok)) { 1335 clear_keylist(&zone->checkds_ok, zone->mctx); 1336 } 1337 if (zone->skr != NULL) { 1338 zone->skrbundle = NULL; 1339 dns_skr_detach(&zone->skr); 1340 } 1341 1342 zone->journalsize = -1; 1343 if (zone->journal != NULL) { 1344 isc_mem_free(zone->mctx, zone->journal); 1345 } 1346 zone->journal = NULL; 1347 if (zone->stats != NULL) { 1348 isc_stats_detach(&zone->stats); 1349 } 1350 if (zone->requeststats != NULL) { 1351 isc_stats_detach(&zone->requeststats); 1352 } 1353 if (zone->rcvquerystats != NULL) { 1354 dns_stats_detach(&zone->rcvquerystats); 1355 } 1356 if (zone->dnssecsignstats != NULL) { 1357 dns_stats_detach(&zone->dnssecsignstats); 1358 } 1359 if (zone->db != NULL) { 1360 zone_detachdb(zone); 1361 } 1362 if (zone->rpzs != NULL) { 1363 REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones); 1364 dns_rpz_zones_detach(&zone->rpzs); 1365 zone->rpz_num = DNS_RPZ_INVALID_NUM; 1366 } 1367 if (zone->catzs != NULL) { 1368 dns_catz_zones_detach(&zone->catzs); 1369 } 1370 zone_freedbargs(zone); 1371 1372 dns_zone_setparentals(zone, NULL, NULL, NULL, NULL, 0); 1373 dns_zone_setprimaries(zone, NULL, NULL, NULL, NULL, 0); 1374 dns_zone_setalsonotify(zone, NULL, NULL, NULL, NULL, 0); 1375 1376 zone->check_names = dns_severity_ignore; 1377 if (zone->update_acl != NULL) { 1378 dns_acl_detach(&zone->update_acl); 1379 } 1380 if (zone->forward_acl != NULL) { 1381 dns_acl_detach(&zone->forward_acl); 1382 } 1383 if (zone->notify_acl != NULL) { 1384 dns_acl_detach(&zone->notify_acl); 1385 } 1386 if (zone->query_acl != NULL) { 1387 dns_acl_detach(&zone->query_acl); 1388 } 1389 if (zone->queryon_acl != NULL) { 1390 dns_acl_detach(&zone->queryon_acl); 1391 } 1392 if (zone->xfr_acl != NULL) { 1393 dns_acl_detach(&zone->xfr_acl); 1394 } 1395 if (dns_name_dynamic(&zone->origin)) { 1396 dns_name_free(&zone->origin, zone->mctx); 1397 } 1398 if (zone->strnamerd != NULL) { 1399 isc_mem_free(zone->mctx, zone->strnamerd); 1400 } 1401 if (zone->strname != NULL) { 1402 isc_mem_free(zone->mctx, zone->strname); 1403 } 1404 if (zone->strrdclass != NULL) { 1405 isc_mem_free(zone->mctx, zone->strrdclass); 1406 } 1407 if (zone->strviewname != NULL) { 1408 isc_mem_free(zone->mctx, zone->strviewname); 1409 } 1410 if (zone->ssutable != NULL) { 1411 dns_ssutable_detach(&zone->ssutable); 1412 } 1413 if (zone->gluecachestats != NULL) { 1414 isc_stats_detach(&zone->gluecachestats); 1415 } 1416 1417 /* last stuff */ 1418 ZONEDB_DESTROYLOCK(&zone->dblock); 1419 isc_mutex_destroy(&zone->lock); 1420 #ifndef _LP64 1421 isc_mutex_destroy(&zone->atomic_lock); 1422 #endif 1423 zone->magic = 0; 1424 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone)); 1425 } 1426 1427 /* 1428 * Returns true iff this the signed side of an inline-signing zone. 1429 * Caller should hold zone lock. 1430 */ 1431 static bool 1432 inline_secure(dns_zone_t *zone) { 1433 REQUIRE(DNS_ZONE_VALID(zone)); 1434 if (zone->raw != NULL) { 1435 return true; 1436 } 1437 return false; 1438 } 1439 1440 /* 1441 * Returns true iff this the unsigned side of an inline-signing zone 1442 * Caller should hold zone lock. 1443 */ 1444 static bool 1445 inline_raw(dns_zone_t *zone) { 1446 REQUIRE(DNS_ZONE_VALID(zone)); 1447 if (zone->secure != NULL) { 1448 return true; 1449 } 1450 return false; 1451 } 1452 1453 /* 1454 * Single shot. 1455 */ 1456 void 1457 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) { 1458 char namebuf[1024]; 1459 1460 REQUIRE(DNS_ZONE_VALID(zone)); 1461 REQUIRE(rdclass != dns_rdataclass_none); 1462 1463 /* 1464 * Test and set. 1465 */ 1466 LOCK_ZONE(zone); 1467 INSIST(zone != zone->raw); 1468 REQUIRE(zone->rdclass == dns_rdataclass_none || 1469 zone->rdclass == rdclass); 1470 zone->rdclass = rdclass; 1471 1472 if (zone->strnamerd != NULL) { 1473 isc_mem_free(zone->mctx, zone->strnamerd); 1474 } 1475 if (zone->strrdclass != NULL) { 1476 isc_mem_free(zone->mctx, zone->strrdclass); 1477 } 1478 1479 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1480 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1481 zone_rdclass_tostr(zone, namebuf, sizeof namebuf); 1482 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf); 1483 1484 if (inline_secure(zone)) { 1485 dns_zone_setclass(zone->raw, rdclass); 1486 } 1487 UNLOCK_ZONE(zone); 1488 } 1489 1490 dns_rdataclass_t 1491 dns_zone_getclass(dns_zone_t *zone) { 1492 REQUIRE(DNS_ZONE_VALID(zone)); 1493 1494 return zone->rdclass; 1495 } 1496 1497 void 1498 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { 1499 REQUIRE(DNS_ZONE_VALID(zone)); 1500 1501 LOCK_ZONE(zone); 1502 zone->notifytype = notifytype; 1503 UNLOCK_ZONE(zone); 1504 } 1505 1506 void 1507 dns_zone_setcheckdstype(dns_zone_t *zone, dns_checkdstype_t checkdstype) { 1508 REQUIRE(DNS_ZONE_VALID(zone)); 1509 1510 LOCK_ZONE(zone); 1511 zone->checkdstype = checkdstype; 1512 UNLOCK_ZONE(zone); 1513 } 1514 1515 isc_result_t 1516 dns_zone_getserial(dns_zone_t *zone, uint32_t *serialp) { 1517 isc_result_t result; 1518 unsigned int soacount; 1519 1520 REQUIRE(DNS_ZONE_VALID(zone)); 1521 REQUIRE(serialp != NULL); 1522 1523 LOCK_ZONE(zone); 1524 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1525 if (zone->db != NULL) { 1526 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, 1527 serialp, NULL, NULL, NULL, NULL, 1528 NULL); 1529 if (result == ISC_R_SUCCESS && soacount == 0) { 1530 result = ISC_R_FAILURE; 1531 } 1532 } else { 1533 result = DNS_R_NOTLOADED; 1534 } 1535 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1536 UNLOCK_ZONE(zone); 1537 1538 return result; 1539 } 1540 1541 /* 1542 * Single shot. 1543 */ 1544 void 1545 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) { 1546 char namebuf[1024]; 1547 1548 REQUIRE(DNS_ZONE_VALID(zone)); 1549 REQUIRE(type != dns_zone_none); 1550 1551 /* 1552 * Test and set. 1553 */ 1554 LOCK_ZONE(zone); 1555 REQUIRE(zone->type == dns_zone_none || zone->type == type); 1556 zone->type = type; 1557 1558 if (zone->strnamerd != NULL) { 1559 isc_mem_free(zone->mctx, zone->strnamerd); 1560 } 1561 1562 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1563 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1564 UNLOCK_ZONE(zone); 1565 } 1566 1567 static void 1568 zone_freedbargs(dns_zone_t *zone) { 1569 unsigned int i; 1570 1571 /* Free the old database argument list. */ 1572 if (zone->db_argv != NULL) { 1573 for (i = 0; i < zone->db_argc; i++) { 1574 isc_mem_free(zone->mctx, zone->db_argv[i]); 1575 } 1576 isc_mem_cput(zone->mctx, zone->db_argv, zone->db_argc, 1577 sizeof(*zone->db_argv)); 1578 } 1579 zone->db_argc = 0; 1580 zone->db_argv = NULL; 1581 } 1582 1583 isc_result_t 1584 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) { 1585 size_t size = 0; 1586 unsigned int i; 1587 isc_result_t result = ISC_R_SUCCESS; 1588 void *mem; 1589 char **tmp, *tmp2, *base; 1590 1591 REQUIRE(DNS_ZONE_VALID(zone)); 1592 REQUIRE(argv != NULL && *argv == NULL); 1593 1594 LOCK_ZONE(zone); 1595 size = ISC_CHECKED_MUL((zone->db_argc + 1), sizeof(char *)); 1596 for (i = 0; i < zone->db_argc; i++) { 1597 size += strlen(zone->db_argv[i]) + 1; 1598 } 1599 mem = isc_mem_allocate(mctx, size); 1600 { 1601 tmp = mem; 1602 tmp2 = mem; 1603 base = mem; 1604 tmp2 += ISC_CHECKED_MUL((zone->db_argc + 1), sizeof(char *)); 1605 for (i = 0; i < zone->db_argc; i++) { 1606 *tmp++ = tmp2; 1607 strlcpy(tmp2, zone->db_argv[i], size - (tmp2 - base)); 1608 tmp2 += strlen(tmp2) + 1; 1609 } 1610 *tmp = NULL; 1611 } 1612 UNLOCK_ZONE(zone); 1613 *argv = mem; 1614 return result; 1615 } 1616 1617 void 1618 dns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc, 1619 const char *const *dbargv) { 1620 char **argv = NULL; 1621 unsigned int i; 1622 1623 REQUIRE(DNS_ZONE_VALID(zone)); 1624 REQUIRE(dbargc >= 1); 1625 REQUIRE(dbargv != NULL); 1626 1627 LOCK_ZONE(zone); 1628 1629 /* Set up a new database argument list. */ 1630 argv = isc_mem_cget(zone->mctx, dbargc, sizeof(*argv)); 1631 for (i = 0; i < dbargc; i++) { 1632 argv[i] = NULL; 1633 } 1634 for (i = 0; i < dbargc; i++) { 1635 argv[i] = isc_mem_strdup(zone->mctx, dbargv[i]); 1636 } 1637 1638 /* Free the old list. */ 1639 zone_freedbargs(zone); 1640 1641 zone->db_argc = dbargc; 1642 zone->db_argv = argv; 1643 1644 UNLOCK_ZONE(zone); 1645 } 1646 1647 static void 1648 dns_zone_setview_helper(dns_zone_t *zone, dns_view_t *view) { 1649 char namebuf[1024]; 1650 1651 if (zone->prev_view == NULL && zone->view != NULL) { 1652 dns_view_weakattach(zone->view, &zone->prev_view); 1653 } 1654 1655 INSIST(zone != zone->raw); 1656 if (zone->view != NULL) { 1657 dns_view_sfd_del(zone->view, &zone->origin); 1658 dns_view_weakdetach(&zone->view); 1659 } 1660 dns_view_weakattach(view, &zone->view); 1661 dns_view_sfd_add(view, &zone->origin); 1662 1663 if (zone->strviewname != NULL) { 1664 isc_mem_free(zone->mctx, zone->strviewname); 1665 } 1666 if (zone->strnamerd != NULL) { 1667 isc_mem_free(zone->mctx, zone->strnamerd); 1668 } 1669 1670 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1671 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1672 zone_viewname_tostr(zone, namebuf, sizeof namebuf); 1673 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf); 1674 1675 if (inline_secure(zone)) { 1676 dns_zone_setview(zone->raw, view); 1677 } 1678 } 1679 1680 void 1681 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) { 1682 REQUIRE(DNS_ZONE_VALID(zone)); 1683 1684 LOCK_ZONE(zone); 1685 dns_zone_setview_helper(zone, view); 1686 UNLOCK_ZONE(zone); 1687 } 1688 1689 dns_view_t * 1690 dns_zone_getview(dns_zone_t *zone) { 1691 REQUIRE(DNS_ZONE_VALID(zone)); 1692 1693 return zone->view; 1694 } 1695 1696 void 1697 dns_zone_setviewcommit(dns_zone_t *zone) { 1698 REQUIRE(DNS_ZONE_VALID(zone)); 1699 1700 LOCK_ZONE(zone); 1701 if (zone->prev_view != NULL) { 1702 dns_view_weakdetach(&zone->prev_view); 1703 } 1704 if (inline_secure(zone)) { 1705 dns_zone_setviewcommit(zone->raw); 1706 } 1707 UNLOCK_ZONE(zone); 1708 } 1709 1710 void 1711 dns_zone_setviewrevert(dns_zone_t *zone) { 1712 REQUIRE(DNS_ZONE_VALID(zone)); 1713 1714 LOCK_ZONE(zone); 1715 if (zone->prev_view != NULL) { 1716 dns_zone_setview_helper(zone, zone->prev_view); 1717 dns_view_weakdetach(&zone->prev_view); 1718 } 1719 if (zone->catzs != NULL) { 1720 zone_catz_enable(zone, zone->catzs); 1721 } 1722 if (inline_secure(zone)) { 1723 dns_zone_setviewrevert(zone->raw); 1724 } 1725 UNLOCK_ZONE(zone); 1726 } 1727 1728 isc_result_t 1729 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) { 1730 isc_result_t result = ISC_R_SUCCESS; 1731 char namebuf[1024]; 1732 1733 REQUIRE(DNS_ZONE_VALID(zone)); 1734 REQUIRE(origin != NULL); 1735 1736 LOCK_ZONE(zone); 1737 INSIST(zone != zone->raw); 1738 if (dns_name_dynamic(&zone->origin)) { 1739 dns_name_free(&zone->origin, zone->mctx); 1740 dns_name_init(&zone->origin, NULL); 1741 } 1742 dns_name_dup(origin, zone->mctx, &zone->origin); 1743 1744 if (zone->strnamerd != NULL) { 1745 isc_mem_free(zone->mctx, zone->strnamerd); 1746 } 1747 if (zone->strname != NULL) { 1748 isc_mem_free(zone->mctx, zone->strname); 1749 } 1750 1751 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1752 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1753 zone_name_tostr(zone, namebuf, sizeof namebuf); 1754 zone->strname = isc_mem_strdup(zone->mctx, namebuf); 1755 1756 if (inline_secure(zone)) { 1757 result = dns_zone_setorigin(zone->raw, origin); 1758 } 1759 UNLOCK_ZONE(zone); 1760 return result; 1761 } 1762 1763 static isc_result_t 1764 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) { 1765 char *copy; 1766 1767 if (value != NULL) { 1768 copy = isc_mem_strdup(zone->mctx, value); 1769 } else { 1770 copy = NULL; 1771 } 1772 1773 if (*field != NULL) { 1774 isc_mem_free(zone->mctx, *field); 1775 } 1776 1777 *field = copy; 1778 return ISC_R_SUCCESS; 1779 } 1780 1781 isc_result_t 1782 dns_zone_setfile(dns_zone_t *zone, const char *file, dns_masterformat_t format, 1783 const dns_master_style_t *style) { 1784 isc_result_t result = ISC_R_SUCCESS; 1785 1786 REQUIRE(DNS_ZONE_VALID(zone)); 1787 REQUIRE(zone->stream == NULL); 1788 1789 LOCK_ZONE(zone); 1790 result = dns_zone_setstring(zone, &zone->masterfile, file); 1791 if (result == ISC_R_SUCCESS) { 1792 zone->masterformat = format; 1793 if (format == dns_masterformat_text) { 1794 zone->masterstyle = style; 1795 } 1796 result = default_journal(zone); 1797 } 1798 UNLOCK_ZONE(zone); 1799 1800 return result; 1801 } 1802 1803 const char * 1804 dns_zone_getfile(dns_zone_t *zone) { 1805 REQUIRE(DNS_ZONE_VALID(zone)); 1806 1807 return zone->masterfile; 1808 } 1809 1810 isc_result_t 1811 dns_zone_setstream(dns_zone_t *zone, const FILE *stream, 1812 dns_masterformat_t format, const dns_master_style_t *style) { 1813 isc_result_t result = ISC_R_SUCCESS; 1814 1815 REQUIRE(DNS_ZONE_VALID(zone)); 1816 REQUIRE(stream != NULL); 1817 REQUIRE(zone->masterfile == NULL); 1818 1819 LOCK_ZONE(zone); 1820 zone->stream = stream; 1821 zone->masterformat = format; 1822 if (format == dns_masterformat_text) { 1823 zone->masterstyle = style; 1824 } 1825 result = default_journal(zone); 1826 UNLOCK_ZONE(zone); 1827 1828 return result; 1829 } 1830 1831 dns_ttl_t 1832 dns_zone_getmaxttl(dns_zone_t *zone) { 1833 REQUIRE(DNS_ZONE_VALID(zone)); 1834 1835 return zone->maxttl; 1836 } 1837 1838 void 1839 dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) { 1840 REQUIRE(DNS_ZONE_VALID(zone)); 1841 1842 LOCK_ZONE(zone); 1843 if (maxttl != 0) { 1844 DNS_ZONE_SETOPTION(zone, DNS_ZONEOPT_CHECKTTL); 1845 } else { 1846 DNS_ZONE_CLROPTION(zone, DNS_ZONEOPT_CHECKTTL); 1847 } 1848 zone->maxttl = maxttl; 1849 UNLOCK_ZONE(zone); 1850 1851 return; 1852 } 1853 1854 static isc_result_t 1855 default_journal(dns_zone_t *zone) { 1856 isc_result_t result; 1857 char *journal; 1858 1859 REQUIRE(DNS_ZONE_VALID(zone)); 1860 REQUIRE(LOCKED_ZONE(zone)); 1861 1862 if (zone->masterfile != NULL) { 1863 /* Calculate string length including '\0'. */ 1864 int len = strlen(zone->masterfile) + sizeof(".jnl"); 1865 journal = isc_mem_allocate(zone->mctx, len); 1866 strlcpy(journal, zone->masterfile, len); 1867 strlcat(journal, ".jnl", len); 1868 } else { 1869 journal = NULL; 1870 } 1871 result = dns_zone_setstring(zone, &zone->journal, journal); 1872 if (journal != NULL) { 1873 isc_mem_free(zone->mctx, journal); 1874 } 1875 return result; 1876 } 1877 1878 isc_result_t 1879 dns_zone_setjournal(dns_zone_t *zone, const char *myjournal) { 1880 isc_result_t result = ISC_R_SUCCESS; 1881 1882 REQUIRE(DNS_ZONE_VALID(zone)); 1883 1884 LOCK_ZONE(zone); 1885 result = dns_zone_setstring(zone, &zone->journal, myjournal); 1886 UNLOCK_ZONE(zone); 1887 1888 return result; 1889 } 1890 1891 char * 1892 dns_zone_getjournal(dns_zone_t *zone) { 1893 REQUIRE(DNS_ZONE_VALID(zone)); 1894 1895 return zone->journal; 1896 } 1897 1898 /* 1899 * Return true iff the zone is "dynamic", in the sense that the zone's 1900 * master file (if any) is written by the server, rather than being 1901 * updated manually and read by the server. 1902 * 1903 * This is true for secondary zones, mirror zones, stub zones, key zones, 1904 * and zones that allow dynamic updates either by having an update 1905 * policy ("ssutable") or an "allow-update" ACL with a value other than 1906 * exactly "{ none; }". 1907 */ 1908 bool 1909 dns_zone_isdynamic(dns_zone_t *zone, bool ignore_freeze) { 1910 REQUIRE(DNS_ZONE_VALID(zone)); 1911 1912 if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror || 1913 zone->type == dns_zone_stub || zone->type == dns_zone_key || 1914 (zone->type == dns_zone_redirect && 1915 dns_remote_addresses(&zone->primaries) != NULL)) 1916 { 1917 return true; 1918 } 1919 1920 /* Inline zones are always dynamic. */ 1921 if (zone->type == dns_zone_primary && zone->raw != NULL) { 1922 return true; 1923 } 1924 1925 /* If !ignore_freeze, we need check whether updates are disabled. */ 1926 if (zone->type == dns_zone_primary && 1927 (!zone->update_disabled || ignore_freeze) && 1928 ((zone->ssutable != NULL) || 1929 (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)))) 1930 { 1931 return true; 1932 } 1933 1934 return false; 1935 } 1936 1937 /* 1938 * Set the response policy index and information for a zone. 1939 */ 1940 isc_result_t 1941 dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs, 1942 dns_rpz_num_t rpz_num) { 1943 /* 1944 * This must happen only once or be redundant. 1945 */ 1946 LOCK_ZONE(zone); 1947 if (zone->rpzs != NULL) { 1948 REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num); 1949 } else { 1950 REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM); 1951 dns_rpz_zones_attach(rpzs, &zone->rpzs); 1952 zone->rpz_num = rpz_num; 1953 } 1954 rpzs->defined |= DNS_RPZ_ZBIT(rpz_num); 1955 UNLOCK_ZONE(zone); 1956 1957 return ISC_R_SUCCESS; 1958 } 1959 1960 dns_rpz_num_t 1961 dns_zone_get_rpz_num(dns_zone_t *zone) { 1962 return zone->rpz_num; 1963 } 1964 1965 /* 1966 * If a zone is a response policy zone, mark its new database. 1967 */ 1968 void 1969 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) { 1970 if (zone->rpz_num == DNS_RPZ_INVALID_NUM) { 1971 return; 1972 } 1973 REQUIRE(zone->rpzs != NULL); 1974 dns_rpz_dbupdate_register(db, zone->rpzs->zones[zone->rpz_num]); 1975 } 1976 1977 static void 1978 dns_zone_rpz_disable_db(dns_zone_t *zone, dns_db_t *db) { 1979 if (zone->rpz_num == DNS_RPZ_INVALID_NUM) { 1980 return; 1981 } 1982 REQUIRE(zone->rpzs != NULL); 1983 dns_rpz_dbupdate_unregister(db, zone->rpzs->zones[zone->rpz_num]); 1984 } 1985 1986 /* 1987 * If a zone is a catalog zone, attach it to update notification in database. 1988 */ 1989 void 1990 dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) { 1991 REQUIRE(DNS_ZONE_VALID(zone)); 1992 REQUIRE(db != NULL); 1993 1994 if (zone->catzs != NULL) { 1995 dns_catz_dbupdate_register(db, zone->catzs); 1996 } 1997 } 1998 1999 static void 2000 dns_zone_catz_disable_db(dns_zone_t *zone, dns_db_t *db) { 2001 REQUIRE(DNS_ZONE_VALID(zone)); 2002 REQUIRE(db != NULL); 2003 2004 if (zone->catzs != NULL) { 2005 dns_catz_dbupdate_unregister(db, zone->catzs); 2006 } 2007 } 2008 2009 static void 2010 zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) { 2011 REQUIRE(DNS_ZONE_VALID(zone)); 2012 REQUIRE(catzs != NULL); 2013 2014 INSIST(zone->catzs == NULL || zone->catzs == catzs); 2015 dns_catz_catzs_set_view(catzs, zone->view); 2016 if (zone->catzs == NULL) { 2017 dns_catz_zones_attach(catzs, &zone->catzs); 2018 } 2019 } 2020 2021 void 2022 dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) { 2023 REQUIRE(DNS_ZONE_VALID(zone)); 2024 2025 LOCK_ZONE(zone); 2026 zone_catz_enable(zone, catzs); 2027 UNLOCK_ZONE(zone); 2028 } 2029 2030 static void 2031 zone_catz_disable(dns_zone_t *zone) { 2032 REQUIRE(DNS_ZONE_VALID(zone)); 2033 2034 if (zone->catzs != NULL) { 2035 if (zone->db != NULL) { 2036 dns_zone_catz_disable_db(zone, zone->db); 2037 } 2038 dns_catz_zones_detach(&zone->catzs); 2039 } 2040 } 2041 2042 void 2043 dns_zone_catz_disable(dns_zone_t *zone) { 2044 REQUIRE(DNS_ZONE_VALID(zone)); 2045 2046 LOCK_ZONE(zone); 2047 zone_catz_disable(zone); 2048 UNLOCK_ZONE(zone); 2049 } 2050 2051 bool 2052 dns_zone_catz_is_enabled(dns_zone_t *zone) { 2053 REQUIRE(DNS_ZONE_VALID(zone)); 2054 2055 return zone->catzs != NULL; 2056 } 2057 2058 /* 2059 * Set catalog zone ownership of the zone 2060 */ 2061 void 2062 dns_zone_set_parentcatz(dns_zone_t *zone, dns_catz_zone_t *catz) { 2063 REQUIRE(DNS_ZONE_VALID(zone)); 2064 REQUIRE(catz != NULL); 2065 LOCK_ZONE(zone); 2066 INSIST(zone->parentcatz == NULL || zone->parentcatz == catz); 2067 zone->parentcatz = catz; 2068 UNLOCK_ZONE(zone); 2069 } 2070 2071 dns_catz_zone_t * 2072 dns_zone_get_parentcatz(dns_zone_t *zone) { 2073 REQUIRE(DNS_ZONE_VALID(zone)); 2074 2075 dns_catz_zone_t *parentcatz = NULL; 2076 2077 LOCK_ZONE(zone); 2078 parentcatz = zone->parentcatz; 2079 UNLOCK_ZONE(zone); 2080 2081 return parentcatz; 2082 } 2083 2084 static bool 2085 zone_touched(dns_zone_t *zone) { 2086 isc_result_t result; 2087 isc_time_t modtime; 2088 dns_include_t *include; 2089 2090 REQUIRE(DNS_ZONE_VALID(zone)); 2091 2092 result = isc_file_getmodtime(zone->masterfile, &modtime); 2093 if (result != ISC_R_SUCCESS || 2094 isc_time_compare(&modtime, &zone->loadtime) > 0) 2095 { 2096 return true; 2097 } 2098 2099 for (include = ISC_LIST_HEAD(zone->includes); include != NULL; 2100 include = ISC_LIST_NEXT(include, link)) 2101 { 2102 result = isc_file_getmodtime(include->name, &modtime); 2103 if (result != ISC_R_SUCCESS || 2104 isc_time_compare(&modtime, &include->filetime) > 0) 2105 { 2106 return true; 2107 } 2108 } 2109 2110 return false; 2111 } 2112 2113 /* 2114 * Note: when dealing with inline-signed zones, external callers will always 2115 * call zone_load() for the secure zone; zone_load() calls itself recursively 2116 * in order to load the raw zone. 2117 */ 2118 static isc_result_t 2119 zone_load(dns_zone_t *zone, unsigned int flags, bool locked) { 2120 isc_result_t result; 2121 isc_time_t now; 2122 isc_time_t loadtime; 2123 dns_db_t *db = NULL; 2124 bool rbt, hasraw, is_dynamic; 2125 2126 REQUIRE(DNS_ZONE_VALID(zone)); 2127 2128 if (!locked) { 2129 LOCK_ZONE(zone); 2130 } 2131 2132 INSIST(zone != zone->raw); 2133 hasraw = inline_secure(zone); 2134 if (hasraw) { 2135 /* 2136 * We are trying to load an inline-signed zone. First call 2137 * self recursively to try loading the raw version of the zone. 2138 * Assuming the raw zone file is readable, there are two 2139 * possibilities: 2140 * 2141 * a) the raw zone was not yet loaded and thus it will be 2142 * loaded now, synchronously; if this succeeds, a 2143 * subsequent attempt to load the signed zone file will 2144 * take place and thus zone_postload() will be called 2145 * twice: first for the raw zone and then for the secure 2146 * zone; the latter call will take care of syncing the raw 2147 * version with the secure version, 2148 * 2149 * b) the raw zone was already loaded and we are trying to 2150 * reload it, which will happen asynchronously; this means 2151 * zone_postload() will only be called for the raw zone 2152 * because "result" returned by the zone_load() call below 2153 * will not be ISC_R_SUCCESS but rather DNS_R_CONTINUE; 2154 * zone_postload() called for the raw zone will take care 2155 * of syncing the raw version with the secure version. 2156 */ 2157 result = zone_load(zone->raw, flags, false); 2158 if (result != ISC_R_SUCCESS) { 2159 if (!locked) { 2160 UNLOCK_ZONE(zone); 2161 } 2162 return result; 2163 } 2164 LOCK_ZONE(zone->raw); 2165 } 2166 2167 now = isc_time_now(); 2168 2169 INSIST(zone->type != dns_zone_none); 2170 2171 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { 2172 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) { 2173 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 2174 } 2175 result = DNS_R_CONTINUE; 2176 goto cleanup; 2177 } 2178 2179 INSIST(zone->db_argc >= 1); 2180 2181 rbt = strcmp(zone->db_argv[0], ZONEDB_DEFAULT) == 0; 2182 2183 if (zone->db != NULL && zone->masterfile == NULL && rbt) { 2184 /* 2185 * The zone has no master file configured. 2186 */ 2187 result = ISC_R_SUCCESS; 2188 goto cleanup; 2189 } 2190 2191 is_dynamic = dns_zone_isdynamic(zone, false); 2192 if (zone->db != NULL && is_dynamic) { 2193 /* 2194 * This is a secondary, stub, or dynamically updated zone 2195 * being reloaded. Do nothing - the database we already 2196 * have is guaranteed to be up-to-date. 2197 */ 2198 if (zone->type == dns_zone_primary && !hasraw) { 2199 result = DNS_R_DYNAMIC; 2200 } else { 2201 result = ISC_R_SUCCESS; 2202 } 2203 goto cleanup; 2204 } 2205 2206 /* 2207 * Store the current time before the zone is loaded, so that if the 2208 * file changes between the time of the load and the time that 2209 * zone->loadtime is set, then the file will still be reloaded 2210 * the next time dns_zone_load is called. 2211 */ 2212 loadtime = isc_time_now(); 2213 2214 /* 2215 * Don't do the load if the file that stores the zone is older 2216 * than the last time the zone was loaded. If the zone has not 2217 * been loaded yet, zone->loadtime will be the epoch. 2218 */ 2219 if (zone->masterfile != NULL) { 2220 isc_time_t filetime; 2221 2222 /* 2223 * The file is already loaded. If we are just doing a 2224 * "rndc reconfig", we are done. 2225 */ 2226 if (!isc_time_isepoch(&zone->loadtime) && 2227 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) 2228 { 2229 result = ISC_R_SUCCESS; 2230 goto cleanup; 2231 } 2232 2233 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 2234 !zone_touched(zone)) 2235 { 2236 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2237 ISC_LOG_DEBUG(1), 2238 "skipping load: master file " 2239 "older than last load"); 2240 result = DNS_R_UPTODATE; 2241 goto cleanup; 2242 } 2243 2244 /* 2245 * If the file modification time is in the past 2246 * set loadtime to that value. 2247 */ 2248 result = isc_file_getmodtime(zone->masterfile, &filetime); 2249 if (result == ISC_R_SUCCESS && 2250 isc_time_compare(&loadtime, &filetime) > 0) 2251 { 2252 loadtime = filetime; 2253 } 2254 } 2255 2256 /* 2257 * Built in zones (with the exception of empty zones) don't need 2258 * to be reloaded. 2259 */ 2260 if (zone->type == dns_zone_primary && 2261 strcmp(zone->db_argv[0], "_builtin") == 0 && 2262 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) && 2263 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 2264 { 2265 result = ISC_R_SUCCESS; 2266 goto cleanup; 2267 } 2268 2269 /* 2270 * Zones associated with a DLZ don't need to be loaded either, 2271 * but we need to associate the database with the zone object. 2272 */ 2273 if (strcmp(zone->db_argv[0], "dlz") == 0) { 2274 dns_dlzdb_t *dlzdb; 2275 dns_dlzfindzone_t findzone; 2276 2277 for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched); 2278 dlzdb != NULL; dlzdb = ISC_LIST_NEXT(dlzdb, link)) 2279 { 2280 INSIST(DNS_DLZ_VALID(dlzdb)); 2281 if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0) { 2282 break; 2283 } 2284 } 2285 2286 if (dlzdb == NULL) { 2287 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2288 ISC_LOG_ERROR, 2289 "DLZ %s does not exist or is set " 2290 "to 'search yes;'", 2291 zone->db_argv[1]); 2292 result = ISC_R_NOTFOUND; 2293 goto cleanup; 2294 } 2295 2296 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 2297 /* ask SDLZ driver if the zone is supported */ 2298 findzone = dlzdb->implementation->methods->findzone; 2299 result = (*findzone)(dlzdb->implementation->driverarg, 2300 dlzdb->dbdata, dlzdb->mctx, 2301 zone->view->rdclass, &zone->origin, NULL, 2302 NULL, &db); 2303 if (result != ISC_R_NOTFOUND) { 2304 if (zone->db != NULL) { 2305 zone_detachdb(zone); 2306 } 2307 zone_attachdb(zone, db); 2308 dns_db_detach(&db); 2309 result = ISC_R_SUCCESS; 2310 } 2311 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 2312 2313 if (result == ISC_R_SUCCESS) { 2314 if (dlzdb->configure_callback == NULL) { 2315 goto cleanup; 2316 } 2317 2318 result = (*dlzdb->configure_callback)(zone->view, dlzdb, 2319 zone); 2320 if (result != ISC_R_SUCCESS) { 2321 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2322 ISC_LOG_ERROR, 2323 "DLZ configuration callback: %s", 2324 isc_result_totext(result)); 2325 } 2326 } 2327 goto cleanup; 2328 } 2329 2330 if ((zone->type == dns_zone_secondary || 2331 zone->type == dns_zone_mirror || zone->type == dns_zone_stub || 2332 (zone->type == dns_zone_redirect && 2333 dns_remote_addresses(&zone->primaries) != NULL)) && 2334 rbt) 2335 { 2336 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FIRSTREFRESH); 2337 2338 if (zone->stream == NULL && 2339 (zone->masterfile == NULL || 2340 !isc_file_exists(zone->masterfile))) 2341 { 2342 if (zone->masterfile != NULL) { 2343 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2344 ISC_LOG_DEBUG(1), 2345 "no master file"); 2346 } 2347 zone->refreshtime = now; 2348 if (zone->loop != NULL) { 2349 zone_settimer(zone, &now); 2350 } 2351 result = ISC_R_SUCCESS; 2352 goto cleanup; 2353 } 2354 } 2355 2356 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1), 2357 "starting load"); 2358 2359 result = dns_zone_makedb(zone, &db); 2360 if (result != ISC_R_SUCCESS) { 2361 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 2362 "loading zone: creating database: %s", 2363 isc_result_totext(result)); 2364 goto cleanup; 2365 } 2366 2367 if (!dns_db_ispersistent(db)) { 2368 if (zone->masterfile != NULL || zone->stream != NULL) { 2369 result = zone_startload(db, zone, loadtime); 2370 } else { 2371 result = DNS_R_NOMASTERFILE; 2372 if (zone->type == dns_zone_primary || 2373 (zone->type == dns_zone_redirect && 2374 dns_remote_addresses(&zone->primaries) == NULL)) 2375 { 2376 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2377 ISC_LOG_ERROR, 2378 "loading zone: " 2379 "no master file configured"); 2380 goto cleanup; 2381 } 2382 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2383 ISC_LOG_INFO, 2384 "loading zone: " 2385 "no master file configured: continuing"); 2386 } 2387 } 2388 2389 if (result == DNS_R_CONTINUE) { 2390 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING); 2391 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) { 2392 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 2393 } 2394 goto cleanup; 2395 } 2396 2397 result = zone_postload(zone, db, loadtime, result); 2398 2399 cleanup: 2400 if (hasraw) { 2401 UNLOCK_ZONE(zone->raw); 2402 } 2403 if (!locked) { 2404 UNLOCK_ZONE(zone); 2405 } 2406 if (db != NULL) { 2407 dns_db_detach(&db); 2408 } 2409 return result; 2410 } 2411 2412 isc_result_t 2413 dns_zone_load(dns_zone_t *zone, bool newonly) { 2414 return zone_load(zone, newonly ? DNS_ZONELOADFLAG_NOSTAT : 0, false); 2415 } 2416 2417 static void 2418 zone_asyncload(void *arg) { 2419 dns_asyncload_t *asl = arg; 2420 dns_zone_t *zone = asl->zone; 2421 isc_result_t result; 2422 2423 REQUIRE(DNS_ZONE_VALID(zone)); 2424 2425 LOCK_ZONE(zone); 2426 result = zone_load(zone, asl->flags, true); 2427 if (result != DNS_R_CONTINUE) { 2428 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); 2429 } 2430 UNLOCK_ZONE(zone); 2431 2432 /* Inform the zone table we've finished loading */ 2433 if (asl->loaded != NULL) { 2434 asl->loaded(asl->loaded_arg); 2435 } 2436 2437 isc_mem_put(zone->mctx, asl, sizeof(*asl)); 2438 dns_zone_idetach(&zone); 2439 } 2440 2441 isc_result_t 2442 dns_zone_asyncload(dns_zone_t *zone, bool newonly, dns_zt_callback_t *done, 2443 void *arg) { 2444 dns_asyncload_t *asl = NULL; 2445 2446 REQUIRE(DNS_ZONE_VALID(zone)); 2447 2448 if (zone->zmgr == NULL) { 2449 return ISC_R_FAILURE; 2450 } 2451 2452 /* If we already have a load pending, stop now */ 2453 LOCK_ZONE(zone); 2454 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) { 2455 UNLOCK_ZONE(zone); 2456 return ISC_R_ALREADYRUNNING; 2457 } 2458 2459 asl = isc_mem_get(zone->mctx, sizeof(*asl)); 2460 2461 asl->zone = NULL; 2462 asl->flags = newonly ? DNS_ZONELOADFLAG_NOSTAT : 0; 2463 asl->loaded = done; 2464 asl->loaded_arg = arg; 2465 2466 zone_iattach(zone, &asl->zone); 2467 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING); 2468 isc_async_run(zone->loop, zone_asyncload, asl); 2469 UNLOCK_ZONE(zone); 2470 2471 return ISC_R_SUCCESS; 2472 } 2473 2474 bool 2475 dns__zone_loadpending(dns_zone_t *zone) { 2476 REQUIRE(DNS_ZONE_VALID(zone)); 2477 2478 return DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING); 2479 } 2480 2481 isc_result_t 2482 dns_zone_loadandthaw(dns_zone_t *zone) { 2483 isc_result_t result; 2484 2485 if (inline_raw(zone)) { 2486 result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW, false); 2487 } else { 2488 /* 2489 * When thawing a zone, we don't know what changes 2490 * have been made. If we do DNSSEC maintenance on this 2491 * zone, schedule a full sign for this zone. 2492 */ 2493 if (zone->type == dns_zone_primary && 2494 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 2495 { 2496 DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN); 2497 } 2498 result = zone_load(zone, DNS_ZONELOADFLAG_THAW, false); 2499 } 2500 2501 switch (result) { 2502 case DNS_R_CONTINUE: 2503 /* Deferred thaw. */ 2504 break; 2505 case DNS_R_UPTODATE: 2506 case ISC_R_SUCCESS: 2507 case DNS_R_SEENINCLUDE: 2508 zone->update_disabled = false; 2509 break; 2510 case DNS_R_NOMASTERFILE: 2511 zone->update_disabled = false; 2512 break; 2513 default: 2514 /* Error, remain in disabled state. */ 2515 break; 2516 } 2517 return result; 2518 } 2519 2520 static unsigned int 2521 get_primary_options(dns_zone_t *zone) { 2522 unsigned int options; 2523 2524 options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN; 2525 if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror || 2526 (zone->type == dns_zone_redirect && 2527 dns_remote_addresses(&zone->primaries) == NULL)) 2528 { 2529 options |= DNS_MASTER_SECONDARY; 2530 } 2531 if (zone->type == dns_zone_key) { 2532 options |= DNS_MASTER_KEY; 2533 } 2534 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) { 2535 options |= DNS_MASTER_CHECKNS; 2536 } 2537 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) { 2538 options |= DNS_MASTER_FATALNS; 2539 } 2540 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) { 2541 options |= DNS_MASTER_CHECKNAMES; 2542 } 2543 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) { 2544 options |= DNS_MASTER_CHECKNAMESFAIL; 2545 } 2546 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) { 2547 options |= DNS_MASTER_CHECKMX; 2548 } 2549 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) { 2550 options |= DNS_MASTER_CHECKMXFAIL; 2551 } 2552 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) { 2553 options |= DNS_MASTER_CHECKWILDCARD; 2554 } 2555 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKTTL)) { 2556 options |= DNS_MASTER_CHECKTTL; 2557 } 2558 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSVCB)) { 2559 options |= DNS_MASTER_CHECKSVCB; 2560 } 2561 2562 return options; 2563 } 2564 2565 static void 2566 zone_registerinclude(const char *filename, void *arg) { 2567 isc_result_t result; 2568 dns_zone_t *zone = (dns_zone_t *)arg; 2569 dns_include_t *inc = NULL; 2570 2571 REQUIRE(DNS_ZONE_VALID(zone)); 2572 2573 if (filename == NULL) { 2574 return; 2575 } 2576 2577 /* 2578 * Suppress duplicates. 2579 */ 2580 for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; 2581 inc = ISC_LIST_NEXT(inc, link)) 2582 { 2583 if (strcmp(filename, inc->name) == 0) { 2584 return; 2585 } 2586 } 2587 2588 inc = isc_mem_get(zone->mctx, sizeof(dns_include_t)); 2589 inc->name = isc_mem_strdup(zone->mctx, filename); 2590 ISC_LINK_INIT(inc, link); 2591 2592 result = isc_file_getmodtime(filename, &inc->filetime); 2593 if (result != ISC_R_SUCCESS) { 2594 isc_time_settoepoch(&inc->filetime); 2595 } 2596 2597 ISC_LIST_APPEND(zone->newincludes, inc, link); 2598 } 2599 2600 static void 2601 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) { 2602 isc_result_t result; 2603 unsigned int soacount; 2604 2605 LOCK(&raw->lock); 2606 if (raw->db != NULL) { 2607 result = zone_get_from_db(raw, raw->db, NULL, &soacount, NULL, 2608 &rawdata->sourceserial, NULL, NULL, 2609 NULL, NULL, NULL); 2610 if (result == ISC_R_SUCCESS && soacount > 0U) { 2611 rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET; 2612 } 2613 } 2614 UNLOCK(&raw->lock); 2615 } 2616 2617 /* 2618 * Save the raw serial number for inline-signing zones. 2619 * (XXX: Other information from the header will be used 2620 * for other purposes in the future, but for now this is 2621 * all we're interested in.) 2622 */ 2623 static void 2624 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { 2625 if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0) { 2626 return; 2627 } 2628 2629 zone->sourceserial = header->sourceserial; 2630 zone->sourceserialset = true; 2631 } 2632 2633 void 2634 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { 2635 if (zone == NULL) { 2636 return; 2637 } 2638 2639 LOCK_ZONE(zone); 2640 zone_setrawdata(zone, header); 2641 UNLOCK_ZONE(zone); 2642 } 2643 2644 static isc_result_t 2645 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { 2646 isc_result_t result; 2647 isc_result_t tresult; 2648 unsigned int options; 2649 dns_load_t *load = isc_mem_get(zone->mctx, sizeof(*load)); 2650 2651 ENTER; 2652 2653 *load = (dns_load_t){ 2654 .loadtime = loadtime, 2655 }; 2656 2657 dns_zone_rpz_enable_db(zone, db); 2658 dns_zone_catz_enable_db(zone, db); 2659 2660 options = get_primary_options(zone); 2661 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) { 2662 options |= DNS_MASTER_MANYERRORS; 2663 } 2664 2665 zone_iattach(zone, &load->zone); 2666 dns_db_attach(db, &load->db); 2667 2668 dns_rdatacallbacks_init(&load->callbacks); 2669 load->callbacks.rawdata = zone_setrawdata; 2670 zone_iattach(zone, &load->callbacks.zone); 2671 2672 result = dns_db_beginload(db, &load->callbacks); 2673 if (result != ISC_R_SUCCESS) { 2674 goto cleanup; 2675 } 2676 2677 if (zone->zmgr != NULL && zone->db != NULL) { 2678 result = dns_master_loadfileasync( 2679 zone->masterfile, dns_db_origin(db), dns_db_origin(db), 2680 zone->rdclass, options, 0, &load->callbacks, zone->loop, 2681 zone_loaddone, load, &zone->loadctx, 2682 zone_registerinclude, zone, zone->mctx, 2683 zone->masterformat, zone->maxttl); 2684 if (result != ISC_R_SUCCESS) { 2685 goto cleanup; 2686 } 2687 2688 return DNS_R_CONTINUE; 2689 } else if (zone->stream != NULL) { 2690 FILE *stream = UNCONST(zone->stream); 2691 result = dns_master_loadstream( 2692 stream, &zone->origin, &zone->origin, zone->rdclass, 2693 options, &load->callbacks, zone->mctx); 2694 } else { 2695 result = dns_master_loadfile( 2696 zone->masterfile, &zone->origin, &zone->origin, 2697 zone->rdclass, options, 0, &load->callbacks, 2698 zone_registerinclude, zone, zone->mctx, 2699 zone->masterformat, zone->maxttl); 2700 } 2701 2702 cleanup: 2703 if (result != ISC_R_SUCCESS) { 2704 dns_zone_rpz_disable_db(zone, load->db); 2705 dns_zone_catz_disable_db(zone, load->db); 2706 } 2707 2708 tresult = dns_db_endload(db, &load->callbacks); 2709 if (result == ISC_R_SUCCESS) { 2710 result = tresult; 2711 } 2712 2713 zone_idetach(&load->callbacks.zone); 2714 dns_db_detach(&load->db); 2715 zone_idetach(&load->zone); 2716 2717 isc_mem_put(zone->mctx, load, sizeof(*load)); 2718 return result; 2719 } 2720 2721 static bool 2722 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2723 dns_name_t *owner) { 2724 isc_result_t result; 2725 char ownerbuf[DNS_NAME_FORMATSIZE]; 2726 char namebuf[DNS_NAME_FORMATSIZE]; 2727 char altbuf[DNS_NAME_FORMATSIZE]; 2728 dns_fixedname_t fixed; 2729 dns_name_t *foundname; 2730 int level; 2731 2732 /* 2733 * "." means the services does not exist. 2734 */ 2735 if (dns_name_equal(name, dns_rootname)) { 2736 return true; 2737 } 2738 2739 /* 2740 * Outside of zone. 2741 */ 2742 if (!dns_name_issubdomain(name, &zone->origin)) { 2743 if (zone->checkmx != NULL) { 2744 return (zone->checkmx)(zone, name, owner); 2745 } 2746 return true; 2747 } 2748 2749 if (zone->type == dns_zone_primary) { 2750 level = ISC_LOG_ERROR; 2751 } else { 2752 level = ISC_LOG_WARNING; 2753 } 2754 2755 foundname = dns_fixedname_initname(&fixed); 2756 2757 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, 2758 foundname, NULL, NULL); 2759 if (result == ISC_R_SUCCESS) { 2760 return true; 2761 } 2762 2763 if (result == DNS_R_NXRRSET) { 2764 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0, 2765 NULL, foundname, NULL, NULL); 2766 if (result == ISC_R_SUCCESS) { 2767 return true; 2768 } 2769 } 2770 2771 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2772 dns_name_format(name, namebuf, sizeof namebuf); 2773 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2774 result == DNS_R_EMPTYNAME) 2775 { 2776 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) { 2777 level = ISC_LOG_WARNING; 2778 } 2779 dns_zone_log(zone, level, 2780 "%s/MX '%s' has no address records (A or AAAA)", 2781 ownerbuf, namebuf); 2782 return (level == ISC_LOG_WARNING) ? true : false; 2783 } 2784 2785 if (result == DNS_R_CNAME) { 2786 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 2787 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2788 { 2789 level = ISC_LOG_WARNING; 2790 } 2791 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { 2792 dns_zone_log(zone, level, 2793 "%s/MX '%s' is a CNAME (illegal)", 2794 ownerbuf, namebuf); 2795 } 2796 return (level == ISC_LOG_WARNING) ? true : false; 2797 } 2798 2799 if (result == DNS_R_DNAME) { 2800 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 2801 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2802 { 2803 level = ISC_LOG_WARNING; 2804 } 2805 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { 2806 dns_name_format(foundname, altbuf, sizeof altbuf); 2807 dns_zone_log(zone, level, 2808 "%s/MX '%s' is below a DNAME" 2809 " '%s' (illegal)", 2810 ownerbuf, namebuf, altbuf); 2811 } 2812 return (level == ISC_LOG_WARNING) ? true : false; 2813 } 2814 2815 if (zone->checkmx != NULL && result == DNS_R_DELEGATION) { 2816 return (zone->checkmx)(zone, name, owner); 2817 } 2818 2819 return true; 2820 } 2821 2822 static bool 2823 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2824 dns_name_t *owner) { 2825 isc_result_t result; 2826 char ownerbuf[DNS_NAME_FORMATSIZE]; 2827 char namebuf[DNS_NAME_FORMATSIZE]; 2828 char altbuf[DNS_NAME_FORMATSIZE]; 2829 dns_fixedname_t fixed; 2830 dns_name_t *foundname; 2831 int level; 2832 2833 /* 2834 * "." means the services does not exist. 2835 */ 2836 if (dns_name_equal(name, dns_rootname)) { 2837 return true; 2838 } 2839 2840 /* 2841 * Outside of zone. 2842 */ 2843 if (!dns_name_issubdomain(name, &zone->origin)) { 2844 if (zone->checksrv != NULL) { 2845 return (zone->checksrv)(zone, name, owner); 2846 } 2847 return true; 2848 } 2849 2850 if (zone->type == dns_zone_primary) { 2851 level = ISC_LOG_ERROR; 2852 } else { 2853 level = ISC_LOG_WARNING; 2854 } 2855 2856 foundname = dns_fixedname_initname(&fixed); 2857 2858 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, 2859 foundname, NULL, NULL); 2860 if (result == ISC_R_SUCCESS) { 2861 return true; 2862 } 2863 2864 if (result == DNS_R_NXRRSET) { 2865 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0, 2866 NULL, foundname, NULL, NULL); 2867 if (result == ISC_R_SUCCESS) { 2868 return true; 2869 } 2870 } 2871 2872 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2873 dns_name_format(name, namebuf, sizeof namebuf); 2874 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2875 result == DNS_R_EMPTYNAME) 2876 { 2877 dns_zone_log(zone, level, 2878 "%s/SRV '%s' has no address records (A or AAAA)", 2879 ownerbuf, namebuf); 2880 /* XXX950 make fatal for 9.5.0. */ 2881 return true; 2882 } 2883 2884 if (result == DNS_R_CNAME) { 2885 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 2886 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2887 { 2888 level = ISC_LOG_WARNING; 2889 } 2890 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { 2891 dns_zone_log(zone, level, 2892 "%s/SRV '%s' is a CNAME (illegal)", 2893 ownerbuf, namebuf); 2894 } 2895 return (level == ISC_LOG_WARNING) ? true : false; 2896 } 2897 2898 if (result == DNS_R_DNAME) { 2899 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 2900 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2901 { 2902 level = ISC_LOG_WARNING; 2903 } 2904 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { 2905 dns_name_format(foundname, altbuf, sizeof altbuf); 2906 dns_zone_log(zone, level, 2907 "%s/SRV '%s' is below a " 2908 "DNAME '%s' (illegal)", 2909 ownerbuf, namebuf, altbuf); 2910 } 2911 return (level == ISC_LOG_WARNING) ? true : false; 2912 } 2913 2914 if (zone->checksrv != NULL && result == DNS_R_DELEGATION) { 2915 return (zone->checksrv)(zone, name, owner); 2916 } 2917 2918 return true; 2919 } 2920 2921 static bool 2922 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2923 dns_name_t *owner) { 2924 bool answer = true; 2925 isc_result_t result, tresult; 2926 char ownerbuf[DNS_NAME_FORMATSIZE]; 2927 char namebuf[DNS_NAME_FORMATSIZE]; 2928 char altbuf[DNS_NAME_FORMATSIZE]; 2929 dns_fixedname_t fixed; 2930 dns_name_t *foundname; 2931 dns_rdataset_t a; 2932 dns_rdataset_t aaaa; 2933 int level; 2934 2935 /* 2936 * Outside of zone. 2937 */ 2938 if (!dns_name_issubdomain(name, &zone->origin)) { 2939 if (zone->checkns != NULL) { 2940 return (zone->checkns)(zone, name, owner, NULL, NULL); 2941 } 2942 return true; 2943 } 2944 2945 if (zone->type == dns_zone_primary) { 2946 level = ISC_LOG_ERROR; 2947 } else { 2948 level = ISC_LOG_WARNING; 2949 } 2950 2951 foundname = dns_fixedname_initname(&fixed); 2952 dns_rdataset_init(&a); 2953 dns_rdataset_init(&aaaa); 2954 2955 /* 2956 * Perform a regular lookup to catch DNAME records then look 2957 * for glue. 2958 */ 2959 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, 2960 foundname, &a, NULL); 2961 switch (result) { 2962 case ISC_R_SUCCESS: 2963 case DNS_R_DNAME: 2964 case DNS_R_CNAME: 2965 break; 2966 default: 2967 if (dns_rdataset_isassociated(&a)) { 2968 dns_rdataset_disassociate(&a); 2969 } 2970 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 2971 DNS_DBFIND_GLUEOK, 0, NULL, foundname, &a, 2972 NULL); 2973 } 2974 if (result == ISC_R_SUCCESS) { 2975 dns_rdataset_disassociate(&a); 2976 return true; 2977 } else if (result == DNS_R_DELEGATION) { 2978 dns_rdataset_disassociate(&a); 2979 } 2980 2981 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION || 2982 result == DNS_R_GLUE) 2983 { 2984 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 2985 DNS_DBFIND_GLUEOK, 0, NULL, foundname, 2986 &aaaa, NULL); 2987 if (tresult == ISC_R_SUCCESS) { 2988 if (dns_rdataset_isassociated(&a)) { 2989 dns_rdataset_disassociate(&a); 2990 } 2991 dns_rdataset_disassociate(&aaaa); 2992 return true; 2993 } 2994 if (tresult == DNS_R_DELEGATION || tresult == DNS_R_DNAME) { 2995 dns_rdataset_disassociate(&aaaa); 2996 } 2997 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) { 2998 /* 2999 * Check glue against child zone. 3000 */ 3001 if (zone->checkns != NULL) { 3002 answer = (zone->checkns)(zone, name, owner, &a, 3003 &aaaa); 3004 } 3005 if (dns_rdataset_isassociated(&a)) { 3006 dns_rdataset_disassociate(&a); 3007 } 3008 if (dns_rdataset_isassociated(&aaaa)) { 3009 dns_rdataset_disassociate(&aaaa); 3010 } 3011 return answer; 3012 } 3013 } 3014 3015 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 3016 dns_name_format(name, namebuf, sizeof namebuf); 3017 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 3018 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) 3019 { 3020 const char *what; 3021 bool required = false; 3022 if (dns_name_issubdomain(name, owner)) { 3023 what = "REQUIRED GLUE "; 3024 required = true; 3025 } else if (result == DNS_R_DELEGATION) { 3026 what = "SIBLING GLUE "; 3027 } else { 3028 what = ""; 3029 } 3030 3031 if (result != DNS_R_DELEGATION || required || 3032 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) 3033 { 3034 dns_zone_log(zone, level, 3035 "%s/NS '%s' has no %s" 3036 "address records (A or AAAA)", 3037 ownerbuf, namebuf, what); 3038 /* 3039 * Log missing address record. 3040 */ 3041 if (result == DNS_R_DELEGATION && zone->checkns != NULL) 3042 { 3043 (void)(zone->checkns)(zone, name, owner, &a, 3044 &aaaa); 3045 } 3046 /* XXX950 make fatal for 9.5.0. */ 3047 /* answer = false; */ 3048 } 3049 } else if (result == DNS_R_CNAME) { 3050 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)", 3051 ownerbuf, namebuf); 3052 /* XXX950 make fatal for 9.5.0. */ 3053 /* answer = false; */ 3054 } else if (result == DNS_R_DNAME) { 3055 dns_name_format(foundname, altbuf, sizeof altbuf); 3056 dns_zone_log(zone, level, 3057 "%s/NS '%s' is below a DNAME '%s' (illegal)", 3058 ownerbuf, namebuf, altbuf); 3059 /* XXX950 make fatal for 9.5.0. */ 3060 /* answer = false; */ 3061 } 3062 3063 if (dns_rdataset_isassociated(&a)) { 3064 dns_rdataset_disassociate(&a); 3065 } 3066 if (dns_rdataset_isassociated(&aaaa)) { 3067 dns_rdataset_disassociate(&aaaa); 3068 } 3069 return answer; 3070 } 3071 3072 static bool 3073 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner, 3074 dns_rdataset_t *rdataset) { 3075 dns_rdataset_t tmprdataset; 3076 isc_result_t result; 3077 bool answer = true; 3078 bool format = true; 3079 int level = ISC_LOG_WARNING; 3080 char ownerbuf[DNS_NAME_FORMATSIZE]; 3081 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 3082 unsigned int count1 = 0; 3083 3084 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL)) { 3085 level = ISC_LOG_ERROR; 3086 } 3087 3088 dns_rdataset_init(&tmprdataset); 3089 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 3090 result = dns_rdataset_next(rdataset)) 3091 { 3092 dns_rdata_t rdata1 = DNS_RDATA_INIT; 3093 unsigned int count2 = 0; 3094 3095 count1++; 3096 dns_rdataset_current(rdataset, &rdata1); 3097 dns_rdataset_clone(rdataset, &tmprdataset); 3098 for (result = dns_rdataset_first(&tmprdataset); 3099 result == ISC_R_SUCCESS; 3100 result = dns_rdataset_next(&tmprdataset)) 3101 { 3102 dns_rdata_t rdata2 = DNS_RDATA_INIT; 3103 count2++; 3104 if (count1 >= count2) { 3105 continue; 3106 } 3107 dns_rdataset_current(&tmprdataset, &rdata2); 3108 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) { 3109 if (format) { 3110 dns_name_format(owner, ownerbuf, 3111 sizeof ownerbuf); 3112 dns_rdatatype_format(rdata1.type, 3113 typebuf, 3114 sizeof(typebuf)); 3115 format = false; 3116 } 3117 dns_zone_log(zone, level, 3118 "%s/%s has " 3119 "semantically identical records", 3120 ownerbuf, typebuf); 3121 if (level == ISC_LOG_ERROR) { 3122 answer = false; 3123 } 3124 break; 3125 } 3126 } 3127 dns_rdataset_disassociate(&tmprdataset); 3128 if (!format) { 3129 break; 3130 } 3131 } 3132 return answer; 3133 } 3134 3135 static bool 3136 zone_check_dup(dns_zone_t *zone, dns_db_t *db) { 3137 dns_dbiterator_t *dbiterator = NULL; 3138 dns_dbnode_t *node = NULL; 3139 dns_fixedname_t fixed; 3140 dns_name_t *name; 3141 dns_rdataset_t rdataset; 3142 dns_rdatasetiter_t *rdsit = NULL; 3143 bool ok = true; 3144 isc_result_t result; 3145 3146 name = dns_fixedname_initname(&fixed); 3147 dns_rdataset_init(&rdataset); 3148 3149 result = dns_db_createiterator(db, 0, &dbiterator); 3150 if (result != ISC_R_SUCCESS) { 3151 return true; 3152 } 3153 3154 for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS; 3155 result = dns_dbiterator_next(dbiterator)) 3156 { 3157 result = dns_dbiterator_current(dbiterator, &node, name); 3158 if (result != ISC_R_SUCCESS) { 3159 continue; 3160 } 3161 3162 result = dns_db_allrdatasets(db, node, NULL, 0, 0, &rdsit); 3163 if (result != ISC_R_SUCCESS) { 3164 continue; 3165 } 3166 3167 for (result = dns_rdatasetiter_first(rdsit); 3168 result == ISC_R_SUCCESS; 3169 result = dns_rdatasetiter_next(rdsit)) 3170 { 3171 dns_rdatasetiter_current(rdsit, &rdataset); 3172 if (!zone_rrset_check_dup(zone, name, &rdataset)) { 3173 ok = false; 3174 } 3175 dns_rdataset_disassociate(&rdataset); 3176 } 3177 dns_rdatasetiter_destroy(&rdsit); 3178 dns_db_detachnode(db, &node); 3179 } 3180 3181 if (node != NULL) { 3182 dns_db_detachnode(db, &node); 3183 } 3184 dns_dbiterator_destroy(&dbiterator); 3185 3186 return ok; 3187 } 3188 3189 static bool 3190 isspf(const dns_rdata_t *rdata) { 3191 char buf[1024]; 3192 const unsigned char *data = rdata->data; 3193 unsigned int rdl = rdata->length, i = 0, tl, len; 3194 3195 while (rdl > 0U) { 3196 len = tl = *data; 3197 ++data; 3198 --rdl; 3199 INSIST(tl <= rdl); 3200 if (len > sizeof(buf) - i - 1) { 3201 len = sizeof(buf) - i - 1; 3202 } 3203 memmove(buf + i, data, len); 3204 i += len; 3205 data += tl; 3206 rdl -= tl; 3207 } 3208 3209 if (i < 6U) { 3210 return false; 3211 } 3212 3213 buf[i] = 0; 3214 if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' ')) { 3215 return true; 3216 } 3217 return false; 3218 } 3219 3220 static bool 3221 integrity_checks(dns_zone_t *zone, dns_db_t *db) { 3222 dns_dbiterator_t *dbiterator = NULL; 3223 dns_dbnode_t *node = NULL; 3224 dns_rdataset_t rdataset; 3225 dns_fixedname_t fixed; 3226 dns_fixedname_t fixedbottom; 3227 dns_rdata_mx_t mx; 3228 dns_rdata_ns_t ns; 3229 dns_rdata_in_srv_t srv; 3230 dns_rdata_t rdata; 3231 dns_name_t *name; 3232 dns_name_t *bottom; 3233 isc_result_t result; 3234 bool ok = true, have_spf, have_txt; 3235 int level; 3236 char namebuf[DNS_NAME_FORMATSIZE]; 3237 3238 name = dns_fixedname_initname(&fixed); 3239 bottom = dns_fixedname_initname(&fixedbottom); 3240 dns_rdataset_init(&rdataset); 3241 dns_rdata_init(&rdata); 3242 3243 result = dns_db_createiterator(db, 0, &dbiterator); 3244 if (result != ISC_R_SUCCESS) { 3245 return true; 3246 } 3247 3248 result = dns_dbiterator_first(dbiterator); 3249 while (result == ISC_R_SUCCESS) { 3250 result = dns_dbiterator_current(dbiterator, &node, name); 3251 if (result != ISC_R_SUCCESS) { 3252 goto cleanup; 3253 } 3254 3255 /* 3256 * Is this name visible in the zone? 3257 */ 3258 if (!dns_name_issubdomain(name, &zone->origin) || 3259 (dns_name_countlabels(bottom) > 0 && 3260 dns_name_issubdomain(name, bottom))) 3261 { 3262 goto next; 3263 } 3264 3265 dns_dbiterator_pause(dbiterator); 3266 3267 /* 3268 * Don't check the NS records at the origin. 3269 */ 3270 if (dns_name_equal(name, &zone->origin)) { 3271 goto checkfords; 3272 } 3273 3274 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns, 3275 0, 0, &rdataset, NULL); 3276 if (result != ISC_R_SUCCESS) { 3277 goto checkfords; 3278 } 3279 /* 3280 * Remember bottom of zone due to NS. 3281 */ 3282 dns_name_copy(name, bottom); 3283 3284 result = dns_rdataset_first(&rdataset); 3285 while (result == ISC_R_SUCCESS) { 3286 dns_rdataset_current(&rdataset, &rdata); 3287 result = dns_rdata_tostruct(&rdata, &ns, NULL); 3288 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3289 if (!zone_check_glue(zone, db, &ns.name, name)) { 3290 ok = false; 3291 } 3292 dns_rdata_reset(&rdata); 3293 result = dns_rdataset_next(&rdataset); 3294 } 3295 dns_rdataset_disassociate(&rdataset); 3296 goto next; 3297 3298 checkfords: 3299 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, 3300 0, 0, &rdataset, NULL); 3301 if (result != ISC_R_SUCCESS) { 3302 goto checkfordname; 3303 } 3304 dns_rdataset_disassociate(&rdataset); 3305 3306 if (zone->type == dns_zone_primary) { 3307 level = ISC_LOG_ERROR; 3308 ok = false; 3309 } else { 3310 level = ISC_LOG_WARNING; 3311 } 3312 dns_name_format(name, namebuf, sizeof(namebuf)); 3313 dns_zone_log(zone, level, "DS not at delegation point (%s)", 3314 namebuf); 3315 3316 checkfordname: 3317 result = dns_db_findrdataset(db, node, NULL, 3318 dns_rdatatype_dname, 0, 0, 3319 &rdataset, NULL); 3320 if (result == ISC_R_SUCCESS) { 3321 /* 3322 * Remember bottom of zone due to DNAME. 3323 */ 3324 dns_name_copy(name, bottom); 3325 dns_rdataset_disassociate(&rdataset); 3326 } 3327 3328 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx, 3329 0, 0, &rdataset, NULL); 3330 if (result != ISC_R_SUCCESS) { 3331 goto checksrv; 3332 } 3333 result = dns_rdataset_first(&rdataset); 3334 while (result == ISC_R_SUCCESS) { 3335 dns_rdataset_current(&rdataset, &rdata); 3336 result = dns_rdata_tostruct(&rdata, &mx, NULL); 3337 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3338 if (!zone_check_mx(zone, db, &mx.mx, name)) { 3339 ok = false; 3340 } 3341 dns_rdata_reset(&rdata); 3342 result = dns_rdataset_next(&rdataset); 3343 } 3344 dns_rdataset_disassociate(&rdataset); 3345 3346 checksrv: 3347 if (zone->rdclass != dns_rdataclass_in) { 3348 goto next; 3349 } 3350 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv, 3351 0, 0, &rdataset, NULL); 3352 if (result != ISC_R_SUCCESS) { 3353 goto checkspf; 3354 } 3355 result = dns_rdataset_first(&rdataset); 3356 while (result == ISC_R_SUCCESS) { 3357 dns_rdataset_current(&rdataset, &rdata); 3358 result = dns_rdata_tostruct(&rdata, &srv, NULL); 3359 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3360 if (!zone_check_srv(zone, db, &srv.target, name)) { 3361 ok = false; 3362 } 3363 dns_rdata_reset(&rdata); 3364 result = dns_rdataset_next(&rdataset); 3365 } 3366 dns_rdataset_disassociate(&rdataset); 3367 3368 checkspf: 3369 /* 3370 * Check if there is a type SPF record without an 3371 * SPF-formatted type TXT record also being present. 3372 */ 3373 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF)) { 3374 goto next; 3375 } 3376 if (zone->rdclass != dns_rdataclass_in) { 3377 goto next; 3378 } 3379 have_spf = have_txt = false; 3380 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf, 3381 0, 0, &rdataset, NULL); 3382 if (result == ISC_R_SUCCESS) { 3383 dns_rdataset_disassociate(&rdataset); 3384 have_spf = true; 3385 } 3386 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt, 3387 0, 0, &rdataset, NULL); 3388 if (result != ISC_R_SUCCESS) { 3389 goto notxt; 3390 } 3391 result = dns_rdataset_first(&rdataset); 3392 while (result == ISC_R_SUCCESS) { 3393 dns_rdataset_current(&rdataset, &rdata); 3394 have_txt = isspf(&rdata); 3395 dns_rdata_reset(&rdata); 3396 if (have_txt) { 3397 break; 3398 } 3399 result = dns_rdataset_next(&rdataset); 3400 } 3401 dns_rdataset_disassociate(&rdataset); 3402 3403 notxt: 3404 if (have_spf && !have_txt) { 3405 dns_name_format(name, namebuf, sizeof(namebuf)); 3406 dns_zone_log(zone, ISC_LOG_WARNING, 3407 "'%s' found type " 3408 "SPF record but no SPF TXT record found, " 3409 "add matching type TXT record", 3410 namebuf); 3411 } 3412 3413 next: 3414 dns_db_detachnode(db, &node); 3415 result = dns_dbiterator_next(dbiterator); 3416 } 3417 3418 cleanup: 3419 if (node != NULL) { 3420 dns_db_detachnode(db, &node); 3421 } 3422 dns_dbiterator_destroy(&dbiterator); 3423 3424 return ok; 3425 } 3426 3427 /* 3428 * OpenSSL verification of RSA keys with exponent 3 is known to be 3429 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn 3430 * if they are in use. 3431 */ 3432 static void 3433 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) { 3434 dns_dbnode_t *node = NULL; 3435 dns_dbversion_t *version = NULL; 3436 dns_rdata_dnskey_t dnskey; 3437 dns_rdata_t rdata = DNS_RDATA_INIT; 3438 dns_rdataset_t rdataset; 3439 isc_result_t result; 3440 3441 result = dns_db_findnode(db, &zone->origin, false, &node); 3442 if (result != ISC_R_SUCCESS) { 3443 goto cleanup; 3444 } 3445 3446 dns_db_currentversion(db, &version); 3447 dns_rdataset_init(&rdataset); 3448 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 3449 dns_rdatatype_none, 0, &rdataset, NULL); 3450 if (result != ISC_R_SUCCESS) { 3451 goto cleanup; 3452 } 3453 3454 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 3455 result = dns_rdataset_next(&rdataset)) 3456 { 3457 dns_rdataset_current(&rdataset, &rdata); 3458 result = dns_rdata_tostruct(&rdata, &dnskey, NULL); 3459 INSIST(result == ISC_R_SUCCESS); 3460 3461 /* 3462 * RFC 3110, section 4: Performance Considerations: 3463 * 3464 * A public exponent of 3 minimizes the effort needed to verify 3465 * a signature. Use of 3 as the public exponent is weak for 3466 * confidentiality uses since, if the same data can be collected 3467 * encrypted under three different keys with an exponent of 3 3468 * then, using the Chinese Remainder Theorem [NETSEC], the 3469 * original plain text can be easily recovered. If a key is 3470 * known to be used only for authentication, as is the case with 3471 * DNSSEC, then an exponent of 3 is acceptable. However other 3472 * applications in the future may wish to leverage DNS 3473 * distributed keys for applications that do require 3474 * confidentiality. For keys which might have such other uses, 3475 * a more conservative choice would be 65537 (F4, the fourth 3476 * fermat number). 3477 */ 3478 if (dnskey.datalen > 1 && dnskey.data[0] == 1 && 3479 dnskey.data[1] == 3 && 3480 (dnskey.algorithm == DNS_KEYALG_RSAMD5 || 3481 dnskey.algorithm == DNS_KEYALG_RSASHA1 || 3482 dnskey.algorithm == DNS_KEYALG_NSEC3RSASHA1 || 3483 dnskey.algorithm == DNS_KEYALG_RSASHA256 || 3484 dnskey.algorithm == DNS_KEYALG_RSASHA512)) 3485 { 3486 char algorithm[DNS_SECALG_FORMATSIZE]; 3487 isc_region_t r; 3488 3489 dns_rdata_toregion(&rdata, &r); 3490 dns_secalg_format(dnskey.algorithm, algorithm, 3491 sizeof(algorithm)); 3492 3493 dnssec_log(zone, ISC_LOG_WARNING, 3494 "weak %s (%u) key found (exponent=3, id=%u)", 3495 algorithm, dnskey.algorithm, 3496 dst_region_computeid(&r)); 3497 } 3498 dns_rdata_reset(&rdata); 3499 } 3500 dns_rdataset_disassociate(&rdataset); 3501 3502 cleanup: 3503 if (node != NULL) { 3504 dns_db_detachnode(db, &node); 3505 } 3506 if (version != NULL) { 3507 dns_db_closeversion(db, &version, false); 3508 } 3509 } 3510 3511 static void 3512 resume_signingwithkey(dns_zone_t *zone) { 3513 dns_dbnode_t *node = NULL; 3514 dns_dbversion_t *version = NULL; 3515 dns_rdata_t rdata = DNS_RDATA_INIT; 3516 dns_rdataset_t rdataset; 3517 isc_result_t result; 3518 dns_db_t *db = NULL; 3519 3520 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3521 if (zone->db != NULL) { 3522 dns_db_attach(zone->db, &db); 3523 } 3524 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3525 if (db == NULL) { 3526 goto cleanup; 3527 } 3528 3529 result = dns_db_findnode(db, &zone->origin, false, &node); 3530 if (result != ISC_R_SUCCESS) { 3531 goto cleanup; 3532 } 3533 3534 dns_db_currentversion(db, &version); 3535 dns_rdataset_init(&rdataset); 3536 result = dns_db_findrdataset(db, node, version, zone->privatetype, 3537 dns_rdatatype_none, 0, &rdataset, NULL); 3538 if (result != ISC_R_SUCCESS) { 3539 INSIST(!dns_rdataset_isassociated(&rdataset)); 3540 goto cleanup; 3541 } 3542 3543 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 3544 result = dns_rdataset_next(&rdataset)) 3545 { 3546 dns_rdataset_current(&rdataset, &rdata); 3547 if (rdata.length != 5 || rdata.data[0] == 0 || 3548 rdata.data[4] != 0) 3549 { 3550 dns_rdata_reset(&rdata); 3551 continue; 3552 } 3553 3554 result = zone_signwithkey(zone, rdata.data[0], 3555 (rdata.data[1] << 8) | rdata.data[2], 3556 rdata.data[3]); 3557 if (result != ISC_R_SUCCESS) { 3558 dnssec_log(zone, ISC_LOG_ERROR, 3559 "zone_signwithkey failed: %s", 3560 isc_result_totext(result)); 3561 } 3562 dns_rdata_reset(&rdata); 3563 } 3564 dns_rdataset_disassociate(&rdataset); 3565 3566 cleanup: 3567 if (db != NULL) { 3568 if (node != NULL) { 3569 dns_db_detachnode(db, &node); 3570 } 3571 if (version != NULL) { 3572 dns_db_closeversion(db, &version, false); 3573 } 3574 dns_db_detach(&db); 3575 } 3576 } 3577 3578 /* 3579 * Initiate adding/removing NSEC3 records belonging to the chain defined by the 3580 * supplied NSEC3PARAM RDATA. 3581 * 3582 * Zone must be locked by caller. 3583 */ 3584 static isc_result_t 3585 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 3586 dns_nsec3chain_t *nsec3chain, *current; 3587 dns_dbversion_t *version = NULL; 3588 bool nseconly = false, nsec3ok = false; 3589 isc_result_t result; 3590 isc_time_t now; 3591 unsigned int options = 0; 3592 char saltbuf[255 * 2 + 1]; 3593 char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")]; 3594 dns_db_t *db = NULL; 3595 3596 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3597 if (zone->db != NULL) { 3598 dns_db_attach(zone->db, &db); 3599 } 3600 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3601 3602 if (db == NULL) { 3603 result = ISC_R_SUCCESS; 3604 goto cleanup; 3605 } 3606 3607 /* 3608 * If this zone is not NSEC3-capable, attempting to remove any NSEC3 3609 * chain from it is pointless as it would not be possible for the 3610 * latter to exist in the first place. 3611 */ 3612 dns_db_currentversion(db, &version); 3613 result = dns_nsec_nseconly(db, version, NULL, &nseconly); 3614 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 3615 dns_db_closeversion(db, &version, false); 3616 if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) { 3617 result = ISC_R_SUCCESS; 3618 goto cleanup; 3619 } 3620 3621 /* 3622 * Allocate and initialize structure preserving state of 3623 * adding/removing records belonging to this NSEC3 chain between 3624 * separate zone_nsec3chain() calls. 3625 */ 3626 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain); 3627 3628 nsec3chain->magic = 0; 3629 nsec3chain->done = false; 3630 nsec3chain->db = NULL; 3631 nsec3chain->dbiterator = NULL; 3632 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass; 3633 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype; 3634 nsec3chain->nsec3param.hash = nsec3param->hash; 3635 nsec3chain->nsec3param.iterations = nsec3param->iterations; 3636 nsec3chain->nsec3param.flags = nsec3param->flags; 3637 nsec3chain->nsec3param.salt_length = nsec3param->salt_length; 3638 memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length); 3639 nsec3chain->nsec3param.salt = nsec3chain->salt; 3640 nsec3chain->seen_nsec = false; 3641 nsec3chain->delete_nsec = false; 3642 nsec3chain->save_delete_nsec = false; 3643 3644 /* 3645 * Log NSEC3 parameters defined by supplied NSEC3PARAM RDATA. 3646 */ 3647 if (nsec3param->flags == 0) { 3648 strlcpy(flags, "NONE", sizeof(flags)); 3649 } else { 3650 flags[0] = '\0'; 3651 if ((nsec3param->flags & DNS_NSEC3FLAG_REMOVE) != 0) { 3652 strlcat(flags, "REMOVE", sizeof(flags)); 3653 } 3654 if ((nsec3param->flags & DNS_NSEC3FLAG_INITIAL) != 0) { 3655 if (flags[0] == '\0') { 3656 strlcpy(flags, "INITIAL", sizeof(flags)); 3657 } else { 3658 strlcat(flags, "|INITIAL", sizeof(flags)); 3659 } 3660 } 3661 if ((nsec3param->flags & DNS_NSEC3FLAG_CREATE) != 0) { 3662 if (flags[0] == '\0') { 3663 strlcpy(flags, "CREATE", sizeof(flags)); 3664 } else { 3665 strlcat(flags, "|CREATE", sizeof(flags)); 3666 } 3667 } 3668 if ((nsec3param->flags & DNS_NSEC3FLAG_NONSEC) != 0) { 3669 if (flags[0] == '\0') { 3670 strlcpy(flags, "NONSEC", sizeof(flags)); 3671 } else { 3672 strlcat(flags, "|NONSEC", sizeof(flags)); 3673 } 3674 } 3675 if ((nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) != 0) { 3676 if (flags[0] == '\0') { 3677 strlcpy(flags, "OPTOUT", sizeof(flags)); 3678 } else { 3679 strlcat(flags, "|OPTOUT", sizeof(flags)); 3680 } 3681 } 3682 } 3683 result = dns_nsec3param_salttotext(nsec3param, saltbuf, 3684 sizeof(saltbuf)); 3685 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3686 dnssec_log(zone, ISC_LOG_INFO, "zone_addnsec3chain(%u,%s,%u,%s)", 3687 nsec3param->hash, flags, nsec3param->iterations, saltbuf); 3688 3689 /* 3690 * If the NSEC3 chain defined by the supplied NSEC3PARAM RDATA is 3691 * currently being processed, interrupt its processing to avoid 3692 * simultaneously adding and removing records for the same NSEC3 chain. 3693 */ 3694 for (current = ISC_LIST_HEAD(zone->nsec3chain); current != NULL; 3695 current = ISC_LIST_NEXT(current, link)) 3696 { 3697 if ((current->db == db) && 3698 (current->nsec3param.hash == nsec3param->hash) && 3699 (current->nsec3param.iterations == 3700 nsec3param->iterations) && 3701 (current->nsec3param.salt_length == 3702 nsec3param->salt_length) && 3703 memcmp(current->nsec3param.salt, nsec3param->salt, 3704 nsec3param->salt_length) == 0) 3705 { 3706 current->done = true; 3707 } 3708 } 3709 3710 /* 3711 * Attach zone database to the structure initialized above and create 3712 * an iterator for it with appropriate options in order to avoid 3713 * creating NSEC3 records for NSEC3 records. 3714 */ 3715 dns_db_attach(db, &nsec3chain->db); 3716 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) { 3717 options = DNS_DB_NONSEC3; 3718 } 3719 result = dns_db_createiterator(nsec3chain->db, options, 3720 &nsec3chain->dbiterator); 3721 if (result == ISC_R_SUCCESS) { 3722 result = dns_dbiterator_first(nsec3chain->dbiterator); 3723 } 3724 if (result == ISC_R_SUCCESS) { 3725 /* 3726 * Database iterator initialization succeeded. We are now 3727 * ready to kick off adding/removing records belonging to this 3728 * NSEC3 chain. Append the structure initialized above to the 3729 * "nsec3chain" list for the zone and set the appropriate zone 3730 * timer so that zone_nsec3chain() is called as soon as 3731 * possible. 3732 */ 3733 dns_dbiterator_pause(nsec3chain->dbiterator); 3734 ISC_LIST_INITANDAPPEND(zone->nsec3chain, nsec3chain, link); 3735 nsec3chain = NULL; 3736 if (isc_time_isepoch(&zone->nsec3chaintime)) { 3737 now = isc_time_now(); 3738 zone->nsec3chaintime = now; 3739 if (zone->loop != NULL) { 3740 zone_settimer(zone, &now); 3741 } 3742 } 3743 } 3744 3745 if (nsec3chain != NULL) { 3746 if (nsec3chain->db != NULL) { 3747 dns_db_detach(&nsec3chain->db); 3748 } 3749 if (nsec3chain->dbiterator != NULL) { 3750 dns_dbiterator_destroy(&nsec3chain->dbiterator); 3751 } 3752 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 3753 } 3754 3755 cleanup: 3756 if (db != NULL) { 3757 dns_db_detach(&db); 3758 } 3759 return result; 3760 } 3761 3762 /* 3763 * Find private-type records at the zone apex which signal that an NSEC3 chain 3764 * should be added or removed. For each such record, extract NSEC3PARAM RDATA 3765 * and pass it to zone_addnsec3chain(). 3766 * 3767 * Zone must be locked by caller. 3768 */ 3769 static void 3770 resume_addnsec3chain(dns_zone_t *zone) { 3771 dns_dbnode_t *node = NULL; 3772 dns_dbversion_t *version = NULL; 3773 dns_rdataset_t rdataset; 3774 isc_result_t result; 3775 dns_rdata_nsec3param_t nsec3param; 3776 bool nseconly = false, nsec3ok = false; 3777 dns_db_t *db = NULL; 3778 3779 INSIST(LOCKED_ZONE(zone)); 3780 3781 if (zone->privatetype == 0) { 3782 return; 3783 } 3784 3785 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3786 if (zone->db != NULL) { 3787 dns_db_attach(zone->db, &db); 3788 } 3789 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3790 if (db == NULL) { 3791 goto cleanup; 3792 } 3793 3794 result = dns_db_findnode(db, &zone->origin, false, &node); 3795 if (result != ISC_R_SUCCESS) { 3796 goto cleanup; 3797 } 3798 3799 dns_db_currentversion(db, &version); 3800 3801 /* 3802 * In order to create NSEC3 chains we need the DNSKEY RRset at zone 3803 * apex to exist and contain no keys using NSEC-only algorithms. 3804 */ 3805 result = dns_nsec_nseconly(db, version, NULL, &nseconly); 3806 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 3807 3808 /* 3809 * Get the RRset containing all private-type records at the zone apex. 3810 */ 3811 dns_rdataset_init(&rdataset); 3812 result = dns_db_findrdataset(db, node, version, zone->privatetype, 3813 dns_rdatatype_none, 0, &rdataset, NULL); 3814 if (result != ISC_R_SUCCESS) { 3815 INSIST(!dns_rdataset_isassociated(&rdataset)); 3816 goto cleanup; 3817 } 3818 3819 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 3820 result = dns_rdataset_next(&rdataset)) 3821 { 3822 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 3823 dns_rdata_t rdata = DNS_RDATA_INIT; 3824 dns_rdata_t private = DNS_RDATA_INIT; 3825 3826 dns_rdataset_current(&rdataset, &private); 3827 /* 3828 * Try extracting NSEC3PARAM RDATA from this private-type 3829 * record. Failure means this private-type record does not 3830 * represent an NSEC3PARAM record, so skip it. 3831 */ 3832 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 3833 sizeof(buf))) 3834 { 3835 continue; 3836 } 3837 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 3838 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3839 if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) || 3840 ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok)) 3841 { 3842 /* 3843 * Pass the NSEC3PARAM RDATA contained in this 3844 * private-type record to zone_addnsec3chain() so that 3845 * it can kick off adding or removing NSEC3 records. 3846 */ 3847 result = zone_addnsec3chain(zone, &nsec3param); 3848 if (result != ISC_R_SUCCESS) { 3849 dnssec_log(zone, ISC_LOG_ERROR, 3850 "zone_addnsec3chain failed: %s", 3851 isc_result_totext(result)); 3852 } 3853 } 3854 } 3855 dns_rdataset_disassociate(&rdataset); 3856 3857 cleanup: 3858 if (db != NULL) { 3859 if (node != NULL) { 3860 dns_db_detachnode(db, &node); 3861 } 3862 if (version != NULL) { 3863 dns_db_closeversion(db, &version, false); 3864 } 3865 dns_db_detach(&db); 3866 } 3867 } 3868 3869 static void 3870 set_resigntime(dns_zone_t *zone) { 3871 dns_fixedname_t fixed; 3872 isc_stdtime_t resign; 3873 isc_result_t result; 3874 uint32_t nanosecs; 3875 dns_db_t *db = NULL; 3876 dns_typepair_t typepair; 3877 3878 INSIST(LOCKED_ZONE(zone)); 3879 3880 /* We only re-sign zones that can be dynamically updated */ 3881 if (!dns_zone_isdynamic(zone, false)) { 3882 return; 3883 } 3884 3885 if (inline_raw(zone)) { 3886 return; 3887 } 3888 3889 dns_fixedname_init(&fixed); 3890 3891 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3892 if (zone->db != NULL) { 3893 dns_db_attach(zone->db, &db); 3894 } 3895 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3896 if (db == NULL) { 3897 isc_time_settoepoch(&zone->resigntime); 3898 return; 3899 } 3900 3901 result = dns_db_getsigningtime(db, &resign, dns_fixedname_name(&fixed), 3902 &typepair); 3903 if (result != ISC_R_SUCCESS) { 3904 isc_time_settoepoch(&zone->resigntime); 3905 goto cleanup; 3906 } 3907 3908 resign -= dns_zone_getsigresigninginterval(zone); 3909 nanosecs = isc_random_uniform(1000000000); 3910 isc_time_set(&zone->resigntime, resign, nanosecs); 3911 3912 cleanup: 3913 dns_db_detach(&db); 3914 return; 3915 } 3916 3917 static isc_result_t 3918 check_nsec3param(dns_zone_t *zone, dns_db_t *db) { 3919 bool ok = false; 3920 dns_dbnode_t *node = NULL; 3921 dns_dbversion_t *version = NULL; 3922 dns_rdata_nsec3param_t nsec3param; 3923 dns_rdataset_t rdataset; 3924 isc_result_t result; 3925 bool dynamic = (zone->type == dns_zone_primary) 3926 ? dns_zone_isdynamic(zone, false) 3927 : false; 3928 3929 dns_rdataset_init(&rdataset); 3930 result = dns_db_findnode(db, &zone->origin, false, &node); 3931 if (result != ISC_R_SUCCESS) { 3932 dns_zone_log(zone, ISC_LOG_ERROR, 3933 "nsec3param lookup failure: %s", 3934 isc_result_totext(result)); 3935 return result; 3936 } 3937 dns_db_currentversion(db, &version); 3938 3939 result = dns_db_findrdataset(db, node, version, 3940 dns_rdatatype_nsec3param, 3941 dns_rdatatype_none, 0, &rdataset, NULL); 3942 if (result == ISC_R_NOTFOUND) { 3943 INSIST(!dns_rdataset_isassociated(&rdataset)); 3944 result = ISC_R_SUCCESS; 3945 goto cleanup; 3946 } 3947 if (result != ISC_R_SUCCESS) { 3948 INSIST(!dns_rdataset_isassociated(&rdataset)); 3949 dns_zone_log(zone, ISC_LOG_ERROR, 3950 "nsec3param lookup failure: %s", 3951 isc_result_totext(result)); 3952 goto cleanup; 3953 } 3954 3955 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 3956 result = dns_rdataset_next(&rdataset)) 3957 { 3958 dns_rdata_t rdata = DNS_RDATA_INIT; 3959 3960 dns_rdataset_current(&rdataset, &rdata); 3961 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 3962 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3963 3964 /* 3965 * For dynamic zones we must support every algorithm so we 3966 * can regenerate all the NSEC3 chains. 3967 * For non-dynamic zones we only need to find a supported 3968 * algorithm. 3969 */ 3970 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) && 3971 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic) 3972 { 3973 dns_zone_log(zone, ISC_LOG_WARNING, 3974 "nsec3 test \"unknown\" hash algorithm " 3975 "found: %u", 3976 nsec3param.hash); 3977 ok = true; 3978 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) { 3979 if (dynamic) { 3980 dns_zone_log(zone, ISC_LOG_ERROR, 3981 "unsupported nsec3 hash algorithm" 3982 " in dynamic zone: %u", 3983 nsec3param.hash); 3984 result = DNS_R_BADZONE; 3985 /* Stop second error message. */ 3986 ok = true; 3987 break; 3988 } else { 3989 dns_zone_log(zone, ISC_LOG_WARNING, 3990 "unsupported nsec3 hash " 3991 "algorithm: %u", 3992 nsec3param.hash); 3993 } 3994 } else { 3995 ok = true; 3996 } 3997 3998 /* 3999 * Warn if the zone has excessive NSEC3 iterations. 4000 */ 4001 if (nsec3param.iterations > dns_nsec3_maxiterations()) { 4002 dnssec_log(zone, ISC_LOG_WARNING, 4003 "excessive NSEC3PARAM iterations %u > %u", 4004 nsec3param.iterations, 4005 dns_nsec3_maxiterations()); 4006 } 4007 } 4008 if (result == ISC_R_NOMORE) { 4009 result = ISC_R_SUCCESS; 4010 } 4011 4012 if (!ok) { 4013 result = DNS_R_BADZONE; 4014 dns_zone_log(zone, ISC_LOG_ERROR, 4015 "no supported nsec3 hash algorithm"); 4016 } 4017 4018 cleanup: 4019 if (dns_rdataset_isassociated(&rdataset)) { 4020 dns_rdataset_disassociate(&rdataset); 4021 } 4022 dns_db_closeversion(db, &version, false); 4023 dns_db_detachnode(db, &node); 4024 return result; 4025 } 4026 4027 /* 4028 * Set the timer for refreshing the key zone to the soonest future time 4029 * of the set (current timer, keydata->refresh, keydata->addhd, 4030 * keydata->removehd). 4031 */ 4032 static void 4033 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key, 4034 isc_stdtime_t now, bool force) { 4035 isc_stdtime_t then; 4036 isc_time_t timenow, timethen; 4037 char timebuf[80]; 4038 4039 ENTER; 4040 then = key->refresh; 4041 if (force) { 4042 then = now; 4043 } 4044 if (key->addhd > now && key->addhd < then) { 4045 then = key->addhd; 4046 } 4047 if (key->removehd > now && key->removehd < then) { 4048 then = key->removehd; 4049 } 4050 4051 timenow = isc_time_now(); 4052 if (then > now) { 4053 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 4054 } else { 4055 timethen = timenow; 4056 } 4057 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 || 4058 isc_time_compare(&timethen, &zone->refreshkeytime) < 0) 4059 { 4060 zone->refreshkeytime = timethen; 4061 } 4062 4063 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 4064 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf); 4065 zone_settimer(zone, &timenow); 4066 } 4067 4068 /* 4069 * If keynode references a key or a DS rdataset, and if the key 4070 * zone does not contain a KEYDATA record for the corresponding name, 4071 * then create an empty KEYDATA and push it into the zone as a placeholder, 4072 * then schedule a key refresh immediately. This new KEYDATA record will be 4073 * updated during the refresh. 4074 * 4075 * If the key zone is changed, set '*changed' to true. 4076 */ 4077 static isc_result_t 4078 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 4079 dns_diff_t *diff, dns_keynode_t *keynode, dns_name_t *keyname, 4080 bool *changed) { 4081 isc_result_t result = ISC_R_SUCCESS; 4082 dns_rdata_t rdata = DNS_RDATA_INIT; 4083 dns_rdata_keydata_t kd; 4084 unsigned char rrdata[4096]; 4085 isc_buffer_t rrdatabuf; 4086 isc_stdtime_t now = isc_stdtime_now(); 4087 4088 REQUIRE(keynode != NULL); 4089 4090 ENTER; 4091 4092 /* 4093 * If the keynode has no trust anchor set, we shouldn't be here. 4094 */ 4095 if (!dns_keynode_dsset(keynode, NULL)) { 4096 return ISC_R_FAILURE; 4097 } 4098 4099 memset(&kd, 0, sizeof(kd)); 4100 kd.common.rdclass = zone->rdclass; 4101 kd.common.rdtype = dns_rdatatype_keydata; 4102 ISC_LINK_INIT(&kd.common, link); 4103 4104 isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); 4105 4106 CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass, dns_rdatatype_keydata, 4107 &kd, &rrdatabuf)); 4108 /* Add rdata to zone. */ 4109 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, keyname, 0, &rdata)); 4110 *changed = true; 4111 4112 /* Refresh new keys from the zone apex as soon as possible. */ 4113 set_refreshkeytimer(zone, &kd, now, true); 4114 return ISC_R_SUCCESS; 4115 4116 failure: 4117 return result; 4118 } 4119 4120 /* 4121 * Remove from the key zone all the KEYDATA records found in rdataset. 4122 */ 4123 static isc_result_t 4124 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 4125 dns_name_t *name, dns_rdataset_t *rdataset) { 4126 dns_rdata_t rdata = DNS_RDATA_INIT; 4127 isc_result_t result, uresult; 4128 4129 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 4130 result = dns_rdataset_next(rdataset)) 4131 { 4132 dns_rdata_reset(&rdata); 4133 dns_rdataset_current(rdataset, &rdata); 4134 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 0, 4135 &rdata); 4136 if (uresult != ISC_R_SUCCESS) { 4137 return uresult; 4138 } 4139 } 4140 if (result == ISC_R_NOMORE) { 4141 result = ISC_R_SUCCESS; 4142 } 4143 return result; 4144 } 4145 4146 /* 4147 * Compute the DNSSEC key ID for a DNSKEY record. 4148 */ 4149 static isc_result_t 4150 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx, 4151 dns_keytag_t *tag) { 4152 isc_result_t result; 4153 dns_rdata_t rdata = DNS_RDATA_INIT; 4154 unsigned char data[4096]; 4155 isc_buffer_t buffer; 4156 dst_key_t *dstkey = NULL; 4157 4158 isc_buffer_init(&buffer, data, sizeof(data)); 4159 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 4160 dns_rdatatype_dnskey, dnskey, &buffer); 4161 4162 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey); 4163 if (result == ISC_R_SUCCESS) { 4164 *tag = dst_key_id(dstkey); 4165 dst_key_free(&dstkey); 4166 } 4167 4168 return result; 4169 } 4170 4171 /* 4172 * Synth-from-dnssec callbacks to add/delete names from namespace tree. 4173 */ 4174 static void 4175 sfd_add(const dns_name_t *name, void *arg) { 4176 if (arg != NULL) { 4177 dns_view_sfd_add(arg, name); 4178 } 4179 } 4180 4181 static void 4182 sfd_del(const dns_name_t *name, void *arg) { 4183 if (arg != NULL) { 4184 dns_view_sfd_del(arg, name); 4185 } 4186 } 4187 4188 /* 4189 * Add key to the security roots. 4190 */ 4191 static void 4192 trust_key(dns_zone_t *zone, dns_name_t *keyname, dns_rdata_dnskey_t *dnskey, 4193 bool initial) { 4194 isc_result_t result; 4195 dns_rdata_t rdata = DNS_RDATA_INIT; 4196 unsigned char data[4096], digest[ISC_MAX_MD_SIZE]; 4197 isc_buffer_t buffer; 4198 dns_keytable_t *sr = NULL; 4199 dns_rdata_ds_t ds; 4200 4201 result = dns_view_getsecroots(zone->view, &sr); 4202 if (result != ISC_R_SUCCESS) { 4203 return; 4204 } 4205 4206 /* Build DS record for key. */ 4207 isc_buffer_init(&buffer, data, sizeof(data)); 4208 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 4209 dns_rdatatype_dnskey, dnskey, &buffer); 4210 CHECK(dns_ds_fromkeyrdata(keyname, &rdata, DNS_DSDIGEST_SHA256, digest, 4211 &ds)); 4212 CHECK(dns_keytable_add(sr, true, initial, keyname, &ds, sfd_add, 4213 zone->view)); 4214 4215 dns_keytable_detach(&sr); 4216 4217 failure: 4218 if (sr != NULL) { 4219 dns_keytable_detach(&sr); 4220 } 4221 return; 4222 } 4223 4224 /* 4225 * Add a null key to the security roots for so that all queries 4226 * to the zone will fail. 4227 */ 4228 static void 4229 fail_secure(dns_zone_t *zone, dns_name_t *keyname) { 4230 isc_result_t result; 4231 dns_keytable_t *sr = NULL; 4232 4233 result = dns_view_getsecroots(zone->view, &sr); 4234 if (result == ISC_R_SUCCESS) { 4235 dns_keytable_marksecure(sr, keyname); 4236 dns_keytable_detach(&sr); 4237 } 4238 } 4239 4240 /* 4241 * Scan a set of KEYDATA records from the key zone. The ones that are 4242 * valid (i.e., the add holddown timer has expired) become trusted keys. 4243 */ 4244 static void 4245 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) { 4246 isc_result_t result; 4247 dns_rdata_t rdata = DNS_RDATA_INIT; 4248 dns_rdata_keydata_t keydata; 4249 dns_rdata_dnskey_t dnskey; 4250 int trusted = 0, revoked = 0, pending = 0; 4251 isc_stdtime_t now = isc_stdtime_now(); 4252 dns_keytable_t *sr = NULL; 4253 4254 result = dns_view_getsecroots(zone->view, &sr); 4255 if (result == ISC_R_SUCCESS) { 4256 dns_keytable_delete(sr, name, sfd_del, zone->view); 4257 dns_keytable_detach(&sr); 4258 } 4259 4260 /* Now insert all the accepted trust anchors from this keydata set. */ 4261 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 4262 result = dns_rdataset_next(rdataset)) 4263 { 4264 dns_rdata_reset(&rdata); 4265 dns_rdataset_current(rdataset, &rdata); 4266 4267 /* Convert rdata to keydata. */ 4268 result = dns_rdata_tostruct(&rdata, &keydata, NULL); 4269 if (result == ISC_R_NOTIMPLEMENTED) { 4270 continue; 4271 } 4272 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4273 4274 /* Set the key refresh timer to force a fast refresh. */ 4275 set_refreshkeytimer(zone, &keydata, now, true); 4276 4277 /* If the removal timer is nonzero, this key was revoked. */ 4278 if (keydata.removehd != 0) { 4279 revoked++; 4280 continue; 4281 } 4282 4283 /* 4284 * If the add timer is still pending, this key is not 4285 * trusted yet. 4286 */ 4287 if (now < keydata.addhd) { 4288 pending++; 4289 continue; 4290 } 4291 4292 /* Convert keydata to dnskey. */ 4293 dns_keydata_todnskey(&keydata, &dnskey, NULL); 4294 4295 /* Add to keytables. */ 4296 trusted++; 4297 trust_key(zone, name, &dnskey, (keydata.addhd == 0)); 4298 } 4299 4300 if (trusted == 0 && pending != 0) { 4301 char namebuf[DNS_NAME_FORMATSIZE]; 4302 dns_name_format(name, namebuf, sizeof namebuf); 4303 dnssec_log(zone, ISC_LOG_ERROR, 4304 "No valid trust anchors for '%s'!", namebuf); 4305 dnssec_log(zone, ISC_LOG_ERROR, 4306 "%d key(s) revoked, %d still pending", revoked, 4307 pending); 4308 dnssec_log(zone, ISC_LOG_ERROR, "All queries to '%s' will fail", 4309 namebuf); 4310 fail_secure(zone, name); 4311 } 4312 } 4313 4314 static isc_result_t 4315 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, 4316 dns_diff_t *diff) { 4317 dns_diff_t temp_diff; 4318 isc_result_t result; 4319 4320 /* 4321 * Create a singleton diff. 4322 */ 4323 dns_diff_init(diff->mctx, &temp_diff); 4324 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); 4325 4326 /* 4327 * Apply it to the database. 4328 */ 4329 result = dns_diff_apply(&temp_diff, db, ver); 4330 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); 4331 if (result != ISC_R_SUCCESS) { 4332 dns_difftuple_free(tuple); 4333 return result; 4334 } 4335 4336 /* 4337 * Merge it into the current pending journal entry. 4338 */ 4339 dns_diff_appendminimal(diff, tuple); 4340 4341 /* 4342 * Do not clear temp_diff. 4343 */ 4344 return ISC_R_SUCCESS; 4345 } 4346 4347 static isc_result_t 4348 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 4349 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, 4350 dns_rdata_t *rdata) { 4351 dns_difftuple_t *tuple = NULL; 4352 isc_result_t result; 4353 result = dns_difftuple_create(diff->mctx, op, name, ttl, rdata, &tuple); 4354 if (result != ISC_R_SUCCESS) { 4355 return result; 4356 } 4357 return do_one_tuple(&tuple, db, ver, diff); 4358 } 4359 4360 static isc_result_t 4361 update_soa_serial(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 4362 dns_diff_t *diff, isc_mem_t *mctx, 4363 dns_updatemethod_t method) { 4364 dns_difftuple_t *deltuple = NULL; 4365 dns_difftuple_t *addtuple = NULL; 4366 uint32_t serial; 4367 isc_result_t result; 4368 dns_updatemethod_t used = dns_updatemethod_none; 4369 4370 INSIST(method != dns_updatemethod_none); 4371 4372 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple)); 4373 CHECK(dns_difftuple_copy(deltuple, &addtuple)); 4374 addtuple->op = DNS_DIFFOP_ADD; 4375 4376 serial = dns_soa_getserial(&addtuple->rdata); 4377 serial = dns_update_soaserial(serial, method, &used); 4378 if (method != used) { 4379 dns_zone_log(zone, ISC_LOG_WARNING, 4380 "update_soa_serial:new serial would be lower than " 4381 "old serial, using increment method instead"); 4382 } 4383 dns_soa_setserial(serial, &addtuple->rdata); 4384 CHECK(do_one_tuple(&deltuple, db, ver, diff)); 4385 CHECK(do_one_tuple(&addtuple, db, ver, diff)); 4386 result = ISC_R_SUCCESS; 4387 4388 failure: 4389 if (addtuple != NULL) { 4390 dns_difftuple_free(&addtuple); 4391 } 4392 if (deltuple != NULL) { 4393 dns_difftuple_free(&deltuple); 4394 } 4395 return result; 4396 } 4397 4398 /* 4399 * Write all transactions in 'diff' to the zone journal file. 4400 */ 4401 static isc_result_t 4402 zone_journal(dns_zone_t *zone, dns_diff_t *diff, uint32_t *sourceserial, 4403 const char *caller) { 4404 const char *journalfile; 4405 isc_result_t result = ISC_R_SUCCESS; 4406 dns_journal_t *journal = NULL; 4407 unsigned int mode = DNS_JOURNAL_CREATE | DNS_JOURNAL_WRITE; 4408 4409 ENTER; 4410 journalfile = dns_zone_getjournal(zone); 4411 if (journalfile != NULL) { 4412 result = dns_journal_open(zone->mctx, journalfile, mode, 4413 &journal); 4414 if (result != ISC_R_SUCCESS) { 4415 dns_zone_log(zone, ISC_LOG_ERROR, 4416 "%s:dns_journal_open -> %s", caller, 4417 isc_result_totext(result)); 4418 return result; 4419 } 4420 4421 if (sourceserial != NULL) { 4422 dns_journal_set_sourceserial(journal, *sourceserial); 4423 } 4424 4425 result = dns_journal_write_transaction(journal, diff); 4426 if (result != ISC_R_SUCCESS) { 4427 dns_zone_log(zone, ISC_LOG_ERROR, 4428 "%s:dns_journal_write_transaction -> %s", 4429 caller, isc_result_totext(result)); 4430 } 4431 dns_journal_destroy(&journal); 4432 } 4433 4434 return result; 4435 } 4436 4437 /* 4438 * Create an SOA record for a newly-created zone 4439 */ 4440 static isc_result_t 4441 add_soa(dns_zone_t *zone, dns_db_t *db) { 4442 isc_result_t result; 4443 dns_rdata_t rdata = DNS_RDATA_INIT; 4444 unsigned char buf[DNS_SOA_BUFFERSIZE]; 4445 dns_dbversion_t *ver = NULL; 4446 dns_diff_t diff; 4447 4448 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA"); 4449 4450 dns_diff_init(zone->mctx, &diff); 4451 result = dns_db_newversion(db, &ver); 4452 if (result != ISC_R_SUCCESS) { 4453 dns_zone_log(zone, ISC_LOG_ERROR, 4454 "add_soa:dns_db_newversion -> %s", 4455 isc_result_totext(result)); 4456 goto failure; 4457 } 4458 4459 /* Build SOA record */ 4460 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass, 4461 0, 0, 0, 0, 0, buf, &rdata); 4462 if (result != ISC_R_SUCCESS) { 4463 dns_zone_log(zone, ISC_LOG_ERROR, 4464 "add_soa:dns_soa_buildrdata -> %s", 4465 isc_result_totext(result)); 4466 goto failure; 4467 } 4468 4469 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD, &zone->origin, 0, 4470 &rdata); 4471 4472 failure: 4473 dns_diff_clear(&diff); 4474 if (ver != NULL) { 4475 dns_db_closeversion(db, &ver, (result == ISC_R_SUCCESS)); 4476 } 4477 4478 INSIST(ver == NULL); 4479 4480 return result; 4481 } 4482 4483 struct addifmissing_arg { 4484 dns_db_t *db; 4485 dns_dbversion_t *ver; 4486 dns_diff_t *diff; 4487 dns_zone_t *zone; 4488 bool *changed; 4489 isc_result_t result; 4490 }; 4491 4492 static void 4493 addifmissing(dns_keytable_t *keytable, dns_keynode_t *keynode, 4494 dns_name_t *keyname, void *arg) { 4495 dns_db_t *db = ((struct addifmissing_arg *)arg)->db; 4496 dns_dbversion_t *ver = ((struct addifmissing_arg *)arg)->ver; 4497 dns_diff_t *diff = ((struct addifmissing_arg *)arg)->diff; 4498 dns_zone_t *zone = ((struct addifmissing_arg *)arg)->zone; 4499 bool *changed = ((struct addifmissing_arg *)arg)->changed; 4500 isc_result_t result; 4501 dns_fixedname_t fname; 4502 4503 UNUSED(keytable); 4504 4505 if (((struct addifmissing_arg *)arg)->result != ISC_R_SUCCESS) { 4506 return; 4507 } 4508 4509 if (!dns_keynode_managed(keynode)) { 4510 return; 4511 } 4512 4513 /* 4514 * If the keynode has no trust anchor set, return. 4515 */ 4516 if (!dns_keynode_dsset(keynode, NULL)) { 4517 return; 4518 } 4519 4520 /* 4521 * Check whether there's already a KEYDATA entry for this name; 4522 * if so, we don't need to add another. 4523 */ 4524 dns_fixedname_init(&fname); 4525 result = dns_db_find(db, keyname, ver, dns_rdatatype_keydata, 4526 DNS_DBFIND_NOWILD, 0, NULL, 4527 dns_fixedname_name(&fname), NULL, NULL); 4528 if (result == ISC_R_SUCCESS) { 4529 return; 4530 } 4531 4532 /* 4533 * Create the keydata. 4534 */ 4535 result = create_keydata(zone, db, ver, diff, keynode, keyname, changed); 4536 if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) { 4537 ((struct addifmissing_arg *)arg)->result = result; 4538 } 4539 } 4540 4541 /* 4542 * Synchronize the set of initializing keys found in managed-keys {} 4543 * statements with the set of trust anchors found in the managed-keys.bind 4544 * zone. If a domain is no longer named in managed-keys, delete all keys 4545 * from that domain from the key zone. If a domain is configured as an 4546 * initial-key in trust-anchors, but there are no references to it in the 4547 * key zone, load the key zone with the initializing key(s) for that 4548 * domain and schedule a key refresh. If a domain is configured as 4549 * an initial-ds in trust-anchors, fetch the DNSKEY RRset, load the key 4550 * zone with the matching key, and schedule a key refresh. 4551 */ 4552 static isc_result_t 4553 sync_keyzone(dns_zone_t *zone, dns_db_t *db) { 4554 isc_result_t result = ISC_R_SUCCESS; 4555 bool changed = false; 4556 bool commit = false; 4557 dns_keynode_t *keynode = NULL; 4558 dns_view_t *view = zone->view; 4559 dns_keytable_t *sr = NULL; 4560 dns_dbversion_t *ver = NULL; 4561 dns_diff_t diff; 4562 dns_rriterator_t rrit; 4563 struct addifmissing_arg arg; 4564 4565 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys"); 4566 4567 dns_diff_init(zone->mctx, &diff); 4568 4569 CHECK(dns_view_getsecroots(view, &sr)); 4570 4571 result = dns_db_newversion(db, &ver); 4572 if (result != ISC_R_SUCCESS) { 4573 dnssec_log(zone, ISC_LOG_ERROR, 4574 "sync_keyzone:dns_db_newversion -> %s", 4575 isc_result_totext(result)); 4576 goto failure; 4577 } 4578 4579 /* 4580 * Walk the zone DB. If we find any keys whose names are no longer 4581 * in trust-anchors, or which have been changed from initial to static, 4582 * (meaning they are permanent and not RFC5011-maintained), delete 4583 * them from the zone. Otherwise call load_secroots(), which 4584 * loads keys into secroots as appropriate. 4585 */ 4586 dns_rriterator_init(&rrit, db, ver, 0); 4587 for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS; 4588 result = dns_rriterator_nextrrset(&rrit)) 4589 { 4590 dns_rdataset_t *rdataset = NULL; 4591 dns_rdata_t rdata = DNS_RDATA_INIT; 4592 dns_rdata_keydata_t keydata; 4593 isc_stdtime_t now = isc_stdtime_now(); 4594 bool load = true; 4595 dns_name_t *rrname = NULL; 4596 uint32_t ttl; 4597 4598 dns_rriterator_current(&rrit, &rrname, &ttl, &rdataset, NULL); 4599 if (!dns_rdataset_isassociated(rdataset)) { 4600 dns_rriterator_destroy(&rrit); 4601 goto failure; 4602 } 4603 4604 if (rdataset->type != dns_rdatatype_keydata) { 4605 continue; 4606 } 4607 4608 /* 4609 * The managed-keys zone can contain a placeholder instead of 4610 * legitimate data, in which case we will not use it, and we 4611 * will try to refresh it. 4612 */ 4613 for (result = dns_rdataset_first(rdataset); 4614 result == ISC_R_SUCCESS; 4615 result = dns_rdataset_next(rdataset)) 4616 { 4617 isc_result_t iresult; 4618 4619 dns_rdata_reset(&rdata); 4620 dns_rdataset_current(rdataset, &rdata); 4621 4622 iresult = dns_rdata_tostruct(&rdata, &keydata, NULL); 4623 /* Do we have a valid placeholder KEYDATA record? */ 4624 if (iresult == ISC_R_SUCCESS && keydata.flags == 0 && 4625 keydata.protocol == 0 && keydata.algorithm == 0) 4626 { 4627 set_refreshkeytimer(zone, &keydata, now, true); 4628 load = false; 4629 } 4630 } 4631 4632 /* 4633 * Release db wrlock to prevent LOR reports against 4634 * dns_keytable_forall() call below. 4635 */ 4636 dns_rriterator_pause(&rrit); 4637 result = dns_keytable_find(sr, rrname, &keynode); 4638 if (result != ISC_R_SUCCESS || !dns_keynode_managed(keynode)) { 4639 CHECK(delete_keydata(db, ver, &diff, rrname, rdataset)); 4640 changed = true; 4641 } else if (load) { 4642 load_secroots(zone, rrname, rdataset); 4643 } 4644 4645 if (keynode != NULL) { 4646 dns_keynode_detach(&keynode); 4647 } 4648 } 4649 dns_rriterator_destroy(&rrit); 4650 4651 /* 4652 * Walk secroots to find any initial keys that aren't in 4653 * the zone. If we find any, add them to the zone directly. 4654 * If any DS-style initial keys are found, refresh the key 4655 * zone so that they'll be looked up. 4656 */ 4657 arg.db = db; 4658 arg.ver = ver; 4659 arg.result = ISC_R_SUCCESS; 4660 arg.diff = &diff; 4661 arg.zone = zone; 4662 arg.changed = &changed; 4663 dns_keytable_forall(sr, addifmissing, &arg); 4664 result = arg.result; 4665 if (changed) { 4666 /* Write changes to journal file. */ 4667 CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx, 4668 zone->updatemethod)); 4669 CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone")); 4670 4671 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 4672 zone_needdump(zone, 30); 4673 commit = true; 4674 } 4675 4676 failure: 4677 if (result != ISC_R_SUCCESS) { 4678 dnssec_log(zone, ISC_LOG_ERROR, 4679 "unable to synchronize managed keys: %s", 4680 isc_result_totext(result)); 4681 isc_time_settoepoch(&zone->refreshkeytime); 4682 } 4683 if (keynode != NULL) { 4684 dns_keynode_detach(&keynode); 4685 } 4686 if (sr != NULL) { 4687 dns_keytable_detach(&sr); 4688 } 4689 if (ver != NULL) { 4690 dns_db_closeversion(db, &ver, commit); 4691 } 4692 dns_diff_clear(&diff); 4693 4694 INSIST(ver == NULL); 4695 4696 return result; 4697 } 4698 4699 isc_result_t 4700 dns_zone_synckeyzone(dns_zone_t *zone) { 4701 isc_result_t result; 4702 dns_db_t *db = NULL; 4703 4704 if (zone->type != dns_zone_key) { 4705 return DNS_R_BADZONE; 4706 } 4707 4708 CHECK(dns_zone_getdb(zone, &db)); 4709 4710 LOCK_ZONE(zone); 4711 result = sync_keyzone(zone, db); 4712 UNLOCK_ZONE(zone); 4713 4714 failure: 4715 if (db != NULL) { 4716 dns_db_detach(&db); 4717 } 4718 return result; 4719 } 4720 4721 static void 4722 maybe_send_secure(dns_zone_t *zone) { 4723 isc_result_t result; 4724 4725 /* 4726 * We've finished loading, or else failed to load, an inline-signing 4727 * 'secure' zone. We now need information about the status of the 4728 * 'raw' zone. If we failed to load, then we need it to send a 4729 * copy of its database; if we succeeded, we need it to send its 4730 * serial number so that we can sync with it. If it has not yet 4731 * loaded, we set a flag so that it will send the necessary 4732 * information when it has finished loading. 4733 */ 4734 if (zone->raw->db != NULL) { 4735 if (zone->db != NULL) { 4736 uint32_t serial; 4737 unsigned int soacount; 4738 4739 result = zone_get_from_db( 4740 zone->raw, zone->raw->db, NULL, &soacount, NULL, 4741 &serial, NULL, NULL, NULL, NULL, NULL); 4742 if (result == ISC_R_SUCCESS && soacount > 0U) { 4743 zone_send_secureserial(zone->raw, serial); 4744 } 4745 } else { 4746 zone_send_securedb(zone->raw, zone->raw->db); 4747 } 4748 } else { 4749 DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE); 4750 } 4751 } 4752 4753 static bool 4754 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) { 4755 isc_result_t result; 4756 bool answer = false; 4757 dns_diff_t diff; 4758 4759 dns_diff_init(mctx, &diff); 4760 result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL); 4761 if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples)) { 4762 answer = true; 4763 } 4764 dns_diff_clear(&diff); 4765 return answer; 4766 } 4767 4768 static void 4769 process_zone_setnsec3param(dns_zone_t *zone) { 4770 struct np3 *npe = NULL; 4771 while ((npe = ISC_LIST_HEAD(zone->setnsec3param_queue)) != NULL) { 4772 ISC_LIST_UNLINK(zone->setnsec3param_queue, npe, link); 4773 zone_iattach(zone, &npe->zone); 4774 isc_async_run(zone->loop, setnsec3param, npe); 4775 } 4776 } 4777 4778 /* 4779 * The zone is presumed to be locked. 4780 * If this is a inline_raw zone the secure version is also locked. 4781 */ 4782 static isc_result_t 4783 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, 4784 isc_result_t result) { 4785 unsigned int soacount = 0; 4786 unsigned int nscount = 0; 4787 unsigned int errors = 0; 4788 uint32_t serial, oldserial, refresh, retry, expire, minimum, soattl; 4789 isc_time_t now; 4790 bool needdump = false; 4791 bool fixjournal = false; 4792 bool hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE); 4793 bool noprimary = false; 4794 bool had_db = false; 4795 dns_include_t *inc; 4796 bool is_dynamic = false; 4797 4798 INSIST(LOCKED_ZONE(zone)); 4799 if (inline_raw(zone)) { 4800 INSIST(LOCKED_ZONE(zone->secure)); 4801 } 4802 4803 now = isc_time_now(); 4804 4805 /* 4806 * Initiate zone transfer? We may need a error code that 4807 * indicates that the "permanent" form does not exist. 4808 * XXX better error feedback to log. 4809 */ 4810 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { 4811 if (zone->type == dns_zone_secondary || 4812 zone->type == dns_zone_mirror || 4813 zone->type == dns_zone_stub || 4814 (zone->type == dns_zone_redirect && 4815 dns_remote_addresses(&zone->primaries) == NULL)) 4816 { 4817 if (result == ISC_R_FILENOTFOUND) { 4818 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4819 ISC_LOG_DEBUG(1), 4820 "no master file"); 4821 } else if (result != DNS_R_NOMASTERFILE) { 4822 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4823 ISC_LOG_ERROR, 4824 "loading from master file %s " 4825 "failed: %s", 4826 zone->masterfile, 4827 isc_result_totext(result)); 4828 } 4829 } else if (zone->type == dns_zone_primary && 4830 inline_secure(zone) && result == ISC_R_FILENOTFOUND) 4831 { 4832 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4833 ISC_LOG_DEBUG(1), 4834 "no master file, requesting db"); 4835 maybe_send_secure(zone); 4836 } else { 4837 int level = ISC_LOG_ERROR; 4838 if (zone->type == dns_zone_key && 4839 result == ISC_R_FILENOTFOUND) 4840 { 4841 level = ISC_LOG_DEBUG(1); 4842 } 4843 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, level, 4844 "loading from master file %s failed: %s", 4845 zone->masterfile, 4846 isc_result_totext(result)); 4847 noprimary = true; 4848 } 4849 4850 if (zone->type != dns_zone_key) { 4851 goto cleanup; 4852 } 4853 } 4854 4855 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(2), 4856 "number of nodes in database: %u", 4857 dns_db_nodecount(db, dns_dbtree_main)); 4858 4859 if (result == DNS_R_SEENINCLUDE) { 4860 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 4861 } else { 4862 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 4863 } 4864 4865 /* 4866 * If there's no master file for a key zone, then the zone is new: 4867 * create an SOA record. (We do this now, instead of later, so that 4868 * if there happens to be a journal file, we can roll forward from 4869 * a sane starting point.) 4870 */ 4871 if (noprimary && zone->type == dns_zone_key) { 4872 result = add_soa(zone, db); 4873 if (result != ISC_R_SUCCESS) { 4874 goto cleanup; 4875 } 4876 } 4877 4878 /* 4879 * Apply update log, if any, on initial load. 4880 */ 4881 if (zone->journal != NULL && 4882 !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) && 4883 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 4884 { 4885 result = zone_journal_rollforward(zone, db, &needdump, 4886 &fixjournal); 4887 if (result != ISC_R_SUCCESS) { 4888 goto cleanup; 4889 } 4890 } 4891 4892 /* 4893 * Obtain ns, soa and cname counts for top of zone. 4894 */ 4895 INSIST(db != NULL); 4896 result = zone_get_from_db(zone, db, &nscount, &soacount, &soattl, 4897 &serial, &refresh, &retry, &expire, &minimum, 4898 &errors); 4899 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) { 4900 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 4901 "could not find NS and/or SOA records"); 4902 } 4903 4904 /* 4905 * Process any queued NSEC3PARAM change requests. Only for dynamic 4906 * zones, an inline-signing zone will perform this action when 4907 * receiving the secure db (receive_secure_db). 4908 */ 4909 is_dynamic = dns_zone_isdynamic(zone, true); 4910 if (is_dynamic) { 4911 process_zone_setnsec3param(zone); 4912 } 4913 4914 /* 4915 * Check to make sure the journal is up to date, and remove the 4916 * journal file if it isn't, as we wouldn't be able to apply 4917 * updates otherwise. 4918 */ 4919 if (zone->journal != NULL && is_dynamic && 4920 !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) 4921 { 4922 uint32_t jserial; 4923 dns_journal_t *journal = NULL; 4924 bool empty = false; 4925 4926 result = dns_journal_open(zone->mctx, zone->journal, 4927 DNS_JOURNAL_READ, &journal); 4928 if (result == ISC_R_SUCCESS) { 4929 jserial = dns_journal_last_serial(journal); 4930 empty = dns_journal_empty(journal); 4931 dns_journal_destroy(&journal); 4932 } else { 4933 jserial = serial; 4934 result = ISC_R_SUCCESS; 4935 } 4936 4937 if (jserial != serial) { 4938 if (!empty) { 4939 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4940 ISC_LOG_INFO, 4941 "journal file is out of date: " 4942 "removing journal file"); 4943 } 4944 if (remove(zone->journal) < 0 && errno != ENOENT) { 4945 char strbuf[ISC_STRERRORSIZE]; 4946 strerror_r(errno, strbuf, sizeof(strbuf)); 4947 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 4948 DNS_LOGMODULE_ZONE, 4949 ISC_LOG_WARNING, 4950 "unable to remove journal " 4951 "'%s': '%s'", 4952 zone->journal, strbuf); 4953 } 4954 } 4955 } 4956 4957 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1), 4958 "loaded; checking validity"); 4959 4960 /* 4961 * Primary / Secondary / Mirror / Stub zones require both NS and SOA 4962 * records at the top of the zone. 4963 */ 4964 4965 switch (zone->type) { 4966 case dns_zone_dlz: 4967 case dns_zone_primary: 4968 case dns_zone_secondary: 4969 case dns_zone_mirror: 4970 case dns_zone_stub: 4971 case dns_zone_redirect: 4972 if (soacount != 1) { 4973 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4974 ISC_LOG_ERROR, "has %d SOA records", 4975 soacount); 4976 result = DNS_R_BADZONE; 4977 } 4978 if (nscount == 0) { 4979 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4980 ISC_LOG_ERROR, "has no NS records"); 4981 result = DNS_R_BADZONE; 4982 } 4983 if (result != ISC_R_SUCCESS) { 4984 goto cleanup; 4985 } 4986 if (zone->type == dns_zone_primary && errors != 0) { 4987 result = DNS_R_BADZONE; 4988 goto cleanup; 4989 } 4990 if (zone->type != dns_zone_stub && 4991 zone->type != dns_zone_redirect) 4992 { 4993 result = check_nsec3param(zone, db); 4994 if (result != ISC_R_SUCCESS) { 4995 goto cleanup; 4996 } 4997 } 4998 if (zone->type == dns_zone_primary && 4999 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) && 5000 !integrity_checks(zone, db)) 5001 { 5002 result = DNS_R_BADZONE; 5003 goto cleanup; 5004 } 5005 if (zone->type == dns_zone_primary && 5006 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) && 5007 !zone_check_dup(zone, db)) 5008 { 5009 result = DNS_R_BADZONE; 5010 goto cleanup; 5011 } 5012 5013 if (zone->type == dns_zone_primary) { 5014 result = dns_zone_cdscheck(zone, db, NULL); 5015 if (result != ISC_R_SUCCESS) { 5016 dns_zone_log(zone, ISC_LOG_ERROR, 5017 "CDS/CDNSKEY consistency checks " 5018 "failed"); 5019 goto cleanup; 5020 } 5021 } 5022 5023 result = dns_zone_verifydb(zone, db, NULL); 5024 if (result != ISC_R_SUCCESS) { 5025 goto cleanup; 5026 } 5027 5028 if (zone->db != NULL) { 5029 unsigned int oldsoacount; 5030 5031 /* 5032 * This is checked in zone_replacedb() for 5033 * secondary zones as they don't reload from disk. 5034 */ 5035 result = zone_get_from_db( 5036 zone, zone->db, NULL, &oldsoacount, NULL, 5037 &oldserial, NULL, NULL, NULL, NULL, NULL); 5038 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5039 RUNTIME_CHECK(oldsoacount > 0U); 5040 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 5041 !isc_serial_gt(serial, oldserial)) 5042 { 5043 uint32_t serialmin, serialmax; 5044 5045 INSIST(zone->type == dns_zone_primary); 5046 INSIST(zone->raw == NULL); 5047 5048 if (serial == oldserial && 5049 zone_unchanged(zone->db, db, zone->mctx)) 5050 { 5051 dns_zone_logc(zone, 5052 DNS_LOGCATEGORY_ZONELOAD, 5053 ISC_LOG_INFO, 5054 "ixfr-from-differences: " 5055 "unchanged"); 5056 zone->loadtime = loadtime; 5057 goto done; 5058 } 5059 5060 serialmin = (oldserial + 1) & 0xffffffffU; 5061 serialmax = (oldserial + 0x7fffffffU) & 5062 0xffffffffU; 5063 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5064 ISC_LOG_ERROR, 5065 "ixfr-from-differences: " 5066 "new serial (%u) out of range " 5067 "[%u - %u]", 5068 serial, serialmin, serialmax); 5069 result = DNS_R_BADZONE; 5070 goto cleanup; 5071 } else if (!isc_serial_ge(serial, oldserial)) { 5072 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5073 ISC_LOG_ERROR, 5074 "zone serial (%u/%u) has gone " 5075 "backwards", 5076 serial, oldserial); 5077 } else if (serial == oldserial && !hasinclude && 5078 strcmp(zone->db_argv[0], "_builtin") != 0) 5079 { 5080 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5081 ISC_LOG_ERROR, 5082 "zone serial (%u) unchanged. " 5083 "zone may fail to transfer " 5084 "to secondaries.", 5085 serial); 5086 } 5087 } 5088 5089 if (zone->type == dns_zone_primary && 5090 (zone->update_acl != NULL || zone->ssutable != NULL) && 5091 dns_zone_getsigresigninginterval(zone) < (3 * refresh) && 5092 dns_db_issecure(db)) 5093 { 5094 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5095 ISC_LOG_WARNING, 5096 "sig-re-signing-interval less than " 5097 "3 * refresh."); 5098 } 5099 5100 zone->refresh = RANGE(refresh, zone->minrefresh, 5101 zone->maxrefresh); 5102 zone->retry = RANGE(retry, zone->minretry, zone->maxretry); 5103 zone->expire = RANGE(expire, zone->refresh + zone->retry, 5104 DNS_MAX_EXPIRE); 5105 zone->soattl = soattl; 5106 zone->minimum = minimum; 5107 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 5108 5109 if (zone->type == dns_zone_secondary || 5110 zone->type == dns_zone_mirror || 5111 zone->type == dns_zone_stub || 5112 (zone->type == dns_zone_redirect && 5113 dns_remote_addresses(&zone->primaries) != NULL)) 5114 { 5115 isc_time_t t; 5116 uint32_t delay; 5117 5118 result = isc_file_getmodtime(zone->journal, &t); 5119 if (result != ISC_R_SUCCESS) { 5120 result = isc_file_getmodtime(zone->masterfile, 5121 &t); 5122 } 5123 if (result == ISC_R_SUCCESS) { 5124 DNS_ZONE_TIME_ADD(&t, zone->expire, 5125 &zone->expiretime); 5126 } else { 5127 DNS_ZONE_TIME_ADD(&now, zone->retry, 5128 &zone->expiretime); 5129 } 5130 5131 delay = (zone->retry - 5132 isc_random_uniform((zone->retry * 3) / 4)); 5133 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime); 5134 if (isc_time_compare(&zone->refreshtime, 5135 &zone->expiretime) >= 0) 5136 { 5137 DNS_ZONE_SETFLAG(zone, 5138 DNS_ZONEFLG_FIRSTREFRESH); 5139 zone->refreshtime = now; 5140 } else { 5141 /* The zone is up to date. */ 5142 DNS_ZONE_CLRFLAG(zone, 5143 DNS_ZONEFLG_FIRSTREFRESH); 5144 } 5145 } 5146 5147 break; 5148 5149 case dns_zone_key: 5150 /* Nothing needs to be done now */ 5151 break; 5152 5153 default: 5154 UNEXPECTED_ERROR("unexpected zone type %d", zone->type); 5155 result = ISC_R_UNEXPECTED; 5156 goto cleanup; 5157 } 5158 5159 /* 5160 * Check for weak DNSKEY's. 5161 */ 5162 if (zone->type == dns_zone_primary) { 5163 zone_check_dnskeys(zone, db); 5164 } 5165 5166 /* 5167 * Schedule DNSSEC key refresh. 5168 */ 5169 if (zone->type == dns_zone_primary && 5170 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 5171 { 5172 zone->refreshkeytime = now; 5173 } 5174 5175 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 5176 if (zone->db != NULL) { 5177 had_db = true; 5178 result = zone_replacedb(zone, db, false); 5179 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 5180 if (result != ISC_R_SUCCESS) { 5181 goto cleanup; 5182 } 5183 } else { 5184 zone_attachdb(zone, db); 5185 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 5186 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | 5187 DNS_ZONEFLG_NEEDSTARTUPNOTIFY); 5188 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) && 5189 inline_raw(zone)) 5190 { 5191 if (zone->secure->db == NULL) { 5192 zone_send_securedb(zone, db); 5193 } else { 5194 zone_send_secureserial(zone, serial); 5195 } 5196 } 5197 } 5198 5199 /* 5200 * Finished loading inline-signing zone; need to get status 5201 * from the raw side now. 5202 */ 5203 if (zone->type == dns_zone_primary && inline_secure(zone)) { 5204 maybe_send_secure(zone); 5205 } 5206 5207 result = ISC_R_SUCCESS; 5208 5209 if (fixjournal) { 5210 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FIXJOURNAL); 5211 zone_journal_compact(zone, zone->db, 0); 5212 } 5213 if (needdump) { 5214 if (zone->type == dns_zone_key) { 5215 zone_needdump(zone, 30); 5216 } else { 5217 zone_needdump(zone, DNS_DUMP_DELAY); 5218 } 5219 } 5220 5221 if (zone->loop != NULL) { 5222 if (zone->type == dns_zone_primary) { 5223 set_resigntime(zone); 5224 resume_signingwithkey(zone); 5225 resume_addnsec3chain(zone); 5226 } 5227 5228 is_dynamic = dns_zone_isdynamic(zone, false); 5229 if (zone->type == dns_zone_primary && is_dynamic && 5230 dns_db_issecure(db) && !inline_raw(zone)) 5231 { 5232 isc_stdtime_t resign; 5233 dns_name_t *name; 5234 dns_fixedname_t fixed; 5235 dns_typepair_t typepair; 5236 5237 name = dns_fixedname_initname(&fixed); 5238 5239 result = dns_db_getsigningtime(db, &resign, name, 5240 &typepair); 5241 if (result == ISC_R_SUCCESS) { 5242 isc_stdtime_t timenow = isc_stdtime_now(); 5243 char namebuf[DNS_NAME_FORMATSIZE]; 5244 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 5245 5246 dns_name_format(name, namebuf, sizeof(namebuf)); 5247 dns_rdatatype_format( 5248 DNS_TYPEPAIR_COVERS(typepair), typebuf, 5249 sizeof(typebuf)); 5250 dnssec_log( 5251 zone, ISC_LOG_DEBUG(3), 5252 "next resign: %s/%s " 5253 "in %d seconds", 5254 namebuf, typebuf, 5255 resign - timenow - 5256 dns_zone_getsigresigninginterval( 5257 zone)); 5258 } else { 5259 dnssec_log(zone, ISC_LOG_WARNING, 5260 "signed dynamic zone has no " 5261 "resign event scheduled"); 5262 } 5263 } 5264 5265 zone_settimer(zone, &now); 5266 } 5267 5268 /* 5269 * Clear old include list. 5270 */ 5271 for (inc = ISC_LIST_HEAD(zone->includes); inc != NULL; 5272 inc = ISC_LIST_HEAD(zone->includes)) 5273 { 5274 ISC_LIST_UNLINK(zone->includes, inc, link); 5275 isc_mem_free(zone->mctx, inc->name); 5276 isc_mem_put(zone->mctx, inc, sizeof(*inc)); 5277 } 5278 zone->nincludes = 0; 5279 5280 /* 5281 * Transfer new include list. 5282 */ 5283 for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; 5284 inc = ISC_LIST_HEAD(zone->newincludes)) 5285 { 5286 ISC_LIST_UNLINK(zone->newincludes, inc, link); 5287 ISC_LIST_APPEND(zone->includes, inc, link); 5288 zone->nincludes++; 5289 } 5290 5291 if (!dns_db_ispersistent(db)) { 5292 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO, 5293 "loaded serial %u%s", serial, 5294 dns_db_issecure(db) ? " (DNSSEC signed)" : ""); 5295 } 5296 5297 if (!had_db && zone->type == dns_zone_mirror) { 5298 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO, 5299 "mirror zone is now in use"); 5300 } 5301 5302 zone->loadtime = loadtime; 5303 goto done; 5304 5305 cleanup: 5306 if (result != ISC_R_SUCCESS) { 5307 dns_zone_rpz_disable_db(zone, db); 5308 dns_zone_catz_disable_db(zone, db); 5309 } 5310 5311 for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; 5312 inc = ISC_LIST_HEAD(zone->newincludes)) 5313 { 5314 ISC_LIST_UNLINK(zone->newincludes, inc, link); 5315 isc_mem_free(zone->mctx, inc->name); 5316 isc_mem_put(zone->mctx, inc, sizeof(*inc)); 5317 } 5318 if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror || 5319 zone->type == dns_zone_stub || zone->type == dns_zone_key || 5320 (zone->type == dns_zone_redirect && 5321 dns_remote_addresses(&zone->primaries) != NULL)) 5322 { 5323 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FIRSTREFRESH); 5324 5325 if (result != ISC_R_NOMEMORY) { 5326 if (zone->journal != NULL) { 5327 zone_saveunique(zone, zone->journal, 5328 "jn-XXXXXXXX"); 5329 } 5330 if (zone->masterfile != NULL) { 5331 zone_saveunique(zone, zone->masterfile, 5332 "db-XXXXXXXX"); 5333 } 5334 } 5335 5336 /* Mark the zone for immediate refresh. */ 5337 zone->refreshtime = now; 5338 if (zone->loop != NULL) { 5339 zone_settimer(zone, &now); 5340 } 5341 result = ISC_R_SUCCESS; 5342 } else if (zone->type == dns_zone_primary || 5343 zone->type == dns_zone_redirect) 5344 { 5345 if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND)) { 5346 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5347 ISC_LOG_ERROR, 5348 "not loaded due to errors."); 5349 } else if (zone->type == dns_zone_primary) { 5350 result = ISC_R_SUCCESS; 5351 } 5352 } 5353 5354 done: 5355 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); 5356 /* 5357 * If this is an inline-signed zone and we were called for the raw 5358 * zone, we need to clear DNS_ZONEFLG_LOADPENDING for the secure zone 5359 * as well, but only if this is a reload, not an initial zone load: in 5360 * the former case, zone_postload() will not be run for the secure 5361 * zone; in the latter case, it will be. Check which case we are 5362 * dealing with by consulting the DNS_ZONEFLG_LOADED flag for the 5363 * secure zone: if it is set, this must be a reload. 5364 */ 5365 if (inline_raw(zone) && DNS_ZONE_FLAG(zone->secure, DNS_ZONEFLG_LOADED)) 5366 { 5367 DNS_ZONE_CLRFLAG(zone->secure, DNS_ZONEFLG_LOADPENDING); 5368 /* 5369 * Re-start zone maintenance if it had been stalled 5370 * due to DNS_ZONEFLG_LOADPENDING being set when 5371 * zone_maintenance was called. 5372 */ 5373 if (zone->secure->loop != NULL) { 5374 zone_settimer(zone->secure, &now); 5375 } 5376 } 5377 5378 zone_debuglog(zone, __func__, 99, "done"); 5379 5380 return result; 5381 } 5382 5383 static bool 5384 exit_check(dns_zone_t *zone) { 5385 REQUIRE(LOCKED_ZONE(zone)); 5386 5387 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && 5388 isc_refcount_current(&zone->irefs) == 0) 5389 { 5390 /* 5391 * DNS_ZONEFLG_SHUTDOWN can only be set if references == 0. 5392 */ 5393 INSIST(isc_refcount_current(&zone->references) == 0); 5394 return true; 5395 } 5396 return false; 5397 } 5398 5399 static bool 5400 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 5401 dns_name_t *name, bool logit) { 5402 isc_result_t result; 5403 char namebuf[DNS_NAME_FORMATSIZE]; 5404 char altbuf[DNS_NAME_FORMATSIZE]; 5405 dns_fixedname_t fixed; 5406 dns_name_t *foundname; 5407 int level; 5408 5409 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) { 5410 return true; 5411 } 5412 5413 if (zone->type == dns_zone_primary) { 5414 level = ISC_LOG_ERROR; 5415 } else { 5416 level = ISC_LOG_WARNING; 5417 } 5418 5419 foundname = dns_fixedname_initname(&fixed); 5420 5421 result = dns_db_find(db, name, version, dns_rdatatype_a, 0, 0, NULL, 5422 foundname, NULL, NULL); 5423 if (result == ISC_R_SUCCESS) { 5424 return true; 5425 } 5426 5427 if (result == DNS_R_NXRRSET) { 5428 result = dns_db_find(db, name, version, dns_rdatatype_aaaa, 0, 5429 0, NULL, foundname, NULL, NULL); 5430 if (result == ISC_R_SUCCESS) { 5431 return true; 5432 } 5433 } 5434 5435 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 5436 result == DNS_R_EMPTYNAME) 5437 { 5438 if (logit) { 5439 dns_name_format(name, namebuf, sizeof namebuf); 5440 dns_zone_log(zone, level, 5441 "NS '%s' has no address " 5442 "records (A or AAAA)", 5443 namebuf); 5444 } 5445 return false; 5446 } 5447 5448 if (result == DNS_R_CNAME) { 5449 if (logit) { 5450 dns_name_format(name, namebuf, sizeof namebuf); 5451 dns_zone_log(zone, level, 5452 "NS '%s' is a CNAME " 5453 "(illegal)", 5454 namebuf); 5455 } 5456 return false; 5457 } 5458 5459 if (result == DNS_R_DNAME) { 5460 if (logit) { 5461 dns_name_format(name, namebuf, sizeof namebuf); 5462 dns_name_format(foundname, altbuf, sizeof altbuf); 5463 dns_zone_log(zone, level, 5464 "NS '%s' is below a DNAME " 5465 "'%s' (illegal)", 5466 namebuf, altbuf); 5467 } 5468 return false; 5469 } 5470 5471 return true; 5472 } 5473 5474 static isc_result_t 5475 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, 5476 dns_dbversion_t *version, unsigned int *nscount, 5477 unsigned int *errors, bool logit) { 5478 isc_result_t result; 5479 unsigned int count = 0; 5480 unsigned int ecount = 0; 5481 dns_rdataset_t rdataset; 5482 dns_rdata_t rdata; 5483 dns_rdata_ns_t ns; 5484 5485 dns_rdataset_init(&rdataset); 5486 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns, 5487 dns_rdatatype_none, 0, &rdataset, NULL); 5488 if (result == ISC_R_NOTFOUND) { 5489 INSIST(!dns_rdataset_isassociated(&rdataset)); 5490 goto success; 5491 } 5492 if (result != ISC_R_SUCCESS) { 5493 INSIST(!dns_rdataset_isassociated(&rdataset)); 5494 goto invalidate_rdataset; 5495 } 5496 5497 result = dns_rdataset_first(&rdataset); 5498 while (result == ISC_R_SUCCESS) { 5499 if (errors != NULL && zone->rdclass == dns_rdataclass_in && 5500 (zone->type == dns_zone_primary || 5501 zone->type == dns_zone_secondary || 5502 zone->type == dns_zone_mirror)) 5503 { 5504 dns_rdata_init(&rdata); 5505 dns_rdataset_current(&rdataset, &rdata); 5506 result = dns_rdata_tostruct(&rdata, &ns, NULL); 5507 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5508 if (dns_name_issubdomain(&ns.name, &zone->origin) && 5509 !zone_check_ns(zone, db, version, &ns.name, logit)) 5510 { 5511 ecount++; 5512 } 5513 } 5514 count++; 5515 result = dns_rdataset_next(&rdataset); 5516 } 5517 dns_rdataset_disassociate(&rdataset); 5518 5519 success: 5520 SET_IF_NOT_NULL(nscount, count); 5521 SET_IF_NOT_NULL(errors, ecount); 5522 5523 result = ISC_R_SUCCESS; 5524 5525 invalidate_rdataset: 5526 dns_rdataset_invalidate(&rdataset); 5527 5528 return result; 5529 } 5530 5531 #define SET_SOA_VALUES(soattl_v, serial_v, refresh_v, retry_v, expire_v, \ 5532 minimum_v) \ 5533 { \ 5534 SET_IF_NOT_NULL(soattl, soattl_v); \ 5535 SET_IF_NOT_NULL(serial, serial_v); \ 5536 SET_IF_NOT_NULL(refresh, refresh_v); \ 5537 SET_IF_NOT_NULL(retry, retry_v); \ 5538 SET_IF_NOT_NULL(expire, expire_v); \ 5539 SET_IF_NOT_NULL(minimum, minimum_v); \ 5540 } 5541 5542 #define CLR_SOA_VALUES() \ 5543 { \ 5544 SET_SOA_VALUES(0, 0, 0, 0, 0, 0); \ 5545 } 5546 5547 static isc_result_t 5548 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 5549 unsigned int *soacount, uint32_t *soattl, uint32_t *serial, 5550 uint32_t *refresh, uint32_t *retry, uint32_t *expire, 5551 uint32_t *minimum) { 5552 isc_result_t result; 5553 unsigned int count = 0; 5554 dns_rdataset_t rdataset; 5555 dns_rdata_t rdata = DNS_RDATA_INIT; 5556 5557 dns_rdataset_init(&rdataset); 5558 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, 5559 dns_rdatatype_none, 0, &rdataset, NULL); 5560 if (result == ISC_R_NOTFOUND) { 5561 INSIST(!dns_rdataset_isassociated(&rdataset)); 5562 result = ISC_R_SUCCESS; 5563 goto invalidate_rdataset; 5564 } 5565 if (result != ISC_R_SUCCESS) { 5566 INSIST(!dns_rdataset_isassociated(&rdataset)); 5567 goto invalidate_rdataset; 5568 } 5569 5570 result = dns_rdataset_first(&rdataset); 5571 while (result == ISC_R_SUCCESS) { 5572 dns_rdata_init(&rdata); 5573 dns_rdataset_current(&rdataset, &rdata); 5574 count++; 5575 if (count == 1) { 5576 dns_rdata_soa_t soa; 5577 result = dns_rdata_tostruct(&rdata, &soa, NULL); 5578 SET_SOA_VALUES(rdataset.ttl, soa.serial, soa.refresh, 5579 soa.retry, soa.expire, soa.minimum); 5580 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5581 } 5582 5583 result = dns_rdataset_next(&rdataset); 5584 dns_rdata_reset(&rdata); 5585 } 5586 dns_rdataset_disassociate(&rdataset); 5587 5588 result = ISC_R_SUCCESS; 5589 5590 invalidate_rdataset: 5591 SET_IF_NOT_NULL(soacount, count); 5592 if (count == 0) { 5593 CLR_SOA_VALUES(); 5594 } 5595 5596 dns_rdataset_invalidate(&rdataset); 5597 5598 return result; 5599 } 5600 5601 /* 5602 * zone must be locked. 5603 */ 5604 static isc_result_t 5605 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 5606 unsigned int *soacount, uint32_t *soattl, uint32_t *serial, 5607 uint32_t *refresh, uint32_t *retry, uint32_t *expire, 5608 uint32_t *minimum, unsigned int *errors) { 5609 isc_result_t result; 5610 isc_result_t answer = ISC_R_SUCCESS; 5611 dns_dbversion_t *version = NULL; 5612 dns_dbnode_t *node; 5613 5614 REQUIRE(db != NULL); 5615 REQUIRE(zone != NULL); 5616 5617 dns_db_currentversion(db, &version); 5618 5619 SET_IF_NOT_NULL(nscount, 0); 5620 SET_IF_NOT_NULL(soacount, 0); 5621 SET_IF_NOT_NULL(errors, 0); 5622 CLR_SOA_VALUES(); 5623 5624 node = NULL; 5625 result = dns_db_findnode(db, &zone->origin, false, &node); 5626 if (result != ISC_R_SUCCESS) { 5627 answer = result; 5628 goto closeversion; 5629 } 5630 5631 if (nscount != NULL || errors != NULL) { 5632 result = zone_count_ns_rr(zone, db, node, version, nscount, 5633 errors, true); 5634 if (result != ISC_R_SUCCESS) { 5635 answer = result; 5636 } 5637 } 5638 5639 if (soacount != NULL || soattl != NULL || serial != NULL || 5640 refresh != NULL || retry != NULL || expire != NULL || 5641 minimum != NULL) 5642 { 5643 result = zone_load_soa_rr(db, node, version, soacount, soattl, 5644 serial, refresh, retry, expire, 5645 minimum); 5646 if (result != ISC_R_SUCCESS) { 5647 answer = result; 5648 } 5649 } 5650 5651 dns_db_detachnode(db, &node); 5652 closeversion: 5653 dns_db_closeversion(db, &version, false); 5654 5655 return answer; 5656 } 5657 5658 static void 5659 zone_destroy(dns_zone_t *zone) { 5660 /* 5661 * Stop things being restarted after we cancel them below. 5662 */ 5663 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING); 5664 dns_zone_log(zone, ISC_LOG_DEBUG(1), "final reference detached"); 5665 5666 if (zone->loop == NULL) { 5667 /* 5668 * This zone is unmanaged; we're probably running in 5669 * named-checkzone or a unit test. There's no loop, so we 5670 * need to free it immediately. 5671 */ 5672 zone_shutdown(zone); 5673 } else { 5674 /* 5675 * This zone has a loop; it can clean 5676 * itself up asynchronously. 5677 */ 5678 isc_async_run(zone->loop, zone_shutdown, zone); 5679 } 5680 } 5681 5682 #if DNS_ZONE_TRACE 5683 ISC_REFCOUNT_TRACE_IMPL(dns_zone, zone_destroy); 5684 #else 5685 ISC_REFCOUNT_IMPL(dns_zone, zone_destroy); 5686 #endif 5687 5688 void 5689 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) { 5690 REQUIRE(DNS_ZONE_VALID(source)); 5691 5692 LOCK_ZONE(source); 5693 zone_iattach(source, target); 5694 UNLOCK_ZONE(source); 5695 } 5696 5697 static void 5698 zone_iattach(dns_zone_t *source, dns_zone_t **target) { 5699 REQUIRE(DNS_ZONE_VALID(source)); 5700 REQUIRE(LOCKED_ZONE(source)); 5701 REQUIRE(target != NULL && *target == NULL); 5702 INSIST(isc_refcount_increment0(&source->irefs) + 5703 isc_refcount_current(&source->references) > 5704 0); 5705 *target = source; 5706 } 5707 5708 static void 5709 zone_idetach(dns_zone_t **zonep) { 5710 dns_zone_t *zone; 5711 5712 /* 5713 * 'zone' locked by caller. 5714 */ 5715 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 5716 REQUIRE(LOCKED_ZONE(*zonep)); 5717 5718 zone = *zonep; 5719 *zonep = NULL; 5720 5721 INSIST(isc_refcount_decrement(&zone->irefs) - 1 + 5722 isc_refcount_current(&zone->references) > 5723 0); 5724 } 5725 5726 void 5727 dns_zone_idetach(dns_zone_t **zonep) { 5728 dns_zone_t *zone; 5729 5730 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 5731 5732 zone = *zonep; 5733 *zonep = NULL; 5734 5735 if (isc_refcount_decrement(&zone->irefs) == 1) { 5736 bool free_needed; 5737 LOCK_ZONE(zone); 5738 free_needed = exit_check(zone); 5739 UNLOCK_ZONE(zone); 5740 if (free_needed) { 5741 zone_free(zone); 5742 } 5743 } 5744 } 5745 5746 isc_mem_t * 5747 dns_zone_getmctx(dns_zone_t *zone) { 5748 REQUIRE(DNS_ZONE_VALID(zone)); 5749 5750 return zone->mctx; 5751 } 5752 5753 dns_zonemgr_t * 5754 dns_zone_getmgr(dns_zone_t *zone) { 5755 REQUIRE(DNS_ZONE_VALID(zone)); 5756 5757 return zone->zmgr; 5758 } 5759 5760 void 5761 dns_zone_setkasp(dns_zone_t *zone, dns_kasp_t *kasp) { 5762 REQUIRE(DNS_ZONE_VALID(zone)); 5763 5764 LOCK_ZONE(zone); 5765 if (zone->kasp != NULL) { 5766 dns_kasp_detach(&zone->kasp); 5767 } 5768 if (kasp != NULL) { 5769 dns_kasp_attach(kasp, &zone->kasp); 5770 } 5771 UNLOCK_ZONE(zone); 5772 } 5773 5774 void 5775 dns_zone_setdefaultkasp(dns_zone_t *zone, dns_kasp_t *kasp) { 5776 REQUIRE(DNS_ZONE_VALID(zone)); 5777 5778 LOCK_ZONE(zone); 5779 if (zone->defaultkasp != NULL) { 5780 dns_kasp_detach(&zone->defaultkasp); 5781 } 5782 if (kasp != NULL) { 5783 dns_kasp_attach(kasp, &zone->defaultkasp); 5784 } 5785 UNLOCK_ZONE(zone); 5786 } 5787 5788 dns_kasp_t * 5789 dns_zone_getkasp(dns_zone_t *zone) { 5790 dns_kasp_t *kasp; 5791 5792 REQUIRE(DNS_ZONE_VALID(zone)); 5793 5794 LOCK_ZONE(zone); 5795 if (inline_raw(zone) && zone->secure != NULL) { 5796 kasp = zone->secure->kasp; 5797 } else { 5798 kasp = zone->kasp; 5799 } 5800 UNLOCK_ZONE(zone); 5801 5802 return kasp; 5803 } 5804 5805 static void 5806 dns_zone_setskr(dns_zone_t *zone, dns_skr_t *skr) { 5807 REQUIRE(DNS_ZONE_VALID(zone)); 5808 5809 LOCK_ZONE(zone); 5810 zone->skrbundle = NULL; 5811 if (zone->skr != NULL) { 5812 dns_skr_detach(&zone->skr); 5813 } 5814 if (skr != NULL) { 5815 dns_skr_attach(skr, &zone->skr); 5816 } 5817 UNLOCK_ZONE(zone); 5818 } 5819 5820 dns_skrbundle_t * 5821 dns_zone_getskrbundle(dns_zone_t *zone) { 5822 dns_skrbundle_t *bundle; 5823 5824 REQUIRE(DNS_ZONE_VALID(zone)); 5825 5826 LOCK_ZONE(zone); 5827 if (inline_raw(zone) && zone->secure != NULL) { 5828 bundle = zone->secure->skrbundle; 5829 } else { 5830 bundle = zone->skrbundle; 5831 } 5832 UNLOCK_ZONE(zone); 5833 5834 return bundle; 5835 } 5836 5837 void 5838 dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option, bool value) { 5839 REQUIRE(DNS_ZONE_VALID(zone)); 5840 5841 if (value) { 5842 DNS_ZONE_SETOPTION(zone, option); 5843 } else { 5844 DNS_ZONE_CLROPTION(zone, option); 5845 } 5846 } 5847 5848 dns_zoneopt_t 5849 dns_zone_getoptions(dns_zone_t *zone) { 5850 REQUIRE(DNS_ZONE_VALID(zone)); 5851 5852 return ISC_ZONE_GET(zone, options); 5853 } 5854 5855 void 5856 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, bool value) { 5857 REQUIRE(DNS_ZONE_VALID(zone)); 5858 5859 if (value) { 5860 DNS_ZONEKEY_SETOPTION(zone, keyopt); 5861 } else { 5862 DNS_ZONEKEY_CLROPTION(zone, keyopt); 5863 } 5864 } 5865 5866 unsigned int 5867 dns_zone_getkeyopts(dns_zone_t *zone) { 5868 REQUIRE(DNS_ZONE_VALID(zone)); 5869 5870 return ISC_ZONE_GET(zone, keyopts); 5871 } 5872 5873 isc_result_t 5874 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 5875 REQUIRE(DNS_ZONE_VALID(zone)); 5876 5877 LOCK_ZONE(zone); 5878 zone->xfrsource4 = *xfrsource; 5879 UNLOCK_ZONE(zone); 5880 5881 return ISC_R_SUCCESS; 5882 } 5883 5884 isc_sockaddr_t * 5885 dns_zone_getxfrsource4(dns_zone_t *zone) { 5886 REQUIRE(DNS_ZONE_VALID(zone)); 5887 return &zone->xfrsource4; 5888 } 5889 5890 isc_result_t 5891 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 5892 REQUIRE(DNS_ZONE_VALID(zone)); 5893 5894 LOCK_ZONE(zone); 5895 zone->xfrsource6 = *xfrsource; 5896 UNLOCK_ZONE(zone); 5897 5898 return ISC_R_SUCCESS; 5899 } 5900 5901 isc_sockaddr_t * 5902 dns_zone_getxfrsource6(dns_zone_t *zone) { 5903 REQUIRE(DNS_ZONE_VALID(zone)); 5904 return &zone->xfrsource6; 5905 } 5906 5907 isc_result_t 5908 dns_zone_setparentalsrc4(dns_zone_t *zone, const isc_sockaddr_t *parentalsrc) { 5909 REQUIRE(DNS_ZONE_VALID(zone)); 5910 5911 LOCK_ZONE(zone); 5912 zone->parentalsrc4 = *parentalsrc; 5913 UNLOCK_ZONE(zone); 5914 5915 return ISC_R_SUCCESS; 5916 } 5917 5918 isc_sockaddr_t * 5919 dns_zone_getparentalsrc4(dns_zone_t *zone) { 5920 REQUIRE(DNS_ZONE_VALID(zone)); 5921 return &zone->parentalsrc4; 5922 } 5923 5924 isc_result_t 5925 dns_zone_setparentalsrc6(dns_zone_t *zone, const isc_sockaddr_t *parentalsrc) { 5926 REQUIRE(DNS_ZONE_VALID(zone)); 5927 5928 LOCK_ZONE(zone); 5929 zone->parentalsrc6 = *parentalsrc; 5930 UNLOCK_ZONE(zone); 5931 5932 return ISC_R_SUCCESS; 5933 } 5934 5935 isc_sockaddr_t * 5936 dns_zone_getparentalsrc6(dns_zone_t *zone) { 5937 REQUIRE(DNS_ZONE_VALID(zone)); 5938 return &zone->parentalsrc6; 5939 } 5940 5941 isc_result_t 5942 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 5943 REQUIRE(DNS_ZONE_VALID(zone)); 5944 5945 LOCK_ZONE(zone); 5946 zone->notifysrc4 = *notifysrc; 5947 UNLOCK_ZONE(zone); 5948 5949 return ISC_R_SUCCESS; 5950 } 5951 5952 isc_sockaddr_t * 5953 dns_zone_getnotifysrc4(dns_zone_t *zone) { 5954 REQUIRE(DNS_ZONE_VALID(zone)); 5955 return &zone->notifysrc4; 5956 } 5957 5958 isc_result_t 5959 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 5960 REQUIRE(DNS_ZONE_VALID(zone)); 5961 5962 LOCK_ZONE(zone); 5963 zone->notifysrc6 = *notifysrc; 5964 UNLOCK_ZONE(zone); 5965 5966 return ISC_R_SUCCESS; 5967 } 5968 5969 isc_sockaddr_t * 5970 dns_zone_getnotifysrc6(dns_zone_t *zone) { 5971 REQUIRE(DNS_ZONE_VALID(zone)); 5972 return &zone->notifysrc6; 5973 } 5974 5975 void 5976 dns_zone_setalsonotify(dns_zone_t *zone, isc_sockaddr_t *addresses, 5977 isc_sockaddr_t *sources, dns_name_t **keynames, 5978 dns_name_t **tlsnames, uint32_t count) { 5979 dns_remote_t remote; 5980 5981 REQUIRE(DNS_ZONE_VALID(zone)); 5982 5983 LOCK_ZONE(zone); 5984 5985 remote.magic = DNS_REMOTE_MAGIC; 5986 remote.addresses = addresses; 5987 remote.sources = sources; 5988 remote.keynames = keynames; 5989 remote.tlsnames = tlsnames; 5990 remote.addrcnt = count; 5991 5992 if (dns_remote_equal(&zone->notify, &remote)) { 5993 goto unlock; 5994 } 5995 5996 dns_remote_clear(&zone->notify); 5997 5998 /* 5999 * If count == 0, don't allocate any space for servers to notify. 6000 */ 6001 if (count == 0) { 6002 goto unlock; 6003 } 6004 6005 /* 6006 * Now set up the notify address and key lists. 6007 */ 6008 dns_remote_init(&zone->notify, count, addresses, sources, keynames, 6009 tlsnames, true, zone->mctx); 6010 6011 unlock: 6012 UNLOCK_ZONE(zone); 6013 } 6014 6015 static bool 6016 has_pf(isc_sockaddr_t *addresses, size_t count, int pf) { 6017 for (size_t i = 0; i < count; i++) { 6018 if (isc_sockaddr_pf(&addresses[i]) == pf) { 6019 return true; 6020 } 6021 } 6022 return false; 6023 } 6024 6025 static void 6026 report_no_active_addresses(dns_zone_t *zone, isc_sockaddr_t *addresses, 6027 size_t count, const char *what) { 6028 if (isc_net_probeipv4() == ISC_R_DISABLED) { 6029 if (!has_pf(addresses, count, AF_INET6)) { 6030 dns_zone_log(zone, ISC_LOG_NOTICE, 6031 "IPv4 disabled and no IPv6 %s", what); 6032 } 6033 } else if (isc_net_probeipv6() == ISC_R_DISABLED) { 6034 if (!has_pf(addresses, count, AF_INET)) { 6035 dns_zone_log(zone, ISC_LOG_NOTICE, 6036 "IPv6 disabled and no IPv4 %s", what); 6037 } 6038 } 6039 } 6040 6041 void 6042 dns_zone_setprimaries(dns_zone_t *zone, isc_sockaddr_t *addresses, 6043 isc_sockaddr_t *sources, dns_name_t **keynames, 6044 dns_name_t **tlsnames, uint32_t count) { 6045 dns_remote_t remote; 6046 6047 REQUIRE(DNS_ZONE_VALID(zone)); 6048 6049 LOCK_ZONE(zone); 6050 6051 remote.magic = DNS_REMOTE_MAGIC; 6052 remote.addresses = addresses; 6053 remote.sources = sources; 6054 remote.keynames = keynames; 6055 remote.tlsnames = tlsnames; 6056 remote.addrcnt = count; 6057 6058 /* 6059 * The refresh code assumes that 'primaries' wouldn't change under it. 6060 * If it will change then kill off any current refresh in progress 6061 * and update the primaries info. If it won't change then we can just 6062 * unlock and exit. 6063 */ 6064 if (!dns_remote_equal(&zone->primaries, &remote)) { 6065 if (zone->request != NULL) { 6066 dns_request_cancel(zone->request); 6067 } 6068 } else { 6069 goto unlock; 6070 } 6071 6072 dns_remote_clear(&zone->primaries); 6073 6074 /* 6075 * If count == 0, don't allocate any space for primaries. 6076 */ 6077 if (count == 0) { 6078 goto unlock; 6079 } 6080 6081 report_no_active_addresses(zone, addresses, count, "primaries"); 6082 6083 /* 6084 * Now set up the primaries and primary key lists. 6085 */ 6086 dns_remote_init(&zone->primaries, count, addresses, sources, keynames, 6087 tlsnames, true, zone->mctx); 6088 6089 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOPRIMARIES); 6090 6091 unlock: 6092 UNLOCK_ZONE(zone); 6093 } 6094 6095 void 6096 dns_zone_setparentals(dns_zone_t *zone, isc_sockaddr_t *addresses, 6097 isc_sockaddr_t *sources, dns_name_t **keynames, 6098 dns_name_t **tlsnames, uint32_t count) { 6099 dns_remote_t remote; 6100 6101 REQUIRE(DNS_ZONE_VALID(zone)); 6102 6103 LOCK_ZONE(zone); 6104 6105 remote.magic = DNS_REMOTE_MAGIC; 6106 remote.addresses = addresses; 6107 remote.sources = sources; 6108 remote.keynames = keynames; 6109 remote.tlsnames = tlsnames; 6110 remote.addrcnt = count; 6111 6112 if (dns_remote_equal(&zone->parentals, &remote)) { 6113 goto unlock; 6114 } 6115 6116 dns_remote_clear(&zone->parentals); 6117 6118 /* 6119 * If count == 0, don't allocate any space for parentals. 6120 */ 6121 if (count == 0) { 6122 goto unlock; 6123 } 6124 6125 report_no_active_addresses(zone, addresses, count, "parental-agents"); 6126 6127 /* 6128 * Now set up the parentals and parental key lists. 6129 */ 6130 dns_remote_init(&zone->parentals, count, addresses, sources, keynames, 6131 tlsnames, true, zone->mctx); 6132 6133 dns_zone_log(zone, ISC_LOG_NOTICE, "checkds: set %u parentals", count); 6134 6135 unlock: 6136 UNLOCK_ZONE(zone); 6137 } 6138 6139 isc_result_t 6140 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) { 6141 isc_result_t result = ISC_R_SUCCESS; 6142 6143 REQUIRE(DNS_ZONE_VALID(zone)); 6144 6145 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 6146 if (zone->db == NULL) { 6147 result = DNS_R_NOTLOADED; 6148 } else { 6149 dns_db_attach(zone->db, dpb); 6150 } 6151 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 6152 6153 return result; 6154 } 6155 6156 void 6157 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) { 6158 REQUIRE(DNS_ZONE_VALID(zone)); 6159 REQUIRE(zone->type == dns_zone_staticstub); 6160 6161 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 6162 REQUIRE(zone->db == NULL); 6163 dns_db_attach(db, &zone->db); 6164 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 6165 } 6166 6167 static bool 6168 was_dumping(dns_zone_t *zone) { 6169 REQUIRE(LOCKED_ZONE(zone)); 6170 6171 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 6172 return true; 6173 } 6174 6175 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 6176 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 6177 isc_time_settoepoch(&zone->dumptime); 6178 return false; 6179 } 6180 6181 static isc_result_t 6182 keyfromfile(dns_zone_t *zone, dst_key_t *pubkey, isc_mem_t *mctx, 6183 dst_key_t **key) { 6184 const char *directory = zone->keydirectory; 6185 dns_kasp_t *kasp = zone->kasp; 6186 dst_key_t *foundkey = NULL; 6187 isc_result_t result = ISC_R_NOTFOUND; 6188 6189 if (kasp == NULL || (strcmp(dns_kasp_getname(kasp), "none") == 0) || 6190 (strcmp(dns_kasp_getname(kasp), "insecure") == 0)) 6191 { 6192 result = dst_key_fromfile( 6193 dst_key_name(pubkey), dst_key_id(pubkey), 6194 dst_key_alg(pubkey), 6195 (DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_STATE), 6196 directory, mctx, &foundkey); 6197 } else { 6198 for (dns_kasp_key_t *kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); 6199 kkey != NULL; kkey = ISC_LIST_NEXT(kkey, link)) 6200 { 6201 dns_keystore_t *ks = dns_kasp_key_keystore(kkey); 6202 directory = dns_keystore_directory(ks, 6203 zone->keydirectory); 6204 6205 result = dst_key_fromfile( 6206 dst_key_name(pubkey), dst_key_id(pubkey), 6207 dst_key_alg(pubkey), 6208 (DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | 6209 DST_TYPE_STATE), 6210 directory, mctx, &foundkey); 6211 if (result == ISC_R_SUCCESS) { 6212 break; 6213 } 6214 } 6215 } 6216 6217 *key = foundkey; 6218 return result; 6219 } 6220 6221 #define is_zone_key(key) \ 6222 ((dst_key_flags(key) & DNS_KEYFLAG_OWNERMASK) == DNS_KEYOWNER_ZONE) 6223 6224 static isc_result_t 6225 findzonekeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 6226 dns_dbnode_t *node, const dns_name_t *name, isc_stdtime_t now, 6227 isc_mem_t *mctx, unsigned int maxkeys, dst_key_t **keys, 6228 unsigned int *nkeys) { 6229 dns_rdataset_t rdataset; 6230 dns_rdata_t rdata = DNS_RDATA_INIT; 6231 isc_result_t result; 6232 dst_key_t *pubkey = NULL; 6233 unsigned int count = 0; 6234 6235 *nkeys = 0; 6236 memset(keys, 0, sizeof(*keys) * maxkeys); 6237 dns_rdataset_init(&rdataset); 6238 RETERR(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0, 6239 &rdataset, NULL)); 6240 RETERR(dns_rdataset_first(&rdataset)); 6241 while (result == ISC_R_SUCCESS && count < maxkeys) { 6242 pubkey = NULL; 6243 dns_rdataset_current(&rdataset, &rdata); 6244 RETERR(dns_dnssec_keyfromrdata(name, &rdata, mctx, &pubkey)); 6245 dst_key_setttl(pubkey, rdataset.ttl); 6246 6247 if (!is_zone_key(pubkey) || 6248 (dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0) 6249 { 6250 goto next; 6251 } 6252 /* Corrupted .key file? */ 6253 if (!dns_name_equal(name, dst_key_name(pubkey))) { 6254 goto next; 6255 } 6256 keys[count] = NULL; 6257 result = keyfromfile(zone, pubkey, mctx, &keys[count]); 6258 6259 /* 6260 * If the key was revoked and the private file 6261 * doesn't exist, maybe it was revoked internally 6262 * by named. Try loading the unrevoked version. 6263 */ 6264 if (result == ISC_R_FILENOTFOUND) { 6265 uint32_t flags; 6266 flags = dst_key_flags(pubkey); 6267 if ((flags & DNS_KEYFLAG_REVOKE) != 0) { 6268 dst_key_setflags(pubkey, 6269 flags & ~DNS_KEYFLAG_REVOKE); 6270 result = keyfromfile(zone, pubkey, mctx, 6271 &keys[count]); 6272 if (result == ISC_R_SUCCESS && 6273 dst_key_pubcompare(pubkey, keys[count], 6274 false)) 6275 { 6276 dst_key_setflags(keys[count], flags); 6277 } 6278 dst_key_setflags(pubkey, flags); 6279 } 6280 } 6281 6282 if (result != ISC_R_SUCCESS) { 6283 char filename[DNS_NAME_FORMATSIZE + 6284 DNS_SECALG_FORMATSIZE + 6285 sizeof("key file for //65535")]; 6286 isc_result_t result2; 6287 isc_buffer_t buf; 6288 6289 isc_buffer_init(&buf, filename, sizeof(filename)); 6290 result2 = dst_key_getfilename( 6291 dst_key_name(pubkey), dst_key_id(pubkey), 6292 dst_key_alg(pubkey), 6293 (DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | 6294 DST_TYPE_STATE), 6295 NULL, mctx, &buf); 6296 if (result2 != ISC_R_SUCCESS) { 6297 char namebuf[DNS_NAME_FORMATSIZE]; 6298 char algbuf[DNS_SECALG_FORMATSIZE]; 6299 6300 dns_name_format(dst_key_name(pubkey), namebuf, 6301 sizeof(namebuf)); 6302 dns_secalg_format(dst_key_alg(pubkey), algbuf, 6303 sizeof(algbuf)); 6304 snprintf(filename, sizeof(filename) - 1, 6305 "key file for %s/%s/%d", namebuf, 6306 algbuf, dst_key_id(pubkey)); 6307 } 6308 6309 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 6310 DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING, 6311 "dns_zone_findkeys: error reading %s: %s", 6312 filename, isc_result_totext(result)); 6313 } 6314 6315 if (result == ISC_R_FILENOTFOUND || result == ISC_R_NOPERM) { 6316 keys[count] = pubkey; 6317 pubkey = NULL; 6318 count++; 6319 goto next; 6320 } 6321 6322 if (result != ISC_R_SUCCESS) { 6323 goto failure; 6324 } 6325 6326 /* 6327 * If a key is marked inactive, skip it 6328 */ 6329 if (!dns_dnssec_keyactive(keys[count], now)) { 6330 dst_key_setinactive(pubkey, true); 6331 dst_key_free(&keys[count]); 6332 keys[count] = pubkey; 6333 pubkey = NULL; 6334 count++; 6335 goto next; 6336 } 6337 6338 /* 6339 * Whatever the key's default TTL may have 6340 * been, the rdataset TTL takes priority. 6341 */ 6342 dst_key_setttl(keys[count], rdataset.ttl); 6343 6344 if ((dst_key_flags(keys[count]) & DNS_KEYTYPE_NOAUTH) != 0) { 6345 /* We should never get here. */ 6346 dst_key_free(&keys[count]); 6347 goto next; 6348 } 6349 count++; 6350 next: 6351 if (pubkey != NULL) { 6352 dst_key_free(&pubkey); 6353 } 6354 dns_rdata_reset(&rdata); 6355 result = dns_rdataset_next(&rdataset); 6356 } 6357 if (result != ISC_R_NOMORE) { 6358 goto failure; 6359 } 6360 if (count == 0) { 6361 result = ISC_R_NOTFOUND; 6362 } else { 6363 result = ISC_R_SUCCESS; 6364 } 6365 6366 failure: 6367 if (dns_rdataset_isassociated(&rdataset)) { 6368 dns_rdataset_disassociate(&rdataset); 6369 } 6370 if (pubkey != NULL) { 6371 dst_key_free(&pubkey); 6372 } 6373 if (result != ISC_R_SUCCESS) { 6374 while (count > 0) { 6375 dst_key_free(&keys[--count]); 6376 } 6377 } 6378 *nkeys = count; 6379 return result; 6380 } 6381 6382 /*% 6383 * Find up to 'maxkeys' DNSSEC keys used for signing version 'ver' of database 6384 * 'db' for zone 'zone' in its key directory, then load these keys into 'keys'. 6385 * Only load the public part of a given key if it is not active at timestamp 6386 * 'now'. Store the number of keys found in 'nkeys'. 6387 */ 6388 isc_result_t 6389 dns_zone_findkeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 6390 isc_stdtime_t now, isc_mem_t *mctx, unsigned int maxkeys, 6391 dst_key_t **keys, unsigned int *nkeys) { 6392 isc_result_t result; 6393 dns_dbnode_t *node = NULL; 6394 6395 REQUIRE(DNS_ZONE_VALID(zone)); 6396 REQUIRE(mctx != NULL); 6397 REQUIRE(nkeys != NULL); 6398 REQUIRE(keys != NULL); 6399 6400 CHECK(dns_db_findnode(db, dns_db_origin(db), false, &node)); 6401 6402 dns_zone_lock_keyfiles(zone); 6403 6404 result = findzonekeys(zone, db, ver, node, dns_db_origin(db), now, mctx, 6405 maxkeys, keys, nkeys); 6406 6407 dns_zone_unlock_keyfiles(zone); 6408 6409 if (result == ISC_R_NOTFOUND) { 6410 result = ISC_R_SUCCESS; 6411 } 6412 6413 failure: 6414 6415 if (node != NULL) { 6416 dns_db_detachnode(db, &node); 6417 } 6418 return result; 6419 } 6420 6421 /*% 6422 * Find DNSSEC keys used for signing zone with dnssec-policy. Load these keys 6423 * into 'keys'. Requires KASP to be locked. 6424 */ 6425 isc_result_t 6426 dns_zone_getdnsseckeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 6427 isc_stdtime_t now, dns_dnsseckeylist_t *keys) { 6428 isc_result_t result; 6429 const char *dir = dns_zone_getkeydirectory(zone); 6430 dns_dbnode_t *node = NULL; 6431 dns_dnsseckey_t *key, *key_next; 6432 dns_dnsseckeylist_t dnskeys; 6433 dns_name_t *origin = dns_zone_getorigin(zone); 6434 dns_kasp_t *kasp = zone->kasp; 6435 dns_rdataset_t keyset; 6436 6437 REQUIRE(DNS_ZONE_VALID(zone)); 6438 REQUIRE(kasp != NULL); 6439 6440 ISC_LIST_INIT(dnskeys); 6441 6442 dns_rdataset_init(&keyset); 6443 6444 CHECK(dns_db_findnode(db, origin, false, &node)); 6445 6446 /* Get keys from private key files. */ 6447 dns_zone_lock_keyfiles(zone); 6448 result = dns_dnssec_findmatchingkeys(origin, kasp, dir, zone->keystores, 6449 now, dns_zone_getmctx(zone), keys); 6450 dns_zone_unlock_keyfiles(zone); 6451 6452 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 6453 goto failure; 6454 } 6455 6456 /* Get public keys (dnskeys). */ 6457 dns_rdataset_init(&keyset); 6458 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 6459 dns_rdatatype_none, 0, &keyset, NULL); 6460 if (result == ISC_R_SUCCESS) { 6461 CHECK(dns_dnssec_keylistfromrdataset( 6462 origin, kasp, dir, dns_zone_getmctx(zone), &keyset, 6463 NULL, NULL, false, false, &dnskeys)); 6464 } else if (result != ISC_R_NOTFOUND) { 6465 CHECK(result); 6466 } 6467 6468 /* Add new 'dnskeys' to 'keys'. */ 6469 for (dns_dnsseckey_t *k1 = ISC_LIST_HEAD(dnskeys); k1 != NULL; 6470 k1 = key_next) 6471 { 6472 dns_dnsseckey_t *k2 = NULL; 6473 key_next = ISC_LIST_NEXT(k1, link); 6474 6475 for (k2 = ISC_LIST_HEAD(*keys); k2 != NULL; 6476 k2 = ISC_LIST_NEXT(k2, link)) 6477 { 6478 if (dst_key_compare(k1->key, k2->key)) { 6479 break; 6480 } 6481 } 6482 /* No match found, add the new key. */ 6483 if (k2 == NULL) { 6484 ISC_LIST_UNLINK(dnskeys, k1, link); 6485 ISC_LIST_APPEND(*keys, k1, link); 6486 } 6487 } 6488 6489 failure: 6490 if (dns_rdataset_isassociated(&keyset)) { 6491 dns_rdataset_disassociate(&keyset); 6492 } 6493 if (node != NULL) { 6494 dns_db_detachnode(db, &node); 6495 } 6496 while (!ISC_LIST_EMPTY(dnskeys)) { 6497 key = ISC_LIST_HEAD(dnskeys); 6498 ISC_LIST_UNLINK(dnskeys, key, link); 6499 dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key); 6500 } 6501 return result; 6502 } 6503 6504 static isc_result_t 6505 offline(dns_db_t *db, dns_dbversion_t *ver, dns__zonediff_t *zonediff, 6506 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { 6507 isc_result_t result; 6508 6509 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) { 6510 return ISC_R_SUCCESS; 6511 } 6512 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, 6513 name, ttl, rdata); 6514 if (result != ISC_R_SUCCESS) { 6515 return result; 6516 } 6517 rdata->flags |= DNS_RDATA_OFFLINE; 6518 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN, 6519 name, ttl, rdata); 6520 zonediff->offline = true; 6521 return result; 6522 } 6523 6524 static void 6525 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, 6526 isc_stdtime_t now) { 6527 unsigned int delta; 6528 char timebuf[80]; 6529 6530 LOCK_ZONE(zone); 6531 zone->key_expiry = when; 6532 if (when <= now) { 6533 dns_zone_log(zone, ISC_LOG_ERROR, 6534 "DNSKEY RRSIG(s) have expired"); 6535 isc_time_settoepoch(&zone->keywarntime); 6536 } else if (when < now + 7 * 24 * 3600) { 6537 isc_time_t t; 6538 isc_time_set(&t, when, 0); 6539 isc_time_formattimestamp(&t, timebuf, 80); 6540 dns_zone_log(zone, ISC_LOG_WARNING, 6541 "DNSKEY RRSIG(s) will expire within 7 days: %s", 6542 timebuf); 6543 delta = when - now; 6544 delta--; /* loop prevention */ 6545 delta /= 24 * 3600; /* to whole days */ 6546 delta *= 24 * 3600; /* to seconds */ 6547 isc_time_set(&zone->keywarntime, when - delta, 0); 6548 } else { 6549 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0); 6550 isc_time_formattimestamp(&zone->keywarntime, timebuf, 80); 6551 dns_zone_log(zone, ISC_LOG_NOTICE, "setting keywarntime to %s", 6552 timebuf); 6553 } 6554 UNLOCK_ZONE(zone); 6555 } 6556 6557 /* 6558 * Helper function to del_sigs(). We don't want to delete RRSIGs that 6559 * have no new key. 6560 */ 6561 static bool 6562 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys, 6563 bool kasp, bool *warn) { 6564 unsigned int i = 0; 6565 isc_result_t ret; 6566 bool have_ksk = false, have_zsk = false; 6567 bool have_pksk = false, have_pzsk = false; 6568 6569 for (i = 0; i < nkeys; i++) { 6570 bool ksk, zsk; 6571 6572 if (have_pksk && have_ksk && have_pzsk && have_zsk) { 6573 break; 6574 } 6575 6576 if (rrsig_ptr->algorithm != dst_key_alg(keys[i])) { 6577 continue; 6578 } 6579 6580 ret = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk); 6581 if (ret != ISC_R_SUCCESS) { 6582 ksk = KSK(keys[i]); 6583 } 6584 ret = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk); 6585 if (ret != ISC_R_SUCCESS) { 6586 zsk = !KSK(keys[i]); 6587 } 6588 6589 if (ksk) { 6590 have_ksk = true; 6591 if (dst_key_isprivate(keys[i])) { 6592 have_pksk = true; 6593 } 6594 } 6595 if (zsk) { 6596 have_zsk = true; 6597 if (dst_key_isprivate(keys[i])) { 6598 have_pzsk = true; 6599 } 6600 } 6601 } 6602 6603 if (have_zsk && have_ksk && !have_pzsk) { 6604 *warn = true; 6605 } 6606 6607 if (have_pksk && have_pzsk) { 6608 return true; 6609 } 6610 6611 /* 6612 * Deleting the SOA RRSIG is always okay. 6613 */ 6614 if (rrsig_ptr->covered == dns_rdatatype_soa) { 6615 return true; 6616 } 6617 6618 /* 6619 * It's okay to delete a signature if there is an active key with the 6620 * same algorithm to replace it, unless that violates the DNSSEC 6621 * policy. 6622 */ 6623 if (have_pksk || have_pzsk) { 6624 if (kasp && have_pzsk) { 6625 return true; 6626 } 6627 return !kasp; 6628 } 6629 6630 /* 6631 * Failing that, it is *not* okay to delete a signature 6632 * if the associated public key is still in the DNSKEY RRset 6633 */ 6634 for (i = 0; i < nkeys; i++) { 6635 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) && 6636 (rrsig_ptr->keyid == dst_key_id(keys[i]))) 6637 { 6638 return false; 6639 } 6640 } 6641 6642 /* 6643 * But if the key is gone, then go ahead. 6644 */ 6645 return true; 6646 } 6647 6648 /* 6649 * Delete expired RRsigs and any RRsigs we are about to re-sign. 6650 * See also update.c:del_keysigs(). 6651 */ 6652 static isc_result_t 6653 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 6654 dns_rdatatype_t type, dns__zonediff_t *zonediff, dst_key_t **keys, 6655 unsigned int nkeys, isc_stdtime_t now, bool incremental) { 6656 isc_result_t result; 6657 dns_dbnode_t *node = NULL; 6658 dns_rdataset_t rdataset; 6659 unsigned int i; 6660 dns_rdata_rrsig_t rrsig; 6661 dns_kasp_t *kasp = zone->kasp; 6662 bool found; 6663 bool offlineksk = false; 6664 int64_t timewarn = 0, timemaybe = 0; 6665 6666 dns_rdataset_init(&rdataset); 6667 6668 if (kasp != NULL) { 6669 offlineksk = dns_kasp_offlineksk(kasp); 6670 } 6671 6672 if (type == dns_rdatatype_nsec3) { 6673 result = dns_db_findnsec3node(db, name, false, &node); 6674 } else { 6675 result = dns_db_findnode(db, name, false, &node); 6676 } 6677 if (result == ISC_R_NOTFOUND) { 6678 return ISC_R_SUCCESS; 6679 } 6680 if (result != ISC_R_SUCCESS) { 6681 goto failure; 6682 } 6683 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type, 6684 (isc_stdtime_t)0, &rdataset, NULL); 6685 dns_db_detachnode(db, &node); 6686 6687 if (result == ISC_R_NOTFOUND) { 6688 INSIST(!dns_rdataset_isassociated(&rdataset)); 6689 return ISC_R_SUCCESS; 6690 } 6691 if (result != ISC_R_SUCCESS) { 6692 INSIST(!dns_rdataset_isassociated(&rdataset)); 6693 goto failure; 6694 } 6695 6696 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 6697 result = dns_rdataset_next(&rdataset)) 6698 { 6699 dns_rdata_t rdata = DNS_RDATA_INIT; 6700 6701 dns_rdataset_current(&rdataset, &rdata); 6702 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 6703 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6704 6705 if (!dns_rdatatype_iskeymaterial(type)) { 6706 bool warn = false, deleted = false; 6707 if (delsig_ok(&rrsig, keys, nkeys, (kasp != NULL), 6708 &warn)) 6709 { 6710 result = update_one_rr(db, ver, zonediff->diff, 6711 DNS_DIFFOP_DELRESIGN, 6712 name, rdataset.ttl, 6713 &rdata); 6714 if (result != ISC_R_SUCCESS) { 6715 break; 6716 } 6717 deleted = true; 6718 } 6719 if (warn && !deleted) { 6720 /* 6721 * At this point, we've got an RRSIG, 6722 * which is signed by an inactive key. 6723 * An administrator needs to provide a new 6724 * key/alg, but until that time, we want to 6725 * keep the old RRSIG. Marking the key as 6726 * offline will prevent us spinning waiting 6727 * for the private part. 6728 */ 6729 if (incremental) { 6730 result = offline(db, ver, zonediff, 6731 name, rdataset.ttl, 6732 &rdata); 6733 if (result != ISC_R_SUCCESS) { 6734 break; 6735 } 6736 } 6737 6738 /* 6739 * Log the key id and algorithm of 6740 * the inactive key with no replacement 6741 */ 6742 if (zone->log_key_expired_timer <= now) { 6743 char origin[DNS_NAME_FORMATSIZE]; 6744 char algbuf[DNS_NAME_FORMATSIZE]; 6745 dns_name_format(&zone->origin, origin, 6746 sizeof(origin)); 6747 dns_secalg_format(rrsig.algorithm, 6748 algbuf, 6749 sizeof(algbuf)); 6750 dns_zone_log(zone, ISC_LOG_WARNING, 6751 "Key %s/%s/%d " 6752 "missing or inactive " 6753 "and has no replacement: " 6754 "retaining signatures.", 6755 origin, algbuf, 6756 rrsig.keyid); 6757 zone->log_key_expired_timer = now + 6758 3600; 6759 } 6760 } 6761 continue; 6762 } 6763 6764 /* 6765 * KSK RRSIGs requires special processing. 6766 */ 6767 found = false; 6768 for (i = 0; i < nkeys; i++) { 6769 if (rrsig.algorithm == dst_key_alg(keys[i]) && 6770 rrsig.keyid == dst_key_id(keys[i])) 6771 { 6772 found = true; 6773 /* 6774 * Mark offline DNSKEY. 6775 * We want the earliest offline expire time 6776 * iff there is a new offline signature. 6777 */ 6778 if (!dst_key_inactive(keys[i]) && 6779 !dst_key_isprivate(keys[i]) && !offlineksk) 6780 { 6781 int64_t timeexpire = dns_time64_from32( 6782 rrsig.timeexpire); 6783 if (timewarn != 0 && 6784 timewarn > timeexpire) 6785 { 6786 timewarn = timeexpire; 6787 } 6788 if (rdata.flags & DNS_RDATA_OFFLINE) { 6789 if (timemaybe == 0 || 6790 timemaybe > timeexpire) 6791 { 6792 timemaybe = timeexpire; 6793 } 6794 break; 6795 } 6796 if (timewarn == 0) { 6797 timewarn = timemaybe; 6798 } 6799 if (timewarn == 0 || 6800 timewarn > timeexpire) 6801 { 6802 timewarn = timeexpire; 6803 } 6804 result = offline(db, ver, zonediff, 6805 name, rdataset.ttl, 6806 &rdata); 6807 break; 6808 } 6809 result = update_one_rr(db, ver, zonediff->diff, 6810 DNS_DIFFOP_DELRESIGN, 6811 name, rdataset.ttl, 6812 &rdata); 6813 break; 6814 } 6815 } 6816 6817 /* 6818 * If there is not a matching DNSKEY then 6819 * delete the RRSIG. 6820 */ 6821 if (!found) { 6822 result = update_one_rr(db, ver, zonediff->diff, 6823 DNS_DIFFOP_DELRESIGN, name, 6824 rdataset.ttl, &rdata); 6825 } 6826 if (result != ISC_R_SUCCESS) { 6827 break; 6828 } 6829 } 6830 6831 dns_rdataset_disassociate(&rdataset); 6832 if (result == ISC_R_NOMORE) { 6833 result = ISC_R_SUCCESS; 6834 } 6835 if (timewarn > 0) { 6836 isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn; 6837 if (timewarn == stdwarn) { 6838 set_key_expiry_warning(zone, (isc_stdtime_t)timewarn, 6839 now); 6840 } else { 6841 dns_zone_log(zone, ISC_LOG_ERROR, 6842 "key expiry warning time out of range"); 6843 } 6844 } 6845 failure: 6846 if (node != NULL) { 6847 dns_db_detachnode(db, &node); 6848 } 6849 return result; 6850 } 6851 6852 static isc_result_t 6853 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_zone_t *zone, 6854 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, 6855 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t now, 6856 isc_stdtime_t inception, isc_stdtime_t expire) { 6857 isc_result_t result; 6858 dns_dbnode_t *node = NULL; 6859 dns_stats_t *dnssecsignstats; 6860 dns_rdataset_t rdataset; 6861 dns_rdata_t sig_rdata = DNS_RDATA_INIT; 6862 unsigned char data[1024]; /* XXX */ 6863 isc_buffer_t buffer; 6864 unsigned int i; 6865 bool use_kasp = false; 6866 bool offlineksk = false; 6867 6868 if (zone->kasp != NULL) { 6869 use_kasp = true; 6870 offlineksk = dns_kasp_offlineksk(zone->kasp); 6871 } 6872 6873 dns_rdataset_init(&rdataset); 6874 isc_buffer_init(&buffer, data, sizeof(data)); 6875 6876 if (type == dns_rdatatype_nsec3) { 6877 result = dns_db_findnsec3node(db, name, false, &node); 6878 } else { 6879 result = dns_db_findnode(db, name, false, &node); 6880 } 6881 if (result == ISC_R_NOTFOUND) { 6882 return ISC_R_SUCCESS; 6883 } 6884 if (result != ISC_R_SUCCESS) { 6885 goto failure; 6886 } 6887 result = dns_db_findrdataset(db, node, ver, type, 0, (isc_stdtime_t)0, 6888 &rdataset, NULL); 6889 dns_db_detachnode(db, &node); 6890 if (result == ISC_R_NOTFOUND) { 6891 INSIST(!dns_rdataset_isassociated(&rdataset)); 6892 return ISC_R_SUCCESS; 6893 } 6894 if (result != ISC_R_SUCCESS) { 6895 INSIST(!dns_rdataset_isassociated(&rdataset)); 6896 goto failure; 6897 } 6898 6899 for (i = 0; i < nkeys; i++) { 6900 /* Don't add signatures for offline or inactive keys */ 6901 if (!dst_key_isprivate(keys[i]) && !offlineksk) { 6902 continue; 6903 } 6904 if (dst_key_inactive(keys[i]) && !offlineksk) { 6905 continue; 6906 } 6907 6908 if (use_kasp) { 6909 /* 6910 * A dnssec-policy is found. Check what RRsets this 6911 * key should sign. 6912 */ 6913 isc_result_t kresult; 6914 isc_stdtime_t when; 6915 bool ksk = false; 6916 bool zsk = false; 6917 bool have_zsk = false; 6918 6919 kresult = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk); 6920 if (kresult != ISC_R_SUCCESS) { 6921 if (KSK(keys[i])) { 6922 ksk = true; 6923 } 6924 } 6925 kresult = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk); 6926 if (kresult != ISC_R_SUCCESS) { 6927 if (!KSK(keys[i])) { 6928 zsk = true; 6929 } 6930 } 6931 6932 /* 6933 * Don't consider inactive keys or offline keys. 6934 */ 6935 if (!dst_key_isprivate(keys[i]) && offlineksk && zsk) { 6936 continue; 6937 } 6938 if (dst_key_inactive(keys[i]) && offlineksk && zsk) { 6939 continue; 6940 } 6941 6942 if (offlineksk) { 6943 have_zsk = true; 6944 } else { 6945 (void)dst_key_have_ksk_and_zsk(keys, nkeys, i, 6946 true, ksk, zsk, 6947 NULL, &have_zsk); 6948 } 6949 6950 if (dns_rdatatype_iskeymaterial(type)) { 6951 /* 6952 * DNSKEY RRset is signed with KSK. 6953 * CDS and CDNSKEY RRsets too (RFC 7344, 4.1). 6954 */ 6955 if (!ksk) { 6956 continue; 6957 } 6958 } else if (!zsk) { 6959 /* 6960 * Other RRsets are signed with ZSK. 6961 */ 6962 if (type != dns_rdatatype_soa && 6963 type != zone->privatetype) 6964 { 6965 continue; 6966 } 6967 if (have_zsk) { 6968 continue; 6969 } 6970 } else if (!dst_key_is_signing(keys[i], DST_BOOL_ZSK, 6971 now, &when)) 6972 { 6973 /* 6974 * This key is not active for zone-signing. 6975 */ 6976 continue; 6977 } 6978 } else if (!REVOKE(keys[i])) { 6979 /* 6980 * Don't consider inactive keys, however the KSK may be 6981 * temporary offline, so do consider keys which private 6982 * key files are unavailable. 6983 */ 6984 bool both = dst_key_have_ksk_and_zsk( 6985 keys, nkeys, i, false, KSK(keys[i]), 6986 !KSK(keys[i]), NULL, NULL); 6987 if (both) { 6988 /* 6989 * CDS and CDNSKEY are signed with KSK (RFC 6990 * 7344, 4.1). 6991 */ 6992 if (dns_rdatatype_iskeymaterial(type)) { 6993 if (!KSK(keys[i])) { 6994 continue; 6995 } 6996 } else if (KSK(keys[i])) { 6997 continue; 6998 } 6999 } 7000 } 7001 7002 /* 7003 * If this key is revoked, it may only sign the DNSKEY RRset. 7004 */ 7005 if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) { 7006 continue; 7007 } 7008 7009 /* Calculate the signature, creating a RRSIG RDATA. */ 7010 isc_buffer_clear(&buffer); 7011 7012 if (offlineksk && dns_rdatatype_iskeymaterial(type)) { 7013 /* Look up the signature in the SKR bundle */ 7014 dns_skrbundle_t *bundle = dns_zone_getskrbundle(zone); 7015 if (bundle == NULL) { 7016 CHECK(DNS_R_NOSKRBUNDLE); 7017 } 7018 CHECK(dns_skrbundle_getsig(bundle, keys[i], type, 7019 &sig_rdata)); 7020 } else { 7021 CHECK(dns_dnssec_sign(name, &rdataset, keys[i], 7022 &inception, &expire, mctx, 7023 &buffer, &sig_rdata)); 7024 } 7025 7026 /* Update the database and journal with the RRSIG. */ 7027 /* XXX inefficient - will cause dataset merging */ 7028 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, name, 7029 rdataset.ttl, &sig_rdata)); 7030 dns_rdata_reset(&sig_rdata); 7031 isc_buffer_init(&buffer, data, sizeof(data)); 7032 7033 /* Update DNSSEC sign statistics. */ 7034 dnssecsignstats = dns_zone_getdnssecsignstats(zone); 7035 if (dnssecsignstats != NULL) { 7036 /* Generated a new signature. */ 7037 dns_dnssecsignstats_increment(dnssecsignstats, 7038 ID(keys[i]), 7039 (uint8_t)ALG(keys[i]), 7040 dns_dnssecsignstats_sign); 7041 /* This is a refresh. */ 7042 dns_dnssecsignstats_increment( 7043 dnssecsignstats, ID(keys[i]), 7044 (uint8_t)ALG(keys[i]), 7045 dns_dnssecsignstats_refresh); 7046 } 7047 } 7048 7049 failure: 7050 if (dns_rdataset_isassociated(&rdataset)) { 7051 dns_rdataset_disassociate(&rdataset); 7052 } 7053 if (node != NULL) { 7054 dns_db_detachnode(db, &node); 7055 } 7056 return result; 7057 } 7058 7059 static void 7060 calculate_rrsig_validity(dns_zone_t *zone, isc_stdtime_t now, 7061 isc_stdtime_t *inception, isc_stdtime_t *soaexpire, 7062 isc_stdtime_t *expire, isc_stdtime_t *fullexpire) { 7063 REQUIRE(inception != NULL); 7064 REQUIRE(soaexpire != NULL); 7065 /* expire and fullexpire are optional */ 7066 7067 isc_stdtime_t jitter = DEFAULT_JITTER; 7068 isc_stdtime_t sigvalidity = dns_zone_getsigvalidityinterval(zone); 7069 isc_stdtime_t shortjitter = 0, fulljitter = 0; 7070 7071 if (zone->kasp != NULL) { 7072 jitter = dns_kasp_sigjitter(zone->kasp); 7073 sigvalidity = dns_kasp_sigvalidity(zone->kasp); 7074 INSIST(jitter <= sigvalidity); 7075 } 7076 7077 if (jitter > sigvalidity) { 7078 jitter = sigvalidity; 7079 } 7080 7081 *inception = now - 3600; /* Allow for clock skew. */ 7082 *soaexpire = now + sigvalidity; 7083 7084 /* 7085 * Spread out signatures over time if they happen to be 7086 * clumped. We don't do this for each add_sigs() call as 7087 * we still want some clustering to occur. In normal operations 7088 * the records should be re-signed as they fall due and they should 7089 * already be spread out. However if the server is off for a 7090 * period we need to ensure that the clusters don't become 7091 * synchronised by using the full jitter range. 7092 */ 7093 if (sigvalidity >= 3600U) { 7094 if (sigvalidity > 7200U) { 7095 shortjitter = isc_random_uniform(3600); 7096 fulljitter = isc_random_uniform(jitter); 7097 } else { 7098 shortjitter = fulljitter = isc_random_uniform(1200); 7099 } 7100 } 7101 7102 SET_IF_NOT_NULL(expire, *soaexpire - shortjitter - 1); 7103 SET_IF_NOT_NULL(fullexpire, *soaexpire - fulljitter - 1); 7104 } 7105 7106 static void 7107 zone_resigninc(dns_zone_t *zone) { 7108 dns_db_t *db = NULL; 7109 dns_dbversion_t *version = NULL; 7110 dns_diff_t _sig_diff; 7111 dns__zonediff_t zonediff; 7112 dns_fixedname_t fixed; 7113 dns_name_t *name; 7114 dns_typepair_t typepair; 7115 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 7116 isc_result_t result; 7117 isc_stdtime_t now, inception, soaexpire, expire, fullexpire, stop; 7118 unsigned int i; 7119 unsigned int nkeys = 0; 7120 isc_stdtime_t resign; 7121 7122 ENTER; 7123 7124 dns_diff_init(zone->mctx, &_sig_diff); 7125 zonediff_init(&zonediff, &_sig_diff); 7126 7127 /* 7128 * Zone is frozen. Pause for 5 minutes. 7129 */ 7130 if (zone->update_disabled) { 7131 result = ISC_R_FAILURE; 7132 goto failure; 7133 } 7134 7135 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 7136 if (zone->db != NULL) { 7137 dns_db_attach(zone->db, &db); 7138 } 7139 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 7140 if (db == NULL) { 7141 result = ISC_R_FAILURE; 7142 goto failure; 7143 } 7144 7145 result = dns_db_newversion(db, &version); 7146 if (result != ISC_R_SUCCESS) { 7147 dns_zone_log(zone, ISC_LOG_ERROR, 7148 "zone_resigninc:dns_db_newversion -> %s", 7149 isc_result_totext(result)); 7150 goto failure; 7151 } 7152 7153 now = isc_stdtime_now(); 7154 7155 result = dns_zone_findkeys(zone, db, version, now, zone->mctx, 7156 DNS_MAXZONEKEYS, zone_keys, &nkeys); 7157 if (result != ISC_R_SUCCESS) { 7158 dns_zone_log(zone, ISC_LOG_ERROR, 7159 "zone_resigninc:dns_zone_findkeys -> %s", 7160 isc_result_totext(result)); 7161 goto failure; 7162 } 7163 7164 calculate_rrsig_validity(zone, now, &inception, &soaexpire, &expire, 7165 &fullexpire); 7166 7167 stop = now + 5; 7168 7169 name = dns_fixedname_initname(&fixed); 7170 result = dns_db_getsigningtime(db, &resign, name, &typepair); 7171 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 7172 dns_zone_log(zone, ISC_LOG_ERROR, 7173 "zone_resigninc:dns_db_getsigningtime -> %s", 7174 isc_result_totext(result)); 7175 } 7176 7177 i = 0; 7178 while (result == ISC_R_SUCCESS) { 7179 dns_rdatatype_t covers = DNS_TYPEPAIR_COVERS(typepair); 7180 7181 resign -= dns_zone_getsigresigninginterval(zone); 7182 7183 /* 7184 * Stop if we hit the SOA as that means we have walked the 7185 * entire zone. The SOA record should always be the most 7186 * recent signature. 7187 */ 7188 /* XXXMPA increase number of RRsets signed pre call */ 7189 if ((covers == dns_rdatatype_soa && 7190 dns_name_equal(name, &zone->origin)) || 7191 i++ > zone->signatures || resign > stop) 7192 { 7193 break; 7194 } 7195 7196 result = del_sigs(zone, db, version, name, covers, &zonediff, 7197 zone_keys, nkeys, now, true); 7198 if (result != ISC_R_SUCCESS) { 7199 dns_zone_log(zone, ISC_LOG_ERROR, 7200 "zone_resigninc:del_sigs -> %s", 7201 isc_result_totext(result)); 7202 break; 7203 } 7204 7205 /* 7206 * If re-signing is over 5 minutes late use 'fullexpire' 7207 * to redistribute the signature over the complete 7208 * re-signing window, otherwise only add a small amount 7209 * of jitter. 7210 */ 7211 result = add_sigs(db, version, name, zone, covers, 7212 zonediff.diff, zone_keys, nkeys, zone->mctx, 7213 now, inception, 7214 resign > (now - 300) ? expire : fullexpire); 7215 if (result != ISC_R_SUCCESS) { 7216 dns_zone_log(zone, ISC_LOG_ERROR, 7217 "zone_resigninc:add_sigs -> %s", 7218 isc_result_totext(result)); 7219 break; 7220 } 7221 result = dns_db_getsigningtime(db, &resign, name, &typepair); 7222 if (nkeys == 0 && result == ISC_R_NOTFOUND) { 7223 result = ISC_R_SUCCESS; 7224 break; 7225 } 7226 if (result != ISC_R_SUCCESS) { 7227 dns_zone_log(zone, ISC_LOG_ERROR, 7228 "zone_resigninc:dns_db_getsigningtime -> " 7229 "%s", 7230 isc_result_totext(result)); 7231 } 7232 } 7233 7234 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS) { 7235 goto failure; 7236 } 7237 7238 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 7239 &zonediff, zone_keys, nkeys, now, true); 7240 if (result != ISC_R_SUCCESS) { 7241 dns_zone_log(zone, ISC_LOG_ERROR, 7242 "zone_resigninc:del_sigs -> %s", 7243 isc_result_totext(result)); 7244 goto failure; 7245 } 7246 7247 /* 7248 * Did we change anything in the zone? 7249 */ 7250 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 7251 /* 7252 * Commit the changes if any key has been marked as offline. 7253 */ 7254 if (zonediff.offline) { 7255 dns_db_closeversion(db, &version, true); 7256 } 7257 goto failure; 7258 } 7259 7260 /* Increment SOA serial if we have made changes */ 7261 result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx, 7262 zone->updatemethod); 7263 if (result != ISC_R_SUCCESS) { 7264 dns_zone_log(zone, ISC_LOG_ERROR, 7265 "zone_resigninc:update_soa_serial -> %s", 7266 isc_result_totext(result)); 7267 goto failure; 7268 } 7269 7270 /* 7271 * Generate maximum life time signatures so that the above loop 7272 * termination is sensible. 7273 */ 7274 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa, 7275 zonediff.diff, zone_keys, nkeys, zone->mctx, now, 7276 inception, soaexpire); 7277 if (result != ISC_R_SUCCESS) { 7278 dns_zone_log(zone, ISC_LOG_ERROR, 7279 "zone_resigninc:add_sigs -> %s", 7280 isc_result_totext(result)); 7281 goto failure; 7282 } 7283 7284 /* Write changes to journal file. */ 7285 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc")); 7286 7287 /* Everything has succeeded. Commit the changes. */ 7288 dns_db_closeversion(db, &version, true); 7289 7290 failure: 7291 dns_diff_clear(&_sig_diff); 7292 for (i = 0; i < nkeys; i++) { 7293 dst_key_free(&zone_keys[i]); 7294 } 7295 if (version != NULL) { 7296 dns_db_closeversion(db, &version, false); 7297 dns_db_detach(&db); 7298 } else if (db != NULL) { 7299 dns_db_detach(&db); 7300 } 7301 7302 LOCK_ZONE(zone); 7303 if (result == ISC_R_SUCCESS) { 7304 set_resigntime(zone); 7305 zone_needdump(zone, DNS_DUMP_DELAY); 7306 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 7307 } else { 7308 /* 7309 * Something failed. Retry in 5 minutes. 7310 */ 7311 isc_interval_t ival; 7312 isc_interval_set(&ival, 300, 0); 7313 isc_time_nowplusinterval(&zone->resigntime, &ival); 7314 } 7315 UNLOCK_ZONE(zone); 7316 7317 INSIST(version == NULL); 7318 } 7319 7320 static isc_result_t 7321 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname, 7322 dns_name_t *newname, bool bottom) { 7323 isc_result_t result; 7324 dns_dbiterator_t *dbit = NULL; 7325 dns_rdatasetiter_t *rdsit = NULL; 7326 dns_dbnode_t *node = NULL; 7327 7328 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit)); 7329 CHECK(dns_dbiterator_seek(dbit, oldname)); 7330 do { 7331 result = dns_dbiterator_next(dbit); 7332 if (result == ISC_R_NOMORE) { 7333 CHECK(dns_dbiterator_first(dbit)); 7334 } 7335 CHECK(dns_dbiterator_current(dbit, &node, newname)); 7336 if (bottom && dns_name_issubdomain(newname, oldname) && 7337 !dns_name_equal(newname, oldname)) 7338 { 7339 dns_db_detachnode(db, &node); 7340 continue; 7341 } 7342 /* 7343 * Is this node empty? 7344 */ 7345 CHECK(dns_db_allrdatasets(db, node, version, 0, 0, &rdsit)); 7346 result = dns_rdatasetiter_first(rdsit); 7347 dns_db_detachnode(db, &node); 7348 dns_rdatasetiter_destroy(&rdsit); 7349 if (result != ISC_R_NOMORE) { 7350 break; 7351 } 7352 } while (1); 7353 failure: 7354 if (node != NULL) { 7355 dns_db_detachnode(db, &node); 7356 } 7357 if (dbit != NULL) { 7358 dns_dbiterator_destroy(&dbit); 7359 } 7360 return result; 7361 } 7362 7363 static bool 7364 signed_with_good_key(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, 7365 dns_dbversion_t *version, dns_rdatatype_t type, 7366 dst_key_t *key) { 7367 isc_result_t result; 7368 dns_rdataset_t rdataset; 7369 dns_rdata_t rdata = DNS_RDATA_INIT; 7370 dns_rdata_rrsig_t rrsig; 7371 int count = 0; 7372 dns_kasp_t *kasp = zone->kasp; 7373 7374 dns_rdataset_init(&rdataset); 7375 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig, 7376 type, 0, &rdataset, NULL); 7377 if (result != ISC_R_SUCCESS) { 7378 INSIST(!dns_rdataset_isassociated(&rdataset)); 7379 return false; 7380 } 7381 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 7382 result = dns_rdataset_next(&rdataset)) 7383 { 7384 dns_rdataset_current(&rdataset, &rdata); 7385 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 7386 INSIST(result == ISC_R_SUCCESS); 7387 if (rrsig.algorithm == dst_key_alg(key) && 7388 rrsig.keyid == dst_key_id(key)) 7389 { 7390 dns_rdataset_disassociate(&rdataset); 7391 return true; 7392 } 7393 if (rrsig.algorithm == dst_key_alg(key)) { 7394 count++; 7395 } 7396 dns_rdata_reset(&rdata); 7397 } 7398 7399 if (zone->kasp != NULL) { 7400 dns_kasp_key_t *kkey; 7401 int zsk_count = 0; 7402 bool approved; 7403 7404 KASP_LOCK(kasp); 7405 for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL; 7406 kkey = ISC_LIST_NEXT(kkey, link)) 7407 { 7408 if (dns_kasp_key_algorithm(kkey) != dst_key_alg(key)) { 7409 continue; 7410 } 7411 if (dns_kasp_key_zsk(kkey)) { 7412 zsk_count++; 7413 } 7414 } 7415 KASP_UNLOCK(kasp); 7416 7417 if (dns_rdatatype_iskeymaterial(type)) { 7418 /* 7419 * CDS and CDNSKEY are signed with KSK like DNSKEY. 7420 * (RFC 7344, section 4.1 specifies that they must 7421 * be signed with a key in the current DS RRset, 7422 * which would only include KSK's.) 7423 */ 7424 approved = false; 7425 } else { 7426 approved = (zsk_count == count); 7427 } 7428 7429 dns_rdataset_disassociate(&rdataset); 7430 return approved; 7431 } 7432 7433 dns_rdataset_disassociate(&rdataset); 7434 return false; 7435 } 7436 7437 static isc_result_t 7438 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 7439 dns_dbnode_t *node, dns_ttl_t ttl, bool bottom, dns_diff_t *diff) { 7440 dns_fixedname_t fixed; 7441 dns_name_t *next; 7442 dns_rdata_t rdata = DNS_RDATA_INIT; 7443 isc_result_t result; 7444 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE]; 7445 7446 next = dns_fixedname_initname(&fixed); 7447 7448 CHECK(next_active(db, version, name, next, bottom)); 7449 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer, &rdata)); 7450 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl, 7451 &rdata)); 7452 failure: 7453 return result; 7454 } 7455 7456 static isc_result_t 7457 check_if_bottom_of_zone(dns_db_t *db, dns_dbnode_t *node, 7458 dns_dbversion_t *version, bool *is_bottom_of_zone) { 7459 isc_result_t result; 7460 dns_rdatasetiter_t *iterator = NULL; 7461 dns_rdataset_t rdataset; 7462 bool seen_soa = false, seen_ns = false, seen_dname = false; 7463 7464 REQUIRE(is_bottom_of_zone != NULL); 7465 7466 result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator); 7467 if (result != ISC_R_SUCCESS) { 7468 if (result == ISC_R_NOTFOUND) { 7469 result = ISC_R_SUCCESS; 7470 } 7471 return result; 7472 } 7473 7474 dns_rdataset_init(&rdataset); 7475 for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; 7476 result = dns_rdatasetiter_next(iterator)) 7477 { 7478 dns_rdatasetiter_current(iterator, &rdataset); 7479 switch (rdataset.type) { 7480 case dns_rdatatype_soa: 7481 seen_soa = true; 7482 break; 7483 case dns_rdatatype_ns: 7484 seen_ns = true; 7485 break; 7486 case dns_rdatatype_dname: 7487 seen_dname = true; 7488 break; 7489 } 7490 dns_rdataset_disassociate(&rdataset); 7491 } 7492 if (result != ISC_R_NOMORE) { 7493 goto failure; 7494 } 7495 if ((seen_ns && !seen_soa) || seen_dname) { 7496 *is_bottom_of_zone = true; 7497 } 7498 result = ISC_R_SUCCESS; 7499 7500 failure: 7501 dns_rdatasetiter_destroy(&iterator); 7502 7503 return result; 7504 } 7505 7506 static isc_result_t 7507 sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name, 7508 dns_dbnode_t *node, dns_dbversion_t *version, bool build_nsec3, 7509 bool build_nsec, dst_key_t *key, isc_stdtime_t now, 7510 isc_stdtime_t inception, isc_stdtime_t expire, dns_ttl_t nsecttl, 7511 bool both, bool is_ksk, bool is_zsk, bool is_bottom_of_zone, 7512 dns_diff_t *diff, int32_t *signatures, isc_mem_t *mctx) { 7513 isc_result_t result; 7514 dns_rdatasetiter_t *iterator = NULL; 7515 dns_rdataset_t rdataset; 7516 dns_rdata_t rdata = DNS_RDATA_INIT; 7517 dns_stats_t *dnssecsignstats; 7518 bool offlineksk = false; 7519 isc_buffer_t buffer; 7520 unsigned char data[1024]; 7521 bool seen_soa, seen_ns, seen_rr, seen_nsec, seen_nsec3, seen_ds; 7522 7523 if (zone->kasp != NULL) { 7524 offlineksk = dns_kasp_offlineksk(zone->kasp); 7525 } 7526 7527 result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator); 7528 if (result != ISC_R_SUCCESS) { 7529 if (result == ISC_R_NOTFOUND) { 7530 result = ISC_R_SUCCESS; 7531 } 7532 return result; 7533 } 7534 7535 dns_rdataset_init(&rdataset); 7536 isc_buffer_init(&buffer, data, sizeof(data)); 7537 seen_rr = seen_soa = seen_ns = seen_nsec = seen_nsec3 = seen_ds = false; 7538 for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; 7539 result = dns_rdatasetiter_next(iterator)) 7540 { 7541 dns_rdatasetiter_current(iterator, &rdataset); 7542 if (rdataset.type == dns_rdatatype_soa) { 7543 seen_soa = true; 7544 } else if (rdataset.type == dns_rdatatype_ns) { 7545 seen_ns = true; 7546 } else if (rdataset.type == dns_rdatatype_ds) { 7547 seen_ds = true; 7548 } else if (rdataset.type == dns_rdatatype_nsec) { 7549 seen_nsec = true; 7550 } else if (rdataset.type == dns_rdatatype_nsec3) { 7551 seen_nsec3 = true; 7552 } 7553 if (rdataset.type != dns_rdatatype_rrsig) { 7554 seen_rr = true; 7555 } 7556 dns_rdataset_disassociate(&rdataset); 7557 } 7558 if (result != ISC_R_NOMORE) { 7559 goto failure; 7560 } 7561 /* 7562 * Going from insecure to NSEC3. 7563 * Don't generate NSEC3 records for NSEC3 records. 7564 */ 7565 if (build_nsec3 && !seen_nsec3 && seen_rr) { 7566 bool unsecure = !seen_ds && seen_ns && !seen_soa; 7567 CHECK(dns_nsec3_addnsec3s(db, version, name, nsecttl, unsecure, 7568 diff)); 7569 (*signatures)--; 7570 } 7571 /* 7572 * Going from insecure to NSEC. 7573 * Don't generate NSEC records for NSEC3 records. 7574 */ 7575 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) { 7576 /* 7577 * Build a NSEC record except at the origin. 7578 */ 7579 if (!dns_name_equal(name, dns_db_origin(db))) { 7580 CHECK(add_nsec(db, version, name, node, nsecttl, 7581 is_bottom_of_zone, diff)); 7582 /* Count a NSEC generation as a signature generation. */ 7583 (*signatures)--; 7584 } 7585 } 7586 result = dns_rdatasetiter_first(iterator); 7587 while (result == ISC_R_SUCCESS) { 7588 isc_stdtime_t when; 7589 7590 dns_rdatasetiter_current(iterator, &rdataset); 7591 if (rdataset.type == dns_rdatatype_soa || 7592 rdataset.type == dns_rdatatype_rrsig) 7593 { 7594 goto next_rdataset; 7595 } 7596 if (dns_rdatatype_iskeymaterial(rdataset.type)) { 7597 /* 7598 * CDS and CDNSKEY are signed with KSK like DNSKEY. 7599 * (RFC 7344, section 4.1 specifies that they must 7600 * be signed with a key in the current DS RRset, 7601 * which would only include KSK's.) 7602 */ 7603 if (!is_ksk && both) { 7604 goto next_rdataset; 7605 } 7606 } else if (!is_zsk && both) { 7607 goto next_rdataset; 7608 } else if (is_zsk && 7609 !dst_key_is_signing(key, DST_BOOL_ZSK, now, &when)) 7610 { 7611 /* Only applies to dnssec-policy. */ 7612 if (zone->kasp != NULL) { 7613 goto next_rdataset; 7614 } 7615 } 7616 7617 if (seen_ns && !seen_soa && rdataset.type != dns_rdatatype_ds && 7618 rdataset.type != dns_rdatatype_nsec) 7619 { 7620 goto next_rdataset; 7621 } 7622 if (signed_with_good_key(zone, db, node, version, rdataset.type, 7623 key)) 7624 { 7625 goto next_rdataset; 7626 } 7627 7628 /* Calculate the signature, creating a RRSIG RDATA. */ 7629 isc_buffer_clear(&buffer); 7630 if (offlineksk && dns_rdatatype_iskeymaterial(rdataset.type)) { 7631 /* Look up the signature in the SKR bundle */ 7632 dns_skrbundle_t *bundle = dns_zone_getskrbundle(zone); 7633 if (bundle == NULL) { 7634 CHECK(DNS_R_NOSKRBUNDLE); 7635 } 7636 CHECK(dns_skrbundle_getsig(bundle, key, rdataset.type, 7637 &rdata)); 7638 } else { 7639 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception, 7640 &expire, mctx, &buffer, &rdata)); 7641 } 7642 7643 /* Update the database and journal with the RRSIG. */ 7644 /* XXX inefficient - will cause dataset merging */ 7645 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN, 7646 name, rdataset.ttl, &rdata)); 7647 dns_rdata_reset(&rdata); 7648 7649 /* Update DNSSEC sign statistics. */ 7650 dnssecsignstats = dns_zone_getdnssecsignstats(zone); 7651 if (dnssecsignstats != NULL) { 7652 /* Generated a new signature. */ 7653 dns_dnssecsignstats_increment(dnssecsignstats, ID(key), 7654 ALG(key), 7655 dns_dnssecsignstats_sign); 7656 /* This is a refresh. */ 7657 dns_dnssecsignstats_increment( 7658 dnssecsignstats, ID(key), ALG(key), 7659 dns_dnssecsignstats_refresh); 7660 } 7661 7662 (*signatures)--; 7663 next_rdataset: 7664 dns_rdataset_disassociate(&rdataset); 7665 result = dns_rdatasetiter_next(iterator); 7666 } 7667 if (result == ISC_R_NOMORE) { 7668 result = ISC_R_SUCCESS; 7669 } 7670 failure: 7671 if (dns_rdataset_isassociated(&rdataset)) { 7672 dns_rdataset_disassociate(&rdataset); 7673 } 7674 if (iterator != NULL) { 7675 dns_rdatasetiter_destroy(&iterator); 7676 } 7677 return result; 7678 } 7679 7680 /* 7681 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist. 7682 */ 7683 static isc_result_t 7684 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 7685 dns_ttl_t nsecttl, bool update_only, dns_diff_t *diff) { 7686 isc_result_t result; 7687 dns_rdataset_t rdataset; 7688 dns_dbnode_t *node = NULL; 7689 7690 CHECK(dns_db_getoriginnode(db, &node)); 7691 if (update_only) { 7692 dns_rdataset_init(&rdataset); 7693 result = dns_db_findrdataset( 7694 db, node, version, dns_rdatatype_nsec, 7695 dns_rdatatype_none, 0, &rdataset, NULL); 7696 if (dns_rdataset_isassociated(&rdataset)) { 7697 dns_rdataset_disassociate(&rdataset); 7698 } 7699 if (result == ISC_R_NOTFOUND) { 7700 goto success; 7701 } 7702 if (result != ISC_R_SUCCESS) { 7703 goto failure; 7704 } 7705 } 7706 CHECK(delete_nsec(db, version, node, name, diff)); 7707 CHECK(add_nsec(db, version, name, node, nsecttl, false, diff)); 7708 success: 7709 result = ISC_R_SUCCESS; 7710 failure: 7711 if (node != NULL) { 7712 dns_db_detachnode(db, &node); 7713 } 7714 return result; 7715 } 7716 7717 static isc_result_t 7718 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing, 7719 dns_dbversion_t *version, bool build_nsec3, dns_ttl_t nsecttl, 7720 dns_diff_t *diff) { 7721 isc_result_t result; 7722 dns_dbnode_t *node = NULL; 7723 dns_rdataset_t rdataset; 7724 dns_rdata_t rdata = DNS_RDATA_INIT; 7725 unsigned char data[5]; 7726 bool seen_done = false; 7727 bool have_rr = false; 7728 7729 dns_rdataset_init(&rdataset); 7730 result = dns_db_getoriginnode(signing->db, &node); 7731 if (result != ISC_R_SUCCESS) { 7732 goto failure; 7733 } 7734 7735 result = dns_db_findrdataset(signing->db, node, version, 7736 zone->privatetype, dns_rdatatype_none, 0, 7737 &rdataset, NULL); 7738 if (result == ISC_R_NOTFOUND) { 7739 INSIST(!dns_rdataset_isassociated(&rdataset)); 7740 result = ISC_R_SUCCESS; 7741 goto failure; 7742 } 7743 if (result != ISC_R_SUCCESS) { 7744 INSIST(!dns_rdataset_isassociated(&rdataset)); 7745 goto failure; 7746 } 7747 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 7748 result = dns_rdataset_next(&rdataset)) 7749 { 7750 dns_rdataset_current(&rdataset, &rdata); 7751 /* 7752 * If we don't match the algorithm or keyid skip the record. 7753 */ 7754 if (rdata.length != 5 || rdata.data[0] != signing->algorithm || 7755 rdata.data[1] != ((signing->keyid >> 8) & 0xff) || 7756 rdata.data[2] != (signing->keyid & 0xff)) 7757 { 7758 have_rr = true; 7759 dns_rdata_reset(&rdata); 7760 continue; 7761 } 7762 /* 7763 * We have a match. If we were signing (!signing->deleteit) 7764 * and we already have a record indicating that we have 7765 * finished signing (rdata.data[4] != 0) then keep it. 7766 * Otherwise it needs to be deleted as we have removed all 7767 * the signatures (signing->deleteit), so any record indicating 7768 * completion is now out of date, or we have finished signing 7769 * with the new record so we no longer need to remember that 7770 * we need to sign the zone with the matching key across a 7771 * nameserver re-start. 7772 */ 7773 if (!signing->deleteit && rdata.data[4] != 0) { 7774 seen_done = true; 7775 have_rr = true; 7776 } else { 7777 CHECK(update_one_rr(signing->db, version, diff, 7778 DNS_DIFFOP_DEL, &zone->origin, 7779 rdataset.ttl, &rdata)); 7780 } 7781 dns_rdata_reset(&rdata); 7782 } 7783 if (result == ISC_R_NOMORE) { 7784 result = ISC_R_SUCCESS; 7785 } 7786 if (!signing->deleteit && !seen_done) { 7787 /* 7788 * If we were signing then we need to indicate that we have 7789 * finished signing the zone with this key. If it is already 7790 * there we don't need to add it a second time. 7791 */ 7792 data[0] = signing->algorithm; 7793 data[1] = (signing->keyid >> 8) & 0xff; 7794 data[2] = signing->keyid & 0xff; 7795 data[3] = 0; 7796 data[4] = 1; 7797 rdata.length = sizeof(data); 7798 rdata.data = data; 7799 rdata.type = zone->privatetype; 7800 rdata.rdclass = dns_db_class(signing->db); 7801 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD, 7802 &zone->origin, rdataset.ttl, &rdata)); 7803 } else if (!have_rr) { 7804 dns_name_t *origin = dns_db_origin(signing->db); 7805 /* 7806 * Rebuild the NSEC/NSEC3 record for the origin as we no 7807 * longer have any private records. 7808 */ 7809 if (build_nsec3) { 7810 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin, 7811 nsecttl, false, diff)); 7812 } 7813 CHECK(updatesecure(signing->db, version, origin, nsecttl, true, 7814 diff)); 7815 } 7816 7817 failure: 7818 if (dns_rdataset_isassociated(&rdataset)) { 7819 dns_rdataset_disassociate(&rdataset); 7820 } 7821 if (node != NULL) { 7822 dns_db_detachnode(signing->db, &node); 7823 } 7824 return result; 7825 } 7826 7827 /* 7828 * Called from zone_nsec3chain() in order to update zone records indicating 7829 * processing status of given NSEC3 chain: 7830 * 7831 * - If the supplied dns_nsec3chain_t structure has been fully processed 7832 * (which is indicated by "active" being set to false): 7833 * 7834 * - remove all NSEC3PARAM records matching the relevant NSEC3 chain, 7835 * 7836 * - remove all private-type records containing NSEC3PARAM RDATA matching 7837 * the relevant NSEC3 chain. 7838 * 7839 * - If the supplied dns_nsec3chain_t structure has not been fully processed 7840 * (which is indicated by "active" being set to true), only remove the 7841 * NSEC3PARAM record which matches the relevant NSEC3 chain and has the 7842 * "flags" field set to 0. 7843 * 7844 * - If given NSEC3 chain is being added, add an NSEC3PARAM record contained 7845 * in the relevant private-type record, but with the "flags" field set to 7846 * 0, indicating that this NSEC3 chain is now complete for this zone. 7847 * 7848 * Note that this function is called at different processing stages for NSEC3 7849 * chain additions vs. removals and needs to handle all cases properly. 7850 */ 7851 static isc_result_t 7852 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain, 7853 bool active, dns_rdatatype_t privatetype, dns_diff_t *diff) { 7854 dns_dbnode_t *node = NULL; 7855 dns_name_t *name = dns_db_origin(db); 7856 dns_rdata_t rdata = DNS_RDATA_INIT; 7857 dns_rdataset_t rdataset; 7858 dns_rdata_nsec3param_t nsec3param; 7859 dns_rdata_soa_t soa; 7860 isc_result_t result; 7861 isc_buffer_t buffer; 7862 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE]; 7863 dns_ttl_t ttl = 0; 7864 bool nseconly = false, nsec3ok = false; 7865 7866 dns_rdataset_init(&rdataset); 7867 7868 result = dns_db_getoriginnode(db, &node); 7869 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7870 7871 /* Default TTL is SOA MINIMUM */ 7872 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0, 0, 7873 &rdataset, NULL); 7874 if (result == ISC_R_SUCCESS) { 7875 CHECK(dns_rdataset_first(&rdataset)); 7876 dns_rdataset_current(&rdataset, &rdata); 7877 CHECK(dns_rdata_tostruct(&rdata, &soa, NULL)); 7878 ttl = soa.minimum; 7879 dns_rdata_reset(&rdata); 7880 } 7881 if (dns_rdataset_isassociated(&rdataset)) { 7882 dns_rdataset_disassociate(&rdataset); 7883 } 7884 7885 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0, 7886 0, &rdataset, NULL); 7887 if (result == ISC_R_NOTFOUND) { 7888 goto try_private; 7889 } 7890 if (result != ISC_R_SUCCESS) { 7891 goto failure; 7892 } 7893 7894 /* 7895 * Delete all NSEC3PARAM records which match that in nsec3chain. 7896 */ 7897 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 7898 result = dns_rdataset_next(&rdataset)) 7899 { 7900 dns_rdataset_current(&rdataset, &rdata); 7901 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 7902 7903 if (nsec3param.hash != chain->nsec3param.hash || 7904 (active && nsec3param.flags != 0) || 7905 nsec3param.iterations != chain->nsec3param.iterations || 7906 nsec3param.salt_length != chain->nsec3param.salt_length || 7907 memcmp(nsec3param.salt, chain->nsec3param.salt, 7908 nsec3param.salt_length)) 7909 { 7910 /* 7911 * If the SOA minimum is different to the current TTL, 7912 * delete the record. We will re-add it with the new 7913 * TTL below. 7914 */ 7915 if (rdataset.ttl != ttl) { 7916 CHECK(update_one_rr(db, ver, diff, 7917 DNS_DIFFOP_DEL, name, 7918 rdataset.ttl, &rdata)); 7919 } 7920 dns_rdata_reset(&rdata); 7921 continue; 7922 } 7923 7924 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 7925 rdataset.ttl, &rdata)); 7926 dns_rdata_reset(&rdata); 7927 } 7928 if (result != ISC_R_NOMORE) { 7929 goto failure; 7930 } 7931 7932 /* 7933 * Restore any NSEC3PARAM records that we deleted to change the TTL. 7934 */ 7935 if (rdataset.ttl != ttl) { 7936 for (result = dns_rdataset_first(&rdataset); 7937 result == ISC_R_SUCCESS; 7938 result = dns_rdataset_next(&rdataset)) 7939 { 7940 dns_rdataset_current(&rdataset, &rdata); 7941 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 7942 7943 if (nsec3param.hash != chain->nsec3param.hash || 7944 (active && nsec3param.flags != 0) || 7945 nsec3param.iterations != 7946 chain->nsec3param.iterations || 7947 nsec3param.salt_length != 7948 chain->nsec3param.salt_length || 7949 memcmp(nsec3param.salt, chain->nsec3param.salt, 7950 nsec3param.salt_length)) 7951 { 7952 CHECK(update_one_rr(db, ver, diff, 7953 DNS_DIFFOP_ADD, name, ttl, 7954 &rdata)); 7955 } 7956 dns_rdata_reset(&rdata); 7957 } 7958 } 7959 7960 dns_rdataset_disassociate(&rdataset); 7961 7962 try_private: 7963 7964 if (active) { 7965 goto add; 7966 } 7967 7968 result = dns_nsec_nseconly(db, ver, diff, &nseconly); 7969 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 7970 7971 /* 7972 * Delete all private records which match that in nsec3chain. 7973 */ 7974 result = dns_db_findrdataset(db, node, ver, privatetype, 0, 0, 7975 &rdataset, NULL); 7976 if (result == ISC_R_NOTFOUND) { 7977 goto add; 7978 } 7979 if (result != ISC_R_SUCCESS) { 7980 goto failure; 7981 } 7982 7983 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 7984 result = dns_rdataset_next(&rdataset)) 7985 { 7986 dns_rdata_t private = DNS_RDATA_INIT; 7987 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 7988 7989 dns_rdataset_current(&rdataset, &private); 7990 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 7991 sizeof(buf))) 7992 { 7993 continue; 7994 } 7995 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 7996 7997 if ((!nsec3ok && 7998 (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) || 7999 nsec3param.hash != chain->nsec3param.hash || 8000 nsec3param.iterations != chain->nsec3param.iterations || 8001 nsec3param.salt_length != chain->nsec3param.salt_length || 8002 memcmp(nsec3param.salt, chain->nsec3param.salt, 8003 nsec3param.salt_length)) 8004 { 8005 dns_rdata_reset(&rdata); 8006 continue; 8007 } 8008 8009 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8010 rdataset.ttl, &private)); 8011 dns_rdata_reset(&rdata); 8012 } 8013 if (result != ISC_R_NOMORE) { 8014 goto failure; 8015 } 8016 8017 add: 8018 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) { 8019 result = ISC_R_SUCCESS; 8020 goto failure; 8021 } 8022 8023 /* 8024 * Add a NSEC3PARAM record which matches that in nsec3chain but 8025 * with all flags bits cleared. 8026 * 8027 * Note: we do not clear chain->nsec3param.flags as this change 8028 * may be reversed. 8029 */ 8030 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf)); 8031 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), 8032 dns_rdatatype_nsec3param, &chain->nsec3param, 8033 &buffer)); 8034 rdata.data[1] = 0; /* Clear flag bits. */ 8035 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata)); 8036 8037 failure: 8038 dns_db_detachnode(db, &node); 8039 if (dns_rdataset_isassociated(&rdataset)) { 8040 dns_rdataset_disassociate(&rdataset); 8041 } 8042 return result; 8043 } 8044 8045 static isc_result_t 8046 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 8047 dns_name_t *name, dns_diff_t *diff) { 8048 dns_rdataset_t rdataset; 8049 isc_result_t result; 8050 8051 dns_rdataset_init(&rdataset); 8052 8053 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0, 8054 &rdataset, NULL); 8055 if (result == ISC_R_NOTFOUND) { 8056 return ISC_R_SUCCESS; 8057 } 8058 if (result != ISC_R_SUCCESS) { 8059 return result; 8060 } 8061 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8062 result = dns_rdataset_next(&rdataset)) 8063 { 8064 dns_rdata_t rdata = DNS_RDATA_INIT; 8065 8066 dns_rdataset_current(&rdataset, &rdata); 8067 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8068 rdataset.ttl, &rdata)); 8069 } 8070 if (result == ISC_R_NOMORE) { 8071 result = ISC_R_SUCCESS; 8072 } 8073 failure: 8074 dns_rdataset_disassociate(&rdataset); 8075 return result; 8076 } 8077 8078 static isc_result_t 8079 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 8080 dns_name_t *name, const dns_rdata_nsec3param_t *param, 8081 dns_diff_t *diff) { 8082 dns_rdataset_t rdataset; 8083 dns_rdata_nsec3_t nsec3; 8084 isc_result_t result; 8085 8086 dns_rdataset_init(&rdataset); 8087 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 0, 0, 8088 &rdataset, NULL); 8089 if (result == ISC_R_NOTFOUND) { 8090 return ISC_R_SUCCESS; 8091 } 8092 if (result != ISC_R_SUCCESS) { 8093 return result; 8094 } 8095 8096 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8097 result = dns_rdataset_next(&rdataset)) 8098 { 8099 dns_rdata_t rdata = DNS_RDATA_INIT; 8100 8101 dns_rdataset_current(&rdataset, &rdata); 8102 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL)); 8103 if (nsec3.hash != param->hash || 8104 nsec3.iterations != param->iterations || 8105 nsec3.salt_length != param->salt_length || 8106 memcmp(nsec3.salt, param->salt, nsec3.salt_length)) 8107 { 8108 continue; 8109 } 8110 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8111 rdataset.ttl, &rdata)); 8112 } 8113 if (result == ISC_R_NOMORE) { 8114 result = ISC_R_SUCCESS; 8115 } 8116 failure: 8117 dns_rdataset_disassociate(&rdataset); 8118 return result; 8119 } 8120 8121 static isc_result_t 8122 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver, 8123 const dns_rdata_nsec3param_t *param, bool *answer) { 8124 dns_dbnode_t *node = NULL; 8125 dns_rdata_t rdata = DNS_RDATA_INIT; 8126 dns_rdata_nsec3param_t myparam; 8127 dns_rdataset_t rdataset; 8128 isc_result_t result; 8129 8130 *answer = false; 8131 8132 result = dns_db_getoriginnode(db, &node); 8133 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8134 8135 dns_rdataset_init(&rdataset); 8136 8137 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0, 8138 &rdataset, NULL); 8139 if (result == ISC_R_SUCCESS) { 8140 dns_rdataset_disassociate(&rdataset); 8141 dns_db_detachnode(db, &node); 8142 return result; 8143 } 8144 if (result != ISC_R_NOTFOUND) { 8145 dns_db_detachnode(db, &node); 8146 return result; 8147 } 8148 8149 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0, 8150 0, &rdataset, NULL); 8151 if (result == ISC_R_NOTFOUND) { 8152 *answer = true; 8153 dns_db_detachnode(db, &node); 8154 return ISC_R_SUCCESS; 8155 } 8156 if (result != ISC_R_SUCCESS) { 8157 dns_db_detachnode(db, &node); 8158 return result; 8159 } 8160 8161 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8162 result = dns_rdataset_next(&rdataset)) 8163 { 8164 dns_rdataset_current(&rdataset, &rdata); 8165 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL)); 8166 dns_rdata_reset(&rdata); 8167 /* 8168 * Ignore any NSEC3PARAM removals. 8169 */ 8170 if (NSEC3REMOVE(myparam.flags)) { 8171 continue; 8172 } 8173 /* 8174 * Ignore the chain that we are in the process of deleting. 8175 */ 8176 if (myparam.hash == param->hash && 8177 myparam.iterations == param->iterations && 8178 myparam.salt_length == param->salt_length && 8179 !memcmp(myparam.salt, param->salt, myparam.salt_length)) 8180 { 8181 continue; 8182 } 8183 /* 8184 * Found an active NSEC3 chain. 8185 */ 8186 break; 8187 } 8188 if (result == ISC_R_NOMORE) { 8189 *answer = true; 8190 result = ISC_R_SUCCESS; 8191 } 8192 8193 failure: 8194 if (dns_rdataset_isassociated(&rdataset)) { 8195 dns_rdataset_disassociate(&rdataset); 8196 } 8197 dns_db_detachnode(db, &node); 8198 return result; 8199 } 8200 8201 /*% 8202 * Given a tuple which is part of a diff, return a pointer to the next tuple in 8203 * that diff which has the same name and type (or NULL if no such tuple is 8204 * found). 8205 */ 8206 static dns_difftuple_t * 8207 find_next_matching_tuple(dns_difftuple_t *cur) { 8208 dns_difftuple_t *next = cur; 8209 8210 while ((next = ISC_LIST_NEXT(next, link)) != NULL) { 8211 if (cur->rdata.type == next->rdata.type && 8212 dns_name_equal(&cur->name, &next->name)) 8213 { 8214 return next; 8215 } 8216 } 8217 8218 return NULL; 8219 } 8220 8221 /*% 8222 * Remove all tuples with the same name and type as 'cur' from 'src' and append 8223 * them to 'dst'. 8224 */ 8225 static void 8226 move_matching_tuples(dns_difftuple_t *cur, dns_diff_t *src, dns_diff_t *dst) { 8227 do { 8228 dns_difftuple_t *next = find_next_matching_tuple(cur); 8229 ISC_LIST_UNLINK(src->tuples, cur, link); 8230 dns_diff_appendminimal(dst, &cur); 8231 cur = next; 8232 } while (cur != NULL); 8233 } 8234 8235 /*% 8236 * Add/remove DNSSEC signatures for the list of "raw" zone changes supplied in 8237 * 'diff'. Gradually remove tuples from 'diff' and append them to 'zonediff' 8238 * along with tuples representing relevant signature changes. 8239 */ 8240 isc_result_t 8241 dns__zone_updatesigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, 8242 dst_key_t *zone_keys[], unsigned int nkeys, 8243 dns_zone_t *zone, isc_stdtime_t inception, 8244 isc_stdtime_t expire, isc_stdtime_t keyexpire, 8245 isc_stdtime_t now, dns__zonediff_t *zonediff) { 8246 dns_difftuple_t *tuple; 8247 isc_result_t result; 8248 8249 while ((tuple = ISC_LIST_HEAD(diff->tuples)) != NULL) { 8250 isc_stdtime_t exp = expire; 8251 8252 if (keyexpire != 0 && 8253 dns_rdatatype_iskeymaterial(tuple->rdata.type)) 8254 { 8255 exp = keyexpire; 8256 } 8257 8258 result = del_sigs(zone, db, version, &tuple->name, 8259 tuple->rdata.type, zonediff, zone_keys, nkeys, 8260 now, false); 8261 if (result != ISC_R_SUCCESS) { 8262 dns_zone_log(zone, ISC_LOG_ERROR, 8263 "dns__zone_updatesigs:del_sigs -> %s", 8264 isc_result_totext(result)); 8265 return result; 8266 } 8267 result = add_sigs(db, version, &tuple->name, zone, 8268 tuple->rdata.type, zonediff->diff, zone_keys, 8269 nkeys, zone->mctx, now, inception, exp); 8270 if (result != ISC_R_SUCCESS) { 8271 dns_zone_log(zone, ISC_LOG_ERROR, 8272 "dns__zone_updatesigs:add_sigs -> %s", 8273 isc_result_totext(result)); 8274 return result; 8275 } 8276 8277 /* 8278 * Signature changes for all RRs with name tuple->name and type 8279 * tuple->rdata.type were appended to zonediff->diff. Now we 8280 * remove all the "raw" changes with the same name and type 8281 * from diff (so that they are not processed by this loop 8282 * again) and append them to zonediff so that they get applied. 8283 */ 8284 move_matching_tuples(tuple, diff, zonediff->diff); 8285 } 8286 return ISC_R_SUCCESS; 8287 } 8288 8289 /* 8290 * Incrementally build and sign a new NSEC3 chain using the parameters 8291 * requested. 8292 */ 8293 static void 8294 zone_nsec3chain(dns_zone_t *zone) { 8295 dns_db_t *db = NULL; 8296 dns_dbnode_t *node = NULL; 8297 dns_dbversion_t *version = NULL; 8298 dns_diff_t _sig_diff; 8299 dns_diff_t nsec_diff; 8300 dns_diff_t nsec3_diff; 8301 dns_diff_t param_diff; 8302 dns__zonediff_t zonediff; 8303 dns_fixedname_t fixed; 8304 dns_fixedname_t nextfixed; 8305 dns_name_t *name, *nextname; 8306 dns_rdataset_t rdataset; 8307 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain; 8308 dns_nsec3chainlist_t cleanup; 8309 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 8310 int32_t signatures; 8311 bool delegation; 8312 bool first; 8313 isc_result_t result; 8314 isc_stdtime_t now, inception, soaexpire, expire; 8315 unsigned int i; 8316 unsigned int nkeys = 0; 8317 uint32_t nodes; 8318 bool unsecure = false; 8319 bool seen_soa, seen_ns, seen_dname, seen_ds; 8320 bool seen_nsec, seen_nsec3, seen_rr; 8321 dns_rdatasetiter_t *iterator = NULL; 8322 bool buildnsecchain; 8323 bool updatensec = false; 8324 dns_rdatatype_t privatetype = zone->privatetype; 8325 8326 ENTER; 8327 8328 dns_rdataset_init(&rdataset); 8329 name = dns_fixedname_initname(&fixed); 8330 nextname = dns_fixedname_initname(&nextfixed); 8331 dns_diff_init(zone->mctx, ¶m_diff); 8332 dns_diff_init(zone->mctx, &nsec3_diff); 8333 dns_diff_init(zone->mctx, &nsec_diff); 8334 dns_diff_init(zone->mctx, &_sig_diff); 8335 zonediff_init(&zonediff, &_sig_diff); 8336 ISC_LIST_INIT(cleanup); 8337 8338 /* 8339 * Updates are disabled. Pause for 5 minutes. 8340 */ 8341 if (zone->update_disabled) { 8342 result = ISC_R_FAILURE; 8343 goto failure; 8344 } 8345 8346 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8347 /* 8348 * This function is called when zone timer fires, after the latter gets 8349 * set by zone_addnsec3chain(). If the action triggering the call to 8350 * zone_addnsec3chain() is closely followed by a zone deletion request, 8351 * it might turn out that the timer thread will not be woken up until 8352 * after the zone is deleted by rmzone(), which calls dns_db_detach() 8353 * for zone->db, causing the latter to become NULL. Return immediately 8354 * if that happens. 8355 */ 8356 if (zone->db != NULL) { 8357 dns_db_attach(zone->db, &db); 8358 } 8359 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8360 if (db == NULL) { 8361 return; 8362 } 8363 8364 result = dns_db_newversion(db, &version); 8365 if (result != ISC_R_SUCCESS) { 8366 dnssec_log(zone, ISC_LOG_ERROR, 8367 "zone_nsec3chain:dns_db_newversion -> %s", 8368 isc_result_totext(result)); 8369 goto failure; 8370 } 8371 8372 now = isc_stdtime_now(); 8373 8374 result = dns_zone_findkeys(zone, db, version, now, zone->mctx, 8375 DNS_MAXZONEKEYS, zone_keys, &nkeys); 8376 if (result != ISC_R_SUCCESS) { 8377 dnssec_log(zone, ISC_LOG_ERROR, 8378 "zone_nsec3chain:dns_zone_findkeys -> %s", 8379 isc_result_totext(result)); 8380 goto failure; 8381 } 8382 8383 calculate_rrsig_validity(zone, now, &inception, &soaexpire, NULL, 8384 &expire); 8385 8386 /* 8387 * We keep pulling nodes off each iterator in turn until 8388 * we have no more nodes to pull off or we reach the limits 8389 * for this quantum. 8390 */ 8391 nodes = zone->nodes; 8392 signatures = zone->signatures; 8393 LOCK_ZONE(zone); 8394 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 8395 UNLOCK_ZONE(zone); 8396 first = true; 8397 8398 if (nsec3chain != NULL) { 8399 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 8400 } 8401 /* 8402 * Generate new NSEC3 chains first. 8403 * 8404 * The following while loop iterates over nodes in the zone database, 8405 * updating the NSEC3 chain by calling dns_nsec3_addnsec3() for each of 8406 * them. Once all nodes are processed, the "delete_nsec" field is 8407 * consulted to check whether we are supposed to remove NSEC records 8408 * from the zone database; if so, the database iterator is reset to 8409 * point to the first node and the loop traverses all of them again, 8410 * this time removing NSEC records. If we hit a node which is obscured 8411 * by a delegation or a DNAME, nodes are skipped over until we find one 8412 * that is not obscured by the same obscuring name and then normal 8413 * processing is resumed. 8414 * 8415 * The above is repeated until all requested NSEC3 chain changes are 8416 * applied or when we reach the limits for this quantum, whichever 8417 * happens first. 8418 * 8419 * Note that the "signatures" variable is only used here to limit the 8420 * amount of work performed. Actual DNSSEC signatures are only 8421 * generated by dns__zone_updatesigs() calls later in this function. 8422 */ 8423 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 8424 dns_dbiterator_pause(nsec3chain->dbiterator); 8425 8426 LOCK_ZONE(zone); 8427 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 8428 8429 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8430 if (nsec3chain->done || nsec3chain->db != zone->db) { 8431 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 8432 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8433 } 8434 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8435 UNLOCK_ZONE(zone); 8436 if (ISC_LIST_TAIL(cleanup) == nsec3chain) { 8437 goto next_addchain; 8438 } 8439 8440 /* 8441 * Possible future db. 8442 */ 8443 if (nsec3chain->db != db) { 8444 goto next_addchain; 8445 } 8446 8447 if (NSEC3REMOVE(nsec3chain->nsec3param.flags)) { 8448 goto next_addchain; 8449 } 8450 8451 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 8452 8453 if (nsec3chain->delete_nsec) { 8454 delegation = false; 8455 dns_dbiterator_pause(nsec3chain->dbiterator); 8456 CHECK(delete_nsec(db, version, node, name, &nsec_diff)); 8457 goto next_addnode; 8458 } 8459 /* 8460 * On the first pass we need to check if the current node 8461 * has not been obscured. 8462 */ 8463 delegation = false; 8464 unsecure = false; 8465 if (first) { 8466 dns_fixedname_t ffound; 8467 dns_name_t *found; 8468 found = dns_fixedname_initname(&ffound); 8469 result = dns_db_find( 8470 db, name, version, dns_rdatatype_soa, 8471 DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); 8472 if ((result == DNS_R_DELEGATION || 8473 result == DNS_R_DNAME) && 8474 !dns_name_equal(name, found)) 8475 { 8476 /* 8477 * Remember the obscuring name so that 8478 * we skip all obscured names. 8479 */ 8480 dns_name_copy(found, name); 8481 delegation = true; 8482 goto next_addnode; 8483 } 8484 } 8485 8486 /* 8487 * Check to see if this is a bottom of zone node. 8488 */ 8489 result = dns_db_allrdatasets(db, node, version, 0, 0, 8490 &iterator); 8491 if (result == ISC_R_NOTFOUND) { 8492 /* Empty node? */ 8493 goto next_addnode; 8494 } 8495 if (result != ISC_R_SUCCESS) { 8496 goto failure; 8497 } 8498 8499 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = false; 8500 for (result = dns_rdatasetiter_first(iterator); 8501 result == ISC_R_SUCCESS; 8502 result = dns_rdatasetiter_next(iterator)) 8503 { 8504 dns_rdatasetiter_current(iterator, &rdataset); 8505 INSIST(rdataset.type != dns_rdatatype_nsec3); 8506 if (rdataset.type == dns_rdatatype_soa) { 8507 seen_soa = true; 8508 } else if (rdataset.type == dns_rdatatype_ns) { 8509 seen_ns = true; 8510 } else if (rdataset.type == dns_rdatatype_dname) { 8511 seen_dname = true; 8512 } else if (rdataset.type == dns_rdatatype_ds) { 8513 seen_ds = true; 8514 } else if (rdataset.type == dns_rdatatype_nsec) { 8515 seen_nsec = true; 8516 } 8517 dns_rdataset_disassociate(&rdataset); 8518 } 8519 dns_rdatasetiter_destroy(&iterator); 8520 /* 8521 * Is there a NSEC chain than needs to be cleaned up? 8522 */ 8523 if (seen_nsec) { 8524 nsec3chain->seen_nsec = true; 8525 } 8526 if (seen_ns && !seen_soa && !seen_ds) { 8527 unsecure = true; 8528 } 8529 if ((seen_ns && !seen_soa) || seen_dname) { 8530 delegation = true; 8531 } 8532 8533 /* 8534 * Process one node. 8535 */ 8536 dns_dbiterator_pause(nsec3chain->dbiterator); 8537 result = dns_nsec3_addnsec3( 8538 db, version, name, &nsec3chain->nsec3param, 8539 zone_nsecttl(zone), unsecure, &nsec3_diff); 8540 if (result != ISC_R_SUCCESS) { 8541 dnssec_log(zone, ISC_LOG_ERROR, 8542 "zone_nsec3chain:" 8543 "dns_nsec3_addnsec3 -> %s", 8544 isc_result_totext(result)); 8545 goto failure; 8546 } 8547 8548 /* 8549 * Treat each call to dns_nsec3_addnsec3() as if it's cost is 8550 * two signatures. Additionally there will, in general, be 8551 * two signature generated below. 8552 * 8553 * If we are only changing the optout flag the cost is half 8554 * that of the cost of generating a completely new chain. 8555 */ 8556 signatures -= 4; 8557 8558 /* 8559 * Go onto next node. 8560 */ 8561 next_addnode: 8562 first = false; 8563 dns_db_detachnode(db, &node); 8564 do { 8565 result = dns_dbiterator_next(nsec3chain->dbiterator); 8566 8567 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) { 8568 dns_dbiterator_pause(nsec3chain->dbiterator); 8569 CHECK(fixup_nsec3param(db, version, nsec3chain, 8570 false, privatetype, 8571 ¶m_diff)); 8572 LOCK_ZONE(zone); 8573 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 8574 link); 8575 UNLOCK_ZONE(zone); 8576 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8577 goto next_addchain; 8578 } 8579 if (result == ISC_R_NOMORE) { 8580 dns_dbiterator_pause(nsec3chain->dbiterator); 8581 if (nsec3chain->seen_nsec) { 8582 CHECK(fixup_nsec3param( 8583 db, version, nsec3chain, true, 8584 privatetype, ¶m_diff)); 8585 nsec3chain->delete_nsec = true; 8586 goto same_addchain; 8587 } 8588 CHECK(fixup_nsec3param(db, version, nsec3chain, 8589 false, privatetype, 8590 ¶m_diff)); 8591 LOCK_ZONE(zone); 8592 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 8593 link); 8594 UNLOCK_ZONE(zone); 8595 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8596 goto next_addchain; 8597 } else if (result != ISC_R_SUCCESS) { 8598 dnssec_log(zone, ISC_LOG_ERROR, 8599 "zone_nsec3chain:" 8600 "dns_dbiterator_next -> %s", 8601 isc_result_totext(result)); 8602 goto failure; 8603 } else if (delegation) { 8604 dns_dbiterator_current(nsec3chain->dbiterator, 8605 &node, nextname); 8606 dns_db_detachnode(db, &node); 8607 if (!dns_name_issubdomain(nextname, name)) { 8608 break; 8609 } 8610 } else { 8611 break; 8612 } 8613 } while (1); 8614 continue; 8615 8616 same_addchain: 8617 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 8618 first = true; 8619 continue; 8620 8621 next_addchain: 8622 dns_dbiterator_pause(nsec3chain->dbiterator); 8623 nsec3chain = nextnsec3chain; 8624 first = true; 8625 if (nsec3chain != NULL) { 8626 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 8627 } 8628 } 8629 8630 if (nsec3chain != NULL) { 8631 goto skip_removals; 8632 } 8633 8634 /* 8635 * Process removals. 8636 * 8637 * This is a counterpart of the above while loop which takes care of 8638 * removing an NSEC3 chain. It starts with determining whether the 8639 * zone needs to switch from NSEC3 to NSEC; if so, it first builds an 8640 * NSEC chain by iterating over all nodes in the zone database and only 8641 * then goes on to remove NSEC3 records be iterating over all nodes 8642 * again and calling deletematchingnsec3() for each of them; otherwise, 8643 * it starts removing NSEC3 records immediately. Rules for processing 8644 * obscured nodes and interrupting work are the same as for the while 8645 * loop above. 8646 */ 8647 LOCK_ZONE(zone); 8648 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 8649 UNLOCK_ZONE(zone); 8650 first = true; 8651 buildnsecchain = false; 8652 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 8653 dns_dbiterator_pause(nsec3chain->dbiterator); 8654 8655 LOCK_ZONE(zone); 8656 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 8657 UNLOCK_ZONE(zone); 8658 8659 if (nsec3chain->db != db) { 8660 goto next_removechain; 8661 } 8662 8663 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) { 8664 goto next_removechain; 8665 } 8666 8667 /* 8668 * Work out if we need to build a NSEC chain as a consequence 8669 * of removing this NSEC3 chain. 8670 */ 8671 if (first && !updatensec && 8672 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) 8673 { 8674 result = need_nsec_chain(db, version, 8675 &nsec3chain->nsec3param, 8676 &buildnsecchain); 8677 if (result != ISC_R_SUCCESS) { 8678 dnssec_log(zone, ISC_LOG_ERROR, 8679 "zone_nsec3chain:" 8680 "need_nsec_chain -> %s", 8681 isc_result_totext(result)); 8682 goto failure; 8683 } 8684 } 8685 8686 if (first) { 8687 dnssec_log(zone, ISC_LOG_DEBUG(3), 8688 "zone_nsec3chain:buildnsecchain = %u\n", 8689 buildnsecchain); 8690 } 8691 8692 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 8693 dns_dbiterator_pause(nsec3chain->dbiterator); 8694 delegation = false; 8695 8696 if (!buildnsecchain) { 8697 /* 8698 * Delete the NSEC3PARAM record matching this chain. 8699 */ 8700 if (first) { 8701 result = fixup_nsec3param( 8702 db, version, nsec3chain, true, 8703 privatetype, ¶m_diff); 8704 if (result != ISC_R_SUCCESS) { 8705 dnssec_log(zone, ISC_LOG_ERROR, 8706 "zone_nsec3chain:" 8707 "fixup_nsec3param -> %s", 8708 isc_result_totext(result)); 8709 goto failure; 8710 } 8711 } 8712 8713 /* 8714 * Delete the NSEC3 records. 8715 */ 8716 result = deletematchingnsec3(db, version, node, name, 8717 &nsec3chain->nsec3param, 8718 &nsec3_diff); 8719 if (result != ISC_R_SUCCESS) { 8720 dnssec_log(zone, ISC_LOG_ERROR, 8721 "zone_nsec3chain:" 8722 "deletematchingnsec3 -> %s", 8723 isc_result_totext(result)); 8724 goto failure; 8725 } 8726 goto next_removenode; 8727 } 8728 8729 if (first) { 8730 dns_fixedname_t ffound; 8731 dns_name_t *found; 8732 found = dns_fixedname_initname(&ffound); 8733 result = dns_db_find( 8734 db, name, version, dns_rdatatype_soa, 8735 DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); 8736 if ((result == DNS_R_DELEGATION || 8737 result == DNS_R_DNAME) && 8738 !dns_name_equal(name, found)) 8739 { 8740 /* 8741 * Remember the obscuring name so that 8742 * we skip all obscured names. 8743 */ 8744 dns_name_copy(found, name); 8745 delegation = true; 8746 goto next_removenode; 8747 } 8748 } 8749 8750 /* 8751 * Check to see if this is a bottom of zone node. 8752 */ 8753 result = dns_db_allrdatasets(db, node, version, 0, 0, 8754 &iterator); 8755 if (result == ISC_R_NOTFOUND) { 8756 /* Empty node? */ 8757 goto next_removenode; 8758 } 8759 if (result != ISC_R_SUCCESS) { 8760 goto failure; 8761 } 8762 8763 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec = 8764 seen_rr = false; 8765 for (result = dns_rdatasetiter_first(iterator); 8766 result == ISC_R_SUCCESS; 8767 result = dns_rdatasetiter_next(iterator)) 8768 { 8769 dns_rdatasetiter_current(iterator, &rdataset); 8770 if (rdataset.type == dns_rdatatype_soa) { 8771 seen_soa = true; 8772 } else if (rdataset.type == dns_rdatatype_ns) { 8773 seen_ns = true; 8774 } else if (rdataset.type == dns_rdatatype_dname) { 8775 seen_dname = true; 8776 } else if (rdataset.type == dns_rdatatype_nsec) { 8777 seen_nsec = true; 8778 } else if (rdataset.type == dns_rdatatype_nsec3) { 8779 seen_nsec3 = true; 8780 } else if (rdataset.type != dns_rdatatype_rrsig) { 8781 seen_rr = true; 8782 } 8783 dns_rdataset_disassociate(&rdataset); 8784 } 8785 dns_rdatasetiter_destroy(&iterator); 8786 8787 if (!seen_rr || seen_nsec3 || seen_nsec) { 8788 goto next_removenode; 8789 } 8790 if ((seen_ns && !seen_soa) || seen_dname) { 8791 delegation = true; 8792 } 8793 8794 /* 8795 * Add a NSEC record except at the origin. 8796 */ 8797 if (!dns_name_equal(name, dns_db_origin(db))) { 8798 dns_dbiterator_pause(nsec3chain->dbiterator); 8799 CHECK(add_nsec(db, version, name, node, 8800 zone_nsecttl(zone), delegation, 8801 &nsec_diff)); 8802 signatures--; 8803 } 8804 8805 next_removenode: 8806 first = false; 8807 dns_db_detachnode(db, &node); 8808 do { 8809 result = dns_dbiterator_next(nsec3chain->dbiterator); 8810 if (result == ISC_R_NOMORE && buildnsecchain) { 8811 /* 8812 * The NSEC chain should now be built. 8813 * We can now remove the NSEC3 chain. 8814 */ 8815 updatensec = true; 8816 goto same_removechain; 8817 } 8818 if (result == ISC_R_NOMORE) { 8819 dns_dbiterator_pause(nsec3chain->dbiterator); 8820 LOCK_ZONE(zone); 8821 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 8822 link); 8823 UNLOCK_ZONE(zone); 8824 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8825 result = fixup_nsec3param( 8826 db, version, nsec3chain, false, 8827 privatetype, ¶m_diff); 8828 if (result != ISC_R_SUCCESS) { 8829 dnssec_log(zone, ISC_LOG_ERROR, 8830 "zone_nsec3chain:" 8831 "fixup_nsec3param -> %s", 8832 isc_result_totext(result)); 8833 goto failure; 8834 } 8835 goto next_removechain; 8836 } else if (result != ISC_R_SUCCESS) { 8837 dnssec_log(zone, ISC_LOG_ERROR, 8838 "zone_nsec3chain:" 8839 "dns_dbiterator_next -> %s", 8840 isc_result_totext(result)); 8841 goto failure; 8842 } else if (delegation) { 8843 dns_dbiterator_current(nsec3chain->dbiterator, 8844 &node, nextname); 8845 dns_db_detachnode(db, &node); 8846 if (!dns_name_issubdomain(nextname, name)) { 8847 break; 8848 } 8849 } else { 8850 break; 8851 } 8852 } while (1); 8853 continue; 8854 8855 same_removechain: 8856 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 8857 buildnsecchain = false; 8858 first = true; 8859 continue; 8860 8861 next_removechain: 8862 dns_dbiterator_pause(nsec3chain->dbiterator); 8863 nsec3chain = nextnsec3chain; 8864 first = true; 8865 } 8866 8867 skip_removals: 8868 /* 8869 * We may need to update the NSEC/NSEC3 records for the zone apex. 8870 */ 8871 if (!ISC_LIST_EMPTY(param_diff.tuples)) { 8872 bool rebuild_nsec = false, rebuild_nsec3 = false; 8873 result = dns_db_getoriginnode(db, &node); 8874 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8875 result = dns_db_allrdatasets(db, node, version, 0, 0, 8876 &iterator); 8877 if (result != ISC_R_SUCCESS) { 8878 dnssec_log(zone, ISC_LOG_ERROR, 8879 "zone_nsec3chain:dns_db_allrdatasets -> %s", 8880 isc_result_totext(result)); 8881 goto failure; 8882 } 8883 for (result = dns_rdatasetiter_first(iterator); 8884 result == ISC_R_SUCCESS; 8885 result = dns_rdatasetiter_next(iterator)) 8886 { 8887 dns_rdatasetiter_current(iterator, &rdataset); 8888 if (rdataset.type == dns_rdatatype_nsec) { 8889 rebuild_nsec = true; 8890 } else if (rdataset.type == dns_rdatatype_nsec3param) { 8891 rebuild_nsec3 = true; 8892 } 8893 dns_rdataset_disassociate(&rdataset); 8894 } 8895 dns_rdatasetiter_destroy(&iterator); 8896 dns_db_detachnode(db, &node); 8897 8898 if (rebuild_nsec) { 8899 if (nsec3chain != NULL) { 8900 dns_dbiterator_pause(nsec3chain->dbiterator); 8901 } 8902 8903 result = updatesecure(db, version, &zone->origin, 8904 zone_nsecttl(zone), true, 8905 &nsec_diff); 8906 if (result != ISC_R_SUCCESS) { 8907 dnssec_log(zone, ISC_LOG_ERROR, 8908 "zone_nsec3chain:updatesecure -> %s", 8909 isc_result_totext(result)); 8910 goto failure; 8911 } 8912 } 8913 8914 if (rebuild_nsec3) { 8915 if (nsec3chain != NULL) { 8916 dns_dbiterator_pause(nsec3chain->dbiterator); 8917 } 8918 8919 result = dns_nsec3_addnsec3s( 8920 db, version, dns_db_origin(db), 8921 zone_nsecttl(zone), false, &nsec3_diff); 8922 if (result != ISC_R_SUCCESS) { 8923 dnssec_log(zone, ISC_LOG_ERROR, 8924 "zone_nsec3chain:" 8925 "dns_nsec3_addnsec3s -> %s", 8926 isc_result_totext(result)); 8927 goto failure; 8928 } 8929 } 8930 } 8931 8932 /* 8933 * Add / update signatures for the NSEC3 records. 8934 */ 8935 if (nsec3chain != NULL) { 8936 dns_dbiterator_pause(nsec3chain->dbiterator); 8937 } 8938 result = dns__zone_updatesigs(&nsec3_diff, db, version, zone_keys, 8939 nkeys, zone, inception, expire, 0, now, 8940 &zonediff); 8941 if (result != ISC_R_SUCCESS) { 8942 dnssec_log(zone, ISC_LOG_ERROR, 8943 "zone_nsec3chain:dns__zone_updatesigs -> %s", 8944 isc_result_totext(result)); 8945 goto failure; 8946 } 8947 8948 /* 8949 * We have changed the NSEC3PARAM or private RRsets 8950 * above so we need to update the signatures. 8951 */ 8952 result = dns__zone_updatesigs(¶m_diff, db, version, zone_keys, 8953 nkeys, zone, inception, expire, 0, now, 8954 &zonediff); 8955 if (result != ISC_R_SUCCESS) { 8956 dnssec_log(zone, ISC_LOG_ERROR, 8957 "zone_nsec3chain:dns__zone_updatesigs -> %s", 8958 isc_result_totext(result)); 8959 goto failure; 8960 } 8961 8962 if (updatensec) { 8963 result = updatesecure(db, version, &zone->origin, 8964 zone_nsecttl(zone), false, &nsec_diff); 8965 if (result != ISC_R_SUCCESS) { 8966 dnssec_log(zone, ISC_LOG_ERROR, 8967 "zone_nsec3chain:updatesecure -> %s", 8968 isc_result_totext(result)); 8969 goto failure; 8970 } 8971 } 8972 8973 result = dns__zone_updatesigs(&nsec_diff, db, version, zone_keys, nkeys, 8974 zone, inception, expire, 0, now, 8975 &zonediff); 8976 if (result != ISC_R_SUCCESS) { 8977 dnssec_log(zone, ISC_LOG_ERROR, 8978 "zone_nsec3chain:dns__zone_updatesigs -> %s", 8979 isc_result_totext(result)); 8980 goto failure; 8981 } 8982 8983 /* 8984 * If we made no effective changes to the zone then we can just 8985 * cleanup otherwise we need to increment the serial. 8986 */ 8987 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 8988 /* 8989 * No need to call dns_db_closeversion() here as it is 8990 * called with commit = true below. 8991 */ 8992 goto done; 8993 } 8994 8995 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 8996 &zonediff, zone_keys, nkeys, now, false); 8997 if (result != ISC_R_SUCCESS) { 8998 dnssec_log(zone, ISC_LOG_ERROR, 8999 "zone_nsec3chain:del_sigs -> %s", 9000 isc_result_totext(result)); 9001 goto failure; 9002 } 9003 9004 result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx, 9005 zone->updatemethod); 9006 if (result != ISC_R_SUCCESS) { 9007 dnssec_log(zone, ISC_LOG_ERROR, 9008 "zone_nsec3chain:update_soa_serial -> %s", 9009 isc_result_totext(result)); 9010 goto failure; 9011 } 9012 9013 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa, 9014 zonediff.diff, zone_keys, nkeys, zone->mctx, now, 9015 inception, soaexpire); 9016 if (result != ISC_R_SUCCESS) { 9017 dnssec_log(zone, ISC_LOG_ERROR, 9018 "zone_nsec3chain:add_sigs -> %s", 9019 isc_result_totext(result)); 9020 goto failure; 9021 } 9022 9023 /* Write changes to journal file. */ 9024 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain")); 9025 9026 LOCK_ZONE(zone); 9027 zone_needdump(zone, DNS_DUMP_DELAY); 9028 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 9029 UNLOCK_ZONE(zone); 9030 9031 done: 9032 /* 9033 * Pause all iterators so that dns_db_closeversion() can succeed. 9034 */ 9035 LOCK_ZONE(zone); 9036 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL; 9037 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 9038 { 9039 dns_dbiterator_pause(nsec3chain->dbiterator); 9040 } 9041 UNLOCK_ZONE(zone); 9042 9043 /* 9044 * Everything has succeeded. Commit the changes. 9045 * Unconditionally commit as zonediff.offline not checked above. 9046 */ 9047 dns_db_closeversion(db, &version, true); 9048 9049 /* 9050 * Everything succeeded so we can clean these up now. 9051 */ 9052 nsec3chain = ISC_LIST_HEAD(cleanup); 9053 while (nsec3chain != NULL) { 9054 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 9055 dns_db_detach(&nsec3chain->db); 9056 dns_dbiterator_destroy(&nsec3chain->dbiterator); 9057 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 9058 nsec3chain = ISC_LIST_HEAD(cleanup); 9059 } 9060 9061 LOCK_ZONE(zone); 9062 set_resigntime(zone); 9063 UNLOCK_ZONE(zone); 9064 9065 failure: 9066 if (result != ISC_R_SUCCESS) { 9067 dnssec_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s", 9068 isc_result_totext(result)); 9069 } 9070 9071 /* 9072 * On error roll back the current nsec3chain. 9073 */ 9074 if (result != ISC_R_SUCCESS && nsec3chain != NULL) { 9075 if (nsec3chain->done) { 9076 dns_db_detach(&nsec3chain->db); 9077 dns_dbiterator_destroy(&nsec3chain->dbiterator); 9078 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 9079 } else { 9080 result = dns_dbiterator_first(nsec3chain->dbiterator); 9081 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9082 dns_dbiterator_pause(nsec3chain->dbiterator); 9083 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 9084 } 9085 } 9086 9087 /* 9088 * Rollback the cleanup list. 9089 */ 9090 nsec3chain = ISC_LIST_TAIL(cleanup); 9091 while (nsec3chain != NULL) { 9092 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 9093 if (nsec3chain->done) { 9094 dns_db_detach(&nsec3chain->db); 9095 dns_dbiterator_destroy(&nsec3chain->dbiterator); 9096 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 9097 } else { 9098 LOCK_ZONE(zone); 9099 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link); 9100 UNLOCK_ZONE(zone); 9101 result = dns_dbiterator_first(nsec3chain->dbiterator); 9102 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9103 dns_dbiterator_pause(nsec3chain->dbiterator); 9104 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 9105 } 9106 nsec3chain = ISC_LIST_TAIL(cleanup); 9107 } 9108 9109 LOCK_ZONE(zone); 9110 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL; 9111 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 9112 { 9113 dns_dbiterator_pause(nsec3chain->dbiterator); 9114 } 9115 UNLOCK_ZONE(zone); 9116 9117 dns_diff_clear(¶m_diff); 9118 dns_diff_clear(&nsec3_diff); 9119 dns_diff_clear(&nsec_diff); 9120 dns_diff_clear(&_sig_diff); 9121 9122 if (iterator != NULL) { 9123 dns_rdatasetiter_destroy(&iterator); 9124 } 9125 9126 for (i = 0; i < nkeys; i++) { 9127 dst_key_free(&zone_keys[i]); 9128 } 9129 9130 if (node != NULL) { 9131 dns_db_detachnode(db, &node); 9132 } 9133 if (version != NULL) { 9134 dns_db_closeversion(db, &version, false); 9135 dns_db_detach(&db); 9136 } else if (db != NULL) { 9137 dns_db_detach(&db); 9138 } 9139 9140 LOCK_ZONE(zone); 9141 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) { 9142 isc_interval_t interval; 9143 if (zone->update_disabled || result != ISC_R_SUCCESS) { 9144 isc_interval_set(&interval, 60, 0); /* 1 minute */ 9145 } else { 9146 isc_interval_set(&interval, 0, 10000000); /* 10 ms */ 9147 } 9148 isc_time_nowplusinterval(&zone->nsec3chaintime, &interval); 9149 } else { 9150 isc_time_settoepoch(&zone->nsec3chaintime); 9151 } 9152 UNLOCK_ZONE(zone); 9153 9154 INSIST(version == NULL); 9155 } 9156 9157 /*% 9158 * Delete all RRSIG records with the given algorithm and keyid. 9159 * Remove the NSEC record and RRSIGs if nkeys is zero. 9160 * If all remaining RRsets are signed with the given algorithm 9161 * set *has_algp to true. 9162 */ 9163 static isc_result_t 9164 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 9165 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm, 9166 uint16_t keyid, bool *has_algp, dns_diff_t *diff) { 9167 dns_rdata_rrsig_t rrsig; 9168 dns_rdataset_t rdataset; 9169 dns_rdatasetiter_t *iterator = NULL; 9170 isc_result_t result; 9171 bool alg_missed = false; 9172 bool alg_found = false; 9173 9174 char namebuf[DNS_NAME_FORMATSIZE]; 9175 dns_name_format(name, namebuf, sizeof(namebuf)); 9176 9177 result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator); 9178 if (result != ISC_R_SUCCESS) { 9179 if (result == ISC_R_NOTFOUND) { 9180 result = ISC_R_SUCCESS; 9181 } 9182 return result; 9183 } 9184 9185 dns_rdataset_init(&rdataset); 9186 for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; 9187 result = dns_rdatasetiter_next(iterator)) 9188 { 9189 bool has_alg = false; 9190 dns_rdatasetiter_current(iterator, &rdataset); 9191 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) { 9192 for (result = dns_rdataset_first(&rdataset); 9193 result == ISC_R_SUCCESS; 9194 result = dns_rdataset_next(&rdataset)) 9195 { 9196 dns_rdata_t rdata = DNS_RDATA_INIT; 9197 dns_rdataset_current(&rdataset, &rdata); 9198 CHECK(update_one_rr(db, version, diff, 9199 DNS_DIFFOP_DEL, name, 9200 rdataset.ttl, &rdata)); 9201 } 9202 if (result != ISC_R_NOMORE) { 9203 goto failure; 9204 } 9205 dns_rdataset_disassociate(&rdataset); 9206 continue; 9207 } 9208 if (rdataset.type != dns_rdatatype_rrsig) { 9209 dns_rdataset_disassociate(&rdataset); 9210 continue; 9211 } 9212 for (result = dns_rdataset_first(&rdataset); 9213 result == ISC_R_SUCCESS; 9214 result = dns_rdataset_next(&rdataset)) 9215 { 9216 dns_rdata_t rdata = DNS_RDATA_INIT; 9217 dns_rdataset_current(&rdataset, &rdata); 9218 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL)); 9219 if (nkeys != 0 && (rrsig.algorithm != algorithm || 9220 rrsig.keyid != keyid)) 9221 { 9222 if (rrsig.algorithm == algorithm) { 9223 has_alg = true; 9224 } 9225 continue; 9226 } 9227 CHECK(update_one_rr(db, version, diff, 9228 DNS_DIFFOP_DELRESIGN, name, 9229 rdataset.ttl, &rdata)); 9230 } 9231 dns_rdataset_disassociate(&rdataset); 9232 if (result != ISC_R_NOMORE) { 9233 break; 9234 } 9235 9236 /* 9237 * After deleting, if there's still a signature for 9238 * 'algorithm', set alg_found; if not, set alg_missed. 9239 */ 9240 if (has_alg) { 9241 alg_found = true; 9242 } else { 9243 alg_missed = true; 9244 } 9245 } 9246 if (result == ISC_R_NOMORE) { 9247 result = ISC_R_SUCCESS; 9248 } 9249 9250 /* 9251 * Set `has_algp` if the algorithm was found in every RRset: 9252 * i.e., found in at least one, and not missing from any. 9253 */ 9254 *has_algp = (alg_found && !alg_missed); 9255 failure: 9256 if (dns_rdataset_isassociated(&rdataset)) { 9257 dns_rdataset_disassociate(&rdataset); 9258 } 9259 dns_rdatasetiter_destroy(&iterator); 9260 return result; 9261 } 9262 9263 /* 9264 * Prevent the zone entering a inconsistent state where 9265 * NSEC only DNSKEYs are present with NSEC3 chains. 9266 */ 9267 bool 9268 dns_zone_check_dnskey_nsec3(dns_zone_t *zone, dns_db_t *db, 9269 dns_dbversion_t *ver, dns_diff_t *diff, 9270 dst_key_t **keys, unsigned int numkeys) { 9271 uint8_t alg; 9272 dns_rdatatype_t privatetype; 9273 ; 9274 bool nseconly = false, nsec3 = false; 9275 isc_result_t result; 9276 9277 REQUIRE(DNS_ZONE_VALID(zone)); 9278 REQUIRE(db != NULL); 9279 9280 privatetype = dns_zone_getprivatetype(zone); 9281 9282 /* Scan the tuples for an NSEC-only DNSKEY */ 9283 if (diff != NULL) { 9284 for (dns_difftuple_t *tuple = ISC_LIST_HEAD(diff->tuples); 9285 tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) 9286 { 9287 if (nseconly && nsec3) { 9288 break; 9289 } 9290 9291 if (tuple->op != DNS_DIFFOP_ADD) { 9292 continue; 9293 } 9294 9295 if (tuple->rdata.type == dns_rdatatype_nsec3param) { 9296 nsec3 = true; 9297 } 9298 9299 if (tuple->rdata.type != dns_rdatatype_dnskey) { 9300 continue; 9301 } 9302 9303 alg = tuple->rdata.data[3]; 9304 if (alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_DSA || 9305 alg == DNS_KEYALG_RSASHA1) 9306 { 9307 nseconly = true; 9308 } 9309 } 9310 } 9311 /* Scan the zone keys for an NSEC-only DNSKEY */ 9312 if (keys != NULL && !nseconly) { 9313 for (unsigned int i = 0; i < numkeys; i++) { 9314 alg = dst_key_alg(keys[i]); 9315 if (alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_DSA || 9316 alg == DNS_KEYALG_RSASHA1) 9317 { 9318 nseconly = true; 9319 break; 9320 } 9321 } 9322 } 9323 9324 /* Check DB for NSEC-only DNSKEY */ 9325 if (!nseconly) { 9326 result = dns_nsec_nseconly(db, ver, diff, &nseconly); 9327 /* 9328 * Adding an NSEC3PARAM record can proceed without a 9329 * DNSKEY (it will trigger a delayed change), so we can 9330 * ignore ISC_R_NOTFOUND here. 9331 */ 9332 if (result == ISC_R_NOTFOUND) { 9333 result = ISC_R_SUCCESS; 9334 } 9335 CHECK(result); 9336 } 9337 9338 /* Check existing DB for NSEC3 */ 9339 if (!nsec3) { 9340 CHECK(dns_nsec3_activex(db, ver, false, privatetype, &nsec3)); 9341 } 9342 9343 /* Check kasp for NSEC3PARAM settings */ 9344 if (!nsec3) { 9345 dns_kasp_t *kasp = zone->kasp; 9346 if (kasp != NULL) { 9347 nsec3 = dns_kasp_nsec3(kasp); 9348 } 9349 } 9350 9351 /* Refuse to allow NSEC3 with NSEC-only keys */ 9352 if (nseconly && nsec3) { 9353 goto failure; 9354 } 9355 9356 return true; 9357 9358 failure: 9359 return false; 9360 } 9361 9362 /* 9363 * Incrementally sign the zone using the keys requested. 9364 * Builds the NSEC chain if required. 9365 */ 9366 static void 9367 zone_sign(dns_zone_t *zone) { 9368 dns_db_t *db = NULL; 9369 dns_dbnode_t *node = NULL; 9370 dns_dbversion_t *version = NULL; 9371 dns_diff_t _sig_diff; 9372 dns_diff_t post_diff; 9373 dns__zonediff_t zonediff; 9374 dns_fixedname_t fixed; 9375 dns_fixedname_t nextfixed; 9376 dns_kasp_t *kasp; 9377 dns_name_t *name, *nextname; 9378 dns_rdataset_t rdataset; 9379 dns_signing_t *signing, *nextsigning; 9380 dns_signinglist_t cleanup; 9381 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 9382 int32_t signatures; 9383 bool is_ksk, is_zsk; 9384 bool with_ksk, with_zsk; 9385 bool commit = false; 9386 bool is_bottom_of_zone; 9387 bool build_nsec = false; 9388 bool build_nsec3 = false; 9389 bool use_kasp = false; 9390 bool first; 9391 isc_result_t result; 9392 isc_stdtime_t now, inception, soaexpire, expire; 9393 unsigned int i, j; 9394 unsigned int nkeys = 0; 9395 uint32_t nodes; 9396 9397 ENTER; 9398 9399 dns_rdataset_init(&rdataset); 9400 name = dns_fixedname_initname(&fixed); 9401 nextname = dns_fixedname_initname(&nextfixed); 9402 dns_diff_init(zone->mctx, &_sig_diff); 9403 dns_diff_init(zone->mctx, &post_diff); 9404 zonediff_init(&zonediff, &_sig_diff); 9405 ISC_LIST_INIT(cleanup); 9406 9407 /* 9408 * Updates are disabled. Pause for 1 minute. 9409 */ 9410 if (zone->update_disabled) { 9411 result = ISC_R_FAILURE; 9412 goto cleanup; 9413 } 9414 9415 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9416 if (zone->db != NULL) { 9417 dns_db_attach(zone->db, &db); 9418 } 9419 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9420 if (db == NULL) { 9421 result = ISC_R_FAILURE; 9422 goto cleanup; 9423 } 9424 9425 result = dns_db_newversion(db, &version); 9426 if (result != ISC_R_SUCCESS) { 9427 dnssec_log(zone, ISC_LOG_ERROR, 9428 "zone_sign:dns_db_newversion -> %s", 9429 isc_result_totext(result)); 9430 goto cleanup; 9431 } 9432 9433 now = isc_stdtime_now(); 9434 9435 result = dns_zone_findkeys(zone, db, version, now, zone->mctx, 9436 DNS_MAXZONEKEYS, zone_keys, &nkeys); 9437 if (result != ISC_R_SUCCESS) { 9438 dnssec_log(zone, ISC_LOG_ERROR, 9439 "zone_sign:dns_zone_findkeys -> %s", 9440 isc_result_totext(result)); 9441 goto cleanup; 9442 } 9443 9444 kasp = zone->kasp; 9445 9446 calculate_rrsig_validity(zone, now, &inception, &soaexpire, NULL, 9447 &expire); 9448 9449 /* 9450 * We keep pulling nodes off each iterator in turn until 9451 * we have no more nodes to pull off or we reach the limits 9452 * for this quantum. 9453 */ 9454 nodes = zone->nodes; 9455 signatures = zone->signatures; 9456 signing = ISC_LIST_HEAD(zone->signing); 9457 first = true; 9458 9459 if (kasp != NULL) { 9460 use_kasp = true; 9461 } 9462 dnssec_log(zone, ISC_LOG_DEBUG(3), "zone_sign:use kasp -> %s", 9463 use_kasp ? "yes" : "no"); 9464 9465 /* Determine which type of chain to build */ 9466 CHECK(dns_private_chains(db, version, zone->privatetype, &build_nsec, 9467 &build_nsec3)); 9468 if (!build_nsec && !build_nsec3) { 9469 if (use_kasp) { 9470 build_nsec3 = dns_kasp_nsec3(kasp); 9471 if (!dns_zone_check_dnskey_nsec3( 9472 zone, db, version, NULL, 9473 (dst_key_t **)&zone_keys, nkeys)) 9474 { 9475 dnssec_log(zone, ISC_LOG_INFO, 9476 "wait building NSEC3 chain until " 9477 "NSEC only DNSKEYs are removed"); 9478 build_nsec3 = false; 9479 } 9480 build_nsec = !build_nsec3; 9481 } else { 9482 /* If neither chain is found, default to NSEC */ 9483 build_nsec = true; 9484 } 9485 } 9486 9487 while (signing != NULL && nodes-- > 0 && signatures > 0) { 9488 bool has_alg = false; 9489 9490 dns_dbiterator_pause(signing->dbiterator); 9491 nextsigning = ISC_LIST_NEXT(signing, link); 9492 9493 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9494 if (signing->done || signing->db != zone->db) { 9495 /* 9496 * The zone has been reloaded. We will have to 9497 * created new signings as part of the reload 9498 * process so we can destroy this one. 9499 */ 9500 ISC_LIST_UNLINK(zone->signing, signing, link); 9501 ISC_LIST_APPEND(cleanup, signing, link); 9502 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9503 goto next_signing; 9504 } 9505 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9506 9507 if (signing->db != db) { 9508 goto next_signing; 9509 } 9510 9511 is_bottom_of_zone = false; 9512 9513 if (first && signing->deleteit) { 9514 /* 9515 * Remove the key we are deleting from consideration. 9516 */ 9517 for (i = 0, j = 0; i < nkeys; i++) { 9518 /* 9519 * Find the key we want to remove. 9520 */ 9521 if (ALG(zone_keys[i]) == signing->algorithm && 9522 dst_key_id(zone_keys[i]) == signing->keyid) 9523 { 9524 dst_key_free(&zone_keys[i]); 9525 continue; 9526 } 9527 zone_keys[j] = zone_keys[i]; 9528 j++; 9529 } 9530 for (i = j; i < nkeys; i++) { 9531 zone_keys[i] = NULL; 9532 } 9533 nkeys = j; 9534 } 9535 9536 dns_dbiterator_current(signing->dbiterator, &node, name); 9537 9538 if (signing->deleteit) { 9539 dns_dbiterator_pause(signing->dbiterator); 9540 CHECK(del_sig(db, version, name, node, nkeys, 9541 signing->algorithm, signing->keyid, 9542 &has_alg, zonediff.diff)); 9543 } 9544 9545 /* 9546 * On the first pass we need to check if the current node 9547 * has not been obscured. 9548 */ 9549 if (first) { 9550 dns_fixedname_t ffound; 9551 dns_name_t *found; 9552 found = dns_fixedname_initname(&ffound); 9553 result = dns_db_find( 9554 db, name, version, dns_rdatatype_soa, 9555 DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); 9556 if ((result == DNS_R_DELEGATION || 9557 result == DNS_R_DNAME) && 9558 !dns_name_equal(name, found)) 9559 { 9560 /* 9561 * Remember the obscuring name so that 9562 * we skip all obscured names. 9563 */ 9564 dns_name_copy(found, name); 9565 is_bottom_of_zone = true; 9566 goto next_node; 9567 } 9568 } 9569 9570 /* 9571 * Process one node. 9572 */ 9573 with_ksk = false; 9574 with_zsk = false; 9575 dns_dbiterator_pause(signing->dbiterator); 9576 9577 CHECK(check_if_bottom_of_zone(db, node, version, 9578 &is_bottom_of_zone)); 9579 9580 for (i = 0; !has_alg && i < nkeys; i++) { 9581 bool both = false; 9582 /* 9583 * Find the keys we want to sign with. 9584 */ 9585 if (!dst_key_isprivate(zone_keys[i])) { 9586 continue; 9587 } 9588 if (dst_key_inactive(zone_keys[i])) { 9589 continue; 9590 } 9591 9592 /* 9593 * When adding look for the specific key. 9594 */ 9595 if (!signing->deleteit && 9596 (dst_key_alg(zone_keys[i]) != signing->algorithm || 9597 dst_key_id(zone_keys[i]) != signing->keyid)) 9598 { 9599 continue; 9600 } 9601 9602 /* 9603 * When deleting make sure we are properly signed 9604 * with the algorithm that was being removed. 9605 */ 9606 if (signing->deleteit && 9607 ALG(zone_keys[i]) != signing->algorithm) 9608 { 9609 continue; 9610 } 9611 9612 /* 9613 * We do KSK processing. 9614 */ 9615 if (use_kasp) { 9616 /* 9617 * A dnssec-policy is found. Check what 9618 * RRsets this key can sign. 9619 */ 9620 isc_result_t kresult; 9621 is_ksk = false; 9622 kresult = dst_key_getbool( 9623 zone_keys[i], DST_BOOL_KSK, &is_ksk); 9624 if (kresult != ISC_R_SUCCESS) { 9625 if (KSK(zone_keys[i])) { 9626 is_ksk = true; 9627 } 9628 } 9629 9630 is_zsk = false; 9631 kresult = dst_key_getbool( 9632 zone_keys[i], DST_BOOL_ZSK, &is_zsk); 9633 if (kresult != ISC_R_SUCCESS) { 9634 if (!KSK(zone_keys[i])) { 9635 is_zsk = true; 9636 } 9637 } 9638 both = true; 9639 } else { 9640 is_ksk = KSK(zone_keys[i]); 9641 is_zsk = !is_ksk; 9642 9643 /* 9644 * Don't consider inactive keys, however the key 9645 * may be temporary offline, so do consider KSKs 9646 * which private key files are unavailable. 9647 */ 9648 both = dst_key_have_ksk_and_zsk( 9649 zone_keys, nkeys, i, false, is_ksk, 9650 is_zsk, NULL, NULL); 9651 if (both || REVOKE(zone_keys[i])) { 9652 is_ksk = KSK(zone_keys[i]); 9653 is_zsk = !KSK(zone_keys[i]); 9654 } else { 9655 is_ksk = false; 9656 is_zsk = false; 9657 } 9658 } 9659 9660 /* 9661 * If deleting signatures, we need to ensure that 9662 * the RRset is still signed at least once by a 9663 * KSK and a ZSK. 9664 */ 9665 if (signing->deleteit && is_zsk && with_zsk) { 9666 continue; 9667 } 9668 9669 if (signing->deleteit && is_ksk && with_ksk) { 9670 continue; 9671 } 9672 9673 CHECK(sign_a_node( 9674 db, zone, name, node, version, build_nsec3, 9675 build_nsec, zone_keys[i], now, inception, 9676 expire, zone_nsecttl(zone), both, is_ksk, 9677 is_zsk, is_bottom_of_zone, zonediff.diff, 9678 &signatures, zone->mctx)); 9679 /* 9680 * If we are adding we are done. Look for other keys 9681 * of the same algorithm if deleting. 9682 */ 9683 if (!signing->deleteit) { 9684 break; 9685 } 9686 if (is_zsk) { 9687 with_zsk = true; 9688 } 9689 if (is_ksk) { 9690 with_ksk = true; 9691 } 9692 } 9693 9694 /* 9695 * Go onto next node. 9696 */ 9697 next_node: 9698 first = false; 9699 dns_db_detachnode(db, &node); 9700 do { 9701 result = dns_dbiterator_next(signing->dbiterator); 9702 if (result == ISC_R_NOMORE) { 9703 ISC_LIST_UNLINK(zone->signing, signing, link); 9704 ISC_LIST_APPEND(cleanup, signing, link); 9705 dns_dbiterator_pause(signing->dbiterator); 9706 if (nkeys != 0 && build_nsec) { 9707 /* 9708 * We have finished regenerating the 9709 * zone with a zone signing key. 9710 * The NSEC chain is now complete and 9711 * there is a full set of signatures 9712 * for the zone. We can now clear the 9713 * OPT bit from the NSEC record. 9714 */ 9715 result = updatesecure( 9716 db, version, &zone->origin, 9717 zone_nsecttl(zone), false, 9718 &post_diff); 9719 if (result != ISC_R_SUCCESS) { 9720 dnssec_log(zone, ISC_LOG_ERROR, 9721 "updatesecure -> %s", 9722 isc_result_totext( 9723 result)); 9724 goto cleanup; 9725 } 9726 } 9727 result = updatesignwithkey( 9728 zone, signing, version, build_nsec3, 9729 zone_nsecttl(zone), &post_diff); 9730 if (result != ISC_R_SUCCESS) { 9731 dnssec_log(zone, ISC_LOG_ERROR, 9732 "updatesignwithkey -> %s", 9733 isc_result_totext(result)); 9734 goto cleanup; 9735 } 9736 build_nsec = false; 9737 goto next_signing; 9738 } else if (result != ISC_R_SUCCESS) { 9739 dnssec_log(zone, ISC_LOG_ERROR, 9740 "zone_sign:" 9741 "dns_dbiterator_next -> %s", 9742 isc_result_totext(result)); 9743 goto cleanup; 9744 } else if (is_bottom_of_zone) { 9745 dns_dbiterator_current(signing->dbiterator, 9746 &node, nextname); 9747 dns_db_detachnode(db, &node); 9748 if (!dns_name_issubdomain(nextname, name)) { 9749 break; 9750 } 9751 } else { 9752 break; 9753 } 9754 } while (1); 9755 continue; 9756 9757 next_signing: 9758 dns_dbiterator_pause(signing->dbiterator); 9759 signing = nextsigning; 9760 first = true; 9761 } 9762 9763 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) { 9764 result = dns__zone_updatesigs(&post_diff, db, version, 9765 zone_keys, nkeys, zone, inception, 9766 expire, 0, now, &zonediff); 9767 if (result != ISC_R_SUCCESS) { 9768 dnssec_log(zone, ISC_LOG_ERROR, 9769 "zone_sign:dns__zone_updatesigs -> %s", 9770 isc_result_totext(result)); 9771 goto cleanup; 9772 } 9773 } 9774 9775 /* 9776 * Have we changed anything? 9777 */ 9778 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 9779 if (zonediff.offline) { 9780 commit = true; 9781 } 9782 result = ISC_R_SUCCESS; 9783 goto pauseall; 9784 } 9785 9786 commit = true; 9787 9788 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 9789 &zonediff, zone_keys, nkeys, now, false); 9790 if (result != ISC_R_SUCCESS) { 9791 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:del_sigs -> %s", 9792 isc_result_totext(result)); 9793 goto cleanup; 9794 } 9795 9796 result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx, 9797 zone->updatemethod); 9798 if (result != ISC_R_SUCCESS) { 9799 dnssec_log(zone, ISC_LOG_ERROR, 9800 "zone_sign:update_soa_serial -> %s", 9801 isc_result_totext(result)); 9802 goto cleanup; 9803 } 9804 9805 /* 9806 * Generate maximum life time signatures so that the above loop 9807 * termination is sensible. 9808 */ 9809 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa, 9810 zonediff.diff, zone_keys, nkeys, zone->mctx, now, 9811 inception, soaexpire); 9812 if (result != ISC_R_SUCCESS) { 9813 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:add_sigs -> %s", 9814 isc_result_totext(result)); 9815 goto cleanup; 9816 } 9817 9818 /* 9819 * Write changes to journal file. 9820 */ 9821 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign")); 9822 9823 pauseall: 9824 /* 9825 * Pause all iterators so that dns_db_closeversion() can succeed. 9826 */ 9827 for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; 9828 signing = ISC_LIST_NEXT(signing, link)) 9829 { 9830 dns_dbiterator_pause(signing->dbiterator); 9831 } 9832 9833 for (signing = ISC_LIST_HEAD(cleanup); signing != NULL; 9834 signing = ISC_LIST_NEXT(signing, link)) 9835 { 9836 dns_dbiterator_pause(signing->dbiterator); 9837 } 9838 9839 /* 9840 * Everything has succeeded. Commit the changes. 9841 */ 9842 dns_db_closeversion(db, &version, commit); 9843 9844 /* 9845 * Everything succeeded so we can clean these up now. 9846 */ 9847 signing = ISC_LIST_HEAD(cleanup); 9848 while (signing != NULL) { 9849 ISC_LIST_UNLINK(cleanup, signing, link); 9850 dns_db_detach(&signing->db); 9851 dns_dbiterator_destroy(&signing->dbiterator); 9852 isc_mem_put(zone->mctx, signing, sizeof *signing); 9853 signing = ISC_LIST_HEAD(cleanup); 9854 } 9855 9856 LOCK_ZONE(zone); 9857 set_resigntime(zone); 9858 if (commit) { 9859 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 9860 zone_needdump(zone, DNS_DUMP_DELAY); 9861 } 9862 UNLOCK_ZONE(zone); 9863 9864 failure: 9865 if (result != ISC_R_SUCCESS) { 9866 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign: failed: %s", 9867 isc_result_totext(result)); 9868 } 9869 9870 cleanup: 9871 /* 9872 * Pause all dbiterators. 9873 */ 9874 for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; 9875 signing = ISC_LIST_NEXT(signing, link)) 9876 { 9877 dns_dbiterator_pause(signing->dbiterator); 9878 } 9879 9880 /* 9881 * Rollback the cleanup list. 9882 */ 9883 signing = ISC_LIST_HEAD(cleanup); 9884 while (signing != NULL) { 9885 ISC_LIST_UNLINK(cleanup, signing, link); 9886 ISC_LIST_PREPEND(zone->signing, signing, link); 9887 dns_dbiterator_first(signing->dbiterator); 9888 dns_dbiterator_pause(signing->dbiterator); 9889 signing = ISC_LIST_HEAD(cleanup); 9890 } 9891 9892 dns_diff_clear(&_sig_diff); 9893 dns_diff_clear(&post_diff); 9894 9895 for (i = 0; i < nkeys; i++) { 9896 dst_key_free(&zone_keys[i]); 9897 } 9898 9899 if (node != NULL) { 9900 dns_db_detachnode(db, &node); 9901 } 9902 9903 if (version != NULL) { 9904 dns_db_closeversion(db, &version, false); 9905 dns_db_detach(&db); 9906 } else if (db != NULL) { 9907 dns_db_detach(&db); 9908 } 9909 9910 LOCK_ZONE(zone); 9911 if (ISC_LIST_HEAD(zone->signing) != NULL) { 9912 isc_interval_t interval; 9913 if (zone->update_disabled || result != ISC_R_SUCCESS) { 9914 isc_interval_set(&interval, 60, 0); /* 1 minute */ 9915 } else { 9916 isc_interval_set(&interval, 0, 10000000); /* 10 ms */ 9917 } 9918 isc_time_nowplusinterval(&zone->signingtime, &interval); 9919 } else { 9920 isc_time_settoepoch(&zone->signingtime); 9921 } 9922 UNLOCK_ZONE(zone); 9923 9924 INSIST(version == NULL); 9925 } 9926 9927 static isc_result_t 9928 normalize_key(dns_rdata_t *rr, dns_rdata_t *target, unsigned char *data, 9929 int size) { 9930 dns_rdata_dnskey_t dnskey; 9931 dns_rdata_keydata_t keydata; 9932 isc_buffer_t buf; 9933 isc_result_t result; 9934 9935 dns_rdata_reset(target); 9936 isc_buffer_init(&buf, data, size); 9937 9938 switch (rr->type) { 9939 case dns_rdatatype_dnskey: 9940 result = dns_rdata_tostruct(rr, &dnskey, NULL); 9941 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9942 dnskey.flags &= ~DNS_KEYFLAG_REVOKE; 9943 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 9944 &dnskey, &buf); 9945 break; 9946 case dns_rdatatype_keydata: 9947 result = dns_rdata_tostruct(rr, &keydata, NULL); 9948 if (result == ISC_R_UNEXPECTEDEND) { 9949 return result; 9950 } 9951 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9952 dns_keydata_todnskey(&keydata, &dnskey, NULL); 9953 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 9954 &dnskey, &buf); 9955 break; 9956 default: 9957 UNREACHABLE(); 9958 } 9959 return ISC_R_SUCCESS; 9960 } 9961 9962 /* 9963 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or 9964 * a KEYDATA rdataset from the key zone. 9965 * 9966 * 'rr' contains either a DNSKEY record, or a KEYDATA record 9967 * 9968 * After normalizing keys to the same format (DNSKEY, with revoke bit 9969 * cleared), return true if a key that matches 'rr' is found in 9970 * 'rdset', or false if not. 9971 */ 9972 9973 static bool 9974 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) { 9975 unsigned char data1[4096], data2[4096]; 9976 dns_rdata_t rdata, rdata1, rdata2; 9977 isc_result_t result; 9978 9979 dns_rdata_init(&rdata); 9980 dns_rdata_init(&rdata1); 9981 dns_rdata_init(&rdata2); 9982 9983 result = normalize_key(rr, &rdata1, data1, sizeof(data1)); 9984 if (result != ISC_R_SUCCESS) { 9985 return false; 9986 } 9987 9988 for (result = dns_rdataset_first(rdset); result == ISC_R_SUCCESS; 9989 result = dns_rdataset_next(rdset)) 9990 { 9991 dns_rdata_reset(&rdata); 9992 dns_rdataset_current(rdset, &rdata); 9993 result = normalize_key(&rdata, &rdata2, data2, sizeof(data2)); 9994 if (result != ISC_R_SUCCESS) { 9995 continue; 9996 } 9997 if (dns_rdata_compare(&rdata1, &rdata2) == 0) { 9998 return true; 9999 } 10000 } 10001 10002 return false; 10003 } 10004 10005 /* 10006 * Calculate the refresh interval for a keydata zone, per 10007 * RFC5011: MAX(1 hr, 10008 * MIN(15 days, 10009 * 1/2 * OrigTTL, 10010 * 1/2 * RRSigExpirationInterval)) 10011 * or for retries: MAX(1 hr, 10012 * MIN(1 day, 10013 * 1/10 * OrigTTL, 10014 * 1/10 * RRSigExpirationInterval)) 10015 */ 10016 static isc_stdtime_t 10017 refresh_time(dns_keyfetch_t *kfetch, bool retry) { 10018 isc_result_t result; 10019 uint32_t t; 10020 dns_rdataset_t *rdset; 10021 dns_rdata_t sigrr = DNS_RDATA_INIT; 10022 dns_rdata_sig_t sig; 10023 isc_stdtime_t now = isc_stdtime_now(); 10024 10025 if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) { 10026 rdset = &kfetch->dnskeysigset; 10027 } else { 10028 return now + dns_zone_mkey_hour; 10029 } 10030 10031 result = dns_rdataset_first(rdset); 10032 if (result != ISC_R_SUCCESS) { 10033 return now + dns_zone_mkey_hour; 10034 } 10035 10036 dns_rdataset_current(rdset, &sigrr); 10037 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 10038 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10039 10040 if (!retry) { 10041 t = sig.originalttl / 2; 10042 10043 if (isc_serial_gt(sig.timeexpire, now)) { 10044 uint32_t exp = (sig.timeexpire - now) / 2; 10045 if (t > exp) { 10046 t = exp; 10047 } 10048 } 10049 10050 if (t > (15 * dns_zone_mkey_day)) { 10051 t = (15 * dns_zone_mkey_day); 10052 } 10053 10054 if (t < dns_zone_mkey_hour) { 10055 t = dns_zone_mkey_hour; 10056 } 10057 } else { 10058 t = sig.originalttl / 10; 10059 10060 if (isc_serial_gt(sig.timeexpire, now)) { 10061 uint32_t exp = (sig.timeexpire - now) / 10; 10062 if (t > exp) { 10063 t = exp; 10064 } 10065 } 10066 10067 if (t > dns_zone_mkey_day) { 10068 t = dns_zone_mkey_day; 10069 } 10070 10071 if (t < dns_zone_mkey_hour) { 10072 t = dns_zone_mkey_hour; 10073 } 10074 } 10075 10076 return now + t; 10077 } 10078 10079 /* 10080 * This routine is called when no changes are needed in a KEYDATA 10081 * record except to simply update the refresh timer. Caller should 10082 * hold zone lock. 10083 */ 10084 static isc_result_t 10085 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) { 10086 isc_result_t result; 10087 isc_buffer_t keyb; 10088 unsigned char key_buf[4096]; 10089 dns_rdata_t rdata = DNS_RDATA_INIT; 10090 dns_rdata_keydata_t keydata; 10091 dns_name_t *name; 10092 dns_zone_t *zone = kfetch->zone; 10093 isc_stdtime_t now = isc_stdtime_now(); 10094 10095 name = dns_fixedname_name(&kfetch->name); 10096 10097 for (result = dns_rdataset_first(&kfetch->keydataset); 10098 result == ISC_R_SUCCESS; 10099 result = dns_rdataset_next(&kfetch->keydataset)) 10100 { 10101 dns_rdata_reset(&rdata); 10102 dns_rdataset_current(&kfetch->keydataset, &rdata); 10103 10104 /* Delete old version */ 10105 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL, name, 10106 0, &rdata)); 10107 10108 /* Update refresh timer */ 10109 result = dns_rdata_tostruct(&rdata, &keydata, NULL); 10110 if (result == ISC_R_UNEXPECTEDEND) { 10111 continue; 10112 } 10113 if (result != ISC_R_SUCCESS) { 10114 goto failure; 10115 } 10116 keydata.refresh = refresh_time(kfetch, true); 10117 set_refreshkeytimer(zone, &keydata, now, false); 10118 10119 dns_rdata_reset(&rdata); 10120 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10121 CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass, 10122 dns_rdatatype_keydata, &keydata, 10123 &keyb)); 10124 10125 /* Insert updated version */ 10126 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD, name, 10127 0, &rdata)); 10128 } 10129 result = ISC_R_SUCCESS; 10130 failure: 10131 return result; 10132 } 10133 10134 /* 10135 * Verify that DNSKEY set is signed by the key specified in 'keydata'. 10136 */ 10137 static bool 10138 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) { 10139 isc_result_t result; 10140 dns_name_t *keyname; 10141 isc_mem_t *mctx; 10142 dns_rdata_t sigrr = DNS_RDATA_INIT; 10143 dns_rdata_t rr = DNS_RDATA_INIT; 10144 dns_rdata_rrsig_t sig; 10145 dns_rdata_dnskey_t dnskey; 10146 dst_key_t *dstkey = NULL; 10147 unsigned char key_buf[4096]; 10148 isc_buffer_t keyb; 10149 bool answer = false; 10150 10151 REQUIRE(kfetch != NULL && keydata != NULL); 10152 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset)); 10153 10154 keyname = dns_fixedname_name(&kfetch->name); 10155 mctx = kfetch->zone->view->mctx; 10156 10157 /* Generate a key from keydata */ 10158 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10159 dns_keydata_todnskey(keydata, &dnskey, NULL); 10160 dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey, 10161 &dnskey, &keyb); 10162 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey); 10163 if (result != ISC_R_SUCCESS) { 10164 return false; 10165 } 10166 10167 /* See if that key generated any of the signatures */ 10168 for (result = dns_rdataset_first(&kfetch->dnskeysigset); 10169 result == ISC_R_SUCCESS; 10170 result = dns_rdataset_next(&kfetch->dnskeysigset)) 10171 { 10172 dns_fixedname_t fixed; 10173 dns_fixedname_init(&fixed); 10174 10175 dns_rdata_reset(&sigrr); 10176 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr); 10177 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 10178 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10179 10180 if (dst_key_alg(dstkey) == sig.algorithm && 10181 dst_key_rid(dstkey) == sig.keyid) 10182 { 10183 result = dns_dnssec_verify( 10184 keyname, &kfetch->dnskeyset, dstkey, false, 0, 10185 mctx, &sigrr, dns_fixedname_name(&fixed)); 10186 10187 dnssec_log(kfetch->zone, ISC_LOG_DEBUG(3), 10188 "Confirm revoked DNSKEY is self-signed: %s", 10189 isc_result_totext(result)); 10190 10191 if (result == ISC_R_SUCCESS) { 10192 answer = true; 10193 break; 10194 } 10195 } 10196 } 10197 10198 dst_key_free(&dstkey); 10199 return answer; 10200 } 10201 10202 /* 10203 * A DNSKEY set has been fetched from the zone apex of a zone whose trust 10204 * anchors are being managed; scan the keyset, and update the key zone and the 10205 * local trust anchors according to RFC5011. 10206 */ 10207 static void 10208 keyfetch_done(void *arg) { 10209 dns_fetchresponse_t *resp = (dns_fetchresponse_t *)arg; 10210 isc_result_t result, eresult; 10211 dns_keyfetch_t *kfetch = NULL; 10212 dns_zone_t *zone = NULL; 10213 isc_mem_t *mctx = NULL; 10214 dns_keytable_t *secroots = NULL; 10215 dns_dbversion_t *ver = NULL; 10216 dns_diff_t diff; 10217 bool alldone = false; 10218 bool commit = false; 10219 dns_name_t *keyname = NULL; 10220 dns_rdata_t sigrr = DNS_RDATA_INIT; 10221 dns_rdata_t dnskeyrr = DNS_RDATA_INIT; 10222 dns_rdata_t keydatarr = DNS_RDATA_INIT; 10223 dns_rdata_rrsig_t sig; 10224 dns_rdata_dnskey_t dnskey; 10225 dns_rdata_keydata_t keydata; 10226 bool initializing; 10227 char namebuf[DNS_NAME_FORMATSIZE]; 10228 unsigned char key_buf[4096]; 10229 isc_buffer_t keyb; 10230 dst_key_t *dstkey = NULL; 10231 isc_stdtime_t now; 10232 int pending = 0; 10233 bool secure = false, initial = false; 10234 bool free_needed; 10235 dns_keynode_t *keynode = NULL; 10236 dns_rdataset_t *dnskeys = NULL, *dnskeysigs = NULL; 10237 dns_rdataset_t *keydataset = NULL, dsset; 10238 10239 INSIST(resp != NULL); 10240 10241 kfetch = resp->arg; 10242 10243 INSIST(kfetch != NULL); 10244 10245 zone = kfetch->zone; 10246 mctx = kfetch->mctx; 10247 keyname = dns_fixedname_name(&kfetch->name); 10248 dnskeys = &kfetch->dnskeyset; 10249 dnskeysigs = &kfetch->dnskeysigset; 10250 keydataset = &kfetch->keydataset; 10251 10252 eresult = resp->result; 10253 10254 /* Free resources which are not of interest */ 10255 if (resp->node != NULL) { 10256 dns_db_detachnode(resp->db, &resp->node); 10257 } 10258 if (resp->db != NULL) { 10259 dns_db_detach(&resp->db); 10260 } 10261 10262 dns_resolver_destroyfetch(&kfetch->fetch); 10263 10264 LOCK_ZONE(zone); 10265 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) { 10266 goto cleanup; 10267 } 10268 10269 now = isc_stdtime_now(); 10270 dns_name_format(keyname, namebuf, sizeof(namebuf)); 10271 10272 result = dns_view_getsecroots(zone->view, &secroots); 10273 INSIST(result == ISC_R_SUCCESS); 10274 10275 dns_diff_init(mctx, &diff); 10276 10277 CHECK(dns_db_newversion(kfetch->db, &ver)); 10278 10279 zone->refreshkeycount--; 10280 alldone = (zone->refreshkeycount == 0); 10281 10282 if (alldone) { 10283 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 10284 } 10285 10286 dnssec_log(zone, ISC_LOG_DEBUG(3), 10287 "Returned from key fetch in keyfetch_done() for '%s': %s", 10288 namebuf, isc_result_totext(eresult)); 10289 10290 /* Fetch failed */ 10291 if (eresult != ISC_R_SUCCESS || !dns_rdataset_isassociated(dnskeys)) { 10292 dnssec_log(zone, ISC_LOG_WARNING, 10293 "Unable to fetch DNSKEY set '%s': %s", namebuf, 10294 isc_result_totext(eresult)); 10295 CHECK(minimal_update(kfetch, ver, &diff)); 10296 goto done; 10297 } 10298 10299 /* No RRSIGs found */ 10300 if (!dns_rdataset_isassociated(dnskeysigs)) { 10301 dnssec_log(zone, ISC_LOG_WARNING, 10302 "No DNSKEY RRSIGs found for '%s': %s", namebuf, 10303 isc_result_totext(eresult)); 10304 CHECK(minimal_update(kfetch, ver, &diff)); 10305 goto done; 10306 } 10307 10308 /* 10309 * Clear any cached trust level, as we need to run validation 10310 * over again; trusted keys might have changed. 10311 */ 10312 dnskeys->trust = dnskeysigs->trust = dns_trust_none; 10313 10314 /* Look up the trust anchor */ 10315 result = dns_keytable_find(secroots, keyname, &keynode); 10316 if (result != ISC_R_SUCCESS) { 10317 goto anchors_done; 10318 } 10319 10320 /* 10321 * If the keynode has a DS trust anchor, use it for verification. 10322 */ 10323 dns_rdataset_init(&dsset); 10324 if (dns_keynode_dsset(keynode, &dsset)) { 10325 for (result = dns_rdataset_first(dnskeysigs); 10326 result == ISC_R_SUCCESS; 10327 result = dns_rdataset_next(dnskeysigs)) 10328 { 10329 isc_result_t tresult; 10330 dns_rdata_t keyrdata = DNS_RDATA_INIT; 10331 10332 dns_rdata_reset(&sigrr); 10333 dns_rdataset_current(dnskeysigs, &sigrr); 10334 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 10335 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10336 10337 for (tresult = dns_rdataset_first(&dsset); 10338 tresult == ISC_R_SUCCESS; 10339 tresult = dns_rdataset_next(&dsset)) 10340 { 10341 dns_rdata_t dsrdata = DNS_RDATA_INIT; 10342 dns_rdata_ds_t ds; 10343 10344 dns_rdata_reset(&dsrdata); 10345 dns_rdataset_current(&dsset, &dsrdata); 10346 tresult = dns_rdata_tostruct(&dsrdata, &ds, 10347 NULL); 10348 RUNTIME_CHECK(tresult == ISC_R_SUCCESS); 10349 10350 if (ds.key_tag != sig.keyid || 10351 ds.algorithm != sig.algorithm) 10352 { 10353 continue; 10354 } 10355 10356 result = dns_dnssec_matchdskey( 10357 keyname, &dsrdata, dnskeys, &keyrdata); 10358 if (result == ISC_R_SUCCESS) { 10359 break; 10360 } 10361 } 10362 10363 if (tresult == ISC_R_NOMORE) { 10364 continue; 10365 } 10366 10367 result = dns_dnssec_keyfromrdata(keyname, &keyrdata, 10368 mctx, &dstkey); 10369 if (result != ISC_R_SUCCESS) { 10370 continue; 10371 } 10372 10373 result = dns_dnssec_verify(keyname, dnskeys, dstkey, 10374 false, 0, mctx, &sigrr, 10375 NULL); 10376 dst_key_free(&dstkey); 10377 10378 dnssec_log(zone, ISC_LOG_DEBUG(3), 10379 "Verifying DNSKEY set for zone " 10380 "'%s' using DS %d/%d: %s", 10381 namebuf, sig.keyid, sig.algorithm, 10382 isc_result_totext(result)); 10383 10384 if (result == ISC_R_SUCCESS) { 10385 dnskeys->trust = dns_trust_secure; 10386 dnskeysigs->trust = dns_trust_secure; 10387 initial = dns_keynode_initial(keynode); 10388 dns_keynode_trust(keynode); 10389 secure = true; 10390 break; 10391 } 10392 } 10393 dns_rdataset_disassociate(&dsset); 10394 } 10395 10396 anchors_done: 10397 if (keynode != NULL) { 10398 dns_keynode_detach(&keynode); 10399 } 10400 10401 /* 10402 * If we were not able to verify the answer using the current 10403 * trusted keys then all we can do is look at any revoked keys. 10404 */ 10405 if (!secure) { 10406 dnssec_log(zone, ISC_LOG_INFO, 10407 "DNSKEY set for zone '%s' could not be verified " 10408 "with current keys", 10409 namebuf); 10410 } 10411 10412 /* 10413 * First scan keydataset to find keys that are not in dnskeyset 10414 * - Missing keys which are not scheduled for removal, 10415 * log a warning 10416 * - Missing keys which are scheduled for removal and 10417 * the remove hold-down timer has completed should 10418 * be removed from the key zone 10419 * - Missing keys whose acceptance timers have not yet 10420 * completed, log a warning and reset the acceptance 10421 * timer to 30 days in the future 10422 * - All keys not being removed have their refresh timers 10423 * updated 10424 */ 10425 initializing = true; 10426 for (result = dns_rdataset_first(keydataset); result == ISC_R_SUCCESS; 10427 result = dns_rdataset_next(keydataset)) 10428 { 10429 dns_keytag_t keytag; 10430 10431 dns_rdata_reset(&keydatarr); 10432 dns_rdataset_current(keydataset, &keydatarr); 10433 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); 10434 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10435 10436 dns_keydata_todnskey(&keydata, &dnskey, NULL); 10437 result = compute_tag(keyname, &dnskey, mctx, &keytag); 10438 if (result != ISC_R_SUCCESS) { 10439 /* 10440 * Skip if we cannot compute the key tag. 10441 * This may happen if the algorithm is unsupported 10442 */ 10443 dns_zone_log(zone, ISC_LOG_ERROR, 10444 "Cannot compute tag for key in zone %s: " 10445 "%s " 10446 "(skipping)", 10447 namebuf, isc_result_totext(result)); 10448 continue; 10449 } 10450 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10451 10452 /* 10453 * If any keydata record has a nonzero add holddown, then 10454 * there was a pre-existing trust anchor for this domain; 10455 * that means we are *not* initializing it and shouldn't 10456 * automatically trust all the keys we find at the zone apex. 10457 */ 10458 initializing = initializing && (keydata.addhd == 0); 10459 10460 if (!matchkey(dnskeys, &keydatarr)) { 10461 bool deletekey = false; 10462 10463 if (!secure) { 10464 if (keydata.removehd != 0 && 10465 keydata.removehd <= now) 10466 { 10467 deletekey = true; 10468 } 10469 } else if (keydata.addhd == 0) { 10470 deletekey = true; 10471 } else if (keydata.addhd > now) { 10472 dnssec_log(zone, ISC_LOG_INFO, 10473 "Pending key %d for zone %s " 10474 "unexpectedly missing from DNSKEY " 10475 "RRset: restarting 30-day " 10476 "acceptance timer", 10477 keytag, namebuf); 10478 if (keydata.addhd < now + dns_zone_mkey_month) { 10479 keydata.addhd = now + 10480 dns_zone_mkey_month; 10481 } 10482 keydata.refresh = refresh_time(kfetch, false); 10483 } else if (keydata.removehd == 0) { 10484 dnssec_log(zone, ISC_LOG_INFO, 10485 "Active key %d for zone %s " 10486 "unexpectedly missing from DNSKEY " 10487 "RRset", 10488 keytag, namebuf); 10489 keydata.refresh = now + dns_zone_mkey_hour; 10490 } else if (keydata.removehd <= now) { 10491 deletekey = true; 10492 dnssec_log( 10493 zone, ISC_LOG_INFO, 10494 "Revoked key %d for zone %s no longer " 10495 "present in DNSKEY RRset: deleting " 10496 "from managed keys database", 10497 keytag, namebuf); 10498 } else { 10499 keydata.refresh = refresh_time(kfetch, false); 10500 } 10501 10502 if (secure || deletekey) { 10503 /* Delete old version */ 10504 CHECK(update_one_rr(kfetch->db, ver, &diff, 10505 DNS_DIFFOP_DEL, keyname, 0, 10506 &keydatarr)); 10507 } 10508 10509 if (!secure || deletekey) { 10510 continue; 10511 } 10512 10513 dns_rdata_reset(&keydatarr); 10514 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10515 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 10516 dns_rdatatype_keydata, &keydata, 10517 &keyb); 10518 10519 /* Insert updated version */ 10520 CHECK(update_one_rr(kfetch->db, ver, &diff, 10521 DNS_DIFFOP_ADD, keyname, 0, 10522 &keydatarr)); 10523 10524 set_refreshkeytimer(zone, &keydata, now, false); 10525 } 10526 } 10527 10528 /* 10529 * Next scan dnskeyset: 10530 * - If new keys are found (i.e., lacking a match in keydataset) 10531 * add them to the key zone and set the acceptance timer 10532 * to 30 days in the future (or to immediately if we've 10533 * determined that we're initializing the zone for the 10534 * first time) 10535 * - Previously-known keys that have been revoked 10536 * must be scheduled for removal from the key zone (or, 10537 * if they hadn't been accepted as trust anchors yet 10538 * anyway, removed at once) 10539 * - Previously-known unrevoked keys whose acceptance timers 10540 * have completed are promoted to trust anchors 10541 * - All keys not being removed have their refresh 10542 * timers updated 10543 */ 10544 for (result = dns_rdataset_first(dnskeys); result == ISC_R_SUCCESS; 10545 result = dns_rdataset_next(dnskeys)) 10546 { 10547 bool revoked = false; 10548 bool newkey = false; 10549 bool updatekey = false; 10550 bool deletekey = false; 10551 bool trustkey = false; 10552 dns_keytag_t keytag; 10553 10554 dns_rdata_reset(&dnskeyrr); 10555 dns_rdataset_current(dnskeys, &dnskeyrr); 10556 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 10557 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10558 10559 /* Skip ZSK's */ 10560 if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) { 10561 continue; 10562 } 10563 10564 result = compute_tag(keyname, &dnskey, mctx, &keytag); 10565 if (result != ISC_R_SUCCESS) { 10566 /* 10567 * Skip if we cannot compute the key tag. 10568 * This may happen if the algorithm is unsupported 10569 */ 10570 dns_zone_log(zone, ISC_LOG_ERROR, 10571 "Cannot compute tag for key in zone %s: " 10572 "%s " 10573 "(skipping)", 10574 namebuf, isc_result_totext(result)); 10575 continue; 10576 } 10577 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10578 10579 revoked = ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0); 10580 10581 if (matchkey(keydataset, &dnskeyrr)) { 10582 dns_rdata_reset(&keydatarr); 10583 dns_rdataset_current(keydataset, &keydatarr); 10584 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); 10585 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10586 10587 if (revoked && revocable(kfetch, &keydata)) { 10588 if (keydata.addhd > now) { 10589 /* 10590 * Key wasn't trusted yet, and now 10591 * it's been revoked? Just remove it 10592 */ 10593 deletekey = true; 10594 dnssec_log(zone, ISC_LOG_INFO, 10595 "Pending key %d for " 10596 "zone %s is now revoked: " 10597 "deleting from the " 10598 "managed keys database", 10599 keytag, namebuf); 10600 } else if (keydata.removehd == 0) { 10601 /* 10602 * Remove key from secroots. 10603 */ 10604 dns_view_untrust(zone->view, keyname, 10605 &dnskey); 10606 10607 /* If initializing, delete now */ 10608 if (keydata.addhd == 0) { 10609 deletekey = true; 10610 } else { 10611 keydata.removehd = 10612 now + 10613 dns_zone_mkey_month; 10614 keydata.flags |= 10615 DNS_KEYFLAG_REVOKE; 10616 } 10617 10618 dnssec_log(zone, ISC_LOG_INFO, 10619 "Trusted key %d for " 10620 "zone %s is now revoked", 10621 keytag, namebuf); 10622 } else if (keydata.removehd < now) { 10623 /* Scheduled for removal */ 10624 deletekey = true; 10625 10626 dnssec_log(zone, ISC_LOG_INFO, 10627 "Revoked key %d for " 10628 "zone %s removal timer " 10629 "complete: deleting from " 10630 "the managed keys database", 10631 keytag, namebuf); 10632 } 10633 } else if (revoked && keydata.removehd == 0) { 10634 dnssec_log(zone, ISC_LOG_WARNING, 10635 "Active key %d for zone " 10636 "%s is revoked but " 10637 "did not self-sign; " 10638 "ignoring", 10639 keytag, namebuf); 10640 continue; 10641 } else if (secure) { 10642 if (keydata.removehd != 0) { 10643 /* 10644 * Key isn't revoked--but it 10645 * seems it used to be. 10646 * Remove it now and add it 10647 * back as if it were a fresh key, 10648 * with a 30-day acceptance timer. 10649 */ 10650 deletekey = true; 10651 newkey = true; 10652 keydata.removehd = 0; 10653 keydata.addhd = now + 10654 dns_zone_mkey_month; 10655 10656 dnssec_log(zone, ISC_LOG_INFO, 10657 "Revoked key %d for " 10658 "zone %s has returned: " 10659 "starting 30-day " 10660 "acceptance timer", 10661 keytag, namebuf); 10662 } else if (keydata.addhd > now) { 10663 pending++; 10664 } else if (keydata.addhd == 0) { 10665 keydata.addhd = now; 10666 } 10667 10668 if (keydata.addhd <= now) { 10669 trustkey = true; 10670 dnssec_log(zone, ISC_LOG_INFO, 10671 "Key %d for zone %s " 10672 "is now trusted (%s)", 10673 keytag, namebuf, 10674 initial ? "initializing key " 10675 "verified" 10676 : "acceptance timer " 10677 "complete"); 10678 } 10679 } else if (keydata.addhd > now) { 10680 /* 10681 * Not secure, and key is pending: 10682 * reset the acceptance timer 10683 */ 10684 pending++; 10685 keydata.addhd = now + dns_zone_mkey_month; 10686 dnssec_log(zone, ISC_LOG_INFO, 10687 "Pending key %d " 10688 "for zone %s was " 10689 "not validated: restarting " 10690 "30-day acceptance timer", 10691 keytag, namebuf); 10692 } 10693 10694 if (!deletekey && !newkey) { 10695 updatekey = true; 10696 } 10697 } else if (secure) { 10698 /* 10699 * Key wasn't in the key zone but it's 10700 * revoked now anyway, so just skip it 10701 */ 10702 if (revoked) { 10703 continue; 10704 } 10705 10706 /* Key wasn't in the key zone: add it */ 10707 newkey = true; 10708 10709 if (initializing) { 10710 dnssec_log(zone, ISC_LOG_WARNING, 10711 "Initializing automatic trust " 10712 "anchor management for zone '%s'; " 10713 "DNSKEY ID %d is now trusted, " 10714 "waiving the normal 30-day " 10715 "waiting period.", 10716 namebuf, keytag); 10717 trustkey = true; 10718 } else { 10719 dnssec_log(zone, ISC_LOG_INFO, 10720 "New key %d observed " 10721 "for zone '%s': " 10722 "starting 30-day " 10723 "acceptance timer", 10724 keytag, namebuf); 10725 } 10726 } else { 10727 /* 10728 * No previously known key, and the key is not 10729 * secure, so skip it. 10730 */ 10731 continue; 10732 } 10733 10734 /* Delete old version */ 10735 if (deletekey || !newkey) { 10736 CHECK(update_one_rr(kfetch->db, ver, &diff, 10737 DNS_DIFFOP_DEL, keyname, 0, 10738 &keydatarr)); 10739 } 10740 10741 if (updatekey) { 10742 /* Set refresh timer */ 10743 keydata.refresh = refresh_time(kfetch, false); 10744 dns_rdata_reset(&keydatarr); 10745 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10746 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 10747 dns_rdatatype_keydata, &keydata, 10748 &keyb); 10749 10750 /* Insert updated version */ 10751 CHECK(update_one_rr(kfetch->db, ver, &diff, 10752 DNS_DIFFOP_ADD, keyname, 0, 10753 &keydatarr)); 10754 } else if (newkey) { 10755 /* Convert DNSKEY to KEYDATA */ 10756 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 10757 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10758 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0, 10759 NULL); 10760 keydata.addhd = initializing 10761 ? now 10762 : now + dns_zone_mkey_month; 10763 keydata.refresh = refresh_time(kfetch, false); 10764 dns_rdata_reset(&keydatarr); 10765 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10766 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 10767 dns_rdatatype_keydata, &keydata, 10768 &keyb); 10769 10770 /* Insert into key zone */ 10771 CHECK(update_one_rr(kfetch->db, ver, &diff, 10772 DNS_DIFFOP_ADD, keyname, 0, 10773 &keydatarr)); 10774 } 10775 10776 if (trustkey) { 10777 /* Trust this key. */ 10778 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 10779 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10780 trust_key(zone, keyname, &dnskey, false); 10781 } 10782 10783 if (secure && !deletekey) { 10784 INSIST(newkey || updatekey); 10785 set_refreshkeytimer(zone, &keydata, now, false); 10786 } 10787 } 10788 10789 /* 10790 * RFC5011 says, "A trust point that has all of its trust anchors 10791 * revoked is considered deleted and is treated as if the trust 10792 * point was never configured." But if someone revoked their 10793 * active key before the standby was trusted, that would mean the 10794 * zone would suddenly be nonsecured. We avoid this by checking to 10795 * see if there's pending keydata. If so, we put a null key in 10796 * the security roots; then all queries to the zone will fail. 10797 */ 10798 if (pending != 0) { 10799 fail_secure(zone, keyname); 10800 } 10801 10802 done: 10803 if (!ISC_LIST_EMPTY(diff.tuples)) { 10804 /* Write changes to journal file. */ 10805 CHECK(update_soa_serial(zone, kfetch->db, ver, &diff, mctx, 10806 zone->updatemethod)); 10807 CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done")); 10808 commit = true; 10809 10810 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 10811 zone_needdump(zone, 30); 10812 } else if (result == ISC_R_NOMORE) { 10813 /* 10814 * If "updatekey" was true for all keys found in the DNSKEY 10815 * response and the previous update of those keys happened 10816 * during the same second (only possible if a key refresh was 10817 * externally triggered), it may happen that all relevant 10818 * update_one_rr() calls will return ISC_R_SUCCESS, but 10819 * diff.tuples will remain empty. Reset result to 10820 * ISC_R_SUCCESS to prevent a bogus warning from being logged. 10821 */ 10822 result = ISC_R_SUCCESS; 10823 } 10824 10825 failure: 10826 if (result != ISC_R_SUCCESS) { 10827 dnssec_log(zone, ISC_LOG_ERROR, 10828 "error during managed-keys processing (%s): " 10829 "DNSSEC validation may be at risk", 10830 isc_result_totext(result)); 10831 } 10832 dns_diff_clear(&diff); 10833 if (ver != NULL) { 10834 dns_db_closeversion(kfetch->db, &ver, commit); 10835 } 10836 10837 cleanup: 10838 dns_db_detach(&kfetch->db); 10839 10840 isc_refcount_decrement(&zone->irefs); 10841 10842 if (dns_rdataset_isassociated(keydataset)) { 10843 dns_rdataset_disassociate(keydataset); 10844 } 10845 if (dns_rdataset_isassociated(dnskeys)) { 10846 dns_rdataset_disassociate(dnskeys); 10847 } 10848 if (dns_rdataset_isassociated(dnskeysigs)) { 10849 dns_rdataset_disassociate(dnskeysigs); 10850 } 10851 10852 dns_name_free(keyname, mctx); 10853 isc_mem_putanddetach(&kfetch->mctx, kfetch, sizeof(dns_keyfetch_t)); 10854 isc_mem_putanddetach(&resp->mctx, resp, sizeof(*resp)); 10855 10856 if (secroots != NULL) { 10857 dns_keytable_detach(&secroots); 10858 } 10859 10860 free_needed = exit_check(zone); 10861 UNLOCK_ZONE(zone); 10862 10863 if (free_needed) { 10864 zone_free(zone); 10865 } 10866 10867 INSIST(ver == NULL); 10868 } 10869 10870 static void 10871 retry_keyfetch(dns_keyfetch_t *kfetch, dns_name_t *kname) { 10872 isc_time_t timenow, timethen; 10873 dns_zone_t *zone = kfetch->zone; 10874 bool free_needed; 10875 char namebuf[DNS_NAME_FORMATSIZE]; 10876 10877 dns_name_format(kname, namebuf, sizeof(namebuf)); 10878 dnssec_log(zone, ISC_LOG_WARNING, 10879 "Failed to create fetch for %s DNSKEY update", namebuf); 10880 10881 /* 10882 * Error during a key fetch; cancel and retry in an hour. 10883 */ 10884 LOCK_ZONE(zone); 10885 zone->refreshkeycount--; 10886 isc_refcount_decrement(&zone->irefs); 10887 dns_db_detach(&kfetch->db); 10888 dns_rdataset_disassociate(&kfetch->keydataset); 10889 dns_name_free(kname, zone->mctx); 10890 isc_mem_putanddetach(&kfetch->mctx, kfetch, sizeof(*kfetch)); 10891 10892 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 10893 /* Don't really retry if we are exiting */ 10894 char timebuf[80]; 10895 10896 timenow = isc_time_now(); 10897 DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen); 10898 zone->refreshkeytime = timethen; 10899 zone_settimer(zone, &timenow); 10900 10901 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 10902 dnssec_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s", 10903 timebuf); 10904 } 10905 10906 free_needed = exit_check(zone); 10907 UNLOCK_ZONE(zone); 10908 10909 if (free_needed) { 10910 zone_free(zone); 10911 } 10912 } 10913 10914 static void 10915 do_keyfetch(void *arg) { 10916 isc_result_t result; 10917 dns_keyfetch_t *kfetch = (dns_keyfetch_t *)arg; 10918 dns_name_t *kname = dns_fixedname_name(&kfetch->name); 10919 dns_resolver_t *resolver = NULL; 10920 dns_zone_t *zone = kfetch->zone; 10921 unsigned int options = DNS_FETCHOPT_NOVALIDATE | DNS_FETCHOPT_UNSHARED | 10922 DNS_FETCHOPT_NOCACHED; 10923 10924 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 10925 goto retry; 10926 } 10927 10928 result = dns_view_getresolver(zone->view, &resolver); 10929 if (result != ISC_R_SUCCESS) { 10930 goto retry; 10931 } 10932 10933 /* 10934 * Use of DNS_FETCHOPT_NOCACHED is essential here. If it is not 10935 * set and the cache still holds a non-expired, validated version 10936 * of the RRset being queried for by the time the response is 10937 * received, the cached RRset will be passed to keyfetch_done() 10938 * instead of the one received in the response as the latter will 10939 * have a lower trust level due to not being validated until 10940 * keyfetch_done() is called. 10941 */ 10942 result = dns_resolver_createfetch( 10943 resolver, kname, dns_rdatatype_dnskey, NULL, NULL, NULL, NULL, 10944 0, options, 0, NULL, zone->loop, keyfetch_done, kfetch, 10945 &kfetch->dnskeyset, &kfetch->dnskeysigset, &kfetch->fetch); 10946 10947 dns_resolver_detach(&resolver); 10948 if (result == ISC_R_SUCCESS) { 10949 return; 10950 } 10951 retry: 10952 retry_keyfetch(kfetch, kname); 10953 } 10954 10955 /* 10956 * Refresh the data in the key zone. Initiate a fetch to look up 10957 * DNSKEY records at the trust anchor name. 10958 */ 10959 static void 10960 zone_refreshkeys(dns_zone_t *zone) { 10961 isc_result_t result; 10962 dns_rriterator_t rrit; 10963 dns_db_t *db = NULL; 10964 dns_dbversion_t *ver = NULL; 10965 dns_diff_t diff; 10966 dns_rdata_t rdata = DNS_RDATA_INIT; 10967 dns_rdata_keydata_t kd; 10968 isc_stdtime_t now = isc_stdtime_now(); 10969 bool commit = false; 10970 bool fetching = false; 10971 bool timerset = false; 10972 10973 ENTER; 10974 REQUIRE(zone->db != NULL); 10975 10976 LOCK_ZONE(zone); 10977 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 10978 isc_time_settoepoch(&zone->refreshkeytime); 10979 UNLOCK_ZONE(zone); 10980 return; 10981 } 10982 10983 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 10984 dns_db_attach(zone->db, &db); 10985 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 10986 10987 dns_diff_init(zone->mctx, &diff); 10988 10989 CHECK(dns_db_newversion(db, &ver)); 10990 10991 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING); 10992 10993 dns_rriterator_init(&rrit, db, ver, 0); 10994 for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS; 10995 result = dns_rriterator_nextrrset(&rrit)) 10996 { 10997 isc_stdtime_t timer = 0xffffffff; 10998 dns_name_t *name = NULL, *kname = NULL; 10999 dns_rdataset_t *kdset = NULL; 11000 uint32_t ttl; 11001 11002 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL); 11003 if (kdset == NULL || kdset->type != dns_rdatatype_keydata || 11004 !dns_rdataset_isassociated(kdset)) 11005 { 11006 continue; 11007 } 11008 11009 /* 11010 * Scan the stored keys looking for ones that need 11011 * removal or refreshing 11012 */ 11013 for (result = dns_rdataset_first(kdset); 11014 result == ISC_R_SUCCESS; result = dns_rdataset_next(kdset)) 11015 { 11016 dns_rdata_reset(&rdata); 11017 dns_rdataset_current(kdset, &rdata); 11018 result = dns_rdata_tostruct(&rdata, &kd, NULL); 11019 RUNTIME_CHECK(result == ISC_R_SUCCESS); 11020 11021 /* Removal timer expired? */ 11022 if (kd.removehd != 0 && kd.removehd < now) { 11023 dns_rriterator_pause(&rrit); 11024 CHECK(update_one_rr(db, ver, &diff, 11025 DNS_DIFFOP_DEL, name, ttl, 11026 &rdata)); 11027 continue; 11028 } 11029 11030 /* Acceptance timer expired? */ 11031 if (kd.addhd <= now) { 11032 timer = kd.addhd; 11033 } 11034 11035 /* Or do we just need to refresh the keyset? */ 11036 if (timer > kd.refresh) { 11037 timer = kd.refresh; 11038 } 11039 11040 dns_rriterator_pause(&rrit); 11041 set_refreshkeytimer(zone, &kd, now, false); 11042 timerset = true; 11043 } 11044 11045 if (timer > now) { 11046 continue; 11047 } 11048 11049 dns_rriterator_pause(&rrit); 11050 11051 #ifdef ENABLE_AFL 11052 if (!dns_fuzzing_resolver) { 11053 #endif /* ifdef ENABLE_AFL */ 11054 dns_keyfetch_t *kfetch = NULL; 11055 11056 kfetch = isc_mem_get(zone->mctx, 11057 sizeof(dns_keyfetch_t)); 11058 *kfetch = (dns_keyfetch_t){ .zone = zone }; 11059 isc_mem_attach(zone->mctx, &kfetch->mctx); 11060 11061 zone->refreshkeycount++; 11062 isc_refcount_increment0(&zone->irefs); 11063 kname = dns_fixedname_initname(&kfetch->name); 11064 dns_name_dup(name, zone->mctx, kname); 11065 dns_rdataset_init(&kfetch->dnskeyset); 11066 dns_rdataset_init(&kfetch->dnskeysigset); 11067 dns_rdataset_init(&kfetch->keydataset); 11068 dns_rdataset_clone(kdset, &kfetch->keydataset); 11069 dns_db_attach(db, &kfetch->db); 11070 11071 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 11072 char namebuf[DNS_NAME_FORMATSIZE]; 11073 dns_name_format(kname, namebuf, 11074 sizeof(namebuf)); 11075 dnssec_log(zone, ISC_LOG_DEBUG(3), 11076 "Creating key fetch in " 11077 "zone_refreshkeys() for '%s'", 11078 namebuf); 11079 } 11080 11081 isc_async_run(zone->loop, do_keyfetch, kfetch); 11082 fetching = true; 11083 #ifdef ENABLE_AFL 11084 } 11085 #endif /* ifdef ENABLE_AFL */ 11086 } 11087 if (!ISC_LIST_EMPTY(diff.tuples)) { 11088 CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx, 11089 zone->updatemethod)); 11090 CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys")); 11091 commit = true; 11092 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 11093 zone_needdump(zone, 30); 11094 } 11095 11096 failure: 11097 if (!timerset) { 11098 isc_time_settoepoch(&zone->refreshkeytime); 11099 } 11100 11101 if (!fetching) { 11102 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 11103 } 11104 11105 dns_diff_clear(&diff); 11106 if (ver != NULL) { 11107 dns_rriterator_destroy(&rrit); 11108 dns_db_closeversion(db, &ver, commit); 11109 } 11110 dns_db_detach(&db); 11111 11112 UNLOCK_ZONE(zone); 11113 11114 INSIST(ver == NULL); 11115 } 11116 11117 static void 11118 zone_maintenance(dns_zone_t *zone) { 11119 isc_time_t now; 11120 isc_result_t result; 11121 bool load_pending, exiting, dumping, viewok = false, notify; 11122 bool refreshkeys, sign, resign, rekey, chain, warn_expire; 11123 11124 REQUIRE(DNS_ZONE_VALID(zone)); 11125 ENTER; 11126 11127 /* 11128 * Are we pending load/reload, exiting, or unconfigured 11129 * (e.g. because of a syntax failure in the config file)? 11130 * If so, don't attempt maintenance. 11131 */ 11132 LOCK_ZONE(zone); 11133 load_pending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING); 11134 exiting = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING); 11135 if (!load_pending && !exiting && zone->view != NULL) { 11136 dns_adb_t *adb = NULL; 11137 dns_view_getadb(zone->view, &adb); 11138 if (adb != NULL) { 11139 dns_adb_detach(&adb); 11140 viewok = true; 11141 } 11142 } 11143 UNLOCK_ZONE(zone); 11144 11145 if (load_pending || exiting || !viewok) { 11146 return; 11147 } 11148 11149 now = isc_time_now(); 11150 11151 /* 11152 * Expire check. 11153 */ 11154 switch (zone->type) { 11155 case dns_zone_redirect: 11156 if (dns_remote_addresses(&zone->primaries) == NULL) { 11157 break; 11158 } 11159 FALLTHROUGH; 11160 case dns_zone_secondary: 11161 case dns_zone_mirror: 11162 case dns_zone_stub: 11163 LOCK_ZONE(zone); 11164 if (isc_time_compare(&now, &zone->expiretime) >= 0 && 11165 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 11166 { 11167 zone_expire(zone); 11168 zone->refreshtime = now; 11169 } 11170 UNLOCK_ZONE(zone); 11171 break; 11172 default: 11173 break; 11174 } 11175 11176 /* 11177 * Up to date check. 11178 */ 11179 switch (zone->type) { 11180 case dns_zone_redirect: 11181 if (dns_remote_addresses(&zone->primaries) == NULL) { 11182 break; 11183 } 11184 FALLTHROUGH; 11185 case dns_zone_secondary: 11186 case dns_zone_mirror: 11187 case dns_zone_stub: 11188 LOCK_ZONE(zone); 11189 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && 11190 isc_time_compare(&now, &zone->refreshtime) >= 0) 11191 { 11192 zone_refresh(zone); 11193 } 11194 UNLOCK_ZONE(zone); 11195 break; 11196 default: 11197 break; 11198 } 11199 11200 /* 11201 * Secondaries send notifies before backing up to disk, 11202 * primaries after. 11203 */ 11204 LOCK_ZONE(zone); 11205 notify = (zone->type == dns_zone_secondary || 11206 zone->type == dns_zone_mirror) && 11207 (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 11208 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) && 11209 isc_time_compare(&now, &zone->notifytime) >= 0; 11210 UNLOCK_ZONE(zone); 11211 11212 if (notify) { 11213 zone_notify(zone, &now); 11214 } 11215 11216 /* 11217 * Do we need to consolidate the backing store? 11218 */ 11219 switch (zone->type) { 11220 case dns_zone_primary: 11221 case dns_zone_secondary: 11222 case dns_zone_mirror: 11223 case dns_zone_key: 11224 case dns_zone_redirect: 11225 case dns_zone_stub: 11226 LOCK_ZONE(zone); 11227 if (zone->masterfile != NULL && 11228 isc_time_compare(&now, &zone->dumptime) >= 0 && 11229 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 11230 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) 11231 { 11232 dumping = was_dumping(zone); 11233 } else { 11234 dumping = true; 11235 } 11236 UNLOCK_ZONE(zone); 11237 if (!dumping) { 11238 result = zone_dump(zone, true); /* loop locked */ 11239 if (result != ISC_R_SUCCESS) { 11240 dns_zone_log(zone, ISC_LOG_WARNING, 11241 "dump failed: %s", 11242 isc_result_totext(result)); 11243 } 11244 } 11245 break; 11246 default: 11247 break; 11248 } 11249 11250 /* 11251 * Primary/redirect zones send notifies now, if needed 11252 */ 11253 switch (zone->type) { 11254 case dns_zone_primary: 11255 case dns_zone_redirect: 11256 LOCK_ZONE(zone); 11257 notify = (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 11258 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) && 11259 isc_time_compare(&now, &zone->notifytime) >= 0; 11260 UNLOCK_ZONE(zone); 11261 if (notify) { 11262 zone_notify(zone, &now); 11263 } 11264 default: 11265 break; 11266 } 11267 11268 /* 11269 * Do we need to refresh keys? 11270 */ 11271 switch (zone->type) { 11272 case dns_zone_key: 11273 LOCK_ZONE(zone); 11274 refreshkeys = isc_time_compare(&now, &zone->refreshkeytime) >= 11275 0 && 11276 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 11277 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING); 11278 UNLOCK_ZONE(zone); 11279 if (refreshkeys) { 11280 zone_refreshkeys(zone); 11281 } 11282 break; 11283 case dns_zone_primary: 11284 LOCK_ZONE(zone); 11285 if (zone->rss != NULL) { 11286 isc_time_settoepoch(&zone->refreshkeytime); 11287 UNLOCK_ZONE(zone); 11288 break; 11289 } 11290 rekey = (!isc_time_isepoch(&zone->refreshkeytime) && 11291 isc_time_compare(&now, &zone->refreshkeytime) >= 0); 11292 UNLOCK_ZONE(zone); 11293 if (rekey) { 11294 zone_rekey(zone); 11295 } 11296 default: 11297 break; 11298 } 11299 11300 switch (zone->type) { 11301 case dns_zone_primary: 11302 case dns_zone_redirect: 11303 case dns_zone_secondary: 11304 /* 11305 * Do we need to sign/resign some RRsets? 11306 */ 11307 LOCK_ZONE(zone); 11308 if (zone->rss != NULL) { 11309 isc_time_settoepoch(&zone->signingtime); 11310 isc_time_settoepoch(&zone->resigntime); 11311 isc_time_settoepoch(&zone->nsec3chaintime); 11312 isc_time_settoepoch(&zone->keywarntime); 11313 UNLOCK_ZONE(zone); 11314 break; 11315 } 11316 sign = !isc_time_isepoch(&zone->signingtime) && 11317 isc_time_compare(&now, &zone->signingtime) >= 0; 11318 resign = !isc_time_isepoch(&zone->resigntime) && 11319 isc_time_compare(&now, &zone->resigntime) >= 0; 11320 chain = !isc_time_isepoch(&zone->nsec3chaintime) && 11321 isc_time_compare(&now, &zone->nsec3chaintime) >= 0; 11322 warn_expire = !isc_time_isepoch(&zone->keywarntime) && 11323 isc_time_compare(&now, &zone->keywarntime) >= 0; 11324 UNLOCK_ZONE(zone); 11325 11326 if (sign) { 11327 zone_sign(zone); 11328 } else if (resign) { 11329 zone_resigninc(zone); 11330 } else if (chain) { 11331 zone_nsec3chain(zone); 11332 } 11333 11334 /* 11335 * Do we need to issue a key expiry warning? 11336 */ 11337 if (warn_expire) { 11338 set_key_expiry_warning(zone, zone->key_expiry, 11339 isc_time_seconds(&now)); 11340 } 11341 break; 11342 11343 default: 11344 break; 11345 } 11346 LOCK_ZONE(zone); 11347 zone_settimer(zone, &now); 11348 UNLOCK_ZONE(zone); 11349 } 11350 11351 void 11352 dns_zone_markdirty(dns_zone_t *zone) { 11353 uint32_t serial; 11354 isc_result_t result = ISC_R_SUCCESS; 11355 dns_zone_t *secure = NULL; 11356 11357 /* 11358 * Obtaining a lock on the zone->secure (see zone_send_secureserial) 11359 * could result in a deadlock due to a LOR so we will spin if we 11360 * can't obtain the both locks. 11361 */ 11362 again: 11363 LOCK_ZONE(zone); 11364 if (zone->type == dns_zone_primary) { 11365 if (inline_raw(zone)) { 11366 unsigned int soacount; 11367 secure = zone->secure; 11368 INSIST(secure != zone); 11369 TRYLOCK_ZONE(result, secure); 11370 if (result != ISC_R_SUCCESS) { 11371 UNLOCK_ZONE(zone); 11372 secure = NULL; 11373 isc_thread_yield(); 11374 goto again; 11375 } 11376 11377 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 11378 if (zone->db != NULL) { 11379 result = zone_get_from_db( 11380 zone, zone->db, NULL, &soacount, NULL, 11381 &serial, NULL, NULL, NULL, NULL, NULL); 11382 } else { 11383 result = DNS_R_NOTLOADED; 11384 } 11385 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11386 if (result == ISC_R_SUCCESS && soacount > 0U) { 11387 zone_send_secureserial(zone, serial); 11388 } 11389 } 11390 11391 /* XXXMPA make separate call back */ 11392 if (result == ISC_R_SUCCESS) { 11393 set_resigntime(zone); 11394 if (zone->loop != NULL) { 11395 isc_time_t now; 11396 now = isc_time_now(); 11397 zone_settimer(zone, &now); 11398 } 11399 } 11400 } 11401 if (secure != NULL) { 11402 UNLOCK_ZONE(secure); 11403 } 11404 zone_needdump(zone, DNS_DUMP_DELAY); 11405 UNLOCK_ZONE(zone); 11406 } 11407 11408 void 11409 dns_zone_expire(dns_zone_t *zone) { 11410 REQUIRE(DNS_ZONE_VALID(zone)); 11411 11412 LOCK_ZONE(zone); 11413 zone_expire(zone); 11414 UNLOCK_ZONE(zone); 11415 } 11416 11417 static void 11418 zone_expire(dns_zone_t *zone) { 11419 dns_db_t *db = NULL; 11420 11421 /* 11422 * 'zone' locked by caller. 11423 */ 11424 11425 REQUIRE(LOCKED_ZONE(zone)); 11426 11427 dns_zone_log(zone, ISC_LOG_WARNING, "expired"); 11428 11429 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED); 11430 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 11431 zone->retry = DNS_ZONE_DEFAULTRETRY; 11432 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 11433 11434 /* 11435 * An RPZ zone has expired; before unloading it, we must 11436 * first remove it from the RPZ summary database. The 11437 * easiest way to do this is "update" it with an empty 11438 * database so that the update callback synchronizes 11439 * the diff automatically. 11440 */ 11441 if (zone->rpzs != NULL && zone->rpz_num != DNS_RPZ_INVALID_NUM) { 11442 isc_result_t result; 11443 dns_rpz_zone_t *rpz = zone->rpzs->zones[zone->rpz_num]; 11444 11445 CHECK(dns_db_create(zone->mctx, ZONEDB_DEFAULT, &zone->origin, 11446 dns_dbtype_zone, zone->rdclass, 0, NULL, 11447 &db)); 11448 CHECK(dns_rpz_dbupdate_callback(db, rpz)); 11449 dns_zone_log(zone, ISC_LOG_WARNING, 11450 "response-policy zone expired; " 11451 "policies unloaded"); 11452 } 11453 11454 failure: 11455 if (db != NULL) { 11456 dns_db_detach(&db); 11457 } 11458 11459 zone_unload(zone); 11460 } 11461 11462 static void 11463 zone_refresh(dns_zone_t *zone) { 11464 isc_interval_t i; 11465 uint32_t oldflags; 11466 isc_result_t result; 11467 11468 REQUIRE(DNS_ZONE_VALID(zone)); 11469 REQUIRE(LOCKED_ZONE(zone)); 11470 11471 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11472 return; 11473 } 11474 11475 /* 11476 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation 11477 * in progress at a time. 11478 */ 11479 11480 oldflags = ISC_ZONE_GET(zone, flags); 11481 if (dns_remote_addresses(&zone->primaries) == NULL) { 11482 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOPRIMARIES); 11483 if ((oldflags & DNS_ZONEFLG_NOPRIMARIES) == 0) { 11484 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 11485 ISC_LOG_ERROR, 11486 "cannot refresh: no primaries"); 11487 } 11488 return; 11489 } 11490 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 11491 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 11492 if ((oldflags & (DNS_ZONEFLG_REFRESH | DNS_ZONEFLG_LOADING)) != 0) { 11493 return; 11494 } 11495 11496 /* 11497 * Set the next refresh time as if refresh check has failed. 11498 * Setting this to the retry time will do that. XXXMLG 11499 * If we are successful it will be reset using zone->refresh. 11500 */ 11501 isc_interval_set(&i, zone->retry - isc_random_uniform(zone->retry / 4), 11502 0); 11503 result = isc_time_nowplusinterval(&zone->refreshtime, &i); 11504 if (result != ISC_R_SUCCESS) { 11505 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_WARNING, 11506 "isc_time_nowplusinterval() failed: %s", 11507 isc_result_totext(result)); 11508 } 11509 11510 /* 11511 * When lacking user-specified timer values from the SOA, 11512 * do exponential backoff of the retry time up to a 11513 * maximum of six hours. 11514 */ 11515 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) { 11516 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600); 11517 } 11518 11519 dns_remote_reset(&zone->primaries, true); 11520 11521 /* initiate soa query */ 11522 queue_soa_query(zone); 11523 } 11524 11525 static void 11526 zone_refresh_async(void *arg) { 11527 dns_zone_t *zone = arg; 11528 11529 LOCK_ZONE(zone); 11530 zone_refresh(zone); 11531 UNLOCK_ZONE(zone); 11532 11533 dns_zone_detach(&zone); 11534 } 11535 11536 void 11537 dns_zone_refresh(dns_zone_t *zone) { 11538 REQUIRE(DNS_ZONE_VALID(zone)); 11539 11540 dns_zone_ref(zone); 11541 isc_async_run(zone->loop, zone_refresh_async, zone); 11542 } 11543 11544 static isc_result_t 11545 zone_journal_rollforward(dns_zone_t *zone, dns_db_t *db, bool *needdump, 11546 bool *fixjournal) { 11547 dns_journal_t *journal = NULL; 11548 unsigned int options; 11549 isc_result_t result; 11550 11551 if (zone->type == dns_zone_primary && 11552 (inline_secure(zone) || 11553 (zone->update_acl != NULL || zone->ssutable != NULL))) 11554 { 11555 options = DNS_JOURNALOPT_RESIGN; 11556 } else { 11557 options = 0; 11558 } 11559 11560 result = dns_journal_open(zone->mctx, zone->journal, DNS_JOURNAL_READ, 11561 &journal); 11562 if (result == ISC_R_NOTFOUND) { 11563 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(3), 11564 "no journal file, but that's OK "); 11565 return ISC_R_SUCCESS; 11566 } else if (result != ISC_R_SUCCESS) { 11567 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 11568 "journal open failed: %s", 11569 isc_result_totext(result)); 11570 return result; 11571 } 11572 11573 if (dns_journal_empty(journal)) { 11574 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1), 11575 "journal empty"); 11576 dns_journal_destroy(&journal); 11577 return ISC_R_SUCCESS; 11578 } 11579 11580 result = dns_journal_rollforward(journal, db, options); 11581 switch (result) { 11582 case ISC_R_SUCCESS: 11583 *needdump = true; 11584 FALLTHROUGH; 11585 case DNS_R_UPTODATE: 11586 if (dns_journal_recovered(journal)) { 11587 *fixjournal = true; 11588 dns_zone_logc( 11589 zone, DNS_LOGCATEGORY_ZONELOAD, 11590 ISC_LOG_DEBUG(1), 11591 "journal rollforward completed successfully " 11592 "using old journal format: %s", 11593 isc_result_totext(result)); 11594 } else { 11595 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 11596 ISC_LOG_DEBUG(1), 11597 "journal rollforward completed " 11598 "successfully: %s", 11599 isc_result_totext(result)); 11600 } 11601 11602 dns_journal_destroy(&journal); 11603 return ISC_R_SUCCESS; 11604 case ISC_R_NOTFOUND: 11605 case ISC_R_RANGE: 11606 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 11607 "journal rollforward failed: journal out of sync " 11608 "with zone"); 11609 dns_journal_destroy(&journal); 11610 return result; 11611 default: 11612 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 11613 "journal rollforward failed: %s", 11614 isc_result_totext(result)); 11615 dns_journal_destroy(&journal); 11616 return result; 11617 } 11618 } 11619 11620 static void 11621 zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial) { 11622 isc_result_t result; 11623 int32_t journalsize; 11624 dns_dbversion_t *ver = NULL; 11625 uint64_t dbsize; 11626 uint32_t options = 0; 11627 11628 INSIST(LOCKED_ZONE(zone)); 11629 if (inline_raw(zone)) { 11630 INSIST(LOCKED_ZONE(zone->secure)); 11631 } 11632 11633 journalsize = zone->journalsize; 11634 if (journalsize == -1) { 11635 journalsize = DNS_JOURNAL_SIZE_MAX; 11636 dns_db_currentversion(db, &ver); 11637 result = dns_db_getsize(db, ver, NULL, &dbsize); 11638 dns_db_closeversion(db, &ver, false); 11639 if (result != ISC_R_SUCCESS) { 11640 dns_zone_log(zone, ISC_LOG_ERROR, 11641 "zone_journal_compact: " 11642 "could not get zone size: %s", 11643 isc_result_totext(result)); 11644 } else if (dbsize < DNS_JOURNAL_SIZE_MAX / 2) { 11645 journalsize = (int32_t)dbsize * 2; 11646 } 11647 } 11648 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FIXJOURNAL)) { 11649 options |= DNS_JOURNAL_COMPACTALL; 11650 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FIXJOURNAL); 11651 zone_debuglog(zone, __func__, 1, "repair full journal"); 11652 } else { 11653 zone_debuglog(zone, __func__, 1, "target journal size %d", 11654 journalsize); 11655 } 11656 result = dns_journal_compact(zone->mctx, zone->journal, serial, options, 11657 journalsize); 11658 switch (result) { 11659 case ISC_R_SUCCESS: 11660 case ISC_R_NOSPACE: 11661 case ISC_R_NOTFOUND: 11662 dns_zone_log(zone, ISC_LOG_DEBUG(3), "dns_journal_compact: %s", 11663 isc_result_totext(result)); 11664 break; 11665 default: 11666 dns_zone_log(zone, ISC_LOG_ERROR, 11667 "dns_journal_compact failed: %s", 11668 isc_result_totext(result)); 11669 break; 11670 } 11671 } 11672 11673 isc_result_t 11674 dns_zone_flush(dns_zone_t *zone) { 11675 isc_result_t result = ISC_R_SUCCESS; 11676 bool dumping; 11677 11678 REQUIRE(DNS_ZONE_VALID(zone)); 11679 11680 LOCK_ZONE(zone); 11681 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH); 11682 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 11683 zone->masterfile != NULL) 11684 { 11685 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 11686 result = ISC_R_ALREADYRUNNING; 11687 dumping = was_dumping(zone); 11688 } else { 11689 dumping = true; 11690 } 11691 UNLOCK_ZONE(zone); 11692 if (!dumping) { 11693 result = zone_dump(zone, true); 11694 } 11695 return result; 11696 } 11697 11698 isc_result_t 11699 dns_zone_dump(dns_zone_t *zone) { 11700 isc_result_t result = ISC_R_ALREADYRUNNING; 11701 bool dumping; 11702 11703 REQUIRE(DNS_ZONE_VALID(zone)); 11704 11705 LOCK_ZONE(zone); 11706 dumping = was_dumping(zone); 11707 UNLOCK_ZONE(zone); 11708 if (!dumping) { 11709 result = zone_dump(zone, false); 11710 } 11711 return result; 11712 } 11713 11714 static void 11715 zone_needdump(dns_zone_t *zone, unsigned int delay) { 11716 isc_time_t dumptime; 11717 isc_time_t now; 11718 11719 /* 11720 * 'zone' locked by caller 11721 */ 11722 11723 REQUIRE(DNS_ZONE_VALID(zone)); 11724 REQUIRE(LOCKED_ZONE(zone)); 11725 ENTER; 11726 11727 /* 11728 * Do we have a place to dump to and are we loaded? 11729 */ 11730 if (zone->masterfile == NULL || 11731 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) 11732 { 11733 return; 11734 } 11735 11736 now = isc_time_now(); 11737 /* add some noise */ 11738 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime); 11739 11740 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 11741 if (isc_time_isepoch(&zone->dumptime) || 11742 isc_time_compare(&zone->dumptime, &dumptime) > 0) 11743 { 11744 zone->dumptime = dumptime; 11745 } 11746 if (zone->loop != NULL) { 11747 zone_settimer(zone, &now); 11748 } 11749 } 11750 11751 static void 11752 dump_done(void *arg, isc_result_t result) { 11753 dns_zone_t *zone = arg; 11754 dns_zone_t *secure = NULL; 11755 dns_db_t *db; 11756 dns_dbversion_t *version; 11757 bool again = false; 11758 bool compact = false; 11759 uint32_t serial; 11760 isc_result_t tresult; 11761 11762 REQUIRE(DNS_ZONE_VALID(zone)); 11763 11764 ENTER; 11765 11766 /* 11767 * Adjust modification time of zone file to preserve expire timing. 11768 */ 11769 if ((zone->type == dns_zone_secondary || 11770 zone->type == dns_zone_mirror || 11771 zone->type == dns_zone_redirect) && 11772 result == ISC_R_SUCCESS) 11773 { 11774 LOCK_ZONE(zone); 11775 isc_time_t when; 11776 isc_interval_t i; 11777 isc_interval_set(&i, zone->expire, 0); 11778 result = isc_time_subtract(&zone->expiretime, &i, &when); 11779 if (result == ISC_R_SUCCESS) { 11780 (void)isc_file_settime(zone->masterfile, &when); 11781 } else { 11782 result = ISC_R_SUCCESS; 11783 } 11784 UNLOCK_ZONE(zone); 11785 } 11786 11787 if (result == ISC_R_SUCCESS && zone->journal != NULL) { 11788 /* 11789 * We don't own these, zone->dctx must stay valid. 11790 */ 11791 db = dns_dumpctx_db(zone->dumpctx); 11792 version = dns_dumpctx_version(zone->dumpctx); 11793 tresult = dns_db_getsoaserial(db, version, &serial); 11794 11795 /* 11796 * Handle lock order inversion. 11797 */ 11798 again: 11799 LOCK_ZONE(zone); 11800 if (inline_raw(zone)) { 11801 secure = zone->secure; 11802 INSIST(secure != zone); 11803 TRYLOCK_ZONE(result, secure); 11804 if (result != ISC_R_SUCCESS) { 11805 UNLOCK_ZONE(zone); 11806 secure = NULL; 11807 isc_thread_yield(); 11808 goto again; 11809 } 11810 } 11811 11812 /* 11813 * If there is a secure version of this zone 11814 * use its serial if it is less than ours. 11815 */ 11816 if (tresult == ISC_R_SUCCESS && secure != NULL) { 11817 uint32_t sserial; 11818 isc_result_t mresult; 11819 11820 ZONEDB_LOCK(&secure->dblock, isc_rwlocktype_read); 11821 if (secure->db != NULL) { 11822 mresult = dns_db_getsoaserial(zone->secure->db, 11823 NULL, &sserial); 11824 if (mresult == ISC_R_SUCCESS && 11825 isc_serial_lt(sserial, serial)) 11826 { 11827 serial = sserial; 11828 } 11829 } 11830 ZONEDB_UNLOCK(&secure->dblock, isc_rwlocktype_read); 11831 } 11832 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) { 11833 dns_db_t *zdb = NULL; 11834 if (dns_zone_getdb(zone, &zdb) == ISC_R_SUCCESS) { 11835 zone_journal_compact(zone, zdb, serial); 11836 dns_db_detach(&zdb); 11837 } 11838 } else if (tresult == ISC_R_SUCCESS) { 11839 compact = true; 11840 zone->compact_serial = serial; 11841 } 11842 if (secure != NULL) { 11843 UNLOCK_ZONE(secure); 11844 } 11845 UNLOCK_ZONE(zone); 11846 } 11847 11848 LOCK_ZONE(zone); 11849 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 11850 if (compact) { 11851 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 11852 } 11853 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN)) { 11854 /* 11855 * If DNS_ZONEFLG_SHUTDOWN is set, all external references to 11856 * the zone are gone, which means it is in the process of being 11857 * cleaned up, so do not reschedule dumping. 11858 * 11859 * Detach from the raw version of the zone in case this 11860 * operation has been deferred in zone_shutdown(). 11861 */ 11862 if (zone->raw != NULL) { 11863 dns_zone_detach(&zone->raw); 11864 } 11865 if (result == ISC_R_SUCCESS) { 11866 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 11867 } 11868 } else if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) { 11869 /* 11870 * Try again in a short while. 11871 */ 11872 zone_needdump(zone, DNS_DUMP_DELAY); 11873 } else if (result == ISC_R_SUCCESS && 11874 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 11875 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 11876 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 11877 { 11878 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 11879 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 11880 isc_time_settoepoch(&zone->dumptime); 11881 again = true; 11882 } else if (result == ISC_R_SUCCESS) { 11883 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 11884 } 11885 11886 if (zone->dumpctx != NULL) { 11887 dns_dumpctx_detach(&zone->dumpctx); 11888 } 11889 UNLOCK_ZONE(zone); 11890 if (again) { 11891 (void)zone_dump(zone, false); 11892 } 11893 dns_zone_idetach(&zone); 11894 } 11895 11896 static isc_result_t 11897 zone_dump(dns_zone_t *zone, bool compact) { 11898 isc_result_t result; 11899 dns_dbversion_t *version = NULL; 11900 bool again = false; 11901 dns_db_t *db = NULL; 11902 char *masterfile = NULL; 11903 dns_masterformat_t masterformat = dns_masterformat_none; 11904 const dns_master_style_t *masterstyle = NULL; 11905 dns_masterrawheader_t rawdata; 11906 11907 /* 11908 * 'compact' MUST only be set if we are loop locked. 11909 */ 11910 11911 REQUIRE(DNS_ZONE_VALID(zone)); 11912 ENTER; 11913 11914 redo: 11915 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 11916 if (zone->db != NULL) { 11917 dns_db_attach(zone->db, &db); 11918 } 11919 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11920 LOCK_ZONE(zone); 11921 if (zone->masterfile != NULL) { 11922 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile); 11923 masterformat = zone->masterformat; 11924 } 11925 if (zone->type == dns_zone_key) { 11926 masterstyle = &dns_master_style_keyzone; 11927 } else if (zone->masterstyle != NULL) { 11928 masterstyle = zone->masterstyle; 11929 } else { 11930 masterstyle = &dns_master_style_default; 11931 } 11932 UNLOCK_ZONE(zone); 11933 if (db == NULL) { 11934 result = DNS_R_NOTLOADED; 11935 goto fail; 11936 } 11937 if (masterfile == NULL) { 11938 result = DNS_R_NOMASTERFILE; 11939 goto fail; 11940 } 11941 11942 dns_db_currentversion(db, &version); 11943 11944 dns_master_initrawheader(&rawdata); 11945 11946 if (inline_secure(zone)) { 11947 get_raw_serial(zone->raw, &rawdata); 11948 } 11949 11950 if (compact && zone->type != dns_zone_stub) { 11951 LOCK_ZONE(zone); 11952 zone_iattach(zone, &(dns_zone_t *){ NULL }); 11953 11954 INSIST(zone != zone->raw); 11955 11956 result = dns_master_dumpasync( 11957 zone->mctx, db, version, masterstyle, masterfile, 11958 zone->loop, dump_done, zone, &zone->dumpctx, 11959 masterformat, &rawdata); 11960 11961 UNLOCK_ZONE(zone); 11962 if (result != ISC_R_SUCCESS) { 11963 dns_zone_idetach(&(dns_zone_t *){ zone }); 11964 goto fail; 11965 } 11966 result = DNS_R_CONTINUE; 11967 } else { 11968 result = dns_master_dump(zone->mctx, db, version, masterstyle, 11969 masterfile, masterformat, &rawdata); 11970 if ((zone->type == dns_zone_secondary || 11971 zone->type == dns_zone_mirror || 11972 zone->type == dns_zone_redirect) && 11973 result == ISC_R_SUCCESS) 11974 { 11975 isc_time_t when; 11976 isc_interval_t i; 11977 isc_interval_set(&i, zone->expire, 0); 11978 result = isc_time_subtract(&zone->expiretime, &i, 11979 &when); 11980 if (result == ISC_R_SUCCESS) { 11981 (void)isc_file_settime(zone->masterfile, &when); 11982 } else { 11983 result = ISC_R_SUCCESS; 11984 } 11985 } 11986 } 11987 fail: 11988 if (version != NULL) { 11989 dns_db_closeversion(db, &version, false); 11990 } 11991 if (db != NULL) { 11992 dns_db_detach(&db); 11993 } 11994 if (masterfile != NULL) { 11995 isc_mem_free(zone->mctx, masterfile); 11996 masterfile = NULL; 11997 } 11998 11999 if (result == DNS_R_CONTINUE) { 12000 /* 12001 * Asyncronous write is in progress. Zone flags will get 12002 * updated on completion. Cleanup is complete. We are done. 12003 */ 12004 return ISC_R_SUCCESS; 12005 } 12006 12007 again = false; 12008 LOCK_ZONE(zone); 12009 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 12010 if (result != ISC_R_SUCCESS) { 12011 /* 12012 * Try again in a short while. 12013 */ 12014 zone_needdump(zone, DNS_DUMP_DELAY); 12015 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 12016 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 12017 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 12018 { 12019 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 12020 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 12021 isc_time_settoepoch(&zone->dumptime); 12022 again = true; 12023 } else { 12024 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 12025 } 12026 UNLOCK_ZONE(zone); 12027 if (again) { 12028 goto redo; 12029 } 12030 12031 return result; 12032 } 12033 12034 static isc_result_t 12035 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style, 12036 dns_masterformat_t format, const uint32_t rawversion) { 12037 isc_result_t result; 12038 dns_dbversion_t *version = NULL; 12039 dns_db_t *db = NULL; 12040 dns_masterrawheader_t rawdata; 12041 12042 REQUIRE(DNS_ZONE_VALID(zone)); 12043 12044 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12045 if (zone->db != NULL) { 12046 dns_db_attach(zone->db, &db); 12047 } 12048 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12049 if (db == NULL) { 12050 return DNS_R_NOTLOADED; 12051 } 12052 12053 dns_db_currentversion(db, &version); 12054 dns_master_initrawheader(&rawdata); 12055 if (rawversion == 0) { 12056 rawdata.flags |= DNS_MASTERRAW_COMPAT; 12057 } else if (inline_secure(zone)) { 12058 get_raw_serial(zone->raw, &rawdata); 12059 } else if (zone->sourceserialset) { 12060 rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET; 12061 rawdata.sourceserial = zone->sourceserial; 12062 } 12063 result = dns_master_dumptostream(zone->mctx, db, version, style, format, 12064 &rawdata, fd); 12065 dns_db_closeversion(db, &version, false); 12066 dns_db_detach(&db); 12067 return result; 12068 } 12069 12070 isc_result_t 12071 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, 12072 const dns_master_style_t *style, 12073 const uint32_t rawversion) { 12074 return dumptostream(zone, fd, style, format, rawversion); 12075 } 12076 12077 void 12078 dns_zone_unload(dns_zone_t *zone) { 12079 REQUIRE(DNS_ZONE_VALID(zone)); 12080 12081 LOCK_ZONE(zone); 12082 zone_unload(zone); 12083 UNLOCK_ZONE(zone); 12084 } 12085 12086 static void 12087 notify_cancel(dns_zone_t *zone) { 12088 dns_notify_t *notify; 12089 12090 /* 12091 * 'zone' locked by caller. 12092 */ 12093 12094 REQUIRE(LOCKED_ZONE(zone)); 12095 12096 for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL; 12097 notify = ISC_LIST_NEXT(notify, link)) 12098 { 12099 if (notify->find != NULL) { 12100 dns_adb_cancelfind(notify->find); 12101 } 12102 if (notify->request != NULL) { 12103 dns_request_cancel(notify->request); 12104 } 12105 } 12106 } 12107 12108 static void 12109 checkds_cancel(dns_zone_t *zone) { 12110 dns_checkds_t *checkds; 12111 12112 /* 12113 * 'zone' locked by caller. 12114 */ 12115 12116 REQUIRE(LOCKED_ZONE(zone)); 12117 12118 for (checkds = ISC_LIST_HEAD(zone->checkds_requests); checkds != NULL; 12119 checkds = ISC_LIST_NEXT(checkds, link)) 12120 { 12121 if (checkds->find != NULL) { 12122 dns_adb_cancelfind(checkds->find); 12123 } 12124 if (checkds->request != NULL) { 12125 dns_request_cancel(checkds->request); 12126 } 12127 } 12128 } 12129 12130 static void 12131 forward_cancel(dns_zone_t *zone) { 12132 dns_forward_t *forward; 12133 12134 /* 12135 * 'zone' locked by caller. 12136 */ 12137 12138 REQUIRE(LOCKED_ZONE(zone)); 12139 12140 for (forward = ISC_LIST_HEAD(zone->forwards); forward != NULL; 12141 forward = ISC_LIST_NEXT(forward, link)) 12142 { 12143 if (forward->request != NULL) { 12144 dns_request_cancel(forward->request); 12145 } 12146 } 12147 } 12148 12149 static void 12150 zone_unload(dns_zone_t *zone) { 12151 /* 12152 * 'zone' locked by caller. 12153 */ 12154 12155 REQUIRE(LOCKED_ZONE(zone)); 12156 12157 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 12158 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 12159 { 12160 if (zone->dumpctx != NULL) { 12161 dns_dumpctx_cancel(zone->dumpctx); 12162 } 12163 } 12164 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 12165 zone_detachdb(zone); 12166 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 12167 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED); 12168 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 12169 12170 if (zone->type == dns_zone_mirror) { 12171 dns_zone_log(zone, ISC_LOG_INFO, 12172 "mirror zone is no longer in use; " 12173 "reverting to normal recursion"); 12174 } 12175 } 12176 12177 void 12178 dns_zone_setminrefreshtime(dns_zone_t *zone, uint32_t val) { 12179 REQUIRE(DNS_ZONE_VALID(zone)); 12180 REQUIRE(val > 0); 12181 12182 zone->minrefresh = val; 12183 } 12184 12185 void 12186 dns_zone_setmaxrefreshtime(dns_zone_t *zone, uint32_t val) { 12187 REQUIRE(DNS_ZONE_VALID(zone)); 12188 REQUIRE(val > 0); 12189 12190 zone->maxrefresh = val; 12191 } 12192 12193 void 12194 dns_zone_setminretrytime(dns_zone_t *zone, uint32_t val) { 12195 REQUIRE(DNS_ZONE_VALID(zone)); 12196 REQUIRE(val > 0); 12197 12198 zone->minretry = val; 12199 } 12200 12201 void 12202 dns_zone_setmaxretrytime(dns_zone_t *zone, uint32_t val) { 12203 REQUIRE(DNS_ZONE_VALID(zone)); 12204 REQUIRE(val > 0); 12205 12206 zone->maxretry = val; 12207 } 12208 12209 uint32_t 12210 dns_zone_getmaxrecords(dns_zone_t *zone) { 12211 REQUIRE(DNS_ZONE_VALID(zone)); 12212 12213 return zone->maxrecords; 12214 } 12215 12216 void 12217 dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) { 12218 REQUIRE(DNS_ZONE_VALID(zone)); 12219 12220 zone->maxrecords = val; 12221 } 12222 12223 void 12224 dns_zone_setmaxrrperset(dns_zone_t *zone, uint32_t val) { 12225 REQUIRE(DNS_ZONE_VALID(zone)); 12226 12227 zone->maxrrperset = val; 12228 if (zone->db != NULL) { 12229 dns_db_setmaxrrperset(zone->db, val); 12230 } 12231 } 12232 12233 void 12234 dns_zone_setmaxtypepername(dns_zone_t *zone, uint32_t val) { 12235 REQUIRE(DNS_ZONE_VALID(zone)); 12236 12237 zone->maxtypepername = val; 12238 if (zone->db != NULL) { 12239 dns_db_setmaxtypepername(zone->db, val); 12240 } 12241 } 12242 12243 static bool 12244 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name, 12245 isc_sockaddr_t *addr, dns_tsigkey_t *key, 12246 dns_transport_t *transport) { 12247 dns_notify_t *notify; 12248 dns_zonemgr_t *zmgr; 12249 isc_result_t result; 12250 12251 for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL; 12252 notify = ISC_LIST_NEXT(notify, link)) 12253 { 12254 if (notify->request != NULL) { 12255 continue; 12256 } 12257 if (name != NULL && dns_name_dynamic(¬ify->ns) && 12258 dns_name_equal(name, ¬ify->ns)) 12259 { 12260 goto requeue; 12261 } 12262 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst) && 12263 notify->key == key && notify->transport == transport) 12264 { 12265 goto requeue; 12266 } 12267 } 12268 return false; 12269 12270 requeue: 12271 /* 12272 * If we are enqueued on the startup ratelimiter and this is 12273 * not a startup notify, re-enqueue on the normal notify 12274 * ratelimiter. 12275 */ 12276 if (notify->rlevent != NULL && (flags & DNS_NOTIFY_STARTUP) == 0 && 12277 (notify->flags & DNS_NOTIFY_STARTUP) != 0) 12278 { 12279 zmgr = notify->zone->zmgr; 12280 result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl, 12281 ¬ify->rlevent); 12282 if (result != ISC_R_SUCCESS) { 12283 return true; 12284 } 12285 12286 notify->flags &= ~DNS_NOTIFY_STARTUP; 12287 result = isc_ratelimiter_enqueue( 12288 notify->zone->zmgr->notifyrl, notify->zone->loop, 12289 notify_send_toaddr, notify, ¬ify->rlevent); 12290 if (result != ISC_R_SUCCESS) { 12291 return false; 12292 } 12293 } 12294 12295 return true; 12296 } 12297 12298 static bool 12299 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) { 12300 dns_tsigkey_t *key = NULL; 12301 isc_sockaddr_t src; 12302 isc_sockaddr_t any; 12303 bool isself; 12304 isc_netaddr_t dstaddr; 12305 isc_result_t result; 12306 12307 if (zone->view == NULL || zone->isself == NULL) { 12308 return false; 12309 } 12310 12311 switch (isc_sockaddr_pf(dst)) { 12312 case PF_INET: 12313 src = zone->notifysrc4; 12314 isc_sockaddr_any(&any); 12315 break; 12316 case PF_INET6: 12317 src = zone->notifysrc6; 12318 isc_sockaddr_any6(&any); 12319 break; 12320 default: 12321 return false; 12322 } 12323 12324 /* 12325 * When sending from any the kernel will assign a source address 12326 * that matches the destination address. 12327 */ 12328 if (isc_sockaddr_eqaddr(&any, &src)) { 12329 src = *dst; 12330 } 12331 12332 isc_netaddr_fromsockaddr(&dstaddr, dst); 12333 result = dns_view_getpeertsig(zone->view, &dstaddr, &key); 12334 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 12335 return false; 12336 } 12337 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass, 12338 zone->isselfarg); 12339 if (key != NULL) { 12340 dns_tsigkey_detach(&key); 12341 } 12342 return isself; 12343 } 12344 12345 static void 12346 notify_destroy(dns_notify_t *notify, bool locked) { 12347 isc_mem_t *mctx; 12348 12349 REQUIRE(DNS_NOTIFY_VALID(notify)); 12350 12351 if (notify->zone != NULL) { 12352 if (!locked) { 12353 LOCK_ZONE(notify->zone); 12354 } 12355 REQUIRE(LOCKED_ZONE(notify->zone)); 12356 if (ISC_LINK_LINKED(notify, link)) { 12357 ISC_LIST_UNLINK(notify->zone->notifies, notify, link); 12358 } 12359 if (!locked) { 12360 UNLOCK_ZONE(notify->zone); 12361 } 12362 if (locked) { 12363 zone_idetach(¬ify->zone); 12364 } else { 12365 dns_zone_idetach(¬ify->zone); 12366 } 12367 } 12368 if (notify->find != NULL) { 12369 dns_adb_destroyfind(¬ify->find); 12370 } 12371 if (notify->request != NULL) { 12372 dns_request_destroy(¬ify->request); 12373 } 12374 if (dns_name_dynamic(¬ify->ns)) { 12375 dns_name_free(¬ify->ns, notify->mctx); 12376 } 12377 if (notify->key != NULL) { 12378 dns_tsigkey_detach(¬ify->key); 12379 } 12380 if (notify->transport != NULL) { 12381 dns_transport_detach(¬ify->transport); 12382 } 12383 mctx = notify->mctx; 12384 isc_mem_put(notify->mctx, notify, sizeof(*notify)); 12385 isc_mem_detach(&mctx); 12386 } 12387 12388 static isc_result_t 12389 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) { 12390 dns_notify_t *notify; 12391 12392 REQUIRE(notifyp != NULL && *notifyp == NULL); 12393 12394 notify = isc_mem_get(mctx, sizeof(*notify)); 12395 *notify = (dns_notify_t){ 12396 .flags = flags, 12397 }; 12398 12399 isc_mem_attach(mctx, ¬ify->mctx); 12400 isc_sockaddr_any(¬ify->src); 12401 isc_sockaddr_any(¬ify->dst); 12402 dns_name_init(¬ify->ns, NULL); 12403 ISC_LINK_INIT(notify, link); 12404 notify->magic = NOTIFY_MAGIC; 12405 *notifyp = notify; 12406 return ISC_R_SUCCESS; 12407 } 12408 12409 /* 12410 * XXXAG should check for DNS_ZONEFLG_EXITING 12411 */ 12412 static void 12413 process_notify_adb_event(void *arg) { 12414 dns_adbfind_t *find = (dns_adbfind_t *)arg; 12415 dns_notify_t *notify = (dns_notify_t *)find->cbarg; 12416 dns_adbstatus_t astat = find->status; 12417 12418 REQUIRE(DNS_NOTIFY_VALID(notify)); 12419 REQUIRE(find == notify->find); 12420 12421 switch (astat) { 12422 case DNS_ADB_MOREADDRESSES: 12423 dns_adb_destroyfind(¬ify->find); 12424 notify_find_address(notify); 12425 return; 12426 12427 case DNS_ADB_NOMOREADDRESSES: 12428 LOCK_ZONE(notify->zone); 12429 notify_send(notify); 12430 UNLOCK_ZONE(notify->zone); 12431 break; 12432 12433 default: 12434 break; 12435 } 12436 12437 notify_destroy(notify, false); 12438 } 12439 12440 static void 12441 notify_find_address(dns_notify_t *notify) { 12442 isc_result_t result; 12443 unsigned int options; 12444 dns_adb_t *adb = NULL; 12445 12446 REQUIRE(DNS_NOTIFY_VALID(notify)); 12447 12448 options = DNS_ADBFIND_WANTEVENT; 12449 if (isc_net_probeipv4() != ISC_R_DISABLED) { 12450 options |= DNS_ADBFIND_INET; 12451 } 12452 if (isc_net_probeipv6() != ISC_R_DISABLED) { 12453 options |= DNS_ADBFIND_INET6; 12454 } 12455 12456 dns_view_getadb(notify->zone->view, &adb); 12457 if (adb == NULL) { 12458 goto destroy; 12459 } 12460 12461 result = dns_adb_createfind( 12462 adb, notify->zone->loop, process_notify_adb_event, notify, 12463 ¬ify->ns, dns_rootname, 0, options, 0, NULL, 12464 notify->zone->view->dstport, 0, NULL, ¬ify->find); 12465 dns_adb_detach(&adb); 12466 12467 /* Something failed? */ 12468 if (result != ISC_R_SUCCESS) { 12469 goto destroy; 12470 } 12471 12472 /* More addresses pending? */ 12473 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) { 12474 return; 12475 } 12476 12477 /* We have as many addresses as we can get. */ 12478 LOCK_ZONE(notify->zone); 12479 notify_send(notify); 12480 UNLOCK_ZONE(notify->zone); 12481 12482 destroy: 12483 notify_destroy(notify, false); 12484 } 12485 12486 static isc_result_t 12487 notify_send_queue(dns_notify_t *notify, bool startup) { 12488 return isc_ratelimiter_enqueue( 12489 startup ? notify->zone->zmgr->startupnotifyrl 12490 : notify->zone->zmgr->notifyrl, 12491 notify->zone->loop, notify_send_toaddr, notify, 12492 ¬ify->rlevent); 12493 } 12494 12495 static void 12496 notify_send_toaddr(void *arg) { 12497 dns_notify_t *notify = (dns_notify_t *)arg; 12498 isc_result_t result; 12499 dns_message_t *message = NULL; 12500 isc_netaddr_t dstip; 12501 dns_tsigkey_t *key = NULL; 12502 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 12503 isc_sockaddr_t src; 12504 unsigned int options, timeout, udptimeout; 12505 bool have_notifysource = false; 12506 isc_tlsctx_cache_t *zmgr_tlsctx_cache = NULL; 12507 12508 REQUIRE(DNS_NOTIFY_VALID(notify)); 12509 12510 LOCK_ZONE(notify->zone); 12511 12512 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 12513 12514 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0 || 12515 notify->rlevent->canceled || 12516 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) || 12517 notify->zone->view->requestmgr == NULL || notify->zone->db == NULL) 12518 { 12519 result = ISC_R_CANCELED; 12520 goto cleanup; 12521 } 12522 12523 /* 12524 * The raw IPv4 address should also exist. Don't send to the 12525 * mapped form. 12526 */ 12527 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 && 12528 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) 12529 { 12530 notify_log(notify->zone, ISC_LOG_DEBUG(3), 12531 "notify: ignoring IPv6 mapped IPV4 address: %s", 12532 addrbuf); 12533 result = ISC_R_CANCELED; 12534 goto cleanup; 12535 } 12536 12537 result = notify_createmessage(notify->zone, notify->flags, &message); 12538 if (result != ISC_R_SUCCESS) { 12539 goto cleanup; 12540 } 12541 12542 if (notify->key != NULL) { 12543 /* Transfer ownership of key */ 12544 key = notify->key; 12545 notify->key = NULL; 12546 } else { 12547 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst); 12548 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key); 12549 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 12550 notify_log(notify->zone, ISC_LOG_ERROR, 12551 "NOTIFY to %s not sent. " 12552 "Peer TSIG key lookup failure.", 12553 addrbuf); 12554 goto cleanup_message; 12555 } 12556 } 12557 12558 if (key != NULL) { 12559 char namebuf[DNS_NAME_FORMATSIZE]; 12560 12561 dns_name_format(key->name, namebuf, sizeof(namebuf)); 12562 notify_log(notify->zone, ISC_LOG_INFO, 12563 "sending notify to %s : TSIG (%s)", addrbuf, 12564 namebuf); 12565 } else { 12566 notify_log(notify->zone, ISC_LOG_INFO, "sending notify to %s", 12567 addrbuf); 12568 } 12569 options = 0; 12570 if (notify->zone->view->peers != NULL) { 12571 dns_peer_t *peer = NULL; 12572 bool usetcp = false; 12573 result = dns_peerlist_peerbyaddr(notify->zone->view->peers, 12574 &dstip, &peer); 12575 if (result == ISC_R_SUCCESS) { 12576 result = dns_peer_getnotifysource(peer, &src); 12577 if (result == ISC_R_SUCCESS) { 12578 have_notifysource = true; 12579 } 12580 result = dns_peer_getforcetcp(peer, &usetcp); 12581 if (result == ISC_R_SUCCESS && usetcp) { 12582 options |= DNS_FETCHOPT_TCP; 12583 } 12584 } 12585 } 12586 switch (isc_sockaddr_pf(¬ify->dst)) { 12587 case PF_INET: 12588 if (!have_notifysource) { 12589 isc_sockaddr_t any; 12590 isc_sockaddr_any(&any); 12591 12592 src = notify->src; 12593 if (isc_sockaddr_equal(&src, &any)) { 12594 src = notify->zone->notifysrc4; 12595 } 12596 } 12597 break; 12598 case PF_INET6: 12599 if (!have_notifysource) { 12600 isc_sockaddr_t any; 12601 isc_sockaddr_any6(&any); 12602 12603 src = notify->src; 12604 if (isc_sockaddr_equal(&src, &any)) { 12605 src = notify->zone->notifysrc6; 12606 } 12607 } 12608 break; 12609 default: 12610 result = ISC_R_NOTIMPLEMENTED; 12611 goto cleanup_key; 12612 } 12613 udptimeout = 5; 12614 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) { 12615 udptimeout = 30; 12616 } 12617 timeout = 3 * udptimeout + 1; 12618 again: 12619 if ((notify->flags & DNS_NOTIFY_TCP) != 0) { 12620 options |= DNS_REQUESTOPT_TCP; 12621 udptimeout = 0; 12622 timeout = 15; 12623 } 12624 12625 zmgr_tlsctx_attach(notify->zone->zmgr, &zmgr_tlsctx_cache); 12626 12627 result = dns_request_create(notify->zone->view->requestmgr, message, 12628 &src, ¬ify->dst, notify->transport, 12629 zmgr_tlsctx_cache, options, key, timeout, 12630 udptimeout, 2, notify->zone->loop, 12631 notify_done, notify, ¬ify->request); 12632 12633 isc_tlsctx_cache_detach(&zmgr_tlsctx_cache); 12634 12635 if (result == ISC_R_SUCCESS) { 12636 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) { 12637 inc_stats(notify->zone, 12638 dns_zonestatscounter_notifyoutv4); 12639 } else { 12640 inc_stats(notify->zone, 12641 dns_zonestatscounter_notifyoutv6); 12642 } 12643 } else if (result == ISC_R_SHUTTINGDOWN || result == ISC_R_CANCELED) { 12644 goto cleanup_key; 12645 } else if ((notify->flags & DNS_NOTIFY_TCP) == 0) { 12646 notify_log(notify->zone, ISC_LOG_NOTICE, 12647 "notify to %s failed: %s: retrying over TCP", 12648 addrbuf, isc_result_totext(result)); 12649 notify->flags |= DNS_NOTIFY_TCP; 12650 goto again; 12651 } 12652 12653 cleanup_key: 12654 if (key != NULL) { 12655 dns_tsigkey_detach(&key); 12656 } 12657 cleanup_message: 12658 dns_message_detach(&message); 12659 cleanup: 12660 UNLOCK_ZONE(notify->zone); 12661 if (notify->rlevent != NULL) { 12662 isc_rlevent_free(¬ify->rlevent); 12663 } 12664 12665 if (result != ISC_R_SUCCESS) { 12666 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 12667 notify_log(notify->zone, ISC_LOG_WARNING, 12668 "notify to %s failed: %s", addrbuf, 12669 isc_result_totext(result)); 12670 notify_destroy(notify, false); 12671 } 12672 } 12673 12674 static void 12675 notify_send(dns_notify_t *notify) { 12676 dns_adbaddrinfo_t *ai; 12677 isc_sockaddr_t dst; 12678 isc_result_t result; 12679 dns_notify_t *newnotify = NULL; 12680 unsigned int flags; 12681 bool startup; 12682 12683 /* 12684 * Zone lock held by caller. 12685 */ 12686 REQUIRE(DNS_NOTIFY_VALID(notify)); 12687 REQUIRE(LOCKED_ZONE(notify->zone)); 12688 12689 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING)) { 12690 return; 12691 } 12692 12693 for (ai = ISC_LIST_HEAD(notify->find->list); ai != NULL; 12694 ai = ISC_LIST_NEXT(ai, publink)) 12695 { 12696 dst = ai->sockaddr; 12697 if (notify_isqueued(notify->zone, notify->flags, NULL, &dst, 12698 NULL, NULL)) 12699 { 12700 continue; 12701 } 12702 if (notify_isself(notify->zone, &dst)) { 12703 continue; 12704 } 12705 newnotify = NULL; 12706 flags = notify->flags & DNS_NOTIFY_NOSOA; 12707 result = notify_create(notify->mctx, flags, &newnotify); 12708 if (result != ISC_R_SUCCESS) { 12709 goto cleanup; 12710 } 12711 zone_iattach(notify->zone, &newnotify->zone); 12712 ISC_LIST_APPEND(newnotify->zone->notifies, newnotify, link); 12713 newnotify->dst = dst; 12714 if (isc_sockaddr_pf(&dst) == AF_INET6) { 12715 isc_sockaddr_any6(&newnotify->src); 12716 } 12717 startup = ((notify->flags & DNS_NOTIFY_STARTUP) != 0); 12718 result = notify_send_queue(newnotify, startup); 12719 if (result != ISC_R_SUCCESS) { 12720 goto cleanup; 12721 } 12722 newnotify = NULL; 12723 } 12724 12725 cleanup: 12726 if (newnotify != NULL) { 12727 notify_destroy(newnotify, true); 12728 } 12729 } 12730 12731 void 12732 dns_zone_notify(dns_zone_t *zone) { 12733 isc_time_t now; 12734 12735 REQUIRE(DNS_ZONE_VALID(zone)); 12736 12737 LOCK_ZONE(zone); 12738 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12739 12740 now = isc_time_now(); 12741 zone_settimer(zone, &now); 12742 UNLOCK_ZONE(zone); 12743 } 12744 12745 static void 12746 zone_notify(dns_zone_t *zone, isc_time_t *now) { 12747 dns_dbnode_t *node = NULL; 12748 dns_db_t *zonedb = NULL; 12749 dns_dbversion_t *version = NULL; 12750 dns_name_t *origin = NULL; 12751 dns_name_t primary; 12752 dns_rdata_ns_t ns; 12753 dns_rdata_soa_t soa; 12754 uint32_t serial; 12755 dns_rdata_t rdata = DNS_RDATA_INIT; 12756 dns_rdataset_t nsrdset; 12757 dns_rdataset_t soardset; 12758 isc_result_t result; 12759 isc_sockaddr_t src; 12760 isc_sockaddr_t dst; 12761 bool isqueued; 12762 dns_notifytype_t notifytype; 12763 unsigned int flags = 0; 12764 bool loggednotify = false; 12765 bool startup; 12766 12767 REQUIRE(DNS_ZONE_VALID(zone)); 12768 12769 LOCK_ZONE(zone); 12770 startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12771 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12772 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY); 12773 notifytype = zone->notifytype; 12774 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime); 12775 UNLOCK_ZONE(zone); 12776 12777 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || 12778 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 12779 { 12780 return; 12781 } 12782 12783 if (notifytype == dns_notifytype_no) { 12784 return; 12785 } 12786 12787 if (notifytype == dns_notifytype_masteronly && 12788 zone->type != dns_zone_primary) 12789 { 12790 return; 12791 } 12792 12793 origin = &zone->origin; 12794 12795 /* 12796 * If the zone is dialup we are done as we don't want to send 12797 * the current soa so as to force a refresh query. 12798 */ 12799 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) { 12800 flags |= DNS_NOTIFY_NOSOA; 12801 } 12802 12803 /* 12804 * Record that this was a notify due to starting up. 12805 */ 12806 if (startup) { 12807 flags |= DNS_NOTIFY_STARTUP; 12808 } 12809 12810 /* 12811 * Get SOA RRset. 12812 */ 12813 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12814 if (zone->db != NULL) { 12815 dns_db_attach(zone->db, &zonedb); 12816 } 12817 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12818 if (zonedb == NULL) { 12819 return; 12820 } 12821 dns_db_currentversion(zonedb, &version); 12822 result = dns_db_findnode(zonedb, origin, false, &node); 12823 if (result != ISC_R_SUCCESS) { 12824 goto cleanup1; 12825 } 12826 12827 dns_rdataset_init(&soardset); 12828 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, 12829 dns_rdatatype_none, 0, &soardset, NULL); 12830 if (result != ISC_R_SUCCESS) { 12831 goto cleanup2; 12832 } 12833 12834 /* 12835 * Find serial and primary server's name. 12836 */ 12837 dns_name_init(&primary, NULL); 12838 result = dns_rdataset_first(&soardset); 12839 if (result != ISC_R_SUCCESS) { 12840 goto cleanup3; 12841 } 12842 dns_rdataset_current(&soardset, &rdata); 12843 result = dns_rdata_tostruct(&rdata, &soa, NULL); 12844 RUNTIME_CHECK(result == ISC_R_SUCCESS); 12845 dns_rdata_reset(&rdata); 12846 dns_name_dup(&soa.origin, zone->mctx, &primary); 12847 serial = soa.serial; 12848 dns_rdataset_disassociate(&soardset); 12849 12850 /* 12851 * Enqueue notify requests for 'also-notify' servers. 12852 */ 12853 LOCK_ZONE(zone); 12854 12855 dns_remote_reset(&zone->notify, false); 12856 while (!dns_remote_done(&zone->notify)) { 12857 dns_tsigkey_t *key = NULL; 12858 dns_transport_t *transport = NULL; 12859 dns_notify_t *notify = NULL; 12860 dns_view_t *view = dns_zone_getview(zone); 12861 12862 if (dns_remote_keyname(&zone->notify) != NULL) { 12863 dns_name_t *keyname = dns_remote_keyname(&zone->notify); 12864 (void)dns_view_gettsig(view, keyname, &key); 12865 } 12866 12867 if (dns_remote_tlsname(&zone->notify) != NULL) { 12868 dns_name_t *tlsname = dns_remote_tlsname(&zone->notify); 12869 result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, 12870 tlsname, &transport); 12871 12872 if (result == ISC_R_SUCCESS) { 12873 notify_log( 12874 zone, ISC_LOG_INFO, 12875 "got TLS configuration for a notify"); 12876 } else { 12877 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 12878 ISC_LOG_ERROR, 12879 "could not get TLS configuration " 12880 "for zone transfer: %s", 12881 isc_result_totext(result)); 12882 goto next; 12883 } 12884 12885 flags |= DNS_NOTIFY_TCP; 12886 } 12887 12888 /* TODO: glue the transport to the notify */ 12889 12890 dst = dns_remote_curraddr(&zone->notify); 12891 src = dns_remote_sourceaddr(&zone->notify); 12892 INSIST(isc_sockaddr_pf(&src) == isc_sockaddr_pf(&dst)); 12893 12894 if (isc_sockaddr_disabled(&dst)) { 12895 goto next; 12896 } 12897 12898 if (notify_isqueued(zone, flags, NULL, &dst, key, transport)) { 12899 if (key != NULL) { 12900 dns_tsigkey_detach(&key); 12901 } 12902 if (transport != NULL) { 12903 dns_transport_detach(&transport); 12904 } 12905 goto next; 12906 } 12907 12908 result = notify_create(zone->mctx, flags, ¬ify); 12909 if (result != ISC_R_SUCCESS) { 12910 if (key != NULL) { 12911 dns_tsigkey_detach(&key); 12912 } 12913 if (transport != NULL) { 12914 dns_transport_detach(&transport); 12915 } 12916 goto next; 12917 } 12918 12919 zone_iattach(zone, ¬ify->zone); 12920 notify->src = src; 12921 notify->dst = dst; 12922 12923 INSIST(notify->key == NULL); 12924 12925 if (key != NULL) { 12926 notify->key = key; 12927 key = NULL; 12928 } 12929 12930 INSIST(notify->transport == NULL); 12931 if (transport != NULL) { 12932 notify->transport = transport; 12933 transport = NULL; 12934 } 12935 12936 ISC_LIST_APPEND(zone->notifies, notify, link); 12937 result = notify_send_queue(notify, startup); 12938 if (result != ISC_R_SUCCESS) { 12939 notify_destroy(notify, true); 12940 } 12941 if (!loggednotify) { 12942 notify_log(zone, ISC_LOG_INFO, 12943 "sending notifies (serial %u)", serial); 12944 loggednotify = true; 12945 } 12946 next: 12947 flags &= ~DNS_NOTIFY_TCP; 12948 dns_remote_next(&zone->notify, false); 12949 } 12950 UNLOCK_ZONE(zone); 12951 12952 if (notifytype == dns_notifytype_explicit) { 12953 goto cleanup3; 12954 } 12955 12956 /* 12957 * Process NS RRset to generate notifies. 12958 */ 12959 12960 dns_rdataset_init(&nsrdset); 12961 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns, 12962 dns_rdatatype_none, 0, &nsrdset, NULL); 12963 if (result != ISC_R_SUCCESS) { 12964 goto cleanup3; 12965 } 12966 12967 result = dns_rdataset_first(&nsrdset); 12968 while (result == ISC_R_SUCCESS) { 12969 dns_notify_t *notify = NULL; 12970 12971 dns_rdataset_current(&nsrdset, &rdata); 12972 result = dns_rdata_tostruct(&rdata, &ns, NULL); 12973 RUNTIME_CHECK(result == ISC_R_SUCCESS); 12974 dns_rdata_reset(&rdata); 12975 /* 12976 * Don't notify the primary server unless explicitly 12977 * configured to do so. 12978 */ 12979 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) && 12980 dns_name_compare(&primary, &ns.name) == 0) 12981 { 12982 result = dns_rdataset_next(&nsrdset); 12983 continue; 12984 } 12985 12986 if (!loggednotify) { 12987 notify_log(zone, ISC_LOG_INFO, 12988 "sending notifies (serial %u)", serial); 12989 loggednotify = true; 12990 } 12991 12992 LOCK_ZONE(zone); 12993 isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL, 12994 NULL); 12995 UNLOCK_ZONE(zone); 12996 if (isqueued) { 12997 result = dns_rdataset_next(&nsrdset); 12998 continue; 12999 } 13000 result = notify_create(zone->mctx, flags, ¬ify); 13001 if (result != ISC_R_SUCCESS) { 13002 continue; 13003 } 13004 dns_zone_iattach(zone, ¬ify->zone); 13005 dns_name_dup(&ns.name, zone->mctx, ¬ify->ns); 13006 LOCK_ZONE(zone); 13007 ISC_LIST_APPEND(zone->notifies, notify, link); 13008 UNLOCK_ZONE(zone); 13009 notify_find_address(notify); 13010 result = dns_rdataset_next(&nsrdset); 13011 } 13012 dns_rdataset_disassociate(&nsrdset); 13013 13014 cleanup3: 13015 if (dns_name_dynamic(&primary)) { 13016 dns_name_free(&primary, zone->mctx); 13017 } 13018 cleanup2: 13019 dns_db_detachnode(zonedb, &node); 13020 cleanup1: 13021 dns_db_closeversion(zonedb, &version, false); 13022 dns_db_detach(&zonedb); 13023 } 13024 13025 /*** 13026 *** Private 13027 ***/ 13028 static void 13029 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, dns_name_t *name, 13030 dns_message_t **messagep) { 13031 dns_message_t *message = NULL; 13032 dns_name_t *qname = NULL; 13033 dns_rdataset_t *qrdataset = NULL; 13034 13035 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, 13036 &message); 13037 13038 message->opcode = dns_opcode_query; 13039 message->rdclass = zone->rdclass; 13040 13041 dns_message_gettempname(message, &qname); 13042 13043 dns_message_gettemprdataset(message, &qrdataset); 13044 13045 /* 13046 * Make question. 13047 */ 13048 dns_name_clone(name, qname); 13049 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype); 13050 ISC_LIST_APPEND(qname->list, qrdataset, link); 13051 dns_message_addname(message, qname, DNS_SECTION_QUESTION); 13052 13053 *messagep = message; 13054 } 13055 13056 static isc_result_t 13057 add_opt(dns_message_t *message, uint16_t udpsize, bool reqnsid, 13058 bool reqexpire) { 13059 isc_result_t result; 13060 dns_rdataset_t *rdataset = NULL; 13061 dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS]; 13062 int count = 0; 13063 13064 /* Set EDNS options if applicable. */ 13065 if (reqnsid) { 13066 INSIST(count < DNS_EDNSOPTIONS); 13067 ednsopts[count].code = DNS_OPT_NSID; 13068 ednsopts[count].length = 0; 13069 ednsopts[count].value = NULL; 13070 count++; 13071 } 13072 if (reqexpire) { 13073 INSIST(count < DNS_EDNSOPTIONS); 13074 ednsopts[count].code = DNS_OPT_EXPIRE; 13075 ednsopts[count].length = 0; 13076 ednsopts[count].value = NULL; 13077 count++; 13078 } 13079 result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0, 13080 ednsopts, count); 13081 if (result != ISC_R_SUCCESS) { 13082 return result; 13083 } 13084 13085 return dns_message_setopt(message, rdataset); 13086 } 13087 13088 /* 13089 * Called when stub zone update is finished. 13090 * Update zone refresh, retry, expire values accordingly with 13091 * SOA received from primary, sync database to file, restart 13092 * zone management timer. 13093 */ 13094 static void 13095 stub_finish_zone_update(dns_stub_t *stub, isc_time_t now) { 13096 uint32_t refresh, retry, expire; 13097 isc_result_t result; 13098 isc_interval_t i; 13099 unsigned int soacount; 13100 dns_zone_t *zone = stub->zone; 13101 13102 /* 13103 * Tidy up. 13104 */ 13105 dns_db_closeversion(stub->db, &stub->version, true); 13106 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 13107 if (zone->db == NULL) { 13108 zone_attachdb(zone, stub->db); 13109 } 13110 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, NULL, 13111 &refresh, &retry, &expire, NULL, NULL); 13112 if (result == ISC_R_SUCCESS && soacount > 0U) { 13113 zone->refresh = RANGE(refresh, zone->minrefresh, 13114 zone->maxrefresh); 13115 zone->retry = RANGE(retry, zone->minretry, zone->maxretry); 13116 zone->expire = RANGE(expire, zone->refresh + zone->retry, 13117 DNS_MAX_EXPIRE); 13118 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 13119 } 13120 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 13121 dns_db_detach(&stub->db); 13122 13123 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 13124 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 13125 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 13126 isc_interval_set(&i, zone->expire, 0); 13127 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); 13128 13129 if (zone->masterfile != NULL) { 13130 zone_needdump(zone, 0); 13131 } 13132 13133 zone_settimer(zone, &now); 13134 } 13135 13136 /* 13137 * Process answers for A and AAAA queries when 13138 * resolving nameserver addresses for which glue 13139 * was missing in a previous answer for a NS query. 13140 */ 13141 static void 13142 stub_glue_response(void *arg) { 13143 dns_request_t *request = (dns_request_t *)arg; 13144 struct stub_glue_request *sgr = dns_request_getarg(request); 13145 struct stub_cb_args *cb_args = sgr->args; 13146 dns_stub_t *stub = cb_args->stub; 13147 dns_message_t *msg = NULL; 13148 dns_zone_t *zone = NULL; 13149 char primary[ISC_SOCKADDR_FORMATSIZE]; 13150 char source[ISC_SOCKADDR_FORMATSIZE]; 13151 uint32_t addr_count, cnamecnt; 13152 isc_result_t result; 13153 isc_sockaddr_t curraddr; 13154 isc_time_t now; 13155 dns_rdataset_t *addr_rdataset = NULL; 13156 dns_dbnode_t *node = NULL; 13157 13158 INSIST(DNS_STUB_VALID(stub)); 13159 13160 zone = stub->zone; 13161 13162 ENTER; 13163 13164 now = isc_time_now(); 13165 13166 LOCK_ZONE(zone); 13167 13168 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 13169 zone_debuglog(zone, __func__, 1, "exiting"); 13170 goto cleanup; 13171 } 13172 13173 curraddr = dns_remote_curraddr(&zone->primaries); 13174 isc_sockaddr_format(&curraddr, primary, sizeof(primary)); 13175 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 13176 13177 if (dns_request_getresult(request) != ISC_R_SUCCESS) { 13178 dns_zonemgr_unreachableadd(zone->zmgr, &curraddr, 13179 &zone->sourceaddr, &now); 13180 dns_zone_log(zone, ISC_LOG_INFO, 13181 "could not refresh stub from primary %s" 13182 " (source %s): %s", 13183 primary, source, 13184 isc_result_totext(dns_request_getresult(request))); 13185 goto cleanup; 13186 } 13187 13188 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, 13189 &msg); 13190 result = dns_request_getresponse(request, msg, 0); 13191 if (result != ISC_R_SUCCESS) { 13192 dns_zone_log(zone, ISC_LOG_INFO, 13193 "refreshing stub: unable to parse response (%s)", 13194 isc_result_totext(result)); 13195 goto cleanup; 13196 } 13197 13198 /* 13199 * Unexpected opcode. 13200 */ 13201 if (msg->opcode != dns_opcode_query) { 13202 char opcode[128]; 13203 isc_buffer_t rb; 13204 13205 isc_buffer_init(&rb, opcode, sizeof(opcode)); 13206 (void)dns_opcode_totext(msg->opcode, &rb); 13207 13208 dns_zone_log(zone, ISC_LOG_INFO, 13209 "refreshing stub: " 13210 "unexpected opcode (%.*s) from %s (source %s)", 13211 (int)rb.used, opcode, primary, source); 13212 goto cleanup; 13213 } 13214 13215 /* 13216 * Unexpected rcode. 13217 */ 13218 if (msg->rcode != dns_rcode_noerror) { 13219 char rcode[128]; 13220 isc_buffer_t rb; 13221 13222 isc_buffer_init(&rb, rcode, sizeof(rcode)); 13223 (void)dns_rcode_totext(msg->rcode, &rb); 13224 13225 dns_zone_log(zone, ISC_LOG_INFO, 13226 "refreshing stub: " 13227 "unexpected rcode (%.*s) from %s (source %s)", 13228 (int)rb.used, rcode, primary, source); 13229 goto cleanup; 13230 } 13231 13232 /* 13233 * We need complete messages. 13234 */ 13235 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 13236 if (dns_request_usedtcp(request)) { 13237 dns_zone_log(zone, ISC_LOG_INFO, 13238 "refreshing stub: truncated TCP " 13239 "response from primary %s (source %s)", 13240 primary, source); 13241 } 13242 goto cleanup; 13243 } 13244 13245 /* 13246 * If non-auth log. 13247 */ 13248 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 13249 dns_zone_log(zone, ISC_LOG_INFO, 13250 "refreshing stub: " 13251 "non-authoritative answer from " 13252 "primary %s (source %s)", 13253 primary, source); 13254 goto cleanup; 13255 } 13256 13257 /* 13258 * Sanity checks. 13259 */ 13260 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 13261 addr_count = message_count(msg, DNS_SECTION_ANSWER, 13262 sgr->ipv4 ? dns_rdatatype_a 13263 : dns_rdatatype_aaaa); 13264 13265 if (cnamecnt != 0) { 13266 dns_zone_log(zone, ISC_LOG_INFO, 13267 "refreshing stub: unexpected CNAME response " 13268 "from primary %s (source %s)", 13269 primary, source); 13270 goto cleanup; 13271 } 13272 13273 if (addr_count == 0) { 13274 dns_zone_log(zone, ISC_LOG_INFO, 13275 "refreshing stub: no %s records in response " 13276 "from primary %s (source %s)", 13277 sgr->ipv4 ? "A" : "AAAA", primary, source); 13278 goto cleanup; 13279 } 13280 /* 13281 * Extract A or AAAA RRset from message. 13282 */ 13283 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &sgr->name, 13284 sgr->ipv4 ? dns_rdatatype_a 13285 : dns_rdatatype_aaaa, 13286 dns_rdatatype_none, NULL, &addr_rdataset); 13287 if (result != ISC_R_SUCCESS) { 13288 if (result != DNS_R_NXDOMAIN && result != DNS_R_NXRRSET) { 13289 char namebuf[DNS_NAME_FORMATSIZE]; 13290 dns_name_format(&sgr->name, namebuf, sizeof(namebuf)); 13291 dns_zone_log( 13292 zone, ISC_LOG_INFO, 13293 "refreshing stub: dns_message_findname(%s/%s) " 13294 "failed (%s)", 13295 namebuf, sgr->ipv4 ? "A" : "AAAA", 13296 isc_result_totext(result)); 13297 } 13298 goto cleanup; 13299 } 13300 13301 result = dns_db_findnode(stub->db, &sgr->name, true, &node); 13302 if (result != ISC_R_SUCCESS) { 13303 dns_zone_log(zone, ISC_LOG_INFO, 13304 "refreshing stub: " 13305 "dns_db_findnode() failed: %s", 13306 isc_result_totext(result)); 13307 goto cleanup; 13308 } 13309 13310 result = dns_db_addrdataset(stub->db, node, stub->version, 0, 13311 addr_rdataset, 0, NULL); 13312 if (result != ISC_R_SUCCESS) { 13313 dns_zone_log(zone, ISC_LOG_INFO, 13314 "refreshing stub: " 13315 "dns_db_addrdataset() failed: %s", 13316 isc_result_totext(result)); 13317 } 13318 dns_db_detachnode(stub->db, &node); 13319 13320 cleanup: 13321 if (msg != NULL) { 13322 dns_message_detach(&msg); 13323 } 13324 13325 dns_name_free(&sgr->name, zone->mctx); 13326 dns_request_destroy(&sgr->request); 13327 isc_mem_put(zone->mctx, sgr, sizeof(*sgr)); 13328 13329 /* If last request, release all related resources */ 13330 if (atomic_fetch_sub_release(&stub->pending_requests, 1) == 1) { 13331 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13332 stub_finish_zone_update(stub, now); 13333 UNLOCK_ZONE(zone); 13334 stub->magic = 0; 13335 dns_zone_idetach(&stub->zone); 13336 INSIST(stub->db == NULL); 13337 INSIST(stub->version == NULL); 13338 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 13339 } else { 13340 UNLOCK_ZONE(zone); 13341 } 13342 } 13343 13344 /* 13345 * Create and send an A or AAAA query to the primary 13346 * server of the stub zone given. 13347 */ 13348 static isc_result_t 13349 stub_request_nameserver_address(struct stub_cb_args *args, bool ipv4, 13350 const dns_name_t *name) { 13351 dns_message_t *message = NULL; 13352 dns_zone_t *zone; 13353 isc_result_t result; 13354 struct stub_glue_request *sgr; 13355 isc_sockaddr_t curraddr; 13356 13357 zone = args->stub->zone; 13358 sgr = isc_mem_get(zone->mctx, sizeof(*sgr)); 13359 *sgr = (struct stub_glue_request){ 13360 .args = args, 13361 .name = (dns_name_t)DNS_NAME_INITEMPTY, 13362 .ipv4 = ipv4, 13363 }; 13364 13365 dns_name_dup(name, zone->mctx, &sgr->name); 13366 13367 create_query(zone, ipv4 ? dns_rdatatype_a : dns_rdatatype_aaaa, 13368 &sgr->name, &message); 13369 13370 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 13371 result = add_opt(message, args->udpsize, args->reqnsid, false); 13372 if (result != ISC_R_SUCCESS) { 13373 zone_debuglog(zone, __func__, 1, 13374 "unable to add opt record: %s", 13375 isc_result_totext(result)); 13376 goto fail; 13377 } 13378 } 13379 13380 atomic_fetch_add_release(&args->stub->pending_requests, 1); 13381 13382 curraddr = dns_remote_curraddr(&zone->primaries); 13383 result = dns_request_create( 13384 zone->view->requestmgr, message, &zone->sourceaddr, &curraddr, 13385 NULL, NULL, DNS_REQUESTOPT_TCP, args->tsig_key, 13386 args->timeout * 3, args->timeout, 2, zone->loop, 13387 stub_glue_response, sgr, &sgr->request); 13388 13389 if (result != ISC_R_SUCCESS) { 13390 uint_fast32_t pr; 13391 pr = atomic_fetch_sub_release(&args->stub->pending_requests, 1); 13392 INSIST(pr > 1); 13393 zone_debuglog(zone, __func__, 1, 13394 "dns_request_create() failed: %s", 13395 isc_result_totext(result)); 13396 goto fail; 13397 } 13398 13399 dns_message_detach(&message); 13400 13401 return ISC_R_SUCCESS; 13402 13403 fail: 13404 dns_name_free(&sgr->name, zone->mctx); 13405 isc_mem_put(zone->mctx, sgr, sizeof(*sgr)); 13406 13407 if (message != NULL) { 13408 dns_message_detach(&message); 13409 } 13410 13411 return result; 13412 } 13413 13414 static isc_result_t 13415 save_nsrrset(dns_message_t *message, dns_name_t *name, 13416 struct stub_cb_args *cb_args, dns_db_t *db, 13417 dns_dbversion_t *version) { 13418 dns_rdataset_t *nsrdataset = NULL; 13419 dns_rdataset_t *rdataset = NULL; 13420 dns_dbnode_t *node = NULL; 13421 dns_rdata_ns_t ns; 13422 isc_result_t result; 13423 dns_rdata_t rdata = DNS_RDATA_INIT; 13424 bool has_glue = false; 13425 dns_name_t *ns_name; 13426 /* 13427 * List of NS entries in answer, keep names that will be used 13428 * to resolve missing A/AAAA glue for each entry. 13429 */ 13430 dns_namelist_t ns_list; 13431 ISC_LIST_INIT(ns_list); 13432 13433 /* 13434 * Extract NS RRset from message. 13435 */ 13436 result = dns_message_findname(message, DNS_SECTION_ANSWER, name, 13437 dns_rdatatype_ns, dns_rdatatype_none, 13438 NULL, &nsrdataset); 13439 if (result != ISC_R_SUCCESS) { 13440 goto done; 13441 } 13442 13443 /* 13444 * Add NS rdataset. 13445 */ 13446 result = dns_db_findnode(db, name, true, &node); 13447 if (result != ISC_R_SUCCESS) { 13448 goto done; 13449 } 13450 result = dns_db_addrdataset(db, node, version, 0, nsrdataset, 0, NULL); 13451 dns_db_detachnode(db, &node); 13452 if (result != ISC_R_SUCCESS) { 13453 goto done; 13454 } 13455 /* 13456 * Add glue rdatasets. 13457 */ 13458 for (result = dns_rdataset_first(nsrdataset); result == ISC_R_SUCCESS; 13459 result = dns_rdataset_next(nsrdataset)) 13460 { 13461 dns_rdataset_current(nsrdataset, &rdata); 13462 result = dns_rdata_tostruct(&rdata, &ns, NULL); 13463 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13464 dns_rdata_reset(&rdata); 13465 13466 if (!dns_name_issubdomain(&ns.name, name)) { 13467 continue; 13468 } 13469 rdataset = NULL; 13470 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL, 13471 &ns.name, dns_rdatatype_aaaa, 13472 dns_rdatatype_none, NULL, 13473 &rdataset); 13474 if (result == ISC_R_SUCCESS) { 13475 has_glue = true; 13476 result = dns_db_findnode(db, &ns.name, true, &node); 13477 if (result != ISC_R_SUCCESS) { 13478 goto done; 13479 } 13480 result = dns_db_addrdataset(db, node, version, 0, 13481 rdataset, 0, NULL); 13482 dns_db_detachnode(db, &node); 13483 if (result != ISC_R_SUCCESS) { 13484 goto done; 13485 } 13486 } 13487 13488 rdataset = NULL; 13489 result = dns_message_findname( 13490 message, DNS_SECTION_ADDITIONAL, &ns.name, 13491 dns_rdatatype_a, dns_rdatatype_none, NULL, &rdataset); 13492 if (result == ISC_R_SUCCESS) { 13493 has_glue = true; 13494 result = dns_db_findnode(db, &ns.name, true, &node); 13495 if (result != ISC_R_SUCCESS) { 13496 goto done; 13497 } 13498 result = dns_db_addrdataset(db, node, version, 0, 13499 rdataset, 0, NULL); 13500 dns_db_detachnode(db, &node); 13501 if (result != ISC_R_SUCCESS) { 13502 goto done; 13503 } 13504 } 13505 13506 /* 13507 * If no glue is found so far, we add the name to the list to 13508 * resolve the A/AAAA glue later. If any glue is found in any 13509 * iteration step, this list will be discarded and only the glue 13510 * provided in this message will be used. 13511 */ 13512 if (!has_glue && dns_name_issubdomain(&ns.name, name)) { 13513 dns_name_t *tmp_name; 13514 tmp_name = isc_mem_get(cb_args->stub->mctx, 13515 sizeof(*tmp_name)); 13516 dns_name_init(tmp_name, NULL); 13517 dns_name_dup(&ns.name, cb_args->stub->mctx, tmp_name); 13518 ISC_LIST_APPEND(ns_list, tmp_name, link); 13519 } 13520 } 13521 13522 if (result != ISC_R_NOMORE) { 13523 goto done; 13524 } 13525 13526 /* 13527 * If no glue records were found, we attempt to resolve A/AAAA 13528 * for each NS entry found in the answer. 13529 */ 13530 if (!has_glue) { 13531 for (ns_name = ISC_LIST_HEAD(ns_list); ns_name != NULL; 13532 ns_name = ISC_LIST_NEXT(ns_name, link)) 13533 { 13534 /* 13535 * Resolve NS IPv4 address/A. 13536 */ 13537 result = stub_request_nameserver_address(cb_args, true, 13538 ns_name); 13539 if (result != ISC_R_SUCCESS) { 13540 goto done; 13541 } 13542 /* 13543 * Resolve NS IPv6 address/AAAA. 13544 */ 13545 result = stub_request_nameserver_address(cb_args, false, 13546 ns_name); 13547 if (result != ISC_R_SUCCESS) { 13548 goto done; 13549 } 13550 } 13551 } 13552 13553 result = ISC_R_SUCCESS; 13554 13555 done: 13556 while ((ns_name = ISC_LIST_HEAD(ns_list)) != NULL) { 13557 ISC_LIST_UNLINK(ns_list, ns_name, link); 13558 dns_name_free(ns_name, cb_args->stub->mctx); 13559 isc_mem_put(cb_args->stub->mctx, ns_name, sizeof(*ns_name)); 13560 } 13561 return result; 13562 } 13563 13564 static void 13565 stub_callback(void *arg) { 13566 dns_request_t *request = (dns_request_t *)arg; 13567 struct stub_cb_args *cb_args = dns_request_getarg(request); 13568 dns_stub_t *stub = cb_args->stub; 13569 dns_message_t *msg = NULL; 13570 dns_zone_t *zone = NULL; 13571 char primary[ISC_SOCKADDR_FORMATSIZE]; 13572 char source[ISC_SOCKADDR_FORMATSIZE]; 13573 uint32_t nscnt, cnamecnt; 13574 isc_result_t result; 13575 isc_sockaddr_t curraddr; 13576 isc_time_t now; 13577 bool exiting = false; 13578 13579 INSIST(DNS_STUB_VALID(stub)); 13580 13581 zone = stub->zone; 13582 13583 ENTER; 13584 13585 now = isc_time_now(); 13586 13587 LOCK_ZONE(zone); 13588 13589 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 13590 goto exiting; 13591 } 13592 13593 curraddr = dns_remote_curraddr(&zone->primaries); 13594 isc_sockaddr_format(&curraddr, primary, sizeof(primary)); 13595 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 13596 13597 result = dns_request_getresult(request); 13598 switch (result) { 13599 case ISC_R_SUCCESS: 13600 break; 13601 case ISC_R_SHUTTINGDOWN: 13602 goto exiting; 13603 case ISC_R_TIMEDOUT: 13604 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 13605 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 13606 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13607 "refreshing stub: timeout retrying " 13608 "without EDNS primary %s (source %s)", 13609 primary, source); 13610 goto same_primary; 13611 } 13612 FALLTHROUGH; 13613 default: 13614 dns_zonemgr_unreachableadd(zone->zmgr, &curraddr, 13615 &zone->sourceaddr, &now); 13616 dns_zone_log(zone, ISC_LOG_INFO, 13617 "could not refresh stub from primary " 13618 "%s (source %s): %s", 13619 primary, source, isc_result_totext(result)); 13620 goto next_primary; 13621 } 13622 13623 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, 13624 &msg); 13625 13626 result = dns_request_getresponse(request, msg, 0); 13627 if (result != ISC_R_SUCCESS) { 13628 goto next_primary; 13629 } 13630 13631 /* 13632 * Unexpected opcode. 13633 */ 13634 if (msg->opcode != dns_opcode_query) { 13635 char opcode[128]; 13636 isc_buffer_t rb; 13637 13638 isc_buffer_init(&rb, opcode, sizeof(opcode)); 13639 (void)dns_opcode_totext(msg->opcode, &rb); 13640 13641 dns_zone_log(zone, ISC_LOG_INFO, 13642 "refreshing stub: " 13643 "unexpected opcode (%.*s) from %s (source %s)", 13644 (int)rb.used, opcode, primary, source); 13645 goto next_primary; 13646 } 13647 13648 /* 13649 * Unexpected rcode. 13650 */ 13651 if (msg->rcode != dns_rcode_noerror) { 13652 char rcode[128]; 13653 isc_buffer_t rb; 13654 13655 isc_buffer_init(&rb, rcode, sizeof(rcode)); 13656 (void)dns_rcode_totext(msg->rcode, &rb); 13657 13658 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 13659 (msg->rcode == dns_rcode_servfail || 13660 msg->rcode == dns_rcode_notimp || 13661 (msg->rcode == dns_rcode_formerr && msg->opt == NULL))) 13662 { 13663 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13664 "refreshing stub: rcode (%.*s) retrying " 13665 "without EDNS primary %s (source %s)", 13666 (int)rb.used, rcode, primary, source); 13667 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 13668 goto same_primary; 13669 } 13670 13671 dns_zone_log(zone, ISC_LOG_INFO, 13672 "refreshing stub: " 13673 "unexpected rcode (%.*s) from %s (source %s)", 13674 (int)rb.used, rcode, primary, source); 13675 goto next_primary; 13676 } 13677 13678 /* 13679 * We need complete messages. 13680 */ 13681 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 13682 if (dns_request_usedtcp(request)) { 13683 dns_zone_log(zone, ISC_LOG_INFO, 13684 "refreshing stub: truncated TCP " 13685 "response from primary %s (source %s)", 13686 primary, source); 13687 goto next_primary; 13688 } 13689 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 13690 goto same_primary; 13691 } 13692 13693 /* 13694 * If non-auth log and next primary. 13695 */ 13696 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 13697 dns_zone_log(zone, ISC_LOG_INFO, 13698 "refreshing stub: " 13699 "non-authoritative answer from " 13700 "primary %s (source %s)", 13701 primary, source); 13702 goto next_primary; 13703 } 13704 13705 /* 13706 * Sanity checks. 13707 */ 13708 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 13709 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns); 13710 13711 if (cnamecnt != 0) { 13712 dns_zone_log(zone, ISC_LOG_INFO, 13713 "refreshing stub: unexpected CNAME response " 13714 "from primary %s (source %s)", 13715 primary, source); 13716 goto next_primary; 13717 } 13718 13719 if (nscnt == 0) { 13720 dns_zone_log(zone, ISC_LOG_INFO, 13721 "refreshing stub: no NS records in response " 13722 "from primary %s (source %s)", 13723 primary, source); 13724 goto next_primary; 13725 } 13726 13727 atomic_fetch_add(&stub->pending_requests, 1); 13728 13729 /* 13730 * Save answer. 13731 */ 13732 result = save_nsrrset(msg, &zone->origin, cb_args, stub->db, 13733 stub->version); 13734 if (result != ISC_R_SUCCESS) { 13735 dns_zone_log(zone, ISC_LOG_INFO, 13736 "refreshing stub: unable to save NS records " 13737 "from primary %s (source %s)", 13738 primary, source); 13739 goto next_primary; 13740 } 13741 13742 dns_message_detach(&msg); 13743 dns_request_destroy(&zone->request); 13744 13745 /* 13746 * Check to see if there are no outstanding requests and 13747 * finish off if that is so. 13748 */ 13749 if (atomic_fetch_sub(&stub->pending_requests, 1) == 1) { 13750 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13751 stub_finish_zone_update(stub, now); 13752 goto free_stub; 13753 } 13754 13755 UNLOCK_ZONE(zone); 13756 return; 13757 13758 exiting: 13759 zone_debuglog(zone, __func__, 1, "exiting"); 13760 exiting = true; 13761 13762 next_primary: 13763 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13764 if (stub->version != NULL) { 13765 dns_db_closeversion(stub->db, &stub->version, false); 13766 } 13767 if (stub->db != NULL) { 13768 dns_db_detach(&stub->db); 13769 } 13770 if (msg != NULL) { 13771 dns_message_detach(&msg); 13772 } 13773 dns_request_destroy(&zone->request); 13774 /* 13775 * Skip to next failed / untried primary. 13776 */ 13777 dns_remote_next(&zone->primaries, true); 13778 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 13779 if (exiting || dns_remote_done(&zone->primaries)) { 13780 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 13781 zone_settimer(zone, &now); 13782 goto free_stub; 13783 } 13784 queue_soa_query(zone); 13785 goto free_stub; 13786 13787 same_primary: 13788 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13789 if (msg != NULL) { 13790 dns_message_detach(&msg); 13791 } 13792 dns_request_destroy(&zone->request); 13793 ns_query(zone, NULL, stub); 13794 UNLOCK_ZONE(zone); 13795 return; 13796 13797 free_stub: 13798 UNLOCK_ZONE(zone); 13799 stub->magic = 0; 13800 dns_zone_idetach(&stub->zone); 13801 INSIST(stub->db == NULL); 13802 INSIST(stub->version == NULL); 13803 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 13804 } 13805 13806 /* 13807 * Get the EDNS EXPIRE option from the response and if it exists trim 13808 * expire to be not more than it. 13809 */ 13810 static void 13811 get_edns_expire(dns_zone_t *zone, dns_message_t *message, uint32_t *expirep) { 13812 isc_result_t result; 13813 uint32_t expire; 13814 dns_rdata_t rdata = DNS_RDATA_INIT; 13815 isc_buffer_t optbuf; 13816 uint16_t optcode; 13817 uint16_t optlen; 13818 13819 REQUIRE(expirep != NULL); 13820 REQUIRE(message != NULL); 13821 13822 if (message->opt == NULL) { 13823 return; 13824 } 13825 13826 result = dns_rdataset_first(message->opt); 13827 if (result == ISC_R_SUCCESS) { 13828 dns_rdataset_current(message->opt, &rdata); 13829 isc_buffer_init(&optbuf, rdata.data, rdata.length); 13830 isc_buffer_add(&optbuf, rdata.length); 13831 while (isc_buffer_remaininglength(&optbuf) >= 4) { 13832 optcode = isc_buffer_getuint16(&optbuf); 13833 optlen = isc_buffer_getuint16(&optbuf); 13834 /* 13835 * A EDNS EXPIRE response has a length of 4. 13836 */ 13837 if (optcode != DNS_OPT_EXPIRE || optlen != 4) { 13838 isc_buffer_forward(&optbuf, optlen); 13839 continue; 13840 } 13841 expire = isc_buffer_getuint32(&optbuf); 13842 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13843 "got EDNS EXPIRE of %u", expire); 13844 /* 13845 * Trim *expirep? 13846 */ 13847 if (expire < *expirep) { 13848 *expirep = expire; 13849 } 13850 break; 13851 } 13852 } 13853 } 13854 13855 /* 13856 * Set the file modification time zone->expire seconds before expiretime. 13857 */ 13858 static void 13859 setmodtime(dns_zone_t *zone, isc_time_t *expiretime) { 13860 isc_result_t result; 13861 isc_time_t when; 13862 isc_interval_t i; 13863 13864 isc_interval_set(&i, zone->expire, 0); 13865 result = isc_time_subtract(expiretime, &i, &when); 13866 if (result != ISC_R_SUCCESS) { 13867 return; 13868 } 13869 13870 result = ISC_R_FAILURE; 13871 if (zone->journal != NULL) { 13872 result = isc_file_settime(zone->journal, &when); 13873 } 13874 if (result == ISC_R_SUCCESS && 13875 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 13876 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 13877 { 13878 result = isc_file_settime(zone->masterfile, &when); 13879 } else if (result != ISC_R_SUCCESS) { 13880 result = isc_file_settime(zone->masterfile, &when); 13881 } 13882 13883 /* 13884 * Someone removed the file from underneath us! 13885 */ 13886 if (result == ISC_R_FILENOTFOUND) { 13887 zone_needdump(zone, DNS_DUMP_DELAY); 13888 } else if (result != ISC_R_SUCCESS) { 13889 dns_zone_log(zone, ISC_LOG_ERROR, 13890 "refresh: could not set " 13891 "file modification time of '%s': %s", 13892 zone->masterfile, isc_result_totext(result)); 13893 } 13894 } 13895 13896 /* 13897 * An SOA query has finished (successfully or not). 13898 */ 13899 static void 13900 refresh_callback(void *arg) { 13901 dns_request_t *request = (dns_request_t *)arg; 13902 dns_zone_t *zone = dns_request_getarg(request); 13903 dns_message_t *msg = NULL; 13904 uint32_t soacnt, cnamecnt, soacount, nscount; 13905 isc_time_t now; 13906 char primary[ISC_SOCKADDR_FORMATSIZE]; 13907 char source[ISC_SOCKADDR_FORMATSIZE]; 13908 dns_rdataset_t *rdataset = NULL; 13909 dns_rdata_t rdata = DNS_RDATA_INIT; 13910 dns_rdata_soa_t soa; 13911 isc_result_t result; 13912 isc_sockaddr_t curraddr; 13913 uint32_t serial, oldserial = 0; 13914 bool do_queue_xfrin = false; 13915 13916 INSIST(DNS_ZONE_VALID(zone)); 13917 13918 ENTER; 13919 13920 now = isc_time_now(); 13921 13922 LOCK_ZONE(zone); 13923 13924 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 13925 goto exiting; 13926 } 13927 13928 /* 13929 * If timeout, log and try the next primary 13930 */ 13931 curraddr = dns_remote_curraddr(&zone->primaries); 13932 isc_sockaddr_format(&curraddr, primary, sizeof(primary)); 13933 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 13934 13935 switch (dns_request_getresult(request)) { 13936 case ISC_R_SUCCESS: 13937 break; 13938 case ISC_R_SHUTTINGDOWN: 13939 goto exiting; 13940 case ISC_R_TIMEDOUT: 13941 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 13942 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 13943 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 13944 ISC_LOG_DEBUG(1), 13945 "refresh: timeout retrying without EDNS " 13946 "primary %s (source %s)", 13947 primary, source); 13948 goto same_primary; 13949 } else if (!dns_request_usedtcp(request)) { 13950 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 13951 ISC_LOG_INFO, 13952 "refresh: retry limit for " 13953 "primary %s exceeded (source %s)", 13954 primary, source); 13955 /* Try with secondary with TCP. */ 13956 if ((zone->type == dns_zone_secondary || 13957 zone->type == dns_zone_mirror || 13958 zone->type == dns_zone_redirect) && 13959 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) 13960 { 13961 if (!dns_zonemgr_unreachable( 13962 zone->zmgr, &curraddr, 13963 &zone->sourceaddr, &now)) 13964 { 13965 DNS_ZONE_SETFLAG( 13966 zone, 13967 DNS_ZONEFLG_SOABEFOREAXFR); 13968 goto tcp_transfer; 13969 } 13970 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 13971 ISC_LOG_DEBUG(1), 13972 "refresh: skipped tcp fallback " 13973 "as primary %s (source %s) is " 13974 "unreachable (cached)", 13975 primary, source); 13976 } 13977 goto next_primary; 13978 } 13979 FALLTHROUGH; 13980 default: 13981 result = dns_request_getresult(request); 13982 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 13983 "refresh: failure trying primary " 13984 "%s (source %s): %s", 13985 primary, source, isc_result_totext(result)); 13986 goto next_primary; 13987 } 13988 13989 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, 13990 &msg); 13991 result = dns_request_getresponse(request, msg, 0); 13992 if (result != ISC_R_SUCCESS) { 13993 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 13994 "refresh: failure trying primary " 13995 "%s (source %s): %s", 13996 primary, source, isc_result_totext(result)); 13997 goto next_primary; 13998 } 13999 14000 /* 14001 * Unexpected opcode. 14002 */ 14003 if (msg->opcode != dns_opcode_query) { 14004 char opcode[128]; 14005 isc_buffer_t rb; 14006 14007 isc_buffer_init(&rb, opcode, sizeof(opcode)); 14008 (void)dns_opcode_totext(msg->opcode, &rb); 14009 14010 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14011 "refresh: " 14012 "unexpected opcode (%.*s) from %s (source %s)", 14013 (int)rb.used, opcode, primary, source); 14014 goto next_primary; 14015 } 14016 14017 /* 14018 * Unexpected rcode. 14019 */ 14020 if (msg->rcode != dns_rcode_noerror) { 14021 char rcode[128]; 14022 isc_buffer_t rb; 14023 14024 isc_buffer_init(&rb, rcode, sizeof(rcode)); 14025 (void)dns_rcode_totext(msg->rcode, &rb); 14026 14027 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 14028 (msg->rcode == dns_rcode_servfail || 14029 msg->rcode == dns_rcode_notimp || 14030 (msg->rcode == dns_rcode_formerr && msg->opt == NULL))) 14031 { 14032 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14033 ISC_LOG_DEBUG(1), 14034 "refresh: rcode (%.*s) retrying without " 14035 "EDNS primary %s (source %s)", 14036 (int)rb.used, rcode, primary, source); 14037 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14038 goto same_primary; 14039 } 14040 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 14041 msg->rcode == dns_rcode_badvers) 14042 { 14043 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14044 ISC_LOG_DEBUG(1), 14045 "refresh: rcode (%.*s) retrying without " 14046 "EDNS EXPIRE OPTION primary %s " 14047 "(source %s)", 14048 (int)rb.used, rcode, primary, source); 14049 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14050 goto same_primary; 14051 } 14052 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14053 "refresh: unexpected rcode (%.*s) from " 14054 "primary %s (source %s)", 14055 (int)rb.used, rcode, primary, source); 14056 /* 14057 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't. 14058 */ 14059 if (msg->rcode == dns_rcode_refused && 14060 (zone->type == dns_zone_secondary || 14061 zone->type == dns_zone_mirror || 14062 zone->type == dns_zone_redirect)) 14063 { 14064 goto tcp_transfer; 14065 } 14066 goto next_primary; 14067 } 14068 14069 /* 14070 * If truncated punt to zone transfer which will query again. 14071 */ 14072 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 14073 if (zone->type == dns_zone_secondary || 14074 zone->type == dns_zone_mirror || 14075 zone->type == dns_zone_redirect) 14076 { 14077 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14078 ISC_LOG_INFO, 14079 "refresh: truncated UDP answer, " 14080 "initiating TCP zone xfer " 14081 "for primary %s (source %s)", 14082 primary, source); 14083 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 14084 goto tcp_transfer; 14085 } else { 14086 INSIST(zone->type == dns_zone_stub); 14087 if (dns_request_usedtcp(request)) { 14088 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14089 ISC_LOG_INFO, 14090 "refresh: truncated TCP response " 14091 "from primary %s (source %s)", 14092 primary, source); 14093 goto next_primary; 14094 } 14095 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 14096 goto same_primary; 14097 } 14098 } 14099 14100 /* 14101 * If non-auth, log and try the next primary 14102 */ 14103 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 14104 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14105 "refresh: non-authoritative answer from " 14106 "primary %s (source %s)", 14107 primary, source); 14108 goto next_primary; 14109 } 14110 14111 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 14112 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa); 14113 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns); 14114 soacount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_soa); 14115 14116 /* 14117 * There should not be a CNAME record at top of zone. 14118 */ 14119 if (cnamecnt != 0) { 14120 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14121 "refresh: CNAME at top of zone " 14122 "in primary %s (source %s)", 14123 primary, source); 14124 goto next_primary; 14125 } 14126 14127 /* 14128 * If referral, log and try the next primary; 14129 */ 14130 if (soacnt == 0 && soacount == 0 && nscount != 0) { 14131 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14132 "refresh: referral response " 14133 "from primary %s (source %s)", 14134 primary, source); 14135 goto next_primary; 14136 } 14137 14138 /* 14139 * If nodata, log and try the next primary; 14140 */ 14141 if (soacnt == 0 && (nscount == 0 || soacount != 0)) { 14142 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14143 "refresh: NODATA response " 14144 "from primary %s (source %s)", 14145 primary, source); 14146 goto next_primary; 14147 } 14148 14149 /* 14150 * Only one soa at top of zone. 14151 */ 14152 if (soacnt != 1) { 14153 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14154 "refresh: answer SOA count (%d) != 1 " 14155 "from primary %s (source %s)", 14156 soacnt, primary, source); 14157 goto next_primary; 14158 } 14159 14160 /* 14161 * Extract serial 14162 */ 14163 rdataset = NULL; 14164 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin, 14165 dns_rdatatype_soa, dns_rdatatype_none, 14166 NULL, &rdataset); 14167 if (result != ISC_R_SUCCESS) { 14168 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14169 "refresh: unable to get SOA record " 14170 "from primary %s (source %s)", 14171 primary, source); 14172 goto next_primary; 14173 } 14174 14175 result = dns_rdataset_first(rdataset); 14176 if (result != ISC_R_SUCCESS) { 14177 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14178 "refresh: dns_rdataset_first() failed"); 14179 goto next_primary; 14180 } 14181 14182 dns_rdataset_current(rdataset, &rdata); 14183 result = dns_rdata_tostruct(&rdata, &soa, NULL); 14184 RUNTIME_CHECK(result == ISC_R_SUCCESS); 14185 14186 serial = soa.serial; 14187 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 14188 unsigned int dbsoacount; 14189 result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount, 14190 NULL, &oldserial, NULL, NULL, NULL, 14191 NULL, NULL); 14192 RUNTIME_CHECK(result == ISC_R_SUCCESS); 14193 RUNTIME_CHECK(dbsoacount > 0U); 14194 zone_debuglogc(zone, DNS_LOGCATEGORY_XFER_IN, __func__, 1, 14195 "serial: new %u, old %u", serial, oldserial); 14196 } else { 14197 zone_debuglogc(zone, DNS_LOGCATEGORY_XFER_IN, __func__, 1, 14198 "serial: new %u, old not loaded", serial); 14199 } 14200 14201 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) || 14202 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) || 14203 isc_serial_gt(serial, oldserial)) 14204 { 14205 if (dns_zonemgr_unreachable(zone->zmgr, &curraddr, 14206 &zone->sourceaddr, &now)) 14207 { 14208 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14209 ISC_LOG_INFO, 14210 "refresh: skipping %s as primary %s " 14211 "(source %s) is unreachable (cached)", 14212 (zone->type == dns_zone_secondary || 14213 zone->type == dns_zone_mirror || 14214 zone->type == dns_zone_redirect) 14215 ? "zone transfer" 14216 : "NS query", 14217 primary, source); 14218 goto next_primary; 14219 } 14220 tcp_transfer: 14221 dns_request_destroy(&zone->request); 14222 if (zone->type == dns_zone_secondary || 14223 zone->type == dns_zone_mirror || 14224 zone->type == dns_zone_redirect) 14225 { 14226 do_queue_xfrin = true; 14227 } else { 14228 INSIST(zone->type == dns_zone_stub); 14229 ns_query(zone, rdataset, NULL); 14230 } 14231 if (msg != NULL) { 14232 dns_message_detach(&msg); 14233 } 14234 } else if (isc_serial_eq(soa.serial, oldserial)) { 14235 isc_time_t expiretime; 14236 uint32_t expire; 14237 14238 /* 14239 * Compute the new expire time based on this response. 14240 */ 14241 expire = zone->expire; 14242 get_edns_expire(zone, msg, &expire); 14243 DNS_ZONE_TIME_ADD(&now, expire, &expiretime); 14244 14245 /* 14246 * Has the expire time improved? 14247 */ 14248 if (isc_time_compare(&expiretime, &zone->expiretime) > 0) { 14249 zone->expiretime = expiretime; 14250 if (zone->masterfile != NULL) { 14251 setmodtime(zone, &expiretime); 14252 } 14253 } 14254 14255 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 14256 dns_remote_mark(&zone->primaries, true); 14257 goto next_primary; 14258 } else { 14259 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER)) { 14260 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14261 ISC_LOG_INFO, 14262 "serial number (%u) " 14263 "received from primary %s < ours (%u)", 14264 soa.serial, primary, oldserial); 14265 } else { 14266 zone_debuglogc(zone, DNS_LOGCATEGORY_XFER_IN, __func__, 14267 1, "ahead"); 14268 } 14269 dns_remote_mark(&zone->primaries, true); 14270 goto next_primary; 14271 } 14272 if (msg != NULL) { 14273 dns_message_detach(&msg); 14274 } 14275 goto detach; 14276 14277 next_primary: 14278 if (msg != NULL) { 14279 dns_message_detach(&msg); 14280 } 14281 dns_request_destroy(&zone->request); 14282 /* 14283 * Skip to next failed / untried primary. 14284 */ 14285 dns_remote_next(&zone->primaries, true); 14286 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 14287 if (dns_remote_done(&zone->primaries)) { 14288 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 14289 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 14290 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 14291 zone->refreshtime = now; 14292 } 14293 zone_settimer(zone, &now); 14294 goto detach; 14295 } 14296 14297 queue_soa_query(zone); 14298 goto detach; 14299 14300 exiting: 14301 dns_request_destroy(&zone->request); 14302 goto detach; 14303 14304 same_primary: 14305 if (msg != NULL) { 14306 dns_message_detach(&msg); 14307 } 14308 dns_request_destroy(&zone->request); 14309 queue_soa_query(zone); 14310 14311 detach: 14312 if (do_queue_xfrin) { 14313 /* Shows in the statistics channel the duration of the step. */ 14314 zone->xfrintime = isc_time_now(); 14315 } 14316 UNLOCK_ZONE(zone); 14317 if (do_queue_xfrin) { 14318 queue_xfrin(zone); 14319 } 14320 dns_zone_idetach(&zone); 14321 return; 14322 } 14323 14324 struct soaquery { 14325 dns_zone_t *zone; 14326 isc_rlevent_t *rlevent; 14327 }; 14328 14329 static void 14330 queue_soa_query(dns_zone_t *zone) { 14331 isc_result_t result; 14332 struct soaquery *sq = NULL; 14333 14334 ENTER; 14335 /* 14336 * Locked by caller 14337 */ 14338 REQUIRE(LOCKED_ZONE(zone)); 14339 14340 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 14341 cancel_refresh(zone); 14342 return; 14343 } 14344 14345 sq = isc_mem_get(zone->mctx, sizeof(*sq)); 14346 *sq = (struct soaquery){ .zone = NULL }; 14347 14348 /* Shows in the statistics channel the duration of the current step. */ 14349 zone->xfrintime = isc_time_now(); 14350 14351 /* 14352 * Attach so that we won't clean up until the event is delivered. 14353 */ 14354 zone_iattach(zone, &sq->zone); 14355 result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->loop, 14356 soa_query, sq, &sq->rlevent); 14357 if (result != ISC_R_SUCCESS) { 14358 zone_idetach(&sq->zone); 14359 isc_mem_put(zone->mctx, sq, sizeof(*sq)); 14360 cancel_refresh(zone); 14361 } 14362 } 14363 14364 static void 14365 soa_query(void *arg) { 14366 struct soaquery *sq = (struct soaquery *)arg; 14367 dns_zone_t *zone = sq->zone; 14368 isc_result_t result = ISC_R_FAILURE; 14369 dns_message_t *message = NULL; 14370 isc_netaddr_t primaryip; 14371 dns_tsigkey_t *key = NULL; 14372 dns_transport_t *transport = NULL; 14373 uint32_t options; 14374 bool cancel = true; 14375 int timeout; 14376 bool have_xfrsource = false, reqnsid, reqexpire; 14377 uint16_t udpsize = SEND_BUFFER_SIZE; 14378 isc_sockaddr_t curraddr, sourceaddr; 14379 bool do_queue_xfrin = false; 14380 14381 REQUIRE(DNS_ZONE_VALID(zone)); 14382 14383 ENTER; 14384 14385 LOCK_ZONE(zone); 14386 if (sq->rlevent->canceled || DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || 14387 zone->view->requestmgr == NULL) 14388 { 14389 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 14390 cancel = false; 14391 } 14392 goto cleanup; 14393 } 14394 14395 again: 14396 dns_zone_logc( 14397 zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(3), 14398 "soa_query: remote server current address index %d count %d", 14399 zone->primaries.curraddr, zone->primaries.addrcnt); 14400 INSIST(dns_remote_count(&zone->primaries) > 0); 14401 INSIST(!dns_remote_done(&zone->primaries)); 14402 14403 sourceaddr = dns_remote_sourceaddr(&zone->primaries); 14404 curraddr = dns_remote_curraddr(&zone->primaries); 14405 isc_netaddr_fromsockaddr(&primaryip, &curraddr); 14406 14407 if (isc_sockaddr_disabled(&curraddr)) { 14408 goto skip_primary; 14409 } 14410 14411 /* 14412 * First, look for a tsig key in the primaries statement, then 14413 * try for a server key. 14414 */ 14415 if (dns_remote_keyname(&zone->primaries) != NULL) { 14416 dns_view_t *view = dns_zone_getview(zone); 14417 dns_name_t *keyname = dns_remote_keyname(&zone->primaries); 14418 result = dns_view_gettsig(view, keyname, &key); 14419 if (result != ISC_R_SUCCESS) { 14420 char namebuf[DNS_NAME_FORMATSIZE]; 14421 dns_name_format(keyname, namebuf, sizeof(namebuf)); 14422 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14423 ISC_LOG_ERROR, "unable to find key: %s", 14424 namebuf); 14425 goto skip_primary; 14426 } 14427 } 14428 if (key == NULL) { 14429 result = dns_view_getpeertsig(zone->view, &primaryip, &key); 14430 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 14431 char addrbuf[ISC_NETADDR_FORMATSIZE]; 14432 isc_netaddr_format(&primaryip, addrbuf, 14433 sizeof(addrbuf)); 14434 dns_zone_logc( 14435 zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, 14436 "unable to find TSIG key for %s", addrbuf); 14437 goto skip_primary; 14438 } 14439 } 14440 14441 if (dns_remote_tlsname(&zone->primaries) != NULL) { 14442 dns_view_t *view = dns_zone_getview(zone); 14443 dns_name_t *tlsname = dns_remote_tlsname(&zone->primaries); 14444 result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname, 14445 &transport); 14446 if (result != ISC_R_SUCCESS) { 14447 char namebuf[DNS_NAME_FORMATSIZE]; 14448 dns_name_format(tlsname, namebuf, sizeof(namebuf)); 14449 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14450 ISC_LOG_ERROR, 14451 "unable to find TLS configuration: %s", 14452 namebuf); 14453 goto skip_primary; 14454 } 14455 } 14456 14457 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? DNS_REQUESTOPT_TCP 14458 : 0; 14459 reqnsid = zone->view->requestnsid; 14460 reqexpire = zone->requestexpire; 14461 if (zone->view->peers != NULL) { 14462 dns_peer_t *peer = NULL; 14463 bool edns, usetcp; 14464 result = dns_peerlist_peerbyaddr(zone->view->peers, &primaryip, 14465 &peer); 14466 if (result == ISC_R_SUCCESS) { 14467 result = dns_peer_getsupportedns(peer, &edns); 14468 if (result == ISC_R_SUCCESS && !edns) { 14469 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14470 } 14471 result = dns_peer_gettransfersource(peer, 14472 &zone->sourceaddr); 14473 if (result == ISC_R_SUCCESS) { 14474 have_xfrsource = true; 14475 } 14476 udpsize = dns_view_getudpsize(zone->view); 14477 (void)dns_peer_getudpsize(peer, &udpsize); 14478 (void)dns_peer_getrequestnsid(peer, &reqnsid); 14479 (void)dns_peer_getrequestexpire(peer, &reqexpire); 14480 result = dns_peer_getforcetcp(peer, &usetcp); 14481 if (result == ISC_R_SUCCESS && usetcp) { 14482 options |= DNS_REQUESTOPT_TCP; 14483 } 14484 } 14485 } 14486 14487 switch (isc_sockaddr_pf(&curraddr)) { 14488 case PF_INET: 14489 if (!have_xfrsource) { 14490 isc_sockaddr_t any; 14491 isc_sockaddr_any(&any); 14492 14493 zone->sourceaddr = sourceaddr; 14494 if (isc_sockaddr_equal(&sourceaddr, &any)) { 14495 zone->sourceaddr = zone->xfrsource4; 14496 } 14497 } 14498 break; 14499 case PF_INET6: 14500 if (!have_xfrsource) { 14501 isc_sockaddr_t any; 14502 isc_sockaddr_any6(&any); 14503 14504 zone->sourceaddr = sourceaddr; 14505 if (isc_sockaddr_equal(&zone->sourceaddr, &any)) { 14506 zone->sourceaddr = zone->xfrsource6; 14507 } 14508 } 14509 break; 14510 default: 14511 result = ISC_R_NOTIMPLEMENTED; 14512 goto cleanup; 14513 } 14514 14515 /* 14516 * FIXME(OS): This is a bit hackish, but it enforces the SOA query to go 14517 * through the XFR channel instead of doing dns_request that doesn't 14518 * have DoT support yet. 14519 */ 14520 if (transport != NULL) { 14521 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 14522 do_queue_xfrin = true; 14523 cancel = false; 14524 result = ISC_R_SUCCESS; 14525 goto cleanup; 14526 } 14527 14528 create_query(zone, dns_rdatatype_soa, &zone->origin, &message); 14529 14530 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 14531 result = add_opt(message, udpsize, reqnsid, reqexpire); 14532 if (result != ISC_R_SUCCESS) { 14533 zone_debuglogc(zone, DNS_LOGCATEGORY_XFER_IN, __func__, 14534 1, "unable to add opt record: %s", 14535 isc_result_totext(result)); 14536 } 14537 } 14538 14539 zone_iattach(zone, &(dns_zone_t *){ NULL }); 14540 timeout = 5; 14541 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) { 14542 timeout = 30; 14543 } 14544 result = dns_request_create( 14545 zone->view->requestmgr, message, &zone->sourceaddr, &curraddr, 14546 NULL, NULL, options, key, timeout * 3 + 1, timeout, 2, 14547 zone->loop, refresh_callback, zone, &zone->request); 14548 if (result != ISC_R_SUCCESS) { 14549 zone_idetach(&(dns_zone_t *){ zone }); 14550 zone_debuglogc(zone, DNS_LOGCATEGORY_XFER_IN, __func__, 1, 14551 "dns_request_create() failed: %s", 14552 isc_result_totext(result)); 14553 goto skip_primary; 14554 } else { 14555 /* Shows in the statistics channel the duration of the query. */ 14556 zone->xfrintime = isc_time_now(); 14557 14558 if (isc_sockaddr_pf(&curraddr) == PF_INET) { 14559 inc_stats(zone, dns_zonestatscounter_soaoutv4); 14560 } else { 14561 inc_stats(zone, dns_zonestatscounter_soaoutv6); 14562 } 14563 } 14564 cancel = false; 14565 cleanup: 14566 if (transport != NULL) { 14567 dns_transport_detach(&transport); 14568 } 14569 if (key != NULL) { 14570 dns_tsigkey_detach(&key); 14571 } 14572 if (result != ISC_R_SUCCESS) { 14573 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 14574 } 14575 if (message != NULL) { 14576 dns_message_detach(&message); 14577 } 14578 if (cancel) { 14579 cancel_refresh(zone); 14580 } 14581 if (do_queue_xfrin) { 14582 /* Shows in the statistics channel the duration of the step. */ 14583 zone->xfrintime = isc_time_now(); 14584 } 14585 UNLOCK_ZONE(zone); 14586 if (do_queue_xfrin) { 14587 queue_xfrin(zone); 14588 } 14589 isc_rlevent_free(&sq->rlevent); 14590 isc_mem_put(zone->mctx, sq, sizeof(*sq)); 14591 dns_zone_idetach(&zone); 14592 return; 14593 14594 skip_primary: 14595 if (transport != NULL) { 14596 dns_transport_detach(&transport); 14597 } 14598 if (key != NULL) { 14599 dns_tsigkey_detach(&key); 14600 } 14601 if (message != NULL) { 14602 dns_message_detach(&message); 14603 } 14604 /* 14605 * Skip to next failed / untried primary. 14606 */ 14607 dns_remote_next(&zone->primaries, true); 14608 if (!dns_remote_done(&zone->primaries)) { 14609 goto again; 14610 } 14611 dns_remote_reset(&zone->primaries, false); 14612 goto cleanup; 14613 } 14614 14615 static void 14616 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { 14617 isc_result_t result; 14618 dns_message_t *message = NULL; 14619 isc_netaddr_t primaryip; 14620 dns_tsigkey_t *key = NULL; 14621 dns_dbnode_t *node = NULL; 14622 int timeout; 14623 bool have_xfrsource = false; 14624 bool reqnsid; 14625 uint16_t udpsize = SEND_BUFFER_SIZE; 14626 isc_sockaddr_t curraddr, sourceaddr; 14627 struct stub_cb_args *cb_args; 14628 14629 REQUIRE(DNS_ZONE_VALID(zone)); 14630 REQUIRE(LOCKED_ZONE(zone)); 14631 REQUIRE((soardataset != NULL && stub == NULL) || 14632 (soardataset == NULL && stub != NULL)); 14633 REQUIRE(stub == NULL || DNS_STUB_VALID(stub)); 14634 14635 ENTER; 14636 14637 if (stub == NULL) { 14638 stub = isc_mem_get(zone->mctx, sizeof(*stub)); 14639 stub->magic = STUB_MAGIC; 14640 stub->mctx = zone->mctx; 14641 stub->zone = NULL; 14642 stub->db = NULL; 14643 stub->version = NULL; 14644 atomic_init(&stub->pending_requests, 0); 14645 14646 /* 14647 * Attach so that the zone won't disappear from under us. 14648 */ 14649 zone_iattach(zone, &stub->zone); 14650 14651 /* 14652 * If a db exists we will update it, otherwise we create a 14653 * new one and attach it to the zone once we have the NS 14654 * RRset and glue. 14655 */ 14656 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 14657 if (zone->db != NULL) { 14658 dns_db_attach(zone->db, &stub->db); 14659 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 14660 } else { 14661 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 14662 14663 INSIST(zone->db_argc >= 1); 14664 result = dns_db_create(zone->mctx, zone->db_argv[0], 14665 &zone->origin, dns_dbtype_stub, 14666 zone->rdclass, zone->db_argc - 1, 14667 zone->db_argv + 1, &stub->db); 14668 if (result != ISC_R_SUCCESS) { 14669 dns_zone_log(zone, ISC_LOG_ERROR, 14670 "refreshing stub: " 14671 "could not create " 14672 "database: %s", 14673 isc_result_totext(result)); 14674 goto cleanup; 14675 } 14676 dns_db_setloop(stub->db, zone->loop); 14677 dns_db_setmaxrrperset(stub->db, zone->maxrrperset); 14678 dns_db_setmaxtypepername(stub->db, 14679 zone->maxtypepername); 14680 } 14681 14682 result = dns_db_newversion(stub->db, &stub->version); 14683 if (result != ISC_R_SUCCESS) { 14684 dns_zone_log(zone, ISC_LOG_INFO, 14685 "refreshing stub: " 14686 "dns_db_newversion() failed: %s", 14687 isc_result_totext(result)); 14688 goto cleanup; 14689 } 14690 14691 /* 14692 * Update SOA record. 14693 */ 14694 result = dns_db_findnode(stub->db, &zone->origin, true, &node); 14695 if (result != ISC_R_SUCCESS) { 14696 dns_zone_log(zone, ISC_LOG_INFO, 14697 "refreshing stub: " 14698 "dns_db_findnode() failed: %s", 14699 isc_result_totext(result)); 14700 goto cleanup; 14701 } 14702 14703 result = dns_db_addrdataset(stub->db, node, stub->version, 0, 14704 soardataset, 0, NULL); 14705 dns_db_detachnode(stub->db, &node); 14706 if (result != ISC_R_SUCCESS) { 14707 dns_zone_log(zone, ISC_LOG_INFO, 14708 "refreshing stub: " 14709 "dns_db_addrdataset() failed: %s", 14710 isc_result_totext(result)); 14711 goto cleanup; 14712 } 14713 } 14714 14715 /* 14716 * XXX Optimisation: Create message when zone is setup and reuse. 14717 */ 14718 create_query(zone, dns_rdatatype_ns, &zone->origin, &message); 14719 14720 INSIST(dns_remote_count(&zone->primaries) > 0); 14721 INSIST(!dns_remote_done(&zone->primaries)); 14722 14723 sourceaddr = dns_remote_sourceaddr(&zone->primaries); 14724 curraddr = dns_remote_curraddr(&zone->primaries); 14725 isc_netaddr_fromsockaddr(&primaryip, &curraddr); 14726 /* 14727 * First, look for a tsig key in the primaries statement, then 14728 * try for a server key. 14729 */ 14730 if (dns_remote_keyname(&zone->primaries) != NULL) { 14731 dns_view_t *view = dns_zone_getview(zone); 14732 dns_name_t *keyname = dns_remote_keyname(&zone->primaries); 14733 result = dns_view_gettsig(view, keyname, &key); 14734 if (result != ISC_R_SUCCESS) { 14735 char namebuf[DNS_NAME_FORMATSIZE]; 14736 dns_name_format(keyname, namebuf, sizeof(namebuf)); 14737 dns_zone_log(zone, ISC_LOG_ERROR, 14738 "unable to find key: %s", namebuf); 14739 } 14740 } 14741 if (key == NULL) { 14742 (void)dns_view_getpeertsig(zone->view, &primaryip, &key); 14743 } 14744 14745 /* FIXME(OS): Do we need the transport here too? Most probably yes */ 14746 14747 reqnsid = zone->view->requestnsid; 14748 if (zone->view->peers != NULL) { 14749 dns_peer_t *peer = NULL; 14750 bool edns; 14751 result = dns_peerlist_peerbyaddr(zone->view->peers, &primaryip, 14752 &peer); 14753 if (result == ISC_R_SUCCESS) { 14754 result = dns_peer_getsupportedns(peer, &edns); 14755 if (result == ISC_R_SUCCESS && !edns) { 14756 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14757 } 14758 result = dns_peer_gettransfersource(peer, 14759 &zone->sourceaddr); 14760 if (result == ISC_R_SUCCESS) { 14761 have_xfrsource = true; 14762 } 14763 udpsize = dns_view_getudpsize(zone->view); 14764 (void)dns_peer_getudpsize(peer, &udpsize); 14765 (void)dns_peer_getrequestnsid(peer, &reqnsid); 14766 } 14767 } 14768 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 14769 result = add_opt(message, udpsize, reqnsid, false); 14770 if (result != ISC_R_SUCCESS) { 14771 zone_debuglog(zone, __func__, 1, 14772 "unable to add opt record: %s", 14773 isc_result_totext(result)); 14774 } 14775 } 14776 14777 /* 14778 * Always use TCP so that we shouldn't truncate in additional section. 14779 */ 14780 switch (isc_sockaddr_pf(&curraddr)) { 14781 case PF_INET: 14782 if (!have_xfrsource) { 14783 isc_sockaddr_t any; 14784 isc_sockaddr_any(&any); 14785 14786 zone->sourceaddr = sourceaddr; 14787 if (isc_sockaddr_equal(&zone->sourceaddr, &any)) { 14788 zone->sourceaddr = zone->xfrsource4; 14789 } 14790 } 14791 break; 14792 case PF_INET6: 14793 if (!have_xfrsource) { 14794 isc_sockaddr_t any; 14795 isc_sockaddr_any6(&any); 14796 14797 zone->sourceaddr = sourceaddr; 14798 if (isc_sockaddr_equal(&zone->sourceaddr, &any)) { 14799 zone->sourceaddr = zone->xfrsource6; 14800 } 14801 } 14802 break; 14803 default: 14804 result = ISC_R_NOTIMPLEMENTED; 14805 POST(result); 14806 goto cleanup; 14807 } 14808 timeout = 5; 14809 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) { 14810 timeout = 30; 14811 } 14812 14813 /* 14814 * Save request parameters so we can reuse them later on 14815 * for resolving missing glue A/AAAA records. 14816 */ 14817 cb_args = isc_mem_get(zone->mctx, sizeof(*cb_args)); 14818 cb_args->stub = stub; 14819 cb_args->tsig_key = key; 14820 cb_args->udpsize = udpsize; 14821 cb_args->timeout = timeout; 14822 cb_args->reqnsid = reqnsid; 14823 14824 result = dns_request_create( 14825 zone->view->requestmgr, message, &zone->sourceaddr, &curraddr, 14826 NULL, NULL, DNS_REQUESTOPT_TCP, key, timeout * 3 + 1, timeout, 14827 2, zone->loop, stub_callback, cb_args, &zone->request); 14828 if (result != ISC_R_SUCCESS) { 14829 zone_debuglog(zone, __func__, 1, 14830 "dns_request_create() failed: %s", 14831 isc_result_totext(result)); 14832 goto cleanup; 14833 } 14834 dns_message_detach(&message); 14835 goto unlock; 14836 14837 cleanup: 14838 cancel_refresh(zone); 14839 stub->magic = 0; 14840 if (stub->version != NULL) { 14841 dns_db_closeversion(stub->db, &stub->version, false); 14842 } 14843 if (stub->db != NULL) { 14844 dns_db_detach(&stub->db); 14845 } 14846 if (stub->zone != NULL) { 14847 zone_idetach(&stub->zone); 14848 } 14849 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 14850 if (message != NULL) { 14851 dns_message_detach(&message); 14852 } 14853 unlock: 14854 if (key != NULL) { 14855 dns_tsigkey_detach(&key); 14856 } 14857 return; 14858 } 14859 14860 /* 14861 * Shut the zone down. 14862 */ 14863 static void 14864 zone_shutdown(void *arg) { 14865 dns_zone_t *zone = (dns_zone_t *)arg; 14866 bool free_needed, linked = false; 14867 dns_zone_t *raw = NULL, *secure = NULL; 14868 dns_view_t *view = NULL, *prev_view = NULL; 14869 14870 REQUIRE(DNS_ZONE_VALID(zone)); 14871 INSIST(isc_refcount_current(&zone->references) == 0); 14872 14873 zone_debuglog(zone, __func__, 3, "shutting down"); 14874 14875 /* 14876 * If we were waiting for xfrin quota, step out of 14877 * the queue. 14878 * If there's no zone manager, we can't be waiting for the 14879 * xfrin quota 14880 */ 14881 if (zone->zmgr != NULL) { 14882 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 14883 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) { 14884 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone, 14885 statelink); 14886 linked = true; 14887 zone->statelist = NULL; 14888 } 14889 if (zone->statelist == &zone->zmgr->xfrin_in_progress) { 14890 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, 14891 statelink); 14892 zone->statelist = NULL; 14893 zmgr_resume_xfrs(zone->zmgr, false); 14894 } 14895 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 14896 } 14897 14898 /* 14899 * In loop context, no locking required. See zone_xfrdone(). 14900 */ 14901 if (zone->xfr != NULL) { 14902 /* The final detach will happen in zone_xfrdone() */ 14903 dns_xfrin_shutdown(zone->xfr); 14904 } 14905 14906 /* Safe to release the zone now */ 14907 if (zone->zmgr != NULL) { 14908 dns_zonemgr_releasezone(zone->zmgr, zone); 14909 } 14910 14911 LOCK_ZONE(zone); 14912 INSIST(zone != zone->raw); 14913 14914 /* 14915 * Detach the views early, we don't need them anymore. However, we need 14916 * to detach them outside of the zone lock to break the lock loop 14917 * between view, adb and zone locks. 14918 */ 14919 view = zone->view; 14920 zone->view = NULL; 14921 prev_view = zone->prev_view; 14922 zone->prev_view = NULL; 14923 14924 if (linked) { 14925 isc_refcount_decrement(&zone->irefs); 14926 } 14927 if (zone->request != NULL) { 14928 dns_request_cancel(zone->request); 14929 } 14930 14931 if (zone->loadctx != NULL) { 14932 dns_loadctx_cancel(zone->loadctx); 14933 } 14934 14935 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 14936 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 14937 { 14938 if (zone->dumpctx != NULL) { 14939 dns_dumpctx_cancel(zone->dumpctx); 14940 } 14941 } 14942 14943 checkds_cancel(zone); 14944 14945 notify_cancel(zone); 14946 14947 forward_cancel(zone); 14948 14949 if (zone->timer != NULL) { 14950 isc_refcount_decrement(&zone->irefs); 14951 isc_timer_destroy(&zone->timer); 14952 } 14953 14954 /* 14955 * We have now canceled everything set the flag to allow exit_check() 14956 * to succeed. We must not unlock between setting this flag and 14957 * calling exit_check(). 14958 */ 14959 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN); 14960 free_needed = exit_check(zone); 14961 /* 14962 * If a dump is in progress for the secure zone, defer detaching from 14963 * the raw zone as it may prevent the unsigned serial number from being 14964 * stored in the raw-format dump of the secure zone. In this scenario, 14965 * dump_done() takes care of cleaning up the zone->raw reference. 14966 */ 14967 if (inline_secure(zone) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 14968 raw = zone->raw; 14969 zone->raw = NULL; 14970 } 14971 if (inline_raw(zone)) { 14972 secure = zone->secure; 14973 zone->secure = NULL; 14974 } 14975 UNLOCK_ZONE(zone); 14976 14977 if (view != NULL) { 14978 dns_view_weakdetach(&view); 14979 } 14980 if (prev_view != NULL) { 14981 dns_view_weakdetach(&prev_view); 14982 } 14983 14984 if (raw != NULL) { 14985 dns_zone_detach(&raw); 14986 } 14987 if (secure != NULL) { 14988 dns_zone_idetach(&secure); 14989 } 14990 if (free_needed) { 14991 zone_free(zone); 14992 } 14993 } 14994 14995 static void 14996 zone_timer(void *arg) { 14997 dns_zone_t *zone = (dns_zone_t *)arg; 14998 14999 REQUIRE(DNS_ZONE_VALID(zone)); 15000 15001 zone_maintenance(zone); 15002 } 15003 15004 static void 15005 zone_timer_stop(dns_zone_t *zone) { 15006 zone_debuglog(zone, __func__, 10, "stop zone timer"); 15007 if (zone->timer != NULL) { 15008 isc_timer_stop(zone->timer); 15009 } 15010 } 15011 15012 static void 15013 zone_timer_set(dns_zone_t *zone, isc_time_t *next, isc_time_t *now) { 15014 isc_interval_t interval; 15015 15016 if (isc_time_compare(next, now) <= 0) { 15017 isc_interval_set(&interval, 0, 0); 15018 } else { 15019 isc_time_subtract(next, now, &interval); 15020 } 15021 15022 if (zone->loop == NULL) { 15023 zone_debuglog(zone, __func__, 10, "zone is not managed"); 15024 } else if (zone->timer == NULL) { 15025 isc_refcount_increment0(&zone->irefs); 15026 isc_timer_create(zone->loop, zone_timer, zone, &zone->timer); 15027 } 15028 if (zone->timer != NULL) { 15029 isc_timer_start(zone->timer, isc_timertype_once, &interval); 15030 } 15031 } 15032 15033 static void 15034 zone__settimer(void *arg) { 15035 zone_settimer_t *data = arg; 15036 dns_zone_t *zone = data->zone; 15037 isc_time_t *now = &data->now; 15038 isc_time_t next; 15039 bool free_needed = false; 15040 15041 REQUIRE(DNS_ZONE_VALID(zone)); 15042 ENTER; 15043 15044 LOCK_ZONE(zone); 15045 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 15046 goto free; 15047 } 15048 isc_time_settoepoch(&next); 15049 15050 switch (zone->type) { 15051 case dns_zone_redirect: 15052 if (dns_remote_addresses(&zone->primaries) != NULL) { 15053 goto treat_as_secondary; 15054 } 15055 FALLTHROUGH; 15056 case dns_zone_primary: 15057 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 15058 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) 15059 { 15060 next = zone->notifytime; 15061 } 15062 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 15063 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15064 { 15065 INSIST(!isc_time_isepoch(&zone->dumptime)); 15066 if (isc_time_isepoch(&next) || 15067 isc_time_compare(&zone->dumptime, &next) < 0) 15068 { 15069 next = zone->dumptime; 15070 } 15071 } 15072 if (zone->type == dns_zone_redirect) { 15073 break; 15074 } 15075 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) && 15076 !isc_time_isepoch(&zone->refreshkeytime)) 15077 { 15078 if (isc_time_isepoch(&next) || 15079 isc_time_compare(&zone->refreshkeytime, &next) < 0) 15080 { 15081 next = zone->refreshkeytime; 15082 } 15083 } 15084 if (!isc_time_isepoch(&zone->resigntime)) { 15085 if (isc_time_isepoch(&next) || 15086 isc_time_compare(&zone->resigntime, &next) < 0) 15087 { 15088 next = zone->resigntime; 15089 } 15090 } 15091 if (!isc_time_isepoch(&zone->keywarntime)) { 15092 if (isc_time_isepoch(&next) || 15093 isc_time_compare(&zone->keywarntime, &next) < 0) 15094 { 15095 next = zone->keywarntime; 15096 } 15097 } 15098 if (!isc_time_isepoch(&zone->signingtime)) { 15099 if (isc_time_isepoch(&next) || 15100 isc_time_compare(&zone->signingtime, &next) < 0) 15101 { 15102 next = zone->signingtime; 15103 } 15104 } 15105 if (!isc_time_isepoch(&zone->nsec3chaintime)) { 15106 if (isc_time_isepoch(&next) || 15107 isc_time_compare(&zone->nsec3chaintime, &next) < 0) 15108 { 15109 next = zone->nsec3chaintime; 15110 } 15111 } 15112 break; 15113 15114 case dns_zone_secondary: 15115 case dns_zone_mirror: 15116 treat_as_secondary: 15117 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 15118 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) 15119 { 15120 next = zone->notifytime; 15121 } 15122 FALLTHROUGH; 15123 case dns_zone_stub: 15124 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) && 15125 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOPRIMARIES) && 15126 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) && 15127 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) && 15128 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) && 15129 !isc_time_isepoch(&zone->refreshtime) && 15130 (isc_time_isepoch(&next) || 15131 isc_time_compare(&zone->refreshtime, &next) < 0)) 15132 { 15133 next = zone->refreshtime; 15134 } 15135 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 15136 !isc_time_isepoch(&zone->expiretime)) 15137 { 15138 if (isc_time_isepoch(&next) || 15139 isc_time_compare(&zone->expiretime, &next) < 0) 15140 { 15141 next = zone->expiretime; 15142 } 15143 } 15144 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 15145 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15146 { 15147 INSIST(!isc_time_isepoch(&zone->dumptime)); 15148 if (isc_time_isepoch(&next) || 15149 isc_time_compare(&zone->dumptime, &next) < 0) 15150 { 15151 next = zone->dumptime; 15152 } 15153 } 15154 break; 15155 15156 case dns_zone_key: 15157 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 15158 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15159 { 15160 INSIST(!isc_time_isepoch(&zone->dumptime)); 15161 if (isc_time_isepoch(&next) || 15162 isc_time_compare(&zone->dumptime, &next) < 0) 15163 { 15164 next = zone->dumptime; 15165 } 15166 } 15167 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) { 15168 if (isc_time_isepoch(&next) || 15169 (!isc_time_isepoch(&zone->refreshkeytime) && 15170 isc_time_compare(&zone->refreshkeytime, &next) < 15171 0)) 15172 { 15173 next = zone->refreshkeytime; 15174 } 15175 } 15176 break; 15177 15178 default: 15179 break; 15180 } 15181 15182 if (isc_time_isepoch(&next)) { 15183 zone_timer_stop(zone); 15184 } else { 15185 zone_timer_set(zone, &next, now); 15186 } 15187 15188 free: 15189 isc_mem_put(zone->mctx, data, sizeof(*data)); 15190 isc_refcount_decrement(&zone->irefs); 15191 free_needed = exit_check(zone); 15192 UNLOCK_ZONE(zone); 15193 if (free_needed) { 15194 zone_free(zone); 15195 } 15196 } 15197 15198 static void 15199 zone_settimer(dns_zone_t *zone, isc_time_t *now) { 15200 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 15201 return; 15202 } 15203 15204 zone_settimer_t *arg = isc_mem_get(zone->mctx, sizeof(*arg)); 15205 *arg = (zone_settimer_t){ 15206 .zone = zone, 15207 .now = *now, 15208 }; 15209 isc_refcount_increment0(&zone->irefs); 15210 isc_async_run(zone->loop, zone__settimer, arg); 15211 } 15212 15213 static void 15214 cancel_refresh(dns_zone_t *zone) { 15215 isc_time_t now; 15216 15217 /* 15218 * 'zone' locked by caller. 15219 */ 15220 15221 REQUIRE(DNS_ZONE_VALID(zone)); 15222 REQUIRE(LOCKED_ZONE(zone)); 15223 15224 ENTER; 15225 15226 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 15227 now = isc_time_now(); 15228 zone_settimer(zone, &now); 15229 } 15230 15231 static isc_result_t 15232 notify_createmessage(dns_zone_t *zone, unsigned int flags, 15233 dns_message_t **messagep) { 15234 dns_db_t *zonedb = NULL; 15235 dns_dbnode_t *node = NULL; 15236 dns_dbversion_t *version = NULL; 15237 dns_message_t *message = NULL; 15238 dns_rdataset_t rdataset; 15239 dns_rdata_t rdata = DNS_RDATA_INIT; 15240 15241 dns_name_t *tempname = NULL; 15242 dns_rdata_t *temprdata = NULL; 15243 dns_rdatalist_t *temprdatalist = NULL; 15244 dns_rdataset_t *temprdataset = NULL; 15245 15246 isc_result_t result; 15247 isc_region_t r; 15248 isc_buffer_t *b = NULL; 15249 15250 REQUIRE(DNS_ZONE_VALID(zone)); 15251 REQUIRE(messagep != NULL && *messagep == NULL); 15252 15253 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, 15254 &message); 15255 15256 message->opcode = dns_opcode_notify; 15257 message->flags |= DNS_MESSAGEFLAG_AA; 15258 message->rdclass = zone->rdclass; 15259 15260 dns_message_gettempname(message, &tempname); 15261 15262 dns_message_gettemprdataset(message, &temprdataset); 15263 15264 /* 15265 * Make question. 15266 */ 15267 dns_name_clone(&zone->origin, tempname); 15268 dns_rdataset_makequestion(temprdataset, zone->rdclass, 15269 dns_rdatatype_soa); 15270 ISC_LIST_APPEND(tempname->list, temprdataset, link); 15271 dns_message_addname(message, tempname, DNS_SECTION_QUESTION); 15272 tempname = NULL; 15273 temprdataset = NULL; 15274 15275 if ((flags & DNS_NOTIFY_NOSOA) != 0) { 15276 goto done; 15277 } 15278 15279 dns_message_gettempname(message, &tempname); 15280 dns_message_gettemprdata(message, &temprdata); 15281 dns_message_gettemprdataset(message, &temprdataset); 15282 dns_message_gettemprdatalist(message, &temprdatalist); 15283 15284 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 15285 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */ 15286 dns_db_attach(zone->db, &zonedb); 15287 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 15288 15289 dns_name_clone(&zone->origin, tempname); 15290 dns_db_currentversion(zonedb, &version); 15291 result = dns_db_findnode(zonedb, tempname, false, &node); 15292 if (result != ISC_R_SUCCESS) { 15293 goto soa_cleanup; 15294 } 15295 15296 dns_rdataset_init(&rdataset); 15297 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, 15298 dns_rdatatype_none, 0, &rdataset, NULL); 15299 if (result != ISC_R_SUCCESS) { 15300 goto soa_cleanup; 15301 } 15302 result = dns_rdataset_first(&rdataset); 15303 if (result != ISC_R_SUCCESS) { 15304 goto soa_cleanup; 15305 } 15306 dns_rdataset_current(&rdataset, &rdata); 15307 dns_rdata_toregion(&rdata, &r); 15308 isc_buffer_allocate(zone->mctx, &b, r.length); 15309 isc_buffer_putmem(b, r.base, r.length); 15310 isc_buffer_usedregion(b, &r); 15311 dns_rdata_init(temprdata); 15312 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r); 15313 dns_message_takebuffer(message, &b); 15314 result = dns_rdataset_next(&rdataset); 15315 dns_rdataset_disassociate(&rdataset); 15316 if (result != ISC_R_NOMORE) { 15317 goto soa_cleanup; 15318 } 15319 temprdatalist->rdclass = rdata.rdclass; 15320 temprdatalist->type = rdata.type; 15321 temprdatalist->ttl = rdataset.ttl; 15322 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link); 15323 15324 dns_rdatalist_tordataset(temprdatalist, temprdataset); 15325 15326 ISC_LIST_APPEND(tempname->list, temprdataset, link); 15327 dns_message_addname(message, tempname, DNS_SECTION_ANSWER); 15328 temprdatalist = NULL; 15329 temprdataset = NULL; 15330 temprdata = NULL; 15331 tempname = NULL; 15332 15333 soa_cleanup: 15334 if (node != NULL) { 15335 dns_db_detachnode(zonedb, &node); 15336 } 15337 if (version != NULL) { 15338 dns_db_closeversion(zonedb, &version, false); 15339 } 15340 if (zonedb != NULL) { 15341 dns_db_detach(&zonedb); 15342 } 15343 if (tempname != NULL) { 15344 dns_message_puttempname(message, &tempname); 15345 } 15346 if (temprdata != NULL) { 15347 dns_message_puttemprdata(message, &temprdata); 15348 } 15349 if (temprdataset != NULL) { 15350 dns_message_puttemprdataset(message, &temprdataset); 15351 } 15352 if (temprdatalist != NULL) { 15353 dns_message_puttemprdatalist(message, &temprdatalist); 15354 } 15355 15356 done: 15357 *messagep = message; 15358 return ISC_R_SUCCESS; 15359 } 15360 15361 isc_result_t 15362 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, 15363 isc_sockaddr_t *to, dns_message_t *msg) { 15364 unsigned int i; 15365 dns_rdata_soa_t soa; 15366 dns_rdataset_t *rdataset = NULL; 15367 dns_rdata_t rdata = DNS_RDATA_INIT; 15368 isc_result_t result; 15369 char fromtext[ISC_SOCKADDR_FORMATSIZE]; 15370 int match = 0; 15371 isc_netaddr_t netaddr; 15372 uint32_t serial = 0; 15373 bool have_serial = false; 15374 dns_tsigkey_t *tsigkey; 15375 const dns_name_t *tsig; 15376 15377 REQUIRE(DNS_ZONE_VALID(zone)); 15378 15379 /* 15380 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support 15381 * ROLLOVER. 15382 * 15383 * SOA: RFC1996 15384 * Check that 'from' is a valid notify source, (zone->primaries). 15385 * Return DNS_R_REFUSED if not. 15386 * 15387 * If the notify message contains a serial number check it 15388 * against the zones serial and return if <= current serial 15389 * 15390 * If a refresh check is progress, if so just record the 15391 * fact we received a NOTIFY and from where and return. 15392 * We will perform a new refresh check when the current one 15393 * completes. Return ISC_R_SUCCESS. 15394 * 15395 * Otherwise initiate a refresh check using 'from' as the 15396 * first address to check. Return ISC_R_SUCCESS. 15397 */ 15398 15399 isc_sockaddr_format(from, fromtext, sizeof(fromtext)); 15400 15401 /* 15402 * Notify messages are processed by the raw zone. 15403 */ 15404 LOCK_ZONE(zone); 15405 INSIST(zone != zone->raw); 15406 if (inline_secure(zone)) { 15407 result = dns_zone_notifyreceive(zone->raw, from, to, msg); 15408 UNLOCK_ZONE(zone); 15409 return result; 15410 } 15411 /* 15412 * We only handle NOTIFY (SOA) at the present. 15413 */ 15414 if (isc_sockaddr_pf(from) == PF_INET) { 15415 inc_stats(zone, dns_zonestatscounter_notifyinv4); 15416 } else { 15417 inc_stats(zone, dns_zonestatscounter_notifyinv6); 15418 } 15419 if (msg->counts[DNS_SECTION_QUESTION] == 0 || 15420 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin, 15421 dns_rdatatype_soa, dns_rdatatype_none, NULL, 15422 NULL) != ISC_R_SUCCESS) 15423 { 15424 UNLOCK_ZONE(zone); 15425 if (msg->counts[DNS_SECTION_QUESTION] == 0) { 15426 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 15427 ISC_LOG_NOTICE, 15428 "NOTIFY with no question " 15429 "section from: %s", 15430 fromtext); 15431 return DNS_R_FORMERR; 15432 } 15433 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_NOTICE, 15434 "NOTIFY zone does not match"); 15435 return DNS_R_NOTIMP; 15436 } 15437 15438 /* 15439 * If we are a primary zone just succeed. 15440 */ 15441 if (zone->type == dns_zone_primary) { 15442 UNLOCK_ZONE(zone); 15443 return ISC_R_SUCCESS; 15444 } 15445 15446 isc_netaddr_fromsockaddr(&netaddr, from); 15447 for (i = 0; i < dns_remote_count(&zone->primaries); i++) { 15448 isc_sockaddr_t sockaddr = dns_remote_addr(&zone->primaries, i); 15449 if (isc_sockaddr_eqaddr(from, &sockaddr)) { 15450 break; 15451 } 15452 if (zone->view->aclenv->match_mapped && 15453 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) && 15454 isc_sockaddr_pf(&sockaddr) == AF_INET) 15455 { 15456 isc_netaddr_t na1, na2; 15457 isc_netaddr_fromv4mapped(&na1, &netaddr); 15458 isc_netaddr_fromsockaddr(&na2, &sockaddr); 15459 if (isc_netaddr_equal(&na1, &na2)) { 15460 break; 15461 } 15462 } 15463 } 15464 15465 /* 15466 * Accept notify requests from non primaries if they are on 15467 * 'zone->notify_acl'. 15468 */ 15469 tsigkey = dns_message_gettsigkey(msg); 15470 tsig = dns_tsigkey_identity(tsigkey); 15471 if (i >= dns_remote_count(&zone->primaries) && 15472 zone->notify_acl != NULL && 15473 (dns_acl_match(&netaddr, tsig, zone->notify_acl, zone->view->aclenv, 15474 &match, NULL) == ISC_R_SUCCESS) && 15475 match > 0) 15476 { 15477 /* Accept notify. */ 15478 } else if (i >= dns_remote_count(&zone->primaries)) { 15479 UNLOCK_ZONE(zone); 15480 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 15481 "refused notify from non-primary: %s", fromtext); 15482 inc_stats(zone, dns_zonestatscounter_notifyrej); 15483 return DNS_R_REFUSED; 15484 } 15485 15486 /* 15487 * If the zone is loaded and there are answers check the serial 15488 * to see if we need to do a refresh. Do not worry about this 15489 * check if we are a dialup zone as we use the notify request 15490 * to trigger a refresh check. 15491 */ 15492 if (msg->counts[DNS_SECTION_ANSWER] > 0 && 15493 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 15494 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) 15495 { 15496 result = dns_message_findname( 15497 msg, DNS_SECTION_ANSWER, &zone->origin, 15498 dns_rdatatype_soa, dns_rdatatype_none, NULL, &rdataset); 15499 if (result == ISC_R_SUCCESS) { 15500 result = dns_rdataset_first(rdataset); 15501 } 15502 if (result == ISC_R_SUCCESS) { 15503 uint32_t oldserial; 15504 unsigned int soacount; 15505 15506 dns_rdataset_current(rdataset, &rdata); 15507 result = dns_rdata_tostruct(&rdata, &soa, NULL); 15508 RUNTIME_CHECK(result == ISC_R_SUCCESS); 15509 serial = soa.serial; 15510 have_serial = true; 15511 /* 15512 * The following should safely be performed without DB 15513 * lock and succeed in this context. 15514 */ 15515 result = zone_get_from_db(zone, zone->db, NULL, 15516 &soacount, NULL, &oldserial, 15517 NULL, NULL, NULL, NULL, NULL); 15518 RUNTIME_CHECK(result == ISC_R_SUCCESS); 15519 RUNTIME_CHECK(soacount > 0U); 15520 if (isc_serial_le(serial, oldserial)) { 15521 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 15522 ISC_LOG_INFO, 15523 "notify from %s: " 15524 "zone is up to date", 15525 fromtext); 15526 UNLOCK_ZONE(zone); 15527 return ISC_R_SUCCESS; 15528 } 15529 } 15530 } 15531 15532 /* 15533 * If we got this far and there was a refresh in progress just 15534 * let it complete. Record where we got the notify from so we 15535 * can perform a refresh check when the current one completes 15536 */ 15537 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { 15538 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 15539 zone->notifyfrom = *from; 15540 UNLOCK_ZONE(zone); 15541 if (have_serial) { 15542 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 15543 ISC_LOG_INFO, 15544 "notify from %s: " 15545 "serial %u: refresh in progress, " 15546 "refresh check queued", 15547 fromtext, serial); 15548 } else { 15549 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 15550 ISC_LOG_INFO, 15551 "notify from %s: " 15552 "refresh in progress, " 15553 "refresh check queued", 15554 fromtext); 15555 } 15556 return ISC_R_SUCCESS; 15557 } 15558 if (have_serial) { 15559 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 15560 "notify from %s: serial %u", fromtext, serial); 15561 } else { 15562 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 15563 "notify from %s: no serial", fromtext); 15564 } 15565 zone->notifyfrom = *from; 15566 UNLOCK_ZONE(zone); 15567 15568 if (to != NULL) { 15569 dns_zonemgr_unreachabledel(zone->zmgr, from, to); 15570 } 15571 dns_zone_refresh(zone); 15572 return ISC_R_SUCCESS; 15573 } 15574 15575 void 15576 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) { 15577 REQUIRE(DNS_ZONE_VALID(zone)); 15578 15579 LOCK_ZONE(zone); 15580 if (zone->notify_acl != NULL) { 15581 dns_acl_detach(&zone->notify_acl); 15582 } 15583 dns_acl_attach(acl, &zone->notify_acl); 15584 UNLOCK_ZONE(zone); 15585 } 15586 15587 void 15588 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) { 15589 REQUIRE(DNS_ZONE_VALID(zone)); 15590 15591 LOCK_ZONE(zone); 15592 if (zone->query_acl != NULL) { 15593 dns_acl_detach(&zone->query_acl); 15594 } 15595 dns_acl_attach(acl, &zone->query_acl); 15596 UNLOCK_ZONE(zone); 15597 } 15598 15599 void 15600 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) { 15601 REQUIRE(DNS_ZONE_VALID(zone)); 15602 15603 LOCK_ZONE(zone); 15604 if (zone->queryon_acl != NULL) { 15605 dns_acl_detach(&zone->queryon_acl); 15606 } 15607 dns_acl_attach(acl, &zone->queryon_acl); 15608 UNLOCK_ZONE(zone); 15609 } 15610 15611 void 15612 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) { 15613 REQUIRE(DNS_ZONE_VALID(zone)); 15614 15615 LOCK_ZONE(zone); 15616 if (zone->update_acl != NULL) { 15617 dns_acl_detach(&zone->update_acl); 15618 } 15619 dns_acl_attach(acl, &zone->update_acl); 15620 UNLOCK_ZONE(zone); 15621 } 15622 15623 void 15624 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) { 15625 REQUIRE(DNS_ZONE_VALID(zone)); 15626 15627 LOCK_ZONE(zone); 15628 if (zone->forward_acl != NULL) { 15629 dns_acl_detach(&zone->forward_acl); 15630 } 15631 dns_acl_attach(acl, &zone->forward_acl); 15632 UNLOCK_ZONE(zone); 15633 } 15634 15635 void 15636 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) { 15637 REQUIRE(DNS_ZONE_VALID(zone)); 15638 15639 LOCK_ZONE(zone); 15640 if (zone->xfr_acl != NULL) { 15641 dns_acl_detach(&zone->xfr_acl); 15642 } 15643 dns_acl_attach(acl, &zone->xfr_acl); 15644 UNLOCK_ZONE(zone); 15645 } 15646 15647 dns_acl_t * 15648 dns_zone_getnotifyacl(dns_zone_t *zone) { 15649 REQUIRE(DNS_ZONE_VALID(zone)); 15650 15651 return zone->notify_acl; 15652 } 15653 15654 dns_acl_t * 15655 dns_zone_getqueryacl(dns_zone_t *zone) { 15656 REQUIRE(DNS_ZONE_VALID(zone)); 15657 15658 return zone->query_acl; 15659 } 15660 15661 dns_acl_t * 15662 dns_zone_getqueryonacl(dns_zone_t *zone) { 15663 REQUIRE(DNS_ZONE_VALID(zone)); 15664 15665 return zone->queryon_acl; 15666 } 15667 15668 dns_acl_t * 15669 dns_zone_getupdateacl(dns_zone_t *zone) { 15670 REQUIRE(DNS_ZONE_VALID(zone)); 15671 15672 return zone->update_acl; 15673 } 15674 15675 dns_acl_t * 15676 dns_zone_getforwardacl(dns_zone_t *zone) { 15677 REQUIRE(DNS_ZONE_VALID(zone)); 15678 15679 return zone->forward_acl; 15680 } 15681 15682 dns_acl_t * 15683 dns_zone_getxfracl(dns_zone_t *zone) { 15684 REQUIRE(DNS_ZONE_VALID(zone)); 15685 15686 return zone->xfr_acl; 15687 } 15688 15689 void 15690 dns_zone_clearupdateacl(dns_zone_t *zone) { 15691 REQUIRE(DNS_ZONE_VALID(zone)); 15692 15693 LOCK_ZONE(zone); 15694 if (zone->update_acl != NULL) { 15695 dns_acl_detach(&zone->update_acl); 15696 } 15697 UNLOCK_ZONE(zone); 15698 } 15699 15700 void 15701 dns_zone_clearforwardacl(dns_zone_t *zone) { 15702 REQUIRE(DNS_ZONE_VALID(zone)); 15703 15704 LOCK_ZONE(zone); 15705 if (zone->forward_acl != NULL) { 15706 dns_acl_detach(&zone->forward_acl); 15707 } 15708 UNLOCK_ZONE(zone); 15709 } 15710 15711 void 15712 dns_zone_clearnotifyacl(dns_zone_t *zone) { 15713 REQUIRE(DNS_ZONE_VALID(zone)); 15714 15715 LOCK_ZONE(zone); 15716 if (zone->notify_acl != NULL) { 15717 dns_acl_detach(&zone->notify_acl); 15718 } 15719 UNLOCK_ZONE(zone); 15720 } 15721 15722 void 15723 dns_zone_clearqueryacl(dns_zone_t *zone) { 15724 REQUIRE(DNS_ZONE_VALID(zone)); 15725 15726 LOCK_ZONE(zone); 15727 if (zone->query_acl != NULL) { 15728 dns_acl_detach(&zone->query_acl); 15729 } 15730 UNLOCK_ZONE(zone); 15731 } 15732 15733 void 15734 dns_zone_clearqueryonacl(dns_zone_t *zone) { 15735 REQUIRE(DNS_ZONE_VALID(zone)); 15736 15737 LOCK_ZONE(zone); 15738 if (zone->queryon_acl != NULL) { 15739 dns_acl_detach(&zone->queryon_acl); 15740 } 15741 UNLOCK_ZONE(zone); 15742 } 15743 15744 void 15745 dns_zone_clearxfracl(dns_zone_t *zone) { 15746 REQUIRE(DNS_ZONE_VALID(zone)); 15747 15748 LOCK_ZONE(zone); 15749 if (zone->xfr_acl != NULL) { 15750 dns_acl_detach(&zone->xfr_acl); 15751 } 15752 UNLOCK_ZONE(zone); 15753 } 15754 15755 bool 15756 dns_zone_getupdatedisabled(dns_zone_t *zone) { 15757 REQUIRE(DNS_ZONE_VALID(zone)); 15758 return zone->update_disabled; 15759 } 15760 15761 void 15762 dns_zone_setupdatedisabled(dns_zone_t *zone, bool state) { 15763 REQUIRE(DNS_ZONE_VALID(zone)); 15764 zone->update_disabled = state; 15765 } 15766 15767 bool 15768 dns_zone_getzeronosoattl(dns_zone_t *zone) { 15769 REQUIRE(DNS_ZONE_VALID(zone)); 15770 return zone->zero_no_soa_ttl; 15771 } 15772 15773 void 15774 dns_zone_setzeronosoattl(dns_zone_t *zone, bool state) { 15775 REQUIRE(DNS_ZONE_VALID(zone)); 15776 zone->zero_no_soa_ttl = state; 15777 } 15778 15779 void 15780 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) { 15781 REQUIRE(DNS_ZONE_VALID(zone)); 15782 15783 zone->check_names = severity; 15784 } 15785 15786 dns_severity_t 15787 dns_zone_getchecknames(dns_zone_t *zone) { 15788 REQUIRE(DNS_ZONE_VALID(zone)); 15789 15790 return zone->check_names; 15791 } 15792 15793 void 15794 dns_zone_setjournalsize(dns_zone_t *zone, int32_t size) { 15795 REQUIRE(DNS_ZONE_VALID(zone)); 15796 15797 zone->journalsize = size; 15798 } 15799 15800 int32_t 15801 dns_zone_getjournalsize(dns_zone_t *zone) { 15802 REQUIRE(DNS_ZONE_VALID(zone)); 15803 15804 return zone->journalsize; 15805 } 15806 15807 static void 15808 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) { 15809 isc_result_t result = ISC_R_FAILURE; 15810 isc_buffer_t buffer; 15811 15812 REQUIRE(buf != NULL); 15813 REQUIRE(length > 1U); 15814 15815 /* 15816 * Leave space for terminating '\0'. 15817 */ 15818 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 15819 if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) { 15820 if (dns_name_dynamic(&zone->origin)) { 15821 result = dns_name_totext( 15822 &zone->origin, DNS_NAME_OMITFINALDOT, &buffer); 15823 } 15824 if (result != ISC_R_SUCCESS && 15825 isc_buffer_availablelength(&buffer) >= 15826 (sizeof("<UNKNOWN>") - 1)) 15827 { 15828 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 15829 } 15830 15831 if (isc_buffer_availablelength(&buffer) > 0) { 15832 isc_buffer_putstr(&buffer, "/"); 15833 } 15834 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 15835 } 15836 15837 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 && 15838 strcmp(zone->view->name, "_default") != 0 && 15839 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) 15840 { 15841 isc_buffer_putstr(&buffer, "/"); 15842 isc_buffer_putstr(&buffer, zone->view->name); 15843 } 15844 if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer)) { 15845 isc_buffer_putstr(&buffer, " (signed)"); 15846 } 15847 if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer)) { 15848 isc_buffer_putstr(&buffer, " (unsigned)"); 15849 } 15850 15851 buf[isc_buffer_usedlength(&buffer)] = '\0'; 15852 } 15853 15854 static void 15855 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) { 15856 isc_result_t result = ISC_R_FAILURE; 15857 isc_buffer_t buffer; 15858 15859 REQUIRE(buf != NULL); 15860 REQUIRE(length > 1U); 15861 15862 /* 15863 * Leave space for terminating '\0'. 15864 */ 15865 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 15866 if (dns_name_dynamic(&zone->origin)) { 15867 result = dns_name_totext(&zone->origin, DNS_NAME_OMITFINALDOT, 15868 &buffer); 15869 } 15870 if (result != ISC_R_SUCCESS && 15871 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1)) 15872 { 15873 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 15874 } 15875 15876 buf[isc_buffer_usedlength(&buffer)] = '\0'; 15877 } 15878 15879 static void 15880 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) { 15881 isc_buffer_t buffer; 15882 15883 REQUIRE(buf != NULL); 15884 REQUIRE(length > 1U); 15885 15886 /* 15887 * Leave space for terminating '\0'. 15888 */ 15889 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 15890 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 15891 15892 buf[isc_buffer_usedlength(&buffer)] = '\0'; 15893 } 15894 15895 static void 15896 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) { 15897 isc_buffer_t buffer; 15898 15899 REQUIRE(buf != NULL); 15900 REQUIRE(length > 1U); 15901 15902 /* 15903 * Leave space for terminating '\0'. 15904 */ 15905 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 15906 15907 if (zone->view == NULL) { 15908 isc_buffer_putstr(&buffer, "_none"); 15909 } else if (strlen(zone->view->name) < 15910 isc_buffer_availablelength(&buffer)) 15911 { 15912 isc_buffer_putstr(&buffer, zone->view->name); 15913 } else { 15914 isc_buffer_putstr(&buffer, "_toolong"); 15915 } 15916 15917 buf[isc_buffer_usedlength(&buffer)] = '\0'; 15918 } 15919 15920 void 15921 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) { 15922 REQUIRE(DNS_ZONE_VALID(zone)); 15923 REQUIRE(buf != NULL); 15924 15925 LOCK_ZONE(zone); 15926 zone_namerd_tostr(zone, buf, length); 15927 UNLOCK_ZONE(zone); 15928 } 15929 15930 void 15931 dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) { 15932 REQUIRE(DNS_ZONE_VALID(zone)); 15933 REQUIRE(buf != NULL); 15934 zone_name_tostr(zone, buf, length); 15935 } 15936 15937 void 15938 dns_zone_logv(dns_zone_t *zone, isc_logcategory_t *category, int level, 15939 const char *prefix, const char *fmt, va_list ap) { 15940 char message[4096]; 15941 const char *zstr; 15942 15943 REQUIRE(DNS_ZONE_VALID(zone)); 15944 15945 if (!isc_log_wouldlog(dns_lctx, level)) { 15946 return; 15947 } 15948 15949 vsnprintf(message, sizeof(message), fmt, ap); 15950 15951 switch (zone->type) { 15952 case dns_zone_key: 15953 zstr = "managed-keys-zone"; 15954 break; 15955 case dns_zone_redirect: 15956 zstr = "redirect-zone"; 15957 break; 15958 default: 15959 zstr = "zone "; 15960 } 15961 15962 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, level, 15963 "%s%s%s%s: %s", (prefix != NULL ? prefix : ""), 15964 (prefix != NULL ? ": " : ""), zstr, zone->strnamerd, 15965 message); 15966 } 15967 15968 static void 15969 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) { 15970 va_list ap; 15971 15972 va_start(ap, fmt); 15973 dns_zone_logv(zone, DNS_LOGCATEGORY_NOTIFY, level, NULL, fmt, ap); 15974 va_end(ap); 15975 } 15976 15977 void 15978 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, int level, 15979 const char *fmt, ...) { 15980 va_list ap; 15981 15982 va_start(ap, fmt); 15983 dns_zone_logv(zone, category, level, NULL, fmt, ap); 15984 va_end(ap); 15985 } 15986 15987 void 15988 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) { 15989 va_list ap; 15990 15991 va_start(ap, fmt); 15992 dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, NULL, fmt, ap); 15993 va_end(ap); 15994 } 15995 15996 static void 15997 zone_debuglogc(dns_zone_t *zone, isc_logcategory_t *category, const char *me, 15998 int debuglevel, const char *fmt, ...) { 15999 int level = ISC_LOG_DEBUG(debuglevel); 16000 va_list ap; 16001 16002 va_start(ap, fmt); 16003 dns_zone_logv(zone, category, level, me, fmt, ap); 16004 va_end(ap); 16005 } 16006 16007 static void 16008 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel, const char *fmt, 16009 ...) { 16010 int level = ISC_LOG_DEBUG(debuglevel); 16011 va_list ap; 16012 16013 va_start(ap, fmt); 16014 dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, me, fmt, ap); 16015 va_end(ap); 16016 } 16017 16018 static void 16019 dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...) { 16020 va_list ap; 16021 16022 va_start(ap, fmt); 16023 dns_zone_logv(zone, DNS_LOGCATEGORY_DNSSEC, level, NULL, fmt, ap); 16024 va_end(ap); 16025 } 16026 16027 static int 16028 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type) { 16029 isc_result_t result; 16030 dns_name_t *name; 16031 dns_rdataset_t *curr; 16032 int count = 0; 16033 16034 result = dns_message_firstname(msg, section); 16035 while (result == ISC_R_SUCCESS) { 16036 name = NULL; 16037 dns_message_currentname(msg, section, &name); 16038 16039 for (curr = ISC_LIST_TAIL(name->list); curr != NULL; 16040 curr = ISC_LIST_PREV(curr, link)) 16041 { 16042 if (curr->type == type) { 16043 count++; 16044 } 16045 } 16046 result = dns_message_nextname(msg, section); 16047 } 16048 16049 return count; 16050 } 16051 16052 void 16053 dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin) { 16054 REQUIRE(DNS_ZONE_VALID(zone)); 16055 16056 zone->maxxfrin = maxxfrin; 16057 } 16058 16059 uint32_t 16060 dns_zone_getmaxxfrin(dns_zone_t *zone) { 16061 REQUIRE(DNS_ZONE_VALID(zone)); 16062 16063 return zone->maxxfrin; 16064 } 16065 16066 void 16067 dns_zone_setmaxxfrout(dns_zone_t *zone, uint32_t maxxfrout) { 16068 REQUIRE(DNS_ZONE_VALID(zone)); 16069 zone->maxxfrout = maxxfrout; 16070 } 16071 16072 uint32_t 16073 dns_zone_getmaxxfrout(dns_zone_t *zone) { 16074 REQUIRE(DNS_ZONE_VALID(zone)); 16075 16076 return zone->maxxfrout; 16077 } 16078 16079 dns_zonetype_t 16080 dns_zone_gettype(dns_zone_t *zone) { 16081 REQUIRE(DNS_ZONE_VALID(zone)); 16082 16083 return zone->type; 16084 } 16085 16086 const char * 16087 dns_zonetype_name(dns_zonetype_t type) { 16088 switch (type) { 16089 case dns_zone_none: 16090 return "none"; 16091 case dns_zone_primary: 16092 return "primary"; 16093 case dns_zone_secondary: 16094 return "secondary"; 16095 case dns_zone_mirror: 16096 return "mirror"; 16097 case dns_zone_stub: 16098 return "stub"; 16099 case dns_zone_staticstub: 16100 return "static-stub"; 16101 case dns_zone_key: 16102 return "key"; 16103 case dns_zone_dlz: 16104 return "dlz"; 16105 case dns_zone_redirect: 16106 return "redirect"; 16107 default: 16108 return "unknown"; 16109 } 16110 } 16111 16112 dns_zonetype_t 16113 dns_zone_getredirecttype(dns_zone_t *zone) { 16114 REQUIRE(DNS_ZONE_VALID(zone)); 16115 REQUIRE(zone->type == dns_zone_redirect); 16116 16117 return dns_remote_addresses(&zone->primaries) == NULL 16118 ? dns_zone_primary 16119 : dns_zone_secondary; 16120 } 16121 16122 dns_name_t * 16123 dns_zone_getorigin(dns_zone_t *zone) { 16124 REQUIRE(DNS_ZONE_VALID(zone)); 16125 16126 return &zone->origin; 16127 } 16128 16129 void 16130 dns_zone_setidlein(dns_zone_t *zone, uint32_t idlein) { 16131 REQUIRE(DNS_ZONE_VALID(zone)); 16132 16133 if (idlein == 0) { 16134 idlein = DNS_DEFAULT_IDLEIN; 16135 } 16136 zone->idlein = idlein; 16137 } 16138 16139 uint32_t 16140 dns_zone_getidlein(dns_zone_t *zone) { 16141 REQUIRE(DNS_ZONE_VALID(zone)); 16142 16143 return zone->idlein; 16144 } 16145 16146 void 16147 dns_zone_setidleout(dns_zone_t *zone, uint32_t idleout) { 16148 REQUIRE(DNS_ZONE_VALID(zone)); 16149 16150 zone->idleout = idleout; 16151 } 16152 16153 uint32_t 16154 dns_zone_getidleout(dns_zone_t *zone) { 16155 REQUIRE(DNS_ZONE_VALID(zone)); 16156 16157 return zone->idleout; 16158 } 16159 16160 static void 16161 notify_done(void *arg) { 16162 dns_request_t *request = (dns_request_t *)arg; 16163 dns_notify_t *notify = dns_request_getarg(request); 16164 isc_result_t result; 16165 dns_message_t *message = NULL; 16166 isc_buffer_t buf; 16167 char rcode[128]; 16168 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 16169 16170 REQUIRE(DNS_NOTIFY_VALID(notify)); 16171 16172 isc_buffer_init(&buf, rcode, sizeof(rcode)); 16173 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 16174 dns_message_create(notify->zone->mctx, NULL, NULL, 16175 DNS_MESSAGE_INTENTPARSE, &message); 16176 16177 result = dns_request_getresult(request); 16178 if (result != ISC_R_SUCCESS) { 16179 goto fail; 16180 } 16181 16182 result = dns_request_getresponse(request, message, 16183 DNS_MESSAGEPARSE_PRESERVEORDER); 16184 if (result != ISC_R_SUCCESS) { 16185 goto fail; 16186 } 16187 16188 result = dns_rcode_totext(message->rcode, &buf); 16189 if (result == ISC_R_SUCCESS) { 16190 notify_log(notify->zone, ISC_LOG_DEBUG(3), 16191 "notify response from %s: %.*s", addrbuf, 16192 (int)buf.used, rcode); 16193 } 16194 16195 fail: 16196 dns_message_detach(&message); 16197 16198 if (result == ISC_R_SUCCESS) { 16199 notify_log(notify->zone, ISC_LOG_DEBUG(1), 16200 "notify to %s successful", addrbuf); 16201 } else if (result == ISC_R_SHUTTINGDOWN || result == ISC_R_CANCELED) { 16202 /* just destroy the notify */ 16203 } else if ((notify->flags & DNS_NOTIFY_TCP) == 0) { 16204 notify_log(notify->zone, ISC_LOG_NOTICE, 16205 "notify to %s failed: %s: retrying over TCP", 16206 addrbuf, isc_result_totext(result)); 16207 notify->flags |= DNS_NOTIFY_TCP; 16208 dns_request_destroy(¬ify->request); 16209 notify_send_queue(notify, (notify->flags & DNS_NOTIFY_STARTUP)); 16210 return; 16211 } else if (result == ISC_R_TIMEDOUT) { 16212 notify_log(notify->zone, ISC_LOG_WARNING, 16213 "notify to %s failed: %s: retries exceeded", addrbuf, 16214 isc_result_totext(result)); 16215 } else { 16216 notify_log(notify->zone, ISC_LOG_WARNING, 16217 "notify to %s failed: %s", addrbuf, 16218 isc_result_totext(result)); 16219 } 16220 notify_destroy(notify, false); 16221 } 16222 16223 struct rss { 16224 dns_zone_t *zone; 16225 dns_db_t *db; 16226 uint32_t serial; 16227 ISC_LINK(struct rss) link; 16228 }; 16229 16230 static void 16231 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) { 16232 UNUSED(arg); 16233 dns_zone_log(zone, level, "%s", message); 16234 } 16235 16236 static isc_result_t 16237 dnskey_inuse(dns_zone_t *zone, dns_rdata_t *rdata, isc_mem_t *mctx, 16238 dns_dnsseckeylist_t *keylist, bool *inuse) { 16239 isc_result_t result; 16240 dst_key_t *dstkey = NULL; 16241 16242 result = dns_dnssec_keyfromrdata(dns_zone_getorigin(zone), rdata, mctx, 16243 &dstkey); 16244 if (result != ISC_R_SUCCESS) { 16245 dns_zone_log(zone, ISC_LOG_ERROR, 16246 "dns_dnssec_keyfromrdata() failed: %s", 16247 isc_result_totext(result)); 16248 return result; 16249 } 16250 16251 for (dns_dnsseckey_t *k = ISC_LIST_HEAD(*keylist); k != NULL; 16252 k = ISC_LIST_NEXT(k, link)) 16253 { 16254 if (dst_key_pubcompare(k->key, dstkey, false)) { 16255 *inuse = true; 16256 break; 16257 } 16258 } 16259 16260 dst_key_free(&dstkey); 16261 return ISC_R_SUCCESS; 16262 } 16263 16264 static isc_result_t 16265 cdnskey_inuse(dns_zone_t *zone, dns_rdata_t *rdata, 16266 dns_dnsseckeylist_t *keylist, bool *inuse) { 16267 isc_result_t result; 16268 dns_rdata_cdnskey_t cdnskey; 16269 16270 result = dns_rdata_tostruct(rdata, &cdnskey, NULL); 16271 if (result != ISC_R_SUCCESS) { 16272 dns_zone_log(zone, ISC_LOG_ERROR, 16273 "dns_rdata_tostruct(cdnskey) failed: %s", 16274 isc_result_totext(result)); 16275 return result; 16276 } 16277 16278 for (dns_dnsseckey_t *k = ISC_LIST_HEAD(*keylist); k != NULL; 16279 k = ISC_LIST_NEXT(k, link)) 16280 { 16281 dns_rdata_t cdnskeyrdata = DNS_RDATA_INIT; 16282 unsigned char keybuf[DST_KEY_MAXSIZE]; 16283 16284 result = dns_dnssec_make_dnskey(k->key, keybuf, sizeof(keybuf), 16285 &cdnskeyrdata); 16286 if (result != ISC_R_SUCCESS) { 16287 dns_zone_log(zone, ISC_LOG_ERROR, 16288 "dns_dnssec_make_dnskey() failed: %s", 16289 isc_result_totext(result)); 16290 return result; 16291 } 16292 16293 cdnskeyrdata.type = dns_rdatatype_cdnskey; 16294 if (dns_rdata_compare(rdata, &cdnskeyrdata) == 0) { 16295 *inuse = true; 16296 break; 16297 } 16298 } 16299 16300 return ISC_R_SUCCESS; 16301 } 16302 16303 static isc_result_t 16304 cds_inuse(dns_zone_t *zone, dns_rdata_t *rdata, dns_dnsseckeylist_t *keylist, 16305 bool *inuse) { 16306 isc_result_t result; 16307 dns_rdata_ds_t cds; 16308 16309 result = dns_rdata_tostruct(rdata, &cds, NULL); 16310 if (result != ISC_R_SUCCESS) { 16311 dns_zone_log(zone, ISC_LOG_ERROR, 16312 "dns_rdata_tostruct(cds) failed: %s", 16313 isc_result_totext(result)); 16314 return result; 16315 } 16316 16317 for (dns_dnsseckey_t *k = ISC_LIST_HEAD(*keylist); k != NULL; 16318 k = ISC_LIST_NEXT(k, link)) 16319 { 16320 dns_rdata_t dnskey = DNS_RDATA_INIT; 16321 dns_rdata_t cdsrdata = DNS_RDATA_INIT; 16322 unsigned char keybuf[DST_KEY_MAXSIZE]; 16323 unsigned char cdsbuf[DNS_DS_BUFFERSIZE]; 16324 16325 if (dst_key_id(k->key) != cds.key_tag || 16326 dst_key_alg(k->key) != cds.algorithm) 16327 { 16328 continue; 16329 } 16330 result = dns_dnssec_make_dnskey(k->key, keybuf, sizeof(keybuf), 16331 &dnskey); 16332 if (result != ISC_R_SUCCESS) { 16333 dns_zone_log(zone, ISC_LOG_ERROR, 16334 "dns_dnssec_make_dnskey() failed: %s", 16335 isc_result_totext(result)); 16336 return result; 16337 } 16338 result = dns_ds_buildrdata(dns_zone_getorigin(zone), &dnskey, 16339 cds.digest_type, cdsbuf, &cdsrdata); 16340 if (result != ISC_R_SUCCESS) { 16341 dns_zone_log(zone, ISC_LOG_ERROR, 16342 "dns_ds_buildrdata(keytag=%d, algo=%d, " 16343 "digest=%d) failed: %s", 16344 cds.key_tag, cds.algorithm, 16345 cds.digest_type, 16346 isc_result_totext(result)); 16347 return result; 16348 } 16349 16350 cdsrdata.type = dns_rdatatype_cds; 16351 if (dns_rdata_compare(rdata, &cdsrdata) == 0) { 16352 *inuse = true; 16353 break; 16354 } 16355 } 16356 16357 return ISC_R_SUCCESS; 16358 } 16359 16360 isc_result_t 16361 dns_zone_dnskey_inuse(dns_zone_t *zone, dns_rdata_t *rdata, bool *inuse) { 16362 dns_dnsseckeylist_t keylist; 16363 dns_dnsseckey_t *key = NULL; 16364 isc_result_t result = ISC_R_SUCCESS; 16365 isc_stdtime_t now = isc_stdtime_now(); 16366 isc_mem_t *mctx; 16367 dns_kasp_t *kasp; 16368 dns_keystorelist_t *keystores; 16369 const char *keydir; 16370 16371 REQUIRE(DNS_ZONE_VALID(zone)); 16372 REQUIRE(dns_rdatatype_iskeymaterial(rdata->type)); 16373 16374 mctx = zone->mctx; 16375 16376 ISC_LIST_INIT(keylist); 16377 16378 *inuse = false; 16379 16380 kasp = dns_zone_getkasp(zone); 16381 keydir = dns_zone_getkeydirectory(zone); 16382 keystores = dns_zone_getkeystores(zone); 16383 16384 dns_zone_lock_keyfiles(zone); 16385 result = dns_dnssec_findmatchingkeys(dns_zone_getorigin(zone), kasp, 16386 keydir, keystores, now, mctx, 16387 &keylist); 16388 dns_zone_unlock_keyfiles(zone); 16389 if (result == ISC_R_NOTFOUND) { 16390 return ISC_R_SUCCESS; 16391 } else if (result != ISC_R_SUCCESS) { 16392 dns_zone_log(zone, ISC_LOG_ERROR, 16393 "dns_dnssec_findmatchingkeys() failed: %s", 16394 isc_result_totext(result)); 16395 return result; 16396 } 16397 16398 switch (rdata->type) { 16399 case dns_rdatatype_dnskey: 16400 result = dnskey_inuse(zone, rdata, mctx, &keylist, inuse); 16401 break; 16402 case dns_rdatatype_cdnskey: 16403 result = cdnskey_inuse(zone, rdata, &keylist, inuse); 16404 break; 16405 case dns_rdatatype_cds: 16406 result = cds_inuse(zone, rdata, &keylist, inuse); 16407 break; 16408 default: 16409 UNREACHABLE(); 16410 break; 16411 } 16412 16413 while (!ISC_LIST_EMPTY(keylist)) { 16414 key = ISC_LIST_HEAD(keylist); 16415 ISC_LIST_UNLINK(keylist, key, link); 16416 dns_dnsseckey_destroy(mctx, &key); 16417 } 16418 return result; 16419 } 16420 16421 static isc_result_t 16422 sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal, 16423 uint32_t start, uint32_t end, dns_difftuple_t **soatuplep, 16424 dns_diff_t *diff) { 16425 isc_result_t result; 16426 dns_difftuple_t *tuple = NULL; 16427 dns_diffop_t op = DNS_DIFFOP_ADD; 16428 int n_soa = 0; 16429 16430 REQUIRE(soatuplep != NULL); 16431 16432 if (start == end) { 16433 return DNS_R_UNCHANGED; 16434 } 16435 16436 CHECK(dns_journal_iter_init(journal, start, end, NULL)); 16437 for (result = dns_journal_first_rr(journal); result == ISC_R_SUCCESS; 16438 result = dns_journal_next_rr(journal)) 16439 { 16440 dns_name_t *name = NULL; 16441 uint32_t ttl; 16442 dns_rdata_t *rdata = NULL; 16443 dns_journal_current_rr(journal, &name, &ttl, &rdata); 16444 16445 if (rdata->type == dns_rdatatype_soa) { 16446 n_soa++; 16447 if (n_soa == 2) { 16448 /* 16449 * Save the latest raw SOA record. 16450 */ 16451 if (*soatuplep != NULL) { 16452 dns_difftuple_free(soatuplep); 16453 } 16454 CHECK(dns_difftuple_create( 16455 diff->mctx, DNS_DIFFOP_ADD, name, ttl, 16456 rdata, soatuplep)); 16457 } 16458 if (n_soa == 3) { 16459 n_soa = 1; 16460 } 16461 continue; 16462 } 16463 16464 /* Sanity. */ 16465 if (n_soa == 0) { 16466 dns_zone_log(raw, ISC_LOG_ERROR, 16467 "corrupt journal file: '%s'\n", 16468 raw->journal); 16469 return ISC_R_FAILURE; 16470 } 16471 16472 if (zone->privatetype != 0 && rdata->type == zone->privatetype) 16473 { 16474 continue; 16475 } 16476 16477 /* 16478 * Skip DNSSEC records that BIND maintains with inline-signing. 16479 */ 16480 if (rdata->type == dns_rdatatype_nsec || 16481 rdata->type == dns_rdatatype_rrsig || 16482 rdata->type == dns_rdatatype_nsec3 || 16483 rdata->type == dns_rdatatype_nsec3param) 16484 { 16485 continue; 16486 } 16487 /* 16488 * Allow DNSKEY, CDNSKEY, CDS because users should be able to 16489 * update the zone with these records from a different provider, 16490 * but skip records that are under our control. 16491 */ 16492 if (dns_rdatatype_iskeymaterial(rdata->type)) { 16493 bool inuse = false; 16494 isc_result_t r = dns_zone_dnskey_inuse(zone, rdata, 16495 &inuse); 16496 if (r == ISC_R_SUCCESS && inuse) { 16497 continue; 16498 } 16499 } 16500 16501 op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD; 16502 16503 CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata, 16504 &tuple)); 16505 dns_diff_appendminimal(diff, &tuple); 16506 } 16507 if (result == ISC_R_NOMORE) { 16508 result = ISC_R_SUCCESS; 16509 } 16510 16511 failure: 16512 return result; 16513 } 16514 16515 /* 16516 * Filter the key material preserving TTL changes. If kasp in effect honour the 16517 * existing ttl. The lists returned by sync_secure_db/dns_db_diffx should be 16518 * DNSSEC RRset order so we can process 'del' and 'add' in parallel rather than 16519 * searching for TTL only changes first and processing them, then checking the 16520 * 'in use' status on a subsequent pass. 16521 */ 16522 16523 static void 16524 filter_keymaterial(dns_zone_t *zone, dns_difftuplelist_t *del, 16525 dns_difftuplelist_t *add, bool kasp, dns_ttl_t ttl) { 16526 dns_difftuple_t *deltuple = ISC_LIST_HEAD(*del); 16527 dns_difftuple_t *addtuple = ISC_LIST_HEAD(*add); 16528 isc_result_t result; 16529 16530 while (deltuple != NULL || addtuple != NULL) { 16531 dns_difftuple_t *delnext = NULL, *addnext = NULL; 16532 bool inuse = false; 16533 if (deltuple != NULL) { 16534 delnext = ISC_LIST_NEXT(deltuple, link); 16535 } 16536 if (addtuple != NULL) { 16537 addnext = ISC_LIST_NEXT(addtuple, link); 16538 } 16539 if (deltuple != NULL && addtuple != NULL) { 16540 int n = dns_rdata_compare(&deltuple->rdata, 16541 &addtuple->rdata); 16542 if (n == 0) { 16543 /* 16544 * If the rdata is equal then the only 16545 * difference will be a TTL change. 16546 */ 16547 if (kasp) { 16548 /* TTL is managed by dnssec-policy */ 16549 ISC_LIST_UNLINK(*del, deltuple, link); 16550 dns_difftuple_free(&deltuple); 16551 ISC_LIST_UNLINK(*add, addtuple, link); 16552 dns_difftuple_free(&addtuple); 16553 } 16554 deltuple = delnext; 16555 addtuple = addnext; 16556 continue; 16557 } 16558 if (n < 0) { 16559 goto checkdel; 16560 } 16561 goto checkadd; 16562 } else if (deltuple != NULL) { 16563 checkdel: 16564 result = dns_zone_dnskey_inuse(zone, &deltuple->rdata, 16565 &inuse); 16566 if (result == ISC_R_SUCCESS && inuse) { 16567 ISC_LIST_UNLINK(*del, deltuple, link); 16568 dns_difftuple_free(&deltuple); 16569 } 16570 deltuple = delnext; 16571 } else { 16572 checkadd: 16573 result = dns_zone_dnskey_inuse(zone, &addtuple->rdata, 16574 &inuse); 16575 if (result == ISC_R_SUCCESS && inuse) { 16576 ISC_LIST_UNLINK(*add, addtuple, link); 16577 dns_difftuple_free(&addtuple); 16578 } else if (kasp) { 16579 addtuple->ttl = ttl; 16580 } 16581 addtuple = addnext; 16582 } 16583 } 16584 } 16585 16586 static isc_result_t 16587 sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb, 16588 dns_dbversion_t *secver, dns_difftuple_t **soatuple, 16589 dns_diff_t *diff) { 16590 isc_result_t result; 16591 dns_db_t *rawdb = NULL; 16592 dns_dbversion_t *rawver = NULL; 16593 dns_difftuple_t *tuple = NULL, *next; 16594 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL; 16595 dns_rdata_soa_t oldsoa, newsoa; 16596 dns_difftuplelist_t add = ISC_LIST_INITIALIZER; 16597 dns_difftuplelist_t del = ISC_LIST_INITIALIZER; 16598 dns_difftuplelist_t keyadd = ISC_LIST_INITIALIZER; 16599 dns_difftuplelist_t keydel = ISC_LIST_INITIALIZER; 16600 dns_difftuplelist_t ckeyadd = ISC_LIST_INITIALIZER; 16601 dns_difftuplelist_t ckeydel = ISC_LIST_INITIALIZER; 16602 dns_difftuplelist_t cdsadd = ISC_LIST_INITIALIZER; 16603 dns_difftuplelist_t cdsdel = ISC_LIST_INITIALIZER; 16604 dns_kasp_t *kasp = NULL; 16605 dns_ttl_t keyttl = 0, ckeyttl = 0, cdsttl = 0; 16606 16607 REQUIRE(DNS_ZONE_VALID(seczone)); 16608 REQUIRE(soatuple != NULL && *soatuple == NULL); 16609 16610 if (!seczone->sourceserialset) { 16611 return DNS_R_UNCHANGED; 16612 } 16613 16614 dns_db_attach(raw->db, &rawdb); 16615 dns_db_currentversion(rawdb, &rawver); 16616 result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL); 16617 dns_db_closeversion(rawdb, &rawver, false); 16618 dns_db_detach(&rawdb); 16619 16620 if (result != ISC_R_SUCCESS) { 16621 return result; 16622 } 16623 16624 /* 16625 * If kasp is in effect honour the existing DNSKEY, CDNSKEY and CDS 16626 * TTLs. 16627 */ 16628 kasp = seczone->kasp; 16629 if (kasp != NULL) { 16630 dns_rdataset_t rdataset; 16631 dns_dbnode_t *node = NULL; 16632 dns_ttl_t ttl = dns_kasp_dnskeyttl(kasp); 16633 16634 dns_rdataset_init(&rdataset); 16635 16636 result = dns_db_getoriginnode(secdb, &node); 16637 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16638 16639 result = dns_db_findrdataset( 16640 secdb, node, secver, dns_rdatatype_dnskey, 16641 dns_rdatatype_none, 0, &rdataset, NULL); 16642 keyttl = (result == ISC_R_SUCCESS) ? rdataset.ttl : ttl; 16643 if (dns_rdataset_isassociated(&rdataset)) { 16644 dns_rdataset_disassociate(&rdataset); 16645 } 16646 16647 result = dns_db_findrdataset( 16648 secdb, node, secver, dns_rdatatype_cdnskey, 16649 dns_rdatatype_none, 0, &rdataset, NULL); 16650 ckeyttl = (result == ISC_R_SUCCESS) ? rdataset.ttl : ttl; 16651 if (dns_rdataset_isassociated(&rdataset)) { 16652 dns_rdataset_disassociate(&rdataset); 16653 } 16654 16655 result = dns_db_findrdataset( 16656 secdb, node, secver, dns_rdatatype_cds, 16657 dns_rdatatype_none, 0, &rdataset, NULL); 16658 cdsttl = (result == ISC_R_SUCCESS) ? rdataset.ttl : ttl; 16659 if (dns_rdataset_isassociated(&rdataset)) { 16660 dns_rdataset_disassociate(&rdataset); 16661 } 16662 dns_db_detachnode(secdb, &node); 16663 } 16664 16665 for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; tuple = next) { 16666 dns_difftuplelist_t *al = &add, *dl = &del; 16667 16668 next = ISC_LIST_NEXT(tuple, link); 16669 16670 /* 16671 * Skip DNSSEC records that BIND maintains with inline-signing. 16672 */ 16673 if (tuple->rdata.type == dns_rdatatype_nsec || 16674 tuple->rdata.type == dns_rdatatype_rrsig || 16675 tuple->rdata.type == dns_rdatatype_nsec3 || 16676 tuple->rdata.type == dns_rdatatype_nsec3param) 16677 { 16678 ISC_LIST_UNLINK(diff->tuples, tuple, link); 16679 dns_difftuple_free(&tuple); 16680 continue; 16681 } 16682 16683 /* 16684 * Apex DNSKEY, CDNSKEY and CDS need special processing so 16685 * split them out. 16686 */ 16687 if (dns_rdatatype_iskeymaterial(tuple->rdata.type) && 16688 dns_name_equal(&tuple->name, &seczone->origin)) 16689 { 16690 switch (tuple->rdata.type) { 16691 case dns_rdatatype_dnskey: 16692 al = &keyadd; 16693 dl = &keydel; 16694 break; 16695 case dns_rdatatype_cdnskey: 16696 al = &ckeyadd; 16697 dl = &ckeydel; 16698 break; 16699 case dns_rdatatype_cds: 16700 al = &cdsadd; 16701 dl = &cdsdel; 16702 break; 16703 default: 16704 UNREACHABLE(); 16705 } 16706 } 16707 16708 if (tuple->rdata.type == dns_rdatatype_soa) { 16709 if (tuple->op == DNS_DIFFOP_DEL) { 16710 INSIST(oldtuple == NULL); 16711 oldtuple = tuple; 16712 } 16713 if (tuple->op == DNS_DIFFOP_ADD) { 16714 INSIST(newtuple == NULL); 16715 newtuple = tuple; 16716 } 16717 } 16718 16719 /* 16720 * Split into deletions and additions. 16721 */ 16722 ISC_LIST_UNLINK(diff->tuples, tuple, link); 16723 switch (tuple->op) { 16724 case DNS_DIFFOP_DEL: 16725 case DNS_DIFFOP_DELRESIGN: 16726 ISC_LIST_APPEND(*dl, tuple, link); 16727 break; 16728 case DNS_DIFFOP_ADD: 16729 case DNS_DIFFOP_ADDRESIGN: 16730 ISC_LIST_APPEND(*al, tuple, link); 16731 break; 16732 default: 16733 UNREACHABLE(); 16734 } 16735 } 16736 16737 if (oldtuple != NULL && newtuple != NULL) { 16738 result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL); 16739 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16740 16741 result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL); 16742 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16743 16744 /* 16745 * If the SOA records are the same except for the serial 16746 * remove them from the diff. 16747 */ 16748 if (oldtuple->ttl == newtuple->ttl && 16749 oldsoa.refresh == newsoa.refresh && 16750 oldsoa.retry == newsoa.retry && 16751 oldsoa.minimum == newsoa.minimum && 16752 oldsoa.expire == newsoa.expire && 16753 dns_name_equal(&oldsoa.origin, &newsoa.origin) && 16754 dns_name_equal(&oldsoa.contact, &newsoa.contact)) 16755 { 16756 ISC_LIST_UNLINK(del, oldtuple, link); 16757 dns_difftuple_free(&oldtuple); 16758 ISC_LIST_UNLINK(add, newtuple, link); 16759 dns_difftuple_free(&newtuple); 16760 } 16761 } 16762 16763 /* 16764 * Filter out keys we manage but still allow TTL changes. 16765 */ 16766 filter_keymaterial(seczone, &keydel, &keyadd, kasp != NULL, keyttl); 16767 filter_keymaterial(seczone, &ckeydel, &ckeyadd, kasp != NULL, ckeyttl); 16768 filter_keymaterial(seczone, &cdsdel, &cdsadd, kasp != NULL, cdsttl); 16769 16770 /* 16771 * Rebuild the diff now that we have filtered it 16772 */ 16773 ISC_LIST_APPENDLIST(diff->tuples, del, link); 16774 ISC_LIST_APPENDLIST(diff->tuples, keydel, link); 16775 ISC_LIST_APPENDLIST(diff->tuples, ckeydel, link); 16776 ISC_LIST_APPENDLIST(diff->tuples, cdsdel, link); 16777 ISC_LIST_APPENDLIST(diff->tuples, add, link); 16778 ISC_LIST_APPENDLIST(diff->tuples, keyadd, link); 16779 ISC_LIST_APPENDLIST(diff->tuples, ckeyadd, link); 16780 ISC_LIST_APPENDLIST(diff->tuples, cdsadd, link); 16781 16782 if (ISC_LIST_EMPTY(diff->tuples)) { 16783 return DNS_R_UNCHANGED; 16784 } 16785 16786 /* 16787 * If there are still SOA records in the diff they can now be removed 16788 * saving the new SOA record. 16789 */ 16790 if (oldtuple != NULL) { 16791 ISC_LIST_UNLINK(diff->tuples, oldtuple, link); 16792 dns_difftuple_free(&oldtuple); 16793 } 16794 16795 if (newtuple != NULL) { 16796 ISC_LIST_UNLINK(diff->tuples, newtuple, link); 16797 *soatuple = newtuple; 16798 } 16799 16800 return ISC_R_SUCCESS; 16801 } 16802 16803 static void 16804 receive_secure_serial(void *arg) { 16805 struct rss *rss = (struct rss *)arg; 16806 dns_zone_t *zone = rss->zone; 16807 isc_result_t result = ISC_R_SUCCESS; 16808 dns_journal_t *rjournal = NULL; 16809 dns_journal_t *sjournal = NULL; 16810 uint32_t start, end = rss->serial; 16811 dns_difftuple_t *tuple = NULL, *soatuple = NULL; 16812 dns_update_log_t log = { update_log_cb, NULL }; 16813 uint32_t newserial = 0, desired = 0; 16814 isc_time_t timenow; 16815 int level = ISC_LOG_ERROR; 16816 16817 ENTER; 16818 16819 LOCK_ZONE(zone); 16820 16821 /* 16822 * The receive_secure_serial() is loop-serialized for the zone. Make 16823 * sure there's no processing currently running. 16824 */ 16825 16826 INSIST(zone->rss == NULL || zone->rss == rss); 16827 16828 if (zone->rss != NULL) { 16829 INSIST(zone->rss == rss); 16830 UNLOCK_ZONE(zone); 16831 } else { 16832 zone->rss = rss; 16833 dns_diff_init(zone->mctx, &zone->rss_diff); 16834 16835 /* 16836 * zone->db may be NULL, if the load from disk failed. 16837 */ 16838 result = ISC_R_SUCCESS; 16839 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 16840 if (zone->db != NULL) { 16841 dns_db_attach(zone->db, &zone->rss_db); 16842 } else { 16843 result = ISC_R_FAILURE; 16844 } 16845 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 16846 16847 if (result == ISC_R_SUCCESS && zone->raw != NULL) { 16848 dns_zone_attach(zone->raw, &zone->rss_raw); 16849 } else { 16850 result = ISC_R_FAILURE; 16851 } 16852 16853 UNLOCK_ZONE(zone); 16854 16855 CHECK(result); 16856 16857 /* 16858 * We first attempt to sync the raw zone to the secure zone 16859 * by using the raw zone's journal, applying all the deltas 16860 * from the latest source-serial of the secure zone up to 16861 * the current serial number of the raw zone. 16862 * 16863 * If that fails, then we'll fall back to a direct comparison 16864 * between raw and secure zones. 16865 */ 16866 CHECK(dns_journal_open(zone->rss_raw->mctx, 16867 zone->rss_raw->journal, 16868 DNS_JOURNAL_WRITE, &rjournal)); 16869 16870 result = dns_journal_open(zone->mctx, zone->journal, 16871 DNS_JOURNAL_READ, &sjournal); 16872 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 16873 goto failure; 16874 } 16875 16876 if (!dns_journal_get_sourceserial(rjournal, &start)) { 16877 start = dns_journal_first_serial(rjournal); 16878 dns_journal_set_sourceserial(rjournal, start); 16879 } 16880 if (sjournal != NULL) { 16881 uint32_t serial; 16882 /* 16883 * We read the secure journal first, if that 16884 * exists use its value provided it is greater 16885 * that from the raw journal. 16886 */ 16887 if (dns_journal_get_sourceserial(sjournal, &serial)) { 16888 if (isc_serial_gt(serial, start)) { 16889 start = serial; 16890 } 16891 } 16892 dns_journal_destroy(&sjournal); 16893 } 16894 16895 dns_db_currentversion(zone->rss_db, &zone->rss_oldver); 16896 CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver)); 16897 16898 /* 16899 * Try to apply diffs from the raw zone's journal to the secure 16900 * zone. If that fails, we recover by syncing up the databases 16901 * directly. 16902 */ 16903 result = sync_secure_journal(zone, zone->rss_raw, rjournal, 16904 start, end, &soatuple, 16905 &zone->rss_diff); 16906 if (result == DNS_R_UNCHANGED) { 16907 goto failure; 16908 } else if (result != ISC_R_SUCCESS) { 16909 CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db, 16910 zone->rss_oldver, &soatuple, 16911 &zone->rss_diff)); 16912 } 16913 16914 CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db, 16915 zone->rss_newver)); 16916 16917 if (soatuple != NULL) { 16918 uint32_t oldserial; 16919 16920 CHECK(dns_db_createsoatuple( 16921 zone->rss_db, zone->rss_oldver, 16922 zone->rss_diff.mctx, DNS_DIFFOP_DEL, &tuple)); 16923 oldserial = dns_soa_getserial(&tuple->rdata); 16924 newserial = desired = 16925 dns_soa_getserial(&soatuple->rdata); 16926 if (!isc_serial_gt(newserial, oldserial)) { 16927 newserial = oldserial + 1; 16928 if (newserial == 0) { 16929 newserial++; 16930 } 16931 dns_soa_setserial(newserial, &soatuple->rdata); 16932 } 16933 CHECK(do_one_tuple(&tuple, zone->rss_db, 16934 zone->rss_newver, &zone->rss_diff)); 16935 CHECK(do_one_tuple(&soatuple, zone->rss_db, 16936 zone->rss_newver, &zone->rss_diff)); 16937 } else { 16938 CHECK(update_soa_serial(zone, zone->rss_db, 16939 zone->rss_newver, 16940 &zone->rss_diff, zone->mctx, 16941 zone->updatemethod)); 16942 } 16943 } 16944 result = dns_update_signaturesinc( 16945 &log, zone, zone->rss_db, zone->rss_oldver, zone->rss_newver, 16946 &zone->rss_diff, zone->sigvalidityinterval, &zone->rss_state); 16947 if (result == DNS_R_CONTINUE) { 16948 if (rjournal != NULL) { 16949 dns_journal_destroy(&rjournal); 16950 } 16951 isc_async_run(zone->loop, receive_secure_serial, rss); 16952 return; 16953 } 16954 16955 /* 16956 * If something went wrong while trying to update the secure zone and 16957 * the latter was already signed before, do not apply raw zone deltas 16958 * to it as that would break existing DNSSEC signatures. However, if 16959 * the secure zone was not yet signed (e.g. because no signing keys 16960 * were created for it), commence applying raw zone deltas to it so 16961 * that contents of the raw zone and the secure zone are kept in sync. 16962 */ 16963 if (result != ISC_R_SUCCESS && dns_db_issecure(zone->rss_db)) { 16964 goto failure; 16965 } 16966 16967 if (rjournal == NULL) { 16968 CHECK(dns_journal_open(zone->rss_raw->mctx, 16969 zone->rss_raw->journal, 16970 DNS_JOURNAL_WRITE, &rjournal)); 16971 } 16972 CHECK(zone_journal(zone, &zone->rss_diff, &end, 16973 "receive_secure_serial")); 16974 16975 dns_journal_set_sourceserial(rjournal, end); 16976 dns_journal_commit(rjournal); 16977 16978 LOCK_ZONE(zone); 16979 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 16980 16981 zone->sourceserial = end; 16982 zone->sourceserialset = true; 16983 zone_needdump(zone, DNS_DUMP_DELAY); 16984 16985 /* 16986 * Set resign time to make sure it is set to the earliest 16987 * signature expiration. 16988 */ 16989 set_resigntime(zone); 16990 timenow = isc_time_now(); 16991 zone_settimer(zone, &timenow); 16992 UNLOCK_ZONE(zone); 16993 16994 dns_db_closeversion(zone->rss_db, &zone->rss_oldver, false); 16995 dns_db_closeversion(zone->rss_db, &zone->rss_newver, true); 16996 16997 if (newserial != 0) { 16998 dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)", 16999 newserial, desired); 17000 } 17001 17002 failure: 17003 isc_mem_put(zone->mctx, rss, sizeof(*rss)); 17004 zone->rss = NULL; 17005 17006 if (zone->rss_raw != NULL) { 17007 dns_zone_detach(&zone->rss_raw); 17008 } 17009 if (result != ISC_R_SUCCESS) { 17010 LOCK_ZONE(zone); 17011 set_resigntime(zone); 17012 timenow = isc_time_now(); 17013 zone_settimer(zone, &timenow); 17014 UNLOCK_ZONE(zone); 17015 if (result == DNS_R_UNCHANGED) { 17016 level = ISC_LOG_INFO; 17017 } 17018 dns_zone_log(zone, level, "receive_secure_serial: %s", 17019 isc_result_totext(result)); 17020 } 17021 if (tuple != NULL) { 17022 dns_difftuple_free(&tuple); 17023 } 17024 if (soatuple != NULL) { 17025 dns_difftuple_free(&soatuple); 17026 } 17027 if (zone->rss_db != NULL) { 17028 if (zone->rss_oldver != NULL) { 17029 dns_db_closeversion(zone->rss_db, &zone->rss_oldver, 17030 false); 17031 } 17032 if (zone->rss_newver != NULL) { 17033 dns_db_closeversion(zone->rss_db, &zone->rss_newver, 17034 false); 17035 } 17036 dns_db_detach(&zone->rss_db); 17037 } 17038 INSIST(zone->rss_oldver == NULL); 17039 INSIST(zone->rss_newver == NULL); 17040 if (rjournal != NULL) { 17041 dns_journal_destroy(&rjournal); 17042 } 17043 dns_diff_clear(&zone->rss_diff); 17044 17045 dns_zone_idetach(&zone); 17046 } 17047 17048 static isc_result_t 17049 zone_send_secureserial(dns_zone_t *zone, uint32_t serial) { 17050 struct rss *rss = NULL; 17051 17052 rss = isc_mem_get(zone->secure->mctx, sizeof(*rss)); 17053 *rss = (struct rss){ 17054 .serial = serial, 17055 .link = ISC_LINK_INITIALIZER, 17056 }; 17057 17058 INSIST(LOCKED_ZONE(zone->secure)); 17059 zone_iattach(zone->secure, &rss->zone); 17060 isc_async_run(zone->secure->loop, receive_secure_serial, rss); 17061 17062 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); 17063 return ISC_R_SUCCESS; 17064 } 17065 17066 static isc_result_t 17067 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 17068 dns_name_t *name, dns_rdataset_t *rdataset, uint32_t oldserial) { 17069 dns_rdata_soa_t soa; 17070 dns_rdata_t rdata = DNS_RDATA_INIT; 17071 dns_rdatalist_t temprdatalist; 17072 dns_rdataset_t temprdataset; 17073 isc_buffer_t b; 17074 isc_result_t result; 17075 unsigned char buf[DNS_SOA_BUFFERSIZE]; 17076 17077 result = dns_rdataset_first(rdataset); 17078 RUNTIME_CHECK(result == ISC_R_SUCCESS); 17079 dns_rdataset_current(rdataset, &rdata); 17080 result = dns_rdata_tostruct(&rdata, &soa, NULL); 17081 RUNTIME_CHECK(result == ISC_R_SUCCESS); 17082 17083 if (isc_serial_gt(soa.serial, oldserial)) { 17084 return dns_db_addrdataset(db, node, version, 0, rdataset, 0, 17085 NULL); 17086 } 17087 /* 17088 * Always bump the serial. 17089 */ 17090 oldserial++; 17091 if (oldserial == 0) { 17092 oldserial++; 17093 } 17094 soa.serial = oldserial; 17095 17096 /* 17097 * Construct a replacement rdataset. 17098 */ 17099 dns_rdata_reset(&rdata); 17100 isc_buffer_init(&b, buf, sizeof(buf)); 17101 result = dns_rdata_fromstruct(&rdata, rdataset->rdclass, 17102 dns_rdatatype_soa, &soa, &b); 17103 RUNTIME_CHECK(result == ISC_R_SUCCESS); 17104 dns_rdatalist_init(&temprdatalist); 17105 temprdatalist.rdclass = rdata.rdclass; 17106 temprdatalist.type = rdata.type; 17107 temprdatalist.ttl = rdataset->ttl; 17108 ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link); 17109 17110 dns_rdataset_init(&temprdataset); 17111 dns_rdatalist_tordataset(&temprdatalist, &temprdataset); 17112 17113 dns_rdataset_getownercase(rdataset, name); 17114 dns_rdataset_setownercase(&temprdataset, name); 17115 return dns_db_addrdataset(db, node, version, 0, &temprdataset, 0, NULL); 17116 } 17117 17118 /* 17119 * This function should populate an nsec3paramlist_t with the 17120 * nsecparam_t data from a zone. 17121 */ 17122 static isc_result_t 17123 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) { 17124 isc_result_t result; 17125 dns_dbnode_t *node = NULL; 17126 dns_rdataset_t rdataset, prdataset; 17127 dns_dbversion_t *version = NULL; 17128 nsec3param_t *nsec3param = NULL; 17129 nsec3param_t *nsec3p = NULL; 17130 nsec3param_t *next; 17131 dns_db_t *db = NULL; 17132 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 17133 17134 REQUIRE(DNS_ZONE_VALID(zone)); 17135 REQUIRE(nsec3list != NULL); 17136 REQUIRE(ISC_LIST_EMPTY(*nsec3list)); 17137 17138 dns_rdataset_init(&rdataset); 17139 dns_rdataset_init(&prdataset); 17140 17141 dns_db_attach(zone->db, &db); 17142 CHECK(dns_db_getoriginnode(db, &node)); 17143 17144 dns_db_currentversion(db, &version); 17145 result = dns_db_findrdataset(db, node, version, 17146 dns_rdatatype_nsec3param, 17147 dns_rdatatype_none, 0, &rdataset, NULL); 17148 17149 if (result != ISC_R_SUCCESS) { 17150 goto getprivate; 17151 } 17152 17153 /* 17154 * Walk nsec3param rdataset making a list of parameters (note that 17155 * multiple simultaneous nsec3 chains are annoyingly legal -- this 17156 * is why we use an nsec3list, even though we will usually only 17157 * have one). 17158 */ 17159 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 17160 result = dns_rdataset_next(&rdataset)) 17161 { 17162 dns_rdata_t rdata = DNS_RDATA_INIT; 17163 dns_rdata_t private = DNS_RDATA_INIT; 17164 17165 dns_rdataset_current(&rdataset, &rdata); 17166 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17167 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 17168 "looping through nsec3param data"); 17169 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t)); 17170 ISC_LINK_INIT(nsec3param, link); 17171 17172 /* 17173 * now transfer the data from the rdata to 17174 * the nsec3param 17175 */ 17176 dns_nsec3param_toprivate(&rdata, &private, zone->privatetype, 17177 nsec3param->data, 17178 sizeof(nsec3param->data)); 17179 nsec3param->length = private.length; 17180 ISC_LIST_APPEND(*nsec3list, nsec3param, link); 17181 } 17182 17183 getprivate: 17184 result = dns_db_findrdataset(db, node, version, zone->privatetype, 17185 dns_rdatatype_none, 0, &prdataset, NULL); 17186 if (result != ISC_R_SUCCESS) { 17187 goto done; 17188 } 17189 17190 /* 17191 * walk private type records, converting them to nsec3 parameters 17192 * using dns_nsec3param_fromprivate(), do the right thing based on 17193 * CREATE and REMOVE flags 17194 */ 17195 for (result = dns_rdataset_first(&prdataset); result == ISC_R_SUCCESS; 17196 result = dns_rdataset_next(&prdataset)) 17197 { 17198 dns_rdata_t rdata = DNS_RDATA_INIT; 17199 dns_rdata_t private = DNS_RDATA_INIT; 17200 17201 dns_rdataset_current(&prdataset, &private); 17202 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17203 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 17204 "looping through nsec3param private data"); 17205 17206 /* 17207 * Do we have a valid private record? 17208 */ 17209 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 17210 sizeof(buf))) 17211 { 17212 continue; 17213 } 17214 17215 /* 17216 * Remove any NSEC3PARAM records scheduled to be removed. 17217 */ 17218 if (NSEC3REMOVE(rdata.data[1])) { 17219 /* 17220 * Zero out the flags. 17221 */ 17222 rdata.data[1] = 0; 17223 17224 for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; 17225 nsec3p = next) 17226 { 17227 next = ISC_LIST_NEXT(nsec3p, link); 17228 17229 if (nsec3p->length == rdata.length + 1 && 17230 memcmp(rdata.data, nsec3p->data + 1, 17231 nsec3p->length - 1) == 0) 17232 { 17233 ISC_LIST_UNLINK(*nsec3list, nsec3p, 17234 link); 17235 isc_mem_put(zone->mctx, nsec3p, 17236 sizeof(nsec3param_t)); 17237 } 17238 } 17239 continue; 17240 } 17241 17242 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t)); 17243 ISC_LINK_INIT(nsec3param, link); 17244 17245 /* 17246 * Copy the remaining private records so the nsec/nsec3 17247 * chain gets created. 17248 */ 17249 INSIST(private.length <= sizeof(nsec3param->data)); 17250 memmove(nsec3param->data, private.data, private.length); 17251 nsec3param->length = private.length; 17252 ISC_LIST_APPEND(*nsec3list, nsec3param, link); 17253 } 17254 17255 done: 17256 if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) { 17257 result = ISC_R_SUCCESS; 17258 } 17259 17260 failure: 17261 if (node != NULL) { 17262 dns_db_detachnode(db, &node); 17263 } 17264 if (version != NULL) { 17265 dns_db_closeversion(db, &version, false); 17266 } 17267 if (db != NULL) { 17268 dns_db_detach(&db); 17269 } 17270 if (dns_rdataset_isassociated(&rdataset)) { 17271 dns_rdataset_disassociate(&rdataset); 17272 } 17273 if (dns_rdataset_isassociated(&prdataset)) { 17274 dns_rdataset_disassociate(&prdataset); 17275 } 17276 return result; 17277 } 17278 17279 /* 17280 * Populate new zone db with private type records found by save_nsec3param(). 17281 */ 17282 static isc_result_t 17283 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 17284 nsec3paramlist_t *nsec3list) { 17285 isc_result_t result = ISC_R_SUCCESS; 17286 dns_diff_t diff; 17287 dns_rdata_t rdata; 17288 nsec3param_t *nsec3p = NULL; 17289 nsec3param_t *next; 17290 17291 REQUIRE(DNS_ZONE_VALID(zone)); 17292 REQUIRE(!ISC_LIST_EMPTY(*nsec3list)); 17293 17294 dns_diff_init(zone->mctx, &diff); 17295 17296 /* 17297 * Loop through the list of private-type records, set the INITIAL 17298 * and CREATE flags, and the add the record to the apex of the tree 17299 * in db. 17300 */ 17301 for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; nsec3p = next) 17302 { 17303 next = ISC_LIST_NEXT(nsec3p, link); 17304 dns_rdata_init(&rdata); 17305 nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL; 17306 rdata.length = nsec3p->length; 17307 rdata.data = nsec3p->data; 17308 rdata.type = zone->privatetype; 17309 rdata.rdclass = zone->rdclass; 17310 result = update_one_rr(db, version, &diff, DNS_DIFFOP_ADD, 17311 &zone->origin, 0, &rdata); 17312 if (result != ISC_R_SUCCESS) { 17313 break; 17314 } 17315 } 17316 17317 dns_diff_clear(&diff); 17318 return result; 17319 } 17320 17321 static isc_result_t 17322 copy_non_dnssec_records(dns_db_t *db, dns_db_t *version, dns_db_t *rawdb, 17323 dns_dbiterator_t *dbiterator, unsigned int *oldserial) { 17324 dns_dbnode_t *rawnode = NULL, *node = NULL; 17325 dns_fixedname_t fixed; 17326 dns_name_t *name = dns_fixedname_initname(&fixed); 17327 dns_rdataset_t rdataset; 17328 dns_rdatasetiter_t *rdsit = NULL; 17329 isc_result_t result; 17330 17331 result = dns_dbiterator_current(dbiterator, &rawnode, name); 17332 if (result != ISC_R_SUCCESS) { 17333 return ISC_R_SUCCESS; 17334 } 17335 17336 dns_dbiterator_pause(dbiterator); 17337 17338 result = dns_db_findnode(db, name, true, &node); 17339 if (result != ISC_R_SUCCESS) { 17340 goto cleanup; 17341 } 17342 17343 result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, 0, &rdsit); 17344 if (result != ISC_R_SUCCESS) { 17345 goto cleanup; 17346 } 17347 17348 dns_rdataset_init(&rdataset); 17349 17350 for (result = dns_rdatasetiter_first(rdsit); result == ISC_R_SUCCESS; 17351 result = dns_rdatasetiter_next(rdsit)) 17352 { 17353 dns_rdatasetiter_current(rdsit, &rdataset); 17354 if (rdataset.type == dns_rdatatype_nsec || 17355 rdataset.type == dns_rdatatype_rrsig || 17356 rdataset.type == dns_rdatatype_nsec3 || 17357 rdataset.type == dns_rdatatype_nsec3param) 17358 { 17359 dns_rdataset_disassociate(&rdataset); 17360 continue; 17361 } 17362 /* 17363 * Allow DNSKEY, CDNSKEY, CDS because users should be able to 17364 * update the zone with these records from a different provider, 17365 * and thus they may exist in the raw version of the zone. 17366 */ 17367 17368 if (rdataset.type == dns_rdatatype_soa && oldserial != NULL) { 17369 result = checkandaddsoa(db, node, version, name, 17370 &rdataset, *oldserial); 17371 } else { 17372 result = dns_db_addrdataset(db, node, version, 0, 17373 &rdataset, 0, NULL); 17374 } 17375 dns_rdataset_disassociate(&rdataset); 17376 if (result != ISC_R_SUCCESS) { 17377 goto cleanup; 17378 } 17379 } 17380 if (result == ISC_R_NOMORE) { 17381 result = ISC_R_SUCCESS; 17382 } 17383 17384 cleanup: 17385 if (rdsit != NULL) { 17386 dns_rdatasetiter_destroy(&rdsit); 17387 } 17388 if (rawnode) { 17389 dns_db_detachnode(rawdb, &rawnode); 17390 } 17391 if (node) { 17392 dns_db_detachnode(db, &node); 17393 } 17394 return result; 17395 } 17396 17397 static void 17398 receive_secure_db(void *arg) { 17399 isc_result_t result; 17400 struct rss *rss = (struct rss *)arg; 17401 dns_zone_t *zone = rss->zone; 17402 dns_db_t *rawdb = rss->db, *db = NULL; 17403 dns_dbiterator_t *dbiterator = NULL; 17404 dns_dbversion_t *version = NULL; 17405 isc_time_t loadtime; 17406 unsigned int oldserial = 0, *oldserialp = NULL; 17407 nsec3paramlist_t nsec3list; 17408 17409 ISC_LIST_INIT(nsec3list); 17410 17411 LOCK_ZONE(zone); 17412 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) { 17413 result = ISC_R_SHUTTINGDOWN; 17414 goto failure; 17415 } 17416 17417 loadtime = isc_time_now(); 17418 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 17419 if (zone->db != NULL) { 17420 result = dns_db_getsoaserial(zone->db, NULL, &oldserial); 17421 if (result == ISC_R_SUCCESS) { 17422 oldserialp = &oldserial; 17423 } 17424 17425 /* 17426 * assemble nsec3parameters from the old zone, and set a flag 17427 * if any are found 17428 */ 17429 result = save_nsec3param(zone, &nsec3list); 17430 if (result != ISC_R_SUCCESS) { 17431 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17432 goto failure; 17433 } 17434 } 17435 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17436 17437 result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, 17438 dns_dbtype_zone, zone->rdclass, 17439 zone->db_argc - 1, zone->db_argv + 1, &db); 17440 if (result != ISC_R_SUCCESS) { 17441 goto failure; 17442 } 17443 17444 result = dns_db_setgluecachestats(db, zone->gluecachestats); 17445 if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { 17446 goto failure; 17447 } 17448 17449 result = dns_db_newversion(db, &version); 17450 if (result != ISC_R_SUCCESS) { 17451 goto failure; 17452 } 17453 17454 result = dns_db_createiterator(rawdb, DNS_DB_NONSEC3, &dbiterator); 17455 if (result != ISC_R_SUCCESS) { 17456 goto failure; 17457 } 17458 17459 for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS; 17460 result = dns_dbiterator_next(dbiterator)) 17461 { 17462 result = copy_non_dnssec_records(db, version, rawdb, dbiterator, 17463 oldserialp); 17464 if (result != ISC_R_SUCCESS) { 17465 goto failure; 17466 } 17467 } 17468 dns_dbiterator_destroy(&dbiterator); 17469 if (result != ISC_R_NOMORE) { 17470 goto failure; 17471 } 17472 17473 /* 17474 * Call restore_nsec3param() to create private-type records from 17475 * the old nsec3 parameters and insert them into db 17476 */ 17477 if (!ISC_LIST_EMPTY(nsec3list)) { 17478 result = restore_nsec3param(zone, db, version, &nsec3list); 17479 if (result != ISC_R_SUCCESS) { 17480 goto failure; 17481 } 17482 } 17483 17484 dns_db_closeversion(db, &version, true); 17485 17486 /* 17487 * Lock hierarchy: zmgr, zone, raw. 17488 */ 17489 INSIST(zone != zone->raw); 17490 LOCK_ZONE(zone->raw); 17491 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 17492 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 17493 zone_needdump(zone, 0); /* XXXMPA */ 17494 UNLOCK_ZONE(zone->raw); 17495 17496 /* 17497 * Process any queued NSEC3PARAM change requests. 17498 */ 17499 process_zone_setnsec3param(zone); 17500 17501 failure: 17502 UNLOCK_ZONE(zone); 17503 if (dbiterator != NULL) { 17504 dns_dbiterator_destroy(&dbiterator); 17505 } 17506 if (result != ISC_R_SUCCESS) { 17507 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s", 17508 isc_result_totext(result)); 17509 } 17510 17511 while (!ISC_LIST_EMPTY(nsec3list)) { 17512 nsec3param_t *nsec3p; 17513 nsec3p = ISC_LIST_HEAD(nsec3list); 17514 ISC_LIST_UNLINK(nsec3list, nsec3p, link); 17515 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t)); 17516 } 17517 if (db != NULL) { 17518 if (version != NULL) { 17519 dns_db_closeversion(db, &version, false); 17520 } 17521 dns_db_detach(&db); 17522 } 17523 17524 dns_db_detach(&rawdb); 17525 isc_mem_put(zone->mctx, rss, sizeof(*rss)); 17526 dns_zone_idetach(&zone); 17527 17528 INSIST(version == NULL); 17529 } 17530 17531 static isc_result_t 17532 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) { 17533 struct rss *rss = NULL; 17534 17535 rss = isc_mem_get(zone->secure->mctx, sizeof(*rss)); 17536 *rss = (struct rss){ .link = ISC_LINK_INITIALIZER }; 17537 17538 INSIST(LOCKED_ZONE(zone->secure)); 17539 zone_iattach(zone->secure, &rss->zone); 17540 dns_db_attach(db, &rss->db); 17541 isc_async_run(zone->secure->loop, receive_secure_db, rss); 17542 17543 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); 17544 return ISC_R_SUCCESS; 17545 } 17546 17547 isc_result_t 17548 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) { 17549 isc_result_t result; 17550 dns_zone_t *secure = NULL; 17551 17552 REQUIRE(DNS_ZONE_VALID(zone)); 17553 again: 17554 LOCK_ZONE(zone); 17555 if (inline_raw(zone)) { 17556 secure = zone->secure; 17557 INSIST(secure != zone); 17558 TRYLOCK_ZONE(result, secure); 17559 if (result != ISC_R_SUCCESS) { 17560 UNLOCK_ZONE(zone); 17561 secure = NULL; 17562 isc_thread_yield(); 17563 goto again; 17564 } 17565 } 17566 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 17567 result = zone_replacedb(zone, db, dump); 17568 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 17569 if (secure != NULL) { 17570 UNLOCK_ZONE(secure); 17571 } 17572 UNLOCK_ZONE(zone); 17573 return result; 17574 } 17575 17576 static isc_result_t 17577 zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) { 17578 dns_dbversion_t *ver; 17579 isc_result_t result; 17580 unsigned int soacount = 0; 17581 unsigned int nscount = 0; 17582 17583 /* 17584 * 'zone' and 'zone->db' locked by caller. 17585 */ 17586 REQUIRE(DNS_ZONE_VALID(zone)); 17587 REQUIRE(LOCKED_ZONE(zone)); 17588 if (inline_raw(zone)) { 17589 REQUIRE(LOCKED_ZONE(zone->secure)); 17590 } 17591 17592 result = zone_get_from_db(zone, db, &nscount, &soacount, NULL, NULL, 17593 NULL, NULL, NULL, NULL, NULL); 17594 if (result == ISC_R_SUCCESS) { 17595 if (soacount != 1) { 17596 dns_zone_log(zone, ISC_LOG_ERROR, "has %d SOA records", 17597 soacount); 17598 result = DNS_R_BADZONE; 17599 } 17600 if (nscount == 0 && zone->type != dns_zone_key) { 17601 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records"); 17602 result = DNS_R_BADZONE; 17603 } 17604 if (result != ISC_R_SUCCESS) { 17605 return result; 17606 } 17607 } else { 17608 dns_zone_log(zone, ISC_LOG_ERROR, 17609 "retrieving SOA and NS records failed: %s", 17610 isc_result_totext(result)); 17611 return result; 17612 } 17613 17614 result = check_nsec3param(zone, db); 17615 if (result != ISC_R_SUCCESS) { 17616 return result; 17617 } 17618 17619 ver = NULL; 17620 dns_db_currentversion(db, &ver); 17621 17622 /* 17623 * The initial version of a secondary zone is always dumped; 17624 * subsequent versions may be journaled instead if this 17625 * is enabled in the configuration. 17626 */ 17627 if (zone->db != NULL && zone->journal != NULL && 17628 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 17629 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) 17630 { 17631 uint32_t serial, oldserial; 17632 17633 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs"); 17634 17635 result = dns_db_getsoaserial(db, ver, &serial); 17636 if (result != ISC_R_SUCCESS) { 17637 dns_zone_log(zone, ISC_LOG_ERROR, 17638 "ixfr-from-differences: unable to get " 17639 "new serial"); 17640 goto fail; 17641 } 17642 17643 /* 17644 * This is checked in zone_postload() for primary zones. 17645 */ 17646 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, 17647 &oldserial, NULL, NULL, NULL, NULL, 17648 NULL); 17649 RUNTIME_CHECK(result == ISC_R_SUCCESS); 17650 RUNTIME_CHECK(soacount > 0U); 17651 if ((zone->type == dns_zone_secondary || 17652 (zone->type == dns_zone_redirect && 17653 dns_remote_addresses(&zone->primaries) != NULL)) && 17654 !isc_serial_gt(serial, oldserial)) 17655 { 17656 uint32_t serialmin, serialmax; 17657 serialmin = (oldserial + 1) & 0xffffffffU; 17658 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; 17659 dns_zone_log(zone, ISC_LOG_ERROR, 17660 "ixfr-from-differences: failed: " 17661 "new serial (%u) out of range [%u - %u]", 17662 serial, serialmin, serialmax); 17663 result = ISC_R_RANGE; 17664 goto fail; 17665 } 17666 17667 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL, 17668 zone->journal); 17669 if (result != ISC_R_SUCCESS) { 17670 char strbuf[ISC_STRERRORSIZE]; 17671 strerror_r(errno, strbuf, sizeof(strbuf)); 17672 dns_zone_log(zone, ISC_LOG_ERROR, 17673 "ixfr-from-differences: failed: " 17674 "%s", 17675 strbuf); 17676 goto fallback; 17677 } 17678 if (dump) { 17679 zone_needdump(zone, DNS_DUMP_DELAY); 17680 } else { 17681 zone_journal_compact(zone, zone->db, serial); 17682 } 17683 if (zone->type == dns_zone_primary && inline_raw(zone)) { 17684 zone_send_secureserial(zone, serial); 17685 } 17686 } else { 17687 fallback: 17688 if (dump && zone->masterfile != NULL) { 17689 /* 17690 * If DNS_ZONEFLG_FORCEXFER was set we don't want 17691 * to keep the old masterfile. 17692 */ 17693 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) && 17694 remove(zone->masterfile) < 0 && errno != ENOENT) 17695 { 17696 char strbuf[ISC_STRERRORSIZE]; 17697 strerror_r(errno, strbuf, sizeof(strbuf)); 17698 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17699 DNS_LOGMODULE_ZONE, 17700 ISC_LOG_WARNING, 17701 "unable to remove masterfile " 17702 "'%s': '%s'", 17703 zone->masterfile, strbuf); 17704 } 17705 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) { 17706 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY); 17707 } else { 17708 zone_needdump(zone, 0); 17709 } 17710 } 17711 if (dump && zone->journal != NULL) { 17712 /* 17713 * The in-memory database just changed, and 17714 * because 'dump' is set, it didn't change by 17715 * being loaded from disk. Also, we have not 17716 * journaled diffs for this change. 17717 * Therefore, the on-disk journal is missing 17718 * the deltas for this change. Since it can 17719 * no longer be used to bring the zone 17720 * up-to-date, it is useless and should be 17721 * removed. 17722 */ 17723 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17724 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 17725 "removing journal file"); 17726 if (remove(zone->journal) < 0 && errno != ENOENT) { 17727 char strbuf[ISC_STRERRORSIZE]; 17728 strerror_r(errno, strbuf, sizeof(strbuf)); 17729 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17730 DNS_LOGMODULE_ZONE, 17731 ISC_LOG_WARNING, 17732 "unable to remove journal " 17733 "'%s': '%s'", 17734 zone->journal, strbuf); 17735 } 17736 } 17737 17738 if (inline_raw(zone)) { 17739 zone_send_securedb(zone, db); 17740 } 17741 } 17742 17743 dns_db_closeversion(db, &ver, false); 17744 17745 dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database"); 17746 17747 if (zone->db != NULL) { 17748 zone_detachdb(zone); 17749 } 17750 zone_attachdb(zone, db); 17751 dns_db_setloop(zone->db, zone->loop); 17752 dns_db_setmaxrrperset(zone->db, zone->maxrrperset); 17753 dns_db_setmaxtypepername(zone->db, zone->maxtypepername); 17754 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY); 17755 return ISC_R_SUCCESS; 17756 17757 fail: 17758 dns_db_closeversion(db, &ver, false); 17759 return result; 17760 } 17761 17762 /* The caller must hold the dblock as a writer. */ 17763 static void 17764 zone_attachdb(dns_zone_t *zone, dns_db_t *db) { 17765 REQUIRE(zone->db == NULL && db != NULL); 17766 17767 dns_db_attach(db, &zone->db); 17768 } 17769 17770 /* The caller must hold the dblock as a writer. */ 17771 static void 17772 zone_detachdb(dns_zone_t *zone) { 17773 REQUIRE(zone->db != NULL); 17774 17775 dns_zone_rpz_disable_db(zone, zone->db); 17776 dns_zone_catz_disable_db(zone, zone->db); 17777 dns_db_detach(&zone->db); 17778 } 17779 17780 static void 17781 zone_xfrdone(dns_zone_t *zone, uint32_t *expireopt, isc_result_t result) { 17782 isc_time_t now, expiretime; 17783 bool again = false; 17784 unsigned int soacount; 17785 unsigned int nscount; 17786 uint32_t serial, refresh, retry, expire, minimum, soattl, oldexpire; 17787 isc_result_t xfrresult = result; 17788 bool free_needed; 17789 dns_zone_t *secure = NULL; 17790 17791 REQUIRE(DNS_ZONE_VALID(zone)); 17792 17793 dns_zone_logc( 17794 zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 17795 expireopt == NULL ? "zone transfer finished: %s" 17796 : "zone transfer finished: %s, expire=%u", 17797 isc_result_totext(result), expireopt != NULL ? *expireopt : 0); 17798 17799 /* 17800 * Obtaining a lock on the zone->secure (see zone_send_secureserial) 17801 * could result in a deadlock due to a LOR so we will spin if we 17802 * can't obtain both locks. 17803 */ 17804 again: 17805 LOCK_ZONE(zone); 17806 if (inline_raw(zone)) { 17807 secure = zone->secure; 17808 INSIST(secure != zone); 17809 TRYLOCK_ZONE(result, secure); 17810 if (result != ISC_R_SUCCESS) { 17811 UNLOCK_ZONE(zone); 17812 secure = NULL; 17813 isc_thread_yield(); 17814 goto again; 17815 } 17816 } 17817 17818 INSIST(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)); 17819 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 17820 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 17821 17822 now = isc_time_now(); 17823 switch (xfrresult) { 17824 case ISC_R_SUCCESS: 17825 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 17826 FALLTHROUGH; 17827 case DNS_R_UPTODATE: 17828 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER | 17829 DNS_ZONEFLG_FIRSTREFRESH); 17830 /* 17831 * Has the zone expired underneath us? 17832 */ 17833 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 17834 if (zone->db == NULL) { 17835 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17836 goto same_primary; 17837 } 17838 17839 oldexpire = zone->expire; 17840 17841 /* 17842 * Update the zone structure's data from the actual 17843 * SOA received. 17844 */ 17845 nscount = 0; 17846 soacount = 0; 17847 INSIST(zone->db != NULL); 17848 result = zone_get_from_db(zone, zone->db, &nscount, &soacount, 17849 &soattl, &serial, &refresh, &retry, 17850 &expire, &minimum, NULL); 17851 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17852 if (result == ISC_R_SUCCESS) { 17853 if (soacount != 1) { 17854 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 17855 ISC_LOG_ERROR, 17856 "transferred zone " 17857 "has %d SOA records", 17858 soacount); 17859 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) 17860 { 17861 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 17862 zone->retry = DNS_ZONE_DEFAULTRETRY; 17863 } 17864 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 17865 zone_unload(zone); 17866 goto next_primary; 17867 } 17868 if (nscount == 0) { 17869 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 17870 ISC_LOG_ERROR, 17871 "transferred zone " 17872 "has no NS records"); 17873 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) 17874 { 17875 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 17876 zone->retry = DNS_ZONE_DEFAULTRETRY; 17877 } 17878 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 17879 zone_unload(zone); 17880 goto next_primary; 17881 } 17882 zone->refresh = RANGE(refresh, zone->minrefresh, 17883 zone->maxrefresh); 17884 zone->retry = RANGE(retry, zone->minretry, 17885 zone->maxretry); 17886 zone->expire = RANGE(expire, 17887 zone->refresh + zone->retry, 17888 DNS_MAX_EXPIRE); 17889 zone->soattl = soattl; 17890 zone->minimum = minimum; 17891 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 17892 } 17893 17894 /* 17895 * Set our next refresh time. 17896 */ 17897 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 17898 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 17899 zone->refreshtime = now; 17900 } else { 17901 DNS_ZONE_JITTER_ADD(&now, zone->refresh, 17902 &zone->refreshtime); 17903 } 17904 17905 /* 17906 * Set our next expire time. If the parent returned 17907 * an EXPIRE option use that to update zone->expiretime. 17908 */ 17909 expire = zone->expire; 17910 if (expireopt != NULL && *expireopt < expire) { 17911 expire = *expireopt; 17912 } 17913 DNS_ZONE_TIME_ADD(&now, expire, &expiretime); 17914 if (oldexpire != zone->expire || 17915 isc_time_compare(&expiretime, &zone->expiretime) > 0) 17916 { 17917 zone->expiretime = expiretime; 17918 } 17919 17920 /* 17921 * Set loadtime. 17922 */ 17923 zone->loadtime = now; 17924 17925 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) { 17926 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")]; 17927 if (zone->tsigkey != NULL) { 17928 char namebuf[DNS_NAME_FORMATSIZE]; 17929 dns_name_format(zone->tsigkey->name, namebuf, 17930 sizeof(namebuf)); 17931 snprintf(buf, sizeof(buf), ": TSIG '%s'", 17932 namebuf); 17933 } else { 17934 buf[0] = '\0'; 17935 } 17936 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 17937 ISC_LOG_INFO, "transferred serial %u%s", 17938 serial, buf); 17939 if (inline_raw(zone)) { 17940 zone_send_secureserial(zone, serial); 17941 } 17942 } 17943 17944 /* 17945 * This is not necessary if we just performed a AXFR 17946 * however it is necessary for an IXFR / UPTODATE and 17947 * won't hurt with an AXFR. 17948 */ 17949 if (zone->masterfile != NULL || zone->journal != NULL) { 17950 unsigned int delay = DNS_DUMP_DELAY; 17951 isc_interval_t i; 17952 isc_time_t when; 17953 17954 /* 17955 * Compute effective modification time. 17956 */ 17957 isc_interval_set(&i, zone->expire, 0); 17958 result = isc_time_subtract(&zone->expiretime, &i, 17959 &when); 17960 if (result != ISC_R_SUCCESS) { 17961 when = now; 17962 } 17963 17964 result = ISC_R_FAILURE; 17965 if (zone->journal != NULL) { 17966 result = isc_file_settime(zone->journal, &when); 17967 } 17968 if (result != ISC_R_SUCCESS && zone->masterfile != NULL) 17969 { 17970 result = isc_file_settime(zone->masterfile, 17971 &when); 17972 } 17973 17974 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) || 17975 result == ISC_R_FILENOTFOUND) 17976 { 17977 delay = 0; 17978 } 17979 17980 if ((result == ISC_R_SUCCESS || 17981 result == ISC_R_FILENOTFOUND) && 17982 zone->masterfile != NULL) 17983 { 17984 zone_needdump(zone, delay); 17985 } else if (result != ISC_R_SUCCESS) { 17986 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 17987 ISC_LOG_ERROR, 17988 "transfer: could not set file " 17989 "modification time of '%s': %s", 17990 zone->masterfile, 17991 isc_result_totext(result)); 17992 } 17993 } 17994 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY); 17995 inc_stats(zone, dns_zonestatscounter_xfrsuccess); 17996 break; 17997 17998 case DNS_R_BADIXFR: 17999 /* Force retry with AXFR. */ 18000 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOIXFR); 18001 goto same_primary; 18002 18003 case DNS_R_TOOMANYRECORDS: 18004 case DNS_R_VERIFYFAILURE: 18005 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 18006 inc_stats(zone, dns_zonestatscounter_xfrfail); 18007 break; 18008 18009 case ISC_R_SHUTTINGDOWN: 18010 dns_remote_reset(&zone->primaries, true); 18011 break; 18012 18013 default: 18014 next_primary: 18015 /* 18016 * Skip to next failed / untried primary. 18017 */ 18018 dns_remote_next(&zone->primaries, true); 18019 same_primary: 18020 if (dns_remote_done(&zone->primaries)) { 18021 dns_remote_reset(&zone->primaries, false); 18022 } else { 18023 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 18024 again = true; 18025 } 18026 inc_stats(zone, dns_zonestatscounter_xfrfail); 18027 break; 18028 } 18029 zone_settimer(zone, &now); 18030 18031 /* 18032 * We are called as the done callback of a zone 18033 * transfer object that just entered its shutting-down state or 18034 * failed to start. Since we are no longer responsible for shutting 18035 * it down, we can detach our reference. 18036 */ 18037 if (zone->xfr != NULL) { 18038 dns_xfrin_detach(&zone->xfr); 18039 } 18040 18041 if (zone->tsigkey != NULL) { 18042 dns_tsigkey_detach(&zone->tsigkey); 18043 } 18044 18045 if (zone->transport != NULL) { 18046 dns_transport_detach(&zone->transport); 18047 } 18048 18049 /* 18050 * Handle any deferred journal compaction. 18051 */ 18052 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) { 18053 dns_db_t *db = NULL; 18054 if (dns_zone_getdb(zone, &db) == ISC_R_SUCCESS) { 18055 zone_journal_compact(zone, db, zone->compact_serial); 18056 dns_db_detach(&db); 18057 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 18058 } 18059 } 18060 18061 if (secure != NULL) { 18062 UNLOCK_ZONE(secure); 18063 } 18064 /* 18065 * This transfer finishing freed up a transfer quota slot. 18066 * Let any other zones waiting for quota have it. 18067 */ 18068 if (zone->zmgr != NULL && 18069 zone->statelist == &zone->zmgr->xfrin_in_progress) 18070 { 18071 UNLOCK_ZONE(zone); 18072 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 18073 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink); 18074 zone->statelist = NULL; 18075 zmgr_resume_xfrs(zone->zmgr, false); 18076 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 18077 LOCK_ZONE(zone); 18078 } 18079 18080 /* 18081 * Retry with a different server if necessary. 18082 */ 18083 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 18084 queue_soa_query(zone); 18085 } 18086 18087 isc_refcount_decrement(&zone->irefs); 18088 free_needed = exit_check(zone); 18089 UNLOCK_ZONE(zone); 18090 if (free_needed) { 18091 zone_free(zone); 18092 } 18093 } 18094 18095 static void 18096 zone_loaddone(void *arg, isc_result_t result) { 18097 dns_load_t *load = arg; 18098 dns_zone_t *zone; 18099 isc_result_t tresult; 18100 dns_zone_t *secure = NULL; 18101 18102 zone = load->zone; 18103 18104 ENTER; 18105 18106 /* 18107 * If zone loading failed, remove the update db callbacks prior 18108 * to calling the list of callbacks in the zone load structure. 18109 */ 18110 if (result != ISC_R_SUCCESS) { 18111 dns_zone_rpz_disable_db(zone, load->db); 18112 dns_zone_catz_disable_db(zone, load->db); 18113 } 18114 18115 tresult = dns_db_endload(load->db, &load->callbacks); 18116 if (tresult != ISC_R_SUCCESS && 18117 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)) 18118 { 18119 result = tresult; 18120 } 18121 18122 /* 18123 * Lock hierarchy: zmgr, zone, raw. 18124 */ 18125 again: 18126 LOCK_ZONE(zone); 18127 INSIST(zone != zone->raw); 18128 if (inline_secure(zone)) { 18129 LOCK_ZONE(zone->raw); 18130 } else if (inline_raw(zone)) { 18131 secure = zone->secure; 18132 TRYLOCK_ZONE(tresult, secure); 18133 if (tresult != ISC_R_SUCCESS) { 18134 UNLOCK_ZONE(zone); 18135 secure = NULL; 18136 isc_thread_yield(); 18137 goto again; 18138 } 18139 } 18140 (void)zone_postload(zone, load->db, load->loadtime, result); 18141 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING); 18142 zone_idetach(&load->callbacks.zone); 18143 /* 18144 * Leave the zone frozen if the reload fails. 18145 */ 18146 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) && 18147 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW)) 18148 { 18149 zone->update_disabled = false; 18150 } 18151 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW); 18152 if (inline_secure(zone)) { 18153 UNLOCK_ZONE(zone->raw); 18154 } else if (secure != NULL) { 18155 UNLOCK_ZONE(secure); 18156 } 18157 UNLOCK_ZONE(zone); 18158 18159 dns_db_detach(&load->db); 18160 if (zone->loadctx != NULL) { 18161 dns_loadctx_detach(&zone->loadctx); 18162 } 18163 isc_mem_put(zone->mctx, load, sizeof(*load)); 18164 18165 dns_zone_idetach(&zone); 18166 } 18167 18168 void 18169 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) { 18170 REQUIRE(DNS_ZONE_VALID(zone)); 18171 REQUIRE(table != NULL); 18172 REQUIRE(*table == NULL); 18173 18174 LOCK_ZONE(zone); 18175 if (zone->ssutable != NULL) { 18176 dns_ssutable_attach(zone->ssutable, table); 18177 } 18178 UNLOCK_ZONE(zone); 18179 } 18180 18181 void 18182 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) { 18183 REQUIRE(DNS_ZONE_VALID(zone)); 18184 18185 LOCK_ZONE(zone); 18186 if (zone->ssutable != NULL) { 18187 dns_ssutable_detach(&zone->ssutable); 18188 } 18189 if (table != NULL) { 18190 dns_ssutable_attach(table, &zone->ssutable); 18191 } 18192 UNLOCK_ZONE(zone); 18193 } 18194 18195 void 18196 dns_zone_setsigvalidityinterval(dns_zone_t *zone, uint32_t interval) { 18197 REQUIRE(DNS_ZONE_VALID(zone)); 18198 18199 zone->sigvalidityinterval = interval; 18200 } 18201 18202 uint32_t 18203 dns_zone_getsigvalidityinterval(dns_zone_t *zone) { 18204 REQUIRE(DNS_ZONE_VALID(zone)); 18205 18206 return zone->sigvalidityinterval; 18207 } 18208 18209 void 18210 dns_zone_setkeyvalidityinterval(dns_zone_t *zone, uint32_t interval) { 18211 REQUIRE(DNS_ZONE_VALID(zone)); 18212 18213 zone->keyvalidityinterval = interval; 18214 } 18215 18216 uint32_t 18217 dns_zone_getkeyvalidityinterval(dns_zone_t *zone) { 18218 REQUIRE(DNS_ZONE_VALID(zone)); 18219 18220 return zone->keyvalidityinterval; 18221 } 18222 18223 void 18224 dns_zone_setsigresigninginterval(dns_zone_t *zone, uint32_t interval) { 18225 isc_time_t now; 18226 18227 REQUIRE(DNS_ZONE_VALID(zone)); 18228 18229 LOCK_ZONE(zone); 18230 zone->sigresigninginterval = interval; 18231 set_resigntime(zone); 18232 if (zone->loop != NULL) { 18233 now = isc_time_now(); 18234 zone_settimer(zone, &now); 18235 } 18236 UNLOCK_ZONE(zone); 18237 } 18238 18239 uint32_t 18240 dns_zone_getsigresigninginterval(dns_zone_t *zone) { 18241 REQUIRE(DNS_ZONE_VALID(zone)); 18242 18243 return zone->sigresigninginterval; 18244 } 18245 18246 isc_sockaddr_t 18247 dns_zone_getsourceaddr(dns_zone_t *zone) { 18248 isc_sockaddr_t sourceaddr; 18249 18250 REQUIRE(DNS_ZONE_VALID(zone)); 18251 18252 LOCK_ZONE(zone); 18253 INSIST(dns_remote_count(&zone->primaries) > 0); 18254 sourceaddr = zone->sourceaddr; 18255 UNLOCK_ZONE(zone); 18256 18257 return sourceaddr; 18258 } 18259 18260 isc_sockaddr_t 18261 dns_zone_getprimaryaddr(dns_zone_t *zone) { 18262 isc_sockaddr_t curraddr; 18263 18264 REQUIRE(DNS_ZONE_VALID(zone)); 18265 18266 LOCK_ZONE(zone); 18267 INSIST(dns_remote_count(&zone->primaries) > 0); 18268 curraddr = dns_remote_curraddr(&zone->primaries); 18269 UNLOCK_ZONE(zone); 18270 18271 return curraddr; 18272 } 18273 18274 isc_time_t 18275 dns_zone_getxfrintime(dns_zone_t *zone) { 18276 isc_time_t xfrintime; 18277 18278 REQUIRE(DNS_ZONE_VALID(zone)); 18279 18280 LOCK_ZONE(zone); 18281 xfrintime = zone->xfrintime; 18282 UNLOCK_ZONE(zone); 18283 18284 return xfrintime; 18285 } 18286 18287 static void 18288 queue_xfrin(dns_zone_t *zone) { 18289 isc_result_t result; 18290 dns_zonemgr_t *zmgr = zone->zmgr; 18291 18292 ENTER; 18293 18294 INSIST(zone->statelist == NULL); 18295 18296 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18297 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink); 18298 isc_refcount_increment0(&zone->irefs); 18299 zone->statelist = &zmgr->waiting_for_xfrin; 18300 result = zmgr_start_xfrin_ifquota(zmgr, zone); 18301 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18302 18303 if (result == ISC_R_QUOTA) { 18304 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 18305 "zone transfer deferred due to quota"); 18306 } else if (result != ISC_R_SUCCESS) { 18307 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, 18308 "starting zone transfer: %s", 18309 isc_result_totext(result)); 18310 } 18311 } 18312 18313 /* 18314 * Get the transport type used for the SOA query to the current primary server 18315 * before an ongoing incoming zone transfer. 18316 * 18317 * Requires: 18318 * The zone is locked by the caller. 18319 */ 18320 static dns_transport_type_t 18321 get_request_transport_type(dns_zone_t *zone) { 18322 dns_transport_type_t transport_type = DNS_TRANSPORT_NONE; 18323 18324 if (zone->transport != NULL) { 18325 transport_type = dns_transport_get_type(zone->transport); 18326 } else { 18327 transport_type = (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC)) 18328 ? DNS_TRANSPORT_TCP 18329 : DNS_TRANSPORT_UDP; 18330 18331 /* Check if the peer is forced to always use TCP. */ 18332 if (transport_type != DNS_TRANSPORT_TCP) { 18333 isc_result_t result; 18334 isc_sockaddr_t primaryaddr; 18335 isc_netaddr_t primaryip; 18336 dns_peer_t *peer = NULL; 18337 18338 primaryaddr = dns_remote_curraddr(&zone->primaries); 18339 isc_netaddr_fromsockaddr(&primaryip, &primaryaddr); 18340 result = dns_peerlist_peerbyaddr(zone->view->peers, 18341 &primaryip, &peer); 18342 if (result == ISC_R_SUCCESS && peer != NULL) { 18343 bool usetcp; 18344 result = dns_peer_getforcetcp(peer, &usetcp); 18345 if (result == ISC_R_SUCCESS && usetcp) { 18346 transport_type = DNS_TRANSPORT_TCP; 18347 } 18348 } 18349 } 18350 } 18351 18352 return transport_type; 18353 } 18354 18355 dns_transport_type_t 18356 dns_zone_getrequesttransporttype(dns_zone_t *zone) { 18357 dns_transport_type_t transport_type; 18358 18359 REQUIRE(DNS_ZONE_VALID(zone)); 18360 18361 LOCK_ZONE(zone); 18362 transport_type = get_request_transport_type(zone); 18363 UNLOCK_ZONE(zone); 18364 18365 return transport_type; 18366 } 18367 18368 /* 18369 * This event callback is called when a zone has received 18370 * any necessary zone transfer quota. This is the time 18371 * to go ahead and start the transfer. 18372 */ 18373 static void 18374 got_transfer_quota(void *arg) { 18375 dns_zone_t *zone = (dns_zone_t *)arg; 18376 isc_result_t result = ISC_R_SUCCESS; 18377 dns_peer_t *peer = NULL; 18378 char primary[ISC_SOCKADDR_FORMATSIZE]; 18379 char source[ISC_SOCKADDR_FORMATSIZE]; 18380 dns_rdatatype_t xfrtype; 18381 isc_netaddr_t primaryip; 18382 isc_sockaddr_t primaryaddr; 18383 isc_sockaddr_t sourceaddr; 18384 isc_time_t now; 18385 dns_transport_type_t soa_transport_type = DNS_TRANSPORT_NONE; 18386 const char *soa_before = ""; 18387 bool loaded; 18388 isc_tlsctx_cache_t *zmgr_tlsctx_cache = NULL; 18389 dns_xfrin_t *xfr = NULL; 18390 18391 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 18392 zone_xfrdone(zone, NULL, ISC_R_CANCELED); 18393 return; 18394 } 18395 18396 now = isc_time_now(); 18397 18398 primaryaddr = dns_remote_curraddr(&zone->primaries); 18399 isc_sockaddr_format(&primaryaddr, primary, sizeof(primary)); 18400 if (dns_zonemgr_unreachable(zone->zmgr, &primaryaddr, &zone->sourceaddr, 18401 &now)) 18402 { 18403 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 18404 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 18405 "got_transfer_quota: skipping zone transfer as " 18406 "primary %s (source %s) is unreachable (cached)", 18407 primary, source); 18408 zone_xfrdone(zone, NULL, ISC_R_CANCELED); 18409 return; 18410 } 18411 18412 isc_netaddr_fromsockaddr(&primaryip, &primaryaddr); 18413 (void)dns_peerlist_peerbyaddr(zone->view->peers, &primaryip, &peer); 18414 18415 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) { 18416 soa_before = "SOA before "; 18417 } 18418 /* 18419 * Decide whether we should request IXFR or AXFR. 18420 */ 18421 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 18422 loaded = (zone->db != NULL); 18423 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 18424 18425 if (!loaded) { 18426 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 18427 "no database exists yet, requesting AXFR of " 18428 "initial version from %s", 18429 primary); 18430 xfrtype = dns_rdatatype_axfr; 18431 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { 18432 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 18433 "forced reload, requesting AXFR of " 18434 "initial version from %s", 18435 primary); 18436 xfrtype = dns_rdatatype_axfr; 18437 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOIXFR)) { 18438 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 18439 "retrying with AXFR from %s due to " 18440 "previous IXFR failure", 18441 primary); 18442 xfrtype = dns_rdatatype_axfr; 18443 LOCK_ZONE(zone); 18444 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOIXFR); 18445 UNLOCK_ZONE(zone); 18446 } else { 18447 bool use_ixfr = true; 18448 if (peer != NULL) { 18449 result = dns_peer_getrequestixfr(peer, &use_ixfr); 18450 } 18451 if (peer == NULL || result != ISC_R_SUCCESS) { 18452 use_ixfr = zone->requestixfr; 18453 } 18454 if (!use_ixfr) { 18455 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18456 ISC_LOG_DEBUG(1), 18457 "IXFR disabled, " 18458 "requesting %sAXFR from %s", 18459 soa_before, primary); 18460 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) { 18461 xfrtype = dns_rdatatype_soa; 18462 } else { 18463 xfrtype = dns_rdatatype_axfr; 18464 } 18465 } else { 18466 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18467 ISC_LOG_DEBUG(1), 18468 "requesting IXFR from %s", primary); 18469 xfrtype = dns_rdatatype_ixfr; 18470 } 18471 } 18472 18473 /* 18474 * Determine if we should attempt to sign the request with TSIG. 18475 */ 18476 result = ISC_R_NOTFOUND; 18477 18478 /* 18479 * First, look for a tsig key in the primaries statement, then 18480 * try for a server key. 18481 */ 18482 if (dns_remote_keyname(&zone->primaries) != NULL) { 18483 dns_view_t *view = dns_zone_getview(zone); 18484 dns_name_t *keyname = dns_remote_keyname(&zone->primaries); 18485 result = dns_view_gettsig(view, keyname, &zone->tsigkey); 18486 } 18487 if (result != ISC_R_SUCCESS) { 18488 INSIST(zone->tsigkey == NULL); 18489 result = dns_view_getpeertsig(zone->view, &primaryip, 18490 &zone->tsigkey); 18491 } 18492 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 18493 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, 18494 "could not get TSIG key for zone transfer: %s", 18495 isc_result_totext(result)); 18496 } 18497 18498 /* 18499 * Get the TLS transport for the primary, if configured. 18500 */ 18501 if (dns_remote_tlsname(&zone->primaries) != NULL) { 18502 dns_view_t *view = dns_zone_getview(zone); 18503 dns_name_t *tlsname = dns_remote_tlsname(&zone->primaries); 18504 result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname, 18505 &zone->transport); 18506 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 18507 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18508 ISC_LOG_ERROR, 18509 "could not get TLS configuration for " 18510 "zone transfer: %s", 18511 isc_result_totext(result)); 18512 } 18513 } 18514 18515 LOCK_ZONE(zone); 18516 if (xfrtype != dns_rdatatype_soa) { 18517 /* 18518 * If 'xfrtype' is dns_rdatatype_soa, then the SOA query will be 18519 * performed by xfrin, otherwise, the SOA request performed by 18520 * soa_query() was successful and we should inform the xfrin 18521 * about the transport type used for that query, so that the 18522 * information can be presented in the statistics channel. 18523 */ 18524 soa_transport_type = get_request_transport_type(zone); 18525 } 18526 sourceaddr = zone->sourceaddr; 18527 UNLOCK_ZONE(zone); 18528 18529 INSIST(isc_sockaddr_pf(&primaryaddr) == isc_sockaddr_pf(&sourceaddr)); 18530 18531 zmgr_tlsctx_attach(zone->zmgr, &zmgr_tlsctx_cache); 18532 18533 dns_xfrin_create(zone, xfrtype, &primaryaddr, &sourceaddr, 18534 zone->tsigkey, soa_transport_type, zone->transport, 18535 zmgr_tlsctx_cache, zone->mctx, &xfr); 18536 INSIST(xfr != NULL); 18537 18538 isc_tlsctx_cache_detach(&zmgr_tlsctx_cache); 18539 18540 LOCK_ZONE(zone); 18541 if (zone->xfr != NULL) { 18542 dns_xfrin_detach(&zone->xfr); 18543 } 18544 dns_xfrin_attach(xfr, &zone->xfr); 18545 UNLOCK_ZONE(zone); 18546 18547 dns_xfrin_detach(&xfr); 18548 18549 /* 18550 * Any failure in this function is handled like a failed 18551 * zone transfer. This ensures that we get removed from 18552 * zmgr->xfrin_in_progress. 18553 */ 18554 result = dns_xfrin_start(zone->xfr, zone_xfrdone); 18555 if (result != ISC_R_SUCCESS) { 18556 zone_xfrdone(zone, NULL, result); 18557 return; 18558 } 18559 18560 LOCK_ZONE(zone); 18561 if (xfrtype == dns_rdatatype_axfr) { 18562 if (isc_sockaddr_pf(&primaryaddr) == PF_INET) { 18563 inc_stats(zone, dns_zonestatscounter_axfrreqv4); 18564 } else { 18565 inc_stats(zone, dns_zonestatscounter_axfrreqv6); 18566 } 18567 } else if (xfrtype == dns_rdatatype_ixfr) { 18568 if (isc_sockaddr_pf(&primaryaddr) == PF_INET) { 18569 inc_stats(zone, dns_zonestatscounter_ixfrreqv4); 18570 } else { 18571 inc_stats(zone, dns_zonestatscounter_ixfrreqv6); 18572 } 18573 } 18574 UNLOCK_ZONE(zone); 18575 } 18576 18577 /* 18578 * Update forwarding support. 18579 */ 18580 18581 static void 18582 forward_destroy(dns_forward_t *forward) { 18583 forward->magic = 0; 18584 if (forward->request != NULL) { 18585 dns_request_destroy(&forward->request); 18586 } 18587 if (forward->msgbuf != NULL) { 18588 isc_buffer_free(&forward->msgbuf); 18589 } 18590 if (forward->transport != NULL) { 18591 dns_transport_detach(&forward->transport); 18592 } 18593 if (forward->zone != NULL) { 18594 LOCK(&forward->zone->lock); 18595 if (ISC_LINK_LINKED(forward, link)) { 18596 ISC_LIST_UNLINK(forward->zone->forwards, forward, link); 18597 } 18598 UNLOCK(&forward->zone->lock); 18599 dns_zone_idetach(&forward->zone); 18600 } 18601 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward)); 18602 } 18603 18604 static isc_result_t 18605 sendtoprimary(dns_forward_t *forward) { 18606 isc_result_t result; 18607 isc_sockaddr_t src, any; 18608 dns_zone_t *zone = forward->zone; 18609 bool tls_transport_invalid = false; 18610 isc_tlsctx_cache_t *zmgr_tlsctx_cache = NULL; 18611 18612 LOCK_ZONE(zone); 18613 18614 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 18615 UNLOCK_ZONE(zone); 18616 return ISC_R_CANCELED; 18617 } 18618 18619 next: 18620 if (forward->which >= dns_remote_count(&forward->zone->primaries)) { 18621 UNLOCK_ZONE(zone); 18622 return ISC_R_NOMORE; 18623 } 18624 18625 forward->addr = dns_remote_addr(&zone->primaries, forward->which); 18626 18627 if (isc_sockaddr_disabled(&forward->addr)) { 18628 forward->which++; 18629 goto next; 18630 } 18631 18632 /* 18633 * Always use TCP regardless of whether the original update 18634 * used TCP. 18635 * XXX The timeout may but a bit small if we are far down a 18636 * transfer graph and have to try several primaries. 18637 */ 18638 switch (isc_sockaddr_pf(&forward->addr)) { 18639 case PF_INET: 18640 isc_sockaddr_any(&any); 18641 src = zone->primaries.sources[forward->which]; 18642 if (isc_sockaddr_equal(&src, &any)) { 18643 src = zone->xfrsource4; 18644 } 18645 break; 18646 case PF_INET6: 18647 isc_sockaddr_any6(&any); 18648 src = zone->primaries.sources[forward->which]; 18649 if (isc_sockaddr_equal(&src, &any)) { 18650 src = zone->xfrsource6; 18651 } 18652 break; 18653 default: 18654 result = ISC_R_NOTIMPLEMENTED; 18655 goto unlock; 18656 } 18657 18658 if (forward->transport != NULL) { 18659 dns_transport_detach(&forward->transport); 18660 } 18661 18662 if (dns_remote_tlsname(&zone->primaries) != NULL && 18663 zone->primaries.tlsnames[forward->which] != NULL) 18664 { 18665 dns_view_t *view = dns_zone_getview(zone); 18666 dns_name_t *tlsname = zone->primaries.tlsnames[forward->which]; 18667 18668 result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname, 18669 &forward->transport); 18670 18671 if (result != ISC_R_SUCCESS) { 18672 /* Log the error message when unlocked. */ 18673 tls_transport_invalid = true; 18674 goto unlock; 18675 } 18676 } 18677 18678 zmgr_tlsctx_attach(zone->zmgr, &zmgr_tlsctx_cache); 18679 18680 result = dns_request_createraw( 18681 forward->zone->view->requestmgr, forward->msgbuf, &src, 18682 &forward->addr, forward->transport, zmgr_tlsctx_cache, 18683 forward->options, 15 /* XXX */, 0, 0, forward->zone->loop, 18684 forward_callback, forward, &forward->request); 18685 18686 isc_tlsctx_cache_detach(&zmgr_tlsctx_cache); 18687 18688 if (result == ISC_R_SUCCESS) { 18689 if (!ISC_LINK_LINKED(forward, link)) { 18690 ISC_LIST_APPEND(zone->forwards, forward, link); 18691 } 18692 } 18693 18694 unlock: 18695 UNLOCK_ZONE(zone); 18696 18697 if (tls_transport_invalid) { 18698 dns_zone_log(zone, ISC_LOG_ERROR, 18699 "could not get TLS configuration " 18700 "for dynamic update: %s", 18701 isc_result_totext(result)); 18702 } 18703 18704 return result; 18705 } 18706 18707 static void 18708 forward_callback(void *arg) { 18709 dns_request_t *request = (dns_request_t *)arg; 18710 dns_forward_t *forward = dns_request_getarg(request); 18711 dns_message_t *msg = NULL; 18712 char primary[ISC_SOCKADDR_FORMATSIZE]; 18713 isc_result_t result; 18714 dns_zone_t *zone; 18715 18716 INSIST(DNS_FORWARD_VALID(forward)); 18717 zone = forward->zone; 18718 INSIST(DNS_ZONE_VALID(zone)); 18719 18720 ENTER; 18721 18722 isc_sockaddr_format(&forward->addr, primary, sizeof(primary)); 18723 18724 result = dns_request_getresult(request); 18725 if (result != ISC_R_SUCCESS) { 18726 dns_zone_log(zone, ISC_LOG_INFO, 18727 "could not forward dynamic update to %s: %s", 18728 primary, isc_result_totext(result)); 18729 goto next_primary; 18730 } 18731 18732 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, 18733 &msg); 18734 18735 result = dns_request_getresponse(request, msg, 18736 DNS_MESSAGEPARSE_PRESERVEORDER | 18737 DNS_MESSAGEPARSE_CLONEBUFFER); 18738 if (result != ISC_R_SUCCESS) { 18739 goto next_primary; 18740 } 18741 18742 /* 18743 * Unexpected opcode. 18744 */ 18745 if (msg->opcode != dns_opcode_update) { 18746 char opcode[128]; 18747 isc_buffer_t rb; 18748 18749 isc_buffer_init(&rb, opcode, sizeof(opcode)); 18750 (void)dns_opcode_totext(msg->opcode, &rb); 18751 18752 dns_zone_log(zone, ISC_LOG_INFO, 18753 "forwarding dynamic update: " 18754 "unexpected opcode (%.*s) from %s", 18755 (int)rb.used, opcode, primary); 18756 goto next_primary; 18757 } 18758 18759 switch (msg->rcode) { 18760 /* 18761 * Pass these rcodes back to client. 18762 */ 18763 case dns_rcode_noerror: 18764 case dns_rcode_yxdomain: 18765 case dns_rcode_yxrrset: 18766 case dns_rcode_nxrrset: 18767 case dns_rcode_refused: 18768 case dns_rcode_nxdomain: { 18769 char rcode[128]; 18770 isc_buffer_t rb; 18771 18772 isc_buffer_init(&rb, rcode, sizeof(rcode)); 18773 (void)dns_rcode_totext(msg->rcode, &rb); 18774 dns_zone_log(zone, ISC_LOG_INFO, 18775 "forwarded dynamic update: " 18776 "primary %s returned: %.*s", 18777 primary, (int)rb.used, rcode); 18778 break; 18779 } 18780 18781 /* These should not occur if the primaries/zone are valid. */ 18782 case dns_rcode_notzone: 18783 case dns_rcode_notauth: { 18784 char rcode[128]; 18785 isc_buffer_t rb; 18786 18787 isc_buffer_init(&rb, rcode, sizeof(rcode)); 18788 (void)dns_rcode_totext(msg->rcode, &rb); 18789 dns_zone_log(zone, ISC_LOG_WARNING, 18790 "forwarding dynamic update: " 18791 "unexpected response: primary %s returned: %.*s", 18792 primary, (int)rb.used, rcode); 18793 goto next_primary; 18794 } 18795 18796 /* Try another server for these rcodes. */ 18797 case dns_rcode_formerr: 18798 case dns_rcode_servfail: 18799 case dns_rcode_notimp: 18800 case dns_rcode_badvers: 18801 default: 18802 goto next_primary; 18803 } 18804 18805 /* call callback */ 18806 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg); 18807 msg = NULL; 18808 dns_request_destroy(&forward->request); 18809 forward_destroy(forward); 18810 return; 18811 18812 next_primary: 18813 if (msg != NULL) { 18814 dns_message_detach(&msg); 18815 } 18816 forward->which++; 18817 dns_request_destroy(&forward->request); 18818 result = sendtoprimary(forward); 18819 if (result != ISC_R_SUCCESS) { 18820 /* call callback */ 18821 dns_zone_log(zone, ISC_LOG_DEBUG(3), 18822 "exhausted dynamic update forwarder list"); 18823 (forward->callback)(forward->callback_arg, result, NULL); 18824 forward_destroy(forward); 18825 } 18826 } 18827 18828 isc_result_t 18829 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg, 18830 dns_updatecallback_t callback, void *callback_arg) { 18831 dns_forward_t *forward; 18832 isc_result_t result; 18833 isc_region_t *mr; 18834 18835 REQUIRE(DNS_ZONE_VALID(zone)); 18836 REQUIRE(msg != NULL); 18837 REQUIRE(callback != NULL); 18838 18839 forward = isc_mem_get(zone->mctx, sizeof(*forward)); 18840 *forward = (dns_forward_t){ .callback = callback, 18841 .callback_arg = callback_arg, 18842 .options = DNS_REQUESTOPT_TCP }; 18843 ISC_LINK_INIT(forward, link); 18844 forward->magic = FORWARD_MAGIC; 18845 18846 /* 18847 * If we have a SIG(0) signed message we need to preserve the 18848 * query id as that is included in the SIG(0) computation. 18849 */ 18850 if (msg->sig0 != NULL) { 18851 forward->options |= DNS_REQUESTOPT_FIXEDID; 18852 } 18853 18854 mr = dns_message_getrawmessage(msg); 18855 if (mr == NULL) { 18856 result = ISC_R_UNEXPECTEDEND; 18857 goto cleanup; 18858 } 18859 18860 isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length); 18861 result = isc_buffer_copyregion(forward->msgbuf, mr); 18862 if (result != ISC_R_SUCCESS) { 18863 goto cleanup; 18864 } 18865 18866 isc_mem_attach(zone->mctx, &forward->mctx); 18867 dns_zone_iattach(zone, &forward->zone); 18868 result = sendtoprimary(forward); 18869 18870 cleanup: 18871 if (result != ISC_R_SUCCESS) { 18872 forward_destroy(forward); 18873 } 18874 return result; 18875 } 18876 18877 isc_result_t 18878 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) { 18879 REQUIRE(DNS_ZONE_VALID(zone)); 18880 REQUIRE(next != NULL && *next == NULL); 18881 18882 *next = ISC_LIST_NEXT(zone, link); 18883 if (*next == NULL) { 18884 return ISC_R_NOMORE; 18885 } else { 18886 return ISC_R_SUCCESS; 18887 } 18888 } 18889 18890 isc_result_t 18891 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) { 18892 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 18893 REQUIRE(first != NULL && *first == NULL); 18894 18895 *first = ISC_LIST_HEAD(zmgr->zones); 18896 if (*first == NULL) { 18897 return ISC_R_NOMORE; 18898 } else { 18899 return ISC_R_SUCCESS; 18900 } 18901 } 18902 18903 /*** 18904 *** Zone manager. 18905 ***/ 18906 18907 static void 18908 zonemgr_keymgmt_init(dns_zonemgr_t *zmgr) { 18909 dns_keymgmt_t *mgmt = isc_mem_get(zmgr->mctx, sizeof(*mgmt)); 18910 18911 *mgmt = (dns_keymgmt_t){ 18912 .magic = KEYMGMT_MAGIC, 18913 }; 18914 18915 isc_mem_attach(zmgr->mctx, &mgmt->mctx); 18916 isc_rwlock_init(&mgmt->lock); 18917 isc_hashmap_create(mgmt->mctx, DNS_KEYMGMT_HASH_BITS, &mgmt->table); 18918 18919 zmgr->keymgmt = mgmt; 18920 } 18921 18922 static void 18923 zonemgr_keymgmt_destroy(dns_zonemgr_t *zmgr) { 18924 dns_keymgmt_t *mgmt = zmgr->keymgmt; 18925 18926 REQUIRE(DNS_KEYMGMT_VALID(mgmt)); 18927 18928 mgmt->magic = 0; 18929 18930 RWLOCK(&mgmt->lock, isc_rwlocktype_write); 18931 INSIST(isc_hashmap_count(mgmt->table) == 0); 18932 RWUNLOCK(&mgmt->lock, isc_rwlocktype_write); 18933 isc_hashmap_destroy(&mgmt->table); 18934 18935 isc_rwlock_destroy(&mgmt->lock); 18936 isc_mem_putanddetach(&mgmt->mctx, mgmt, sizeof(dns_keymgmt_t)); 18937 } 18938 18939 static bool 18940 kfio_match(void *node, const void *key) { 18941 const dns_keyfileio_t *kfio = node; 18942 18943 return dns_name_equal(kfio->name, key); 18944 } 18945 18946 static void 18947 zonemgr_keymgmt_add(dns_zonemgr_t *zmgr, dns_zone_t *zone, 18948 dns_keyfileio_t **added) { 18949 dns_keymgmt_t *mgmt = zmgr->keymgmt; 18950 dns_keyfileio_t *kfio = NULL; 18951 isc_result_t result; 18952 dns_fixedname_t fname; 18953 dns_name_t *name; 18954 18955 REQUIRE(DNS_KEYMGMT_VALID(mgmt)); 18956 REQUIRE(added != NULL && *added == NULL); 18957 18958 name = dns_fixedname_initname(&fname); 18959 dns_name_downcase(&zone->origin, name, NULL); 18960 18961 RWLOCK(&mgmt->lock, isc_rwlocktype_write); 18962 18963 result = isc_hashmap_find(mgmt->table, dns_name_hash(name), kfio_match, 18964 name, (void **)&kfio); 18965 switch (result) { 18966 case ISC_R_SUCCESS: 18967 isc_refcount_increment(&kfio->references); 18968 break; 18969 case ISC_R_NOTFOUND: 18970 kfio = isc_mem_get(mgmt->mctx, sizeof(*kfio)); 18971 *kfio = (dns_keyfileio_t){ 18972 .magic = KEYFILEIO_MAGIC, 18973 }; 18974 isc_refcount_init(&kfio->references, 1); 18975 kfio->name = dns_fixedname_initname(&kfio->fname); 18976 dns_name_copy(name, kfio->name); 18977 18978 isc_mutex_init(&kfio->lock); 18979 result = isc_hashmap_add(mgmt->table, dns_name_hash(kfio->name), 18980 kfio_match, kfio->name, kfio, NULL); 18981 INSIST(result == ISC_R_SUCCESS); 18982 break; 18983 default: 18984 UNREACHABLE(); 18985 } 18986 *added = kfio; 18987 RWUNLOCK(&mgmt->lock, isc_rwlocktype_write); 18988 } 18989 18990 static bool 18991 match_ptr(void *node, const void *key) { 18992 return node == key; 18993 } 18994 18995 static void 18996 zonemgr_keymgmt_delete(dns_zonemgr_t *zmgr, dns_keyfileio_t **deleted) { 18997 REQUIRE(DNS_KEYMGMT_VALID(zmgr->keymgmt)); 18998 REQUIRE(deleted != NULL && DNS_KEYFILEIO_VALID(*deleted)); 18999 19000 dns_keymgmt_t *mgmt = zmgr->keymgmt; 19001 dns_keyfileio_t *kfio = *deleted; 19002 isc_result_t result; 19003 19004 *deleted = NULL; 19005 19006 RWLOCK(&mgmt->lock, isc_rwlocktype_write); 19007 19008 if (isc_refcount_decrement(&kfio->references) == 1) { 19009 isc_refcount_destroy(&kfio->references); 19010 kfio->magic = 0; 19011 isc_mutex_destroy(&kfio->lock); 19012 19013 result = isc_hashmap_delete(mgmt->table, 19014 dns_name_hash(kfio->name), 19015 match_ptr, kfio); 19016 INSIST(result == ISC_R_SUCCESS); 19017 19018 isc_mem_put(mgmt->mctx, kfio, sizeof(*kfio)); 19019 } 19020 19021 RWUNLOCK(&mgmt->lock, isc_rwlocktype_write); 19022 } 19023 19024 void 19025 dns_zonemgr_create(isc_mem_t *mctx, isc_nm_t *netmgr, dns_zonemgr_t **zmgrp) { 19026 dns_zonemgr_t *zmgr = NULL; 19027 isc_loop_t *loop = isc_loop(); 19028 isc_loopmgr_t *loopmgr = isc_loop_getloopmgr(loop); 19029 19030 REQUIRE(mctx != NULL); 19031 REQUIRE(netmgr != NULL); 19032 REQUIRE(zmgrp != NULL && *zmgrp == NULL); 19033 19034 zmgr = isc_mem_get(mctx, sizeof(*zmgr)); 19035 19036 *zmgr = (dns_zonemgr_t){ 19037 .loopmgr = loopmgr, 19038 .netmgr = netmgr, 19039 .workers = isc_loopmgr_nloops(loopmgr), 19040 .transfersin = 10, 19041 .transfersperns = 2, 19042 }; 19043 19044 isc_refcount_init(&zmgr->refs, 1); 19045 isc_mem_attach(mctx, &zmgr->mctx); 19046 19047 ISC_LIST_INIT(zmgr->zones); 19048 ISC_LIST_INIT(zmgr->waiting_for_xfrin); 19049 ISC_LIST_INIT(zmgr->xfrin_in_progress); 19050 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable)); 19051 for (size_t i = 0; i < UNREACH_CACHE_SIZE; i++) { 19052 atomic_init(&zmgr->unreachable[i].expire, 0); 19053 } 19054 isc_rwlock_init(&zmgr->rwlock); 19055 19056 /* Unreachable lock. */ 19057 isc_rwlock_init(&zmgr->urlock); 19058 19059 isc_ratelimiter_create(loop, &zmgr->checkdsrl); 19060 isc_ratelimiter_create(loop, &zmgr->notifyrl); 19061 isc_ratelimiter_create(loop, &zmgr->refreshrl); 19062 isc_ratelimiter_create(loop, &zmgr->startupnotifyrl); 19063 isc_ratelimiter_create(loop, &zmgr->startuprefreshrl); 19064 19065 zmgr->mctxpool = isc_mem_cget(zmgr->mctx, zmgr->workers, 19066 sizeof(zmgr->mctxpool[0])); 19067 for (size_t i = 0; i < zmgr->workers; i++) { 19068 isc_mem_create(&zmgr->mctxpool[i]); 19069 isc_mem_setname(zmgr->mctxpool[i], "zonemgr-mctxpool"); 19070 } 19071 19072 /* Key file I/O locks. */ 19073 zonemgr_keymgmt_init(zmgr); 19074 19075 /* Default to 20 refresh queries / notifies / checkds per second. */ 19076 setrl(zmgr->checkdsrl, &zmgr->checkdsrate, 20); 19077 setrl(zmgr->notifyrl, &zmgr->notifyrate, 20); 19078 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20); 19079 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20); 19080 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20); 19081 isc_ratelimiter_setpushpop(zmgr->startupnotifyrl, true); 19082 isc_ratelimiter_setpushpop(zmgr->startuprefreshrl, true); 19083 19084 zmgr->tlsctx_cache = NULL; 19085 isc_rwlock_init(&zmgr->tlsctx_cache_rwlock); 19086 19087 zmgr->magic = ZONEMGR_MAGIC; 19088 19089 *zmgrp = zmgr; 19090 } 19091 19092 isc_result_t 19093 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) { 19094 isc_mem_t *mctx = NULL; 19095 dns_zone_t *zone = NULL; 19096 unsigned int tid; 19097 19098 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19099 REQUIRE(zonep != NULL && *zonep == NULL); 19100 19101 if (zmgr->mctxpool == NULL) { 19102 return ISC_R_FAILURE; 19103 } 19104 19105 tid = isc_random_uniform(zmgr->workers); 19106 19107 mctx = zmgr->mctxpool[tid]; 19108 if (mctx == NULL) { 19109 return ISC_R_FAILURE; 19110 } 19111 19112 dns_zone_create(&zone, mctx, tid); 19113 19114 *zonep = zone; 19115 19116 return ISC_R_SUCCESS; 19117 } 19118 19119 isc_result_t 19120 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 19121 REQUIRE(DNS_ZONE_VALID(zone)); 19122 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19123 19124 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19125 LOCK_ZONE(zone); 19126 REQUIRE(zone->timer == NULL); 19127 REQUIRE(zone->zmgr == NULL); 19128 19129 isc_loop_t *loop = isc_loop_get(zmgr->loopmgr, zone->tid); 19130 isc_loop_attach(loop, &zone->loop); 19131 19132 zonemgr_keymgmt_add(zmgr, zone, &zone->kfio); 19133 INSIST(zone->kfio != NULL); 19134 19135 ISC_LIST_APPEND(zmgr->zones, zone, link); 19136 zone->zmgr = zmgr; 19137 19138 isc_refcount_increment(&zmgr->refs); 19139 19140 UNLOCK_ZONE(zone); 19141 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19142 return ISC_R_SUCCESS; 19143 } 19144 19145 void 19146 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 19147 REQUIRE(DNS_ZONE_VALID(zone)); 19148 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19149 REQUIRE(zone->zmgr == zmgr); 19150 19151 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19152 LOCK_ZONE(zone); 19153 19154 ISC_LIST_UNLINK(zmgr->zones, zone, link); 19155 19156 if (zone->kfio != NULL) { 19157 zonemgr_keymgmt_delete(zmgr, &zone->kfio); 19158 ENSURE(zone->kfio == NULL); 19159 } 19160 19161 if (zone->timer != NULL) { 19162 isc_refcount_decrement(&zone->irefs); 19163 isc_timer_destroy(&zone->timer); 19164 } 19165 19166 isc_loop_detach(&zone->loop); 19167 19168 /* Detach below, outside of the write lock. */ 19169 zone->zmgr = NULL; 19170 19171 UNLOCK_ZONE(zone); 19172 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19173 19174 dns_zonemgr_detach(&zmgr); 19175 } 19176 19177 void 19178 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) { 19179 REQUIRE(DNS_ZONEMGR_VALID(source)); 19180 REQUIRE(target != NULL && *target == NULL); 19181 19182 isc_refcount_increment(&source->refs); 19183 19184 *target = source; 19185 } 19186 19187 void 19188 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) { 19189 dns_zonemgr_t *zmgr; 19190 19191 REQUIRE(zmgrp != NULL); 19192 zmgr = *zmgrp; 19193 *zmgrp = NULL; 19194 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19195 19196 if (isc_refcount_decrement(&zmgr->refs) == 1) { 19197 zonemgr_free(zmgr); 19198 } 19199 } 19200 19201 isc_result_t 19202 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) { 19203 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19204 19205 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19206 for (dns_zone_t *zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 19207 zone = ISC_LIST_NEXT(zone, link)) 19208 { 19209 isc_time_t now; 19210 19211 LOCK_ZONE(zone); 19212 now = isc_time_now(); 19213 zone_settimer(zone, &now); 19214 UNLOCK_ZONE(zone); 19215 } 19216 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19217 19218 /* 19219 * Recent configuration changes may have increased the 19220 * amount of available transfers quota. Make sure any 19221 * transfers currently blocked on quota get started if 19222 * possible. 19223 */ 19224 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19225 zmgr_resume_xfrs(zmgr, true); 19226 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19227 return ISC_R_SUCCESS; 19228 } 19229 19230 void 19231 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) { 19232 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19233 19234 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19235 zmgr_resume_xfrs(zmgr, true); 19236 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19237 } 19238 19239 void 19240 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) { 19241 dns_zone_t *zone; 19242 19243 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19244 19245 isc_ratelimiter_shutdown(zmgr->checkdsrl); 19246 isc_ratelimiter_shutdown(zmgr->notifyrl); 19247 isc_ratelimiter_shutdown(zmgr->refreshrl); 19248 isc_ratelimiter_shutdown(zmgr->startupnotifyrl); 19249 isc_ratelimiter_shutdown(zmgr->startuprefreshrl); 19250 19251 for (size_t i = 0; i < zmgr->workers; i++) { 19252 isc_mem_detach(&zmgr->mctxpool[i]); 19253 } 19254 19255 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19256 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 19257 zone = ISC_LIST_NEXT(zone, link)) 19258 { 19259 LOCK_ZONE(zone); 19260 forward_cancel(zone); 19261 UNLOCK_ZONE(zone); 19262 } 19263 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19264 } 19265 19266 static void 19267 zonemgr_free(dns_zonemgr_t *zmgr) { 19268 REQUIRE(ISC_LIST_EMPTY(zmgr->zones)); 19269 19270 zmgr->magic = 0; 19271 19272 isc_refcount_destroy(&zmgr->refs); 19273 isc_ratelimiter_detach(&zmgr->checkdsrl); 19274 isc_ratelimiter_detach(&zmgr->notifyrl); 19275 isc_ratelimiter_detach(&zmgr->refreshrl); 19276 isc_ratelimiter_detach(&zmgr->startupnotifyrl); 19277 isc_ratelimiter_detach(&zmgr->startuprefreshrl); 19278 19279 isc_mem_cput(zmgr->mctx, zmgr->mctxpool, zmgr->workers, 19280 sizeof(zmgr->mctxpool[0])); 19281 19282 isc_rwlock_destroy(&zmgr->urlock); 19283 isc_rwlock_destroy(&zmgr->rwlock); 19284 isc_rwlock_destroy(&zmgr->tlsctx_cache_rwlock); 19285 19286 zonemgr_keymgmt_destroy(zmgr); 19287 19288 if (zmgr->tlsctx_cache != NULL) { 19289 isc_tlsctx_cache_detach(&zmgr->tlsctx_cache); 19290 } 19291 isc_mem_putanddetach(&zmgr->mctx, zmgr, sizeof(*zmgr)); 19292 } 19293 19294 void 19295 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value) { 19296 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19297 19298 zmgr->transfersin = value; 19299 } 19300 19301 uint32_t 19302 dns_zonemgr_gettransfersin(dns_zonemgr_t *zmgr) { 19303 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19304 19305 return zmgr->transfersin; 19306 } 19307 19308 void 19309 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, uint32_t value) { 19310 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19311 19312 zmgr->transfersperns = value; 19313 } 19314 19315 uint32_t 19316 dns_zonemgr_gettransfersperns(dns_zonemgr_t *zmgr) { 19317 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19318 19319 return zmgr->transfersperns; 19320 } 19321 19322 /* 19323 * Try to start a new incoming zone transfer to fill a quota 19324 * slot that was just vacated. 19325 * 19326 * Requires: 19327 * The zone manager is locked by the caller. 19328 */ 19329 static void 19330 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi) { 19331 dns_zone_t *zone; 19332 dns_zone_t *next; 19333 19334 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); zone != NULL; 19335 zone = next) 19336 { 19337 isc_result_t result; 19338 next = ISC_LIST_NEXT(zone, statelink); 19339 result = zmgr_start_xfrin_ifquota(zmgr, zone); 19340 if (result == ISC_R_SUCCESS) { 19341 if (multi) { 19342 continue; 19343 } 19344 /* 19345 * We successfully filled the slot. We're done. 19346 */ 19347 break; 19348 } else if (result == ISC_R_QUOTA) { 19349 /* 19350 * Not enough quota. This is probably the per-server 19351 * quota, because we usually get called when a unit of 19352 * global quota has just been freed. Try the next 19353 * zone, it may succeed if it uses another primary. 19354 */ 19355 continue; 19356 } else { 19357 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 19358 ISC_LOG_DEBUG(1), 19359 "starting zone transfer: %s", 19360 isc_result_totext(result)); 19361 break; 19362 } 19363 } 19364 } 19365 19366 /* 19367 * Try to start an incoming zone transfer for 'zone', quota permitting. 19368 * 19369 * Requires: 19370 * The zone manager is locked by the caller. 19371 * 19372 * Returns: 19373 * ISC_R_SUCCESS There was enough quota and we attempted to 19374 * start a transfer. zone_xfrdone() has been or will 19375 * be called. 19376 * ISC_R_QUOTA Not enough quota. 19377 * Others Failure. 19378 */ 19379 static isc_result_t 19380 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 19381 dns_peer_t *peer = NULL; 19382 isc_netaddr_t primaryip; 19383 isc_sockaddr_t curraddr; 19384 uint32_t nxfrsin, nxfrsperns; 19385 dns_zone_t *x = NULL; 19386 uint32_t maxtransfersin, maxtransfersperns; 19387 19388 /* 19389 * If we are exiting just pretend we got quota so the zone will 19390 * be cleaned up in the zone's loop context. 19391 */ 19392 LOCK_ZONE(zone); 19393 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 19394 UNLOCK_ZONE(zone); 19395 goto gotquota; 19396 } 19397 19398 /* 19399 * Find any configured information about the server we'd 19400 * like to transfer this zone from. 19401 */ 19402 curraddr = dns_remote_curraddr(&zone->primaries); 19403 isc_netaddr_fromsockaddr(&primaryip, &curraddr); 19404 (void)dns_peerlist_peerbyaddr(zone->view->peers, &primaryip, &peer); 19405 UNLOCK_ZONE(zone); 19406 19407 /* 19408 * Determine the total maximum number of simultaneous 19409 * transfers allowed, and the maximum for this specific 19410 * primary. 19411 */ 19412 maxtransfersin = zmgr->transfersin; 19413 maxtransfersperns = zmgr->transfersperns; 19414 if (peer != NULL) { 19415 (void)dns_peer_gettransfers(peer, &maxtransfersperns); 19416 } 19417 19418 /* 19419 * Count the total number of transfers that are in progress, 19420 * and the number of transfers in progress from this primary. 19421 * We linearly scan a list of all transfers; if this turns 19422 * out to be too slow, we could hash on the primary address. 19423 */ 19424 nxfrsin = nxfrsperns = 0; 19425 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress); x != NULL; 19426 x = ISC_LIST_NEXT(x, statelink)) 19427 { 19428 isc_netaddr_t xip; 19429 isc_sockaddr_t xaddr; 19430 19431 LOCK_ZONE(x); 19432 xaddr = dns_remote_curraddr(&x->primaries); 19433 isc_netaddr_fromsockaddr(&xip, &xaddr); 19434 UNLOCK_ZONE(x); 19435 19436 nxfrsin++; 19437 if (isc_netaddr_equal(&xip, &primaryip)) { 19438 nxfrsperns++; 19439 } 19440 } 19441 19442 /* Enforce quota. */ 19443 if (nxfrsin >= maxtransfersin) { 19444 return ISC_R_QUOTA; 19445 } 19446 19447 if (nxfrsperns >= maxtransfersperns) { 19448 return ISC_R_QUOTA; 19449 } 19450 19451 gotquota: 19452 /* 19453 * We have sufficient quota. Move the zone to the "xfrin_in_progress" 19454 * list and start the actual transfer asynchronously. 19455 */ 19456 LOCK_ZONE(zone); 19457 INSIST(zone->statelist == &zmgr->waiting_for_xfrin); 19458 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink); 19459 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink); 19460 zone->statelist = &zmgr->xfrin_in_progress; 19461 isc_async_run(zone->loop, got_transfer_quota, zone); 19462 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 19463 "Transfer started."); 19464 UNLOCK_ZONE(zone); 19465 19466 return ISC_R_SUCCESS; 19467 } 19468 19469 static void 19470 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) { 19471 char *buf; 19472 int buflen; 19473 isc_result_t result; 19474 19475 buflen = strlen(path) + strlen(templat) + 2; 19476 19477 buf = isc_mem_get(zone->mctx, buflen); 19478 19479 result = isc_file_template(path, templat, buf, buflen); 19480 if (result != ISC_R_SUCCESS) { 19481 goto cleanup; 19482 } 19483 19484 result = isc_file_renameunique(path, buf); 19485 if (result != ISC_R_SUCCESS) { 19486 goto cleanup; 19487 } 19488 19489 dns_zone_log(zone, ISC_LOG_WARNING, 19490 "unable to load from '%s'; " 19491 "renaming file to '%s' for failure analysis and " 19492 "retransferring.", 19493 path, buf); 19494 19495 cleanup: 19496 isc_mem_put(zone->mctx, buf, buflen); 19497 } 19498 19499 static void 19500 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) { 19501 isc_interval_t interval; 19502 uint32_t s, ns; 19503 uint32_t pertic; 19504 19505 if (value == 0) { 19506 value = 1; 19507 } 19508 19509 if (value == 1) { 19510 s = 1; 19511 ns = 0; 19512 pertic = 1; 19513 } else if (value <= 10) { 19514 s = 0; 19515 ns = 1000000000 / value; 19516 pertic = 1; 19517 } else { 19518 s = 0; 19519 ns = (1000000000 / value) * 10; 19520 pertic = 10; 19521 } 19522 19523 isc_interval_set(&interval, s, ns); 19524 19525 isc_ratelimiter_setinterval(rl, &interval); 19526 isc_ratelimiter_setpertic(rl, pertic); 19527 19528 *rate = value; 19529 } 19530 19531 void 19532 dns_zonemgr_setcheckdsrate(dns_zonemgr_t *zmgr, unsigned int value) { 19533 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19534 19535 setrl(zmgr->checkdsrl, &zmgr->checkdsrate, value); 19536 } 19537 19538 void 19539 dns_zonemgr_setnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) { 19540 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19541 19542 setrl(zmgr->notifyrl, &zmgr->notifyrate, value); 19543 } 19544 19545 void 19546 dns_zonemgr_setstartupnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) { 19547 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19548 19549 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value); 19550 } 19551 19552 void 19553 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) { 19554 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19555 19556 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value); 19557 /* XXXMPA separate out once we have the code to support this. */ 19558 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value); 19559 } 19560 19561 unsigned int 19562 dns_zonemgr_getnotifyrate(dns_zonemgr_t *zmgr) { 19563 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19564 19565 return zmgr->notifyrate; 19566 } 19567 19568 unsigned int 19569 dns_zonemgr_getstartupnotifyrate(dns_zonemgr_t *zmgr) { 19570 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19571 19572 return zmgr->startupnotifyrate; 19573 } 19574 19575 unsigned int 19576 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) { 19577 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19578 19579 return zmgr->serialqueryrate; 19580 } 19581 19582 bool 19583 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 19584 isc_sockaddr_t *local, isc_time_t *now) { 19585 unsigned int i; 19586 uint32_t seconds = isc_time_seconds(now); 19587 uint32_t count = 0; 19588 19589 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19590 19591 RWLOCK(&zmgr->urlock, isc_rwlocktype_read); 19592 for (i = 0; i < UNREACH_CACHE_SIZE; i++) { 19593 if (atomic_load(&zmgr->unreachable[i].expire) >= seconds && 19594 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 19595 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 19596 { 19597 atomic_store_relaxed(&zmgr->unreachable[i].last, 19598 seconds); 19599 count = zmgr->unreachable[i].count; 19600 break; 19601 } 19602 } 19603 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read); 19604 return i < UNREACH_CACHE_SIZE && count > 1U; 19605 } 19606 19607 void 19608 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 19609 isc_sockaddr_t *local) { 19610 unsigned int i; 19611 19612 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19613 19614 RWLOCK(&zmgr->urlock, isc_rwlocktype_read); 19615 for (i = 0; i < UNREACH_CACHE_SIZE; i++) { 19616 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 19617 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 19618 { 19619 atomic_store_relaxed(&zmgr->unreachable[i].expire, 0); 19620 break; 19621 } 19622 } 19623 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read); 19624 } 19625 19626 void 19627 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 19628 isc_sockaddr_t *local, isc_time_t *now) { 19629 uint32_t seconds = isc_time_seconds(now); 19630 uint32_t expire = 0, last = seconds; 19631 unsigned int slot = UNREACH_CACHE_SIZE, oldest = 0; 19632 bool update_entry = true; 19633 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19634 19635 RWLOCK(&zmgr->urlock, isc_rwlocktype_write); 19636 for (unsigned int i = 0; i < UNREACH_CACHE_SIZE; i++) { 19637 /* Existing entry? */ 19638 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 19639 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 19640 { 19641 update_entry = false; 19642 slot = i; 19643 expire = atomic_load_relaxed( 19644 &zmgr->unreachable[i].expire); 19645 break; 19646 } 19647 /* Pick first empty slot? */ 19648 if (atomic_load_relaxed(&zmgr->unreachable[i].expire) < seconds) 19649 { 19650 slot = i; 19651 break; 19652 } 19653 /* The worst case, least recently used slot? */ 19654 if (atomic_load_relaxed(&zmgr->unreachable[i].last) < last) { 19655 last = atomic_load_relaxed(&zmgr->unreachable[i].last); 19656 oldest = i; 19657 } 19658 } 19659 19660 /* We haven't found any existing or free slots, use the oldest */ 19661 if (slot == UNREACH_CACHE_SIZE) { 19662 slot = oldest; 19663 } 19664 19665 if (expire < seconds) { 19666 /* Expired or new entry, reset count to 1 */ 19667 zmgr->unreachable[slot].count = 1; 19668 } else { 19669 zmgr->unreachable[slot].count++; 19670 } 19671 atomic_store_relaxed(&zmgr->unreachable[slot].expire, 19672 seconds + UNREACH_HOLD_TIME); 19673 atomic_store_relaxed(&zmgr->unreachable[slot].last, seconds); 19674 if (update_entry) { 19675 zmgr->unreachable[slot].remote = *remote; 19676 zmgr->unreachable[slot].local = *local; 19677 } 19678 19679 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write); 19680 } 19681 19682 void 19683 dns_zone_stopxfr(dns_zone_t *zone) { 19684 dns_xfrin_t *xfr = NULL; 19685 19686 REQUIRE(DNS_ZONE_VALID(zone)); 19687 19688 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_read); 19689 LOCK_ZONE(zone); 19690 if (zone->statelist == &zone->zmgr->xfrin_in_progress && 19691 zone->xfr != NULL) 19692 { 19693 dns_xfrin_attach(zone->xfr, &xfr); 19694 } 19695 UNLOCK_ZONE(zone); 19696 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_read); 19697 19698 if (xfr != NULL) { 19699 dns_xfrin_shutdown(xfr); 19700 dns_xfrin_detach(&xfr); 19701 } 19702 } 19703 19704 void 19705 dns_zone_forcexfr(dns_zone_t *zone) { 19706 REQUIRE(DNS_ZONE_VALID(zone)); 19707 19708 if (zone->type == dns_zone_primary || 19709 (zone->type == dns_zone_redirect && 19710 dns_remote_addresses(&zone->primaries) == NULL)) 19711 { 19712 return; 19713 } 19714 19715 LOCK_ZONE(zone); 19716 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER); 19717 UNLOCK_ZONE(zone); 19718 dns_zone_refresh(zone); 19719 } 19720 19721 bool 19722 dns_zone_isforced(dns_zone_t *zone) { 19723 REQUIRE(DNS_ZONE_VALID(zone)); 19724 19725 return DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER); 19726 } 19727 19728 isc_result_t 19729 dns_zone_setstatistics(dns_zone_t *zone, bool on) { 19730 /* 19731 * This function is obsoleted. 19732 */ 19733 UNUSED(zone); 19734 UNUSED(on); 19735 return ISC_R_NOTIMPLEMENTED; 19736 } 19737 19738 uint64_t * 19739 dns_zone_getstatscounters(dns_zone_t *zone) { 19740 /* 19741 * This function is obsoleted. 19742 */ 19743 UNUSED(zone); 19744 return NULL; 19745 } 19746 19747 void 19748 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) { 19749 REQUIRE(DNS_ZONE_VALID(zone)); 19750 REQUIRE(zone->stats == NULL); 19751 19752 LOCK_ZONE(zone); 19753 zone->stats = NULL; 19754 isc_stats_attach(stats, &zone->stats); 19755 UNLOCK_ZONE(zone); 19756 } 19757 19758 void 19759 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) { 19760 REQUIRE(DNS_ZONE_VALID(zone)); 19761 19762 LOCK_ZONE(zone); 19763 if (zone->requeststats_on && stats == NULL) { 19764 zone->requeststats_on = false; 19765 } else if (!zone->requeststats_on && stats != NULL) { 19766 if (zone->requeststats == NULL) { 19767 isc_stats_attach(stats, &zone->requeststats); 19768 } 19769 zone->requeststats_on = true; 19770 } 19771 UNLOCK_ZONE(zone); 19772 } 19773 19774 void 19775 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) { 19776 REQUIRE(DNS_ZONE_VALID(zone)); 19777 19778 LOCK_ZONE(zone); 19779 if (zone->requeststats_on && stats != NULL) { 19780 if (zone->rcvquerystats == NULL) { 19781 dns_stats_attach(stats, &zone->rcvquerystats); 19782 zone->requeststats_on = true; 19783 } 19784 } 19785 UNLOCK_ZONE(zone); 19786 } 19787 19788 void 19789 dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats) { 19790 REQUIRE(DNS_ZONE_VALID(zone)); 19791 19792 LOCK_ZONE(zone); 19793 if (stats != NULL && zone->dnssecsignstats == NULL) { 19794 dns_stats_attach(stats, &zone->dnssecsignstats); 19795 } 19796 UNLOCK_ZONE(zone); 19797 } 19798 19799 dns_stats_t * 19800 dns_zone_getdnssecsignstats(dns_zone_t *zone) { 19801 REQUIRE(DNS_ZONE_VALID(zone)); 19802 19803 return zone->dnssecsignstats; 19804 } 19805 19806 isc_stats_t * 19807 dns_zone_getrequeststats(dns_zone_t *zone) { 19808 /* 19809 * We don't lock zone for efficiency reason. This is not catastrophic 19810 * because requeststats must always be valid when requeststats_on is 19811 * true. 19812 * Some counters may be incremented while requeststats_on is becoming 19813 * false, or some cannot be incremented just after the statistics are 19814 * installed, but it shouldn't matter much in practice. 19815 */ 19816 if (zone->requeststats_on) { 19817 return zone->requeststats; 19818 } else { 19819 return NULL; 19820 } 19821 } 19822 19823 /* 19824 * Return the received query stats bucket 19825 * see note from dns_zone_getrequeststats() 19826 */ 19827 dns_stats_t * 19828 dns_zone_getrcvquerystats(dns_zone_t *zone) { 19829 if (zone->requeststats_on) { 19830 return zone->rcvquerystats; 19831 } else { 19832 return NULL; 19833 } 19834 } 19835 19836 void 19837 dns_zone_dialup(dns_zone_t *zone) { 19838 REQUIRE(DNS_ZONE_VALID(zone)); 19839 19840 zone_debuglog(zone, __func__, 3, "notify = %d, refresh = %d", 19841 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY), 19842 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)); 19843 19844 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) { 19845 dns_zone_notify(zone); 19846 } 19847 if (zone->type != dns_zone_primary && 19848 dns_remote_addresses(&zone->primaries) != NULL && 19849 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 19850 { 19851 dns_zone_refresh(zone); 19852 } 19853 } 19854 19855 void 19856 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) { 19857 REQUIRE(DNS_ZONE_VALID(zone)); 19858 19859 LOCK_ZONE(zone); 19860 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY | 19861 DNS_ZONEFLG_DIALREFRESH | 19862 DNS_ZONEFLG_NOREFRESH); 19863 switch (dialup) { 19864 case dns_dialuptype_no: 19865 break; 19866 case dns_dialuptype_yes: 19867 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY | 19868 DNS_ZONEFLG_DIALREFRESH | 19869 DNS_ZONEFLG_NOREFRESH)); 19870 break; 19871 case dns_dialuptype_notify: 19872 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 19873 break; 19874 case dns_dialuptype_notifypassive: 19875 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 19876 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 19877 break; 19878 case dns_dialuptype_refresh: 19879 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH); 19880 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 19881 break; 19882 case dns_dialuptype_passive: 19883 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 19884 break; 19885 default: 19886 UNREACHABLE(); 19887 } 19888 UNLOCK_ZONE(zone); 19889 } 19890 19891 isc_result_t 19892 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) { 19893 isc_result_t result = ISC_R_SUCCESS; 19894 19895 REQUIRE(DNS_ZONE_VALID(zone)); 19896 19897 LOCK_ZONE(zone); 19898 result = dns_zone_setstring(zone, &zone->keydirectory, directory); 19899 UNLOCK_ZONE(zone); 19900 19901 return result; 19902 } 19903 19904 const char * 19905 dns_zone_getkeydirectory(dns_zone_t *zone) { 19906 REQUIRE(DNS_ZONE_VALID(zone)); 19907 19908 return zone->keydirectory; 19909 } 19910 19911 void 19912 dns_zone_setkeystores(dns_zone_t *zone, dns_keystorelist_t *keystores) { 19913 REQUIRE(DNS_ZONE_VALID(zone)); 19914 19915 LOCK_ZONE(zone); 19916 zone->keystores = keystores; 19917 UNLOCK_ZONE(zone); 19918 } 19919 19920 dns_keystorelist_t * 19921 dns_zone_getkeystores(dns_zone_t *zone) { 19922 dns_keystorelist_t *ks = NULL; 19923 19924 REQUIRE(DNS_ZONE_VALID(zone)); 19925 19926 LOCK_ZONE(zone); 19927 if (inline_raw(zone) && zone->secure != NULL) { 19928 ks = zone->secure->keystores; 19929 } else { 19930 ks = zone->keystores; 19931 } 19932 UNLOCK_ZONE(zone); 19933 19934 return ks; 19935 } 19936 19937 unsigned int 19938 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, dns_zonestate_t state) { 19939 dns_zone_t *zone; 19940 unsigned int count = 0; 19941 19942 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19943 19944 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19945 switch (state) { 19946 case DNS_ZONESTATE_XFERRUNNING: 19947 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress); 19948 zone != NULL; zone = ISC_LIST_NEXT(zone, statelink)) 19949 { 19950 count++; 19951 } 19952 break; 19953 case DNS_ZONESTATE_XFERDEFERRED: 19954 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); 19955 zone != NULL; zone = ISC_LIST_NEXT(zone, statelink)) 19956 { 19957 count++; 19958 } 19959 break; 19960 case DNS_ZONESTATE_XFERFIRSTREFRESH: 19961 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 19962 zone = ISC_LIST_NEXT(zone, link)) 19963 { 19964 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FIRSTREFRESH)) { 19965 count++; 19966 } 19967 } 19968 break; 19969 case DNS_ZONESTATE_SOAQUERY: 19970 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 19971 zone = ISC_LIST_NEXT(zone, link)) 19972 { 19973 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { 19974 count++; 19975 } 19976 } 19977 break; 19978 case DNS_ZONESTATE_ANY: 19979 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 19980 zone = ISC_LIST_NEXT(zone, link)) 19981 { 19982 dns_view_t *view = zone->view; 19983 if (view != NULL && strcmp(view->name, "_bind") == 0) { 19984 continue; 19985 } 19986 count++; 19987 } 19988 break; 19989 case DNS_ZONESTATE_AUTOMATIC: 19990 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 19991 zone = ISC_LIST_NEXT(zone, link)) 19992 { 19993 dns_view_t *view = zone->view; 19994 if (view != NULL && strcmp(view->name, "_bind") == 0) { 19995 continue; 19996 } 19997 if (zone->automatic) { 19998 count++; 19999 } 20000 } 20001 break; 20002 default: 20003 UNREACHABLE(); 20004 } 20005 20006 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 20007 20008 return count; 20009 } 20010 20011 isc_result_t 20012 dns_zone_getxfr(dns_zone_t *zone, dns_xfrin_t **xfrp, bool *is_firstrefresh, 20013 bool *is_running, bool *is_deferred, bool *is_presoa, 20014 bool *is_pending, bool *needs_refresh) { 20015 REQUIRE(DNS_ZONE_VALID(zone)); 20016 REQUIRE(xfrp != NULL && *xfrp == NULL); 20017 20018 if (zone->zmgr == NULL) { 20019 return ISC_R_FAILURE; 20020 } 20021 20022 /* Reset. */ 20023 *is_firstrefresh = false; 20024 *is_running = false; 20025 *is_deferred = false; 20026 *is_presoa = false; 20027 *is_pending = false; 20028 *needs_refresh = false; 20029 20030 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_read); 20031 LOCK_ZONE(zone); 20032 *is_firstrefresh = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FIRSTREFRESH); 20033 if (zone->xfr != NULL) { 20034 dns_xfrin_attach(zone->xfr, xfrp); 20035 } 20036 if (zone->statelist == &zone->zmgr->xfrin_in_progress) { 20037 *is_running = true; 20038 /* 20039 * The NEEDREFRESH flag is set only when a notify was received 20040 * while the current zone transfer is running. 20041 */ 20042 *needs_refresh = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 20043 } else if (zone->statelist == &zone->zmgr->waiting_for_xfrin) { 20044 *is_deferred = true; 20045 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { 20046 if (zone->request != NULL) { 20047 *is_presoa = true; 20048 } else { 20049 *is_pending = true; 20050 } 20051 } else { 20052 /* 20053 * No operation is ongoing or pending, just check if the zone 20054 * needs a refresh by looking at the refresh and expire times. 20055 */ 20056 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && 20057 (zone->type == dns_zone_secondary || 20058 zone->type == dns_zone_mirror || 20059 zone->type == dns_zone_stub)) 20060 { 20061 isc_time_t now = isc_time_now(); 20062 if (isc_time_compare(&now, &zone->refreshtime) >= 0 || 20063 isc_time_compare(&now, &zone->expiretime) >= 0) 20064 { 20065 *needs_refresh = true; 20066 } 20067 } 20068 } 20069 UNLOCK_ZONE(zone); 20070 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_read); 20071 20072 return ISC_R_SUCCESS; 20073 } 20074 20075 void 20076 dns_zone_lock_keyfiles(dns_zone_t *zone) { 20077 REQUIRE(DNS_ZONE_VALID(zone)); 20078 20079 if (zone->kasp == NULL) { 20080 /* No need to lock, nothing is writing key files. */ 20081 return; 20082 } 20083 20084 REQUIRE(DNS_KEYFILEIO_VALID(zone->kfio)); 20085 isc_mutex_lock(&zone->kfio->lock); 20086 } 20087 20088 void 20089 dns_zone_unlock_keyfiles(dns_zone_t *zone) { 20090 REQUIRE(DNS_ZONE_VALID(zone)); 20091 20092 if (zone->kasp == NULL) { 20093 /* No need to lock, nothing is writing key files. */ 20094 return; 20095 } 20096 20097 REQUIRE(DNS_KEYFILEIO_VALID(zone->kfio)); 20098 isc_mutex_unlock(&zone->kfio->lock); 20099 } 20100 20101 isc_result_t 20102 dns_zone_checknames(dns_zone_t *zone, const dns_name_t *name, 20103 dns_rdata_t *rdata) { 20104 bool ok = true; 20105 bool fail = false; 20106 char namebuf[DNS_NAME_FORMATSIZE]; 20107 char namebuf2[DNS_NAME_FORMATSIZE]; 20108 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 20109 int level = ISC_LOG_WARNING; 20110 dns_name_t bad; 20111 20112 REQUIRE(DNS_ZONE_VALID(zone)); 20113 20114 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) && 20115 rdata->type != dns_rdatatype_nsec3) 20116 { 20117 return ISC_R_SUCCESS; 20118 } 20119 20120 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) || 20121 rdata->type == dns_rdatatype_nsec3) 20122 { 20123 level = ISC_LOG_ERROR; 20124 fail = true; 20125 } 20126 20127 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, true); 20128 if (!ok) { 20129 dns_name_format(name, namebuf, sizeof(namebuf)); 20130 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 20131 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf, 20132 isc_result_totext(DNS_R_BADOWNERNAME)); 20133 if (fail) { 20134 return DNS_R_BADOWNERNAME; 20135 } 20136 } 20137 20138 dns_name_init(&bad, NULL); 20139 ok = dns_rdata_checknames(rdata, name, &bad); 20140 if (!ok) { 20141 dns_name_format(name, namebuf, sizeof(namebuf)); 20142 dns_name_format(&bad, namebuf2, sizeof(namebuf2)); 20143 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 20144 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf, 20145 namebuf2, isc_result_totext(DNS_R_BADNAME)); 20146 if (fail) { 20147 return DNS_R_BADNAME; 20148 } 20149 } 20150 20151 return ISC_R_SUCCESS; 20152 } 20153 20154 void 20155 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) { 20156 REQUIRE(DNS_ZONE_VALID(zone)); 20157 zone->checkmx = checkmx; 20158 } 20159 20160 void 20161 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) { 20162 REQUIRE(DNS_ZONE_VALID(zone)); 20163 zone->checksrv = checksrv; 20164 } 20165 20166 void 20167 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) { 20168 REQUIRE(DNS_ZONE_VALID(zone)); 20169 zone->checkns = checkns; 20170 } 20171 20172 void 20173 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) { 20174 REQUIRE(DNS_ZONE_VALID(zone)); 20175 20176 LOCK_ZONE(zone); 20177 zone->isself = isself; 20178 zone->isselfarg = arg; 20179 UNLOCK_ZONE(zone); 20180 } 20181 20182 void 20183 dns_zone_setnotifydelay(dns_zone_t *zone, uint32_t delay) { 20184 REQUIRE(DNS_ZONE_VALID(zone)); 20185 20186 LOCK_ZONE(zone); 20187 zone->notifydelay = delay; 20188 UNLOCK_ZONE(zone); 20189 } 20190 20191 uint32_t 20192 dns_zone_getnotifydelay(dns_zone_t *zone) { 20193 REQUIRE(DNS_ZONE_VALID(zone)); 20194 20195 return zone->notifydelay; 20196 } 20197 20198 isc_result_t 20199 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid, 20200 bool deleteit) { 20201 isc_result_t result; 20202 REQUIRE(DNS_ZONE_VALID(zone)); 20203 20204 dnssec_log(zone, ISC_LOG_NOTICE, 20205 "dns_zone_signwithkey(algorithm=%u, keyid=%u)", algorithm, 20206 keyid); 20207 LOCK_ZONE(zone); 20208 result = zone_signwithkey(zone, algorithm, keyid, deleteit); 20209 UNLOCK_ZONE(zone); 20210 20211 return result; 20212 } 20213 20214 /* 20215 * Called when a dynamic update for an NSEC3PARAM record is received. 20216 * 20217 * If set, transform the NSEC3 salt into human-readable form so that it can be 20218 * logged. Then call zone_addnsec3chain(), passing NSEC3PARAM RDATA to it. 20219 */ 20220 isc_result_t 20221 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 20222 isc_result_t result; 20223 char salt[255 * 2 + 1]; 20224 20225 REQUIRE(DNS_ZONE_VALID(zone)); 20226 20227 result = dns_nsec3param_salttotext(nsec3param, salt, sizeof(salt)); 20228 RUNTIME_CHECK(result == ISC_R_SUCCESS); 20229 dnssec_log(zone, ISC_LOG_NOTICE, 20230 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)", 20231 nsec3param->hash, nsec3param->iterations, salt); 20232 LOCK_ZONE(zone); 20233 result = zone_addnsec3chain(zone, nsec3param); 20234 UNLOCK_ZONE(zone); 20235 20236 return result; 20237 } 20238 20239 void 20240 dns_zone_setnodes(dns_zone_t *zone, uint32_t nodes) { 20241 REQUIRE(DNS_ZONE_VALID(zone)); 20242 20243 if (nodes == 0) { 20244 nodes = 1; 20245 } 20246 zone->nodes = nodes; 20247 } 20248 20249 void 20250 dns_zone_setsignatures(dns_zone_t *zone, uint32_t signatures) { 20251 REQUIRE(DNS_ZONE_VALID(zone)); 20252 20253 /* 20254 * We treat signatures as a signed value so explicitly 20255 * limit its range here. 20256 */ 20257 if (signatures > INT32_MAX) { 20258 signatures = INT32_MAX; 20259 } else if (signatures == 0) { 20260 signatures = 1; 20261 } 20262 zone->signatures = signatures; 20263 } 20264 20265 uint32_t 20266 dns_zone_getsignatures(dns_zone_t *zone) { 20267 REQUIRE(DNS_ZONE_VALID(zone)); 20268 return zone->signatures; 20269 } 20270 20271 void 20272 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) { 20273 REQUIRE(DNS_ZONE_VALID(zone)); 20274 zone->privatetype = type; 20275 } 20276 20277 dns_rdatatype_t 20278 dns_zone_getprivatetype(dns_zone_t *zone) { 20279 REQUIRE(DNS_ZONE_VALID(zone)); 20280 return zone->privatetype; 20281 } 20282 20283 static isc_result_t 20284 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid, 20285 bool deleteit) { 20286 dns_signing_t *signing; 20287 dns_signing_t *current; 20288 isc_result_t result = ISC_R_SUCCESS; 20289 isc_time_t now; 20290 dns_db_t *db = NULL; 20291 20292 signing = isc_mem_get(zone->mctx, sizeof *signing); 20293 20294 signing->magic = 0; 20295 signing->db = NULL; 20296 signing->dbiterator = NULL; 20297 signing->algorithm = algorithm; 20298 signing->keyid = keyid; 20299 signing->deleteit = deleteit; 20300 signing->done = false; 20301 20302 now = isc_time_now(); 20303 20304 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 20305 if (zone->db != NULL) { 20306 dns_db_attach(zone->db, &db); 20307 } 20308 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 20309 20310 if (db == NULL) { 20311 result = ISC_R_NOTFOUND; 20312 goto cleanup; 20313 } 20314 20315 dns_db_attach(db, &signing->db); 20316 20317 for (current = ISC_LIST_HEAD(zone->signing); current != NULL; 20318 current = ISC_LIST_NEXT(current, link)) 20319 { 20320 if (current->db == signing->db && 20321 current->algorithm == signing->algorithm && 20322 current->keyid == signing->keyid) 20323 { 20324 if (current->deleteit != signing->deleteit) { 20325 current->done = true; 20326 } else { 20327 goto cleanup; 20328 } 20329 } 20330 } 20331 20332 result = dns_db_createiterator(signing->db, 0, &signing->dbiterator); 20333 20334 if (result == ISC_R_SUCCESS) { 20335 result = dns_dbiterator_first(signing->dbiterator); 20336 } 20337 if (result == ISC_R_SUCCESS) { 20338 dns_dbiterator_pause(signing->dbiterator); 20339 ISC_LIST_INITANDAPPEND(zone->signing, signing, link); 20340 signing = NULL; 20341 if (isc_time_isepoch(&zone->signingtime)) { 20342 zone->signingtime = now; 20343 if (zone->loop != NULL) { 20344 zone_settimer(zone, &now); 20345 } 20346 } 20347 } 20348 20349 cleanup: 20350 if (signing != NULL) { 20351 if (signing->db != NULL) { 20352 dns_db_detach(&signing->db); 20353 } 20354 if (signing->dbiterator != NULL) { 20355 dns_dbiterator_destroy(&signing->dbiterator); 20356 } 20357 isc_mem_put(zone->mctx, signing, sizeof *signing); 20358 } 20359 if (db != NULL) { 20360 dns_db_detach(&db); 20361 } 20362 return result; 20363 } 20364 20365 /* Called once; *timep should be set to the current time. */ 20366 static isc_result_t 20367 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) { 20368 isc_result_t result; 20369 isc_stdtime_t now, then = 0, event; 20370 int i; 20371 20372 now = *timep; 20373 20374 for (i = 0; i <= DST_MAX_TIMES; i++) { 20375 result = dst_key_gettime(key, i, &event); 20376 if (result == ISC_R_SUCCESS && event > now && 20377 (then == 0 || event < then)) 20378 { 20379 then = event; 20380 } 20381 } 20382 20383 if (then != 0) { 20384 *timep = then; 20385 return ISC_R_SUCCESS; 20386 } 20387 20388 return ISC_R_NOTFOUND; 20389 } 20390 20391 static isc_result_t 20392 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 20393 const dns_rdata_t *rdata, bool *flag) { 20394 dns_rdataset_t rdataset; 20395 dns_dbnode_t *node = NULL; 20396 isc_result_t result; 20397 20398 dns_rdataset_init(&rdataset); 20399 if (rdata->type == dns_rdatatype_nsec3) { 20400 CHECK(dns_db_findnsec3node(db, name, false, &node)); 20401 } else { 20402 CHECK(dns_db_findnode(db, name, false, &node)); 20403 } 20404 result = dns_db_findrdataset(db, node, ver, rdata->type, 0, 20405 (isc_stdtime_t)0, &rdataset, NULL); 20406 if (result == ISC_R_NOTFOUND) { 20407 *flag = false; 20408 result = ISC_R_SUCCESS; 20409 goto failure; 20410 } 20411 20412 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 20413 result = dns_rdataset_next(&rdataset)) 20414 { 20415 dns_rdata_t myrdata = DNS_RDATA_INIT; 20416 dns_rdataset_current(&rdataset, &myrdata); 20417 if (!dns_rdata_compare(&myrdata, rdata)) { 20418 break; 20419 } 20420 } 20421 dns_rdataset_disassociate(&rdataset); 20422 if (result == ISC_R_SUCCESS) { 20423 *flag = true; 20424 } else if (result == ISC_R_NOMORE) { 20425 *flag = false; 20426 result = ISC_R_SUCCESS; 20427 } 20428 20429 failure: 20430 if (node != NULL) { 20431 dns_db_detachnode(db, &node); 20432 } 20433 return result; 20434 } 20435 20436 /* 20437 * Add records to signal the state of signing or of key removal. 20438 */ 20439 static isc_result_t 20440 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, 20441 dns_dbversion_t *ver, dns_diff_t *diff, bool sign_all) { 20442 dns_difftuple_t *tuple = NULL, *newtuple = NULL, *next = NULL; 20443 dns_difftuple_t *addtuple = NULL, *deltuple = NULL; 20444 dns_rdata_dnskey_t dnskey; 20445 dns_rdata_t rdata = DNS_RDATA_INIT; 20446 bool flag; 20447 isc_region_t r; 20448 isc_result_t result = ISC_R_SUCCESS; 20449 uint16_t keyid; 20450 unsigned char buf[5]; 20451 dns_name_t *name = dns_db_origin(db); 20452 dns_difftuplelist_t add = ISC_LIST_INITIALIZER; 20453 dns_difftuplelist_t del = ISC_LIST_INITIALIZER; 20454 dns_difftuplelist_t tuples = ISC_LIST_INITIALIZER; 20455 20456 /* 20457 * Move non DNSKEY and not DNSSEC DNSKEY records to tuples 20458 * and sort the remaining DNSKEY records to add and del. 20459 */ 20460 for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; 20461 tuple = ISC_LIST_HEAD(diff->tuples)) 20462 { 20463 if (tuple->rdata.type != dns_rdatatype_dnskey) { 20464 ISC_LIST_UNLINK(diff->tuples, tuple, link); 20465 ISC_LIST_APPEND(tuples, tuple, link); 20466 continue; 20467 } 20468 20469 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL); 20470 RUNTIME_CHECK(result == ISC_R_SUCCESS); 20471 if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK | 20472 DNS_KEYTYPE_NOAUTH)) != DNS_KEYOWNER_ZONE) 20473 { 20474 ISC_LIST_UNLINK(diff->tuples, tuple, link); 20475 ISC_LIST_APPEND(tuples, tuple, link); 20476 continue; 20477 } 20478 20479 ISC_LIST_UNLINK(diff->tuples, tuple, link); 20480 switch (tuple->op) { 20481 case DNS_DIFFOP_DEL: 20482 case DNS_DIFFOP_DELRESIGN: 20483 ISC_LIST_APPEND(del, tuple, link); 20484 break; 20485 case DNS_DIFFOP_ADD: 20486 case DNS_DIFFOP_ADDRESIGN: 20487 ISC_LIST_APPEND(add, tuple, link); 20488 break; 20489 default: 20490 UNREACHABLE(); 20491 } 20492 } 20493 20494 /* 20495 * Put the tuples that don't need more processing back onto 20496 * diff->tuples. 20497 */ 20498 ISC_LIST_APPENDLIST(diff->tuples, tuples, link); 20499 20500 /* 20501 * Filter out DNSKEY TTL changes and put them back onto diff->tuples. 20502 */ 20503 for (deltuple = ISC_LIST_HEAD(del); deltuple != NULL; deltuple = next) { 20504 next = ISC_LIST_NEXT(deltuple, link); 20505 for (addtuple = ISC_LIST_HEAD(add); addtuple != NULL; 20506 addtuple = ISC_LIST_NEXT(addtuple, link)) 20507 { 20508 int n = dns_rdata_compare(&deltuple->rdata, 20509 &addtuple->rdata); 20510 if (n == 0) { 20511 ISC_LIST_UNLINK(del, deltuple, link); 20512 ISC_LIST_APPEND(diff->tuples, deltuple, link); 20513 ISC_LIST_UNLINK(add, addtuple, link); 20514 ISC_LIST_APPEND(diff->tuples, addtuple, link); 20515 break; 20516 } 20517 } 20518 } 20519 20520 /* 20521 * Combine any remaining DNSKEY changes together. 20522 */ 20523 ISC_LIST_APPENDLIST(tuples, add, link); 20524 ISC_LIST_APPENDLIST(tuples, del, link); 20525 20526 /* 20527 * Add private records for keys that have been removed 20528 * or added. 20529 */ 20530 for (tuple = ISC_LIST_HEAD(tuples); tuple != NULL; 20531 tuple = ISC_LIST_NEXT(tuple, link)) 20532 { 20533 dns_rdata_toregion(&tuple->rdata, &r); 20534 20535 keyid = dst_region_computeid(&r); 20536 20537 buf[0] = dnskey.algorithm; 20538 buf[1] = (keyid & 0xff00) >> 8; 20539 buf[2] = (keyid & 0xff); 20540 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1; 20541 buf[4] = 0; 20542 rdata.data = buf; 20543 rdata.length = sizeof(buf); 20544 rdata.type = privatetype; 20545 rdata.rdclass = tuple->rdata.rdclass; 20546 20547 if (sign_all || tuple->op == DNS_DIFFOP_DEL) { 20548 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 20549 if (flag) { 20550 continue; 20551 } 20552 20553 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, 20554 name, 0, &rdata, &newtuple)); 20555 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 20556 INSIST(newtuple == NULL); 20557 } 20558 20559 /* 20560 * Remove any record which says this operation has already 20561 * completed. 20562 */ 20563 buf[4] = 1; 20564 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 20565 if (flag) { 20566 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, 20567 name, 0, &rdata, &newtuple)); 20568 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 20569 INSIST(newtuple == NULL); 20570 } 20571 } 20572 20573 failure: 20574 /* 20575 * Put the DNSKEY changes we cared about back on diff->tuples. 20576 */ 20577 ISC_LIST_APPENDLIST(diff->tuples, tuples, link); 20578 INSIST(ISC_LIST_EMPTY(add)); 20579 INSIST(ISC_LIST_EMPTY(del)); 20580 INSIST(ISC_LIST_EMPTY(tuples)); 20581 return result; 20582 } 20583 20584 /* 20585 * See if dns__zone_updatesigs() will update signature for RRset 'rrtype' at 20586 * the apex, and if not tickle them and cause to sign so that newly activated 20587 * keys are used. 20588 */ 20589 static isc_result_t 20590 tickle_apex_rrset(dns_rdatatype_t rrtype, dns_zone_t *zone, dns_db_t *db, 20591 dns_dbversion_t *ver, isc_stdtime_t now, dns_diff_t *diff, 20592 dns__zonediff_t *zonediff, dst_key_t **keys, 20593 unsigned int nkeys, isc_stdtime_t inception, 20594 isc_stdtime_t keyexpire) { 20595 dns_difftuple_t *tuple; 20596 isc_result_t result; 20597 20598 for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; 20599 tuple = ISC_LIST_NEXT(tuple, link)) 20600 { 20601 if (tuple->rdata.type == rrtype && 20602 dns_name_equal(&tuple->name, &zone->origin)) 20603 { 20604 break; 20605 } 20606 } 20607 20608 if (tuple == NULL) { 20609 result = del_sigs(zone, db, ver, &zone->origin, rrtype, 20610 zonediff, keys, nkeys, now, false); 20611 if (result != ISC_R_SUCCESS) { 20612 dnssec_log(zone, ISC_LOG_ERROR, 20613 "sign_apex:del_sigs -> %s", 20614 isc_result_totext(result)); 20615 return result; 20616 } 20617 result = add_sigs(db, ver, &zone->origin, zone, rrtype, 20618 zonediff->diff, keys, nkeys, zone->mctx, now, 20619 inception, keyexpire); 20620 if (result != ISC_R_SUCCESS) { 20621 dnssec_log(zone, ISC_LOG_ERROR, 20622 "sign_apex:add_sigs -> %s", 20623 isc_result_totext(result)); 20624 return result; 20625 } 20626 } 20627 20628 return ISC_R_SUCCESS; 20629 } 20630 20631 static isc_result_t 20632 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 20633 isc_stdtime_t now, dns_diff_t *diff, dns__zonediff_t *zonediff) { 20634 isc_result_t result; 20635 isc_stdtime_t inception, soaexpire, keyexpire; 20636 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 20637 unsigned int nkeys = 0, i; 20638 20639 result = dns_zone_findkeys(zone, db, ver, now, zone->mctx, 20640 DNS_MAXZONEKEYS, zone_keys, &nkeys); 20641 if (result != ISC_R_SUCCESS) { 20642 dnssec_log(zone, ISC_LOG_ERROR, 20643 "sign_apex:dns_zone_findkeys -> %s", 20644 isc_result_totext(result)); 20645 return result; 20646 } 20647 20648 inception = now - 3600; /* Allow for clock skew. */ 20649 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 20650 20651 keyexpire = dns_zone_getkeyvalidityinterval(zone); 20652 if (keyexpire == 0) { 20653 keyexpire = soaexpire - 1; 20654 } else { 20655 keyexpire += now; 20656 } 20657 20658 /* 20659 * See if dns__zone_updatesigs() will update DNSKEY/CDS/CDNSKEY 20660 * signature and if not cause them to sign so that newly activated 20661 * keys are used. 20662 */ 20663 result = tickle_apex_rrset(dns_rdatatype_dnskey, zone, db, ver, now, 20664 diff, zonediff, zone_keys, nkeys, inception, 20665 keyexpire); 20666 if (result != ISC_R_SUCCESS) { 20667 goto failure; 20668 } 20669 result = tickle_apex_rrset(dns_rdatatype_cds, zone, db, ver, now, diff, 20670 zonediff, zone_keys, nkeys, inception, 20671 keyexpire); 20672 if (result != ISC_R_SUCCESS) { 20673 goto failure; 20674 } 20675 result = tickle_apex_rrset(dns_rdatatype_cdnskey, zone, db, ver, now, 20676 diff, zonediff, zone_keys, nkeys, inception, 20677 keyexpire); 20678 if (result != ISC_R_SUCCESS) { 20679 goto failure; 20680 } 20681 20682 result = dns__zone_updatesigs(diff, db, ver, zone_keys, nkeys, zone, 20683 inception, soaexpire, keyexpire, now, 20684 zonediff); 20685 20686 if (result != ISC_R_SUCCESS) { 20687 dnssec_log(zone, ISC_LOG_ERROR, 20688 "sign_apex:dns__zone_updatesigs -> %s", 20689 isc_result_totext(result)); 20690 goto failure; 20691 } 20692 20693 failure: 20694 for (i = 0; i < nkeys; i++) { 20695 dst_key_free(&zone_keys[i]); 20696 } 20697 return result; 20698 } 20699 20700 static isc_result_t 20701 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 20702 dns_diff_t *diff) { 20703 isc_result_t result; 20704 dns_dbnode_t *node = NULL; 20705 dns_rdataset_t rdataset; 20706 20707 dns_rdataset_init(&rdataset); 20708 CHECK(dns_db_getoriginnode(db, &node)); 20709 20710 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 20711 dns_rdatatype_none, 0, &rdataset, NULL); 20712 if (dns_rdataset_isassociated(&rdataset)) { 20713 dns_rdataset_disassociate(&rdataset); 20714 } 20715 if (result != ISC_R_NOTFOUND) { 20716 goto failure; 20717 } 20718 20719 result = dns_nsec3param_deletechains(db, ver, zone, true, diff); 20720 20721 failure: 20722 if (node != NULL) { 20723 dns_db_detachnode(db, &node); 20724 } 20725 return result; 20726 } 20727 20728 /* 20729 * Given an RRSIG rdataset and an algorithm, determine whether there 20730 * are any signatures using that algorithm. 20731 */ 20732 static bool 20733 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) { 20734 dns_rdata_t rdata = DNS_RDATA_INIT; 20735 dns_rdata_rrsig_t rrsig; 20736 isc_result_t result; 20737 20738 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig); 20739 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) { 20740 return false; 20741 } 20742 20743 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 20744 result = dns_rdataset_next(rdataset)) 20745 { 20746 dns_rdataset_current(rdataset, &rdata); 20747 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 20748 RUNTIME_CHECK(result == ISC_R_SUCCESS); 20749 dns_rdata_reset(&rdata); 20750 if (rrsig.algorithm == alg) { 20751 return true; 20752 } 20753 } 20754 20755 return false; 20756 } 20757 20758 static isc_result_t 20759 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 20760 dns_diff_t *diff) { 20761 dns_name_t *origin; 20762 bool build_nsec3; 20763 isc_result_t result; 20764 20765 origin = dns_db_origin(db); 20766 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL, 20767 &build_nsec3)); 20768 if (build_nsec3) { 20769 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone_nsecttl(zone), 20770 false, zone->privatetype, diff)); 20771 } 20772 CHECK(updatesecure(db, ver, origin, zone_nsecttl(zone), true, diff)); 20773 20774 failure: 20775 return result; 20776 } 20777 20778 static void 20779 dnssec_report(const char *format, ...) { 20780 va_list args; 20781 va_start(args, format); 20782 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_ZONE, 20783 ISC_LOG_INFO, format, args); 20784 va_end(args); 20785 } 20786 20787 static void 20788 checkds_destroy(dns_checkds_t *checkds, bool locked) { 20789 REQUIRE(DNS_CHECKDS_VALID(checkds)); 20790 20791 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 20792 "checkds: destroy DS query"); 20793 20794 if (checkds->zone != NULL) { 20795 if (!locked) { 20796 LOCK_ZONE(checkds->zone); 20797 } 20798 REQUIRE(LOCKED_ZONE(checkds->zone)); 20799 if (ISC_LINK_LINKED(checkds, link)) { 20800 ISC_LIST_UNLINK(checkds->zone->checkds_requests, 20801 checkds, link); 20802 } 20803 if (!locked) { 20804 UNLOCK_ZONE(checkds->zone); 20805 } 20806 if (locked) { 20807 zone_idetach(&checkds->zone); 20808 } else { 20809 dns_zone_idetach(&checkds->zone); 20810 } 20811 } 20812 if (checkds->find != NULL) { 20813 dns_adb_destroyfind(&checkds->find); 20814 } 20815 if (checkds->request != NULL) { 20816 dns_request_destroy(&checkds->request); 20817 } 20818 if (dns_name_dynamic(&checkds->ns)) { 20819 dns_name_free(&checkds->ns, checkds->mctx); 20820 } 20821 if (checkds->key != NULL) { 20822 dns_tsigkey_detach(&checkds->key); 20823 } 20824 if (checkds->transport != NULL) { 20825 dns_transport_detach(&checkds->transport); 20826 } 20827 INSIST(checkds->rlevent == NULL); 20828 isc_mem_putanddetach(&checkds->mctx, checkds, sizeof(*checkds)); 20829 } 20830 20831 static isc_result_t 20832 make_dnskey(dst_key_t *key, unsigned char *buf, int bufsize, 20833 dns_rdata_t *target) { 20834 isc_result_t result; 20835 isc_buffer_t b; 20836 isc_region_t r; 20837 20838 isc_buffer_init(&b, buf, bufsize); 20839 result = dst_key_todns(key, &b); 20840 if (result != ISC_R_SUCCESS) { 20841 return result; 20842 } 20843 20844 dns_rdata_reset(target); 20845 isc_buffer_usedregion(&b, &r); 20846 dns_rdata_fromregion(target, dst_key_class(key), dns_rdatatype_dnskey, 20847 &r); 20848 return ISC_R_SUCCESS; 20849 } 20850 20851 static bool 20852 do_checkds(dns_zone_t *zone, dst_key_t *key, isc_stdtime_t now, 20853 bool dspublish) { 20854 dns_kasp_t *kasp = zone->kasp; 20855 isc_result_t result; 20856 uint32_t count = 0; 20857 uint32_t num; 20858 20859 switch (zone->checkdstype) { 20860 case dns_checkdstype_yes: 20861 num = zone->parent_nscount; 20862 break; 20863 case dns_checkdstype_explicit: 20864 num = dns_remote_count(&zone->parentals); 20865 break; 20866 case dns_checkdstype_no: 20867 default: 20868 dns_zone_log(zone, ISC_LOG_WARNING, 20869 "checkds: option is disabled"); 20870 return false; 20871 } 20872 20873 if (dspublish) { 20874 (void)dst_key_getnum(key, DST_NUM_DSPUBCOUNT, &count); 20875 count += 1; 20876 dst_key_setnum(key, DST_NUM_DSPUBCOUNT, count); 20877 dns_zone_log(zone, ISC_LOG_DEBUG(3), 20878 "checkds: %u DS published " 20879 "for key %u", 20880 count, dst_key_id(key)); 20881 20882 if (count != num) { 20883 return false; 20884 } 20885 } else { 20886 (void)dst_key_getnum(key, DST_NUM_DSDELCOUNT, &count); 20887 count += 1; 20888 dst_key_setnum(key, DST_NUM_DSDELCOUNT, count); 20889 dns_zone_log(zone, ISC_LOG_DEBUG(3), 20890 "checkds: %u DS withdrawn " 20891 "for key %u", 20892 count, dst_key_id(key)); 20893 20894 if (count != num) { 20895 return false; 20896 } 20897 } 20898 20899 dns_zone_log(zone, ISC_LOG_DEBUG(3), 20900 "checkds: checkds %s for key " 20901 "%u", 20902 dspublish ? "published" : "withdrawn", dst_key_id(key)); 20903 20904 dns_zone_lock_keyfiles(zone); 20905 result = dns_keymgr_checkds_id(kasp, &zone->checkds_ok, now, now, 20906 dspublish, dst_key_id(key), 20907 dst_key_alg(key)); 20908 dns_zone_unlock_keyfiles(zone); 20909 20910 if (result != ISC_R_SUCCESS) { 20911 dns_zone_log(zone, ISC_LOG_WARNING, 20912 "checkds: checkds for key %u failed: %s", 20913 dst_key_id(key), isc_result_totext(result)); 20914 return false; 20915 } 20916 20917 return true; 20918 } 20919 20920 static isc_result_t 20921 validate_ds(dns_zone_t *zone, dns_message_t *message) { 20922 UNUSED(zone); 20923 UNUSED(message); 20924 20925 /* Get closest trust anchor */ 20926 20927 /* Check that trust anchor is (grand)parent of zone. */ 20928 20929 /* Find the DNSKEY signing the message. */ 20930 20931 /* Check that DNSKEY is in chain of trust. */ 20932 20933 /* Validate DS RRset. */ 20934 20935 return ISC_R_SUCCESS; 20936 } 20937 20938 static void 20939 checkds_done(void *arg) { 20940 dns_request_t *request = (dns_request_t *)arg; 20941 dns_checkds_t *checkds = dns_request_getarg(request); 20942 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 20943 char rcode[128]; 20944 dns_zone_t *zone = NULL; 20945 dns_db_t *db = NULL; 20946 dns_dbversion_t *version = NULL; 20947 dns_dnsseckey_t *key = NULL; 20948 dns_dnsseckeylist_t keys; 20949 dns_kasp_t *kasp = NULL; 20950 dns_message_t *message = NULL; 20951 dns_rdataset_t *ds_rrset = NULL; 20952 isc_buffer_t buf; 20953 isc_result_t result; 20954 isc_stdtime_t now; 20955 isc_time_t timenow; 20956 bool rekey = false; 20957 bool empty = false; 20958 20959 REQUIRE(DNS_CHECKDS_VALID(checkds)); 20960 20961 zone = checkds->zone; 20962 20963 ISC_LIST_INIT(keys); 20964 20965 kasp = zone->kasp; 20966 INSIST(kasp != NULL); 20967 20968 isc_buffer_init(&buf, rcode, sizeof(rcode)); 20969 isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf)); 20970 20971 dns_zone_log(zone, ISC_LOG_DEBUG(1), "checkds: DS query to %s: done", 20972 addrbuf); 20973 20974 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, 20975 &message); 20976 INSIST(message != NULL); 20977 20978 CHECK(dns_request_getresult(request)); 20979 CHECK(dns_request_getresponse(request, message, 20980 DNS_MESSAGEPARSE_PRESERVEORDER)); 20981 CHECK(dns_rcode_totext(message->rcode, &buf)); 20982 20983 dns_zone_log(zone, ISC_LOG_DEBUG(3), 20984 "checkds: DS response from %s: %.*s", addrbuf, 20985 (int)buf.used, rcode); 20986 20987 /* Validate response. */ 20988 CHECK(validate_ds(zone, message)); 20989 20990 /* Check RCODE. */ 20991 if (message->rcode != dns_rcode_noerror) { 20992 dns_zone_log(zone, ISC_LOG_NOTICE, 20993 "checkds: bad DS response from %s: %.*s", addrbuf, 20994 (int)buf.used, rcode); 20995 goto failure; 20996 } 20997 20998 /* Make sure that either AA or RA bit is set. */ 20999 if ((message->flags & DNS_MESSAGEFLAG_AA) == 0 && 21000 (message->flags & DNS_MESSAGEFLAG_RA) == 0) 21001 { 21002 dns_zone_log(zone, ISC_LOG_NOTICE, 21003 "checkds: bad DS response from %s: expected AA or " 21004 "RA bit set", 21005 addrbuf); 21006 goto failure; 21007 } 21008 21009 /* Lookup DS RRset. */ 21010 result = dns_message_firstname(message, DNS_SECTION_ANSWER); 21011 while (result == ISC_R_SUCCESS) { 21012 dns_name_t *name = NULL; 21013 dns_rdataset_t *rdataset; 21014 21015 dns_message_currentname(message, DNS_SECTION_ANSWER, &name); 21016 if (dns_name_compare(&zone->origin, name) != 0) { 21017 goto next; 21018 } 21019 21020 for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; 21021 rdataset = ISC_LIST_NEXT(rdataset, link)) 21022 { 21023 if (rdataset->type != dns_rdatatype_ds) { 21024 goto next; 21025 } 21026 21027 ds_rrset = rdataset; 21028 break; 21029 } 21030 21031 if (ds_rrset != NULL) { 21032 break; 21033 } 21034 21035 next: 21036 result = dns_message_nextname(message, DNS_SECTION_ANSWER); 21037 } 21038 21039 if (ds_rrset == NULL) { 21040 empty = true; 21041 dns_zone_log(zone, ISC_LOG_NOTICE, 21042 "checkds: empty DS response from %s", addrbuf); 21043 } 21044 21045 timenow = isc_time_now(); 21046 now = isc_time_seconds(&timenow); 21047 21048 CHECK(dns_zone_getdb(zone, &db)); 21049 dns_db_currentversion(db, &version); 21050 21051 KASP_LOCK(kasp); 21052 LOCK_ZONE(zone); 21053 for (key = ISC_LIST_HEAD(zone->checkds_ok); key != NULL; 21054 key = ISC_LIST_NEXT(key, link)) 21055 { 21056 bool alldone = false, found = false; 21057 bool checkdspub = false, checkdsdel = false, ksk = false; 21058 dst_key_state_t ds_state = DST_KEY_STATE_NA; 21059 isc_stdtime_t published = 0, withdrawn = 0; 21060 isc_result_t ret = ISC_R_SUCCESS; 21061 21062 /* Is this key have the KSK role? */ 21063 (void)dst_key_role(key->key, &ksk, NULL); 21064 if (!ksk) { 21065 continue; 21066 } 21067 21068 /* Do we need to check the DS RRset for this key? */ 21069 (void)dst_key_getstate(key->key, DST_KEY_DS, &ds_state); 21070 (void)dst_key_gettime(key->key, DST_TIME_DSPUBLISH, &published); 21071 (void)dst_key_gettime(key->key, DST_TIME_DSDELETE, &withdrawn); 21072 21073 if (ds_state == DST_KEY_STATE_RUMOURED && published == 0) { 21074 checkdspub = true; 21075 } else if (ds_state == DST_KEY_STATE_UNRETENTIVE && 21076 withdrawn == 0) 21077 { 21078 checkdsdel = true; 21079 } 21080 if (!checkdspub && !checkdsdel) { 21081 continue; 21082 } 21083 21084 if (empty) { 21085 goto dswithdrawn; 21086 } 21087 21088 /* Find the appropriate DS record. */ 21089 ret = dns_rdataset_first(ds_rrset); 21090 while (ret == ISC_R_SUCCESS) { 21091 dns_rdata_ds_t ds; 21092 dns_rdata_t dnskey = DNS_RDATA_INIT; 21093 dns_rdata_t dsrdata = DNS_RDATA_INIT; 21094 dns_rdata_t rdata = DNS_RDATA_INIT; 21095 isc_result_t r; 21096 unsigned char dsbuf[DNS_DS_BUFFERSIZE]; 21097 unsigned char keybuf[DST_KEY_MAXSIZE]; 21098 21099 dns_rdataset_current(ds_rrset, &rdata); 21100 r = dns_rdata_tostruct(&rdata, &ds, NULL); 21101 if (r != ISC_R_SUCCESS) { 21102 goto nextds; 21103 } 21104 /* Check key tag and algorithm. */ 21105 if (dst_key_id(key->key) != ds.key_tag) { 21106 goto nextds; 21107 } 21108 if (dst_key_alg(key->key) != ds.algorithm) { 21109 goto nextds; 21110 } 21111 /* Derive DS from DNSKEY, see if the rdata is equal. */ 21112 make_dnskey(key->key, keybuf, sizeof(keybuf), &dnskey); 21113 r = dns_ds_buildrdata(&zone->origin, &dnskey, 21114 ds.digest_type, dsbuf, &dsrdata); 21115 if (r != ISC_R_SUCCESS) { 21116 goto nextds; 21117 } 21118 if (dns_rdata_compare(&rdata, &dsrdata) == 0) { 21119 found = true; 21120 if (checkdspub) { 21121 /* DS Published. */ 21122 alldone = do_checkds(zone, key->key, 21123 now, true); 21124 if (alldone) { 21125 rekey = true; 21126 } 21127 } 21128 } 21129 21130 nextds: 21131 ret = dns_rdataset_next(ds_rrset); 21132 } 21133 21134 dswithdrawn: 21135 /* DS withdrawn. */ 21136 if (checkdsdel && !found) { 21137 alldone = do_checkds(zone, key->key, now, false); 21138 if (alldone) { 21139 rekey = true; 21140 } 21141 } 21142 } 21143 UNLOCK_ZONE(zone); 21144 KASP_UNLOCK(kasp); 21145 21146 /* Rekey after checkds. */ 21147 if (rekey) { 21148 dns_zone_rekey(zone, false); 21149 } 21150 21151 failure: 21152 if (result != ISC_R_SUCCESS) { 21153 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21154 "checkds: DS request failed: %s", 21155 isc_result_totext(result)); 21156 } 21157 21158 if (version != NULL) { 21159 dns_db_closeversion(db, &version, false); 21160 } 21161 if (db != NULL) { 21162 dns_db_detach(&db); 21163 } 21164 21165 while (!ISC_LIST_EMPTY(keys)) { 21166 key = ISC_LIST_HEAD(keys); 21167 ISC_LIST_UNLINK(keys, key, link); 21168 dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key); 21169 } 21170 21171 checkds_destroy(checkds, false); 21172 dns_message_detach(&message); 21173 } 21174 21175 static bool 21176 checkds_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr, 21177 dns_tsigkey_t *key, dns_transport_t *transport) { 21178 dns_checkds_t *checkds; 21179 21180 for (checkds = ISC_LIST_HEAD(zone->checkds_requests); checkds != NULL; 21181 checkds = ISC_LIST_NEXT(checkds, link)) 21182 { 21183 if (checkds->request != NULL) { 21184 continue; 21185 } 21186 if (name != NULL && dns_name_equal(name, &checkds->ns)) { 21187 return true; 21188 } 21189 if (addr != NULL && isc_sockaddr_equal(addr, &checkds->dst) && 21190 checkds->key == key && checkds->transport == transport) 21191 { 21192 return true; 21193 } 21194 } 21195 return false; 21196 } 21197 21198 static isc_result_t 21199 checkds_create(isc_mem_t *mctx, unsigned int flags, dns_checkds_t **checkdsp) { 21200 dns_checkds_t *checkds; 21201 21202 REQUIRE(checkdsp != NULL && *checkdsp == NULL); 21203 21204 checkds = isc_mem_get(mctx, sizeof(*checkds)); 21205 *checkds = (dns_checkds_t){ 21206 .flags = flags, 21207 }; 21208 21209 isc_mem_attach(mctx, &checkds->mctx); 21210 isc_sockaddr_any(&checkds->dst); 21211 dns_name_init(&checkds->ns, NULL); 21212 ISC_LINK_INIT(checkds, link); 21213 checkds->magic = CHECKDS_MAGIC; 21214 *checkdsp = checkds; 21215 return ISC_R_SUCCESS; 21216 } 21217 21218 static void 21219 checkds_createmessage(dns_zone_t *zone, dns_message_t **messagep) { 21220 dns_message_t *message = NULL; 21221 21222 dns_name_t *tempname = NULL; 21223 dns_rdataset_t *temprdataset = NULL; 21224 21225 REQUIRE(DNS_ZONE_VALID(zone)); 21226 REQUIRE(messagep != NULL && *messagep == NULL); 21227 21228 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, 21229 &message); 21230 21231 message->opcode = dns_opcode_query; 21232 message->rdclass = zone->rdclass; 21233 message->flags |= DNS_MESSAGEFLAG_RD; 21234 21235 dns_message_gettempname(message, &tempname); 21236 21237 dns_message_gettemprdataset(message, &temprdataset); 21238 21239 /* 21240 * Make question. 21241 */ 21242 dns_name_init(tempname, NULL); 21243 dns_name_clone(&zone->origin, tempname); 21244 dns_rdataset_makequestion(temprdataset, zone->rdclass, 21245 dns_rdatatype_ds); 21246 ISC_LIST_APPEND(tempname->list, temprdataset, link); 21247 dns_message_addname(message, tempname, DNS_SECTION_QUESTION); 21248 tempname = NULL; 21249 temprdataset = NULL; 21250 21251 *messagep = message; 21252 } 21253 21254 /* 21255 * XXXAG should check for DNS_ZONEFLG_EXITING 21256 */ 21257 static void 21258 process_checkds_adb_event(void *arg) { 21259 dns_adbfind_t *find = (dns_adbfind_t *)arg; 21260 dns_checkds_t *checkds = (dns_checkds_t *)find->cbarg; 21261 dns_adbstatus_t astat = find->status; 21262 21263 REQUIRE(DNS_CHECKDS_VALID(checkds)); 21264 REQUIRE(find == checkds->find); 21265 21266 switch (astat) { 21267 case DNS_ADB_MOREADDRESSES: 21268 dns_adb_destroyfind(&checkds->find); 21269 checkds_find_address(checkds); 21270 return; 21271 21272 case DNS_ADB_NOMOREADDRESSES: 21273 LOCK_ZONE(checkds->zone); 21274 checkds_send_tons(checkds); 21275 UNLOCK_ZONE(checkds->zone); 21276 break; 21277 21278 default: 21279 break; 21280 } 21281 21282 checkds_destroy(checkds, false); 21283 } 21284 21285 static void 21286 checkds_find_address(dns_checkds_t *checkds) { 21287 isc_result_t result; 21288 unsigned int options; 21289 dns_adb_t *adb = NULL; 21290 21291 REQUIRE(DNS_CHECKDS_VALID(checkds)); 21292 21293 options = DNS_ADBFIND_WANTEVENT; 21294 if (isc_net_probeipv4() != ISC_R_DISABLED) { 21295 options |= DNS_ADBFIND_INET; 21296 } 21297 if (isc_net_probeipv6() != ISC_R_DISABLED) { 21298 options |= DNS_ADBFIND_INET6; 21299 } 21300 21301 dns_view_getadb(checkds->zone->view, &adb); 21302 if (adb == NULL) { 21303 goto destroy; 21304 } 21305 21306 result = dns_adb_createfind( 21307 adb, checkds->zone->loop, process_checkds_adb_event, checkds, 21308 &checkds->ns, dns_rootname, 0, options, 0, NULL, 21309 checkds->zone->view->dstport, 0, NULL, &checkds->find); 21310 dns_adb_detach(&adb); 21311 21312 /* Something failed? */ 21313 if (result != ISC_R_SUCCESS) { 21314 goto destroy; 21315 } 21316 21317 /* More addresses pending? */ 21318 if ((checkds->find->options & DNS_ADBFIND_WANTEVENT) != 0) { 21319 return; 21320 } 21321 21322 /* We have as many addresses as we can get. */ 21323 LOCK_ZONE(checkds->zone); 21324 checkds_send_tons(checkds); 21325 UNLOCK_ZONE(checkds->zone); 21326 21327 destroy: 21328 checkds_destroy(checkds, false); 21329 } 21330 21331 static void 21332 checkds_send_toaddr(void *arg) { 21333 dns_checkds_t *checkds = (dns_checkds_t *)arg; 21334 isc_result_t result; 21335 dns_message_t *message = NULL; 21336 isc_netaddr_t dstip; 21337 dns_tsigkey_t *key = NULL; 21338 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 21339 isc_sockaddr_t src; 21340 unsigned int options, timeout; 21341 bool have_checkdssource = false; 21342 bool canceled = checkds->rlevent->canceled; 21343 21344 REQUIRE(DNS_CHECKDS_VALID(checkds)); 21345 21346 isc_rlevent_free(&checkds->rlevent); 21347 21348 LOCK_ZONE(checkds->zone); 21349 21350 if (DNS_ZONE_FLAG(checkds->zone, DNS_ZONEFLG_LOADED) == 0 || canceled || 21351 DNS_ZONE_FLAG(checkds->zone, DNS_ZONEFLG_EXITING) || 21352 checkds->zone->view->requestmgr == NULL || 21353 checkds->zone->db == NULL) 21354 { 21355 result = ISC_R_CANCELED; 21356 goto cleanup; 21357 } 21358 21359 /* 21360 * The raw IPv4 address should also exist. Don't send to the 21361 * mapped form. 21362 */ 21363 if (isc_sockaddr_pf(&checkds->dst) == PF_INET6 && 21364 IN6_IS_ADDR_V4MAPPED(&checkds->dst.type.sin6.sin6_addr)) 21365 { 21366 isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf)); 21367 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21368 "checkds: ignoring IPv6 mapped IPV4 address: %s", 21369 addrbuf); 21370 result = ISC_R_CANCELED; 21371 goto cleanup; 21372 } 21373 21374 checkds_createmessage(checkds->zone, &message); 21375 21376 isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf)); 21377 if (checkds->key != NULL) { 21378 /* Transfer ownership of key */ 21379 key = checkds->key; 21380 checkds->key = NULL; 21381 } else { 21382 isc_netaddr_fromsockaddr(&dstip, &checkds->dst); 21383 result = dns_view_getpeertsig(checkds->zone->view, &dstip, 21384 &key); 21385 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 21386 dns_zone_log(checkds->zone, ISC_LOG_ERROR, 21387 "checkds: DS query to %s not sent. " 21388 "Peer TSIG key lookup failure.", 21389 addrbuf); 21390 goto cleanup_message; 21391 } 21392 } 21393 21394 if (key != NULL) { 21395 char namebuf[DNS_NAME_FORMATSIZE]; 21396 21397 dns_name_format(key->name, namebuf, sizeof(namebuf)); 21398 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21399 "checkds: sending DS query to %s : TSIG (%s)", 21400 addrbuf, namebuf); 21401 } else { 21402 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21403 "checkds: sending DS query to %s", addrbuf); 21404 } 21405 options = 0; 21406 if (checkds->zone->view->peers != NULL) { 21407 dns_peer_t *peer = NULL; 21408 bool usetcp = false; 21409 result = dns_peerlist_peerbyaddr(checkds->zone->view->peers, 21410 &dstip, &peer); 21411 if (result == ISC_R_SUCCESS) { 21412 result = dns_peer_getquerysource(peer, &src); 21413 if (result == ISC_R_SUCCESS) { 21414 have_checkdssource = true; 21415 } 21416 result = dns_peer_getforcetcp(peer, &usetcp); 21417 if (result == ISC_R_SUCCESS && usetcp) { 21418 options |= DNS_FETCHOPT_TCP; 21419 } 21420 } 21421 } 21422 switch (isc_sockaddr_pf(&checkds->dst)) { 21423 case PF_INET: 21424 if (!have_checkdssource) { 21425 isc_sockaddr_t any; 21426 isc_sockaddr_any(&any); 21427 21428 src = checkds->src; 21429 if (isc_sockaddr_equal(&src, &any)) { 21430 src = checkds->zone->parentalsrc4; 21431 } 21432 } 21433 break; 21434 case PF_INET6: 21435 if (!have_checkdssource) { 21436 isc_sockaddr_t any; 21437 isc_sockaddr_any6(&any); 21438 21439 src = checkds->src; 21440 if (isc_sockaddr_equal(&src, &any)) { 21441 src = checkds->zone->parentalsrc6; 21442 } 21443 } 21444 break; 21445 default: 21446 result = ISC_R_NOTIMPLEMENTED; 21447 goto cleanup_key; 21448 } 21449 21450 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21451 "checkds: create request for DS query to %s", addrbuf); 21452 21453 timeout = 5; 21454 options |= DNS_REQUESTOPT_TCP; 21455 result = dns_request_create( 21456 checkds->zone->view->requestmgr, message, &src, &checkds->dst, 21457 NULL, NULL, options, key, timeout * 3 + 1, timeout, 2, 21458 checkds->zone->loop, checkds_done, checkds, &checkds->request); 21459 if (result != ISC_R_SUCCESS) { 21460 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21461 "checkds: dns_request_create() to %s failed: %s", 21462 addrbuf, isc_result_totext(result)); 21463 } 21464 21465 cleanup_key: 21466 if (key != NULL) { 21467 dns_tsigkey_detach(&key); 21468 } 21469 cleanup_message: 21470 dns_message_detach(&message); 21471 cleanup: 21472 UNLOCK_ZONE(checkds->zone); 21473 if (result != ISC_R_SUCCESS) { 21474 checkds_destroy(checkds, false); 21475 } 21476 } 21477 21478 static void 21479 checkds_send_tons(dns_checkds_t *checkds) { 21480 dns_adbaddrinfo_t *ai; 21481 isc_sockaddr_t dst; 21482 isc_result_t result; 21483 dns_checkds_t *newcheckds = NULL; 21484 dns_zone_t *zone = NULL; 21485 21486 /* 21487 * Zone lock held by caller. 21488 */ 21489 REQUIRE(DNS_CHECKDS_VALID(checkds)); 21490 REQUIRE(LOCKED_ZONE(checkds->zone)); 21491 21492 zone = checkds->zone; 21493 21494 if (DNS_ZONE_FLAG(checkds->zone, DNS_ZONEFLG_EXITING)) { 21495 return; 21496 } 21497 21498 for (ai = ISC_LIST_HEAD(checkds->find->list); ai != NULL; 21499 ai = ISC_LIST_NEXT(ai, publink)) 21500 { 21501 dst = ai->sockaddr; 21502 if (checkds_isqueued(zone, NULL, &dst, NULL, NULL)) { 21503 continue; 21504 } 21505 21506 newcheckds = NULL; 21507 result = checkds_create(checkds->mctx, 0, &newcheckds); 21508 if (result != ISC_R_SUCCESS) { 21509 goto cleanup; 21510 } 21511 zone_iattach(zone, &newcheckds->zone); 21512 ISC_LIST_APPEND(newcheckds->zone->checkds_requests, newcheckds, 21513 link); 21514 newcheckds->dst = dst; 21515 dns_name_dup(&checkds->ns, checkds->mctx, &newcheckds->ns); 21516 switch (isc_sockaddr_pf(&newcheckds->dst)) { 21517 case PF_INET: 21518 isc_sockaddr_any(&newcheckds->src); 21519 break; 21520 case PF_INET6: 21521 isc_sockaddr_any6(&newcheckds->src); 21522 break; 21523 default: 21524 UNREACHABLE(); 21525 } 21526 /* 21527 * XXXWMM: Should we attach key and transport here? 21528 * Probably not, because we expect the name servers to be 21529 * publicly available on the default transport protocol. 21530 */ 21531 21532 result = isc_ratelimiter_enqueue( 21533 newcheckds->zone->zmgr->checkdsrl, 21534 newcheckds->zone->loop, checkds_send_toaddr, newcheckds, 21535 &newcheckds->rlevent); 21536 if (result != ISC_R_SUCCESS) { 21537 goto cleanup; 21538 } 21539 newcheckds = NULL; 21540 } 21541 21542 cleanup: 21543 if (newcheckds != NULL) { 21544 checkds_destroy(newcheckds, true); 21545 } 21546 } 21547 21548 static void 21549 checkds_send(dns_zone_t *zone) { 21550 dns_view_t *view = dns_zone_getview(zone); 21551 isc_result_t result; 21552 unsigned int flags = 0; 21553 unsigned int i = 0; 21554 21555 /* 21556 * Zone lock held by caller. 21557 */ 21558 REQUIRE(LOCKED_ZONE(zone)); 21559 21560 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21561 "checkds: start sending DS queries to %u parentals", 21562 dns_remote_count(&zone->parentals)); 21563 21564 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 21565 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21566 "checkds: abort, named exiting"); 21567 return; 21568 } 21569 21570 dns_remote_reset(&zone->parentals, false); 21571 while (!dns_remote_done(&zone->parentals)) { 21572 dns_tsigkey_t *key = NULL; 21573 dns_transport_t *transport = NULL; 21574 isc_sockaddr_t src, dst; 21575 dns_checkds_t *checkds = NULL; 21576 21577 i++; 21578 21579 if (dns_remote_keyname(&zone->parentals) != NULL) { 21580 dns_name_t *keyname = 21581 dns_remote_keyname(&zone->parentals); 21582 (void)dns_view_gettsig(view, keyname, &key); 21583 } 21584 21585 if (dns_remote_tlsname(&zone->parentals) != NULL) { 21586 dns_name_t *tlsname = 21587 dns_remote_tlsname(&zone->parentals); 21588 (void)dns_view_gettransport(view, DNS_TRANSPORT_TLS, 21589 tlsname, &transport); 21590 dns_zone_logc( 21591 zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 21592 "got TLS configuration for zone transfer"); 21593 } 21594 21595 dst = dns_remote_curraddr(&zone->parentals); 21596 src = dns_remote_sourceaddr(&zone->parentals); 21597 INSIST(isc_sockaddr_pf(&src) == isc_sockaddr_pf(&dst)); 21598 21599 if (isc_sockaddr_disabled(&dst)) { 21600 goto next; 21601 } 21602 21603 /* TODO: glue the transport to the checkds request */ 21604 21605 if (checkds_isqueued(zone, NULL, &dst, key, transport)) { 21606 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21607 "checkds: DS query to parent " 21608 "%d is queued", 21609 i); 21610 if (key != NULL) { 21611 dns_tsigkey_detach(&key); 21612 } 21613 if (transport != NULL) { 21614 dns_transport_detach(&transport); 21615 } 21616 goto next; 21617 } 21618 21619 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21620 "checkds: create DS query for " 21621 "parent %d", 21622 i); 21623 21624 result = checkds_create(zone->mctx, flags, &checkds); 21625 if (result != ISC_R_SUCCESS) { 21626 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21627 "checkds: create DS query for " 21628 "parent %d failed", 21629 i); 21630 goto next; 21631 } 21632 zone_iattach(zone, &checkds->zone); 21633 dns_name_dup(dns_rootname, checkds->mctx, &checkds->ns); 21634 checkds->src = src; 21635 checkds->dst = dst; 21636 21637 INSIST(checkds->key == NULL); 21638 if (key != NULL) { 21639 checkds->key = key; 21640 key = NULL; 21641 } 21642 21643 INSIST(checkds->transport == NULL); 21644 if (transport != NULL) { 21645 checkds->transport = transport; 21646 transport = NULL; 21647 } 21648 21649 ISC_LIST_APPEND(zone->checkds_requests, checkds, link); 21650 result = isc_ratelimiter_enqueue( 21651 checkds->zone->zmgr->checkdsrl, checkds->zone->loop, 21652 checkds_send_toaddr, checkds, &checkds->rlevent); 21653 if (result != ISC_R_SUCCESS) { 21654 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21655 "checkds: send DS query to " 21656 "parent %d failed", 21657 i); 21658 checkds_destroy(checkds, true); 21659 } 21660 21661 next: 21662 dns_remote_next(&zone->parentals, false); 21663 } 21664 } 21665 21666 /* 21667 * An NS RRset has been fetched from the parent of a zone whose DS RRset needs 21668 * to be checked; scan the RRset and start sending queries to the parental 21669 * agents. 21670 */ 21671 static void 21672 nsfetch_done(void *arg) { 21673 dns_fetchresponse_t *resp = (dns_fetchresponse_t *)arg; 21674 isc_result_t result, eresult; 21675 dns_nsfetch_t *nsfetch = NULL; 21676 dns_zone_t *zone = NULL; 21677 isc_mem_t *mctx = NULL; 21678 dns_name_t *zname = NULL; 21679 dns_name_t *pname = NULL; 21680 char pnamebuf[DNS_NAME_FORMATSIZE]; 21681 bool free_needed, levelup = false; 21682 dns_rdataset_t *nsrrset = NULL; 21683 dns_rdataset_t *nssigset = NULL; 21684 21685 INSIST(resp != NULL); 21686 21687 nsfetch = resp->arg; 21688 21689 INSIST(nsfetch != NULL); 21690 21691 zone = nsfetch->zone; 21692 mctx = nsfetch->mctx; 21693 zname = dns_fixedname_name(&nsfetch->name); 21694 pname = &nsfetch->pname; 21695 nsrrset = &nsfetch->nsrrset; 21696 nssigset = &nsfetch->nssigset; 21697 eresult = resp->result; 21698 21699 /* Free resources which are not of interest */ 21700 if (resp->node != NULL) { 21701 dns_db_detachnode(resp->db, &resp->node); 21702 } 21703 if (resp->db != NULL) { 21704 dns_db_detach(&resp->db); 21705 } 21706 dns_resolver_destroyfetch(&nsfetch->fetch); 21707 21708 LOCK_ZONE(zone); 21709 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) { 21710 goto cleanup; 21711 } 21712 21713 zone->nsfetchcount--; 21714 21715 dns_name_format(pname, pnamebuf, sizeof(pnamebuf)); 21716 dnssec_log(zone, ISC_LOG_DEBUG(3), 21717 "Returned from '%s' NS fetch in nsfetch_done(): %s", 21718 pnamebuf, isc_result_totext(eresult)); 21719 21720 if (eresult == DNS_R_NCACHENXRRSET || eresult == DNS_R_NXRRSET) { 21721 dnssec_log(zone, ISC_LOG_DEBUG(3), 21722 "NODATA response for NS '%s', level up", pnamebuf); 21723 levelup = true; 21724 goto cleanup; 21725 21726 } else if (eresult != ISC_R_SUCCESS) { 21727 dnssec_log(zone, ISC_LOG_WARNING, 21728 "Unable to fetch NS set '%s': %s", pnamebuf, 21729 isc_result_totext(eresult)); 21730 result = eresult; 21731 goto done; 21732 } 21733 21734 /* No NS records found */ 21735 if (!dns_rdataset_isassociated(nsrrset)) { 21736 dnssec_log(zone, ISC_LOG_WARNING, 21737 "No NS records found for '%s'", pnamebuf); 21738 result = ISC_R_NOTFOUND; 21739 goto done; 21740 } 21741 21742 /* No RRSIGs found */ 21743 if (!dns_rdataset_isassociated(nssigset)) { 21744 dnssec_log(zone, ISC_LOG_WARNING, "No NS RRSIGs found for '%s'", 21745 pnamebuf); 21746 result = DNS_R_MUSTBESECURE; 21747 goto done; 21748 } 21749 21750 /* Check trust level */ 21751 if (nsrrset->trust < dns_trust_secure) { 21752 dnssec_log(zone, ISC_LOG_WARNING, 21753 "Invalid NS RRset for '%s' trust level %u", pnamebuf, 21754 nsrrset->trust); 21755 result = DNS_R_MUSTBESECURE; 21756 goto done; 21757 } 21758 21759 /* Record the number of NS records we found. */ 21760 zone->parent_nscount = dns_rdataset_count(nsrrset); 21761 21762 UNLOCK_ZONE(zone); 21763 21764 /* Look up the addresses for the found parental name servers. */ 21765 for (result = dns_rdataset_first(nsrrset); result == ISC_R_SUCCESS; 21766 result = dns_rdataset_next(nsrrset)) 21767 { 21768 dns_checkds_t *checkds = NULL; 21769 dns_rdata_t rdata = DNS_RDATA_INIT; 21770 dns_rdata_ns_t ns; 21771 bool isqueued; 21772 21773 dns_rdataset_current(nsrrset, &rdata); 21774 result = dns_rdata_tostruct(&rdata, &ns, NULL); 21775 RUNTIME_CHECK(result == ISC_R_SUCCESS); 21776 21777 dns_rdata_reset(&rdata); 21778 21779 LOCK_ZONE(zone); 21780 isqueued = checkds_isqueued(zone, &ns.name, NULL, NULL, NULL); 21781 UNLOCK_ZONE(zone); 21782 if (isqueued) { 21783 continue; 21784 } 21785 result = checkds_create(zone->mctx, 0, &checkds); 21786 if (result != ISC_R_SUCCESS) { 21787 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21788 "checkds: checkds_create() failed: %s", 21789 isc_result_totext(result)); 21790 break; 21791 } 21792 21793 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 21794 char nsnamebuf[DNS_NAME_FORMATSIZE]; 21795 dns_name_format(&ns.name, nsnamebuf, sizeof(nsnamebuf)); 21796 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21797 "checkds: send DS query to NS %s", 21798 nsnamebuf); 21799 } 21800 21801 LOCK_ZONE(zone); 21802 zone_iattach(zone, &checkds->zone); 21803 dns_name_dup(&ns.name, zone->mctx, &checkds->ns); 21804 ISC_LIST_APPEND(zone->checkds_requests, checkds, link); 21805 UNLOCK_ZONE(zone); 21806 21807 checkds_find_address(checkds); 21808 } 21809 if (result == ISC_R_NOMORE) { 21810 result = ISC_R_SUCCESS; 21811 } 21812 21813 LOCK_ZONE(zone); 21814 21815 done: 21816 if (result != ISC_R_SUCCESS) { 21817 dnssec_log( 21818 zone, ISC_LOG_ERROR, 21819 "checkds: error during parental-agents processing: %s", 21820 isc_result_totext(result)); 21821 } 21822 21823 cleanup: 21824 isc_refcount_decrement(&zone->irefs); 21825 21826 if (dns_rdataset_isassociated(nsrrset)) { 21827 dns_rdataset_disassociate(nsrrset); 21828 } 21829 if (dns_rdataset_isassociated(nssigset)) { 21830 dns_rdataset_disassociate(nssigset); 21831 } 21832 isc_mem_putanddetach(&resp->mctx, resp, sizeof(*resp)); 21833 21834 if (levelup) { 21835 UNLOCK_ZONE(zone); 21836 nsfetch_levelup(nsfetch); 21837 return; 21838 } 21839 21840 dns_name_free(zname, mctx); 21841 isc_mem_putanddetach(&nsfetch->mctx, nsfetch, sizeof(dns_nsfetch_t)); 21842 21843 free_needed = exit_check(zone); 21844 UNLOCK_ZONE(zone); 21845 21846 if (free_needed) { 21847 zone_free(zone); 21848 } 21849 } 21850 21851 static void 21852 do_nsfetch(void *arg) { 21853 dns_nsfetch_t *nsfetch = (dns_nsfetch_t *)arg; 21854 isc_result_t result; 21855 unsigned int nlabels = 1; 21856 dns_resolver_t *resolver = NULL; 21857 dns_zone_t *zone = nsfetch->zone; 21858 unsigned int options = DNS_FETCHOPT_UNSHARED | DNS_FETCHOPT_NOCACHED; 21859 21860 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 21861 result = ISC_R_SHUTTINGDOWN; 21862 goto cleanup; 21863 } 21864 21865 result = dns_view_getresolver(zone->view, &resolver); 21866 if (result != ISC_R_SUCCESS) { 21867 goto cleanup; 21868 } 21869 21870 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 21871 char namebuf[DNS_NAME_FORMATSIZE]; 21872 dns_name_format(&nsfetch->pname, namebuf, sizeof(namebuf)); 21873 dnssec_log(zone, ISC_LOG_WARNING, 21874 "Create fetch for '%s' NS request", namebuf); 21875 } 21876 21877 /* Derive parent domain. XXXWMM: Check for root domain */ 21878 dns_name_split(&nsfetch->pname, 21879 dns_name_countlabels(&nsfetch->pname) - nlabels, NULL, 21880 &nsfetch->pname); 21881 21882 /* 21883 * Use of DNS_FETCHOPT_NOCACHED is essential here. If it is not 21884 * set and the cache still holds a non-expired, validated version 21885 * of the RRset being queried for by the time the response is 21886 * received, the cached RRset will be passed to nsfetch_done() 21887 * instead of the one received in the response as the latter will 21888 * have a lower trust level due to not being validated until 21889 * nsfetch_done() is called. 21890 */ 21891 result = dns_resolver_createfetch( 21892 resolver, &nsfetch->pname, dns_rdatatype_ns, NULL, NULL, NULL, 21893 NULL, 0, options, 0, NULL, zone->loop, nsfetch_done, nsfetch, 21894 &nsfetch->nsrrset, &nsfetch->nssigset, &nsfetch->fetch); 21895 21896 dns_resolver_detach(&resolver); 21897 21898 cleanup: 21899 if (result != ISC_R_SUCCESS) { 21900 dns_name_t *zname = dns_fixedname_name(&nsfetch->name); 21901 bool free_needed; 21902 char namebuf[DNS_NAME_FORMATSIZE]; 21903 dns_name_format(&nsfetch->pname, namebuf, sizeof(namebuf)); 21904 dnssec_log(zone, ISC_LOG_WARNING, 21905 "Failed to create fetch for '%s' NS request", 21906 namebuf); 21907 LOCK_ZONE(zone); 21908 zone->nsfetchcount--; 21909 isc_refcount_decrement(&zone->irefs); 21910 21911 dns_name_free(zname, zone->mctx); 21912 isc_mem_putanddetach(&nsfetch->mctx, nsfetch, sizeof(*nsfetch)); 21913 21914 free_needed = exit_check(zone); 21915 UNLOCK_ZONE(zone); 21916 if (free_needed) { 21917 zone_free(zone); 21918 } 21919 } 21920 } 21921 21922 /* 21923 * Retry an NS RRset lookup, one level up. In other words, this function should 21924 * be called on an dns_nsfetch structure where the response yielded in a NODATA 21925 * response. This must be because there is an empty non-terminal inbetween the 21926 * child and parent zone. 21927 */ 21928 static void 21929 nsfetch_levelup(dns_nsfetch_t *nsfetch) { 21930 dns_zone_t *zone = nsfetch->zone; 21931 21932 #ifdef ENABLE_AFL 21933 if (!dns_fuzzing_resolver) { 21934 #endif /* ifdef ENABLE_AFL */ 21935 LOCK_ZONE(zone); 21936 zone->nsfetchcount++; 21937 isc_refcount_increment0(&zone->irefs); 21938 21939 dns_rdataset_init(&nsfetch->nsrrset); 21940 dns_rdataset_init(&nsfetch->nssigset); 21941 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 21942 dnssec_log(zone, ISC_LOG_DEBUG(3), 21943 "Creating parent NS fetch in " 21944 "nsfetch_levelup()"); 21945 } 21946 isc_async_run(zone->loop, do_nsfetch, nsfetch); 21947 UNLOCK_ZONE(zone); 21948 #ifdef ENABLE_AFL 21949 } 21950 #endif /* ifdef ENABLE_AFL */ 21951 } 21952 21953 static void 21954 zone_checkds(dns_zone_t *zone) { 21955 bool cdscheck = false; 21956 dns_checkdstype_t checkdstype = zone->checkdstype; 21957 21958 if (checkdstype == dns_checkdstype_no) { 21959 return; 21960 } 21961 21962 for (dns_dnsseckey_t *key = ISC_LIST_HEAD(zone->checkds_ok); 21963 key != NULL; key = ISC_LIST_NEXT(key, link)) 21964 { 21965 dst_key_state_t ds_state = DST_KEY_STATE_NA; 21966 bool ksk = false; 21967 isc_stdtime_t published = 0, withdrawn = 0; 21968 21969 /* Is this key have the KSK role? */ 21970 (void)dst_key_role(key->key, &ksk, NULL); 21971 if (!ksk) { 21972 continue; 21973 } 21974 21975 /* Do we need to check the DS RRset? */ 21976 (void)dst_key_getstate(key->key, DST_KEY_DS, &ds_state); 21977 (void)dst_key_gettime(key->key, DST_TIME_DSPUBLISH, &published); 21978 (void)dst_key_gettime(key->key, DST_TIME_DSDELETE, &withdrawn); 21979 21980 if (ds_state == DST_KEY_STATE_RUMOURED && published == 0) { 21981 dst_key_setnum(key->key, DST_NUM_DSPUBCOUNT, 0); 21982 cdscheck = true; 21983 } else if (ds_state == DST_KEY_STATE_UNRETENTIVE && 21984 withdrawn == 0) 21985 { 21986 dst_key_setnum(key->key, DST_NUM_DSDELCOUNT, 0); 21987 cdscheck = true; 21988 } 21989 } 21990 21991 if (!cdscheck) { 21992 return; 21993 } 21994 21995 if (checkdstype == dns_checkdstype_explicit) { 21996 /* Request the DS RRset. */ 21997 LOCK_ZONE(zone); 21998 checkds_send(zone); 21999 UNLOCK_ZONE(zone); 22000 return; 22001 } 22002 22003 INSIST(checkdstype == dns_checkdstype_yes); 22004 22005 #ifdef ENABLE_AFL 22006 if (!dns_fuzzing_resolver) { 22007 #endif /* ifdef ENABLE_AFL */ 22008 dns_nsfetch_t *nsfetch; 22009 dns_name_t *name = NULL; 22010 22011 nsfetch = isc_mem_get(zone->mctx, sizeof(dns_nsfetch_t)); 22012 *nsfetch = (dns_nsfetch_t){ .zone = zone }; 22013 isc_mem_attach(zone->mctx, &nsfetch->mctx); 22014 LOCK_ZONE(zone); 22015 zone->nsfetchcount++; 22016 isc_refcount_increment0(&zone->irefs); 22017 name = dns_fixedname_initname(&nsfetch->name); 22018 dns_name_init(&nsfetch->pname, NULL); 22019 dns_name_clone(&zone->origin, &nsfetch->pname); 22020 dns_name_dup(&zone->origin, zone->mctx, name); 22021 dns_rdataset_init(&nsfetch->nsrrset); 22022 dns_rdataset_init(&nsfetch->nssigset); 22023 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 22024 dnssec_log( 22025 zone, ISC_LOG_DEBUG(3), 22026 "Creating parent NS fetch in zone_checkds()"); 22027 } 22028 isc_async_run(zone->loop, do_nsfetch, nsfetch); 22029 UNLOCK_ZONE(zone); 22030 #ifdef ENABLE_AFL 22031 } 22032 #endif /* ifdef ENABLE_AFL */ 22033 } 22034 22035 static isc_result_t 22036 update_ttl(dns_rdataset_t *rdataset, dns_name_t *name, dns_ttl_t ttl, 22037 dns_diff_t *diff) { 22038 isc_result_t result; 22039 22040 /* 22041 * Delete everything using the existing TTL. 22042 */ 22043 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 22044 result = dns_rdataset_next(rdataset)) 22045 { 22046 dns_difftuple_t *tuple = NULL; 22047 dns_rdata_t rdata = DNS_RDATA_INIT; 22048 22049 dns_rdataset_current(rdataset, &rdata); 22050 result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name, 22051 rdataset->ttl, &rdata, &tuple); 22052 if (result != ISC_R_SUCCESS) { 22053 return result; 22054 } 22055 dns_diff_appendminimal(diff, &tuple); 22056 } 22057 if (result != ISC_R_NOMORE) { 22058 return result; 22059 } 22060 22061 /* 22062 * Add everything using the new TTL. 22063 */ 22064 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 22065 result = dns_rdataset_next(rdataset)) 22066 { 22067 dns_difftuple_t *tuple = NULL; 22068 dns_rdata_t rdata = DNS_RDATA_INIT; 22069 22070 dns_rdataset_current(rdataset, &rdata); 22071 result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, 22072 ttl, &rdata, &tuple); 22073 if (result != ISC_R_SUCCESS) { 22074 return result; 22075 } 22076 dns_diff_appendminimal(diff, &tuple); 22077 } 22078 if (result != ISC_R_NOMORE) { 22079 return result; 22080 } 22081 return ISC_R_SUCCESS; 22082 } 22083 22084 static isc_result_t 22085 zone_verifykeys(dns_zone_t *zone, dns_dnsseckeylist_t *newkeys) { 22086 dns_dnsseckey_t *key1, *key2, *next; 22087 22088 /* 22089 * Make sure that the existing keys are also present in the new keylist. 22090 */ 22091 for (key1 = ISC_LIST_HEAD(zone->keyring); key1 != NULL; key1 = next) { 22092 bool found = false; 22093 next = ISC_LIST_NEXT(key1, link); 22094 22095 if (dst_key_is_unused(key1->key)) { 22096 continue; 22097 } 22098 if (key1->purge) { 22099 continue; 22100 } 22101 22102 for (key2 = ISC_LIST_HEAD(*newkeys); key2 != NULL; 22103 key2 = ISC_LIST_NEXT(key2, link)) 22104 { 22105 if (dst_key_compare(key1->key, key2->key)) { 22106 found = true; 22107 break; 22108 } 22109 } 22110 22111 if (!found) { 22112 char keystr[DST_KEY_FORMATSIZE]; 22113 dst_key_format(key1->key, keystr, sizeof(keystr)); 22114 dnssec_log(zone, ISC_LOG_DEBUG(1), 22115 "verifykeys: key %s - not available", 22116 keystr); 22117 return ISC_R_NOTFOUND; 22118 } 22119 } 22120 22121 /* All good. */ 22122 return ISC_R_SUCCESS; 22123 } 22124 22125 static void 22126 remove_rdataset(dns_zone_t *zone, dns_diff_t *diff, dns_rdataset_t *rdataset) { 22127 if (!dns_rdataset_isassociated(rdataset)) { 22128 return; 22129 } 22130 22131 for (isc_result_t result = dns_rdataset_first(rdataset); 22132 result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) 22133 { 22134 dns_rdata_t rdata = DNS_RDATA_INIT; 22135 dns_difftuple_t *tuple = NULL; 22136 22137 dns_rdataset_current(rdataset, &rdata); 22138 dns_difftuple_create(zone->mctx, DNS_DIFFOP_DEL, &zone->origin, 22139 rdataset->ttl, &rdata, &tuple); 22140 dns_diff_append(diff, &tuple); 22141 } 22142 return; 22143 } 22144 22145 static void 22146 add_tuple(dns_diff_t *diff, dns_difftuple_t *tuple) { 22147 dns_difftuple_t *copy = NULL; 22148 22149 dns_difftuple_copy(tuple, ©); 22150 dns_diff_appendminimal(diff, ©); 22151 } 22152 22153 static void 22154 zone_apply_skrbundle(dns_zone_t *zone, dns_skrbundle_t *bundle, 22155 dns_rdataset_t *dnskeyset, dns_rdataset_t *cdsset, 22156 dns_rdataset_t *cdnskeyset, dns_diff_t *diff) { 22157 dns_kasp_t *kasp = zone->kasp; 22158 22159 REQUIRE(DNS_ZONE_VALID(zone)); 22160 REQUIRE(DNS_KASP_VALID(kasp)); 22161 REQUIRE(DNS_SKRBUNDLE_VALID(bundle)); 22162 22163 /* Remove existing DNSKEY, CDS, and CDNSKEY records. */ 22164 remove_rdataset(zone, diff, dnskeyset); 22165 remove_rdataset(zone, diff, cdsset); 22166 remove_rdataset(zone, diff, cdnskeyset); 22167 22168 /* Add the records from the bundle. */ 22169 dns_difftuple_t *tuple = ISC_LIST_HEAD(bundle->diff.tuples); 22170 while (tuple != NULL) { 22171 switch (tuple->rdata.type) { 22172 case dns_rdatatype_dnskey: 22173 add_tuple(diff, tuple); 22174 break; 22175 case dns_rdatatype_cdnskey: 22176 case dns_rdatatype_cds: 22177 add_tuple(diff, tuple); 22178 break; 22179 case dns_rdatatype_rrsig: 22180 /* Not interested in right now */ 22181 break; 22182 default: 22183 INSIST(0); 22184 } 22185 22186 tuple = ISC_LIST_NEXT(tuple, link); 22187 } 22188 } 22189 22190 static void 22191 zone_rekey(dns_zone_t *zone) { 22192 isc_result_t result; 22193 dns_db_t *db = NULL; 22194 dns_dbnode_t *node = NULL; 22195 dns_dbversion_t *ver = NULL; 22196 dns_rdataset_t cdsset, soaset, soasigs, keyset, keysigs, cdnskeyset; 22197 dns_dnsseckeylist_t dnskeys, keys, rmkeys; 22198 dns_dnsseckey_t *key = NULL; 22199 dns_diff_t diff, _sig_diff; 22200 dns_kasp_t *kasp; 22201 dns_skrbundle_t *bundle = NULL; 22202 dns__zonediff_t zonediff; 22203 bool commit = false, newactive = false; 22204 bool newalg = false; 22205 bool fullsign; 22206 bool offlineksk = false; 22207 uint32_t sigval = 0; 22208 dns_ttl_t ttl = 3600; 22209 const char *dir = NULL; 22210 isc_mem_t *mctx = NULL; 22211 isc_stdtime_t now, nexttime = 0; 22212 isc_time_t timenow; 22213 isc_interval_t ival; 22214 char timebuf[80]; 22215 22216 REQUIRE(DNS_ZONE_VALID(zone)); 22217 22218 ISC_LIST_INIT(dnskeys); 22219 ISC_LIST_INIT(keys); 22220 ISC_LIST_INIT(rmkeys); 22221 dns_rdataset_init(&soaset); 22222 dns_rdataset_init(&soasigs); 22223 dns_rdataset_init(&keyset); 22224 dns_rdataset_init(&keysigs); 22225 dns_rdataset_init(&cdsset); 22226 dns_rdataset_init(&cdnskeyset); 22227 mctx = zone->mctx; 22228 dns_diff_init(mctx, &diff); 22229 dns_diff_init(mctx, &_sig_diff); 22230 zonediff_init(&zonediff, &_sig_diff); 22231 22232 CHECK(dns_zone_getdb(zone, &db)); 22233 CHECK(dns_db_newversion(db, &ver)); 22234 CHECK(dns_db_getoriginnode(db, &node)); 22235 22236 timenow = isc_time_now(); 22237 now = isc_time_seconds(&timenow); 22238 22239 kasp = zone->kasp; 22240 dir = dns_zone_getkeydirectory(zone); 22241 22242 dnssec_log(zone, ISC_LOG_INFO, "reconfiguring zone keys"); 22243 22244 /* Get the SOA record's TTL */ 22245 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 22246 dns_rdatatype_none, 0, &soaset, &soasigs)); 22247 ttl = soaset.ttl; 22248 dns_rdataset_disassociate(&soaset); 22249 22250 if (kasp != NULL) { 22251 ttl = dns_kasp_dnskeyttl(kasp); 22252 offlineksk = dns_kasp_offlineksk(kasp); 22253 sigval = dns_kasp_sigvalidity_dnskey(kasp); 22254 } 22255 22256 /* Get the current DNSKEY rdataset */ 22257 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 22258 dns_rdatatype_none, 0, &keyset, &keysigs); 22259 if (result == ISC_R_SUCCESS) { 22260 /* 22261 * If we don't have a policy then use the DNSKEY ttl 22262 * if it exists. Otherwise update the DNSKEY ttl if 22263 * needed. 22264 */ 22265 if (kasp == NULL) { 22266 ttl = keyset.ttl; 22267 } else if (ttl != keyset.ttl && !offlineksk) { 22268 result = update_ttl(&keyset, &zone->origin, ttl, &diff); 22269 if (result != ISC_R_SUCCESS) { 22270 dnssec_log(zone, ISC_LOG_ERROR, 22271 "Updating DNSKEY TTL from %u to %u " 22272 "failed: %s", 22273 keyset.ttl, ttl, 22274 isc_result_totext(result)); 22275 goto failure; 22276 } 22277 dnssec_log(zone, ISC_LOG_INFO, 22278 "Updating DNSKEY TTL from %u to %u", 22279 keyset.ttl, ttl); 22280 keyset.ttl = ttl; 22281 } 22282 22283 dns_zone_lock_keyfiles(zone); 22284 22285 result = dns_dnssec_keylistfromrdataset( 22286 &zone->origin, kasp, dir, mctx, &keyset, &keysigs, 22287 &soasigs, false, false, &dnskeys); 22288 22289 dns_zone_unlock_keyfiles(zone); 22290 22291 if (result != ISC_R_SUCCESS) { 22292 goto failure; 22293 } 22294 } else if (result != ISC_R_NOTFOUND) { 22295 goto failure; 22296 } 22297 22298 /* Get the current CDS rdataset */ 22299 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cds, 22300 dns_rdatatype_none, 0, &cdsset, NULL); 22301 if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdsset)) { 22302 dns_rdataset_disassociate(&cdsset); 22303 } else if (result == ISC_R_SUCCESS && kasp != NULL && 22304 ttl != cdsset.ttl && !offlineksk) 22305 { 22306 result = update_ttl(&cdsset, &zone->origin, ttl, &diff); 22307 if (result != ISC_R_SUCCESS) { 22308 dnssec_log(zone, ISC_LOG_ERROR, 22309 "Updating CDS TTL from %u to %u failed: %s", 22310 cdsset.ttl, ttl, isc_result_totext(result)); 22311 goto failure; 22312 } 22313 dnssec_log(zone, ISC_LOG_INFO, "Updating CDS TTL from %u to %u", 22314 cdsset.ttl, ttl); 22315 cdsset.ttl = ttl; 22316 } 22317 22318 /* Get the current CDNSKEY rdataset */ 22319 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cdnskey, 22320 dns_rdatatype_none, 0, &cdnskeyset, NULL); 22321 if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdnskeyset)) { 22322 dns_rdataset_disassociate(&cdnskeyset); 22323 } else if (result == ISC_R_SUCCESS && kasp != NULL && 22324 ttl != cdnskeyset.ttl && !offlineksk) 22325 { 22326 result = update_ttl(&cdnskeyset, &zone->origin, ttl, &diff); 22327 if (result != ISC_R_SUCCESS) { 22328 dnssec_log( 22329 zone, ISC_LOG_ERROR, 22330 "Updating CDNSKEY TTL from %u to %u failed: %s", 22331 cdnskeyset.ttl, ttl, isc_result_totext(result)); 22332 goto failure; 22333 } 22334 dnssec_log(zone, ISC_LOG_INFO, 22335 "Updating CDNSKEY TTL from %u to %u", cdnskeyset.ttl, 22336 ttl); 22337 cdnskeyset.ttl = ttl; 22338 } 22339 22340 /* 22341 * True when called from "rndc sign". Indicates the zone should be 22342 * fully signed now. 22343 */ 22344 fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN); 22345 22346 if (offlineksk) { 22347 /* Lookup the correct bundle in the SKR. */ 22348 LOCK_ZONE(zone); 22349 if (zone->skr == NULL) { 22350 UNLOCK_ZONE(zone); 22351 dnssec_log(zone, ISC_LOG_DEBUG(1), 22352 "zone_rekey:dns_skr_lookup failed: " 22353 "no SKR available"); 22354 result = DNS_R_NOSKRFILE; 22355 goto failure; 22356 } 22357 bundle = dns_skr_lookup(zone->skr, now, sigval); 22358 zone->skrbundle = bundle; 22359 UNLOCK_ZONE(zone); 22360 22361 if (bundle == NULL) { 22362 char nowstr[26]; /* Minimal buf per ctime_r() spec. */ 22363 char utc[sizeof("YYYYMMDDHHSSMM")]; 22364 isc_buffer_t b; 22365 isc_region_t r; 22366 isc_buffer_init(&b, utc, sizeof(utc)); 22367 22368 isc_stdtime_tostring(now, nowstr, sizeof(nowstr)); 22369 (void)dns_time32_totext(now, &b); 22370 isc_buffer_usedregion(&b, &r); 22371 dnssec_log(zone, ISC_LOG_DEBUG(1), 22372 "zone_rekey:dns_skr_lookup failed: " 22373 "no available SKR bundle for time " 22374 "%.*s (%s)", 22375 (int)r.length, r.base, nowstr); 22376 result = DNS_R_NOSKRBUNDLE; 22377 goto failure; 22378 } 22379 22380 zone_apply_skrbundle(zone, bundle, &keyset, &cdsset, 22381 &cdnskeyset, &diff); 22382 22383 dns_skrbundle_t *next = ISC_LIST_NEXT(bundle, link); 22384 if (next != NULL) { 22385 if (nexttime == 0) { 22386 nexttime = next->inception; 22387 } 22388 } else { 22389 dnssec_log(zone, ISC_LOG_WARNING, 22390 "zone_rekey: last bundle in skr, please " 22391 "import new skr file"); 22392 } 22393 } 22394 22395 /* 22396 * DNSSEC Key and Signing Policy 22397 */ 22398 22399 KASP_LOCK(kasp); 22400 22401 dns_zone_lock_keyfiles(zone); 22402 result = dns_dnssec_findmatchingkeys(&zone->origin, kasp, dir, 22403 zone->keystores, now, mctx, &keys); 22404 dns_zone_unlock_keyfiles(zone); 22405 22406 if (result != ISC_R_SUCCESS) { 22407 dnssec_log(zone, ISC_LOG_DEBUG(1), 22408 "zone_rekey:dns_dnssec_findmatchingkeys failed: %s", 22409 isc_result_totext(result)); 22410 } 22411 22412 if (kasp != NULL && !offlineksk) { 22413 /* Verify new keys. */ 22414 isc_result_t ret = zone_verifykeys(zone, &keys); 22415 if (ret != ISC_R_SUCCESS) { 22416 dnssec_log(zone, ISC_LOG_ERROR, 22417 "zone_rekey:zone_verifykeys failed: " 22418 "some key files are missing"); 22419 KASP_UNLOCK(kasp); 22420 goto failure; 22421 } 22422 22423 /* 22424 * Check DS at parental agents. Clear ongoing checks. 22425 */ 22426 LOCK_ZONE(zone); 22427 checkds_cancel(zone); 22428 clear_keylist(&zone->checkds_ok, zone->mctx); 22429 ISC_LIST_INIT(zone->checkds_ok); 22430 UNLOCK_ZONE(zone); 22431 22432 ret = dns_zone_getdnsseckeys(zone, db, ver, now, 22433 &zone->checkds_ok); 22434 if (ret == ISC_R_SUCCESS) { 22435 zone_checkds(zone); 22436 } else { 22437 dnssec_log(zone, 22438 (ret == ISC_R_NOTFOUND) ? ISC_LOG_DEBUG(1) 22439 : ISC_LOG_ERROR, 22440 "zone_rekey:dns_zone_getdnsseckeys failed: " 22441 "%s", 22442 isc_result_totext(ret)); 22443 } 22444 22445 /* Run keymgr. */ 22446 if (result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND) { 22447 dns_zone_lock_keyfiles(zone); 22448 result = dns_keymgr_run(&zone->origin, zone->rdclass, 22449 mctx, &keys, &dnskeys, dir, 22450 kasp, now, &nexttime); 22451 dns_zone_unlock_keyfiles(zone); 22452 22453 if (result != ISC_R_SUCCESS) { 22454 dnssec_log(zone, ISC_LOG_ERROR, 22455 "zone_rekey:dns_keymgr_run " 22456 "failed: %s", 22457 isc_result_totext(result)); 22458 KASP_UNLOCK(kasp); 22459 goto failure; 22460 } 22461 } 22462 } else if (offlineksk) { 22463 /* 22464 * With offline-ksk enabled we don't run the keymgr. 22465 * Instead we derive the states from the timing metadata. 22466 */ 22467 dns_zone_lock_keyfiles(zone); 22468 result = dns_keymgr_offline(&zone->origin, &keys, kasp, now, 22469 &nexttime); 22470 dns_zone_unlock_keyfiles(zone); 22471 22472 if (result != ISC_R_SUCCESS) { 22473 dnssec_log(zone, ISC_LOG_ERROR, 22474 "zone_rekey:dns_keymgr_offline " 22475 "failed: %s", 22476 isc_result_totext(result)); 22477 } 22478 } 22479 22480 KASP_UNLOCK(kasp); 22481 22482 /* 22483 * Update CDS, CDNSKEY and DNSKEY record sets if the keymgr ran 22484 * successfully (dns_keymgr_run returned ISC_R_SUCCESS), or in 22485 * case of DNSSEC management without dnssec-policy if we have keys 22486 * (dns_dnssec_findmatchingkeys returned ISC_R_SUCCESS). 22487 */ 22488 if (result == ISC_R_SUCCESS) { 22489 dns_kasp_digestlist_t digests; 22490 bool cdsdel = false; 22491 bool cdnskeydel = false; 22492 bool cdnskeypub = true; 22493 bool sane_diff, sane_dnskey; 22494 isc_stdtime_t when; 22495 22496 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys, 22497 &zone->origin, ttl, &diff, mctx, 22498 dnssec_report); 22499 /* 22500 * Keys couldn't be updated for some reason; 22501 * try again later. 22502 */ 22503 if (result != ISC_R_SUCCESS) { 22504 dnssec_log(zone, ISC_LOG_ERROR, 22505 "zone_rekey:couldn't update zone keys: %s", 22506 isc_result_totext(result)); 22507 goto failure; 22508 } 22509 22510 if (offlineksk) { 22511 /* We can skip a lot of things */ 22512 goto post_sync; 22513 } 22514 22515 /* 22516 * Publish CDS/CDNSKEY DELETE records if the zone is 22517 * transitioning from secure to insecure. 22518 */ 22519 if (kasp != NULL) { 22520 if (strcmp(dns_kasp_getname(kasp), "insecure") == 0) { 22521 cdsdel = true; 22522 cdnskeydel = true; 22523 } 22524 digests = dns_kasp_digests(kasp); 22525 cdnskeypub = dns_kasp_cdnskey(kasp); 22526 } else { 22527 /* Check if there is a CDS DELETE record. */ 22528 if (dns_rdataset_isassociated(&cdsset)) { 22529 for (result = dns_rdataset_first(&cdsset); 22530 result == ISC_R_SUCCESS; 22531 result = dns_rdataset_next(&cdsset)) 22532 { 22533 dns_rdata_t crdata = DNS_RDATA_INIT; 22534 dns_rdataset_current(&cdsset, &crdata); 22535 /* 22536 * CDS deletion record has this form 22537 * "0 0 0 00" which is 5 zero octets. 22538 */ 22539 if (crdata.length == 5U && 22540 memcmp(crdata.data, 22541 (unsigned char[5]){ 0, 0, 0, 22542 0, 0 }, 22543 5) == 0) 22544 { 22545 cdsdel = true; 22546 break; 22547 } 22548 } 22549 } 22550 22551 /* Check if there is a CDNSKEY DELETE record. */ 22552 if (dns_rdataset_isassociated(&cdnskeyset)) { 22553 for (result = dns_rdataset_first(&cdnskeyset); 22554 result == ISC_R_SUCCESS; 22555 result = dns_rdataset_next(&cdnskeyset)) 22556 { 22557 dns_rdata_t crdata = DNS_RDATA_INIT; 22558 dns_rdataset_current(&cdnskeyset, 22559 &crdata); 22560 /* 22561 * CDNSKEY deletion record has this form 22562 * "0 3 0 AA==" which is 2 zero octets, 22563 * a 3, and 2 zero octets. 22564 */ 22565 if (crdata.length == 5U && 22566 memcmp(crdata.data, 22567 (unsigned char[5]){ 0, 0, 3, 22568 0, 0 }, 22569 5) == 0) 22570 { 22571 cdnskeydel = true; 22572 break; 22573 } 22574 } 22575 } 22576 22577 digests = dns_kasp_digests(zone->defaultkasp); 22578 } 22579 22580 /* 22581 * Update CDS / CDNSKEY records. 22582 */ 22583 result = dns_dnssec_syncupdate(&dnskeys, &rmkeys, &cdsset, 22584 &cdnskeyset, now, &digests, 22585 cdnskeypub, ttl, &diff, mctx); 22586 if (result != ISC_R_SUCCESS) { 22587 dnssec_log(zone, ISC_LOG_ERROR, 22588 "zone_rekey:couldn't update CDS/CDNSKEY: %s", 22589 isc_result_totext(result)); 22590 goto failure; 22591 } 22592 22593 if (cdsdel || cdnskeydel) { 22594 /* 22595 * Only publish CDS/CDNSKEY DELETE records if there is 22596 * a KSK that can be used to verify the RRset. This 22597 * means there must be a key with the KSK role that is 22598 * published and is used for signing. 22599 */ 22600 bool allow = false; 22601 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 22602 key = ISC_LIST_NEXT(key, link)) 22603 { 22604 dst_key_t *dstk = key->key; 22605 22606 if (dst_key_is_published(dstk, now, &when) && 22607 dst_key_is_signing(dstk, DST_BOOL_KSK, now, 22608 &when)) 22609 { 22610 allow = true; 22611 break; 22612 } 22613 } 22614 if (cdsdel) { 22615 cdsdel = allow; 22616 } 22617 if (cdnskeydel) { 22618 cdnskeydel = allow; 22619 } 22620 } 22621 result = dns_dnssec_syncdelete( 22622 &cdsset, &cdnskeyset, &zone->origin, zone->rdclass, ttl, 22623 &diff, mctx, cdsdel, cdnskeydel); 22624 if (result != ISC_R_SUCCESS) { 22625 dnssec_log(zone, ISC_LOG_ERROR, 22626 "zone_rekey:couldn't update CDS/CDNSKEY " 22627 "DELETE records: %s", 22628 isc_result_totext(result)); 22629 goto failure; 22630 } 22631 22632 post_sync: 22633 /* 22634 * See if any pre-existing keys have newly become active; 22635 * also, see if any new key is for a new algorithm, as in that 22636 * event, we need to sign the zone fully. (If there's a new 22637 * key, but it's for an already-existing algorithm, then 22638 * the zone signing can be handled incrementally.) 22639 */ 22640 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 22641 key = ISC_LIST_NEXT(key, link)) 22642 { 22643 if (!key->first_sign) { 22644 continue; 22645 } 22646 22647 newactive = true; 22648 22649 if (!dns_rdataset_isassociated(&keysigs)) { 22650 newalg = true; 22651 break; 22652 } 22653 22654 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) { 22655 /* 22656 * This isn't a new algorithm; clear 22657 * first_sign so we won't sign the 22658 * whole zone with this key later. 22659 */ 22660 key->first_sign = false; 22661 } else { 22662 newalg = true; 22663 break; 22664 } 22665 } 22666 22667 /* 22668 * A sane diff is one that is not empty, and that does not 22669 * introduce a zone with NSEC only DNSKEYs along with NSEC3 22670 * chains. 22671 */ 22672 sane_dnskey = dns_zone_check_dnskey_nsec3(zone, db, ver, &diff, 22673 NULL, 0); 22674 sane_diff = !ISC_LIST_EMPTY(diff.tuples) && sane_dnskey; 22675 if (!sane_dnskey) { 22676 dnssec_log(zone, ISC_LOG_ERROR, 22677 "NSEC only DNSKEYs and NSEC3 chains not " 22678 "allowed"); 22679 } 22680 22681 if (newactive || fullsign || sane_diff) { 22682 CHECK(dns_diff_apply(&diff, db, ver)); 22683 CHECK(clean_nsec3param(zone, db, ver, &diff)); 22684 CHECK(add_signing_records(db, zone->privatetype, ver, 22685 &diff, (newalg || fullsign))); 22686 CHECK(update_soa_serial(zone, db, ver, &diff, mctx, 22687 zone->updatemethod)); 22688 CHECK(add_chains(zone, db, ver, &diff)); 22689 CHECK(sign_apex(zone, db, ver, now, &diff, &zonediff)); 22690 CHECK(zone_journal(zone, zonediff.diff, NULL, 22691 "zone_rekey")); 22692 commit = true; 22693 } 22694 } 22695 22696 dns_db_closeversion(db, &ver, true); 22697 22698 LOCK_ZONE(zone); 22699 22700 if (commit) { 22701 dns_difftuple_t *tuple; 22702 dns_stats_t *dnssecsignstats = 22703 dns_zone_getdnssecsignstats(zone); 22704 22705 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 22706 22707 zone_needdump(zone, DNS_DUMP_DELAY); 22708 22709 zone_settimer(zone, &timenow); 22710 22711 /* Remove any signatures from removed keys. */ 22712 if (!ISC_LIST_EMPTY(rmkeys)) { 22713 for (key = ISC_LIST_HEAD(rmkeys); key != NULL; 22714 key = ISC_LIST_NEXT(key, link)) 22715 { 22716 result = zone_signwithkey( 22717 zone, dst_key_alg(key->key), 22718 dst_key_id(key->key), true); 22719 if (result != ISC_R_SUCCESS) { 22720 dnssec_log(zone, ISC_LOG_ERROR, 22721 "zone_signwithkey failed: " 22722 "%s", 22723 isc_result_totext(result)); 22724 } 22725 22726 /* Clear DNSSEC sign statistics. */ 22727 if (dnssecsignstats != NULL) { 22728 dns_dnssecsignstats_clear( 22729 dnssecsignstats, 22730 dst_key_id(key->key), 22731 dst_key_alg(key->key)); 22732 /* 22733 * Also clear the dnssec-sign 22734 * statistics of the revoked key id. 22735 */ 22736 dns_dnssecsignstats_clear( 22737 dnssecsignstats, 22738 dst_key_rid(key->key), 22739 dst_key_alg(key->key)); 22740 } 22741 } 22742 } 22743 22744 if (fullsign) { 22745 /* 22746 * "rndc sign" was called, so we now sign the zone 22747 * with all active keys, whether they're new or not. 22748 */ 22749 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 22750 key = ISC_LIST_NEXT(key, link)) 22751 { 22752 if (!key->force_sign && !key->hint_sign) { 22753 continue; 22754 } 22755 22756 result = zone_signwithkey( 22757 zone, dst_key_alg(key->key), 22758 dst_key_id(key->key), false); 22759 if (result != ISC_R_SUCCESS) { 22760 dnssec_log(zone, ISC_LOG_ERROR, 22761 "zone_signwithkey failed: " 22762 "%s", 22763 isc_result_totext(result)); 22764 } 22765 } 22766 } else if (newalg) { 22767 /* 22768 * We haven't been told to sign fully, but a new 22769 * algorithm was added to the DNSKEY. We sign 22770 * the full zone, but only with newly active 22771 * keys. 22772 */ 22773 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 22774 key = ISC_LIST_NEXT(key, link)) 22775 { 22776 if (!key->first_sign) { 22777 continue; 22778 } 22779 22780 result = zone_signwithkey( 22781 zone, dst_key_alg(key->key), 22782 dst_key_id(key->key), false); 22783 if (result != ISC_R_SUCCESS) { 22784 dnssec_log(zone, ISC_LOG_ERROR, 22785 "zone_signwithkey failed: " 22786 "%s", 22787 isc_result_totext(result)); 22788 } 22789 } 22790 } 22791 22792 /* 22793 * Clear fullsign flag, if it was set, so we don't do 22794 * another full signing next time. 22795 */ 22796 DNS_ZONEKEY_CLROPTION(zone, DNS_ZONEKEY_FULLSIGN); 22797 22798 /* 22799 * Cause the zone to add/delete NSEC3 chains for the 22800 * deferred NSEC3PARAM changes. 22801 */ 22802 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples); 22803 tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) 22804 { 22805 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 22806 dns_rdata_t rdata = DNS_RDATA_INIT; 22807 dns_rdata_nsec3param_t nsec3param; 22808 22809 if (tuple->rdata.type != zone->privatetype || 22810 tuple->op != DNS_DIFFOP_ADD) 22811 { 22812 continue; 22813 } 22814 22815 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata, 22816 buf, sizeof(buf))) 22817 { 22818 continue; 22819 } 22820 22821 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 22822 RUNTIME_CHECK(result == ISC_R_SUCCESS); 22823 if (nsec3param.flags == 0) { 22824 continue; 22825 } 22826 22827 result = zone_addnsec3chain(zone, &nsec3param); 22828 if (result != ISC_R_SUCCESS) { 22829 dnssec_log(zone, ISC_LOG_ERROR, 22830 "zone_addnsec3chain failed: %s", 22831 isc_result_totext(result)); 22832 } 22833 } 22834 22835 /* 22836 * Activate any NSEC3 chain updates that may have 22837 * been scheduled before this rekey. 22838 */ 22839 if (fullsign || newalg) { 22840 resume_addnsec3chain(zone); 22841 } 22842 22843 /* 22844 * Schedule the next resigning event 22845 */ 22846 set_resigntime(zone); 22847 } 22848 22849 isc_time_settoepoch(&zone->refreshkeytime); 22850 22851 /* 22852 * If keymgr provided a next time, use the calculated next rekey time. 22853 */ 22854 if (kasp != NULL) { 22855 isc_time_t timenext; 22856 uint32_t nexttime_seconds; 22857 22858 /* 22859 * Set the key refresh timer to the next scheduled key event 22860 * or to 'dnssec-loadkeys-interval' seconds in the future 22861 * if no next key event is scheduled (nexttime == 0). 22862 */ 22863 if (nexttime > 0) { 22864 nexttime_seconds = nexttime - now; 22865 } else { 22866 nexttime_seconds = zone->refreshkeyinterval; 22867 } 22868 22869 DNS_ZONE_TIME_ADD(&timenow, nexttime_seconds, &timenext); 22870 zone->refreshkeytime = timenext; 22871 zone_settimer(zone, &timenow); 22872 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 22873 22874 dnssec_log(zone, ISC_LOG_DEBUG(3), 22875 "next key event in %u seconds", nexttime_seconds); 22876 dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); 22877 } 22878 /* 22879 * If we're doing key maintenance, set the key refresh timer to 22880 * the next scheduled key event or to 'dnssec-loadkeys-interval' 22881 * seconds in the future, whichever is sooner. 22882 */ 22883 else if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 22884 { 22885 isc_time_t timethen; 22886 isc_stdtime_t then; 22887 22888 DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval, 22889 &timethen); 22890 zone->refreshkeytime = timethen; 22891 22892 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 22893 key = ISC_LIST_NEXT(key, link)) 22894 { 22895 then = now; 22896 result = next_keyevent(key->key, &then); 22897 if (result != ISC_R_SUCCESS) { 22898 continue; 22899 } 22900 22901 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 22902 if (isc_time_compare(&timethen, &zone->refreshkeytime) < 22903 0) 22904 { 22905 zone->refreshkeytime = timethen; 22906 } 22907 } 22908 22909 zone_settimer(zone, &timenow); 22910 22911 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 22912 dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); 22913 } 22914 UNLOCK_ZONE(zone); 22915 22916 /* 22917 * Remember which keys have been used. 22918 */ 22919 if (!ISC_LIST_EMPTY(zone->keyring)) { 22920 clear_keylist(&zone->keyring, zone->mctx); 22921 } 22922 while ((key = ISC_LIST_HEAD(dnskeys)) != NULL) { 22923 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 22924 /* This debug log is used in the kasp system test */ 22925 char algbuf[DNS_SECALG_FORMATSIZE]; 22926 dns_secalg_format(dst_key_alg(key->key), algbuf, 22927 sizeof(algbuf)); 22928 dnssec_log(zone, ISC_LOG_DEBUG(3), 22929 "zone_rekey done: key %d/%s", 22930 dst_key_id(key->key), algbuf); 22931 } 22932 ISC_LIST_UNLINK(dnskeys, key, link); 22933 ISC_LIST_APPEND(zone->keyring, key, link); 22934 } 22935 22936 result = ISC_R_SUCCESS; 22937 22938 failure: 22939 LOCK_ZONE(zone); 22940 if (result != ISC_R_SUCCESS) { 22941 /* 22942 * Something went wrong; try again in ten minutes or 22943 * after a key refresh interval, whichever is shorter. 22944 */ 22945 int loglevel = ISC_LOG_DEBUG(3); 22946 if (result != DNS_R_NOTLOADED) { 22947 loglevel = ISC_LOG_ERROR; 22948 } 22949 dnssec_log(zone, loglevel, 22950 "zone_rekey failure: %s (retry in %u seconds)", 22951 isc_result_totext(result), 22952 ISC_MIN(zone->refreshkeyinterval, 600)); 22953 isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 22954 0); 22955 isc_time_nowplusinterval(&zone->refreshkeytime, &ival); 22956 } 22957 UNLOCK_ZONE(zone); 22958 22959 dns_diff_clear(&diff); 22960 dns_diff_clear(&_sig_diff); 22961 22962 clear_keylist(&dnskeys, mctx); 22963 clear_keylist(&keys, mctx); 22964 clear_keylist(&rmkeys, mctx); 22965 22966 if (ver != NULL) { 22967 dns_db_closeversion(db, &ver, false); 22968 } 22969 if (dns_rdataset_isassociated(&cdsset)) { 22970 dns_rdataset_disassociate(&cdsset); 22971 } 22972 if (dns_rdataset_isassociated(&keyset)) { 22973 dns_rdataset_disassociate(&keyset); 22974 } 22975 if (dns_rdataset_isassociated(&keysigs)) { 22976 dns_rdataset_disassociate(&keysigs); 22977 } 22978 if (dns_rdataset_isassociated(&soasigs)) { 22979 dns_rdataset_disassociate(&soasigs); 22980 } 22981 if (dns_rdataset_isassociated(&cdnskeyset)) { 22982 dns_rdataset_disassociate(&cdnskeyset); 22983 } 22984 if (node != NULL) { 22985 dns_db_detachnode(db, &node); 22986 } 22987 if (db != NULL) { 22988 dns_db_detach(&db); 22989 } 22990 22991 INSIST(ver == NULL); 22992 } 22993 22994 void 22995 dns_zone_rekey(dns_zone_t *zone, bool fullsign) { 22996 isc_time_t now; 22997 22998 if (zone->type == dns_zone_primary && zone->loop != NULL) { 22999 LOCK_ZONE(zone); 23000 23001 if (fullsign) { 23002 DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN); 23003 } 23004 23005 now = isc_time_now(); 23006 zone->refreshkeytime = now; 23007 zone_settimer(zone, &now); 23008 23009 UNLOCK_ZONE(zone); 23010 } 23011 } 23012 23013 isc_result_t 23014 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 23015 unsigned int *errors) { 23016 isc_result_t result; 23017 dns_dbnode_t *node = NULL; 23018 23019 REQUIRE(DNS_ZONE_VALID(zone)); 23020 REQUIRE(errors != NULL); 23021 23022 result = dns_db_getoriginnode(db, &node); 23023 if (result != ISC_R_SUCCESS) { 23024 return result; 23025 } 23026 result = zone_count_ns_rr(zone, db, node, version, NULL, errors, false); 23027 dns_db_detachnode(db, &node); 23028 return result; 23029 } 23030 23031 isc_result_t 23032 dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { 23033 isc_result_t result; 23034 dns_dbnode_t *node = NULL; 23035 dns_rdataset_t dnskey, cds, cdnskey; 23036 unsigned char algorithms[256]; 23037 unsigned int i; 23038 bool empty = false; 23039 23040 enum { notexpected = 0, expected = 1, found = 2 }; 23041 23042 REQUIRE(DNS_ZONE_VALID(zone)); 23043 23044 result = dns_db_getoriginnode(db, &node); 23045 if (result != ISC_R_SUCCESS) { 23046 return result; 23047 } 23048 23049 dns_rdataset_init(&cds); 23050 dns_rdataset_init(&dnskey); 23051 dns_rdataset_init(&cdnskey); 23052 23053 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds, 23054 dns_rdatatype_none, 0, &cds, NULL); 23055 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 23056 goto failure; 23057 } 23058 23059 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey, 23060 dns_rdatatype_none, 0, &cdnskey, NULL); 23061 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 23062 goto failure; 23063 } 23064 23065 if (!dns_rdataset_isassociated(&cds) && 23066 !dns_rdataset_isassociated(&cdnskey)) 23067 { 23068 result = ISC_R_SUCCESS; 23069 goto failure; 23070 } 23071 23072 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 23073 dns_rdatatype_none, 0, &dnskey, NULL); 23074 if (result == ISC_R_NOTFOUND) { 23075 empty = true; 23076 } else if (result != ISC_R_SUCCESS) { 23077 goto failure; 23078 } 23079 23080 /* 23081 * For each DNSSEC algorithm in the CDS RRset there must be 23082 * a matching DNSKEY record with the exception of a CDS deletion 23083 * record which must be by itself. 23084 */ 23085 if (dns_rdataset_isassociated(&cds)) { 23086 bool delete = false; 23087 memset(algorithms, notexpected, sizeof(algorithms)); 23088 for (result = dns_rdataset_first(&cds); result == ISC_R_SUCCESS; 23089 result = dns_rdataset_next(&cds)) 23090 { 23091 dns_rdata_t crdata = DNS_RDATA_INIT; 23092 dns_rdata_cds_t structcds; 23093 23094 dns_rdataset_current(&cds, &crdata); 23095 /* 23096 * CDS deletion record has this form "0 0 0 00" which 23097 * is 5 zero octets. 23098 */ 23099 if (crdata.length == 5U && 23100 memcmp(crdata.data, 23101 (unsigned char[5]){ 0, 0, 0, 0, 0 }, 5) == 0) 23102 { 23103 delete = true; 23104 continue; 23105 } 23106 23107 if (empty) { 23108 result = DNS_R_BADCDS; 23109 goto failure; 23110 } 23111 23112 CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL)); 23113 if (algorithms[structcds.algorithm] == 0) { 23114 algorithms[structcds.algorithm] = expected; 23115 } 23116 for (result = dns_rdataset_first(&dnskey); 23117 result == ISC_R_SUCCESS; 23118 result = dns_rdataset_next(&dnskey)) 23119 { 23120 dns_rdata_t rdata = DNS_RDATA_INIT; 23121 dns_rdata_dnskey_t structdnskey; 23122 23123 dns_rdataset_current(&dnskey, &rdata); 23124 CHECK(dns_rdata_tostruct(&rdata, &structdnskey, 23125 NULL)); 23126 23127 if (structdnskey.algorithm == 23128 structcds.algorithm) 23129 { 23130 algorithms[structcds.algorithm] = found; 23131 } 23132 } 23133 if (result != ISC_R_NOMORE) { 23134 goto failure; 23135 } 23136 } 23137 for (i = 0; i < sizeof(algorithms); i++) { 23138 if (delete) { 23139 if (algorithms[i] != notexpected) { 23140 result = DNS_R_BADCDS; 23141 goto failure; 23142 } 23143 } else if (algorithms[i] == expected) { 23144 result = DNS_R_BADCDS; 23145 goto failure; 23146 } 23147 } 23148 } 23149 23150 /* 23151 * For each DNSSEC algorithm in the CDNSKEY RRset there must be 23152 * a matching DNSKEY record with the exception of a CDNSKEY deletion 23153 * record which must be by itself. 23154 */ 23155 if (dns_rdataset_isassociated(&cdnskey)) { 23156 bool delete = false; 23157 memset(algorithms, notexpected, sizeof(algorithms)); 23158 for (result = dns_rdataset_first(&cdnskey); 23159 result == ISC_R_SUCCESS; 23160 result = dns_rdataset_next(&cdnskey)) 23161 { 23162 dns_rdata_t crdata = DNS_RDATA_INIT; 23163 dns_rdata_cdnskey_t structcdnskey; 23164 23165 dns_rdataset_current(&cdnskey, &crdata); 23166 /* 23167 * CDNSKEY deletion record has this form 23168 * "0 3 0 AA==" which is 2 zero octets, a 3, 23169 * and 2 zero octets. 23170 */ 23171 if (crdata.length == 5U && 23172 memcmp(crdata.data, 23173 (unsigned char[5]){ 0, 0, 3, 0, 0 }, 5) == 0) 23174 { 23175 delete = true; 23176 continue; 23177 } 23178 23179 if (empty) { 23180 result = DNS_R_BADCDNSKEY; 23181 goto failure; 23182 } 23183 23184 CHECK(dns_rdata_tostruct(&crdata, &structcdnskey, 23185 NULL)); 23186 if (algorithms[structcdnskey.algorithm] == 0) { 23187 algorithms[structcdnskey.algorithm] = expected; 23188 } 23189 for (result = dns_rdataset_first(&dnskey); 23190 result == ISC_R_SUCCESS; 23191 result = dns_rdataset_next(&dnskey)) 23192 { 23193 dns_rdata_t rdata = DNS_RDATA_INIT; 23194 dns_rdata_dnskey_t structdnskey; 23195 23196 dns_rdataset_current(&dnskey, &rdata); 23197 CHECK(dns_rdata_tostruct(&rdata, &structdnskey, 23198 NULL)); 23199 23200 if (structdnskey.algorithm == 23201 structcdnskey.algorithm) 23202 { 23203 algorithms[structcdnskey.algorithm] = 23204 found; 23205 } 23206 } 23207 if (result != ISC_R_NOMORE) { 23208 goto failure; 23209 } 23210 } 23211 for (i = 0; i < sizeof(algorithms); i++) { 23212 if (delete) { 23213 if (algorithms[i] != notexpected) { 23214 result = DNS_R_BADCDNSKEY; 23215 goto failure; 23216 } 23217 } else if (algorithms[i] == expected) { 23218 result = DNS_R_BADCDNSKEY; 23219 goto failure; 23220 } 23221 } 23222 } 23223 result = ISC_R_SUCCESS; 23224 23225 failure: 23226 if (dns_rdataset_isassociated(&cds)) { 23227 dns_rdataset_disassociate(&cds); 23228 } 23229 if (dns_rdataset_isassociated(&dnskey)) { 23230 dns_rdataset_disassociate(&dnskey); 23231 } 23232 if (dns_rdataset_isassociated(&cdnskey)) { 23233 dns_rdataset_disassociate(&cdnskey); 23234 } 23235 dns_db_detachnode(db, &node); 23236 return result; 23237 } 23238 23239 void 23240 dns_zone_setautomatic(dns_zone_t *zone, bool automatic) { 23241 REQUIRE(DNS_ZONE_VALID(zone)); 23242 23243 LOCK_ZONE(zone); 23244 zone->automatic = automatic; 23245 UNLOCK_ZONE(zone); 23246 } 23247 23248 bool 23249 dns_zone_getautomatic(dns_zone_t *zone) { 23250 REQUIRE(DNS_ZONE_VALID(zone)); 23251 return zone->automatic; 23252 } 23253 23254 void 23255 dns_zone_setadded(dns_zone_t *zone, bool added) { 23256 REQUIRE(DNS_ZONE_VALID(zone)); 23257 23258 LOCK_ZONE(zone); 23259 zone->added = added; 23260 UNLOCK_ZONE(zone); 23261 } 23262 23263 bool 23264 dns_zone_getadded(dns_zone_t *zone) { 23265 REQUIRE(DNS_ZONE_VALID(zone)); 23266 return zone->added; 23267 } 23268 23269 isc_result_t 23270 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db) { 23271 isc_time_t loadtime; 23272 isc_result_t result; 23273 dns_zone_t *secure = NULL; 23274 23275 loadtime = isc_time_now(); 23276 23277 /* 23278 * Lock hierarchy: zmgr, zone, raw. 23279 */ 23280 again: 23281 LOCK_ZONE(zone); 23282 INSIST(zone != zone->raw); 23283 if (inline_secure(zone)) { 23284 LOCK_ZONE(zone->raw); 23285 } else if (inline_raw(zone)) { 23286 secure = zone->secure; 23287 TRYLOCK_ZONE(result, secure); 23288 if (result != ISC_R_SUCCESS) { 23289 UNLOCK_ZONE(zone); 23290 secure = NULL; 23291 isc_thread_yield(); 23292 goto again; 23293 } 23294 } 23295 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 23296 if (inline_secure(zone)) { 23297 UNLOCK_ZONE(zone->raw); 23298 } else if (secure != NULL) { 23299 UNLOCK_ZONE(secure); 23300 } 23301 UNLOCK_ZONE(zone); 23302 return result; 23303 } 23304 23305 isc_result_t 23306 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, uint32_t interval) { 23307 REQUIRE(DNS_ZONE_VALID(zone)); 23308 if (interval == 0) { 23309 return ISC_R_RANGE; 23310 } 23311 /* Maximum value: 24 hours (3600 minutes) */ 23312 if (interval > (24 * 60)) { 23313 interval = (24 * 60); 23314 } 23315 /* Multiply by 60 for seconds */ 23316 zone->refreshkeyinterval = interval * 60; 23317 return ISC_R_SUCCESS; 23318 } 23319 23320 void 23321 dns_zone_setrequestixfr(dns_zone_t *zone, bool flag) { 23322 REQUIRE(DNS_ZONE_VALID(zone)); 23323 zone->requestixfr = flag; 23324 } 23325 23326 bool 23327 dns_zone_getrequestixfr(dns_zone_t *zone) { 23328 REQUIRE(DNS_ZONE_VALID(zone)); 23329 return zone->requestixfr; 23330 } 23331 23332 void 23333 dns_zone_setixfrratio(dns_zone_t *zone, uint32_t ratio) { 23334 REQUIRE(DNS_ZONE_VALID(zone)); 23335 zone->ixfr_ratio = ratio; 23336 } 23337 23338 uint32_t 23339 dns_zone_getixfrratio(dns_zone_t *zone) { 23340 REQUIRE(DNS_ZONE_VALID(zone)); 23341 return zone->ixfr_ratio; 23342 } 23343 23344 void 23345 dns_zone_setrequestexpire(dns_zone_t *zone, bool flag) { 23346 REQUIRE(DNS_ZONE_VALID(zone)); 23347 zone->requestexpire = flag; 23348 } 23349 23350 bool 23351 dns_zone_getrequestexpire(dns_zone_t *zone) { 23352 REQUIRE(DNS_ZONE_VALID(zone)); 23353 return zone->requestexpire; 23354 } 23355 23356 void 23357 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) { 23358 REQUIRE(DNS_ZONE_VALID(zone)); 23359 zone->updatemethod = method; 23360 } 23361 23362 dns_updatemethod_t 23363 dns_zone_getserialupdatemethod(dns_zone_t *zone) { 23364 REQUIRE(DNS_ZONE_VALID(zone)); 23365 return zone->updatemethod; 23366 } 23367 23368 /* 23369 * Lock hierarchy: zmgr, zone, raw. 23370 */ 23371 isc_result_t 23372 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) { 23373 dns_zonemgr_t *zmgr; 23374 23375 REQUIRE(DNS_ZONE_VALID(zone)); 23376 REQUIRE(zone->zmgr != NULL); 23377 REQUIRE(zone->loop != NULL); 23378 REQUIRE(zone->raw == NULL); 23379 23380 REQUIRE(DNS_ZONE_VALID(raw)); 23381 REQUIRE(raw->zmgr == NULL); 23382 REQUIRE(raw->loop == NULL); 23383 REQUIRE(raw->secure == NULL); 23384 23385 REQUIRE(zone != raw); 23386 23387 /* 23388 * Lock hierarchy: zmgr, zone, raw. 23389 */ 23390 zmgr = zone->zmgr; 23391 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 23392 LOCK_ZONE(zone); 23393 LOCK_ZONE(raw); 23394 23395 isc_loop_attach(zone->loop, &raw->loop); 23396 23397 /* dns_zone_attach(raw, &zone->raw); */ 23398 isc_refcount_increment(&raw->references); 23399 zone->raw = raw; 23400 23401 /* dns_zone_iattach(zone, &raw->secure); */ 23402 zone_iattach(zone, &raw->secure); 23403 23404 ISC_LIST_APPEND(zmgr->zones, raw, link); 23405 raw->zmgr = zmgr; 23406 isc_refcount_increment(&zmgr->refs); 23407 23408 UNLOCK_ZONE(raw); 23409 UNLOCK_ZONE(zone); 23410 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 23411 return ISC_R_SUCCESS; 23412 } 23413 23414 void 23415 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) { 23416 REQUIRE(DNS_ZONE_VALID(zone)); 23417 REQUIRE(raw != NULL && *raw == NULL); 23418 23419 LOCK(&zone->lock); 23420 INSIST(zone != zone->raw); 23421 if (zone->raw != NULL) { 23422 dns_zone_attach(zone->raw, raw); 23423 } 23424 UNLOCK(&zone->lock); 23425 } 23426 23427 bool 23428 dns_zone_israw(dns_zone_t *zone) { 23429 bool israw; 23430 REQUIRE(DNS_ZONE_VALID(zone)); 23431 LOCK(&zone->lock); 23432 israw = zone->secure != NULL; 23433 UNLOCK(&zone->lock); 23434 return israw; 23435 } 23436 23437 bool 23438 dns_zone_issecure(dns_zone_t *zone) { 23439 bool issecure; 23440 REQUIRE(DNS_ZONE_VALID(zone)); 23441 LOCK(&zone->lock); 23442 issecure = zone->raw != NULL; 23443 UNLOCK(&zone->lock); 23444 return issecure; 23445 } 23446 23447 struct keydone { 23448 bool all; 23449 unsigned char data[5]; 23450 dns_zone_t *zone; 23451 }; 23452 23453 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL) 23454 23455 static void 23456 keydone(void *arg) { 23457 bool commit = false; 23458 isc_result_t result; 23459 dns_rdata_t rdata = DNS_RDATA_INIT; 23460 dns_dbversion_t *oldver = NULL, *newver = NULL; 23461 dns_db_t *db = NULL; 23462 dns_dbnode_t *node = NULL; 23463 dns_rdataset_t rdataset; 23464 dns_diff_t diff; 23465 struct keydone *kd = (struct keydone *)arg; 23466 dns_zone_t *zone = kd->zone; 23467 dns_update_log_t log = { update_log_cb, NULL }; 23468 bool clear_pending = false; 23469 23470 INSIST(DNS_ZONE_VALID(zone)); 23471 23472 ENTER; 23473 23474 dns_rdataset_init(&rdataset); 23475 dns_diff_init(zone->mctx, &diff); 23476 23477 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 23478 if (zone->db != NULL) { 23479 dns_db_attach(zone->db, &db); 23480 } 23481 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 23482 if (db == NULL) { 23483 goto failure; 23484 } 23485 23486 dns_db_currentversion(db, &oldver); 23487 result = dns_db_newversion(db, &newver); 23488 if (result != ISC_R_SUCCESS) { 23489 dnssec_log(zone, ISC_LOG_ERROR, 23490 "keydone:dns_db_newversion -> %s", 23491 isc_result_totext(result)); 23492 goto failure; 23493 } 23494 23495 result = dns_db_getoriginnode(db, &node); 23496 if (result != ISC_R_SUCCESS) { 23497 goto failure; 23498 } 23499 23500 result = dns_db_findrdataset(db, node, newver, zone->privatetype, 23501 dns_rdatatype_none, 0, &rdataset, NULL); 23502 if (result == ISC_R_NOTFOUND) { 23503 INSIST(!dns_rdataset_isassociated(&rdataset)); 23504 goto failure; 23505 } 23506 if (result != ISC_R_SUCCESS) { 23507 INSIST(!dns_rdataset_isassociated(&rdataset)); 23508 goto failure; 23509 } 23510 23511 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 23512 result = dns_rdataset_next(&rdataset)) 23513 { 23514 bool found = false; 23515 23516 dns_rdataset_current(&rdataset, &rdata); 23517 23518 if (kd->all) { 23519 if (rdata.length == 5 && rdata.data[0] != 0 && 23520 rdata.data[3] == 0 && rdata.data[4] == 1) 23521 { 23522 found = true; 23523 } else if (rdata.data[0] == 0 && 23524 (rdata.data[2] & PENDINGFLAGS) != 0) 23525 { 23526 found = true; 23527 clear_pending = true; 23528 } 23529 } else if (rdata.length == 5 && 23530 memcmp(rdata.data, kd->data, 5) == 0) 23531 { 23532 found = true; 23533 } 23534 23535 if (found) { 23536 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL, 23537 &zone->origin, rdataset.ttl, 23538 &rdata)); 23539 } 23540 dns_rdata_reset(&rdata); 23541 } 23542 23543 if (!ISC_LIST_EMPTY(diff.tuples)) { 23544 /* Write changes to journal file. */ 23545 CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx, 23546 zone->updatemethod)); 23547 23548 result = dns_update_signatures(&log, zone, db, oldver, newver, 23549 &diff, 23550 zone->sigvalidityinterval); 23551 if (!clear_pending) { 23552 CHECK(result); 23553 } 23554 23555 CHECK(zone_journal(zone, &diff, NULL, "keydone")); 23556 commit = true; 23557 23558 LOCK_ZONE(zone); 23559 DNS_ZONE_SETFLAG(zone, 23560 DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY); 23561 zone_needdump(zone, 30); 23562 UNLOCK_ZONE(zone); 23563 } 23564 23565 failure: 23566 if (dns_rdataset_isassociated(&rdataset)) { 23567 dns_rdataset_disassociate(&rdataset); 23568 } 23569 if (db != NULL) { 23570 if (node != NULL) { 23571 dns_db_detachnode(db, &node); 23572 } 23573 if (oldver != NULL) { 23574 dns_db_closeversion(db, &oldver, false); 23575 } 23576 if (newver != NULL) { 23577 dns_db_closeversion(db, &newver, commit); 23578 } 23579 dns_db_detach(&db); 23580 } 23581 dns_diff_clear(&diff); 23582 isc_mem_put(zone->mctx, kd, sizeof(*kd)); 23583 dns_zone_idetach(&zone); 23584 23585 INSIST(oldver == NULL); 23586 INSIST(newver == NULL); 23587 } 23588 23589 isc_result_t 23590 dns_zone_keydone(dns_zone_t *zone, const char *keystr) { 23591 isc_result_t result = ISC_R_SUCCESS; 23592 struct keydone *kd = NULL; 23593 isc_buffer_t b; 23594 23595 REQUIRE(DNS_ZONE_VALID(zone)); 23596 23597 LOCK_ZONE(zone); 23598 23599 kd = isc_mem_get(zone->mctx, sizeof(*kd)); 23600 *kd = (struct keydone){ .all = false }; 23601 23602 if (strcasecmp(keystr, "all") == 0) { 23603 kd->all = true; 23604 } else { 23605 isc_textregion_t r; 23606 const char *algstr = NULL; 23607 dns_keytag_t keyid; 23608 dns_secalg_t alg; 23609 size_t n; 23610 23611 n = sscanf(keystr, "%hu/", &keyid); 23612 if (n == 0U) { 23613 CHECK(ISC_R_FAILURE); 23614 } 23615 23616 algstr = strchr(keystr, '/'); 23617 if (algstr != NULL) { 23618 algstr++; 23619 } else { 23620 CHECK(ISC_R_FAILURE); 23621 } 23622 23623 n = sscanf(algstr, "%hhu", &alg); 23624 if (n == 0U) { 23625 r.base = UNCONST(algstr); 23626 r.length = strlen(algstr); 23627 CHECK(dns_secalg_fromtext(&alg, &r)); 23628 } 23629 23630 /* construct a private-type rdata */ 23631 isc_buffer_init(&b, kd->data, sizeof(kd->data)); 23632 isc_buffer_putuint8(&b, alg); 23633 isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8); 23634 isc_buffer_putuint8(&b, (keyid & 0xff)); 23635 isc_buffer_putuint8(&b, 0); 23636 isc_buffer_putuint8(&b, 1); 23637 } 23638 23639 zone_iattach(zone, &kd->zone); 23640 isc_async_run(zone->loop, keydone, kd); 23641 kd = NULL; 23642 23643 failure: 23644 if (kd != NULL) { 23645 isc_mem_put(zone->mctx, kd, sizeof(*kd)); 23646 } 23647 UNLOCK_ZONE(zone); 23648 return result; 23649 } 23650 23651 /* 23652 * Called from the zone loop's queue after the relevant event is posted by 23653 * dns_zone_setnsec3param(). 23654 */ 23655 static void 23656 setnsec3param(void *arg) { 23657 struct np3 *npe = (struct np3 *)arg; 23658 dns_zone_t *zone = npe->zone; 23659 bool loadpending; 23660 23661 INSIST(DNS_ZONE_VALID(zone)); 23662 23663 ENTER; 23664 23665 LOCK_ZONE(zone); 23666 loadpending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING); 23667 UNLOCK_ZONE(zone); 23668 23669 /* 23670 * The receive_secure_serial() and setnsec3param() calls are 23671 * loop-serialized for the zone. Make sure there's no processing 23672 * currently running. 23673 */ 23674 INSIST(zone->rss_newver == NULL); 23675 23676 bool rescheduled = false; 23677 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 23678 /* 23679 * The zone is not yet fully loaded. Reschedule the event to 23680 * be picked up later. This turns this function into a busy 23681 * wait, but it only happens at startup. 23682 */ 23683 if (zone->db == NULL && loadpending) { 23684 rescheduled = true; 23685 isc_async_run(zone->loop, setnsec3param, npe); 23686 } 23687 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 23688 if (rescheduled) { 23689 return; 23690 } 23691 23692 rss_post(npe); 23693 23694 dns_zone_idetach(&zone); 23695 } 23696 23697 static void 23698 salt2text(unsigned char *salt, uint8_t saltlen, unsigned char *text, 23699 unsigned int textlen) { 23700 isc_region_t r; 23701 isc_buffer_t buf; 23702 isc_result_t result; 23703 23704 r.base = salt; 23705 r.length = (unsigned int)saltlen; 23706 23707 isc_buffer_init(&buf, text, textlen); 23708 result = isc_hex_totext(&r, 2, "", &buf); 23709 if (result == ISC_R_SUCCESS) { 23710 text[saltlen * 2] = 0; 23711 } else { 23712 text[0] = 0; 23713 } 23714 } 23715 23716 /* 23717 * Check whether NSEC3 chain addition or removal specified by the private-type 23718 * record passed with the event was already queued (or even fully performed). 23719 * If not, modify the relevant private-type records at the zone apex and call 23720 * resume_addnsec3chain(). 23721 */ 23722 static void 23723 rss_post(void *arg) { 23724 struct np3 *npe = (struct np3 *)arg; 23725 dns_zone_t *zone = npe->zone; 23726 nsec3param_t *np = &npe->params; 23727 bool commit = false; 23728 isc_result_t result; 23729 dns_dbversion_t *oldver = NULL, *newver = NULL; 23730 dns_db_t *db = NULL; 23731 dns_dbnode_t *node = NULL; 23732 dns_rdataset_t prdataset, nrdataset; 23733 dns_diff_t diff; 23734 dns_update_log_t log = { update_log_cb, NULL }; 23735 dns_rdata_t rdata; 23736 bool nseconly; 23737 bool exists = false; 23738 23739 ENTER; 23740 23741 dns_rdataset_init(&prdataset); 23742 dns_rdataset_init(&nrdataset); 23743 dns_diff_init(zone->mctx, &diff); 23744 23745 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 23746 if (zone->db != NULL) { 23747 dns_db_attach(zone->db, &db); 23748 } 23749 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 23750 if (db == NULL) { 23751 goto failure; 23752 } 23753 23754 dns_db_currentversion(db, &oldver); 23755 result = dns_db_newversion(db, &newver); 23756 if (result != ISC_R_SUCCESS) { 23757 dnssec_log(zone, ISC_LOG_ERROR, 23758 "setnsec3param:dns_db_newversion -> %s", 23759 isc_result_totext(result)); 23760 goto failure; 23761 } 23762 23763 CHECK(dns_db_getoriginnode(db, &node)); 23764 23765 /* 23766 * Do we need to look up the NSEC3 parameters? 23767 */ 23768 if (np->lookup) { 23769 dns_rdata_nsec3param_t param; 23770 dns_rdata_t nrdata = DNS_RDATA_INIT; 23771 dns_rdata_t prdata = DNS_RDATA_INIT; 23772 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE]; 23773 unsigned char saltbuf[255]; 23774 isc_buffer_t b; 23775 23776 param.salt = NULL; 23777 result = dns__zone_lookup_nsec3param(zone, &np->rdata, ¶m, 23778 saltbuf, np->resalt); 23779 if (result == ISC_R_SUCCESS) { 23780 /* 23781 * Success because the NSEC3PARAM already exists, but 23782 * function returns void, so goto failure to clean up. 23783 */ 23784 goto failure; 23785 } 23786 if (result != DNS_R_NSEC3RESALT && result != ISC_R_NOTFOUND) { 23787 dnssec_log(zone, ISC_LOG_DEBUG(3), 23788 "setnsec3param:lookup nsec3param -> %s", 23789 isc_result_totext(result)); 23790 goto failure; 23791 } 23792 23793 INSIST(param.salt != NULL); 23794 23795 /* Update NSEC3 parameters. */ 23796 np->rdata.hash = param.hash; 23797 np->rdata.flags = param.flags; 23798 np->rdata.iterations = param.iterations; 23799 np->rdata.salt_length = param.salt_length; 23800 np->rdata.salt = param.salt; 23801 23802 isc_buffer_init(&b, nbuf, sizeof(nbuf)); 23803 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass, 23804 dns_rdatatype_nsec3param, &np->rdata, 23805 &b)); 23806 dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype, 23807 np->data, sizeof(np->data)); 23808 np->length = prdata.length; 23809 np->nsec = false; 23810 } 23811 23812 /* 23813 * Does a private-type record already exist for this chain? 23814 */ 23815 result = dns_db_findrdataset(db, node, newver, zone->privatetype, 23816 dns_rdatatype_none, 0, &prdataset, NULL); 23817 if (result == ISC_R_SUCCESS) { 23818 for (result = dns_rdataset_first(&prdataset); 23819 result == ISC_R_SUCCESS; 23820 result = dns_rdataset_next(&prdataset)) 23821 { 23822 dns_rdata_init(&rdata); 23823 dns_rdataset_current(&prdataset, &rdata); 23824 23825 if (np->length == rdata.length && 23826 memcmp(rdata.data, np->data, np->length) == 0) 23827 { 23828 exists = true; 23829 break; 23830 } 23831 } 23832 } else if (result != ISC_R_NOTFOUND) { 23833 INSIST(!dns_rdataset_isassociated(&prdataset)); 23834 goto failure; 23835 } 23836 23837 /* 23838 * Does the chain already exist? 23839 */ 23840 result = dns_db_findrdataset(db, node, newver, dns_rdatatype_nsec3param, 23841 dns_rdatatype_none, 0, &nrdataset, NULL); 23842 if (result == ISC_R_SUCCESS) { 23843 for (result = dns_rdataset_first(&nrdataset); 23844 result == ISC_R_SUCCESS; 23845 result = dns_rdataset_next(&nrdataset)) 23846 { 23847 dns_rdata_init(&rdata); 23848 dns_rdataset_current(&nrdataset, &rdata); 23849 23850 if (np->length == (rdata.length + 1) && 23851 memcmp(rdata.data, np->data + 1, np->length - 1) == 23852 0) 23853 { 23854 exists = true; 23855 break; 23856 } 23857 } 23858 } else if (result != ISC_R_NOTFOUND) { 23859 INSIST(!dns_rdataset_isassociated(&nrdataset)); 23860 goto failure; 23861 } 23862 23863 /* 23864 * We need to remove any existing NSEC3 chains if the supplied NSEC3 23865 * parameters are supposed to replace the current ones or if we are 23866 * switching to NSEC. 23867 */ 23868 if (!exists && np->replace && (np->length != 0 || np->nsec)) { 23869 CHECK(dns_nsec3param_deletechains(db, newver, zone, !np->nsec, 23870 &diff)); 23871 } 23872 23873 if (!exists && np->length != 0) { 23874 /* 23875 * We're creating an NSEC3 chain. Add the private-type record 23876 * passed in the event handler's argument to the zone apex. 23877 * 23878 * If the zone is not currently capable of supporting an NSEC3 23879 * chain (due to the DNSKEY RRset at the zone apex not existing 23880 * or containing at least one key using an NSEC-only 23881 * algorithm), add the INITIAL flag, so these parameters can be 23882 * used later when NSEC3 becomes available. 23883 */ 23884 dns_rdata_init(&rdata); 23885 23886 np->data[2] |= DNS_NSEC3FLAG_CREATE; 23887 result = dns_nsec_nseconly(db, newver, NULL, &nseconly); 23888 if (result == ISC_R_NOTFOUND || nseconly) { 23889 np->data[2] |= DNS_NSEC3FLAG_INITIAL; 23890 } 23891 23892 rdata.length = np->length; 23893 rdata.data = np->data; 23894 rdata.type = zone->privatetype; 23895 rdata.rdclass = zone->rdclass; 23896 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD, 23897 &zone->origin, 0, &rdata)); 23898 } 23899 23900 /* 23901 * If we changed anything in the zone, write changes to journal file 23902 * and set commit to true so that resume_addnsec3chain() will be 23903 * called below in order to kick off adding/removing relevant NSEC3 23904 * records. 23905 */ 23906 if (!ISC_LIST_EMPTY(diff.tuples)) { 23907 CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx, 23908 zone->updatemethod)); 23909 result = dns_update_signatures(&log, zone, db, oldver, newver, 23910 &diff, 23911 zone->sigvalidityinterval); 23912 if (result != ISC_R_NOTFOUND) { 23913 CHECK(result); 23914 } 23915 CHECK(zone_journal(zone, &diff, NULL, "setnsec3param")); 23916 commit = true; 23917 23918 LOCK_ZONE(zone); 23919 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 23920 zone_needdump(zone, 30); 23921 UNLOCK_ZONE(zone); 23922 } 23923 23924 failure: 23925 if (dns_rdataset_isassociated(&prdataset)) { 23926 dns_rdataset_disassociate(&prdataset); 23927 } 23928 if (dns_rdataset_isassociated(&nrdataset)) { 23929 dns_rdataset_disassociate(&nrdataset); 23930 } 23931 if (node != NULL) { 23932 dns_db_detachnode(db, &node); 23933 } 23934 if (oldver != NULL) { 23935 dns_db_closeversion(db, &oldver, false); 23936 } 23937 if (newver != NULL) { 23938 dns_db_closeversion(db, &newver, commit); 23939 } 23940 if (db != NULL) { 23941 dns_db_detach(&db); 23942 } 23943 if (commit) { 23944 LOCK_ZONE(zone); 23945 resume_addnsec3chain(zone); 23946 UNLOCK_ZONE(zone); 23947 } 23948 dns_diff_clear(&diff); 23949 isc_mem_put(zone->mctx, npe, sizeof(*npe)); 23950 23951 INSIST(oldver == NULL); 23952 INSIST(newver == NULL); 23953 } 23954 23955 /* 23956 * Check if zone has NSEC3PARAM (and thus a chain) with the right parameters. 23957 * 23958 * If 'salt' is NULL, a match is found if the salt has the requested length, 23959 * otherwise the NSEC3 salt must match the requested salt value too. 23960 * 23961 * Returns ISC_R_SUCCESS, if a match is found, or an error if no match is 23962 * found, or if the db lookup failed. 23963 */ 23964 isc_result_t 23965 dns__zone_lookup_nsec3param(dns_zone_t *zone, dns_rdata_nsec3param_t *lookup, 23966 dns_rdata_nsec3param_t *param, 23967 unsigned char saltbuf[255], bool resalt) { 23968 isc_result_t result = ISC_R_UNEXPECTED; 23969 dns_dbnode_t *node = NULL; 23970 dns_db_t *db = NULL; 23971 dns_dbversion_t *version = NULL; 23972 dns_rdataset_t rdataset; 23973 dns_rdata_nsec3param_t nsec3param; 23974 dns_rdata_t rdata = DNS_RDATA_INIT; 23975 23976 REQUIRE(DNS_ZONE_VALID(zone)); 23977 23978 dns_rdataset_init(&rdataset); 23979 23980 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 23981 if (zone->db != NULL) { 23982 dns_db_attach(zone->db, &db); 23983 } 23984 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 23985 if (db == NULL) { 23986 result = ISC_R_FAILURE; 23987 goto setparam; 23988 } 23989 23990 result = dns_db_findnode(db, &zone->origin, false, &node); 23991 if (result != ISC_R_SUCCESS) { 23992 dns_zone_log(zone, ISC_LOG_ERROR, 23993 "dns__zone_lookup_nsec3param:" 23994 "dns_db_findnode -> %s", 23995 isc_result_totext(result)); 23996 result = ISC_R_FAILURE; 23997 goto setparam; 23998 } 23999 dns_db_currentversion(db, &version); 24000 24001 result = dns_db_findrdataset(db, node, version, 24002 dns_rdatatype_nsec3param, 24003 dns_rdatatype_none, 0, &rdataset, NULL); 24004 if (result != ISC_R_SUCCESS) { 24005 INSIST(!dns_rdataset_isassociated(&rdataset)); 24006 if (result != ISC_R_NOTFOUND) { 24007 dns_zone_log(zone, ISC_LOG_ERROR, 24008 "dns__zone_lookup_nsec3param:" 24009 "dns_db_findrdataset -> %s", 24010 isc_result_totext(result)); 24011 } 24012 goto setparam; 24013 } 24014 24015 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 24016 result = dns_rdataset_next(&rdataset)) 24017 { 24018 dns_rdataset_current(&rdataset, &rdata); 24019 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 24020 INSIST(result == ISC_R_SUCCESS); 24021 dns_rdata_reset(&rdata); 24022 24023 /* Check parameters. */ 24024 if (nsec3param.hash != lookup->hash) { 24025 continue; 24026 } 24027 if (nsec3param.iterations != lookup->iterations) { 24028 continue; 24029 } 24030 if (nsec3param.salt_length != lookup->salt_length) { 24031 continue; 24032 } 24033 if (lookup->salt != NULL) { 24034 if (memcmp(nsec3param.salt, lookup->salt, 24035 lookup->salt_length) != 0) 24036 { 24037 continue; 24038 } 24039 } 24040 /* Found a match. */ 24041 result = ISC_R_SUCCESS; 24042 param->hash = nsec3param.hash; 24043 param->flags = nsec3param.flags; 24044 param->iterations = nsec3param.iterations; 24045 param->salt_length = nsec3param.salt_length; 24046 param->salt = nsec3param.salt; 24047 break; 24048 } 24049 24050 if (result == ISC_R_NOMORE) { 24051 result = ISC_R_NOTFOUND; 24052 } 24053 24054 setparam: 24055 if (result != ISC_R_SUCCESS) { 24056 /* Found no match. */ 24057 param->hash = lookup->hash; 24058 param->flags = lookup->flags; 24059 param->iterations = lookup->iterations; 24060 param->salt_length = lookup->salt_length; 24061 param->salt = lookup->salt; 24062 } 24063 24064 if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) { 24065 goto failure; 24066 } 24067 24068 if (param->salt_length == 0) { 24069 param->salt = (unsigned char *)"-"; 24070 } else if (resalt || param->salt == NULL) { 24071 unsigned char *newsalt; 24072 unsigned char salttext[255 * 2 + 1]; 24073 do { 24074 /* Generate a new salt. */ 24075 result = dns_nsec3_generate_salt(saltbuf, 24076 param->salt_length); 24077 if (result != ISC_R_SUCCESS) { 24078 break; 24079 } 24080 newsalt = saltbuf; 24081 salt2text(newsalt, param->salt_length, salttext, 24082 sizeof(salttext)); 24083 dnssec_log(zone, ISC_LOG_INFO, "generated salt: %s", 24084 salttext); 24085 /* Check for salt conflict. */ 24086 if (param->salt != NULL && 24087 memcmp(newsalt, param->salt, param->salt_length) == 24088 0) 24089 { 24090 result = ISC_R_SUCCESS; 24091 } else { 24092 param->salt = newsalt; 24093 result = DNS_R_NSEC3RESALT; 24094 } 24095 } while (result == ISC_R_SUCCESS); 24096 24097 INSIST(result != ISC_R_SUCCESS); 24098 } 24099 24100 failure: 24101 if (dns_rdataset_isassociated(&rdataset)) { 24102 dns_rdataset_disassociate(&rdataset); 24103 } 24104 if (node != NULL) { 24105 dns_db_detachnode(db, &node); 24106 } 24107 if (version != NULL) { 24108 dns_db_closeversion(db, &version, false); 24109 } 24110 if (db != NULL) { 24111 dns_db_detach(&db); 24112 } 24113 24114 return result; 24115 } 24116 24117 /* 24118 * Called when an "rndc signing -nsec3param ..." command is received, or the 24119 * 'dnssec-policy' has changed. 24120 * 24121 * Allocate and prepare an nsec3param_t structure which holds information about 24122 * the NSEC3 changes requested for the zone: 24123 * 24124 * - if NSEC3 is to be disabled ("-nsec3param none"), only set the "nsec" 24125 * field of the structure to true and the "replace" field to the value 24126 * of the "replace" argument, leaving other fields initialized to zeros, to 24127 * signal that the zone should be signed using NSEC instead of NSEC3, 24128 * 24129 * - otherwise, prepare NSEC3PARAM RDATA that will eventually be inserted at 24130 * the zone apex, convert it to a private-type record and store the latter 24131 * in the "data" field of the nsec3param_t structure. 24132 * 24133 * Once the nsec3param_t structure is prepared, post an event to the zone's 24134 * loop which will cause setnsec3param() to be called with the prepared 24135 * structure passed as an argument. 24136 */ 24137 isc_result_t 24138 dns_zone_setnsec3param(dns_zone_t *zone, uint8_t hash, uint8_t flags, 24139 uint16_t iter, uint8_t saltlen, unsigned char *salt, 24140 bool replace, bool resalt) { 24141 isc_result_t result = ISC_R_SUCCESS; 24142 dns_rdata_nsec3param_t param, lookup; 24143 dns_rdata_t nrdata = DNS_RDATA_INIT; 24144 dns_rdata_t prdata = DNS_RDATA_INIT; 24145 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE]; 24146 unsigned char saltbuf[255]; 24147 struct np3 *npe = NULL; 24148 nsec3param_t *np = NULL; 24149 isc_buffer_t b; 24150 bool do_lookup = false; 24151 24152 REQUIRE(DNS_ZONE_VALID(zone)); 24153 24154 LOCK_ZONE(zone); 24155 24156 /* 24157 * First check if the requested NSEC3 parameters are already 24158 * set, if so, no need to set again. 24159 */ 24160 if (hash != 0) { 24161 lookup.hash = hash; 24162 lookup.flags = flags; 24163 lookup.iterations = iter; 24164 lookup.salt_length = saltlen; 24165 lookup.salt = salt; 24166 param.salt = NULL; 24167 result = dns__zone_lookup_nsec3param(zone, &lookup, ¶m, 24168 saltbuf, resalt); 24169 if (result == ISC_R_SUCCESS) { 24170 UNLOCK_ZONE(zone); 24171 return ISC_R_SUCCESS; 24172 } 24173 /* 24174 * Schedule lookup if lookup above failed (may happen if 24175 * zone db is NULL for example). 24176 */ 24177 do_lookup = (param.salt == NULL) ? true : false; 24178 } 24179 24180 npe = isc_mem_get(zone->mctx, sizeof(*npe)); 24181 *npe = (struct np3){ 24182 .link = ISC_LINK_INITIALIZER, 24183 }; 24184 24185 np = &npe->params; 24186 *np = (struct nsec3param){ 24187 .replace = replace, 24188 .resalt = resalt, 24189 .lookup = do_lookup, 24190 }; 24191 24192 if (hash == 0) { 24193 np->nsec = true; 24194 dnssec_log(zone, ISC_LOG_DEBUG(3), "setnsec3param:nsec"); 24195 } else { 24196 param.common.rdclass = zone->rdclass; 24197 param.common.rdtype = dns_rdatatype_nsec3param; 24198 ISC_LINK_INIT(¶m.common, link); 24199 param.mctx = NULL; 24200 /* 24201 * nsec3 specific param set in 24202 * dns__zone_lookup_nsec3param() 24203 */ 24204 isc_buffer_init(&b, nbuf, sizeof(nbuf)); 24205 24206 if (param.salt != NULL) { 24207 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass, 24208 dns_rdatatype_nsec3param, 24209 ¶m, &b)); 24210 dns_nsec3param_toprivate(&nrdata, &prdata, 24211 zone->privatetype, np->data, 24212 sizeof(np->data)); 24213 np->length = prdata.length; 24214 } 24215 24216 np->rdata = param; 24217 24218 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 24219 unsigned char salttext[255 * 2 + 1]; 24220 if (param.salt != NULL) { 24221 salt2text(param.salt, param.salt_length, 24222 salttext, sizeof(salttext)); 24223 } 24224 dnssec_log(zone, ISC_LOG_DEBUG(3), 24225 "setnsec3param:nsec3 %u %u %u %u:%s", 24226 param.hash, param.flags, param.iterations, 24227 param.salt_length, 24228 param.salt == NULL ? "unknown" 24229 : (char *)salttext); 24230 } 24231 } 24232 24233 /* 24234 * setnsec3param() will silently return early if the zone does 24235 * not yet have a database. Prevent that by queueing the event 24236 * up if zone->db is NULL. All events queued here are 24237 * subsequently processed by receive_secure_db() if it ever gets 24238 * called or simply freed by zone_free() otherwise. 24239 */ 24240 24241 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 24242 if (zone->db != NULL) { 24243 zone_iattach(zone, &npe->zone); 24244 isc_async_run(zone->loop, setnsec3param, npe); 24245 } else { 24246 ISC_LIST_APPEND(zone->setnsec3param_queue, npe, link); 24247 } 24248 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 24249 24250 result = ISC_R_SUCCESS; 24251 24252 failure: 24253 UNLOCK_ZONE(zone); 24254 return result; 24255 } 24256 24257 isc_result_t 24258 dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) { 24259 REQUIRE(DNS_ZONE_VALID(zone)); 24260 REQUIRE(loadtime != NULL); 24261 24262 LOCK_ZONE(zone); 24263 *loadtime = zone->loadtime; 24264 UNLOCK_ZONE(zone); 24265 return ISC_R_SUCCESS; 24266 } 24267 24268 isc_result_t 24269 dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) { 24270 REQUIRE(DNS_ZONE_VALID(zone)); 24271 REQUIRE(expiretime != NULL); 24272 24273 LOCK_ZONE(zone); 24274 *expiretime = zone->expiretime; 24275 UNLOCK_ZONE(zone); 24276 return ISC_R_SUCCESS; 24277 } 24278 24279 isc_result_t 24280 dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) { 24281 REQUIRE(DNS_ZONE_VALID(zone)); 24282 REQUIRE(refreshtime != NULL); 24283 24284 LOCK_ZONE(zone); 24285 *refreshtime = zone->refreshtime; 24286 UNLOCK_ZONE(zone); 24287 return ISC_R_SUCCESS; 24288 } 24289 24290 isc_result_t 24291 dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) { 24292 REQUIRE(DNS_ZONE_VALID(zone)); 24293 REQUIRE(refreshkeytime != NULL); 24294 24295 LOCK_ZONE(zone); 24296 *refreshkeytime = zone->refreshkeytime; 24297 UNLOCK_ZONE(zone); 24298 return ISC_R_SUCCESS; 24299 } 24300 24301 unsigned int 24302 dns_zone_getincludes(dns_zone_t *zone, char ***includesp) { 24303 dns_include_t *include; 24304 char **array = NULL; 24305 unsigned int n = 0; 24306 24307 REQUIRE(DNS_ZONE_VALID(zone)); 24308 REQUIRE(includesp != NULL && *includesp == NULL); 24309 24310 LOCK_ZONE(zone); 24311 if (zone->nincludes == 0) { 24312 goto done; 24313 } 24314 24315 array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes); 24316 for (include = ISC_LIST_HEAD(zone->includes); include != NULL; 24317 include = ISC_LIST_NEXT(include, link)) 24318 { 24319 INSIST(n < zone->nincludes); 24320 array[n++] = isc_mem_strdup(zone->mctx, include->name); 24321 } 24322 INSIST(n == zone->nincludes); 24323 *includesp = array; 24324 24325 done: 24326 UNLOCK_ZONE(zone); 24327 return n; 24328 } 24329 24330 void 24331 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) { 24332 REQUIRE(DNS_ZONE_VALID(zone)); 24333 24334 zone->statlevel = level; 24335 } 24336 24337 dns_zonestat_level_t 24338 dns_zone_getstatlevel(dns_zone_t *zone) { 24339 REQUIRE(DNS_ZONE_VALID(zone)); 24340 24341 return zone->statlevel; 24342 } 24343 24344 static void 24345 setserial(void *arg) { 24346 uint32_t oldserial, desired; 24347 bool commit = false; 24348 isc_result_t result; 24349 dns_dbversion_t *oldver = NULL, *newver = NULL; 24350 dns_db_t *db = NULL; 24351 dns_diff_t diff; 24352 struct setserial *sse = (struct setserial *)arg; 24353 dns_zone_t *zone = sse->zone; 24354 dns_update_log_t log = { update_log_cb, NULL }; 24355 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL; 24356 24357 INSIST(DNS_ZONE_VALID(zone)); 24358 24359 ENTER; 24360 24361 if (zone->update_disabled) { 24362 goto disabled; 24363 } 24364 24365 desired = sse->serial; 24366 24367 dns_diff_init(zone->mctx, &diff); 24368 24369 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 24370 if (zone->db != NULL) { 24371 dns_db_attach(zone->db, &db); 24372 } 24373 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 24374 if (db == NULL) { 24375 goto failure; 24376 } 24377 24378 dns_db_currentversion(db, &oldver); 24379 result = dns_db_newversion(db, &newver); 24380 if (result != ISC_R_SUCCESS) { 24381 dns_zone_log(zone, ISC_LOG_ERROR, 24382 "setserial:dns_db_newversion -> %s", 24383 isc_result_totext(result)); 24384 goto failure; 24385 } 24386 24387 CHECK(dns_db_createsoatuple(db, oldver, diff.mctx, DNS_DIFFOP_DEL, 24388 &oldtuple)); 24389 CHECK(dns_difftuple_copy(oldtuple, &newtuple)); 24390 newtuple->op = DNS_DIFFOP_ADD; 24391 24392 oldserial = dns_soa_getserial(&oldtuple->rdata); 24393 if (desired == 0U) { 24394 desired = 1; 24395 } 24396 if (!isc_serial_gt(desired, oldserial)) { 24397 if (desired != oldserial) { 24398 dns_zone_log(zone, ISC_LOG_INFO, 24399 "setserial: desired serial (%u) " 24400 "out of range (%u-%u)", 24401 desired, oldserial + 1, 24402 (oldserial + 0x7fffffff)); 24403 } 24404 goto failure; 24405 } 24406 24407 dns_soa_setserial(desired, &newtuple->rdata); 24408 CHECK(do_one_tuple(&oldtuple, db, newver, &diff)); 24409 CHECK(do_one_tuple(&newtuple, db, newver, &diff)); 24410 result = dns_update_signatures(&log, zone, db, oldver, newver, &diff, 24411 zone->sigvalidityinterval); 24412 if (result != ISC_R_NOTFOUND) { 24413 CHECK(result); 24414 } 24415 24416 /* Write changes to journal file. */ 24417 CHECK(zone_journal(zone, &diff, NULL, "setserial")); 24418 commit = true; 24419 24420 LOCK_ZONE(zone); 24421 zone_needdump(zone, 30); 24422 UNLOCK_ZONE(zone); 24423 24424 failure: 24425 if (oldtuple != NULL) { 24426 dns_difftuple_free(&oldtuple); 24427 } 24428 if (newtuple != NULL) { 24429 dns_difftuple_free(&newtuple); 24430 } 24431 if (oldver != NULL) { 24432 dns_db_closeversion(db, &oldver, false); 24433 } 24434 if (newver != NULL) { 24435 dns_db_closeversion(db, &newver, commit); 24436 } 24437 if (db != NULL) { 24438 dns_db_detach(&db); 24439 } 24440 dns_diff_clear(&diff); 24441 24442 disabled: 24443 isc_mem_put(zone->mctx, sse, sizeof(*sse)); 24444 dns_zone_idetach(&zone); 24445 24446 INSIST(oldver == NULL); 24447 INSIST(newver == NULL); 24448 } 24449 24450 isc_result_t 24451 dns_zone_setserial(dns_zone_t *zone, uint32_t serial) { 24452 isc_result_t result = ISC_R_SUCCESS; 24453 struct setserial *sse = NULL; 24454 24455 REQUIRE(DNS_ZONE_VALID(zone)); 24456 24457 LOCK_ZONE(zone); 24458 24459 if (!inline_secure(zone)) { 24460 if (!dns_zone_isdynamic(zone, true)) { 24461 result = DNS_R_NOTDYNAMIC; 24462 goto failure; 24463 } 24464 } 24465 24466 if (zone->update_disabled) { 24467 result = DNS_R_FROZEN; 24468 goto failure; 24469 } 24470 24471 sse = isc_mem_get(zone->mctx, sizeof(*sse)); 24472 *sse = (struct setserial){ .serial = serial }; 24473 zone_iattach(zone, &sse->zone); 24474 isc_async_run(zone->loop, setserial, sse); 24475 24476 failure: 24477 UNLOCK_ZONE(zone); 24478 return result; 24479 } 24480 24481 isc_stats_t * 24482 dns_zone_getgluecachestats(dns_zone_t *zone) { 24483 REQUIRE(DNS_ZONE_VALID(zone)); 24484 24485 return zone->gluecachestats; 24486 } 24487 24488 bool 24489 dns_zone_isloaded(dns_zone_t *zone) { 24490 REQUIRE(DNS_ZONE_VALID(zone)); 24491 24492 return DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED); 24493 } 24494 24495 isc_result_t 24496 dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver) { 24497 dns_dbversion_t *version = NULL; 24498 dns_keytable_t *secroots = NULL; 24499 isc_result_t result; 24500 dns_name_t *origin; 24501 24502 REQUIRE(DNS_ZONE_VALID(zone)); 24503 REQUIRE(db != NULL); 24504 24505 ENTER; 24506 24507 if (dns_zone_gettype(zone) != dns_zone_mirror) { 24508 return ISC_R_SUCCESS; 24509 } 24510 24511 if (ver == NULL) { 24512 dns_db_currentversion(db, &version); 24513 } else { 24514 version = ver; 24515 } 24516 24517 if (zone->view != NULL) { 24518 result = dns_view_getsecroots(zone->view, &secroots); 24519 if (result != ISC_R_SUCCESS) { 24520 goto done; 24521 } 24522 } 24523 24524 origin = dns_db_origin(db); 24525 result = dns_zoneverify_dnssec(zone, db, version, origin, secroots, 24526 zone->mctx, true, false, dnssec_report); 24527 24528 done: 24529 if (secroots != NULL) { 24530 dns_keytable_detach(&secroots); 24531 } 24532 24533 if (ver == NULL) { 24534 dns_db_closeversion(db, &version, false); 24535 } 24536 24537 if (result != ISC_R_SUCCESS) { 24538 dnssec_log(zone, ISC_LOG_ERROR, "zone verification failed: %s", 24539 isc_result_totext(result)); 24540 result = DNS_R_VERIFYFAILURE; 24541 } 24542 24543 return result; 24544 } 24545 24546 static dns_ttl_t 24547 zone_nsecttl(dns_zone_t *zone) { 24548 REQUIRE(DNS_ZONE_VALID(zone)); 24549 24550 return ISC_MIN(zone->minimum, zone->soattl); 24551 } 24552 24553 void 24554 dns_zonemgr_set_tlsctx_cache(dns_zonemgr_t *zmgr, 24555 isc_tlsctx_cache_t *tlsctx_cache) { 24556 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 24557 REQUIRE(tlsctx_cache != NULL); 24558 24559 RWLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_write); 24560 24561 if (zmgr->tlsctx_cache != NULL) { 24562 isc_tlsctx_cache_detach(&zmgr->tlsctx_cache); 24563 } 24564 24565 isc_tlsctx_cache_attach(tlsctx_cache, &zmgr->tlsctx_cache); 24566 24567 RWUNLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_write); 24568 } 24569 24570 static void 24571 zmgr_tlsctx_attach(dns_zonemgr_t *zmgr, isc_tlsctx_cache_t **ptlsctx_cache) { 24572 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 24573 REQUIRE(ptlsctx_cache != NULL && *ptlsctx_cache == NULL); 24574 24575 RWLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_read); 24576 24577 INSIST(zmgr->tlsctx_cache != NULL); 24578 isc_tlsctx_cache_attach(zmgr->tlsctx_cache, ptlsctx_cache); 24579 24580 RWUNLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_read); 24581 } 24582 24583 isc_mem_t * 24584 dns_zone_getmem(dns_zone_t *zone) { 24585 return zone->mctx; 24586 } 24587 24588 unsigned int 24589 dns_zone_gettid(dns_zone_t *zone) { 24590 return zone->tid; 24591 } 24592 24593 isc_loop_t * 24594 dns_zone_getloop(dns_zone_t *zone) { 24595 return zone->loop; 24596 } 24597 24598 isc_result_t 24599 dns_zone_makedb(dns_zone_t *zone, dns_db_t **dbp) { 24600 REQUIRE(DNS_ZONE_VALID(zone)); 24601 REQUIRE(dbp != NULL && *dbp == NULL); 24602 24603 dns_db_t *db = NULL; 24604 24605 isc_result_t result = dns_db_create( 24606 zone->mctx, zone->db_argv[0], &zone->origin, 24607 (zone->type == dns_zone_stub) ? dns_dbtype_stub 24608 : dns_dbtype_zone, 24609 zone->rdclass, zone->db_argc - 1, zone->db_argv + 1, &db); 24610 if (result != ISC_R_SUCCESS) { 24611 return result; 24612 } 24613 24614 switch (zone->type) { 24615 case dns_zone_primary: 24616 case dns_zone_secondary: 24617 case dns_zone_mirror: 24618 result = dns_db_setgluecachestats(db, zone->gluecachestats); 24619 if (result == ISC_R_NOTIMPLEMENTED) { 24620 result = ISC_R_SUCCESS; 24621 } 24622 if (result != ISC_R_SUCCESS) { 24623 dns_db_detach(&db); 24624 return result; 24625 } 24626 break; 24627 default: 24628 break; 24629 } 24630 24631 dns_db_setloop(db, zone->loop); 24632 dns_db_setmaxrrperset(db, zone->maxrrperset); 24633 dns_db_setmaxtypepername(db, zone->maxtypepername); 24634 24635 *dbp = db; 24636 24637 return ISC_R_SUCCESS; 24638 } 24639 24640 isc_result_t 24641 dns_zone_import_skr(dns_zone_t *zone, const char *file) { 24642 dns_skr_t *skr = NULL; 24643 isc_result_t result; 24644 24645 REQUIRE(DNS_ZONE_VALID(zone)); 24646 REQUIRE(zone->kasp != NULL); 24647 REQUIRE(file != NULL); 24648 24649 dns_skr_create(zone->mctx, file, &zone->origin, zone->rdclass, &skr); 24650 24651 CHECK(dns_skr_read(zone->mctx, file, &zone->origin, zone->rdclass, 24652 dns_kasp_dnskeyttl(zone->kasp), &skr)); 24653 24654 dns_zone_setskr(zone, skr); 24655 dnssec_log(zone, ISC_LOG_DEBUG(1), "imported skr file %s", file); 24656 24657 failure: 24658 dns_skr_detach(&skr); 24659 24660 return result; 24661 } 24662