1/* $NetBSD: zone.c,v 1.1 2024/02/18 20:57:34 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/atomic.h> 23#include <isc/file.h> 24#include <isc/hex.h> 25#include <isc/md.h> 26#include <isc/mutex.h> 27#include <isc/pool.h> 28#include <isc/print.h> 29#include <isc/random.h> 30#include <isc/ratelimiter.h> 31#include <isc/refcount.h> 32#include <isc/rwlock.h> 33#include <isc/serial.h> 34#include <isc/stats.h> 35#include <isc/stdtime.h> 36#include <isc/strerr.h> 37#include <isc/string.h> 38#include <isc/taskpool.h> 39#include <isc/thread.h> 40#include <isc/timer.h> 41#include <isc/util.h> 42 43#include <dns/acl.h> 44#include <dns/adb.h> 45#include <dns/callbacks.h> 46#include <dns/catz.h> 47#include <dns/db.h> 48#include <dns/dbiterator.h> 49#include <dns/dlz.h> 50#include <dns/dnssec.h> 51#include <dns/events.h> 52#include <dns/journal.h> 53#include <dns/kasp.h> 54#include <dns/keydata.h> 55#include <dns/keymgr.h> 56#include <dns/keytable.h> 57#include <dns/keyvalues.h> 58#include <dns/log.h> 59#include <dns/master.h> 60#include <dns/masterdump.h> 61#include <dns/message.h> 62#include <dns/name.h> 63#include <dns/nsec.h> 64#include <dns/nsec3.h> 65#include <dns/opcode.h> 66#include <dns/peer.h> 67#include <dns/private.h> 68#include <dns/rcode.h> 69#include <dns/rdata.h> 70#include <dns/rdataclass.h> 71#include <dns/rdatalist.h> 72#include <dns/rdataset.h> 73#include <dns/rdatasetiter.h> 74#include <dns/rdatastruct.h> 75#include <dns/rdatatype.h> 76#include <dns/request.h> 77#include <dns/resolver.h> 78#include <dns/result.h> 79#include <dns/rriterator.h> 80#include <dns/soa.h> 81#include <dns/ssu.h> 82#include <dns/stats.h> 83#include <dns/time.h> 84#include <dns/tsig.h> 85#include <dns/update.h> 86#include <dns/xfrin.h> 87#include <dns/zone.h> 88#include <dns/zoneverify.h> 89#include <dns/zt.h> 90 91#include <dst/dst.h> 92 93#include "zone_p.h" 94 95#define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E') 96#define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC) 97 98#define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y') 99#define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC) 100 101#define CHECKDS_MAGIC ISC_MAGIC('C', 'h', 'D', 'S') 102#define DNS_CHECKDS_VALID(checkds) ISC_MAGIC_VALID(checkds, CHECKDS_MAGIC) 103 104#define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b') 105#define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC) 106 107#define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r') 108#define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC) 109 110#define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd') 111#define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC) 112 113#define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w') 114#define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC) 115 116#define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O') 117#define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC) 118 119#define KEYMGMT_MAGIC ISC_MAGIC('M', 'g', 'm', 't') 120#define DNS_KEYMGMT_VALID(load) ISC_MAGIC_VALID(load, KEYMGMT_MAGIC) 121 122#define KEYFILEIO_MAGIC ISC_MAGIC('K', 'y', 'I', 'O') 123#define DNS_KEYFILEIO_VALID(kfio) ISC_MAGIC_VALID(kfio, KEYFILEIO_MAGIC) 124 125/*% 126 * Ensure 'a' is at least 'min' but not more than 'max'. 127 */ 128#define RANGE(a, min, max) (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max))) 129 130#define NSEC3REMOVE(x) (((x)&DNS_NSEC3FLAG_REMOVE) != 0) 131 132/*% 133 * Key flags 134 */ 135#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0) 136#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0) 137#define ID(x) dst_key_id(x) 138#define ALG(x) dst_key_alg(x) 139 140/*% 141 * KASP flags 142 */ 143#define KASP_LOCK(k) \ 144 if ((k) != NULL) { \ 145 LOCK((&((k)->lock))); \ 146 } 147 148#define KASP_UNLOCK(k) \ 149 if ((k) != NULL) { \ 150 UNLOCK((&((k)->lock))); \ 151 } 152 153/* 154 * Default values. 155 */ 156#define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */ 157#define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */ 158#define MAX_XFER_TIME (2 * 3600) /*%< Documented default is 2 hours */ 159#define RESIGN_DELAY 3600 /*%< 1 hour */ 160 161#ifndef DNS_MAX_EXPIRE 162#define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */ 163#endif /* ifndef DNS_MAX_EXPIRE */ 164 165#ifndef DNS_DUMP_DELAY 166#define DNS_DUMP_DELAY 900 /*%< 15 minutes */ 167#endif /* ifndef DNS_DUMP_DELAY */ 168 169typedef struct dns_notify dns_notify_t; 170typedef struct dns_checkds dns_checkds_t; 171typedef struct dns_stub dns_stub_t; 172typedef struct dns_load dns_load_t; 173typedef struct dns_forward dns_forward_t; 174typedef ISC_LIST(dns_forward_t) dns_forwardlist_t; 175typedef struct dns_io dns_io_t; 176typedef ISC_LIST(dns_io_t) dns_iolist_t; 177typedef struct dns_keymgmt dns_keymgmt_t; 178typedef struct dns_signing dns_signing_t; 179typedef ISC_LIST(dns_signing_t) dns_signinglist_t; 180typedef struct dns_nsec3chain dns_nsec3chain_t; 181typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t; 182typedef struct dns_keyfetch dns_keyfetch_t; 183typedef struct dns_asyncload dns_asyncload_t; 184typedef struct dns_include dns_include_t; 185 186#define DNS_ZONE_CHECKLOCK 187#ifdef DNS_ZONE_CHECKLOCK 188#define LOCK_ZONE(z) \ 189 do { \ 190 LOCK(&(z)->lock); \ 191 INSIST(!(z)->locked); \ 192 (z)->locked = true; \ 193 } while (0) 194#define UNLOCK_ZONE(z) \ 195 do { \ 196 (z)->locked = false; \ 197 UNLOCK(&(z)->lock); \ 198 } while (0) 199#define LOCKED_ZONE(z) ((z)->locked) 200#define TRYLOCK_ZONE(result, z) \ 201 do { \ 202 result = isc_mutex_trylock(&(z)->lock); \ 203 if (result == ISC_R_SUCCESS) { \ 204 INSIST(!(z)->locked); \ 205 (z)->locked = true; \ 206 } \ 207 } while (0) 208#else /* ifdef DNS_ZONE_CHECKLOCK */ 209#define LOCK_ZONE(z) LOCK(&(z)->lock) 210#define UNLOCK_ZONE(z) UNLOCK(&(z)->lock) 211#define LOCKED_ZONE(z) true 212#define TRYLOCK_ZONE(result, z) \ 213 do { \ 214 result = isc_mutex_trylock(&(z)->lock); \ 215 } while (0) 216#endif /* ifdef DNS_ZONE_CHECKLOCK */ 217 218#define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0) 219#define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l) 220#define ZONEDB_LOCK(l, t) RWLOCK((l), (t)) 221#define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t)) 222 223#ifdef ENABLE_AFL 224extern bool dns_fuzzing_resolver; 225#endif /* ifdef ENABLE_AFL */ 226 227/*% 228 * Hold key file IO locks. 229 */ 230typedef struct dns_keyfileio { 231 unsigned int magic; 232 struct dns_keyfileio *next; 233 uint32_t hashval; 234 dns_fixedname_t fname; 235 dns_name_t *name; 236 isc_refcount_t references; 237 isc_mutex_t lock; 238} dns_keyfileio_t; 239 240struct dns_keymgmt { 241 unsigned int magic; 242 isc_rwlock_t lock; 243 isc_mem_t *mctx; 244 245 dns_keyfileio_t **table; 246 247 atomic_uint_fast32_t count; 248 249 uint32_t bits; 250}; 251 252struct dns_zone { 253 /* Unlocked */ 254 unsigned int magic; 255 isc_mutex_t lock; 256#ifdef DNS_ZONE_CHECKLOCK 257 bool locked; 258#endif /* ifdef DNS_ZONE_CHECKLOCK */ 259 isc_mem_t *mctx; 260 isc_refcount_t erefs; 261 262 isc_rwlock_t dblock; 263 dns_db_t *db; /* Locked by dblock */ 264 265 /* Locked */ 266 dns_zonemgr_t *zmgr; 267 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */ 268 isc_timer_t *timer; 269 isc_refcount_t irefs; 270 dns_name_t origin; 271 char *masterfile; 272 ISC_LIST(dns_include_t) includes; /* Include files */ 273 ISC_LIST(dns_include_t) newincludes; /* Loading */ 274 unsigned int nincludes; 275 dns_masterformat_t masterformat; 276 const dns_master_style_t *masterstyle; 277 char *journal; 278 int32_t journalsize; 279 dns_rdataclass_t rdclass; 280 dns_zonetype_t type; 281#ifdef __NetBSD__ 282 atomic_uint_fast32_t flags; 283 atomic_uint_fast32_t options; 284#else 285 atomic_uint_fast64_t flags; 286 atomic_uint_fast64_t options; 287#endif 288 unsigned int db_argc; 289 char **db_argv; 290 isc_time_t expiretime; 291 isc_time_t refreshtime; 292 isc_time_t dumptime; 293 isc_time_t loadtime; 294 isc_time_t notifytime; 295 isc_time_t resigntime; 296 isc_time_t keywarntime; 297 isc_time_t signingtime; 298 isc_time_t nsec3chaintime; 299 isc_time_t refreshkeytime; 300 uint32_t refreshkeyinterval; 301 uint32_t refreshkeycount; 302 uint32_t refresh; 303 uint32_t retry; 304 uint32_t expire; 305 uint32_t minimum; 306 isc_stdtime_t key_expiry; 307 isc_stdtime_t log_key_expired_timer; 308 char *keydirectory; 309 dns_keyfileio_t *kfio; 310 311 uint32_t maxrefresh; 312 uint32_t minrefresh; 313 uint32_t maxretry; 314 uint32_t minretry; 315 316 uint32_t maxrecords; 317 318 isc_sockaddr_t *masters; 319 isc_dscp_t *masterdscps; 320 dns_name_t **masterkeynames; 321 bool *mastersok; 322 unsigned int masterscnt; 323 unsigned int curmaster; 324 isc_sockaddr_t masteraddr; 325 326 isc_sockaddr_t *parentals; 327 isc_dscp_t *parentaldscps; 328 dns_name_t **parentalkeynames; 329 dns_dnsseckeylist_t checkds_ok; 330 unsigned int parentalscnt; 331 isc_sockaddr_t parentaladdr; 332 333 dns_notifytype_t notifytype; 334 isc_sockaddr_t *notify; 335 dns_name_t **notifykeynames; 336 isc_dscp_t *notifydscp; 337 unsigned int notifycnt; 338 isc_sockaddr_t notifyfrom; 339 isc_task_t *task; 340 isc_task_t *loadtask; 341 isc_sockaddr_t notifysrc4; 342 isc_sockaddr_t notifysrc6; 343 isc_sockaddr_t parentalsrc4; 344 isc_sockaddr_t parentalsrc6; 345 isc_sockaddr_t xfrsource4; 346 isc_sockaddr_t xfrsource6; 347 isc_sockaddr_t altxfrsource4; 348 isc_sockaddr_t altxfrsource6; 349 isc_sockaddr_t sourceaddr; 350 isc_dscp_t notifysrc4dscp; 351 isc_dscp_t notifysrc6dscp; 352 isc_dscp_t parentalsrc4dscp; 353 isc_dscp_t parentalsrc6dscp; 354 isc_dscp_t xfrsource4dscp; 355 isc_dscp_t xfrsource6dscp; 356 isc_dscp_t altxfrsource4dscp; 357 isc_dscp_t altxfrsource6dscp; 358 dns_xfrin_ctx_t *xfr; /* task locked */ 359 dns_tsigkey_t *tsigkey; /* key used for xfr */ 360 /* Access Control Lists */ 361 dns_acl_t *update_acl; 362 dns_acl_t *forward_acl; 363 dns_acl_t *notify_acl; 364 dns_acl_t *query_acl; 365 dns_acl_t *queryon_acl; 366 dns_acl_t *xfr_acl; 367 bool update_disabled; 368 bool zero_no_soa_ttl; 369 dns_severity_t check_names; 370 ISC_LIST(dns_notify_t) notifies; 371 ISC_LIST(dns_checkds_t) checkds_requests; 372 dns_request_t *request; 373 dns_loadctx_t *lctx; 374 dns_io_t *readio; 375 dns_dumpctx_t *dctx; 376 dns_io_t *writeio; 377 uint32_t maxxfrin; 378 uint32_t maxxfrout; 379 uint32_t idlein; 380 uint32_t idleout; 381 isc_event_t ctlevent; 382 dns_ssutable_t *ssutable; 383 uint32_t sigvalidityinterval; 384 uint32_t keyvalidityinterval; 385 uint32_t sigresigninginterval; 386 dns_view_t *view; 387 dns_view_t *prev_view; 388 dns_kasp_t *kasp; 389 dns_checkmxfunc_t checkmx; 390 dns_checksrvfunc_t checksrv; 391 dns_checknsfunc_t checkns; 392 /*% 393 * Zones in certain states such as "waiting for zone transfer" 394 * or "zone transfer in progress" are kept on per-state linked lists 395 * in the zone manager using the 'statelink' field. The 'statelist' 396 * field points at the list the zone is currently on. It the zone 397 * is not on any such list, statelist is NULL. 398 */ 399 ISC_LINK(dns_zone_t) statelink; 400 dns_zonelist_t *statelist; 401 /*% 402 * Statistics counters about zone management. 403 */ 404 isc_stats_t *stats; 405 /*% 406 * Optional per-zone statistics counters. Counted outside of this 407 * module. 408 */ 409 dns_zonestat_level_t statlevel; 410 bool requeststats_on; 411 isc_stats_t *requeststats; 412 dns_stats_t *rcvquerystats; 413 dns_stats_t *dnssecsignstats; 414 uint32_t notifydelay; 415 dns_isselffunc_t isself; 416 void *isselfarg; 417 418 char *strnamerd; 419 char *strname; 420 char *strrdclass; 421 char *strviewname; 422 423 /*% 424 * Serial number for deferred journal compaction. 425 */ 426 uint32_t compact_serial; 427 /*% 428 * Keys that are signing the zone for the first time. 429 */ 430 dns_signinglist_t signing; 431 dns_nsec3chainlist_t nsec3chain; 432 /*% 433 * List of outstanding NSEC3PARAM change requests. 434 */ 435 isc_eventlist_t setnsec3param_queue; 436 /*% 437 * Signing / re-signing quantum stopping parameters. 438 */ 439 uint32_t signatures; 440 uint32_t nodes; 441 dns_rdatatype_t privatetype; 442 443 /*% 444 * Autosigning/key-maintenance options 445 */ 446#ifdef __NetBSD__ 447 atomic_uint_fast32_t keyopts; 448#else 449 atomic_uint_fast64_t keyopts; 450#endif 451 452 /*% 453 * True if added by "rndc addzone" 454 */ 455 bool added; 456 457 /*% 458 * True if added by automatically by named. 459 */ 460 bool automatic; 461 462 /*% 463 * response policy data to be relayed to the database 464 */ 465 dns_rpz_zones_t *rpzs; 466 dns_rpz_num_t rpz_num; 467 468 /*% 469 * catalog zone data 470 */ 471 dns_catz_zones_t *catzs; 472 473 /*% 474 * parent catalog zone 475 */ 476 dns_catz_zone_t *parentcatz; 477 478 /*% 479 * Serial number update method. 480 */ 481 dns_updatemethod_t updatemethod; 482 483 /*% 484 * whether ixfr is requested 485 */ 486 bool requestixfr; 487 uint32_t ixfr_ratio; 488 489 /*% 490 * whether EDNS EXPIRE is requested 491 */ 492 bool requestexpire; 493 494 /*% 495 * Outstanding forwarded UPDATE requests. 496 */ 497 dns_forwardlist_t forwards; 498 499 dns_zone_t *raw; 500 dns_zone_t *secure; 501 502 bool sourceserialset; 503 uint32_t sourceserial; 504 505 /*% 506 * soa and maximum zone ttl 507 */ 508 dns_ttl_t soattl; 509 dns_ttl_t maxttl; 510 511 /* 512 * Inline zone signing state. 513 */ 514 dns_diff_t rss_diff; 515 isc_eventlist_t rss_events; 516 isc_eventlist_t rss_post; 517 dns_dbversion_t *rss_newver; 518 dns_dbversion_t *rss_oldver; 519 dns_db_t *rss_db; 520 dns_zone_t *rss_raw; 521 isc_event_t *rss_event; 522 dns_update_state_t *rss_state; 523 524 isc_stats_t *gluecachestats; 525}; 526 527#define zonediff_init(z, d) \ 528 do { \ 529 dns__zonediff_t *_z = (z); \ 530 (_z)->diff = (d); \ 531 (_z)->offline = false; \ 532 } while (0) 533 534#define DNS_ZONE_FLAG(z, f) ((atomic_load_relaxed(&(z)->flags) & (f)) != 0) 535#define DNS_ZONE_SETFLAG(z, f) atomic_fetch_or(&(z)->flags, (f)) 536#define DNS_ZONE_CLRFLAG(z, f) atomic_fetch_and(&(z)->flags, ~(f)) 537typedef enum { 538 DNS_ZONEFLG_REFRESH = 0x00000001U, /*%< refresh check in progress */ 539 DNS_ZONEFLG_NEEDDUMP = 0x00000002U, /*%< zone need consolidation */ 540 DNS_ZONEFLG_USEVC = 0x00000004U, /*%< use tcp for refresh query */ 541 DNS_ZONEFLG_DUMPING = 0x00000008U, /*%< a dump is in progress */ 542 DNS_ZONEFLG_HASINCLUDE = 0x00000010U, /*%< $INCLUDE in zone file */ 543 DNS_ZONEFLG_LOADED = 0x00000020U, /*%< database has loaded */ 544 DNS_ZONEFLG_EXITING = 0x00000040U, /*%< zone is being destroyed */ 545 DNS_ZONEFLG_EXPIRED = 0x00000080U, /*%< zone has expired */ 546 DNS_ZONEFLG_NEEDREFRESH = 0x00000100U, /*%< refresh check needed */ 547 DNS_ZONEFLG_UPTODATE = 0x00000200U, /*%< zone contents are 548 * up-to-date */ 549 DNS_ZONEFLG_NEEDNOTIFY = 0x00000400U, /*%< need to send out notify 550 * messages */ 551 DNS_ZONEFLG_FIXJOURNAL = 0x00000800U, /*%< journal file had 552 * recoverable error, 553 * needs rewriting */ 554 DNS_ZONEFLG_NOMASTERS = 0x00001000U, /*%< an attempt to refresh a 555 * zone with no primaries 556 * occurred */ 557 DNS_ZONEFLG_LOADING = 0x00002000U, /*%< load from disk in progress*/ 558 DNS_ZONEFLG_HAVETIMERS = 0x00004000U, /*%< timer values have been set 559 * from SOA (if not set, we 560 * are still using 561 * default timer values) */ 562 DNS_ZONEFLG_FORCEXFER = 0x00008000U, /*%< Force a zone xfer */ 563 DNS_ZONEFLG_NOREFRESH = 0x00010000U, 564 DNS_ZONEFLG_DIALNOTIFY = 0x00020000U, 565 DNS_ZONEFLG_DIALREFRESH = 0x00040000U, 566 DNS_ZONEFLG_SHUTDOWN = 0x00080000U, 567 DNS_ZONEFLG_NOIXFR = 0x00100000U, /*%< IXFR failed, force AXFR */ 568 DNS_ZONEFLG_FLUSH = 0x00200000U, 569 DNS_ZONEFLG_NOEDNS = 0x00400000U, 570 DNS_ZONEFLG_USEALTXFRSRC = 0x00800000U, 571 DNS_ZONEFLG_SOABEFOREAXFR = 0x01000000U, 572 DNS_ZONEFLG_NEEDCOMPACT = 0x02000000U, 573 DNS_ZONEFLG_REFRESHING = 0x04000000U, /*%< Refreshing keydata */ 574 DNS_ZONEFLG_THAW = 0x08000000U, 575 DNS_ZONEFLG_LOADPENDING = 0x10000000U, /*%< Loading scheduled */ 576 DNS_ZONEFLG_NODELAY = 0x20000000U, 577 DNS_ZONEFLG_SENDSECURE = 0x40000000U, 578 DNS_ZONEFLG_NEEDSTARTUPNOTIFY = 0x80000000U, /*%< need to send out 579 * notify due to the zone 580 * just being loaded for 581 * the first time. */ 582#ifndef __NetBSD__ 583 /* 584 * DO NOT add any new zone flags here until all platforms 585 * support 64-bit enum values. Currently they fail on 586 * Windows. 587 */ 588 DNS_ZONEFLG___MAX = UINT64_MAX, /* trick to make the ENUM 64-bit wide */ 589#endif 590} dns_zoneflg_t; 591 592#define DNS_ZONE_OPTION(z, o) ((atomic_load_relaxed(&(z)->options) & (o)) != 0) 593#define DNS_ZONE_SETOPTION(z, o) atomic_fetch_or(&(z)->options, (o)) 594#define DNS_ZONE_CLROPTION(z, o) atomic_fetch_and(&(z)->options, ~(o)) 595 596#define DNS_ZONEKEY_OPTION(z, o) \ 597 ((atomic_load_relaxed(&(z)->keyopts) & (o)) != 0) 598#define DNS_ZONEKEY_SETOPTION(z, o) atomic_fetch_or(&(z)->keyopts, (o)) 599#define DNS_ZONEKEY_CLROPTION(z, o) atomic_fetch_and(&(z)->keyopts, ~(o)) 600 601/* Flags for zone_load() */ 602typedef enum { 603 DNS_ZONELOADFLAG_NOSTAT = 0x00000001U, /* Do not stat() master files */ 604 DNS_ZONELOADFLAG_THAW = 0x00000002U, /* Thaw the zone on successful 605 * load. */ 606} dns_zoneloadflag_t; 607 608#define UNREACH_CACHE_SIZE 10U 609#define UNREACH_HOLD_TIME 600 /* 10 minutes */ 610 611#define CHECK(op) \ 612 do { \ 613 result = (op); \ 614 if (result != ISC_R_SUCCESS) \ 615 goto failure; \ 616 } while (0) 617 618struct dns_unreachable { 619 isc_sockaddr_t remote; 620 isc_sockaddr_t local; 621 atomic_uint_fast32_t expire; 622 atomic_uint_fast32_t last; 623 uint32_t count; 624}; 625 626struct dns_zonemgr { 627 unsigned int magic; 628 isc_mem_t *mctx; 629 isc_refcount_t refs; 630 isc_taskmgr_t *taskmgr; 631 isc_timermgr_t *timermgr; 632 isc_socketmgr_t *socketmgr; 633 isc_taskpool_t *zonetasks; 634 isc_taskpool_t *loadtasks; 635 isc_task_t *task; 636 isc_pool_t *mctxpool; 637 isc_ratelimiter_t *checkdsrl; 638 isc_ratelimiter_t *notifyrl; 639 isc_ratelimiter_t *refreshrl; 640 isc_ratelimiter_t *startupnotifyrl; 641 isc_ratelimiter_t *startuprefreshrl; 642 isc_rwlock_t rwlock; 643 isc_mutex_t iolock; 644 isc_rwlock_t urlock; 645 646 /* Locked by rwlock. */ 647 dns_zonelist_t zones; 648 dns_zonelist_t waiting_for_xfrin; 649 dns_zonelist_t xfrin_in_progress; 650 651 /* Configuration data. */ 652 uint32_t transfersin; 653 uint32_t transfersperns; 654 unsigned int checkdsrate; 655 unsigned int notifyrate; 656 unsigned int startupnotifyrate; 657 unsigned int serialqueryrate; 658 unsigned int startupserialqueryrate; 659 660 /* Locked by iolock */ 661 uint32_t iolimit; 662 uint32_t ioactive; 663 dns_iolist_t high; 664 dns_iolist_t low; 665 666 /* Locked by urlock. */ 667 /* LRU cache */ 668 struct dns_unreachable unreachable[UNREACH_CACHE_SIZE]; 669 670 dns_keymgmt_t *keymgmt; 671}; 672 673/*% 674 * Hold notify state. 675 */ 676struct dns_notify { 677 unsigned int magic; 678 unsigned int flags; 679 isc_mem_t *mctx; 680 dns_zone_t *zone; 681 dns_adbfind_t *find; 682 dns_request_t *request; 683 dns_name_t ns; 684 isc_sockaddr_t dst; 685 dns_tsigkey_t *key; 686 isc_dscp_t dscp; 687 ISC_LINK(dns_notify_t) link; 688 isc_event_t *event; 689}; 690 691#define DNS_NOTIFY_NOSOA 0x0001U 692#define DNS_NOTIFY_STARTUP 0x0002U 693 694/*% 695 * Hold checkds state. 696 */ 697struct dns_checkds { 698 unsigned int magic; 699 unsigned int flags; 700 isc_mem_t *mctx; 701 dns_zone_t *zone; 702 dns_request_t *request; 703 isc_sockaddr_t dst; 704 dns_tsigkey_t *key; 705 isc_dscp_t dscp; 706 ISC_LINK(dns_checkds_t) link; 707 isc_event_t *event; 708}; 709 710/*% 711 * dns_stub holds state while performing a 'stub' transfer. 712 * 'db' is the zone's 'db' or a new one if this is the initial 713 * transfer. 714 */ 715 716struct dns_stub { 717 unsigned int magic; 718 isc_mem_t *mctx; 719 dns_zone_t *zone; 720 dns_db_t *db; 721 dns_dbversion_t *version; 722 atomic_uint_fast32_t pending_requests; 723}; 724 725/*% 726 * Hold load state. 727 */ 728struct dns_load { 729 unsigned int magic; 730 isc_mem_t *mctx; 731 dns_zone_t *zone; 732 dns_db_t *db; 733 isc_time_t loadtime; 734 dns_rdatacallbacks_t callbacks; 735}; 736 737/*% 738 * Hold forward state. 739 */ 740struct dns_forward { 741 unsigned int magic; 742 isc_mem_t *mctx; 743 dns_zone_t *zone; 744 isc_buffer_t *msgbuf; 745 dns_request_t *request; 746 uint32_t which; 747 isc_sockaddr_t addr; 748 dns_updatecallback_t callback; 749 void *callback_arg; 750 unsigned int options; 751 ISC_LINK(dns_forward_t) link; 752}; 753 754/*% 755 * Hold IO request state. 756 */ 757struct dns_io { 758 unsigned int magic; 759 dns_zonemgr_t *zmgr; 760 bool high; 761 isc_task_t *task; 762 ISC_LINK(dns_io_t) link; 763 isc_event_t *event; 764}; 765 766/*% 767 * Hold state for when we are signing a zone with a new 768 * DNSKEY as result of an update. 769 */ 770struct dns_signing { 771 unsigned int magic; 772 dns_db_t *db; 773 dns_dbiterator_t *dbiterator; 774 dns_secalg_t algorithm; 775 uint16_t keyid; 776 bool deleteit; 777 bool done; 778 ISC_LINK(dns_signing_t) link; 779}; 780 781struct dns_nsec3chain { 782 unsigned int magic; 783 dns_db_t *db; 784 dns_dbiterator_t *dbiterator; 785 dns_rdata_nsec3param_t nsec3param; 786 unsigned char salt[255]; 787 bool done; 788 bool seen_nsec; 789 bool delete_nsec; 790 bool save_delete_nsec; 791 ISC_LINK(dns_nsec3chain_t) link; 792}; 793 794/*%< 795 * 'dbiterator' contains a iterator for the database. If we are creating 796 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are 797 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be 798 * iterated. 799 * 800 * 'nsec3param' contains the parameters of the NSEC3 chain being created 801 * or removed. 802 * 803 * 'salt' is buffer space and is referenced via 'nsec3param.salt'. 804 * 805 * 'seen_nsec' will be set to true if, while iterating the zone to create a 806 * NSEC3 chain, a NSEC record is seen. 807 * 808 * 'delete_nsec' will be set to true if, at the completion of the creation 809 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we 810 * are in the process of deleting the NSEC chain. 811 * 812 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec' 813 * so it can be recovered in the event of a error. 814 */ 815 816struct dns_keyfetch { 817 isc_mem_t *mctx; 818 dns_fixedname_t name; 819 dns_rdataset_t keydataset; 820 dns_rdataset_t dnskeyset; 821 dns_rdataset_t dnskeysigset; 822 dns_zone_t *zone; 823 dns_db_t *db; 824 dns_fetch_t *fetch; 825}; 826 827/*% 828 * Hold state for an asynchronous load 829 */ 830struct dns_asyncload { 831 dns_zone_t *zone; 832 unsigned int flags; 833 dns_zt_zoneloaded_t loaded; 834 void *loaded_arg; 835}; 836 837/*% 838 * Reference to an include file encountered during loading 839 */ 840struct dns_include { 841 char *name; 842 isc_time_t filetime; 843 ISC_LINK(dns_include_t) link; 844}; 845 846/* 847 * These can be overridden by the -T mkeytimers option on the command 848 * line, so that we can test with shorter periods than specified in 849 * RFC 5011. 850 */ 851#define HOUR 3600 852#define DAY (24 * HOUR) 853#define MONTH (30 * DAY) 854LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_hour = HOUR; 855LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_day = DAY; 856LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_month = MONTH; 857 858#define SEND_BUFFER_SIZE 2048 859 860static void 861zone_settimer(dns_zone_t *, isc_time_t *); 862static void 863cancel_refresh(dns_zone_t *); 864static void 865zone_debuglog(dns_zone_t *zone, const char *, int debuglevel, const char *msg, 866 ...) ISC_FORMAT_PRINTF(4, 5); 867static void 868notify_log(dns_zone_t *zone, int level, const char *fmt, ...) 869 ISC_FORMAT_PRINTF(3, 4); 870static void 871dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...) 872 ISC_FORMAT_PRINTF(3, 4); 873static void 874queue_xfrin(dns_zone_t *zone); 875static isc_result_t 876update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 877 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, 878 dns_rdata_t *rdata); 879static void 880zone_unload(dns_zone_t *zone); 881static void 882zone_expire(dns_zone_t *zone); 883static void 884zone_iattach(dns_zone_t *source, dns_zone_t **target); 885static void 886zone_idetach(dns_zone_t **zonep); 887static isc_result_t 888zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump); 889static void 890zone_attachdb(dns_zone_t *zone, dns_db_t *db); 891static void 892zone_detachdb(dns_zone_t *zone); 893static void 894zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs); 895static void 896zone_catz_disable(dns_zone_t *zone); 897static isc_result_t 898default_journal(dns_zone_t *zone); 899static void 900zone_xfrdone(dns_zone_t *zone, isc_result_t result); 901static isc_result_t 902zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, 903 isc_result_t result); 904static void 905zone_needdump(dns_zone_t *zone, unsigned int delay); 906static void 907zone_shutdown(isc_task_t *, isc_event_t *); 908static void 909zone_loaddone(void *arg, isc_result_t result); 910static isc_result_t 911zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime); 912static void 913zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length); 914static void 915zone_name_tostr(dns_zone_t *zone, char *buf, size_t length); 916static void 917zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length); 918static void 919zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length); 920static isc_result_t 921zone_send_secureserial(dns_zone_t *zone, uint32_t serial); 922static void 923refresh_callback(isc_task_t *, isc_event_t *); 924static void 925stub_callback(isc_task_t *, isc_event_t *); 926static void 927queue_soa_query(dns_zone_t *zone); 928static void 929soa_query(isc_task_t *, isc_event_t *); 930static void 931ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub); 932static int 933message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type); 934static void 935checkds_cancel(dns_zone_t *zone); 936static void 937checkds_send(dns_zone_t *zone); 938static isc_result_t 939checkds_createmessage(dns_zone_t *zone, dns_message_t **messagep); 940static void 941checkds_done(isc_task_t *task, isc_event_t *event); 942static void 943checkds_send_toaddr(isc_task_t *task, isc_event_t *event); 944static void 945notify_cancel(dns_zone_t *zone); 946static void 947notify_find_address(dns_notify_t *notify); 948static void 949notify_send(dns_notify_t *notify); 950static isc_result_t 951notify_createmessage(dns_zone_t *zone, unsigned int flags, 952 dns_message_t **messagep); 953static void 954notify_done(isc_task_t *task, isc_event_t *event); 955static void 956notify_send_toaddr(isc_task_t *task, isc_event_t *event); 957static isc_result_t 958zone_dump(dns_zone_t *, bool); 959static void 960got_transfer_quota(isc_task_t *task, isc_event_t *event); 961static isc_result_t 962zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone); 963static void 964zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi); 965static void 966zonemgr_free(dns_zonemgr_t *zmgr); 967static isc_result_t 968zonemgr_getio(dns_zonemgr_t *zmgr, bool high, isc_task_t *task, 969 isc_taskaction_t action, void *arg, dns_io_t **iop); 970static void 971zonemgr_putio(dns_io_t **iop); 972static void 973zonemgr_cancelio(dns_io_t *io); 974static void 975rss_post(dns_zone_t *, isc_event_t *); 976 977static isc_result_t 978zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 979 unsigned int *soacount, uint32_t *soattl, uint32_t *serial, 980 uint32_t *refresh, uint32_t *retry, uint32_t *expire, 981 uint32_t *minimum, unsigned int *errors); 982 983static void 984zone_freedbargs(dns_zone_t *zone); 985static void 986forward_callback(isc_task_t *task, isc_event_t *event); 987static void 988zone_saveunique(dns_zone_t *zone, const char *path, const char *templat); 989static void 990zone_maintenance(dns_zone_t *zone); 991static void 992zone_notify(dns_zone_t *zone, isc_time_t *now); 993static void 994dump_done(void *arg, isc_result_t result); 995static isc_result_t 996zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid, 997 bool deleteit); 998static isc_result_t 999delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 1000 dns_name_t *name, dns_diff_t *diff); 1001static void 1002zone_rekey(dns_zone_t *zone); 1003static isc_result_t 1004zone_send_securedb(dns_zone_t *zone, dns_db_t *db); 1005static dns_ttl_t 1006zone_nsecttl(dns_zone_t *zone); 1007static void 1008setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value); 1009static void 1010zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial); 1011static isc_result_t 1012zone_journal_rollforward(dns_zone_t *zone, dns_db_t *db, bool *needdump, 1013 bool *fixjournal); 1014 1015#define ENTER zone_debuglog(zone, me, 1, "enter") 1016 1017static const unsigned int dbargc_default = 1; 1018static const char *dbargv_default[] = { "rbt" }; 1019 1020#define DNS_ZONE_JITTER_ADD(a, b, c) \ 1021 do { \ 1022 isc_interval_t _i; \ 1023 uint32_t _j; \ 1024 _j = (b)-isc_random_uniform((b) / 4); \ 1025 isc_interval_set(&_i, _j, 0); \ 1026 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 1027 dns_zone_log(zone, ISC_LOG_WARNING, \ 1028 "epoch approaching: upgrade required: " \ 1029 "now + %s failed", \ 1030 #b); \ 1031 isc_interval_set(&_i, _j / 2, 0); \ 1032 (void)isc_time_add((a), &_i, (c)); \ 1033 } \ 1034 } while (0) 1035 1036#define DNS_ZONE_TIME_ADD(a, b, c) \ 1037 do { \ 1038 isc_interval_t _i; \ 1039 isc_interval_set(&_i, (b), 0); \ 1040 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 1041 dns_zone_log(zone, ISC_LOG_WARNING, \ 1042 "epoch approaching: upgrade required: " \ 1043 "now + %s failed", \ 1044 #b); \ 1045 isc_interval_set(&_i, (b) / 2, 0); \ 1046 (void)isc_time_add((a), &_i, (c)); \ 1047 } \ 1048 } while (0) 1049 1050typedef struct nsec3param nsec3param_t; 1051struct nsec3param { 1052 dns_rdata_nsec3param_t rdata; 1053 unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1]; 1054 unsigned int length; 1055 bool nsec; 1056 bool replace; 1057 bool resalt; 1058 bool lookup; 1059 ISC_LINK(nsec3param_t) link; 1060}; 1061typedef ISC_LIST(nsec3param_t) nsec3paramlist_t; 1062struct np3event { 1063 isc_event_t event; 1064 nsec3param_t params; 1065}; 1066 1067struct ssevent { 1068 isc_event_t event; 1069 uint32_t serial; 1070}; 1071 1072struct stub_cb_args { 1073 dns_stub_t *stub; 1074 dns_tsigkey_t *tsig_key; 1075 isc_dscp_t dscp; 1076 uint16_t udpsize; 1077 int timeout; 1078 bool reqnsid; 1079}; 1080 1081struct stub_glue_request { 1082 dns_request_t *request; 1083 dns_name_t name; 1084 struct stub_cb_args *args; 1085 bool ipv4; 1086}; 1087 1088/*% 1089 * Increment resolver-related statistics counters. Zone must be locked. 1090 */ 1091static void 1092inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { 1093 if (zone->stats != NULL) { 1094 isc_stats_increment(zone->stats, counter); 1095 } 1096} 1097 1098/*** 1099 *** Public functions. 1100 ***/ 1101 1102isc_result_t 1103dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { 1104 isc_result_t result; 1105 isc_time_t now; 1106 dns_zone_t *zone = NULL; 1107 dns_zone_t z = { .masterformat = dns_masterformat_none, 1108 .journalsize = -1, 1109 .rdclass = dns_rdataclass_none, 1110 .type = dns_zone_none, 1111 .refresh = DNS_ZONE_DEFAULTREFRESH, 1112 .retry = DNS_ZONE_DEFAULTRETRY, 1113 .maxrefresh = DNS_ZONE_MAXREFRESH, 1114 .minrefresh = DNS_ZONE_MINREFRESH, 1115 .maxretry = DNS_ZONE_MAXRETRY, 1116 .minretry = DNS_ZONE_MINRETRY, 1117 .notifytype = dns_notifytype_yes, 1118 .zero_no_soa_ttl = true, 1119 .check_names = dns_severity_ignore, 1120 .idlein = DNS_DEFAULT_IDLEIN, 1121 .idleout = DNS_DEFAULT_IDLEOUT, 1122 .notifysrc4dscp = -1, 1123 .notifysrc6dscp = -1, 1124 .parentalsrc4dscp = -1, 1125 .parentalsrc6dscp = -1, 1126 .xfrsource4dscp = -1, 1127 .xfrsource6dscp = -1, 1128 .altxfrsource4dscp = -1, 1129 .altxfrsource6dscp = -1, 1130 .maxxfrin = MAX_XFER_TIME, 1131 .maxxfrout = MAX_XFER_TIME, 1132 .sigvalidityinterval = 30 * 24 * 3600, 1133 .sigresigninginterval = 7 * 24 * 3600, 1134 .statlevel = dns_zonestat_none, 1135 .notifydelay = 5, 1136 .signatures = 10, 1137 .nodes = 100, 1138 .privatetype = (dns_rdatatype_t)0xffffU, 1139 .rpz_num = DNS_RPZ_INVALID_NUM, 1140 .requestixfr = true, 1141 .ixfr_ratio = 100, 1142 .requestexpire = true, 1143 .updatemethod = dns_updatemethod_increment, 1144 .magic = ZONE_MAGIC }; 1145 1146 REQUIRE(zonep != NULL && *zonep == NULL); 1147 REQUIRE(mctx != NULL); 1148 1149 TIME_NOW(&now); 1150 zone = isc_mem_get(mctx, sizeof(*zone)); 1151 *zone = z; 1152 1153 zone->mctx = NULL; 1154 isc_mem_attach(mctx, &zone->mctx); 1155 isc_mutex_init(&zone->lock); 1156 ZONEDB_INITLOCK(&zone->dblock); 1157 /* XXX MPA check that all elements are initialised */ 1158#ifdef DNS_ZONE_CHECKLOCK 1159 zone->locked = false; 1160#endif /* ifdef DNS_ZONE_CHECKLOCK */ 1161 1162 zone->notifytime = now; 1163 1164 ISC_LINK_INIT(zone, link); 1165 isc_refcount_init(&zone->erefs, 1); 1166 isc_refcount_init(&zone->irefs, 0); 1167 dns_name_init(&zone->origin, NULL); 1168 ISC_LIST_INIT(zone->includes); 1169 ISC_LIST_INIT(zone->newincludes); 1170 atomic_init(&zone->flags, 0); 1171 atomic_init(&zone->options, 0); 1172 atomic_init(&zone->keyopts, 0); 1173 isc_time_settoepoch(&zone->expiretime); 1174 isc_time_settoepoch(&zone->refreshtime); 1175 isc_time_settoepoch(&zone->dumptime); 1176 isc_time_settoepoch(&zone->loadtime); 1177 isc_time_settoepoch(&zone->resigntime); 1178 isc_time_settoepoch(&zone->keywarntime); 1179 isc_time_settoepoch(&zone->signingtime); 1180 isc_time_settoepoch(&zone->nsec3chaintime); 1181 isc_time_settoepoch(&zone->refreshkeytime); 1182 ISC_LIST_INIT(zone->notifies); 1183 ISC_LIST_INIT(zone->checkds_requests); 1184 isc_sockaddr_any(&zone->notifysrc4); 1185 isc_sockaddr_any6(&zone->notifysrc6); 1186 isc_sockaddr_any(&zone->parentalsrc4); 1187 isc_sockaddr_any6(&zone->parentalsrc6); 1188 isc_sockaddr_any(&zone->xfrsource4); 1189 isc_sockaddr_any6(&zone->xfrsource6); 1190 isc_sockaddr_any(&zone->altxfrsource4); 1191 isc_sockaddr_any6(&zone->altxfrsource6); 1192 ISC_LINK_INIT(zone, statelink); 1193 ISC_LIST_INIT(zone->signing); 1194 ISC_LIST_INIT(zone->nsec3chain); 1195 ISC_LIST_INIT(zone->setnsec3param_queue); 1196 ISC_LIST_INIT(zone->forwards); 1197 ISC_LIST_INIT(zone->rss_events); 1198 ISC_LIST_INIT(zone->rss_post); 1199 1200 result = isc_stats_create(mctx, &zone->gluecachestats, 1201 dns_gluecachestatscounter_max); 1202 if (result != ISC_R_SUCCESS) { 1203 goto free_refs; 1204 } 1205 1206 /* Must be after magic is set. */ 1207 dns_zone_setdbtype(zone, dbargc_default, dbargv_default); 1208 1209 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL, 1210 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, NULL, 1211 NULL); 1212 *zonep = zone; 1213 return (ISC_R_SUCCESS); 1214 1215free_refs: 1216 isc_refcount_decrement0(&zone->erefs); 1217 isc_refcount_destroy(&zone->erefs); 1218 isc_refcount_destroy(&zone->irefs); 1219 ZONEDB_DESTROYLOCK(&zone->dblock); 1220 isc_mutex_destroy(&zone->lock); 1221 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone)); 1222 return (result); 1223} 1224 1225static void 1226clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) { 1227 dns_dnsseckey_t *key; 1228 while (!ISC_LIST_EMPTY(*list)) { 1229 key = ISC_LIST_HEAD(*list); 1230 ISC_LIST_UNLINK(*list, key, link); 1231 dns_dnsseckey_destroy(mctx, &key); 1232 } 1233} 1234 1235/* 1236 * Free a zone. Because we require that there be no more 1237 * outstanding events or references, no locking is necessary. 1238 */ 1239static void 1240zone_free(dns_zone_t *zone) { 1241 dns_signing_t *signing; 1242 dns_nsec3chain_t *nsec3chain; 1243 isc_event_t *event; 1244 dns_include_t *include; 1245 1246 REQUIRE(DNS_ZONE_VALID(zone)); 1247 isc_refcount_destroy(&zone->erefs); 1248 isc_refcount_destroy(&zone->irefs); 1249 REQUIRE(!LOCKED_ZONE(zone)); 1250 REQUIRE(zone->timer == NULL); 1251 REQUIRE(zone->zmgr == NULL); 1252 1253 /* 1254 * Managed objects. Order is important. 1255 */ 1256 if (zone->request != NULL) { 1257 dns_request_destroy(&zone->request); /* XXXMPA */ 1258 } 1259 INSIST(zone->readio == NULL); 1260 INSIST(zone->statelist == NULL); 1261 INSIST(zone->writeio == NULL); 1262 INSIST(zone->view == NULL); 1263 INSIST(zone->prev_view == NULL); 1264 1265 if (zone->task != NULL) { 1266 isc_task_detach(&zone->task); 1267 } 1268 if (zone->loadtask != NULL) { 1269 isc_task_detach(&zone->loadtask); 1270 } 1271 1272 /* Unmanaged objects */ 1273 while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) { 1274 event = ISC_LIST_HEAD(zone->setnsec3param_queue); 1275 ISC_LIST_UNLINK(zone->setnsec3param_queue, event, ev_link); 1276 isc_event_free(&event); 1277 } 1278 while (!ISC_LIST_EMPTY(zone->rss_post)) { 1279 event = ISC_LIST_HEAD(zone->rss_post); 1280 ISC_LIST_UNLINK(zone->rss_post, event, ev_link); 1281 isc_event_free(&event); 1282 } 1283 for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; 1284 signing = ISC_LIST_HEAD(zone->signing)) 1285 { 1286 ISC_LIST_UNLINK(zone->signing, signing, link); 1287 dns_db_detach(&signing->db); 1288 dns_dbiterator_destroy(&signing->dbiterator); 1289 isc_mem_put(zone->mctx, signing, sizeof *signing); 1290 } 1291 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL; 1292 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) 1293 { 1294 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 1295 dns_db_detach(&nsec3chain->db); 1296 dns_dbiterator_destroy(&nsec3chain->dbiterator); 1297 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 1298 } 1299 for (include = ISC_LIST_HEAD(zone->includes); include != NULL; 1300 include = ISC_LIST_HEAD(zone->includes)) 1301 { 1302 ISC_LIST_UNLINK(zone->includes, include, link); 1303 isc_mem_free(zone->mctx, include->name); 1304 isc_mem_put(zone->mctx, include, sizeof *include); 1305 } 1306 for (include = ISC_LIST_HEAD(zone->newincludes); include != NULL; 1307 include = ISC_LIST_HEAD(zone->newincludes)) 1308 { 1309 ISC_LIST_UNLINK(zone->newincludes, include, link); 1310 isc_mem_free(zone->mctx, include->name); 1311 isc_mem_put(zone->mctx, include, sizeof *include); 1312 } 1313 if (zone->masterfile != NULL) { 1314 isc_mem_free(zone->mctx, zone->masterfile); 1315 } 1316 zone->masterfile = NULL; 1317 if (zone->keydirectory != NULL) { 1318 isc_mem_free(zone->mctx, zone->keydirectory); 1319 } 1320 zone->keydirectory = NULL; 1321 if (zone->kasp != NULL) { 1322 dns_kasp_detach(&zone->kasp); 1323 } 1324 if (!ISC_LIST_EMPTY(zone->checkds_ok)) { 1325 clear_keylist(&zone->checkds_ok, zone->mctx); 1326 } 1327 1328 zone->journalsize = -1; 1329 if (zone->journal != NULL) { 1330 isc_mem_free(zone->mctx, zone->journal); 1331 } 1332 zone->journal = NULL; 1333 if (zone->stats != NULL) { 1334 isc_stats_detach(&zone->stats); 1335 } 1336 if (zone->requeststats != NULL) { 1337 isc_stats_detach(&zone->requeststats); 1338 } 1339 if (zone->rcvquerystats != NULL) { 1340 dns_stats_detach(&zone->rcvquerystats); 1341 } 1342 if (zone->dnssecsignstats != NULL) { 1343 dns_stats_detach(&zone->dnssecsignstats); 1344 } 1345 if (zone->db != NULL) { 1346 zone_detachdb(zone); 1347 } 1348 if (zone->rpzs != NULL) { 1349 REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones); 1350 dns_rpz_detach_rpzs(&zone->rpzs); 1351 zone->rpz_num = DNS_RPZ_INVALID_NUM; 1352 } 1353 if (zone->catzs != NULL) { 1354 dns_catz_catzs_detach(&zone->catzs); 1355 } 1356 zone_freedbargs(zone); 1357 1358 RUNTIME_CHECK(dns_zone_setparentals(zone, NULL, NULL, 0) == 1359 ISC_R_SUCCESS); 1360 RUNTIME_CHECK(dns_zone_setprimarieswithkeys(zone, NULL, NULL, 0) == 1361 ISC_R_SUCCESS); 1362 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) == ISC_R_SUCCESS); 1363 zone->check_names = dns_severity_ignore; 1364 if (zone->update_acl != NULL) { 1365 dns_acl_detach(&zone->update_acl); 1366 } 1367 if (zone->forward_acl != NULL) { 1368 dns_acl_detach(&zone->forward_acl); 1369 } 1370 if (zone->notify_acl != NULL) { 1371 dns_acl_detach(&zone->notify_acl); 1372 } 1373 if (zone->query_acl != NULL) { 1374 dns_acl_detach(&zone->query_acl); 1375 } 1376 if (zone->queryon_acl != NULL) { 1377 dns_acl_detach(&zone->queryon_acl); 1378 } 1379 if (zone->xfr_acl != NULL) { 1380 dns_acl_detach(&zone->xfr_acl); 1381 } 1382 if (dns_name_dynamic(&zone->origin)) { 1383 dns_name_free(&zone->origin, zone->mctx); 1384 } 1385 if (zone->strnamerd != NULL) { 1386 isc_mem_free(zone->mctx, zone->strnamerd); 1387 } 1388 if (zone->strname != NULL) { 1389 isc_mem_free(zone->mctx, zone->strname); 1390 } 1391 if (zone->strrdclass != NULL) { 1392 isc_mem_free(zone->mctx, zone->strrdclass); 1393 } 1394 if (zone->strviewname != NULL) { 1395 isc_mem_free(zone->mctx, zone->strviewname); 1396 } 1397 if (zone->ssutable != NULL) { 1398 dns_ssutable_detach(&zone->ssutable); 1399 } 1400 if (zone->gluecachestats != NULL) { 1401 isc_stats_detach(&zone->gluecachestats); 1402 } 1403 1404 /* last stuff */ 1405 ZONEDB_DESTROYLOCK(&zone->dblock); 1406 isc_mutex_destroy(&zone->lock); 1407 zone->magic = 0; 1408 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone)); 1409} 1410 1411/* 1412 * Returns true iff this the signed side of an inline-signing zone. 1413 * Caller should hold zone lock. 1414 */ 1415static bool 1416inline_secure(dns_zone_t *zone) { 1417 REQUIRE(DNS_ZONE_VALID(zone)); 1418 if (zone->raw != NULL) { 1419 return (true); 1420 } 1421 return (false); 1422} 1423 1424/* 1425 * Returns true iff this the unsigned side of an inline-signing zone 1426 * Caller should hold zone lock. 1427 */ 1428static bool 1429inline_raw(dns_zone_t *zone) { 1430 REQUIRE(DNS_ZONE_VALID(zone)); 1431 if (zone->secure != NULL) { 1432 return (true); 1433 } 1434 return (false); 1435} 1436 1437/* 1438 * Single shot. 1439 */ 1440void 1441dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) { 1442 char namebuf[1024]; 1443 1444 REQUIRE(DNS_ZONE_VALID(zone)); 1445 REQUIRE(rdclass != dns_rdataclass_none); 1446 1447 /* 1448 * Test and set. 1449 */ 1450 LOCK_ZONE(zone); 1451 INSIST(zone != zone->raw); 1452 REQUIRE(zone->rdclass == dns_rdataclass_none || 1453 zone->rdclass == rdclass); 1454 zone->rdclass = rdclass; 1455 1456 if (zone->strnamerd != NULL) { 1457 isc_mem_free(zone->mctx, zone->strnamerd); 1458 } 1459 if (zone->strrdclass != NULL) { 1460 isc_mem_free(zone->mctx, zone->strrdclass); 1461 } 1462 1463 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1464 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1465 zone_rdclass_tostr(zone, namebuf, sizeof namebuf); 1466 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf); 1467 1468 if (inline_secure(zone)) { 1469 dns_zone_setclass(zone->raw, rdclass); 1470 } 1471 UNLOCK_ZONE(zone); 1472} 1473 1474dns_rdataclass_t 1475dns_zone_getclass(dns_zone_t *zone) { 1476 REQUIRE(DNS_ZONE_VALID(zone)); 1477 1478 return (zone->rdclass); 1479} 1480 1481void 1482dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { 1483 REQUIRE(DNS_ZONE_VALID(zone)); 1484 1485 LOCK_ZONE(zone); 1486 zone->notifytype = notifytype; 1487 UNLOCK_ZONE(zone); 1488} 1489 1490isc_result_t 1491dns_zone_getserial(dns_zone_t *zone, uint32_t *serialp) { 1492 isc_result_t result; 1493 unsigned int soacount; 1494 1495 REQUIRE(DNS_ZONE_VALID(zone)); 1496 REQUIRE(serialp != NULL); 1497 1498 LOCK_ZONE(zone); 1499 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1500 if (zone->db != NULL) { 1501 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, 1502 serialp, NULL, NULL, NULL, NULL, 1503 NULL); 1504 if (result == ISC_R_SUCCESS && soacount == 0) { 1505 result = ISC_R_FAILURE; 1506 } 1507 } else { 1508 result = DNS_R_NOTLOADED; 1509 } 1510 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1511 UNLOCK_ZONE(zone); 1512 1513 return (result); 1514} 1515 1516/* 1517 * Single shot. 1518 */ 1519void 1520dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) { 1521 char namebuf[1024]; 1522 1523 REQUIRE(DNS_ZONE_VALID(zone)); 1524 REQUIRE(type != dns_zone_none); 1525 1526 /* 1527 * Test and set. 1528 */ 1529 LOCK_ZONE(zone); 1530 REQUIRE(zone->type == dns_zone_none || zone->type == type); 1531 zone->type = type; 1532 1533 if (zone->strnamerd != NULL) { 1534 isc_mem_free(zone->mctx, zone->strnamerd); 1535 } 1536 1537 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1538 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1539 UNLOCK_ZONE(zone); 1540} 1541 1542static void 1543zone_freedbargs(dns_zone_t *zone) { 1544 unsigned int i; 1545 1546 /* Free the old database argument list. */ 1547 if (zone->db_argv != NULL) { 1548 for (i = 0; i < zone->db_argc; i++) { 1549 isc_mem_free(zone->mctx, zone->db_argv[i]); 1550 } 1551 isc_mem_put(zone->mctx, zone->db_argv, 1552 zone->db_argc * sizeof(*zone->db_argv)); 1553 } 1554 zone->db_argc = 0; 1555 zone->db_argv = NULL; 1556} 1557 1558isc_result_t 1559dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) { 1560 size_t size = 0; 1561 unsigned int i; 1562 isc_result_t result = ISC_R_SUCCESS; 1563 void *mem; 1564 char **tmp, *tmp2, *base; 1565 1566 REQUIRE(DNS_ZONE_VALID(zone)); 1567 REQUIRE(argv != NULL && *argv == NULL); 1568 1569 LOCK_ZONE(zone); 1570 size = (zone->db_argc + 1) * sizeof(char *); 1571 for (i = 0; i < zone->db_argc; i++) { 1572 size += strlen(zone->db_argv[i]) + 1; 1573 } 1574 mem = isc_mem_allocate(mctx, size); 1575 { 1576 tmp = mem; 1577 tmp2 = mem; 1578 base = mem; 1579 tmp2 += (zone->db_argc + 1) * sizeof(char *); 1580 for (i = 0; i < zone->db_argc; i++) { 1581 *tmp++ = tmp2; 1582 strlcpy(tmp2, zone->db_argv[i], size - (tmp2 - base)); 1583 tmp2 += strlen(tmp2) + 1; 1584 } 1585 *tmp = NULL; 1586 } 1587 UNLOCK_ZONE(zone); 1588 *argv = mem; 1589 return (result); 1590} 1591 1592void 1593dns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc, 1594 const char *const *dbargv) { 1595 char **argv = NULL; 1596 unsigned int i; 1597 1598 REQUIRE(DNS_ZONE_VALID(zone)); 1599 REQUIRE(dbargc >= 1); 1600 REQUIRE(dbargv != NULL); 1601 1602 LOCK_ZONE(zone); 1603 1604 /* Set up a new database argument list. */ 1605 argv = isc_mem_get(zone->mctx, dbargc * sizeof(*argv)); 1606 for (i = 0; i < dbargc; i++) { 1607 argv[i] = NULL; 1608 } 1609 for (i = 0; i < dbargc; i++) { 1610 argv[i] = isc_mem_strdup(zone->mctx, dbargv[i]); 1611 } 1612 1613 /* Free the old list. */ 1614 zone_freedbargs(zone); 1615 1616 zone->db_argc = dbargc; 1617 zone->db_argv = argv; 1618 1619 UNLOCK_ZONE(zone); 1620} 1621 1622static void 1623dns_zone_setview_helper(dns_zone_t *zone, dns_view_t *view) { 1624 char namebuf[1024]; 1625 1626 if (zone->prev_view == NULL && zone->view != NULL) { 1627 dns_view_weakattach(zone->view, &zone->prev_view); 1628 } 1629 1630 INSIST(zone != zone->raw); 1631 if (zone->view != NULL) { 1632 dns_view_weakdetach(&zone->view); 1633 } 1634 dns_view_weakattach(view, &zone->view); 1635 1636 if (zone->strviewname != NULL) { 1637 isc_mem_free(zone->mctx, zone->strviewname); 1638 } 1639 if (zone->strnamerd != NULL) { 1640 isc_mem_free(zone->mctx, zone->strnamerd); 1641 } 1642 1643 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1644 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1645 zone_viewname_tostr(zone, namebuf, sizeof namebuf); 1646 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf); 1647 1648 if (inline_secure(zone)) { 1649 dns_zone_setview(zone->raw, view); 1650 } 1651} 1652 1653void 1654dns_zone_setview(dns_zone_t *zone, dns_view_t *view) { 1655 REQUIRE(DNS_ZONE_VALID(zone)); 1656 1657 LOCK_ZONE(zone); 1658 dns_zone_setview_helper(zone, view); 1659 UNLOCK_ZONE(zone); 1660} 1661 1662dns_view_t * 1663dns_zone_getview(dns_zone_t *zone) { 1664 REQUIRE(DNS_ZONE_VALID(zone)); 1665 1666 return (zone->view); 1667} 1668 1669void 1670dns_zone_setviewcommit(dns_zone_t *zone) { 1671 REQUIRE(DNS_ZONE_VALID(zone)); 1672 1673 LOCK_ZONE(zone); 1674 if (zone->prev_view != NULL) { 1675 dns_view_weakdetach(&zone->prev_view); 1676 } 1677 if (inline_secure(zone)) { 1678 dns_zone_setviewcommit(zone->raw); 1679 } 1680 UNLOCK_ZONE(zone); 1681} 1682 1683void 1684dns_zone_setviewrevert(dns_zone_t *zone) { 1685 REQUIRE(DNS_ZONE_VALID(zone)); 1686 1687 LOCK_ZONE(zone); 1688 if (zone->prev_view != NULL) { 1689 dns_zone_setview_helper(zone, zone->prev_view); 1690 dns_view_weakdetach(&zone->prev_view); 1691 } 1692 if (zone->catzs != NULL) { 1693 zone_catz_enable(zone, zone->catzs); 1694 } 1695 if (inline_secure(zone)) { 1696 dns_zone_setviewrevert(zone->raw); 1697 } 1698 UNLOCK_ZONE(zone); 1699} 1700 1701isc_result_t 1702dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) { 1703 isc_result_t result = ISC_R_SUCCESS; 1704 char namebuf[1024]; 1705 1706 REQUIRE(DNS_ZONE_VALID(zone)); 1707 REQUIRE(origin != NULL); 1708 1709 LOCK_ZONE(zone); 1710 INSIST(zone != zone->raw); 1711 if (dns_name_dynamic(&zone->origin)) { 1712 dns_name_free(&zone->origin, zone->mctx); 1713 dns_name_init(&zone->origin, NULL); 1714 } 1715 dns_name_dup(origin, zone->mctx, &zone->origin); 1716 1717 if (zone->strnamerd != NULL) { 1718 isc_mem_free(zone->mctx, zone->strnamerd); 1719 } 1720 if (zone->strname != NULL) { 1721 isc_mem_free(zone->mctx, zone->strname); 1722 } 1723 1724 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1725 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1726 zone_name_tostr(zone, namebuf, sizeof namebuf); 1727 zone->strname = isc_mem_strdup(zone->mctx, namebuf); 1728 1729 if (inline_secure(zone)) { 1730 result = dns_zone_setorigin(zone->raw, origin); 1731 } 1732 UNLOCK_ZONE(zone); 1733 return (result); 1734} 1735 1736static isc_result_t 1737dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) { 1738 char *copy; 1739 1740 if (value != NULL) { 1741 copy = isc_mem_strdup(zone->mctx, value); 1742 } else { 1743 copy = NULL; 1744 } 1745 1746 if (*field != NULL) { 1747 isc_mem_free(zone->mctx, *field); 1748 } 1749 1750 *field = copy; 1751 return (ISC_R_SUCCESS); 1752} 1753 1754isc_result_t 1755dns_zone_setfile(dns_zone_t *zone, const char *file, dns_masterformat_t format, 1756 const dns_master_style_t *style) { 1757 isc_result_t result = ISC_R_SUCCESS; 1758 1759 REQUIRE(DNS_ZONE_VALID(zone)); 1760 1761 LOCK_ZONE(zone); 1762 result = dns_zone_setstring(zone, &zone->masterfile, file); 1763 if (result == ISC_R_SUCCESS) { 1764 zone->masterformat = format; 1765 if (format == dns_masterformat_text) { 1766 zone->masterstyle = style; 1767 } 1768 result = default_journal(zone); 1769 } 1770 UNLOCK_ZONE(zone); 1771 1772 return (result); 1773} 1774 1775const char * 1776dns_zone_getfile(dns_zone_t *zone) { 1777 REQUIRE(DNS_ZONE_VALID(zone)); 1778 1779 return (zone->masterfile); 1780} 1781 1782dns_ttl_t 1783dns_zone_getmaxttl(dns_zone_t *zone) { 1784 REQUIRE(DNS_ZONE_VALID(zone)); 1785 1786 return (zone->maxttl); 1787} 1788 1789void 1790dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) { 1791 REQUIRE(DNS_ZONE_VALID(zone)); 1792 1793 LOCK_ZONE(zone); 1794 if (maxttl != 0) { 1795 DNS_ZONE_SETOPTION(zone, DNS_ZONEOPT_CHECKTTL); 1796 } else { 1797 DNS_ZONE_CLROPTION(zone, DNS_ZONEOPT_CHECKTTL); 1798 } 1799 zone->maxttl = maxttl; 1800 UNLOCK_ZONE(zone); 1801 1802 return; 1803} 1804 1805static isc_result_t 1806default_journal(dns_zone_t *zone) { 1807 isc_result_t result; 1808 char *journal; 1809 1810 REQUIRE(DNS_ZONE_VALID(zone)); 1811 REQUIRE(LOCKED_ZONE(zone)); 1812 1813 if (zone->masterfile != NULL) { 1814 /* Calculate string length including '\0'. */ 1815 int len = strlen(zone->masterfile) + sizeof(".jnl"); 1816 journal = isc_mem_allocate(zone->mctx, len); 1817 strlcpy(journal, zone->masterfile, len); 1818 strlcat(journal, ".jnl", len); 1819 } else { 1820 journal = NULL; 1821 } 1822 result = dns_zone_setstring(zone, &zone->journal, journal); 1823 if (journal != NULL) { 1824 isc_mem_free(zone->mctx, journal); 1825 } 1826 return (result); 1827} 1828 1829isc_result_t 1830dns_zone_setjournal(dns_zone_t *zone, const char *myjournal) { 1831 isc_result_t result = ISC_R_SUCCESS; 1832 1833 REQUIRE(DNS_ZONE_VALID(zone)); 1834 1835 LOCK_ZONE(zone); 1836 result = dns_zone_setstring(zone, &zone->journal, myjournal); 1837 UNLOCK_ZONE(zone); 1838 1839 return (result); 1840} 1841 1842char * 1843dns_zone_getjournal(dns_zone_t *zone) { 1844 REQUIRE(DNS_ZONE_VALID(zone)); 1845 1846 return (zone->journal); 1847} 1848 1849/* 1850 * Return true iff the zone is "dynamic", in the sense that the zone's 1851 * master file (if any) is written by the server, rather than being 1852 * updated manually and read by the server. 1853 * 1854 * This is true for slave zones, mirror zones, stub zones, key zones, 1855 * and zones that allow dynamic updates either by having an update 1856 * policy ("ssutable") or an "allow-update" ACL with a value other than 1857 * exactly "{ none; }". 1858 */ 1859bool 1860dns_zone_isdynamic(dns_zone_t *zone, bool ignore_freeze) { 1861 REQUIRE(DNS_ZONE_VALID(zone)); 1862 1863 if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror || 1864 zone->type == dns_zone_stub || zone->type == dns_zone_key || 1865 (zone->type == dns_zone_redirect && zone->masters != NULL)) 1866 { 1867 return (true); 1868 } 1869 1870 /* Inline zones are always dynamic. */ 1871 if (zone->type == dns_zone_primary && zone->raw != NULL) { 1872 return (true); 1873 } 1874 1875 /* If !ignore_freeze, we need check whether updates are disabled. */ 1876 if (zone->type == dns_zone_primary && 1877 (!zone->update_disabled || ignore_freeze) && 1878 ((zone->ssutable != NULL) || 1879 (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)))) 1880 { 1881 return (true); 1882 } 1883 1884 return (false); 1885} 1886 1887/* 1888 * Set the response policy index and information for a zone. 1889 */ 1890isc_result_t 1891dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs, 1892 dns_rpz_num_t rpz_num) { 1893 /* 1894 * Only RBTDB zones can be used for response policy zones, 1895 * because only they have the code to create the summary data. 1896 * Only zones that are loaded instead of mmap()ed create the 1897 * summary data and so can be policy zones. 1898 */ 1899 if (strcmp(zone->db_argv[0], "rbt") != 0 && 1900 strcmp(zone->db_argv[0], "rbt64") != 0) 1901 { 1902 return (ISC_R_NOTIMPLEMENTED); 1903 } 1904 if (zone->masterformat == dns_masterformat_map) { 1905 return (ISC_R_NOTIMPLEMENTED); 1906 } 1907 1908 /* 1909 * This must happen only once or be redundant. 1910 */ 1911 LOCK_ZONE(zone); 1912 if (zone->rpzs != NULL) { 1913 REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num); 1914 } else { 1915 REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM); 1916 dns_rpz_attach_rpzs(rpzs, &zone->rpzs); 1917 zone->rpz_num = rpz_num; 1918 } 1919 rpzs->defined |= DNS_RPZ_ZBIT(rpz_num); 1920 UNLOCK_ZONE(zone); 1921 1922 return (ISC_R_SUCCESS); 1923} 1924 1925dns_rpz_num_t 1926dns_zone_get_rpz_num(dns_zone_t *zone) { 1927 return (zone->rpz_num); 1928} 1929 1930/* 1931 * If a zone is a response policy zone, mark its new database. 1932 */ 1933void 1934dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) { 1935 isc_result_t result; 1936 if (zone->rpz_num == DNS_RPZ_INVALID_NUM) { 1937 return; 1938 } 1939 REQUIRE(zone->rpzs != NULL); 1940 result = dns_db_updatenotify_register(db, dns_rpz_dbupdate_callback, 1941 zone->rpzs->zones[zone->rpz_num]); 1942 REQUIRE(result == ISC_R_SUCCESS); 1943} 1944 1945static void 1946dns_zone_rpz_disable_db(dns_zone_t *zone, dns_db_t *db) { 1947 if (zone->rpz_num == DNS_RPZ_INVALID_NUM) { 1948 return; 1949 } 1950 REQUIRE(zone->rpzs != NULL); 1951 (void)dns_db_updatenotify_unregister(db, dns_rpz_dbupdate_callback, 1952 zone->rpzs->zones[zone->rpz_num]); 1953} 1954 1955/* 1956 * If a zone is a catalog zone, attach it to update notification in database. 1957 */ 1958void 1959dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) { 1960 REQUIRE(DNS_ZONE_VALID(zone)); 1961 REQUIRE(db != NULL); 1962 1963 if (zone->catzs != NULL) { 1964 dns_db_updatenotify_register(db, dns_catz_dbupdate_callback, 1965 zone->catzs); 1966 } 1967} 1968 1969static void 1970dns_zone_catz_disable_db(dns_zone_t *zone, dns_db_t *db) { 1971 REQUIRE(DNS_ZONE_VALID(zone)); 1972 REQUIRE(db != NULL); 1973 1974 if (zone->catzs != NULL) { 1975 dns_db_updatenotify_unregister(db, dns_catz_dbupdate_callback, 1976 zone->catzs); 1977 } 1978} 1979 1980static void 1981zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) { 1982 REQUIRE(DNS_ZONE_VALID(zone)); 1983 REQUIRE(catzs != NULL); 1984 1985 INSIST(zone->catzs == NULL || zone->catzs == catzs); 1986 dns_catz_catzs_set_view(catzs, zone->view); 1987 if (zone->catzs == NULL) { 1988 dns_catz_catzs_attach(catzs, &zone->catzs); 1989 } 1990} 1991 1992void 1993dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) { 1994 REQUIRE(DNS_ZONE_VALID(zone)); 1995 1996 LOCK_ZONE(zone); 1997 zone_catz_enable(zone, catzs); 1998 UNLOCK_ZONE(zone); 1999} 2000 2001static void 2002zone_catz_disable(dns_zone_t *zone) { 2003 REQUIRE(DNS_ZONE_VALID(zone)); 2004 2005 if (zone->catzs != NULL) { 2006 if (zone->db != NULL) { 2007 dns_zone_catz_disable_db(zone, zone->db); 2008 } 2009 dns_catz_catzs_detach(&zone->catzs); 2010 } 2011} 2012 2013void 2014dns_zone_catz_disable(dns_zone_t *zone) { 2015 REQUIRE(DNS_ZONE_VALID(zone)); 2016 2017 LOCK_ZONE(zone); 2018 zone_catz_disable(zone); 2019 UNLOCK_ZONE(zone); 2020} 2021 2022bool 2023dns_zone_catz_is_enabled(dns_zone_t *zone) { 2024 REQUIRE(DNS_ZONE_VALID(zone)); 2025 2026 return (zone->catzs != NULL); 2027} 2028 2029/* 2030 * Set catalog zone ownership of the zone 2031 */ 2032void 2033dns_zone_set_parentcatz(dns_zone_t *zone, dns_catz_zone_t *catz) { 2034 REQUIRE(DNS_ZONE_VALID(zone)); 2035 REQUIRE(catz != NULL); 2036 LOCK_ZONE(zone); 2037 INSIST(zone->parentcatz == NULL || zone->parentcatz == catz); 2038 zone->parentcatz = catz; 2039 UNLOCK_ZONE(zone); 2040} 2041 2042dns_catz_zone_t * 2043dns_zone_get_parentcatz(const dns_zone_t *zone) { 2044 REQUIRE(DNS_ZONE_VALID(zone)); 2045 return (zone->parentcatz); 2046} 2047 2048static bool 2049zone_touched(dns_zone_t *zone) { 2050 isc_result_t result; 2051 isc_time_t modtime; 2052 dns_include_t *include; 2053 2054 REQUIRE(DNS_ZONE_VALID(zone)); 2055 2056 result = isc_file_getmodtime(zone->masterfile, &modtime); 2057 if (result != ISC_R_SUCCESS || 2058 isc_time_compare(&modtime, &zone->loadtime) > 0) 2059 { 2060 return (true); 2061 } 2062 2063 for (include = ISC_LIST_HEAD(zone->includes); include != NULL; 2064 include = ISC_LIST_NEXT(include, link)) 2065 { 2066 result = isc_file_getmodtime(include->name, &modtime); 2067 if (result != ISC_R_SUCCESS || 2068 isc_time_compare(&modtime, &include->filetime) > 0) 2069 { 2070 return (true); 2071 } 2072 } 2073 2074 return (false); 2075} 2076 2077/* 2078 * Note: when dealing with inline-signed zones, external callers will always 2079 * call zone_load() for the secure zone; zone_load() calls itself recursively 2080 * in order to load the raw zone. 2081 */ 2082static isc_result_t 2083zone_load(dns_zone_t *zone, unsigned int flags, bool locked) { 2084 isc_result_t result; 2085 isc_time_t now; 2086 isc_time_t loadtime; 2087 dns_db_t *db = NULL; 2088 bool rbt, hasraw, is_dynamic; 2089 2090 REQUIRE(DNS_ZONE_VALID(zone)); 2091 2092 if (!locked) { 2093 LOCK_ZONE(zone); 2094 } 2095 2096 INSIST(zone != zone->raw); 2097 hasraw = inline_secure(zone); 2098 if (hasraw) { 2099 /* 2100 * We are trying to load an inline-signed zone. First call 2101 * self recursively to try loading the raw version of the zone. 2102 * Assuming the raw zone file is readable, there are two 2103 * possibilities: 2104 * 2105 * a) the raw zone was not yet loaded and thus it will be 2106 * loaded now, synchronously; if this succeeds, a 2107 * subsequent attempt to load the signed zone file will 2108 * take place and thus zone_postload() will be called 2109 * twice: first for the raw zone and then for the secure 2110 * zone; the latter call will take care of syncing the raw 2111 * version with the secure version, 2112 * 2113 * b) the raw zone was already loaded and we are trying to 2114 * reload it, which will happen asynchronously; this means 2115 * zone_postload() will only be called for the raw zone 2116 * because "result" returned by the zone_load() call below 2117 * will not be ISC_R_SUCCESS but rather DNS_R_CONTINUE; 2118 * zone_postload() called for the raw zone will take care 2119 * of syncing the raw version with the secure version. 2120 */ 2121 result = zone_load(zone->raw, flags, false); 2122 if (result != ISC_R_SUCCESS) { 2123 if (!locked) { 2124 UNLOCK_ZONE(zone); 2125 } 2126 return (result); 2127 } 2128 LOCK_ZONE(zone->raw); 2129 } 2130 2131 TIME_NOW(&now); 2132 2133 INSIST(zone->type != dns_zone_none); 2134 2135 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { 2136 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) { 2137 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 2138 } 2139 result = DNS_R_CONTINUE; 2140 goto cleanup; 2141 } 2142 2143 INSIST(zone->db_argc >= 1); 2144 2145 rbt = strcmp(zone->db_argv[0], "rbt") == 0 || 2146 strcmp(zone->db_argv[0], "rbt64") == 0; 2147 2148 if (zone->db != NULL && zone->masterfile == NULL && rbt) { 2149 /* 2150 * The zone has no master file configured. 2151 */ 2152 result = ISC_R_SUCCESS; 2153 goto cleanup; 2154 } 2155 2156 is_dynamic = dns_zone_isdynamic(zone, false); 2157 if (zone->db != NULL && is_dynamic) { 2158 /* 2159 * This is a slave, stub, or dynamically updated zone being 2160 * reloaded. Do nothing - the database we already 2161 * have is guaranteed to be up-to-date. 2162 */ 2163 if (zone->type == dns_zone_primary && !hasraw) { 2164 result = DNS_R_DYNAMIC; 2165 } else { 2166 result = ISC_R_SUCCESS; 2167 } 2168 goto cleanup; 2169 } 2170 2171 /* 2172 * Store the current time before the zone is loaded, so that if the 2173 * file changes between the time of the load and the time that 2174 * zone->loadtime is set, then the file will still be reloaded 2175 * the next time dns_zone_load is called. 2176 */ 2177 TIME_NOW(&loadtime); 2178 2179 /* 2180 * Don't do the load if the file that stores the zone is older 2181 * than the last time the zone was loaded. If the zone has not 2182 * been loaded yet, zone->loadtime will be the epoch. 2183 */ 2184 if (zone->masterfile != NULL) { 2185 isc_time_t filetime; 2186 2187 /* 2188 * The file is already loaded. If we are just doing a 2189 * "rndc reconfig", we are done. 2190 */ 2191 if (!isc_time_isepoch(&zone->loadtime) && 2192 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) 2193 { 2194 result = ISC_R_SUCCESS; 2195 goto cleanup; 2196 } 2197 2198 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 2199 !zone_touched(zone)) 2200 { 2201 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2202 ISC_LOG_DEBUG(1), 2203 "skipping load: master file " 2204 "older than last load"); 2205 result = DNS_R_UPTODATE; 2206 goto cleanup; 2207 } 2208 2209 /* 2210 * If the file modification time is in the past 2211 * set loadtime to that value. 2212 */ 2213 result = isc_file_getmodtime(zone->masterfile, &filetime); 2214 if (result == ISC_R_SUCCESS && 2215 isc_time_compare(&loadtime, &filetime) > 0) 2216 { 2217 loadtime = filetime; 2218 } 2219 } 2220 2221 /* 2222 * Built in zones (with the exception of empty zones) don't need 2223 * to be reloaded. 2224 */ 2225 if (zone->type == dns_zone_primary && 2226 strcmp(zone->db_argv[0], "_builtin") == 0 && 2227 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) && 2228 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 2229 { 2230 result = ISC_R_SUCCESS; 2231 goto cleanup; 2232 } 2233 2234 /* 2235 * Zones associated with a DLZ don't need to be loaded either, 2236 * but we need to associate the database with the zone object. 2237 */ 2238 if (strcmp(zone->db_argv[0], "dlz") == 0) { 2239 dns_dlzdb_t *dlzdb; 2240 dns_dlzfindzone_t findzone; 2241 2242 for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched); 2243 dlzdb != NULL; dlzdb = ISC_LIST_NEXT(dlzdb, link)) 2244 { 2245 INSIST(DNS_DLZ_VALID(dlzdb)); 2246 if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0) { 2247 break; 2248 } 2249 } 2250 2251 if (dlzdb == NULL) { 2252 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2253 ISC_LOG_ERROR, 2254 "DLZ %s does not exist or is set " 2255 "to 'search yes;'", 2256 zone->db_argv[1]); 2257 result = ISC_R_NOTFOUND; 2258 goto cleanup; 2259 } 2260 2261 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 2262 /* ask SDLZ driver if the zone is supported */ 2263 findzone = dlzdb->implementation->methods->findzone; 2264 result = (*findzone)(dlzdb->implementation->driverarg, 2265 dlzdb->dbdata, dlzdb->mctx, 2266 zone->view->rdclass, &zone->origin, NULL, 2267 NULL, &db); 2268 if (result != ISC_R_NOTFOUND) { 2269 if (zone->db != NULL) { 2270 zone_detachdb(zone); 2271 } 2272 zone_attachdb(zone, db); 2273 dns_db_detach(&db); 2274 result = ISC_R_SUCCESS; 2275 } 2276 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 2277 2278 if (result == ISC_R_SUCCESS) { 2279 if (dlzdb->configure_callback == NULL) { 2280 goto cleanup; 2281 } 2282 2283 result = (*dlzdb->configure_callback)(zone->view, dlzdb, 2284 zone); 2285 if (result != ISC_R_SUCCESS) { 2286 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2287 ISC_LOG_ERROR, 2288 "DLZ configuration callback: %s", 2289 isc_result_totext(result)); 2290 } 2291 } 2292 goto cleanup; 2293 } 2294 2295 if ((zone->type == dns_zone_secondary || 2296 zone->type == dns_zone_mirror || zone->type == dns_zone_stub || 2297 (zone->type == dns_zone_redirect && zone->masters != NULL)) && 2298 rbt) 2299 { 2300 if (zone->masterfile == NULL || 2301 !isc_file_exists(zone->masterfile)) 2302 { 2303 if (zone->masterfile != NULL) { 2304 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2305 ISC_LOG_DEBUG(1), 2306 "no master file"); 2307 } 2308 zone->refreshtime = now; 2309 if (zone->task != NULL) { 2310 zone_settimer(zone, &now); 2311 } 2312 result = ISC_R_SUCCESS; 2313 goto cleanup; 2314 } 2315 } 2316 2317 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1), 2318 "starting load"); 2319 2320 result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, 2321 (zone->type == dns_zone_stub) ? dns_dbtype_stub 2322 : dns_dbtype_zone, 2323 zone->rdclass, zone->db_argc - 1, 2324 zone->db_argv + 1, &db); 2325 2326 if (result != ISC_R_SUCCESS) { 2327 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 2328 "loading zone: creating database: %s", 2329 isc_result_totext(result)); 2330 goto cleanup; 2331 } 2332 dns_db_settask(db, zone->task); 2333 2334 if (zone->type == dns_zone_primary || 2335 zone->type == dns_zone_secondary || zone->type == dns_zone_mirror) 2336 { 2337 result = dns_db_setgluecachestats(db, zone->gluecachestats); 2338 if (result == ISC_R_NOTIMPLEMENTED) { 2339 result = ISC_R_SUCCESS; 2340 } 2341 if (result != ISC_R_SUCCESS) { 2342 goto cleanup; 2343 } 2344 } 2345 2346 if (!dns_db_ispersistent(db)) { 2347 if (zone->masterfile != NULL) { 2348 result = zone_startload(db, zone, loadtime); 2349 } else { 2350 result = DNS_R_NOMASTERFILE; 2351 if (zone->type == dns_zone_primary || 2352 (zone->type == dns_zone_redirect && 2353 zone->masters == NULL)) 2354 { 2355 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2356 ISC_LOG_ERROR, 2357 "loading zone: " 2358 "no master file configured"); 2359 goto cleanup; 2360 } 2361 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2362 ISC_LOG_INFO, 2363 "loading zone: " 2364 "no master file configured: continuing"); 2365 } 2366 } 2367 2368 if (result == DNS_R_CONTINUE) { 2369 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING); 2370 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) { 2371 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 2372 } 2373 goto cleanup; 2374 } 2375 2376 result = zone_postload(zone, db, loadtime, result); 2377 2378cleanup: 2379 if (hasraw) { 2380 UNLOCK_ZONE(zone->raw); 2381 } 2382 if (!locked) { 2383 UNLOCK_ZONE(zone); 2384 } 2385 if (db != NULL) { 2386 dns_db_detach(&db); 2387 } 2388 return (result); 2389} 2390 2391isc_result_t 2392dns_zone_load(dns_zone_t *zone, bool newonly) { 2393 return (zone_load(zone, newonly ? DNS_ZONELOADFLAG_NOSTAT : 0, false)); 2394} 2395 2396static void 2397zone_asyncload(isc_task_t *task, isc_event_t *event) { 2398 dns_asyncload_t *asl = event->ev_arg; 2399 dns_zone_t *zone = asl->zone; 2400 isc_result_t result; 2401 2402 UNUSED(task); 2403 2404 REQUIRE(DNS_ZONE_VALID(zone)); 2405 2406 isc_event_free(&event); 2407 2408 LOCK_ZONE(zone); 2409 result = zone_load(zone, asl->flags, true); 2410 if (result != DNS_R_CONTINUE) { 2411 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); 2412 } 2413 UNLOCK_ZONE(zone); 2414 2415 /* Inform the zone table we've finished loading */ 2416 if (asl->loaded != NULL) { 2417 (asl->loaded)(asl->loaded_arg, zone, task); 2418 } 2419 2420 /* Reduce the quantum */ 2421 isc_task_setquantum(zone->loadtask, 1); 2422 2423 isc_mem_put(zone->mctx, asl, sizeof(*asl)); 2424 dns_zone_idetach(&zone); 2425} 2426 2427isc_result_t 2428dns_zone_asyncload(dns_zone_t *zone, bool newonly, dns_zt_zoneloaded_t done, 2429 void *arg) { 2430 isc_event_t *e; 2431 dns_asyncload_t *asl = NULL; 2432 2433 REQUIRE(DNS_ZONE_VALID(zone)); 2434 2435 if (zone->zmgr == NULL) { 2436 return (ISC_R_FAILURE); 2437 } 2438 2439 /* If we already have a load pending, stop now */ 2440 LOCK_ZONE(zone); 2441 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) { 2442 UNLOCK_ZONE(zone); 2443 return (ISC_R_ALREADYRUNNING); 2444 } 2445 2446 asl = isc_mem_get(zone->mctx, sizeof(*asl)); 2447 2448 asl->zone = NULL; 2449 asl->flags = newonly ? DNS_ZONELOADFLAG_NOSTAT : 0; 2450 asl->loaded = done; 2451 asl->loaded_arg = arg; 2452 2453 e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr, DNS_EVENT_ZONELOAD, 2454 zone_asyncload, asl, sizeof(isc_event_t)); 2455 2456 zone_iattach(zone, &asl->zone); 2457 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING); 2458 isc_task_send(zone->loadtask, &e); 2459 UNLOCK_ZONE(zone); 2460 2461 return (ISC_R_SUCCESS); 2462} 2463 2464bool 2465dns__zone_loadpending(dns_zone_t *zone) { 2466 REQUIRE(DNS_ZONE_VALID(zone)); 2467 2468 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)); 2469} 2470 2471isc_result_t 2472dns_zone_loadandthaw(dns_zone_t *zone) { 2473 isc_result_t result; 2474 2475 if (inline_raw(zone)) { 2476 result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW, false); 2477 } else { 2478 /* 2479 * When thawing a zone, we don't know what changes 2480 * have been made. If we do DNSSEC maintenance on this 2481 * zone, schedule a full sign for this zone. 2482 */ 2483 if (zone->type == dns_zone_primary && 2484 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 2485 { 2486 DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN); 2487 } 2488 result = zone_load(zone, DNS_ZONELOADFLAG_THAW, false); 2489 } 2490 2491 switch (result) { 2492 case DNS_R_CONTINUE: 2493 /* Deferred thaw. */ 2494 break; 2495 case DNS_R_UPTODATE: 2496 case ISC_R_SUCCESS: 2497 case DNS_R_SEENINCLUDE: 2498 zone->update_disabled = false; 2499 break; 2500 case DNS_R_NOMASTERFILE: 2501 zone->update_disabled = false; 2502 break; 2503 default: 2504 /* Error, remain in disabled state. */ 2505 break; 2506 } 2507 return (result); 2508} 2509 2510static unsigned int 2511get_master_options(dns_zone_t *zone) { 2512 unsigned int options; 2513 2514 options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN; 2515 if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror || 2516 (zone->type == dns_zone_redirect && zone->masters == NULL)) 2517 { 2518 options |= DNS_MASTER_SLAVE; 2519 } 2520 if (zone->type == dns_zone_key) { 2521 options |= DNS_MASTER_KEY; 2522 } 2523 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) { 2524 options |= DNS_MASTER_CHECKNS; 2525 } 2526 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) { 2527 options |= DNS_MASTER_FATALNS; 2528 } 2529 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) { 2530 options |= DNS_MASTER_CHECKNAMES; 2531 } 2532 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) { 2533 options |= DNS_MASTER_CHECKNAMESFAIL; 2534 } 2535 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) { 2536 options |= DNS_MASTER_CHECKMX; 2537 } 2538 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) { 2539 options |= DNS_MASTER_CHECKMXFAIL; 2540 } 2541 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) { 2542 options |= DNS_MASTER_CHECKWILDCARD; 2543 } 2544 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKTTL)) { 2545 options |= DNS_MASTER_CHECKTTL; 2546 } 2547 2548 return (options); 2549} 2550 2551static void 2552zone_registerinclude(const char *filename, void *arg) { 2553 isc_result_t result; 2554 dns_zone_t *zone = (dns_zone_t *)arg; 2555 dns_include_t *inc = NULL; 2556 2557 REQUIRE(DNS_ZONE_VALID(zone)); 2558 2559 if (filename == NULL) { 2560 return; 2561 } 2562 2563 /* 2564 * Suppress duplicates. 2565 */ 2566 for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; 2567 inc = ISC_LIST_NEXT(inc, link)) 2568 { 2569 if (strcmp(filename, inc->name) == 0) { 2570 return; 2571 } 2572 } 2573 2574 inc = isc_mem_get(zone->mctx, sizeof(dns_include_t)); 2575 inc->name = isc_mem_strdup(zone->mctx, filename); 2576 ISC_LINK_INIT(inc, link); 2577 2578 result = isc_file_getmodtime(filename, &inc->filetime); 2579 if (result != ISC_R_SUCCESS) { 2580 isc_time_settoepoch(&inc->filetime); 2581 } 2582 2583 ISC_LIST_APPEND(zone->newincludes, inc, link); 2584} 2585 2586static void 2587zone_gotreadhandle(isc_task_t *task, isc_event_t *event) { 2588 dns_load_t *load = event->ev_arg; 2589 isc_result_t result = ISC_R_SUCCESS; 2590 unsigned int options; 2591 2592 REQUIRE(DNS_LOAD_VALID(load)); 2593 2594 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) { 2595 result = ISC_R_CANCELED; 2596 } 2597 isc_event_free(&event); 2598 if (result == ISC_R_CANCELED) { 2599 goto fail; 2600 } 2601 2602 options = get_master_options(load->zone); 2603 2604 result = dns_master_loadfileinc( 2605 load->zone->masterfile, dns_db_origin(load->db), 2606 dns_db_origin(load->db), load->zone->rdclass, options, 0, 2607 &load->callbacks, task, zone_loaddone, load, &load->zone->lctx, 2608 zone_registerinclude, load->zone, load->zone->mctx, 2609 load->zone->masterformat, load->zone->maxttl); 2610 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE && 2611 result != DNS_R_SEENINCLUDE) 2612 { 2613 goto fail; 2614 } 2615 return; 2616 2617fail: 2618 zone_loaddone(load, result); 2619} 2620 2621static void 2622get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) { 2623 isc_result_t result; 2624 unsigned int soacount; 2625 2626 LOCK(&raw->lock); 2627 if (raw->db != NULL) { 2628 result = zone_get_from_db(raw, raw->db, NULL, &soacount, NULL, 2629 &rawdata->sourceserial, NULL, NULL, 2630 NULL, NULL, NULL); 2631 if (result == ISC_R_SUCCESS && soacount > 0U) { 2632 rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET; 2633 } 2634 } 2635 UNLOCK(&raw->lock); 2636} 2637 2638static void 2639zone_gotwritehandle(isc_task_t *task, isc_event_t *event) { 2640 const char me[] = "zone_gotwritehandle"; 2641 dns_zone_t *zone = event->ev_arg; 2642 isc_result_t result = ISC_R_SUCCESS; 2643 dns_dbversion_t *version = NULL; 2644 dns_masterrawheader_t rawdata; 2645 dns_db_t *db = NULL; 2646 2647 REQUIRE(DNS_ZONE_VALID(zone)); 2648 INSIST(task == zone->task); 2649 ENTER; 2650 2651 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) { 2652 result = ISC_R_CANCELED; 2653 } 2654 isc_event_free(&event); 2655 if (result == ISC_R_CANCELED) { 2656 goto fail; 2657 } 2658 2659 LOCK_ZONE(zone); 2660 INSIST(zone != zone->raw); 2661 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 2662 if (zone->db != NULL) { 2663 dns_db_attach(zone->db, &db); 2664 } 2665 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 2666 if (db != NULL) { 2667 const dns_master_style_t *output_style; 2668 dns_db_currentversion(db, &version); 2669 dns_master_initrawheader(&rawdata); 2670 if (inline_secure(zone)) { 2671 get_raw_serial(zone->raw, &rawdata); 2672 } 2673 if (zone->type == dns_zone_key) { 2674 output_style = &dns_master_style_keyzone; 2675 } else if (zone->masterstyle != NULL) { 2676 output_style = zone->masterstyle; 2677 } else { 2678 output_style = &dns_master_style_default; 2679 } 2680 result = dns_master_dumpasync( 2681 zone->mctx, db, version, output_style, zone->masterfile, 2682 zone->task, dump_done, zone, &zone->dctx, 2683 zone->masterformat, &rawdata); 2684 dns_db_closeversion(db, &version, false); 2685 } else { 2686 result = ISC_R_CANCELED; 2687 } 2688 if (db != NULL) { 2689 dns_db_detach(&db); 2690 } 2691 UNLOCK_ZONE(zone); 2692 if (result != DNS_R_CONTINUE) { 2693 goto fail; 2694 } 2695 return; 2696 2697fail: 2698 dump_done(zone, result); 2699} 2700 2701/* 2702 * Save the raw serial number for inline-signing zones. 2703 * (XXX: Other information from the header will be used 2704 * for other purposes in the future, but for now this is 2705 * all we're interested in.) 2706 */ 2707static void 2708zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { 2709 if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0) { 2710 return; 2711 } 2712 2713 zone->sourceserial = header->sourceserial; 2714 zone->sourceserialset = true; 2715} 2716 2717void 2718dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { 2719 if (zone == NULL) { 2720 return; 2721 } 2722 2723 LOCK_ZONE(zone); 2724 zone_setrawdata(zone, header); 2725 UNLOCK_ZONE(zone); 2726} 2727 2728static isc_result_t 2729zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { 2730 const char me[] = "zone_startload"; 2731 dns_load_t *load; 2732 isc_result_t result; 2733 isc_result_t tresult; 2734 unsigned int options; 2735 2736 ENTER; 2737 2738 dns_zone_rpz_enable_db(zone, db); 2739 dns_zone_catz_enable_db(zone, db); 2740 2741 options = get_master_options(zone); 2742 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) { 2743 options |= DNS_MASTER_MANYERRORS; 2744 } 2745 2746 if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) { 2747 load = isc_mem_get(zone->mctx, sizeof(*load)); 2748 2749 load->mctx = NULL; 2750 load->zone = NULL; 2751 load->db = NULL; 2752 load->loadtime = loadtime; 2753 load->magic = LOAD_MAGIC; 2754 2755 isc_mem_attach(zone->mctx, &load->mctx); 2756 zone_iattach(zone, &load->zone); 2757 dns_db_attach(db, &load->db); 2758 dns_rdatacallbacks_init(&load->callbacks); 2759 load->callbacks.rawdata = zone_setrawdata; 2760 zone_iattach(zone, &load->callbacks.zone); 2761 result = dns_db_beginload(db, &load->callbacks); 2762 if (result != ISC_R_SUCCESS) { 2763 goto cleanup; 2764 } 2765 result = zonemgr_getio(zone->zmgr, true, zone->loadtask, 2766 zone_gotreadhandle, load, &zone->readio); 2767 if (result != ISC_R_SUCCESS) { 2768 /* 2769 * We can't report multiple errors so ignore 2770 * the result of dns_db_endload(). 2771 */ 2772 (void)dns_db_endload(load->db, &load->callbacks); 2773 goto cleanup; 2774 } else { 2775 result = DNS_R_CONTINUE; 2776 } 2777 } else { 2778 dns_rdatacallbacks_t callbacks; 2779 2780 dns_rdatacallbacks_init(&callbacks); 2781 callbacks.rawdata = zone_setrawdata; 2782 zone_iattach(zone, &callbacks.zone); 2783 result = dns_db_beginload(db, &callbacks); 2784 if (result != ISC_R_SUCCESS) { 2785 zone_idetach(&callbacks.zone); 2786 return (result); 2787 } 2788 result = dns_master_loadfile( 2789 zone->masterfile, &zone->origin, &zone->origin, 2790 zone->rdclass, options, 0, &callbacks, 2791 zone_registerinclude, zone, zone->mctx, 2792 zone->masterformat, zone->maxttl); 2793 tresult = dns_db_endload(db, &callbacks); 2794 if (result == ISC_R_SUCCESS) { 2795 result = tresult; 2796 } 2797 zone_idetach(&callbacks.zone); 2798 } 2799 2800 return (result); 2801 2802cleanup: 2803 load->magic = 0; 2804 dns_db_detach(&load->db); 2805 zone_idetach(&load->zone); 2806 zone_idetach(&load->callbacks.zone); 2807 isc_mem_detach(&load->mctx); 2808 isc_mem_put(zone->mctx, load, sizeof(*load)); 2809 return (result); 2810} 2811 2812static bool 2813zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2814 dns_name_t *owner) { 2815 isc_result_t result; 2816 char ownerbuf[DNS_NAME_FORMATSIZE]; 2817 char namebuf[DNS_NAME_FORMATSIZE]; 2818 char altbuf[DNS_NAME_FORMATSIZE]; 2819 dns_fixedname_t fixed; 2820 dns_name_t *foundname; 2821 int level; 2822 2823 /* 2824 * "." means the services does not exist. 2825 */ 2826 if (dns_name_equal(name, dns_rootname)) { 2827 return (true); 2828 } 2829 2830 /* 2831 * Outside of zone. 2832 */ 2833 if (!dns_name_issubdomain(name, &zone->origin)) { 2834 if (zone->checkmx != NULL) { 2835 return ((zone->checkmx)(zone, name, owner)); 2836 } 2837 return (true); 2838 } 2839 2840 if (zone->type == dns_zone_primary) { 2841 level = ISC_LOG_ERROR; 2842 } else { 2843 level = ISC_LOG_WARNING; 2844 } 2845 2846 foundname = dns_fixedname_initname(&fixed); 2847 2848 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, 2849 foundname, NULL, NULL); 2850 if (result == ISC_R_SUCCESS) { 2851 return (true); 2852 } 2853 2854 if (result == DNS_R_NXRRSET) { 2855 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0, 2856 NULL, foundname, NULL, NULL); 2857 if (result == ISC_R_SUCCESS) { 2858 return (true); 2859 } 2860 } 2861 2862 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2863 dns_name_format(name, namebuf, sizeof namebuf); 2864 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2865 result == DNS_R_EMPTYNAME) 2866 { 2867 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) { 2868 level = ISC_LOG_WARNING; 2869 } 2870 dns_zone_log(zone, level, 2871 "%s/MX '%s' has no address records (A or AAAA)", 2872 ownerbuf, namebuf); 2873 return ((level == ISC_LOG_WARNING) ? true : false); 2874 } 2875 2876 if (result == DNS_R_CNAME) { 2877 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 2878 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2879 { 2880 level = ISC_LOG_WARNING; 2881 } 2882 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { 2883 dns_zone_log(zone, level, 2884 "%s/MX '%s' is a CNAME (illegal)", 2885 ownerbuf, namebuf); 2886 } 2887 return ((level == ISC_LOG_WARNING) ? true : false); 2888 } 2889 2890 if (result == DNS_R_DNAME) { 2891 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 2892 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2893 { 2894 level = ISC_LOG_WARNING; 2895 } 2896 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { 2897 dns_name_format(foundname, altbuf, sizeof altbuf); 2898 dns_zone_log(zone, level, 2899 "%s/MX '%s' is below a DNAME" 2900 " '%s' (illegal)", 2901 ownerbuf, namebuf, altbuf); 2902 } 2903 return ((level == ISC_LOG_WARNING) ? true : false); 2904 } 2905 2906 if (zone->checkmx != NULL && result == DNS_R_DELEGATION) { 2907 return ((zone->checkmx)(zone, name, owner)); 2908 } 2909 2910 return (true); 2911} 2912 2913static bool 2914zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2915 dns_name_t *owner) { 2916 isc_result_t result; 2917 char ownerbuf[DNS_NAME_FORMATSIZE]; 2918 char namebuf[DNS_NAME_FORMATSIZE]; 2919 char altbuf[DNS_NAME_FORMATSIZE]; 2920 dns_fixedname_t fixed; 2921 dns_name_t *foundname; 2922 int level; 2923 2924 /* 2925 * "." means the services does not exist. 2926 */ 2927 if (dns_name_equal(name, dns_rootname)) { 2928 return (true); 2929 } 2930 2931 /* 2932 * Outside of zone. 2933 */ 2934 if (!dns_name_issubdomain(name, &zone->origin)) { 2935 if (zone->checksrv != NULL) { 2936 return ((zone->checksrv)(zone, name, owner)); 2937 } 2938 return (true); 2939 } 2940 2941 if (zone->type == dns_zone_primary) { 2942 level = ISC_LOG_ERROR; 2943 } else { 2944 level = ISC_LOG_WARNING; 2945 } 2946 2947 foundname = dns_fixedname_initname(&fixed); 2948 2949 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, 2950 foundname, NULL, NULL); 2951 if (result == ISC_R_SUCCESS) { 2952 return (true); 2953 } 2954 2955 if (result == DNS_R_NXRRSET) { 2956 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0, 2957 NULL, foundname, NULL, NULL); 2958 if (result == ISC_R_SUCCESS) { 2959 return (true); 2960 } 2961 } 2962 2963 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2964 dns_name_format(name, namebuf, sizeof namebuf); 2965 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2966 result == DNS_R_EMPTYNAME) 2967 { 2968 dns_zone_log(zone, level, 2969 "%s/SRV '%s' has no address records (A or AAAA)", 2970 ownerbuf, namebuf); 2971 /* XXX950 make fatal for 9.5.0. */ 2972 return (true); 2973 } 2974 2975 if (result == DNS_R_CNAME) { 2976 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 2977 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2978 { 2979 level = ISC_LOG_WARNING; 2980 } 2981 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { 2982 dns_zone_log(zone, level, 2983 "%s/SRV '%s' is a CNAME (illegal)", 2984 ownerbuf, namebuf); 2985 } 2986 return ((level == ISC_LOG_WARNING) ? true : false); 2987 } 2988 2989 if (result == DNS_R_DNAME) { 2990 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 2991 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2992 { 2993 level = ISC_LOG_WARNING; 2994 } 2995 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { 2996 dns_name_format(foundname, altbuf, sizeof altbuf); 2997 dns_zone_log(zone, level, 2998 "%s/SRV '%s' is below a " 2999 "DNAME '%s' (illegal)", 3000 ownerbuf, namebuf, altbuf); 3001 } 3002 return ((level == ISC_LOG_WARNING) ? true : false); 3003 } 3004 3005 if (zone->checksrv != NULL && result == DNS_R_DELEGATION) { 3006 return ((zone->checksrv)(zone, name, owner)); 3007 } 3008 3009 return (true); 3010} 3011 3012static bool 3013zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 3014 dns_name_t *owner) { 3015 bool answer = true; 3016 isc_result_t result, tresult; 3017 char ownerbuf[DNS_NAME_FORMATSIZE]; 3018 char namebuf[DNS_NAME_FORMATSIZE]; 3019 char altbuf[DNS_NAME_FORMATSIZE]; 3020 dns_fixedname_t fixed; 3021 dns_name_t *foundname; 3022 dns_rdataset_t a; 3023 dns_rdataset_t aaaa; 3024 int level; 3025 3026 /* 3027 * Outside of zone. 3028 */ 3029 if (!dns_name_issubdomain(name, &zone->origin)) { 3030 if (zone->checkns != NULL) { 3031 return ((zone->checkns)(zone, name, owner, NULL, NULL)); 3032 } 3033 return (true); 3034 } 3035 3036 if (zone->type == dns_zone_primary) { 3037 level = ISC_LOG_ERROR; 3038 } else { 3039 level = ISC_LOG_WARNING; 3040 } 3041 3042 foundname = dns_fixedname_initname(&fixed); 3043 dns_rdataset_init(&a); 3044 dns_rdataset_init(&aaaa); 3045 3046 /* 3047 * Perform a regular lookup to catch DNAME records then look 3048 * for glue. 3049 */ 3050 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, 3051 foundname, &a, NULL); 3052 switch (result) { 3053 case ISC_R_SUCCESS: 3054 case DNS_R_DNAME: 3055 case DNS_R_CNAME: 3056 break; 3057 default: 3058 if (dns_rdataset_isassociated(&a)) { 3059 dns_rdataset_disassociate(&a); 3060 } 3061 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 3062 DNS_DBFIND_GLUEOK, 0, NULL, foundname, &a, 3063 NULL); 3064 } 3065 if (result == ISC_R_SUCCESS) { 3066 dns_rdataset_disassociate(&a); 3067 return (true); 3068 } else if (result == DNS_R_DELEGATION) { 3069 dns_rdataset_disassociate(&a); 3070 } 3071 3072 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION || 3073 result == DNS_R_GLUE) 3074 { 3075 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 3076 DNS_DBFIND_GLUEOK, 0, NULL, foundname, 3077 &aaaa, NULL); 3078 if (tresult == ISC_R_SUCCESS) { 3079 if (dns_rdataset_isassociated(&a)) { 3080 dns_rdataset_disassociate(&a); 3081 } 3082 dns_rdataset_disassociate(&aaaa); 3083 return (true); 3084 } 3085 if (tresult == DNS_R_DELEGATION || tresult == DNS_R_DNAME) { 3086 dns_rdataset_disassociate(&aaaa); 3087 } 3088 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) { 3089 /* 3090 * Check glue against child zone. 3091 */ 3092 if (zone->checkns != NULL) { 3093 answer = (zone->checkns)(zone, name, owner, &a, 3094 &aaaa); 3095 } 3096 if (dns_rdataset_isassociated(&a)) { 3097 dns_rdataset_disassociate(&a); 3098 } 3099 if (dns_rdataset_isassociated(&aaaa)) { 3100 dns_rdataset_disassociate(&aaaa); 3101 } 3102 return (answer); 3103 } 3104 } 3105 3106 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 3107 dns_name_format(name, namebuf, sizeof namebuf); 3108 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 3109 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) 3110 { 3111 const char *what; 3112 bool required = false; 3113 if (dns_name_issubdomain(name, owner)) { 3114 what = "REQUIRED GLUE "; 3115 required = true; 3116 } else if (result == DNS_R_DELEGATION) { 3117 what = "SIBLING GLUE "; 3118 } else { 3119 what = ""; 3120 } 3121 3122 if (result != DNS_R_DELEGATION || required || 3123 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) 3124 { 3125 dns_zone_log(zone, level, 3126 "%s/NS '%s' has no %s" 3127 "address records (A or AAAA)", 3128 ownerbuf, namebuf, what); 3129 /* 3130 * Log missing address record. 3131 */ 3132 if (result == DNS_R_DELEGATION && zone->checkns != NULL) 3133 { 3134 (void)(zone->checkns)(zone, name, owner, &a, 3135 &aaaa); 3136 } 3137 /* XXX950 make fatal for 9.5.0. */ 3138 /* answer = false; */ 3139 } 3140 } else if (result == DNS_R_CNAME) { 3141 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)", 3142 ownerbuf, namebuf); 3143 /* XXX950 make fatal for 9.5.0. */ 3144 /* answer = false; */ 3145 } else if (result == DNS_R_DNAME) { 3146 dns_name_format(foundname, altbuf, sizeof altbuf); 3147 dns_zone_log(zone, level, 3148 "%s/NS '%s' is below a DNAME '%s' (illegal)", 3149 ownerbuf, namebuf, altbuf); 3150 /* XXX950 make fatal for 9.5.0. */ 3151 /* answer = false; */ 3152 } 3153 3154 if (dns_rdataset_isassociated(&a)) { 3155 dns_rdataset_disassociate(&a); 3156 } 3157 if (dns_rdataset_isassociated(&aaaa)) { 3158 dns_rdataset_disassociate(&aaaa); 3159 } 3160 return (answer); 3161} 3162 3163static bool 3164zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner, 3165 dns_rdataset_t *rdataset) { 3166 dns_rdataset_t tmprdataset; 3167 isc_result_t result; 3168 bool answer = true; 3169 bool format = true; 3170 int level = ISC_LOG_WARNING; 3171 char ownerbuf[DNS_NAME_FORMATSIZE]; 3172 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 3173 unsigned int count1 = 0; 3174 3175 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL)) { 3176 level = ISC_LOG_ERROR; 3177 } 3178 3179 dns_rdataset_init(&tmprdataset); 3180 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 3181 result = dns_rdataset_next(rdataset)) 3182 { 3183 dns_rdata_t rdata1 = DNS_RDATA_INIT; 3184 unsigned int count2 = 0; 3185 3186 count1++; 3187 dns_rdataset_current(rdataset, &rdata1); 3188 dns_rdataset_clone(rdataset, &tmprdataset); 3189 for (result = dns_rdataset_first(&tmprdataset); 3190 result == ISC_R_SUCCESS; 3191 result = dns_rdataset_next(&tmprdataset)) 3192 { 3193 dns_rdata_t rdata2 = DNS_RDATA_INIT; 3194 count2++; 3195 if (count1 >= count2) { 3196 continue; 3197 } 3198 dns_rdataset_current(&tmprdataset, &rdata2); 3199 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) { 3200 if (format) { 3201 dns_name_format(owner, ownerbuf, 3202 sizeof ownerbuf); 3203 dns_rdatatype_format(rdata1.type, 3204 typebuf, 3205 sizeof(typebuf)); 3206 format = false; 3207 } 3208 dns_zone_log(zone, level, 3209 "%s/%s has " 3210 "semantically identical records", 3211 ownerbuf, typebuf); 3212 if (level == ISC_LOG_ERROR) { 3213 answer = false; 3214 } 3215 break; 3216 } 3217 } 3218 dns_rdataset_disassociate(&tmprdataset); 3219 if (!format) { 3220 break; 3221 } 3222 } 3223 return (answer); 3224} 3225 3226static bool 3227zone_check_dup(dns_zone_t *zone, dns_db_t *db) { 3228 dns_dbiterator_t *dbiterator = NULL; 3229 dns_dbnode_t *node = NULL; 3230 dns_fixedname_t fixed; 3231 dns_name_t *name; 3232 dns_rdataset_t rdataset; 3233 dns_rdatasetiter_t *rdsit = NULL; 3234 bool ok = true; 3235 isc_result_t result; 3236 3237 name = dns_fixedname_initname(&fixed); 3238 dns_rdataset_init(&rdataset); 3239 3240 result = dns_db_createiterator(db, 0, &dbiterator); 3241 if (result != ISC_R_SUCCESS) { 3242 return (true); 3243 } 3244 3245 for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS; 3246 result = dns_dbiterator_next(dbiterator)) 3247 { 3248 result = dns_dbiterator_current(dbiterator, &node, name); 3249 if (result != ISC_R_SUCCESS) { 3250 continue; 3251 } 3252 3253 result = dns_db_allrdatasets(db, node, NULL, 0, 0, &rdsit); 3254 if (result != ISC_R_SUCCESS) { 3255 continue; 3256 } 3257 3258 for (result = dns_rdatasetiter_first(rdsit); 3259 result == ISC_R_SUCCESS; 3260 result = dns_rdatasetiter_next(rdsit)) 3261 { 3262 dns_rdatasetiter_current(rdsit, &rdataset); 3263 if (!zone_rrset_check_dup(zone, name, &rdataset)) { 3264 ok = false; 3265 } 3266 dns_rdataset_disassociate(&rdataset); 3267 } 3268 dns_rdatasetiter_destroy(&rdsit); 3269 dns_db_detachnode(db, &node); 3270 } 3271 3272 if (node != NULL) { 3273 dns_db_detachnode(db, &node); 3274 } 3275 dns_dbiterator_destroy(&dbiterator); 3276 3277 return (ok); 3278} 3279 3280static bool 3281isspf(const dns_rdata_t *rdata) { 3282 char buf[1024]; 3283 const unsigned char *data = rdata->data; 3284 unsigned int rdl = rdata->length, i = 0, tl, len; 3285 3286 while (rdl > 0U) { 3287 len = tl = *data; 3288 ++data; 3289 --rdl; 3290 INSIST(tl <= rdl); 3291 if (len > sizeof(buf) - i - 1) { 3292 len = sizeof(buf) - i - 1; 3293 } 3294 memmove(buf + i, data, len); 3295 i += len; 3296 data += tl; 3297 rdl -= tl; 3298 } 3299 3300 if (i < 6U) { 3301 return (false); 3302 } 3303 3304 buf[i] = 0; 3305 if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' ')) { 3306 return (true); 3307 } 3308 return (false); 3309} 3310 3311static bool 3312integrity_checks(dns_zone_t *zone, dns_db_t *db) { 3313 dns_dbiterator_t *dbiterator = NULL; 3314 dns_dbnode_t *node = NULL; 3315 dns_rdataset_t rdataset; 3316 dns_fixedname_t fixed; 3317 dns_fixedname_t fixedbottom; 3318 dns_rdata_mx_t mx; 3319 dns_rdata_ns_t ns; 3320 dns_rdata_in_srv_t srv; 3321 dns_rdata_t rdata; 3322 dns_name_t *name; 3323 dns_name_t *bottom; 3324 isc_result_t result; 3325 bool ok = true, have_spf, have_txt; 3326 3327 name = dns_fixedname_initname(&fixed); 3328 bottom = dns_fixedname_initname(&fixedbottom); 3329 dns_rdataset_init(&rdataset); 3330 dns_rdata_init(&rdata); 3331 3332 result = dns_db_createiterator(db, 0, &dbiterator); 3333 if (result != ISC_R_SUCCESS) { 3334 return (true); 3335 } 3336 3337 result = dns_dbiterator_first(dbiterator); 3338 while (result == ISC_R_SUCCESS) { 3339 result = dns_dbiterator_current(dbiterator, &node, name); 3340 if (result != ISC_R_SUCCESS) { 3341 goto cleanup; 3342 } 3343 3344 /* 3345 * Is this name visible in the zone? 3346 */ 3347 if (!dns_name_issubdomain(name, &zone->origin) || 3348 (dns_name_countlabels(bottom) > 0 && 3349 dns_name_issubdomain(name, bottom))) 3350 { 3351 goto next; 3352 } 3353 3354 dns_dbiterator_pause(dbiterator); 3355 3356 /* 3357 * Don't check the NS records at the origin. 3358 */ 3359 if (dns_name_equal(name, &zone->origin)) { 3360 goto checkfordname; 3361 } 3362 3363 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns, 3364 0, 0, &rdataset, NULL); 3365 if (result != ISC_R_SUCCESS) { 3366 goto checkfordname; 3367 } 3368 /* 3369 * Remember bottom of zone due to NS. 3370 */ 3371 dns_name_copynf(name, bottom); 3372 3373 result = dns_rdataset_first(&rdataset); 3374 while (result == ISC_R_SUCCESS) { 3375 dns_rdataset_current(&rdataset, &rdata); 3376 result = dns_rdata_tostruct(&rdata, &ns, NULL); 3377 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3378 if (!zone_check_glue(zone, db, &ns.name, name)) { 3379 ok = false; 3380 } 3381 dns_rdata_reset(&rdata); 3382 result = dns_rdataset_next(&rdataset); 3383 } 3384 dns_rdataset_disassociate(&rdataset); 3385 goto next; 3386 3387 checkfordname: 3388 result = dns_db_findrdataset(db, node, NULL, 3389 dns_rdatatype_dname, 0, 0, 3390 &rdataset, NULL); 3391 if (result == ISC_R_SUCCESS) { 3392 /* 3393 * Remember bottom of zone due to DNAME. 3394 */ 3395 dns_name_copynf(name, bottom); 3396 dns_rdataset_disassociate(&rdataset); 3397 } 3398 3399 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx, 3400 0, 0, &rdataset, NULL); 3401 if (result != ISC_R_SUCCESS) { 3402 goto checksrv; 3403 } 3404 result = dns_rdataset_first(&rdataset); 3405 while (result == ISC_R_SUCCESS) { 3406 dns_rdataset_current(&rdataset, &rdata); 3407 result = dns_rdata_tostruct(&rdata, &mx, NULL); 3408 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3409 if (!zone_check_mx(zone, db, &mx.mx, name)) { 3410 ok = false; 3411 } 3412 dns_rdata_reset(&rdata); 3413 result = dns_rdataset_next(&rdataset); 3414 } 3415 dns_rdataset_disassociate(&rdataset); 3416 3417 checksrv: 3418 if (zone->rdclass != dns_rdataclass_in) { 3419 goto next; 3420 } 3421 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv, 3422 0, 0, &rdataset, NULL); 3423 if (result != ISC_R_SUCCESS) { 3424 goto checkspf; 3425 } 3426 result = dns_rdataset_first(&rdataset); 3427 while (result == ISC_R_SUCCESS) { 3428 dns_rdataset_current(&rdataset, &rdata); 3429 result = dns_rdata_tostruct(&rdata, &srv, NULL); 3430 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3431 if (!zone_check_srv(zone, db, &srv.target, name)) { 3432 ok = false; 3433 } 3434 dns_rdata_reset(&rdata); 3435 result = dns_rdataset_next(&rdataset); 3436 } 3437 dns_rdataset_disassociate(&rdataset); 3438 3439 checkspf: 3440 /* 3441 * Check if there is a type SPF record without an 3442 * SPF-formatted type TXT record also being present. 3443 */ 3444 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF)) { 3445 goto next; 3446 } 3447 if (zone->rdclass != dns_rdataclass_in) { 3448 goto next; 3449 } 3450 have_spf = have_txt = false; 3451 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf, 3452 0, 0, &rdataset, NULL); 3453 if (result == ISC_R_SUCCESS) { 3454 dns_rdataset_disassociate(&rdataset); 3455 have_spf = true; 3456 } 3457 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt, 3458 0, 0, &rdataset, NULL); 3459 if (result != ISC_R_SUCCESS) { 3460 goto notxt; 3461 } 3462 result = dns_rdataset_first(&rdataset); 3463 while (result == ISC_R_SUCCESS) { 3464 dns_rdataset_current(&rdataset, &rdata); 3465 have_txt = isspf(&rdata); 3466 dns_rdata_reset(&rdata); 3467 if (have_txt) { 3468 break; 3469 } 3470 result = dns_rdataset_next(&rdataset); 3471 } 3472 dns_rdataset_disassociate(&rdataset); 3473 3474 notxt: 3475 if (have_spf && !have_txt) { 3476 char namebuf[DNS_NAME_FORMATSIZE]; 3477 3478 dns_name_format(name, namebuf, sizeof(namebuf)); 3479 dns_zone_log(zone, ISC_LOG_WARNING, 3480 "'%s' found type " 3481 "SPF record but no SPF TXT record found, " 3482 "add matching type TXT record", 3483 namebuf); 3484 } 3485 3486 next: 3487 dns_db_detachnode(db, &node); 3488 result = dns_dbiterator_next(dbiterator); 3489 } 3490 3491cleanup: 3492 if (node != NULL) { 3493 dns_db_detachnode(db, &node); 3494 } 3495 dns_dbiterator_destroy(&dbiterator); 3496 3497 return (ok); 3498} 3499 3500/* 3501 * OpenSSL verification of RSA keys with exponent 3 is known to be 3502 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn 3503 * if they are in use. 3504 */ 3505static void 3506zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) { 3507 dns_dbnode_t *node = NULL; 3508 dns_dbversion_t *version = NULL; 3509 dns_rdata_dnskey_t dnskey; 3510 dns_rdata_t rdata = DNS_RDATA_INIT; 3511 dns_rdataset_t rdataset; 3512 isc_result_t result; 3513 3514 result = dns_db_findnode(db, &zone->origin, false, &node); 3515 if (result != ISC_R_SUCCESS) { 3516 goto cleanup; 3517 } 3518 3519 dns_db_currentversion(db, &version); 3520 dns_rdataset_init(&rdataset); 3521 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 3522 dns_rdatatype_none, 0, &rdataset, NULL); 3523 if (result != ISC_R_SUCCESS) { 3524 goto cleanup; 3525 } 3526 3527 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 3528 result = dns_rdataset_next(&rdataset)) 3529 { 3530 dns_rdataset_current(&rdataset, &rdata); 3531 result = dns_rdata_tostruct(&rdata, &dnskey, NULL); 3532 INSIST(result == ISC_R_SUCCESS); 3533 3534 /* 3535 * RFC 3110, section 4: Performance Considerations: 3536 * 3537 * A public exponent of 3 minimizes the effort needed to verify 3538 * a signature. Use of 3 as the public exponent is weak for 3539 * confidentiality uses since, if the same data can be collected 3540 * encrypted under three different keys with an exponent of 3 3541 * then, using the Chinese Remainder Theorem [NETSEC], the 3542 * original plain text can be easily recovered. If a key is 3543 * known to be used only for authentication, as is the case with 3544 * DNSSEC, then an exponent of 3 is acceptable. However other 3545 * applications in the future may wish to leverage DNS 3546 * distributed keys for applications that do require 3547 * confidentiality. For keys which might have such other uses, 3548 * a more conservative choice would be 65537 (F4, the fourth 3549 * fermat number). 3550 */ 3551 if (dnskey.datalen > 1 && dnskey.data[0] == 1 && 3552 dnskey.data[1] == 3 && 3553 (dnskey.algorithm == DNS_KEYALG_RSAMD5 || 3554 dnskey.algorithm == DNS_KEYALG_RSASHA1 || 3555 dnskey.algorithm == DNS_KEYALG_NSEC3RSASHA1 || 3556 dnskey.algorithm == DNS_KEYALG_RSASHA256 || 3557 dnskey.algorithm == DNS_KEYALG_RSASHA512)) 3558 { 3559 char algorithm[DNS_SECALG_FORMATSIZE]; 3560 isc_region_t r; 3561 3562 dns_rdata_toregion(&rdata, &r); 3563 dns_secalg_format(dnskey.algorithm, algorithm, 3564 sizeof(algorithm)); 3565 3566 dnssec_log(zone, ISC_LOG_WARNING, 3567 "weak %s (%u) key found (exponent=3, id=%u)", 3568 algorithm, dnskey.algorithm, 3569 dst_region_computeid(&r)); 3570 } 3571 dns_rdata_reset(&rdata); 3572 } 3573 dns_rdataset_disassociate(&rdataset); 3574 3575cleanup: 3576 if (node != NULL) { 3577 dns_db_detachnode(db, &node); 3578 } 3579 if (version != NULL) { 3580 dns_db_closeversion(db, &version, false); 3581 } 3582} 3583 3584static void 3585resume_signingwithkey(dns_zone_t *zone) { 3586 dns_dbnode_t *node = NULL; 3587 dns_dbversion_t *version = NULL; 3588 dns_rdata_t rdata = DNS_RDATA_INIT; 3589 dns_rdataset_t rdataset; 3590 isc_result_t result; 3591 dns_db_t *db = NULL; 3592 3593 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3594 if (zone->db != NULL) { 3595 dns_db_attach(zone->db, &db); 3596 } 3597 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3598 if (db == NULL) { 3599 goto cleanup; 3600 } 3601 3602 result = dns_db_findnode(db, &zone->origin, false, &node); 3603 if (result != ISC_R_SUCCESS) { 3604 goto cleanup; 3605 } 3606 3607 dns_db_currentversion(db, &version); 3608 dns_rdataset_init(&rdataset); 3609 result = dns_db_findrdataset(db, node, version, zone->privatetype, 3610 dns_rdatatype_none, 0, &rdataset, NULL); 3611 if (result != ISC_R_SUCCESS) { 3612 INSIST(!dns_rdataset_isassociated(&rdataset)); 3613 goto cleanup; 3614 } 3615 3616 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 3617 result = dns_rdataset_next(&rdataset)) 3618 { 3619 dns_rdataset_current(&rdataset, &rdata); 3620 if (rdata.length != 5 || rdata.data[0] == 0 || 3621 rdata.data[4] != 0) 3622 { 3623 dns_rdata_reset(&rdata); 3624 continue; 3625 } 3626 3627 result = zone_signwithkey(zone, rdata.data[0], 3628 (rdata.data[1] << 8) | rdata.data[2], 3629 rdata.data[3]); 3630 if (result != ISC_R_SUCCESS) { 3631 dnssec_log(zone, ISC_LOG_ERROR, 3632 "zone_signwithkey failed: %s", 3633 dns_result_totext(result)); 3634 } 3635 dns_rdata_reset(&rdata); 3636 } 3637 dns_rdataset_disassociate(&rdataset); 3638 3639cleanup: 3640 if (db != NULL) { 3641 if (node != NULL) { 3642 dns_db_detachnode(db, &node); 3643 } 3644 if (version != NULL) { 3645 dns_db_closeversion(db, &version, false); 3646 } 3647 dns_db_detach(&db); 3648 } 3649} 3650 3651/* 3652 * Initiate adding/removing NSEC3 records belonging to the chain defined by the 3653 * supplied NSEC3PARAM RDATA. 3654 * 3655 * Zone must be locked by caller. 3656 */ 3657static isc_result_t 3658zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 3659 dns_nsec3chain_t *nsec3chain, *current; 3660 dns_dbversion_t *version = NULL; 3661 bool nseconly = false, nsec3ok = false; 3662 isc_result_t result; 3663 isc_time_t now; 3664 unsigned int options = 0; 3665 char saltbuf[255 * 2 + 1]; 3666 char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")]; 3667 dns_db_t *db = NULL; 3668 3669 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3670 if (zone->db != NULL) { 3671 dns_db_attach(zone->db, &db); 3672 } 3673 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3674 3675 if (db == NULL) { 3676 result = ISC_R_SUCCESS; 3677 goto cleanup; 3678 } 3679 3680 /* 3681 * If this zone is not NSEC3-capable, attempting to remove any NSEC3 3682 * chain from it is pointless as it would not be possible for the 3683 * latter to exist in the first place. 3684 */ 3685 dns_db_currentversion(db, &version); 3686 result = dns_nsec_nseconly(db, version, &nseconly); 3687 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 3688 dns_db_closeversion(db, &version, false); 3689 if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) { 3690 result = ISC_R_SUCCESS; 3691 goto cleanup; 3692 } 3693 3694 /* 3695 * Allocate and initialize structure preserving state of 3696 * adding/removing records belonging to this NSEC3 chain between 3697 * separate zone_nsec3chain() calls. 3698 */ 3699 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain); 3700 3701 nsec3chain->magic = 0; 3702 nsec3chain->done = false; 3703 nsec3chain->db = NULL; 3704 nsec3chain->dbiterator = NULL; 3705 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass; 3706 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype; 3707 nsec3chain->nsec3param.hash = nsec3param->hash; 3708 nsec3chain->nsec3param.iterations = nsec3param->iterations; 3709 nsec3chain->nsec3param.flags = nsec3param->flags; 3710 nsec3chain->nsec3param.salt_length = nsec3param->salt_length; 3711 memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length); 3712 nsec3chain->nsec3param.salt = nsec3chain->salt; 3713 nsec3chain->seen_nsec = false; 3714 nsec3chain->delete_nsec = false; 3715 nsec3chain->save_delete_nsec = false; 3716 3717 /* 3718 * Log NSEC3 parameters defined by supplied NSEC3PARAM RDATA. 3719 */ 3720 if (nsec3param->flags == 0) { 3721 strlcpy(flags, "NONE", sizeof(flags)); 3722 } else { 3723 flags[0] = '\0'; 3724 if ((nsec3param->flags & DNS_NSEC3FLAG_REMOVE) != 0) { 3725 strlcat(flags, "REMOVE", sizeof(flags)); 3726 } 3727 if ((nsec3param->flags & DNS_NSEC3FLAG_INITIAL) != 0) { 3728 if (flags[0] == '\0') { 3729 strlcpy(flags, "INITIAL", sizeof(flags)); 3730 } else { 3731 strlcat(flags, "|INITIAL", sizeof(flags)); 3732 } 3733 } 3734 if ((nsec3param->flags & DNS_NSEC3FLAG_CREATE) != 0) { 3735 if (flags[0] == '\0') { 3736 strlcpy(flags, "CREATE", sizeof(flags)); 3737 } else { 3738 strlcat(flags, "|CREATE", sizeof(flags)); 3739 } 3740 } 3741 if ((nsec3param->flags & DNS_NSEC3FLAG_NONSEC) != 0) { 3742 if (flags[0] == '\0') { 3743 strlcpy(flags, "NONSEC", sizeof(flags)); 3744 } else { 3745 strlcat(flags, "|NONSEC", sizeof(flags)); 3746 } 3747 } 3748 if ((nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) != 0) { 3749 if (flags[0] == '\0') { 3750 strlcpy(flags, "OPTOUT", sizeof(flags)); 3751 } else { 3752 strlcat(flags, "|OPTOUT", sizeof(flags)); 3753 } 3754 } 3755 } 3756 result = dns_nsec3param_salttotext(nsec3param, saltbuf, 3757 sizeof(saltbuf)); 3758 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3759 dnssec_log(zone, ISC_LOG_INFO, "zone_addnsec3chain(%u,%s,%u,%s)", 3760 nsec3param->hash, flags, nsec3param->iterations, saltbuf); 3761 3762 /* 3763 * If the NSEC3 chain defined by the supplied NSEC3PARAM RDATA is 3764 * currently being processed, interrupt its processing to avoid 3765 * simultaneously adding and removing records for the same NSEC3 chain. 3766 */ 3767 for (current = ISC_LIST_HEAD(zone->nsec3chain); current != NULL; 3768 current = ISC_LIST_NEXT(current, link)) 3769 { 3770 if ((current->db == db) && 3771 (current->nsec3param.hash == nsec3param->hash) && 3772 (current->nsec3param.iterations == 3773 nsec3param->iterations) && 3774 (current->nsec3param.salt_length == 3775 nsec3param->salt_length) && 3776 memcmp(current->nsec3param.salt, nsec3param->salt, 3777 nsec3param->salt_length) == 0) 3778 { 3779 current->done = true; 3780 } 3781 } 3782 3783 /* 3784 * Attach zone database to the structure initialized above and create 3785 * an iterator for it with appropriate options in order to avoid 3786 * creating NSEC3 records for NSEC3 records. 3787 */ 3788 dns_db_attach(db, &nsec3chain->db); 3789 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) { 3790 options = DNS_DB_NONSEC3; 3791 } 3792 result = dns_db_createiterator(nsec3chain->db, options, 3793 &nsec3chain->dbiterator); 3794 if (result == ISC_R_SUCCESS) { 3795 result = dns_dbiterator_first(nsec3chain->dbiterator); 3796 } 3797 if (result == ISC_R_SUCCESS) { 3798 /* 3799 * Database iterator initialization succeeded. We are now 3800 * ready to kick off adding/removing records belonging to this 3801 * NSEC3 chain. Append the structure initialized above to the 3802 * "nsec3chain" list for the zone and set the appropriate zone 3803 * timer so that zone_nsec3chain() is called as soon as 3804 * possible. 3805 */ 3806 dns_dbiterator_pause(nsec3chain->dbiterator); 3807 ISC_LIST_INITANDAPPEND(zone->nsec3chain, nsec3chain, link); 3808 nsec3chain = NULL; 3809 if (isc_time_isepoch(&zone->nsec3chaintime)) { 3810 TIME_NOW(&now); 3811 zone->nsec3chaintime = now; 3812 if (zone->task != NULL) { 3813 zone_settimer(zone, &now); 3814 } 3815 } 3816 } 3817 3818 if (nsec3chain != NULL) { 3819 if (nsec3chain->db != NULL) { 3820 dns_db_detach(&nsec3chain->db); 3821 } 3822 if (nsec3chain->dbiterator != NULL) { 3823 dns_dbiterator_destroy(&nsec3chain->dbiterator); 3824 } 3825 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 3826 } 3827 3828cleanup: 3829 if (db != NULL) { 3830 dns_db_detach(&db); 3831 } 3832 return (result); 3833} 3834 3835/* 3836 * Find private-type records at the zone apex which signal that an NSEC3 chain 3837 * should be added or removed. For each such record, extract NSEC3PARAM RDATA 3838 * and pass it to zone_addnsec3chain(). 3839 * 3840 * Zone must be locked by caller. 3841 */ 3842static void 3843resume_addnsec3chain(dns_zone_t *zone) { 3844 dns_dbnode_t *node = NULL; 3845 dns_dbversion_t *version = NULL; 3846 dns_rdataset_t rdataset; 3847 isc_result_t result; 3848 dns_rdata_nsec3param_t nsec3param; 3849 bool nseconly = false, nsec3ok = false; 3850 dns_db_t *db = NULL; 3851 3852 INSIST(LOCKED_ZONE(zone)); 3853 3854 if (zone->privatetype == 0) { 3855 return; 3856 } 3857 3858 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3859 if (zone->db != NULL) { 3860 dns_db_attach(zone->db, &db); 3861 } 3862 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3863 if (db == NULL) { 3864 goto cleanup; 3865 } 3866 3867 result = dns_db_findnode(db, &zone->origin, false, &node); 3868 if (result != ISC_R_SUCCESS) { 3869 goto cleanup; 3870 } 3871 3872 dns_db_currentversion(db, &version); 3873 3874 /* 3875 * In order to create NSEC3 chains we need the DNSKEY RRset at zone 3876 * apex to exist and contain no keys using NSEC-only algorithms. 3877 */ 3878 result = dns_nsec_nseconly(db, version, &nseconly); 3879 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 3880 3881 /* 3882 * Get the RRset containing all private-type records at the zone apex. 3883 */ 3884 dns_rdataset_init(&rdataset); 3885 result = dns_db_findrdataset(db, node, version, zone->privatetype, 3886 dns_rdatatype_none, 0, &rdataset, NULL); 3887 if (result != ISC_R_SUCCESS) { 3888 INSIST(!dns_rdataset_isassociated(&rdataset)); 3889 goto cleanup; 3890 } 3891 3892 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 3893 result = dns_rdataset_next(&rdataset)) 3894 { 3895 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 3896 dns_rdata_t rdata = DNS_RDATA_INIT; 3897 dns_rdata_t private = DNS_RDATA_INIT; 3898 3899 dns_rdataset_current(&rdataset, &private); 3900 /* 3901 * Try extracting NSEC3PARAM RDATA from this private-type 3902 * record. Failure means this private-type record does not 3903 * represent an NSEC3PARAM record, so skip it. 3904 */ 3905 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 3906 sizeof(buf))) 3907 { 3908 continue; 3909 } 3910 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 3911 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3912 if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) || 3913 ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok)) 3914 { 3915 /* 3916 * Pass the NSEC3PARAM RDATA contained in this 3917 * private-type record to zone_addnsec3chain() so that 3918 * it can kick off adding or removing NSEC3 records. 3919 */ 3920 result = zone_addnsec3chain(zone, &nsec3param); 3921 if (result != ISC_R_SUCCESS) { 3922 dnssec_log(zone, ISC_LOG_ERROR, 3923 "zone_addnsec3chain failed: %s", 3924 dns_result_totext(result)); 3925 } 3926 } 3927 } 3928 dns_rdataset_disassociate(&rdataset); 3929 3930cleanup: 3931 if (db != NULL) { 3932 if (node != NULL) { 3933 dns_db_detachnode(db, &node); 3934 } 3935 if (version != NULL) { 3936 dns_db_closeversion(db, &version, false); 3937 } 3938 dns_db_detach(&db); 3939 } 3940} 3941 3942static void 3943set_resigntime(dns_zone_t *zone) { 3944 dns_rdataset_t rdataset; 3945 dns_fixedname_t fixed; 3946 unsigned int resign; 3947 isc_result_t result; 3948 uint32_t nanosecs; 3949 dns_db_t *db = NULL; 3950 3951 INSIST(LOCKED_ZONE(zone)); 3952 3953 /* We only re-sign zones that can be dynamically updated */ 3954 if (zone->update_disabled) { 3955 return; 3956 } 3957 3958 if (!inline_secure(zone) && 3959 (zone->type != dns_zone_primary || 3960 (zone->ssutable == NULL && 3961 (zone->update_acl == NULL || dns_acl_isnone(zone->update_acl))))) 3962 { 3963 return; 3964 } 3965 3966 dns_rdataset_init(&rdataset); 3967 dns_fixedname_init(&fixed); 3968 3969 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3970 if (zone->db != NULL) { 3971 dns_db_attach(zone->db, &db); 3972 } 3973 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3974 if (db == NULL) { 3975 isc_time_settoepoch(&zone->resigntime); 3976 return; 3977 } 3978 3979 result = dns_db_getsigningtime(db, &rdataset, 3980 dns_fixedname_name(&fixed)); 3981 if (result != ISC_R_SUCCESS) { 3982 isc_time_settoepoch(&zone->resigntime); 3983 goto cleanup; 3984 } 3985 3986 resign = rdataset.resign - dns_zone_getsigresigninginterval(zone); 3987 dns_rdataset_disassociate(&rdataset); 3988 nanosecs = isc_random_uniform(1000000000); 3989 isc_time_set(&zone->resigntime, resign, nanosecs); 3990 3991cleanup: 3992 dns_db_detach(&db); 3993 return; 3994} 3995 3996static isc_result_t 3997check_nsec3param(dns_zone_t *zone, dns_db_t *db) { 3998 bool ok = false; 3999 dns_dbnode_t *node = NULL; 4000 dns_dbversion_t *version = NULL; 4001 dns_rdata_nsec3param_t nsec3param; 4002 dns_rdataset_t rdataset; 4003 isc_result_t result; 4004 bool dynamic = (zone->type == dns_zone_primary) 4005 ? dns_zone_isdynamic(zone, false) 4006 : false; 4007 4008 dns_rdataset_init(&rdataset); 4009 result = dns_db_findnode(db, &zone->origin, false, &node); 4010 if (result != ISC_R_SUCCESS) { 4011 dns_zone_log(zone, ISC_LOG_ERROR, 4012 "nsec3param lookup failure: %s", 4013 dns_result_totext(result)); 4014 return (result); 4015 } 4016 dns_db_currentversion(db, &version); 4017 4018 result = dns_db_findrdataset(db, node, version, 4019 dns_rdatatype_nsec3param, 4020 dns_rdatatype_none, 0, &rdataset, NULL); 4021 if (result == ISC_R_NOTFOUND) { 4022 INSIST(!dns_rdataset_isassociated(&rdataset)); 4023 result = ISC_R_SUCCESS; 4024 goto cleanup; 4025 } 4026 if (result != ISC_R_SUCCESS) { 4027 INSIST(!dns_rdataset_isassociated(&rdataset)); 4028 dns_zone_log(zone, ISC_LOG_ERROR, 4029 "nsec3param lookup failure: %s", 4030 dns_result_totext(result)); 4031 goto cleanup; 4032 } 4033 4034 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 4035 result = dns_rdataset_next(&rdataset)) 4036 { 4037 dns_rdata_t rdata = DNS_RDATA_INIT; 4038 4039 dns_rdataset_current(&rdataset, &rdata); 4040 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 4041 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4042 4043 /* 4044 * For dynamic zones we must support every algorithm so we 4045 * can regenerate all the NSEC3 chains. 4046 * For non-dynamic zones we only need to find a supported 4047 * algorithm. 4048 */ 4049 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) && 4050 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic) 4051 { 4052 dns_zone_log(zone, ISC_LOG_WARNING, 4053 "nsec3 test \"unknown\" hash algorithm " 4054 "found: %u", 4055 nsec3param.hash); 4056 ok = true; 4057 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) { 4058 if (dynamic) { 4059 dns_zone_log(zone, ISC_LOG_ERROR, 4060 "unsupported nsec3 hash algorithm" 4061 " in dynamic zone: %u", 4062 nsec3param.hash); 4063 result = DNS_R_BADZONE; 4064 /* Stop second error message. */ 4065 ok = true; 4066 break; 4067 } else { 4068 dns_zone_log(zone, ISC_LOG_WARNING, 4069 "unsupported nsec3 hash " 4070 "algorithm: %u", 4071 nsec3param.hash); 4072 } 4073 } else { 4074 ok = true; 4075 } 4076 4077 /* 4078 * Warn if the zone has excessive NSEC3 iterations. 4079 */ 4080 if (nsec3param.iterations > dns_nsec3_maxiterations()) { 4081 dnssec_log(zone, ISC_LOG_WARNING, 4082 "excessive NSEC3PARAM iterations %u > %u", 4083 nsec3param.iterations, 4084 dns_nsec3_maxiterations()); 4085 } 4086 } 4087 if (result == ISC_R_NOMORE) { 4088 result = ISC_R_SUCCESS; 4089 } 4090 4091 if (!ok) { 4092 result = DNS_R_BADZONE; 4093 dns_zone_log(zone, ISC_LOG_ERROR, 4094 "no supported nsec3 hash algorithm"); 4095 } 4096 4097cleanup: 4098 if (dns_rdataset_isassociated(&rdataset)) { 4099 dns_rdataset_disassociate(&rdataset); 4100 } 4101 dns_db_closeversion(db, &version, false); 4102 dns_db_detachnode(db, &node); 4103 return (result); 4104} 4105 4106/* 4107 * Set the timer for refreshing the key zone to the soonest future time 4108 * of the set (current timer, keydata->refresh, keydata->addhd, 4109 * keydata->removehd). 4110 */ 4111static void 4112set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key, 4113 isc_stdtime_t now, bool force) { 4114 const char me[] = "set_refreshkeytimer"; 4115 isc_stdtime_t then; 4116 isc_time_t timenow, timethen; 4117 char timebuf[80]; 4118 4119 ENTER; 4120 then = key->refresh; 4121 if (force) { 4122 then = now; 4123 } 4124 if (key->addhd > now && key->addhd < then) { 4125 then = key->addhd; 4126 } 4127 if (key->removehd > now && key->removehd < then) { 4128 then = key->removehd; 4129 } 4130 4131 TIME_NOW(&timenow); 4132 if (then > now) { 4133 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 4134 } else { 4135 timethen = timenow; 4136 } 4137 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 || 4138 isc_time_compare(&timethen, &zone->refreshkeytime) < 0) 4139 { 4140 zone->refreshkeytime = timethen; 4141 } 4142 4143 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 4144 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf); 4145 zone_settimer(zone, &timenow); 4146} 4147 4148/* 4149 * If keynode references a key or a DS rdataset, and if the key 4150 * zone does not contain a KEYDATA record for the corresponding name, 4151 * then create an empty KEYDATA and push it into the zone as a placeholder, 4152 * then schedule a key refresh immediately. This new KEYDATA record will be 4153 * updated during the refresh. 4154 * 4155 * If the key zone is changed, set '*changed' to true. 4156 */ 4157static isc_result_t 4158create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 4159 dns_diff_t *diff, dns_keynode_t *keynode, dns_name_t *keyname, 4160 bool *changed) { 4161 const char me[] = "create_keydata"; 4162 isc_result_t result = ISC_R_SUCCESS; 4163 dns_rdata_t rdata = DNS_RDATA_INIT; 4164 dns_rdata_keydata_t kd; 4165 unsigned char rrdata[4096]; 4166 isc_buffer_t rrdatabuf; 4167 isc_stdtime_t now; 4168 4169 REQUIRE(keynode != NULL); 4170 4171 ENTER; 4172 isc_stdtime_get(&now); 4173 4174 /* 4175 * If the keynode has no trust anchor set, we shouldn't be here. 4176 */ 4177 if (!dns_keynode_dsset(keynode, NULL)) { 4178 return (ISC_R_FAILURE); 4179 } 4180 4181 memset(&kd, 0, sizeof(kd)); 4182 kd.common.rdclass = zone->rdclass; 4183 kd.common.rdtype = dns_rdatatype_keydata; 4184 ISC_LINK_INIT(&kd.common, link); 4185 4186 isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); 4187 4188 CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass, dns_rdatatype_keydata, 4189 &kd, &rrdatabuf)); 4190 /* Add rdata to zone. */ 4191 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, keyname, 0, &rdata)); 4192 *changed = true; 4193 4194 /* Refresh new keys from the zone apex as soon as possible. */ 4195 set_refreshkeytimer(zone, &kd, now, true); 4196 return (ISC_R_SUCCESS); 4197 4198failure: 4199 return (result); 4200} 4201 4202/* 4203 * Remove from the key zone all the KEYDATA records found in rdataset. 4204 */ 4205static isc_result_t 4206delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 4207 dns_name_t *name, dns_rdataset_t *rdataset) { 4208 dns_rdata_t rdata = DNS_RDATA_INIT; 4209 isc_result_t result, uresult; 4210 4211 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 4212 result = dns_rdataset_next(rdataset)) 4213 { 4214 dns_rdata_reset(&rdata); 4215 dns_rdataset_current(rdataset, &rdata); 4216 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 0, 4217 &rdata); 4218 if (uresult != ISC_R_SUCCESS) { 4219 return (uresult); 4220 } 4221 } 4222 if (result == ISC_R_NOMORE) { 4223 result = ISC_R_SUCCESS; 4224 } 4225 return (result); 4226} 4227 4228/* 4229 * Compute the DNSSEC key ID for a DNSKEY record. 4230 */ 4231static isc_result_t 4232compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx, 4233 dns_keytag_t *tag) { 4234 isc_result_t result; 4235 dns_rdata_t rdata = DNS_RDATA_INIT; 4236 unsigned char data[4096]; 4237 isc_buffer_t buffer; 4238 dst_key_t *dstkey = NULL; 4239 4240 isc_buffer_init(&buffer, data, sizeof(data)); 4241 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 4242 dns_rdatatype_dnskey, dnskey, &buffer); 4243 4244 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey); 4245 if (result == ISC_R_SUCCESS) { 4246 *tag = dst_key_id(dstkey); 4247 dst_key_free(&dstkey); 4248 } 4249 4250 return (result); 4251} 4252 4253/* 4254 * Add key to the security roots. 4255 */ 4256static void 4257trust_key(dns_zone_t *zone, dns_name_t *keyname, dns_rdata_dnskey_t *dnskey, 4258 bool initial) { 4259 isc_result_t result; 4260 dns_rdata_t rdata = DNS_RDATA_INIT; 4261 unsigned char data[4096], digest[ISC_MAX_MD_SIZE]; 4262 isc_buffer_t buffer; 4263 dns_keytable_t *sr = NULL; 4264 dns_rdata_ds_t ds; 4265 4266 result = dns_view_getsecroots(zone->view, &sr); 4267 if (result != ISC_R_SUCCESS) { 4268 return; 4269 } 4270 4271 /* Build DS record for key. */ 4272 isc_buffer_init(&buffer, data, sizeof(data)); 4273 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 4274 dns_rdatatype_dnskey, dnskey, &buffer); 4275 CHECK(dns_ds_fromkeyrdata(keyname, &rdata, DNS_DSDIGEST_SHA256, digest, 4276 &ds)); 4277 CHECK(dns_keytable_add(sr, true, initial, keyname, &ds)); 4278 4279 dns_keytable_detach(&sr); 4280 4281failure: 4282 if (sr != NULL) { 4283 dns_keytable_detach(&sr); 4284 } 4285 return; 4286} 4287 4288/* 4289 * Add a null key to the security roots for so that all queries 4290 * to the zone will fail. 4291 */ 4292static void 4293fail_secure(dns_zone_t *zone, dns_name_t *keyname) { 4294 isc_result_t result; 4295 dns_keytable_t *sr = NULL; 4296 4297 result = dns_view_getsecroots(zone->view, &sr); 4298 if (result == ISC_R_SUCCESS) { 4299 dns_keytable_marksecure(sr, keyname); 4300 dns_keytable_detach(&sr); 4301 } 4302} 4303 4304/* 4305 * Scan a set of KEYDATA records from the key zone. The ones that are 4306 * valid (i.e., the add holddown timer has expired) become trusted keys. 4307 */ 4308static void 4309load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) { 4310 isc_result_t result; 4311 dns_rdata_t rdata = DNS_RDATA_INIT; 4312 dns_rdata_keydata_t keydata; 4313 dns_rdata_dnskey_t dnskey; 4314 int trusted = 0, revoked = 0, pending = 0; 4315 isc_stdtime_t now; 4316 dns_keytable_t *sr = NULL; 4317 4318 isc_stdtime_get(&now); 4319 4320 result = dns_view_getsecroots(zone->view, &sr); 4321 if (result == ISC_R_SUCCESS) { 4322 dns_keytable_delete(sr, name); 4323 dns_keytable_detach(&sr); 4324 } 4325 4326 /* Now insert all the accepted trust anchors from this keydata set. */ 4327 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 4328 result = dns_rdataset_next(rdataset)) 4329 { 4330 dns_rdata_reset(&rdata); 4331 dns_rdataset_current(rdataset, &rdata); 4332 4333 /* Convert rdata to keydata. */ 4334 result = dns_rdata_tostruct(&rdata, &keydata, NULL); 4335 if (result == ISC_R_UNEXPECTEDEND) { 4336 continue; 4337 } 4338 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4339 4340 /* Set the key refresh timer to force a fast refresh. */ 4341 set_refreshkeytimer(zone, &keydata, now, true); 4342 4343 /* If the removal timer is nonzero, this key was revoked. */ 4344 if (keydata.removehd != 0) { 4345 revoked++; 4346 continue; 4347 } 4348 4349 /* 4350 * If the add timer is still pending, this key is not 4351 * trusted yet. 4352 */ 4353 if (now < keydata.addhd) { 4354 pending++; 4355 continue; 4356 } 4357 4358 /* Convert keydata to dnskey. */ 4359 dns_keydata_todnskey(&keydata, &dnskey, NULL); 4360 4361 /* Add to keytables. */ 4362 trusted++; 4363 trust_key(zone, name, &dnskey, (keydata.addhd == 0)); 4364 } 4365 4366 if (trusted == 0 && pending != 0) { 4367 char namebuf[DNS_NAME_FORMATSIZE]; 4368 dns_name_format(name, namebuf, sizeof namebuf); 4369 dnssec_log(zone, ISC_LOG_ERROR, 4370 "No valid trust anchors for '%s'!", namebuf); 4371 dnssec_log(zone, ISC_LOG_ERROR, 4372 "%d key(s) revoked, %d still pending", revoked, 4373 pending); 4374 dnssec_log(zone, ISC_LOG_ERROR, "All queries to '%s' will fail", 4375 namebuf); 4376 fail_secure(zone, name); 4377 } 4378} 4379 4380static isc_result_t 4381do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, 4382 dns_diff_t *diff) { 4383 dns_diff_t temp_diff; 4384 isc_result_t result; 4385 4386 /* 4387 * Create a singleton diff. 4388 */ 4389 dns_diff_init(diff->mctx, &temp_diff); 4390 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); 4391 4392 /* 4393 * Apply it to the database. 4394 */ 4395 result = dns_diff_apply(&temp_diff, db, ver); 4396 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); 4397 if (result != ISC_R_SUCCESS) { 4398 dns_difftuple_free(tuple); 4399 return (result); 4400 } 4401 4402 /* 4403 * Merge it into the current pending journal entry. 4404 */ 4405 dns_diff_appendminimal(diff, tuple); 4406 4407 /* 4408 * Do not clear temp_diff. 4409 */ 4410 return (ISC_R_SUCCESS); 4411} 4412 4413static isc_result_t 4414update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 4415 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, 4416 dns_rdata_t *rdata) { 4417 dns_difftuple_t *tuple = NULL; 4418 isc_result_t result; 4419 result = dns_difftuple_create(diff->mctx, op, name, ttl, rdata, &tuple); 4420 if (result != ISC_R_SUCCESS) { 4421 return (result); 4422 } 4423 return (do_one_tuple(&tuple, db, ver, diff)); 4424} 4425 4426static isc_result_t 4427update_soa_serial(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 4428 dns_diff_t *diff, isc_mem_t *mctx, 4429 dns_updatemethod_t method) { 4430 dns_difftuple_t *deltuple = NULL; 4431 dns_difftuple_t *addtuple = NULL; 4432 uint32_t serial; 4433 isc_result_t result; 4434 dns_updatemethod_t used = dns_updatemethod_none; 4435 4436 INSIST(method != dns_updatemethod_none); 4437 4438 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple)); 4439 CHECK(dns_difftuple_copy(deltuple, &addtuple)); 4440 addtuple->op = DNS_DIFFOP_ADD; 4441 4442 serial = dns_soa_getserial(&addtuple->rdata); 4443 serial = dns_update_soaserial(serial, method, &used); 4444 if (method != used) { 4445 dns_zone_log(zone, ISC_LOG_WARNING, 4446 "update_soa_serial:new serial would be lower than " 4447 "old serial, using increment method instead"); 4448 } 4449 dns_soa_setserial(serial, &addtuple->rdata); 4450 CHECK(do_one_tuple(&deltuple, db, ver, diff)); 4451 CHECK(do_one_tuple(&addtuple, db, ver, diff)); 4452 result = ISC_R_SUCCESS; 4453 4454failure: 4455 if (addtuple != NULL) { 4456 dns_difftuple_free(&addtuple); 4457 } 4458 if (deltuple != NULL) { 4459 dns_difftuple_free(&deltuple); 4460 } 4461 return (result); 4462} 4463 4464/* 4465 * Write all transactions in 'diff' to the zone journal file. 4466 */ 4467static isc_result_t 4468zone_journal(dns_zone_t *zone, dns_diff_t *diff, uint32_t *sourceserial, 4469 const char *caller) { 4470 const char me[] = "zone_journal"; 4471 const char *journalfile; 4472 isc_result_t result = ISC_R_SUCCESS; 4473 dns_journal_t *journal = NULL; 4474 unsigned int mode = DNS_JOURNAL_CREATE | DNS_JOURNAL_WRITE; 4475 4476 ENTER; 4477 journalfile = dns_zone_getjournal(zone); 4478 if (journalfile != NULL) { 4479 result = dns_journal_open(zone->mctx, journalfile, mode, 4480 &journal); 4481 if (result != ISC_R_SUCCESS) { 4482 dns_zone_log(zone, ISC_LOG_ERROR, 4483 "%s:dns_journal_open -> %s", caller, 4484 dns_result_totext(result)); 4485 return (result); 4486 } 4487 4488 if (sourceserial != NULL) { 4489 dns_journal_set_sourceserial(journal, *sourceserial); 4490 } 4491 4492 result = dns_journal_write_transaction(journal, diff); 4493 if (result != ISC_R_SUCCESS) { 4494 dns_zone_log(zone, ISC_LOG_ERROR, 4495 "%s:dns_journal_write_transaction -> %s", 4496 caller, dns_result_totext(result)); 4497 } 4498 dns_journal_destroy(&journal); 4499 } 4500 4501 return (result); 4502} 4503 4504/* 4505 * Create an SOA record for a newly-created zone 4506 */ 4507static isc_result_t 4508add_soa(dns_zone_t *zone, dns_db_t *db) { 4509 isc_result_t result; 4510 dns_rdata_t rdata = DNS_RDATA_INIT; 4511 unsigned char buf[DNS_SOA_BUFFERSIZE]; 4512 dns_dbversion_t *ver = NULL; 4513 dns_diff_t diff; 4514 4515 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA"); 4516 4517 dns_diff_init(zone->mctx, &diff); 4518 result = dns_db_newversion(db, &ver); 4519 if (result != ISC_R_SUCCESS) { 4520 dns_zone_log(zone, ISC_LOG_ERROR, 4521 "add_soa:dns_db_newversion -> %s", 4522 dns_result_totext(result)); 4523 goto failure; 4524 } 4525 4526 /* Build SOA record */ 4527 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass, 4528 0, 0, 0, 0, 0, buf, &rdata); 4529 if (result != ISC_R_SUCCESS) { 4530 dns_zone_log(zone, ISC_LOG_ERROR, 4531 "add_soa:dns_soa_buildrdata -> %s", 4532 dns_result_totext(result)); 4533 goto failure; 4534 } 4535 4536 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD, &zone->origin, 0, 4537 &rdata); 4538 4539failure: 4540 dns_diff_clear(&diff); 4541 if (ver != NULL) { 4542 dns_db_closeversion(db, &ver, (result == ISC_R_SUCCESS)); 4543 } 4544 4545 INSIST(ver == NULL); 4546 4547 return (result); 4548} 4549 4550struct addifmissing_arg { 4551 dns_db_t *db; 4552 dns_dbversion_t *ver; 4553 dns_diff_t *diff; 4554 dns_zone_t *zone; 4555 bool *changed; 4556 isc_result_t result; 4557}; 4558 4559static void 4560addifmissing(dns_keytable_t *keytable, dns_keynode_t *keynode, 4561 dns_name_t *keyname, void *arg) { 4562 dns_db_t *db = ((struct addifmissing_arg *)arg)->db; 4563 dns_dbversion_t *ver = ((struct addifmissing_arg *)arg)->ver; 4564 dns_diff_t *diff = ((struct addifmissing_arg *)arg)->diff; 4565 dns_zone_t *zone = ((struct addifmissing_arg *)arg)->zone; 4566 bool *changed = ((struct addifmissing_arg *)arg)->changed; 4567 isc_result_t result; 4568 dns_fixedname_t fname; 4569 4570 UNUSED(keytable); 4571 4572 if (((struct addifmissing_arg *)arg)->result != ISC_R_SUCCESS) { 4573 return; 4574 } 4575 4576 if (!dns_keynode_managed(keynode)) { 4577 return; 4578 } 4579 4580 /* 4581 * If the keynode has no trust anchor set, return. 4582 */ 4583 if (!dns_keynode_dsset(keynode, NULL)) { 4584 return; 4585 } 4586 4587 /* 4588 * Check whether there's already a KEYDATA entry for this name; 4589 * if so, we don't need to add another. 4590 */ 4591 dns_fixedname_init(&fname); 4592 result = dns_db_find(db, keyname, ver, dns_rdatatype_keydata, 4593 DNS_DBFIND_NOWILD, 0, NULL, 4594 dns_fixedname_name(&fname), NULL, NULL); 4595 if (result == ISC_R_SUCCESS) { 4596 return; 4597 } 4598 4599 /* 4600 * Create the keydata. 4601 */ 4602 result = create_keydata(zone, db, ver, diff, keynode, keyname, changed); 4603 if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) { 4604 ((struct addifmissing_arg *)arg)->result = result; 4605 } 4606} 4607 4608/* 4609 * Synchronize the set of initializing keys found in managed-keys {} 4610 * statements with the set of trust anchors found in the managed-keys.bind 4611 * zone. If a domain is no longer named in managed-keys, delete all keys 4612 * from that domain from the key zone. If a domain is configured as an 4613 * initial-key in trust-anchors, but there are no references to it in the 4614 * key zone, load the key zone with the initializing key(s) for that 4615 * domain and schedule a key refresh. If a domain is configured as 4616 * an initial-ds in trust-anchors, fetch the DNSKEY RRset, load the key 4617 * zone with the matching key, and schedule a key refresh. 4618 */ 4619static isc_result_t 4620sync_keyzone(dns_zone_t *zone, dns_db_t *db) { 4621 isc_result_t result = ISC_R_SUCCESS; 4622 bool changed = false; 4623 bool commit = false; 4624 dns_keynode_t *keynode = NULL; 4625 dns_view_t *view = zone->view; 4626 dns_keytable_t *sr = NULL; 4627 dns_dbversion_t *ver = NULL; 4628 dns_diff_t diff; 4629 dns_rriterator_t rrit; 4630 struct addifmissing_arg arg; 4631 4632 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys"); 4633 4634 dns_diff_init(zone->mctx, &diff); 4635 4636 CHECK(dns_view_getsecroots(view, &sr)); 4637 4638 result = dns_db_newversion(db, &ver); 4639 if (result != ISC_R_SUCCESS) { 4640 dnssec_log(zone, ISC_LOG_ERROR, 4641 "sync_keyzone:dns_db_newversion -> %s", 4642 dns_result_totext(result)); 4643 goto failure; 4644 } 4645 4646 /* 4647 * Walk the zone DB. If we find any keys whose names are no longer 4648 * in trust-anchors, or which have been changed from initial to static, 4649 * (meaning they are permanent and not RFC5011-maintained), delete 4650 * them from the zone. Otherwise call load_secroots(), which 4651 * loads keys into secroots as appropriate. 4652 */ 4653 dns_rriterator_init(&rrit, db, ver, 0); 4654 for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS; 4655 result = dns_rriterator_nextrrset(&rrit)) 4656 { 4657 dns_rdataset_t *rdataset = NULL; 4658 dns_rdata_t rdata = DNS_RDATA_INIT; 4659 dns_rdata_keydata_t keydata; 4660 isc_stdtime_t now; 4661 bool load = true; 4662 dns_name_t *rrname = NULL; 4663 uint32_t ttl; 4664 4665 isc_stdtime_get(&now); 4666 4667 dns_rriterator_current(&rrit, &rrname, &ttl, &rdataset, NULL); 4668 if (!dns_rdataset_isassociated(rdataset)) { 4669 dns_rriterator_destroy(&rrit); 4670 goto failure; 4671 } 4672 4673 if (rdataset->type != dns_rdatatype_keydata) { 4674 continue; 4675 } 4676 4677 /* 4678 * The managed-keys zone can contain a placeholder instead of 4679 * legitimate data, in which case we will not use it, and we 4680 * will try to refresh it. 4681 */ 4682 for (result = dns_rdataset_first(rdataset); 4683 result == ISC_R_SUCCESS; 4684 result = dns_rdataset_next(rdataset)) 4685 { 4686 isc_result_t iresult; 4687 4688 dns_rdata_reset(&rdata); 4689 dns_rdataset_current(rdataset, &rdata); 4690 4691 iresult = dns_rdata_tostruct(&rdata, &keydata, NULL); 4692 /* Do we have a valid placeholder KEYDATA record? */ 4693 if (iresult == ISC_R_SUCCESS && keydata.flags == 0 && 4694 keydata.protocol == 0 && keydata.algorithm == 0) 4695 { 4696 set_refreshkeytimer(zone, &keydata, now, true); 4697 load = false; 4698 } 4699 } 4700 4701 /* 4702 * Release db wrlock to prevent LOR reports against 4703 * dns_keytable_forall() call below. 4704 */ 4705 dns_rriterator_pause(&rrit); 4706 result = dns_keytable_find(sr, rrname, &keynode); 4707 if (result != ISC_R_SUCCESS || !dns_keynode_managed(keynode)) { 4708 CHECK(delete_keydata(db, ver, &diff, rrname, rdataset)); 4709 changed = true; 4710 } else if (load) { 4711 load_secroots(zone, rrname, rdataset); 4712 } 4713 4714 if (keynode != NULL) { 4715 dns_keytable_detachkeynode(sr, &keynode); 4716 } 4717 } 4718 dns_rriterator_destroy(&rrit); 4719 4720 /* 4721 * Walk secroots to find any initial keys that aren't in 4722 * the zone. If we find any, add them to the zone directly. 4723 * If any DS-style initial keys are found, refresh the key 4724 * zone so that they'll be looked up. 4725 */ 4726 arg.db = db; 4727 arg.ver = ver; 4728 arg.result = ISC_R_SUCCESS; 4729 arg.diff = &diff; 4730 arg.zone = zone; 4731 arg.changed = &changed; 4732 dns_keytable_forall(sr, addifmissing, &arg); 4733 result = arg.result; 4734 if (changed) { 4735 /* Write changes to journal file. */ 4736 CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx, 4737 zone->updatemethod)); 4738 CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone")); 4739 4740 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 4741 zone_needdump(zone, 30); 4742 commit = true; 4743 } 4744 4745failure: 4746 if (result != ISC_R_SUCCESS) { 4747 dnssec_log(zone, ISC_LOG_ERROR, 4748 "unable to synchronize managed keys: %s", 4749 dns_result_totext(result)); 4750 isc_time_settoepoch(&zone->refreshkeytime); 4751 } 4752 if (keynode != NULL) { 4753 dns_keytable_detachkeynode(sr, &keynode); 4754 } 4755 if (sr != NULL) { 4756 dns_keytable_detach(&sr); 4757 } 4758 if (ver != NULL) { 4759 dns_db_closeversion(db, &ver, commit); 4760 } 4761 dns_diff_clear(&diff); 4762 4763 INSIST(ver == NULL); 4764 4765 return (result); 4766} 4767 4768isc_result_t 4769dns_zone_synckeyzone(dns_zone_t *zone) { 4770 isc_result_t result; 4771 dns_db_t *db = NULL; 4772 4773 if (zone->type != dns_zone_key) { 4774 return (DNS_R_BADZONE); 4775 } 4776 4777 CHECK(dns_zone_getdb(zone, &db)); 4778 4779 LOCK_ZONE(zone); 4780 result = sync_keyzone(zone, db); 4781 UNLOCK_ZONE(zone); 4782 4783failure: 4784 if (db != NULL) { 4785 dns_db_detach(&db); 4786 } 4787 return (result); 4788} 4789 4790static void 4791maybe_send_secure(dns_zone_t *zone) { 4792 isc_result_t result; 4793 4794 /* 4795 * We've finished loading, or else failed to load, an inline-signing 4796 * 'secure' zone. We now need information about the status of the 4797 * 'raw' zone. If we failed to load, then we need it to send a 4798 * copy of its database; if we succeeded, we need it to send its 4799 * serial number so that we can sync with it. If it has not yet 4800 * loaded, we set a flag so that it will send the necessary 4801 * information when it has finished loading. 4802 */ 4803 if (zone->raw->db != NULL) { 4804 if (zone->db != NULL) { 4805 uint32_t serial; 4806 unsigned int soacount; 4807 4808 result = zone_get_from_db( 4809 zone->raw, zone->raw->db, NULL, &soacount, NULL, 4810 &serial, NULL, NULL, NULL, NULL, NULL); 4811 if (result == ISC_R_SUCCESS && soacount > 0U) { 4812 zone_send_secureserial(zone->raw, serial); 4813 } 4814 } else { 4815 zone_send_securedb(zone->raw, zone->raw->db); 4816 } 4817 } else { 4818 DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE); 4819 } 4820} 4821 4822static bool 4823zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) { 4824 isc_result_t result; 4825 bool answer = false; 4826 dns_diff_t diff; 4827 4828 dns_diff_init(mctx, &diff); 4829 result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL); 4830 if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples)) { 4831 answer = true; 4832 } 4833 dns_diff_clear(&diff); 4834 return (answer); 4835} 4836 4837/* 4838 * The zone is presumed to be locked. 4839 * If this is a inline_raw zone the secure version is also locked. 4840 */ 4841static isc_result_t 4842zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, 4843 isc_result_t result) { 4844 unsigned int soacount = 0; 4845 unsigned int nscount = 0; 4846 unsigned int errors = 0; 4847 uint32_t serial, oldserial, refresh, retry, expire, minimum, soattl; 4848 isc_time_t now; 4849 bool needdump = false; 4850 bool fixjournal = false; 4851 bool hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE); 4852 bool nomaster = false; 4853 bool had_db = false; 4854 dns_include_t *inc; 4855 bool is_dynamic = false; 4856 4857 INSIST(LOCKED_ZONE(zone)); 4858 if (inline_raw(zone)) { 4859 INSIST(LOCKED_ZONE(zone->secure)); 4860 } 4861 4862 TIME_NOW(&now); 4863 4864 /* 4865 * Initiate zone transfer? We may need a error code that 4866 * indicates that the "permanent" form does not exist. 4867 * XXX better error feedback to log. 4868 */ 4869 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { 4870 if (zone->type == dns_zone_secondary || 4871 zone->type == dns_zone_mirror || 4872 zone->type == dns_zone_stub || 4873 (zone->type == dns_zone_redirect && zone->masters == NULL)) 4874 { 4875 if (result == ISC_R_FILENOTFOUND) { 4876 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4877 ISC_LOG_DEBUG(1), 4878 "no master file"); 4879 } else if (result != DNS_R_NOMASTERFILE) { 4880 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4881 ISC_LOG_ERROR, 4882 "loading from master file %s " 4883 "failed: %s", 4884 zone->masterfile, 4885 dns_result_totext(result)); 4886 } 4887 } else if (zone->type == dns_zone_primary && 4888 inline_secure(zone) && result == ISC_R_FILENOTFOUND) 4889 { 4890 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4891 ISC_LOG_DEBUG(1), 4892 "no master file, requesting db"); 4893 maybe_send_secure(zone); 4894 } else { 4895 int level = ISC_LOG_ERROR; 4896 if (zone->type == dns_zone_key && 4897 result == ISC_R_FILENOTFOUND) 4898 { 4899 level = ISC_LOG_DEBUG(1); 4900 } 4901 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, level, 4902 "loading from master file %s failed: %s", 4903 zone->masterfile, 4904 dns_result_totext(result)); 4905 nomaster = true; 4906 } 4907 4908 if (zone->type != dns_zone_key) { 4909 goto cleanup; 4910 } 4911 } 4912 4913 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(2), 4914 "number of nodes in database: %u", dns_db_nodecount(db)); 4915 4916 if (result == DNS_R_SEENINCLUDE) { 4917 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 4918 } else { 4919 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 4920 } 4921 4922 /* 4923 * If there's no master file for a key zone, then the zone is new: 4924 * create an SOA record. (We do this now, instead of later, so that 4925 * if there happens to be a journal file, we can roll forward from 4926 * a sane starting point.) 4927 */ 4928 if (nomaster && zone->type == dns_zone_key) { 4929 result = add_soa(zone, db); 4930 if (result != ISC_R_SUCCESS) { 4931 goto cleanup; 4932 } 4933 } 4934 4935 /* 4936 * Apply update log, if any, on initial load. 4937 */ 4938 if (zone->journal != NULL && 4939 !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) && 4940 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 4941 { 4942 result = zone_journal_rollforward(zone, db, &needdump, 4943 &fixjournal); 4944 if (result != ISC_R_SUCCESS) { 4945 goto cleanup; 4946 } 4947 } 4948 4949 /* 4950 * Obtain ns, soa and cname counts for top of zone. 4951 */ 4952 INSIST(db != NULL); 4953 result = zone_get_from_db(zone, db, &nscount, &soacount, &soattl, 4954 &serial, &refresh, &retry, &expire, &minimum, 4955 &errors); 4956 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) { 4957 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 4958 "could not find NS and/or SOA records"); 4959 } 4960 4961 /* 4962 * Process any queued NSEC3PARAM change requests. Only for dynamic 4963 * zones, an inline-signing zone will perform this action when 4964 * receiving the secure db (receive_secure_db). 4965 */ 4966 is_dynamic = dns_zone_isdynamic(zone, true); 4967 if (is_dynamic) { 4968 isc_event_t *setnsec3param_event; 4969 dns_zone_t *dummy; 4970 4971 while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) { 4972 setnsec3param_event = 4973 ISC_LIST_HEAD(zone->setnsec3param_queue); 4974 ISC_LIST_UNLINK(zone->setnsec3param_queue, 4975 setnsec3param_event, ev_link); 4976 dummy = NULL; 4977 zone_iattach(zone, &dummy); 4978 isc_task_send(zone->task, &setnsec3param_event); 4979 } 4980 } 4981 4982 /* 4983 * Check to make sure the journal is up to date, and remove the 4984 * journal file if it isn't, as we wouldn't be able to apply 4985 * updates otherwise. 4986 */ 4987 if (zone->journal != NULL && is_dynamic && 4988 !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) 4989 { 4990 uint32_t jserial; 4991 dns_journal_t *journal = NULL; 4992 bool empty = false; 4993 4994 result = dns_journal_open(zone->mctx, zone->journal, 4995 DNS_JOURNAL_READ, &journal); 4996 if (result == ISC_R_SUCCESS) { 4997 jserial = dns_journal_last_serial(journal); 4998 empty = dns_journal_empty(journal); 4999 dns_journal_destroy(&journal); 5000 } else { 5001 jserial = serial; 5002 result = ISC_R_SUCCESS; 5003 } 5004 5005 if (jserial != serial) { 5006 if (!empty) { 5007 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5008 ISC_LOG_INFO, 5009 "journal file is out of date: " 5010 "removing journal file"); 5011 } 5012 if (remove(zone->journal) < 0 && errno != ENOENT) { 5013 char strbuf[ISC_STRERRORSIZE]; 5014 strerror_r(errno, strbuf, sizeof(strbuf)); 5015 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 5016 DNS_LOGMODULE_ZONE, 5017 ISC_LOG_WARNING, 5018 "unable to remove journal " 5019 "'%s': '%s'", 5020 zone->journal, strbuf); 5021 } 5022 } 5023 } 5024 5025 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1), 5026 "loaded; checking validity"); 5027 5028 /* 5029 * Master / Slave / Mirror / Stub zones require both NS and SOA records 5030 * at the top of the zone. 5031 */ 5032 5033 switch (zone->type) { 5034 case dns_zone_dlz: 5035 case dns_zone_primary: 5036 case dns_zone_secondary: 5037 case dns_zone_mirror: 5038 case dns_zone_stub: 5039 case dns_zone_redirect: 5040 if (soacount != 1) { 5041 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5042 ISC_LOG_ERROR, "has %d SOA records", 5043 soacount); 5044 result = DNS_R_BADZONE; 5045 } 5046 if (nscount == 0) { 5047 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5048 ISC_LOG_ERROR, "has no NS records"); 5049 result = DNS_R_BADZONE; 5050 } 5051 if (result != ISC_R_SUCCESS) { 5052 goto cleanup; 5053 } 5054 if (zone->type == dns_zone_primary && errors != 0) { 5055 result = DNS_R_BADZONE; 5056 goto cleanup; 5057 } 5058 if (zone->type != dns_zone_stub && 5059 zone->type != dns_zone_redirect) 5060 { 5061 result = check_nsec3param(zone, db); 5062 if (result != ISC_R_SUCCESS) { 5063 goto cleanup; 5064 } 5065 } 5066 if (zone->type == dns_zone_primary && 5067 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) && 5068 !integrity_checks(zone, db)) 5069 { 5070 result = DNS_R_BADZONE; 5071 goto cleanup; 5072 } 5073 if (zone->type == dns_zone_primary && 5074 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) && 5075 !zone_check_dup(zone, db)) 5076 { 5077 result = DNS_R_BADZONE; 5078 goto cleanup; 5079 } 5080 5081 if (zone->type == dns_zone_primary) { 5082 result = dns_zone_cdscheck(zone, db, NULL); 5083 if (result != ISC_R_SUCCESS) { 5084 dns_zone_log(zone, ISC_LOG_ERROR, 5085 "CDS/CDNSKEY consistency checks " 5086 "failed"); 5087 goto cleanup; 5088 } 5089 } 5090 5091 result = dns_zone_verifydb(zone, db, NULL); 5092 if (result != ISC_R_SUCCESS) { 5093 goto cleanup; 5094 } 5095 5096 if (zone->db != NULL) { 5097 unsigned int oldsoacount; 5098 5099 /* 5100 * This is checked in zone_replacedb() for slave zones 5101 * as they don't reload from disk. 5102 */ 5103 result = zone_get_from_db( 5104 zone, zone->db, NULL, &oldsoacount, NULL, 5105 &oldserial, NULL, NULL, NULL, NULL, NULL); 5106 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5107 RUNTIME_CHECK(oldsoacount > 0U); 5108 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 5109 !isc_serial_gt(serial, oldserial)) 5110 { 5111 uint32_t serialmin, serialmax; 5112 5113 INSIST(zone->type == dns_zone_primary); 5114 INSIST(zone->raw == NULL); 5115 5116 if (serial == oldserial && 5117 zone_unchanged(zone->db, db, zone->mctx)) 5118 { 5119 dns_zone_logc(zone, 5120 DNS_LOGCATEGORY_ZONELOAD, 5121 ISC_LOG_INFO, 5122 "ixfr-from-differences: " 5123 "unchanged"); 5124 zone->loadtime = loadtime; 5125 goto done; 5126 } 5127 5128 serialmin = (oldserial + 1) & 0xffffffffU; 5129 serialmax = (oldserial + 0x7fffffffU) & 5130 0xffffffffU; 5131 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5132 ISC_LOG_ERROR, 5133 "ixfr-from-differences: " 5134 "new serial (%u) out of range " 5135 "[%u - %u]", 5136 serial, serialmin, serialmax); 5137 result = DNS_R_BADZONE; 5138 goto cleanup; 5139 } else if (!isc_serial_ge(serial, oldserial)) { 5140 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5141 ISC_LOG_ERROR, 5142 "zone serial (%u/%u) has gone " 5143 "backwards", 5144 serial, oldserial); 5145 } else if (serial == oldserial && !hasinclude && 5146 strcmp(zone->db_argv[0], "_builtin") != 0) 5147 { 5148 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5149 ISC_LOG_ERROR, 5150 "zone serial (%u) unchanged. " 5151 "zone may fail to transfer " 5152 "to slaves.", 5153 serial); 5154 } 5155 } 5156 5157 if (zone->type == dns_zone_primary && 5158 (zone->update_acl != NULL || zone->ssutable != NULL) && 5159 dns_zone_getsigresigninginterval(zone) < (3 * refresh) && 5160 dns_db_issecure(db)) 5161 { 5162 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5163 ISC_LOG_WARNING, 5164 "sig-re-signing-interval less than " 5165 "3 * refresh."); 5166 } 5167 5168 zone->refresh = RANGE(refresh, zone->minrefresh, 5169 zone->maxrefresh); 5170 zone->retry = RANGE(retry, zone->minretry, zone->maxretry); 5171 zone->expire = RANGE(expire, zone->refresh + zone->retry, 5172 DNS_MAX_EXPIRE); 5173 zone->soattl = soattl; 5174 zone->minimum = minimum; 5175 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 5176 5177 if (zone->type == dns_zone_secondary || 5178 zone->type == dns_zone_mirror || 5179 zone->type == dns_zone_stub || 5180 (zone->type == dns_zone_redirect && zone->masters != NULL)) 5181 { 5182 isc_time_t t; 5183 uint32_t delay; 5184 5185 result = isc_file_getmodtime(zone->journal, &t); 5186 if (result != ISC_R_SUCCESS) { 5187 result = isc_file_getmodtime(zone->masterfile, 5188 &t); 5189 } 5190 if (result == ISC_R_SUCCESS) { 5191 DNS_ZONE_TIME_ADD(&t, zone->expire, 5192 &zone->expiretime); 5193 } else { 5194 DNS_ZONE_TIME_ADD(&now, zone->retry, 5195 &zone->expiretime); 5196 } 5197 5198 delay = (zone->retry - 5199 isc_random_uniform((zone->retry * 3) / 4)); 5200 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime); 5201 if (isc_time_compare(&zone->refreshtime, 5202 &zone->expiretime) >= 0) 5203 { 5204 zone->refreshtime = now; 5205 } 5206 } 5207 5208 break; 5209 5210 case dns_zone_key: 5211 /* Nothing needs to be done now */ 5212 break; 5213 5214 default: 5215 UNEXPECTED_ERROR(__FILE__, __LINE__, "unexpected zone type %d", 5216 zone->type); 5217 result = ISC_R_UNEXPECTED; 5218 goto cleanup; 5219 } 5220 5221 /* 5222 * Check for weak DNSKEY's. 5223 */ 5224 if (zone->type == dns_zone_primary) { 5225 zone_check_dnskeys(zone, db); 5226 } 5227 5228 /* 5229 * Schedule DNSSEC key refresh. 5230 */ 5231 if (zone->type == dns_zone_primary && 5232 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 5233 { 5234 zone->refreshkeytime = now; 5235 } 5236 5237 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 5238 if (zone->db != NULL) { 5239 had_db = true; 5240 result = zone_replacedb(zone, db, false); 5241 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 5242 if (result != ISC_R_SUCCESS) { 5243 goto cleanup; 5244 } 5245 } else { 5246 zone_attachdb(zone, db); 5247 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 5248 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | 5249 DNS_ZONEFLG_NEEDSTARTUPNOTIFY); 5250 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) && 5251 inline_raw(zone)) 5252 { 5253 if (zone->secure->db == NULL) { 5254 zone_send_securedb(zone, db); 5255 } else { 5256 zone_send_secureserial(zone, serial); 5257 } 5258 } 5259 } 5260 5261 /* 5262 * Finished loading inline-signing zone; need to get status 5263 * from the raw side now. 5264 */ 5265 if (zone->type == dns_zone_primary && inline_secure(zone)) { 5266 maybe_send_secure(zone); 5267 } 5268 5269 result = ISC_R_SUCCESS; 5270 5271 if (fixjournal) { 5272 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FIXJOURNAL); 5273 zone_journal_compact(zone, zone->db, 0); 5274 } 5275 if (needdump) { 5276 if (zone->type == dns_zone_key) { 5277 zone_needdump(zone, 30); 5278 } else { 5279 zone_needdump(zone, DNS_DUMP_DELAY); 5280 } 5281 } 5282 5283 if (zone->task != NULL) { 5284 if (zone->type == dns_zone_primary) { 5285 set_resigntime(zone); 5286 resume_signingwithkey(zone); 5287 resume_addnsec3chain(zone); 5288 } 5289 5290 is_dynamic = dns_zone_isdynamic(zone, false); 5291 if (zone->type == dns_zone_primary && 5292 !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) && 5293 is_dynamic && dns_db_issecure(db)) 5294 { 5295 dns_name_t *name; 5296 dns_fixedname_t fixed; 5297 dns_rdataset_t next; 5298 5299 dns_rdataset_init(&next); 5300 name = dns_fixedname_initname(&fixed); 5301 5302 result = dns_db_getsigningtime(db, &next, name); 5303 if (result == ISC_R_SUCCESS) { 5304 isc_stdtime_t timenow; 5305 char namebuf[DNS_NAME_FORMATSIZE]; 5306 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 5307 5308 isc_stdtime_get(&timenow); 5309 dns_name_format(name, namebuf, sizeof(namebuf)); 5310 dns_rdatatype_format(next.covers, typebuf, 5311 sizeof(typebuf)); 5312 dnssec_log( 5313 zone, ISC_LOG_DEBUG(3), 5314 "next resign: %s/%s " 5315 "in %d seconds", 5316 namebuf, typebuf, 5317 next.resign - timenow - 5318 dns_zone_getsigresigninginterval( 5319 zone)); 5320 dns_rdataset_disassociate(&next); 5321 } else { 5322 dnssec_log(zone, ISC_LOG_WARNING, 5323 "signed dynamic zone has no " 5324 "resign event scheduled"); 5325 } 5326 } 5327 5328 zone_settimer(zone, &now); 5329 } 5330 5331 /* 5332 * Clear old include list. 5333 */ 5334 for (inc = ISC_LIST_HEAD(zone->includes); inc != NULL; 5335 inc = ISC_LIST_HEAD(zone->includes)) 5336 { 5337 ISC_LIST_UNLINK(zone->includes, inc, link); 5338 isc_mem_free(zone->mctx, inc->name); 5339 isc_mem_put(zone->mctx, inc, sizeof(*inc)); 5340 } 5341 zone->nincludes = 0; 5342 5343 /* 5344 * Transfer new include list. 5345 */ 5346 for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; 5347 inc = ISC_LIST_HEAD(zone->newincludes)) 5348 { 5349 ISC_LIST_UNLINK(zone->newincludes, inc, link); 5350 ISC_LIST_APPEND(zone->includes, inc, link); 5351 zone->nincludes++; 5352 } 5353 5354 if (!dns_db_ispersistent(db)) { 5355 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO, 5356 "loaded serial %u%s", serial, 5357 dns_db_issecure(db) ? " (DNSSEC signed)" : ""); 5358 } 5359 5360 if (!had_db && zone->type == dns_zone_mirror) { 5361 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO, 5362 "mirror zone is now in use"); 5363 } 5364 5365 zone->loadtime = loadtime; 5366 goto done; 5367 5368cleanup: 5369 if (result != ISC_R_SUCCESS) { 5370 dns_zone_rpz_disable_db(zone, db); 5371 dns_zone_catz_disable_db(zone, db); 5372 } 5373 5374 for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; 5375 inc = ISC_LIST_HEAD(zone->newincludes)) 5376 { 5377 ISC_LIST_UNLINK(zone->newincludes, inc, link); 5378 isc_mem_free(zone->mctx, inc->name); 5379 isc_mem_put(zone->mctx, inc, sizeof(*inc)); 5380 } 5381 if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror || 5382 zone->type == dns_zone_stub || zone->type == dns_zone_key || 5383 (zone->type == dns_zone_redirect && zone->masters != NULL)) 5384 { 5385 if (result != ISC_R_NOMEMORY) { 5386 if (zone->journal != NULL) { 5387 zone_saveunique(zone, zone->journal, 5388 "jn-XXXXXXXX"); 5389 } 5390 if (zone->masterfile != NULL) { 5391 zone_saveunique(zone, zone->masterfile, 5392 "db-XXXXXXXX"); 5393 } 5394 } 5395 5396 /* Mark the zone for immediate refresh. */ 5397 zone->refreshtime = now; 5398 if (zone->task != NULL) { 5399 zone_settimer(zone, &now); 5400 } 5401 result = ISC_R_SUCCESS; 5402 } else if (zone->type == dns_zone_primary || 5403 zone->type == dns_zone_redirect) 5404 { 5405 if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND)) { 5406 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5407 ISC_LOG_ERROR, 5408 "not loaded due to errors."); 5409 } else if (zone->type == dns_zone_primary) { 5410 result = ISC_R_SUCCESS; 5411 } 5412 } 5413 5414done: 5415 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); 5416 /* 5417 * If this is an inline-signed zone and we were called for the raw 5418 * zone, we need to clear DNS_ZONEFLG_LOADPENDING for the secure zone 5419 * as well, but only if this is a reload, not an initial zone load: in 5420 * the former case, zone_postload() will not be run for the secure 5421 * zone; in the latter case, it will be. Check which case we are 5422 * dealing with by consulting the DNS_ZONEFLG_LOADED flag for the 5423 * secure zone: if it is set, this must be a reload. 5424 */ 5425 if (inline_raw(zone) && DNS_ZONE_FLAG(zone->secure, DNS_ZONEFLG_LOADED)) 5426 { 5427 DNS_ZONE_CLRFLAG(zone->secure, DNS_ZONEFLG_LOADPENDING); 5428 /* 5429 * Re-start zone maintenance if it had been stalled 5430 * due to DNS_ZONEFLG_LOADPENDING being set when 5431 * zone_maintenance was called. 5432 */ 5433 if (zone->secure->task != NULL) { 5434 zone_settimer(zone->secure, &now); 5435 } 5436 } 5437 5438 zone_debuglog(zone, "zone_postload", 99, "done"); 5439 5440 return (result); 5441} 5442 5443static bool 5444exit_check(dns_zone_t *zone) { 5445 REQUIRE(LOCKED_ZONE(zone)); 5446 5447 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && 5448 isc_refcount_current(&zone->irefs) == 0) 5449 { 5450 /* 5451 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0. 5452 */ 5453 INSIST(isc_refcount_current(&zone->erefs) == 0); 5454 return (true); 5455 } 5456 return (false); 5457} 5458 5459static bool 5460zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 5461 dns_name_t *name, bool logit) { 5462 isc_result_t result; 5463 char namebuf[DNS_NAME_FORMATSIZE]; 5464 char altbuf[DNS_NAME_FORMATSIZE]; 5465 dns_fixedname_t fixed; 5466 dns_name_t *foundname; 5467 int level; 5468 5469 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) { 5470 return (true); 5471 } 5472 5473 if (zone->type == dns_zone_primary) { 5474 level = ISC_LOG_ERROR; 5475 } else { 5476 level = ISC_LOG_WARNING; 5477 } 5478 5479 foundname = dns_fixedname_initname(&fixed); 5480 5481 result = dns_db_find(db, name, version, dns_rdatatype_a, 0, 0, NULL, 5482 foundname, NULL, NULL); 5483 if (result == ISC_R_SUCCESS) { 5484 return (true); 5485 } 5486 5487 if (result == DNS_R_NXRRSET) { 5488 result = dns_db_find(db, name, version, dns_rdatatype_aaaa, 0, 5489 0, NULL, foundname, NULL, NULL); 5490 if (result == ISC_R_SUCCESS) { 5491 return (true); 5492 } 5493 } 5494 5495 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 5496 result == DNS_R_EMPTYNAME) 5497 { 5498 if (logit) { 5499 dns_name_format(name, namebuf, sizeof namebuf); 5500 dns_zone_log(zone, level, 5501 "NS '%s' has no address " 5502 "records (A or AAAA)", 5503 namebuf); 5504 } 5505 return (false); 5506 } 5507 5508 if (result == DNS_R_CNAME) { 5509 if (logit) { 5510 dns_name_format(name, namebuf, sizeof namebuf); 5511 dns_zone_log(zone, level, 5512 "NS '%s' is a CNAME " 5513 "(illegal)", 5514 namebuf); 5515 } 5516 return (false); 5517 } 5518 5519 if (result == DNS_R_DNAME) { 5520 if (logit) { 5521 dns_name_format(name, namebuf, sizeof namebuf); 5522 dns_name_format(foundname, altbuf, sizeof altbuf); 5523 dns_zone_log(zone, level, 5524 "NS '%s' is below a DNAME " 5525 "'%s' (illegal)", 5526 namebuf, altbuf); 5527 } 5528 return (false); 5529 } 5530 5531 return (true); 5532} 5533 5534static isc_result_t 5535zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, 5536 dns_dbversion_t *version, unsigned int *nscount, 5537 unsigned int *errors, bool logit) { 5538 isc_result_t result; 5539 unsigned int count = 0; 5540 unsigned int ecount = 0; 5541 dns_rdataset_t rdataset; 5542 dns_rdata_t rdata; 5543 dns_rdata_ns_t ns; 5544 5545 dns_rdataset_init(&rdataset); 5546 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns, 5547 dns_rdatatype_none, 0, &rdataset, NULL); 5548 if (result == ISC_R_NOTFOUND) { 5549 INSIST(!dns_rdataset_isassociated(&rdataset)); 5550 goto success; 5551 } 5552 if (result != ISC_R_SUCCESS) { 5553 INSIST(!dns_rdataset_isassociated(&rdataset)); 5554 goto invalidate_rdataset; 5555 } 5556 5557 result = dns_rdataset_first(&rdataset); 5558 while (result == ISC_R_SUCCESS) { 5559 if (errors != NULL && zone->rdclass == dns_rdataclass_in && 5560 (zone->type == dns_zone_primary || 5561 zone->type == dns_zone_secondary || 5562 zone->type == dns_zone_mirror)) 5563 { 5564 dns_rdata_init(&rdata); 5565 dns_rdataset_current(&rdataset, &rdata); 5566 result = dns_rdata_tostruct(&rdata, &ns, NULL); 5567 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5568 if (dns_name_issubdomain(&ns.name, &zone->origin) && 5569 !zone_check_ns(zone, db, version, &ns.name, logit)) 5570 { 5571 ecount++; 5572 } 5573 } 5574 count++; 5575 result = dns_rdataset_next(&rdataset); 5576 } 5577 dns_rdataset_disassociate(&rdataset); 5578 5579success: 5580 if (nscount != NULL) { 5581 *nscount = count; 5582 } 5583 if (errors != NULL) { 5584 *errors = ecount; 5585 } 5586 5587 result = ISC_R_SUCCESS; 5588 5589invalidate_rdataset: 5590 dns_rdataset_invalidate(&rdataset); 5591 5592 return (result); 5593} 5594 5595#define SET_IF_NOT_NULL(obj, val) \ 5596 if (obj != NULL) { \ 5597 *obj = val; \ 5598 } 5599 5600#define SET_SOA_VALUES(soattl_v, serial_v, refresh_v, retry_v, expire_v, \ 5601 minimum_v) \ 5602 { \ 5603 SET_IF_NOT_NULL(soattl, soattl_v); \ 5604 SET_IF_NOT_NULL(serial, serial_v); \ 5605 SET_IF_NOT_NULL(refresh, refresh_v); \ 5606 SET_IF_NOT_NULL(retry, retry_v); \ 5607 SET_IF_NOT_NULL(expire, expire_v); \ 5608 SET_IF_NOT_NULL(minimum, minimum_v); \ 5609 } 5610 5611#define CLR_SOA_VALUES() \ 5612 { \ 5613 SET_SOA_VALUES(0, 0, 0, 0, 0, 0); \ 5614 } 5615 5616static isc_result_t 5617zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 5618 unsigned int *soacount, uint32_t *soattl, uint32_t *serial, 5619 uint32_t *refresh, uint32_t *retry, uint32_t *expire, 5620 uint32_t *minimum) { 5621 isc_result_t result; 5622 unsigned int count = 0; 5623 dns_rdataset_t rdataset; 5624 dns_rdata_t rdata = DNS_RDATA_INIT; 5625 5626 dns_rdataset_init(&rdataset); 5627 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, 5628 dns_rdatatype_none, 0, &rdataset, NULL); 5629 if (result == ISC_R_NOTFOUND) { 5630 INSIST(!dns_rdataset_isassociated(&rdataset)); 5631 result = ISC_R_SUCCESS; 5632 goto invalidate_rdataset; 5633 } 5634 if (result != ISC_R_SUCCESS) { 5635 INSIST(!dns_rdataset_isassociated(&rdataset)); 5636 goto invalidate_rdataset; 5637 } 5638 5639 result = dns_rdataset_first(&rdataset); 5640 while (result == ISC_R_SUCCESS) { 5641 dns_rdata_init(&rdata); 5642 dns_rdataset_current(&rdataset, &rdata); 5643 count++; 5644 if (count == 1) { 5645 dns_rdata_soa_t soa; 5646 result = dns_rdata_tostruct(&rdata, &soa, NULL); 5647 SET_SOA_VALUES(rdataset.ttl, soa.serial, soa.refresh, 5648 soa.retry, soa.expire, soa.minimum); 5649 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5650 } 5651 5652 result = dns_rdataset_next(&rdataset); 5653 dns_rdata_reset(&rdata); 5654 } 5655 dns_rdataset_disassociate(&rdataset); 5656 5657 result = ISC_R_SUCCESS; 5658 5659invalidate_rdataset: 5660 SET_IF_NOT_NULL(soacount, count); 5661 if (count == 0) { 5662 CLR_SOA_VALUES(); 5663 } 5664 5665 dns_rdataset_invalidate(&rdataset); 5666 5667 return (result); 5668} 5669 5670/* 5671 * zone must be locked. 5672 */ 5673static isc_result_t 5674zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 5675 unsigned int *soacount, uint32_t *soattl, uint32_t *serial, 5676 uint32_t *refresh, uint32_t *retry, uint32_t *expire, 5677 uint32_t *minimum, unsigned int *errors) { 5678 isc_result_t result; 5679 isc_result_t answer = ISC_R_SUCCESS; 5680 dns_dbversion_t *version = NULL; 5681 dns_dbnode_t *node; 5682 5683 REQUIRE(db != NULL); 5684 REQUIRE(zone != NULL); 5685 5686 dns_db_currentversion(db, &version); 5687 5688 SET_IF_NOT_NULL(nscount, 0); 5689 SET_IF_NOT_NULL(soacount, 0); 5690 SET_IF_NOT_NULL(errors, 0); 5691 CLR_SOA_VALUES(); 5692 5693 node = NULL; 5694 result = dns_db_findnode(db, &zone->origin, false, &node); 5695 if (result != ISC_R_SUCCESS) { 5696 answer = result; 5697 goto closeversion; 5698 } 5699 5700 if (nscount != NULL || errors != NULL) { 5701 result = zone_count_ns_rr(zone, db, node, version, nscount, 5702 errors, true); 5703 if (result != ISC_R_SUCCESS) { 5704 answer = result; 5705 } 5706 } 5707 5708 if (soacount != NULL || soattl != NULL || serial != NULL || 5709 refresh != NULL || retry != NULL || expire != NULL || 5710 minimum != NULL) 5711 { 5712 result = zone_load_soa_rr(db, node, version, soacount, soattl, 5713 serial, refresh, retry, expire, 5714 minimum); 5715 if (result != ISC_R_SUCCESS) { 5716 answer = result; 5717 } 5718 } 5719 5720 dns_db_detachnode(db, &node); 5721closeversion: 5722 dns_db_closeversion(db, &version, false); 5723 5724 return (answer); 5725} 5726 5727void 5728dns_zone_attach(dns_zone_t *source, dns_zone_t **target) { 5729 REQUIRE(DNS_ZONE_VALID(source)); 5730 REQUIRE(target != NULL && *target == NULL); 5731 isc_refcount_increment(&source->erefs); 5732 *target = source; 5733} 5734 5735void 5736dns_zone_detach(dns_zone_t **zonep) { 5737 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 5738 5739 dns_zone_t *zone = *zonep; 5740 *zonep = NULL; 5741 5742 if (isc_refcount_decrement(&zone->erefs) == 1) { 5743 isc_event_t *ev = &zone->ctlevent; 5744 5745 isc_refcount_destroy(&zone->erefs); 5746 5747 /* 5748 * Stop things being restarted after we cancel them below. 5749 */ 5750 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING); 5751 dns_zone_log(zone, ISC_LOG_DEBUG(1), 5752 "final reference detached"); 5753 if (zone->task != NULL) { 5754 /* 5755 * This zone has a task; it can clean 5756 * itself up asynchronously. 5757 */ 5758 isc_task_send(zone->task, &ev); 5759 return; 5760 } 5761 5762 /* 5763 * This zone is unmanaged; we're probably running in 5764 * named-checkzone or a unit test. There's no task, 5765 * so we need to free it immediately. 5766 * 5767 * Unmanaged zones must not have null views; we have no way 5768 * of detaching from the view here without causing deadlock 5769 * because this code is called with the view already 5770 * locked. 5771 */ 5772 INSIST(zone->view == NULL); 5773 5774 zone_shutdown(zone->task, ev); 5775 ev = NULL; 5776 } 5777} 5778 5779void 5780dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) { 5781 REQUIRE(DNS_ZONE_VALID(source)); 5782 5783 LOCK_ZONE(source); 5784 zone_iattach(source, target); 5785 UNLOCK_ZONE(source); 5786} 5787 5788static void 5789zone_iattach(dns_zone_t *source, dns_zone_t **target) { 5790 REQUIRE(DNS_ZONE_VALID(source)); 5791 REQUIRE(LOCKED_ZONE(source)); 5792 REQUIRE(target != NULL && *target == NULL); 5793 INSIST(isc_refcount_increment0(&source->irefs) + 5794 isc_refcount_current(&source->erefs) > 5795 0); 5796 *target = source; 5797} 5798 5799static void 5800zone_idetach(dns_zone_t **zonep) { 5801 dns_zone_t *zone; 5802 5803 /* 5804 * 'zone' locked by caller. 5805 */ 5806 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 5807 REQUIRE(LOCKED_ZONE(*zonep)); 5808 5809 zone = *zonep; 5810 *zonep = NULL; 5811 5812 INSIST(isc_refcount_decrement(&zone->irefs) - 1 + 5813 isc_refcount_current(&zone->erefs) > 5814 0); 5815} 5816 5817void 5818dns_zone_idetach(dns_zone_t **zonep) { 5819 dns_zone_t *zone; 5820 5821 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 5822 5823 zone = *zonep; 5824 *zonep = NULL; 5825 5826 if (isc_refcount_decrement(&zone->irefs) == 1) { 5827 bool free_needed; 5828 LOCK_ZONE(zone); 5829 free_needed = exit_check(zone); 5830 UNLOCK_ZONE(zone); 5831 if (free_needed) { 5832 zone_free(zone); 5833 } 5834 } 5835} 5836 5837isc_mem_t * 5838dns_zone_getmctx(dns_zone_t *zone) { 5839 REQUIRE(DNS_ZONE_VALID(zone)); 5840 5841 return (zone->mctx); 5842} 5843 5844dns_zonemgr_t * 5845dns_zone_getmgr(dns_zone_t *zone) { 5846 REQUIRE(DNS_ZONE_VALID(zone)); 5847 5848 return (zone->zmgr); 5849} 5850 5851void 5852dns_zone_setkasp(dns_zone_t *zone, dns_kasp_t *kasp) { 5853 REQUIRE(DNS_ZONE_VALID(zone)); 5854 5855 LOCK_ZONE(zone); 5856 if (zone->kasp != NULL) { 5857 dns_kasp_detach(&zone->kasp); 5858 } 5859 if (kasp != NULL) { 5860 dns_kasp_attach(kasp, &zone->kasp); 5861 } 5862 UNLOCK_ZONE(zone); 5863} 5864 5865dns_kasp_t * 5866dns_zone_getkasp(dns_zone_t *zone) { 5867 REQUIRE(DNS_ZONE_VALID(zone)); 5868 5869 return (zone->kasp); 5870} 5871 5872void 5873dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option, bool value) { 5874 REQUIRE(DNS_ZONE_VALID(zone)); 5875 5876 if (value) { 5877 DNS_ZONE_SETOPTION(zone, option); 5878 } else { 5879 DNS_ZONE_CLROPTION(zone, option); 5880 } 5881} 5882 5883dns_zoneopt_t 5884dns_zone_getoptions(dns_zone_t *zone) { 5885 REQUIRE(DNS_ZONE_VALID(zone)); 5886 5887 return (atomic_load_relaxed(&zone->options)); 5888} 5889 5890void 5891dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, bool value) { 5892 REQUIRE(DNS_ZONE_VALID(zone)); 5893 5894 if (value) { 5895 DNS_ZONEKEY_SETOPTION(zone, keyopt); 5896 } else { 5897 DNS_ZONEKEY_CLROPTION(zone, keyopt); 5898 } 5899} 5900 5901unsigned int 5902dns_zone_getkeyopts(dns_zone_t *zone) { 5903 REQUIRE(DNS_ZONE_VALID(zone)); 5904 5905 return (atomic_load_relaxed(&zone->keyopts)); 5906} 5907 5908isc_result_t 5909dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 5910 REQUIRE(DNS_ZONE_VALID(zone)); 5911 5912 LOCK_ZONE(zone); 5913 zone->xfrsource4 = *xfrsource; 5914 UNLOCK_ZONE(zone); 5915 5916 return (ISC_R_SUCCESS); 5917} 5918 5919isc_sockaddr_t * 5920dns_zone_getxfrsource4(dns_zone_t *zone) { 5921 REQUIRE(DNS_ZONE_VALID(zone)); 5922 return (&zone->xfrsource4); 5923} 5924 5925isc_result_t 5926dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) { 5927 REQUIRE(DNS_ZONE_VALID(zone)); 5928 5929 LOCK_ZONE(zone); 5930 zone->xfrsource4dscp = dscp; 5931 UNLOCK_ZONE(zone); 5932 5933 return (ISC_R_SUCCESS); 5934} 5935 5936isc_dscp_t 5937dns_zone_getxfrsource4dscp(dns_zone_t *zone) { 5938 REQUIRE(DNS_ZONE_VALID(zone)); 5939 return (zone->xfrsource4dscp); 5940} 5941 5942isc_result_t 5943dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 5944 REQUIRE(DNS_ZONE_VALID(zone)); 5945 5946 LOCK_ZONE(zone); 5947 zone->xfrsource6 = *xfrsource; 5948 UNLOCK_ZONE(zone); 5949 5950 return (ISC_R_SUCCESS); 5951} 5952 5953isc_sockaddr_t * 5954dns_zone_getxfrsource6(dns_zone_t *zone) { 5955 REQUIRE(DNS_ZONE_VALID(zone)); 5956 return (&zone->xfrsource6); 5957} 5958 5959isc_dscp_t 5960dns_zone_getxfrsource6dscp(dns_zone_t *zone) { 5961 REQUIRE(DNS_ZONE_VALID(zone)); 5962 return (zone->xfrsource6dscp); 5963} 5964 5965isc_result_t 5966dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) { 5967 REQUIRE(DNS_ZONE_VALID(zone)); 5968 5969 LOCK_ZONE(zone); 5970 zone->xfrsource6dscp = dscp; 5971 UNLOCK_ZONE(zone); 5972 5973 return (ISC_R_SUCCESS); 5974} 5975 5976isc_result_t 5977dns_zone_setaltxfrsource4(dns_zone_t *zone, 5978 const isc_sockaddr_t *altxfrsource) { 5979 REQUIRE(DNS_ZONE_VALID(zone)); 5980 5981 LOCK_ZONE(zone); 5982 zone->altxfrsource4 = *altxfrsource; 5983 UNLOCK_ZONE(zone); 5984 5985 return (ISC_R_SUCCESS); 5986} 5987 5988isc_sockaddr_t * 5989dns_zone_getaltxfrsource4(dns_zone_t *zone) { 5990 REQUIRE(DNS_ZONE_VALID(zone)); 5991 return (&zone->altxfrsource4); 5992} 5993 5994isc_result_t 5995dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) { 5996 REQUIRE(DNS_ZONE_VALID(zone)); 5997 5998 LOCK_ZONE(zone); 5999 zone->altxfrsource4dscp = dscp; 6000 UNLOCK_ZONE(zone); 6001 6002 return (ISC_R_SUCCESS); 6003} 6004 6005isc_dscp_t 6006dns_zone_getaltxfrsource4dscp(dns_zone_t *zone) { 6007 REQUIRE(DNS_ZONE_VALID(zone)); 6008 return (zone->altxfrsource4dscp); 6009} 6010 6011isc_result_t 6012dns_zone_setaltxfrsource6(dns_zone_t *zone, 6013 const isc_sockaddr_t *altxfrsource) { 6014 REQUIRE(DNS_ZONE_VALID(zone)); 6015 6016 LOCK_ZONE(zone); 6017 zone->altxfrsource6 = *altxfrsource; 6018 UNLOCK_ZONE(zone); 6019 6020 return (ISC_R_SUCCESS); 6021} 6022 6023isc_sockaddr_t * 6024dns_zone_getaltxfrsource6(dns_zone_t *zone) { 6025 REQUIRE(DNS_ZONE_VALID(zone)); 6026 return (&zone->altxfrsource6); 6027} 6028 6029isc_result_t 6030dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) { 6031 REQUIRE(DNS_ZONE_VALID(zone)); 6032 6033 LOCK_ZONE(zone); 6034 zone->altxfrsource6dscp = dscp; 6035 UNLOCK_ZONE(zone); 6036 6037 return (ISC_R_SUCCESS); 6038} 6039 6040isc_dscp_t 6041dns_zone_getaltxfrsource6dscp(dns_zone_t *zone) { 6042 REQUIRE(DNS_ZONE_VALID(zone)); 6043 return (zone->altxfrsource6dscp); 6044} 6045 6046isc_result_t 6047dns_zone_setparentalsrc4(dns_zone_t *zone, const isc_sockaddr_t *parentalsrc) { 6048 REQUIRE(DNS_ZONE_VALID(zone)); 6049 6050 LOCK_ZONE(zone); 6051 zone->parentalsrc4 = *parentalsrc; 6052 UNLOCK_ZONE(zone); 6053 6054 return (ISC_R_SUCCESS); 6055} 6056 6057isc_sockaddr_t * 6058dns_zone_getparentalsrc4(dns_zone_t *zone) { 6059 REQUIRE(DNS_ZONE_VALID(zone)); 6060 return (&zone->parentalsrc4); 6061} 6062 6063isc_result_t 6064dns_zone_setparentalsrc4dscp(dns_zone_t *zone, isc_dscp_t dscp) { 6065 REQUIRE(DNS_ZONE_VALID(zone)); 6066 6067 LOCK_ZONE(zone); 6068 zone->parentalsrc4dscp = dscp; 6069 UNLOCK_ZONE(zone); 6070 6071 return (ISC_R_SUCCESS); 6072} 6073 6074isc_dscp_t 6075dns_zone_getparentalsrc4dscp(dns_zone_t *zone) { 6076 REQUIRE(DNS_ZONE_VALID(zone)); 6077 return (zone->parentalsrc4dscp); 6078} 6079 6080isc_result_t 6081dns_zone_setparentalsrc6(dns_zone_t *zone, const isc_sockaddr_t *parentalsrc) { 6082 REQUIRE(DNS_ZONE_VALID(zone)); 6083 6084 LOCK_ZONE(zone); 6085 zone->parentalsrc6 = *parentalsrc; 6086 UNLOCK_ZONE(zone); 6087 6088 return (ISC_R_SUCCESS); 6089} 6090 6091isc_sockaddr_t * 6092dns_zone_getparentalsrc6(dns_zone_t *zone) { 6093 REQUIRE(DNS_ZONE_VALID(zone)); 6094 return (&zone->parentalsrc6); 6095} 6096 6097isc_result_t 6098dns_zone_setparentalsrc6dscp(dns_zone_t *zone, isc_dscp_t dscp) { 6099 REQUIRE(DNS_ZONE_VALID(zone)); 6100 6101 LOCK_ZONE(zone); 6102 zone->parentalsrc6dscp = dscp; 6103 UNLOCK_ZONE(zone); 6104 6105 return (ISC_R_SUCCESS); 6106} 6107 6108isc_dscp_t 6109dns_zone_getparentalsrc6dscp(dns_zone_t *zone) { 6110 REQUIRE(DNS_ZONE_VALID(zone)); 6111 return (zone->parentalsrc6dscp); 6112} 6113 6114isc_result_t 6115dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 6116 REQUIRE(DNS_ZONE_VALID(zone)); 6117 6118 LOCK_ZONE(zone); 6119 zone->notifysrc4 = *notifysrc; 6120 UNLOCK_ZONE(zone); 6121 6122 return (ISC_R_SUCCESS); 6123} 6124 6125isc_sockaddr_t * 6126dns_zone_getnotifysrc4(dns_zone_t *zone) { 6127 REQUIRE(DNS_ZONE_VALID(zone)); 6128 return (&zone->notifysrc4); 6129} 6130 6131isc_result_t 6132dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp) { 6133 REQUIRE(DNS_ZONE_VALID(zone)); 6134 6135 LOCK_ZONE(zone); 6136 zone->notifysrc4dscp = dscp; 6137 UNLOCK_ZONE(zone); 6138 6139 return (ISC_R_SUCCESS); 6140} 6141 6142isc_dscp_t 6143dns_zone_getnotifysrc4dscp(dns_zone_t *zone) { 6144 REQUIRE(DNS_ZONE_VALID(zone)); 6145 return (zone->notifysrc4dscp); 6146} 6147 6148isc_result_t 6149dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 6150 REQUIRE(DNS_ZONE_VALID(zone)); 6151 6152 LOCK_ZONE(zone); 6153 zone->notifysrc6 = *notifysrc; 6154 UNLOCK_ZONE(zone); 6155 6156 return (ISC_R_SUCCESS); 6157} 6158 6159isc_sockaddr_t * 6160dns_zone_getnotifysrc6(dns_zone_t *zone) { 6161 REQUIRE(DNS_ZONE_VALID(zone)); 6162 return (&zone->notifysrc6); 6163} 6164 6165isc_result_t 6166dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp) { 6167 REQUIRE(DNS_ZONE_VALID(zone)); 6168 6169 LOCK_ZONE(zone); 6170 zone->notifysrc6dscp = dscp; 6171 UNLOCK_ZONE(zone); 6172 6173 return (ISC_R_SUCCESS); 6174} 6175 6176isc_dscp_t 6177dns_zone_getnotifysrc6dscp(dns_zone_t *zone) { 6178 REQUIRE(DNS_ZONE_VALID(zone)); 6179 return (zone->notifysrc6dscp); 6180} 6181 6182static bool 6183same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist, 6184 uint32_t count) { 6185 unsigned int i; 6186 6187 for (i = 0; i < count; i++) { 6188 if (!isc_sockaddr_equal(&oldlist[i], &newlist[i])) { 6189 return (false); 6190 } 6191 } 6192 return (true); 6193} 6194 6195static bool 6196same_keynames(dns_name_t *const *oldlist, dns_name_t *const *newlist, 6197 uint32_t count) { 6198 unsigned int i; 6199 6200 if (oldlist == NULL && newlist == NULL) { 6201 return (true); 6202 } 6203 if (oldlist == NULL || newlist == NULL) { 6204 return (false); 6205 } 6206 6207 for (i = 0; i < count; i++) { 6208 if (oldlist[i] == NULL && newlist[i] == NULL) { 6209 continue; 6210 } 6211 if (oldlist[i] == NULL || newlist[i] == NULL || 6212 !dns_name_equal(oldlist[i], newlist[i])) 6213 { 6214 return (false); 6215 } 6216 } 6217 return (true); 6218} 6219 6220static void 6221clear_serverslist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp, 6222 dns_name_t ***keynamesp, unsigned int *countp, 6223 isc_mem_t *mctx) { 6224 unsigned int count; 6225 isc_sockaddr_t *addrs; 6226 isc_dscp_t *dscps; 6227 dns_name_t **keynames; 6228 6229 REQUIRE(countp != NULL && addrsp != NULL && dscpsp != NULL && 6230 keynamesp != NULL); 6231 6232 count = *countp; 6233 *countp = 0; 6234 addrs = *addrsp; 6235 *addrsp = NULL; 6236 dscps = *dscpsp; 6237 *dscpsp = NULL; 6238 keynames = *keynamesp; 6239 *keynamesp = NULL; 6240 6241 if (addrs != NULL) { 6242 isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t)); 6243 } 6244 6245 if (dscps != NULL) { 6246 isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t)); 6247 } 6248 6249 if (keynames != NULL) { 6250 unsigned int i; 6251 for (i = 0; i < count; i++) { 6252 if (keynames[i] != NULL) { 6253 dns_name_free(keynames[i], mctx); 6254 isc_mem_put(mctx, keynames[i], 6255 sizeof(dns_name_t)); 6256 keynames[i] = NULL; 6257 } 6258 } 6259 isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *)); 6260 } 6261} 6262 6263static isc_result_t 6264set_serverslist(unsigned int count, const isc_sockaddr_t *addrs, 6265 isc_sockaddr_t **newaddrsp, const isc_dscp_t *dscp, 6266 isc_dscp_t **newdscpp, dns_name_t **names, 6267 dns_name_t ***newnamesp, isc_mem_t *mctx) { 6268 isc_sockaddr_t *newaddrs = NULL; 6269 isc_dscp_t *newdscp = NULL; 6270 dns_name_t **newnames = NULL; 6271 unsigned int i; 6272 6273 REQUIRE(newaddrsp != NULL && *newaddrsp == NULL); 6274 REQUIRE(newdscpp != NULL && *newdscpp == NULL); 6275 REQUIRE(newnamesp != NULL && *newnamesp == NULL); 6276 6277 newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs)); 6278 memmove(newaddrs, addrs, count * sizeof(*newaddrs)); 6279 6280 if (dscp != NULL) { 6281 newdscp = isc_mem_get(mctx, count * sizeof(*newdscp)); 6282 memmove(newdscp, dscp, count * sizeof(*newdscp)); 6283 } else { 6284 newdscp = NULL; 6285 } 6286 6287 if (names != NULL) { 6288 newnames = isc_mem_get(mctx, count * sizeof(*newnames)); 6289 for (i = 0; i < count; i++) { 6290 newnames[i] = NULL; 6291 } 6292 for (i = 0; i < count; i++) { 6293 if (names[i] != NULL) { 6294 newnames[i] = isc_mem_get(mctx, 6295 sizeof(dns_name_t)); 6296 dns_name_init(newnames[i], NULL); 6297 dns_name_dup(names[i], mctx, newnames[i]); 6298 } 6299 } 6300 } else { 6301 newnames = NULL; 6302 } 6303 6304 *newdscpp = newdscp; 6305 *newaddrsp = newaddrs; 6306 *newnamesp = newnames; 6307 return (ISC_R_SUCCESS); 6308} 6309 6310isc_result_t 6311dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, 6312 uint32_t count) { 6313 return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, NULL, 6314 count)); 6315} 6316 6317isc_result_t 6318dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify, 6319 dns_name_t **keynames, uint32_t count) { 6320 return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, keynames, 6321 count)); 6322} 6323 6324isc_result_t 6325dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify, 6326 const isc_dscp_t *dscps, dns_name_t **keynames, 6327 uint32_t count) { 6328 isc_result_t result; 6329 isc_sockaddr_t *newaddrs = NULL; 6330 isc_dscp_t *newdscps = NULL; 6331 dns_name_t **newnames = NULL; 6332 6333 REQUIRE(DNS_ZONE_VALID(zone)); 6334 REQUIRE(count == 0 || notify != NULL); 6335 if (keynames != NULL) { 6336 REQUIRE(count != 0); 6337 } 6338 6339 LOCK_ZONE(zone); 6340 6341 if (count == zone->notifycnt && 6342 same_addrs(zone->notify, notify, count) && 6343 same_keynames(zone->notifykeynames, keynames, count)) 6344 { 6345 goto unlock; 6346 } 6347 6348 clear_serverslist(&zone->notify, &zone->notifydscp, 6349 &zone->notifykeynames, &zone->notifycnt, zone->mctx); 6350 6351 if (count == 0) { 6352 goto unlock; 6353 } 6354 6355 /* 6356 * Set up the notify and notifykey lists 6357 */ 6358 result = set_serverslist(count, notify, &newaddrs, dscps, &newdscps, 6359 keynames, &newnames, zone->mctx); 6360 if (result != ISC_R_SUCCESS) { 6361 goto unlock; 6362 } 6363 6364 /* 6365 * Everything is ok so attach to the zone. 6366 */ 6367 zone->notify = newaddrs; 6368 zone->notifydscp = newdscps; 6369 zone->notifykeynames = newnames; 6370 zone->notifycnt = count; 6371unlock: 6372 UNLOCK_ZONE(zone); 6373 return (ISC_R_SUCCESS); 6374} 6375 6376isc_result_t 6377dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *masters, 6378 uint32_t count) { 6379 isc_result_t result; 6380 6381 result = dns_zone_setprimarieswithkeys(zone, masters, NULL, count); 6382 return (result); 6383} 6384 6385isc_result_t 6386dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters, 6387 dns_name_t **keynames, uint32_t count) { 6388 isc_result_t result = ISC_R_SUCCESS; 6389 isc_sockaddr_t *newaddrs = NULL; 6390 isc_dscp_t *newdscps = NULL; 6391 dns_name_t **newnames = NULL; 6392 bool *newok; 6393 unsigned int i; 6394 6395 REQUIRE(DNS_ZONE_VALID(zone)); 6396 REQUIRE(count == 0 || masters != NULL); 6397 if (keynames != NULL) { 6398 REQUIRE(count != 0); 6399 } 6400 6401 LOCK_ZONE(zone); 6402 /* 6403 * The refresh code assumes that 'primaries' wouldn't change under it. 6404 * If it will change then kill off any current refresh in progress 6405 * and update the primaries info. If it won't change then we can just 6406 * unlock and exit. 6407 */ 6408 if (count != zone->masterscnt || 6409 !same_addrs(zone->masters, masters, count) || 6410 !same_keynames(zone->masterkeynames, keynames, count)) 6411 { 6412 if (zone->request != NULL) { 6413 dns_request_cancel(zone->request); 6414 } 6415 } else { 6416 goto unlock; 6417 } 6418 6419 /* 6420 * This needs to happen before clear_addresskeylist() sets 6421 * zone->masterscnt to 0: 6422 */ 6423 if (zone->mastersok != NULL) { 6424 isc_mem_put(zone->mctx, zone->mastersok, 6425 zone->masterscnt * sizeof(bool)); 6426 zone->mastersok = NULL; 6427 } 6428 clear_serverslist(&zone->masters, &zone->masterdscps, 6429 &zone->masterkeynames, &zone->masterscnt, zone->mctx); 6430 /* 6431 * If count == 0, don't allocate any space for masters, mastersok or 6432 * keynames so internally, those pointers are NULL if count == 0 6433 */ 6434 if (count == 0) { 6435 goto unlock; 6436 } 6437 6438 /* 6439 * mastersok must contain count elements 6440 */ 6441 newok = isc_mem_get(zone->mctx, count * sizeof(*newok)); 6442 for (i = 0; i < count; i++) { 6443 newok[i] = false; 6444 } 6445 6446 /* 6447 * Now set up the primaries and primary key lists 6448 */ 6449 result = set_serverslist(count, masters, &newaddrs, NULL, &newdscps, 6450 keynames, &newnames, zone->mctx); 6451 INSIST(newdscps == NULL); 6452 if (result != ISC_R_SUCCESS) { 6453 isc_mem_put(zone->mctx, newok, count * sizeof(*newok)); 6454 goto unlock; 6455 } 6456 6457 /* 6458 * Everything is ok so attach to the zone. 6459 */ 6460 zone->curmaster = 0; 6461 zone->mastersok = newok; 6462 zone->masters = newaddrs; 6463 zone->masterdscps = newdscps; 6464 zone->masterkeynames = newnames; 6465 zone->masterscnt = count; 6466 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS); 6467 6468unlock: 6469 UNLOCK_ZONE(zone); 6470 return (result); 6471} 6472 6473isc_result_t 6474dns_zone_setparentals(dns_zone_t *zone, const isc_sockaddr_t *parentals, 6475 dns_name_t **keynames, uint32_t count) { 6476 isc_result_t result = ISC_R_SUCCESS; 6477 isc_sockaddr_t *newaddrs = NULL; 6478 isc_dscp_t *newdscps = NULL; 6479 dns_name_t **newkeynames = NULL; 6480 6481 REQUIRE(DNS_ZONE_VALID(zone)); 6482 REQUIRE(count == 0 || parentals != NULL); 6483 if (keynames != NULL) { 6484 REQUIRE(count != 0); 6485 } 6486 6487 LOCK_ZONE(zone); 6488 6489 clear_serverslist(&zone->parentals, &zone->parentaldscps, 6490 &zone->parentalkeynames, &zone->parentalscnt, 6491 zone->mctx); 6492 /* 6493 * If count == 0, don't allocate any space for parentals, or keynames 6494 * so internally, those pointers are NULL if count == 0 6495 */ 6496 if (count == 0) { 6497 goto unlock; 6498 } 6499 6500 /* 6501 * Now set up the parentals and parental key lists 6502 */ 6503 result = set_serverslist(count, parentals, &newaddrs, NULL, &newdscps, 6504 keynames, &newkeynames, zone->mctx); 6505 INSIST(newdscps == NULL); 6506 if (result != ISC_R_SUCCESS) { 6507 goto unlock; 6508 } 6509 6510 /* 6511 * Everything is ok so attach to the zone. 6512 */ 6513 zone->parentals = newaddrs; 6514 zone->parentaldscps = newdscps; 6515 zone->parentalkeynames = newkeynames; 6516 zone->parentalscnt = count; 6517 6518 dns_zone_log(zone, ISC_LOG_NOTICE, "checkds: set %u parentals", count); 6519 6520unlock: 6521 UNLOCK_ZONE(zone); 6522 return (result); 6523} 6524 6525isc_result_t 6526dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) { 6527 isc_result_t result = ISC_R_SUCCESS; 6528 6529 REQUIRE(DNS_ZONE_VALID(zone)); 6530 6531 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 6532 if (zone->db == NULL) { 6533 result = DNS_R_NOTLOADED; 6534 } else { 6535 dns_db_attach(zone->db, dpb); 6536 } 6537 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 6538 6539 return (result); 6540} 6541 6542void 6543dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) { 6544 REQUIRE(DNS_ZONE_VALID(zone)); 6545 REQUIRE(zone->type == dns_zone_staticstub); 6546 6547 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 6548 REQUIRE(zone->db == NULL); 6549 dns_db_attach(db, &zone->db); 6550 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 6551} 6552 6553/* 6554 * Coordinates the starting of routine jobs. 6555 */ 6556void 6557dns_zone_maintenance(dns_zone_t *zone) { 6558 const char me[] = "dns_zone_maintenance"; 6559 isc_time_t now; 6560 6561 REQUIRE(DNS_ZONE_VALID(zone)); 6562 ENTER; 6563 6564 LOCK_ZONE(zone); 6565 TIME_NOW(&now); 6566 zone_settimer(zone, &now); 6567 UNLOCK_ZONE(zone); 6568} 6569 6570static bool 6571was_dumping(dns_zone_t *zone) { 6572 REQUIRE(LOCKED_ZONE(zone)); 6573 6574 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 6575 return (true); 6576 } 6577 6578 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 6579 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 6580 isc_time_settoepoch(&zone->dumptime); 6581 return (false); 6582} 6583 6584/*% 6585 * Find up to 'maxkeys' DNSSEC keys used for signing version 'ver' of database 6586 * 'db' for zone 'zone' in its key directory, then load these keys into 'keys'. 6587 * Only load the public part of a given key if it is not active at timestamp 6588 * 'now'. Store the number of keys found in 'nkeys'. 6589 */ 6590isc_result_t 6591dns__zone_findkeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 6592 isc_stdtime_t now, isc_mem_t *mctx, unsigned int maxkeys, 6593 dst_key_t **keys, unsigned int *nkeys) { 6594 isc_result_t result; 6595 dns_dbnode_t *node = NULL; 6596 const char *directory = dns_zone_getkeydirectory(zone); 6597 6598 CHECK(dns_db_findnode(db, dns_db_origin(db), false, &node)); 6599 memset(keys, 0, sizeof(*keys) * maxkeys); 6600 6601 dns_zone_lock_keyfiles(zone); 6602 6603 result = dns_dnssec_findzonekeys(db, ver, node, dns_db_origin(db), 6604 directory, now, mctx, maxkeys, keys, 6605 nkeys); 6606 6607 dns_zone_unlock_keyfiles(zone); 6608 6609 if (result == ISC_R_NOTFOUND) { 6610 result = ISC_R_SUCCESS; 6611 } 6612 6613failure: 6614 6615 if (node != NULL) { 6616 dns_db_detachnode(db, &node); 6617 } 6618 return (result); 6619} 6620 6621/*% 6622 * Find DNSSEC keys used for signing zone with dnssec-policy. Load these keys 6623 * into 'keys'. Requires KASP to be locked. 6624 */ 6625isc_result_t 6626dns_zone_getdnsseckeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 6627 isc_stdtime_t now, dns_dnsseckeylist_t *keys) { 6628 isc_result_t result; 6629 const char *dir = dns_zone_getkeydirectory(zone); 6630 dns_dbnode_t *node = NULL; 6631 dns_dnsseckey_t *key, *key_next; 6632 dns_dnsseckeylist_t dnskeys; 6633 dns_name_t *origin = dns_zone_getorigin(zone); 6634 dns_kasp_t *kasp = dns_zone_getkasp(zone); 6635 dns_rdataset_t keyset; 6636 6637 REQUIRE(DNS_ZONE_VALID(zone)); 6638 REQUIRE(kasp != NULL); 6639 6640 ISC_LIST_INIT(dnskeys); 6641 6642 dns_rdataset_init(&keyset); 6643 6644 CHECK(dns_db_findnode(db, origin, false, &node)); 6645 6646 /* Get keys from private key files. */ 6647 dns_zone_lock_keyfiles(zone); 6648 result = dns_dnssec_findmatchingkeys(origin, dir, now, 6649 dns_zone_getmctx(zone), keys); 6650 dns_zone_unlock_keyfiles(zone); 6651 6652 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 6653 goto failure; 6654 } 6655 6656 /* Get public keys (dnskeys). */ 6657 dns_rdataset_init(&keyset); 6658 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 6659 dns_rdatatype_none, 0, &keyset, NULL); 6660 if (result == ISC_R_SUCCESS) { 6661 CHECK(dns_dnssec_keylistfromrdataset( 6662 origin, dir, dns_zone_getmctx(zone), &keyset, NULL, 6663 NULL, false, false, &dnskeys)); 6664 } else if (result != ISC_R_NOTFOUND) { 6665 CHECK(result); 6666 } 6667 6668 /* Add new 'dnskeys' to 'keys'. */ 6669 for (dns_dnsseckey_t *k1 = ISC_LIST_HEAD(dnskeys); k1 != NULL; 6670 k1 = key_next) 6671 { 6672 dns_dnsseckey_t *k2 = NULL; 6673 key_next = ISC_LIST_NEXT(k1, link); 6674 6675 for (k2 = ISC_LIST_HEAD(*keys); k2 != NULL; 6676 k2 = ISC_LIST_NEXT(k2, link)) 6677 { 6678 if (dst_key_compare(k1->key, k2->key)) { 6679 break; 6680 } 6681 } 6682 /* No match found, add the new key. */ 6683 if (k2 == NULL) { 6684 ISC_LIST_UNLINK(dnskeys, k1, link); 6685 ISC_LIST_APPEND(*keys, k1, link); 6686 } 6687 } 6688 6689failure: 6690 if (dns_rdataset_isassociated(&keyset)) { 6691 dns_rdataset_disassociate(&keyset); 6692 } 6693 if (node != NULL) { 6694 dns_db_detachnode(db, &node); 6695 } 6696 while (!ISC_LIST_EMPTY(dnskeys)) { 6697 key = ISC_LIST_HEAD(dnskeys); 6698 ISC_LIST_UNLINK(dnskeys, key, link); 6699 dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key); 6700 } 6701 return (result); 6702} 6703 6704static isc_result_t 6705offline(dns_db_t *db, dns_dbversion_t *ver, dns__zonediff_t *zonediff, 6706 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { 6707 isc_result_t result; 6708 6709 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) { 6710 return (ISC_R_SUCCESS); 6711 } 6712 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, 6713 name, ttl, rdata); 6714 if (result != ISC_R_SUCCESS) { 6715 return (result); 6716 } 6717 rdata->flags |= DNS_RDATA_OFFLINE; 6718 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN, 6719 name, ttl, rdata); 6720 zonediff->offline = true; 6721 return (result); 6722} 6723 6724static void 6725set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, 6726 isc_stdtime_t now) { 6727 unsigned int delta; 6728 char timebuf[80]; 6729 6730 LOCK_ZONE(zone); 6731 zone->key_expiry = when; 6732 if (when <= now) { 6733 dns_zone_log(zone, ISC_LOG_ERROR, 6734 "DNSKEY RRSIG(s) have expired"); 6735 isc_time_settoepoch(&zone->keywarntime); 6736 } else if (when < now + 7 * 24 * 3600) { 6737 isc_time_t t; 6738 isc_time_set(&t, when, 0); 6739 isc_time_formattimestamp(&t, timebuf, 80); 6740 dns_zone_log(zone, ISC_LOG_WARNING, 6741 "DNSKEY RRSIG(s) will expire within 7 days: %s", 6742 timebuf); 6743 delta = when - now; 6744 delta--; /* loop prevention */ 6745 delta /= 24 * 3600; /* to whole days */ 6746 delta *= 24 * 3600; /* to seconds */ 6747 isc_time_set(&zone->keywarntime, when - delta, 0); 6748 } else { 6749 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0); 6750 isc_time_formattimestamp(&zone->keywarntime, timebuf, 80); 6751 dns_zone_log(zone, ISC_LOG_NOTICE, "setting keywarntime to %s", 6752 timebuf); 6753 } 6754 UNLOCK_ZONE(zone); 6755} 6756 6757/* 6758 * Helper function to del_sigs(). We don't want to delete RRSIGs that 6759 * have no new key. 6760 */ 6761static bool 6762delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys, 6763 bool kasp, bool *warn) { 6764 unsigned int i = 0; 6765 isc_result_t ret; 6766 bool have_ksk = false, have_zsk = false; 6767 bool have_pksk = false, have_pzsk = false; 6768 6769 for (i = 0; i < nkeys; i++) { 6770 bool ksk, zsk; 6771 6772 if (have_pksk && have_ksk && have_pzsk && have_zsk) { 6773 break; 6774 } 6775 6776 if (rrsig_ptr->algorithm != dst_key_alg(keys[i])) { 6777 continue; 6778 } 6779 6780 ret = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk); 6781 if (ret != ISC_R_SUCCESS) { 6782 ksk = KSK(keys[i]); 6783 } 6784 ret = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk); 6785 if (ret != ISC_R_SUCCESS) { 6786 zsk = !KSK(keys[i]); 6787 } 6788 6789 if (ksk) { 6790 have_ksk = true; 6791 if (dst_key_isprivate(keys[i])) { 6792 have_pksk = true; 6793 } 6794 } 6795 if (zsk) { 6796 have_zsk = true; 6797 if (dst_key_isprivate(keys[i])) { 6798 have_pzsk = true; 6799 } 6800 } 6801 } 6802 6803 if (have_zsk && have_ksk && !have_pzsk) { 6804 *warn = true; 6805 } 6806 6807 if (have_pksk && have_pzsk) { 6808 return (true); 6809 } 6810 6811 /* 6812 * Deleting the SOA RRSIG is always okay. 6813 */ 6814 if (rrsig_ptr->covered == dns_rdatatype_soa) { 6815 return (true); 6816 } 6817 6818 /* 6819 * It's okay to delete a signature if there is an active key with the 6820 * same algorithm to replace it, unless that violates the DNSSEC 6821 * policy. 6822 */ 6823 if (have_pksk || have_pzsk) { 6824 if (kasp && have_pzsk) { 6825 return (true); 6826 } 6827 return (!kasp); 6828 } 6829 6830 /* 6831 * Failing that, it is *not* okay to delete a signature 6832 * if the associated public key is still in the DNSKEY RRset 6833 */ 6834 for (i = 0; i < nkeys; i++) { 6835 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) && 6836 (rrsig_ptr->keyid == dst_key_id(keys[i]))) 6837 { 6838 return (false); 6839 } 6840 } 6841 6842 /* 6843 * But if the key is gone, then go ahead. 6844 */ 6845 return (true); 6846} 6847 6848/* 6849 * Delete expired RRsigs and any RRsigs we are about to re-sign. 6850 * See also update.c:del_keysigs(). 6851 */ 6852static isc_result_t 6853del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 6854 dns_rdatatype_t type, dns__zonediff_t *zonediff, dst_key_t **keys, 6855 unsigned int nkeys, isc_stdtime_t now, bool incremental) { 6856 isc_result_t result; 6857 dns_dbnode_t *node = NULL; 6858 dns_rdataset_t rdataset; 6859 unsigned int i; 6860 dns_rdata_rrsig_t rrsig; 6861 bool kasp = (dns_zone_getkasp(zone) != NULL); 6862 bool found; 6863 int64_t timewarn = 0, timemaybe = 0; 6864 6865 dns_rdataset_init(&rdataset); 6866 6867 if (type == dns_rdatatype_nsec3) { 6868 result = dns_db_findnsec3node(db, name, false, &node); 6869 } else { 6870 result = dns_db_findnode(db, name, false, &node); 6871 } 6872 if (result == ISC_R_NOTFOUND) { 6873 return (ISC_R_SUCCESS); 6874 } 6875 if (result != ISC_R_SUCCESS) { 6876 goto failure; 6877 } 6878 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type, 6879 (isc_stdtime_t)0, &rdataset, NULL); 6880 dns_db_detachnode(db, &node); 6881 6882 if (result == ISC_R_NOTFOUND) { 6883 INSIST(!dns_rdataset_isassociated(&rdataset)); 6884 return (ISC_R_SUCCESS); 6885 } 6886 if (result != ISC_R_SUCCESS) { 6887 INSIST(!dns_rdataset_isassociated(&rdataset)); 6888 goto failure; 6889 } 6890 6891 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 6892 result = dns_rdataset_next(&rdataset)) 6893 { 6894 dns_rdata_t rdata = DNS_RDATA_INIT; 6895 6896 dns_rdataset_current(&rdataset, &rdata); 6897 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 6898 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6899 6900 if (type != dns_rdatatype_dnskey && type != dns_rdatatype_cds && 6901 type != dns_rdatatype_cdnskey) 6902 { 6903 bool warn = false, deleted = false; 6904 if (delsig_ok(&rrsig, keys, nkeys, kasp, &warn)) { 6905 result = update_one_rr(db, ver, zonediff->diff, 6906 DNS_DIFFOP_DELRESIGN, 6907 name, rdataset.ttl, 6908 &rdata); 6909 if (result != ISC_R_SUCCESS) { 6910 break; 6911 } 6912 deleted = true; 6913 } 6914 if (warn && !deleted) { 6915 /* 6916 * At this point, we've got an RRSIG, 6917 * which is signed by an inactive key. 6918 * An administrator needs to provide a new 6919 * key/alg, but until that time, we want to 6920 * keep the old RRSIG. Marking the key as 6921 * offline will prevent us spinning waiting 6922 * for the private part. 6923 */ 6924 if (incremental) { 6925 result = offline(db, ver, zonediff, 6926 name, rdataset.ttl, 6927 &rdata); 6928 if (result != ISC_R_SUCCESS) { 6929 break; 6930 } 6931 } 6932 6933 /* 6934 * Log the key id and algorithm of 6935 * the inactive key with no replacement 6936 */ 6937 if (zone->log_key_expired_timer <= now) { 6938 char origin[DNS_NAME_FORMATSIZE]; 6939 char algbuf[DNS_NAME_FORMATSIZE]; 6940 dns_name_format(&zone->origin, origin, 6941 sizeof(origin)); 6942 dns_secalg_format(rrsig.algorithm, 6943 algbuf, 6944 sizeof(algbuf)); 6945 dns_zone_log(zone, ISC_LOG_WARNING, 6946 "Key %s/%s/%d " 6947 "missing or inactive " 6948 "and has no replacement: " 6949 "retaining signatures.", 6950 origin, algbuf, 6951 rrsig.keyid); 6952 zone->log_key_expired_timer = now + 6953 3600; 6954 } 6955 } 6956 continue; 6957 } 6958 6959 /* 6960 * KSK RRSIGs requires special processing. 6961 */ 6962 found = false; 6963 for (i = 0; i < nkeys; i++) { 6964 if (rrsig.algorithm == dst_key_alg(keys[i]) && 6965 rrsig.keyid == dst_key_id(keys[i])) 6966 { 6967 found = true; 6968 /* 6969 * Mark offline DNSKEY. 6970 * We want the earliest offline expire time 6971 * iff there is a new offline signature. 6972 */ 6973 if (!dst_key_inactive(keys[i]) && 6974 !dst_key_isprivate(keys[i])) 6975 { 6976 int64_t timeexpire = dns_time64_from32( 6977 rrsig.timeexpire); 6978 if (timewarn != 0 && 6979 timewarn > timeexpire) 6980 { 6981 timewarn = timeexpire; 6982 } 6983 if (rdata.flags & DNS_RDATA_OFFLINE) { 6984 if (timemaybe == 0 || 6985 timemaybe > timeexpire) 6986 { 6987 timemaybe = timeexpire; 6988 } 6989 break; 6990 } 6991 if (timewarn == 0) { 6992 timewarn = timemaybe; 6993 } 6994 if (timewarn == 0 || 6995 timewarn > timeexpire) 6996 { 6997 timewarn = timeexpire; 6998 } 6999 result = offline(db, ver, zonediff, 7000 name, rdataset.ttl, 7001 &rdata); 7002 break; 7003 } 7004 result = update_one_rr(db, ver, zonediff->diff, 7005 DNS_DIFFOP_DELRESIGN, 7006 name, rdataset.ttl, 7007 &rdata); 7008 break; 7009 } 7010 } 7011 7012 /* 7013 * If there is not a matching DNSKEY then 7014 * delete the RRSIG. 7015 */ 7016 if (!found) { 7017 result = update_one_rr(db, ver, zonediff->diff, 7018 DNS_DIFFOP_DELRESIGN, name, 7019 rdataset.ttl, &rdata); 7020 } 7021 if (result != ISC_R_SUCCESS) { 7022 break; 7023 } 7024 } 7025 7026 dns_rdataset_disassociate(&rdataset); 7027 if (result == ISC_R_NOMORE) { 7028 result = ISC_R_SUCCESS; 7029 } 7030 if (timewarn > 0) { 7031 isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn; 7032 if (timewarn == stdwarn) { 7033 set_key_expiry_warning(zone, (isc_stdtime_t)timewarn, 7034 now); 7035 } else { 7036 dns_zone_log(zone, ISC_LOG_ERROR, 7037 "key expiry warning time out of range"); 7038 } 7039 } 7040failure: 7041 if (node != NULL) { 7042 dns_db_detachnode(db, &node); 7043 } 7044 return (result); 7045} 7046 7047static isc_result_t 7048add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_zone_t *zone, 7049 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, 7050 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception, 7051 isc_stdtime_t expire, bool check_ksk, bool keyset_kskonly) { 7052 isc_result_t result; 7053 dns_dbnode_t *node = NULL; 7054 dns_stats_t *dnssecsignstats; 7055 dns_rdataset_t rdataset; 7056 dns_rdata_t sig_rdata = DNS_RDATA_INIT; 7057 unsigned char data[1024]; /* XXX */ 7058 isc_buffer_t buffer; 7059 unsigned int i, j; 7060 bool use_kasp = false; 7061 7062 if (dns_zone_getkasp(zone) != NULL) { 7063 check_ksk = false; 7064 keyset_kskonly = true; 7065 use_kasp = true; 7066 } 7067 7068 dns_rdataset_init(&rdataset); 7069 isc_buffer_init(&buffer, data, sizeof(data)); 7070 7071 if (type == dns_rdatatype_nsec3) { 7072 result = dns_db_findnsec3node(db, name, false, &node); 7073 } else { 7074 result = dns_db_findnode(db, name, false, &node); 7075 } 7076 if (result == ISC_R_NOTFOUND) { 7077 return (ISC_R_SUCCESS); 7078 } 7079 if (result != ISC_R_SUCCESS) { 7080 goto failure; 7081 } 7082 result = dns_db_findrdataset(db, node, ver, type, 0, (isc_stdtime_t)0, 7083 &rdataset, NULL); 7084 dns_db_detachnode(db, &node); 7085 if (result == ISC_R_NOTFOUND) { 7086 INSIST(!dns_rdataset_isassociated(&rdataset)); 7087 return (ISC_R_SUCCESS); 7088 } 7089 if (result != ISC_R_SUCCESS) { 7090 INSIST(!dns_rdataset_isassociated(&rdataset)); 7091 goto failure; 7092 } 7093 7094 for (i = 0; i < nkeys; i++) { 7095 bool both = false; 7096 7097 /* Don't add signatures for offline or inactive keys */ 7098 if (!dst_key_isprivate(keys[i])) { 7099 continue; 7100 } 7101 if (dst_key_inactive(keys[i])) { 7102 continue; 7103 } 7104 7105 if (check_ksk && !REVOKE(keys[i])) { 7106 bool have_ksk, have_nonksk; 7107 if (KSK(keys[i])) { 7108 have_ksk = true; 7109 have_nonksk = false; 7110 } else { 7111 have_ksk = false; 7112 have_nonksk = true; 7113 } 7114 7115 for (j = 0; j < nkeys; j++) { 7116 if (j == i || ALG(keys[i]) != ALG(keys[j])) { 7117 continue; 7118 } 7119 7120 /* 7121 * Don't consider inactive keys, however 7122 * the KSK may be temporary offline, so do 7123 * consider keys which private key files are 7124 * unavailable. 7125 */ 7126 if (dst_key_inactive(keys[j])) { 7127 continue; 7128 } 7129 7130 if (REVOKE(keys[j])) { 7131 continue; 7132 } 7133 if (KSK(keys[j])) { 7134 have_ksk = true; 7135 } else if (dst_key_isprivate(keys[j])) { 7136 have_nonksk = true; 7137 } 7138 both = have_ksk && have_nonksk; 7139 if (both) { 7140 break; 7141 } 7142 } 7143 } 7144 if (use_kasp) { 7145 /* 7146 * A dnssec-policy is found. Check what RRsets this 7147 * key should sign. 7148 */ 7149 isc_result_t kresult; 7150 isc_stdtime_t when; 7151 bool ksk = false; 7152 bool zsk = false; 7153 bool have_ksk = false; 7154 bool have_zsk = false; 7155 7156 kresult = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk); 7157 if (kresult != ISC_R_SUCCESS) { 7158 if (KSK(keys[i])) { 7159 ksk = true; 7160 } 7161 } 7162 kresult = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk); 7163 if (kresult != ISC_R_SUCCESS) { 7164 if (!KSK(keys[i])) { 7165 zsk = true; 7166 } 7167 } 7168 7169 have_ksk = ksk; 7170 have_zsk = zsk; 7171 both = have_ksk && have_zsk; 7172 7173 for (j = 0; j < nkeys; j++) { 7174 if (both) { 7175 break; 7176 } 7177 7178 if (j == i || ALG(keys[i]) != ALG(keys[j])) { 7179 continue; 7180 } 7181 7182 /* 7183 * Don't consider inactive keys or offline keys. 7184 */ 7185 if (!dst_key_isprivate(keys[j])) { 7186 continue; 7187 } 7188 if (dst_key_inactive(keys[j])) { 7189 continue; 7190 } 7191 7192 if (REVOKE(keys[j])) { 7193 continue; 7194 } 7195 7196 if (!have_ksk) { 7197 kresult = dst_key_getbool(keys[j], 7198 DST_BOOL_KSK, 7199 &have_ksk); 7200 if (kresult != ISC_R_SUCCESS) { 7201 if (KSK(keys[j])) { 7202 have_ksk = true; 7203 } 7204 } 7205 } 7206 if (!have_zsk) { 7207 kresult = dst_key_getbool(keys[j], 7208 DST_BOOL_ZSK, 7209 &have_zsk); 7210 if (kresult != ISC_R_SUCCESS) { 7211 if (!KSK(keys[j])) { 7212 have_zsk = true; 7213 } 7214 } 7215 } 7216 both = have_ksk && have_zsk; 7217 } 7218 7219 if (type == dns_rdatatype_dnskey || 7220 type == dns_rdatatype_cdnskey || 7221 type == dns_rdatatype_cds) 7222 { 7223 /* 7224 * DNSKEY RRset is signed with KSK. 7225 * CDS and CDNSKEY RRsets too (RFC 7344, 4.1). 7226 */ 7227 if (!ksk) { 7228 continue; 7229 } 7230 } else if (!zsk) { 7231 /* 7232 * Other RRsets are signed with ZSK. 7233 */ 7234 if (type != dns_rdatatype_soa && 7235 type != zone->privatetype) 7236 { 7237 continue; 7238 } 7239 if (have_zsk) { 7240 continue; 7241 } 7242 } else if (!dst_key_is_signing(keys[i], DST_BOOL_ZSK, 7243 inception, &when)) 7244 { 7245 /* 7246 * This key is not active for zone-signing. 7247 */ 7248 continue; 7249 } 7250 7251 /* 7252 * If this key is revoked, it may only sign the 7253 * DNSKEY RRset. 7254 */ 7255 if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) { 7256 continue; 7257 } 7258 } else if (both) { 7259 /* 7260 * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1). 7261 */ 7262 if (type == dns_rdatatype_dnskey || 7263 type == dns_rdatatype_cdnskey || 7264 type == dns_rdatatype_cds) 7265 { 7266 if (!KSK(keys[i]) && keyset_kskonly) { 7267 continue; 7268 } 7269 } else if (KSK(keys[i])) { 7270 continue; 7271 } 7272 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) { 7273 continue; 7274 } 7275 7276 /* Calculate the signature, creating a RRSIG RDATA. */ 7277 isc_buffer_clear(&buffer); 7278 CHECK(dns_dnssec_sign(name, &rdataset, keys[i], &inception, 7279 &expire, mctx, &buffer, &sig_rdata)); 7280 7281 /* Update the database and journal with the RRSIG. */ 7282 /* XXX inefficient - will cause dataset merging */ 7283 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, name, 7284 rdataset.ttl, &sig_rdata)); 7285 dns_rdata_reset(&sig_rdata); 7286 isc_buffer_init(&buffer, data, sizeof(data)); 7287 7288 /* Update DNSSEC sign statistics. */ 7289 dnssecsignstats = dns_zone_getdnssecsignstats(zone); 7290 if (dnssecsignstats != NULL) { 7291 /* Generated a new signature. */ 7292 dns_dnssecsignstats_increment(dnssecsignstats, 7293 ID(keys[i]), 7294 (uint8_t)ALG(keys[i]), 7295 dns_dnssecsignstats_sign); 7296 /* This is a refresh. */ 7297 dns_dnssecsignstats_increment( 7298 dnssecsignstats, ID(keys[i]), 7299 (uint8_t)ALG(keys[i]), 7300 dns_dnssecsignstats_refresh); 7301 } 7302 } 7303 7304failure: 7305 if (dns_rdataset_isassociated(&rdataset)) { 7306 dns_rdataset_disassociate(&rdataset); 7307 } 7308 if (node != NULL) { 7309 dns_db_detachnode(db, &node); 7310 } 7311 return (result); 7312} 7313 7314static void 7315zone_resigninc(dns_zone_t *zone) { 7316 const char *me = "zone_resigninc"; 7317 dns_db_t *db = NULL; 7318 dns_dbversion_t *version = NULL; 7319 dns_diff_t _sig_diff; 7320 dns__zonediff_t zonediff; 7321 dns_fixedname_t fixed; 7322 dns_name_t *name; 7323 dns_rdataset_t rdataset; 7324 dns_rdatatype_t covers; 7325 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 7326 bool check_ksk, keyset_kskonly = false; 7327 isc_result_t result; 7328 isc_stdtime_t now, inception, soaexpire, expire, fullexpire, stop; 7329 uint32_t sigvalidityinterval, expiryinterval; 7330 unsigned int i; 7331 unsigned int nkeys = 0; 7332 unsigned int resign; 7333 7334 ENTER; 7335 7336 dns_rdataset_init(&rdataset); 7337 dns_diff_init(zone->mctx, &_sig_diff); 7338 zonediff_init(&zonediff, &_sig_diff); 7339 7340 /* 7341 * Zone is frozen or automatic resigning is disabled. 7342 * Pause for 5 minutes. 7343 */ 7344 if (zone->update_disabled || 7345 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN)) 7346 { 7347 result = ISC_R_FAILURE; 7348 goto failure; 7349 } 7350 7351 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 7352 if (zone->db != NULL) { 7353 dns_db_attach(zone->db, &db); 7354 } 7355 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 7356 if (db == NULL) { 7357 result = ISC_R_FAILURE; 7358 goto failure; 7359 } 7360 7361 result = dns_db_newversion(db, &version); 7362 if (result != ISC_R_SUCCESS) { 7363 dns_zone_log(zone, ISC_LOG_ERROR, 7364 "zone_resigninc:dns_db_newversion -> %s", 7365 dns_result_totext(result)); 7366 goto failure; 7367 } 7368 7369 isc_stdtime_get(&now); 7370 7371 result = dns__zone_findkeys(zone, db, version, now, zone->mctx, 7372 DNS_MAXZONEKEYS, zone_keys, &nkeys); 7373 if (result != ISC_R_SUCCESS) { 7374 dns_zone_log(zone, ISC_LOG_ERROR, 7375 "zone_resigninc:dns__zone_findkeys -> %s", 7376 dns_result_totext(result)); 7377 goto failure; 7378 } 7379 7380 sigvalidityinterval = dns_zone_getsigvalidityinterval(zone); 7381 inception = now - 3600; /* Allow for clock skew. */ 7382 soaexpire = now + sigvalidityinterval; 7383 expiryinterval = dns_zone_getsigresigninginterval(zone); 7384 if (expiryinterval > sigvalidityinterval) { 7385 expiryinterval = sigvalidityinterval; 7386 } else { 7387 expiryinterval = sigvalidityinterval - expiryinterval; 7388 } 7389 7390 /* 7391 * Spread out signatures over time if they happen to be 7392 * clumped. We don't do this for each add_sigs() call as 7393 * we still want some clustering to occur. In normal operations 7394 * the records should be re-signed as they fall due and they should 7395 * already be spread out. However if the server is off for a 7396 * period we need to ensure that the clusters don't become 7397 * synchronised by using the full jitter range. 7398 */ 7399 if (sigvalidityinterval >= 3600U) { 7400 uint32_t normaljitter, fulljitter; 7401 if (sigvalidityinterval > 7200U) { 7402 normaljitter = isc_random_uniform(3600); 7403 fulljitter = isc_random_uniform(expiryinterval); 7404 } else { 7405 normaljitter = fulljitter = isc_random_uniform(1200); 7406 } 7407 expire = soaexpire - normaljitter - 1; 7408 fullexpire = soaexpire - fulljitter - 1; 7409 } else { 7410 expire = fullexpire = soaexpire - 1; 7411 } 7412 stop = now + 5; 7413 7414 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 7415 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 7416 7417 name = dns_fixedname_initname(&fixed); 7418 result = dns_db_getsigningtime(db, &rdataset, name); 7419 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 7420 dns_zone_log(zone, ISC_LOG_ERROR, 7421 "zone_resigninc:dns_db_getsigningtime -> %s", 7422 dns_result_totext(result)); 7423 } 7424 7425 i = 0; 7426 while (result == ISC_R_SUCCESS) { 7427 resign = rdataset.resign - 7428 dns_zone_getsigresigninginterval(zone); 7429 covers = rdataset.covers; 7430 dns_rdataset_disassociate(&rdataset); 7431 7432 /* 7433 * Stop if we hit the SOA as that means we have walked the 7434 * entire zone. The SOA record should always be the most 7435 * recent signature. 7436 */ 7437 /* XXXMPA increase number of RRsets signed pre call */ 7438 if ((covers == dns_rdatatype_soa && 7439 dns_name_equal(name, &zone->origin)) || 7440 i++ > zone->signatures || resign > stop) 7441 { 7442 break; 7443 } 7444 7445 result = del_sigs(zone, db, version, name, covers, &zonediff, 7446 zone_keys, nkeys, now, true); 7447 if (result != ISC_R_SUCCESS) { 7448 dns_zone_log(zone, ISC_LOG_ERROR, 7449 "zone_resigninc:del_sigs -> %s", 7450 dns_result_totext(result)); 7451 break; 7452 } 7453 7454 /* 7455 * If re-signing is over 5 minutes late use 'fullexpire' 7456 * to redistribute the signature over the complete 7457 * re-signing window, otherwise only add a small amount 7458 * of jitter. 7459 */ 7460 result = add_sigs(db, version, name, zone, covers, 7461 zonediff.diff, zone_keys, nkeys, zone->mctx, 7462 inception, 7463 resign > (now - 300) ? expire : fullexpire, 7464 check_ksk, keyset_kskonly); 7465 if (result != ISC_R_SUCCESS) { 7466 dns_zone_log(zone, ISC_LOG_ERROR, 7467 "zone_resigninc:add_sigs -> %s", 7468 dns_result_totext(result)); 7469 break; 7470 } 7471 result = dns_db_getsigningtime(db, &rdataset, name); 7472 if (nkeys == 0 && result == ISC_R_NOTFOUND) { 7473 result = ISC_R_SUCCESS; 7474 break; 7475 } 7476 if (result != ISC_R_SUCCESS) { 7477 dns_zone_log(zone, ISC_LOG_ERROR, 7478 "zone_resigninc:dns_db_getsigningtime -> " 7479 "%s", 7480 dns_result_totext(result)); 7481 } 7482 } 7483 7484 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS) { 7485 goto failure; 7486 } 7487 7488 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 7489 &zonediff, zone_keys, nkeys, now, true); 7490 if (result != ISC_R_SUCCESS) { 7491 dns_zone_log(zone, ISC_LOG_ERROR, 7492 "zone_resigninc:del_sigs -> %s", 7493 dns_result_totext(result)); 7494 goto failure; 7495 } 7496 7497 /* 7498 * Did we change anything in the zone? 7499 */ 7500 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 7501 /* 7502 * Commit the changes if any key has been marked as offline. 7503 */ 7504 if (zonediff.offline) { 7505 dns_db_closeversion(db, &version, true); 7506 } 7507 goto failure; 7508 } 7509 7510 /* Increment SOA serial if we have made changes */ 7511 result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx, 7512 zone->updatemethod); 7513 if (result != ISC_R_SUCCESS) { 7514 dns_zone_log(zone, ISC_LOG_ERROR, 7515 "zone_resigninc:update_soa_serial -> %s", 7516 dns_result_totext(result)); 7517 goto failure; 7518 } 7519 7520 /* 7521 * Generate maximum life time signatures so that the above loop 7522 * termination is sensible. 7523 */ 7524 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa, 7525 zonediff.diff, zone_keys, nkeys, zone->mctx, 7526 inception, soaexpire, check_ksk, keyset_kskonly); 7527 if (result != ISC_R_SUCCESS) { 7528 dns_zone_log(zone, ISC_LOG_ERROR, 7529 "zone_resigninc:add_sigs -> %s", 7530 dns_result_totext(result)); 7531 goto failure; 7532 } 7533 7534 /* Write changes to journal file. */ 7535 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc")); 7536 7537 /* Everything has succeeded. Commit the changes. */ 7538 dns_db_closeversion(db, &version, true); 7539 7540failure: 7541 dns_diff_clear(&_sig_diff); 7542 for (i = 0; i < nkeys; i++) { 7543 dst_key_free(&zone_keys[i]); 7544 } 7545 if (version != NULL) { 7546 dns_db_closeversion(db, &version, false); 7547 dns_db_detach(&db); 7548 } else if (db != NULL) { 7549 dns_db_detach(&db); 7550 } 7551 7552 LOCK_ZONE(zone); 7553 if (result == ISC_R_SUCCESS) { 7554 set_resigntime(zone); 7555 zone_needdump(zone, DNS_DUMP_DELAY); 7556 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 7557 } else { 7558 /* 7559 * Something failed. Retry in 5 minutes. 7560 */ 7561 isc_interval_t ival; 7562 isc_interval_set(&ival, 300, 0); 7563 isc_time_nowplusinterval(&zone->resigntime, &ival); 7564 } 7565 UNLOCK_ZONE(zone); 7566 7567 INSIST(version == NULL); 7568} 7569 7570static isc_result_t 7571next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname, 7572 dns_name_t *newname, bool bottom) { 7573 isc_result_t result; 7574 dns_dbiterator_t *dbit = NULL; 7575 dns_rdatasetiter_t *rdsit = NULL; 7576 dns_dbnode_t *node = NULL; 7577 7578 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit)); 7579 CHECK(dns_dbiterator_seek(dbit, oldname)); 7580 do { 7581 result = dns_dbiterator_next(dbit); 7582 if (result == ISC_R_NOMORE) { 7583 CHECK(dns_dbiterator_first(dbit)); 7584 } 7585 CHECK(dns_dbiterator_current(dbit, &node, newname)); 7586 if (bottom && dns_name_issubdomain(newname, oldname) && 7587 !dns_name_equal(newname, oldname)) 7588 { 7589 dns_db_detachnode(db, &node); 7590 continue; 7591 } 7592 /* 7593 * Is this node empty? 7594 */ 7595 CHECK(dns_db_allrdatasets(db, node, version, 0, 0, &rdsit)); 7596 result = dns_rdatasetiter_first(rdsit); 7597 dns_db_detachnode(db, &node); 7598 dns_rdatasetiter_destroy(&rdsit); 7599 if (result != ISC_R_NOMORE) { 7600 break; 7601 } 7602 } while (1); 7603failure: 7604 if (node != NULL) { 7605 dns_db_detachnode(db, &node); 7606 } 7607 if (dbit != NULL) { 7608 dns_dbiterator_destroy(&dbit); 7609 } 7610 return (result); 7611} 7612 7613static bool 7614signed_with_good_key(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, 7615 dns_dbversion_t *version, dns_rdatatype_t type, 7616 dst_key_t *key) { 7617 isc_result_t result; 7618 dns_rdataset_t rdataset; 7619 dns_rdata_t rdata = DNS_RDATA_INIT; 7620 dns_rdata_rrsig_t rrsig; 7621 int count = 0; 7622 dns_kasp_t *kasp = dns_zone_getkasp(zone); 7623 7624 dns_rdataset_init(&rdataset); 7625 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig, 7626 type, 0, &rdataset, NULL); 7627 if (result != ISC_R_SUCCESS) { 7628 INSIST(!dns_rdataset_isassociated(&rdataset)); 7629 return (false); 7630 } 7631 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 7632 result = dns_rdataset_next(&rdataset)) 7633 { 7634 dns_rdataset_current(&rdataset, &rdata); 7635 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 7636 INSIST(result == ISC_R_SUCCESS); 7637 if (rrsig.algorithm == dst_key_alg(key) && 7638 rrsig.keyid == dst_key_id(key)) 7639 { 7640 dns_rdataset_disassociate(&rdataset); 7641 return (true); 7642 } 7643 if (rrsig.algorithm == dst_key_alg(key)) { 7644 count++; 7645 } 7646 dns_rdata_reset(&rdata); 7647 } 7648 7649 if (dns_zone_getkasp(zone) != NULL) { 7650 dns_kasp_key_t *kkey; 7651 int zsk_count = 0; 7652 bool approved; 7653 7654 KASP_LOCK(kasp); 7655 for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL; 7656 kkey = ISC_LIST_NEXT(kkey, link)) 7657 { 7658 if (dns_kasp_key_algorithm(kkey) != dst_key_alg(key)) { 7659 continue; 7660 } 7661 if (dns_kasp_key_zsk(kkey)) { 7662 zsk_count++; 7663 } 7664 } 7665 KASP_UNLOCK(kasp); 7666 7667 if (type == dns_rdatatype_dnskey || 7668 type == dns_rdatatype_cdnskey || type == dns_rdatatype_cds) 7669 { 7670 /* 7671 * CDS and CDNSKEY are signed with KSK like DNSKEY. 7672 * (RFC 7344, section 4.1 specifies that they must 7673 * be signed with a key in the current DS RRset, 7674 * which would only include KSK's.) 7675 */ 7676 approved = false; 7677 } else { 7678 approved = (zsk_count == count); 7679 } 7680 7681 dns_rdataset_disassociate(&rdataset); 7682 return (approved); 7683 } 7684 7685 dns_rdataset_disassociate(&rdataset); 7686 return (false); 7687} 7688 7689static isc_result_t 7690add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 7691 dns_dbnode_t *node, dns_ttl_t ttl, bool bottom, dns_diff_t *diff) { 7692 dns_fixedname_t fixed; 7693 dns_name_t *next; 7694 dns_rdata_t rdata = DNS_RDATA_INIT; 7695 isc_result_t result; 7696 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE]; 7697 7698 next = dns_fixedname_initname(&fixed); 7699 7700 CHECK(next_active(db, version, name, next, bottom)); 7701 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer, &rdata)); 7702 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl, 7703 &rdata)); 7704failure: 7705 return (result); 7706} 7707 7708static isc_result_t 7709check_if_bottom_of_zone(dns_db_t *db, dns_dbnode_t *node, 7710 dns_dbversion_t *version, bool *is_bottom_of_zone) { 7711 isc_result_t result; 7712 dns_rdatasetiter_t *iterator = NULL; 7713 dns_rdataset_t rdataset; 7714 bool seen_soa = false, seen_ns = false, seen_dname = false; 7715 7716 REQUIRE(is_bottom_of_zone != NULL); 7717 7718 result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator); 7719 if (result != ISC_R_SUCCESS) { 7720 if (result == ISC_R_NOTFOUND) { 7721 result = ISC_R_SUCCESS; 7722 } 7723 return (result); 7724 } 7725 7726 dns_rdataset_init(&rdataset); 7727 for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; 7728 result = dns_rdatasetiter_next(iterator)) 7729 { 7730 dns_rdatasetiter_current(iterator, &rdataset); 7731 switch (rdataset.type) { 7732 case dns_rdatatype_soa: 7733 seen_soa = true; 7734 break; 7735 case dns_rdatatype_ns: 7736 seen_ns = true; 7737 break; 7738 case dns_rdatatype_dname: 7739 seen_dname = true; 7740 break; 7741 } 7742 dns_rdataset_disassociate(&rdataset); 7743 } 7744 if (result != ISC_R_NOMORE) { 7745 goto failure; 7746 } 7747 if ((seen_ns && !seen_soa) || seen_dname) { 7748 *is_bottom_of_zone = true; 7749 } 7750 result = ISC_R_SUCCESS; 7751 7752failure: 7753 dns_rdatasetiter_destroy(&iterator); 7754 7755 return (result); 7756} 7757 7758static isc_result_t 7759sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name, 7760 dns_dbnode_t *node, dns_dbversion_t *version, bool build_nsec3, 7761 bool build_nsec, dst_key_t *key, isc_stdtime_t inception, 7762 isc_stdtime_t expire, dns_ttl_t nsecttl, bool is_ksk, bool is_zsk, 7763 bool keyset_kskonly, bool is_bottom_of_zone, dns_diff_t *diff, 7764 int32_t *signatures, isc_mem_t *mctx) { 7765 isc_result_t result; 7766 dns_rdatasetiter_t *iterator = NULL; 7767 dns_rdataset_t rdataset; 7768 dns_rdata_t rdata = DNS_RDATA_INIT; 7769 dns_stats_t *dnssecsignstats; 7770 7771 isc_buffer_t buffer; 7772 unsigned char data[1024]; 7773 bool seen_soa, seen_ns, seen_rr, seen_nsec, seen_nsec3, seen_ds; 7774 7775 result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator); 7776 if (result != ISC_R_SUCCESS) { 7777 if (result == ISC_R_NOTFOUND) { 7778 result = ISC_R_SUCCESS; 7779 } 7780 return (result); 7781 } 7782 7783 dns_rdataset_init(&rdataset); 7784 isc_buffer_init(&buffer, data, sizeof(data)); 7785 seen_rr = seen_soa = seen_ns = seen_nsec = seen_nsec3 = seen_ds = false; 7786 for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; 7787 result = dns_rdatasetiter_next(iterator)) 7788 { 7789 dns_rdatasetiter_current(iterator, &rdataset); 7790 if (rdataset.type == dns_rdatatype_soa) { 7791 seen_soa = true; 7792 } else if (rdataset.type == dns_rdatatype_ns) { 7793 seen_ns = true; 7794 } else if (rdataset.type == dns_rdatatype_ds) { 7795 seen_ds = true; 7796 } else if (rdataset.type == dns_rdatatype_nsec) { 7797 seen_nsec = true; 7798 } else if (rdataset.type == dns_rdatatype_nsec3) { 7799 seen_nsec3 = true; 7800 } 7801 if (rdataset.type != dns_rdatatype_rrsig) { 7802 seen_rr = true; 7803 } 7804 dns_rdataset_disassociate(&rdataset); 7805 } 7806 if (result != ISC_R_NOMORE) { 7807 goto failure; 7808 } 7809 /* 7810 * Going from insecure to NSEC3. 7811 * Don't generate NSEC3 records for NSEC3 records. 7812 */ 7813 if (build_nsec3 && !seen_nsec3 && seen_rr) { 7814 bool unsecure = !seen_ds && seen_ns && !seen_soa; 7815 CHECK(dns_nsec3_addnsec3s(db, version, name, nsecttl, unsecure, 7816 diff)); 7817 (*signatures)--; 7818 } 7819 /* 7820 * Going from insecure to NSEC. 7821 * Don't generate NSEC records for NSEC3 records. 7822 */ 7823 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) { 7824 /* 7825 * Build a NSEC record except at the origin. 7826 */ 7827 if (!dns_name_equal(name, dns_db_origin(db))) { 7828 CHECK(add_nsec(db, version, name, node, nsecttl, 7829 is_bottom_of_zone, diff)); 7830 /* Count a NSEC generation as a signature generation. */ 7831 (*signatures)--; 7832 } 7833 } 7834 result = dns_rdatasetiter_first(iterator); 7835 while (result == ISC_R_SUCCESS) { 7836 isc_stdtime_t when; 7837 7838 dns_rdatasetiter_current(iterator, &rdataset); 7839 if (rdataset.type == dns_rdatatype_soa || 7840 rdataset.type == dns_rdatatype_rrsig) 7841 { 7842 goto next_rdataset; 7843 } 7844 if (rdataset.type == dns_rdatatype_dnskey || 7845 rdataset.type == dns_rdatatype_cdnskey || 7846 rdataset.type == dns_rdatatype_cds) 7847 { 7848 /* 7849 * CDS and CDNSKEY are signed with KSK like DNSKEY. 7850 * (RFC 7344, section 4.1 specifies that they must 7851 * be signed with a key in the current DS RRset, 7852 * which would only include KSK's.) 7853 */ 7854 if (!is_ksk && keyset_kskonly) { 7855 goto next_rdataset; 7856 } 7857 } else if (!is_zsk) { 7858 goto next_rdataset; 7859 } else if (is_zsk && !dst_key_is_signing(key, DST_BOOL_ZSK, 7860 inception, &when)) 7861 { 7862 /* Only applies to dnssec-policy. */ 7863 if (dns_zone_getkasp(zone) != NULL) { 7864 goto next_rdataset; 7865 } 7866 } 7867 7868 if (seen_ns && !seen_soa && rdataset.type != dns_rdatatype_ds && 7869 rdataset.type != dns_rdatatype_nsec) 7870 { 7871 goto next_rdataset; 7872 } 7873 if (signed_with_good_key(zone, db, node, version, rdataset.type, 7874 key)) 7875 { 7876 goto next_rdataset; 7877 } 7878 7879 /* Calculate the signature, creating a RRSIG RDATA. */ 7880 isc_buffer_clear(&buffer); 7881 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception, &expire, 7882 mctx, &buffer, &rdata)); 7883 /* Update the database and journal with the RRSIG. */ 7884 /* XXX inefficient - will cause dataset merging */ 7885 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN, 7886 name, rdataset.ttl, &rdata)); 7887 dns_rdata_reset(&rdata); 7888 7889 /* Update DNSSEC sign statistics. */ 7890 dnssecsignstats = dns_zone_getdnssecsignstats(zone); 7891 if (dnssecsignstats != NULL) { 7892 /* Generated a new signature. */ 7893 dns_dnssecsignstats_increment(dnssecsignstats, ID(key), 7894 ALG(key), 7895 dns_dnssecsignstats_sign); 7896 /* This is a refresh. */ 7897 dns_dnssecsignstats_increment( 7898 dnssecsignstats, ID(key), ALG(key), 7899 dns_dnssecsignstats_refresh); 7900 } 7901 7902 (*signatures)--; 7903 next_rdataset: 7904 dns_rdataset_disassociate(&rdataset); 7905 result = dns_rdatasetiter_next(iterator); 7906 } 7907 if (result == ISC_R_NOMORE) { 7908 result = ISC_R_SUCCESS; 7909 } 7910failure: 7911 if (dns_rdataset_isassociated(&rdataset)) { 7912 dns_rdataset_disassociate(&rdataset); 7913 } 7914 if (iterator != NULL) { 7915 dns_rdatasetiter_destroy(&iterator); 7916 } 7917 return (result); 7918} 7919 7920/* 7921 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist. 7922 */ 7923static isc_result_t 7924updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 7925 dns_ttl_t nsecttl, bool update_only, dns_diff_t *diff) { 7926 isc_result_t result; 7927 dns_rdataset_t rdataset; 7928 dns_dbnode_t *node = NULL; 7929 7930 CHECK(dns_db_getoriginnode(db, &node)); 7931 if (update_only) { 7932 dns_rdataset_init(&rdataset); 7933 result = dns_db_findrdataset( 7934 db, node, version, dns_rdatatype_nsec, 7935 dns_rdatatype_none, 0, &rdataset, NULL); 7936 if (dns_rdataset_isassociated(&rdataset)) { 7937 dns_rdataset_disassociate(&rdataset); 7938 } 7939 if (result == ISC_R_NOTFOUND) { 7940 goto success; 7941 } 7942 if (result != ISC_R_SUCCESS) { 7943 goto failure; 7944 } 7945 } 7946 CHECK(delete_nsec(db, version, node, name, diff)); 7947 CHECK(add_nsec(db, version, name, node, nsecttl, false, diff)); 7948success: 7949 result = ISC_R_SUCCESS; 7950failure: 7951 if (node != NULL) { 7952 dns_db_detachnode(db, &node); 7953 } 7954 return (result); 7955} 7956 7957static isc_result_t 7958updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing, 7959 dns_dbversion_t *version, bool build_nsec3, dns_ttl_t nsecttl, 7960 dns_diff_t *diff) { 7961 isc_result_t result; 7962 dns_dbnode_t *node = NULL; 7963 dns_rdataset_t rdataset; 7964 dns_rdata_t rdata = DNS_RDATA_INIT; 7965 unsigned char data[5]; 7966 bool seen_done = false; 7967 bool have_rr = false; 7968 7969 dns_rdataset_init(&rdataset); 7970 result = dns_db_getoriginnode(signing->db, &node); 7971 if (result != ISC_R_SUCCESS) { 7972 goto failure; 7973 } 7974 7975 result = dns_db_findrdataset(signing->db, node, version, 7976 zone->privatetype, dns_rdatatype_none, 0, 7977 &rdataset, NULL); 7978 if (result == ISC_R_NOTFOUND) { 7979 INSIST(!dns_rdataset_isassociated(&rdataset)); 7980 result = ISC_R_SUCCESS; 7981 goto failure; 7982 } 7983 if (result != ISC_R_SUCCESS) { 7984 INSIST(!dns_rdataset_isassociated(&rdataset)); 7985 goto failure; 7986 } 7987 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 7988 result = dns_rdataset_next(&rdataset)) 7989 { 7990 dns_rdataset_current(&rdataset, &rdata); 7991 /* 7992 * If we don't match the algorithm or keyid skip the record. 7993 */ 7994 if (rdata.length != 5 || rdata.data[0] != signing->algorithm || 7995 rdata.data[1] != ((signing->keyid >> 8) & 0xff) || 7996 rdata.data[2] != (signing->keyid & 0xff)) 7997 { 7998 have_rr = true; 7999 dns_rdata_reset(&rdata); 8000 continue; 8001 } 8002 /* 8003 * We have a match. If we were signing (!signing->deleteit) 8004 * and we already have a record indicating that we have 8005 * finished signing (rdata.data[4] != 0) then keep it. 8006 * Otherwise it needs to be deleted as we have removed all 8007 * the signatures (signing->deleteit), so any record indicating 8008 * completion is now out of date, or we have finished signing 8009 * with the new record so we no longer need to remember that 8010 * we need to sign the zone with the matching key across a 8011 * nameserver re-start. 8012 */ 8013 if (!signing->deleteit && rdata.data[4] != 0) { 8014 seen_done = true; 8015 have_rr = true; 8016 } else { 8017 CHECK(update_one_rr(signing->db, version, diff, 8018 DNS_DIFFOP_DEL, &zone->origin, 8019 rdataset.ttl, &rdata)); 8020 } 8021 dns_rdata_reset(&rdata); 8022 } 8023 if (result == ISC_R_NOMORE) { 8024 result = ISC_R_SUCCESS; 8025 } 8026 if (!signing->deleteit && !seen_done) { 8027 /* 8028 * If we were signing then we need to indicate that we have 8029 * finished signing the zone with this key. If it is already 8030 * there we don't need to add it a second time. 8031 */ 8032 data[0] = signing->algorithm; 8033 data[1] = (signing->keyid >> 8) & 0xff; 8034 data[2] = signing->keyid & 0xff; 8035 data[3] = 0; 8036 data[4] = 1; 8037 rdata.length = sizeof(data); 8038 rdata.data = data; 8039 rdata.type = zone->privatetype; 8040 rdata.rdclass = dns_db_class(signing->db); 8041 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD, 8042 &zone->origin, rdataset.ttl, &rdata)); 8043 } else if (!have_rr) { 8044 dns_name_t *origin = dns_db_origin(signing->db); 8045 /* 8046 * Rebuild the NSEC/NSEC3 record for the origin as we no 8047 * longer have any private records. 8048 */ 8049 if (build_nsec3) { 8050 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin, 8051 nsecttl, false, diff)); 8052 } 8053 CHECK(updatesecure(signing->db, version, origin, nsecttl, true, 8054 diff)); 8055 } 8056 8057failure: 8058 if (dns_rdataset_isassociated(&rdataset)) { 8059 dns_rdataset_disassociate(&rdataset); 8060 } 8061 if (node != NULL) { 8062 dns_db_detachnode(signing->db, &node); 8063 } 8064 return (result); 8065} 8066 8067/* 8068 * Called from zone_nsec3chain() in order to update zone records indicating 8069 * processing status of given NSEC3 chain: 8070 * 8071 * - If the supplied dns_nsec3chain_t structure has been fully processed 8072 * (which is indicated by "active" being set to false): 8073 * 8074 * - remove all NSEC3PARAM records matching the relevant NSEC3 chain, 8075 * 8076 * - remove all private-type records containing NSEC3PARAM RDATA matching 8077 * the relevant NSEC3 chain. 8078 * 8079 * - If the supplied dns_nsec3chain_t structure has not been fully processed 8080 * (which is indicated by "active" being set to true), only remove the 8081 * NSEC3PARAM record which matches the relevant NSEC3 chain and has the 8082 * "flags" field set to 0. 8083 * 8084 * - If given NSEC3 chain is being added, add an NSEC3PARAM record contained 8085 * in the relevant private-type record, but with the "flags" field set to 8086 * 0, indicating that this NSEC3 chain is now complete for this zone. 8087 * 8088 * Note that this function is called at different processing stages for NSEC3 8089 * chain additions vs. removals and needs to handle all cases properly. 8090 */ 8091static isc_result_t 8092fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain, 8093 bool active, dns_rdatatype_t privatetype, dns_diff_t *diff) { 8094 dns_dbnode_t *node = NULL; 8095 dns_name_t *name = dns_db_origin(db); 8096 dns_rdata_t rdata = DNS_RDATA_INIT; 8097 dns_rdataset_t rdataset; 8098 dns_rdata_nsec3param_t nsec3param; 8099 isc_result_t result; 8100 isc_buffer_t buffer; 8101 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE]; 8102 dns_ttl_t ttl = 0; 8103 bool nseconly = false, nsec3ok = false; 8104 8105 dns_rdataset_init(&rdataset); 8106 8107 result = dns_db_getoriginnode(db, &node); 8108 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8109 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0, 8110 0, &rdataset, NULL); 8111 if (result == ISC_R_NOTFOUND) { 8112 goto try_private; 8113 } 8114 if (result != ISC_R_SUCCESS) { 8115 goto failure; 8116 } 8117 8118 /* 8119 * Preserve the existing ttl. 8120 */ 8121 ttl = rdataset.ttl; 8122 8123 /* 8124 * Delete all NSEC3PARAM records which match that in nsec3chain. 8125 */ 8126 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8127 result = dns_rdataset_next(&rdataset)) 8128 { 8129 dns_rdataset_current(&rdataset, &rdata); 8130 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 8131 8132 if (nsec3param.hash != chain->nsec3param.hash || 8133 (active && nsec3param.flags != 0) || 8134 nsec3param.iterations != chain->nsec3param.iterations || 8135 nsec3param.salt_length != chain->nsec3param.salt_length || 8136 memcmp(nsec3param.salt, chain->nsec3param.salt, 8137 nsec3param.salt_length)) 8138 { 8139 dns_rdata_reset(&rdata); 8140 continue; 8141 } 8142 8143 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8144 rdataset.ttl, &rdata)); 8145 dns_rdata_reset(&rdata); 8146 } 8147 if (result != ISC_R_NOMORE) { 8148 goto failure; 8149 } 8150 8151 dns_rdataset_disassociate(&rdataset); 8152 8153try_private: 8154 8155 if (active) { 8156 goto add; 8157 } 8158 8159 result = dns_nsec_nseconly(db, ver, &nseconly); 8160 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 8161 8162 /* 8163 * Delete all private records which match that in nsec3chain. 8164 */ 8165 result = dns_db_findrdataset(db, node, ver, privatetype, 0, 0, 8166 &rdataset, NULL); 8167 if (result == ISC_R_NOTFOUND) { 8168 goto add; 8169 } 8170 if (result != ISC_R_SUCCESS) { 8171 goto failure; 8172 } 8173 8174 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8175 result = dns_rdataset_next(&rdataset)) 8176 { 8177 dns_rdata_t private = DNS_RDATA_INIT; 8178 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 8179 8180 dns_rdataset_current(&rdataset, &private); 8181 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 8182 sizeof(buf))) 8183 { 8184 continue; 8185 } 8186 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 8187 8188 if ((!nsec3ok && 8189 (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) || 8190 nsec3param.hash != chain->nsec3param.hash || 8191 nsec3param.iterations != chain->nsec3param.iterations || 8192 nsec3param.salt_length != chain->nsec3param.salt_length || 8193 memcmp(nsec3param.salt, chain->nsec3param.salt, 8194 nsec3param.salt_length)) 8195 { 8196 dns_rdata_reset(&rdata); 8197 continue; 8198 } 8199 8200 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8201 rdataset.ttl, &private)); 8202 dns_rdata_reset(&rdata); 8203 } 8204 if (result != ISC_R_NOMORE) { 8205 goto failure; 8206 } 8207 8208add: 8209 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) { 8210 result = ISC_R_SUCCESS; 8211 goto failure; 8212 } 8213 8214 /* 8215 * Add a NSEC3PARAM record which matches that in nsec3chain but 8216 * with all flags bits cleared. 8217 * 8218 * Note: we do not clear chain->nsec3param.flags as this change 8219 * may be reversed. 8220 */ 8221 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf)); 8222 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), 8223 dns_rdatatype_nsec3param, &chain->nsec3param, 8224 &buffer)); 8225 rdata.data[1] = 0; /* Clear flag bits. */ 8226 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata)); 8227 8228failure: 8229 dns_db_detachnode(db, &node); 8230 if (dns_rdataset_isassociated(&rdataset)) { 8231 dns_rdataset_disassociate(&rdataset); 8232 } 8233 return (result); 8234} 8235 8236static isc_result_t 8237delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 8238 dns_name_t *name, dns_diff_t *diff) { 8239 dns_rdataset_t rdataset; 8240 isc_result_t result; 8241 8242 dns_rdataset_init(&rdataset); 8243 8244 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0, 8245 &rdataset, NULL); 8246 if (result == ISC_R_NOTFOUND) { 8247 return (ISC_R_SUCCESS); 8248 } 8249 if (result != ISC_R_SUCCESS) { 8250 return (result); 8251 } 8252 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8253 result = dns_rdataset_next(&rdataset)) 8254 { 8255 dns_rdata_t rdata = DNS_RDATA_INIT; 8256 8257 dns_rdataset_current(&rdataset, &rdata); 8258 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8259 rdataset.ttl, &rdata)); 8260 } 8261 if (result == ISC_R_NOMORE) { 8262 result = ISC_R_SUCCESS; 8263 } 8264failure: 8265 dns_rdataset_disassociate(&rdataset); 8266 return (result); 8267} 8268 8269static isc_result_t 8270deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 8271 dns_name_t *name, const dns_rdata_nsec3param_t *param, 8272 dns_diff_t *diff) { 8273 dns_rdataset_t rdataset; 8274 dns_rdata_nsec3_t nsec3; 8275 isc_result_t result; 8276 8277 dns_rdataset_init(&rdataset); 8278 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 0, 0, 8279 &rdataset, NULL); 8280 if (result == ISC_R_NOTFOUND) { 8281 return (ISC_R_SUCCESS); 8282 } 8283 if (result != ISC_R_SUCCESS) { 8284 return (result); 8285 } 8286 8287 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8288 result = dns_rdataset_next(&rdataset)) 8289 { 8290 dns_rdata_t rdata = DNS_RDATA_INIT; 8291 8292 dns_rdataset_current(&rdataset, &rdata); 8293 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL)); 8294 if (nsec3.hash != param->hash || 8295 nsec3.iterations != param->iterations || 8296 nsec3.salt_length != param->salt_length || 8297 memcmp(nsec3.salt, param->salt, nsec3.salt_length)) 8298 { 8299 continue; 8300 } 8301 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8302 rdataset.ttl, &rdata)); 8303 } 8304 if (result == ISC_R_NOMORE) { 8305 result = ISC_R_SUCCESS; 8306 } 8307failure: 8308 dns_rdataset_disassociate(&rdataset); 8309 return (result); 8310} 8311 8312static isc_result_t 8313need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver, 8314 const dns_rdata_nsec3param_t *param, bool *answer) { 8315 dns_dbnode_t *node = NULL; 8316 dns_rdata_t rdata = DNS_RDATA_INIT; 8317 dns_rdata_nsec3param_t myparam; 8318 dns_rdataset_t rdataset; 8319 isc_result_t result; 8320 8321 *answer = false; 8322 8323 result = dns_db_getoriginnode(db, &node); 8324 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8325 8326 dns_rdataset_init(&rdataset); 8327 8328 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0, 8329 &rdataset, NULL); 8330 if (result == ISC_R_SUCCESS) { 8331 dns_rdataset_disassociate(&rdataset); 8332 dns_db_detachnode(db, &node); 8333 return (result); 8334 } 8335 if (result != ISC_R_NOTFOUND) { 8336 dns_db_detachnode(db, &node); 8337 return (result); 8338 } 8339 8340 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0, 8341 0, &rdataset, NULL); 8342 if (result == ISC_R_NOTFOUND) { 8343 *answer = true; 8344 dns_db_detachnode(db, &node); 8345 return (ISC_R_SUCCESS); 8346 } 8347 if (result != ISC_R_SUCCESS) { 8348 dns_db_detachnode(db, &node); 8349 return (result); 8350 } 8351 8352 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8353 result = dns_rdataset_next(&rdataset)) 8354 { 8355 dns_rdataset_current(&rdataset, &rdata); 8356 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL)); 8357 dns_rdata_reset(&rdata); 8358 /* 8359 * Ignore any NSEC3PARAM removals. 8360 */ 8361 if (NSEC3REMOVE(myparam.flags)) { 8362 continue; 8363 } 8364 /* 8365 * Ignore the chain that we are in the process of deleting. 8366 */ 8367 if (myparam.hash == param->hash && 8368 myparam.iterations == param->iterations && 8369 myparam.salt_length == param->salt_length && 8370 !memcmp(myparam.salt, param->salt, myparam.salt_length)) 8371 { 8372 continue; 8373 } 8374 /* 8375 * Found an active NSEC3 chain. 8376 */ 8377 break; 8378 } 8379 if (result == ISC_R_NOMORE) { 8380 *answer = true; 8381 result = ISC_R_SUCCESS; 8382 } 8383 8384failure: 8385 if (dns_rdataset_isassociated(&rdataset)) { 8386 dns_rdataset_disassociate(&rdataset); 8387 } 8388 dns_db_detachnode(db, &node); 8389 return (result); 8390} 8391 8392/*% 8393 * Given a tuple which is part of a diff, return a pointer to the next tuple in 8394 * that diff which has the same name and type (or NULL if no such tuple is 8395 * found). 8396 */ 8397static dns_difftuple_t * 8398find_next_matching_tuple(dns_difftuple_t *cur) { 8399 dns_difftuple_t *next = cur; 8400 8401 while ((next = ISC_LIST_NEXT(next, link)) != NULL) { 8402 if (cur->rdata.type == next->rdata.type && 8403 dns_name_equal(&cur->name, &next->name)) 8404 { 8405 return (next); 8406 } 8407 } 8408 8409 return (NULL); 8410} 8411 8412/*% 8413 * Remove all tuples with the same name and type as 'cur' from 'src' and append 8414 * them to 'dst'. 8415 */ 8416static void 8417move_matching_tuples(dns_difftuple_t *cur, dns_diff_t *src, dns_diff_t *dst) { 8418 do { 8419 dns_difftuple_t *next = find_next_matching_tuple(cur); 8420 ISC_LIST_UNLINK(src->tuples, cur, link); 8421 dns_diff_appendminimal(dst, &cur); 8422 cur = next; 8423 } while (cur != NULL); 8424} 8425 8426/*% 8427 * Add/remove DNSSEC signatures for the list of "raw" zone changes supplied in 8428 * 'diff'. Gradually remove tuples from 'diff' and append them to 'zonediff' 8429 * along with tuples representing relevant signature changes. 8430 */ 8431isc_result_t 8432dns__zone_updatesigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, 8433 dst_key_t *zone_keys[], unsigned int nkeys, 8434 dns_zone_t *zone, isc_stdtime_t inception, 8435 isc_stdtime_t expire, isc_stdtime_t keyexpire, 8436 isc_stdtime_t now, bool check_ksk, bool keyset_kskonly, 8437 dns__zonediff_t *zonediff) { 8438 dns_difftuple_t *tuple; 8439 isc_result_t result; 8440 8441 while ((tuple = ISC_LIST_HEAD(diff->tuples)) != NULL) { 8442 isc_stdtime_t exp = expire; 8443 8444 if (keyexpire != 0 && 8445 (tuple->rdata.type == dns_rdatatype_dnskey || 8446 tuple->rdata.type == dns_rdatatype_cdnskey || 8447 tuple->rdata.type == dns_rdatatype_cds)) 8448 { 8449 exp = keyexpire; 8450 } 8451 8452 result = del_sigs(zone, db, version, &tuple->name, 8453 tuple->rdata.type, zonediff, zone_keys, nkeys, 8454 now, false); 8455 if (result != ISC_R_SUCCESS) { 8456 dns_zone_log(zone, ISC_LOG_ERROR, 8457 "dns__zone_updatesigs:del_sigs -> %s", 8458 dns_result_totext(result)); 8459 return (result); 8460 } 8461 result = add_sigs(db, version, &tuple->name, zone, 8462 tuple->rdata.type, zonediff->diff, zone_keys, 8463 nkeys, zone->mctx, inception, exp, check_ksk, 8464 keyset_kskonly); 8465 if (result != ISC_R_SUCCESS) { 8466 dns_zone_log(zone, ISC_LOG_ERROR, 8467 "dns__zone_updatesigs:add_sigs -> %s", 8468 dns_result_totext(result)); 8469 return (result); 8470 } 8471 8472 /* 8473 * Signature changes for all RRs with name tuple->name and type 8474 * tuple->rdata.type were appended to zonediff->diff. Now we 8475 * remove all the "raw" changes with the same name and type 8476 * from diff (so that they are not processed by this loop 8477 * again) and append them to zonediff so that they get applied. 8478 */ 8479 move_matching_tuples(tuple, diff, zonediff->diff); 8480 } 8481 return (ISC_R_SUCCESS); 8482} 8483 8484/* 8485 * Incrementally build and sign a new NSEC3 chain using the parameters 8486 * requested. 8487 */ 8488static void 8489zone_nsec3chain(dns_zone_t *zone) { 8490 const char *me = "zone_nsec3chain"; 8491 dns_db_t *db = NULL; 8492 dns_dbnode_t *node = NULL; 8493 dns_dbversion_t *version = NULL; 8494 dns_diff_t _sig_diff; 8495 dns_diff_t nsec_diff; 8496 dns_diff_t nsec3_diff; 8497 dns_diff_t param_diff; 8498 dns__zonediff_t zonediff; 8499 dns_fixedname_t fixed; 8500 dns_fixedname_t nextfixed; 8501 dns_name_t *name, *nextname; 8502 dns_rdataset_t rdataset; 8503 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain; 8504 dns_nsec3chainlist_t cleanup; 8505 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 8506 int32_t signatures; 8507 bool check_ksk, keyset_kskonly; 8508 bool delegation; 8509 bool first; 8510 isc_result_t result; 8511 isc_stdtime_t now, inception, soaexpire, expire; 8512 uint32_t jitter, sigvalidityinterval, expiryinterval; 8513 unsigned int i; 8514 unsigned int nkeys = 0; 8515 uint32_t nodes; 8516 bool unsecure = false; 8517 bool seen_soa, seen_ns, seen_dname, seen_ds; 8518 bool seen_nsec, seen_nsec3, seen_rr; 8519 dns_rdatasetiter_t *iterator = NULL; 8520 bool buildnsecchain; 8521 bool updatensec = false; 8522 dns_rdatatype_t privatetype = zone->privatetype; 8523 8524 ENTER; 8525 8526 dns_rdataset_init(&rdataset); 8527 name = dns_fixedname_initname(&fixed); 8528 nextname = dns_fixedname_initname(&nextfixed); 8529 dns_diff_init(zone->mctx, ¶m_diff); 8530 dns_diff_init(zone->mctx, &nsec3_diff); 8531 dns_diff_init(zone->mctx, &nsec_diff); 8532 dns_diff_init(zone->mctx, &_sig_diff); 8533 zonediff_init(&zonediff, &_sig_diff); 8534 ISC_LIST_INIT(cleanup); 8535 8536 /* 8537 * Updates are disabled. Pause for 5 minutes. 8538 */ 8539 if (zone->update_disabled) { 8540 result = ISC_R_FAILURE; 8541 goto failure; 8542 } 8543 8544 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8545 /* 8546 * This function is called when zone timer fires, after the latter gets 8547 * set by zone_addnsec3chain(). If the action triggering the call to 8548 * zone_addnsec3chain() is closely followed by a zone deletion request, 8549 * it might turn out that the timer thread will not be woken up until 8550 * after the zone is deleted by rmzone(), which calls dns_db_detach() 8551 * for zone->db, causing the latter to become NULL. Return immediately 8552 * if that happens. 8553 */ 8554 if (zone->db != NULL) { 8555 dns_db_attach(zone->db, &db); 8556 } 8557 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8558 if (db == NULL) { 8559 return; 8560 } 8561 8562 result = dns_db_newversion(db, &version); 8563 if (result != ISC_R_SUCCESS) { 8564 dnssec_log(zone, ISC_LOG_ERROR, 8565 "zone_nsec3chain:dns_db_newversion -> %s", 8566 dns_result_totext(result)); 8567 goto failure; 8568 } 8569 8570 isc_stdtime_get(&now); 8571 8572 result = dns__zone_findkeys(zone, db, version, now, zone->mctx, 8573 DNS_MAXZONEKEYS, zone_keys, &nkeys); 8574 if (result != ISC_R_SUCCESS) { 8575 dnssec_log(zone, ISC_LOG_ERROR, 8576 "zone_nsec3chain:dns__zone_findkeys -> %s", 8577 dns_result_totext(result)); 8578 goto failure; 8579 } 8580 8581 sigvalidityinterval = dns_zone_getsigvalidityinterval(zone); 8582 inception = now - 3600; /* Allow for clock skew. */ 8583 soaexpire = now + sigvalidityinterval; 8584 expiryinterval = dns_zone_getsigresigninginterval(zone); 8585 if (expiryinterval > sigvalidityinterval) { 8586 expiryinterval = sigvalidityinterval; 8587 } else { 8588 expiryinterval = sigvalidityinterval - expiryinterval; 8589 } 8590 8591 /* 8592 * Spread out signatures over time if they happen to be 8593 * clumped. We don't do this for each add_sigs() call as 8594 * we still want some clustering to occur. 8595 */ 8596 if (sigvalidityinterval >= 3600U) { 8597 if (sigvalidityinterval > 7200U) { 8598 jitter = isc_random_uniform(expiryinterval); 8599 } else { 8600 jitter = isc_random_uniform(1200); 8601 } 8602 expire = soaexpire - jitter - 1; 8603 } else { 8604 expire = soaexpire - 1; 8605 } 8606 8607 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 8608 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 8609 8610 /* 8611 * We keep pulling nodes off each iterator in turn until 8612 * we have no more nodes to pull off or we reach the limits 8613 * for this quantum. 8614 */ 8615 nodes = zone->nodes; 8616 signatures = zone->signatures; 8617 LOCK_ZONE(zone); 8618 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 8619 UNLOCK_ZONE(zone); 8620 first = true; 8621 8622 if (nsec3chain != NULL) { 8623 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 8624 } 8625 /* 8626 * Generate new NSEC3 chains first. 8627 * 8628 * The following while loop iterates over nodes in the zone database, 8629 * updating the NSEC3 chain by calling dns_nsec3_addnsec3() for each of 8630 * them. Once all nodes are processed, the "delete_nsec" field is 8631 * consulted to check whether we are supposed to remove NSEC records 8632 * from the zone database; if so, the database iterator is reset to 8633 * point to the first node and the loop traverses all of them again, 8634 * this time removing NSEC records. If we hit a node which is obscured 8635 * by a delegation or a DNAME, nodes are skipped over until we find one 8636 * that is not obscured by the same obscuring name and then normal 8637 * processing is resumed. 8638 * 8639 * The above is repeated until all requested NSEC3 chain changes are 8640 * applied or when we reach the limits for this quantum, whichever 8641 * happens first. 8642 * 8643 * Note that the "signatures" variable is only used here to limit the 8644 * amount of work performed. Actual DNSSEC signatures are only 8645 * generated by dns__zone_updatesigs() calls later in this function. 8646 */ 8647 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 8648 dns_dbiterator_pause(nsec3chain->dbiterator); 8649 8650 LOCK_ZONE(zone); 8651 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 8652 8653 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8654 if (nsec3chain->done || nsec3chain->db != zone->db) { 8655 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 8656 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8657 } 8658 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8659 UNLOCK_ZONE(zone); 8660 if (ISC_LIST_TAIL(cleanup) == nsec3chain) { 8661 goto next_addchain; 8662 } 8663 8664 /* 8665 * Possible future db. 8666 */ 8667 if (nsec3chain->db != db) { 8668 goto next_addchain; 8669 } 8670 8671 if (NSEC3REMOVE(nsec3chain->nsec3param.flags)) { 8672 goto next_addchain; 8673 } 8674 8675 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 8676 8677 if (nsec3chain->delete_nsec) { 8678 delegation = false; 8679 dns_dbiterator_pause(nsec3chain->dbiterator); 8680 CHECK(delete_nsec(db, version, node, name, &nsec_diff)); 8681 goto next_addnode; 8682 } 8683 /* 8684 * On the first pass we need to check if the current node 8685 * has not been obscured. 8686 */ 8687 delegation = false; 8688 unsecure = false; 8689 if (first) { 8690 dns_fixedname_t ffound; 8691 dns_name_t *found; 8692 found = dns_fixedname_initname(&ffound); 8693 result = dns_db_find( 8694 db, name, version, dns_rdatatype_soa, 8695 DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); 8696 if ((result == DNS_R_DELEGATION || 8697 result == DNS_R_DNAME) && 8698 !dns_name_equal(name, found)) 8699 { 8700 /* 8701 * Remember the obscuring name so that 8702 * we skip all obscured names. 8703 */ 8704 dns_name_copynf(found, name); 8705 delegation = true; 8706 goto next_addnode; 8707 } 8708 } 8709 8710 /* 8711 * Check to see if this is a bottom of zone node. 8712 */ 8713 result = dns_db_allrdatasets(db, node, version, 0, 0, 8714 &iterator); 8715 if (result == ISC_R_NOTFOUND) { 8716 /* Empty node? */ 8717 goto next_addnode; 8718 } 8719 if (result != ISC_R_SUCCESS) { 8720 goto failure; 8721 } 8722 8723 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = false; 8724 for (result = dns_rdatasetiter_first(iterator); 8725 result == ISC_R_SUCCESS; 8726 result = dns_rdatasetiter_next(iterator)) 8727 { 8728 dns_rdatasetiter_current(iterator, &rdataset); 8729 INSIST(rdataset.type != dns_rdatatype_nsec3); 8730 if (rdataset.type == dns_rdatatype_soa) { 8731 seen_soa = true; 8732 } else if (rdataset.type == dns_rdatatype_ns) { 8733 seen_ns = true; 8734 } else if (rdataset.type == dns_rdatatype_dname) { 8735 seen_dname = true; 8736 } else if (rdataset.type == dns_rdatatype_ds) { 8737 seen_ds = true; 8738 } else if (rdataset.type == dns_rdatatype_nsec) { 8739 seen_nsec = true; 8740 } 8741 dns_rdataset_disassociate(&rdataset); 8742 } 8743 dns_rdatasetiter_destroy(&iterator); 8744 /* 8745 * Is there a NSEC chain than needs to be cleaned up? 8746 */ 8747 if (seen_nsec) { 8748 nsec3chain->seen_nsec = true; 8749 } 8750 if (seen_ns && !seen_soa && !seen_ds) { 8751 unsecure = true; 8752 } 8753 if ((seen_ns && !seen_soa) || seen_dname) { 8754 delegation = true; 8755 } 8756 8757 /* 8758 * Process one node. 8759 */ 8760 dns_dbiterator_pause(nsec3chain->dbiterator); 8761 result = dns_nsec3_addnsec3( 8762 db, version, name, &nsec3chain->nsec3param, 8763 zone_nsecttl(zone), unsecure, &nsec3_diff); 8764 if (result != ISC_R_SUCCESS) { 8765 dnssec_log(zone, ISC_LOG_ERROR, 8766 "zone_nsec3chain:" 8767 "dns_nsec3_addnsec3 -> %s", 8768 dns_result_totext(result)); 8769 goto failure; 8770 } 8771 8772 /* 8773 * Treat each call to dns_nsec3_addnsec3() as if it's cost is 8774 * two signatures. Additionally there will, in general, be 8775 * two signature generated below. 8776 * 8777 * If we are only changing the optout flag the cost is half 8778 * that of the cost of generating a completely new chain. 8779 */ 8780 signatures -= 4; 8781 8782 /* 8783 * Go onto next node. 8784 */ 8785 next_addnode: 8786 first = false; 8787 dns_db_detachnode(db, &node); 8788 do { 8789 result = dns_dbiterator_next(nsec3chain->dbiterator); 8790 8791 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) { 8792 dns_dbiterator_pause(nsec3chain->dbiterator); 8793 CHECK(fixup_nsec3param(db, version, nsec3chain, 8794 false, privatetype, 8795 ¶m_diff)); 8796 LOCK_ZONE(zone); 8797 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 8798 link); 8799 UNLOCK_ZONE(zone); 8800 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8801 goto next_addchain; 8802 } 8803 if (result == ISC_R_NOMORE) { 8804 dns_dbiterator_pause(nsec3chain->dbiterator); 8805 if (nsec3chain->seen_nsec) { 8806 CHECK(fixup_nsec3param( 8807 db, version, nsec3chain, true, 8808 privatetype, ¶m_diff)); 8809 nsec3chain->delete_nsec = true; 8810 goto same_addchain; 8811 } 8812 CHECK(fixup_nsec3param(db, version, nsec3chain, 8813 false, privatetype, 8814 ¶m_diff)); 8815 LOCK_ZONE(zone); 8816 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 8817 link); 8818 UNLOCK_ZONE(zone); 8819 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8820 goto next_addchain; 8821 } else if (result != ISC_R_SUCCESS) { 8822 dnssec_log(zone, ISC_LOG_ERROR, 8823 "zone_nsec3chain:" 8824 "dns_dbiterator_next -> %s", 8825 dns_result_totext(result)); 8826 goto failure; 8827 } else if (delegation) { 8828 dns_dbiterator_current(nsec3chain->dbiterator, 8829 &node, nextname); 8830 dns_db_detachnode(db, &node); 8831 if (!dns_name_issubdomain(nextname, name)) { 8832 break; 8833 } 8834 } else { 8835 break; 8836 } 8837 } while (1); 8838 continue; 8839 8840 same_addchain: 8841 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 8842 first = true; 8843 continue; 8844 8845 next_addchain: 8846 dns_dbiterator_pause(nsec3chain->dbiterator); 8847 nsec3chain = nextnsec3chain; 8848 first = true; 8849 if (nsec3chain != NULL) { 8850 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 8851 } 8852 } 8853 8854 if (nsec3chain != NULL) { 8855 goto skip_removals; 8856 } 8857 8858 /* 8859 * Process removals. 8860 * 8861 * This is a counterpart of the above while loop which takes care of 8862 * removing an NSEC3 chain. It starts with determining whether the 8863 * zone needs to switch from NSEC3 to NSEC; if so, it first builds an 8864 * NSEC chain by iterating over all nodes in the zone database and only 8865 * then goes on to remove NSEC3 records be iterating over all nodes 8866 * again and calling deletematchingnsec3() for each of them; otherwise, 8867 * it starts removing NSEC3 records immediately. Rules for processing 8868 * obscured nodes and interrupting work are the same as for the while 8869 * loop above. 8870 */ 8871 LOCK_ZONE(zone); 8872 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 8873 UNLOCK_ZONE(zone); 8874 first = true; 8875 buildnsecchain = false; 8876 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 8877 dns_dbiterator_pause(nsec3chain->dbiterator); 8878 8879 LOCK_ZONE(zone); 8880 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 8881 UNLOCK_ZONE(zone); 8882 8883 if (nsec3chain->db != db) { 8884 goto next_removechain; 8885 } 8886 8887 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) { 8888 goto next_removechain; 8889 } 8890 8891 /* 8892 * Work out if we need to build a NSEC chain as a consequence 8893 * of removing this NSEC3 chain. 8894 */ 8895 if (first && !updatensec && 8896 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) 8897 { 8898 result = need_nsec_chain(db, version, 8899 &nsec3chain->nsec3param, 8900 &buildnsecchain); 8901 if (result != ISC_R_SUCCESS) { 8902 dnssec_log(zone, ISC_LOG_ERROR, 8903 "zone_nsec3chain:" 8904 "need_nsec_chain -> %s", 8905 dns_result_totext(result)); 8906 goto failure; 8907 } 8908 } 8909 8910 if (first) { 8911 dnssec_log(zone, ISC_LOG_DEBUG(3), 8912 "zone_nsec3chain:buildnsecchain = %u\n", 8913 buildnsecchain); 8914 } 8915 8916 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 8917 dns_dbiterator_pause(nsec3chain->dbiterator); 8918 delegation = false; 8919 8920 if (!buildnsecchain) { 8921 /* 8922 * Delete the NSEC3PARAM record matching this chain. 8923 */ 8924 if (first) { 8925 result = fixup_nsec3param( 8926 db, version, nsec3chain, true, 8927 privatetype, ¶m_diff); 8928 if (result != ISC_R_SUCCESS) { 8929 dnssec_log(zone, ISC_LOG_ERROR, 8930 "zone_nsec3chain:" 8931 "fixup_nsec3param -> %s", 8932 dns_result_totext(result)); 8933 goto failure; 8934 } 8935 } 8936 8937 /* 8938 * Delete the NSEC3 records. 8939 */ 8940 result = deletematchingnsec3(db, version, node, name, 8941 &nsec3chain->nsec3param, 8942 &nsec3_diff); 8943 if (result != ISC_R_SUCCESS) { 8944 dnssec_log(zone, ISC_LOG_ERROR, 8945 "zone_nsec3chain:" 8946 "deletematchingnsec3 -> %s", 8947 dns_result_totext(result)); 8948 goto failure; 8949 } 8950 goto next_removenode; 8951 } 8952 8953 if (first) { 8954 dns_fixedname_t ffound; 8955 dns_name_t *found; 8956 found = dns_fixedname_initname(&ffound); 8957 result = dns_db_find( 8958 db, name, version, dns_rdatatype_soa, 8959 DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); 8960 if ((result == DNS_R_DELEGATION || 8961 result == DNS_R_DNAME) && 8962 !dns_name_equal(name, found)) 8963 { 8964 /* 8965 * Remember the obscuring name so that 8966 * we skip all obscured names. 8967 */ 8968 dns_name_copynf(found, name); 8969 delegation = true; 8970 goto next_removenode; 8971 } 8972 } 8973 8974 /* 8975 * Check to see if this is a bottom of zone node. 8976 */ 8977 result = dns_db_allrdatasets(db, node, version, 0, 0, 8978 &iterator); 8979 if (result == ISC_R_NOTFOUND) { 8980 /* Empty node? */ 8981 goto next_removenode; 8982 } 8983 if (result != ISC_R_SUCCESS) { 8984 goto failure; 8985 } 8986 8987 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec = 8988 seen_rr = false; 8989 for (result = dns_rdatasetiter_first(iterator); 8990 result == ISC_R_SUCCESS; 8991 result = dns_rdatasetiter_next(iterator)) 8992 { 8993 dns_rdatasetiter_current(iterator, &rdataset); 8994 if (rdataset.type == dns_rdatatype_soa) { 8995 seen_soa = true; 8996 } else if (rdataset.type == dns_rdatatype_ns) { 8997 seen_ns = true; 8998 } else if (rdataset.type == dns_rdatatype_dname) { 8999 seen_dname = true; 9000 } else if (rdataset.type == dns_rdatatype_nsec) { 9001 seen_nsec = true; 9002 } else if (rdataset.type == dns_rdatatype_nsec3) { 9003 seen_nsec3 = true; 9004 } else if (rdataset.type != dns_rdatatype_rrsig) { 9005 seen_rr = true; 9006 } 9007 dns_rdataset_disassociate(&rdataset); 9008 } 9009 dns_rdatasetiter_destroy(&iterator); 9010 9011 if (!seen_rr || seen_nsec3 || seen_nsec) { 9012 goto next_removenode; 9013 } 9014 if ((seen_ns && !seen_soa) || seen_dname) { 9015 delegation = true; 9016 } 9017 9018 /* 9019 * Add a NSEC record except at the origin. 9020 */ 9021 if (!dns_name_equal(name, dns_db_origin(db))) { 9022 dns_dbiterator_pause(nsec3chain->dbiterator); 9023 CHECK(add_nsec(db, version, name, node, 9024 zone_nsecttl(zone), delegation, 9025 &nsec_diff)); 9026 signatures--; 9027 } 9028 9029 next_removenode: 9030 first = false; 9031 dns_db_detachnode(db, &node); 9032 do { 9033 result = dns_dbiterator_next(nsec3chain->dbiterator); 9034 if (result == ISC_R_NOMORE && buildnsecchain) { 9035 /* 9036 * The NSEC chain should now be built. 9037 * We can now remove the NSEC3 chain. 9038 */ 9039 updatensec = true; 9040 goto same_removechain; 9041 } 9042 if (result == ISC_R_NOMORE) { 9043 dns_dbiterator_pause(nsec3chain->dbiterator); 9044 LOCK_ZONE(zone); 9045 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 9046 link); 9047 UNLOCK_ZONE(zone); 9048 ISC_LIST_APPEND(cleanup, nsec3chain, link); 9049 result = fixup_nsec3param( 9050 db, version, nsec3chain, false, 9051 privatetype, ¶m_diff); 9052 if (result != ISC_R_SUCCESS) { 9053 dnssec_log(zone, ISC_LOG_ERROR, 9054 "zone_nsec3chain:" 9055 "fixup_nsec3param -> %s", 9056 dns_result_totext(result)); 9057 goto failure; 9058 } 9059 goto next_removechain; 9060 } else if (result != ISC_R_SUCCESS) { 9061 dnssec_log(zone, ISC_LOG_ERROR, 9062 "zone_nsec3chain:" 9063 "dns_dbiterator_next -> %s", 9064 dns_result_totext(result)); 9065 goto failure; 9066 } else if (delegation) { 9067 dns_dbiterator_current(nsec3chain->dbiterator, 9068 &node, nextname); 9069 dns_db_detachnode(db, &node); 9070 if (!dns_name_issubdomain(nextname, name)) { 9071 break; 9072 } 9073 } else { 9074 break; 9075 } 9076 } while (1); 9077 continue; 9078 9079 same_removechain: 9080 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 9081 buildnsecchain = false; 9082 first = true; 9083 continue; 9084 9085 next_removechain: 9086 dns_dbiterator_pause(nsec3chain->dbiterator); 9087 nsec3chain = nextnsec3chain; 9088 first = true; 9089 } 9090 9091skip_removals: 9092 /* 9093 * We may need to update the NSEC/NSEC3 records for the zone apex. 9094 */ 9095 if (!ISC_LIST_EMPTY(param_diff.tuples)) { 9096 bool rebuild_nsec = false, rebuild_nsec3 = false; 9097 result = dns_db_getoriginnode(db, &node); 9098 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9099 result = dns_db_allrdatasets(db, node, version, 0, 0, 9100 &iterator); 9101 if (result != ISC_R_SUCCESS) { 9102 dnssec_log(zone, ISC_LOG_ERROR, 9103 "zone_nsec3chain:dns_db_allrdatasets -> %s", 9104 dns_result_totext(result)); 9105 goto failure; 9106 } 9107 for (result = dns_rdatasetiter_first(iterator); 9108 result == ISC_R_SUCCESS; 9109 result = dns_rdatasetiter_next(iterator)) 9110 { 9111 dns_rdatasetiter_current(iterator, &rdataset); 9112 if (rdataset.type == dns_rdatatype_nsec) { 9113 rebuild_nsec = true; 9114 } else if (rdataset.type == dns_rdatatype_nsec3param) { 9115 rebuild_nsec3 = true; 9116 } 9117 dns_rdataset_disassociate(&rdataset); 9118 } 9119 dns_rdatasetiter_destroy(&iterator); 9120 dns_db_detachnode(db, &node); 9121 9122 if (rebuild_nsec) { 9123 if (nsec3chain != NULL) { 9124 dns_dbiterator_pause(nsec3chain->dbiterator); 9125 } 9126 9127 result = updatesecure(db, version, &zone->origin, 9128 zone_nsecttl(zone), true, 9129 &nsec_diff); 9130 if (result != ISC_R_SUCCESS) { 9131 dnssec_log(zone, ISC_LOG_ERROR, 9132 "zone_nsec3chain:updatesecure -> %s", 9133 dns_result_totext(result)); 9134 goto failure; 9135 } 9136 } 9137 9138 if (rebuild_nsec3) { 9139 if (nsec3chain != NULL) { 9140 dns_dbiterator_pause(nsec3chain->dbiterator); 9141 } 9142 9143 result = dns_nsec3_addnsec3s( 9144 db, version, dns_db_origin(db), 9145 zone_nsecttl(zone), false, &nsec3_diff); 9146 if (result != ISC_R_SUCCESS) { 9147 dnssec_log(zone, ISC_LOG_ERROR, 9148 "zone_nsec3chain:" 9149 "dns_nsec3_addnsec3s -> %s", 9150 dns_result_totext(result)); 9151 goto failure; 9152 } 9153 } 9154 } 9155 9156 /* 9157 * Add / update signatures for the NSEC3 records. 9158 */ 9159 if (nsec3chain != NULL) { 9160 dns_dbiterator_pause(nsec3chain->dbiterator); 9161 } 9162 result = dns__zone_updatesigs(&nsec3_diff, db, version, zone_keys, 9163 nkeys, zone, inception, expire, 0, now, 9164 check_ksk, keyset_kskonly, &zonediff); 9165 if (result != ISC_R_SUCCESS) { 9166 dnssec_log(zone, ISC_LOG_ERROR, 9167 "zone_nsec3chain:dns__zone_updatesigs -> %s", 9168 dns_result_totext(result)); 9169 goto failure; 9170 } 9171 9172 /* 9173 * We have changed the NSEC3PARAM or private RRsets 9174 * above so we need to update the signatures. 9175 */ 9176 result = dns__zone_updatesigs(¶m_diff, db, version, zone_keys, 9177 nkeys, zone, inception, expire, 0, now, 9178 check_ksk, keyset_kskonly, &zonediff); 9179 if (result != ISC_R_SUCCESS) { 9180 dnssec_log(zone, ISC_LOG_ERROR, 9181 "zone_nsec3chain:dns__zone_updatesigs -> %s", 9182 dns_result_totext(result)); 9183 goto failure; 9184 } 9185 9186 if (updatensec) { 9187 result = updatesecure(db, version, &zone->origin, 9188 zone_nsecttl(zone), false, &nsec_diff); 9189 if (result != ISC_R_SUCCESS) { 9190 dnssec_log(zone, ISC_LOG_ERROR, 9191 "zone_nsec3chain:updatesecure -> %s", 9192 dns_result_totext(result)); 9193 goto failure; 9194 } 9195 } 9196 9197 result = dns__zone_updatesigs(&nsec_diff, db, version, zone_keys, nkeys, 9198 zone, inception, expire, 0, now, 9199 check_ksk, keyset_kskonly, &zonediff); 9200 if (result != ISC_R_SUCCESS) { 9201 dnssec_log(zone, ISC_LOG_ERROR, 9202 "zone_nsec3chain:dns__zone_updatesigs -> %s", 9203 dns_result_totext(result)); 9204 goto failure; 9205 } 9206 9207 /* 9208 * If we made no effective changes to the zone then we can just 9209 * cleanup otherwise we need to increment the serial. 9210 */ 9211 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 9212 /* 9213 * No need to call dns_db_closeversion() here as it is 9214 * called with commit = true below. 9215 */ 9216 goto done; 9217 } 9218 9219 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 9220 &zonediff, zone_keys, nkeys, now, false); 9221 if (result != ISC_R_SUCCESS) { 9222 dnssec_log(zone, ISC_LOG_ERROR, 9223 "zone_nsec3chain:del_sigs -> %s", 9224 dns_result_totext(result)); 9225 goto failure; 9226 } 9227 9228 result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx, 9229 zone->updatemethod); 9230 if (result != ISC_R_SUCCESS) { 9231 dnssec_log(zone, ISC_LOG_ERROR, 9232 "zone_nsec3chain:update_soa_serial -> %s", 9233 dns_result_totext(result)); 9234 goto failure; 9235 } 9236 9237 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa, 9238 zonediff.diff, zone_keys, nkeys, zone->mctx, 9239 inception, soaexpire, check_ksk, keyset_kskonly); 9240 if (result != ISC_R_SUCCESS) { 9241 dnssec_log(zone, ISC_LOG_ERROR, 9242 "zone_nsec3chain:add_sigs -> %s", 9243 dns_result_totext(result)); 9244 goto failure; 9245 } 9246 9247 /* Write changes to journal file. */ 9248 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain")); 9249 9250 LOCK_ZONE(zone); 9251 zone_needdump(zone, DNS_DUMP_DELAY); 9252 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 9253 UNLOCK_ZONE(zone); 9254 9255done: 9256 /* 9257 * Pause all iterators so that dns_db_closeversion() can succeed. 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 /* 9268 * Everything has succeeded. Commit the changes. 9269 * Unconditionally commit as zonediff.offline not checked above. 9270 */ 9271 dns_db_closeversion(db, &version, true); 9272 9273 /* 9274 * Everything succeeded so we can clean these up now. 9275 */ 9276 nsec3chain = ISC_LIST_HEAD(cleanup); 9277 while (nsec3chain != NULL) { 9278 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 9279 dns_db_detach(&nsec3chain->db); 9280 dns_dbiterator_destroy(&nsec3chain->dbiterator); 9281 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 9282 nsec3chain = ISC_LIST_HEAD(cleanup); 9283 } 9284 9285 LOCK_ZONE(zone); 9286 set_resigntime(zone); 9287 UNLOCK_ZONE(zone); 9288 9289failure: 9290 if (result != ISC_R_SUCCESS) { 9291 dnssec_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s", 9292 dns_result_totext(result)); 9293 } 9294 9295 /* 9296 * On error roll back the current nsec3chain. 9297 */ 9298 if (result != ISC_R_SUCCESS && nsec3chain != NULL) { 9299 if (nsec3chain->done) { 9300 dns_db_detach(&nsec3chain->db); 9301 dns_dbiterator_destroy(&nsec3chain->dbiterator); 9302 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 9303 } else { 9304 result = dns_dbiterator_first(nsec3chain->dbiterator); 9305 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9306 dns_dbiterator_pause(nsec3chain->dbiterator); 9307 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 9308 } 9309 } 9310 9311 /* 9312 * Rollback the cleanup list. 9313 */ 9314 nsec3chain = ISC_LIST_TAIL(cleanup); 9315 while (nsec3chain != NULL) { 9316 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 9317 if (nsec3chain->done) { 9318 dns_db_detach(&nsec3chain->db); 9319 dns_dbiterator_destroy(&nsec3chain->dbiterator); 9320 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 9321 } else { 9322 LOCK_ZONE(zone); 9323 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link); 9324 UNLOCK_ZONE(zone); 9325 result = dns_dbiterator_first(nsec3chain->dbiterator); 9326 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9327 dns_dbiterator_pause(nsec3chain->dbiterator); 9328 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 9329 } 9330 nsec3chain = ISC_LIST_TAIL(cleanup); 9331 } 9332 9333 LOCK_ZONE(zone); 9334 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL; 9335 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 9336 { 9337 dns_dbiterator_pause(nsec3chain->dbiterator); 9338 } 9339 UNLOCK_ZONE(zone); 9340 9341 dns_diff_clear(¶m_diff); 9342 dns_diff_clear(&nsec3_diff); 9343 dns_diff_clear(&nsec_diff); 9344 dns_diff_clear(&_sig_diff); 9345 9346 if (iterator != NULL) { 9347 dns_rdatasetiter_destroy(&iterator); 9348 } 9349 9350 for (i = 0; i < nkeys; i++) { 9351 dst_key_free(&zone_keys[i]); 9352 } 9353 9354 if (node != NULL) { 9355 dns_db_detachnode(db, &node); 9356 } 9357 if (version != NULL) { 9358 dns_db_closeversion(db, &version, false); 9359 dns_db_detach(&db); 9360 } else if (db != NULL) { 9361 dns_db_detach(&db); 9362 } 9363 9364 LOCK_ZONE(zone); 9365 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) { 9366 isc_interval_t interval; 9367 if (zone->update_disabled || result != ISC_R_SUCCESS) { 9368 isc_interval_set(&interval, 60, 0); /* 1 minute */ 9369 } else { 9370 isc_interval_set(&interval, 0, 10000000); /* 10 ms */ 9371 } 9372 isc_time_nowplusinterval(&zone->nsec3chaintime, &interval); 9373 } else { 9374 isc_time_settoepoch(&zone->nsec3chaintime); 9375 } 9376 UNLOCK_ZONE(zone); 9377 9378 INSIST(version == NULL); 9379} 9380 9381/*% 9382 * Delete all RRSIG records with the given algorithm and keyid. 9383 * Remove the NSEC record and RRSIGs if nkeys is zero. 9384 * If all remaining RRsets are signed with the given algorithm 9385 * set *has_algp to true. 9386 */ 9387static isc_result_t 9388del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 9389 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm, 9390 uint16_t keyid, bool *has_algp, dns_diff_t *diff) { 9391 dns_rdata_rrsig_t rrsig; 9392 dns_rdataset_t rdataset; 9393 dns_rdatasetiter_t *iterator = NULL; 9394 isc_result_t result; 9395 bool alg_missed = false; 9396 bool alg_found = false; 9397 9398 char namebuf[DNS_NAME_FORMATSIZE]; 9399 dns_name_format(name, namebuf, sizeof(namebuf)); 9400 9401 result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator); 9402 if (result != ISC_R_SUCCESS) { 9403 if (result == ISC_R_NOTFOUND) { 9404 result = ISC_R_SUCCESS; 9405 } 9406 return (result); 9407 } 9408 9409 dns_rdataset_init(&rdataset); 9410 for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; 9411 result = dns_rdatasetiter_next(iterator)) 9412 { 9413 bool has_alg = false; 9414 dns_rdatasetiter_current(iterator, &rdataset); 9415 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) { 9416 for (result = dns_rdataset_first(&rdataset); 9417 result == ISC_R_SUCCESS; 9418 result = dns_rdataset_next(&rdataset)) 9419 { 9420 dns_rdata_t rdata = DNS_RDATA_INIT; 9421 dns_rdataset_current(&rdataset, &rdata); 9422 CHECK(update_one_rr(db, version, diff, 9423 DNS_DIFFOP_DEL, name, 9424 rdataset.ttl, &rdata)); 9425 } 9426 if (result != ISC_R_NOMORE) { 9427 goto failure; 9428 } 9429 dns_rdataset_disassociate(&rdataset); 9430 continue; 9431 } 9432 if (rdataset.type != dns_rdatatype_rrsig) { 9433 dns_rdataset_disassociate(&rdataset); 9434 continue; 9435 } 9436 for (result = dns_rdataset_first(&rdataset); 9437 result == ISC_R_SUCCESS; 9438 result = dns_rdataset_next(&rdataset)) 9439 { 9440 dns_rdata_t rdata = DNS_RDATA_INIT; 9441 dns_rdataset_current(&rdataset, &rdata); 9442 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL)); 9443 if (nkeys != 0 && (rrsig.algorithm != algorithm || 9444 rrsig.keyid != keyid)) 9445 { 9446 if (rrsig.algorithm == algorithm) { 9447 has_alg = true; 9448 } 9449 continue; 9450 } 9451 CHECK(update_one_rr(db, version, diff, 9452 DNS_DIFFOP_DELRESIGN, name, 9453 rdataset.ttl, &rdata)); 9454 } 9455 dns_rdataset_disassociate(&rdataset); 9456 if (result != ISC_R_NOMORE) { 9457 break; 9458 } 9459 9460 /* 9461 * After deleting, if there's still a signature for 9462 * 'algorithm', set alg_found; if not, set alg_missed. 9463 */ 9464 if (has_alg) { 9465 alg_found = true; 9466 } else { 9467 alg_missed = true; 9468 } 9469 } 9470 if (result == ISC_R_NOMORE) { 9471 result = ISC_R_SUCCESS; 9472 } 9473 9474 /* 9475 * Set `has_algp` if the algorithm was found in every RRset: 9476 * i.e., found in at least one, and not missing from any. 9477 */ 9478 *has_algp = (alg_found && !alg_missed); 9479failure: 9480 if (dns_rdataset_isassociated(&rdataset)) { 9481 dns_rdataset_disassociate(&rdataset); 9482 } 9483 dns_rdatasetiter_destroy(&iterator); 9484 return (result); 9485} 9486 9487/* 9488 * Incrementally sign the zone using the keys requested. 9489 * Builds the NSEC chain if required. 9490 */ 9491static void 9492zone_sign(dns_zone_t *zone) { 9493 const char *me = "zone_sign"; 9494 dns_db_t *db = NULL; 9495 dns_dbnode_t *node = NULL; 9496 dns_dbversion_t *version = NULL; 9497 dns_diff_t _sig_diff; 9498 dns_diff_t post_diff; 9499 dns__zonediff_t zonediff; 9500 dns_fixedname_t fixed; 9501 dns_fixedname_t nextfixed; 9502 dns_kasp_t *kasp; 9503 dns_name_t *name, *nextname; 9504 dns_rdataset_t rdataset; 9505 dns_signing_t *signing, *nextsigning; 9506 dns_signinglist_t cleanup; 9507 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 9508 int32_t signatures; 9509 bool check_ksk, keyset_kskonly, is_ksk, is_zsk; 9510 bool with_ksk, with_zsk; 9511 bool commit = false; 9512 bool is_bottom_of_zone; 9513 bool build_nsec = false; 9514 bool build_nsec3 = false; 9515 bool use_kasp = false; 9516 bool first; 9517 isc_result_t result; 9518 isc_stdtime_t now, inception, soaexpire, expire; 9519 uint32_t jitter, sigvalidityinterval, expiryinterval; 9520 unsigned int i, j; 9521 unsigned int nkeys = 0; 9522 uint32_t nodes; 9523 9524 ENTER; 9525 9526 dns_rdataset_init(&rdataset); 9527 name = dns_fixedname_initname(&fixed); 9528 nextname = dns_fixedname_initname(&nextfixed); 9529 dns_diff_init(zone->mctx, &_sig_diff); 9530 dns_diff_init(zone->mctx, &post_diff); 9531 zonediff_init(&zonediff, &_sig_diff); 9532 ISC_LIST_INIT(cleanup); 9533 9534 /* 9535 * Updates are disabled. Pause for 1 minute. 9536 */ 9537 if (zone->update_disabled) { 9538 result = ISC_R_FAILURE; 9539 goto cleanup; 9540 } 9541 9542 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9543 if (zone->db != NULL) { 9544 dns_db_attach(zone->db, &db); 9545 } 9546 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9547 if (db == NULL) { 9548 result = ISC_R_FAILURE; 9549 goto cleanup; 9550 } 9551 9552 result = dns_db_newversion(db, &version); 9553 if (result != ISC_R_SUCCESS) { 9554 dnssec_log(zone, ISC_LOG_ERROR, 9555 "zone_sign:dns_db_newversion -> %s", 9556 dns_result_totext(result)); 9557 goto cleanup; 9558 } 9559 9560 isc_stdtime_get(&now); 9561 9562 result = dns__zone_findkeys(zone, db, version, now, zone->mctx, 9563 DNS_MAXZONEKEYS, zone_keys, &nkeys); 9564 if (result != ISC_R_SUCCESS) { 9565 dnssec_log(zone, ISC_LOG_ERROR, 9566 "zone_sign:dns__zone_findkeys -> %s", 9567 dns_result_totext(result)); 9568 goto cleanup; 9569 } 9570 9571 kasp = dns_zone_getkasp(zone); 9572 sigvalidityinterval = dns_zone_getsigvalidityinterval(zone); 9573 inception = now - 3600; /* Allow for clock skew. */ 9574 soaexpire = now + sigvalidityinterval; 9575 expiryinterval = dns_zone_getsigresigninginterval(zone); 9576 if (expiryinterval > sigvalidityinterval) { 9577 expiryinterval = sigvalidityinterval; 9578 } else { 9579 expiryinterval = sigvalidityinterval - expiryinterval; 9580 } 9581 9582 /* 9583 * Spread out signatures over time if they happen to be 9584 * clumped. We don't do this for each add_sigs() call as 9585 * we still want some clustering to occur. 9586 */ 9587 if (sigvalidityinterval >= 3600U) { 9588 if (sigvalidityinterval > 7200U) { 9589 jitter = isc_random_uniform(expiryinterval); 9590 } else { 9591 jitter = isc_random_uniform(1200); 9592 } 9593 expire = soaexpire - jitter - 1; 9594 } else { 9595 expire = soaexpire - 1; 9596 } 9597 9598 /* 9599 * We keep pulling nodes off each iterator in turn until 9600 * we have no more nodes to pull off or we reach the limits 9601 * for this quantum. 9602 */ 9603 nodes = zone->nodes; 9604 signatures = zone->signatures; 9605 signing = ISC_LIST_HEAD(zone->signing); 9606 first = true; 9607 9608 if (dns_zone_getkasp(zone) != NULL) { 9609 check_ksk = false; 9610 keyset_kskonly = true; 9611 use_kasp = true; 9612 } else { 9613 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 9614 keyset_kskonly = DNS_ZONE_OPTION(zone, 9615 DNS_ZONEOPT_DNSKEYKSKONLY); 9616 } 9617 dnssec_log(zone, ISC_LOG_DEBUG(3), "zone_sign:use kasp -> %s", 9618 use_kasp ? "yes" : "no"); 9619 9620 /* Determine which type of chain to build */ 9621 CHECK(dns_private_chains(db, version, zone->privatetype, &build_nsec, 9622 &build_nsec3)); 9623 if (!build_nsec && !build_nsec3) { 9624 if (use_kasp) { 9625 build_nsec3 = dns_kasp_nsec3(kasp); 9626 build_nsec = !build_nsec3; 9627 } else { 9628 /* If neither chain is found, default to NSEC */ 9629 build_nsec = true; 9630 } 9631 } 9632 9633 while (signing != NULL && nodes-- > 0 && signatures > 0) { 9634 bool has_alg = false; 9635 9636 dns_dbiterator_pause(signing->dbiterator); 9637 nextsigning = ISC_LIST_NEXT(signing, link); 9638 9639 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9640 if (signing->done || signing->db != zone->db) { 9641 /* 9642 * The zone has been reloaded. We will have to 9643 * created new signings as part of the reload 9644 * process so we can destroy this one. 9645 */ 9646 ISC_LIST_UNLINK(zone->signing, signing, link); 9647 ISC_LIST_APPEND(cleanup, signing, link); 9648 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9649 goto next_signing; 9650 } 9651 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9652 9653 if (signing->db != db) { 9654 goto next_signing; 9655 } 9656 9657 is_bottom_of_zone = false; 9658 9659 if (first && signing->deleteit) { 9660 /* 9661 * Remove the key we are deleting from consideration. 9662 */ 9663 for (i = 0, j = 0; i < nkeys; i++) { 9664 /* 9665 * Find the key we want to remove. 9666 */ 9667 if (ALG(zone_keys[i]) == signing->algorithm && 9668 dst_key_id(zone_keys[i]) == signing->keyid) 9669 { 9670 bool ksk = false; 9671 isc_result_t ret = dst_key_getbool( 9672 zone_keys[i], DST_BOOL_KSK, 9673 &ksk); 9674 if (ret != ISC_R_SUCCESS) { 9675 ksk = KSK(zone_keys[i]); 9676 } 9677 if (ksk) { 9678 dst_key_free(&zone_keys[i]); 9679 } 9680 continue; 9681 } 9682 zone_keys[j] = zone_keys[i]; 9683 j++; 9684 } 9685 for (i = j; i < nkeys; i++) { 9686 zone_keys[i] = NULL; 9687 } 9688 nkeys = j; 9689 } 9690 9691 dns_dbiterator_current(signing->dbiterator, &node, name); 9692 9693 if (signing->deleteit) { 9694 dns_dbiterator_pause(signing->dbiterator); 9695 CHECK(del_sig(db, version, name, node, nkeys, 9696 signing->algorithm, signing->keyid, 9697 &has_alg, zonediff.diff)); 9698 } 9699 9700 /* 9701 * On the first pass we need to check if the current node 9702 * has not been obscured. 9703 */ 9704 if (first) { 9705 dns_fixedname_t ffound; 9706 dns_name_t *found; 9707 found = dns_fixedname_initname(&ffound); 9708 result = dns_db_find( 9709 db, name, version, dns_rdatatype_soa, 9710 DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); 9711 if ((result == DNS_R_DELEGATION || 9712 result == DNS_R_DNAME) && 9713 !dns_name_equal(name, found)) 9714 { 9715 /* 9716 * Remember the obscuring name so that 9717 * we skip all obscured names. 9718 */ 9719 dns_name_copynf(found, name); 9720 is_bottom_of_zone = true; 9721 goto next_node; 9722 } 9723 } 9724 9725 /* 9726 * Process one node. 9727 */ 9728 with_ksk = false; 9729 with_zsk = false; 9730 dns_dbiterator_pause(signing->dbiterator); 9731 9732 CHECK(check_if_bottom_of_zone(db, node, version, 9733 &is_bottom_of_zone)); 9734 9735 for (i = 0; !has_alg && i < nkeys; i++) { 9736 bool both = false; 9737 9738 /* 9739 * Find the keys we want to sign with. 9740 */ 9741 if (!dst_key_isprivate(zone_keys[i])) { 9742 continue; 9743 } 9744 if (dst_key_inactive(zone_keys[i])) { 9745 continue; 9746 } 9747 9748 /* 9749 * When adding look for the specific key. 9750 */ 9751 if (!signing->deleteit && 9752 (dst_key_alg(zone_keys[i]) != signing->algorithm || 9753 dst_key_id(zone_keys[i]) != signing->keyid)) 9754 { 9755 continue; 9756 } 9757 9758 /* 9759 * When deleting make sure we are properly signed 9760 * with the algorithm that was being removed. 9761 */ 9762 if (signing->deleteit && 9763 ALG(zone_keys[i]) != signing->algorithm) 9764 { 9765 continue; 9766 } 9767 9768 /* 9769 * Do we do KSK processing? 9770 */ 9771 if (check_ksk && !REVOKE(zone_keys[i])) { 9772 bool have_ksk, have_nonksk; 9773 if (KSK(zone_keys[i])) { 9774 have_ksk = true; 9775 have_nonksk = false; 9776 } else { 9777 have_ksk = false; 9778 have_nonksk = true; 9779 } 9780 for (j = 0; j < nkeys; j++) { 9781 if (j == i || (ALG(zone_keys[i]) != 9782 ALG(zone_keys[j]))) 9783 { 9784 continue; 9785 } 9786 /* 9787 * Don't consider inactive keys, however 9788 * the key may be temporary offline, so 9789 * do consider KSKs which private key 9790 * files are unavailable. 9791 */ 9792 if (dst_key_inactive(zone_keys[j])) { 9793 continue; 9794 } 9795 if (REVOKE(zone_keys[j])) { 9796 continue; 9797 } 9798 if (KSK(zone_keys[j])) { 9799 have_ksk = true; 9800 } else if (dst_key_isprivate( 9801 zone_keys[j])) 9802 { 9803 have_nonksk = true; 9804 } 9805 both = have_ksk && have_nonksk; 9806 if (both) { 9807 break; 9808 } 9809 } 9810 } 9811 if (use_kasp) { 9812 /* 9813 * A dnssec-policy is found. Check what 9814 * RRsets this key can sign. 9815 */ 9816 isc_result_t kresult; 9817 is_ksk = false; 9818 kresult = dst_key_getbool( 9819 zone_keys[i], DST_BOOL_KSK, &is_ksk); 9820 if (kresult != ISC_R_SUCCESS) { 9821 if (KSK(zone_keys[i])) { 9822 is_ksk = true; 9823 } 9824 } 9825 9826 is_zsk = false; 9827 kresult = dst_key_getbool( 9828 zone_keys[i], DST_BOOL_ZSK, &is_zsk); 9829 if (kresult != ISC_R_SUCCESS) { 9830 if (!KSK(zone_keys[i])) { 9831 is_zsk = true; 9832 } 9833 } 9834 /* Treat as if we have both KSK and ZSK. */ 9835 both = true; 9836 } else if (both || REVOKE(zone_keys[i])) { 9837 is_ksk = KSK(zone_keys[i]); 9838 is_zsk = !KSK(zone_keys[i]); 9839 } else { 9840 is_ksk = false; 9841 is_zsk = true; 9842 } 9843 9844 /* 9845 * If deleting signatures, we need to ensure that 9846 * the RRset is still signed at least once by a 9847 * KSK and a ZSK. 9848 */ 9849 if (signing->deleteit && is_zsk && with_zsk) { 9850 continue; 9851 } 9852 9853 if (signing->deleteit && is_ksk && with_ksk) { 9854 continue; 9855 } 9856 9857 CHECK(sign_a_node( 9858 db, zone, name, node, version, build_nsec3, 9859 build_nsec, zone_keys[i], inception, expire, 9860 zone_nsecttl(zone), is_ksk, is_zsk, 9861 (both && keyset_kskonly), is_bottom_of_zone, 9862 zonediff.diff, &signatures, zone->mctx)); 9863 /* 9864 * If we are adding we are done. Look for other keys 9865 * of the same algorithm if deleting. 9866 */ 9867 if (!signing->deleteit) { 9868 break; 9869 } 9870 if (is_zsk) { 9871 with_zsk = true; 9872 } 9873 if (is_ksk) { 9874 with_ksk = true; 9875 } 9876 } 9877 9878 /* 9879 * Go onto next node. 9880 */ 9881 next_node: 9882 first = false; 9883 dns_db_detachnode(db, &node); 9884 do { 9885 result = dns_dbiterator_next(signing->dbiterator); 9886 if (result == ISC_R_NOMORE) { 9887 ISC_LIST_UNLINK(zone->signing, signing, link); 9888 ISC_LIST_APPEND(cleanup, signing, link); 9889 dns_dbiterator_pause(signing->dbiterator); 9890 if (nkeys != 0 && build_nsec) { 9891 /* 9892 * We have finished regenerating the 9893 * zone with a zone signing key. 9894 * The NSEC chain is now complete and 9895 * there is a full set of signatures 9896 * for the zone. We can now clear the 9897 * OPT bit from the NSEC record. 9898 */ 9899 result = updatesecure( 9900 db, version, &zone->origin, 9901 zone_nsecttl(zone), false, 9902 &post_diff); 9903 if (result != ISC_R_SUCCESS) { 9904 dnssec_log(zone, ISC_LOG_ERROR, 9905 "updatesecure -> %s", 9906 dns_result_totext( 9907 result)); 9908 goto cleanup; 9909 } 9910 } 9911 result = updatesignwithkey( 9912 zone, signing, version, build_nsec3, 9913 zone_nsecttl(zone), &post_diff); 9914 if (result != ISC_R_SUCCESS) { 9915 dnssec_log(zone, ISC_LOG_ERROR, 9916 "updatesignwithkey -> %s", 9917 dns_result_totext(result)); 9918 goto cleanup; 9919 } 9920 build_nsec = false; 9921 goto next_signing; 9922 } else if (result != ISC_R_SUCCESS) { 9923 dnssec_log(zone, ISC_LOG_ERROR, 9924 "zone_sign:" 9925 "dns_dbiterator_next -> %s", 9926 dns_result_totext(result)); 9927 goto cleanup; 9928 } else if (is_bottom_of_zone) { 9929 dns_dbiterator_current(signing->dbiterator, 9930 &node, nextname); 9931 dns_db_detachnode(db, &node); 9932 if (!dns_name_issubdomain(nextname, name)) { 9933 break; 9934 } 9935 } else { 9936 break; 9937 } 9938 } while (1); 9939 continue; 9940 9941 next_signing: 9942 dns_dbiterator_pause(signing->dbiterator); 9943 signing = nextsigning; 9944 first = true; 9945 } 9946 9947 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) { 9948 result = dns__zone_updatesigs(&post_diff, db, version, 9949 zone_keys, nkeys, zone, inception, 9950 expire, 0, now, check_ksk, 9951 keyset_kskonly, &zonediff); 9952 if (result != ISC_R_SUCCESS) { 9953 dnssec_log(zone, ISC_LOG_ERROR, 9954 "zone_sign:dns__zone_updatesigs -> %s", 9955 dns_result_totext(result)); 9956 goto cleanup; 9957 } 9958 } 9959 9960 /* 9961 * Have we changed anything? 9962 */ 9963 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 9964 if (zonediff.offline) { 9965 commit = true; 9966 } 9967 result = ISC_R_SUCCESS; 9968 goto pauseall; 9969 } 9970 9971 commit = true; 9972 9973 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 9974 &zonediff, zone_keys, nkeys, now, false); 9975 if (result != ISC_R_SUCCESS) { 9976 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:del_sigs -> %s", 9977 dns_result_totext(result)); 9978 goto cleanup; 9979 } 9980 9981 result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx, 9982 zone->updatemethod); 9983 if (result != ISC_R_SUCCESS) { 9984 dnssec_log(zone, ISC_LOG_ERROR, 9985 "zone_sign:update_soa_serial -> %s", 9986 dns_result_totext(result)); 9987 goto cleanup; 9988 } 9989 9990 /* 9991 * Generate maximum life time signatures so that the above loop 9992 * termination is sensible. 9993 */ 9994 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa, 9995 zonediff.diff, zone_keys, nkeys, zone->mctx, 9996 inception, soaexpire, check_ksk, keyset_kskonly); 9997 if (result != ISC_R_SUCCESS) { 9998 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:add_sigs -> %s", 9999 dns_result_totext(result)); 10000 goto cleanup; 10001 } 10002 10003 /* 10004 * Write changes to journal file. 10005 */ 10006 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign")); 10007 10008pauseall: 10009 /* 10010 * Pause all iterators so that dns_db_closeversion() can succeed. 10011 */ 10012 for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; 10013 signing = ISC_LIST_NEXT(signing, link)) 10014 { 10015 dns_dbiterator_pause(signing->dbiterator); 10016 } 10017 10018 for (signing = ISC_LIST_HEAD(cleanup); signing != NULL; 10019 signing = ISC_LIST_NEXT(signing, link)) 10020 { 10021 dns_dbiterator_pause(signing->dbiterator); 10022 } 10023 10024 /* 10025 * Everything has succeeded. Commit the changes. 10026 */ 10027 dns_db_closeversion(db, &version, commit); 10028 10029 /* 10030 * Everything succeeded so we can clean these up now. 10031 */ 10032 signing = ISC_LIST_HEAD(cleanup); 10033 while (signing != NULL) { 10034 ISC_LIST_UNLINK(cleanup, signing, link); 10035 dns_db_detach(&signing->db); 10036 dns_dbiterator_destroy(&signing->dbiterator); 10037 isc_mem_put(zone->mctx, signing, sizeof *signing); 10038 signing = ISC_LIST_HEAD(cleanup); 10039 } 10040 10041 LOCK_ZONE(zone); 10042 set_resigntime(zone); 10043 if (commit) { 10044 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 10045 zone_needdump(zone, DNS_DUMP_DELAY); 10046 } 10047 UNLOCK_ZONE(zone); 10048 10049failure: 10050 if (result != ISC_R_SUCCESS) { 10051 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign: failed: %s", 10052 dns_result_totext(result)); 10053 } 10054 10055cleanup: 10056 /* 10057 * Pause all dbiterators. 10058 */ 10059 for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; 10060 signing = ISC_LIST_NEXT(signing, link)) 10061 { 10062 dns_dbiterator_pause(signing->dbiterator); 10063 } 10064 10065 /* 10066 * Rollback the cleanup list. 10067 */ 10068 signing = ISC_LIST_HEAD(cleanup); 10069 while (signing != NULL) { 10070 ISC_LIST_UNLINK(cleanup, signing, link); 10071 ISC_LIST_PREPEND(zone->signing, signing, link); 10072 dns_dbiterator_first(signing->dbiterator); 10073 dns_dbiterator_pause(signing->dbiterator); 10074 signing = ISC_LIST_HEAD(cleanup); 10075 } 10076 10077 dns_diff_clear(&_sig_diff); 10078 10079 for (i = 0; i < nkeys; i++) { 10080 dst_key_free(&zone_keys[i]); 10081 } 10082 10083 if (node != NULL) { 10084 dns_db_detachnode(db, &node); 10085 } 10086 10087 if (version != NULL) { 10088 dns_db_closeversion(db, &version, false); 10089 dns_db_detach(&db); 10090 } else if (db != NULL) { 10091 dns_db_detach(&db); 10092 } 10093 10094 LOCK_ZONE(zone); 10095 if (ISC_LIST_HEAD(zone->signing) != NULL) { 10096 isc_interval_t interval; 10097 if (zone->update_disabled || result != ISC_R_SUCCESS) { 10098 isc_interval_set(&interval, 60, 0); /* 1 minute */ 10099 } else { 10100 isc_interval_set(&interval, 0, 10000000); /* 10 ms */ 10101 } 10102 isc_time_nowplusinterval(&zone->signingtime, &interval); 10103 } else { 10104 isc_time_settoepoch(&zone->signingtime); 10105 } 10106 UNLOCK_ZONE(zone); 10107 10108 INSIST(version == NULL); 10109} 10110 10111static isc_result_t 10112normalize_key(dns_rdata_t *rr, dns_rdata_t *target, unsigned char *data, 10113 int size) { 10114 dns_rdata_dnskey_t dnskey; 10115 dns_rdata_keydata_t keydata; 10116 isc_buffer_t buf; 10117 isc_result_t result; 10118 10119 dns_rdata_reset(target); 10120 isc_buffer_init(&buf, data, size); 10121 10122 switch (rr->type) { 10123 case dns_rdatatype_dnskey: 10124 result = dns_rdata_tostruct(rr, &dnskey, NULL); 10125 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10126 dnskey.flags &= ~DNS_KEYFLAG_REVOKE; 10127 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 10128 &dnskey, &buf); 10129 break; 10130 case dns_rdatatype_keydata: 10131 result = dns_rdata_tostruct(rr, &keydata, NULL); 10132 if (result == ISC_R_UNEXPECTEDEND) { 10133 return (result); 10134 } 10135 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10136 dns_keydata_todnskey(&keydata, &dnskey, NULL); 10137 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 10138 &dnskey, &buf); 10139 break; 10140 default: 10141 UNREACHABLE(); 10142 } 10143 return (ISC_R_SUCCESS); 10144} 10145 10146/* 10147 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or 10148 * a KEYDATA rdataset from the key zone. 10149 * 10150 * 'rr' contains either a DNSKEY record, or a KEYDATA record 10151 * 10152 * After normalizing keys to the same format (DNSKEY, with revoke bit 10153 * cleared), return true if a key that matches 'rr' is found in 10154 * 'rdset', or false if not. 10155 */ 10156 10157static bool 10158matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) { 10159 unsigned char data1[4096], data2[4096]; 10160 dns_rdata_t rdata, rdata1, rdata2; 10161 isc_result_t result; 10162 10163 dns_rdata_init(&rdata); 10164 dns_rdata_init(&rdata1); 10165 dns_rdata_init(&rdata2); 10166 10167 result = normalize_key(rr, &rdata1, data1, sizeof(data1)); 10168 if (result != ISC_R_SUCCESS) { 10169 return (false); 10170 } 10171 10172 for (result = dns_rdataset_first(rdset); result == ISC_R_SUCCESS; 10173 result = dns_rdataset_next(rdset)) 10174 { 10175 dns_rdata_reset(&rdata); 10176 dns_rdataset_current(rdset, &rdata); 10177 result = normalize_key(&rdata, &rdata2, data2, sizeof(data2)); 10178 if (result != ISC_R_SUCCESS) { 10179 continue; 10180 } 10181 if (dns_rdata_compare(&rdata1, &rdata2) == 0) { 10182 return (true); 10183 } 10184 } 10185 10186 return (false); 10187} 10188 10189/* 10190 * Calculate the refresh interval for a keydata zone, per 10191 * RFC5011: MAX(1 hr, 10192 * MIN(15 days, 10193 * 1/2 * OrigTTL, 10194 * 1/2 * RRSigExpirationInterval)) 10195 * or for retries: MAX(1 hr, 10196 * MIN(1 day, 10197 * 1/10 * OrigTTL, 10198 * 1/10 * RRSigExpirationInterval)) 10199 */ 10200static isc_stdtime_t 10201refresh_time(dns_keyfetch_t *kfetch, bool retry) { 10202 isc_result_t result; 10203 uint32_t t; 10204 dns_rdataset_t *rdset; 10205 dns_rdata_t sigrr = DNS_RDATA_INIT; 10206 dns_rdata_sig_t sig; 10207 isc_stdtime_t now; 10208 10209 isc_stdtime_get(&now); 10210 10211 if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) { 10212 rdset = &kfetch->dnskeysigset; 10213 } else { 10214 return (now + dns_zone_mkey_hour); 10215 } 10216 10217 result = dns_rdataset_first(rdset); 10218 if (result != ISC_R_SUCCESS) { 10219 return (now + dns_zone_mkey_hour); 10220 } 10221 10222 dns_rdataset_current(rdset, &sigrr); 10223 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 10224 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10225 10226 if (!retry) { 10227 t = sig.originalttl / 2; 10228 10229 if (isc_serial_gt(sig.timeexpire, now)) { 10230 uint32_t exp = (sig.timeexpire - now) / 2; 10231 if (t > exp) { 10232 t = exp; 10233 } 10234 } 10235 10236 if (t > (15 * dns_zone_mkey_day)) { 10237 t = (15 * dns_zone_mkey_day); 10238 } 10239 10240 if (t < dns_zone_mkey_hour) { 10241 t = dns_zone_mkey_hour; 10242 } 10243 } else { 10244 t = sig.originalttl / 10; 10245 10246 if (isc_serial_gt(sig.timeexpire, now)) { 10247 uint32_t exp = (sig.timeexpire - now) / 10; 10248 if (t > exp) { 10249 t = exp; 10250 } 10251 } 10252 10253 if (t > dns_zone_mkey_day) { 10254 t = dns_zone_mkey_day; 10255 } 10256 10257 if (t < dns_zone_mkey_hour) { 10258 t = dns_zone_mkey_hour; 10259 } 10260 } 10261 10262 return (now + t); 10263} 10264 10265/* 10266 * This routine is called when no changes are needed in a KEYDATA 10267 * record except to simply update the refresh timer. Caller should 10268 * hold zone lock. 10269 */ 10270static isc_result_t 10271minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) { 10272 isc_result_t result; 10273 isc_buffer_t keyb; 10274 unsigned char key_buf[4096]; 10275 dns_rdata_t rdata = DNS_RDATA_INIT; 10276 dns_rdata_keydata_t keydata; 10277 dns_name_t *name; 10278 dns_zone_t *zone = kfetch->zone; 10279 isc_stdtime_t now; 10280 10281 name = dns_fixedname_name(&kfetch->name); 10282 isc_stdtime_get(&now); 10283 10284 for (result = dns_rdataset_first(&kfetch->keydataset); 10285 result == ISC_R_SUCCESS; 10286 result = dns_rdataset_next(&kfetch->keydataset)) 10287 { 10288 dns_rdata_reset(&rdata); 10289 dns_rdataset_current(&kfetch->keydataset, &rdata); 10290 10291 /* Delete old version */ 10292 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL, name, 10293 0, &rdata)); 10294 10295 /* Update refresh timer */ 10296 result = dns_rdata_tostruct(&rdata, &keydata, NULL); 10297 if (result == ISC_R_UNEXPECTEDEND) { 10298 continue; 10299 } 10300 if (result != ISC_R_SUCCESS) { 10301 goto failure; 10302 } 10303 keydata.refresh = refresh_time(kfetch, true); 10304 set_refreshkeytimer(zone, &keydata, now, false); 10305 10306 dns_rdata_reset(&rdata); 10307 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10308 CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass, 10309 dns_rdatatype_keydata, &keydata, 10310 &keyb)); 10311 10312 /* Insert updated version */ 10313 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD, name, 10314 0, &rdata)); 10315 } 10316 result = ISC_R_SUCCESS; 10317failure: 10318 return (result); 10319} 10320 10321/* 10322 * Verify that DNSKEY set is signed by the key specified in 'keydata'. 10323 */ 10324static bool 10325revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) { 10326 isc_result_t result; 10327 dns_name_t *keyname; 10328 isc_mem_t *mctx; 10329 dns_rdata_t sigrr = DNS_RDATA_INIT; 10330 dns_rdata_t rr = DNS_RDATA_INIT; 10331 dns_rdata_rrsig_t sig; 10332 dns_rdata_dnskey_t dnskey; 10333 dst_key_t *dstkey = NULL; 10334 unsigned char key_buf[4096]; 10335 isc_buffer_t keyb; 10336 bool answer = false; 10337 10338 REQUIRE(kfetch != NULL && keydata != NULL); 10339 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset)); 10340 10341 keyname = dns_fixedname_name(&kfetch->name); 10342 mctx = kfetch->zone->view->mctx; 10343 10344 /* Generate a key from keydata */ 10345 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10346 dns_keydata_todnskey(keydata, &dnskey, NULL); 10347 dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey, 10348 &dnskey, &keyb); 10349 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey); 10350 if (result != ISC_R_SUCCESS) { 10351 return (false); 10352 } 10353 10354 /* See if that key generated any of the signatures */ 10355 for (result = dns_rdataset_first(&kfetch->dnskeysigset); 10356 result == ISC_R_SUCCESS; 10357 result = dns_rdataset_next(&kfetch->dnskeysigset)) 10358 { 10359 dns_fixedname_t fixed; 10360 dns_fixedname_init(&fixed); 10361 10362 dns_rdata_reset(&sigrr); 10363 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr); 10364 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 10365 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10366 10367 if (dst_key_alg(dstkey) == sig.algorithm && 10368 dst_key_rid(dstkey) == sig.keyid) 10369 { 10370 result = dns_dnssec_verify( 10371 keyname, &kfetch->dnskeyset, dstkey, false, 0, 10372 mctx, &sigrr, dns_fixedname_name(&fixed)); 10373 10374 dnssec_log(kfetch->zone, ISC_LOG_DEBUG(3), 10375 "Confirm revoked DNSKEY is self-signed: %s", 10376 dns_result_totext(result)); 10377 10378 if (result == ISC_R_SUCCESS) { 10379 answer = true; 10380 break; 10381 } 10382 } 10383 } 10384 10385 dst_key_free(&dstkey); 10386 return (answer); 10387} 10388 10389/* 10390 * A DNSKEY set has been fetched from the zone apex of a zone whose trust 10391 * anchors are being managed; scan the keyset, and update the key zone and the 10392 * local trust anchors according to RFC5011. 10393 */ 10394static void 10395keyfetch_done(isc_task_t *task, isc_event_t *event) { 10396 isc_result_t result, eresult; 10397 dns_fetchevent_t *devent; 10398 dns_keyfetch_t *kfetch; 10399 dns_zone_t *zone; 10400 isc_mem_t *mctx = NULL; 10401 dns_keytable_t *secroots = NULL; 10402 dns_dbversion_t *ver = NULL; 10403 dns_diff_t diff; 10404 bool alldone = false; 10405 bool commit = false; 10406 dns_name_t *keyname = NULL; 10407 dns_rdata_t sigrr = DNS_RDATA_INIT; 10408 dns_rdata_t dnskeyrr = DNS_RDATA_INIT; 10409 dns_rdata_t keydatarr = DNS_RDATA_INIT; 10410 dns_rdata_rrsig_t sig; 10411 dns_rdata_dnskey_t dnskey; 10412 dns_rdata_keydata_t keydata; 10413 bool initializing; 10414 char namebuf[DNS_NAME_FORMATSIZE]; 10415 unsigned char key_buf[4096]; 10416 isc_buffer_t keyb; 10417 dst_key_t *dstkey = NULL; 10418 isc_stdtime_t now; 10419 int pending = 0; 10420 bool secure = false, initial = false; 10421 bool free_needed; 10422 dns_keynode_t *keynode = NULL; 10423 dns_rdataset_t *dnskeys = NULL, *dnskeysigs = NULL; 10424 dns_rdataset_t *keydataset = NULL, dsset; 10425 10426 UNUSED(task); 10427 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE); 10428 INSIST(event->ev_arg != NULL); 10429 10430 kfetch = event->ev_arg; 10431 zone = kfetch->zone; 10432 mctx = kfetch->mctx; 10433 keyname = dns_fixedname_name(&kfetch->name); 10434 dnskeys = &kfetch->dnskeyset; 10435 dnskeysigs = &kfetch->dnskeysigset; 10436 keydataset = &kfetch->keydataset; 10437 10438 devent = (dns_fetchevent_t *)event; 10439 eresult = devent->result; 10440 10441 /* Free resources which are not of interest */ 10442 if (devent->node != NULL) { 10443 dns_db_detachnode(devent->db, &devent->node); 10444 } 10445 if (devent->db != NULL) { 10446 dns_db_detach(&devent->db); 10447 } 10448 isc_event_free(&event); 10449 dns_resolver_destroyfetch(&kfetch->fetch); 10450 10451 LOCK_ZONE(zone); 10452 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) { 10453 goto cleanup; 10454 } 10455 10456 isc_stdtime_get(&now); 10457 dns_name_format(keyname, namebuf, sizeof(namebuf)); 10458 10459 result = dns_view_getsecroots(zone->view, &secroots); 10460 INSIST(result == ISC_R_SUCCESS); 10461 10462 dns_diff_init(mctx, &diff); 10463 10464 CHECK(dns_db_newversion(kfetch->db, &ver)); 10465 10466 zone->refreshkeycount--; 10467 alldone = (zone->refreshkeycount == 0); 10468 10469 if (alldone) { 10470 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 10471 } 10472 10473 dnssec_log(zone, ISC_LOG_DEBUG(3), 10474 "Returned from key fetch in keyfetch_done() for '%s': %s", 10475 namebuf, dns_result_totext(eresult)); 10476 10477 /* Fetch failed */ 10478 if (eresult != ISC_R_SUCCESS || !dns_rdataset_isassociated(dnskeys)) { 10479 dnssec_log(zone, ISC_LOG_WARNING, 10480 "Unable to fetch DNSKEY set '%s': %s", namebuf, 10481 dns_result_totext(eresult)); 10482 CHECK(minimal_update(kfetch, ver, &diff)); 10483 goto done; 10484 } 10485 10486 /* No RRSIGs found */ 10487 if (!dns_rdataset_isassociated(dnskeysigs)) { 10488 dnssec_log(zone, ISC_LOG_WARNING, 10489 "No DNSKEY RRSIGs found for '%s': %s", namebuf, 10490 dns_result_totext(eresult)); 10491 CHECK(minimal_update(kfetch, ver, &diff)); 10492 goto done; 10493 } 10494 10495 /* 10496 * Clear any cached trust level, as we need to run validation 10497 * over again; trusted keys might have changed. 10498 */ 10499 dnskeys->trust = dnskeysigs->trust = dns_trust_none; 10500 10501 /* Look up the trust anchor */ 10502 result = dns_keytable_find(secroots, keyname, &keynode); 10503 if (result != ISC_R_SUCCESS) { 10504 goto anchors_done; 10505 } 10506 10507 /* 10508 * If the keynode has a DS trust anchor, use it for verification. 10509 */ 10510 dns_rdataset_init(&dsset); 10511 if (dns_keynode_dsset(keynode, &dsset)) { 10512 for (result = dns_rdataset_first(dnskeysigs); 10513 result == ISC_R_SUCCESS; 10514 result = dns_rdataset_next(dnskeysigs)) 10515 { 10516 isc_result_t tresult; 10517 dns_rdata_t keyrdata = DNS_RDATA_INIT; 10518 10519 dns_rdata_reset(&sigrr); 10520 dns_rdataset_current(dnskeysigs, &sigrr); 10521 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 10522 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10523 10524 for (tresult = dns_rdataset_first(&dsset); 10525 tresult == ISC_R_SUCCESS; 10526 tresult = dns_rdataset_next(&dsset)) 10527 { 10528 dns_rdata_t dsrdata = DNS_RDATA_INIT; 10529 dns_rdata_ds_t ds; 10530 10531 dns_rdata_reset(&dsrdata); 10532 dns_rdataset_current(&dsset, &dsrdata); 10533 tresult = dns_rdata_tostruct(&dsrdata, &ds, 10534 NULL); 10535 RUNTIME_CHECK(tresult == ISC_R_SUCCESS); 10536 10537 if (ds.key_tag != sig.keyid || 10538 ds.algorithm != sig.algorithm) 10539 { 10540 continue; 10541 } 10542 10543 result = dns_dnssec_matchdskey( 10544 keyname, &dsrdata, dnskeys, &keyrdata); 10545 if (result == ISC_R_SUCCESS) { 10546 break; 10547 } 10548 } 10549 10550 if (tresult == ISC_R_NOMORE) { 10551 continue; 10552 } 10553 10554 result = dns_dnssec_keyfromrdata(keyname, &keyrdata, 10555 mctx, &dstkey); 10556 if (result != ISC_R_SUCCESS) { 10557 continue; 10558 } 10559 10560 result = dns_dnssec_verify(keyname, dnskeys, dstkey, 10561 false, 0, mctx, &sigrr, 10562 NULL); 10563 dst_key_free(&dstkey); 10564 10565 dnssec_log(zone, ISC_LOG_DEBUG(3), 10566 "Verifying DNSKEY set for zone " 10567 "'%s' using DS %d/%d: %s", 10568 namebuf, sig.keyid, sig.algorithm, 10569 dns_result_totext(result)); 10570 10571 if (result == ISC_R_SUCCESS) { 10572 dnskeys->trust = dns_trust_secure; 10573 dnskeysigs->trust = dns_trust_secure; 10574 initial = dns_keynode_initial(keynode); 10575 dns_keynode_trust(keynode); 10576 secure = true; 10577 break; 10578 } 10579 } 10580 dns_rdataset_disassociate(&dsset); 10581 } 10582 10583anchors_done: 10584 if (keynode != NULL) { 10585 dns_keytable_detachkeynode(secroots, &keynode); 10586 } 10587 10588 /* 10589 * If we were not able to verify the answer using the current 10590 * trusted keys then all we can do is look at any revoked keys. 10591 */ 10592 if (!secure) { 10593 dnssec_log(zone, ISC_LOG_INFO, 10594 "DNSKEY set for zone '%s' could not be verified " 10595 "with current keys", 10596 namebuf); 10597 } 10598 10599 /* 10600 * First scan keydataset to find keys that are not in dnskeyset 10601 * - Missing keys which are not scheduled for removal, 10602 * log a warning 10603 * - Missing keys which are scheduled for removal and 10604 * the remove hold-down timer has completed should 10605 * be removed from the key zone 10606 * - Missing keys whose acceptance timers have not yet 10607 * completed, log a warning and reset the acceptance 10608 * timer to 30 days in the future 10609 * - All keys not being removed have their refresh timers 10610 * updated 10611 */ 10612 initializing = true; 10613 for (result = dns_rdataset_first(keydataset); result == ISC_R_SUCCESS; 10614 result = dns_rdataset_next(keydataset)) 10615 { 10616 dns_keytag_t keytag; 10617 10618 dns_rdata_reset(&keydatarr); 10619 dns_rdataset_current(keydataset, &keydatarr); 10620 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); 10621 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10622 10623 dns_keydata_todnskey(&keydata, &dnskey, NULL); 10624 result = compute_tag(keyname, &dnskey, mctx, &keytag); 10625 if (result != ISC_R_SUCCESS) { 10626 /* 10627 * Skip if we cannot compute the key tag. 10628 * This may happen if the algorithm is unsupported 10629 */ 10630 dns_zone_log(zone, ISC_LOG_ERROR, 10631 "Cannot compute tag for key in zone %s: " 10632 "%s " 10633 "(skipping)", 10634 namebuf, dns_result_totext(result)); 10635 continue; 10636 } 10637 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10638 10639 /* 10640 * If any keydata record has a nonzero add holddown, then 10641 * there was a pre-existing trust anchor for this domain; 10642 * that means we are *not* initializing it and shouldn't 10643 * automatically trust all the keys we find at the zone apex. 10644 */ 10645 initializing = initializing && (keydata.addhd == 0); 10646 10647 if (!matchkey(dnskeys, &keydatarr)) { 10648 bool deletekey = false; 10649 10650 if (!secure) { 10651 if (keydata.removehd != 0 && 10652 keydata.removehd <= now) 10653 { 10654 deletekey = true; 10655 } 10656 } else if (keydata.addhd == 0) { 10657 deletekey = true; 10658 } else if (keydata.addhd > now) { 10659 dnssec_log(zone, ISC_LOG_INFO, 10660 "Pending key %d for zone %s " 10661 "unexpectedly missing " 10662 "restarting 30-day acceptance " 10663 "timer", 10664 keytag, namebuf); 10665 if (keydata.addhd < now + dns_zone_mkey_month) { 10666 keydata.addhd = now + 10667 dns_zone_mkey_month; 10668 } 10669 keydata.refresh = refresh_time(kfetch, false); 10670 } else if (keydata.removehd == 0) { 10671 dnssec_log(zone, ISC_LOG_INFO, 10672 "Active key %d for zone %s " 10673 "unexpectedly missing", 10674 keytag, namebuf); 10675 keydata.refresh = now + dns_zone_mkey_hour; 10676 } else if (keydata.removehd <= now) { 10677 deletekey = true; 10678 dnssec_log(zone, ISC_LOG_INFO, 10679 "Revoked key %d for zone %s " 10680 "missing: deleting from " 10681 "managed keys database", 10682 keytag, namebuf); 10683 } else { 10684 keydata.refresh = refresh_time(kfetch, false); 10685 } 10686 10687 if (secure || deletekey) { 10688 /* Delete old version */ 10689 CHECK(update_one_rr(kfetch->db, ver, &diff, 10690 DNS_DIFFOP_DEL, keyname, 0, 10691 &keydatarr)); 10692 } 10693 10694 if (!secure || deletekey) { 10695 continue; 10696 } 10697 10698 dns_rdata_reset(&keydatarr); 10699 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10700 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 10701 dns_rdatatype_keydata, &keydata, 10702 &keyb); 10703 10704 /* Insert updated version */ 10705 CHECK(update_one_rr(kfetch->db, ver, &diff, 10706 DNS_DIFFOP_ADD, keyname, 0, 10707 &keydatarr)); 10708 10709 set_refreshkeytimer(zone, &keydata, now, false); 10710 } 10711 } 10712 10713 /* 10714 * Next scan dnskeyset: 10715 * - If new keys are found (i.e., lacking a match in keydataset) 10716 * add them to the key zone and set the acceptance timer 10717 * to 30 days in the future (or to immediately if we've 10718 * determined that we're initializing the zone for the 10719 * first time) 10720 * - Previously-known keys that have been revoked 10721 * must be scheduled for removal from the key zone (or, 10722 * if they hadn't been accepted as trust anchors yet 10723 * anyway, removed at once) 10724 * - Previously-known unrevoked keys whose acceptance timers 10725 * have completed are promoted to trust anchors 10726 * - All keys not being removed have their refresh 10727 * timers updated 10728 */ 10729 for (result = dns_rdataset_first(dnskeys); result == ISC_R_SUCCESS; 10730 result = dns_rdataset_next(dnskeys)) 10731 { 10732 bool revoked = false; 10733 bool newkey = false; 10734 bool updatekey = false; 10735 bool deletekey = false; 10736 bool trustkey = false; 10737 dns_keytag_t keytag; 10738 10739 dns_rdata_reset(&dnskeyrr); 10740 dns_rdataset_current(dnskeys, &dnskeyrr); 10741 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 10742 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10743 10744 /* Skip ZSK's */ 10745 if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) { 10746 continue; 10747 } 10748 10749 result = compute_tag(keyname, &dnskey, mctx, &keytag); 10750 if (result != ISC_R_SUCCESS) { 10751 /* 10752 * Skip if we cannot compute the key tag. 10753 * This may happen if the algorithm is unsupported 10754 */ 10755 dns_zone_log(zone, ISC_LOG_ERROR, 10756 "Cannot compute tag for key in zone %s: " 10757 "%s " 10758 "(skipping)", 10759 namebuf, dns_result_totext(result)); 10760 continue; 10761 } 10762 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10763 10764 revoked = ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0); 10765 10766 if (matchkey(keydataset, &dnskeyrr)) { 10767 dns_rdata_reset(&keydatarr); 10768 dns_rdataset_current(keydataset, &keydatarr); 10769 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); 10770 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10771 10772 if (revoked && revocable(kfetch, &keydata)) { 10773 if (keydata.addhd > now) { 10774 /* 10775 * Key wasn't trusted yet, and now 10776 * it's been revoked? Just remove it 10777 */ 10778 deletekey = true; 10779 dnssec_log(zone, ISC_LOG_INFO, 10780 "Pending key %d for " 10781 "zone %s is now revoked: " 10782 "deleting from the " 10783 "managed keys database", 10784 keytag, namebuf); 10785 } else if (keydata.removehd == 0) { 10786 /* 10787 * Remove key from secroots. 10788 */ 10789 dns_view_untrust(zone->view, keyname, 10790 &dnskey); 10791 10792 /* If initializing, delete now */ 10793 if (keydata.addhd == 0) { 10794 deletekey = true; 10795 } else { 10796 keydata.removehd = 10797 now + 10798 dns_zone_mkey_month; 10799 keydata.flags |= 10800 DNS_KEYFLAG_REVOKE; 10801 } 10802 10803 dnssec_log(zone, ISC_LOG_INFO, 10804 "Trusted key %d for " 10805 "zone %s is now revoked", 10806 keytag, namebuf); 10807 } else if (keydata.removehd < now) { 10808 /* Scheduled for removal */ 10809 deletekey = true; 10810 10811 dnssec_log(zone, ISC_LOG_INFO, 10812 "Revoked key %d for " 10813 "zone %s removal timer " 10814 "complete: deleting from " 10815 "the managed keys database", 10816 keytag, namebuf); 10817 } 10818 } else if (revoked && keydata.removehd == 0) { 10819 dnssec_log(zone, ISC_LOG_WARNING, 10820 "Active key %d for zone " 10821 "%s is revoked but " 10822 "did not self-sign; " 10823 "ignoring", 10824 keytag, namebuf); 10825 continue; 10826 } else if (secure) { 10827 if (keydata.removehd != 0) { 10828 /* 10829 * Key isn't revoked--but it 10830 * seems it used to be. 10831 * Remove it now and add it 10832 * back as if it were a fresh key, 10833 * with a 30-day acceptance timer. 10834 */ 10835 deletekey = true; 10836 newkey = true; 10837 keydata.removehd = 0; 10838 keydata.addhd = now + 10839 dns_zone_mkey_month; 10840 10841 dnssec_log(zone, ISC_LOG_INFO, 10842 "Revoked key %d for " 10843 "zone %s has returned: " 10844 "starting 30-day " 10845 "acceptance timer", 10846 keytag, namebuf); 10847 } else if (keydata.addhd > now) { 10848 pending++; 10849 } else if (keydata.addhd == 0) { 10850 keydata.addhd = now; 10851 } 10852 10853 if (keydata.addhd <= now) { 10854 trustkey = true; 10855 dnssec_log(zone, ISC_LOG_INFO, 10856 "Key %d for zone %s " 10857 "is now trusted (%s)", 10858 keytag, namebuf, 10859 initial ? "initializing key " 10860 "verified" 10861 : "acceptance timer " 10862 "complete"); 10863 } 10864 } else if (keydata.addhd > now) { 10865 /* 10866 * Not secure, and key is pending: 10867 * reset the acceptance timer 10868 */ 10869 pending++; 10870 keydata.addhd = now + dns_zone_mkey_month; 10871 dnssec_log(zone, ISC_LOG_INFO, 10872 "Pending key %d " 10873 "for zone %s was " 10874 "not validated: restarting " 10875 "30-day acceptance timer", 10876 keytag, namebuf); 10877 } 10878 10879 if (!deletekey && !newkey) { 10880 updatekey = true; 10881 } 10882 } else if (secure) { 10883 /* 10884 * Key wasn't in the key zone but it's 10885 * revoked now anyway, so just skip it 10886 */ 10887 if (revoked) { 10888 continue; 10889 } 10890 10891 /* Key wasn't in the key zone: add it */ 10892 newkey = true; 10893 10894 if (initializing) { 10895 dnssec_log(zone, ISC_LOG_WARNING, 10896 "Initializing automatic trust " 10897 "anchor management for zone '%s'; " 10898 "DNSKEY ID %d is now trusted, " 10899 "waiving the normal 30-day " 10900 "waiting period.", 10901 namebuf, keytag); 10902 trustkey = true; 10903 } else { 10904 dnssec_log(zone, ISC_LOG_INFO, 10905 "New key %d observed " 10906 "for zone '%s': " 10907 "starting 30-day " 10908 "acceptance timer", 10909 keytag, namebuf); 10910 } 10911 } else { 10912 /* 10913 * No previously known key, and the key is not 10914 * secure, so skip it. 10915 */ 10916 continue; 10917 } 10918 10919 /* Delete old version */ 10920 if (deletekey || !newkey) { 10921 CHECK(update_one_rr(kfetch->db, ver, &diff, 10922 DNS_DIFFOP_DEL, keyname, 0, 10923 &keydatarr)); 10924 } 10925 10926 if (updatekey) { 10927 /* Set refresh timer */ 10928 keydata.refresh = refresh_time(kfetch, false); 10929 dns_rdata_reset(&keydatarr); 10930 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10931 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 10932 dns_rdatatype_keydata, &keydata, 10933 &keyb); 10934 10935 /* Insert updated version */ 10936 CHECK(update_one_rr(kfetch->db, ver, &diff, 10937 DNS_DIFFOP_ADD, keyname, 0, 10938 &keydatarr)); 10939 } else if (newkey) { 10940 /* Convert DNSKEY to KEYDATA */ 10941 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 10942 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10943 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0, 10944 NULL); 10945 keydata.addhd = initializing 10946 ? now 10947 : now + dns_zone_mkey_month; 10948 keydata.refresh = refresh_time(kfetch, false); 10949 dns_rdata_reset(&keydatarr); 10950 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10951 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 10952 dns_rdatatype_keydata, &keydata, 10953 &keyb); 10954 10955 /* Insert into key zone */ 10956 CHECK(update_one_rr(kfetch->db, ver, &diff, 10957 DNS_DIFFOP_ADD, keyname, 0, 10958 &keydatarr)); 10959 } 10960 10961 if (trustkey) { 10962 /* Trust this key. */ 10963 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 10964 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10965 trust_key(zone, keyname, &dnskey, false); 10966 } 10967 10968 if (secure && !deletekey) { 10969 INSIST(newkey || updatekey); 10970 set_refreshkeytimer(zone, &keydata, now, false); 10971 } 10972 } 10973 10974 /* 10975 * RFC5011 says, "A trust point that has all of its trust anchors 10976 * revoked is considered deleted and is treated as if the trust 10977 * point was never configured." But if someone revoked their 10978 * active key before the standby was trusted, that would mean the 10979 * zone would suddenly be nonsecured. We avoid this by checking to 10980 * see if there's pending keydata. If so, we put a null key in 10981 * the security roots; then all queries to the zone will fail. 10982 */ 10983 if (pending != 0) { 10984 fail_secure(zone, keyname); 10985 } 10986 10987done: 10988 if (!ISC_LIST_EMPTY(diff.tuples)) { 10989 /* Write changes to journal file. */ 10990 CHECK(update_soa_serial(zone, kfetch->db, ver, &diff, mctx, 10991 zone->updatemethod)); 10992 CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done")); 10993 commit = true; 10994 10995 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 10996 zone_needdump(zone, 30); 10997 } else if (result == ISC_R_NOMORE) { 10998 /* 10999 * If "updatekey" was true for all keys found in the DNSKEY 11000 * response and the previous update of those keys happened 11001 * during the same second (only possible if a key refresh was 11002 * externally triggered), it may happen that all relevant 11003 * update_one_rr() calls will return ISC_R_SUCCESS, but 11004 * diff.tuples will remain empty. Reset result to 11005 * ISC_R_SUCCESS to prevent a bogus warning from being logged. 11006 */ 11007 result = ISC_R_SUCCESS; 11008 } 11009 11010failure: 11011 if (result != ISC_R_SUCCESS) { 11012 dnssec_log(zone, ISC_LOG_ERROR, 11013 "error during managed-keys processing (%s): " 11014 "DNSSEC validation may be at risk", 11015 isc_result_totext(result)); 11016 } 11017 dns_diff_clear(&diff); 11018 if (ver != NULL) { 11019 dns_db_closeversion(kfetch->db, &ver, commit); 11020 } 11021 11022cleanup: 11023 dns_db_detach(&kfetch->db); 11024 11025 /* The zone must be managed */ 11026 INSIST(kfetch->zone->task != NULL); 11027 isc_refcount_decrement(&zone->irefs); 11028 11029 if (dns_rdataset_isassociated(keydataset)) { 11030 dns_rdataset_disassociate(keydataset); 11031 } 11032 if (dns_rdataset_isassociated(dnskeys)) { 11033 dns_rdataset_disassociate(dnskeys); 11034 } 11035 if (dns_rdataset_isassociated(dnskeysigs)) { 11036 dns_rdataset_disassociate(dnskeysigs); 11037 } 11038 11039 dns_name_free(keyname, mctx); 11040 isc_mem_putanddetach(&kfetch->mctx, kfetch, sizeof(dns_keyfetch_t)); 11041 11042 if (secroots != NULL) { 11043 dns_keytable_detach(&secroots); 11044 } 11045 11046 free_needed = exit_check(zone); 11047 UNLOCK_ZONE(zone); 11048 11049 if (free_needed) { 11050 zone_free(zone); 11051 } 11052 11053 INSIST(ver == NULL); 11054} 11055 11056static void 11057retry_keyfetch(dns_keyfetch_t *kfetch, dns_name_t *kname) { 11058 isc_time_t timenow, timethen; 11059 dns_zone_t *zone = kfetch->zone; 11060 bool free_needed; 11061 char namebuf[DNS_NAME_FORMATSIZE]; 11062 11063 dns_name_format(kname, namebuf, sizeof(namebuf)); 11064 dnssec_log(zone, ISC_LOG_WARNING, 11065 "Failed to create fetch for %s DNSKEY update", namebuf); 11066 11067 /* 11068 * Error during a key fetch; cancel and retry in an hour. 11069 */ 11070 LOCK_ZONE(zone); 11071 zone->refreshkeycount--; 11072 isc_refcount_decrement(&zone->irefs); 11073 dns_db_detach(&kfetch->db); 11074 dns_rdataset_disassociate(&kfetch->keydataset); 11075 dns_name_free(kname, zone->mctx); 11076 isc_mem_putanddetach(&kfetch->mctx, kfetch, sizeof(*kfetch)); 11077 11078 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11079 /* Don't really retry if we are exiting */ 11080 char timebuf[80]; 11081 11082 TIME_NOW(&timenow); 11083 DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen); 11084 zone->refreshkeytime = timethen; 11085 zone_settimer(zone, &timenow); 11086 11087 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 11088 dnssec_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s", 11089 timebuf); 11090 } 11091 11092 free_needed = exit_check(zone); 11093 UNLOCK_ZONE(zone); 11094 11095 if (free_needed) { 11096 zone_free(zone); 11097 } 11098} 11099 11100static void 11101do_keyfetch(isc_task_t *task, isc_event_t *event) { 11102 isc_result_t result; 11103 dns_keyfetch_t *kfetch = (dns_keyfetch_t *)event->ev_arg; 11104 dns_name_t *kname = dns_fixedname_name(&kfetch->name); 11105 dns_zone_t *zone = kfetch->zone; 11106 11107 UNUSED(task); 11108 11109 isc_event_free(&event); 11110 11111 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11112 retry_keyfetch(kfetch, kname); 11113 return; 11114 } 11115 11116 /* 11117 * Use of DNS_FETCHOPT_NOCACHED is essential here. If it is not 11118 * set and the cache still holds a non-expired, validated version 11119 * of the RRset being queried for by the time the response is 11120 * received, the cached RRset will be passed to keyfetch_done() 11121 * instead of the one received in the response as the latter will 11122 * have a lower trust level due to not being validated until 11123 * keyfetch_done() is called. 11124 */ 11125 result = dns_resolver_createfetch( 11126 zone->view->resolver, kname, dns_rdatatype_dnskey, NULL, NULL, 11127 NULL, NULL, 0, 11128 DNS_FETCHOPT_NOVALIDATE | DNS_FETCHOPT_UNSHARED | 11129 DNS_FETCHOPT_NOCACHED, 11130 0, NULL, zone->task, keyfetch_done, kfetch, &kfetch->dnskeyset, 11131 &kfetch->dnskeysigset, &kfetch->fetch); 11132 11133 if (result != ISC_R_SUCCESS) { 11134 retry_keyfetch(kfetch, kname); 11135 } 11136} 11137 11138/* 11139 * Refresh the data in the key zone. Initiate a fetch to look up 11140 * DNSKEY records at the trust anchor name. 11141 */ 11142static void 11143zone_refreshkeys(dns_zone_t *zone) { 11144 const char me[] = "zone_refreshkeys"; 11145 isc_result_t result; 11146 dns_rriterator_t rrit; 11147 dns_db_t *db = NULL; 11148 dns_dbversion_t *ver = NULL; 11149 dns_diff_t diff; 11150 dns_rdata_t rdata = DNS_RDATA_INIT; 11151 dns_rdata_keydata_t kd; 11152 isc_stdtime_t now; 11153 bool commit = false; 11154 bool fetching = false; 11155 bool timerset = false; 11156 11157 ENTER; 11158 REQUIRE(zone->db != NULL); 11159 11160 isc_stdtime_get(&now); 11161 11162 LOCK_ZONE(zone); 11163 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11164 isc_time_settoepoch(&zone->refreshkeytime); 11165 UNLOCK_ZONE(zone); 11166 return; 11167 } 11168 11169 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 11170 dns_db_attach(zone->db, &db); 11171 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11172 11173 dns_diff_init(zone->mctx, &diff); 11174 11175 CHECK(dns_db_newversion(db, &ver)); 11176 11177 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING); 11178 11179 dns_rriterator_init(&rrit, db, ver, 0); 11180 for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS; 11181 result = dns_rriterator_nextrrset(&rrit)) 11182 { 11183 isc_stdtime_t timer = 0xffffffff; 11184 dns_name_t *name = NULL, *kname = NULL; 11185 dns_rdataset_t *kdset = NULL; 11186 uint32_t ttl; 11187 11188 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL); 11189 if (kdset == NULL || kdset->type != dns_rdatatype_keydata || 11190 !dns_rdataset_isassociated(kdset)) 11191 { 11192 continue; 11193 } 11194 11195 /* 11196 * Scan the stored keys looking for ones that need 11197 * removal or refreshing 11198 */ 11199 for (result = dns_rdataset_first(kdset); 11200 result == ISC_R_SUCCESS; result = dns_rdataset_next(kdset)) 11201 { 11202 dns_rdata_reset(&rdata); 11203 dns_rdataset_current(kdset, &rdata); 11204 result = dns_rdata_tostruct(&rdata, &kd, NULL); 11205 RUNTIME_CHECK(result == ISC_R_SUCCESS); 11206 11207 /* Removal timer expired? */ 11208 if (kd.removehd != 0 && kd.removehd < now) { 11209 dns_rriterator_pause(&rrit); 11210 CHECK(update_one_rr(db, ver, &diff, 11211 DNS_DIFFOP_DEL, name, ttl, 11212 &rdata)); 11213 continue; 11214 } 11215 11216 /* Acceptance timer expired? */ 11217 if (kd.addhd <= now) { 11218 timer = kd.addhd; 11219 } 11220 11221 /* Or do we just need to refresh the keyset? */ 11222 if (timer > kd.refresh) { 11223 timer = kd.refresh; 11224 } 11225 11226 dns_rriterator_pause(&rrit); 11227 set_refreshkeytimer(zone, &kd, now, false); 11228 timerset = true; 11229 } 11230 11231 if (timer > now) { 11232 continue; 11233 } 11234 11235 dns_rriterator_pause(&rrit); 11236 11237#ifdef ENABLE_AFL 11238 if (!dns_fuzzing_resolver) { 11239#endif /* ifdef ENABLE_AFL */ 11240 dns_keyfetch_t *kfetch = NULL; 11241 isc_event_t *e; 11242 11243 kfetch = isc_mem_get(zone->mctx, 11244 sizeof(dns_keyfetch_t)); 11245 *kfetch = (dns_keyfetch_t){ .zone = zone }; 11246 isc_mem_attach(zone->mctx, &kfetch->mctx); 11247 11248 zone->refreshkeycount++; 11249 isc_refcount_increment0(&zone->irefs); 11250 kname = dns_fixedname_initname(&kfetch->name); 11251 dns_name_dup(name, zone->mctx, kname); 11252 dns_rdataset_init(&kfetch->dnskeyset); 11253 dns_rdataset_init(&kfetch->dnskeysigset); 11254 dns_rdataset_init(&kfetch->keydataset); 11255 dns_rdataset_clone(kdset, &kfetch->keydataset); 11256 dns_db_attach(db, &kfetch->db); 11257 11258 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 11259 char namebuf[DNS_NAME_FORMATSIZE]; 11260 dns_name_format(kname, namebuf, 11261 sizeof(namebuf)); 11262 dnssec_log(zone, ISC_LOG_DEBUG(3), 11263 "Creating key fetch in " 11264 "zone_refreshkeys() for '%s'", 11265 namebuf); 11266 } 11267 11268 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE, 11269 do_keyfetch, kfetch, 11270 sizeof(isc_event_t)); 11271 isc_task_send(zone->task, &e); 11272 fetching = true; 11273#ifdef ENABLE_AFL 11274 } 11275#endif /* ifdef ENABLE_AFL */ 11276 } 11277 if (!ISC_LIST_EMPTY(diff.tuples)) { 11278 CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx, 11279 zone->updatemethod)); 11280 CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys")); 11281 commit = true; 11282 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 11283 zone_needdump(zone, 30); 11284 } 11285 11286failure: 11287 if (!timerset) { 11288 isc_time_settoepoch(&zone->refreshkeytime); 11289 } 11290 11291 if (!fetching) { 11292 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 11293 } 11294 11295 dns_diff_clear(&diff); 11296 if (ver != NULL) { 11297 dns_rriterator_destroy(&rrit); 11298 dns_db_closeversion(db, &ver, commit); 11299 } 11300 dns_db_detach(&db); 11301 11302 UNLOCK_ZONE(zone); 11303 11304 INSIST(ver == NULL); 11305} 11306 11307static void 11308zone_maintenance(dns_zone_t *zone) { 11309 const char me[] = "zone_maintenance"; 11310 isc_time_t now; 11311 isc_result_t result; 11312 bool dumping, load_pending, exiting, viewok; 11313 bool need_notify; 11314 11315 REQUIRE(DNS_ZONE_VALID(zone)); 11316 ENTER; 11317 11318 /* 11319 * Are we pending load/reload, exiting, or unconfigured 11320 * (e.g. because of a syntax failure in the config file)? 11321 * If so, don't attempt maintenance. 11322 */ 11323 LOCK_ZONE(zone); 11324 load_pending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING); 11325 exiting = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING); 11326 viewok = (zone->view != NULL && zone->view->adb != NULL); 11327 UNLOCK_ZONE(zone); 11328 11329 if (load_pending || exiting || !viewok) { 11330 return; 11331 } 11332 11333 TIME_NOW(&now); 11334 11335 /* 11336 * Expire check. 11337 */ 11338 switch (zone->type) { 11339 case dns_zone_redirect: 11340 if (zone->masters == NULL) { 11341 break; 11342 } 11343 FALLTHROUGH; 11344 case dns_zone_secondary: 11345 case dns_zone_mirror: 11346 case dns_zone_stub: 11347 LOCK_ZONE(zone); 11348 if (isc_time_compare(&now, &zone->expiretime) >= 0 && 11349 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 11350 { 11351 zone_expire(zone); 11352 zone->refreshtime = now; 11353 } 11354 UNLOCK_ZONE(zone); 11355 break; 11356 default: 11357 break; 11358 } 11359 11360 /* 11361 * Up to date check. 11362 */ 11363 switch (zone->type) { 11364 case dns_zone_redirect: 11365 if (zone->masters == NULL) { 11366 break; 11367 } 11368 FALLTHROUGH; 11369 case dns_zone_secondary: 11370 case dns_zone_mirror: 11371 case dns_zone_stub: 11372 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && 11373 isc_time_compare(&now, &zone->refreshtime) >= 0) 11374 { 11375 dns_zone_refresh(zone); 11376 } 11377 break; 11378 default: 11379 break; 11380 } 11381 11382 /* 11383 * Secondaries send notifies before backing up to disk, 11384 * primaries after. 11385 */ 11386 LOCK_ZONE(zone); 11387 need_notify = (zone->type == dns_zone_secondary || 11388 zone->type == dns_zone_mirror) && 11389 (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 11390 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) && 11391 (isc_time_compare(&now, &zone->notifytime) >= 0); 11392 UNLOCK_ZONE(zone); 11393 11394 if (need_notify) { 11395 zone_notify(zone, &now); 11396 } 11397 11398 /* 11399 * Do we need to consolidate the backing store? 11400 */ 11401 switch (zone->type) { 11402 case dns_zone_primary: 11403 case dns_zone_secondary: 11404 case dns_zone_mirror: 11405 case dns_zone_key: 11406 case dns_zone_redirect: 11407 case dns_zone_stub: 11408 LOCK_ZONE(zone); 11409 if (zone->masterfile != NULL && 11410 isc_time_compare(&now, &zone->dumptime) >= 0 && 11411 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 11412 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) 11413 { 11414 dumping = was_dumping(zone); 11415 } else { 11416 dumping = true; 11417 } 11418 UNLOCK_ZONE(zone); 11419 if (!dumping) { 11420 result = zone_dump(zone, true); /* task locked */ 11421 if (result != ISC_R_SUCCESS) { 11422 dns_zone_log(zone, ISC_LOG_WARNING, 11423 "dump failed: %s", 11424 dns_result_totext(result)); 11425 } 11426 } 11427 break; 11428 default: 11429 break; 11430 } 11431 11432 /* 11433 * Master/redirect zones send notifies now, if needed 11434 */ 11435 switch (zone->type) { 11436 case dns_zone_primary: 11437 case dns_zone_redirect: 11438 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 11439 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) && 11440 isc_time_compare(&now, &zone->notifytime) >= 0) 11441 { 11442 zone_notify(zone, &now); 11443 } 11444 default: 11445 break; 11446 } 11447 11448 /* 11449 * Do we need to refresh keys? 11450 */ 11451 switch (zone->type) { 11452 case dns_zone_key: 11453 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) { 11454 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 11455 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) 11456 { 11457 zone_refreshkeys(zone); 11458 } 11459 } 11460 break; 11461 case dns_zone_primary: 11462 if (!isc_time_isepoch(&zone->refreshkeytime) && 11463 isc_time_compare(&now, &zone->refreshkeytime) >= 0 && 11464 zone->rss_event == NULL) 11465 { 11466 zone_rekey(zone); 11467 } 11468 default: 11469 break; 11470 } 11471 11472 switch (zone->type) { 11473 case dns_zone_primary: 11474 case dns_zone_redirect: 11475 case dns_zone_secondary: 11476 /* 11477 * Do we need to sign/resign some RRsets? 11478 */ 11479 if (zone->rss_event != NULL) { 11480 break; 11481 } 11482 if (!isc_time_isepoch(&zone->signingtime) && 11483 isc_time_compare(&now, &zone->signingtime) >= 0) 11484 { 11485 zone_sign(zone); 11486 } else if (!isc_time_isepoch(&zone->resigntime) && 11487 isc_time_compare(&now, &zone->resigntime) >= 0) 11488 { 11489 zone_resigninc(zone); 11490 } else if (!isc_time_isepoch(&zone->nsec3chaintime) && 11491 isc_time_compare(&now, &zone->nsec3chaintime) >= 0) 11492 { 11493 zone_nsec3chain(zone); 11494 } 11495 /* 11496 * Do we need to issue a key expiry warning? 11497 */ 11498 if (!isc_time_isepoch(&zone->keywarntime) && 11499 isc_time_compare(&now, &zone->keywarntime) >= 0) 11500 { 11501 set_key_expiry_warning(zone, zone->key_expiry, 11502 isc_time_seconds(&now)); 11503 } 11504 break; 11505 11506 default: 11507 break; 11508 } 11509 LOCK_ZONE(zone); 11510 zone_settimer(zone, &now); 11511 UNLOCK_ZONE(zone); 11512} 11513 11514void 11515dns_zone_markdirty(dns_zone_t *zone) { 11516 uint32_t serial; 11517 isc_result_t result = ISC_R_SUCCESS; 11518 dns_zone_t *secure = NULL; 11519 11520 /* 11521 * Obtaining a lock on the zone->secure (see zone_send_secureserial) 11522 * could result in a deadlock due to a LOR so we will spin if we 11523 * can't obtain the both locks. 11524 */ 11525again: 11526 LOCK_ZONE(zone); 11527 if (zone->type == dns_zone_primary) { 11528 if (inline_raw(zone)) { 11529 unsigned int soacount; 11530 secure = zone->secure; 11531 INSIST(secure != zone); 11532 TRYLOCK_ZONE(result, secure); 11533 if (result != ISC_R_SUCCESS) { 11534 UNLOCK_ZONE(zone); 11535 secure = NULL; 11536 isc_thread_yield(); 11537 goto again; 11538 } 11539 11540 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 11541 if (zone->db != NULL) { 11542 result = zone_get_from_db( 11543 zone, zone->db, NULL, &soacount, NULL, 11544 &serial, NULL, NULL, NULL, NULL, NULL); 11545 } else { 11546 result = DNS_R_NOTLOADED; 11547 } 11548 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11549 if (result == ISC_R_SUCCESS && soacount > 0U) { 11550 zone_send_secureserial(zone, serial); 11551 } 11552 } 11553 11554 /* XXXMPA make separate call back */ 11555 if (result == ISC_R_SUCCESS) { 11556 set_resigntime(zone); 11557 if (zone->task != NULL) { 11558 isc_time_t now; 11559 TIME_NOW(&now); 11560 zone_settimer(zone, &now); 11561 } 11562 } 11563 } 11564 if (secure != NULL) { 11565 UNLOCK_ZONE(secure); 11566 } 11567 zone_needdump(zone, DNS_DUMP_DELAY); 11568 UNLOCK_ZONE(zone); 11569} 11570 11571void 11572dns_zone_expire(dns_zone_t *zone) { 11573 REQUIRE(DNS_ZONE_VALID(zone)); 11574 11575 LOCK_ZONE(zone); 11576 zone_expire(zone); 11577 UNLOCK_ZONE(zone); 11578} 11579 11580static void 11581zone_expire(dns_zone_t *zone) { 11582 dns_db_t *db = NULL; 11583 11584 /* 11585 * 'zone' locked by caller. 11586 */ 11587 11588 REQUIRE(LOCKED_ZONE(zone)); 11589 11590 dns_zone_log(zone, ISC_LOG_WARNING, "expired"); 11591 11592 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED); 11593 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 11594 zone->retry = DNS_ZONE_DEFAULTRETRY; 11595 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 11596 11597 /* 11598 * An RPZ zone has expired; before unloading it, we must 11599 * first remove it from the RPZ summary database. The 11600 * easiest way to do this is "update" it with an empty 11601 * database so that the update callback synchronizes 11602 * the diff automatically. 11603 */ 11604 if (zone->rpzs != NULL && zone->rpz_num != DNS_RPZ_INVALID_NUM) { 11605 isc_result_t result; 11606 dns_rpz_zone_t *rpz = zone->rpzs->zones[zone->rpz_num]; 11607 11608 CHECK(dns_db_create(zone->mctx, "rbt", &zone->origin, 11609 dns_dbtype_zone, zone->rdclass, 0, NULL, 11610 &db)); 11611 CHECK(dns_rpz_dbupdate_callback(db, rpz)); 11612 dns_zone_log(zone, ISC_LOG_WARNING, 11613 "response-policy zone expired; " 11614 "policies unloaded"); 11615 } 11616 11617failure: 11618 if (db != NULL) { 11619 dns_db_detach(&db); 11620 } 11621 11622 zone_unload(zone); 11623} 11624 11625void 11626dns_zone_refresh(dns_zone_t *zone) { 11627 isc_interval_t i; 11628 uint32_t oldflags; 11629 unsigned int j; 11630 isc_result_t result; 11631 11632 REQUIRE(DNS_ZONE_VALID(zone)); 11633 11634 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11635 return; 11636 } 11637 11638 /* 11639 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation 11640 * in progress at a time. 11641 */ 11642 11643 LOCK_ZONE(zone); 11644 oldflags = atomic_load(&zone->flags); 11645 if (zone->masterscnt == 0) { 11646 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS); 11647 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0) { 11648 dns_zone_log(zone, ISC_LOG_ERROR, 11649 "cannot refresh: no primaries"); 11650 } 11651 goto unlock; 11652 } 11653 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 11654 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 11655 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 11656 if ((oldflags & (DNS_ZONEFLG_REFRESH | DNS_ZONEFLG_LOADING)) != 0) { 11657 goto unlock; 11658 } 11659 11660 /* 11661 * Set the next refresh time as if refresh check has failed. 11662 * Setting this to the retry time will do that. XXXMLG 11663 * If we are successful it will be reset using zone->refresh. 11664 */ 11665 isc_interval_set(&i, zone->retry - isc_random_uniform(zone->retry / 4), 11666 0); 11667 result = isc_time_nowplusinterval(&zone->refreshtime, &i); 11668 if (result != ISC_R_SUCCESS) { 11669 dns_zone_log(zone, ISC_LOG_WARNING, 11670 "isc_time_nowplusinterval() failed: %s", 11671 dns_result_totext(result)); 11672 } 11673 11674 /* 11675 * When lacking user-specified timer values from the SOA, 11676 * do exponential backoff of the retry time up to a 11677 * maximum of six hours. 11678 */ 11679 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) { 11680 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600); 11681 } 11682 11683 zone->curmaster = 0; 11684 for (j = 0; j < zone->masterscnt; j++) { 11685 zone->mastersok[j] = false; 11686 } 11687 /* initiate soa query */ 11688 queue_soa_query(zone); 11689unlock: 11690 UNLOCK_ZONE(zone); 11691} 11692 11693static isc_result_t 11694zone_journal_rollforward(dns_zone_t *zone, dns_db_t *db, bool *needdump, 11695 bool *fixjournal) { 11696 dns_journal_t *journal = NULL; 11697 unsigned int options; 11698 isc_result_t result; 11699 11700 if (zone->type == dns_zone_primary && 11701 (inline_secure(zone) || 11702 (zone->update_acl != NULL || zone->ssutable != NULL))) 11703 { 11704 options = DNS_JOURNALOPT_RESIGN; 11705 } else { 11706 options = 0; 11707 } 11708 11709 result = dns_journal_open(zone->mctx, zone->journal, DNS_JOURNAL_READ, 11710 &journal); 11711 if (result == ISC_R_NOTFOUND) { 11712 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(3), 11713 "no journal file, but that's OK "); 11714 return (ISC_R_SUCCESS); 11715 } else if (result != ISC_R_SUCCESS) { 11716 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 11717 "journal open failed: %s", 11718 dns_result_totext(result)); 11719 return (result); 11720 } 11721 11722 if (dns_journal_empty(journal)) { 11723 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1), 11724 "journal empty"); 11725 dns_journal_destroy(&journal); 11726 return (ISC_R_SUCCESS); 11727 } 11728 11729 result = dns_journal_rollforward(journal, db, options); 11730 switch (result) { 11731 case ISC_R_SUCCESS: 11732 *needdump = true; 11733 FALLTHROUGH; 11734 case DNS_R_UPTODATE: 11735 if (dns_journal_recovered(journal)) { 11736 *fixjournal = true; 11737 dns_zone_logc( 11738 zone, DNS_LOGCATEGORY_ZONELOAD, 11739 ISC_LOG_DEBUG(1), 11740 "journal rollforward completed successfully " 11741 "using old journal format: %s", 11742 dns_result_totext(result)); 11743 } else { 11744 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 11745 ISC_LOG_DEBUG(1), 11746 "journal rollforward completed " 11747 "successfully: %s", 11748 dns_result_totext(result)); 11749 } 11750 11751 dns_journal_destroy(&journal); 11752 return (ISC_R_SUCCESS); 11753 case ISC_R_NOTFOUND: 11754 case ISC_R_RANGE: 11755 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 11756 "journal rollforward failed: journal out of sync " 11757 "with zone"); 11758 dns_journal_destroy(&journal); 11759 return (result); 11760 default: 11761 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 11762 "journal rollforward failed: %s", 11763 dns_result_totext(result)); 11764 dns_journal_destroy(&journal); 11765 return (result); 11766 } 11767} 11768 11769static void 11770zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial) { 11771 isc_result_t result; 11772 int32_t journalsize; 11773 dns_dbversion_t *ver = NULL; 11774 uint64_t dbsize; 11775 uint32_t options = 0; 11776 11777 INSIST(LOCKED_ZONE(zone)); 11778 if (inline_raw(zone)) { 11779 INSIST(LOCKED_ZONE(zone->secure)); 11780 } 11781 11782 journalsize = zone->journalsize; 11783 if (journalsize == -1) { 11784 journalsize = DNS_JOURNAL_SIZE_MAX; 11785 dns_db_currentversion(db, &ver); 11786 result = dns_db_getsize(db, ver, NULL, &dbsize); 11787 dns_db_closeversion(db, &ver, false); 11788 if (result != ISC_R_SUCCESS) { 11789 dns_zone_log(zone, ISC_LOG_ERROR, 11790 "zone_journal_compact: " 11791 "could not get zone size: %s", 11792 isc_result_totext(result)); 11793 } else if (dbsize < DNS_JOURNAL_SIZE_MAX / 2) { 11794 journalsize = (int32_t)dbsize * 2; 11795 } 11796 } 11797 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FIXJOURNAL)) { 11798 options |= DNS_JOURNAL_COMPACTALL; 11799 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FIXJOURNAL); 11800 zone_debuglog(zone, "zone_journal_compact", 1, 11801 "repair full journal"); 11802 } else { 11803 zone_debuglog(zone, "zone_journal_compact", 1, 11804 "target journal size %d", journalsize); 11805 } 11806 result = dns_journal_compact(zone->mctx, zone->journal, serial, options, 11807 journalsize); 11808 switch (result) { 11809 case ISC_R_SUCCESS: 11810 case ISC_R_NOSPACE: 11811 case ISC_R_NOTFOUND: 11812 dns_zone_log(zone, ISC_LOG_DEBUG(3), "dns_journal_compact: %s", 11813 dns_result_totext(result)); 11814 break; 11815 default: 11816 dns_zone_log(zone, ISC_LOG_ERROR, 11817 "dns_journal_compact failed: %s", 11818 dns_result_totext(result)); 11819 break; 11820 } 11821} 11822 11823isc_result_t 11824dns_zone_flush(dns_zone_t *zone) { 11825 isc_result_t result = ISC_R_SUCCESS; 11826 bool dumping; 11827 11828 REQUIRE(DNS_ZONE_VALID(zone)); 11829 11830 LOCK_ZONE(zone); 11831 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH); 11832 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 11833 zone->masterfile != NULL) 11834 { 11835 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 11836 result = ISC_R_ALREADYRUNNING; 11837 dumping = was_dumping(zone); 11838 } else { 11839 dumping = true; 11840 } 11841 UNLOCK_ZONE(zone); 11842 if (!dumping) { 11843 result = zone_dump(zone, true); /* Unknown task. */ 11844 } 11845 return (result); 11846} 11847 11848isc_result_t 11849dns_zone_dump(dns_zone_t *zone) { 11850 isc_result_t result = ISC_R_ALREADYRUNNING; 11851 bool dumping; 11852 11853 REQUIRE(DNS_ZONE_VALID(zone)); 11854 11855 LOCK_ZONE(zone); 11856 dumping = was_dumping(zone); 11857 UNLOCK_ZONE(zone); 11858 if (!dumping) { 11859 result = zone_dump(zone, false); /* Unknown task. */ 11860 } 11861 return (result); 11862} 11863 11864static void 11865zone_needdump(dns_zone_t *zone, unsigned int delay) { 11866 const char me[] = "zone_needdump"; 11867 isc_time_t dumptime; 11868 isc_time_t now; 11869 11870 /* 11871 * 'zone' locked by caller 11872 */ 11873 11874 REQUIRE(DNS_ZONE_VALID(zone)); 11875 REQUIRE(LOCKED_ZONE(zone)); 11876 ENTER; 11877 11878 /* 11879 * Do we have a place to dump to and are we loaded? 11880 */ 11881 if (zone->masterfile == NULL || 11882 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) 11883 { 11884 return; 11885 } 11886 11887 TIME_NOW(&now); 11888 /* add some noise */ 11889 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime); 11890 11891 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 11892 if (isc_time_isepoch(&zone->dumptime) || 11893 isc_time_compare(&zone->dumptime, &dumptime) > 0) 11894 { 11895 zone->dumptime = dumptime; 11896 } 11897 if (zone->task != NULL) { 11898 zone_settimer(zone, &now); 11899 } 11900} 11901 11902static void 11903dump_done(void *arg, isc_result_t result) { 11904 const char me[] = "dump_done"; 11905 dns_zone_t *zone = arg; 11906 dns_zone_t *secure = NULL; 11907 dns_db_t *db; 11908 dns_dbversion_t *version; 11909 bool again = false; 11910 bool compact = false; 11911 uint32_t serial; 11912 isc_result_t tresult; 11913 11914 REQUIRE(DNS_ZONE_VALID(zone)); 11915 11916 ENTER; 11917 11918 if (result == ISC_R_SUCCESS && zone->journal != NULL) { 11919 /* 11920 * We don't own these, zone->dctx must stay valid. 11921 */ 11922 db = dns_dumpctx_db(zone->dctx); 11923 version = dns_dumpctx_version(zone->dctx); 11924 tresult = dns_db_getsoaserial(db, version, &serial); 11925 11926 /* 11927 * Handle lock order inversion. 11928 */ 11929 again: 11930 LOCK_ZONE(zone); 11931 if (inline_raw(zone)) { 11932 secure = zone->secure; 11933 INSIST(secure != zone); 11934 TRYLOCK_ZONE(result, secure); 11935 if (result != ISC_R_SUCCESS) { 11936 UNLOCK_ZONE(zone); 11937 secure = NULL; 11938 isc_thread_yield(); 11939 goto again; 11940 } 11941 } 11942 11943 /* 11944 * If there is a secure version of this zone 11945 * use its serial if it is less than ours. 11946 */ 11947 if (tresult == ISC_R_SUCCESS && secure != NULL) { 11948 uint32_t sserial; 11949 isc_result_t mresult; 11950 11951 ZONEDB_LOCK(&secure->dblock, isc_rwlocktype_read); 11952 if (secure->db != NULL) { 11953 mresult = dns_db_getsoaserial(zone->secure->db, 11954 NULL, &sserial); 11955 if (mresult == ISC_R_SUCCESS && 11956 isc_serial_lt(sserial, serial)) 11957 { 11958 serial = sserial; 11959 } 11960 } 11961 ZONEDB_UNLOCK(&secure->dblock, isc_rwlocktype_read); 11962 } 11963 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) { 11964 dns_db_t *zdb = NULL; 11965 if (dns_zone_getdb(zone, &zdb) == ISC_R_SUCCESS) { 11966 zone_journal_compact(zone, zdb, serial); 11967 dns_db_detach(&zdb); 11968 } 11969 } else if (tresult == ISC_R_SUCCESS) { 11970 compact = true; 11971 zone->compact_serial = serial; 11972 } 11973 if (secure != NULL) { 11974 UNLOCK_ZONE(secure); 11975 } 11976 UNLOCK_ZONE(zone); 11977 } 11978 11979 LOCK_ZONE(zone); 11980 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 11981 if (compact) { 11982 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 11983 } 11984 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN)) { 11985 /* 11986 * If DNS_ZONEFLG_SHUTDOWN is set, all external references to 11987 * the zone are gone, which means it is in the process of being 11988 * cleaned up, so do not reschedule dumping. 11989 * 11990 * Detach from the raw version of the zone in case this 11991 * operation has been deferred in zone_shutdown(). 11992 */ 11993 if (zone->raw != NULL) { 11994 dns_zone_detach(&zone->raw); 11995 } 11996 if (result == ISC_R_SUCCESS) { 11997 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 11998 } 11999 } else if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) { 12000 /* 12001 * Try again in a short while. 12002 */ 12003 zone_needdump(zone, DNS_DUMP_DELAY); 12004 } else if (result == ISC_R_SUCCESS && 12005 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 12006 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 12007 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 12008 { 12009 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 12010 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 12011 isc_time_settoepoch(&zone->dumptime); 12012 again = true; 12013 } else if (result == ISC_R_SUCCESS) { 12014 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 12015 } 12016 12017 if (zone->dctx != NULL) { 12018 dns_dumpctx_detach(&zone->dctx); 12019 } 12020 zonemgr_putio(&zone->writeio); 12021 UNLOCK_ZONE(zone); 12022 if (again) { 12023 (void)zone_dump(zone, false); 12024 } 12025 dns_zone_idetach(&zone); 12026} 12027 12028static isc_result_t 12029zone_dump(dns_zone_t *zone, bool compact) { 12030 const char me[] = "zone_dump"; 12031 isc_result_t result; 12032 dns_dbversion_t *version = NULL; 12033 bool again; 12034 dns_db_t *db = NULL; 12035 char *masterfile = NULL; 12036 dns_masterformat_t masterformat = dns_masterformat_none; 12037 12038 /* 12039 * 'compact' MUST only be set if we are task locked. 12040 */ 12041 12042 REQUIRE(DNS_ZONE_VALID(zone)); 12043 ENTER; 12044 12045redo: 12046 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12047 if (zone->db != NULL) { 12048 dns_db_attach(zone->db, &db); 12049 } 12050 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12051 LOCK_ZONE(zone); 12052 if (zone->masterfile != NULL) { 12053 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile); 12054 masterformat = zone->masterformat; 12055 } 12056 UNLOCK_ZONE(zone); 12057 if (db == NULL) { 12058 result = DNS_R_NOTLOADED; 12059 goto fail; 12060 } 12061 if (masterfile == NULL) { 12062 result = DNS_R_NOMASTERFILE; 12063 goto fail; 12064 } 12065 12066 if (compact && zone->type != dns_zone_stub) { 12067 dns_zone_t *dummy = NULL; 12068 LOCK_ZONE(zone); 12069 zone_iattach(zone, &dummy); 12070 result = zonemgr_getio(zone->zmgr, false, zone->task, 12071 zone_gotwritehandle, zone, 12072 &zone->writeio); 12073 if (result != ISC_R_SUCCESS) { 12074 zone_idetach(&dummy); 12075 } else { 12076 result = DNS_R_CONTINUE; 12077 } 12078 UNLOCK_ZONE(zone); 12079 } else { 12080 const dns_master_style_t *output_style; 12081 12082 dns_masterrawheader_t rawdata; 12083 dns_db_currentversion(db, &version); 12084 dns_master_initrawheader(&rawdata); 12085 if (inline_secure(zone)) { 12086 get_raw_serial(zone->raw, &rawdata); 12087 } 12088 if (zone->type == dns_zone_key) { 12089 output_style = &dns_master_style_keyzone; 12090 } else { 12091 output_style = &dns_master_style_default; 12092 } 12093 result = dns_master_dump(zone->mctx, db, version, output_style, 12094 masterfile, masterformat, &rawdata); 12095 dns_db_closeversion(db, &version, false); 12096 } 12097fail: 12098 if (db != NULL) { 12099 dns_db_detach(&db); 12100 } 12101 if (masterfile != NULL) { 12102 isc_mem_free(zone->mctx, masterfile); 12103 } 12104 masterfile = NULL; 12105 12106 if (result == DNS_R_CONTINUE) { 12107 return (ISC_R_SUCCESS); /* XXXMPA */ 12108 } 12109 12110 again = false; 12111 LOCK_ZONE(zone); 12112 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 12113 if (result != ISC_R_SUCCESS) { 12114 /* 12115 * Try again in a short while. 12116 */ 12117 zone_needdump(zone, DNS_DUMP_DELAY); 12118 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 12119 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 12120 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 12121 { 12122 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 12123 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 12124 isc_time_settoepoch(&zone->dumptime); 12125 again = true; 12126 } else { 12127 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 12128 } 12129 UNLOCK_ZONE(zone); 12130 if (again) { 12131 goto redo; 12132 } 12133 12134 return (result); 12135} 12136 12137static isc_result_t 12138dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style, 12139 dns_masterformat_t format, const uint32_t rawversion) { 12140 isc_result_t result; 12141 dns_dbversion_t *version = NULL; 12142 dns_db_t *db = NULL; 12143 dns_masterrawheader_t rawdata; 12144 12145 REQUIRE(DNS_ZONE_VALID(zone)); 12146 12147 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12148 if (zone->db != NULL) { 12149 dns_db_attach(zone->db, &db); 12150 } 12151 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12152 if (db == NULL) { 12153 return (DNS_R_NOTLOADED); 12154 } 12155 12156 dns_db_currentversion(db, &version); 12157 dns_master_initrawheader(&rawdata); 12158 if (rawversion == 0) { 12159 rawdata.flags |= DNS_MASTERRAW_COMPAT; 12160 } else if (inline_secure(zone)) { 12161 get_raw_serial(zone->raw, &rawdata); 12162 } else if (zone->sourceserialset) { 12163 rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET; 12164 rawdata.sourceserial = zone->sourceserial; 12165 } 12166 result = dns_master_dumptostream(zone->mctx, db, version, style, format, 12167 &rawdata, fd); 12168 dns_db_closeversion(db, &version, false); 12169 dns_db_detach(&db); 12170 return (result); 12171} 12172 12173isc_result_t 12174dns_zone_dumptostream(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, 12175 const dns_master_style_t *style, 12176 const uint32_t rawversion) { 12177 return (dumptostream(zone, fd, style, format, rawversion)); 12178} 12179 12180void 12181dns_zone_unload(dns_zone_t *zone) { 12182 REQUIRE(DNS_ZONE_VALID(zone)); 12183 12184 LOCK_ZONE(zone); 12185 zone_unload(zone); 12186 UNLOCK_ZONE(zone); 12187} 12188 12189static void 12190notify_cancel(dns_zone_t *zone) { 12191 dns_notify_t *notify; 12192 12193 /* 12194 * 'zone' locked by caller. 12195 */ 12196 12197 REQUIRE(LOCKED_ZONE(zone)); 12198 12199 for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL; 12200 notify = ISC_LIST_NEXT(notify, link)) 12201 { 12202 if (notify->find != NULL) { 12203 dns_adb_cancelfind(notify->find); 12204 } 12205 if (notify->request != NULL) { 12206 dns_request_cancel(notify->request); 12207 } 12208 } 12209} 12210 12211static void 12212checkds_cancel(dns_zone_t *zone) { 12213 dns_checkds_t *checkds; 12214 12215 /* 12216 * 'zone' locked by caller. 12217 */ 12218 12219 REQUIRE(LOCKED_ZONE(zone)); 12220 12221 for (checkds = ISC_LIST_HEAD(zone->checkds_requests); checkds != NULL; 12222 checkds = ISC_LIST_NEXT(checkds, link)) 12223 { 12224 if (checkds->request != NULL) { 12225 dns_request_cancel(checkds->request); 12226 } 12227 } 12228} 12229 12230static void 12231forward_cancel(dns_zone_t *zone) { 12232 dns_forward_t *forward; 12233 12234 /* 12235 * 'zone' locked by caller. 12236 */ 12237 12238 REQUIRE(LOCKED_ZONE(zone)); 12239 12240 for (forward = ISC_LIST_HEAD(zone->forwards); forward != NULL; 12241 forward = ISC_LIST_NEXT(forward, link)) 12242 { 12243 if (forward->request != NULL) { 12244 dns_request_cancel(forward->request); 12245 } 12246 } 12247} 12248 12249static void 12250zone_unload(dns_zone_t *zone) { 12251 /* 12252 * 'zone' locked by caller. 12253 */ 12254 12255 REQUIRE(LOCKED_ZONE(zone)); 12256 12257 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 12258 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 12259 { 12260 if (zone->writeio != NULL) { 12261 zonemgr_cancelio(zone->writeio); 12262 } 12263 12264 if (zone->dctx != NULL) { 12265 dns_dumpctx_cancel(zone->dctx); 12266 } 12267 } 12268 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 12269 zone_detachdb(zone); 12270 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 12271 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED); 12272 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 12273 12274 if (zone->type == dns_zone_mirror) { 12275 dns_zone_log(zone, ISC_LOG_INFO, 12276 "mirror zone is no longer in use; " 12277 "reverting to normal recursion"); 12278 } 12279} 12280 12281void 12282dns_zone_setminrefreshtime(dns_zone_t *zone, uint32_t val) { 12283 REQUIRE(DNS_ZONE_VALID(zone)); 12284 REQUIRE(val > 0); 12285 12286 zone->minrefresh = val; 12287} 12288 12289void 12290dns_zone_setmaxrefreshtime(dns_zone_t *zone, uint32_t val) { 12291 REQUIRE(DNS_ZONE_VALID(zone)); 12292 REQUIRE(val > 0); 12293 12294 zone->maxrefresh = val; 12295} 12296 12297void 12298dns_zone_setminretrytime(dns_zone_t *zone, uint32_t val) { 12299 REQUIRE(DNS_ZONE_VALID(zone)); 12300 REQUIRE(val > 0); 12301 12302 zone->minretry = val; 12303} 12304 12305void 12306dns_zone_setmaxretrytime(dns_zone_t *zone, uint32_t val) { 12307 REQUIRE(DNS_ZONE_VALID(zone)); 12308 REQUIRE(val > 0); 12309 12310 zone->maxretry = val; 12311} 12312 12313uint32_t 12314dns_zone_getmaxrecords(dns_zone_t *zone) { 12315 REQUIRE(DNS_ZONE_VALID(zone)); 12316 12317 return (zone->maxrecords); 12318} 12319 12320void 12321dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) { 12322 REQUIRE(DNS_ZONE_VALID(zone)); 12323 12324 zone->maxrecords = val; 12325} 12326 12327static bool 12328notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name, 12329 isc_sockaddr_t *addr, dns_tsigkey_t *key) { 12330 dns_notify_t *notify; 12331 dns_zonemgr_t *zmgr; 12332 isc_result_t result; 12333 12334 for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL; 12335 notify = ISC_LIST_NEXT(notify, link)) 12336 { 12337 if (notify->request != NULL) { 12338 continue; 12339 } 12340 if (name != NULL && dns_name_dynamic(¬ify->ns) && 12341 dns_name_equal(name, ¬ify->ns)) 12342 { 12343 goto requeue; 12344 } 12345 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst) && 12346 notify->key == key) 12347 { 12348 goto requeue; 12349 } 12350 } 12351 return (false); 12352 12353requeue: 12354 /* 12355 * If we are enqueued on the startup ratelimiter and this is 12356 * not a startup notify, re-enqueue on the normal notify 12357 * ratelimiter. 12358 */ 12359 if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0 && 12360 (notify->flags & DNS_NOTIFY_STARTUP) != 0) 12361 { 12362 zmgr = notify->zone->zmgr; 12363 result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl, 12364 notify->event); 12365 if (result != ISC_R_SUCCESS) { 12366 return (true); 12367 } 12368 12369 notify->flags &= ~DNS_NOTIFY_STARTUP; 12370 result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl, 12371 notify->zone->task, 12372 ¬ify->event); 12373 if (result != ISC_R_SUCCESS) { 12374 isc_event_free(¬ify->event); 12375 return (false); 12376 } 12377 } 12378 12379 return (true); 12380} 12381 12382static bool 12383notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) { 12384 dns_tsigkey_t *key = NULL; 12385 isc_sockaddr_t src; 12386 isc_sockaddr_t any; 12387 bool isself; 12388 isc_netaddr_t dstaddr; 12389 isc_result_t result; 12390 12391 if (zone->view == NULL || zone->isself == NULL) { 12392 return (false); 12393 } 12394 12395 switch (isc_sockaddr_pf(dst)) { 12396 case PF_INET: 12397 src = zone->notifysrc4; 12398 isc_sockaddr_any(&any); 12399 break; 12400 case PF_INET6: 12401 src = zone->notifysrc6; 12402 isc_sockaddr_any6(&any); 12403 break; 12404 default: 12405 return (false); 12406 } 12407 12408 /* 12409 * When sending from any the kernel will assign a source address 12410 * that matches the destination address. 12411 */ 12412 if (isc_sockaddr_eqaddr(&any, &src)) { 12413 src = *dst; 12414 } 12415 12416 isc_netaddr_fromsockaddr(&dstaddr, dst); 12417 result = dns_view_getpeertsig(zone->view, &dstaddr, &key); 12418 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 12419 return (false); 12420 } 12421 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass, 12422 zone->isselfarg); 12423 if (key != NULL) { 12424 dns_tsigkey_detach(&key); 12425 } 12426 return (isself); 12427} 12428 12429static void 12430notify_destroy(dns_notify_t *notify, bool locked) { 12431 isc_mem_t *mctx; 12432 12433 REQUIRE(DNS_NOTIFY_VALID(notify)); 12434 12435 if (notify->zone != NULL) { 12436 if (!locked) { 12437 LOCK_ZONE(notify->zone); 12438 } 12439 REQUIRE(LOCKED_ZONE(notify->zone)); 12440 if (ISC_LINK_LINKED(notify, link)) { 12441 ISC_LIST_UNLINK(notify->zone->notifies, notify, link); 12442 } 12443 if (!locked) { 12444 UNLOCK_ZONE(notify->zone); 12445 } 12446 if (locked) { 12447 zone_idetach(¬ify->zone); 12448 } else { 12449 dns_zone_idetach(¬ify->zone); 12450 } 12451 } 12452 if (notify->find != NULL) { 12453 dns_adb_destroyfind(¬ify->find); 12454 } 12455 if (notify->request != NULL) { 12456 dns_request_destroy(¬ify->request); 12457 } 12458 if (dns_name_dynamic(¬ify->ns)) { 12459 dns_name_free(¬ify->ns, notify->mctx); 12460 } 12461 if (notify->key != NULL) { 12462 dns_tsigkey_detach(¬ify->key); 12463 } 12464 mctx = notify->mctx; 12465 isc_mem_put(notify->mctx, notify, sizeof(*notify)); 12466 isc_mem_detach(&mctx); 12467} 12468 12469static isc_result_t 12470notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) { 12471 dns_notify_t *notify; 12472 12473 REQUIRE(notifyp != NULL && *notifyp == NULL); 12474 12475 notify = isc_mem_get(mctx, sizeof(*notify)); 12476 12477 notify->mctx = NULL; 12478 isc_mem_attach(mctx, ¬ify->mctx); 12479 notify->flags = flags; 12480 notify->zone = NULL; 12481 notify->find = NULL; 12482 notify->request = NULL; 12483 notify->key = NULL; 12484 notify->event = NULL; 12485 isc_sockaddr_any(¬ify->dst); 12486 dns_name_init(¬ify->ns, NULL); 12487 ISC_LINK_INIT(notify, link); 12488 notify->magic = NOTIFY_MAGIC; 12489 *notifyp = notify; 12490 return (ISC_R_SUCCESS); 12491} 12492 12493/* 12494 * XXXAG should check for DNS_ZONEFLG_EXITING 12495 */ 12496static void 12497process_adb_event(isc_task_t *task, isc_event_t *ev) { 12498 dns_notify_t *notify; 12499 isc_eventtype_t result; 12500 12501 UNUSED(task); 12502 12503 notify = ev->ev_arg; 12504 REQUIRE(DNS_NOTIFY_VALID(notify)); 12505 INSIST(task == notify->zone->task); 12506 result = ev->ev_type; 12507 isc_event_free(&ev); 12508 if (result == DNS_EVENT_ADBMOREADDRESSES) { 12509 dns_adb_destroyfind(¬ify->find); 12510 notify_find_address(notify); 12511 return; 12512 } 12513 if (result == DNS_EVENT_ADBNOMOREADDRESSES) { 12514 LOCK_ZONE(notify->zone); 12515 notify_send(notify); 12516 UNLOCK_ZONE(notify->zone); 12517 } 12518 notify_destroy(notify, false); 12519} 12520 12521static void 12522notify_find_address(dns_notify_t *notify) { 12523 isc_result_t result; 12524 unsigned int options; 12525 12526 REQUIRE(DNS_NOTIFY_VALID(notify)); 12527 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET | DNS_ADBFIND_INET6 | 12528 DNS_ADBFIND_RETURNLAME; 12529 12530 if (notify->zone->view->adb == NULL) { 12531 goto destroy; 12532 } 12533 12534 result = dns_adb_createfind( 12535 notify->zone->view->adb, notify->zone->task, process_adb_event, 12536 notify, ¬ify->ns, dns_rootname, 0, options, 0, NULL, 12537 notify->zone->view->dstport, 0, NULL, ¬ify->find); 12538 12539 /* Something failed? */ 12540 if (result != ISC_R_SUCCESS) { 12541 goto destroy; 12542 } 12543 12544 /* More addresses pending? */ 12545 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) { 12546 return; 12547 } 12548 12549 /* We have as many addresses as we can get. */ 12550 LOCK_ZONE(notify->zone); 12551 notify_send(notify); 12552 UNLOCK_ZONE(notify->zone); 12553 12554destroy: 12555 notify_destroy(notify, false); 12556} 12557 12558static isc_result_t 12559notify_send_queue(dns_notify_t *notify, bool startup) { 12560 isc_event_t *e; 12561 isc_result_t result; 12562 12563 INSIST(notify->event == NULL); 12564 e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR, 12565 notify_send_toaddr, notify, sizeof(isc_event_t)); 12566 if (startup) { 12567 notify->event = e; 12568 } 12569 e->ev_arg = notify; 12570 e->ev_sender = NULL; 12571 result = isc_ratelimiter_enqueue( 12572 startup ? notify->zone->zmgr->startupnotifyrl 12573 : notify->zone->zmgr->notifyrl, 12574 notify->zone->task, &e); 12575 if (result != ISC_R_SUCCESS) { 12576 isc_event_free(&e); 12577 notify->event = NULL; 12578 } 12579 return (result); 12580} 12581 12582static void 12583notify_send_toaddr(isc_task_t *task, isc_event_t *event) { 12584 dns_notify_t *notify; 12585 isc_result_t result; 12586 dns_message_t *message = NULL; 12587 isc_netaddr_t dstip; 12588 dns_tsigkey_t *key = NULL; 12589 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 12590 isc_sockaddr_t src; 12591 unsigned int options, timeout; 12592 bool have_notifysource = false; 12593 bool have_notifydscp = false; 12594 isc_dscp_t dscp = -1; 12595 12596 notify = event->ev_arg; 12597 REQUIRE(DNS_NOTIFY_VALID(notify)); 12598 12599 UNUSED(task); 12600 12601 LOCK_ZONE(notify->zone); 12602 12603 notify->event = NULL; 12604 12605 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) { 12606 result = ISC_R_CANCELED; 12607 goto cleanup; 12608 } 12609 12610 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 || 12611 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) || 12612 notify->zone->view->requestmgr == NULL || notify->zone->db == NULL) 12613 { 12614 result = ISC_R_CANCELED; 12615 goto cleanup; 12616 } 12617 12618 /* 12619 * The raw IPv4 address should also exist. Don't send to the 12620 * mapped form. 12621 */ 12622 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 && 12623 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) 12624 { 12625 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 12626 notify_log(notify->zone, ISC_LOG_DEBUG(3), 12627 "notify: ignoring IPv6 mapped IPV4 address: %s", 12628 addrbuf); 12629 result = ISC_R_CANCELED; 12630 goto cleanup; 12631 } 12632 12633 result = notify_createmessage(notify->zone, notify->flags, &message); 12634 if (result != ISC_R_SUCCESS) { 12635 goto cleanup; 12636 } 12637 12638 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 12639 if (notify->key != NULL) { 12640 /* Transfer ownership of key */ 12641 key = notify->key; 12642 notify->key = NULL; 12643 } else { 12644 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst); 12645 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key); 12646 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 12647 notify_log(notify->zone, ISC_LOG_ERROR, 12648 "NOTIFY to %s not sent. " 12649 "Peer TSIG key lookup failure.", 12650 addrbuf); 12651 goto cleanup_message; 12652 } 12653 } 12654 12655 if (key != NULL) { 12656 char namebuf[DNS_NAME_FORMATSIZE]; 12657 12658 dns_name_format(&key->name, namebuf, sizeof(namebuf)); 12659 notify_log(notify->zone, ISC_LOG_DEBUG(3), 12660 "sending notify to %s : TSIG (%s)", addrbuf, 12661 namebuf); 12662 } else { 12663 notify_log(notify->zone, ISC_LOG_DEBUG(3), 12664 "sending notify to %s", addrbuf); 12665 } 12666 options = 0; 12667 if (notify->zone->view->peers != NULL) { 12668 dns_peer_t *peer = NULL; 12669 bool usetcp = false; 12670 result = dns_peerlist_peerbyaddr(notify->zone->view->peers, 12671 &dstip, &peer); 12672 if (result == ISC_R_SUCCESS) { 12673 result = dns_peer_getnotifysource(peer, &src); 12674 if (result == ISC_R_SUCCESS) { 12675 have_notifysource = true; 12676 } 12677 dns_peer_getnotifydscp(peer, &dscp); 12678 if (dscp != -1) { 12679 have_notifydscp = true; 12680 } 12681 result = dns_peer_getforcetcp(peer, &usetcp); 12682 if (result == ISC_R_SUCCESS && usetcp) { 12683 options |= DNS_FETCHOPT_TCP; 12684 } 12685 } 12686 } 12687 switch (isc_sockaddr_pf(¬ify->dst)) { 12688 case PF_INET: 12689 if (!have_notifysource) { 12690 src = notify->zone->notifysrc4; 12691 } 12692 if (!have_notifydscp) { 12693 dscp = notify->zone->notifysrc4dscp; 12694 } 12695 break; 12696 case PF_INET6: 12697 if (!have_notifysource) { 12698 src = notify->zone->notifysrc6; 12699 } 12700 if (!have_notifydscp) { 12701 dscp = notify->zone->notifysrc6dscp; 12702 } 12703 break; 12704 default: 12705 result = ISC_R_NOTIMPLEMENTED; 12706 goto cleanup_key; 12707 } 12708 timeout = 15; 12709 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) { 12710 timeout = 30; 12711 } 12712 result = dns_request_createvia( 12713 notify->zone->view->requestmgr, message, &src, ¬ify->dst, 12714 dscp, options, key, timeout * 3, timeout, 0, notify->zone->task, 12715 notify_done, notify, ¬ify->request); 12716 if (result == ISC_R_SUCCESS) { 12717 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) { 12718 inc_stats(notify->zone, 12719 dns_zonestatscounter_notifyoutv4); 12720 } else { 12721 inc_stats(notify->zone, 12722 dns_zonestatscounter_notifyoutv6); 12723 } 12724 } 12725 12726cleanup_key: 12727 if (key != NULL) { 12728 dns_tsigkey_detach(&key); 12729 } 12730cleanup_message: 12731 dns_message_detach(&message); 12732cleanup: 12733 UNLOCK_ZONE(notify->zone); 12734 isc_event_free(&event); 12735 if (result != ISC_R_SUCCESS) { 12736 notify_destroy(notify, false); 12737 } 12738} 12739 12740static void 12741notify_send(dns_notify_t *notify) { 12742 dns_adbaddrinfo_t *ai; 12743 isc_sockaddr_t dst; 12744 isc_result_t result; 12745 dns_notify_t *newnotify = NULL; 12746 unsigned int flags; 12747 bool startup; 12748 12749 /* 12750 * Zone lock held by caller. 12751 */ 12752 REQUIRE(DNS_NOTIFY_VALID(notify)); 12753 REQUIRE(LOCKED_ZONE(notify->zone)); 12754 12755 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING)) { 12756 return; 12757 } 12758 12759 for (ai = ISC_LIST_HEAD(notify->find->list); ai != NULL; 12760 ai = ISC_LIST_NEXT(ai, publink)) 12761 { 12762 dst = ai->sockaddr; 12763 if (notify_isqueued(notify->zone, notify->flags, NULL, &dst, 12764 NULL)) 12765 { 12766 continue; 12767 } 12768 if (notify_isself(notify->zone, &dst)) { 12769 continue; 12770 } 12771 newnotify = NULL; 12772 flags = notify->flags & DNS_NOTIFY_NOSOA; 12773 result = notify_create(notify->mctx, flags, &newnotify); 12774 if (result != ISC_R_SUCCESS) { 12775 goto cleanup; 12776 } 12777 zone_iattach(notify->zone, &newnotify->zone); 12778 ISC_LIST_APPEND(newnotify->zone->notifies, newnotify, link); 12779 newnotify->dst = dst; 12780 startup = ((notify->flags & DNS_NOTIFY_STARTUP) != 0); 12781 result = notify_send_queue(newnotify, startup); 12782 if (result != ISC_R_SUCCESS) { 12783 goto cleanup; 12784 } 12785 newnotify = NULL; 12786 } 12787 12788cleanup: 12789 if (newnotify != NULL) { 12790 notify_destroy(newnotify, true); 12791 } 12792} 12793 12794void 12795dns_zone_notify(dns_zone_t *zone) { 12796 isc_time_t now; 12797 12798 REQUIRE(DNS_ZONE_VALID(zone)); 12799 12800 LOCK_ZONE(zone); 12801 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12802 12803 TIME_NOW(&now); 12804 zone_settimer(zone, &now); 12805 UNLOCK_ZONE(zone); 12806} 12807 12808static void 12809zone_notify(dns_zone_t *zone, isc_time_t *now) { 12810 dns_dbnode_t *node = NULL; 12811 dns_db_t *zonedb = NULL; 12812 dns_dbversion_t *version = NULL; 12813 dns_name_t *origin = NULL; 12814 dns_name_t master; 12815 dns_rdata_ns_t ns; 12816 dns_rdata_soa_t soa; 12817 uint32_t serial; 12818 dns_rdata_t rdata = DNS_RDATA_INIT; 12819 dns_rdataset_t nsrdset; 12820 dns_rdataset_t soardset; 12821 isc_result_t result; 12822 unsigned int i; 12823 isc_sockaddr_t dst; 12824 bool isqueued; 12825 dns_notifytype_t notifytype; 12826 unsigned int flags = 0; 12827 bool loggednotify = false; 12828 bool startup; 12829 12830 REQUIRE(DNS_ZONE_VALID(zone)); 12831 12832 LOCK_ZONE(zone); 12833 startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12834 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12835 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY); 12836 notifytype = zone->notifytype; 12837 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime); 12838 UNLOCK_ZONE(zone); 12839 12840 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || 12841 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 12842 { 12843 return; 12844 } 12845 12846 if (notifytype == dns_notifytype_no) { 12847 return; 12848 } 12849 12850 if (notifytype == dns_notifytype_masteronly && 12851 zone->type != dns_zone_primary) 12852 { 12853 return; 12854 } 12855 12856 origin = &zone->origin; 12857 12858 /* 12859 * If the zone is dialup we are done as we don't want to send 12860 * the current soa so as to force a refresh query. 12861 */ 12862 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) { 12863 flags |= DNS_NOTIFY_NOSOA; 12864 } 12865 12866 /* 12867 * Record that this was a notify due to starting up. 12868 */ 12869 if (startup) { 12870 flags |= DNS_NOTIFY_STARTUP; 12871 } 12872 12873 /* 12874 * Get SOA RRset. 12875 */ 12876 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12877 if (zone->db != NULL) { 12878 dns_db_attach(zone->db, &zonedb); 12879 } 12880 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12881 if (zonedb == NULL) { 12882 return; 12883 } 12884 dns_db_currentversion(zonedb, &version); 12885 result = dns_db_findnode(zonedb, origin, false, &node); 12886 if (result != ISC_R_SUCCESS) { 12887 goto cleanup1; 12888 } 12889 12890 dns_rdataset_init(&soardset); 12891 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, 12892 dns_rdatatype_none, 0, &soardset, NULL); 12893 if (result != ISC_R_SUCCESS) { 12894 goto cleanup2; 12895 } 12896 12897 /* 12898 * Find serial and master server's name. 12899 */ 12900 dns_name_init(&master, NULL); 12901 result = dns_rdataset_first(&soardset); 12902 if (result != ISC_R_SUCCESS) { 12903 goto cleanup3; 12904 } 12905 dns_rdataset_current(&soardset, &rdata); 12906 result = dns_rdata_tostruct(&rdata, &soa, NULL); 12907 RUNTIME_CHECK(result == ISC_R_SUCCESS); 12908 dns_rdata_reset(&rdata); 12909 dns_name_dup(&soa.origin, zone->mctx, &master); 12910 serial = soa.serial; 12911 dns_rdataset_disassociate(&soardset); 12912 12913 /* 12914 * Enqueue notify requests for 'also-notify' servers. 12915 */ 12916 LOCK_ZONE(zone); 12917 for (i = 0; i < zone->notifycnt; i++) { 12918 dns_tsigkey_t *key = NULL; 12919 dns_notify_t *notify = NULL; 12920 12921 if ((zone->notifykeynames != NULL) && 12922 (zone->notifykeynames[i] != NULL)) 12923 { 12924 dns_view_t *view = dns_zone_getview(zone); 12925 dns_name_t *keyname = zone->notifykeynames[i]; 12926 (void)dns_view_gettsig(view, keyname, &key); 12927 } 12928 12929 dst = zone->notify[i]; 12930 if (notify_isqueued(zone, flags, NULL, &dst, key)) { 12931 if (key != NULL) { 12932 dns_tsigkey_detach(&key); 12933 } 12934 continue; 12935 } 12936 12937 result = notify_create(zone->mctx, flags, ¬ify); 12938 if (result != ISC_R_SUCCESS) { 12939 if (key != NULL) { 12940 dns_tsigkey_detach(&key); 12941 } 12942 continue; 12943 } 12944 12945 zone_iattach(zone, ¬ify->zone); 12946 notify->dst = dst; 12947 12948 INSIST(notify->key == NULL); 12949 12950 if (key != NULL) { 12951 notify->key = key; 12952 key = NULL; 12953 } 12954 12955 ISC_LIST_APPEND(zone->notifies, notify, link); 12956 result = notify_send_queue(notify, startup); 12957 if (result != ISC_R_SUCCESS) { 12958 notify_destroy(notify, true); 12959 } 12960 if (!loggednotify) { 12961 notify_log(zone, ISC_LOG_INFO, 12962 "sending notifies (serial %u)", serial); 12963 loggednotify = true; 12964 } 12965 } 12966 UNLOCK_ZONE(zone); 12967 12968 if (notifytype == dns_notifytype_explicit) { 12969 goto cleanup3; 12970 } 12971 12972 /* 12973 * Process NS RRset to generate notifies. 12974 */ 12975 12976 dns_rdataset_init(&nsrdset); 12977 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns, 12978 dns_rdatatype_none, 0, &nsrdset, NULL); 12979 if (result != ISC_R_SUCCESS) { 12980 goto cleanup3; 12981 } 12982 12983 result = dns_rdataset_first(&nsrdset); 12984 while (result == ISC_R_SUCCESS) { 12985 dns_notify_t *notify = NULL; 12986 12987 dns_rdataset_current(&nsrdset, &rdata); 12988 result = dns_rdata_tostruct(&rdata, &ns, NULL); 12989 RUNTIME_CHECK(result == ISC_R_SUCCESS); 12990 dns_rdata_reset(&rdata); 12991 /* 12992 * Don't notify the master server unless explicitly 12993 * configured to do so. 12994 */ 12995 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) && 12996 dns_name_compare(&master, &ns.name) == 0) 12997 { 12998 result = dns_rdataset_next(&nsrdset); 12999 continue; 13000 } 13001 13002 if (!loggednotify) { 13003 notify_log(zone, ISC_LOG_INFO, 13004 "sending notifies (serial %u)", serial); 13005 loggednotify = true; 13006 } 13007 13008 LOCK_ZONE(zone); 13009 isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL); 13010 UNLOCK_ZONE(zone); 13011 if (isqueued) { 13012 result = dns_rdataset_next(&nsrdset); 13013 continue; 13014 } 13015 result = notify_create(zone->mctx, flags, ¬ify); 13016 if (result != ISC_R_SUCCESS) { 13017 continue; 13018 } 13019 dns_zone_iattach(zone, ¬ify->zone); 13020 dns_name_dup(&ns.name, zone->mctx, ¬ify->ns); 13021 LOCK_ZONE(zone); 13022 ISC_LIST_APPEND(zone->notifies, notify, link); 13023 UNLOCK_ZONE(zone); 13024 notify_find_address(notify); 13025 result = dns_rdataset_next(&nsrdset); 13026 } 13027 dns_rdataset_disassociate(&nsrdset); 13028 13029cleanup3: 13030 if (dns_name_dynamic(&master)) { 13031 dns_name_free(&master, zone->mctx); 13032 } 13033cleanup2: 13034 dns_db_detachnode(zonedb, &node); 13035cleanup1: 13036 dns_db_closeversion(zonedb, &version, false); 13037 dns_db_detach(&zonedb); 13038} 13039 13040/*** 13041 *** Private 13042 ***/ 13043static isc_result_t 13044create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, dns_name_t *name, 13045 dns_message_t **messagep) { 13046 dns_message_t *message = NULL; 13047 dns_name_t *qname = NULL; 13048 dns_rdataset_t *qrdataset = NULL; 13049 isc_result_t result; 13050 13051 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message); 13052 13053 message->opcode = dns_opcode_query; 13054 message->rdclass = zone->rdclass; 13055 13056 result = dns_message_gettempname(message, &qname); 13057 if (result != ISC_R_SUCCESS) { 13058 goto cleanup; 13059 } 13060 13061 result = dns_message_gettemprdataset(message, &qrdataset); 13062 if (result != ISC_R_SUCCESS) { 13063 goto cleanup; 13064 } 13065 13066 /* 13067 * Make question. 13068 */ 13069 dns_name_clone(name, qname); 13070 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype); 13071 ISC_LIST_APPEND(qname->list, qrdataset, link); 13072 dns_message_addname(message, qname, DNS_SECTION_QUESTION); 13073 13074 *messagep = message; 13075 return (ISC_R_SUCCESS); 13076 13077cleanup: 13078 if (qname != NULL) { 13079 dns_message_puttempname(message, &qname); 13080 } 13081 if (qrdataset != NULL) { 13082 dns_message_puttemprdataset(message, &qrdataset); 13083 } 13084 dns_message_detach(&message); 13085 return (result); 13086} 13087 13088static isc_result_t 13089add_opt(dns_message_t *message, uint16_t udpsize, bool reqnsid, 13090 bool reqexpire) { 13091 isc_result_t result; 13092 dns_rdataset_t *rdataset = NULL; 13093 dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS]; 13094 int count = 0; 13095 13096 /* Set EDNS options if applicable. */ 13097 if (reqnsid) { 13098 INSIST(count < DNS_EDNSOPTIONS); 13099 ednsopts[count].code = DNS_OPT_NSID; 13100 ednsopts[count].length = 0; 13101 ednsopts[count].value = NULL; 13102 count++; 13103 } 13104 if (reqexpire) { 13105 INSIST(count < DNS_EDNSOPTIONS); 13106 ednsopts[count].code = DNS_OPT_EXPIRE; 13107 ednsopts[count].length = 0; 13108 ednsopts[count].value = NULL; 13109 count++; 13110 } 13111 result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0, 13112 ednsopts, count); 13113 if (result != ISC_R_SUCCESS) { 13114 return (result); 13115 } 13116 13117 return (dns_message_setopt(message, rdataset)); 13118} 13119 13120/* 13121 * Called when stub zone update is finished. 13122 * Update zone refresh, retry, expire values accordingly with 13123 * SOA received from master, sync database to file, restart 13124 * zone management timer. 13125 */ 13126static void 13127stub_finish_zone_update(dns_stub_t *stub, isc_time_t now) { 13128 uint32_t refresh, retry, expire; 13129 isc_result_t result; 13130 isc_interval_t i; 13131 unsigned int soacount; 13132 dns_zone_t *zone = stub->zone; 13133 13134 /* 13135 * Tidy up. 13136 */ 13137 dns_db_closeversion(stub->db, &stub->version, true); 13138 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 13139 if (zone->db == NULL) { 13140 zone_attachdb(zone, stub->db); 13141 } 13142 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, NULL, 13143 &refresh, &retry, &expire, NULL, NULL); 13144 if (result == ISC_R_SUCCESS && soacount > 0U) { 13145 zone->refresh = RANGE(refresh, zone->minrefresh, 13146 zone->maxrefresh); 13147 zone->retry = RANGE(retry, zone->minretry, zone->maxretry); 13148 zone->expire = RANGE(expire, zone->refresh + zone->retry, 13149 DNS_MAX_EXPIRE); 13150 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 13151 } 13152 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 13153 dns_db_detach(&stub->db); 13154 13155 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 13156 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 13157 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 13158 isc_interval_set(&i, zone->expire, 0); 13159 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); 13160 13161 if (zone->masterfile != NULL) { 13162 zone_needdump(zone, 0); 13163 } 13164 13165 zone_settimer(zone, &now); 13166} 13167 13168/* 13169 * Process answers for A and AAAA queries when 13170 * resolving nameserver addresses for which glue 13171 * was missing in a previous answer for a NS query. 13172 */ 13173static void 13174stub_glue_response_cb(isc_task_t *task, isc_event_t *event) { 13175 const char me[] = "stub_glue_response_cb"; 13176 dns_requestevent_t *revent = (dns_requestevent_t *)event; 13177 dns_stub_t *stub = NULL; 13178 dns_message_t *msg = NULL; 13179 dns_zone_t *zone = NULL; 13180 char master[ISC_SOCKADDR_FORMATSIZE]; 13181 char source[ISC_SOCKADDR_FORMATSIZE]; 13182 uint32_t addr_count, cnamecnt; 13183 isc_result_t result; 13184 isc_time_t now; 13185 struct stub_glue_request *request; 13186 struct stub_cb_args *cb_args; 13187 dns_rdataset_t *addr_rdataset = NULL; 13188 dns_dbnode_t *node = NULL; 13189 13190 UNUSED(task); 13191 13192 request = revent->ev_arg; 13193 cb_args = request->args; 13194 stub = cb_args->stub; 13195 INSIST(DNS_STUB_VALID(stub)); 13196 13197 zone = stub->zone; 13198 13199 ENTER; 13200 13201 TIME_NOW(&now); 13202 13203 LOCK_ZONE(zone); 13204 13205 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 13206 zone_debuglog(zone, me, 1, "exiting"); 13207 goto cleanup; 13208 } 13209 13210 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 13211 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 13212 13213 if (revent->result != ISC_R_SUCCESS) { 13214 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr, 13215 &zone->sourceaddr, &now); 13216 dns_zone_log(zone, ISC_LOG_INFO, 13217 "could not refresh stub from master %s" 13218 " (source %s): %s", 13219 master, source, dns_result_totext(revent->result)); 13220 goto cleanup; 13221 } 13222 13223 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 13224 result = dns_request_getresponse(revent->request, msg, 0); 13225 if (result != ISC_R_SUCCESS) { 13226 dns_zone_log(zone, ISC_LOG_INFO, 13227 "refreshing stub: unable to parse response (%s)", 13228 isc_result_totext(result)); 13229 goto cleanup; 13230 } 13231 13232 /* 13233 * Unexpected opcode. 13234 */ 13235 if (msg->opcode != dns_opcode_query) { 13236 char opcode[128]; 13237 isc_buffer_t rb; 13238 13239 isc_buffer_init(&rb, opcode, sizeof(opcode)); 13240 (void)dns_opcode_totext(msg->opcode, &rb); 13241 13242 dns_zone_log(zone, ISC_LOG_INFO, 13243 "refreshing stub: " 13244 "unexpected opcode (%.*s) from %s (source %s)", 13245 (int)rb.used, opcode, master, source); 13246 goto cleanup; 13247 } 13248 13249 /* 13250 * Unexpected rcode. 13251 */ 13252 if (msg->rcode != dns_rcode_noerror) { 13253 char rcode[128]; 13254 isc_buffer_t rb; 13255 13256 isc_buffer_init(&rb, rcode, sizeof(rcode)); 13257 (void)dns_rcode_totext(msg->rcode, &rb); 13258 13259 dns_zone_log(zone, ISC_LOG_INFO, 13260 "refreshing stub: " 13261 "unexpected rcode (%.*s) from %s (source %s)", 13262 (int)rb.used, rcode, master, source); 13263 goto cleanup; 13264 } 13265 13266 /* 13267 * We need complete messages. 13268 */ 13269 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 13270 if (dns_request_usedtcp(revent->request)) { 13271 dns_zone_log(zone, ISC_LOG_INFO, 13272 "refreshing stub: truncated TCP " 13273 "response from master %s (source %s)", 13274 master, source); 13275 } 13276 goto cleanup; 13277 } 13278 13279 /* 13280 * If non-auth log. 13281 */ 13282 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 13283 dns_zone_log(zone, ISC_LOG_INFO, 13284 "refreshing stub: " 13285 "non-authoritative answer from " 13286 "master %s (source %s)", 13287 master, source); 13288 goto cleanup; 13289 } 13290 13291 /* 13292 * Sanity checks. 13293 */ 13294 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 13295 addr_count = message_count(msg, DNS_SECTION_ANSWER, 13296 request->ipv4 ? dns_rdatatype_a 13297 : dns_rdatatype_aaaa); 13298 13299 if (cnamecnt != 0) { 13300 dns_zone_log(zone, ISC_LOG_INFO, 13301 "refreshing stub: unexpected CNAME response " 13302 "from master %s (source %s)", 13303 master, source); 13304 goto cleanup; 13305 } 13306 13307 if (addr_count == 0) { 13308 dns_zone_log(zone, ISC_LOG_INFO, 13309 "refreshing stub: no %s records in response " 13310 "from master %s (source %s)", 13311 request->ipv4 ? "A" : "AAAA", master, source); 13312 goto cleanup; 13313 } 13314 /* 13315 * Extract A or AAAA RRset from message. 13316 */ 13317 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &request->name, 13318 request->ipv4 ? dns_rdatatype_a 13319 : dns_rdatatype_aaaa, 13320 dns_rdatatype_none, NULL, &addr_rdataset); 13321 if (result != ISC_R_SUCCESS) { 13322 if (result != DNS_R_NXDOMAIN && result != DNS_R_NXRRSET) { 13323 char namebuf[DNS_NAME_FORMATSIZE]; 13324 dns_name_format(&request->name, namebuf, 13325 sizeof(namebuf)); 13326 dns_zone_log( 13327 zone, ISC_LOG_INFO, 13328 "refreshing stub: dns_message_findname(%s/%s) " 13329 "failed (%s)", 13330 namebuf, request->ipv4 ? "A" : "AAAA", 13331 isc_result_totext(result)); 13332 } 13333 goto cleanup; 13334 } 13335 13336 result = dns_db_findnode(stub->db, &request->name, true, &node); 13337 if (result != ISC_R_SUCCESS) { 13338 dns_zone_log(zone, ISC_LOG_INFO, 13339 "refreshing stub: " 13340 "dns_db_findnode() failed: %s", 13341 dns_result_totext(result)); 13342 goto cleanup; 13343 } 13344 13345 result = dns_db_addrdataset(stub->db, node, stub->version, 0, 13346 addr_rdataset, 0, NULL); 13347 if (result != ISC_R_SUCCESS) { 13348 dns_zone_log(zone, ISC_LOG_INFO, 13349 "refreshing stub: " 13350 "dns_db_addrdataset() failed: %s", 13351 dns_result_totext(result)); 13352 } 13353 dns_db_detachnode(stub->db, &node); 13354 13355cleanup: 13356 if (msg != NULL) { 13357 dns_message_detach(&msg); 13358 } 13359 isc_event_free(&event); 13360 dns_name_free(&request->name, zone->mctx); 13361 dns_request_destroy(&request->request); 13362 isc_mem_put(zone->mctx, request, sizeof(*request)); 13363 13364 /* If last request, release all related resources */ 13365 if (atomic_fetch_sub_release(&stub->pending_requests, 1) == 1) { 13366 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13367 stub_finish_zone_update(stub, now); 13368 UNLOCK_ZONE(zone); 13369 stub->magic = 0; 13370 dns_zone_idetach(&stub->zone); 13371 INSIST(stub->db == NULL); 13372 INSIST(stub->version == NULL); 13373 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 13374 } else { 13375 UNLOCK_ZONE(zone); 13376 } 13377} 13378 13379/* 13380 * Create and send an A or AAAA query to the master 13381 * server of the stub zone given. 13382 */ 13383static isc_result_t 13384stub_request_nameserver_address(struct stub_cb_args *args, bool ipv4, 13385 const dns_name_t *name) { 13386 dns_message_t *message = NULL; 13387 dns_zone_t *zone; 13388 isc_result_t result; 13389 struct stub_glue_request *request; 13390 13391 zone = args->stub->zone; 13392 request = isc_mem_get(zone->mctx, sizeof(*request)); 13393 request->request = NULL; 13394 request->args = args; 13395 request->name = (dns_name_t)DNS_NAME_INITEMPTY; 13396 request->ipv4 = ipv4; 13397 dns_name_dup(name, zone->mctx, &request->name); 13398 13399 result = create_query(zone, ipv4 ? dns_rdatatype_a : dns_rdatatype_aaaa, 13400 &request->name, &message); 13401 INSIST(result == ISC_R_SUCCESS); 13402 13403 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 13404 result = add_opt(message, args->udpsize, args->reqnsid, false); 13405 if (result != ISC_R_SUCCESS) { 13406 zone_debuglog(zone, "stub_send_query", 1, 13407 "unable to add opt record: %s", 13408 dns_result_totext(result)); 13409 goto fail; 13410 } 13411 } 13412 13413 atomic_fetch_add_release(&args->stub->pending_requests, 1); 13414 13415 result = dns_request_createvia( 13416 zone->view->requestmgr, message, &zone->sourceaddr, 13417 &zone->masteraddr, args->dscp, DNS_REQUESTOPT_TCP, 13418 args->tsig_key, args->timeout * 3, args->timeout, 0, zone->task, 13419 stub_glue_response_cb, request, &request->request); 13420 13421 if (result != ISC_R_SUCCESS) { 13422 INSIST(atomic_fetch_sub_release(&args->stub->pending_requests, 13423 1) > 1); 13424 zone_debuglog(zone, "stub_send_query", 1, 13425 "dns_request_createvia() failed: %s", 13426 dns_result_totext(result)); 13427 goto fail; 13428 } 13429 13430 dns_message_detach(&message); 13431 13432 return (ISC_R_SUCCESS); 13433 13434fail: 13435 dns_name_free(&request->name, zone->mctx); 13436 isc_mem_put(zone->mctx, request, sizeof(*request)); 13437 13438 if (message != NULL) { 13439 dns_message_detach(&message); 13440 } 13441 13442 return (result); 13443} 13444 13445static isc_result_t 13446save_nsrrset(dns_message_t *message, dns_name_t *name, 13447 struct stub_cb_args *cb_args, dns_db_t *db, 13448 dns_dbversion_t *version) { 13449 dns_rdataset_t *nsrdataset = NULL; 13450 dns_rdataset_t *rdataset = NULL; 13451 dns_dbnode_t *node = NULL; 13452 dns_rdata_ns_t ns; 13453 isc_result_t result; 13454 dns_rdata_t rdata = DNS_RDATA_INIT; 13455 bool has_glue = false; 13456 dns_name_t *ns_name; 13457 /* 13458 * List of NS entries in answer, keep names that will be used 13459 * to resolve missing A/AAAA glue for each entry. 13460 */ 13461 dns_namelist_t ns_list; 13462 ISC_LIST_INIT(ns_list); 13463 13464 /* 13465 * Extract NS RRset from message. 13466 */ 13467 result = dns_message_findname(message, DNS_SECTION_ANSWER, name, 13468 dns_rdatatype_ns, dns_rdatatype_none, 13469 NULL, &nsrdataset); 13470 if (result != ISC_R_SUCCESS) { 13471 goto done; 13472 } 13473 13474 /* 13475 * Add NS rdataset. 13476 */ 13477 result = dns_db_findnode(db, name, true, &node); 13478 if (result != ISC_R_SUCCESS) { 13479 goto done; 13480 } 13481 result = dns_db_addrdataset(db, node, version, 0, nsrdataset, 0, NULL); 13482 dns_db_detachnode(db, &node); 13483 if (result != ISC_R_SUCCESS) { 13484 goto done; 13485 } 13486 /* 13487 * Add glue rdatasets. 13488 */ 13489 for (result = dns_rdataset_first(nsrdataset); result == ISC_R_SUCCESS; 13490 result = dns_rdataset_next(nsrdataset)) 13491 { 13492 dns_rdataset_current(nsrdataset, &rdata); 13493 result = dns_rdata_tostruct(&rdata, &ns, NULL); 13494 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13495 dns_rdata_reset(&rdata); 13496 13497 if (!dns_name_issubdomain(&ns.name, name)) { 13498 continue; 13499 } 13500 rdataset = NULL; 13501 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL, 13502 &ns.name, dns_rdatatype_aaaa, 13503 dns_rdatatype_none, NULL, 13504 &rdataset); 13505 if (result == ISC_R_SUCCESS) { 13506 has_glue = true; 13507 result = dns_db_findnode(db, &ns.name, true, &node); 13508 if (result != ISC_R_SUCCESS) { 13509 goto done; 13510 } 13511 result = dns_db_addrdataset(db, node, version, 0, 13512 rdataset, 0, NULL); 13513 dns_db_detachnode(db, &node); 13514 if (result != ISC_R_SUCCESS) { 13515 goto done; 13516 } 13517 } 13518 13519 rdataset = NULL; 13520 result = dns_message_findname( 13521 message, DNS_SECTION_ADDITIONAL, &ns.name, 13522 dns_rdatatype_a, dns_rdatatype_none, NULL, &rdataset); 13523 if (result == ISC_R_SUCCESS) { 13524 has_glue = true; 13525 result = dns_db_findnode(db, &ns.name, true, &node); 13526 if (result != ISC_R_SUCCESS) { 13527 goto done; 13528 } 13529 result = dns_db_addrdataset(db, node, version, 0, 13530 rdataset, 0, NULL); 13531 dns_db_detachnode(db, &node); 13532 if (result != ISC_R_SUCCESS) { 13533 goto done; 13534 } 13535 } 13536 13537 /* 13538 * If no glue is found so far, we add the name to the list to 13539 * resolve the A/AAAA glue later. If any glue is found in any 13540 * iteration step, this list will be discarded and only the glue 13541 * provided in this message will be used. 13542 */ 13543 if (!has_glue && dns_name_issubdomain(&ns.name, name)) { 13544 dns_name_t *tmp_name; 13545 tmp_name = isc_mem_get(cb_args->stub->mctx, 13546 sizeof(*tmp_name)); 13547 dns_name_init(tmp_name, NULL); 13548 dns_name_dup(&ns.name, cb_args->stub->mctx, tmp_name); 13549 ISC_LIST_APPEND(ns_list, tmp_name, link); 13550 } 13551 } 13552 13553 if (result != ISC_R_NOMORE) { 13554 goto done; 13555 } 13556 13557 /* 13558 * If no glue records were found, we attempt to resolve A/AAAA 13559 * for each NS entry found in the answer. 13560 */ 13561 if (!has_glue) { 13562 for (ns_name = ISC_LIST_HEAD(ns_list); ns_name != NULL; 13563 ns_name = ISC_LIST_NEXT(ns_name, link)) 13564 { 13565 /* 13566 * Resolve NS IPv4 address/A. 13567 */ 13568 result = stub_request_nameserver_address(cb_args, true, 13569 ns_name); 13570 if (result != ISC_R_SUCCESS) { 13571 goto done; 13572 } 13573 /* 13574 * Resolve NS IPv6 address/AAAA. 13575 */ 13576 result = stub_request_nameserver_address(cb_args, false, 13577 ns_name); 13578 if (result != ISC_R_SUCCESS) { 13579 goto done; 13580 } 13581 } 13582 } 13583 13584 result = ISC_R_SUCCESS; 13585 13586done: 13587 while ((ns_name = ISC_LIST_HEAD(ns_list)) != NULL) { 13588 ISC_LIST_UNLINK(ns_list, ns_name, link); 13589 dns_name_free(ns_name, cb_args->stub->mctx); 13590 isc_mem_put(cb_args->stub->mctx, ns_name, sizeof(*ns_name)); 13591 } 13592 return (result); 13593} 13594 13595static void 13596stub_callback(isc_task_t *task, isc_event_t *event) { 13597 const char me[] = "stub_callback"; 13598 dns_requestevent_t *revent = (dns_requestevent_t *)event; 13599 dns_stub_t *stub = NULL; 13600 dns_message_t *msg = NULL; 13601 dns_zone_t *zone = NULL; 13602 char master[ISC_SOCKADDR_FORMATSIZE]; 13603 char source[ISC_SOCKADDR_FORMATSIZE]; 13604 uint32_t nscnt, cnamecnt; 13605 isc_result_t result; 13606 isc_time_t now; 13607 bool exiting = false; 13608 unsigned int j; 13609 struct stub_cb_args *cb_args; 13610 13611 cb_args = revent->ev_arg; 13612 stub = cb_args->stub; 13613 INSIST(DNS_STUB_VALID(stub)); 13614 13615 UNUSED(task); 13616 13617 zone = stub->zone; 13618 13619 ENTER; 13620 13621 TIME_NOW(&now); 13622 13623 LOCK_ZONE(zone); 13624 13625 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 13626 zone_debuglog(zone, me, 1, "exiting"); 13627 exiting = true; 13628 goto next_master; 13629 } 13630 13631 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 13632 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 13633 13634 if (revent->result != ISC_R_SUCCESS) { 13635 if (revent->result == ISC_R_TIMEDOUT && 13636 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) 13637 { 13638 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 13639 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13640 "refreshing stub: timeout retrying " 13641 " without EDNS master %s (source %s)", 13642 master, source); 13643 goto same_master; 13644 } 13645 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr, 13646 &zone->sourceaddr, &now); 13647 dns_zone_log(zone, ISC_LOG_INFO, 13648 "could not refresh stub from master %s" 13649 " (source %s): %s", 13650 master, source, dns_result_totext(revent->result)); 13651 goto next_master; 13652 } 13653 13654 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 13655 13656 result = dns_request_getresponse(revent->request, msg, 0); 13657 if (result != ISC_R_SUCCESS) { 13658 goto next_master; 13659 } 13660 13661 /* 13662 * Unexpected opcode. 13663 */ 13664 if (msg->opcode != dns_opcode_query) { 13665 char opcode[128]; 13666 isc_buffer_t rb; 13667 13668 isc_buffer_init(&rb, opcode, sizeof(opcode)); 13669 (void)dns_opcode_totext(msg->opcode, &rb); 13670 13671 dns_zone_log(zone, ISC_LOG_INFO, 13672 "refreshing stub: " 13673 "unexpected opcode (%.*s) from %s (source %s)", 13674 (int)rb.used, opcode, master, source); 13675 goto next_master; 13676 } 13677 13678 /* 13679 * Unexpected rcode. 13680 */ 13681 if (msg->rcode != dns_rcode_noerror) { 13682 char rcode[128]; 13683 isc_buffer_t rb; 13684 13685 isc_buffer_init(&rb, rcode, sizeof(rcode)); 13686 (void)dns_rcode_totext(msg->rcode, &rb); 13687 13688 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 13689 (msg->rcode == dns_rcode_servfail || 13690 msg->rcode == dns_rcode_notimp || 13691 msg->rcode == dns_rcode_formerr)) 13692 { 13693 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13694 "refreshing stub: rcode (%.*s) retrying " 13695 "without EDNS master %s (source %s)", 13696 (int)rb.used, rcode, master, source); 13697 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 13698 goto same_master; 13699 } 13700 13701 dns_zone_log(zone, ISC_LOG_INFO, 13702 "refreshing stub: " 13703 "unexpected rcode (%.*s) from %s (source %s)", 13704 (int)rb.used, rcode, master, source); 13705 goto next_master; 13706 } 13707 13708 /* 13709 * We need complete messages. 13710 */ 13711 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 13712 if (dns_request_usedtcp(revent->request)) { 13713 dns_zone_log(zone, ISC_LOG_INFO, 13714 "refreshing stub: truncated TCP " 13715 "response from master %s (source %s)", 13716 master, source); 13717 goto next_master; 13718 } 13719 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 13720 goto same_master; 13721 } 13722 13723 /* 13724 * If non-auth log and next master. 13725 */ 13726 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 13727 dns_zone_log(zone, ISC_LOG_INFO, 13728 "refreshing stub: " 13729 "non-authoritative answer from " 13730 "master %s (source %s)", 13731 master, source); 13732 goto next_master; 13733 } 13734 13735 /* 13736 * Sanity checks. 13737 */ 13738 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 13739 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns); 13740 13741 if (cnamecnt != 0) { 13742 dns_zone_log(zone, ISC_LOG_INFO, 13743 "refreshing stub: unexpected CNAME response " 13744 "from master %s (source %s)", 13745 master, source); 13746 goto next_master; 13747 } 13748 13749 if (nscnt == 0) { 13750 dns_zone_log(zone, ISC_LOG_INFO, 13751 "refreshing stub: no NS records in response " 13752 "from master %s (source %s)", 13753 master, source); 13754 goto next_master; 13755 } 13756 13757 atomic_fetch_add(&stub->pending_requests, 1); 13758 13759 /* 13760 * Save answer. 13761 */ 13762 result = save_nsrrset(msg, &zone->origin, cb_args, stub->db, 13763 stub->version); 13764 if (result != ISC_R_SUCCESS) { 13765 dns_zone_log(zone, ISC_LOG_INFO, 13766 "refreshing stub: unable to save NS records " 13767 "from master %s (source %s)", 13768 master, source); 13769 goto next_master; 13770 } 13771 13772 dns_message_detach(&msg); 13773 isc_event_free(&event); 13774 dns_request_destroy(&zone->request); 13775 13776 /* 13777 * Check to see if there are no outstanding requests and 13778 * finish off if that is so. 13779 */ 13780 if (atomic_fetch_sub(&stub->pending_requests, 1) == 1) { 13781 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13782 stub_finish_zone_update(stub, now); 13783 goto free_stub; 13784 } 13785 13786 UNLOCK_ZONE(zone); 13787 return; 13788 13789next_master: 13790 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13791 if (stub->version != NULL) { 13792 dns_db_closeversion(stub->db, &stub->version, false); 13793 } 13794 if (stub->db != NULL) { 13795 dns_db_detach(&stub->db); 13796 } 13797 if (msg != NULL) { 13798 dns_message_detach(&msg); 13799 } 13800 isc_event_free(&event); 13801 dns_request_destroy(&zone->request); 13802 /* 13803 * Skip to next failed / untried master. 13804 */ 13805 do { 13806 zone->curmaster++; 13807 } while (zone->curmaster < zone->masterscnt && 13808 zone->mastersok[zone->curmaster]); 13809 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 13810 if (exiting || zone->curmaster >= zone->masterscnt) { 13811 bool done = true; 13812 if (!exiting && 13813 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 13814 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) 13815 { 13816 /* 13817 * Did we get a good answer from all the primaries? 13818 */ 13819 for (j = 0; j < zone->masterscnt; j++) { 13820 if (!zone->mastersok[j]) { 13821 { 13822 done = false; 13823 break; 13824 } 13825 } 13826 } 13827 } else { 13828 done = true; 13829 } 13830 if (!done) { 13831 zone->curmaster = 0; 13832 /* 13833 * Find the next failed master. 13834 */ 13835 while (zone->curmaster < zone->masterscnt && 13836 zone->mastersok[zone->curmaster]) 13837 { 13838 zone->curmaster++; 13839 } 13840 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 13841 } else { 13842 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 13843 13844 zone_settimer(zone, &now); 13845 goto free_stub; 13846 } 13847 } 13848 queue_soa_query(zone); 13849 goto free_stub; 13850 13851same_master: 13852 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13853 if (msg != NULL) { 13854 dns_message_detach(&msg); 13855 } 13856 isc_event_free(&event); 13857 dns_request_destroy(&zone->request); 13858 ns_query(zone, NULL, stub); 13859 UNLOCK_ZONE(zone); 13860 goto done; 13861 13862free_stub: 13863 UNLOCK_ZONE(zone); 13864 stub->magic = 0; 13865 dns_zone_idetach(&stub->zone); 13866 INSIST(stub->db == NULL); 13867 INSIST(stub->version == NULL); 13868 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 13869 13870done: 13871 INSIST(event == NULL); 13872 return; 13873} 13874 13875/* 13876 * Get the EDNS EXPIRE option from the response and if it exists trim 13877 * expire to be not more than it. 13878 */ 13879static void 13880get_edns_expire(dns_zone_t *zone, dns_message_t *message, uint32_t *expirep) { 13881 isc_result_t result; 13882 uint32_t expire; 13883 dns_rdata_t rdata = DNS_RDATA_INIT; 13884 isc_buffer_t optbuf; 13885 uint16_t optcode; 13886 uint16_t optlen; 13887 13888 REQUIRE(expirep != NULL); 13889 REQUIRE(message != NULL); 13890 13891 if (message->opt == NULL) { 13892 return; 13893 } 13894 13895 result = dns_rdataset_first(message->opt); 13896 if (result == ISC_R_SUCCESS) { 13897 dns_rdataset_current(message->opt, &rdata); 13898 isc_buffer_init(&optbuf, rdata.data, rdata.length); 13899 isc_buffer_add(&optbuf, rdata.length); 13900 while (isc_buffer_remaininglength(&optbuf) >= 4) { 13901 optcode = isc_buffer_getuint16(&optbuf); 13902 optlen = isc_buffer_getuint16(&optbuf); 13903 /* 13904 * A EDNS EXPIRE response has a length of 4. 13905 */ 13906 if (optcode != DNS_OPT_EXPIRE || optlen != 4) { 13907 isc_buffer_forward(&optbuf, optlen); 13908 continue; 13909 } 13910 expire = isc_buffer_getuint32(&optbuf); 13911 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13912 "got EDNS EXPIRE of %u", expire); 13913 /* 13914 * Trim *expirep? 13915 */ 13916 if (expire < *expirep) { 13917 *expirep = expire; 13918 } 13919 break; 13920 } 13921 } 13922} 13923 13924/* 13925 * Set the file modification time zone->expire seconds before expiretime. 13926 */ 13927static void 13928setmodtime(dns_zone_t *zone, isc_time_t *expiretime) { 13929 isc_result_t result; 13930 isc_time_t when; 13931 isc_interval_t i; 13932 13933 isc_interval_set(&i, zone->expire, 0); 13934 result = isc_time_subtract(expiretime, &i, &when); 13935 if (result != ISC_R_SUCCESS) { 13936 return; 13937 } 13938 13939 result = ISC_R_FAILURE; 13940 if (zone->journal != NULL) { 13941 result = isc_file_settime(zone->journal, &when); 13942 } 13943 if (result == ISC_R_SUCCESS && 13944 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 13945 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 13946 { 13947 result = isc_file_settime(zone->masterfile, &when); 13948 } else if (result != ISC_R_SUCCESS) { 13949 result = isc_file_settime(zone->masterfile, &when); 13950 } 13951 13952 /* 13953 * Someone removed the file from underneath us! 13954 */ 13955 if (result == ISC_R_FILENOTFOUND) { 13956 zone_needdump(zone, DNS_DUMP_DELAY); 13957 } else if (result != ISC_R_SUCCESS) { 13958 dns_zone_log(zone, ISC_LOG_ERROR, 13959 "refresh: could not set " 13960 "file modification time of '%s': %s", 13961 zone->masterfile, dns_result_totext(result)); 13962 } 13963} 13964 13965/* 13966 * An SOA query has finished (successfully or not). 13967 */ 13968static void 13969refresh_callback(isc_task_t *task, isc_event_t *event) { 13970 const char me[] = "refresh_callback"; 13971 dns_requestevent_t *revent = (dns_requestevent_t *)event; 13972 dns_zone_t *zone; 13973 dns_message_t *msg = NULL; 13974 uint32_t soacnt, cnamecnt, soacount, nscount; 13975 isc_time_t now; 13976 char master[ISC_SOCKADDR_FORMATSIZE]; 13977 char source[ISC_SOCKADDR_FORMATSIZE]; 13978 dns_rdataset_t *rdataset = NULL; 13979 dns_rdata_t rdata = DNS_RDATA_INIT; 13980 dns_rdata_soa_t soa; 13981 isc_result_t result; 13982 uint32_t serial, oldserial = 0; 13983 unsigned int j; 13984 bool do_queue_xfrin = false; 13985 13986 zone = revent->ev_arg; 13987 INSIST(DNS_ZONE_VALID(zone)); 13988 13989 UNUSED(task); 13990 13991 ENTER; 13992 13993 TIME_NOW(&now); 13994 13995 LOCK_ZONE(zone); 13996 13997 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 13998 isc_event_free(&event); 13999 dns_request_destroy(&zone->request); 14000 goto detach; 14001 } 14002 14003 /* 14004 * if timeout log and next master; 14005 */ 14006 14007 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 14008 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 14009 14010 if (revent->result != ISC_R_SUCCESS) { 14011 if (revent->result == ISC_R_TIMEDOUT && 14012 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) 14013 { 14014 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14015 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14016 "refresh: timeout retrying without EDNS " 14017 "master %s (source %s)", 14018 master, source); 14019 goto same_master; 14020 } 14021 if (revent->result == ISC_R_TIMEDOUT && 14022 !dns_request_usedtcp(revent->request)) 14023 { 14024 dns_zone_log(zone, ISC_LOG_INFO, 14025 "refresh: retry limit for " 14026 "master %s exceeded (source %s)", 14027 master, source); 14028 /* Try with slave with TCP. */ 14029 if ((zone->type == dns_zone_secondary || 14030 zone->type == dns_zone_mirror || 14031 zone->type == dns_zone_redirect) && 14032 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) 14033 { 14034 if (!dns_zonemgr_unreachable( 14035 zone->zmgr, &zone->masteraddr, 14036 &zone->sourceaddr, &now)) 14037 { 14038 DNS_ZONE_SETFLAG( 14039 zone, 14040 DNS_ZONEFLG_SOABEFOREAXFR); 14041 goto tcp_transfer; 14042 } 14043 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14044 "refresh: skipped tcp fallback " 14045 "as master %s (source %s) is " 14046 "unreachable (cached)", 14047 master, source); 14048 } 14049 } else { 14050 dns_zone_log(zone, ISC_LOG_INFO, 14051 "refresh: failure trying master " 14052 "%s (source %s): %s", 14053 master, source, 14054 dns_result_totext(revent->result)); 14055 } 14056 goto next_master; 14057 } 14058 14059 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 14060 result = dns_request_getresponse(revent->request, msg, 0); 14061 if (result != ISC_R_SUCCESS) { 14062 dns_zone_log(zone, ISC_LOG_INFO, 14063 "refresh: failure trying master " 14064 "%s (source %s): %s", 14065 master, source, dns_result_totext(result)); 14066 goto next_master; 14067 } 14068 14069 /* 14070 * Unexpected opcode. 14071 */ 14072 if (msg->opcode != dns_opcode_query) { 14073 char opcode[128]; 14074 isc_buffer_t rb; 14075 14076 isc_buffer_init(&rb, opcode, sizeof(opcode)); 14077 (void)dns_opcode_totext(msg->opcode, &rb); 14078 14079 dns_zone_log(zone, ISC_LOG_INFO, 14080 "refresh: " 14081 "unexpected opcode (%.*s) from %s (source %s)", 14082 (int)rb.used, opcode, master, source); 14083 goto next_master; 14084 } 14085 14086 /* 14087 * Unexpected rcode. 14088 */ 14089 if (msg->rcode != dns_rcode_noerror) { 14090 char rcode[128]; 14091 isc_buffer_t rb; 14092 14093 isc_buffer_init(&rb, rcode, sizeof(rcode)); 14094 (void)dns_rcode_totext(msg->rcode, &rb); 14095 14096 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 14097 (msg->rcode == dns_rcode_servfail || 14098 msg->rcode == dns_rcode_notimp || 14099 msg->rcode == dns_rcode_formerr)) 14100 { 14101 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14102 "refresh: rcode (%.*s) retrying without " 14103 "EDNS master %s (source %s)", 14104 (int)rb.used, rcode, master, source); 14105 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14106 goto same_master; 14107 } 14108 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 14109 msg->rcode == dns_rcode_badvers) 14110 { 14111 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14112 "refresh: rcode (%.*s) retrying without " 14113 "EDNS EXPIRE OPTION master %s (source %s)", 14114 (int)rb.used, rcode, master, source); 14115 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14116 goto same_master; 14117 } 14118 dns_zone_log(zone, ISC_LOG_INFO, 14119 "refresh: unexpected rcode (%.*s) from " 14120 "master %s (source %s)", 14121 (int)rb.used, rcode, master, source); 14122 /* 14123 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't. 14124 */ 14125 if (msg->rcode == dns_rcode_refused && 14126 (zone->type == dns_zone_secondary || 14127 zone->type == dns_zone_mirror || 14128 zone->type == dns_zone_redirect)) 14129 { 14130 goto tcp_transfer; 14131 } 14132 goto next_master; 14133 } 14134 14135 /* 14136 * If truncated punt to zone transfer which will query again. 14137 */ 14138 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 14139 if (zone->type == dns_zone_secondary || 14140 zone->type == dns_zone_mirror || 14141 zone->type == dns_zone_redirect) 14142 { 14143 dns_zone_log(zone, ISC_LOG_INFO, 14144 "refresh: truncated UDP answer, " 14145 "initiating TCP zone xfer " 14146 "for master %s (source %s)", 14147 master, source); 14148 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 14149 goto tcp_transfer; 14150 } else { 14151 INSIST(zone->type == dns_zone_stub); 14152 if (dns_request_usedtcp(revent->request)) { 14153 dns_zone_log(zone, ISC_LOG_INFO, 14154 "refresh: truncated TCP response " 14155 "from master %s (source %s)", 14156 master, source); 14157 goto next_master; 14158 } 14159 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 14160 goto same_master; 14161 } 14162 } 14163 14164 /* 14165 * if non-auth log and next master; 14166 */ 14167 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 14168 dns_zone_log(zone, ISC_LOG_INFO, 14169 "refresh: non-authoritative answer from " 14170 "master %s (source %s)", 14171 master, source); 14172 goto next_master; 14173 } 14174 14175 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 14176 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa); 14177 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns); 14178 soacount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_soa); 14179 14180 /* 14181 * There should not be a CNAME record at top of zone. 14182 */ 14183 if (cnamecnt != 0) { 14184 dns_zone_log(zone, ISC_LOG_INFO, 14185 "refresh: CNAME at top of zone " 14186 "in master %s (source %s)", 14187 master, source); 14188 goto next_master; 14189 } 14190 14191 /* 14192 * if referral log and next master; 14193 */ 14194 if (soacnt == 0 && soacount == 0 && nscount != 0) { 14195 dns_zone_log(zone, ISC_LOG_INFO, 14196 "refresh: referral response " 14197 "from master %s (source %s)", 14198 master, source); 14199 goto next_master; 14200 } 14201 14202 /* 14203 * if nodata log and next master; 14204 */ 14205 if (soacnt == 0 && (nscount == 0 || soacount != 0)) { 14206 dns_zone_log(zone, ISC_LOG_INFO, 14207 "refresh: NODATA response " 14208 "from master %s (source %s)", 14209 master, source); 14210 goto next_master; 14211 } 14212 14213 /* 14214 * Only one soa at top of zone. 14215 */ 14216 if (soacnt != 1) { 14217 dns_zone_log(zone, ISC_LOG_INFO, 14218 "refresh: answer SOA count (%d) != 1 " 14219 "from master %s (source %s)", 14220 soacnt, master, source); 14221 goto next_master; 14222 } 14223 14224 /* 14225 * Extract serial 14226 */ 14227 rdataset = NULL; 14228 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin, 14229 dns_rdatatype_soa, dns_rdatatype_none, 14230 NULL, &rdataset); 14231 if (result != ISC_R_SUCCESS) { 14232 dns_zone_log(zone, ISC_LOG_INFO, 14233 "refresh: unable to get SOA record " 14234 "from master %s (source %s)", 14235 master, source); 14236 goto next_master; 14237 } 14238 14239 result = dns_rdataset_first(rdataset); 14240 if (result != ISC_R_SUCCESS) { 14241 dns_zone_log(zone, ISC_LOG_INFO, 14242 "refresh: dns_rdataset_first() failed"); 14243 goto next_master; 14244 } 14245 14246 dns_rdataset_current(rdataset, &rdata); 14247 result = dns_rdata_tostruct(&rdata, &soa, NULL); 14248 RUNTIME_CHECK(result == ISC_R_SUCCESS); 14249 14250 serial = soa.serial; 14251 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 14252 unsigned int dbsoacount; 14253 result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount, 14254 NULL, &oldserial, NULL, NULL, NULL, 14255 NULL, NULL); 14256 RUNTIME_CHECK(result == ISC_R_SUCCESS); 14257 RUNTIME_CHECK(dbsoacount > 0U); 14258 zone_debuglog(zone, me, 1, "serial: new %u, old %u", serial, 14259 oldserial); 14260 } else { 14261 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded", 14262 serial); 14263 } 14264 14265 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) || 14266 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) || 14267 isc_serial_gt(serial, oldserial)) 14268 { 14269 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, 14270 &zone->sourceaddr, &now)) 14271 { 14272 dns_zone_log(zone, ISC_LOG_INFO, 14273 "refresh: skipping %s as master %s " 14274 "(source %s) is unreachable (cached)", 14275 (zone->type == dns_zone_secondary || 14276 zone->type == dns_zone_mirror || 14277 zone->type == dns_zone_redirect) 14278 ? "zone transfer" 14279 : "NS query", 14280 master, source); 14281 goto next_master; 14282 } 14283 tcp_transfer: 14284 isc_event_free(&event); 14285 dns_request_destroy(&zone->request); 14286 if (zone->type == dns_zone_secondary || 14287 zone->type == dns_zone_mirror || 14288 zone->type == dns_zone_redirect) 14289 { 14290 do_queue_xfrin = true; 14291 } else { 14292 INSIST(zone->type == dns_zone_stub); 14293 ns_query(zone, rdataset, NULL); 14294 } 14295 if (msg != NULL) { 14296 dns_message_detach(&msg); 14297 } 14298 } else if (isc_serial_eq(soa.serial, oldserial)) { 14299 isc_time_t expiretime; 14300 uint32_t expire; 14301 14302 /* 14303 * Compute the new expire time based on this response. 14304 */ 14305 expire = zone->expire; 14306 get_edns_expire(zone, msg, &expire); 14307 DNS_ZONE_TIME_ADD(&now, expire, &expiretime); 14308 14309 /* 14310 * Has the expire time improved? 14311 */ 14312 if (isc_time_compare(&expiretime, &zone->expiretime) > 0) { 14313 zone->expiretime = expiretime; 14314 if (zone->masterfile != NULL) { 14315 setmodtime(zone, &expiretime); 14316 } 14317 } 14318 14319 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 14320 zone->mastersok[zone->curmaster] = true; 14321 goto next_master; 14322 } else { 14323 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER)) { 14324 dns_zone_log(zone, ISC_LOG_INFO, 14325 "serial number (%u) " 14326 "received from master %s < ours (%u)", 14327 soa.serial, master, oldserial); 14328 } else { 14329 zone_debuglog(zone, me, 1, "ahead"); 14330 } 14331 zone->mastersok[zone->curmaster] = true; 14332 goto next_master; 14333 } 14334 if (msg != NULL) { 14335 dns_message_detach(&msg); 14336 } 14337 goto detach; 14338 14339next_master: 14340 if (msg != NULL) { 14341 dns_message_detach(&msg); 14342 } 14343 isc_event_free(&event); 14344 dns_request_destroy(&zone->request); 14345 /* 14346 * Skip to next failed / untried master. 14347 */ 14348 do { 14349 zone->curmaster++; 14350 } while (zone->curmaster < zone->masterscnt && 14351 zone->mastersok[zone->curmaster]); 14352 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 14353 if (zone->curmaster >= zone->masterscnt) { 14354 bool done = true; 14355 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 14356 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) 14357 { 14358 /* 14359 * Did we get a good answer from all the primaries? 14360 */ 14361 for (j = 0; j < zone->masterscnt; j++) { 14362 if (!zone->mastersok[j]) { 14363 { 14364 done = false; 14365 break; 14366 } 14367 } 14368 } 14369 } else { 14370 done = true; 14371 } 14372 if (!done) { 14373 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 14374 zone->curmaster = 0; 14375 /* 14376 * Find the next failed master. 14377 */ 14378 while (zone->curmaster < zone->masterscnt && 14379 zone->mastersok[zone->curmaster]) 14380 { 14381 zone->curmaster++; 14382 } 14383 goto requeue; 14384 } 14385 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 14386 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 14387 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 14388 zone->refreshtime = now; 14389 } 14390 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 14391 zone_settimer(zone, &now); 14392 goto detach; 14393 } 14394 14395requeue: 14396 queue_soa_query(zone); 14397 goto detach; 14398 14399same_master: 14400 if (msg != NULL) { 14401 dns_message_detach(&msg); 14402 } 14403 isc_event_free(&event); 14404 dns_request_destroy(&zone->request); 14405 queue_soa_query(zone); 14406 14407detach: 14408 UNLOCK_ZONE(zone); 14409 if (do_queue_xfrin) { 14410 queue_xfrin(zone); 14411 } 14412 dns_zone_idetach(&zone); 14413 return; 14414} 14415 14416static void 14417queue_soa_query(dns_zone_t *zone) { 14418 const char me[] = "queue_soa_query"; 14419 isc_event_t *e; 14420 dns_zone_t *dummy = NULL; 14421 isc_result_t result; 14422 14423 ENTER; 14424 /* 14425 * Locked by caller 14426 */ 14427 REQUIRE(LOCKED_ZONE(zone)); 14428 14429 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 14430 cancel_refresh(zone); 14431 return; 14432 } 14433 14434 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE, soa_query, 14435 zone, sizeof(isc_event_t)); 14436 14437 /* 14438 * Attach so that we won't clean up 14439 * until the event is delivered. 14440 */ 14441 zone_iattach(zone, &dummy); 14442 14443 e->ev_arg = zone; 14444 e->ev_sender = NULL; 14445 result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e); 14446 if (result != ISC_R_SUCCESS) { 14447 zone_idetach(&dummy); 14448 isc_event_free(&e); 14449 cancel_refresh(zone); 14450 } 14451} 14452 14453static void 14454soa_query(isc_task_t *task, isc_event_t *event) { 14455 const char me[] = "soa_query"; 14456 isc_result_t result = ISC_R_FAILURE; 14457 dns_message_t *message = NULL; 14458 dns_zone_t *zone = event->ev_arg; 14459 dns_zone_t *dummy = NULL; 14460 isc_netaddr_t masterip; 14461 dns_tsigkey_t *key = NULL; 14462 uint32_t options; 14463 bool cancel = true; 14464 int timeout; 14465 bool have_xfrsource, have_xfrdscp, reqnsid, reqexpire; 14466 uint16_t udpsize = SEND_BUFFER_SIZE; 14467 isc_dscp_t dscp = -1; 14468 14469 REQUIRE(DNS_ZONE_VALID(zone)); 14470 14471 UNUSED(task); 14472 14473 ENTER; 14474 14475 LOCK_ZONE(zone); 14476 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) || 14477 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || 14478 zone->view->requestmgr == NULL) 14479 { 14480 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 14481 cancel = false; 14482 } 14483 goto cleanup; 14484 } 14485 14486again: 14487 result = create_query(zone, dns_rdatatype_soa, &zone->origin, &message); 14488 if (result != ISC_R_SUCCESS) { 14489 goto cleanup; 14490 } 14491 14492 INSIST(zone->masterscnt > 0); 14493 INSIST(zone->curmaster < zone->masterscnt); 14494 14495 zone->masteraddr = zone->masters[zone->curmaster]; 14496 14497 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 14498 /* 14499 * First, look for a tsig key in the master statement, then 14500 * try for a server key. 14501 */ 14502 if ((zone->masterkeynames != NULL) && 14503 (zone->masterkeynames[zone->curmaster] != NULL)) 14504 { 14505 dns_view_t *view = dns_zone_getview(zone); 14506 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 14507 result = dns_view_gettsig(view, keyname, &key); 14508 if (result != ISC_R_SUCCESS) { 14509 char namebuf[DNS_NAME_FORMATSIZE]; 14510 dns_name_format(keyname, namebuf, sizeof(namebuf)); 14511 dns_zone_log(zone, ISC_LOG_ERROR, 14512 "unable to find key: %s", namebuf); 14513 goto skip_master; 14514 } 14515 } 14516 if (key == NULL) { 14517 result = dns_view_getpeertsig(zone->view, &masterip, &key); 14518 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 14519 char addrbuf[ISC_NETADDR_FORMATSIZE]; 14520 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf)); 14521 dns_zone_log(zone, ISC_LOG_ERROR, 14522 "unable to find TSIG key for %s", addrbuf); 14523 goto skip_master; 14524 } 14525 } 14526 14527 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? DNS_REQUESTOPT_TCP 14528 : 0; 14529 have_xfrsource = have_xfrdscp = false; 14530 reqnsid = zone->view->requestnsid; 14531 reqexpire = zone->requestexpire; 14532 if (zone->view->peers != NULL) { 14533 dns_peer_t *peer = NULL; 14534 bool edns, usetcp; 14535 result = dns_peerlist_peerbyaddr(zone->view->peers, &masterip, 14536 &peer); 14537 if (result == ISC_R_SUCCESS) { 14538 result = dns_peer_getsupportedns(peer, &edns); 14539 if (result == ISC_R_SUCCESS && !edns) { 14540 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14541 } 14542 result = dns_peer_gettransfersource(peer, 14543 &zone->sourceaddr); 14544 if (result == ISC_R_SUCCESS) { 14545 have_xfrsource = true; 14546 } 14547 (void)dns_peer_gettransferdscp(peer, &dscp); 14548 if (dscp != -1) { 14549 have_xfrdscp = true; 14550 } 14551 if (zone->view->resolver != NULL) { 14552 udpsize = dns_resolver_getudpsize( 14553 zone->view->resolver); 14554 } 14555 (void)dns_peer_getudpsize(peer, &udpsize); 14556 (void)dns_peer_getrequestnsid(peer, &reqnsid); 14557 (void)dns_peer_getrequestexpire(peer, &reqexpire); 14558 result = dns_peer_getforcetcp(peer, &usetcp); 14559 if (result == ISC_R_SUCCESS && usetcp) { 14560 options |= DNS_REQUESTOPT_TCP; 14561 } 14562 } 14563 } 14564 14565 switch (isc_sockaddr_pf(&zone->masteraddr)) { 14566 case PF_INET: 14567 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 14568 if (isc_sockaddr_equal(&zone->altxfrsource4, 14569 &zone->xfrsource4)) 14570 { 14571 goto skip_master; 14572 } 14573 zone->sourceaddr = zone->altxfrsource4; 14574 if (!have_xfrdscp) { 14575 dscp = zone->altxfrsource4dscp; 14576 } 14577 } else if (!have_xfrsource) { 14578 zone->sourceaddr = zone->xfrsource4; 14579 if (!have_xfrdscp) { 14580 dscp = zone->xfrsource4dscp; 14581 } 14582 } 14583 break; 14584 case PF_INET6: 14585 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 14586 if (isc_sockaddr_equal(&zone->altxfrsource6, 14587 &zone->xfrsource6)) 14588 { 14589 goto skip_master; 14590 } 14591 zone->sourceaddr = zone->altxfrsource6; 14592 if (!have_xfrdscp) { 14593 dscp = zone->altxfrsource6dscp; 14594 } 14595 } else if (!have_xfrsource) { 14596 zone->sourceaddr = zone->xfrsource6; 14597 if (!have_xfrdscp) { 14598 dscp = zone->xfrsource6dscp; 14599 } 14600 } 14601 break; 14602 default: 14603 result = ISC_R_NOTIMPLEMENTED; 14604 goto cleanup; 14605 } 14606 14607 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 14608 result = add_opt(message, udpsize, reqnsid, reqexpire); 14609 if (result != ISC_R_SUCCESS) { 14610 zone_debuglog(zone, me, 1, 14611 "unable to add opt record: %s", 14612 dns_result_totext(result)); 14613 } 14614 } 14615 14616 zone_iattach(zone, &dummy); 14617 timeout = 15; 14618 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) { 14619 timeout = 30; 14620 } 14621 result = dns_request_createvia( 14622 zone->view->requestmgr, message, &zone->sourceaddr, 14623 &zone->masteraddr, dscp, options, key, timeout * 3, timeout, 0, 14624 zone->task, refresh_callback, zone, &zone->request); 14625 if (result != ISC_R_SUCCESS) { 14626 zone_idetach(&dummy); 14627 zone_debuglog(zone, me, 1, 14628 "dns_request_createvia4() failed: %s", 14629 dns_result_totext(result)); 14630 goto skip_master; 14631 } else { 14632 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET) { 14633 inc_stats(zone, dns_zonestatscounter_soaoutv4); 14634 } else { 14635 inc_stats(zone, dns_zonestatscounter_soaoutv6); 14636 } 14637 } 14638 cancel = false; 14639 14640cleanup: 14641 if (key != NULL) { 14642 dns_tsigkey_detach(&key); 14643 } 14644 if (result != ISC_R_SUCCESS) { 14645 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 14646 } 14647 if (message != NULL) { 14648 dns_message_detach(&message); 14649 } 14650 if (cancel) { 14651 cancel_refresh(zone); 14652 } 14653 isc_event_free(&event); 14654 UNLOCK_ZONE(zone); 14655 dns_zone_idetach(&zone); 14656 return; 14657 14658skip_master: 14659 if (key != NULL) { 14660 dns_tsigkey_detach(&key); 14661 } 14662 dns_message_detach(&message); 14663 /* 14664 * Skip to next failed / untried master. 14665 */ 14666 do { 14667 zone->curmaster++; 14668 } while (zone->curmaster < zone->masterscnt && 14669 zone->mastersok[zone->curmaster]); 14670 if (zone->curmaster < zone->masterscnt) { 14671 goto again; 14672 } 14673 zone->curmaster = 0; 14674 goto cleanup; 14675} 14676 14677static void 14678ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { 14679 const char me[] = "ns_query"; 14680 isc_result_t result; 14681 dns_message_t *message = NULL; 14682 isc_netaddr_t masterip; 14683 dns_tsigkey_t *key = NULL; 14684 dns_dbnode_t *node = NULL; 14685 int timeout; 14686 bool have_xfrsource = false, have_xfrdscp = false; 14687 bool reqnsid; 14688 uint16_t udpsize = SEND_BUFFER_SIZE; 14689 isc_dscp_t dscp = -1; 14690 struct stub_cb_args *cb_args; 14691 14692 REQUIRE(DNS_ZONE_VALID(zone)); 14693 REQUIRE(LOCKED_ZONE(zone)); 14694 REQUIRE((soardataset != NULL && stub == NULL) || 14695 (soardataset == NULL && stub != NULL)); 14696 REQUIRE(stub == NULL || DNS_STUB_VALID(stub)); 14697 14698 ENTER; 14699 14700 if (stub == NULL) { 14701 stub = isc_mem_get(zone->mctx, sizeof(*stub)); 14702 stub->magic = STUB_MAGIC; 14703 stub->mctx = zone->mctx; 14704 stub->zone = NULL; 14705 stub->db = NULL; 14706 stub->version = NULL; 14707 atomic_init(&stub->pending_requests, 0); 14708 14709 /* 14710 * Attach so that the zone won't disappear from under us. 14711 */ 14712 zone_iattach(zone, &stub->zone); 14713 14714 /* 14715 * If a db exists we will update it, otherwise we create a 14716 * new one and attach it to the zone once we have the NS 14717 * RRset and glue. 14718 */ 14719 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 14720 if (zone->db != NULL) { 14721 dns_db_attach(zone->db, &stub->db); 14722 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 14723 } else { 14724 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 14725 14726 INSIST(zone->db_argc >= 1); 14727 result = dns_db_create(zone->mctx, zone->db_argv[0], 14728 &zone->origin, dns_dbtype_stub, 14729 zone->rdclass, zone->db_argc - 1, 14730 zone->db_argv + 1, &stub->db); 14731 if (result != ISC_R_SUCCESS) { 14732 dns_zone_log(zone, ISC_LOG_ERROR, 14733 "refreshing stub: " 14734 "could not create " 14735 "database: %s", 14736 dns_result_totext(result)); 14737 goto cleanup; 14738 } 14739 dns_db_settask(stub->db, zone->task); 14740 } 14741 14742 result = dns_db_newversion(stub->db, &stub->version); 14743 if (result != ISC_R_SUCCESS) { 14744 dns_zone_log(zone, ISC_LOG_INFO, 14745 "refreshing stub: " 14746 "dns_db_newversion() failed: %s", 14747 dns_result_totext(result)); 14748 goto cleanup; 14749 } 14750 14751 /* 14752 * Update SOA record. 14753 */ 14754 result = dns_db_findnode(stub->db, &zone->origin, true, &node); 14755 if (result != ISC_R_SUCCESS) { 14756 dns_zone_log(zone, ISC_LOG_INFO, 14757 "refreshing stub: " 14758 "dns_db_findnode() failed: %s", 14759 dns_result_totext(result)); 14760 goto cleanup; 14761 } 14762 14763 result = dns_db_addrdataset(stub->db, node, stub->version, 0, 14764 soardataset, 0, NULL); 14765 dns_db_detachnode(stub->db, &node); 14766 if (result != ISC_R_SUCCESS) { 14767 dns_zone_log(zone, ISC_LOG_INFO, 14768 "refreshing stub: " 14769 "dns_db_addrdataset() failed: %s", 14770 dns_result_totext(result)); 14771 goto cleanup; 14772 } 14773 } 14774 14775 /* 14776 * XXX Optimisation: Create message when zone is setup and reuse. 14777 */ 14778 result = create_query(zone, dns_rdatatype_ns, &zone->origin, &message); 14779 INSIST(result == ISC_R_SUCCESS); 14780 14781 INSIST(zone->masterscnt > 0); 14782 INSIST(zone->curmaster < zone->masterscnt); 14783 zone->masteraddr = zone->masters[zone->curmaster]; 14784 14785 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 14786 /* 14787 * First, look for a tsig key in the master statement, then 14788 * try for a server key. 14789 */ 14790 if ((zone->masterkeynames != NULL) && 14791 (zone->masterkeynames[zone->curmaster] != NULL)) 14792 { 14793 dns_view_t *view = dns_zone_getview(zone); 14794 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 14795 result = dns_view_gettsig(view, keyname, &key); 14796 if (result != ISC_R_SUCCESS) { 14797 char namebuf[DNS_NAME_FORMATSIZE]; 14798 dns_name_format(keyname, namebuf, sizeof(namebuf)); 14799 dns_zone_log(zone, ISC_LOG_ERROR, 14800 "unable to find key: %s", namebuf); 14801 } 14802 } 14803 if (key == NULL) { 14804 (void)dns_view_getpeertsig(zone->view, &masterip, &key); 14805 } 14806 14807 reqnsid = zone->view->requestnsid; 14808 if (zone->view->peers != NULL) { 14809 dns_peer_t *peer = NULL; 14810 bool edns; 14811 result = dns_peerlist_peerbyaddr(zone->view->peers, &masterip, 14812 &peer); 14813 if (result == ISC_R_SUCCESS) { 14814 result = dns_peer_getsupportedns(peer, &edns); 14815 if (result == ISC_R_SUCCESS && !edns) { 14816 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14817 } 14818 result = dns_peer_gettransfersource(peer, 14819 &zone->sourceaddr); 14820 if (result == ISC_R_SUCCESS) { 14821 have_xfrsource = true; 14822 } 14823 result = dns_peer_gettransferdscp(peer, &dscp); 14824 if (result == ISC_R_SUCCESS && dscp != -1) { 14825 have_xfrdscp = true; 14826 } 14827 if (zone->view->resolver != NULL) { 14828 udpsize = dns_resolver_getudpsize( 14829 zone->view->resolver); 14830 } 14831 (void)dns_peer_getudpsize(peer, &udpsize); 14832 (void)dns_peer_getrequestnsid(peer, &reqnsid); 14833 } 14834 } 14835 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 14836 result = add_opt(message, udpsize, reqnsid, false); 14837 if (result != ISC_R_SUCCESS) { 14838 zone_debuglog(zone, me, 1, 14839 "unable to add opt record: %s", 14840 dns_result_totext(result)); 14841 } 14842 } 14843 14844 /* 14845 * Always use TCP so that we shouldn't truncate in additional section. 14846 */ 14847 switch (isc_sockaddr_pf(&zone->masteraddr)) { 14848 case PF_INET: 14849 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 14850 zone->sourceaddr = zone->altxfrsource4; 14851 if (!have_xfrdscp) { 14852 dscp = zone->altxfrsource4dscp; 14853 } 14854 } else if (!have_xfrsource) { 14855 zone->sourceaddr = zone->xfrsource4; 14856 if (!have_xfrdscp) { 14857 dscp = zone->xfrsource4dscp; 14858 } 14859 } 14860 break; 14861 case PF_INET6: 14862 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 14863 zone->sourceaddr = zone->altxfrsource6; 14864 if (!have_xfrdscp) { 14865 dscp = zone->altxfrsource6dscp; 14866 } 14867 } else if (!have_xfrsource) { 14868 zone->sourceaddr = zone->xfrsource6; 14869 if (!have_xfrdscp) { 14870 dscp = zone->xfrsource6dscp; 14871 } 14872 } 14873 break; 14874 default: 14875 result = ISC_R_NOTIMPLEMENTED; 14876 POST(result); 14877 goto cleanup; 14878 } 14879 timeout = 15; 14880 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) { 14881 timeout = 30; 14882 } 14883 14884 /* 14885 * Save request parameters so we can reuse them later on 14886 * for resolving missing glue A/AAAA records. 14887 */ 14888 cb_args = isc_mem_get(zone->mctx, sizeof(*cb_args)); 14889 cb_args->stub = stub; 14890 cb_args->tsig_key = key; 14891 cb_args->dscp = dscp; 14892 cb_args->udpsize = udpsize; 14893 cb_args->timeout = timeout; 14894 cb_args->reqnsid = reqnsid; 14895 14896 result = dns_request_createvia( 14897 zone->view->requestmgr, message, &zone->sourceaddr, 14898 &zone->masteraddr, dscp, DNS_REQUESTOPT_TCP, key, timeout * 3, 14899 timeout, 0, zone->task, stub_callback, cb_args, &zone->request); 14900 if (result != ISC_R_SUCCESS) { 14901 zone_debuglog(zone, me, 1, "dns_request_createvia() failed: %s", 14902 dns_result_totext(result)); 14903 goto cleanup; 14904 } 14905 dns_message_detach(&message); 14906 goto unlock; 14907 14908cleanup: 14909 cancel_refresh(zone); 14910 stub->magic = 0; 14911 if (stub->version != NULL) { 14912 dns_db_closeversion(stub->db, &stub->version, false); 14913 } 14914 if (stub->db != NULL) { 14915 dns_db_detach(&stub->db); 14916 } 14917 if (stub->zone != NULL) { 14918 zone_idetach(&stub->zone); 14919 } 14920 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 14921 if (message != NULL) { 14922 dns_message_detach(&message); 14923 } 14924unlock: 14925 if (key != NULL) { 14926 dns_tsigkey_detach(&key); 14927 } 14928 return; 14929} 14930 14931/* 14932 * Shut the zone down. 14933 */ 14934static void 14935zone_shutdown(isc_task_t *task, isc_event_t *event) { 14936 dns_zone_t *zone = (dns_zone_t *)event->ev_arg; 14937 bool free_needed, linked = false; 14938 dns_zone_t *raw = NULL, *secure = NULL; 14939 dns_view_t *view = NULL, *prev_view = NULL; 14940 14941 UNUSED(task); 14942 REQUIRE(DNS_ZONE_VALID(zone)); 14943 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL); 14944 INSIST(isc_refcount_current(&zone->erefs) == 0); 14945 14946 zone_debuglog(zone, "zone_shutdown", 3, "shutting down"); 14947 14948 /* 14949 * If we were waiting for xfrin quota, step out of 14950 * the queue. 14951 * If there's no zone manager, we can't be waiting for the 14952 * xfrin quota 14953 */ 14954 if (zone->zmgr != NULL) { 14955 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 14956 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) { 14957 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone, 14958 statelink); 14959 linked = true; 14960 zone->statelist = NULL; 14961 } 14962 if (zone->statelist == &zone->zmgr->xfrin_in_progress) { 14963 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, 14964 statelink); 14965 zone->statelist = NULL; 14966 zmgr_resume_xfrs(zone->zmgr, false); 14967 } 14968 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 14969 } 14970 14971 /* 14972 * In task context, no locking required. See zone_xfrdone(). 14973 */ 14974 if (zone->xfr != NULL) { 14975 dns_xfrin_shutdown(zone->xfr); 14976 } 14977 14978 /* Safe to release the zone now */ 14979 if (zone->zmgr != NULL) { 14980 dns_zonemgr_releasezone(zone->zmgr, zone); 14981 } 14982 14983 LOCK_ZONE(zone); 14984 INSIST(zone != zone->raw); 14985 14986 /* 14987 * Detach the views early, we don't need them anymore. However, we need 14988 * to detach them outside of the zone lock to break the lock loop 14989 * between view, adb and zone locks. 14990 */ 14991 view = zone->view; 14992 zone->view = NULL; 14993 prev_view = zone->prev_view; 14994 zone->prev_view = NULL; 14995 14996 if (linked) { 14997 isc_refcount_decrement(&zone->irefs); 14998 } 14999 if (zone->request != NULL) { 15000 dns_request_cancel(zone->request); 15001 } 15002 15003 if (zone->readio != NULL) { 15004 zonemgr_cancelio(zone->readio); 15005 } 15006 15007 if (zone->lctx != NULL) { 15008 dns_loadctx_cancel(zone->lctx); 15009 } 15010 15011 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 15012 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15013 { 15014 if (zone->writeio != NULL) { 15015 zonemgr_cancelio(zone->writeio); 15016 } 15017 15018 if (zone->dctx != NULL) { 15019 dns_dumpctx_cancel(zone->dctx); 15020 } 15021 } 15022 15023 checkds_cancel(zone); 15024 15025 notify_cancel(zone); 15026 15027 forward_cancel(zone); 15028 15029 if (zone->timer != NULL) { 15030 isc_timer_destroy(&zone->timer); 15031 isc_refcount_decrement(&zone->irefs); 15032 } 15033 15034 /* 15035 * We have now canceled everything set the flag to allow exit_check() 15036 * to succeed. We must not unlock between setting this flag and 15037 * calling exit_check(). 15038 */ 15039 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN); 15040 free_needed = exit_check(zone); 15041 /* 15042 * If a dump is in progress for the secure zone, defer detaching from 15043 * the raw zone as it may prevent the unsigned serial number from being 15044 * stored in the raw-format dump of the secure zone. In this scenario, 15045 * dump_done() takes care of cleaning up the zone->raw reference. 15046 */ 15047 if (inline_secure(zone) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 15048 raw = zone->raw; 15049 zone->raw = NULL; 15050 } 15051 if (inline_raw(zone)) { 15052 secure = zone->secure; 15053 zone->secure = NULL; 15054 } 15055 UNLOCK_ZONE(zone); 15056 15057 if (view != NULL) { 15058 dns_view_weakdetach(&view); 15059 } 15060 if (prev_view != NULL) { 15061 dns_view_weakdetach(&prev_view); 15062 } 15063 15064 if (raw != NULL) { 15065 dns_zone_detach(&raw); 15066 } 15067 if (secure != NULL) { 15068 dns_zone_idetach(&secure); 15069 } 15070 if (free_needed) { 15071 zone_free(zone); 15072 } 15073} 15074 15075static void 15076zone_timer(isc_task_t *task, isc_event_t *event) { 15077 const char me[] = "zone_timer"; 15078 dns_zone_t *zone = (dns_zone_t *)event->ev_arg; 15079 15080 UNUSED(task); 15081 REQUIRE(DNS_ZONE_VALID(zone)); 15082 15083 ENTER; 15084 15085 zone_maintenance(zone); 15086 15087 isc_event_free(&event); 15088} 15089 15090static void 15091zone_settimer(dns_zone_t *zone, isc_time_t *now) { 15092 const char me[] = "zone_settimer"; 15093 isc_time_t next; 15094 isc_result_t result; 15095 15096 REQUIRE(DNS_ZONE_VALID(zone)); 15097 REQUIRE(LOCKED_ZONE(zone)); 15098 ENTER; 15099 15100 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 15101 return; 15102 } 15103 15104 isc_time_settoepoch(&next); 15105 15106 switch (zone->type) { 15107 case dns_zone_redirect: 15108 if (zone->masters != NULL) { 15109 goto treat_as_slave; 15110 } 15111 FALLTHROUGH; 15112 case dns_zone_primary: 15113 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 15114 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) 15115 { 15116 next = zone->notifytime; 15117 } 15118 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 15119 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15120 { 15121 INSIST(!isc_time_isepoch(&zone->dumptime)); 15122 if (isc_time_isepoch(&next) || 15123 isc_time_compare(&zone->dumptime, &next) < 0) 15124 { 15125 next = zone->dumptime; 15126 } 15127 } 15128 if (zone->type == dns_zone_redirect) { 15129 break; 15130 } 15131 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) && 15132 !isc_time_isepoch(&zone->refreshkeytime)) 15133 { 15134 if (isc_time_isepoch(&next) || 15135 isc_time_compare(&zone->refreshkeytime, &next) < 0) 15136 { 15137 next = zone->refreshkeytime; 15138 } 15139 } 15140 if (!isc_time_isepoch(&zone->resigntime)) { 15141 if (isc_time_isepoch(&next) || 15142 isc_time_compare(&zone->resigntime, &next) < 0) 15143 { 15144 next = zone->resigntime; 15145 } 15146 } 15147 if (!isc_time_isepoch(&zone->keywarntime)) { 15148 if (isc_time_isepoch(&next) || 15149 isc_time_compare(&zone->keywarntime, &next) < 0) 15150 { 15151 next = zone->keywarntime; 15152 } 15153 } 15154 if (!isc_time_isepoch(&zone->signingtime)) { 15155 if (isc_time_isepoch(&next) || 15156 isc_time_compare(&zone->signingtime, &next) < 0) 15157 { 15158 next = zone->signingtime; 15159 } 15160 } 15161 if (!isc_time_isepoch(&zone->nsec3chaintime)) { 15162 if (isc_time_isepoch(&next) || 15163 isc_time_compare(&zone->nsec3chaintime, &next) < 0) 15164 { 15165 next = zone->nsec3chaintime; 15166 } 15167 } 15168 break; 15169 15170 case dns_zone_secondary: 15171 case dns_zone_mirror: 15172 treat_as_slave: 15173 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 15174 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) 15175 { 15176 next = zone->notifytime; 15177 } 15178 FALLTHROUGH; 15179 case dns_zone_stub: 15180 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) && 15181 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) && 15182 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) && 15183 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) && 15184 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) && 15185 !isc_time_isepoch(&zone->refreshtime) && 15186 (isc_time_isepoch(&next) || 15187 isc_time_compare(&zone->refreshtime, &next) < 0)) 15188 { 15189 next = zone->refreshtime; 15190 } 15191 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 15192 !isc_time_isepoch(&zone->expiretime)) 15193 { 15194 if (isc_time_isepoch(&next) || 15195 isc_time_compare(&zone->expiretime, &next) < 0) 15196 { 15197 next = zone->expiretime; 15198 } 15199 } 15200 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 15201 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15202 { 15203 INSIST(!isc_time_isepoch(&zone->dumptime)); 15204 if (isc_time_isepoch(&next) || 15205 isc_time_compare(&zone->dumptime, &next) < 0) 15206 { 15207 next = zone->dumptime; 15208 } 15209 } 15210 break; 15211 15212 case dns_zone_key: 15213 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 15214 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15215 { 15216 INSIST(!isc_time_isepoch(&zone->dumptime)); 15217 if (isc_time_isepoch(&next) || 15218 isc_time_compare(&zone->dumptime, &next) < 0) 15219 { 15220 next = zone->dumptime; 15221 } 15222 } 15223 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) { 15224 if (isc_time_isepoch(&next) || 15225 (!isc_time_isepoch(&zone->refreshkeytime) && 15226 isc_time_compare(&zone->refreshkeytime, &next) < 15227 0)) 15228 { 15229 next = zone->refreshkeytime; 15230 } 15231 } 15232 break; 15233 15234 default: 15235 break; 15236 } 15237 15238 if (isc_time_isepoch(&next)) { 15239 zone_debuglog(zone, me, 10, "settimer inactive"); 15240 result = isc_timer_reset(zone->timer, isc_timertype_inactive, 15241 NULL, NULL, true); 15242 if (result != ISC_R_SUCCESS) { 15243 dns_zone_log(zone, ISC_LOG_ERROR, 15244 "could not deactivate zone timer: %s", 15245 isc_result_totext(result)); 15246 } 15247 } else { 15248 if (isc_time_compare(&next, now) <= 0) { 15249 next = *now; 15250 } 15251 result = isc_timer_reset(zone->timer, isc_timertype_once, &next, 15252 NULL, true); 15253 if (result != ISC_R_SUCCESS) { 15254 dns_zone_log(zone, ISC_LOG_ERROR, 15255 "could not reset zone timer: %s", 15256 isc_result_totext(result)); 15257 } 15258 } 15259} 15260 15261static void 15262cancel_refresh(dns_zone_t *zone) { 15263 const char me[] = "cancel_refresh"; 15264 isc_time_t now; 15265 15266 /* 15267 * 'zone' locked by caller. 15268 */ 15269 15270 REQUIRE(DNS_ZONE_VALID(zone)); 15271 REQUIRE(LOCKED_ZONE(zone)); 15272 15273 ENTER; 15274 15275 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 15276 TIME_NOW(&now); 15277 zone_settimer(zone, &now); 15278} 15279 15280static isc_result_t 15281notify_createmessage(dns_zone_t *zone, unsigned int flags, 15282 dns_message_t **messagep) { 15283 dns_db_t *zonedb = NULL; 15284 dns_dbnode_t *node = NULL; 15285 dns_dbversion_t *version = NULL; 15286 dns_message_t *message = NULL; 15287 dns_rdataset_t rdataset; 15288 dns_rdata_t rdata = DNS_RDATA_INIT; 15289 15290 dns_name_t *tempname = NULL; 15291 dns_rdata_t *temprdata = NULL; 15292 dns_rdatalist_t *temprdatalist = NULL; 15293 dns_rdataset_t *temprdataset = NULL; 15294 15295 isc_result_t result; 15296 isc_region_t r; 15297 isc_buffer_t *b = NULL; 15298 15299 REQUIRE(DNS_ZONE_VALID(zone)); 15300 REQUIRE(messagep != NULL && *messagep == NULL); 15301 15302 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message); 15303 15304 message->opcode = dns_opcode_notify; 15305 message->flags |= DNS_MESSAGEFLAG_AA; 15306 message->rdclass = zone->rdclass; 15307 15308 result = dns_message_gettempname(message, &tempname); 15309 if (result != ISC_R_SUCCESS) { 15310 goto cleanup; 15311 } 15312 15313 result = dns_message_gettemprdataset(message, &temprdataset); 15314 if (result != ISC_R_SUCCESS) { 15315 goto cleanup; 15316 } 15317 15318 /* 15319 * Make question. 15320 */ 15321 dns_name_clone(&zone->origin, tempname); 15322 dns_rdataset_makequestion(temprdataset, zone->rdclass, 15323 dns_rdatatype_soa); 15324 ISC_LIST_APPEND(tempname->list, temprdataset, link); 15325 dns_message_addname(message, tempname, DNS_SECTION_QUESTION); 15326 tempname = NULL; 15327 temprdataset = NULL; 15328 15329 if ((flags & DNS_NOTIFY_NOSOA) != 0) { 15330 goto done; 15331 } 15332 15333 result = dns_message_gettempname(message, &tempname); 15334 if (result != ISC_R_SUCCESS) { 15335 goto soa_cleanup; 15336 } 15337 result = dns_message_gettemprdata(message, &temprdata); 15338 if (result != ISC_R_SUCCESS) { 15339 goto soa_cleanup; 15340 } 15341 result = dns_message_gettemprdataset(message, &temprdataset); 15342 if (result != ISC_R_SUCCESS) { 15343 goto soa_cleanup; 15344 } 15345 result = dns_message_gettemprdatalist(message, &temprdatalist); 15346 if (result != ISC_R_SUCCESS) { 15347 goto soa_cleanup; 15348 } 15349 15350 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 15351 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */ 15352 dns_db_attach(zone->db, &zonedb); 15353 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 15354 15355 dns_name_clone(&zone->origin, tempname); 15356 dns_db_currentversion(zonedb, &version); 15357 result = dns_db_findnode(zonedb, tempname, false, &node); 15358 if (result != ISC_R_SUCCESS) { 15359 goto soa_cleanup; 15360 } 15361 15362 dns_rdataset_init(&rdataset); 15363 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, 15364 dns_rdatatype_none, 0, &rdataset, NULL); 15365 if (result != ISC_R_SUCCESS) { 15366 goto soa_cleanup; 15367 } 15368 result = dns_rdataset_first(&rdataset); 15369 if (result != ISC_R_SUCCESS) { 15370 goto soa_cleanup; 15371 } 15372 dns_rdataset_current(&rdataset, &rdata); 15373 dns_rdata_toregion(&rdata, &r); 15374 isc_buffer_allocate(zone->mctx, &b, r.length); 15375 isc_buffer_putmem(b, r.base, r.length); 15376 isc_buffer_usedregion(b, &r); 15377 dns_rdata_init(temprdata); 15378 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r); 15379 dns_message_takebuffer(message, &b); 15380 result = dns_rdataset_next(&rdataset); 15381 dns_rdataset_disassociate(&rdataset); 15382 if (result != ISC_R_NOMORE) { 15383 goto soa_cleanup; 15384 } 15385 temprdatalist->rdclass = rdata.rdclass; 15386 temprdatalist->type = rdata.type; 15387 temprdatalist->ttl = rdataset.ttl; 15388 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link); 15389 15390 result = dns_rdatalist_tordataset(temprdatalist, temprdataset); 15391 if (result != ISC_R_SUCCESS) { 15392 goto soa_cleanup; 15393 } 15394 15395 ISC_LIST_APPEND(tempname->list, temprdataset, link); 15396 dns_message_addname(message, tempname, DNS_SECTION_ANSWER); 15397 temprdatalist = NULL; 15398 temprdataset = NULL; 15399 temprdata = NULL; 15400 tempname = NULL; 15401 15402soa_cleanup: 15403 if (node != NULL) { 15404 dns_db_detachnode(zonedb, &node); 15405 } 15406 if (version != NULL) { 15407 dns_db_closeversion(zonedb, &version, false); 15408 } 15409 if (zonedb != NULL) { 15410 dns_db_detach(&zonedb); 15411 } 15412 if (tempname != NULL) { 15413 dns_message_puttempname(message, &tempname); 15414 } 15415 if (temprdata != NULL) { 15416 dns_message_puttemprdata(message, &temprdata); 15417 } 15418 if (temprdataset != NULL) { 15419 dns_message_puttemprdataset(message, &temprdataset); 15420 } 15421 if (temprdatalist != NULL) { 15422 dns_message_puttemprdatalist(message, &temprdatalist); 15423 } 15424 15425done: 15426 *messagep = message; 15427 return (ISC_R_SUCCESS); 15428 15429cleanup: 15430 if (tempname != NULL) { 15431 dns_message_puttempname(message, &tempname); 15432 } 15433 if (temprdataset != NULL) { 15434 dns_message_puttemprdataset(message, &temprdataset); 15435 } 15436 dns_message_detach(&message); 15437 return (result); 15438} 15439 15440isc_result_t 15441dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, 15442 isc_sockaddr_t *to, dns_message_t *msg) { 15443 unsigned int i; 15444 dns_rdata_soa_t soa; 15445 dns_rdataset_t *rdataset = NULL; 15446 dns_rdata_t rdata = DNS_RDATA_INIT; 15447 isc_result_t result; 15448 char fromtext[ISC_SOCKADDR_FORMATSIZE]; 15449 int match = 0; 15450 isc_netaddr_t netaddr; 15451 uint32_t serial = 0; 15452 bool have_serial = false; 15453 dns_tsigkey_t *tsigkey; 15454 const dns_name_t *tsig; 15455 15456 REQUIRE(DNS_ZONE_VALID(zone)); 15457 15458 /* 15459 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support 15460 * ROLLOVER. 15461 * 15462 * SOA: RFC1996 15463 * Check that 'from' is a valid notify source, (zone->masters). 15464 * Return DNS_R_REFUSED if not. 15465 * 15466 * If the notify message contains a serial number check it 15467 * against the zones serial and return if <= current serial 15468 * 15469 * If a refresh check is progress, if so just record the 15470 * fact we received a NOTIFY and from where and return. 15471 * We will perform a new refresh check when the current one 15472 * completes. Return ISC_R_SUCCESS. 15473 * 15474 * Otherwise initiate a refresh check using 'from' as the 15475 * first address to check. Return ISC_R_SUCCESS. 15476 */ 15477 15478 isc_sockaddr_format(from, fromtext, sizeof(fromtext)); 15479 15480 /* 15481 * Notify messages are processed by the raw zone. 15482 */ 15483 LOCK_ZONE(zone); 15484 INSIST(zone != zone->raw); 15485 if (inline_secure(zone)) { 15486 result = dns_zone_notifyreceive(zone->raw, from, to, msg); 15487 UNLOCK_ZONE(zone); 15488 return (result); 15489 } 15490 /* 15491 * We only handle NOTIFY (SOA) at the present. 15492 */ 15493 if (isc_sockaddr_pf(from) == PF_INET) { 15494 inc_stats(zone, dns_zonestatscounter_notifyinv4); 15495 } else { 15496 inc_stats(zone, dns_zonestatscounter_notifyinv6); 15497 } 15498 if (msg->counts[DNS_SECTION_QUESTION] == 0 || 15499 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin, 15500 dns_rdatatype_soa, dns_rdatatype_none, NULL, 15501 NULL) != ISC_R_SUCCESS) 15502 { 15503 UNLOCK_ZONE(zone); 15504 if (msg->counts[DNS_SECTION_QUESTION] == 0) { 15505 dns_zone_log(zone, ISC_LOG_NOTICE, 15506 "NOTIFY with no " 15507 "question section from: %s", 15508 fromtext); 15509 return (DNS_R_FORMERR); 15510 } 15511 dns_zone_log(zone, ISC_LOG_NOTICE, 15512 "NOTIFY zone does not match"); 15513 return (DNS_R_NOTIMP); 15514 } 15515 15516 /* 15517 * If we are a master zone just succeed. 15518 */ 15519 if (zone->type == dns_zone_primary) { 15520 UNLOCK_ZONE(zone); 15521 return (ISC_R_SUCCESS); 15522 } 15523 15524 isc_netaddr_fromsockaddr(&netaddr, from); 15525 for (i = 0; i < zone->masterscnt; i++) { 15526 if (isc_sockaddr_eqaddr(from, &zone->masters[i])) { 15527 break; 15528 } 15529 if (zone->view->aclenv.match_mapped && 15530 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) && 15531 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) 15532 { 15533 isc_netaddr_t na1, na2; 15534 isc_netaddr_fromv4mapped(&na1, &netaddr); 15535 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]); 15536 if (isc_netaddr_equal(&na1, &na2)) { 15537 break; 15538 } 15539 } 15540 } 15541 15542 /* 15543 * Accept notify requests from non masters if they are on 15544 * 'zone->notify_acl'. 15545 */ 15546 tsigkey = dns_message_gettsigkey(msg); 15547 tsig = dns_tsigkey_identity(tsigkey); 15548 if (i >= zone->masterscnt && zone->notify_acl != NULL && 15549 (dns_acl_match(&netaddr, tsig, zone->notify_acl, 15550 &zone->view->aclenv, &match, 15551 NULL) == ISC_R_SUCCESS) && 15552 match > 0) 15553 { 15554 /* Accept notify. */ 15555 } else if (i >= zone->masterscnt) { 15556 UNLOCK_ZONE(zone); 15557 dns_zone_log(zone, ISC_LOG_INFO, 15558 "refused notify from non-master: %s", fromtext); 15559 inc_stats(zone, dns_zonestatscounter_notifyrej); 15560 return (DNS_R_REFUSED); 15561 } 15562 15563 /* 15564 * If the zone is loaded and there are answers check the serial 15565 * to see if we need to do a refresh. Do not worry about this 15566 * check if we are a dialup zone as we use the notify request 15567 * to trigger a refresh check. 15568 */ 15569 if (msg->counts[DNS_SECTION_ANSWER] > 0 && 15570 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 15571 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) 15572 { 15573 result = dns_message_findname( 15574 msg, DNS_SECTION_ANSWER, &zone->origin, 15575 dns_rdatatype_soa, dns_rdatatype_none, NULL, &rdataset); 15576 if (result == ISC_R_SUCCESS) { 15577 result = dns_rdataset_first(rdataset); 15578 } 15579 if (result == ISC_R_SUCCESS) { 15580 uint32_t oldserial; 15581 unsigned int soacount; 15582 15583 dns_rdataset_current(rdataset, &rdata); 15584 result = dns_rdata_tostruct(&rdata, &soa, NULL); 15585 RUNTIME_CHECK(result == ISC_R_SUCCESS); 15586 serial = soa.serial; 15587 have_serial = true; 15588 /* 15589 * The following should safely be performed without DB 15590 * lock and succeed in this context. 15591 */ 15592 result = zone_get_from_db(zone, zone->db, NULL, 15593 &soacount, NULL, &oldserial, 15594 NULL, NULL, NULL, NULL, NULL); 15595 RUNTIME_CHECK(result == ISC_R_SUCCESS); 15596 RUNTIME_CHECK(soacount > 0U); 15597 if (isc_serial_le(serial, oldserial)) { 15598 dns_zone_log(zone, ISC_LOG_INFO, 15599 "notify from %s: " 15600 "zone is up to date", 15601 fromtext); 15602 UNLOCK_ZONE(zone); 15603 return (ISC_R_SUCCESS); 15604 } 15605 } 15606 } 15607 15608 /* 15609 * If we got this far and there was a refresh in progress just 15610 * let it complete. Record where we got the notify from so we 15611 * can perform a refresh check when the current one completes 15612 */ 15613 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { 15614 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 15615 zone->notifyfrom = *from; 15616 UNLOCK_ZONE(zone); 15617 if (have_serial) { 15618 dns_zone_log(zone, ISC_LOG_INFO, 15619 "notify from %s: serial %u: refresh in " 15620 "progress, refresh check queued", 15621 fromtext, serial); 15622 } else { 15623 dns_zone_log(zone, ISC_LOG_INFO, 15624 "notify from %s: refresh in progress, " 15625 "refresh check queued", 15626 fromtext); 15627 } 15628 return (ISC_R_SUCCESS); 15629 } 15630 if (have_serial) { 15631 dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: serial %u", 15632 fromtext, serial); 15633 } else { 15634 dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: no serial", 15635 fromtext); 15636 } 15637 zone->notifyfrom = *from; 15638 UNLOCK_ZONE(zone); 15639 15640 if (to != NULL) { 15641 dns_zonemgr_unreachabledel(zone->zmgr, from, to); 15642 } 15643 dns_zone_refresh(zone); 15644 return (ISC_R_SUCCESS); 15645} 15646 15647void 15648dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) { 15649 REQUIRE(DNS_ZONE_VALID(zone)); 15650 15651 LOCK_ZONE(zone); 15652 if (zone->notify_acl != NULL) { 15653 dns_acl_detach(&zone->notify_acl); 15654 } 15655 dns_acl_attach(acl, &zone->notify_acl); 15656 UNLOCK_ZONE(zone); 15657} 15658 15659void 15660dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) { 15661 REQUIRE(DNS_ZONE_VALID(zone)); 15662 15663 LOCK_ZONE(zone); 15664 if (zone->query_acl != NULL) { 15665 dns_acl_detach(&zone->query_acl); 15666 } 15667 dns_acl_attach(acl, &zone->query_acl); 15668 UNLOCK_ZONE(zone); 15669} 15670 15671void 15672dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) { 15673 REQUIRE(DNS_ZONE_VALID(zone)); 15674 15675 LOCK_ZONE(zone); 15676 if (zone->queryon_acl != NULL) { 15677 dns_acl_detach(&zone->queryon_acl); 15678 } 15679 dns_acl_attach(acl, &zone->queryon_acl); 15680 UNLOCK_ZONE(zone); 15681} 15682 15683void 15684dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) { 15685 REQUIRE(DNS_ZONE_VALID(zone)); 15686 15687 LOCK_ZONE(zone); 15688 if (zone->update_acl != NULL) { 15689 dns_acl_detach(&zone->update_acl); 15690 } 15691 dns_acl_attach(acl, &zone->update_acl); 15692 UNLOCK_ZONE(zone); 15693} 15694 15695void 15696dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) { 15697 REQUIRE(DNS_ZONE_VALID(zone)); 15698 15699 LOCK_ZONE(zone); 15700 if (zone->forward_acl != NULL) { 15701 dns_acl_detach(&zone->forward_acl); 15702 } 15703 dns_acl_attach(acl, &zone->forward_acl); 15704 UNLOCK_ZONE(zone); 15705} 15706 15707void 15708dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) { 15709 REQUIRE(DNS_ZONE_VALID(zone)); 15710 15711 LOCK_ZONE(zone); 15712 if (zone->xfr_acl != NULL) { 15713 dns_acl_detach(&zone->xfr_acl); 15714 } 15715 dns_acl_attach(acl, &zone->xfr_acl); 15716 UNLOCK_ZONE(zone); 15717} 15718 15719dns_acl_t * 15720dns_zone_getnotifyacl(dns_zone_t *zone) { 15721 REQUIRE(DNS_ZONE_VALID(zone)); 15722 15723 return (zone->notify_acl); 15724} 15725 15726dns_acl_t * 15727dns_zone_getqueryacl(dns_zone_t *zone) { 15728 REQUIRE(DNS_ZONE_VALID(zone)); 15729 15730 return (zone->query_acl); 15731} 15732 15733dns_acl_t * 15734dns_zone_getqueryonacl(dns_zone_t *zone) { 15735 REQUIRE(DNS_ZONE_VALID(zone)); 15736 15737 return (zone->queryon_acl); 15738} 15739 15740dns_acl_t * 15741dns_zone_getupdateacl(dns_zone_t *zone) { 15742 REQUIRE(DNS_ZONE_VALID(zone)); 15743 15744 return (zone->update_acl); 15745} 15746 15747dns_acl_t * 15748dns_zone_getforwardacl(dns_zone_t *zone) { 15749 REQUIRE(DNS_ZONE_VALID(zone)); 15750 15751 return (zone->forward_acl); 15752} 15753 15754dns_acl_t * 15755dns_zone_getxfracl(dns_zone_t *zone) { 15756 REQUIRE(DNS_ZONE_VALID(zone)); 15757 15758 return (zone->xfr_acl); 15759} 15760 15761void 15762dns_zone_clearupdateacl(dns_zone_t *zone) { 15763 REQUIRE(DNS_ZONE_VALID(zone)); 15764 15765 LOCK_ZONE(zone); 15766 if (zone->update_acl != NULL) { 15767 dns_acl_detach(&zone->update_acl); 15768 } 15769 UNLOCK_ZONE(zone); 15770} 15771 15772void 15773dns_zone_clearforwardacl(dns_zone_t *zone) { 15774 REQUIRE(DNS_ZONE_VALID(zone)); 15775 15776 LOCK_ZONE(zone); 15777 if (zone->forward_acl != NULL) { 15778 dns_acl_detach(&zone->forward_acl); 15779 } 15780 UNLOCK_ZONE(zone); 15781} 15782 15783void 15784dns_zone_clearnotifyacl(dns_zone_t *zone) { 15785 REQUIRE(DNS_ZONE_VALID(zone)); 15786 15787 LOCK_ZONE(zone); 15788 if (zone->notify_acl != NULL) { 15789 dns_acl_detach(&zone->notify_acl); 15790 } 15791 UNLOCK_ZONE(zone); 15792} 15793 15794void 15795dns_zone_clearqueryacl(dns_zone_t *zone) { 15796 REQUIRE(DNS_ZONE_VALID(zone)); 15797 15798 LOCK_ZONE(zone); 15799 if (zone->query_acl != NULL) { 15800 dns_acl_detach(&zone->query_acl); 15801 } 15802 UNLOCK_ZONE(zone); 15803} 15804 15805void 15806dns_zone_clearqueryonacl(dns_zone_t *zone) { 15807 REQUIRE(DNS_ZONE_VALID(zone)); 15808 15809 LOCK_ZONE(zone); 15810 if (zone->queryon_acl != NULL) { 15811 dns_acl_detach(&zone->queryon_acl); 15812 } 15813 UNLOCK_ZONE(zone); 15814} 15815 15816void 15817dns_zone_clearxfracl(dns_zone_t *zone) { 15818 REQUIRE(DNS_ZONE_VALID(zone)); 15819 15820 LOCK_ZONE(zone); 15821 if (zone->xfr_acl != NULL) { 15822 dns_acl_detach(&zone->xfr_acl); 15823 } 15824 UNLOCK_ZONE(zone); 15825} 15826 15827bool 15828dns_zone_getupdatedisabled(dns_zone_t *zone) { 15829 REQUIRE(DNS_ZONE_VALID(zone)); 15830 return (zone->update_disabled); 15831} 15832 15833void 15834dns_zone_setupdatedisabled(dns_zone_t *zone, bool state) { 15835 REQUIRE(DNS_ZONE_VALID(zone)); 15836 zone->update_disabled = state; 15837} 15838 15839bool 15840dns_zone_getzeronosoattl(dns_zone_t *zone) { 15841 REQUIRE(DNS_ZONE_VALID(zone)); 15842 return (zone->zero_no_soa_ttl); 15843} 15844 15845void 15846dns_zone_setzeronosoattl(dns_zone_t *zone, bool state) { 15847 REQUIRE(DNS_ZONE_VALID(zone)); 15848 zone->zero_no_soa_ttl = state; 15849} 15850 15851void 15852dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) { 15853 REQUIRE(DNS_ZONE_VALID(zone)); 15854 15855 zone->check_names = severity; 15856} 15857 15858dns_severity_t 15859dns_zone_getchecknames(dns_zone_t *zone) { 15860 REQUIRE(DNS_ZONE_VALID(zone)); 15861 15862 return (zone->check_names); 15863} 15864 15865void 15866dns_zone_setjournalsize(dns_zone_t *zone, int32_t size) { 15867 REQUIRE(DNS_ZONE_VALID(zone)); 15868 15869 zone->journalsize = size; 15870} 15871 15872int32_t 15873dns_zone_getjournalsize(dns_zone_t *zone) { 15874 REQUIRE(DNS_ZONE_VALID(zone)); 15875 15876 return (zone->journalsize); 15877} 15878 15879static void 15880zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) { 15881 isc_result_t result = ISC_R_FAILURE; 15882 isc_buffer_t buffer; 15883 15884 REQUIRE(buf != NULL); 15885 REQUIRE(length > 1U); 15886 15887 /* 15888 * Leave space for terminating '\0'. 15889 */ 15890 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 15891 if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) { 15892 if (dns_name_dynamic(&zone->origin)) { 15893 result = dns_name_totext(&zone->origin, true, &buffer); 15894 } 15895 if (result != ISC_R_SUCCESS && 15896 isc_buffer_availablelength(&buffer) >= 15897 (sizeof("<UNKNOWN>") - 1)) 15898 { 15899 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 15900 } 15901 15902 if (isc_buffer_availablelength(&buffer) > 0) { 15903 isc_buffer_putstr(&buffer, "/"); 15904 } 15905 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 15906 } 15907 15908 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 && 15909 strcmp(zone->view->name, "_default") != 0 && 15910 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) 15911 { 15912 isc_buffer_putstr(&buffer, "/"); 15913 isc_buffer_putstr(&buffer, zone->view->name); 15914 } 15915 if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer)) { 15916 isc_buffer_putstr(&buffer, " (signed)"); 15917 } 15918 if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer)) { 15919 isc_buffer_putstr(&buffer, " (unsigned)"); 15920 } 15921 15922 buf[isc_buffer_usedlength(&buffer)] = '\0'; 15923} 15924 15925static void 15926zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) { 15927 isc_result_t result = ISC_R_FAILURE; 15928 isc_buffer_t buffer; 15929 15930 REQUIRE(buf != NULL); 15931 REQUIRE(length > 1U); 15932 15933 /* 15934 * Leave space for terminating '\0'. 15935 */ 15936 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 15937 if (dns_name_dynamic(&zone->origin)) { 15938 result = dns_name_totext(&zone->origin, true, &buffer); 15939 } 15940 if (result != ISC_R_SUCCESS && 15941 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1)) 15942 { 15943 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 15944 } 15945 15946 buf[isc_buffer_usedlength(&buffer)] = '\0'; 15947} 15948 15949static void 15950zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) { 15951 isc_buffer_t buffer; 15952 15953 REQUIRE(buf != NULL); 15954 REQUIRE(length > 1U); 15955 15956 /* 15957 * Leave space for terminating '\0'. 15958 */ 15959 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 15960 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 15961 15962 buf[isc_buffer_usedlength(&buffer)] = '\0'; 15963} 15964 15965static void 15966zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) { 15967 isc_buffer_t buffer; 15968 15969 REQUIRE(buf != NULL); 15970 REQUIRE(length > 1U); 15971 15972 /* 15973 * Leave space for terminating '\0'. 15974 */ 15975 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 15976 15977 if (zone->view == NULL) { 15978 isc_buffer_putstr(&buffer, "_none"); 15979 } else if (strlen(zone->view->name) < 15980 isc_buffer_availablelength(&buffer)) 15981 { 15982 isc_buffer_putstr(&buffer, zone->view->name); 15983 } else { 15984 isc_buffer_putstr(&buffer, "_toolong"); 15985 } 15986 15987 buf[isc_buffer_usedlength(&buffer)] = '\0'; 15988} 15989 15990void 15991dns_zone_name(dns_zone_t *zone, char *buf, size_t length) { 15992 REQUIRE(DNS_ZONE_VALID(zone)); 15993 REQUIRE(buf != NULL); 15994 15995 LOCK_ZONE(zone); 15996 zone_namerd_tostr(zone, buf, length); 15997 UNLOCK_ZONE(zone); 15998} 15999 16000void 16001dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) { 16002 REQUIRE(DNS_ZONE_VALID(zone)); 16003 REQUIRE(buf != NULL); 16004 zone_name_tostr(zone, buf, length); 16005} 16006 16007void 16008dns_zone_logv(dns_zone_t *zone, isc_logcategory_t *category, int level, 16009 const char *prefix, const char *fmt, va_list ap) { 16010 char message[4096]; 16011 const char *zstr; 16012 16013 REQUIRE(DNS_ZONE_VALID(zone)); 16014 16015 if (!isc_log_wouldlog(dns_lctx, level)) { 16016 return; 16017 } 16018 16019 vsnprintf(message, sizeof(message), fmt, ap); 16020 16021 switch (zone->type) { 16022 case dns_zone_key: 16023 zstr = "managed-keys-zone"; 16024 break; 16025 case dns_zone_redirect: 16026 zstr = "redirect-zone"; 16027 break; 16028 default: 16029 zstr = "zone "; 16030 } 16031 16032 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, level, 16033 "%s%s%s%s: %s", (prefix != NULL ? prefix : ""), 16034 (prefix != NULL ? ": " : ""), zstr, zone->strnamerd, 16035 message); 16036} 16037 16038static void 16039notify_log(dns_zone_t *zone, int level, const char *fmt, ...) { 16040 va_list ap; 16041 16042 va_start(ap, fmt); 16043 dns_zone_logv(zone, DNS_LOGCATEGORY_NOTIFY, level, NULL, fmt, ap); 16044 va_end(ap); 16045} 16046 16047void 16048dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, int level, 16049 const char *fmt, ...) { 16050 va_list ap; 16051 16052 va_start(ap, fmt); 16053 dns_zone_logv(zone, category, level, NULL, fmt, ap); 16054 va_end(ap); 16055} 16056 16057void 16058dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) { 16059 va_list ap; 16060 16061 va_start(ap, fmt); 16062 dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, NULL, fmt, ap); 16063 va_end(ap); 16064} 16065 16066static void 16067zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel, const char *fmt, 16068 ...) { 16069 int level = ISC_LOG_DEBUG(debuglevel); 16070 va_list ap; 16071 16072 va_start(ap, fmt); 16073 dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, me, fmt, ap); 16074 va_end(ap); 16075} 16076 16077static void 16078dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...) { 16079 va_list ap; 16080 16081 va_start(ap, fmt); 16082 dns_zone_logv(zone, DNS_LOGCATEGORY_DNSSEC, level, NULL, fmt, ap); 16083 va_end(ap); 16084} 16085 16086static int 16087message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type) { 16088 isc_result_t result; 16089 dns_name_t *name; 16090 dns_rdataset_t *curr; 16091 int count = 0; 16092 16093 result = dns_message_firstname(msg, section); 16094 while (result == ISC_R_SUCCESS) { 16095 name = NULL; 16096 dns_message_currentname(msg, section, &name); 16097 16098 for (curr = ISC_LIST_TAIL(name->list); curr != NULL; 16099 curr = ISC_LIST_PREV(curr, link)) 16100 { 16101 if (curr->type == type) { 16102 count++; 16103 } 16104 } 16105 result = dns_message_nextname(msg, section); 16106 } 16107 16108 return (count); 16109} 16110 16111void 16112dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin) { 16113 REQUIRE(DNS_ZONE_VALID(zone)); 16114 16115 zone->maxxfrin = maxxfrin; 16116} 16117 16118uint32_t 16119dns_zone_getmaxxfrin(dns_zone_t *zone) { 16120 REQUIRE(DNS_ZONE_VALID(zone)); 16121 16122 return (zone->maxxfrin); 16123} 16124 16125void 16126dns_zone_setmaxxfrout(dns_zone_t *zone, uint32_t maxxfrout) { 16127 REQUIRE(DNS_ZONE_VALID(zone)); 16128 zone->maxxfrout = maxxfrout; 16129} 16130 16131uint32_t 16132dns_zone_getmaxxfrout(dns_zone_t *zone) { 16133 REQUIRE(DNS_ZONE_VALID(zone)); 16134 16135 return (zone->maxxfrout); 16136} 16137 16138dns_zonetype_t 16139dns_zone_gettype(dns_zone_t *zone) { 16140 REQUIRE(DNS_ZONE_VALID(zone)); 16141 16142 return (zone->type); 16143} 16144 16145const char * 16146dns_zonetype_name(dns_zonetype_t type) { 16147 switch (type) { 16148 case dns_zone_none: 16149 return ("none"); 16150 case dns_zone_primary: 16151 return ("primary"); 16152 case dns_zone_secondary: 16153 return ("secondary"); 16154 case dns_zone_mirror: 16155 return ("mirror"); 16156 case dns_zone_stub: 16157 return ("stub"); 16158 case dns_zone_staticstub: 16159 return ("static-stub"); 16160 case dns_zone_key: 16161 return ("key"); 16162 case dns_zone_dlz: 16163 return ("dlz"); 16164 case dns_zone_redirect: 16165 return ("redirect"); 16166 default: 16167 return ("unknown"); 16168 } 16169} 16170 16171dns_zonetype_t 16172dns_zone_getredirecttype(dns_zone_t *zone) { 16173 REQUIRE(DNS_ZONE_VALID(zone)); 16174 REQUIRE(zone->type == dns_zone_redirect); 16175 16176 return (zone->masters == NULL ? dns_zone_primary : dns_zone_secondary); 16177} 16178 16179dns_name_t * 16180dns_zone_getorigin(dns_zone_t *zone) { 16181 REQUIRE(DNS_ZONE_VALID(zone)); 16182 16183 return (&zone->origin); 16184} 16185 16186void 16187dns_zone_settask(dns_zone_t *zone, isc_task_t *task) { 16188 REQUIRE(DNS_ZONE_VALID(zone)); 16189 16190 LOCK_ZONE(zone); 16191 if (zone->task != NULL) { 16192 isc_task_detach(&zone->task); 16193 } 16194 isc_task_attach(task, &zone->task); 16195 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 16196 if (zone->db != NULL) { 16197 dns_db_settask(zone->db, zone->task); 16198 } 16199 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 16200 UNLOCK_ZONE(zone); 16201} 16202 16203void 16204dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) { 16205 REQUIRE(DNS_ZONE_VALID(zone)); 16206 isc_task_attach(zone->task, target); 16207} 16208 16209void 16210dns_zone_setidlein(dns_zone_t *zone, uint32_t idlein) { 16211 REQUIRE(DNS_ZONE_VALID(zone)); 16212 16213 if (idlein == 0) { 16214 idlein = DNS_DEFAULT_IDLEIN; 16215 } 16216 zone->idlein = idlein; 16217} 16218 16219uint32_t 16220dns_zone_getidlein(dns_zone_t *zone) { 16221 REQUIRE(DNS_ZONE_VALID(zone)); 16222 16223 return (zone->idlein); 16224} 16225 16226void 16227dns_zone_setidleout(dns_zone_t *zone, uint32_t idleout) { 16228 REQUIRE(DNS_ZONE_VALID(zone)); 16229 16230 zone->idleout = idleout; 16231} 16232 16233uint32_t 16234dns_zone_getidleout(dns_zone_t *zone) { 16235 REQUIRE(DNS_ZONE_VALID(zone)); 16236 16237 return (zone->idleout); 16238} 16239 16240static void 16241notify_done(isc_task_t *task, isc_event_t *event) { 16242 dns_requestevent_t *revent = (dns_requestevent_t *)event; 16243 dns_notify_t *notify; 16244 isc_result_t result; 16245 dns_message_t *message = NULL; 16246 isc_buffer_t buf; 16247 char rcode[128]; 16248 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 16249 16250 UNUSED(task); 16251 16252 notify = event->ev_arg; 16253 REQUIRE(DNS_NOTIFY_VALID(notify)); 16254 INSIST(task == notify->zone->task); 16255 16256 isc_buffer_init(&buf, rcode, sizeof(rcode)); 16257 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 16258 dns_message_create(notify->zone->mctx, DNS_MESSAGE_INTENTPARSE, 16259 &message); 16260 16261 result = revent->result; 16262 if (result == ISC_R_SUCCESS) { 16263 result = 16264 dns_request_getresponse(revent->request, message, 16265 DNS_MESSAGEPARSE_PRESERVEORDER); 16266 } 16267 if (result == ISC_R_SUCCESS) { 16268 result = dns_rcode_totext(message->rcode, &buf); 16269 } 16270 if (result == ISC_R_SUCCESS) { 16271 notify_log(notify->zone, ISC_LOG_DEBUG(3), 16272 "notify response from %s: %.*s", addrbuf, 16273 (int)buf.used, rcode); 16274 } else { 16275 notify_log(notify->zone, ISC_LOG_DEBUG(2), 16276 "notify to %s failed: %s", addrbuf, 16277 dns_result_totext(result)); 16278 } 16279 16280 /* 16281 * Old bind's return formerr if they see a soa record. Retry w/o 16282 * the soa if we see a formerr and had sent a SOA. 16283 */ 16284 isc_event_free(&event); 16285 if (message->rcode == dns_rcode_formerr && 16286 (notify->flags & DNS_NOTIFY_NOSOA) == 0) 16287 { 16288 bool startup; 16289 16290 notify->flags |= DNS_NOTIFY_NOSOA; 16291 dns_request_destroy(¬ify->request); 16292 startup = (notify->flags & DNS_NOTIFY_STARTUP); 16293 result = notify_send_queue(notify, startup); 16294 if (result != ISC_R_SUCCESS) { 16295 notify_destroy(notify, false); 16296 } 16297 } else { 16298 if (result == ISC_R_TIMEDOUT) { 16299 notify_log(notify->zone, ISC_LOG_DEBUG(1), 16300 "notify to %s: retries exceeded", addrbuf); 16301 } 16302 notify_destroy(notify, false); 16303 } 16304 dns_message_detach(&message); 16305} 16306 16307struct secure_event { 16308 isc_event_t e; 16309 dns_db_t *db; 16310 uint32_t serial; 16311}; 16312 16313static void 16314update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) { 16315 UNUSED(arg); 16316 dns_zone_log(zone, level, "%s", message); 16317} 16318 16319static isc_result_t 16320sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal, 16321 uint32_t start, uint32_t end, dns_difftuple_t **soatuplep, 16322 dns_diff_t *diff) { 16323 isc_result_t result; 16324 dns_difftuple_t *tuple = NULL; 16325 dns_diffop_t op = DNS_DIFFOP_ADD; 16326 int n_soa = 0; 16327 16328 REQUIRE(soatuplep != NULL); 16329 16330 if (start == end) { 16331 return (DNS_R_UNCHANGED); 16332 } 16333 16334 CHECK(dns_journal_iter_init(journal, start, end, NULL)); 16335 for (result = dns_journal_first_rr(journal); result == ISC_R_SUCCESS; 16336 result = dns_journal_next_rr(journal)) 16337 { 16338 dns_name_t *name = NULL; 16339 uint32_t ttl; 16340 dns_rdata_t *rdata = NULL; 16341 dns_journal_current_rr(journal, &name, &ttl, &rdata); 16342 16343 if (rdata->type == dns_rdatatype_soa) { 16344 n_soa++; 16345 if (n_soa == 2) { 16346 /* 16347 * Save the latest raw SOA record. 16348 */ 16349 if (*soatuplep != NULL) { 16350 dns_difftuple_free(soatuplep); 16351 } 16352 CHECK(dns_difftuple_create( 16353 diff->mctx, DNS_DIFFOP_ADD, name, ttl, 16354 rdata, soatuplep)); 16355 } 16356 if (n_soa == 3) { 16357 n_soa = 1; 16358 } 16359 continue; 16360 } 16361 16362 /* Sanity. */ 16363 if (n_soa == 0) { 16364 dns_zone_log(raw, ISC_LOG_ERROR, 16365 "corrupt journal file: '%s'\n", 16366 raw->journal); 16367 return (ISC_R_FAILURE); 16368 } 16369 16370 if (zone->privatetype != 0 && rdata->type == zone->privatetype) 16371 { 16372 continue; 16373 } 16374 16375 if (rdata->type == dns_rdatatype_nsec || 16376 rdata->type == dns_rdatatype_rrsig || 16377 rdata->type == dns_rdatatype_nsec3 || 16378 rdata->type == dns_rdatatype_dnskey || 16379 rdata->type == dns_rdatatype_nsec3param) 16380 { 16381 continue; 16382 } 16383 16384 op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD; 16385 16386 CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata, 16387 &tuple)); 16388 dns_diff_appendminimal(diff, &tuple); 16389 } 16390 if (result == ISC_R_NOMORE) { 16391 result = ISC_R_SUCCESS; 16392 } 16393 16394failure: 16395 return (result); 16396} 16397 16398static isc_result_t 16399sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb, 16400 dns_dbversion_t *secver, dns_difftuple_t **soatuple, 16401 dns_diff_t *diff) { 16402 isc_result_t result; 16403 dns_db_t *rawdb = NULL; 16404 dns_dbversion_t *rawver = NULL; 16405 dns_difftuple_t *tuple = NULL, *next; 16406 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL; 16407 dns_rdata_soa_t oldsoa, newsoa; 16408 16409 REQUIRE(DNS_ZONE_VALID(seczone)); 16410 REQUIRE(soatuple != NULL && *soatuple == NULL); 16411 16412 if (!seczone->sourceserialset) { 16413 return (DNS_R_UNCHANGED); 16414 } 16415 16416 dns_db_attach(raw->db, &rawdb); 16417 dns_db_currentversion(rawdb, &rawver); 16418 result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL); 16419 dns_db_closeversion(rawdb, &rawver, false); 16420 dns_db_detach(&rawdb); 16421 16422 if (result != ISC_R_SUCCESS) { 16423 return (result); 16424 } 16425 16426 for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; tuple = next) { 16427 next = ISC_LIST_NEXT(tuple, link); 16428 if (tuple->rdata.type == dns_rdatatype_nsec || 16429 tuple->rdata.type == dns_rdatatype_rrsig || 16430 tuple->rdata.type == dns_rdatatype_dnskey || 16431 tuple->rdata.type == dns_rdatatype_nsec3 || 16432 tuple->rdata.type == dns_rdatatype_nsec3param) 16433 { 16434 ISC_LIST_UNLINK(diff->tuples, tuple, link); 16435 dns_difftuple_free(&tuple); 16436 continue; 16437 } 16438 if (tuple->rdata.type == dns_rdatatype_soa) { 16439 if (tuple->op == DNS_DIFFOP_DEL) { 16440 INSIST(oldtuple == NULL); 16441 oldtuple = tuple; 16442 } 16443 if (tuple->op == DNS_DIFFOP_ADD) { 16444 INSIST(newtuple == NULL); 16445 newtuple = tuple; 16446 } 16447 } 16448 } 16449 16450 if (oldtuple != NULL && newtuple != NULL) { 16451 result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL); 16452 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16453 16454 result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL); 16455 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16456 16457 /* 16458 * If the SOA records are the same except for the serial 16459 * remove them from the diff. 16460 */ 16461 if (oldtuple->ttl == newtuple->ttl && 16462 oldsoa.refresh == newsoa.refresh && 16463 oldsoa.retry == newsoa.retry && 16464 oldsoa.minimum == newsoa.minimum && 16465 oldsoa.expire == newsoa.expire && 16466 dns_name_equal(&oldsoa.origin, &newsoa.origin) && 16467 dns_name_equal(&oldsoa.contact, &newsoa.contact)) 16468 { 16469 ISC_LIST_UNLINK(diff->tuples, oldtuple, link); 16470 dns_difftuple_free(&oldtuple); 16471 ISC_LIST_UNLINK(diff->tuples, newtuple, link); 16472 dns_difftuple_free(&newtuple); 16473 } 16474 } 16475 16476 if (ISC_LIST_EMPTY(diff->tuples)) { 16477 return (DNS_R_UNCHANGED); 16478 } 16479 16480 /* 16481 * If there are still SOA records in the diff they can now be removed 16482 * saving the new SOA record. 16483 */ 16484 if (oldtuple != NULL) { 16485 ISC_LIST_UNLINK(diff->tuples, oldtuple, link); 16486 dns_difftuple_free(&oldtuple); 16487 } 16488 16489 if (newtuple != NULL) { 16490 ISC_LIST_UNLINK(diff->tuples, newtuple, link); 16491 *soatuple = newtuple; 16492 } 16493 16494 return (ISC_R_SUCCESS); 16495} 16496 16497static void 16498receive_secure_serial(isc_task_t *task, isc_event_t *event) { 16499 static char me[] = "receive_secure_serial"; 16500 isc_result_t result = ISC_R_SUCCESS; 16501 dns_journal_t *rjournal = NULL; 16502 dns_journal_t *sjournal = NULL; 16503 uint32_t start, end; 16504 dns_zone_t *zone; 16505 dns_difftuple_t *tuple = NULL, *soatuple = NULL; 16506 dns_update_log_t log = { update_log_cb, NULL }; 16507 uint32_t newserial = 0, desired = 0; 16508 isc_time_t timenow; 16509 int level = ISC_LOG_ERROR; 16510 16511 UNUSED(task); 16512 16513 zone = event->ev_arg; 16514 end = ((struct secure_event *)event)->serial; 16515 16516 ENTER; 16517 16518 LOCK_ZONE(zone); 16519 16520 /* 16521 * If we are already processing a receive secure serial event 16522 * for the zone, just queue the new one and exit. 16523 */ 16524 if (zone->rss_event != NULL && zone->rss_event != event) { 16525 ISC_LIST_APPEND(zone->rss_events, event, ev_link); 16526 UNLOCK_ZONE(zone); 16527 return; 16528 } 16529 16530nextevent: 16531 if (zone->rss_event != NULL) { 16532 INSIST(zone->rss_event == event); 16533 UNLOCK_ZONE(zone); 16534 } else { 16535 zone->rss_event = event; 16536 dns_diff_init(zone->mctx, &zone->rss_diff); 16537 16538 /* 16539 * zone->db may be NULL, if the load from disk failed. 16540 */ 16541 result = ISC_R_SUCCESS; 16542 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 16543 if (zone->db != NULL) { 16544 dns_db_attach(zone->db, &zone->rss_db); 16545 } else { 16546 result = ISC_R_FAILURE; 16547 } 16548 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 16549 16550 if (result == ISC_R_SUCCESS && zone->raw != NULL) { 16551 dns_zone_attach(zone->raw, &zone->rss_raw); 16552 } else { 16553 result = ISC_R_FAILURE; 16554 } 16555 16556 UNLOCK_ZONE(zone); 16557 16558 CHECK(result); 16559 16560 /* 16561 * We first attempt to sync the raw zone to the secure zone 16562 * by using the raw zone's journal, applying all the deltas 16563 * from the latest source-serial of the secure zone up to 16564 * the current serial number of the raw zone. 16565 * 16566 * If that fails, then we'll fall back to a direct comparison 16567 * between raw and secure zones. 16568 */ 16569 CHECK(dns_journal_open(zone->rss_raw->mctx, 16570 zone->rss_raw->journal, 16571 DNS_JOURNAL_WRITE, &rjournal)); 16572 16573 result = dns_journal_open(zone->mctx, zone->journal, 16574 DNS_JOURNAL_READ, &sjournal); 16575 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 16576 goto failure; 16577 } 16578 16579 if (!dns_journal_get_sourceserial(rjournal, &start)) { 16580 start = dns_journal_first_serial(rjournal); 16581 dns_journal_set_sourceserial(rjournal, start); 16582 } 16583 if (sjournal != NULL) { 16584 uint32_t serial; 16585 /* 16586 * We read the secure journal first, if that 16587 * exists use its value provided it is greater 16588 * that from the raw journal. 16589 */ 16590 if (dns_journal_get_sourceserial(sjournal, &serial)) { 16591 if (isc_serial_gt(serial, start)) { 16592 start = serial; 16593 } 16594 } 16595 dns_journal_destroy(&sjournal); 16596 } 16597 16598 dns_db_currentversion(zone->rss_db, &zone->rss_oldver); 16599 CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver)); 16600 16601 /* 16602 * Try to apply diffs from the raw zone's journal to the secure 16603 * zone. If that fails, we recover by syncing up the databases 16604 * directly. 16605 */ 16606 result = sync_secure_journal(zone, zone->rss_raw, rjournal, 16607 start, end, &soatuple, 16608 &zone->rss_diff); 16609 if (result == DNS_R_UNCHANGED) { 16610 level = ISC_LOG_INFO; 16611 goto failure; 16612 } else if (result != ISC_R_SUCCESS) { 16613 CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db, 16614 zone->rss_oldver, &soatuple, 16615 &zone->rss_diff)); 16616 } 16617 16618 CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db, 16619 zone->rss_newver)); 16620 16621 if (soatuple != NULL) { 16622 uint32_t oldserial; 16623 16624 CHECK(dns_db_createsoatuple( 16625 zone->rss_db, zone->rss_oldver, 16626 zone->rss_diff.mctx, DNS_DIFFOP_DEL, &tuple)); 16627 oldserial = dns_soa_getserial(&tuple->rdata); 16628 newserial = desired = 16629 dns_soa_getserial(&soatuple->rdata); 16630 if (!isc_serial_gt(newserial, oldserial)) { 16631 newserial = oldserial + 1; 16632 if (newserial == 0) { 16633 newserial++; 16634 } 16635 dns_soa_setserial(newserial, &soatuple->rdata); 16636 } 16637 CHECK(do_one_tuple(&tuple, zone->rss_db, 16638 zone->rss_newver, &zone->rss_diff)); 16639 CHECK(do_one_tuple(&soatuple, zone->rss_db, 16640 zone->rss_newver, &zone->rss_diff)); 16641 } else { 16642 CHECK(update_soa_serial(zone, zone->rss_db, 16643 zone->rss_newver, 16644 &zone->rss_diff, zone->mctx, 16645 zone->updatemethod)); 16646 } 16647 } 16648 result = dns_update_signaturesinc( 16649 &log, zone, zone->rss_db, zone->rss_oldver, zone->rss_newver, 16650 &zone->rss_diff, zone->sigvalidityinterval, &zone->rss_state); 16651 if (result == DNS_R_CONTINUE) { 16652 if (rjournal != NULL) { 16653 dns_journal_destroy(&rjournal); 16654 } 16655 isc_task_send(task, &event); 16656 return; 16657 } 16658 /* 16659 * If something went wrong while trying to update the secure zone and 16660 * the latter was already signed before, do not apply raw zone deltas 16661 * to it as that would break existing DNSSEC signatures. However, if 16662 * the secure zone was not yet signed (e.g. because no signing keys 16663 * were created for it), commence applying raw zone deltas to it so 16664 * that contents of the raw zone and the secure zone are kept in sync. 16665 */ 16666 if (result != ISC_R_SUCCESS && dns_db_issecure(zone->rss_db)) { 16667 goto failure; 16668 } 16669 16670 if (rjournal == NULL) { 16671 CHECK(dns_journal_open(zone->rss_raw->mctx, 16672 zone->rss_raw->journal, 16673 DNS_JOURNAL_WRITE, &rjournal)); 16674 } 16675 CHECK(zone_journal(zone, &zone->rss_diff, &end, 16676 "receive_secure_serial")); 16677 16678 dns_journal_set_sourceserial(rjournal, end); 16679 dns_journal_commit(rjournal); 16680 16681 LOCK_ZONE(zone); 16682 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 16683 16684 zone->sourceserial = end; 16685 zone->sourceserialset = true; 16686 zone_needdump(zone, DNS_DUMP_DELAY); 16687 16688 /* 16689 * Set resign time to make sure it is set to the earliest 16690 * signature expiration. 16691 */ 16692 set_resigntime(zone); 16693 TIME_NOW(&timenow); 16694 zone_settimer(zone, &timenow); 16695 UNLOCK_ZONE(zone); 16696 16697 dns_db_closeversion(zone->rss_db, &zone->rss_oldver, false); 16698 dns_db_closeversion(zone->rss_db, &zone->rss_newver, true); 16699 16700 if (newserial != 0) { 16701 dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)", 16702 newserial, desired); 16703 } 16704 16705failure: 16706 isc_event_free(&zone->rss_event); 16707 event = ISC_LIST_HEAD(zone->rss_events); 16708 16709 if (zone->rss_raw != NULL) { 16710 dns_zone_detach(&zone->rss_raw); 16711 } 16712 if (result != ISC_R_SUCCESS) { 16713 LOCK_ZONE(zone); 16714 set_resigntime(zone); 16715 TIME_NOW(&timenow); 16716 zone_settimer(zone, &timenow); 16717 UNLOCK_ZONE(zone); 16718 dns_zone_log(zone, level, "receive_secure_serial: %s", 16719 dns_result_totext(result)); 16720 } 16721 if (tuple != NULL) { 16722 dns_difftuple_free(&tuple); 16723 } 16724 if (soatuple != NULL) { 16725 dns_difftuple_free(&soatuple); 16726 } 16727 if (zone->rss_db != NULL) { 16728 if (zone->rss_oldver != NULL) { 16729 dns_db_closeversion(zone->rss_db, &zone->rss_oldver, 16730 false); 16731 } 16732 if (zone->rss_newver != NULL) { 16733 dns_db_closeversion(zone->rss_db, &zone->rss_newver, 16734 false); 16735 } 16736 dns_db_detach(&zone->rss_db); 16737 } 16738 INSIST(zone->rss_oldver == NULL); 16739 INSIST(zone->rss_newver == NULL); 16740 if (rjournal != NULL) { 16741 dns_journal_destroy(&rjournal); 16742 } 16743 dns_diff_clear(&zone->rss_diff); 16744 16745 if (event != NULL) { 16746 LOCK_ZONE(zone); 16747 isc_refcount_decrement(&zone->irefs); 16748 ISC_LIST_UNLINK(zone->rss_events, event, ev_link); 16749 goto nextevent; 16750 } 16751 16752 event = ISC_LIST_HEAD(zone->rss_post); 16753 while (event != NULL) { 16754 ISC_LIST_UNLINK(zone->rss_post, event, ev_link); 16755 rss_post(zone, event); 16756 event = ISC_LIST_HEAD(zone->rss_post); 16757 } 16758 16759 dns_zone_idetach(&zone); 16760} 16761 16762static isc_result_t 16763zone_send_secureserial(dns_zone_t *zone, uint32_t serial) { 16764 isc_event_t *e; 16765 dns_zone_t *dummy = NULL; 16766 16767 e = isc_event_allocate(zone->secure->mctx, zone, 16768 DNS_EVENT_ZONESECURESERIAL, 16769 receive_secure_serial, zone->secure, 16770 sizeof(struct secure_event)); 16771 ((struct secure_event *)e)->serial = serial; 16772 INSIST(LOCKED_ZONE(zone->secure)); 16773 zone_iattach(zone->secure, &dummy); 16774 isc_task_send(zone->secure->task, &e); 16775 16776 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); 16777 return (ISC_R_SUCCESS); 16778} 16779 16780static isc_result_t 16781checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 16782 dns_rdataset_t *rdataset, uint32_t oldserial) { 16783 dns_rdata_soa_t soa; 16784 dns_rdata_t rdata = DNS_RDATA_INIT; 16785 dns_rdatalist_t temprdatalist; 16786 dns_rdataset_t temprdataset; 16787 isc_buffer_t b; 16788 isc_result_t result; 16789 unsigned char buf[DNS_SOA_BUFFERSIZE]; 16790 dns_fixedname_t fixed; 16791 dns_name_t *name; 16792 16793 result = dns_rdataset_first(rdataset); 16794 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16795 dns_rdataset_current(rdataset, &rdata); 16796 result = dns_rdata_tostruct(&rdata, &soa, NULL); 16797 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16798 16799 if (isc_serial_gt(soa.serial, oldserial)) { 16800 return (dns_db_addrdataset(db, node, version, 0, rdataset, 0, 16801 NULL)); 16802 } 16803 /* 16804 * Always bump the serial. 16805 */ 16806 oldserial++; 16807 if (oldserial == 0) { 16808 oldserial++; 16809 } 16810 soa.serial = oldserial; 16811 16812 /* 16813 * Construct a replacement rdataset. 16814 */ 16815 dns_rdata_reset(&rdata); 16816 isc_buffer_init(&b, buf, sizeof(buf)); 16817 result = dns_rdata_fromstruct(&rdata, rdataset->rdclass, 16818 dns_rdatatype_soa, &soa, &b); 16819 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16820 dns_rdatalist_init(&temprdatalist); 16821 temprdatalist.rdclass = rdata.rdclass; 16822 temprdatalist.type = rdata.type; 16823 temprdatalist.ttl = rdataset->ttl; 16824 ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link); 16825 16826 dns_rdataset_init(&temprdataset); 16827 result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset); 16828 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16829 16830 name = dns_fixedname_initname(&fixed); 16831 result = dns_db_nodefullname(db, node, name); 16832 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16833 dns_rdataset_getownercase(rdataset, name); 16834 dns_rdataset_setownercase(&temprdataset, name); 16835 return (dns_db_addrdataset(db, node, version, 0, &temprdataset, 0, 16836 NULL)); 16837} 16838 16839/* 16840 * This function should populate an nsec3paramlist_t with the 16841 * nsecparam_t data from a zone. 16842 */ 16843static isc_result_t 16844save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) { 16845 isc_result_t result; 16846 dns_dbnode_t *node = NULL; 16847 dns_rdataset_t rdataset, prdataset; 16848 dns_dbversion_t *version = NULL; 16849 nsec3param_t *nsec3param = NULL; 16850 nsec3param_t *nsec3p = NULL; 16851 nsec3param_t *next; 16852 dns_db_t *db = NULL; 16853 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 16854 16855 REQUIRE(DNS_ZONE_VALID(zone)); 16856 REQUIRE(nsec3list != NULL); 16857 REQUIRE(ISC_LIST_EMPTY(*nsec3list)); 16858 16859 dns_rdataset_init(&rdataset); 16860 dns_rdataset_init(&prdataset); 16861 16862 dns_db_attach(zone->db, &db); 16863 CHECK(dns_db_getoriginnode(db, &node)); 16864 16865 dns_db_currentversion(db, &version); 16866 result = dns_db_findrdataset(db, node, version, 16867 dns_rdatatype_nsec3param, 16868 dns_rdatatype_none, 0, &rdataset, NULL); 16869 16870 if (result != ISC_R_SUCCESS) { 16871 goto getprivate; 16872 } 16873 16874 /* 16875 * Walk nsec3param rdataset making a list of parameters (note that 16876 * multiple simultaneous nsec3 chains are annoyingly legal -- this 16877 * is why we use an nsec3list, even though we will usually only 16878 * have one). 16879 */ 16880 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 16881 result = dns_rdataset_next(&rdataset)) 16882 { 16883 dns_rdata_t rdata = DNS_RDATA_INIT; 16884 dns_rdata_t private = DNS_RDATA_INIT; 16885 16886 dns_rdataset_current(&rdataset, &rdata); 16887 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 16888 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 16889 "looping through nsec3param data"); 16890 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t)); 16891 ISC_LINK_INIT(nsec3param, link); 16892 16893 /* 16894 * now transfer the data from the rdata to 16895 * the nsec3param 16896 */ 16897 dns_nsec3param_toprivate(&rdata, &private, zone->privatetype, 16898 nsec3param->data, 16899 sizeof(nsec3param->data)); 16900 nsec3param->length = private.length; 16901 ISC_LIST_APPEND(*nsec3list, nsec3param, link); 16902 } 16903 16904getprivate: 16905 result = dns_db_findrdataset(db, node, version, zone->privatetype, 16906 dns_rdatatype_none, 0, &prdataset, NULL); 16907 if (result != ISC_R_SUCCESS) { 16908 goto done; 16909 } 16910 16911 /* 16912 * walk private type records, converting them to nsec3 parameters 16913 * using dns_nsec3param_fromprivate(), do the right thing based on 16914 * CREATE and REMOVE flags 16915 */ 16916 for (result = dns_rdataset_first(&prdataset); result == ISC_R_SUCCESS; 16917 result = dns_rdataset_next(&prdataset)) 16918 { 16919 dns_rdata_t rdata = DNS_RDATA_INIT; 16920 dns_rdata_t private = DNS_RDATA_INIT; 16921 16922 dns_rdataset_current(&prdataset, &private); 16923 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 16924 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 16925 "looping through nsec3param private data"); 16926 16927 /* 16928 * Do we have a valid private record? 16929 */ 16930 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 16931 sizeof(buf))) 16932 { 16933 continue; 16934 } 16935 16936 /* 16937 * Remove any NSEC3PARAM records scheduled to be removed. 16938 */ 16939 if (NSEC3REMOVE(rdata.data[1])) { 16940 /* 16941 * Zero out the flags. 16942 */ 16943 rdata.data[1] = 0; 16944 16945 for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; 16946 nsec3p = next) 16947 { 16948 next = ISC_LIST_NEXT(nsec3p, link); 16949 16950 if (nsec3p->length == rdata.length + 1 && 16951 memcmp(rdata.data, nsec3p->data + 1, 16952 nsec3p->length - 1) == 0) 16953 { 16954 ISC_LIST_UNLINK(*nsec3list, nsec3p, 16955 link); 16956 isc_mem_put(zone->mctx, nsec3p, 16957 sizeof(nsec3param_t)); 16958 } 16959 } 16960 continue; 16961 } 16962 16963 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t)); 16964 ISC_LINK_INIT(nsec3param, link); 16965 16966 /* 16967 * Copy the remaining private records so the nsec/nsec3 16968 * chain gets created. 16969 */ 16970 INSIST(private.length <= sizeof(nsec3param->data)); 16971 memmove(nsec3param->data, private.data, private.length); 16972 nsec3param->length = private.length; 16973 ISC_LIST_APPEND(*nsec3list, nsec3param, link); 16974 } 16975 16976done: 16977 if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) { 16978 result = ISC_R_SUCCESS; 16979 } 16980 16981failure: 16982 if (node != NULL) { 16983 dns_db_detachnode(db, &node); 16984 } 16985 if (version != NULL) { 16986 dns_db_closeversion(db, &version, false); 16987 } 16988 if (db != NULL) { 16989 dns_db_detach(&db); 16990 } 16991 if (dns_rdataset_isassociated(&rdataset)) { 16992 dns_rdataset_disassociate(&rdataset); 16993 } 16994 if (dns_rdataset_isassociated(&prdataset)) { 16995 dns_rdataset_disassociate(&prdataset); 16996 } 16997 return (result); 16998} 16999 17000/* 17001 * Populate new zone db with private type records found by save_nsec3param(). 17002 */ 17003static isc_result_t 17004restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 17005 nsec3paramlist_t *nsec3list) { 17006 isc_result_t result = ISC_R_SUCCESS; 17007 dns_diff_t diff; 17008 dns_rdata_t rdata; 17009 nsec3param_t *nsec3p = NULL; 17010 nsec3param_t *next; 17011 17012 REQUIRE(DNS_ZONE_VALID(zone)); 17013 REQUIRE(!ISC_LIST_EMPTY(*nsec3list)); 17014 17015 dns_diff_init(zone->mctx, &diff); 17016 17017 /* 17018 * Loop through the list of private-type records, set the INITIAL 17019 * and CREATE flags, and the add the record to the apex of the tree 17020 * in db. 17021 */ 17022 for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; nsec3p = next) 17023 { 17024 next = ISC_LIST_NEXT(nsec3p, link); 17025 dns_rdata_init(&rdata); 17026 nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL; 17027 rdata.length = nsec3p->length; 17028 rdata.data = nsec3p->data; 17029 rdata.type = zone->privatetype; 17030 rdata.rdclass = zone->rdclass; 17031 result = update_one_rr(db, version, &diff, DNS_DIFFOP_ADD, 17032 &zone->origin, 0, &rdata); 17033 if (result != ISC_R_SUCCESS) { 17034 break; 17035 } 17036 } 17037 17038 dns_diff_clear(&diff); 17039 return (result); 17040} 17041 17042static isc_result_t 17043copy_non_dnssec_records(dns_db_t *db, dns_db_t *version, dns_db_t *rawdb, 17044 dns_dbiterator_t *dbiterator, unsigned int *oldserial) { 17045 dns_dbnode_t *rawnode = NULL, *node = NULL; 17046 dns_fixedname_t fixed; 17047 dns_name_t *name = dns_fixedname_initname(&fixed); 17048 dns_rdataset_t rdataset; 17049 dns_rdatasetiter_t *rdsit = NULL; 17050 isc_result_t result; 17051 17052 result = dns_dbiterator_current(dbiterator, &rawnode, name); 17053 if (result != ISC_R_SUCCESS) { 17054 return (ISC_R_SUCCESS); 17055 } 17056 17057 dns_dbiterator_pause(dbiterator); 17058 17059 result = dns_db_findnode(db, name, true, &node); 17060 if (result != ISC_R_SUCCESS) { 17061 goto cleanup; 17062 } 17063 17064 result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, 0, &rdsit); 17065 if (result != ISC_R_SUCCESS) { 17066 goto cleanup; 17067 } 17068 17069 dns_rdataset_init(&rdataset); 17070 17071 for (result = dns_rdatasetiter_first(rdsit); result == ISC_R_SUCCESS; 17072 result = dns_rdatasetiter_next(rdsit)) 17073 { 17074 dns_rdatasetiter_current(rdsit, &rdataset); 17075 if (rdataset.type == dns_rdatatype_nsec || 17076 rdataset.type == dns_rdatatype_rrsig || 17077 rdataset.type == dns_rdatatype_nsec3 || 17078 rdataset.type == dns_rdatatype_dnskey || 17079 rdataset.type == dns_rdatatype_nsec3param) 17080 { 17081 dns_rdataset_disassociate(&rdataset); 17082 continue; 17083 } 17084 if (rdataset.type == dns_rdatatype_soa && oldserial != NULL) { 17085 result = checkandaddsoa(db, node, version, &rdataset, 17086 *oldserial); 17087 } else { 17088 result = dns_db_addrdataset(db, node, version, 0, 17089 &rdataset, 0, NULL); 17090 } 17091 dns_rdataset_disassociate(&rdataset); 17092 if (result != ISC_R_SUCCESS) { 17093 goto cleanup; 17094 } 17095 } 17096 if (result == ISC_R_NOMORE) { 17097 result = ISC_R_SUCCESS; 17098 } 17099 17100cleanup: 17101 if (rdsit != NULL) { 17102 dns_rdatasetiter_destroy(&rdsit); 17103 } 17104 if (rawnode) { 17105 dns_db_detachnode(rawdb, &rawnode); 17106 } 17107 if (node) { 17108 dns_db_detachnode(db, &node); 17109 } 17110 return (result); 17111} 17112 17113static void 17114receive_secure_db(isc_task_t *task, isc_event_t *event) { 17115 isc_result_t result; 17116 dns_zone_t *zone; 17117 dns_db_t *rawdb, *db = NULL; 17118 dns_dbiterator_t *dbiterator = NULL; 17119 dns_dbversion_t *version = NULL; 17120 isc_time_t loadtime; 17121 unsigned int oldserial = 0, *oldserialp = NULL; 17122 nsec3paramlist_t nsec3list; 17123 isc_event_t *setnsec3param_event; 17124 dns_zone_t *dummy; 17125 17126 UNUSED(task); 17127 17128 ISC_LIST_INIT(nsec3list); 17129 17130 zone = event->ev_arg; 17131 rawdb = ((struct secure_event *)event)->db; 17132 isc_event_free(&event); 17133 17134 LOCK_ZONE(zone); 17135 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) { 17136 result = ISC_R_SHUTTINGDOWN; 17137 goto failure; 17138 } 17139 17140 TIME_NOW(&loadtime); 17141 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 17142 if (zone->db != NULL) { 17143 result = dns_db_getsoaserial(zone->db, NULL, &oldserial); 17144 if (result == ISC_R_SUCCESS) { 17145 oldserialp = &oldserial; 17146 } 17147 17148 /* 17149 * assemble nsec3parameters from the old zone, and set a flag 17150 * if any are found 17151 */ 17152 result = save_nsec3param(zone, &nsec3list); 17153 if (result != ISC_R_SUCCESS) { 17154 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17155 goto failure; 17156 } 17157 } 17158 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17159 17160 result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, 17161 dns_dbtype_zone, zone->rdclass, 17162 zone->db_argc - 1, zone->db_argv + 1, &db); 17163 if (result != ISC_R_SUCCESS) { 17164 goto failure; 17165 } 17166 17167 result = dns_db_setgluecachestats(db, zone->gluecachestats); 17168 if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { 17169 goto failure; 17170 } 17171 17172 result = dns_db_newversion(db, &version); 17173 if (result != ISC_R_SUCCESS) { 17174 goto failure; 17175 } 17176 17177 result = dns_db_createiterator(rawdb, 0, &dbiterator); 17178 if (result != ISC_R_SUCCESS) { 17179 goto failure; 17180 } 17181 17182 for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS; 17183 result = dns_dbiterator_next(dbiterator)) 17184 { 17185 result = copy_non_dnssec_records(db, version, rawdb, dbiterator, 17186 oldserialp); 17187 if (result != ISC_R_SUCCESS) { 17188 goto failure; 17189 } 17190 } 17191 dns_dbiterator_destroy(&dbiterator); 17192 if (result != ISC_R_NOMORE) { 17193 goto failure; 17194 } 17195 17196 /* 17197 * Call restore_nsec3param() to create private-type records from 17198 * the old nsec3 parameters and insert them into db 17199 */ 17200 if (!ISC_LIST_EMPTY(nsec3list)) { 17201 result = restore_nsec3param(zone, db, version, &nsec3list); 17202 if (result != ISC_R_SUCCESS) { 17203 goto failure; 17204 } 17205 } 17206 17207 dns_db_closeversion(db, &version, true); 17208 17209 /* 17210 * Lock hierarchy: zmgr, zone, raw. 17211 */ 17212 INSIST(zone != zone->raw); 17213 LOCK_ZONE(zone->raw); 17214 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 17215 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 17216 zone_needdump(zone, 0); /* XXXMPA */ 17217 UNLOCK_ZONE(zone->raw); 17218 17219 /* 17220 * Process any queued NSEC3PARAM change requests. 17221 */ 17222 while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) { 17223 setnsec3param_event = ISC_LIST_HEAD(zone->setnsec3param_queue); 17224 ISC_LIST_UNLINK(zone->setnsec3param_queue, setnsec3param_event, 17225 ev_link); 17226 dummy = NULL; 17227 zone_iattach(zone, &dummy); 17228 isc_task_send(zone->task, &setnsec3param_event); 17229 } 17230 17231failure: 17232 UNLOCK_ZONE(zone); 17233 if (dbiterator != NULL) { 17234 dns_dbiterator_destroy(&dbiterator); 17235 } 17236 if (result != ISC_R_SUCCESS) { 17237 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s", 17238 dns_result_totext(result)); 17239 } 17240 17241 while (!ISC_LIST_EMPTY(nsec3list)) { 17242 nsec3param_t *nsec3p; 17243 nsec3p = ISC_LIST_HEAD(nsec3list); 17244 ISC_LIST_UNLINK(nsec3list, nsec3p, link); 17245 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t)); 17246 } 17247 if (db != NULL) { 17248 if (version != NULL) { 17249 dns_db_closeversion(db, &version, false); 17250 } 17251 dns_db_detach(&db); 17252 } 17253 dns_db_detach(&rawdb); 17254 dns_zone_idetach(&zone); 17255 17256 INSIST(version == NULL); 17257} 17258 17259static isc_result_t 17260zone_send_securedb(dns_zone_t *zone, dns_db_t *db) { 17261 isc_event_t *e; 17262 dns_db_t *dummy = NULL; 17263 dns_zone_t *secure = NULL; 17264 17265 e = isc_event_allocate(zone->secure->mctx, zone, DNS_EVENT_ZONESECUREDB, 17266 receive_secure_db, zone->secure, 17267 sizeof(struct secure_event)); 17268 dns_db_attach(db, &dummy); 17269 ((struct secure_event *)e)->db = dummy; 17270 INSIST(LOCKED_ZONE(zone->secure)); 17271 zone_iattach(zone->secure, &secure); 17272 isc_task_send(zone->secure->task, &e); 17273 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); 17274 return (ISC_R_SUCCESS); 17275} 17276 17277isc_result_t 17278dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) { 17279 isc_result_t result; 17280 dns_zone_t *secure = NULL; 17281 17282 REQUIRE(DNS_ZONE_VALID(zone)); 17283again: 17284 LOCK_ZONE(zone); 17285 if (inline_raw(zone)) { 17286 secure = zone->secure; 17287 INSIST(secure != zone); 17288 TRYLOCK_ZONE(result, secure); 17289 if (result != ISC_R_SUCCESS) { 17290 UNLOCK_ZONE(zone); 17291 secure = NULL; 17292 isc_thread_yield(); 17293 goto again; 17294 } 17295 } 17296 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 17297 result = zone_replacedb(zone, db, dump); 17298 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 17299 if (secure != NULL) { 17300 UNLOCK_ZONE(secure); 17301 } 17302 UNLOCK_ZONE(zone); 17303 return (result); 17304} 17305 17306static isc_result_t 17307zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) { 17308 dns_dbversion_t *ver; 17309 isc_result_t result; 17310 unsigned int soacount = 0; 17311 unsigned int nscount = 0; 17312 17313 /* 17314 * 'zone' and 'zone->db' locked by caller. 17315 */ 17316 REQUIRE(DNS_ZONE_VALID(zone)); 17317 REQUIRE(LOCKED_ZONE(zone)); 17318 if (inline_raw(zone)) { 17319 REQUIRE(LOCKED_ZONE(zone->secure)); 17320 } 17321 17322 result = zone_get_from_db(zone, db, &nscount, &soacount, NULL, NULL, 17323 NULL, NULL, NULL, NULL, NULL); 17324 if (result == ISC_R_SUCCESS) { 17325 if (soacount != 1) { 17326 dns_zone_log(zone, ISC_LOG_ERROR, "has %d SOA records", 17327 soacount); 17328 result = DNS_R_BADZONE; 17329 } 17330 if (nscount == 0 && zone->type != dns_zone_key) { 17331 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records"); 17332 result = DNS_R_BADZONE; 17333 } 17334 if (result != ISC_R_SUCCESS) { 17335 return (result); 17336 } 17337 } else { 17338 dns_zone_log(zone, ISC_LOG_ERROR, 17339 "retrieving SOA and NS records failed: %s", 17340 dns_result_totext(result)); 17341 return (result); 17342 } 17343 17344 result = check_nsec3param(zone, db); 17345 if (result != ISC_R_SUCCESS) { 17346 return (result); 17347 } 17348 17349 ver = NULL; 17350 dns_db_currentversion(db, &ver); 17351 17352 /* 17353 * The initial version of a slave zone is always dumped; 17354 * subsequent versions may be journaled instead if this 17355 * is enabled in the configuration. 17356 */ 17357 if (zone->db != NULL && zone->journal != NULL && 17358 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 17359 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) 17360 { 17361 uint32_t serial, oldserial; 17362 17363 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs"); 17364 17365 result = dns_db_getsoaserial(db, ver, &serial); 17366 if (result != ISC_R_SUCCESS) { 17367 dns_zone_log(zone, ISC_LOG_ERROR, 17368 "ixfr-from-differences: unable to get " 17369 "new serial"); 17370 goto fail; 17371 } 17372 17373 /* 17374 * This is checked in zone_postload() for master zones. 17375 */ 17376 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, 17377 &oldserial, NULL, NULL, NULL, NULL, 17378 NULL); 17379 RUNTIME_CHECK(result == ISC_R_SUCCESS); 17380 RUNTIME_CHECK(soacount > 0U); 17381 if ((zone->type == dns_zone_secondary || 17382 (zone->type == dns_zone_redirect && 17383 zone->masters != NULL)) && 17384 !isc_serial_gt(serial, oldserial)) 17385 { 17386 uint32_t serialmin, serialmax; 17387 serialmin = (oldserial + 1) & 0xffffffffU; 17388 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; 17389 dns_zone_log(zone, ISC_LOG_ERROR, 17390 "ixfr-from-differences: failed: " 17391 "new serial (%u) out of range [%u - %u]", 17392 serial, serialmin, serialmax); 17393 result = ISC_R_RANGE; 17394 goto fail; 17395 } 17396 17397 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL, 17398 zone->journal); 17399 if (result != ISC_R_SUCCESS) { 17400 char strbuf[ISC_STRERRORSIZE]; 17401 strerror_r(errno, strbuf, sizeof(strbuf)); 17402 dns_zone_log(zone, ISC_LOG_ERROR, 17403 "ixfr-from-differences: failed: " 17404 "%s", 17405 strbuf); 17406 goto fallback; 17407 } 17408 if (dump) { 17409 zone_needdump(zone, DNS_DUMP_DELAY); 17410 } else { 17411 zone_journal_compact(zone, zone->db, serial); 17412 } 17413 if (zone->type == dns_zone_primary && inline_raw(zone)) { 17414 zone_send_secureserial(zone, serial); 17415 } 17416 } else { 17417 fallback: 17418 if (dump && zone->masterfile != NULL) { 17419 /* 17420 * If DNS_ZONEFLG_FORCEXFER was set we don't want 17421 * to keep the old masterfile. 17422 */ 17423 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) && 17424 remove(zone->masterfile) < 0 && errno != ENOENT) 17425 { 17426 char strbuf[ISC_STRERRORSIZE]; 17427 strerror_r(errno, strbuf, sizeof(strbuf)); 17428 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17429 DNS_LOGMODULE_ZONE, 17430 ISC_LOG_WARNING, 17431 "unable to remove masterfile " 17432 "'%s': '%s'", 17433 zone->masterfile, strbuf); 17434 } 17435 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) { 17436 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY); 17437 } else { 17438 zone_needdump(zone, 0); 17439 } 17440 } 17441 if (dump && zone->journal != NULL) { 17442 /* 17443 * The in-memory database just changed, and 17444 * because 'dump' is set, it didn't change by 17445 * being loaded from disk. Also, we have not 17446 * journaled diffs for this change. 17447 * Therefore, the on-disk journal is missing 17448 * the deltas for this change. Since it can 17449 * no longer be used to bring the zone 17450 * up-to-date, it is useless and should be 17451 * removed. 17452 */ 17453 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17454 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 17455 "removing journal file"); 17456 if (remove(zone->journal) < 0 && errno != ENOENT) { 17457 char strbuf[ISC_STRERRORSIZE]; 17458 strerror_r(errno, strbuf, sizeof(strbuf)); 17459 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17460 DNS_LOGMODULE_ZONE, 17461 ISC_LOG_WARNING, 17462 "unable to remove journal " 17463 "'%s': '%s'", 17464 zone->journal, strbuf); 17465 } 17466 } 17467 17468 if (inline_raw(zone)) { 17469 zone_send_securedb(zone, db); 17470 } 17471 } 17472 17473 dns_db_closeversion(db, &ver, false); 17474 17475 dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database"); 17476 17477 if (zone->db != NULL) { 17478 zone_detachdb(zone); 17479 } 17480 zone_attachdb(zone, db); 17481 dns_db_settask(zone->db, zone->task); 17482 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY); 17483 return (ISC_R_SUCCESS); 17484 17485fail: 17486 dns_db_closeversion(db, &ver, false); 17487 return (result); 17488} 17489 17490/* The caller must hold the dblock as a writer. */ 17491static void 17492zone_attachdb(dns_zone_t *zone, dns_db_t *db) { 17493 REQUIRE(zone->db == NULL && db != NULL); 17494 17495 dns_db_attach(db, &zone->db); 17496} 17497 17498/* The caller must hold the dblock as a writer. */ 17499static void 17500zone_detachdb(dns_zone_t *zone) { 17501 REQUIRE(zone->db != NULL); 17502 17503 dns_zone_rpz_disable_db(zone, zone->db); 17504 dns_zone_catz_disable_db(zone, zone->db); 17505 dns_db_detach(&zone->db); 17506} 17507 17508static void 17509zone_xfrdone(dns_zone_t *zone, isc_result_t result) { 17510 isc_time_t now; 17511 bool again = false; 17512 unsigned int soacount; 17513 unsigned int nscount; 17514 uint32_t serial, refresh, retry, expire, minimum, soattl; 17515 isc_result_t xfrresult = result; 17516 bool free_needed; 17517 dns_zone_t *secure = NULL; 17518 17519 REQUIRE(DNS_ZONE_VALID(zone)); 17520 17521 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 17522 "zone transfer finished: %s", dns_result_totext(result)); 17523 17524 /* 17525 * Obtaining a lock on the zone->secure (see zone_send_secureserial) 17526 * could result in a deadlock due to a LOR so we will spin if we 17527 * can't obtain the both locks. 17528 */ 17529again: 17530 LOCK_ZONE(zone); 17531 if (inline_raw(zone)) { 17532 secure = zone->secure; 17533 INSIST(secure != zone); 17534 TRYLOCK_ZONE(result, secure); 17535 if (result != ISC_R_SUCCESS) { 17536 UNLOCK_ZONE(zone); 17537 secure = NULL; 17538 isc_thread_yield(); 17539 goto again; 17540 } 17541 } 17542 17543 INSIST(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)); 17544 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 17545 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 17546 17547 TIME_NOW(&now); 17548 switch (xfrresult) { 17549 case ISC_R_SUCCESS: 17550 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 17551 FALLTHROUGH; 17552 case DNS_R_UPTODATE: 17553 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER); 17554 /* 17555 * Has the zone expired underneath us? 17556 */ 17557 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 17558 if (zone->db == NULL) { 17559 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17560 goto same_master; 17561 } 17562 17563 /* 17564 * Update the zone structure's data from the actual 17565 * SOA received. 17566 */ 17567 nscount = 0; 17568 soacount = 0; 17569 INSIST(zone->db != NULL); 17570 result = zone_get_from_db(zone, zone->db, &nscount, &soacount, 17571 &soattl, &serial, &refresh, &retry, 17572 &expire, &minimum, NULL); 17573 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17574 if (result == ISC_R_SUCCESS) { 17575 if (soacount != 1) { 17576 dns_zone_log(zone, ISC_LOG_ERROR, 17577 "transferred zone " 17578 "has %d SOA records", 17579 soacount); 17580 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) 17581 { 17582 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 17583 zone->retry = DNS_ZONE_DEFAULTRETRY; 17584 } 17585 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 17586 zone_unload(zone); 17587 goto next_master; 17588 } 17589 if (nscount == 0) { 17590 dns_zone_log(zone, ISC_LOG_ERROR, 17591 "transferred zone " 17592 "has no NS records"); 17593 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) 17594 { 17595 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 17596 zone->retry = DNS_ZONE_DEFAULTRETRY; 17597 } 17598 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 17599 zone_unload(zone); 17600 goto next_master; 17601 } 17602 zone->refresh = RANGE(refresh, zone->minrefresh, 17603 zone->maxrefresh); 17604 zone->retry = RANGE(retry, zone->minretry, 17605 zone->maxretry); 17606 zone->expire = RANGE(expire, 17607 zone->refresh + zone->retry, 17608 DNS_MAX_EXPIRE); 17609 zone->soattl = soattl; 17610 zone->minimum = minimum; 17611 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 17612 } 17613 17614 /* 17615 * Set our next update/expire times. 17616 */ 17617 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 17618 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 17619 zone->refreshtime = now; 17620 DNS_ZONE_TIME_ADD(&now, zone->expire, 17621 &zone->expiretime); 17622 } else { 17623 DNS_ZONE_JITTER_ADD(&now, zone->refresh, 17624 &zone->refreshtime); 17625 DNS_ZONE_TIME_ADD(&now, zone->expire, 17626 &zone->expiretime); 17627 } 17628 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) { 17629 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")]; 17630 if (zone->tsigkey != NULL) { 17631 char namebuf[DNS_NAME_FORMATSIZE]; 17632 dns_name_format(&zone->tsigkey->name, namebuf, 17633 sizeof(namebuf)); 17634 snprintf(buf, sizeof(buf), ": TSIG '%s'", 17635 namebuf); 17636 } else { 17637 buf[0] = '\0'; 17638 } 17639 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 17640 ISC_LOG_INFO, "transferred serial %u%s", 17641 serial, buf); 17642 if (inline_raw(zone)) { 17643 zone_send_secureserial(zone, serial); 17644 } 17645 } 17646 17647 /* 17648 * This is not necessary if we just performed a AXFR 17649 * however it is necessary for an IXFR / UPTODATE and 17650 * won't hurt with an AXFR. 17651 */ 17652 if (zone->masterfile != NULL || zone->journal != NULL) { 17653 unsigned int delay = DNS_DUMP_DELAY; 17654 17655 result = ISC_R_FAILURE; 17656 if (zone->journal != NULL) { 17657 result = isc_file_settime(zone->journal, &now); 17658 } 17659 if (result != ISC_R_SUCCESS && zone->masterfile != NULL) 17660 { 17661 result = isc_file_settime(zone->masterfile, 17662 &now); 17663 } 17664 17665 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) || 17666 result == ISC_R_FILENOTFOUND) 17667 { 17668 delay = 0; 17669 } 17670 17671 if ((result == ISC_R_SUCCESS || 17672 result == ISC_R_FILENOTFOUND) && 17673 zone->masterfile != NULL) 17674 { 17675 zone_needdump(zone, delay); 17676 } else if (result != ISC_R_SUCCESS) { 17677 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 17678 ISC_LOG_ERROR, 17679 "transfer: could not set file " 17680 "modification time of '%s': %s", 17681 zone->masterfile, 17682 dns_result_totext(result)); 17683 } 17684 } 17685 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY); 17686 inc_stats(zone, dns_zonestatscounter_xfrsuccess); 17687 break; 17688 17689 case DNS_R_BADIXFR: 17690 /* Force retry with AXFR. */ 17691 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOIXFR); 17692 goto same_master; 17693 17694 case DNS_R_TOOMANYRECORDS: 17695 case DNS_R_VERIFYFAILURE: 17696 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 17697 inc_stats(zone, dns_zonestatscounter_xfrfail); 17698 break; 17699 17700 default: 17701 next_master: 17702 /* 17703 * Skip to next failed / untried master. 17704 */ 17705 do { 17706 zone->curmaster++; 17707 } while (zone->curmaster < zone->masterscnt && 17708 zone->mastersok[zone->curmaster]); 17709 same_master: 17710 if (zone->curmaster >= zone->masterscnt) { 17711 zone->curmaster = 0; 17712 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 17713 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) 17714 { 17715 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 17716 DNS_ZONE_SETFLAG(zone, 17717 DNS_ZONEFLG_USEALTXFRSRC); 17718 while (zone->curmaster < zone->masterscnt && 17719 zone->mastersok[zone->curmaster]) 17720 { 17721 zone->curmaster++; 17722 } 17723 again = true; 17724 } else { 17725 DNS_ZONE_CLRFLAG(zone, 17726 DNS_ZONEFLG_USEALTXFRSRC); 17727 } 17728 } else { 17729 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 17730 again = true; 17731 } 17732 inc_stats(zone, dns_zonestatscounter_xfrfail); 17733 break; 17734 } 17735 zone_settimer(zone, &now); 17736 17737 /* 17738 * If creating the transfer object failed, zone->xfr is NULL. 17739 * Otherwise, we are called as the done callback of a zone 17740 * transfer object that just entered its shutting-down 17741 * state. Since we are no longer responsible for shutting 17742 * it down, we can detach our reference. 17743 */ 17744 if (zone->xfr != NULL) { 17745 dns_xfrin_detach(&zone->xfr); 17746 } 17747 17748 if (zone->tsigkey != NULL) { 17749 dns_tsigkey_detach(&zone->tsigkey); 17750 } 17751 17752 /* 17753 * Handle any deferred journal compaction. 17754 */ 17755 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) { 17756 dns_db_t *db = NULL; 17757 if (dns_zone_getdb(zone, &db) == ISC_R_SUCCESS) { 17758 zone_journal_compact(zone, db, zone->compact_serial); 17759 dns_db_detach(&db); 17760 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 17761 } 17762 } 17763 17764 if (secure != NULL) { 17765 UNLOCK_ZONE(secure); 17766 } 17767 /* 17768 * This transfer finishing freed up a transfer quota slot. 17769 * Let any other zones waiting for quota have it. 17770 */ 17771 if (zone->zmgr != NULL && 17772 zone->statelist == &zone->zmgr->xfrin_in_progress) 17773 { 17774 UNLOCK_ZONE(zone); 17775 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 17776 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink); 17777 zone->statelist = NULL; 17778 zmgr_resume_xfrs(zone->zmgr, false); 17779 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 17780 LOCK_ZONE(zone); 17781 } 17782 17783 /* 17784 * Retry with a different server if necessary. 17785 */ 17786 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 17787 queue_soa_query(zone); 17788 } 17789 17790 isc_refcount_decrement(&zone->irefs); 17791 free_needed = exit_check(zone); 17792 UNLOCK_ZONE(zone); 17793 if (free_needed) { 17794 zone_free(zone); 17795 } 17796} 17797 17798static void 17799zone_loaddone(void *arg, isc_result_t result) { 17800 static char me[] = "zone_loaddone"; 17801 dns_load_t *load = arg; 17802 dns_zone_t *zone; 17803 isc_result_t tresult; 17804 dns_zone_t *secure = NULL; 17805 17806 REQUIRE(DNS_LOAD_VALID(load)); 17807 zone = load->zone; 17808 17809 ENTER; 17810 17811 /* 17812 * If zone loading failed, remove the update db callbacks prior 17813 * to calling the list of callbacks in the zone load structure. 17814 */ 17815 if (result != ISC_R_SUCCESS) { 17816 dns_zone_rpz_disable_db(zone, load->db); 17817 dns_zone_catz_disable_db(zone, load->db); 17818 } 17819 17820 tresult = dns_db_endload(load->db, &load->callbacks); 17821 if (tresult != ISC_R_SUCCESS && 17822 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)) 17823 { 17824 result = tresult; 17825 } 17826 17827 /* 17828 * Lock hierarchy: zmgr, zone, raw. 17829 */ 17830again: 17831 LOCK_ZONE(zone); 17832 INSIST(zone != zone->raw); 17833 if (inline_secure(zone)) { 17834 LOCK_ZONE(zone->raw); 17835 } else if (inline_raw(zone)) { 17836 secure = zone->secure; 17837 TRYLOCK_ZONE(tresult, secure); 17838 if (tresult != ISC_R_SUCCESS) { 17839 UNLOCK_ZONE(zone); 17840 secure = NULL; 17841 isc_thread_yield(); 17842 goto again; 17843 } 17844 } 17845 (void)zone_postload(zone, load->db, load->loadtime, result); 17846 zonemgr_putio(&zone->readio); 17847 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING); 17848 zone_idetach(&load->callbacks.zone); 17849 /* 17850 * Leave the zone frozen if the reload fails. 17851 */ 17852 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) && 17853 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW)) 17854 { 17855 zone->update_disabled = false; 17856 } 17857 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW); 17858 if (inline_secure(zone)) { 17859 UNLOCK_ZONE(zone->raw); 17860 } else if (secure != NULL) { 17861 UNLOCK_ZONE(secure); 17862 } 17863 UNLOCK_ZONE(zone); 17864 17865 load->magic = 0; 17866 dns_db_detach(&load->db); 17867 if (load->zone->lctx != NULL) { 17868 dns_loadctx_detach(&load->zone->lctx); 17869 } 17870 dns_zone_idetach(&load->zone); 17871 isc_mem_putanddetach(&load->mctx, load, sizeof(*load)); 17872} 17873 17874void 17875dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) { 17876 REQUIRE(DNS_ZONE_VALID(zone)); 17877 REQUIRE(table != NULL); 17878 REQUIRE(*table == NULL); 17879 17880 LOCK_ZONE(zone); 17881 if (zone->ssutable != NULL) { 17882 dns_ssutable_attach(zone->ssutable, table); 17883 } 17884 UNLOCK_ZONE(zone); 17885} 17886 17887void 17888dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) { 17889 REQUIRE(DNS_ZONE_VALID(zone)); 17890 17891 LOCK_ZONE(zone); 17892 if (zone->ssutable != NULL) { 17893 dns_ssutable_detach(&zone->ssutable); 17894 } 17895 if (table != NULL) { 17896 dns_ssutable_attach(table, &zone->ssutable); 17897 } 17898 UNLOCK_ZONE(zone); 17899} 17900 17901void 17902dns_zone_setsigvalidityinterval(dns_zone_t *zone, uint32_t interval) { 17903 REQUIRE(DNS_ZONE_VALID(zone)); 17904 17905 zone->sigvalidityinterval = interval; 17906} 17907 17908uint32_t 17909dns_zone_getsigvalidityinterval(dns_zone_t *zone) { 17910 REQUIRE(DNS_ZONE_VALID(zone)); 17911 17912 return (zone->sigvalidityinterval); 17913} 17914 17915void 17916dns_zone_setkeyvalidityinterval(dns_zone_t *zone, uint32_t interval) { 17917 REQUIRE(DNS_ZONE_VALID(zone)); 17918 17919 zone->keyvalidityinterval = interval; 17920} 17921 17922uint32_t 17923dns_zone_getkeyvalidityinterval(dns_zone_t *zone) { 17924 REQUIRE(DNS_ZONE_VALID(zone)); 17925 17926 return (zone->keyvalidityinterval); 17927} 17928 17929void 17930dns_zone_setsigresigninginterval(dns_zone_t *zone, uint32_t interval) { 17931 isc_time_t now; 17932 17933 REQUIRE(DNS_ZONE_VALID(zone)); 17934 17935 LOCK_ZONE(zone); 17936 zone->sigresigninginterval = interval; 17937 set_resigntime(zone); 17938 if (zone->task != NULL) { 17939 TIME_NOW(&now); 17940 zone_settimer(zone, &now); 17941 } 17942 UNLOCK_ZONE(zone); 17943} 17944 17945uint32_t 17946dns_zone_getsigresigninginterval(dns_zone_t *zone) { 17947 REQUIRE(DNS_ZONE_VALID(zone)); 17948 17949 return (zone->sigresigninginterval); 17950} 17951 17952static void 17953queue_xfrin(dns_zone_t *zone) { 17954 const char me[] = "queue_xfrin"; 17955 isc_result_t result; 17956 dns_zonemgr_t *zmgr = zone->zmgr; 17957 17958 ENTER; 17959 17960 INSIST(zone->statelist == NULL); 17961 17962 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 17963 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink); 17964 isc_refcount_increment0(&zone->irefs); 17965 zone->statelist = &zmgr->waiting_for_xfrin; 17966 result = zmgr_start_xfrin_ifquota(zmgr, zone); 17967 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 17968 17969 if (result == ISC_R_QUOTA) { 17970 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 17971 "zone transfer deferred due to quota"); 17972 } else if (result != ISC_R_SUCCESS) { 17973 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, 17974 "starting zone transfer: %s", 17975 isc_result_totext(result)); 17976 } 17977} 17978 17979/* 17980 * This event callback is called when a zone has received 17981 * any necessary zone transfer quota. This is the time 17982 * to go ahead and start the transfer. 17983 */ 17984static void 17985got_transfer_quota(isc_task_t *task, isc_event_t *event) { 17986 isc_result_t result = ISC_R_SUCCESS; 17987 dns_peer_t *peer = NULL; 17988 char master[ISC_SOCKADDR_FORMATSIZE]; 17989 char source[ISC_SOCKADDR_FORMATSIZE]; 17990 dns_rdatatype_t xfrtype; 17991 dns_zone_t *zone = event->ev_arg; 17992 isc_netaddr_t masterip; 17993 isc_sockaddr_t sourceaddr; 17994 isc_sockaddr_t masteraddr; 17995 isc_time_t now; 17996 const char *soa_before = ""; 17997 isc_dscp_t dscp = -1; 17998 bool loaded; 17999 18000 UNUSED(task); 18001 18002 INSIST(task == zone->task); 18003 18004 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 18005 result = ISC_R_CANCELED; 18006 goto cleanup; 18007 } 18008 18009 TIME_NOW(&now); 18010 18011 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 18012 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, 18013 &zone->sourceaddr, &now)) 18014 { 18015 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 18016 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 18017 "got_transfer_quota: skipping zone transfer as " 18018 "master %s (source %s) is unreachable (cached)", 18019 master, source); 18020 result = ISC_R_CANCELED; 18021 goto cleanup; 18022 } 18023 18024 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 18025 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer); 18026 18027 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) { 18028 soa_before = "SOA before "; 18029 } 18030 /* 18031 * Decide whether we should request IXFR or AXFR. 18032 */ 18033 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 18034 loaded = (zone->db != NULL); 18035 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 18036 18037 if (!loaded) { 18038 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 18039 "no database exists yet, requesting AXFR of " 18040 "initial version from %s", 18041 master); 18042 xfrtype = dns_rdatatype_axfr; 18043 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { 18044 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 18045 "forced reload, requesting AXFR of " 18046 "initial version from %s", 18047 master); 18048 xfrtype = dns_rdatatype_axfr; 18049 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOIXFR)) { 18050 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 18051 "retrying with AXFR from %s due to " 18052 "previous IXFR failure", 18053 master); 18054 xfrtype = dns_rdatatype_axfr; 18055 LOCK_ZONE(zone); 18056 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOIXFR); 18057 UNLOCK_ZONE(zone); 18058 } else { 18059 bool use_ixfr = true; 18060 if (peer != NULL) { 18061 result = dns_peer_getrequestixfr(peer, &use_ixfr); 18062 } 18063 if (peer == NULL || result != ISC_R_SUCCESS) { 18064 use_ixfr = zone->requestixfr; 18065 } 18066 if (!use_ixfr) { 18067 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18068 ISC_LOG_DEBUG(1), 18069 "IXFR disabled, " 18070 "requesting %sAXFR from %s", 18071 soa_before, master); 18072 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) { 18073 xfrtype = dns_rdatatype_soa; 18074 } else { 18075 xfrtype = dns_rdatatype_axfr; 18076 } 18077 } else { 18078 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18079 ISC_LOG_DEBUG(1), 18080 "requesting IXFR from %s", master); 18081 xfrtype = dns_rdatatype_ixfr; 18082 } 18083 } 18084 18085 /* 18086 * Determine if we should attempt to sign the request with TSIG. 18087 */ 18088 result = ISC_R_NOTFOUND; 18089 18090 /* 18091 * First, look for a tsig key in the master statement, then 18092 * try for a server key. 18093 */ 18094 if ((zone->masterkeynames != NULL) && 18095 (zone->masterkeynames[zone->curmaster] != NULL)) 18096 { 18097 dns_view_t *view = dns_zone_getview(zone); 18098 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 18099 result = dns_view_gettsig(view, keyname, &zone->tsigkey); 18100 } 18101 if (zone->tsigkey == NULL) { 18102 result = dns_view_getpeertsig(zone->view, &masterip, 18103 &zone->tsigkey); 18104 } 18105 18106 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 18107 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, 18108 "could not get TSIG key for zone transfer: %s", 18109 isc_result_totext(result)); 18110 } 18111 18112 if (zone->masterdscps != NULL) { 18113 dscp = zone->masterdscps[zone->curmaster]; 18114 } 18115 18116 LOCK_ZONE(zone); 18117 masteraddr = zone->masteraddr; 18118 sourceaddr = zone->sourceaddr; 18119 switch (isc_sockaddr_pf(&masteraddr)) { 18120 case PF_INET: 18121 if (dscp == -1) { 18122 dscp = zone->xfrsource4dscp; 18123 } 18124 break; 18125 case PF_INET6: 18126 if (dscp == -1) { 18127 dscp = zone->xfrsource6dscp; 18128 } 18129 break; 18130 default: 18131 UNREACHABLE(); 18132 } 18133 UNLOCK_ZONE(zone); 18134 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr)); 18135 result = dns_xfrin_create(zone, xfrtype, &masteraddr, &sourceaddr, dscp, 18136 zone->tsigkey, zone->mctx, 18137 zone->zmgr->timermgr, zone->zmgr->socketmgr, 18138 zone->task, zone_xfrdone, &zone->xfr); 18139 if (result == ISC_R_SUCCESS) { 18140 LOCK_ZONE(zone); 18141 if (xfrtype == dns_rdatatype_axfr) { 18142 if (isc_sockaddr_pf(&masteraddr) == PF_INET) { 18143 inc_stats(zone, dns_zonestatscounter_axfrreqv4); 18144 } else { 18145 inc_stats(zone, dns_zonestatscounter_axfrreqv6); 18146 } 18147 } else if (xfrtype == dns_rdatatype_ixfr) { 18148 if (isc_sockaddr_pf(&masteraddr) == PF_INET) { 18149 inc_stats(zone, dns_zonestatscounter_ixfrreqv4); 18150 } else { 18151 inc_stats(zone, dns_zonestatscounter_ixfrreqv6); 18152 } 18153 } 18154 UNLOCK_ZONE(zone); 18155 } 18156cleanup: 18157 /* 18158 * Any failure in this function is handled like a failed 18159 * zone transfer. This ensures that we get removed from 18160 * zmgr->xfrin_in_progress. 18161 */ 18162 if (result != ISC_R_SUCCESS) { 18163 zone_xfrdone(zone, result); 18164 } 18165 18166 isc_event_free(&event); 18167} 18168 18169/* 18170 * Update forwarding support. 18171 */ 18172 18173static void 18174forward_destroy(dns_forward_t *forward) { 18175 forward->magic = 0; 18176 if (forward->request != NULL) { 18177 dns_request_destroy(&forward->request); 18178 } 18179 if (forward->msgbuf != NULL) { 18180 isc_buffer_free(&forward->msgbuf); 18181 } 18182 if (forward->zone != NULL) { 18183 LOCK(&forward->zone->lock); 18184 if (ISC_LINK_LINKED(forward, link)) { 18185 ISC_LIST_UNLINK(forward->zone->forwards, forward, link); 18186 } 18187 UNLOCK(&forward->zone->lock); 18188 dns_zone_idetach(&forward->zone); 18189 } 18190 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward)); 18191} 18192 18193static isc_result_t 18194sendtomaster(dns_forward_t *forward) { 18195 isc_result_t result; 18196 isc_sockaddr_t src; 18197 isc_dscp_t dscp = -1; 18198 18199 LOCK_ZONE(forward->zone); 18200 18201 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) { 18202 UNLOCK_ZONE(forward->zone); 18203 return (ISC_R_CANCELED); 18204 } 18205 18206 if (forward->which >= forward->zone->masterscnt) { 18207 UNLOCK_ZONE(forward->zone); 18208 return (ISC_R_NOMORE); 18209 } 18210 18211 forward->addr = forward->zone->masters[forward->which]; 18212 /* 18213 * Always use TCP regardless of whether the original update 18214 * used TCP. 18215 * XXX The timeout may but a bit small if we are far down a 18216 * transfer graph and the master has to try several masters. 18217 */ 18218 switch (isc_sockaddr_pf(&forward->addr)) { 18219 case PF_INET: 18220 src = forward->zone->xfrsource4; 18221 dscp = forward->zone->xfrsource4dscp; 18222 break; 18223 case PF_INET6: 18224 src = forward->zone->xfrsource6; 18225 dscp = forward->zone->xfrsource6dscp; 18226 break; 18227 default: 18228 result = ISC_R_NOTIMPLEMENTED; 18229 goto unlock; 18230 } 18231 result = dns_request_createraw(forward->zone->view->requestmgr, 18232 forward->msgbuf, &src, &forward->addr, 18233 dscp, forward->options, 15 /* XXX */, 0, 18234 0, forward->zone->task, forward_callback, 18235 forward, &forward->request); 18236 if (result == ISC_R_SUCCESS) { 18237 if (!ISC_LINK_LINKED(forward, link)) { 18238 ISC_LIST_APPEND(forward->zone->forwards, forward, link); 18239 } 18240 } 18241 18242unlock: 18243 UNLOCK_ZONE(forward->zone); 18244 return (result); 18245} 18246 18247static void 18248forward_callback(isc_task_t *task, isc_event_t *event) { 18249 const char me[] = "forward_callback"; 18250 dns_requestevent_t *revent = (dns_requestevent_t *)event; 18251 dns_message_t *msg = NULL; 18252 char master[ISC_SOCKADDR_FORMATSIZE]; 18253 isc_result_t result; 18254 dns_forward_t *forward; 18255 dns_zone_t *zone; 18256 18257 UNUSED(task); 18258 18259 forward = revent->ev_arg; 18260 INSIST(DNS_FORWARD_VALID(forward)); 18261 zone = forward->zone; 18262 INSIST(DNS_ZONE_VALID(zone)); 18263 18264 ENTER; 18265 18266 isc_sockaddr_format(&forward->addr, master, sizeof(master)); 18267 18268 if (revent->result != ISC_R_SUCCESS) { 18269 dns_zone_log(zone, ISC_LOG_INFO, 18270 "could not forward dynamic update to %s: %s", 18271 master, dns_result_totext(revent->result)); 18272 goto next_master; 18273 } 18274 18275 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 18276 18277 result = dns_request_getresponse(revent->request, msg, 18278 DNS_MESSAGEPARSE_PRESERVEORDER | 18279 DNS_MESSAGEPARSE_CLONEBUFFER); 18280 if (result != ISC_R_SUCCESS) { 18281 goto next_master; 18282 } 18283 18284 /* 18285 * Unexpected opcode. 18286 */ 18287 if (msg->opcode != dns_opcode_update) { 18288 char opcode[128]; 18289 isc_buffer_t rb; 18290 18291 isc_buffer_init(&rb, opcode, sizeof(opcode)); 18292 (void)dns_opcode_totext(msg->opcode, &rb); 18293 18294 dns_zone_log(zone, ISC_LOG_INFO, 18295 "forwarding dynamic update: " 18296 "unexpected opcode (%.*s) from %s", 18297 (int)rb.used, opcode, master); 18298 goto next_master; 18299 } 18300 18301 switch (msg->rcode) { 18302 /* 18303 * Pass these rcodes back to client. 18304 */ 18305 case dns_rcode_noerror: 18306 case dns_rcode_yxdomain: 18307 case dns_rcode_yxrrset: 18308 case dns_rcode_nxrrset: 18309 case dns_rcode_refused: 18310 case dns_rcode_nxdomain: { 18311 char rcode[128]; 18312 isc_buffer_t rb; 18313 18314 isc_buffer_init(&rb, rcode, sizeof(rcode)); 18315 (void)dns_rcode_totext(msg->rcode, &rb); 18316 dns_zone_log(zone, ISC_LOG_INFO, 18317 "forwarded dynamic update: " 18318 "master %s returned: %.*s", 18319 master, (int)rb.used, rcode); 18320 break; 18321 } 18322 18323 /* These should not occur if the primaries/zone are valid. */ 18324 case dns_rcode_notzone: 18325 case dns_rcode_notauth: { 18326 char rcode[128]; 18327 isc_buffer_t rb; 18328 18329 isc_buffer_init(&rb, rcode, sizeof(rcode)); 18330 (void)dns_rcode_totext(msg->rcode, &rb); 18331 dns_zone_log(zone, ISC_LOG_WARNING, 18332 "forwarding dynamic update: " 18333 "unexpected response: master %s returned: %.*s", 18334 master, (int)rb.used, rcode); 18335 goto next_master; 18336 } 18337 18338 /* Try another server for these rcodes. */ 18339 case dns_rcode_formerr: 18340 case dns_rcode_servfail: 18341 case dns_rcode_notimp: 18342 case dns_rcode_badvers: 18343 default: 18344 goto next_master; 18345 } 18346 18347 /* call callback */ 18348 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg); 18349 msg = NULL; 18350 dns_request_destroy(&forward->request); 18351 forward_destroy(forward); 18352 isc_event_free(&event); 18353 return; 18354 18355next_master: 18356 if (msg != NULL) { 18357 dns_message_detach(&msg); 18358 } 18359 isc_event_free(&event); 18360 forward->which++; 18361 dns_request_destroy(&forward->request); 18362 result = sendtomaster(forward); 18363 if (result != ISC_R_SUCCESS) { 18364 /* call callback */ 18365 dns_zone_log(zone, ISC_LOG_DEBUG(3), 18366 "exhausted dynamic update forwarder list"); 18367 (forward->callback)(forward->callback_arg, result, NULL); 18368 forward_destroy(forward); 18369 } 18370} 18371 18372isc_result_t 18373dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg, 18374 dns_updatecallback_t callback, void *callback_arg) { 18375 dns_forward_t *forward; 18376 isc_result_t result; 18377 isc_region_t *mr; 18378 18379 REQUIRE(DNS_ZONE_VALID(zone)); 18380 REQUIRE(msg != NULL); 18381 REQUIRE(callback != NULL); 18382 18383 forward = isc_mem_get(zone->mctx, sizeof(*forward)); 18384 18385 forward->request = NULL; 18386 forward->zone = NULL; 18387 forward->msgbuf = NULL; 18388 forward->which = 0; 18389 forward->mctx = 0; 18390 forward->callback = callback; 18391 forward->callback_arg = callback_arg; 18392 ISC_LINK_INIT(forward, link); 18393 forward->magic = FORWARD_MAGIC; 18394 forward->options = DNS_REQUESTOPT_TCP; 18395 /* 18396 * If we have a SIG(0) signed message we need to preserve the 18397 * query id as that is included in the SIG(0) computation. 18398 */ 18399 if (msg->sig0 != NULL) { 18400 forward->options |= DNS_REQUESTOPT_FIXEDID; 18401 } 18402 18403 mr = dns_message_getrawmessage(msg); 18404 if (mr == NULL) { 18405 result = ISC_R_UNEXPECTEDEND; 18406 goto cleanup; 18407 } 18408 18409 isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length); 18410 result = isc_buffer_copyregion(forward->msgbuf, mr); 18411 if (result != ISC_R_SUCCESS) { 18412 goto cleanup; 18413 } 18414 18415 isc_mem_attach(zone->mctx, &forward->mctx); 18416 dns_zone_iattach(zone, &forward->zone); 18417 result = sendtomaster(forward); 18418 18419cleanup: 18420 if (result != ISC_R_SUCCESS) { 18421 forward_destroy(forward); 18422 } 18423 return (result); 18424} 18425 18426isc_result_t 18427dns_zone_next(dns_zone_t *zone, dns_zone_t **next) { 18428 REQUIRE(DNS_ZONE_VALID(zone)); 18429 REQUIRE(next != NULL && *next == NULL); 18430 18431 *next = ISC_LIST_NEXT(zone, link); 18432 if (*next == NULL) { 18433 return (ISC_R_NOMORE); 18434 } else { 18435 return (ISC_R_SUCCESS); 18436 } 18437} 18438 18439isc_result_t 18440dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) { 18441 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 18442 REQUIRE(first != NULL && *first == NULL); 18443 18444 *first = ISC_LIST_HEAD(zmgr->zones); 18445 if (*first == NULL) { 18446 return (ISC_R_NOMORE); 18447 } else { 18448 return (ISC_R_SUCCESS); 18449 } 18450} 18451 18452/*** 18453 *** Zone manager. 18454 ***/ 18455 18456#define KEYMGMT_OVERCOMMIT 3 18457#define KEYMGMT_BITS_MIN 2U 18458#define KEYMGMT_BITS_MAX 32U 18459 18460/* 18461 * WMM: Static hash functions copied from lib/dns/rbtdb.c. Should be moved to 18462 * lib/isc/hash.c when we refactor the hash table code. 18463 */ 18464#define GOLDEN_RATIO_32 0x61C88647 18465#define HASHSIZE(bits) (UINT64_C(1) << (bits)) 18466 18467static uint32_t 18468hash_index(uint32_t val, uint32_t bits) { 18469 return (val * GOLDEN_RATIO_32 >> (32 - bits)); 18470} 18471 18472static uint32_t 18473hash_bits_grow(uint32_t bits, uint32_t count) { 18474 uint32_t newbits = bits; 18475 while (count >= HASHSIZE(newbits) && newbits < KEYMGMT_BITS_MAX) { 18476 newbits++; 18477 } 18478 return (newbits); 18479} 18480 18481static uint32_t 18482hash_bits_shrink(uint32_t bits, uint32_t count) { 18483 uint32_t newbits = bits; 18484 while (count <= HASHSIZE(newbits) && newbits > KEYMGMT_BITS_MIN) { 18485 newbits--; 18486 } 18487 return (newbits); 18488} 18489 18490static void 18491zonemgr_keymgmt_init(dns_zonemgr_t *zmgr) { 18492 dns_keymgmt_t *mgmt = isc_mem_get(zmgr->mctx, sizeof(*mgmt)); 18493 uint32_t size; 18494 18495 *mgmt = (dns_keymgmt_t){ 18496 .bits = KEYMGMT_BITS_MIN, 18497 }; 18498 isc_mem_attach(zmgr->mctx, &mgmt->mctx); 18499 isc_rwlock_init(&mgmt->lock, 0, 0); 18500 18501 size = HASHSIZE(mgmt->bits); 18502 mgmt->table = isc_mem_get(mgmt->mctx, sizeof(*mgmt->table) * size); 18503 memset(mgmt->table, 0, size * sizeof(mgmt->table[0])); 18504 18505 atomic_init(&mgmt->count, 0); 18506 mgmt->magic = KEYMGMT_MAGIC; 18507 18508 zmgr->keymgmt = mgmt; 18509} 18510 18511static void 18512zonemgr_keymgmt_destroy(dns_zonemgr_t *zmgr) { 18513 dns_keymgmt_t *mgmt = zmgr->keymgmt; 18514 uint32_t size; 18515 18516 REQUIRE(DNS_KEYMGMT_VALID(mgmt)); 18517 18518 size = HASHSIZE(mgmt->bits); 18519 18520 RWLOCK(&mgmt->lock, isc_rwlocktype_write); 18521 INSIST(mgmt->count == 0); 18522 RWUNLOCK(&mgmt->lock, isc_rwlocktype_write); 18523 18524 mgmt->magic = 0; 18525 isc_rwlock_destroy(&mgmt->lock); 18526 isc_mem_put(mgmt->mctx, mgmt->table, size * sizeof(mgmt->table[0])); 18527 isc_mem_putanddetach(&mgmt->mctx, mgmt, sizeof(dns_keymgmt_t)); 18528} 18529 18530static void 18531zonemgr_keymgmt_resize(dns_zonemgr_t *zmgr) { 18532 dns_keyfileio_t **newtable; 18533 dns_keymgmt_t *mgmt = zmgr->keymgmt; 18534 uint32_t bits, newbits, count, size, newsize; 18535 bool grow; 18536 18537 REQUIRE(DNS_KEYMGMT_VALID(mgmt)); 18538 18539 RWLOCK(&mgmt->lock, isc_rwlocktype_read); 18540 count = atomic_load_relaxed(&mgmt->count); 18541 bits = mgmt->bits; 18542 RWUNLOCK(&mgmt->lock, isc_rwlocktype_read); 18543 18544 size = HASHSIZE(bits); 18545 INSIST(size > 0); 18546 18547 if (count >= (size * KEYMGMT_OVERCOMMIT)) { 18548 grow = true; 18549 } else if (count < (size / 2)) { 18550 grow = false; 18551 } else { 18552 /* No need to resize. */ 18553 return; 18554 } 18555 18556 if (grow) { 18557 newbits = hash_bits_grow(bits, count); 18558 } else { 18559 newbits = hash_bits_shrink(bits, count); 18560 } 18561 18562 if (newbits == bits) { 18563 /* 18564 * Bit values may stay the same if maximum or minimum is 18565 * reached. 18566 */ 18567 return; 18568 } 18569 18570 newsize = HASHSIZE(newbits); 18571 INSIST(newsize > 0); 18572 18573 RWLOCK(&mgmt->lock, isc_rwlocktype_write); 18574 18575 newtable = isc_mem_get(mgmt->mctx, sizeof(dns_keyfileio_t *) * newsize); 18576 memset(newtable, 0, sizeof(dns_keyfileio_t *) * newsize); 18577 18578 for (unsigned int i = 0; i < size; i++) { 18579 dns_keyfileio_t *kfio, *next; 18580 for (kfio = mgmt->table[i]; kfio != NULL; kfio = next) { 18581 uint32_t hash = hash_index(kfio->hashval, newbits); 18582 next = kfio->next; 18583 kfio->next = newtable[hash]; 18584 newtable[hash] = kfio; 18585 } 18586 mgmt->table[i] = NULL; 18587 } 18588 18589 isc_mem_put(mgmt->mctx, mgmt->table, sizeof(*mgmt->table) * size); 18590 mgmt->bits = newbits; 18591 mgmt->table = newtable; 18592 18593 RWUNLOCK(&mgmt->lock, isc_rwlocktype_write); 18594} 18595 18596static void 18597zonemgr_keymgmt_add(dns_zonemgr_t *zmgr, dns_zone_t *zone, 18598 dns_keyfileio_t **added) { 18599 dns_keymgmt_t *mgmt = zmgr->keymgmt; 18600 uint32_t hashval, hash; 18601 dns_keyfileio_t *kfio, *next; 18602 18603 REQUIRE(DNS_KEYMGMT_VALID(mgmt)); 18604 REQUIRE(added != NULL && *added == NULL); 18605 18606 RWLOCK(&mgmt->lock, isc_rwlocktype_write); 18607 18608 hashval = dns_name_hash(&zone->origin, false); 18609 hash = hash_index(hashval, mgmt->bits); 18610 18611 for (kfio = mgmt->table[hash]; kfio != NULL; kfio = next) { 18612 next = kfio->next; 18613 if (dns_name_equal(kfio->name, &zone->origin)) { 18614 /* Already in table, increment the counter. */ 18615 isc_refcount_increment(&kfio->references); 18616 break; 18617 } 18618 } 18619 18620 if (kfio == NULL) { 18621 /* No entry found, add it. */ 18622 kfio = isc_mem_get(mgmt->mctx, sizeof(*kfio)); 18623 *kfio = (dns_keyfileio_t){ 18624 .hashval = hashval, 18625 .next = mgmt->table[hash], 18626 .magic = KEYFILEIO_MAGIC, 18627 }; 18628 18629 isc_refcount_init(&kfio->references, 1); 18630 18631 kfio->name = dns_fixedname_initname(&kfio->fname); 18632 dns_name_copynf(&zone->origin, kfio->name); 18633 18634 isc_mutex_init(&kfio->lock); 18635 18636 mgmt->table[hash] = kfio; 18637 18638 atomic_fetch_add_relaxed(&mgmt->count, 1); 18639 } 18640 18641 RWUNLOCK(&mgmt->lock, isc_rwlocktype_write); 18642 18643 *added = kfio; 18644 18645 /* 18646 * Call resize, that function will also check if resize is necessary. 18647 */ 18648 zonemgr_keymgmt_resize(zmgr); 18649} 18650 18651static void 18652zonemgr_keymgmt_delete(dns_zonemgr_t *zmgr, dns_zone_t *zone, 18653 dns_keyfileio_t **deleted) { 18654 dns_keymgmt_t *mgmt = zmgr->keymgmt; 18655 uint32_t hashval, hash; 18656 dns_keyfileio_t *kfio, *prev, *next; 18657 18658 REQUIRE(DNS_KEYMGMT_VALID(mgmt)); 18659 REQUIRE(deleted != NULL && DNS_KEYFILEIO_VALID(*deleted)); 18660 18661 RWLOCK(&mgmt->lock, isc_rwlocktype_write); 18662 18663 hashval = dns_name_hash(&zone->origin, false); 18664 hash = hash_index(hashval, mgmt->bits); 18665 18666 prev = NULL; 18667 for (kfio = mgmt->table[hash]; kfio != NULL; kfio = next) { 18668 next = kfio->next; 18669 if (dns_name_equal(kfio->name, &zone->origin)) { 18670 INSIST(kfio == *deleted); 18671 *deleted = NULL; 18672 18673 if (isc_refcount_decrement(&kfio->references) == 1) { 18674 if (prev == NULL) { 18675 mgmt->table[hash] = kfio->next; 18676 } else { 18677 prev->next = kfio->next; 18678 } 18679 18680 isc_refcount_destroy(&kfio->references); 18681 isc_mutex_destroy(&kfio->lock); 18682 isc_mem_put(mgmt->mctx, kfio, sizeof(*kfio)); 18683 18684 atomic_fetch_sub_relaxed(&mgmt->count, 1); 18685 } 18686 break; 18687 } 18688 18689 prev = kfio; 18690 } 18691 18692 RWUNLOCK(&mgmt->lock, isc_rwlocktype_write); 18693 18694 /* 18695 * Call resize, that function will also check if resize is necessary. 18696 */ 18697 zonemgr_keymgmt_resize(zmgr); 18698} 18699 18700isc_result_t 18701dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, 18702 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, 18703 dns_zonemgr_t **zmgrp) { 18704 dns_zonemgr_t *zmgr; 18705 isc_result_t result; 18706 18707 zmgr = isc_mem_get(mctx, sizeof(*zmgr)); 18708 zmgr->mctx = NULL; 18709 isc_refcount_init(&zmgr->refs, 1); 18710 isc_mem_attach(mctx, &zmgr->mctx); 18711 zmgr->taskmgr = taskmgr; 18712 zmgr->timermgr = timermgr; 18713 zmgr->socketmgr = socketmgr; 18714 zmgr->zonetasks = NULL; 18715 zmgr->loadtasks = NULL; 18716 zmgr->mctxpool = NULL; 18717 zmgr->task = NULL; 18718 zmgr->checkdsrl = NULL; 18719 zmgr->notifyrl = NULL; 18720 zmgr->refreshrl = NULL; 18721 zmgr->startupnotifyrl = NULL; 18722 zmgr->startuprefreshrl = NULL; 18723 ISC_LIST_INIT(zmgr->zones); 18724 ISC_LIST_INIT(zmgr->waiting_for_xfrin); 18725 ISC_LIST_INIT(zmgr->xfrin_in_progress); 18726 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable)); 18727 for (size_t i = 0; i < UNREACH_CACHE_SIZE; i++) { 18728 atomic_init(&zmgr->unreachable[i].expire, 0); 18729 } 18730 isc_rwlock_init(&zmgr->rwlock, 0, 0); 18731 18732 zmgr->transfersin = 10; 18733 zmgr->transfersperns = 2; 18734 18735 /* Unreachable lock. */ 18736 isc_rwlock_init(&zmgr->urlock, 0, 0); 18737 18738 /* Create a single task for queueing of SOA queries. */ 18739 result = isc_task_create(taskmgr, 1, &zmgr->task); 18740 if (result != ISC_R_SUCCESS) { 18741 goto free_urlock; 18742 } 18743 18744 isc_task_setname(zmgr->task, "zmgr", zmgr); 18745 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 18746 &zmgr->checkdsrl); 18747 if (result != ISC_R_SUCCESS) { 18748 goto free_task; 18749 } 18750 18751 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 18752 &zmgr->notifyrl); 18753 if (result != ISC_R_SUCCESS) { 18754 goto free_checkdsrl; 18755 } 18756 18757 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 18758 &zmgr->refreshrl); 18759 if (result != ISC_R_SUCCESS) { 18760 goto free_notifyrl; 18761 } 18762 18763 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 18764 &zmgr->startupnotifyrl); 18765 if (result != ISC_R_SUCCESS) { 18766 goto free_refreshrl; 18767 } 18768 18769 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 18770 &zmgr->startuprefreshrl); 18771 if (result != ISC_R_SUCCESS) { 18772 goto free_startupnotifyrl; 18773 } 18774 18775 /* Key file I/O locks. */ 18776 zonemgr_keymgmt_init(zmgr); 18777 18778 /* Default to 20 refresh queries / notifies / checkds per second. */ 18779 setrl(zmgr->checkdsrl, &zmgr->checkdsrate, 20); 18780 setrl(zmgr->notifyrl, &zmgr->notifyrate, 20); 18781 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20); 18782 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20); 18783 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20); 18784 isc_ratelimiter_setpushpop(zmgr->startupnotifyrl, true); 18785 isc_ratelimiter_setpushpop(zmgr->startuprefreshrl, true); 18786 18787 zmgr->iolimit = 1; 18788 zmgr->ioactive = 0; 18789 ISC_LIST_INIT(zmgr->high); 18790 ISC_LIST_INIT(zmgr->low); 18791 18792 isc_mutex_init(&zmgr->iolock); 18793 18794 zmgr->magic = ZONEMGR_MAGIC; 18795 18796 *zmgrp = zmgr; 18797 return (ISC_R_SUCCESS); 18798 18799#if 0 18800 free_iolock: 18801 isc_mutex_destroy(&zmgr->iolock); 18802#endif /* if 0 */ 18803free_startupnotifyrl: 18804 isc_ratelimiter_detach(&zmgr->startupnotifyrl); 18805free_refreshrl: 18806 isc_ratelimiter_detach(&zmgr->refreshrl); 18807free_notifyrl: 18808 isc_ratelimiter_detach(&zmgr->notifyrl); 18809free_checkdsrl: 18810 isc_ratelimiter_detach(&zmgr->checkdsrl); 18811free_task: 18812 isc_task_detach(&zmgr->task); 18813free_urlock: 18814 isc_rwlock_destroy(&zmgr->urlock); 18815 isc_rwlock_destroy(&zmgr->rwlock); 18816 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); 18817 isc_mem_detach(&mctx); 18818 return (result); 18819} 18820 18821isc_result_t 18822dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) { 18823 isc_result_t result; 18824 isc_mem_t *mctx = NULL; 18825 dns_zone_t *zone = NULL; 18826 void *item; 18827 18828 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 18829 REQUIRE(zonep != NULL && *zonep == NULL); 18830 18831 if (zmgr->mctxpool == NULL) { 18832 return (ISC_R_FAILURE); 18833 } 18834 18835 item = isc_pool_get(zmgr->mctxpool); 18836 if (item == NULL) { 18837 return (ISC_R_FAILURE); 18838 } 18839 18840 isc_mem_attach((isc_mem_t *)item, &mctx); 18841 result = dns_zone_create(&zone, mctx); 18842 isc_mem_detach(&mctx); 18843 18844 if (result == ISC_R_SUCCESS) { 18845 *zonep = zone; 18846 } 18847 18848 return (result); 18849} 18850 18851isc_result_t 18852dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 18853 isc_result_t result; 18854 18855 REQUIRE(DNS_ZONE_VALID(zone)); 18856 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 18857 18858 if (zmgr->zonetasks == NULL) { 18859 return (ISC_R_FAILURE); 18860 } 18861 18862 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18863 LOCK_ZONE(zone); 18864 REQUIRE(zone->task == NULL); 18865 REQUIRE(zone->timer == NULL); 18866 REQUIRE(zone->zmgr == NULL); 18867 18868 isc_taskpool_gettask(zmgr->zonetasks, &zone->task); 18869 isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask); 18870 18871 /* 18872 * Set the task name. The tag will arbitrarily point to one 18873 * of the zones sharing the task (in practice, the one 18874 * to be managed last). 18875 */ 18876 isc_task_setname(zone->task, "zone", zone); 18877 isc_task_setname(zone->loadtask, "loadzone", zone); 18878 18879 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL, 18880 NULL, zone->task, zone_timer, zone, 18881 &zone->timer); 18882 18883 if (result != ISC_R_SUCCESS) { 18884 goto cleanup_tasks; 18885 } 18886 18887 /* 18888 * The timer "holds" a iref. 18889 */ 18890 isc_refcount_increment0(&zone->irefs); 18891 18892 zonemgr_keymgmt_add(zmgr, zone, &zone->kfio); 18893 INSIST(zone->kfio != NULL); 18894 18895 ISC_LIST_APPEND(zmgr->zones, zone, link); 18896 zone->zmgr = zmgr; 18897 isc_refcount_increment(&zmgr->refs); 18898 18899 goto unlock; 18900 18901cleanup_tasks: 18902 isc_task_detach(&zone->loadtask); 18903 isc_task_detach(&zone->task); 18904 18905unlock: 18906 UNLOCK_ZONE(zone); 18907 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18908 return (result); 18909} 18910 18911void 18912dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 18913 REQUIRE(DNS_ZONE_VALID(zone)); 18914 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 18915 REQUIRE(zone->zmgr == zmgr); 18916 18917 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18918 LOCK_ZONE(zone); 18919 18920 ISC_LIST_UNLINK(zmgr->zones, zone, link); 18921 18922 if (zone->kfio != NULL) { 18923 zonemgr_keymgmt_delete(zmgr, zone, &zone->kfio); 18924 ENSURE(zone->kfio == NULL); 18925 } 18926 18927 /* Detach below, outside of the write lock. */ 18928 zone->zmgr = NULL; 18929 18930 UNLOCK_ZONE(zone); 18931 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18932 18933 dns_zonemgr_detach(&zmgr); 18934} 18935 18936void 18937dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) { 18938 REQUIRE(DNS_ZONEMGR_VALID(source)); 18939 REQUIRE(target != NULL && *target == NULL); 18940 18941 isc_refcount_increment(&source->refs); 18942 18943 *target = source; 18944} 18945 18946void 18947dns_zonemgr_detach(dns_zonemgr_t **zmgrp) { 18948 dns_zonemgr_t *zmgr; 18949 18950 REQUIRE(zmgrp != NULL); 18951 zmgr = *zmgrp; 18952 *zmgrp = NULL; 18953 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 18954 18955 if (isc_refcount_decrement(&zmgr->refs) == 1) { 18956 zonemgr_free(zmgr); 18957 } 18958} 18959 18960isc_result_t 18961dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) { 18962 dns_zone_t *p; 18963 18964 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 18965 18966 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 18967 for (p = ISC_LIST_HEAD(zmgr->zones); p != NULL; 18968 p = ISC_LIST_NEXT(p, link)) 18969 { 18970 dns_zone_maintenance(p); 18971 } 18972 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 18973 18974 /* 18975 * Recent configuration changes may have increased the 18976 * amount of available transfers quota. Make sure any 18977 * transfers currently blocked on quota get started if 18978 * possible. 18979 */ 18980 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18981 zmgr_resume_xfrs(zmgr, true); 18982 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18983 return (ISC_R_SUCCESS); 18984} 18985 18986void 18987dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) { 18988 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 18989 18990 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18991 zmgr_resume_xfrs(zmgr, true); 18992 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18993} 18994 18995void 18996dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) { 18997 dns_zone_t *zone; 18998 18999 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19000 19001 isc_ratelimiter_shutdown(zmgr->checkdsrl); 19002 isc_ratelimiter_shutdown(zmgr->notifyrl); 19003 isc_ratelimiter_shutdown(zmgr->refreshrl); 19004 isc_ratelimiter_shutdown(zmgr->startupnotifyrl); 19005 isc_ratelimiter_shutdown(zmgr->startuprefreshrl); 19006 19007 if (zmgr->task != NULL) { 19008 isc_task_destroy(&zmgr->task); 19009 } 19010 if (zmgr->zonetasks != NULL) { 19011 isc_taskpool_destroy(&zmgr->zonetasks); 19012 } 19013 if (zmgr->loadtasks != NULL) { 19014 isc_taskpool_destroy(&zmgr->loadtasks); 19015 } 19016 if (zmgr->mctxpool != NULL) { 19017 isc_pool_destroy(&zmgr->mctxpool); 19018 } 19019 19020 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19021 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 19022 zone = ISC_LIST_NEXT(zone, link)) 19023 { 19024 LOCK_ZONE(zone); 19025 forward_cancel(zone); 19026 UNLOCK_ZONE(zone); 19027 } 19028 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19029} 19030 19031static isc_result_t 19032mctxinit(void **target, void *arg) { 19033 isc_mem_t *mctx = NULL; 19034 19035 UNUSED(arg); 19036 19037 REQUIRE(target != NULL && *target == NULL); 19038 19039 isc_mem_create(&mctx); 19040 isc_mem_setname(mctx, "zonemgr-pool", NULL); 19041 19042 *target = mctx; 19043 return (ISC_R_SUCCESS); 19044} 19045 19046static void 19047mctxfree(void **target) { 19048 isc_mem_t *mctx = *(isc_mem_t **)target; 19049 isc_mem_detach(&mctx); 19050 *target = NULL; 19051} 19052 19053#define ZONES_PER_TASK 100 19054#define ZONES_PER_MCTX 1000 19055 19056isc_result_t 19057dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) { 19058 isc_result_t result; 19059 int ntasks = num_zones / ZONES_PER_TASK; 19060 int nmctx = num_zones / ZONES_PER_MCTX; 19061 isc_taskpool_t *pool = NULL; 19062 isc_pool_t *mctxpool = NULL; 19063 19064 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19065 19066 /* 19067 * For anything fewer than 1000 zones we use 10 tasks in 19068 * the task pools. More than that, and we'll scale at one 19069 * task per 100 zones. Similarly, for anything smaller than 19070 * 2000 zones we use 2 memory contexts, then scale at 1:1000. 19071 */ 19072 if (ntasks < 10) { 19073 ntasks = 10; 19074 } 19075 if (nmctx < 2) { 19076 nmctx = 2; 19077 } 19078 19079 /* Create or resize the zone task pools. */ 19080 if (zmgr->zonetasks == NULL) { 19081 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks, 19082 2, false, &pool); 19083 } else { 19084 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, false, 19085 &pool); 19086 } 19087 19088 if (result == ISC_R_SUCCESS) { 19089 zmgr->zonetasks = pool; 19090 } 19091 19092 pool = NULL; 19093 if (zmgr->loadtasks == NULL) { 19094 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks, 19095 UINT_MAX, true, &pool); 19096 } else { 19097 result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, true, 19098 &pool); 19099 } 19100 19101 if (result == ISC_R_SUCCESS) { 19102 zmgr->loadtasks = pool; 19103 } 19104 19105 /* Create or resize the zone memory context pool. */ 19106 if (zmgr->mctxpool == NULL) { 19107 result = isc_pool_create(zmgr->mctx, nmctx, mctxfree, mctxinit, 19108 NULL, &mctxpool); 19109 } else { 19110 result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool); 19111 } 19112 19113 if (result == ISC_R_SUCCESS) { 19114 zmgr->mctxpool = mctxpool; 19115 } 19116 19117 return (result); 19118} 19119 19120static void 19121zonemgr_free(dns_zonemgr_t *zmgr) { 19122 isc_mem_t *mctx; 19123 19124 INSIST(ISC_LIST_EMPTY(zmgr->zones)); 19125 19126 zmgr->magic = 0; 19127 19128 isc_refcount_destroy(&zmgr->refs); 19129 isc_mutex_destroy(&zmgr->iolock); 19130 isc_ratelimiter_detach(&zmgr->checkdsrl); 19131 isc_ratelimiter_detach(&zmgr->notifyrl); 19132 isc_ratelimiter_detach(&zmgr->refreshrl); 19133 isc_ratelimiter_detach(&zmgr->startupnotifyrl); 19134 isc_ratelimiter_detach(&zmgr->startuprefreshrl); 19135 19136 isc_rwlock_destroy(&zmgr->urlock); 19137 isc_rwlock_destroy(&zmgr->rwlock); 19138 19139 zonemgr_keymgmt_destroy(zmgr); 19140 19141 mctx = zmgr->mctx; 19142 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); 19143 isc_mem_detach(&mctx); 19144} 19145 19146void 19147dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value) { 19148 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19149 19150 zmgr->transfersin = value; 19151} 19152 19153uint32_t 19154dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) { 19155 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19156 19157 return (zmgr->transfersin); 19158} 19159 19160void 19161dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, uint32_t value) { 19162 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19163 19164 zmgr->transfersperns = value; 19165} 19166 19167uint32_t 19168dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) { 19169 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19170 19171 return (zmgr->transfersperns); 19172} 19173 19174isc_taskmgr_t * 19175dns_zonemgr_gettaskmgr(dns_zonemgr_t *zmgr) { 19176 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19177 19178 return (zmgr->taskmgr); 19179} 19180 19181/* 19182 * Try to start a new incoming zone transfer to fill a quota 19183 * slot that was just vacated. 19184 * 19185 * Requires: 19186 * The zone manager is locked by the caller. 19187 */ 19188static void 19189zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi) { 19190 dns_zone_t *zone; 19191 dns_zone_t *next; 19192 19193 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); zone != NULL; 19194 zone = next) 19195 { 19196 isc_result_t result; 19197 next = ISC_LIST_NEXT(zone, statelink); 19198 result = zmgr_start_xfrin_ifquota(zmgr, zone); 19199 if (result == ISC_R_SUCCESS) { 19200 if (multi) { 19201 continue; 19202 } 19203 /* 19204 * We successfully filled the slot. We're done. 19205 */ 19206 break; 19207 } else if (result == ISC_R_QUOTA) { 19208 /* 19209 * Not enough quota. This is probably the per-server 19210 * quota, because we usually get called when a unit of 19211 * global quota has just been freed. Try the next 19212 * zone, it may succeed if it uses another master. 19213 */ 19214 continue; 19215 } else { 19216 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 19217 ISC_LOG_DEBUG(1), 19218 "starting zone transfer: %s", 19219 isc_result_totext(result)); 19220 break; 19221 } 19222 } 19223} 19224 19225/* 19226 * Try to start an incoming zone transfer for 'zone', quota permitting. 19227 * 19228 * Requires: 19229 * The zone manager is locked by the caller. 19230 * 19231 * Returns: 19232 * ISC_R_SUCCESS There was enough quota and we attempted to 19233 * start a transfer. zone_xfrdone() has been or will 19234 * be called. 19235 * ISC_R_QUOTA Not enough quota. 19236 * Others Failure. 19237 */ 19238static isc_result_t 19239zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 19240 dns_peer_t *peer = NULL; 19241 isc_netaddr_t masterip; 19242 uint32_t nxfrsin, nxfrsperns; 19243 dns_zone_t *x; 19244 uint32_t maxtransfersin, maxtransfersperns; 19245 isc_event_t *e; 19246 19247 /* 19248 * If we are exiting just pretend we got quota so the zone will 19249 * be cleaned up in the zone's task context. 19250 */ 19251 LOCK_ZONE(zone); 19252 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 19253 UNLOCK_ZONE(zone); 19254 goto gotquota; 19255 } 19256 19257 /* 19258 * Find any configured information about the server we'd 19259 * like to transfer this zone from. 19260 */ 19261 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 19262 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer); 19263 UNLOCK_ZONE(zone); 19264 19265 /* 19266 * Determine the total maximum number of simultaneous 19267 * transfers allowed, and the maximum for this specific 19268 * master. 19269 */ 19270 maxtransfersin = zmgr->transfersin; 19271 maxtransfersperns = zmgr->transfersperns; 19272 if (peer != NULL) { 19273 (void)dns_peer_gettransfers(peer, &maxtransfersperns); 19274 } 19275 19276 /* 19277 * Count the total number of transfers that are in progress, 19278 * and the number of transfers in progress from this master. 19279 * We linearly scan a list of all transfers; if this turns 19280 * out to be too slow, we could hash on the master address. 19281 */ 19282 nxfrsin = nxfrsperns = 0; 19283 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress); x != NULL; 19284 x = ISC_LIST_NEXT(x, statelink)) 19285 { 19286 isc_netaddr_t xip; 19287 19288 LOCK_ZONE(x); 19289 isc_netaddr_fromsockaddr(&xip, &x->masteraddr); 19290 UNLOCK_ZONE(x); 19291 19292 nxfrsin++; 19293 if (isc_netaddr_equal(&xip, &masterip)) { 19294 nxfrsperns++; 19295 } 19296 } 19297 19298 /* Enforce quota. */ 19299 if (nxfrsin >= maxtransfersin) { 19300 return (ISC_R_QUOTA); 19301 } 19302 19303 if (nxfrsperns >= maxtransfersperns) { 19304 return (ISC_R_QUOTA); 19305 } 19306 19307gotquota: 19308 /* 19309 * We have sufficient quota. Move the zone to the "xfrin_in_progress" 19310 * list and send it an event to let it start the actual transfer in the 19311 * context of its own task. 19312 */ 19313 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN, 19314 got_transfer_quota, zone, sizeof(isc_event_t)); 19315 19316 LOCK_ZONE(zone); 19317 INSIST(zone->statelist == &zmgr->waiting_for_xfrin); 19318 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink); 19319 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink); 19320 zone->statelist = &zmgr->xfrin_in_progress; 19321 isc_task_send(zone->task, &e); 19322 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 19323 "Transfer started."); 19324 UNLOCK_ZONE(zone); 19325 19326 return (ISC_R_SUCCESS); 19327} 19328 19329void 19330dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, uint32_t iolimit) { 19331 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19332 REQUIRE(iolimit > 0); 19333 19334 zmgr->iolimit = iolimit; 19335} 19336 19337uint32_t 19338dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) { 19339 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19340 19341 return (zmgr->iolimit); 19342} 19343 19344/* 19345 * Get permission to request a file handle from the OS. 19346 * An event will be sent to action when one is available. 19347 * There are two queues available (high and low), the high 19348 * queue will be serviced before the low one. 19349 * 19350 * zonemgr_putio() must be called after the event is delivered to 19351 * 'action'. 19352 */ 19353 19354static isc_result_t 19355zonemgr_getio(dns_zonemgr_t *zmgr, bool high, isc_task_t *task, 19356 isc_taskaction_t action, void *arg, dns_io_t **iop) { 19357 dns_io_t *io; 19358 bool queue; 19359 19360 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19361 REQUIRE(iop != NULL && *iop == NULL); 19362 19363 io = isc_mem_get(zmgr->mctx, sizeof(*io)); 19364 19365 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY, 19366 action, arg, sizeof(*io->event)); 19367 19368 io->zmgr = zmgr; 19369 io->high = high; 19370 io->task = NULL; 19371 isc_task_attach(task, &io->task); 19372 ISC_LINK_INIT(io, link); 19373 io->magic = IO_MAGIC; 19374 19375 LOCK(&zmgr->iolock); 19376 zmgr->ioactive++; 19377 queue = (zmgr->ioactive > zmgr->iolimit); 19378 if (queue) { 19379 if (io->high) { 19380 ISC_LIST_APPEND(zmgr->high, io, link); 19381 } else { 19382 ISC_LIST_APPEND(zmgr->low, io, link); 19383 } 19384 } 19385 UNLOCK(&zmgr->iolock); 19386 *iop = io; 19387 19388 if (!queue) { 19389 isc_task_send(io->task, &io->event); 19390 } 19391 return (ISC_R_SUCCESS); 19392} 19393 19394static void 19395zonemgr_putio(dns_io_t **iop) { 19396 dns_io_t *io; 19397 dns_io_t *next; 19398 dns_zonemgr_t *zmgr; 19399 19400 REQUIRE(iop != NULL); 19401 io = *iop; 19402 *iop = NULL; 19403 REQUIRE(DNS_IO_VALID(io)); 19404 19405 INSIST(!ISC_LINK_LINKED(io, link)); 19406 INSIST(io->event == NULL); 19407 19408 zmgr = io->zmgr; 19409 isc_task_detach(&io->task); 19410 io->magic = 0; 19411 isc_mem_put(zmgr->mctx, io, sizeof(*io)); 19412 19413 LOCK(&zmgr->iolock); 19414 INSIST(zmgr->ioactive > 0); 19415 zmgr->ioactive--; 19416 next = HEAD(zmgr->high); 19417 if (next == NULL) { 19418 next = HEAD(zmgr->low); 19419 } 19420 if (next != NULL) { 19421 if (next->high) { 19422 ISC_LIST_UNLINK(zmgr->high, next, link); 19423 } else { 19424 ISC_LIST_UNLINK(zmgr->low, next, link); 19425 } 19426 INSIST(next->event != NULL); 19427 } 19428 UNLOCK(&zmgr->iolock); 19429 if (next != NULL) { 19430 isc_task_send(next->task, &next->event); 19431 } 19432} 19433 19434static void 19435zonemgr_cancelio(dns_io_t *io) { 19436 bool send_event = false; 19437 19438 REQUIRE(DNS_IO_VALID(io)); 19439 19440 /* 19441 * If we are queued to be run then dequeue. 19442 */ 19443 LOCK(&io->zmgr->iolock); 19444 if (ISC_LINK_LINKED(io, link)) { 19445 if (io->high) { 19446 ISC_LIST_UNLINK(io->zmgr->high, io, link); 19447 } else { 19448 ISC_LIST_UNLINK(io->zmgr->low, io, link); 19449 } 19450 19451 send_event = true; 19452 INSIST(io->event != NULL); 19453 } 19454 UNLOCK(&io->zmgr->iolock); 19455 if (send_event) { 19456 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED; 19457 isc_task_send(io->task, &io->event); 19458 } 19459} 19460 19461static void 19462zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) { 19463 char *buf; 19464 int buflen; 19465 isc_result_t result; 19466 19467 buflen = strlen(path) + strlen(templat) + 2; 19468 19469 buf = isc_mem_get(zone->mctx, buflen); 19470 19471 result = isc_file_template(path, templat, buf, buflen); 19472 if (result != ISC_R_SUCCESS) { 19473 goto cleanup; 19474 } 19475 19476 result = isc_file_renameunique(path, buf); 19477 if (result != ISC_R_SUCCESS) { 19478 goto cleanup; 19479 } 19480 19481 dns_zone_log(zone, ISC_LOG_WARNING, 19482 "unable to load from '%s'; " 19483 "renaming file to '%s' for failure analysis and " 19484 "retransferring.", 19485 path, buf); 19486 19487cleanup: 19488 isc_mem_put(zone->mctx, buf, buflen); 19489} 19490 19491static void 19492setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) { 19493 isc_interval_t interval; 19494 uint32_t s, ns; 19495 uint32_t pertic; 19496 isc_result_t result; 19497 19498 if (value == 0) { 19499 value = 1; 19500 } 19501 19502 if (value == 1) { 19503 s = 1; 19504 ns = 0; 19505 pertic = 1; 19506 } else if (value <= 10) { 19507 s = 0; 19508 ns = 1000000000 / value; 19509 pertic = 1; 19510 } else { 19511 s = 0; 19512 ns = (1000000000 / value) * 10; 19513 pertic = 10; 19514 } 19515 19516 isc_interval_set(&interval, s, ns); 19517 19518 result = isc_ratelimiter_setinterval(rl, &interval); 19519 RUNTIME_CHECK(result == ISC_R_SUCCESS); 19520 isc_ratelimiter_setpertic(rl, pertic); 19521 19522 *rate = value; 19523} 19524 19525void 19526dns_zonemgr_setcheckdsrate(dns_zonemgr_t *zmgr, unsigned int value) { 19527 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19528 19529 setrl(zmgr->checkdsrl, &zmgr->checkdsrate, value); 19530} 19531 19532void 19533dns_zonemgr_setnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) { 19534 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19535 19536 setrl(zmgr->notifyrl, &zmgr->notifyrate, value); 19537} 19538 19539void 19540dns_zonemgr_setstartupnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) { 19541 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19542 19543 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value); 19544} 19545 19546void 19547dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) { 19548 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19549 19550 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value); 19551 /* XXXMPA separate out once we have the code to support this. */ 19552 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value); 19553} 19554 19555unsigned int 19556dns_zonemgr_getnotifyrate(dns_zonemgr_t *zmgr) { 19557 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19558 19559 return (zmgr->notifyrate); 19560} 19561 19562unsigned int 19563dns_zonemgr_getstartupnotifyrate(dns_zonemgr_t *zmgr) { 19564 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19565 19566 return (zmgr->startupnotifyrate); 19567} 19568 19569unsigned int 19570dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) { 19571 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19572 19573 return (zmgr->serialqueryrate); 19574} 19575 19576bool 19577dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 19578 isc_sockaddr_t *local, isc_time_t *now) { 19579 unsigned int i; 19580 uint32_t seconds = isc_time_seconds(now); 19581 uint32_t count = 0; 19582 19583 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19584 19585 RWLOCK(&zmgr->urlock, isc_rwlocktype_read); 19586 for (i = 0; i < UNREACH_CACHE_SIZE; i++) { 19587 if (atomic_load(&zmgr->unreachable[i].expire) >= seconds && 19588 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 19589 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 19590 { 19591 atomic_store_relaxed(&zmgr->unreachable[i].last, 19592 seconds); 19593 count = zmgr->unreachable[i].count; 19594 break; 19595 } 19596 } 19597 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read); 19598 return (i < UNREACH_CACHE_SIZE && count > 1U); 19599} 19600 19601void 19602dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 19603 isc_sockaddr_t *local) { 19604 unsigned int i; 19605 char master[ISC_SOCKADDR_FORMATSIZE]; 19606 char source[ISC_SOCKADDR_FORMATSIZE]; 19607 19608 isc_sockaddr_format(remote, master, sizeof(master)); 19609 isc_sockaddr_format(local, source, sizeof(source)); 19610 19611 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19612 19613 RWLOCK(&zmgr->urlock, isc_rwlocktype_read); 19614 for (i = 0; i < UNREACH_CACHE_SIZE; i++) { 19615 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 19616 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 19617 { 19618 atomic_store_relaxed(&zmgr->unreachable[i].expire, 0); 19619 break; 19620 } 19621 } 19622 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read); 19623} 19624 19625void 19626dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 19627 isc_sockaddr_t *local, isc_time_t *now) { 19628 uint32_t seconds = isc_time_seconds(now); 19629 uint32_t expire = 0, last = seconds; 19630 unsigned int slot = UNREACH_CACHE_SIZE, oldest = 0; 19631 bool update_entry = true; 19632 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19633 19634 RWLOCK(&zmgr->urlock, isc_rwlocktype_write); 19635 for (unsigned int i = 0; i < UNREACH_CACHE_SIZE; i++) { 19636 /* Existing entry? */ 19637 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 19638 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 19639 { 19640 update_entry = false; 19641 slot = i; 19642 expire = atomic_load_relaxed( 19643 &zmgr->unreachable[i].expire); 19644 break; 19645 } 19646 /* Pick first empty slot? */ 19647 if (atomic_load_relaxed(&zmgr->unreachable[i].expire) < seconds) 19648 { 19649 slot = i; 19650 break; 19651 } 19652 /* The worst case, least recently used slot? */ 19653 if (atomic_load_relaxed(&zmgr->unreachable[i].last) < last) { 19654 last = atomic_load_relaxed(&zmgr->unreachable[i].last); 19655 oldest = i; 19656 } 19657 } 19658 19659 /* We haven't found any existing or free slots, use the oldest */ 19660 if (slot == UNREACH_CACHE_SIZE) { 19661 slot = oldest; 19662 } 19663 19664 if (expire < seconds) { 19665 /* Expired or new entry, reset count to 1 */ 19666 zmgr->unreachable[slot].count = 1; 19667 } else { 19668 zmgr->unreachable[slot].count++; 19669 } 19670 atomic_store_relaxed(&zmgr->unreachable[slot].expire, 19671 seconds + UNREACH_HOLD_TIME); 19672 atomic_store_relaxed(&zmgr->unreachable[slot].last, seconds); 19673 if (update_entry) { 19674 zmgr->unreachable[slot].remote = *remote; 19675 zmgr->unreachable[slot].local = *local; 19676 } 19677 19678 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write); 19679} 19680 19681void 19682dns_zone_forcereload(dns_zone_t *zone) { 19683 REQUIRE(DNS_ZONE_VALID(zone)); 19684 19685 if (zone->type == dns_zone_primary || 19686 (zone->type == dns_zone_redirect && zone->masters == NULL)) 19687 { 19688 return; 19689 } 19690 19691 LOCK_ZONE(zone); 19692 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER); 19693 UNLOCK_ZONE(zone); 19694 dns_zone_refresh(zone); 19695} 19696 19697bool 19698dns_zone_isforced(dns_zone_t *zone) { 19699 REQUIRE(DNS_ZONE_VALID(zone)); 19700 19701 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)); 19702} 19703 19704isc_result_t 19705dns_zone_setstatistics(dns_zone_t *zone, bool on) { 19706 /* 19707 * This function is obsoleted. 19708 */ 19709 UNUSED(zone); 19710 UNUSED(on); 19711 return (ISC_R_NOTIMPLEMENTED); 19712} 19713 19714uint64_t * 19715dns_zone_getstatscounters(dns_zone_t *zone) { 19716 /* 19717 * This function is obsoleted. 19718 */ 19719 UNUSED(zone); 19720 return (NULL); 19721} 19722 19723void 19724dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) { 19725 REQUIRE(DNS_ZONE_VALID(zone)); 19726 REQUIRE(zone->stats == NULL); 19727 19728 LOCK_ZONE(zone); 19729 zone->stats = NULL; 19730 isc_stats_attach(stats, &zone->stats); 19731 UNLOCK_ZONE(zone); 19732} 19733 19734void 19735dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) { 19736 REQUIRE(DNS_ZONE_VALID(zone)); 19737 19738 LOCK_ZONE(zone); 19739 if (zone->requeststats_on && stats == NULL) { 19740 zone->requeststats_on = false; 19741 } else if (!zone->requeststats_on && stats != NULL) { 19742 if (zone->requeststats == NULL) { 19743 isc_stats_attach(stats, &zone->requeststats); 19744 } 19745 zone->requeststats_on = true; 19746 } 19747 UNLOCK_ZONE(zone); 19748} 19749 19750void 19751dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) { 19752 REQUIRE(DNS_ZONE_VALID(zone)); 19753 19754 LOCK_ZONE(zone); 19755 if (zone->requeststats_on && stats != NULL) { 19756 if (zone->rcvquerystats == NULL) { 19757 dns_stats_attach(stats, &zone->rcvquerystats); 19758 zone->requeststats_on = true; 19759 } 19760 } 19761 UNLOCK_ZONE(zone); 19762} 19763 19764void 19765dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats) { 19766 REQUIRE(DNS_ZONE_VALID(zone)); 19767 19768 LOCK_ZONE(zone); 19769 if (stats != NULL && zone->dnssecsignstats == NULL) { 19770 dns_stats_attach(stats, &zone->dnssecsignstats); 19771 } 19772 UNLOCK_ZONE(zone); 19773} 19774 19775dns_stats_t * 19776dns_zone_getdnssecsignstats(dns_zone_t *zone) { 19777 REQUIRE(DNS_ZONE_VALID(zone)); 19778 19779 return (zone->dnssecsignstats); 19780} 19781 19782isc_stats_t * 19783dns_zone_getrequeststats(dns_zone_t *zone) { 19784 /* 19785 * We don't lock zone for efficiency reason. This is not catastrophic 19786 * because requeststats must always be valid when requeststats_on is 19787 * true. 19788 * Some counters may be incremented while requeststats_on is becoming 19789 * false, or some cannot be incremented just after the statistics are 19790 * installed, but it shouldn't matter much in practice. 19791 */ 19792 if (zone->requeststats_on) { 19793 return (zone->requeststats); 19794 } else { 19795 return (NULL); 19796 } 19797} 19798 19799/* 19800 * Return the received query stats bucket 19801 * see note from dns_zone_getrequeststats() 19802 */ 19803dns_stats_t * 19804dns_zone_getrcvquerystats(dns_zone_t *zone) { 19805 if (zone->requeststats_on) { 19806 return (zone->rcvquerystats); 19807 } else { 19808 return (NULL); 19809 } 19810} 19811 19812void 19813dns_zone_dialup(dns_zone_t *zone) { 19814 REQUIRE(DNS_ZONE_VALID(zone)); 19815 19816 zone_debuglog(zone, "dns_zone_dialup", 3, "notify = %d, refresh = %d", 19817 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY), 19818 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)); 19819 19820 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) { 19821 dns_zone_notify(zone); 19822 } 19823 if (zone->type != dns_zone_primary && zone->masters != NULL && 19824 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 19825 { 19826 dns_zone_refresh(zone); 19827 } 19828} 19829 19830void 19831dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) { 19832 REQUIRE(DNS_ZONE_VALID(zone)); 19833 19834 LOCK_ZONE(zone); 19835 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY | 19836 DNS_ZONEFLG_DIALREFRESH | 19837 DNS_ZONEFLG_NOREFRESH); 19838 switch (dialup) { 19839 case dns_dialuptype_no: 19840 break; 19841 case dns_dialuptype_yes: 19842 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY | 19843 DNS_ZONEFLG_DIALREFRESH | 19844 DNS_ZONEFLG_NOREFRESH)); 19845 break; 19846 case dns_dialuptype_notify: 19847 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 19848 break; 19849 case dns_dialuptype_notifypassive: 19850 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 19851 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 19852 break; 19853 case dns_dialuptype_refresh: 19854 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH); 19855 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 19856 break; 19857 case dns_dialuptype_passive: 19858 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 19859 break; 19860 default: 19861 UNREACHABLE(); 19862 } 19863 UNLOCK_ZONE(zone); 19864} 19865 19866isc_result_t 19867dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) { 19868 isc_result_t result = ISC_R_SUCCESS; 19869 19870 REQUIRE(DNS_ZONE_VALID(zone)); 19871 19872 LOCK_ZONE(zone); 19873 result = dns_zone_setstring(zone, &zone->keydirectory, directory); 19874 UNLOCK_ZONE(zone); 19875 19876 return (result); 19877} 19878 19879const char * 19880dns_zone_getkeydirectory(dns_zone_t *zone) { 19881 REQUIRE(DNS_ZONE_VALID(zone)); 19882 19883 return (zone->keydirectory); 19884} 19885 19886unsigned int 19887dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) { 19888 dns_zone_t *zone; 19889 unsigned int count = 0; 19890 19891 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19892 19893 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19894 switch (state) { 19895 case DNS_ZONESTATE_XFERRUNNING: 19896 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress); 19897 zone != NULL; zone = ISC_LIST_NEXT(zone, statelink)) 19898 { 19899 count++; 19900 } 19901 break; 19902 case DNS_ZONESTATE_XFERDEFERRED: 19903 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); 19904 zone != NULL; zone = ISC_LIST_NEXT(zone, statelink)) 19905 { 19906 count++; 19907 } 19908 break; 19909 case DNS_ZONESTATE_SOAQUERY: 19910 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 19911 zone = ISC_LIST_NEXT(zone, link)) 19912 { 19913 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { 19914 count++; 19915 } 19916 } 19917 break; 19918 case DNS_ZONESTATE_ANY: 19919 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 19920 zone = ISC_LIST_NEXT(zone, link)) 19921 { 19922 dns_view_t *view = zone->view; 19923 if (view != NULL && strcmp(view->name, "_bind") == 0) { 19924 continue; 19925 } 19926 count++; 19927 } 19928 break; 19929 case DNS_ZONESTATE_AUTOMATIC: 19930 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 19931 zone = ISC_LIST_NEXT(zone, link)) 19932 { 19933 dns_view_t *view = zone->view; 19934 if (view != NULL && strcmp(view->name, "_bind") == 0) { 19935 continue; 19936 } 19937 if (zone->automatic) { 19938 count++; 19939 } 19940 } 19941 break; 19942 default: 19943 UNREACHABLE(); 19944 } 19945 19946 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19947 19948 return (count); 19949} 19950 19951void 19952dns_zone_lock_keyfiles(dns_zone_t *zone) { 19953 REQUIRE(DNS_ZONE_VALID(zone)); 19954 19955 if (zone->kasp == NULL) { 19956 /* No need to lock, nothing is writing key files. */ 19957 return; 19958 } 19959 19960 REQUIRE(DNS_KEYFILEIO_VALID(zone->kfio)); 19961 isc_mutex_lock(&zone->kfio->lock); 19962} 19963 19964void 19965dns_zone_unlock_keyfiles(dns_zone_t *zone) { 19966 REQUIRE(DNS_ZONE_VALID(zone)); 19967 19968 if (zone->kasp == NULL) { 19969 /* No need to lock, nothing is writing key files. */ 19970 return; 19971 } 19972 19973 REQUIRE(DNS_KEYFILEIO_VALID(zone->kfio)); 19974 isc_mutex_unlock(&zone->kfio->lock); 19975} 19976 19977isc_result_t 19978dns_zone_checknames(dns_zone_t *zone, const dns_name_t *name, 19979 dns_rdata_t *rdata) { 19980 bool ok = true; 19981 bool fail = false; 19982 char namebuf[DNS_NAME_FORMATSIZE]; 19983 char namebuf2[DNS_NAME_FORMATSIZE]; 19984 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 19985 int level = ISC_LOG_WARNING; 19986 dns_name_t bad; 19987 19988 REQUIRE(DNS_ZONE_VALID(zone)); 19989 19990 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) && 19991 rdata->type != dns_rdatatype_nsec3) 19992 { 19993 return (ISC_R_SUCCESS); 19994 } 19995 19996 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) || 19997 rdata->type == dns_rdatatype_nsec3) 19998 { 19999 level = ISC_LOG_ERROR; 20000 fail = true; 20001 } 20002 20003 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, true); 20004 if (!ok) { 20005 dns_name_format(name, namebuf, sizeof(namebuf)); 20006 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 20007 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf, 20008 dns_result_totext(DNS_R_BADOWNERNAME)); 20009 if (fail) { 20010 return (DNS_R_BADOWNERNAME); 20011 } 20012 } 20013 20014 dns_name_init(&bad, NULL); 20015 ok = dns_rdata_checknames(rdata, name, &bad); 20016 if (!ok) { 20017 dns_name_format(name, namebuf, sizeof(namebuf)); 20018 dns_name_format(&bad, namebuf2, sizeof(namebuf2)); 20019 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 20020 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf, 20021 namebuf2, dns_result_totext(DNS_R_BADNAME)); 20022 if (fail) { 20023 return (DNS_R_BADNAME); 20024 } 20025 } 20026 20027 return (ISC_R_SUCCESS); 20028} 20029 20030void 20031dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) { 20032 REQUIRE(DNS_ZONE_VALID(zone)); 20033 zone->checkmx = checkmx; 20034} 20035 20036void 20037dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) { 20038 REQUIRE(DNS_ZONE_VALID(zone)); 20039 zone->checksrv = checksrv; 20040} 20041 20042void 20043dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) { 20044 REQUIRE(DNS_ZONE_VALID(zone)); 20045 zone->checkns = checkns; 20046} 20047 20048void 20049dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) { 20050 REQUIRE(DNS_ZONE_VALID(zone)); 20051 20052 LOCK_ZONE(zone); 20053 zone->isself = isself; 20054 zone->isselfarg = arg; 20055 UNLOCK_ZONE(zone); 20056} 20057 20058void 20059dns_zone_setnotifydelay(dns_zone_t *zone, uint32_t delay) { 20060 REQUIRE(DNS_ZONE_VALID(zone)); 20061 20062 LOCK_ZONE(zone); 20063 zone->notifydelay = delay; 20064 UNLOCK_ZONE(zone); 20065} 20066 20067uint32_t 20068dns_zone_getnotifydelay(dns_zone_t *zone) { 20069 REQUIRE(DNS_ZONE_VALID(zone)); 20070 20071 return (zone->notifydelay); 20072} 20073 20074isc_result_t 20075dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid, 20076 bool deleteit) { 20077 isc_result_t result; 20078 REQUIRE(DNS_ZONE_VALID(zone)); 20079 20080 dnssec_log(zone, ISC_LOG_NOTICE, 20081 "dns_zone_signwithkey(algorithm=%u, keyid=%u)", algorithm, 20082 keyid); 20083 LOCK_ZONE(zone); 20084 result = zone_signwithkey(zone, algorithm, keyid, deleteit); 20085 UNLOCK_ZONE(zone); 20086 20087 return (result); 20088} 20089 20090/* 20091 * Called when a dynamic update for an NSEC3PARAM record is received. 20092 * 20093 * If set, transform the NSEC3 salt into human-readable form so that it can be 20094 * logged. Then call zone_addnsec3chain(), passing NSEC3PARAM RDATA to it. 20095 */ 20096isc_result_t 20097dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 20098 isc_result_t result; 20099 char salt[255 * 2 + 1]; 20100 20101 REQUIRE(DNS_ZONE_VALID(zone)); 20102 20103 result = dns_nsec3param_salttotext(nsec3param, salt, sizeof(salt)); 20104 RUNTIME_CHECK(result == ISC_R_SUCCESS); 20105 dnssec_log(zone, ISC_LOG_NOTICE, 20106 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)", 20107 nsec3param->hash, nsec3param->iterations, salt); 20108 LOCK_ZONE(zone); 20109 result = zone_addnsec3chain(zone, nsec3param); 20110 UNLOCK_ZONE(zone); 20111 20112 return (result); 20113} 20114 20115void 20116dns_zone_setnodes(dns_zone_t *zone, uint32_t nodes) { 20117 REQUIRE(DNS_ZONE_VALID(zone)); 20118 20119 if (nodes == 0) { 20120 nodes = 1; 20121 } 20122 zone->nodes = nodes; 20123} 20124 20125void 20126dns_zone_setsignatures(dns_zone_t *zone, uint32_t signatures) { 20127 REQUIRE(DNS_ZONE_VALID(zone)); 20128 20129 /* 20130 * We treat signatures as a signed value so explicitly 20131 * limit its range here. 20132 */ 20133 if (signatures > INT32_MAX) { 20134 signatures = INT32_MAX; 20135 } else if (signatures == 0) { 20136 signatures = 1; 20137 } 20138 zone->signatures = signatures; 20139} 20140 20141uint32_t 20142dns_zone_getsignatures(dns_zone_t *zone) { 20143 REQUIRE(DNS_ZONE_VALID(zone)); 20144 return (zone->signatures); 20145} 20146 20147void 20148dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) { 20149 REQUIRE(DNS_ZONE_VALID(zone)); 20150 zone->privatetype = type; 20151} 20152 20153dns_rdatatype_t 20154dns_zone_getprivatetype(dns_zone_t *zone) { 20155 REQUIRE(DNS_ZONE_VALID(zone)); 20156 return (zone->privatetype); 20157} 20158 20159static isc_result_t 20160zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid, 20161 bool deleteit) { 20162 dns_signing_t *signing; 20163 dns_signing_t *current; 20164 isc_result_t result = ISC_R_SUCCESS; 20165 isc_time_t now; 20166 dns_db_t *db = NULL; 20167 20168 signing = isc_mem_get(zone->mctx, sizeof *signing); 20169 20170 signing->magic = 0; 20171 signing->db = NULL; 20172 signing->dbiterator = NULL; 20173 signing->algorithm = algorithm; 20174 signing->keyid = keyid; 20175 signing->deleteit = deleteit; 20176 signing->done = false; 20177 20178 TIME_NOW(&now); 20179 20180 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 20181 if (zone->db != NULL) { 20182 dns_db_attach(zone->db, &db); 20183 } 20184 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 20185 20186 if (db == NULL) { 20187 result = ISC_R_NOTFOUND; 20188 goto cleanup; 20189 } 20190 20191 dns_db_attach(db, &signing->db); 20192 20193 for (current = ISC_LIST_HEAD(zone->signing); current != NULL; 20194 current = ISC_LIST_NEXT(current, link)) 20195 { 20196 if (current->db == signing->db && 20197 current->algorithm == signing->algorithm && 20198 current->keyid == signing->keyid) 20199 { 20200 if (current->deleteit != signing->deleteit) { 20201 current->done = true; 20202 } else { 20203 goto cleanup; 20204 } 20205 } 20206 } 20207 20208 result = dns_db_createiterator(signing->db, 0, &signing->dbiterator); 20209 20210 if (result == ISC_R_SUCCESS) { 20211 result = dns_dbiterator_first(signing->dbiterator); 20212 } 20213 if (result == ISC_R_SUCCESS) { 20214 dns_dbiterator_pause(signing->dbiterator); 20215 ISC_LIST_INITANDAPPEND(zone->signing, signing, link); 20216 signing = NULL; 20217 if (isc_time_isepoch(&zone->signingtime)) { 20218 zone->signingtime = now; 20219 if (zone->task != NULL) { 20220 zone_settimer(zone, &now); 20221 } 20222 } 20223 } 20224 20225cleanup: 20226 if (signing != NULL) { 20227 if (signing->db != NULL) { 20228 dns_db_detach(&signing->db); 20229 } 20230 if (signing->dbiterator != NULL) { 20231 dns_dbiterator_destroy(&signing->dbiterator); 20232 } 20233 isc_mem_put(zone->mctx, signing, sizeof *signing); 20234 } 20235 if (db != NULL) { 20236 dns_db_detach(&db); 20237 } 20238 return (result); 20239} 20240 20241/* Called once; *timep should be set to the current time. */ 20242static isc_result_t 20243next_keyevent(dst_key_t *key, isc_stdtime_t *timep) { 20244 isc_result_t result; 20245 isc_stdtime_t now, then = 0, event; 20246 int i; 20247 20248 now = *timep; 20249 20250 for (i = 0; i <= DST_MAX_TIMES; i++) { 20251 result = dst_key_gettime(key, i, &event); 20252 if (result == ISC_R_SUCCESS && event > now && 20253 (then == 0 || event < then)) 20254 { 20255 then = event; 20256 } 20257 } 20258 20259 if (then != 0) { 20260 *timep = then; 20261 return (ISC_R_SUCCESS); 20262 } 20263 20264 return (ISC_R_NOTFOUND); 20265} 20266 20267static isc_result_t 20268rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 20269 const dns_rdata_t *rdata, bool *flag) { 20270 dns_rdataset_t rdataset; 20271 dns_dbnode_t *node = NULL; 20272 isc_result_t result; 20273 20274 dns_rdataset_init(&rdataset); 20275 if (rdata->type == dns_rdatatype_nsec3) { 20276 CHECK(dns_db_findnsec3node(db, name, false, &node)); 20277 } else { 20278 CHECK(dns_db_findnode(db, name, false, &node)); 20279 } 20280 result = dns_db_findrdataset(db, node, ver, rdata->type, 0, 20281 (isc_stdtime_t)0, &rdataset, NULL); 20282 if (result == ISC_R_NOTFOUND) { 20283 *flag = false; 20284 result = ISC_R_SUCCESS; 20285 goto failure; 20286 } 20287 20288 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 20289 result = dns_rdataset_next(&rdataset)) 20290 { 20291 dns_rdata_t myrdata = DNS_RDATA_INIT; 20292 dns_rdataset_current(&rdataset, &myrdata); 20293 if (!dns_rdata_compare(&myrdata, rdata)) { 20294 break; 20295 } 20296 } 20297 dns_rdataset_disassociate(&rdataset); 20298 if (result == ISC_R_SUCCESS) { 20299 *flag = true; 20300 } else if (result == ISC_R_NOMORE) { 20301 *flag = false; 20302 result = ISC_R_SUCCESS; 20303 } 20304 20305failure: 20306 if (node != NULL) { 20307 dns_db_detachnode(db, &node); 20308 } 20309 return (result); 20310} 20311 20312/* 20313 * Add records to signal the state of signing or of key removal. 20314 */ 20315static isc_result_t 20316add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, 20317 dns_dbversion_t *ver, dns_diff_t *diff, bool sign_all) { 20318 dns_difftuple_t *tuple, *newtuple = NULL; 20319 dns_rdata_dnskey_t dnskey; 20320 dns_rdata_t rdata = DNS_RDATA_INIT; 20321 bool flag; 20322 isc_region_t r; 20323 isc_result_t result = ISC_R_SUCCESS; 20324 uint16_t keyid; 20325 unsigned char buf[5]; 20326 dns_name_t *name = dns_db_origin(db); 20327 20328 for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; 20329 tuple = ISC_LIST_NEXT(tuple, link)) 20330 { 20331 if (tuple->rdata.type != dns_rdatatype_dnskey) { 20332 continue; 20333 } 20334 20335 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL); 20336 RUNTIME_CHECK(result == ISC_R_SUCCESS); 20337 if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK | 20338 DNS_KEYTYPE_NOAUTH)) != DNS_KEYOWNER_ZONE) 20339 { 20340 continue; 20341 } 20342 20343 dns_rdata_toregion(&tuple->rdata, &r); 20344 20345 keyid = dst_region_computeid(&r); 20346 20347 buf[0] = dnskey.algorithm; 20348 buf[1] = (keyid & 0xff00) >> 8; 20349 buf[2] = (keyid & 0xff); 20350 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1; 20351 buf[4] = 0; 20352 rdata.data = buf; 20353 rdata.length = sizeof(buf); 20354 rdata.type = privatetype; 20355 rdata.rdclass = tuple->rdata.rdclass; 20356 20357 if (sign_all || tuple->op == DNS_DIFFOP_DEL) { 20358 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 20359 if (flag) { 20360 continue; 20361 } 20362 20363 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, 20364 name, 0, &rdata, &newtuple)); 20365 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 20366 INSIST(newtuple == NULL); 20367 } 20368 20369 /* 20370 * Remove any record which says this operation has already 20371 * completed. 20372 */ 20373 buf[4] = 1; 20374 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 20375 if (flag) { 20376 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, 20377 name, 0, &rdata, &newtuple)); 20378 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 20379 INSIST(newtuple == NULL); 20380 } 20381 } 20382failure: 20383 return (result); 20384} 20385 20386/* 20387 * See if dns__zone_updatesigs() will update signature for RRset 'rrtype' at 20388 * the apex, and if not tickle them and cause to sign so that newly activated 20389 * keys are used. 20390 */ 20391static isc_result_t 20392tickle_apex_rrset(dns_rdatatype_t rrtype, dns_zone_t *zone, dns_db_t *db, 20393 dns_dbversion_t *ver, isc_stdtime_t now, dns_diff_t *diff, 20394 dns__zonediff_t *zonediff, dst_key_t **keys, 20395 unsigned int nkeys, isc_stdtime_t inception, 20396 isc_stdtime_t keyexpire, bool check_ksk, 20397 bool keyset_kskonly) { 20398 dns_difftuple_t *tuple; 20399 isc_result_t result; 20400 20401 for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; 20402 tuple = ISC_LIST_NEXT(tuple, link)) 20403 { 20404 if (tuple->rdata.type == rrtype && 20405 dns_name_equal(&tuple->name, &zone->origin)) 20406 { 20407 break; 20408 } 20409 } 20410 20411 if (tuple == NULL) { 20412 result = del_sigs(zone, db, ver, &zone->origin, rrtype, 20413 zonediff, keys, nkeys, now, false); 20414 if (result != ISC_R_SUCCESS) { 20415 dnssec_log(zone, ISC_LOG_ERROR, 20416 "sign_apex:del_sigs -> %s", 20417 dns_result_totext(result)); 20418 return (result); 20419 } 20420 result = add_sigs(db, ver, &zone->origin, zone, rrtype, 20421 zonediff->diff, keys, nkeys, zone->mctx, 20422 inception, keyexpire, check_ksk, 20423 keyset_kskonly); 20424 if (result != ISC_R_SUCCESS) { 20425 dnssec_log(zone, ISC_LOG_ERROR, 20426 "sign_apex:add_sigs -> %s", 20427 dns_result_totext(result)); 20428 return (result); 20429 } 20430 } 20431 20432 return (ISC_R_SUCCESS); 20433} 20434 20435static isc_result_t 20436sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 20437 isc_stdtime_t now, dns_diff_t *diff, dns__zonediff_t *zonediff) { 20438 isc_result_t result; 20439 isc_stdtime_t inception, soaexpire, keyexpire; 20440 bool check_ksk, keyset_kskonly; 20441 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 20442 unsigned int nkeys = 0, i; 20443 20444 result = dns__zone_findkeys(zone, db, ver, now, zone->mctx, 20445 DNS_MAXZONEKEYS, zone_keys, &nkeys); 20446 if (result != ISC_R_SUCCESS) { 20447 dnssec_log(zone, ISC_LOG_ERROR, 20448 "sign_apex:dns__zone_findkeys -> %s", 20449 dns_result_totext(result)); 20450 return (result); 20451 } 20452 20453 inception = now - 3600; /* Allow for clock skew. */ 20454 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 20455 20456 keyexpire = dns_zone_getkeyvalidityinterval(zone); 20457 if (keyexpire == 0) { 20458 keyexpire = soaexpire - 1; 20459 } else { 20460 keyexpire += now; 20461 } 20462 20463 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 20464 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 20465 20466 /* 20467 * See if dns__zone_updatesigs() will update DNSKEY/CDS/CDNSKEY 20468 * signature and if not cause them to sign so that newly activated 20469 * keys are used. 20470 */ 20471 result = tickle_apex_rrset(dns_rdatatype_dnskey, zone, db, ver, now, 20472 diff, zonediff, zone_keys, nkeys, inception, 20473 keyexpire, check_ksk, keyset_kskonly); 20474 if (result != ISC_R_SUCCESS) { 20475 goto failure; 20476 } 20477 result = tickle_apex_rrset(dns_rdatatype_cds, zone, db, ver, now, diff, 20478 zonediff, zone_keys, nkeys, inception, 20479 keyexpire, check_ksk, keyset_kskonly); 20480 if (result != ISC_R_SUCCESS) { 20481 goto failure; 20482 } 20483 result = tickle_apex_rrset(dns_rdatatype_cdnskey, zone, db, ver, now, 20484 diff, zonediff, zone_keys, nkeys, inception, 20485 keyexpire, check_ksk, keyset_kskonly); 20486 if (result != ISC_R_SUCCESS) { 20487 goto failure; 20488 } 20489 20490 result = dns__zone_updatesigs(diff, db, ver, zone_keys, nkeys, zone, 20491 inception, soaexpire, keyexpire, now, 20492 check_ksk, keyset_kskonly, zonediff); 20493 20494 if (result != ISC_R_SUCCESS) { 20495 dnssec_log(zone, ISC_LOG_ERROR, 20496 "sign_apex:dns__zone_updatesigs -> %s", 20497 dns_result_totext(result)); 20498 goto failure; 20499 } 20500 20501failure: 20502 for (i = 0; i < nkeys; i++) { 20503 dst_key_free(&zone_keys[i]); 20504 } 20505 return (result); 20506} 20507 20508/* 20509 * Prevent the zone entering a inconsistent state where 20510 * NSEC only DNSKEYs are present with NSEC3 chains. 20511 * See update.c:check_dnssec() 20512 */ 20513static bool 20514dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 20515 dns_diff_t *diff) { 20516 isc_result_t result; 20517 dns_difftuple_t *tuple; 20518 bool nseconly = false, nsec3 = false; 20519 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); 20520 20521 /* Scan the tuples for an NSEC-only DNSKEY */ 20522 for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; 20523 tuple = ISC_LIST_NEXT(tuple, link)) 20524 { 20525 uint8_t alg; 20526 if (tuple->rdata.type != dns_rdatatype_dnskey || 20527 tuple->op != DNS_DIFFOP_ADD) 20528 { 20529 continue; 20530 } 20531 20532 alg = tuple->rdata.data[3]; 20533 if (alg == DST_ALG_RSASHA1) { 20534 nseconly = true; 20535 break; 20536 } 20537 } 20538 20539 /* Check existing DB for NSEC-only DNSKEY */ 20540 if (!nseconly) { 20541 result = dns_nsec_nseconly(db, ver, &nseconly); 20542 if (result == ISC_R_NOTFOUND) { 20543 result = ISC_R_SUCCESS; 20544 } 20545 CHECK(result); 20546 } 20547 20548 /* Check existing DB for NSEC3 */ 20549 if (!nsec3) { 20550 CHECK(dns_nsec3_activex(db, ver, false, privatetype, &nsec3)); 20551 } 20552 20553 /* Refuse to allow NSEC3 with NSEC-only keys */ 20554 if (nseconly && nsec3) { 20555 dnssec_log(zone, ISC_LOG_ERROR, 20556 "NSEC only DNSKEYs and NSEC3 chains not allowed"); 20557 goto failure; 20558 } 20559 20560 return (true); 20561 20562failure: 20563 return (false); 20564} 20565 20566static isc_result_t 20567clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 20568 dns_diff_t *diff) { 20569 isc_result_t result; 20570 dns_dbnode_t *node = NULL; 20571 dns_rdataset_t rdataset; 20572 20573 dns_rdataset_init(&rdataset); 20574 CHECK(dns_db_getoriginnode(db, &node)); 20575 20576 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 20577 dns_rdatatype_none, 0, &rdataset, NULL); 20578 if (dns_rdataset_isassociated(&rdataset)) { 20579 dns_rdataset_disassociate(&rdataset); 20580 } 20581 if (result != ISC_R_NOTFOUND) { 20582 goto failure; 20583 } 20584 20585 result = dns_nsec3param_deletechains(db, ver, zone, true, diff); 20586 20587failure: 20588 if (node != NULL) { 20589 dns_db_detachnode(db, &node); 20590 } 20591 return (result); 20592} 20593 20594/* 20595 * Given an RRSIG rdataset and an algorithm, determine whether there 20596 * are any signatures using that algorithm. 20597 */ 20598static bool 20599signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) { 20600 dns_rdata_t rdata = DNS_RDATA_INIT; 20601 dns_rdata_rrsig_t rrsig; 20602 isc_result_t result; 20603 20604 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig); 20605 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) { 20606 return (false); 20607 } 20608 20609 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 20610 result = dns_rdataset_next(rdataset)) 20611 { 20612 dns_rdataset_current(rdataset, &rdata); 20613 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 20614 RUNTIME_CHECK(result == ISC_R_SUCCESS); 20615 dns_rdata_reset(&rdata); 20616 if (rrsig.algorithm == alg) { 20617 return (true); 20618 } 20619 } 20620 20621 return (false); 20622} 20623 20624static isc_result_t 20625add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 20626 dns_diff_t *diff) { 20627 dns_name_t *origin; 20628 bool build_nsec3; 20629 isc_result_t result; 20630 20631 origin = dns_db_origin(db); 20632 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL, 20633 &build_nsec3)); 20634 if (build_nsec3) { 20635 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone_nsecttl(zone), 20636 false, zone->privatetype, diff)); 20637 } 20638 CHECK(updatesecure(db, ver, origin, zone_nsecttl(zone), true, diff)); 20639 20640failure: 20641 return (result); 20642} 20643 20644static void 20645dnssec_report(const char *format, ...) { 20646 va_list args; 20647 va_start(args, format); 20648 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_ZONE, 20649 ISC_LOG_INFO, format, args); 20650 va_end(args); 20651} 20652 20653static void 20654checkds_destroy(dns_checkds_t *checkds, bool locked) { 20655 isc_mem_t *mctx; 20656 20657 REQUIRE(DNS_CHECKDS_VALID(checkds)); 20658 20659 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 20660 "checkds: destroy DS query"); 20661 20662 if (checkds->zone != NULL) { 20663 if (!locked) { 20664 LOCK_ZONE(checkds->zone); 20665 } 20666 REQUIRE(LOCKED_ZONE(checkds->zone)); 20667 if (ISC_LINK_LINKED(checkds, link)) { 20668 ISC_LIST_UNLINK(checkds->zone->checkds_requests, 20669 checkds, link); 20670 } 20671 if (!locked) { 20672 UNLOCK_ZONE(checkds->zone); 20673 } 20674 if (locked) { 20675 zone_idetach(&checkds->zone); 20676 } else { 20677 dns_zone_idetach(&checkds->zone); 20678 } 20679 } 20680 if (checkds->request != NULL) { 20681 dns_request_destroy(&checkds->request); 20682 } 20683 if (checkds->key != NULL) { 20684 dns_tsigkey_detach(&checkds->key); 20685 } 20686 mctx = checkds->mctx; 20687 isc_mem_put(checkds->mctx, checkds, sizeof(*checkds)); 20688 isc_mem_detach(&mctx); 20689} 20690 20691static isc_result_t 20692make_dnskey(dst_key_t *key, unsigned char *buf, int bufsize, 20693 dns_rdata_t *target) { 20694 isc_result_t result; 20695 isc_buffer_t b; 20696 isc_region_t r; 20697 20698 isc_buffer_init(&b, buf, bufsize); 20699 result = dst_key_todns(key, &b); 20700 if (result != ISC_R_SUCCESS) { 20701 return (result); 20702 } 20703 20704 dns_rdata_reset(target); 20705 isc_buffer_usedregion(&b, &r); 20706 dns_rdata_fromregion(target, dst_key_class(key), dns_rdatatype_dnskey, 20707 &r); 20708 return (ISC_R_SUCCESS); 20709} 20710 20711static bool 20712do_checkds(dns_zone_t *zone, dst_key_t *key, isc_stdtime_t now, 20713 bool dspublish) { 20714 dns_kasp_t *kasp = dns_zone_getkasp(zone); 20715 const char *dir = dns_zone_getkeydirectory(zone); 20716 isc_result_t result; 20717 uint32_t count = 0; 20718 20719 if (dspublish) { 20720 (void)dst_key_getnum(key, DST_NUM_DSPUBCOUNT, &count); 20721 count += 1; 20722 dst_key_setnum(key, DST_NUM_DSPUBCOUNT, count); 20723 dns_zone_log(zone, ISC_LOG_DEBUG(3), 20724 "checkds: %u DS published " 20725 "for key %u", 20726 count, dst_key_id(key)); 20727 20728 if (count != zone->parentalscnt) { 20729 return false; 20730 } 20731 } else { 20732 (void)dst_key_getnum(key, DST_NUM_DSDELCOUNT, &count); 20733 count += 1; 20734 dst_key_setnum(key, DST_NUM_DSDELCOUNT, count); 20735 dns_zone_log(zone, ISC_LOG_DEBUG(3), 20736 "checkds: %u DS withdrawn " 20737 "for key %u", 20738 count, dst_key_id(key)); 20739 20740 if (count != zone->parentalscnt) { 20741 return false; 20742 } 20743 } 20744 20745 dns_zone_log(zone, ISC_LOG_DEBUG(3), 20746 "checkds: checkds %s for key " 20747 "%u", 20748 dspublish ? "published" : "withdrawn", dst_key_id(key)); 20749 20750 dns_zone_lock_keyfiles(zone); 20751 result = dns_keymgr_checkds_id(kasp, &zone->checkds_ok, dir, now, now, 20752 dspublish, dst_key_id(key), 20753 dst_key_alg(key)); 20754 dns_zone_unlock_keyfiles(zone); 20755 20756 if (result != ISC_R_SUCCESS) { 20757 dns_zone_log(zone, ISC_LOG_WARNING, 20758 "checkds: checkds for key %u failed: %s", 20759 dst_key_id(key), isc_result_totext(result)); 20760 return false; 20761 } 20762 20763 return true; 20764} 20765 20766static isc_result_t 20767validate_ds(dns_zone_t *zone, dns_message_t *message) { 20768 UNUSED(zone); 20769 UNUSED(message); 20770 20771 /* Get closest trust anchor */ 20772 20773 /* Check that trust anchor is (grand)parent of zone. */ 20774 20775 /* Find the DNSKEY signing the message. */ 20776 20777 /* Check that DNSKEY is in chain of trust. */ 20778 20779 /* Validate DS RRset. */ 20780 20781 return (ISC_R_SUCCESS); 20782} 20783 20784static void 20785checkds_done(isc_task_t *task, isc_event_t *event) { 20786 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 20787 char rcode[128]; 20788 dns_checkds_t *checkds; 20789 dns_zone_t *zone; 20790 dns_db_t *db = NULL; 20791 dns_dbversion_t *version = NULL; 20792 dns_dnsseckey_t *key; 20793 dns_dnsseckeylist_t keys; 20794 dns_kasp_t *kasp = NULL; 20795 dns_message_t *message = NULL; 20796 dns_rdataset_t *ds_rrset = NULL; 20797 dns_requestevent_t *revent = (dns_requestevent_t *)event; 20798 isc_buffer_t buf; 20799 isc_result_t result; 20800 isc_stdtime_t now; 20801 isc_time_t timenow; 20802 bool rekey = false; 20803 bool empty = false; 20804 20805 UNUSED(task); 20806 20807 checkds = event->ev_arg; 20808 REQUIRE(DNS_CHECKDS_VALID(checkds)); 20809 20810 zone = checkds->zone; 20811 INSIST(task == zone->task); 20812 20813 ISC_LIST_INIT(keys); 20814 20815 kasp = zone->kasp; 20816 INSIST(kasp != NULL); 20817 20818 isc_buffer_init(&buf, rcode, sizeof(rcode)); 20819 isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf)); 20820 20821 dns_zone_log(zone, ISC_LOG_DEBUG(1), "checkds: DS query to %s: done", 20822 addrbuf); 20823 20824 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &message); 20825 INSIST(message != NULL); 20826 20827 CHECK(revent->result); 20828 CHECK(dns_request_getresponse(revent->request, message, 20829 DNS_MESSAGEPARSE_PRESERVEORDER)); 20830 CHECK(dns_rcode_totext(message->rcode, &buf)); 20831 20832 dns_zone_log(zone, ISC_LOG_DEBUG(3), 20833 "checkds: DS response from %s: %.*s", addrbuf, 20834 (int)buf.used, rcode); 20835 20836 /* Validate response. */ 20837 CHECK(validate_ds(zone, message)); 20838 20839 if (message->rcode != dns_rcode_noerror) { 20840 dns_zone_log(zone, ISC_LOG_NOTICE, 20841 "checkds: bad DS response from %s: %.*s", addrbuf, 20842 (int)buf.used, rcode); 20843 goto failure; 20844 } 20845 20846 /* Lookup DS RRset. */ 20847 result = dns_message_firstname(message, DNS_SECTION_ANSWER); 20848 while (result == ISC_R_SUCCESS) { 20849 dns_name_t *name = NULL; 20850 dns_rdataset_t *rdataset; 20851 20852 dns_message_currentname(message, DNS_SECTION_ANSWER, &name); 20853 if (dns_name_compare(&zone->origin, name) != 0) { 20854 goto next; 20855 } 20856 20857 for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; 20858 rdataset = ISC_LIST_NEXT(rdataset, link)) 20859 { 20860 if (rdataset->type != dns_rdatatype_ds) { 20861 goto next; 20862 } 20863 20864 ds_rrset = rdataset; 20865 break; 20866 } 20867 20868 if (ds_rrset != NULL) { 20869 break; 20870 } 20871 20872 next: 20873 result = dns_message_nextname(message, DNS_SECTION_ANSWER); 20874 } 20875 20876 if (ds_rrset == NULL) { 20877 empty = true; 20878 dns_zone_log(zone, ISC_LOG_NOTICE, 20879 "checkds: empty DS response from %s", addrbuf); 20880 } 20881 20882 TIME_NOW(&timenow); 20883 now = isc_time_seconds(&timenow); 20884 20885 CHECK(dns_zone_getdb(zone, &db)); 20886 dns_db_currentversion(db, &version); 20887 20888 KASP_LOCK(kasp); 20889 LOCK_ZONE(zone); 20890 for (key = ISC_LIST_HEAD(zone->checkds_ok); key != NULL; 20891 key = ISC_LIST_NEXT(key, link)) 20892 { 20893 bool alldone = false, found = false; 20894 bool checkdspub = false, checkdsdel = false, ksk = false; 20895 dst_key_state_t ds_state = DST_KEY_STATE_NA; 20896 isc_stdtime_t published = 0, withdrawn = 0; 20897 isc_result_t ret = ISC_R_SUCCESS; 20898 20899 /* Is this key have the KSK role? */ 20900 (void)dst_key_role(key->key, &ksk, NULL); 20901 if (!ksk) { 20902 continue; 20903 } 20904 20905 /* Do we need to check the DS RRset for this key? */ 20906 (void)dst_key_getstate(key->key, DST_KEY_DS, &ds_state); 20907 (void)dst_key_gettime(key->key, DST_TIME_DSPUBLISH, &published); 20908 (void)dst_key_gettime(key->key, DST_TIME_DSDELETE, &withdrawn); 20909 20910 if (ds_state == DST_KEY_STATE_RUMOURED && published == 0) { 20911 checkdspub = true; 20912 } else if (ds_state == DST_KEY_STATE_UNRETENTIVE && 20913 withdrawn == 0) 20914 { 20915 checkdsdel = true; 20916 } 20917 if (!checkdspub && !checkdsdel) { 20918 continue; 20919 } 20920 20921 if (empty) { 20922 goto dswithdrawn; 20923 } 20924 20925 /* Find the appropriate DS record. */ 20926 ret = dns_rdataset_first(ds_rrset); 20927 while (ret == ISC_R_SUCCESS) { 20928 dns_rdata_ds_t ds; 20929 dns_rdata_t dnskey = DNS_RDATA_INIT; 20930 dns_rdata_t dsrdata = DNS_RDATA_INIT; 20931 dns_rdata_t rdata = DNS_RDATA_INIT; 20932 isc_result_t r; 20933 unsigned char dsbuf[DNS_DS_BUFFERSIZE]; 20934 unsigned char keybuf[DST_KEY_MAXSIZE]; 20935 20936 dns_rdataset_current(ds_rrset, &rdata); 20937 r = dns_rdata_tostruct(&rdata, &ds, NULL); 20938 if (r != ISC_R_SUCCESS) { 20939 goto nextds; 20940 } 20941 /* Check key tag and algorithm. */ 20942 if (dst_key_id(key->key) != ds.key_tag) { 20943 goto nextds; 20944 } 20945 if (dst_key_alg(key->key) != ds.algorithm) { 20946 goto nextds; 20947 } 20948 /* Derive DS from DNSKEY, see if the rdata is equal. */ 20949 make_dnskey(key->key, keybuf, sizeof(keybuf), &dnskey); 20950 r = dns_ds_buildrdata(&zone->origin, &dnskey, 20951 ds.digest_type, dsbuf, &dsrdata); 20952 if (r != ISC_R_SUCCESS) { 20953 goto nextds; 20954 } 20955 if (dns_rdata_compare(&rdata, &dsrdata) == 0) { 20956 found = true; 20957 if (checkdspub) { 20958 /* DS Published. */ 20959 alldone = do_checkds(zone, key->key, 20960 now, true); 20961 if (alldone) { 20962 rekey = true; 20963 } 20964 } 20965 } 20966 20967 nextds: 20968 ret = dns_rdataset_next(ds_rrset); 20969 } 20970 20971 dswithdrawn: 20972 /* DS withdrawn. */ 20973 if (checkdsdel && !found) { 20974 alldone = do_checkds(zone, key->key, now, false); 20975 if (alldone) { 20976 rekey = true; 20977 } 20978 } 20979 } 20980 UNLOCK_ZONE(zone); 20981 KASP_UNLOCK(kasp); 20982 20983 /* Rekey after checkds. */ 20984 if (rekey) { 20985 dns_zone_rekey(zone, false); 20986 } 20987 20988failure: 20989 if (result != ISC_R_SUCCESS) { 20990 dns_zone_log(zone, ISC_LOG_DEBUG(3), 20991 "checkds: DS request failed: %s", 20992 isc_result_totext(result)); 20993 } 20994 20995 if (version != NULL) { 20996 dns_db_closeversion(db, &version, false); 20997 } 20998 if (db != NULL) { 20999 dns_db_detach(&db); 21000 } 21001 21002 while (!ISC_LIST_EMPTY(keys)) { 21003 key = ISC_LIST_HEAD(keys); 21004 ISC_LIST_UNLINK(keys, key, link); 21005 dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key); 21006 } 21007 21008 isc_event_free(&event); 21009 checkds_destroy(checkds, false); 21010 dns_message_detach(&message); 21011} 21012 21013static bool 21014checkds_isqueued(dns_zone_t *zone, isc_sockaddr_t *addr, dns_tsigkey_t *key) { 21015 dns_checkds_t *checkds; 21016 21017 for (checkds = ISC_LIST_HEAD(zone->checkds_requests); checkds != NULL; 21018 checkds = ISC_LIST_NEXT(checkds, link)) 21019 { 21020 if (checkds->request != NULL) { 21021 continue; 21022 } 21023 if (addr != NULL && isc_sockaddr_equal(addr, &checkds->dst) && 21024 checkds->key == key) 21025 { 21026 return (true); 21027 } 21028 } 21029 return (false); 21030} 21031 21032static isc_result_t 21033checkds_create(isc_mem_t *mctx, unsigned int flags, dns_checkds_t **checkdsp) { 21034 dns_checkds_t *checkds; 21035 21036 REQUIRE(checkdsp != NULL && *checkdsp == NULL); 21037 21038 checkds = isc_mem_get(mctx, sizeof(*checkds)); 21039 *checkds = (dns_checkds_t){ 21040 .flags = flags, 21041 }; 21042 21043 isc_mem_attach(mctx, &checkds->mctx); 21044 isc_sockaddr_any(&checkds->dst); 21045 ISC_LINK_INIT(checkds, link); 21046 checkds->magic = CHECKDS_MAGIC; 21047 *checkdsp = checkds; 21048 return (ISC_R_SUCCESS); 21049} 21050 21051static isc_result_t 21052checkds_createmessage(dns_zone_t *zone, dns_message_t **messagep) { 21053 dns_message_t *message = NULL; 21054 21055 dns_name_t *tempname = NULL; 21056 dns_rdataset_t *temprdataset = NULL; 21057 21058 isc_result_t result; 21059 21060 REQUIRE(DNS_ZONE_VALID(zone)); 21061 REQUIRE(messagep != NULL && *messagep == NULL); 21062 21063 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message); 21064 21065 message->opcode = dns_opcode_query; 21066 message->rdclass = zone->rdclass; 21067 21068 result = dns_message_gettempname(message, &tempname); 21069 if (result != ISC_R_SUCCESS) { 21070 goto cleanup; 21071 } 21072 21073 result = dns_message_gettemprdataset(message, &temprdataset); 21074 if (result != ISC_R_SUCCESS) { 21075 goto cleanup; 21076 } 21077 21078 /* 21079 * Make question. 21080 */ 21081 dns_name_init(tempname, NULL); 21082 dns_name_clone(&zone->origin, tempname); 21083 dns_rdataset_makequestion(temprdataset, zone->rdclass, 21084 dns_rdatatype_ds); 21085 ISC_LIST_APPEND(tempname->list, temprdataset, link); 21086 dns_message_addname(message, tempname, DNS_SECTION_QUESTION); 21087 tempname = NULL; 21088 temprdataset = NULL; 21089 21090 *messagep = message; 21091 return (ISC_R_SUCCESS); 21092 21093cleanup: 21094 if (tempname != NULL) { 21095 dns_message_puttempname(message, &tempname); 21096 } 21097 if (temprdataset != NULL) { 21098 dns_message_puttemprdataset(message, &temprdataset); 21099 } 21100 dns_message_detach(&message); 21101 return (result); 21102} 21103 21104static void 21105checkds_send_toaddr(isc_task_t *task, isc_event_t *event) { 21106 dns_checkds_t *checkds; 21107 isc_result_t result; 21108 dns_message_t *message = NULL; 21109 isc_netaddr_t dstip; 21110 dns_tsigkey_t *key = NULL; 21111 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 21112 isc_sockaddr_t src; 21113 unsigned int options, timeout; 21114 bool have_checkdssource = false; 21115 bool have_checkdsdscp = false; 21116 isc_dscp_t dscp = -1; 21117 21118 checkds = event->ev_arg; 21119 REQUIRE(DNS_CHECKDS_VALID(checkds)); 21120 21121 UNUSED(task); 21122 21123 LOCK_ZONE(checkds->zone); 21124 21125 checkds->event = NULL; 21126 21127 if (DNS_ZONE_FLAG(checkds->zone, DNS_ZONEFLG_LOADED) == 0) { 21128 result = ISC_R_CANCELED; 21129 goto cleanup; 21130 } 21131 21132 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 || 21133 DNS_ZONE_FLAG(checkds->zone, DNS_ZONEFLG_EXITING) || 21134 checkds->zone->view->requestmgr == NULL || 21135 checkds->zone->db == NULL) 21136 { 21137 result = ISC_R_CANCELED; 21138 goto cleanup; 21139 } 21140 21141 /* 21142 * The raw IPv4 address should also exist. Don't send to the 21143 * mapped form. 21144 */ 21145 if (isc_sockaddr_pf(&checkds->dst) == PF_INET6 && 21146 IN6_IS_ADDR_V4MAPPED(&checkds->dst.type.sin6.sin6_addr)) 21147 { 21148 isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf)); 21149 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21150 "checkds: ignoring IPv6 mapped IPV4 address: %s", 21151 addrbuf); 21152 result = ISC_R_CANCELED; 21153 goto cleanup; 21154 } 21155 21156 result = checkds_createmessage(checkds->zone, &message); 21157 if (result != ISC_R_SUCCESS) { 21158 goto cleanup; 21159 } 21160 21161 isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf)); 21162 if (checkds->key != NULL) { 21163 /* Transfer ownership of key */ 21164 key = checkds->key; 21165 checkds->key = NULL; 21166 } else { 21167 isc_netaddr_fromsockaddr(&dstip, &checkds->dst); 21168 result = dns_view_getpeertsig(checkds->zone->view, &dstip, 21169 &key); 21170 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 21171 dns_zone_log(checkds->zone, ISC_LOG_ERROR, 21172 "checkds: DS query to %s not sent. " 21173 "Peer TSIG key lookup failure.", 21174 addrbuf); 21175 goto cleanup_message; 21176 } 21177 } 21178 21179 if (key != NULL) { 21180 char namebuf[DNS_NAME_FORMATSIZE]; 21181 21182 dns_name_format(&key->name, namebuf, sizeof(namebuf)); 21183 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21184 "checkds: sending DS query to %s : TSIG (%s)", 21185 addrbuf, namebuf); 21186 } else { 21187 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21188 "checkds: sending DS query to %s", addrbuf); 21189 } 21190 options = 0; 21191 if (checkds->zone->view->peers != NULL) { 21192 dns_peer_t *peer = NULL; 21193 bool usetcp = false; 21194 result = dns_peerlist_peerbyaddr(checkds->zone->view->peers, 21195 &dstip, &peer); 21196 if (result == ISC_R_SUCCESS) { 21197 result = dns_peer_getquerysource(peer, &src); 21198 if (result == ISC_R_SUCCESS) { 21199 have_checkdssource = true; 21200 } 21201 dns_peer_getquerydscp(peer, &dscp); 21202 if (dscp != -1) { 21203 have_checkdsdscp = true; 21204 } 21205 result = dns_peer_getforcetcp(peer, &usetcp); 21206 if (result == ISC_R_SUCCESS && usetcp) { 21207 options |= DNS_FETCHOPT_TCP; 21208 } 21209 } 21210 } 21211 switch (isc_sockaddr_pf(&checkds->dst)) { 21212 case PF_INET: 21213 if (!have_checkdssource) { 21214 src = checkds->zone->parentalsrc4; 21215 } 21216 if (!have_checkdsdscp) { 21217 dscp = checkds->zone->parentalsrc4dscp; 21218 } 21219 break; 21220 case PF_INET6: 21221 if (!have_checkdssource) { 21222 src = checkds->zone->parentalsrc6; 21223 } 21224 if (!have_checkdsdscp) { 21225 dscp = checkds->zone->parentalsrc6dscp; 21226 } 21227 break; 21228 default: 21229 result = ISC_R_NOTIMPLEMENTED; 21230 goto cleanup_key; 21231 } 21232 21233 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21234 "checkds: create request for DS query to %s", addrbuf); 21235 21236 timeout = 15; 21237 options |= DNS_REQUESTOPT_TCP; 21238 result = dns_request_createvia( 21239 checkds->zone->view->requestmgr, message, &src, &checkds->dst, 21240 dscp, options, key, timeout * 3, timeout, 0, 21241 checkds->zone->task, checkds_done, checkds, &checkds->request); 21242 if (result != ISC_R_SUCCESS) { 21243 dns_zone_log( 21244 checkds->zone, ISC_LOG_DEBUG(3), 21245 "checkds: dns_request_createvia() to %s failed: %s", 21246 addrbuf, dns_result_totext(result)); 21247 } 21248 21249cleanup_key: 21250 if (key != NULL) { 21251 dns_tsigkey_detach(&key); 21252 } 21253cleanup_message: 21254 dns_message_detach(&message); 21255cleanup: 21256 UNLOCK_ZONE(checkds->zone); 21257 isc_event_free(&event); 21258 if (result != ISC_R_SUCCESS) { 21259 checkds_destroy(checkds, false); 21260 } 21261} 21262 21263static isc_result_t 21264checkds_send_queue(dns_checkds_t *checkds) { 21265 isc_event_t *e; 21266 isc_result_t result; 21267 21268 INSIST(checkds->event == NULL); 21269 e = isc_event_allocate(checkds->mctx, NULL, DNS_EVENT_CHECKDSSENDTOADDR, 21270 checkds_send_toaddr, checkds, 21271 sizeof(isc_event_t)); 21272 e->ev_arg = checkds; 21273 e->ev_sender = NULL; 21274 result = isc_ratelimiter_enqueue(checkds->zone->zmgr->checkdsrl, 21275 checkds->zone->task, &e); 21276 if (result != ISC_R_SUCCESS) { 21277 isc_event_free(&e); 21278 checkds->event = NULL; 21279 } 21280 return (result); 21281} 21282 21283static void 21284checkds_send(dns_zone_t *zone) { 21285 dns_view_t *view = dns_zone_getview(zone); 21286 isc_result_t result; 21287 unsigned int flags = 0; 21288 21289 /* 21290 * Zone lock held by caller. 21291 */ 21292 REQUIRE(LOCKED_ZONE(zone)); 21293 21294 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21295 "checkds: start sending DS queries to %u parentals", 21296 zone->parentalscnt); 21297 21298 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 21299 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21300 "checkds: abort, named exiting"); 21301 return; 21302 } 21303 21304 for (unsigned int i = 0; i < zone->parentalscnt; i++) { 21305 dns_tsigkey_t *key = NULL; 21306 isc_sockaddr_t dst; 21307 dns_checkds_t *checkds = NULL; 21308 21309 if ((zone->parentalkeynames != NULL) && 21310 (zone->parentalkeynames[i] != NULL)) 21311 { 21312 dns_name_t *keyname = zone->parentalkeynames[i]; 21313 (void)dns_view_gettsig(view, keyname, &key); 21314 } 21315 21316 dst = zone->parentals[i]; 21317 21318 if (checkds_isqueued(zone, &dst, key)) { 21319 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21320 "checkds: DS query to parent " 21321 "%d is queued", 21322 i); 21323 if (key != NULL) { 21324 dns_tsigkey_detach(&key); 21325 } 21326 continue; 21327 } 21328 21329 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21330 "checkds: create DS query for " 21331 "parent %d", 21332 i); 21333 21334 result = checkds_create(zone->mctx, flags, &checkds); 21335 if (result != ISC_R_SUCCESS) { 21336 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21337 "checkds: create DS query for " 21338 "parent %d failed", 21339 i); 21340 continue; 21341 } 21342 zone_iattach(zone, &checkds->zone); 21343 checkds->dst = dst; 21344 21345 INSIST(checkds->key == NULL); 21346 if (key != NULL) { 21347 checkds->key = key; 21348 key = NULL; 21349 } 21350 21351 ISC_LIST_APPEND(zone->checkds_requests, checkds, link); 21352 result = checkds_send_queue(checkds); 21353 if (result != ISC_R_SUCCESS) { 21354 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21355 "checkds: send DS query to " 21356 "parent %d failed", 21357 i); 21358 checkds_destroy(checkds, true); 21359 } 21360 } 21361} 21362 21363static void 21364zone_checkds(dns_zone_t *zone) { 21365 bool cdscheck = false; 21366 21367 for (dns_dnsseckey_t *key = ISC_LIST_HEAD(zone->checkds_ok); 21368 key != NULL; key = ISC_LIST_NEXT(key, link)) 21369 { 21370 dst_key_state_t ds_state = DST_KEY_STATE_NA; 21371 bool ksk = false; 21372 isc_stdtime_t published = 0, withdrawn = 0; 21373 21374 /* Is this key have the KSK role? */ 21375 (void)dst_key_role(key->key, &ksk, NULL); 21376 if (!ksk) { 21377 continue; 21378 } 21379 21380 /* Do we need to check the DS RRset? */ 21381 (void)dst_key_getstate(key->key, DST_KEY_DS, &ds_state); 21382 (void)dst_key_gettime(key->key, DST_TIME_DSPUBLISH, &published); 21383 (void)dst_key_gettime(key->key, DST_TIME_DSDELETE, &withdrawn); 21384 21385 if (ds_state == DST_KEY_STATE_RUMOURED && published == 0) { 21386 dst_key_setnum(key->key, DST_NUM_DSPUBCOUNT, 0); 21387 cdscheck = true; 21388 } else if (ds_state == DST_KEY_STATE_UNRETENTIVE && 21389 withdrawn == 0) 21390 { 21391 dst_key_setnum(key->key, DST_NUM_DSDELCOUNT, 0); 21392 cdscheck = true; 21393 } 21394 } 21395 21396 if (cdscheck) { 21397 /* Request the DS RRset. */ 21398 LOCK_ZONE(zone); 21399 checkds_send(zone); 21400 UNLOCK_ZONE(zone); 21401 } 21402} 21403 21404static void 21405zone_rekey(dns_zone_t *zone) { 21406 isc_result_t result; 21407 dns_db_t *db = NULL; 21408 dns_dbnode_t *node = NULL; 21409 dns_dbversion_t *ver = NULL; 21410 dns_rdataset_t cdsset, soaset, soasigs, keyset, keysigs, cdnskeyset; 21411 dns_dnsseckeylist_t dnskeys, keys, rmkeys; 21412 dns_dnsseckey_t *key = NULL; 21413 dns_diff_t diff, _sig_diff; 21414 dns_kasp_t *kasp; 21415 dns__zonediff_t zonediff; 21416 bool commit = false, newactive = false; 21417 bool newalg = false; 21418 bool fullsign; 21419 dns_ttl_t ttl = 3600; 21420 const char *dir = NULL; 21421 isc_mem_t *mctx = NULL; 21422 isc_stdtime_t now, nexttime = 0; 21423 isc_time_t timenow; 21424 isc_interval_t ival; 21425 char timebuf[80]; 21426 21427 REQUIRE(DNS_ZONE_VALID(zone)); 21428 21429 ISC_LIST_INIT(dnskeys); 21430 ISC_LIST_INIT(keys); 21431 ISC_LIST_INIT(rmkeys); 21432 dns_rdataset_init(&soaset); 21433 dns_rdataset_init(&soasigs); 21434 dns_rdataset_init(&keyset); 21435 dns_rdataset_init(&keysigs); 21436 dns_rdataset_init(&cdsset); 21437 dns_rdataset_init(&cdnskeyset); 21438 dir = dns_zone_getkeydirectory(zone); 21439 mctx = zone->mctx; 21440 dns_diff_init(mctx, &diff); 21441 dns_diff_init(mctx, &_sig_diff); 21442 zonediff_init(&zonediff, &_sig_diff); 21443 21444 CHECK(dns_zone_getdb(zone, &db)); 21445 CHECK(dns_db_newversion(db, &ver)); 21446 CHECK(dns_db_getoriginnode(db, &node)); 21447 21448 TIME_NOW(&timenow); 21449 now = isc_time_seconds(&timenow); 21450 21451 kasp = dns_zone_getkasp(zone); 21452 21453 dnssec_log(zone, ISC_LOG_INFO, "reconfiguring zone keys"); 21454 21455 /* Get the SOA record's TTL */ 21456 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 21457 dns_rdatatype_none, 0, &soaset, &soasigs)); 21458 ttl = soaset.ttl; 21459 dns_rdataset_disassociate(&soaset); 21460 21461 /* Get the DNSKEY rdataset */ 21462 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 21463 dns_rdatatype_none, 0, &keyset, &keysigs); 21464 if (result == ISC_R_SUCCESS) { 21465 ttl = keyset.ttl; 21466 21467 dns_zone_lock_keyfiles(zone); 21468 21469 result = dns_dnssec_keylistfromrdataset( 21470 &zone->origin, dir, mctx, &keyset, &keysigs, &soasigs, 21471 false, false, &dnskeys); 21472 21473 dns_zone_unlock_keyfiles(zone); 21474 21475 if (result != ISC_R_SUCCESS) { 21476 goto failure; 21477 } 21478 } else if (result != ISC_R_NOTFOUND) { 21479 goto failure; 21480 } 21481 21482 /* Get the CDS rdataset */ 21483 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cds, 21484 dns_rdatatype_none, 0, &cdsset, NULL); 21485 if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdsset)) { 21486 dns_rdataset_disassociate(&cdsset); 21487 } 21488 21489 /* Get the CDNSKEY rdataset */ 21490 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cdnskey, 21491 dns_rdatatype_none, 0, &cdnskeyset, NULL); 21492 if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdnskeyset)) { 21493 dns_rdataset_disassociate(&cdnskeyset); 21494 } 21495 21496 /* 21497 * True when called from "rndc sign". Indicates the zone should be 21498 * fully signed now. 21499 */ 21500 fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN); 21501 21502 KASP_LOCK(kasp); 21503 21504 dns_zone_lock_keyfiles(zone); 21505 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, now, mctx, 21506 &keys); 21507 dns_zone_unlock_keyfiles(zone); 21508 21509 if (result != ISC_R_SUCCESS) { 21510 dnssec_log(zone, ISC_LOG_DEBUG(1), 21511 "zone_rekey:dns_dnssec_findmatchingkeys failed: %s", 21512 isc_result_totext(result)); 21513 } 21514 21515 if (kasp != NULL) { 21516 /* 21517 * Check DS at parental agents. Clear ongoing checks. 21518 */ 21519 LOCK_ZONE(zone); 21520 checkds_cancel(zone); 21521 clear_keylist(&zone->checkds_ok, zone->mctx); 21522 ISC_LIST_INIT(zone->checkds_ok); 21523 UNLOCK_ZONE(zone); 21524 21525 result = dns_zone_getdnsseckeys(zone, db, ver, now, 21526 &zone->checkds_ok); 21527 21528 if (result == ISC_R_SUCCESS) { 21529 zone_checkds(zone); 21530 } else { 21531 dnssec_log(zone, 21532 (result == ISC_R_NOTFOUND) ? ISC_LOG_DEBUG(1) 21533 : ISC_LOG_ERROR, 21534 "zone_rekey:dns_zone_getdnsseckeys failed: " 21535 "%s", 21536 isc_result_totext(result)); 21537 } 21538 21539 if (result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND) { 21540 dns_zone_lock_keyfiles(zone); 21541 result = dns_keymgr_run(&zone->origin, zone->rdclass, 21542 dir, mctx, &keys, &dnskeys, 21543 kasp, now, &nexttime); 21544 dns_zone_unlock_keyfiles(zone); 21545 21546 if (result != ISC_R_SUCCESS) { 21547 dnssec_log(zone, ISC_LOG_ERROR, 21548 "zone_rekey:dns_dnssec_keymgr " 21549 "failed: %s", 21550 isc_result_totext(result)); 21551 KASP_UNLOCK(kasp); 21552 goto failure; 21553 } 21554 } 21555 } 21556 21557 KASP_UNLOCK(kasp); 21558 21559 if (result == ISC_R_SUCCESS) { 21560 bool cdsdel = false; 21561 bool cdnskeydel = false; 21562 isc_stdtime_t when; 21563 21564 /* 21565 * Publish CDS/CDNSKEY DELETE records if the zone is 21566 * transitioning from secure to insecure. 21567 */ 21568 if (kasp != NULL) { 21569 if (strcmp(dns_kasp_getname(kasp), "insecure") == 0) { 21570 cdsdel = true; 21571 cdnskeydel = true; 21572 } 21573 } else { 21574 /* Check if there is a CDS DELETE record. */ 21575 if (dns_rdataset_isassociated(&cdsset)) { 21576 for (result = dns_rdataset_first(&cdsset); 21577 result == ISC_R_SUCCESS; 21578 result = dns_rdataset_next(&cdsset)) 21579 { 21580 dns_rdata_t crdata = DNS_RDATA_INIT; 21581 dns_rdataset_current(&cdsset, &crdata); 21582 /* 21583 * CDS deletion record has this form 21584 * "0 0 0 00" which is 5 zero octets. 21585 */ 21586 if (crdata.length == 5U && 21587 memcmp(crdata.data, 21588 (unsigned char[5]){ 0, 0, 0, 21589 0, 0 }, 21590 5) == 0) 21591 { 21592 cdsdel = true; 21593 break; 21594 } 21595 } 21596 } 21597 21598 /* Check if there is a CDNSKEY DELETE record. */ 21599 if (dns_rdataset_isassociated(&cdnskeyset)) { 21600 for (result = dns_rdataset_first(&cdnskeyset); 21601 result == ISC_R_SUCCESS; 21602 result = dns_rdataset_next(&cdnskeyset)) 21603 { 21604 dns_rdata_t crdata = DNS_RDATA_INIT; 21605 dns_rdataset_current(&cdnskeyset, 21606 &crdata); 21607 /* 21608 * CDNSKEY deletion record has this form 21609 * "0 3 0 AA==" which is 2 zero octets, 21610 * a 3, and 2 zero octets. 21611 */ 21612 if (crdata.length == 5U && 21613 memcmp(crdata.data, 21614 (unsigned char[5]){ 0, 0, 3, 21615 0, 0 }, 21616 5) == 0) 21617 { 21618 cdnskeydel = true; 21619 break; 21620 } 21621 } 21622 } 21623 } 21624 21625 /* 21626 * Only update DNSKEY TTL if we have a policy. 21627 */ 21628 if (kasp != NULL) { 21629 ttl = dns_kasp_dnskeyttl(kasp); 21630 } 21631 21632 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys, 21633 &zone->origin, ttl, &diff, mctx, 21634 dnssec_report); 21635 /* 21636 * Keys couldn't be updated for some reason; 21637 * try again later. 21638 */ 21639 if (result != ISC_R_SUCCESS) { 21640 dnssec_log(zone, ISC_LOG_ERROR, 21641 "zone_rekey:couldn't update zone keys: %s", 21642 isc_result_totext(result)); 21643 goto failure; 21644 } 21645 21646 /* 21647 * Update CDS / CDNSKEY records. 21648 */ 21649 result = dns_dnssec_syncupdate(&dnskeys, &rmkeys, &cdsset, 21650 &cdnskeyset, now, ttl, &diff, 21651 mctx); 21652 if (result != ISC_R_SUCCESS) { 21653 dnssec_log(zone, ISC_LOG_ERROR, 21654 "zone_rekey:couldn't update CDS/CDNSKEY: %s", 21655 isc_result_totext(result)); 21656 goto failure; 21657 } 21658 21659 if (cdsdel || cdnskeydel) { 21660 /* 21661 * Only publish CDS/CDNSKEY DELETE records if there is 21662 * a KSK that can be used to verify the RRset. This 21663 * means there must be a key with the KSK role that is 21664 * published and is used for signing. 21665 */ 21666 bool allow = false; 21667 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 21668 key = ISC_LIST_NEXT(key, link)) 21669 { 21670 dst_key_t *dstk = key->key; 21671 21672 if (dst_key_is_published(dstk, now, &when) && 21673 dst_key_is_signing(dstk, DST_BOOL_KSK, now, 21674 &when)) 21675 { 21676 allow = true; 21677 break; 21678 } 21679 } 21680 if (cdsdel) { 21681 cdsdel = allow; 21682 } 21683 if (cdnskeydel) { 21684 cdnskeydel = allow; 21685 } 21686 } 21687 result = dns_dnssec_syncdelete( 21688 &cdsset, &cdnskeyset, &zone->origin, zone->rdclass, ttl, 21689 &diff, mctx, cdsdel, cdnskeydel); 21690 if (result != ISC_R_SUCCESS) { 21691 dnssec_log(zone, ISC_LOG_ERROR, 21692 "zone_rekey:couldn't update CDS/CDNSKEY " 21693 "DELETE records: %s", 21694 isc_result_totext(result)); 21695 goto failure; 21696 } 21697 21698 /* 21699 * See if any pre-existing keys have newly become active; 21700 * also, see if any new key is for a new algorithm, as in that 21701 * event, we need to sign the zone fully. (If there's a new 21702 * key, but it's for an already-existing algorithm, then 21703 * the zone signing can be handled incrementally.) 21704 */ 21705 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 21706 key = ISC_LIST_NEXT(key, link)) 21707 { 21708 if (!key->first_sign) { 21709 continue; 21710 } 21711 21712 newactive = true; 21713 21714 if (!dns_rdataset_isassociated(&keysigs)) { 21715 newalg = true; 21716 break; 21717 } 21718 21719 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) { 21720 /* 21721 * This isn't a new algorithm; clear 21722 * first_sign so we won't sign the 21723 * whole zone with this key later. 21724 */ 21725 key->first_sign = false; 21726 } else { 21727 newalg = true; 21728 break; 21729 } 21730 } 21731 21732 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) && 21733 dnskey_sane(zone, db, ver, &diff)) 21734 { 21735 CHECK(dns_diff_apply(&diff, db, ver)); 21736 CHECK(clean_nsec3param(zone, db, ver, &diff)); 21737 CHECK(add_signing_records(db, zone->privatetype, ver, 21738 &diff, (newalg || fullsign))); 21739 CHECK(update_soa_serial(zone, db, ver, &diff, mctx, 21740 zone->updatemethod)); 21741 CHECK(add_chains(zone, db, ver, &diff)); 21742 CHECK(sign_apex(zone, db, ver, now, &diff, &zonediff)); 21743 CHECK(zone_journal(zone, zonediff.diff, NULL, 21744 "zone_rekey")); 21745 commit = true; 21746 } 21747 } 21748 21749 dns_db_closeversion(db, &ver, true); 21750 21751 LOCK_ZONE(zone); 21752 21753 if (commit) { 21754 dns_difftuple_t *tuple; 21755 dns_stats_t *dnssecsignstats = 21756 dns_zone_getdnssecsignstats(zone); 21757 21758 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 21759 21760 zone_needdump(zone, DNS_DUMP_DELAY); 21761 21762 zone_settimer(zone, &timenow); 21763 21764 /* Remove any signatures from removed keys. */ 21765 if (!ISC_LIST_EMPTY(rmkeys)) { 21766 for (key = ISC_LIST_HEAD(rmkeys); key != NULL; 21767 key = ISC_LIST_NEXT(key, link)) 21768 { 21769 result = zone_signwithkey( 21770 zone, dst_key_alg(key->key), 21771 dst_key_id(key->key), true); 21772 if (result != ISC_R_SUCCESS) { 21773 dnssec_log(zone, ISC_LOG_ERROR, 21774 "zone_signwithkey failed: " 21775 "%s", 21776 dns_result_totext(result)); 21777 } 21778 21779 /* Clear DNSSEC sign statistics. */ 21780 if (dnssecsignstats != NULL) { 21781 dns_dnssecsignstats_clear( 21782 dnssecsignstats, 21783 dst_key_id(key->key), 21784 dst_key_alg(key->key)); 21785 /* 21786 * Also clear the dnssec-sign 21787 * statistics of the revoked key id. 21788 */ 21789 dns_dnssecsignstats_clear( 21790 dnssecsignstats, 21791 dst_key_rid(key->key), 21792 dst_key_alg(key->key)); 21793 } 21794 } 21795 } 21796 21797 if (fullsign) { 21798 /* 21799 * "rndc sign" was called, so we now sign the zone 21800 * with all active keys, whether they're new or not. 21801 */ 21802 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 21803 key = ISC_LIST_NEXT(key, link)) 21804 { 21805 if (!key->force_sign && !key->hint_sign) { 21806 continue; 21807 } 21808 21809 result = zone_signwithkey( 21810 zone, dst_key_alg(key->key), 21811 dst_key_id(key->key), false); 21812 if (result != ISC_R_SUCCESS) { 21813 dnssec_log(zone, ISC_LOG_ERROR, 21814 "zone_signwithkey failed: " 21815 "%s", 21816 dns_result_totext(result)); 21817 } 21818 } 21819 } else if (newalg) { 21820 /* 21821 * We haven't been told to sign fully, but a new 21822 * algorithm was added to the DNSKEY. We sign 21823 * the full zone, but only with newly active 21824 * keys. 21825 */ 21826 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 21827 key = ISC_LIST_NEXT(key, link)) 21828 { 21829 if (!key->first_sign) { 21830 continue; 21831 } 21832 21833 result = zone_signwithkey( 21834 zone, dst_key_alg(key->key), 21835 dst_key_id(key->key), false); 21836 if (result != ISC_R_SUCCESS) { 21837 dnssec_log(zone, ISC_LOG_ERROR, 21838 "zone_signwithkey failed: " 21839 "%s", 21840 dns_result_totext(result)); 21841 } 21842 } 21843 } 21844 21845 /* 21846 * Clear fullsign flag, if it was set, so we don't do 21847 * another full signing next time. 21848 */ 21849 DNS_ZONEKEY_CLROPTION(zone, DNS_ZONEKEY_FULLSIGN); 21850 21851 /* 21852 * Cause the zone to add/delete NSEC3 chains for the 21853 * deferred NSEC3PARAM changes. 21854 */ 21855 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples); 21856 tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) 21857 { 21858 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 21859 dns_rdata_t rdata = DNS_RDATA_INIT; 21860 dns_rdata_nsec3param_t nsec3param; 21861 21862 if (tuple->rdata.type != zone->privatetype || 21863 tuple->op != DNS_DIFFOP_ADD) 21864 { 21865 continue; 21866 } 21867 21868 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata, 21869 buf, sizeof(buf))) 21870 { 21871 continue; 21872 } 21873 21874 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 21875 RUNTIME_CHECK(result == ISC_R_SUCCESS); 21876 if (nsec3param.flags == 0) { 21877 continue; 21878 } 21879 21880 result = zone_addnsec3chain(zone, &nsec3param); 21881 if (result != ISC_R_SUCCESS) { 21882 dnssec_log(zone, ISC_LOG_ERROR, 21883 "zone_addnsec3chain failed: %s", 21884 dns_result_totext(result)); 21885 } 21886 } 21887 21888 /* 21889 * Activate any NSEC3 chain updates that may have 21890 * been scheduled before this rekey. 21891 */ 21892 if (fullsign || newalg) { 21893 resume_addnsec3chain(zone); 21894 } 21895 21896 /* 21897 * Schedule the next resigning event 21898 */ 21899 set_resigntime(zone); 21900 } 21901 21902 isc_time_settoepoch(&zone->refreshkeytime); 21903 21904 /* 21905 * If keymgr provided a next time, use the calculated next rekey time. 21906 */ 21907 if (kasp != NULL) { 21908 isc_time_t timenext; 21909 uint32_t nexttime_seconds; 21910 21911 /* 21912 * Set the key refresh timer to the next scheduled key event 21913 * or to 'dnssec-loadkeys-interval' seconds in the future 21914 * if no next key event is scheduled (nexttime == 0). 21915 */ 21916 if (nexttime > 0) { 21917 nexttime_seconds = nexttime - now; 21918 } else { 21919 nexttime_seconds = zone->refreshkeyinterval; 21920 } 21921 21922 DNS_ZONE_TIME_ADD(&timenow, nexttime_seconds, &timenext); 21923 zone->refreshkeytime = timenext; 21924 zone_settimer(zone, &timenow); 21925 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 21926 21927 dnssec_log(zone, ISC_LOG_DEBUG(3), 21928 "next key event in %u seconds", nexttime_seconds); 21929 dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); 21930 } 21931 /* 21932 * If we're doing key maintenance, set the key refresh timer to 21933 * the next scheduled key event or to 'dnssec-loadkeys-interval' 21934 * seconds in the future, whichever is sooner. 21935 */ 21936 else if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 21937 { 21938 isc_time_t timethen; 21939 isc_stdtime_t then; 21940 21941 DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval, 21942 &timethen); 21943 zone->refreshkeytime = timethen; 21944 21945 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 21946 key = ISC_LIST_NEXT(key, link)) 21947 { 21948 then = now; 21949 result = next_keyevent(key->key, &then); 21950 if (result != ISC_R_SUCCESS) { 21951 continue; 21952 } 21953 21954 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 21955 if (isc_time_compare(&timethen, &zone->refreshkeytime) < 21956 0) 21957 { 21958 zone->refreshkeytime = timethen; 21959 } 21960 } 21961 21962 zone_settimer(zone, &timenow); 21963 21964 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 21965 dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); 21966 } 21967 UNLOCK_ZONE(zone); 21968 21969 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 21970 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 21971 key = ISC_LIST_NEXT(key, link)) 21972 { 21973 /* This debug log is used in the kasp system test */ 21974 char algbuf[DNS_SECALG_FORMATSIZE]; 21975 dns_secalg_format(dst_key_alg(key->key), algbuf, 21976 sizeof(algbuf)); 21977 dnssec_log(zone, ISC_LOG_DEBUG(3), 21978 "zone_rekey done: key %d/%s", 21979 dst_key_id(key->key), algbuf); 21980 } 21981 } 21982 21983 result = ISC_R_SUCCESS; 21984 21985failure: 21986 LOCK_ZONE(zone); 21987 if (result != ISC_R_SUCCESS) { 21988 /* 21989 * Something went wrong; try again in ten minutes or 21990 * after a key refresh interval, whichever is shorter. 21991 */ 21992 dnssec_log(zone, ISC_LOG_DEBUG(3), 21993 "zone_rekey failure: %s (retry in %u seconds)", 21994 isc_result_totext(result), 21995 ISC_MIN(zone->refreshkeyinterval, 600)); 21996 isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 21997 0); 21998 isc_time_nowplusinterval(&zone->refreshkeytime, &ival); 21999 } 22000 UNLOCK_ZONE(zone); 22001 22002 dns_diff_clear(&diff); 22003 dns_diff_clear(&_sig_diff); 22004 22005 clear_keylist(&dnskeys, mctx); 22006 clear_keylist(&keys, mctx); 22007 clear_keylist(&rmkeys, mctx); 22008 22009 if (ver != NULL) { 22010 dns_db_closeversion(db, &ver, false); 22011 } 22012 if (dns_rdataset_isassociated(&cdsset)) { 22013 dns_rdataset_disassociate(&cdsset); 22014 } 22015 if (dns_rdataset_isassociated(&keyset)) { 22016 dns_rdataset_disassociate(&keyset); 22017 } 22018 if (dns_rdataset_isassociated(&keysigs)) { 22019 dns_rdataset_disassociate(&keysigs); 22020 } 22021 if (dns_rdataset_isassociated(&soasigs)) { 22022 dns_rdataset_disassociate(&soasigs); 22023 } 22024 if (dns_rdataset_isassociated(&cdnskeyset)) { 22025 dns_rdataset_disassociate(&cdnskeyset); 22026 } 22027 if (node != NULL) { 22028 dns_db_detachnode(db, &node); 22029 } 22030 if (db != NULL) { 22031 dns_db_detach(&db); 22032 } 22033 22034 INSIST(ver == NULL); 22035} 22036 22037void 22038dns_zone_rekey(dns_zone_t *zone, bool fullsign) { 22039 isc_time_t now; 22040 22041 if (zone->type == dns_zone_primary && zone->task != NULL) { 22042 LOCK_ZONE(zone); 22043 22044 if (fullsign) { 22045 DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN); 22046 } 22047 22048 TIME_NOW(&now); 22049 zone->refreshkeytime = now; 22050 zone_settimer(zone, &now); 22051 22052 UNLOCK_ZONE(zone); 22053 } 22054} 22055 22056isc_result_t 22057dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 22058 unsigned int *errors) { 22059 isc_result_t result; 22060 dns_dbnode_t *node = NULL; 22061 22062 REQUIRE(DNS_ZONE_VALID(zone)); 22063 REQUIRE(errors != NULL); 22064 22065 result = dns_db_getoriginnode(db, &node); 22066 if (result != ISC_R_SUCCESS) { 22067 return (result); 22068 } 22069 result = zone_count_ns_rr(zone, db, node, version, NULL, errors, false); 22070 dns_db_detachnode(db, &node); 22071 return (result); 22072} 22073 22074isc_result_t 22075dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { 22076 isc_result_t result; 22077 dns_dbnode_t *node = NULL; 22078 dns_rdataset_t dnskey, cds, cdnskey; 22079 unsigned char algorithms[256]; 22080 unsigned int i; 22081 bool empty = false; 22082 22083 enum { notexpected = 0, expected = 1, found = 2 }; 22084 22085 REQUIRE(DNS_ZONE_VALID(zone)); 22086 22087 result = dns_db_getoriginnode(db, &node); 22088 if (result != ISC_R_SUCCESS) { 22089 return (result); 22090 } 22091 22092 dns_rdataset_init(&cds); 22093 dns_rdataset_init(&dnskey); 22094 dns_rdataset_init(&cdnskey); 22095 22096 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds, 22097 dns_rdatatype_none, 0, &cds, NULL); 22098 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 22099 goto failure; 22100 } 22101 22102 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey, 22103 dns_rdatatype_none, 0, &cdnskey, NULL); 22104 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 22105 goto failure; 22106 } 22107 22108 if (!dns_rdataset_isassociated(&cds) && 22109 !dns_rdataset_isassociated(&cdnskey)) 22110 { 22111 result = ISC_R_SUCCESS; 22112 goto failure; 22113 } 22114 22115 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 22116 dns_rdatatype_none, 0, &dnskey, NULL); 22117 if (result == ISC_R_NOTFOUND) { 22118 empty = true; 22119 } else if (result != ISC_R_SUCCESS) { 22120 goto failure; 22121 } 22122 22123 /* 22124 * For each DNSSEC algorithm in the CDS RRset there must be 22125 * a matching DNSKEY record with the exception of a CDS deletion 22126 * record which must be by itself. 22127 */ 22128 if (dns_rdataset_isassociated(&cds)) { 22129 bool delete = false; 22130 memset(algorithms, notexpected, sizeof(algorithms)); 22131 for (result = dns_rdataset_first(&cds); result == ISC_R_SUCCESS; 22132 result = dns_rdataset_next(&cds)) 22133 { 22134 dns_rdata_t crdata = DNS_RDATA_INIT; 22135 dns_rdata_cds_t structcds; 22136 22137 dns_rdataset_current(&cds, &crdata); 22138 /* 22139 * CDS deletion record has this form "0 0 0 00" which 22140 * is 5 zero octets. 22141 */ 22142 if (crdata.length == 5U && 22143 memcmp(crdata.data, 22144 (unsigned char[5]){ 0, 0, 0, 0, 0 }, 5) == 0) 22145 { 22146 delete = true; 22147 continue; 22148 } 22149 22150 if (empty) { 22151 result = DNS_R_BADCDS; 22152 goto failure; 22153 } 22154 22155 CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL)); 22156 if (algorithms[structcds.algorithm] == 0) { 22157 algorithms[structcds.algorithm] = expected; 22158 } 22159 for (result = dns_rdataset_first(&dnskey); 22160 result == ISC_R_SUCCESS; 22161 result = dns_rdataset_next(&dnskey)) 22162 { 22163 dns_rdata_t rdata = DNS_RDATA_INIT; 22164 dns_rdata_dnskey_t structdnskey; 22165 22166 dns_rdataset_current(&dnskey, &rdata); 22167 CHECK(dns_rdata_tostruct(&rdata, &structdnskey, 22168 NULL)); 22169 22170 if (structdnskey.algorithm == 22171 structcds.algorithm) 22172 { 22173 algorithms[structcds.algorithm] = found; 22174 } 22175 } 22176 if (result != ISC_R_NOMORE) { 22177 goto failure; 22178 } 22179 } 22180 for (i = 0; i < sizeof(algorithms); i++) { 22181 if (delete) { 22182 if (algorithms[i] != notexpected) { 22183 result = DNS_R_BADCDS; 22184 goto failure; 22185 } 22186 } else if (algorithms[i] == expected) { 22187 result = DNS_R_BADCDS; 22188 goto failure; 22189 } 22190 } 22191 } 22192 22193 /* 22194 * For each DNSSEC algorithm in the CDNSKEY RRset there must be 22195 * a matching DNSKEY record with the exception of a CDNSKEY deletion 22196 * record which must be by itself. 22197 */ 22198 if (dns_rdataset_isassociated(&cdnskey)) { 22199 bool delete = false; 22200 memset(algorithms, notexpected, sizeof(algorithms)); 22201 for (result = dns_rdataset_first(&cdnskey); 22202 result == ISC_R_SUCCESS; 22203 result = dns_rdataset_next(&cdnskey)) 22204 { 22205 dns_rdata_t crdata = DNS_RDATA_INIT; 22206 dns_rdata_cdnskey_t structcdnskey; 22207 22208 dns_rdataset_current(&cdnskey, &crdata); 22209 /* 22210 * CDNSKEY deletion record has this form 22211 * "0 3 0 AA==" which is 2 zero octets, a 3, 22212 * and 2 zero octets. 22213 */ 22214 if (crdata.length == 5U && 22215 memcmp(crdata.data, 22216 (unsigned char[5]){ 0, 0, 3, 0, 0 }, 5) == 0) 22217 { 22218 delete = true; 22219 continue; 22220 } 22221 22222 if (empty) { 22223 result = DNS_R_BADCDNSKEY; 22224 goto failure; 22225 } 22226 22227 CHECK(dns_rdata_tostruct(&crdata, &structcdnskey, 22228 NULL)); 22229 if (algorithms[structcdnskey.algorithm] == 0) { 22230 algorithms[structcdnskey.algorithm] = expected; 22231 } 22232 for (result = dns_rdataset_first(&dnskey); 22233 result == ISC_R_SUCCESS; 22234 result = dns_rdataset_next(&dnskey)) 22235 { 22236 dns_rdata_t rdata = DNS_RDATA_INIT; 22237 dns_rdata_dnskey_t structdnskey; 22238 22239 dns_rdataset_current(&dnskey, &rdata); 22240 CHECK(dns_rdata_tostruct(&rdata, &structdnskey, 22241 NULL)); 22242 22243 if (structdnskey.algorithm == 22244 structcdnskey.algorithm) 22245 { 22246 algorithms[structcdnskey.algorithm] = 22247 found; 22248 } 22249 } 22250 if (result != ISC_R_NOMORE) { 22251 goto failure; 22252 } 22253 } 22254 for (i = 0; i < sizeof(algorithms); i++) { 22255 if (delete) { 22256 if (algorithms[i] != notexpected) { 22257 result = DNS_R_BADCDNSKEY; 22258 goto failure; 22259 } 22260 } else if (algorithms[i] == expected) { 22261 result = DNS_R_BADCDNSKEY; 22262 goto failure; 22263 } 22264 } 22265 } 22266 result = ISC_R_SUCCESS; 22267 22268failure: 22269 if (dns_rdataset_isassociated(&cds)) { 22270 dns_rdataset_disassociate(&cds); 22271 } 22272 if (dns_rdataset_isassociated(&dnskey)) { 22273 dns_rdataset_disassociate(&dnskey); 22274 } 22275 if (dns_rdataset_isassociated(&cdnskey)) { 22276 dns_rdataset_disassociate(&cdnskey); 22277 } 22278 dns_db_detachnode(db, &node); 22279 return (result); 22280} 22281 22282void 22283dns_zone_setautomatic(dns_zone_t *zone, bool automatic) { 22284 REQUIRE(DNS_ZONE_VALID(zone)); 22285 22286 LOCK_ZONE(zone); 22287 zone->automatic = automatic; 22288 UNLOCK_ZONE(zone); 22289} 22290 22291bool 22292dns_zone_getautomatic(dns_zone_t *zone) { 22293 REQUIRE(DNS_ZONE_VALID(zone)); 22294 return (zone->automatic); 22295} 22296 22297void 22298dns_zone_setadded(dns_zone_t *zone, bool added) { 22299 REQUIRE(DNS_ZONE_VALID(zone)); 22300 22301 LOCK_ZONE(zone); 22302 zone->added = added; 22303 UNLOCK_ZONE(zone); 22304} 22305 22306bool 22307dns_zone_getadded(dns_zone_t *zone) { 22308 REQUIRE(DNS_ZONE_VALID(zone)); 22309 return (zone->added); 22310} 22311 22312isc_result_t 22313dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db) { 22314 isc_time_t loadtime; 22315 isc_result_t result; 22316 dns_zone_t *secure = NULL; 22317 22318 TIME_NOW(&loadtime); 22319 22320 /* 22321 * Lock hierarchy: zmgr, zone, raw. 22322 */ 22323again: 22324 LOCK_ZONE(zone); 22325 INSIST(zone != zone->raw); 22326 if (inline_secure(zone)) { 22327 LOCK_ZONE(zone->raw); 22328 } else if (inline_raw(zone)) { 22329 secure = zone->secure; 22330 TRYLOCK_ZONE(result, secure); 22331 if (result != ISC_R_SUCCESS) { 22332 UNLOCK_ZONE(zone); 22333 secure = NULL; 22334 isc_thread_yield(); 22335 goto again; 22336 } 22337 } 22338 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 22339 if (inline_secure(zone)) { 22340 UNLOCK_ZONE(zone->raw); 22341 } else if (secure != NULL) { 22342 UNLOCK_ZONE(secure); 22343 } 22344 UNLOCK_ZONE(zone); 22345 return (result); 22346} 22347 22348isc_result_t 22349dns_zone_setrefreshkeyinterval(dns_zone_t *zone, uint32_t interval) { 22350 REQUIRE(DNS_ZONE_VALID(zone)); 22351 if (interval == 0) { 22352 return (ISC_R_RANGE); 22353 } 22354 /* Maximum value: 24 hours (3600 minutes) */ 22355 if (interval > (24 * 60)) { 22356 interval = (24 * 60); 22357 } 22358 /* Multiply by 60 for seconds */ 22359 zone->refreshkeyinterval = interval * 60; 22360 return (ISC_R_SUCCESS); 22361} 22362 22363void 22364dns_zone_setrequestixfr(dns_zone_t *zone, bool flag) { 22365 REQUIRE(DNS_ZONE_VALID(zone)); 22366 zone->requestixfr = flag; 22367} 22368 22369bool 22370dns_zone_getrequestixfr(dns_zone_t *zone) { 22371 REQUIRE(DNS_ZONE_VALID(zone)); 22372 return (zone->requestixfr); 22373} 22374 22375void 22376dns_zone_setixfrratio(dns_zone_t *zone, uint32_t ratio) { 22377 REQUIRE(DNS_ZONE_VALID(zone)); 22378 zone->ixfr_ratio = ratio; 22379} 22380 22381uint32_t 22382dns_zone_getixfrratio(dns_zone_t *zone) { 22383 REQUIRE(DNS_ZONE_VALID(zone)); 22384 return (zone->ixfr_ratio); 22385} 22386 22387void 22388dns_zone_setrequestexpire(dns_zone_t *zone, bool flag) { 22389 REQUIRE(DNS_ZONE_VALID(zone)); 22390 zone->requestexpire = flag; 22391} 22392 22393bool 22394dns_zone_getrequestexpire(dns_zone_t *zone) { 22395 REQUIRE(DNS_ZONE_VALID(zone)); 22396 return (zone->requestexpire); 22397} 22398 22399void 22400dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) { 22401 REQUIRE(DNS_ZONE_VALID(zone)); 22402 zone->updatemethod = method; 22403} 22404 22405dns_updatemethod_t 22406dns_zone_getserialupdatemethod(dns_zone_t *zone) { 22407 REQUIRE(DNS_ZONE_VALID(zone)); 22408 return (zone->updatemethod); 22409} 22410 22411/* 22412 * Lock hierarchy: zmgr, zone, raw. 22413 */ 22414isc_result_t 22415dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) { 22416 isc_result_t result; 22417 dns_zonemgr_t *zmgr; 22418 22419 REQUIRE(DNS_ZONE_VALID(zone)); 22420 REQUIRE(zone->zmgr != NULL); 22421 REQUIRE(zone->task != NULL); 22422 REQUIRE(zone->loadtask != NULL); 22423 REQUIRE(zone->raw == NULL); 22424 22425 REQUIRE(DNS_ZONE_VALID(raw)); 22426 REQUIRE(raw->zmgr == NULL); 22427 REQUIRE(raw->task == NULL); 22428 REQUIRE(raw->loadtask == NULL); 22429 REQUIRE(raw->secure == NULL); 22430 22431 REQUIRE(zone != raw); 22432 22433 /* 22434 * Lock hierarchy: zmgr, zone, raw. 22435 */ 22436 zmgr = zone->zmgr; 22437 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 22438 LOCK_ZONE(zone); 22439 LOCK_ZONE(raw); 22440 22441 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL, 22442 NULL, zone->task, zone_timer, raw, 22443 &raw->timer); 22444 if (result != ISC_R_SUCCESS) { 22445 goto unlock; 22446 } 22447 22448 /* 22449 * The timer "holds" a iref. 22450 */ 22451 isc_refcount_increment0(&raw->irefs); 22452 22453 /* dns_zone_attach(raw, &zone->raw); */ 22454 isc_refcount_increment(&raw->erefs); 22455 zone->raw = raw; 22456 22457 /* dns_zone_iattach(zone, &raw->secure); */ 22458 zone_iattach(zone, &raw->secure); 22459 22460 isc_task_attach(zone->task, &raw->task); 22461 isc_task_attach(zone->loadtask, &raw->loadtask); 22462 22463 ISC_LIST_APPEND(zmgr->zones, raw, link); 22464 raw->zmgr = zmgr; 22465 isc_refcount_increment(&zmgr->refs); 22466 22467unlock: 22468 UNLOCK_ZONE(raw); 22469 UNLOCK_ZONE(zone); 22470 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 22471 return (result); 22472} 22473 22474void 22475dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) { 22476 REQUIRE(DNS_ZONE_VALID(zone)); 22477 REQUIRE(raw != NULL && *raw == NULL); 22478 22479 LOCK(&zone->lock); 22480 INSIST(zone != zone->raw); 22481 if (zone->raw != NULL) { 22482 dns_zone_attach(zone->raw, raw); 22483 } 22484 UNLOCK(&zone->lock); 22485} 22486 22487struct keydone { 22488 isc_event_t event; 22489 bool all; 22490 unsigned char data[5]; 22491}; 22492 22493#define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL) 22494 22495static void 22496keydone(isc_task_t *task, isc_event_t *event) { 22497 const char *me = "keydone"; 22498 bool commit = false; 22499 isc_result_t result; 22500 dns_rdata_t rdata = DNS_RDATA_INIT; 22501 dns_dbversion_t *oldver = NULL, *newver = NULL; 22502 dns_zone_t *zone; 22503 dns_db_t *db = NULL; 22504 dns_dbnode_t *node = NULL; 22505 dns_rdataset_t rdataset; 22506 dns_diff_t diff; 22507 struct keydone *kd = (struct keydone *)event; 22508 dns_update_log_t log = { update_log_cb, NULL }; 22509 bool clear_pending = false; 22510 22511 UNUSED(task); 22512 22513 zone = event->ev_arg; 22514 INSIST(DNS_ZONE_VALID(zone)); 22515 22516 ENTER; 22517 22518 dns_rdataset_init(&rdataset); 22519 dns_diff_init(zone->mctx, &diff); 22520 22521 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 22522 if (zone->db != NULL) { 22523 dns_db_attach(zone->db, &db); 22524 } 22525 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 22526 if (db == NULL) { 22527 goto failure; 22528 } 22529 22530 dns_db_currentversion(db, &oldver); 22531 result = dns_db_newversion(db, &newver); 22532 if (result != ISC_R_SUCCESS) { 22533 dnssec_log(zone, ISC_LOG_ERROR, 22534 "keydone:dns_db_newversion -> %s", 22535 dns_result_totext(result)); 22536 goto failure; 22537 } 22538 22539 result = dns_db_getoriginnode(db, &node); 22540 if (result != ISC_R_SUCCESS) { 22541 goto failure; 22542 } 22543 22544 result = dns_db_findrdataset(db, node, newver, zone->privatetype, 22545 dns_rdatatype_none, 0, &rdataset, NULL); 22546 if (result == ISC_R_NOTFOUND) { 22547 INSIST(!dns_rdataset_isassociated(&rdataset)); 22548 goto failure; 22549 } 22550 if (result != ISC_R_SUCCESS) { 22551 INSIST(!dns_rdataset_isassociated(&rdataset)); 22552 goto failure; 22553 } 22554 22555 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 22556 result = dns_rdataset_next(&rdataset)) 22557 { 22558 bool found = false; 22559 22560 dns_rdataset_current(&rdataset, &rdata); 22561 22562 if (kd->all) { 22563 if (rdata.length == 5 && rdata.data[0] != 0 && 22564 rdata.data[3] == 0 && rdata.data[4] == 1) 22565 { 22566 found = true; 22567 } else if (rdata.data[0] == 0 && 22568 (rdata.data[2] & PENDINGFLAGS) != 0) 22569 { 22570 found = true; 22571 clear_pending = true; 22572 } 22573 } else if (rdata.length == 5 && 22574 memcmp(rdata.data, kd->data, 5) == 0) 22575 { 22576 found = true; 22577 } 22578 22579 if (found) { 22580 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL, 22581 &zone->origin, rdataset.ttl, 22582 &rdata)); 22583 } 22584 dns_rdata_reset(&rdata); 22585 } 22586 22587 if (!ISC_LIST_EMPTY(diff.tuples)) { 22588 /* Write changes to journal file. */ 22589 CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx, 22590 zone->updatemethod)); 22591 22592 result = dns_update_signatures(&log, zone, db, oldver, newver, 22593 &diff, 22594 zone->sigvalidityinterval); 22595 if (!clear_pending) { 22596 CHECK(result); 22597 } 22598 22599 CHECK(zone_journal(zone, &diff, NULL, "keydone")); 22600 commit = true; 22601 22602 LOCK_ZONE(zone); 22603 DNS_ZONE_SETFLAG(zone, 22604 DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY); 22605 zone_needdump(zone, 30); 22606 UNLOCK_ZONE(zone); 22607 } 22608 22609failure: 22610 if (dns_rdataset_isassociated(&rdataset)) { 22611 dns_rdataset_disassociate(&rdataset); 22612 } 22613 if (db != NULL) { 22614 if (node != NULL) { 22615 dns_db_detachnode(db, &node); 22616 } 22617 if (oldver != NULL) { 22618 dns_db_closeversion(db, &oldver, false); 22619 } 22620 if (newver != NULL) { 22621 dns_db_closeversion(db, &newver, commit); 22622 } 22623 dns_db_detach(&db); 22624 } 22625 dns_diff_clear(&diff); 22626 isc_event_free(&event); 22627 dns_zone_idetach(&zone); 22628 22629 INSIST(oldver == NULL); 22630 INSIST(newver == NULL); 22631} 22632 22633isc_result_t 22634dns_zone_keydone(dns_zone_t *zone, const char *keystr) { 22635 isc_result_t result = ISC_R_SUCCESS; 22636 isc_event_t *e; 22637 isc_buffer_t b; 22638 dns_zone_t *dummy = NULL; 22639 struct keydone *kd; 22640 22641 REQUIRE(DNS_ZONE_VALID(zone)); 22642 22643 LOCK_ZONE(zone); 22644 22645 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone, 22646 zone, sizeof(struct keydone)); 22647 22648 kd = (struct keydone *)e; 22649 if (strcasecmp(keystr, "all") == 0) { 22650 kd->all = true; 22651 } else { 22652 isc_textregion_t r; 22653 const char *algstr; 22654 dns_keytag_t keyid; 22655 dns_secalg_t alg; 22656 size_t n; 22657 22658 kd->all = false; 22659 22660 n = sscanf(keystr, "%hu/", &keyid); 22661 if (n == 0U) { 22662 CHECK(ISC_R_FAILURE); 22663 } 22664 22665 algstr = strchr(keystr, '/'); 22666 if (algstr != NULL) { 22667 algstr++; 22668 } else { 22669 CHECK(ISC_R_FAILURE); 22670 } 22671 22672 n = sscanf(algstr, "%hhu", &alg); 22673 if (n == 0U) { 22674 DE_CONST(algstr, r.base); 22675 r.length = strlen(algstr); 22676 CHECK(dns_secalg_fromtext(&alg, &r)); 22677 } 22678 22679 /* construct a private-type rdata */ 22680 isc_buffer_init(&b, kd->data, sizeof(kd->data)); 22681 isc_buffer_putuint8(&b, alg); 22682 isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8); 22683 isc_buffer_putuint8(&b, (keyid & 0xff)); 22684 isc_buffer_putuint8(&b, 0); 22685 isc_buffer_putuint8(&b, 1); 22686 } 22687 22688 zone_iattach(zone, &dummy); 22689 isc_task_send(zone->task, &e); 22690 22691failure: 22692 if (e != NULL) { 22693 isc_event_free(&e); 22694 } 22695 UNLOCK_ZONE(zone); 22696 return (result); 22697} 22698 22699/* 22700 * Called from the zone task's queue after the relevant event is posted by 22701 * dns_zone_setnsec3param(). 22702 */ 22703static void 22704setnsec3param(isc_task_t *task, isc_event_t *event) { 22705 const char *me = "setnsec3param"; 22706 dns_zone_t *zone = event->ev_arg; 22707 bool loadpending; 22708 22709 INSIST(DNS_ZONE_VALID(zone)); 22710 22711 UNUSED(task); 22712 22713 ENTER; 22714 22715 LOCK_ZONE(zone); 22716 loadpending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING); 22717 UNLOCK_ZONE(zone); 22718 22719 /* 22720 * If receive_secure_serial is still processing or we have a 22721 * queued event append rss_post queue. 22722 */ 22723 if (zone->rss_newver != NULL || ISC_LIST_HEAD(zone->rss_post) != NULL) { 22724 /* 22725 * Wait for receive_secure_serial() to finish processing. 22726 */ 22727 ISC_LIST_APPEND(zone->rss_post, event, ev_link); 22728 } else { 22729 bool rescheduled = false; 22730 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 22731 /* 22732 * The zone is not yet fully loaded. Reschedule the event to 22733 * be picked up later. This turns this function into a busy 22734 * wait, but it only happens at startup. 22735 */ 22736 if (zone->db == NULL && loadpending) { 22737 rescheduled = true; 22738 isc_task_send(task, &event); 22739 } 22740 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 22741 if (rescheduled) { 22742 return; 22743 } 22744 22745 rss_post(zone, event); 22746 } 22747 dns_zone_idetach(&zone); 22748} 22749 22750static void 22751salt2text(unsigned char *salt, uint8_t saltlen, unsigned char *text, 22752 unsigned int textlen) { 22753 isc_region_t r; 22754 isc_buffer_t buf; 22755 isc_result_t result; 22756 22757 r.base = salt; 22758 r.length = (unsigned int)saltlen; 22759 22760 isc_buffer_init(&buf, text, textlen); 22761 result = isc_hex_totext(&r, 2, "", &buf); 22762 if (result == ISC_R_SUCCESS) { 22763 text[saltlen * 2] = 0; 22764 } else { 22765 text[0] = 0; 22766 } 22767} 22768 22769/* 22770 * Check whether NSEC3 chain addition or removal specified by the private-type 22771 * record passed with the event was already queued (or even fully performed). 22772 * If not, modify the relevant private-type records at the zone apex and call 22773 * resume_addnsec3chain(). 22774 */ 22775static void 22776rss_post(dns_zone_t *zone, isc_event_t *event) { 22777 const char *me = "rss_post"; 22778 bool commit = false; 22779 isc_result_t result; 22780 dns_dbversion_t *oldver = NULL, *newver = NULL; 22781 dns_db_t *db = NULL; 22782 dns_dbnode_t *node = NULL; 22783 dns_rdataset_t prdataset, nrdataset; 22784 dns_diff_t diff; 22785 struct np3event *npe = (struct np3event *)event; 22786 nsec3param_t *np; 22787 dns_update_log_t log = { update_log_cb, NULL }; 22788 dns_rdata_t rdata; 22789 bool nseconly; 22790 bool exists = false; 22791 22792 ENTER; 22793 22794 np = &npe->params; 22795 22796 dns_rdataset_init(&prdataset); 22797 dns_rdataset_init(&nrdataset); 22798 dns_diff_init(zone->mctx, &diff); 22799 22800 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 22801 if (zone->db != NULL) { 22802 dns_db_attach(zone->db, &db); 22803 } 22804 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 22805 if (db == NULL) { 22806 goto failure; 22807 } 22808 22809 dns_db_currentversion(db, &oldver); 22810 result = dns_db_newversion(db, &newver); 22811 if (result != ISC_R_SUCCESS) { 22812 dnssec_log(zone, ISC_LOG_ERROR, 22813 "setnsec3param:dns_db_newversion -> %s", 22814 dns_result_totext(result)); 22815 goto failure; 22816 } 22817 22818 CHECK(dns_db_getoriginnode(db, &node)); 22819 22820 /* 22821 * Do we need to look up the NSEC3 parameters? 22822 */ 22823 if (np->lookup) { 22824 dns_rdata_nsec3param_t param; 22825 dns_rdata_t nrdata = DNS_RDATA_INIT; 22826 dns_rdata_t prdata = DNS_RDATA_INIT; 22827 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE]; 22828 unsigned char saltbuf[255]; 22829 isc_buffer_t b; 22830 22831 param.salt = NULL; 22832 result = dns__zone_lookup_nsec3param(zone, &np->rdata, ¶m, 22833 saltbuf, np->resalt); 22834 if (result == ISC_R_SUCCESS) { 22835 /* 22836 * Success because the NSEC3PARAM already exists, but 22837 * function returns void, so goto failure to clean up. 22838 */ 22839 goto failure; 22840 } 22841 if (result != DNS_R_NSEC3RESALT && result != ISC_R_NOTFOUND) { 22842 dnssec_log(zone, ISC_LOG_DEBUG(3), 22843 "setnsec3param:lookup nsec3param -> %s", 22844 isc_result_totext(result)); 22845 goto failure; 22846 } 22847 22848 INSIST(param.salt != NULL); 22849 22850 /* Update NSEC3 parameters. */ 22851 np->rdata.hash = param.hash; 22852 np->rdata.flags = param.flags; 22853 np->rdata.iterations = param.iterations; 22854 np->rdata.salt_length = param.salt_length; 22855 np->rdata.salt = param.salt; 22856 22857 isc_buffer_init(&b, nbuf, sizeof(nbuf)); 22858 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass, 22859 dns_rdatatype_nsec3param, &np->rdata, 22860 &b)); 22861 dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype, 22862 np->data, sizeof(np->data)); 22863 np->length = prdata.length; 22864 np->nsec = false; 22865 } 22866 22867 /* 22868 * Does a private-type record already exist for this chain? 22869 */ 22870 result = dns_db_findrdataset(db, node, newver, zone->privatetype, 22871 dns_rdatatype_none, 0, &prdataset, NULL); 22872 if (result == ISC_R_SUCCESS) { 22873 for (result = dns_rdataset_first(&prdataset); 22874 result == ISC_R_SUCCESS; 22875 result = dns_rdataset_next(&prdataset)) 22876 { 22877 dns_rdata_init(&rdata); 22878 dns_rdataset_current(&prdataset, &rdata); 22879 22880 if (np->length == rdata.length && 22881 memcmp(rdata.data, np->data, np->length) == 0) 22882 { 22883 exists = true; 22884 break; 22885 } 22886 } 22887 } else if (result != ISC_R_NOTFOUND) { 22888 INSIST(!dns_rdataset_isassociated(&prdataset)); 22889 goto failure; 22890 } 22891 22892 /* 22893 * Does the chain already exist? 22894 */ 22895 result = dns_db_findrdataset(db, node, newver, dns_rdatatype_nsec3param, 22896 dns_rdatatype_none, 0, &nrdataset, NULL); 22897 if (result == ISC_R_SUCCESS) { 22898 for (result = dns_rdataset_first(&nrdataset); 22899 result == ISC_R_SUCCESS; 22900 result = dns_rdataset_next(&nrdataset)) 22901 { 22902 dns_rdata_init(&rdata); 22903 dns_rdataset_current(&nrdataset, &rdata); 22904 22905 if (np->length == (rdata.length + 1) && 22906 memcmp(rdata.data, np->data + 1, np->length - 1) == 22907 0) 22908 { 22909 exists = true; 22910 break; 22911 } 22912 } 22913 } else if (result != ISC_R_NOTFOUND) { 22914 INSIST(!dns_rdataset_isassociated(&nrdataset)); 22915 goto failure; 22916 } 22917 22918 /* 22919 * We need to remove any existing NSEC3 chains if the supplied NSEC3 22920 * parameters are supposed to replace the current ones or if we are 22921 * switching to NSEC. 22922 */ 22923 if (!exists && np->replace && (np->length != 0 || np->nsec)) { 22924 CHECK(dns_nsec3param_deletechains(db, newver, zone, !np->nsec, 22925 &diff)); 22926 } 22927 22928 if (!exists && np->length != 0) { 22929 /* 22930 * We're creating an NSEC3 chain. Add the private-type record 22931 * passed in the event handler's argument to the zone apex. 22932 * 22933 * If the zone is not currently capable of supporting an NSEC3 22934 * chain (due to the DNSKEY RRset at the zone apex not existing 22935 * or containing at least one key using an NSEC-only 22936 * algorithm), add the INITIAL flag, so these parameters can be 22937 * used later when NSEC3 becomes available. 22938 */ 22939 dns_rdata_init(&rdata); 22940 22941 np->data[2] |= DNS_NSEC3FLAG_CREATE; 22942 result = dns_nsec_nseconly(db, newver, &nseconly); 22943 if (result == ISC_R_NOTFOUND || nseconly) { 22944 np->data[2] |= DNS_NSEC3FLAG_INITIAL; 22945 } 22946 22947 rdata.length = np->length; 22948 rdata.data = np->data; 22949 rdata.type = zone->privatetype; 22950 rdata.rdclass = zone->rdclass; 22951 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD, 22952 &zone->origin, 0, &rdata)); 22953 } 22954 22955 /* 22956 * If we changed anything in the zone, write changes to journal file 22957 * and set commit to true so that resume_addnsec3chain() will be 22958 * called below in order to kick off adding/removing relevant NSEC3 22959 * records. 22960 */ 22961 if (!ISC_LIST_EMPTY(diff.tuples)) { 22962 CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx, 22963 zone->updatemethod)); 22964 result = dns_update_signatures(&log, zone, db, oldver, newver, 22965 &diff, 22966 zone->sigvalidityinterval); 22967 if (result != ISC_R_NOTFOUND) { 22968 CHECK(result); 22969 } 22970 CHECK(zone_journal(zone, &diff, NULL, "setnsec3param")); 22971 commit = true; 22972 22973 LOCK_ZONE(zone); 22974 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 22975 zone_needdump(zone, 30); 22976 UNLOCK_ZONE(zone); 22977 } 22978 22979failure: 22980 if (dns_rdataset_isassociated(&prdataset)) { 22981 dns_rdataset_disassociate(&prdataset); 22982 } 22983 if (dns_rdataset_isassociated(&nrdataset)) { 22984 dns_rdataset_disassociate(&nrdataset); 22985 } 22986 if (node != NULL) { 22987 dns_db_detachnode(db, &node); 22988 } 22989 if (oldver != NULL) { 22990 dns_db_closeversion(db, &oldver, false); 22991 } 22992 if (newver != NULL) { 22993 dns_db_closeversion(db, &newver, commit); 22994 } 22995 if (db != NULL) { 22996 dns_db_detach(&db); 22997 } 22998 if (commit) { 22999 LOCK_ZONE(zone); 23000 resume_addnsec3chain(zone); 23001 UNLOCK_ZONE(zone); 23002 } 23003 dns_diff_clear(&diff); 23004 isc_event_free(&event); 23005 23006 INSIST(oldver == NULL); 23007 INSIST(newver == NULL); 23008} 23009 23010/* 23011 * Check if zone has NSEC3PARAM (and thus a chain) with the right parameters. 23012 * 23013 * If 'salt' is NULL, a match is found if the salt has the requested length, 23014 * otherwise the NSEC3 salt must match the requested salt value too. 23015 * 23016 * Returns ISC_R_SUCCESS, if a match is found, or an error if no match is 23017 * found, or if the db lookup failed. 23018 */ 23019isc_result_t 23020dns__zone_lookup_nsec3param(dns_zone_t *zone, dns_rdata_nsec3param_t *lookup, 23021 dns_rdata_nsec3param_t *param, 23022 unsigned char saltbuf[255], bool resalt) { 23023 isc_result_t result = ISC_R_UNEXPECTED; 23024 dns_dbnode_t *node = NULL; 23025 dns_db_t *db = NULL; 23026 dns_dbversion_t *version = NULL; 23027 dns_rdataset_t rdataset; 23028 dns_rdata_nsec3param_t nsec3param; 23029 dns_rdata_t rdata = DNS_RDATA_INIT; 23030 23031 REQUIRE(DNS_ZONE_VALID(zone)); 23032 23033 dns_rdataset_init(&rdataset); 23034 23035 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 23036 if (zone->db != NULL) { 23037 dns_db_attach(zone->db, &db); 23038 } 23039 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 23040 if (db == NULL) { 23041 result = ISC_R_FAILURE; 23042 goto setparam; 23043 } 23044 23045 result = dns_db_findnode(db, &zone->origin, false, &node); 23046 if (result != ISC_R_SUCCESS) { 23047 dns_zone_log(zone, ISC_LOG_ERROR, 23048 "dns__zone_lookup_nsec3param:" 23049 "dns_db_findnode -> %s", 23050 dns_result_totext(result)); 23051 result = ISC_R_FAILURE; 23052 goto setparam; 23053 } 23054 dns_db_currentversion(db, &version); 23055 23056 result = dns_db_findrdataset(db, node, version, 23057 dns_rdatatype_nsec3param, 23058 dns_rdatatype_none, 0, &rdataset, NULL); 23059 if (result != ISC_R_SUCCESS) { 23060 INSIST(!dns_rdataset_isassociated(&rdataset)); 23061 if (result != ISC_R_NOTFOUND) { 23062 dns_zone_log(zone, ISC_LOG_ERROR, 23063 "dns__zone_lookup_nsec3param:" 23064 "dns_db_findrdataset -> %s", 23065 dns_result_totext(result)); 23066 } 23067 goto setparam; 23068 } 23069 23070 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 23071 result = dns_rdataset_next(&rdataset)) 23072 { 23073 dns_rdataset_current(&rdataset, &rdata); 23074 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 23075 INSIST(result == ISC_R_SUCCESS); 23076 dns_rdata_reset(&rdata); 23077 23078 /* Check parameters. */ 23079 if (nsec3param.hash != lookup->hash) { 23080 continue; 23081 } 23082 if (nsec3param.iterations != lookup->iterations) { 23083 continue; 23084 } 23085 if (nsec3param.salt_length != lookup->salt_length) { 23086 continue; 23087 } 23088 if (lookup->salt != NULL) { 23089 if (memcmp(nsec3param.salt, lookup->salt, 23090 lookup->salt_length) != 0) 23091 { 23092 continue; 23093 } 23094 } 23095 /* Found a match. */ 23096 result = ISC_R_SUCCESS; 23097 param->hash = nsec3param.hash; 23098 param->flags = nsec3param.flags; 23099 param->iterations = nsec3param.iterations; 23100 param->salt_length = nsec3param.salt_length; 23101 param->salt = nsec3param.salt; 23102 break; 23103 } 23104 23105 if (result == ISC_R_NOMORE) { 23106 result = ISC_R_NOTFOUND; 23107 } 23108 23109setparam: 23110 if (result != ISC_R_SUCCESS) { 23111 /* Found no match. */ 23112 param->hash = lookup->hash; 23113 param->flags = lookup->flags; 23114 param->iterations = lookup->iterations; 23115 param->salt_length = lookup->salt_length; 23116 param->salt = lookup->salt; 23117 } 23118 23119 if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) { 23120 goto failure; 23121 } 23122 23123 if (param->salt_length == 0) { 23124 DE_CONST("-", param->salt); 23125 } else if (resalt || param->salt == NULL) { 23126 unsigned char *newsalt; 23127 unsigned char salttext[255 * 2 + 1]; 23128 do { 23129 /* Generate a new salt. */ 23130 result = dns_nsec3_generate_salt(saltbuf, 23131 param->salt_length); 23132 if (result != ISC_R_SUCCESS) { 23133 break; 23134 } 23135 newsalt = saltbuf; 23136 salt2text(newsalt, param->salt_length, salttext, 23137 sizeof(salttext)); 23138 dnssec_log(zone, ISC_LOG_INFO, "generated salt: %s", 23139 salttext); 23140 /* Check for salt conflict. */ 23141 if (param->salt != NULL && 23142 memcmp(newsalt, param->salt, param->salt_length) == 23143 0) 23144 { 23145 result = ISC_R_SUCCESS; 23146 } else { 23147 param->salt = newsalt; 23148 result = DNS_R_NSEC3RESALT; 23149 } 23150 } while (result == ISC_R_SUCCESS); 23151 23152 INSIST(result != ISC_R_SUCCESS); 23153 } 23154 23155failure: 23156 if (dns_rdataset_isassociated(&rdataset)) { 23157 dns_rdataset_disassociate(&rdataset); 23158 } 23159 if (node != NULL) { 23160 dns_db_detachnode(db, &node); 23161 } 23162 if (version != NULL) { 23163 dns_db_closeversion(db, &version, false); 23164 } 23165 if (db != NULL) { 23166 dns_db_detach(&db); 23167 } 23168 23169 return (result); 23170} 23171 23172/* 23173 * Called when an "rndc signing -nsec3param ..." command is received, or the 23174 * 'dnssec-policy' has changed. 23175 * 23176 * Allocate and prepare an nsec3param_t structure which holds information about 23177 * the NSEC3 changes requested for the zone: 23178 * 23179 * - if NSEC3 is to be disabled ("-nsec3param none"), only set the "nsec" 23180 * field of the structure to true and the "replace" field to the value 23181 * of the "replace" argument, leaving other fields initialized to zeros, to 23182 * signal that the zone should be signed using NSEC instead of NSEC3, 23183 * 23184 * - otherwise, prepare NSEC3PARAM RDATA that will eventually be inserted at 23185 * the zone apex, convert it to a private-type record and store the latter 23186 * in the "data" field of the nsec3param_t structure. 23187 * 23188 * Once the nsec3param_t structure is prepared, post an event to the zone's 23189 * task which will cause setnsec3param() to be called with the prepared 23190 * structure passed as an argument. 23191 */ 23192isc_result_t 23193dns_zone_setnsec3param(dns_zone_t *zone, uint8_t hash, uint8_t flags, 23194 uint16_t iter, uint8_t saltlen, unsigned char *salt, 23195 bool replace, bool resalt) { 23196 isc_result_t result = ISC_R_SUCCESS; 23197 dns_rdata_nsec3param_t param, lookup; 23198 dns_rdata_t nrdata = DNS_RDATA_INIT; 23199 dns_rdata_t prdata = DNS_RDATA_INIT; 23200 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE]; 23201 unsigned char saltbuf[255]; 23202 struct np3event *npe; 23203 nsec3param_t *np; 23204 dns_zone_t *dummy = NULL; 23205 isc_buffer_t b; 23206 isc_event_t *e = NULL; 23207 bool do_lookup = false; 23208 23209 REQUIRE(DNS_ZONE_VALID(zone)); 23210 23211 LOCK_ZONE(zone); 23212 23213 /* 23214 * First check if the requested NSEC3 parameters are already set, 23215 * if so, no need to set again. 23216 */ 23217 if (hash != 0) { 23218 lookup.hash = hash; 23219 lookup.flags = flags; 23220 lookup.iterations = iter; 23221 lookup.salt_length = saltlen; 23222 lookup.salt = salt; 23223 param.salt = NULL; 23224 result = dns__zone_lookup_nsec3param(zone, &lookup, ¶m, 23225 saltbuf, resalt); 23226 if (result == ISC_R_SUCCESS) { 23227 UNLOCK_ZONE(zone); 23228 return (ISC_R_SUCCESS); 23229 } 23230 /* 23231 * Schedule lookup if lookup above failed (may happen if zone 23232 * db is NULL for example). 23233 */ 23234 do_lookup = (param.salt == NULL) ? true : false; 23235 } 23236 23237 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM, 23238 setnsec3param, zone, sizeof(struct np3event)); 23239 23240 npe = (struct np3event *)e; 23241 np = &npe->params; 23242 np->replace = replace; 23243 np->resalt = resalt; 23244 np->lookup = do_lookup; 23245 if (hash == 0) { 23246 np->length = 0; 23247 np->nsec = true; 23248 dnssec_log(zone, ISC_LOG_DEBUG(3), "setnsec3param:nsec"); 23249 } else { 23250 param.common.rdclass = zone->rdclass; 23251 param.common.rdtype = dns_rdatatype_nsec3param; 23252 ISC_LINK_INIT(¶m.common, link); 23253 param.mctx = NULL; 23254 /* nsec3 specific param set in dns__zone_lookup_nsec3param() */ 23255 isc_buffer_init(&b, nbuf, sizeof(nbuf)); 23256 23257 if (param.salt != NULL) { 23258 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass, 23259 dns_rdatatype_nsec3param, 23260 ¶m, &b)); 23261 dns_nsec3param_toprivate(&nrdata, &prdata, 23262 zone->privatetype, np->data, 23263 sizeof(np->data)); 23264 np->length = prdata.length; 23265 } 23266 23267 np->rdata = param; 23268 np->nsec = false; 23269 23270 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 23271 unsigned char salttext[255 * 2 + 1]; 23272 if (param.salt != NULL) { 23273 salt2text(param.salt, param.salt_length, 23274 salttext, sizeof(salttext)); 23275 } 23276 dnssec_log(zone, ISC_LOG_DEBUG(3), 23277 "setnsec3param:nsec3 %u %u %u %u:%s", 23278 param.hash, param.flags, param.iterations, 23279 param.salt_length, 23280 param.salt == NULL ? "unknown" 23281 : (char *)salttext); 23282 } 23283 } 23284 23285 /* 23286 * setnsec3param() will silently return early if the zone does not yet 23287 * have a database. Prevent that by queueing the event up if zone->db 23288 * is NULL. All events queued here are subsequently processed by 23289 * receive_secure_db() if it ever gets called or simply freed by 23290 * zone_free() otherwise. 23291 */ 23292 23293 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 23294 if (zone->db != NULL) { 23295 zone_iattach(zone, &dummy); 23296 isc_task_send(zone->task, &e); 23297 } else { 23298 ISC_LIST_APPEND(zone->setnsec3param_queue, e, ev_link); 23299 e = NULL; 23300 } 23301 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 23302 23303 result = ISC_R_SUCCESS; 23304 23305failure: 23306 if (e != NULL) { 23307 isc_event_free(&e); 23308 } 23309 UNLOCK_ZONE(zone); 23310 return (result); 23311} 23312 23313isc_result_t 23314dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) { 23315 REQUIRE(DNS_ZONE_VALID(zone)); 23316 REQUIRE(loadtime != NULL); 23317 23318 LOCK_ZONE(zone); 23319 *loadtime = zone->loadtime; 23320 UNLOCK_ZONE(zone); 23321 return (ISC_R_SUCCESS); 23322} 23323 23324isc_result_t 23325dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) { 23326 REQUIRE(DNS_ZONE_VALID(zone)); 23327 REQUIRE(expiretime != NULL); 23328 23329 LOCK_ZONE(zone); 23330 *expiretime = zone->expiretime; 23331 UNLOCK_ZONE(zone); 23332 return (ISC_R_SUCCESS); 23333} 23334 23335isc_result_t 23336dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) { 23337 REQUIRE(DNS_ZONE_VALID(zone)); 23338 REQUIRE(refreshtime != NULL); 23339 23340 LOCK_ZONE(zone); 23341 *refreshtime = zone->refreshtime; 23342 UNLOCK_ZONE(zone); 23343 return (ISC_R_SUCCESS); 23344} 23345 23346isc_result_t 23347dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) { 23348 REQUIRE(DNS_ZONE_VALID(zone)); 23349 REQUIRE(refreshkeytime != NULL); 23350 23351 LOCK_ZONE(zone); 23352 *refreshkeytime = zone->refreshkeytime; 23353 UNLOCK_ZONE(zone); 23354 return (ISC_R_SUCCESS); 23355} 23356 23357unsigned int 23358dns_zone_getincludes(dns_zone_t *zone, char ***includesp) { 23359 dns_include_t *include; 23360 char **array = NULL; 23361 unsigned int n = 0; 23362 23363 REQUIRE(DNS_ZONE_VALID(zone)); 23364 REQUIRE(includesp != NULL && *includesp == NULL); 23365 23366 LOCK_ZONE(zone); 23367 if (zone->nincludes == 0) { 23368 goto done; 23369 } 23370 23371 array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes); 23372 for (include = ISC_LIST_HEAD(zone->includes); include != NULL; 23373 include = ISC_LIST_NEXT(include, link)) 23374 { 23375 INSIST(n < zone->nincludes); 23376 array[n++] = isc_mem_strdup(zone->mctx, include->name); 23377 } 23378 INSIST(n == zone->nincludes); 23379 *includesp = array; 23380 23381done: 23382 UNLOCK_ZONE(zone); 23383 return (n); 23384} 23385 23386void 23387dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) { 23388 REQUIRE(DNS_ZONE_VALID(zone)); 23389 23390 zone->statlevel = level; 23391} 23392 23393dns_zonestat_level_t 23394dns_zone_getstatlevel(dns_zone_t *zone) { 23395 REQUIRE(DNS_ZONE_VALID(zone)); 23396 23397 return (zone->statlevel); 23398} 23399 23400static void 23401setserial(isc_task_t *task, isc_event_t *event) { 23402 uint32_t oldserial, desired; 23403 const char *me = "setserial"; 23404 bool commit = false; 23405 isc_result_t result; 23406 dns_dbversion_t *oldver = NULL, *newver = NULL; 23407 dns_zone_t *zone; 23408 dns_db_t *db = NULL; 23409 dns_diff_t diff; 23410 struct ssevent *sse = (struct ssevent *)event; 23411 dns_update_log_t log = { update_log_cb, NULL }; 23412 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL; 23413 23414 UNUSED(task); 23415 23416 zone = event->ev_arg; 23417 INSIST(DNS_ZONE_VALID(zone)); 23418 23419 ENTER; 23420 23421 if (zone->update_disabled) { 23422 goto disabled; 23423 } 23424 23425 desired = sse->serial; 23426 23427 dns_diff_init(zone->mctx, &diff); 23428 23429 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 23430 if (zone->db != NULL) { 23431 dns_db_attach(zone->db, &db); 23432 } 23433 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 23434 if (db == NULL) { 23435 goto failure; 23436 } 23437 23438 dns_db_currentversion(db, &oldver); 23439 result = dns_db_newversion(db, &newver); 23440 if (result != ISC_R_SUCCESS) { 23441 dns_zone_log(zone, ISC_LOG_ERROR, 23442 "setserial:dns_db_newversion -> %s", 23443 dns_result_totext(result)); 23444 goto failure; 23445 } 23446 23447 CHECK(dns_db_createsoatuple(db, oldver, diff.mctx, DNS_DIFFOP_DEL, 23448 &oldtuple)); 23449 CHECK(dns_difftuple_copy(oldtuple, &newtuple)); 23450 newtuple->op = DNS_DIFFOP_ADD; 23451 23452 oldserial = dns_soa_getserial(&oldtuple->rdata); 23453 if (desired == 0U) { 23454 desired = 1; 23455 } 23456 if (!isc_serial_gt(desired, oldserial)) { 23457 if (desired != oldserial) { 23458 dns_zone_log(zone, ISC_LOG_INFO, 23459 "setserial: desired serial (%u) " 23460 "out of range (%u-%u)", 23461 desired, oldserial + 1, 23462 (oldserial + 0x7fffffff)); 23463 } 23464 goto failure; 23465 } 23466 23467 dns_soa_setserial(desired, &newtuple->rdata); 23468 CHECK(do_one_tuple(&oldtuple, db, newver, &diff)); 23469 CHECK(do_one_tuple(&newtuple, db, newver, &diff)); 23470 result = dns_update_signatures(&log, zone, db, oldver, newver, &diff, 23471 zone->sigvalidityinterval); 23472 if (result != ISC_R_NOTFOUND) { 23473 CHECK(result); 23474 } 23475 23476 /* Write changes to journal file. */ 23477 CHECK(zone_journal(zone, &diff, NULL, "setserial")); 23478 commit = true; 23479 23480 LOCK_ZONE(zone); 23481 zone_needdump(zone, 30); 23482 UNLOCK_ZONE(zone); 23483 23484failure: 23485 if (oldtuple != NULL) { 23486 dns_difftuple_free(&oldtuple); 23487 } 23488 if (newtuple != NULL) { 23489 dns_difftuple_free(&newtuple); 23490 } 23491 if (oldver != NULL) { 23492 dns_db_closeversion(db, &oldver, false); 23493 } 23494 if (newver != NULL) { 23495 dns_db_closeversion(db, &newver, commit); 23496 } 23497 if (db != NULL) { 23498 dns_db_detach(&db); 23499 } 23500 dns_diff_clear(&diff); 23501 23502disabled: 23503 isc_event_free(&event); 23504 dns_zone_idetach(&zone); 23505 23506 INSIST(oldver == NULL); 23507 INSIST(newver == NULL); 23508} 23509 23510isc_result_t 23511dns_zone_setserial(dns_zone_t *zone, uint32_t serial) { 23512 isc_result_t result = ISC_R_SUCCESS; 23513 dns_zone_t *dummy = NULL; 23514 isc_event_t *e = NULL; 23515 struct ssevent *sse; 23516 23517 REQUIRE(DNS_ZONE_VALID(zone)); 23518 23519 LOCK_ZONE(zone); 23520 23521 if (!inline_secure(zone)) { 23522 if (!dns_zone_isdynamic(zone, true)) { 23523 result = DNS_R_NOTDYNAMIC; 23524 goto failure; 23525 } 23526 } 23527 23528 if (zone->update_disabled) { 23529 result = DNS_R_FROZEN; 23530 goto failure; 23531 } 23532 23533 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETSERIAL, setserial, 23534 zone, sizeof(struct ssevent)); 23535 23536 sse = (struct ssevent *)e; 23537 sse->serial = serial; 23538 23539 zone_iattach(zone, &dummy); 23540 isc_task_send(zone->task, &e); 23541 23542failure: 23543 if (e != NULL) { 23544 isc_event_free(&e); 23545 } 23546 UNLOCK_ZONE(zone); 23547 return (result); 23548} 23549 23550isc_stats_t * 23551dns_zone_getgluecachestats(dns_zone_t *zone) { 23552 REQUIRE(DNS_ZONE_VALID(zone)); 23553 23554 return (zone->gluecachestats); 23555} 23556 23557bool 23558dns_zone_isloaded(dns_zone_t *zone) { 23559 REQUIRE(DNS_ZONE_VALID(zone)); 23560 23561 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)); 23562} 23563 23564isc_result_t 23565dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver) { 23566 dns_dbversion_t *version = NULL; 23567 dns_keytable_t *secroots = NULL; 23568 isc_result_t result; 23569 dns_name_t *origin; 23570 23571 const char me[] = "dns_zone_verifydb"; 23572 23573 REQUIRE(DNS_ZONE_VALID(zone)); 23574 REQUIRE(db != NULL); 23575 23576 ENTER; 23577 23578 if (dns_zone_gettype(zone) != dns_zone_mirror) { 23579 return (ISC_R_SUCCESS); 23580 } 23581 23582 if (ver == NULL) { 23583 dns_db_currentversion(db, &version); 23584 } else { 23585 version = ver; 23586 } 23587 23588 if (zone->view != NULL) { 23589 result = dns_view_getsecroots(zone->view, &secroots); 23590 if (result != ISC_R_SUCCESS) { 23591 goto done; 23592 } 23593 } 23594 23595 origin = dns_db_origin(db); 23596 result = dns_zoneverify_dnssec(zone, db, version, origin, secroots, 23597 zone->mctx, true, false, dnssec_report); 23598 23599done: 23600 if (secroots != NULL) { 23601 dns_keytable_detach(&secroots); 23602 } 23603 23604 if (ver == NULL) { 23605 dns_db_closeversion(db, &version, false); 23606 } 23607 23608 if (result != ISC_R_SUCCESS) { 23609 dnssec_log(zone, ISC_LOG_ERROR, "zone verification failed: %s", 23610 isc_result_totext(result)); 23611 result = DNS_R_VERIFYFAILURE; 23612 } 23613 23614 return (result); 23615} 23616 23617static dns_ttl_t 23618zone_nsecttl(dns_zone_t *zone) { 23619 REQUIRE(DNS_ZONE_VALID(zone)); 23620 23621 return (ISC_MIN(zone->minimum, zone->soattl)); 23622} 23623