1 /* $NetBSD: zone.c,v 1.27 2026/04/08 00:16:14 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/list.h> 29 #include <isc/loop.h> 30 #include <isc/md.h> 31 #include <isc/mutex.h> 32 #include <isc/overflow.h> 33 #include <isc/random.h> 34 #include <isc/ratelimiter.h> 35 #include <isc/refcount.h> 36 #include <isc/result.h> 37 #include <isc/rwlock.h> 38 #include <isc/serial.h> 39 #include <isc/stats.h> 40 #include <isc/stdtime.h> 41 #include <isc/strerr.h> 42 #include <isc/string.h> 43 #include <isc/thread.h> 44 #include <isc/tid.h> 45 #include <isc/timer.h> 46 #include <isc/tls.h> 47 #include <isc/util.h> 48 49 #include <dns/acl.h> 50 #include <dns/adb.h> 51 #include <dns/callbacks.h> 52 #include <dns/catz.h> 53 #include <dns/db.h> 54 #include <dns/dbiterator.h> 55 #include <dns/dlz.h> 56 #include <dns/dnssec.h> 57 #include <dns/journal.h> 58 #include <dns/kasp.h> 59 #include <dns/keydata.h> 60 #include <dns/keymgr.h> 61 #include <dns/keytable.h> 62 #include <dns/keyvalues.h> 63 #include <dns/log.h> 64 #include <dns/master.h> 65 #include <dns/masterdump.h> 66 #include <dns/message.h> 67 #include <dns/name.h> 68 #include <dns/nsec.h> 69 #include <dns/nsec3.h> 70 #include <dns/opcode.h> 71 #include <dns/peer.h> 72 #include <dns/private.h> 73 #include <dns/rcode.h> 74 #include <dns/rdata.h> 75 #include <dns/rdataclass.h> 76 #include <dns/rdatalist.h> 77 #include <dns/rdataset.h> 78 #include <dns/rdatasetiter.h> 79 #include <dns/rdatastruct.h> 80 #include <dns/rdatatype.h> 81 #include <dns/remote.h> 82 #include <dns/request.h> 83 #include <dns/resolver.h> 84 #include <dns/rriterator.h> 85 #include <dns/skr.h> 86 #include <dns/soa.h> 87 #include <dns/ssu.h> 88 #include <dns/stats.h> 89 #include <dns/time.h> 90 #include <dns/tsig.h> 91 #include <dns/ttl.h> 92 #include <dns/update.h> 93 #include <dns/xfrin.h> 94 #include <dns/zone.h> 95 #include <dns/zoneverify.h> 96 #include <dns/zt.h> 97 98 #include <dst/dst.h> 99 100 #include "zone_p.h" 101 102 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E') 103 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC) 104 105 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y') 106 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC) 107 108 #define CHECKDS_MAGIC ISC_MAGIC('C', 'h', 'D', 'S') 109 #define DNS_CHECKDS_VALID(checkds) ISC_MAGIC_VALID(checkds, CHECKDS_MAGIC) 110 111 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b') 112 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC) 113 114 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r') 115 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC) 116 117 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w') 118 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC) 119 120 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O') 121 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC) 122 123 #define KEYMGMT_MAGIC ISC_MAGIC('M', 'g', 'm', 't') 124 #define DNS_KEYMGMT_VALID(load) ISC_MAGIC_VALID(load, KEYMGMT_MAGIC) 125 126 #define KEYFILEIO_MAGIC ISC_MAGIC('K', 'y', 'I', 'O') 127 #define DNS_KEYFILEIO_VALID(kfio) ISC_MAGIC_VALID(kfio, KEYFILEIO_MAGIC) 128 129 /*% 130 * Ensure 'a' is at least 'min' but not more than 'max'. 131 */ 132 #define RANGE(a, min, max) (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max))) 133 134 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) 135 136 /*% 137 * Key flags 138 */ 139 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0) 140 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0) 141 #define ID(x) dst_key_id(x) 142 #define ALG(x) dst_key_alg(x) 143 144 /*% 145 * KASP flags 146 */ 147 #define KASP_LOCK(k) \ 148 if ((k) != NULL) { \ 149 LOCK(&((k)->lock)); \ 150 } 151 152 #define KASP_UNLOCK(k) \ 153 if ((k) != NULL) { \ 154 UNLOCK(&((k)->lock)); \ 155 } 156 157 /* 158 * Default values. 159 */ 160 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */ 161 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */ 162 #define MAX_XFER_TIME (2 * 3600) /*%< Documented default is 2 hours */ 163 #define RESIGN_DELAY 3600 /*%< 1 hour */ 164 165 #ifndef DNS_MAX_EXPIRE 166 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */ 167 #endif /* ifndef DNS_MAX_EXPIRE */ 168 169 #ifndef DNS_DUMP_DELAY 170 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */ 171 #endif /* ifndef DNS_DUMP_DELAY */ 172 173 typedef struct dns_notify dns_notify_t; 174 typedef struct dns_checkds dns_checkds_t; 175 typedef struct dns_stub dns_stub_t; 176 typedef struct dns_load dns_load_t; 177 typedef struct dns_forward dns_forward_t; 178 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t; 179 typedef struct dns_keymgmt dns_keymgmt_t; 180 typedef struct dns_signing dns_signing_t; 181 typedef ISC_LIST(dns_signing_t) dns_signinglist_t; 182 typedef struct dns_nsec3chain dns_nsec3chain_t; 183 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t; 184 typedef struct dns_nsfetch dns_nsfetch_t; 185 typedef struct dns_keyfetch dns_keyfetch_t; 186 typedef struct dns_asyncload dns_asyncload_t; 187 typedef struct dns_include dns_include_t; 188 189 #define DNS_ZONE_CHECKLOCK 190 #ifdef DNS_ZONE_CHECKLOCK 191 #define LOCK_ZONE(z) \ 192 do { \ 193 LOCK(&(z)->lock); \ 194 INSIST(!(z)->locked); \ 195 (z)->locked = true; \ 196 } while (0) 197 #define UNLOCK_ZONE(z) \ 198 do { \ 199 INSIST((z)->locked); \ 200 (z)->locked = false; \ 201 UNLOCK(&(z)->lock); \ 202 } while (0) 203 #define LOCKED_ZONE(z) ((z)->locked) 204 #define TRYLOCK_ZONE(result, z) \ 205 do { \ 206 result = isc_mutex_trylock(&(z)->lock); \ 207 if (result == ISC_R_SUCCESS) { \ 208 INSIST(!(z)->locked); \ 209 (z)->locked = true; \ 210 } \ 211 } while (0) 212 #else /* ifdef DNS_ZONE_CHECKLOCK */ 213 #define LOCK_ZONE(z) LOCK(&(z)->lock) 214 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock) 215 #define LOCKED_ZONE(z) true 216 #define TRYLOCK_ZONE(result, z) \ 217 do { \ 218 result = isc_mutex_trylock(&(z)->lock); \ 219 } while (0) 220 #endif /* ifdef DNS_ZONE_CHECKLOCK */ 221 222 #define ZONEDB_INITLOCK(l) isc_rwlock_init(l) 223 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l) 224 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t)) 225 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t)) 226 227 #ifdef ENABLE_AFL 228 extern bool dns_fuzzing_resolver; 229 #endif /* ifdef ENABLE_AFL */ 230 231 /*% 232 * Hold key file IO locks. 233 */ 234 typedef struct dns_keyfileio { 235 unsigned int magic; 236 isc_mutex_t lock; 237 isc_refcount_t references; 238 dns_name_t *name; 239 dns_fixedname_t fname; 240 } dns_keyfileio_t; 241 242 struct dns_keymgmt { 243 unsigned int magic; 244 isc_rwlock_t lock; 245 isc_mem_t *mctx; 246 isc_hashmap_t *table; 247 }; 248 249 /* 250 * Initial size of the keymgmt hash table. 251 */ 252 #define DNS_KEYMGMT_HASH_BITS 12 253 254 struct dns_zone { 255 /* Unlocked */ 256 unsigned int magic; 257 isc_mutex_t lock; 258 #ifndef _LP64 259 isc_mutex_t atomic_lock; 260 #endif 261 #ifdef DNS_ZONE_CHECKLOCK 262 bool locked; 263 #endif /* ifdef DNS_ZONE_CHECKLOCK */ 264 isc_mem_t *mctx; 265 isc_refcount_t references; 266 267 isc_rwlock_t dblock; 268 dns_db_t *db; /* Locked by dblock */ 269 270 unsigned int tid; 271 272 /* Locked */ 273 dns_zonemgr_t *zmgr; 274 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */ 275 isc_loop_t *loop; 276 isc_timer_t *timer; 277 isc_refcount_t irefs; 278 dns_name_t origin; 279 char *masterfile; 280 const FILE *stream; /* loading from a stream? */ 281 ISC_LIST(dns_include_t) includes; /* Include files */ 282 ISC_LIST(dns_include_t) newincludes; /* Loading */ 283 unsigned int nincludes; 284 dns_masterformat_t masterformat; 285 const dns_master_style_t *masterstyle; 286 char *journal; 287 int32_t journalsize; 288 dns_rdataclass_t rdclass; 289 dns_zonetype_t type; 290 #ifdef _LP64 291 atomic_uint_fast64_t flags; 292 atomic_uint_fast64_t options; 293 #else 294 uint64_t flags; 295 uint64_t options; 296 #endif 297 unsigned int db_argc; 298 char **db_argv; 299 isc_time_t expiretime; 300 isc_time_t refreshtime; 301 isc_time_t dumptime; 302 isc_time_t loadtime; 303 isc_time_t notifytime; 304 isc_time_t resigntime; 305 isc_time_t keywarntime; 306 isc_time_t signingtime; 307 isc_time_t nsec3chaintime; 308 isc_time_t refreshkeytime; 309 isc_time_t xfrintime; 310 uint32_t refreshkeyinterval; 311 uint32_t refreshkeycount; 312 uint32_t refresh; 313 uint32_t retry; 314 uint32_t expire; 315 uint32_t minimum; 316 isc_stdtime_t key_expiry; 317 isc_stdtime_t log_key_expired_timer; 318 char *keydirectory; 319 dns_keyfileio_t *kfio; 320 dns_keystorelist_t *keystores; 321 dns_xfrin_t *xfr; 322 323 uint32_t maxrefresh; 324 uint32_t minrefresh; 325 uint32_t maxretry; 326 uint32_t minretry; 327 328 uint32_t maxrecords; 329 uint32_t maxrrperset; 330 uint32_t maxtypepername; 331 332 dns_remote_t primaries; 333 334 dns_remote_t parentals; 335 dns_dnsseckeylist_t checkds_ok; 336 dns_checkdstype_t checkdstype; 337 uint32_t nsfetchcount; 338 uint32_t parent_nscount; 339 340 dns_remote_t notify; 341 dns_notifytype_t notifytype; 342 isc_sockaddr_t notifyfrom; 343 isc_sockaddr_t notifysrc4; 344 isc_sockaddr_t notifysrc6; 345 isc_sockaddr_t parentalsrc4; 346 isc_sockaddr_t parentalsrc6; 347 isc_sockaddr_t xfrsource4; 348 isc_sockaddr_t xfrsource6; 349 isc_sockaddr_t sourceaddr; 350 dns_tsigkey_t *tsigkey; /* key used for xfr */ 351 dns_transport_t *transport; /* transport used for xfr */ 352 /* Access Control Lists */ 353 dns_acl_t *update_acl; 354 dns_acl_t *forward_acl; 355 dns_acl_t *notify_acl; 356 dns_acl_t *query_acl; 357 dns_acl_t *queryon_acl; 358 dns_acl_t *xfr_acl; 359 bool update_disabled; 360 bool zero_no_soa_ttl; 361 dns_severity_t check_names; 362 ISC_LIST(dns_notify_t) notifies; 363 ISC_LIST(dns_checkds_t) checkds_requests; 364 dns_request_t *request; 365 dns_loadctx_t *loadctx; 366 dns_dumpctx_t *dumpctx; 367 uint32_t minxfrratebytesin; 368 uint32_t minxfrratesecondsin; 369 uint32_t maxxfrin; 370 uint32_t maxxfrout; 371 uint32_t idlein; 372 uint32_t idleout; 373 dns_ssutable_t *ssutable; 374 uint32_t sigvalidityinterval; 375 uint32_t keyvalidityinterval; 376 uint32_t sigresigninginterval; 377 dns_view_t *view; 378 dns_view_t *prev_view; 379 dns_kasp_t *kasp; 380 dns_kasp_t *defaultkasp; 381 dns_dnsseckeylist_t keyring; 382 dns_checkmxfunc_t checkmx; 383 dns_checksrvfunc_t checksrv; 384 dns_checknsfunc_t checkns; 385 /*% 386 * Zones in certain states such as "waiting for zone transfer" 387 * or "zone transfer in progress" are kept on per-state linked lists 388 * in the zone manager using the 'statelink' field. The 'statelist' 389 * field points at the list the zone is currently on. It the zone 390 * is not on any such list, statelist is NULL. 391 */ 392 ISC_LINK(dns_zone_t) statelink; 393 dns_zonelist_t *statelist; 394 /*% 395 * Statistics counters about zone management. 396 */ 397 isc_stats_t *stats; 398 /*% 399 * Optional per-zone statistics counters. Counted outside of this 400 * module. 401 */ 402 dns_zonestat_level_t statlevel; 403 bool requeststats_on; 404 isc_stats_t *requeststats; 405 dns_stats_t *rcvquerystats; 406 dns_stats_t *dnssecsignstats; 407 uint32_t notifydelay; 408 uint32_t notifydefer; 409 dns_isselffunc_t isself; 410 void *isselfarg; 411 412 char *strnamerd; 413 char *strname; 414 char *strrdclass; 415 char *strviewname; 416 417 /*% 418 * Serial number for deferred journal compaction. 419 */ 420 uint32_t compact_serial; 421 /*% 422 * Keys that are signing the zone for the first time. 423 */ 424 dns_signinglist_t signing; 425 dns_nsec3chainlist_t nsec3chain; 426 /*% 427 * List of outstanding NSEC3PARAM change requests. 428 */ 429 ISC_LIST(struct np3) setnsec3param_queue; 430 /*% 431 * Signing / re-signing quantum stopping parameters. 432 */ 433 uint32_t signatures; 434 uint32_t nodes; 435 dns_rdatatype_t privatetype; 436 437 /*% 438 * Autosigning/key-maintenance options 439 */ 440 #ifdef _LP64 441 atomic_uint_fast64_t keyopts; 442 #else 443 uint64_t keyopts; 444 #endif 445 446 /*% 447 * True if added by "rndc addzone" 448 */ 449 bool added; 450 451 /*% 452 * True if added by automatically by named. 453 */ 454 bool automatic; 455 456 /*% 457 * response policy data to be relayed to the database 458 */ 459 dns_rpz_zones_t *rpzs; 460 dns_rpz_num_t rpz_num; 461 462 /*% 463 * catalog zone data 464 */ 465 dns_catz_zones_t *catzs; 466 467 /*% 468 * parent catalog zone 469 */ 470 dns_catz_zone_t *parentcatz; 471 472 /*% 473 * Serial number update method. 474 */ 475 dns_updatemethod_t updatemethod; 476 477 /*% 478 * whether ixfr is requested 479 */ 480 bool requestixfr; 481 uint32_t ixfr_ratio; 482 483 /*% 484 * whether EDNS EXPIRE is requested 485 */ 486 bool requestexpire; 487 488 /*% 489 * Outstanding forwarded UPDATE requests. 490 */ 491 dns_forwardlist_t forwards; 492 493 dns_zone_t *raw; 494 dns_zone_t *secure; 495 496 bool sourceserialset; 497 uint32_t sourceserial; 498 499 /*% 500 * soa and maximum zone ttl 501 */ 502 dns_ttl_t soattl; 503 dns_ttl_t maxttl; 504 505 /* 506 * Inline zone signing state. 507 */ 508 dns_diff_t rss_diff; 509 dns_dbversion_t *rss_newver; 510 dns_dbversion_t *rss_oldver; 511 dns_db_t *rss_db; 512 dns_zone_t *rss_raw; 513 struct rss *rss; 514 dns_update_state_t *rss_state; 515 516 isc_stats_t *gluecachestats; 517 518 /*% 519 * Offline KSK signed key responses. 520 */ 521 dns_skr_t *skr; 522 dns_skrbundle_t *skrbundle; 523 }; 524 525 #define zonediff_init(z, d) \ 526 do { \ 527 dns__zonediff_t *_z = (z); \ 528 (_z)->diff = (d); \ 529 (_z)->offline = false; \ 530 } while (0) 531 #ifdef _LP64 532 #define ISC_ZONE_GET(z, f) atomic_load_relaxed(&(z)->f) 533 #define ISC_ZONE_SET(z, f, o) atomic_fetch_or(&(z)->f, (o)) 534 #define ISC_ZONE_CLR(z, f, o) atomic_fetch_and(&(z)->f, ~(o)) 535 #else 536 #define ISC_ZONE_GET(z, f) \ 537 ({ \ 538 isc_mutex_lock(&(z)->atomic_lock); \ 539 uint64_t x = (z)->f; \ 540 isc_mutex_unlock(&(z)->atomic_lock); \ 541 x; \ 542 }) 543 #define ISC_ZONE_SET(z, f, o) \ 544 ({ \ 545 isc_mutex_lock(&(z)->atomic_lock); \ 546 uint64_t x = ((z)->f | (o)); \ 547 isc_mutex_unlock(&(z)->atomic_lock); \ 548 x; \ 549 }) 550 #define ISC_ZONE_CLR(z, f, o) \ 551 ({ \ 552 isc_mutex_lock(&(z)->atomic_lock); \ 553 uint64_t x = ((z)->f & ~(o)); \ 554 isc_mutex_unlock(&(z)->atomic_lock); \ 555 x; \ 556 }) 557 #endif 558 #define ISC_ZONE_TEST(z, f, o) ((ISC_ZONE_GET(z, f) & (o)) != 0) 559 560 #define DNS_ZONE_FLAG(z, f) ISC_ZONE_TEST(z, flags, f) 561 #define DNS_ZONE_SETFLAG(z, f) ISC_ZONE_SET(z, flags, f) 562 #define DNS_ZONE_CLRFLAG(z, f) ISC_ZONE_CLR(z, flags, f) 563 typedef enum { 564 DNS_ZONEFLG_REFRESH = 0x00000001U, /*%< refresh check in progress */ 565 DNS_ZONEFLG_NEEDDUMP = 0x00000002U, /*%< zone need consolidation */ 566 DNS_ZONEFLG_USEVC = 0x00000004U, /*%< use tcp for refresh query */ 567 DNS_ZONEFLG_DUMPING = 0x00000008U, /*%< a dump is in progress */ 568 DNS_ZONEFLG_HASINCLUDE = 0x00000010U, /*%< $INCLUDE in zone file */ 569 DNS_ZONEFLG_LOADED = 0x00000020U, /*%< database has loaded */ 570 DNS_ZONEFLG_EXITING = 0x00000040U, /*%< zone is being destroyed */ 571 DNS_ZONEFLG_EXPIRED = 0x00000080U, /*%< zone has expired */ 572 DNS_ZONEFLG_NEEDREFRESH = 0x00000100U, /*%< refresh check needed */ 573 DNS_ZONEFLG_UPTODATE = 0x00000200U, /*%< zone contents are 574 * up-to-date */ 575 DNS_ZONEFLG_NEEDNOTIFY = 0x00000400U, /*%< need to send out notify 576 * messages */ 577 DNS_ZONEFLG_FIXJOURNAL = 0x00000800U, /*%< journal file had 578 * recoverable error, 579 * needs rewriting */ 580 DNS_ZONEFLG_NOPRIMARIES = 0x00001000U, /*%< an attempt to refresh a 581 * zone with no primaries 582 * occurred */ 583 DNS_ZONEFLG_LOADING = 0x00002000U, /*%< load from disk in progress*/ 584 DNS_ZONEFLG_HAVETIMERS = 0x00004000U, /*%< timer values have been set 585 * from SOA (if not set, we 586 * are still using 587 * default timer values) */ 588 DNS_ZONEFLG_FORCEXFER = 0x00008000U, /*%< Force a zone xfer */ 589 DNS_ZONEFLG_NOREFRESH = 0x00010000U, 590 DNS_ZONEFLG_DIALNOTIFY = 0x00020000U, 591 DNS_ZONEFLG_DIALREFRESH = 0x00040000U, 592 DNS_ZONEFLG_SHUTDOWN = 0x00080000U, 593 DNS_ZONEFLG_NOIXFR = 0x00100000U, /*%< IXFR failed, force AXFR */ 594 DNS_ZONEFLG_FLUSH = 0x00200000U, 595 DNS_ZONEFLG_NOEDNS = 0x00400000U, 596 DNS_ZONEFLG_USEALTXFRSRC = 0x00800000U, /*%< Obsoleted. */ 597 DNS_ZONEFLG_SOABEFOREAXFR = 0x01000000U, 598 DNS_ZONEFLG_NEEDCOMPACT = 0x02000000U, 599 DNS_ZONEFLG_REFRESHING = 0x04000000U, /*%< Refreshing keydata */ 600 DNS_ZONEFLG_THAW = 0x08000000U, 601 DNS_ZONEFLG_LOADPENDING = 0x10000000U, /*%< Loading scheduled */ 602 DNS_ZONEFLG_NODELAY = 0x20000000U, 603 DNS_ZONEFLG_SENDSECURE = 0x40000000U, 604 DNS_ZONEFLG_NEEDSTARTUPNOTIFY = 0x80000000U, /*%< need to send out 605 * notify due to the zone 606 * just being loaded for 607 * the first time. */ 608 DNS_ZONEFLG_NOTIFYNODEFER = 0x100000000U, /*%< ignore the 609 * notify-defer option. */ 610 DNS_ZONEFLG_NOTIFYDEFERRED = 0x200000000U, /*%< notify was deferred 611 * according to the 612 * notify-defer option. */ 613 DNS_ZONEFLG_FIRSTREFRESH = 0x400000000U, /*%< First refresh pending */ 614 DNS_ZONEFLG___MAX = UINT64_MAX, /* trick to make the ENUM 64-bit wide */ 615 } dns_zoneflg_t; 616 617 #define DNS_ZONE_OPTION(z, o) ISC_ZONE_TEST(z, options, o) 618 #define DNS_ZONE_SETOPTION(z, o) ISC_ZONE_SET(z, options, o) 619 #define DNS_ZONE_CLROPTION(z, o) ISC_ZONE_CLR(z, options, o) 620 #define DNS_ZONEKEY_OPTION(z, o) ISC_ZONE_TEST(z, keyopts, o) 621 #define DNS_ZONEKEY_SETOPTION(z, o) ISC_ZONE_SET(z, keyopts, o) 622 #define DNS_ZONEKEY_CLROPTION(z, o) ISC_ZONE_CLR(z, keyopts, o) 623 624 /* Flags for zone_load() */ 625 typedef enum { 626 DNS_ZONELOADFLAG_NOSTAT = 0x00000001U, /* Do not stat() master files */ 627 DNS_ZONELOADFLAG_THAW = 0x00000002U, /* Thaw the zone on successful 628 * load. */ 629 } dns_zoneloadflag_t; 630 631 #define UNREACH_CACHE_SIZE 10U 632 #define UNREACH_HOLD_TIME 600 /* 10 minutes */ 633 634 struct dns_unreachable { 635 isc_sockaddr_t remote; 636 isc_sockaddr_t local; 637 atomic_uint_fast32_t expire; 638 atomic_uint_fast32_t last; 639 uint32_t count; 640 }; 641 642 struct dns_zonemgr { 643 unsigned int magic; 644 isc_mem_t *mctx; 645 isc_refcount_t refs; 646 isc_loopmgr_t *loopmgr; 647 isc_nm_t *netmgr; 648 uint32_t workers; 649 isc_mem_t **mctxpool; 650 isc_ratelimiter_t *checkdsrl; 651 isc_ratelimiter_t *notifyrl; 652 isc_ratelimiter_t *refreshrl; 653 isc_ratelimiter_t *startupnotifyrl; 654 isc_ratelimiter_t *startuprefreshrl; 655 isc_rwlock_t rwlock; 656 isc_rwlock_t urlock; 657 658 /* Locked by rwlock. */ 659 dns_zonelist_t zones; 660 dns_zonelist_t waiting_for_xfrin; 661 dns_zonelist_t xfrin_in_progress; 662 663 /* Configuration data. */ 664 uint32_t transfersin; 665 uint32_t transfersperns; 666 unsigned int checkdsrate; 667 unsigned int notifyrate; 668 unsigned int startupnotifyrate; 669 unsigned int serialqueryrate; 670 unsigned int startupserialqueryrate; 671 672 /* Locked by urlock. */ 673 /* LRU cache */ 674 struct dns_unreachable unreachable[UNREACH_CACHE_SIZE]; 675 676 dns_keymgmt_t *keymgmt; 677 678 isc_tlsctx_cache_t *tlsctx_cache; 679 isc_rwlock_t tlsctx_cache_rwlock; 680 }; 681 682 /*% 683 * Hold notify state. 684 */ 685 struct dns_notify { 686 unsigned int magic; 687 unsigned int flags; 688 isc_mem_t *mctx; 689 dns_zone_t *zone; 690 dns_adbfind_t *find; 691 dns_request_t *request; 692 dns_name_t ns; 693 isc_sockaddr_t src; 694 isc_sockaddr_t dst; 695 dns_tsigkey_t *key; 696 dns_transport_t *transport; 697 ISC_LINK(dns_notify_t) link; 698 isc_rlevent_t *rlevent; 699 }; 700 701 typedef enum dns_notify_flags { 702 DNS_NOTIFY_NOSOA = 1 << 0, 703 DNS_NOTIFY_STARTUP = 1 << 1, 704 DNS_NOTIFY_TCP = 1 << 2, 705 } dns_notify_flags_t; 706 707 /*% 708 * Hold checkds state. 709 */ 710 struct dns_checkds { 711 unsigned int magic; 712 dns_notify_flags_t flags; 713 isc_mem_t *mctx; 714 dns_zone_t *zone; 715 dns_adbfind_t *find; 716 dns_request_t *request; 717 dns_name_t ns; 718 isc_sockaddr_t src; 719 isc_sockaddr_t dst; 720 dns_tsigkey_t *key; 721 dns_transport_t *transport; 722 ISC_LINK(dns_checkds_t) link; 723 isc_rlevent_t *rlevent; 724 }; 725 726 /*% 727 * dns_stub holds state while performing a 'stub' transfer. 728 * 'db' is the zone's 'db' or a new one if this is the initial 729 * transfer. 730 */ 731 732 struct dns_stub { 733 unsigned int magic; 734 isc_mem_t *mctx; 735 dns_zone_t *zone; 736 dns_db_t *db; 737 dns_dbversion_t *version; 738 atomic_uint_fast32_t pending_requests; 739 }; 740 741 /*% 742 * Hold load state. 743 */ 744 struct dns_load { 745 dns_zone_t *zone; 746 dns_db_t *db; 747 isc_time_t loadtime; 748 dns_rdatacallbacks_t callbacks; 749 }; 750 751 /*% 752 * Hold forward state. 753 */ 754 struct dns_forward { 755 unsigned int magic; 756 isc_mem_t *mctx; 757 dns_zone_t *zone; 758 isc_buffer_t *msgbuf; 759 dns_request_t *request; 760 uint32_t which; 761 isc_sockaddr_t addr; 762 dns_transport_t *transport; 763 dns_updatecallback_t callback; 764 void *callback_arg; 765 unsigned int options; 766 ISC_LINK(dns_forward_t) link; 767 }; 768 769 /*% 770 * Hold state for when we are signing a zone with a new 771 * DNSKEY as result of an update. 772 */ 773 struct dns_signing { 774 unsigned int magic; 775 dns_db_t *db; 776 dns_dbiterator_t *dbiterator; 777 dns_secalg_t algorithm; 778 uint16_t keyid; 779 bool deleteit; 780 bool fullsign; 781 bool done; 782 ISC_LINK(dns_signing_t) link; 783 }; 784 785 struct dns_nsec3chain { 786 unsigned int magic; 787 dns_db_t *db; 788 dns_dbiterator_t *dbiterator; 789 dns_rdata_nsec3param_t nsec3param; 790 unsigned char salt[255]; 791 bool done; 792 bool seen_nsec; 793 bool delete_nsec; 794 bool save_delete_nsec; 795 ISC_LINK(dns_nsec3chain_t) link; 796 }; 797 798 /*%< 799 * 'dbiterator' contains a iterator for the database. If we are creating 800 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are 801 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be 802 * iterated. 803 * 804 * 'nsec3param' contains the parameters of the NSEC3 chain being created 805 * or removed. 806 * 807 * 'salt' is buffer space and is referenced via 'nsec3param.salt'. 808 * 809 * 'seen_nsec' will be set to true if, while iterating the zone to create a 810 * NSEC3 chain, a NSEC record is seen. 811 * 812 * 'delete_nsec' will be set to true if, at the completion of the creation 813 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we 814 * are in the process of deleting the NSEC chain. 815 * 816 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec' 817 * so it can be recovered in the event of a error. 818 */ 819 820 struct dns_keyfetch { 821 isc_mem_t *mctx; 822 dns_fixedname_t name; 823 dns_rdataset_t keydataset; 824 dns_rdataset_t dnskeyset; 825 dns_rdataset_t dnskeysigset; 826 dns_zone_t *zone; 827 dns_db_t *db; 828 dns_fetch_t *fetch; 829 }; 830 831 struct dns_nsfetch { 832 isc_mem_t *mctx; 833 dns_fixedname_t name; 834 dns_name_t pname; 835 dns_rdataset_t nsrrset; 836 dns_rdataset_t nssigset; 837 dns_zone_t *zone; 838 dns_fetch_t *fetch; 839 }; 840 841 /*% 842 * Hold state for an asynchronous load 843 */ 844 struct dns_asyncload { 845 dns_zone_t *zone; 846 unsigned int flags; 847 dns_zt_callback_t *loaded; 848 void *loaded_arg; 849 }; 850 851 /*% 852 * Reference to an include file encountered during loading 853 */ 854 struct dns_include { 855 char *name; 856 isc_time_t filetime; 857 ISC_LINK(dns_include_t) link; 858 }; 859 860 /* 861 * These can be overridden by the -T mkeytimers option on the command 862 * line, so that we can test with shorter periods than specified in 863 * RFC 5011. 864 */ 865 #define HOUR 3600 866 #define DAY (24 * HOUR) 867 #define MONTH (30 * DAY) 868 unsigned int dns_zone_mkey_hour = HOUR; 869 unsigned int dns_zone_mkey_day = DAY; 870 unsigned int dns_zone_mkey_month = MONTH; 871 872 #define SEND_BUFFER_SIZE 2048 873 874 static void 875 zone_timer_set(dns_zone_t *zone, isc_time_t *next, isc_time_t *now); 876 877 typedef struct zone_settimer { 878 dns_zone_t *zone; 879 isc_time_t now; 880 } zone_settimer_t; 881 882 static void 883 zone_settimer(dns_zone_t *, isc_time_t *); 884 static void 885 cancel_refresh(dns_zone_t *); 886 static void 887 zone_debuglogc(dns_zone_t *zone, isc_logcategory_t *category, const char *me, 888 int debuglevel, const char *fmt, ...); 889 static void 890 zone_debuglog(dns_zone_t *zone, const char *, int debuglevel, const char *msg, 891 ...) ISC_FORMAT_PRINTF(4, 5); 892 static void 893 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) 894 ISC_FORMAT_PRINTF(3, 4); 895 static void 896 dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...) 897 ISC_FORMAT_PRINTF(3, 4); 898 static void 899 queue_xfrin(dns_zone_t *zone); 900 static isc_result_t 901 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 902 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, 903 dns_rdata_t *rdata); 904 static void 905 zone_unload(dns_zone_t *zone); 906 static void 907 zone_expire(dns_zone_t *zone); 908 static void 909 zone_refresh(dns_zone_t *zone); 910 static void 911 zone_iattach(dns_zone_t *source, dns_zone_t **target); 912 static void 913 zone_idetach(dns_zone_t **zonep); 914 static isc_result_t 915 zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump); 916 static void 917 zone_attachdb(dns_zone_t *zone, dns_db_t *db); 918 static void 919 zone_detachdb(dns_zone_t *zone); 920 static void 921 zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs); 922 static void 923 zone_catz_disable(dns_zone_t *zone); 924 static isc_result_t 925 default_journal(dns_zone_t *zone); 926 static void 927 zone_xfrdone(dns_zone_t *zone, uint32_t *expireopt, isc_result_t result); 928 static isc_result_t 929 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, 930 isc_result_t result); 931 static void 932 zone_needdump(dns_zone_t *zone, unsigned int delay); 933 static void 934 zone_shutdown(void *arg); 935 static void 936 zone_loaddone(void *arg, isc_result_t result); 937 static isc_result_t 938 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime); 939 static void 940 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length); 941 static void 942 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length); 943 static void 944 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length); 945 static void 946 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length); 947 static isc_result_t 948 zone_send_secureserial(dns_zone_t *zone, uint32_t serial); 949 static void 950 refresh_callback(void *arg); 951 static void 952 stub_callback(void *arg); 953 static void 954 queue_soa_query(dns_zone_t *zone); 955 static void 956 soa_query(void *arg); 957 static void 958 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub); 959 static int 960 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type); 961 static void 962 checkds_cancel(dns_zone_t *zone); 963 static void 964 checkds_find_address(dns_checkds_t *checkds); 965 static void 966 checkds_send(dns_zone_t *zone); 967 static void 968 checkds_createmessage(dns_zone_t *zone, dns_message_t **messagep); 969 static void 970 checkds_done(void *arg); 971 static void 972 checkds_send_tons(dns_checkds_t *checkds); 973 static void 974 checkds_send_toaddr(void *arg); 975 static void 976 nsfetch_levelup(dns_nsfetch_t *nsfetch); 977 static void 978 notify_cancel(dns_zone_t *zone); 979 static void 980 notify_find_address(dns_notify_t *notify); 981 static void 982 notify_send(dns_notify_t *notify); 983 static isc_result_t 984 notify_createmessage(dns_zone_t *zone, unsigned int flags, 985 dns_message_t **messagep); 986 static void 987 notify_done(void *arg); 988 static void 989 notify_send_toaddr(void *arg); 990 static isc_result_t 991 zone_dump(dns_zone_t *, bool); 992 static void 993 got_transfer_quota(void *arg); 994 static isc_result_t 995 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone); 996 static void 997 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi); 998 static void 999 zonemgr_free(dns_zonemgr_t *zmgr); 1000 static void 1001 rss_post(void *arg); 1002 1003 static isc_result_t 1004 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 1005 unsigned int *soacount, uint32_t *soattl, uint32_t *serial, 1006 uint32_t *refresh, uint32_t *retry, uint32_t *expire, 1007 uint32_t *minimum, unsigned int *errors); 1008 1009 static void 1010 zone_freedbargs(dns_zone_t *zone); 1011 static void 1012 forward_callback(void *arg); 1013 static void 1014 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat); 1015 static void 1016 zone_maintenance(dns_zone_t *zone); 1017 static void 1018 zone_notify(dns_zone_t *zone, isc_time_t *now); 1019 static void 1020 dump_done(void *arg, isc_result_t result); 1021 static isc_result_t 1022 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid, 1023 bool deleteit, bool fullsign); 1024 static isc_result_t 1025 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 1026 dns_name_t *name, dns_diff_t *diff); 1027 static void 1028 zone_rekey(dns_zone_t *zone); 1029 static isc_result_t 1030 zone_send_securedb(dns_zone_t *zone, dns_db_t *db); 1031 static dns_ttl_t 1032 zone_nsecttl(dns_zone_t *zone); 1033 static void 1034 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value); 1035 static void 1036 zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial); 1037 static isc_result_t 1038 zone_journal_rollforward(dns_zone_t *zone, dns_db_t *db, bool *needdump, 1039 bool *fixjournal); 1040 static void 1041 setnsec3param(void *arg); 1042 1043 static void 1044 zmgr_tlsctx_attach(dns_zonemgr_t *zmgr, isc_tlsctx_cache_t **ptlsctx_cache); 1045 /*%< 1046 * Attach to TLS client context cache used for zone transfers via 1047 * encrypted transports (e.g. XoT). 1048 * 1049 * The obtained reference needs to be detached by a call to 1050 * 'isc_tlsctx_cache_detach()' when not needed anymore. 1051 * 1052 * Requires: 1053 *\li 'zmgr' is a valid zone manager. 1054 *\li 'ptlsctx_cache' is not 'NULL' and points to 'NULL'. 1055 */ 1056 1057 #define ENTER zone_debuglog(zone, __func__, 1, "enter") 1058 1059 static const unsigned int dbargc_default = 1; 1060 static const char *dbargv_default[] = { ZONEDB_DEFAULT }; 1061 1062 #define DNS_ZONE_JITTER_ADD(a, b, c) \ 1063 do { \ 1064 isc_interval_t _i; \ 1065 uint32_t _j; \ 1066 _j = (b) - isc_random_uniform((b) / 4); \ 1067 isc_interval_set(&_i, _j, 0); \ 1068 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 1069 dns_zone_log(zone, ISC_LOG_WARNING, \ 1070 "epoch approaching: upgrade required: " \ 1071 "now + %s failed", \ 1072 #b); \ 1073 isc_interval_set(&_i, _j / 2, 0); \ 1074 (void)isc_time_add((a), &_i, (c)); \ 1075 } \ 1076 } while (0) 1077 1078 #define DNS_ZONE_TIME_ADD(a, b, c) \ 1079 do { \ 1080 isc_interval_t _i; \ 1081 isc_interval_set(&_i, (b), 0); \ 1082 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 1083 dns_zone_log(zone, ISC_LOG_WARNING, \ 1084 "epoch approaching: upgrade required: " \ 1085 "now + %s failed", \ 1086 #b); \ 1087 isc_interval_set(&_i, (b) / 2, 0); \ 1088 (void)isc_time_add((a), &_i, (c)); \ 1089 } \ 1090 } while (0) 1091 1092 #define DNS_ZONE_TIME_SUBTRACT(a, b, c) \ 1093 do { \ 1094 isc_interval_t _i; \ 1095 isc_interval_set(&_i, (b), 0); \ 1096 if (isc_time_subtract((a), &_i, (c)) != ISC_R_SUCCESS) { \ 1097 dns_zone_log(zone, ISC_LOG_WARNING, \ 1098 "epoch approaching: upgrade required: " \ 1099 "isc_time_subtract() failed"); \ 1100 isc_interval_set(&_i, (b) / 2, 0); \ 1101 (void)isc_time_subtract((a), &_i, (c)); \ 1102 } \ 1103 } while (0) 1104 1105 typedef struct nsec3param nsec3param_t; 1106 struct nsec3param { 1107 dns_rdata_nsec3param_t rdata; 1108 unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1]; 1109 unsigned int length; 1110 bool nsec; 1111 bool replace; 1112 bool resalt; 1113 bool lookup; 1114 ISC_LINK(nsec3param_t) link; 1115 }; 1116 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t; 1117 1118 struct np3 { 1119 dns_zone_t *zone; 1120 nsec3param_t params; 1121 ISC_LINK(struct np3) link; 1122 }; 1123 1124 struct setserial { 1125 dns_zone_t *zone; 1126 uint32_t serial; 1127 }; 1128 1129 struct stub_cb_args { 1130 dns_stub_t *stub; 1131 dns_tsigkey_t *tsig_key; 1132 uint16_t udpsize; 1133 int timeout; 1134 bool reqnsid; 1135 }; 1136 1137 struct stub_glue_request { 1138 dns_request_t *request; 1139 dns_name_t name; 1140 struct stub_cb_args *args; 1141 bool ipv4; 1142 }; 1143 1144 /*% 1145 * Increment resolver-related statistics counters. Zone must be locked. 1146 */ 1147 static void 1148 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { 1149 if (zone->stats != NULL) { 1150 isc_stats_increment(zone->stats, counter); 1151 } 1152 } 1153 1154 /*** 1155 *** Public functions. 1156 ***/ 1157 1158 void 1159 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx, unsigned int tid) { 1160 isc_time_t now; 1161 dns_zone_t *zone = NULL; 1162 1163 REQUIRE(zonep != NULL && *zonep == NULL); 1164 REQUIRE(mctx != NULL); 1165 1166 now = isc_time_now(); 1167 zone = isc_mem_get(mctx, sizeof(*zone)); 1168 *zone = (dns_zone_t){ 1169 .masterformat = dns_masterformat_none, 1170 .journalsize = -1, 1171 .rdclass = dns_rdataclass_none, 1172 .type = dns_zone_none, 1173 .refresh = DNS_ZONE_DEFAULTREFRESH, 1174 .retry = DNS_ZONE_DEFAULTRETRY, 1175 .maxrefresh = DNS_ZONE_MAXREFRESH, 1176 .minrefresh = DNS_ZONE_MINREFRESH, 1177 .maxretry = DNS_ZONE_MAXRETRY, 1178 .minretry = DNS_ZONE_MINRETRY, 1179 .checkdstype = dns_checkdstype_yes, 1180 .notifytype = dns_notifytype_yes, 1181 .zero_no_soa_ttl = true, 1182 .check_names = dns_severity_ignore, 1183 .idlein = DNS_DEFAULT_IDLEIN, 1184 .idleout = DNS_DEFAULT_IDLEOUT, 1185 .maxxfrin = MAX_XFER_TIME, 1186 .maxxfrout = MAX_XFER_TIME, 1187 .sigvalidityinterval = 30 * 24 * 3600, 1188 .sigresigninginterval = 7 * 24 * 3600, 1189 .statlevel = dns_zonestat_none, 1190 .notifydelay = 5, 1191 .signatures = 10, 1192 .nodes = 100, 1193 .privatetype = (dns_rdatatype_t)0xffffU, 1194 .rpz_num = DNS_RPZ_INVALID_NUM, 1195 .requestixfr = true, 1196 .ixfr_ratio = 100, 1197 .requestexpire = true, 1198 .updatemethod = dns_updatemethod_increment, 1199 .tid = tid, 1200 .notifytime = now, 1201 .newincludes = ISC_LIST_INITIALIZER, 1202 .notifies = ISC_LIST_INITIALIZER, 1203 .checkds_requests = ISC_LIST_INITIALIZER, 1204 .signing = ISC_LIST_INITIALIZER, 1205 .nsec3chain = ISC_LIST_INITIALIZER, 1206 .setnsec3param_queue = ISC_LIST_INITIALIZER, 1207 .forwards = ISC_LIST_INITIALIZER, 1208 .link = ISC_LINK_INITIALIZER, 1209 .statelink = ISC_LINK_INITIALIZER, 1210 }; 1211 dns_remote_t r = { 1212 .magic = DNS_REMOTE_MAGIC, 1213 }; 1214 1215 isc_mem_attach(mctx, &zone->mctx); 1216 isc_mutex_init(&zone->lock); 1217 #ifndef _LP64 1218 isc_mutex_init(&zone->atomic_lock); 1219 #endif 1220 ZONEDB_INITLOCK(&zone->dblock); 1221 1222 isc_refcount_init(&zone->references, 1); 1223 isc_refcount_init(&zone->irefs, 0); 1224 dns_name_init(&zone->origin, NULL); 1225 isc_sockaddr_any(&zone->notifysrc4); 1226 isc_sockaddr_any6(&zone->notifysrc6); 1227 isc_sockaddr_any(&zone->parentalsrc4); 1228 isc_sockaddr_any6(&zone->parentalsrc6); 1229 isc_sockaddr_any(&zone->xfrsource4); 1230 isc_sockaddr_any6(&zone->xfrsource6); 1231 1232 zone->primaries = r; 1233 zone->parentals = r; 1234 zone->notify = r; 1235 zone->defaultkasp = NULL; 1236 ISC_LIST_INIT(zone->keyring); 1237 1238 isc_stats_create(mctx, &zone->gluecachestats, 1239 dns_gluecachestatscounter_max); 1240 1241 zone->magic = ZONE_MAGIC; 1242 1243 /* Must be after magic is set. */ 1244 dns_zone_setdbtype(zone, dbargc_default, dbargv_default); 1245 1246 *zonep = zone; 1247 } 1248 1249 static void 1250 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) { 1251 dns_dnsseckey_t *key; 1252 while (!ISC_LIST_EMPTY(*list)) { 1253 key = ISC_LIST_HEAD(*list); 1254 ISC_LIST_UNLINK(*list, key, link); 1255 dns_dnsseckey_destroy(mctx, &key); 1256 } 1257 } 1258 1259 /* 1260 * Free a zone. Because we require that there be no more 1261 * outstanding events or references, no locking is necessary. 1262 */ 1263 static void 1264 zone_free(dns_zone_t *zone) { 1265 dns_signing_t *signing = NULL; 1266 dns_nsec3chain_t *nsec3chain = NULL; 1267 dns_include_t *include = NULL; 1268 1269 REQUIRE(DNS_ZONE_VALID(zone)); 1270 REQUIRE(!LOCKED_ZONE(zone)); 1271 REQUIRE(zone->timer == NULL); 1272 REQUIRE(zone->zmgr == NULL); 1273 1274 isc_refcount_destroy(&zone->references); 1275 isc_refcount_destroy(&zone->irefs); 1276 1277 /* 1278 * Managed objects. Order is important. 1279 */ 1280 if (zone->request != NULL) { 1281 dns_request_destroy(&zone->request); /* XXXMPA */ 1282 } 1283 INSIST(zone->statelist == NULL); 1284 INSIST(zone->view == NULL); 1285 INSIST(zone->prev_view == NULL); 1286 1287 /* Unmanaged objects */ 1288 for (struct np3 *npe = ISC_LIST_HEAD(zone->setnsec3param_queue); 1289 npe != NULL; npe = ISC_LIST_HEAD(zone->setnsec3param_queue)) 1290 { 1291 ISC_LIST_UNLINK(zone->setnsec3param_queue, npe, link); 1292 isc_mem_put(zone->mctx, npe, sizeof(*npe)); 1293 } 1294 1295 for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; 1296 signing = ISC_LIST_HEAD(zone->signing)) 1297 { 1298 ISC_LIST_UNLINK(zone->signing, signing, link); 1299 dns_db_detach(&signing->db); 1300 dns_dbiterator_destroy(&signing->dbiterator); 1301 isc_mem_put(zone->mctx, signing, sizeof *signing); 1302 } 1303 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL; 1304 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) 1305 { 1306 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 1307 dns_db_detach(&nsec3chain->db); 1308 dns_dbiterator_destroy(&nsec3chain->dbiterator); 1309 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 1310 } 1311 for (include = ISC_LIST_HEAD(zone->includes); include != NULL; 1312 include = ISC_LIST_HEAD(zone->includes)) 1313 { 1314 ISC_LIST_UNLINK(zone->includes, include, link); 1315 isc_mem_free(zone->mctx, include->name); 1316 isc_mem_put(zone->mctx, include, sizeof *include); 1317 } 1318 for (include = ISC_LIST_HEAD(zone->newincludes); include != NULL; 1319 include = ISC_LIST_HEAD(zone->newincludes)) 1320 { 1321 ISC_LIST_UNLINK(zone->newincludes, include, link); 1322 isc_mem_free(zone->mctx, include->name); 1323 isc_mem_put(zone->mctx, include, sizeof *include); 1324 } 1325 if (zone->masterfile != NULL) { 1326 isc_mem_free(zone->mctx, zone->masterfile); 1327 } 1328 zone->masterfile = NULL; 1329 if (zone->keydirectory != NULL) { 1330 isc_mem_free(zone->mctx, zone->keydirectory); 1331 } 1332 zone->keydirectory = NULL; 1333 if (zone->kasp != NULL) { 1334 dns_kasp_detach(&zone->kasp); 1335 } 1336 if (zone->defaultkasp != NULL) { 1337 dns_kasp_detach(&zone->defaultkasp); 1338 } 1339 if (!ISC_LIST_EMPTY(zone->keyring)) { 1340 clear_keylist(&zone->keyring, zone->mctx); 1341 } 1342 if (!ISC_LIST_EMPTY(zone->checkds_ok)) { 1343 clear_keylist(&zone->checkds_ok, zone->mctx); 1344 } 1345 if (zone->skr != NULL) { 1346 zone->skrbundle = NULL; 1347 dns_skr_detach(&zone->skr); 1348 } 1349 1350 zone->journalsize = -1; 1351 if (zone->journal != NULL) { 1352 isc_mem_free(zone->mctx, zone->journal); 1353 } 1354 zone->journal = NULL; 1355 if (zone->stats != NULL) { 1356 isc_stats_detach(&zone->stats); 1357 } 1358 if (zone->requeststats != NULL) { 1359 isc_stats_detach(&zone->requeststats); 1360 } 1361 if (zone->rcvquerystats != NULL) { 1362 dns_stats_detach(&zone->rcvquerystats); 1363 } 1364 if (zone->dnssecsignstats != NULL) { 1365 dns_stats_detach(&zone->dnssecsignstats); 1366 } 1367 if (zone->db != NULL) { 1368 zone_detachdb(zone); 1369 } 1370 if (zone->rpzs != NULL) { 1371 REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones); 1372 dns_rpz_zones_detach(&zone->rpzs); 1373 zone->rpz_num = DNS_RPZ_INVALID_NUM; 1374 } 1375 if (zone->catzs != NULL) { 1376 dns_catz_zones_detach(&zone->catzs); 1377 } 1378 zone_freedbargs(zone); 1379 1380 dns_zone_setparentals(zone, NULL, NULL, NULL, NULL, 0); 1381 dns_zone_setprimaries(zone, NULL, NULL, NULL, NULL, 0); 1382 dns_zone_setalsonotify(zone, NULL, NULL, NULL, NULL, 0); 1383 1384 zone->check_names = dns_severity_ignore; 1385 if (zone->update_acl != NULL) { 1386 dns_acl_detach(&zone->update_acl); 1387 } 1388 if (zone->forward_acl != NULL) { 1389 dns_acl_detach(&zone->forward_acl); 1390 } 1391 if (zone->notify_acl != NULL) { 1392 dns_acl_detach(&zone->notify_acl); 1393 } 1394 if (zone->query_acl != NULL) { 1395 dns_acl_detach(&zone->query_acl); 1396 } 1397 if (zone->queryon_acl != NULL) { 1398 dns_acl_detach(&zone->queryon_acl); 1399 } 1400 if (zone->xfr_acl != NULL) { 1401 dns_acl_detach(&zone->xfr_acl); 1402 } 1403 if (dns_name_dynamic(&zone->origin)) { 1404 dns_name_free(&zone->origin, zone->mctx); 1405 } 1406 if (zone->strnamerd != NULL) { 1407 isc_mem_free(zone->mctx, zone->strnamerd); 1408 } 1409 if (zone->strname != NULL) { 1410 isc_mem_free(zone->mctx, zone->strname); 1411 } 1412 if (zone->strrdclass != NULL) { 1413 isc_mem_free(zone->mctx, zone->strrdclass); 1414 } 1415 if (zone->strviewname != NULL) { 1416 isc_mem_free(zone->mctx, zone->strviewname); 1417 } 1418 if (zone->ssutable != NULL) { 1419 dns_ssutable_detach(&zone->ssutable); 1420 } 1421 if (zone->gluecachestats != NULL) { 1422 isc_stats_detach(&zone->gluecachestats); 1423 } 1424 1425 /* last stuff */ 1426 ZONEDB_DESTROYLOCK(&zone->dblock); 1427 isc_mutex_destroy(&zone->lock); 1428 #ifndef _LP64 1429 isc_mutex_destroy(&zone->atomic_lock); 1430 #endif 1431 zone->magic = 0; 1432 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone)); 1433 } 1434 1435 /* 1436 * Returns true iff this the signed side of an inline-signing zone. 1437 * Caller should hold zone lock. 1438 */ 1439 static bool 1440 inline_secure(dns_zone_t *zone) { 1441 REQUIRE(DNS_ZONE_VALID(zone)); 1442 if (zone->raw != NULL) { 1443 return true; 1444 } 1445 return false; 1446 } 1447 1448 /* 1449 * Returns true iff this the unsigned side of an inline-signing zone 1450 * Caller should hold zone lock. 1451 */ 1452 static bool 1453 inline_raw(dns_zone_t *zone) { 1454 REQUIRE(DNS_ZONE_VALID(zone)); 1455 if (zone->secure != NULL) { 1456 return true; 1457 } 1458 return false; 1459 } 1460 1461 /* 1462 * Single shot. 1463 */ 1464 void 1465 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) { 1466 char namebuf[1024]; 1467 1468 REQUIRE(DNS_ZONE_VALID(zone)); 1469 REQUIRE(rdclass != dns_rdataclass_none); 1470 1471 /* 1472 * Test and set. 1473 */ 1474 LOCK_ZONE(zone); 1475 INSIST(zone != zone->raw); 1476 REQUIRE(zone->rdclass == dns_rdataclass_none || 1477 zone->rdclass == rdclass); 1478 zone->rdclass = rdclass; 1479 1480 if (zone->strnamerd != NULL) { 1481 isc_mem_free(zone->mctx, zone->strnamerd); 1482 } 1483 if (zone->strrdclass != NULL) { 1484 isc_mem_free(zone->mctx, zone->strrdclass); 1485 } 1486 1487 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1488 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1489 zone_rdclass_tostr(zone, namebuf, sizeof namebuf); 1490 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf); 1491 1492 if (inline_secure(zone)) { 1493 dns_zone_setclass(zone->raw, rdclass); 1494 } 1495 UNLOCK_ZONE(zone); 1496 } 1497 1498 dns_rdataclass_t 1499 dns_zone_getclass(dns_zone_t *zone) { 1500 REQUIRE(DNS_ZONE_VALID(zone)); 1501 1502 return zone->rdclass; 1503 } 1504 1505 void 1506 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { 1507 REQUIRE(DNS_ZONE_VALID(zone)); 1508 1509 LOCK_ZONE(zone); 1510 zone->notifytype = notifytype; 1511 UNLOCK_ZONE(zone); 1512 } 1513 1514 void 1515 dns_zone_setcheckdstype(dns_zone_t *zone, dns_checkdstype_t checkdstype) { 1516 REQUIRE(DNS_ZONE_VALID(zone)); 1517 1518 LOCK_ZONE(zone); 1519 zone->checkdstype = checkdstype; 1520 UNLOCK_ZONE(zone); 1521 } 1522 1523 isc_result_t 1524 dns_zone_getserial(dns_zone_t *zone, uint32_t *serialp) { 1525 isc_result_t result; 1526 unsigned int soacount; 1527 1528 REQUIRE(DNS_ZONE_VALID(zone)); 1529 REQUIRE(serialp != NULL); 1530 1531 LOCK_ZONE(zone); 1532 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1533 if (zone->db != NULL) { 1534 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, 1535 serialp, NULL, NULL, NULL, NULL, 1536 NULL); 1537 if (result == ISC_R_SUCCESS && soacount == 0) { 1538 result = ISC_R_FAILURE; 1539 } 1540 } else { 1541 result = DNS_R_NOTLOADED; 1542 } 1543 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1544 UNLOCK_ZONE(zone); 1545 1546 return result; 1547 } 1548 1549 /* 1550 * Single shot. 1551 */ 1552 void 1553 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) { 1554 char namebuf[1024]; 1555 1556 REQUIRE(DNS_ZONE_VALID(zone)); 1557 REQUIRE(type != dns_zone_none); 1558 1559 /* 1560 * Test and set. 1561 */ 1562 LOCK_ZONE(zone); 1563 REQUIRE(zone->type == dns_zone_none || zone->type == type); 1564 zone->type = type; 1565 1566 if (zone->strnamerd != NULL) { 1567 isc_mem_free(zone->mctx, zone->strnamerd); 1568 } 1569 1570 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1571 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1572 UNLOCK_ZONE(zone); 1573 } 1574 1575 static void 1576 zone_freedbargs(dns_zone_t *zone) { 1577 unsigned int i; 1578 1579 /* Free the old database argument list. */ 1580 if (zone->db_argv != NULL) { 1581 for (i = 0; i < zone->db_argc; i++) { 1582 isc_mem_free(zone->mctx, zone->db_argv[i]); 1583 } 1584 isc_mem_cput(zone->mctx, zone->db_argv, zone->db_argc, 1585 sizeof(*zone->db_argv)); 1586 } 1587 zone->db_argc = 0; 1588 zone->db_argv = NULL; 1589 } 1590 1591 isc_result_t 1592 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) { 1593 size_t size = 0; 1594 unsigned int i; 1595 isc_result_t result = ISC_R_SUCCESS; 1596 void *mem; 1597 char **tmp, *tmp2, *base; 1598 1599 REQUIRE(DNS_ZONE_VALID(zone)); 1600 REQUIRE(argv != NULL && *argv == NULL); 1601 1602 LOCK_ZONE(zone); 1603 size = ISC_CHECKED_MUL(zone->db_argc + 1, sizeof(char *)); 1604 for (i = 0; i < zone->db_argc; i++) { 1605 size += strlen(zone->db_argv[i]) + 1; 1606 } 1607 mem = isc_mem_allocate(mctx, size); 1608 { 1609 tmp = mem; 1610 tmp2 = mem; 1611 base = mem; 1612 tmp2 += ISC_CHECKED_MUL(zone->db_argc + 1, sizeof(char *)); 1613 for (i = 0; i < zone->db_argc; i++) { 1614 *tmp++ = tmp2; 1615 strlcpy(tmp2, zone->db_argv[i], size - (tmp2 - base)); 1616 tmp2 += strlen(tmp2) + 1; 1617 } 1618 *tmp = NULL; 1619 } 1620 UNLOCK_ZONE(zone); 1621 *argv = mem; 1622 return result; 1623 } 1624 1625 void 1626 dns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc, 1627 const char *const *dbargv) { 1628 char **argv = NULL; 1629 unsigned int i; 1630 1631 REQUIRE(DNS_ZONE_VALID(zone)); 1632 REQUIRE(dbargc >= 1); 1633 REQUIRE(dbargv != NULL); 1634 1635 LOCK_ZONE(zone); 1636 1637 /* Set up a new database argument list. */ 1638 argv = isc_mem_cget(zone->mctx, dbargc, sizeof(*argv)); 1639 for (i = 0; i < dbargc; i++) { 1640 argv[i] = NULL; 1641 } 1642 for (i = 0; i < dbargc; i++) { 1643 argv[i] = isc_mem_strdup(zone->mctx, dbargv[i]); 1644 } 1645 1646 /* Free the old list. */ 1647 zone_freedbargs(zone); 1648 1649 zone->db_argc = dbargc; 1650 zone->db_argv = argv; 1651 1652 UNLOCK_ZONE(zone); 1653 } 1654 1655 static void 1656 dns_zone_setview_helper(dns_zone_t *zone, dns_view_t *view) { 1657 char namebuf[1024]; 1658 1659 if (zone->prev_view == NULL && zone->view != NULL) { 1660 dns_view_weakattach(zone->view, &zone->prev_view); 1661 } 1662 1663 INSIST(zone != zone->raw); 1664 if (zone->view != NULL) { 1665 dns_view_sfd_del(zone->view, &zone->origin); 1666 dns_view_weakdetach(&zone->view); 1667 } 1668 dns_view_weakattach(view, &zone->view); 1669 dns_view_sfd_add(view, &zone->origin); 1670 1671 if (zone->strviewname != NULL) { 1672 isc_mem_free(zone->mctx, zone->strviewname); 1673 } 1674 if (zone->strnamerd != NULL) { 1675 isc_mem_free(zone->mctx, zone->strnamerd); 1676 } 1677 1678 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1679 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1680 zone_viewname_tostr(zone, namebuf, sizeof namebuf); 1681 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf); 1682 1683 if (inline_secure(zone)) { 1684 dns_zone_setview(zone->raw, view); 1685 } 1686 } 1687 1688 void 1689 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) { 1690 REQUIRE(DNS_ZONE_VALID(zone)); 1691 1692 LOCK_ZONE(zone); 1693 dns_zone_setview_helper(zone, view); 1694 UNLOCK_ZONE(zone); 1695 } 1696 1697 dns_view_t * 1698 dns_zone_getview(dns_zone_t *zone) { 1699 REQUIRE(DNS_ZONE_VALID(zone)); 1700 1701 return zone->view; 1702 } 1703 1704 void 1705 dns_zone_setviewcommit(dns_zone_t *zone) { 1706 REQUIRE(DNS_ZONE_VALID(zone)); 1707 1708 LOCK_ZONE(zone); 1709 if (zone->prev_view != NULL) { 1710 dns_view_weakdetach(&zone->prev_view); 1711 } 1712 if (inline_secure(zone)) { 1713 dns_zone_setviewcommit(zone->raw); 1714 } 1715 UNLOCK_ZONE(zone); 1716 } 1717 1718 void 1719 dns_zone_setviewrevert(dns_zone_t *zone) { 1720 REQUIRE(DNS_ZONE_VALID(zone)); 1721 1722 LOCK_ZONE(zone); 1723 if (zone->prev_view != NULL) { 1724 dns_zone_setview_helper(zone, zone->prev_view); 1725 dns_view_weakdetach(&zone->prev_view); 1726 } 1727 if (zone->catzs != NULL) { 1728 zone_catz_enable(zone, zone->catzs); 1729 } 1730 if (inline_secure(zone)) { 1731 dns_zone_setviewrevert(zone->raw); 1732 } 1733 UNLOCK_ZONE(zone); 1734 } 1735 1736 isc_result_t 1737 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) { 1738 isc_result_t result = ISC_R_SUCCESS; 1739 char namebuf[1024]; 1740 1741 REQUIRE(DNS_ZONE_VALID(zone)); 1742 REQUIRE(origin != NULL); 1743 1744 LOCK_ZONE(zone); 1745 INSIST(zone != zone->raw); 1746 if (dns_name_dynamic(&zone->origin)) { 1747 dns_name_free(&zone->origin, zone->mctx); 1748 dns_name_init(&zone->origin, NULL); 1749 } 1750 dns_name_dup(origin, zone->mctx, &zone->origin); 1751 1752 if (zone->strnamerd != NULL) { 1753 isc_mem_free(zone->mctx, zone->strnamerd); 1754 } 1755 if (zone->strname != NULL) { 1756 isc_mem_free(zone->mctx, zone->strname); 1757 } 1758 1759 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1760 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1761 zone_name_tostr(zone, namebuf, sizeof namebuf); 1762 zone->strname = isc_mem_strdup(zone->mctx, namebuf); 1763 1764 if (inline_secure(zone)) { 1765 result = dns_zone_setorigin(zone->raw, origin); 1766 } 1767 UNLOCK_ZONE(zone); 1768 return result; 1769 } 1770 1771 static isc_result_t 1772 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) { 1773 char *copy; 1774 1775 if (value != NULL) { 1776 copy = isc_mem_strdup(zone->mctx, value); 1777 } else { 1778 copy = NULL; 1779 } 1780 1781 if (*field != NULL) { 1782 isc_mem_free(zone->mctx, *field); 1783 } 1784 1785 *field = copy; 1786 return ISC_R_SUCCESS; 1787 } 1788 1789 isc_result_t 1790 dns_zone_setfile(dns_zone_t *zone, const char *file, dns_masterformat_t format, 1791 const dns_master_style_t *style) { 1792 isc_result_t result = ISC_R_SUCCESS; 1793 1794 REQUIRE(DNS_ZONE_VALID(zone)); 1795 REQUIRE(zone->stream == NULL); 1796 1797 LOCK_ZONE(zone); 1798 result = dns_zone_setstring(zone, &zone->masterfile, file); 1799 if (result == ISC_R_SUCCESS) { 1800 zone->masterformat = format; 1801 if (format == dns_masterformat_text) { 1802 zone->masterstyle = style; 1803 } 1804 result = default_journal(zone); 1805 } 1806 UNLOCK_ZONE(zone); 1807 1808 return result; 1809 } 1810 1811 const char * 1812 dns_zone_getfile(dns_zone_t *zone) { 1813 REQUIRE(DNS_ZONE_VALID(zone)); 1814 1815 return zone->masterfile; 1816 } 1817 1818 isc_result_t 1819 dns_zone_setstream(dns_zone_t *zone, const FILE *stream, 1820 dns_masterformat_t format, const dns_master_style_t *style) { 1821 isc_result_t result = ISC_R_SUCCESS; 1822 1823 REQUIRE(DNS_ZONE_VALID(zone)); 1824 REQUIRE(stream != NULL); 1825 REQUIRE(zone->masterfile == NULL); 1826 1827 LOCK_ZONE(zone); 1828 zone->stream = stream; 1829 zone->masterformat = format; 1830 if (format == dns_masterformat_text) { 1831 zone->masterstyle = style; 1832 } 1833 result = default_journal(zone); 1834 UNLOCK_ZONE(zone); 1835 1836 return result; 1837 } 1838 1839 dns_ttl_t 1840 dns_zone_getmaxttl(dns_zone_t *zone) { 1841 REQUIRE(DNS_ZONE_VALID(zone)); 1842 1843 return zone->maxttl; 1844 } 1845 1846 void 1847 dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) { 1848 REQUIRE(DNS_ZONE_VALID(zone)); 1849 1850 LOCK_ZONE(zone); 1851 if (maxttl != 0) { 1852 DNS_ZONE_SETOPTION(zone, DNS_ZONEOPT_CHECKTTL); 1853 } else { 1854 DNS_ZONE_CLROPTION(zone, DNS_ZONEOPT_CHECKTTL); 1855 } 1856 zone->maxttl = maxttl; 1857 UNLOCK_ZONE(zone); 1858 1859 return; 1860 } 1861 1862 static isc_result_t 1863 default_journal(dns_zone_t *zone) { 1864 isc_result_t result; 1865 char *journal; 1866 1867 REQUIRE(DNS_ZONE_VALID(zone)); 1868 REQUIRE(LOCKED_ZONE(zone)); 1869 1870 if (zone->masterfile != NULL) { 1871 /* Calculate string length including '\0'. */ 1872 int len = strlen(zone->masterfile) + sizeof(".jnl"); 1873 journal = isc_mem_allocate(zone->mctx, len); 1874 strlcpy(journal, zone->masterfile, len); 1875 strlcat(journal, ".jnl", len); 1876 } else { 1877 journal = NULL; 1878 } 1879 result = dns_zone_setstring(zone, &zone->journal, journal); 1880 if (journal != NULL) { 1881 isc_mem_free(zone->mctx, journal); 1882 } 1883 return result; 1884 } 1885 1886 isc_result_t 1887 dns_zone_setjournal(dns_zone_t *zone, const char *myjournal) { 1888 isc_result_t result = ISC_R_SUCCESS; 1889 1890 REQUIRE(DNS_ZONE_VALID(zone)); 1891 1892 LOCK_ZONE(zone); 1893 result = dns_zone_setstring(zone, &zone->journal, myjournal); 1894 UNLOCK_ZONE(zone); 1895 1896 return result; 1897 } 1898 1899 char * 1900 dns_zone_getjournal(dns_zone_t *zone) { 1901 REQUIRE(DNS_ZONE_VALID(zone)); 1902 1903 return zone->journal; 1904 } 1905 1906 /* 1907 * Return true iff the zone is "dynamic", in the sense that the zone's 1908 * master file (if any) is written by the server, rather than being 1909 * updated manually and read by the server. 1910 * 1911 * This is true for secondary zones, mirror zones, stub zones, key zones, 1912 * and zones that allow dynamic updates either by having an update 1913 * policy ("ssutable") or an "allow-update" ACL with a value other than 1914 * exactly "{ none; }". 1915 */ 1916 bool 1917 dns_zone_isdynamic(dns_zone_t *zone, bool ignore_freeze) { 1918 REQUIRE(DNS_ZONE_VALID(zone)); 1919 1920 if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror || 1921 zone->type == dns_zone_stub || zone->type == dns_zone_key || 1922 (zone->type == dns_zone_redirect && 1923 dns_remote_addresses(&zone->primaries) != NULL)) 1924 { 1925 return true; 1926 } 1927 1928 /* Inline zones are always dynamic. */ 1929 if (zone->type == dns_zone_primary && zone->raw != NULL) { 1930 return true; 1931 } 1932 1933 /* If !ignore_freeze, we need check whether updates are disabled. */ 1934 if (zone->type == dns_zone_primary && 1935 (!zone->update_disabled || ignore_freeze) && 1936 ((zone->ssutable != NULL) || 1937 (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)))) 1938 { 1939 return true; 1940 } 1941 1942 return false; 1943 } 1944 1945 /* 1946 * Set the response policy index and information for a zone. 1947 */ 1948 isc_result_t 1949 dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs, 1950 dns_rpz_num_t rpz_num) { 1951 /* 1952 * This must happen only once or be redundant. 1953 */ 1954 LOCK_ZONE(zone); 1955 if (zone->rpzs != NULL) { 1956 REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num); 1957 } else { 1958 REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM); 1959 dns_rpz_zones_attach(rpzs, &zone->rpzs); 1960 zone->rpz_num = rpz_num; 1961 } 1962 rpzs->defined |= DNS_RPZ_ZBIT(rpz_num); 1963 UNLOCK_ZONE(zone); 1964 1965 return ISC_R_SUCCESS; 1966 } 1967 1968 dns_rpz_num_t 1969 dns_zone_get_rpz_num(dns_zone_t *zone) { 1970 return zone->rpz_num; 1971 } 1972 1973 /* 1974 * If a zone is a response policy zone, mark its new database. 1975 */ 1976 void 1977 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) { 1978 if (zone->rpz_num == DNS_RPZ_INVALID_NUM) { 1979 return; 1980 } 1981 REQUIRE(zone->rpzs != NULL); 1982 dns_rpz_dbupdate_register(db, zone->rpzs->zones[zone->rpz_num]); 1983 } 1984 1985 static void 1986 dns_zone_rpz_disable_db(dns_zone_t *zone, dns_db_t *db) { 1987 if (zone->rpz_num == DNS_RPZ_INVALID_NUM) { 1988 return; 1989 } 1990 REQUIRE(zone->rpzs != NULL); 1991 dns_rpz_dbupdate_unregister(db, zone->rpzs->zones[zone->rpz_num]); 1992 } 1993 1994 /* 1995 * If a zone is a catalog zone, attach it to update notification in database. 1996 */ 1997 void 1998 dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) { 1999 REQUIRE(DNS_ZONE_VALID(zone)); 2000 REQUIRE(db != NULL); 2001 2002 if (zone->catzs != NULL) { 2003 dns_catz_dbupdate_register(db, zone->catzs); 2004 } 2005 } 2006 2007 static void 2008 dns_zone_catz_disable_db(dns_zone_t *zone, dns_db_t *db) { 2009 REQUIRE(DNS_ZONE_VALID(zone)); 2010 REQUIRE(db != NULL); 2011 2012 if (zone->catzs != NULL) { 2013 dns_catz_dbupdate_unregister(db, zone->catzs); 2014 } 2015 } 2016 2017 static void 2018 zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) { 2019 REQUIRE(DNS_ZONE_VALID(zone)); 2020 REQUIRE(catzs != NULL); 2021 2022 INSIST(zone->catzs == NULL || zone->catzs == catzs); 2023 dns_catz_catzs_set_view(catzs, zone->view); 2024 if (zone->catzs == NULL) { 2025 dns_catz_zones_attach(catzs, &zone->catzs); 2026 } 2027 } 2028 2029 void 2030 dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) { 2031 REQUIRE(DNS_ZONE_VALID(zone)); 2032 2033 LOCK_ZONE(zone); 2034 zone_catz_enable(zone, catzs); 2035 UNLOCK_ZONE(zone); 2036 } 2037 2038 static void 2039 zone_catz_disable(dns_zone_t *zone) { 2040 REQUIRE(DNS_ZONE_VALID(zone)); 2041 2042 if (zone->catzs != NULL) { 2043 if (zone->db != NULL) { 2044 dns_zone_catz_disable_db(zone, zone->db); 2045 } 2046 dns_catz_zones_detach(&zone->catzs); 2047 } 2048 } 2049 2050 void 2051 dns_zone_catz_disable(dns_zone_t *zone) { 2052 REQUIRE(DNS_ZONE_VALID(zone)); 2053 2054 LOCK_ZONE(zone); 2055 zone_catz_disable(zone); 2056 UNLOCK_ZONE(zone); 2057 } 2058 2059 bool 2060 dns_zone_catz_is_enabled(dns_zone_t *zone) { 2061 REQUIRE(DNS_ZONE_VALID(zone)); 2062 2063 return zone->catzs != NULL; 2064 } 2065 2066 /* 2067 * Set catalog zone ownership of the zone 2068 */ 2069 void 2070 dns_zone_set_parentcatz(dns_zone_t *zone, dns_catz_zone_t *catz) { 2071 REQUIRE(DNS_ZONE_VALID(zone)); 2072 REQUIRE(catz != NULL); 2073 LOCK_ZONE(zone); 2074 INSIST(zone->parentcatz == NULL || zone->parentcatz == catz); 2075 zone->parentcatz = catz; 2076 UNLOCK_ZONE(zone); 2077 } 2078 2079 dns_catz_zone_t * 2080 dns_zone_get_parentcatz(dns_zone_t *zone) { 2081 REQUIRE(DNS_ZONE_VALID(zone)); 2082 2083 dns_catz_zone_t *parentcatz = NULL; 2084 2085 LOCK_ZONE(zone); 2086 parentcatz = zone->parentcatz; 2087 UNLOCK_ZONE(zone); 2088 2089 return parentcatz; 2090 } 2091 2092 static bool 2093 zone_touched(dns_zone_t *zone) { 2094 isc_result_t result; 2095 isc_time_t modtime; 2096 dns_include_t *include; 2097 2098 REQUIRE(DNS_ZONE_VALID(zone)); 2099 2100 result = isc_file_getmodtime(zone->masterfile, &modtime); 2101 if (result != ISC_R_SUCCESS || 2102 isc_time_compare(&modtime, &zone->loadtime) > 0) 2103 { 2104 return true; 2105 } 2106 2107 for (include = ISC_LIST_HEAD(zone->includes); include != NULL; 2108 include = ISC_LIST_NEXT(include, link)) 2109 { 2110 result = isc_file_getmodtime(include->name, &modtime); 2111 if (result != ISC_R_SUCCESS || 2112 isc_time_compare(&modtime, &include->filetime) > 0) 2113 { 2114 return true; 2115 } 2116 } 2117 2118 return false; 2119 } 2120 2121 /* 2122 * Note: when dealing with inline-signed zones, external callers will always 2123 * call zone_load() for the secure zone; zone_load() calls itself recursively 2124 * in order to load the raw zone. 2125 */ 2126 static isc_result_t 2127 zone_load(dns_zone_t *zone, unsigned int flags, bool locked) { 2128 isc_result_t result; 2129 isc_time_t now; 2130 isc_time_t loadtime; 2131 dns_db_t *db = NULL; 2132 bool rbt, hasraw, is_dynamic; 2133 2134 REQUIRE(DNS_ZONE_VALID(zone)); 2135 2136 if (!locked) { 2137 LOCK_ZONE(zone); 2138 } 2139 2140 INSIST(zone != zone->raw); 2141 hasraw = inline_secure(zone); 2142 if (hasraw) { 2143 /* 2144 * We are trying to load an inline-signed zone. First call 2145 * self recursively to try loading the raw version of the zone. 2146 * Assuming the raw zone file is readable, there are two 2147 * possibilities: 2148 * 2149 * a) the raw zone was not yet loaded and thus it will be 2150 * loaded now, synchronously; if this succeeds, a 2151 * subsequent attempt to load the signed zone file will 2152 * take place and thus zone_postload() will be called 2153 * twice: first for the raw zone and then for the secure 2154 * zone; the latter call will take care of syncing the raw 2155 * version with the secure version, 2156 * 2157 * b) the raw zone was already loaded and we are trying to 2158 * reload it, which will happen asynchronously; this means 2159 * zone_postload() will only be called for the raw zone 2160 * because "result" returned by the zone_load() call below 2161 * will not be ISC_R_SUCCESS but rather DNS_R_CONTINUE; 2162 * zone_postload() called for the raw zone will take care 2163 * of syncing the raw version with the secure version. 2164 */ 2165 result = zone_load(zone->raw, flags, false); 2166 if (result != ISC_R_SUCCESS) { 2167 if (!locked) { 2168 UNLOCK_ZONE(zone); 2169 } 2170 return result; 2171 } 2172 LOCK_ZONE(zone->raw); 2173 } 2174 2175 now = isc_time_now(); 2176 2177 INSIST(zone->type != dns_zone_none); 2178 2179 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { 2180 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) { 2181 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 2182 } 2183 result = DNS_R_CONTINUE; 2184 goto cleanup; 2185 } 2186 2187 INSIST(zone->db_argc >= 1); 2188 2189 rbt = strcmp(zone->db_argv[0], ZONEDB_DEFAULT) == 0; 2190 2191 if (zone->db != NULL && zone->masterfile == NULL && rbt) { 2192 /* 2193 * The zone has no master file configured. 2194 */ 2195 result = ISC_R_SUCCESS; 2196 goto cleanup; 2197 } 2198 2199 is_dynamic = dns_zone_isdynamic(zone, false); 2200 if (zone->db != NULL && is_dynamic) { 2201 /* 2202 * This is a secondary, stub, or dynamically updated zone 2203 * being reloaded. Do nothing - the database we already 2204 * have is guaranteed to be up-to-date. 2205 */ 2206 if (zone->type == dns_zone_primary && !hasraw) { 2207 result = DNS_R_DYNAMIC; 2208 } else { 2209 result = ISC_R_SUCCESS; 2210 } 2211 goto cleanup; 2212 } 2213 2214 /* 2215 * Store the current time before the zone is loaded, so that if the 2216 * file changes between the time of the load and the time that 2217 * zone->loadtime is set, then the file will still be reloaded 2218 * the next time dns_zone_load is called. 2219 */ 2220 loadtime = isc_time_now(); 2221 2222 /* 2223 * Don't do the load if the file that stores the zone is older 2224 * than the last time the zone was loaded. If the zone has not 2225 * been loaded yet, zone->loadtime will be the epoch. 2226 */ 2227 if (zone->masterfile != NULL) { 2228 isc_time_t filetime; 2229 2230 /* 2231 * The file is already loaded. If we are just doing a 2232 * "rndc reconfig", we are done. 2233 */ 2234 if (!isc_time_isepoch(&zone->loadtime) && 2235 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) 2236 { 2237 result = ISC_R_SUCCESS; 2238 goto cleanup; 2239 } 2240 2241 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 2242 !zone_touched(zone)) 2243 { 2244 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2245 ISC_LOG_DEBUG(1), 2246 "skipping load: master file " 2247 "older than last load"); 2248 result = DNS_R_UPTODATE; 2249 goto cleanup; 2250 } 2251 2252 /* 2253 * If the file modification time is in the past 2254 * set loadtime to that value. 2255 */ 2256 result = isc_file_getmodtime(zone->masterfile, &filetime); 2257 if (result == ISC_R_SUCCESS && 2258 isc_time_compare(&loadtime, &filetime) > 0) 2259 { 2260 loadtime = filetime; 2261 } 2262 } 2263 2264 /* 2265 * Built in zones (with the exception of empty zones) don't need 2266 * to be reloaded. 2267 */ 2268 if (zone->type == dns_zone_primary && 2269 strcmp(zone->db_argv[0], "_builtin") == 0 && 2270 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) && 2271 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 2272 { 2273 result = ISC_R_SUCCESS; 2274 goto cleanup; 2275 } 2276 2277 /* 2278 * Zones associated with a DLZ don't need to be loaded either, 2279 * but we need to associate the database with the zone object. 2280 */ 2281 if (strcmp(zone->db_argv[0], "dlz") == 0) { 2282 dns_dlzdb_t *dlzdb; 2283 dns_dlzfindzone_t findzone; 2284 2285 for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched); 2286 dlzdb != NULL; dlzdb = ISC_LIST_NEXT(dlzdb, link)) 2287 { 2288 INSIST(DNS_DLZ_VALID(dlzdb)); 2289 if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0) { 2290 break; 2291 } 2292 } 2293 2294 if (dlzdb == NULL) { 2295 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2296 ISC_LOG_ERROR, 2297 "DLZ %s does not exist or is set " 2298 "to 'search yes;'", 2299 zone->db_argv[1]); 2300 result = ISC_R_NOTFOUND; 2301 goto cleanup; 2302 } 2303 2304 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 2305 /* ask SDLZ driver if the zone is supported */ 2306 findzone = dlzdb->implementation->methods->findzone; 2307 result = (*findzone)(dlzdb->implementation->driverarg, 2308 dlzdb->dbdata, dlzdb->mctx, 2309 zone->view->rdclass, &zone->origin, NULL, 2310 NULL, &db); 2311 if (result != ISC_R_NOTFOUND) { 2312 if (zone->db != NULL) { 2313 zone_detachdb(zone); 2314 } 2315 zone_attachdb(zone, db); 2316 dns_db_detach(&db); 2317 result = ISC_R_SUCCESS; 2318 } 2319 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 2320 2321 if (result == ISC_R_SUCCESS) { 2322 if (dlzdb->configure_callback == NULL) { 2323 goto cleanup; 2324 } 2325 2326 result = (*dlzdb->configure_callback)(zone->view, dlzdb, 2327 zone); 2328 if (result != ISC_R_SUCCESS) { 2329 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2330 ISC_LOG_ERROR, 2331 "DLZ configuration callback: %s", 2332 isc_result_totext(result)); 2333 } 2334 } 2335 goto cleanup; 2336 } 2337 2338 if ((zone->type == dns_zone_secondary || 2339 zone->type == dns_zone_mirror || zone->type == dns_zone_stub || 2340 (zone->type == dns_zone_redirect && 2341 dns_remote_addresses(&zone->primaries) != NULL)) && 2342 rbt) 2343 { 2344 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FIRSTREFRESH); 2345 2346 if (zone->stream == NULL && 2347 (zone->masterfile == NULL || 2348 !isc_file_exists(zone->masterfile))) 2349 { 2350 if (zone->masterfile != NULL) { 2351 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2352 ISC_LOG_DEBUG(1), 2353 "no master file"); 2354 } 2355 zone->refreshtime = now; 2356 if (zone->loop != NULL) { 2357 zone_settimer(zone, &now); 2358 } 2359 result = ISC_R_SUCCESS; 2360 goto cleanup; 2361 } 2362 } 2363 2364 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1), 2365 "starting load"); 2366 2367 result = dns_zone_makedb(zone, &db); 2368 if (result != ISC_R_SUCCESS) { 2369 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 2370 "loading zone: creating database: %s", 2371 isc_result_totext(result)); 2372 goto cleanup; 2373 } 2374 2375 if (!dns_db_ispersistent(db)) { 2376 if (zone->masterfile != NULL || zone->stream != NULL) { 2377 result = zone_startload(db, zone, loadtime); 2378 } else { 2379 result = DNS_R_NOMASTERFILE; 2380 if (zone->type == dns_zone_primary || 2381 (zone->type == dns_zone_redirect && 2382 dns_remote_addresses(&zone->primaries) == NULL)) 2383 { 2384 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2385 ISC_LOG_ERROR, 2386 "loading zone: " 2387 "no master file configured"); 2388 goto cleanup; 2389 } 2390 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2391 ISC_LOG_INFO, 2392 "loading zone: " 2393 "no master file configured: continuing"); 2394 } 2395 } 2396 2397 if (result == DNS_R_CONTINUE) { 2398 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING); 2399 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) { 2400 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 2401 } 2402 goto cleanup; 2403 } 2404 2405 result = zone_postload(zone, db, loadtime, result); 2406 2407 cleanup: 2408 if (hasraw) { 2409 UNLOCK_ZONE(zone->raw); 2410 } 2411 if (!locked) { 2412 UNLOCK_ZONE(zone); 2413 } 2414 if (db != NULL) { 2415 dns_db_detach(&db); 2416 } 2417 return result; 2418 } 2419 2420 isc_result_t 2421 dns_zone_load(dns_zone_t *zone, bool newonly) { 2422 return zone_load(zone, newonly ? DNS_ZONELOADFLAG_NOSTAT : 0, false); 2423 } 2424 2425 static void 2426 zone_asyncload(void *arg) { 2427 dns_asyncload_t *asl = arg; 2428 dns_zone_t *zone = asl->zone; 2429 isc_result_t result; 2430 2431 REQUIRE(DNS_ZONE_VALID(zone)); 2432 2433 LOCK_ZONE(zone); 2434 result = zone_load(zone, asl->flags, true); 2435 if (result != DNS_R_CONTINUE) { 2436 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); 2437 } 2438 UNLOCK_ZONE(zone); 2439 2440 /* Inform the zone table we've finished loading */ 2441 if (asl->loaded != NULL) { 2442 asl->loaded(asl->loaded_arg); 2443 } 2444 2445 isc_mem_put(zone->mctx, asl, sizeof(*asl)); 2446 dns_zone_idetach(&zone); 2447 } 2448 2449 isc_result_t 2450 dns_zone_asyncload(dns_zone_t *zone, bool newonly, dns_zt_callback_t *done, 2451 void *arg) { 2452 dns_asyncload_t *asl = NULL; 2453 2454 REQUIRE(DNS_ZONE_VALID(zone)); 2455 2456 if (zone->zmgr == NULL) { 2457 return ISC_R_FAILURE; 2458 } 2459 2460 /* If we already have a load pending, stop now */ 2461 LOCK_ZONE(zone); 2462 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) { 2463 UNLOCK_ZONE(zone); 2464 return ISC_R_ALREADYRUNNING; 2465 } 2466 2467 asl = isc_mem_get(zone->mctx, sizeof(*asl)); 2468 2469 asl->zone = NULL; 2470 asl->flags = newonly ? DNS_ZONELOADFLAG_NOSTAT : 0; 2471 asl->loaded = done; 2472 asl->loaded_arg = arg; 2473 2474 zone_iattach(zone, &asl->zone); 2475 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING); 2476 isc_async_run(zone->loop, zone_asyncload, asl); 2477 UNLOCK_ZONE(zone); 2478 2479 return ISC_R_SUCCESS; 2480 } 2481 2482 bool 2483 dns__zone_loadpending(dns_zone_t *zone) { 2484 REQUIRE(DNS_ZONE_VALID(zone)); 2485 2486 return DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING); 2487 } 2488 2489 isc_result_t 2490 dns_zone_loadandthaw(dns_zone_t *zone) { 2491 isc_result_t result; 2492 2493 if (inline_raw(zone)) { 2494 result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW, false); 2495 } else { 2496 /* 2497 * When thawing a zone, we don't know what changes 2498 * have been made. If we do DNSSEC maintenance on this 2499 * zone, schedule a full sign for this zone. 2500 */ 2501 if (zone->type == dns_zone_primary && 2502 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 2503 { 2504 DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN); 2505 } 2506 result = zone_load(zone, DNS_ZONELOADFLAG_THAW, false); 2507 } 2508 2509 switch (result) { 2510 case DNS_R_CONTINUE: 2511 /* Deferred thaw. */ 2512 break; 2513 case DNS_R_UPTODATE: 2514 case ISC_R_SUCCESS: 2515 case DNS_R_SEENINCLUDE: 2516 zone->update_disabled = false; 2517 break; 2518 case DNS_R_NOMASTERFILE: 2519 zone->update_disabled = false; 2520 break; 2521 default: 2522 /* Error, remain in disabled state. */ 2523 break; 2524 } 2525 return result; 2526 } 2527 2528 static unsigned int 2529 get_primary_options(dns_zone_t *zone) { 2530 unsigned int options; 2531 2532 options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN; 2533 if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror || 2534 (zone->type == dns_zone_redirect && 2535 dns_remote_addresses(&zone->primaries) == NULL)) 2536 { 2537 options |= DNS_MASTER_SECONDARY; 2538 } 2539 if (zone->type == dns_zone_key) { 2540 options |= DNS_MASTER_KEY; 2541 } 2542 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) { 2543 options |= DNS_MASTER_CHECKNS; 2544 } 2545 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) { 2546 options |= DNS_MASTER_FATALNS; 2547 } 2548 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) { 2549 options |= DNS_MASTER_CHECKNAMES; 2550 } 2551 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) { 2552 options |= DNS_MASTER_CHECKNAMESFAIL; 2553 } 2554 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) { 2555 options |= DNS_MASTER_CHECKMX; 2556 } 2557 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) { 2558 options |= DNS_MASTER_CHECKMXFAIL; 2559 } 2560 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) { 2561 options |= DNS_MASTER_CHECKWILDCARD; 2562 } 2563 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKTTL)) { 2564 options |= DNS_MASTER_CHECKTTL; 2565 } 2566 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSVCB)) { 2567 options |= DNS_MASTER_CHECKSVCB; 2568 } 2569 2570 return options; 2571 } 2572 2573 static void 2574 zone_registerinclude(const char *filename, void *arg) { 2575 isc_result_t result; 2576 dns_zone_t *zone = (dns_zone_t *)arg; 2577 dns_include_t *inc = NULL; 2578 2579 REQUIRE(DNS_ZONE_VALID(zone)); 2580 2581 if (filename == NULL) { 2582 return; 2583 } 2584 2585 /* 2586 * Suppress duplicates. 2587 */ 2588 for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; 2589 inc = ISC_LIST_NEXT(inc, link)) 2590 { 2591 if (strcmp(filename, inc->name) == 0) { 2592 return; 2593 } 2594 } 2595 2596 inc = isc_mem_get(zone->mctx, sizeof(dns_include_t)); 2597 inc->name = isc_mem_strdup(zone->mctx, filename); 2598 ISC_LINK_INIT(inc, link); 2599 2600 result = isc_file_getmodtime(filename, &inc->filetime); 2601 if (result != ISC_R_SUCCESS) { 2602 isc_time_settoepoch(&inc->filetime); 2603 } 2604 2605 ISC_LIST_APPEND(zone->newincludes, inc, link); 2606 } 2607 2608 static void 2609 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) { 2610 isc_result_t result; 2611 unsigned int soacount; 2612 2613 LOCK(&raw->lock); 2614 if (raw->db != NULL) { 2615 result = zone_get_from_db(raw, raw->db, NULL, &soacount, NULL, 2616 &rawdata->sourceserial, NULL, NULL, 2617 NULL, NULL, NULL); 2618 if (result == ISC_R_SUCCESS && soacount > 0U) { 2619 rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET; 2620 } 2621 } 2622 UNLOCK(&raw->lock); 2623 } 2624 2625 /* 2626 * Save the raw serial number for inline-signing zones. 2627 * (XXX: Other information from the header will be used 2628 * for other purposes in the future, but for now this is 2629 * all we're interested in.) 2630 */ 2631 static void 2632 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { 2633 if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0) { 2634 return; 2635 } 2636 2637 zone->sourceserial = header->sourceserial; 2638 zone->sourceserialset = true; 2639 } 2640 2641 void 2642 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { 2643 if (zone == NULL) { 2644 return; 2645 } 2646 2647 LOCK_ZONE(zone); 2648 zone_setrawdata(zone, header); 2649 UNLOCK_ZONE(zone); 2650 } 2651 2652 static isc_result_t 2653 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { 2654 isc_result_t result; 2655 isc_result_t tresult; 2656 unsigned int options; 2657 dns_load_t *load = isc_mem_get(zone->mctx, sizeof(*load)); 2658 2659 ENTER; 2660 2661 *load = (dns_load_t){ 2662 .loadtime = loadtime, 2663 }; 2664 2665 dns_zone_rpz_enable_db(zone, db); 2666 dns_zone_catz_enable_db(zone, db); 2667 2668 options = get_primary_options(zone); 2669 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) { 2670 options |= DNS_MASTER_MANYERRORS; 2671 } 2672 2673 zone_iattach(zone, &load->zone); 2674 dns_db_attach(db, &load->db); 2675 2676 dns_rdatacallbacks_init(&load->callbacks); 2677 load->callbacks.rawdata = zone_setrawdata; 2678 zone_iattach(zone, &load->callbacks.zone); 2679 2680 result = dns_db_beginload(db, &load->callbacks); 2681 if (result != ISC_R_SUCCESS) { 2682 goto cleanup; 2683 } 2684 2685 if (zone->zmgr != NULL && zone->db != NULL) { 2686 result = dns_master_loadfileasync( 2687 zone->masterfile, dns_db_origin(db), dns_db_origin(db), 2688 zone->rdclass, options, 0, &load->callbacks, zone->loop, 2689 zone_loaddone, load, &zone->loadctx, 2690 zone_registerinclude, zone, zone->mctx, 2691 zone->masterformat, zone->maxttl); 2692 if (result != ISC_R_SUCCESS) { 2693 goto cleanup; 2694 } 2695 2696 return DNS_R_CONTINUE; 2697 } else if (zone->stream != NULL) { 2698 FILE *stream = UNCONST(zone->stream); 2699 result = dns_master_loadstream( 2700 stream, &zone->origin, &zone->origin, zone->rdclass, 2701 options, &load->callbacks, zone->mctx); 2702 } else { 2703 result = dns_master_loadfile( 2704 zone->masterfile, &zone->origin, &zone->origin, 2705 zone->rdclass, options, 0, &load->callbacks, 2706 zone_registerinclude, zone, zone->mctx, 2707 zone->masterformat, zone->maxttl); 2708 } 2709 2710 cleanup: 2711 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { 2712 dns_zone_rpz_disable_db(zone, load->db); 2713 dns_zone_catz_disable_db(zone, load->db); 2714 } 2715 2716 tresult = dns_db_endload(db, &load->callbacks); 2717 if (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) { 2718 result = tresult; 2719 } 2720 2721 zone_idetach(&load->callbacks.zone); 2722 dns_db_detach(&load->db); 2723 zone_idetach(&load->zone); 2724 2725 isc_mem_put(zone->mctx, load, sizeof(*load)); 2726 return result; 2727 } 2728 2729 static bool 2730 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2731 dns_name_t *owner) { 2732 isc_result_t result; 2733 char ownerbuf[DNS_NAME_FORMATSIZE]; 2734 char namebuf[DNS_NAME_FORMATSIZE]; 2735 char altbuf[DNS_NAME_FORMATSIZE]; 2736 dns_fixedname_t fixed; 2737 dns_name_t *foundname; 2738 int level; 2739 2740 /* 2741 * "." means the services does not exist. 2742 */ 2743 if (dns_name_equal(name, dns_rootname)) { 2744 return true; 2745 } 2746 2747 /* 2748 * Outside of zone. 2749 */ 2750 if (!dns_name_issubdomain(name, &zone->origin)) { 2751 if (zone->checkmx != NULL) { 2752 return (zone->checkmx)(zone, name, owner); 2753 } 2754 return true; 2755 } 2756 2757 if (zone->type == dns_zone_primary) { 2758 level = ISC_LOG_ERROR; 2759 } else { 2760 level = ISC_LOG_WARNING; 2761 } 2762 2763 foundname = dns_fixedname_initname(&fixed); 2764 2765 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, 2766 foundname, NULL, NULL); 2767 if (result == ISC_R_SUCCESS) { 2768 return true; 2769 } 2770 2771 if (result == DNS_R_NXRRSET) { 2772 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0, 2773 NULL, foundname, NULL, NULL); 2774 if (result == ISC_R_SUCCESS) { 2775 return true; 2776 } 2777 } 2778 2779 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2780 dns_name_format(name, namebuf, sizeof namebuf); 2781 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2782 result == DNS_R_EMPTYNAME) 2783 { 2784 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) { 2785 level = ISC_LOG_WARNING; 2786 } 2787 dns_zone_log(zone, level, 2788 "%s/MX '%s' has no address records (A or AAAA)", 2789 ownerbuf, namebuf); 2790 return (level == ISC_LOG_WARNING) ? true : false; 2791 } 2792 2793 if (result == DNS_R_CNAME) { 2794 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 2795 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2796 { 2797 level = ISC_LOG_WARNING; 2798 } 2799 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { 2800 dns_zone_log(zone, level, 2801 "%s/MX '%s' is a CNAME (illegal)", 2802 ownerbuf, namebuf); 2803 } 2804 return (level == ISC_LOG_WARNING) ? true : false; 2805 } 2806 2807 if (result == DNS_R_DNAME) { 2808 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 2809 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2810 { 2811 level = ISC_LOG_WARNING; 2812 } 2813 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { 2814 dns_name_format(foundname, altbuf, sizeof altbuf); 2815 dns_zone_log(zone, level, 2816 "%s/MX '%s' is below a DNAME" 2817 " '%s' (illegal)", 2818 ownerbuf, namebuf, altbuf); 2819 } 2820 return (level == ISC_LOG_WARNING) ? true : false; 2821 } 2822 2823 if (zone->checkmx != NULL && result == DNS_R_DELEGATION) { 2824 return (zone->checkmx)(zone, name, owner); 2825 } 2826 2827 return true; 2828 } 2829 2830 static bool 2831 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2832 dns_name_t *owner) { 2833 isc_result_t result; 2834 char ownerbuf[DNS_NAME_FORMATSIZE]; 2835 char namebuf[DNS_NAME_FORMATSIZE]; 2836 char altbuf[DNS_NAME_FORMATSIZE]; 2837 dns_fixedname_t fixed; 2838 dns_name_t *foundname; 2839 int level; 2840 2841 /* 2842 * "." means the services does not exist. 2843 */ 2844 if (dns_name_equal(name, dns_rootname)) { 2845 return true; 2846 } 2847 2848 /* 2849 * Outside of zone. 2850 */ 2851 if (!dns_name_issubdomain(name, &zone->origin)) { 2852 if (zone->checksrv != NULL) { 2853 return (zone->checksrv)(zone, name, owner); 2854 } 2855 return true; 2856 } 2857 2858 if (zone->type == dns_zone_primary) { 2859 level = ISC_LOG_ERROR; 2860 } else { 2861 level = ISC_LOG_WARNING; 2862 } 2863 2864 foundname = dns_fixedname_initname(&fixed); 2865 2866 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, 2867 foundname, NULL, NULL); 2868 if (result == ISC_R_SUCCESS) { 2869 return true; 2870 } 2871 2872 if (result == DNS_R_NXRRSET) { 2873 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0, 2874 NULL, foundname, NULL, NULL); 2875 if (result == ISC_R_SUCCESS) { 2876 return true; 2877 } 2878 } 2879 2880 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2881 dns_name_format(name, namebuf, sizeof namebuf); 2882 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2883 result == DNS_R_EMPTYNAME) 2884 { 2885 dns_zone_log(zone, level, 2886 "%s/SRV '%s' has no address records (A or AAAA)", 2887 ownerbuf, namebuf); 2888 /* XXX950 make fatal for 9.5.0. */ 2889 return true; 2890 } 2891 2892 if (result == DNS_R_CNAME) { 2893 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 2894 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2895 { 2896 level = ISC_LOG_WARNING; 2897 } 2898 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { 2899 dns_zone_log(zone, level, 2900 "%s/SRV '%s' is a CNAME (illegal)", 2901 ownerbuf, namebuf); 2902 } 2903 return (level == ISC_LOG_WARNING) ? true : false; 2904 } 2905 2906 if (result == DNS_R_DNAME) { 2907 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 2908 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2909 { 2910 level = ISC_LOG_WARNING; 2911 } 2912 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { 2913 dns_name_format(foundname, altbuf, sizeof altbuf); 2914 dns_zone_log(zone, level, 2915 "%s/SRV '%s' is below a " 2916 "DNAME '%s' (illegal)", 2917 ownerbuf, namebuf, altbuf); 2918 } 2919 return (level == ISC_LOG_WARNING) ? true : false; 2920 } 2921 2922 if (zone->checksrv != NULL && result == DNS_R_DELEGATION) { 2923 return (zone->checksrv)(zone, name, owner); 2924 } 2925 2926 return true; 2927 } 2928 2929 static bool 2930 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2931 dns_name_t *owner) { 2932 bool answer = true; 2933 isc_result_t result, tresult; 2934 char ownerbuf[DNS_NAME_FORMATSIZE]; 2935 char namebuf[DNS_NAME_FORMATSIZE]; 2936 char altbuf[DNS_NAME_FORMATSIZE]; 2937 dns_fixedname_t fixed; 2938 dns_name_t *foundname; 2939 dns_rdataset_t a; 2940 dns_rdataset_t aaaa; 2941 int level; 2942 2943 /* 2944 * Outside of zone. 2945 */ 2946 if (!dns_name_issubdomain(name, &zone->origin)) { 2947 if (zone->checkns != NULL) { 2948 return (zone->checkns)(zone, name, owner, NULL, NULL); 2949 } 2950 return true; 2951 } 2952 2953 if (zone->type == dns_zone_primary) { 2954 level = ISC_LOG_ERROR; 2955 } else { 2956 level = ISC_LOG_WARNING; 2957 } 2958 2959 foundname = dns_fixedname_initname(&fixed); 2960 dns_rdataset_init(&a); 2961 dns_rdataset_init(&aaaa); 2962 2963 /* 2964 * Perform a regular lookup to catch DNAME records then look 2965 * for glue. 2966 */ 2967 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, 2968 foundname, &a, NULL); 2969 switch (result) { 2970 case ISC_R_SUCCESS: 2971 case DNS_R_DNAME: 2972 case DNS_R_CNAME: 2973 break; 2974 default: 2975 if (dns_rdataset_isassociated(&a)) { 2976 dns_rdataset_disassociate(&a); 2977 } 2978 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 2979 DNS_DBFIND_GLUEOK, 0, NULL, foundname, &a, 2980 NULL); 2981 } 2982 if (result == ISC_R_SUCCESS) { 2983 dns_rdataset_disassociate(&a); 2984 return true; 2985 } else if (result == DNS_R_DELEGATION) { 2986 dns_rdataset_disassociate(&a); 2987 } 2988 2989 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION || 2990 result == DNS_R_GLUE) 2991 { 2992 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 2993 DNS_DBFIND_GLUEOK, 0, NULL, foundname, 2994 &aaaa, NULL); 2995 if (tresult == ISC_R_SUCCESS) { 2996 if (dns_rdataset_isassociated(&a)) { 2997 dns_rdataset_disassociate(&a); 2998 } 2999 dns_rdataset_disassociate(&aaaa); 3000 return true; 3001 } 3002 if (tresult == DNS_R_DELEGATION || tresult == DNS_R_DNAME) { 3003 dns_rdataset_disassociate(&aaaa); 3004 } 3005 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) { 3006 /* 3007 * Check glue against child zone. 3008 */ 3009 if (zone->checkns != NULL) { 3010 answer = (zone->checkns)(zone, name, owner, &a, 3011 &aaaa); 3012 } 3013 if (dns_rdataset_isassociated(&a)) { 3014 dns_rdataset_disassociate(&a); 3015 } 3016 if (dns_rdataset_isassociated(&aaaa)) { 3017 dns_rdataset_disassociate(&aaaa); 3018 } 3019 return answer; 3020 } 3021 } 3022 3023 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 3024 dns_name_format(name, namebuf, sizeof namebuf); 3025 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 3026 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) 3027 { 3028 const char *what; 3029 bool required = false; 3030 if (dns_name_issubdomain(name, owner)) { 3031 what = "REQUIRED GLUE "; 3032 required = true; 3033 } else if (result == DNS_R_DELEGATION) { 3034 what = "SIBLING GLUE "; 3035 } else { 3036 what = ""; 3037 } 3038 3039 if (result != DNS_R_DELEGATION || required || 3040 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) 3041 { 3042 dns_zone_log(zone, level, 3043 "%s/NS '%s' has no %s" 3044 "address records (A or AAAA)", 3045 ownerbuf, namebuf, what); 3046 /* 3047 * Log missing address record. 3048 */ 3049 if (result == DNS_R_DELEGATION && zone->checkns != NULL) 3050 { 3051 (void)(zone->checkns)(zone, name, owner, &a, 3052 &aaaa); 3053 } 3054 /* XXX950 make fatal for 9.5.0. */ 3055 /* answer = false; */ 3056 } 3057 } else if (result == DNS_R_CNAME) { 3058 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)", 3059 ownerbuf, namebuf); 3060 /* XXX950 make fatal for 9.5.0. */ 3061 /* answer = false; */ 3062 } else if (result == DNS_R_DNAME) { 3063 dns_name_format(foundname, altbuf, sizeof altbuf); 3064 dns_zone_log(zone, level, 3065 "%s/NS '%s' is below a DNAME '%s' (illegal)", 3066 ownerbuf, namebuf, altbuf); 3067 /* XXX950 make fatal for 9.5.0. */ 3068 /* answer = false; */ 3069 } 3070 3071 if (dns_rdataset_isassociated(&a)) { 3072 dns_rdataset_disassociate(&a); 3073 } 3074 if (dns_rdataset_isassociated(&aaaa)) { 3075 dns_rdataset_disassociate(&aaaa); 3076 } 3077 return answer; 3078 } 3079 3080 static bool 3081 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner, 3082 dns_rdataset_t *rdataset) { 3083 dns_rdataset_t tmprdataset; 3084 isc_result_t result; 3085 bool answer = true; 3086 bool format = true; 3087 int level = ISC_LOG_WARNING; 3088 char ownerbuf[DNS_NAME_FORMATSIZE]; 3089 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 3090 unsigned int count1 = 0; 3091 3092 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL)) { 3093 level = ISC_LOG_ERROR; 3094 } 3095 3096 dns_rdataset_init(&tmprdataset); 3097 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 3098 result = dns_rdataset_next(rdataset)) 3099 { 3100 dns_rdata_t rdata1 = DNS_RDATA_INIT; 3101 unsigned int count2 = 0; 3102 3103 count1++; 3104 dns_rdataset_current(rdataset, &rdata1); 3105 dns_rdataset_clone(rdataset, &tmprdataset); 3106 for (result = dns_rdataset_first(&tmprdataset); 3107 result == ISC_R_SUCCESS; 3108 result = dns_rdataset_next(&tmprdataset)) 3109 { 3110 dns_rdata_t rdata2 = DNS_RDATA_INIT; 3111 count2++; 3112 if (count1 >= count2) { 3113 continue; 3114 } 3115 dns_rdataset_current(&tmprdataset, &rdata2); 3116 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) { 3117 if (format) { 3118 dns_name_format(owner, ownerbuf, 3119 sizeof ownerbuf); 3120 dns_rdatatype_format(rdata1.type, 3121 typebuf, 3122 sizeof(typebuf)); 3123 format = false; 3124 } 3125 dns_zone_log(zone, level, 3126 "%s/%s has " 3127 "semantically identical records", 3128 ownerbuf, typebuf); 3129 if (level == ISC_LOG_ERROR) { 3130 answer = false; 3131 } 3132 break; 3133 } 3134 } 3135 dns_rdataset_disassociate(&tmprdataset); 3136 if (!format) { 3137 break; 3138 } 3139 } 3140 return answer; 3141 } 3142 3143 static bool 3144 zone_check_dup(dns_zone_t *zone, dns_db_t *db) { 3145 dns_dbiterator_t *dbiterator = NULL; 3146 dns_dbnode_t *node = NULL; 3147 dns_fixedname_t fixed; 3148 dns_name_t *name; 3149 dns_rdataset_t rdataset; 3150 dns_rdatasetiter_t *rdsit = NULL; 3151 bool ok = true; 3152 isc_result_t result; 3153 3154 name = dns_fixedname_initname(&fixed); 3155 dns_rdataset_init(&rdataset); 3156 3157 result = dns_db_createiterator(db, 0, &dbiterator); 3158 if (result != ISC_R_SUCCESS) { 3159 return true; 3160 } 3161 3162 for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS; 3163 result = dns_dbiterator_next(dbiterator)) 3164 { 3165 result = dns_dbiterator_current(dbiterator, &node, name); 3166 if (result != ISC_R_SUCCESS) { 3167 continue; 3168 } 3169 3170 result = dns_db_allrdatasets(db, node, NULL, 0, 0, &rdsit); 3171 if (result != ISC_R_SUCCESS) { 3172 continue; 3173 } 3174 3175 for (result = dns_rdatasetiter_first(rdsit); 3176 result == ISC_R_SUCCESS; 3177 result = dns_rdatasetiter_next(rdsit)) 3178 { 3179 dns_rdatasetiter_current(rdsit, &rdataset); 3180 if (!zone_rrset_check_dup(zone, name, &rdataset)) { 3181 ok = false; 3182 } 3183 dns_rdataset_disassociate(&rdataset); 3184 } 3185 dns_rdatasetiter_destroy(&rdsit); 3186 dns_db_detachnode(db, &node); 3187 } 3188 3189 if (node != NULL) { 3190 dns_db_detachnode(db, &node); 3191 } 3192 dns_dbiterator_destroy(&dbiterator); 3193 3194 return ok; 3195 } 3196 3197 static bool 3198 isspf(const dns_rdata_t *rdata) { 3199 char buf[1024]; 3200 const unsigned char *data = rdata->data; 3201 unsigned int rdl = rdata->length, i = 0, tl, len; 3202 3203 while (rdl > 0U) { 3204 len = tl = *data; 3205 ++data; 3206 --rdl; 3207 INSIST(tl <= rdl); 3208 if (len > sizeof(buf) - i - 1) { 3209 len = sizeof(buf) - i - 1; 3210 } 3211 memmove(buf + i, data, len); 3212 i += len; 3213 data += tl; 3214 rdl -= tl; 3215 } 3216 3217 if (i < 6U) { 3218 return false; 3219 } 3220 3221 buf[i] = 0; 3222 if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' ')) { 3223 return true; 3224 } 3225 return false; 3226 } 3227 3228 static bool 3229 integrity_checks(dns_zone_t *zone, dns_db_t *db) { 3230 dns_dbiterator_t *dbiterator = NULL; 3231 dns_dbnode_t *node = NULL; 3232 dns_rdataset_t rdataset; 3233 dns_fixedname_t fixed; 3234 dns_fixedname_t fixedbottom; 3235 dns_rdata_mx_t mx; 3236 dns_rdata_ns_t ns; 3237 dns_rdata_in_srv_t srv; 3238 dns_name_t *name; 3239 dns_name_t *bottom; 3240 isc_result_t result; 3241 bool ok = true, have_spf, have_txt; 3242 int level; 3243 char namebuf[DNS_NAME_FORMATSIZE]; 3244 bool logged_algorithm[DST_MAX_ALGS]; 3245 bool logged_digest_type[DNS_DSDIGEST_MAX + 1]; 3246 3247 name = dns_fixedname_initname(&fixed); 3248 bottom = dns_fixedname_initname(&fixedbottom); 3249 dns_rdataset_init(&rdataset); 3250 3251 result = dns_db_createiterator(db, 0, &dbiterator); 3252 if (result != ISC_R_SUCCESS) { 3253 return true; 3254 } 3255 3256 result = dns_dbiterator_first(dbiterator); 3257 while (result == ISC_R_SUCCESS) { 3258 result = dns_dbiterator_current(dbiterator, &node, name); 3259 if (result != ISC_R_SUCCESS) { 3260 goto cleanup; 3261 } 3262 3263 /* 3264 * Is this name visible in the zone? 3265 */ 3266 if (!dns_name_issubdomain(name, &zone->origin) || 3267 (dns_name_countlabels(bottom) > 0 && 3268 dns_name_issubdomain(name, bottom))) 3269 { 3270 goto next; 3271 } 3272 3273 dns_dbiterator_pause(dbiterator); 3274 3275 /* 3276 * Check for deprecated KEY algorithms 3277 */ 3278 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_key, 3279 0, 0, &rdataset, NULL); 3280 if (result != ISC_R_SUCCESS) { 3281 goto checkforns; 3282 } 3283 3284 memset(logged_algorithm, 0, sizeof(logged_algorithm)); 3285 for (result = dns_rdataset_first(&rdataset); 3286 result == ISC_R_SUCCESS; 3287 result = dns_rdataset_next(&rdataset)) 3288 { 3289 dns_rdata_t rdata = DNS_RDATA_INIT; 3290 dns_rdata_key_t key; 3291 dns_rdataset_current(&rdataset, &rdata); 3292 3293 result = dns_rdata_tostruct(&rdata, &key, NULL); 3294 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3295 3296 /* 3297 * If we ever deprecate a private algorithm use 3298 * dst_algorithm_fromdata() here. 3299 */ 3300 switch (key.algorithm) { 3301 case DNS_KEYALG_RSASHA1: 3302 case DNS_KEYALG_NSEC3RSASHA1: 3303 if (!logged_algorithm[key.algorithm]) { 3304 char algbuf[DNS_SECALG_FORMATSIZE]; 3305 dns_name_format(name, namebuf, 3306 sizeof(namebuf)); 3307 dns_secalg_format(key.algorithm, algbuf, 3308 sizeof(algbuf)); 3309 dnssec_log(zone, ISC_LOG_WARNING, 3310 "%s/KEY deprecated " 3311 "algorithm %u (%s)", 3312 namebuf, key.algorithm, 3313 algbuf); 3314 logged_algorithm[key.algorithm] = true; 3315 } 3316 break; 3317 default: 3318 break; 3319 } 3320 } 3321 dns_rdataset_disassociate(&rdataset); 3322 3323 checkforns: 3324 /* 3325 * Don't check the NS records at the origin. 3326 */ 3327 if (dns_name_equal(name, &zone->origin)) { 3328 goto checkfords; 3329 } 3330 3331 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns, 3332 0, 0, &rdataset, NULL); 3333 if (result != ISC_R_SUCCESS) { 3334 goto checkfords; 3335 } 3336 3337 /* 3338 * Remember bottom of zone due to NS. 3339 */ 3340 dns_name_copy(name, bottom); 3341 3342 result = dns_rdataset_first(&rdataset); 3343 while (result == ISC_R_SUCCESS) { 3344 dns_rdata_t rdata = DNS_RDATA_INIT; 3345 dns_rdataset_current(&rdataset, &rdata); 3346 result = dns_rdata_tostruct(&rdata, &ns, NULL); 3347 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3348 if (!zone_check_glue(zone, db, &ns.name, name)) { 3349 ok = false; 3350 } 3351 dns_rdata_reset(&rdata); 3352 result = dns_rdataset_next(&rdataset); 3353 } 3354 dns_rdataset_disassociate(&rdataset); 3355 3356 /* 3357 * Check for deprecated DS digest types. 3358 */ 3359 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, 3360 0, 0, &rdataset, NULL); 3361 if (result != ISC_R_SUCCESS) { 3362 goto next; 3363 } 3364 3365 memset(logged_algorithm, 0, sizeof(logged_algorithm)); 3366 memset(logged_digest_type, 0, sizeof(logged_digest_type)); 3367 for (result = dns_rdataset_first(&rdataset); 3368 result == ISC_R_SUCCESS; 3369 result = dns_rdataset_next(&rdataset)) 3370 { 3371 dns_rdata_t rdata = DNS_RDATA_INIT; 3372 dns_rdataset_current(&rdataset, &rdata); 3373 dns_rdata_ds_t ds; 3374 3375 result = dns_rdata_tostruct(&rdata, &ds, NULL); 3376 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3377 switch (ds.digest_type) { 3378 case DNS_DSDIGEST_SHA1: 3379 case DNS_DSDIGEST_GOST: 3380 if (!logged_digest_type[ds.digest_type]) { 3381 char algbuf[DNS_DSDIGEST_FORMATSIZE]; 3382 dns_name_format(name, namebuf, 3383 sizeof(namebuf)); 3384 dns_dsdigest_format(ds.digest_type, 3385 algbuf, 3386 sizeof(algbuf)); 3387 dnssec_log(zone, ISC_LOG_WARNING, 3388 "%s/DS deprecated digest " 3389 "type %u (%s)", 3390 namebuf, ds.digest_type, 3391 algbuf); 3392 logged_digest_type[ds.digest_type] = 3393 true; 3394 } 3395 break; 3396 } 3397 3398 /* 3399 * If we ever deprecate a private algorithm use 3400 * dst_algorithm_fromdata() here. 3401 */ 3402 switch (ds.algorithm) { 3403 case DNS_KEYALG_RSASHA1: 3404 case DNS_KEYALG_NSEC3RSASHA1: 3405 if (!logged_algorithm[ds.algorithm]) { 3406 char algbuf[DNS_SECALG_FORMATSIZE]; 3407 dns_name_format(name, namebuf, 3408 sizeof(namebuf)); 3409 dns_secalg_format(ds.algorithm, algbuf, 3410 sizeof(algbuf)); 3411 dnssec_log(zone, ISC_LOG_WARNING, 3412 "%s/DS deprecated algorithm " 3413 "%u (%s)", 3414 namebuf, ds.algorithm, 3415 algbuf); 3416 logged_algorithm[ds.algorithm] = true; 3417 } 3418 break; 3419 } 3420 } 3421 dns_rdataset_disassociate(&rdataset); 3422 3423 goto next; 3424 3425 checkfords: 3426 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, 3427 0, 0, &rdataset, NULL); 3428 if (result != ISC_R_SUCCESS) { 3429 goto checkfordname; 3430 } 3431 dns_rdataset_disassociate(&rdataset); 3432 3433 if (zone->type == dns_zone_primary) { 3434 level = ISC_LOG_ERROR; 3435 ok = false; 3436 } else { 3437 level = ISC_LOG_WARNING; 3438 } 3439 dns_name_format(name, namebuf, sizeof(namebuf)); 3440 dns_zone_log(zone, level, "DS not at delegation point (%s)", 3441 namebuf); 3442 3443 checkfordname: 3444 result = dns_db_findrdataset(db, node, NULL, 3445 dns_rdatatype_dname, 0, 0, 3446 &rdataset, NULL); 3447 if (result == ISC_R_SUCCESS) { 3448 /* 3449 * Remember bottom of zone due to DNAME. 3450 */ 3451 dns_name_copy(name, bottom); 3452 dns_rdataset_disassociate(&rdataset); 3453 } 3454 3455 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx, 3456 0, 0, &rdataset, NULL); 3457 if (result != ISC_R_SUCCESS) { 3458 goto checksrv; 3459 } 3460 result = dns_rdataset_first(&rdataset); 3461 while (result == ISC_R_SUCCESS) { 3462 dns_rdata_t rdata = DNS_RDATA_INIT; 3463 dns_rdataset_current(&rdataset, &rdata); 3464 result = dns_rdata_tostruct(&rdata, &mx, NULL); 3465 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3466 if (!zone_check_mx(zone, db, &mx.mx, name)) { 3467 ok = false; 3468 } 3469 dns_rdata_reset(&rdata); 3470 result = dns_rdataset_next(&rdataset); 3471 } 3472 dns_rdataset_disassociate(&rdataset); 3473 3474 checksrv: 3475 if (zone->rdclass != dns_rdataclass_in) { 3476 goto next; 3477 } 3478 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv, 3479 0, 0, &rdataset, NULL); 3480 if (result != ISC_R_SUCCESS) { 3481 goto checkspf; 3482 } 3483 result = dns_rdataset_first(&rdataset); 3484 while (result == ISC_R_SUCCESS) { 3485 dns_rdata_t rdata = DNS_RDATA_INIT; 3486 dns_rdataset_current(&rdataset, &rdata); 3487 result = dns_rdata_tostruct(&rdata, &srv, NULL); 3488 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3489 if (!zone_check_srv(zone, db, &srv.target, name)) { 3490 ok = false; 3491 } 3492 dns_rdata_reset(&rdata); 3493 result = dns_rdataset_next(&rdataset); 3494 } 3495 dns_rdataset_disassociate(&rdataset); 3496 3497 checkspf: 3498 /* 3499 * Check if there is a type SPF record without an 3500 * SPF-formatted type TXT record also being present. 3501 */ 3502 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF)) { 3503 goto next; 3504 } 3505 if (zone->rdclass != dns_rdataclass_in) { 3506 goto next; 3507 } 3508 have_spf = have_txt = false; 3509 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf, 3510 0, 0, &rdataset, NULL); 3511 if (result == ISC_R_SUCCESS) { 3512 dns_rdataset_disassociate(&rdataset); 3513 have_spf = true; 3514 } 3515 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt, 3516 0, 0, &rdataset, NULL); 3517 if (result != ISC_R_SUCCESS) { 3518 goto notxt; 3519 } 3520 result = dns_rdataset_first(&rdataset); 3521 while (result == ISC_R_SUCCESS) { 3522 dns_rdata_t rdata = DNS_RDATA_INIT; 3523 dns_rdataset_current(&rdataset, &rdata); 3524 have_txt = isspf(&rdata); 3525 dns_rdata_reset(&rdata); 3526 if (have_txt) { 3527 break; 3528 } 3529 result = dns_rdataset_next(&rdataset); 3530 } 3531 dns_rdataset_disassociate(&rdataset); 3532 3533 notxt: 3534 if (have_spf && !have_txt) { 3535 dns_name_format(name, namebuf, sizeof(namebuf)); 3536 dns_zone_log(zone, ISC_LOG_WARNING, 3537 "'%s' found type " 3538 "SPF record but no SPF TXT record found, " 3539 "add matching type TXT record", 3540 namebuf); 3541 } 3542 3543 next: 3544 dns_db_detachnode(db, &node); 3545 result = dns_dbiterator_next(dbiterator); 3546 } 3547 3548 cleanup: 3549 if (node != NULL) { 3550 dns_db_detachnode(db, &node); 3551 } 3552 dns_dbiterator_destroy(&dbiterator); 3553 3554 return ok; 3555 } 3556 3557 /* 3558 * OpenSSL verification of RSA keys with exponent 3 is known to be 3559 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn 3560 * if they are in use. 3561 */ 3562 static void 3563 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) { 3564 dns_dbnode_t *node = NULL; 3565 dns_dbversion_t *version = NULL; 3566 dns_rdata_dnskey_t dnskey; 3567 dns_rdataset_t rdataset; 3568 isc_result_t result; 3569 bool logged_algorithm[DST_MAX_ALGS] = { 0 }; 3570 bool alldeprecated = true; 3571 3572 result = dns_db_findnode(db, &zone->origin, false, &node); 3573 if (result != ISC_R_SUCCESS) { 3574 goto cleanup; 3575 } 3576 3577 dns_db_currentversion(db, &version); 3578 dns_rdataset_init(&rdataset); 3579 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 3580 dns_rdatatype_none, 0, &rdataset, NULL); 3581 if (result != ISC_R_SUCCESS) { 3582 goto cleanup; 3583 } 3584 3585 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 3586 result = dns_rdataset_next(&rdataset)) 3587 { 3588 char algbuf[DNS_SECALG_FORMATSIZE]; 3589 dns_rdata_t rdata = DNS_RDATA_INIT; 3590 dns_rdataset_current(&rdataset, &rdata); 3591 result = dns_rdata_tostruct(&rdata, &dnskey, NULL); 3592 INSIST(result == ISC_R_SUCCESS); 3593 3594 /* 3595 * RFC 3110, section 4: Performance Considerations: 3596 * 3597 * A public exponent of 3 minimizes the effort needed to verify 3598 * a signature. Use of 3 as the public exponent is weak for 3599 * confidentiality uses since, if the same data can be collected 3600 * encrypted under three different keys with an exponent of 3 3601 * then, using the Chinese Remainder Theorem [NETSEC], the 3602 * original plain text can be easily recovered. If a key is 3603 * known to be used only for authentication, as is the case with 3604 * DNSSEC, then an exponent of 3 is acceptable. However other 3605 * applications in the future may wish to leverage DNS 3606 * distributed keys for applications that do require 3607 * confidentiality. For keys which might have such other uses, 3608 * a more conservative choice would be 65537 (F4, the fourth 3609 * fermat number). 3610 */ 3611 if (dnskey.datalen > 1 && dnskey.data[0] == 1 && 3612 dnskey.data[1] == 3 && 3613 (dnskey.algorithm == DNS_KEYALG_RSAMD5 || 3614 dnskey.algorithm == DNS_KEYALG_RSASHA1 || 3615 dnskey.algorithm == DNS_KEYALG_NSEC3RSASHA1 || 3616 dnskey.algorithm == DNS_KEYALG_RSASHA256 || 3617 dnskey.algorithm == DNS_KEYALG_RSASHA512)) 3618 { 3619 char algorithm[DNS_SECALG_FORMATSIZE]; 3620 isc_region_t r; 3621 3622 dns_rdata_toregion(&rdata, &r); 3623 dns_secalg_format(dnskey.algorithm, algorithm, 3624 sizeof(algorithm)); 3625 3626 dnssec_log(zone, ISC_LOG_WARNING, 3627 "weak %s (%u) key found (exponent=3, id=%u)", 3628 algorithm, dnskey.algorithm, 3629 dst_region_computeid(&r)); 3630 } 3631 3632 switch (dnskey.algorithm) { 3633 case DNS_KEYALG_RSAMD5: 3634 case DNS_KEYALG_DSA: 3635 case DNS_KEYALG_RSASHA1: 3636 case DNS_KEYALG_NSEC3DSA: 3637 case DNS_KEYALG_NSEC3RSASHA1: 3638 case DNS_KEYALG_ECCGOST: 3639 if (!logged_algorithm[dnskey.algorithm]) { 3640 dns_secalg_format(dnskey.algorithm, algbuf, 3641 sizeof(algbuf)); 3642 dnssec_log(zone, ISC_LOG_WARNING, 3643 "deprecated DNSKEY algorithm found: " 3644 "%u (%s)\n", 3645 dnskey.algorithm, algbuf); 3646 logged_algorithm[dnskey.algorithm] = true; 3647 } 3648 break; 3649 default: 3650 alldeprecated = false; 3651 break; 3652 } 3653 } 3654 dns_rdataset_disassociate(&rdataset); 3655 3656 if (alldeprecated) { 3657 dnssec_log(zone, ISC_LOG_WARNING, 3658 "all DNSKEY algorithms found are deprecated"); 3659 } 3660 3661 cleanup: 3662 if (node != NULL) { 3663 dns_db_detachnode(db, &node); 3664 } 3665 if (version != NULL) { 3666 dns_db_closeversion(db, &version, false); 3667 } 3668 } 3669 3670 static void 3671 resume_signingwithkey(dns_zone_t *zone) { 3672 dns_dbnode_t *node = NULL; 3673 dns_dbversion_t *version = NULL; 3674 dns_rdata_t rdata = DNS_RDATA_INIT; 3675 dns_rdataset_t rdataset; 3676 isc_result_t result; 3677 dns_db_t *db = NULL; 3678 3679 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3680 if (zone->db != NULL) { 3681 dns_db_attach(zone->db, &db); 3682 } 3683 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3684 if (db == NULL) { 3685 goto cleanup; 3686 } 3687 3688 result = dns_db_findnode(db, &zone->origin, false, &node); 3689 if (result != ISC_R_SUCCESS) { 3690 goto cleanup; 3691 } 3692 3693 dns_db_currentversion(db, &version); 3694 dns_rdataset_init(&rdataset); 3695 result = dns_db_findrdataset(db, node, version, zone->privatetype, 3696 dns_rdatatype_none, 0, &rdataset, NULL); 3697 if (result != ISC_R_SUCCESS) { 3698 INSIST(!dns_rdataset_isassociated(&rdataset)); 3699 goto cleanup; 3700 } 3701 3702 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 3703 result = dns_rdataset_next(&rdataset)) 3704 { 3705 dns_rdataset_current(&rdataset, &rdata); 3706 if (rdata.length != 5 || rdata.data[0] == 0 || 3707 rdata.data[4] != 0) 3708 { 3709 dns_rdata_reset(&rdata); 3710 continue; 3711 } 3712 3713 result = zone_signwithkey(zone, rdata.data[0], 3714 (rdata.data[1] << 8) | rdata.data[2], 3715 rdata.data[3], false); 3716 if (result != ISC_R_SUCCESS) { 3717 dnssec_log(zone, ISC_LOG_ERROR, 3718 "zone_signwithkey failed: %s", 3719 isc_result_totext(result)); 3720 } 3721 dns_rdata_reset(&rdata); 3722 } 3723 dns_rdataset_disassociate(&rdataset); 3724 3725 cleanup: 3726 if (db != NULL) { 3727 if (node != NULL) { 3728 dns_db_detachnode(db, &node); 3729 } 3730 if (version != NULL) { 3731 dns_db_closeversion(db, &version, false); 3732 } 3733 dns_db_detach(&db); 3734 } 3735 } 3736 3737 /* 3738 * Initiate adding/removing NSEC3 records belonging to the chain defined by the 3739 * supplied NSEC3PARAM RDATA. 3740 * 3741 * Zone must be locked by caller. 3742 */ 3743 static isc_result_t 3744 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 3745 dns_nsec3chain_t *nsec3chain, *current; 3746 dns_dbversion_t *version = NULL; 3747 bool nseconly = false, nsec3ok = false; 3748 isc_result_t result; 3749 isc_time_t now; 3750 unsigned int options = 0; 3751 char saltbuf[255 * 2 + 1]; 3752 char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")]; 3753 dns_db_t *db = NULL; 3754 3755 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3756 if (zone->db != NULL) { 3757 dns_db_attach(zone->db, &db); 3758 } 3759 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3760 3761 if (db == NULL) { 3762 result = ISC_R_SUCCESS; 3763 goto cleanup; 3764 } 3765 3766 /* 3767 * If this zone is not NSEC3-capable, attempting to remove any NSEC3 3768 * chain from it is pointless as it would not be possible for the 3769 * latter to exist in the first place. 3770 */ 3771 dns_db_currentversion(db, &version); 3772 result = dns_nsec_nseconly(db, version, NULL, &nseconly); 3773 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 3774 dns_db_closeversion(db, &version, false); 3775 if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) { 3776 result = ISC_R_SUCCESS; 3777 goto cleanup; 3778 } 3779 3780 /* 3781 * Allocate and initialize structure preserving state of 3782 * adding/removing records belonging to this NSEC3 chain between 3783 * separate zone_nsec3chain() calls. 3784 */ 3785 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain); 3786 3787 nsec3chain->magic = 0; 3788 nsec3chain->done = false; 3789 nsec3chain->db = NULL; 3790 nsec3chain->dbiterator = NULL; 3791 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass; 3792 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype; 3793 nsec3chain->nsec3param.hash = nsec3param->hash; 3794 nsec3chain->nsec3param.iterations = nsec3param->iterations; 3795 nsec3chain->nsec3param.flags = nsec3param->flags; 3796 nsec3chain->nsec3param.salt_length = nsec3param->salt_length; 3797 memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length); 3798 nsec3chain->nsec3param.salt = nsec3chain->salt; 3799 nsec3chain->seen_nsec = false; 3800 nsec3chain->delete_nsec = false; 3801 nsec3chain->save_delete_nsec = false; 3802 3803 /* 3804 * Log NSEC3 parameters defined by supplied NSEC3PARAM RDATA. 3805 */ 3806 if (nsec3param->flags == 0) { 3807 strlcpy(flags, "NONE", sizeof(flags)); 3808 } else { 3809 flags[0] = '\0'; 3810 if ((nsec3param->flags & DNS_NSEC3FLAG_REMOVE) != 0) { 3811 strlcat(flags, "REMOVE", sizeof(flags)); 3812 } 3813 if ((nsec3param->flags & DNS_NSEC3FLAG_INITIAL) != 0) { 3814 if (flags[0] == '\0') { 3815 strlcpy(flags, "INITIAL", sizeof(flags)); 3816 } else { 3817 strlcat(flags, "|INITIAL", sizeof(flags)); 3818 } 3819 } 3820 if ((nsec3param->flags & DNS_NSEC3FLAG_CREATE) != 0) { 3821 if (flags[0] == '\0') { 3822 strlcpy(flags, "CREATE", sizeof(flags)); 3823 } else { 3824 strlcat(flags, "|CREATE", sizeof(flags)); 3825 } 3826 } 3827 if ((nsec3param->flags & DNS_NSEC3FLAG_NONSEC) != 0) { 3828 if (flags[0] == '\0') { 3829 strlcpy(flags, "NONSEC", sizeof(flags)); 3830 } else { 3831 strlcat(flags, "|NONSEC", sizeof(flags)); 3832 } 3833 } 3834 if ((nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) != 0) { 3835 if (flags[0] == '\0') { 3836 strlcpy(flags, "OPTOUT", sizeof(flags)); 3837 } else { 3838 strlcat(flags, "|OPTOUT", sizeof(flags)); 3839 } 3840 } 3841 } 3842 result = dns_nsec3param_salttotext(nsec3param, saltbuf, 3843 sizeof(saltbuf)); 3844 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3845 dnssec_log(zone, ISC_LOG_INFO, "zone_addnsec3chain(%u,%s,%u,%s)", 3846 nsec3param->hash, flags, nsec3param->iterations, saltbuf); 3847 3848 /* 3849 * If the NSEC3 chain defined by the supplied NSEC3PARAM RDATA is 3850 * currently being processed, interrupt its processing to avoid 3851 * simultaneously adding and removing records for the same NSEC3 chain. 3852 */ 3853 for (current = ISC_LIST_HEAD(zone->nsec3chain); current != NULL; 3854 current = ISC_LIST_NEXT(current, link)) 3855 { 3856 if ((current->db == db) && 3857 (current->nsec3param.hash == nsec3param->hash) && 3858 (current->nsec3param.iterations == 3859 nsec3param->iterations) && 3860 (current->nsec3param.salt_length == 3861 nsec3param->salt_length) && 3862 memcmp(current->nsec3param.salt, nsec3param->salt, 3863 nsec3param->salt_length) == 0) 3864 { 3865 current->done = true; 3866 } 3867 } 3868 3869 /* 3870 * Attach zone database to the structure initialized above and create 3871 * an iterator for it with appropriate options in order to avoid 3872 * creating NSEC3 records for NSEC3 records. 3873 */ 3874 dns_db_attach(db, &nsec3chain->db); 3875 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) { 3876 options = DNS_DB_NONSEC3; 3877 } 3878 result = dns_db_createiterator(nsec3chain->db, options, 3879 &nsec3chain->dbiterator); 3880 if (result == ISC_R_SUCCESS) { 3881 result = dns_dbiterator_first(nsec3chain->dbiterator); 3882 } 3883 if (result == ISC_R_SUCCESS) { 3884 /* 3885 * Database iterator initialization succeeded. We are now 3886 * ready to kick off adding/removing records belonging to this 3887 * NSEC3 chain. Append the structure initialized above to the 3888 * "nsec3chain" list for the zone and set the appropriate zone 3889 * timer so that zone_nsec3chain() is called as soon as 3890 * possible. 3891 */ 3892 dns_dbiterator_pause(nsec3chain->dbiterator); 3893 ISC_LIST_INITANDAPPEND(zone->nsec3chain, nsec3chain, link); 3894 nsec3chain = NULL; 3895 if (isc_time_isepoch(&zone->nsec3chaintime)) { 3896 now = isc_time_now(); 3897 zone->nsec3chaintime = now; 3898 if (zone->loop != NULL) { 3899 zone_settimer(zone, &now); 3900 } 3901 } 3902 } 3903 3904 if (nsec3chain != NULL) { 3905 if (nsec3chain->db != NULL) { 3906 dns_db_detach(&nsec3chain->db); 3907 } 3908 if (nsec3chain->dbiterator != NULL) { 3909 dns_dbiterator_destroy(&nsec3chain->dbiterator); 3910 } 3911 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 3912 } 3913 3914 cleanup: 3915 if (db != NULL) { 3916 dns_db_detach(&db); 3917 } 3918 return result; 3919 } 3920 3921 /* 3922 * Find private-type records at the zone apex which signal that an NSEC3 chain 3923 * should be added or removed. For each such record, extract NSEC3PARAM RDATA 3924 * and pass it to zone_addnsec3chain(). 3925 * 3926 * Zone must be locked by caller. 3927 */ 3928 static void 3929 resume_addnsec3chain(dns_zone_t *zone) { 3930 dns_dbnode_t *node = NULL; 3931 dns_dbversion_t *version = NULL; 3932 dns_rdataset_t rdataset; 3933 isc_result_t result; 3934 dns_rdata_nsec3param_t nsec3param; 3935 bool nseconly = false, nsec3ok = false; 3936 dns_db_t *db = NULL; 3937 3938 INSIST(LOCKED_ZONE(zone)); 3939 3940 if (zone->privatetype == 0) { 3941 return; 3942 } 3943 3944 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3945 if (zone->db != NULL) { 3946 dns_db_attach(zone->db, &db); 3947 } 3948 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3949 if (db == NULL) { 3950 goto cleanup; 3951 } 3952 3953 result = dns_db_findnode(db, &zone->origin, false, &node); 3954 if (result != ISC_R_SUCCESS) { 3955 goto cleanup; 3956 } 3957 3958 dns_db_currentversion(db, &version); 3959 3960 /* 3961 * In order to create NSEC3 chains we need the DNSKEY RRset at zone 3962 * apex to exist and contain no keys using NSEC-only algorithms. 3963 */ 3964 result = dns_nsec_nseconly(db, version, NULL, &nseconly); 3965 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 3966 3967 /* 3968 * Get the RRset containing all private-type records at the zone apex. 3969 */ 3970 dns_rdataset_init(&rdataset); 3971 result = dns_db_findrdataset(db, node, version, zone->privatetype, 3972 dns_rdatatype_none, 0, &rdataset, NULL); 3973 if (result != ISC_R_SUCCESS) { 3974 INSIST(!dns_rdataset_isassociated(&rdataset)); 3975 goto cleanup; 3976 } 3977 3978 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 3979 result = dns_rdataset_next(&rdataset)) 3980 { 3981 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 3982 dns_rdata_t rdata = DNS_RDATA_INIT; 3983 dns_rdata_t private = DNS_RDATA_INIT; 3984 3985 dns_rdataset_current(&rdataset, &private); 3986 /* 3987 * Try extracting NSEC3PARAM RDATA from this private-type 3988 * record. Failure means this private-type record does not 3989 * represent an NSEC3PARAM record, so skip it. 3990 */ 3991 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 3992 sizeof(buf))) 3993 { 3994 continue; 3995 } 3996 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 3997 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3998 if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) || 3999 ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok)) 4000 { 4001 /* 4002 * Pass the NSEC3PARAM RDATA contained in this 4003 * private-type record to zone_addnsec3chain() so that 4004 * it can kick off adding or removing NSEC3 records. 4005 */ 4006 result = zone_addnsec3chain(zone, &nsec3param); 4007 if (result != ISC_R_SUCCESS) { 4008 dnssec_log(zone, ISC_LOG_ERROR, 4009 "zone_addnsec3chain failed: %s", 4010 isc_result_totext(result)); 4011 } 4012 } 4013 } 4014 dns_rdataset_disassociate(&rdataset); 4015 4016 cleanup: 4017 if (db != NULL) { 4018 if (node != NULL) { 4019 dns_db_detachnode(db, &node); 4020 } 4021 if (version != NULL) { 4022 dns_db_closeversion(db, &version, false); 4023 } 4024 dns_db_detach(&db); 4025 } 4026 } 4027 4028 static void 4029 set_resigntime(dns_zone_t *zone) { 4030 dns_fixedname_t fixed; 4031 isc_stdtime_t resign; 4032 isc_result_t result; 4033 uint32_t nanosecs; 4034 dns_db_t *db = NULL; 4035 dns_typepair_t typepair; 4036 4037 INSIST(LOCKED_ZONE(zone)); 4038 4039 /* We only re-sign zones that can be dynamically updated */ 4040 if (!dns_zone_isdynamic(zone, false)) { 4041 return; 4042 } 4043 4044 if (inline_raw(zone)) { 4045 return; 4046 } 4047 4048 dns_fixedname_init(&fixed); 4049 4050 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 4051 if (zone->db != NULL) { 4052 dns_db_attach(zone->db, &db); 4053 } 4054 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 4055 if (db == NULL) { 4056 isc_time_settoepoch(&zone->resigntime); 4057 return; 4058 } 4059 4060 result = dns_db_getsigningtime(db, &resign, dns_fixedname_name(&fixed), 4061 &typepair); 4062 if (result != ISC_R_SUCCESS) { 4063 isc_time_settoepoch(&zone->resigntime); 4064 goto cleanup; 4065 } 4066 4067 resign -= dns_zone_getsigresigninginterval(zone); 4068 nanosecs = isc_random_uniform(1000000000); 4069 isc_time_set(&zone->resigntime, resign, nanosecs); 4070 4071 cleanup: 4072 dns_db_detach(&db); 4073 return; 4074 } 4075 4076 static isc_result_t 4077 check_nsec3param(dns_zone_t *zone, dns_db_t *db) { 4078 bool ok = false; 4079 dns_dbnode_t *node = NULL; 4080 dns_dbversion_t *version = NULL; 4081 dns_rdata_nsec3param_t nsec3param; 4082 dns_rdataset_t rdataset; 4083 isc_result_t result; 4084 bool dynamic = (zone->type == dns_zone_primary) 4085 ? dns_zone_isdynamic(zone, false) 4086 : false; 4087 4088 dns_rdataset_init(&rdataset); 4089 result = dns_db_findnode(db, &zone->origin, false, &node); 4090 if (result != ISC_R_SUCCESS) { 4091 dns_zone_log(zone, ISC_LOG_ERROR, 4092 "nsec3param lookup failure: %s", 4093 isc_result_totext(result)); 4094 return result; 4095 } 4096 dns_db_currentversion(db, &version); 4097 4098 result = dns_db_findrdataset(db, node, version, 4099 dns_rdatatype_nsec3param, 4100 dns_rdatatype_none, 0, &rdataset, NULL); 4101 if (result == ISC_R_NOTFOUND) { 4102 INSIST(!dns_rdataset_isassociated(&rdataset)); 4103 result = ISC_R_SUCCESS; 4104 goto cleanup; 4105 } 4106 if (result != ISC_R_SUCCESS) { 4107 INSIST(!dns_rdataset_isassociated(&rdataset)); 4108 dns_zone_log(zone, ISC_LOG_ERROR, 4109 "nsec3param lookup failure: %s", 4110 isc_result_totext(result)); 4111 goto cleanup; 4112 } 4113 4114 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 4115 result = dns_rdataset_next(&rdataset)) 4116 { 4117 dns_rdata_t rdata = DNS_RDATA_INIT; 4118 4119 dns_rdataset_current(&rdataset, &rdata); 4120 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 4121 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4122 4123 /* 4124 * For dynamic zones we must support every algorithm so we 4125 * can regenerate all the NSEC3 chains. 4126 * For non-dynamic zones we only need to find a supported 4127 * algorithm. 4128 */ 4129 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) && 4130 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic) 4131 { 4132 dns_zone_log(zone, ISC_LOG_WARNING, 4133 "nsec3 test \"unknown\" hash algorithm " 4134 "found: %u", 4135 nsec3param.hash); 4136 ok = true; 4137 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) { 4138 if (dynamic) { 4139 dns_zone_log(zone, ISC_LOG_ERROR, 4140 "unsupported nsec3 hash algorithm" 4141 " in dynamic zone: %u", 4142 nsec3param.hash); 4143 result = DNS_R_BADZONE; 4144 /* Stop second error message. */ 4145 ok = true; 4146 break; 4147 } else { 4148 dns_zone_log(zone, ISC_LOG_WARNING, 4149 "unsupported nsec3 hash " 4150 "algorithm: %u", 4151 nsec3param.hash); 4152 } 4153 } else { 4154 ok = true; 4155 } 4156 4157 /* 4158 * Warn if the zone has excessive NSEC3 iterations. 4159 */ 4160 if (nsec3param.iterations > dns_nsec3_maxiterations()) { 4161 dnssec_log(zone, ISC_LOG_WARNING, 4162 "excessive NSEC3PARAM iterations %u > %u", 4163 nsec3param.iterations, 4164 dns_nsec3_maxiterations()); 4165 } 4166 } 4167 if (result == ISC_R_NOMORE) { 4168 result = ISC_R_SUCCESS; 4169 } 4170 4171 if (!ok) { 4172 result = DNS_R_BADZONE; 4173 dns_zone_log(zone, ISC_LOG_ERROR, 4174 "no supported nsec3 hash algorithm"); 4175 } 4176 4177 cleanup: 4178 if (dns_rdataset_isassociated(&rdataset)) { 4179 dns_rdataset_disassociate(&rdataset); 4180 } 4181 dns_db_closeversion(db, &version, false); 4182 dns_db_detachnode(db, &node); 4183 return result; 4184 } 4185 4186 /* 4187 * Set the timer for refreshing the key zone to the soonest future time 4188 * of the set (current timer, keydata->refresh, keydata->addhd, 4189 * keydata->removehd). 4190 */ 4191 static void 4192 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key, 4193 isc_stdtime_t now, bool force) { 4194 isc_stdtime_t then; 4195 isc_time_t timenow, timethen; 4196 char timebuf[80]; 4197 4198 ENTER; 4199 then = key->refresh; 4200 if (force) { 4201 then = now; 4202 } 4203 if (key->addhd > now && key->addhd < then) { 4204 then = key->addhd; 4205 } 4206 if (key->removehd > now && key->removehd < then) { 4207 then = key->removehd; 4208 } 4209 4210 timenow = isc_time_now(); 4211 if (then > now) { 4212 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 4213 } else { 4214 timethen = timenow; 4215 } 4216 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 || 4217 isc_time_compare(&timethen, &zone->refreshkeytime) < 0) 4218 { 4219 zone->refreshkeytime = timethen; 4220 } 4221 4222 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 4223 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf); 4224 zone_settimer(zone, &timenow); 4225 } 4226 4227 /* 4228 * If keynode references a key or a DS rdataset, and if the key 4229 * zone does not contain a KEYDATA record for the corresponding name, 4230 * then create an empty KEYDATA and push it into the zone as a placeholder, 4231 * then schedule a key refresh immediately. This new KEYDATA record will be 4232 * updated during the refresh. 4233 * 4234 * If the key zone is changed, set '*changed' to true. 4235 */ 4236 static isc_result_t 4237 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 4238 dns_diff_t *diff, dns_keynode_t *keynode, dns_name_t *keyname, 4239 bool *changed) { 4240 isc_result_t result = ISC_R_SUCCESS; 4241 dns_rdata_t rdata = DNS_RDATA_INIT; 4242 dns_rdata_keydata_t kd; 4243 unsigned char rrdata[4096]; 4244 isc_buffer_t rrdatabuf; 4245 isc_stdtime_t now = isc_stdtime_now(); 4246 4247 REQUIRE(keynode != NULL); 4248 4249 ENTER; 4250 4251 /* 4252 * If the keynode has no trust anchor set, we shouldn't be here. 4253 */ 4254 if (!dns_keynode_dsset(keynode, NULL)) { 4255 return ISC_R_FAILURE; 4256 } 4257 4258 memset(&kd, 0, sizeof(kd)); 4259 kd.common.rdclass = zone->rdclass; 4260 kd.common.rdtype = dns_rdatatype_keydata; 4261 ISC_LINK_INIT(&kd.common, link); 4262 4263 isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); 4264 4265 CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass, dns_rdatatype_keydata, 4266 &kd, &rrdatabuf)); 4267 /* Add rdata to zone. */ 4268 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, keyname, 0, &rdata)); 4269 *changed = true; 4270 4271 /* Refresh new keys from the zone apex as soon as possible. */ 4272 set_refreshkeytimer(zone, &kd, now, true); 4273 return ISC_R_SUCCESS; 4274 4275 cleanup: 4276 return result; 4277 } 4278 4279 /* 4280 * Remove from the key zone all the KEYDATA records found in rdataset. 4281 */ 4282 static isc_result_t 4283 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 4284 dns_name_t *name, dns_rdataset_t *rdataset) { 4285 dns_rdata_t rdata = DNS_RDATA_INIT; 4286 isc_result_t result, uresult; 4287 4288 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 4289 result = dns_rdataset_next(rdataset)) 4290 { 4291 dns_rdata_reset(&rdata); 4292 dns_rdataset_current(rdataset, &rdata); 4293 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 0, 4294 &rdata); 4295 if (uresult != ISC_R_SUCCESS) { 4296 return uresult; 4297 } 4298 } 4299 if (result == ISC_R_NOMORE) { 4300 result = ISC_R_SUCCESS; 4301 } 4302 return result; 4303 } 4304 4305 /* 4306 * Compute the DNSSEC key ID for a DNSKEY record. 4307 */ 4308 static isc_result_t 4309 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx, 4310 dns_keytag_t *tag) { 4311 isc_result_t result; 4312 dns_rdata_t rdata = DNS_RDATA_INIT; 4313 unsigned char data[4096]; 4314 isc_buffer_t buffer; 4315 dst_key_t *dstkey = NULL; 4316 4317 isc_buffer_init(&buffer, data, sizeof(data)); 4318 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 4319 dns_rdatatype_dnskey, dnskey, &buffer); 4320 4321 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey); 4322 if (result == ISC_R_SUCCESS) { 4323 *tag = dst_key_id(dstkey); 4324 dst_key_free(&dstkey); 4325 } 4326 4327 return result; 4328 } 4329 4330 /* 4331 * Synth-from-dnssec callbacks to add/delete names from namespace tree. 4332 */ 4333 static void 4334 sfd_add(const dns_name_t *name, void *arg) { 4335 if (arg != NULL) { 4336 dns_view_sfd_add(arg, name); 4337 } 4338 } 4339 4340 static void 4341 sfd_del(const dns_name_t *name, void *arg) { 4342 if (arg != NULL) { 4343 dns_view_sfd_del(arg, name); 4344 } 4345 } 4346 4347 /* 4348 * Add key to the security roots. 4349 */ 4350 static void 4351 trust_key(dns_zone_t *zone, dns_name_t *keyname, dns_rdata_dnskey_t *dnskey, 4352 bool initial) { 4353 isc_result_t result; 4354 dns_rdata_t rdata = DNS_RDATA_INIT; 4355 unsigned char data[4096], digest[ISC_MAX_MD_SIZE]; 4356 isc_buffer_t buffer; 4357 dns_keytable_t *sr = NULL; 4358 dns_rdata_ds_t ds; 4359 4360 result = dns_view_getsecroots(zone->view, &sr); 4361 if (result != ISC_R_SUCCESS) { 4362 return; 4363 } 4364 4365 /* Build DS record for key. */ 4366 isc_buffer_init(&buffer, data, sizeof(data)); 4367 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 4368 dns_rdatatype_dnskey, dnskey, &buffer); 4369 CHECK(dns_ds_fromkeyrdata(keyname, &rdata, DNS_DSDIGEST_SHA256, digest, 4370 &ds)); 4371 CHECK(dns_keytable_add(sr, true, initial, keyname, &ds, sfd_add, 4372 zone->view)); 4373 4374 dns_keytable_detach(&sr); 4375 4376 cleanup: 4377 if (sr != NULL) { 4378 dns_keytable_detach(&sr); 4379 } 4380 return; 4381 } 4382 4383 /* 4384 * Add a null key to the security roots for so that all queries 4385 * to the zone will fail. 4386 */ 4387 static void 4388 fail_secure(dns_zone_t *zone, dns_name_t *keyname) { 4389 isc_result_t result; 4390 dns_keytable_t *sr = NULL; 4391 4392 result = dns_view_getsecroots(zone->view, &sr); 4393 if (result == ISC_R_SUCCESS) { 4394 dns_keytable_marksecure(sr, keyname); 4395 dns_keytable_detach(&sr); 4396 } 4397 } 4398 4399 /* 4400 * Scan a set of KEYDATA records from the key zone. The ones that are 4401 * valid (i.e., the add holddown timer has expired) become trusted keys. 4402 */ 4403 static void 4404 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) { 4405 isc_result_t result; 4406 dns_rdata_t rdata = DNS_RDATA_INIT; 4407 dns_rdata_keydata_t keydata; 4408 dns_rdata_dnskey_t dnskey; 4409 int trusted = 0, revoked = 0, pending = 0; 4410 isc_stdtime_t now = isc_stdtime_now(); 4411 dns_keytable_t *sr = NULL; 4412 4413 result = dns_view_getsecroots(zone->view, &sr); 4414 if (result == ISC_R_SUCCESS) { 4415 dns_keytable_delete(sr, name, sfd_del, zone->view); 4416 dns_keytable_detach(&sr); 4417 } 4418 4419 /* Now insert all the accepted trust anchors from this keydata set. */ 4420 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 4421 result = dns_rdataset_next(rdataset)) 4422 { 4423 dns_rdata_reset(&rdata); 4424 dns_rdataset_current(rdataset, &rdata); 4425 4426 /* Convert rdata to keydata. */ 4427 result = dns_rdata_tostruct(&rdata, &keydata, NULL); 4428 if (result == ISC_R_NOTIMPLEMENTED) { 4429 continue; 4430 } 4431 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4432 4433 /* Set the key refresh timer to force a fast refresh. */ 4434 set_refreshkeytimer(zone, &keydata, now, true); 4435 4436 /* If the removal timer is nonzero, this key was revoked. */ 4437 if (keydata.removehd != 0) { 4438 revoked++; 4439 continue; 4440 } 4441 4442 /* 4443 * If the add timer is still pending, this key is not 4444 * trusted yet. 4445 */ 4446 if (now < keydata.addhd) { 4447 pending++; 4448 continue; 4449 } 4450 4451 /* Convert keydata to dnskey. */ 4452 dns_keydata_todnskey(&keydata, &dnskey, NULL); 4453 4454 /* Add to keytables. */ 4455 trusted++; 4456 trust_key(zone, name, &dnskey, keydata.addhd == 0); 4457 } 4458 4459 if (trusted == 0 && pending != 0) { 4460 char namebuf[DNS_NAME_FORMATSIZE]; 4461 dns_name_format(name, namebuf, sizeof namebuf); 4462 dnssec_log(zone, ISC_LOG_ERROR, 4463 "No valid trust anchors for '%s'!", namebuf); 4464 dnssec_log(zone, ISC_LOG_ERROR, 4465 "%d key(s) revoked, %d still pending", revoked, 4466 pending); 4467 dnssec_log(zone, ISC_LOG_ERROR, "All queries to '%s' will fail", 4468 namebuf); 4469 fail_secure(zone, name); 4470 } 4471 } 4472 4473 static isc_result_t 4474 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, 4475 dns_diff_t *diff) { 4476 dns_diff_t temp_diff; 4477 isc_result_t result; 4478 4479 /* 4480 * Create a singleton diff. 4481 */ 4482 dns_diff_init(diff->mctx, &temp_diff); 4483 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); 4484 4485 /* 4486 * Apply it to the database. 4487 */ 4488 result = dns_diff_apply(&temp_diff, db, ver); 4489 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); 4490 if (result != ISC_R_SUCCESS) { 4491 dns_difftuple_free(tuple); 4492 return result; 4493 } 4494 4495 /* 4496 * Merge it into the current pending journal entry. 4497 */ 4498 dns_diff_appendminimal(diff, tuple); 4499 4500 /* 4501 * Do not clear temp_diff. 4502 */ 4503 return ISC_R_SUCCESS; 4504 } 4505 4506 static isc_result_t 4507 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 4508 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, 4509 dns_rdata_t *rdata) { 4510 dns_difftuple_t *tuple = NULL; 4511 isc_result_t result; 4512 result = dns_difftuple_create(diff->mctx, op, name, ttl, rdata, &tuple); 4513 if (result != ISC_R_SUCCESS) { 4514 return result; 4515 } 4516 return do_one_tuple(&tuple, db, ver, diff); 4517 } 4518 4519 static isc_result_t 4520 update_soa_serial(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 4521 dns_diff_t *diff, isc_mem_t *mctx, 4522 dns_updatemethod_t method) { 4523 dns_difftuple_t *deltuple = NULL; 4524 dns_difftuple_t *addtuple = NULL; 4525 uint32_t serial; 4526 isc_result_t result; 4527 dns_updatemethod_t used = dns_updatemethod_none; 4528 4529 INSIST(method != dns_updatemethod_none); 4530 4531 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple)); 4532 CHECK(dns_difftuple_copy(deltuple, &addtuple)); 4533 addtuple->op = DNS_DIFFOP_ADD; 4534 4535 serial = dns_soa_getserial(&addtuple->rdata); 4536 serial = dns_update_soaserial(serial, method, &used); 4537 if (method != used) { 4538 dns_zone_log(zone, ISC_LOG_WARNING, 4539 "update_soa_serial:new serial would be lower than " 4540 "old serial, using increment method instead"); 4541 } 4542 dns_soa_setserial(serial, &addtuple->rdata); 4543 CHECK(do_one_tuple(&deltuple, db, ver, diff)); 4544 CHECK(do_one_tuple(&addtuple, db, ver, diff)); 4545 result = ISC_R_SUCCESS; 4546 4547 cleanup: 4548 if (addtuple != NULL) { 4549 dns_difftuple_free(&addtuple); 4550 } 4551 if (deltuple != NULL) { 4552 dns_difftuple_free(&deltuple); 4553 } 4554 return result; 4555 } 4556 4557 /* 4558 * Write all transactions in 'diff' to the zone journal file. 4559 */ 4560 static isc_result_t 4561 zone_journal(dns_zone_t *zone, dns_diff_t *diff, uint32_t *sourceserial, 4562 const char *caller) { 4563 const char *journalfile; 4564 isc_result_t result = ISC_R_SUCCESS; 4565 dns_journal_t *journal = NULL; 4566 unsigned int mode = DNS_JOURNAL_CREATE | DNS_JOURNAL_WRITE; 4567 4568 ENTER; 4569 journalfile = dns_zone_getjournal(zone); 4570 if (journalfile != NULL) { 4571 result = dns_journal_open(zone->mctx, journalfile, mode, 4572 &journal); 4573 if (result != ISC_R_SUCCESS) { 4574 dns_zone_log(zone, ISC_LOG_ERROR, 4575 "%s:dns_journal_open -> %s", caller, 4576 isc_result_totext(result)); 4577 return result; 4578 } 4579 4580 if (sourceserial != NULL) { 4581 dns_journal_set_sourceserial(journal, *sourceserial); 4582 } 4583 4584 result = dns_journal_write_transaction(journal, diff); 4585 if (result != ISC_R_SUCCESS) { 4586 dns_zone_log(zone, ISC_LOG_ERROR, 4587 "%s:dns_journal_write_transaction -> %s", 4588 caller, isc_result_totext(result)); 4589 } 4590 dns_journal_destroy(&journal); 4591 } 4592 4593 return result; 4594 } 4595 4596 /* 4597 * Create an SOA record for a newly-created zone 4598 */ 4599 static isc_result_t 4600 add_soa(dns_zone_t *zone, dns_db_t *db) { 4601 isc_result_t result; 4602 dns_rdata_t rdata = DNS_RDATA_INIT; 4603 unsigned char buf[DNS_SOA_BUFFERSIZE]; 4604 dns_dbversion_t *ver = NULL; 4605 dns_diff_t diff; 4606 4607 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA"); 4608 4609 dns_diff_init(zone->mctx, &diff); 4610 result = dns_db_newversion(db, &ver); 4611 if (result != ISC_R_SUCCESS) { 4612 dns_zone_log(zone, ISC_LOG_ERROR, 4613 "add_soa:dns_db_newversion -> %s", 4614 isc_result_totext(result)); 4615 goto cleanup; 4616 } 4617 4618 /* Build SOA record */ 4619 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass, 4620 0, 0, 0, 0, 0, buf, &rdata); 4621 if (result != ISC_R_SUCCESS) { 4622 dns_zone_log(zone, ISC_LOG_ERROR, 4623 "add_soa:dns_soa_buildrdata -> %s", 4624 isc_result_totext(result)); 4625 goto cleanup; 4626 } 4627 4628 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD, &zone->origin, 0, 4629 &rdata); 4630 4631 cleanup: 4632 dns_diff_clear(&diff); 4633 if (ver != NULL) { 4634 dns_db_closeversion(db, &ver, result == ISC_R_SUCCESS); 4635 } 4636 4637 INSIST(ver == NULL); 4638 4639 return result; 4640 } 4641 4642 struct addifmissing_arg { 4643 dns_db_t *db; 4644 dns_dbversion_t *ver; 4645 dns_diff_t *diff; 4646 dns_zone_t *zone; 4647 bool *changed; 4648 isc_result_t result; 4649 }; 4650 4651 static void 4652 addifmissing(dns_keytable_t *keytable, dns_keynode_t *keynode, 4653 dns_name_t *keyname, void *arg) { 4654 dns_db_t *db = ((struct addifmissing_arg *)arg)->db; 4655 dns_dbversion_t *ver = ((struct addifmissing_arg *)arg)->ver; 4656 dns_diff_t *diff = ((struct addifmissing_arg *)arg)->diff; 4657 dns_zone_t *zone = ((struct addifmissing_arg *)arg)->zone; 4658 bool *changed = ((struct addifmissing_arg *)arg)->changed; 4659 isc_result_t result; 4660 dns_fixedname_t fname; 4661 4662 UNUSED(keytable); 4663 4664 if (((struct addifmissing_arg *)arg)->result != ISC_R_SUCCESS) { 4665 return; 4666 } 4667 4668 if (!dns_keynode_managed(keynode)) { 4669 return; 4670 } 4671 4672 /* 4673 * If the keynode has no trust anchor set, return. 4674 */ 4675 if (!dns_keynode_dsset(keynode, NULL)) { 4676 return; 4677 } 4678 4679 /* 4680 * Check whether there's already a KEYDATA entry for this name; 4681 * if so, we don't need to add another. 4682 */ 4683 dns_fixedname_init(&fname); 4684 result = dns_db_find(db, keyname, ver, dns_rdatatype_keydata, 4685 DNS_DBFIND_NOWILD, 0, NULL, 4686 dns_fixedname_name(&fname), NULL, NULL); 4687 if (result == ISC_R_SUCCESS) { 4688 return; 4689 } 4690 4691 /* 4692 * Create the keydata. 4693 */ 4694 result = create_keydata(zone, db, ver, diff, keynode, keyname, changed); 4695 if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) { 4696 ((struct addifmissing_arg *)arg)->result = result; 4697 } 4698 } 4699 4700 /* 4701 * Synchronize the set of initializing keys found in managed-keys {} 4702 * statements with the set of trust anchors found in the managed-keys.bind 4703 * zone. If a domain is no longer named in managed-keys, delete all keys 4704 * from that domain from the key zone. If a domain is configured as an 4705 * initial-key in trust-anchors, but there are no references to it in the 4706 * key zone, load the key zone with the initializing key(s) for that 4707 * domain and schedule a key refresh. If a domain is configured as 4708 * an initial-ds in trust-anchors, fetch the DNSKEY RRset, load the key 4709 * zone with the matching key, and schedule a key refresh. 4710 */ 4711 static isc_result_t 4712 sync_keyzone(dns_zone_t *zone, dns_db_t *db) { 4713 isc_result_t result = ISC_R_SUCCESS; 4714 bool changed = false; 4715 bool commit = false; 4716 dns_keynode_t *keynode = NULL; 4717 dns_view_t *view = zone->view; 4718 dns_keytable_t *sr = NULL; 4719 dns_dbversion_t *ver = NULL; 4720 dns_diff_t diff; 4721 dns_rriterator_t rrit; 4722 struct addifmissing_arg arg; 4723 4724 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys"); 4725 4726 dns_diff_init(zone->mctx, &diff); 4727 4728 CHECK(dns_view_getsecroots(view, &sr)); 4729 4730 result = dns_db_newversion(db, &ver); 4731 if (result != ISC_R_SUCCESS) { 4732 dnssec_log(zone, ISC_LOG_ERROR, 4733 "sync_keyzone:dns_db_newversion -> %s", 4734 isc_result_totext(result)); 4735 goto cleanup; 4736 } 4737 4738 /* 4739 * Walk the zone DB. If we find any keys whose names are no longer 4740 * in trust-anchors, or which have been changed from initial to static, 4741 * (meaning they are permanent and not RFC5011-maintained), delete 4742 * them from the zone. Otherwise call load_secroots(), which 4743 * loads keys into secroots as appropriate. 4744 */ 4745 dns_rriterator_init(&rrit, db, ver, 0); 4746 for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS; 4747 result = dns_rriterator_nextrrset(&rrit)) 4748 { 4749 dns_rdataset_t *rdataset = NULL; 4750 dns_rdata_t rdata = DNS_RDATA_INIT; 4751 dns_rdata_keydata_t keydata; 4752 isc_stdtime_t now = isc_stdtime_now(); 4753 bool load = true; 4754 dns_name_t *rrname = NULL; 4755 uint32_t ttl; 4756 4757 dns_rriterator_current(&rrit, &rrname, &ttl, &rdataset, NULL); 4758 if (!dns_rdataset_isassociated(rdataset)) { 4759 dns_rriterator_destroy(&rrit); 4760 goto cleanup; 4761 } 4762 4763 if (rdataset->type != dns_rdatatype_keydata) { 4764 continue; 4765 } 4766 4767 /* 4768 * The managed-keys zone can contain a placeholder instead of 4769 * legitimate data, in which case we will not use it, and we 4770 * will try to refresh it. 4771 */ 4772 for (result = dns_rdataset_first(rdataset); 4773 result == ISC_R_SUCCESS; 4774 result = dns_rdataset_next(rdataset)) 4775 { 4776 isc_result_t iresult; 4777 4778 dns_rdata_reset(&rdata); 4779 dns_rdataset_current(rdataset, &rdata); 4780 4781 iresult = dns_rdata_tostruct(&rdata, &keydata, NULL); 4782 /* Do we have a valid placeholder KEYDATA record? */ 4783 if (iresult == ISC_R_SUCCESS && keydata.flags == 0 && 4784 keydata.protocol == 0 && keydata.algorithm == 0) 4785 { 4786 set_refreshkeytimer(zone, &keydata, now, true); 4787 load = false; 4788 } 4789 } 4790 4791 /* 4792 * Release db wrlock to prevent LOR reports against 4793 * dns_keytable_forall() call below. 4794 */ 4795 dns_rriterator_pause(&rrit); 4796 result = dns_keytable_find(sr, rrname, &keynode); 4797 if (result != ISC_R_SUCCESS || !dns_keynode_managed(keynode)) { 4798 CHECK(delete_keydata(db, ver, &diff, rrname, rdataset)); 4799 changed = true; 4800 } else if (load) { 4801 load_secroots(zone, rrname, rdataset); 4802 } 4803 4804 if (keynode != NULL) { 4805 dns_keynode_detach(&keynode); 4806 } 4807 } 4808 dns_rriterator_destroy(&rrit); 4809 4810 /* 4811 * Walk secroots to find any initial keys that aren't in 4812 * the zone. If we find any, add them to the zone directly. 4813 * If any DS-style initial keys are found, refresh the key 4814 * zone so that they'll be looked up. 4815 */ 4816 arg.db = db; 4817 arg.ver = ver; 4818 arg.result = ISC_R_SUCCESS; 4819 arg.diff = &diff; 4820 arg.zone = zone; 4821 arg.changed = &changed; 4822 dns_keytable_forall(sr, addifmissing, &arg); 4823 result = arg.result; 4824 if (changed) { 4825 /* Write changes to journal file. */ 4826 CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx, 4827 zone->updatemethod)); 4828 CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone")); 4829 4830 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 4831 zone_needdump(zone, 30); 4832 commit = true; 4833 } 4834 4835 cleanup: 4836 if (result != ISC_R_SUCCESS) { 4837 dnssec_log(zone, ISC_LOG_ERROR, 4838 "unable to synchronize managed keys: %s", 4839 isc_result_totext(result)); 4840 isc_time_settoepoch(&zone->refreshkeytime); 4841 } 4842 if (keynode != NULL) { 4843 dns_keynode_detach(&keynode); 4844 } 4845 if (sr != NULL) { 4846 dns_keytable_detach(&sr); 4847 } 4848 if (ver != NULL) { 4849 dns_db_closeversion(db, &ver, commit); 4850 } 4851 dns_diff_clear(&diff); 4852 4853 INSIST(ver == NULL); 4854 4855 return result; 4856 } 4857 4858 isc_result_t 4859 dns_zone_synckeyzone(dns_zone_t *zone) { 4860 isc_result_t result; 4861 dns_db_t *db = NULL; 4862 4863 if (zone->type != dns_zone_key) { 4864 return DNS_R_BADZONE; 4865 } 4866 4867 CHECK(dns_zone_getdb(zone, &db)); 4868 4869 LOCK_ZONE(zone); 4870 result = sync_keyzone(zone, db); 4871 UNLOCK_ZONE(zone); 4872 4873 cleanup: 4874 if (db != NULL) { 4875 dns_db_detach(&db); 4876 } 4877 return result; 4878 } 4879 4880 static void 4881 maybe_send_secure(dns_zone_t *zone) { 4882 isc_result_t result; 4883 4884 /* 4885 * We've finished loading, or else failed to load, an inline-signing 4886 * 'secure' zone. We now need information about the status of the 4887 * 'raw' zone. If we failed to load, then we need it to send a 4888 * copy of its database; if we succeeded, we need it to send its 4889 * serial number so that we can sync with it. If it has not yet 4890 * loaded, we set a flag so that it will send the necessary 4891 * information when it has finished loading. 4892 */ 4893 if (zone->raw->db != NULL) { 4894 if (zone->db != NULL) { 4895 uint32_t serial; 4896 unsigned int soacount; 4897 4898 result = zone_get_from_db( 4899 zone->raw, zone->raw->db, NULL, &soacount, NULL, 4900 &serial, NULL, NULL, NULL, NULL, NULL); 4901 if (result == ISC_R_SUCCESS && soacount > 0U) { 4902 zone_send_secureserial(zone->raw, serial); 4903 } 4904 } else { 4905 zone_send_securedb(zone->raw, zone->raw->db); 4906 } 4907 } else { 4908 DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE); 4909 } 4910 } 4911 4912 static bool 4913 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) { 4914 isc_result_t result; 4915 bool answer = false; 4916 dns_diff_t diff; 4917 4918 dns_diff_init(mctx, &diff); 4919 result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL); 4920 if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples)) { 4921 answer = true; 4922 } 4923 dns_diff_clear(&diff); 4924 return answer; 4925 } 4926 4927 static void 4928 process_zone_setnsec3param(dns_zone_t *zone) { 4929 struct np3 *npe = NULL; 4930 while ((npe = ISC_LIST_HEAD(zone->setnsec3param_queue)) != NULL) { 4931 ISC_LIST_UNLINK(zone->setnsec3param_queue, npe, link); 4932 zone_iattach(zone, &npe->zone); 4933 isc_async_run(zone->loop, setnsec3param, npe); 4934 } 4935 } 4936 4937 /* 4938 * The zone is presumed to be locked. 4939 * If this is a inline_raw zone the secure version is also locked. 4940 */ 4941 static isc_result_t 4942 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, 4943 isc_result_t result) { 4944 unsigned int soacount = 0; 4945 unsigned int nscount = 0; 4946 unsigned int errors = 0; 4947 uint32_t serial, oldserial, refresh, retry, expire, minimum, soattl; 4948 isc_time_t now; 4949 bool needdump = false; 4950 bool fixjournal = false; 4951 bool hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE); 4952 bool noprimary = false; 4953 bool had_db = false; 4954 dns_include_t *inc; 4955 bool is_dynamic = false; 4956 4957 INSIST(LOCKED_ZONE(zone)); 4958 if (inline_raw(zone)) { 4959 INSIST(LOCKED_ZONE(zone->secure)); 4960 } 4961 4962 now = isc_time_now(); 4963 4964 /* 4965 * Initiate zone transfer? We may need a error code that 4966 * indicates that the "permanent" form does not exist. 4967 * XXX better error feedback to log. 4968 */ 4969 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { 4970 if (zone->type == dns_zone_secondary || 4971 zone->type == dns_zone_mirror || 4972 zone->type == dns_zone_stub || 4973 (zone->type == dns_zone_redirect && 4974 dns_remote_addresses(&zone->primaries) == NULL)) 4975 { 4976 if (result == ISC_R_FILENOTFOUND) { 4977 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4978 ISC_LOG_DEBUG(1), 4979 "no master file"); 4980 } else if (result != DNS_R_NOMASTERFILE) { 4981 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4982 ISC_LOG_ERROR, 4983 "loading from master file %s " 4984 "failed: %s", 4985 zone->masterfile, 4986 isc_result_totext(result)); 4987 } 4988 } else if (zone->type == dns_zone_primary && 4989 inline_secure(zone) && result == ISC_R_FILENOTFOUND) 4990 { 4991 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4992 ISC_LOG_DEBUG(1), 4993 "no master file, requesting db"); 4994 maybe_send_secure(zone); 4995 } else { 4996 int level = ISC_LOG_ERROR; 4997 if (zone->type == dns_zone_key && 4998 result == ISC_R_FILENOTFOUND) 4999 { 5000 level = ISC_LOG_DEBUG(1); 5001 } 5002 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, level, 5003 "loading from master file %s failed: %s", 5004 zone->masterfile, 5005 isc_result_totext(result)); 5006 noprimary = true; 5007 } 5008 5009 if (zone->type != dns_zone_key) { 5010 goto cleanup; 5011 } 5012 } 5013 5014 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(2), 5015 "number of nodes in database: %u", 5016 dns_db_nodecount(db, dns_dbtree_main)); 5017 5018 if (result == DNS_R_SEENINCLUDE) { 5019 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 5020 } else { 5021 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 5022 } 5023 5024 /* 5025 * If there's no master file for a key zone, then the zone is new: 5026 * create an SOA record. (We do this now, instead of later, so that 5027 * if there happens to be a journal file, we can roll forward from 5028 * a sane starting point.) 5029 */ 5030 if (noprimary && zone->type == dns_zone_key) { 5031 result = add_soa(zone, db); 5032 if (result != ISC_R_SUCCESS) { 5033 goto cleanup; 5034 } 5035 } 5036 5037 /* 5038 * Apply update log, if any, on initial load. 5039 */ 5040 if (zone->journal != NULL && 5041 !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) && 5042 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 5043 { 5044 result = zone_journal_rollforward(zone, db, &needdump, 5045 &fixjournal); 5046 if (result != ISC_R_SUCCESS) { 5047 goto cleanup; 5048 } 5049 } 5050 5051 /* 5052 * Obtain ns, soa and cname counts for top of zone. 5053 */ 5054 INSIST(db != NULL); 5055 result = zone_get_from_db(zone, db, &nscount, &soacount, &soattl, 5056 &serial, &refresh, &retry, &expire, &minimum, 5057 &errors); 5058 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) { 5059 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 5060 "could not find NS and/or SOA records"); 5061 } 5062 5063 /* 5064 * Process any queued NSEC3PARAM change requests. Only for dynamic 5065 * zones, an inline-signing zone will perform this action when 5066 * receiving the secure db (receive_secure_db). 5067 */ 5068 is_dynamic = dns_zone_isdynamic(zone, true); 5069 if (is_dynamic) { 5070 process_zone_setnsec3param(zone); 5071 } 5072 5073 /* 5074 * Check to make sure the journal is up to date, and remove the 5075 * journal file if it isn't, as we wouldn't be able to apply 5076 * updates otherwise. 5077 */ 5078 if (zone->journal != NULL && is_dynamic && 5079 !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) 5080 { 5081 uint32_t jserial; 5082 dns_journal_t *journal = NULL; 5083 bool empty = false; 5084 5085 result = dns_journal_open(zone->mctx, zone->journal, 5086 DNS_JOURNAL_READ, &journal); 5087 if (result == ISC_R_SUCCESS) { 5088 jserial = dns_journal_last_serial(journal); 5089 empty = dns_journal_empty(journal); 5090 dns_journal_destroy(&journal); 5091 } else { 5092 jserial = serial; 5093 result = ISC_R_SUCCESS; 5094 } 5095 5096 if (jserial != serial) { 5097 if (!empty) { 5098 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5099 ISC_LOG_INFO, 5100 "journal file is out of date: " 5101 "removing journal file"); 5102 } 5103 if (remove(zone->journal) < 0 && errno != ENOENT) { 5104 char strbuf[ISC_STRERRORSIZE]; 5105 strerror_r(errno, strbuf, sizeof(strbuf)); 5106 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 5107 DNS_LOGMODULE_ZONE, 5108 ISC_LOG_WARNING, 5109 "unable to remove journal " 5110 "'%s': '%s'", 5111 zone->journal, strbuf); 5112 } 5113 } 5114 } 5115 5116 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1), 5117 "loaded; checking validity"); 5118 5119 /* 5120 * Primary / Secondary / Mirror / Stub zones require both NS and SOA 5121 * records at the top of the zone. 5122 */ 5123 5124 switch (zone->type) { 5125 case dns_zone_dlz: 5126 case dns_zone_primary: 5127 case dns_zone_secondary: 5128 case dns_zone_mirror: 5129 case dns_zone_stub: 5130 case dns_zone_redirect: 5131 if (soacount != 1) { 5132 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5133 ISC_LOG_ERROR, "has %d SOA records", 5134 soacount); 5135 result = DNS_R_BADZONE; 5136 } 5137 if (nscount == 0) { 5138 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5139 ISC_LOG_ERROR, "has no NS records"); 5140 result = DNS_R_BADZONE; 5141 } 5142 if (result != ISC_R_SUCCESS) { 5143 goto cleanup; 5144 } 5145 if (zone->type == dns_zone_primary && errors != 0) { 5146 result = DNS_R_BADZONE; 5147 goto cleanup; 5148 } 5149 if (zone->type != dns_zone_stub && 5150 zone->type != dns_zone_redirect) 5151 { 5152 result = check_nsec3param(zone, db); 5153 if (result != ISC_R_SUCCESS) { 5154 goto cleanup; 5155 } 5156 } 5157 if (zone->type == dns_zone_primary && 5158 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) && 5159 !integrity_checks(zone, db)) 5160 { 5161 result = DNS_R_BADZONE; 5162 goto cleanup; 5163 } 5164 if (zone->type == dns_zone_primary && 5165 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) && 5166 !zone_check_dup(zone, db)) 5167 { 5168 result = DNS_R_BADZONE; 5169 goto cleanup; 5170 } 5171 5172 if (zone->type == dns_zone_primary) { 5173 result = dns_zone_cdscheck(zone, db, NULL); 5174 if (result != ISC_R_SUCCESS) { 5175 dns_zone_log(zone, ISC_LOG_ERROR, 5176 "CDS/CDNSKEY consistency checks " 5177 "failed"); 5178 goto cleanup; 5179 } 5180 } 5181 5182 result = dns_zone_verifydb(zone, db, NULL); 5183 if (result != ISC_R_SUCCESS) { 5184 goto cleanup; 5185 } 5186 5187 if (zone->db != NULL) { 5188 unsigned int oldsoacount; 5189 5190 /* 5191 * This is checked in zone_replacedb() for 5192 * secondary zones as they don't reload from disk. 5193 */ 5194 result = zone_get_from_db( 5195 zone, zone->db, NULL, &oldsoacount, NULL, 5196 &oldserial, NULL, NULL, NULL, NULL, NULL); 5197 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5198 RUNTIME_CHECK(oldsoacount > 0U); 5199 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 5200 !isc_serial_gt(serial, oldserial)) 5201 { 5202 uint32_t serialmin, serialmax; 5203 5204 INSIST(zone->type == dns_zone_primary); 5205 INSIST(zone->raw == NULL); 5206 5207 if (serial == oldserial && 5208 zone_unchanged(zone->db, db, zone->mctx)) 5209 { 5210 dns_zone_logc(zone, 5211 DNS_LOGCATEGORY_ZONELOAD, 5212 ISC_LOG_INFO, 5213 "ixfr-from-differences: " 5214 "unchanged"); 5215 zone->loadtime = loadtime; 5216 goto done; 5217 } 5218 5219 serialmin = (oldserial + 1) & 0xffffffffU; 5220 serialmax = (oldserial + 0x7fffffffU) & 5221 0xffffffffU; 5222 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5223 ISC_LOG_ERROR, 5224 "ixfr-from-differences: " 5225 "new serial (%u) out of range " 5226 "[%u - %u]", 5227 serial, serialmin, serialmax); 5228 result = DNS_R_BADZONE; 5229 goto cleanup; 5230 } else if (!isc_serial_ge(serial, oldserial)) { 5231 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5232 ISC_LOG_ERROR, 5233 "zone serial (%u/%u) has gone " 5234 "backwards", 5235 serial, oldserial); 5236 } else if (serial == oldserial && !hasinclude && 5237 strcmp(zone->db_argv[0], "_builtin") != 0) 5238 { 5239 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5240 ISC_LOG_ERROR, 5241 "zone serial (%u) unchanged. " 5242 "zone may fail to transfer " 5243 "to secondaries.", 5244 serial); 5245 } 5246 } 5247 5248 if (zone->type == dns_zone_primary && 5249 (zone->update_acl != NULL || zone->ssutable != NULL) && 5250 dns_zone_getsigresigninginterval(zone) < (3 * refresh) && 5251 dns_db_issecure(db)) 5252 { 5253 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5254 ISC_LOG_WARNING, 5255 "sig-re-signing-interval less than " 5256 "3 * refresh."); 5257 } 5258 5259 zone->refresh = RANGE(refresh, zone->minrefresh, 5260 zone->maxrefresh); 5261 zone->retry = RANGE(retry, zone->minretry, zone->maxretry); 5262 zone->expire = RANGE(expire, zone->refresh + zone->retry, 5263 DNS_MAX_EXPIRE); 5264 zone->soattl = soattl; 5265 zone->minimum = minimum; 5266 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 5267 5268 if (zone->type == dns_zone_secondary || 5269 zone->type == dns_zone_mirror || 5270 zone->type == dns_zone_stub || 5271 (zone->type == dns_zone_redirect && 5272 dns_remote_addresses(&zone->primaries) != NULL)) 5273 { 5274 isc_time_t t; 5275 uint32_t delay; 5276 5277 result = isc_file_getmodtime(zone->journal, &t); 5278 if (result != ISC_R_SUCCESS) { 5279 result = isc_file_getmodtime(zone->masterfile, 5280 &t); 5281 } 5282 if (result == ISC_R_SUCCESS) { 5283 DNS_ZONE_TIME_ADD(&t, zone->expire, 5284 &zone->expiretime); 5285 } else { 5286 DNS_ZONE_TIME_ADD(&now, zone->retry, 5287 &zone->expiretime); 5288 } 5289 5290 delay = (zone->retry - 5291 isc_random_uniform((zone->retry * 3) / 4)); 5292 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime); 5293 if (isc_time_compare(&zone->refreshtime, 5294 &zone->expiretime) >= 0) 5295 { 5296 DNS_ZONE_SETFLAG(zone, 5297 DNS_ZONEFLG_FIRSTREFRESH); 5298 zone->refreshtime = now; 5299 } else { 5300 /* The zone is up to date. */ 5301 DNS_ZONE_CLRFLAG(zone, 5302 DNS_ZONEFLG_FIRSTREFRESH); 5303 } 5304 } 5305 5306 break; 5307 5308 case dns_zone_key: 5309 /* Nothing needs to be done now */ 5310 break; 5311 5312 default: 5313 UNEXPECTED_ERROR("unexpected zone type %d", zone->type); 5314 result = ISC_R_UNEXPECTED; 5315 goto cleanup; 5316 } 5317 5318 /* 5319 * Check for weak DNSKEY's. 5320 */ 5321 if (zone->type == dns_zone_primary) { 5322 zone_check_dnskeys(zone, db); 5323 } 5324 5325 /* 5326 * Schedule DNSSEC key refresh. 5327 */ 5328 if (zone->type == dns_zone_primary && 5329 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 5330 { 5331 zone->refreshkeytime = now; 5332 } 5333 5334 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 5335 if (zone->db != NULL) { 5336 had_db = true; 5337 result = zone_replacedb(zone, db, false); 5338 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 5339 if (result != ISC_R_SUCCESS) { 5340 goto cleanup; 5341 } 5342 } else { 5343 zone_attachdb(zone, db); 5344 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 5345 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | 5346 DNS_ZONEFLG_NEEDSTARTUPNOTIFY); 5347 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) && 5348 inline_raw(zone)) 5349 { 5350 if (zone->secure->db == NULL) { 5351 zone_send_securedb(zone, db); 5352 } else { 5353 zone_send_secureserial(zone, serial); 5354 } 5355 } 5356 } 5357 5358 /* 5359 * Finished loading inline-signing zone; need to get status 5360 * from the raw side now. 5361 */ 5362 if (zone->type == dns_zone_primary && inline_secure(zone)) { 5363 maybe_send_secure(zone); 5364 } 5365 5366 result = ISC_R_SUCCESS; 5367 5368 if (fixjournal) { 5369 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FIXJOURNAL); 5370 zone_journal_compact(zone, zone->db, 0); 5371 } 5372 if (needdump) { 5373 if (zone->type == dns_zone_key) { 5374 zone_needdump(zone, 30); 5375 } else { 5376 zone_needdump(zone, DNS_DUMP_DELAY); 5377 } 5378 } 5379 5380 if (zone->loop != NULL) { 5381 if (zone->type == dns_zone_primary) { 5382 set_resigntime(zone); 5383 resume_signingwithkey(zone); 5384 resume_addnsec3chain(zone); 5385 } 5386 5387 is_dynamic = dns_zone_isdynamic(zone, false); 5388 if (zone->type == dns_zone_primary && is_dynamic && 5389 dns_db_issecure(db) && !inline_raw(zone)) 5390 { 5391 isc_stdtime_t resign; 5392 dns_name_t *name; 5393 dns_fixedname_t fixed; 5394 dns_typepair_t typepair; 5395 5396 name = dns_fixedname_initname(&fixed); 5397 5398 result = dns_db_getsigningtime(db, &resign, name, 5399 &typepair); 5400 if (result == ISC_R_SUCCESS) { 5401 isc_stdtime_t timenow = isc_stdtime_now(); 5402 char namebuf[DNS_NAME_FORMATSIZE]; 5403 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 5404 5405 dns_name_format(name, namebuf, sizeof(namebuf)); 5406 dns_rdatatype_format( 5407 DNS_TYPEPAIR_COVERS(typepair), typebuf, 5408 sizeof(typebuf)); 5409 dnssec_log( 5410 zone, ISC_LOG_DEBUG(3), 5411 "next resign: %s/%s " 5412 "in %d seconds", 5413 namebuf, typebuf, 5414 resign - timenow - 5415 dns_zone_getsigresigninginterval( 5416 zone)); 5417 } else { 5418 dnssec_log(zone, ISC_LOG_WARNING, 5419 "signed dynamic zone has no " 5420 "resign event scheduled"); 5421 } 5422 } 5423 5424 zone_settimer(zone, &now); 5425 } 5426 5427 /* 5428 * Clear old include list. 5429 */ 5430 for (inc = ISC_LIST_HEAD(zone->includes); inc != NULL; 5431 inc = ISC_LIST_HEAD(zone->includes)) 5432 { 5433 ISC_LIST_UNLINK(zone->includes, inc, link); 5434 isc_mem_free(zone->mctx, inc->name); 5435 isc_mem_put(zone->mctx, inc, sizeof(*inc)); 5436 } 5437 zone->nincludes = 0; 5438 5439 /* 5440 * Transfer new include list. 5441 */ 5442 for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; 5443 inc = ISC_LIST_HEAD(zone->newincludes)) 5444 { 5445 ISC_LIST_UNLINK(zone->newincludes, inc, link); 5446 ISC_LIST_APPEND(zone->includes, inc, link); 5447 zone->nincludes++; 5448 } 5449 5450 if (!dns_db_ispersistent(db)) { 5451 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO, 5452 "loaded serial %u%s", serial, 5453 dns_db_issecure(db) ? " (DNSSEC signed)" : ""); 5454 } 5455 5456 if (!had_db && zone->type == dns_zone_mirror) { 5457 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO, 5458 "mirror zone is now in use"); 5459 } 5460 5461 zone->loadtime = loadtime; 5462 goto done; 5463 5464 cleanup: 5465 if (result != ISC_R_SUCCESS) { 5466 dns_zone_rpz_disable_db(zone, db); 5467 dns_zone_catz_disable_db(zone, db); 5468 } 5469 5470 for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; 5471 inc = ISC_LIST_HEAD(zone->newincludes)) 5472 { 5473 ISC_LIST_UNLINK(zone->newincludes, inc, link); 5474 isc_mem_free(zone->mctx, inc->name); 5475 isc_mem_put(zone->mctx, inc, sizeof(*inc)); 5476 } 5477 if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror || 5478 zone->type == dns_zone_stub || zone->type == dns_zone_key || 5479 (zone->type == dns_zone_redirect && 5480 dns_remote_addresses(&zone->primaries) != NULL)) 5481 { 5482 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FIRSTREFRESH); 5483 5484 if (result != ISC_R_NOMEMORY) { 5485 if (zone->journal != NULL) { 5486 zone_saveunique(zone, zone->journal, 5487 "jn-XXXXXXXX"); 5488 } 5489 if (zone->masterfile != NULL) { 5490 zone_saveunique(zone, zone->masterfile, 5491 "db-XXXXXXXX"); 5492 } 5493 } 5494 5495 /* Mark the zone for immediate refresh. */ 5496 zone->refreshtime = now; 5497 if (zone->loop != NULL) { 5498 zone_settimer(zone, &now); 5499 } 5500 result = ISC_R_SUCCESS; 5501 } else if (zone->type == dns_zone_primary || 5502 zone->type == dns_zone_redirect) 5503 { 5504 if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND)) { 5505 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5506 ISC_LOG_ERROR, 5507 "not loaded due to errors."); 5508 } else if (zone->type == dns_zone_primary) { 5509 result = ISC_R_SUCCESS; 5510 } 5511 } 5512 5513 done: 5514 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); 5515 /* 5516 * If this is an inline-signed zone and we were called for the raw 5517 * zone, we need to clear DNS_ZONEFLG_LOADPENDING for the secure zone 5518 * as well, but only if this is a reload, not an initial zone load: in 5519 * the former case, zone_postload() will not be run for the secure 5520 * zone; in the latter case, it will be. Check which case we are 5521 * dealing with by consulting the DNS_ZONEFLG_LOADED flag for the 5522 * secure zone: if it is set, this must be a reload. 5523 */ 5524 if (inline_raw(zone) && DNS_ZONE_FLAG(zone->secure, DNS_ZONEFLG_LOADED)) 5525 { 5526 DNS_ZONE_CLRFLAG(zone->secure, DNS_ZONEFLG_LOADPENDING); 5527 /* 5528 * Re-start zone maintenance if it had been stalled 5529 * due to DNS_ZONEFLG_LOADPENDING being set when 5530 * zone_maintenance was called. 5531 */ 5532 if (zone->secure->loop != NULL) { 5533 zone_settimer(zone->secure, &now); 5534 } 5535 } 5536 5537 zone_debuglog(zone, __func__, 99, "done"); 5538 5539 return result; 5540 } 5541 5542 static bool 5543 exit_check(dns_zone_t *zone) { 5544 REQUIRE(LOCKED_ZONE(zone)); 5545 5546 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && 5547 isc_refcount_current(&zone->irefs) == 0) 5548 { 5549 /* 5550 * DNS_ZONEFLG_SHUTDOWN can only be set if references == 0. 5551 */ 5552 INSIST(isc_refcount_current(&zone->references) == 0); 5553 return true; 5554 } 5555 return false; 5556 } 5557 5558 static bool 5559 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 5560 dns_name_t *name, bool logit) { 5561 isc_result_t result; 5562 char namebuf[DNS_NAME_FORMATSIZE]; 5563 char altbuf[DNS_NAME_FORMATSIZE]; 5564 dns_fixedname_t fixed; 5565 dns_name_t *foundname; 5566 int level; 5567 5568 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) { 5569 return true; 5570 } 5571 5572 if (zone->type == dns_zone_primary) { 5573 level = ISC_LOG_ERROR; 5574 } else { 5575 level = ISC_LOG_WARNING; 5576 } 5577 5578 foundname = dns_fixedname_initname(&fixed); 5579 5580 result = dns_db_find(db, name, version, dns_rdatatype_a, 0, 0, NULL, 5581 foundname, NULL, NULL); 5582 if (result == ISC_R_SUCCESS) { 5583 return true; 5584 } 5585 5586 if (result == DNS_R_NXRRSET) { 5587 result = dns_db_find(db, name, version, dns_rdatatype_aaaa, 0, 5588 0, NULL, foundname, NULL, NULL); 5589 if (result == ISC_R_SUCCESS) { 5590 return true; 5591 } 5592 } 5593 5594 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 5595 result == DNS_R_EMPTYNAME) 5596 { 5597 if (logit) { 5598 dns_name_format(name, namebuf, sizeof namebuf); 5599 dns_zone_log(zone, level, 5600 "NS '%s' has no address " 5601 "records (A or AAAA)", 5602 namebuf); 5603 } 5604 return false; 5605 } 5606 5607 if (result == DNS_R_CNAME) { 5608 if (logit) { 5609 dns_name_format(name, namebuf, sizeof namebuf); 5610 dns_zone_log(zone, level, 5611 "NS '%s' is a CNAME " 5612 "(illegal)", 5613 namebuf); 5614 } 5615 return false; 5616 } 5617 5618 if (result == DNS_R_DNAME) { 5619 if (logit) { 5620 dns_name_format(name, namebuf, sizeof namebuf); 5621 dns_name_format(foundname, altbuf, sizeof altbuf); 5622 dns_zone_log(zone, level, 5623 "NS '%s' is below a DNAME " 5624 "'%s' (illegal)", 5625 namebuf, altbuf); 5626 } 5627 return false; 5628 } 5629 5630 return true; 5631 } 5632 5633 static isc_result_t 5634 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, 5635 dns_dbversion_t *version, unsigned int *nscount, 5636 unsigned int *errors, bool logit) { 5637 isc_result_t result; 5638 unsigned int count = 0; 5639 unsigned int ecount = 0; 5640 dns_rdataset_t rdataset; 5641 dns_rdata_t rdata; 5642 dns_rdata_ns_t ns; 5643 5644 dns_rdataset_init(&rdataset); 5645 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns, 5646 dns_rdatatype_none, 0, &rdataset, NULL); 5647 if (result == ISC_R_NOTFOUND) { 5648 INSIST(!dns_rdataset_isassociated(&rdataset)); 5649 goto success; 5650 } 5651 if (result != ISC_R_SUCCESS) { 5652 INSIST(!dns_rdataset_isassociated(&rdataset)); 5653 goto invalidate_rdataset; 5654 } 5655 5656 result = dns_rdataset_first(&rdataset); 5657 while (result == ISC_R_SUCCESS) { 5658 if (errors != NULL && zone->rdclass == dns_rdataclass_in && 5659 (zone->type == dns_zone_primary || 5660 zone->type == dns_zone_secondary || 5661 zone->type == dns_zone_mirror)) 5662 { 5663 dns_rdata_init(&rdata); 5664 dns_rdataset_current(&rdataset, &rdata); 5665 result = dns_rdata_tostruct(&rdata, &ns, NULL); 5666 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5667 if (dns_name_issubdomain(&ns.name, &zone->origin) && 5668 !zone_check_ns(zone, db, version, &ns.name, logit)) 5669 { 5670 ecount++; 5671 } 5672 } 5673 count++; 5674 result = dns_rdataset_next(&rdataset); 5675 } 5676 dns_rdataset_disassociate(&rdataset); 5677 5678 success: 5679 SET_IF_NOT_NULL(nscount, count); 5680 SET_IF_NOT_NULL(errors, ecount); 5681 5682 result = ISC_R_SUCCESS; 5683 5684 invalidate_rdataset: 5685 dns_rdataset_invalidate(&rdataset); 5686 5687 return result; 5688 } 5689 5690 #define SET_SOA_VALUES(soattl_v, serial_v, refresh_v, retry_v, expire_v, \ 5691 minimum_v) \ 5692 { \ 5693 SET_IF_NOT_NULL(soattl, soattl_v); \ 5694 SET_IF_NOT_NULL(serial, serial_v); \ 5695 SET_IF_NOT_NULL(refresh, refresh_v); \ 5696 SET_IF_NOT_NULL(retry, retry_v); \ 5697 SET_IF_NOT_NULL(expire, expire_v); \ 5698 SET_IF_NOT_NULL(minimum, minimum_v); \ 5699 } 5700 5701 #define CLR_SOA_VALUES() \ 5702 { \ 5703 SET_SOA_VALUES(0, 0, 0, 0, 0, 0); \ 5704 } 5705 5706 static isc_result_t 5707 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 5708 unsigned int *soacount, uint32_t *soattl, uint32_t *serial, 5709 uint32_t *refresh, uint32_t *retry, uint32_t *expire, 5710 uint32_t *minimum) { 5711 isc_result_t result; 5712 unsigned int count = 0; 5713 dns_rdataset_t rdataset; 5714 dns_rdata_t rdata = DNS_RDATA_INIT; 5715 5716 dns_rdataset_init(&rdataset); 5717 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, 5718 dns_rdatatype_none, 0, &rdataset, NULL); 5719 if (result == ISC_R_NOTFOUND) { 5720 INSIST(!dns_rdataset_isassociated(&rdataset)); 5721 result = ISC_R_SUCCESS; 5722 goto invalidate_rdataset; 5723 } 5724 if (result != ISC_R_SUCCESS) { 5725 INSIST(!dns_rdataset_isassociated(&rdataset)); 5726 goto invalidate_rdataset; 5727 } 5728 5729 result = dns_rdataset_first(&rdataset); 5730 while (result == ISC_R_SUCCESS) { 5731 dns_rdata_init(&rdata); 5732 dns_rdataset_current(&rdataset, &rdata); 5733 count++; 5734 if (count == 1) { 5735 dns_rdata_soa_t soa; 5736 result = dns_rdata_tostruct(&rdata, &soa, NULL); 5737 SET_SOA_VALUES(rdataset.ttl, soa.serial, soa.refresh, 5738 soa.retry, soa.expire, soa.minimum); 5739 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5740 } 5741 5742 result = dns_rdataset_next(&rdataset); 5743 dns_rdata_reset(&rdata); 5744 } 5745 dns_rdataset_disassociate(&rdataset); 5746 5747 result = ISC_R_SUCCESS; 5748 5749 invalidate_rdataset: 5750 SET_IF_NOT_NULL(soacount, count); 5751 if (count == 0) { 5752 CLR_SOA_VALUES(); 5753 } 5754 5755 dns_rdataset_invalidate(&rdataset); 5756 5757 return result; 5758 } 5759 5760 /* 5761 * zone must be locked. 5762 */ 5763 static isc_result_t 5764 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 5765 unsigned int *soacount, uint32_t *soattl, uint32_t *serial, 5766 uint32_t *refresh, uint32_t *retry, uint32_t *expire, 5767 uint32_t *minimum, unsigned int *errors) { 5768 isc_result_t result; 5769 isc_result_t answer = ISC_R_SUCCESS; 5770 dns_dbversion_t *version = NULL; 5771 dns_dbnode_t *node; 5772 5773 REQUIRE(db != NULL); 5774 REQUIRE(zone != NULL); 5775 5776 dns_db_currentversion(db, &version); 5777 5778 SET_IF_NOT_NULL(nscount, 0); 5779 SET_IF_NOT_NULL(soacount, 0); 5780 SET_IF_NOT_NULL(errors, 0); 5781 CLR_SOA_VALUES(); 5782 5783 node = NULL; 5784 result = dns_db_findnode(db, &zone->origin, false, &node); 5785 if (result != ISC_R_SUCCESS) { 5786 answer = result; 5787 goto closeversion; 5788 } 5789 5790 if (nscount != NULL || errors != NULL) { 5791 result = zone_count_ns_rr(zone, db, node, version, nscount, 5792 errors, true); 5793 if (result != ISC_R_SUCCESS) { 5794 answer = result; 5795 } 5796 } 5797 5798 if (soacount != NULL || soattl != NULL || serial != NULL || 5799 refresh != NULL || retry != NULL || expire != NULL || 5800 minimum != NULL) 5801 { 5802 result = zone_load_soa_rr(db, node, version, soacount, soattl, 5803 serial, refresh, retry, expire, 5804 minimum); 5805 if (result != ISC_R_SUCCESS) { 5806 answer = result; 5807 } 5808 } 5809 5810 dns_db_detachnode(db, &node); 5811 closeversion: 5812 dns_db_closeversion(db, &version, false); 5813 5814 return answer; 5815 } 5816 5817 static void 5818 zone_destroy(dns_zone_t *zone) { 5819 /* 5820 * Stop things being restarted after we cancel them below. 5821 */ 5822 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING); 5823 dns_zone_log(zone, ISC_LOG_DEBUG(1), "final reference detached"); 5824 5825 if (zone->loop == NULL) { 5826 /* 5827 * This zone is unmanaged; we're probably running in 5828 * named-checkzone or a unit test. There's no loop, so we 5829 * need to free it immediately. 5830 */ 5831 zone_shutdown(zone); 5832 } else { 5833 /* 5834 * This zone has a loop; it can clean 5835 * itself up asynchronously. 5836 */ 5837 isc_async_run(zone->loop, zone_shutdown, zone); 5838 } 5839 } 5840 5841 #if DNS_ZONE_TRACE 5842 ISC_REFCOUNT_TRACE_IMPL(dns_zone, zone_destroy); 5843 #else 5844 ISC_REFCOUNT_IMPL(dns_zone, zone_destroy); 5845 #endif 5846 5847 void 5848 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) { 5849 REQUIRE(DNS_ZONE_VALID(source)); 5850 5851 LOCK_ZONE(source); 5852 zone_iattach(source, target); 5853 UNLOCK_ZONE(source); 5854 } 5855 5856 static void 5857 zone_iattach(dns_zone_t *source, dns_zone_t **target) { 5858 REQUIRE(DNS_ZONE_VALID(source)); 5859 REQUIRE(LOCKED_ZONE(source)); 5860 REQUIRE(target != NULL && *target == NULL); 5861 INSIST(isc_refcount_increment0(&source->irefs) + 5862 isc_refcount_current(&source->references) > 5863 0); 5864 *target = source; 5865 } 5866 5867 static void 5868 zone_idetach(dns_zone_t **zonep) { 5869 dns_zone_t *zone; 5870 5871 /* 5872 * 'zone' locked by caller. 5873 */ 5874 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 5875 REQUIRE(LOCKED_ZONE(*zonep)); 5876 5877 zone = *zonep; 5878 *zonep = NULL; 5879 5880 INSIST(isc_refcount_decrement(&zone->irefs) - 1 + 5881 isc_refcount_current(&zone->references) > 5882 0); 5883 } 5884 5885 void 5886 dns_zone_idetach(dns_zone_t **zonep) { 5887 dns_zone_t *zone; 5888 5889 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 5890 5891 zone = *zonep; 5892 *zonep = NULL; 5893 5894 if (isc_refcount_decrement(&zone->irefs) == 1) { 5895 bool free_needed; 5896 LOCK_ZONE(zone); 5897 free_needed = exit_check(zone); 5898 UNLOCK_ZONE(zone); 5899 if (free_needed) { 5900 zone_free(zone); 5901 } 5902 } 5903 } 5904 5905 isc_mem_t * 5906 dns_zone_getmctx(dns_zone_t *zone) { 5907 REQUIRE(DNS_ZONE_VALID(zone)); 5908 5909 return zone->mctx; 5910 } 5911 5912 dns_zonemgr_t * 5913 dns_zone_getmgr(dns_zone_t *zone) { 5914 REQUIRE(DNS_ZONE_VALID(zone)); 5915 5916 return zone->zmgr; 5917 } 5918 5919 void 5920 dns_zone_setkasp(dns_zone_t *zone, dns_kasp_t *kasp) { 5921 REQUIRE(DNS_ZONE_VALID(zone)); 5922 5923 LOCK_ZONE(zone); 5924 if (zone->kasp != NULL) { 5925 dns_kasp_detach(&zone->kasp); 5926 } 5927 if (kasp != NULL) { 5928 dns_kasp_attach(kasp, &zone->kasp); 5929 } 5930 UNLOCK_ZONE(zone); 5931 } 5932 5933 void 5934 dns_zone_setdefaultkasp(dns_zone_t *zone, dns_kasp_t *kasp) { 5935 REQUIRE(DNS_ZONE_VALID(zone)); 5936 5937 LOCK_ZONE(zone); 5938 if (zone->defaultkasp != NULL) { 5939 dns_kasp_detach(&zone->defaultkasp); 5940 } 5941 if (kasp != NULL) { 5942 dns_kasp_attach(kasp, &zone->defaultkasp); 5943 } 5944 UNLOCK_ZONE(zone); 5945 } 5946 5947 dns_kasp_t * 5948 dns_zone_getkasp(dns_zone_t *zone) { 5949 dns_kasp_t *kasp; 5950 5951 REQUIRE(DNS_ZONE_VALID(zone)); 5952 5953 LOCK_ZONE(zone); 5954 if (inline_raw(zone) && zone->secure != NULL) { 5955 kasp = zone->secure->kasp; 5956 } else { 5957 kasp = zone->kasp; 5958 } 5959 UNLOCK_ZONE(zone); 5960 5961 return kasp; 5962 } 5963 5964 static void 5965 dns_zone_setskr(dns_zone_t *zone, dns_skr_t *skr) { 5966 REQUIRE(DNS_ZONE_VALID(zone)); 5967 5968 LOCK_ZONE(zone); 5969 zone->skrbundle = NULL; 5970 if (zone->skr != NULL) { 5971 dns_skr_detach(&zone->skr); 5972 } 5973 if (skr != NULL) { 5974 dns_skr_attach(skr, &zone->skr); 5975 } 5976 UNLOCK_ZONE(zone); 5977 } 5978 5979 dns_skrbundle_t * 5980 dns_zone_getskrbundle(dns_zone_t *zone) { 5981 dns_skrbundle_t *bundle; 5982 5983 REQUIRE(DNS_ZONE_VALID(zone)); 5984 5985 LOCK_ZONE(zone); 5986 if (inline_raw(zone) && zone->secure != NULL) { 5987 bundle = zone->secure->skrbundle; 5988 } else { 5989 bundle = zone->skrbundle; 5990 } 5991 UNLOCK_ZONE(zone); 5992 5993 return bundle; 5994 } 5995 5996 void 5997 dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option, bool value) { 5998 REQUIRE(DNS_ZONE_VALID(zone)); 5999 6000 if (value) { 6001 DNS_ZONE_SETOPTION(zone, option); 6002 } else { 6003 DNS_ZONE_CLROPTION(zone, option); 6004 } 6005 } 6006 6007 dns_zoneopt_t 6008 dns_zone_getoptions(dns_zone_t *zone) { 6009 REQUIRE(DNS_ZONE_VALID(zone)); 6010 6011 return ISC_ZONE_GET(zone, options); 6012 } 6013 6014 void 6015 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, bool value) { 6016 REQUIRE(DNS_ZONE_VALID(zone)); 6017 6018 if (value) { 6019 DNS_ZONEKEY_SETOPTION(zone, keyopt); 6020 } else { 6021 DNS_ZONEKEY_CLROPTION(zone, keyopt); 6022 } 6023 } 6024 6025 unsigned int 6026 dns_zone_getkeyopts(dns_zone_t *zone) { 6027 REQUIRE(DNS_ZONE_VALID(zone)); 6028 6029 return ISC_ZONE_GET(zone, keyopts); 6030 } 6031 6032 void 6033 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 6034 REQUIRE(DNS_ZONE_VALID(zone)); 6035 REQUIRE(xfrsource != NULL); 6036 6037 LOCK_ZONE(zone); 6038 zone->xfrsource4 = *xfrsource; 6039 UNLOCK_ZONE(zone); 6040 } 6041 6042 void 6043 dns_zone_getxfrsource4(dns_zone_t *zone, isc_sockaddr_t *xfrsource) { 6044 REQUIRE(DNS_ZONE_VALID(zone)); 6045 REQUIRE(xfrsource != NULL); 6046 6047 LOCK_ZONE(zone); 6048 *xfrsource = zone->xfrsource4; 6049 UNLOCK_ZONE(zone); 6050 } 6051 6052 void 6053 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 6054 REQUIRE(DNS_ZONE_VALID(zone)); 6055 REQUIRE(xfrsource != NULL); 6056 6057 LOCK_ZONE(zone); 6058 zone->xfrsource6 = *xfrsource; 6059 UNLOCK_ZONE(zone); 6060 } 6061 6062 void 6063 dns_zone_getxfrsource6(dns_zone_t *zone, isc_sockaddr_t *xfrsource) { 6064 REQUIRE(DNS_ZONE_VALID(zone)); 6065 REQUIRE(xfrsource != NULL); 6066 6067 LOCK_ZONE(zone); 6068 *xfrsource = zone->xfrsource6; 6069 UNLOCK_ZONE(zone); 6070 } 6071 6072 void 6073 dns_zone_setparentalsrc4(dns_zone_t *zone, const isc_sockaddr_t *parentalsrc) { 6074 REQUIRE(DNS_ZONE_VALID(zone)); 6075 REQUIRE(parentalsrc != NULL); 6076 6077 LOCK_ZONE(zone); 6078 zone->parentalsrc4 = *parentalsrc; 6079 UNLOCK_ZONE(zone); 6080 } 6081 6082 void 6083 dns_zone_getparentalsrc4(dns_zone_t *zone, isc_sockaddr_t *parentalsrc) { 6084 REQUIRE(DNS_ZONE_VALID(zone)); 6085 REQUIRE(parentalsrc != NULL); 6086 6087 LOCK_ZONE(zone); 6088 *parentalsrc = zone->parentalsrc4; 6089 UNLOCK_ZONE(zone); 6090 } 6091 6092 void 6093 dns_zone_setparentalsrc6(dns_zone_t *zone, const isc_sockaddr_t *parentalsrc) { 6094 REQUIRE(DNS_ZONE_VALID(zone)); 6095 6096 LOCK_ZONE(zone); 6097 zone->parentalsrc6 = *parentalsrc; 6098 UNLOCK_ZONE(zone); 6099 } 6100 6101 void 6102 dns_zone_getparentalsrc6(dns_zone_t *zone, isc_sockaddr_t *parentalsrc) { 6103 REQUIRE(DNS_ZONE_VALID(zone)); 6104 REQUIRE(parentalsrc != NULL); 6105 6106 LOCK_ZONE(zone); 6107 *parentalsrc = zone->parentalsrc6; 6108 UNLOCK_ZONE(zone); 6109 } 6110 6111 void 6112 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 6113 REQUIRE(DNS_ZONE_VALID(zone)); 6114 REQUIRE(notifysrc != NULL); 6115 6116 LOCK_ZONE(zone); 6117 zone->notifysrc4 = *notifysrc; 6118 UNLOCK_ZONE(zone); 6119 } 6120 6121 void 6122 dns_zone_getnotifysrc4(dns_zone_t *zone, isc_sockaddr_t *notifysrc) { 6123 REQUIRE(DNS_ZONE_VALID(zone)); 6124 REQUIRE(notifysrc != NULL); 6125 6126 LOCK_ZONE(zone); 6127 *notifysrc = zone->notifysrc4; 6128 UNLOCK_ZONE(zone); 6129 } 6130 6131 void 6132 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 6133 REQUIRE(DNS_ZONE_VALID(zone)); 6134 REQUIRE(notifysrc != NULL); 6135 6136 LOCK_ZONE(zone); 6137 zone->notifysrc6 = *notifysrc; 6138 UNLOCK_ZONE(zone); 6139 } 6140 6141 void 6142 dns_zone_getnotifysrc6(dns_zone_t *zone, isc_sockaddr_t *notifysrc) { 6143 REQUIRE(DNS_ZONE_VALID(zone)); 6144 REQUIRE(notifysrc != NULL); 6145 6146 LOCK_ZONE(zone); 6147 *notifysrc = zone->notifysrc6; 6148 UNLOCK_ZONE(zone); 6149 } 6150 6151 void 6152 dns_zone_setalsonotify(dns_zone_t *zone, isc_sockaddr_t *addresses, 6153 isc_sockaddr_t *sources, dns_name_t **keynames, 6154 dns_name_t **tlsnames, uint32_t count) { 6155 dns_remote_t remote; 6156 6157 REQUIRE(DNS_ZONE_VALID(zone)); 6158 6159 LOCK_ZONE(zone); 6160 6161 remote.magic = DNS_REMOTE_MAGIC; 6162 remote.addresses = addresses; 6163 remote.sources = sources; 6164 remote.keynames = keynames; 6165 remote.tlsnames = tlsnames; 6166 remote.addrcnt = count; 6167 6168 if (dns_remote_equal(&zone->notify, &remote)) { 6169 goto unlock; 6170 } 6171 6172 dns_remote_clear(&zone->notify); 6173 6174 /* 6175 * If count == 0, don't allocate any space for servers to notify. 6176 */ 6177 if (count == 0) { 6178 goto unlock; 6179 } 6180 6181 /* 6182 * Now set up the notify address and key lists. 6183 */ 6184 dns_remote_init(&zone->notify, count, addresses, sources, keynames, 6185 tlsnames, true, zone->mctx); 6186 6187 unlock: 6188 UNLOCK_ZONE(zone); 6189 } 6190 6191 static bool 6192 has_pf(isc_sockaddr_t *addresses, size_t count, int pf) { 6193 for (size_t i = 0; i < count; i++) { 6194 if (isc_sockaddr_pf(&addresses[i]) == pf) { 6195 return true; 6196 } 6197 } 6198 return false; 6199 } 6200 6201 static void 6202 report_no_active_addresses(dns_zone_t *zone, isc_sockaddr_t *addresses, 6203 size_t count, const char *what) { 6204 if (isc_net_probeipv4() == ISC_R_DISABLED) { 6205 if (!has_pf(addresses, count, AF_INET6)) { 6206 dns_zone_log(zone, ISC_LOG_NOTICE, 6207 "IPv4 disabled and no IPv6 %s", what); 6208 } 6209 } else if (isc_net_probeipv6() == ISC_R_DISABLED) { 6210 if (!has_pf(addresses, count, AF_INET)) { 6211 dns_zone_log(zone, ISC_LOG_NOTICE, 6212 "IPv6 disabled and no IPv4 %s", what); 6213 } 6214 } 6215 } 6216 6217 void 6218 dns_zone_setprimaries(dns_zone_t *zone, isc_sockaddr_t *addresses, 6219 isc_sockaddr_t *sources, dns_name_t **keynames, 6220 dns_name_t **tlsnames, uint32_t count) { 6221 dns_remote_t remote; 6222 6223 REQUIRE(DNS_ZONE_VALID(zone)); 6224 6225 LOCK_ZONE(zone); 6226 6227 remote.magic = DNS_REMOTE_MAGIC; 6228 remote.addresses = addresses; 6229 remote.sources = sources; 6230 remote.keynames = keynames; 6231 remote.tlsnames = tlsnames; 6232 remote.addrcnt = count; 6233 6234 /* 6235 * The refresh code assumes that 'primaries' wouldn't change under it. 6236 * If it will change then kill off any current refresh in progress 6237 * and update the primaries info. If it won't change then we can just 6238 * unlock and exit. 6239 */ 6240 if (!dns_remote_equal(&zone->primaries, &remote)) { 6241 if (zone->request != NULL) { 6242 dns_request_cancel(zone->request); 6243 } 6244 } else { 6245 goto unlock; 6246 } 6247 6248 dns_remote_clear(&zone->primaries); 6249 6250 /* 6251 * If count == 0, don't allocate any space for primaries. 6252 */ 6253 if (count == 0) { 6254 goto unlock; 6255 } 6256 6257 report_no_active_addresses(zone, addresses, count, "primaries"); 6258 6259 /* 6260 * Now set up the primaries and primary key lists. 6261 */ 6262 dns_remote_init(&zone->primaries, count, addresses, sources, keynames, 6263 tlsnames, true, zone->mctx); 6264 6265 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOPRIMARIES); 6266 6267 unlock: 6268 UNLOCK_ZONE(zone); 6269 } 6270 6271 void 6272 dns_zone_setparentals(dns_zone_t *zone, isc_sockaddr_t *addresses, 6273 isc_sockaddr_t *sources, dns_name_t **keynames, 6274 dns_name_t **tlsnames, uint32_t count) { 6275 dns_remote_t remote; 6276 6277 REQUIRE(DNS_ZONE_VALID(zone)); 6278 6279 LOCK_ZONE(zone); 6280 6281 remote.magic = DNS_REMOTE_MAGIC; 6282 remote.addresses = addresses; 6283 remote.sources = sources; 6284 remote.keynames = keynames; 6285 remote.tlsnames = tlsnames; 6286 remote.addrcnt = count; 6287 6288 if (dns_remote_equal(&zone->parentals, &remote)) { 6289 goto unlock; 6290 } 6291 6292 dns_remote_clear(&zone->parentals); 6293 6294 /* 6295 * If count == 0, don't allocate any space for parentals. 6296 */ 6297 if (count == 0) { 6298 goto unlock; 6299 } 6300 6301 report_no_active_addresses(zone, addresses, count, "parental-agents"); 6302 6303 /* 6304 * Now set up the parentals and parental key lists. 6305 */ 6306 dns_remote_init(&zone->parentals, count, addresses, sources, keynames, 6307 tlsnames, true, zone->mctx); 6308 6309 dns_zone_log(zone, ISC_LOG_NOTICE, "checkds: set %u parentals", count); 6310 6311 unlock: 6312 UNLOCK_ZONE(zone); 6313 } 6314 6315 isc_result_t 6316 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) { 6317 isc_result_t result = ISC_R_SUCCESS; 6318 6319 REQUIRE(DNS_ZONE_VALID(zone)); 6320 6321 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 6322 if (zone->db == NULL) { 6323 result = DNS_R_NOTLOADED; 6324 } else { 6325 dns_db_attach(zone->db, dpb); 6326 } 6327 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 6328 6329 return result; 6330 } 6331 6332 void 6333 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) { 6334 REQUIRE(DNS_ZONE_VALID(zone)); 6335 REQUIRE(zone->type == dns_zone_staticstub); 6336 6337 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 6338 REQUIRE(zone->db == NULL); 6339 dns_db_attach(db, &zone->db); 6340 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 6341 } 6342 6343 static bool 6344 was_dumping(dns_zone_t *zone) { 6345 REQUIRE(LOCKED_ZONE(zone)); 6346 6347 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 6348 return true; 6349 } 6350 6351 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 6352 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 6353 isc_time_settoepoch(&zone->dumptime); 6354 return false; 6355 } 6356 6357 static isc_result_t 6358 keyfromfile(dns_zone_t *zone, dst_key_t *pubkey, isc_mem_t *mctx, 6359 dst_key_t **key) { 6360 const char *directory = zone->keydirectory; 6361 dns_kasp_t *kasp = zone->kasp; 6362 dst_key_t *foundkey = NULL; 6363 isc_result_t result = ISC_R_NOTFOUND; 6364 6365 if (kasp == NULL || (strcmp(dns_kasp_getname(kasp), "none") == 0) || 6366 (strcmp(dns_kasp_getname(kasp), "insecure") == 0)) 6367 { 6368 result = dst_key_fromfile( 6369 dst_key_name(pubkey), dst_key_id(pubkey), 6370 dst_key_alg(pubkey), 6371 DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_STATE, 6372 directory, mctx, &foundkey); 6373 } else { 6374 for (dns_kasp_key_t *kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); 6375 kkey != NULL; kkey = ISC_LIST_NEXT(kkey, link)) 6376 { 6377 dns_keystore_t *ks = dns_kasp_key_keystore(kkey); 6378 directory = dns_keystore_directory(ks, 6379 zone->keydirectory); 6380 6381 result = dst_key_fromfile( 6382 dst_key_name(pubkey), dst_key_id(pubkey), 6383 dst_key_alg(pubkey), 6384 DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | 6385 DST_TYPE_STATE, 6386 directory, mctx, &foundkey); 6387 if (result == ISC_R_SUCCESS) { 6388 break; 6389 } 6390 } 6391 } 6392 6393 *key = foundkey; 6394 return result; 6395 } 6396 6397 #define is_zone_key(key) \ 6398 ((dst_key_flags(key) & DNS_KEYFLAG_OWNERMASK) == DNS_KEYOWNER_ZONE) 6399 6400 static isc_result_t 6401 findzonekeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 6402 dns_dbnode_t *node, const dns_name_t *name, isc_stdtime_t now, 6403 isc_mem_t *mctx, unsigned int maxkeys, dst_key_t **keys, 6404 unsigned int *nkeys) { 6405 dns_rdataset_t rdataset; 6406 dns_rdata_t rdata = DNS_RDATA_INIT; 6407 isc_result_t result; 6408 dst_key_t *pubkey = NULL; 6409 unsigned int count = 0; 6410 6411 *nkeys = 0; 6412 memset(keys, 0, sizeof(*keys) * maxkeys); 6413 dns_rdataset_init(&rdataset); 6414 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 0, 0, 6415 &rdataset, NULL)); 6416 CHECK(dns_rdataset_first(&rdataset)); 6417 while (result == ISC_R_SUCCESS && count < maxkeys) { 6418 pubkey = NULL; 6419 dns_rdataset_current(&rdataset, &rdata); 6420 CHECK(dns_dnssec_keyfromrdata(name, &rdata, mctx, &pubkey)); 6421 dst_key_setttl(pubkey, rdataset.ttl); 6422 6423 if (!is_zone_key(pubkey)) { 6424 goto next; 6425 } 6426 /* Corrupted .key file? */ 6427 if (!dns_name_equal(name, dst_key_name(pubkey))) { 6428 goto next; 6429 } 6430 keys[count] = NULL; 6431 result = keyfromfile(zone, pubkey, mctx, &keys[count]); 6432 6433 /* 6434 * If the key was revoked and the private file 6435 * doesn't exist, maybe it was revoked internally 6436 * by named. Try loading the unrevoked version. 6437 */ 6438 if (result == ISC_R_FILENOTFOUND) { 6439 uint32_t flags; 6440 flags = dst_key_flags(pubkey); 6441 if ((flags & DNS_KEYFLAG_REVOKE) != 0) { 6442 dst_key_setflags(pubkey, 6443 flags & ~DNS_KEYFLAG_REVOKE); 6444 result = keyfromfile(zone, pubkey, mctx, 6445 &keys[count]); 6446 if (result == ISC_R_SUCCESS && 6447 dst_key_pubcompare(pubkey, keys[count], 6448 false)) 6449 { 6450 dst_key_setflags(keys[count], flags); 6451 } 6452 dst_key_setflags(pubkey, flags); 6453 } 6454 } 6455 6456 if (result != ISC_R_SUCCESS) { 6457 char filename[DNS_NAME_FORMATSIZE + 6458 DNS_SECALG_FORMATSIZE + 6459 sizeof("key file for //65535")]; 6460 isc_result_t result2; 6461 isc_buffer_t buf; 6462 6463 isc_buffer_init(&buf, filename, sizeof(filename)); 6464 result2 = dst_key_getfilename( 6465 dst_key_name(pubkey), dst_key_id(pubkey), 6466 dst_key_alg(pubkey), 6467 DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | 6468 DST_TYPE_STATE, 6469 NULL, mctx, &buf); 6470 if (result2 != ISC_R_SUCCESS) { 6471 char namebuf[DNS_NAME_FORMATSIZE]; 6472 char algbuf[DNS_SECALG_FORMATSIZE]; 6473 6474 dns_name_format(dst_key_name(pubkey), namebuf, 6475 sizeof(namebuf)); 6476 dns_secalg_format(dst_key_alg(pubkey), algbuf, 6477 sizeof(algbuf)); 6478 snprintf(filename, sizeof(filename) - 1, 6479 "key file for %s/%s/%d", namebuf, 6480 algbuf, dst_key_id(pubkey)); 6481 } 6482 6483 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 6484 DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING, 6485 "dns_zone_findkeys: error reading %s: %s", 6486 filename, isc_result_totext(result)); 6487 } 6488 6489 if (result == ISC_R_FILENOTFOUND || result == ISC_R_NOPERM) { 6490 keys[count] = pubkey; 6491 pubkey = NULL; 6492 count++; 6493 goto next; 6494 } 6495 6496 CHECK(result); 6497 6498 /* 6499 * If a key is marked inactive, skip it 6500 */ 6501 if (!dns_dnssec_keyactive(keys[count], now)) { 6502 dst_key_setinactive(pubkey, true); 6503 dst_key_free(&keys[count]); 6504 keys[count] = pubkey; 6505 pubkey = NULL; 6506 count++; 6507 goto next; 6508 } 6509 6510 /* 6511 * Whatever the key's default TTL may have 6512 * been, the rdataset TTL takes priority. 6513 */ 6514 dst_key_setttl(keys[count], rdataset.ttl); 6515 count++; 6516 next: 6517 if (pubkey != NULL) { 6518 dst_key_free(&pubkey); 6519 } 6520 dns_rdata_reset(&rdata); 6521 result = dns_rdataset_next(&rdataset); 6522 } 6523 if (result != ISC_R_NOMORE) { 6524 CHECK(result); 6525 } 6526 if (count == 0) { 6527 result = ISC_R_NOTFOUND; 6528 } else { 6529 result = ISC_R_SUCCESS; 6530 } 6531 6532 cleanup: 6533 if (dns_rdataset_isassociated(&rdataset)) { 6534 dns_rdataset_disassociate(&rdataset); 6535 } 6536 if (pubkey != NULL) { 6537 dst_key_free(&pubkey); 6538 } 6539 if (result != ISC_R_SUCCESS) { 6540 while (count > 0) { 6541 dst_key_free(&keys[--count]); 6542 } 6543 } 6544 *nkeys = count; 6545 return result; 6546 } 6547 6548 /*% 6549 * Find up to 'maxkeys' DNSSEC keys used for signing version 'ver' of database 6550 * 'db' for zone 'zone' in its key directory, then load these keys into 'keys'. 6551 * Only load the public part of a given key if it is not active at timestamp 6552 * 'now'. Store the number of keys found in 'nkeys'. 6553 */ 6554 isc_result_t 6555 dns_zone_findkeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 6556 isc_stdtime_t now, isc_mem_t *mctx, unsigned int maxkeys, 6557 dst_key_t **keys, unsigned int *nkeys) { 6558 isc_result_t result; 6559 dns_dbnode_t *node = NULL; 6560 6561 REQUIRE(DNS_ZONE_VALID(zone)); 6562 REQUIRE(mctx != NULL); 6563 REQUIRE(nkeys != NULL); 6564 REQUIRE(keys != NULL); 6565 6566 CHECK(dns_db_findnode(db, dns_db_origin(db), false, &node)); 6567 6568 dns_zone_lock_keyfiles(zone); 6569 6570 result = findzonekeys(zone, db, ver, node, dns_db_origin(db), now, mctx, 6571 maxkeys, keys, nkeys); 6572 6573 dns_zone_unlock_keyfiles(zone); 6574 6575 if (result == ISC_R_NOTFOUND) { 6576 result = ISC_R_SUCCESS; 6577 } 6578 6579 cleanup: 6580 6581 if (node != NULL) { 6582 dns_db_detachnode(db, &node); 6583 } 6584 return result; 6585 } 6586 6587 void 6588 dns_zone_prepare_shutdown(dns_zone_t *zone) { 6589 REQUIRE(DNS_ZONE_VALID(zone)); 6590 6591 LOCK_ZONE(zone); 6592 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING); 6593 UNLOCK_ZONE(zone); 6594 } 6595 6596 /*% 6597 * Find DNSSEC keys used for signing zone with dnssec-policy. Load these keys 6598 * into 'keys'. Requires KASP to be locked. 6599 */ 6600 isc_result_t 6601 dns_zone_getdnsseckeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 6602 isc_stdtime_t now, dns_dnsseckeylist_t *keys) { 6603 isc_result_t result; 6604 const char *dir = dns_zone_getkeydirectory(zone); 6605 dns_dbnode_t *node = NULL; 6606 dns_dnsseckey_t *key, *key_next; 6607 dns_dnsseckeylist_t dnskeys; 6608 dns_name_t *origin = dns_zone_getorigin(zone); 6609 dns_kasp_t *kasp = zone->kasp; 6610 dns_rdataset_t keyset; 6611 6612 REQUIRE(DNS_ZONE_VALID(zone)); 6613 REQUIRE(kasp != NULL); 6614 6615 ISC_LIST_INIT(dnskeys); 6616 6617 dns_rdataset_init(&keyset); 6618 6619 CHECK(dns_db_findnode(db, origin, false, &node)); 6620 6621 /* Get keys from private key files. */ 6622 dns_zone_lock_keyfiles(zone); 6623 result = dns_dnssec_findmatchingkeys(origin, kasp, dir, zone->keystores, 6624 now, false, dns_zone_getmctx(zone), 6625 keys); 6626 dns_zone_unlock_keyfiles(zone); 6627 6628 if (result != ISC_R_NOTFOUND) { 6629 CHECK(result); 6630 } 6631 6632 /* Get public keys (dnskeys). */ 6633 dns_rdataset_init(&keyset); 6634 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 6635 dns_rdatatype_none, 0, &keyset, NULL); 6636 if (result == ISC_R_SUCCESS) { 6637 CHECK(dns_dnssec_keylistfromrdataset( 6638 origin, kasp, dir, dns_zone_getmctx(zone), &keyset, 6639 NULL, NULL, false, false, &dnskeys)); 6640 } else if (result != ISC_R_NOTFOUND) { 6641 CHECK(result); 6642 } 6643 6644 /* Add new 'dnskeys' to 'keys'. */ 6645 for (dns_dnsseckey_t *k1 = ISC_LIST_HEAD(dnskeys); k1 != NULL; 6646 k1 = key_next) 6647 { 6648 dns_dnsseckey_t *k2 = NULL; 6649 key_next = ISC_LIST_NEXT(k1, link); 6650 6651 for (k2 = ISC_LIST_HEAD(*keys); k2 != NULL; 6652 k2 = ISC_LIST_NEXT(k2, link)) 6653 { 6654 if (dst_key_compare(k1->key, k2->key)) { 6655 break; 6656 } 6657 } 6658 /* No match found, add the new key. */ 6659 if (k2 == NULL) { 6660 ISC_LIST_UNLINK(dnskeys, k1, link); 6661 ISC_LIST_APPEND(*keys, k1, link); 6662 } 6663 } 6664 6665 cleanup: 6666 if (dns_rdataset_isassociated(&keyset)) { 6667 dns_rdataset_disassociate(&keyset); 6668 } 6669 if (node != NULL) { 6670 dns_db_detachnode(db, &node); 6671 } 6672 while (!ISC_LIST_EMPTY(dnskeys)) { 6673 key = ISC_LIST_HEAD(dnskeys); 6674 ISC_LIST_UNLINK(dnskeys, key, link); 6675 dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key); 6676 } 6677 return result; 6678 } 6679 6680 static isc_result_t 6681 offline(dns_db_t *db, dns_dbversion_t *ver, dns__zonediff_t *zonediff, 6682 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { 6683 isc_result_t result; 6684 6685 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) { 6686 return ISC_R_SUCCESS; 6687 } 6688 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, 6689 name, ttl, rdata); 6690 if (result != ISC_R_SUCCESS) { 6691 return result; 6692 } 6693 rdata->flags |= DNS_RDATA_OFFLINE; 6694 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN, 6695 name, ttl, rdata); 6696 zonediff->offline = true; 6697 return result; 6698 } 6699 6700 static void 6701 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, 6702 isc_stdtime_t now) { 6703 unsigned int delta; 6704 char timebuf[80]; 6705 6706 LOCK_ZONE(zone); 6707 zone->key_expiry = when; 6708 if (when <= now) { 6709 dns_zone_log(zone, ISC_LOG_ERROR, 6710 "DNSKEY RRSIG(s) have expired"); 6711 isc_time_settoepoch(&zone->keywarntime); 6712 } else if (when < now + 7 * 24 * 3600) { 6713 isc_time_t t; 6714 isc_time_set(&t, when, 0); 6715 isc_time_formattimestamp(&t, timebuf, 80); 6716 dns_zone_log(zone, ISC_LOG_WARNING, 6717 "DNSKEY RRSIG(s) will expire within 7 days: %s", 6718 timebuf); 6719 delta = when - now; 6720 delta--; /* loop prevention */ 6721 delta /= 24 * 3600; /* to whole days */ 6722 delta *= 24 * 3600; /* to seconds */ 6723 isc_time_set(&zone->keywarntime, when - delta, 0); 6724 } else { 6725 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0); 6726 isc_time_formattimestamp(&zone->keywarntime, timebuf, 80); 6727 dns_zone_log(zone, ISC_LOG_NOTICE, "setting keywarntime to %s", 6728 timebuf); 6729 } 6730 UNLOCK_ZONE(zone); 6731 } 6732 6733 /* 6734 * Helper function to del_sigs(). We don't want to delete RRSIGs that 6735 * have no new key. 6736 */ 6737 static bool 6738 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys, 6739 bool kasp, bool *warn) { 6740 unsigned int i = 0; 6741 isc_result_t ret; 6742 bool have_ksk = false, have_zsk = false; 6743 bool have_pksk = false, have_pzsk = false; 6744 6745 for (i = 0; i < nkeys; i++) { 6746 bool ksk, zsk; 6747 6748 if (have_pksk && have_ksk && have_pzsk && have_zsk) { 6749 break; 6750 } 6751 6752 if (rrsig_ptr->algorithm != dst_key_alg(keys[i])) { 6753 continue; 6754 } 6755 6756 ret = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk); 6757 if (ret != ISC_R_SUCCESS) { 6758 ksk = KSK(keys[i]); 6759 } 6760 ret = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk); 6761 if (ret != ISC_R_SUCCESS) { 6762 zsk = !KSK(keys[i]); 6763 } 6764 6765 if (ksk) { 6766 have_ksk = true; 6767 if (dst_key_isprivate(keys[i])) { 6768 have_pksk = true; 6769 } 6770 } 6771 if (zsk) { 6772 have_zsk = true; 6773 if (dst_key_isprivate(keys[i])) { 6774 have_pzsk = true; 6775 } 6776 } 6777 } 6778 6779 if (have_zsk && have_ksk && !have_pzsk) { 6780 *warn = true; 6781 } 6782 6783 if (have_pksk && have_pzsk) { 6784 return true; 6785 } 6786 6787 /* 6788 * Deleting the SOA RRSIG is always okay. 6789 */ 6790 if (rrsig_ptr->covered == dns_rdatatype_soa) { 6791 return true; 6792 } 6793 6794 /* 6795 * It's okay to delete a signature if there is an active key with the 6796 * same algorithm to replace it, unless that violates the DNSSEC 6797 * policy. 6798 */ 6799 if (have_pksk || have_pzsk) { 6800 if (kasp && have_pzsk) { 6801 return true; 6802 } 6803 return !kasp; 6804 } 6805 6806 /* 6807 * Failing that, it is *not* okay to delete a signature 6808 * if the associated public key is still in the DNSKEY RRset 6809 */ 6810 for (i = 0; i < nkeys; i++) { 6811 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) && 6812 (rrsig_ptr->keyid == dst_key_id(keys[i]))) 6813 { 6814 return false; 6815 } 6816 } 6817 6818 /* 6819 * But if the key is gone, then go ahead. 6820 */ 6821 return true; 6822 } 6823 6824 /* 6825 * Delete expired RRsigs and any RRsigs we are about to re-sign. 6826 * See also update.c:del_keysigs(). 6827 */ 6828 static isc_result_t 6829 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 6830 dns_rdatatype_t type, dns__zonediff_t *zonediff, dst_key_t **keys, 6831 unsigned int nkeys, isc_stdtime_t now, bool incremental) { 6832 isc_result_t result; 6833 dns_dbnode_t *node = NULL; 6834 dns_rdataset_t rdataset; 6835 unsigned int i; 6836 dns_rdata_rrsig_t rrsig; 6837 dns_kasp_t *kasp = zone->kasp; 6838 bool found; 6839 bool offlineksk = false; 6840 int64_t timewarn = 0, timemaybe = 0; 6841 6842 dns_rdataset_init(&rdataset); 6843 6844 if (kasp != NULL) { 6845 offlineksk = dns_kasp_offlineksk(kasp); 6846 } 6847 6848 if (type == dns_rdatatype_nsec3) { 6849 result = dns_db_findnsec3node(db, name, false, &node); 6850 } else { 6851 result = dns_db_findnode(db, name, false, &node); 6852 } 6853 if (result == ISC_R_NOTFOUND) { 6854 return ISC_R_SUCCESS; 6855 } 6856 CHECK(result); 6857 6858 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type, 6859 (isc_stdtime_t)0, &rdataset, NULL); 6860 dns_db_detachnode(db, &node); 6861 6862 if (result == ISC_R_NOTFOUND) { 6863 INSIST(!dns_rdataset_isassociated(&rdataset)); 6864 return ISC_R_SUCCESS; 6865 } 6866 if (result != ISC_R_SUCCESS) { 6867 INSIST(!dns_rdataset_isassociated(&rdataset)); 6868 goto cleanup; 6869 } 6870 6871 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 6872 result = dns_rdataset_next(&rdataset)) 6873 { 6874 dns_rdata_t rdata = DNS_RDATA_INIT; 6875 6876 dns_rdataset_current(&rdataset, &rdata); 6877 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 6878 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6879 6880 if (!dns_rdatatype_iskeymaterial(type)) { 6881 bool warn = false, deleted = false; 6882 if (delsig_ok(&rrsig, keys, nkeys, kasp != NULL, &warn)) 6883 { 6884 result = update_one_rr(db, ver, zonediff->diff, 6885 DNS_DIFFOP_DELRESIGN, 6886 name, rdataset.ttl, 6887 &rdata); 6888 if (result != ISC_R_SUCCESS) { 6889 break; 6890 } 6891 deleted = true; 6892 } 6893 if (warn && !deleted) { 6894 /* 6895 * At this point, we've got an RRSIG, 6896 * which is signed by an inactive key. 6897 * An administrator needs to provide a new 6898 * key/alg, but until that time, we want to 6899 * keep the old RRSIG. Marking the key as 6900 * offline will prevent us spinning waiting 6901 * for the private part. 6902 */ 6903 if (incremental) { 6904 result = offline(db, ver, zonediff, 6905 name, rdataset.ttl, 6906 &rdata); 6907 if (result != ISC_R_SUCCESS) { 6908 break; 6909 } 6910 } 6911 6912 /* 6913 * Log the key id and algorithm of 6914 * the inactive key with no replacement 6915 */ 6916 if (zone->log_key_expired_timer <= now) { 6917 char origin[DNS_NAME_FORMATSIZE]; 6918 char algbuf[DNS_NAME_FORMATSIZE]; 6919 dns_name_format(&zone->origin, origin, 6920 sizeof(origin)); 6921 dns_secalg_format(rrsig.algorithm, 6922 algbuf, 6923 sizeof(algbuf)); 6924 dns_zone_log(zone, ISC_LOG_WARNING, 6925 "Key %s/%s/%d " 6926 "missing or inactive " 6927 "and has no replacement: " 6928 "retaining signatures.", 6929 origin, algbuf, 6930 rrsig.keyid); 6931 zone->log_key_expired_timer = now + 6932 3600; 6933 } 6934 } 6935 continue; 6936 } 6937 6938 /* 6939 * KSK RRSIGs requires special processing. 6940 */ 6941 found = false; 6942 for (i = 0; i < nkeys; i++) { 6943 if (rrsig.algorithm == dst_key_alg(keys[i]) && 6944 rrsig.keyid == dst_key_id(keys[i])) 6945 { 6946 found = true; 6947 /* 6948 * Mark offline DNSKEY. 6949 * We want the earliest offline expire time 6950 * iff there is a new offline signature. 6951 */ 6952 if (!dst_key_inactive(keys[i]) && 6953 !dst_key_isprivate(keys[i]) && !offlineksk) 6954 { 6955 int64_t timeexpire = dns_time64_from32( 6956 rrsig.timeexpire); 6957 if (timewarn != 0 && 6958 timewarn > timeexpire) 6959 { 6960 timewarn = timeexpire; 6961 } 6962 if (rdata.flags & DNS_RDATA_OFFLINE) { 6963 if (timemaybe == 0 || 6964 timemaybe > timeexpire) 6965 { 6966 timemaybe = timeexpire; 6967 } 6968 break; 6969 } 6970 if (timewarn == 0) { 6971 timewarn = timemaybe; 6972 } 6973 if (timewarn == 0 || 6974 timewarn > timeexpire) 6975 { 6976 timewarn = timeexpire; 6977 } 6978 result = offline(db, ver, zonediff, 6979 name, rdataset.ttl, 6980 &rdata); 6981 break; 6982 } 6983 result = update_one_rr(db, ver, zonediff->diff, 6984 DNS_DIFFOP_DELRESIGN, 6985 name, rdataset.ttl, 6986 &rdata); 6987 break; 6988 } 6989 } 6990 6991 /* 6992 * If there is not a matching DNSKEY then 6993 * delete the RRSIG. 6994 */ 6995 if (!found) { 6996 result = update_one_rr(db, ver, zonediff->diff, 6997 DNS_DIFFOP_DELRESIGN, name, 6998 rdataset.ttl, &rdata); 6999 } 7000 if (result != ISC_R_SUCCESS) { 7001 break; 7002 } 7003 } 7004 7005 dns_rdataset_disassociate(&rdataset); 7006 if (result == ISC_R_NOMORE) { 7007 result = ISC_R_SUCCESS; 7008 } 7009 if (timewarn > 0) { 7010 isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn; 7011 if (timewarn == stdwarn) { 7012 set_key_expiry_warning(zone, (isc_stdtime_t)timewarn, 7013 now); 7014 } else { 7015 dns_zone_log(zone, ISC_LOG_ERROR, 7016 "key expiry warning time out of range"); 7017 } 7018 } 7019 cleanup: 7020 if (node != NULL) { 7021 dns_db_detachnode(db, &node); 7022 } 7023 return result; 7024 } 7025 7026 static isc_result_t 7027 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_zone_t *zone, 7028 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, 7029 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t now, 7030 isc_stdtime_t inception, isc_stdtime_t expire) { 7031 isc_result_t result; 7032 dns_dbnode_t *node = NULL; 7033 dns_stats_t *dnssecsignstats; 7034 dns_rdataset_t rdataset; 7035 dns_rdata_t sig_rdata = DNS_RDATA_INIT; 7036 unsigned char data[1024]; /* XXX */ 7037 isc_buffer_t buffer; 7038 unsigned int i; 7039 bool use_kasp = false; 7040 bool offlineksk = false; 7041 7042 if (zone->kasp != NULL) { 7043 use_kasp = true; 7044 offlineksk = dns_kasp_offlineksk(zone->kasp); 7045 } 7046 7047 dns_rdataset_init(&rdataset); 7048 isc_buffer_init(&buffer, data, sizeof(data)); 7049 7050 if (type == dns_rdatatype_nsec3) { 7051 result = dns_db_findnsec3node(db, name, false, &node); 7052 } else { 7053 result = dns_db_findnode(db, name, false, &node); 7054 } 7055 if (result == ISC_R_NOTFOUND) { 7056 return ISC_R_SUCCESS; 7057 } 7058 CHECK(result); 7059 7060 result = dns_db_findrdataset(db, node, ver, type, 0, (isc_stdtime_t)0, 7061 &rdataset, NULL); 7062 dns_db_detachnode(db, &node); 7063 if (result == ISC_R_NOTFOUND) { 7064 INSIST(!dns_rdataset_isassociated(&rdataset)); 7065 return ISC_R_SUCCESS; 7066 } 7067 if (result != ISC_R_SUCCESS) { 7068 INSIST(!dns_rdataset_isassociated(&rdataset)); 7069 goto cleanup; 7070 } 7071 7072 for (i = 0; i < nkeys; i++) { 7073 /* Don't add signatures for offline or inactive keys */ 7074 if (!dst_key_isprivate(keys[i]) && !offlineksk) { 7075 continue; 7076 } 7077 if (dst_key_inactive(keys[i]) && !offlineksk) { 7078 continue; 7079 } 7080 7081 if (use_kasp) { 7082 /* 7083 * A dnssec-policy is found. Check what RRsets this 7084 * key should sign. 7085 */ 7086 isc_result_t kresult; 7087 isc_stdtime_t when; 7088 bool ksk = false; 7089 bool zsk = false; 7090 bool have_zsk = false; 7091 7092 kresult = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk); 7093 if (kresult != ISC_R_SUCCESS) { 7094 if (KSK(keys[i])) { 7095 ksk = true; 7096 } 7097 } 7098 kresult = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk); 7099 if (kresult != ISC_R_SUCCESS) { 7100 if (!KSK(keys[i])) { 7101 zsk = true; 7102 } 7103 } 7104 7105 /* 7106 * Don't consider inactive keys or offline keys. 7107 */ 7108 if (!dst_key_isprivate(keys[i]) && offlineksk && zsk) { 7109 continue; 7110 } 7111 if (dst_key_inactive(keys[i]) && offlineksk && zsk) { 7112 continue; 7113 } 7114 7115 if (offlineksk) { 7116 have_zsk = true; 7117 } else { 7118 (void)dst_key_have_ksk_and_zsk(keys, nkeys, i, 7119 true, ksk, zsk, 7120 NULL, &have_zsk); 7121 } 7122 7123 if (dns_rdatatype_iskeymaterial(type)) { 7124 /* 7125 * DNSKEY RRset is signed with KSK. 7126 * CDS and CDNSKEY RRsets too (RFC 7344, 4.1). 7127 */ 7128 if (!ksk) { 7129 continue; 7130 } 7131 } else if (!zsk) { 7132 /* 7133 * Other RRsets are signed with ZSK. 7134 */ 7135 if (type != dns_rdatatype_soa && 7136 type != zone->privatetype) 7137 { 7138 continue; 7139 } 7140 if (have_zsk) { 7141 continue; 7142 } 7143 } else if (!dst_key_is_signing(keys[i], DST_BOOL_ZSK, 7144 now, &when)) 7145 { 7146 /* 7147 * This key is not active for zone-signing. 7148 */ 7149 continue; 7150 } 7151 } else if (!REVOKE(keys[i])) { 7152 /* 7153 * Don't consider inactive keys, however the KSK may be 7154 * temporary offline, so do consider keys which private 7155 * key files are unavailable. 7156 */ 7157 bool both = dst_key_have_ksk_and_zsk( 7158 keys, nkeys, i, false, KSK(keys[i]), 7159 !KSK(keys[i]), NULL, NULL); 7160 if (both) { 7161 /* 7162 * CDS and CDNSKEY are signed with KSK (RFC 7163 * 7344, 4.1). 7164 */ 7165 if (dns_rdatatype_iskeymaterial(type)) { 7166 if (!KSK(keys[i])) { 7167 continue; 7168 } 7169 } else if (KSK(keys[i])) { 7170 continue; 7171 } 7172 } 7173 } 7174 7175 /* 7176 * If this key is revoked, it may only sign the DNSKEY RRset. 7177 */ 7178 if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) { 7179 continue; 7180 } 7181 7182 /* Calculate the signature, creating a RRSIG RDATA. */ 7183 isc_buffer_clear(&buffer); 7184 7185 if (offlineksk && dns_rdatatype_iskeymaterial(type)) { 7186 /* Look up the signature in the SKR bundle */ 7187 dns_skrbundle_t *bundle = dns_zone_getskrbundle(zone); 7188 if (bundle == NULL) { 7189 CHECK(DNS_R_NOSKRBUNDLE); 7190 } 7191 CHECK(dns_skrbundle_getsig(bundle, keys[i], type, 7192 &sig_rdata)); 7193 } else { 7194 CHECK(dns_dnssec_sign(name, &rdataset, keys[i], 7195 &inception, &expire, mctx, 7196 &buffer, &sig_rdata)); 7197 } 7198 7199 /* Update the database and journal with the RRSIG. */ 7200 /* XXX inefficient - will cause dataset merging */ 7201 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, name, 7202 rdataset.ttl, &sig_rdata)); 7203 dns_rdata_reset(&sig_rdata); 7204 isc_buffer_init(&buffer, data, sizeof(data)); 7205 7206 /* Update DNSSEC sign statistics. */ 7207 dnssecsignstats = dns_zone_getdnssecsignstats(zone); 7208 if (dnssecsignstats != NULL) { 7209 /* Generated a new signature. */ 7210 dns_dnssecsignstats_increment(dnssecsignstats, 7211 ID(keys[i]), 7212 (uint8_t)ALG(keys[i]), 7213 dns_dnssecsignstats_sign); 7214 /* This is a refresh. */ 7215 dns_dnssecsignstats_increment( 7216 dnssecsignstats, ID(keys[i]), 7217 (uint8_t)ALG(keys[i]), 7218 dns_dnssecsignstats_refresh); 7219 } 7220 } 7221 7222 cleanup: 7223 if (dns_rdataset_isassociated(&rdataset)) { 7224 dns_rdataset_disassociate(&rdataset); 7225 } 7226 if (node != NULL) { 7227 dns_db_detachnode(db, &node); 7228 } 7229 return result; 7230 } 7231 7232 static void 7233 calculate_rrsig_validity(dns_zone_t *zone, isc_stdtime_t now, 7234 isc_stdtime_t *inception, isc_stdtime_t *soaexpire, 7235 isc_stdtime_t *expire, isc_stdtime_t *fullexpire) { 7236 REQUIRE(inception != NULL); 7237 REQUIRE(soaexpire != NULL); 7238 /* expire and fullexpire are optional */ 7239 7240 isc_stdtime_t jitter = DEFAULT_JITTER; 7241 isc_stdtime_t sigvalidity = dns_zone_getsigvalidityinterval(zone); 7242 isc_stdtime_t shortjitter = 0, fulljitter = 0; 7243 7244 if (zone->kasp != NULL) { 7245 jitter = dns_kasp_sigjitter(zone->kasp); 7246 sigvalidity = dns_kasp_sigvalidity(zone->kasp); 7247 INSIST(jitter <= sigvalidity); 7248 } 7249 7250 if (jitter > sigvalidity) { 7251 jitter = sigvalidity; 7252 } 7253 7254 *inception = now - 3600; /* Allow for clock skew. */ 7255 *soaexpire = now + sigvalidity; 7256 7257 /* 7258 * Spread out signatures over time if they happen to be 7259 * clumped. We don't do this for each add_sigs() call as 7260 * we still want some clustering to occur. In normal operations 7261 * the records should be re-signed as they fall due and they should 7262 * already be spread out. However if the server is off for a 7263 * period we need to ensure that the clusters don't become 7264 * synchronised by using the full jitter range. 7265 */ 7266 if (sigvalidity >= 3600U) { 7267 if (sigvalidity > 7200U) { 7268 shortjitter = isc_random_uniform(3600); 7269 fulljitter = isc_random_uniform(jitter); 7270 } else { 7271 shortjitter = fulljitter = isc_random_uniform(1200); 7272 } 7273 } 7274 7275 SET_IF_NOT_NULL(expire, *soaexpire - shortjitter - 1); 7276 SET_IF_NOT_NULL(fullexpire, *soaexpire - fulljitter - 1); 7277 } 7278 7279 static void 7280 zone_resigninc(dns_zone_t *zone) { 7281 dns_db_t *db = NULL; 7282 dns_dbversion_t *version = NULL; 7283 dns_diff_t _sig_diff; 7284 dns__zonediff_t zonediff; 7285 dns_fixedname_t fixed; 7286 dns_name_t *name; 7287 dns_typepair_t typepair; 7288 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 7289 isc_result_t result; 7290 isc_stdtime_t now, inception, soaexpire, expire, fullexpire, stop; 7291 unsigned int i; 7292 unsigned int nkeys = 0; 7293 isc_stdtime_t resign; 7294 7295 ENTER; 7296 7297 dns_diff_init(zone->mctx, &_sig_diff); 7298 zonediff_init(&zonediff, &_sig_diff); 7299 7300 /* 7301 * Zone is frozen. Pause for 5 minutes. 7302 */ 7303 if (zone->update_disabled) { 7304 CHECK(ISC_R_FAILURE); 7305 } 7306 7307 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 7308 if (zone->db != NULL) { 7309 dns_db_attach(zone->db, &db); 7310 } 7311 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 7312 if (db == NULL) { 7313 CHECK(ISC_R_FAILURE); 7314 } 7315 7316 result = dns_db_newversion(db, &version); 7317 if (result != ISC_R_SUCCESS) { 7318 dns_zone_log(zone, ISC_LOG_ERROR, 7319 "zone_resigninc:dns_db_newversion -> %s", 7320 isc_result_totext(result)); 7321 goto cleanup; 7322 } 7323 7324 now = isc_stdtime_now(); 7325 7326 result = dns_zone_findkeys(zone, db, version, now, zone->mctx, 7327 DNS_MAXZONEKEYS, zone_keys, &nkeys); 7328 if (result != ISC_R_SUCCESS) { 7329 dns_zone_log(zone, ISC_LOG_ERROR, 7330 "zone_resigninc:dns_zone_findkeys -> %s", 7331 isc_result_totext(result)); 7332 goto cleanup; 7333 } 7334 7335 calculate_rrsig_validity(zone, now, &inception, &soaexpire, &expire, 7336 &fullexpire); 7337 7338 stop = now + 5; 7339 7340 name = dns_fixedname_initname(&fixed); 7341 result = dns_db_getsigningtime(db, &resign, name, &typepair); 7342 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 7343 dns_zone_log(zone, ISC_LOG_ERROR, 7344 "zone_resigninc:dns_db_getsigningtime -> %s", 7345 isc_result_totext(result)); 7346 } 7347 7348 i = 0; 7349 while (result == ISC_R_SUCCESS) { 7350 dns_rdatatype_t covers = DNS_TYPEPAIR_COVERS(typepair); 7351 7352 resign -= dns_zone_getsigresigninginterval(zone); 7353 7354 /* 7355 * Stop if we hit the SOA as that means we have walked the 7356 * entire zone. The SOA record should always be the most 7357 * recent signature. 7358 */ 7359 /* XXXMPA increase number of RRsets signed pre call */ 7360 if ((covers == dns_rdatatype_soa && 7361 dns_name_equal(name, &zone->origin)) || 7362 i++ > zone->signatures || resign > stop) 7363 { 7364 break; 7365 } 7366 7367 result = del_sigs(zone, db, version, name, covers, &zonediff, 7368 zone_keys, nkeys, now, true); 7369 if (result != ISC_R_SUCCESS) { 7370 dns_zone_log(zone, ISC_LOG_ERROR, 7371 "zone_resigninc:del_sigs -> %s", 7372 isc_result_totext(result)); 7373 break; 7374 } 7375 7376 /* 7377 * If re-signing is over 5 minutes late use 'fullexpire' 7378 * to redistribute the signature over the complete 7379 * re-signing window, otherwise only add a small amount 7380 * of jitter. 7381 */ 7382 result = add_sigs(db, version, name, zone, covers, 7383 zonediff.diff, zone_keys, nkeys, zone->mctx, 7384 now, inception, 7385 resign > (now - 300) ? expire : fullexpire); 7386 if (result != ISC_R_SUCCESS) { 7387 dns_zone_log(zone, ISC_LOG_ERROR, 7388 "zone_resigninc:add_sigs -> %s", 7389 isc_result_totext(result)); 7390 break; 7391 } 7392 result = dns_db_getsigningtime(db, &resign, name, &typepair); 7393 if (nkeys == 0 && result == ISC_R_NOTFOUND) { 7394 result = ISC_R_SUCCESS; 7395 break; 7396 } 7397 if (result != ISC_R_SUCCESS) { 7398 dns_zone_log(zone, ISC_LOG_ERROR, 7399 "zone_resigninc:dns_db_getsigningtime -> " 7400 "%s", 7401 isc_result_totext(result)); 7402 } 7403 } 7404 7405 if (result != ISC_R_NOMORE) { 7406 CHECK(result); 7407 } 7408 7409 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 7410 &zonediff, zone_keys, nkeys, now, true); 7411 if (result != ISC_R_SUCCESS) { 7412 dns_zone_log(zone, ISC_LOG_ERROR, 7413 "zone_resigninc:del_sigs -> %s", 7414 isc_result_totext(result)); 7415 goto cleanup; 7416 } 7417 7418 /* 7419 * Did we change anything in the zone? 7420 */ 7421 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 7422 /* 7423 * Commit the changes if any key has been marked as offline. 7424 */ 7425 if (zonediff.offline) { 7426 dns_db_closeversion(db, &version, true); 7427 } 7428 goto cleanup; 7429 } 7430 7431 /* Increment SOA serial if we have made changes */ 7432 result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx, 7433 zone->updatemethod); 7434 if (result != ISC_R_SUCCESS) { 7435 dns_zone_log(zone, ISC_LOG_ERROR, 7436 "zone_resigninc:update_soa_serial -> %s", 7437 isc_result_totext(result)); 7438 goto cleanup; 7439 } 7440 7441 /* 7442 * Generate maximum life time signatures so that the above loop 7443 * termination is sensible. 7444 */ 7445 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa, 7446 zonediff.diff, zone_keys, nkeys, zone->mctx, now, 7447 inception, soaexpire); 7448 if (result != ISC_R_SUCCESS) { 7449 dns_zone_log(zone, ISC_LOG_ERROR, 7450 "zone_resigninc:add_sigs -> %s", 7451 isc_result_totext(result)); 7452 goto cleanup; 7453 } 7454 7455 /* Write changes to journal file. */ 7456 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc")); 7457 7458 /* Everything has succeeded. Commit the changes. */ 7459 dns_db_closeversion(db, &version, true); 7460 7461 cleanup: 7462 dns_diff_clear(&_sig_diff); 7463 for (i = 0; i < nkeys; i++) { 7464 dst_key_free(&zone_keys[i]); 7465 } 7466 if (version != NULL) { 7467 dns_db_closeversion(db, &version, false); 7468 dns_db_detach(&db); 7469 } else if (db != NULL) { 7470 dns_db_detach(&db); 7471 } 7472 7473 LOCK_ZONE(zone); 7474 if (result == ISC_R_SUCCESS) { 7475 set_resigntime(zone); 7476 zone_needdump(zone, DNS_DUMP_DELAY); 7477 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 7478 } else { 7479 /* 7480 * Something failed. Retry in 5 minutes. 7481 */ 7482 isc_interval_t ival; 7483 isc_interval_set(&ival, 300, 0); 7484 isc_time_nowplusinterval(&zone->resigntime, &ival); 7485 } 7486 UNLOCK_ZONE(zone); 7487 7488 INSIST(version == NULL); 7489 } 7490 7491 static isc_result_t 7492 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname, 7493 dns_name_t *newname, bool bottom) { 7494 isc_result_t result; 7495 dns_dbiterator_t *dbit = NULL; 7496 dns_rdatasetiter_t *rdsit = NULL; 7497 dns_dbnode_t *node = NULL; 7498 7499 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit)); 7500 CHECK(dns_dbiterator_seek(dbit, oldname)); 7501 do { 7502 result = dns_dbiterator_next(dbit); 7503 if (result == ISC_R_NOMORE) { 7504 CHECK(dns_dbiterator_first(dbit)); 7505 } 7506 CHECK(dns_dbiterator_current(dbit, &node, newname)); 7507 if (bottom && dns_name_issubdomain(newname, oldname) && 7508 !dns_name_equal(newname, oldname)) 7509 { 7510 dns_db_detachnode(db, &node); 7511 continue; 7512 } 7513 /* 7514 * Is this node empty? 7515 */ 7516 CHECK(dns_db_allrdatasets(db, node, version, 0, 0, &rdsit)); 7517 result = dns_rdatasetiter_first(rdsit); 7518 dns_db_detachnode(db, &node); 7519 dns_rdatasetiter_destroy(&rdsit); 7520 if (result != ISC_R_NOMORE) { 7521 break; 7522 } 7523 } while (1); 7524 cleanup: 7525 if (node != NULL) { 7526 dns_db_detachnode(db, &node); 7527 } 7528 if (dbit != NULL) { 7529 dns_dbiterator_destroy(&dbit); 7530 } 7531 return result; 7532 } 7533 7534 static bool 7535 signed_with_good_key(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, 7536 dns_dbversion_t *version, dns_rdatatype_t type, 7537 dst_key_t *key, bool fullsign) { 7538 isc_result_t result; 7539 dns_rdataset_t rdataset; 7540 dns_rdata_t rdata = DNS_RDATA_INIT; 7541 dns_rdata_rrsig_t rrsig; 7542 int count = 0; 7543 dns_kasp_t *kasp = zone->kasp; 7544 7545 dns_rdataset_init(&rdataset); 7546 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig, 7547 type, 0, &rdataset, NULL); 7548 if (result != ISC_R_SUCCESS) { 7549 INSIST(!dns_rdataset_isassociated(&rdataset)); 7550 return false; 7551 } 7552 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 7553 result = dns_rdataset_next(&rdataset)) 7554 { 7555 dns_rdataset_current(&rdataset, &rdata); 7556 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 7557 INSIST(result == ISC_R_SUCCESS); 7558 if (rrsig.algorithm == dst_key_alg(key) && 7559 rrsig.keyid == dst_key_id(key)) 7560 { 7561 dns_rdataset_disassociate(&rdataset); 7562 return true; 7563 } 7564 if (rrsig.algorithm == dst_key_alg(key)) { 7565 count++; 7566 } 7567 dns_rdata_reset(&rdata); 7568 } 7569 7570 if (zone->kasp != NULL && !fullsign) { 7571 dns_kasp_key_t *kkey; 7572 int zsk_count = 0; 7573 bool approved; 7574 7575 KASP_LOCK(kasp); 7576 for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL; 7577 kkey = ISC_LIST_NEXT(kkey, link)) 7578 { 7579 if (dns_kasp_key_algorithm(kkey) != dst_key_alg(key)) { 7580 continue; 7581 } 7582 if (dns_kasp_key_zsk(kkey)) { 7583 zsk_count++; 7584 } 7585 } 7586 KASP_UNLOCK(kasp); 7587 7588 if (dns_rdatatype_iskeymaterial(type)) { 7589 /* 7590 * CDS and CDNSKEY are signed with KSK like DNSKEY. 7591 * (RFC 7344, section 4.1 specifies that they must 7592 * be signed with a key in the current DS RRset, 7593 * which would only include KSK's.) 7594 */ 7595 approved = false; 7596 } else { 7597 approved = (zsk_count == count); 7598 } 7599 7600 dns_rdataset_disassociate(&rdataset); 7601 return approved; 7602 } 7603 7604 dns_rdataset_disassociate(&rdataset); 7605 return false; 7606 } 7607 7608 static isc_result_t 7609 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 7610 dns_dbnode_t *node, dns_ttl_t ttl, bool bottom, dns_diff_t *diff) { 7611 dns_fixedname_t fixed; 7612 dns_name_t *next; 7613 dns_rdata_t rdata = DNS_RDATA_INIT; 7614 isc_result_t result; 7615 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE]; 7616 7617 next = dns_fixedname_initname(&fixed); 7618 7619 CHECK(next_active(db, version, name, next, bottom)); 7620 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer, &rdata)); 7621 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl, 7622 &rdata)); 7623 cleanup: 7624 return result; 7625 } 7626 7627 static isc_result_t 7628 check_if_bottom_of_zone(dns_db_t *db, dns_dbnode_t *node, 7629 dns_dbversion_t *version, bool *is_bottom_of_zone) { 7630 isc_result_t result; 7631 dns_rdatasetiter_t *iterator = NULL; 7632 dns_rdataset_t rdataset; 7633 bool seen_soa = false, seen_ns = false, seen_dname = false; 7634 7635 REQUIRE(is_bottom_of_zone != NULL); 7636 7637 result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator); 7638 if (result != ISC_R_SUCCESS) { 7639 if (result == ISC_R_NOTFOUND) { 7640 result = ISC_R_SUCCESS; 7641 } 7642 return result; 7643 } 7644 7645 dns_rdataset_init(&rdataset); 7646 for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; 7647 result = dns_rdatasetiter_next(iterator)) 7648 { 7649 dns_rdatasetiter_current(iterator, &rdataset); 7650 switch (rdataset.type) { 7651 case dns_rdatatype_soa: 7652 seen_soa = true; 7653 break; 7654 case dns_rdatatype_ns: 7655 seen_ns = true; 7656 break; 7657 case dns_rdatatype_dname: 7658 seen_dname = true; 7659 break; 7660 } 7661 dns_rdataset_disassociate(&rdataset); 7662 } 7663 if (result != ISC_R_NOMORE) { 7664 goto cleanup; 7665 } 7666 if ((seen_ns && !seen_soa) || seen_dname) { 7667 *is_bottom_of_zone = true; 7668 } 7669 result = ISC_R_SUCCESS; 7670 7671 cleanup: 7672 dns_rdatasetiter_destroy(&iterator); 7673 7674 return result; 7675 } 7676 7677 typedef struct seen { 7678 bool rr; 7679 bool soa; 7680 bool ns; 7681 bool nsec; 7682 bool nsec3; 7683 bool ds; 7684 bool dname; 7685 } seen_t; 7686 7687 static isc_result_t 7688 allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 7689 dns_rdatasetiter_t **iterp, seen_t *seen) { 7690 isc_result_t result; 7691 dns_rdataset_t rdataset = DNS_RDATASET_INIT; 7692 7693 *seen = (seen_t){}; 7694 7695 RETERR(dns_db_allrdatasets(db, node, version, 0, 0, iterp)); 7696 7697 for (result = dns_rdatasetiter_first(*iterp); result == ISC_R_SUCCESS; 7698 result = dns_rdatasetiter_next(*iterp)) 7699 { 7700 dns_rdatasetiter_current(*iterp, &rdataset); 7701 7702 if (rdataset.type == dns_rdatatype_rrsig) { 7703 dns_rdataset_disassociate(&rdataset); 7704 continue; 7705 } 7706 7707 (*seen).rr = true; 7708 7709 if (rdataset.type == dns_rdatatype_soa) { 7710 (*seen).soa = true; 7711 } else if (rdataset.type == dns_rdatatype_ns) { 7712 (*seen).ns = true; 7713 } else if (rdataset.type == dns_rdatatype_ds) { 7714 (*seen).ds = true; 7715 } else if (rdataset.type == dns_rdatatype_dname) { 7716 (*seen).dname = true; 7717 } else if (rdataset.type == dns_rdatatype_nsec) { 7718 (*seen).nsec = true; 7719 } else if (rdataset.type == dns_rdatatype_nsec3) { 7720 (*seen).nsec3 = true; 7721 } 7722 7723 dns_rdataset_disassociate(&rdataset); 7724 } 7725 7726 return ISC_R_SUCCESS; 7727 } 7728 7729 static isc_result_t 7730 sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name, 7731 dns_dbnode_t *node, dns_dbversion_t *version, bool build_nsec3, 7732 bool build_nsec, dst_key_t *key, isc_stdtime_t now, 7733 isc_stdtime_t inception, isc_stdtime_t expire, dns_ttl_t nsecttl, 7734 bool both, bool is_ksk, bool is_zsk, bool fullsign, 7735 bool is_bottom_of_zone, dns_diff_t *diff, int32_t *signatures, 7736 isc_mem_t *mctx) { 7737 isc_result_t result; 7738 dns_rdatasetiter_t *iterator = NULL; 7739 dns_rdataset_t rdataset; 7740 dns_rdata_t rdata = DNS_RDATA_INIT; 7741 dns_stats_t *dnssecsignstats; 7742 bool offlineksk = false; 7743 isc_buffer_t buffer; 7744 unsigned char data[1024]; 7745 seen_t seen; 7746 7747 if (zone->kasp != NULL) { 7748 offlineksk = dns_kasp_offlineksk(zone->kasp); 7749 } 7750 7751 result = allrdatasets(db, node, version, &iterator, &seen); 7752 if (result != ISC_R_SUCCESS) { 7753 if (result == ISC_R_NOTFOUND) { 7754 result = ISC_R_SUCCESS; 7755 } 7756 return result; 7757 } 7758 7759 dns_rdataset_init(&rdataset); 7760 isc_buffer_init(&buffer, data, sizeof(data)); 7761 7762 /* 7763 * Going from insecure to NSEC3. 7764 * Don't generate NSEC3 records for NSEC3 records. 7765 */ 7766 if (build_nsec3 && !seen.nsec3 && seen.rr) { 7767 bool unsecure = !seen.ds && seen.ns && !seen.soa; 7768 CHECK(dns_nsec3_addnsec3s(db, version, name, nsecttl, unsecure, 7769 diff)); 7770 (*signatures)--; 7771 } 7772 /* 7773 * Going from insecure to NSEC. 7774 * Don't generate NSEC records for NSEC3 records. 7775 */ 7776 if (build_nsec && !seen.nsec3 && !seen.nsec && seen.rr) { 7777 /* 7778 * Build a NSEC record except at the origin. 7779 */ 7780 if (!dns_name_equal(name, dns_db_origin(db))) { 7781 CHECK(add_nsec(db, version, name, node, nsecttl, 7782 is_bottom_of_zone, diff)); 7783 /* Count a NSEC generation as a signature generation. */ 7784 (*signatures)--; 7785 } 7786 } 7787 result = dns_rdatasetiter_first(iterator); 7788 while (result == ISC_R_SUCCESS) { 7789 isc_stdtime_t when; 7790 7791 dns_rdatasetiter_current(iterator, &rdataset); 7792 if (rdataset.type == dns_rdatatype_soa || 7793 rdataset.type == dns_rdatatype_rrsig) 7794 { 7795 goto next_rdataset; 7796 } 7797 if (dns_rdatatype_iskeymaterial(rdataset.type)) { 7798 /* 7799 * CDS and CDNSKEY are signed with KSK like DNSKEY. 7800 * (RFC 7344, section 4.1 specifies that they must 7801 * be signed with a key in the current DS RRset, 7802 * which would only include KSK's.) 7803 */ 7804 if (!is_ksk && both) { 7805 goto next_rdataset; 7806 } 7807 } else if (!is_zsk && both) { 7808 goto next_rdataset; 7809 } else if (is_zsk && 7810 !dst_key_is_signing(key, DST_BOOL_ZSK, now, &when)) 7811 { 7812 /* Only applies to dnssec-policy. */ 7813 if (zone->kasp != NULL) { 7814 goto next_rdataset; 7815 } 7816 } 7817 7818 if (seen.ns && !seen.soa && rdataset.type != dns_rdatatype_ds && 7819 rdataset.type != dns_rdatatype_nsec) 7820 { 7821 goto next_rdataset; 7822 } 7823 if (signed_with_good_key(zone, db, node, version, rdataset.type, 7824 key, fullsign)) 7825 { 7826 goto next_rdataset; 7827 } 7828 7829 /* Calculate the signature, creating a RRSIG RDATA. */ 7830 isc_buffer_clear(&buffer); 7831 if (offlineksk && dns_rdatatype_iskeymaterial(rdataset.type)) { 7832 /* Look up the signature in the SKR bundle */ 7833 dns_skrbundle_t *bundle = dns_zone_getskrbundle(zone); 7834 if (bundle == NULL) { 7835 CHECK(DNS_R_NOSKRBUNDLE); 7836 } 7837 CHECK(dns_skrbundle_getsig(bundle, key, rdataset.type, 7838 &rdata)); 7839 } else { 7840 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception, 7841 &expire, mctx, &buffer, &rdata)); 7842 } 7843 7844 /* Update the database and journal with the RRSIG. */ 7845 /* XXX inefficient - will cause dataset merging */ 7846 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN, 7847 name, rdataset.ttl, &rdata)); 7848 dns_rdata_reset(&rdata); 7849 7850 /* Update DNSSEC sign statistics. */ 7851 dnssecsignstats = dns_zone_getdnssecsignstats(zone); 7852 if (dnssecsignstats != NULL) { 7853 /* Generated a new signature. */ 7854 dns_dnssecsignstats_increment(dnssecsignstats, ID(key), 7855 ALG(key), 7856 dns_dnssecsignstats_sign); 7857 /* This is a refresh. */ 7858 dns_dnssecsignstats_increment( 7859 dnssecsignstats, ID(key), ALG(key), 7860 dns_dnssecsignstats_refresh); 7861 } 7862 7863 (*signatures)--; 7864 next_rdataset: 7865 dns_rdataset_disassociate(&rdataset); 7866 result = dns_rdatasetiter_next(iterator); 7867 } 7868 if (result == ISC_R_NOMORE) { 7869 result = ISC_R_SUCCESS; 7870 } 7871 7872 cleanup: 7873 if (dns_rdataset_isassociated(&rdataset)) { 7874 dns_rdataset_disassociate(&rdataset); 7875 } 7876 if (iterator != NULL) { 7877 dns_rdatasetiter_destroy(&iterator); 7878 } 7879 return result; 7880 } 7881 7882 /* 7883 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist. 7884 */ 7885 static isc_result_t 7886 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 7887 dns_ttl_t nsecttl, bool update_only, dns_diff_t *diff) { 7888 isc_result_t result; 7889 dns_rdataset_t rdataset; 7890 dns_dbnode_t *node = NULL; 7891 7892 CHECK(dns_db_getoriginnode(db, &node)); 7893 if (update_only) { 7894 dns_rdataset_init(&rdataset); 7895 result = dns_db_findrdataset( 7896 db, node, version, dns_rdatatype_nsec, 7897 dns_rdatatype_none, 0, &rdataset, NULL); 7898 if (dns_rdataset_isassociated(&rdataset)) { 7899 dns_rdataset_disassociate(&rdataset); 7900 } 7901 if (result == ISC_R_NOTFOUND) { 7902 goto success; 7903 } 7904 CHECK(result); 7905 } 7906 CHECK(delete_nsec(db, version, node, name, diff)); 7907 CHECK(add_nsec(db, version, name, node, nsecttl, false, diff)); 7908 success: 7909 result = ISC_R_SUCCESS; 7910 cleanup: 7911 if (node != NULL) { 7912 dns_db_detachnode(db, &node); 7913 } 7914 return result; 7915 } 7916 7917 static isc_result_t 7918 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing, 7919 dns_dbversion_t *version, bool build_nsec3, dns_ttl_t nsecttl, 7920 dns_diff_t *diff) { 7921 isc_result_t result; 7922 dns_dbnode_t *node = NULL; 7923 dns_rdataset_t rdataset; 7924 dns_rdata_t rdata = DNS_RDATA_INIT; 7925 unsigned char data[5]; 7926 bool seen_done = false; 7927 bool have_rr = false; 7928 7929 dns_rdataset_init(&rdataset); 7930 CHECK(dns_db_getoriginnode(signing->db, &node)); 7931 7932 result = dns_db_findrdataset(signing->db, node, version, 7933 zone->privatetype, dns_rdatatype_none, 0, 7934 &rdataset, NULL); 7935 if (result == ISC_R_NOTFOUND) { 7936 INSIST(!dns_rdataset_isassociated(&rdataset)); 7937 result = ISC_R_SUCCESS; 7938 goto cleanup; 7939 } 7940 if (result != ISC_R_SUCCESS) { 7941 INSIST(!dns_rdataset_isassociated(&rdataset)); 7942 goto cleanup; 7943 } 7944 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 7945 result = dns_rdataset_next(&rdataset)) 7946 { 7947 dns_rdataset_current(&rdataset, &rdata); 7948 /* 7949 * If we don't match the algorithm or keyid skip the record. 7950 */ 7951 if (rdata.length != 5 || rdata.data[0] != signing->algorithm || 7952 rdata.data[1] != ((signing->keyid >> 8) & 0xff) || 7953 rdata.data[2] != (signing->keyid & 0xff)) 7954 { 7955 have_rr = true; 7956 dns_rdata_reset(&rdata); 7957 continue; 7958 } 7959 /* 7960 * We have a match. If we were signing (!signing->deleteit) 7961 * and we already have a record indicating that we have 7962 * finished signing (rdata.data[4] != 0) then keep it. 7963 * Otherwise it needs to be deleted as we have removed all 7964 * the signatures (signing->deleteit), so any record indicating 7965 * completion is now out of date, or we have finished signing 7966 * with the new record so we no longer need to remember that 7967 * we need to sign the zone with the matching key across a 7968 * nameserver re-start. 7969 */ 7970 if (!signing->deleteit && rdata.data[4] != 0) { 7971 seen_done = true; 7972 have_rr = true; 7973 } else { 7974 CHECK(update_one_rr(signing->db, version, diff, 7975 DNS_DIFFOP_DEL, &zone->origin, 7976 rdataset.ttl, &rdata)); 7977 } 7978 dns_rdata_reset(&rdata); 7979 } 7980 if (result == ISC_R_NOMORE) { 7981 result = ISC_R_SUCCESS; 7982 } 7983 if (!signing->deleteit && !seen_done) { 7984 /* 7985 * If we were signing then we need to indicate that we have 7986 * finished signing the zone with this key. If it is already 7987 * there we don't need to add it a second time. 7988 */ 7989 data[0] = signing->algorithm; 7990 data[1] = (signing->keyid >> 8) & 0xff; 7991 data[2] = signing->keyid & 0xff; 7992 data[3] = 0; 7993 data[4] = 1; 7994 rdata.length = sizeof(data); 7995 rdata.data = data; 7996 rdata.type = zone->privatetype; 7997 rdata.rdclass = dns_db_class(signing->db); 7998 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD, 7999 &zone->origin, rdataset.ttl, &rdata)); 8000 } else if (!have_rr) { 8001 dns_name_t *origin = dns_db_origin(signing->db); 8002 /* 8003 * Rebuild the NSEC/NSEC3 record for the origin as we no 8004 * longer have any private records. 8005 */ 8006 if (build_nsec3) { 8007 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin, 8008 nsecttl, false, diff)); 8009 } 8010 CHECK(updatesecure(signing->db, version, origin, nsecttl, true, 8011 diff)); 8012 } 8013 8014 cleanup: 8015 if (dns_rdataset_isassociated(&rdataset)) { 8016 dns_rdataset_disassociate(&rdataset); 8017 } 8018 if (node != NULL) { 8019 dns_db_detachnode(signing->db, &node); 8020 } 8021 return result; 8022 } 8023 8024 /* 8025 * Called from zone_nsec3chain() in order to update zone records indicating 8026 * processing status of given NSEC3 chain: 8027 * 8028 * - If the supplied dns_nsec3chain_t structure has been fully processed 8029 * (which is indicated by "active" being set to false): 8030 * 8031 * - remove all NSEC3PARAM records matching the relevant NSEC3 chain, 8032 * 8033 * - remove all private-type records containing NSEC3PARAM RDATA matching 8034 * the relevant NSEC3 chain. 8035 * 8036 * - If the supplied dns_nsec3chain_t structure has not been fully processed 8037 * (which is indicated by "active" being set to true), only remove the 8038 * NSEC3PARAM record which matches the relevant NSEC3 chain and has the 8039 * "flags" field set to 0. 8040 * 8041 * - If given NSEC3 chain is being added, add an NSEC3PARAM record contained 8042 * in the relevant private-type record, but with the "flags" field set to 8043 * 0, indicating that this NSEC3 chain is now complete for this zone. 8044 * 8045 * Note that this function is called at different processing stages for NSEC3 8046 * chain additions vs. removals and needs to handle all cases properly. 8047 */ 8048 static isc_result_t 8049 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain, 8050 bool active, dns_rdatatype_t privatetype, dns_diff_t *diff) { 8051 dns_dbnode_t *node = NULL; 8052 dns_name_t *name = dns_db_origin(db); 8053 dns_rdata_t rdata = DNS_RDATA_INIT; 8054 dns_rdataset_t rdataset; 8055 dns_rdata_nsec3param_t nsec3param; 8056 dns_rdata_soa_t soa; 8057 isc_result_t result; 8058 isc_buffer_t buffer; 8059 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE]; 8060 dns_ttl_t ttl = 0; 8061 bool nseconly = false, nsec3ok = false; 8062 8063 dns_rdataset_init(&rdataset); 8064 8065 result = dns_db_getoriginnode(db, &node); 8066 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8067 8068 /* Default TTL is SOA MINIMUM */ 8069 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0, 0, 8070 &rdataset, NULL); 8071 if (result == ISC_R_SUCCESS) { 8072 CHECK(dns_rdataset_first(&rdataset)); 8073 dns_rdataset_current(&rdataset, &rdata); 8074 CHECK(dns_rdata_tostruct(&rdata, &soa, NULL)); 8075 ttl = soa.minimum; 8076 dns_rdata_reset(&rdata); 8077 } 8078 if (dns_rdataset_isassociated(&rdataset)) { 8079 dns_rdataset_disassociate(&rdataset); 8080 } 8081 8082 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0, 8083 0, &rdataset, NULL); 8084 if (result == ISC_R_NOTFOUND) { 8085 goto try_private; 8086 } 8087 if (result != ISC_R_SUCCESS) { 8088 goto cleanup; 8089 } 8090 8091 /* 8092 * Delete all NSEC3PARAM records which match that in nsec3chain. 8093 */ 8094 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8095 result = dns_rdataset_next(&rdataset)) 8096 { 8097 dns_rdataset_current(&rdataset, &rdata); 8098 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 8099 8100 if (nsec3param.hash != chain->nsec3param.hash || 8101 (active && nsec3param.flags != 0) || 8102 nsec3param.iterations != chain->nsec3param.iterations || 8103 nsec3param.salt_length != chain->nsec3param.salt_length || 8104 memcmp(nsec3param.salt, chain->nsec3param.salt, 8105 nsec3param.salt_length)) 8106 { 8107 /* 8108 * If the SOA minimum is different to the current TTL, 8109 * delete the record. We will re-add it with the new 8110 * TTL below. 8111 */ 8112 if (rdataset.ttl != ttl) { 8113 CHECK(update_one_rr(db, ver, diff, 8114 DNS_DIFFOP_DEL, name, 8115 rdataset.ttl, &rdata)); 8116 } 8117 dns_rdata_reset(&rdata); 8118 continue; 8119 } 8120 8121 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8122 rdataset.ttl, &rdata)); 8123 dns_rdata_reset(&rdata); 8124 } 8125 if (result != ISC_R_NOMORE) { 8126 goto cleanup; 8127 } 8128 8129 /* 8130 * Restore any NSEC3PARAM records that we deleted to change the TTL. 8131 */ 8132 if (rdataset.ttl != ttl) { 8133 for (result = dns_rdataset_first(&rdataset); 8134 result == ISC_R_SUCCESS; 8135 result = dns_rdataset_next(&rdataset)) 8136 { 8137 dns_rdataset_current(&rdataset, &rdata); 8138 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 8139 8140 if (nsec3param.hash != chain->nsec3param.hash || 8141 (active && nsec3param.flags != 0) || 8142 nsec3param.iterations != 8143 chain->nsec3param.iterations || 8144 nsec3param.salt_length != 8145 chain->nsec3param.salt_length || 8146 memcmp(nsec3param.salt, chain->nsec3param.salt, 8147 nsec3param.salt_length)) 8148 { 8149 CHECK(update_one_rr(db, ver, diff, 8150 DNS_DIFFOP_ADD, name, ttl, 8151 &rdata)); 8152 } 8153 dns_rdata_reset(&rdata); 8154 } 8155 } 8156 8157 dns_rdataset_disassociate(&rdataset); 8158 8159 try_private: 8160 8161 if (active) { 8162 goto add; 8163 } 8164 8165 result = dns_nsec_nseconly(db, ver, diff, &nseconly); 8166 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 8167 8168 /* 8169 * Delete all private records which match that in nsec3chain. 8170 */ 8171 result = dns_db_findrdataset(db, node, ver, privatetype, 0, 0, 8172 &rdataset, NULL); 8173 if (result == ISC_R_NOTFOUND) { 8174 goto add; 8175 } 8176 CHECK(result); 8177 8178 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8179 result = dns_rdataset_next(&rdataset)) 8180 { 8181 dns_rdata_t private = DNS_RDATA_INIT; 8182 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 8183 8184 dns_rdataset_current(&rdataset, &private); 8185 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 8186 sizeof(buf))) 8187 { 8188 continue; 8189 } 8190 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 8191 8192 if ((!nsec3ok && 8193 (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) || 8194 nsec3param.hash != chain->nsec3param.hash || 8195 nsec3param.iterations != chain->nsec3param.iterations || 8196 nsec3param.salt_length != chain->nsec3param.salt_length || 8197 memcmp(nsec3param.salt, chain->nsec3param.salt, 8198 nsec3param.salt_length)) 8199 { 8200 dns_rdata_reset(&rdata); 8201 continue; 8202 } 8203 8204 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8205 rdataset.ttl, &private)); 8206 dns_rdata_reset(&rdata); 8207 } 8208 if (result != ISC_R_NOMORE) { 8209 goto cleanup; 8210 } 8211 8212 add: 8213 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) { 8214 result = ISC_R_SUCCESS; 8215 goto cleanup; 8216 } 8217 8218 /* 8219 * Add a NSEC3PARAM record which matches that in nsec3chain but 8220 * with all flags bits cleared. 8221 * 8222 * Note: we do not clear chain->nsec3param.flags as this change 8223 * may be reversed. 8224 */ 8225 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf)); 8226 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), 8227 dns_rdatatype_nsec3param, &chain->nsec3param, 8228 &buffer)); 8229 rdata.data[1] = 0; /* Clear flag bits. */ 8230 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata)); 8231 8232 cleanup: 8233 dns_db_detachnode(db, &node); 8234 if (dns_rdataset_isassociated(&rdataset)) { 8235 dns_rdataset_disassociate(&rdataset); 8236 } 8237 return result; 8238 } 8239 8240 static isc_result_t 8241 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 8242 dns_name_t *name, dns_diff_t *diff) { 8243 dns_rdataset_t rdataset; 8244 isc_result_t result; 8245 8246 dns_rdataset_init(&rdataset); 8247 8248 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0, 8249 &rdataset, NULL); 8250 if (result == ISC_R_NOTFOUND) { 8251 return ISC_R_SUCCESS; 8252 } 8253 if (result != ISC_R_SUCCESS) { 8254 return result; 8255 } 8256 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8257 result = dns_rdataset_next(&rdataset)) 8258 { 8259 dns_rdata_t rdata = DNS_RDATA_INIT; 8260 8261 dns_rdataset_current(&rdataset, &rdata); 8262 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8263 rdataset.ttl, &rdata)); 8264 } 8265 if (result == ISC_R_NOMORE) { 8266 result = ISC_R_SUCCESS; 8267 } 8268 8269 cleanup: 8270 dns_rdataset_disassociate(&rdataset); 8271 return result; 8272 } 8273 8274 static isc_result_t 8275 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 8276 dns_name_t *name, const dns_rdata_nsec3param_t *param, 8277 dns_diff_t *diff) { 8278 dns_rdataset_t rdataset; 8279 dns_rdata_nsec3_t nsec3; 8280 isc_result_t result; 8281 8282 dns_rdataset_init(&rdataset); 8283 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 0, 0, 8284 &rdataset, NULL); 8285 if (result == ISC_R_NOTFOUND) { 8286 return ISC_R_SUCCESS; 8287 } 8288 if (result != ISC_R_SUCCESS) { 8289 return result; 8290 } 8291 8292 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8293 result = dns_rdataset_next(&rdataset)) 8294 { 8295 dns_rdata_t rdata = DNS_RDATA_INIT; 8296 8297 dns_rdataset_current(&rdataset, &rdata); 8298 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL)); 8299 if (nsec3.hash != param->hash || 8300 nsec3.iterations != param->iterations || 8301 nsec3.salt_length != param->salt_length || 8302 memcmp(nsec3.salt, param->salt, nsec3.salt_length)) 8303 { 8304 continue; 8305 } 8306 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8307 rdataset.ttl, &rdata)); 8308 } 8309 if (result == ISC_R_NOMORE) { 8310 result = ISC_R_SUCCESS; 8311 } 8312 8313 cleanup: 8314 dns_rdataset_disassociate(&rdataset); 8315 return result; 8316 } 8317 8318 static isc_result_t 8319 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver, 8320 const dns_rdata_nsec3param_t *param, bool *answer) { 8321 dns_dbnode_t *node = NULL; 8322 dns_rdata_t rdata = DNS_RDATA_INIT; 8323 dns_rdata_nsec3param_t myparam; 8324 dns_rdataset_t rdataset; 8325 isc_result_t result; 8326 8327 *answer = false; 8328 8329 result = dns_db_getoriginnode(db, &node); 8330 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8331 8332 dns_rdataset_init(&rdataset); 8333 8334 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0, 8335 &rdataset, NULL); 8336 if (result == ISC_R_SUCCESS) { 8337 dns_rdataset_disassociate(&rdataset); 8338 dns_db_detachnode(db, &node); 8339 return result; 8340 } 8341 if (result != ISC_R_NOTFOUND) { 8342 dns_db_detachnode(db, &node); 8343 return result; 8344 } 8345 8346 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0, 8347 0, &rdataset, NULL); 8348 if (result == ISC_R_NOTFOUND) { 8349 *answer = true; 8350 dns_db_detachnode(db, &node); 8351 return ISC_R_SUCCESS; 8352 } 8353 if (result != ISC_R_SUCCESS) { 8354 dns_db_detachnode(db, &node); 8355 return result; 8356 } 8357 8358 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8359 result = dns_rdataset_next(&rdataset)) 8360 { 8361 dns_rdataset_current(&rdataset, &rdata); 8362 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL)); 8363 dns_rdata_reset(&rdata); 8364 /* 8365 * Ignore any NSEC3PARAM removals. 8366 */ 8367 if (NSEC3REMOVE(myparam.flags)) { 8368 continue; 8369 } 8370 /* 8371 * Ignore the chain that we are in the process of deleting. 8372 */ 8373 if (myparam.hash == param->hash && 8374 myparam.iterations == param->iterations && 8375 myparam.salt_length == param->salt_length && 8376 !memcmp(myparam.salt, param->salt, myparam.salt_length)) 8377 { 8378 continue; 8379 } 8380 /* 8381 * Found an active NSEC3 chain. 8382 */ 8383 break; 8384 } 8385 if (result == ISC_R_NOMORE) { 8386 *answer = true; 8387 result = ISC_R_SUCCESS; 8388 } 8389 8390 cleanup: 8391 if (dns_rdataset_isassociated(&rdataset)) { 8392 dns_rdataset_disassociate(&rdataset); 8393 } 8394 dns_db_detachnode(db, &node); 8395 return result; 8396 } 8397 8398 /*% 8399 * Given a tuple which is part of a diff, return a pointer to the next tuple in 8400 * that diff which has the same name and type (or NULL if no such tuple is 8401 * found). 8402 */ 8403 static dns_difftuple_t * 8404 find_next_matching_tuple(dns_difftuple_t *cur) { 8405 dns_difftuple_t *next = cur; 8406 8407 while ((next = ISC_LIST_NEXT(next, link)) != NULL) { 8408 if (cur->rdata.type == next->rdata.type && 8409 dns_name_equal(&cur->name, &next->name)) 8410 { 8411 return next; 8412 } 8413 } 8414 8415 return NULL; 8416 } 8417 8418 /*% 8419 * Remove all tuples with the same name and type as 'cur' from 'src' and append 8420 * them to 'dst'. 8421 */ 8422 static void 8423 move_matching_tuples(dns_difftuple_t *cur, dns_diff_t *src, dns_diff_t *dst) { 8424 do { 8425 dns_difftuple_t *next = find_next_matching_tuple(cur); 8426 ISC_LIST_UNLINK(src->tuples, cur, link); 8427 dns_diff_appendminimal(dst, &cur); 8428 cur = next; 8429 } while (cur != NULL); 8430 } 8431 8432 /*% 8433 * Add/remove DNSSEC signatures for the list of "raw" zone changes supplied in 8434 * 'diff'. Gradually remove tuples from 'diff' and append them to 'zonediff' 8435 * along with tuples representing relevant signature changes. 8436 */ 8437 isc_result_t 8438 dns__zone_updatesigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, 8439 dst_key_t *zone_keys[], unsigned int nkeys, 8440 dns_zone_t *zone, isc_stdtime_t inception, 8441 isc_stdtime_t expire, isc_stdtime_t keyexpire, 8442 isc_stdtime_t now, dns__zonediff_t *zonediff) { 8443 dns_difftuple_t *tuple; 8444 isc_result_t result; 8445 8446 while ((tuple = ISC_LIST_HEAD(diff->tuples)) != NULL) { 8447 isc_stdtime_t exp = expire; 8448 8449 if (keyexpire != 0 && 8450 dns_rdatatype_iskeymaterial(tuple->rdata.type)) 8451 { 8452 exp = keyexpire; 8453 } 8454 8455 result = del_sigs(zone, db, version, &tuple->name, 8456 tuple->rdata.type, zonediff, zone_keys, nkeys, 8457 now, false); 8458 if (result != ISC_R_SUCCESS) { 8459 dns_zone_log(zone, ISC_LOG_ERROR, 8460 "dns__zone_updatesigs:del_sigs -> %s", 8461 isc_result_totext(result)); 8462 return result; 8463 } 8464 result = add_sigs(db, version, &tuple->name, zone, 8465 tuple->rdata.type, zonediff->diff, zone_keys, 8466 nkeys, zone->mctx, now, inception, exp); 8467 if (result != ISC_R_SUCCESS) { 8468 dns_zone_log(zone, ISC_LOG_ERROR, 8469 "dns__zone_updatesigs:add_sigs -> %s", 8470 isc_result_totext(result)); 8471 return result; 8472 } 8473 8474 /* 8475 * Signature changes for all RRs with name tuple->name and type 8476 * tuple->rdata.type were appended to zonediff->diff. Now we 8477 * remove all the "raw" changes with the same name and type 8478 * from diff (so that they are not processed by this loop 8479 * again) and append them to zonediff so that they get applied. 8480 */ 8481 move_matching_tuples(tuple, diff, zonediff->diff); 8482 } 8483 return ISC_R_SUCCESS; 8484 } 8485 8486 /* 8487 * Incrementally build and sign a new NSEC3 chain using the parameters 8488 * requested. 8489 */ 8490 static void 8491 zone_nsec3chain(dns_zone_t *zone) { 8492 dns_db_t *db = NULL; 8493 dns_dbnode_t *node = NULL; 8494 dns_dbversion_t *version = NULL; 8495 dns_diff_t _sig_diff; 8496 dns_diff_t nsec_diff; 8497 dns_diff_t nsec3_diff; 8498 dns_diff_t param_diff; 8499 dns__zonediff_t zonediff; 8500 dns_fixedname_t fixed; 8501 dns_fixedname_t nextfixed; 8502 dns_name_t *name, *nextname; 8503 dns_rdataset_t rdataset; 8504 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain; 8505 dns_nsec3chainlist_t cleanup; 8506 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 8507 int32_t signatures; 8508 bool delegation; 8509 bool first; 8510 isc_result_t result; 8511 isc_stdtime_t now, inception, soaexpire, expire; 8512 unsigned int i; 8513 unsigned int nkeys = 0; 8514 uint32_t nodes; 8515 bool unsecure = false; 8516 seen_t seen; 8517 dns_rdatasetiter_t *iterator = NULL; 8518 bool buildnsecchain; 8519 bool updatensec = false; 8520 dns_rdatatype_t privatetype = zone->privatetype; 8521 8522 ENTER; 8523 8524 dns_rdataset_init(&rdataset); 8525 name = dns_fixedname_initname(&fixed); 8526 nextname = dns_fixedname_initname(&nextfixed); 8527 dns_diff_init(zone->mctx, ¶m_diff); 8528 dns_diff_init(zone->mctx, &nsec3_diff); 8529 dns_diff_init(zone->mctx, &nsec_diff); 8530 dns_diff_init(zone->mctx, &_sig_diff); 8531 zonediff_init(&zonediff, &_sig_diff); 8532 ISC_LIST_INIT(cleanup); 8533 8534 /* 8535 * Updates are disabled. Pause for 5 minutes. 8536 */ 8537 if (zone->update_disabled) { 8538 CHECK(ISC_R_FAILURE); 8539 } 8540 8541 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8542 /* 8543 * This function is called when zone timer fires, after the latter gets 8544 * set by zone_addnsec3chain(). If the action triggering the call to 8545 * zone_addnsec3chain() is closely followed by a zone deletion request, 8546 * it might turn out that the timer thread will not be woken up until 8547 * after the zone is deleted by rmzone(), which calls dns_db_detach() 8548 * for zone->db, causing the latter to become NULL. Return immediately 8549 * if that happens. 8550 */ 8551 if (zone->db != NULL) { 8552 dns_db_attach(zone->db, &db); 8553 } 8554 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8555 if (db == NULL) { 8556 return; 8557 } 8558 8559 result = dns_db_newversion(db, &version); 8560 if (result != ISC_R_SUCCESS) { 8561 dnssec_log(zone, ISC_LOG_ERROR, 8562 "zone_nsec3chain:dns_db_newversion -> %s", 8563 isc_result_totext(result)); 8564 goto cleanup; 8565 } 8566 8567 now = isc_stdtime_now(); 8568 8569 result = dns_zone_findkeys(zone, db, version, now, zone->mctx, 8570 DNS_MAXZONEKEYS, zone_keys, &nkeys); 8571 if (result != ISC_R_SUCCESS) { 8572 dnssec_log(zone, ISC_LOG_ERROR, 8573 "zone_nsec3chain:dns_zone_findkeys -> %s", 8574 isc_result_totext(result)); 8575 goto cleanup; 8576 } 8577 8578 calculate_rrsig_validity(zone, now, &inception, &soaexpire, NULL, 8579 &expire); 8580 8581 /* 8582 * We keep pulling nodes off each iterator in turn until 8583 * we have no more nodes to pull off or we reach the limits 8584 * for this quantum. 8585 */ 8586 nodes = zone->nodes; 8587 signatures = zone->signatures; 8588 LOCK_ZONE(zone); 8589 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 8590 UNLOCK_ZONE(zone); 8591 first = true; 8592 8593 if (nsec3chain != NULL) { 8594 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 8595 } 8596 /* 8597 * Generate new NSEC3 chains first. 8598 * 8599 * The following while loop iterates over nodes in the zone database, 8600 * updating the NSEC3 chain by calling dns_nsec3_addnsec3() for each of 8601 * them. Once all nodes are processed, the "delete_nsec" field is 8602 * consulted to check whether we are supposed to remove NSEC records 8603 * from the zone database; if so, the database iterator is reset to 8604 * point to the first node and the loop traverses all of them again, 8605 * this time removing NSEC records. If we hit a node which is obscured 8606 * by a delegation or a DNAME, nodes are skipped over until we find one 8607 * that is not obscured by the same obscuring name and then normal 8608 * processing is resumed. 8609 * 8610 * The above is repeated until all requested NSEC3 chain changes are 8611 * applied or when we reach the limits for this quantum, whichever 8612 * happens first. 8613 * 8614 * Note that the "signatures" variable is only used here to limit the 8615 * amount of work performed. Actual DNSSEC signatures are only 8616 * generated by dns__zone_updatesigs() calls later in this function. 8617 */ 8618 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 8619 dns_dbiterator_pause(nsec3chain->dbiterator); 8620 8621 LOCK_ZONE(zone); 8622 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 8623 8624 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8625 if (nsec3chain->done || nsec3chain->db != zone->db) { 8626 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 8627 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8628 } 8629 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8630 UNLOCK_ZONE(zone); 8631 if (ISC_LIST_TAIL(cleanup) == nsec3chain) { 8632 goto next_addchain; 8633 } 8634 8635 /* 8636 * Possible future db. 8637 */ 8638 if (nsec3chain->db != db) { 8639 goto next_addchain; 8640 } 8641 8642 if (NSEC3REMOVE(nsec3chain->nsec3param.flags)) { 8643 goto next_addchain; 8644 } 8645 8646 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 8647 8648 if (nsec3chain->delete_nsec) { 8649 delegation = false; 8650 dns_dbiterator_pause(nsec3chain->dbiterator); 8651 CHECK(delete_nsec(db, version, node, name, &nsec_diff)); 8652 goto next_addnode; 8653 } 8654 /* 8655 * On the first pass we need to check if the current node 8656 * has not been obscured. 8657 */ 8658 delegation = false; 8659 unsecure = false; 8660 if (first) { 8661 dns_fixedname_t ffound; 8662 dns_name_t *found; 8663 found = dns_fixedname_initname(&ffound); 8664 result = dns_db_find( 8665 db, name, version, dns_rdatatype_soa, 8666 DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); 8667 if ((result == DNS_R_DELEGATION || 8668 result == DNS_R_DNAME) && 8669 !dns_name_equal(name, found)) 8670 { 8671 /* 8672 * Remember the obscuring name so that 8673 * we skip all obscured names. 8674 */ 8675 dns_name_copy(found, name); 8676 delegation = true; 8677 goto next_addnode; 8678 } 8679 } 8680 8681 /* 8682 * Check to see if this is a bottom of zone node. 8683 */ 8684 result = allrdatasets(db, node, version, &iterator, &seen); 8685 if (result == ISC_R_NOTFOUND) { 8686 /* Empty node? */ 8687 goto next_addnode; 8688 } 8689 CHECK(result); 8690 8691 INSIST(!seen.nsec3); 8692 8693 dns_rdatasetiter_destroy(&iterator); 8694 /* 8695 * Is there a NSEC chain than needs to be cleaned up? 8696 */ 8697 if (seen.nsec) { 8698 nsec3chain->seen_nsec = true; 8699 } 8700 8701 if (seen.ns && !seen.soa && !seen.ds) { 8702 unsecure = true; 8703 } 8704 if ((seen.ns && !seen.soa) || seen.dname) { 8705 delegation = true; 8706 } 8707 8708 /* 8709 * Process one node. 8710 */ 8711 dns_dbiterator_pause(nsec3chain->dbiterator); 8712 result = dns_nsec3_addnsec3( 8713 db, version, name, &nsec3chain->nsec3param, 8714 zone_nsecttl(zone), unsecure, &nsec3_diff); 8715 if (result != ISC_R_SUCCESS) { 8716 dnssec_log(zone, ISC_LOG_ERROR, 8717 "zone_nsec3chain:" 8718 "dns_nsec3_addnsec3 -> %s", 8719 isc_result_totext(result)); 8720 goto cleanup; 8721 } 8722 8723 /* 8724 * Treat each call to dns_nsec3_addnsec3() as if it's cost is 8725 * two signatures. Additionally there will, in general, be 8726 * two signature generated below. 8727 * 8728 * If we are only changing the optout flag the cost is half 8729 * that of the cost of generating a completely new chain. 8730 */ 8731 signatures -= 4; 8732 8733 /* 8734 * Go onto next node. 8735 */ 8736 next_addnode: 8737 first = false; 8738 dns_db_detachnode(db, &node); 8739 do { 8740 result = dns_dbiterator_next(nsec3chain->dbiterator); 8741 8742 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) { 8743 dns_dbiterator_pause(nsec3chain->dbiterator); 8744 CHECK(fixup_nsec3param(db, version, nsec3chain, 8745 false, privatetype, 8746 ¶m_diff)); 8747 LOCK_ZONE(zone); 8748 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 8749 link); 8750 UNLOCK_ZONE(zone); 8751 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8752 goto next_addchain; 8753 } 8754 if (result == ISC_R_NOMORE) { 8755 dns_dbiterator_pause(nsec3chain->dbiterator); 8756 if (nsec3chain->seen_nsec) { 8757 CHECK(fixup_nsec3param( 8758 db, version, nsec3chain, true, 8759 privatetype, ¶m_diff)); 8760 nsec3chain->delete_nsec = true; 8761 goto same_addchain; 8762 } 8763 CHECK(fixup_nsec3param(db, version, nsec3chain, 8764 false, privatetype, 8765 ¶m_diff)); 8766 LOCK_ZONE(zone); 8767 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 8768 link); 8769 UNLOCK_ZONE(zone); 8770 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8771 goto next_addchain; 8772 } else if (result != ISC_R_SUCCESS) { 8773 dnssec_log(zone, ISC_LOG_ERROR, 8774 "zone_nsec3chain:" 8775 "dns_dbiterator_next -> %s", 8776 isc_result_totext(result)); 8777 goto cleanup; 8778 } else if (delegation) { 8779 dns_dbiterator_current(nsec3chain->dbiterator, 8780 &node, nextname); 8781 dns_db_detachnode(db, &node); 8782 if (!dns_name_issubdomain(nextname, name)) { 8783 break; 8784 } 8785 } else { 8786 break; 8787 } 8788 } while (1); 8789 continue; 8790 8791 same_addchain: 8792 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 8793 first = true; 8794 continue; 8795 8796 next_addchain: 8797 dns_dbiterator_pause(nsec3chain->dbiterator); 8798 nsec3chain = nextnsec3chain; 8799 first = true; 8800 if (nsec3chain != NULL) { 8801 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 8802 } 8803 } 8804 8805 if (nsec3chain != NULL) { 8806 goto skip_removals; 8807 } 8808 8809 /* 8810 * Process removals. 8811 * 8812 * This is a counterpart of the above while loop which takes care of 8813 * removing an NSEC3 chain. It starts with determining whether the 8814 * zone needs to switch from NSEC3 to NSEC; if so, it first builds an 8815 * NSEC chain by iterating over all nodes in the zone database and only 8816 * then goes on to remove NSEC3 records be iterating over all nodes 8817 * again and calling deletematchingnsec3() for each of them; otherwise, 8818 * it starts removing NSEC3 records immediately. Rules for processing 8819 * obscured nodes and interrupting work are the same as for the while 8820 * loop above. 8821 */ 8822 LOCK_ZONE(zone); 8823 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 8824 UNLOCK_ZONE(zone); 8825 first = true; 8826 buildnsecchain = false; 8827 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 8828 dns_dbiterator_pause(nsec3chain->dbiterator); 8829 8830 LOCK_ZONE(zone); 8831 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 8832 UNLOCK_ZONE(zone); 8833 8834 if (nsec3chain->db != db) { 8835 goto next_removechain; 8836 } 8837 8838 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) { 8839 goto next_removechain; 8840 } 8841 8842 /* 8843 * Work out if we need to build a NSEC chain as a consequence 8844 * of removing this NSEC3 chain. 8845 */ 8846 if (first && !updatensec && 8847 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) 8848 { 8849 result = need_nsec_chain(db, version, 8850 &nsec3chain->nsec3param, 8851 &buildnsecchain); 8852 if (result != ISC_R_SUCCESS) { 8853 dnssec_log(zone, ISC_LOG_ERROR, 8854 "zone_nsec3chain:" 8855 "need_nsec_chain -> %s", 8856 isc_result_totext(result)); 8857 goto cleanup; 8858 } 8859 } 8860 8861 if (first) { 8862 dnssec_log(zone, ISC_LOG_DEBUG(3), 8863 "zone_nsec3chain:buildnsecchain = %u", 8864 buildnsecchain); 8865 } 8866 8867 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 8868 dns_dbiterator_pause(nsec3chain->dbiterator); 8869 delegation = false; 8870 8871 if (!buildnsecchain) { 8872 /* 8873 * Delete the NSEC3PARAM record matching this chain. 8874 */ 8875 if (first) { 8876 result = fixup_nsec3param( 8877 db, version, nsec3chain, true, 8878 privatetype, ¶m_diff); 8879 if (result != ISC_R_SUCCESS) { 8880 dnssec_log(zone, ISC_LOG_ERROR, 8881 "zone_nsec3chain:" 8882 "fixup_nsec3param -> %s", 8883 isc_result_totext(result)); 8884 goto cleanup; 8885 } 8886 } 8887 8888 /* 8889 * Delete the NSEC3 records. 8890 */ 8891 result = deletematchingnsec3(db, version, node, name, 8892 &nsec3chain->nsec3param, 8893 &nsec3_diff); 8894 if (result != ISC_R_SUCCESS) { 8895 dnssec_log(zone, ISC_LOG_ERROR, 8896 "zone_nsec3chain:" 8897 "deletematchingnsec3 -> %s", 8898 isc_result_totext(result)); 8899 goto cleanup; 8900 } 8901 goto next_removenode; 8902 } 8903 8904 if (first) { 8905 dns_fixedname_t ffound; 8906 dns_name_t *found; 8907 found = dns_fixedname_initname(&ffound); 8908 result = dns_db_find( 8909 db, name, version, dns_rdatatype_soa, 8910 DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); 8911 if ((result == DNS_R_DELEGATION || 8912 result == DNS_R_DNAME) && 8913 !dns_name_equal(name, found)) 8914 { 8915 /* 8916 * Remember the obscuring name so that 8917 * we skip all obscured names. 8918 */ 8919 dns_name_copy(found, name); 8920 delegation = true; 8921 goto next_removenode; 8922 } 8923 } 8924 8925 /* 8926 * Check to see if this is a bottom of zone node. 8927 */ 8928 result = allrdatasets(db, node, version, &iterator, &seen); 8929 if (result == ISC_R_NOTFOUND) { 8930 /* Empty node? */ 8931 goto next_removenode; 8932 } 8933 CHECK(result); 8934 8935 dns_rdatasetiter_destroy(&iterator); 8936 8937 if (!seen.rr || seen.nsec3 || seen.nsec) { 8938 goto next_removenode; 8939 } 8940 if ((seen.ns && !seen.soa) || seen.dname) { 8941 delegation = true; 8942 } 8943 8944 /* 8945 * Add a NSEC record except at the origin. 8946 */ 8947 if (!dns_name_equal(name, dns_db_origin(db))) { 8948 dns_dbiterator_pause(nsec3chain->dbiterator); 8949 CHECK(add_nsec(db, version, name, node, 8950 zone_nsecttl(zone), delegation, 8951 &nsec_diff)); 8952 signatures--; 8953 } 8954 8955 next_removenode: 8956 first = false; 8957 dns_db_detachnode(db, &node); 8958 do { 8959 result = dns_dbiterator_next(nsec3chain->dbiterator); 8960 if (result == ISC_R_NOMORE && buildnsecchain) { 8961 /* 8962 * The NSEC chain should now be built. 8963 * We can now remove the NSEC3 chain. 8964 */ 8965 updatensec = true; 8966 goto same_removechain; 8967 } 8968 if (result == ISC_R_NOMORE) { 8969 dns_dbiterator_pause(nsec3chain->dbiterator); 8970 LOCK_ZONE(zone); 8971 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 8972 link); 8973 UNLOCK_ZONE(zone); 8974 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8975 result = fixup_nsec3param( 8976 db, version, nsec3chain, false, 8977 privatetype, ¶m_diff); 8978 if (result != ISC_R_SUCCESS) { 8979 dnssec_log(zone, ISC_LOG_ERROR, 8980 "zone_nsec3chain:" 8981 "fixup_nsec3param -> %s", 8982 isc_result_totext(result)); 8983 goto cleanup; 8984 } 8985 goto next_removechain; 8986 } else if (result != ISC_R_SUCCESS) { 8987 dnssec_log(zone, ISC_LOG_ERROR, 8988 "zone_nsec3chain:" 8989 "dns_dbiterator_next -> %s", 8990 isc_result_totext(result)); 8991 goto cleanup; 8992 } else if (delegation) { 8993 dns_dbiterator_current(nsec3chain->dbiterator, 8994 &node, nextname); 8995 dns_db_detachnode(db, &node); 8996 if (!dns_name_issubdomain(nextname, name)) { 8997 break; 8998 } 8999 } else { 9000 break; 9001 } 9002 } while (1); 9003 continue; 9004 9005 same_removechain: 9006 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 9007 buildnsecchain = false; 9008 first = true; 9009 continue; 9010 9011 next_removechain: 9012 dns_dbiterator_pause(nsec3chain->dbiterator); 9013 nsec3chain = nextnsec3chain; 9014 first = true; 9015 } 9016 9017 skip_removals: 9018 /* 9019 * We may need to update the NSEC/NSEC3 records for the zone apex. 9020 */ 9021 if (!ISC_LIST_EMPTY(param_diff.tuples)) { 9022 bool rebuild_nsec = false, rebuild_nsec3 = false; 9023 result = dns_db_getoriginnode(db, &node); 9024 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9025 result = dns_db_allrdatasets(db, node, version, 0, 0, 9026 &iterator); 9027 if (result != ISC_R_SUCCESS) { 9028 dnssec_log(zone, ISC_LOG_ERROR, 9029 "zone_nsec3chain:dns_db_allrdatasets -> %s", 9030 isc_result_totext(result)); 9031 goto cleanup; 9032 } 9033 for (result = dns_rdatasetiter_first(iterator); 9034 result == ISC_R_SUCCESS; 9035 result = dns_rdatasetiter_next(iterator)) 9036 { 9037 dns_rdatasetiter_current(iterator, &rdataset); 9038 if (rdataset.type == dns_rdatatype_nsec) { 9039 rebuild_nsec = true; 9040 } else if (rdataset.type == dns_rdatatype_nsec3param) { 9041 rebuild_nsec3 = true; 9042 } 9043 dns_rdataset_disassociate(&rdataset); 9044 } 9045 dns_rdatasetiter_destroy(&iterator); 9046 dns_db_detachnode(db, &node); 9047 9048 if (rebuild_nsec) { 9049 if (nsec3chain != NULL) { 9050 dns_dbiterator_pause(nsec3chain->dbiterator); 9051 } 9052 9053 result = updatesecure(db, version, &zone->origin, 9054 zone_nsecttl(zone), true, 9055 &nsec_diff); 9056 if (result != ISC_R_SUCCESS) { 9057 dnssec_log(zone, ISC_LOG_ERROR, 9058 "zone_nsec3chain:updatesecure -> %s", 9059 isc_result_totext(result)); 9060 goto cleanup; 9061 } 9062 } 9063 9064 if (rebuild_nsec3) { 9065 if (nsec3chain != NULL) { 9066 dns_dbiterator_pause(nsec3chain->dbiterator); 9067 } 9068 9069 result = dns_nsec3_addnsec3s( 9070 db, version, dns_db_origin(db), 9071 zone_nsecttl(zone), false, &nsec3_diff); 9072 if (result != ISC_R_SUCCESS) { 9073 dnssec_log(zone, ISC_LOG_ERROR, 9074 "zone_nsec3chain:" 9075 "dns_nsec3_addnsec3s -> %s", 9076 isc_result_totext(result)); 9077 goto cleanup; 9078 } 9079 } 9080 } 9081 9082 /* 9083 * Add / update signatures for the NSEC3 records. 9084 */ 9085 if (nsec3chain != NULL) { 9086 dns_dbiterator_pause(nsec3chain->dbiterator); 9087 } 9088 result = dns__zone_updatesigs(&nsec3_diff, db, version, zone_keys, 9089 nkeys, zone, inception, expire, 0, now, 9090 &zonediff); 9091 if (result != ISC_R_SUCCESS) { 9092 dnssec_log(zone, ISC_LOG_ERROR, 9093 "zone_nsec3chain:dns__zone_updatesigs -> %s", 9094 isc_result_totext(result)); 9095 goto cleanup; 9096 } 9097 9098 /* 9099 * We have changed the NSEC3PARAM or private RRsets 9100 * above so we need to update the signatures. 9101 */ 9102 result = dns__zone_updatesigs(¶m_diff, db, version, zone_keys, 9103 nkeys, zone, inception, expire, 0, now, 9104 &zonediff); 9105 if (result != ISC_R_SUCCESS) { 9106 dnssec_log(zone, ISC_LOG_ERROR, 9107 "zone_nsec3chain:dns__zone_updatesigs -> %s", 9108 isc_result_totext(result)); 9109 goto cleanup; 9110 } 9111 9112 if (updatensec) { 9113 result = updatesecure(db, version, &zone->origin, 9114 zone_nsecttl(zone), false, &nsec_diff); 9115 if (result != ISC_R_SUCCESS) { 9116 dnssec_log(zone, ISC_LOG_ERROR, 9117 "zone_nsec3chain:updatesecure -> %s", 9118 isc_result_totext(result)); 9119 goto cleanup; 9120 } 9121 } 9122 9123 result = dns__zone_updatesigs(&nsec_diff, db, version, zone_keys, nkeys, 9124 zone, inception, expire, 0, now, 9125 &zonediff); 9126 if (result != ISC_R_SUCCESS) { 9127 dnssec_log(zone, ISC_LOG_ERROR, 9128 "zone_nsec3chain:dns__zone_updatesigs -> %s", 9129 isc_result_totext(result)); 9130 goto cleanup; 9131 } 9132 9133 /* 9134 * If we made no effective changes to the zone then we can just 9135 * cleanup otherwise we need to increment the serial. 9136 */ 9137 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 9138 /* 9139 * No need to call dns_db_closeversion() here as it is 9140 * called with commit = true below. 9141 */ 9142 goto closeversion; 9143 } 9144 9145 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 9146 &zonediff, zone_keys, nkeys, now, false); 9147 if (result != ISC_R_SUCCESS) { 9148 dnssec_log(zone, ISC_LOG_ERROR, 9149 "zone_nsec3chain:del_sigs -> %s", 9150 isc_result_totext(result)); 9151 goto cleanup; 9152 } 9153 9154 result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx, 9155 zone->updatemethod); 9156 if (result != ISC_R_SUCCESS) { 9157 dnssec_log(zone, ISC_LOG_ERROR, 9158 "zone_nsec3chain:update_soa_serial -> %s", 9159 isc_result_totext(result)); 9160 goto cleanup; 9161 } 9162 9163 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa, 9164 zonediff.diff, zone_keys, nkeys, zone->mctx, now, 9165 inception, soaexpire); 9166 if (result != ISC_R_SUCCESS) { 9167 dnssec_log(zone, ISC_LOG_ERROR, 9168 "zone_nsec3chain:add_sigs -> %s", 9169 isc_result_totext(result)); 9170 goto cleanup; 9171 } 9172 9173 /* Write changes to journal file. */ 9174 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain")); 9175 9176 LOCK_ZONE(zone); 9177 zone_needdump(zone, DNS_DUMP_DELAY); 9178 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 9179 UNLOCK_ZONE(zone); 9180 9181 closeversion: 9182 /* 9183 * Pause all iterators so that dns_db_closeversion() can succeed. 9184 */ 9185 LOCK_ZONE(zone); 9186 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL; 9187 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 9188 { 9189 dns_dbiterator_pause(nsec3chain->dbiterator); 9190 } 9191 UNLOCK_ZONE(zone); 9192 9193 /* 9194 * Everything has succeeded. Commit the changes. 9195 * Unconditionally commit as zonediff.offline not checked above. 9196 */ 9197 dns_db_closeversion(db, &version, true); 9198 9199 /* 9200 * Everything succeeded so we can clean these up now. 9201 */ 9202 nsec3chain = ISC_LIST_HEAD(cleanup); 9203 while (nsec3chain != NULL) { 9204 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 9205 dns_db_detach(&nsec3chain->db); 9206 dns_dbiterator_destroy(&nsec3chain->dbiterator); 9207 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 9208 nsec3chain = ISC_LIST_HEAD(cleanup); 9209 } 9210 9211 LOCK_ZONE(zone); 9212 set_resigntime(zone); 9213 UNLOCK_ZONE(zone); 9214 9215 cleanup: 9216 if (result != ISC_R_SUCCESS) { 9217 dnssec_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s", 9218 isc_result_totext(result)); 9219 } 9220 9221 /* 9222 * On error roll back the current nsec3chain. 9223 */ 9224 if (result != ISC_R_SUCCESS && nsec3chain != NULL) { 9225 if (nsec3chain->done) { 9226 dns_db_detach(&nsec3chain->db); 9227 dns_dbiterator_destroy(&nsec3chain->dbiterator); 9228 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 9229 } else { 9230 result = dns_dbiterator_first(nsec3chain->dbiterator); 9231 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9232 dns_dbiterator_pause(nsec3chain->dbiterator); 9233 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 9234 } 9235 } 9236 9237 /* 9238 * Rollback the cleanup list. 9239 */ 9240 nsec3chain = ISC_LIST_TAIL(cleanup); 9241 while (nsec3chain != NULL) { 9242 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 9243 if (nsec3chain->done) { 9244 dns_db_detach(&nsec3chain->db); 9245 dns_dbiterator_destroy(&nsec3chain->dbiterator); 9246 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 9247 } else { 9248 LOCK_ZONE(zone); 9249 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link); 9250 UNLOCK_ZONE(zone); 9251 result = dns_dbiterator_first(nsec3chain->dbiterator); 9252 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9253 dns_dbiterator_pause(nsec3chain->dbiterator); 9254 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 9255 } 9256 nsec3chain = ISC_LIST_TAIL(cleanup); 9257 } 9258 9259 LOCK_ZONE(zone); 9260 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL; 9261 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 9262 { 9263 dns_dbiterator_pause(nsec3chain->dbiterator); 9264 } 9265 UNLOCK_ZONE(zone); 9266 9267 dns_diff_clear(¶m_diff); 9268 dns_diff_clear(&nsec3_diff); 9269 dns_diff_clear(&nsec_diff); 9270 dns_diff_clear(&_sig_diff); 9271 9272 if (iterator != NULL) { 9273 dns_rdatasetiter_destroy(&iterator); 9274 } 9275 9276 for (i = 0; i < nkeys; i++) { 9277 dst_key_free(&zone_keys[i]); 9278 } 9279 9280 if (node != NULL) { 9281 dns_db_detachnode(db, &node); 9282 } 9283 if (version != NULL) { 9284 dns_db_closeversion(db, &version, false); 9285 dns_db_detach(&db); 9286 } else if (db != NULL) { 9287 dns_db_detach(&db); 9288 } 9289 9290 LOCK_ZONE(zone); 9291 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) { 9292 isc_interval_t interval; 9293 if (zone->update_disabled || result != ISC_R_SUCCESS) { 9294 isc_interval_set(&interval, 60, 0); /* 1 minute */ 9295 } else { 9296 isc_interval_set(&interval, 0, 10000000); /* 10 ms */ 9297 } 9298 isc_time_nowplusinterval(&zone->nsec3chaintime, &interval); 9299 } else { 9300 isc_time_settoepoch(&zone->nsec3chaintime); 9301 } 9302 UNLOCK_ZONE(zone); 9303 9304 INSIST(version == NULL); 9305 } 9306 9307 /*% 9308 * Delete all RRSIG records with the given algorithm and keyid. 9309 * Remove the NSEC record and RRSIGs if nkeys is zero. 9310 * If all remaining RRsets are signed with the given algorithm 9311 * set *has_algp to true. 9312 */ 9313 static isc_result_t 9314 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 9315 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm, 9316 uint16_t keyid, bool *has_algp, dns_diff_t *diff) { 9317 dns_rdata_rrsig_t rrsig; 9318 dns_rdataset_t rdataset; 9319 dns_rdatasetiter_t *iterator = NULL; 9320 isc_result_t result; 9321 bool alg_missed = false; 9322 bool alg_found = false; 9323 9324 char namebuf[DNS_NAME_FORMATSIZE]; 9325 dns_name_format(name, namebuf, sizeof(namebuf)); 9326 9327 result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator); 9328 if (result != ISC_R_SUCCESS) { 9329 if (result == ISC_R_NOTFOUND) { 9330 result = ISC_R_SUCCESS; 9331 } 9332 return result; 9333 } 9334 9335 dns_rdataset_init(&rdataset); 9336 for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; 9337 result = dns_rdatasetiter_next(iterator)) 9338 { 9339 bool has_alg = false; 9340 dns_rdatasetiter_current(iterator, &rdataset); 9341 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) { 9342 for (result = dns_rdataset_first(&rdataset); 9343 result == ISC_R_SUCCESS; 9344 result = dns_rdataset_next(&rdataset)) 9345 { 9346 dns_rdata_t rdata = DNS_RDATA_INIT; 9347 dns_rdataset_current(&rdataset, &rdata); 9348 CHECK(update_one_rr(db, version, diff, 9349 DNS_DIFFOP_DEL, name, 9350 rdataset.ttl, &rdata)); 9351 } 9352 if (result != ISC_R_NOMORE) { 9353 goto cleanup; 9354 } 9355 dns_rdataset_disassociate(&rdataset); 9356 continue; 9357 } 9358 if (rdataset.type != dns_rdatatype_rrsig) { 9359 dns_rdataset_disassociate(&rdataset); 9360 continue; 9361 } 9362 for (result = dns_rdataset_first(&rdataset); 9363 result == ISC_R_SUCCESS; 9364 result = dns_rdataset_next(&rdataset)) 9365 { 9366 dns_rdata_t rdata = DNS_RDATA_INIT; 9367 dns_rdataset_current(&rdataset, &rdata); 9368 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL)); 9369 if (nkeys != 0 && (rrsig.algorithm != algorithm || 9370 rrsig.keyid != keyid)) 9371 { 9372 if (rrsig.algorithm == algorithm) { 9373 has_alg = true; 9374 } 9375 continue; 9376 } 9377 CHECK(update_one_rr(db, version, diff, 9378 DNS_DIFFOP_DELRESIGN, name, 9379 rdataset.ttl, &rdata)); 9380 } 9381 dns_rdataset_disassociate(&rdataset); 9382 if (result != ISC_R_NOMORE) { 9383 break; 9384 } 9385 9386 /* 9387 * After deleting, if there's still a signature for 9388 * 'algorithm', set alg_found; if not, set alg_missed. 9389 */ 9390 if (has_alg) { 9391 alg_found = true; 9392 } else { 9393 alg_missed = true; 9394 } 9395 } 9396 if (result == ISC_R_NOMORE) { 9397 result = ISC_R_SUCCESS; 9398 } 9399 9400 /* 9401 * Set `has_algp` if the algorithm was found in every RRset: 9402 * i.e., found in at least one, and not missing from any. 9403 */ 9404 *has_algp = (alg_found && !alg_missed); 9405 cleanup: 9406 if (dns_rdataset_isassociated(&rdataset)) { 9407 dns_rdataset_disassociate(&rdataset); 9408 } 9409 dns_rdatasetiter_destroy(&iterator); 9410 return result; 9411 } 9412 9413 /* 9414 * Prevent the zone entering a inconsistent state where 9415 * NSEC only DNSKEYs are present with NSEC3 chains. 9416 */ 9417 bool 9418 dns_zone_check_dnskey_nsec3(dns_zone_t *zone, dns_db_t *db, 9419 dns_dbversion_t *ver, dns_diff_t *diff, 9420 dst_key_t **keys, unsigned int numkeys) { 9421 uint8_t alg; 9422 dns_rdatatype_t privatetype; 9423 ; 9424 bool nseconly = false, nsec3 = false; 9425 isc_result_t result; 9426 9427 REQUIRE(DNS_ZONE_VALID(zone)); 9428 REQUIRE(db != NULL); 9429 9430 privatetype = dns_zone_getprivatetype(zone); 9431 9432 /* Scan the tuples for an NSEC-only DNSKEY */ 9433 if (diff != NULL) { 9434 for (dns_difftuple_t *tuple = ISC_LIST_HEAD(diff->tuples); 9435 tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) 9436 { 9437 if (nseconly && nsec3) { 9438 break; 9439 } 9440 9441 if (tuple->op != DNS_DIFFOP_ADD) { 9442 continue; 9443 } 9444 9445 if (tuple->rdata.type == dns_rdatatype_nsec3param) { 9446 nsec3 = true; 9447 } 9448 9449 if (tuple->rdata.type != dns_rdatatype_dnskey) { 9450 continue; 9451 } 9452 9453 alg = tuple->rdata.data[3]; 9454 if (alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_DSA || 9455 alg == DNS_KEYALG_RSASHA1) 9456 { 9457 nseconly = true; 9458 } 9459 } 9460 } 9461 /* Scan the zone keys for an NSEC-only DNSKEY */ 9462 if (keys != NULL && !nseconly) { 9463 for (unsigned int i = 0; i < numkeys; i++) { 9464 alg = dst_key_alg(keys[i]); 9465 if (alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_DSA || 9466 alg == DNS_KEYALG_RSASHA1) 9467 { 9468 nseconly = true; 9469 break; 9470 } 9471 } 9472 } 9473 9474 /* Check DB for NSEC-only DNSKEY */ 9475 if (!nseconly) { 9476 result = dns_nsec_nseconly(db, ver, diff, &nseconly); 9477 /* 9478 * Adding an NSEC3PARAM record can proceed without a 9479 * DNSKEY (it will trigger a delayed change), so we can 9480 * ignore ISC_R_NOTFOUND here. 9481 */ 9482 if (result == ISC_R_NOTFOUND) { 9483 result = ISC_R_SUCCESS; 9484 } 9485 CHECK(result); 9486 } 9487 9488 /* Check existing DB for NSEC3 */ 9489 if (!nsec3) { 9490 CHECK(dns_nsec3_activex(db, ver, false, privatetype, &nsec3)); 9491 } 9492 9493 /* Check kasp for NSEC3PARAM settings */ 9494 if (!nsec3) { 9495 dns_kasp_t *kasp = zone->kasp; 9496 if (kasp != NULL) { 9497 nsec3 = dns_kasp_nsec3(kasp); 9498 } 9499 } 9500 9501 /* Refuse to allow NSEC3 with NSEC-only keys */ 9502 if (nseconly && nsec3) { 9503 goto cleanup; 9504 } 9505 9506 return true; 9507 9508 cleanup: 9509 return false; 9510 } 9511 9512 /* 9513 * Incrementally sign the zone using the keys requested. 9514 * Builds the NSEC chain if required. 9515 */ 9516 static void 9517 zone_sign(dns_zone_t *zone) { 9518 dns_db_t *db = NULL; 9519 dns_dbnode_t *node = NULL; 9520 dns_dbversion_t *version = NULL; 9521 dns_diff_t _sig_diff; 9522 dns_diff_t post_diff; 9523 dns__zonediff_t zonediff; 9524 dns_fixedname_t fixed; 9525 dns_fixedname_t nextfixed; 9526 dns_kasp_t *kasp; 9527 dns_name_t *name, *nextname; 9528 dns_rdataset_t rdataset; 9529 dns_signing_t *signing, *nextsigning; 9530 dns_signinglist_t cleanup; 9531 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 9532 int32_t signatures; 9533 bool is_ksk, is_zsk; 9534 bool with_ksk, with_zsk; 9535 bool commit = false; 9536 bool is_bottom_of_zone; 9537 bool build_nsec = false; 9538 bool build_nsec3 = false; 9539 bool use_kasp = false; 9540 bool first; 9541 isc_result_t result; 9542 isc_stdtime_t now, inception, soaexpire, expire; 9543 unsigned int i, j; 9544 unsigned int nkeys = 0; 9545 uint32_t nodes; 9546 9547 ENTER; 9548 9549 dns_rdataset_init(&rdataset); 9550 name = dns_fixedname_initname(&fixed); 9551 nextname = dns_fixedname_initname(&nextfixed); 9552 dns_diff_init(zone->mctx, &_sig_diff); 9553 dns_diff_init(zone->mctx, &post_diff); 9554 zonediff_init(&zonediff, &_sig_diff); 9555 ISC_LIST_INIT(cleanup); 9556 9557 /* 9558 * Updates are disabled. Pause for 1 minute. 9559 */ 9560 if (zone->update_disabled) { 9561 result = ISC_R_FAILURE; 9562 goto done; 9563 } 9564 9565 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9566 if (zone->db != NULL) { 9567 dns_db_attach(zone->db, &db); 9568 } 9569 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9570 if (db == NULL) { 9571 result = ISC_R_FAILURE; 9572 goto done; 9573 } 9574 9575 result = dns_db_newversion(db, &version); 9576 if (result != ISC_R_SUCCESS) { 9577 dnssec_log(zone, ISC_LOG_ERROR, 9578 "zone_sign:dns_db_newversion -> %s", 9579 isc_result_totext(result)); 9580 goto done; 9581 } 9582 9583 now = isc_stdtime_now(); 9584 9585 result = dns_zone_findkeys(zone, db, version, now, zone->mctx, 9586 DNS_MAXZONEKEYS, zone_keys, &nkeys); 9587 if (result != ISC_R_SUCCESS) { 9588 dnssec_log(zone, ISC_LOG_ERROR, 9589 "zone_sign:dns_zone_findkeys -> %s", 9590 isc_result_totext(result)); 9591 goto done; 9592 } 9593 9594 kasp = zone->kasp; 9595 9596 calculate_rrsig_validity(zone, now, &inception, &soaexpire, NULL, 9597 &expire); 9598 9599 /* 9600 * We keep pulling nodes off each iterator in turn until 9601 * we have no more nodes to pull off or we reach the limits 9602 * for this quantum. 9603 */ 9604 nodes = zone->nodes; 9605 signatures = zone->signatures; 9606 signing = ISC_LIST_HEAD(zone->signing); 9607 first = true; 9608 9609 if (kasp != NULL) { 9610 use_kasp = true; 9611 } 9612 dnssec_log(zone, ISC_LOG_DEBUG(3), "zone_sign:use kasp -> %s", 9613 use_kasp ? "yes" : "no"); 9614 9615 /* Determine which type of chain to build */ 9616 CHECK(dns_private_chains(db, version, zone->privatetype, &build_nsec, 9617 &build_nsec3)); 9618 if (!build_nsec && !build_nsec3) { 9619 if (use_kasp) { 9620 build_nsec3 = dns_kasp_nsec3(kasp); 9621 if (!dns_zone_check_dnskey_nsec3( 9622 zone, db, version, NULL, 9623 (dst_key_t **)&zone_keys, nkeys)) 9624 { 9625 dnssec_log(zone, ISC_LOG_INFO, 9626 "wait building NSEC3 chain until " 9627 "NSEC only DNSKEYs are removed"); 9628 build_nsec3 = false; 9629 } 9630 build_nsec = !build_nsec3; 9631 } else { 9632 /* If neither chain is found, default to NSEC */ 9633 build_nsec = true; 9634 } 9635 } 9636 9637 while (signing != NULL && nodes-- > 0 && signatures > 0) { 9638 bool has_alg = false; 9639 9640 dns_dbiterator_pause(signing->dbiterator); 9641 nextsigning = ISC_LIST_NEXT(signing, link); 9642 9643 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9644 if (signing->done || signing->db != zone->db) { 9645 /* 9646 * The zone has been reloaded. We will have to 9647 * created new signings as part of the reload 9648 * process so we can destroy this one. 9649 */ 9650 ISC_LIST_UNLINK(zone->signing, signing, link); 9651 ISC_LIST_APPEND(cleanup, signing, link); 9652 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9653 goto next_signing; 9654 } 9655 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9656 9657 if (signing->db != db) { 9658 goto next_signing; 9659 } 9660 9661 is_bottom_of_zone = false; 9662 9663 if (first && signing->deleteit) { 9664 /* 9665 * Remove the key we are deleting from consideration. 9666 */ 9667 for (i = 0, j = 0; i < nkeys; i++) { 9668 /* 9669 * Find the key we want to remove. 9670 */ 9671 if (ALG(zone_keys[i]) == signing->algorithm && 9672 dst_key_id(zone_keys[i]) == signing->keyid) 9673 { 9674 dst_key_free(&zone_keys[i]); 9675 continue; 9676 } 9677 zone_keys[j] = zone_keys[i]; 9678 j++; 9679 } 9680 for (i = j; i < nkeys; i++) { 9681 zone_keys[i] = NULL; 9682 } 9683 nkeys = j; 9684 } 9685 9686 dns_dbiterator_current(signing->dbiterator, &node, name); 9687 9688 if (signing->deleteit) { 9689 dns_dbiterator_pause(signing->dbiterator); 9690 CHECK(del_sig(db, version, name, node, nkeys, 9691 signing->algorithm, signing->keyid, 9692 &has_alg, zonediff.diff)); 9693 } 9694 9695 /* 9696 * On the first pass we need to check if the current node 9697 * has not been obscured. 9698 */ 9699 if (first) { 9700 dns_fixedname_t ffound; 9701 dns_name_t *found; 9702 found = dns_fixedname_initname(&ffound); 9703 result = dns_db_find( 9704 db, name, version, dns_rdatatype_soa, 9705 DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); 9706 if ((result == DNS_R_DELEGATION || 9707 result == DNS_R_DNAME) && 9708 !dns_name_equal(name, found)) 9709 { 9710 /* 9711 * Remember the obscuring name so that 9712 * we skip all obscured names. 9713 */ 9714 dns_name_copy(found, name); 9715 is_bottom_of_zone = true; 9716 goto next_node; 9717 } 9718 } 9719 9720 /* 9721 * Process one node. 9722 */ 9723 with_ksk = false; 9724 with_zsk = false; 9725 dns_dbiterator_pause(signing->dbiterator); 9726 9727 CHECK(check_if_bottom_of_zone(db, node, version, 9728 &is_bottom_of_zone)); 9729 9730 for (i = 0; !has_alg && i < nkeys; i++) { 9731 bool both = false; 9732 /* 9733 * Find the keys we want to sign with. 9734 */ 9735 if (!dst_key_isprivate(zone_keys[i])) { 9736 continue; 9737 } 9738 if (dst_key_inactive(zone_keys[i])) { 9739 continue; 9740 } 9741 9742 /* 9743 * When adding look for the specific key. 9744 */ 9745 if (!signing->deleteit && 9746 (dst_key_alg(zone_keys[i]) != signing->algorithm || 9747 dst_key_id(zone_keys[i]) != signing->keyid)) 9748 { 9749 continue; 9750 } 9751 9752 /* 9753 * When deleting make sure we are properly signed 9754 * with the algorithm that was being removed. 9755 */ 9756 if (signing->deleteit && 9757 ALG(zone_keys[i]) != signing->algorithm) 9758 { 9759 continue; 9760 } 9761 9762 /* 9763 * We do KSK processing. 9764 */ 9765 if (use_kasp) { 9766 /* 9767 * A dnssec-policy is found. Check what 9768 * RRsets this key can sign. 9769 */ 9770 isc_result_t kresult; 9771 is_ksk = false; 9772 kresult = dst_key_getbool( 9773 zone_keys[i], DST_BOOL_KSK, &is_ksk); 9774 if (kresult != ISC_R_SUCCESS) { 9775 if (KSK(zone_keys[i])) { 9776 is_ksk = true; 9777 } 9778 } 9779 9780 is_zsk = false; 9781 kresult = dst_key_getbool( 9782 zone_keys[i], DST_BOOL_ZSK, &is_zsk); 9783 if (kresult != ISC_R_SUCCESS) { 9784 if (!KSK(zone_keys[i])) { 9785 is_zsk = true; 9786 } 9787 } 9788 both = true; 9789 } else { 9790 is_ksk = KSK(zone_keys[i]); 9791 is_zsk = !is_ksk; 9792 9793 /* 9794 * Don't consider inactive keys, however the key 9795 * may be temporary offline, so do consider KSKs 9796 * which private key files are unavailable. 9797 */ 9798 both = dst_key_have_ksk_and_zsk( 9799 zone_keys, nkeys, i, false, is_ksk, 9800 is_zsk, NULL, NULL); 9801 if (both || REVOKE(zone_keys[i])) { 9802 is_ksk = KSK(zone_keys[i]); 9803 is_zsk = !KSK(zone_keys[i]); 9804 } else { 9805 is_ksk = false; 9806 is_zsk = false; 9807 } 9808 } 9809 9810 /* 9811 * If deleting signatures, we need to ensure that 9812 * the RRset is still signed at least once by a 9813 * KSK and a ZSK. 9814 */ 9815 if (signing->deleteit && is_zsk && with_zsk) { 9816 continue; 9817 } 9818 9819 if (signing->deleteit && is_ksk && with_ksk) { 9820 continue; 9821 } 9822 9823 CHECK(sign_a_node( 9824 db, zone, name, node, version, build_nsec3, 9825 build_nsec, zone_keys[i], now, inception, 9826 expire, zone_nsecttl(zone), both, is_ksk, 9827 is_zsk, signing->fullsign, is_bottom_of_zone, 9828 zonediff.diff, &signatures, zone->mctx)); 9829 /* 9830 * If we are adding we are done. Look for other keys 9831 * of the same algorithm if deleting. 9832 */ 9833 if (!signing->deleteit) { 9834 break; 9835 } 9836 if (is_zsk) { 9837 with_zsk = true; 9838 } 9839 if (is_ksk) { 9840 with_ksk = true; 9841 } 9842 } 9843 9844 /* 9845 * Go onto next node. 9846 */ 9847 next_node: 9848 first = false; 9849 dns_db_detachnode(db, &node); 9850 do { 9851 result = dns_dbiterator_next(signing->dbiterator); 9852 if (result == ISC_R_NOMORE) { 9853 ISC_LIST_UNLINK(zone->signing, signing, link); 9854 ISC_LIST_APPEND(cleanup, signing, link); 9855 dns_dbiterator_pause(signing->dbiterator); 9856 if (nkeys != 0 && build_nsec) { 9857 /* 9858 * We have finished regenerating the 9859 * zone with a zone signing key. 9860 * The NSEC chain is now complete and 9861 * there is a full set of signatures 9862 * for the zone. We can now clear the 9863 * OPT bit from the NSEC record. 9864 */ 9865 result = updatesecure( 9866 db, version, &zone->origin, 9867 zone_nsecttl(zone), false, 9868 &post_diff); 9869 if (result != ISC_R_SUCCESS) { 9870 dnssec_log(zone, ISC_LOG_ERROR, 9871 "updatesecure -> %s", 9872 isc_result_totext( 9873 result)); 9874 goto done; 9875 } 9876 } 9877 result = updatesignwithkey( 9878 zone, signing, version, build_nsec3, 9879 zone_nsecttl(zone), &post_diff); 9880 if (result != ISC_R_SUCCESS) { 9881 dnssec_log(zone, ISC_LOG_ERROR, 9882 "updatesignwithkey -> %s", 9883 isc_result_totext(result)); 9884 goto done; 9885 } 9886 build_nsec = false; 9887 goto next_signing; 9888 } else if (result != ISC_R_SUCCESS) { 9889 dnssec_log(zone, ISC_LOG_ERROR, 9890 "zone_sign:" 9891 "dns_dbiterator_next -> %s", 9892 isc_result_totext(result)); 9893 goto done; 9894 } else if (is_bottom_of_zone) { 9895 dns_dbiterator_current(signing->dbiterator, 9896 &node, nextname); 9897 dns_db_detachnode(db, &node); 9898 if (!dns_name_issubdomain(nextname, name)) { 9899 break; 9900 } 9901 } else { 9902 break; 9903 } 9904 } while (1); 9905 continue; 9906 9907 next_signing: 9908 dns_dbiterator_pause(signing->dbiterator); 9909 signing = nextsigning; 9910 first = true; 9911 } 9912 9913 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) { 9914 result = dns__zone_updatesigs(&post_diff, db, version, 9915 zone_keys, nkeys, zone, inception, 9916 expire, 0, now, &zonediff); 9917 if (result != ISC_R_SUCCESS) { 9918 dnssec_log(zone, ISC_LOG_ERROR, 9919 "zone_sign:dns__zone_updatesigs -> %s", 9920 isc_result_totext(result)); 9921 goto done; 9922 } 9923 } 9924 9925 /* 9926 * Have we changed anything? 9927 */ 9928 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 9929 if (zonediff.offline) { 9930 commit = true; 9931 } 9932 result = ISC_R_SUCCESS; 9933 goto pauseall; 9934 } 9935 9936 commit = true; 9937 9938 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 9939 &zonediff, zone_keys, nkeys, now, false); 9940 if (result != ISC_R_SUCCESS) { 9941 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:del_sigs -> %s", 9942 isc_result_totext(result)); 9943 goto done; 9944 } 9945 9946 result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx, 9947 zone->updatemethod); 9948 if (result != ISC_R_SUCCESS) { 9949 dnssec_log(zone, ISC_LOG_ERROR, 9950 "zone_sign:update_soa_serial -> %s", 9951 isc_result_totext(result)); 9952 goto done; 9953 } 9954 9955 /* 9956 * Generate maximum life time signatures so that the above loop 9957 * termination is sensible. 9958 */ 9959 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa, 9960 zonediff.diff, zone_keys, nkeys, zone->mctx, now, 9961 inception, soaexpire); 9962 if (result != ISC_R_SUCCESS) { 9963 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:add_sigs -> %s", 9964 isc_result_totext(result)); 9965 goto done; 9966 } 9967 9968 /* 9969 * Write changes to journal file. 9970 */ 9971 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign")); 9972 9973 pauseall: 9974 /* 9975 * Pause all iterators so that dns_db_closeversion() can succeed. 9976 */ 9977 for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; 9978 signing = ISC_LIST_NEXT(signing, link)) 9979 { 9980 dns_dbiterator_pause(signing->dbiterator); 9981 } 9982 9983 for (signing = ISC_LIST_HEAD(cleanup); signing != NULL; 9984 signing = ISC_LIST_NEXT(signing, link)) 9985 { 9986 dns_dbiterator_pause(signing->dbiterator); 9987 } 9988 9989 /* 9990 * Everything has succeeded. Commit the changes. 9991 */ 9992 dns_db_closeversion(db, &version, commit); 9993 9994 /* 9995 * Everything succeeded so we can clean these up now. 9996 */ 9997 signing = ISC_LIST_HEAD(cleanup); 9998 while (signing != NULL) { 9999 ISC_LIST_UNLINK(cleanup, signing, link); 10000 dns_db_detach(&signing->db); 10001 dns_dbiterator_destroy(&signing->dbiterator); 10002 isc_mem_put(zone->mctx, signing, sizeof *signing); 10003 signing = ISC_LIST_HEAD(cleanup); 10004 } 10005 10006 LOCK_ZONE(zone); 10007 set_resigntime(zone); 10008 if (commit) { 10009 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 10010 zone_needdump(zone, DNS_DUMP_DELAY); 10011 } 10012 UNLOCK_ZONE(zone); 10013 10014 cleanup: 10015 if (result != ISC_R_SUCCESS) { 10016 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign: failed: %s", 10017 isc_result_totext(result)); 10018 } 10019 10020 done: 10021 /* 10022 * Pause all dbiterators. 10023 */ 10024 for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; 10025 signing = ISC_LIST_NEXT(signing, link)) 10026 { 10027 dns_dbiterator_pause(signing->dbiterator); 10028 } 10029 10030 /* 10031 * Rollback the cleanup list. 10032 */ 10033 signing = ISC_LIST_HEAD(cleanup); 10034 while (signing != NULL) { 10035 ISC_LIST_UNLINK(cleanup, signing, link); 10036 ISC_LIST_PREPEND(zone->signing, signing, link); 10037 dns_dbiterator_first(signing->dbiterator); 10038 dns_dbiterator_pause(signing->dbiterator); 10039 signing = ISC_LIST_HEAD(cleanup); 10040 } 10041 10042 dns_diff_clear(&_sig_diff); 10043 dns_diff_clear(&post_diff); 10044 10045 for (i = 0; i < nkeys; i++) { 10046 dst_key_free(&zone_keys[i]); 10047 } 10048 10049 if (node != NULL) { 10050 dns_db_detachnode(db, &node); 10051 } 10052 10053 if (version != NULL) { 10054 dns_db_closeversion(db, &version, false); 10055 dns_db_detach(&db); 10056 } else if (db != NULL) { 10057 dns_db_detach(&db); 10058 } 10059 10060 LOCK_ZONE(zone); 10061 if (ISC_LIST_HEAD(zone->signing) != NULL) { 10062 isc_interval_t interval; 10063 if (zone->update_disabled || result != ISC_R_SUCCESS) { 10064 isc_interval_set(&interval, 60, 0); /* 1 minute */ 10065 } else { 10066 isc_interval_set(&interval, 0, 10000000); /* 10 ms */ 10067 } 10068 isc_time_nowplusinterval(&zone->signingtime, &interval); 10069 } else { 10070 isc_time_settoepoch(&zone->signingtime); 10071 } 10072 UNLOCK_ZONE(zone); 10073 10074 INSIST(version == NULL); 10075 } 10076 10077 static isc_result_t 10078 normalize_key(dns_rdata_t *rr, dns_rdata_t *target, unsigned char *data, 10079 int size) { 10080 dns_rdata_dnskey_t dnskey; 10081 dns_rdata_keydata_t keydata; 10082 isc_buffer_t buf; 10083 isc_result_t result; 10084 10085 dns_rdata_reset(target); 10086 isc_buffer_init(&buf, data, size); 10087 10088 switch (rr->type) { 10089 case dns_rdatatype_dnskey: 10090 result = dns_rdata_tostruct(rr, &dnskey, NULL); 10091 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10092 dnskey.flags &= ~DNS_KEYFLAG_REVOKE; 10093 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 10094 &dnskey, &buf); 10095 break; 10096 case dns_rdatatype_keydata: 10097 result = dns_rdata_tostruct(rr, &keydata, NULL); 10098 if (result == ISC_R_UNEXPECTEDEND) { 10099 return result; 10100 } 10101 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10102 dns_keydata_todnskey(&keydata, &dnskey, NULL); 10103 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 10104 &dnskey, &buf); 10105 break; 10106 default: 10107 UNREACHABLE(); 10108 } 10109 return ISC_R_SUCCESS; 10110 } 10111 10112 /* 10113 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or 10114 * a KEYDATA rdataset from the key zone. 10115 * 10116 * 'rr' contains either a DNSKEY record, or a KEYDATA record 10117 * 10118 * After normalizing keys to the same format (DNSKEY, with revoke bit 10119 * cleared), return true if a key that matches 'rr' is found in 10120 * 'rdset', or false if not. 10121 */ 10122 10123 static bool 10124 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) { 10125 unsigned char data1[4096], data2[4096]; 10126 dns_rdata_t rdata, rdata1, rdata2; 10127 isc_result_t result; 10128 10129 dns_rdata_init(&rdata); 10130 dns_rdata_init(&rdata1); 10131 dns_rdata_init(&rdata2); 10132 10133 result = normalize_key(rr, &rdata1, data1, sizeof(data1)); 10134 if (result != ISC_R_SUCCESS) { 10135 return false; 10136 } 10137 10138 for (result = dns_rdataset_first(rdset); result == ISC_R_SUCCESS; 10139 result = dns_rdataset_next(rdset)) 10140 { 10141 dns_rdata_reset(&rdata); 10142 dns_rdataset_current(rdset, &rdata); 10143 result = normalize_key(&rdata, &rdata2, data2, sizeof(data2)); 10144 if (result != ISC_R_SUCCESS) { 10145 continue; 10146 } 10147 if (dns_rdata_compare(&rdata1, &rdata2) == 0) { 10148 return true; 10149 } 10150 } 10151 10152 return false; 10153 } 10154 10155 /* 10156 * Calculate the refresh interval for a keydata zone, per 10157 * RFC5011: MAX(1 hr, 10158 * MIN(15 days, 10159 * 1/2 * OrigTTL, 10160 * 1/2 * RRSigExpirationInterval)) 10161 * or for retries: MAX(1 hr, 10162 * MIN(1 day, 10163 * 1/10 * OrigTTL, 10164 * 1/10 * RRSigExpirationInterval)) 10165 */ 10166 static isc_stdtime_t 10167 refresh_time(dns_keyfetch_t *kfetch, bool retry) { 10168 isc_result_t result; 10169 uint32_t t; 10170 dns_rdataset_t *rdset; 10171 dns_rdata_t sigrr = DNS_RDATA_INIT; 10172 dns_rdata_sig_t sig; 10173 isc_stdtime_t now = isc_stdtime_now(); 10174 10175 if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) { 10176 rdset = &kfetch->dnskeysigset; 10177 } else { 10178 return now + dns_zone_mkey_hour; 10179 } 10180 10181 result = dns_rdataset_first(rdset); 10182 if (result != ISC_R_SUCCESS) { 10183 return now + dns_zone_mkey_hour; 10184 } 10185 10186 dns_rdataset_current(rdset, &sigrr); 10187 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 10188 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10189 10190 if (!retry) { 10191 t = sig.originalttl / 2; 10192 10193 if (isc_serial_gt(sig.timeexpire, now)) { 10194 uint32_t exp = (sig.timeexpire - now) / 2; 10195 if (t > exp) { 10196 t = exp; 10197 } 10198 } 10199 10200 if (t > (15 * dns_zone_mkey_day)) { 10201 t = (15 * dns_zone_mkey_day); 10202 } 10203 10204 if (t < dns_zone_mkey_hour) { 10205 t = dns_zone_mkey_hour; 10206 } 10207 } else { 10208 t = sig.originalttl / 10; 10209 10210 if (isc_serial_gt(sig.timeexpire, now)) { 10211 uint32_t exp = (sig.timeexpire - now) / 10; 10212 if (t > exp) { 10213 t = exp; 10214 } 10215 } 10216 10217 if (t > dns_zone_mkey_day) { 10218 t = dns_zone_mkey_day; 10219 } 10220 10221 if (t < dns_zone_mkey_hour) { 10222 t = dns_zone_mkey_hour; 10223 } 10224 } 10225 10226 return now + t; 10227 } 10228 10229 /* 10230 * This routine is called when no changes are needed in a KEYDATA 10231 * record except to simply update the refresh timer. Caller should 10232 * hold zone lock. 10233 */ 10234 static isc_result_t 10235 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) { 10236 isc_result_t result; 10237 isc_buffer_t keyb; 10238 unsigned char key_buf[4096]; 10239 dns_rdata_t rdata = DNS_RDATA_INIT; 10240 dns_rdata_keydata_t keydata; 10241 dns_name_t *name; 10242 dns_zone_t *zone = kfetch->zone; 10243 isc_stdtime_t now = isc_stdtime_now(); 10244 10245 name = dns_fixedname_name(&kfetch->name); 10246 10247 for (result = dns_rdataset_first(&kfetch->keydataset); 10248 result == ISC_R_SUCCESS; 10249 result = dns_rdataset_next(&kfetch->keydataset)) 10250 { 10251 dns_rdata_reset(&rdata); 10252 dns_rdataset_current(&kfetch->keydataset, &rdata); 10253 10254 /* Delete old version */ 10255 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL, name, 10256 0, &rdata)); 10257 10258 /* Update refresh timer */ 10259 result = dns_rdata_tostruct(&rdata, &keydata, NULL); 10260 if (result == ISC_R_UNEXPECTEDEND) { 10261 continue; 10262 } 10263 CHECK(result); 10264 10265 keydata.refresh = refresh_time(kfetch, true); 10266 set_refreshkeytimer(zone, &keydata, now, false); 10267 10268 dns_rdata_reset(&rdata); 10269 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10270 CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass, 10271 dns_rdatatype_keydata, &keydata, 10272 &keyb)); 10273 10274 /* Insert updated version */ 10275 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD, name, 10276 0, &rdata)); 10277 } 10278 result = ISC_R_SUCCESS; 10279 cleanup: 10280 return result; 10281 } 10282 10283 /* 10284 * Verify that DNSKEY set is signed by the key specified in 'keydata'. 10285 */ 10286 static bool 10287 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) { 10288 isc_result_t result; 10289 dns_name_t *keyname; 10290 isc_mem_t *mctx; 10291 dns_rdata_t sigrr = DNS_RDATA_INIT; 10292 dns_rdata_t rr = DNS_RDATA_INIT; 10293 dns_rdata_rrsig_t sig; 10294 dns_rdata_dnskey_t dnskey; 10295 dst_key_t *dstkey = NULL; 10296 unsigned char key_buf[4096]; 10297 isc_buffer_t keyb; 10298 bool answer = false; 10299 10300 REQUIRE(kfetch != NULL && keydata != NULL); 10301 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset)); 10302 10303 keyname = dns_fixedname_name(&kfetch->name); 10304 mctx = kfetch->zone->view->mctx; 10305 10306 /* Generate a key from keydata */ 10307 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10308 dns_keydata_todnskey(keydata, &dnskey, NULL); 10309 dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey, 10310 &dnskey, &keyb); 10311 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey); 10312 if (result != ISC_R_SUCCESS) { 10313 return false; 10314 } 10315 10316 /* See if that key generated any of the signatures */ 10317 for (result = dns_rdataset_first(&kfetch->dnskeysigset); 10318 result == ISC_R_SUCCESS; 10319 result = dns_rdataset_next(&kfetch->dnskeysigset)) 10320 { 10321 dns_fixedname_t fixed; 10322 dns_fixedname_init(&fixed); 10323 10324 dns_rdata_reset(&sigrr); 10325 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr); 10326 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 10327 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10328 10329 if (dst_key_alg(dstkey) == sig.algorithm && 10330 dst_key_rid(dstkey) == sig.keyid) 10331 { 10332 result = dns_dnssec_verify( 10333 keyname, &kfetch->dnskeyset, dstkey, false, 0, 10334 mctx, &sigrr, dns_fixedname_name(&fixed)); 10335 10336 dnssec_log(kfetch->zone, ISC_LOG_DEBUG(3), 10337 "Confirm revoked DNSKEY is self-signed: %s", 10338 isc_result_totext(result)); 10339 10340 if (result == ISC_R_SUCCESS) { 10341 answer = true; 10342 break; 10343 } 10344 } 10345 } 10346 10347 dst_key_free(&dstkey); 10348 return answer; 10349 } 10350 10351 /* 10352 * A DNSKEY set has been fetched from the zone apex of a zone whose trust 10353 * anchors are being managed; scan the keyset, and update the key zone and the 10354 * local trust anchors according to RFC5011. 10355 */ 10356 static void 10357 keyfetch_done(void *arg) { 10358 dns_fetchresponse_t *resp = (dns_fetchresponse_t *)arg; 10359 isc_result_t result, eresult; 10360 dns_keyfetch_t *kfetch = NULL; 10361 dns_zone_t *zone = NULL; 10362 isc_mem_t *mctx = NULL; 10363 dns_keytable_t *secroots = NULL; 10364 dns_dbversion_t *ver = NULL; 10365 dns_diff_t diff; 10366 bool alldone = false; 10367 bool commit = false; 10368 dns_name_t *keyname = NULL; 10369 dns_rdata_t sigrr = DNS_RDATA_INIT; 10370 dns_rdata_t dnskeyrr = DNS_RDATA_INIT; 10371 dns_rdata_t keydatarr = DNS_RDATA_INIT; 10372 dns_rdata_rrsig_t sig; 10373 dns_rdata_dnskey_t dnskey; 10374 dns_rdata_keydata_t keydata; 10375 bool initializing; 10376 char namebuf[DNS_NAME_FORMATSIZE]; 10377 unsigned char key_buf[4096]; 10378 isc_buffer_t keyb; 10379 dst_key_t *dstkey = NULL; 10380 isc_stdtime_t now; 10381 int pending = 0; 10382 bool secure = false, initial = false; 10383 bool free_needed; 10384 dns_keynode_t *keynode = NULL; 10385 dns_rdataset_t *dnskeys = NULL, *dnskeysigs = NULL; 10386 dns_rdataset_t *keydataset = NULL, dsset; 10387 10388 INSIST(resp != NULL); 10389 10390 kfetch = resp->arg; 10391 10392 INSIST(kfetch != NULL); 10393 10394 zone = kfetch->zone; 10395 mctx = kfetch->mctx; 10396 keyname = dns_fixedname_name(&kfetch->name); 10397 dnskeys = &kfetch->dnskeyset; 10398 dnskeysigs = &kfetch->dnskeysigset; 10399 keydataset = &kfetch->keydataset; 10400 10401 eresult = resp->result; 10402 10403 /* Free resources which are not of interest */ 10404 if (resp->node != NULL) { 10405 dns_db_detachnode(resp->db, &resp->node); 10406 } 10407 if (resp->db != NULL) { 10408 dns_db_detach(&resp->db); 10409 } 10410 10411 dns_resolver_destroyfetch(&kfetch->fetch); 10412 10413 LOCK_ZONE(zone); 10414 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) { 10415 goto out; 10416 } 10417 10418 now = isc_stdtime_now(); 10419 dns_name_format(keyname, namebuf, sizeof(namebuf)); 10420 10421 result = dns_view_getsecroots(zone->view, &secroots); 10422 INSIST(result == ISC_R_SUCCESS); 10423 10424 dns_diff_init(mctx, &diff); 10425 10426 CHECK(dns_db_newversion(kfetch->db, &ver)); 10427 10428 zone->refreshkeycount--; 10429 alldone = (zone->refreshkeycount == 0); 10430 10431 if (alldone) { 10432 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 10433 } 10434 10435 dnssec_log(zone, ISC_LOG_DEBUG(3), 10436 "Returned from key fetch in keyfetch_done() for '%s': %s", 10437 namebuf, isc_result_totext(eresult)); 10438 10439 /* Fetch failed */ 10440 if (eresult != ISC_R_SUCCESS || !dns_rdataset_isassociated(dnskeys)) { 10441 dnssec_log(zone, ISC_LOG_WARNING, 10442 "Unable to fetch DNSKEY set '%s': %s", namebuf, 10443 isc_result_totext(eresult)); 10444 CHECK(minimal_update(kfetch, ver, &diff)); 10445 goto done; 10446 } 10447 10448 /* No RRSIGs found */ 10449 if (!dns_rdataset_isassociated(dnskeysigs)) { 10450 dnssec_log(zone, ISC_LOG_WARNING, 10451 "No DNSKEY RRSIGs found for '%s': %s", namebuf, 10452 isc_result_totext(eresult)); 10453 CHECK(minimal_update(kfetch, ver, &diff)); 10454 goto done; 10455 } 10456 10457 /* 10458 * Clear any cached trust level, as we need to run validation 10459 * over again; trusted keys might have changed. 10460 */ 10461 dnskeys->trust = dnskeysigs->trust = dns_trust_none; 10462 10463 /* Look up the trust anchor */ 10464 result = dns_keytable_find(secroots, keyname, &keynode); 10465 if (result != ISC_R_SUCCESS) { 10466 goto anchors_done; 10467 } 10468 10469 /* 10470 * If the keynode has a DS trust anchor, use it for verification. 10471 */ 10472 dns_rdataset_init(&dsset); 10473 if (dns_keynode_dsset(keynode, &dsset)) { 10474 for (result = dns_rdataset_first(dnskeysigs); 10475 result == ISC_R_SUCCESS; 10476 result = dns_rdataset_next(dnskeysigs)) 10477 { 10478 isc_result_t tresult; 10479 dns_rdata_t keyrdata = DNS_RDATA_INIT; 10480 10481 dns_rdata_reset(&sigrr); 10482 dns_rdataset_current(dnskeysigs, &sigrr); 10483 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 10484 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10485 10486 for (tresult = dns_rdataset_first(&dsset); 10487 tresult == ISC_R_SUCCESS; 10488 tresult = dns_rdataset_next(&dsset)) 10489 { 10490 dns_rdata_t dsrdata = DNS_RDATA_INIT; 10491 dns_rdata_ds_t ds; 10492 10493 dns_rdata_reset(&dsrdata); 10494 dns_rdataset_current(&dsset, &dsrdata); 10495 tresult = dns_rdata_tostruct(&dsrdata, &ds, 10496 NULL); 10497 RUNTIME_CHECK(tresult == ISC_R_SUCCESS); 10498 10499 if (ds.key_tag != sig.keyid || 10500 ds.algorithm != sig.algorithm) 10501 { 10502 continue; 10503 } 10504 10505 result = dns_dnssec_matchdskey( 10506 keyname, &dsrdata, dnskeys, &keyrdata); 10507 if (result == ISC_R_SUCCESS) { 10508 break; 10509 } 10510 } 10511 10512 if (tresult == ISC_R_NOMORE) { 10513 continue; 10514 } 10515 10516 result = dns_dnssec_keyfromrdata(keyname, &keyrdata, 10517 mctx, &dstkey); 10518 if (result != ISC_R_SUCCESS) { 10519 continue; 10520 } 10521 10522 result = dns_dnssec_verify(keyname, dnskeys, dstkey, 10523 false, 0, mctx, &sigrr, 10524 NULL); 10525 dst_key_free(&dstkey); 10526 10527 dnssec_log(zone, ISC_LOG_DEBUG(3), 10528 "Verifying DNSKEY set for zone " 10529 "'%s' using DS %d/%d: %s", 10530 namebuf, sig.keyid, sig.algorithm, 10531 isc_result_totext(result)); 10532 10533 if (result == ISC_R_SUCCESS) { 10534 dnskeys->trust = dns_trust_secure; 10535 dnskeysigs->trust = dns_trust_secure; 10536 initial = dns_keynode_initial(keynode); 10537 dns_keynode_trust(keynode); 10538 secure = true; 10539 break; 10540 } 10541 } 10542 dns_rdataset_disassociate(&dsset); 10543 } 10544 10545 anchors_done: 10546 if (keynode != NULL) { 10547 dns_keynode_detach(&keynode); 10548 } 10549 10550 /* 10551 * If we were not able to verify the answer using the current 10552 * trusted keys then all we can do is look at any revoked keys. 10553 */ 10554 if (!secure) { 10555 dnssec_log(zone, ISC_LOG_INFO, 10556 "DNSKEY set for zone '%s' could not be verified " 10557 "with current keys", 10558 namebuf); 10559 } 10560 10561 /* 10562 * First scan keydataset to find keys that are not in dnskeyset 10563 * - Missing keys which are not scheduled for removal, 10564 * log a warning 10565 * - Missing keys which are scheduled for removal and 10566 * the remove hold-down timer has completed should 10567 * be removed from the key zone 10568 * - Missing keys whose acceptance timers have not yet 10569 * completed, log a warning and reset the acceptance 10570 * timer to 30 days in the future 10571 * - All keys not being removed have their refresh timers 10572 * updated 10573 */ 10574 initializing = true; 10575 for (result = dns_rdataset_first(keydataset); result == ISC_R_SUCCESS; 10576 result = dns_rdataset_next(keydataset)) 10577 { 10578 dns_keytag_t keytag; 10579 10580 dns_rdata_reset(&keydatarr); 10581 dns_rdataset_current(keydataset, &keydatarr); 10582 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); 10583 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10584 10585 dns_keydata_todnskey(&keydata, &dnskey, NULL); 10586 result = compute_tag(keyname, &dnskey, mctx, &keytag); 10587 if (result != ISC_R_SUCCESS) { 10588 /* 10589 * Skip if we cannot compute the key tag. 10590 * This may happen if the algorithm is unsupported 10591 */ 10592 dns_zone_log(zone, ISC_LOG_ERROR, 10593 "Cannot compute tag for key in zone %s: " 10594 "%s " 10595 "(skipping)", 10596 namebuf, isc_result_totext(result)); 10597 continue; 10598 } 10599 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10600 10601 /* 10602 * If any keydata record has a nonzero add holddown, then 10603 * there was a pre-existing trust anchor for this domain; 10604 * that means we are *not* initializing it and shouldn't 10605 * automatically trust all the keys we find at the zone apex. 10606 */ 10607 initializing = initializing && (keydata.addhd == 0); 10608 10609 if (!matchkey(dnskeys, &keydatarr)) { 10610 bool deletekey = false; 10611 10612 if (!secure) { 10613 if (keydata.removehd != 0 && 10614 keydata.removehd <= now) 10615 { 10616 deletekey = true; 10617 } 10618 } else if (keydata.addhd == 0) { 10619 deletekey = true; 10620 } else if (keydata.addhd > now) { 10621 dnssec_log(zone, ISC_LOG_INFO, 10622 "Pending key %d for zone %s " 10623 "unexpectedly missing from DNSKEY " 10624 "RRset: restarting 30-day " 10625 "acceptance timer", 10626 keytag, namebuf); 10627 if (keydata.addhd < now + dns_zone_mkey_month) { 10628 keydata.addhd = now + 10629 dns_zone_mkey_month; 10630 } 10631 keydata.refresh = refresh_time(kfetch, false); 10632 } else if (keydata.removehd == 0) { 10633 dnssec_log(zone, ISC_LOG_INFO, 10634 "Active key %d for zone %s " 10635 "unexpectedly missing from DNSKEY " 10636 "RRset", 10637 keytag, namebuf); 10638 keydata.refresh = now + dns_zone_mkey_hour; 10639 } else if (keydata.removehd <= now) { 10640 deletekey = true; 10641 dnssec_log( 10642 zone, ISC_LOG_INFO, 10643 "Revoked key %d for zone %s no longer " 10644 "present in DNSKEY RRset: deleting " 10645 "from managed keys database", 10646 keytag, namebuf); 10647 } else { 10648 keydata.refresh = refresh_time(kfetch, false); 10649 } 10650 10651 if (secure || deletekey) { 10652 /* Delete old version */ 10653 CHECK(update_one_rr(kfetch->db, ver, &diff, 10654 DNS_DIFFOP_DEL, keyname, 0, 10655 &keydatarr)); 10656 } 10657 10658 if (!secure || deletekey) { 10659 continue; 10660 } 10661 10662 dns_rdata_reset(&keydatarr); 10663 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10664 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 10665 dns_rdatatype_keydata, &keydata, 10666 &keyb); 10667 10668 /* Insert updated version */ 10669 CHECK(update_one_rr(kfetch->db, ver, &diff, 10670 DNS_DIFFOP_ADD, keyname, 0, 10671 &keydatarr)); 10672 10673 set_refreshkeytimer(zone, &keydata, now, false); 10674 } 10675 } 10676 10677 /* 10678 * Next scan dnskeyset: 10679 * - If new keys are found (i.e., lacking a match in keydataset) 10680 * add them to the key zone and set the acceptance timer 10681 * to 30 days in the future (or to immediately if we've 10682 * determined that we're initializing the zone for the 10683 * first time) 10684 * - Previously-known keys that have been revoked 10685 * must be scheduled for removal from the key zone (or, 10686 * if they hadn't been accepted as trust anchors yet 10687 * anyway, removed at once) 10688 * - Previously-known unrevoked keys whose acceptance timers 10689 * have completed are promoted to trust anchors 10690 * - All keys not being removed have their refresh 10691 * timers updated 10692 */ 10693 for (result = dns_rdataset_first(dnskeys); result == ISC_R_SUCCESS; 10694 result = dns_rdataset_next(dnskeys)) 10695 { 10696 bool revoked = false; 10697 bool newkey = false; 10698 bool updatekey = false; 10699 bool deletekey = false; 10700 bool trustkey = false; 10701 dns_keytag_t keytag; 10702 10703 dns_rdata_reset(&dnskeyrr); 10704 dns_rdataset_current(dnskeys, &dnskeyrr); 10705 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 10706 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10707 10708 /* Skip ZSK's */ 10709 if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) { 10710 continue; 10711 } 10712 10713 result = compute_tag(keyname, &dnskey, mctx, &keytag); 10714 if (result != ISC_R_SUCCESS) { 10715 /* 10716 * Skip if we cannot compute the key tag. 10717 * This may happen if the algorithm is unsupported 10718 */ 10719 dns_zone_log(zone, ISC_LOG_ERROR, 10720 "Cannot compute tag for key in zone %s: " 10721 "%s " 10722 "(skipping)", 10723 namebuf, isc_result_totext(result)); 10724 continue; 10725 } 10726 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10727 10728 revoked = ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0); 10729 10730 if (matchkey(keydataset, &dnskeyrr)) { 10731 dns_rdata_reset(&keydatarr); 10732 dns_rdataset_current(keydataset, &keydatarr); 10733 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); 10734 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10735 10736 if (revoked && revocable(kfetch, &keydata)) { 10737 if (keydata.addhd > now) { 10738 /* 10739 * Key wasn't trusted yet, and now 10740 * it's been revoked? Just remove it 10741 */ 10742 deletekey = true; 10743 dnssec_log(zone, ISC_LOG_INFO, 10744 "Pending key %d for " 10745 "zone %s is now revoked: " 10746 "deleting from the " 10747 "managed keys database", 10748 keytag, namebuf); 10749 } else if (keydata.removehd == 0) { 10750 /* 10751 * Remove key from secroots. 10752 */ 10753 dns_view_untrust(zone->view, keyname, 10754 &dnskey); 10755 10756 /* If initializing, delete now */ 10757 if (keydata.addhd == 0) { 10758 deletekey = true; 10759 } else { 10760 keydata.removehd = 10761 now + 10762 dns_zone_mkey_month; 10763 keydata.flags |= 10764 DNS_KEYFLAG_REVOKE; 10765 } 10766 10767 dnssec_log(zone, ISC_LOG_INFO, 10768 "Trusted key %d for " 10769 "zone %s is now revoked", 10770 keytag, namebuf); 10771 } else if (keydata.removehd < now) { 10772 /* Scheduled for removal */ 10773 deletekey = true; 10774 10775 dnssec_log(zone, ISC_LOG_INFO, 10776 "Revoked key %d for " 10777 "zone %s removal timer " 10778 "complete: deleting from " 10779 "the managed keys database", 10780 keytag, namebuf); 10781 } 10782 } else if (revoked && keydata.removehd == 0) { 10783 dnssec_log(zone, ISC_LOG_WARNING, 10784 "Active key %d for zone " 10785 "%s is revoked but " 10786 "did not self-sign; " 10787 "ignoring", 10788 keytag, namebuf); 10789 continue; 10790 } else if (secure) { 10791 if (keydata.removehd != 0) { 10792 /* 10793 * Key isn't revoked--but it 10794 * seems it used to be. 10795 * Remove it now and add it 10796 * back as if it were a fresh key, 10797 * with a 30-day acceptance timer. 10798 */ 10799 deletekey = true; 10800 newkey = true; 10801 keydata.removehd = 0; 10802 keydata.addhd = now + 10803 dns_zone_mkey_month; 10804 10805 dnssec_log(zone, ISC_LOG_INFO, 10806 "Revoked key %d for " 10807 "zone %s has returned: " 10808 "starting 30-day " 10809 "acceptance timer", 10810 keytag, namebuf); 10811 } else if (keydata.addhd > now) { 10812 pending++; 10813 } else if (keydata.addhd == 0) { 10814 keydata.addhd = now; 10815 } 10816 10817 if (keydata.addhd <= now) { 10818 trustkey = true; 10819 dnssec_log(zone, ISC_LOG_INFO, 10820 "Key %d for zone %s " 10821 "is now trusted (%s)", 10822 keytag, namebuf, 10823 initial ? "initializing key " 10824 "verified" 10825 : "acceptance timer " 10826 "complete"); 10827 } 10828 } else if (keydata.addhd > now) { 10829 /* 10830 * Not secure, and key is pending: 10831 * reset the acceptance timer 10832 */ 10833 pending++; 10834 keydata.addhd = now + dns_zone_mkey_month; 10835 dnssec_log(zone, ISC_LOG_INFO, 10836 "Pending key %d " 10837 "for zone %s was " 10838 "not validated: restarting " 10839 "30-day acceptance timer", 10840 keytag, namebuf); 10841 } 10842 10843 if (!deletekey && !newkey) { 10844 updatekey = true; 10845 } 10846 } else if (secure) { 10847 /* 10848 * Key wasn't in the key zone but it's 10849 * revoked now anyway, so just skip it 10850 */ 10851 if (revoked) { 10852 continue; 10853 } 10854 10855 /* Key wasn't in the key zone: add it */ 10856 newkey = true; 10857 10858 if (initializing) { 10859 dnssec_log(zone, ISC_LOG_WARNING, 10860 "Initializing automatic trust " 10861 "anchor management for zone '%s'; " 10862 "DNSKEY ID %d is now trusted, " 10863 "waiving the normal 30-day " 10864 "waiting period.", 10865 namebuf, keytag); 10866 trustkey = true; 10867 } else { 10868 dnssec_log(zone, ISC_LOG_INFO, 10869 "New key %d observed " 10870 "for zone '%s': " 10871 "starting 30-day " 10872 "acceptance timer", 10873 keytag, namebuf); 10874 } 10875 } else { 10876 /* 10877 * No previously known key, and the key is not 10878 * secure, so skip it. 10879 */ 10880 continue; 10881 } 10882 10883 /* Delete old version */ 10884 if (deletekey || !newkey) { 10885 CHECK(update_one_rr(kfetch->db, ver, &diff, 10886 DNS_DIFFOP_DEL, keyname, 0, 10887 &keydatarr)); 10888 } 10889 10890 if (updatekey) { 10891 /* Set refresh timer */ 10892 keydata.refresh = refresh_time(kfetch, false); 10893 dns_rdata_reset(&keydatarr); 10894 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10895 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 10896 dns_rdatatype_keydata, &keydata, 10897 &keyb); 10898 10899 /* Insert updated version */ 10900 CHECK(update_one_rr(kfetch->db, ver, &diff, 10901 DNS_DIFFOP_ADD, keyname, 0, 10902 &keydatarr)); 10903 } else if (newkey) { 10904 /* Convert DNSKEY to KEYDATA */ 10905 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 10906 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10907 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0, 10908 NULL); 10909 keydata.addhd = initializing 10910 ? now 10911 : now + dns_zone_mkey_month; 10912 keydata.refresh = refresh_time(kfetch, false); 10913 dns_rdata_reset(&keydatarr); 10914 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10915 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 10916 dns_rdatatype_keydata, &keydata, 10917 &keyb); 10918 10919 /* Insert into key zone */ 10920 CHECK(update_one_rr(kfetch->db, ver, &diff, 10921 DNS_DIFFOP_ADD, keyname, 0, 10922 &keydatarr)); 10923 } 10924 10925 if (trustkey) { 10926 /* Trust this key. */ 10927 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 10928 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10929 trust_key(zone, keyname, &dnskey, false); 10930 } 10931 10932 if (secure && !deletekey) { 10933 INSIST(newkey || updatekey); 10934 set_refreshkeytimer(zone, &keydata, now, false); 10935 } 10936 } 10937 10938 /* 10939 * RFC5011 says, "A trust point that has all of its trust anchors 10940 * revoked is considered deleted and is treated as if the trust 10941 * point was never configured." But if someone revoked their 10942 * active key before the standby was trusted, that would mean the 10943 * zone would suddenly be nonsecured. We avoid this by checking to 10944 * see if there's pending keydata. If so, we put a null key in 10945 * the security roots; then all queries to the zone will fail. 10946 */ 10947 if (pending != 0) { 10948 fail_secure(zone, keyname); 10949 } 10950 10951 done: 10952 if (!ISC_LIST_EMPTY(diff.tuples)) { 10953 /* Write changes to journal file. */ 10954 CHECK(update_soa_serial(zone, kfetch->db, ver, &diff, mctx, 10955 zone->updatemethod)); 10956 CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done")); 10957 commit = true; 10958 10959 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 10960 zone_needdump(zone, 30); 10961 } else if (result == ISC_R_NOMORE) { 10962 /* 10963 * If "updatekey" was true for all keys found in the DNSKEY 10964 * response and the previous update of those keys happened 10965 * during the same second (only possible if a key refresh was 10966 * externally triggered), it may happen that all relevant 10967 * update_one_rr() calls will return ISC_R_SUCCESS, but 10968 * diff.tuples will remain empty. Reset result to 10969 * ISC_R_SUCCESS to prevent a bogus warning from being logged. 10970 */ 10971 result = ISC_R_SUCCESS; 10972 } 10973 10974 cleanup: 10975 if (result != ISC_R_SUCCESS) { 10976 dnssec_log(zone, ISC_LOG_ERROR, 10977 "error during managed-keys processing (%s): " 10978 "DNSSEC validation may be at risk", 10979 isc_result_totext(result)); 10980 } 10981 dns_diff_clear(&diff); 10982 if (ver != NULL) { 10983 dns_db_closeversion(kfetch->db, &ver, commit); 10984 } 10985 10986 out: 10987 dns_db_detach(&kfetch->db); 10988 10989 isc_refcount_decrement(&zone->irefs); 10990 10991 if (dns_rdataset_isassociated(keydataset)) { 10992 dns_rdataset_disassociate(keydataset); 10993 } 10994 if (dns_rdataset_isassociated(dnskeys)) { 10995 dns_rdataset_disassociate(dnskeys); 10996 } 10997 if (dns_rdataset_isassociated(dnskeysigs)) { 10998 dns_rdataset_disassociate(dnskeysigs); 10999 } 11000 11001 dns_resolver_freefresp(&resp); 11002 dns_name_free(keyname, mctx); 11003 isc_mem_putanddetach(&kfetch->mctx, kfetch, sizeof(dns_keyfetch_t)); 11004 11005 if (secroots != NULL) { 11006 dns_keytable_detach(&secroots); 11007 } 11008 11009 free_needed = exit_check(zone); 11010 UNLOCK_ZONE(zone); 11011 11012 if (free_needed) { 11013 zone_free(zone); 11014 } 11015 11016 INSIST(ver == NULL); 11017 } 11018 11019 static void 11020 retry_keyfetch(dns_keyfetch_t *kfetch, dns_name_t *kname) { 11021 isc_time_t timenow, timethen; 11022 dns_zone_t *zone = kfetch->zone; 11023 bool free_needed; 11024 char namebuf[DNS_NAME_FORMATSIZE]; 11025 11026 dns_name_format(kname, namebuf, sizeof(namebuf)); 11027 dnssec_log(zone, ISC_LOG_WARNING, 11028 "Failed to create fetch for %s DNSKEY update", namebuf); 11029 11030 /* 11031 * Error during a key fetch; cancel and retry in an hour. 11032 */ 11033 LOCK_ZONE(zone); 11034 zone->refreshkeycount--; 11035 isc_refcount_decrement(&zone->irefs); 11036 dns_db_detach(&kfetch->db); 11037 dns_rdataset_disassociate(&kfetch->keydataset); 11038 dns_name_free(kname, zone->mctx); 11039 isc_mem_putanddetach(&kfetch->mctx, kfetch, sizeof(*kfetch)); 11040 11041 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11042 /* Don't really retry if we are exiting */ 11043 char timebuf[80]; 11044 11045 timenow = isc_time_now(); 11046 DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen); 11047 zone->refreshkeytime = timethen; 11048 zone_settimer(zone, &timenow); 11049 11050 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 11051 dnssec_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s", 11052 timebuf); 11053 } 11054 11055 free_needed = exit_check(zone); 11056 UNLOCK_ZONE(zone); 11057 11058 if (free_needed) { 11059 zone_free(zone); 11060 } 11061 } 11062 11063 static void 11064 do_keyfetch(void *arg) { 11065 isc_result_t result; 11066 dns_keyfetch_t *kfetch = (dns_keyfetch_t *)arg; 11067 dns_name_t *kname = dns_fixedname_name(&kfetch->name); 11068 dns_resolver_t *resolver = NULL; 11069 dns_zone_t *zone = kfetch->zone; 11070 unsigned int options = DNS_FETCHOPT_NOVALIDATE | DNS_FETCHOPT_UNSHARED | 11071 DNS_FETCHOPT_NOCACHED; 11072 11073 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11074 goto retry; 11075 } 11076 11077 result = dns_view_getresolver(zone->view, &resolver); 11078 if (result != ISC_R_SUCCESS) { 11079 goto retry; 11080 } 11081 11082 /* 11083 * Use of DNS_FETCHOPT_NOCACHED is essential here. If it is not 11084 * set and the cache still holds a non-expired, validated version 11085 * of the RRset being queried for by the time the response is 11086 * received, the cached RRset will be passed to keyfetch_done() 11087 * instead of the one received in the response as the latter will 11088 * have a lower trust level due to not being validated until 11089 * keyfetch_done() is called. 11090 */ 11091 result = dns_resolver_createfetch( 11092 resolver, kname, dns_rdatatype_dnskey, NULL, NULL, NULL, NULL, 11093 0, options, 0, NULL, NULL, NULL, zone->loop, keyfetch_done, 11094 kfetch, NULL, &kfetch->dnskeyset, &kfetch->dnskeysigset, 11095 &kfetch->fetch); 11096 11097 dns_resolver_detach(&resolver); 11098 if (result == ISC_R_SUCCESS) { 11099 return; 11100 } 11101 retry: 11102 retry_keyfetch(kfetch, kname); 11103 } 11104 11105 /* 11106 * Refresh the data in the key zone. Initiate a fetch to look up 11107 * DNSKEY records at the trust anchor name. 11108 */ 11109 static void 11110 zone_refreshkeys(dns_zone_t *zone) { 11111 isc_result_t result; 11112 dns_rriterator_t rrit; 11113 dns_db_t *db = NULL; 11114 dns_dbversion_t *ver = NULL; 11115 dns_diff_t diff; 11116 dns_rdata_t rdata = DNS_RDATA_INIT; 11117 dns_rdata_keydata_t kd; 11118 isc_stdtime_t now = isc_stdtime_now(); 11119 bool commit = false; 11120 bool fetching = false; 11121 bool timerset = false; 11122 11123 ENTER; 11124 REQUIRE(zone->db != NULL); 11125 11126 LOCK_ZONE(zone); 11127 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11128 isc_time_settoepoch(&zone->refreshkeytime); 11129 UNLOCK_ZONE(zone); 11130 return; 11131 } 11132 11133 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 11134 dns_db_attach(zone->db, &db); 11135 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11136 11137 dns_diff_init(zone->mctx, &diff); 11138 11139 CHECK(dns_db_newversion(db, &ver)); 11140 11141 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING); 11142 11143 dns_rriterator_init(&rrit, db, ver, 0); 11144 for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS; 11145 result = dns_rriterator_nextrrset(&rrit)) 11146 { 11147 isc_stdtime_t timer = 0xffffffff; 11148 dns_name_t *name = NULL, *kname = NULL; 11149 dns_rdataset_t *kdset = NULL; 11150 uint32_t ttl; 11151 11152 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL); 11153 if (kdset == NULL || kdset->type != dns_rdatatype_keydata || 11154 !dns_rdataset_isassociated(kdset)) 11155 { 11156 continue; 11157 } 11158 11159 /* 11160 * Scan the stored keys looking for ones that need 11161 * removal or refreshing 11162 */ 11163 for (result = dns_rdataset_first(kdset); 11164 result == ISC_R_SUCCESS; result = dns_rdataset_next(kdset)) 11165 { 11166 dns_rdata_reset(&rdata); 11167 dns_rdataset_current(kdset, &rdata); 11168 result = dns_rdata_tostruct(&rdata, &kd, NULL); 11169 RUNTIME_CHECK(result == ISC_R_SUCCESS); 11170 11171 /* Removal timer expired? */ 11172 if (kd.removehd != 0 && kd.removehd < now) { 11173 dns_rriterator_pause(&rrit); 11174 CHECK(update_one_rr(db, ver, &diff, 11175 DNS_DIFFOP_DEL, name, ttl, 11176 &rdata)); 11177 continue; 11178 } 11179 11180 /* Acceptance timer expired? */ 11181 if (kd.addhd <= now) { 11182 timer = kd.addhd; 11183 } 11184 11185 /* Or do we just need to refresh the keyset? */ 11186 if (timer > kd.refresh) { 11187 timer = kd.refresh; 11188 } 11189 11190 dns_rriterator_pause(&rrit); 11191 set_refreshkeytimer(zone, &kd, now, false); 11192 timerset = true; 11193 } 11194 11195 if (timer > now) { 11196 continue; 11197 } 11198 11199 dns_rriterator_pause(&rrit); 11200 11201 #ifdef ENABLE_AFL 11202 if (!dns_fuzzing_resolver) { 11203 #endif /* ifdef ENABLE_AFL */ 11204 dns_keyfetch_t *kfetch = NULL; 11205 11206 kfetch = isc_mem_get(zone->mctx, 11207 sizeof(dns_keyfetch_t)); 11208 *kfetch = (dns_keyfetch_t){ .zone = zone }; 11209 isc_mem_attach(zone->mctx, &kfetch->mctx); 11210 11211 zone->refreshkeycount++; 11212 isc_refcount_increment0(&zone->irefs); 11213 kname = dns_fixedname_initname(&kfetch->name); 11214 dns_name_dup(name, zone->mctx, kname); 11215 dns_rdataset_init(&kfetch->dnskeyset); 11216 dns_rdataset_init(&kfetch->dnskeysigset); 11217 dns_rdataset_init(&kfetch->keydataset); 11218 dns_rdataset_clone(kdset, &kfetch->keydataset); 11219 dns_db_attach(db, &kfetch->db); 11220 11221 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 11222 char namebuf[DNS_NAME_FORMATSIZE]; 11223 dns_name_format(kname, namebuf, 11224 sizeof(namebuf)); 11225 dnssec_log(zone, ISC_LOG_DEBUG(3), 11226 "Creating key fetch in " 11227 "zone_refreshkeys() for '%s'", 11228 namebuf); 11229 } 11230 11231 isc_async_run(zone->loop, do_keyfetch, kfetch); 11232 fetching = true; 11233 #ifdef ENABLE_AFL 11234 } 11235 #endif /* ifdef ENABLE_AFL */ 11236 } 11237 if (!ISC_LIST_EMPTY(diff.tuples)) { 11238 CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx, 11239 zone->updatemethod)); 11240 CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys")); 11241 commit = true; 11242 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 11243 zone_needdump(zone, 30); 11244 } 11245 11246 cleanup: 11247 if (!timerset) { 11248 isc_time_settoepoch(&zone->refreshkeytime); 11249 } 11250 11251 if (!fetching) { 11252 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 11253 } 11254 11255 dns_diff_clear(&diff); 11256 if (ver != NULL) { 11257 dns_rriterator_destroy(&rrit); 11258 dns_db_closeversion(db, &ver, commit); 11259 } 11260 dns_db_detach(&db); 11261 11262 UNLOCK_ZONE(zone); 11263 11264 INSIST(ver == NULL); 11265 } 11266 11267 static void 11268 zone_maintenance(dns_zone_t *zone) { 11269 isc_time_t now; 11270 isc_result_t result; 11271 bool load_pending, exiting, dumping, viewok = false, notify; 11272 bool refreshkeys, sign, resign, rekey, chain, warn_expire; 11273 11274 REQUIRE(DNS_ZONE_VALID(zone)); 11275 ENTER; 11276 11277 /* 11278 * Are we pending load/reload, exiting, or unconfigured 11279 * (e.g. because of a syntax failure in the config file)? 11280 * If so, don't attempt maintenance. 11281 */ 11282 LOCK_ZONE(zone); 11283 load_pending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING); 11284 exiting = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING); 11285 if (!load_pending && !exiting && zone->view != NULL) { 11286 dns_adb_t *adb = NULL; 11287 dns_view_getadb(zone->view, &adb); 11288 if (adb != NULL) { 11289 dns_adb_detach(&adb); 11290 viewok = true; 11291 } 11292 } 11293 UNLOCK_ZONE(zone); 11294 11295 if (load_pending || exiting || !viewok) { 11296 return; 11297 } 11298 11299 now = isc_time_now(); 11300 11301 /* 11302 * Expire check. 11303 */ 11304 switch (zone->type) { 11305 case dns_zone_redirect: 11306 if (dns_remote_addresses(&zone->primaries) == NULL) { 11307 break; 11308 } 11309 FALLTHROUGH; 11310 case dns_zone_secondary: 11311 case dns_zone_mirror: 11312 case dns_zone_stub: 11313 LOCK_ZONE(zone); 11314 if (isc_time_compare(&now, &zone->expiretime) >= 0 && 11315 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 11316 { 11317 zone_expire(zone); 11318 zone->refreshtime = now; 11319 } 11320 UNLOCK_ZONE(zone); 11321 break; 11322 default: 11323 break; 11324 } 11325 11326 /* 11327 * Up to date check. 11328 */ 11329 switch (zone->type) { 11330 case dns_zone_redirect: 11331 if (dns_remote_addresses(&zone->primaries) == NULL) { 11332 break; 11333 } 11334 FALLTHROUGH; 11335 case dns_zone_secondary: 11336 case dns_zone_mirror: 11337 case dns_zone_stub: 11338 LOCK_ZONE(zone); 11339 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && 11340 isc_time_compare(&now, &zone->refreshtime) >= 0) 11341 { 11342 zone_refresh(zone); 11343 } 11344 UNLOCK_ZONE(zone); 11345 break; 11346 default: 11347 break; 11348 } 11349 11350 /* 11351 * Secondaries send notifies before backing up to disk, 11352 * primaries after. 11353 */ 11354 LOCK_ZONE(zone); 11355 if (zone->notifydefer != 0 && 11356 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOTIFYNODEFER) && 11357 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOTIFYDEFERRED)) 11358 { 11359 if (isc_time_compare(&now, &zone->notifytime) > 0) { 11360 zone->notifytime = now; 11361 } 11362 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOTIFYDEFERRED); 11363 DNS_ZONE_TIME_ADD(&zone->notifytime, zone->notifydefer, 11364 &zone->notifytime); 11365 } 11366 notify = (zone->type == dns_zone_secondary || 11367 zone->type == dns_zone_mirror) && 11368 (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 11369 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) && 11370 isc_time_compare(&now, &zone->notifytime) >= 0; 11371 UNLOCK_ZONE(zone); 11372 11373 if (notify) { 11374 zone_notify(zone, &now); 11375 } 11376 11377 /* 11378 * Do we need to consolidate the backing store? 11379 */ 11380 switch (zone->type) { 11381 case dns_zone_primary: 11382 case dns_zone_secondary: 11383 case dns_zone_mirror: 11384 case dns_zone_key: 11385 case dns_zone_redirect: 11386 case dns_zone_stub: 11387 LOCK_ZONE(zone); 11388 if (zone->masterfile != NULL && 11389 isc_time_compare(&now, &zone->dumptime) >= 0 && 11390 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 11391 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) 11392 { 11393 dumping = was_dumping(zone); 11394 } else { 11395 dumping = true; 11396 } 11397 UNLOCK_ZONE(zone); 11398 if (!dumping) { 11399 result = zone_dump(zone, true); /* loop locked */ 11400 if (result != ISC_R_SUCCESS) { 11401 dns_zone_log(zone, ISC_LOG_WARNING, 11402 "dump failed: %s", 11403 isc_result_totext(result)); 11404 } 11405 } 11406 break; 11407 default: 11408 break; 11409 } 11410 11411 /* 11412 * Primary/redirect zones send notifies now, if needed 11413 */ 11414 switch (zone->type) { 11415 case dns_zone_primary: 11416 case dns_zone_redirect: 11417 LOCK_ZONE(zone); 11418 notify = (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 11419 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) && 11420 isc_time_compare(&now, &zone->notifytime) >= 0; 11421 UNLOCK_ZONE(zone); 11422 if (notify) { 11423 zone_notify(zone, &now); 11424 } 11425 default: 11426 break; 11427 } 11428 11429 /* 11430 * Do we need to refresh keys? 11431 */ 11432 switch (zone->type) { 11433 case dns_zone_key: 11434 LOCK_ZONE(zone); 11435 refreshkeys = isc_time_compare(&now, &zone->refreshkeytime) >= 11436 0 && 11437 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 11438 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING); 11439 UNLOCK_ZONE(zone); 11440 if (refreshkeys) { 11441 zone_refreshkeys(zone); 11442 } 11443 break; 11444 case dns_zone_primary: 11445 LOCK_ZONE(zone); 11446 if (zone->rss != NULL) { 11447 isc_time_settoepoch(&zone->refreshkeytime); 11448 UNLOCK_ZONE(zone); 11449 break; 11450 } 11451 rekey = (!isc_time_isepoch(&zone->refreshkeytime) && 11452 isc_time_compare(&now, &zone->refreshkeytime) >= 0); 11453 UNLOCK_ZONE(zone); 11454 if (rekey) { 11455 zone_rekey(zone); 11456 } 11457 default: 11458 break; 11459 } 11460 11461 switch (zone->type) { 11462 case dns_zone_primary: 11463 case dns_zone_redirect: 11464 case dns_zone_secondary: 11465 /* 11466 * Do we need to sign/resign some RRsets? 11467 */ 11468 LOCK_ZONE(zone); 11469 if (zone->rss != NULL) { 11470 isc_time_settoepoch(&zone->signingtime); 11471 isc_time_settoepoch(&zone->resigntime); 11472 isc_time_settoepoch(&zone->nsec3chaintime); 11473 isc_time_settoepoch(&zone->keywarntime); 11474 UNLOCK_ZONE(zone); 11475 break; 11476 } 11477 sign = !isc_time_isepoch(&zone->signingtime) && 11478 isc_time_compare(&now, &zone->signingtime) >= 0; 11479 resign = !isc_time_isepoch(&zone->resigntime) && 11480 isc_time_compare(&now, &zone->resigntime) >= 0; 11481 chain = !isc_time_isepoch(&zone->nsec3chaintime) && 11482 isc_time_compare(&now, &zone->nsec3chaintime) >= 0; 11483 warn_expire = !isc_time_isepoch(&zone->keywarntime) && 11484 isc_time_compare(&now, &zone->keywarntime) >= 0; 11485 UNLOCK_ZONE(zone); 11486 11487 if (sign) { 11488 zone_sign(zone); 11489 } else if (resign) { 11490 zone_resigninc(zone); 11491 } else if (chain) { 11492 zone_nsec3chain(zone); 11493 } 11494 11495 /* 11496 * Do we need to issue a key expiry warning? 11497 */ 11498 if (warn_expire) { 11499 set_key_expiry_warning(zone, zone->key_expiry, 11500 isc_time_seconds(&now)); 11501 } 11502 break; 11503 11504 default: 11505 break; 11506 } 11507 LOCK_ZONE(zone); 11508 zone_settimer(zone, &now); 11509 UNLOCK_ZONE(zone); 11510 } 11511 11512 void 11513 dns_zone_markdirty(dns_zone_t *zone) { 11514 uint32_t serial; 11515 isc_result_t result = ISC_R_SUCCESS; 11516 dns_zone_t *secure = NULL; 11517 11518 /* 11519 * Obtaining a lock on the zone->secure (see zone_send_secureserial) 11520 * could result in a deadlock due to a LOR so we will spin if we 11521 * can't obtain the both locks. 11522 */ 11523 again: 11524 LOCK_ZONE(zone); 11525 if (zone->type == dns_zone_primary) { 11526 if (inline_raw(zone)) { 11527 unsigned int soacount; 11528 secure = zone->secure; 11529 INSIST(secure != zone); 11530 TRYLOCK_ZONE(result, secure); 11531 if (result != ISC_R_SUCCESS) { 11532 UNLOCK_ZONE(zone); 11533 secure = NULL; 11534 isc_thread_yield(); 11535 goto again; 11536 } 11537 11538 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 11539 if (zone->db != NULL) { 11540 result = zone_get_from_db( 11541 zone, zone->db, NULL, &soacount, NULL, 11542 &serial, NULL, NULL, NULL, NULL, NULL); 11543 } else { 11544 result = DNS_R_NOTLOADED; 11545 } 11546 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11547 if (result == ISC_R_SUCCESS && soacount > 0U) { 11548 zone_send_secureserial(zone, serial); 11549 } 11550 } 11551 11552 /* XXXMPA make separate call back */ 11553 if (result == ISC_R_SUCCESS) { 11554 set_resigntime(zone); 11555 if (zone->loop != NULL) { 11556 isc_time_t now; 11557 now = isc_time_now(); 11558 zone_settimer(zone, &now); 11559 } 11560 } 11561 } 11562 if (secure != NULL) { 11563 UNLOCK_ZONE(secure); 11564 } 11565 zone_needdump(zone, DNS_DUMP_DELAY); 11566 UNLOCK_ZONE(zone); 11567 } 11568 11569 void 11570 dns_zone_expire(dns_zone_t *zone) { 11571 REQUIRE(DNS_ZONE_VALID(zone)); 11572 11573 LOCK_ZONE(zone); 11574 zone_expire(zone); 11575 UNLOCK_ZONE(zone); 11576 } 11577 11578 static void 11579 zone_expire(dns_zone_t *zone) { 11580 dns_db_t *db = NULL; 11581 11582 /* 11583 * 'zone' locked by caller. 11584 */ 11585 11586 REQUIRE(LOCKED_ZONE(zone)); 11587 11588 dns_zone_log(zone, ISC_LOG_WARNING, "expired"); 11589 11590 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED); 11591 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 11592 zone->retry = DNS_ZONE_DEFAULTRETRY; 11593 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 11594 11595 /* 11596 * An RPZ zone has expired; before unloading it, we must 11597 * first remove it from the RPZ summary database. The 11598 * easiest way to do this is "update" it with an empty 11599 * database so that the update callback synchronizes 11600 * the diff automatically. 11601 */ 11602 if (zone->rpzs != NULL && zone->rpz_num != DNS_RPZ_INVALID_NUM) { 11603 isc_result_t result; 11604 dns_rpz_zone_t *rpz = zone->rpzs->zones[zone->rpz_num]; 11605 11606 CHECK(dns_db_create(zone->mctx, ZONEDB_DEFAULT, &zone->origin, 11607 dns_dbtype_zone, zone->rdclass, 0, NULL, 11608 &db)); 11609 CHECK(dns_rpz_dbupdate_callback(db, rpz)); 11610 dns_zone_log(zone, ISC_LOG_WARNING, 11611 "response-policy zone expired; " 11612 "policies unloaded"); 11613 } 11614 11615 cleanup: 11616 if (db != NULL) { 11617 dns_db_detach(&db); 11618 } 11619 11620 zone_unload(zone); 11621 } 11622 11623 static void 11624 zone_refresh(dns_zone_t *zone) { 11625 isc_interval_t i; 11626 uint32_t oldflags; 11627 isc_result_t result; 11628 11629 REQUIRE(DNS_ZONE_VALID(zone)); 11630 REQUIRE(LOCKED_ZONE(zone)); 11631 11632 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11633 return; 11634 } 11635 11636 /* 11637 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation 11638 * in progress at a time. 11639 */ 11640 11641 oldflags = ISC_ZONE_GET(zone, flags); 11642 if (dns_remote_addresses(&zone->primaries) == NULL) { 11643 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOPRIMARIES); 11644 if ((oldflags & DNS_ZONEFLG_NOPRIMARIES) == 0) { 11645 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 11646 ISC_LOG_ERROR, 11647 "cannot refresh: no primaries"); 11648 } 11649 return; 11650 } 11651 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 11652 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 11653 if ((oldflags & (DNS_ZONEFLG_REFRESH | DNS_ZONEFLG_LOADING)) != 0) { 11654 return; 11655 } 11656 11657 /* 11658 * Set the next refresh time as if refresh check has failed. 11659 * Setting this to the retry time will do that. XXXMLG 11660 * If we are successful it will be reset using zone->refresh. 11661 */ 11662 isc_interval_set(&i, zone->retry - isc_random_uniform(zone->retry / 4), 11663 0); 11664 result = isc_time_nowplusinterval(&zone->refreshtime, &i); 11665 if (result != ISC_R_SUCCESS) { 11666 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_WARNING, 11667 "isc_time_nowplusinterval() failed: %s", 11668 isc_result_totext(result)); 11669 } 11670 11671 /* 11672 * When lacking user-specified timer values from the SOA, 11673 * do exponential backoff of the retry time up to a 11674 * maximum of six hours. 11675 */ 11676 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) { 11677 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600); 11678 } 11679 11680 dns_remote_reset(&zone->primaries, true); 11681 11682 /* initiate soa query */ 11683 queue_soa_query(zone); 11684 } 11685 11686 static void 11687 zone_refresh_async(void *arg) { 11688 dns_zone_t *zone = arg; 11689 11690 LOCK_ZONE(zone); 11691 zone_refresh(zone); 11692 UNLOCK_ZONE(zone); 11693 11694 dns_zone_detach(&zone); 11695 } 11696 11697 void 11698 dns_zone_refresh(dns_zone_t *zone) { 11699 REQUIRE(DNS_ZONE_VALID(zone)); 11700 11701 dns_zone_ref(zone); 11702 isc_async_run(zone->loop, zone_refresh_async, zone); 11703 } 11704 11705 static isc_result_t 11706 zone_journal_rollforward(dns_zone_t *zone, dns_db_t *db, bool *needdump, 11707 bool *fixjournal) { 11708 dns_journal_t *journal = NULL; 11709 unsigned int options; 11710 isc_result_t result; 11711 11712 if (zone->type == dns_zone_primary && 11713 (inline_secure(zone) || 11714 (zone->update_acl != NULL || zone->ssutable != NULL))) 11715 { 11716 options = DNS_JOURNALOPT_RESIGN; 11717 } else { 11718 options = 0; 11719 } 11720 11721 result = dns_journal_open(zone->mctx, zone->journal, DNS_JOURNAL_READ, 11722 &journal); 11723 if (result == ISC_R_NOTFOUND) { 11724 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(3), 11725 "no journal file, but that's OK "); 11726 return ISC_R_SUCCESS; 11727 } else if (result != ISC_R_SUCCESS) { 11728 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 11729 "journal open failed: %s", 11730 isc_result_totext(result)); 11731 return result; 11732 } 11733 11734 if (dns_journal_empty(journal)) { 11735 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1), 11736 "journal empty"); 11737 dns_journal_destroy(&journal); 11738 return ISC_R_SUCCESS; 11739 } 11740 11741 result = dns_journal_rollforward(journal, db, options); 11742 switch (result) { 11743 case ISC_R_SUCCESS: 11744 *needdump = true; 11745 FALLTHROUGH; 11746 case DNS_R_UPTODATE: 11747 if (dns_journal_recovered(journal)) { 11748 *fixjournal = true; 11749 dns_zone_logc( 11750 zone, DNS_LOGCATEGORY_ZONELOAD, 11751 ISC_LOG_DEBUG(1), 11752 "journal rollforward completed successfully " 11753 "using old journal format: %s", 11754 isc_result_totext(result)); 11755 } else { 11756 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 11757 ISC_LOG_DEBUG(1), 11758 "journal rollforward completed " 11759 "successfully: %s", 11760 isc_result_totext(result)); 11761 } 11762 11763 dns_journal_destroy(&journal); 11764 return ISC_R_SUCCESS; 11765 case ISC_R_NOTFOUND: 11766 case ISC_R_RANGE: 11767 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 11768 "journal rollforward failed: journal out of sync " 11769 "with zone"); 11770 dns_journal_destroy(&journal); 11771 return result; 11772 default: 11773 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 11774 "journal rollforward failed: %s", 11775 isc_result_totext(result)); 11776 dns_journal_destroy(&journal); 11777 return result; 11778 } 11779 } 11780 11781 static void 11782 zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial) { 11783 isc_result_t result; 11784 int32_t journalsize; 11785 dns_dbversion_t *ver = NULL; 11786 uint64_t dbsize; 11787 uint32_t options = 0; 11788 11789 INSIST(LOCKED_ZONE(zone)); 11790 if (inline_raw(zone)) { 11791 INSIST(LOCKED_ZONE(zone->secure)); 11792 } 11793 11794 journalsize = zone->journalsize; 11795 if (journalsize == -1) { 11796 journalsize = DNS_JOURNAL_SIZE_MAX; 11797 dns_db_currentversion(db, &ver); 11798 result = dns_db_getsize(db, ver, NULL, &dbsize); 11799 dns_db_closeversion(db, &ver, false); 11800 if (result != ISC_R_SUCCESS) { 11801 dns_zone_log(zone, ISC_LOG_ERROR, 11802 "zone_journal_compact: " 11803 "could not get zone size: %s", 11804 isc_result_totext(result)); 11805 } else if (dbsize < DNS_JOURNAL_SIZE_MAX / 2) { 11806 journalsize = (int32_t)dbsize * 2; 11807 } 11808 } 11809 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FIXJOURNAL)) { 11810 options |= DNS_JOURNAL_COMPACTALL; 11811 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FIXJOURNAL); 11812 zone_debuglog(zone, __func__, 1, "repair full journal"); 11813 } else { 11814 zone_debuglog(zone, __func__, 1, "target journal size %d", 11815 journalsize); 11816 } 11817 result = dns_journal_compact(zone->mctx, zone->journal, serial, options, 11818 journalsize); 11819 switch (result) { 11820 case ISC_R_SUCCESS: 11821 case ISC_R_NOSPACE: 11822 case ISC_R_NOTFOUND: 11823 dns_zone_log(zone, ISC_LOG_DEBUG(3), "dns_journal_compact: %s", 11824 isc_result_totext(result)); 11825 break; 11826 default: 11827 dns_zone_log(zone, ISC_LOG_ERROR, 11828 "dns_journal_compact failed: %s", 11829 isc_result_totext(result)); 11830 break; 11831 } 11832 } 11833 11834 isc_result_t 11835 dns_zone_flush(dns_zone_t *zone) { 11836 isc_result_t result = ISC_R_SUCCESS; 11837 bool dumping; 11838 11839 REQUIRE(DNS_ZONE_VALID(zone)); 11840 11841 LOCK_ZONE(zone); 11842 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH); 11843 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 11844 zone->masterfile != NULL) 11845 { 11846 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 11847 result = ISC_R_ALREADYRUNNING; 11848 dumping = was_dumping(zone); 11849 } else { 11850 dumping = true; 11851 } 11852 UNLOCK_ZONE(zone); 11853 if (!dumping) { 11854 result = zone_dump(zone, true); 11855 } 11856 return result; 11857 } 11858 11859 isc_result_t 11860 dns_zone_dump(dns_zone_t *zone) { 11861 isc_result_t result = ISC_R_ALREADYRUNNING; 11862 bool dumping; 11863 11864 REQUIRE(DNS_ZONE_VALID(zone)); 11865 11866 LOCK_ZONE(zone); 11867 dumping = was_dumping(zone); 11868 UNLOCK_ZONE(zone); 11869 if (!dumping) { 11870 result = zone_dump(zone, false); 11871 } 11872 return result; 11873 } 11874 11875 static void 11876 zone_needdump(dns_zone_t *zone, unsigned int delay) { 11877 isc_time_t dumptime; 11878 isc_time_t now; 11879 11880 /* 11881 * 'zone' locked by caller 11882 */ 11883 11884 REQUIRE(DNS_ZONE_VALID(zone)); 11885 REQUIRE(LOCKED_ZONE(zone)); 11886 ENTER; 11887 11888 /* 11889 * Do we have a place to dump to and are we loaded? 11890 */ 11891 if (zone->masterfile == NULL || 11892 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) 11893 { 11894 return; 11895 } 11896 11897 now = isc_time_now(); 11898 /* add some noise */ 11899 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime); 11900 11901 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 11902 if (isc_time_isepoch(&zone->dumptime) || 11903 isc_time_compare(&zone->dumptime, &dumptime) > 0) 11904 { 11905 zone->dumptime = dumptime; 11906 } 11907 if (zone->loop != NULL) { 11908 zone_settimer(zone, &now); 11909 } 11910 } 11911 11912 static void 11913 dump_done(void *arg, isc_result_t result) { 11914 dns_zone_t *zone = arg; 11915 dns_zone_t *secure = NULL; 11916 dns_db_t *db; 11917 dns_dbversion_t *version; 11918 bool again = false; 11919 bool compact = false; 11920 uint32_t serial; 11921 isc_result_t tresult; 11922 11923 REQUIRE(DNS_ZONE_VALID(zone)); 11924 11925 ENTER; 11926 11927 /* 11928 * Adjust modification time of zone file to preserve expire timing. 11929 */ 11930 if ((zone->type == dns_zone_secondary || 11931 zone->type == dns_zone_mirror || 11932 zone->type == dns_zone_redirect) && 11933 result == ISC_R_SUCCESS) 11934 { 11935 LOCK_ZONE(zone); 11936 isc_time_t when; 11937 isc_interval_t i; 11938 isc_interval_set(&i, zone->expire, 0); 11939 result = isc_time_subtract(&zone->expiretime, &i, &when); 11940 if (result == ISC_R_SUCCESS) { 11941 (void)isc_file_settime(zone->masterfile, &when); 11942 } else { 11943 result = ISC_R_SUCCESS; 11944 } 11945 UNLOCK_ZONE(zone); 11946 } 11947 11948 if (result == ISC_R_SUCCESS && zone->journal != NULL) { 11949 /* 11950 * We don't own these, zone->dctx must stay valid. 11951 */ 11952 db = dns_dumpctx_db(zone->dumpctx); 11953 version = dns_dumpctx_version(zone->dumpctx); 11954 tresult = dns_db_getsoaserial(db, version, &serial); 11955 11956 /* 11957 * Handle lock order inversion. 11958 */ 11959 again: 11960 LOCK_ZONE(zone); 11961 if (inline_raw(zone)) { 11962 secure = zone->secure; 11963 INSIST(secure != zone); 11964 TRYLOCK_ZONE(result, secure); 11965 if (result != ISC_R_SUCCESS) { 11966 UNLOCK_ZONE(zone); 11967 secure = NULL; 11968 isc_thread_yield(); 11969 goto again; 11970 } 11971 } 11972 11973 /* 11974 * If there is a secure version of this zone 11975 * use its serial if it is less than ours. 11976 */ 11977 if (tresult == ISC_R_SUCCESS && secure != NULL) { 11978 uint32_t sserial; 11979 isc_result_t mresult; 11980 11981 ZONEDB_LOCK(&secure->dblock, isc_rwlocktype_read); 11982 if (secure->db != NULL) { 11983 mresult = dns_db_getsoaserial(zone->secure->db, 11984 NULL, &sserial); 11985 if (mresult == ISC_R_SUCCESS && 11986 isc_serial_lt(sserial, serial)) 11987 { 11988 serial = sserial; 11989 } 11990 } 11991 ZONEDB_UNLOCK(&secure->dblock, isc_rwlocktype_read); 11992 } 11993 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) { 11994 dns_db_t *zdb = NULL; 11995 if (dns_zone_getdb(zone, &zdb) == ISC_R_SUCCESS) { 11996 zone_journal_compact(zone, zdb, serial); 11997 dns_db_detach(&zdb); 11998 } 11999 } else if (tresult == ISC_R_SUCCESS) { 12000 compact = true; 12001 zone->compact_serial = serial; 12002 } 12003 if (secure != NULL) { 12004 UNLOCK_ZONE(secure); 12005 } 12006 UNLOCK_ZONE(zone); 12007 } 12008 12009 LOCK_ZONE(zone); 12010 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 12011 if (compact) { 12012 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 12013 } 12014 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN)) { 12015 /* 12016 * If DNS_ZONEFLG_SHUTDOWN is set, all external references to 12017 * the zone are gone, which means it is in the process of being 12018 * cleaned up, so do not reschedule dumping. 12019 * 12020 * Detach from the raw version of the zone in case this 12021 * operation has been deferred in zone_shutdown(). 12022 */ 12023 if (zone->raw != NULL) { 12024 dns_zone_detach(&zone->raw); 12025 } 12026 if (result == ISC_R_SUCCESS) { 12027 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 12028 } 12029 } else if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) { 12030 /* 12031 * Try again in a short while. 12032 */ 12033 zone_needdump(zone, DNS_DUMP_DELAY); 12034 } else if (result == ISC_R_SUCCESS && 12035 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 12036 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 12037 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 12038 { 12039 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 12040 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 12041 isc_time_settoepoch(&zone->dumptime); 12042 again = true; 12043 } else if (result == ISC_R_SUCCESS) { 12044 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 12045 } 12046 12047 if (zone->dumpctx != NULL) { 12048 dns_dumpctx_detach(&zone->dumpctx); 12049 } 12050 UNLOCK_ZONE(zone); 12051 if (again) { 12052 (void)zone_dump(zone, false); 12053 } 12054 dns_zone_idetach(&zone); 12055 } 12056 12057 static isc_result_t 12058 zone_dump(dns_zone_t *zone, bool compact) { 12059 isc_result_t result; 12060 dns_dbversion_t *version = NULL; 12061 bool again = false; 12062 dns_db_t *db = NULL; 12063 char *masterfile = NULL; 12064 dns_masterformat_t masterformat = dns_masterformat_none; 12065 const dns_master_style_t *masterstyle = NULL; 12066 dns_masterrawheader_t rawdata; 12067 12068 /* 12069 * 'compact' MUST only be set if we are loop locked. 12070 */ 12071 12072 REQUIRE(DNS_ZONE_VALID(zone)); 12073 ENTER; 12074 12075 redo: 12076 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12077 if (zone->db != NULL) { 12078 dns_db_attach(zone->db, &db); 12079 } 12080 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12081 LOCK_ZONE(zone); 12082 if (zone->masterfile != NULL) { 12083 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile); 12084 masterformat = zone->masterformat; 12085 } 12086 if (zone->type == dns_zone_key) { 12087 masterstyle = &dns_master_style_keyzone; 12088 } else if (zone->masterstyle != NULL) { 12089 masterstyle = zone->masterstyle; 12090 } else { 12091 masterstyle = &dns_master_style_default; 12092 } 12093 UNLOCK_ZONE(zone); 12094 if (db == NULL) { 12095 result = DNS_R_NOTLOADED; 12096 goto fail; 12097 } 12098 if (masterfile == NULL) { 12099 result = DNS_R_NOMASTERFILE; 12100 goto fail; 12101 } 12102 12103 dns_db_currentversion(db, &version); 12104 12105 dns_master_initrawheader(&rawdata); 12106 12107 if (inline_secure(zone)) { 12108 get_raw_serial(zone->raw, &rawdata); 12109 } 12110 12111 if (compact && zone->type != dns_zone_stub) { 12112 LOCK_ZONE(zone); 12113 zone_iattach(zone, &(dns_zone_t *){ NULL }); 12114 12115 INSIST(zone != zone->raw); 12116 12117 result = dns_master_dumpasync( 12118 zone->mctx, db, version, masterstyle, masterfile, 12119 zone->loop, dump_done, zone, &zone->dumpctx, 12120 masterformat, &rawdata); 12121 12122 UNLOCK_ZONE(zone); 12123 if (result != ISC_R_SUCCESS) { 12124 dns_zone_idetach(&(dns_zone_t *){ zone }); 12125 goto fail; 12126 } 12127 result = DNS_R_CONTINUE; 12128 } else { 12129 result = dns_master_dump(zone->mctx, db, version, masterstyle, 12130 masterfile, masterformat, &rawdata); 12131 if ((zone->type == dns_zone_secondary || 12132 zone->type == dns_zone_mirror || 12133 zone->type == dns_zone_redirect) && 12134 result == ISC_R_SUCCESS) 12135 { 12136 isc_time_t when; 12137 isc_interval_t i; 12138 isc_interval_set(&i, zone->expire, 0); 12139 result = isc_time_subtract(&zone->expiretime, &i, 12140 &when); 12141 if (result == ISC_R_SUCCESS) { 12142 (void)isc_file_settime(zone->masterfile, &when); 12143 } else { 12144 result = ISC_R_SUCCESS; 12145 } 12146 } 12147 } 12148 fail: 12149 if (version != NULL) { 12150 dns_db_closeversion(db, &version, false); 12151 } 12152 if (db != NULL) { 12153 dns_db_detach(&db); 12154 } 12155 if (masterfile != NULL) { 12156 isc_mem_free(zone->mctx, masterfile); 12157 masterfile = NULL; 12158 } 12159 12160 if (result == DNS_R_CONTINUE) { 12161 /* 12162 * Asyncronous write is in progress. Zone flags will get 12163 * updated on completion. Cleanup is complete. We are done. 12164 */ 12165 return ISC_R_SUCCESS; 12166 } 12167 12168 again = false; 12169 LOCK_ZONE(zone); 12170 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 12171 if (result != ISC_R_SUCCESS) { 12172 /* 12173 * Try again in a short while. 12174 */ 12175 zone_needdump(zone, DNS_DUMP_DELAY); 12176 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 12177 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 12178 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 12179 { 12180 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 12181 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 12182 isc_time_settoepoch(&zone->dumptime); 12183 again = true; 12184 } else { 12185 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 12186 } 12187 UNLOCK_ZONE(zone); 12188 if (again) { 12189 goto redo; 12190 } 12191 12192 return result; 12193 } 12194 12195 static isc_result_t 12196 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style, 12197 dns_masterformat_t format, const uint32_t rawversion) { 12198 isc_result_t result; 12199 dns_dbversion_t *version = NULL; 12200 dns_db_t *db = NULL; 12201 dns_masterrawheader_t rawdata; 12202 12203 REQUIRE(DNS_ZONE_VALID(zone)); 12204 12205 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12206 if (zone->db != NULL) { 12207 dns_db_attach(zone->db, &db); 12208 } 12209 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12210 if (db == NULL) { 12211 return DNS_R_NOTLOADED; 12212 } 12213 12214 dns_db_currentversion(db, &version); 12215 dns_master_initrawheader(&rawdata); 12216 if (rawversion == 0) { 12217 rawdata.flags |= DNS_MASTERRAW_COMPAT; 12218 } else if (inline_secure(zone)) { 12219 get_raw_serial(zone->raw, &rawdata); 12220 } else if (zone->sourceserialset) { 12221 rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET; 12222 rawdata.sourceserial = zone->sourceserial; 12223 } 12224 result = dns_master_dumptostream(zone->mctx, db, version, style, format, 12225 &rawdata, fd); 12226 dns_db_closeversion(db, &version, false); 12227 dns_db_detach(&db); 12228 return result; 12229 } 12230 12231 isc_result_t 12232 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, 12233 const dns_master_style_t *style, 12234 const uint32_t rawversion) { 12235 return dumptostream(zone, fd, style, format, rawversion); 12236 } 12237 12238 void 12239 dns_zone_unload(dns_zone_t *zone) { 12240 REQUIRE(DNS_ZONE_VALID(zone)); 12241 12242 LOCK_ZONE(zone); 12243 zone_unload(zone); 12244 UNLOCK_ZONE(zone); 12245 } 12246 12247 static void 12248 notify_cancel(dns_zone_t *zone) { 12249 dns_notify_t *notify; 12250 12251 /* 12252 * 'zone' locked by caller. 12253 */ 12254 12255 REQUIRE(LOCKED_ZONE(zone)); 12256 12257 for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL; 12258 notify = ISC_LIST_NEXT(notify, link)) 12259 { 12260 if (notify->find != NULL) { 12261 dns_adb_cancelfind(notify->find); 12262 } 12263 if (notify->request != NULL) { 12264 dns_request_cancel(notify->request); 12265 } 12266 } 12267 } 12268 12269 static void 12270 checkds_cancel(dns_zone_t *zone) { 12271 dns_checkds_t *checkds; 12272 12273 /* 12274 * 'zone' locked by caller. 12275 */ 12276 12277 REQUIRE(LOCKED_ZONE(zone)); 12278 12279 for (checkds = ISC_LIST_HEAD(zone->checkds_requests); checkds != NULL; 12280 checkds = ISC_LIST_NEXT(checkds, link)) 12281 { 12282 if (checkds->find != NULL) { 12283 dns_adb_cancelfind(checkds->find); 12284 } 12285 if (checkds->request != NULL) { 12286 dns_request_cancel(checkds->request); 12287 } 12288 } 12289 } 12290 12291 static void 12292 forward_cancel(dns_zone_t *zone) { 12293 dns_forward_t *forward; 12294 12295 /* 12296 * 'zone' locked by caller. 12297 */ 12298 12299 REQUIRE(LOCKED_ZONE(zone)); 12300 12301 for (forward = ISC_LIST_HEAD(zone->forwards); forward != NULL; 12302 forward = ISC_LIST_NEXT(forward, link)) 12303 { 12304 if (forward->request != NULL) { 12305 dns_request_cancel(forward->request); 12306 } 12307 } 12308 } 12309 12310 static void 12311 zone_unload(dns_zone_t *zone) { 12312 /* 12313 * 'zone' locked by caller. 12314 */ 12315 12316 REQUIRE(LOCKED_ZONE(zone)); 12317 12318 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 12319 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 12320 { 12321 if (zone->dumpctx != NULL) { 12322 dns_dumpctx_cancel(zone->dumpctx); 12323 } 12324 } 12325 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 12326 zone_detachdb(zone); 12327 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 12328 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED); 12329 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 12330 12331 if (zone->type == dns_zone_mirror) { 12332 dns_zone_log(zone, ISC_LOG_INFO, 12333 "mirror zone is no longer in use; " 12334 "reverting to normal recursion"); 12335 } 12336 } 12337 12338 void 12339 dns_zone_setminrefreshtime(dns_zone_t *zone, uint32_t val) { 12340 REQUIRE(DNS_ZONE_VALID(zone)); 12341 REQUIRE(val > 0); 12342 12343 zone->minrefresh = val; 12344 } 12345 12346 void 12347 dns_zone_setmaxrefreshtime(dns_zone_t *zone, uint32_t val) { 12348 REQUIRE(DNS_ZONE_VALID(zone)); 12349 REQUIRE(val > 0); 12350 12351 zone->maxrefresh = val; 12352 } 12353 12354 void 12355 dns_zone_setminretrytime(dns_zone_t *zone, uint32_t val) { 12356 REQUIRE(DNS_ZONE_VALID(zone)); 12357 REQUIRE(val > 0); 12358 12359 zone->minretry = val; 12360 } 12361 12362 void 12363 dns_zone_setmaxretrytime(dns_zone_t *zone, uint32_t val) { 12364 REQUIRE(DNS_ZONE_VALID(zone)); 12365 REQUIRE(val > 0); 12366 12367 zone->maxretry = val; 12368 } 12369 12370 uint32_t 12371 dns_zone_getmaxrecords(dns_zone_t *zone) { 12372 REQUIRE(DNS_ZONE_VALID(zone)); 12373 12374 return zone->maxrecords; 12375 } 12376 12377 void 12378 dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) { 12379 REQUIRE(DNS_ZONE_VALID(zone)); 12380 12381 zone->maxrecords = val; 12382 } 12383 12384 void 12385 dns_zone_setmaxrrperset(dns_zone_t *zone, uint32_t val) { 12386 REQUIRE(DNS_ZONE_VALID(zone)); 12387 12388 zone->maxrrperset = val; 12389 if (zone->db != NULL) { 12390 dns_db_setmaxrrperset(zone->db, val); 12391 } 12392 } 12393 12394 void 12395 dns_zone_setmaxtypepername(dns_zone_t *zone, uint32_t val) { 12396 REQUIRE(DNS_ZONE_VALID(zone)); 12397 12398 zone->maxtypepername = val; 12399 if (zone->db != NULL) { 12400 dns_db_setmaxtypepername(zone->db, val); 12401 } 12402 } 12403 12404 static bool 12405 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name, 12406 isc_sockaddr_t *addr, dns_tsigkey_t *key, 12407 dns_transport_t *transport) { 12408 dns_notify_t *notify; 12409 dns_zonemgr_t *zmgr; 12410 isc_result_t result; 12411 12412 for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL; 12413 notify = ISC_LIST_NEXT(notify, link)) 12414 { 12415 if (notify->request != NULL) { 12416 continue; 12417 } 12418 if (name != NULL && dns_name_dynamic(¬ify->ns) && 12419 dns_name_equal(name, ¬ify->ns)) 12420 { 12421 goto requeue; 12422 } 12423 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst) && 12424 notify->key == key && notify->transport == transport) 12425 { 12426 goto requeue; 12427 } 12428 } 12429 return false; 12430 12431 requeue: 12432 /* 12433 * If we are enqueued on the startup ratelimiter and this is 12434 * not a startup notify, re-enqueue on the normal notify 12435 * ratelimiter. 12436 */ 12437 if (notify->rlevent != NULL && (flags & DNS_NOTIFY_STARTUP) == 0 && 12438 (notify->flags & DNS_NOTIFY_STARTUP) != 0) 12439 { 12440 zmgr = notify->zone->zmgr; 12441 result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl, 12442 ¬ify->rlevent); 12443 if (result != ISC_R_SUCCESS) { 12444 return true; 12445 } 12446 12447 notify->flags &= ~DNS_NOTIFY_STARTUP; 12448 result = isc_ratelimiter_enqueue( 12449 notify->zone->zmgr->notifyrl, notify->zone->loop, 12450 notify_send_toaddr, notify, ¬ify->rlevent); 12451 if (result != ISC_R_SUCCESS) { 12452 return false; 12453 } 12454 } 12455 12456 return true; 12457 } 12458 12459 static bool 12460 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) { 12461 dns_tsigkey_t *key = NULL; 12462 isc_sockaddr_t src; 12463 isc_sockaddr_t any; 12464 bool isself; 12465 isc_netaddr_t dstaddr; 12466 isc_result_t result; 12467 12468 if (zone->view == NULL || zone->isself == NULL) { 12469 return false; 12470 } 12471 12472 switch (isc_sockaddr_pf(dst)) { 12473 case PF_INET: 12474 src = zone->notifysrc4; 12475 isc_sockaddr_any(&any); 12476 break; 12477 case PF_INET6: 12478 src = zone->notifysrc6; 12479 isc_sockaddr_any6(&any); 12480 break; 12481 default: 12482 return false; 12483 } 12484 12485 /* 12486 * When sending from any the kernel will assign a source address 12487 * that matches the destination address. 12488 */ 12489 if (isc_sockaddr_eqaddr(&any, &src)) { 12490 src = *dst; 12491 } 12492 12493 isc_netaddr_fromsockaddr(&dstaddr, dst); 12494 result = dns_view_getpeertsig(zone->view, &dstaddr, &key); 12495 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 12496 return false; 12497 } 12498 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass, 12499 zone->isselfarg); 12500 if (key != NULL) { 12501 dns_tsigkey_detach(&key); 12502 } 12503 return isself; 12504 } 12505 12506 static void 12507 notify_destroy(dns_notify_t *notify, bool locked) { 12508 isc_mem_t *mctx; 12509 12510 REQUIRE(DNS_NOTIFY_VALID(notify)); 12511 12512 if (notify->zone != NULL) { 12513 if (!locked) { 12514 LOCK_ZONE(notify->zone); 12515 } 12516 REQUIRE(LOCKED_ZONE(notify->zone)); 12517 if (ISC_LINK_LINKED(notify, link)) { 12518 ISC_LIST_UNLINK(notify->zone->notifies, notify, link); 12519 } 12520 if (!locked) { 12521 UNLOCK_ZONE(notify->zone); 12522 } 12523 if (locked) { 12524 zone_idetach(¬ify->zone); 12525 } else { 12526 dns_zone_idetach(¬ify->zone); 12527 } 12528 } 12529 if (notify->find != NULL) { 12530 dns_adb_destroyfind(¬ify->find); 12531 } 12532 if (notify->request != NULL) { 12533 dns_request_destroy(¬ify->request); 12534 } 12535 if (dns_name_dynamic(¬ify->ns)) { 12536 dns_name_free(¬ify->ns, notify->mctx); 12537 } 12538 if (notify->key != NULL) { 12539 dns_tsigkey_detach(¬ify->key); 12540 } 12541 if (notify->transport != NULL) { 12542 dns_transport_detach(¬ify->transport); 12543 } 12544 mctx = notify->mctx; 12545 isc_mem_put(notify->mctx, notify, sizeof(*notify)); 12546 isc_mem_detach(&mctx); 12547 } 12548 12549 static isc_result_t 12550 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) { 12551 dns_notify_t *notify; 12552 12553 REQUIRE(notifyp != NULL && *notifyp == NULL); 12554 12555 notify = isc_mem_get(mctx, sizeof(*notify)); 12556 *notify = (dns_notify_t){ 12557 .flags = flags, 12558 }; 12559 12560 isc_mem_attach(mctx, ¬ify->mctx); 12561 isc_sockaddr_any(¬ify->src); 12562 isc_sockaddr_any(¬ify->dst); 12563 dns_name_init(¬ify->ns, NULL); 12564 ISC_LINK_INIT(notify, link); 12565 notify->magic = NOTIFY_MAGIC; 12566 *notifyp = notify; 12567 return ISC_R_SUCCESS; 12568 } 12569 12570 /* 12571 * XXXAG should check for DNS_ZONEFLG_EXITING 12572 */ 12573 static void 12574 process_notify_adb_event(void *arg) { 12575 dns_adbfind_t *find = (dns_adbfind_t *)arg; 12576 dns_notify_t *notify = (dns_notify_t *)find->cbarg; 12577 dns_adbstatus_t astat = find->status; 12578 12579 REQUIRE(DNS_NOTIFY_VALID(notify)); 12580 REQUIRE(find == notify->find); 12581 12582 switch (astat) { 12583 case DNS_ADB_MOREADDRESSES: 12584 dns_adb_destroyfind(¬ify->find); 12585 notify_find_address(notify); 12586 return; 12587 12588 case DNS_ADB_NOMOREADDRESSES: 12589 LOCK_ZONE(notify->zone); 12590 notify_send(notify); 12591 UNLOCK_ZONE(notify->zone); 12592 break; 12593 12594 default: 12595 break; 12596 } 12597 12598 notify_destroy(notify, false); 12599 } 12600 12601 static void 12602 notify_find_address(dns_notify_t *notify) { 12603 isc_result_t result; 12604 unsigned int options; 12605 dns_adb_t *adb = NULL; 12606 12607 REQUIRE(DNS_NOTIFY_VALID(notify)); 12608 12609 options = DNS_ADBFIND_WANTEVENT; 12610 if (isc_net_probeipv4() != ISC_R_DISABLED) { 12611 options |= DNS_ADBFIND_INET; 12612 } 12613 if (isc_net_probeipv6() != ISC_R_DISABLED) { 12614 options |= DNS_ADBFIND_INET6; 12615 } 12616 12617 dns_view_getadb(notify->zone->view, &adb); 12618 if (adb == NULL) { 12619 goto destroy; 12620 } 12621 12622 result = dns_adb_createfind(adb, notify->zone->loop, 12623 process_notify_adb_event, notify, 12624 ¬ify->ns, dns_rootname, 0, options, 0, 12625 NULL, notify->zone->view->dstport, 0, NULL, 12626 NULL, NULL, ¬ify->find); 12627 dns_adb_detach(&adb); 12628 12629 /* Something failed? */ 12630 if (result != ISC_R_SUCCESS) { 12631 goto destroy; 12632 } 12633 12634 /* More addresses pending? */ 12635 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) { 12636 return; 12637 } 12638 12639 /* We have as many addresses as we can get. */ 12640 LOCK_ZONE(notify->zone); 12641 notify_send(notify); 12642 UNLOCK_ZONE(notify->zone); 12643 12644 destroy: 12645 notify_destroy(notify, false); 12646 } 12647 12648 static isc_result_t 12649 notify_send_queue(dns_notify_t *notify, bool startup) { 12650 return isc_ratelimiter_enqueue( 12651 startup ? notify->zone->zmgr->startupnotifyrl 12652 : notify->zone->zmgr->notifyrl, 12653 notify->zone->loop, notify_send_toaddr, notify, 12654 ¬ify->rlevent); 12655 } 12656 12657 static void 12658 notify_send_toaddr(void *arg) { 12659 dns_notify_t *notify = (dns_notify_t *)arg; 12660 isc_result_t result; 12661 dns_message_t *message = NULL; 12662 isc_netaddr_t dstip; 12663 dns_tsigkey_t *key = NULL; 12664 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 12665 isc_sockaddr_t src; 12666 unsigned int options, timeout, udptimeout; 12667 bool have_notifysource = false; 12668 isc_tlsctx_cache_t *zmgr_tlsctx_cache = NULL; 12669 12670 REQUIRE(DNS_NOTIFY_VALID(notify)); 12671 12672 LOCK_ZONE(notify->zone); 12673 12674 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 12675 12676 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0 || 12677 notify->rlevent->canceled || 12678 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) || 12679 notify->zone->view->requestmgr == NULL || notify->zone->db == NULL) 12680 { 12681 result = ISC_R_CANCELED; 12682 goto cleanup; 12683 } 12684 12685 /* 12686 * The raw IPv4 address should also exist. Don't send to the 12687 * mapped form. 12688 */ 12689 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 && 12690 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) 12691 { 12692 notify_log(notify->zone, ISC_LOG_DEBUG(3), 12693 "notify: ignoring IPv6 mapped IPV4 address: %s", 12694 addrbuf); 12695 result = ISC_R_CANCELED; 12696 goto cleanup; 12697 } 12698 12699 result = notify_createmessage(notify->zone, notify->flags, &message); 12700 if (result != ISC_R_SUCCESS) { 12701 goto cleanup; 12702 } 12703 12704 if (notify->key != NULL) { 12705 /* Transfer ownership of key */ 12706 key = notify->key; 12707 notify->key = NULL; 12708 } else { 12709 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst); 12710 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key); 12711 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 12712 notify_log(notify->zone, ISC_LOG_ERROR, 12713 "NOTIFY to %s not sent. " 12714 "Peer TSIG key lookup failure.", 12715 addrbuf); 12716 goto cleanup_message; 12717 } 12718 } 12719 12720 if (key != NULL) { 12721 char namebuf[DNS_NAME_FORMATSIZE]; 12722 12723 dns_name_format(key->name, namebuf, sizeof(namebuf)); 12724 notify_log(notify->zone, ISC_LOG_INFO, 12725 "sending notify to %s : TSIG (%s)", addrbuf, 12726 namebuf); 12727 } else { 12728 notify_log(notify->zone, ISC_LOG_INFO, "sending notify to %s", 12729 addrbuf); 12730 } 12731 options = 0; 12732 if (notify->zone->view->peers != NULL) { 12733 dns_peer_t *peer = NULL; 12734 bool usetcp = false; 12735 result = dns_peerlist_peerbyaddr(notify->zone->view->peers, 12736 &dstip, &peer); 12737 if (result == ISC_R_SUCCESS) { 12738 result = dns_peer_getnotifysource(peer, &src); 12739 if (result == ISC_R_SUCCESS) { 12740 have_notifysource = true; 12741 } 12742 result = dns_peer_getforcetcp(peer, &usetcp); 12743 if (result == ISC_R_SUCCESS && usetcp) { 12744 options |= DNS_FETCHOPT_TCP; 12745 } 12746 } 12747 } 12748 switch (isc_sockaddr_pf(¬ify->dst)) { 12749 case PF_INET: 12750 if (!have_notifysource) { 12751 isc_sockaddr_t any; 12752 isc_sockaddr_any(&any); 12753 12754 src = notify->src; 12755 if (isc_sockaddr_equal(&src, &any)) { 12756 src = notify->zone->notifysrc4; 12757 } 12758 } 12759 break; 12760 case PF_INET6: 12761 if (!have_notifysource) { 12762 isc_sockaddr_t any; 12763 isc_sockaddr_any6(&any); 12764 12765 src = notify->src; 12766 if (isc_sockaddr_equal(&src, &any)) { 12767 src = notify->zone->notifysrc6; 12768 } 12769 } 12770 break; 12771 default: 12772 result = ISC_R_NOTIMPLEMENTED; 12773 goto cleanup_key; 12774 } 12775 udptimeout = 5; 12776 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) { 12777 udptimeout = 30; 12778 } 12779 timeout = 3 * udptimeout + 1; 12780 again: 12781 if ((notify->flags & DNS_NOTIFY_TCP) != 0) { 12782 options |= DNS_REQUESTOPT_TCP; 12783 udptimeout = 0; 12784 timeout = 15; 12785 } 12786 12787 zmgr_tlsctx_attach(notify->zone->zmgr, &zmgr_tlsctx_cache); 12788 12789 result = dns_request_create(notify->zone->view->requestmgr, message, 12790 &src, ¬ify->dst, notify->transport, 12791 zmgr_tlsctx_cache, options, key, timeout, 12792 udptimeout, 2, notify->zone->loop, 12793 notify_done, notify, ¬ify->request); 12794 12795 isc_tlsctx_cache_detach(&zmgr_tlsctx_cache); 12796 12797 switch (result) { 12798 case ISC_R_SUCCESS: 12799 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) { 12800 inc_stats(notify->zone, 12801 dns_zonestatscounter_notifyoutv4); 12802 } else { 12803 inc_stats(notify->zone, 12804 dns_zonestatscounter_notifyoutv6); 12805 } 12806 break; 12807 case ISC_R_SHUTTINGDOWN: 12808 case ISC_R_CANCELED: 12809 case ISC_R_ADDRNOTAVAIL: 12810 case DNS_R_BLACKHOLED: 12811 case ISC_R_FAMILYNOSUPPORT: 12812 notify_log(notify->zone, ISC_LOG_NOTICE, 12813 "notify to %s failed: %s", addrbuf, 12814 isc_result_totext(result)); 12815 break; 12816 default: 12817 if ((notify->flags & DNS_NOTIFY_TCP) == 0) { 12818 notify_log(notify->zone, ISC_LOG_NOTICE, 12819 "notify to %s failed: %s: retrying over TCP", 12820 addrbuf, isc_result_totext(result)); 12821 notify->flags |= DNS_NOTIFY_TCP; 12822 goto again; 12823 } 12824 } 12825 12826 cleanup_key: 12827 if (key != NULL) { 12828 dns_tsigkey_detach(&key); 12829 } 12830 cleanup_message: 12831 dns_message_detach(&message); 12832 cleanup: 12833 UNLOCK_ZONE(notify->zone); 12834 if (notify->rlevent != NULL) { 12835 isc_rlevent_free(¬ify->rlevent); 12836 } 12837 12838 if (result != ISC_R_SUCCESS) { 12839 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 12840 notify_log(notify->zone, ISC_LOG_WARNING, 12841 "notify to %s failed: %s", addrbuf, 12842 isc_result_totext(result)); 12843 notify_destroy(notify, false); 12844 } 12845 } 12846 12847 static void 12848 notify_send(dns_notify_t *notify) { 12849 dns_adbaddrinfo_t *ai; 12850 isc_sockaddr_t dst; 12851 isc_result_t result; 12852 dns_notify_t *newnotify = NULL; 12853 unsigned int flags; 12854 bool startup; 12855 12856 /* 12857 * Zone lock held by caller. 12858 */ 12859 REQUIRE(DNS_NOTIFY_VALID(notify)); 12860 REQUIRE(LOCKED_ZONE(notify->zone)); 12861 12862 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING)) { 12863 return; 12864 } 12865 12866 for (ai = ISC_LIST_HEAD(notify->find->list); ai != NULL; 12867 ai = ISC_LIST_NEXT(ai, publink)) 12868 { 12869 dst = ai->sockaddr; 12870 if (notify_isqueued(notify->zone, notify->flags, NULL, &dst, 12871 NULL, NULL)) 12872 { 12873 continue; 12874 } 12875 if (notify_isself(notify->zone, &dst)) { 12876 continue; 12877 } 12878 newnotify = NULL; 12879 flags = notify->flags & DNS_NOTIFY_NOSOA; 12880 result = notify_create(notify->mctx, flags, &newnotify); 12881 if (result != ISC_R_SUCCESS) { 12882 goto cleanup; 12883 } 12884 zone_iattach(notify->zone, &newnotify->zone); 12885 ISC_LIST_APPEND(newnotify->zone->notifies, newnotify, link); 12886 newnotify->dst = dst; 12887 if (isc_sockaddr_pf(&dst) == AF_INET6) { 12888 isc_sockaddr_any6(&newnotify->src); 12889 } 12890 startup = ((notify->flags & DNS_NOTIFY_STARTUP) != 0); 12891 result = notify_send_queue(newnotify, startup); 12892 if (result != ISC_R_SUCCESS) { 12893 goto cleanup; 12894 } 12895 newnotify = NULL; 12896 } 12897 12898 cleanup: 12899 if (newnotify != NULL) { 12900 notify_destroy(newnotify, true); 12901 } 12902 } 12903 12904 void 12905 dns_zone_notify(dns_zone_t *zone, bool nodefer) { 12906 isc_time_t now; 12907 12908 REQUIRE(DNS_ZONE_VALID(zone)); 12909 12910 LOCK_ZONE(zone); 12911 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12912 if (nodefer) { 12913 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOTIFYDEFERRED)) { 12914 /* 12915 * We have previously deferred the notify, but we have a 12916 * new request not to defer it. Reverse the deferring 12917 * operation. 12918 */ 12919 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOTIFYDEFERRED); 12920 DNS_ZONE_TIME_SUBTRACT(&zone->notifytime, 12921 zone->notifydefer, 12922 &zone->notifytime); 12923 } 12924 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOTIFYNODEFER); 12925 } 12926 now = isc_time_now(); 12927 zone_settimer(zone, &now); 12928 UNLOCK_ZONE(zone); 12929 } 12930 12931 static void 12932 zone_notify(dns_zone_t *zone, isc_time_t *now) { 12933 dns_dbnode_t *node = NULL; 12934 dns_db_t *zonedb = NULL; 12935 dns_dbversion_t *version = NULL; 12936 dns_name_t *origin = NULL; 12937 dns_name_t primary; 12938 dns_rdata_ns_t ns; 12939 dns_rdata_soa_t soa; 12940 uint32_t serial; 12941 dns_rdata_t rdata = DNS_RDATA_INIT; 12942 dns_rdataset_t nsrdset; 12943 dns_rdataset_t soardset; 12944 isc_result_t result; 12945 isc_sockaddr_t src; 12946 isc_sockaddr_t dst; 12947 bool isqueued; 12948 dns_notifytype_t notifytype; 12949 unsigned int flags = 0; 12950 bool loggednotify = false; 12951 bool startup; 12952 12953 REQUIRE(DNS_ZONE_VALID(zone)); 12954 12955 LOCK_ZONE(zone); 12956 startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12957 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY | 12958 DNS_ZONEFLG_NEEDSTARTUPNOTIFY | 12959 DNS_ZONEFLG_NOTIFYNODEFER | 12960 DNS_ZONEFLG_NOTIFYDEFERRED); 12961 notifytype = zone->notifytype; 12962 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime); 12963 UNLOCK_ZONE(zone); 12964 12965 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || 12966 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 12967 { 12968 return; 12969 } 12970 12971 if (notifytype == dns_notifytype_no) { 12972 return; 12973 } 12974 12975 if (notifytype == dns_notifytype_masteronly && 12976 zone->type != dns_zone_primary) 12977 { 12978 return; 12979 } 12980 12981 origin = &zone->origin; 12982 12983 /* 12984 * If the zone is dialup we are done as we don't want to send 12985 * the current soa so as to force a refresh query. 12986 */ 12987 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) { 12988 flags |= DNS_NOTIFY_NOSOA; 12989 } 12990 12991 /* 12992 * Record that this was a notify due to starting up. 12993 */ 12994 if (startup) { 12995 flags |= DNS_NOTIFY_STARTUP; 12996 } 12997 12998 /* 12999 * Get SOA RRset. 13000 */ 13001 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 13002 if (zone->db != NULL) { 13003 dns_db_attach(zone->db, &zonedb); 13004 } 13005 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 13006 if (zonedb == NULL) { 13007 return; 13008 } 13009 dns_db_currentversion(zonedb, &version); 13010 result = dns_db_findnode(zonedb, origin, false, &node); 13011 if (result != ISC_R_SUCCESS) { 13012 goto cleanup1; 13013 } 13014 13015 dns_rdataset_init(&soardset); 13016 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, 13017 dns_rdatatype_none, 0, &soardset, NULL); 13018 if (result != ISC_R_SUCCESS) { 13019 goto cleanup2; 13020 } 13021 13022 /* 13023 * Find serial and primary server's name. 13024 */ 13025 dns_name_init(&primary, NULL); 13026 result = dns_rdataset_first(&soardset); 13027 if (result != ISC_R_SUCCESS) { 13028 goto cleanup3; 13029 } 13030 dns_rdataset_current(&soardset, &rdata); 13031 result = dns_rdata_tostruct(&rdata, &soa, NULL); 13032 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13033 dns_rdata_reset(&rdata); 13034 dns_name_dup(&soa.origin, zone->mctx, &primary); 13035 serial = soa.serial; 13036 dns_rdataset_disassociate(&soardset); 13037 13038 /* 13039 * Enqueue notify requests for 'also-notify' servers. 13040 */ 13041 LOCK_ZONE(zone); 13042 13043 dns_remote_reset(&zone->notify, false); 13044 while (!dns_remote_done(&zone->notify)) { 13045 dns_tsigkey_t *key = NULL; 13046 dns_transport_t *transport = NULL; 13047 dns_notify_t *notify = NULL; 13048 dns_view_t *view = dns_zone_getview(zone); 13049 13050 if (dns_remote_keyname(&zone->notify) != NULL) { 13051 dns_name_t *keyname = dns_remote_keyname(&zone->notify); 13052 (void)dns_view_gettsig(view, keyname, &key); 13053 } 13054 13055 if (dns_remote_tlsname(&zone->notify) != NULL) { 13056 dns_name_t *tlsname = dns_remote_tlsname(&zone->notify); 13057 result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, 13058 tlsname, &transport); 13059 13060 if (result == ISC_R_SUCCESS) { 13061 notify_log( 13062 zone, ISC_LOG_INFO, 13063 "got TLS configuration for a notify"); 13064 } else { 13065 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 13066 ISC_LOG_ERROR, 13067 "could not get TLS configuration " 13068 "for zone transfer: %s", 13069 isc_result_totext(result)); 13070 if (key != NULL) { 13071 dns_tsigkey_detach(&key); 13072 } 13073 goto next; 13074 } 13075 13076 flags |= DNS_NOTIFY_TCP; 13077 } 13078 13079 /* TODO: glue the transport to the notify */ 13080 13081 dst = dns_remote_curraddr(&zone->notify); 13082 src = dns_remote_sourceaddr(&zone->notify); 13083 INSIST(isc_sockaddr_pf(&src) == isc_sockaddr_pf(&dst)); 13084 13085 if (isc_sockaddr_disabled(&dst)) { 13086 if (key != NULL) { 13087 dns_tsigkey_detach(&key); 13088 } 13089 if (transport != NULL) { 13090 dns_transport_detach(&transport); 13091 } 13092 goto next; 13093 } 13094 13095 if (notify_isqueued(zone, flags, NULL, &dst, key, transport)) { 13096 if (key != NULL) { 13097 dns_tsigkey_detach(&key); 13098 } 13099 if (transport != NULL) { 13100 dns_transport_detach(&transport); 13101 } 13102 goto next; 13103 } 13104 13105 result = notify_create(zone->mctx, flags, ¬ify); 13106 if (result != ISC_R_SUCCESS) { 13107 if (key != NULL) { 13108 dns_tsigkey_detach(&key); 13109 } 13110 if (transport != NULL) { 13111 dns_transport_detach(&transport); 13112 } 13113 goto next; 13114 } 13115 13116 zone_iattach(zone, ¬ify->zone); 13117 notify->src = src; 13118 notify->dst = dst; 13119 13120 INSIST(notify->key == NULL); 13121 13122 if (key != NULL) { 13123 notify->key = key; 13124 key = NULL; 13125 } 13126 13127 INSIST(notify->transport == NULL); 13128 if (transport != NULL) { 13129 notify->transport = transport; 13130 transport = NULL; 13131 } 13132 13133 ISC_LIST_APPEND(zone->notifies, notify, link); 13134 result = notify_send_queue(notify, startup); 13135 if (result != ISC_R_SUCCESS) { 13136 notify_destroy(notify, true); 13137 } 13138 if (!loggednotify) { 13139 notify_log(zone, ISC_LOG_INFO, 13140 "sending notifies (serial %u)", serial); 13141 loggednotify = true; 13142 } 13143 next: 13144 flags &= ~DNS_NOTIFY_TCP; 13145 dns_remote_next(&zone->notify, false); 13146 } 13147 UNLOCK_ZONE(zone); 13148 13149 if (notifytype == dns_notifytype_explicit) { 13150 goto cleanup3; 13151 } 13152 13153 /* 13154 * Process NS RRset to generate notifies. 13155 */ 13156 13157 dns_rdataset_init(&nsrdset); 13158 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns, 13159 dns_rdatatype_none, 0, &nsrdset, NULL); 13160 if (result != ISC_R_SUCCESS) { 13161 goto cleanup3; 13162 } 13163 13164 result = dns_rdataset_first(&nsrdset); 13165 while (result == ISC_R_SUCCESS) { 13166 dns_notify_t *notify = NULL; 13167 13168 dns_rdataset_current(&nsrdset, &rdata); 13169 result = dns_rdata_tostruct(&rdata, &ns, NULL); 13170 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13171 dns_rdata_reset(&rdata); 13172 /* 13173 * Don't notify the primary server unless explicitly 13174 * configured to do so. 13175 */ 13176 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) && 13177 dns_name_compare(&primary, &ns.name) == 0) 13178 { 13179 result = dns_rdataset_next(&nsrdset); 13180 continue; 13181 } 13182 13183 if (!loggednotify) { 13184 notify_log(zone, ISC_LOG_INFO, 13185 "sending notifies (serial %u)", serial); 13186 loggednotify = true; 13187 } 13188 13189 LOCK_ZONE(zone); 13190 isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL, 13191 NULL); 13192 UNLOCK_ZONE(zone); 13193 if (isqueued) { 13194 result = dns_rdataset_next(&nsrdset); 13195 continue; 13196 } 13197 result = notify_create(zone->mctx, flags, ¬ify); 13198 if (result != ISC_R_SUCCESS) { 13199 continue; 13200 } 13201 dns_zone_iattach(zone, ¬ify->zone); 13202 dns_name_dup(&ns.name, zone->mctx, ¬ify->ns); 13203 LOCK_ZONE(zone); 13204 ISC_LIST_APPEND(zone->notifies, notify, link); 13205 UNLOCK_ZONE(zone); 13206 notify_find_address(notify); 13207 result = dns_rdataset_next(&nsrdset); 13208 } 13209 dns_rdataset_disassociate(&nsrdset); 13210 13211 cleanup3: 13212 if (dns_name_dynamic(&primary)) { 13213 dns_name_free(&primary, zone->mctx); 13214 } 13215 cleanup2: 13216 dns_db_detachnode(zonedb, &node); 13217 cleanup1: 13218 dns_db_closeversion(zonedb, &version, false); 13219 dns_db_detach(&zonedb); 13220 } 13221 13222 /*** 13223 *** Private 13224 ***/ 13225 static void 13226 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, dns_name_t *name, 13227 dns_message_t **messagep) { 13228 dns_message_t *message = NULL; 13229 dns_name_t *qname = NULL; 13230 dns_rdataset_t *qrdataset = NULL; 13231 13232 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, 13233 &message); 13234 13235 message->opcode = dns_opcode_query; 13236 message->rdclass = zone->rdclass; 13237 13238 dns_message_gettempname(message, &qname); 13239 13240 dns_message_gettemprdataset(message, &qrdataset); 13241 13242 /* 13243 * Make question. 13244 */ 13245 dns_name_clone(name, qname); 13246 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype); 13247 ISC_LIST_APPEND(qname->list, qrdataset, link); 13248 dns_message_addname(message, qname, DNS_SECTION_QUESTION); 13249 13250 *messagep = message; 13251 } 13252 13253 static isc_result_t 13254 add_opt(dns_message_t *message, uint16_t udpsize, bool reqnsid, 13255 bool reqexpire) { 13256 isc_result_t result; 13257 dns_rdataset_t *rdataset = NULL; 13258 dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS]; 13259 int count = 0; 13260 13261 /* Set EDNS options if applicable. */ 13262 if (reqnsid) { 13263 INSIST(count < DNS_EDNSOPTIONS); 13264 ednsopts[count].code = DNS_OPT_NSID; 13265 ednsopts[count].length = 0; 13266 ednsopts[count].value = NULL; 13267 count++; 13268 } 13269 if (reqexpire) { 13270 INSIST(count < DNS_EDNSOPTIONS); 13271 ednsopts[count].code = DNS_OPT_EXPIRE; 13272 ednsopts[count].length = 0; 13273 ednsopts[count].value = NULL; 13274 count++; 13275 } 13276 result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0, 13277 ednsopts, count); 13278 if (result != ISC_R_SUCCESS) { 13279 return result; 13280 } 13281 13282 return dns_message_setopt(message, rdataset); 13283 } 13284 13285 /* 13286 * Called when stub zone update is finished. 13287 * Update zone refresh, retry, expire values accordingly with 13288 * SOA received from primary, sync database to file, restart 13289 * zone management timer. 13290 */ 13291 static void 13292 stub_finish_zone_update(dns_stub_t *stub, isc_time_t now) { 13293 uint32_t refresh, retry, expire; 13294 isc_result_t result; 13295 isc_interval_t i; 13296 unsigned int soacount; 13297 dns_zone_t *zone = stub->zone; 13298 13299 /* 13300 * Tidy up. 13301 */ 13302 dns_db_closeversion(stub->db, &stub->version, true); 13303 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 13304 if (zone->db == NULL) { 13305 zone_attachdb(zone, stub->db); 13306 } 13307 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, NULL, 13308 &refresh, &retry, &expire, NULL, NULL); 13309 if (result == ISC_R_SUCCESS && soacount > 0U) { 13310 zone->refresh = RANGE(refresh, zone->minrefresh, 13311 zone->maxrefresh); 13312 zone->retry = RANGE(retry, zone->minretry, zone->maxretry); 13313 zone->expire = RANGE(expire, zone->refresh + zone->retry, 13314 DNS_MAX_EXPIRE); 13315 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 13316 } 13317 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 13318 dns_db_detach(&stub->db); 13319 13320 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 13321 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 13322 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 13323 isc_interval_set(&i, zone->expire, 0); 13324 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); 13325 13326 if (zone->masterfile != NULL) { 13327 zone_needdump(zone, 0); 13328 } 13329 13330 zone_settimer(zone, &now); 13331 } 13332 13333 /* 13334 * Process answers for A and AAAA queries when 13335 * resolving nameserver addresses for which glue 13336 * was missing in a previous answer for a NS query. 13337 */ 13338 static void 13339 stub_glue_response(void *arg) { 13340 dns_request_t *request = (dns_request_t *)arg; 13341 struct stub_glue_request *sgr = dns_request_getarg(request); 13342 struct stub_cb_args *cb_args = sgr->args; 13343 dns_stub_t *stub = cb_args->stub; 13344 dns_message_t *msg = NULL; 13345 dns_zone_t *zone = NULL; 13346 char primary[ISC_SOCKADDR_FORMATSIZE]; 13347 char source[ISC_SOCKADDR_FORMATSIZE]; 13348 uint32_t addr_count, cnamecnt; 13349 isc_result_t result; 13350 isc_sockaddr_t curraddr; 13351 isc_time_t now; 13352 dns_rdataset_t *addr_rdataset = NULL; 13353 dns_dbnode_t *node = NULL; 13354 13355 INSIST(DNS_STUB_VALID(stub)); 13356 13357 zone = stub->zone; 13358 13359 ENTER; 13360 13361 now = isc_time_now(); 13362 13363 LOCK_ZONE(zone); 13364 13365 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 13366 zone_debuglog(zone, __func__, 1, "exiting"); 13367 goto cleanup; 13368 } 13369 13370 curraddr = dns_remote_curraddr(&zone->primaries); 13371 isc_sockaddr_format(&curraddr, primary, sizeof(primary)); 13372 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 13373 13374 if (dns_request_getresult(request) != ISC_R_SUCCESS) { 13375 dns_zonemgr_unreachableadd(zone->zmgr, &curraddr, 13376 &zone->sourceaddr, &now); 13377 dns_zone_log(zone, ISC_LOG_INFO, 13378 "could not refresh stub from primary %s" 13379 " (source %s): %s", 13380 primary, source, 13381 isc_result_totext(dns_request_getresult(request))); 13382 goto cleanup; 13383 } 13384 13385 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, 13386 &msg); 13387 result = dns_request_getresponse(request, msg, 0); 13388 if (result != ISC_R_SUCCESS) { 13389 dns_zone_log(zone, ISC_LOG_INFO, 13390 "refreshing stub: unable to parse response (%s)", 13391 isc_result_totext(result)); 13392 goto cleanup; 13393 } 13394 13395 /* 13396 * Unexpected opcode. 13397 */ 13398 if (msg->opcode != dns_opcode_query) { 13399 char opcode[128]; 13400 isc_buffer_t rb; 13401 13402 isc_buffer_init(&rb, opcode, sizeof(opcode)); 13403 (void)dns_opcode_totext(msg->opcode, &rb); 13404 13405 dns_zone_log(zone, ISC_LOG_INFO, 13406 "refreshing stub: " 13407 "unexpected opcode (%.*s) from %s (source %s)", 13408 (int)rb.used, opcode, primary, source); 13409 goto cleanup; 13410 } 13411 13412 /* 13413 * Unexpected rcode. 13414 */ 13415 if (msg->rcode != dns_rcode_noerror) { 13416 char rcode[128]; 13417 isc_buffer_t rb; 13418 13419 isc_buffer_init(&rb, rcode, sizeof(rcode)); 13420 (void)dns_rcode_totext(msg->rcode, &rb); 13421 13422 dns_zone_log(zone, ISC_LOG_INFO, 13423 "refreshing stub: " 13424 "unexpected rcode (%.*s) from %s (source %s)", 13425 (int)rb.used, rcode, primary, source); 13426 goto cleanup; 13427 } 13428 13429 /* 13430 * We need complete messages. 13431 */ 13432 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 13433 if (dns_request_usedtcp(request)) { 13434 dns_zone_log(zone, ISC_LOG_INFO, 13435 "refreshing stub: truncated TCP " 13436 "response from primary %s (source %s)", 13437 primary, source); 13438 } 13439 goto cleanup; 13440 } 13441 13442 /* 13443 * If non-auth log. 13444 */ 13445 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 13446 dns_zone_log(zone, ISC_LOG_INFO, 13447 "refreshing stub: " 13448 "non-authoritative answer from " 13449 "primary %s (source %s)", 13450 primary, source); 13451 goto cleanup; 13452 } 13453 13454 /* 13455 * Sanity checks. 13456 */ 13457 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 13458 addr_count = message_count(msg, DNS_SECTION_ANSWER, 13459 sgr->ipv4 ? dns_rdatatype_a 13460 : dns_rdatatype_aaaa); 13461 13462 if (cnamecnt != 0) { 13463 dns_zone_log(zone, ISC_LOG_INFO, 13464 "refreshing stub: unexpected CNAME response " 13465 "from primary %s (source %s)", 13466 primary, source); 13467 goto cleanup; 13468 } 13469 13470 if (addr_count == 0) { 13471 dns_zone_log(zone, ISC_LOG_INFO, 13472 "refreshing stub: no %s records in response " 13473 "from primary %s (source %s)", 13474 sgr->ipv4 ? "A" : "AAAA", primary, source); 13475 goto cleanup; 13476 } 13477 /* 13478 * Extract A or AAAA RRset from message. 13479 */ 13480 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &sgr->name, 13481 sgr->ipv4 ? dns_rdatatype_a 13482 : dns_rdatatype_aaaa, 13483 dns_rdatatype_none, NULL, &addr_rdataset); 13484 if (result != ISC_R_SUCCESS) { 13485 if (result != DNS_R_NXDOMAIN && result != DNS_R_NXRRSET) { 13486 char namebuf[DNS_NAME_FORMATSIZE]; 13487 dns_name_format(&sgr->name, namebuf, sizeof(namebuf)); 13488 dns_zone_log( 13489 zone, ISC_LOG_INFO, 13490 "refreshing stub: dns_message_findname(%s/%s) " 13491 "failed (%s)", 13492 namebuf, sgr->ipv4 ? "A" : "AAAA", 13493 isc_result_totext(result)); 13494 } 13495 goto cleanup; 13496 } 13497 13498 result = dns_db_findnode(stub->db, &sgr->name, true, &node); 13499 if (result != ISC_R_SUCCESS) { 13500 dns_zone_log(zone, ISC_LOG_INFO, 13501 "refreshing stub: " 13502 "dns_db_findnode() failed: %s", 13503 isc_result_totext(result)); 13504 goto cleanup; 13505 } 13506 13507 result = dns_db_addrdataset(stub->db, node, stub->version, 0, 13508 addr_rdataset, 0, NULL); 13509 if (result != ISC_R_SUCCESS) { 13510 dns_zone_log(zone, ISC_LOG_INFO, 13511 "refreshing stub: " 13512 "dns_db_addrdataset() failed: %s", 13513 isc_result_totext(result)); 13514 } 13515 dns_db_detachnode(stub->db, &node); 13516 13517 cleanup: 13518 if (msg != NULL) { 13519 dns_message_detach(&msg); 13520 } 13521 13522 dns_name_free(&sgr->name, zone->mctx); 13523 dns_request_destroy(&sgr->request); 13524 isc_mem_put(zone->mctx, sgr, sizeof(*sgr)); 13525 13526 /* If last request, release all related resources */ 13527 if (atomic_fetch_sub_release(&stub->pending_requests, 1) == 1) { 13528 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13529 stub_finish_zone_update(stub, now); 13530 UNLOCK_ZONE(zone); 13531 stub->magic = 0; 13532 dns_zone_idetach(&stub->zone); 13533 INSIST(stub->db == NULL); 13534 INSIST(stub->version == NULL); 13535 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 13536 } else { 13537 UNLOCK_ZONE(zone); 13538 } 13539 } 13540 13541 /* 13542 * Create and send an A or AAAA query to the primary 13543 * server of the stub zone given. 13544 */ 13545 static isc_result_t 13546 stub_request_nameserver_address(struct stub_cb_args *args, bool ipv4, 13547 const dns_name_t *name) { 13548 dns_message_t *message = NULL; 13549 dns_zone_t *zone; 13550 isc_result_t result; 13551 struct stub_glue_request *sgr; 13552 isc_sockaddr_t curraddr; 13553 13554 zone = args->stub->zone; 13555 sgr = isc_mem_get(zone->mctx, sizeof(*sgr)); 13556 *sgr = (struct stub_glue_request){ 13557 .args = args, 13558 .name = (dns_name_t)DNS_NAME_INITEMPTY, 13559 .ipv4 = ipv4, 13560 }; 13561 13562 dns_name_dup(name, zone->mctx, &sgr->name); 13563 13564 create_query(zone, ipv4 ? dns_rdatatype_a : dns_rdatatype_aaaa, 13565 &sgr->name, &message); 13566 13567 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 13568 result = add_opt(message, args->udpsize, args->reqnsid, false); 13569 if (result != ISC_R_SUCCESS) { 13570 zone_debuglog(zone, __func__, 1, 13571 "unable to add opt record: %s", 13572 isc_result_totext(result)); 13573 goto fail; 13574 } 13575 } 13576 13577 atomic_fetch_add_release(&args->stub->pending_requests, 1); 13578 13579 curraddr = dns_remote_curraddr(&zone->primaries); 13580 result = dns_request_create( 13581 zone->view->requestmgr, message, &zone->sourceaddr, &curraddr, 13582 NULL, NULL, DNS_REQUESTOPT_TCP, args->tsig_key, 13583 args->timeout * 3, args->timeout, 2, zone->loop, 13584 stub_glue_response, sgr, &sgr->request); 13585 13586 if (result != ISC_R_SUCCESS) { 13587 uint_fast32_t pr; 13588 pr = atomic_fetch_sub_release(&args->stub->pending_requests, 1); 13589 INSIST(pr > 1); 13590 zone_debuglog(zone, __func__, 1, 13591 "dns_request_create() failed: %s", 13592 isc_result_totext(result)); 13593 goto fail; 13594 } 13595 13596 dns_message_detach(&message); 13597 13598 return ISC_R_SUCCESS; 13599 13600 fail: 13601 dns_name_free(&sgr->name, zone->mctx); 13602 isc_mem_put(zone->mctx, sgr, sizeof(*sgr)); 13603 13604 if (message != NULL) { 13605 dns_message_detach(&message); 13606 } 13607 13608 return result; 13609 } 13610 13611 static isc_result_t 13612 save_nsrrset(dns_message_t *message, dns_name_t *name, 13613 struct stub_cb_args *cb_args, dns_db_t *db, 13614 dns_dbversion_t *version) { 13615 dns_rdataset_t *nsrdataset = NULL; 13616 dns_rdataset_t *rdataset = NULL; 13617 dns_dbnode_t *node = NULL; 13618 dns_rdata_ns_t ns; 13619 isc_result_t result; 13620 dns_rdata_t rdata = DNS_RDATA_INIT; 13621 bool has_glue = false; 13622 dns_name_t *ns_name; 13623 /* 13624 * List of NS entries in answer, keep names that will be used 13625 * to resolve missing A/AAAA glue for each entry. 13626 */ 13627 dns_namelist_t ns_list; 13628 ISC_LIST_INIT(ns_list); 13629 13630 /* 13631 * Extract NS RRset from message. 13632 */ 13633 result = dns_message_findname(message, DNS_SECTION_ANSWER, name, 13634 dns_rdatatype_ns, dns_rdatatype_none, 13635 NULL, &nsrdataset); 13636 if (result != ISC_R_SUCCESS) { 13637 goto done; 13638 } 13639 13640 /* 13641 * Add NS rdataset. 13642 */ 13643 result = dns_db_findnode(db, name, true, &node); 13644 if (result != ISC_R_SUCCESS) { 13645 goto done; 13646 } 13647 result = dns_db_addrdataset(db, node, version, 0, nsrdataset, 0, NULL); 13648 dns_db_detachnode(db, &node); 13649 if (result != ISC_R_SUCCESS) { 13650 goto done; 13651 } 13652 /* 13653 * Add glue rdatasets. 13654 */ 13655 for (result = dns_rdataset_first(nsrdataset); result == ISC_R_SUCCESS; 13656 result = dns_rdataset_next(nsrdataset)) 13657 { 13658 dns_rdataset_current(nsrdataset, &rdata); 13659 result = dns_rdata_tostruct(&rdata, &ns, NULL); 13660 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13661 dns_rdata_reset(&rdata); 13662 13663 if (!dns_name_issubdomain(&ns.name, name)) { 13664 continue; 13665 } 13666 rdataset = NULL; 13667 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL, 13668 &ns.name, dns_rdatatype_aaaa, 13669 dns_rdatatype_none, NULL, 13670 &rdataset); 13671 if (result == ISC_R_SUCCESS) { 13672 has_glue = true; 13673 result = dns_db_findnode(db, &ns.name, true, &node); 13674 if (result != ISC_R_SUCCESS) { 13675 goto done; 13676 } 13677 result = dns_db_addrdataset(db, node, version, 0, 13678 rdataset, 0, NULL); 13679 dns_db_detachnode(db, &node); 13680 if (result != ISC_R_SUCCESS) { 13681 goto done; 13682 } 13683 } 13684 13685 rdataset = NULL; 13686 result = dns_message_findname( 13687 message, DNS_SECTION_ADDITIONAL, &ns.name, 13688 dns_rdatatype_a, dns_rdatatype_none, NULL, &rdataset); 13689 if (result == ISC_R_SUCCESS) { 13690 has_glue = true; 13691 result = dns_db_findnode(db, &ns.name, true, &node); 13692 if (result != ISC_R_SUCCESS) { 13693 goto done; 13694 } 13695 result = dns_db_addrdataset(db, node, version, 0, 13696 rdataset, 0, NULL); 13697 dns_db_detachnode(db, &node); 13698 if (result != ISC_R_SUCCESS) { 13699 goto done; 13700 } 13701 } 13702 13703 /* 13704 * If no glue is found so far, we add the name to the list to 13705 * resolve the A/AAAA glue later. If any glue is found in any 13706 * iteration step, this list will be discarded and only the glue 13707 * provided in this message will be used. 13708 */ 13709 if (!has_glue && dns_name_issubdomain(&ns.name, name)) { 13710 dns_name_t *tmp_name; 13711 tmp_name = isc_mem_get(cb_args->stub->mctx, 13712 sizeof(*tmp_name)); 13713 dns_name_init(tmp_name, NULL); 13714 dns_name_dup(&ns.name, cb_args->stub->mctx, tmp_name); 13715 ISC_LIST_APPEND(ns_list, tmp_name, link); 13716 } 13717 } 13718 13719 if (result != ISC_R_NOMORE) { 13720 goto done; 13721 } 13722 13723 /* 13724 * If no glue records were found, we attempt to resolve A/AAAA 13725 * for each NS entry found in the answer. 13726 */ 13727 if (!has_glue) { 13728 for (ns_name = ISC_LIST_HEAD(ns_list); ns_name != NULL; 13729 ns_name = ISC_LIST_NEXT(ns_name, link)) 13730 { 13731 /* 13732 * Resolve NS IPv4 address/A. 13733 */ 13734 result = stub_request_nameserver_address(cb_args, true, 13735 ns_name); 13736 if (result != ISC_R_SUCCESS) { 13737 goto done; 13738 } 13739 /* 13740 * Resolve NS IPv6 address/AAAA. 13741 */ 13742 result = stub_request_nameserver_address(cb_args, false, 13743 ns_name); 13744 if (result != ISC_R_SUCCESS) { 13745 goto done; 13746 } 13747 } 13748 } 13749 13750 result = ISC_R_SUCCESS; 13751 13752 done: 13753 while ((ns_name = ISC_LIST_HEAD(ns_list)) != NULL) { 13754 ISC_LIST_UNLINK(ns_list, ns_name, link); 13755 dns_name_free(ns_name, cb_args->stub->mctx); 13756 isc_mem_put(cb_args->stub->mctx, ns_name, sizeof(*ns_name)); 13757 } 13758 return result; 13759 } 13760 13761 static void 13762 stub_callback(void *arg) { 13763 dns_request_t *request = (dns_request_t *)arg; 13764 struct stub_cb_args *cb_args = dns_request_getarg(request); 13765 dns_stub_t *stub = cb_args->stub; 13766 dns_message_t *msg = NULL; 13767 dns_zone_t *zone = NULL; 13768 char primary[ISC_SOCKADDR_FORMATSIZE]; 13769 char source[ISC_SOCKADDR_FORMATSIZE]; 13770 uint32_t nscnt, cnamecnt; 13771 isc_result_t result; 13772 isc_sockaddr_t curraddr; 13773 isc_time_t now; 13774 bool exiting = false; 13775 13776 INSIST(DNS_STUB_VALID(stub)); 13777 13778 zone = stub->zone; 13779 13780 ENTER; 13781 13782 now = isc_time_now(); 13783 13784 LOCK_ZONE(zone); 13785 13786 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 13787 goto exiting; 13788 } 13789 13790 curraddr = dns_remote_curraddr(&zone->primaries); 13791 isc_sockaddr_format(&curraddr, primary, sizeof(primary)); 13792 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 13793 13794 result = dns_request_getresult(request); 13795 switch (result) { 13796 case ISC_R_SUCCESS: 13797 break; 13798 case ISC_R_SHUTTINGDOWN: 13799 case ISC_R_CANCELED: 13800 goto exiting; 13801 case ISC_R_TIMEDOUT: 13802 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 13803 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 13804 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13805 "refreshing stub: timeout retrying " 13806 "without EDNS primary %s (source %s)", 13807 primary, source); 13808 goto same_primary; 13809 } 13810 FALLTHROUGH; 13811 default: 13812 dns_zonemgr_unreachableadd(zone->zmgr, &curraddr, 13813 &zone->sourceaddr, &now); 13814 dns_zone_log(zone, ISC_LOG_INFO, 13815 "could not refresh stub from primary " 13816 "%s (source %s): %s", 13817 primary, source, isc_result_totext(result)); 13818 goto next_primary; 13819 } 13820 13821 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, 13822 &msg); 13823 13824 result = dns_request_getresponse(request, msg, 0); 13825 if (result != ISC_R_SUCCESS) { 13826 goto next_primary; 13827 } 13828 13829 /* 13830 * Unexpected opcode. 13831 */ 13832 if (msg->opcode != dns_opcode_query) { 13833 char opcode[128]; 13834 isc_buffer_t rb; 13835 13836 isc_buffer_init(&rb, opcode, sizeof(opcode)); 13837 (void)dns_opcode_totext(msg->opcode, &rb); 13838 13839 dns_zone_log(zone, ISC_LOG_INFO, 13840 "refreshing stub: " 13841 "unexpected opcode (%.*s) from %s (source %s)", 13842 (int)rb.used, opcode, primary, source); 13843 goto next_primary; 13844 } 13845 13846 /* 13847 * Unexpected rcode. 13848 */ 13849 if (msg->rcode != dns_rcode_noerror) { 13850 char rcode[128]; 13851 isc_buffer_t rb; 13852 13853 isc_buffer_init(&rb, rcode, sizeof(rcode)); 13854 (void)dns_rcode_totext(msg->rcode, &rb); 13855 13856 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 13857 (msg->rcode == dns_rcode_servfail || 13858 msg->rcode == dns_rcode_notimp || 13859 (msg->rcode == dns_rcode_formerr && msg->opt == NULL))) 13860 { 13861 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13862 "refreshing stub: rcode (%.*s) retrying " 13863 "without EDNS primary %s (source %s)", 13864 (int)rb.used, rcode, primary, source); 13865 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 13866 goto same_primary; 13867 } 13868 13869 dns_zone_log(zone, ISC_LOG_INFO, 13870 "refreshing stub: " 13871 "unexpected rcode (%.*s) from %s (source %s)", 13872 (int)rb.used, rcode, primary, source); 13873 goto next_primary; 13874 } 13875 13876 /* 13877 * We need complete messages. 13878 */ 13879 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 13880 if (dns_request_usedtcp(request)) { 13881 dns_zone_log(zone, ISC_LOG_INFO, 13882 "refreshing stub: truncated TCP " 13883 "response from primary %s (source %s)", 13884 primary, source); 13885 goto next_primary; 13886 } 13887 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 13888 goto same_primary; 13889 } 13890 13891 /* 13892 * If non-auth log and next primary. 13893 */ 13894 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 13895 dns_zone_log(zone, ISC_LOG_INFO, 13896 "refreshing stub: " 13897 "non-authoritative answer from " 13898 "primary %s (source %s)", 13899 primary, source); 13900 goto next_primary; 13901 } 13902 13903 /* 13904 * Sanity checks. 13905 */ 13906 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 13907 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns); 13908 13909 if (cnamecnt != 0) { 13910 dns_zone_log(zone, ISC_LOG_INFO, 13911 "refreshing stub: unexpected CNAME response " 13912 "from primary %s (source %s)", 13913 primary, source); 13914 goto next_primary; 13915 } 13916 13917 if (nscnt == 0) { 13918 dns_zone_log(zone, ISC_LOG_INFO, 13919 "refreshing stub: no NS records in response " 13920 "from primary %s (source %s)", 13921 primary, source); 13922 goto next_primary; 13923 } 13924 13925 atomic_fetch_add(&stub->pending_requests, 1); 13926 13927 /* 13928 * Save answer. 13929 */ 13930 result = save_nsrrset(msg, &zone->origin, cb_args, stub->db, 13931 stub->version); 13932 if (result != ISC_R_SUCCESS) { 13933 dns_zone_log(zone, ISC_LOG_INFO, 13934 "refreshing stub: unable to save NS records " 13935 "from primary %s (source %s)", 13936 primary, source); 13937 goto next_primary; 13938 } 13939 13940 dns_message_detach(&msg); 13941 dns_request_destroy(&zone->request); 13942 13943 /* 13944 * Check to see if there are no outstanding requests and 13945 * finish off if that is so. 13946 */ 13947 if (atomic_fetch_sub(&stub->pending_requests, 1) == 1) { 13948 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13949 stub_finish_zone_update(stub, now); 13950 goto free_stub; 13951 } 13952 13953 UNLOCK_ZONE(zone); 13954 return; 13955 13956 exiting: 13957 zone_debuglog(zone, __func__, 1, "exiting"); 13958 exiting = true; 13959 13960 next_primary: 13961 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13962 if (stub->version != NULL) { 13963 dns_db_closeversion(stub->db, &stub->version, false); 13964 } 13965 if (stub->db != NULL) { 13966 dns_db_detach(&stub->db); 13967 } 13968 if (msg != NULL) { 13969 dns_message_detach(&msg); 13970 } 13971 dns_request_destroy(&zone->request); 13972 /* 13973 * Skip to next failed / untried primary. 13974 */ 13975 dns_remote_next(&zone->primaries, true); 13976 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 13977 if (exiting || dns_remote_done(&zone->primaries)) { 13978 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 13979 zone_settimer(zone, &now); 13980 goto free_stub; 13981 } 13982 queue_soa_query(zone); 13983 goto free_stub; 13984 13985 same_primary: 13986 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13987 if (msg != NULL) { 13988 dns_message_detach(&msg); 13989 } 13990 dns_request_destroy(&zone->request); 13991 ns_query(zone, NULL, stub); 13992 UNLOCK_ZONE(zone); 13993 return; 13994 13995 free_stub: 13996 UNLOCK_ZONE(zone); 13997 stub->magic = 0; 13998 dns_zone_idetach(&stub->zone); 13999 INSIST(stub->db == NULL); 14000 INSIST(stub->version == NULL); 14001 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 14002 } 14003 14004 /* 14005 * Get the EDNS EXPIRE option from the response and if it exists trim 14006 * expire to be not more than it. 14007 */ 14008 static void 14009 get_edns_expire(dns_zone_t *zone, dns_message_t *message, uint32_t *expirep) { 14010 isc_result_t result; 14011 uint32_t expire; 14012 dns_rdata_t rdata = DNS_RDATA_INIT; 14013 isc_buffer_t optbuf; 14014 uint16_t optcode; 14015 uint16_t optlen; 14016 14017 REQUIRE(expirep != NULL); 14018 REQUIRE(message != NULL); 14019 14020 if (message->opt == NULL) { 14021 return; 14022 } 14023 14024 result = dns_rdataset_first(message->opt); 14025 if (result == ISC_R_SUCCESS) { 14026 dns_rdataset_current(message->opt, &rdata); 14027 isc_buffer_init(&optbuf, rdata.data, rdata.length); 14028 isc_buffer_add(&optbuf, rdata.length); 14029 while (isc_buffer_remaininglength(&optbuf) >= 4) { 14030 optcode = isc_buffer_getuint16(&optbuf); 14031 optlen = isc_buffer_getuint16(&optbuf); 14032 /* 14033 * A EDNS EXPIRE response has a length of 4. 14034 */ 14035 if (optcode != DNS_OPT_EXPIRE || optlen != 4) { 14036 isc_buffer_forward(&optbuf, optlen); 14037 continue; 14038 } 14039 expire = isc_buffer_getuint32(&optbuf); 14040 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14041 "got EDNS EXPIRE of %u", expire); 14042 /* 14043 * Trim *expirep? 14044 */ 14045 if (expire < *expirep) { 14046 *expirep = expire; 14047 } 14048 break; 14049 } 14050 } 14051 } 14052 14053 /* 14054 * Set the file modification time zone->expire seconds before expiretime. 14055 */ 14056 static void 14057 setmodtime(dns_zone_t *zone, isc_time_t *expiretime) { 14058 isc_result_t result; 14059 isc_time_t when; 14060 isc_interval_t i; 14061 14062 isc_interval_set(&i, zone->expire, 0); 14063 result = isc_time_subtract(expiretime, &i, &when); 14064 if (result != ISC_R_SUCCESS) { 14065 return; 14066 } 14067 14068 result = ISC_R_FAILURE; 14069 if (zone->journal != NULL) { 14070 result = isc_file_settime(zone->journal, &when); 14071 } 14072 if (result == ISC_R_SUCCESS && 14073 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 14074 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 14075 { 14076 result = isc_file_settime(zone->masterfile, &when); 14077 } else if (result != ISC_R_SUCCESS) { 14078 result = isc_file_settime(zone->masterfile, &when); 14079 } 14080 14081 /* 14082 * Someone removed the file from underneath us! 14083 */ 14084 if (result == ISC_R_FILENOTFOUND) { 14085 zone_needdump(zone, DNS_DUMP_DELAY); 14086 } else if (result != ISC_R_SUCCESS) { 14087 dns_zone_log(zone, ISC_LOG_ERROR, 14088 "refresh: could not set " 14089 "file modification time of '%s': %s", 14090 zone->masterfile, isc_result_totext(result)); 14091 } 14092 } 14093 14094 /* 14095 * An SOA query has finished (successfully or not). 14096 */ 14097 static void 14098 refresh_callback(void *arg) { 14099 dns_request_t *request = (dns_request_t *)arg; 14100 dns_zone_t *zone = dns_request_getarg(request); 14101 dns_message_t *msg = NULL; 14102 uint32_t soacnt, cnamecnt, soacount, nscount; 14103 isc_time_t now; 14104 char primary[ISC_SOCKADDR_FORMATSIZE]; 14105 char source[ISC_SOCKADDR_FORMATSIZE]; 14106 dns_rdataset_t *rdataset = NULL; 14107 dns_rdata_t rdata = DNS_RDATA_INIT; 14108 dns_rdata_soa_t soa; 14109 isc_result_t result; 14110 const isc_result_t eresult = dns_request_getresult(request); 14111 isc_sockaddr_t curraddr; 14112 uint32_t serial, oldserial = 0; 14113 bool do_queue_xfrin = false; 14114 14115 INSIST(DNS_ZONE_VALID(zone)); 14116 14117 ENTER; 14118 14119 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 14120 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(3), 14121 "refresh: request result: %s", 14122 isc_result_totext(eresult)); 14123 } 14124 14125 now = isc_time_now(); 14126 14127 LOCK_ZONE(zone); 14128 14129 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 14130 goto exiting; 14131 } 14132 14133 /* 14134 * If timeout, log and try the next primary 14135 */ 14136 curraddr = dns_remote_curraddr(&zone->primaries); 14137 isc_sockaddr_format(&curraddr, primary, sizeof(primary)); 14138 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 14139 14140 switch (eresult) { 14141 case ISC_R_SUCCESS: 14142 break; 14143 case ISC_R_SHUTTINGDOWN: 14144 case ISC_R_CANCELED: 14145 goto exiting; 14146 case ISC_R_TIMEDOUT: 14147 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 14148 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14149 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14150 ISC_LOG_DEBUG(1), 14151 "refresh: timeout retrying without EDNS " 14152 "primary %s (source %s)", 14153 primary, source); 14154 goto same_primary; 14155 } else if (!dns_request_usedtcp(request)) { 14156 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14157 ISC_LOG_INFO, 14158 "refresh: retry limit for " 14159 "primary %s exceeded (source %s)", 14160 primary, source); 14161 /* Try with secondary with TCP. */ 14162 if ((zone->type == dns_zone_secondary || 14163 zone->type == dns_zone_mirror || 14164 zone->type == dns_zone_redirect) && 14165 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) 14166 { 14167 if (!dns_zonemgr_unreachable( 14168 zone->zmgr, &curraddr, 14169 &zone->sourceaddr, &now)) 14170 { 14171 DNS_ZONE_SETFLAG( 14172 zone, 14173 DNS_ZONEFLG_SOABEFOREAXFR); 14174 goto tcp_transfer; 14175 } 14176 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14177 ISC_LOG_DEBUG(1), 14178 "refresh: skipped tcp fallback " 14179 "as primary %s (source %s) is " 14180 "unreachable (cached)", 14181 primary, source); 14182 } 14183 goto next_primary; 14184 } 14185 FALLTHROUGH; 14186 default: 14187 result = eresult; 14188 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14189 "refresh: failure trying primary " 14190 "%s (source %s): %s", 14191 primary, source, isc_result_totext(result)); 14192 goto next_primary; 14193 } 14194 14195 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, 14196 &msg); 14197 result = dns_request_getresponse(request, msg, 0); 14198 if (result != ISC_R_SUCCESS) { 14199 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14200 "refresh: failure trying primary " 14201 "%s (source %s): %s", 14202 primary, source, isc_result_totext(result)); 14203 goto next_primary; 14204 } 14205 14206 /* 14207 * Unexpected opcode. 14208 */ 14209 if (msg->opcode != dns_opcode_query) { 14210 char opcode[128]; 14211 isc_buffer_t rb; 14212 14213 isc_buffer_init(&rb, opcode, sizeof(opcode)); 14214 (void)dns_opcode_totext(msg->opcode, &rb); 14215 14216 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14217 "refresh: " 14218 "unexpected opcode (%.*s) from %s (source %s)", 14219 (int)rb.used, opcode, primary, source); 14220 goto next_primary; 14221 } 14222 14223 /* 14224 * Unexpected rcode. 14225 */ 14226 if (msg->rcode != dns_rcode_noerror) { 14227 char rcode[128]; 14228 isc_buffer_t rb; 14229 14230 isc_buffer_init(&rb, rcode, sizeof(rcode)); 14231 (void)dns_rcode_totext(msg->rcode, &rb); 14232 14233 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 14234 (msg->rcode == dns_rcode_servfail || 14235 msg->rcode == dns_rcode_notimp || 14236 (msg->rcode == dns_rcode_formerr && msg->opt == NULL))) 14237 { 14238 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14239 ISC_LOG_DEBUG(1), 14240 "refresh: rcode (%.*s) retrying without " 14241 "EDNS primary %s (source %s)", 14242 (int)rb.used, rcode, primary, source); 14243 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14244 goto same_primary; 14245 } 14246 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 14247 msg->rcode == dns_rcode_badvers) 14248 { 14249 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14250 ISC_LOG_DEBUG(1), 14251 "refresh: rcode (%.*s) retrying without " 14252 "EDNS EXPIRE OPTION primary %s " 14253 "(source %s)", 14254 (int)rb.used, rcode, primary, source); 14255 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14256 goto same_primary; 14257 } 14258 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14259 "refresh: unexpected rcode (%.*s) from " 14260 "primary %s (source %s)", 14261 (int)rb.used, rcode, primary, source); 14262 /* 14263 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't. 14264 */ 14265 if (msg->rcode == dns_rcode_refused && 14266 (zone->type == dns_zone_secondary || 14267 zone->type == dns_zone_mirror || 14268 zone->type == dns_zone_redirect)) 14269 { 14270 goto tcp_transfer; 14271 } 14272 goto next_primary; 14273 } 14274 14275 /* 14276 * If truncated punt to zone transfer which will query again. 14277 */ 14278 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 14279 if (zone->type == dns_zone_secondary || 14280 zone->type == dns_zone_mirror || 14281 zone->type == dns_zone_redirect) 14282 { 14283 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14284 ISC_LOG_INFO, 14285 "refresh: truncated UDP answer, " 14286 "initiating TCP zone xfer " 14287 "for primary %s (source %s)", 14288 primary, source); 14289 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 14290 goto tcp_transfer; 14291 } else { 14292 INSIST(zone->type == dns_zone_stub); 14293 if (dns_request_usedtcp(request)) { 14294 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14295 ISC_LOG_INFO, 14296 "refresh: truncated TCP response " 14297 "from primary %s (source %s)", 14298 primary, source); 14299 goto next_primary; 14300 } 14301 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 14302 goto same_primary; 14303 } 14304 } 14305 14306 /* 14307 * If non-auth, log and try the next primary 14308 */ 14309 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 14310 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14311 "refresh: non-authoritative answer from " 14312 "primary %s (source %s)", 14313 primary, source); 14314 goto next_primary; 14315 } 14316 14317 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 14318 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa); 14319 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns); 14320 soacount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_soa); 14321 14322 /* 14323 * There should not be a CNAME record at top of zone. 14324 */ 14325 if (cnamecnt != 0) { 14326 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14327 "refresh: CNAME at top of zone " 14328 "in primary %s (source %s)", 14329 primary, source); 14330 goto next_primary; 14331 } 14332 14333 /* 14334 * If referral, log and try the next primary; 14335 */ 14336 if (soacnt == 0 && soacount == 0 && nscount != 0) { 14337 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14338 "refresh: referral response " 14339 "from primary %s (source %s)", 14340 primary, source); 14341 goto next_primary; 14342 } 14343 14344 /* 14345 * If nodata, log and try the next primary; 14346 */ 14347 if (soacnt == 0 && (nscount == 0 || soacount != 0)) { 14348 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14349 "refresh: NODATA response " 14350 "from primary %s (source %s)", 14351 primary, source); 14352 goto next_primary; 14353 } 14354 14355 /* 14356 * Only one soa at top of zone. 14357 */ 14358 if (soacnt != 1) { 14359 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14360 "refresh: answer SOA count (%d) != 1 " 14361 "from primary %s (source %s)", 14362 soacnt, primary, source); 14363 goto next_primary; 14364 } 14365 14366 /* 14367 * Extract serial 14368 */ 14369 rdataset = NULL; 14370 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin, 14371 dns_rdatatype_soa, dns_rdatatype_none, 14372 NULL, &rdataset); 14373 if (result != ISC_R_SUCCESS) { 14374 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14375 "refresh: unable to get SOA record " 14376 "from primary %s (source %s)", 14377 primary, source); 14378 goto next_primary; 14379 } 14380 14381 result = dns_rdataset_first(rdataset); 14382 if (result != ISC_R_SUCCESS) { 14383 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14384 "refresh: dns_rdataset_first() failed"); 14385 goto next_primary; 14386 } 14387 14388 dns_rdataset_current(rdataset, &rdata); 14389 result = dns_rdata_tostruct(&rdata, &soa, NULL); 14390 RUNTIME_CHECK(result == ISC_R_SUCCESS); 14391 14392 serial = soa.serial; 14393 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 14394 unsigned int dbsoacount; 14395 result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount, 14396 NULL, &oldserial, NULL, NULL, NULL, 14397 NULL, NULL); 14398 RUNTIME_CHECK(result == ISC_R_SUCCESS); 14399 RUNTIME_CHECK(dbsoacount > 0U); 14400 zone_debuglogc(zone, DNS_LOGCATEGORY_XFER_IN, __func__, 1, 14401 "serial: new %u, old %u", serial, oldserial); 14402 } else { 14403 zone_debuglogc(zone, DNS_LOGCATEGORY_XFER_IN, __func__, 1, 14404 "serial: new %u, old not loaded", serial); 14405 } 14406 14407 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) || 14408 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) || 14409 isc_serial_gt(serial, oldserial)) 14410 { 14411 if (dns_zonemgr_unreachable(zone->zmgr, &curraddr, 14412 &zone->sourceaddr, &now)) 14413 { 14414 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14415 ISC_LOG_INFO, 14416 "refresh: skipping %s as primary %s " 14417 "(source %s) is unreachable (cached)", 14418 (zone->type == dns_zone_secondary || 14419 zone->type == dns_zone_mirror || 14420 zone->type == dns_zone_redirect) 14421 ? "zone transfer" 14422 : "NS query", 14423 primary, source); 14424 goto next_primary; 14425 } 14426 tcp_transfer: 14427 dns_request_destroy(&zone->request); 14428 if (zone->type == dns_zone_secondary || 14429 zone->type == dns_zone_mirror || 14430 zone->type == dns_zone_redirect) 14431 { 14432 do_queue_xfrin = true; 14433 } else { 14434 INSIST(zone->type == dns_zone_stub); 14435 ns_query(zone, rdataset, NULL); 14436 } 14437 if (msg != NULL) { 14438 dns_message_detach(&msg); 14439 } 14440 } else if (isc_serial_eq(soa.serial, oldserial)) { 14441 isc_time_t expiretime; 14442 uint32_t expire; 14443 14444 /* 14445 * Compute the new expire time based on this response. 14446 */ 14447 expire = zone->expire; 14448 get_edns_expire(zone, msg, &expire); 14449 DNS_ZONE_TIME_ADD(&now, expire, &expiretime); 14450 14451 /* 14452 * Has the expire time improved? 14453 */ 14454 if (isc_time_compare(&expiretime, &zone->expiretime) > 0) { 14455 zone->expiretime = expiretime; 14456 if (zone->masterfile != NULL) { 14457 setmodtime(zone, &expiretime); 14458 } 14459 } 14460 14461 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 14462 dns_remote_mark(&zone->primaries, true); 14463 goto next_primary; 14464 } else { 14465 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER)) { 14466 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14467 ISC_LOG_INFO, 14468 "serial number (%u) " 14469 "received from primary %s < ours (%u)", 14470 soa.serial, primary, oldserial); 14471 } else { 14472 zone_debuglogc(zone, DNS_LOGCATEGORY_XFER_IN, __func__, 14473 1, "ahead"); 14474 } 14475 dns_remote_mark(&zone->primaries, true); 14476 goto next_primary; 14477 } 14478 if (msg != NULL) { 14479 dns_message_detach(&msg); 14480 } 14481 goto detach; 14482 14483 next_primary: 14484 if (msg != NULL) { 14485 dns_message_detach(&msg); 14486 } 14487 dns_request_destroy(&zone->request); 14488 /* 14489 * Skip to next failed / untried primary. 14490 */ 14491 dns_remote_next(&zone->primaries, true); 14492 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 14493 if (dns_remote_done(&zone->primaries)) { 14494 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 14495 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 14496 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 14497 zone->refreshtime = now; 14498 } 14499 zone_settimer(zone, &now); 14500 goto detach; 14501 } 14502 14503 queue_soa_query(zone); 14504 goto detach; 14505 14506 exiting: 14507 /* 14508 * We can get here not only during shutdown, but also when the refresh 14509 * is canceled during reconfiguration. In that case, make sure to clear 14510 * the DNS_ZONEFLG_REFRESH flag so that future zone refreshes don't get 14511 * stuck, and make sure a new refresh attempt is made again soon after 14512 * the reconfiguration is complete. 14513 */ 14514 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 14515 zone->refreshtime = now; 14516 zone_settimer(zone, &now); 14517 14518 dns_request_destroy(&zone->request); 14519 goto detach; 14520 14521 same_primary: 14522 if (msg != NULL) { 14523 dns_message_detach(&msg); 14524 } 14525 dns_request_destroy(&zone->request); 14526 queue_soa_query(zone); 14527 14528 detach: 14529 if (do_queue_xfrin) { 14530 /* Shows in the statistics channel the duration of the step. */ 14531 zone->xfrintime = isc_time_now(); 14532 } 14533 UNLOCK_ZONE(zone); 14534 if (do_queue_xfrin) { 14535 queue_xfrin(zone); 14536 } 14537 dns_zone_idetach(&zone); 14538 return; 14539 } 14540 14541 struct soaquery { 14542 dns_zone_t *zone; 14543 isc_rlevent_t *rlevent; 14544 }; 14545 14546 static void 14547 queue_soa_query(dns_zone_t *zone) { 14548 isc_result_t result; 14549 struct soaquery *sq = NULL; 14550 14551 ENTER; 14552 /* 14553 * Locked by caller 14554 */ 14555 REQUIRE(LOCKED_ZONE(zone)); 14556 14557 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 14558 cancel_refresh(zone); 14559 return; 14560 } 14561 14562 sq = isc_mem_get(zone->mctx, sizeof(*sq)); 14563 *sq = (struct soaquery){ .zone = NULL }; 14564 14565 /* Shows in the statistics channel the duration of the current step. */ 14566 zone->xfrintime = isc_time_now(); 14567 14568 /* 14569 * Attach so that we won't clean up until the event is delivered. 14570 */ 14571 zone_iattach(zone, &sq->zone); 14572 result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->loop, 14573 soa_query, sq, &sq->rlevent); 14574 if (result != ISC_R_SUCCESS) { 14575 zone_idetach(&sq->zone); 14576 isc_mem_put(zone->mctx, sq, sizeof(*sq)); 14577 cancel_refresh(zone); 14578 } 14579 } 14580 14581 static void 14582 soa_query(void *arg) { 14583 struct soaquery *sq = (struct soaquery *)arg; 14584 dns_zone_t *zone = sq->zone; 14585 isc_result_t result = ISC_R_FAILURE; 14586 dns_message_t *message = NULL; 14587 isc_netaddr_t primaryip; 14588 dns_tsigkey_t *key = NULL; 14589 dns_transport_t *transport = NULL; 14590 uint32_t options; 14591 bool cancel = true; 14592 int timeout; 14593 bool have_xfrsource = false, reqnsid, reqexpire; 14594 uint16_t udpsize = SEND_BUFFER_SIZE; 14595 isc_sockaddr_t curraddr, sourceaddr; 14596 bool do_queue_xfrin = false; 14597 14598 REQUIRE(DNS_ZONE_VALID(zone)); 14599 14600 ENTER; 14601 14602 LOCK_ZONE(zone); 14603 if (sq->rlevent->canceled || DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || 14604 zone->view->requestmgr == NULL) 14605 { 14606 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 14607 cancel = false; 14608 } 14609 goto cleanup; 14610 } 14611 14612 again: 14613 dns_zone_logc( 14614 zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(3), 14615 "soa_query: remote server current address index %d count %d", 14616 zone->primaries.curraddr, zone->primaries.addrcnt); 14617 INSIST(dns_remote_count(&zone->primaries) > 0); 14618 INSIST(!dns_remote_done(&zone->primaries)); 14619 14620 sourceaddr = dns_remote_sourceaddr(&zone->primaries); 14621 curraddr = dns_remote_curraddr(&zone->primaries); 14622 isc_netaddr_fromsockaddr(&primaryip, &curraddr); 14623 14624 if (isc_sockaddr_disabled(&curraddr)) { 14625 goto skip_primary; 14626 } 14627 14628 /* 14629 * First, look for a tsig key in the primaries statement, then 14630 * try for a server key. 14631 */ 14632 if (dns_remote_keyname(&zone->primaries) != NULL) { 14633 dns_view_t *view = dns_zone_getview(zone); 14634 dns_name_t *keyname = dns_remote_keyname(&zone->primaries); 14635 result = dns_view_gettsig(view, keyname, &key); 14636 if (result != ISC_R_SUCCESS) { 14637 char namebuf[DNS_NAME_FORMATSIZE]; 14638 dns_name_format(keyname, namebuf, sizeof(namebuf)); 14639 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14640 ISC_LOG_ERROR, "unable to find key: %s", 14641 namebuf); 14642 goto skip_primary; 14643 } 14644 } 14645 if (key == NULL) { 14646 result = dns_view_getpeertsig(zone->view, &primaryip, &key); 14647 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 14648 char addrbuf[ISC_NETADDR_FORMATSIZE]; 14649 isc_netaddr_format(&primaryip, addrbuf, 14650 sizeof(addrbuf)); 14651 dns_zone_logc( 14652 zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, 14653 "unable to find TSIG key for %s", addrbuf); 14654 goto skip_primary; 14655 } 14656 } 14657 14658 if (dns_remote_tlsname(&zone->primaries) != NULL) { 14659 dns_view_t *view = dns_zone_getview(zone); 14660 dns_name_t *tlsname = dns_remote_tlsname(&zone->primaries); 14661 result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname, 14662 &transport); 14663 if (result != ISC_R_SUCCESS) { 14664 char namebuf[DNS_NAME_FORMATSIZE]; 14665 dns_name_format(tlsname, namebuf, sizeof(namebuf)); 14666 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 14667 ISC_LOG_ERROR, 14668 "unable to find TLS configuration: %s", 14669 namebuf); 14670 goto skip_primary; 14671 } 14672 } 14673 14674 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? DNS_REQUESTOPT_TCP 14675 : 0; 14676 reqnsid = zone->view->requestnsid; 14677 reqexpire = zone->requestexpire; 14678 if (zone->view->peers != NULL) { 14679 dns_peer_t *peer = NULL; 14680 bool edns, usetcp; 14681 result = dns_peerlist_peerbyaddr(zone->view->peers, &primaryip, 14682 &peer); 14683 if (result == ISC_R_SUCCESS) { 14684 result = dns_peer_getsupportedns(peer, &edns); 14685 if (result == ISC_R_SUCCESS && !edns) { 14686 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14687 } 14688 result = dns_peer_gettransfersource(peer, 14689 &zone->sourceaddr); 14690 if (result == ISC_R_SUCCESS) { 14691 have_xfrsource = true; 14692 } 14693 udpsize = dns_view_getudpsize(zone->view); 14694 (void)dns_peer_getudpsize(peer, &udpsize); 14695 (void)dns_peer_getrequestnsid(peer, &reqnsid); 14696 (void)dns_peer_getrequestexpire(peer, &reqexpire); 14697 result = dns_peer_getforcetcp(peer, &usetcp); 14698 if (result == ISC_R_SUCCESS && usetcp) { 14699 options |= DNS_REQUESTOPT_TCP; 14700 } 14701 } 14702 } 14703 14704 switch (isc_sockaddr_pf(&curraddr)) { 14705 case PF_INET: 14706 if (!have_xfrsource) { 14707 isc_sockaddr_t any; 14708 isc_sockaddr_any(&any); 14709 14710 zone->sourceaddr = sourceaddr; 14711 if (isc_sockaddr_equal(&sourceaddr, &any)) { 14712 zone->sourceaddr = zone->xfrsource4; 14713 } 14714 } 14715 break; 14716 case PF_INET6: 14717 if (!have_xfrsource) { 14718 isc_sockaddr_t any; 14719 isc_sockaddr_any6(&any); 14720 14721 zone->sourceaddr = sourceaddr; 14722 if (isc_sockaddr_equal(&zone->sourceaddr, &any)) { 14723 zone->sourceaddr = zone->xfrsource6; 14724 } 14725 } 14726 break; 14727 default: 14728 result = ISC_R_NOTIMPLEMENTED; 14729 goto cleanup; 14730 } 14731 14732 /* 14733 * FIXME(OS): This is a bit hackish, but it enforces the SOA query to go 14734 * through the XFR channel instead of doing dns_request that doesn't 14735 * have DoT support yet. 14736 */ 14737 if (transport != NULL) { 14738 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 14739 do_queue_xfrin = true; 14740 cancel = false; 14741 result = ISC_R_SUCCESS; 14742 goto cleanup; 14743 } 14744 14745 create_query(zone, dns_rdatatype_soa, &zone->origin, &message); 14746 14747 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 14748 result = add_opt(message, udpsize, reqnsid, reqexpire); 14749 if (result != ISC_R_SUCCESS) { 14750 zone_debuglogc(zone, DNS_LOGCATEGORY_XFER_IN, __func__, 14751 1, "unable to add opt record: %s", 14752 isc_result_totext(result)); 14753 } 14754 } 14755 14756 zone_iattach(zone, &(dns_zone_t *){ NULL }); 14757 timeout = 5; 14758 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) { 14759 timeout = 30; 14760 } 14761 result = dns_request_create( 14762 zone->view->requestmgr, message, &zone->sourceaddr, &curraddr, 14763 NULL, NULL, options, key, timeout * 3 + 1, timeout, 2, 14764 zone->loop, refresh_callback, zone, &zone->request); 14765 if (result != ISC_R_SUCCESS) { 14766 zone_idetach(&(dns_zone_t *){ zone }); 14767 zone_debuglogc(zone, DNS_LOGCATEGORY_XFER_IN, __func__, 1, 14768 "dns_request_create() failed: %s", 14769 isc_result_totext(result)); 14770 goto skip_primary; 14771 } else { 14772 /* Shows in the statistics channel the duration of the query. */ 14773 zone->xfrintime = isc_time_now(); 14774 14775 if (isc_sockaddr_pf(&curraddr) == PF_INET) { 14776 inc_stats(zone, dns_zonestatscounter_soaoutv4); 14777 } else { 14778 inc_stats(zone, dns_zonestatscounter_soaoutv6); 14779 } 14780 } 14781 cancel = false; 14782 cleanup: 14783 if (transport != NULL) { 14784 dns_transport_detach(&transport); 14785 } 14786 if (key != NULL) { 14787 dns_tsigkey_detach(&key); 14788 } 14789 if (result != ISC_R_SUCCESS) { 14790 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 14791 } 14792 if (message != NULL) { 14793 dns_message_detach(&message); 14794 } 14795 if (cancel) { 14796 cancel_refresh(zone); 14797 } 14798 if (do_queue_xfrin) { 14799 /* Shows in the statistics channel the duration of the step. */ 14800 zone->xfrintime = isc_time_now(); 14801 } 14802 UNLOCK_ZONE(zone); 14803 if (do_queue_xfrin) { 14804 queue_xfrin(zone); 14805 } 14806 isc_rlevent_free(&sq->rlevent); 14807 isc_mem_put(zone->mctx, sq, sizeof(*sq)); 14808 dns_zone_idetach(&zone); 14809 return; 14810 14811 skip_primary: 14812 if (transport != NULL) { 14813 dns_transport_detach(&transport); 14814 } 14815 if (key != NULL) { 14816 dns_tsigkey_detach(&key); 14817 } 14818 if (message != NULL) { 14819 dns_message_detach(&message); 14820 } 14821 /* 14822 * Skip to next failed / untried primary. 14823 */ 14824 dns_remote_next(&zone->primaries, true); 14825 if (!dns_remote_done(&zone->primaries)) { 14826 goto again; 14827 } 14828 dns_remote_reset(&zone->primaries, false); 14829 goto cleanup; 14830 } 14831 14832 static void 14833 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { 14834 isc_result_t result; 14835 dns_message_t *message = NULL; 14836 isc_netaddr_t primaryip; 14837 dns_tsigkey_t *key = NULL; 14838 dns_dbnode_t *node = NULL; 14839 int timeout; 14840 bool have_xfrsource = false; 14841 bool reqnsid; 14842 uint16_t udpsize = SEND_BUFFER_SIZE; 14843 isc_sockaddr_t curraddr, sourceaddr; 14844 struct stub_cb_args *cb_args = NULL; 14845 14846 REQUIRE(DNS_ZONE_VALID(zone)); 14847 REQUIRE(LOCKED_ZONE(zone)); 14848 REQUIRE((soardataset != NULL && stub == NULL) || 14849 (soardataset == NULL && stub != NULL)); 14850 REQUIRE(stub == NULL || DNS_STUB_VALID(stub)); 14851 14852 ENTER; 14853 14854 if (stub == NULL) { 14855 stub = isc_mem_get(zone->mctx, sizeof(*stub)); 14856 stub->magic = STUB_MAGIC; 14857 stub->mctx = zone->mctx; 14858 stub->zone = NULL; 14859 stub->db = NULL; 14860 stub->version = NULL; 14861 atomic_init(&stub->pending_requests, 0); 14862 14863 /* 14864 * Attach so that the zone won't disappear from under us. 14865 */ 14866 zone_iattach(zone, &stub->zone); 14867 14868 /* 14869 * If a db exists we will update it, otherwise we create a 14870 * new one and attach it to the zone once we have the NS 14871 * RRset and glue. 14872 */ 14873 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 14874 if (zone->db != NULL) { 14875 dns_db_attach(zone->db, &stub->db); 14876 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 14877 } else { 14878 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 14879 14880 INSIST(zone->db_argc >= 1); 14881 result = dns_db_create(zone->mctx, zone->db_argv[0], 14882 &zone->origin, dns_dbtype_stub, 14883 zone->rdclass, zone->db_argc - 1, 14884 zone->db_argv + 1, &stub->db); 14885 if (result != ISC_R_SUCCESS) { 14886 dns_zone_log(zone, ISC_LOG_ERROR, 14887 "refreshing stub: " 14888 "could not create " 14889 "database: %s", 14890 isc_result_totext(result)); 14891 goto cleanup; 14892 } 14893 dns_db_setloop(stub->db, zone->loop); 14894 dns_db_setmaxrrperset(stub->db, zone->maxrrperset); 14895 dns_db_setmaxtypepername(stub->db, 14896 zone->maxtypepername); 14897 } 14898 14899 result = dns_db_newversion(stub->db, &stub->version); 14900 if (result != ISC_R_SUCCESS) { 14901 dns_zone_log(zone, ISC_LOG_INFO, 14902 "refreshing stub: " 14903 "dns_db_newversion() failed: %s", 14904 isc_result_totext(result)); 14905 goto cleanup; 14906 } 14907 14908 /* 14909 * Update SOA record. 14910 */ 14911 result = dns_db_findnode(stub->db, &zone->origin, true, &node); 14912 if (result != ISC_R_SUCCESS) { 14913 dns_zone_log(zone, ISC_LOG_INFO, 14914 "refreshing stub: " 14915 "dns_db_findnode() failed: %s", 14916 isc_result_totext(result)); 14917 goto cleanup; 14918 } 14919 14920 result = dns_db_addrdataset(stub->db, node, stub->version, 0, 14921 soardataset, 0, NULL); 14922 dns_db_detachnode(stub->db, &node); 14923 if (result != ISC_R_SUCCESS) { 14924 dns_zone_log(zone, ISC_LOG_INFO, 14925 "refreshing stub: " 14926 "dns_db_addrdataset() failed: %s", 14927 isc_result_totext(result)); 14928 goto cleanup; 14929 } 14930 } 14931 14932 /* 14933 * XXX Optimisation: Create message when zone is setup and reuse. 14934 */ 14935 create_query(zone, dns_rdatatype_ns, &zone->origin, &message); 14936 14937 INSIST(dns_remote_count(&zone->primaries) > 0); 14938 INSIST(!dns_remote_done(&zone->primaries)); 14939 14940 sourceaddr = dns_remote_sourceaddr(&zone->primaries); 14941 curraddr = dns_remote_curraddr(&zone->primaries); 14942 isc_netaddr_fromsockaddr(&primaryip, &curraddr); 14943 /* 14944 * First, look for a tsig key in the primaries statement, then 14945 * try for a server key. 14946 */ 14947 if (dns_remote_keyname(&zone->primaries) != NULL) { 14948 dns_view_t *view = dns_zone_getview(zone); 14949 dns_name_t *keyname = dns_remote_keyname(&zone->primaries); 14950 result = dns_view_gettsig(view, keyname, &key); 14951 if (result != ISC_R_SUCCESS) { 14952 char namebuf[DNS_NAME_FORMATSIZE]; 14953 dns_name_format(keyname, namebuf, sizeof(namebuf)); 14954 dns_zone_log(zone, ISC_LOG_ERROR, 14955 "unable to find key: %s", namebuf); 14956 } 14957 } 14958 if (key == NULL) { 14959 (void)dns_view_getpeertsig(zone->view, &primaryip, &key); 14960 } 14961 14962 /* FIXME(OS): Do we need the transport here too? Most probably yes */ 14963 14964 reqnsid = zone->view->requestnsid; 14965 if (zone->view->peers != NULL) { 14966 dns_peer_t *peer = NULL; 14967 bool edns; 14968 result = dns_peerlist_peerbyaddr(zone->view->peers, &primaryip, 14969 &peer); 14970 if (result == ISC_R_SUCCESS) { 14971 result = dns_peer_getsupportedns(peer, &edns); 14972 if (result == ISC_R_SUCCESS && !edns) { 14973 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14974 } 14975 result = dns_peer_gettransfersource(peer, 14976 &zone->sourceaddr); 14977 if (result == ISC_R_SUCCESS) { 14978 have_xfrsource = true; 14979 } 14980 udpsize = dns_view_getudpsize(zone->view); 14981 (void)dns_peer_getudpsize(peer, &udpsize); 14982 (void)dns_peer_getrequestnsid(peer, &reqnsid); 14983 } 14984 } 14985 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 14986 result = add_opt(message, udpsize, reqnsid, false); 14987 if (result != ISC_R_SUCCESS) { 14988 zone_debuglog(zone, __func__, 1, 14989 "unable to add opt record: %s", 14990 isc_result_totext(result)); 14991 } 14992 } 14993 14994 /* 14995 * Always use TCP so that we shouldn't truncate in additional section. 14996 */ 14997 switch (isc_sockaddr_pf(&curraddr)) { 14998 case PF_INET: 14999 if (!have_xfrsource) { 15000 isc_sockaddr_t any; 15001 isc_sockaddr_any(&any); 15002 15003 zone->sourceaddr = sourceaddr; 15004 if (isc_sockaddr_equal(&zone->sourceaddr, &any)) { 15005 zone->sourceaddr = zone->xfrsource4; 15006 } 15007 } 15008 break; 15009 case PF_INET6: 15010 if (!have_xfrsource) { 15011 isc_sockaddr_t any; 15012 isc_sockaddr_any6(&any); 15013 15014 zone->sourceaddr = sourceaddr; 15015 if (isc_sockaddr_equal(&zone->sourceaddr, &any)) { 15016 zone->sourceaddr = zone->xfrsource6; 15017 } 15018 } 15019 break; 15020 default: 15021 result = ISC_R_NOTIMPLEMENTED; 15022 POST(result); 15023 goto cleanup; 15024 } 15025 timeout = 5; 15026 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) { 15027 timeout = 30; 15028 } 15029 15030 /* 15031 * Save request parameters so we can reuse them later on 15032 * for resolving missing glue A/AAAA records. 15033 */ 15034 cb_args = isc_mem_get(zone->mctx, sizeof(*cb_args)); 15035 cb_args->stub = stub; 15036 cb_args->tsig_key = key; 15037 cb_args->udpsize = udpsize; 15038 cb_args->timeout = timeout; 15039 cb_args->reqnsid = reqnsid; 15040 15041 result = dns_request_create( 15042 zone->view->requestmgr, message, &zone->sourceaddr, &curraddr, 15043 NULL, NULL, DNS_REQUESTOPT_TCP, key, timeout * 3 + 1, timeout, 15044 2, zone->loop, stub_callback, cb_args, &zone->request); 15045 if (result != ISC_R_SUCCESS) { 15046 zone_debuglog(zone, __func__, 1, 15047 "dns_request_create() failed: %s", 15048 isc_result_totext(result)); 15049 goto cleanup; 15050 } 15051 dns_message_detach(&message); 15052 goto unlock; 15053 15054 cleanup: 15055 cancel_refresh(zone); 15056 stub->magic = 0; 15057 if (stub->version != NULL) { 15058 dns_db_closeversion(stub->db, &stub->version, false); 15059 } 15060 if (stub->db != NULL) { 15061 dns_db_detach(&stub->db); 15062 } 15063 if (stub->zone != NULL) { 15064 zone_idetach(&stub->zone); 15065 } 15066 if (cb_args != NULL) { 15067 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 15068 } 15069 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 15070 if (message != NULL) { 15071 dns_message_detach(&message); 15072 } 15073 unlock: 15074 if (key != NULL) { 15075 dns_tsigkey_detach(&key); 15076 } 15077 return; 15078 } 15079 15080 /* 15081 * Shut the zone down. 15082 */ 15083 static void 15084 zone_shutdown(void *arg) { 15085 dns_zone_t *zone = (dns_zone_t *)arg; 15086 bool free_needed, linked = false; 15087 dns_zone_t *raw = NULL, *secure = NULL; 15088 dns_view_t *view = NULL, *prev_view = NULL; 15089 15090 REQUIRE(DNS_ZONE_VALID(zone)); 15091 INSIST(isc_refcount_current(&zone->references) == 0); 15092 15093 zone_debuglog(zone, __func__, 3, "shutting down"); 15094 15095 /* 15096 * If we were waiting for xfrin quota, step out of 15097 * the queue. 15098 * If there's no zone manager, we can't be waiting for the 15099 * xfrin quota 15100 */ 15101 if (zone->zmgr != NULL) { 15102 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 15103 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) { 15104 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone, 15105 statelink); 15106 linked = true; 15107 zone->statelist = NULL; 15108 } 15109 if (zone->statelist == &zone->zmgr->xfrin_in_progress) { 15110 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, 15111 statelink); 15112 zone->statelist = NULL; 15113 zmgr_resume_xfrs(zone->zmgr, false); 15114 } 15115 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 15116 } 15117 15118 /* 15119 * In loop context, no locking required. See zone_xfrdone(). 15120 */ 15121 if (zone->xfr != NULL) { 15122 /* The final detach will happen in zone_xfrdone() */ 15123 dns_xfrin_shutdown(zone->xfr); 15124 } 15125 15126 /* Safe to release the zone now */ 15127 if (zone->zmgr != NULL) { 15128 dns_zonemgr_releasezone(zone->zmgr, zone); 15129 } 15130 15131 LOCK_ZONE(zone); 15132 INSIST(zone != zone->raw); 15133 15134 /* 15135 * Detach the views early, we don't need them anymore. However, we need 15136 * to detach them outside of the zone lock to break the lock loop 15137 * between view, adb and zone locks. 15138 */ 15139 view = zone->view; 15140 zone->view = NULL; 15141 prev_view = zone->prev_view; 15142 zone->prev_view = NULL; 15143 15144 if (linked) { 15145 isc_refcount_decrement(&zone->irefs); 15146 } 15147 if (zone->request != NULL) { 15148 dns_request_cancel(zone->request); 15149 } 15150 15151 if (zone->loadctx != NULL) { 15152 dns_loadctx_cancel(zone->loadctx); 15153 } 15154 15155 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 15156 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15157 { 15158 if (zone->dumpctx != NULL) { 15159 dns_dumpctx_cancel(zone->dumpctx); 15160 } 15161 } 15162 15163 checkds_cancel(zone); 15164 15165 notify_cancel(zone); 15166 15167 forward_cancel(zone); 15168 15169 if (zone->timer != NULL) { 15170 isc_refcount_decrement(&zone->irefs); 15171 isc_timer_destroy(&zone->timer); 15172 } 15173 15174 /* 15175 * We have now canceled everything set the flag to allow exit_check() 15176 * to succeed. We must not unlock between setting this flag and 15177 * calling exit_check(). 15178 */ 15179 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN); 15180 free_needed = exit_check(zone); 15181 /* 15182 * If a dump is in progress for the secure zone, defer detaching from 15183 * the raw zone as it may prevent the unsigned serial number from being 15184 * stored in the raw-format dump of the secure zone. In this scenario, 15185 * dump_done() takes care of cleaning up the zone->raw reference. 15186 */ 15187 if (inline_secure(zone) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 15188 raw = zone->raw; 15189 zone->raw = NULL; 15190 } 15191 if (inline_raw(zone)) { 15192 secure = zone->secure; 15193 zone->secure = NULL; 15194 } 15195 UNLOCK_ZONE(zone); 15196 15197 if (view != NULL) { 15198 dns_view_weakdetach(&view); 15199 } 15200 if (prev_view != NULL) { 15201 dns_view_weakdetach(&prev_view); 15202 } 15203 15204 if (raw != NULL) { 15205 dns_zone_detach(&raw); 15206 } 15207 if (secure != NULL) { 15208 dns_zone_idetach(&secure); 15209 } 15210 if (free_needed) { 15211 zone_free(zone); 15212 } 15213 } 15214 15215 static void 15216 zone_timer(void *arg) { 15217 dns_zone_t *zone = (dns_zone_t *)arg; 15218 15219 REQUIRE(DNS_ZONE_VALID(zone)); 15220 15221 zone_maintenance(zone); 15222 } 15223 15224 static void 15225 zone_timer_stop(dns_zone_t *zone) { 15226 zone_debuglog(zone, __func__, 10, "stop zone timer"); 15227 if (zone->timer != NULL) { 15228 isc_timer_stop(zone->timer); 15229 } 15230 } 15231 15232 static void 15233 zone_timer_set(dns_zone_t *zone, isc_time_t *next, isc_time_t *now) { 15234 isc_interval_t interval; 15235 15236 if (isc_time_compare(next, now) <= 0) { 15237 isc_interval_set(&interval, 0, 0); 15238 } else { 15239 isc_time_subtract(next, now, &interval); 15240 } 15241 15242 if (zone->loop == NULL) { 15243 zone_debuglog(zone, __func__, 10, "zone is not managed"); 15244 } else if (zone->timer == NULL) { 15245 isc_refcount_increment0(&zone->irefs); 15246 isc_timer_create(zone->loop, zone_timer, zone, &zone->timer); 15247 } 15248 if (zone->timer != NULL) { 15249 isc_timer_start(zone->timer, isc_timertype_once, &interval); 15250 } 15251 } 15252 15253 static void 15254 zone__settimer(void *arg) { 15255 zone_settimer_t *data = arg; 15256 dns_zone_t *zone = data->zone; 15257 isc_time_t *now = &data->now; 15258 isc_time_t next; 15259 bool free_needed = false; 15260 15261 REQUIRE(DNS_ZONE_VALID(zone)); 15262 ENTER; 15263 15264 LOCK_ZONE(zone); 15265 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 15266 goto free; 15267 } 15268 isc_time_settoepoch(&next); 15269 15270 switch (zone->type) { 15271 case dns_zone_redirect: 15272 if (dns_remote_addresses(&zone->primaries) != NULL) { 15273 goto treat_as_secondary; 15274 } 15275 FALLTHROUGH; 15276 case dns_zone_primary: 15277 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 15278 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) 15279 { 15280 next = zone->notifytime; 15281 } 15282 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 15283 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15284 { 15285 INSIST(!isc_time_isepoch(&zone->dumptime)); 15286 if (isc_time_isepoch(&next) || 15287 isc_time_compare(&zone->dumptime, &next) < 0) 15288 { 15289 next = zone->dumptime; 15290 } 15291 } 15292 if (zone->type == dns_zone_redirect) { 15293 break; 15294 } 15295 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) && 15296 !isc_time_isepoch(&zone->refreshkeytime)) 15297 { 15298 if (isc_time_isepoch(&next) || 15299 isc_time_compare(&zone->refreshkeytime, &next) < 0) 15300 { 15301 next = zone->refreshkeytime; 15302 } 15303 } 15304 if (!isc_time_isepoch(&zone->resigntime)) { 15305 if (isc_time_isepoch(&next) || 15306 isc_time_compare(&zone->resigntime, &next) < 0) 15307 { 15308 next = zone->resigntime; 15309 } 15310 } 15311 if (!isc_time_isepoch(&zone->keywarntime)) { 15312 if (isc_time_isepoch(&next) || 15313 isc_time_compare(&zone->keywarntime, &next) < 0) 15314 { 15315 next = zone->keywarntime; 15316 } 15317 } 15318 if (!isc_time_isepoch(&zone->signingtime)) { 15319 if (isc_time_isepoch(&next) || 15320 isc_time_compare(&zone->signingtime, &next) < 0) 15321 { 15322 next = zone->signingtime; 15323 } 15324 } 15325 if (!isc_time_isepoch(&zone->nsec3chaintime)) { 15326 if (isc_time_isepoch(&next) || 15327 isc_time_compare(&zone->nsec3chaintime, &next) < 0) 15328 { 15329 next = zone->nsec3chaintime; 15330 } 15331 } 15332 break; 15333 15334 case dns_zone_secondary: 15335 case dns_zone_mirror: 15336 treat_as_secondary: 15337 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 15338 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) 15339 { 15340 next = zone->notifytime; 15341 } 15342 FALLTHROUGH; 15343 case dns_zone_stub: 15344 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) && 15345 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOPRIMARIES) && 15346 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) && 15347 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) && 15348 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) && 15349 !isc_time_isepoch(&zone->refreshtime) && 15350 (isc_time_isepoch(&next) || 15351 isc_time_compare(&zone->refreshtime, &next) < 0)) 15352 { 15353 next = zone->refreshtime; 15354 } 15355 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 15356 !isc_time_isepoch(&zone->expiretime)) 15357 { 15358 if (isc_time_isepoch(&next) || 15359 isc_time_compare(&zone->expiretime, &next) < 0) 15360 { 15361 next = zone->expiretime; 15362 } 15363 } 15364 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 15365 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15366 { 15367 INSIST(!isc_time_isepoch(&zone->dumptime)); 15368 if (isc_time_isepoch(&next) || 15369 isc_time_compare(&zone->dumptime, &next) < 0) 15370 { 15371 next = zone->dumptime; 15372 } 15373 } 15374 break; 15375 15376 case dns_zone_key: 15377 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 15378 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15379 { 15380 INSIST(!isc_time_isepoch(&zone->dumptime)); 15381 if (isc_time_isepoch(&next) || 15382 isc_time_compare(&zone->dumptime, &next) < 0) 15383 { 15384 next = zone->dumptime; 15385 } 15386 } 15387 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) { 15388 if (isc_time_isepoch(&next) || 15389 (!isc_time_isepoch(&zone->refreshkeytime) && 15390 isc_time_compare(&zone->refreshkeytime, &next) < 15391 0)) 15392 { 15393 next = zone->refreshkeytime; 15394 } 15395 } 15396 break; 15397 15398 default: 15399 break; 15400 } 15401 15402 if (isc_time_isepoch(&next)) { 15403 zone_timer_stop(zone); 15404 } else { 15405 zone_timer_set(zone, &next, now); 15406 } 15407 15408 free: 15409 isc_mem_put(zone->mctx, data, sizeof(*data)); 15410 isc_refcount_decrement(&zone->irefs); 15411 free_needed = exit_check(zone); 15412 UNLOCK_ZONE(zone); 15413 if (free_needed) { 15414 zone_free(zone); 15415 } 15416 } 15417 15418 static void 15419 zone_settimer(dns_zone_t *zone, isc_time_t *now) { 15420 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 15421 return; 15422 } 15423 15424 zone_settimer_t *arg = isc_mem_get(zone->mctx, sizeof(*arg)); 15425 *arg = (zone_settimer_t){ 15426 .zone = zone, 15427 .now = *now, 15428 }; 15429 isc_refcount_increment0(&zone->irefs); 15430 isc_async_run(zone->loop, zone__settimer, arg); 15431 } 15432 15433 static void 15434 cancel_refresh(dns_zone_t *zone) { 15435 isc_time_t now; 15436 15437 /* 15438 * 'zone' locked by caller. 15439 */ 15440 15441 REQUIRE(DNS_ZONE_VALID(zone)); 15442 REQUIRE(LOCKED_ZONE(zone)); 15443 15444 ENTER; 15445 15446 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 15447 now = isc_time_now(); 15448 zone_settimer(zone, &now); 15449 } 15450 15451 static isc_result_t 15452 notify_createmessage(dns_zone_t *zone, unsigned int flags, 15453 dns_message_t **messagep) { 15454 dns_db_t *zonedb = NULL; 15455 dns_dbnode_t *node = NULL; 15456 dns_dbversion_t *version = NULL; 15457 dns_message_t *message = NULL; 15458 dns_rdataset_t rdataset; 15459 dns_rdata_t rdata = DNS_RDATA_INIT; 15460 15461 dns_name_t *tempname = NULL; 15462 dns_rdata_t *temprdata = NULL; 15463 dns_rdatalist_t *temprdatalist = NULL; 15464 dns_rdataset_t *temprdataset = NULL; 15465 15466 isc_result_t result; 15467 isc_region_t r; 15468 isc_buffer_t *b = NULL; 15469 15470 REQUIRE(DNS_ZONE_VALID(zone)); 15471 REQUIRE(messagep != NULL && *messagep == NULL); 15472 15473 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, 15474 &message); 15475 15476 message->opcode = dns_opcode_notify; 15477 message->flags |= DNS_MESSAGEFLAG_AA; 15478 message->rdclass = zone->rdclass; 15479 15480 dns_message_gettempname(message, &tempname); 15481 15482 dns_message_gettemprdataset(message, &temprdataset); 15483 15484 /* 15485 * Make question. 15486 */ 15487 dns_name_clone(&zone->origin, tempname); 15488 dns_rdataset_makequestion(temprdataset, zone->rdclass, 15489 dns_rdatatype_soa); 15490 ISC_LIST_APPEND(tempname->list, temprdataset, link); 15491 dns_message_addname(message, tempname, DNS_SECTION_QUESTION); 15492 tempname = NULL; 15493 temprdataset = NULL; 15494 15495 if ((flags & DNS_NOTIFY_NOSOA) != 0) { 15496 goto done; 15497 } 15498 15499 dns_message_gettempname(message, &tempname); 15500 dns_message_gettemprdata(message, &temprdata); 15501 dns_message_gettemprdataset(message, &temprdataset); 15502 dns_message_gettemprdatalist(message, &temprdatalist); 15503 15504 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 15505 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */ 15506 dns_db_attach(zone->db, &zonedb); 15507 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 15508 15509 dns_name_clone(&zone->origin, tempname); 15510 dns_db_currentversion(zonedb, &version); 15511 result = dns_db_findnode(zonedb, tempname, false, &node); 15512 if (result != ISC_R_SUCCESS) { 15513 goto soa_cleanup; 15514 } 15515 15516 dns_rdataset_init(&rdataset); 15517 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, 15518 dns_rdatatype_none, 0, &rdataset, NULL); 15519 if (result != ISC_R_SUCCESS) { 15520 goto soa_cleanup; 15521 } 15522 result = dns_rdataset_first(&rdataset); 15523 if (result != ISC_R_SUCCESS) { 15524 goto soa_cleanup; 15525 } 15526 dns_rdataset_current(&rdataset, &rdata); 15527 dns_rdata_toregion(&rdata, &r); 15528 isc_buffer_allocate(zone->mctx, &b, r.length); 15529 isc_buffer_putmem(b, r.base, r.length); 15530 isc_buffer_usedregion(b, &r); 15531 dns_rdata_init(temprdata); 15532 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r); 15533 dns_message_takebuffer(message, &b); 15534 result = dns_rdataset_next(&rdataset); 15535 dns_rdataset_disassociate(&rdataset); 15536 if (result != ISC_R_NOMORE) { 15537 goto soa_cleanup; 15538 } 15539 temprdatalist->rdclass = rdata.rdclass; 15540 temprdatalist->type = rdata.type; 15541 temprdatalist->ttl = rdataset.ttl; 15542 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link); 15543 15544 dns_rdatalist_tordataset(temprdatalist, temprdataset); 15545 15546 ISC_LIST_APPEND(tempname->list, temprdataset, link); 15547 dns_message_addname(message, tempname, DNS_SECTION_ANSWER); 15548 temprdatalist = NULL; 15549 temprdataset = NULL; 15550 temprdata = NULL; 15551 tempname = NULL; 15552 15553 soa_cleanup: 15554 if (node != NULL) { 15555 dns_db_detachnode(zonedb, &node); 15556 } 15557 if (version != NULL) { 15558 dns_db_closeversion(zonedb, &version, false); 15559 } 15560 if (zonedb != NULL) { 15561 dns_db_detach(&zonedb); 15562 } 15563 if (tempname != NULL) { 15564 dns_message_puttempname(message, &tempname); 15565 } 15566 if (temprdata != NULL) { 15567 dns_message_puttemprdata(message, &temprdata); 15568 } 15569 if (temprdataset != NULL) { 15570 dns_message_puttemprdataset(message, &temprdataset); 15571 } 15572 if (temprdatalist != NULL) { 15573 dns_message_puttemprdatalist(message, &temprdatalist); 15574 } 15575 15576 done: 15577 *messagep = message; 15578 return ISC_R_SUCCESS; 15579 } 15580 15581 isc_result_t 15582 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, 15583 isc_sockaddr_t *to, dns_message_t *msg) { 15584 unsigned int i; 15585 dns_rdata_soa_t soa; 15586 dns_rdataset_t *rdataset = NULL; 15587 dns_rdata_t rdata = DNS_RDATA_INIT; 15588 isc_result_t result; 15589 char fromtext[ISC_SOCKADDR_FORMATSIZE]; 15590 int match = 0; 15591 isc_netaddr_t netaddr; 15592 uint32_t serial = 0; 15593 bool have_serial = false; 15594 dns_tsigkey_t *tsigkey; 15595 const dns_name_t *tsig; 15596 15597 REQUIRE(DNS_ZONE_VALID(zone)); 15598 15599 /* 15600 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support 15601 * ROLLOVER. 15602 * 15603 * SOA: RFC1996 15604 * Check that 'from' is a valid notify source, (zone->primaries). 15605 * Return DNS_R_REFUSED if not. 15606 * 15607 * If the notify message contains a serial number check it 15608 * against the zones serial and return if <= current serial 15609 * 15610 * If a refresh check is progress, if so just record the 15611 * fact we received a NOTIFY and from where and return. 15612 * We will perform a new refresh check when the current one 15613 * completes. Return ISC_R_SUCCESS. 15614 * 15615 * Otherwise initiate a refresh check using 'from' as the 15616 * first address to check. Return ISC_R_SUCCESS. 15617 */ 15618 15619 isc_sockaddr_format(from, fromtext, sizeof(fromtext)); 15620 15621 /* 15622 * Notify messages are processed by the raw zone. 15623 */ 15624 LOCK_ZONE(zone); 15625 INSIST(zone != zone->raw); 15626 if (inline_secure(zone)) { 15627 result = dns_zone_notifyreceive(zone->raw, from, to, msg); 15628 UNLOCK_ZONE(zone); 15629 return result; 15630 } 15631 /* 15632 * We only handle NOTIFY (SOA) at the present. 15633 */ 15634 if (isc_sockaddr_pf(from) == PF_INET) { 15635 inc_stats(zone, dns_zonestatscounter_notifyinv4); 15636 } else { 15637 inc_stats(zone, dns_zonestatscounter_notifyinv6); 15638 } 15639 if (msg->counts[DNS_SECTION_QUESTION] == 0 || 15640 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin, 15641 dns_rdatatype_soa, dns_rdatatype_none, NULL, 15642 NULL) != ISC_R_SUCCESS) 15643 { 15644 UNLOCK_ZONE(zone); 15645 if (msg->counts[DNS_SECTION_QUESTION] == 0) { 15646 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 15647 ISC_LOG_NOTICE, 15648 "NOTIFY with no question " 15649 "section from: %s", 15650 fromtext); 15651 return DNS_R_FORMERR; 15652 } 15653 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_NOTICE, 15654 "NOTIFY zone does not match"); 15655 return DNS_R_NOTIMP; 15656 } 15657 15658 /* 15659 * If we are a primary zone just succeed. 15660 */ 15661 if (zone->type == dns_zone_primary) { 15662 UNLOCK_ZONE(zone); 15663 return ISC_R_SUCCESS; 15664 } 15665 15666 isc_netaddr_fromsockaddr(&netaddr, from); 15667 for (i = 0; i < dns_remote_count(&zone->primaries); i++) { 15668 isc_sockaddr_t sockaddr = dns_remote_addr(&zone->primaries, i); 15669 if (isc_sockaddr_eqaddr(from, &sockaddr)) { 15670 break; 15671 } 15672 if (zone->view->aclenv->match_mapped && 15673 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) && 15674 isc_sockaddr_pf(&sockaddr) == AF_INET) 15675 { 15676 isc_netaddr_t na1, na2; 15677 isc_netaddr_fromv4mapped(&na1, &netaddr); 15678 isc_netaddr_fromsockaddr(&na2, &sockaddr); 15679 if (isc_netaddr_equal(&na1, &na2)) { 15680 break; 15681 } 15682 } 15683 } 15684 15685 /* 15686 * Accept notify requests from non primaries if they are on 15687 * 'zone->notify_acl'. 15688 */ 15689 tsigkey = dns_message_gettsigkey(msg); 15690 tsig = dns_tsigkey_identity(tsigkey); 15691 if (i >= dns_remote_count(&zone->primaries) && 15692 zone->notify_acl != NULL && 15693 (dns_acl_match(&netaddr, tsig, zone->notify_acl, zone->view->aclenv, 15694 &match, NULL) == ISC_R_SUCCESS) && 15695 match > 0) 15696 { 15697 /* Accept notify. */ 15698 } else if (i >= dns_remote_count(&zone->primaries)) { 15699 UNLOCK_ZONE(zone); 15700 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 15701 "refused notify from non-primary: %s", fromtext); 15702 inc_stats(zone, dns_zonestatscounter_notifyrej); 15703 return DNS_R_REFUSED; 15704 } 15705 15706 /* 15707 * If the zone is loaded and there are answers check the serial 15708 * to see if we need to do a refresh. Do not worry about this 15709 * check if we are a dialup zone as we use the notify request 15710 * to trigger a refresh check. 15711 */ 15712 if (msg->counts[DNS_SECTION_ANSWER] > 0 && 15713 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 15714 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) 15715 { 15716 result = dns_message_findname( 15717 msg, DNS_SECTION_ANSWER, &zone->origin, 15718 dns_rdatatype_soa, dns_rdatatype_none, NULL, &rdataset); 15719 if (result == ISC_R_SUCCESS) { 15720 result = dns_rdataset_first(rdataset); 15721 } 15722 if (result == ISC_R_SUCCESS) { 15723 uint32_t oldserial; 15724 unsigned int soacount; 15725 15726 dns_rdataset_current(rdataset, &rdata); 15727 result = dns_rdata_tostruct(&rdata, &soa, NULL); 15728 RUNTIME_CHECK(result == ISC_R_SUCCESS); 15729 serial = soa.serial; 15730 have_serial = true; 15731 /* 15732 * The following should safely be performed without DB 15733 * lock and succeed in this context. 15734 */ 15735 result = zone_get_from_db(zone, zone->db, NULL, 15736 &soacount, NULL, &oldserial, 15737 NULL, NULL, NULL, NULL, NULL); 15738 RUNTIME_CHECK(result == ISC_R_SUCCESS); 15739 RUNTIME_CHECK(soacount > 0U); 15740 if (isc_serial_le(serial, oldserial)) { 15741 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 15742 ISC_LOG_INFO, 15743 "notify from %s: " 15744 "zone is up to date", 15745 fromtext); 15746 UNLOCK_ZONE(zone); 15747 return ISC_R_SUCCESS; 15748 } 15749 } 15750 } 15751 15752 /* 15753 * If we got this far and there was a refresh in progress just 15754 * let it complete. Record where we got the notify from so we 15755 * can perform a refresh check when the current one completes 15756 */ 15757 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { 15758 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 15759 zone->notifyfrom = *from; 15760 UNLOCK_ZONE(zone); 15761 if (have_serial) { 15762 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 15763 ISC_LOG_INFO, 15764 "notify from %s: " 15765 "serial %u: refresh in progress, " 15766 "refresh check queued", 15767 fromtext, serial); 15768 } else { 15769 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 15770 ISC_LOG_INFO, 15771 "notify from %s: " 15772 "refresh in progress, " 15773 "refresh check queued", 15774 fromtext); 15775 } 15776 return ISC_R_SUCCESS; 15777 } 15778 if (have_serial) { 15779 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 15780 "notify from %s: serial %u", fromtext, serial); 15781 } else { 15782 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 15783 "notify from %s: no serial", fromtext); 15784 } 15785 zone->notifyfrom = *from; 15786 UNLOCK_ZONE(zone); 15787 15788 if (to != NULL) { 15789 dns_zonemgr_unreachabledel(zone->zmgr, from, to); 15790 } 15791 dns_zone_refresh(zone); 15792 return ISC_R_SUCCESS; 15793 } 15794 15795 void 15796 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) { 15797 REQUIRE(DNS_ZONE_VALID(zone)); 15798 15799 LOCK_ZONE(zone); 15800 if (zone->notify_acl != NULL) { 15801 dns_acl_detach(&zone->notify_acl); 15802 } 15803 dns_acl_attach(acl, &zone->notify_acl); 15804 UNLOCK_ZONE(zone); 15805 } 15806 15807 void 15808 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) { 15809 REQUIRE(DNS_ZONE_VALID(zone)); 15810 15811 LOCK_ZONE(zone); 15812 if (zone->query_acl != NULL) { 15813 dns_acl_detach(&zone->query_acl); 15814 } 15815 dns_acl_attach(acl, &zone->query_acl); 15816 UNLOCK_ZONE(zone); 15817 } 15818 15819 void 15820 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) { 15821 REQUIRE(DNS_ZONE_VALID(zone)); 15822 15823 LOCK_ZONE(zone); 15824 if (zone->queryon_acl != NULL) { 15825 dns_acl_detach(&zone->queryon_acl); 15826 } 15827 dns_acl_attach(acl, &zone->queryon_acl); 15828 UNLOCK_ZONE(zone); 15829 } 15830 15831 void 15832 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) { 15833 REQUIRE(DNS_ZONE_VALID(zone)); 15834 15835 LOCK_ZONE(zone); 15836 if (zone->update_acl != NULL) { 15837 dns_acl_detach(&zone->update_acl); 15838 } 15839 dns_acl_attach(acl, &zone->update_acl); 15840 UNLOCK_ZONE(zone); 15841 } 15842 15843 void 15844 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) { 15845 REQUIRE(DNS_ZONE_VALID(zone)); 15846 15847 LOCK_ZONE(zone); 15848 if (zone->forward_acl != NULL) { 15849 dns_acl_detach(&zone->forward_acl); 15850 } 15851 dns_acl_attach(acl, &zone->forward_acl); 15852 UNLOCK_ZONE(zone); 15853 } 15854 15855 void 15856 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) { 15857 REQUIRE(DNS_ZONE_VALID(zone)); 15858 15859 LOCK_ZONE(zone); 15860 if (zone->xfr_acl != NULL) { 15861 dns_acl_detach(&zone->xfr_acl); 15862 } 15863 dns_acl_attach(acl, &zone->xfr_acl); 15864 UNLOCK_ZONE(zone); 15865 } 15866 15867 dns_acl_t * 15868 dns_zone_getnotifyacl(dns_zone_t *zone) { 15869 REQUIRE(DNS_ZONE_VALID(zone)); 15870 15871 return zone->notify_acl; 15872 } 15873 15874 dns_acl_t * 15875 dns_zone_getqueryacl(dns_zone_t *zone) { 15876 REQUIRE(DNS_ZONE_VALID(zone)); 15877 15878 return zone->query_acl; 15879 } 15880 15881 dns_acl_t * 15882 dns_zone_getqueryonacl(dns_zone_t *zone) { 15883 REQUIRE(DNS_ZONE_VALID(zone)); 15884 15885 return zone->queryon_acl; 15886 } 15887 15888 dns_acl_t * 15889 dns_zone_getupdateacl(dns_zone_t *zone) { 15890 REQUIRE(DNS_ZONE_VALID(zone)); 15891 15892 return zone->update_acl; 15893 } 15894 15895 dns_acl_t * 15896 dns_zone_getforwardacl(dns_zone_t *zone) { 15897 REQUIRE(DNS_ZONE_VALID(zone)); 15898 15899 return zone->forward_acl; 15900 } 15901 15902 dns_acl_t * 15903 dns_zone_getxfracl(dns_zone_t *zone) { 15904 REQUIRE(DNS_ZONE_VALID(zone)); 15905 15906 return zone->xfr_acl; 15907 } 15908 15909 void 15910 dns_zone_clearupdateacl(dns_zone_t *zone) { 15911 REQUIRE(DNS_ZONE_VALID(zone)); 15912 15913 LOCK_ZONE(zone); 15914 if (zone->update_acl != NULL) { 15915 dns_acl_detach(&zone->update_acl); 15916 } 15917 UNLOCK_ZONE(zone); 15918 } 15919 15920 void 15921 dns_zone_clearforwardacl(dns_zone_t *zone) { 15922 REQUIRE(DNS_ZONE_VALID(zone)); 15923 15924 LOCK_ZONE(zone); 15925 if (zone->forward_acl != NULL) { 15926 dns_acl_detach(&zone->forward_acl); 15927 } 15928 UNLOCK_ZONE(zone); 15929 } 15930 15931 void 15932 dns_zone_clearnotifyacl(dns_zone_t *zone) { 15933 REQUIRE(DNS_ZONE_VALID(zone)); 15934 15935 LOCK_ZONE(zone); 15936 if (zone->notify_acl != NULL) { 15937 dns_acl_detach(&zone->notify_acl); 15938 } 15939 UNLOCK_ZONE(zone); 15940 } 15941 15942 void 15943 dns_zone_clearqueryacl(dns_zone_t *zone) { 15944 REQUIRE(DNS_ZONE_VALID(zone)); 15945 15946 LOCK_ZONE(zone); 15947 if (zone->query_acl != NULL) { 15948 dns_acl_detach(&zone->query_acl); 15949 } 15950 UNLOCK_ZONE(zone); 15951 } 15952 15953 void 15954 dns_zone_clearqueryonacl(dns_zone_t *zone) { 15955 REQUIRE(DNS_ZONE_VALID(zone)); 15956 15957 LOCK_ZONE(zone); 15958 if (zone->queryon_acl != NULL) { 15959 dns_acl_detach(&zone->queryon_acl); 15960 } 15961 UNLOCK_ZONE(zone); 15962 } 15963 15964 void 15965 dns_zone_clearxfracl(dns_zone_t *zone) { 15966 REQUIRE(DNS_ZONE_VALID(zone)); 15967 15968 LOCK_ZONE(zone); 15969 if (zone->xfr_acl != NULL) { 15970 dns_acl_detach(&zone->xfr_acl); 15971 } 15972 UNLOCK_ZONE(zone); 15973 } 15974 15975 bool 15976 dns_zone_getupdatedisabled(dns_zone_t *zone) { 15977 REQUIRE(DNS_ZONE_VALID(zone)); 15978 return zone->update_disabled; 15979 } 15980 15981 void 15982 dns_zone_setupdatedisabled(dns_zone_t *zone, bool state) { 15983 REQUIRE(DNS_ZONE_VALID(zone)); 15984 zone->update_disabled = state; 15985 } 15986 15987 bool 15988 dns_zone_getzeronosoattl(dns_zone_t *zone) { 15989 REQUIRE(DNS_ZONE_VALID(zone)); 15990 return zone->zero_no_soa_ttl; 15991 } 15992 15993 void 15994 dns_zone_setzeronosoattl(dns_zone_t *zone, bool state) { 15995 REQUIRE(DNS_ZONE_VALID(zone)); 15996 zone->zero_no_soa_ttl = state; 15997 } 15998 15999 void 16000 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) { 16001 REQUIRE(DNS_ZONE_VALID(zone)); 16002 16003 zone->check_names = severity; 16004 } 16005 16006 dns_severity_t 16007 dns_zone_getchecknames(dns_zone_t *zone) { 16008 REQUIRE(DNS_ZONE_VALID(zone)); 16009 16010 return zone->check_names; 16011 } 16012 16013 void 16014 dns_zone_setjournalsize(dns_zone_t *zone, int32_t size) { 16015 REQUIRE(DNS_ZONE_VALID(zone)); 16016 16017 zone->journalsize = size; 16018 } 16019 16020 int32_t 16021 dns_zone_getjournalsize(dns_zone_t *zone) { 16022 REQUIRE(DNS_ZONE_VALID(zone)); 16023 16024 return zone->journalsize; 16025 } 16026 16027 static void 16028 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) { 16029 isc_result_t result = ISC_R_FAILURE; 16030 isc_buffer_t buffer; 16031 16032 REQUIRE(buf != NULL); 16033 REQUIRE(length > 1U); 16034 16035 /* 16036 * Leave space for terminating '\0'. 16037 */ 16038 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 16039 if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) { 16040 if (dns_name_dynamic(&zone->origin)) { 16041 result = dns_name_totext( 16042 &zone->origin, DNS_NAME_OMITFINALDOT, &buffer); 16043 } 16044 if (result != ISC_R_SUCCESS && 16045 isc_buffer_availablelength(&buffer) >= 16046 (sizeof("<UNKNOWN>") - 1)) 16047 { 16048 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 16049 } 16050 16051 if (isc_buffer_availablelength(&buffer) > 0) { 16052 isc_buffer_putstr(&buffer, "/"); 16053 } 16054 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 16055 } 16056 16057 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 && 16058 strcmp(zone->view->name, "_default") != 0 && 16059 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) 16060 { 16061 isc_buffer_putstr(&buffer, "/"); 16062 isc_buffer_putstr(&buffer, zone->view->name); 16063 } 16064 if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer)) { 16065 isc_buffer_putstr(&buffer, " (signed)"); 16066 } 16067 if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer)) { 16068 isc_buffer_putstr(&buffer, " (unsigned)"); 16069 } 16070 16071 buf[isc_buffer_usedlength(&buffer)] = '\0'; 16072 } 16073 16074 static void 16075 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) { 16076 isc_result_t result = ISC_R_FAILURE; 16077 isc_buffer_t buffer; 16078 16079 REQUIRE(buf != NULL); 16080 REQUIRE(length > 1U); 16081 16082 /* 16083 * Leave space for terminating '\0'. 16084 */ 16085 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 16086 if (dns_name_dynamic(&zone->origin)) { 16087 result = dns_name_totext(&zone->origin, DNS_NAME_OMITFINALDOT, 16088 &buffer); 16089 } 16090 if (result != ISC_R_SUCCESS && 16091 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1)) 16092 { 16093 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 16094 } 16095 16096 buf[isc_buffer_usedlength(&buffer)] = '\0'; 16097 } 16098 16099 static void 16100 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) { 16101 isc_buffer_t buffer; 16102 16103 REQUIRE(buf != NULL); 16104 REQUIRE(length > 1U); 16105 16106 /* 16107 * Leave space for terminating '\0'. 16108 */ 16109 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 16110 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 16111 16112 buf[isc_buffer_usedlength(&buffer)] = '\0'; 16113 } 16114 16115 static void 16116 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) { 16117 isc_buffer_t buffer; 16118 16119 REQUIRE(buf != NULL); 16120 REQUIRE(length > 1U); 16121 16122 /* 16123 * Leave space for terminating '\0'. 16124 */ 16125 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 16126 16127 if (zone->view == NULL) { 16128 isc_buffer_putstr(&buffer, "_none"); 16129 } else if (strlen(zone->view->name) < 16130 isc_buffer_availablelength(&buffer)) 16131 { 16132 isc_buffer_putstr(&buffer, zone->view->name); 16133 } else { 16134 isc_buffer_putstr(&buffer, "_toolong"); 16135 } 16136 16137 buf[isc_buffer_usedlength(&buffer)] = '\0'; 16138 } 16139 16140 void 16141 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) { 16142 REQUIRE(DNS_ZONE_VALID(zone)); 16143 REQUIRE(buf != NULL); 16144 16145 LOCK_ZONE(zone); 16146 zone_namerd_tostr(zone, buf, length); 16147 UNLOCK_ZONE(zone); 16148 } 16149 16150 void 16151 dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) { 16152 REQUIRE(DNS_ZONE_VALID(zone)); 16153 REQUIRE(buf != NULL); 16154 zone_name_tostr(zone, buf, length); 16155 } 16156 16157 void 16158 dns_zone_logv(dns_zone_t *zone, isc_logcategory_t *category, int level, 16159 const char *prefix, const char *fmt, va_list ap) { 16160 char message[4096]; 16161 const char *zstr; 16162 16163 REQUIRE(DNS_ZONE_VALID(zone)); 16164 16165 if (!isc_log_wouldlog(dns_lctx, level)) { 16166 return; 16167 } 16168 16169 vsnprintf(message, sizeof(message), fmt, ap); 16170 16171 switch (zone->type) { 16172 case dns_zone_key: 16173 zstr = "managed-keys-zone"; 16174 break; 16175 case dns_zone_redirect: 16176 zstr = "redirect-zone"; 16177 break; 16178 default: 16179 zstr = "zone "; 16180 } 16181 16182 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, level, 16183 "%s%s%s%s: %s", prefix != NULL ? prefix : "", 16184 prefix != NULL ? ": " : "", zstr, zone->strnamerd, 16185 message); 16186 } 16187 16188 static void 16189 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) { 16190 va_list ap; 16191 16192 va_start(ap, fmt); 16193 dns_zone_logv(zone, DNS_LOGCATEGORY_NOTIFY, level, NULL, fmt, ap); 16194 va_end(ap); 16195 } 16196 16197 void 16198 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, int level, 16199 const char *fmt, ...) { 16200 va_list ap; 16201 16202 va_start(ap, fmt); 16203 dns_zone_logv(zone, category, level, NULL, fmt, ap); 16204 va_end(ap); 16205 } 16206 16207 void 16208 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) { 16209 va_list ap; 16210 16211 va_start(ap, fmt); 16212 dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, NULL, fmt, ap); 16213 va_end(ap); 16214 } 16215 16216 static void 16217 zone_debuglogc(dns_zone_t *zone, isc_logcategory_t *category, const char *me, 16218 int debuglevel, const char *fmt, ...) { 16219 int level = ISC_LOG_DEBUG(debuglevel); 16220 va_list ap; 16221 16222 va_start(ap, fmt); 16223 dns_zone_logv(zone, category, level, me, fmt, ap); 16224 va_end(ap); 16225 } 16226 16227 static void 16228 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel, const char *fmt, 16229 ...) { 16230 int level = ISC_LOG_DEBUG(debuglevel); 16231 va_list ap; 16232 16233 va_start(ap, fmt); 16234 dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, me, fmt, ap); 16235 va_end(ap); 16236 } 16237 16238 static void 16239 dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...) { 16240 va_list ap; 16241 16242 va_start(ap, fmt); 16243 dns_zone_logv(zone, DNS_LOGCATEGORY_DNSSEC, level, NULL, fmt, ap); 16244 va_end(ap); 16245 } 16246 16247 static int 16248 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type) { 16249 isc_result_t result; 16250 dns_name_t *name; 16251 dns_rdataset_t *curr; 16252 int count = 0; 16253 16254 result = dns_message_firstname(msg, section); 16255 while (result == ISC_R_SUCCESS) { 16256 name = NULL; 16257 dns_message_currentname(msg, section, &name); 16258 16259 for (curr = ISC_LIST_TAIL(name->list); curr != NULL; 16260 curr = ISC_LIST_PREV(curr, link)) 16261 { 16262 if (curr->type == type) { 16263 count++; 16264 } 16265 } 16266 result = dns_message_nextname(msg, section); 16267 } 16268 16269 return count; 16270 } 16271 16272 void 16273 dns_zone_setminxfrratein(dns_zone_t *zone, uint32_t bytes, uint32_t seconds) { 16274 REQUIRE(DNS_ZONE_VALID(zone)); 16275 16276 zone->minxfrratebytesin = bytes; 16277 zone->minxfrratesecondsin = seconds; 16278 } 16279 16280 uint32_t 16281 dns_zone_getminxfrratebytesin(dns_zone_t *zone) { 16282 REQUIRE(DNS_ZONE_VALID(zone)); 16283 16284 return zone->minxfrratebytesin; 16285 } 16286 16287 uint32_t 16288 dns_zone_getminxfrratesecondsin(dns_zone_t *zone) { 16289 REQUIRE(DNS_ZONE_VALID(zone)); 16290 16291 return zone->minxfrratesecondsin; 16292 } 16293 16294 void 16295 dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin) { 16296 REQUIRE(DNS_ZONE_VALID(zone)); 16297 16298 zone->maxxfrin = maxxfrin; 16299 } 16300 16301 uint32_t 16302 dns_zone_getmaxxfrin(dns_zone_t *zone) { 16303 REQUIRE(DNS_ZONE_VALID(zone)); 16304 16305 return zone->maxxfrin; 16306 } 16307 16308 void 16309 dns_zone_setmaxxfrout(dns_zone_t *zone, uint32_t maxxfrout) { 16310 REQUIRE(DNS_ZONE_VALID(zone)); 16311 zone->maxxfrout = maxxfrout; 16312 } 16313 16314 uint32_t 16315 dns_zone_getmaxxfrout(dns_zone_t *zone) { 16316 REQUIRE(DNS_ZONE_VALID(zone)); 16317 16318 return zone->maxxfrout; 16319 } 16320 16321 dns_zonetype_t 16322 dns_zone_gettype(dns_zone_t *zone) { 16323 REQUIRE(DNS_ZONE_VALID(zone)); 16324 16325 return zone->type; 16326 } 16327 16328 const char * 16329 dns_zonetype_name(dns_zonetype_t type) { 16330 switch (type) { 16331 case dns_zone_none: 16332 return "none"; 16333 case dns_zone_primary: 16334 return "primary"; 16335 case dns_zone_secondary: 16336 return "secondary"; 16337 case dns_zone_mirror: 16338 return "mirror"; 16339 case dns_zone_stub: 16340 return "stub"; 16341 case dns_zone_staticstub: 16342 return "static-stub"; 16343 case dns_zone_key: 16344 return "key"; 16345 case dns_zone_dlz: 16346 return "dlz"; 16347 case dns_zone_redirect: 16348 return "redirect"; 16349 default: 16350 return "unknown"; 16351 } 16352 } 16353 16354 dns_zonetype_t 16355 dns_zone_getredirecttype(dns_zone_t *zone) { 16356 REQUIRE(DNS_ZONE_VALID(zone)); 16357 REQUIRE(zone->type == dns_zone_redirect); 16358 16359 return dns_remote_addresses(&zone->primaries) == NULL 16360 ? dns_zone_primary 16361 : dns_zone_secondary; 16362 } 16363 16364 dns_name_t * 16365 dns_zone_getorigin(dns_zone_t *zone) { 16366 REQUIRE(DNS_ZONE_VALID(zone)); 16367 16368 return &zone->origin; 16369 } 16370 16371 void 16372 dns_zone_setidlein(dns_zone_t *zone, uint32_t idlein) { 16373 REQUIRE(DNS_ZONE_VALID(zone)); 16374 16375 if (idlein == 0) { 16376 idlein = DNS_DEFAULT_IDLEIN; 16377 } 16378 zone->idlein = idlein; 16379 } 16380 16381 uint32_t 16382 dns_zone_getidlein(dns_zone_t *zone) { 16383 REQUIRE(DNS_ZONE_VALID(zone)); 16384 16385 return zone->idlein; 16386 } 16387 16388 void 16389 dns_zone_setidleout(dns_zone_t *zone, uint32_t idleout) { 16390 REQUIRE(DNS_ZONE_VALID(zone)); 16391 16392 zone->idleout = idleout; 16393 } 16394 16395 uint32_t 16396 dns_zone_getidleout(dns_zone_t *zone) { 16397 REQUIRE(DNS_ZONE_VALID(zone)); 16398 16399 return zone->idleout; 16400 } 16401 16402 static void 16403 notify_done(void *arg) { 16404 dns_request_t *request = (dns_request_t *)arg; 16405 dns_notify_t *notify = dns_request_getarg(request); 16406 isc_result_t result; 16407 dns_message_t *message = NULL; 16408 isc_buffer_t buf; 16409 char rcode[128]; 16410 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 16411 16412 REQUIRE(DNS_NOTIFY_VALID(notify)); 16413 16414 isc_buffer_init(&buf, rcode, sizeof(rcode)); 16415 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 16416 dns_message_create(notify->zone->mctx, NULL, NULL, 16417 DNS_MESSAGE_INTENTPARSE, &message); 16418 16419 result = dns_request_getresult(request); 16420 if (result != ISC_R_SUCCESS) { 16421 goto fail; 16422 } 16423 16424 result = dns_request_getresponse(request, message, 16425 DNS_MESSAGEPARSE_PRESERVEORDER); 16426 if (result != ISC_R_SUCCESS) { 16427 goto fail; 16428 } 16429 16430 result = dns_rcode_totext(message->rcode, &buf); 16431 if (result == ISC_R_SUCCESS) { 16432 notify_log(notify->zone, ISC_LOG_DEBUG(3), 16433 "notify response from %s: %.*s", addrbuf, 16434 (int)buf.used, rcode); 16435 } 16436 16437 fail: 16438 dns_message_detach(&message); 16439 16440 if (result == ISC_R_SUCCESS) { 16441 notify_log(notify->zone, ISC_LOG_DEBUG(1), 16442 "notify to %s successful", addrbuf); 16443 } else if (result == ISC_R_SHUTTINGDOWN || result == ISC_R_CANCELED) { 16444 /* just destroy the notify */ 16445 } else if ((notify->flags & DNS_NOTIFY_TCP) == 0) { 16446 notify_log(notify->zone, ISC_LOG_NOTICE, 16447 "notify to %s failed: %s: retrying over TCP", 16448 addrbuf, isc_result_totext(result)); 16449 notify->flags |= DNS_NOTIFY_TCP; 16450 dns_request_destroy(¬ify->request); 16451 notify_send_queue(notify, notify->flags & DNS_NOTIFY_STARTUP); 16452 return; 16453 } else if (result == ISC_R_TIMEDOUT) { 16454 notify_log(notify->zone, ISC_LOG_WARNING, 16455 "notify to %s failed: %s: retries exceeded", addrbuf, 16456 isc_result_totext(result)); 16457 } else { 16458 notify_log(notify->zone, ISC_LOG_WARNING, 16459 "notify to %s failed: %s", addrbuf, 16460 isc_result_totext(result)); 16461 } 16462 notify_destroy(notify, false); 16463 } 16464 16465 struct rss { 16466 dns_zone_t *zone; 16467 dns_db_t *db; 16468 uint32_t serial; 16469 ISC_LINK(struct rss) link; 16470 }; 16471 16472 static void 16473 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) { 16474 UNUSED(arg); 16475 dns_zone_log(zone, level, "%s", message); 16476 } 16477 16478 static isc_result_t 16479 dnskey_inuse(dns_zone_t *zone, dns_rdata_t *rdata, isc_mem_t *mctx, 16480 dns_dnsseckeylist_t *keylist, bool *inuse) { 16481 isc_result_t result; 16482 dst_key_t *dstkey = NULL; 16483 16484 result = dns_dnssec_keyfromrdata(dns_zone_getorigin(zone), rdata, mctx, 16485 &dstkey); 16486 if (result != ISC_R_SUCCESS) { 16487 dns_zone_log(zone, ISC_LOG_ERROR, 16488 "dns_dnssec_keyfromrdata() failed: %s", 16489 isc_result_totext(result)); 16490 return result; 16491 } 16492 16493 for (dns_dnsseckey_t *k = ISC_LIST_HEAD(*keylist); k != NULL; 16494 k = ISC_LIST_NEXT(k, link)) 16495 { 16496 if (dst_key_pubcompare(k->key, dstkey, false)) { 16497 *inuse = true; 16498 break; 16499 } 16500 } 16501 16502 dst_key_free(&dstkey); 16503 return ISC_R_SUCCESS; 16504 } 16505 16506 static isc_result_t 16507 cdnskey_inuse(dns_zone_t *zone, dns_rdata_t *rdata, 16508 dns_dnsseckeylist_t *keylist, bool *inuse) { 16509 isc_result_t result; 16510 dns_rdata_cdnskey_t cdnskey; 16511 16512 result = dns_rdata_tostruct(rdata, &cdnskey, NULL); 16513 if (result != ISC_R_SUCCESS) { 16514 dns_zone_log(zone, ISC_LOG_ERROR, 16515 "dns_rdata_tostruct(cdnskey) failed: %s", 16516 isc_result_totext(result)); 16517 return result; 16518 } 16519 16520 for (dns_dnsseckey_t *k = ISC_LIST_HEAD(*keylist); k != NULL; 16521 k = ISC_LIST_NEXT(k, link)) 16522 { 16523 dns_rdata_t cdnskeyrdata = DNS_RDATA_INIT; 16524 unsigned char keybuf[DST_KEY_MAXSIZE]; 16525 16526 result = dns_dnssec_make_dnskey(k->key, keybuf, sizeof(keybuf), 16527 &cdnskeyrdata); 16528 if (result != ISC_R_SUCCESS) { 16529 dns_zone_log(zone, ISC_LOG_ERROR, 16530 "dns_dnssec_make_dnskey() failed: %s", 16531 isc_result_totext(result)); 16532 return result; 16533 } 16534 16535 cdnskeyrdata.type = dns_rdatatype_cdnskey; 16536 if (dns_rdata_compare(rdata, &cdnskeyrdata) == 0) { 16537 *inuse = true; 16538 break; 16539 } 16540 } 16541 16542 return ISC_R_SUCCESS; 16543 } 16544 16545 static isc_result_t 16546 cds_inuse(dns_zone_t *zone, dns_rdata_t *rdata, dns_dnsseckeylist_t *keylist, 16547 bool *inuse) { 16548 isc_result_t result; 16549 dns_rdata_ds_t cds; 16550 16551 result = dns_rdata_tostruct(rdata, &cds, NULL); 16552 if (result != ISC_R_SUCCESS) { 16553 dns_zone_log(zone, ISC_LOG_ERROR, 16554 "dns_rdata_tostruct(cds) failed: %s", 16555 isc_result_totext(result)); 16556 return result; 16557 } 16558 16559 for (dns_dnsseckey_t *k = ISC_LIST_HEAD(*keylist); k != NULL; 16560 k = ISC_LIST_NEXT(k, link)) 16561 { 16562 dns_rdata_t dnskey = DNS_RDATA_INIT; 16563 dns_rdata_t cdsrdata = DNS_RDATA_INIT; 16564 unsigned char keybuf[DST_KEY_MAXSIZE]; 16565 unsigned char cdsbuf[DNS_DS_BUFFERSIZE]; 16566 16567 if (dst_key_id(k->key) != cds.key_tag || 16568 dst_key_alg(k->key) != cds.algorithm) 16569 { 16570 continue; 16571 } 16572 result = dns_dnssec_make_dnskey(k->key, keybuf, sizeof(keybuf), 16573 &dnskey); 16574 if (result != ISC_R_SUCCESS) { 16575 dns_zone_log(zone, ISC_LOG_ERROR, 16576 "dns_dnssec_make_dnskey() failed: %s", 16577 isc_result_totext(result)); 16578 return result; 16579 } 16580 result = dns_ds_buildrdata(dns_zone_getorigin(zone), &dnskey, 16581 cds.digest_type, cdsbuf, &cdsrdata); 16582 if (result != ISC_R_SUCCESS) { 16583 dns_zone_log(zone, ISC_LOG_ERROR, 16584 "dns_ds_buildrdata(keytag=%d, algo=%d, " 16585 "digest=%d) failed: %s", 16586 cds.key_tag, cds.algorithm, 16587 cds.digest_type, 16588 isc_result_totext(result)); 16589 return result; 16590 } 16591 16592 cdsrdata.type = dns_rdatatype_cds; 16593 if (dns_rdata_compare(rdata, &cdsrdata) == 0) { 16594 *inuse = true; 16595 break; 16596 } 16597 } 16598 16599 return ISC_R_SUCCESS; 16600 } 16601 16602 isc_result_t 16603 dns_zone_dnskey_inuse(dns_zone_t *zone, dns_rdata_t *rdata, bool *inuse) { 16604 dns_dnsseckeylist_t keylist; 16605 dns_dnsseckey_t *key = NULL; 16606 isc_result_t result = ISC_R_SUCCESS; 16607 isc_stdtime_t now = isc_stdtime_now(); 16608 isc_mem_t *mctx; 16609 dns_kasp_t *kasp; 16610 dns_keystorelist_t *keystores; 16611 const char *keydir; 16612 16613 REQUIRE(DNS_ZONE_VALID(zone)); 16614 REQUIRE(dns_rdatatype_iskeymaterial(rdata->type)); 16615 16616 mctx = zone->mctx; 16617 16618 ISC_LIST_INIT(keylist); 16619 16620 *inuse = false; 16621 16622 kasp = dns_zone_getkasp(zone); 16623 keydir = dns_zone_getkeydirectory(zone); 16624 keystores = dns_zone_getkeystores(zone); 16625 16626 dns_zone_lock_keyfiles(zone); 16627 result = dns_dnssec_findmatchingkeys(dns_zone_getorigin(zone), kasp, 16628 keydir, keystores, now, false, 16629 mctx, &keylist); 16630 dns_zone_unlock_keyfiles(zone); 16631 if (result == ISC_R_NOTFOUND) { 16632 return ISC_R_SUCCESS; 16633 } else if (result != ISC_R_SUCCESS) { 16634 dns_zone_log(zone, ISC_LOG_ERROR, 16635 "dns_dnssec_findmatchingkeys() failed: %s", 16636 isc_result_totext(result)); 16637 return result; 16638 } 16639 16640 switch (rdata->type) { 16641 case dns_rdatatype_dnskey: 16642 result = dnskey_inuse(zone, rdata, mctx, &keylist, inuse); 16643 break; 16644 case dns_rdatatype_cdnskey: 16645 result = cdnskey_inuse(zone, rdata, &keylist, inuse); 16646 break; 16647 case dns_rdatatype_cds: 16648 result = cds_inuse(zone, rdata, &keylist, inuse); 16649 break; 16650 default: 16651 UNREACHABLE(); 16652 break; 16653 } 16654 16655 while (!ISC_LIST_EMPTY(keylist)) { 16656 key = ISC_LIST_HEAD(keylist); 16657 ISC_LIST_UNLINK(keylist, key, link); 16658 dns_dnsseckey_destroy(mctx, &key); 16659 } 16660 return result; 16661 } 16662 16663 static isc_result_t 16664 sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal, 16665 uint32_t start, uint32_t end, dns_difftuple_t **soatuplep, 16666 dns_diff_t *diff) { 16667 isc_result_t result; 16668 dns_difftuple_t *tuple = NULL; 16669 dns_diffop_t op = DNS_DIFFOP_ADD; 16670 int n_soa = 0; 16671 16672 REQUIRE(soatuplep != NULL); 16673 16674 if (start == end) { 16675 return DNS_R_UNCHANGED; 16676 } 16677 16678 CHECK(dns_journal_iter_init(journal, start, end, NULL)); 16679 for (result = dns_journal_first_rr(journal); result == ISC_R_SUCCESS; 16680 result = dns_journal_next_rr(journal)) 16681 { 16682 dns_name_t *name = NULL; 16683 uint32_t ttl; 16684 dns_rdata_t *rdata = NULL; 16685 dns_journal_current_rr(journal, &name, &ttl, &rdata); 16686 16687 if (rdata->type == dns_rdatatype_soa) { 16688 n_soa++; 16689 if (n_soa == 2) { 16690 /* 16691 * Save the latest raw SOA record. 16692 */ 16693 if (*soatuplep != NULL) { 16694 dns_difftuple_free(soatuplep); 16695 } 16696 CHECK(dns_difftuple_create( 16697 diff->mctx, DNS_DIFFOP_ADD, name, ttl, 16698 rdata, soatuplep)); 16699 } 16700 if (n_soa == 3) { 16701 n_soa = 1; 16702 } 16703 continue; 16704 } 16705 16706 /* Sanity. */ 16707 if (n_soa == 0) { 16708 dns_zone_log(raw, ISC_LOG_ERROR, 16709 "corrupt journal file: '%s'\n", 16710 raw->journal); 16711 return ISC_R_FAILURE; 16712 } 16713 16714 if (zone->privatetype != 0 && rdata->type == zone->privatetype) 16715 { 16716 continue; 16717 } 16718 16719 /* 16720 * Skip DNSSEC records that BIND maintains with inline-signing. 16721 */ 16722 if (rdata->type == dns_rdatatype_nsec || 16723 rdata->type == dns_rdatatype_rrsig || 16724 rdata->type == dns_rdatatype_nsec3 || 16725 rdata->type == dns_rdatatype_nsec3param) 16726 { 16727 continue; 16728 } 16729 /* 16730 * Allow DNSKEY, CDNSKEY, CDS because users should be able to 16731 * update the zone with these records from a different provider, 16732 * but skip records that are under our control. 16733 */ 16734 if (dns_rdatatype_iskeymaterial(rdata->type)) { 16735 bool inuse = false; 16736 isc_result_t r = dns_zone_dnskey_inuse(zone, rdata, 16737 &inuse); 16738 if (r == ISC_R_SUCCESS && inuse) { 16739 continue; 16740 } 16741 } 16742 16743 op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD; 16744 16745 CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata, 16746 &tuple)); 16747 dns_diff_appendminimal(diff, &tuple); 16748 } 16749 if (result == ISC_R_NOMORE) { 16750 result = ISC_R_SUCCESS; 16751 } 16752 16753 cleanup: 16754 return result; 16755 } 16756 16757 /* 16758 * Filter the key material preserving TTL changes. If kasp in effect honour the 16759 * existing ttl. The lists returned by sync_secure_db/dns_db_diffx should be 16760 * DNSSEC RRset order so we can process 'del' and 'add' in parallel rather than 16761 * searching for TTL only changes first and processing them, then checking the 16762 * 'in use' status on a subsequent pass. 16763 */ 16764 16765 static void 16766 filter_keymaterial(dns_zone_t *zone, dns_difftuplelist_t *del, 16767 dns_difftuplelist_t *add, bool kasp, dns_ttl_t ttl) { 16768 dns_difftuple_t *deltuple = ISC_LIST_HEAD(*del); 16769 dns_difftuple_t *addtuple = ISC_LIST_HEAD(*add); 16770 isc_result_t result; 16771 16772 while (deltuple != NULL || addtuple != NULL) { 16773 dns_difftuple_t *delnext = NULL, *addnext = NULL; 16774 bool inuse = false; 16775 if (deltuple != NULL) { 16776 delnext = ISC_LIST_NEXT(deltuple, link); 16777 } 16778 if (addtuple != NULL) { 16779 addnext = ISC_LIST_NEXT(addtuple, link); 16780 } 16781 if (deltuple != NULL && addtuple != NULL) { 16782 int n = dns_rdata_compare(&deltuple->rdata, 16783 &addtuple->rdata); 16784 if (n == 0) { 16785 /* 16786 * If the rdata is equal then the only 16787 * difference will be a TTL change. 16788 */ 16789 if (kasp) { 16790 /* TTL is managed by dnssec-policy */ 16791 ISC_LIST_UNLINK(*del, deltuple, link); 16792 dns_difftuple_free(&deltuple); 16793 ISC_LIST_UNLINK(*add, addtuple, link); 16794 dns_difftuple_free(&addtuple); 16795 } 16796 deltuple = delnext; 16797 addtuple = addnext; 16798 continue; 16799 } 16800 if (n < 0) { 16801 goto checkdel; 16802 } 16803 goto checkadd; 16804 } else if (deltuple != NULL) { 16805 checkdel: 16806 result = dns_zone_dnskey_inuse(zone, &deltuple->rdata, 16807 &inuse); 16808 if (result == ISC_R_SUCCESS && inuse) { 16809 ISC_LIST_UNLINK(*del, deltuple, link); 16810 dns_difftuple_free(&deltuple); 16811 } 16812 deltuple = delnext; 16813 } else { 16814 checkadd: 16815 result = dns_zone_dnskey_inuse(zone, &addtuple->rdata, 16816 &inuse); 16817 if (result == ISC_R_SUCCESS && inuse) { 16818 ISC_LIST_UNLINK(*add, addtuple, link); 16819 dns_difftuple_free(&addtuple); 16820 } else if (kasp) { 16821 addtuple->ttl = ttl; 16822 } 16823 addtuple = addnext; 16824 } 16825 } 16826 } 16827 16828 static isc_result_t 16829 sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb, 16830 dns_dbversion_t *secver, dns_difftuple_t **soatuple, 16831 dns_diff_t *diff) { 16832 isc_result_t result; 16833 dns_db_t *rawdb = NULL; 16834 dns_dbversion_t *rawver = NULL; 16835 dns_difftuple_t *tuple = NULL, *next; 16836 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL; 16837 dns_rdata_soa_t oldsoa, newsoa; 16838 dns_difftuplelist_t add = ISC_LIST_INITIALIZER; 16839 dns_difftuplelist_t del = ISC_LIST_INITIALIZER; 16840 dns_difftuplelist_t keyadd = ISC_LIST_INITIALIZER; 16841 dns_difftuplelist_t keydel = ISC_LIST_INITIALIZER; 16842 dns_difftuplelist_t ckeyadd = ISC_LIST_INITIALIZER; 16843 dns_difftuplelist_t ckeydel = ISC_LIST_INITIALIZER; 16844 dns_difftuplelist_t cdsadd = ISC_LIST_INITIALIZER; 16845 dns_difftuplelist_t cdsdel = ISC_LIST_INITIALIZER; 16846 dns_kasp_t *kasp = NULL; 16847 dns_ttl_t keyttl = 0, ckeyttl = 0, cdsttl = 0; 16848 16849 REQUIRE(DNS_ZONE_VALID(seczone)); 16850 REQUIRE(soatuple != NULL && *soatuple == NULL); 16851 16852 if (!seczone->sourceserialset) { 16853 return DNS_R_UNCHANGED; 16854 } 16855 16856 dns_db_attach(raw->db, &rawdb); 16857 dns_db_currentversion(rawdb, &rawver); 16858 result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL); 16859 dns_db_closeversion(rawdb, &rawver, false); 16860 dns_db_detach(&rawdb); 16861 16862 if (result != ISC_R_SUCCESS) { 16863 return result; 16864 } 16865 16866 /* 16867 * If kasp is in effect honour the existing DNSKEY, CDNSKEY and CDS 16868 * TTLs. 16869 */ 16870 kasp = seczone->kasp; 16871 if (kasp != NULL) { 16872 dns_rdataset_t rdataset; 16873 dns_dbnode_t *node = NULL; 16874 dns_ttl_t ttl = dns_kasp_dnskeyttl(kasp); 16875 16876 dns_rdataset_init(&rdataset); 16877 16878 result = dns_db_getoriginnode(secdb, &node); 16879 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16880 16881 result = dns_db_findrdataset( 16882 secdb, node, secver, dns_rdatatype_dnskey, 16883 dns_rdatatype_none, 0, &rdataset, NULL); 16884 keyttl = (result == ISC_R_SUCCESS) ? rdataset.ttl : ttl; 16885 if (dns_rdataset_isassociated(&rdataset)) { 16886 dns_rdataset_disassociate(&rdataset); 16887 } 16888 16889 result = dns_db_findrdataset( 16890 secdb, node, secver, dns_rdatatype_cdnskey, 16891 dns_rdatatype_none, 0, &rdataset, NULL); 16892 ckeyttl = (result == ISC_R_SUCCESS) ? rdataset.ttl : ttl; 16893 if (dns_rdataset_isassociated(&rdataset)) { 16894 dns_rdataset_disassociate(&rdataset); 16895 } 16896 16897 result = dns_db_findrdataset( 16898 secdb, node, secver, dns_rdatatype_cds, 16899 dns_rdatatype_none, 0, &rdataset, NULL); 16900 cdsttl = (result == ISC_R_SUCCESS) ? rdataset.ttl : ttl; 16901 if (dns_rdataset_isassociated(&rdataset)) { 16902 dns_rdataset_disassociate(&rdataset); 16903 } 16904 dns_db_detachnode(secdb, &node); 16905 } 16906 16907 for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; tuple = next) { 16908 dns_difftuplelist_t *al = &add, *dl = &del; 16909 16910 next = ISC_LIST_NEXT(tuple, link); 16911 16912 /* 16913 * Skip private records that BIND maintains with inline-signing. 16914 */ 16915 if (seczone->privatetype != 0 && 16916 tuple->rdata.type == seczone->privatetype) 16917 { 16918 ISC_LIST_UNLINK(diff->tuples, tuple, link); 16919 dns_difftuple_free(&tuple); 16920 continue; 16921 } 16922 16923 /* 16924 * Skip DNSSEC records that BIND maintains with inline-signing. 16925 */ 16926 if (tuple->rdata.type == dns_rdatatype_nsec || 16927 tuple->rdata.type == dns_rdatatype_rrsig || 16928 tuple->rdata.type == dns_rdatatype_nsec3 || 16929 tuple->rdata.type == dns_rdatatype_nsec3param) 16930 { 16931 ISC_LIST_UNLINK(diff->tuples, tuple, link); 16932 dns_difftuple_free(&tuple); 16933 continue; 16934 } 16935 16936 /* 16937 * Apex DNSKEY, CDNSKEY and CDS need special processing so 16938 * split them out. 16939 */ 16940 if (dns_rdatatype_iskeymaterial(tuple->rdata.type) && 16941 dns_name_equal(&tuple->name, &seczone->origin)) 16942 { 16943 switch (tuple->rdata.type) { 16944 case dns_rdatatype_dnskey: 16945 al = &keyadd; 16946 dl = &keydel; 16947 break; 16948 case dns_rdatatype_cdnskey: 16949 al = &ckeyadd; 16950 dl = &ckeydel; 16951 break; 16952 case dns_rdatatype_cds: 16953 al = &cdsadd; 16954 dl = &cdsdel; 16955 break; 16956 default: 16957 UNREACHABLE(); 16958 } 16959 } 16960 16961 if (tuple->rdata.type == dns_rdatatype_soa) { 16962 if (tuple->op == DNS_DIFFOP_DEL) { 16963 INSIST(oldtuple == NULL); 16964 oldtuple = tuple; 16965 } 16966 if (tuple->op == DNS_DIFFOP_ADD) { 16967 INSIST(newtuple == NULL); 16968 newtuple = tuple; 16969 } 16970 } 16971 16972 /* 16973 * Split into deletions and additions. 16974 */ 16975 ISC_LIST_UNLINK(diff->tuples, tuple, link); 16976 switch (tuple->op) { 16977 case DNS_DIFFOP_DEL: 16978 case DNS_DIFFOP_DELRESIGN: 16979 ISC_LIST_APPEND(*dl, tuple, link); 16980 break; 16981 case DNS_DIFFOP_ADD: 16982 case DNS_DIFFOP_ADDRESIGN: 16983 ISC_LIST_APPEND(*al, tuple, link); 16984 break; 16985 default: 16986 UNREACHABLE(); 16987 } 16988 } 16989 16990 if (oldtuple != NULL && newtuple != NULL) { 16991 result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL); 16992 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16993 16994 result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL); 16995 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16996 16997 /* 16998 * If the SOA records are the same except for the serial 16999 * remove them from the diff. 17000 */ 17001 if (oldtuple->ttl == newtuple->ttl && 17002 oldsoa.refresh == newsoa.refresh && 17003 oldsoa.retry == newsoa.retry && 17004 oldsoa.minimum == newsoa.minimum && 17005 oldsoa.expire == newsoa.expire && 17006 dns_name_equal(&oldsoa.origin, &newsoa.origin) && 17007 dns_name_equal(&oldsoa.contact, &newsoa.contact)) 17008 { 17009 ISC_LIST_UNLINK(del, oldtuple, link); 17010 dns_difftuple_free(&oldtuple); 17011 ISC_LIST_UNLINK(add, newtuple, link); 17012 dns_difftuple_free(&newtuple); 17013 } 17014 } 17015 17016 /* 17017 * Filter out keys we manage but still allow TTL changes. 17018 */ 17019 filter_keymaterial(seczone, &keydel, &keyadd, kasp != NULL, keyttl); 17020 filter_keymaterial(seczone, &ckeydel, &ckeyadd, kasp != NULL, ckeyttl); 17021 filter_keymaterial(seczone, &cdsdel, &cdsadd, kasp != NULL, cdsttl); 17022 17023 /* 17024 * Rebuild the diff now that we have filtered it 17025 */ 17026 ISC_LIST_APPENDLIST(diff->tuples, del, link); 17027 ISC_LIST_APPENDLIST(diff->tuples, keydel, link); 17028 ISC_LIST_APPENDLIST(diff->tuples, ckeydel, link); 17029 ISC_LIST_APPENDLIST(diff->tuples, cdsdel, link); 17030 ISC_LIST_APPENDLIST(diff->tuples, add, link); 17031 ISC_LIST_APPENDLIST(diff->tuples, keyadd, link); 17032 ISC_LIST_APPENDLIST(diff->tuples, ckeyadd, link); 17033 ISC_LIST_APPENDLIST(diff->tuples, cdsadd, link); 17034 17035 if (ISC_LIST_EMPTY(diff->tuples)) { 17036 return DNS_R_UNCHANGED; 17037 } 17038 17039 /* 17040 * If there are still SOA records in the diff they can now be removed 17041 * saving the new SOA record. 17042 */ 17043 if (oldtuple != NULL) { 17044 ISC_LIST_UNLINK(diff->tuples, oldtuple, link); 17045 dns_difftuple_free(&oldtuple); 17046 } 17047 17048 if (newtuple != NULL) { 17049 ISC_LIST_UNLINK(diff->tuples, newtuple, link); 17050 *soatuple = newtuple; 17051 } 17052 17053 return ISC_R_SUCCESS; 17054 } 17055 17056 static void 17057 receive_secure_serial(void *arg) { 17058 struct rss *rss = (struct rss *)arg; 17059 dns_zone_t *zone = rss->zone; 17060 isc_result_t result = ISC_R_SUCCESS; 17061 dns_journal_t *rjournal = NULL; 17062 dns_journal_t *sjournal = NULL; 17063 uint32_t start, end = rss->serial; 17064 dns_difftuple_t *tuple = NULL, *soatuple = NULL; 17065 dns_update_log_t log = { update_log_cb, NULL }; 17066 uint32_t newserial = 0, desired = 0; 17067 isc_time_t timenow; 17068 int level = ISC_LOG_ERROR; 17069 17070 ENTER; 17071 17072 LOCK_ZONE(zone); 17073 17074 /* 17075 * The receive_secure_serial() is loop-serialized for the zone. Make 17076 * sure there's no processing currently running. 17077 */ 17078 17079 INSIST(zone->rss == NULL || zone->rss == rss); 17080 17081 if (zone->rss != NULL) { 17082 INSIST(zone->rss == rss); 17083 UNLOCK_ZONE(zone); 17084 } else { 17085 zone->rss = rss; 17086 dns_diff_init(zone->mctx, &zone->rss_diff); 17087 17088 /* 17089 * zone->db may be NULL, if the load from disk failed. 17090 */ 17091 result = ISC_R_SUCCESS; 17092 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 17093 if (zone->db != NULL) { 17094 dns_db_attach(zone->db, &zone->rss_db); 17095 } else { 17096 result = ISC_R_FAILURE; 17097 } 17098 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17099 17100 if (result == ISC_R_SUCCESS && zone->raw != NULL) { 17101 dns_zone_attach(zone->raw, &zone->rss_raw); 17102 } else { 17103 result = ISC_R_FAILURE; 17104 } 17105 17106 UNLOCK_ZONE(zone); 17107 17108 CHECK(result); 17109 17110 /* 17111 * We first attempt to sync the raw zone to the secure zone 17112 * by using the raw zone's journal, applying all the deltas 17113 * from the latest source-serial of the secure zone up to 17114 * the current serial number of the raw zone. 17115 * 17116 * If that fails, then we'll fall back to a direct comparison 17117 * between raw and secure zones. 17118 */ 17119 CHECK(dns_journal_open(zone->rss_raw->mctx, 17120 zone->rss_raw->journal, 17121 DNS_JOURNAL_WRITE, &rjournal)); 17122 17123 result = dns_journal_open(zone->mctx, zone->journal, 17124 DNS_JOURNAL_READ, &sjournal); 17125 if (result != ISC_R_NOTFOUND) { 17126 CHECK(result); 17127 } 17128 17129 if (!dns_journal_get_sourceserial(rjournal, &start)) { 17130 start = dns_journal_first_serial(rjournal); 17131 dns_journal_set_sourceserial(rjournal, start); 17132 } 17133 if (sjournal != NULL) { 17134 uint32_t serial; 17135 /* 17136 * We read the secure journal first, if that 17137 * exists use its value provided it is greater 17138 * that from the raw journal. 17139 */ 17140 if (dns_journal_get_sourceserial(sjournal, &serial)) { 17141 if (isc_serial_gt(serial, start)) { 17142 start = serial; 17143 } 17144 } 17145 dns_journal_destroy(&sjournal); 17146 } 17147 17148 dns_db_currentversion(zone->rss_db, &zone->rss_oldver); 17149 CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver)); 17150 17151 /* 17152 * Try to apply diffs from the raw zone's journal to the secure 17153 * zone. If that fails, we recover by syncing up the databases 17154 * directly. 17155 */ 17156 result = sync_secure_journal(zone, zone->rss_raw, rjournal, 17157 start, end, &soatuple, 17158 &zone->rss_diff); 17159 if (result == DNS_R_UNCHANGED) { 17160 goto cleanup; 17161 } else if (result != ISC_R_SUCCESS) { 17162 CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db, 17163 zone->rss_oldver, &soatuple, 17164 &zone->rss_diff)); 17165 } 17166 17167 CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db, 17168 zone->rss_newver)); 17169 17170 if (soatuple != NULL) { 17171 uint32_t oldserial; 17172 17173 CHECK(dns_db_createsoatuple( 17174 zone->rss_db, zone->rss_oldver, 17175 zone->rss_diff.mctx, DNS_DIFFOP_DEL, &tuple)); 17176 oldserial = dns_soa_getserial(&tuple->rdata); 17177 newserial = desired = 17178 dns_soa_getserial(&soatuple->rdata); 17179 if (!isc_serial_gt(newserial, oldserial)) { 17180 newserial = oldserial + 1; 17181 if (newserial == 0) { 17182 newserial++; 17183 } 17184 dns_soa_setserial(newserial, &soatuple->rdata); 17185 } 17186 CHECK(do_one_tuple(&tuple, zone->rss_db, 17187 zone->rss_newver, &zone->rss_diff)); 17188 CHECK(do_one_tuple(&soatuple, zone->rss_db, 17189 zone->rss_newver, &zone->rss_diff)); 17190 } else { 17191 CHECK(update_soa_serial(zone, zone->rss_db, 17192 zone->rss_newver, 17193 &zone->rss_diff, zone->mctx, 17194 zone->updatemethod)); 17195 } 17196 } 17197 result = dns_update_signaturesinc( 17198 &log, zone, zone->rss_db, zone->rss_oldver, zone->rss_newver, 17199 &zone->rss_diff, zone->sigvalidityinterval, &zone->rss_state); 17200 if (result == DNS_R_CONTINUE) { 17201 if (rjournal != NULL) { 17202 dns_journal_destroy(&rjournal); 17203 } 17204 isc_async_run(zone->loop, receive_secure_serial, rss); 17205 return; 17206 } 17207 17208 /* 17209 * If something went wrong while trying to update the secure zone and 17210 * the latter was already signed before, do not apply raw zone deltas 17211 * to it as that would break existing DNSSEC signatures. However, if 17212 * the secure zone was not yet signed (e.g. because no signing keys 17213 * were created for it), commence applying raw zone deltas to it so 17214 * that contents of the raw zone and the secure zone are kept in sync. 17215 */ 17216 if (result != ISC_R_SUCCESS && dns_db_issecure(zone->rss_db)) { 17217 goto cleanup; 17218 } 17219 17220 if (rjournal == NULL) { 17221 CHECK(dns_journal_open(zone->rss_raw->mctx, 17222 zone->rss_raw->journal, 17223 DNS_JOURNAL_WRITE, &rjournal)); 17224 } 17225 CHECK(zone_journal(zone, &zone->rss_diff, &end, 17226 "receive_secure_serial")); 17227 17228 dns_journal_set_sourceserial(rjournal, end); 17229 dns_journal_commit(rjournal); 17230 17231 LOCK_ZONE(zone); 17232 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 17233 17234 zone->sourceserial = end; 17235 zone->sourceserialset = true; 17236 zone_needdump(zone, DNS_DUMP_DELAY); 17237 17238 /* 17239 * Set resign time to make sure it is set to the earliest 17240 * signature expiration. 17241 */ 17242 set_resigntime(zone); 17243 timenow = isc_time_now(); 17244 zone_settimer(zone, &timenow); 17245 UNLOCK_ZONE(zone); 17246 17247 dns_db_closeversion(zone->rss_db, &zone->rss_oldver, false); 17248 dns_db_closeversion(zone->rss_db, &zone->rss_newver, true); 17249 17250 if (newserial != 0) { 17251 dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)", 17252 newserial, desired); 17253 } 17254 17255 cleanup: 17256 isc_mem_put(zone->mctx, rss, sizeof(*rss)); 17257 zone->rss = NULL; 17258 17259 if (zone->rss_raw != NULL) { 17260 dns_zone_detach(&zone->rss_raw); 17261 } 17262 if (result != ISC_R_SUCCESS) { 17263 LOCK_ZONE(zone); 17264 set_resigntime(zone); 17265 timenow = isc_time_now(); 17266 zone_settimer(zone, &timenow); 17267 UNLOCK_ZONE(zone); 17268 if (result == DNS_R_UNCHANGED) { 17269 level = ISC_LOG_INFO; 17270 } 17271 dns_zone_log(zone, level, "receive_secure_serial: %s", 17272 isc_result_totext(result)); 17273 } 17274 if (tuple != NULL) { 17275 dns_difftuple_free(&tuple); 17276 } 17277 if (soatuple != NULL) { 17278 dns_difftuple_free(&soatuple); 17279 } 17280 if (zone->rss_db != NULL) { 17281 if (zone->rss_oldver != NULL) { 17282 dns_db_closeversion(zone->rss_db, &zone->rss_oldver, 17283 false); 17284 } 17285 if (zone->rss_newver != NULL) { 17286 dns_db_closeversion(zone->rss_db, &zone->rss_newver, 17287 false); 17288 } 17289 dns_db_detach(&zone->rss_db); 17290 } 17291 INSIST(zone->rss_oldver == NULL); 17292 INSIST(zone->rss_newver == NULL); 17293 if (rjournal != NULL) { 17294 dns_journal_destroy(&rjournal); 17295 } 17296 dns_diff_clear(&zone->rss_diff); 17297 17298 dns_zone_idetach(&zone); 17299 } 17300 17301 static isc_result_t 17302 zone_send_secureserial(dns_zone_t *zone, uint32_t serial) { 17303 struct rss *rss = NULL; 17304 17305 rss = isc_mem_get(zone->secure->mctx, sizeof(*rss)); 17306 *rss = (struct rss){ 17307 .serial = serial, 17308 .link = ISC_LINK_INITIALIZER, 17309 }; 17310 17311 INSIST(LOCKED_ZONE(zone->secure)); 17312 zone_iattach(zone->secure, &rss->zone); 17313 isc_async_run(zone->secure->loop, receive_secure_serial, rss); 17314 17315 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); 17316 return ISC_R_SUCCESS; 17317 } 17318 17319 static isc_result_t 17320 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 17321 dns_name_t *name, dns_rdataset_t *rdataset, uint32_t oldserial) { 17322 dns_rdata_soa_t soa; 17323 dns_rdata_t rdata = DNS_RDATA_INIT; 17324 dns_rdatalist_t temprdatalist; 17325 dns_rdataset_t temprdataset; 17326 isc_buffer_t b; 17327 isc_result_t result; 17328 unsigned char buf[DNS_SOA_BUFFERSIZE]; 17329 17330 result = dns_rdataset_first(rdataset); 17331 RUNTIME_CHECK(result == ISC_R_SUCCESS); 17332 dns_rdataset_current(rdataset, &rdata); 17333 result = dns_rdata_tostruct(&rdata, &soa, NULL); 17334 RUNTIME_CHECK(result == ISC_R_SUCCESS); 17335 17336 if (isc_serial_gt(soa.serial, oldserial)) { 17337 return dns_db_addrdataset(db, node, version, 0, rdataset, 0, 17338 NULL); 17339 } 17340 /* 17341 * Always bump the serial. 17342 */ 17343 oldserial++; 17344 if (oldserial == 0) { 17345 oldserial++; 17346 } 17347 soa.serial = oldserial; 17348 17349 /* 17350 * Construct a replacement rdataset. 17351 */ 17352 dns_rdata_reset(&rdata); 17353 isc_buffer_init(&b, buf, sizeof(buf)); 17354 result = dns_rdata_fromstruct(&rdata, rdataset->rdclass, 17355 dns_rdatatype_soa, &soa, &b); 17356 RUNTIME_CHECK(result == ISC_R_SUCCESS); 17357 dns_rdatalist_init(&temprdatalist); 17358 temprdatalist.rdclass = rdata.rdclass; 17359 temprdatalist.type = rdata.type; 17360 temprdatalist.ttl = rdataset->ttl; 17361 ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link); 17362 17363 dns_rdataset_init(&temprdataset); 17364 dns_rdatalist_tordataset(&temprdatalist, &temprdataset); 17365 17366 dns_rdataset_getownercase(rdataset, name); 17367 dns_rdataset_setownercase(&temprdataset, name); 17368 return dns_db_addrdataset(db, node, version, 0, &temprdataset, 0, NULL); 17369 } 17370 17371 /* 17372 * This function should populate an nsec3paramlist_t with the 17373 * nsecparam_t data from a zone. 17374 */ 17375 static isc_result_t 17376 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) { 17377 isc_result_t result; 17378 dns_dbnode_t *node = NULL; 17379 dns_rdataset_t rdataset, prdataset; 17380 dns_dbversion_t *version = NULL; 17381 nsec3param_t *nsec3param = NULL; 17382 nsec3param_t *nsec3p = NULL; 17383 nsec3param_t *next; 17384 dns_db_t *db = NULL; 17385 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 17386 17387 REQUIRE(DNS_ZONE_VALID(zone)); 17388 REQUIRE(nsec3list != NULL); 17389 REQUIRE(ISC_LIST_EMPTY(*nsec3list)); 17390 17391 dns_rdataset_init(&rdataset); 17392 dns_rdataset_init(&prdataset); 17393 17394 dns_db_attach(zone->db, &db); 17395 CHECK(dns_db_getoriginnode(db, &node)); 17396 17397 dns_db_currentversion(db, &version); 17398 result = dns_db_findrdataset(db, node, version, 17399 dns_rdatatype_nsec3param, 17400 dns_rdatatype_none, 0, &rdataset, NULL); 17401 17402 if (result != ISC_R_SUCCESS) { 17403 goto getprivate; 17404 } 17405 17406 /* 17407 * Walk nsec3param rdataset making a list of parameters (note that 17408 * multiple simultaneous nsec3 chains are annoyingly legal -- this 17409 * is why we use an nsec3list, even though we will usually only 17410 * have one). 17411 */ 17412 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 17413 result = dns_rdataset_next(&rdataset)) 17414 { 17415 dns_rdata_t rdata = DNS_RDATA_INIT; 17416 dns_rdata_t private = DNS_RDATA_INIT; 17417 17418 dns_rdataset_current(&rdataset, &rdata); 17419 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17420 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 17421 "looping through nsec3param data"); 17422 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t)); 17423 ISC_LINK_INIT(nsec3param, link); 17424 17425 /* 17426 * now transfer the data from the rdata to 17427 * the nsec3param 17428 */ 17429 dns_nsec3param_toprivate(&rdata, &private, zone->privatetype, 17430 nsec3param->data, 17431 sizeof(nsec3param->data)); 17432 nsec3param->length = private.length; 17433 ISC_LIST_APPEND(*nsec3list, nsec3param, link); 17434 } 17435 17436 getprivate: 17437 result = dns_db_findrdataset(db, node, version, zone->privatetype, 17438 dns_rdatatype_none, 0, &prdataset, NULL); 17439 if (result != ISC_R_SUCCESS) { 17440 goto done; 17441 } 17442 17443 /* 17444 * walk private type records, converting them to nsec3 parameters 17445 * using dns_nsec3param_fromprivate(), do the right thing based on 17446 * CREATE and REMOVE flags 17447 */ 17448 for (result = dns_rdataset_first(&prdataset); result == ISC_R_SUCCESS; 17449 result = dns_rdataset_next(&prdataset)) 17450 { 17451 dns_rdata_t rdata = DNS_RDATA_INIT; 17452 dns_rdata_t private = DNS_RDATA_INIT; 17453 17454 dns_rdataset_current(&prdataset, &private); 17455 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17456 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 17457 "looping through nsec3param private data"); 17458 17459 /* 17460 * Do we have a valid private record? 17461 */ 17462 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 17463 sizeof(buf))) 17464 { 17465 continue; 17466 } 17467 17468 /* 17469 * Remove any NSEC3PARAM records scheduled to be removed. 17470 */ 17471 if (NSEC3REMOVE(rdata.data[1])) { 17472 /* 17473 * Zero out the flags. 17474 */ 17475 rdata.data[1] = 0; 17476 17477 for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; 17478 nsec3p = next) 17479 { 17480 next = ISC_LIST_NEXT(nsec3p, link); 17481 17482 if (nsec3p->length == 17483 (unsigned int)rdata.length + 1 && 17484 memcmp(rdata.data, nsec3p->data + 1, 17485 nsec3p->length - 1) == 0) 17486 { 17487 ISC_LIST_UNLINK(*nsec3list, nsec3p, 17488 link); 17489 isc_mem_put(zone->mctx, nsec3p, 17490 sizeof(nsec3param_t)); 17491 } 17492 } 17493 continue; 17494 } 17495 17496 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t)); 17497 ISC_LINK_INIT(nsec3param, link); 17498 17499 /* 17500 * Copy the remaining private records so the nsec/nsec3 17501 * chain gets created. 17502 */ 17503 INSIST(private.length <= sizeof(nsec3param->data)); 17504 memmove(nsec3param->data, private.data, private.length); 17505 nsec3param->length = private.length; 17506 ISC_LIST_APPEND(*nsec3list, nsec3param, link); 17507 } 17508 17509 done: 17510 if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) { 17511 result = ISC_R_SUCCESS; 17512 } 17513 17514 cleanup: 17515 if (node != NULL) { 17516 dns_db_detachnode(db, &node); 17517 } 17518 if (version != NULL) { 17519 dns_db_closeversion(db, &version, false); 17520 } 17521 if (db != NULL) { 17522 dns_db_detach(&db); 17523 } 17524 if (dns_rdataset_isassociated(&rdataset)) { 17525 dns_rdataset_disassociate(&rdataset); 17526 } 17527 if (dns_rdataset_isassociated(&prdataset)) { 17528 dns_rdataset_disassociate(&prdataset); 17529 } 17530 return result; 17531 } 17532 17533 /* 17534 * Populate new zone db with private type records found by save_nsec3param(). 17535 */ 17536 static isc_result_t 17537 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 17538 nsec3paramlist_t *nsec3list) { 17539 isc_result_t result = ISC_R_SUCCESS; 17540 dns_diff_t diff; 17541 dns_rdata_t rdata; 17542 nsec3param_t *nsec3p = NULL; 17543 nsec3param_t *next; 17544 17545 REQUIRE(DNS_ZONE_VALID(zone)); 17546 REQUIRE(!ISC_LIST_EMPTY(*nsec3list)); 17547 17548 dns_diff_init(zone->mctx, &diff); 17549 17550 /* 17551 * Loop through the list of private-type records, set the INITIAL 17552 * and CREATE flags, and the add the record to the apex of the tree 17553 * in db. 17554 */ 17555 for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; nsec3p = next) 17556 { 17557 next = ISC_LIST_NEXT(nsec3p, link); 17558 dns_rdata_init(&rdata); 17559 nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL; 17560 rdata.length = nsec3p->length; 17561 rdata.data = nsec3p->data; 17562 rdata.type = zone->privatetype; 17563 rdata.rdclass = zone->rdclass; 17564 result = update_one_rr(db, version, &diff, DNS_DIFFOP_ADD, 17565 &zone->origin, 0, &rdata); 17566 if (result != ISC_R_SUCCESS) { 17567 break; 17568 } 17569 } 17570 17571 dns_diff_clear(&diff); 17572 return result; 17573 } 17574 17575 static isc_result_t 17576 copy_non_dnssec_records(dns_db_t *db, dns_db_t *version, dns_db_t *rawdb, 17577 dns_dbiterator_t *dbiterator, unsigned int *oldserial) { 17578 dns_dbnode_t *rawnode = NULL, *node = NULL; 17579 dns_fixedname_t fixed; 17580 dns_name_t *name = dns_fixedname_initname(&fixed); 17581 dns_rdataset_t rdataset; 17582 dns_rdatasetiter_t *rdsit = NULL; 17583 isc_result_t result; 17584 17585 result = dns_dbiterator_current(dbiterator, &rawnode, name); 17586 if (result != ISC_R_SUCCESS) { 17587 return ISC_R_SUCCESS; 17588 } 17589 17590 dns_dbiterator_pause(dbiterator); 17591 17592 result = dns_db_findnode(db, name, true, &node); 17593 if (result != ISC_R_SUCCESS) { 17594 goto cleanup; 17595 } 17596 17597 result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, 0, &rdsit); 17598 if (result != ISC_R_SUCCESS) { 17599 goto cleanup; 17600 } 17601 17602 dns_rdataset_init(&rdataset); 17603 17604 for (result = dns_rdatasetiter_first(rdsit); result == ISC_R_SUCCESS; 17605 result = dns_rdatasetiter_next(rdsit)) 17606 { 17607 dns_rdatasetiter_current(rdsit, &rdataset); 17608 if (rdataset.type == dns_rdatatype_nsec || 17609 rdataset.type == dns_rdatatype_rrsig || 17610 rdataset.type == dns_rdatatype_nsec3 || 17611 rdataset.type == dns_rdatatype_nsec3param) 17612 { 17613 dns_rdataset_disassociate(&rdataset); 17614 continue; 17615 } 17616 /* 17617 * Allow DNSKEY, CDNSKEY, CDS because users should be able to 17618 * update the zone with these records from a different provider, 17619 * and thus they may exist in the raw version of the zone. 17620 */ 17621 17622 if (rdataset.type == dns_rdatatype_soa && oldserial != NULL) { 17623 result = checkandaddsoa(db, node, version, name, 17624 &rdataset, *oldserial); 17625 } else { 17626 result = dns_db_addrdataset(db, node, version, 0, 17627 &rdataset, 0, NULL); 17628 } 17629 dns_rdataset_disassociate(&rdataset); 17630 if (result != ISC_R_SUCCESS) { 17631 goto cleanup; 17632 } 17633 } 17634 if (result == ISC_R_NOMORE) { 17635 result = ISC_R_SUCCESS; 17636 } 17637 17638 cleanup: 17639 if (rdsit != NULL) { 17640 dns_rdatasetiter_destroy(&rdsit); 17641 } 17642 if (rawnode) { 17643 dns_db_detachnode(rawdb, &rawnode); 17644 } 17645 if (node) { 17646 dns_db_detachnode(db, &node); 17647 } 17648 return result; 17649 } 17650 17651 static void 17652 receive_secure_db(void *arg) { 17653 isc_result_t result; 17654 struct rss *rss = (struct rss *)arg; 17655 dns_zone_t *zone = rss->zone; 17656 dns_db_t *rawdb = rss->db, *db = NULL; 17657 dns_dbiterator_t *dbiterator = NULL; 17658 dns_dbversion_t *version = NULL; 17659 isc_time_t loadtime; 17660 unsigned int oldserial = 0, *oldserialp = NULL; 17661 nsec3paramlist_t nsec3list; 17662 17663 ISC_LIST_INIT(nsec3list); 17664 17665 LOCK_ZONE(zone); 17666 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) { 17667 CHECK(ISC_R_SHUTTINGDOWN); 17668 } 17669 17670 loadtime = isc_time_now(); 17671 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 17672 if (zone->db != NULL) { 17673 result = dns_db_getsoaserial(zone->db, NULL, &oldserial); 17674 if (result == ISC_R_SUCCESS) { 17675 oldserialp = &oldserial; 17676 } 17677 17678 /* 17679 * assemble nsec3parameters from the old zone, and set a flag 17680 * if any are found 17681 */ 17682 result = save_nsec3param(zone, &nsec3list); 17683 if (result != ISC_R_SUCCESS) { 17684 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17685 goto cleanup; 17686 } 17687 } 17688 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17689 17690 CHECK(dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, 17691 dns_dbtype_zone, zone->rdclass, zone->db_argc - 1, 17692 zone->db_argv + 1, &db)); 17693 17694 result = dns_db_setgluecachestats(db, zone->gluecachestats); 17695 if (result != ISC_R_NOTIMPLEMENTED) { 17696 CHECK(result); 17697 } 17698 17699 CHECK(dns_db_newversion(db, &version)); 17700 CHECK(dns_db_createiterator(rawdb, DNS_DB_NONSEC3, &dbiterator)); 17701 17702 for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS; 17703 result = dns_dbiterator_next(dbiterator)) 17704 { 17705 CHECK(copy_non_dnssec_records(db, version, rawdb, dbiterator, 17706 oldserialp)); 17707 } 17708 dns_dbiterator_destroy(&dbiterator); 17709 if (result != ISC_R_NOMORE) { 17710 goto cleanup; 17711 } 17712 17713 /* 17714 * Call restore_nsec3param() to create private-type records from 17715 * the old nsec3 parameters and insert them into db 17716 */ 17717 if (!ISC_LIST_EMPTY(nsec3list)) { 17718 CHECK(restore_nsec3param(zone, db, version, &nsec3list)); 17719 } 17720 17721 dns_db_closeversion(db, &version, true); 17722 17723 /* 17724 * Lock hierarchy: zmgr, zone, raw. 17725 */ 17726 INSIST(zone != zone->raw); 17727 LOCK_ZONE(zone->raw); 17728 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 17729 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 17730 zone_needdump(zone, 0); /* XXXMPA */ 17731 UNLOCK_ZONE(zone->raw); 17732 17733 /* 17734 * Process any queued NSEC3PARAM change requests. 17735 */ 17736 process_zone_setnsec3param(zone); 17737 17738 cleanup: 17739 UNLOCK_ZONE(zone); 17740 if (dbiterator != NULL) { 17741 dns_dbiterator_destroy(&dbiterator); 17742 } 17743 if (result != ISC_R_SUCCESS) { 17744 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s", 17745 isc_result_totext(result)); 17746 } 17747 17748 while (!ISC_LIST_EMPTY(nsec3list)) { 17749 nsec3param_t *nsec3p; 17750 nsec3p = ISC_LIST_HEAD(nsec3list); 17751 ISC_LIST_UNLINK(nsec3list, nsec3p, link); 17752 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t)); 17753 } 17754 if (db != NULL) { 17755 if (version != NULL) { 17756 dns_db_closeversion(db, &version, false); 17757 } 17758 dns_db_detach(&db); 17759 } 17760 17761 dns_db_detach(&rawdb); 17762 isc_mem_put(zone->mctx, rss, sizeof(*rss)); 17763 dns_zone_idetach(&zone); 17764 17765 INSIST(version == NULL); 17766 } 17767 17768 static isc_result_t 17769 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) { 17770 struct rss *rss = NULL; 17771 17772 rss = isc_mem_get(zone->secure->mctx, sizeof(*rss)); 17773 *rss = (struct rss){ .link = ISC_LINK_INITIALIZER }; 17774 17775 INSIST(LOCKED_ZONE(zone->secure)); 17776 zone_iattach(zone->secure, &rss->zone); 17777 dns_db_attach(db, &rss->db); 17778 isc_async_run(zone->secure->loop, receive_secure_db, rss); 17779 17780 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); 17781 return ISC_R_SUCCESS; 17782 } 17783 17784 isc_result_t 17785 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) { 17786 isc_result_t result; 17787 dns_zone_t *secure = NULL; 17788 17789 REQUIRE(DNS_ZONE_VALID(zone)); 17790 again: 17791 LOCK_ZONE(zone); 17792 if (inline_raw(zone)) { 17793 secure = zone->secure; 17794 INSIST(secure != zone); 17795 TRYLOCK_ZONE(result, secure); 17796 if (result != ISC_R_SUCCESS) { 17797 UNLOCK_ZONE(zone); 17798 secure = NULL; 17799 isc_thread_yield(); 17800 goto again; 17801 } 17802 } 17803 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 17804 result = zone_replacedb(zone, db, dump); 17805 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 17806 if (secure != NULL) { 17807 UNLOCK_ZONE(secure); 17808 } 17809 UNLOCK_ZONE(zone); 17810 return result; 17811 } 17812 17813 static isc_result_t 17814 zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) { 17815 dns_dbversion_t *ver; 17816 isc_result_t result; 17817 unsigned int soacount = 0; 17818 unsigned int nscount = 0; 17819 17820 /* 17821 * 'zone' and 'zone->db' locked by caller. 17822 */ 17823 REQUIRE(DNS_ZONE_VALID(zone)); 17824 REQUIRE(LOCKED_ZONE(zone)); 17825 if (inline_raw(zone)) { 17826 REQUIRE(LOCKED_ZONE(zone->secure)); 17827 } 17828 17829 result = zone_get_from_db(zone, db, &nscount, &soacount, NULL, NULL, 17830 NULL, NULL, NULL, NULL, NULL); 17831 if (result == ISC_R_SUCCESS) { 17832 if (soacount != 1) { 17833 dns_zone_log(zone, ISC_LOG_ERROR, "has %d SOA records", 17834 soacount); 17835 result = DNS_R_BADZONE; 17836 } 17837 if (nscount == 0 && zone->type != dns_zone_key) { 17838 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records"); 17839 result = DNS_R_BADZONE; 17840 } 17841 if (result != ISC_R_SUCCESS) { 17842 return result; 17843 } 17844 } else { 17845 dns_zone_log(zone, ISC_LOG_ERROR, 17846 "retrieving SOA and NS records failed: %s", 17847 isc_result_totext(result)); 17848 return result; 17849 } 17850 17851 result = check_nsec3param(zone, db); 17852 if (result != ISC_R_SUCCESS) { 17853 return result; 17854 } 17855 17856 ver = NULL; 17857 dns_db_currentversion(db, &ver); 17858 17859 /* 17860 * The initial version of a secondary zone is always dumped; 17861 * subsequent versions may be journaled instead if this 17862 * is enabled in the configuration. 17863 */ 17864 if (zone->db != NULL && zone->journal != NULL && 17865 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 17866 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) 17867 { 17868 uint32_t serial, oldserial; 17869 17870 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs"); 17871 17872 result = dns_db_getsoaserial(db, ver, &serial); 17873 if (result != ISC_R_SUCCESS) { 17874 dns_zone_log(zone, ISC_LOG_ERROR, 17875 "ixfr-from-differences: unable to get " 17876 "new serial"); 17877 goto fail; 17878 } 17879 17880 /* 17881 * This is checked in zone_postload() for primary zones. 17882 */ 17883 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, 17884 &oldserial, NULL, NULL, NULL, NULL, 17885 NULL); 17886 RUNTIME_CHECK(result == ISC_R_SUCCESS); 17887 RUNTIME_CHECK(soacount > 0U); 17888 if ((zone->type == dns_zone_secondary || 17889 (zone->type == dns_zone_redirect && 17890 dns_remote_addresses(&zone->primaries) != NULL)) && 17891 !isc_serial_gt(serial, oldserial)) 17892 { 17893 uint32_t serialmin, serialmax; 17894 serialmin = (oldserial + 1) & 0xffffffffU; 17895 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; 17896 dns_zone_log(zone, ISC_LOG_ERROR, 17897 "ixfr-from-differences: failed: " 17898 "new serial (%u) out of range [%u - %u]", 17899 serial, serialmin, serialmax); 17900 result = ISC_R_RANGE; 17901 goto fail; 17902 } 17903 17904 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL, 17905 zone->journal); 17906 if (result != ISC_R_SUCCESS) { 17907 char strbuf[ISC_STRERRORSIZE]; 17908 strerror_r(errno, strbuf, sizeof(strbuf)); 17909 dns_zone_log(zone, ISC_LOG_ERROR, 17910 "ixfr-from-differences: failed: " 17911 "%s", 17912 strbuf); 17913 goto fallback; 17914 } 17915 if (dump) { 17916 zone_needdump(zone, DNS_DUMP_DELAY); 17917 } else { 17918 zone_journal_compact(zone, zone->db, serial); 17919 } 17920 if (zone->type == dns_zone_primary && inline_raw(zone)) { 17921 zone_send_secureserial(zone, serial); 17922 } 17923 } else { 17924 fallback: 17925 if (dump && zone->masterfile != NULL) { 17926 /* 17927 * If DNS_ZONEFLG_FORCEXFER was set we don't want 17928 * to keep the old masterfile. 17929 */ 17930 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) && 17931 remove(zone->masterfile) < 0 && errno != ENOENT) 17932 { 17933 char strbuf[ISC_STRERRORSIZE]; 17934 strerror_r(errno, strbuf, sizeof(strbuf)); 17935 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17936 DNS_LOGMODULE_ZONE, 17937 ISC_LOG_WARNING, 17938 "unable to remove masterfile " 17939 "'%s': '%s'", 17940 zone->masterfile, strbuf); 17941 } 17942 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) { 17943 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY); 17944 } else { 17945 zone_needdump(zone, 0); 17946 } 17947 } 17948 if (dump && zone->journal != NULL) { 17949 /* 17950 * The in-memory database just changed, and 17951 * because 'dump' is set, it didn't change by 17952 * being loaded from disk. Also, we have not 17953 * journaled diffs for this change. 17954 * Therefore, the on-disk journal is missing 17955 * the deltas for this change. Since it can 17956 * no longer be used to bring the zone 17957 * up-to-date, it is useless and should be 17958 * removed. 17959 */ 17960 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17961 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 17962 "removing journal file"); 17963 if (remove(zone->journal) < 0 && errno != ENOENT) { 17964 char strbuf[ISC_STRERRORSIZE]; 17965 strerror_r(errno, strbuf, sizeof(strbuf)); 17966 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17967 DNS_LOGMODULE_ZONE, 17968 ISC_LOG_WARNING, 17969 "unable to remove journal " 17970 "'%s': '%s'", 17971 zone->journal, strbuf); 17972 } 17973 } 17974 17975 if (inline_raw(zone)) { 17976 zone_send_securedb(zone, db); 17977 } 17978 } 17979 17980 dns_db_closeversion(db, &ver, false); 17981 17982 dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database"); 17983 17984 if (zone->db != NULL) { 17985 zone_detachdb(zone); 17986 } 17987 zone_attachdb(zone, db); 17988 dns_db_setloop(zone->db, zone->loop); 17989 dns_db_setmaxrrperset(zone->db, zone->maxrrperset); 17990 dns_db_setmaxtypepername(zone->db, zone->maxtypepername); 17991 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY); 17992 return ISC_R_SUCCESS; 17993 17994 fail: 17995 dns_db_closeversion(db, &ver, false); 17996 return result; 17997 } 17998 17999 /* The caller must hold the dblock as a writer. */ 18000 static void 18001 zone_attachdb(dns_zone_t *zone, dns_db_t *db) { 18002 REQUIRE(zone->db == NULL && db != NULL); 18003 18004 dns_db_attach(db, &zone->db); 18005 } 18006 18007 /* The caller must hold the dblock as a writer. */ 18008 static void 18009 zone_detachdb(dns_zone_t *zone) { 18010 REQUIRE(zone->db != NULL); 18011 18012 dns_zone_rpz_disable_db(zone, zone->db); 18013 dns_zone_catz_disable_db(zone, zone->db); 18014 dns_db_detach(&zone->db); 18015 } 18016 18017 static void 18018 zone_xfrdone(dns_zone_t *zone, uint32_t *expireopt, isc_result_t result) { 18019 isc_time_t now, expiretime; 18020 bool again = false; 18021 unsigned int soacount; 18022 unsigned int nscount; 18023 uint32_t serial, refresh, retry, expire, minimum, soattl, oldexpire; 18024 isc_result_t xfrresult = result; 18025 bool free_needed; 18026 dns_zone_t *secure = NULL; 18027 18028 REQUIRE(DNS_ZONE_VALID(zone)); 18029 18030 dns_zone_logc( 18031 zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 18032 expireopt == NULL ? "zone transfer finished: %s" 18033 : "zone transfer finished: %s, expire=%u", 18034 isc_result_totext(result), expireopt != NULL ? *expireopt : 0); 18035 18036 /* 18037 * Obtaining a lock on the zone->secure (see zone_send_secureserial) 18038 * could result in a deadlock due to a LOR so we will spin if we 18039 * can't obtain both locks. 18040 */ 18041 again: 18042 LOCK_ZONE(zone); 18043 if (inline_raw(zone)) { 18044 secure = zone->secure; 18045 INSIST(secure != zone); 18046 TRYLOCK_ZONE(result, secure); 18047 if (result != ISC_R_SUCCESS) { 18048 UNLOCK_ZONE(zone); 18049 secure = NULL; 18050 isc_thread_yield(); 18051 goto again; 18052 } 18053 } 18054 18055 INSIST(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)); 18056 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 18057 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 18058 18059 now = isc_time_now(); 18060 switch (xfrresult) { 18061 case ISC_R_SUCCESS: 18062 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 18063 FALLTHROUGH; 18064 case DNS_R_UPTODATE: 18065 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER | 18066 DNS_ZONEFLG_FIRSTREFRESH); 18067 /* 18068 * Has the zone expired underneath us? 18069 */ 18070 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 18071 if (zone->db == NULL) { 18072 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 18073 goto same_primary; 18074 } 18075 18076 oldexpire = zone->expire; 18077 18078 /* 18079 * Update the zone structure's data from the actual 18080 * SOA received. 18081 */ 18082 nscount = 0; 18083 soacount = 0; 18084 INSIST(zone->db != NULL); 18085 result = zone_get_from_db(zone, zone->db, &nscount, &soacount, 18086 &soattl, &serial, &refresh, &retry, 18087 &expire, &minimum, NULL); 18088 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 18089 if (result == ISC_R_SUCCESS) { 18090 if (soacount != 1) { 18091 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18092 ISC_LOG_ERROR, 18093 "transferred zone " 18094 "has %d SOA records", 18095 soacount); 18096 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) 18097 { 18098 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 18099 zone->retry = DNS_ZONE_DEFAULTRETRY; 18100 } 18101 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 18102 zone_unload(zone); 18103 goto next_primary; 18104 } 18105 if (nscount == 0) { 18106 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18107 ISC_LOG_ERROR, 18108 "transferred zone " 18109 "has no NS records"); 18110 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) 18111 { 18112 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 18113 zone->retry = DNS_ZONE_DEFAULTRETRY; 18114 } 18115 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 18116 zone_unload(zone); 18117 goto next_primary; 18118 } 18119 zone->refresh = RANGE(refresh, zone->minrefresh, 18120 zone->maxrefresh); 18121 zone->retry = RANGE(retry, zone->minretry, 18122 zone->maxretry); 18123 zone->expire = RANGE(expire, 18124 zone->refresh + zone->retry, 18125 DNS_MAX_EXPIRE); 18126 zone->soattl = soattl; 18127 zone->minimum = minimum; 18128 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 18129 } 18130 18131 /* 18132 * Set our next refresh time. 18133 */ 18134 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 18135 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 18136 zone->refreshtime = now; 18137 } else { 18138 DNS_ZONE_JITTER_ADD(&now, zone->refresh, 18139 &zone->refreshtime); 18140 } 18141 18142 /* 18143 * Set our next expire time. If the parent returned 18144 * an EXPIRE option use that to update zone->expiretime. 18145 */ 18146 expire = zone->expire; 18147 if (expireopt != NULL && *expireopt < expire) { 18148 expire = *expireopt; 18149 } 18150 DNS_ZONE_TIME_ADD(&now, expire, &expiretime); 18151 if (oldexpire != zone->expire || 18152 isc_time_compare(&expiretime, &zone->expiretime) > 0) 18153 { 18154 zone->expiretime = expiretime; 18155 } 18156 18157 /* 18158 * Set loadtime. 18159 */ 18160 zone->loadtime = now; 18161 18162 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) { 18163 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")]; 18164 if (zone->tsigkey != NULL) { 18165 char namebuf[DNS_NAME_FORMATSIZE]; 18166 dns_name_format(zone->tsigkey->name, namebuf, 18167 sizeof(namebuf)); 18168 snprintf(buf, sizeof(buf), ": TSIG '%s'", 18169 namebuf); 18170 } else { 18171 buf[0] = '\0'; 18172 } 18173 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18174 ISC_LOG_INFO, "transferred serial %u%s", 18175 serial, buf); 18176 if (inline_raw(zone)) { 18177 zone_send_secureserial(zone, serial); 18178 } 18179 } 18180 18181 /* 18182 * This is not necessary if we just performed a AXFR 18183 * however it is necessary for an IXFR / UPTODATE and 18184 * won't hurt with an AXFR. 18185 */ 18186 if (zone->masterfile != NULL || zone->journal != NULL) { 18187 unsigned int delay = DNS_DUMP_DELAY; 18188 isc_interval_t i; 18189 isc_time_t when; 18190 18191 /* 18192 * Compute effective modification time. 18193 */ 18194 isc_interval_set(&i, zone->expire, 0); 18195 result = isc_time_subtract(&zone->expiretime, &i, 18196 &when); 18197 if (result != ISC_R_SUCCESS) { 18198 when = now; 18199 } 18200 18201 result = ISC_R_FAILURE; 18202 if (zone->journal != NULL) { 18203 result = isc_file_settime(zone->journal, &when); 18204 } 18205 if (result != ISC_R_SUCCESS && zone->masterfile != NULL) 18206 { 18207 result = isc_file_settime(zone->masterfile, 18208 &when); 18209 } 18210 18211 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) || 18212 result == ISC_R_FILENOTFOUND) 18213 { 18214 delay = 0; 18215 } 18216 18217 if ((result == ISC_R_SUCCESS || 18218 result == ISC_R_FILENOTFOUND) && 18219 zone->masterfile != NULL) 18220 { 18221 zone_needdump(zone, delay); 18222 } else if (result != ISC_R_SUCCESS) { 18223 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18224 ISC_LOG_ERROR, 18225 "transfer: could not set file " 18226 "modification time of '%s': %s", 18227 zone->masterfile, 18228 isc_result_totext(result)); 18229 } 18230 } 18231 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY); 18232 inc_stats(zone, dns_zonestatscounter_xfrsuccess); 18233 break; 18234 18235 case DNS_R_BADIXFR: 18236 /* Force retry with AXFR. */ 18237 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOIXFR); 18238 goto same_primary; 18239 18240 case DNS_R_TOOMANYRECORDS: 18241 case DNS_R_VERIFYFAILURE: 18242 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 18243 inc_stats(zone, dns_zonestatscounter_xfrfail); 18244 break; 18245 18246 case ISC_R_SHUTTINGDOWN: 18247 dns_remote_reset(&zone->primaries, true); 18248 break; 18249 18250 default: 18251 next_primary: 18252 /* 18253 * Skip to next failed / untried primary. 18254 */ 18255 dns_remote_next(&zone->primaries, true); 18256 same_primary: 18257 if (dns_remote_done(&zone->primaries)) { 18258 dns_remote_reset(&zone->primaries, false); 18259 } else { 18260 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 18261 again = true; 18262 } 18263 inc_stats(zone, dns_zonestatscounter_xfrfail); 18264 break; 18265 } 18266 zone_settimer(zone, &now); 18267 18268 /* 18269 * We are called as the done callback of a zone 18270 * transfer object that just entered its shutting-down state or 18271 * failed to start. Since we are no longer responsible for shutting 18272 * it down, we can detach our reference. 18273 */ 18274 if (zone->xfr != NULL) { 18275 dns_xfrin_detach(&zone->xfr); 18276 } 18277 18278 if (zone->tsigkey != NULL) { 18279 dns_tsigkey_detach(&zone->tsigkey); 18280 } 18281 18282 if (zone->transport != NULL) { 18283 dns_transport_detach(&zone->transport); 18284 } 18285 18286 /* 18287 * Handle any deferred journal compaction. 18288 */ 18289 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) { 18290 dns_db_t *db = NULL; 18291 if (dns_zone_getdb(zone, &db) == ISC_R_SUCCESS) { 18292 zone_journal_compact(zone, db, zone->compact_serial); 18293 dns_db_detach(&db); 18294 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 18295 } 18296 } 18297 18298 if (secure != NULL) { 18299 UNLOCK_ZONE(secure); 18300 } 18301 /* 18302 * This transfer finishing freed up a transfer quota slot. 18303 * Let any other zones waiting for quota have it. 18304 */ 18305 if (zone->zmgr != NULL && 18306 zone->statelist == &zone->zmgr->xfrin_in_progress) 18307 { 18308 UNLOCK_ZONE(zone); 18309 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 18310 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink); 18311 zone->statelist = NULL; 18312 zmgr_resume_xfrs(zone->zmgr, false); 18313 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 18314 LOCK_ZONE(zone); 18315 } 18316 18317 /* 18318 * Retry with a different server if necessary. 18319 */ 18320 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 18321 queue_soa_query(zone); 18322 } 18323 18324 isc_refcount_decrement(&zone->irefs); 18325 free_needed = exit_check(zone); 18326 UNLOCK_ZONE(zone); 18327 if (free_needed) { 18328 zone_free(zone); 18329 } 18330 } 18331 18332 static void 18333 zone_loaddone(void *arg, isc_result_t result) { 18334 dns_load_t *load = arg; 18335 dns_zone_t *zone; 18336 isc_result_t tresult; 18337 dns_zone_t *secure = NULL; 18338 18339 zone = load->zone; 18340 18341 ENTER; 18342 18343 /* 18344 * If zone loading failed, remove the update db callbacks prior 18345 * to calling the list of callbacks in the zone load structure. 18346 */ 18347 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { 18348 dns_zone_rpz_disable_db(zone, load->db); 18349 dns_zone_catz_disable_db(zone, load->db); 18350 } 18351 18352 tresult = dns_db_endload(load->db, &load->callbacks); 18353 if (tresult != ISC_R_SUCCESS && 18354 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)) 18355 { 18356 result = tresult; 18357 } 18358 18359 /* 18360 * Lock hierarchy: zmgr, zone, raw. 18361 */ 18362 again: 18363 LOCK_ZONE(zone); 18364 INSIST(zone != zone->raw); 18365 if (inline_secure(zone)) { 18366 LOCK_ZONE(zone->raw); 18367 } else if (inline_raw(zone)) { 18368 secure = zone->secure; 18369 TRYLOCK_ZONE(tresult, secure); 18370 if (tresult != ISC_R_SUCCESS) { 18371 UNLOCK_ZONE(zone); 18372 secure = NULL; 18373 isc_thread_yield(); 18374 goto again; 18375 } 18376 } 18377 (void)zone_postload(zone, load->db, load->loadtime, result); 18378 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING); 18379 zone_idetach(&load->callbacks.zone); 18380 /* 18381 * Leave the zone frozen if the reload fails. 18382 */ 18383 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) && 18384 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW)) 18385 { 18386 zone->update_disabled = false; 18387 } 18388 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW); 18389 if (inline_secure(zone)) { 18390 UNLOCK_ZONE(zone->raw); 18391 } else if (secure != NULL) { 18392 UNLOCK_ZONE(secure); 18393 } 18394 UNLOCK_ZONE(zone); 18395 18396 dns_db_detach(&load->db); 18397 if (zone->loadctx != NULL) { 18398 dns_loadctx_detach(&zone->loadctx); 18399 } 18400 isc_mem_put(zone->mctx, load, sizeof(*load)); 18401 18402 dns_zone_idetach(&zone); 18403 } 18404 18405 void 18406 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) { 18407 REQUIRE(DNS_ZONE_VALID(zone)); 18408 REQUIRE(table != NULL); 18409 REQUIRE(*table == NULL); 18410 18411 LOCK_ZONE(zone); 18412 if (zone->ssutable != NULL) { 18413 dns_ssutable_attach(zone->ssutable, table); 18414 } 18415 UNLOCK_ZONE(zone); 18416 } 18417 18418 void 18419 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) { 18420 REQUIRE(DNS_ZONE_VALID(zone)); 18421 18422 LOCK_ZONE(zone); 18423 if (zone->ssutable != NULL) { 18424 dns_ssutable_detach(&zone->ssutable); 18425 } 18426 if (table != NULL) { 18427 dns_ssutable_attach(table, &zone->ssutable); 18428 } 18429 UNLOCK_ZONE(zone); 18430 } 18431 18432 void 18433 dns_zone_setsigvalidityinterval(dns_zone_t *zone, uint32_t interval) { 18434 REQUIRE(DNS_ZONE_VALID(zone)); 18435 18436 zone->sigvalidityinterval = interval; 18437 } 18438 18439 uint32_t 18440 dns_zone_getsigvalidityinterval(dns_zone_t *zone) { 18441 REQUIRE(DNS_ZONE_VALID(zone)); 18442 18443 return zone->sigvalidityinterval; 18444 } 18445 18446 void 18447 dns_zone_setkeyvalidityinterval(dns_zone_t *zone, uint32_t interval) { 18448 REQUIRE(DNS_ZONE_VALID(zone)); 18449 18450 zone->keyvalidityinterval = interval; 18451 } 18452 18453 uint32_t 18454 dns_zone_getkeyvalidityinterval(dns_zone_t *zone) { 18455 REQUIRE(DNS_ZONE_VALID(zone)); 18456 18457 return zone->keyvalidityinterval; 18458 } 18459 18460 void 18461 dns_zone_setsigresigninginterval(dns_zone_t *zone, uint32_t interval) { 18462 isc_time_t now; 18463 18464 REQUIRE(DNS_ZONE_VALID(zone)); 18465 18466 LOCK_ZONE(zone); 18467 zone->sigresigninginterval = interval; 18468 set_resigntime(zone); 18469 if (zone->loop != NULL) { 18470 now = isc_time_now(); 18471 zone_settimer(zone, &now); 18472 } 18473 UNLOCK_ZONE(zone); 18474 } 18475 18476 uint32_t 18477 dns_zone_getsigresigninginterval(dns_zone_t *zone) { 18478 REQUIRE(DNS_ZONE_VALID(zone)); 18479 18480 return zone->sigresigninginterval; 18481 } 18482 18483 void 18484 dns_zone_getsourceaddr(dns_zone_t *zone, isc_sockaddr_t *sourceaddr) { 18485 REQUIRE(DNS_ZONE_VALID(zone)); 18486 REQUIRE(sourceaddr != NULL); 18487 18488 LOCK_ZONE(zone); 18489 INSIST(dns_remote_count(&zone->primaries) > 0); 18490 *sourceaddr = zone->sourceaddr; 18491 UNLOCK_ZONE(zone); 18492 } 18493 18494 isc_result_t 18495 dns_zone_getprimaryaddr(dns_zone_t *zone, isc_sockaddr_t *primaryaddr) { 18496 isc_result_t result = ISC_R_NOMORE; 18497 18498 REQUIRE(DNS_ZONE_VALID(zone)); 18499 REQUIRE(primaryaddr != NULL); 18500 18501 LOCK_ZONE(zone); 18502 INSIST(dns_remote_count(&zone->primaries) > 0); 18503 if (!dns_remote_done(&zone->primaries)) { 18504 *primaryaddr = dns_remote_curraddr(&zone->primaries); 18505 result = ISC_R_SUCCESS; 18506 } 18507 UNLOCK_ZONE(zone); 18508 18509 return result; 18510 } 18511 18512 isc_time_t 18513 dns_zone_getxfrintime(dns_zone_t *zone) { 18514 isc_time_t xfrintime; 18515 18516 REQUIRE(DNS_ZONE_VALID(zone)); 18517 18518 LOCK_ZONE(zone); 18519 xfrintime = zone->xfrintime; 18520 UNLOCK_ZONE(zone); 18521 18522 return xfrintime; 18523 } 18524 18525 static void 18526 queue_xfrin(dns_zone_t *zone) { 18527 isc_result_t result; 18528 dns_zonemgr_t *zmgr = zone->zmgr; 18529 18530 ENTER; 18531 18532 INSIST(zone->statelist == NULL); 18533 18534 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18535 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink); 18536 isc_refcount_increment0(&zone->irefs); 18537 zone->statelist = &zmgr->waiting_for_xfrin; 18538 result = zmgr_start_xfrin_ifquota(zmgr, zone); 18539 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18540 18541 if (result == ISC_R_QUOTA) { 18542 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 18543 "zone transfer deferred due to quota"); 18544 } else if (result != ISC_R_SUCCESS) { 18545 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, 18546 "starting zone transfer: %s", 18547 isc_result_totext(result)); 18548 } 18549 } 18550 18551 /* 18552 * Get the transport type used for the SOA query to the current primary server 18553 * before an ongoing incoming zone transfer. 18554 * 18555 * Requires: 18556 * The zone is locked by the caller. 18557 */ 18558 static dns_transport_type_t 18559 get_request_transport_type(dns_zone_t *zone) { 18560 dns_transport_type_t transport_type = DNS_TRANSPORT_NONE; 18561 18562 if (zone->transport != NULL) { 18563 transport_type = dns_transport_get_type(zone->transport); 18564 } else { 18565 transport_type = (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC)) 18566 ? DNS_TRANSPORT_TCP 18567 : DNS_TRANSPORT_UDP; 18568 18569 /* Check if the peer is forced to always use TCP. */ 18570 if (transport_type != DNS_TRANSPORT_TCP && 18571 !dns_remote_done(&zone->primaries)) 18572 { 18573 isc_result_t result; 18574 isc_sockaddr_t primaryaddr; 18575 isc_netaddr_t primaryip; 18576 dns_peer_t *peer = NULL; 18577 18578 primaryaddr = dns_remote_curraddr(&zone->primaries); 18579 isc_netaddr_fromsockaddr(&primaryip, &primaryaddr); 18580 result = dns_peerlist_peerbyaddr(zone->view->peers, 18581 &primaryip, &peer); 18582 if (result == ISC_R_SUCCESS && peer != NULL) { 18583 bool usetcp; 18584 result = dns_peer_getforcetcp(peer, &usetcp); 18585 if (result == ISC_R_SUCCESS && usetcp) { 18586 transport_type = DNS_TRANSPORT_TCP; 18587 } 18588 } 18589 } 18590 } 18591 18592 return transport_type; 18593 } 18594 18595 dns_transport_type_t 18596 dns_zone_getrequesttransporttype(dns_zone_t *zone) { 18597 dns_transport_type_t transport_type; 18598 18599 REQUIRE(DNS_ZONE_VALID(zone)); 18600 18601 LOCK_ZONE(zone); 18602 transport_type = get_request_transport_type(zone); 18603 UNLOCK_ZONE(zone); 18604 18605 return transport_type; 18606 } 18607 18608 /* 18609 * This event callback is called when a zone has received 18610 * any necessary zone transfer quota. This is the time 18611 * to go ahead and start the transfer. 18612 */ 18613 static void 18614 got_transfer_quota(void *arg) { 18615 dns_zone_t *zone = (dns_zone_t *)arg; 18616 isc_result_t result = ISC_R_SUCCESS; 18617 dns_peer_t *peer = NULL; 18618 char primary[ISC_SOCKADDR_FORMATSIZE]; 18619 char source[ISC_SOCKADDR_FORMATSIZE]; 18620 dns_rdatatype_t xfrtype; 18621 isc_netaddr_t primaryip; 18622 isc_sockaddr_t primaryaddr; 18623 isc_sockaddr_t sourceaddr; 18624 isc_time_t now; 18625 dns_transport_type_t soa_transport_type = DNS_TRANSPORT_NONE; 18626 const char *soa_before = ""; 18627 bool loaded; 18628 isc_tlsctx_cache_t *zmgr_tlsctx_cache = NULL; 18629 dns_xfrin_t *xfr = NULL; 18630 18631 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 18632 zone_xfrdone(zone, NULL, ISC_R_CANCELED); 18633 return; 18634 } 18635 18636 now = isc_time_now(); 18637 18638 primaryaddr = dns_remote_curraddr(&zone->primaries); 18639 isc_sockaddr_format(&primaryaddr, primary, sizeof(primary)); 18640 if (dns_zonemgr_unreachable(zone->zmgr, &primaryaddr, &zone->sourceaddr, 18641 &now)) 18642 { 18643 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 18644 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 18645 "got_transfer_quota: skipping zone transfer as " 18646 "primary %s (source %s) is unreachable (cached)", 18647 primary, source); 18648 zone_xfrdone(zone, NULL, ISC_R_CANCELED); 18649 return; 18650 } 18651 18652 isc_netaddr_fromsockaddr(&primaryip, &primaryaddr); 18653 (void)dns_peerlist_peerbyaddr(zone->view->peers, &primaryip, &peer); 18654 18655 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) { 18656 soa_before = "SOA before "; 18657 } 18658 /* 18659 * Decide whether we should request IXFR or AXFR. 18660 */ 18661 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 18662 loaded = (zone->db != NULL); 18663 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 18664 18665 if (!loaded) { 18666 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 18667 "no database exists yet, requesting AXFR of " 18668 "initial version from %s", 18669 primary); 18670 xfrtype = dns_rdatatype_axfr; 18671 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { 18672 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 18673 "forced reload, requesting AXFR of " 18674 "initial version from %s", 18675 primary); 18676 xfrtype = dns_rdatatype_axfr; 18677 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOIXFR)) { 18678 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 18679 "retrying with AXFR from %s due to " 18680 "previous IXFR failure", 18681 primary); 18682 xfrtype = dns_rdatatype_axfr; 18683 LOCK_ZONE(zone); 18684 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOIXFR); 18685 UNLOCK_ZONE(zone); 18686 } else { 18687 bool use_ixfr = true; 18688 if (peer != NULL) { 18689 result = dns_peer_getrequestixfr(peer, &use_ixfr); 18690 } 18691 if (peer == NULL || result != ISC_R_SUCCESS) { 18692 use_ixfr = zone->requestixfr; 18693 } 18694 if (!use_ixfr) { 18695 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18696 ISC_LOG_DEBUG(1), 18697 "IXFR disabled, " 18698 "requesting %sAXFR from %s", 18699 soa_before, primary); 18700 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) { 18701 xfrtype = dns_rdatatype_soa; 18702 } else { 18703 xfrtype = dns_rdatatype_axfr; 18704 } 18705 } else { 18706 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18707 ISC_LOG_DEBUG(1), 18708 "requesting IXFR from %s", primary); 18709 xfrtype = dns_rdatatype_ixfr; 18710 } 18711 } 18712 18713 /* 18714 * Determine if we should attempt to sign the request with TSIG. 18715 */ 18716 result = ISC_R_NOTFOUND; 18717 18718 /* 18719 * First, look for a tsig key in the primaries statement, then 18720 * try for a server key. 18721 */ 18722 if (dns_remote_keyname(&zone->primaries) != NULL) { 18723 dns_view_t *view = dns_zone_getview(zone); 18724 dns_name_t *keyname = dns_remote_keyname(&zone->primaries); 18725 result = dns_view_gettsig(view, keyname, &zone->tsigkey); 18726 } 18727 if (result != ISC_R_SUCCESS) { 18728 INSIST(zone->tsigkey == NULL); 18729 result = dns_view_getpeertsig(zone->view, &primaryip, 18730 &zone->tsigkey); 18731 } 18732 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 18733 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, 18734 "could not get TSIG key for zone transfer: %s", 18735 isc_result_totext(result)); 18736 } 18737 18738 /* 18739 * Get the TLS transport for the primary, if configured. 18740 */ 18741 if (dns_remote_tlsname(&zone->primaries) != NULL) { 18742 dns_view_t *view = dns_zone_getview(zone); 18743 dns_name_t *tlsname = dns_remote_tlsname(&zone->primaries); 18744 result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname, 18745 &zone->transport); 18746 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 18747 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18748 ISC_LOG_ERROR, 18749 "could not get TLS configuration for " 18750 "zone transfer: %s", 18751 isc_result_totext(result)); 18752 } 18753 } 18754 18755 LOCK_ZONE(zone); 18756 if (xfrtype != dns_rdatatype_soa) { 18757 /* 18758 * If 'xfrtype' is dns_rdatatype_soa, then the SOA query will be 18759 * performed by xfrin, otherwise, the SOA request performed by 18760 * soa_query() was successful and we should inform the xfrin 18761 * about the transport type used for that query, so that the 18762 * information can be presented in the statistics channel. 18763 */ 18764 soa_transport_type = get_request_transport_type(zone); 18765 } 18766 sourceaddr = zone->sourceaddr; 18767 UNLOCK_ZONE(zone); 18768 18769 INSIST(isc_sockaddr_pf(&primaryaddr) == isc_sockaddr_pf(&sourceaddr)); 18770 18771 zmgr_tlsctx_attach(zone->zmgr, &zmgr_tlsctx_cache); 18772 18773 dns_xfrin_create(zone, xfrtype, &primaryaddr, &sourceaddr, 18774 zone->tsigkey, soa_transport_type, zone->transport, 18775 zmgr_tlsctx_cache, zone->mctx, &xfr); 18776 INSIST(xfr != NULL); 18777 18778 isc_tlsctx_cache_detach(&zmgr_tlsctx_cache); 18779 18780 LOCK_ZONE(zone); 18781 if (zone->xfr != NULL) { 18782 dns_xfrin_detach(&zone->xfr); 18783 } 18784 dns_xfrin_attach(xfr, &zone->xfr); 18785 UNLOCK_ZONE(zone); 18786 18787 dns_xfrin_detach(&xfr); 18788 18789 /* 18790 * Any failure in this function is handled like a failed 18791 * zone transfer. This ensures that we get removed from 18792 * zmgr->xfrin_in_progress. 18793 */ 18794 result = dns_xfrin_start(zone->xfr, zone_xfrdone); 18795 if (result != ISC_R_SUCCESS) { 18796 zone_xfrdone(zone, NULL, result); 18797 return; 18798 } 18799 18800 LOCK_ZONE(zone); 18801 if (xfrtype == dns_rdatatype_axfr) { 18802 if (isc_sockaddr_pf(&primaryaddr) == PF_INET) { 18803 inc_stats(zone, dns_zonestatscounter_axfrreqv4); 18804 } else { 18805 inc_stats(zone, dns_zonestatscounter_axfrreqv6); 18806 } 18807 } else if (xfrtype == dns_rdatatype_ixfr) { 18808 if (isc_sockaddr_pf(&primaryaddr) == PF_INET) { 18809 inc_stats(zone, dns_zonestatscounter_ixfrreqv4); 18810 } else { 18811 inc_stats(zone, dns_zonestatscounter_ixfrreqv6); 18812 } 18813 } 18814 UNLOCK_ZONE(zone); 18815 } 18816 18817 /* 18818 * Update forwarding support. 18819 */ 18820 18821 static void 18822 forward_destroy(dns_forward_t *forward) { 18823 forward->magic = 0; 18824 if (forward->request != NULL) { 18825 dns_request_destroy(&forward->request); 18826 } 18827 if (forward->msgbuf != NULL) { 18828 isc_buffer_free(&forward->msgbuf); 18829 } 18830 if (forward->transport != NULL) { 18831 dns_transport_detach(&forward->transport); 18832 } 18833 if (forward->zone != NULL) { 18834 LOCK(&forward->zone->lock); 18835 if (ISC_LINK_LINKED(forward, link)) { 18836 ISC_LIST_UNLINK(forward->zone->forwards, forward, link); 18837 } 18838 UNLOCK(&forward->zone->lock); 18839 dns_zone_idetach(&forward->zone); 18840 } 18841 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward)); 18842 } 18843 18844 static isc_result_t 18845 sendtoprimary(dns_forward_t *forward) { 18846 isc_result_t result; 18847 isc_sockaddr_t src, any; 18848 dns_zone_t *zone = forward->zone; 18849 bool tls_transport_invalid = false; 18850 isc_tlsctx_cache_t *zmgr_tlsctx_cache = NULL; 18851 18852 LOCK_ZONE(zone); 18853 18854 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 18855 UNLOCK_ZONE(zone); 18856 return ISC_R_CANCELED; 18857 } 18858 18859 next: 18860 if (forward->which >= dns_remote_count(&forward->zone->primaries)) { 18861 UNLOCK_ZONE(zone); 18862 return ISC_R_NOMORE; 18863 } 18864 18865 forward->addr = dns_remote_addr(&zone->primaries, forward->which); 18866 18867 if (isc_sockaddr_disabled(&forward->addr)) { 18868 forward->which++; 18869 goto next; 18870 } 18871 18872 /* 18873 * Always use TCP regardless of whether the original update 18874 * used TCP. 18875 * XXX The timeout may but a bit small if we are far down a 18876 * transfer graph and have to try several primaries. 18877 */ 18878 switch (isc_sockaddr_pf(&forward->addr)) { 18879 case PF_INET: 18880 isc_sockaddr_any(&any); 18881 src = zone->primaries.sources[forward->which]; 18882 if (isc_sockaddr_equal(&src, &any)) { 18883 src = zone->xfrsource4; 18884 } 18885 break; 18886 case PF_INET6: 18887 isc_sockaddr_any6(&any); 18888 src = zone->primaries.sources[forward->which]; 18889 if (isc_sockaddr_equal(&src, &any)) { 18890 src = zone->xfrsource6; 18891 } 18892 break; 18893 default: 18894 result = ISC_R_NOTIMPLEMENTED; 18895 goto unlock; 18896 } 18897 18898 if (forward->transport != NULL) { 18899 dns_transport_detach(&forward->transport); 18900 } 18901 18902 if (dns_remote_tlsname(&zone->primaries) != NULL && 18903 zone->primaries.tlsnames[forward->which] != NULL) 18904 { 18905 dns_view_t *view = dns_zone_getview(zone); 18906 dns_name_t *tlsname = zone->primaries.tlsnames[forward->which]; 18907 18908 result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname, 18909 &forward->transport); 18910 18911 if (result != ISC_R_SUCCESS) { 18912 /* Log the error message when unlocked. */ 18913 tls_transport_invalid = true; 18914 goto unlock; 18915 } 18916 } 18917 18918 zmgr_tlsctx_attach(zone->zmgr, &zmgr_tlsctx_cache); 18919 18920 result = dns_request_createraw( 18921 forward->zone->view->requestmgr, forward->msgbuf, &src, 18922 &forward->addr, forward->transport, zmgr_tlsctx_cache, 18923 forward->options, 15 /* XXX */, 0, 0, forward->zone->loop, 18924 forward_callback, forward, &forward->request); 18925 18926 isc_tlsctx_cache_detach(&zmgr_tlsctx_cache); 18927 18928 if (result == ISC_R_SUCCESS) { 18929 if (!ISC_LINK_LINKED(forward, link)) { 18930 ISC_LIST_APPEND(zone->forwards, forward, link); 18931 } 18932 } 18933 18934 unlock: 18935 UNLOCK_ZONE(zone); 18936 18937 if (tls_transport_invalid) { 18938 dns_zone_log(zone, ISC_LOG_ERROR, 18939 "could not get TLS configuration " 18940 "for dynamic update: %s", 18941 isc_result_totext(result)); 18942 } 18943 18944 return result; 18945 } 18946 18947 static void 18948 forward_callback(void *arg) { 18949 dns_request_t *request = (dns_request_t *)arg; 18950 dns_forward_t *forward = dns_request_getarg(request); 18951 dns_message_t *msg = NULL; 18952 char primary[ISC_SOCKADDR_FORMATSIZE]; 18953 isc_result_t result; 18954 dns_zone_t *zone; 18955 18956 INSIST(DNS_FORWARD_VALID(forward)); 18957 zone = forward->zone; 18958 INSIST(DNS_ZONE_VALID(zone)); 18959 18960 ENTER; 18961 18962 isc_sockaddr_format(&forward->addr, primary, sizeof(primary)); 18963 18964 result = dns_request_getresult(request); 18965 if (result != ISC_R_SUCCESS) { 18966 dns_zone_log(zone, ISC_LOG_INFO, 18967 "could not forward dynamic update to %s: %s", 18968 primary, isc_result_totext(result)); 18969 goto next_primary; 18970 } 18971 18972 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, 18973 &msg); 18974 18975 result = dns_request_getresponse(request, msg, 18976 DNS_MESSAGEPARSE_PRESERVEORDER | 18977 DNS_MESSAGEPARSE_CLONEBUFFER); 18978 if (result != ISC_R_SUCCESS) { 18979 goto next_primary; 18980 } 18981 18982 /* 18983 * Unexpected opcode. 18984 */ 18985 if (msg->opcode != dns_opcode_update) { 18986 char opcode[128]; 18987 isc_buffer_t rb; 18988 18989 isc_buffer_init(&rb, opcode, sizeof(opcode)); 18990 (void)dns_opcode_totext(msg->opcode, &rb); 18991 18992 dns_zone_log(zone, ISC_LOG_INFO, 18993 "forwarding dynamic update: " 18994 "unexpected opcode (%.*s) from %s", 18995 (int)rb.used, opcode, primary); 18996 goto next_primary; 18997 } 18998 18999 switch (msg->rcode) { 19000 /* 19001 * Pass these rcodes back to client. 19002 */ 19003 case dns_rcode_noerror: 19004 case dns_rcode_yxdomain: 19005 case dns_rcode_yxrrset: 19006 case dns_rcode_nxrrset: 19007 case dns_rcode_refused: 19008 case dns_rcode_nxdomain: { 19009 char rcode[128]; 19010 isc_buffer_t rb; 19011 19012 isc_buffer_init(&rb, rcode, sizeof(rcode)); 19013 (void)dns_rcode_totext(msg->rcode, &rb); 19014 dns_zone_log(zone, ISC_LOG_INFO, 19015 "forwarded dynamic update: " 19016 "primary %s returned: %.*s", 19017 primary, (int)rb.used, rcode); 19018 break; 19019 } 19020 19021 /* These should not occur if the primaries/zone are valid. */ 19022 case dns_rcode_notzone: 19023 case dns_rcode_notauth: { 19024 char rcode[128]; 19025 isc_buffer_t rb; 19026 19027 isc_buffer_init(&rb, rcode, sizeof(rcode)); 19028 (void)dns_rcode_totext(msg->rcode, &rb); 19029 dns_zone_log(zone, ISC_LOG_WARNING, 19030 "forwarding dynamic update: " 19031 "unexpected response: primary %s returned: %.*s", 19032 primary, (int)rb.used, rcode); 19033 goto next_primary; 19034 } 19035 19036 /* Try another server for these rcodes. */ 19037 case dns_rcode_formerr: 19038 case dns_rcode_servfail: 19039 case dns_rcode_notimp: 19040 case dns_rcode_badvers: 19041 default: 19042 goto next_primary; 19043 } 19044 19045 /* call callback */ 19046 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg); 19047 msg = NULL; 19048 dns_request_destroy(&forward->request); 19049 forward_destroy(forward); 19050 return; 19051 19052 next_primary: 19053 if (msg != NULL) { 19054 dns_message_detach(&msg); 19055 } 19056 forward->which++; 19057 dns_request_destroy(&forward->request); 19058 result = sendtoprimary(forward); 19059 if (result != ISC_R_SUCCESS) { 19060 /* call callback */ 19061 dns_zone_log(zone, ISC_LOG_DEBUG(3), 19062 "exhausted dynamic update forwarder list"); 19063 (forward->callback)(forward->callback_arg, result, NULL); 19064 forward_destroy(forward); 19065 } 19066 } 19067 19068 isc_result_t 19069 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg, 19070 dns_updatecallback_t callback, void *callback_arg) { 19071 dns_forward_t *forward; 19072 isc_result_t result; 19073 isc_region_t *mr; 19074 19075 REQUIRE(DNS_ZONE_VALID(zone)); 19076 REQUIRE(msg != NULL); 19077 REQUIRE(callback != NULL); 19078 19079 forward = isc_mem_get(zone->mctx, sizeof(*forward)); 19080 *forward = (dns_forward_t){ .callback = callback, 19081 .callback_arg = callback_arg, 19082 .options = DNS_REQUESTOPT_TCP }; 19083 ISC_LINK_INIT(forward, link); 19084 forward->magic = FORWARD_MAGIC; 19085 19086 /* 19087 * If we have a SIG(0) signed message we need to preserve the 19088 * query id as that is included in the SIG(0) computation. 19089 */ 19090 if (msg->sig0 != NULL) { 19091 forward->options |= DNS_REQUESTOPT_FIXEDID; 19092 } 19093 19094 mr = dns_message_getrawmessage(msg); 19095 if (mr == NULL) { 19096 result = ISC_R_UNEXPECTEDEND; 19097 goto cleanup; 19098 } 19099 19100 isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length); 19101 result = isc_buffer_copyregion(forward->msgbuf, mr); 19102 if (result != ISC_R_SUCCESS) { 19103 goto cleanup; 19104 } 19105 19106 isc_mem_attach(zone->mctx, &forward->mctx); 19107 dns_zone_iattach(zone, &forward->zone); 19108 result = sendtoprimary(forward); 19109 19110 cleanup: 19111 if (result != ISC_R_SUCCESS) { 19112 forward_destroy(forward); 19113 } 19114 return result; 19115 } 19116 19117 isc_result_t 19118 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) { 19119 REQUIRE(DNS_ZONE_VALID(zone)); 19120 REQUIRE(next != NULL && *next == NULL); 19121 19122 *next = ISC_LIST_NEXT(zone, link); 19123 if (*next == NULL) { 19124 return ISC_R_NOMORE; 19125 } else { 19126 return ISC_R_SUCCESS; 19127 } 19128 } 19129 19130 isc_result_t 19131 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) { 19132 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19133 REQUIRE(first != NULL && *first == NULL); 19134 19135 *first = ISC_LIST_HEAD(zmgr->zones); 19136 if (*first == NULL) { 19137 return ISC_R_NOMORE; 19138 } else { 19139 return ISC_R_SUCCESS; 19140 } 19141 } 19142 19143 /*** 19144 *** Zone manager. 19145 ***/ 19146 19147 static void 19148 zonemgr_keymgmt_init(dns_zonemgr_t *zmgr) { 19149 dns_keymgmt_t *mgmt = isc_mem_get(zmgr->mctx, sizeof(*mgmt)); 19150 19151 *mgmt = (dns_keymgmt_t){ 19152 .magic = KEYMGMT_MAGIC, 19153 }; 19154 19155 isc_mem_attach(zmgr->mctx, &mgmt->mctx); 19156 isc_rwlock_init(&mgmt->lock); 19157 isc_hashmap_create(mgmt->mctx, DNS_KEYMGMT_HASH_BITS, &mgmt->table); 19158 19159 zmgr->keymgmt = mgmt; 19160 } 19161 19162 static void 19163 zonemgr_keymgmt_destroy(dns_zonemgr_t *zmgr) { 19164 dns_keymgmt_t *mgmt = zmgr->keymgmt; 19165 19166 REQUIRE(DNS_KEYMGMT_VALID(mgmt)); 19167 19168 mgmt->magic = 0; 19169 19170 RWLOCK(&mgmt->lock, isc_rwlocktype_write); 19171 INSIST(isc_hashmap_count(mgmt->table) == 0); 19172 RWUNLOCK(&mgmt->lock, isc_rwlocktype_write); 19173 isc_hashmap_destroy(&mgmt->table); 19174 19175 isc_rwlock_destroy(&mgmt->lock); 19176 isc_mem_putanddetach(&mgmt->mctx, mgmt, sizeof(dns_keymgmt_t)); 19177 } 19178 19179 static bool 19180 kfio_match(void *node, const void *key) { 19181 const dns_keyfileio_t *kfio = node; 19182 19183 return dns_name_equal(kfio->name, key); 19184 } 19185 19186 static void 19187 zonemgr_keymgmt_add(dns_zonemgr_t *zmgr, dns_zone_t *zone, 19188 dns_keyfileio_t **added) { 19189 dns_keymgmt_t *mgmt = zmgr->keymgmt; 19190 dns_keyfileio_t *kfio = NULL; 19191 isc_result_t result; 19192 dns_fixedname_t fname; 19193 dns_name_t *name; 19194 19195 REQUIRE(DNS_KEYMGMT_VALID(mgmt)); 19196 REQUIRE(added != NULL && *added == NULL); 19197 19198 name = dns_fixedname_initname(&fname); 19199 dns_name_downcase(&zone->origin, name, NULL); 19200 19201 RWLOCK(&mgmt->lock, isc_rwlocktype_write); 19202 19203 result = isc_hashmap_find(mgmt->table, dns_name_hash(name), kfio_match, 19204 name, (void **)&kfio); 19205 switch (result) { 19206 case ISC_R_SUCCESS: 19207 isc_refcount_increment(&kfio->references); 19208 break; 19209 case ISC_R_NOTFOUND: 19210 kfio = isc_mem_get(mgmt->mctx, sizeof(*kfio)); 19211 *kfio = (dns_keyfileio_t){ 19212 .magic = KEYFILEIO_MAGIC, 19213 }; 19214 isc_refcount_init(&kfio->references, 1); 19215 kfio->name = dns_fixedname_initname(&kfio->fname); 19216 dns_name_copy(name, kfio->name); 19217 19218 isc_mutex_init(&kfio->lock); 19219 result = isc_hashmap_add(mgmt->table, dns_name_hash(kfio->name), 19220 kfio_match, kfio->name, kfio, NULL); 19221 INSIST(result == ISC_R_SUCCESS); 19222 break; 19223 default: 19224 UNREACHABLE(); 19225 } 19226 *added = kfio; 19227 RWUNLOCK(&mgmt->lock, isc_rwlocktype_write); 19228 } 19229 19230 static bool 19231 match_ptr(void *node, const void *key) { 19232 return node == key; 19233 } 19234 19235 static void 19236 zonemgr_keymgmt_delete(dns_zonemgr_t *zmgr, dns_keyfileio_t **deleted) { 19237 REQUIRE(DNS_KEYMGMT_VALID(zmgr->keymgmt)); 19238 REQUIRE(deleted != NULL && DNS_KEYFILEIO_VALID(*deleted)); 19239 19240 dns_keymgmt_t *mgmt = zmgr->keymgmt; 19241 dns_keyfileio_t *kfio = *deleted; 19242 isc_result_t result; 19243 19244 *deleted = NULL; 19245 19246 RWLOCK(&mgmt->lock, isc_rwlocktype_write); 19247 19248 if (isc_refcount_decrement(&kfio->references) == 1) { 19249 isc_refcount_destroy(&kfio->references); 19250 kfio->magic = 0; 19251 isc_mutex_destroy(&kfio->lock); 19252 19253 result = isc_hashmap_delete(mgmt->table, 19254 dns_name_hash(kfio->name), 19255 match_ptr, kfio); 19256 INSIST(result == ISC_R_SUCCESS); 19257 19258 isc_mem_put(mgmt->mctx, kfio, sizeof(*kfio)); 19259 } 19260 19261 RWUNLOCK(&mgmt->lock, isc_rwlocktype_write); 19262 } 19263 19264 void 19265 dns_zonemgr_create(isc_mem_t *mctx, isc_nm_t *netmgr, dns_zonemgr_t **zmgrp) { 19266 dns_zonemgr_t *zmgr = NULL; 19267 isc_loop_t *loop = isc_loop(); 19268 isc_loopmgr_t *loopmgr = isc_loop_getloopmgr(loop); 19269 19270 REQUIRE(mctx != NULL); 19271 REQUIRE(netmgr != NULL); 19272 REQUIRE(zmgrp != NULL && *zmgrp == NULL); 19273 19274 zmgr = isc_mem_get(mctx, sizeof(*zmgr)); 19275 19276 *zmgr = (dns_zonemgr_t){ 19277 .loopmgr = loopmgr, 19278 .netmgr = netmgr, 19279 .workers = isc_loopmgr_nloops(loopmgr), 19280 .transfersin = 10, 19281 .transfersperns = 2, 19282 }; 19283 19284 isc_refcount_init(&zmgr->refs, 1); 19285 isc_mem_attach(mctx, &zmgr->mctx); 19286 19287 ISC_LIST_INIT(zmgr->zones); 19288 ISC_LIST_INIT(zmgr->waiting_for_xfrin); 19289 ISC_LIST_INIT(zmgr->xfrin_in_progress); 19290 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable)); 19291 for (size_t i = 0; i < UNREACH_CACHE_SIZE; i++) { 19292 atomic_init(&zmgr->unreachable[i].expire, 0); 19293 } 19294 isc_rwlock_init(&zmgr->rwlock); 19295 19296 /* Unreachable lock. */ 19297 isc_rwlock_init(&zmgr->urlock); 19298 19299 isc_ratelimiter_create(loop, &zmgr->checkdsrl); 19300 isc_ratelimiter_create(loop, &zmgr->notifyrl); 19301 isc_ratelimiter_create(loop, &zmgr->refreshrl); 19302 isc_ratelimiter_create(loop, &zmgr->startupnotifyrl); 19303 isc_ratelimiter_create(loop, &zmgr->startuprefreshrl); 19304 19305 zmgr->mctxpool = isc_mem_cget(zmgr->mctx, zmgr->workers, 19306 sizeof(zmgr->mctxpool[0])); 19307 for (size_t i = 0; i < zmgr->workers; i++) { 19308 isc_mem_create(&zmgr->mctxpool[i]); 19309 isc_mem_setname(zmgr->mctxpool[i], "zonemgr-mctxpool"); 19310 } 19311 19312 /* Key file I/O locks. */ 19313 zonemgr_keymgmt_init(zmgr); 19314 19315 /* Default to 20 refresh queries / notifies / checkds per second. */ 19316 setrl(zmgr->checkdsrl, &zmgr->checkdsrate, 20); 19317 setrl(zmgr->notifyrl, &zmgr->notifyrate, 20); 19318 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20); 19319 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20); 19320 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20); 19321 isc_ratelimiter_setpushpop(zmgr->startupnotifyrl, true); 19322 isc_ratelimiter_setpushpop(zmgr->startuprefreshrl, true); 19323 19324 zmgr->tlsctx_cache = NULL; 19325 isc_rwlock_init(&zmgr->tlsctx_cache_rwlock); 19326 19327 zmgr->magic = ZONEMGR_MAGIC; 19328 19329 *zmgrp = zmgr; 19330 } 19331 19332 isc_result_t 19333 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) { 19334 isc_mem_t *mctx = NULL; 19335 dns_zone_t *zone = NULL; 19336 unsigned int tid; 19337 19338 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19339 REQUIRE(zonep != NULL && *zonep == NULL); 19340 19341 if (zmgr->mctxpool == NULL) { 19342 return ISC_R_FAILURE; 19343 } 19344 19345 tid = isc_random_uniform(zmgr->workers); 19346 19347 mctx = zmgr->mctxpool[tid]; 19348 if (mctx == NULL) { 19349 return ISC_R_FAILURE; 19350 } 19351 19352 dns_zone_create(&zone, mctx, tid); 19353 19354 *zonep = zone; 19355 19356 return ISC_R_SUCCESS; 19357 } 19358 19359 isc_result_t 19360 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 19361 REQUIRE(DNS_ZONE_VALID(zone)); 19362 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19363 19364 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19365 LOCK_ZONE(zone); 19366 REQUIRE(zone->timer == NULL); 19367 REQUIRE(zone->zmgr == NULL); 19368 19369 isc_loop_t *loop = isc_loop_get(zmgr->loopmgr, zone->tid); 19370 isc_loop_attach(loop, &zone->loop); 19371 19372 zonemgr_keymgmt_add(zmgr, zone, &zone->kfio); 19373 INSIST(zone->kfio != NULL); 19374 19375 ISC_LIST_APPEND(zmgr->zones, zone, link); 19376 zone->zmgr = zmgr; 19377 19378 isc_refcount_increment(&zmgr->refs); 19379 19380 UNLOCK_ZONE(zone); 19381 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19382 return ISC_R_SUCCESS; 19383 } 19384 19385 void 19386 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 19387 REQUIRE(DNS_ZONE_VALID(zone)); 19388 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19389 REQUIRE(zone->zmgr == zmgr); 19390 19391 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19392 LOCK_ZONE(zone); 19393 19394 ISC_LIST_UNLINK(zmgr->zones, zone, link); 19395 19396 if (zone->kfio != NULL) { 19397 zonemgr_keymgmt_delete(zmgr, &zone->kfio); 19398 ENSURE(zone->kfio == NULL); 19399 } 19400 19401 if (zone->timer != NULL) { 19402 isc_refcount_decrement(&zone->irefs); 19403 isc_timer_destroy(&zone->timer); 19404 } 19405 19406 isc_loop_detach(&zone->loop); 19407 19408 /* Detach below, outside of the write lock. */ 19409 zone->zmgr = NULL; 19410 19411 UNLOCK_ZONE(zone); 19412 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19413 19414 dns_zonemgr_detach(&zmgr); 19415 } 19416 19417 void 19418 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) { 19419 REQUIRE(DNS_ZONEMGR_VALID(source)); 19420 REQUIRE(target != NULL && *target == NULL); 19421 19422 isc_refcount_increment(&source->refs); 19423 19424 *target = source; 19425 } 19426 19427 void 19428 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) { 19429 dns_zonemgr_t *zmgr; 19430 19431 REQUIRE(zmgrp != NULL); 19432 zmgr = *zmgrp; 19433 *zmgrp = NULL; 19434 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19435 19436 if (isc_refcount_decrement(&zmgr->refs) == 1) { 19437 zonemgr_free(zmgr); 19438 } 19439 } 19440 19441 isc_result_t 19442 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) { 19443 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19444 19445 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19446 for (dns_zone_t *zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 19447 zone = ISC_LIST_NEXT(zone, link)) 19448 { 19449 isc_time_t now; 19450 19451 LOCK_ZONE(zone); 19452 now = isc_time_now(); 19453 zone_settimer(zone, &now); 19454 UNLOCK_ZONE(zone); 19455 } 19456 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19457 19458 /* 19459 * Recent configuration changes may have increased the 19460 * amount of available transfers quota. Make sure any 19461 * transfers currently blocked on quota get started if 19462 * possible. 19463 */ 19464 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19465 zmgr_resume_xfrs(zmgr, true); 19466 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19467 return ISC_R_SUCCESS; 19468 } 19469 19470 void 19471 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) { 19472 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19473 19474 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19475 zmgr_resume_xfrs(zmgr, true); 19476 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19477 } 19478 19479 void 19480 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) { 19481 dns_zone_t *zone; 19482 19483 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19484 19485 isc_ratelimiter_shutdown(zmgr->checkdsrl); 19486 isc_ratelimiter_shutdown(zmgr->notifyrl); 19487 isc_ratelimiter_shutdown(zmgr->refreshrl); 19488 isc_ratelimiter_shutdown(zmgr->startupnotifyrl); 19489 isc_ratelimiter_shutdown(zmgr->startuprefreshrl); 19490 19491 for (size_t i = 0; i < zmgr->workers; i++) { 19492 isc_mem_detach(&zmgr->mctxpool[i]); 19493 } 19494 19495 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19496 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 19497 zone = ISC_LIST_NEXT(zone, link)) 19498 { 19499 LOCK_ZONE(zone); 19500 forward_cancel(zone); 19501 UNLOCK_ZONE(zone); 19502 } 19503 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19504 } 19505 19506 static void 19507 zonemgr_free(dns_zonemgr_t *zmgr) { 19508 REQUIRE(ISC_LIST_EMPTY(zmgr->zones)); 19509 19510 zmgr->magic = 0; 19511 19512 isc_refcount_destroy(&zmgr->refs); 19513 isc_ratelimiter_detach(&zmgr->checkdsrl); 19514 isc_ratelimiter_detach(&zmgr->notifyrl); 19515 isc_ratelimiter_detach(&zmgr->refreshrl); 19516 isc_ratelimiter_detach(&zmgr->startupnotifyrl); 19517 isc_ratelimiter_detach(&zmgr->startuprefreshrl); 19518 19519 isc_mem_cput(zmgr->mctx, zmgr->mctxpool, zmgr->workers, 19520 sizeof(zmgr->mctxpool[0])); 19521 19522 isc_rwlock_destroy(&zmgr->urlock); 19523 isc_rwlock_destroy(&zmgr->rwlock); 19524 isc_rwlock_destroy(&zmgr->tlsctx_cache_rwlock); 19525 19526 zonemgr_keymgmt_destroy(zmgr); 19527 19528 if (zmgr->tlsctx_cache != NULL) { 19529 isc_tlsctx_cache_detach(&zmgr->tlsctx_cache); 19530 } 19531 isc_mem_putanddetach(&zmgr->mctx, zmgr, sizeof(*zmgr)); 19532 } 19533 19534 void 19535 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value) { 19536 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19537 19538 zmgr->transfersin = value; 19539 } 19540 19541 uint32_t 19542 dns_zonemgr_gettransfersin(dns_zonemgr_t *zmgr) { 19543 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19544 19545 return zmgr->transfersin; 19546 } 19547 19548 void 19549 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, uint32_t value) { 19550 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19551 19552 zmgr->transfersperns = value; 19553 } 19554 19555 uint32_t 19556 dns_zonemgr_gettransfersperns(dns_zonemgr_t *zmgr) { 19557 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19558 19559 return zmgr->transfersperns; 19560 } 19561 19562 /* 19563 * Try to start a new incoming zone transfer to fill a quota 19564 * slot that was just vacated. 19565 * 19566 * Requires: 19567 * The zone manager is locked by the caller. 19568 */ 19569 static void 19570 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi) { 19571 dns_zone_t *zone; 19572 dns_zone_t *next; 19573 19574 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); zone != NULL; 19575 zone = next) 19576 { 19577 isc_result_t result; 19578 next = ISC_LIST_NEXT(zone, statelink); 19579 result = zmgr_start_xfrin_ifquota(zmgr, zone); 19580 if (result == ISC_R_SUCCESS) { 19581 if (multi) { 19582 continue; 19583 } 19584 /* 19585 * We successfully filled the slot. We're done. 19586 */ 19587 break; 19588 } else if (result == ISC_R_QUOTA) { 19589 /* 19590 * Not enough quota. This is probably the per-server 19591 * quota, because we usually get called when a unit of 19592 * global quota has just been freed. Try the next 19593 * zone, it may succeed if it uses another primary. 19594 */ 19595 continue; 19596 } else { 19597 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 19598 ISC_LOG_DEBUG(1), 19599 "starting zone transfer: %s", 19600 isc_result_totext(result)); 19601 break; 19602 } 19603 } 19604 } 19605 19606 /* 19607 * Try to start an incoming zone transfer for 'zone', quota permitting. 19608 * 19609 * Requires: 19610 * The zone manager is locked by the caller. 19611 * 19612 * Returns: 19613 * ISC_R_SUCCESS There was enough quota and we attempted to 19614 * start a transfer. zone_xfrdone() has been or will 19615 * be called. 19616 * ISC_R_QUOTA Not enough quota. 19617 * Others Failure. 19618 */ 19619 static isc_result_t 19620 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 19621 dns_peer_t *peer = NULL; 19622 isc_netaddr_t primaryip; 19623 isc_sockaddr_t curraddr; 19624 uint32_t nxfrsin, nxfrsperns; 19625 dns_zone_t *x = NULL; 19626 uint32_t maxtransfersin, maxtransfersperns; 19627 19628 /* 19629 * If we are exiting just pretend we got quota so the zone will 19630 * be cleaned up in the zone's loop context. 19631 */ 19632 LOCK_ZONE(zone); 19633 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 19634 UNLOCK_ZONE(zone); 19635 goto gotquota; 19636 } 19637 19638 /* 19639 * Find any configured information about the server we'd 19640 * like to transfer this zone from. 19641 */ 19642 curraddr = dns_remote_curraddr(&zone->primaries); 19643 isc_netaddr_fromsockaddr(&primaryip, &curraddr); 19644 (void)dns_peerlist_peerbyaddr(zone->view->peers, &primaryip, &peer); 19645 UNLOCK_ZONE(zone); 19646 19647 /* 19648 * Determine the total maximum number of simultaneous 19649 * transfers allowed, and the maximum for this specific 19650 * primary. 19651 */ 19652 maxtransfersin = zmgr->transfersin; 19653 maxtransfersperns = zmgr->transfersperns; 19654 if (peer != NULL) { 19655 (void)dns_peer_gettransfers(peer, &maxtransfersperns); 19656 } 19657 19658 /* 19659 * Count the total number of transfers that are in progress, 19660 * and the number of transfers in progress from this primary. 19661 * We linearly scan a list of all transfers; if this turns 19662 * out to be too slow, we could hash on the primary address. 19663 */ 19664 nxfrsin = nxfrsperns = 0; 19665 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress); x != NULL; 19666 x = ISC_LIST_NEXT(x, statelink)) 19667 { 19668 isc_netaddr_t xip; 19669 isc_sockaddr_t xaddr; 19670 19671 LOCK_ZONE(x); 19672 xaddr = dns_remote_curraddr(&x->primaries); 19673 isc_netaddr_fromsockaddr(&xip, &xaddr); 19674 UNLOCK_ZONE(x); 19675 19676 nxfrsin++; 19677 if (isc_netaddr_equal(&xip, &primaryip)) { 19678 nxfrsperns++; 19679 } 19680 } 19681 19682 /* Enforce quota. */ 19683 if (nxfrsin >= maxtransfersin) { 19684 return ISC_R_QUOTA; 19685 } 19686 19687 if (nxfrsperns >= maxtransfersperns) { 19688 return ISC_R_QUOTA; 19689 } 19690 19691 gotquota: 19692 /* 19693 * We have sufficient quota. Move the zone to the "xfrin_in_progress" 19694 * list and start the actual transfer asynchronously. 19695 */ 19696 LOCK_ZONE(zone); 19697 INSIST(zone->statelist == &zmgr->waiting_for_xfrin); 19698 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink); 19699 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink); 19700 zone->statelist = &zmgr->xfrin_in_progress; 19701 isc_async_run(zone->loop, got_transfer_quota, zone); 19702 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 19703 "Transfer started."); 19704 UNLOCK_ZONE(zone); 19705 19706 return ISC_R_SUCCESS; 19707 } 19708 19709 static void 19710 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) { 19711 char *buf; 19712 int buflen; 19713 isc_result_t result; 19714 19715 buflen = strlen(path) + strlen(templat) + 2; 19716 19717 buf = isc_mem_get(zone->mctx, buflen); 19718 19719 result = isc_file_template(path, templat, buf, buflen); 19720 if (result != ISC_R_SUCCESS) { 19721 goto cleanup; 19722 } 19723 19724 result = isc_file_renameunique(path, buf); 19725 if (result != ISC_R_SUCCESS) { 19726 goto cleanup; 19727 } 19728 19729 dns_zone_log(zone, ISC_LOG_WARNING, 19730 "unable to load from '%s'; " 19731 "renaming file to '%s' for failure analysis and " 19732 "retransferring.", 19733 path, buf); 19734 19735 cleanup: 19736 isc_mem_put(zone->mctx, buf, buflen); 19737 } 19738 19739 static void 19740 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) { 19741 isc_interval_t interval; 19742 uint32_t s, ns; 19743 uint32_t pertic; 19744 19745 if (value == 0) { 19746 value = 1; 19747 } 19748 19749 if (value == 1) { 19750 s = 1; 19751 ns = 0; 19752 pertic = 1; 19753 } else if (value <= 10) { 19754 s = 0; 19755 ns = 1000000000 / value; 19756 pertic = 1; 19757 } else { 19758 s = 0; 19759 ns = (1000000000 / value) * 10; 19760 pertic = 10; 19761 } 19762 19763 isc_interval_set(&interval, s, ns); 19764 19765 isc_ratelimiter_setinterval(rl, &interval); 19766 isc_ratelimiter_setpertic(rl, pertic); 19767 19768 *rate = value; 19769 } 19770 19771 void 19772 dns_zonemgr_setcheckdsrate(dns_zonemgr_t *zmgr, unsigned int value) { 19773 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19774 19775 setrl(zmgr->checkdsrl, &zmgr->checkdsrate, value); 19776 } 19777 19778 void 19779 dns_zonemgr_setnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) { 19780 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19781 19782 setrl(zmgr->notifyrl, &zmgr->notifyrate, value); 19783 } 19784 19785 void 19786 dns_zonemgr_setstartupnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) { 19787 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19788 19789 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value); 19790 } 19791 19792 void 19793 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) { 19794 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19795 19796 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value); 19797 /* XXXMPA separate out once we have the code to support this. */ 19798 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value); 19799 } 19800 19801 unsigned int 19802 dns_zonemgr_getnotifyrate(dns_zonemgr_t *zmgr) { 19803 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19804 19805 return zmgr->notifyrate; 19806 } 19807 19808 unsigned int 19809 dns_zonemgr_getstartupnotifyrate(dns_zonemgr_t *zmgr) { 19810 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19811 19812 return zmgr->startupnotifyrate; 19813 } 19814 19815 unsigned int 19816 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) { 19817 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19818 19819 return zmgr->serialqueryrate; 19820 } 19821 19822 bool 19823 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 19824 isc_sockaddr_t *local, isc_time_t *now) { 19825 unsigned int i; 19826 uint32_t seconds = isc_time_seconds(now); 19827 uint32_t count = 0; 19828 19829 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19830 19831 RWLOCK(&zmgr->urlock, isc_rwlocktype_read); 19832 for (i = 0; i < UNREACH_CACHE_SIZE; i++) { 19833 if (atomic_load(&zmgr->unreachable[i].expire) >= seconds && 19834 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 19835 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 19836 { 19837 atomic_store_relaxed(&zmgr->unreachable[i].last, 19838 seconds); 19839 count = zmgr->unreachable[i].count; 19840 break; 19841 } 19842 } 19843 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read); 19844 return i < UNREACH_CACHE_SIZE && count > 1U; 19845 } 19846 19847 void 19848 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 19849 isc_sockaddr_t *local) { 19850 unsigned int i; 19851 19852 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19853 19854 RWLOCK(&zmgr->urlock, isc_rwlocktype_read); 19855 for (i = 0; i < UNREACH_CACHE_SIZE; i++) { 19856 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 19857 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 19858 { 19859 atomic_store_relaxed(&zmgr->unreachable[i].expire, 0); 19860 break; 19861 } 19862 } 19863 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read); 19864 } 19865 19866 void 19867 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 19868 isc_sockaddr_t *local, isc_time_t *now) { 19869 uint32_t seconds = isc_time_seconds(now); 19870 uint32_t expire = 0, last = seconds; 19871 unsigned int slot = UNREACH_CACHE_SIZE, oldest = 0; 19872 bool update_entry = true; 19873 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19874 19875 RWLOCK(&zmgr->urlock, isc_rwlocktype_write); 19876 for (unsigned int i = 0; i < UNREACH_CACHE_SIZE; i++) { 19877 /* Existing entry? */ 19878 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 19879 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 19880 { 19881 update_entry = false; 19882 slot = i; 19883 expire = atomic_load_relaxed( 19884 &zmgr->unreachable[i].expire); 19885 break; 19886 } 19887 /* Pick first empty slot? */ 19888 if (atomic_load_relaxed(&zmgr->unreachable[i].expire) < seconds) 19889 { 19890 slot = i; 19891 break; 19892 } 19893 /* The worst case, least recently used slot? */ 19894 if (atomic_load_relaxed(&zmgr->unreachable[i].last) < last) { 19895 last = atomic_load_relaxed(&zmgr->unreachable[i].last); 19896 oldest = i; 19897 } 19898 } 19899 19900 /* We haven't found any existing or free slots, use the oldest */ 19901 if (slot == UNREACH_CACHE_SIZE) { 19902 slot = oldest; 19903 } 19904 19905 if (expire < seconds) { 19906 /* Expired or new entry, reset count to 1 */ 19907 zmgr->unreachable[slot].count = 1; 19908 } else { 19909 zmgr->unreachable[slot].count++; 19910 } 19911 atomic_store_relaxed(&zmgr->unreachable[slot].expire, 19912 seconds + UNREACH_HOLD_TIME); 19913 atomic_store_relaxed(&zmgr->unreachable[slot].last, seconds); 19914 if (update_entry) { 19915 zmgr->unreachable[slot].remote = *remote; 19916 zmgr->unreachable[slot].local = *local; 19917 } 19918 19919 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write); 19920 } 19921 19922 void 19923 dns_zone_stopxfr(dns_zone_t *zone) { 19924 dns_xfrin_t *xfr = NULL; 19925 19926 REQUIRE(DNS_ZONE_VALID(zone)); 19927 19928 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_read); 19929 LOCK_ZONE(zone); 19930 if (zone->statelist == &zone->zmgr->xfrin_in_progress && 19931 zone->xfr != NULL) 19932 { 19933 dns_xfrin_attach(zone->xfr, &xfr); 19934 } 19935 UNLOCK_ZONE(zone); 19936 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_read); 19937 19938 if (xfr != NULL) { 19939 dns_xfrin_shutdown(xfr); 19940 dns_xfrin_detach(&xfr); 19941 } 19942 } 19943 19944 void 19945 dns_zone_forcexfr(dns_zone_t *zone) { 19946 REQUIRE(DNS_ZONE_VALID(zone)); 19947 19948 if (zone->type == dns_zone_primary || 19949 (zone->type == dns_zone_redirect && 19950 dns_remote_addresses(&zone->primaries) == NULL)) 19951 { 19952 return; 19953 } 19954 19955 LOCK_ZONE(zone); 19956 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER); 19957 UNLOCK_ZONE(zone); 19958 dns_zone_refresh(zone); 19959 } 19960 19961 bool 19962 dns_zone_isforced(dns_zone_t *zone) { 19963 REQUIRE(DNS_ZONE_VALID(zone)); 19964 19965 return DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER); 19966 } 19967 19968 isc_result_t 19969 dns_zone_setstatistics(dns_zone_t *zone, bool on) { 19970 /* 19971 * This function is obsoleted. 19972 */ 19973 UNUSED(zone); 19974 UNUSED(on); 19975 return ISC_R_NOTIMPLEMENTED; 19976 } 19977 19978 uint64_t * 19979 dns_zone_getstatscounters(dns_zone_t *zone) { 19980 /* 19981 * This function is obsoleted. 19982 */ 19983 UNUSED(zone); 19984 return NULL; 19985 } 19986 19987 void 19988 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) { 19989 REQUIRE(DNS_ZONE_VALID(zone)); 19990 REQUIRE(zone->stats == NULL); 19991 19992 LOCK_ZONE(zone); 19993 zone->stats = NULL; 19994 isc_stats_attach(stats, &zone->stats); 19995 UNLOCK_ZONE(zone); 19996 } 19997 19998 void 19999 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) { 20000 REQUIRE(DNS_ZONE_VALID(zone)); 20001 20002 LOCK_ZONE(zone); 20003 if (zone->requeststats_on && stats == NULL) { 20004 zone->requeststats_on = false; 20005 } else if (!zone->requeststats_on && stats != NULL) { 20006 if (zone->requeststats == NULL) { 20007 isc_stats_attach(stats, &zone->requeststats); 20008 } 20009 zone->requeststats_on = true; 20010 } 20011 UNLOCK_ZONE(zone); 20012 } 20013 20014 void 20015 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) { 20016 REQUIRE(DNS_ZONE_VALID(zone)); 20017 20018 LOCK_ZONE(zone); 20019 if (zone->requeststats_on && stats != NULL) { 20020 if (zone->rcvquerystats == NULL) { 20021 dns_stats_attach(stats, &zone->rcvquerystats); 20022 zone->requeststats_on = true; 20023 } 20024 } 20025 UNLOCK_ZONE(zone); 20026 } 20027 20028 void 20029 dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats) { 20030 REQUIRE(DNS_ZONE_VALID(zone)); 20031 20032 LOCK_ZONE(zone); 20033 if (stats != NULL && zone->dnssecsignstats == NULL) { 20034 dns_stats_attach(stats, &zone->dnssecsignstats); 20035 } 20036 UNLOCK_ZONE(zone); 20037 } 20038 20039 dns_stats_t * 20040 dns_zone_getdnssecsignstats(dns_zone_t *zone) { 20041 REQUIRE(DNS_ZONE_VALID(zone)); 20042 20043 return zone->dnssecsignstats; 20044 } 20045 20046 isc_stats_t * 20047 dns_zone_getrequeststats(dns_zone_t *zone) { 20048 /* 20049 * We don't lock zone for efficiency reason. This is not catastrophic 20050 * because requeststats must always be valid when requeststats_on is 20051 * true. 20052 * Some counters may be incremented while requeststats_on is becoming 20053 * false, or some cannot be incremented just after the statistics are 20054 * installed, but it shouldn't matter much in practice. 20055 */ 20056 if (zone->requeststats_on) { 20057 return zone->requeststats; 20058 } else { 20059 return NULL; 20060 } 20061 } 20062 20063 /* 20064 * Return the received query stats bucket 20065 * see note from dns_zone_getrequeststats() 20066 */ 20067 dns_stats_t * 20068 dns_zone_getrcvquerystats(dns_zone_t *zone) { 20069 if (zone->requeststats_on) { 20070 return zone->rcvquerystats; 20071 } else { 20072 return NULL; 20073 } 20074 } 20075 20076 void 20077 dns_zone_dialup(dns_zone_t *zone) { 20078 REQUIRE(DNS_ZONE_VALID(zone)); 20079 20080 zone_debuglog(zone, __func__, 3, "notify = %d, refresh = %d", 20081 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY), 20082 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)); 20083 20084 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) { 20085 dns_zone_notify(zone, true); 20086 } 20087 if (zone->type != dns_zone_primary && 20088 dns_remote_addresses(&zone->primaries) != NULL && 20089 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 20090 { 20091 dns_zone_refresh(zone); 20092 } 20093 } 20094 20095 void 20096 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) { 20097 REQUIRE(DNS_ZONE_VALID(zone)); 20098 20099 LOCK_ZONE(zone); 20100 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY | 20101 DNS_ZONEFLG_DIALREFRESH | 20102 DNS_ZONEFLG_NOREFRESH); 20103 switch (dialup) { 20104 case dns_dialuptype_no: 20105 break; 20106 case dns_dialuptype_yes: 20107 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY | 20108 DNS_ZONEFLG_DIALREFRESH | 20109 DNS_ZONEFLG_NOREFRESH); 20110 break; 20111 case dns_dialuptype_notify: 20112 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 20113 break; 20114 case dns_dialuptype_notifypassive: 20115 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 20116 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 20117 break; 20118 case dns_dialuptype_refresh: 20119 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH); 20120 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 20121 break; 20122 case dns_dialuptype_passive: 20123 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 20124 break; 20125 default: 20126 UNREACHABLE(); 20127 } 20128 UNLOCK_ZONE(zone); 20129 } 20130 20131 isc_result_t 20132 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) { 20133 isc_result_t result = ISC_R_SUCCESS; 20134 20135 REQUIRE(DNS_ZONE_VALID(zone)); 20136 20137 LOCK_ZONE(zone); 20138 result = dns_zone_setstring(zone, &zone->keydirectory, directory); 20139 UNLOCK_ZONE(zone); 20140 20141 return result; 20142 } 20143 20144 const char * 20145 dns_zone_getkeydirectory(dns_zone_t *zone) { 20146 REQUIRE(DNS_ZONE_VALID(zone)); 20147 20148 return zone->keydirectory; 20149 } 20150 20151 void 20152 dns_zone_setkeystores(dns_zone_t *zone, dns_keystorelist_t *keystores) { 20153 REQUIRE(DNS_ZONE_VALID(zone)); 20154 20155 LOCK_ZONE(zone); 20156 zone->keystores = keystores; 20157 UNLOCK_ZONE(zone); 20158 } 20159 20160 dns_keystorelist_t * 20161 dns_zone_getkeystores(dns_zone_t *zone) { 20162 dns_keystorelist_t *ks = NULL; 20163 20164 REQUIRE(DNS_ZONE_VALID(zone)); 20165 20166 LOCK_ZONE(zone); 20167 if (inline_raw(zone) && zone->secure != NULL) { 20168 ks = zone->secure->keystores; 20169 } else { 20170 ks = zone->keystores; 20171 } 20172 UNLOCK_ZONE(zone); 20173 20174 return ks; 20175 } 20176 20177 unsigned int 20178 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, dns_zonestate_t state) { 20179 dns_zone_t *zone; 20180 unsigned int count = 0; 20181 20182 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 20183 20184 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 20185 switch (state) { 20186 case DNS_ZONESTATE_XFERRUNNING: 20187 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress); 20188 zone != NULL; zone = ISC_LIST_NEXT(zone, statelink)) 20189 { 20190 count++; 20191 } 20192 break; 20193 case DNS_ZONESTATE_XFERDEFERRED: 20194 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); 20195 zone != NULL; zone = ISC_LIST_NEXT(zone, statelink)) 20196 { 20197 count++; 20198 } 20199 break; 20200 case DNS_ZONESTATE_XFERFIRSTREFRESH: 20201 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 20202 zone = ISC_LIST_NEXT(zone, link)) 20203 { 20204 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FIRSTREFRESH)) { 20205 count++; 20206 } 20207 } 20208 break; 20209 case DNS_ZONESTATE_SOAQUERY: 20210 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 20211 zone = ISC_LIST_NEXT(zone, link)) 20212 { 20213 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { 20214 count++; 20215 } 20216 } 20217 break; 20218 case DNS_ZONESTATE_ANY: 20219 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 20220 zone = ISC_LIST_NEXT(zone, link)) 20221 { 20222 dns_view_t *view = zone->view; 20223 if (view != NULL && strcmp(view->name, "_bind") == 0) { 20224 continue; 20225 } 20226 count++; 20227 } 20228 break; 20229 case DNS_ZONESTATE_AUTOMATIC: 20230 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 20231 zone = ISC_LIST_NEXT(zone, link)) 20232 { 20233 dns_view_t *view = zone->view; 20234 if (view != NULL && strcmp(view->name, "_bind") == 0) { 20235 continue; 20236 } 20237 if (zone->automatic) { 20238 count++; 20239 } 20240 } 20241 break; 20242 default: 20243 UNREACHABLE(); 20244 } 20245 20246 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 20247 20248 return count; 20249 } 20250 20251 isc_result_t 20252 dns_zone_getxfr(dns_zone_t *zone, dns_xfrin_t **xfrp, bool *is_firstrefresh, 20253 bool *is_running, bool *is_deferred, bool *is_presoa, 20254 bool *is_pending, bool *needs_refresh) { 20255 REQUIRE(DNS_ZONE_VALID(zone)); 20256 REQUIRE(xfrp != NULL && *xfrp == NULL); 20257 20258 if (zone->zmgr == NULL) { 20259 return ISC_R_FAILURE; 20260 } 20261 20262 /* Reset. */ 20263 *is_firstrefresh = false; 20264 *is_running = false; 20265 *is_deferred = false; 20266 *is_presoa = false; 20267 *is_pending = false; 20268 *needs_refresh = false; 20269 20270 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_read); 20271 LOCK_ZONE(zone); 20272 *is_firstrefresh = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FIRSTREFRESH); 20273 if (zone->xfr != NULL) { 20274 dns_xfrin_attach(zone->xfr, xfrp); 20275 } 20276 if (zone->statelist == &zone->zmgr->xfrin_in_progress) { 20277 *is_running = true; 20278 /* 20279 * The NEEDREFRESH flag is set only when a notify was received 20280 * while the current zone transfer is running. 20281 */ 20282 *needs_refresh = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 20283 } else if (zone->statelist == &zone->zmgr->waiting_for_xfrin) { 20284 *is_deferred = true; 20285 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { 20286 if (zone->request != NULL) { 20287 *is_presoa = true; 20288 } else { 20289 *is_pending = true; 20290 } 20291 } else { 20292 /* 20293 * No operation is ongoing or pending, just check if the zone 20294 * needs a refresh by looking at the refresh and expire times. 20295 */ 20296 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && 20297 (zone->type == dns_zone_secondary || 20298 zone->type == dns_zone_mirror || 20299 zone->type == dns_zone_stub)) 20300 { 20301 isc_time_t now = isc_time_now(); 20302 if (isc_time_compare(&now, &zone->refreshtime) >= 0 || 20303 isc_time_compare(&now, &zone->expiretime) >= 0) 20304 { 20305 *needs_refresh = true; 20306 } 20307 } 20308 } 20309 UNLOCK_ZONE(zone); 20310 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_read); 20311 20312 return ISC_R_SUCCESS; 20313 } 20314 20315 void 20316 dns_zone_lock_keyfiles(dns_zone_t *zone) { 20317 REQUIRE(DNS_ZONE_VALID(zone)); 20318 20319 if (zone->kasp == NULL) { 20320 /* No need to lock, nothing is writing key files. */ 20321 return; 20322 } 20323 20324 REQUIRE(DNS_KEYFILEIO_VALID(zone->kfio)); 20325 isc_mutex_lock(&zone->kfio->lock); 20326 } 20327 20328 void 20329 dns_zone_unlock_keyfiles(dns_zone_t *zone) { 20330 REQUIRE(DNS_ZONE_VALID(zone)); 20331 20332 if (zone->kasp == NULL) { 20333 /* No need to lock, nothing is writing key files. */ 20334 return; 20335 } 20336 20337 REQUIRE(DNS_KEYFILEIO_VALID(zone->kfio)); 20338 isc_mutex_unlock(&zone->kfio->lock); 20339 } 20340 20341 isc_result_t 20342 dns_zone_checknames(dns_zone_t *zone, const dns_name_t *name, 20343 dns_rdata_t *rdata) { 20344 bool ok = true; 20345 bool fail = false; 20346 char namebuf[DNS_NAME_FORMATSIZE]; 20347 char namebuf2[DNS_NAME_FORMATSIZE]; 20348 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 20349 int level = ISC_LOG_WARNING; 20350 dns_name_t bad; 20351 20352 REQUIRE(DNS_ZONE_VALID(zone)); 20353 20354 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) && 20355 rdata->type != dns_rdatatype_nsec3) 20356 { 20357 return ISC_R_SUCCESS; 20358 } 20359 20360 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) || 20361 rdata->type == dns_rdatatype_nsec3) 20362 { 20363 level = ISC_LOG_ERROR; 20364 fail = true; 20365 } 20366 20367 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, true); 20368 if (!ok) { 20369 dns_name_format(name, namebuf, sizeof(namebuf)); 20370 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 20371 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf, 20372 isc_result_totext(DNS_R_BADOWNERNAME)); 20373 if (fail) { 20374 return DNS_R_BADOWNERNAME; 20375 } 20376 } 20377 20378 dns_name_init(&bad, NULL); 20379 ok = dns_rdata_checknames(rdata, name, &bad); 20380 if (!ok) { 20381 dns_name_format(name, namebuf, sizeof(namebuf)); 20382 dns_name_format(&bad, namebuf2, sizeof(namebuf2)); 20383 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 20384 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf, 20385 namebuf2, isc_result_totext(DNS_R_BADNAME)); 20386 if (fail) { 20387 return DNS_R_BADNAME; 20388 } 20389 } 20390 20391 return ISC_R_SUCCESS; 20392 } 20393 20394 void 20395 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) { 20396 REQUIRE(DNS_ZONE_VALID(zone)); 20397 zone->checkmx = checkmx; 20398 } 20399 20400 void 20401 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) { 20402 REQUIRE(DNS_ZONE_VALID(zone)); 20403 zone->checksrv = checksrv; 20404 } 20405 20406 void 20407 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) { 20408 REQUIRE(DNS_ZONE_VALID(zone)); 20409 zone->checkns = checkns; 20410 } 20411 20412 void 20413 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) { 20414 REQUIRE(DNS_ZONE_VALID(zone)); 20415 20416 LOCK_ZONE(zone); 20417 zone->isself = isself; 20418 zone->isselfarg = arg; 20419 UNLOCK_ZONE(zone); 20420 } 20421 20422 void 20423 dns_zone_setnotifydefer(dns_zone_t *zone, uint32_t defer) { 20424 REQUIRE(DNS_ZONE_VALID(zone)); 20425 20426 LOCK_ZONE(zone); 20427 zone->notifydefer = defer; 20428 UNLOCK_ZONE(zone); 20429 } 20430 20431 void 20432 dns_zone_setnotifydelay(dns_zone_t *zone, uint32_t delay) { 20433 REQUIRE(DNS_ZONE_VALID(zone)); 20434 20435 LOCK_ZONE(zone); 20436 zone->notifydelay = delay; 20437 UNLOCK_ZONE(zone); 20438 } 20439 20440 /* 20441 * Called when a dynamic update for an NSEC3PARAM record is received. 20442 * 20443 * If set, transform the NSEC3 salt into human-readable form so that it can be 20444 * logged. Then call zone_addnsec3chain(), passing NSEC3PARAM RDATA to it. 20445 */ 20446 isc_result_t 20447 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 20448 isc_result_t result; 20449 char salt[255 * 2 + 1]; 20450 20451 REQUIRE(DNS_ZONE_VALID(zone)); 20452 20453 result = dns_nsec3param_salttotext(nsec3param, salt, sizeof(salt)); 20454 RUNTIME_CHECK(result == ISC_R_SUCCESS); 20455 dnssec_log(zone, ISC_LOG_NOTICE, 20456 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)", 20457 nsec3param->hash, nsec3param->iterations, salt); 20458 LOCK_ZONE(zone); 20459 result = zone_addnsec3chain(zone, nsec3param); 20460 UNLOCK_ZONE(zone); 20461 20462 return result; 20463 } 20464 20465 void 20466 dns_zone_setnodes(dns_zone_t *zone, uint32_t nodes) { 20467 REQUIRE(DNS_ZONE_VALID(zone)); 20468 20469 if (nodes == 0) { 20470 nodes = 1; 20471 } 20472 zone->nodes = nodes; 20473 } 20474 20475 void 20476 dns_zone_setsignatures(dns_zone_t *zone, uint32_t signatures) { 20477 REQUIRE(DNS_ZONE_VALID(zone)); 20478 20479 /* 20480 * We treat signatures as a signed value so explicitly 20481 * limit its range here. 20482 */ 20483 if (signatures > INT32_MAX) { 20484 signatures = INT32_MAX; 20485 } else if (signatures == 0) { 20486 signatures = 1; 20487 } 20488 zone->signatures = signatures; 20489 } 20490 20491 uint32_t 20492 dns_zone_getsignatures(dns_zone_t *zone) { 20493 REQUIRE(DNS_ZONE_VALID(zone)); 20494 return zone->signatures; 20495 } 20496 20497 void 20498 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) { 20499 REQUIRE(DNS_ZONE_VALID(zone)); 20500 zone->privatetype = type; 20501 } 20502 20503 dns_rdatatype_t 20504 dns_zone_getprivatetype(dns_zone_t *zone) { 20505 REQUIRE(DNS_ZONE_VALID(zone)); 20506 return zone->privatetype; 20507 } 20508 20509 static isc_result_t 20510 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid, 20511 bool deleteit, bool fullsign) { 20512 dns_signing_t *signing; 20513 dns_signing_t *current; 20514 isc_result_t result = ISC_R_SUCCESS; 20515 isc_time_t now; 20516 dns_db_t *db = NULL; 20517 20518 signing = isc_mem_get(zone->mctx, sizeof *signing); 20519 20520 signing->magic = 0; 20521 signing->db = NULL; 20522 signing->dbiterator = NULL; 20523 signing->algorithm = algorithm; 20524 signing->keyid = keyid; 20525 signing->deleteit = deleteit; 20526 signing->fullsign = fullsign; 20527 signing->done = false; 20528 20529 now = isc_time_now(); 20530 20531 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 20532 if (zone->db != NULL) { 20533 dns_db_attach(zone->db, &db); 20534 } 20535 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 20536 20537 if (db == NULL) { 20538 result = ISC_R_NOTFOUND; 20539 goto cleanup; 20540 } 20541 20542 dns_db_attach(db, &signing->db); 20543 20544 for (current = ISC_LIST_HEAD(zone->signing); current != NULL; 20545 current = ISC_LIST_NEXT(current, link)) 20546 { 20547 if (current->db == signing->db && 20548 current->algorithm == signing->algorithm && 20549 current->keyid == signing->keyid) 20550 { 20551 if (current->deleteit != signing->deleteit) { 20552 current->done = true; 20553 } else { 20554 goto cleanup; 20555 } 20556 } 20557 } 20558 20559 result = dns_db_createiterator(signing->db, 0, &signing->dbiterator); 20560 20561 if (result == ISC_R_SUCCESS) { 20562 result = dns_dbiterator_first(signing->dbiterator); 20563 } 20564 if (result == ISC_R_SUCCESS) { 20565 dns_dbiterator_pause(signing->dbiterator); 20566 ISC_LIST_INITANDAPPEND(zone->signing, signing, link); 20567 signing = NULL; 20568 if (isc_time_isepoch(&zone->signingtime)) { 20569 zone->signingtime = now; 20570 if (zone->loop != NULL) { 20571 zone_settimer(zone, &now); 20572 } 20573 } 20574 } 20575 20576 cleanup: 20577 if (signing != NULL) { 20578 if (signing->db != NULL) { 20579 dns_db_detach(&signing->db); 20580 } 20581 if (signing->dbiterator != NULL) { 20582 dns_dbiterator_destroy(&signing->dbiterator); 20583 } 20584 isc_mem_put(zone->mctx, signing, sizeof *signing); 20585 } 20586 if (db != NULL) { 20587 dns_db_detach(&db); 20588 } 20589 return result; 20590 } 20591 20592 /* Called once; *timep should be set to the current time. */ 20593 static isc_result_t 20594 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) { 20595 isc_result_t result; 20596 isc_stdtime_t now, then = 0, event; 20597 int i; 20598 20599 now = *timep; 20600 20601 for (i = 0; i < DST_MAX_TIMES; i++) { 20602 result = dst_key_gettime(key, i, &event); 20603 if (result == ISC_R_SUCCESS && event > now && 20604 (then == 0 || event < then)) 20605 { 20606 then = event; 20607 } 20608 } 20609 20610 if (then != 0) { 20611 *timep = then; 20612 return ISC_R_SUCCESS; 20613 } 20614 20615 return ISC_R_NOTFOUND; 20616 } 20617 20618 static isc_result_t 20619 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 20620 const dns_rdata_t *rdata, bool *flag) { 20621 dns_rdataset_t rdataset; 20622 dns_dbnode_t *node = NULL; 20623 isc_result_t result; 20624 20625 dns_rdataset_init(&rdataset); 20626 if (rdata->type == dns_rdatatype_nsec3) { 20627 CHECK(dns_db_findnsec3node(db, name, false, &node)); 20628 } else { 20629 CHECK(dns_db_findnode(db, name, false, &node)); 20630 } 20631 result = dns_db_findrdataset(db, node, ver, rdata->type, 0, 20632 (isc_stdtime_t)0, &rdataset, NULL); 20633 if (result == ISC_R_NOTFOUND) { 20634 *flag = false; 20635 result = ISC_R_SUCCESS; 20636 goto cleanup; 20637 } 20638 20639 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 20640 result = dns_rdataset_next(&rdataset)) 20641 { 20642 dns_rdata_t myrdata = DNS_RDATA_INIT; 20643 dns_rdataset_current(&rdataset, &myrdata); 20644 if (!dns_rdata_compare(&myrdata, rdata)) { 20645 break; 20646 } 20647 } 20648 dns_rdataset_disassociate(&rdataset); 20649 if (result == ISC_R_SUCCESS) { 20650 *flag = true; 20651 } else if (result == ISC_R_NOMORE) { 20652 *flag = false; 20653 result = ISC_R_SUCCESS; 20654 } 20655 20656 cleanup: 20657 if (node != NULL) { 20658 dns_db_detachnode(db, &node); 20659 } 20660 return result; 20661 } 20662 20663 /* 20664 * Add records to signal the state of signing or of key removal. 20665 */ 20666 static isc_result_t 20667 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, 20668 dns_dbversion_t *ver, dns_diff_t *diff, bool sign_all) { 20669 dns_difftuple_t *tuple = NULL, *newtuple = NULL, *next = NULL; 20670 dns_difftuple_t *addtuple = NULL, *deltuple = NULL; 20671 dns_rdata_dnskey_t dnskey; 20672 dns_rdata_t rdata = DNS_RDATA_INIT; 20673 bool flag; 20674 isc_region_t r; 20675 isc_result_t result = ISC_R_SUCCESS; 20676 uint16_t keyid; 20677 unsigned char buf[5]; 20678 dns_name_t *name = dns_db_origin(db); 20679 dns_difftuplelist_t add = ISC_LIST_INITIALIZER; 20680 dns_difftuplelist_t del = ISC_LIST_INITIALIZER; 20681 dns_difftuplelist_t tuples = ISC_LIST_INITIALIZER; 20682 20683 /* 20684 * Move non DNSKEY and not DNSSEC DNSKEY records to tuples 20685 * and sort the remaining DNSKEY records to add and del. 20686 */ 20687 for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; 20688 tuple = ISC_LIST_HEAD(diff->tuples)) 20689 { 20690 if (tuple->rdata.type != dns_rdatatype_dnskey) { 20691 ISC_LIST_UNLINK(diff->tuples, tuple, link); 20692 ISC_LIST_APPEND(tuples, tuple, link); 20693 continue; 20694 } 20695 20696 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL); 20697 RUNTIME_CHECK(result == ISC_R_SUCCESS); 20698 if ((dnskey.flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) 20699 { 20700 ISC_LIST_UNLINK(diff->tuples, tuple, link); 20701 ISC_LIST_APPEND(tuples, tuple, link); 20702 continue; 20703 } 20704 20705 ISC_LIST_UNLINK(diff->tuples, tuple, link); 20706 switch (tuple->op) { 20707 case DNS_DIFFOP_DEL: 20708 case DNS_DIFFOP_DELRESIGN: 20709 ISC_LIST_APPEND(del, tuple, link); 20710 break; 20711 case DNS_DIFFOP_ADD: 20712 case DNS_DIFFOP_ADDRESIGN: 20713 ISC_LIST_APPEND(add, tuple, link); 20714 break; 20715 default: 20716 UNREACHABLE(); 20717 } 20718 } 20719 20720 /* 20721 * Put the tuples that don't need more processing back onto 20722 * diff->tuples. 20723 */ 20724 ISC_LIST_APPENDLIST(diff->tuples, tuples, link); 20725 20726 /* 20727 * Filter out DNSKEY TTL changes and put them back onto diff->tuples. 20728 */ 20729 for (deltuple = ISC_LIST_HEAD(del); deltuple != NULL; deltuple = next) { 20730 next = ISC_LIST_NEXT(deltuple, link); 20731 for (addtuple = ISC_LIST_HEAD(add); addtuple != NULL; 20732 addtuple = ISC_LIST_NEXT(addtuple, link)) 20733 { 20734 int n = dns_rdata_compare(&deltuple->rdata, 20735 &addtuple->rdata); 20736 if (n == 0) { 20737 ISC_LIST_UNLINK(del, deltuple, link); 20738 ISC_LIST_APPEND(diff->tuples, deltuple, link); 20739 ISC_LIST_UNLINK(add, addtuple, link); 20740 ISC_LIST_APPEND(diff->tuples, addtuple, link); 20741 break; 20742 } 20743 } 20744 } 20745 20746 /* 20747 * Combine any remaining DNSKEY changes together. 20748 */ 20749 ISC_LIST_APPENDLIST(tuples, add, link); 20750 ISC_LIST_APPENDLIST(tuples, del, link); 20751 20752 /* 20753 * Add private records for keys that have been removed 20754 * or added. 20755 */ 20756 for (tuple = ISC_LIST_HEAD(tuples); tuple != NULL; 20757 tuple = ISC_LIST_NEXT(tuple, link)) 20758 { 20759 dns_rdata_toregion(&tuple->rdata, &r); 20760 20761 keyid = dst_region_computeid(&r); 20762 20763 buf[0] = dnskey.algorithm; 20764 buf[1] = (keyid & 0xff00) >> 8; 20765 buf[2] = (keyid & 0xff); 20766 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1; 20767 buf[4] = 0; 20768 rdata.data = buf; 20769 rdata.length = sizeof(buf); 20770 rdata.type = privatetype; 20771 rdata.rdclass = tuple->rdata.rdclass; 20772 20773 if (sign_all || tuple->op == DNS_DIFFOP_DEL) { 20774 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 20775 if (flag) { 20776 continue; 20777 } 20778 20779 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, 20780 name, 0, &rdata, &newtuple)); 20781 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 20782 INSIST(newtuple == NULL); 20783 } 20784 20785 /* 20786 * Remove any record which says this operation has already 20787 * completed. 20788 */ 20789 buf[4] = 1; 20790 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 20791 if (flag) { 20792 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, 20793 name, 0, &rdata, &newtuple)); 20794 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 20795 INSIST(newtuple == NULL); 20796 } 20797 } 20798 20799 cleanup: 20800 /* 20801 * Put the DNSKEY changes we cared about back on diff->tuples. 20802 */ 20803 ISC_LIST_APPENDLIST(diff->tuples, tuples, link); 20804 INSIST(ISC_LIST_EMPTY(add)); 20805 INSIST(ISC_LIST_EMPTY(del)); 20806 INSIST(ISC_LIST_EMPTY(tuples)); 20807 return result; 20808 } 20809 20810 /* 20811 * See if dns__zone_updatesigs() will update signature for RRset 'rrtype' at 20812 * the apex, and if not tickle them and cause to sign so that newly activated 20813 * keys are used. 20814 */ 20815 static isc_result_t 20816 tickle_apex_rrset(dns_rdatatype_t rrtype, dns_zone_t *zone, dns_db_t *db, 20817 dns_dbversion_t *ver, isc_stdtime_t now, dns_diff_t *diff, 20818 dns__zonediff_t *zonediff, dst_key_t **keys, 20819 unsigned int nkeys, isc_stdtime_t inception, 20820 isc_stdtime_t keyexpire) { 20821 dns_difftuple_t *tuple; 20822 isc_result_t result; 20823 20824 for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; 20825 tuple = ISC_LIST_NEXT(tuple, link)) 20826 { 20827 if (tuple->rdata.type == rrtype && 20828 dns_name_equal(&tuple->name, &zone->origin)) 20829 { 20830 break; 20831 } 20832 } 20833 20834 if (tuple == NULL) { 20835 result = del_sigs(zone, db, ver, &zone->origin, rrtype, 20836 zonediff, keys, nkeys, now, false); 20837 if (result != ISC_R_SUCCESS) { 20838 dnssec_log(zone, ISC_LOG_ERROR, 20839 "sign_apex:del_sigs -> %s", 20840 isc_result_totext(result)); 20841 return result; 20842 } 20843 result = add_sigs(db, ver, &zone->origin, zone, rrtype, 20844 zonediff->diff, keys, nkeys, zone->mctx, now, 20845 inception, keyexpire); 20846 if (result != ISC_R_SUCCESS) { 20847 dnssec_log(zone, ISC_LOG_ERROR, 20848 "sign_apex:add_sigs -> %s", 20849 isc_result_totext(result)); 20850 return result; 20851 } 20852 } 20853 20854 return ISC_R_SUCCESS; 20855 } 20856 20857 static isc_result_t 20858 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 20859 isc_stdtime_t now, dns_diff_t *diff, dns__zonediff_t *zonediff) { 20860 isc_result_t result; 20861 isc_stdtime_t inception, soaexpire, keyexpire; 20862 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 20863 unsigned int nkeys = 0, i; 20864 20865 result = dns_zone_findkeys(zone, db, ver, now, zone->mctx, 20866 DNS_MAXZONEKEYS, zone_keys, &nkeys); 20867 if (result != ISC_R_SUCCESS) { 20868 dnssec_log(zone, ISC_LOG_ERROR, 20869 "sign_apex:dns_zone_findkeys -> %s", 20870 isc_result_totext(result)); 20871 return result; 20872 } 20873 20874 inception = now - 3600; /* Allow for clock skew. */ 20875 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 20876 20877 keyexpire = dns_zone_getkeyvalidityinterval(zone); 20878 if (keyexpire == 0) { 20879 keyexpire = soaexpire - 1; 20880 } else { 20881 keyexpire += now; 20882 } 20883 20884 /* 20885 * See if dns__zone_updatesigs() will update DNSKEY/CDS/CDNSKEY 20886 * signature and if not cause them to sign so that newly activated 20887 * keys are used. 20888 */ 20889 CHECK(tickle_apex_rrset(dns_rdatatype_dnskey, zone, db, ver, now, diff, 20890 zonediff, zone_keys, nkeys, inception, 20891 keyexpire)); 20892 CHECK(tickle_apex_rrset(dns_rdatatype_cds, zone, db, ver, now, diff, 20893 zonediff, zone_keys, nkeys, inception, 20894 keyexpire)); 20895 CHECK(tickle_apex_rrset(dns_rdatatype_cdnskey, zone, db, ver, now, diff, 20896 zonediff, zone_keys, nkeys, inception, 20897 keyexpire)); 20898 20899 result = dns__zone_updatesigs(diff, db, ver, zone_keys, nkeys, zone, 20900 inception, soaexpire, keyexpire, now, 20901 zonediff); 20902 if (result != ISC_R_SUCCESS) { 20903 dnssec_log(zone, ISC_LOG_ERROR, 20904 "sign_apex:dns__zone_updatesigs -> %s", 20905 isc_result_totext(result)); 20906 } 20907 20908 cleanup: 20909 for (i = 0; i < nkeys; i++) { 20910 dst_key_free(&zone_keys[i]); 20911 } 20912 return result; 20913 } 20914 20915 static isc_result_t 20916 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 20917 dns_diff_t *diff) { 20918 isc_result_t result; 20919 dns_dbnode_t *node = NULL; 20920 dns_rdataset_t rdataset; 20921 20922 dns_rdataset_init(&rdataset); 20923 CHECK(dns_db_getoriginnode(db, &node)); 20924 20925 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 20926 dns_rdatatype_none, 0, &rdataset, NULL); 20927 if (dns_rdataset_isassociated(&rdataset)) { 20928 dns_rdataset_disassociate(&rdataset); 20929 } 20930 if (result != ISC_R_NOTFOUND) { 20931 goto cleanup; 20932 } 20933 20934 result = dns_nsec3param_deletechains(db, ver, zone, true, diff); 20935 20936 cleanup: 20937 if (node != NULL) { 20938 dns_db_detachnode(db, &node); 20939 } 20940 return result; 20941 } 20942 20943 /* 20944 * Given an RRSIG rdataset and an algorithm, determine whether there 20945 * are any signatures using that algorithm. 20946 */ 20947 static bool 20948 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) { 20949 dns_rdata_t rdata = DNS_RDATA_INIT; 20950 dns_rdata_rrsig_t rrsig; 20951 isc_result_t result; 20952 20953 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig); 20954 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) { 20955 return false; 20956 } 20957 20958 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 20959 result = dns_rdataset_next(rdataset)) 20960 { 20961 dns_rdataset_current(rdataset, &rdata); 20962 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 20963 RUNTIME_CHECK(result == ISC_R_SUCCESS); 20964 dns_rdata_reset(&rdata); 20965 if (rrsig.algorithm == alg) { 20966 return true; 20967 } 20968 } 20969 20970 return false; 20971 } 20972 20973 static isc_result_t 20974 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 20975 dns_diff_t *diff) { 20976 dns_name_t *origin; 20977 bool build_nsec3; 20978 isc_result_t result; 20979 20980 origin = dns_db_origin(db); 20981 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL, 20982 &build_nsec3)); 20983 if (build_nsec3) { 20984 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone_nsecttl(zone), 20985 false, zone->privatetype, diff)); 20986 } 20987 CHECK(updatesecure(db, ver, origin, zone_nsecttl(zone), true, diff)); 20988 20989 cleanup: 20990 return result; 20991 } 20992 20993 static void 20994 dnssec_report(const char *format, ...) { 20995 va_list args; 20996 va_start(args, format); 20997 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_ZONE, 20998 ISC_LOG_INFO, format, args); 20999 va_end(args); 21000 } 21001 21002 static void 21003 checkds_destroy(dns_checkds_t *checkds, bool locked) { 21004 REQUIRE(DNS_CHECKDS_VALID(checkds)); 21005 21006 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21007 "checkds: destroy DS query"); 21008 21009 if (checkds->zone != NULL) { 21010 if (!locked) { 21011 LOCK_ZONE(checkds->zone); 21012 } 21013 REQUIRE(LOCKED_ZONE(checkds->zone)); 21014 if (ISC_LINK_LINKED(checkds, link)) { 21015 ISC_LIST_UNLINK(checkds->zone->checkds_requests, 21016 checkds, link); 21017 } 21018 if (!locked) { 21019 UNLOCK_ZONE(checkds->zone); 21020 } 21021 if (locked) { 21022 zone_idetach(&checkds->zone); 21023 } else { 21024 dns_zone_idetach(&checkds->zone); 21025 } 21026 } 21027 if (checkds->find != NULL) { 21028 dns_adb_destroyfind(&checkds->find); 21029 } 21030 if (checkds->request != NULL) { 21031 dns_request_destroy(&checkds->request); 21032 } 21033 if (dns_name_dynamic(&checkds->ns)) { 21034 dns_name_free(&checkds->ns, checkds->mctx); 21035 } 21036 if (checkds->key != NULL) { 21037 dns_tsigkey_detach(&checkds->key); 21038 } 21039 if (checkds->transport != NULL) { 21040 dns_transport_detach(&checkds->transport); 21041 } 21042 INSIST(checkds->rlevent == NULL); 21043 isc_mem_putanddetach(&checkds->mctx, checkds, sizeof(*checkds)); 21044 } 21045 21046 static isc_result_t 21047 make_dnskey(dst_key_t *key, unsigned char *buf, int bufsize, 21048 dns_rdata_t *target) { 21049 isc_result_t result; 21050 isc_buffer_t b; 21051 isc_region_t r; 21052 21053 isc_buffer_init(&b, buf, bufsize); 21054 result = dst_key_todns(key, &b); 21055 if (result != ISC_R_SUCCESS) { 21056 return result; 21057 } 21058 21059 dns_rdata_reset(target); 21060 isc_buffer_usedregion(&b, &r); 21061 dns_rdata_fromregion(target, dst_key_class(key), dns_rdatatype_dnskey, 21062 &r); 21063 return ISC_R_SUCCESS; 21064 } 21065 21066 static bool 21067 do_checkds(dns_zone_t *zone, dst_key_t *key, isc_stdtime_t now, 21068 bool dspublish) { 21069 dns_kasp_t *kasp = zone->kasp; 21070 isc_result_t result; 21071 uint32_t count = 0; 21072 uint32_t num; 21073 21074 switch (zone->checkdstype) { 21075 case dns_checkdstype_yes: 21076 num = zone->parent_nscount; 21077 break; 21078 case dns_checkdstype_explicit: 21079 num = dns_remote_count(&zone->parentals); 21080 break; 21081 case dns_checkdstype_no: 21082 default: 21083 dns_zone_log(zone, ISC_LOG_WARNING, 21084 "checkds: option is disabled"); 21085 return false; 21086 } 21087 21088 if (dspublish) { 21089 (void)dst_key_getnum(key, DST_NUM_DSPUBCOUNT, &count); 21090 count += 1; 21091 dst_key_setnum(key, DST_NUM_DSPUBCOUNT, count); 21092 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21093 "checkds: %u DS published " 21094 "for key %u", 21095 count, dst_key_id(key)); 21096 21097 if (count != num) { 21098 return false; 21099 } 21100 } else { 21101 (void)dst_key_getnum(key, DST_NUM_DSDELCOUNT, &count); 21102 count += 1; 21103 dst_key_setnum(key, DST_NUM_DSDELCOUNT, count); 21104 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21105 "checkds: %u DS withdrawn " 21106 "for key %u", 21107 count, dst_key_id(key)); 21108 21109 if (count != num) { 21110 return false; 21111 } 21112 } 21113 21114 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21115 "checkds: checkds %s for key " 21116 "%u", 21117 dspublish ? "published" : "withdrawn", dst_key_id(key)); 21118 21119 dns_zone_lock_keyfiles(zone); 21120 result = dns_keymgr_checkds_id(kasp, &zone->checkds_ok, now, now, 21121 dspublish, dst_key_id(key), 21122 dst_key_alg(key)); 21123 dns_zone_unlock_keyfiles(zone); 21124 21125 if (result != ISC_R_SUCCESS) { 21126 dns_zone_log(zone, ISC_LOG_WARNING, 21127 "checkds: checkds for key %u failed: %s", 21128 dst_key_id(key), isc_result_totext(result)); 21129 return false; 21130 } 21131 21132 return true; 21133 } 21134 21135 static isc_result_t 21136 validate_ds(dns_zone_t *zone, dns_message_t *message) { 21137 UNUSED(zone); 21138 UNUSED(message); 21139 21140 /* Get closest trust anchor */ 21141 21142 /* Check that trust anchor is (grand)parent of zone. */ 21143 21144 /* Find the DNSKEY signing the message. */ 21145 21146 /* Check that DNSKEY is in chain of trust. */ 21147 21148 /* Validate DS RRset. */ 21149 21150 return ISC_R_SUCCESS; 21151 } 21152 21153 static void 21154 checkds_done(void *arg) { 21155 dns_request_t *request = (dns_request_t *)arg; 21156 dns_checkds_t *checkds = dns_request_getarg(request); 21157 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 21158 char rcode[128]; 21159 dns_zone_t *zone = NULL; 21160 dns_db_t *db = NULL; 21161 dns_dbversion_t *version = NULL; 21162 dns_dnsseckey_t *key = NULL; 21163 dns_dnsseckeylist_t keys; 21164 dns_kasp_t *kasp = NULL; 21165 dns_message_t *message = NULL; 21166 dns_rdataset_t *ds_rrset = NULL; 21167 isc_buffer_t buf; 21168 isc_result_t result; 21169 isc_stdtime_t now; 21170 isc_time_t timenow; 21171 bool rekey = false; 21172 bool empty = false; 21173 21174 REQUIRE(DNS_CHECKDS_VALID(checkds)); 21175 21176 zone = checkds->zone; 21177 21178 ISC_LIST_INIT(keys); 21179 21180 kasp = zone->kasp; 21181 INSIST(kasp != NULL); 21182 21183 isc_buffer_init(&buf, rcode, sizeof(rcode)); 21184 isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf)); 21185 21186 dns_zone_log(zone, ISC_LOG_DEBUG(1), "checkds: DS query to %s: done", 21187 addrbuf); 21188 21189 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, 21190 &message); 21191 INSIST(message != NULL); 21192 21193 CHECK(dns_request_getresult(request)); 21194 CHECK(dns_request_getresponse(request, message, 21195 DNS_MESSAGEPARSE_PRESERVEORDER)); 21196 CHECK(dns_rcode_totext(message->rcode, &buf)); 21197 21198 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21199 "checkds: DS response from %s: %.*s", addrbuf, 21200 (int)buf.used, rcode); 21201 21202 /* Validate response. */ 21203 CHECK(validate_ds(zone, message)); 21204 21205 /* Check RCODE. */ 21206 if (message->rcode != dns_rcode_noerror) { 21207 dns_zone_log(zone, ISC_LOG_NOTICE, 21208 "checkds: bad DS response from %s: %.*s", addrbuf, 21209 (int)buf.used, rcode); 21210 goto cleanup; 21211 } 21212 21213 /* Make sure that either AA or RA bit is set. */ 21214 if ((message->flags & DNS_MESSAGEFLAG_AA) == 0 && 21215 (message->flags & DNS_MESSAGEFLAG_RA) == 0) 21216 { 21217 dns_zone_log(zone, ISC_LOG_NOTICE, 21218 "checkds: bad DS response from %s: expected AA or " 21219 "RA bit set", 21220 addrbuf); 21221 goto cleanup; 21222 } 21223 21224 /* Lookup DS RRset. */ 21225 result = dns_message_firstname(message, DNS_SECTION_ANSWER); 21226 while (result == ISC_R_SUCCESS) { 21227 dns_name_t *name = NULL; 21228 dns_rdataset_t *rdataset; 21229 21230 dns_message_currentname(message, DNS_SECTION_ANSWER, &name); 21231 if (dns_name_compare(&zone->origin, name) != 0) { 21232 goto next; 21233 } 21234 21235 for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; 21236 rdataset = ISC_LIST_NEXT(rdataset, link)) 21237 { 21238 if (rdataset->type != dns_rdatatype_ds) { 21239 goto next; 21240 } 21241 21242 ds_rrset = rdataset; 21243 break; 21244 } 21245 21246 if (ds_rrset != NULL) { 21247 break; 21248 } 21249 21250 next: 21251 result = dns_message_nextname(message, DNS_SECTION_ANSWER); 21252 } 21253 21254 if (ds_rrset == NULL) { 21255 empty = true; 21256 dns_zone_log(zone, ISC_LOG_NOTICE, 21257 "checkds: empty DS response from %s", addrbuf); 21258 } 21259 21260 timenow = isc_time_now(); 21261 now = isc_time_seconds(&timenow); 21262 21263 CHECK(dns_zone_getdb(zone, &db)); 21264 dns_db_currentversion(db, &version); 21265 21266 KASP_LOCK(kasp); 21267 LOCK_ZONE(zone); 21268 for (key = ISC_LIST_HEAD(zone->checkds_ok); key != NULL; 21269 key = ISC_LIST_NEXT(key, link)) 21270 { 21271 bool alldone = false, found = false; 21272 bool checkdspub = false, checkdsdel = false, ksk = false; 21273 dst_key_state_t ds_state = DST_KEY_STATE_NA; 21274 isc_stdtime_t published = 0, withdrawn = 0; 21275 isc_result_t ret = ISC_R_SUCCESS; 21276 21277 /* Is this key have the KSK role? */ 21278 (void)dst_key_role(key->key, &ksk, NULL); 21279 if (!ksk) { 21280 continue; 21281 } 21282 21283 /* Do we need to check the DS RRset for this key? */ 21284 (void)dst_key_getstate(key->key, DST_KEY_DS, &ds_state); 21285 (void)dst_key_gettime(key->key, DST_TIME_DSPUBLISH, &published); 21286 (void)dst_key_gettime(key->key, DST_TIME_DSDELETE, &withdrawn); 21287 21288 if (ds_state == DST_KEY_STATE_RUMOURED && published == 0) { 21289 checkdspub = true; 21290 } else if (ds_state == DST_KEY_STATE_UNRETENTIVE && 21291 withdrawn == 0) 21292 { 21293 checkdsdel = true; 21294 } 21295 if (!checkdspub && !checkdsdel) { 21296 continue; 21297 } 21298 21299 if (empty) { 21300 goto dswithdrawn; 21301 } 21302 21303 /* Find the appropriate DS record. */ 21304 ret = dns_rdataset_first(ds_rrset); 21305 while (ret == ISC_R_SUCCESS) { 21306 dns_rdata_ds_t ds; 21307 dns_rdata_t dnskey = DNS_RDATA_INIT; 21308 dns_rdata_t dsrdata = DNS_RDATA_INIT; 21309 dns_rdata_t rdata = DNS_RDATA_INIT; 21310 isc_result_t r; 21311 unsigned char dsbuf[DNS_DS_BUFFERSIZE]; 21312 unsigned char keybuf[DST_KEY_MAXSIZE]; 21313 21314 dns_rdataset_current(ds_rrset, &rdata); 21315 r = dns_rdata_tostruct(&rdata, &ds, NULL); 21316 if (r != ISC_R_SUCCESS) { 21317 goto nextds; 21318 } 21319 /* Check key tag and algorithm. */ 21320 if (dst_key_id(key->key) != ds.key_tag) { 21321 goto nextds; 21322 } 21323 if (dst_key_alg(key->key) != ds.algorithm) { 21324 goto nextds; 21325 } 21326 /* Derive DS from DNSKEY, see if the rdata is equal. */ 21327 make_dnskey(key->key, keybuf, sizeof(keybuf), &dnskey); 21328 r = dns_ds_buildrdata(&zone->origin, &dnskey, 21329 ds.digest_type, dsbuf, &dsrdata); 21330 if (r != ISC_R_SUCCESS) { 21331 goto nextds; 21332 } 21333 if (dns_rdata_compare(&rdata, &dsrdata) == 0) { 21334 found = true; 21335 if (checkdspub) { 21336 /* DS Published. */ 21337 alldone = do_checkds(zone, key->key, 21338 now, true); 21339 if (alldone) { 21340 rekey = true; 21341 } 21342 } 21343 } 21344 21345 nextds: 21346 ret = dns_rdataset_next(ds_rrset); 21347 } 21348 21349 dswithdrawn: 21350 /* DS withdrawn. */ 21351 if (checkdsdel && !found) { 21352 alldone = do_checkds(zone, key->key, now, false); 21353 if (alldone) { 21354 rekey = true; 21355 } 21356 } 21357 } 21358 UNLOCK_ZONE(zone); 21359 KASP_UNLOCK(kasp); 21360 21361 /* Rekey after checkds. */ 21362 if (rekey) { 21363 dns_zone_rekey(zone, false, false); 21364 } 21365 21366 cleanup: 21367 if (result != ISC_R_SUCCESS) { 21368 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21369 "checkds: DS request failed: %s", 21370 isc_result_totext(result)); 21371 } 21372 21373 if (version != NULL) { 21374 dns_db_closeversion(db, &version, false); 21375 } 21376 if (db != NULL) { 21377 dns_db_detach(&db); 21378 } 21379 21380 while (!ISC_LIST_EMPTY(keys)) { 21381 key = ISC_LIST_HEAD(keys); 21382 ISC_LIST_UNLINK(keys, key, link); 21383 dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key); 21384 } 21385 21386 checkds_destroy(checkds, false); 21387 dns_message_detach(&message); 21388 } 21389 21390 static bool 21391 checkds_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr, 21392 dns_tsigkey_t *key, dns_transport_t *transport) { 21393 dns_checkds_t *checkds; 21394 21395 for (checkds = ISC_LIST_HEAD(zone->checkds_requests); checkds != NULL; 21396 checkds = ISC_LIST_NEXT(checkds, link)) 21397 { 21398 if (checkds->request != NULL) { 21399 continue; 21400 } 21401 if (name != NULL && dns_name_equal(name, &checkds->ns)) { 21402 return true; 21403 } 21404 if (addr != NULL && isc_sockaddr_equal(addr, &checkds->dst) && 21405 checkds->key == key && checkds->transport == transport) 21406 { 21407 return true; 21408 } 21409 } 21410 return false; 21411 } 21412 21413 static void 21414 checkds_create(isc_mem_t *mctx, unsigned int flags, dns_checkds_t **checkdsp) { 21415 dns_checkds_t *checkds; 21416 21417 REQUIRE(checkdsp != NULL && *checkdsp == NULL); 21418 21419 checkds = isc_mem_get(mctx, sizeof(*checkds)); 21420 *checkds = (dns_checkds_t){ 21421 .magic = CHECKDS_MAGIC, 21422 .flags = flags, 21423 .link = ISC_LINK_INITIALIZER, 21424 .ns = DNS_NAME_INITEMPTY, 21425 }; 21426 21427 isc_mem_attach(mctx, &checkds->mctx); 21428 21429 isc_sockaddr_any(&checkds->dst); 21430 21431 *checkdsp = checkds; 21432 } 21433 21434 static void 21435 checkds_createmessage(dns_zone_t *zone, dns_message_t **messagep) { 21436 dns_message_t *message = NULL; 21437 21438 dns_name_t *tempname = NULL; 21439 dns_rdataset_t *temprdataset = NULL; 21440 21441 REQUIRE(DNS_ZONE_VALID(zone)); 21442 REQUIRE(messagep != NULL && *messagep == NULL); 21443 21444 dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, 21445 &message); 21446 21447 message->opcode = dns_opcode_query; 21448 message->rdclass = zone->rdclass; 21449 message->flags |= DNS_MESSAGEFLAG_RD; 21450 21451 dns_message_gettempname(message, &tempname); 21452 21453 dns_message_gettemprdataset(message, &temprdataset); 21454 21455 /* 21456 * Make question. 21457 */ 21458 dns_name_init(tempname, NULL); 21459 dns_name_clone(&zone->origin, tempname); 21460 dns_rdataset_makequestion(temprdataset, zone->rdclass, 21461 dns_rdatatype_ds); 21462 ISC_LIST_APPEND(tempname->list, temprdataset, link); 21463 dns_message_addname(message, tempname, DNS_SECTION_QUESTION); 21464 tempname = NULL; 21465 temprdataset = NULL; 21466 21467 *messagep = message; 21468 } 21469 21470 /* 21471 * XXXAG should check for DNS_ZONEFLG_EXITING 21472 */ 21473 static void 21474 process_checkds_adb_event(void *arg) { 21475 dns_adbfind_t *find = (dns_adbfind_t *)arg; 21476 dns_checkds_t *checkds = (dns_checkds_t *)find->cbarg; 21477 dns_adbstatus_t astat = find->status; 21478 21479 REQUIRE(DNS_CHECKDS_VALID(checkds)); 21480 REQUIRE(find == checkds->find); 21481 21482 switch (astat) { 21483 case DNS_ADB_MOREADDRESSES: 21484 dns_adb_destroyfind(&checkds->find); 21485 checkds_find_address(checkds); 21486 return; 21487 21488 case DNS_ADB_NOMOREADDRESSES: 21489 LOCK_ZONE(checkds->zone); 21490 checkds_send_tons(checkds); 21491 UNLOCK_ZONE(checkds->zone); 21492 break; 21493 21494 default: 21495 break; 21496 } 21497 21498 checkds_destroy(checkds, false); 21499 } 21500 21501 static void 21502 checkds_find_address(dns_checkds_t *checkds) { 21503 isc_result_t result; 21504 unsigned int options; 21505 dns_adb_t *adb = NULL; 21506 21507 REQUIRE(DNS_CHECKDS_VALID(checkds)); 21508 21509 options = DNS_ADBFIND_WANTEVENT; 21510 if (isc_net_probeipv4() != ISC_R_DISABLED) { 21511 options |= DNS_ADBFIND_INET; 21512 } 21513 if (isc_net_probeipv6() != ISC_R_DISABLED) { 21514 options |= DNS_ADBFIND_INET6; 21515 } 21516 21517 dns_view_getadb(checkds->zone->view, &adb); 21518 if (adb == NULL) { 21519 goto destroy; 21520 } 21521 21522 result = dns_adb_createfind(adb, checkds->zone->loop, 21523 process_checkds_adb_event, checkds, 21524 &checkds->ns, dns_rootname, 0, options, 0, 21525 NULL, checkds->zone->view->dstport, 0, NULL, 21526 NULL, NULL, &checkds->find); 21527 dns_adb_detach(&adb); 21528 21529 /* Something failed? */ 21530 if (result != ISC_R_SUCCESS) { 21531 goto destroy; 21532 } 21533 21534 /* More addresses pending? */ 21535 if ((checkds->find->options & DNS_ADBFIND_WANTEVENT) != 0) { 21536 return; 21537 } 21538 21539 /* We have as many addresses as we can get. */ 21540 LOCK_ZONE(checkds->zone); 21541 checkds_send_tons(checkds); 21542 UNLOCK_ZONE(checkds->zone); 21543 21544 destroy: 21545 checkds_destroy(checkds, false); 21546 } 21547 21548 static void 21549 checkds_send_toaddr(void *arg) { 21550 dns_checkds_t *checkds = (dns_checkds_t *)arg; 21551 isc_result_t result; 21552 dns_message_t *message = NULL; 21553 isc_netaddr_t dstip; 21554 dns_tsigkey_t *key = NULL; 21555 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 21556 isc_sockaddr_t src; 21557 unsigned int options, timeout; 21558 bool have_checkdssource = false; 21559 bool canceled = checkds->rlevent->canceled; 21560 21561 REQUIRE(DNS_CHECKDS_VALID(checkds)); 21562 21563 isc_rlevent_free(&checkds->rlevent); 21564 21565 LOCK_ZONE(checkds->zone); 21566 21567 if (DNS_ZONE_FLAG(checkds->zone, DNS_ZONEFLG_LOADED) == 0 || canceled || 21568 DNS_ZONE_FLAG(checkds->zone, DNS_ZONEFLG_EXITING) || 21569 checkds->zone->view->requestmgr == NULL || 21570 checkds->zone->db == NULL) 21571 { 21572 result = ISC_R_CANCELED; 21573 goto cleanup; 21574 } 21575 21576 /* 21577 * The raw IPv4 address should also exist. Don't send to the 21578 * mapped form. 21579 */ 21580 if (isc_sockaddr_pf(&checkds->dst) == PF_INET6 && 21581 IN6_IS_ADDR_V4MAPPED(&checkds->dst.type.sin6.sin6_addr)) 21582 { 21583 isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf)); 21584 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21585 "checkds: ignoring IPv6 mapped IPV4 address: %s", 21586 addrbuf); 21587 result = ISC_R_CANCELED; 21588 goto cleanup; 21589 } 21590 21591 checkds_createmessage(checkds->zone, &message); 21592 21593 isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf)); 21594 if (checkds->key != NULL) { 21595 /* Transfer ownership of key */ 21596 key = checkds->key; 21597 checkds->key = NULL; 21598 } else { 21599 isc_netaddr_fromsockaddr(&dstip, &checkds->dst); 21600 result = dns_view_getpeertsig(checkds->zone->view, &dstip, 21601 &key); 21602 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 21603 dns_zone_log(checkds->zone, ISC_LOG_ERROR, 21604 "checkds: DS query to %s not sent. " 21605 "Peer TSIG key lookup failure.", 21606 addrbuf); 21607 goto cleanup_message; 21608 } 21609 } 21610 21611 if (key != NULL) { 21612 char namebuf[DNS_NAME_FORMATSIZE]; 21613 21614 dns_name_format(key->name, namebuf, sizeof(namebuf)); 21615 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21616 "checkds: sending DS query to %s : TSIG (%s)", 21617 addrbuf, namebuf); 21618 } else { 21619 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21620 "checkds: sending DS query to %s", addrbuf); 21621 } 21622 options = 0; 21623 if (checkds->zone->view->peers != NULL) { 21624 dns_peer_t *peer = NULL; 21625 bool usetcp = false; 21626 result = dns_peerlist_peerbyaddr(checkds->zone->view->peers, 21627 &dstip, &peer); 21628 if (result == ISC_R_SUCCESS) { 21629 result = dns_peer_getquerysource(peer, &src); 21630 if (result == ISC_R_SUCCESS) { 21631 have_checkdssource = true; 21632 } 21633 result = dns_peer_getforcetcp(peer, &usetcp); 21634 if (result == ISC_R_SUCCESS && usetcp) { 21635 options |= DNS_FETCHOPT_TCP; 21636 } 21637 } 21638 } 21639 switch (isc_sockaddr_pf(&checkds->dst)) { 21640 case PF_INET: 21641 if (!have_checkdssource) { 21642 isc_sockaddr_t any; 21643 isc_sockaddr_any(&any); 21644 21645 src = checkds->src; 21646 if (isc_sockaddr_equal(&src, &any)) { 21647 src = checkds->zone->parentalsrc4; 21648 } 21649 } 21650 break; 21651 case PF_INET6: 21652 if (!have_checkdssource) { 21653 isc_sockaddr_t any; 21654 isc_sockaddr_any6(&any); 21655 21656 src = checkds->src; 21657 if (isc_sockaddr_equal(&src, &any)) { 21658 src = checkds->zone->parentalsrc6; 21659 } 21660 } 21661 break; 21662 default: 21663 result = ISC_R_NOTIMPLEMENTED; 21664 goto cleanup_key; 21665 } 21666 21667 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21668 "checkds: create request for DS query to %s", addrbuf); 21669 21670 timeout = 5; 21671 options |= DNS_REQUESTOPT_TCP; 21672 result = dns_request_create( 21673 checkds->zone->view->requestmgr, message, &src, &checkds->dst, 21674 NULL, NULL, options, key, timeout * 3 + 1, timeout, 2, 21675 checkds->zone->loop, checkds_done, checkds, &checkds->request); 21676 if (result != ISC_R_SUCCESS) { 21677 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21678 "checkds: dns_request_create() to %s failed: %s", 21679 addrbuf, isc_result_totext(result)); 21680 } 21681 21682 cleanup_key: 21683 if (key != NULL) { 21684 dns_tsigkey_detach(&key); 21685 } 21686 cleanup_message: 21687 dns_message_detach(&message); 21688 cleanup: 21689 UNLOCK_ZONE(checkds->zone); 21690 if (result != ISC_R_SUCCESS) { 21691 checkds_destroy(checkds, false); 21692 } 21693 } 21694 21695 static void 21696 checkds_send_tons(dns_checkds_t *checkds) { 21697 dns_adbaddrinfo_t *ai; 21698 isc_sockaddr_t dst; 21699 isc_result_t result; 21700 dns_checkds_t *newcheckds = NULL; 21701 dns_zone_t *zone = NULL; 21702 21703 /* 21704 * Zone lock held by caller. 21705 */ 21706 REQUIRE(DNS_CHECKDS_VALID(checkds)); 21707 REQUIRE(LOCKED_ZONE(checkds->zone)); 21708 21709 zone = checkds->zone; 21710 21711 if (DNS_ZONE_FLAG(checkds->zone, DNS_ZONEFLG_EXITING)) { 21712 return; 21713 } 21714 21715 for (ai = ISC_LIST_HEAD(checkds->find->list); ai != NULL; 21716 ai = ISC_LIST_NEXT(ai, publink)) 21717 { 21718 dst = ai->sockaddr; 21719 if (checkds_isqueued(zone, NULL, &dst, NULL, NULL)) { 21720 continue; 21721 } 21722 21723 newcheckds = NULL; 21724 checkds_create(checkds->mctx, 0, &newcheckds); 21725 zone_iattach(zone, &newcheckds->zone); 21726 ISC_LIST_APPEND(newcheckds->zone->checkds_requests, newcheckds, 21727 link); 21728 newcheckds->dst = dst; 21729 dns_name_dup(&checkds->ns, checkds->mctx, &newcheckds->ns); 21730 switch (isc_sockaddr_pf(&newcheckds->dst)) { 21731 case PF_INET: 21732 isc_sockaddr_any(&newcheckds->src); 21733 break; 21734 case PF_INET6: 21735 isc_sockaddr_any6(&newcheckds->src); 21736 break; 21737 default: 21738 UNREACHABLE(); 21739 } 21740 /* 21741 * XXXWMM: Should we attach key and transport here? 21742 * Probably not, because we expect the name servers to be 21743 * publicly available on the default transport protocol. 21744 */ 21745 21746 result = isc_ratelimiter_enqueue( 21747 newcheckds->zone->zmgr->checkdsrl, 21748 newcheckds->zone->loop, checkds_send_toaddr, newcheckds, 21749 &newcheckds->rlevent); 21750 if (result != ISC_R_SUCCESS) { 21751 goto cleanup; 21752 } 21753 newcheckds = NULL; 21754 } 21755 21756 cleanup: 21757 if (newcheckds != NULL) { 21758 checkds_destroy(newcheckds, true); 21759 } 21760 } 21761 21762 static void 21763 checkds_send(dns_zone_t *zone) { 21764 dns_view_t *view = dns_zone_getview(zone); 21765 isc_result_t result; 21766 unsigned int flags = 0; 21767 unsigned int i = 0; 21768 21769 /* 21770 * Zone lock held by caller. 21771 */ 21772 REQUIRE(LOCKED_ZONE(zone)); 21773 21774 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21775 "checkds: start sending DS queries to %u parentals", 21776 dns_remote_count(&zone->parentals)); 21777 21778 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 21779 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21780 "checkds: abort, named exiting"); 21781 return; 21782 } 21783 21784 dns_remote_reset(&zone->parentals, false); 21785 while (!dns_remote_done(&zone->parentals)) { 21786 dns_tsigkey_t *key = NULL; 21787 dns_transport_t *transport = NULL; 21788 isc_sockaddr_t src, dst; 21789 dns_checkds_t *checkds = NULL; 21790 21791 i++; 21792 21793 if (dns_remote_keyname(&zone->parentals) != NULL) { 21794 dns_name_t *keyname = 21795 dns_remote_keyname(&zone->parentals); 21796 (void)dns_view_gettsig(view, keyname, &key); 21797 } 21798 21799 if (dns_remote_tlsname(&zone->parentals) != NULL) { 21800 dns_name_t *tlsname = 21801 dns_remote_tlsname(&zone->parentals); 21802 (void)dns_view_gettransport(view, DNS_TRANSPORT_TLS, 21803 tlsname, &transport); 21804 dns_zone_logc( 21805 zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 21806 "got TLS configuration for zone transfer"); 21807 } 21808 21809 dst = dns_remote_curraddr(&zone->parentals); 21810 src = dns_remote_sourceaddr(&zone->parentals); 21811 INSIST(isc_sockaddr_pf(&src) == isc_sockaddr_pf(&dst)); 21812 21813 if (isc_sockaddr_disabled(&dst)) { 21814 if (key != NULL) { 21815 dns_tsigkey_detach(&key); 21816 } 21817 if (transport != NULL) { 21818 dns_transport_detach(&transport); 21819 } 21820 goto next; 21821 } 21822 21823 /* TODO: glue the transport to the checkds request */ 21824 21825 if (checkds_isqueued(zone, NULL, &dst, key, transport)) { 21826 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21827 "checkds: DS query to parent " 21828 "%d is queued", 21829 i); 21830 if (key != NULL) { 21831 dns_tsigkey_detach(&key); 21832 } 21833 if (transport != NULL) { 21834 dns_transport_detach(&transport); 21835 } 21836 goto next; 21837 } 21838 21839 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21840 "checkds: create DS query for " 21841 "parent %d", 21842 i); 21843 21844 checkds_create(zone->mctx, flags, &checkds); 21845 zone_iattach(zone, &checkds->zone); 21846 dns_name_dup(dns_rootname, checkds->mctx, &checkds->ns); 21847 checkds->src = src; 21848 checkds->dst = dst; 21849 21850 INSIST(checkds->key == NULL); 21851 if (key != NULL) { 21852 checkds->key = key; 21853 key = NULL; 21854 } 21855 21856 INSIST(checkds->transport == NULL); 21857 if (transport != NULL) { 21858 checkds->transport = transport; 21859 transport = NULL; 21860 } 21861 21862 ISC_LIST_APPEND(zone->checkds_requests, checkds, link); 21863 result = isc_ratelimiter_enqueue( 21864 checkds->zone->zmgr->checkdsrl, checkds->zone->loop, 21865 checkds_send_toaddr, checkds, &checkds->rlevent); 21866 if (result != ISC_R_SUCCESS) { 21867 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21868 "checkds: send DS query to " 21869 "parent %d failed", 21870 i); 21871 checkds_destroy(checkds, true); 21872 } 21873 21874 next: 21875 dns_remote_next(&zone->parentals, false); 21876 } 21877 } 21878 21879 /* 21880 * An NS RRset has been fetched from the parent of a zone whose DS RRset needs 21881 * to be checked; scan the RRset and start sending queries to the parental 21882 * agents. 21883 */ 21884 static void 21885 nsfetch_done(void *arg) { 21886 dns_fetchresponse_t *resp = (dns_fetchresponse_t *)arg; 21887 isc_result_t result, eresult; 21888 dns_nsfetch_t *nsfetch = NULL; 21889 dns_zone_t *zone = NULL; 21890 isc_mem_t *mctx = NULL; 21891 dns_name_t *zname = NULL; 21892 dns_name_t *pname = NULL; 21893 char pnamebuf[DNS_NAME_FORMATSIZE]; 21894 bool free_needed, levelup = false; 21895 dns_rdataset_t *nsrrset = NULL; 21896 dns_rdataset_t *nssigset = NULL; 21897 21898 INSIST(resp != NULL); 21899 21900 nsfetch = resp->arg; 21901 21902 INSIST(nsfetch != NULL); 21903 21904 zone = nsfetch->zone; 21905 mctx = nsfetch->mctx; 21906 zname = dns_fixedname_name(&nsfetch->name); 21907 pname = &nsfetch->pname; 21908 nsrrset = &nsfetch->nsrrset; 21909 nssigset = &nsfetch->nssigset; 21910 eresult = resp->result; 21911 21912 /* Free resources which are not of interest */ 21913 if (resp->node != NULL) { 21914 dns_db_detachnode(resp->db, &resp->node); 21915 } 21916 if (resp->db != NULL) { 21917 dns_db_detach(&resp->db); 21918 } 21919 dns_resolver_destroyfetch(&nsfetch->fetch); 21920 21921 LOCK_ZONE(zone); 21922 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) { 21923 goto cleanup; 21924 } 21925 21926 zone->nsfetchcount--; 21927 21928 dns_name_format(pname, pnamebuf, sizeof(pnamebuf)); 21929 dnssec_log(zone, ISC_LOG_DEBUG(3), 21930 "Returned from '%s' NS fetch in nsfetch_done(): %s", 21931 pnamebuf, isc_result_totext(eresult)); 21932 21933 if (eresult == DNS_R_NCACHENXRRSET || eresult == DNS_R_NXRRSET) { 21934 dnssec_log(zone, ISC_LOG_DEBUG(3), 21935 "NODATA response for NS '%s', level up", pnamebuf); 21936 levelup = true; 21937 goto cleanup; 21938 21939 } else if (eresult != ISC_R_SUCCESS) { 21940 dnssec_log(zone, ISC_LOG_WARNING, 21941 "Unable to fetch NS set '%s': %s", pnamebuf, 21942 isc_result_totext(eresult)); 21943 result = eresult; 21944 goto done; 21945 } 21946 21947 /* No NS records found */ 21948 if (!dns_rdataset_isassociated(nsrrset)) { 21949 dnssec_log(zone, ISC_LOG_WARNING, 21950 "No NS records found for '%s'", pnamebuf); 21951 result = ISC_R_NOTFOUND; 21952 goto done; 21953 } 21954 21955 /* No RRSIGs found */ 21956 if (!dns_rdataset_isassociated(nssigset)) { 21957 dnssec_log(zone, ISC_LOG_WARNING, "No NS RRSIGs found for '%s'", 21958 pnamebuf); 21959 result = DNS_R_MUSTBESECURE; 21960 goto done; 21961 } 21962 21963 /* Check trust level */ 21964 if (nsrrset->trust < dns_trust_secure) { 21965 dnssec_log(zone, ISC_LOG_WARNING, 21966 "Invalid NS RRset for '%s' trust level %u", pnamebuf, 21967 nsrrset->trust); 21968 result = DNS_R_MUSTBESECURE; 21969 goto done; 21970 } 21971 21972 /* Record the number of NS records we found. */ 21973 zone->parent_nscount = dns_rdataset_count(nsrrset); 21974 21975 UNLOCK_ZONE(zone); 21976 21977 /* Look up the addresses for the found parental name servers. */ 21978 for (result = dns_rdataset_first(nsrrset); result == ISC_R_SUCCESS; 21979 result = dns_rdataset_next(nsrrset)) 21980 { 21981 dns_checkds_t *checkds = NULL; 21982 dns_rdata_t rdata = DNS_RDATA_INIT; 21983 dns_rdata_ns_t ns; 21984 bool isqueued; 21985 21986 dns_rdataset_current(nsrrset, &rdata); 21987 result = dns_rdata_tostruct(&rdata, &ns, NULL); 21988 RUNTIME_CHECK(result == ISC_R_SUCCESS); 21989 21990 dns_rdata_reset(&rdata); 21991 21992 LOCK_ZONE(zone); 21993 isqueued = checkds_isqueued(zone, &ns.name, NULL, NULL, NULL); 21994 UNLOCK_ZONE(zone); 21995 if (isqueued) { 21996 continue; 21997 } 21998 checkds_create(zone->mctx, 0, &checkds); 21999 22000 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 22001 char nsnamebuf[DNS_NAME_FORMATSIZE]; 22002 dns_name_format(&ns.name, nsnamebuf, sizeof(nsnamebuf)); 22003 dns_zone_log(zone, ISC_LOG_DEBUG(3), 22004 "checkds: send DS query to NS %s", 22005 nsnamebuf); 22006 } 22007 22008 LOCK_ZONE(zone); 22009 zone_iattach(zone, &checkds->zone); 22010 dns_name_dup(&ns.name, zone->mctx, &checkds->ns); 22011 ISC_LIST_APPEND(zone->checkds_requests, checkds, link); 22012 UNLOCK_ZONE(zone); 22013 22014 checkds_find_address(checkds); 22015 } 22016 if (result == ISC_R_NOMORE) { 22017 result = ISC_R_SUCCESS; 22018 } 22019 22020 LOCK_ZONE(zone); 22021 22022 done: 22023 if (result != ISC_R_SUCCESS) { 22024 dnssec_log( 22025 zone, ISC_LOG_ERROR, 22026 "checkds: error during parental-agents processing: %s", 22027 isc_result_totext(result)); 22028 } 22029 22030 cleanup: 22031 isc_refcount_decrement(&zone->irefs); 22032 22033 if (dns_rdataset_isassociated(nsrrset)) { 22034 dns_rdataset_disassociate(nsrrset); 22035 } 22036 if (dns_rdataset_isassociated(nssigset)) { 22037 dns_rdataset_disassociate(nssigset); 22038 } 22039 22040 dns_resolver_freefresp(&resp); 22041 22042 if (levelup) { 22043 UNLOCK_ZONE(zone); 22044 nsfetch_levelup(nsfetch); 22045 return; 22046 } 22047 22048 dns_name_free(zname, mctx); 22049 isc_mem_putanddetach(&nsfetch->mctx, nsfetch, sizeof(dns_nsfetch_t)); 22050 22051 free_needed = exit_check(zone); 22052 UNLOCK_ZONE(zone); 22053 22054 if (free_needed) { 22055 zone_free(zone); 22056 } 22057 } 22058 22059 static void 22060 do_nsfetch(void *arg) { 22061 dns_nsfetch_t *nsfetch = (dns_nsfetch_t *)arg; 22062 isc_result_t result; 22063 unsigned int nlabels = 1; 22064 dns_resolver_t *resolver = NULL; 22065 dns_zone_t *zone = nsfetch->zone; 22066 unsigned int options = DNS_FETCHOPT_UNSHARED | DNS_FETCHOPT_NOCACHED; 22067 22068 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 22069 result = ISC_R_SHUTTINGDOWN; 22070 goto cleanup; 22071 } 22072 22073 result = dns_view_getresolver(zone->view, &resolver); 22074 if (result != ISC_R_SUCCESS) { 22075 goto cleanup; 22076 } 22077 22078 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 22079 char namebuf[DNS_NAME_FORMATSIZE]; 22080 dns_name_format(&nsfetch->pname, namebuf, sizeof(namebuf)); 22081 dnssec_log(zone, ISC_LOG_DEBUG(3), 22082 "Create fetch for '%s' NS request", namebuf); 22083 } 22084 22085 /* Derive parent domain. XXXWMM: Check for root domain */ 22086 dns_name_split(&nsfetch->pname, 22087 dns_name_countlabels(&nsfetch->pname) - nlabels, NULL, 22088 &nsfetch->pname); 22089 22090 /* 22091 * Use of DNS_FETCHOPT_NOCACHED is essential here. If it is not 22092 * set and the cache still holds a non-expired, validated version 22093 * of the RRset being queried for by the time the response is 22094 * received, the cached RRset will be passed to nsfetch_done() 22095 * instead of the one received in the response as the latter will 22096 * have a lower trust level due to not being validated until 22097 * nsfetch_done() is called. 22098 */ 22099 result = dns_resolver_createfetch( 22100 resolver, &nsfetch->pname, dns_rdatatype_ns, NULL, NULL, NULL, 22101 NULL, 0, options, 0, NULL, NULL, NULL, zone->loop, nsfetch_done, 22102 nsfetch, NULL, &nsfetch->nsrrset, &nsfetch->nssigset, 22103 &nsfetch->fetch); 22104 22105 dns_resolver_detach(&resolver); 22106 22107 cleanup: 22108 if (result != ISC_R_SUCCESS) { 22109 dns_name_t *zname = dns_fixedname_name(&nsfetch->name); 22110 bool free_needed; 22111 char namebuf[DNS_NAME_FORMATSIZE]; 22112 dns_name_format(&nsfetch->pname, namebuf, sizeof(namebuf)); 22113 dnssec_log(zone, ISC_LOG_WARNING, 22114 "Failed to create fetch for '%s' NS request", 22115 namebuf); 22116 LOCK_ZONE(zone); 22117 zone->nsfetchcount--; 22118 isc_refcount_decrement(&zone->irefs); 22119 22120 dns_name_free(zname, zone->mctx); 22121 isc_mem_putanddetach(&nsfetch->mctx, nsfetch, sizeof(*nsfetch)); 22122 22123 free_needed = exit_check(zone); 22124 UNLOCK_ZONE(zone); 22125 if (free_needed) { 22126 zone_free(zone); 22127 } 22128 } 22129 } 22130 22131 /* 22132 * Retry an NS RRset lookup, one level up. In other words, this function should 22133 * be called on an dns_nsfetch structure where the response yielded in a NODATA 22134 * response. This must be because there is an empty non-terminal inbetween the 22135 * child and parent zone. 22136 */ 22137 static void 22138 nsfetch_levelup(dns_nsfetch_t *nsfetch) { 22139 dns_zone_t *zone = nsfetch->zone; 22140 22141 #ifdef ENABLE_AFL 22142 if (!dns_fuzzing_resolver) { 22143 #endif /* ifdef ENABLE_AFL */ 22144 LOCK_ZONE(zone); 22145 zone->nsfetchcount++; 22146 isc_refcount_increment0(&zone->irefs); 22147 22148 dns_rdataset_init(&nsfetch->nsrrset); 22149 dns_rdataset_init(&nsfetch->nssigset); 22150 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 22151 dnssec_log(zone, ISC_LOG_DEBUG(3), 22152 "Creating parent NS fetch in " 22153 "nsfetch_levelup()"); 22154 } 22155 isc_async_run(zone->loop, do_nsfetch, nsfetch); 22156 UNLOCK_ZONE(zone); 22157 #ifdef ENABLE_AFL 22158 } 22159 #endif /* ifdef ENABLE_AFL */ 22160 } 22161 22162 static void 22163 zone_checkds(dns_zone_t *zone) { 22164 bool cdscheck = false; 22165 dns_checkdstype_t checkdstype = zone->checkdstype; 22166 22167 if (checkdstype == dns_checkdstype_no) { 22168 return; 22169 } 22170 22171 for (dns_dnsseckey_t *key = ISC_LIST_HEAD(zone->checkds_ok); 22172 key != NULL; key = ISC_LIST_NEXT(key, link)) 22173 { 22174 dst_key_state_t ds_state = DST_KEY_STATE_NA; 22175 bool ksk = false; 22176 isc_stdtime_t published = 0, withdrawn = 0; 22177 22178 /* Is this key have the KSK role? */ 22179 (void)dst_key_role(key->key, &ksk, NULL); 22180 if (!ksk) { 22181 continue; 22182 } 22183 22184 /* Do we need to check the DS RRset? */ 22185 (void)dst_key_getstate(key->key, DST_KEY_DS, &ds_state); 22186 (void)dst_key_gettime(key->key, DST_TIME_DSPUBLISH, &published); 22187 (void)dst_key_gettime(key->key, DST_TIME_DSDELETE, &withdrawn); 22188 22189 if (ds_state == DST_KEY_STATE_RUMOURED && published == 0) { 22190 dst_key_setnum(key->key, DST_NUM_DSPUBCOUNT, 0); 22191 cdscheck = true; 22192 } else if (ds_state == DST_KEY_STATE_UNRETENTIVE && 22193 withdrawn == 0) 22194 { 22195 dst_key_setnum(key->key, DST_NUM_DSDELCOUNT, 0); 22196 cdscheck = true; 22197 } 22198 } 22199 22200 if (!cdscheck) { 22201 return; 22202 } 22203 22204 if (checkdstype == dns_checkdstype_explicit) { 22205 /* Request the DS RRset. */ 22206 LOCK_ZONE(zone); 22207 checkds_send(zone); 22208 UNLOCK_ZONE(zone); 22209 return; 22210 } 22211 22212 INSIST(checkdstype == dns_checkdstype_yes); 22213 22214 #ifdef ENABLE_AFL 22215 if (!dns_fuzzing_resolver) { 22216 #endif /* ifdef ENABLE_AFL */ 22217 dns_nsfetch_t *nsfetch; 22218 dns_name_t *name = NULL; 22219 22220 nsfetch = isc_mem_get(zone->mctx, sizeof(dns_nsfetch_t)); 22221 *nsfetch = (dns_nsfetch_t){ .zone = zone }; 22222 isc_mem_attach(zone->mctx, &nsfetch->mctx); 22223 LOCK_ZONE(zone); 22224 zone->nsfetchcount++; 22225 isc_refcount_increment0(&zone->irefs); 22226 name = dns_fixedname_initname(&nsfetch->name); 22227 dns_name_init(&nsfetch->pname, NULL); 22228 dns_name_clone(&zone->origin, &nsfetch->pname); 22229 dns_name_dup(&zone->origin, zone->mctx, name); 22230 dns_rdataset_init(&nsfetch->nsrrset); 22231 dns_rdataset_init(&nsfetch->nssigset); 22232 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 22233 dnssec_log( 22234 zone, ISC_LOG_DEBUG(3), 22235 "Creating parent NS fetch in zone_checkds()"); 22236 } 22237 isc_async_run(zone->loop, do_nsfetch, nsfetch); 22238 UNLOCK_ZONE(zone); 22239 #ifdef ENABLE_AFL 22240 } 22241 #endif /* ifdef ENABLE_AFL */ 22242 } 22243 22244 static isc_result_t 22245 update_ttl(dns_rdataset_t *rdataset, dns_name_t *name, dns_ttl_t ttl, 22246 dns_diff_t *diff) { 22247 isc_result_t result; 22248 22249 /* 22250 * Delete everything using the existing TTL. 22251 */ 22252 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 22253 result = dns_rdataset_next(rdataset)) 22254 { 22255 dns_difftuple_t *tuple = NULL; 22256 dns_rdata_t rdata = DNS_RDATA_INIT; 22257 22258 dns_rdataset_current(rdataset, &rdata); 22259 result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name, 22260 rdataset->ttl, &rdata, &tuple); 22261 if (result != ISC_R_SUCCESS) { 22262 return result; 22263 } 22264 dns_diff_appendminimal(diff, &tuple); 22265 } 22266 if (result != ISC_R_NOMORE) { 22267 return result; 22268 } 22269 22270 /* 22271 * Add everything using the new TTL. 22272 */ 22273 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 22274 result = dns_rdataset_next(rdataset)) 22275 { 22276 dns_difftuple_t *tuple = NULL; 22277 dns_rdata_t rdata = DNS_RDATA_INIT; 22278 22279 dns_rdataset_current(rdataset, &rdata); 22280 result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, 22281 ttl, &rdata, &tuple); 22282 if (result != ISC_R_SUCCESS) { 22283 return result; 22284 } 22285 dns_diff_appendminimal(diff, &tuple); 22286 } 22287 if (result != ISC_R_NOMORE) { 22288 return result; 22289 } 22290 return ISC_R_SUCCESS; 22291 } 22292 22293 static isc_result_t 22294 zone_verifykeys(dns_zone_t *zone, dns_dnsseckeylist_t *newkeys, 22295 uint32_t purgeval, isc_stdtime_t now) { 22296 dns_dnsseckey_t *key1, *key2, *next; 22297 22298 /* 22299 * Make sure that the existing keys are also present in the new keylist. 22300 */ 22301 for (key1 = ISC_LIST_HEAD(zone->keyring); key1 != NULL; key1 = next) { 22302 bool found = false; 22303 next = ISC_LIST_NEXT(key1, link); 22304 22305 if (dst_key_is_unused(key1->key)) { 22306 continue; 22307 } 22308 if (dns_keymgr_key_may_be_purged(key1->key, purgeval, now)) { 22309 continue; 22310 } 22311 if (key1->purge) { 22312 continue; 22313 } 22314 22315 for (key2 = ISC_LIST_HEAD(*newkeys); key2 != NULL; 22316 key2 = ISC_LIST_NEXT(key2, link)) 22317 { 22318 if (dst_key_compare(key1->key, key2->key)) { 22319 found = true; 22320 break; 22321 } 22322 } 22323 22324 if (!found) { 22325 char keystr[DST_KEY_FORMATSIZE]; 22326 dst_key_format(key1->key, keystr, sizeof(keystr)); 22327 dnssec_log(zone, ISC_LOG_DEBUG(1), 22328 "verifykeys: key %s - not available", 22329 keystr); 22330 return ISC_R_NOTFOUND; 22331 } 22332 } 22333 22334 /* All good. */ 22335 return ISC_R_SUCCESS; 22336 } 22337 22338 static void 22339 remove_rdataset(dns_zone_t *zone, dns_diff_t *diff, dns_rdataset_t *rdataset) { 22340 if (!dns_rdataset_isassociated(rdataset)) { 22341 return; 22342 } 22343 22344 for (isc_result_t result = dns_rdataset_first(rdataset); 22345 result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) 22346 { 22347 dns_rdata_t rdata = DNS_RDATA_INIT; 22348 dns_difftuple_t *tuple = NULL; 22349 22350 dns_rdataset_current(rdataset, &rdata); 22351 dns_difftuple_create(zone->mctx, DNS_DIFFOP_DEL, &zone->origin, 22352 rdataset->ttl, &rdata, &tuple); 22353 dns_diff_append(diff, &tuple); 22354 } 22355 return; 22356 } 22357 22358 static void 22359 add_tuple(dns_diff_t *diff, dns_difftuple_t *tuple) { 22360 dns_difftuple_t *copy = NULL; 22361 22362 dns_difftuple_copy(tuple, ©); 22363 dns_diff_appendminimal(diff, ©); 22364 } 22365 22366 static void 22367 zone_apply_skrbundle(dns_zone_t *zone, dns_skrbundle_t *bundle, 22368 dns_rdataset_t *dnskeyset, dns_rdataset_t *cdsset, 22369 dns_rdataset_t *cdnskeyset, dns_diff_t *diff) { 22370 dns_kasp_t *kasp = zone->kasp; 22371 22372 REQUIRE(DNS_ZONE_VALID(zone)); 22373 REQUIRE(DNS_KASP_VALID(kasp)); 22374 REQUIRE(DNS_SKRBUNDLE_VALID(bundle)); 22375 22376 /* Remove existing DNSKEY, CDS, and CDNSKEY records. */ 22377 remove_rdataset(zone, diff, dnskeyset); 22378 remove_rdataset(zone, diff, cdsset); 22379 remove_rdataset(zone, diff, cdnskeyset); 22380 22381 /* Add the records from the bundle. */ 22382 dns_difftuple_t *tuple = ISC_LIST_HEAD(bundle->diff.tuples); 22383 while (tuple != NULL) { 22384 switch (tuple->rdata.type) { 22385 case dns_rdatatype_dnskey: 22386 add_tuple(diff, tuple); 22387 break; 22388 case dns_rdatatype_cdnskey: 22389 case dns_rdatatype_cds: 22390 add_tuple(diff, tuple); 22391 break; 22392 case dns_rdatatype_rrsig: 22393 /* Not interested in right now */ 22394 break; 22395 default: 22396 INSIST(0); 22397 } 22398 22399 tuple = ISC_LIST_NEXT(tuple, link); 22400 } 22401 } 22402 22403 static void 22404 zone_rekey(dns_zone_t *zone) { 22405 isc_result_t result; 22406 dns_db_t *db = NULL; 22407 dns_dbnode_t *node = NULL; 22408 dns_dbversion_t *ver = NULL; 22409 dns_rdataset_t cdsset, soaset, soasigs, keyset, keysigs, cdnskeyset; 22410 dns_dnsseckeylist_t dnskeys, keys, rmkeys; 22411 dns_dnsseckey_t *key = NULL; 22412 dns_diff_t diff, _sig_diff; 22413 dns_kasp_t *kasp; 22414 dns_skrbundle_t *bundle = NULL; 22415 dns__zonediff_t zonediff; 22416 bool commit = false, newactive = false; 22417 bool newalg = false; 22418 bool fullsign; 22419 bool offlineksk = false; 22420 bool kasp_change = false; 22421 uint8_t options = 0; 22422 uint32_t sigval = 0; 22423 dns_ttl_t ttl = 3600; 22424 const char *dir = NULL; 22425 isc_mem_t *mctx = NULL; 22426 isc_stdtime_t now, nexttime = 0; 22427 isc_time_t timenow; 22428 isc_interval_t ival; 22429 char timebuf[80]; 22430 22431 REQUIRE(DNS_ZONE_VALID(zone)); 22432 22433 ISC_LIST_INIT(dnskeys); 22434 ISC_LIST_INIT(keys); 22435 ISC_LIST_INIT(rmkeys); 22436 dns_rdataset_init(&soaset); 22437 dns_rdataset_init(&soasigs); 22438 dns_rdataset_init(&keyset); 22439 dns_rdataset_init(&keysigs); 22440 dns_rdataset_init(&cdsset); 22441 dns_rdataset_init(&cdnskeyset); 22442 mctx = zone->mctx; 22443 dns_diff_init(mctx, &diff); 22444 dns_diff_init(mctx, &_sig_diff); 22445 zonediff_init(&zonediff, &_sig_diff); 22446 22447 CHECK(dns_zone_getdb(zone, &db)); 22448 CHECK(dns_db_newversion(db, &ver)); 22449 CHECK(dns_db_getoriginnode(db, &node)); 22450 22451 timenow = isc_time_now(); 22452 now = isc_time_seconds(&timenow); 22453 22454 kasp = zone->kasp; 22455 dir = dns_zone_getkeydirectory(zone); 22456 22457 dnssec_log(zone, ISC_LOG_INFO, "reconfiguring zone keys"); 22458 22459 /* Get the SOA record's TTL */ 22460 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 22461 dns_rdatatype_none, 0, &soaset, &soasigs)); 22462 ttl = soaset.ttl; 22463 dns_rdataset_disassociate(&soaset); 22464 22465 if (kasp != NULL) { 22466 ttl = dns_kasp_dnskeyttl(kasp); 22467 offlineksk = dns_kasp_offlineksk(kasp); 22468 sigval = dns_kasp_sigvalidity_dnskey(kasp); 22469 } 22470 22471 /* Get the current DNSKEY rdataset */ 22472 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 22473 dns_rdatatype_none, 0, &keyset, &keysigs); 22474 if (result == ISC_R_SUCCESS) { 22475 /* 22476 * If we don't have a policy then use the DNSKEY ttl 22477 * if it exists. Otherwise update the DNSKEY ttl if 22478 * needed. 22479 */ 22480 if (kasp == NULL) { 22481 ttl = keyset.ttl; 22482 } else if (ttl != keyset.ttl && !offlineksk) { 22483 result = update_ttl(&keyset, &zone->origin, ttl, &diff); 22484 if (result != ISC_R_SUCCESS) { 22485 dnssec_log(zone, ISC_LOG_ERROR, 22486 "Updating DNSKEY TTL from %u to %u " 22487 "failed: %s", 22488 keyset.ttl, ttl, 22489 isc_result_totext(result)); 22490 goto cleanup; 22491 } 22492 dnssec_log(zone, ISC_LOG_INFO, 22493 "Updating DNSKEY TTL from %u to %u", 22494 keyset.ttl, ttl); 22495 keyset.ttl = ttl; 22496 } 22497 22498 dns_zone_lock_keyfiles(zone); 22499 22500 result = dns_dnssec_keylistfromrdataset( 22501 &zone->origin, kasp, dir, mctx, &keyset, &keysigs, 22502 &soasigs, false, false, &dnskeys); 22503 22504 dns_zone_unlock_keyfiles(zone); 22505 22506 CHECK(result); 22507 } else if (result != ISC_R_NOTFOUND) { 22508 goto cleanup; 22509 } 22510 22511 /* Get the current CDS rdataset */ 22512 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cds, 22513 dns_rdatatype_none, 0, &cdsset, NULL); 22514 if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdsset)) { 22515 dns_rdataset_disassociate(&cdsset); 22516 } else if (result == ISC_R_SUCCESS && kasp != NULL && 22517 ttl != cdsset.ttl && !offlineksk) 22518 { 22519 result = update_ttl(&cdsset, &zone->origin, ttl, &diff); 22520 if (result != ISC_R_SUCCESS) { 22521 dnssec_log(zone, ISC_LOG_ERROR, 22522 "Updating CDS TTL from %u to %u failed: %s", 22523 cdsset.ttl, ttl, isc_result_totext(result)); 22524 goto cleanup; 22525 } 22526 dnssec_log(zone, ISC_LOG_INFO, "Updating CDS TTL from %u to %u", 22527 cdsset.ttl, ttl); 22528 cdsset.ttl = ttl; 22529 } 22530 22531 /* Get the current CDNSKEY rdataset */ 22532 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cdnskey, 22533 dns_rdatatype_none, 0, &cdnskeyset, NULL); 22534 if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdnskeyset)) { 22535 dns_rdataset_disassociate(&cdnskeyset); 22536 } else if (result == ISC_R_SUCCESS && kasp != NULL && 22537 ttl != cdnskeyset.ttl && !offlineksk) 22538 { 22539 result = update_ttl(&cdnskeyset, &zone->origin, ttl, &diff); 22540 if (result != ISC_R_SUCCESS) { 22541 dnssec_log( 22542 zone, ISC_LOG_ERROR, 22543 "Updating CDNSKEY TTL from %u to %u failed: %s", 22544 cdnskeyset.ttl, ttl, isc_result_totext(result)); 22545 goto cleanup; 22546 } 22547 dnssec_log(zone, ISC_LOG_INFO, 22548 "Updating CDNSKEY TTL from %u to %u", cdnskeyset.ttl, 22549 ttl); 22550 cdnskeyset.ttl = ttl; 22551 } 22552 22553 /* 22554 * True when called from "rndc sign". Indicates the zone should be 22555 * fully signed now. 22556 */ 22557 fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN); 22558 if (fullsign) { 22559 options |= DNS_KEYMGRATTR_FULLSIGN; 22560 } 22561 22562 /* 22563 * True when called from "rndc dnssec -step". Indicates the zone 22564 * is allowed to do the next step(s) in the keymgr process. 22565 */ 22566 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FORCEKEYMGR)) { 22567 options |= DNS_KEYMGRATTR_FORCESTEP; 22568 } 22569 22570 if (offlineksk) { 22571 /* Lookup the correct bundle in the SKR. */ 22572 LOCK_ZONE(zone); 22573 if (zone->skr == NULL) { 22574 UNLOCK_ZONE(zone); 22575 dnssec_log(zone, ISC_LOG_DEBUG(1), 22576 "zone_rekey:dns_skr_lookup failed: " 22577 "no SKR available"); 22578 CHECK(DNS_R_NOSKRFILE); 22579 } 22580 bundle = dns_skr_lookup(zone->skr, now, sigval); 22581 zone->skrbundle = bundle; 22582 UNLOCK_ZONE(zone); 22583 22584 if (bundle == NULL) { 22585 char nowstr[26]; /* Minimal buf per ctime_r() spec. */ 22586 char utc[sizeof("YYYYMMDDHHSSMM")]; 22587 isc_buffer_t b; 22588 isc_region_t r; 22589 isc_buffer_init(&b, utc, sizeof(utc)); 22590 22591 isc_stdtime_tostring(now, nowstr, sizeof(nowstr)); 22592 (void)dns_time32_totext(now, &b); 22593 isc_buffer_usedregion(&b, &r); 22594 dnssec_log(zone, ISC_LOG_DEBUG(1), 22595 "zone_rekey:dns_skr_lookup failed: " 22596 "no available SKR bundle for time " 22597 "%.*s (%s)", 22598 (int)r.length, r.base, nowstr); 22599 CHECK(DNS_R_NOSKRBUNDLE); 22600 } 22601 22602 zone_apply_skrbundle(zone, bundle, &keyset, &cdsset, 22603 &cdnskeyset, &diff); 22604 22605 dns_skrbundle_t *next = ISC_LIST_NEXT(bundle, link); 22606 if (next != NULL) { 22607 if (nexttime == 0) { 22608 nexttime = next->inception; 22609 } 22610 } else { 22611 dnssec_log(zone, ISC_LOG_WARNING, 22612 "zone_rekey: last bundle in skr, please " 22613 "import new skr file"); 22614 } 22615 } 22616 22617 /* 22618 * DNSSEC Key and Signing Policy 22619 */ 22620 22621 KASP_LOCK(kasp); 22622 22623 dns_zone_lock_keyfiles(zone); 22624 result = dns_dnssec_findmatchingkeys(&zone->origin, kasp, dir, 22625 zone->keystores, now, false, mctx, 22626 &keys); 22627 dns_zone_unlock_keyfiles(zone); 22628 22629 if (result != ISC_R_SUCCESS) { 22630 dnssec_log(zone, ISC_LOG_DEBUG(1), 22631 "zone_rekey:dns_dnssec_findmatchingkeys failed: %s", 22632 isc_result_totext(result)); 22633 } 22634 22635 if (kasp != NULL && !offlineksk) { 22636 /* Verify new keys. */ 22637 isc_result_t ret = zone_verifykeys( 22638 zone, &keys, dns_kasp_purgekeys(kasp), now); 22639 if (ret != ISC_R_SUCCESS) { 22640 dnssec_log(zone, ISC_LOG_ERROR, 22641 "zone_rekey:zone_verifykeys failed: " 22642 "some key files are missing"); 22643 KASP_UNLOCK(kasp); 22644 goto cleanup; 22645 } 22646 22647 /* 22648 * Check DS at parental agents. Clear ongoing checks. 22649 */ 22650 LOCK_ZONE(zone); 22651 checkds_cancel(zone); 22652 clear_keylist(&zone->checkds_ok, zone->mctx); 22653 ISC_LIST_INIT(zone->checkds_ok); 22654 UNLOCK_ZONE(zone); 22655 22656 ret = dns_zone_getdnsseckeys(zone, db, ver, now, 22657 &zone->checkds_ok); 22658 if (ret == ISC_R_SUCCESS) { 22659 zone_checkds(zone); 22660 } else { 22661 dnssec_log(zone, 22662 (ret == ISC_R_NOTFOUND) ? ISC_LOG_DEBUG(1) 22663 : ISC_LOG_ERROR, 22664 "zone_rekey:dns_zone_getdnsseckeys failed: " 22665 "%s", 22666 isc_result_totext(ret)); 22667 } 22668 22669 /* Run keymgr. */ 22670 if (result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND) { 22671 dns_zone_lock_keyfiles(zone); 22672 result = dns_keymgr_run(&zone->origin, zone->rdclass, 22673 mctx, &keys, &dnskeys, dir, 22674 kasp, options, now, &nexttime); 22675 dns_zone_unlock_keyfiles(zone); 22676 22677 if (result == ISC_R_SUCCESS) { 22678 kasp_change = true; 22679 } else if (result == DNS_R_UNCHANGED) { 22680 result = ISC_R_SUCCESS; 22681 } else { 22682 dnssec_log(zone, ISC_LOG_ERROR, 22683 "zone_rekey:dns_keymgr_run " 22684 "failed: %s", 22685 isc_result_totext(result)); 22686 KASP_UNLOCK(kasp); 22687 goto cleanup; 22688 } 22689 } 22690 } else if (offlineksk) { 22691 /* 22692 * With offline-ksk enabled we don't run the keymgr. 22693 * Instead we derive the states from the timing metadata. 22694 */ 22695 dns_zone_lock_keyfiles(zone); 22696 result = dns_keymgr_offline(&zone->origin, &keys, kasp, now, 22697 &nexttime); 22698 dns_zone_unlock_keyfiles(zone); 22699 22700 if (result != ISC_R_SUCCESS) { 22701 dnssec_log(zone, ISC_LOG_ERROR, 22702 "zone_rekey:dns_keymgr_offline " 22703 "failed: %s", 22704 isc_result_totext(result)); 22705 } 22706 } 22707 22708 KASP_UNLOCK(kasp); 22709 22710 /* 22711 * Update CDS, CDNSKEY and DNSKEY record sets if the keymgr ran 22712 * successfully (dns_keymgr_run returned ISC_R_SUCCESS), or in 22713 * case of DNSSEC management without dnssec-policy if we have keys 22714 * (dns_dnssec_findmatchingkeys returned ISC_R_SUCCESS). 22715 */ 22716 if (result == ISC_R_SUCCESS) { 22717 dns_kasp_digestlist_t digests; 22718 bool cdsdel = false; 22719 bool cdnskeydel = false; 22720 bool cdnskeypub = true; 22721 bool sane_diff, sane_dnskey; 22722 isc_stdtime_t when; 22723 22724 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys, 22725 &zone->origin, ttl, &diff, mctx, 22726 dnssec_report); 22727 /* 22728 * Keys couldn't be updated for some reason; 22729 * try again later. 22730 */ 22731 if (result != ISC_R_SUCCESS) { 22732 dnssec_log(zone, ISC_LOG_ERROR, 22733 "zone_rekey:couldn't update zone keys: %s", 22734 isc_result_totext(result)); 22735 goto cleanup; 22736 } 22737 22738 if (offlineksk) { 22739 /* We can skip a lot of things */ 22740 goto post_sync; 22741 } 22742 22743 /* 22744 * Publish CDS/CDNSKEY DELETE records if the zone is 22745 * transitioning from secure to insecure. 22746 */ 22747 if (kasp != NULL) { 22748 if (strcmp(dns_kasp_getname(kasp), "insecure") == 0) { 22749 cdsdel = true; 22750 cdnskeydel = true; 22751 } 22752 digests = dns_kasp_digests(kasp); 22753 cdnskeypub = dns_kasp_cdnskey(kasp); 22754 } else { 22755 /* Check if there is a CDS DELETE record. */ 22756 if (dns_rdataset_isassociated(&cdsset)) { 22757 for (result = dns_rdataset_first(&cdsset); 22758 result == ISC_R_SUCCESS; 22759 result = dns_rdataset_next(&cdsset)) 22760 { 22761 dns_rdata_t crdata = DNS_RDATA_INIT; 22762 dns_rdataset_current(&cdsset, &crdata); 22763 /* 22764 * CDS deletion record has this form 22765 * "0 0 0 00" which is 5 zero octets. 22766 */ 22767 if (crdata.length == 5U && 22768 memcmp(crdata.data, 22769 (unsigned char[5]){ 0, 0, 0, 22770 0, 0 }, 22771 5) == 0) 22772 { 22773 cdsdel = true; 22774 break; 22775 } 22776 } 22777 } 22778 22779 /* Check if there is a CDNSKEY DELETE record. */ 22780 if (dns_rdataset_isassociated(&cdnskeyset)) { 22781 for (result = dns_rdataset_first(&cdnskeyset); 22782 result == ISC_R_SUCCESS; 22783 result = dns_rdataset_next(&cdnskeyset)) 22784 { 22785 dns_rdata_t crdata = DNS_RDATA_INIT; 22786 dns_rdataset_current(&cdnskeyset, 22787 &crdata); 22788 /* 22789 * CDNSKEY deletion record has this form 22790 * "0 3 0 AA==" which is 2 zero octets, 22791 * a 3, and 2 zero octets. 22792 */ 22793 if (crdata.length == 5U && 22794 memcmp(crdata.data, 22795 (unsigned char[5]){ 0, 0, 3, 22796 0, 0 }, 22797 5) == 0) 22798 { 22799 cdnskeydel = true; 22800 break; 22801 } 22802 } 22803 } 22804 22805 digests = dns_kasp_digests(zone->defaultkasp); 22806 } 22807 22808 /* 22809 * Update CDS / CDNSKEY records. 22810 */ 22811 result = dns_dnssec_syncupdate(&dnskeys, &rmkeys, &cdsset, 22812 &cdnskeyset, now, &digests, 22813 cdnskeypub, ttl, &diff, mctx); 22814 if (result != ISC_R_SUCCESS) { 22815 dnssec_log(zone, ISC_LOG_ERROR, 22816 "zone_rekey:couldn't update CDS/CDNSKEY: %s", 22817 isc_result_totext(result)); 22818 goto cleanup; 22819 } 22820 22821 if (cdsdel || cdnskeydel) { 22822 /* 22823 * Only publish CDS/CDNSKEY DELETE records if there is 22824 * a KSK that can be used to verify the RRset. This 22825 * means there must be a key with the KSK role that is 22826 * published and is used for signing. 22827 */ 22828 bool allow = false; 22829 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 22830 key = ISC_LIST_NEXT(key, link)) 22831 { 22832 dst_key_t *dstk = key->key; 22833 22834 if (dst_key_is_published(dstk, now, &when) && 22835 dst_key_is_signing(dstk, DST_BOOL_KSK, now, 22836 &when)) 22837 { 22838 allow = true; 22839 break; 22840 } 22841 } 22842 if (cdsdel) { 22843 cdsdel = allow; 22844 } 22845 if (cdnskeydel) { 22846 cdnskeydel = allow; 22847 } 22848 } 22849 result = dns_dnssec_syncdelete( 22850 &cdsset, &cdnskeyset, &zone->origin, zone->rdclass, ttl, 22851 &diff, mctx, cdsdel, cdnskeydel); 22852 if (result != ISC_R_SUCCESS) { 22853 dnssec_log(zone, ISC_LOG_ERROR, 22854 "zone_rekey:couldn't update CDS/CDNSKEY " 22855 "DELETE records: %s", 22856 isc_result_totext(result)); 22857 goto cleanup; 22858 } 22859 22860 post_sync: 22861 /* 22862 * See if any pre-existing keys have newly become active; 22863 * also, see if any new key is for a new algorithm, as in that 22864 * event, we need to sign the zone fully. (If there's a new 22865 * key, but it's for an already-existing algorithm, then 22866 * the zone signing can be handled incrementally.) 22867 */ 22868 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 22869 key = ISC_LIST_NEXT(key, link)) 22870 { 22871 if (!key->first_sign) { 22872 continue; 22873 } 22874 22875 newactive = true; 22876 22877 if (!dns_rdataset_isassociated(&keysigs)) { 22878 newalg = true; 22879 break; 22880 } 22881 22882 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) { 22883 /* 22884 * This isn't a new algorithm; clear 22885 * first_sign so we won't sign the 22886 * whole zone with this key later. 22887 */ 22888 key->first_sign = false; 22889 } else { 22890 newalg = true; 22891 break; 22892 } 22893 } 22894 22895 /* 22896 * A sane diff is one that is not empty, and that does not 22897 * introduce a zone with NSEC only DNSKEYs along with NSEC3 22898 * chains. 22899 */ 22900 sane_dnskey = dns_zone_check_dnskey_nsec3(zone, db, ver, &diff, 22901 NULL, 0); 22902 sane_diff = !ISC_LIST_EMPTY(diff.tuples) && sane_dnskey; 22903 if (!sane_dnskey) { 22904 dnssec_log(zone, ISC_LOG_ERROR, 22905 "NSEC only DNSKEYs and NSEC3 chains not " 22906 "allowed"); 22907 } 22908 22909 if (newactive || fullsign || sane_diff || kasp_change) { 22910 CHECK(dns_diff_apply(&diff, db, ver)); 22911 CHECK(clean_nsec3param(zone, db, ver, &diff)); 22912 CHECK(add_signing_records(db, zone->privatetype, ver, 22913 &diff, newalg || fullsign)); 22914 CHECK(update_soa_serial(zone, db, ver, &diff, mctx, 22915 zone->updatemethod)); 22916 CHECK(add_chains(zone, db, ver, &diff)); 22917 CHECK(sign_apex(zone, db, ver, now, &diff, &zonediff)); 22918 CHECK(zone_journal(zone, zonediff.diff, NULL, 22919 "zone_rekey")); 22920 commit = true; 22921 } 22922 } 22923 22924 dns_db_closeversion(db, &ver, true); 22925 22926 LOCK_ZONE(zone); 22927 22928 if (commit) { 22929 dns_difftuple_t *tuple; 22930 dns_stats_t *dnssecsignstats = 22931 dns_zone_getdnssecsignstats(zone); 22932 22933 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 22934 22935 zone_needdump(zone, DNS_DUMP_DELAY); 22936 22937 zone_settimer(zone, &timenow); 22938 22939 /* Remove any signatures from removed keys. */ 22940 if (!ISC_LIST_EMPTY(rmkeys)) { 22941 for (key = ISC_LIST_HEAD(rmkeys); key != NULL; 22942 key = ISC_LIST_NEXT(key, link)) 22943 { 22944 result = zone_signwithkey( 22945 zone, dst_key_alg(key->key), 22946 dst_key_id(key->key), true, false); 22947 if (result != ISC_R_SUCCESS) { 22948 dnssec_log(zone, ISC_LOG_ERROR, 22949 "zone_signwithkey failed: " 22950 "%s", 22951 isc_result_totext(result)); 22952 } 22953 22954 /* Clear DNSSEC sign statistics. */ 22955 if (dnssecsignstats != NULL) { 22956 dns_dnssecsignstats_clear( 22957 dnssecsignstats, 22958 dst_key_id(key->key), 22959 dst_key_alg(key->key)); 22960 /* 22961 * Also clear the dnssec-sign 22962 * statistics of the revoked key id. 22963 */ 22964 dns_dnssecsignstats_clear( 22965 dnssecsignstats, 22966 dst_key_rid(key->key), 22967 dst_key_alg(key->key)); 22968 } 22969 } 22970 } 22971 22972 if (fullsign) { 22973 /* 22974 * "rndc sign" was called, so we now sign the zone 22975 * with all active keys, whether they're new or not. 22976 */ 22977 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 22978 key = ISC_LIST_NEXT(key, link)) 22979 { 22980 if (!key->force_sign && !key->hint_sign) { 22981 continue; 22982 } 22983 22984 result = zone_signwithkey( 22985 zone, dst_key_alg(key->key), 22986 dst_key_id(key->key), false, true); 22987 if (result != ISC_R_SUCCESS) { 22988 dnssec_log(zone, ISC_LOG_ERROR, 22989 "zone_signwithkey failed: " 22990 "%s", 22991 isc_result_totext(result)); 22992 } 22993 } 22994 /* 22995 * ...and remove signatures for all inactive keys. 22996 */ 22997 ISC_LIST_FOREACH(dnskeys, key, link) { 22998 if (!key->force_sign && !key->hint_sign) { 22999 result = zone_signwithkey( 23000 zone, dst_key_alg(key->key), 23001 dst_key_id(key->key), true, 23002 false); 23003 if (result != ISC_R_SUCCESS) { 23004 dnssec_log(zone, ISC_LOG_ERROR, 23005 "zone_signwithkey " 23006 "failed: " 23007 "%s", 23008 isc_result_totext( 23009 result)); 23010 } 23011 } 23012 } 23013 23014 } else if (newalg) { 23015 /* 23016 * We haven't been told to sign fully, but a new 23017 * algorithm was added to the DNSKEY. We sign 23018 * the full zone, but only with newly active 23019 * keys. 23020 */ 23021 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 23022 key = ISC_LIST_NEXT(key, link)) 23023 { 23024 if (!key->first_sign) { 23025 continue; 23026 } 23027 23028 result = zone_signwithkey( 23029 zone, dst_key_alg(key->key), 23030 dst_key_id(key->key), false, false); 23031 if (result != ISC_R_SUCCESS) { 23032 dnssec_log(zone, ISC_LOG_ERROR, 23033 "zone_signwithkey failed: " 23034 "%s", 23035 isc_result_totext(result)); 23036 } 23037 } 23038 } 23039 23040 /* 23041 * Clear fullsign flag, if it was set, so we don't do 23042 * another full signing next time. 23043 */ 23044 DNS_ZONEKEY_CLROPTION(zone, DNS_ZONEKEY_FULLSIGN); 23045 23046 /* 23047 * Cause the zone to add/delete NSEC3 chains for the 23048 * deferred NSEC3PARAM changes. 23049 */ 23050 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples); 23051 tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) 23052 { 23053 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 23054 dns_rdata_t rdata = DNS_RDATA_INIT; 23055 dns_rdata_nsec3param_t nsec3param; 23056 23057 if (tuple->rdata.type != zone->privatetype || 23058 tuple->op != DNS_DIFFOP_ADD) 23059 { 23060 continue; 23061 } 23062 23063 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata, 23064 buf, sizeof(buf))) 23065 { 23066 continue; 23067 } 23068 23069 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 23070 RUNTIME_CHECK(result == ISC_R_SUCCESS); 23071 if (nsec3param.flags == 0) { 23072 continue; 23073 } 23074 23075 result = zone_addnsec3chain(zone, &nsec3param); 23076 if (result != ISC_R_SUCCESS) { 23077 dnssec_log(zone, ISC_LOG_ERROR, 23078 "zone_addnsec3chain failed: %s", 23079 isc_result_totext(result)); 23080 } 23081 } 23082 23083 /* 23084 * Activate any NSEC3 chain updates that may have 23085 * been scheduled before this rekey. 23086 */ 23087 if (fullsign || newalg) { 23088 resume_addnsec3chain(zone); 23089 } 23090 23091 /* 23092 * Schedule the next resigning event 23093 */ 23094 set_resigntime(zone); 23095 } 23096 23097 isc_time_settoepoch(&zone->refreshkeytime); 23098 23099 /* 23100 * If keymgr provided a next time, use the calculated next rekey time. 23101 */ 23102 if (kasp != NULL) { 23103 isc_time_t timenext; 23104 uint32_t nexttime_seconds; 23105 23106 /* 23107 * Set the key refresh timer to the next scheduled key event 23108 * or to 'dnssec-loadkeys-interval' seconds in the future 23109 * if no next key event is scheduled (nexttime == 0). 23110 */ 23111 if (nexttime > 0) { 23112 nexttime_seconds = nexttime - now; 23113 } else { 23114 nexttime_seconds = zone->refreshkeyinterval; 23115 } 23116 23117 DNS_ZONE_TIME_ADD(&timenow, nexttime_seconds, &timenext); 23118 zone->refreshkeytime = timenext; 23119 zone_settimer(zone, &timenow); 23120 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 23121 23122 dnssec_log(zone, ISC_LOG_DEBUG(3), 23123 "next key event in %u seconds", nexttime_seconds); 23124 dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); 23125 } 23126 /* 23127 * If we're doing key maintenance, set the key refresh timer to 23128 * the next scheduled key event or to 'dnssec-loadkeys-interval' 23129 * seconds in the future, whichever is sooner. 23130 */ 23131 else if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 23132 { 23133 isc_time_t timethen; 23134 isc_stdtime_t then; 23135 23136 DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval, 23137 &timethen); 23138 zone->refreshkeytime = timethen; 23139 23140 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 23141 key = ISC_LIST_NEXT(key, link)) 23142 { 23143 then = now; 23144 result = next_keyevent(key->key, &then); 23145 if (result != ISC_R_SUCCESS) { 23146 continue; 23147 } 23148 23149 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 23150 if (isc_time_compare(&timethen, &zone->refreshkeytime) < 23151 0) 23152 { 23153 zone->refreshkeytime = timethen; 23154 } 23155 } 23156 23157 zone_settimer(zone, &timenow); 23158 23159 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 23160 dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); 23161 } 23162 UNLOCK_ZONE(zone); 23163 23164 /* 23165 * Remember which keys have been used. 23166 */ 23167 if (!ISC_LIST_EMPTY(zone->keyring)) { 23168 clear_keylist(&zone->keyring, zone->mctx); 23169 } 23170 while ((key = ISC_LIST_HEAD(dnskeys)) != NULL) { 23171 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 23172 /* This debug log is used in the kasp system test */ 23173 char algbuf[DNS_SECALG_FORMATSIZE]; 23174 dns_secalg_format(dst_key_alg(key->key), algbuf, 23175 sizeof(algbuf)); 23176 dnssec_log(zone, ISC_LOG_DEBUG(3), 23177 "zone_rekey done: key %d/%s", 23178 dst_key_id(key->key), algbuf); 23179 } 23180 ISC_LIST_UNLINK(dnskeys, key, link); 23181 ISC_LIST_APPEND(zone->keyring, key, link); 23182 } 23183 23184 result = ISC_R_SUCCESS; 23185 23186 cleanup: 23187 LOCK_ZONE(zone); 23188 if (result != ISC_R_SUCCESS) { 23189 /* 23190 * Something went wrong; try again in ten minutes or 23191 * after a key refresh interval, whichever is shorter. 23192 */ 23193 int loglevel = ISC_LOG_DEBUG(3); 23194 if (result != DNS_R_NOTLOADED) { 23195 loglevel = ISC_LOG_ERROR; 23196 } 23197 dnssec_log(zone, loglevel, 23198 "zone_rekey failure: %s (retry in %u seconds)", 23199 isc_result_totext(result), 23200 ISC_MIN(zone->refreshkeyinterval, 600)); 23201 isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 23202 0); 23203 isc_time_nowplusinterval(&zone->refreshkeytime, &ival); 23204 } 23205 23206 /* 23207 * Clear forcekeymgr flag, if it was set, so we don't do 23208 * another force next time. 23209 */ 23210 DNS_ZONE_CLROPTION(zone, DNS_ZONEOPT_FORCEKEYMGR); 23211 23212 UNLOCK_ZONE(zone); 23213 23214 dns_diff_clear(&diff); 23215 dns_diff_clear(&_sig_diff); 23216 23217 clear_keylist(&dnskeys, mctx); 23218 clear_keylist(&keys, mctx); 23219 clear_keylist(&rmkeys, mctx); 23220 23221 if (ver != NULL) { 23222 dns_db_closeversion(db, &ver, false); 23223 } 23224 if (dns_rdataset_isassociated(&cdsset)) { 23225 dns_rdataset_disassociate(&cdsset); 23226 } 23227 if (dns_rdataset_isassociated(&keyset)) { 23228 dns_rdataset_disassociate(&keyset); 23229 } 23230 if (dns_rdataset_isassociated(&keysigs)) { 23231 dns_rdataset_disassociate(&keysigs); 23232 } 23233 if (dns_rdataset_isassociated(&soasigs)) { 23234 dns_rdataset_disassociate(&soasigs); 23235 } 23236 if (dns_rdataset_isassociated(&cdnskeyset)) { 23237 dns_rdataset_disassociate(&cdnskeyset); 23238 } 23239 if (node != NULL) { 23240 dns_db_detachnode(db, &node); 23241 } 23242 if (db != NULL) { 23243 dns_db_detach(&db); 23244 } 23245 23246 INSIST(ver == NULL); 23247 } 23248 23249 void 23250 dns_zone_rekey(dns_zone_t *zone, bool fullsign, bool forcekeymgr) { 23251 isc_time_t now; 23252 23253 if (zone->type == dns_zone_primary && zone->loop != NULL) { 23254 LOCK_ZONE(zone); 23255 23256 if (fullsign) { 23257 DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN); 23258 } 23259 if (forcekeymgr) { 23260 DNS_ZONE_SETOPTION(zone, DNS_ZONEOPT_FORCEKEYMGR); 23261 } 23262 23263 now = isc_time_now(); 23264 zone->refreshkeytime = now; 23265 zone_settimer(zone, &now); 23266 23267 UNLOCK_ZONE(zone); 23268 } 23269 } 23270 23271 isc_result_t 23272 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 23273 unsigned int *errors) { 23274 isc_result_t result; 23275 dns_dbnode_t *node = NULL; 23276 23277 REQUIRE(DNS_ZONE_VALID(zone)); 23278 REQUIRE(errors != NULL); 23279 23280 result = dns_db_getoriginnode(db, &node); 23281 if (result != ISC_R_SUCCESS) { 23282 return result; 23283 } 23284 result = zone_count_ns_rr(zone, db, node, version, NULL, errors, false); 23285 dns_db_detachnode(db, &node); 23286 return result; 23287 } 23288 23289 isc_result_t 23290 dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { 23291 isc_result_t result; 23292 dns_dbnode_t *node = NULL; 23293 dns_rdataset_t dnskey, cds, cdnskey; 23294 unsigned char algorithms[256]; 23295 unsigned int i; 23296 bool empty = false; 23297 23298 enum { notexpected = 0, expected = 1, found = 2 }; 23299 23300 REQUIRE(DNS_ZONE_VALID(zone)); 23301 23302 result = dns_db_getoriginnode(db, &node); 23303 if (result != ISC_R_SUCCESS) { 23304 return result; 23305 } 23306 23307 dns_rdataset_init(&cds); 23308 dns_rdataset_init(&dnskey); 23309 dns_rdataset_init(&cdnskey); 23310 23311 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds, 23312 dns_rdatatype_none, 0, &cds, NULL); 23313 if (result != ISC_R_NOTFOUND) { 23314 CHECK(result); 23315 } 23316 23317 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey, 23318 dns_rdatatype_none, 0, &cdnskey, NULL); 23319 if (result != ISC_R_NOTFOUND) { 23320 CHECK(result); 23321 } 23322 23323 if (!dns_rdataset_isassociated(&cds) && 23324 !dns_rdataset_isassociated(&cdnskey)) 23325 { 23326 result = ISC_R_SUCCESS; 23327 goto cleanup; 23328 } 23329 23330 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 23331 dns_rdatatype_none, 0, &dnskey, NULL); 23332 if (result == ISC_R_NOTFOUND) { 23333 empty = true; 23334 } else { 23335 CHECK(result); 23336 } 23337 23338 /* 23339 * For each DNSSEC algorithm in the CDS RRset there must be 23340 * a matching DNSKEY record with the exception of a CDS deletion 23341 * record which must be by itself. 23342 */ 23343 if (dns_rdataset_isassociated(&cds)) { 23344 bool logged_digest_type[DNS_DSDIGEST_MAX + 1] = { 0 }; 23345 bool delete = false; 23346 memset(algorithms, notexpected, sizeof(algorithms)); 23347 for (result = dns_rdataset_first(&cds); result == ISC_R_SUCCESS; 23348 result = dns_rdataset_next(&cds)) 23349 { 23350 dns_rdata_t crdata = DNS_RDATA_INIT; 23351 dns_rdata_cds_t structcds; 23352 23353 dns_rdataset_current(&cds, &crdata); 23354 /* 23355 * CDS deletion record has this form "0 0 0 00" which 23356 * is 5 zero octets. 23357 */ 23358 if (crdata.length == 5U && 23359 memcmp(crdata.data, 23360 (unsigned char[5]){ 0, 0, 0, 0, 0 }, 5) == 0) 23361 { 23362 delete = true; 23363 continue; 23364 } 23365 23366 if (empty) { 23367 CHECK(DNS_R_BADCDS); 23368 } 23369 23370 CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL)); 23371 23372 /* 23373 * Log deprecated CDS digest types. 23374 */ 23375 switch (structcds.digest_type) { 23376 case DNS_DSDIGEST_SHA1: 23377 case DNS_DSDIGEST_GOST: 23378 if (!logged_digest_type[structcds.digest_type]) 23379 { 23380 char algbuf[DNS_DSDIGEST_FORMATSIZE]; 23381 dns_dsdigest_format( 23382 structcds.digest_type, algbuf, 23383 sizeof(algbuf)); 23384 dnssec_log(zone, ISC_LOG_WARNING, 23385 "deprecated CDS digest type " 23386 "%u (%s)", 23387 structcds.digest_type, 23388 algbuf); 23389 logged_digest_type[structcds.digest_type] = 23390 true; 23391 } 23392 break; 23393 } 23394 23395 if (algorithms[structcds.algorithm] == 0) { 23396 algorithms[structcds.algorithm] = expected; 23397 } 23398 for (result = dns_rdataset_first(&dnskey); 23399 result == ISC_R_SUCCESS; 23400 result = dns_rdataset_next(&dnskey)) 23401 { 23402 dns_rdata_t rdata = DNS_RDATA_INIT; 23403 dns_rdata_dnskey_t structdnskey; 23404 23405 dns_rdataset_current(&dnskey, &rdata); 23406 CHECK(dns_rdata_tostruct(&rdata, &structdnskey, 23407 NULL)); 23408 23409 if (structdnskey.algorithm == 23410 structcds.algorithm) 23411 { 23412 algorithms[structcds.algorithm] = found; 23413 } 23414 } 23415 if (result != ISC_R_NOMORE) { 23416 goto cleanup; 23417 } 23418 } 23419 for (i = 0; i < sizeof(algorithms); i++) { 23420 if (delete) { 23421 if (algorithms[i] != notexpected) { 23422 CHECK(DNS_R_BADCDS); 23423 } 23424 } else if (algorithms[i] == expected) { 23425 CHECK(DNS_R_BADCDS); 23426 } 23427 } 23428 } 23429 23430 /* 23431 * For each DNSSEC algorithm in the CDNSKEY RRset there must be 23432 * a matching DNSKEY record with the exception of a CDNSKEY deletion 23433 * record which must be by itself. 23434 */ 23435 if (dns_rdataset_isassociated(&cdnskey)) { 23436 bool delete = false; 23437 memset(algorithms, notexpected, sizeof(algorithms)); 23438 for (result = dns_rdataset_first(&cdnskey); 23439 result == ISC_R_SUCCESS; 23440 result = dns_rdataset_next(&cdnskey)) 23441 { 23442 dns_rdata_t crdata = DNS_RDATA_INIT; 23443 dns_rdata_cdnskey_t structcdnskey; 23444 23445 dns_rdataset_current(&cdnskey, &crdata); 23446 /* 23447 * CDNSKEY deletion record has this form 23448 * "0 3 0 AA==" which is 2 zero octets, a 3, 23449 * and 2 zero octets. 23450 */ 23451 if (crdata.length == 5U && 23452 memcmp(crdata.data, 23453 (unsigned char[5]){ 0, 0, 3, 0, 0 }, 5) == 0) 23454 { 23455 delete = true; 23456 continue; 23457 } 23458 23459 if (empty) { 23460 CHECK(DNS_R_BADCDNSKEY); 23461 } 23462 23463 CHECK(dns_rdata_tostruct(&crdata, &structcdnskey, 23464 NULL)); 23465 if (algorithms[structcdnskey.algorithm] == 0) { 23466 algorithms[structcdnskey.algorithm] = expected; 23467 } 23468 for (result = dns_rdataset_first(&dnskey); 23469 result == ISC_R_SUCCESS; 23470 result = dns_rdataset_next(&dnskey)) 23471 { 23472 dns_rdata_t rdata = DNS_RDATA_INIT; 23473 dns_rdata_dnskey_t structdnskey; 23474 23475 dns_rdataset_current(&dnskey, &rdata); 23476 CHECK(dns_rdata_tostruct(&rdata, &structdnskey, 23477 NULL)); 23478 23479 if (structdnskey.algorithm == 23480 structcdnskey.algorithm) 23481 { 23482 algorithms[structcdnskey.algorithm] = 23483 found; 23484 } 23485 } 23486 if (result != ISC_R_NOMORE) { 23487 goto cleanup; 23488 } 23489 } 23490 for (i = 0; i < sizeof(algorithms); i++) { 23491 if (delete) { 23492 if (algorithms[i] != notexpected) { 23493 CHECK(DNS_R_BADCDNSKEY); 23494 } 23495 } else if (algorithms[i] == expected) { 23496 CHECK(DNS_R_BADCDNSKEY); 23497 } 23498 } 23499 } 23500 result = ISC_R_SUCCESS; 23501 23502 cleanup: 23503 if (dns_rdataset_isassociated(&cds)) { 23504 dns_rdataset_disassociate(&cds); 23505 } 23506 if (dns_rdataset_isassociated(&dnskey)) { 23507 dns_rdataset_disassociate(&dnskey); 23508 } 23509 if (dns_rdataset_isassociated(&cdnskey)) { 23510 dns_rdataset_disassociate(&cdnskey); 23511 } 23512 dns_db_detachnode(db, &node); 23513 return result; 23514 } 23515 23516 void 23517 dns_zone_setautomatic(dns_zone_t *zone, bool automatic) { 23518 REQUIRE(DNS_ZONE_VALID(zone)); 23519 23520 LOCK_ZONE(zone); 23521 zone->automatic = automatic; 23522 UNLOCK_ZONE(zone); 23523 } 23524 23525 bool 23526 dns_zone_getautomatic(dns_zone_t *zone) { 23527 REQUIRE(DNS_ZONE_VALID(zone)); 23528 return zone->automatic; 23529 } 23530 23531 void 23532 dns_zone_setadded(dns_zone_t *zone, bool added) { 23533 REQUIRE(DNS_ZONE_VALID(zone)); 23534 23535 LOCK_ZONE(zone); 23536 zone->added = added; 23537 UNLOCK_ZONE(zone); 23538 } 23539 23540 bool 23541 dns_zone_getadded(dns_zone_t *zone) { 23542 REQUIRE(DNS_ZONE_VALID(zone)); 23543 return zone->added; 23544 } 23545 23546 isc_result_t 23547 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db) { 23548 isc_time_t loadtime; 23549 isc_result_t result; 23550 dns_zone_t *secure = NULL; 23551 23552 loadtime = isc_time_now(); 23553 23554 /* 23555 * Lock hierarchy: zmgr, zone, raw. 23556 */ 23557 again: 23558 LOCK_ZONE(zone); 23559 INSIST(zone != zone->raw); 23560 if (inline_secure(zone)) { 23561 LOCK_ZONE(zone->raw); 23562 } else if (inline_raw(zone)) { 23563 secure = zone->secure; 23564 TRYLOCK_ZONE(result, secure); 23565 if (result != ISC_R_SUCCESS) { 23566 UNLOCK_ZONE(zone); 23567 secure = NULL; 23568 isc_thread_yield(); 23569 goto again; 23570 } 23571 } 23572 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 23573 if (inline_secure(zone)) { 23574 UNLOCK_ZONE(zone->raw); 23575 } else if (secure != NULL) { 23576 UNLOCK_ZONE(secure); 23577 } 23578 UNLOCK_ZONE(zone); 23579 return result; 23580 } 23581 23582 isc_result_t 23583 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, uint32_t interval) { 23584 REQUIRE(DNS_ZONE_VALID(zone)); 23585 if (interval == 0) { 23586 return ISC_R_RANGE; 23587 } 23588 /* Maximum value: 24 hours (3600 minutes) */ 23589 if (interval > (24 * 60)) { 23590 interval = (24 * 60); 23591 } 23592 /* Multiply by 60 for seconds */ 23593 zone->refreshkeyinterval = interval * 60; 23594 return ISC_R_SUCCESS; 23595 } 23596 23597 void 23598 dns_zone_setrequestixfr(dns_zone_t *zone, bool flag) { 23599 REQUIRE(DNS_ZONE_VALID(zone)); 23600 zone->requestixfr = flag; 23601 } 23602 23603 bool 23604 dns_zone_getrequestixfr(dns_zone_t *zone) { 23605 REQUIRE(DNS_ZONE_VALID(zone)); 23606 return zone->requestixfr; 23607 } 23608 23609 void 23610 dns_zone_setixfrratio(dns_zone_t *zone, uint32_t ratio) { 23611 REQUIRE(DNS_ZONE_VALID(zone)); 23612 zone->ixfr_ratio = ratio; 23613 } 23614 23615 uint32_t 23616 dns_zone_getixfrratio(dns_zone_t *zone) { 23617 REQUIRE(DNS_ZONE_VALID(zone)); 23618 return zone->ixfr_ratio; 23619 } 23620 23621 void 23622 dns_zone_setrequestexpire(dns_zone_t *zone, bool flag) { 23623 REQUIRE(DNS_ZONE_VALID(zone)); 23624 zone->requestexpire = flag; 23625 } 23626 23627 bool 23628 dns_zone_getrequestexpire(dns_zone_t *zone) { 23629 REQUIRE(DNS_ZONE_VALID(zone)); 23630 return zone->requestexpire; 23631 } 23632 23633 void 23634 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) { 23635 REQUIRE(DNS_ZONE_VALID(zone)); 23636 zone->updatemethod = method; 23637 } 23638 23639 dns_updatemethod_t 23640 dns_zone_getserialupdatemethod(dns_zone_t *zone) { 23641 REQUIRE(DNS_ZONE_VALID(zone)); 23642 return zone->updatemethod; 23643 } 23644 23645 /* 23646 * Lock hierarchy: zmgr, zone, raw. 23647 */ 23648 isc_result_t 23649 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) { 23650 dns_zonemgr_t *zmgr; 23651 23652 REQUIRE(DNS_ZONE_VALID(zone)); 23653 REQUIRE(zone->zmgr != NULL); 23654 REQUIRE(zone->loop != NULL); 23655 REQUIRE(zone->raw == NULL); 23656 23657 REQUIRE(DNS_ZONE_VALID(raw)); 23658 REQUIRE(raw->zmgr == NULL); 23659 REQUIRE(raw->loop == NULL); 23660 REQUIRE(raw->secure == NULL); 23661 23662 REQUIRE(zone != raw); 23663 23664 /* 23665 * Lock hierarchy: zmgr, zone, raw. 23666 */ 23667 zmgr = zone->zmgr; 23668 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 23669 LOCK_ZONE(zone); 23670 LOCK_ZONE(raw); 23671 23672 isc_loop_attach(zone->loop, &raw->loop); 23673 23674 /* dns_zone_attach(raw, &zone->raw); */ 23675 isc_refcount_increment(&raw->references); 23676 zone->raw = raw; 23677 23678 /* dns_zone_iattach(zone, &raw->secure); */ 23679 zone_iattach(zone, &raw->secure); 23680 23681 ISC_LIST_APPEND(zmgr->zones, raw, link); 23682 raw->zmgr = zmgr; 23683 isc_refcount_increment(&zmgr->refs); 23684 23685 UNLOCK_ZONE(raw); 23686 UNLOCK_ZONE(zone); 23687 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 23688 return ISC_R_SUCCESS; 23689 } 23690 23691 void 23692 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) { 23693 REQUIRE(DNS_ZONE_VALID(zone)); 23694 REQUIRE(raw != NULL && *raw == NULL); 23695 23696 LOCK(&zone->lock); 23697 INSIST(zone != zone->raw); 23698 if (zone->raw != NULL) { 23699 dns_zone_attach(zone->raw, raw); 23700 } 23701 UNLOCK(&zone->lock); 23702 } 23703 23704 bool 23705 dns_zone_israw(dns_zone_t *zone) { 23706 bool israw; 23707 REQUIRE(DNS_ZONE_VALID(zone)); 23708 LOCK(&zone->lock); 23709 israw = zone->secure != NULL; 23710 UNLOCK(&zone->lock); 23711 return israw; 23712 } 23713 23714 bool 23715 dns_zone_issecure(dns_zone_t *zone) { 23716 bool issecure; 23717 REQUIRE(DNS_ZONE_VALID(zone)); 23718 LOCK(&zone->lock); 23719 issecure = zone->raw != NULL; 23720 UNLOCK(&zone->lock); 23721 return issecure; 23722 } 23723 23724 struct keydone { 23725 bool all; 23726 unsigned char data[5]; 23727 dns_zone_t *zone; 23728 }; 23729 23730 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL) 23731 23732 static void 23733 keydone(void *arg) { 23734 bool commit = false; 23735 isc_result_t result; 23736 dns_rdata_t rdata = DNS_RDATA_INIT; 23737 dns_dbversion_t *oldver = NULL, *newver = NULL; 23738 dns_db_t *db = NULL; 23739 dns_dbnode_t *node = NULL; 23740 dns_rdataset_t rdataset; 23741 dns_diff_t diff; 23742 struct keydone *kd = (struct keydone *)arg; 23743 dns_zone_t *zone = kd->zone; 23744 dns_update_log_t log = { update_log_cb, NULL }; 23745 bool clear_pending = false; 23746 23747 INSIST(DNS_ZONE_VALID(zone)); 23748 23749 ENTER; 23750 23751 dns_rdataset_init(&rdataset); 23752 dns_diff_init(zone->mctx, &diff); 23753 23754 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 23755 if (zone->db != NULL) { 23756 dns_db_attach(zone->db, &db); 23757 } 23758 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 23759 if (db == NULL) { 23760 goto cleanup; 23761 } 23762 23763 dns_db_currentversion(db, &oldver); 23764 result = dns_db_newversion(db, &newver); 23765 if (result != ISC_R_SUCCESS) { 23766 dnssec_log(zone, ISC_LOG_ERROR, 23767 "keydone:dns_db_newversion -> %s", 23768 isc_result_totext(result)); 23769 goto cleanup; 23770 } 23771 23772 CHECK(dns_db_getoriginnode(db, &node)); 23773 23774 result = dns_db_findrdataset(db, node, newver, zone->privatetype, 23775 dns_rdatatype_none, 0, &rdataset, NULL); 23776 if (result != ISC_R_SUCCESS) { 23777 INSIST(!dns_rdataset_isassociated(&rdataset)); 23778 goto cleanup; 23779 } 23780 23781 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 23782 result = dns_rdataset_next(&rdataset)) 23783 { 23784 bool found = false; 23785 23786 dns_rdataset_current(&rdataset, &rdata); 23787 23788 if (kd->all) { 23789 if (rdata.length == 5 && rdata.data[0] != 0 && 23790 rdata.data[3] == 0 && rdata.data[4] == 1) 23791 { 23792 found = true; 23793 } else if (rdata.data[0] == 0 && 23794 (rdata.data[2] & PENDINGFLAGS) != 0) 23795 { 23796 found = true; 23797 clear_pending = true; 23798 } 23799 } else if (rdata.length == 5 && 23800 memcmp(rdata.data, kd->data, 5) == 0) 23801 { 23802 found = true; 23803 } 23804 23805 if (found) { 23806 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL, 23807 &zone->origin, rdataset.ttl, 23808 &rdata)); 23809 } 23810 dns_rdata_reset(&rdata); 23811 } 23812 23813 if (!ISC_LIST_EMPTY(diff.tuples)) { 23814 /* Write changes to journal file. */ 23815 CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx, 23816 zone->updatemethod)); 23817 23818 result = dns_update_signatures(&log, zone, db, oldver, newver, 23819 &diff, 23820 zone->sigvalidityinterval); 23821 if (!clear_pending) { 23822 CHECK(result); 23823 } 23824 23825 CHECK(zone_journal(zone, &diff, NULL, "keydone")); 23826 commit = true; 23827 23828 LOCK_ZONE(zone); 23829 DNS_ZONE_SETFLAG(zone, 23830 DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY); 23831 zone_needdump(zone, 30); 23832 UNLOCK_ZONE(zone); 23833 } 23834 23835 cleanup: 23836 if (dns_rdataset_isassociated(&rdataset)) { 23837 dns_rdataset_disassociate(&rdataset); 23838 } 23839 if (db != NULL) { 23840 if (node != NULL) { 23841 dns_db_detachnode(db, &node); 23842 } 23843 if (oldver != NULL) { 23844 dns_db_closeversion(db, &oldver, false); 23845 } 23846 if (newver != NULL) { 23847 dns_db_closeversion(db, &newver, commit); 23848 } 23849 dns_db_detach(&db); 23850 } 23851 dns_diff_clear(&diff); 23852 isc_mem_put(zone->mctx, kd, sizeof(*kd)); 23853 dns_zone_idetach(&zone); 23854 23855 INSIST(oldver == NULL); 23856 INSIST(newver == NULL); 23857 } 23858 23859 isc_result_t 23860 dns_zone_keydone(dns_zone_t *zone, const char *keystr) { 23861 isc_result_t result = ISC_R_SUCCESS; 23862 struct keydone *kd = NULL; 23863 isc_buffer_t b; 23864 23865 REQUIRE(DNS_ZONE_VALID(zone)); 23866 23867 LOCK_ZONE(zone); 23868 23869 kd = isc_mem_get(zone->mctx, sizeof(*kd)); 23870 *kd = (struct keydone){ .all = false }; 23871 23872 if (strcasecmp(keystr, "all") == 0) { 23873 kd->all = true; 23874 } else { 23875 isc_textregion_t r; 23876 const char *algstr = NULL; 23877 dns_keytag_t keyid; 23878 dns_secalg_t alg; 23879 size_t n; 23880 23881 n = sscanf(keystr, "%hu/", &keyid); 23882 if (n == 0U) { 23883 CHECK(ISC_R_FAILURE); 23884 } 23885 23886 algstr = strchr(keystr, '/'); 23887 if (algstr != NULL) { 23888 algstr++; 23889 } else { 23890 CHECK(ISC_R_FAILURE); 23891 } 23892 23893 n = sscanf(algstr, "%hhu", &alg); 23894 if (n == 0U) { 23895 r.base = UNCONST(algstr); 23896 r.length = strlen(algstr); 23897 CHECK(dns_secalg_fromtext(&alg, &r)); 23898 } 23899 23900 /* construct a private-type rdata */ 23901 isc_buffer_init(&b, kd->data, sizeof(kd->data)); 23902 isc_buffer_putuint8(&b, alg); 23903 isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8); 23904 isc_buffer_putuint8(&b, keyid & 0xff); 23905 isc_buffer_putuint8(&b, 0); 23906 isc_buffer_putuint8(&b, 1); 23907 } 23908 23909 zone_iattach(zone, &kd->zone); 23910 isc_async_run(zone->loop, keydone, kd); 23911 kd = NULL; 23912 23913 cleanup: 23914 if (kd != NULL) { 23915 isc_mem_put(zone->mctx, kd, sizeof(*kd)); 23916 } 23917 UNLOCK_ZONE(zone); 23918 return result; 23919 } 23920 23921 /* 23922 * Called from the zone loop's queue after the relevant event is posted by 23923 * dns_zone_setnsec3param(). 23924 */ 23925 static void 23926 setnsec3param(void *arg) { 23927 struct np3 *npe = (struct np3 *)arg; 23928 dns_zone_t *zone = npe->zone; 23929 bool loadpending; 23930 23931 INSIST(DNS_ZONE_VALID(zone)); 23932 23933 ENTER; 23934 23935 LOCK_ZONE(zone); 23936 loadpending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING); 23937 UNLOCK_ZONE(zone); 23938 23939 /* 23940 * The receive_secure_serial() and setnsec3param() calls are 23941 * loop-serialized for the zone. Make sure there's no processing 23942 * currently running. 23943 */ 23944 INSIST(zone->rss_newver == NULL); 23945 23946 bool rescheduled = false; 23947 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 23948 /* 23949 * The zone is not yet fully loaded. Reschedule the event to 23950 * be picked up later. This turns this function into a busy 23951 * wait, but it only happens at startup. 23952 */ 23953 if (zone->db == NULL && loadpending) { 23954 rescheduled = true; 23955 isc_async_run(zone->loop, setnsec3param, npe); 23956 } 23957 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 23958 if (rescheduled) { 23959 return; 23960 } 23961 23962 rss_post(npe); 23963 23964 dns_zone_idetach(&zone); 23965 } 23966 23967 static void 23968 salt2text(unsigned char *salt, uint8_t saltlen, unsigned char *text, 23969 unsigned int textlen) { 23970 isc_region_t r; 23971 isc_buffer_t buf; 23972 isc_result_t result; 23973 23974 r.base = salt; 23975 r.length = (unsigned int)saltlen; 23976 23977 isc_buffer_init(&buf, text, textlen); 23978 result = isc_hex_totext(&r, 2, "", &buf); 23979 if (result == ISC_R_SUCCESS) { 23980 text[saltlen * 2] = 0; 23981 } else { 23982 text[0] = 0; 23983 } 23984 } 23985 23986 /* 23987 * Check whether NSEC3 chain addition or removal specified by the private-type 23988 * record passed with the event was already queued (or even fully performed). 23989 * If not, modify the relevant private-type records at the zone apex and call 23990 * resume_addnsec3chain(). 23991 */ 23992 static void 23993 rss_post(void *arg) { 23994 struct np3 *npe = (struct np3 *)arg; 23995 dns_zone_t *zone = npe->zone; 23996 nsec3param_t *np = &npe->params; 23997 bool commit = false; 23998 isc_result_t result; 23999 dns_dbversion_t *oldver = NULL, *newver = NULL; 24000 dns_db_t *db = NULL; 24001 dns_dbnode_t *node = NULL; 24002 dns_rdataset_t prdataset, nrdataset; 24003 dns_diff_t diff; 24004 dns_update_log_t log = { update_log_cb, NULL }; 24005 dns_rdata_t rdata; 24006 bool nseconly; 24007 bool exists = false; 24008 24009 ENTER; 24010 24011 dns_rdataset_init(&prdataset); 24012 dns_rdataset_init(&nrdataset); 24013 dns_diff_init(zone->mctx, &diff); 24014 24015 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 24016 if (zone->db != NULL) { 24017 dns_db_attach(zone->db, &db); 24018 } 24019 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 24020 if (db == NULL) { 24021 goto cleanup; 24022 } 24023 24024 dns_db_currentversion(db, &oldver); 24025 result = dns_db_newversion(db, &newver); 24026 if (result != ISC_R_SUCCESS) { 24027 dnssec_log(zone, ISC_LOG_ERROR, 24028 "setnsec3param:dns_db_newversion -> %s", 24029 isc_result_totext(result)); 24030 goto cleanup; 24031 } 24032 24033 CHECK(dns_db_getoriginnode(db, &node)); 24034 24035 /* 24036 * Do we need to look up the NSEC3 parameters? 24037 */ 24038 if (np->lookup) { 24039 dns_rdata_nsec3param_t param; 24040 dns_rdata_t nrdata = DNS_RDATA_INIT; 24041 dns_rdata_t prdata = DNS_RDATA_INIT; 24042 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE]; 24043 unsigned char saltbuf[255]; 24044 isc_buffer_t b; 24045 24046 param.salt = NULL; 24047 result = dns__zone_lookup_nsec3param(zone, &np->rdata, ¶m, 24048 saltbuf, np->resalt); 24049 if (result == ISC_R_SUCCESS) { 24050 /* 24051 * Success because the NSEC3PARAM already exists, but 24052 * function returns void, so goto cleanup. 24053 */ 24054 goto cleanup; 24055 } 24056 if (result != DNS_R_NSEC3RESALT && result != ISC_R_NOTFOUND) { 24057 dnssec_log(zone, ISC_LOG_DEBUG(3), 24058 "setnsec3param:lookup nsec3param -> %s", 24059 isc_result_totext(result)); 24060 goto cleanup; 24061 } 24062 24063 INSIST(param.salt != NULL); 24064 24065 /* Update NSEC3 parameters. */ 24066 np->rdata.hash = param.hash; 24067 np->rdata.flags = param.flags; 24068 np->rdata.iterations = param.iterations; 24069 np->rdata.salt_length = param.salt_length; 24070 np->rdata.salt = param.salt; 24071 24072 isc_buffer_init(&b, nbuf, sizeof(nbuf)); 24073 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass, 24074 dns_rdatatype_nsec3param, &np->rdata, 24075 &b)); 24076 dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype, 24077 np->data, sizeof(np->data)); 24078 np->length = prdata.length; 24079 np->nsec = false; 24080 } 24081 24082 /* 24083 * Does a private-type record already exist for this chain? 24084 */ 24085 result = dns_db_findrdataset(db, node, newver, zone->privatetype, 24086 dns_rdatatype_none, 0, &prdataset, NULL); 24087 if (result == ISC_R_SUCCESS) { 24088 for (result = dns_rdataset_first(&prdataset); 24089 result == ISC_R_SUCCESS; 24090 result = dns_rdataset_next(&prdataset)) 24091 { 24092 dns_rdata_init(&rdata); 24093 dns_rdataset_current(&prdataset, &rdata); 24094 24095 if (np->length == rdata.length && 24096 memcmp(rdata.data, np->data, np->length) == 0) 24097 { 24098 exists = true; 24099 break; 24100 } 24101 } 24102 } else if (result != ISC_R_NOTFOUND) { 24103 INSIST(!dns_rdataset_isassociated(&prdataset)); 24104 goto cleanup; 24105 } 24106 24107 /* 24108 * Does the chain already exist? 24109 */ 24110 result = dns_db_findrdataset(db, node, newver, dns_rdatatype_nsec3param, 24111 dns_rdatatype_none, 0, &nrdataset, NULL); 24112 if (result == ISC_R_SUCCESS) { 24113 for (result = dns_rdataset_first(&nrdataset); 24114 result == ISC_R_SUCCESS; 24115 result = dns_rdataset_next(&nrdataset)) 24116 { 24117 dns_rdata_init(&rdata); 24118 dns_rdataset_current(&nrdataset, &rdata); 24119 24120 if (np->length == ((unsigned int)rdata.length + 1) && 24121 memcmp(rdata.data, np->data + 1, np->length - 1) == 24122 0) 24123 { 24124 exists = true; 24125 break; 24126 } 24127 } 24128 } else if (result != ISC_R_NOTFOUND) { 24129 INSIST(!dns_rdataset_isassociated(&nrdataset)); 24130 goto cleanup; 24131 } 24132 24133 /* 24134 * We need to remove any existing NSEC3 chains if the supplied NSEC3 24135 * parameters are supposed to replace the current ones or if we are 24136 * switching to NSEC. 24137 */ 24138 if (!exists && np->replace && (np->length != 0 || np->nsec)) { 24139 CHECK(dns_nsec3param_deletechains(db, newver, zone, !np->nsec, 24140 &diff)); 24141 } 24142 24143 if (!exists && np->length != 0) { 24144 /* 24145 * We're creating an NSEC3 chain. Add the private-type record 24146 * passed in the event handler's argument to the zone apex. 24147 * 24148 * If the zone is not currently capable of supporting an NSEC3 24149 * chain (due to the DNSKEY RRset at the zone apex not existing 24150 * or containing at least one key using an NSEC-only 24151 * algorithm), add the INITIAL flag, so these parameters can be 24152 * used later when NSEC3 becomes available. 24153 */ 24154 dns_rdata_init(&rdata); 24155 24156 np->data[2] |= DNS_NSEC3FLAG_CREATE; 24157 result = dns_nsec_nseconly(db, newver, NULL, &nseconly); 24158 if (result == ISC_R_NOTFOUND || nseconly) { 24159 np->data[2] |= DNS_NSEC3FLAG_INITIAL; 24160 } 24161 24162 rdata.length = np->length; 24163 rdata.data = np->data; 24164 rdata.type = zone->privatetype; 24165 rdata.rdclass = zone->rdclass; 24166 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD, 24167 &zone->origin, 0, &rdata)); 24168 } 24169 24170 /* 24171 * If we changed anything in the zone, write changes to journal file 24172 * and set commit to true so that resume_addnsec3chain() will be 24173 * called below in order to kick off adding/removing relevant NSEC3 24174 * records. 24175 */ 24176 if (!ISC_LIST_EMPTY(diff.tuples)) { 24177 CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx, 24178 zone->updatemethod)); 24179 result = dns_update_signatures(&log, zone, db, oldver, newver, 24180 &diff, 24181 zone->sigvalidityinterval); 24182 if (result != ISC_R_NOTFOUND) { 24183 CHECK(result); 24184 } 24185 CHECK(zone_journal(zone, &diff, NULL, "setnsec3param")); 24186 commit = true; 24187 24188 LOCK_ZONE(zone); 24189 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 24190 zone_needdump(zone, 30); 24191 UNLOCK_ZONE(zone); 24192 } 24193 24194 cleanup: 24195 if (dns_rdataset_isassociated(&prdataset)) { 24196 dns_rdataset_disassociate(&prdataset); 24197 } 24198 if (dns_rdataset_isassociated(&nrdataset)) { 24199 dns_rdataset_disassociate(&nrdataset); 24200 } 24201 if (node != NULL) { 24202 dns_db_detachnode(db, &node); 24203 } 24204 if (oldver != NULL) { 24205 dns_db_closeversion(db, &oldver, false); 24206 } 24207 if (newver != NULL) { 24208 dns_db_closeversion(db, &newver, commit); 24209 } 24210 if (db != NULL) { 24211 dns_db_detach(&db); 24212 } 24213 if (commit) { 24214 LOCK_ZONE(zone); 24215 resume_addnsec3chain(zone); 24216 UNLOCK_ZONE(zone); 24217 } 24218 dns_diff_clear(&diff); 24219 isc_mem_put(zone->mctx, npe, sizeof(*npe)); 24220 24221 INSIST(oldver == NULL); 24222 INSIST(newver == NULL); 24223 } 24224 24225 /* 24226 * Check if zone has NSEC3PARAM (and thus a chain) with the right parameters. 24227 * 24228 * If 'salt' is NULL, a match is found if the salt has the requested length, 24229 * otherwise the NSEC3 salt must match the requested salt value too. 24230 * 24231 * Returns ISC_R_SUCCESS, if a match is found, or an error if no match is 24232 * found, or if the db lookup failed. 24233 */ 24234 isc_result_t 24235 dns__zone_lookup_nsec3param(dns_zone_t *zone, dns_rdata_nsec3param_t *lookup, 24236 dns_rdata_nsec3param_t *param, 24237 unsigned char saltbuf[255], bool resalt) { 24238 isc_result_t result = ISC_R_UNEXPECTED; 24239 dns_dbnode_t *node = NULL; 24240 dns_db_t *db = NULL; 24241 dns_dbversion_t *version = NULL; 24242 dns_rdataset_t rdataset; 24243 dns_rdata_nsec3param_t nsec3param; 24244 dns_rdata_t rdata = DNS_RDATA_INIT; 24245 24246 REQUIRE(DNS_ZONE_VALID(zone)); 24247 24248 dns_rdataset_init(&rdataset); 24249 24250 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 24251 if (zone->db != NULL) { 24252 dns_db_attach(zone->db, &db); 24253 } 24254 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 24255 if (db == NULL) { 24256 result = ISC_R_FAILURE; 24257 goto setparam; 24258 } 24259 24260 result = dns_db_findnode(db, &zone->origin, false, &node); 24261 if (result != ISC_R_SUCCESS) { 24262 dns_zone_log(zone, ISC_LOG_ERROR, 24263 "dns__zone_lookup_nsec3param:" 24264 "dns_db_findnode -> %s", 24265 isc_result_totext(result)); 24266 result = ISC_R_FAILURE; 24267 goto setparam; 24268 } 24269 dns_db_currentversion(db, &version); 24270 24271 result = dns_db_findrdataset(db, node, version, 24272 dns_rdatatype_nsec3param, 24273 dns_rdatatype_none, 0, &rdataset, NULL); 24274 if (result != ISC_R_SUCCESS) { 24275 INSIST(!dns_rdataset_isassociated(&rdataset)); 24276 if (result != ISC_R_NOTFOUND) { 24277 dns_zone_log(zone, ISC_LOG_ERROR, 24278 "dns__zone_lookup_nsec3param:" 24279 "dns_db_findrdataset -> %s", 24280 isc_result_totext(result)); 24281 } 24282 goto setparam; 24283 } 24284 24285 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 24286 result = dns_rdataset_next(&rdataset)) 24287 { 24288 dns_rdataset_current(&rdataset, &rdata); 24289 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 24290 INSIST(result == ISC_R_SUCCESS); 24291 dns_rdata_reset(&rdata); 24292 24293 /* Check parameters. */ 24294 if (nsec3param.hash != lookup->hash) { 24295 continue; 24296 } 24297 if (nsec3param.iterations != lookup->iterations) { 24298 continue; 24299 } 24300 if (nsec3param.salt_length != lookup->salt_length) { 24301 continue; 24302 } 24303 if (lookup->salt != NULL) { 24304 if (memcmp(nsec3param.salt, lookup->salt, 24305 lookup->salt_length) != 0) 24306 { 24307 continue; 24308 } 24309 } 24310 /* Found a match. */ 24311 result = ISC_R_SUCCESS; 24312 param->hash = nsec3param.hash; 24313 param->flags = nsec3param.flags; 24314 param->iterations = nsec3param.iterations; 24315 param->salt_length = nsec3param.salt_length; 24316 param->salt = nsec3param.salt; 24317 break; 24318 } 24319 24320 if (result == ISC_R_NOMORE) { 24321 result = ISC_R_NOTFOUND; 24322 } 24323 24324 setparam: 24325 if (result != ISC_R_SUCCESS) { 24326 /* Found no match. */ 24327 param->hash = lookup->hash; 24328 param->flags = lookup->flags; 24329 param->iterations = lookup->iterations; 24330 param->salt_length = lookup->salt_length; 24331 param->salt = lookup->salt; 24332 } 24333 24334 if (result != ISC_R_NOTFOUND) { 24335 CHECK(result); 24336 } 24337 24338 if (param->salt_length == 0) { 24339 param->salt = (unsigned char *)"-"; 24340 } else if (resalt || param->salt == NULL) { 24341 unsigned char *newsalt; 24342 unsigned char salttext[255 * 2 + 1]; 24343 do { 24344 /* Generate a new salt. */ 24345 result = dns_nsec3_generate_salt(saltbuf, 24346 param->salt_length); 24347 if (result != ISC_R_SUCCESS) { 24348 break; 24349 } 24350 newsalt = saltbuf; 24351 salt2text(newsalt, param->salt_length, salttext, 24352 sizeof(salttext)); 24353 dnssec_log(zone, ISC_LOG_INFO, "generated salt: %s", 24354 salttext); 24355 /* Check for salt conflict. */ 24356 if (param->salt != NULL && 24357 memcmp(newsalt, param->salt, param->salt_length) == 24358 0) 24359 { 24360 result = ISC_R_SUCCESS; 24361 } else { 24362 param->salt = newsalt; 24363 result = DNS_R_NSEC3RESALT; 24364 } 24365 } while (result == ISC_R_SUCCESS); 24366 24367 INSIST(result != ISC_R_SUCCESS); 24368 } 24369 24370 cleanup: 24371 if (dns_rdataset_isassociated(&rdataset)) { 24372 dns_rdataset_disassociate(&rdataset); 24373 } 24374 if (node != NULL) { 24375 dns_db_detachnode(db, &node); 24376 } 24377 if (version != NULL) { 24378 dns_db_closeversion(db, &version, false); 24379 } 24380 if (db != NULL) { 24381 dns_db_detach(&db); 24382 } 24383 24384 return result; 24385 } 24386 24387 /* 24388 * Called when an "rndc signing -nsec3param ..." command is received, or the 24389 * 'dnssec-policy' has changed. 24390 * 24391 * Allocate and prepare an nsec3param_t structure which holds information about 24392 * the NSEC3 changes requested for the zone: 24393 * 24394 * - if NSEC3 is to be disabled ("-nsec3param none"), only set the "nsec" 24395 * field of the structure to true and the "replace" field to the value 24396 * of the "replace" argument, leaving other fields initialized to zeros, to 24397 * signal that the zone should be signed using NSEC instead of NSEC3, 24398 * 24399 * - otherwise, prepare NSEC3PARAM RDATA that will eventually be inserted at 24400 * the zone apex, convert it to a private-type record and store the latter 24401 * in the "data" field of the nsec3param_t structure. 24402 * 24403 * Once the nsec3param_t structure is prepared, post an event to the zone's 24404 * loop which will cause setnsec3param() to be called with the prepared 24405 * structure passed as an argument. 24406 */ 24407 isc_result_t 24408 dns_zone_setnsec3param(dns_zone_t *zone, uint8_t hash, uint8_t flags, 24409 uint16_t iter, uint8_t saltlen, unsigned char *salt, 24410 bool replace, bool resalt) { 24411 isc_result_t result = ISC_R_SUCCESS; 24412 dns_rdata_nsec3param_t param, lookup; 24413 dns_rdata_t nrdata = DNS_RDATA_INIT; 24414 dns_rdata_t prdata = DNS_RDATA_INIT; 24415 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE]; 24416 unsigned char saltbuf[255]; 24417 struct np3 *npe = NULL; 24418 nsec3param_t *np = NULL; 24419 isc_buffer_t b; 24420 bool do_lookup = false; 24421 24422 REQUIRE(DNS_ZONE_VALID(zone)); 24423 24424 LOCK_ZONE(zone); 24425 24426 /* 24427 * First check if the requested NSEC3 parameters are already 24428 * set, if so, no need to set again. 24429 */ 24430 if (hash != 0) { 24431 lookup.hash = hash; 24432 lookup.flags = flags; 24433 lookup.iterations = iter; 24434 lookup.salt_length = saltlen; 24435 lookup.salt = salt; 24436 param.salt = NULL; 24437 result = dns__zone_lookup_nsec3param(zone, &lookup, ¶m, 24438 saltbuf, resalt); 24439 if (result == ISC_R_SUCCESS) { 24440 UNLOCK_ZONE(zone); 24441 return ISC_R_SUCCESS; 24442 } 24443 /* 24444 * Schedule lookup if lookup above failed (may happen if 24445 * zone db is NULL for example). 24446 */ 24447 do_lookup = (param.salt == NULL) ? true : false; 24448 } 24449 24450 npe = isc_mem_get(zone->mctx, sizeof(*npe)); 24451 *npe = (struct np3){ 24452 .link = ISC_LINK_INITIALIZER, 24453 }; 24454 24455 np = &npe->params; 24456 *np = (struct nsec3param){ 24457 .replace = replace, 24458 .resalt = resalt, 24459 .lookup = do_lookup, 24460 }; 24461 24462 if (hash == 0) { 24463 np->nsec = true; 24464 dnssec_log(zone, ISC_LOG_DEBUG(3), "setnsec3param:nsec"); 24465 } else { 24466 param.common.rdclass = zone->rdclass; 24467 param.common.rdtype = dns_rdatatype_nsec3param; 24468 ISC_LINK_INIT(¶m.common, link); 24469 param.mctx = NULL; 24470 /* 24471 * nsec3 specific param set in 24472 * dns__zone_lookup_nsec3param() 24473 */ 24474 isc_buffer_init(&b, nbuf, sizeof(nbuf)); 24475 24476 if (param.salt != NULL) { 24477 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass, 24478 dns_rdatatype_nsec3param, 24479 ¶m, &b)); 24480 dns_nsec3param_toprivate(&nrdata, &prdata, 24481 zone->privatetype, np->data, 24482 sizeof(np->data)); 24483 np->length = prdata.length; 24484 } 24485 24486 np->rdata = param; 24487 24488 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 24489 unsigned char salttext[255 * 2 + 1]; 24490 if (param.salt != NULL) { 24491 salt2text(param.salt, param.salt_length, 24492 salttext, sizeof(salttext)); 24493 } 24494 dnssec_log(zone, ISC_LOG_DEBUG(3), 24495 "setnsec3param:nsec3 %u %u %u %u:%s", 24496 param.hash, param.flags, param.iterations, 24497 param.salt_length, 24498 param.salt == NULL ? "unknown" 24499 : (char *)salttext); 24500 } 24501 } 24502 24503 /* 24504 * setnsec3param() will silently return early if the zone does 24505 * not yet have a database. Prevent that by queueing the event 24506 * up if zone->db is NULL. All events queued here are 24507 * subsequently processed by receive_secure_db() if it ever gets 24508 * called or simply freed by zone_free() otherwise. 24509 */ 24510 24511 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 24512 if (zone->db != NULL) { 24513 zone_iattach(zone, &npe->zone); 24514 isc_async_run(zone->loop, setnsec3param, npe); 24515 } else { 24516 ISC_LIST_APPEND(zone->setnsec3param_queue, npe, link); 24517 } 24518 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 24519 24520 result = ISC_R_SUCCESS; 24521 24522 cleanup: 24523 UNLOCK_ZONE(zone); 24524 return result; 24525 } 24526 24527 isc_result_t 24528 dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) { 24529 REQUIRE(DNS_ZONE_VALID(zone)); 24530 REQUIRE(loadtime != NULL); 24531 24532 LOCK_ZONE(zone); 24533 *loadtime = zone->loadtime; 24534 UNLOCK_ZONE(zone); 24535 return ISC_R_SUCCESS; 24536 } 24537 24538 isc_result_t 24539 dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) { 24540 REQUIRE(DNS_ZONE_VALID(zone)); 24541 REQUIRE(expiretime != NULL); 24542 24543 LOCK_ZONE(zone); 24544 *expiretime = zone->expiretime; 24545 UNLOCK_ZONE(zone); 24546 return ISC_R_SUCCESS; 24547 } 24548 24549 isc_result_t 24550 dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) { 24551 REQUIRE(DNS_ZONE_VALID(zone)); 24552 REQUIRE(refreshtime != NULL); 24553 24554 LOCK_ZONE(zone); 24555 *refreshtime = zone->refreshtime; 24556 UNLOCK_ZONE(zone); 24557 return ISC_R_SUCCESS; 24558 } 24559 24560 isc_result_t 24561 dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) { 24562 REQUIRE(DNS_ZONE_VALID(zone)); 24563 REQUIRE(refreshkeytime != NULL); 24564 24565 LOCK_ZONE(zone); 24566 *refreshkeytime = zone->refreshkeytime; 24567 UNLOCK_ZONE(zone); 24568 return ISC_R_SUCCESS; 24569 } 24570 24571 unsigned int 24572 dns_zone_getincludes(dns_zone_t *zone, char ***includesp) { 24573 dns_include_t *include; 24574 char **array = NULL; 24575 unsigned int n = 0; 24576 24577 REQUIRE(DNS_ZONE_VALID(zone)); 24578 REQUIRE(includesp != NULL && *includesp == NULL); 24579 24580 LOCK_ZONE(zone); 24581 if (zone->nincludes == 0) { 24582 goto done; 24583 } 24584 24585 array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes); 24586 for (include = ISC_LIST_HEAD(zone->includes); include != NULL; 24587 include = ISC_LIST_NEXT(include, link)) 24588 { 24589 INSIST(n < zone->nincludes); 24590 array[n++] = isc_mem_strdup(zone->mctx, include->name); 24591 } 24592 INSIST(n == zone->nincludes); 24593 *includesp = array; 24594 24595 done: 24596 UNLOCK_ZONE(zone); 24597 return n; 24598 } 24599 24600 void 24601 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) { 24602 REQUIRE(DNS_ZONE_VALID(zone)); 24603 24604 zone->statlevel = level; 24605 } 24606 24607 dns_zonestat_level_t 24608 dns_zone_getstatlevel(dns_zone_t *zone) { 24609 REQUIRE(DNS_ZONE_VALID(zone)); 24610 24611 return zone->statlevel; 24612 } 24613 24614 static void 24615 setserial(void *arg) { 24616 uint32_t oldserial, desired; 24617 bool commit = false; 24618 isc_result_t result; 24619 dns_dbversion_t *oldver = NULL, *newver = NULL; 24620 dns_db_t *db = NULL; 24621 dns_diff_t diff; 24622 struct setserial *sse = (struct setserial *)arg; 24623 dns_zone_t *zone = sse->zone; 24624 dns_update_log_t log = { update_log_cb, NULL }; 24625 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL; 24626 24627 INSIST(DNS_ZONE_VALID(zone)); 24628 24629 ENTER; 24630 24631 if (zone->update_disabled) { 24632 goto disabled; 24633 } 24634 24635 desired = sse->serial; 24636 24637 dns_diff_init(zone->mctx, &diff); 24638 24639 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 24640 if (zone->db != NULL) { 24641 dns_db_attach(zone->db, &db); 24642 } 24643 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 24644 if (db == NULL) { 24645 goto cleanup; 24646 } 24647 24648 dns_db_currentversion(db, &oldver); 24649 result = dns_db_newversion(db, &newver); 24650 if (result != ISC_R_SUCCESS) { 24651 dns_zone_log(zone, ISC_LOG_ERROR, 24652 "setserial:dns_db_newversion -> %s", 24653 isc_result_totext(result)); 24654 goto cleanup; 24655 } 24656 24657 CHECK(dns_db_createsoatuple(db, oldver, diff.mctx, DNS_DIFFOP_DEL, 24658 &oldtuple)); 24659 CHECK(dns_difftuple_copy(oldtuple, &newtuple)); 24660 newtuple->op = DNS_DIFFOP_ADD; 24661 24662 oldserial = dns_soa_getserial(&oldtuple->rdata); 24663 if (desired == 0U) { 24664 desired = 1; 24665 } 24666 if (!isc_serial_gt(desired, oldserial)) { 24667 if (desired != oldserial) { 24668 dns_zone_log(zone, ISC_LOG_INFO, 24669 "setserial: desired serial (%u) " 24670 "out of range (%u-%u)", 24671 desired, oldserial + 1, 24672 oldserial + 0x7fffffff); 24673 } 24674 goto cleanup; 24675 } 24676 24677 dns_soa_setserial(desired, &newtuple->rdata); 24678 CHECK(do_one_tuple(&oldtuple, db, newver, &diff)); 24679 CHECK(do_one_tuple(&newtuple, db, newver, &diff)); 24680 result = dns_update_signatures(&log, zone, db, oldver, newver, &diff, 24681 zone->sigvalidityinterval); 24682 if (result != ISC_R_NOTFOUND) { 24683 CHECK(result); 24684 } 24685 24686 /* Write changes to journal file. */ 24687 CHECK(zone_journal(zone, &diff, NULL, "setserial")); 24688 commit = true; 24689 24690 LOCK_ZONE(zone); 24691 zone_needdump(zone, 30); 24692 UNLOCK_ZONE(zone); 24693 24694 cleanup: 24695 if (oldtuple != NULL) { 24696 dns_difftuple_free(&oldtuple); 24697 } 24698 if (newtuple != NULL) { 24699 dns_difftuple_free(&newtuple); 24700 } 24701 if (oldver != NULL) { 24702 dns_db_closeversion(db, &oldver, false); 24703 } 24704 if (newver != NULL) { 24705 dns_db_closeversion(db, &newver, commit); 24706 } 24707 if (db != NULL) { 24708 dns_db_detach(&db); 24709 } 24710 dns_diff_clear(&diff); 24711 24712 disabled: 24713 isc_mem_put(zone->mctx, sse, sizeof(*sse)); 24714 dns_zone_idetach(&zone); 24715 24716 INSIST(oldver == NULL); 24717 INSIST(newver == NULL); 24718 } 24719 24720 isc_result_t 24721 dns_zone_setserial(dns_zone_t *zone, uint32_t serial) { 24722 isc_result_t result = ISC_R_SUCCESS; 24723 struct setserial *sse = NULL; 24724 24725 REQUIRE(DNS_ZONE_VALID(zone)); 24726 24727 LOCK_ZONE(zone); 24728 24729 if (!inline_secure(zone)) { 24730 if (!dns_zone_isdynamic(zone, true)) { 24731 CHECK(DNS_R_NOTDYNAMIC); 24732 } 24733 } 24734 24735 if (zone->update_disabled) { 24736 CHECK(DNS_R_FROZEN); 24737 } 24738 24739 sse = isc_mem_get(zone->mctx, sizeof(*sse)); 24740 *sse = (struct setserial){ .serial = serial }; 24741 zone_iattach(zone, &sse->zone); 24742 isc_async_run(zone->loop, setserial, sse); 24743 24744 cleanup: 24745 UNLOCK_ZONE(zone); 24746 return result; 24747 } 24748 24749 isc_stats_t * 24750 dns_zone_getgluecachestats(dns_zone_t *zone) { 24751 REQUIRE(DNS_ZONE_VALID(zone)); 24752 24753 return zone->gluecachestats; 24754 } 24755 24756 bool 24757 dns_zone_isloaded(dns_zone_t *zone) { 24758 REQUIRE(DNS_ZONE_VALID(zone)); 24759 24760 return DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED); 24761 } 24762 24763 isc_result_t 24764 dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver) { 24765 dns_dbversion_t *version = NULL; 24766 dns_keytable_t *secroots = NULL; 24767 isc_result_t result; 24768 dns_name_t *origin; 24769 24770 REQUIRE(DNS_ZONE_VALID(zone)); 24771 REQUIRE(db != NULL); 24772 24773 ENTER; 24774 24775 if (dns_zone_gettype(zone) != dns_zone_mirror) { 24776 return ISC_R_SUCCESS; 24777 } 24778 24779 if (ver == NULL) { 24780 dns_db_currentversion(db, &version); 24781 } else { 24782 version = ver; 24783 } 24784 24785 if (zone->view != NULL) { 24786 result = dns_view_getsecroots(zone->view, &secroots); 24787 CHECK(result); 24788 } 24789 24790 origin = dns_db_origin(db); 24791 result = dns_zoneverify_dnssec(zone, db, version, origin, secroots, 24792 zone->mctx, true, false, dnssec_report); 24793 24794 cleanup: 24795 if (secroots != NULL) { 24796 dns_keytable_detach(&secroots); 24797 } 24798 24799 if (ver == NULL) { 24800 dns_db_closeversion(db, &version, false); 24801 } 24802 24803 if (result != ISC_R_SUCCESS) { 24804 dnssec_log(zone, ISC_LOG_ERROR, "zone verification failed: %s", 24805 isc_result_totext(result)); 24806 result = DNS_R_VERIFYFAILURE; 24807 } 24808 24809 return result; 24810 } 24811 24812 static dns_ttl_t 24813 zone_nsecttl(dns_zone_t *zone) { 24814 REQUIRE(DNS_ZONE_VALID(zone)); 24815 24816 return ISC_MIN(zone->minimum, zone->soattl); 24817 } 24818 24819 void 24820 dns_zonemgr_set_tlsctx_cache(dns_zonemgr_t *zmgr, 24821 isc_tlsctx_cache_t *tlsctx_cache) { 24822 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 24823 REQUIRE(tlsctx_cache != NULL); 24824 24825 RWLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_write); 24826 24827 if (zmgr->tlsctx_cache != NULL) { 24828 isc_tlsctx_cache_detach(&zmgr->tlsctx_cache); 24829 } 24830 24831 isc_tlsctx_cache_attach(tlsctx_cache, &zmgr->tlsctx_cache); 24832 24833 RWUNLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_write); 24834 } 24835 24836 static void 24837 zmgr_tlsctx_attach(dns_zonemgr_t *zmgr, isc_tlsctx_cache_t **ptlsctx_cache) { 24838 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 24839 REQUIRE(ptlsctx_cache != NULL && *ptlsctx_cache == NULL); 24840 24841 RWLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_read); 24842 24843 INSIST(zmgr->tlsctx_cache != NULL); 24844 isc_tlsctx_cache_attach(zmgr->tlsctx_cache, ptlsctx_cache); 24845 24846 RWUNLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_read); 24847 } 24848 24849 isc_mem_t * 24850 dns_zone_getmem(dns_zone_t *zone) { 24851 return zone->mctx; 24852 } 24853 24854 unsigned int 24855 dns_zone_gettid(dns_zone_t *zone) { 24856 return zone->tid; 24857 } 24858 24859 isc_loop_t * 24860 dns_zone_getloop(dns_zone_t *zone) { 24861 return zone->loop; 24862 } 24863 24864 isc_result_t 24865 dns_zone_makedb(dns_zone_t *zone, dns_db_t **dbp) { 24866 REQUIRE(DNS_ZONE_VALID(zone)); 24867 REQUIRE(dbp != NULL && *dbp == NULL); 24868 24869 dns_db_t *db = NULL; 24870 24871 isc_result_t result = dns_db_create( 24872 zone->mctx, zone->db_argv[0], &zone->origin, 24873 (zone->type == dns_zone_stub) ? dns_dbtype_stub 24874 : dns_dbtype_zone, 24875 zone->rdclass, zone->db_argc - 1, zone->db_argv + 1, &db); 24876 if (result != ISC_R_SUCCESS) { 24877 return result; 24878 } 24879 24880 switch (zone->type) { 24881 case dns_zone_primary: 24882 case dns_zone_secondary: 24883 case dns_zone_mirror: 24884 result = dns_db_setgluecachestats(db, zone->gluecachestats); 24885 if (result == ISC_R_NOTIMPLEMENTED) { 24886 result = ISC_R_SUCCESS; 24887 } 24888 if (result != ISC_R_SUCCESS) { 24889 dns_db_detach(&db); 24890 return result; 24891 } 24892 break; 24893 default: 24894 break; 24895 } 24896 24897 dns_db_setloop(db, zone->loop); 24898 dns_db_setmaxrrperset(db, zone->maxrrperset); 24899 dns_db_setmaxtypepername(db, zone->maxtypepername); 24900 24901 *dbp = db; 24902 24903 return ISC_R_SUCCESS; 24904 } 24905 24906 isc_result_t 24907 dns_zone_import_skr(dns_zone_t *zone, const char *file) { 24908 dns_skr_t *skr = NULL; 24909 isc_result_t result; 24910 24911 REQUIRE(DNS_ZONE_VALID(zone)); 24912 REQUIRE(zone->kasp != NULL); 24913 REQUIRE(file != NULL); 24914 24915 dns_skr_create(zone->mctx, file, &zone->origin, zone->rdclass, &skr); 24916 24917 CHECK(dns_skr_read(zone->mctx, file, &zone->origin, zone->rdclass, 24918 dns_kasp_dnskeyttl(zone->kasp), &skr)); 24919 24920 dns_zone_setskr(zone, skr); 24921 dnssec_log(zone, ISC_LOG_DEBUG(1), "imported skr file %s", file); 24922 24923 cleanup: 24924 dns_skr_detach(&skr); 24925 24926 return result; 24927 } 24928