1/* $NetBSD: zone.c,v 1.19 2024/02/21 22:52:08 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/result.h> 33#include <isc/rwlock.h> 34#include <isc/serial.h> 35#include <isc/stats.h> 36#include <isc/stdtime.h> 37#include <isc/strerr.h> 38#include <isc/string.h> 39#include <isc/taskpool.h> 40#include <isc/thread.h> 41#include <isc/timer.h> 42#include <isc/tls.h> 43#include <isc/util.h> 44 45#include <dns/acl.h> 46#include <dns/adb.h> 47#include <dns/callbacks.h> 48#include <dns/catz.h> 49#include <dns/db.h> 50#include <dns/dbiterator.h> 51#include <dns/dlz.h> 52#include <dns/dnssec.h> 53#include <dns/events.h> 54#include <dns/journal.h> 55#include <dns/kasp.h> 56#include <dns/keydata.h> 57#include <dns/keymgr.h> 58#include <dns/keytable.h> 59#include <dns/keyvalues.h> 60#include <dns/log.h> 61#include <dns/master.h> 62#include <dns/masterdump.h> 63#include <dns/message.h> 64#include <dns/name.h> 65#include <dns/nsec.h> 66#include <dns/nsec3.h> 67#include <dns/opcode.h> 68#include <dns/peer.h> 69#include <dns/private.h> 70#include <dns/rcode.h> 71#include <dns/rdata.h> 72#include <dns/rdataclass.h> 73#include <dns/rdatalist.h> 74#include <dns/rdataset.h> 75#include <dns/rdatasetiter.h> 76#include <dns/rdatastruct.h> 77#include <dns/rdatatype.h> 78#include <dns/request.h> 79#include <dns/resolver.h> 80#include <dns/rriterator.h> 81#include <dns/soa.h> 82#include <dns/ssu.h> 83#include <dns/stats.h> 84#include <dns/time.h> 85#include <dns/tsig.h> 86#include <dns/update.h> 87#include <dns/xfrin.h> 88#include <dns/zone.h> 89#include <dns/zoneverify.h> 90#include <dns/zt.h> 91 92#include <dst/dst.h> 93 94#include "zone_p.h" 95 96#define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E') 97#define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC) 98 99#define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y') 100#define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC) 101 102#define CHECKDS_MAGIC ISC_MAGIC('C', 'h', 'D', 'S') 103#define DNS_CHECKDS_VALID(checkds) ISC_MAGIC_VALID(checkds, CHECKDS_MAGIC) 104 105#define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b') 106#define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC) 107 108#define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r') 109#define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC) 110 111#define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd') 112#define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC) 113 114#define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w') 115#define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC) 116 117#define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O') 118#define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC) 119 120#define KEYMGMT_MAGIC ISC_MAGIC('M', 'g', 'm', 't') 121#define DNS_KEYMGMT_VALID(load) ISC_MAGIC_VALID(load, KEYMGMT_MAGIC) 122 123#define KEYFILEIO_MAGIC ISC_MAGIC('K', 'y', 'I', 'O') 124#define DNS_KEYFILEIO_VALID(kfio) ISC_MAGIC_VALID(kfio, KEYFILEIO_MAGIC) 125 126/*% 127 * Ensure 'a' is at least 'min' but not more than 'max'. 128 */ 129#define RANGE(a, min, max) (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max))) 130 131#define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) 132 133/*% 134 * Key flags 135 */ 136#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0) 137#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0) 138#define ID(x) dst_key_id(x) 139#define ALG(x) dst_key_alg(x) 140 141/*% 142 * KASP flags 143 */ 144#define KASP_LOCK(k) \ 145 if ((k) != NULL) { \ 146 LOCK((&((k)->lock))); \ 147 } 148 149#define KASP_UNLOCK(k) \ 150 if ((k) != NULL) { \ 151 UNLOCK((&((k)->lock))); \ 152 } 153 154/* 155 * Default values. 156 */ 157#define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */ 158#define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */ 159#define MAX_XFER_TIME (2 * 3600) /*%< Documented default is 2 hours */ 160#define RESIGN_DELAY 3600 /*%< 1 hour */ 161 162#ifndef DNS_MAX_EXPIRE 163#define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */ 164#endif /* ifndef DNS_MAX_EXPIRE */ 165 166#ifndef DNS_DUMP_DELAY 167#define DNS_DUMP_DELAY 900 /*%< 15 minutes */ 168#endif /* ifndef DNS_DUMP_DELAY */ 169 170typedef struct dns_notify dns_notify_t; 171typedef struct dns_checkds dns_checkds_t; 172typedef struct dns_stub dns_stub_t; 173typedef struct dns_load dns_load_t; 174typedef struct dns_forward dns_forward_t; 175typedef ISC_LIST(dns_forward_t) dns_forwardlist_t; 176typedef struct dns_io dns_io_t; 177typedef ISC_LIST(dns_io_t) dns_iolist_t; 178typedef struct dns_keymgmt dns_keymgmt_t; 179typedef struct dns_signing dns_signing_t; 180typedef ISC_LIST(dns_signing_t) dns_signinglist_t; 181typedef struct dns_nsec3chain dns_nsec3chain_t; 182typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t; 183typedef struct dns_keyfetch dns_keyfetch_t; 184typedef struct dns_asyncload dns_asyncload_t; 185typedef struct dns_include dns_include_t; 186 187#define DNS_ZONE_CHECKLOCK 188#ifdef DNS_ZONE_CHECKLOCK 189#define LOCK_ZONE(z) \ 190 do { \ 191 LOCK(&(z)->lock); \ 192 INSIST(!(z)->locked); \ 193 (z)->locked = true; \ 194 } while (0) 195#define UNLOCK_ZONE(z) \ 196 do { \ 197 (z)->locked = false; \ 198 UNLOCK(&(z)->lock); \ 199 } while (0) 200#define LOCKED_ZONE(z) ((z)->locked) 201#define TRYLOCK_ZONE(result, z) \ 202 do { \ 203 result = isc_mutex_trylock(&(z)->lock); \ 204 if (result == ISC_R_SUCCESS) { \ 205 INSIST(!(z)->locked); \ 206 (z)->locked = true; \ 207 } \ 208 } while (0) 209#else /* ifdef DNS_ZONE_CHECKLOCK */ 210#define LOCK_ZONE(z) LOCK(&(z)->lock) 211#define UNLOCK_ZONE(z) UNLOCK(&(z)->lock) 212#define LOCKED_ZONE(z) true 213#define TRYLOCK_ZONE(result, z) \ 214 do { \ 215 result = isc_mutex_trylock(&(z)->lock); \ 216 } while (0) 217#endif /* ifdef DNS_ZONE_CHECKLOCK */ 218 219#define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0) 220#define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l) 221#define ZONEDB_LOCK(l, t) RWLOCK((l), (t)) 222#define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t)) 223 224#ifdef ENABLE_AFL 225extern bool dns_fuzzing_resolver; 226#endif /* ifdef ENABLE_AFL */ 227 228/*% 229 * Hold key file IO locks. 230 */ 231typedef struct dns_keyfileio { 232 unsigned int magic; 233 struct dns_keyfileio *next; 234 uint32_t hashval; 235 dns_fixedname_t fname; 236 dns_name_t *name; 237 isc_refcount_t references; 238 isc_mutex_t lock; 239} dns_keyfileio_t; 240 241struct dns_keymgmt { 242 unsigned int magic; 243 isc_rwlock_t lock; 244 isc_mem_t *mctx; 245 246 dns_keyfileio_t **table; 247 248 atomic_uint_fast32_t count; 249 250 uint32_t bits; 251}; 252 253struct dns_zone { 254 /* Unlocked */ 255 unsigned int magic; 256 isc_mutex_t lock; 257#ifdef DNS_ZONE_CHECKLOCK 258 bool locked; 259#endif /* ifdef DNS_ZONE_CHECKLOCK */ 260 isc_mem_t *mctx; 261 isc_refcount_t erefs; 262 263 isc_rwlock_t dblock; 264 dns_db_t *db; /* Locked by dblock */ 265 266 /* Locked */ 267 dns_zonemgr_t *zmgr; 268 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */ 269 isc_timer_t *timer; 270 isc_refcount_t irefs; 271 dns_name_t origin; 272 char *masterfile; 273 const FILE *stream; /* loading from a stream? */ 274 ISC_LIST(dns_include_t) includes; /* Include files */ 275 ISC_LIST(dns_include_t) newincludes; /* Loading */ 276 unsigned int nincludes; 277 dns_masterformat_t masterformat; 278 const dns_master_style_t *masterstyle; 279 char *journal; 280 int32_t journalsize; 281 dns_rdataclass_t rdclass; 282 dns_zonetype_t type; 283#ifdef __NetBSD__ 284 atomic_uint_fast32_t flags; 285 atomic_uint_fast32_t options; 286#else 287 atomic_uint_fast64_t flags; 288 atomic_uint_fast64_t options; 289#endif 290 unsigned int db_argc; 291 char **db_argv; 292 isc_time_t expiretime; 293 isc_time_t refreshtime; 294 isc_time_t dumptime; 295 isc_time_t loadtime; 296 isc_time_t notifytime; 297 isc_time_t resigntime; 298 isc_time_t keywarntime; 299 isc_time_t signingtime; 300 isc_time_t nsec3chaintime; 301 isc_time_t refreshkeytime; 302 uint32_t refreshkeyinterval; 303 uint32_t refreshkeycount; 304 uint32_t refresh; 305 uint32_t retry; 306 uint32_t expire; 307 uint32_t minimum; 308 isc_stdtime_t key_expiry; 309 isc_stdtime_t log_key_expired_timer; 310 char *keydirectory; 311 dns_keyfileio_t *kfio; 312 313 uint32_t maxrefresh; 314 uint32_t minrefresh; 315 uint32_t maxretry; 316 uint32_t minretry; 317 318 uint32_t maxrecords; 319 320 isc_sockaddr_t *primaries; 321 dns_name_t **primarykeynames; 322 dns_name_t **primarytlsnames; 323 bool *primariesok; 324 unsigned int primariescnt; 325 unsigned int curprimary; 326 isc_sockaddr_t primaryaddr; 327 328 isc_sockaddr_t *parentals; 329 dns_name_t **parentalkeynames; 330 dns_name_t **parentaltlsnames; 331 dns_dnsseckeylist_t checkds_ok; 332 unsigned int parentalscnt; 333 isc_sockaddr_t parentaladdr; 334 335 dns_notifytype_t notifytype; 336 isc_sockaddr_t *notify; 337 dns_name_t **notifykeynames; 338 dns_name_t **notifytlsnames; 339 unsigned int notifycnt; 340 isc_sockaddr_t notifyfrom; 341 isc_task_t *task; 342 isc_task_t *loadtask; 343 isc_sockaddr_t notifysrc4; 344 isc_sockaddr_t notifysrc6; 345 isc_sockaddr_t parentalsrc4; 346 isc_sockaddr_t parentalsrc6; 347 isc_sockaddr_t xfrsource4; 348 isc_sockaddr_t xfrsource6; 349 isc_sockaddr_t altxfrsource4; 350 isc_sockaddr_t altxfrsource6; 351 isc_sockaddr_t sourceaddr; 352 dns_xfrin_ctx_t *xfr; /* task locked */ 353 dns_tsigkey_t *tsigkey; /* key used for xfr */ 354 dns_transport_t *transport; /* transport used for xfr */ 355 /* Access Control Lists */ 356 dns_acl_t *update_acl; 357 dns_acl_t *forward_acl; 358 dns_acl_t *notify_acl; 359 dns_acl_t *query_acl; 360 dns_acl_t *queryon_acl; 361 dns_acl_t *xfr_acl; 362 bool update_disabled; 363 bool zero_no_soa_ttl; 364 dns_severity_t check_names; 365 ISC_LIST(dns_notify_t) notifies; 366 ISC_LIST(dns_checkds_t) checkds_requests; 367 dns_request_t *request; 368 dns_loadctx_t *lctx; 369 dns_io_t *readio; 370 dns_dumpctx_t *dctx; 371 dns_io_t *writeio; 372 uint32_t maxxfrin; 373 uint32_t maxxfrout; 374 uint32_t idlein; 375 uint32_t idleout; 376 isc_event_t ctlevent; 377 dns_ssutable_t *ssutable; 378 uint32_t sigvalidityinterval; 379 uint32_t keyvalidityinterval; 380 uint32_t sigresigninginterval; 381 dns_view_t *view; 382 dns_view_t *prev_view; 383 dns_kasp_t *kasp; 384 dns_checkmxfunc_t checkmx; 385 dns_checksrvfunc_t checksrv; 386 dns_checknsfunc_t checkns; 387 /*% 388 * Zones in certain states such as "waiting for zone transfer" 389 * or "zone transfer in progress" are kept on per-state linked lists 390 * in the zone manager using the 'statelink' field. The 'statelist' 391 * field points at the list the zone is currently on. It the zone 392 * is not on any such list, statelist is NULL. 393 */ 394 ISC_LINK(dns_zone_t) statelink; 395 dns_zonelist_t *statelist; 396 /*% 397 * Statistics counters about zone management. 398 */ 399 isc_stats_t *stats; 400 /*% 401 * Optional per-zone statistics counters. Counted outside of this 402 * module. 403 */ 404 dns_zonestat_level_t statlevel; 405 bool requeststats_on; 406 isc_stats_t *requeststats; 407 dns_stats_t *rcvquerystats; 408 dns_stats_t *dnssecsignstats; 409 uint32_t notifydelay; 410 dns_isselffunc_t isself; 411 void *isselfarg; 412 413 char *strnamerd; 414 char *strname; 415 char *strrdclass; 416 char *strviewname; 417 418 /*% 419 * Serial number for deferred journal compaction. 420 */ 421 uint32_t compact_serial; 422 /*% 423 * Keys that are signing the zone for the first time. 424 */ 425 dns_signinglist_t signing; 426 dns_nsec3chainlist_t nsec3chain; 427 /*% 428 * List of outstanding NSEC3PARAM change requests. 429 */ 430 isc_eventlist_t setnsec3param_queue; 431 /*% 432 * Signing / re-signing quantum stopping parameters. 433 */ 434 uint32_t signatures; 435 uint32_t nodes; 436 dns_rdatatype_t privatetype; 437 438 /*% 439 * Autosigning/key-maintenance options 440 */ 441#ifdef __NetBSD__ 442 atomic_uint_fast32_t keyopts; 443#else 444 atomic_uint_fast64_t keyopts; 445#endif 446 447 /*% 448 * True if added by "rndc addzone" 449 */ 450 bool added; 451 452 /*% 453 * True if added by automatically by named. 454 */ 455 bool automatic; 456 457 /*% 458 * response policy data to be relayed to the database 459 */ 460 dns_rpz_zones_t *rpzs; 461 dns_rpz_num_t rpz_num; 462 463 /*% 464 * catalog zone data 465 */ 466 dns_catz_zones_t *catzs; 467 468 /*% 469 * parent catalog zone 470 */ 471 dns_catz_zone_t *parentcatz; 472 473 /*% 474 * Serial number update method. 475 */ 476 dns_updatemethod_t updatemethod; 477 478 /*% 479 * whether ixfr is requested 480 */ 481 bool requestixfr; 482 uint32_t ixfr_ratio; 483 484 /*% 485 * whether EDNS EXPIRE is requested 486 */ 487 bool requestexpire; 488 489 /*% 490 * Outstanding forwarded UPDATE requests. 491 */ 492 dns_forwardlist_t forwards; 493 494 dns_zone_t *raw; 495 dns_zone_t *secure; 496 497 bool sourceserialset; 498 uint32_t sourceserial; 499 500 /*% 501 * soa and maximum zone ttl 502 */ 503 dns_ttl_t soattl; 504 dns_ttl_t maxttl; 505 506 /* 507 * Inline zone signing state. 508 */ 509 dns_diff_t rss_diff; 510 isc_eventlist_t rss_events; 511 isc_eventlist_t rss_post; 512 dns_dbversion_t *rss_newver; 513 dns_dbversion_t *rss_oldver; 514 dns_db_t *rss_db; 515 dns_zone_t *rss_raw; 516 isc_event_t *rss_event; 517 dns_update_state_t *rss_state; 518 519 isc_stats_t *gluecachestats; 520}; 521 522#define zonediff_init(z, d) \ 523 do { \ 524 dns__zonediff_t *_z = (z); \ 525 (_z)->diff = (d); \ 526 (_z)->offline = false; \ 527 } while (0) 528 529#define DNS_ZONE_FLAG(z, f) ((atomic_load_relaxed(&(z)->flags) & (f)) != 0) 530#define DNS_ZONE_SETFLAG(z, f) atomic_fetch_or(&(z)->flags, (f)) 531#define DNS_ZONE_CLRFLAG(z, f) atomic_fetch_and(&(z)->flags, ~(f)) 532typedef enum { 533 DNS_ZONEFLG_REFRESH = 0x00000001U, /*%< refresh check in progress */ 534 DNS_ZONEFLG_NEEDDUMP = 0x00000002U, /*%< zone need consolidation */ 535 DNS_ZONEFLG_USEVC = 0x00000004U, /*%< use tcp for refresh query */ 536 DNS_ZONEFLG_DUMPING = 0x00000008U, /*%< a dump is in progress */ 537 DNS_ZONEFLG_HASINCLUDE = 0x00000010U, /*%< $INCLUDE in zone file */ 538 DNS_ZONEFLG_LOADED = 0x00000020U, /*%< database has loaded */ 539 DNS_ZONEFLG_EXITING = 0x00000040U, /*%< zone is being destroyed */ 540 DNS_ZONEFLG_EXPIRED = 0x00000080U, /*%< zone has expired */ 541 DNS_ZONEFLG_NEEDREFRESH = 0x00000100U, /*%< refresh check needed */ 542 DNS_ZONEFLG_UPTODATE = 0x00000200U, /*%< zone contents are 543 * up-to-date */ 544 DNS_ZONEFLG_NEEDNOTIFY = 0x00000400U, /*%< need to send out notify 545 * messages */ 546 DNS_ZONEFLG_FIXJOURNAL = 0x00000800U, /*%< journal file had 547 * recoverable error, 548 * needs rewriting */ 549 DNS_ZONEFLG_NOPRIMARIES = 0x00001000U, /*%< an attempt to refresh a 550 * zone with no primaries 551 * occurred */ 552 DNS_ZONEFLG_LOADING = 0x00002000U, /*%< load from disk in progress*/ 553 DNS_ZONEFLG_HAVETIMERS = 0x00004000U, /*%< timer values have been set 554 * from SOA (if not set, we 555 * are still using 556 * default timer values) */ 557 DNS_ZONEFLG_FORCEXFER = 0x00008000U, /*%< Force a zone xfer */ 558 DNS_ZONEFLG_NOREFRESH = 0x00010000U, 559 DNS_ZONEFLG_DIALNOTIFY = 0x00020000U, 560 DNS_ZONEFLG_DIALREFRESH = 0x00040000U, 561 DNS_ZONEFLG_SHUTDOWN = 0x00080000U, 562 DNS_ZONEFLG_NOIXFR = 0x00100000U, /*%< IXFR failed, force AXFR */ 563 DNS_ZONEFLG_FLUSH = 0x00200000U, 564 DNS_ZONEFLG_NOEDNS = 0x00400000U, 565 DNS_ZONEFLG_USEALTXFRSRC = 0x00800000U, 566 DNS_ZONEFLG_SOABEFOREAXFR = 0x01000000U, 567 DNS_ZONEFLG_NEEDCOMPACT = 0x02000000U, 568 DNS_ZONEFLG_REFRESHING = 0x04000000U, /*%< Refreshing keydata */ 569 DNS_ZONEFLG_THAW = 0x08000000U, 570 DNS_ZONEFLG_LOADPENDING = 0x10000000U, /*%< Loading scheduled */ 571 DNS_ZONEFLG_NODELAY = 0x20000000U, 572 DNS_ZONEFLG_SENDSECURE = 0x40000000U, 573 DNS_ZONEFLG_NEEDSTARTUPNOTIFY = 0x80000000U, /*%< need to send out 574 * notify due to the zone 575 * just being loaded for 576 * the first time. */ 577#ifndef __NetBSD__ 578 /* 579 * DO NOT add any new zone flags here until all platforms 580 * support 64-bit enum values. Currently they fail on 581 * Windows. 582 */ 583 DNS_ZONEFLG___MAX = UINT64_MAX, /* trick to make the ENUM 64-bit wide */ 584#endif 585} dns_zoneflg_t; 586 587#define DNS_ZONE_OPTION(z, o) ((atomic_load_relaxed(&(z)->options) & (o)) != 0) 588#define DNS_ZONE_SETOPTION(z, o) atomic_fetch_or(&(z)->options, (o)) 589#define DNS_ZONE_CLROPTION(z, o) atomic_fetch_and(&(z)->options, ~(o)) 590 591#define DNS_ZONEKEY_OPTION(z, o) \ 592 ((atomic_load_relaxed(&(z)->keyopts) & (o)) != 0) 593#define DNS_ZONEKEY_SETOPTION(z, o) atomic_fetch_or(&(z)->keyopts, (o)) 594#define DNS_ZONEKEY_CLROPTION(z, o) atomic_fetch_and(&(z)->keyopts, ~(o)) 595 596/* Flags for zone_load() */ 597typedef enum { 598 DNS_ZONELOADFLAG_NOSTAT = 0x00000001U, /* Do not stat() master files */ 599 DNS_ZONELOADFLAG_THAW = 0x00000002U, /* Thaw the zone on successful 600 * load. */ 601} dns_zoneloadflag_t; 602 603#define UNREACH_CACHE_SIZE 10U 604#define UNREACH_HOLD_TIME 600 /* 10 minutes */ 605 606#define CHECK(op) \ 607 do { \ 608 result = (op); \ 609 if (result != ISC_R_SUCCESS) \ 610 goto failure; \ 611 } while (0) 612 613struct dns_unreachable { 614 isc_sockaddr_t remote; 615 isc_sockaddr_t local; 616 atomic_uint_fast32_t expire; 617 atomic_uint_fast32_t last; 618 uint32_t count; 619}; 620 621struct dns_zonemgr { 622 unsigned int magic; 623 isc_mem_t *mctx; 624 isc_refcount_t refs; 625 isc_taskmgr_t *taskmgr; 626 isc_timermgr_t *timermgr; 627 isc_nm_t *netmgr; 628 isc_taskpool_t *zonetasks; 629 isc_taskpool_t *loadtasks; 630 isc_task_t *task; 631 isc_pool_t *mctxpool; 632 isc_ratelimiter_t *checkdsrl; 633 isc_ratelimiter_t *notifyrl; 634 isc_ratelimiter_t *refreshrl; 635 isc_ratelimiter_t *startupnotifyrl; 636 isc_ratelimiter_t *startuprefreshrl; 637 isc_rwlock_t rwlock; 638 isc_mutex_t iolock; 639 isc_rwlock_t urlock; 640 641 /* Locked by rwlock. */ 642 dns_zonelist_t zones; 643 dns_zonelist_t waiting_for_xfrin; 644 dns_zonelist_t xfrin_in_progress; 645 646 /* Configuration data. */ 647 uint32_t transfersin; 648 uint32_t transfersperns; 649 unsigned int checkdsrate; 650 unsigned int notifyrate; 651 unsigned int startupnotifyrate; 652 unsigned int serialqueryrate; 653 unsigned int startupserialqueryrate; 654 655 /* Locked by iolock */ 656 uint32_t iolimit; 657 uint32_t ioactive; 658 dns_iolist_t high; 659 dns_iolist_t low; 660 661 /* Locked by urlock. */ 662 /* LRU cache */ 663 struct dns_unreachable unreachable[UNREACH_CACHE_SIZE]; 664 665 dns_keymgmt_t *keymgmt; 666 667 isc_tlsctx_cache_t *tlsctx_cache; 668 isc_rwlock_t tlsctx_cache_rwlock; 669}; 670 671/*% 672 * Hold notify state. 673 */ 674struct dns_notify { 675 unsigned int magic; 676 unsigned int flags; 677 isc_mem_t *mctx; 678 dns_zone_t *zone; 679 dns_adbfind_t *find; 680 dns_request_t *request; 681 dns_name_t ns; 682 isc_sockaddr_t dst; 683 dns_tsigkey_t *key; 684 dns_transport_t *transport; 685 ISC_LINK(dns_notify_t) link; 686 isc_event_t *event; 687}; 688 689#define DNS_NOTIFY_NOSOA 0x0001U 690#define DNS_NOTIFY_STARTUP 0x0002U 691 692/*% 693 * Hold checkds state. 694 */ 695struct dns_checkds { 696 unsigned int magic; 697 unsigned int flags; 698 isc_mem_t *mctx; 699 dns_zone_t *zone; 700 dns_request_t *request; 701 isc_sockaddr_t dst; 702 dns_tsigkey_t *key; 703 dns_transport_t *transport; 704 ISC_LINK(dns_checkds_t) link; 705 isc_event_t *event; 706}; 707 708/*% 709 * dns_stub holds state while performing a 'stub' transfer. 710 * 'db' is the zone's 'db' or a new one if this is the initial 711 * transfer. 712 */ 713 714struct dns_stub { 715 unsigned int magic; 716 isc_mem_t *mctx; 717 dns_zone_t *zone; 718 dns_db_t *db; 719 dns_dbversion_t *version; 720 atomic_uint_fast32_t pending_requests; 721}; 722 723/*% 724 * Hold load state. 725 */ 726struct dns_load { 727 unsigned int magic; 728 isc_mem_t *mctx; 729 dns_zone_t *zone; 730 dns_db_t *db; 731 isc_time_t loadtime; 732 dns_rdatacallbacks_t callbacks; 733}; 734 735/*% 736 * Hold forward state. 737 */ 738struct dns_forward { 739 unsigned int magic; 740 isc_mem_t *mctx; 741 dns_zone_t *zone; 742 isc_buffer_t *msgbuf; 743 dns_request_t *request; 744 uint32_t which; 745 isc_sockaddr_t addr; 746 dns_updatecallback_t callback; 747 void *callback_arg; 748 unsigned int options; 749 ISC_LINK(dns_forward_t) link; 750}; 751 752/*% 753 * Hold IO request state. 754 */ 755struct dns_io { 756 unsigned int magic; 757 dns_zonemgr_t *zmgr; 758 bool high; 759 isc_task_t *task; 760 ISC_LINK(dns_io_t) link; 761 isc_event_t *event; 762}; 763 764/*% 765 * Hold state for when we are signing a zone with a new 766 * DNSKEY as result of an update. 767 */ 768struct dns_signing { 769 unsigned int magic; 770 dns_db_t *db; 771 dns_dbiterator_t *dbiterator; 772 dns_secalg_t algorithm; 773 uint16_t keyid; 774 bool deleteit; 775 bool done; 776 ISC_LINK(dns_signing_t) link; 777}; 778 779struct dns_nsec3chain { 780 unsigned int magic; 781 dns_db_t *db; 782 dns_dbiterator_t *dbiterator; 783 dns_rdata_nsec3param_t nsec3param; 784 unsigned char salt[255]; 785 bool done; 786 bool seen_nsec; 787 bool delete_nsec; 788 bool save_delete_nsec; 789 ISC_LINK(dns_nsec3chain_t) link; 790}; 791 792/*%< 793 * 'dbiterator' contains a iterator for the database. If we are creating 794 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are 795 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be 796 * iterated. 797 * 798 * 'nsec3param' contains the parameters of the NSEC3 chain being created 799 * or removed. 800 * 801 * 'salt' is buffer space and is referenced via 'nsec3param.salt'. 802 * 803 * 'seen_nsec' will be set to true if, while iterating the zone to create a 804 * NSEC3 chain, a NSEC record is seen. 805 * 806 * 'delete_nsec' will be set to true if, at the completion of the creation 807 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we 808 * are in the process of deleting the NSEC chain. 809 * 810 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec' 811 * so it can be recovered in the event of a error. 812 */ 813 814struct dns_keyfetch { 815 isc_mem_t *mctx; 816 dns_fixedname_t name; 817 dns_rdataset_t keydataset; 818 dns_rdataset_t dnskeyset; 819 dns_rdataset_t dnskeysigset; 820 dns_zone_t *zone; 821 dns_db_t *db; 822 dns_fetch_t *fetch; 823}; 824 825/*% 826 * Hold state for an asynchronous load 827 */ 828struct dns_asyncload { 829 dns_zone_t *zone; 830 unsigned int flags; 831 dns_zt_zoneloaded_t loaded; 832 void *loaded_arg; 833}; 834 835/*% 836 * Reference to an include file encountered during loading 837 */ 838struct dns_include { 839 char *name; 840 isc_time_t filetime; 841 ISC_LINK(dns_include_t) link; 842}; 843 844/* 845 * These can be overridden by the -T mkeytimers option on the command 846 * line, so that we can test with shorter periods than specified in 847 * RFC 5011. 848 */ 849#define HOUR 3600 850#define DAY (24 * HOUR) 851#define MONTH (30 * DAY) 852unsigned int dns_zone_mkey_hour = HOUR; 853unsigned int dns_zone_mkey_day = DAY; 854unsigned int dns_zone_mkey_month = MONTH; 855 856#define SEND_BUFFER_SIZE 2048 857 858static void 859zone_settimer(dns_zone_t *, isc_time_t *); 860static void 861cancel_refresh(dns_zone_t *); 862static void 863zone_debuglog(dns_zone_t *zone, const char *, int debuglevel, const char *msg, 864 ...) ISC_FORMAT_PRINTF(4, 5); 865static void 866notify_log(dns_zone_t *zone, int level, const char *fmt, ...) 867 ISC_FORMAT_PRINTF(3, 4); 868static void 869dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...) 870 ISC_FORMAT_PRINTF(3, 4); 871static void 872queue_xfrin(dns_zone_t *zone); 873static isc_result_t 874update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 875 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, 876 dns_rdata_t *rdata); 877static void 878zone_unload(dns_zone_t *zone); 879static void 880zone_expire(dns_zone_t *zone); 881static void 882zone_refresh(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 void 1018zmgr_tlsctx_attach(dns_zonemgr_t *zmgr, isc_tlsctx_cache_t **ptlsctx_cache); 1019/*%< 1020 * Attach to TLS client context cache used for zone transfers via 1021 * encrypted transports (e.g. XoT). 1022 * 1023 * The obtained reference needs to be detached by a call to 1024 * 'isc_tlsctx_cache_detach()' when not needed anymore. 1025 * 1026 * Requires: 1027 *\li 'zmgr' is a valid zone manager. 1028 *\li 'ptlsctx_cache' is not 'NULL' and points to 'NULL'. 1029 */ 1030 1031static const unsigned int dbargc_default = 1; 1032static const char *dbargv_default[] = { "rbt" }; 1033 1034#define DNS_ZONE_JITTER_ADD(a, b, c) \ 1035 do { \ 1036 isc_interval_t _i; \ 1037 uint32_t _j; \ 1038 _j = (b)-isc_random_uniform((b) / 4); \ 1039 isc_interval_set(&_i, _j, 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, _j / 2, 0); \ 1046 (void)isc_time_add((a), &_i, (c)); \ 1047 } \ 1048 } while (0) 1049 1050#define DNS_ZONE_TIME_ADD(a, b, c) \ 1051 do { \ 1052 isc_interval_t _i; \ 1053 isc_interval_set(&_i, (b), 0); \ 1054 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 1055 dns_zone_log(zone, ISC_LOG_WARNING, \ 1056 "epoch approaching: upgrade required: " \ 1057 "now + %s failed", \ 1058 #b); \ 1059 isc_interval_set(&_i, (b) / 2, 0); \ 1060 (void)isc_time_add((a), &_i, (c)); \ 1061 } \ 1062 } while (0) 1063 1064typedef struct nsec3param nsec3param_t; 1065struct nsec3param { 1066 dns_rdata_nsec3param_t rdata; 1067 unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1]; 1068 unsigned int length; 1069 bool nsec; 1070 bool replace; 1071 bool resalt; 1072 bool lookup; 1073 ISC_LINK(nsec3param_t) link; 1074}; 1075typedef ISC_LIST(nsec3param_t) nsec3paramlist_t; 1076struct np3event { 1077 isc_event_t event; 1078 nsec3param_t params; 1079}; 1080 1081struct ssevent { 1082 isc_event_t event; 1083 uint32_t serial; 1084}; 1085 1086struct stub_cb_args { 1087 dns_stub_t *stub; 1088 dns_tsigkey_t *tsig_key; 1089 uint16_t udpsize; 1090 int timeout; 1091 bool reqnsid; 1092}; 1093 1094struct stub_glue_request { 1095 dns_request_t *request; 1096 dns_name_t name; 1097 struct stub_cb_args *args; 1098 bool ipv4; 1099}; 1100 1101/*% 1102 * Increment resolver-related statistics counters. Zone must be locked. 1103 */ 1104static void 1105inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { 1106 if (zone->stats != NULL) { 1107 isc_stats_increment(zone->stats, counter); 1108 } 1109} 1110 1111/*** 1112 *** Public functions. 1113 ***/ 1114 1115isc_result_t 1116dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { 1117 isc_result_t result; 1118 isc_time_t now; 1119 dns_zone_t *zone = NULL; 1120 dns_zone_t z = { .masterformat = dns_masterformat_none, 1121 .journalsize = -1, 1122 .rdclass = dns_rdataclass_none, 1123 .type = dns_zone_none, 1124 .refresh = DNS_ZONE_DEFAULTREFRESH, 1125 .retry = DNS_ZONE_DEFAULTRETRY, 1126 .maxrefresh = DNS_ZONE_MAXREFRESH, 1127 .minrefresh = DNS_ZONE_MINREFRESH, 1128 .maxretry = DNS_ZONE_MAXRETRY, 1129 .minretry = DNS_ZONE_MINRETRY, 1130 .notifytype = dns_notifytype_yes, 1131 .zero_no_soa_ttl = true, 1132 .check_names = dns_severity_ignore, 1133 .idlein = DNS_DEFAULT_IDLEIN, 1134 .idleout = DNS_DEFAULT_IDLEOUT, 1135 .maxxfrin = MAX_XFER_TIME, 1136 .maxxfrout = MAX_XFER_TIME, 1137 .sigvalidityinterval = 30 * 24 * 3600, 1138 .sigresigninginterval = 7 * 24 * 3600, 1139 .statlevel = dns_zonestat_none, 1140 .notifydelay = 5, 1141 .signatures = 10, 1142 .nodes = 100, 1143 .privatetype = (dns_rdatatype_t)0xffffU, 1144 .rpz_num = DNS_RPZ_INVALID_NUM, 1145 .requestixfr = true, 1146 .ixfr_ratio = 100, 1147 .requestexpire = true, 1148 .updatemethod = dns_updatemethod_increment, 1149 .magic = ZONE_MAGIC }; 1150 1151 REQUIRE(zonep != NULL && *zonep == NULL); 1152 REQUIRE(mctx != NULL); 1153 1154 TIME_NOW(&now); 1155 zone = isc_mem_get(mctx, sizeof(*zone)); 1156 *zone = z; 1157 1158 zone->mctx = NULL; 1159 isc_mem_attach(mctx, &zone->mctx); 1160 isc_mutex_init(&zone->lock); 1161 ZONEDB_INITLOCK(&zone->dblock); 1162 /* XXX MPA check that all elements are initialised */ 1163#ifdef DNS_ZONE_CHECKLOCK 1164 zone->locked = false; 1165#endif /* ifdef DNS_ZONE_CHECKLOCK */ 1166 1167 zone->notifytime = now; 1168 1169 ISC_LINK_INIT(zone, link); 1170 isc_refcount_init(&zone->erefs, 1); 1171 isc_refcount_init(&zone->irefs, 0); 1172 dns_name_init(&zone->origin, NULL); 1173 ISC_LIST_INIT(zone->includes); 1174 ISC_LIST_INIT(zone->newincludes); 1175 atomic_init(&zone->flags, 0); 1176 atomic_init(&zone->options, 0); 1177 atomic_init(&zone->keyopts, 0); 1178 isc_time_settoepoch(&zone->expiretime); 1179 isc_time_settoepoch(&zone->refreshtime); 1180 isc_time_settoepoch(&zone->dumptime); 1181 isc_time_settoepoch(&zone->loadtime); 1182 isc_time_settoepoch(&zone->resigntime); 1183 isc_time_settoepoch(&zone->keywarntime); 1184 isc_time_settoepoch(&zone->signingtime); 1185 isc_time_settoepoch(&zone->nsec3chaintime); 1186 isc_time_settoepoch(&zone->refreshkeytime); 1187 ISC_LIST_INIT(zone->notifies); 1188 ISC_LIST_INIT(zone->checkds_requests); 1189 isc_sockaddr_any(&zone->notifysrc4); 1190 isc_sockaddr_any6(&zone->notifysrc6); 1191 isc_sockaddr_any(&zone->parentalsrc4); 1192 isc_sockaddr_any6(&zone->parentalsrc6); 1193 isc_sockaddr_any(&zone->xfrsource4); 1194 isc_sockaddr_any6(&zone->xfrsource6); 1195 isc_sockaddr_any(&zone->altxfrsource4); 1196 isc_sockaddr_any6(&zone->altxfrsource6); 1197 ISC_LINK_INIT(zone, statelink); 1198 ISC_LIST_INIT(zone->signing); 1199 ISC_LIST_INIT(zone->nsec3chain); 1200 ISC_LIST_INIT(zone->setnsec3param_queue); 1201 ISC_LIST_INIT(zone->forwards); 1202 ISC_LIST_INIT(zone->rss_events); 1203 ISC_LIST_INIT(zone->rss_post); 1204 1205 result = isc_stats_create(mctx, &zone->gluecachestats, 1206 dns_gluecachestatscounter_max); 1207 if (result != ISC_R_SUCCESS) { 1208 goto free_refs; 1209 } 1210 1211 /* Must be after magic is set. */ 1212 dns_zone_setdbtype(zone, dbargc_default, dbargv_default); 1213 1214 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL, 1215 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, NULL, 1216 NULL); 1217 *zonep = zone; 1218 return (ISC_R_SUCCESS); 1219 1220free_refs: 1221 isc_refcount_decrement0(&zone->erefs); 1222 isc_refcount_destroy(&zone->erefs); 1223 isc_refcount_destroy(&zone->irefs); 1224 ZONEDB_DESTROYLOCK(&zone->dblock); 1225 isc_mutex_destroy(&zone->lock); 1226 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone)); 1227 return (result); 1228} 1229 1230static void 1231clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) { 1232 dns_dnsseckey_t *key; 1233 while (!ISC_LIST_EMPTY(*list)) { 1234 key = ISC_LIST_HEAD(*list); 1235 ISC_LIST_UNLINK(*list, key, link); 1236 dns_dnsseckey_destroy(mctx, &key); 1237 } 1238} 1239 1240/* 1241 * Free a zone. Because we require that there be no more 1242 * outstanding events or references, no locking is necessary. 1243 */ 1244static void 1245zone_free(dns_zone_t *zone) { 1246 dns_signing_t *signing; 1247 dns_nsec3chain_t *nsec3chain; 1248 isc_event_t *event; 1249 dns_include_t *include; 1250 1251 REQUIRE(DNS_ZONE_VALID(zone)); 1252 isc_refcount_destroy(&zone->erefs); 1253 isc_refcount_destroy(&zone->irefs); 1254 REQUIRE(!LOCKED_ZONE(zone)); 1255 REQUIRE(zone->timer == NULL); 1256 REQUIRE(zone->zmgr == NULL); 1257 1258 /* 1259 * Managed objects. Order is important. 1260 */ 1261 if (zone->request != NULL) { 1262 dns_request_destroy(&zone->request); /* XXXMPA */ 1263 } 1264 INSIST(zone->readio == NULL); 1265 INSIST(zone->statelist == NULL); 1266 INSIST(zone->writeio == NULL); 1267 INSIST(zone->view == NULL); 1268 INSIST(zone->prev_view == NULL); 1269 1270 if (zone->task != NULL) { 1271 isc_task_detach(&zone->task); 1272 } 1273 if (zone->loadtask != NULL) { 1274 isc_task_detach(&zone->loadtask); 1275 } 1276 1277 /* Unmanaged objects */ 1278 while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) { 1279 event = ISC_LIST_HEAD(zone->setnsec3param_queue); 1280 ISC_LIST_UNLINK(zone->setnsec3param_queue, event, ev_link); 1281 isc_event_free(&event); 1282 } 1283 while (!ISC_LIST_EMPTY(zone->rss_post)) { 1284 event = ISC_LIST_HEAD(zone->rss_post); 1285 ISC_LIST_UNLINK(zone->rss_post, event, ev_link); 1286 isc_event_free(&event); 1287 } 1288 for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; 1289 signing = ISC_LIST_HEAD(zone->signing)) 1290 { 1291 ISC_LIST_UNLINK(zone->signing, signing, link); 1292 dns_db_detach(&signing->db); 1293 dns_dbiterator_destroy(&signing->dbiterator); 1294 isc_mem_put(zone->mctx, signing, sizeof *signing); 1295 } 1296 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL; 1297 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) 1298 { 1299 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 1300 dns_db_detach(&nsec3chain->db); 1301 dns_dbiterator_destroy(&nsec3chain->dbiterator); 1302 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 1303 } 1304 for (include = ISC_LIST_HEAD(zone->includes); include != NULL; 1305 include = ISC_LIST_HEAD(zone->includes)) 1306 { 1307 ISC_LIST_UNLINK(zone->includes, include, link); 1308 isc_mem_free(zone->mctx, include->name); 1309 isc_mem_put(zone->mctx, include, sizeof *include); 1310 } 1311 for (include = ISC_LIST_HEAD(zone->newincludes); include != NULL; 1312 include = ISC_LIST_HEAD(zone->newincludes)) 1313 { 1314 ISC_LIST_UNLINK(zone->newincludes, include, link); 1315 isc_mem_free(zone->mctx, include->name); 1316 isc_mem_put(zone->mctx, include, sizeof *include); 1317 } 1318 if (zone->masterfile != NULL) { 1319 isc_mem_free(zone->mctx, zone->masterfile); 1320 } 1321 zone->masterfile = NULL; 1322 if (zone->keydirectory != NULL) { 1323 isc_mem_free(zone->mctx, zone->keydirectory); 1324 } 1325 zone->keydirectory = NULL; 1326 if (zone->kasp != NULL) { 1327 dns_kasp_detach(&zone->kasp); 1328 } 1329 if (!ISC_LIST_EMPTY(zone->checkds_ok)) { 1330 clear_keylist(&zone->checkds_ok, zone->mctx); 1331 } 1332 1333 zone->journalsize = -1; 1334 if (zone->journal != NULL) { 1335 isc_mem_free(zone->mctx, zone->journal); 1336 } 1337 zone->journal = NULL; 1338 if (zone->stats != NULL) { 1339 isc_stats_detach(&zone->stats); 1340 } 1341 if (zone->requeststats != NULL) { 1342 isc_stats_detach(&zone->requeststats); 1343 } 1344 if (zone->rcvquerystats != NULL) { 1345 dns_stats_detach(&zone->rcvquerystats); 1346 } 1347 if (zone->dnssecsignstats != NULL) { 1348 dns_stats_detach(&zone->dnssecsignstats); 1349 } 1350 if (zone->db != NULL) { 1351 zone_detachdb(zone); 1352 } 1353 if (zone->rpzs != NULL) { 1354 REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones); 1355 dns_rpz_detach_rpzs(&zone->rpzs); 1356 zone->rpz_num = DNS_RPZ_INVALID_NUM; 1357 } 1358 if (zone->catzs != NULL) { 1359 dns_catz_detach_catzs(&zone->catzs); 1360 } 1361 zone_freedbargs(zone); 1362 dns_zone_setparentals(zone, NULL, NULL, NULL, 0); 1363 dns_zone_setprimaries(zone, NULL, NULL, NULL, 0); 1364 dns_zone_setalsonotify(zone, NULL, NULL, NULL, 0); 1365 1366 zone->check_names = dns_severity_ignore; 1367 if (zone->update_acl != NULL) { 1368 dns_acl_detach(&zone->update_acl); 1369 } 1370 if (zone->forward_acl != NULL) { 1371 dns_acl_detach(&zone->forward_acl); 1372 } 1373 if (zone->notify_acl != NULL) { 1374 dns_acl_detach(&zone->notify_acl); 1375 } 1376 if (zone->query_acl != NULL) { 1377 dns_acl_detach(&zone->query_acl); 1378 } 1379 if (zone->queryon_acl != NULL) { 1380 dns_acl_detach(&zone->queryon_acl); 1381 } 1382 if (zone->xfr_acl != NULL) { 1383 dns_acl_detach(&zone->xfr_acl); 1384 } 1385 if (dns_name_dynamic(&zone->origin)) { 1386 dns_name_free(&zone->origin, zone->mctx); 1387 } 1388 if (zone->strnamerd != NULL) { 1389 isc_mem_free(zone->mctx, zone->strnamerd); 1390 } 1391 if (zone->strname != NULL) { 1392 isc_mem_free(zone->mctx, zone->strname); 1393 } 1394 if (zone->strrdclass != NULL) { 1395 isc_mem_free(zone->mctx, zone->strrdclass); 1396 } 1397 if (zone->strviewname != NULL) { 1398 isc_mem_free(zone->mctx, zone->strviewname); 1399 } 1400 if (zone->ssutable != NULL) { 1401 dns_ssutable_detach(&zone->ssutable); 1402 } 1403 if (zone->gluecachestats != NULL) { 1404 isc_stats_detach(&zone->gluecachestats); 1405 } 1406 1407 /* last stuff */ 1408 ZONEDB_DESTROYLOCK(&zone->dblock); 1409 isc_mutex_destroy(&zone->lock); 1410 zone->magic = 0; 1411 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone)); 1412} 1413 1414/* 1415 * Returns true iff this the signed side of an inline-signing zone. 1416 * Caller should hold zone lock. 1417 */ 1418static bool 1419inline_secure(dns_zone_t *zone) { 1420 REQUIRE(DNS_ZONE_VALID(zone)); 1421 if (zone->raw != NULL) { 1422 return (true); 1423 } 1424 return (false); 1425} 1426 1427/* 1428 * Returns true iff this the unsigned side of an inline-signing zone 1429 * Caller should hold zone lock. 1430 */ 1431static bool 1432inline_raw(dns_zone_t *zone) { 1433 REQUIRE(DNS_ZONE_VALID(zone)); 1434 if (zone->secure != NULL) { 1435 return (true); 1436 } 1437 return (false); 1438} 1439 1440/* 1441 * Single shot. 1442 */ 1443void 1444dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) { 1445 char namebuf[1024]; 1446 1447 REQUIRE(DNS_ZONE_VALID(zone)); 1448 REQUIRE(rdclass != dns_rdataclass_none); 1449 1450 /* 1451 * Test and set. 1452 */ 1453 LOCK_ZONE(zone); 1454 INSIST(zone != zone->raw); 1455 REQUIRE(zone->rdclass == dns_rdataclass_none || 1456 zone->rdclass == rdclass); 1457 zone->rdclass = rdclass; 1458 1459 if (zone->strnamerd != NULL) { 1460 isc_mem_free(zone->mctx, zone->strnamerd); 1461 } 1462 if (zone->strrdclass != NULL) { 1463 isc_mem_free(zone->mctx, zone->strrdclass); 1464 } 1465 1466 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1467 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1468 zone_rdclass_tostr(zone, namebuf, sizeof namebuf); 1469 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf); 1470 1471 if (inline_secure(zone)) { 1472 dns_zone_setclass(zone->raw, rdclass); 1473 } 1474 UNLOCK_ZONE(zone); 1475} 1476 1477dns_rdataclass_t 1478dns_zone_getclass(dns_zone_t *zone) { 1479 REQUIRE(DNS_ZONE_VALID(zone)); 1480 1481 return (zone->rdclass); 1482} 1483 1484void 1485dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { 1486 REQUIRE(DNS_ZONE_VALID(zone)); 1487 1488 LOCK_ZONE(zone); 1489 zone->notifytype = notifytype; 1490 UNLOCK_ZONE(zone); 1491} 1492 1493isc_result_t 1494dns_zone_getserial(dns_zone_t *zone, uint32_t *serialp) { 1495 isc_result_t result; 1496 unsigned int soacount; 1497 1498 REQUIRE(DNS_ZONE_VALID(zone)); 1499 REQUIRE(serialp != NULL); 1500 1501 LOCK_ZONE(zone); 1502 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1503 if (zone->db != NULL) { 1504 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, 1505 serialp, NULL, NULL, NULL, NULL, 1506 NULL); 1507 if (result == ISC_R_SUCCESS && soacount == 0) { 1508 result = ISC_R_FAILURE; 1509 } 1510 } else { 1511 result = DNS_R_NOTLOADED; 1512 } 1513 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1514 UNLOCK_ZONE(zone); 1515 1516 return (result); 1517} 1518 1519/* 1520 * Single shot. 1521 */ 1522void 1523dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) { 1524 char namebuf[1024]; 1525 1526 REQUIRE(DNS_ZONE_VALID(zone)); 1527 REQUIRE(type != dns_zone_none); 1528 1529 /* 1530 * Test and set. 1531 */ 1532 LOCK_ZONE(zone); 1533 REQUIRE(zone->type == dns_zone_none || zone->type == type); 1534 zone->type = type; 1535 1536 if (zone->strnamerd != NULL) { 1537 isc_mem_free(zone->mctx, zone->strnamerd); 1538 } 1539 1540 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1541 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1542 UNLOCK_ZONE(zone); 1543} 1544 1545static void 1546zone_freedbargs(dns_zone_t *zone) { 1547 unsigned int i; 1548 1549 /* Free the old database argument list. */ 1550 if (zone->db_argv != NULL) { 1551 for (i = 0; i < zone->db_argc; i++) { 1552 isc_mem_free(zone->mctx, zone->db_argv[i]); 1553 } 1554 isc_mem_put(zone->mctx, zone->db_argv, 1555 zone->db_argc * sizeof(*zone->db_argv)); 1556 } 1557 zone->db_argc = 0; 1558 zone->db_argv = NULL; 1559} 1560 1561isc_result_t 1562dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) { 1563 size_t size = 0; 1564 unsigned int i; 1565 isc_result_t result = ISC_R_SUCCESS; 1566 void *mem; 1567 char **tmp, *tmp2, *base; 1568 1569 REQUIRE(DNS_ZONE_VALID(zone)); 1570 REQUIRE(argv != NULL && *argv == NULL); 1571 1572 LOCK_ZONE(zone); 1573 size = (zone->db_argc + 1) * sizeof(char *); 1574 for (i = 0; i < zone->db_argc; i++) { 1575 size += strlen(zone->db_argv[i]) + 1; 1576 } 1577 mem = isc_mem_allocate(mctx, size); 1578 { 1579 tmp = mem; 1580 tmp2 = mem; 1581 base = mem; 1582 tmp2 += (zone->db_argc + 1) * sizeof(char *); 1583 for (i = 0; i < zone->db_argc; i++) { 1584 *tmp++ = tmp2; 1585 strlcpy(tmp2, zone->db_argv[i], size - (tmp2 - base)); 1586 tmp2 += strlen(tmp2) + 1; 1587 } 1588 *tmp = NULL; 1589 } 1590 UNLOCK_ZONE(zone); 1591 *argv = mem; 1592 return (result); 1593} 1594 1595void 1596dns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc, 1597 const char *const *dbargv) { 1598 char **argv = NULL; 1599 unsigned int i; 1600 1601 REQUIRE(DNS_ZONE_VALID(zone)); 1602 REQUIRE(dbargc >= 1); 1603 REQUIRE(dbargv != NULL); 1604 1605 LOCK_ZONE(zone); 1606 1607 /* Set up a new database argument list. */ 1608 argv = isc_mem_get(zone->mctx, dbargc * sizeof(*argv)); 1609 for (i = 0; i < dbargc; i++) { 1610 argv[i] = NULL; 1611 } 1612 for (i = 0; i < dbargc; i++) { 1613 argv[i] = isc_mem_strdup(zone->mctx, dbargv[i]); 1614 } 1615 1616 /* Free the old list. */ 1617 zone_freedbargs(zone); 1618 1619 zone->db_argc = dbargc; 1620 zone->db_argv = argv; 1621 1622 UNLOCK_ZONE(zone); 1623} 1624 1625static void 1626dns_zone_setview_helper(dns_zone_t *zone, dns_view_t *view) { 1627 char namebuf[1024]; 1628 1629 if (zone->prev_view == NULL && zone->view != NULL) { 1630 dns_view_weakattach(zone->view, &zone->prev_view); 1631 } 1632 1633 INSIST(zone != zone->raw); 1634 if (zone->view != NULL) { 1635 dns_view_sfd_del(zone->view, &zone->origin); 1636 dns_view_weakdetach(&zone->view); 1637 } 1638 dns_view_weakattach(view, &zone->view); 1639 dns_view_sfd_add(view, &zone->origin); 1640 1641 if (zone->strviewname != NULL) { 1642 isc_mem_free(zone->mctx, zone->strviewname); 1643 } 1644 if (zone->strnamerd != NULL) { 1645 isc_mem_free(zone->mctx, zone->strnamerd); 1646 } 1647 1648 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1649 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1650 zone_viewname_tostr(zone, namebuf, sizeof namebuf); 1651 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf); 1652 1653 if (inline_secure(zone)) { 1654 dns_zone_setview(zone->raw, view); 1655 } 1656} 1657 1658void 1659dns_zone_setview(dns_zone_t *zone, dns_view_t *view) { 1660 REQUIRE(DNS_ZONE_VALID(zone)); 1661 1662 LOCK_ZONE(zone); 1663 dns_zone_setview_helper(zone, view); 1664 UNLOCK_ZONE(zone); 1665} 1666 1667dns_view_t * 1668dns_zone_getview(dns_zone_t *zone) { 1669 REQUIRE(DNS_ZONE_VALID(zone)); 1670 1671 return (zone->view); 1672} 1673 1674void 1675dns_zone_setviewcommit(dns_zone_t *zone) { 1676 REQUIRE(DNS_ZONE_VALID(zone)); 1677 1678 LOCK_ZONE(zone); 1679 if (zone->prev_view != NULL) { 1680 dns_view_weakdetach(&zone->prev_view); 1681 } 1682 if (inline_secure(zone)) { 1683 dns_zone_setviewcommit(zone->raw); 1684 } 1685 UNLOCK_ZONE(zone); 1686} 1687 1688void 1689dns_zone_setviewrevert(dns_zone_t *zone) { 1690 REQUIRE(DNS_ZONE_VALID(zone)); 1691 1692 LOCK_ZONE(zone); 1693 if (zone->prev_view != NULL) { 1694 dns_zone_setview_helper(zone, zone->prev_view); 1695 dns_view_weakdetach(&zone->prev_view); 1696 } 1697 if (zone->catzs != NULL) { 1698 zone_catz_enable(zone, zone->catzs); 1699 } 1700 if (inline_secure(zone)) { 1701 dns_zone_setviewrevert(zone->raw); 1702 } 1703 UNLOCK_ZONE(zone); 1704} 1705 1706isc_result_t 1707dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) { 1708 isc_result_t result = ISC_R_SUCCESS; 1709 char namebuf[1024]; 1710 1711 REQUIRE(DNS_ZONE_VALID(zone)); 1712 REQUIRE(origin != NULL); 1713 1714 LOCK_ZONE(zone); 1715 INSIST(zone != zone->raw); 1716 if (dns_name_dynamic(&zone->origin)) { 1717 dns_name_free(&zone->origin, zone->mctx); 1718 dns_name_init(&zone->origin, NULL); 1719 } 1720 dns_name_dup(origin, zone->mctx, &zone->origin); 1721 1722 if (zone->strnamerd != NULL) { 1723 isc_mem_free(zone->mctx, zone->strnamerd); 1724 } 1725 if (zone->strname != NULL) { 1726 isc_mem_free(zone->mctx, zone->strname); 1727 } 1728 1729 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1730 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1731 zone_name_tostr(zone, namebuf, sizeof namebuf); 1732 zone->strname = isc_mem_strdup(zone->mctx, namebuf); 1733 1734 if (inline_secure(zone)) { 1735 result = dns_zone_setorigin(zone->raw, origin); 1736 } 1737 UNLOCK_ZONE(zone); 1738 return (result); 1739} 1740 1741static isc_result_t 1742dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) { 1743 char *copy; 1744 1745 if (value != NULL) { 1746 copy = isc_mem_strdup(zone->mctx, value); 1747 } else { 1748 copy = NULL; 1749 } 1750 1751 if (*field != NULL) { 1752 isc_mem_free(zone->mctx, *field); 1753 } 1754 1755 *field = copy; 1756 return (ISC_R_SUCCESS); 1757} 1758 1759isc_result_t 1760dns_zone_setfile(dns_zone_t *zone, const char *file, dns_masterformat_t format, 1761 const dns_master_style_t *style) { 1762 isc_result_t result = ISC_R_SUCCESS; 1763 1764 REQUIRE(DNS_ZONE_VALID(zone)); 1765 REQUIRE(zone->stream == NULL); 1766 1767 LOCK_ZONE(zone); 1768 result = dns_zone_setstring(zone, &zone->masterfile, file); 1769 if (result == ISC_R_SUCCESS) { 1770 zone->masterformat = format; 1771 if (format == dns_masterformat_text) { 1772 zone->masterstyle = style; 1773 } 1774 result = default_journal(zone); 1775 } 1776 UNLOCK_ZONE(zone); 1777 1778 return (result); 1779} 1780 1781const char * 1782dns_zone_getfile(dns_zone_t *zone) { 1783 REQUIRE(DNS_ZONE_VALID(zone)); 1784 1785 return (zone->masterfile); 1786} 1787 1788isc_result_t 1789dns_zone_setstream(dns_zone_t *zone, const FILE *stream, 1790 dns_masterformat_t format, const dns_master_style_t *style) { 1791 isc_result_t result = ISC_R_SUCCESS; 1792 1793 REQUIRE(DNS_ZONE_VALID(zone)); 1794 REQUIRE(stream != NULL); 1795 REQUIRE(zone->masterfile == NULL); 1796 1797 LOCK_ZONE(zone); 1798 zone->stream = stream; 1799 zone->masterformat = format; 1800 if (format == dns_masterformat_text) { 1801 zone->masterstyle = style; 1802 } 1803 result = default_journal(zone); 1804 UNLOCK_ZONE(zone); 1805 1806 return (result); 1807} 1808 1809dns_ttl_t 1810dns_zone_getmaxttl(dns_zone_t *zone) { 1811 REQUIRE(DNS_ZONE_VALID(zone)); 1812 1813 return (zone->maxttl); 1814} 1815 1816void 1817dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) { 1818 REQUIRE(DNS_ZONE_VALID(zone)); 1819 1820 LOCK_ZONE(zone); 1821 if (maxttl != 0) { 1822 DNS_ZONE_SETOPTION(zone, DNS_ZONEOPT_CHECKTTL); 1823 } else { 1824 DNS_ZONE_CLROPTION(zone, DNS_ZONEOPT_CHECKTTL); 1825 } 1826 zone->maxttl = maxttl; 1827 UNLOCK_ZONE(zone); 1828 1829 return; 1830} 1831 1832static isc_result_t 1833default_journal(dns_zone_t *zone) { 1834 isc_result_t result; 1835 char *journal; 1836 1837 REQUIRE(DNS_ZONE_VALID(zone)); 1838 REQUIRE(LOCKED_ZONE(zone)); 1839 1840 if (zone->masterfile != NULL) { 1841 /* Calculate string length including '\0'. */ 1842 int len = strlen(zone->masterfile) + sizeof(".jnl"); 1843 journal = isc_mem_allocate(zone->mctx, len); 1844 strlcpy(journal, zone->masterfile, len); 1845 strlcat(journal, ".jnl", len); 1846 } else { 1847 journal = NULL; 1848 } 1849 result = dns_zone_setstring(zone, &zone->journal, journal); 1850 if (journal != NULL) { 1851 isc_mem_free(zone->mctx, journal); 1852 } 1853 return (result); 1854} 1855 1856isc_result_t 1857dns_zone_setjournal(dns_zone_t *zone, const char *myjournal) { 1858 isc_result_t result = ISC_R_SUCCESS; 1859 1860 REQUIRE(DNS_ZONE_VALID(zone)); 1861 1862 LOCK_ZONE(zone); 1863 result = dns_zone_setstring(zone, &zone->journal, myjournal); 1864 UNLOCK_ZONE(zone); 1865 1866 return (result); 1867} 1868 1869char * 1870dns_zone_getjournal(dns_zone_t *zone) { 1871 REQUIRE(DNS_ZONE_VALID(zone)); 1872 1873 return (zone->journal); 1874} 1875 1876/* 1877 * Return true iff the zone is "dynamic", in the sense that the zone's 1878 * master file (if any) is written by the server, rather than being 1879 * updated manually and read by the server. 1880 * 1881 * This is true for secondary zones, mirror zones, stub zones, key zones, 1882 * and zones that allow dynamic updates either by having an update 1883 * policy ("ssutable") or an "allow-update" ACL with a value other than 1884 * exactly "{ none; }". 1885 */ 1886bool 1887dns_zone_isdynamic(dns_zone_t *zone, bool ignore_freeze) { 1888 REQUIRE(DNS_ZONE_VALID(zone)); 1889 1890 if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror || 1891 zone->type == dns_zone_stub || zone->type == dns_zone_key || 1892 (zone->type == dns_zone_redirect && zone->primaries != NULL)) 1893 { 1894 return (true); 1895 } 1896 1897 /* Inline zones are always dynamic. */ 1898 if (zone->type == dns_zone_primary && zone->raw != NULL) { 1899 return (true); 1900 } 1901 1902 /* If !ignore_freeze, we need check whether updates are disabled. */ 1903 if (zone->type == dns_zone_primary && 1904 (!zone->update_disabled || ignore_freeze) && 1905 ((zone->ssutable != NULL) || 1906 (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)))) 1907 { 1908 return (true); 1909 } 1910 1911 return (false); 1912} 1913 1914/* 1915 * Set the response policy index and information for a zone. 1916 */ 1917isc_result_t 1918dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs, 1919 dns_rpz_num_t rpz_num) { 1920 /* 1921 * Only RBTDB zones can be used for response policy zones, 1922 * because only they have the code to create the summary data. 1923 * Only zones that are loaded instead of mmap()ed create the 1924 * summary data and so can be policy zones. 1925 */ 1926 if (strcmp(zone->db_argv[0], "rbt") != 0 && 1927 strcmp(zone->db_argv[0], "rbt64") != 0) 1928 { 1929 return (ISC_R_NOTIMPLEMENTED); 1930 } 1931 1932 /* 1933 * This must happen only once or be redundant. 1934 */ 1935 LOCK_ZONE(zone); 1936 if (zone->rpzs != NULL) { 1937 REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num); 1938 } else { 1939 REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM); 1940 dns_rpz_attach_rpzs(rpzs, &zone->rpzs); 1941 zone->rpz_num = rpz_num; 1942 } 1943 rpzs->defined |= DNS_RPZ_ZBIT(rpz_num); 1944 UNLOCK_ZONE(zone); 1945 1946 return (ISC_R_SUCCESS); 1947} 1948 1949dns_rpz_num_t 1950dns_zone_get_rpz_num(dns_zone_t *zone) { 1951 return (zone->rpz_num); 1952} 1953 1954/* 1955 * If a zone is a response policy zone, mark its new database. 1956 */ 1957void 1958dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) { 1959 isc_result_t result; 1960 if (zone->rpz_num == DNS_RPZ_INVALID_NUM) { 1961 return; 1962 } 1963 REQUIRE(zone->rpzs != NULL); 1964 result = dns_db_updatenotify_register(db, dns_rpz_dbupdate_callback, 1965 zone->rpzs->zones[zone->rpz_num]); 1966 REQUIRE(result == ISC_R_SUCCESS); 1967} 1968 1969static void 1970dns_zone_rpz_disable_db(dns_zone_t *zone, dns_db_t *db) { 1971 if (zone->rpz_num == DNS_RPZ_INVALID_NUM) { 1972 return; 1973 } 1974 REQUIRE(zone->rpzs != NULL); 1975 (void)dns_db_updatenotify_unregister(db, dns_rpz_dbupdate_callback, 1976 zone->rpzs->zones[zone->rpz_num]); 1977} 1978 1979/* 1980 * If a zone is a catalog zone, attach it to update notification in database. 1981 */ 1982void 1983dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) { 1984 REQUIRE(DNS_ZONE_VALID(zone)); 1985 REQUIRE(db != NULL); 1986 1987 if (zone->catzs != NULL) { 1988 dns_catz_dbupdate_register(db, zone->catzs); 1989 } 1990} 1991 1992static void 1993dns_zone_catz_disable_db(dns_zone_t *zone, dns_db_t *db) { 1994 REQUIRE(DNS_ZONE_VALID(zone)); 1995 REQUIRE(db != NULL); 1996 1997 if (zone->catzs != NULL) { 1998 dns_catz_dbupdate_unregister(db, zone->catzs); 1999 } 2000} 2001 2002static void 2003zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) { 2004 REQUIRE(DNS_ZONE_VALID(zone)); 2005 REQUIRE(catzs != NULL); 2006 2007 INSIST(zone->catzs == NULL || zone->catzs == catzs); 2008 dns_catz_catzs_set_view(catzs, zone->view); 2009 if (zone->catzs == NULL) { 2010 dns_catz_attach_catzs(catzs, &zone->catzs); 2011 } 2012} 2013 2014void 2015dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) { 2016 REQUIRE(DNS_ZONE_VALID(zone)); 2017 2018 LOCK_ZONE(zone); 2019 zone_catz_enable(zone, catzs); 2020 UNLOCK_ZONE(zone); 2021} 2022 2023static void 2024zone_catz_disable(dns_zone_t *zone) { 2025 REQUIRE(DNS_ZONE_VALID(zone)); 2026 2027 if (zone->catzs != NULL) { 2028 if (zone->db != NULL) { 2029 dns_zone_catz_disable_db(zone, zone->db); 2030 } 2031 dns_catz_detach_catzs(&zone->catzs); 2032 } 2033} 2034 2035void 2036dns_zone_catz_disable(dns_zone_t *zone) { 2037 REQUIRE(DNS_ZONE_VALID(zone)); 2038 2039 LOCK_ZONE(zone); 2040 zone_catz_disable(zone); 2041 UNLOCK_ZONE(zone); 2042} 2043 2044bool 2045dns_zone_catz_is_enabled(dns_zone_t *zone) { 2046 REQUIRE(DNS_ZONE_VALID(zone)); 2047 2048 return (zone->catzs != NULL); 2049} 2050 2051/* 2052 * Set catalog zone ownership of the zone 2053 */ 2054void 2055dns_zone_set_parentcatz(dns_zone_t *zone, dns_catz_zone_t *catz) { 2056 REQUIRE(DNS_ZONE_VALID(zone)); 2057 REQUIRE(catz != NULL); 2058 LOCK_ZONE(zone); 2059 INSIST(zone->parentcatz == NULL || zone->parentcatz == catz); 2060 zone->parentcatz = catz; 2061 UNLOCK_ZONE(zone); 2062} 2063 2064dns_catz_zone_t * 2065dns_zone_get_parentcatz(const dns_zone_t *zone) { 2066 REQUIRE(DNS_ZONE_VALID(zone)); 2067 return (zone->parentcatz); 2068} 2069 2070static bool 2071zone_touched(dns_zone_t *zone) { 2072 isc_result_t result; 2073 isc_time_t modtime; 2074 dns_include_t *include; 2075 2076 REQUIRE(DNS_ZONE_VALID(zone)); 2077 2078 result = isc_file_getmodtime(zone->masterfile, &modtime); 2079 if (result != ISC_R_SUCCESS || 2080 isc_time_compare(&modtime, &zone->loadtime) > 0) 2081 { 2082 return (true); 2083 } 2084 2085 for (include = ISC_LIST_HEAD(zone->includes); include != NULL; 2086 include = ISC_LIST_NEXT(include, link)) 2087 { 2088 result = isc_file_getmodtime(include->name, &modtime); 2089 if (result != ISC_R_SUCCESS || 2090 isc_time_compare(&modtime, &include->filetime) > 0) 2091 { 2092 return (true); 2093 } 2094 } 2095 2096 return (false); 2097} 2098 2099/* 2100 * Note: when dealing with inline-signed zones, external callers will always 2101 * call zone_load() for the secure zone; zone_load() calls itself recursively 2102 * in order to load the raw zone. 2103 */ 2104static isc_result_t 2105zone_load(dns_zone_t *zone, unsigned int flags, bool locked) { 2106 isc_result_t result; 2107 isc_time_t now; 2108 isc_time_t loadtime; 2109 dns_db_t *db = NULL; 2110 bool rbt, hasraw, is_dynamic; 2111 2112 REQUIRE(DNS_ZONE_VALID(zone)); 2113 2114 if (!locked) { 2115 LOCK_ZONE(zone); 2116 } 2117 2118 INSIST(zone != zone->raw); 2119 hasraw = inline_secure(zone); 2120 if (hasraw) { 2121 /* 2122 * We are trying to load an inline-signed zone. First call 2123 * self recursively to try loading the raw version of the zone. 2124 * Assuming the raw zone file is readable, there are two 2125 * possibilities: 2126 * 2127 * a) the raw zone was not yet loaded and thus it will be 2128 * loaded now, synchronously; if this succeeds, a 2129 * subsequent attempt to load the signed zone file will 2130 * take place and thus zone_postload() will be called 2131 * twice: first for the raw zone and then for the secure 2132 * zone; the latter call will take care of syncing the raw 2133 * version with the secure version, 2134 * 2135 * b) the raw zone was already loaded and we are trying to 2136 * reload it, which will happen asynchronously; this means 2137 * zone_postload() will only be called for the raw zone 2138 * because "result" returned by the zone_load() call below 2139 * will not be ISC_R_SUCCESS but rather DNS_R_CONTINUE; 2140 * zone_postload() called for the raw zone will take care 2141 * of syncing the raw version with the secure version. 2142 */ 2143 result = zone_load(zone->raw, flags, false); 2144 if (result != ISC_R_SUCCESS) { 2145 if (!locked) { 2146 UNLOCK_ZONE(zone); 2147 } 2148 return (result); 2149 } 2150 LOCK_ZONE(zone->raw); 2151 } 2152 2153 TIME_NOW(&now); 2154 2155 INSIST(zone->type != dns_zone_none); 2156 2157 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { 2158 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) { 2159 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 2160 } 2161 result = DNS_R_CONTINUE; 2162 goto cleanup; 2163 } 2164 2165 INSIST(zone->db_argc >= 1); 2166 2167 rbt = strcmp(zone->db_argv[0], "rbt") == 0 || 2168 strcmp(zone->db_argv[0], "rbt64") == 0; 2169 2170 if (zone->db != NULL && zone->masterfile == NULL && rbt) { 2171 /* 2172 * The zone has no master file configured. 2173 */ 2174 result = ISC_R_SUCCESS; 2175 goto cleanup; 2176 } 2177 2178 is_dynamic = dns_zone_isdynamic(zone, false); 2179 if (zone->db != NULL && is_dynamic) { 2180 /* 2181 * This is a secondary, stub, or dynamically updated zone 2182 * being reloaded. Do nothing - the database we already 2183 * have is guaranteed to be up-to-date. 2184 */ 2185 if (zone->type == dns_zone_primary && !hasraw) { 2186 result = DNS_R_DYNAMIC; 2187 } else { 2188 result = ISC_R_SUCCESS; 2189 } 2190 goto cleanup; 2191 } 2192 2193 /* 2194 * Store the current time before the zone is loaded, so that if the 2195 * file changes between the time of the load and the time that 2196 * zone->loadtime is set, then the file will still be reloaded 2197 * the next time dns_zone_load is called. 2198 */ 2199 TIME_NOW(&loadtime); 2200 2201 /* 2202 * Don't do the load if the file that stores the zone is older 2203 * than the last time the zone was loaded. If the zone has not 2204 * been loaded yet, zone->loadtime will be the epoch. 2205 */ 2206 if (zone->masterfile != NULL) { 2207 isc_time_t filetime; 2208 2209 /* 2210 * The file is already loaded. If we are just doing a 2211 * "rndc reconfig", we are done. 2212 */ 2213 if (!isc_time_isepoch(&zone->loadtime) && 2214 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) 2215 { 2216 result = ISC_R_SUCCESS; 2217 goto cleanup; 2218 } 2219 2220 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 2221 !zone_touched(zone)) 2222 { 2223 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2224 ISC_LOG_DEBUG(1), 2225 "skipping load: master file " 2226 "older than last load"); 2227 result = DNS_R_UPTODATE; 2228 goto cleanup; 2229 } 2230 2231 /* 2232 * If the file modification time is in the past 2233 * set loadtime to that value. 2234 */ 2235 result = isc_file_getmodtime(zone->masterfile, &filetime); 2236 if (result == ISC_R_SUCCESS && 2237 isc_time_compare(&loadtime, &filetime) > 0) 2238 { 2239 loadtime = filetime; 2240 } 2241 } 2242 2243 /* 2244 * Built in zones (with the exception of empty zones) don't need 2245 * to be reloaded. 2246 */ 2247 if (zone->type == dns_zone_primary && 2248 strcmp(zone->db_argv[0], "_builtin") == 0 && 2249 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) && 2250 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 2251 { 2252 result = ISC_R_SUCCESS; 2253 goto cleanup; 2254 } 2255 2256 /* 2257 * Zones associated with a DLZ don't need to be loaded either, 2258 * but we need to associate the database with the zone object. 2259 */ 2260 if (strcmp(zone->db_argv[0], "dlz") == 0) { 2261 dns_dlzdb_t *dlzdb; 2262 dns_dlzfindzone_t findzone; 2263 2264 for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched); 2265 dlzdb != NULL; dlzdb = ISC_LIST_NEXT(dlzdb, link)) 2266 { 2267 INSIST(DNS_DLZ_VALID(dlzdb)); 2268 if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0) { 2269 break; 2270 } 2271 } 2272 2273 if (dlzdb == NULL) { 2274 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2275 ISC_LOG_ERROR, 2276 "DLZ %s does not exist or is set " 2277 "to 'search yes;'", 2278 zone->db_argv[1]); 2279 result = ISC_R_NOTFOUND; 2280 goto cleanup; 2281 } 2282 2283 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 2284 /* ask SDLZ driver if the zone is supported */ 2285 findzone = dlzdb->implementation->methods->findzone; 2286 result = (*findzone)(dlzdb->implementation->driverarg, 2287 dlzdb->dbdata, dlzdb->mctx, 2288 zone->view->rdclass, &zone->origin, NULL, 2289 NULL, &db); 2290 if (result != ISC_R_NOTFOUND) { 2291 if (zone->db != NULL) { 2292 zone_detachdb(zone); 2293 } 2294 zone_attachdb(zone, db); 2295 dns_db_detach(&db); 2296 result = ISC_R_SUCCESS; 2297 } 2298 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 2299 2300 if (result == ISC_R_SUCCESS) { 2301 if (dlzdb->configure_callback == NULL) { 2302 goto cleanup; 2303 } 2304 2305 result = (*dlzdb->configure_callback)(zone->view, dlzdb, 2306 zone); 2307 if (result != ISC_R_SUCCESS) { 2308 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2309 ISC_LOG_ERROR, 2310 "DLZ configuration callback: %s", 2311 isc_result_totext(result)); 2312 } 2313 } 2314 goto cleanup; 2315 } 2316 2317 if ((zone->type == dns_zone_secondary || 2318 zone->type == dns_zone_mirror || zone->type == dns_zone_stub || 2319 (zone->type == dns_zone_redirect && zone->primaries != NULL)) && 2320 rbt) 2321 { 2322 if (zone->stream == NULL && 2323 (zone->masterfile == NULL || 2324 !isc_file_exists(zone->masterfile))) 2325 { 2326 if (zone->masterfile != NULL) { 2327 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2328 ISC_LOG_DEBUG(1), 2329 "no master file"); 2330 } 2331 zone->refreshtime = now; 2332 if (zone->task != NULL) { 2333 zone_settimer(zone, &now); 2334 } 2335 result = ISC_R_SUCCESS; 2336 goto cleanup; 2337 } 2338 } 2339 2340 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1), 2341 "starting load"); 2342 2343 result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, 2344 (zone->type == dns_zone_stub) ? dns_dbtype_stub 2345 : dns_dbtype_zone, 2346 zone->rdclass, zone->db_argc - 1, 2347 zone->db_argv + 1, &db); 2348 2349 if (result != ISC_R_SUCCESS) { 2350 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 2351 "loading zone: creating database: %s", 2352 isc_result_totext(result)); 2353 goto cleanup; 2354 } 2355 dns_db_settask(db, zone->task); 2356 2357 if (zone->type == dns_zone_primary || 2358 zone->type == dns_zone_secondary || zone->type == dns_zone_mirror) 2359 { 2360 result = dns_db_setgluecachestats(db, zone->gluecachestats); 2361 if (result == ISC_R_NOTIMPLEMENTED) { 2362 result = ISC_R_SUCCESS; 2363 } 2364 if (result != ISC_R_SUCCESS) { 2365 goto cleanup; 2366 } 2367 } 2368 2369 if (!dns_db_ispersistent(db)) { 2370 if (zone->masterfile != NULL || zone->stream != NULL) { 2371 result = zone_startload(db, zone, loadtime); 2372 } else { 2373 result = DNS_R_NOMASTERFILE; 2374 if (zone->type == dns_zone_primary || 2375 (zone->type == dns_zone_redirect && 2376 zone->primaries == NULL)) 2377 { 2378 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2379 ISC_LOG_ERROR, 2380 "loading zone: " 2381 "no master file configured"); 2382 goto cleanup; 2383 } 2384 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 2385 ISC_LOG_INFO, 2386 "loading zone: " 2387 "no master file configured: continuing"); 2388 } 2389 } 2390 2391 if (result == DNS_R_CONTINUE) { 2392 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING); 2393 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) { 2394 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 2395 } 2396 goto cleanup; 2397 } 2398 2399 result = zone_postload(zone, db, loadtime, result); 2400 2401cleanup: 2402 if (hasraw) { 2403 UNLOCK_ZONE(zone->raw); 2404 } 2405 if (!locked) { 2406 UNLOCK_ZONE(zone); 2407 } 2408 if (db != NULL) { 2409 dns_db_detach(&db); 2410 } 2411 return (result); 2412} 2413 2414isc_result_t 2415dns_zone_load(dns_zone_t *zone, bool newonly) { 2416 return (zone_load(zone, newonly ? DNS_ZONELOADFLAG_NOSTAT : 0, false)); 2417} 2418 2419static void 2420zone_asyncload(isc_task_t *task, isc_event_t *event) { 2421 dns_asyncload_t *asl = event->ev_arg; 2422 dns_zone_t *zone = asl->zone; 2423 isc_result_t result; 2424 2425 UNUSED(task); 2426 2427 REQUIRE(DNS_ZONE_VALID(zone)); 2428 2429 isc_event_free(&event); 2430 2431 LOCK_ZONE(zone); 2432 result = zone_load(zone, asl->flags, true); 2433 if (result != DNS_R_CONTINUE) { 2434 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); 2435 } 2436 UNLOCK_ZONE(zone); 2437 2438 /* Inform the zone table we've finished loading */ 2439 if (asl->loaded != NULL) { 2440 (asl->loaded)(asl->loaded_arg, zone, task); 2441 } 2442 2443 /* Reduce the quantum */ 2444 isc_task_setquantum(zone->loadtask, 1); 2445 2446 isc_mem_put(zone->mctx, asl, sizeof(*asl)); 2447 dns_zone_idetach(&zone); 2448} 2449 2450isc_result_t 2451dns_zone_asyncload(dns_zone_t *zone, bool newonly, dns_zt_zoneloaded_t done, 2452 void *arg) { 2453 isc_event_t *e; 2454 dns_asyncload_t *asl = NULL; 2455 2456 REQUIRE(DNS_ZONE_VALID(zone)); 2457 2458 if (zone->zmgr == NULL) { 2459 return (ISC_R_FAILURE); 2460 } 2461 2462 /* If we already have a load pending, stop now */ 2463 LOCK_ZONE(zone); 2464 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) { 2465 UNLOCK_ZONE(zone); 2466 return (ISC_R_ALREADYRUNNING); 2467 } 2468 2469 asl = isc_mem_get(zone->mctx, sizeof(*asl)); 2470 2471 asl->zone = NULL; 2472 asl->flags = newonly ? DNS_ZONELOADFLAG_NOSTAT : 0; 2473 asl->loaded = done; 2474 asl->loaded_arg = arg; 2475 2476 e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr, DNS_EVENT_ZONELOAD, 2477 zone_asyncload, asl, sizeof(isc_event_t)); 2478 2479 zone_iattach(zone, &asl->zone); 2480 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING); 2481 isc_task_send(zone->loadtask, &e); 2482 UNLOCK_ZONE(zone); 2483 2484 return (ISC_R_SUCCESS); 2485} 2486 2487bool 2488dns__zone_loadpending(dns_zone_t *zone) { 2489 REQUIRE(DNS_ZONE_VALID(zone)); 2490 2491 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)); 2492} 2493 2494isc_result_t 2495dns_zone_loadandthaw(dns_zone_t *zone) { 2496 isc_result_t result; 2497 2498 if (inline_raw(zone)) { 2499 result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW, false); 2500 } else { 2501 /* 2502 * When thawing a zone, we don't know what changes 2503 * have been made. If we do DNSSEC maintenance on this 2504 * zone, schedule a full sign for this zone. 2505 */ 2506 if (zone->type == dns_zone_primary && 2507 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 2508 { 2509 DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN); 2510 } 2511 result = zone_load(zone, DNS_ZONELOADFLAG_THAW, false); 2512 } 2513 2514 switch (result) { 2515 case DNS_R_CONTINUE: 2516 /* Deferred thaw. */ 2517 break; 2518 case DNS_R_UPTODATE: 2519 case ISC_R_SUCCESS: 2520 case DNS_R_SEENINCLUDE: 2521 zone->update_disabled = false; 2522 break; 2523 case DNS_R_NOMASTERFILE: 2524 zone->update_disabled = false; 2525 break; 2526 default: 2527 /* Error, remain in disabled state. */ 2528 break; 2529 } 2530 return (result); 2531} 2532 2533static unsigned int 2534get_primary_options(dns_zone_t *zone) { 2535 unsigned int options; 2536 2537 options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN; 2538 if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror || 2539 (zone->type == dns_zone_redirect && zone->primaries == NULL)) 2540 { 2541 options |= DNS_MASTER_SECONDARY; 2542 } 2543 if (zone->type == dns_zone_key) { 2544 options |= DNS_MASTER_KEY; 2545 } 2546 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) { 2547 options |= DNS_MASTER_CHECKNS; 2548 } 2549 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) { 2550 options |= DNS_MASTER_FATALNS; 2551 } 2552 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) { 2553 options |= DNS_MASTER_CHECKNAMES; 2554 } 2555 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) { 2556 options |= DNS_MASTER_CHECKNAMESFAIL; 2557 } 2558 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) { 2559 options |= DNS_MASTER_CHECKMX; 2560 } 2561 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) { 2562 options |= DNS_MASTER_CHECKMXFAIL; 2563 } 2564 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) { 2565 options |= DNS_MASTER_CHECKWILDCARD; 2566 } 2567 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKTTL)) { 2568 options |= DNS_MASTER_CHECKTTL; 2569 } 2570 2571 return (options); 2572} 2573 2574static void 2575zone_registerinclude(const char *filename, void *arg) { 2576 isc_result_t result; 2577 dns_zone_t *zone = (dns_zone_t *)arg; 2578 dns_include_t *inc = NULL; 2579 2580 REQUIRE(DNS_ZONE_VALID(zone)); 2581 2582 if (filename == NULL) { 2583 return; 2584 } 2585 2586 /* 2587 * Suppress duplicates. 2588 */ 2589 for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; 2590 inc = ISC_LIST_NEXT(inc, link)) 2591 { 2592 if (strcmp(filename, inc->name) == 0) { 2593 return; 2594 } 2595 } 2596 2597 inc = isc_mem_get(zone->mctx, sizeof(dns_include_t)); 2598 inc->name = isc_mem_strdup(zone->mctx, filename); 2599 ISC_LINK_INIT(inc, link); 2600 2601 result = isc_file_getmodtime(filename, &inc->filetime); 2602 if (result != ISC_R_SUCCESS) { 2603 isc_time_settoepoch(&inc->filetime); 2604 } 2605 2606 ISC_LIST_APPEND(zone->newincludes, inc, link); 2607} 2608 2609static void 2610zone_gotreadhandle(isc_task_t *task, isc_event_t *event) { 2611 dns_load_t *load = event->ev_arg; 2612 isc_result_t result = ISC_R_SUCCESS; 2613 unsigned int options; 2614 2615 REQUIRE(DNS_LOAD_VALID(load)); 2616 2617 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) { 2618 result = ISC_R_CANCELED; 2619 } 2620 isc_event_free(&event); 2621 if (result == ISC_R_CANCELED) { 2622 goto fail; 2623 } 2624 2625 options = get_primary_options(load->zone); 2626 2627 result = dns_master_loadfileinc( 2628 load->zone->masterfile, dns_db_origin(load->db), 2629 dns_db_origin(load->db), load->zone->rdclass, options, 0, 2630 &load->callbacks, task, zone_loaddone, load, &load->zone->lctx, 2631 zone_registerinclude, load->zone, load->zone->mctx, 2632 load->zone->masterformat, load->zone->maxttl); 2633 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE && 2634 result != DNS_R_SEENINCLUDE) 2635 { 2636 goto fail; 2637 } 2638 return; 2639 2640fail: 2641 zone_loaddone(load, result); 2642} 2643 2644static void 2645get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) { 2646 isc_result_t result; 2647 unsigned int soacount; 2648 2649 LOCK(&raw->lock); 2650 if (raw->db != NULL) { 2651 result = zone_get_from_db(raw, raw->db, NULL, &soacount, NULL, 2652 &rawdata->sourceserial, NULL, NULL, 2653 NULL, NULL, NULL); 2654 if (result == ISC_R_SUCCESS && soacount > 0U) { 2655 rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET; 2656 } 2657 } 2658 UNLOCK(&raw->lock); 2659} 2660 2661static void 2662zone_gotwritehandle(isc_task_t *task, isc_event_t *event) { 2663 const char me[] = "zone_gotwritehandle"; 2664 dns_zone_t *zone = event->ev_arg; 2665 isc_result_t result = ISC_R_SUCCESS; 2666 dns_dbversion_t *version = NULL; 2667 dns_masterrawheader_t rawdata; 2668 dns_db_t *db = NULL; 2669 2670 REQUIRE(DNS_ZONE_VALID(zone)); 2671 INSIST(task == zone->task); 2672 ENTER; 2673 2674 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) { 2675 result = ISC_R_CANCELED; 2676 } 2677 isc_event_free(&event); 2678 if (result == ISC_R_CANCELED) { 2679 goto fail; 2680 } 2681 2682 LOCK_ZONE(zone); 2683 INSIST(zone != zone->raw); 2684 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 2685 if (zone->db != NULL) { 2686 dns_db_attach(zone->db, &db); 2687 } 2688 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 2689 if (db != NULL) { 2690 const dns_master_style_t *output_style; 2691 dns_db_currentversion(db, &version); 2692 dns_master_initrawheader(&rawdata); 2693 if (inline_secure(zone)) { 2694 get_raw_serial(zone->raw, &rawdata); 2695 } 2696 if (zone->type == dns_zone_key) { 2697 output_style = &dns_master_style_keyzone; 2698 } else if (zone->masterstyle != NULL) { 2699 output_style = zone->masterstyle; 2700 } else { 2701 output_style = &dns_master_style_default; 2702 } 2703 result = dns_master_dumpasync( 2704 zone->mctx, db, version, output_style, zone->masterfile, 2705 zone->task, dump_done, zone, &zone->dctx, 2706 zone->masterformat, &rawdata); 2707 dns_db_closeversion(db, &version, false); 2708 } else { 2709 result = ISC_R_CANCELED; 2710 } 2711 if (db != NULL) { 2712 dns_db_detach(&db); 2713 } 2714 UNLOCK_ZONE(zone); 2715 if (result != DNS_R_CONTINUE) { 2716 goto fail; 2717 } 2718 return; 2719 2720fail: 2721 dump_done(zone, result); 2722} 2723 2724/* 2725 * Save the raw serial number for inline-signing zones. 2726 * (XXX: Other information from the header will be used 2727 * for other purposes in the future, but for now this is 2728 * all we're interested in.) 2729 */ 2730static void 2731zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { 2732 if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0) { 2733 return; 2734 } 2735 2736 zone->sourceserial = header->sourceserial; 2737 zone->sourceserialset = true; 2738} 2739 2740void 2741dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { 2742 if (zone == NULL) { 2743 return; 2744 } 2745 2746 LOCK_ZONE(zone); 2747 zone_setrawdata(zone, header); 2748 UNLOCK_ZONE(zone); 2749} 2750 2751static isc_result_t 2752zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { 2753 const char me[] = "zone_startload"; 2754 dns_load_t *load; 2755 isc_result_t result; 2756 isc_result_t tresult; 2757 unsigned int options; 2758 2759 ENTER; 2760 2761 dns_zone_rpz_enable_db(zone, db); 2762 dns_zone_catz_enable_db(zone, db); 2763 2764 options = get_primary_options(zone); 2765 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) { 2766 options |= DNS_MASTER_MANYERRORS; 2767 } 2768 2769 if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) { 2770 load = isc_mem_get(zone->mctx, sizeof(*load)); 2771 2772 load->mctx = NULL; 2773 load->zone = NULL; 2774 load->db = NULL; 2775 load->loadtime = loadtime; 2776 load->magic = LOAD_MAGIC; 2777 2778 isc_mem_attach(zone->mctx, &load->mctx); 2779 zone_iattach(zone, &load->zone); 2780 dns_db_attach(db, &load->db); 2781 dns_rdatacallbacks_init(&load->callbacks); 2782 load->callbacks.rawdata = zone_setrawdata; 2783 zone_iattach(zone, &load->callbacks.zone); 2784 result = dns_db_beginload(db, &load->callbacks); 2785 if (result != ISC_R_SUCCESS) { 2786 goto cleanup; 2787 } 2788 result = zonemgr_getio(zone->zmgr, true, zone->loadtask, 2789 zone_gotreadhandle, load, &zone->readio); 2790 if (result != ISC_R_SUCCESS) { 2791 /* 2792 * We can't report multiple errors so ignore 2793 * the result of dns_db_endload(). 2794 */ 2795 (void)dns_db_endload(load->db, &load->callbacks); 2796 goto cleanup; 2797 } else { 2798 result = DNS_R_CONTINUE; 2799 } 2800 } else { 2801 dns_rdatacallbacks_t callbacks; 2802 2803 dns_rdatacallbacks_init(&callbacks); 2804 callbacks.rawdata = zone_setrawdata; 2805 zone_iattach(zone, &callbacks.zone); 2806 result = dns_db_beginload(db, &callbacks); 2807 if (result != ISC_R_SUCCESS) { 2808 zone_idetach(&callbacks.zone); 2809 return (result); 2810 } 2811 2812 if (zone->stream != NULL) { 2813 FILE *stream = NULL; 2814 DE_CONST(zone->stream, stream); 2815 result = dns_master_loadstream( 2816 stream, &zone->origin, &zone->origin, 2817 zone->rdclass, options, &callbacks, zone->mctx); 2818 } else { 2819 result = dns_master_loadfile( 2820 zone->masterfile, &zone->origin, &zone->origin, 2821 zone->rdclass, options, 0, &callbacks, 2822 zone_registerinclude, zone, zone->mctx, 2823 zone->masterformat, zone->maxttl); 2824 } 2825 2826 tresult = dns_db_endload(db, &callbacks); 2827 if (result == ISC_R_SUCCESS) { 2828 result = tresult; 2829 } 2830 zone_idetach(&callbacks.zone); 2831 } 2832 2833 return (result); 2834 2835cleanup: 2836 load->magic = 0; 2837 dns_db_detach(&load->db); 2838 zone_idetach(&load->zone); 2839 zone_idetach(&load->callbacks.zone); 2840 isc_mem_detach(&load->mctx); 2841 isc_mem_put(zone->mctx, load, sizeof(*load)); 2842 return (result); 2843} 2844 2845static bool 2846zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2847 dns_name_t *owner) { 2848 isc_result_t result; 2849 char ownerbuf[DNS_NAME_FORMATSIZE]; 2850 char namebuf[DNS_NAME_FORMATSIZE]; 2851 char altbuf[DNS_NAME_FORMATSIZE]; 2852 dns_fixedname_t fixed; 2853 dns_name_t *foundname; 2854 int level; 2855 2856 /* 2857 * "." means the services does not exist. 2858 */ 2859 if (dns_name_equal(name, dns_rootname)) { 2860 return (true); 2861 } 2862 2863 /* 2864 * Outside of zone. 2865 */ 2866 if (!dns_name_issubdomain(name, &zone->origin)) { 2867 if (zone->checkmx != NULL) { 2868 return ((zone->checkmx)(zone, name, owner)); 2869 } 2870 return (true); 2871 } 2872 2873 if (zone->type == dns_zone_primary) { 2874 level = ISC_LOG_ERROR; 2875 } else { 2876 level = ISC_LOG_WARNING; 2877 } 2878 2879 foundname = dns_fixedname_initname(&fixed); 2880 2881 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, 2882 foundname, NULL, NULL); 2883 if (result == ISC_R_SUCCESS) { 2884 return (true); 2885 } 2886 2887 if (result == DNS_R_NXRRSET) { 2888 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0, 2889 NULL, foundname, NULL, NULL); 2890 if (result == ISC_R_SUCCESS) { 2891 return (true); 2892 } 2893 } 2894 2895 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2896 dns_name_format(name, namebuf, sizeof namebuf); 2897 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2898 result == DNS_R_EMPTYNAME) 2899 { 2900 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) { 2901 level = ISC_LOG_WARNING; 2902 } 2903 dns_zone_log(zone, level, 2904 "%s/MX '%s' has no address records (A or AAAA)", 2905 ownerbuf, namebuf); 2906 return ((level == ISC_LOG_WARNING) ? true : false); 2907 } 2908 2909 if (result == DNS_R_CNAME) { 2910 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 2911 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2912 { 2913 level = ISC_LOG_WARNING; 2914 } 2915 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { 2916 dns_zone_log(zone, level, 2917 "%s/MX '%s' is a CNAME (illegal)", 2918 ownerbuf, namebuf); 2919 } 2920 return ((level == ISC_LOG_WARNING) ? true : false); 2921 } 2922 2923 if (result == DNS_R_DNAME) { 2924 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 2925 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2926 { 2927 level = ISC_LOG_WARNING; 2928 } 2929 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { 2930 dns_name_format(foundname, altbuf, sizeof altbuf); 2931 dns_zone_log(zone, level, 2932 "%s/MX '%s' is below a DNAME" 2933 " '%s' (illegal)", 2934 ownerbuf, namebuf, altbuf); 2935 } 2936 return ((level == ISC_LOG_WARNING) ? true : false); 2937 } 2938 2939 if (zone->checkmx != NULL && result == DNS_R_DELEGATION) { 2940 return ((zone->checkmx)(zone, name, owner)); 2941 } 2942 2943 return (true); 2944} 2945 2946static bool 2947zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2948 dns_name_t *owner) { 2949 isc_result_t result; 2950 char ownerbuf[DNS_NAME_FORMATSIZE]; 2951 char namebuf[DNS_NAME_FORMATSIZE]; 2952 char altbuf[DNS_NAME_FORMATSIZE]; 2953 dns_fixedname_t fixed; 2954 dns_name_t *foundname; 2955 int level; 2956 2957 /* 2958 * "." means the services does not exist. 2959 */ 2960 if (dns_name_equal(name, dns_rootname)) { 2961 return (true); 2962 } 2963 2964 /* 2965 * Outside of zone. 2966 */ 2967 if (!dns_name_issubdomain(name, &zone->origin)) { 2968 if (zone->checksrv != NULL) { 2969 return ((zone->checksrv)(zone, name, owner)); 2970 } 2971 return (true); 2972 } 2973 2974 if (zone->type == dns_zone_primary) { 2975 level = ISC_LOG_ERROR; 2976 } else { 2977 level = ISC_LOG_WARNING; 2978 } 2979 2980 foundname = dns_fixedname_initname(&fixed); 2981 2982 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, 2983 foundname, NULL, NULL); 2984 if (result == ISC_R_SUCCESS) { 2985 return (true); 2986 } 2987 2988 if (result == DNS_R_NXRRSET) { 2989 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0, 2990 NULL, foundname, NULL, NULL); 2991 if (result == ISC_R_SUCCESS) { 2992 return (true); 2993 } 2994 } 2995 2996 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2997 dns_name_format(name, namebuf, sizeof namebuf); 2998 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2999 result == DNS_R_EMPTYNAME) 3000 { 3001 dns_zone_log(zone, level, 3002 "%s/SRV '%s' has no address records (A or AAAA)", 3003 ownerbuf, namebuf); 3004 /* XXX950 make fatal for 9.5.0. */ 3005 return (true); 3006 } 3007 3008 if (result == DNS_R_CNAME) { 3009 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 3010 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 3011 { 3012 level = ISC_LOG_WARNING; 3013 } 3014 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { 3015 dns_zone_log(zone, level, 3016 "%s/SRV '%s' is a CNAME (illegal)", 3017 ownerbuf, namebuf); 3018 } 3019 return ((level == ISC_LOG_WARNING) ? true : false); 3020 } 3021 3022 if (result == DNS_R_DNAME) { 3023 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 3024 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 3025 { 3026 level = ISC_LOG_WARNING; 3027 } 3028 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { 3029 dns_name_format(foundname, altbuf, sizeof altbuf); 3030 dns_zone_log(zone, level, 3031 "%s/SRV '%s' is below a " 3032 "DNAME '%s' (illegal)", 3033 ownerbuf, namebuf, altbuf); 3034 } 3035 return ((level == ISC_LOG_WARNING) ? true : false); 3036 } 3037 3038 if (zone->checksrv != NULL && result == DNS_R_DELEGATION) { 3039 return ((zone->checksrv)(zone, name, owner)); 3040 } 3041 3042 return (true); 3043} 3044 3045static bool 3046zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 3047 dns_name_t *owner) { 3048 bool answer = true; 3049 isc_result_t result, tresult; 3050 char ownerbuf[DNS_NAME_FORMATSIZE]; 3051 char namebuf[DNS_NAME_FORMATSIZE]; 3052 char altbuf[DNS_NAME_FORMATSIZE]; 3053 dns_fixedname_t fixed; 3054 dns_name_t *foundname; 3055 dns_rdataset_t a; 3056 dns_rdataset_t aaaa; 3057 int level; 3058 3059 /* 3060 * Outside of zone. 3061 */ 3062 if (!dns_name_issubdomain(name, &zone->origin)) { 3063 if (zone->checkns != NULL) { 3064 return ((zone->checkns)(zone, name, owner, NULL, NULL)); 3065 } 3066 return (true); 3067 } 3068 3069 if (zone->type == dns_zone_primary) { 3070 level = ISC_LOG_ERROR; 3071 } else { 3072 level = ISC_LOG_WARNING; 3073 } 3074 3075 foundname = dns_fixedname_initname(&fixed); 3076 dns_rdataset_init(&a); 3077 dns_rdataset_init(&aaaa); 3078 3079 /* 3080 * Perform a regular lookup to catch DNAME records then look 3081 * for glue. 3082 */ 3083 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL, 3084 foundname, &a, NULL); 3085 switch (result) { 3086 case ISC_R_SUCCESS: 3087 case DNS_R_DNAME: 3088 case DNS_R_CNAME: 3089 break; 3090 default: 3091 if (dns_rdataset_isassociated(&a)) { 3092 dns_rdataset_disassociate(&a); 3093 } 3094 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 3095 DNS_DBFIND_GLUEOK, 0, NULL, foundname, &a, 3096 NULL); 3097 } 3098 if (result == ISC_R_SUCCESS) { 3099 dns_rdataset_disassociate(&a); 3100 return (true); 3101 } else if (result == DNS_R_DELEGATION) { 3102 dns_rdataset_disassociate(&a); 3103 } 3104 3105 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION || 3106 result == DNS_R_GLUE) 3107 { 3108 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 3109 DNS_DBFIND_GLUEOK, 0, NULL, foundname, 3110 &aaaa, NULL); 3111 if (tresult == ISC_R_SUCCESS) { 3112 if (dns_rdataset_isassociated(&a)) { 3113 dns_rdataset_disassociate(&a); 3114 } 3115 dns_rdataset_disassociate(&aaaa); 3116 return (true); 3117 } 3118 if (tresult == DNS_R_DELEGATION || tresult == DNS_R_DNAME) { 3119 dns_rdataset_disassociate(&aaaa); 3120 } 3121 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) { 3122 /* 3123 * Check glue against child zone. 3124 */ 3125 if (zone->checkns != NULL) { 3126 answer = (zone->checkns)(zone, name, owner, &a, 3127 &aaaa); 3128 } 3129 if (dns_rdataset_isassociated(&a)) { 3130 dns_rdataset_disassociate(&a); 3131 } 3132 if (dns_rdataset_isassociated(&aaaa)) { 3133 dns_rdataset_disassociate(&aaaa); 3134 } 3135 return (answer); 3136 } 3137 } 3138 3139 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 3140 dns_name_format(name, namebuf, sizeof namebuf); 3141 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 3142 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) 3143 { 3144 const char *what; 3145 bool required = false; 3146 if (dns_name_issubdomain(name, owner)) { 3147 what = "REQUIRED GLUE "; 3148 required = true; 3149 } else if (result == DNS_R_DELEGATION) { 3150 what = "SIBLING GLUE "; 3151 } else { 3152 what = ""; 3153 } 3154 3155 if (result != DNS_R_DELEGATION || required || 3156 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) 3157 { 3158 dns_zone_log(zone, level, 3159 "%s/NS '%s' has no %s" 3160 "address records (A or AAAA)", 3161 ownerbuf, namebuf, what); 3162 /* 3163 * Log missing address record. 3164 */ 3165 if (result == DNS_R_DELEGATION && zone->checkns != NULL) 3166 { 3167 (void)(zone->checkns)(zone, name, owner, &a, 3168 &aaaa); 3169 } 3170 /* XXX950 make fatal for 9.5.0. */ 3171 /* answer = false; */ 3172 } 3173 } else if (result == DNS_R_CNAME) { 3174 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)", 3175 ownerbuf, namebuf); 3176 /* XXX950 make fatal for 9.5.0. */ 3177 /* answer = false; */ 3178 } else if (result == DNS_R_DNAME) { 3179 dns_name_format(foundname, altbuf, sizeof altbuf); 3180 dns_zone_log(zone, level, 3181 "%s/NS '%s' is below a DNAME '%s' (illegal)", 3182 ownerbuf, namebuf, altbuf); 3183 /* XXX950 make fatal for 9.5.0. */ 3184 /* answer = false; */ 3185 } 3186 3187 if (dns_rdataset_isassociated(&a)) { 3188 dns_rdataset_disassociate(&a); 3189 } 3190 if (dns_rdataset_isassociated(&aaaa)) { 3191 dns_rdataset_disassociate(&aaaa); 3192 } 3193 return (answer); 3194} 3195 3196static bool 3197zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner, 3198 dns_rdataset_t *rdataset) { 3199 dns_rdataset_t tmprdataset; 3200 isc_result_t result; 3201 bool answer = true; 3202 bool format = true; 3203 int level = ISC_LOG_WARNING; 3204 char ownerbuf[DNS_NAME_FORMATSIZE]; 3205 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 3206 unsigned int count1 = 0; 3207 3208 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL)) { 3209 level = ISC_LOG_ERROR; 3210 } 3211 3212 dns_rdataset_init(&tmprdataset); 3213 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 3214 result = dns_rdataset_next(rdataset)) 3215 { 3216 dns_rdata_t rdata1 = DNS_RDATA_INIT; 3217 unsigned int count2 = 0; 3218 3219 count1++; 3220 dns_rdataset_current(rdataset, &rdata1); 3221 dns_rdataset_clone(rdataset, &tmprdataset); 3222 for (result = dns_rdataset_first(&tmprdataset); 3223 result == ISC_R_SUCCESS; 3224 result = dns_rdataset_next(&tmprdataset)) 3225 { 3226 dns_rdata_t rdata2 = DNS_RDATA_INIT; 3227 count2++; 3228 if (count1 >= count2) { 3229 continue; 3230 } 3231 dns_rdataset_current(&tmprdataset, &rdata2); 3232 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) { 3233 if (format) { 3234 dns_name_format(owner, ownerbuf, 3235 sizeof ownerbuf); 3236 dns_rdatatype_format(rdata1.type, 3237 typebuf, 3238 sizeof(typebuf)); 3239 format = false; 3240 } 3241 dns_zone_log(zone, level, 3242 "%s/%s has " 3243 "semantically identical records", 3244 ownerbuf, typebuf); 3245 if (level == ISC_LOG_ERROR) { 3246 answer = false; 3247 } 3248 break; 3249 } 3250 } 3251 dns_rdataset_disassociate(&tmprdataset); 3252 if (!format) { 3253 break; 3254 } 3255 } 3256 return (answer); 3257} 3258 3259static bool 3260zone_check_dup(dns_zone_t *zone, dns_db_t *db) { 3261 dns_dbiterator_t *dbiterator = NULL; 3262 dns_dbnode_t *node = NULL; 3263 dns_fixedname_t fixed; 3264 dns_name_t *name; 3265 dns_rdataset_t rdataset; 3266 dns_rdatasetiter_t *rdsit = NULL; 3267 bool ok = true; 3268 isc_result_t result; 3269 3270 name = dns_fixedname_initname(&fixed); 3271 dns_rdataset_init(&rdataset); 3272 3273 result = dns_db_createiterator(db, 0, &dbiterator); 3274 if (result != ISC_R_SUCCESS) { 3275 return (true); 3276 } 3277 3278 for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS; 3279 result = dns_dbiterator_next(dbiterator)) 3280 { 3281 result = dns_dbiterator_current(dbiterator, &node, name); 3282 if (result != ISC_R_SUCCESS) { 3283 continue; 3284 } 3285 3286 result = dns_db_allrdatasets(db, node, NULL, 0, 0, &rdsit); 3287 if (result != ISC_R_SUCCESS) { 3288 continue; 3289 } 3290 3291 for (result = dns_rdatasetiter_first(rdsit); 3292 result == ISC_R_SUCCESS; 3293 result = dns_rdatasetiter_next(rdsit)) 3294 { 3295 dns_rdatasetiter_current(rdsit, &rdataset); 3296 if (!zone_rrset_check_dup(zone, name, &rdataset)) { 3297 ok = false; 3298 } 3299 dns_rdataset_disassociate(&rdataset); 3300 } 3301 dns_rdatasetiter_destroy(&rdsit); 3302 dns_db_detachnode(db, &node); 3303 } 3304 3305 if (node != NULL) { 3306 dns_db_detachnode(db, &node); 3307 } 3308 dns_dbiterator_destroy(&dbiterator); 3309 3310 return (ok); 3311} 3312 3313static bool 3314isspf(const dns_rdata_t *rdata) { 3315 char buf[1024]; 3316 const unsigned char *data = rdata->data; 3317 unsigned int rdl = rdata->length, i = 0, tl, len; 3318 3319 while (rdl > 0U) { 3320 len = tl = *data; 3321 ++data; 3322 --rdl; 3323 INSIST(tl <= rdl); 3324 if (len > sizeof(buf) - i - 1) { 3325 len = sizeof(buf) - i - 1; 3326 } 3327 memmove(buf + i, data, len); 3328 i += len; 3329 data += tl; 3330 rdl -= tl; 3331 } 3332 3333 if (i < 6U) { 3334 return (false); 3335 } 3336 3337 buf[i] = 0; 3338 if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' ')) { 3339 return (true); 3340 } 3341 return (false); 3342} 3343 3344static bool 3345integrity_checks(dns_zone_t *zone, dns_db_t *db) { 3346 dns_dbiterator_t *dbiterator = NULL; 3347 dns_dbnode_t *node = NULL; 3348 dns_rdataset_t rdataset; 3349 dns_fixedname_t fixed; 3350 dns_fixedname_t fixedbottom; 3351 dns_rdata_mx_t mx; 3352 dns_rdata_ns_t ns; 3353 dns_rdata_in_srv_t srv; 3354 dns_rdata_t rdata; 3355 dns_name_t *name; 3356 dns_name_t *bottom; 3357 isc_result_t result; 3358 bool ok = true, have_spf, have_txt; 3359 3360 name = dns_fixedname_initname(&fixed); 3361 bottom = dns_fixedname_initname(&fixedbottom); 3362 dns_rdataset_init(&rdataset); 3363 dns_rdata_init(&rdata); 3364 3365 result = dns_db_createiterator(db, 0, &dbiterator); 3366 if (result != ISC_R_SUCCESS) { 3367 return (true); 3368 } 3369 3370 result = dns_dbiterator_first(dbiterator); 3371 while (result == ISC_R_SUCCESS) { 3372 result = dns_dbiterator_current(dbiterator, &node, name); 3373 if (result != ISC_R_SUCCESS) { 3374 goto cleanup; 3375 } 3376 3377 /* 3378 * Is this name visible in the zone? 3379 */ 3380 if (!dns_name_issubdomain(name, &zone->origin) || 3381 (dns_name_countlabels(bottom) > 0 && 3382 dns_name_issubdomain(name, bottom))) 3383 { 3384 goto next; 3385 } 3386 3387 dns_dbiterator_pause(dbiterator); 3388 3389 /* 3390 * Don't check the NS records at the origin. 3391 */ 3392 if (dns_name_equal(name, &zone->origin)) { 3393 goto checkfordname; 3394 } 3395 3396 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns, 3397 0, 0, &rdataset, NULL); 3398 if (result != ISC_R_SUCCESS) { 3399 goto checkfordname; 3400 } 3401 /* 3402 * Remember bottom of zone due to NS. 3403 */ 3404 dns_name_copy(name, bottom); 3405 3406 result = dns_rdataset_first(&rdataset); 3407 while (result == ISC_R_SUCCESS) { 3408 dns_rdataset_current(&rdataset, &rdata); 3409 result = dns_rdata_tostruct(&rdata, &ns, NULL); 3410 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3411 if (!zone_check_glue(zone, db, &ns.name, name)) { 3412 ok = false; 3413 } 3414 dns_rdata_reset(&rdata); 3415 result = dns_rdataset_next(&rdataset); 3416 } 3417 dns_rdataset_disassociate(&rdataset); 3418 goto next; 3419 3420 checkfordname: 3421 result = dns_db_findrdataset(db, node, NULL, 3422 dns_rdatatype_dname, 0, 0, 3423 &rdataset, NULL); 3424 if (result == ISC_R_SUCCESS) { 3425 /* 3426 * Remember bottom of zone due to DNAME. 3427 */ 3428 dns_name_copy(name, bottom); 3429 dns_rdataset_disassociate(&rdataset); 3430 } 3431 3432 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx, 3433 0, 0, &rdataset, NULL); 3434 if (result != ISC_R_SUCCESS) { 3435 goto checksrv; 3436 } 3437 result = dns_rdataset_first(&rdataset); 3438 while (result == ISC_R_SUCCESS) { 3439 dns_rdataset_current(&rdataset, &rdata); 3440 result = dns_rdata_tostruct(&rdata, &mx, NULL); 3441 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3442 if (!zone_check_mx(zone, db, &mx.mx, name)) { 3443 ok = false; 3444 } 3445 dns_rdata_reset(&rdata); 3446 result = dns_rdataset_next(&rdataset); 3447 } 3448 dns_rdataset_disassociate(&rdataset); 3449 3450 checksrv: 3451 if (zone->rdclass != dns_rdataclass_in) { 3452 goto next; 3453 } 3454 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv, 3455 0, 0, &rdataset, NULL); 3456 if (result != ISC_R_SUCCESS) { 3457 goto checkspf; 3458 } 3459 result = dns_rdataset_first(&rdataset); 3460 while (result == ISC_R_SUCCESS) { 3461 dns_rdataset_current(&rdataset, &rdata); 3462 result = dns_rdata_tostruct(&rdata, &srv, NULL); 3463 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3464 if (!zone_check_srv(zone, db, &srv.target, name)) { 3465 ok = false; 3466 } 3467 dns_rdata_reset(&rdata); 3468 result = dns_rdataset_next(&rdataset); 3469 } 3470 dns_rdataset_disassociate(&rdataset); 3471 3472 checkspf: 3473 /* 3474 * Check if there is a type SPF record without an 3475 * SPF-formatted type TXT record also being present. 3476 */ 3477 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF)) { 3478 goto next; 3479 } 3480 if (zone->rdclass != dns_rdataclass_in) { 3481 goto next; 3482 } 3483 have_spf = have_txt = false; 3484 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf, 3485 0, 0, &rdataset, NULL); 3486 if (result == ISC_R_SUCCESS) { 3487 dns_rdataset_disassociate(&rdataset); 3488 have_spf = true; 3489 } 3490 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt, 3491 0, 0, &rdataset, NULL); 3492 if (result != ISC_R_SUCCESS) { 3493 goto notxt; 3494 } 3495 result = dns_rdataset_first(&rdataset); 3496 while (result == ISC_R_SUCCESS) { 3497 dns_rdataset_current(&rdataset, &rdata); 3498 have_txt = isspf(&rdata); 3499 dns_rdata_reset(&rdata); 3500 if (have_txt) { 3501 break; 3502 } 3503 result = dns_rdataset_next(&rdataset); 3504 } 3505 dns_rdataset_disassociate(&rdataset); 3506 3507 notxt: 3508 if (have_spf && !have_txt) { 3509 char namebuf[DNS_NAME_FORMATSIZE]; 3510 3511 dns_name_format(name, namebuf, sizeof(namebuf)); 3512 dns_zone_log(zone, ISC_LOG_WARNING, 3513 "'%s' found type " 3514 "SPF record but no SPF TXT record found, " 3515 "add matching type TXT record", 3516 namebuf); 3517 } 3518 3519 next: 3520 dns_db_detachnode(db, &node); 3521 result = dns_dbiterator_next(dbiterator); 3522 } 3523 3524cleanup: 3525 if (node != NULL) { 3526 dns_db_detachnode(db, &node); 3527 } 3528 dns_dbiterator_destroy(&dbiterator); 3529 3530 return (ok); 3531} 3532 3533/* 3534 * OpenSSL verification of RSA keys with exponent 3 is known to be 3535 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn 3536 * if they are in use. 3537 */ 3538static void 3539zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) { 3540 dns_dbnode_t *node = NULL; 3541 dns_dbversion_t *version = NULL; 3542 dns_rdata_dnskey_t dnskey; 3543 dns_rdata_t rdata = DNS_RDATA_INIT; 3544 dns_rdataset_t rdataset; 3545 isc_result_t result; 3546 3547 result = dns_db_findnode(db, &zone->origin, false, &node); 3548 if (result != ISC_R_SUCCESS) { 3549 goto cleanup; 3550 } 3551 3552 dns_db_currentversion(db, &version); 3553 dns_rdataset_init(&rdataset); 3554 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 3555 dns_rdatatype_none, 0, &rdataset, NULL); 3556 if (result != ISC_R_SUCCESS) { 3557 goto cleanup; 3558 } 3559 3560 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 3561 result = dns_rdataset_next(&rdataset)) 3562 { 3563 dns_rdataset_current(&rdataset, &rdata); 3564 result = dns_rdata_tostruct(&rdata, &dnskey, NULL); 3565 INSIST(result == ISC_R_SUCCESS); 3566 3567 /* 3568 * RFC 3110, section 4: Performance Considerations: 3569 * 3570 * A public exponent of 3 minimizes the effort needed to verify 3571 * a signature. Use of 3 as the public exponent is weak for 3572 * confidentiality uses since, if the same data can be collected 3573 * encrypted under three different keys with an exponent of 3 3574 * then, using the Chinese Remainder Theorem [NETSEC], the 3575 * original plain text can be easily recovered. If a key is 3576 * known to be used only for authentication, as is the case with 3577 * DNSSEC, then an exponent of 3 is acceptable. However other 3578 * applications in the future may wish to leverage DNS 3579 * distributed keys for applications that do require 3580 * confidentiality. For keys which might have such other uses, 3581 * a more conservative choice would be 65537 (F4, the fourth 3582 * fermat number). 3583 */ 3584 if (dnskey.datalen > 1 && dnskey.data[0] == 1 && 3585 dnskey.data[1] == 3 && 3586 (dnskey.algorithm == DNS_KEYALG_RSAMD5 || 3587 dnskey.algorithm == DNS_KEYALG_RSASHA1 || 3588 dnskey.algorithm == DNS_KEYALG_NSEC3RSASHA1 || 3589 dnskey.algorithm == DNS_KEYALG_RSASHA256 || 3590 dnskey.algorithm == DNS_KEYALG_RSASHA512)) 3591 { 3592 char algorithm[DNS_SECALG_FORMATSIZE]; 3593 isc_region_t r; 3594 3595 dns_rdata_toregion(&rdata, &r); 3596 dns_secalg_format(dnskey.algorithm, algorithm, 3597 sizeof(algorithm)); 3598 3599 dnssec_log(zone, ISC_LOG_WARNING, 3600 "weak %s (%u) key found (exponent=3, id=%u)", 3601 algorithm, dnskey.algorithm, 3602 dst_region_computeid(&r)); 3603 } 3604 dns_rdata_reset(&rdata); 3605 } 3606 dns_rdataset_disassociate(&rdataset); 3607 3608cleanup: 3609 if (node != NULL) { 3610 dns_db_detachnode(db, &node); 3611 } 3612 if (version != NULL) { 3613 dns_db_closeversion(db, &version, false); 3614 } 3615} 3616 3617static void 3618resume_signingwithkey(dns_zone_t *zone) { 3619 dns_dbnode_t *node = NULL; 3620 dns_dbversion_t *version = NULL; 3621 dns_rdata_t rdata = DNS_RDATA_INIT; 3622 dns_rdataset_t rdataset; 3623 isc_result_t result; 3624 dns_db_t *db = NULL; 3625 3626 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3627 if (zone->db != NULL) { 3628 dns_db_attach(zone->db, &db); 3629 } 3630 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3631 if (db == NULL) { 3632 goto cleanup; 3633 } 3634 3635 result = dns_db_findnode(db, &zone->origin, false, &node); 3636 if (result != ISC_R_SUCCESS) { 3637 goto cleanup; 3638 } 3639 3640 dns_db_currentversion(db, &version); 3641 dns_rdataset_init(&rdataset); 3642 result = dns_db_findrdataset(db, node, version, zone->privatetype, 3643 dns_rdatatype_none, 0, &rdataset, NULL); 3644 if (result != ISC_R_SUCCESS) { 3645 INSIST(!dns_rdataset_isassociated(&rdataset)); 3646 goto cleanup; 3647 } 3648 3649 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 3650 result = dns_rdataset_next(&rdataset)) 3651 { 3652 dns_rdataset_current(&rdataset, &rdata); 3653 if (rdata.length != 5 || rdata.data[0] == 0 || 3654 rdata.data[4] != 0) 3655 { 3656 dns_rdata_reset(&rdata); 3657 continue; 3658 } 3659 3660 result = zone_signwithkey(zone, rdata.data[0], 3661 (rdata.data[1] << 8) | rdata.data[2], 3662 rdata.data[3]); 3663 if (result != ISC_R_SUCCESS) { 3664 dnssec_log(zone, ISC_LOG_ERROR, 3665 "zone_signwithkey failed: %s", 3666 isc_result_totext(result)); 3667 } 3668 dns_rdata_reset(&rdata); 3669 } 3670 dns_rdataset_disassociate(&rdataset); 3671 3672cleanup: 3673 if (db != NULL) { 3674 if (node != NULL) { 3675 dns_db_detachnode(db, &node); 3676 } 3677 if (version != NULL) { 3678 dns_db_closeversion(db, &version, false); 3679 } 3680 dns_db_detach(&db); 3681 } 3682} 3683 3684/* 3685 * Initiate adding/removing NSEC3 records belonging to the chain defined by the 3686 * supplied NSEC3PARAM RDATA. 3687 * 3688 * Zone must be locked by caller. 3689 */ 3690static isc_result_t 3691zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 3692 dns_nsec3chain_t *nsec3chain, *current; 3693 dns_dbversion_t *version = NULL; 3694 bool nseconly = false, nsec3ok = false; 3695 isc_result_t result; 3696 isc_time_t now; 3697 unsigned int options = 0; 3698 char saltbuf[255 * 2 + 1]; 3699 char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")]; 3700 dns_db_t *db = NULL; 3701 3702 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3703 if (zone->db != NULL) { 3704 dns_db_attach(zone->db, &db); 3705 } 3706 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3707 3708 if (db == NULL) { 3709 result = ISC_R_SUCCESS; 3710 goto cleanup; 3711 } 3712 3713 /* 3714 * If this zone is not NSEC3-capable, attempting to remove any NSEC3 3715 * chain from it is pointless as it would not be possible for the 3716 * latter to exist in the first place. 3717 */ 3718 dns_db_currentversion(db, &version); 3719 result = dns_nsec_nseconly(db, version, NULL, &nseconly); 3720 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 3721 dns_db_closeversion(db, &version, false); 3722 if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) { 3723 result = ISC_R_SUCCESS; 3724 goto cleanup; 3725 } 3726 3727 /* 3728 * Allocate and initialize structure preserving state of 3729 * adding/removing records belonging to this NSEC3 chain between 3730 * separate zone_nsec3chain() calls. 3731 */ 3732 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain); 3733 3734 nsec3chain->magic = 0; 3735 nsec3chain->done = false; 3736 nsec3chain->db = NULL; 3737 nsec3chain->dbiterator = NULL; 3738 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass; 3739 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype; 3740 nsec3chain->nsec3param.hash = nsec3param->hash; 3741 nsec3chain->nsec3param.iterations = nsec3param->iterations; 3742 nsec3chain->nsec3param.flags = nsec3param->flags; 3743 nsec3chain->nsec3param.salt_length = nsec3param->salt_length; 3744 memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length); 3745 nsec3chain->nsec3param.salt = nsec3chain->salt; 3746 nsec3chain->seen_nsec = false; 3747 nsec3chain->delete_nsec = false; 3748 nsec3chain->save_delete_nsec = false; 3749 3750 /* 3751 * Log NSEC3 parameters defined by supplied NSEC3PARAM RDATA. 3752 */ 3753 if (nsec3param->flags == 0) { 3754 strlcpy(flags, "NONE", sizeof(flags)); 3755 } else { 3756 flags[0] = '\0'; 3757 if ((nsec3param->flags & DNS_NSEC3FLAG_REMOVE) != 0) { 3758 strlcat(flags, "REMOVE", sizeof(flags)); 3759 } 3760 if ((nsec3param->flags & DNS_NSEC3FLAG_INITIAL) != 0) { 3761 if (flags[0] == '\0') { 3762 strlcpy(flags, "INITIAL", sizeof(flags)); 3763 } else { 3764 strlcat(flags, "|INITIAL", sizeof(flags)); 3765 } 3766 } 3767 if ((nsec3param->flags & DNS_NSEC3FLAG_CREATE) != 0) { 3768 if (flags[0] == '\0') { 3769 strlcpy(flags, "CREATE", sizeof(flags)); 3770 } else { 3771 strlcat(flags, "|CREATE", sizeof(flags)); 3772 } 3773 } 3774 if ((nsec3param->flags & DNS_NSEC3FLAG_NONSEC) != 0) { 3775 if (flags[0] == '\0') { 3776 strlcpy(flags, "NONSEC", sizeof(flags)); 3777 } else { 3778 strlcat(flags, "|NONSEC", sizeof(flags)); 3779 } 3780 } 3781 if ((nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) != 0) { 3782 if (flags[0] == '\0') { 3783 strlcpy(flags, "OPTOUT", sizeof(flags)); 3784 } else { 3785 strlcat(flags, "|OPTOUT", sizeof(flags)); 3786 } 3787 } 3788 } 3789 result = dns_nsec3param_salttotext(nsec3param, saltbuf, 3790 sizeof(saltbuf)); 3791 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3792 dnssec_log(zone, ISC_LOG_INFO, "zone_addnsec3chain(%u,%s,%u,%s)", 3793 nsec3param->hash, flags, nsec3param->iterations, saltbuf); 3794 3795 /* 3796 * If the NSEC3 chain defined by the supplied NSEC3PARAM RDATA is 3797 * currently being processed, interrupt its processing to avoid 3798 * simultaneously adding and removing records for the same NSEC3 chain. 3799 */ 3800 for (current = ISC_LIST_HEAD(zone->nsec3chain); current != NULL; 3801 current = ISC_LIST_NEXT(current, link)) 3802 { 3803 if ((current->db == db) && 3804 (current->nsec3param.hash == nsec3param->hash) && 3805 (current->nsec3param.iterations == 3806 nsec3param->iterations) && 3807 (current->nsec3param.salt_length == 3808 nsec3param->salt_length) && 3809 memcmp(current->nsec3param.salt, nsec3param->salt, 3810 nsec3param->salt_length) == 0) 3811 { 3812 current->done = true; 3813 } 3814 } 3815 3816 /* 3817 * Attach zone database to the structure initialized above and create 3818 * an iterator for it with appropriate options in order to avoid 3819 * creating NSEC3 records for NSEC3 records. 3820 */ 3821 dns_db_attach(db, &nsec3chain->db); 3822 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) { 3823 options = DNS_DB_NONSEC3; 3824 } 3825 result = dns_db_createiterator(nsec3chain->db, options, 3826 &nsec3chain->dbiterator); 3827 if (result == ISC_R_SUCCESS) { 3828 result = dns_dbiterator_first(nsec3chain->dbiterator); 3829 } 3830 if (result == ISC_R_SUCCESS) { 3831 /* 3832 * Database iterator initialization succeeded. We are now 3833 * ready to kick off adding/removing records belonging to this 3834 * NSEC3 chain. Append the structure initialized above to the 3835 * "nsec3chain" list for the zone and set the appropriate zone 3836 * timer so that zone_nsec3chain() is called as soon as 3837 * possible. 3838 */ 3839 dns_dbiterator_pause(nsec3chain->dbiterator); 3840 ISC_LIST_INITANDAPPEND(zone->nsec3chain, nsec3chain, link); 3841 nsec3chain = NULL; 3842 if (isc_time_isepoch(&zone->nsec3chaintime)) { 3843 TIME_NOW(&now); 3844 zone->nsec3chaintime = now; 3845 if (zone->task != NULL) { 3846 zone_settimer(zone, &now); 3847 } 3848 } 3849 } 3850 3851 if (nsec3chain != NULL) { 3852 if (nsec3chain->db != NULL) { 3853 dns_db_detach(&nsec3chain->db); 3854 } 3855 if (nsec3chain->dbiterator != NULL) { 3856 dns_dbiterator_destroy(&nsec3chain->dbiterator); 3857 } 3858 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 3859 } 3860 3861cleanup: 3862 if (db != NULL) { 3863 dns_db_detach(&db); 3864 } 3865 return (result); 3866} 3867 3868/* 3869 * Find private-type records at the zone apex which signal that an NSEC3 chain 3870 * should be added or removed. For each such record, extract NSEC3PARAM RDATA 3871 * and pass it to zone_addnsec3chain(). 3872 * 3873 * Zone must be locked by caller. 3874 */ 3875static void 3876resume_addnsec3chain(dns_zone_t *zone) { 3877 dns_dbnode_t *node = NULL; 3878 dns_dbversion_t *version = NULL; 3879 dns_rdataset_t rdataset; 3880 isc_result_t result; 3881 dns_rdata_nsec3param_t nsec3param; 3882 bool nseconly = false, nsec3ok = false; 3883 dns_db_t *db = NULL; 3884 3885 INSIST(LOCKED_ZONE(zone)); 3886 3887 if (zone->privatetype == 0) { 3888 return; 3889 } 3890 3891 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3892 if (zone->db != NULL) { 3893 dns_db_attach(zone->db, &db); 3894 } 3895 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3896 if (db == NULL) { 3897 goto cleanup; 3898 } 3899 3900 result = dns_db_findnode(db, &zone->origin, false, &node); 3901 if (result != ISC_R_SUCCESS) { 3902 goto cleanup; 3903 } 3904 3905 dns_db_currentversion(db, &version); 3906 3907 /* 3908 * In order to create NSEC3 chains we need the DNSKEY RRset at zone 3909 * apex to exist and contain no keys using NSEC-only algorithms. 3910 */ 3911 result = dns_nsec_nseconly(db, version, NULL, &nseconly); 3912 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 3913 3914 /* 3915 * Get the RRset containing all private-type records at the zone apex. 3916 */ 3917 dns_rdataset_init(&rdataset); 3918 result = dns_db_findrdataset(db, node, version, zone->privatetype, 3919 dns_rdatatype_none, 0, &rdataset, NULL); 3920 if (result != ISC_R_SUCCESS) { 3921 INSIST(!dns_rdataset_isassociated(&rdataset)); 3922 goto cleanup; 3923 } 3924 3925 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 3926 result = dns_rdataset_next(&rdataset)) 3927 { 3928 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 3929 dns_rdata_t rdata = DNS_RDATA_INIT; 3930 dns_rdata_t private = DNS_RDATA_INIT; 3931 3932 dns_rdataset_current(&rdataset, &private); 3933 /* 3934 * Try extracting NSEC3PARAM RDATA from this private-type 3935 * record. Failure means this private-type record does not 3936 * represent an NSEC3PARAM record, so skip it. 3937 */ 3938 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 3939 sizeof(buf))) 3940 { 3941 continue; 3942 } 3943 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 3944 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3945 if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) || 3946 ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok)) 3947 { 3948 /* 3949 * Pass the NSEC3PARAM RDATA contained in this 3950 * private-type record to zone_addnsec3chain() so that 3951 * it can kick off adding or removing NSEC3 records. 3952 */ 3953 result = zone_addnsec3chain(zone, &nsec3param); 3954 if (result != ISC_R_SUCCESS) { 3955 dnssec_log(zone, ISC_LOG_ERROR, 3956 "zone_addnsec3chain failed: %s", 3957 isc_result_totext(result)); 3958 } 3959 } 3960 } 3961 dns_rdataset_disassociate(&rdataset); 3962 3963cleanup: 3964 if (db != NULL) { 3965 if (node != NULL) { 3966 dns_db_detachnode(db, &node); 3967 } 3968 if (version != NULL) { 3969 dns_db_closeversion(db, &version, false); 3970 } 3971 dns_db_detach(&db); 3972 } 3973} 3974 3975static void 3976set_resigntime(dns_zone_t *zone) { 3977 dns_rdataset_t rdataset; 3978 dns_fixedname_t fixed; 3979 unsigned int resign; 3980 isc_result_t result; 3981 uint32_t nanosecs; 3982 dns_db_t *db = NULL; 3983 3984 INSIST(LOCKED_ZONE(zone)); 3985 3986 /* We only re-sign zones that can be dynamically updated */ 3987 if (!dns_zone_isdynamic(zone, false)) { 3988 return; 3989 } 3990 3991 if (inline_raw(zone)) { 3992 return; 3993 } 3994 3995 dns_rdataset_init(&rdataset); 3996 dns_fixedname_init(&fixed); 3997 3998 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3999 if (zone->db != NULL) { 4000 dns_db_attach(zone->db, &db); 4001 } 4002 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 4003 if (db == NULL) { 4004 isc_time_settoepoch(&zone->resigntime); 4005 return; 4006 } 4007 4008 result = dns_db_getsigningtime(db, &rdataset, 4009 dns_fixedname_name(&fixed)); 4010 if (result != ISC_R_SUCCESS) { 4011 isc_time_settoepoch(&zone->resigntime); 4012 goto cleanup; 4013 } 4014 4015 resign = rdataset.resign - dns_zone_getsigresigninginterval(zone); 4016 dns_rdataset_disassociate(&rdataset); 4017 nanosecs = isc_random_uniform(1000000000); 4018 isc_time_set(&zone->resigntime, resign, nanosecs); 4019 4020cleanup: 4021 dns_db_detach(&db); 4022 return; 4023} 4024 4025static isc_result_t 4026check_nsec3param(dns_zone_t *zone, dns_db_t *db) { 4027 bool ok = false; 4028 dns_dbnode_t *node = NULL; 4029 dns_dbversion_t *version = NULL; 4030 dns_rdata_nsec3param_t nsec3param; 4031 dns_rdataset_t rdataset; 4032 isc_result_t result; 4033 bool dynamic = (zone->type == dns_zone_primary) 4034 ? dns_zone_isdynamic(zone, false) 4035 : false; 4036 4037 dns_rdataset_init(&rdataset); 4038 result = dns_db_findnode(db, &zone->origin, false, &node); 4039 if (result != ISC_R_SUCCESS) { 4040 dns_zone_log(zone, ISC_LOG_ERROR, 4041 "nsec3param lookup failure: %s", 4042 isc_result_totext(result)); 4043 return (result); 4044 } 4045 dns_db_currentversion(db, &version); 4046 4047 result = dns_db_findrdataset(db, node, version, 4048 dns_rdatatype_nsec3param, 4049 dns_rdatatype_none, 0, &rdataset, NULL); 4050 if (result == ISC_R_NOTFOUND) { 4051 INSIST(!dns_rdataset_isassociated(&rdataset)); 4052 result = ISC_R_SUCCESS; 4053 goto cleanup; 4054 } 4055 if (result != ISC_R_SUCCESS) { 4056 INSIST(!dns_rdataset_isassociated(&rdataset)); 4057 dns_zone_log(zone, ISC_LOG_ERROR, 4058 "nsec3param lookup failure: %s", 4059 isc_result_totext(result)); 4060 goto cleanup; 4061 } 4062 4063 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 4064 result = dns_rdataset_next(&rdataset)) 4065 { 4066 dns_rdata_t rdata = DNS_RDATA_INIT; 4067 4068 dns_rdataset_current(&rdataset, &rdata); 4069 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 4070 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4071 4072 /* 4073 * For dynamic zones we must support every algorithm so we 4074 * can regenerate all the NSEC3 chains. 4075 * For non-dynamic zones we only need to find a supported 4076 * algorithm. 4077 */ 4078 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) && 4079 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic) 4080 { 4081 dns_zone_log(zone, ISC_LOG_WARNING, 4082 "nsec3 test \"unknown\" hash algorithm " 4083 "found: %u", 4084 nsec3param.hash); 4085 ok = true; 4086 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) { 4087 if (dynamic) { 4088 dns_zone_log(zone, ISC_LOG_ERROR, 4089 "unsupported nsec3 hash algorithm" 4090 " in dynamic zone: %u", 4091 nsec3param.hash); 4092 result = DNS_R_BADZONE; 4093 /* Stop second error message. */ 4094 ok = true; 4095 break; 4096 } else { 4097 dns_zone_log(zone, ISC_LOG_WARNING, 4098 "unsupported nsec3 hash " 4099 "algorithm: %u", 4100 nsec3param.hash); 4101 } 4102 } else { 4103 ok = true; 4104 } 4105 4106 /* 4107 * Warn if the zone has excessive NSEC3 iterations. 4108 */ 4109 if (nsec3param.iterations > dns_nsec3_maxiterations()) { 4110 dnssec_log(zone, ISC_LOG_WARNING, 4111 "excessive NSEC3PARAM iterations %u > %u", 4112 nsec3param.iterations, 4113 dns_nsec3_maxiterations()); 4114 } 4115 } 4116 if (result == ISC_R_NOMORE) { 4117 result = ISC_R_SUCCESS; 4118 } 4119 4120 if (!ok) { 4121 result = DNS_R_BADZONE; 4122 dns_zone_log(zone, ISC_LOG_ERROR, 4123 "no supported nsec3 hash algorithm"); 4124 } 4125 4126cleanup: 4127 if (dns_rdataset_isassociated(&rdataset)) { 4128 dns_rdataset_disassociate(&rdataset); 4129 } 4130 dns_db_closeversion(db, &version, false); 4131 dns_db_detachnode(db, &node); 4132 return (result); 4133} 4134 4135/* 4136 * Set the timer for refreshing the key zone to the soonest future time 4137 * of the set (current timer, keydata->refresh, keydata->addhd, 4138 * keydata->removehd). 4139 */ 4140static void 4141set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key, 4142 isc_stdtime_t now, bool force) { 4143 const char me[] = "set_refreshkeytimer"; 4144 isc_stdtime_t then; 4145 isc_time_t timenow, timethen; 4146 char timebuf[80]; 4147 4148 ENTER; 4149 then = key->refresh; 4150 if (force) { 4151 then = now; 4152 } 4153 if (key->addhd > now && key->addhd < then) { 4154 then = key->addhd; 4155 } 4156 if (key->removehd > now && key->removehd < then) { 4157 then = key->removehd; 4158 } 4159 4160 TIME_NOW(&timenow); 4161 if (then > now) { 4162 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 4163 } else { 4164 timethen = timenow; 4165 } 4166 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 || 4167 isc_time_compare(&timethen, &zone->refreshkeytime) < 0) 4168 { 4169 zone->refreshkeytime = timethen; 4170 } 4171 4172 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 4173 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf); 4174 zone_settimer(zone, &timenow); 4175} 4176 4177/* 4178 * If keynode references a key or a DS rdataset, and if the key 4179 * zone does not contain a KEYDATA record for the corresponding name, 4180 * then create an empty KEYDATA and push it into the zone as a placeholder, 4181 * then schedule a key refresh immediately. This new KEYDATA record will be 4182 * updated during the refresh. 4183 * 4184 * If the key zone is changed, set '*changed' to true. 4185 */ 4186static isc_result_t 4187create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 4188 dns_diff_t *diff, dns_keynode_t *keynode, dns_name_t *keyname, 4189 bool *changed) { 4190 const char me[] = "create_keydata"; 4191 isc_result_t result = ISC_R_SUCCESS; 4192 dns_rdata_t rdata = DNS_RDATA_INIT; 4193 dns_rdata_keydata_t kd; 4194 unsigned char rrdata[4096]; 4195 isc_buffer_t rrdatabuf; 4196 isc_stdtime_t now; 4197 4198 REQUIRE(keynode != NULL); 4199 4200 ENTER; 4201 isc_stdtime_get(&now); 4202 4203 /* 4204 * If the keynode has no trust anchor set, we shouldn't be here. 4205 */ 4206 if (!dns_keynode_dsset(keynode, NULL)) { 4207 return (ISC_R_FAILURE); 4208 } 4209 4210 memset(&kd, 0, sizeof(kd)); 4211 kd.common.rdclass = zone->rdclass; 4212 kd.common.rdtype = dns_rdatatype_keydata; 4213 ISC_LINK_INIT(&kd.common, link); 4214 4215 isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); 4216 4217 CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass, dns_rdatatype_keydata, 4218 &kd, &rrdatabuf)); 4219 /* Add rdata to zone. */ 4220 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, keyname, 0, &rdata)); 4221 *changed = true; 4222 4223 /* Refresh new keys from the zone apex as soon as possible. */ 4224 set_refreshkeytimer(zone, &kd, now, true); 4225 return (ISC_R_SUCCESS); 4226 4227failure: 4228 return (result); 4229} 4230 4231/* 4232 * Remove from the key zone all the KEYDATA records found in rdataset. 4233 */ 4234static isc_result_t 4235delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 4236 dns_name_t *name, dns_rdataset_t *rdataset) { 4237 dns_rdata_t rdata = DNS_RDATA_INIT; 4238 isc_result_t result, uresult; 4239 4240 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 4241 result = dns_rdataset_next(rdataset)) 4242 { 4243 dns_rdata_reset(&rdata); 4244 dns_rdataset_current(rdataset, &rdata); 4245 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 0, 4246 &rdata); 4247 if (uresult != ISC_R_SUCCESS) { 4248 return (uresult); 4249 } 4250 } 4251 if (result == ISC_R_NOMORE) { 4252 result = ISC_R_SUCCESS; 4253 } 4254 return (result); 4255} 4256 4257/* 4258 * Compute the DNSSEC key ID for a DNSKEY record. 4259 */ 4260static isc_result_t 4261compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx, 4262 dns_keytag_t *tag) { 4263 isc_result_t result; 4264 dns_rdata_t rdata = DNS_RDATA_INIT; 4265 unsigned char data[4096]; 4266 isc_buffer_t buffer; 4267 dst_key_t *dstkey = NULL; 4268 4269 isc_buffer_init(&buffer, data, sizeof(data)); 4270 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 4271 dns_rdatatype_dnskey, dnskey, &buffer); 4272 4273 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey); 4274 if (result == ISC_R_SUCCESS) { 4275 *tag = dst_key_id(dstkey); 4276 dst_key_free(&dstkey); 4277 } 4278 4279 return (result); 4280} 4281 4282/* 4283 * Synth-from-dnssec callbacks to add/delete names from namespace tree. 4284 */ 4285static void 4286sfd_add(const dns_name_t *name, void *arg) { 4287 if (arg != NULL) { 4288 dns_view_sfd_add(arg, name); 4289 } 4290} 4291 4292static void 4293sfd_del(const dns_name_t *name, void *arg) { 4294 if (arg != NULL) { 4295 dns_view_sfd_del(arg, name); 4296 } 4297} 4298 4299/* 4300 * Add key to the security roots. 4301 */ 4302static void 4303trust_key(dns_zone_t *zone, dns_name_t *keyname, dns_rdata_dnskey_t *dnskey, 4304 bool initial) { 4305 isc_result_t result; 4306 dns_rdata_t rdata = DNS_RDATA_INIT; 4307 unsigned char data[4096], digest[ISC_MAX_MD_SIZE]; 4308 isc_buffer_t buffer; 4309 dns_keytable_t *sr = NULL; 4310 dns_rdata_ds_t ds; 4311 4312 result = dns_view_getsecroots(zone->view, &sr); 4313 if (result != ISC_R_SUCCESS) { 4314 return; 4315 } 4316 4317 /* Build DS record for key. */ 4318 isc_buffer_init(&buffer, data, sizeof(data)); 4319 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 4320 dns_rdatatype_dnskey, dnskey, &buffer); 4321 CHECK(dns_ds_fromkeyrdata(keyname, &rdata, DNS_DSDIGEST_SHA256, digest, 4322 &ds)); 4323 CHECK(dns_keytable_add(sr, true, initial, keyname, &ds, sfd_add, 4324 zone->view)); 4325 4326 dns_keytable_detach(&sr); 4327 4328failure: 4329 if (sr != NULL) { 4330 dns_keytable_detach(&sr); 4331 } 4332 return; 4333} 4334 4335/* 4336 * Add a null key to the security roots for so that all queries 4337 * to the zone will fail. 4338 */ 4339static void 4340fail_secure(dns_zone_t *zone, dns_name_t *keyname) { 4341 isc_result_t result; 4342 dns_keytable_t *sr = NULL; 4343 4344 result = dns_view_getsecroots(zone->view, &sr); 4345 if (result == ISC_R_SUCCESS) { 4346 dns_keytable_marksecure(sr, keyname); 4347 dns_keytable_detach(&sr); 4348 } 4349} 4350 4351/* 4352 * Scan a set of KEYDATA records from the key zone. The ones that are 4353 * valid (i.e., the add holddown timer has expired) become trusted keys. 4354 */ 4355static void 4356load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) { 4357 isc_result_t result; 4358 dns_rdata_t rdata = DNS_RDATA_INIT; 4359 dns_rdata_keydata_t keydata; 4360 dns_rdata_dnskey_t dnskey; 4361 int trusted = 0, revoked = 0, pending = 0; 4362 isc_stdtime_t now; 4363 dns_keytable_t *sr = NULL; 4364 4365 isc_stdtime_get(&now); 4366 4367 result = dns_view_getsecroots(zone->view, &sr); 4368 if (result == ISC_R_SUCCESS) { 4369 dns_keytable_delete(sr, name, sfd_del, zone->view); 4370 dns_keytable_detach(&sr); 4371 } 4372 4373 /* Now insert all the accepted trust anchors from this keydata set. */ 4374 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 4375 result = dns_rdataset_next(rdataset)) 4376 { 4377 dns_rdata_reset(&rdata); 4378 dns_rdataset_current(rdataset, &rdata); 4379 4380 /* Convert rdata to keydata. */ 4381 result = dns_rdata_tostruct(&rdata, &keydata, NULL); 4382 if (result == ISC_R_UNEXPECTEDEND) { 4383 continue; 4384 } 4385 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4386 4387 /* Set the key refresh timer to force a fast refresh. */ 4388 set_refreshkeytimer(zone, &keydata, now, true); 4389 4390 /* If the removal timer is nonzero, this key was revoked. */ 4391 if (keydata.removehd != 0) { 4392 revoked++; 4393 continue; 4394 } 4395 4396 /* 4397 * If the add timer is still pending, this key is not 4398 * trusted yet. 4399 */ 4400 if (now < keydata.addhd) { 4401 pending++; 4402 continue; 4403 } 4404 4405 /* Convert keydata to dnskey. */ 4406 dns_keydata_todnskey(&keydata, &dnskey, NULL); 4407 4408 /* Add to keytables. */ 4409 trusted++; 4410 trust_key(zone, name, &dnskey, (keydata.addhd == 0)); 4411 } 4412 4413 if (trusted == 0 && pending != 0) { 4414 char namebuf[DNS_NAME_FORMATSIZE]; 4415 dns_name_format(name, namebuf, sizeof namebuf); 4416 dnssec_log(zone, ISC_LOG_ERROR, 4417 "No valid trust anchors for '%s'!", namebuf); 4418 dnssec_log(zone, ISC_LOG_ERROR, 4419 "%d key(s) revoked, %d still pending", revoked, 4420 pending); 4421 dnssec_log(zone, ISC_LOG_ERROR, "All queries to '%s' will fail", 4422 namebuf); 4423 fail_secure(zone, name); 4424 } 4425} 4426 4427static isc_result_t 4428do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, 4429 dns_diff_t *diff) { 4430 dns_diff_t temp_diff; 4431 isc_result_t result; 4432 4433 /* 4434 * Create a singleton diff. 4435 */ 4436 dns_diff_init(diff->mctx, &temp_diff); 4437 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); 4438 4439 /* 4440 * Apply it to the database. 4441 */ 4442 result = dns_diff_apply(&temp_diff, db, ver); 4443 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); 4444 if (result != ISC_R_SUCCESS) { 4445 dns_difftuple_free(tuple); 4446 return (result); 4447 } 4448 4449 /* 4450 * Merge it into the current pending journal entry. 4451 */ 4452 dns_diff_appendminimal(diff, tuple); 4453 4454 /* 4455 * Do not clear temp_diff. 4456 */ 4457 return (ISC_R_SUCCESS); 4458} 4459 4460static isc_result_t 4461update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 4462 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, 4463 dns_rdata_t *rdata) { 4464 dns_difftuple_t *tuple = NULL; 4465 isc_result_t result; 4466 result = dns_difftuple_create(diff->mctx, op, name, ttl, rdata, &tuple); 4467 if (result != ISC_R_SUCCESS) { 4468 return (result); 4469 } 4470 return (do_one_tuple(&tuple, db, ver, diff)); 4471} 4472 4473static isc_result_t 4474update_soa_serial(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 4475 dns_diff_t *diff, isc_mem_t *mctx, 4476 dns_updatemethod_t method) { 4477 dns_difftuple_t *deltuple = NULL; 4478 dns_difftuple_t *addtuple = NULL; 4479 uint32_t serial; 4480 isc_result_t result; 4481 dns_updatemethod_t used = dns_updatemethod_none; 4482 4483 INSIST(method != dns_updatemethod_none); 4484 4485 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple)); 4486 CHECK(dns_difftuple_copy(deltuple, &addtuple)); 4487 addtuple->op = DNS_DIFFOP_ADD; 4488 4489 serial = dns_soa_getserial(&addtuple->rdata); 4490 serial = dns_update_soaserial(serial, method, &used); 4491 if (method != used) { 4492 dns_zone_log(zone, ISC_LOG_WARNING, 4493 "update_soa_serial:new serial would be lower than " 4494 "old serial, using increment method instead"); 4495 } 4496 dns_soa_setserial(serial, &addtuple->rdata); 4497 CHECK(do_one_tuple(&deltuple, db, ver, diff)); 4498 CHECK(do_one_tuple(&addtuple, db, ver, diff)); 4499 result = ISC_R_SUCCESS; 4500 4501failure: 4502 if (addtuple != NULL) { 4503 dns_difftuple_free(&addtuple); 4504 } 4505 if (deltuple != NULL) { 4506 dns_difftuple_free(&deltuple); 4507 } 4508 return (result); 4509} 4510 4511/* 4512 * Write all transactions in 'diff' to the zone journal file. 4513 */ 4514static isc_result_t 4515zone_journal(dns_zone_t *zone, dns_diff_t *diff, uint32_t *sourceserial, 4516 const char *caller) { 4517 const char me[] = "zone_journal"; 4518 const char *journalfile; 4519 isc_result_t result = ISC_R_SUCCESS; 4520 dns_journal_t *journal = NULL; 4521 unsigned int mode = DNS_JOURNAL_CREATE | DNS_JOURNAL_WRITE; 4522 4523 ENTER; 4524 journalfile = dns_zone_getjournal(zone); 4525 if (journalfile != NULL) { 4526 result = dns_journal_open(zone->mctx, journalfile, mode, 4527 &journal); 4528 if (result != ISC_R_SUCCESS) { 4529 dns_zone_log(zone, ISC_LOG_ERROR, 4530 "%s:dns_journal_open -> %s", caller, 4531 isc_result_totext(result)); 4532 return (result); 4533 } 4534 4535 if (sourceserial != NULL) { 4536 dns_journal_set_sourceserial(journal, *sourceserial); 4537 } 4538 4539 result = dns_journal_write_transaction(journal, diff); 4540 if (result != ISC_R_SUCCESS) { 4541 dns_zone_log(zone, ISC_LOG_ERROR, 4542 "%s:dns_journal_write_transaction -> %s", 4543 caller, isc_result_totext(result)); 4544 } 4545 dns_journal_destroy(&journal); 4546 } 4547 4548 return (result); 4549} 4550 4551/* 4552 * Create an SOA record for a newly-created zone 4553 */ 4554static isc_result_t 4555add_soa(dns_zone_t *zone, dns_db_t *db) { 4556 isc_result_t result; 4557 dns_rdata_t rdata = DNS_RDATA_INIT; 4558 unsigned char buf[DNS_SOA_BUFFERSIZE]; 4559 dns_dbversion_t *ver = NULL; 4560 dns_diff_t diff; 4561 4562 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA"); 4563 4564 dns_diff_init(zone->mctx, &diff); 4565 result = dns_db_newversion(db, &ver); 4566 if (result != ISC_R_SUCCESS) { 4567 dns_zone_log(zone, ISC_LOG_ERROR, 4568 "add_soa:dns_db_newversion -> %s", 4569 isc_result_totext(result)); 4570 goto failure; 4571 } 4572 4573 /* Build SOA record */ 4574 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass, 4575 0, 0, 0, 0, 0, buf, &rdata); 4576 if (result != ISC_R_SUCCESS) { 4577 dns_zone_log(zone, ISC_LOG_ERROR, 4578 "add_soa:dns_soa_buildrdata -> %s", 4579 isc_result_totext(result)); 4580 goto failure; 4581 } 4582 4583 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD, &zone->origin, 0, 4584 &rdata); 4585 4586failure: 4587 dns_diff_clear(&diff); 4588 if (ver != NULL) { 4589 dns_db_closeversion(db, &ver, (result == ISC_R_SUCCESS)); 4590 } 4591 4592 INSIST(ver == NULL); 4593 4594 return (result); 4595} 4596 4597struct addifmissing_arg { 4598 dns_db_t *db; 4599 dns_dbversion_t *ver; 4600 dns_diff_t *diff; 4601 dns_zone_t *zone; 4602 bool *changed; 4603 isc_result_t result; 4604}; 4605 4606static void 4607addifmissing(dns_keytable_t *keytable, dns_keynode_t *keynode, 4608 dns_name_t *keyname, void *arg) { 4609 dns_db_t *db = ((struct addifmissing_arg *)arg)->db; 4610 dns_dbversion_t *ver = ((struct addifmissing_arg *)arg)->ver; 4611 dns_diff_t *diff = ((struct addifmissing_arg *)arg)->diff; 4612 dns_zone_t *zone = ((struct addifmissing_arg *)arg)->zone; 4613 bool *changed = ((struct addifmissing_arg *)arg)->changed; 4614 isc_result_t result; 4615 dns_fixedname_t fname; 4616 4617 UNUSED(keytable); 4618 4619 if (((struct addifmissing_arg *)arg)->result != ISC_R_SUCCESS) { 4620 return; 4621 } 4622 4623 if (!dns_keynode_managed(keynode)) { 4624 return; 4625 } 4626 4627 /* 4628 * If the keynode has no trust anchor set, return. 4629 */ 4630 if (!dns_keynode_dsset(keynode, NULL)) { 4631 return; 4632 } 4633 4634 /* 4635 * Check whether there's already a KEYDATA entry for this name; 4636 * if so, we don't need to add another. 4637 */ 4638 dns_fixedname_init(&fname); 4639 result = dns_db_find(db, keyname, ver, dns_rdatatype_keydata, 4640 DNS_DBFIND_NOWILD, 0, NULL, 4641 dns_fixedname_name(&fname), NULL, NULL); 4642 if (result == ISC_R_SUCCESS) { 4643 return; 4644 } 4645 4646 /* 4647 * Create the keydata. 4648 */ 4649 result = create_keydata(zone, db, ver, diff, keynode, keyname, changed); 4650 if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) { 4651 ((struct addifmissing_arg *)arg)->result = result; 4652 } 4653} 4654 4655/* 4656 * Synchronize the set of initializing keys found in managed-keys {} 4657 * statements with the set of trust anchors found in the managed-keys.bind 4658 * zone. If a domain is no longer named in managed-keys, delete all keys 4659 * from that domain from the key zone. If a domain is configured as an 4660 * initial-key in trust-anchors, but there are no references to it in the 4661 * key zone, load the key zone with the initializing key(s) for that 4662 * domain and schedule a key refresh. If a domain is configured as 4663 * an initial-ds in trust-anchors, fetch the DNSKEY RRset, load the key 4664 * zone with the matching key, and schedule a key refresh. 4665 */ 4666static isc_result_t 4667sync_keyzone(dns_zone_t *zone, dns_db_t *db) { 4668 isc_result_t result = ISC_R_SUCCESS; 4669 bool changed = false; 4670 bool commit = false; 4671 dns_keynode_t *keynode = NULL; 4672 dns_view_t *view = zone->view; 4673 dns_keytable_t *sr = NULL; 4674 dns_dbversion_t *ver = NULL; 4675 dns_diff_t diff; 4676 dns_rriterator_t rrit; 4677 struct addifmissing_arg arg; 4678 4679 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys"); 4680 4681 dns_diff_init(zone->mctx, &diff); 4682 4683 CHECK(dns_view_getsecroots(view, &sr)); 4684 4685 result = dns_db_newversion(db, &ver); 4686 if (result != ISC_R_SUCCESS) { 4687 dnssec_log(zone, ISC_LOG_ERROR, 4688 "sync_keyzone:dns_db_newversion -> %s", 4689 isc_result_totext(result)); 4690 goto failure; 4691 } 4692 4693 /* 4694 * Walk the zone DB. If we find any keys whose names are no longer 4695 * in trust-anchors, or which have been changed from initial to static, 4696 * (meaning they are permanent and not RFC5011-maintained), delete 4697 * them from the zone. Otherwise call load_secroots(), which 4698 * loads keys into secroots as appropriate. 4699 */ 4700 dns_rriterator_init(&rrit, db, ver, 0); 4701 for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS; 4702 result = dns_rriterator_nextrrset(&rrit)) 4703 { 4704 dns_rdataset_t *rdataset = NULL; 4705 dns_rdata_t rdata = DNS_RDATA_INIT; 4706 dns_rdata_keydata_t keydata; 4707 isc_stdtime_t now; 4708 bool load = true; 4709 dns_name_t *rrname = NULL; 4710 uint32_t ttl; 4711 4712 isc_stdtime_get(&now); 4713 4714 dns_rriterator_current(&rrit, &rrname, &ttl, &rdataset, NULL); 4715 if (!dns_rdataset_isassociated(rdataset)) { 4716 dns_rriterator_destroy(&rrit); 4717 goto failure; 4718 } 4719 4720 if (rdataset->type != dns_rdatatype_keydata) { 4721 continue; 4722 } 4723 4724 /* 4725 * The managed-keys zone can contain a placeholder instead of 4726 * legitimate data, in which case we will not use it, and we 4727 * will try to refresh it. 4728 */ 4729 for (result = dns_rdataset_first(rdataset); 4730 result == ISC_R_SUCCESS; 4731 result = dns_rdataset_next(rdataset)) 4732 { 4733 isc_result_t iresult; 4734 4735 dns_rdata_reset(&rdata); 4736 dns_rdataset_current(rdataset, &rdata); 4737 4738 iresult = dns_rdata_tostruct(&rdata, &keydata, NULL); 4739 /* Do we have a valid placeholder KEYDATA record? */ 4740 if (iresult == ISC_R_SUCCESS && keydata.flags == 0 && 4741 keydata.protocol == 0 && keydata.algorithm == 0) 4742 { 4743 set_refreshkeytimer(zone, &keydata, now, true); 4744 load = false; 4745 } 4746 } 4747 4748 /* 4749 * Release db wrlock to prevent LOR reports against 4750 * dns_keytable_forall() call below. 4751 */ 4752 dns_rriterator_pause(&rrit); 4753 result = dns_keytable_find(sr, rrname, &keynode); 4754 if (result != ISC_R_SUCCESS || !dns_keynode_managed(keynode)) { 4755 CHECK(delete_keydata(db, ver, &diff, rrname, rdataset)); 4756 changed = true; 4757 } else if (load) { 4758 load_secroots(zone, rrname, rdataset); 4759 } 4760 4761 if (keynode != NULL) { 4762 dns_keytable_detachkeynode(sr, &keynode); 4763 } 4764 } 4765 dns_rriterator_destroy(&rrit); 4766 4767 /* 4768 * Walk secroots to find any initial keys that aren't in 4769 * the zone. If we find any, add them to the zone directly. 4770 * If any DS-style initial keys are found, refresh the key 4771 * zone so that they'll be looked up. 4772 */ 4773 arg.db = db; 4774 arg.ver = ver; 4775 arg.result = ISC_R_SUCCESS; 4776 arg.diff = &diff; 4777 arg.zone = zone; 4778 arg.changed = &changed; 4779 dns_keytable_forall(sr, addifmissing, &arg); 4780 result = arg.result; 4781 if (changed) { 4782 /* Write changes to journal file. */ 4783 CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx, 4784 zone->updatemethod)); 4785 CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone")); 4786 4787 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 4788 zone_needdump(zone, 30); 4789 commit = true; 4790 } 4791 4792failure: 4793 if (result != ISC_R_SUCCESS) { 4794 dnssec_log(zone, ISC_LOG_ERROR, 4795 "unable to synchronize managed keys: %s", 4796 isc_result_totext(result)); 4797 isc_time_settoepoch(&zone->refreshkeytime); 4798 } 4799 if (keynode != NULL) { 4800 dns_keytable_detachkeynode(sr, &keynode); 4801 } 4802 if (sr != NULL) { 4803 dns_keytable_detach(&sr); 4804 } 4805 if (ver != NULL) { 4806 dns_db_closeversion(db, &ver, commit); 4807 } 4808 dns_diff_clear(&diff); 4809 4810 INSIST(ver == NULL); 4811 4812 return (result); 4813} 4814 4815isc_result_t 4816dns_zone_synckeyzone(dns_zone_t *zone) { 4817 isc_result_t result; 4818 dns_db_t *db = NULL; 4819 4820 if (zone->type != dns_zone_key) { 4821 return (DNS_R_BADZONE); 4822 } 4823 4824 CHECK(dns_zone_getdb(zone, &db)); 4825 4826 LOCK_ZONE(zone); 4827 result = sync_keyzone(zone, db); 4828 UNLOCK_ZONE(zone); 4829 4830failure: 4831 if (db != NULL) { 4832 dns_db_detach(&db); 4833 } 4834 return (result); 4835} 4836 4837static void 4838maybe_send_secure(dns_zone_t *zone) { 4839 isc_result_t result; 4840 4841 /* 4842 * We've finished loading, or else failed to load, an inline-signing 4843 * 'secure' zone. We now need information about the status of the 4844 * 'raw' zone. If we failed to load, then we need it to send a 4845 * copy of its database; if we succeeded, we need it to send its 4846 * serial number so that we can sync with it. If it has not yet 4847 * loaded, we set a flag so that it will send the necessary 4848 * information when it has finished loading. 4849 */ 4850 if (zone->raw->db != NULL) { 4851 if (zone->db != NULL) { 4852 uint32_t serial; 4853 unsigned int soacount; 4854 4855 result = zone_get_from_db( 4856 zone->raw, zone->raw->db, NULL, &soacount, NULL, 4857 &serial, NULL, NULL, NULL, NULL, NULL); 4858 if (result == ISC_R_SUCCESS && soacount > 0U) { 4859 zone_send_secureserial(zone->raw, serial); 4860 } 4861 } else { 4862 zone_send_securedb(zone->raw, zone->raw->db); 4863 } 4864 } else { 4865 DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE); 4866 } 4867} 4868 4869static bool 4870zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) { 4871 isc_result_t result; 4872 bool answer = false; 4873 dns_diff_t diff; 4874 4875 dns_diff_init(mctx, &diff); 4876 result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL); 4877 if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples)) { 4878 answer = true; 4879 } 4880 dns_diff_clear(&diff); 4881 return (answer); 4882} 4883 4884/* 4885 * The zone is presumed to be locked. 4886 * If this is a inline_raw zone the secure version is also locked. 4887 */ 4888static isc_result_t 4889zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, 4890 isc_result_t result) { 4891 unsigned int soacount = 0; 4892 unsigned int nscount = 0; 4893 unsigned int errors = 0; 4894 uint32_t serial, oldserial, refresh, retry, expire, minimum, soattl; 4895 isc_time_t now; 4896 bool needdump = false; 4897 bool fixjournal = false; 4898 bool hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE); 4899 bool noprimary = false; 4900 bool had_db = false; 4901 dns_include_t *inc; 4902 bool is_dynamic = false; 4903 4904 INSIST(LOCKED_ZONE(zone)); 4905 if (inline_raw(zone)) { 4906 INSIST(LOCKED_ZONE(zone->secure)); 4907 } 4908 4909 TIME_NOW(&now); 4910 4911 /* 4912 * Initiate zone transfer? We may need a error code that 4913 * indicates that the "permanent" form does not exist. 4914 * XXX better error feedback to log. 4915 */ 4916 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { 4917 if (zone->type == dns_zone_secondary || 4918 zone->type == dns_zone_mirror || 4919 zone->type == dns_zone_stub || 4920 (zone->type == dns_zone_redirect && 4921 zone->primaries == NULL)) 4922 { 4923 if (result == ISC_R_FILENOTFOUND) { 4924 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4925 ISC_LOG_DEBUG(1), 4926 "no master file"); 4927 } else if (result != DNS_R_NOMASTERFILE) { 4928 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4929 ISC_LOG_ERROR, 4930 "loading from master file %s " 4931 "failed: %s", 4932 zone->masterfile, 4933 isc_result_totext(result)); 4934 } 4935 } else if (zone->type == dns_zone_primary && 4936 inline_secure(zone) && result == ISC_R_FILENOTFOUND) 4937 { 4938 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 4939 ISC_LOG_DEBUG(1), 4940 "no master file, requesting db"); 4941 maybe_send_secure(zone); 4942 } else { 4943 int level = ISC_LOG_ERROR; 4944 if (zone->type == dns_zone_key && 4945 result == ISC_R_FILENOTFOUND) 4946 { 4947 level = ISC_LOG_DEBUG(1); 4948 } 4949 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, level, 4950 "loading from master file %s failed: %s", 4951 zone->masterfile, 4952 isc_result_totext(result)); 4953 noprimary = true; 4954 } 4955 4956 if (zone->type != dns_zone_key) { 4957 goto cleanup; 4958 } 4959 } 4960 4961 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(2), 4962 "number of nodes in database: %u", 4963 dns_db_nodecount(db, dns_dbtree_main)); 4964 4965 if (result == DNS_R_SEENINCLUDE) { 4966 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 4967 } else { 4968 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 4969 } 4970 4971 /* 4972 * If there's no master file for a key zone, then the zone is new: 4973 * create an SOA record. (We do this now, instead of later, so that 4974 * if there happens to be a journal file, we can roll forward from 4975 * a sane starting point.) 4976 */ 4977 if (noprimary && zone->type == dns_zone_key) { 4978 result = add_soa(zone, db); 4979 if (result != ISC_R_SUCCESS) { 4980 goto cleanup; 4981 } 4982 } 4983 4984 /* 4985 * Apply update log, if any, on initial load. 4986 */ 4987 if (zone->journal != NULL && 4988 !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) && 4989 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 4990 { 4991 result = zone_journal_rollforward(zone, db, &needdump, 4992 &fixjournal); 4993 if (result != ISC_R_SUCCESS) { 4994 goto cleanup; 4995 } 4996 } 4997 4998 /* 4999 * Obtain ns, soa and cname counts for top of zone. 5000 */ 5001 INSIST(db != NULL); 5002 result = zone_get_from_db(zone, db, &nscount, &soacount, &soattl, 5003 &serial, &refresh, &retry, &expire, &minimum, 5004 &errors); 5005 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) { 5006 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 5007 "could not find NS and/or SOA records"); 5008 } 5009 5010 /* 5011 * Process any queued NSEC3PARAM change requests. Only for dynamic 5012 * zones, an inline-signing zone will perform this action when 5013 * receiving the secure db (receive_secure_db). 5014 */ 5015 is_dynamic = dns_zone_isdynamic(zone, true); 5016 if (is_dynamic) { 5017 isc_event_t *setnsec3param_event; 5018 dns_zone_t *dummy; 5019 5020 while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) { 5021 setnsec3param_event = 5022 ISC_LIST_HEAD(zone->setnsec3param_queue); 5023 ISC_LIST_UNLINK(zone->setnsec3param_queue, 5024 setnsec3param_event, ev_link); 5025 dummy = NULL; 5026 zone_iattach(zone, &dummy); 5027 isc_task_send(zone->task, &setnsec3param_event); 5028 } 5029 } 5030 5031 /* 5032 * Check to make sure the journal is up to date, and remove the 5033 * journal file if it isn't, as we wouldn't be able to apply 5034 * updates otherwise. 5035 */ 5036 if (zone->journal != NULL && is_dynamic && 5037 !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) 5038 { 5039 uint32_t jserial; 5040 dns_journal_t *journal = NULL; 5041 bool empty = false; 5042 5043 result = dns_journal_open(zone->mctx, zone->journal, 5044 DNS_JOURNAL_READ, &journal); 5045 if (result == ISC_R_SUCCESS) { 5046 jserial = dns_journal_last_serial(journal); 5047 empty = dns_journal_empty(journal); 5048 dns_journal_destroy(&journal); 5049 } else { 5050 jserial = serial; 5051 result = ISC_R_SUCCESS; 5052 } 5053 5054 if (jserial != serial) { 5055 if (!empty) { 5056 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5057 ISC_LOG_INFO, 5058 "journal file is out of date: " 5059 "removing journal file"); 5060 } 5061 if (remove(zone->journal) < 0 && errno != ENOENT) { 5062 char strbuf[ISC_STRERRORSIZE]; 5063 strerror_r(errno, strbuf, sizeof(strbuf)); 5064 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 5065 DNS_LOGMODULE_ZONE, 5066 ISC_LOG_WARNING, 5067 "unable to remove journal " 5068 "'%s': '%s'", 5069 zone->journal, strbuf); 5070 } 5071 } 5072 } 5073 5074 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1), 5075 "loaded; checking validity"); 5076 5077 /* 5078 * Primary / Secondary / Mirror / Stub zones require both NS and SOA 5079 * records at the top of the zone. 5080 */ 5081 5082 switch (zone->type) { 5083 case dns_zone_dlz: 5084 case dns_zone_primary: 5085 case dns_zone_secondary: 5086 case dns_zone_mirror: 5087 case dns_zone_stub: 5088 case dns_zone_redirect: 5089 if (soacount != 1) { 5090 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5091 ISC_LOG_ERROR, "has %d SOA records", 5092 soacount); 5093 result = DNS_R_BADZONE; 5094 } 5095 if (nscount == 0) { 5096 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5097 ISC_LOG_ERROR, "has no NS records"); 5098 result = DNS_R_BADZONE; 5099 } 5100 if (result != ISC_R_SUCCESS) { 5101 goto cleanup; 5102 } 5103 if (zone->type == dns_zone_primary && errors != 0) { 5104 result = DNS_R_BADZONE; 5105 goto cleanup; 5106 } 5107 if (zone->type != dns_zone_stub && 5108 zone->type != dns_zone_redirect) 5109 { 5110 result = check_nsec3param(zone, db); 5111 if (result != ISC_R_SUCCESS) { 5112 goto cleanup; 5113 } 5114 } 5115 if (zone->type == dns_zone_primary && 5116 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) && 5117 !integrity_checks(zone, db)) 5118 { 5119 result = DNS_R_BADZONE; 5120 goto cleanup; 5121 } 5122 if (zone->type == dns_zone_primary && 5123 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) && 5124 !zone_check_dup(zone, db)) 5125 { 5126 result = DNS_R_BADZONE; 5127 goto cleanup; 5128 } 5129 5130 if (zone->type == dns_zone_primary) { 5131 result = dns_zone_cdscheck(zone, db, NULL); 5132 if (result != ISC_R_SUCCESS) { 5133 dns_zone_log(zone, ISC_LOG_ERROR, 5134 "CDS/CDNSKEY consistency checks " 5135 "failed"); 5136 goto cleanup; 5137 } 5138 } 5139 5140 result = dns_zone_verifydb(zone, db, NULL); 5141 if (result != ISC_R_SUCCESS) { 5142 goto cleanup; 5143 } 5144 5145 if (zone->db != NULL) { 5146 unsigned int oldsoacount; 5147 5148 /* 5149 * This is checked in zone_replacedb() for 5150 * secondary zones as they don't reload from disk. 5151 */ 5152 result = zone_get_from_db( 5153 zone, zone->db, NULL, &oldsoacount, NULL, 5154 &oldserial, NULL, NULL, NULL, NULL, NULL); 5155 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5156 RUNTIME_CHECK(oldsoacount > 0U); 5157 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 5158 !isc_serial_gt(serial, oldserial)) 5159 { 5160 uint32_t serialmin, serialmax; 5161 5162 INSIST(zone->type == dns_zone_primary); 5163 INSIST(zone->raw == NULL); 5164 5165 if (serial == oldserial && 5166 zone_unchanged(zone->db, db, zone->mctx)) 5167 { 5168 dns_zone_logc(zone, 5169 DNS_LOGCATEGORY_ZONELOAD, 5170 ISC_LOG_INFO, 5171 "ixfr-from-differences: " 5172 "unchanged"); 5173 zone->loadtime = loadtime; 5174 goto done; 5175 } 5176 5177 serialmin = (oldserial + 1) & 0xffffffffU; 5178 serialmax = (oldserial + 0x7fffffffU) & 5179 0xffffffffU; 5180 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5181 ISC_LOG_ERROR, 5182 "ixfr-from-differences: " 5183 "new serial (%u) out of range " 5184 "[%u - %u]", 5185 serial, serialmin, serialmax); 5186 result = DNS_R_BADZONE; 5187 goto cleanup; 5188 } else if (!isc_serial_ge(serial, oldserial)) { 5189 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5190 ISC_LOG_ERROR, 5191 "zone serial (%u/%u) has gone " 5192 "backwards", 5193 serial, oldserial); 5194 } else if (serial == oldserial && !hasinclude && 5195 strcmp(zone->db_argv[0], "_builtin") != 0) 5196 { 5197 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5198 ISC_LOG_ERROR, 5199 "zone serial (%u) unchanged. " 5200 "zone may fail to transfer " 5201 "to secondaries.", 5202 serial); 5203 } 5204 } 5205 5206 if (zone->type == dns_zone_primary && 5207 (zone->update_acl != NULL || zone->ssutable != NULL) && 5208 dns_zone_getsigresigninginterval(zone) < (3 * refresh) && 5209 dns_db_issecure(db)) 5210 { 5211 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5212 ISC_LOG_WARNING, 5213 "sig-re-signing-interval less than " 5214 "3 * refresh."); 5215 } 5216 5217 zone->refresh = RANGE(refresh, zone->minrefresh, 5218 zone->maxrefresh); 5219 zone->retry = RANGE(retry, zone->minretry, zone->maxretry); 5220 zone->expire = RANGE(expire, zone->refresh + zone->retry, 5221 DNS_MAX_EXPIRE); 5222 zone->soattl = soattl; 5223 zone->minimum = minimum; 5224 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 5225 5226 if (zone->type == dns_zone_secondary || 5227 zone->type == dns_zone_mirror || 5228 zone->type == dns_zone_stub || 5229 (zone->type == dns_zone_redirect && 5230 zone->primaries != NULL)) 5231 { 5232 isc_time_t t; 5233 uint32_t delay; 5234 5235 result = isc_file_getmodtime(zone->journal, &t); 5236 if (result != ISC_R_SUCCESS) { 5237 result = isc_file_getmodtime(zone->masterfile, 5238 &t); 5239 } 5240 if (result == ISC_R_SUCCESS) { 5241 DNS_ZONE_TIME_ADD(&t, zone->expire, 5242 &zone->expiretime); 5243 } else { 5244 DNS_ZONE_TIME_ADD(&now, zone->retry, 5245 &zone->expiretime); 5246 } 5247 5248 delay = (zone->retry - 5249 isc_random_uniform((zone->retry * 3) / 4)); 5250 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime); 5251 if (isc_time_compare(&zone->refreshtime, 5252 &zone->expiretime) >= 0) 5253 { 5254 zone->refreshtime = now; 5255 } 5256 } 5257 5258 break; 5259 5260 case dns_zone_key: 5261 /* Nothing needs to be done now */ 5262 break; 5263 5264 default: 5265 UNEXPECTED_ERROR("unexpected zone type %d", zone->type); 5266 result = ISC_R_UNEXPECTED; 5267 goto cleanup; 5268 } 5269 5270 /* 5271 * Check for weak DNSKEY's. 5272 */ 5273 if (zone->type == dns_zone_primary) { 5274 zone_check_dnskeys(zone, db); 5275 } 5276 5277 /* 5278 * Schedule DNSSEC key refresh. 5279 */ 5280 if (zone->type == dns_zone_primary && 5281 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 5282 { 5283 zone->refreshkeytime = now; 5284 } 5285 5286 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 5287 if (zone->db != NULL) { 5288 had_db = true; 5289 result = zone_replacedb(zone, db, false); 5290 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 5291 if (result != ISC_R_SUCCESS) { 5292 goto cleanup; 5293 } 5294 } else { 5295 zone_attachdb(zone, db); 5296 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 5297 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | 5298 DNS_ZONEFLG_NEEDSTARTUPNOTIFY); 5299 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) && 5300 inline_raw(zone)) 5301 { 5302 if (zone->secure->db == NULL) { 5303 zone_send_securedb(zone, db); 5304 } else { 5305 zone_send_secureserial(zone, serial); 5306 } 5307 } 5308 } 5309 5310 /* 5311 * Finished loading inline-signing zone; need to get status 5312 * from the raw side now. 5313 */ 5314 if (zone->type == dns_zone_primary && inline_secure(zone)) { 5315 maybe_send_secure(zone); 5316 } 5317 5318 result = ISC_R_SUCCESS; 5319 5320 if (fixjournal) { 5321 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FIXJOURNAL); 5322 zone_journal_compact(zone, zone->db, 0); 5323 } 5324 if (needdump) { 5325 if (zone->type == dns_zone_key) { 5326 zone_needdump(zone, 30); 5327 } else { 5328 zone_needdump(zone, DNS_DUMP_DELAY); 5329 } 5330 } 5331 5332 if (zone->task != NULL) { 5333 if (zone->type == dns_zone_primary) { 5334 set_resigntime(zone); 5335 resume_signingwithkey(zone); 5336 resume_addnsec3chain(zone); 5337 } 5338 5339 is_dynamic = dns_zone_isdynamic(zone, false); 5340 if (zone->type == dns_zone_primary && 5341 !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) && 5342 is_dynamic && dns_db_issecure(db) && !inline_raw(zone)) 5343 { 5344 dns_name_t *name; 5345 dns_fixedname_t fixed; 5346 dns_rdataset_t next; 5347 5348 dns_rdataset_init(&next); 5349 name = dns_fixedname_initname(&fixed); 5350 5351 result = dns_db_getsigningtime(db, &next, name); 5352 if (result == ISC_R_SUCCESS) { 5353 isc_stdtime_t timenow; 5354 char namebuf[DNS_NAME_FORMATSIZE]; 5355 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 5356 5357 isc_stdtime_get(&timenow); 5358 dns_name_format(name, namebuf, sizeof(namebuf)); 5359 dns_rdatatype_format(next.covers, typebuf, 5360 sizeof(typebuf)); 5361 dnssec_log( 5362 zone, ISC_LOG_DEBUG(3), 5363 "next resign: %s/%s " 5364 "in %d seconds", 5365 namebuf, typebuf, 5366 next.resign - timenow - 5367 dns_zone_getsigresigninginterval( 5368 zone)); 5369 dns_rdataset_disassociate(&next); 5370 } else { 5371 dnssec_log(zone, ISC_LOG_WARNING, 5372 "signed dynamic zone has no " 5373 "resign event scheduled"); 5374 } 5375 } 5376 5377 zone_settimer(zone, &now); 5378 } 5379 5380 /* 5381 * Clear old include list. 5382 */ 5383 for (inc = ISC_LIST_HEAD(zone->includes); inc != NULL; 5384 inc = ISC_LIST_HEAD(zone->includes)) 5385 { 5386 ISC_LIST_UNLINK(zone->includes, inc, link); 5387 isc_mem_free(zone->mctx, inc->name); 5388 isc_mem_put(zone->mctx, inc, sizeof(*inc)); 5389 } 5390 zone->nincludes = 0; 5391 5392 /* 5393 * Transfer new include list. 5394 */ 5395 for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; 5396 inc = ISC_LIST_HEAD(zone->newincludes)) 5397 { 5398 ISC_LIST_UNLINK(zone->newincludes, inc, link); 5399 ISC_LIST_APPEND(zone->includes, inc, link); 5400 zone->nincludes++; 5401 } 5402 5403 if (!dns_db_ispersistent(db)) { 5404 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO, 5405 "loaded serial %u%s", serial, 5406 dns_db_issecure(db) ? " (DNSSEC signed)" : ""); 5407 } 5408 5409 if (!had_db && zone->type == dns_zone_mirror) { 5410 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO, 5411 "mirror zone is now in use"); 5412 } 5413 5414 zone->loadtime = loadtime; 5415 goto done; 5416 5417cleanup: 5418 if (result != ISC_R_SUCCESS) { 5419 dns_zone_rpz_disable_db(zone, db); 5420 dns_zone_catz_disable_db(zone, db); 5421 } 5422 5423 for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL; 5424 inc = ISC_LIST_HEAD(zone->newincludes)) 5425 { 5426 ISC_LIST_UNLINK(zone->newincludes, inc, link); 5427 isc_mem_free(zone->mctx, inc->name); 5428 isc_mem_put(zone->mctx, inc, sizeof(*inc)); 5429 } 5430 if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror || 5431 zone->type == dns_zone_stub || zone->type == dns_zone_key || 5432 (zone->type == dns_zone_redirect && zone->primaries != NULL)) 5433 { 5434 if (result != ISC_R_NOMEMORY) { 5435 if (zone->journal != NULL) { 5436 zone_saveunique(zone, zone->journal, 5437 "jn-XXXXXXXX"); 5438 } 5439 if (zone->masterfile != NULL) { 5440 zone_saveunique(zone, zone->masterfile, 5441 "db-XXXXXXXX"); 5442 } 5443 } 5444 5445 /* Mark the zone for immediate refresh. */ 5446 zone->refreshtime = now; 5447 if (zone->task != NULL) { 5448 zone_settimer(zone, &now); 5449 } 5450 result = ISC_R_SUCCESS; 5451 } else if (zone->type == dns_zone_primary || 5452 zone->type == dns_zone_redirect) 5453 { 5454 if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND)) { 5455 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 5456 ISC_LOG_ERROR, 5457 "not loaded due to errors."); 5458 } else if (zone->type == dns_zone_primary) { 5459 result = ISC_R_SUCCESS; 5460 } 5461 } 5462 5463done: 5464 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); 5465 /* 5466 * If this is an inline-signed zone and we were called for the raw 5467 * zone, we need to clear DNS_ZONEFLG_LOADPENDING for the secure zone 5468 * as well, but only if this is a reload, not an initial zone load: in 5469 * the former case, zone_postload() will not be run for the secure 5470 * zone; in the latter case, it will be. Check which case we are 5471 * dealing with by consulting the DNS_ZONEFLG_LOADED flag for the 5472 * secure zone: if it is set, this must be a reload. 5473 */ 5474 if (inline_raw(zone) && DNS_ZONE_FLAG(zone->secure, DNS_ZONEFLG_LOADED)) 5475 { 5476 DNS_ZONE_CLRFLAG(zone->secure, DNS_ZONEFLG_LOADPENDING); 5477 /* 5478 * Re-start zone maintenance if it had been stalled 5479 * due to DNS_ZONEFLG_LOADPENDING being set when 5480 * zone_maintenance was called. 5481 */ 5482 if (zone->secure->task != NULL) { 5483 zone_settimer(zone->secure, &now); 5484 } 5485 } 5486 5487 zone_debuglog(zone, "zone_postload", 99, "done"); 5488 5489 return (result); 5490} 5491 5492static bool 5493exit_check(dns_zone_t *zone) { 5494 REQUIRE(LOCKED_ZONE(zone)); 5495 5496 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && 5497 isc_refcount_current(&zone->irefs) == 0) 5498 { 5499 /* 5500 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0. 5501 */ 5502 INSIST(isc_refcount_current(&zone->erefs) == 0); 5503 return (true); 5504 } 5505 return (false); 5506} 5507 5508static bool 5509zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 5510 dns_name_t *name, bool logit) { 5511 isc_result_t result; 5512 char namebuf[DNS_NAME_FORMATSIZE]; 5513 char altbuf[DNS_NAME_FORMATSIZE]; 5514 dns_fixedname_t fixed; 5515 dns_name_t *foundname; 5516 int level; 5517 5518 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) { 5519 return (true); 5520 } 5521 5522 if (zone->type == dns_zone_primary) { 5523 level = ISC_LOG_ERROR; 5524 } else { 5525 level = ISC_LOG_WARNING; 5526 } 5527 5528 foundname = dns_fixedname_initname(&fixed); 5529 5530 result = dns_db_find(db, name, version, dns_rdatatype_a, 0, 0, NULL, 5531 foundname, NULL, NULL); 5532 if (result == ISC_R_SUCCESS) { 5533 return (true); 5534 } 5535 5536 if (result == DNS_R_NXRRSET) { 5537 result = dns_db_find(db, name, version, dns_rdatatype_aaaa, 0, 5538 0, NULL, foundname, NULL, NULL); 5539 if (result == ISC_R_SUCCESS) { 5540 return (true); 5541 } 5542 } 5543 5544 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 5545 result == DNS_R_EMPTYNAME) 5546 { 5547 if (logit) { 5548 dns_name_format(name, namebuf, sizeof namebuf); 5549 dns_zone_log(zone, level, 5550 "NS '%s' has no address " 5551 "records (A or AAAA)", 5552 namebuf); 5553 } 5554 return (false); 5555 } 5556 5557 if (result == DNS_R_CNAME) { 5558 if (logit) { 5559 dns_name_format(name, namebuf, sizeof namebuf); 5560 dns_zone_log(zone, level, 5561 "NS '%s' is a CNAME " 5562 "(illegal)", 5563 namebuf); 5564 } 5565 return (false); 5566 } 5567 5568 if (result == DNS_R_DNAME) { 5569 if (logit) { 5570 dns_name_format(name, namebuf, sizeof namebuf); 5571 dns_name_format(foundname, altbuf, sizeof altbuf); 5572 dns_zone_log(zone, level, 5573 "NS '%s' is below a DNAME " 5574 "'%s' (illegal)", 5575 namebuf, altbuf); 5576 } 5577 return (false); 5578 } 5579 5580 return (true); 5581} 5582 5583static isc_result_t 5584zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, 5585 dns_dbversion_t *version, unsigned int *nscount, 5586 unsigned int *errors, bool logit) { 5587 isc_result_t result; 5588 unsigned int count = 0; 5589 unsigned int ecount = 0; 5590 dns_rdataset_t rdataset; 5591 dns_rdata_t rdata; 5592 dns_rdata_ns_t ns; 5593 5594 dns_rdataset_init(&rdataset); 5595 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns, 5596 dns_rdatatype_none, 0, &rdataset, NULL); 5597 if (result == ISC_R_NOTFOUND) { 5598 INSIST(!dns_rdataset_isassociated(&rdataset)); 5599 goto success; 5600 } 5601 if (result != ISC_R_SUCCESS) { 5602 INSIST(!dns_rdataset_isassociated(&rdataset)); 5603 goto invalidate_rdataset; 5604 } 5605 5606 result = dns_rdataset_first(&rdataset); 5607 while (result == ISC_R_SUCCESS) { 5608 if (errors != NULL && zone->rdclass == dns_rdataclass_in && 5609 (zone->type == dns_zone_primary || 5610 zone->type == dns_zone_secondary || 5611 zone->type == dns_zone_mirror)) 5612 { 5613 dns_rdata_init(&rdata); 5614 dns_rdataset_current(&rdataset, &rdata); 5615 result = dns_rdata_tostruct(&rdata, &ns, NULL); 5616 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5617 if (dns_name_issubdomain(&ns.name, &zone->origin) && 5618 !zone_check_ns(zone, db, version, &ns.name, logit)) 5619 { 5620 ecount++; 5621 } 5622 } 5623 count++; 5624 result = dns_rdataset_next(&rdataset); 5625 } 5626 dns_rdataset_disassociate(&rdataset); 5627 5628success: 5629 if (nscount != NULL) { 5630 *nscount = count; 5631 } 5632 if (errors != NULL) { 5633 *errors = ecount; 5634 } 5635 5636 result = ISC_R_SUCCESS; 5637 5638invalidate_rdataset: 5639 dns_rdataset_invalidate(&rdataset); 5640 5641 return (result); 5642} 5643 5644#define SET_IF_NOT_NULL(obj, val) \ 5645 if (obj != NULL) { \ 5646 *obj = val; \ 5647 } 5648 5649#define SET_SOA_VALUES(soattl_v, serial_v, refresh_v, retry_v, expire_v, \ 5650 minimum_v) \ 5651 { \ 5652 SET_IF_NOT_NULL(soattl, soattl_v); \ 5653 SET_IF_NOT_NULL(serial, serial_v); \ 5654 SET_IF_NOT_NULL(refresh, refresh_v); \ 5655 SET_IF_NOT_NULL(retry, retry_v); \ 5656 SET_IF_NOT_NULL(expire, expire_v); \ 5657 SET_IF_NOT_NULL(minimum, minimum_v); \ 5658 } 5659 5660#define CLR_SOA_VALUES() \ 5661 { \ 5662 SET_SOA_VALUES(0, 0, 0, 0, 0, 0); \ 5663 } 5664 5665static isc_result_t 5666zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 5667 unsigned int *soacount, uint32_t *soattl, uint32_t *serial, 5668 uint32_t *refresh, uint32_t *retry, uint32_t *expire, 5669 uint32_t *minimum) { 5670 isc_result_t result; 5671 unsigned int count = 0; 5672 dns_rdataset_t rdataset; 5673 dns_rdata_t rdata = DNS_RDATA_INIT; 5674 5675 dns_rdataset_init(&rdataset); 5676 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, 5677 dns_rdatatype_none, 0, &rdataset, NULL); 5678 if (result == ISC_R_NOTFOUND) { 5679 INSIST(!dns_rdataset_isassociated(&rdataset)); 5680 result = ISC_R_SUCCESS; 5681 goto invalidate_rdataset; 5682 } 5683 if (result != ISC_R_SUCCESS) { 5684 INSIST(!dns_rdataset_isassociated(&rdataset)); 5685 goto invalidate_rdataset; 5686 } 5687 5688 result = dns_rdataset_first(&rdataset); 5689 while (result == ISC_R_SUCCESS) { 5690 dns_rdata_init(&rdata); 5691 dns_rdataset_current(&rdataset, &rdata); 5692 count++; 5693 if (count == 1) { 5694 dns_rdata_soa_t soa; 5695 result = dns_rdata_tostruct(&rdata, &soa, NULL); 5696 SET_SOA_VALUES(rdataset.ttl, soa.serial, soa.refresh, 5697 soa.retry, soa.expire, soa.minimum); 5698 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5699 } 5700 5701 result = dns_rdataset_next(&rdataset); 5702 dns_rdata_reset(&rdata); 5703 } 5704 dns_rdataset_disassociate(&rdataset); 5705 5706 result = ISC_R_SUCCESS; 5707 5708invalidate_rdataset: 5709 SET_IF_NOT_NULL(soacount, count); 5710 if (count == 0) { 5711 CLR_SOA_VALUES(); 5712 } 5713 5714 dns_rdataset_invalidate(&rdataset); 5715 5716 return (result); 5717} 5718 5719/* 5720 * zone must be locked. 5721 */ 5722static isc_result_t 5723zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 5724 unsigned int *soacount, uint32_t *soattl, uint32_t *serial, 5725 uint32_t *refresh, uint32_t *retry, uint32_t *expire, 5726 uint32_t *minimum, unsigned int *errors) { 5727 isc_result_t result; 5728 isc_result_t answer = ISC_R_SUCCESS; 5729 dns_dbversion_t *version = NULL; 5730 dns_dbnode_t *node; 5731 5732 REQUIRE(db != NULL); 5733 REQUIRE(zone != NULL); 5734 5735 dns_db_currentversion(db, &version); 5736 5737 SET_IF_NOT_NULL(nscount, 0); 5738 SET_IF_NOT_NULL(soacount, 0); 5739 SET_IF_NOT_NULL(errors, 0); 5740 CLR_SOA_VALUES(); 5741 5742 node = NULL; 5743 result = dns_db_findnode(db, &zone->origin, false, &node); 5744 if (result != ISC_R_SUCCESS) { 5745 answer = result; 5746 goto closeversion; 5747 } 5748 5749 if (nscount != NULL || errors != NULL) { 5750 result = zone_count_ns_rr(zone, db, node, version, nscount, 5751 errors, true); 5752 if (result != ISC_R_SUCCESS) { 5753 answer = result; 5754 } 5755 } 5756 5757 if (soacount != NULL || soattl != NULL || serial != NULL || 5758 refresh != NULL || retry != NULL || expire != NULL || 5759 minimum != NULL) 5760 { 5761 result = zone_load_soa_rr(db, node, version, soacount, soattl, 5762 serial, refresh, retry, expire, 5763 minimum); 5764 if (result != ISC_R_SUCCESS) { 5765 answer = result; 5766 } 5767 } 5768 5769 dns_db_detachnode(db, &node); 5770closeversion: 5771 dns_db_closeversion(db, &version, false); 5772 5773 return (answer); 5774} 5775 5776void 5777dns_zone_attach(dns_zone_t *source, dns_zone_t **target) { 5778 REQUIRE(DNS_ZONE_VALID(source)); 5779 REQUIRE(target != NULL && *target == NULL); 5780 isc_refcount_increment(&source->erefs); 5781 *target = source; 5782} 5783 5784void 5785dns_zone_detach(dns_zone_t **zonep) { 5786 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 5787 5788 dns_zone_t *zone = *zonep; 5789 *zonep = NULL; 5790 5791 if (isc_refcount_decrement(&zone->erefs) == 1) { 5792 isc_event_t *ev = &zone->ctlevent; 5793 5794 isc_refcount_destroy(&zone->erefs); 5795 5796 /* 5797 * Stop things being restarted after we cancel them below. 5798 */ 5799 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING); 5800 dns_zone_log(zone, ISC_LOG_DEBUG(1), 5801 "final reference detached"); 5802 if (zone->task != NULL) { 5803 /* 5804 * This zone has a task; it can clean 5805 * itself up asynchronously. 5806 */ 5807 isc_task_send(zone->task, &ev); 5808 return; 5809 } 5810 5811 /* 5812 * This zone is unmanaged; we're probably running in 5813 * named-checkzone or a unit test. There's no task, 5814 * so we need to free it immediately. 5815 * 5816 * Unmanaged zones must not have null views; we have no way 5817 * of detaching from the view here without causing deadlock 5818 * because this code is called with the view already 5819 * locked. 5820 */ 5821 INSIST(zone->view == NULL); 5822 5823 zone_shutdown(zone->task, ev); 5824 ev = NULL; 5825 } 5826} 5827 5828void 5829dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) { 5830 REQUIRE(DNS_ZONE_VALID(source)); 5831 5832 LOCK_ZONE(source); 5833 zone_iattach(source, target); 5834 UNLOCK_ZONE(source); 5835} 5836 5837static void 5838zone_iattach(dns_zone_t *source, dns_zone_t **target) { 5839 REQUIRE(DNS_ZONE_VALID(source)); 5840 REQUIRE(LOCKED_ZONE(source)); 5841 REQUIRE(target != NULL && *target == NULL); 5842 INSIST(isc_refcount_increment0(&source->irefs) + 5843 isc_refcount_current(&source->erefs) > 5844 0); 5845 *target = source; 5846} 5847 5848static void 5849zone_idetach(dns_zone_t **zonep) { 5850 dns_zone_t *zone; 5851 5852 /* 5853 * 'zone' locked by caller. 5854 */ 5855 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 5856 REQUIRE(LOCKED_ZONE(*zonep)); 5857 5858 zone = *zonep; 5859 *zonep = NULL; 5860 5861 INSIST(isc_refcount_decrement(&zone->irefs) - 1 + 5862 isc_refcount_current(&zone->erefs) > 5863 0); 5864} 5865 5866void 5867dns_zone_idetach(dns_zone_t **zonep) { 5868 dns_zone_t *zone; 5869 5870 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 5871 5872 zone = *zonep; 5873 *zonep = NULL; 5874 5875 if (isc_refcount_decrement(&zone->irefs) == 1) { 5876 bool free_needed; 5877 LOCK_ZONE(zone); 5878 free_needed = exit_check(zone); 5879 UNLOCK_ZONE(zone); 5880 if (free_needed) { 5881 zone_free(zone); 5882 } 5883 } 5884} 5885 5886isc_mem_t * 5887dns_zone_getmctx(dns_zone_t *zone) { 5888 REQUIRE(DNS_ZONE_VALID(zone)); 5889 5890 return (zone->mctx); 5891} 5892 5893dns_zonemgr_t * 5894dns_zone_getmgr(dns_zone_t *zone) { 5895 REQUIRE(DNS_ZONE_VALID(zone)); 5896 5897 return (zone->zmgr); 5898} 5899 5900void 5901dns_zone_setkasp(dns_zone_t *zone, dns_kasp_t *kasp) { 5902 REQUIRE(DNS_ZONE_VALID(zone)); 5903 5904 LOCK_ZONE(zone); 5905 if (zone->kasp != NULL) { 5906 dns_kasp_detach(&zone->kasp); 5907 } 5908 if (kasp != NULL) { 5909 dns_kasp_attach(kasp, &zone->kasp); 5910 } 5911 UNLOCK_ZONE(zone); 5912} 5913 5914dns_kasp_t * 5915dns_zone_getkasp(dns_zone_t *zone) { 5916 REQUIRE(DNS_ZONE_VALID(zone)); 5917 5918 return (zone->kasp); 5919} 5920 5921void 5922dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option, bool value) { 5923 REQUIRE(DNS_ZONE_VALID(zone)); 5924 5925 if (value) { 5926 DNS_ZONE_SETOPTION(zone, option); 5927 } else { 5928 DNS_ZONE_CLROPTION(zone, option); 5929 } 5930} 5931 5932dns_zoneopt_t 5933dns_zone_getoptions(dns_zone_t *zone) { 5934 REQUIRE(DNS_ZONE_VALID(zone)); 5935 5936 return (atomic_load_relaxed(&zone->options)); 5937} 5938 5939void 5940dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, bool value) { 5941 REQUIRE(DNS_ZONE_VALID(zone)); 5942 5943 if (value) { 5944 DNS_ZONEKEY_SETOPTION(zone, keyopt); 5945 } else { 5946 DNS_ZONEKEY_CLROPTION(zone, keyopt); 5947 } 5948} 5949 5950unsigned int 5951dns_zone_getkeyopts(dns_zone_t *zone) { 5952 REQUIRE(DNS_ZONE_VALID(zone)); 5953 5954 return (atomic_load_relaxed(&zone->keyopts)); 5955} 5956 5957isc_result_t 5958dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 5959 REQUIRE(DNS_ZONE_VALID(zone)); 5960 5961 LOCK_ZONE(zone); 5962 zone->xfrsource4 = *xfrsource; 5963 UNLOCK_ZONE(zone); 5964 5965 return (ISC_R_SUCCESS); 5966} 5967 5968isc_sockaddr_t * 5969dns_zone_getxfrsource4(dns_zone_t *zone) { 5970 REQUIRE(DNS_ZONE_VALID(zone)); 5971 return (&zone->xfrsource4); 5972} 5973 5974isc_result_t 5975dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 5976 REQUIRE(DNS_ZONE_VALID(zone)); 5977 5978 LOCK_ZONE(zone); 5979 zone->xfrsource6 = *xfrsource; 5980 UNLOCK_ZONE(zone); 5981 5982 return (ISC_R_SUCCESS); 5983} 5984 5985isc_sockaddr_t * 5986dns_zone_getxfrsource6(dns_zone_t *zone) { 5987 REQUIRE(DNS_ZONE_VALID(zone)); 5988 return (&zone->xfrsource6); 5989} 5990 5991isc_result_t 5992dns_zone_setaltxfrsource4(dns_zone_t *zone, 5993 const isc_sockaddr_t *altxfrsource) { 5994 REQUIRE(DNS_ZONE_VALID(zone)); 5995 5996 LOCK_ZONE(zone); 5997 zone->altxfrsource4 = *altxfrsource; 5998 UNLOCK_ZONE(zone); 5999 6000 return (ISC_R_SUCCESS); 6001} 6002 6003isc_sockaddr_t * 6004dns_zone_getaltxfrsource4(dns_zone_t *zone) { 6005 REQUIRE(DNS_ZONE_VALID(zone)); 6006 return (&zone->altxfrsource4); 6007} 6008 6009isc_result_t 6010dns_zone_setaltxfrsource6(dns_zone_t *zone, 6011 const isc_sockaddr_t *altxfrsource) { 6012 REQUIRE(DNS_ZONE_VALID(zone)); 6013 6014 LOCK_ZONE(zone); 6015 zone->altxfrsource6 = *altxfrsource; 6016 UNLOCK_ZONE(zone); 6017 6018 return (ISC_R_SUCCESS); 6019} 6020 6021isc_sockaddr_t * 6022dns_zone_getaltxfrsource6(dns_zone_t *zone) { 6023 REQUIRE(DNS_ZONE_VALID(zone)); 6024 return (&zone->altxfrsource6); 6025} 6026 6027isc_result_t 6028dns_zone_setparentalsrc4(dns_zone_t *zone, const isc_sockaddr_t *parentalsrc) { 6029 REQUIRE(DNS_ZONE_VALID(zone)); 6030 6031 LOCK_ZONE(zone); 6032 zone->parentalsrc4 = *parentalsrc; 6033 UNLOCK_ZONE(zone); 6034 6035 return (ISC_R_SUCCESS); 6036} 6037 6038isc_sockaddr_t * 6039dns_zone_getparentalsrc4(dns_zone_t *zone) { 6040 REQUIRE(DNS_ZONE_VALID(zone)); 6041 return (&zone->parentalsrc4); 6042} 6043 6044isc_result_t 6045dns_zone_setparentalsrc6(dns_zone_t *zone, const isc_sockaddr_t *parentalsrc) { 6046 REQUIRE(DNS_ZONE_VALID(zone)); 6047 6048 LOCK_ZONE(zone); 6049 zone->parentalsrc6 = *parentalsrc; 6050 UNLOCK_ZONE(zone); 6051 6052 return (ISC_R_SUCCESS); 6053} 6054 6055isc_sockaddr_t * 6056dns_zone_getparentalsrc6(dns_zone_t *zone) { 6057 REQUIRE(DNS_ZONE_VALID(zone)); 6058 return (&zone->parentalsrc6); 6059} 6060 6061isc_result_t 6062dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 6063 REQUIRE(DNS_ZONE_VALID(zone)); 6064 6065 LOCK_ZONE(zone); 6066 zone->notifysrc4 = *notifysrc; 6067 UNLOCK_ZONE(zone); 6068 6069 return (ISC_R_SUCCESS); 6070} 6071 6072isc_sockaddr_t * 6073dns_zone_getnotifysrc4(dns_zone_t *zone) { 6074 REQUIRE(DNS_ZONE_VALID(zone)); 6075 return (&zone->notifysrc4); 6076} 6077 6078isc_result_t 6079dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 6080 REQUIRE(DNS_ZONE_VALID(zone)); 6081 6082 LOCK_ZONE(zone); 6083 zone->notifysrc6 = *notifysrc; 6084 UNLOCK_ZONE(zone); 6085 6086 return (ISC_R_SUCCESS); 6087} 6088 6089isc_sockaddr_t * 6090dns_zone_getnotifysrc6(dns_zone_t *zone) { 6091 REQUIRE(DNS_ZONE_VALID(zone)); 6092 return (&zone->notifysrc6); 6093} 6094 6095static bool 6096same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist, 6097 uint32_t count) { 6098 unsigned int i; 6099 6100 for (i = 0; i < count; i++) { 6101 if (!isc_sockaddr_equal(&oldlist[i], &newlist[i])) { 6102 return (false); 6103 } 6104 } 6105 return (true); 6106} 6107 6108static bool 6109same_names(dns_name_t *const *oldlist, dns_name_t *const *newlist, 6110 uint32_t count) { 6111 unsigned int i; 6112 6113 if (oldlist == NULL && newlist == NULL) { 6114 return (true); 6115 } 6116 if (oldlist == NULL || newlist == NULL) { 6117 return (false); 6118 } 6119 6120 for (i = 0; i < count; i++) { 6121 if (oldlist[i] == NULL && newlist[i] == NULL) { 6122 continue; 6123 } 6124 if (oldlist[i] == NULL || newlist[i] == NULL || 6125 !dns_name_equal(oldlist[i], newlist[i])) 6126 { 6127 return (false); 6128 } 6129 } 6130 return (true); 6131} 6132 6133static void 6134clear_serverslist(isc_sockaddr_t **addrsp, dns_name_t ***keynamesp, 6135 dns_name_t ***tlsnamesp, unsigned int *countp, 6136 isc_mem_t *mctx) { 6137 unsigned int count; 6138 isc_sockaddr_t *addrs; 6139 dns_name_t **keynames; 6140 dns_name_t **tlsnames; 6141 6142 REQUIRE(countp != NULL); 6143 REQUIRE(addrsp != NULL); 6144 REQUIRE(keynamesp != NULL); 6145 REQUIRE(tlsnamesp != NULL); 6146 6147 count = *countp; 6148 *countp = 0; 6149 addrs = *addrsp; 6150 *addrsp = NULL; 6151 keynames = *keynamesp; 6152 *keynamesp = NULL; 6153 tlsnames = *tlsnamesp; 6154 *tlsnamesp = NULL; 6155 6156 if (addrs != NULL) { 6157 isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t)); 6158 } 6159 6160 if (keynames != NULL) { 6161 unsigned int i; 6162 for (i = 0; i < count; i++) { 6163 if (keynames[i] != NULL) { 6164 dns_name_free(keynames[i], mctx); 6165 isc_mem_put(mctx, keynames[i], 6166 sizeof(dns_name_t)); 6167 keynames[i] = NULL; 6168 } 6169 } 6170 isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *)); 6171 } 6172 6173 if (tlsnames != NULL) { 6174 unsigned int i; 6175 for (i = 0; i < count; i++) { 6176 if (tlsnames[i] != NULL) { 6177 dns_name_free(tlsnames[i], mctx); 6178 isc_mem_put(mctx, tlsnames[i], 6179 sizeof(dns_name_t)); 6180 tlsnames[i] = NULL; 6181 } 6182 } 6183 isc_mem_put(mctx, tlsnames, count * sizeof(dns_name_t *)); 6184 } 6185} 6186 6187static void 6188set_serverslist(unsigned int count, const isc_sockaddr_t *addrs, 6189 isc_sockaddr_t **newaddrsp, dns_name_t **keynames, 6190 dns_name_t ***newkeynamesp, dns_name_t **tlsnames, 6191 dns_name_t ***newtlsnamesp, isc_mem_t *mctx) { 6192 isc_sockaddr_t *newaddrs = NULL; 6193 dns_name_t **newkeynames = NULL; 6194 dns_name_t **newtlsnames = NULL; 6195 unsigned int i; 6196 6197 REQUIRE(newaddrsp != NULL && *newaddrsp == NULL); 6198 REQUIRE(newkeynamesp != NULL && *newkeynamesp == NULL); 6199 REQUIRE(newtlsnamesp != NULL && *newtlsnamesp == NULL); 6200 6201 newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs)); 6202 memmove(newaddrs, addrs, count * sizeof(*newaddrs)); 6203 6204 if (keynames != NULL) { 6205 newkeynames = isc_mem_get(mctx, count * sizeof(*newkeynames)); 6206 for (i = 0; i < count; i++) { 6207 newkeynames[i] = NULL; 6208 } 6209 for (i = 0; i < count; i++) { 6210 if (keynames[i] != NULL) { 6211 newkeynames[i] = 6212 isc_mem_get(mctx, sizeof(dns_name_t)); 6213 dns_name_init(newkeynames[i], NULL); 6214 dns_name_dup(keynames[i], mctx, newkeynames[i]); 6215 } 6216 } 6217 } 6218 6219 if (tlsnames != NULL) { 6220 newtlsnames = isc_mem_get(mctx, count * sizeof(*newtlsnames)); 6221 for (i = 0; i < count; i++) { 6222 newtlsnames[i] = NULL; 6223 } 6224 for (i = 0; i < count; i++) { 6225 if (tlsnames[i] != NULL) { 6226 newtlsnames[i] = 6227 isc_mem_get(mctx, sizeof(dns_name_t)); 6228 dns_name_init(newtlsnames[i], NULL); 6229 dns_name_dup(tlsnames[i], mctx, newtlsnames[i]); 6230 } 6231 } 6232 } 6233 6234 *newaddrsp = newaddrs; 6235 *newkeynamesp = newkeynames; 6236 *newtlsnamesp = newtlsnames; 6237} 6238 6239void 6240dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, 6241 dns_name_t **keynames, dns_name_t **tlsnames, 6242 uint32_t count) { 6243 isc_sockaddr_t *newaddrs = NULL; 6244 dns_name_t **newkeynames = NULL; 6245 dns_name_t **newtlsnames = NULL; 6246 6247 REQUIRE(DNS_ZONE_VALID(zone)); 6248 REQUIRE(count == 0 || notify != NULL); 6249 if (keynames != NULL) { 6250 REQUIRE(count != 0); 6251 } 6252 6253 LOCK_ZONE(zone); 6254 6255 if (count == zone->notifycnt && 6256 same_addrs(zone->notify, notify, count) && 6257 same_names(zone->notifykeynames, keynames, count) && 6258 same_names(zone->notifytlsnames, tlsnames, count)) 6259 { 6260 goto unlock; 6261 } 6262 6263 clear_serverslist(&zone->notify, &zone->notifykeynames, 6264 &zone->notifytlsnames, &zone->notifycnt, zone->mctx); 6265 6266 if (count == 0) { 6267 goto unlock; 6268 } 6269 6270 /* 6271 * Set up the notify and notifykey lists 6272 */ 6273 set_serverslist(count, notify, &newaddrs, keynames, &newkeynames, 6274 tlsnames, &newtlsnames, zone->mctx); 6275 6276 /* 6277 * Everything is ok so attach to the zone. 6278 */ 6279 zone->notify = newaddrs; 6280 zone->notifykeynames = newkeynames; 6281 zone->notifytlsnames = newtlsnames; 6282 zone->notifycnt = count; 6283unlock: 6284 UNLOCK_ZONE(zone); 6285} 6286 6287void 6288dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *primaries, 6289 dns_name_t **keynames, dns_name_t **tlsnames, 6290 uint32_t count) { 6291 isc_sockaddr_t *newaddrs = NULL; 6292 dns_name_t **newkeynames = NULL; 6293 dns_name_t **newtlsnames = NULL; 6294 bool *newok; 6295 unsigned int i; 6296 6297 REQUIRE(DNS_ZONE_VALID(zone)); 6298 REQUIRE(count == 0 || primaries != NULL); 6299 if (keynames != NULL || tlsnames != NULL) { 6300 REQUIRE(count != 0); 6301 } 6302 6303 LOCK_ZONE(zone); 6304 /* 6305 * The refresh code assumes that 'primaries' wouldn't change under it. 6306 * If it will change then kill off any current refresh in progress 6307 * and update the primaries info. If it won't change then we can just 6308 * unlock and exit. 6309 */ 6310 if (count != zone->primariescnt || 6311 !same_addrs(zone->primaries, primaries, count) || 6312 !same_names(zone->primarykeynames, keynames, count) || 6313 !same_names(zone->primarytlsnames, tlsnames, count)) 6314 { 6315 if (zone->request != NULL) { 6316 dns_request_cancel(zone->request); 6317 } 6318 } else { 6319 goto unlock; 6320 } 6321 6322 /* 6323 * This needs to happen before clear_addresskeylist() sets 6324 * zone->primariescnt to 0: 6325 */ 6326 if (zone->primariesok != NULL) { 6327 isc_mem_put(zone->mctx, zone->primariesok, 6328 zone->primariescnt * sizeof(bool)); 6329 zone->primariesok = NULL; 6330 } 6331 clear_serverslist(&zone->primaries, &zone->primarykeynames, 6332 &zone->primarytlsnames, &zone->primariescnt, 6333 zone->mctx); 6334 /* 6335 * If count == 0, don't allocate any space for primaries, primariesok or 6336 * keynames so internally, those pointers are NULL if count == 0 6337 */ 6338 if (count == 0) { 6339 goto unlock; 6340 } 6341 6342 /* 6343 * primariesok must contain count elements 6344 */ 6345 newok = isc_mem_get(zone->mctx, count * sizeof(*newok)); 6346 for (i = 0; i < count; i++) { 6347 newok[i] = false; 6348 } 6349 6350 /* 6351 * Now set up the primaries and primary key lists 6352 */ 6353 set_serverslist(count, primaries, &newaddrs, keynames, &newkeynames, 6354 tlsnames, &newtlsnames, zone->mctx); 6355 6356 /* 6357 * Everything is ok so attach to the zone. 6358 */ 6359 zone->curprimary = 0; 6360 zone->primariesok = newok; 6361 zone->primaries = newaddrs; 6362 zone->primarykeynames = newkeynames; 6363 zone->primarytlsnames = newtlsnames; 6364 zone->primariescnt = count; 6365 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOPRIMARIES); 6366 6367unlock: 6368 UNLOCK_ZONE(zone); 6369} 6370 6371void 6372dns_zone_setparentals(dns_zone_t *zone, const isc_sockaddr_t *parentals, 6373 dns_name_t **keynames, dns_name_t **tlsnames, 6374 uint32_t count) { 6375 isc_sockaddr_t *newaddrs = NULL; 6376 dns_name_t **newkeynames = NULL; 6377 dns_name_t **newtlsnames = NULL; 6378 6379 REQUIRE(DNS_ZONE_VALID(zone)); 6380 REQUIRE(count == 0 || parentals != NULL); 6381 if (keynames != NULL || tlsnames != NULL) { 6382 REQUIRE(count != 0); 6383 } 6384 6385 LOCK_ZONE(zone); 6386 6387 clear_serverslist(&zone->parentals, &zone->parentalkeynames, 6388 &zone->parentaltlsnames, &zone->parentalscnt, 6389 zone->mctx); 6390 /* 6391 * If count == 0, don't allocate any space for parentals, or keynames 6392 * so internally, those pointers are NULL if count == 0 6393 */ 6394 if (count == 0) { 6395 goto unlock; 6396 } 6397 6398 /* 6399 * Now set up the parentals and parental key lists 6400 */ 6401 set_serverslist(count, parentals, &newaddrs, keynames, &newkeynames, 6402 tlsnames, &newtlsnames, zone->mctx); 6403 6404 /* 6405 * Everything is ok so attach to the zone. 6406 */ 6407 zone->parentals = newaddrs; 6408 zone->parentalkeynames = newkeynames; 6409 zone->parentaltlsnames = newtlsnames; 6410 zone->parentalscnt = count; 6411 6412 dns_zone_log(zone, ISC_LOG_NOTICE, "checkds: set %u parentals", count); 6413 6414unlock: 6415 UNLOCK_ZONE(zone); 6416} 6417 6418isc_result_t 6419dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) { 6420 isc_result_t result = ISC_R_SUCCESS; 6421 6422 REQUIRE(DNS_ZONE_VALID(zone)); 6423 6424 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 6425 if (zone->db == NULL) { 6426 result = DNS_R_NOTLOADED; 6427 } else { 6428 dns_db_attach(zone->db, dpb); 6429 } 6430 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 6431 6432 return (result); 6433} 6434 6435void 6436dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) { 6437 REQUIRE(DNS_ZONE_VALID(zone)); 6438 REQUIRE(zone->type == dns_zone_staticstub); 6439 6440 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 6441 REQUIRE(zone->db == NULL); 6442 dns_db_attach(db, &zone->db); 6443 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 6444} 6445 6446/* 6447 * Coordinates the starting of routine jobs. 6448 */ 6449void 6450dns_zone_maintenance(dns_zone_t *zone) { 6451 const char me[] = "dns_zone_maintenance"; 6452 isc_time_t now; 6453 6454 REQUIRE(DNS_ZONE_VALID(zone)); 6455 ENTER; 6456 6457 LOCK_ZONE(zone); 6458 TIME_NOW(&now); 6459 zone_settimer(zone, &now); 6460 UNLOCK_ZONE(zone); 6461} 6462 6463static bool 6464was_dumping(dns_zone_t *zone) { 6465 REQUIRE(LOCKED_ZONE(zone)); 6466 6467 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 6468 return (true); 6469 } 6470 6471 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 6472 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 6473 isc_time_settoepoch(&zone->dumptime); 6474 return (false); 6475} 6476 6477/*% 6478 * Find up to 'maxkeys' DNSSEC keys used for signing version 'ver' of database 6479 * 'db' for zone 'zone' in its key directory, then load these keys into 'keys'. 6480 * Only load the public part of a given key if it is not active at timestamp 6481 * 'now'. Store the number of keys found in 'nkeys'. 6482 */ 6483isc_result_t 6484dns__zone_findkeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 6485 isc_stdtime_t now, isc_mem_t *mctx, unsigned int maxkeys, 6486 dst_key_t **keys, unsigned int *nkeys) { 6487 isc_result_t result; 6488 dns_dbnode_t *node = NULL; 6489 const char *directory = dns_zone_getkeydirectory(zone); 6490 6491 CHECK(dns_db_findnode(db, dns_db_origin(db), false, &node)); 6492 memset(keys, 0, sizeof(*keys) * maxkeys); 6493 6494 dns_zone_lock_keyfiles(zone); 6495 6496 result = dns_dnssec_findzonekeys(db, ver, node, dns_db_origin(db), 6497 directory, now, mctx, maxkeys, keys, 6498 nkeys); 6499 6500 dns_zone_unlock_keyfiles(zone); 6501 6502 if (result == ISC_R_NOTFOUND) { 6503 result = ISC_R_SUCCESS; 6504 } 6505 6506failure: 6507 6508 if (node != NULL) { 6509 dns_db_detachnode(db, &node); 6510 } 6511 return (result); 6512} 6513 6514/*% 6515 * Find DNSSEC keys used for signing zone with dnssec-policy. Load these keys 6516 * into 'keys'. Requires KASP to be locked. 6517 */ 6518isc_result_t 6519dns_zone_getdnsseckeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 6520 isc_stdtime_t now, dns_dnsseckeylist_t *keys) { 6521 isc_result_t result; 6522 const char *dir = dns_zone_getkeydirectory(zone); 6523 dns_dbnode_t *node = NULL; 6524 dns_dnsseckey_t *key, *key_next; 6525 dns_dnsseckeylist_t dnskeys; 6526 dns_name_t *origin = dns_zone_getorigin(zone); 6527 dns_kasp_t *kasp = dns_zone_getkasp(zone); 6528 dns_rdataset_t keyset; 6529 6530 REQUIRE(DNS_ZONE_VALID(zone)); 6531 REQUIRE(kasp != NULL); 6532 6533 ISC_LIST_INIT(dnskeys); 6534 6535 dns_rdataset_init(&keyset); 6536 6537 CHECK(dns_db_findnode(db, origin, false, &node)); 6538 6539 /* Get keys from private key files. */ 6540 dns_zone_lock_keyfiles(zone); 6541 result = dns_dnssec_findmatchingkeys(origin, dir, now, 6542 dns_zone_getmctx(zone), keys); 6543 dns_zone_unlock_keyfiles(zone); 6544 6545 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 6546 goto failure; 6547 } 6548 6549 /* Get public keys (dnskeys). */ 6550 dns_rdataset_init(&keyset); 6551 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 6552 dns_rdatatype_none, 0, &keyset, NULL); 6553 if (result == ISC_R_SUCCESS) { 6554 CHECK(dns_dnssec_keylistfromrdataset( 6555 origin, dir, dns_zone_getmctx(zone), &keyset, NULL, 6556 NULL, false, false, &dnskeys)); 6557 } else if (result != ISC_R_NOTFOUND) { 6558 CHECK(result); 6559 } 6560 6561 /* Add new 'dnskeys' to 'keys'. */ 6562 for (dns_dnsseckey_t *k1 = ISC_LIST_HEAD(dnskeys); k1 != NULL; 6563 k1 = key_next) 6564 { 6565 dns_dnsseckey_t *k2 = NULL; 6566 key_next = ISC_LIST_NEXT(k1, link); 6567 6568 for (k2 = ISC_LIST_HEAD(*keys); k2 != NULL; 6569 k2 = ISC_LIST_NEXT(k2, link)) 6570 { 6571 if (dst_key_compare(k1->key, k2->key)) { 6572 break; 6573 } 6574 } 6575 /* No match found, add the new key. */ 6576 if (k2 == NULL) { 6577 ISC_LIST_UNLINK(dnskeys, k1, link); 6578 ISC_LIST_APPEND(*keys, k1, link); 6579 } 6580 } 6581 6582failure: 6583 if (dns_rdataset_isassociated(&keyset)) { 6584 dns_rdataset_disassociate(&keyset); 6585 } 6586 if (node != NULL) { 6587 dns_db_detachnode(db, &node); 6588 } 6589 while (!ISC_LIST_EMPTY(dnskeys)) { 6590 key = ISC_LIST_HEAD(dnskeys); 6591 ISC_LIST_UNLINK(dnskeys, key, link); 6592 dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key); 6593 } 6594 return (result); 6595} 6596 6597static isc_result_t 6598offline(dns_db_t *db, dns_dbversion_t *ver, dns__zonediff_t *zonediff, 6599 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { 6600 isc_result_t result; 6601 6602 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) { 6603 return (ISC_R_SUCCESS); 6604 } 6605 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, 6606 name, ttl, rdata); 6607 if (result != ISC_R_SUCCESS) { 6608 return (result); 6609 } 6610 rdata->flags |= DNS_RDATA_OFFLINE; 6611 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN, 6612 name, ttl, rdata); 6613 zonediff->offline = true; 6614 return (result); 6615} 6616 6617static void 6618set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, 6619 isc_stdtime_t now) { 6620 unsigned int delta; 6621 char timebuf[80]; 6622 6623 LOCK_ZONE(zone); 6624 zone->key_expiry = when; 6625 if (when <= now) { 6626 dns_zone_log(zone, ISC_LOG_ERROR, 6627 "DNSKEY RRSIG(s) have expired"); 6628 isc_time_settoepoch(&zone->keywarntime); 6629 } else if (when < now + 7 * 24 * 3600) { 6630 isc_time_t t; 6631 isc_time_set(&t, when, 0); 6632 isc_time_formattimestamp(&t, timebuf, 80); 6633 dns_zone_log(zone, ISC_LOG_WARNING, 6634 "DNSKEY RRSIG(s) will expire within 7 days: %s", 6635 timebuf); 6636 delta = when - now; 6637 delta--; /* loop prevention */ 6638 delta /= 24 * 3600; /* to whole days */ 6639 delta *= 24 * 3600; /* to seconds */ 6640 isc_time_set(&zone->keywarntime, when - delta, 0); 6641 } else { 6642 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0); 6643 isc_time_formattimestamp(&zone->keywarntime, timebuf, 80); 6644 dns_zone_log(zone, ISC_LOG_NOTICE, "setting keywarntime to %s", 6645 timebuf); 6646 } 6647 UNLOCK_ZONE(zone); 6648} 6649 6650/* 6651 * Helper function to del_sigs(). We don't want to delete RRSIGs that 6652 * have no new key. 6653 */ 6654static bool 6655delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys, 6656 bool kasp, bool *warn) { 6657 unsigned int i = 0; 6658 isc_result_t ret; 6659 bool have_ksk = false, have_zsk = false; 6660 bool have_pksk = false, have_pzsk = false; 6661 6662 for (i = 0; i < nkeys; i++) { 6663 bool ksk, zsk; 6664 6665 if (have_pksk && have_ksk && have_pzsk && have_zsk) { 6666 break; 6667 } 6668 6669 if (rrsig_ptr->algorithm != dst_key_alg(keys[i])) { 6670 continue; 6671 } 6672 6673 ret = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk); 6674 if (ret != ISC_R_SUCCESS) { 6675 ksk = KSK(keys[i]); 6676 } 6677 ret = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk); 6678 if (ret != ISC_R_SUCCESS) { 6679 zsk = !KSK(keys[i]); 6680 } 6681 6682 if (ksk) { 6683 have_ksk = true; 6684 if (dst_key_isprivate(keys[i])) { 6685 have_pksk = true; 6686 } 6687 } 6688 if (zsk) { 6689 have_zsk = true; 6690 if (dst_key_isprivate(keys[i])) { 6691 have_pzsk = true; 6692 } 6693 } 6694 } 6695 6696 if (have_zsk && have_ksk && !have_pzsk) { 6697 *warn = true; 6698 } 6699 6700 if (have_pksk && have_pzsk) { 6701 return (true); 6702 } 6703 6704 /* 6705 * Deleting the SOA RRSIG is always okay. 6706 */ 6707 if (rrsig_ptr->covered == dns_rdatatype_soa) { 6708 return (true); 6709 } 6710 6711 /* 6712 * It's okay to delete a signature if there is an active key with the 6713 * same algorithm to replace it, unless that violates the DNSSEC 6714 * policy. 6715 */ 6716 if (have_pksk || have_pzsk) { 6717 if (kasp && have_pzsk) { 6718 return (true); 6719 } 6720 return (!kasp); 6721 } 6722 6723 /* 6724 * Failing that, it is *not* okay to delete a signature 6725 * if the associated public key is still in the DNSKEY RRset 6726 */ 6727 for (i = 0; i < nkeys; i++) { 6728 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) && 6729 (rrsig_ptr->keyid == dst_key_id(keys[i]))) 6730 { 6731 return (false); 6732 } 6733 } 6734 6735 /* 6736 * But if the key is gone, then go ahead. 6737 */ 6738 return (true); 6739} 6740 6741/* 6742 * Delete expired RRsigs and any RRsigs we are about to re-sign. 6743 * See also update.c:del_keysigs(). 6744 */ 6745static isc_result_t 6746del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 6747 dns_rdatatype_t type, dns__zonediff_t *zonediff, dst_key_t **keys, 6748 unsigned int nkeys, isc_stdtime_t now, bool incremental) { 6749 isc_result_t result; 6750 dns_dbnode_t *node = NULL; 6751 dns_rdataset_t rdataset; 6752 unsigned int i; 6753 dns_rdata_rrsig_t rrsig; 6754 bool kasp = (dns_zone_getkasp(zone) != NULL); 6755 bool found; 6756 int64_t timewarn = 0, timemaybe = 0; 6757 6758 dns_rdataset_init(&rdataset); 6759 6760 if (type == dns_rdatatype_nsec3) { 6761 result = dns_db_findnsec3node(db, name, false, &node); 6762 } else { 6763 result = dns_db_findnode(db, name, false, &node); 6764 } 6765 if (result == ISC_R_NOTFOUND) { 6766 return (ISC_R_SUCCESS); 6767 } 6768 if (result != ISC_R_SUCCESS) { 6769 goto failure; 6770 } 6771 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type, 6772 (isc_stdtime_t)0, &rdataset, NULL); 6773 dns_db_detachnode(db, &node); 6774 6775 if (result == ISC_R_NOTFOUND) { 6776 INSIST(!dns_rdataset_isassociated(&rdataset)); 6777 return (ISC_R_SUCCESS); 6778 } 6779 if (result != ISC_R_SUCCESS) { 6780 INSIST(!dns_rdataset_isassociated(&rdataset)); 6781 goto failure; 6782 } 6783 6784 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 6785 result = dns_rdataset_next(&rdataset)) 6786 { 6787 dns_rdata_t rdata = DNS_RDATA_INIT; 6788 6789 dns_rdataset_current(&rdataset, &rdata); 6790 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 6791 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6792 6793 if (type != dns_rdatatype_dnskey && type != dns_rdatatype_cds && 6794 type != dns_rdatatype_cdnskey) 6795 { 6796 bool warn = false, deleted = false; 6797 if (delsig_ok(&rrsig, keys, nkeys, kasp, &warn)) { 6798 result = update_one_rr(db, ver, zonediff->diff, 6799 DNS_DIFFOP_DELRESIGN, 6800 name, rdataset.ttl, 6801 &rdata); 6802 if (result != ISC_R_SUCCESS) { 6803 break; 6804 } 6805 deleted = true; 6806 } 6807 if (warn && !deleted) { 6808 /* 6809 * At this point, we've got an RRSIG, 6810 * which is signed by an inactive key. 6811 * An administrator needs to provide a new 6812 * key/alg, but until that time, we want to 6813 * keep the old RRSIG. Marking the key as 6814 * offline will prevent us spinning waiting 6815 * for the private part. 6816 */ 6817 if (incremental) { 6818 result = offline(db, ver, zonediff, 6819 name, rdataset.ttl, 6820 &rdata); 6821 if (result != ISC_R_SUCCESS) { 6822 break; 6823 } 6824 } 6825 6826 /* 6827 * Log the key id and algorithm of 6828 * the inactive key with no replacement 6829 */ 6830 if (zone->log_key_expired_timer <= now) { 6831 char origin[DNS_NAME_FORMATSIZE]; 6832 char algbuf[DNS_NAME_FORMATSIZE]; 6833 dns_name_format(&zone->origin, origin, 6834 sizeof(origin)); 6835 dns_secalg_format(rrsig.algorithm, 6836 algbuf, 6837 sizeof(algbuf)); 6838 dns_zone_log(zone, ISC_LOG_WARNING, 6839 "Key %s/%s/%d " 6840 "missing or inactive " 6841 "and has no replacement: " 6842 "retaining signatures.", 6843 origin, algbuf, 6844 rrsig.keyid); 6845 zone->log_key_expired_timer = now + 6846 3600; 6847 } 6848 } 6849 continue; 6850 } 6851 6852 /* 6853 * KSK RRSIGs requires special processing. 6854 */ 6855 found = false; 6856 for (i = 0; i < nkeys; i++) { 6857 if (rrsig.algorithm == dst_key_alg(keys[i]) && 6858 rrsig.keyid == dst_key_id(keys[i])) 6859 { 6860 found = true; 6861 /* 6862 * Mark offline DNSKEY. 6863 * We want the earliest offline expire time 6864 * iff there is a new offline signature. 6865 */ 6866 if (!dst_key_inactive(keys[i]) && 6867 !dst_key_isprivate(keys[i])) 6868 { 6869 int64_t timeexpire = dns_time64_from32( 6870 rrsig.timeexpire); 6871 if (timewarn != 0 && 6872 timewarn > timeexpire) 6873 { 6874 timewarn = timeexpire; 6875 } 6876 if (rdata.flags & DNS_RDATA_OFFLINE) { 6877 if (timemaybe == 0 || 6878 timemaybe > timeexpire) 6879 { 6880 timemaybe = timeexpire; 6881 } 6882 break; 6883 } 6884 if (timewarn == 0) { 6885 timewarn = timemaybe; 6886 } 6887 if (timewarn == 0 || 6888 timewarn > timeexpire) 6889 { 6890 timewarn = timeexpire; 6891 } 6892 result = offline(db, ver, zonediff, 6893 name, rdataset.ttl, 6894 &rdata); 6895 break; 6896 } 6897 result = update_one_rr(db, ver, zonediff->diff, 6898 DNS_DIFFOP_DELRESIGN, 6899 name, rdataset.ttl, 6900 &rdata); 6901 break; 6902 } 6903 } 6904 6905 /* 6906 * If there is not a matching DNSKEY then 6907 * delete the RRSIG. 6908 */ 6909 if (!found) { 6910 result = update_one_rr(db, ver, zonediff->diff, 6911 DNS_DIFFOP_DELRESIGN, name, 6912 rdataset.ttl, &rdata); 6913 } 6914 if (result != ISC_R_SUCCESS) { 6915 break; 6916 } 6917 } 6918 6919 dns_rdataset_disassociate(&rdataset); 6920 if (result == ISC_R_NOMORE) { 6921 result = ISC_R_SUCCESS; 6922 } 6923 if (timewarn > 0) { 6924 isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn; 6925 if (timewarn == stdwarn) { 6926 set_key_expiry_warning(zone, (isc_stdtime_t)timewarn, 6927 now); 6928 } else { 6929 dns_zone_log(zone, ISC_LOG_ERROR, 6930 "key expiry warning time out of range"); 6931 } 6932 } 6933failure: 6934 if (node != NULL) { 6935 dns_db_detachnode(db, &node); 6936 } 6937 return (result); 6938} 6939 6940static isc_result_t 6941add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_zone_t *zone, 6942 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, 6943 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t now, 6944 isc_stdtime_t inception, isc_stdtime_t expire, bool check_ksk, 6945 bool keyset_kskonly) { 6946 isc_result_t result; 6947 dns_dbnode_t *node = NULL; 6948 dns_stats_t *dnssecsignstats; 6949 dns_rdataset_t rdataset; 6950 dns_rdata_t sig_rdata = DNS_RDATA_INIT; 6951 unsigned char data[1024]; /* XXX */ 6952 isc_buffer_t buffer; 6953 unsigned int i, j; 6954 bool use_kasp = false; 6955 6956 if (dns_zone_getkasp(zone) != NULL) { 6957 check_ksk = false; 6958 keyset_kskonly = true; 6959 use_kasp = true; 6960 } 6961 6962 dns_rdataset_init(&rdataset); 6963 isc_buffer_init(&buffer, data, sizeof(data)); 6964 6965 if (type == dns_rdatatype_nsec3) { 6966 result = dns_db_findnsec3node(db, name, false, &node); 6967 } else { 6968 result = dns_db_findnode(db, name, false, &node); 6969 } 6970 if (result == ISC_R_NOTFOUND) { 6971 return (ISC_R_SUCCESS); 6972 } 6973 if (result != ISC_R_SUCCESS) { 6974 goto failure; 6975 } 6976 result = dns_db_findrdataset(db, node, ver, type, 0, (isc_stdtime_t)0, 6977 &rdataset, NULL); 6978 dns_db_detachnode(db, &node); 6979 if (result == ISC_R_NOTFOUND) { 6980 INSIST(!dns_rdataset_isassociated(&rdataset)); 6981 return (ISC_R_SUCCESS); 6982 } 6983 if (result != ISC_R_SUCCESS) { 6984 INSIST(!dns_rdataset_isassociated(&rdataset)); 6985 goto failure; 6986 } 6987 6988 for (i = 0; i < nkeys; i++) { 6989 bool both = false; 6990 6991 /* Don't add signatures for offline or inactive keys */ 6992 if (!dst_key_isprivate(keys[i])) { 6993 continue; 6994 } 6995 if (dst_key_inactive(keys[i])) { 6996 continue; 6997 } 6998 6999 if (check_ksk && !REVOKE(keys[i])) { 7000 bool have_ksk, have_nonksk; 7001 if (KSK(keys[i])) { 7002 have_ksk = true; 7003 have_nonksk = false; 7004 } else { 7005 have_ksk = false; 7006 have_nonksk = true; 7007 } 7008 7009 for (j = 0; j < nkeys; j++) { 7010 if (j == i || ALG(keys[i]) != ALG(keys[j])) { 7011 continue; 7012 } 7013 7014 /* 7015 * Don't consider inactive keys, however 7016 * the KSK may be temporary offline, so do 7017 * consider keys which private key files are 7018 * unavailable. 7019 */ 7020 if (dst_key_inactive(keys[j])) { 7021 continue; 7022 } 7023 7024 if (REVOKE(keys[j])) { 7025 continue; 7026 } 7027 if (KSK(keys[j])) { 7028 have_ksk = true; 7029 } else if (dst_key_isprivate(keys[j])) { 7030 have_nonksk = true; 7031 } 7032 both = have_ksk && have_nonksk; 7033 if (both) { 7034 break; 7035 } 7036 } 7037 } 7038 if (use_kasp) { 7039 /* 7040 * A dnssec-policy is found. Check what RRsets this 7041 * key should sign. 7042 */ 7043 isc_result_t kresult; 7044 isc_stdtime_t when; 7045 bool ksk = false; 7046 bool zsk = false; 7047 bool have_ksk = false; 7048 bool have_zsk = false; 7049 7050 kresult = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk); 7051 if (kresult != ISC_R_SUCCESS) { 7052 if (KSK(keys[i])) { 7053 ksk = true; 7054 } 7055 } 7056 kresult = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk); 7057 if (kresult != ISC_R_SUCCESS) { 7058 if (!KSK(keys[i])) { 7059 zsk = true; 7060 } 7061 } 7062 7063 have_ksk = ksk; 7064 have_zsk = zsk; 7065 both = have_ksk && have_zsk; 7066 7067 for (j = 0; j < nkeys; j++) { 7068 if (both) { 7069 break; 7070 } 7071 7072 if (j == i || ALG(keys[i]) != ALG(keys[j])) { 7073 continue; 7074 } 7075 7076 /* 7077 * Don't consider inactive keys or offline keys. 7078 */ 7079 if (!dst_key_isprivate(keys[j])) { 7080 continue; 7081 } 7082 if (dst_key_inactive(keys[j])) { 7083 continue; 7084 } 7085 7086 if (REVOKE(keys[j])) { 7087 continue; 7088 } 7089 7090 if (!have_ksk) { 7091 kresult = dst_key_getbool(keys[j], 7092 DST_BOOL_KSK, 7093 &have_ksk); 7094 if (kresult != ISC_R_SUCCESS) { 7095 if (KSK(keys[j])) { 7096 have_ksk = true; 7097 } 7098 } 7099 } 7100 if (!have_zsk) { 7101 kresult = dst_key_getbool(keys[j], 7102 DST_BOOL_ZSK, 7103 &have_zsk); 7104 if (kresult != ISC_R_SUCCESS) { 7105 if (!KSK(keys[j])) { 7106 have_zsk = true; 7107 } 7108 } 7109 } 7110 both = have_ksk && have_zsk; 7111 } 7112 7113 if (type == dns_rdatatype_dnskey || 7114 type == dns_rdatatype_cdnskey || 7115 type == dns_rdatatype_cds) 7116 { 7117 /* 7118 * DNSKEY RRset is signed with KSK. 7119 * CDS and CDNSKEY RRsets too (RFC 7344, 4.1). 7120 */ 7121 if (!ksk) { 7122 continue; 7123 } 7124 } else if (!zsk) { 7125 /* 7126 * Other RRsets are signed with ZSK. 7127 */ 7128 if (type != dns_rdatatype_soa && 7129 type != zone->privatetype) 7130 { 7131 continue; 7132 } 7133 if (have_zsk) { 7134 continue; 7135 } 7136 } else if (!dst_key_is_signing(keys[i], DST_BOOL_ZSK, 7137 now, &when)) 7138 { 7139 /* 7140 * This key is not active for zone-signing. 7141 */ 7142 continue; 7143 } 7144 7145 /* 7146 * If this key is revoked, it may only sign the 7147 * DNSKEY RRset. 7148 */ 7149 if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) { 7150 continue; 7151 } 7152 } else if (both) { 7153 /* 7154 * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1). 7155 */ 7156 if (type == dns_rdatatype_dnskey || 7157 type == dns_rdatatype_cdnskey || 7158 type == dns_rdatatype_cds) 7159 { 7160 if (!KSK(keys[i]) && keyset_kskonly) { 7161 continue; 7162 } 7163 } else if (KSK(keys[i])) { 7164 continue; 7165 } 7166 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) { 7167 continue; 7168 } 7169 7170 /* Calculate the signature, creating a RRSIG RDATA. */ 7171 isc_buffer_clear(&buffer); 7172 CHECK(dns_dnssec_sign(name, &rdataset, keys[i], &inception, 7173 &expire, mctx, &buffer, &sig_rdata)); 7174 7175 /* Update the database and journal with the RRSIG. */ 7176 /* XXX inefficient - will cause dataset merging */ 7177 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, name, 7178 rdataset.ttl, &sig_rdata)); 7179 dns_rdata_reset(&sig_rdata); 7180 isc_buffer_init(&buffer, data, sizeof(data)); 7181 7182 /* Update DNSSEC sign statistics. */ 7183 dnssecsignstats = dns_zone_getdnssecsignstats(zone); 7184 if (dnssecsignstats != NULL) { 7185 /* Generated a new signature. */ 7186 dns_dnssecsignstats_increment(dnssecsignstats, 7187 ID(keys[i]), 7188 (uint8_t)ALG(keys[i]), 7189 dns_dnssecsignstats_sign); 7190 /* This is a refresh. */ 7191 dns_dnssecsignstats_increment( 7192 dnssecsignstats, ID(keys[i]), 7193 (uint8_t)ALG(keys[i]), 7194 dns_dnssecsignstats_refresh); 7195 } 7196 } 7197 7198failure: 7199 if (dns_rdataset_isassociated(&rdataset)) { 7200 dns_rdataset_disassociate(&rdataset); 7201 } 7202 if (node != NULL) { 7203 dns_db_detachnode(db, &node); 7204 } 7205 return (result); 7206} 7207 7208static void 7209zone_resigninc(dns_zone_t *zone) { 7210 const char *me = "zone_resigninc"; 7211 dns_db_t *db = NULL; 7212 dns_dbversion_t *version = NULL; 7213 dns_diff_t _sig_diff; 7214 dns__zonediff_t zonediff; 7215 dns_fixedname_t fixed; 7216 dns_name_t *name; 7217 dns_rdataset_t rdataset; 7218 dns_rdatatype_t covers; 7219 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 7220 bool check_ksk, keyset_kskonly = false; 7221 isc_result_t result; 7222 isc_stdtime_t now, inception, soaexpire, expire, fullexpire, stop; 7223 uint32_t sigvalidityinterval, expiryinterval; 7224 unsigned int i; 7225 unsigned int nkeys = 0; 7226 unsigned int resign; 7227 7228 ENTER; 7229 7230 dns_rdataset_init(&rdataset); 7231 dns_diff_init(zone->mctx, &_sig_diff); 7232 zonediff_init(&zonediff, &_sig_diff); 7233 7234 /* 7235 * Zone is frozen or automatic resigning is disabled. 7236 * Pause for 5 minutes. 7237 */ 7238 if (zone->update_disabled || 7239 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN)) 7240 { 7241 result = ISC_R_FAILURE; 7242 goto failure; 7243 } 7244 7245 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 7246 if (zone->db != NULL) { 7247 dns_db_attach(zone->db, &db); 7248 } 7249 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 7250 if (db == NULL) { 7251 result = ISC_R_FAILURE; 7252 goto failure; 7253 } 7254 7255 result = dns_db_newversion(db, &version); 7256 if (result != ISC_R_SUCCESS) { 7257 dns_zone_log(zone, ISC_LOG_ERROR, 7258 "zone_resigninc:dns_db_newversion -> %s", 7259 isc_result_totext(result)); 7260 goto failure; 7261 } 7262 7263 isc_stdtime_get(&now); 7264 7265 result = dns__zone_findkeys(zone, db, version, now, zone->mctx, 7266 DNS_MAXZONEKEYS, zone_keys, &nkeys); 7267 if (result != ISC_R_SUCCESS) { 7268 dns_zone_log(zone, ISC_LOG_ERROR, 7269 "zone_resigninc:dns__zone_findkeys -> %s", 7270 isc_result_totext(result)); 7271 goto failure; 7272 } 7273 7274 sigvalidityinterval = dns_zone_getsigvalidityinterval(zone); 7275 inception = now - 3600; /* Allow for clock skew. */ 7276 soaexpire = now + sigvalidityinterval; 7277 expiryinterval = dns_zone_getsigresigninginterval(zone); 7278 if (expiryinterval > sigvalidityinterval) { 7279 expiryinterval = sigvalidityinterval; 7280 } else { 7281 expiryinterval = sigvalidityinterval - expiryinterval; 7282 } 7283 7284 /* 7285 * Spread out signatures over time if they happen to be 7286 * clumped. We don't do this for each add_sigs() call as 7287 * we still want some clustering to occur. In normal operations 7288 * the records should be re-signed as they fall due and they should 7289 * already be spread out. However if the server is off for a 7290 * period we need to ensure that the clusters don't become 7291 * synchronised by using the full jitter range. 7292 */ 7293 if (sigvalidityinterval >= 3600U) { 7294 uint32_t normaljitter, fulljitter; 7295 if (sigvalidityinterval > 7200U) { 7296 normaljitter = isc_random_uniform(3600); 7297 fulljitter = isc_random_uniform(expiryinterval); 7298 } else { 7299 normaljitter = fulljitter = isc_random_uniform(1200); 7300 } 7301 expire = soaexpire - normaljitter - 1; 7302 fullexpire = soaexpire - fulljitter - 1; 7303 } else { 7304 expire = fullexpire = soaexpire - 1; 7305 } 7306 stop = now + 5; 7307 7308 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 7309 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 7310 7311 name = dns_fixedname_initname(&fixed); 7312 result = dns_db_getsigningtime(db, &rdataset, name); 7313 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 7314 dns_zone_log(zone, ISC_LOG_ERROR, 7315 "zone_resigninc:dns_db_getsigningtime -> %s", 7316 isc_result_totext(result)); 7317 } 7318 7319 i = 0; 7320 while (result == ISC_R_SUCCESS) { 7321 resign = rdataset.resign - 7322 dns_zone_getsigresigninginterval(zone); 7323 covers = rdataset.covers; 7324 dns_rdataset_disassociate(&rdataset); 7325 7326 /* 7327 * Stop if we hit the SOA as that means we have walked the 7328 * entire zone. The SOA record should always be the most 7329 * recent signature. 7330 */ 7331 /* XXXMPA increase number of RRsets signed pre call */ 7332 if ((covers == dns_rdatatype_soa && 7333 dns_name_equal(name, &zone->origin)) || 7334 i++ > zone->signatures || resign > stop) 7335 { 7336 break; 7337 } 7338 7339 result = del_sigs(zone, db, version, name, covers, &zonediff, 7340 zone_keys, nkeys, now, true); 7341 if (result != ISC_R_SUCCESS) { 7342 dns_zone_log(zone, ISC_LOG_ERROR, 7343 "zone_resigninc:del_sigs -> %s", 7344 isc_result_totext(result)); 7345 break; 7346 } 7347 7348 /* 7349 * If re-signing is over 5 minutes late use 'fullexpire' 7350 * to redistribute the signature over the complete 7351 * re-signing window, otherwise only add a small amount 7352 * of jitter. 7353 */ 7354 result = add_sigs(db, version, name, zone, covers, 7355 zonediff.diff, zone_keys, nkeys, zone->mctx, 7356 now, inception, 7357 resign > (now - 300) ? expire : fullexpire, 7358 check_ksk, keyset_kskonly); 7359 if (result != ISC_R_SUCCESS) { 7360 dns_zone_log(zone, ISC_LOG_ERROR, 7361 "zone_resigninc:add_sigs -> %s", 7362 isc_result_totext(result)); 7363 break; 7364 } 7365 result = dns_db_getsigningtime(db, &rdataset, name); 7366 if (nkeys == 0 && result == ISC_R_NOTFOUND) { 7367 result = ISC_R_SUCCESS; 7368 break; 7369 } 7370 if (result != ISC_R_SUCCESS) { 7371 dns_zone_log(zone, ISC_LOG_ERROR, 7372 "zone_resigninc:dns_db_getsigningtime -> " 7373 "%s", 7374 isc_result_totext(result)); 7375 } 7376 } 7377 7378 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS) { 7379 goto failure; 7380 } 7381 7382 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 7383 &zonediff, zone_keys, nkeys, now, true); 7384 if (result != ISC_R_SUCCESS) { 7385 dns_zone_log(zone, ISC_LOG_ERROR, 7386 "zone_resigninc:del_sigs -> %s", 7387 isc_result_totext(result)); 7388 goto failure; 7389 } 7390 7391 /* 7392 * Did we change anything in the zone? 7393 */ 7394 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 7395 /* 7396 * Commit the changes if any key has been marked as offline. 7397 */ 7398 if (zonediff.offline) { 7399 dns_db_closeversion(db, &version, true); 7400 } 7401 goto failure; 7402 } 7403 7404 /* Increment SOA serial if we have made changes */ 7405 result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx, 7406 zone->updatemethod); 7407 if (result != ISC_R_SUCCESS) { 7408 dns_zone_log(zone, ISC_LOG_ERROR, 7409 "zone_resigninc:update_soa_serial -> %s", 7410 isc_result_totext(result)); 7411 goto failure; 7412 } 7413 7414 /* 7415 * Generate maximum life time signatures so that the above loop 7416 * termination is sensible. 7417 */ 7418 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa, 7419 zonediff.diff, zone_keys, nkeys, zone->mctx, now, 7420 inception, soaexpire, check_ksk, keyset_kskonly); 7421 if (result != ISC_R_SUCCESS) { 7422 dns_zone_log(zone, ISC_LOG_ERROR, 7423 "zone_resigninc:add_sigs -> %s", 7424 isc_result_totext(result)); 7425 goto failure; 7426 } 7427 7428 /* Write changes to journal file. */ 7429 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc")); 7430 7431 /* Everything has succeeded. Commit the changes. */ 7432 dns_db_closeversion(db, &version, true); 7433 7434failure: 7435 dns_diff_clear(&_sig_diff); 7436 for (i = 0; i < nkeys; i++) { 7437 dst_key_free(&zone_keys[i]); 7438 } 7439 if (version != NULL) { 7440 dns_db_closeversion(db, &version, false); 7441 dns_db_detach(&db); 7442 } else if (db != NULL) { 7443 dns_db_detach(&db); 7444 } 7445 7446 LOCK_ZONE(zone); 7447 if (result == ISC_R_SUCCESS) { 7448 set_resigntime(zone); 7449 zone_needdump(zone, DNS_DUMP_DELAY); 7450 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 7451 } else { 7452 /* 7453 * Something failed. Retry in 5 minutes. 7454 */ 7455 isc_interval_t ival; 7456 isc_interval_set(&ival, 300, 0); 7457 isc_time_nowplusinterval(&zone->resigntime, &ival); 7458 } 7459 UNLOCK_ZONE(zone); 7460 7461 INSIST(version == NULL); 7462} 7463 7464static isc_result_t 7465next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname, 7466 dns_name_t *newname, bool bottom) { 7467 isc_result_t result; 7468 dns_dbiterator_t *dbit = NULL; 7469 dns_rdatasetiter_t *rdsit = NULL; 7470 dns_dbnode_t *node = NULL; 7471 7472 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit)); 7473 CHECK(dns_dbiterator_seek(dbit, oldname)); 7474 do { 7475 result = dns_dbiterator_next(dbit); 7476 if (result == ISC_R_NOMORE) { 7477 CHECK(dns_dbiterator_first(dbit)); 7478 } 7479 CHECK(dns_dbiterator_current(dbit, &node, newname)); 7480 if (bottom && dns_name_issubdomain(newname, oldname) && 7481 !dns_name_equal(newname, oldname)) 7482 { 7483 dns_db_detachnode(db, &node); 7484 continue; 7485 } 7486 /* 7487 * Is this node empty? 7488 */ 7489 CHECK(dns_db_allrdatasets(db, node, version, 0, 0, &rdsit)); 7490 result = dns_rdatasetiter_first(rdsit); 7491 dns_db_detachnode(db, &node); 7492 dns_rdatasetiter_destroy(&rdsit); 7493 if (result != ISC_R_NOMORE) { 7494 break; 7495 } 7496 } while (1); 7497failure: 7498 if (node != NULL) { 7499 dns_db_detachnode(db, &node); 7500 } 7501 if (dbit != NULL) { 7502 dns_dbiterator_destroy(&dbit); 7503 } 7504 return (result); 7505} 7506 7507static bool 7508signed_with_good_key(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, 7509 dns_dbversion_t *version, dns_rdatatype_t type, 7510 dst_key_t *key) { 7511 isc_result_t result; 7512 dns_rdataset_t rdataset; 7513 dns_rdata_t rdata = DNS_RDATA_INIT; 7514 dns_rdata_rrsig_t rrsig; 7515 int count = 0; 7516 dns_kasp_t *kasp = dns_zone_getkasp(zone); 7517 7518 dns_rdataset_init(&rdataset); 7519 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig, 7520 type, 0, &rdataset, NULL); 7521 if (result != ISC_R_SUCCESS) { 7522 INSIST(!dns_rdataset_isassociated(&rdataset)); 7523 return (false); 7524 } 7525 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 7526 result = dns_rdataset_next(&rdataset)) 7527 { 7528 dns_rdataset_current(&rdataset, &rdata); 7529 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 7530 INSIST(result == ISC_R_SUCCESS); 7531 if (rrsig.algorithm == dst_key_alg(key) && 7532 rrsig.keyid == dst_key_id(key)) 7533 { 7534 dns_rdataset_disassociate(&rdataset); 7535 return (true); 7536 } 7537 if (rrsig.algorithm == dst_key_alg(key)) { 7538 count++; 7539 } 7540 dns_rdata_reset(&rdata); 7541 } 7542 7543 if (dns_zone_getkasp(zone) != NULL) { 7544 dns_kasp_key_t *kkey; 7545 int zsk_count = 0; 7546 bool approved; 7547 7548 KASP_LOCK(kasp); 7549 for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL; 7550 kkey = ISC_LIST_NEXT(kkey, link)) 7551 { 7552 if (dns_kasp_key_algorithm(kkey) != dst_key_alg(key)) { 7553 continue; 7554 } 7555 if (dns_kasp_key_zsk(kkey)) { 7556 zsk_count++; 7557 } 7558 } 7559 KASP_UNLOCK(kasp); 7560 7561 if (type == dns_rdatatype_dnskey || 7562 type == dns_rdatatype_cdnskey || type == dns_rdatatype_cds) 7563 { 7564 /* 7565 * CDS and CDNSKEY are signed with KSK like DNSKEY. 7566 * (RFC 7344, section 4.1 specifies that they must 7567 * be signed with a key in the current DS RRset, 7568 * which would only include KSK's.) 7569 */ 7570 approved = false; 7571 } else { 7572 approved = (zsk_count == count); 7573 } 7574 7575 dns_rdataset_disassociate(&rdataset); 7576 return (approved); 7577 } 7578 7579 dns_rdataset_disassociate(&rdataset); 7580 return (false); 7581} 7582 7583static isc_result_t 7584add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 7585 dns_dbnode_t *node, dns_ttl_t ttl, bool bottom, dns_diff_t *diff) { 7586 dns_fixedname_t fixed; 7587 dns_name_t *next; 7588 dns_rdata_t rdata = DNS_RDATA_INIT; 7589 isc_result_t result; 7590 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE]; 7591 7592 next = dns_fixedname_initname(&fixed); 7593 7594 CHECK(next_active(db, version, name, next, bottom)); 7595 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer, &rdata)); 7596 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl, 7597 &rdata)); 7598failure: 7599 return (result); 7600} 7601 7602static isc_result_t 7603check_if_bottom_of_zone(dns_db_t *db, dns_dbnode_t *node, 7604 dns_dbversion_t *version, bool *is_bottom_of_zone) { 7605 isc_result_t result; 7606 dns_rdatasetiter_t *iterator = NULL; 7607 dns_rdataset_t rdataset; 7608 bool seen_soa = false, seen_ns = false, seen_dname = false; 7609 7610 REQUIRE(is_bottom_of_zone != NULL); 7611 7612 result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator); 7613 if (result != ISC_R_SUCCESS) { 7614 if (result == ISC_R_NOTFOUND) { 7615 result = ISC_R_SUCCESS; 7616 } 7617 return (result); 7618 } 7619 7620 dns_rdataset_init(&rdataset); 7621 for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; 7622 result = dns_rdatasetiter_next(iterator)) 7623 { 7624 dns_rdatasetiter_current(iterator, &rdataset); 7625 switch (rdataset.type) { 7626 case dns_rdatatype_soa: 7627 seen_soa = true; 7628 break; 7629 case dns_rdatatype_ns: 7630 seen_ns = true; 7631 break; 7632 case dns_rdatatype_dname: 7633 seen_dname = true; 7634 break; 7635 } 7636 dns_rdataset_disassociate(&rdataset); 7637 } 7638 if (result != ISC_R_NOMORE) { 7639 goto failure; 7640 } 7641 if ((seen_ns && !seen_soa) || seen_dname) { 7642 *is_bottom_of_zone = true; 7643 } 7644 result = ISC_R_SUCCESS; 7645 7646failure: 7647 dns_rdatasetiter_destroy(&iterator); 7648 7649 return (result); 7650} 7651 7652static isc_result_t 7653sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name, 7654 dns_dbnode_t *node, dns_dbversion_t *version, bool build_nsec3, 7655 bool build_nsec, dst_key_t *key, isc_stdtime_t now, 7656 isc_stdtime_t inception, isc_stdtime_t expire, dns_ttl_t nsecttl, 7657 bool is_ksk, bool is_zsk, bool keyset_kskonly, 7658 bool is_bottom_of_zone, dns_diff_t *diff, int32_t *signatures, 7659 isc_mem_t *mctx) { 7660 isc_result_t result; 7661 dns_rdatasetiter_t *iterator = NULL; 7662 dns_rdataset_t rdataset; 7663 dns_rdata_t rdata = DNS_RDATA_INIT; 7664 dns_stats_t *dnssecsignstats; 7665 7666 isc_buffer_t buffer; 7667 unsigned char data[1024]; 7668 bool seen_soa, seen_ns, seen_rr, seen_nsec, seen_nsec3, seen_ds; 7669 7670 result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator); 7671 if (result != ISC_R_SUCCESS) { 7672 if (result == ISC_R_NOTFOUND) { 7673 result = ISC_R_SUCCESS; 7674 } 7675 return (result); 7676 } 7677 7678 dns_rdataset_init(&rdataset); 7679 isc_buffer_init(&buffer, data, sizeof(data)); 7680 seen_rr = seen_soa = seen_ns = seen_nsec = seen_nsec3 = seen_ds = false; 7681 for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; 7682 result = dns_rdatasetiter_next(iterator)) 7683 { 7684 dns_rdatasetiter_current(iterator, &rdataset); 7685 if (rdataset.type == dns_rdatatype_soa) { 7686 seen_soa = true; 7687 } else if (rdataset.type == dns_rdatatype_ns) { 7688 seen_ns = true; 7689 } else if (rdataset.type == dns_rdatatype_ds) { 7690 seen_ds = true; 7691 } else if (rdataset.type == dns_rdatatype_nsec) { 7692 seen_nsec = true; 7693 } else if (rdataset.type == dns_rdatatype_nsec3) { 7694 seen_nsec3 = true; 7695 } 7696 if (rdataset.type != dns_rdatatype_rrsig) { 7697 seen_rr = true; 7698 } 7699 dns_rdataset_disassociate(&rdataset); 7700 } 7701 if (result != ISC_R_NOMORE) { 7702 goto failure; 7703 } 7704 /* 7705 * Going from insecure to NSEC3. 7706 * Don't generate NSEC3 records for NSEC3 records. 7707 */ 7708 if (build_nsec3 && !seen_nsec3 && seen_rr) { 7709 bool unsecure = !seen_ds && seen_ns && !seen_soa; 7710 CHECK(dns_nsec3_addnsec3s(db, version, name, nsecttl, unsecure, 7711 diff)); 7712 (*signatures)--; 7713 } 7714 /* 7715 * Going from insecure to NSEC. 7716 * Don't generate NSEC records for NSEC3 records. 7717 */ 7718 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) { 7719 /* 7720 * Build a NSEC record except at the origin. 7721 */ 7722 if (!dns_name_equal(name, dns_db_origin(db))) { 7723 CHECK(add_nsec(db, version, name, node, nsecttl, 7724 is_bottom_of_zone, diff)); 7725 /* Count a NSEC generation as a signature generation. */ 7726 (*signatures)--; 7727 } 7728 } 7729 result = dns_rdatasetiter_first(iterator); 7730 while (result == ISC_R_SUCCESS) { 7731 isc_stdtime_t when; 7732 7733 dns_rdatasetiter_current(iterator, &rdataset); 7734 if (rdataset.type == dns_rdatatype_soa || 7735 rdataset.type == dns_rdatatype_rrsig) 7736 { 7737 goto next_rdataset; 7738 } 7739 if (rdataset.type == dns_rdatatype_dnskey || 7740 rdataset.type == dns_rdatatype_cdnskey || 7741 rdataset.type == dns_rdatatype_cds) 7742 { 7743 /* 7744 * CDS and CDNSKEY are signed with KSK like DNSKEY. 7745 * (RFC 7344, section 4.1 specifies that they must 7746 * be signed with a key in the current DS RRset, 7747 * which would only include KSK's.) 7748 */ 7749 if (!is_ksk && keyset_kskonly) { 7750 goto next_rdataset; 7751 } 7752 } else if (!is_zsk) { 7753 goto next_rdataset; 7754 } else if (is_zsk && 7755 !dst_key_is_signing(key, DST_BOOL_ZSK, now, &when)) 7756 { 7757 /* Only applies to dnssec-policy. */ 7758 if (dns_zone_getkasp(zone) != NULL) { 7759 goto next_rdataset; 7760 } 7761 } 7762 7763 if (seen_ns && !seen_soa && rdataset.type != dns_rdatatype_ds && 7764 rdataset.type != dns_rdatatype_nsec) 7765 { 7766 goto next_rdataset; 7767 } 7768 if (signed_with_good_key(zone, db, node, version, rdataset.type, 7769 key)) 7770 { 7771 goto next_rdataset; 7772 } 7773 7774 /* Calculate the signature, creating a RRSIG RDATA. */ 7775 isc_buffer_clear(&buffer); 7776 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception, &expire, 7777 mctx, &buffer, &rdata)); 7778 /* Update the database and journal with the RRSIG. */ 7779 /* XXX inefficient - will cause dataset merging */ 7780 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN, 7781 name, rdataset.ttl, &rdata)); 7782 dns_rdata_reset(&rdata); 7783 7784 /* Update DNSSEC sign statistics. */ 7785 dnssecsignstats = dns_zone_getdnssecsignstats(zone); 7786 if (dnssecsignstats != NULL) { 7787 /* Generated a new signature. */ 7788 dns_dnssecsignstats_increment(dnssecsignstats, ID(key), 7789 ALG(key), 7790 dns_dnssecsignstats_sign); 7791 /* This is a refresh. */ 7792 dns_dnssecsignstats_increment( 7793 dnssecsignstats, ID(key), ALG(key), 7794 dns_dnssecsignstats_refresh); 7795 } 7796 7797 (*signatures)--; 7798 next_rdataset: 7799 dns_rdataset_disassociate(&rdataset); 7800 result = dns_rdatasetiter_next(iterator); 7801 } 7802 if (result == ISC_R_NOMORE) { 7803 result = ISC_R_SUCCESS; 7804 } 7805failure: 7806 if (dns_rdataset_isassociated(&rdataset)) { 7807 dns_rdataset_disassociate(&rdataset); 7808 } 7809 if (iterator != NULL) { 7810 dns_rdatasetiter_destroy(&iterator); 7811 } 7812 return (result); 7813} 7814 7815/* 7816 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist. 7817 */ 7818static isc_result_t 7819updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 7820 dns_ttl_t nsecttl, bool update_only, dns_diff_t *diff) { 7821 isc_result_t result; 7822 dns_rdataset_t rdataset; 7823 dns_dbnode_t *node = NULL; 7824 7825 CHECK(dns_db_getoriginnode(db, &node)); 7826 if (update_only) { 7827 dns_rdataset_init(&rdataset); 7828 result = dns_db_findrdataset( 7829 db, node, version, dns_rdatatype_nsec, 7830 dns_rdatatype_none, 0, &rdataset, NULL); 7831 if (dns_rdataset_isassociated(&rdataset)) { 7832 dns_rdataset_disassociate(&rdataset); 7833 } 7834 if (result == ISC_R_NOTFOUND) { 7835 goto success; 7836 } 7837 if (result != ISC_R_SUCCESS) { 7838 goto failure; 7839 } 7840 } 7841 CHECK(delete_nsec(db, version, node, name, diff)); 7842 CHECK(add_nsec(db, version, name, node, nsecttl, false, diff)); 7843success: 7844 result = ISC_R_SUCCESS; 7845failure: 7846 if (node != NULL) { 7847 dns_db_detachnode(db, &node); 7848 } 7849 return (result); 7850} 7851 7852static isc_result_t 7853updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing, 7854 dns_dbversion_t *version, bool build_nsec3, dns_ttl_t nsecttl, 7855 dns_diff_t *diff) { 7856 isc_result_t result; 7857 dns_dbnode_t *node = NULL; 7858 dns_rdataset_t rdataset; 7859 dns_rdata_t rdata = DNS_RDATA_INIT; 7860 unsigned char data[5]; 7861 bool seen_done = false; 7862 bool have_rr = false; 7863 7864 dns_rdataset_init(&rdataset); 7865 result = dns_db_getoriginnode(signing->db, &node); 7866 if (result != ISC_R_SUCCESS) { 7867 goto failure; 7868 } 7869 7870 result = dns_db_findrdataset(signing->db, node, version, 7871 zone->privatetype, dns_rdatatype_none, 0, 7872 &rdataset, NULL); 7873 if (result == ISC_R_NOTFOUND) { 7874 INSIST(!dns_rdataset_isassociated(&rdataset)); 7875 result = ISC_R_SUCCESS; 7876 goto failure; 7877 } 7878 if (result != ISC_R_SUCCESS) { 7879 INSIST(!dns_rdataset_isassociated(&rdataset)); 7880 goto failure; 7881 } 7882 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 7883 result = dns_rdataset_next(&rdataset)) 7884 { 7885 dns_rdataset_current(&rdataset, &rdata); 7886 /* 7887 * If we don't match the algorithm or keyid skip the record. 7888 */ 7889 if (rdata.length != 5 || rdata.data[0] != signing->algorithm || 7890 rdata.data[1] != ((signing->keyid >> 8) & 0xff) || 7891 rdata.data[2] != (signing->keyid & 0xff)) 7892 { 7893 have_rr = true; 7894 dns_rdata_reset(&rdata); 7895 continue; 7896 } 7897 /* 7898 * We have a match. If we were signing (!signing->deleteit) 7899 * and we already have a record indicating that we have 7900 * finished signing (rdata.data[4] != 0) then keep it. 7901 * Otherwise it needs to be deleted as we have removed all 7902 * the signatures (signing->deleteit), so any record indicating 7903 * completion is now out of date, or we have finished signing 7904 * with the new record so we no longer need to remember that 7905 * we need to sign the zone with the matching key across a 7906 * nameserver re-start. 7907 */ 7908 if (!signing->deleteit && rdata.data[4] != 0) { 7909 seen_done = true; 7910 have_rr = true; 7911 } else { 7912 CHECK(update_one_rr(signing->db, version, diff, 7913 DNS_DIFFOP_DEL, &zone->origin, 7914 rdataset.ttl, &rdata)); 7915 } 7916 dns_rdata_reset(&rdata); 7917 } 7918 if (result == ISC_R_NOMORE) { 7919 result = ISC_R_SUCCESS; 7920 } 7921 if (!signing->deleteit && !seen_done) { 7922 /* 7923 * If we were signing then we need to indicate that we have 7924 * finished signing the zone with this key. If it is already 7925 * there we don't need to add it a second time. 7926 */ 7927 data[0] = signing->algorithm; 7928 data[1] = (signing->keyid >> 8) & 0xff; 7929 data[2] = signing->keyid & 0xff; 7930 data[3] = 0; 7931 data[4] = 1; 7932 rdata.length = sizeof(data); 7933 rdata.data = data; 7934 rdata.type = zone->privatetype; 7935 rdata.rdclass = dns_db_class(signing->db); 7936 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD, 7937 &zone->origin, rdataset.ttl, &rdata)); 7938 } else if (!have_rr) { 7939 dns_name_t *origin = dns_db_origin(signing->db); 7940 /* 7941 * Rebuild the NSEC/NSEC3 record for the origin as we no 7942 * longer have any private records. 7943 */ 7944 if (build_nsec3) { 7945 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin, 7946 nsecttl, false, diff)); 7947 } 7948 CHECK(updatesecure(signing->db, version, origin, nsecttl, true, 7949 diff)); 7950 } 7951 7952failure: 7953 if (dns_rdataset_isassociated(&rdataset)) { 7954 dns_rdataset_disassociate(&rdataset); 7955 } 7956 if (node != NULL) { 7957 dns_db_detachnode(signing->db, &node); 7958 } 7959 return (result); 7960} 7961 7962/* 7963 * Called from zone_nsec3chain() in order to update zone records indicating 7964 * processing status of given NSEC3 chain: 7965 * 7966 * - If the supplied dns_nsec3chain_t structure has been fully processed 7967 * (which is indicated by "active" being set to false): 7968 * 7969 * - remove all NSEC3PARAM records matching the relevant NSEC3 chain, 7970 * 7971 * - remove all private-type records containing NSEC3PARAM RDATA matching 7972 * the relevant NSEC3 chain. 7973 * 7974 * - If the supplied dns_nsec3chain_t structure has not been fully processed 7975 * (which is indicated by "active" being set to true), only remove the 7976 * NSEC3PARAM record which matches the relevant NSEC3 chain and has the 7977 * "flags" field set to 0. 7978 * 7979 * - If given NSEC3 chain is being added, add an NSEC3PARAM record contained 7980 * in the relevant private-type record, but with the "flags" field set to 7981 * 0, indicating that this NSEC3 chain is now complete for this zone. 7982 * 7983 * Note that this function is called at different processing stages for NSEC3 7984 * chain additions vs. removals and needs to handle all cases properly. 7985 */ 7986static isc_result_t 7987fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain, 7988 bool active, dns_rdatatype_t privatetype, dns_diff_t *diff) { 7989 dns_dbnode_t *node = NULL; 7990 dns_name_t *name = dns_db_origin(db); 7991 dns_rdata_t rdata = DNS_RDATA_INIT; 7992 dns_rdataset_t rdataset; 7993 dns_rdata_nsec3param_t nsec3param; 7994 isc_result_t result; 7995 isc_buffer_t buffer; 7996 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE]; 7997 dns_ttl_t ttl = 0; 7998 bool nseconly = false, nsec3ok = false; 7999 8000 dns_rdataset_init(&rdataset); 8001 8002 result = dns_db_getoriginnode(db, &node); 8003 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8004 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0, 8005 0, &rdataset, NULL); 8006 if (result == ISC_R_NOTFOUND) { 8007 goto try_private; 8008 } 8009 if (result != ISC_R_SUCCESS) { 8010 goto failure; 8011 } 8012 8013 /* 8014 * Preserve the existing ttl. 8015 */ 8016 ttl = rdataset.ttl; 8017 8018 /* 8019 * Delete all NSEC3PARAM records which match that in nsec3chain. 8020 */ 8021 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8022 result = dns_rdataset_next(&rdataset)) 8023 { 8024 dns_rdataset_current(&rdataset, &rdata); 8025 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 8026 8027 if (nsec3param.hash != chain->nsec3param.hash || 8028 (active && nsec3param.flags != 0) || 8029 nsec3param.iterations != chain->nsec3param.iterations || 8030 nsec3param.salt_length != chain->nsec3param.salt_length || 8031 memcmp(nsec3param.salt, chain->nsec3param.salt, 8032 nsec3param.salt_length)) 8033 { 8034 dns_rdata_reset(&rdata); 8035 continue; 8036 } 8037 8038 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8039 rdataset.ttl, &rdata)); 8040 dns_rdata_reset(&rdata); 8041 } 8042 if (result != ISC_R_NOMORE) { 8043 goto failure; 8044 } 8045 8046 dns_rdataset_disassociate(&rdataset); 8047 8048try_private: 8049 8050 if (active) { 8051 goto add; 8052 } 8053 8054 result = dns_nsec_nseconly(db, ver, diff, &nseconly); 8055 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 8056 8057 /* 8058 * Delete all private records which match that in nsec3chain. 8059 */ 8060 result = dns_db_findrdataset(db, node, ver, privatetype, 0, 0, 8061 &rdataset, NULL); 8062 if (result == ISC_R_NOTFOUND) { 8063 goto add; 8064 } 8065 if (result != ISC_R_SUCCESS) { 8066 goto failure; 8067 } 8068 8069 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8070 result = dns_rdataset_next(&rdataset)) 8071 { 8072 dns_rdata_t private = DNS_RDATA_INIT; 8073 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 8074 8075 dns_rdataset_current(&rdataset, &private); 8076 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 8077 sizeof(buf))) 8078 { 8079 continue; 8080 } 8081 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 8082 8083 if ((!nsec3ok && 8084 (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) || 8085 nsec3param.hash != chain->nsec3param.hash || 8086 nsec3param.iterations != chain->nsec3param.iterations || 8087 nsec3param.salt_length != chain->nsec3param.salt_length || 8088 memcmp(nsec3param.salt, chain->nsec3param.salt, 8089 nsec3param.salt_length)) 8090 { 8091 dns_rdata_reset(&rdata); 8092 continue; 8093 } 8094 8095 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8096 rdataset.ttl, &private)); 8097 dns_rdata_reset(&rdata); 8098 } 8099 if (result != ISC_R_NOMORE) { 8100 goto failure; 8101 } 8102 8103add: 8104 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) { 8105 result = ISC_R_SUCCESS; 8106 goto failure; 8107 } 8108 8109 /* 8110 * Add a NSEC3PARAM record which matches that in nsec3chain but 8111 * with all flags bits cleared. 8112 * 8113 * Note: we do not clear chain->nsec3param.flags as this change 8114 * may be reversed. 8115 */ 8116 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf)); 8117 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), 8118 dns_rdatatype_nsec3param, &chain->nsec3param, 8119 &buffer)); 8120 rdata.data[1] = 0; /* Clear flag bits. */ 8121 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata)); 8122 8123failure: 8124 dns_db_detachnode(db, &node); 8125 if (dns_rdataset_isassociated(&rdataset)) { 8126 dns_rdataset_disassociate(&rdataset); 8127 } 8128 return (result); 8129} 8130 8131static isc_result_t 8132delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 8133 dns_name_t *name, dns_diff_t *diff) { 8134 dns_rdataset_t rdataset; 8135 isc_result_t result; 8136 8137 dns_rdataset_init(&rdataset); 8138 8139 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0, 8140 &rdataset, NULL); 8141 if (result == ISC_R_NOTFOUND) { 8142 return (ISC_R_SUCCESS); 8143 } 8144 if (result != ISC_R_SUCCESS) { 8145 return (result); 8146 } 8147 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8148 result = dns_rdataset_next(&rdataset)) 8149 { 8150 dns_rdata_t rdata = DNS_RDATA_INIT; 8151 8152 dns_rdataset_current(&rdataset, &rdata); 8153 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8154 rdataset.ttl, &rdata)); 8155 } 8156 if (result == ISC_R_NOMORE) { 8157 result = ISC_R_SUCCESS; 8158 } 8159failure: 8160 dns_rdataset_disassociate(&rdataset); 8161 return (result); 8162} 8163 8164static isc_result_t 8165deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 8166 dns_name_t *name, const dns_rdata_nsec3param_t *param, 8167 dns_diff_t *diff) { 8168 dns_rdataset_t rdataset; 8169 dns_rdata_nsec3_t nsec3; 8170 isc_result_t result; 8171 8172 dns_rdataset_init(&rdataset); 8173 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 0, 0, 8174 &rdataset, NULL); 8175 if (result == ISC_R_NOTFOUND) { 8176 return (ISC_R_SUCCESS); 8177 } 8178 if (result != ISC_R_SUCCESS) { 8179 return (result); 8180 } 8181 8182 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8183 result = dns_rdataset_next(&rdataset)) 8184 { 8185 dns_rdata_t rdata = DNS_RDATA_INIT; 8186 8187 dns_rdataset_current(&rdataset, &rdata); 8188 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL)); 8189 if (nsec3.hash != param->hash || 8190 nsec3.iterations != param->iterations || 8191 nsec3.salt_length != param->salt_length || 8192 memcmp(nsec3.salt, param->salt, nsec3.salt_length)) 8193 { 8194 continue; 8195 } 8196 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 8197 rdataset.ttl, &rdata)); 8198 } 8199 if (result == ISC_R_NOMORE) { 8200 result = ISC_R_SUCCESS; 8201 } 8202failure: 8203 dns_rdataset_disassociate(&rdataset); 8204 return (result); 8205} 8206 8207static isc_result_t 8208need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver, 8209 const dns_rdata_nsec3param_t *param, bool *answer) { 8210 dns_dbnode_t *node = NULL; 8211 dns_rdata_t rdata = DNS_RDATA_INIT; 8212 dns_rdata_nsec3param_t myparam; 8213 dns_rdataset_t rdataset; 8214 isc_result_t result; 8215 8216 *answer = false; 8217 8218 result = dns_db_getoriginnode(db, &node); 8219 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8220 8221 dns_rdataset_init(&rdataset); 8222 8223 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0, 8224 &rdataset, NULL); 8225 if (result == ISC_R_SUCCESS) { 8226 dns_rdataset_disassociate(&rdataset); 8227 dns_db_detachnode(db, &node); 8228 return (result); 8229 } 8230 if (result != ISC_R_NOTFOUND) { 8231 dns_db_detachnode(db, &node); 8232 return (result); 8233 } 8234 8235 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0, 8236 0, &rdataset, NULL); 8237 if (result == ISC_R_NOTFOUND) { 8238 *answer = true; 8239 dns_db_detachnode(db, &node); 8240 return (ISC_R_SUCCESS); 8241 } 8242 if (result != ISC_R_SUCCESS) { 8243 dns_db_detachnode(db, &node); 8244 return (result); 8245 } 8246 8247 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 8248 result = dns_rdataset_next(&rdataset)) 8249 { 8250 dns_rdataset_current(&rdataset, &rdata); 8251 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL)); 8252 dns_rdata_reset(&rdata); 8253 /* 8254 * Ignore any NSEC3PARAM removals. 8255 */ 8256 if (NSEC3REMOVE(myparam.flags)) { 8257 continue; 8258 } 8259 /* 8260 * Ignore the chain that we are in the process of deleting. 8261 */ 8262 if (myparam.hash == param->hash && 8263 myparam.iterations == param->iterations && 8264 myparam.salt_length == param->salt_length && 8265 !memcmp(myparam.salt, param->salt, myparam.salt_length)) 8266 { 8267 continue; 8268 } 8269 /* 8270 * Found an active NSEC3 chain. 8271 */ 8272 break; 8273 } 8274 if (result == ISC_R_NOMORE) { 8275 *answer = true; 8276 result = ISC_R_SUCCESS; 8277 } 8278 8279failure: 8280 if (dns_rdataset_isassociated(&rdataset)) { 8281 dns_rdataset_disassociate(&rdataset); 8282 } 8283 dns_db_detachnode(db, &node); 8284 return (result); 8285} 8286 8287/*% 8288 * Given a tuple which is part of a diff, return a pointer to the next tuple in 8289 * that diff which has the same name and type (or NULL if no such tuple is 8290 * found). 8291 */ 8292static dns_difftuple_t * 8293find_next_matching_tuple(dns_difftuple_t *cur) { 8294 dns_difftuple_t *next = cur; 8295 8296 while ((next = ISC_LIST_NEXT(next, link)) != NULL) { 8297 if (cur->rdata.type == next->rdata.type && 8298 dns_name_equal(&cur->name, &next->name)) 8299 { 8300 return (next); 8301 } 8302 } 8303 8304 return (NULL); 8305} 8306 8307/*% 8308 * Remove all tuples with the same name and type as 'cur' from 'src' and append 8309 * them to 'dst'. 8310 */ 8311static void 8312move_matching_tuples(dns_difftuple_t *cur, dns_diff_t *src, dns_diff_t *dst) { 8313 do { 8314 dns_difftuple_t *next = find_next_matching_tuple(cur); 8315 ISC_LIST_UNLINK(src->tuples, cur, link); 8316 dns_diff_appendminimal(dst, &cur); 8317 cur = next; 8318 } while (cur != NULL); 8319} 8320 8321/*% 8322 * Add/remove DNSSEC signatures for the list of "raw" zone changes supplied in 8323 * 'diff'. Gradually remove tuples from 'diff' and append them to 'zonediff' 8324 * along with tuples representing relevant signature changes. 8325 */ 8326isc_result_t 8327dns__zone_updatesigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, 8328 dst_key_t *zone_keys[], unsigned int nkeys, 8329 dns_zone_t *zone, isc_stdtime_t inception, 8330 isc_stdtime_t expire, isc_stdtime_t keyexpire, 8331 isc_stdtime_t now, bool check_ksk, bool keyset_kskonly, 8332 dns__zonediff_t *zonediff) { 8333 dns_difftuple_t *tuple; 8334 isc_result_t result; 8335 8336 while ((tuple = ISC_LIST_HEAD(diff->tuples)) != NULL) { 8337 isc_stdtime_t exp = expire; 8338 8339 if (keyexpire != 0 && 8340 (tuple->rdata.type == dns_rdatatype_dnskey || 8341 tuple->rdata.type == dns_rdatatype_cdnskey || 8342 tuple->rdata.type == dns_rdatatype_cds)) 8343 { 8344 exp = keyexpire; 8345 } 8346 8347 result = del_sigs(zone, db, version, &tuple->name, 8348 tuple->rdata.type, zonediff, zone_keys, nkeys, 8349 now, false); 8350 if (result != ISC_R_SUCCESS) { 8351 dns_zone_log(zone, ISC_LOG_ERROR, 8352 "dns__zone_updatesigs:del_sigs -> %s", 8353 isc_result_totext(result)); 8354 return (result); 8355 } 8356 result = add_sigs(db, version, &tuple->name, zone, 8357 tuple->rdata.type, zonediff->diff, zone_keys, 8358 nkeys, zone->mctx, now, inception, exp, 8359 check_ksk, keyset_kskonly); 8360 if (result != ISC_R_SUCCESS) { 8361 dns_zone_log(zone, ISC_LOG_ERROR, 8362 "dns__zone_updatesigs:add_sigs -> %s", 8363 isc_result_totext(result)); 8364 return (result); 8365 } 8366 8367 /* 8368 * Signature changes for all RRs with name tuple->name and type 8369 * tuple->rdata.type were appended to zonediff->diff. Now we 8370 * remove all the "raw" changes with the same name and type 8371 * from diff (so that they are not processed by this loop 8372 * again) and append them to zonediff so that they get applied. 8373 */ 8374 move_matching_tuples(tuple, diff, zonediff->diff); 8375 } 8376 return (ISC_R_SUCCESS); 8377} 8378 8379/* 8380 * Incrementally build and sign a new NSEC3 chain using the parameters 8381 * requested. 8382 */ 8383static void 8384zone_nsec3chain(dns_zone_t *zone) { 8385 const char *me = "zone_nsec3chain"; 8386 dns_db_t *db = NULL; 8387 dns_dbnode_t *node = NULL; 8388 dns_dbversion_t *version = NULL; 8389 dns_diff_t _sig_diff; 8390 dns_diff_t nsec_diff; 8391 dns_diff_t nsec3_diff; 8392 dns_diff_t param_diff; 8393 dns__zonediff_t zonediff; 8394 dns_fixedname_t fixed; 8395 dns_fixedname_t nextfixed; 8396 dns_name_t *name, *nextname; 8397 dns_rdataset_t rdataset; 8398 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain; 8399 dns_nsec3chainlist_t cleanup; 8400 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 8401 int32_t signatures; 8402 bool check_ksk, keyset_kskonly; 8403 bool delegation; 8404 bool first; 8405 isc_result_t result; 8406 isc_stdtime_t now, inception, soaexpire, expire; 8407 uint32_t jitter, sigvalidityinterval, expiryinterval; 8408 unsigned int i; 8409 unsigned int nkeys = 0; 8410 uint32_t nodes; 8411 bool unsecure = false; 8412 bool seen_soa, seen_ns, seen_dname, seen_ds; 8413 bool seen_nsec, seen_nsec3, seen_rr; 8414 dns_rdatasetiter_t *iterator = NULL; 8415 bool buildnsecchain; 8416 bool updatensec = false; 8417 dns_rdatatype_t privatetype = zone->privatetype; 8418 8419 ENTER; 8420 8421 dns_rdataset_init(&rdataset); 8422 name = dns_fixedname_initname(&fixed); 8423 nextname = dns_fixedname_initname(&nextfixed); 8424 dns_diff_init(zone->mctx, ¶m_diff); 8425 dns_diff_init(zone->mctx, &nsec3_diff); 8426 dns_diff_init(zone->mctx, &nsec_diff); 8427 dns_diff_init(zone->mctx, &_sig_diff); 8428 zonediff_init(&zonediff, &_sig_diff); 8429 ISC_LIST_INIT(cleanup); 8430 8431 /* 8432 * Updates are disabled. Pause for 5 minutes. 8433 */ 8434 if (zone->update_disabled) { 8435 result = ISC_R_FAILURE; 8436 goto failure; 8437 } 8438 8439 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8440 /* 8441 * This function is called when zone timer fires, after the latter gets 8442 * set by zone_addnsec3chain(). If the action triggering the call to 8443 * zone_addnsec3chain() is closely followed by a zone deletion request, 8444 * it might turn out that the timer thread will not be woken up until 8445 * after the zone is deleted by rmzone(), which calls dns_db_detach() 8446 * for zone->db, causing the latter to become NULL. Return immediately 8447 * if that happens. 8448 */ 8449 if (zone->db != NULL) { 8450 dns_db_attach(zone->db, &db); 8451 } 8452 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8453 if (db == NULL) { 8454 return; 8455 } 8456 8457 result = dns_db_newversion(db, &version); 8458 if (result != ISC_R_SUCCESS) { 8459 dnssec_log(zone, ISC_LOG_ERROR, 8460 "zone_nsec3chain:dns_db_newversion -> %s", 8461 isc_result_totext(result)); 8462 goto failure; 8463 } 8464 8465 isc_stdtime_get(&now); 8466 8467 result = dns__zone_findkeys(zone, db, version, now, zone->mctx, 8468 DNS_MAXZONEKEYS, zone_keys, &nkeys); 8469 if (result != ISC_R_SUCCESS) { 8470 dnssec_log(zone, ISC_LOG_ERROR, 8471 "zone_nsec3chain:dns__zone_findkeys -> %s", 8472 isc_result_totext(result)); 8473 goto failure; 8474 } 8475 8476 sigvalidityinterval = dns_zone_getsigvalidityinterval(zone); 8477 inception = now - 3600; /* Allow for clock skew. */ 8478 soaexpire = now + sigvalidityinterval; 8479 expiryinterval = dns_zone_getsigresigninginterval(zone); 8480 if (expiryinterval > sigvalidityinterval) { 8481 expiryinterval = sigvalidityinterval; 8482 } else { 8483 expiryinterval = sigvalidityinterval - expiryinterval; 8484 } 8485 8486 /* 8487 * Spread out signatures over time if they happen to be 8488 * clumped. We don't do this for each add_sigs() call as 8489 * we still want some clustering to occur. 8490 */ 8491 if (sigvalidityinterval >= 3600U) { 8492 if (sigvalidityinterval > 7200U) { 8493 jitter = isc_random_uniform(expiryinterval); 8494 } else { 8495 jitter = isc_random_uniform(1200); 8496 } 8497 expire = soaexpire - jitter - 1; 8498 } else { 8499 expire = soaexpire - 1; 8500 } 8501 8502 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 8503 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 8504 8505 /* 8506 * We keep pulling nodes off each iterator in turn until 8507 * we have no more nodes to pull off or we reach the limits 8508 * for this quantum. 8509 */ 8510 nodes = zone->nodes; 8511 signatures = zone->signatures; 8512 LOCK_ZONE(zone); 8513 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 8514 UNLOCK_ZONE(zone); 8515 first = true; 8516 8517 if (nsec3chain != NULL) { 8518 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 8519 } 8520 /* 8521 * Generate new NSEC3 chains first. 8522 * 8523 * The following while loop iterates over nodes in the zone database, 8524 * updating the NSEC3 chain by calling dns_nsec3_addnsec3() for each of 8525 * them. Once all nodes are processed, the "delete_nsec" field is 8526 * consulted to check whether we are supposed to remove NSEC records 8527 * from the zone database; if so, the database iterator is reset to 8528 * point to the first node and the loop traverses all of them again, 8529 * this time removing NSEC records. If we hit a node which is obscured 8530 * by a delegation or a DNAME, nodes are skipped over until we find one 8531 * that is not obscured by the same obscuring name and then normal 8532 * processing is resumed. 8533 * 8534 * The above is repeated until all requested NSEC3 chain changes are 8535 * applied or when we reach the limits for this quantum, whichever 8536 * happens first. 8537 * 8538 * Note that the "signatures" variable is only used here to limit the 8539 * amount of work performed. Actual DNSSEC signatures are only 8540 * generated by dns__zone_updatesigs() calls later in this function. 8541 */ 8542 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 8543 dns_dbiterator_pause(nsec3chain->dbiterator); 8544 8545 LOCK_ZONE(zone); 8546 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 8547 8548 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8549 if (nsec3chain->done || nsec3chain->db != zone->db) { 8550 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 8551 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8552 } 8553 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8554 UNLOCK_ZONE(zone); 8555 if (ISC_LIST_TAIL(cleanup) == nsec3chain) { 8556 goto next_addchain; 8557 } 8558 8559 /* 8560 * Possible future db. 8561 */ 8562 if (nsec3chain->db != db) { 8563 goto next_addchain; 8564 } 8565 8566 if (NSEC3REMOVE(nsec3chain->nsec3param.flags)) { 8567 goto next_addchain; 8568 } 8569 8570 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 8571 8572 if (nsec3chain->delete_nsec) { 8573 delegation = false; 8574 dns_dbiterator_pause(nsec3chain->dbiterator); 8575 CHECK(delete_nsec(db, version, node, name, &nsec_diff)); 8576 goto next_addnode; 8577 } 8578 /* 8579 * On the first pass we need to check if the current node 8580 * has not been obscured. 8581 */ 8582 delegation = false; 8583 unsecure = false; 8584 if (first) { 8585 dns_fixedname_t ffound; 8586 dns_name_t *found; 8587 found = dns_fixedname_initname(&ffound); 8588 result = dns_db_find( 8589 db, name, version, dns_rdatatype_soa, 8590 DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); 8591 if ((result == DNS_R_DELEGATION || 8592 result == DNS_R_DNAME) && 8593 !dns_name_equal(name, found)) 8594 { 8595 /* 8596 * Remember the obscuring name so that 8597 * we skip all obscured names. 8598 */ 8599 dns_name_copy(found, name); 8600 delegation = true; 8601 goto next_addnode; 8602 } 8603 } 8604 8605 /* 8606 * Check to see if this is a bottom of zone node. 8607 */ 8608 result = dns_db_allrdatasets(db, node, version, 0, 0, 8609 &iterator); 8610 if (result == ISC_R_NOTFOUND) { 8611 /* Empty node? */ 8612 goto next_addnode; 8613 } 8614 if (result != ISC_R_SUCCESS) { 8615 goto failure; 8616 } 8617 8618 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = false; 8619 for (result = dns_rdatasetiter_first(iterator); 8620 result == ISC_R_SUCCESS; 8621 result = dns_rdatasetiter_next(iterator)) 8622 { 8623 dns_rdatasetiter_current(iterator, &rdataset); 8624 INSIST(rdataset.type != dns_rdatatype_nsec3); 8625 if (rdataset.type == dns_rdatatype_soa) { 8626 seen_soa = true; 8627 } else if (rdataset.type == dns_rdatatype_ns) { 8628 seen_ns = true; 8629 } else if (rdataset.type == dns_rdatatype_dname) { 8630 seen_dname = true; 8631 } else if (rdataset.type == dns_rdatatype_ds) { 8632 seen_ds = true; 8633 } else if (rdataset.type == dns_rdatatype_nsec) { 8634 seen_nsec = true; 8635 } 8636 dns_rdataset_disassociate(&rdataset); 8637 } 8638 dns_rdatasetiter_destroy(&iterator); 8639 /* 8640 * Is there a NSEC chain than needs to be cleaned up? 8641 */ 8642 if (seen_nsec) { 8643 nsec3chain->seen_nsec = true; 8644 } 8645 if (seen_ns && !seen_soa && !seen_ds) { 8646 unsecure = true; 8647 } 8648 if ((seen_ns && !seen_soa) || seen_dname) { 8649 delegation = true; 8650 } 8651 8652 /* 8653 * Process one node. 8654 */ 8655 dns_dbiterator_pause(nsec3chain->dbiterator); 8656 result = dns_nsec3_addnsec3( 8657 db, version, name, &nsec3chain->nsec3param, 8658 zone_nsecttl(zone), unsecure, &nsec3_diff); 8659 if (result != ISC_R_SUCCESS) { 8660 dnssec_log(zone, ISC_LOG_ERROR, 8661 "zone_nsec3chain:" 8662 "dns_nsec3_addnsec3 -> %s", 8663 isc_result_totext(result)); 8664 goto failure; 8665 } 8666 8667 /* 8668 * Treat each call to dns_nsec3_addnsec3() as if it's cost is 8669 * two signatures. Additionally there will, in general, be 8670 * two signature generated below. 8671 * 8672 * If we are only changing the optout flag the cost is half 8673 * that of the cost of generating a completely new chain. 8674 */ 8675 signatures -= 4; 8676 8677 /* 8678 * Go onto next node. 8679 */ 8680 next_addnode: 8681 first = false; 8682 dns_db_detachnode(db, &node); 8683 do { 8684 result = dns_dbiterator_next(nsec3chain->dbiterator); 8685 8686 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) { 8687 dns_dbiterator_pause(nsec3chain->dbiterator); 8688 CHECK(fixup_nsec3param(db, version, nsec3chain, 8689 false, privatetype, 8690 ¶m_diff)); 8691 LOCK_ZONE(zone); 8692 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 8693 link); 8694 UNLOCK_ZONE(zone); 8695 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8696 goto next_addchain; 8697 } 8698 if (result == ISC_R_NOMORE) { 8699 dns_dbiterator_pause(nsec3chain->dbiterator); 8700 if (nsec3chain->seen_nsec) { 8701 CHECK(fixup_nsec3param( 8702 db, version, nsec3chain, true, 8703 privatetype, ¶m_diff)); 8704 nsec3chain->delete_nsec = true; 8705 goto same_addchain; 8706 } 8707 CHECK(fixup_nsec3param(db, version, nsec3chain, 8708 false, privatetype, 8709 ¶m_diff)); 8710 LOCK_ZONE(zone); 8711 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 8712 link); 8713 UNLOCK_ZONE(zone); 8714 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8715 goto next_addchain; 8716 } else if (result != ISC_R_SUCCESS) { 8717 dnssec_log(zone, ISC_LOG_ERROR, 8718 "zone_nsec3chain:" 8719 "dns_dbiterator_next -> %s", 8720 isc_result_totext(result)); 8721 goto failure; 8722 } else if (delegation) { 8723 dns_dbiterator_current(nsec3chain->dbiterator, 8724 &node, nextname); 8725 dns_db_detachnode(db, &node); 8726 if (!dns_name_issubdomain(nextname, name)) { 8727 break; 8728 } 8729 } else { 8730 break; 8731 } 8732 } while (1); 8733 continue; 8734 8735 same_addchain: 8736 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 8737 first = true; 8738 continue; 8739 8740 next_addchain: 8741 dns_dbiterator_pause(nsec3chain->dbiterator); 8742 nsec3chain = nextnsec3chain; 8743 first = true; 8744 if (nsec3chain != NULL) { 8745 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 8746 } 8747 } 8748 8749 if (nsec3chain != NULL) { 8750 goto skip_removals; 8751 } 8752 8753 /* 8754 * Process removals. 8755 * 8756 * This is a counterpart of the above while loop which takes care of 8757 * removing an NSEC3 chain. It starts with determining whether the 8758 * zone needs to switch from NSEC3 to NSEC; if so, it first builds an 8759 * NSEC chain by iterating over all nodes in the zone database and only 8760 * then goes on to remove NSEC3 records be iterating over all nodes 8761 * again and calling deletematchingnsec3() for each of them; otherwise, 8762 * it starts removing NSEC3 records immediately. Rules for processing 8763 * obscured nodes and interrupting work are the same as for the while 8764 * loop above. 8765 */ 8766 LOCK_ZONE(zone); 8767 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 8768 UNLOCK_ZONE(zone); 8769 first = true; 8770 buildnsecchain = false; 8771 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 8772 dns_dbiterator_pause(nsec3chain->dbiterator); 8773 8774 LOCK_ZONE(zone); 8775 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 8776 UNLOCK_ZONE(zone); 8777 8778 if (nsec3chain->db != db) { 8779 goto next_removechain; 8780 } 8781 8782 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) { 8783 goto next_removechain; 8784 } 8785 8786 /* 8787 * Work out if we need to build a NSEC chain as a consequence 8788 * of removing this NSEC3 chain. 8789 */ 8790 if (first && !updatensec && 8791 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) 8792 { 8793 result = need_nsec_chain(db, version, 8794 &nsec3chain->nsec3param, 8795 &buildnsecchain); 8796 if (result != ISC_R_SUCCESS) { 8797 dnssec_log(zone, ISC_LOG_ERROR, 8798 "zone_nsec3chain:" 8799 "need_nsec_chain -> %s", 8800 isc_result_totext(result)); 8801 goto failure; 8802 } 8803 } 8804 8805 if (first) { 8806 dnssec_log(zone, ISC_LOG_DEBUG(3), 8807 "zone_nsec3chain:buildnsecchain = %u\n", 8808 buildnsecchain); 8809 } 8810 8811 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 8812 dns_dbiterator_pause(nsec3chain->dbiterator); 8813 delegation = false; 8814 8815 if (!buildnsecchain) { 8816 /* 8817 * Delete the NSEC3PARAM record matching this chain. 8818 */ 8819 if (first) { 8820 result = fixup_nsec3param( 8821 db, version, nsec3chain, true, 8822 privatetype, ¶m_diff); 8823 if (result != ISC_R_SUCCESS) { 8824 dnssec_log(zone, ISC_LOG_ERROR, 8825 "zone_nsec3chain:" 8826 "fixup_nsec3param -> %s", 8827 isc_result_totext(result)); 8828 goto failure; 8829 } 8830 } 8831 8832 /* 8833 * Delete the NSEC3 records. 8834 */ 8835 result = deletematchingnsec3(db, version, node, name, 8836 &nsec3chain->nsec3param, 8837 &nsec3_diff); 8838 if (result != ISC_R_SUCCESS) { 8839 dnssec_log(zone, ISC_LOG_ERROR, 8840 "zone_nsec3chain:" 8841 "deletematchingnsec3 -> %s", 8842 isc_result_totext(result)); 8843 goto failure; 8844 } 8845 goto next_removenode; 8846 } 8847 8848 if (first) { 8849 dns_fixedname_t ffound; 8850 dns_name_t *found; 8851 found = dns_fixedname_initname(&ffound); 8852 result = dns_db_find( 8853 db, name, version, dns_rdatatype_soa, 8854 DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); 8855 if ((result == DNS_R_DELEGATION || 8856 result == DNS_R_DNAME) && 8857 !dns_name_equal(name, found)) 8858 { 8859 /* 8860 * Remember the obscuring name so that 8861 * we skip all obscured names. 8862 */ 8863 dns_name_copy(found, name); 8864 delegation = true; 8865 goto next_removenode; 8866 } 8867 } 8868 8869 /* 8870 * Check to see if this is a bottom of zone node. 8871 */ 8872 result = dns_db_allrdatasets(db, node, version, 0, 0, 8873 &iterator); 8874 if (result == ISC_R_NOTFOUND) { 8875 /* Empty node? */ 8876 goto next_removenode; 8877 } 8878 if (result != ISC_R_SUCCESS) { 8879 goto failure; 8880 } 8881 8882 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec = 8883 seen_rr = false; 8884 for (result = dns_rdatasetiter_first(iterator); 8885 result == ISC_R_SUCCESS; 8886 result = dns_rdatasetiter_next(iterator)) 8887 { 8888 dns_rdatasetiter_current(iterator, &rdataset); 8889 if (rdataset.type == dns_rdatatype_soa) { 8890 seen_soa = true; 8891 } else if (rdataset.type == dns_rdatatype_ns) { 8892 seen_ns = true; 8893 } else if (rdataset.type == dns_rdatatype_dname) { 8894 seen_dname = true; 8895 } else if (rdataset.type == dns_rdatatype_nsec) { 8896 seen_nsec = true; 8897 } else if (rdataset.type == dns_rdatatype_nsec3) { 8898 seen_nsec3 = true; 8899 } else if (rdataset.type != dns_rdatatype_rrsig) { 8900 seen_rr = true; 8901 } 8902 dns_rdataset_disassociate(&rdataset); 8903 } 8904 dns_rdatasetiter_destroy(&iterator); 8905 8906 if (!seen_rr || seen_nsec3 || seen_nsec) { 8907 goto next_removenode; 8908 } 8909 if ((seen_ns && !seen_soa) || seen_dname) { 8910 delegation = true; 8911 } 8912 8913 /* 8914 * Add a NSEC record except at the origin. 8915 */ 8916 if (!dns_name_equal(name, dns_db_origin(db))) { 8917 dns_dbiterator_pause(nsec3chain->dbiterator); 8918 CHECK(add_nsec(db, version, name, node, 8919 zone_nsecttl(zone), delegation, 8920 &nsec_diff)); 8921 signatures--; 8922 } 8923 8924 next_removenode: 8925 first = false; 8926 dns_db_detachnode(db, &node); 8927 do { 8928 result = dns_dbiterator_next(nsec3chain->dbiterator); 8929 if (result == ISC_R_NOMORE && buildnsecchain) { 8930 /* 8931 * The NSEC chain should now be built. 8932 * We can now remove the NSEC3 chain. 8933 */ 8934 updatensec = true; 8935 goto same_removechain; 8936 } 8937 if (result == ISC_R_NOMORE) { 8938 dns_dbiterator_pause(nsec3chain->dbiterator); 8939 LOCK_ZONE(zone); 8940 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 8941 link); 8942 UNLOCK_ZONE(zone); 8943 ISC_LIST_APPEND(cleanup, nsec3chain, link); 8944 result = fixup_nsec3param( 8945 db, version, nsec3chain, false, 8946 privatetype, ¶m_diff); 8947 if (result != ISC_R_SUCCESS) { 8948 dnssec_log(zone, ISC_LOG_ERROR, 8949 "zone_nsec3chain:" 8950 "fixup_nsec3param -> %s", 8951 isc_result_totext(result)); 8952 goto failure; 8953 } 8954 goto next_removechain; 8955 } else if (result != ISC_R_SUCCESS) { 8956 dnssec_log(zone, ISC_LOG_ERROR, 8957 "zone_nsec3chain:" 8958 "dns_dbiterator_next -> %s", 8959 isc_result_totext(result)); 8960 goto failure; 8961 } else if (delegation) { 8962 dns_dbiterator_current(nsec3chain->dbiterator, 8963 &node, nextname); 8964 dns_db_detachnode(db, &node); 8965 if (!dns_name_issubdomain(nextname, name)) { 8966 break; 8967 } 8968 } else { 8969 break; 8970 } 8971 } while (1); 8972 continue; 8973 8974 same_removechain: 8975 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 8976 buildnsecchain = false; 8977 first = true; 8978 continue; 8979 8980 next_removechain: 8981 dns_dbiterator_pause(nsec3chain->dbiterator); 8982 nsec3chain = nextnsec3chain; 8983 first = true; 8984 } 8985 8986skip_removals: 8987 /* 8988 * We may need to update the NSEC/NSEC3 records for the zone apex. 8989 */ 8990 if (!ISC_LIST_EMPTY(param_diff.tuples)) { 8991 bool rebuild_nsec = false, rebuild_nsec3 = false; 8992 result = dns_db_getoriginnode(db, &node); 8993 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8994 result = dns_db_allrdatasets(db, node, version, 0, 0, 8995 &iterator); 8996 if (result != ISC_R_SUCCESS) { 8997 dnssec_log(zone, ISC_LOG_ERROR, 8998 "zone_nsec3chain:dns_db_allrdatasets -> %s", 8999 isc_result_totext(result)); 9000 goto failure; 9001 } 9002 for (result = dns_rdatasetiter_first(iterator); 9003 result == ISC_R_SUCCESS; 9004 result = dns_rdatasetiter_next(iterator)) 9005 { 9006 dns_rdatasetiter_current(iterator, &rdataset); 9007 if (rdataset.type == dns_rdatatype_nsec) { 9008 rebuild_nsec = true; 9009 } else if (rdataset.type == dns_rdatatype_nsec3param) { 9010 rebuild_nsec3 = true; 9011 } 9012 dns_rdataset_disassociate(&rdataset); 9013 } 9014 dns_rdatasetiter_destroy(&iterator); 9015 dns_db_detachnode(db, &node); 9016 9017 if (rebuild_nsec) { 9018 if (nsec3chain != NULL) { 9019 dns_dbiterator_pause(nsec3chain->dbiterator); 9020 } 9021 9022 result = updatesecure(db, version, &zone->origin, 9023 zone_nsecttl(zone), true, 9024 &nsec_diff); 9025 if (result != ISC_R_SUCCESS) { 9026 dnssec_log(zone, ISC_LOG_ERROR, 9027 "zone_nsec3chain:updatesecure -> %s", 9028 isc_result_totext(result)); 9029 goto failure; 9030 } 9031 } 9032 9033 if (rebuild_nsec3) { 9034 if (nsec3chain != NULL) { 9035 dns_dbiterator_pause(nsec3chain->dbiterator); 9036 } 9037 9038 result = dns_nsec3_addnsec3s( 9039 db, version, dns_db_origin(db), 9040 zone_nsecttl(zone), false, &nsec3_diff); 9041 if (result != ISC_R_SUCCESS) { 9042 dnssec_log(zone, ISC_LOG_ERROR, 9043 "zone_nsec3chain:" 9044 "dns_nsec3_addnsec3s -> %s", 9045 isc_result_totext(result)); 9046 goto failure; 9047 } 9048 } 9049 } 9050 9051 /* 9052 * Add / update signatures for the NSEC3 records. 9053 */ 9054 if (nsec3chain != NULL) { 9055 dns_dbiterator_pause(nsec3chain->dbiterator); 9056 } 9057 result = dns__zone_updatesigs(&nsec3_diff, db, version, zone_keys, 9058 nkeys, zone, inception, expire, 0, now, 9059 check_ksk, keyset_kskonly, &zonediff); 9060 if (result != ISC_R_SUCCESS) { 9061 dnssec_log(zone, ISC_LOG_ERROR, 9062 "zone_nsec3chain:dns__zone_updatesigs -> %s", 9063 isc_result_totext(result)); 9064 goto failure; 9065 } 9066 9067 /* 9068 * We have changed the NSEC3PARAM or private RRsets 9069 * above so we need to update the signatures. 9070 */ 9071 result = dns__zone_updatesigs(¶m_diff, db, version, zone_keys, 9072 nkeys, zone, inception, expire, 0, now, 9073 check_ksk, keyset_kskonly, &zonediff); 9074 if (result != ISC_R_SUCCESS) { 9075 dnssec_log(zone, ISC_LOG_ERROR, 9076 "zone_nsec3chain:dns__zone_updatesigs -> %s", 9077 isc_result_totext(result)); 9078 goto failure; 9079 } 9080 9081 if (updatensec) { 9082 result = updatesecure(db, version, &zone->origin, 9083 zone_nsecttl(zone), false, &nsec_diff); 9084 if (result != ISC_R_SUCCESS) { 9085 dnssec_log(zone, ISC_LOG_ERROR, 9086 "zone_nsec3chain:updatesecure -> %s", 9087 isc_result_totext(result)); 9088 goto failure; 9089 } 9090 } 9091 9092 result = dns__zone_updatesigs(&nsec_diff, db, version, zone_keys, nkeys, 9093 zone, inception, expire, 0, now, 9094 check_ksk, keyset_kskonly, &zonediff); 9095 if (result != ISC_R_SUCCESS) { 9096 dnssec_log(zone, ISC_LOG_ERROR, 9097 "zone_nsec3chain:dns__zone_updatesigs -> %s", 9098 isc_result_totext(result)); 9099 goto failure; 9100 } 9101 9102 /* 9103 * If we made no effective changes to the zone then we can just 9104 * cleanup otherwise we need to increment the serial. 9105 */ 9106 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 9107 /* 9108 * No need to call dns_db_closeversion() here as it is 9109 * called with commit = true below. 9110 */ 9111 goto done; 9112 } 9113 9114 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 9115 &zonediff, zone_keys, nkeys, now, false); 9116 if (result != ISC_R_SUCCESS) { 9117 dnssec_log(zone, ISC_LOG_ERROR, 9118 "zone_nsec3chain:del_sigs -> %s", 9119 isc_result_totext(result)); 9120 goto failure; 9121 } 9122 9123 result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx, 9124 zone->updatemethod); 9125 if (result != ISC_R_SUCCESS) { 9126 dnssec_log(zone, ISC_LOG_ERROR, 9127 "zone_nsec3chain:update_soa_serial -> %s", 9128 isc_result_totext(result)); 9129 goto failure; 9130 } 9131 9132 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa, 9133 zonediff.diff, zone_keys, nkeys, zone->mctx, now, 9134 inception, soaexpire, check_ksk, keyset_kskonly); 9135 if (result != ISC_R_SUCCESS) { 9136 dnssec_log(zone, ISC_LOG_ERROR, 9137 "zone_nsec3chain:add_sigs -> %s", 9138 isc_result_totext(result)); 9139 goto failure; 9140 } 9141 9142 /* Write changes to journal file. */ 9143 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain")); 9144 9145 LOCK_ZONE(zone); 9146 zone_needdump(zone, DNS_DUMP_DELAY); 9147 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 9148 UNLOCK_ZONE(zone); 9149 9150done: 9151 /* 9152 * Pause all iterators so that dns_db_closeversion() can succeed. 9153 */ 9154 LOCK_ZONE(zone); 9155 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL; 9156 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 9157 { 9158 dns_dbiterator_pause(nsec3chain->dbiterator); 9159 } 9160 UNLOCK_ZONE(zone); 9161 9162 /* 9163 * Everything has succeeded. Commit the changes. 9164 * Unconditionally commit as zonediff.offline not checked above. 9165 */ 9166 dns_db_closeversion(db, &version, true); 9167 9168 /* 9169 * Everything succeeded so we can clean these up now. 9170 */ 9171 nsec3chain = ISC_LIST_HEAD(cleanup); 9172 while (nsec3chain != NULL) { 9173 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 9174 dns_db_detach(&nsec3chain->db); 9175 dns_dbiterator_destroy(&nsec3chain->dbiterator); 9176 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 9177 nsec3chain = ISC_LIST_HEAD(cleanup); 9178 } 9179 9180 LOCK_ZONE(zone); 9181 set_resigntime(zone); 9182 UNLOCK_ZONE(zone); 9183 9184failure: 9185 if (result != ISC_R_SUCCESS) { 9186 dnssec_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s", 9187 isc_result_totext(result)); 9188 } 9189 9190 /* 9191 * On error roll back the current nsec3chain. 9192 */ 9193 if (result != ISC_R_SUCCESS && nsec3chain != NULL) { 9194 if (nsec3chain->done) { 9195 dns_db_detach(&nsec3chain->db); 9196 dns_dbiterator_destroy(&nsec3chain->dbiterator); 9197 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 9198 } else { 9199 result = dns_dbiterator_first(nsec3chain->dbiterator); 9200 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9201 dns_dbiterator_pause(nsec3chain->dbiterator); 9202 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 9203 } 9204 } 9205 9206 /* 9207 * Rollback the cleanup list. 9208 */ 9209 nsec3chain = ISC_LIST_TAIL(cleanup); 9210 while (nsec3chain != NULL) { 9211 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 9212 if (nsec3chain->done) { 9213 dns_db_detach(&nsec3chain->db); 9214 dns_dbiterator_destroy(&nsec3chain->dbiterator); 9215 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 9216 } else { 9217 LOCK_ZONE(zone); 9218 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link); 9219 UNLOCK_ZONE(zone); 9220 result = dns_dbiterator_first(nsec3chain->dbiterator); 9221 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9222 dns_dbiterator_pause(nsec3chain->dbiterator); 9223 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 9224 } 9225 nsec3chain = ISC_LIST_TAIL(cleanup); 9226 } 9227 9228 LOCK_ZONE(zone); 9229 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL; 9230 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 9231 { 9232 dns_dbiterator_pause(nsec3chain->dbiterator); 9233 } 9234 UNLOCK_ZONE(zone); 9235 9236 dns_diff_clear(¶m_diff); 9237 dns_diff_clear(&nsec3_diff); 9238 dns_diff_clear(&nsec_diff); 9239 dns_diff_clear(&_sig_diff); 9240 9241 if (iterator != NULL) { 9242 dns_rdatasetiter_destroy(&iterator); 9243 } 9244 9245 for (i = 0; i < nkeys; i++) { 9246 dst_key_free(&zone_keys[i]); 9247 } 9248 9249 if (node != NULL) { 9250 dns_db_detachnode(db, &node); 9251 } 9252 if (version != NULL) { 9253 dns_db_closeversion(db, &version, false); 9254 dns_db_detach(&db); 9255 } else if (db != NULL) { 9256 dns_db_detach(&db); 9257 } 9258 9259 LOCK_ZONE(zone); 9260 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) { 9261 isc_interval_t interval; 9262 if (zone->update_disabled || result != ISC_R_SUCCESS) { 9263 isc_interval_set(&interval, 60, 0); /* 1 minute */ 9264 } else { 9265 isc_interval_set(&interval, 0, 10000000); /* 10 ms */ 9266 } 9267 isc_time_nowplusinterval(&zone->nsec3chaintime, &interval); 9268 } else { 9269 isc_time_settoepoch(&zone->nsec3chaintime); 9270 } 9271 UNLOCK_ZONE(zone); 9272 9273 INSIST(version == NULL); 9274} 9275 9276/*% 9277 * Delete all RRSIG records with the given algorithm and keyid. 9278 * Remove the NSEC record and RRSIGs if nkeys is zero. 9279 * If all remaining RRsets are signed with the given algorithm 9280 * set *has_algp to true. 9281 */ 9282static isc_result_t 9283del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 9284 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm, 9285 uint16_t keyid, bool *has_algp, dns_diff_t *diff) { 9286 dns_rdata_rrsig_t rrsig; 9287 dns_rdataset_t rdataset; 9288 dns_rdatasetiter_t *iterator = NULL; 9289 isc_result_t result; 9290 bool alg_missed = false; 9291 bool alg_found = false; 9292 9293 char namebuf[DNS_NAME_FORMATSIZE]; 9294 dns_name_format(name, namebuf, sizeof(namebuf)); 9295 9296 result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator); 9297 if (result != ISC_R_SUCCESS) { 9298 if (result == ISC_R_NOTFOUND) { 9299 result = ISC_R_SUCCESS; 9300 } 9301 return (result); 9302 } 9303 9304 dns_rdataset_init(&rdataset); 9305 for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS; 9306 result = dns_rdatasetiter_next(iterator)) 9307 { 9308 bool has_alg = false; 9309 dns_rdatasetiter_current(iterator, &rdataset); 9310 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) { 9311 for (result = dns_rdataset_first(&rdataset); 9312 result == ISC_R_SUCCESS; 9313 result = dns_rdataset_next(&rdataset)) 9314 { 9315 dns_rdata_t rdata = DNS_RDATA_INIT; 9316 dns_rdataset_current(&rdataset, &rdata); 9317 CHECK(update_one_rr(db, version, diff, 9318 DNS_DIFFOP_DEL, name, 9319 rdataset.ttl, &rdata)); 9320 } 9321 if (result != ISC_R_NOMORE) { 9322 goto failure; 9323 } 9324 dns_rdataset_disassociate(&rdataset); 9325 continue; 9326 } 9327 if (rdataset.type != dns_rdatatype_rrsig) { 9328 dns_rdataset_disassociate(&rdataset); 9329 continue; 9330 } 9331 for (result = dns_rdataset_first(&rdataset); 9332 result == ISC_R_SUCCESS; 9333 result = dns_rdataset_next(&rdataset)) 9334 { 9335 dns_rdata_t rdata = DNS_RDATA_INIT; 9336 dns_rdataset_current(&rdataset, &rdata); 9337 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL)); 9338 if (nkeys != 0 && (rrsig.algorithm != algorithm || 9339 rrsig.keyid != keyid)) 9340 { 9341 if (rrsig.algorithm == algorithm) { 9342 has_alg = true; 9343 } 9344 continue; 9345 } 9346 CHECK(update_one_rr(db, version, diff, 9347 DNS_DIFFOP_DELRESIGN, name, 9348 rdataset.ttl, &rdata)); 9349 } 9350 dns_rdataset_disassociate(&rdataset); 9351 if (result != ISC_R_NOMORE) { 9352 break; 9353 } 9354 9355 /* 9356 * After deleting, if there's still a signature for 9357 * 'algorithm', set alg_found; if not, set alg_missed. 9358 */ 9359 if (has_alg) { 9360 alg_found = true; 9361 } else { 9362 alg_missed = true; 9363 } 9364 } 9365 if (result == ISC_R_NOMORE) { 9366 result = ISC_R_SUCCESS; 9367 } 9368 9369 /* 9370 * Set `has_algp` if the algorithm was found in every RRset: 9371 * i.e., found in at least one, and not missing from any. 9372 */ 9373 *has_algp = (alg_found && !alg_missed); 9374failure: 9375 if (dns_rdataset_isassociated(&rdataset)) { 9376 dns_rdataset_disassociate(&rdataset); 9377 } 9378 dns_rdatasetiter_destroy(&iterator); 9379 return (result); 9380} 9381 9382/* 9383 * Prevent the zone entering a inconsistent state where 9384 * NSEC only DNSKEYs are present with NSEC3 chains. 9385 */ 9386bool 9387dns_zone_check_dnskey_nsec3(dns_zone_t *zone, dns_db_t *db, 9388 dns_dbversion_t *ver, dns_diff_t *diff, 9389 dst_key_t **keys, unsigned int numkeys) { 9390 uint8_t alg; 9391 dns_rdatatype_t privatetype; 9392 ; 9393 bool nseconly = false, nsec3 = false; 9394 isc_result_t result; 9395 9396 REQUIRE(DNS_ZONE_VALID(zone)); 9397 REQUIRE(db != NULL); 9398 9399 privatetype = dns_zone_getprivatetype(zone); 9400 9401 /* Scan the tuples for an NSEC-only DNSKEY */ 9402 if (diff != NULL) { 9403 for (dns_difftuple_t *tuple = ISC_LIST_HEAD(diff->tuples); 9404 tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) 9405 { 9406 if (nseconly && nsec3) { 9407 break; 9408 } 9409 9410 if (tuple->op != DNS_DIFFOP_ADD) { 9411 continue; 9412 } 9413 9414 if (tuple->rdata.type == dns_rdatatype_nsec3param) { 9415 nsec3 = true; 9416 } 9417 9418 if (tuple->rdata.type != dns_rdatatype_dnskey) { 9419 continue; 9420 } 9421 9422 alg = tuple->rdata.data[3]; 9423 if (alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_DH || 9424 alg == DNS_KEYALG_DSA || alg == DNS_KEYALG_RSASHA1) 9425 { 9426 nseconly = true; 9427 } 9428 } 9429 } 9430 /* Scan the zone keys for an NSEC-only DNSKEY */ 9431 if (keys != NULL && !nseconly) { 9432 for (unsigned int i = 0; i < numkeys; i++) { 9433 alg = dst_key_alg(keys[i]); 9434 if (alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_DH || 9435 alg == DNS_KEYALG_DSA || alg == DNS_KEYALG_RSASHA1) 9436 { 9437 nseconly = true; 9438 break; 9439 } 9440 } 9441 } 9442 9443 /* Check DB for NSEC-only DNSKEY */ 9444 if (!nseconly) { 9445 result = dns_nsec_nseconly(db, ver, diff, &nseconly); 9446 /* 9447 * Adding an NSEC3PARAM record can proceed without a 9448 * DNSKEY (it will trigger a delayed change), so we can 9449 * ignore ISC_R_NOTFOUND here. 9450 */ 9451 if (result == ISC_R_NOTFOUND) { 9452 result = ISC_R_SUCCESS; 9453 } 9454 CHECK(result); 9455 } 9456 9457 /* Check existing DB for NSEC3 */ 9458 if (!nsec3) { 9459 CHECK(dns_nsec3_activex(db, ver, false, privatetype, &nsec3)); 9460 } 9461 9462 /* Check kasp for NSEC3PARAM settings */ 9463 if (!nsec3) { 9464 dns_kasp_t *kasp = dns_zone_getkasp(zone); 9465 if (kasp != NULL) { 9466 nsec3 = dns_kasp_nsec3(kasp); 9467 } 9468 } 9469 9470 /* Refuse to allow NSEC3 with NSEC-only keys */ 9471 if (nseconly && nsec3) { 9472 goto failure; 9473 } 9474 9475 return (true); 9476 9477failure: 9478 return (false); 9479} 9480 9481/* 9482 * Incrementally sign the zone using the keys requested. 9483 * Builds the NSEC chain if required. 9484 */ 9485static void 9486zone_sign(dns_zone_t *zone) { 9487 const char *me = "zone_sign"; 9488 dns_db_t *db = NULL; 9489 dns_dbnode_t *node = NULL; 9490 dns_dbversion_t *version = NULL; 9491 dns_diff_t _sig_diff; 9492 dns_diff_t post_diff; 9493 dns__zonediff_t zonediff; 9494 dns_fixedname_t fixed; 9495 dns_fixedname_t nextfixed; 9496 dns_kasp_t *kasp; 9497 dns_name_t *name, *nextname; 9498 dns_rdataset_t rdataset; 9499 dns_signing_t *signing, *nextsigning; 9500 dns_signinglist_t cleanup; 9501 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 9502 int32_t signatures; 9503 bool check_ksk, keyset_kskonly, is_ksk, is_zsk; 9504 bool with_ksk, with_zsk; 9505 bool commit = false; 9506 bool is_bottom_of_zone; 9507 bool build_nsec = false; 9508 bool build_nsec3 = false; 9509 bool use_kasp = false; 9510 bool first; 9511 isc_result_t result; 9512 isc_stdtime_t now, inception, soaexpire, expire; 9513 uint32_t jitter, sigvalidityinterval, expiryinterval; 9514 unsigned int i, j; 9515 unsigned int nkeys = 0; 9516 uint32_t nodes; 9517 9518 ENTER; 9519 9520 dns_rdataset_init(&rdataset); 9521 name = dns_fixedname_initname(&fixed); 9522 nextname = dns_fixedname_initname(&nextfixed); 9523 dns_diff_init(zone->mctx, &_sig_diff); 9524 dns_diff_init(zone->mctx, &post_diff); 9525 zonediff_init(&zonediff, &_sig_diff); 9526 ISC_LIST_INIT(cleanup); 9527 9528 /* 9529 * Updates are disabled. Pause for 1 minute. 9530 */ 9531 if (zone->update_disabled) { 9532 result = ISC_R_FAILURE; 9533 goto cleanup; 9534 } 9535 9536 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9537 if (zone->db != NULL) { 9538 dns_db_attach(zone->db, &db); 9539 } 9540 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9541 if (db == NULL) { 9542 result = ISC_R_FAILURE; 9543 goto cleanup; 9544 } 9545 9546 result = dns_db_newversion(db, &version); 9547 if (result != ISC_R_SUCCESS) { 9548 dnssec_log(zone, ISC_LOG_ERROR, 9549 "zone_sign:dns_db_newversion -> %s", 9550 isc_result_totext(result)); 9551 goto cleanup; 9552 } 9553 9554 isc_stdtime_get(&now); 9555 9556 result = dns__zone_findkeys(zone, db, version, now, zone->mctx, 9557 DNS_MAXZONEKEYS, zone_keys, &nkeys); 9558 if (result != ISC_R_SUCCESS) { 9559 dnssec_log(zone, ISC_LOG_ERROR, 9560 "zone_sign:dns__zone_findkeys -> %s", 9561 isc_result_totext(result)); 9562 goto cleanup; 9563 } 9564 9565 kasp = dns_zone_getkasp(zone); 9566 sigvalidityinterval = dns_zone_getsigvalidityinterval(zone); 9567 inception = now - 3600; /* Allow for clock skew. */ 9568 soaexpire = now + sigvalidityinterval; 9569 expiryinterval = dns_zone_getsigresigninginterval(zone); 9570 if (expiryinterval > sigvalidityinterval) { 9571 expiryinterval = sigvalidityinterval; 9572 } else { 9573 expiryinterval = sigvalidityinterval - expiryinterval; 9574 } 9575 9576 /* 9577 * Spread out signatures over time if they happen to be 9578 * clumped. We don't do this for each add_sigs() call as 9579 * we still want some clustering to occur. 9580 */ 9581 if (sigvalidityinterval >= 3600U) { 9582 if (sigvalidityinterval > 7200U) { 9583 jitter = isc_random_uniform(expiryinterval); 9584 } else { 9585 jitter = isc_random_uniform(1200); 9586 } 9587 expire = soaexpire - jitter - 1; 9588 } else { 9589 expire = soaexpire - 1; 9590 } 9591 9592 /* 9593 * We keep pulling nodes off each iterator in turn until 9594 * we have no more nodes to pull off or we reach the limits 9595 * for this quantum. 9596 */ 9597 nodes = zone->nodes; 9598 signatures = zone->signatures; 9599 signing = ISC_LIST_HEAD(zone->signing); 9600 first = true; 9601 9602 if (dns_zone_getkasp(zone) != NULL) { 9603 check_ksk = false; 9604 keyset_kskonly = true; 9605 use_kasp = true; 9606 } else { 9607 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 9608 keyset_kskonly = DNS_ZONE_OPTION(zone, 9609 DNS_ZONEOPT_DNSKEYKSKONLY); 9610 } 9611 dnssec_log(zone, ISC_LOG_DEBUG(3), "zone_sign:use kasp -> %s", 9612 use_kasp ? "yes" : "no"); 9613 9614 /* Determine which type of chain to build */ 9615 CHECK(dns_private_chains(db, version, zone->privatetype, &build_nsec, 9616 &build_nsec3)); 9617 if (!build_nsec && !build_nsec3) { 9618 if (use_kasp) { 9619 build_nsec3 = dns_kasp_nsec3(kasp); 9620 if (!dns_zone_check_dnskey_nsec3( 9621 zone, db, version, NULL, 9622 (dst_key_t **)&zone_keys, nkeys)) 9623 { 9624 dnssec_log(zone, ISC_LOG_INFO, 9625 "wait building NSEC3 chain until " 9626 "NSEC only DNSKEYs are removed"); 9627 build_nsec3 = false; 9628 } 9629 build_nsec = !build_nsec3; 9630 } else { 9631 /* If neither chain is found, default to NSEC */ 9632 build_nsec = true; 9633 } 9634 } 9635 9636 while (signing != NULL && nodes-- > 0 && signatures > 0) { 9637 bool has_alg = false; 9638 9639 dns_dbiterator_pause(signing->dbiterator); 9640 nextsigning = ISC_LIST_NEXT(signing, link); 9641 9642 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9643 if (signing->done || signing->db != zone->db) { 9644 /* 9645 * The zone has been reloaded. We will have to 9646 * created new signings as part of the reload 9647 * process so we can destroy this one. 9648 */ 9649 ISC_LIST_UNLINK(zone->signing, signing, link); 9650 ISC_LIST_APPEND(cleanup, signing, link); 9651 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9652 goto next_signing; 9653 } 9654 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9655 9656 if (signing->db != db) { 9657 goto next_signing; 9658 } 9659 9660 is_bottom_of_zone = false; 9661 9662 if (first && signing->deleteit) { 9663 /* 9664 * Remove the key we are deleting from consideration. 9665 */ 9666 for (i = 0, j = 0; i < nkeys; i++) { 9667 /* 9668 * Find the key we want to remove. 9669 */ 9670 if (ALG(zone_keys[i]) == signing->algorithm && 9671 dst_key_id(zone_keys[i]) == signing->keyid) 9672 { 9673 dst_key_free(&zone_keys[i]); 9674 continue; 9675 } 9676 zone_keys[j] = zone_keys[i]; 9677 j++; 9678 } 9679 for (i = j; i < nkeys; i++) { 9680 zone_keys[i] = NULL; 9681 } 9682 nkeys = j; 9683 } 9684 9685 dns_dbiterator_current(signing->dbiterator, &node, name); 9686 9687 if (signing->deleteit) { 9688 dns_dbiterator_pause(signing->dbiterator); 9689 CHECK(del_sig(db, version, name, node, nkeys, 9690 signing->algorithm, signing->keyid, 9691 &has_alg, zonediff.diff)); 9692 } 9693 9694 /* 9695 * On the first pass we need to check if the current node 9696 * has not been obscured. 9697 */ 9698 if (first) { 9699 dns_fixedname_t ffound; 9700 dns_name_t *found; 9701 found = dns_fixedname_initname(&ffound); 9702 result = dns_db_find( 9703 db, name, version, dns_rdatatype_soa, 9704 DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL); 9705 if ((result == DNS_R_DELEGATION || 9706 result == DNS_R_DNAME) && 9707 !dns_name_equal(name, found)) 9708 { 9709 /* 9710 * Remember the obscuring name so that 9711 * we skip all obscured names. 9712 */ 9713 dns_name_copy(found, name); 9714 is_bottom_of_zone = true; 9715 goto next_node; 9716 } 9717 } 9718 9719 /* 9720 * Process one node. 9721 */ 9722 with_ksk = false; 9723 with_zsk = false; 9724 dns_dbiterator_pause(signing->dbiterator); 9725 9726 CHECK(check_if_bottom_of_zone(db, node, version, 9727 &is_bottom_of_zone)); 9728 9729 for (i = 0; !has_alg && i < nkeys; i++) { 9730 bool both = false; 9731 9732 /* 9733 * Find the keys we want to sign with. 9734 */ 9735 if (!dst_key_isprivate(zone_keys[i])) { 9736 continue; 9737 } 9738 if (dst_key_inactive(zone_keys[i])) { 9739 continue; 9740 } 9741 9742 /* 9743 * When adding look for the specific key. 9744 */ 9745 if (!signing->deleteit && 9746 (dst_key_alg(zone_keys[i]) != signing->algorithm || 9747 dst_key_id(zone_keys[i]) != signing->keyid)) 9748 { 9749 continue; 9750 } 9751 9752 /* 9753 * When deleting make sure we are properly signed 9754 * with the algorithm that was being removed. 9755 */ 9756 if (signing->deleteit && 9757 ALG(zone_keys[i]) != signing->algorithm) 9758 { 9759 continue; 9760 } 9761 9762 /* 9763 * Do we do KSK processing? 9764 */ 9765 if (check_ksk && !REVOKE(zone_keys[i])) { 9766 bool have_ksk, have_nonksk; 9767 if (KSK(zone_keys[i])) { 9768 have_ksk = true; 9769 have_nonksk = false; 9770 } else { 9771 have_ksk = false; 9772 have_nonksk = true; 9773 } 9774 for (j = 0; j < nkeys; j++) { 9775 if (j == i || (ALG(zone_keys[i]) != 9776 ALG(zone_keys[j]))) 9777 { 9778 continue; 9779 } 9780 /* 9781 * Don't consider inactive keys, however 9782 * the key may be temporary offline, so 9783 * do consider KSKs which private key 9784 * files are unavailable. 9785 */ 9786 if (dst_key_inactive(zone_keys[j])) { 9787 continue; 9788 } 9789 if (REVOKE(zone_keys[j])) { 9790 continue; 9791 } 9792 if (KSK(zone_keys[j])) { 9793 have_ksk = true; 9794 } else if (dst_key_isprivate( 9795 zone_keys[j])) 9796 { 9797 have_nonksk = true; 9798 } 9799 both = have_ksk && have_nonksk; 9800 if (both) { 9801 break; 9802 } 9803 } 9804 } 9805 if (use_kasp) { 9806 /* 9807 * A dnssec-policy is found. Check what 9808 * RRsets this key can sign. 9809 */ 9810 isc_result_t kresult; 9811 is_ksk = false; 9812 kresult = dst_key_getbool( 9813 zone_keys[i], DST_BOOL_KSK, &is_ksk); 9814 if (kresult != ISC_R_SUCCESS) { 9815 if (KSK(zone_keys[i])) { 9816 is_ksk = true; 9817 } 9818 } 9819 9820 is_zsk = false; 9821 kresult = dst_key_getbool( 9822 zone_keys[i], DST_BOOL_ZSK, &is_zsk); 9823 if (kresult != ISC_R_SUCCESS) { 9824 if (!KSK(zone_keys[i])) { 9825 is_zsk = true; 9826 } 9827 } 9828 /* Treat as if we have both KSK and ZSK. */ 9829 both = true; 9830 } else if (both || REVOKE(zone_keys[i])) { 9831 is_ksk = KSK(zone_keys[i]); 9832 is_zsk = !KSK(zone_keys[i]); 9833 } else { 9834 is_ksk = false; 9835 is_zsk = true; 9836 } 9837 9838 /* 9839 * If deleting signatures, we need to ensure that 9840 * the RRset is still signed at least once by a 9841 * KSK and a ZSK. 9842 */ 9843 if (signing->deleteit && is_zsk && with_zsk) { 9844 continue; 9845 } 9846 9847 if (signing->deleteit && is_ksk && with_ksk) { 9848 continue; 9849 } 9850 9851 CHECK(sign_a_node( 9852 db, zone, name, node, version, build_nsec3, 9853 build_nsec, zone_keys[i], now, inception, 9854 expire, zone_nsecttl(zone), is_ksk, is_zsk, 9855 (both && keyset_kskonly), is_bottom_of_zone, 9856 zonediff.diff, &signatures, zone->mctx)); 9857 /* 9858 * If we are adding we are done. Look for other keys 9859 * of the same algorithm if deleting. 9860 */ 9861 if (!signing->deleteit) { 9862 break; 9863 } 9864 if (is_zsk) { 9865 with_zsk = true; 9866 } 9867 if (is_ksk) { 9868 with_ksk = true; 9869 } 9870 } 9871 9872 /* 9873 * Go onto next node. 9874 */ 9875 next_node: 9876 first = false; 9877 dns_db_detachnode(db, &node); 9878 do { 9879 result = dns_dbiterator_next(signing->dbiterator); 9880 if (result == ISC_R_NOMORE) { 9881 ISC_LIST_UNLINK(zone->signing, signing, link); 9882 ISC_LIST_APPEND(cleanup, signing, link); 9883 dns_dbiterator_pause(signing->dbiterator); 9884 if (nkeys != 0 && build_nsec) { 9885 /* 9886 * We have finished regenerating the 9887 * zone with a zone signing key. 9888 * The NSEC chain is now complete and 9889 * there is a full set of signatures 9890 * for the zone. We can now clear the 9891 * OPT bit from the NSEC record. 9892 */ 9893 result = updatesecure( 9894 db, version, &zone->origin, 9895 zone_nsecttl(zone), false, 9896 &post_diff); 9897 if (result != ISC_R_SUCCESS) { 9898 dnssec_log(zone, ISC_LOG_ERROR, 9899 "updatesecure -> %s", 9900 isc_result_totext( 9901 result)); 9902 goto cleanup; 9903 } 9904 } 9905 result = updatesignwithkey( 9906 zone, signing, version, build_nsec3, 9907 zone_nsecttl(zone), &post_diff); 9908 if (result != ISC_R_SUCCESS) { 9909 dnssec_log(zone, ISC_LOG_ERROR, 9910 "updatesignwithkey -> %s", 9911 isc_result_totext(result)); 9912 goto cleanup; 9913 } 9914 build_nsec = false; 9915 goto next_signing; 9916 } else if (result != ISC_R_SUCCESS) { 9917 dnssec_log(zone, ISC_LOG_ERROR, 9918 "zone_sign:" 9919 "dns_dbiterator_next -> %s", 9920 isc_result_totext(result)); 9921 goto cleanup; 9922 } else if (is_bottom_of_zone) { 9923 dns_dbiterator_current(signing->dbiterator, 9924 &node, nextname); 9925 dns_db_detachnode(db, &node); 9926 if (!dns_name_issubdomain(nextname, name)) { 9927 break; 9928 } 9929 } else { 9930 break; 9931 } 9932 } while (1); 9933 continue; 9934 9935 next_signing: 9936 dns_dbiterator_pause(signing->dbiterator); 9937 signing = nextsigning; 9938 first = true; 9939 } 9940 9941 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) { 9942 result = dns__zone_updatesigs(&post_diff, db, version, 9943 zone_keys, nkeys, zone, inception, 9944 expire, 0, now, check_ksk, 9945 keyset_kskonly, &zonediff); 9946 if (result != ISC_R_SUCCESS) { 9947 dnssec_log(zone, ISC_LOG_ERROR, 9948 "zone_sign:dns__zone_updatesigs -> %s", 9949 isc_result_totext(result)); 9950 goto cleanup; 9951 } 9952 } 9953 9954 /* 9955 * Have we changed anything? 9956 */ 9957 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 9958 if (zonediff.offline) { 9959 commit = true; 9960 } 9961 result = ISC_R_SUCCESS; 9962 goto pauseall; 9963 } 9964 9965 commit = true; 9966 9967 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 9968 &zonediff, zone_keys, nkeys, now, false); 9969 if (result != ISC_R_SUCCESS) { 9970 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:del_sigs -> %s", 9971 isc_result_totext(result)); 9972 goto cleanup; 9973 } 9974 9975 result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx, 9976 zone->updatemethod); 9977 if (result != ISC_R_SUCCESS) { 9978 dnssec_log(zone, ISC_LOG_ERROR, 9979 "zone_sign:update_soa_serial -> %s", 9980 isc_result_totext(result)); 9981 goto cleanup; 9982 } 9983 9984 /* 9985 * Generate maximum life time signatures so that the above loop 9986 * termination is sensible. 9987 */ 9988 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa, 9989 zonediff.diff, zone_keys, nkeys, zone->mctx, now, 9990 inception, soaexpire, check_ksk, keyset_kskonly); 9991 if (result != ISC_R_SUCCESS) { 9992 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:add_sigs -> %s", 9993 isc_result_totext(result)); 9994 goto cleanup; 9995 } 9996 9997 /* 9998 * Write changes to journal file. 9999 */ 10000 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign")); 10001 10002pauseall: 10003 /* 10004 * Pause all iterators so that dns_db_closeversion() can succeed. 10005 */ 10006 for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; 10007 signing = ISC_LIST_NEXT(signing, link)) 10008 { 10009 dns_dbiterator_pause(signing->dbiterator); 10010 } 10011 10012 for (signing = ISC_LIST_HEAD(cleanup); signing != NULL; 10013 signing = ISC_LIST_NEXT(signing, link)) 10014 { 10015 dns_dbiterator_pause(signing->dbiterator); 10016 } 10017 10018 /* 10019 * Everything has succeeded. Commit the changes. 10020 */ 10021 dns_db_closeversion(db, &version, commit); 10022 10023 /* 10024 * Everything succeeded so we can clean these up now. 10025 */ 10026 signing = ISC_LIST_HEAD(cleanup); 10027 while (signing != NULL) { 10028 ISC_LIST_UNLINK(cleanup, signing, link); 10029 dns_db_detach(&signing->db); 10030 dns_dbiterator_destroy(&signing->dbiterator); 10031 isc_mem_put(zone->mctx, signing, sizeof *signing); 10032 signing = ISC_LIST_HEAD(cleanup); 10033 } 10034 10035 LOCK_ZONE(zone); 10036 set_resigntime(zone); 10037 if (commit) { 10038 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 10039 zone_needdump(zone, DNS_DUMP_DELAY); 10040 } 10041 UNLOCK_ZONE(zone); 10042 10043failure: 10044 if (result != ISC_R_SUCCESS) { 10045 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign: failed: %s", 10046 isc_result_totext(result)); 10047 } 10048 10049cleanup: 10050 /* 10051 * Pause all dbiterators. 10052 */ 10053 for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL; 10054 signing = ISC_LIST_NEXT(signing, link)) 10055 { 10056 dns_dbiterator_pause(signing->dbiterator); 10057 } 10058 10059 /* 10060 * Rollback the cleanup list. 10061 */ 10062 signing = ISC_LIST_HEAD(cleanup); 10063 while (signing != NULL) { 10064 ISC_LIST_UNLINK(cleanup, signing, link); 10065 ISC_LIST_PREPEND(zone->signing, signing, link); 10066 dns_dbiterator_first(signing->dbiterator); 10067 dns_dbiterator_pause(signing->dbiterator); 10068 signing = ISC_LIST_HEAD(cleanup); 10069 } 10070 10071 dns_diff_clear(&_sig_diff); 10072 10073 for (i = 0; i < nkeys; i++) { 10074 dst_key_free(&zone_keys[i]); 10075 } 10076 10077 if (node != NULL) { 10078 dns_db_detachnode(db, &node); 10079 } 10080 10081 if (version != NULL) { 10082 dns_db_closeversion(db, &version, false); 10083 dns_db_detach(&db); 10084 } else if (db != NULL) { 10085 dns_db_detach(&db); 10086 } 10087 10088 LOCK_ZONE(zone); 10089 if (ISC_LIST_HEAD(zone->signing) != NULL) { 10090 isc_interval_t interval; 10091 if (zone->update_disabled || result != ISC_R_SUCCESS) { 10092 isc_interval_set(&interval, 60, 0); /* 1 minute */ 10093 } else { 10094 isc_interval_set(&interval, 0, 10000000); /* 10 ms */ 10095 } 10096 isc_time_nowplusinterval(&zone->signingtime, &interval); 10097 } else { 10098 isc_time_settoepoch(&zone->signingtime); 10099 } 10100 UNLOCK_ZONE(zone); 10101 10102 INSIST(version == NULL); 10103} 10104 10105static isc_result_t 10106normalize_key(dns_rdata_t *rr, dns_rdata_t *target, unsigned char *data, 10107 int size) { 10108 dns_rdata_dnskey_t dnskey; 10109 dns_rdata_keydata_t keydata; 10110 isc_buffer_t buf; 10111 isc_result_t result; 10112 10113 dns_rdata_reset(target); 10114 isc_buffer_init(&buf, data, size); 10115 10116 switch (rr->type) { 10117 case dns_rdatatype_dnskey: 10118 result = dns_rdata_tostruct(rr, &dnskey, NULL); 10119 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10120 dnskey.flags &= ~DNS_KEYFLAG_REVOKE; 10121 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 10122 &dnskey, &buf); 10123 break; 10124 case dns_rdatatype_keydata: 10125 result = dns_rdata_tostruct(rr, &keydata, NULL); 10126 if (result == ISC_R_UNEXPECTEDEND) { 10127 return (result); 10128 } 10129 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10130 dns_keydata_todnskey(&keydata, &dnskey, NULL); 10131 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 10132 &dnskey, &buf); 10133 break; 10134 default: 10135 UNREACHABLE(); 10136 } 10137 return (ISC_R_SUCCESS); 10138} 10139 10140/* 10141 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or 10142 * a KEYDATA rdataset from the key zone. 10143 * 10144 * 'rr' contains either a DNSKEY record, or a KEYDATA record 10145 * 10146 * After normalizing keys to the same format (DNSKEY, with revoke bit 10147 * cleared), return true if a key that matches 'rr' is found in 10148 * 'rdset', or false if not. 10149 */ 10150 10151static bool 10152matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) { 10153 unsigned char data1[4096], data2[4096]; 10154 dns_rdata_t rdata, rdata1, rdata2; 10155 isc_result_t result; 10156 10157 dns_rdata_init(&rdata); 10158 dns_rdata_init(&rdata1); 10159 dns_rdata_init(&rdata2); 10160 10161 result = normalize_key(rr, &rdata1, data1, sizeof(data1)); 10162 if (result != ISC_R_SUCCESS) { 10163 return (false); 10164 } 10165 10166 for (result = dns_rdataset_first(rdset); result == ISC_R_SUCCESS; 10167 result = dns_rdataset_next(rdset)) 10168 { 10169 dns_rdata_reset(&rdata); 10170 dns_rdataset_current(rdset, &rdata); 10171 result = normalize_key(&rdata, &rdata2, data2, sizeof(data2)); 10172 if (result != ISC_R_SUCCESS) { 10173 continue; 10174 } 10175 if (dns_rdata_compare(&rdata1, &rdata2) == 0) { 10176 return (true); 10177 } 10178 } 10179 10180 return (false); 10181} 10182 10183/* 10184 * Calculate the refresh interval for a keydata zone, per 10185 * RFC5011: MAX(1 hr, 10186 * MIN(15 days, 10187 * 1/2 * OrigTTL, 10188 * 1/2 * RRSigExpirationInterval)) 10189 * or for retries: MAX(1 hr, 10190 * MIN(1 day, 10191 * 1/10 * OrigTTL, 10192 * 1/10 * RRSigExpirationInterval)) 10193 */ 10194static isc_stdtime_t 10195refresh_time(dns_keyfetch_t *kfetch, bool retry) { 10196 isc_result_t result; 10197 uint32_t t; 10198 dns_rdataset_t *rdset; 10199 dns_rdata_t sigrr = DNS_RDATA_INIT; 10200 dns_rdata_sig_t sig; 10201 isc_stdtime_t now; 10202 10203 isc_stdtime_get(&now); 10204 10205 if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) { 10206 rdset = &kfetch->dnskeysigset; 10207 } else { 10208 return (now + dns_zone_mkey_hour); 10209 } 10210 10211 result = dns_rdataset_first(rdset); 10212 if (result != ISC_R_SUCCESS) { 10213 return (now + dns_zone_mkey_hour); 10214 } 10215 10216 dns_rdataset_current(rdset, &sigrr); 10217 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 10218 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10219 10220 if (!retry) { 10221 t = sig.originalttl / 2; 10222 10223 if (isc_serial_gt(sig.timeexpire, now)) { 10224 uint32_t exp = (sig.timeexpire - now) / 2; 10225 if (t > exp) { 10226 t = exp; 10227 } 10228 } 10229 10230 if (t > (15 * dns_zone_mkey_day)) { 10231 t = (15 * dns_zone_mkey_day); 10232 } 10233 10234 if (t < dns_zone_mkey_hour) { 10235 t = dns_zone_mkey_hour; 10236 } 10237 } else { 10238 t = sig.originalttl / 10; 10239 10240 if (isc_serial_gt(sig.timeexpire, now)) { 10241 uint32_t exp = (sig.timeexpire - now) / 10; 10242 if (t > exp) { 10243 t = exp; 10244 } 10245 } 10246 10247 if (t > dns_zone_mkey_day) { 10248 t = dns_zone_mkey_day; 10249 } 10250 10251 if (t < dns_zone_mkey_hour) { 10252 t = dns_zone_mkey_hour; 10253 } 10254 } 10255 10256 return (now + t); 10257} 10258 10259/* 10260 * This routine is called when no changes are needed in a KEYDATA 10261 * record except to simply update the refresh timer. Caller should 10262 * hold zone lock. 10263 */ 10264static isc_result_t 10265minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) { 10266 isc_result_t result; 10267 isc_buffer_t keyb; 10268 unsigned char key_buf[4096]; 10269 dns_rdata_t rdata = DNS_RDATA_INIT; 10270 dns_rdata_keydata_t keydata; 10271 dns_name_t *name; 10272 dns_zone_t *zone = kfetch->zone; 10273 isc_stdtime_t now; 10274 10275 name = dns_fixedname_name(&kfetch->name); 10276 isc_stdtime_get(&now); 10277 10278 for (result = dns_rdataset_first(&kfetch->keydataset); 10279 result == ISC_R_SUCCESS; 10280 result = dns_rdataset_next(&kfetch->keydataset)) 10281 { 10282 dns_rdata_reset(&rdata); 10283 dns_rdataset_current(&kfetch->keydataset, &rdata); 10284 10285 /* Delete old version */ 10286 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL, name, 10287 0, &rdata)); 10288 10289 /* Update refresh timer */ 10290 result = dns_rdata_tostruct(&rdata, &keydata, NULL); 10291 if (result == ISC_R_UNEXPECTEDEND) { 10292 continue; 10293 } 10294 if (result != ISC_R_SUCCESS) { 10295 goto failure; 10296 } 10297 keydata.refresh = refresh_time(kfetch, true); 10298 set_refreshkeytimer(zone, &keydata, now, false); 10299 10300 dns_rdata_reset(&rdata); 10301 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10302 CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass, 10303 dns_rdatatype_keydata, &keydata, 10304 &keyb)); 10305 10306 /* Insert updated version */ 10307 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD, name, 10308 0, &rdata)); 10309 } 10310 result = ISC_R_SUCCESS; 10311failure: 10312 return (result); 10313} 10314 10315/* 10316 * Verify that DNSKEY set is signed by the key specified in 'keydata'. 10317 */ 10318static bool 10319revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) { 10320 isc_result_t result; 10321 dns_name_t *keyname; 10322 isc_mem_t *mctx; 10323 dns_rdata_t sigrr = DNS_RDATA_INIT; 10324 dns_rdata_t rr = DNS_RDATA_INIT; 10325 dns_rdata_rrsig_t sig; 10326 dns_rdata_dnskey_t dnskey; 10327 dst_key_t *dstkey = NULL; 10328 unsigned char key_buf[4096]; 10329 isc_buffer_t keyb; 10330 bool answer = false; 10331 10332 REQUIRE(kfetch != NULL && keydata != NULL); 10333 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset)); 10334 10335 keyname = dns_fixedname_name(&kfetch->name); 10336 mctx = kfetch->zone->view->mctx; 10337 10338 /* Generate a key from keydata */ 10339 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10340 dns_keydata_todnskey(keydata, &dnskey, NULL); 10341 dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey, 10342 &dnskey, &keyb); 10343 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey); 10344 if (result != ISC_R_SUCCESS) { 10345 return (false); 10346 } 10347 10348 /* See if that key generated any of the signatures */ 10349 for (result = dns_rdataset_first(&kfetch->dnskeysigset); 10350 result == ISC_R_SUCCESS; 10351 result = dns_rdataset_next(&kfetch->dnskeysigset)) 10352 { 10353 dns_fixedname_t fixed; 10354 dns_fixedname_init(&fixed); 10355 10356 dns_rdata_reset(&sigrr); 10357 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr); 10358 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 10359 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10360 10361 if (dst_key_alg(dstkey) == sig.algorithm && 10362 dst_key_rid(dstkey) == sig.keyid) 10363 { 10364 result = dns_dnssec_verify( 10365 keyname, &kfetch->dnskeyset, dstkey, false, 0, 10366 mctx, &sigrr, dns_fixedname_name(&fixed)); 10367 10368 dnssec_log(kfetch->zone, ISC_LOG_DEBUG(3), 10369 "Confirm revoked DNSKEY is self-signed: %s", 10370 isc_result_totext(result)); 10371 10372 if (result == ISC_R_SUCCESS) { 10373 answer = true; 10374 break; 10375 } 10376 } 10377 } 10378 10379 dst_key_free(&dstkey); 10380 return (answer); 10381} 10382 10383/* 10384 * A DNSKEY set has been fetched from the zone apex of a zone whose trust 10385 * anchors are being managed; scan the keyset, and update the key zone and the 10386 * local trust anchors according to RFC5011. 10387 */ 10388static void 10389keyfetch_done(isc_task_t *task, isc_event_t *event) { 10390 isc_result_t result, eresult; 10391 dns_fetchevent_t *devent; 10392 dns_keyfetch_t *kfetch; 10393 dns_zone_t *zone; 10394 isc_mem_t *mctx = NULL; 10395 dns_keytable_t *secroots = NULL; 10396 dns_dbversion_t *ver = NULL; 10397 dns_diff_t diff; 10398 bool alldone = false; 10399 bool commit = false; 10400 dns_name_t *keyname = NULL; 10401 dns_rdata_t sigrr = DNS_RDATA_INIT; 10402 dns_rdata_t dnskeyrr = DNS_RDATA_INIT; 10403 dns_rdata_t keydatarr = DNS_RDATA_INIT; 10404 dns_rdata_rrsig_t sig; 10405 dns_rdata_dnskey_t dnskey; 10406 dns_rdata_keydata_t keydata; 10407 bool initializing; 10408 char namebuf[DNS_NAME_FORMATSIZE]; 10409 unsigned char key_buf[4096]; 10410 isc_buffer_t keyb; 10411 dst_key_t *dstkey = NULL; 10412 isc_stdtime_t now; 10413 int pending = 0; 10414 bool secure = false, initial = false; 10415 bool free_needed; 10416 dns_keynode_t *keynode = NULL; 10417 dns_rdataset_t *dnskeys = NULL, *dnskeysigs = NULL; 10418 dns_rdataset_t *keydataset = NULL, dsset; 10419 10420 UNUSED(task); 10421 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE); 10422 INSIST(event->ev_arg != NULL); 10423 10424 kfetch = event->ev_arg; 10425 zone = kfetch->zone; 10426 mctx = kfetch->mctx; 10427 keyname = dns_fixedname_name(&kfetch->name); 10428 dnskeys = &kfetch->dnskeyset; 10429 dnskeysigs = &kfetch->dnskeysigset; 10430 keydataset = &kfetch->keydataset; 10431 10432 devent = (dns_fetchevent_t *)event; 10433 eresult = devent->result; 10434 10435 /* Free resources which are not of interest */ 10436 if (devent->node != NULL) { 10437 dns_db_detachnode(devent->db, &devent->node); 10438 } 10439 if (devent->db != NULL) { 10440 dns_db_detach(&devent->db); 10441 } 10442 isc_event_free(&event); 10443 dns_resolver_destroyfetch(&kfetch->fetch); 10444 10445 LOCK_ZONE(zone); 10446 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) { 10447 goto cleanup; 10448 } 10449 10450 isc_stdtime_get(&now); 10451 dns_name_format(keyname, namebuf, sizeof(namebuf)); 10452 10453 result = dns_view_getsecroots(zone->view, &secroots); 10454 INSIST(result == ISC_R_SUCCESS); 10455 10456 dns_diff_init(mctx, &diff); 10457 10458 CHECK(dns_db_newversion(kfetch->db, &ver)); 10459 10460 zone->refreshkeycount--; 10461 alldone = (zone->refreshkeycount == 0); 10462 10463 if (alldone) { 10464 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 10465 } 10466 10467 dnssec_log(zone, ISC_LOG_DEBUG(3), 10468 "Returned from key fetch in keyfetch_done() for '%s': %s", 10469 namebuf, isc_result_totext(eresult)); 10470 10471 /* Fetch failed */ 10472 if (eresult != ISC_R_SUCCESS || !dns_rdataset_isassociated(dnskeys)) { 10473 dnssec_log(zone, ISC_LOG_WARNING, 10474 "Unable to fetch DNSKEY set '%s': %s", namebuf, 10475 isc_result_totext(eresult)); 10476 CHECK(minimal_update(kfetch, ver, &diff)); 10477 goto done; 10478 } 10479 10480 /* No RRSIGs found */ 10481 if (!dns_rdataset_isassociated(dnskeysigs)) { 10482 dnssec_log(zone, ISC_LOG_WARNING, 10483 "No DNSKEY RRSIGs found for '%s': %s", namebuf, 10484 isc_result_totext(eresult)); 10485 CHECK(minimal_update(kfetch, ver, &diff)); 10486 goto done; 10487 } 10488 10489 /* 10490 * Clear any cached trust level, as we need to run validation 10491 * over again; trusted keys might have changed. 10492 */ 10493 dnskeys->trust = dnskeysigs->trust = dns_trust_none; 10494 10495 /* Look up the trust anchor */ 10496 result = dns_keytable_find(secroots, keyname, &keynode); 10497 if (result != ISC_R_SUCCESS) { 10498 goto anchors_done; 10499 } 10500 10501 /* 10502 * If the keynode has a DS trust anchor, use it for verification. 10503 */ 10504 dns_rdataset_init(&dsset); 10505 if (dns_keynode_dsset(keynode, &dsset)) { 10506 for (result = dns_rdataset_first(dnskeysigs); 10507 result == ISC_R_SUCCESS; 10508 result = dns_rdataset_next(dnskeysigs)) 10509 { 10510 isc_result_t tresult; 10511 dns_rdata_t keyrdata = DNS_RDATA_INIT; 10512 10513 dns_rdata_reset(&sigrr); 10514 dns_rdataset_current(dnskeysigs, &sigrr); 10515 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 10516 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10517 10518 for (tresult = dns_rdataset_first(&dsset); 10519 tresult == ISC_R_SUCCESS; 10520 tresult = dns_rdataset_next(&dsset)) 10521 { 10522 dns_rdata_t dsrdata = DNS_RDATA_INIT; 10523 dns_rdata_ds_t ds; 10524 10525 dns_rdata_reset(&dsrdata); 10526 dns_rdataset_current(&dsset, &dsrdata); 10527 tresult = dns_rdata_tostruct(&dsrdata, &ds, 10528 NULL); 10529 RUNTIME_CHECK(tresult == ISC_R_SUCCESS); 10530 10531 if (ds.key_tag != sig.keyid || 10532 ds.algorithm != sig.algorithm) 10533 { 10534 continue; 10535 } 10536 10537 result = dns_dnssec_matchdskey( 10538 keyname, &dsrdata, dnskeys, &keyrdata); 10539 if (result == ISC_R_SUCCESS) { 10540 break; 10541 } 10542 } 10543 10544 if (tresult == ISC_R_NOMORE) { 10545 continue; 10546 } 10547 10548 result = dns_dnssec_keyfromrdata(keyname, &keyrdata, 10549 mctx, &dstkey); 10550 if (result != ISC_R_SUCCESS) { 10551 continue; 10552 } 10553 10554 result = dns_dnssec_verify(keyname, dnskeys, dstkey, 10555 false, 0, mctx, &sigrr, 10556 NULL); 10557 dst_key_free(&dstkey); 10558 10559 dnssec_log(zone, ISC_LOG_DEBUG(3), 10560 "Verifying DNSKEY set for zone " 10561 "'%s' using DS %d/%d: %s", 10562 namebuf, sig.keyid, sig.algorithm, 10563 isc_result_totext(result)); 10564 10565 if (result == ISC_R_SUCCESS) { 10566 dnskeys->trust = dns_trust_secure; 10567 dnskeysigs->trust = dns_trust_secure; 10568 initial = dns_keynode_initial(keynode); 10569 dns_keynode_trust(keynode); 10570 secure = true; 10571 break; 10572 } 10573 } 10574 dns_rdataset_disassociate(&dsset); 10575 } 10576 10577anchors_done: 10578 if (keynode != NULL) { 10579 dns_keytable_detachkeynode(secroots, &keynode); 10580 } 10581 10582 /* 10583 * If we were not able to verify the answer using the current 10584 * trusted keys then all we can do is look at any revoked keys. 10585 */ 10586 if (!secure) { 10587 dnssec_log(zone, ISC_LOG_INFO, 10588 "DNSKEY set for zone '%s' could not be verified " 10589 "with current keys", 10590 namebuf); 10591 } 10592 10593 /* 10594 * First scan keydataset to find keys that are not in dnskeyset 10595 * - Missing keys which are not scheduled for removal, 10596 * log a warning 10597 * - Missing keys which are scheduled for removal and 10598 * the remove hold-down timer has completed should 10599 * be removed from the key zone 10600 * - Missing keys whose acceptance timers have not yet 10601 * completed, log a warning and reset the acceptance 10602 * timer to 30 days in the future 10603 * - All keys not being removed have their refresh timers 10604 * updated 10605 */ 10606 initializing = true; 10607 for (result = dns_rdataset_first(keydataset); result == ISC_R_SUCCESS; 10608 result = dns_rdataset_next(keydataset)) 10609 { 10610 dns_keytag_t keytag; 10611 10612 dns_rdata_reset(&keydatarr); 10613 dns_rdataset_current(keydataset, &keydatarr); 10614 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); 10615 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10616 10617 dns_keydata_todnskey(&keydata, &dnskey, NULL); 10618 result = compute_tag(keyname, &dnskey, mctx, &keytag); 10619 if (result != ISC_R_SUCCESS) { 10620 /* 10621 * Skip if we cannot compute the key tag. 10622 * This may happen if the algorithm is unsupported 10623 */ 10624 dns_zone_log(zone, ISC_LOG_ERROR, 10625 "Cannot compute tag for key in zone %s: " 10626 "%s " 10627 "(skipping)", 10628 namebuf, isc_result_totext(result)); 10629 continue; 10630 } 10631 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10632 10633 /* 10634 * If any keydata record has a nonzero add holddown, then 10635 * there was a pre-existing trust anchor for this domain; 10636 * that means we are *not* initializing it and shouldn't 10637 * automatically trust all the keys we find at the zone apex. 10638 */ 10639 initializing = initializing && (keydata.addhd == 0); 10640 10641 if (!matchkey(dnskeys, &keydatarr)) { 10642 bool deletekey = false; 10643 10644 if (!secure) { 10645 if (keydata.removehd != 0 && 10646 keydata.removehd <= now) 10647 { 10648 deletekey = true; 10649 } 10650 } else if (keydata.addhd == 0) { 10651 deletekey = true; 10652 } else if (keydata.addhd > now) { 10653 dnssec_log(zone, ISC_LOG_INFO, 10654 "Pending key %d for zone %s " 10655 "unexpectedly missing from DNSKEY " 10656 "RRset: restarting 30-day " 10657 "acceptance timer", 10658 keytag, namebuf); 10659 if (keydata.addhd < now + dns_zone_mkey_month) { 10660 keydata.addhd = now + 10661 dns_zone_mkey_month; 10662 } 10663 keydata.refresh = refresh_time(kfetch, false); 10664 } else if (keydata.removehd == 0) { 10665 dnssec_log(zone, ISC_LOG_INFO, 10666 "Active key %d for zone %s " 10667 "unexpectedly missing from DNSKEY " 10668 "RRset", 10669 keytag, namebuf); 10670 keydata.refresh = now + dns_zone_mkey_hour; 10671 } else if (keydata.removehd <= now) { 10672 deletekey = true; 10673 dnssec_log( 10674 zone, ISC_LOG_INFO, 10675 "Revoked key %d for zone %s no longer " 10676 "present in DNSKEY RRset: deleting " 10677 "from managed keys database", 10678 keytag, namebuf); 10679 } else { 10680 keydata.refresh = refresh_time(kfetch, false); 10681 } 10682 10683 if (secure || deletekey) { 10684 /* Delete old version */ 10685 CHECK(update_one_rr(kfetch->db, ver, &diff, 10686 DNS_DIFFOP_DEL, keyname, 0, 10687 &keydatarr)); 10688 } 10689 10690 if (!secure || deletekey) { 10691 continue; 10692 } 10693 10694 dns_rdata_reset(&keydatarr); 10695 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10696 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 10697 dns_rdatatype_keydata, &keydata, 10698 &keyb); 10699 10700 /* Insert updated version */ 10701 CHECK(update_one_rr(kfetch->db, ver, &diff, 10702 DNS_DIFFOP_ADD, keyname, 0, 10703 &keydatarr)); 10704 10705 set_refreshkeytimer(zone, &keydata, now, false); 10706 } 10707 } 10708 10709 /* 10710 * Next scan dnskeyset: 10711 * - If new keys are found (i.e., lacking a match in keydataset) 10712 * add them to the key zone and set the acceptance timer 10713 * to 30 days in the future (or to immediately if we've 10714 * determined that we're initializing the zone for the 10715 * first time) 10716 * - Previously-known keys that have been revoked 10717 * must be scheduled for removal from the key zone (or, 10718 * if they hadn't been accepted as trust anchors yet 10719 * anyway, removed at once) 10720 * - Previously-known unrevoked keys whose acceptance timers 10721 * have completed are promoted to trust anchors 10722 * - All keys not being removed have their refresh 10723 * timers updated 10724 */ 10725 for (result = dns_rdataset_first(dnskeys); result == ISC_R_SUCCESS; 10726 result = dns_rdataset_next(dnskeys)) 10727 { 10728 bool revoked = false; 10729 bool newkey = false; 10730 bool updatekey = false; 10731 bool deletekey = false; 10732 bool trustkey = false; 10733 dns_keytag_t keytag; 10734 10735 dns_rdata_reset(&dnskeyrr); 10736 dns_rdataset_current(dnskeys, &dnskeyrr); 10737 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 10738 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10739 10740 /* Skip ZSK's */ 10741 if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) { 10742 continue; 10743 } 10744 10745 result = compute_tag(keyname, &dnskey, mctx, &keytag); 10746 if (result != ISC_R_SUCCESS) { 10747 /* 10748 * Skip if we cannot compute the key tag. 10749 * This may happen if the algorithm is unsupported 10750 */ 10751 dns_zone_log(zone, ISC_LOG_ERROR, 10752 "Cannot compute tag for key in zone %s: " 10753 "%s " 10754 "(skipping)", 10755 namebuf, isc_result_totext(result)); 10756 continue; 10757 } 10758 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10759 10760 revoked = ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0); 10761 10762 if (matchkey(keydataset, &dnskeyrr)) { 10763 dns_rdata_reset(&keydatarr); 10764 dns_rdataset_current(keydataset, &keydatarr); 10765 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); 10766 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10767 10768 if (revoked && revocable(kfetch, &keydata)) { 10769 if (keydata.addhd > now) { 10770 /* 10771 * Key wasn't trusted yet, and now 10772 * it's been revoked? Just remove it 10773 */ 10774 deletekey = true; 10775 dnssec_log(zone, ISC_LOG_INFO, 10776 "Pending key %d for " 10777 "zone %s is now revoked: " 10778 "deleting from the " 10779 "managed keys database", 10780 keytag, namebuf); 10781 } else if (keydata.removehd == 0) { 10782 /* 10783 * Remove key from secroots. 10784 */ 10785 dns_view_untrust(zone->view, keyname, 10786 &dnskey); 10787 10788 /* If initializing, delete now */ 10789 if (keydata.addhd == 0) { 10790 deletekey = true; 10791 } else { 10792 keydata.removehd = 10793 now + 10794 dns_zone_mkey_month; 10795 keydata.flags |= 10796 DNS_KEYFLAG_REVOKE; 10797 } 10798 10799 dnssec_log(zone, ISC_LOG_INFO, 10800 "Trusted key %d for " 10801 "zone %s is now revoked", 10802 keytag, namebuf); 10803 } else if (keydata.removehd < now) { 10804 /* Scheduled for removal */ 10805 deletekey = true; 10806 10807 dnssec_log(zone, ISC_LOG_INFO, 10808 "Revoked key %d for " 10809 "zone %s removal timer " 10810 "complete: deleting from " 10811 "the managed keys database", 10812 keytag, namebuf); 10813 } 10814 } else if (revoked && keydata.removehd == 0) { 10815 dnssec_log(zone, ISC_LOG_WARNING, 10816 "Active key %d for zone " 10817 "%s is revoked but " 10818 "did not self-sign; " 10819 "ignoring", 10820 keytag, namebuf); 10821 continue; 10822 } else if (secure) { 10823 if (keydata.removehd != 0) { 10824 /* 10825 * Key isn't revoked--but it 10826 * seems it used to be. 10827 * Remove it now and add it 10828 * back as if it were a fresh key, 10829 * with a 30-day acceptance timer. 10830 */ 10831 deletekey = true; 10832 newkey = true; 10833 keydata.removehd = 0; 10834 keydata.addhd = now + 10835 dns_zone_mkey_month; 10836 10837 dnssec_log(zone, ISC_LOG_INFO, 10838 "Revoked key %d for " 10839 "zone %s has returned: " 10840 "starting 30-day " 10841 "acceptance timer", 10842 keytag, namebuf); 10843 } else if (keydata.addhd > now) { 10844 pending++; 10845 } else if (keydata.addhd == 0) { 10846 keydata.addhd = now; 10847 } 10848 10849 if (keydata.addhd <= now) { 10850 trustkey = true; 10851 dnssec_log(zone, ISC_LOG_INFO, 10852 "Key %d for zone %s " 10853 "is now trusted (%s)", 10854 keytag, namebuf, 10855 initial ? "initializing key " 10856 "verified" 10857 : "acceptance timer " 10858 "complete"); 10859 } 10860 } else if (keydata.addhd > now) { 10861 /* 10862 * Not secure, and key is pending: 10863 * reset the acceptance timer 10864 */ 10865 pending++; 10866 keydata.addhd = now + dns_zone_mkey_month; 10867 dnssec_log(zone, ISC_LOG_INFO, 10868 "Pending key %d " 10869 "for zone %s was " 10870 "not validated: restarting " 10871 "30-day acceptance timer", 10872 keytag, namebuf); 10873 } 10874 10875 if (!deletekey && !newkey) { 10876 updatekey = true; 10877 } 10878 } else if (secure) { 10879 /* 10880 * Key wasn't in the key zone but it's 10881 * revoked now anyway, so just skip it 10882 */ 10883 if (revoked) { 10884 continue; 10885 } 10886 10887 /* Key wasn't in the key zone: add it */ 10888 newkey = true; 10889 10890 if (initializing) { 10891 dnssec_log(zone, ISC_LOG_WARNING, 10892 "Initializing automatic trust " 10893 "anchor management for zone '%s'; " 10894 "DNSKEY ID %d is now trusted, " 10895 "waiving the normal 30-day " 10896 "waiting period.", 10897 namebuf, keytag); 10898 trustkey = true; 10899 } else { 10900 dnssec_log(zone, ISC_LOG_INFO, 10901 "New key %d observed " 10902 "for zone '%s': " 10903 "starting 30-day " 10904 "acceptance timer", 10905 keytag, namebuf); 10906 } 10907 } else { 10908 /* 10909 * No previously known key, and the key is not 10910 * secure, so skip it. 10911 */ 10912 continue; 10913 } 10914 10915 /* Delete old version */ 10916 if (deletekey || !newkey) { 10917 CHECK(update_one_rr(kfetch->db, ver, &diff, 10918 DNS_DIFFOP_DEL, keyname, 0, 10919 &keydatarr)); 10920 } 10921 10922 if (updatekey) { 10923 /* Set refresh timer */ 10924 keydata.refresh = refresh_time(kfetch, false); 10925 dns_rdata_reset(&keydatarr); 10926 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10927 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 10928 dns_rdatatype_keydata, &keydata, 10929 &keyb); 10930 10931 /* Insert updated version */ 10932 CHECK(update_one_rr(kfetch->db, ver, &diff, 10933 DNS_DIFFOP_ADD, keyname, 0, 10934 &keydatarr)); 10935 } else if (newkey) { 10936 /* Convert DNSKEY to KEYDATA */ 10937 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 10938 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10939 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0, 10940 NULL); 10941 keydata.addhd = initializing 10942 ? now 10943 : now + dns_zone_mkey_month; 10944 keydata.refresh = refresh_time(kfetch, false); 10945 dns_rdata_reset(&keydatarr); 10946 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 10947 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 10948 dns_rdatatype_keydata, &keydata, 10949 &keyb); 10950 10951 /* Insert into key zone */ 10952 CHECK(update_one_rr(kfetch->db, ver, &diff, 10953 DNS_DIFFOP_ADD, keyname, 0, 10954 &keydatarr)); 10955 } 10956 10957 if (trustkey) { 10958 /* Trust this key. */ 10959 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 10960 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10961 trust_key(zone, keyname, &dnskey, false); 10962 } 10963 10964 if (secure && !deletekey) { 10965 INSIST(newkey || updatekey); 10966 set_refreshkeytimer(zone, &keydata, now, false); 10967 } 10968 } 10969 10970 /* 10971 * RFC5011 says, "A trust point that has all of its trust anchors 10972 * revoked is considered deleted and is treated as if the trust 10973 * point was never configured." But if someone revoked their 10974 * active key before the standby was trusted, that would mean the 10975 * zone would suddenly be nonsecured. We avoid this by checking to 10976 * see if there's pending keydata. If so, we put a null key in 10977 * the security roots; then all queries to the zone will fail. 10978 */ 10979 if (pending != 0) { 10980 fail_secure(zone, keyname); 10981 } 10982 10983done: 10984 if (!ISC_LIST_EMPTY(diff.tuples)) { 10985 /* Write changes to journal file. */ 10986 CHECK(update_soa_serial(zone, kfetch->db, ver, &diff, mctx, 10987 zone->updatemethod)); 10988 CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done")); 10989 commit = true; 10990 10991 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 10992 zone_needdump(zone, 30); 10993 } else if (result == ISC_R_NOMORE) { 10994 /* 10995 * If "updatekey" was true for all keys found in the DNSKEY 10996 * response and the previous update of those keys happened 10997 * during the same second (only possible if a key refresh was 10998 * externally triggered), it may happen that all relevant 10999 * update_one_rr() calls will return ISC_R_SUCCESS, but 11000 * diff.tuples will remain empty. Reset result to 11001 * ISC_R_SUCCESS to prevent a bogus warning from being logged. 11002 */ 11003 result = ISC_R_SUCCESS; 11004 } 11005 11006failure: 11007 if (result != ISC_R_SUCCESS) { 11008 dnssec_log(zone, ISC_LOG_ERROR, 11009 "error during managed-keys processing (%s): " 11010 "DNSSEC validation may be at risk", 11011 isc_result_totext(result)); 11012 } 11013 dns_diff_clear(&diff); 11014 if (ver != NULL) { 11015 dns_db_closeversion(kfetch->db, &ver, commit); 11016 } 11017 11018cleanup: 11019 dns_db_detach(&kfetch->db); 11020 11021 /* The zone must be managed */ 11022 INSIST(kfetch->zone->task != NULL); 11023 isc_refcount_decrement(&zone->irefs); 11024 11025 if (dns_rdataset_isassociated(keydataset)) { 11026 dns_rdataset_disassociate(keydataset); 11027 } 11028 if (dns_rdataset_isassociated(dnskeys)) { 11029 dns_rdataset_disassociate(dnskeys); 11030 } 11031 if (dns_rdataset_isassociated(dnskeysigs)) { 11032 dns_rdataset_disassociate(dnskeysigs); 11033 } 11034 11035 dns_name_free(keyname, mctx); 11036 isc_mem_putanddetach(&kfetch->mctx, kfetch, sizeof(dns_keyfetch_t)); 11037 11038 if (secroots != NULL) { 11039 dns_keytable_detach(&secroots); 11040 } 11041 11042 free_needed = exit_check(zone); 11043 UNLOCK_ZONE(zone); 11044 11045 if (free_needed) { 11046 zone_free(zone); 11047 } 11048 11049 INSIST(ver == NULL); 11050} 11051 11052static void 11053retry_keyfetch(dns_keyfetch_t *kfetch, dns_name_t *kname) { 11054 isc_time_t timenow, timethen; 11055 dns_zone_t *zone = kfetch->zone; 11056 bool free_needed; 11057 char namebuf[DNS_NAME_FORMATSIZE]; 11058 11059 dns_name_format(kname, namebuf, sizeof(namebuf)); 11060 dnssec_log(zone, ISC_LOG_WARNING, 11061 "Failed to create fetch for %s DNSKEY update", namebuf); 11062 11063 /* 11064 * Error during a key fetch; cancel and retry in an hour. 11065 */ 11066 LOCK_ZONE(zone); 11067 zone->refreshkeycount--; 11068 isc_refcount_decrement(&zone->irefs); 11069 dns_db_detach(&kfetch->db); 11070 dns_rdataset_disassociate(&kfetch->keydataset); 11071 dns_name_free(kname, zone->mctx); 11072 isc_mem_putanddetach(&kfetch->mctx, kfetch, sizeof(*kfetch)); 11073 11074 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11075 /* Don't really retry if we are exiting */ 11076 char timebuf[80]; 11077 11078 TIME_NOW(&timenow); 11079 DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen); 11080 zone->refreshkeytime = timethen; 11081 zone_settimer(zone, &timenow); 11082 11083 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 11084 dnssec_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s", 11085 timebuf); 11086 } 11087 11088 free_needed = exit_check(zone); 11089 UNLOCK_ZONE(zone); 11090 11091 if (free_needed) { 11092 zone_free(zone); 11093 } 11094} 11095 11096static void 11097do_keyfetch(isc_task_t *task, isc_event_t *event) { 11098 isc_result_t result; 11099 dns_keyfetch_t *kfetch = (dns_keyfetch_t *)event->ev_arg; 11100 dns_name_t *kname = dns_fixedname_name(&kfetch->name); 11101 dns_zone_t *zone = kfetch->zone; 11102 11103 UNUSED(task); 11104 11105 isc_event_free(&event); 11106 11107 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11108 retry_keyfetch(kfetch, kname); 11109 return; 11110 } 11111 11112 /* 11113 * Use of DNS_FETCHOPT_NOCACHED is essential here. If it is not 11114 * set and the cache still holds a non-expired, validated version 11115 * of the RRset being queried for by the time the response is 11116 * received, the cached RRset will be passed to keyfetch_done() 11117 * instead of the one received in the response as the latter will 11118 * have a lower trust level due to not being validated until 11119 * keyfetch_done() is called. 11120 */ 11121 result = dns_resolver_createfetch( 11122 zone->view->resolver, kname, dns_rdatatype_dnskey, NULL, NULL, 11123 NULL, NULL, 0, 11124 DNS_FETCHOPT_NOVALIDATE | DNS_FETCHOPT_UNSHARED | 11125 DNS_FETCHOPT_NOCACHED, 11126 0, NULL, zone->task, keyfetch_done, kfetch, &kfetch->dnskeyset, 11127 &kfetch->dnskeysigset, &kfetch->fetch); 11128 11129 if (result != ISC_R_SUCCESS) { 11130 retry_keyfetch(kfetch, kname); 11131 } 11132} 11133 11134/* 11135 * Refresh the data in the key zone. Initiate a fetch to look up 11136 * DNSKEY records at the trust anchor name. 11137 */ 11138static void 11139zone_refreshkeys(dns_zone_t *zone) { 11140 const char me[] = "zone_refreshkeys"; 11141 isc_result_t result; 11142 dns_rriterator_t rrit; 11143 dns_db_t *db = NULL; 11144 dns_dbversion_t *ver = NULL; 11145 dns_diff_t diff; 11146 dns_rdata_t rdata = DNS_RDATA_INIT; 11147 dns_rdata_keydata_t kd; 11148 isc_stdtime_t now; 11149 bool commit = false; 11150 bool fetching = false; 11151 bool timerset = false; 11152 11153 ENTER; 11154 REQUIRE(zone->db != NULL); 11155 11156 isc_stdtime_get(&now); 11157 11158 LOCK_ZONE(zone); 11159 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11160 isc_time_settoepoch(&zone->refreshkeytime); 11161 UNLOCK_ZONE(zone); 11162 return; 11163 } 11164 11165 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 11166 dns_db_attach(zone->db, &db); 11167 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11168 11169 dns_diff_init(zone->mctx, &diff); 11170 11171 CHECK(dns_db_newversion(db, &ver)); 11172 11173 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING); 11174 11175 dns_rriterator_init(&rrit, db, ver, 0); 11176 for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS; 11177 result = dns_rriterator_nextrrset(&rrit)) 11178 { 11179 isc_stdtime_t timer = 0xffffffff; 11180 dns_name_t *name = NULL, *kname = NULL; 11181 dns_rdataset_t *kdset = NULL; 11182 uint32_t ttl; 11183 11184 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL); 11185 if (kdset == NULL || kdset->type != dns_rdatatype_keydata || 11186 !dns_rdataset_isassociated(kdset)) 11187 { 11188 continue; 11189 } 11190 11191 /* 11192 * Scan the stored keys looking for ones that need 11193 * removal or refreshing 11194 */ 11195 for (result = dns_rdataset_first(kdset); 11196 result == ISC_R_SUCCESS; result = dns_rdataset_next(kdset)) 11197 { 11198 dns_rdata_reset(&rdata); 11199 dns_rdataset_current(kdset, &rdata); 11200 result = dns_rdata_tostruct(&rdata, &kd, NULL); 11201 RUNTIME_CHECK(result == ISC_R_SUCCESS); 11202 11203 /* Removal timer expired? */ 11204 if (kd.removehd != 0 && kd.removehd < now) { 11205 dns_rriterator_pause(&rrit); 11206 CHECK(update_one_rr(db, ver, &diff, 11207 DNS_DIFFOP_DEL, name, ttl, 11208 &rdata)); 11209 continue; 11210 } 11211 11212 /* Acceptance timer expired? */ 11213 if (kd.addhd <= now) { 11214 timer = kd.addhd; 11215 } 11216 11217 /* Or do we just need to refresh the keyset? */ 11218 if (timer > kd.refresh) { 11219 timer = kd.refresh; 11220 } 11221 11222 dns_rriterator_pause(&rrit); 11223 set_refreshkeytimer(zone, &kd, now, false); 11224 timerset = true; 11225 } 11226 11227 if (timer > now) { 11228 continue; 11229 } 11230 11231 dns_rriterator_pause(&rrit); 11232 11233#ifdef ENABLE_AFL 11234 if (!dns_fuzzing_resolver) { 11235#endif /* ifdef ENABLE_AFL */ 11236 dns_keyfetch_t *kfetch = NULL; 11237 isc_event_t *e; 11238 11239 kfetch = isc_mem_get(zone->mctx, 11240 sizeof(dns_keyfetch_t)); 11241 *kfetch = (dns_keyfetch_t){ .zone = zone }; 11242 isc_mem_attach(zone->mctx, &kfetch->mctx); 11243 11244 zone->refreshkeycount++; 11245 isc_refcount_increment0(&zone->irefs); 11246 kname = dns_fixedname_initname(&kfetch->name); 11247 dns_name_dup(name, zone->mctx, kname); 11248 dns_rdataset_init(&kfetch->dnskeyset); 11249 dns_rdataset_init(&kfetch->dnskeysigset); 11250 dns_rdataset_init(&kfetch->keydataset); 11251 dns_rdataset_clone(kdset, &kfetch->keydataset); 11252 dns_db_attach(db, &kfetch->db); 11253 11254 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 11255 char namebuf[DNS_NAME_FORMATSIZE]; 11256 dns_name_format(kname, namebuf, 11257 sizeof(namebuf)); 11258 dnssec_log(zone, ISC_LOG_DEBUG(3), 11259 "Creating key fetch in " 11260 "zone_refreshkeys() for '%s'", 11261 namebuf); 11262 } 11263 11264 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE, 11265 do_keyfetch, kfetch, 11266 sizeof(isc_event_t)); 11267 isc_task_send(zone->task, &e); 11268 fetching = true; 11269#ifdef ENABLE_AFL 11270 } 11271#endif /* ifdef ENABLE_AFL */ 11272 } 11273 if (!ISC_LIST_EMPTY(diff.tuples)) { 11274 CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx, 11275 zone->updatemethod)); 11276 CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys")); 11277 commit = true; 11278 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 11279 zone_needdump(zone, 30); 11280 } 11281 11282failure: 11283 if (!timerset) { 11284 isc_time_settoepoch(&zone->refreshkeytime); 11285 } 11286 11287 if (!fetching) { 11288 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 11289 } 11290 11291 dns_diff_clear(&diff); 11292 if (ver != NULL) { 11293 dns_rriterator_destroy(&rrit); 11294 dns_db_closeversion(db, &ver, commit); 11295 } 11296 dns_db_detach(&db); 11297 11298 UNLOCK_ZONE(zone); 11299 11300 INSIST(ver == NULL); 11301} 11302 11303static void 11304zone_maintenance(dns_zone_t *zone) { 11305 const char me[] = "zone_maintenance"; 11306 isc_time_t now; 11307 isc_result_t result; 11308 bool load_pending, exiting, dumping, viewok, notify; 11309 bool refreshkeys, sign, resign, rekey, chain, warn_expire; 11310 11311 REQUIRE(DNS_ZONE_VALID(zone)); 11312 ENTER; 11313 11314 /* 11315 * Are we pending load/reload, exiting, or unconfigured 11316 * (e.g. because of a syntax failure in the config file)? 11317 * If so, don't attempt maintenance. 11318 */ 11319 LOCK_ZONE(zone); 11320 load_pending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING); 11321 exiting = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING); 11322 viewok = (zone->view != NULL && zone->view->adb != NULL); 11323 UNLOCK_ZONE(zone); 11324 11325 if (load_pending || exiting || !viewok) { 11326 return; 11327 } 11328 11329 TIME_NOW(&now); 11330 11331 /* 11332 * Expire check. 11333 */ 11334 switch (zone->type) { 11335 case dns_zone_redirect: 11336 if (zone->primaries == NULL) { 11337 break; 11338 } 11339 FALLTHROUGH; 11340 case dns_zone_secondary: 11341 case dns_zone_mirror: 11342 case dns_zone_stub: 11343 LOCK_ZONE(zone); 11344 if (isc_time_compare(&now, &zone->expiretime) >= 0 && 11345 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 11346 { 11347 zone_expire(zone); 11348 zone->refreshtime = now; 11349 } 11350 UNLOCK_ZONE(zone); 11351 break; 11352 default: 11353 break; 11354 } 11355 11356 /* 11357 * Up to date check. 11358 */ 11359 switch (zone->type) { 11360 case dns_zone_redirect: 11361 if (zone->primaries == NULL) { 11362 break; 11363 } 11364 FALLTHROUGH; 11365 case dns_zone_secondary: 11366 case dns_zone_mirror: 11367 case dns_zone_stub: 11368 LOCK_ZONE(zone); 11369 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && 11370 isc_time_compare(&now, &zone->refreshtime) >= 0) 11371 { 11372 zone_refresh(zone); 11373 } 11374 UNLOCK_ZONE(zone); 11375 break; 11376 default: 11377 break; 11378 } 11379 11380 /* 11381 * Secondaries send notifies before backing up to disk, 11382 * primaries after. 11383 */ 11384 LOCK_ZONE(zone); 11385 notify = (zone->type == dns_zone_secondary || 11386 zone->type == dns_zone_mirror) && 11387 (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 11388 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) && 11389 isc_time_compare(&now, &zone->notifytime) >= 0; 11390 UNLOCK_ZONE(zone); 11391 11392 if (notify) { 11393 zone_notify(zone, &now); 11394 } 11395 11396 /* 11397 * Do we need to consolidate the backing store? 11398 */ 11399 switch (zone->type) { 11400 case dns_zone_primary: 11401 case dns_zone_secondary: 11402 case dns_zone_mirror: 11403 case dns_zone_key: 11404 case dns_zone_redirect: 11405 case dns_zone_stub: 11406 LOCK_ZONE(zone); 11407 if (zone->masterfile != NULL && 11408 isc_time_compare(&now, &zone->dumptime) >= 0 && 11409 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 11410 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) 11411 { 11412 dumping = was_dumping(zone); 11413 } else { 11414 dumping = true; 11415 } 11416 UNLOCK_ZONE(zone); 11417 if (!dumping) { 11418 result = zone_dump(zone, true); /* task locked */ 11419 if (result != ISC_R_SUCCESS) { 11420 dns_zone_log(zone, ISC_LOG_WARNING, 11421 "dump failed: %s", 11422 isc_result_totext(result)); 11423 } 11424 } 11425 break; 11426 default: 11427 break; 11428 } 11429 11430 /* 11431 * Primary/redirect zones send notifies now, if needed 11432 */ 11433 switch (zone->type) { 11434 case dns_zone_primary: 11435 case dns_zone_redirect: 11436 LOCK_ZONE(zone); 11437 notify = (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 11438 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) && 11439 isc_time_compare(&now, &zone->notifytime) >= 0; 11440 UNLOCK_ZONE(zone); 11441 if (notify) { 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 LOCK_ZONE(zone); 11454 refreshkeys = isc_time_compare(&now, &zone->refreshkeytime) >= 11455 0 && 11456 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 11457 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING); 11458 UNLOCK_ZONE(zone); 11459 if (refreshkeys) { 11460 zone_refreshkeys(zone); 11461 } 11462 break; 11463 case dns_zone_primary: 11464 LOCK_ZONE(zone); 11465 rekey = (!isc_time_isepoch(&zone->refreshkeytime) && 11466 isc_time_compare(&now, &zone->refreshkeytime) >= 0 && 11467 zone->rss_event == NULL); 11468 UNLOCK_ZONE(zone); 11469 if (rekey) { 11470 zone_rekey(zone); 11471 } 11472 default: 11473 break; 11474 } 11475 11476 switch (zone->type) { 11477 case dns_zone_primary: 11478 case dns_zone_redirect: 11479 case dns_zone_secondary: 11480 /* 11481 * Do we need to sign/resign some RRsets? 11482 */ 11483 LOCK_ZONE(zone); 11484 if (zone->rss_event != NULL) { 11485 UNLOCK_ZONE(zone); 11486 break; 11487 } 11488 sign = !isc_time_isepoch(&zone->signingtime) && 11489 isc_time_compare(&now, &zone->signingtime) >= 0; 11490 resign = !isc_time_isepoch(&zone->resigntime) && 11491 isc_time_compare(&now, &zone->resigntime) >= 0; 11492 chain = !isc_time_isepoch(&zone->nsec3chaintime) && 11493 isc_time_compare(&now, &zone->nsec3chaintime) >= 0; 11494 warn_expire = !isc_time_isepoch(&zone->keywarntime) && 11495 isc_time_compare(&now, &zone->keywarntime) >= 0; 11496 UNLOCK_ZONE(zone); 11497 11498 if (sign) { 11499 zone_sign(zone); 11500 } else if (resign) { 11501 zone_resigninc(zone); 11502 } else if (chain) { 11503 zone_nsec3chain(zone); 11504 } 11505 11506 /* 11507 * Do we need to issue a key expiry warning? 11508 */ 11509 if (warn_expire) { 11510 set_key_expiry_warning(zone, zone->key_expiry, 11511 isc_time_seconds(&now)); 11512 } 11513 break; 11514 11515 default: 11516 break; 11517 } 11518 LOCK_ZONE(zone); 11519 zone_settimer(zone, &now); 11520 UNLOCK_ZONE(zone); 11521} 11522 11523void 11524dns_zone_markdirty(dns_zone_t *zone) { 11525 uint32_t serial; 11526 isc_result_t result = ISC_R_SUCCESS; 11527 dns_zone_t *secure = NULL; 11528 11529 /* 11530 * Obtaining a lock on the zone->secure (see zone_send_secureserial) 11531 * could result in a deadlock due to a LOR so we will spin if we 11532 * can't obtain the both locks. 11533 */ 11534again: 11535 LOCK_ZONE(zone); 11536 if (zone->type == dns_zone_primary) { 11537 if (inline_raw(zone)) { 11538 unsigned int soacount; 11539 secure = zone->secure; 11540 INSIST(secure != zone); 11541 TRYLOCK_ZONE(result, secure); 11542 if (result != ISC_R_SUCCESS) { 11543 UNLOCK_ZONE(zone); 11544 secure = NULL; 11545 isc_thread_yield(); 11546 goto again; 11547 } 11548 11549 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 11550 if (zone->db != NULL) { 11551 result = zone_get_from_db( 11552 zone, zone->db, NULL, &soacount, NULL, 11553 &serial, NULL, NULL, NULL, NULL, NULL); 11554 } else { 11555 result = DNS_R_NOTLOADED; 11556 } 11557 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11558 if (result == ISC_R_SUCCESS && soacount > 0U) { 11559 zone_send_secureserial(zone, serial); 11560 } 11561 } 11562 11563 /* XXXMPA make separate call back */ 11564 if (result == ISC_R_SUCCESS) { 11565 set_resigntime(zone); 11566 if (zone->task != NULL) { 11567 isc_time_t now; 11568 TIME_NOW(&now); 11569 zone_settimer(zone, &now); 11570 } 11571 } 11572 } 11573 if (secure != NULL) { 11574 UNLOCK_ZONE(secure); 11575 } 11576 zone_needdump(zone, DNS_DUMP_DELAY); 11577 UNLOCK_ZONE(zone); 11578} 11579 11580void 11581dns_zone_expire(dns_zone_t *zone) { 11582 REQUIRE(DNS_ZONE_VALID(zone)); 11583 11584 LOCK_ZONE(zone); 11585 zone_expire(zone); 11586 UNLOCK_ZONE(zone); 11587} 11588 11589static void 11590zone_expire(dns_zone_t *zone) { 11591 dns_db_t *db = NULL; 11592 11593 /* 11594 * 'zone' locked by caller. 11595 */ 11596 11597 REQUIRE(LOCKED_ZONE(zone)); 11598 11599 dns_zone_log(zone, ISC_LOG_WARNING, "expired"); 11600 11601 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED); 11602 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 11603 zone->retry = DNS_ZONE_DEFAULTRETRY; 11604 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 11605 11606 /* 11607 * An RPZ zone has expired; before unloading it, we must 11608 * first remove it from the RPZ summary database. The 11609 * easiest way to do this is "update" it with an empty 11610 * database so that the update callback synchronizes 11611 * the diff automatically. 11612 */ 11613 if (zone->rpzs != NULL && zone->rpz_num != DNS_RPZ_INVALID_NUM) { 11614 isc_result_t result; 11615 dns_rpz_zone_t *rpz = zone->rpzs->zones[zone->rpz_num]; 11616 11617 CHECK(dns_db_create(zone->mctx, "rbt", &zone->origin, 11618 dns_dbtype_zone, zone->rdclass, 0, NULL, 11619 &db)); 11620 CHECK(dns_rpz_dbupdate_callback(db, rpz)); 11621 dns_zone_log(zone, ISC_LOG_WARNING, 11622 "response-policy zone expired; " 11623 "policies unloaded"); 11624 } 11625 11626failure: 11627 if (db != NULL) { 11628 dns_db_detach(&db); 11629 } 11630 11631 zone_unload(zone); 11632} 11633 11634static void 11635zone_refresh(dns_zone_t *zone) { 11636 isc_interval_t i; 11637 uint32_t oldflags; 11638 unsigned int j; 11639 isc_result_t result; 11640 11641 REQUIRE(DNS_ZONE_VALID(zone)); 11642 REQUIRE(LOCKED_ZONE(zone)); 11643 11644 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11645 return; 11646 } 11647 11648 /* 11649 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation 11650 * in progress at a time. 11651 */ 11652 11653 oldflags = atomic_load(&zone->flags); 11654 if (zone->primariescnt == 0) { 11655 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOPRIMARIES); 11656 if ((oldflags & DNS_ZONEFLG_NOPRIMARIES) == 0) { 11657 dns_zone_log(zone, ISC_LOG_ERROR, 11658 "cannot refresh: no primaries"); 11659 } 11660 return; 11661 } 11662 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 11663 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 11664 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 11665 if ((oldflags & (DNS_ZONEFLG_REFRESH | DNS_ZONEFLG_LOADING)) != 0) { 11666 return; 11667 } 11668 11669 /* 11670 * Set the next refresh time as if refresh check has failed. 11671 * Setting this to the retry time will do that. XXXMLG 11672 * If we are successful it will be reset using zone->refresh. 11673 */ 11674 isc_interval_set(&i, zone->retry - isc_random_uniform(zone->retry / 4), 11675 0); 11676 result = isc_time_nowplusinterval(&zone->refreshtime, &i); 11677 if (result != ISC_R_SUCCESS) { 11678 dns_zone_log(zone, ISC_LOG_WARNING, 11679 "isc_time_nowplusinterval() failed: %s", 11680 isc_result_totext(result)); 11681 } 11682 11683 /* 11684 * When lacking user-specified timer values from the SOA, 11685 * do exponential backoff of the retry time up to a 11686 * maximum of six hours. 11687 */ 11688 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) { 11689 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600); 11690 } 11691 11692 zone->curprimary = 0; 11693 for (j = 0; j < zone->primariescnt; j++) { 11694 zone->primariesok[j] = false; 11695 } 11696 /* initiate soa query */ 11697 queue_soa_query(zone); 11698} 11699 11700void 11701dns_zone_refresh(dns_zone_t *zone) { 11702 LOCK_ZONE(zone); 11703 zone_refresh(zone); 11704 UNLOCK_ZONE(zone); 11705} 11706 11707static isc_result_t 11708zone_journal_rollforward(dns_zone_t *zone, dns_db_t *db, bool *needdump, 11709 bool *fixjournal) { 11710 dns_journal_t *journal = NULL; 11711 unsigned int options; 11712 isc_result_t result; 11713 11714 if (zone->type == dns_zone_primary && 11715 (inline_secure(zone) || 11716 (zone->update_acl != NULL || zone->ssutable != NULL))) 11717 { 11718 options = DNS_JOURNALOPT_RESIGN; 11719 } else { 11720 options = 0; 11721 } 11722 11723 result = dns_journal_open(zone->mctx, zone->journal, DNS_JOURNAL_READ, 11724 &journal); 11725 if (result == ISC_R_NOTFOUND) { 11726 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(3), 11727 "no journal file, but that's OK "); 11728 return (ISC_R_SUCCESS); 11729 } else if (result != ISC_R_SUCCESS) { 11730 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 11731 "journal open failed: %s", 11732 isc_result_totext(result)); 11733 return (result); 11734 } 11735 11736 if (dns_journal_empty(journal)) { 11737 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1), 11738 "journal empty"); 11739 dns_journal_destroy(&journal); 11740 return (ISC_R_SUCCESS); 11741 } 11742 11743 result = dns_journal_rollforward(journal, db, options); 11744 switch (result) { 11745 case ISC_R_SUCCESS: 11746 *needdump = true; 11747 FALLTHROUGH; 11748 case DNS_R_UPTODATE: 11749 if (dns_journal_recovered(journal)) { 11750 *fixjournal = true; 11751 dns_zone_logc( 11752 zone, DNS_LOGCATEGORY_ZONELOAD, 11753 ISC_LOG_DEBUG(1), 11754 "journal rollforward completed successfully " 11755 "using old journal format: %s", 11756 isc_result_totext(result)); 11757 } else { 11758 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, 11759 ISC_LOG_DEBUG(1), 11760 "journal rollforward completed " 11761 "successfully: %s", 11762 isc_result_totext(result)); 11763 } 11764 11765 dns_journal_destroy(&journal); 11766 return (ISC_R_SUCCESS); 11767 case ISC_R_NOTFOUND: 11768 case ISC_R_RANGE: 11769 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 11770 "journal rollforward failed: journal out of sync " 11771 "with zone"); 11772 dns_journal_destroy(&journal); 11773 return (result); 11774 default: 11775 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR, 11776 "journal rollforward failed: %s", 11777 isc_result_totext(result)); 11778 dns_journal_destroy(&journal); 11779 return (result); 11780 } 11781} 11782 11783static void 11784zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial) { 11785 isc_result_t result; 11786 int32_t journalsize; 11787 dns_dbversion_t *ver = NULL; 11788 uint64_t dbsize; 11789 uint32_t options = 0; 11790 11791 INSIST(LOCKED_ZONE(zone)); 11792 if (inline_raw(zone)) { 11793 INSIST(LOCKED_ZONE(zone->secure)); 11794 } 11795 11796 journalsize = zone->journalsize; 11797 if (journalsize == -1) { 11798 journalsize = DNS_JOURNAL_SIZE_MAX; 11799 dns_db_currentversion(db, &ver); 11800 result = dns_db_getsize(db, ver, NULL, &dbsize); 11801 dns_db_closeversion(db, &ver, false); 11802 if (result != ISC_R_SUCCESS) { 11803 dns_zone_log(zone, ISC_LOG_ERROR, 11804 "zone_journal_compact: " 11805 "could not get zone size: %s", 11806 isc_result_totext(result)); 11807 } else if (dbsize < DNS_JOURNAL_SIZE_MAX / 2) { 11808 journalsize = (int32_t)dbsize * 2; 11809 } 11810 } 11811 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FIXJOURNAL)) { 11812 options |= DNS_JOURNAL_COMPACTALL; 11813 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FIXJOURNAL); 11814 zone_debuglog(zone, "zone_journal_compact", 1, 11815 "repair full journal"); 11816 } else { 11817 zone_debuglog(zone, "zone_journal_compact", 1, 11818 "target journal size %d", journalsize); 11819 } 11820 result = dns_journal_compact(zone->mctx, zone->journal, serial, options, 11821 journalsize); 11822 switch (result) { 11823 case ISC_R_SUCCESS: 11824 case ISC_R_NOSPACE: 11825 case ISC_R_NOTFOUND: 11826 dns_zone_log(zone, ISC_LOG_DEBUG(3), "dns_journal_compact: %s", 11827 isc_result_totext(result)); 11828 break; 11829 default: 11830 dns_zone_log(zone, ISC_LOG_ERROR, 11831 "dns_journal_compact failed: %s", 11832 isc_result_totext(result)); 11833 break; 11834 } 11835} 11836 11837isc_result_t 11838dns_zone_flush(dns_zone_t *zone) { 11839 isc_result_t result = ISC_R_SUCCESS; 11840 bool dumping; 11841 11842 REQUIRE(DNS_ZONE_VALID(zone)); 11843 11844 LOCK_ZONE(zone); 11845 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH); 11846 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 11847 zone->masterfile != NULL) 11848 { 11849 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 11850 result = ISC_R_ALREADYRUNNING; 11851 dumping = was_dumping(zone); 11852 } else { 11853 dumping = true; 11854 } 11855 UNLOCK_ZONE(zone); 11856 if (!dumping) { 11857 result = zone_dump(zone, true); /* Unknown task. */ 11858 } 11859 return (result); 11860} 11861 11862isc_result_t 11863dns_zone_dump(dns_zone_t *zone) { 11864 isc_result_t result = ISC_R_ALREADYRUNNING; 11865 bool dumping; 11866 11867 REQUIRE(DNS_ZONE_VALID(zone)); 11868 11869 LOCK_ZONE(zone); 11870 dumping = was_dumping(zone); 11871 UNLOCK_ZONE(zone); 11872 if (!dumping) { 11873 result = zone_dump(zone, false); /* Unknown task. */ 11874 } 11875 return (result); 11876} 11877 11878static void 11879zone_needdump(dns_zone_t *zone, unsigned int delay) { 11880 const char me[] = "zone_needdump"; 11881 isc_time_t dumptime; 11882 isc_time_t now; 11883 11884 /* 11885 * 'zone' locked by caller 11886 */ 11887 11888 REQUIRE(DNS_ZONE_VALID(zone)); 11889 REQUIRE(LOCKED_ZONE(zone)); 11890 ENTER; 11891 11892 /* 11893 * Do we have a place to dump to and are we loaded? 11894 */ 11895 if (zone->masterfile == NULL || 11896 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) 11897 { 11898 return; 11899 } 11900 11901 TIME_NOW(&now); 11902 /* add some noise */ 11903 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime); 11904 11905 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 11906 if (isc_time_isepoch(&zone->dumptime) || 11907 isc_time_compare(&zone->dumptime, &dumptime) > 0) 11908 { 11909 zone->dumptime = dumptime; 11910 } 11911 if (zone->task != NULL) { 11912 zone_settimer(zone, &now); 11913 } 11914} 11915 11916static void 11917dump_done(void *arg, isc_result_t result) { 11918 const char me[] = "dump_done"; 11919 dns_zone_t *zone = arg; 11920 dns_zone_t *secure = NULL; 11921 dns_db_t *db; 11922 dns_dbversion_t *version; 11923 bool again = false; 11924 bool compact = false; 11925 uint32_t serial; 11926 isc_result_t tresult; 11927 11928 REQUIRE(DNS_ZONE_VALID(zone)); 11929 11930 ENTER; 11931 11932 if (result == ISC_R_SUCCESS && zone->journal != NULL) { 11933 /* 11934 * We don't own these, zone->dctx must stay valid. 11935 */ 11936 db = dns_dumpctx_db(zone->dctx); 11937 version = dns_dumpctx_version(zone->dctx); 11938 tresult = dns_db_getsoaserial(db, version, &serial); 11939 11940 /* 11941 * Handle lock order inversion. 11942 */ 11943 again: 11944 LOCK_ZONE(zone); 11945 if (inline_raw(zone)) { 11946 secure = zone->secure; 11947 INSIST(secure != zone); 11948 TRYLOCK_ZONE(result, secure); 11949 if (result != ISC_R_SUCCESS) { 11950 UNLOCK_ZONE(zone); 11951 secure = NULL; 11952 isc_thread_yield(); 11953 goto again; 11954 } 11955 } 11956 11957 /* 11958 * If there is a secure version of this zone 11959 * use its serial if it is less than ours. 11960 */ 11961 if (tresult == ISC_R_SUCCESS && secure != NULL) { 11962 uint32_t sserial; 11963 isc_result_t mresult; 11964 11965 ZONEDB_LOCK(&secure->dblock, isc_rwlocktype_read); 11966 if (secure->db != NULL) { 11967 mresult = dns_db_getsoaserial(zone->secure->db, 11968 NULL, &sserial); 11969 if (mresult == ISC_R_SUCCESS && 11970 isc_serial_lt(sserial, serial)) 11971 { 11972 serial = sserial; 11973 } 11974 } 11975 ZONEDB_UNLOCK(&secure->dblock, isc_rwlocktype_read); 11976 } 11977 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) { 11978 dns_db_t *zdb = NULL; 11979 if (dns_zone_getdb(zone, &zdb) == ISC_R_SUCCESS) { 11980 zone_journal_compact(zone, zdb, serial); 11981 dns_db_detach(&zdb); 11982 } 11983 } else if (tresult == ISC_R_SUCCESS) { 11984 compact = true; 11985 zone->compact_serial = serial; 11986 } 11987 if (secure != NULL) { 11988 UNLOCK_ZONE(secure); 11989 } 11990 UNLOCK_ZONE(zone); 11991 } 11992 11993 LOCK_ZONE(zone); 11994 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 11995 if (compact) { 11996 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 11997 } 11998 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN)) { 11999 /* 12000 * If DNS_ZONEFLG_SHUTDOWN is set, all external references to 12001 * the zone are gone, which means it is in the process of being 12002 * cleaned up, so do not reschedule dumping. 12003 * 12004 * Detach from the raw version of the zone in case this 12005 * operation has been deferred in zone_shutdown(). 12006 */ 12007 if (zone->raw != NULL) { 12008 dns_zone_detach(&zone->raw); 12009 } 12010 if (result == ISC_R_SUCCESS) { 12011 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 12012 } 12013 } else if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) { 12014 /* 12015 * Try again in a short while. 12016 */ 12017 zone_needdump(zone, DNS_DUMP_DELAY); 12018 } else if (result == ISC_R_SUCCESS && 12019 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 12020 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 12021 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 12022 { 12023 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 12024 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 12025 isc_time_settoepoch(&zone->dumptime); 12026 again = true; 12027 } else if (result == ISC_R_SUCCESS) { 12028 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 12029 } 12030 12031 if (zone->dctx != NULL) { 12032 dns_dumpctx_detach(&zone->dctx); 12033 } 12034 zonemgr_putio(&zone->writeio); 12035 UNLOCK_ZONE(zone); 12036 if (again) { 12037 (void)zone_dump(zone, false); 12038 } 12039 dns_zone_idetach(&zone); 12040} 12041 12042static isc_result_t 12043zone_dump(dns_zone_t *zone, bool compact) { 12044 const char me[] = "zone_dump"; 12045 isc_result_t result; 12046 dns_dbversion_t *version = NULL; 12047 bool again; 12048 dns_db_t *db = NULL; 12049 char *masterfile = NULL; 12050 dns_masterformat_t masterformat = dns_masterformat_none; 12051 12052 /* 12053 * 'compact' MUST only be set if we are task locked. 12054 */ 12055 12056 REQUIRE(DNS_ZONE_VALID(zone)); 12057 ENTER; 12058 12059redo: 12060 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12061 if (zone->db != NULL) { 12062 dns_db_attach(zone->db, &db); 12063 } 12064 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12065 LOCK_ZONE(zone); 12066 if (zone->masterfile != NULL) { 12067 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile); 12068 masterformat = zone->masterformat; 12069 } 12070 UNLOCK_ZONE(zone); 12071 if (db == NULL) { 12072 result = DNS_R_NOTLOADED; 12073 goto fail; 12074 } 12075 if (masterfile == NULL) { 12076 result = DNS_R_NOMASTERFILE; 12077 goto fail; 12078 } 12079 12080 if (compact && zone->type != dns_zone_stub) { 12081 dns_zone_t *dummy = NULL; 12082 LOCK_ZONE(zone); 12083 zone_iattach(zone, &dummy); 12084 result = zonemgr_getio(zone->zmgr, false, zone->task, 12085 zone_gotwritehandle, zone, 12086 &zone->writeio); 12087 if (result != ISC_R_SUCCESS) { 12088 zone_idetach(&dummy); 12089 } else { 12090 result = DNS_R_CONTINUE; 12091 } 12092 UNLOCK_ZONE(zone); 12093 } else { 12094 const dns_master_style_t *output_style; 12095 12096 dns_masterrawheader_t rawdata; 12097 dns_db_currentversion(db, &version); 12098 dns_master_initrawheader(&rawdata); 12099 if (inline_secure(zone)) { 12100 get_raw_serial(zone->raw, &rawdata); 12101 } 12102 if (zone->type == dns_zone_key) { 12103 output_style = &dns_master_style_keyzone; 12104 } else { 12105 output_style = &dns_master_style_default; 12106 } 12107 result = dns_master_dump(zone->mctx, db, version, output_style, 12108 masterfile, masterformat, &rawdata); 12109 dns_db_closeversion(db, &version, false); 12110 } 12111fail: 12112 if (db != NULL) { 12113 dns_db_detach(&db); 12114 } 12115 if (masterfile != NULL) { 12116 isc_mem_free(zone->mctx, masterfile); 12117 } 12118 masterfile = NULL; 12119 12120 if (result == DNS_R_CONTINUE) { 12121 return (ISC_R_SUCCESS); /* XXXMPA */ 12122 } 12123 12124 again = false; 12125 LOCK_ZONE(zone); 12126 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 12127 if (result != ISC_R_SUCCESS) { 12128 /* 12129 * Try again in a short while. 12130 */ 12131 zone_needdump(zone, DNS_DUMP_DELAY); 12132 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 12133 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 12134 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 12135 { 12136 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 12137 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 12138 isc_time_settoepoch(&zone->dumptime); 12139 again = true; 12140 } else { 12141 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 12142 } 12143 UNLOCK_ZONE(zone); 12144 if (again) { 12145 goto redo; 12146 } 12147 12148 return (result); 12149} 12150 12151static isc_result_t 12152dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style, 12153 dns_masterformat_t format, const uint32_t rawversion) { 12154 isc_result_t result; 12155 dns_dbversion_t *version = NULL; 12156 dns_db_t *db = NULL; 12157 dns_masterrawheader_t rawdata; 12158 12159 REQUIRE(DNS_ZONE_VALID(zone)); 12160 12161 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12162 if (zone->db != NULL) { 12163 dns_db_attach(zone->db, &db); 12164 } 12165 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12166 if (db == NULL) { 12167 return (DNS_R_NOTLOADED); 12168 } 12169 12170 dns_db_currentversion(db, &version); 12171 dns_master_initrawheader(&rawdata); 12172 if (rawversion == 0) { 12173 rawdata.flags |= DNS_MASTERRAW_COMPAT; 12174 } else if (inline_secure(zone)) { 12175 get_raw_serial(zone->raw, &rawdata); 12176 } else if (zone->sourceserialset) { 12177 rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET; 12178 rawdata.sourceserial = zone->sourceserial; 12179 } 12180 result = dns_master_dumptostream(zone->mctx, db, version, style, format, 12181 &rawdata, fd); 12182 dns_db_closeversion(db, &version, false); 12183 dns_db_detach(&db); 12184 return (result); 12185} 12186 12187isc_result_t 12188dns_zone_dumptostream(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, 12189 const dns_master_style_t *style, 12190 const uint32_t rawversion) { 12191 return (dumptostream(zone, fd, style, format, rawversion)); 12192} 12193 12194void 12195dns_zone_unload(dns_zone_t *zone) { 12196 REQUIRE(DNS_ZONE_VALID(zone)); 12197 12198 LOCK_ZONE(zone); 12199 zone_unload(zone); 12200 UNLOCK_ZONE(zone); 12201} 12202 12203static void 12204notify_cancel(dns_zone_t *zone) { 12205 dns_notify_t *notify; 12206 12207 /* 12208 * 'zone' locked by caller. 12209 */ 12210 12211 REQUIRE(LOCKED_ZONE(zone)); 12212 12213 for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL; 12214 notify = ISC_LIST_NEXT(notify, link)) 12215 { 12216 if (notify->find != NULL) { 12217 dns_adb_cancelfind(notify->find); 12218 } 12219 if (notify->request != NULL) { 12220 dns_request_cancel(notify->request); 12221 } 12222 } 12223} 12224 12225static void 12226checkds_cancel(dns_zone_t *zone) { 12227 dns_checkds_t *checkds; 12228 12229 /* 12230 * 'zone' locked by caller. 12231 */ 12232 12233 REQUIRE(LOCKED_ZONE(zone)); 12234 12235 for (checkds = ISC_LIST_HEAD(zone->checkds_requests); checkds != NULL; 12236 checkds = ISC_LIST_NEXT(checkds, link)) 12237 { 12238 if (checkds->request != NULL) { 12239 dns_request_cancel(checkds->request); 12240 } 12241 } 12242} 12243 12244static void 12245forward_cancel(dns_zone_t *zone) { 12246 dns_forward_t *forward; 12247 12248 /* 12249 * 'zone' locked by caller. 12250 */ 12251 12252 REQUIRE(LOCKED_ZONE(zone)); 12253 12254 for (forward = ISC_LIST_HEAD(zone->forwards); forward != NULL; 12255 forward = ISC_LIST_NEXT(forward, link)) 12256 { 12257 if (forward->request != NULL) { 12258 dns_request_cancel(forward->request); 12259 } 12260 } 12261} 12262 12263static void 12264zone_unload(dns_zone_t *zone) { 12265 /* 12266 * 'zone' locked by caller. 12267 */ 12268 12269 REQUIRE(LOCKED_ZONE(zone)); 12270 12271 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 12272 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 12273 { 12274 if (zone->writeio != NULL) { 12275 zonemgr_cancelio(zone->writeio); 12276 } 12277 12278 if (zone->dctx != NULL) { 12279 dns_dumpctx_cancel(zone->dctx); 12280 } 12281 } 12282 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 12283 zone_detachdb(zone); 12284 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 12285 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED); 12286 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 12287 12288 if (zone->type == dns_zone_mirror) { 12289 dns_zone_log(zone, ISC_LOG_INFO, 12290 "mirror zone is no longer in use; " 12291 "reverting to normal recursion"); 12292 } 12293} 12294 12295void 12296dns_zone_setminrefreshtime(dns_zone_t *zone, uint32_t val) { 12297 REQUIRE(DNS_ZONE_VALID(zone)); 12298 REQUIRE(val > 0); 12299 12300 zone->minrefresh = val; 12301} 12302 12303void 12304dns_zone_setmaxrefreshtime(dns_zone_t *zone, uint32_t val) { 12305 REQUIRE(DNS_ZONE_VALID(zone)); 12306 REQUIRE(val > 0); 12307 12308 zone->maxrefresh = val; 12309} 12310 12311void 12312dns_zone_setminretrytime(dns_zone_t *zone, uint32_t val) { 12313 REQUIRE(DNS_ZONE_VALID(zone)); 12314 REQUIRE(val > 0); 12315 12316 zone->minretry = val; 12317} 12318 12319void 12320dns_zone_setmaxretrytime(dns_zone_t *zone, uint32_t val) { 12321 REQUIRE(DNS_ZONE_VALID(zone)); 12322 REQUIRE(val > 0); 12323 12324 zone->maxretry = val; 12325} 12326 12327uint32_t 12328dns_zone_getmaxrecords(dns_zone_t *zone) { 12329 REQUIRE(DNS_ZONE_VALID(zone)); 12330 12331 return (zone->maxrecords); 12332} 12333 12334void 12335dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) { 12336 REQUIRE(DNS_ZONE_VALID(zone)); 12337 12338 zone->maxrecords = val; 12339} 12340 12341static bool 12342notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name, 12343 isc_sockaddr_t *addr, dns_tsigkey_t *key, 12344 dns_transport_t *transport) { 12345 dns_notify_t *notify; 12346 dns_zonemgr_t *zmgr; 12347 isc_result_t result; 12348 12349 for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL; 12350 notify = ISC_LIST_NEXT(notify, link)) 12351 { 12352 if (notify->request != NULL) { 12353 continue; 12354 } 12355 if (name != NULL && dns_name_dynamic(¬ify->ns) && 12356 dns_name_equal(name, ¬ify->ns)) 12357 { 12358 goto requeue; 12359 } 12360 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst) && 12361 notify->key == key && notify->transport == transport) 12362 { 12363 goto requeue; 12364 } 12365 } 12366 return (false); 12367 12368requeue: 12369 /* 12370 * If we are enqueued on the startup ratelimiter and this is 12371 * not a startup notify, re-enqueue on the normal notify 12372 * ratelimiter. 12373 */ 12374 if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0 && 12375 (notify->flags & DNS_NOTIFY_STARTUP) != 0) 12376 { 12377 zmgr = notify->zone->zmgr; 12378 result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl, 12379 notify->event); 12380 if (result != ISC_R_SUCCESS) { 12381 return (true); 12382 } 12383 12384 notify->flags &= ~DNS_NOTIFY_STARTUP; 12385 result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl, 12386 notify->zone->task, 12387 ¬ify->event); 12388 if (result != ISC_R_SUCCESS) { 12389 isc_event_free(¬ify->event); 12390 return (false); 12391 } 12392 } 12393 12394 return (true); 12395} 12396 12397static bool 12398notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) { 12399 dns_tsigkey_t *key = NULL; 12400 isc_sockaddr_t src; 12401 isc_sockaddr_t any; 12402 bool isself; 12403 isc_netaddr_t dstaddr; 12404 isc_result_t result; 12405 12406 if (zone->view == NULL || zone->isself == NULL) { 12407 return (false); 12408 } 12409 12410 switch (isc_sockaddr_pf(dst)) { 12411 case PF_INET: 12412 src = zone->notifysrc4; 12413 isc_sockaddr_any(&any); 12414 break; 12415 case PF_INET6: 12416 src = zone->notifysrc6; 12417 isc_sockaddr_any6(&any); 12418 break; 12419 default: 12420 return (false); 12421 } 12422 12423 /* 12424 * When sending from any the kernel will assign a source address 12425 * that matches the destination address. 12426 */ 12427 if (isc_sockaddr_eqaddr(&any, &src)) { 12428 src = *dst; 12429 } 12430 12431 isc_netaddr_fromsockaddr(&dstaddr, dst); 12432 result = dns_view_getpeertsig(zone->view, &dstaddr, &key); 12433 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 12434 return (false); 12435 } 12436 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass, 12437 zone->isselfarg); 12438 if (key != NULL) { 12439 dns_tsigkey_detach(&key); 12440 } 12441 return (isself); 12442} 12443 12444static void 12445notify_destroy(dns_notify_t *notify, bool locked) { 12446 isc_mem_t *mctx; 12447 12448 REQUIRE(DNS_NOTIFY_VALID(notify)); 12449 12450 if (notify->zone != NULL) { 12451 if (!locked) { 12452 LOCK_ZONE(notify->zone); 12453 } 12454 REQUIRE(LOCKED_ZONE(notify->zone)); 12455 if (ISC_LINK_LINKED(notify, link)) { 12456 ISC_LIST_UNLINK(notify->zone->notifies, notify, link); 12457 } 12458 if (!locked) { 12459 UNLOCK_ZONE(notify->zone); 12460 } 12461 if (locked) { 12462 zone_idetach(¬ify->zone); 12463 } else { 12464 dns_zone_idetach(¬ify->zone); 12465 } 12466 } 12467 if (notify->find != NULL) { 12468 dns_adb_destroyfind(¬ify->find); 12469 } 12470 if (notify->request != NULL) { 12471 dns_request_destroy(¬ify->request); 12472 } 12473 if (dns_name_dynamic(¬ify->ns)) { 12474 dns_name_free(¬ify->ns, notify->mctx); 12475 } 12476 if (notify->key != NULL) { 12477 dns_tsigkey_detach(¬ify->key); 12478 } 12479 if (notify->transport != NULL) { 12480 dns_transport_detach(¬ify->transport); 12481 } 12482 mctx = notify->mctx; 12483 isc_mem_put(notify->mctx, notify, sizeof(*notify)); 12484 isc_mem_detach(&mctx); 12485} 12486 12487static isc_result_t 12488notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) { 12489 dns_notify_t *notify; 12490 12491 REQUIRE(notifyp != NULL && *notifyp == NULL); 12492 12493 notify = isc_mem_get(mctx, sizeof(*notify)); 12494 *notify = (dns_notify_t){ 12495 .flags = flags, 12496 }; 12497 12498 isc_mem_attach(mctx, ¬ify->mctx); 12499 isc_sockaddr_any(¬ify->dst); 12500 dns_name_init(¬ify->ns, NULL); 12501 ISC_LINK_INIT(notify, link); 12502 notify->magic = NOTIFY_MAGIC; 12503 *notifyp = notify; 12504 return (ISC_R_SUCCESS); 12505} 12506 12507/* 12508 * XXXAG should check for DNS_ZONEFLG_EXITING 12509 */ 12510static void 12511process_adb_event(isc_task_t *task, isc_event_t *ev) { 12512 dns_notify_t *notify; 12513 isc_eventtype_t result; 12514 12515 UNUSED(task); 12516 12517 notify = ev->ev_arg; 12518 REQUIRE(DNS_NOTIFY_VALID(notify)); 12519 INSIST(task == notify->zone->task); 12520 result = ev->ev_type; 12521 isc_event_free(&ev); 12522 if (result == DNS_EVENT_ADBMOREADDRESSES) { 12523 dns_adb_destroyfind(¬ify->find); 12524 notify_find_address(notify); 12525 return; 12526 } 12527 if (result == DNS_EVENT_ADBNOMOREADDRESSES) { 12528 LOCK_ZONE(notify->zone); 12529 notify_send(notify); 12530 UNLOCK_ZONE(notify->zone); 12531 } 12532 notify_destroy(notify, false); 12533} 12534 12535static void 12536notify_find_address(dns_notify_t *notify) { 12537 isc_result_t result; 12538 unsigned int options; 12539 12540 REQUIRE(DNS_NOTIFY_VALID(notify)); 12541 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET | DNS_ADBFIND_INET6 | 12542 DNS_ADBFIND_RETURNLAME; 12543 12544 if (notify->zone->view->adb == NULL) { 12545 goto destroy; 12546 } 12547 12548 result = dns_adb_createfind( 12549 notify->zone->view->adb, notify->zone->task, process_adb_event, 12550 notify, ¬ify->ns, dns_rootname, 0, options, 0, NULL, 12551 notify->zone->view->dstport, 0, NULL, ¬ify->find); 12552 12553 /* Something failed? */ 12554 if (result != ISC_R_SUCCESS) { 12555 goto destroy; 12556 } 12557 12558 /* More addresses pending? */ 12559 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) { 12560 return; 12561 } 12562 12563 /* We have as many addresses as we can get. */ 12564 LOCK_ZONE(notify->zone); 12565 notify_send(notify); 12566 UNLOCK_ZONE(notify->zone); 12567 12568destroy: 12569 notify_destroy(notify, false); 12570} 12571 12572static isc_result_t 12573notify_send_queue(dns_notify_t *notify, bool startup) { 12574 isc_event_t *e; 12575 isc_result_t result; 12576 12577 INSIST(notify->event == NULL); 12578 e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR, 12579 notify_send_toaddr, notify, sizeof(isc_event_t)); 12580 if (startup) { 12581 notify->event = e; 12582 } 12583 e->ev_arg = notify; 12584 e->ev_sender = NULL; 12585 result = isc_ratelimiter_enqueue( 12586 startup ? notify->zone->zmgr->startupnotifyrl 12587 : notify->zone->zmgr->notifyrl, 12588 notify->zone->task, &e); 12589 if (result != ISC_R_SUCCESS) { 12590 isc_event_free(&e); 12591 notify->event = NULL; 12592 } 12593 return (result); 12594} 12595 12596static void 12597notify_send_toaddr(isc_task_t *task, isc_event_t *event) { 12598 dns_notify_t *notify; 12599 isc_result_t result; 12600 dns_message_t *message = NULL; 12601 isc_netaddr_t dstip; 12602 dns_tsigkey_t *key = NULL; 12603 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 12604 isc_sockaddr_t src; 12605 unsigned int options, timeout; 12606 bool have_notifysource = false; 12607 12608 notify = event->ev_arg; 12609 REQUIRE(DNS_NOTIFY_VALID(notify)); 12610 12611 UNUSED(task); 12612 12613 LOCK_ZONE(notify->zone); 12614 12615 notify->event = NULL; 12616 12617 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) { 12618 result = ISC_R_CANCELED; 12619 goto cleanup; 12620 } 12621 12622 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 || 12623 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) || 12624 notify->zone->view->requestmgr == NULL || notify->zone->db == NULL) 12625 { 12626 result = ISC_R_CANCELED; 12627 goto cleanup; 12628 } 12629 12630 /* 12631 * The raw IPv4 address should also exist. Don't send to the 12632 * mapped form. 12633 */ 12634 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 && 12635 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) 12636 { 12637 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 12638 notify_log(notify->zone, ISC_LOG_DEBUG(3), 12639 "notify: ignoring IPv6 mapped IPV4 address: %s", 12640 addrbuf); 12641 result = ISC_R_CANCELED; 12642 goto cleanup; 12643 } 12644 12645 result = notify_createmessage(notify->zone, notify->flags, &message); 12646 if (result != ISC_R_SUCCESS) { 12647 goto cleanup; 12648 } 12649 12650 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 12651 if (notify->key != NULL) { 12652 /* Transfer ownership of key */ 12653 key = notify->key; 12654 notify->key = NULL; 12655 } else { 12656 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst); 12657 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key); 12658 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 12659 notify_log(notify->zone, ISC_LOG_ERROR, 12660 "NOTIFY to %s not sent. " 12661 "Peer TSIG key lookup failure.", 12662 addrbuf); 12663 goto cleanup_message; 12664 } 12665 } 12666 12667 if (key != NULL) { 12668 char namebuf[DNS_NAME_FORMATSIZE]; 12669 12670 dns_name_format(&key->name, namebuf, sizeof(namebuf)); 12671 notify_log(notify->zone, ISC_LOG_DEBUG(3), 12672 "sending notify to %s : TSIG (%s)", addrbuf, 12673 namebuf); 12674 } else { 12675 notify_log(notify->zone, ISC_LOG_DEBUG(3), 12676 "sending notify to %s", addrbuf); 12677 } 12678 options = 0; 12679 if (notify->zone->view->peers != NULL) { 12680 dns_peer_t *peer = NULL; 12681 bool usetcp = false; 12682 result = dns_peerlist_peerbyaddr(notify->zone->view->peers, 12683 &dstip, &peer); 12684 if (result == ISC_R_SUCCESS) { 12685 result = dns_peer_getnotifysource(peer, &src); 12686 if (result == ISC_R_SUCCESS) { 12687 have_notifysource = true; 12688 } 12689 result = dns_peer_getforcetcp(peer, &usetcp); 12690 if (result == ISC_R_SUCCESS && usetcp) { 12691 options |= DNS_FETCHOPT_TCP; 12692 } 12693 } 12694 } 12695 switch (isc_sockaddr_pf(¬ify->dst)) { 12696 case PF_INET: 12697 if (!have_notifysource) { 12698 src = notify->zone->notifysrc4; 12699 } 12700 break; 12701 case PF_INET6: 12702 if (!have_notifysource) { 12703 src = notify->zone->notifysrc6; 12704 } 12705 break; 12706 default: 12707 result = ISC_R_NOTIMPLEMENTED; 12708 goto cleanup_key; 12709 } 12710 timeout = 5; 12711 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) { 12712 timeout = 30; 12713 } 12714 result = dns_request_create( 12715 notify->zone->view->requestmgr, message, &src, ¬ify->dst, 12716 options, key, timeout * 3 + 1, timeout, 2, notify->zone->task, 12717 notify_done, notify, ¬ify->request); 12718 if (result == ISC_R_SUCCESS) { 12719 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) { 12720 inc_stats(notify->zone, 12721 dns_zonestatscounter_notifyoutv4); 12722 } else { 12723 inc_stats(notify->zone, 12724 dns_zonestatscounter_notifyoutv6); 12725 } 12726 } 12727 12728cleanup_key: 12729 if (key != NULL) { 12730 dns_tsigkey_detach(&key); 12731 } 12732cleanup_message: 12733 dns_message_detach(&message); 12734cleanup: 12735 UNLOCK_ZONE(notify->zone); 12736 isc_event_free(&event); 12737 if (result != ISC_R_SUCCESS) { 12738 notify_destroy(notify, false); 12739 } 12740} 12741 12742static void 12743notify_send(dns_notify_t *notify) { 12744 dns_adbaddrinfo_t *ai; 12745 isc_sockaddr_t dst; 12746 isc_result_t result; 12747 dns_notify_t *newnotify = NULL; 12748 unsigned int flags; 12749 bool startup; 12750 12751 /* 12752 * Zone lock held by caller. 12753 */ 12754 REQUIRE(DNS_NOTIFY_VALID(notify)); 12755 REQUIRE(LOCKED_ZONE(notify->zone)); 12756 12757 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING)) { 12758 return; 12759 } 12760 12761 for (ai = ISC_LIST_HEAD(notify->find->list); ai != NULL; 12762 ai = ISC_LIST_NEXT(ai, publink)) 12763 { 12764 dst = ai->sockaddr; 12765 if (notify_isqueued(notify->zone, notify->flags, NULL, &dst, 12766 NULL, NULL)) 12767 { 12768 continue; 12769 } 12770 if (notify_isself(notify->zone, &dst)) { 12771 continue; 12772 } 12773 newnotify = NULL; 12774 flags = notify->flags & DNS_NOTIFY_NOSOA; 12775 result = notify_create(notify->mctx, flags, &newnotify); 12776 if (result != ISC_R_SUCCESS) { 12777 goto cleanup; 12778 } 12779 zone_iattach(notify->zone, &newnotify->zone); 12780 ISC_LIST_APPEND(newnotify->zone->notifies, newnotify, link); 12781 newnotify->dst = dst; 12782 startup = ((notify->flags & DNS_NOTIFY_STARTUP) != 0); 12783 result = notify_send_queue(newnotify, startup); 12784 if (result != ISC_R_SUCCESS) { 12785 goto cleanup; 12786 } 12787 newnotify = NULL; 12788 } 12789 12790cleanup: 12791 if (newnotify != NULL) { 12792 notify_destroy(newnotify, true); 12793 } 12794} 12795 12796void 12797dns_zone_notify(dns_zone_t *zone) { 12798 isc_time_t now; 12799 12800 REQUIRE(DNS_ZONE_VALID(zone)); 12801 12802 LOCK_ZONE(zone); 12803 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12804 12805 TIME_NOW(&now); 12806 zone_settimer(zone, &now); 12807 UNLOCK_ZONE(zone); 12808} 12809 12810static void 12811zone_notify(dns_zone_t *zone, isc_time_t *now) { 12812 dns_dbnode_t *node = NULL; 12813 dns_db_t *zonedb = NULL; 12814 dns_dbversion_t *version = NULL; 12815 dns_name_t *origin = NULL; 12816 dns_name_t primary; 12817 dns_rdata_ns_t ns; 12818 dns_rdata_soa_t soa; 12819 uint32_t serial; 12820 dns_rdata_t rdata = DNS_RDATA_INIT; 12821 dns_rdataset_t nsrdset; 12822 dns_rdataset_t soardset; 12823 isc_result_t result; 12824 unsigned int i; 12825 isc_sockaddr_t dst; 12826 bool isqueued; 12827 dns_notifytype_t notifytype; 12828 unsigned int flags = 0; 12829 bool loggednotify = false; 12830 bool startup; 12831 12832 REQUIRE(DNS_ZONE_VALID(zone)); 12833 12834 LOCK_ZONE(zone); 12835 startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12836 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12837 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY); 12838 notifytype = zone->notifytype; 12839 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime); 12840 UNLOCK_ZONE(zone); 12841 12842 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || 12843 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 12844 { 12845 return; 12846 } 12847 12848 if (notifytype == dns_notifytype_no) { 12849 return; 12850 } 12851 12852 if (notifytype == dns_notifytype_masteronly && 12853 zone->type != dns_zone_primary) 12854 { 12855 return; 12856 } 12857 12858 origin = &zone->origin; 12859 12860 /* 12861 * If the zone is dialup we are done as we don't want to send 12862 * the current soa so as to force a refresh query. 12863 */ 12864 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) { 12865 flags |= DNS_NOTIFY_NOSOA; 12866 } 12867 12868 /* 12869 * Record that this was a notify due to starting up. 12870 */ 12871 if (startup) { 12872 flags |= DNS_NOTIFY_STARTUP; 12873 } 12874 12875 /* 12876 * Get SOA RRset. 12877 */ 12878 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12879 if (zone->db != NULL) { 12880 dns_db_attach(zone->db, &zonedb); 12881 } 12882 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12883 if (zonedb == NULL) { 12884 return; 12885 } 12886 dns_db_currentversion(zonedb, &version); 12887 result = dns_db_findnode(zonedb, origin, false, &node); 12888 if (result != ISC_R_SUCCESS) { 12889 goto cleanup1; 12890 } 12891 12892 dns_rdataset_init(&soardset); 12893 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, 12894 dns_rdatatype_none, 0, &soardset, NULL); 12895 if (result != ISC_R_SUCCESS) { 12896 goto cleanup2; 12897 } 12898 12899 /* 12900 * Find serial and primary server's name. 12901 */ 12902 dns_name_init(&primary, NULL); 12903 result = dns_rdataset_first(&soardset); 12904 if (result != ISC_R_SUCCESS) { 12905 goto cleanup3; 12906 } 12907 dns_rdataset_current(&soardset, &rdata); 12908 result = dns_rdata_tostruct(&rdata, &soa, NULL); 12909 RUNTIME_CHECK(result == ISC_R_SUCCESS); 12910 dns_rdata_reset(&rdata); 12911 dns_name_dup(&soa.origin, zone->mctx, &primary); 12912 serial = soa.serial; 12913 dns_rdataset_disassociate(&soardset); 12914 12915 /* 12916 * Enqueue notify requests for 'also-notify' servers. 12917 */ 12918 LOCK_ZONE(zone); 12919 for (i = 0; i < zone->notifycnt; i++) { 12920 dns_tsigkey_t *key = NULL; 12921 dns_transport_t *transport = NULL; 12922 dns_notify_t *notify = NULL; 12923 dns_view_t *view = dns_zone_getview(zone); 12924 12925 if ((zone->notifykeynames != NULL) && 12926 (zone->notifykeynames[i] != NULL)) 12927 { 12928 dns_name_t *keyname = zone->notifykeynames[i]; 12929 (void)dns_view_gettsig(view, keyname, &key); 12930 } 12931 12932 if ((zone->notifytlsnames != NULL) && 12933 (zone->notifytlsnames[i] != NULL)) 12934 { 12935 dns_name_t *tlsname = zone->notifytlsnames[i]; 12936 (void)dns_view_gettransport(view, DNS_TRANSPORT_TLS, 12937 tlsname, &transport); 12938 12939 dns_zone_logc( 12940 zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 12941 "got TLS configuration for zone transfer"); 12942 } 12943 12944 /* TODO: glue the transport to the notify */ 12945 12946 dst = zone->notify[i]; 12947 if (notify_isqueued(zone, flags, NULL, &dst, key, transport)) { 12948 if (key != NULL) { 12949 dns_tsigkey_detach(&key); 12950 } 12951 if (transport != NULL) { 12952 dns_transport_detach(&transport); 12953 } 12954 continue; 12955 } 12956 12957 result = notify_create(zone->mctx, flags, ¬ify); 12958 if (result != ISC_R_SUCCESS) { 12959 if (key != NULL) { 12960 dns_tsigkey_detach(&key); 12961 } 12962 if (transport != NULL) { 12963 dns_transport_detach(&transport); 12964 } 12965 continue; 12966 } 12967 12968 zone_iattach(zone, ¬ify->zone); 12969 notify->dst = dst; 12970 12971 INSIST(notify->key == NULL); 12972 12973 if (key != NULL) { 12974 notify->key = key; 12975 key = NULL; 12976 } 12977 12978 INSIST(notify->transport == NULL); 12979 if (transport != NULL) { 12980 notify->transport = transport; 12981 transport = NULL; 12982 } 12983 12984 ISC_LIST_APPEND(zone->notifies, notify, link); 12985 result = notify_send_queue(notify, startup); 12986 if (result != ISC_R_SUCCESS) { 12987 notify_destroy(notify, true); 12988 } 12989 if (!loggednotify) { 12990 notify_log(zone, ISC_LOG_INFO, 12991 "sending notifies (serial %u)", serial); 12992 loggednotify = true; 12993 } 12994 } 12995 UNLOCK_ZONE(zone); 12996 12997 if (notifytype == dns_notifytype_explicit) { 12998 goto cleanup3; 12999 } 13000 13001 /* 13002 * Process NS RRset to generate notifies. 13003 */ 13004 13005 dns_rdataset_init(&nsrdset); 13006 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns, 13007 dns_rdatatype_none, 0, &nsrdset, NULL); 13008 if (result != ISC_R_SUCCESS) { 13009 goto cleanup3; 13010 } 13011 13012 result = dns_rdataset_first(&nsrdset); 13013 while (result == ISC_R_SUCCESS) { 13014 dns_notify_t *notify = NULL; 13015 13016 dns_rdataset_current(&nsrdset, &rdata); 13017 result = dns_rdata_tostruct(&rdata, &ns, NULL); 13018 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13019 dns_rdata_reset(&rdata); 13020 /* 13021 * Don't notify the primary server unless explicitly 13022 * configured to do so. 13023 */ 13024 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) && 13025 dns_name_compare(&primary, &ns.name) == 0) 13026 { 13027 result = dns_rdataset_next(&nsrdset); 13028 continue; 13029 } 13030 13031 if (!loggednotify) { 13032 notify_log(zone, ISC_LOG_INFO, 13033 "sending notifies (serial %u)", serial); 13034 loggednotify = true; 13035 } 13036 13037 LOCK_ZONE(zone); 13038 isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL, 13039 NULL); 13040 UNLOCK_ZONE(zone); 13041 if (isqueued) { 13042 result = dns_rdataset_next(&nsrdset); 13043 continue; 13044 } 13045 result = notify_create(zone->mctx, flags, ¬ify); 13046 if (result != ISC_R_SUCCESS) { 13047 continue; 13048 } 13049 dns_zone_iattach(zone, ¬ify->zone); 13050 dns_name_dup(&ns.name, zone->mctx, ¬ify->ns); 13051 LOCK_ZONE(zone); 13052 ISC_LIST_APPEND(zone->notifies, notify, link); 13053 UNLOCK_ZONE(zone); 13054 notify_find_address(notify); 13055 result = dns_rdataset_next(&nsrdset); 13056 } 13057 dns_rdataset_disassociate(&nsrdset); 13058 13059cleanup3: 13060 if (dns_name_dynamic(&primary)) { 13061 dns_name_free(&primary, zone->mctx); 13062 } 13063cleanup2: 13064 dns_db_detachnode(zonedb, &node); 13065cleanup1: 13066 dns_db_closeversion(zonedb, &version, false); 13067 dns_db_detach(&zonedb); 13068} 13069 13070/*** 13071 *** Private 13072 ***/ 13073static isc_result_t 13074create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, dns_name_t *name, 13075 dns_message_t **messagep) { 13076 dns_message_t *message = NULL; 13077 dns_name_t *qname = NULL; 13078 dns_rdataset_t *qrdataset = NULL; 13079 isc_result_t result; 13080 13081 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message); 13082 13083 message->opcode = dns_opcode_query; 13084 message->rdclass = zone->rdclass; 13085 13086 result = dns_message_gettempname(message, &qname); 13087 if (result != ISC_R_SUCCESS) { 13088 goto cleanup; 13089 } 13090 13091 result = dns_message_gettemprdataset(message, &qrdataset); 13092 if (result != ISC_R_SUCCESS) { 13093 goto cleanup; 13094 } 13095 13096 /* 13097 * Make question. 13098 */ 13099 dns_name_clone(name, qname); 13100 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype); 13101 ISC_LIST_APPEND(qname->list, qrdataset, link); 13102 dns_message_addname(message, qname, DNS_SECTION_QUESTION); 13103 13104 *messagep = message; 13105 return (ISC_R_SUCCESS); 13106 13107cleanup: 13108 if (qname != NULL) { 13109 dns_message_puttempname(message, &qname); 13110 } 13111 if (qrdataset != NULL) { 13112 dns_message_puttemprdataset(message, &qrdataset); 13113 } 13114 dns_message_detach(&message); 13115 return (result); 13116} 13117 13118static isc_result_t 13119add_opt(dns_message_t *message, uint16_t udpsize, bool reqnsid, 13120 bool reqexpire) { 13121 isc_result_t result; 13122 dns_rdataset_t *rdataset = NULL; 13123 dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS]; 13124 int count = 0; 13125 13126 /* Set EDNS options if applicable. */ 13127 if (reqnsid) { 13128 INSIST(count < DNS_EDNSOPTIONS); 13129 ednsopts[count].code = DNS_OPT_NSID; 13130 ednsopts[count].length = 0; 13131 ednsopts[count].value = NULL; 13132 count++; 13133 } 13134 if (reqexpire) { 13135 INSIST(count < DNS_EDNSOPTIONS); 13136 ednsopts[count].code = DNS_OPT_EXPIRE; 13137 ednsopts[count].length = 0; 13138 ednsopts[count].value = NULL; 13139 count++; 13140 } 13141 result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0, 13142 ednsopts, count); 13143 if (result != ISC_R_SUCCESS) { 13144 return (result); 13145 } 13146 13147 return (dns_message_setopt(message, rdataset)); 13148} 13149 13150/* 13151 * Called when stub zone update is finished. 13152 * Update zone refresh, retry, expire values accordingly with 13153 * SOA received from primary, sync database to file, restart 13154 * zone management timer. 13155 */ 13156static void 13157stub_finish_zone_update(dns_stub_t *stub, isc_time_t now) { 13158 uint32_t refresh, retry, expire; 13159 isc_result_t result; 13160 isc_interval_t i; 13161 unsigned int soacount; 13162 dns_zone_t *zone = stub->zone; 13163 13164 /* 13165 * Tidy up. 13166 */ 13167 dns_db_closeversion(stub->db, &stub->version, true); 13168 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 13169 if (zone->db == NULL) { 13170 zone_attachdb(zone, stub->db); 13171 } 13172 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, NULL, 13173 &refresh, &retry, &expire, NULL, NULL); 13174 if (result == ISC_R_SUCCESS && soacount > 0U) { 13175 zone->refresh = RANGE(refresh, zone->minrefresh, 13176 zone->maxrefresh); 13177 zone->retry = RANGE(retry, zone->minretry, zone->maxretry); 13178 zone->expire = RANGE(expire, zone->refresh + zone->retry, 13179 DNS_MAX_EXPIRE); 13180 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 13181 } 13182 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 13183 dns_db_detach(&stub->db); 13184 13185 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 13186 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 13187 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 13188 isc_interval_set(&i, zone->expire, 0); 13189 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); 13190 13191 if (zone->masterfile != NULL) { 13192 zone_needdump(zone, 0); 13193 } 13194 13195 zone_settimer(zone, &now); 13196} 13197 13198/* 13199 * Process answers for A and AAAA queries when 13200 * resolving nameserver addresses for which glue 13201 * was missing in a previous answer for a NS query. 13202 */ 13203static void 13204stub_glue_response_cb(isc_task_t *task, isc_event_t *event) { 13205 const char me[] = "stub_glue_response_cb"; 13206 dns_requestevent_t *revent = (dns_requestevent_t *)event; 13207 dns_stub_t *stub = NULL; 13208 dns_message_t *msg = NULL; 13209 dns_zone_t *zone = NULL; 13210 char primary[ISC_SOCKADDR_FORMATSIZE]; 13211 char source[ISC_SOCKADDR_FORMATSIZE]; 13212 uint32_t addr_count, cnamecnt; 13213 isc_result_t result; 13214 isc_time_t now; 13215 struct stub_glue_request *request; 13216 struct stub_cb_args *cb_args; 13217 dns_rdataset_t *addr_rdataset = NULL; 13218 dns_dbnode_t *node = NULL; 13219 13220 UNUSED(task); 13221 13222 request = revent->ev_arg; 13223 cb_args = request->args; 13224 stub = cb_args->stub; 13225 INSIST(DNS_STUB_VALID(stub)); 13226 13227 zone = stub->zone; 13228 13229 ENTER; 13230 13231 TIME_NOW(&now); 13232 13233 LOCK_ZONE(zone); 13234 13235 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 13236 zone_debuglog(zone, me, 1, "exiting"); 13237 goto cleanup; 13238 } 13239 13240 isc_sockaddr_format(&zone->primaryaddr, primary, sizeof(primary)); 13241 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 13242 13243 if (revent->result != ISC_R_SUCCESS) { 13244 dns_zonemgr_unreachableadd(zone->zmgr, &zone->primaryaddr, 13245 &zone->sourceaddr, &now); 13246 dns_zone_log(zone, ISC_LOG_INFO, 13247 "could not refresh stub from primary %s" 13248 " (source %s): %s", 13249 primary, source, 13250 isc_result_totext(revent->result)); 13251 goto cleanup; 13252 } 13253 13254 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 13255 result = dns_request_getresponse(revent->request, msg, 0); 13256 if (result != ISC_R_SUCCESS) { 13257 dns_zone_log(zone, ISC_LOG_INFO, 13258 "refreshing stub: unable to parse response (%s)", 13259 isc_result_totext(result)); 13260 goto cleanup; 13261 } 13262 13263 /* 13264 * Unexpected opcode. 13265 */ 13266 if (msg->opcode != dns_opcode_query) { 13267 char opcode[128]; 13268 isc_buffer_t rb; 13269 13270 isc_buffer_init(&rb, opcode, sizeof(opcode)); 13271 (void)dns_opcode_totext(msg->opcode, &rb); 13272 13273 dns_zone_log(zone, ISC_LOG_INFO, 13274 "refreshing stub: " 13275 "unexpected opcode (%.*s) from %s (source %s)", 13276 (int)rb.used, opcode, primary, source); 13277 goto cleanup; 13278 } 13279 13280 /* 13281 * Unexpected rcode. 13282 */ 13283 if (msg->rcode != dns_rcode_noerror) { 13284 char rcode[128]; 13285 isc_buffer_t rb; 13286 13287 isc_buffer_init(&rb, rcode, sizeof(rcode)); 13288 (void)dns_rcode_totext(msg->rcode, &rb); 13289 13290 dns_zone_log(zone, ISC_LOG_INFO, 13291 "refreshing stub: " 13292 "unexpected rcode (%.*s) from %s (source %s)", 13293 (int)rb.used, rcode, primary, source); 13294 goto cleanup; 13295 } 13296 13297 /* 13298 * We need complete messages. 13299 */ 13300 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 13301 if (dns_request_usedtcp(revent->request)) { 13302 dns_zone_log(zone, ISC_LOG_INFO, 13303 "refreshing stub: truncated TCP " 13304 "response from primary %s (source %s)", 13305 primary, source); 13306 } 13307 goto cleanup; 13308 } 13309 13310 /* 13311 * If non-auth log. 13312 */ 13313 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 13314 dns_zone_log(zone, ISC_LOG_INFO, 13315 "refreshing stub: " 13316 "non-authoritative answer from " 13317 "primary %s (source %s)", 13318 primary, source); 13319 goto cleanup; 13320 } 13321 13322 /* 13323 * Sanity checks. 13324 */ 13325 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 13326 addr_count = message_count(msg, DNS_SECTION_ANSWER, 13327 request->ipv4 ? dns_rdatatype_a 13328 : dns_rdatatype_aaaa); 13329 13330 if (cnamecnt != 0) { 13331 dns_zone_log(zone, ISC_LOG_INFO, 13332 "refreshing stub: unexpected CNAME response " 13333 "from primary %s (source %s)", 13334 primary, source); 13335 goto cleanup; 13336 } 13337 13338 if (addr_count == 0) { 13339 dns_zone_log(zone, ISC_LOG_INFO, 13340 "refreshing stub: no %s records in response " 13341 "from primary %s (source %s)", 13342 request->ipv4 ? "A" : "AAAA", primary, source); 13343 goto cleanup; 13344 } 13345 /* 13346 * Extract A or AAAA RRset from message. 13347 */ 13348 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &request->name, 13349 request->ipv4 ? dns_rdatatype_a 13350 : dns_rdatatype_aaaa, 13351 dns_rdatatype_none, NULL, &addr_rdataset); 13352 if (result != ISC_R_SUCCESS) { 13353 if (result != DNS_R_NXDOMAIN && result != DNS_R_NXRRSET) { 13354 char namebuf[DNS_NAME_FORMATSIZE]; 13355 dns_name_format(&request->name, namebuf, 13356 sizeof(namebuf)); 13357 dns_zone_log( 13358 zone, ISC_LOG_INFO, 13359 "refreshing stub: dns_message_findname(%s/%s) " 13360 "failed (%s)", 13361 namebuf, request->ipv4 ? "A" : "AAAA", 13362 isc_result_totext(result)); 13363 } 13364 goto cleanup; 13365 } 13366 13367 result = dns_db_findnode(stub->db, &request->name, true, &node); 13368 if (result != ISC_R_SUCCESS) { 13369 dns_zone_log(zone, ISC_LOG_INFO, 13370 "refreshing stub: " 13371 "dns_db_findnode() failed: %s", 13372 isc_result_totext(result)); 13373 goto cleanup; 13374 } 13375 13376 result = dns_db_addrdataset(stub->db, node, stub->version, 0, 13377 addr_rdataset, 0, NULL); 13378 if (result != ISC_R_SUCCESS) { 13379 dns_zone_log(zone, ISC_LOG_INFO, 13380 "refreshing stub: " 13381 "dns_db_addrdataset() failed: %s", 13382 isc_result_totext(result)); 13383 } 13384 dns_db_detachnode(stub->db, &node); 13385 13386cleanup: 13387 if (msg != NULL) { 13388 dns_message_detach(&msg); 13389 } 13390 isc_event_free(&event); 13391 dns_name_free(&request->name, zone->mctx); 13392 dns_request_destroy(&request->request); 13393 isc_mem_put(zone->mctx, request, sizeof(*request)); 13394 13395 /* If last request, release all related resources */ 13396 if (atomic_fetch_sub_release(&stub->pending_requests, 1) == 1) { 13397 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13398 stub_finish_zone_update(stub, now); 13399 UNLOCK_ZONE(zone); 13400 stub->magic = 0; 13401 dns_zone_idetach(&stub->zone); 13402 INSIST(stub->db == NULL); 13403 INSIST(stub->version == NULL); 13404 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 13405 } else { 13406 UNLOCK_ZONE(zone); 13407 } 13408} 13409 13410/* 13411 * Create and send an A or AAAA query to the primary 13412 * server of the stub zone given. 13413 */ 13414static isc_result_t 13415stub_request_nameserver_address(struct stub_cb_args *args, bool ipv4, 13416 const dns_name_t *name) { 13417 dns_message_t *message = NULL; 13418 dns_zone_t *zone; 13419 isc_result_t result; 13420 struct stub_glue_request *request; 13421 13422 zone = args->stub->zone; 13423 request = isc_mem_get(zone->mctx, sizeof(*request)); 13424 request->request = NULL; 13425 request->args = args; 13426 request->name = (dns_name_t)DNS_NAME_INITEMPTY; 13427 request->ipv4 = ipv4; 13428 dns_name_dup(name, zone->mctx, &request->name); 13429 13430 result = create_query(zone, ipv4 ? dns_rdatatype_a : dns_rdatatype_aaaa, 13431 &request->name, &message); 13432 INSIST(result == ISC_R_SUCCESS); 13433 13434 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 13435 result = add_opt(message, args->udpsize, args->reqnsid, false); 13436 if (result != ISC_R_SUCCESS) { 13437 zone_debuglog(zone, "stub_send_query", 1, 13438 "unable to add opt record: %s", 13439 isc_result_totext(result)); 13440 goto fail; 13441 } 13442 } 13443 13444 atomic_fetch_add_release(&args->stub->pending_requests, 1); 13445 13446 result = dns_request_create( 13447 zone->view->requestmgr, message, &zone->sourceaddr, 13448 &zone->primaryaddr, DNS_REQUESTOPT_TCP, args->tsig_key, 13449 args->timeout * 3, args->timeout, 2, zone->task, 13450 stub_glue_response_cb, request, &request->request); 13451 13452 if (result != ISC_R_SUCCESS) { 13453 uint_fast32_t pr; 13454 pr = atomic_fetch_sub_release(&args->stub->pending_requests, 1); 13455 INSIST(pr > 1); 13456 zone_debuglog(zone, "stub_send_query", 1, 13457 "dns_request_create() failed: %s", 13458 isc_result_totext(result)); 13459 goto fail; 13460 } 13461 13462 dns_message_detach(&message); 13463 13464 return (ISC_R_SUCCESS); 13465 13466fail: 13467 dns_name_free(&request->name, zone->mctx); 13468 isc_mem_put(zone->mctx, request, sizeof(*request)); 13469 13470 if (message != NULL) { 13471 dns_message_detach(&message); 13472 } 13473 13474 return (result); 13475} 13476 13477static isc_result_t 13478save_nsrrset(dns_message_t *message, dns_name_t *name, 13479 struct stub_cb_args *cb_args, dns_db_t *db, 13480 dns_dbversion_t *version) { 13481 dns_rdataset_t *nsrdataset = NULL; 13482 dns_rdataset_t *rdataset = NULL; 13483 dns_dbnode_t *node = NULL; 13484 dns_rdata_ns_t ns; 13485 isc_result_t result; 13486 dns_rdata_t rdata = DNS_RDATA_INIT; 13487 bool has_glue = false; 13488 dns_name_t *ns_name; 13489 /* 13490 * List of NS entries in answer, keep names that will be used 13491 * to resolve missing A/AAAA glue for each entry. 13492 */ 13493 dns_namelist_t ns_list; 13494 ISC_LIST_INIT(ns_list); 13495 13496 /* 13497 * Extract NS RRset from message. 13498 */ 13499 result = dns_message_findname(message, DNS_SECTION_ANSWER, name, 13500 dns_rdatatype_ns, dns_rdatatype_none, 13501 NULL, &nsrdataset); 13502 if (result != ISC_R_SUCCESS) { 13503 goto done; 13504 } 13505 13506 /* 13507 * Add NS rdataset. 13508 */ 13509 result = dns_db_findnode(db, name, true, &node); 13510 if (result != ISC_R_SUCCESS) { 13511 goto done; 13512 } 13513 result = dns_db_addrdataset(db, node, version, 0, nsrdataset, 0, NULL); 13514 dns_db_detachnode(db, &node); 13515 if (result != ISC_R_SUCCESS) { 13516 goto done; 13517 } 13518 /* 13519 * Add glue rdatasets. 13520 */ 13521 for (result = dns_rdataset_first(nsrdataset); result == ISC_R_SUCCESS; 13522 result = dns_rdataset_next(nsrdataset)) 13523 { 13524 dns_rdataset_current(nsrdataset, &rdata); 13525 result = dns_rdata_tostruct(&rdata, &ns, NULL); 13526 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13527 dns_rdata_reset(&rdata); 13528 13529 if (!dns_name_issubdomain(&ns.name, name)) { 13530 continue; 13531 } 13532 rdataset = NULL; 13533 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL, 13534 &ns.name, dns_rdatatype_aaaa, 13535 dns_rdatatype_none, NULL, 13536 &rdataset); 13537 if (result == ISC_R_SUCCESS) { 13538 has_glue = true; 13539 result = dns_db_findnode(db, &ns.name, true, &node); 13540 if (result != ISC_R_SUCCESS) { 13541 goto done; 13542 } 13543 result = dns_db_addrdataset(db, node, version, 0, 13544 rdataset, 0, NULL); 13545 dns_db_detachnode(db, &node); 13546 if (result != ISC_R_SUCCESS) { 13547 goto done; 13548 } 13549 } 13550 13551 rdataset = NULL; 13552 result = dns_message_findname( 13553 message, DNS_SECTION_ADDITIONAL, &ns.name, 13554 dns_rdatatype_a, dns_rdatatype_none, NULL, &rdataset); 13555 if (result == ISC_R_SUCCESS) { 13556 has_glue = true; 13557 result = dns_db_findnode(db, &ns.name, true, &node); 13558 if (result != ISC_R_SUCCESS) { 13559 goto done; 13560 } 13561 result = dns_db_addrdataset(db, node, version, 0, 13562 rdataset, 0, NULL); 13563 dns_db_detachnode(db, &node); 13564 if (result != ISC_R_SUCCESS) { 13565 goto done; 13566 } 13567 } 13568 13569 /* 13570 * If no glue is found so far, we add the name to the list to 13571 * resolve the A/AAAA glue later. If any glue is found in any 13572 * iteration step, this list will be discarded and only the glue 13573 * provided in this message will be used. 13574 */ 13575 if (!has_glue && dns_name_issubdomain(&ns.name, name)) { 13576 dns_name_t *tmp_name; 13577 tmp_name = isc_mem_get(cb_args->stub->mctx, 13578 sizeof(*tmp_name)); 13579 dns_name_init(tmp_name, NULL); 13580 dns_name_dup(&ns.name, cb_args->stub->mctx, tmp_name); 13581 ISC_LIST_APPEND(ns_list, tmp_name, link); 13582 } 13583 } 13584 13585 if (result != ISC_R_NOMORE) { 13586 goto done; 13587 } 13588 13589 /* 13590 * If no glue records were found, we attempt to resolve A/AAAA 13591 * for each NS entry found in the answer. 13592 */ 13593 if (!has_glue) { 13594 for (ns_name = ISC_LIST_HEAD(ns_list); ns_name != NULL; 13595 ns_name = ISC_LIST_NEXT(ns_name, link)) 13596 { 13597 /* 13598 * Resolve NS IPv4 address/A. 13599 */ 13600 result = stub_request_nameserver_address(cb_args, true, 13601 ns_name); 13602 if (result != ISC_R_SUCCESS) { 13603 goto done; 13604 } 13605 /* 13606 * Resolve NS IPv6 address/AAAA. 13607 */ 13608 result = stub_request_nameserver_address(cb_args, false, 13609 ns_name); 13610 if (result != ISC_R_SUCCESS) { 13611 goto done; 13612 } 13613 } 13614 } 13615 13616 result = ISC_R_SUCCESS; 13617 13618done: 13619 while ((ns_name = ISC_LIST_HEAD(ns_list)) != NULL) { 13620 ISC_LIST_UNLINK(ns_list, ns_name, link); 13621 dns_name_free(ns_name, cb_args->stub->mctx); 13622 isc_mem_put(cb_args->stub->mctx, ns_name, sizeof(*ns_name)); 13623 } 13624 return (result); 13625} 13626 13627static void 13628stub_callback(isc_task_t *task, isc_event_t *event) { 13629 const char me[] = "stub_callback"; 13630 dns_requestevent_t *revent = (dns_requestevent_t *)event; 13631 dns_stub_t *stub = NULL; 13632 dns_message_t *msg = NULL; 13633 dns_zone_t *zone = NULL; 13634 char primary[ISC_SOCKADDR_FORMATSIZE]; 13635 char source[ISC_SOCKADDR_FORMATSIZE]; 13636 uint32_t nscnt, cnamecnt; 13637 isc_result_t result; 13638 isc_time_t now; 13639 bool exiting = false; 13640 unsigned int j; 13641 struct stub_cb_args *cb_args; 13642 13643 cb_args = revent->ev_arg; 13644 stub = cb_args->stub; 13645 INSIST(DNS_STUB_VALID(stub)); 13646 13647 UNUSED(task); 13648 13649 zone = stub->zone; 13650 13651 ENTER; 13652 13653 TIME_NOW(&now); 13654 13655 LOCK_ZONE(zone); 13656 13657 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 13658 goto exiting; 13659 } 13660 13661 isc_sockaddr_format(&zone->primaryaddr, primary, sizeof(primary)); 13662 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 13663 13664 switch (revent->result) { 13665 case ISC_R_SUCCESS: 13666 break; 13667 case ISC_R_SHUTTINGDOWN: 13668 goto exiting; 13669 case ISC_R_TIMEDOUT: 13670 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 13671 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 13672 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13673 "refreshing stub: timeout retrying " 13674 "without EDNS primary %s (source %s)", 13675 primary, source); 13676 goto same_primary; 13677 } 13678 FALLTHROUGH; 13679 default: 13680 dns_zonemgr_unreachableadd(zone->zmgr, &zone->primaryaddr, 13681 &zone->sourceaddr, &now); 13682 dns_zone_log(zone, ISC_LOG_INFO, 13683 "could not refresh stub from primary " 13684 "%s (source %s): %s", 13685 primary, source, 13686 isc_result_totext(revent->result)); 13687 goto next_primary; 13688 } 13689 13690 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 13691 13692 result = dns_request_getresponse(revent->request, msg, 0); 13693 if (result != ISC_R_SUCCESS) { 13694 goto next_primary; 13695 } 13696 13697 /* 13698 * Unexpected opcode. 13699 */ 13700 if (msg->opcode != dns_opcode_query) { 13701 char opcode[128]; 13702 isc_buffer_t rb; 13703 13704 isc_buffer_init(&rb, opcode, sizeof(opcode)); 13705 (void)dns_opcode_totext(msg->opcode, &rb); 13706 13707 dns_zone_log(zone, ISC_LOG_INFO, 13708 "refreshing stub: " 13709 "unexpected opcode (%.*s) from %s (source %s)", 13710 (int)rb.used, opcode, primary, source); 13711 goto next_primary; 13712 } 13713 13714 /* 13715 * Unexpected rcode. 13716 */ 13717 if (msg->rcode != dns_rcode_noerror) { 13718 char rcode[128]; 13719 isc_buffer_t rb; 13720 13721 isc_buffer_init(&rb, rcode, sizeof(rcode)); 13722 (void)dns_rcode_totext(msg->rcode, &rb); 13723 13724 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 13725 (msg->rcode == dns_rcode_servfail || 13726 msg->rcode == dns_rcode_notimp || 13727 (msg->rcode == dns_rcode_formerr && msg->opt == NULL))) 13728 { 13729 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13730 "refreshing stub: rcode (%.*s) retrying " 13731 "without EDNS primary %s (source %s)", 13732 (int)rb.used, rcode, primary, source); 13733 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 13734 goto same_primary; 13735 } 13736 13737 dns_zone_log(zone, ISC_LOG_INFO, 13738 "refreshing stub: " 13739 "unexpected rcode (%.*s) from %s (source %s)", 13740 (int)rb.used, rcode, primary, source); 13741 goto next_primary; 13742 } 13743 13744 /* 13745 * We need complete messages. 13746 */ 13747 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 13748 if (dns_request_usedtcp(revent->request)) { 13749 dns_zone_log(zone, ISC_LOG_INFO, 13750 "refreshing stub: truncated TCP " 13751 "response from primary %s (source %s)", 13752 primary, source); 13753 goto next_primary; 13754 } 13755 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 13756 goto same_primary; 13757 } 13758 13759 /* 13760 * If non-auth log and next primary. 13761 */ 13762 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 13763 dns_zone_log(zone, ISC_LOG_INFO, 13764 "refreshing stub: " 13765 "non-authoritative answer from " 13766 "primary %s (source %s)", 13767 primary, source); 13768 goto next_primary; 13769 } 13770 13771 /* 13772 * Sanity checks. 13773 */ 13774 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 13775 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns); 13776 13777 if (cnamecnt != 0) { 13778 dns_zone_log(zone, ISC_LOG_INFO, 13779 "refreshing stub: unexpected CNAME response " 13780 "from primary %s (source %s)", 13781 primary, source); 13782 goto next_primary; 13783 } 13784 13785 if (nscnt == 0) { 13786 dns_zone_log(zone, ISC_LOG_INFO, 13787 "refreshing stub: no NS records in response " 13788 "from primary %s (source %s)", 13789 primary, source); 13790 goto next_primary; 13791 } 13792 13793 atomic_fetch_add(&stub->pending_requests, 1); 13794 13795 /* 13796 * Save answer. 13797 */ 13798 result = save_nsrrset(msg, &zone->origin, cb_args, stub->db, 13799 stub->version); 13800 if (result != ISC_R_SUCCESS) { 13801 dns_zone_log(zone, ISC_LOG_INFO, 13802 "refreshing stub: unable to save NS records " 13803 "from primary %s (source %s)", 13804 primary, source); 13805 goto next_primary; 13806 } 13807 13808 dns_message_detach(&msg); 13809 isc_event_free(&event); 13810 dns_request_destroy(&zone->request); 13811 13812 /* 13813 * Check to see if there are no outstanding requests and 13814 * finish off if that is so. 13815 */ 13816 if (atomic_fetch_sub(&stub->pending_requests, 1) == 1) { 13817 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13818 stub_finish_zone_update(stub, now); 13819 goto free_stub; 13820 } 13821 13822 UNLOCK_ZONE(zone); 13823 return; 13824 13825exiting: 13826 zone_debuglog(zone, me, 1, "exiting"); 13827 exiting = true; 13828 13829next_primary: 13830 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13831 if (stub->version != NULL) { 13832 dns_db_closeversion(stub->db, &stub->version, false); 13833 } 13834 if (stub->db != NULL) { 13835 dns_db_detach(&stub->db); 13836 } 13837 if (msg != NULL) { 13838 dns_message_detach(&msg); 13839 } 13840 isc_event_free(&event); 13841 dns_request_destroy(&zone->request); 13842 /* 13843 * Skip to next failed / untried primary. 13844 */ 13845 do { 13846 zone->curprimary++; 13847 } while (zone->curprimary < zone->primariescnt && 13848 zone->primariesok[zone->curprimary]); 13849 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 13850 if (exiting || zone->curprimary >= zone->primariescnt) { 13851 bool done = true; 13852 if (!exiting && 13853 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 13854 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) 13855 { 13856 /* 13857 * Did we get a good answer from all the primaries? 13858 */ 13859 for (j = 0; j < zone->primariescnt; j++) { 13860 if (!zone->primariesok[j]) { 13861 { 13862 done = false; 13863 break; 13864 } 13865 } 13866 } 13867 } else { 13868 done = true; 13869 } 13870 if (!done) { 13871 zone->curprimary = 0; 13872 /* 13873 * Find the next failed primary. 13874 */ 13875 while (zone->curprimary < zone->primariescnt && 13876 zone->primariesok[zone->curprimary]) 13877 { 13878 zone->curprimary++; 13879 } 13880 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 13881 } else { 13882 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 13883 13884 zone_settimer(zone, &now); 13885 goto free_stub; 13886 } 13887 } 13888 queue_soa_query(zone); 13889 goto free_stub; 13890 13891same_primary: 13892 isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args)); 13893 if (msg != NULL) { 13894 dns_message_detach(&msg); 13895 } 13896 isc_event_free(&event); 13897 dns_request_destroy(&zone->request); 13898 ns_query(zone, NULL, stub); 13899 UNLOCK_ZONE(zone); 13900 goto done; 13901 13902free_stub: 13903 UNLOCK_ZONE(zone); 13904 stub->magic = 0; 13905 dns_zone_idetach(&stub->zone); 13906 INSIST(stub->db == NULL); 13907 INSIST(stub->version == NULL); 13908 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 13909 13910done: 13911 INSIST(event == NULL); 13912 return; 13913} 13914 13915/* 13916 * Get the EDNS EXPIRE option from the response and if it exists trim 13917 * expire to be not more than it. 13918 */ 13919static void 13920get_edns_expire(dns_zone_t *zone, dns_message_t *message, uint32_t *expirep) { 13921 isc_result_t result; 13922 uint32_t expire; 13923 dns_rdata_t rdata = DNS_RDATA_INIT; 13924 isc_buffer_t optbuf; 13925 uint16_t optcode; 13926 uint16_t optlen; 13927 13928 REQUIRE(expirep != NULL); 13929 REQUIRE(message != NULL); 13930 13931 if (message->opt == NULL) { 13932 return; 13933 } 13934 13935 result = dns_rdataset_first(message->opt); 13936 if (result == ISC_R_SUCCESS) { 13937 dns_rdataset_current(message->opt, &rdata); 13938 isc_buffer_init(&optbuf, rdata.data, rdata.length); 13939 isc_buffer_add(&optbuf, rdata.length); 13940 while (isc_buffer_remaininglength(&optbuf) >= 4) { 13941 optcode = isc_buffer_getuint16(&optbuf); 13942 optlen = isc_buffer_getuint16(&optbuf); 13943 /* 13944 * A EDNS EXPIRE response has a length of 4. 13945 */ 13946 if (optcode != DNS_OPT_EXPIRE || optlen != 4) { 13947 isc_buffer_forward(&optbuf, optlen); 13948 continue; 13949 } 13950 expire = isc_buffer_getuint32(&optbuf); 13951 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13952 "got EDNS EXPIRE of %u", expire); 13953 /* 13954 * Trim *expirep? 13955 */ 13956 if (expire < *expirep) { 13957 *expirep = expire; 13958 } 13959 break; 13960 } 13961 } 13962} 13963 13964/* 13965 * Set the file modification time zone->expire seconds before expiretime. 13966 */ 13967static void 13968setmodtime(dns_zone_t *zone, isc_time_t *expiretime) { 13969 isc_result_t result; 13970 isc_time_t when; 13971 isc_interval_t i; 13972 13973 isc_interval_set(&i, zone->expire, 0); 13974 result = isc_time_subtract(expiretime, &i, &when); 13975 if (result != ISC_R_SUCCESS) { 13976 return; 13977 } 13978 13979 result = ISC_R_FAILURE; 13980 if (zone->journal != NULL) { 13981 result = isc_file_settime(zone->journal, &when); 13982 } 13983 if (result == ISC_R_SUCCESS && 13984 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 13985 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 13986 { 13987 result = isc_file_settime(zone->masterfile, &when); 13988 } else if (result != ISC_R_SUCCESS) { 13989 result = isc_file_settime(zone->masterfile, &when); 13990 } 13991 13992 /* 13993 * Someone removed the file from underneath us! 13994 */ 13995 if (result == ISC_R_FILENOTFOUND) { 13996 zone_needdump(zone, DNS_DUMP_DELAY); 13997 } else if (result != ISC_R_SUCCESS) { 13998 dns_zone_log(zone, ISC_LOG_ERROR, 13999 "refresh: could not set " 14000 "file modification time of '%s': %s", 14001 zone->masterfile, isc_result_totext(result)); 14002 } 14003} 14004 14005/* 14006 * An SOA query has finished (successfully or not). 14007 */ 14008static void 14009refresh_callback(isc_task_t *task, isc_event_t *event) { 14010 const char me[] = "refresh_callback"; 14011 dns_requestevent_t *revent = (dns_requestevent_t *)event; 14012 dns_zone_t *zone; 14013 dns_message_t *msg = NULL; 14014 uint32_t soacnt, cnamecnt, soacount, nscount; 14015 isc_time_t now; 14016 char primary[ISC_SOCKADDR_FORMATSIZE]; 14017 char source[ISC_SOCKADDR_FORMATSIZE]; 14018 dns_rdataset_t *rdataset = NULL; 14019 dns_rdata_t rdata = DNS_RDATA_INIT; 14020 dns_rdata_soa_t soa; 14021 isc_result_t result; 14022 uint32_t serial, oldserial = 0; 14023 unsigned int j; 14024 bool do_queue_xfrin = false; 14025 14026 zone = revent->ev_arg; 14027 INSIST(DNS_ZONE_VALID(zone)); 14028 14029 UNUSED(task); 14030 14031 ENTER; 14032 14033 TIME_NOW(&now); 14034 14035 LOCK_ZONE(zone); 14036 14037 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 14038 goto exiting; 14039 } 14040 14041 /* 14042 * If timeout, log and try the next primary 14043 */ 14044 isc_sockaddr_format(&zone->primaryaddr, primary, sizeof(primary)); 14045 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 14046 14047 switch (revent->result) { 14048 case ISC_R_SUCCESS: 14049 break; 14050 case ISC_R_SHUTTINGDOWN: 14051 goto exiting; 14052 case ISC_R_TIMEDOUT: 14053 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 14054 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14055 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14056 "refresh: timeout retrying without EDNS " 14057 "primary %s (source %s)", 14058 primary, source); 14059 goto same_primary; 14060 } else if (!dns_request_usedtcp(revent->request)) { 14061 dns_zone_log(zone, ISC_LOG_INFO, 14062 "refresh: retry limit for " 14063 "primary %s exceeded (source %s)", 14064 primary, source); 14065 /* Try with secondary with TCP. */ 14066 if ((zone->type == dns_zone_secondary || 14067 zone->type == dns_zone_mirror || 14068 zone->type == dns_zone_redirect) && 14069 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) 14070 { 14071 if (!dns_zonemgr_unreachable( 14072 zone->zmgr, &zone->primaryaddr, 14073 &zone->sourceaddr, &now)) 14074 { 14075 DNS_ZONE_SETFLAG( 14076 zone, 14077 DNS_ZONEFLG_SOABEFOREAXFR); 14078 goto tcp_transfer; 14079 } 14080 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14081 "refresh: skipped tcp fallback " 14082 "as primary %s (source %s) is " 14083 "unreachable (cached)", 14084 primary, source); 14085 } 14086 goto next_primary; 14087 } 14088 FALLTHROUGH; 14089 default: 14090 dns_zone_log(zone, ISC_LOG_INFO, 14091 "refresh: failure trying primary " 14092 "%s (source %s): %s", 14093 primary, source, 14094 isc_result_totext(revent->result)); 14095 goto next_primary; 14096 } 14097 14098 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 14099 result = dns_request_getresponse(revent->request, msg, 0); 14100 if (result != ISC_R_SUCCESS) { 14101 dns_zone_log(zone, ISC_LOG_INFO, 14102 "refresh: failure trying primary " 14103 "%s (source %s): %s", 14104 primary, source, isc_result_totext(result)); 14105 goto next_primary; 14106 } 14107 14108 /* 14109 * Unexpected opcode. 14110 */ 14111 if (msg->opcode != dns_opcode_query) { 14112 char opcode[128]; 14113 isc_buffer_t rb; 14114 14115 isc_buffer_init(&rb, opcode, sizeof(opcode)); 14116 (void)dns_opcode_totext(msg->opcode, &rb); 14117 14118 dns_zone_log(zone, ISC_LOG_INFO, 14119 "refresh: " 14120 "unexpected opcode (%.*s) from %s (source %s)", 14121 (int)rb.used, opcode, primary, source); 14122 goto next_primary; 14123 } 14124 14125 /* 14126 * Unexpected rcode. 14127 */ 14128 if (msg->rcode != dns_rcode_noerror) { 14129 char rcode[128]; 14130 isc_buffer_t rb; 14131 14132 isc_buffer_init(&rb, rcode, sizeof(rcode)); 14133 (void)dns_rcode_totext(msg->rcode, &rb); 14134 14135 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 14136 (msg->rcode == dns_rcode_servfail || 14137 msg->rcode == dns_rcode_notimp || 14138 (msg->rcode == dns_rcode_formerr && msg->opt == NULL))) 14139 { 14140 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14141 "refresh: rcode (%.*s) retrying without " 14142 "EDNS primary %s (source %s)", 14143 (int)rb.used, rcode, primary, source); 14144 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14145 goto same_primary; 14146 } 14147 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 14148 msg->rcode == dns_rcode_badvers) 14149 { 14150 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14151 "refresh: rcode (%.*s) retrying without " 14152 "EDNS EXPIRE OPTION primary %s " 14153 "(source %s)", 14154 (int)rb.used, rcode, primary, source); 14155 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14156 goto same_primary; 14157 } 14158 dns_zone_log(zone, ISC_LOG_INFO, 14159 "refresh: unexpected rcode (%.*s) from " 14160 "primary %s (source %s)", 14161 (int)rb.used, rcode, primary, source); 14162 /* 14163 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't. 14164 */ 14165 if (msg->rcode == dns_rcode_refused && 14166 (zone->type == dns_zone_secondary || 14167 zone->type == dns_zone_mirror || 14168 zone->type == dns_zone_redirect)) 14169 { 14170 goto tcp_transfer; 14171 } 14172 goto next_primary; 14173 } 14174 14175 /* 14176 * If truncated punt to zone transfer which will query again. 14177 */ 14178 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 14179 if (zone->type == dns_zone_secondary || 14180 zone->type == dns_zone_mirror || 14181 zone->type == dns_zone_redirect) 14182 { 14183 dns_zone_log(zone, ISC_LOG_INFO, 14184 "refresh: truncated UDP answer, " 14185 "initiating TCP zone xfer " 14186 "for primary %s (source %s)", 14187 primary, source); 14188 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 14189 goto tcp_transfer; 14190 } else { 14191 INSIST(zone->type == dns_zone_stub); 14192 if (dns_request_usedtcp(revent->request)) { 14193 dns_zone_log(zone, ISC_LOG_INFO, 14194 "refresh: truncated TCP response " 14195 "from primary %s (source %s)", 14196 primary, source); 14197 goto next_primary; 14198 } 14199 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 14200 goto same_primary; 14201 } 14202 } 14203 14204 /* 14205 * If non-auth, log and try the next primary 14206 */ 14207 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 14208 dns_zone_log(zone, ISC_LOG_INFO, 14209 "refresh: non-authoritative answer from " 14210 "primary %s (source %s)", 14211 primary, source); 14212 goto next_primary; 14213 } 14214 14215 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 14216 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa); 14217 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns); 14218 soacount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_soa); 14219 14220 /* 14221 * There should not be a CNAME record at top of zone. 14222 */ 14223 if (cnamecnt != 0) { 14224 dns_zone_log(zone, ISC_LOG_INFO, 14225 "refresh: CNAME at top of zone " 14226 "in primary %s (source %s)", 14227 primary, source); 14228 goto next_primary; 14229 } 14230 14231 /* 14232 * If referral, log and try the next primary; 14233 */ 14234 if (soacnt == 0 && soacount == 0 && nscount != 0) { 14235 dns_zone_log(zone, ISC_LOG_INFO, 14236 "refresh: referral response " 14237 "from primary %s (source %s)", 14238 primary, source); 14239 goto next_primary; 14240 } 14241 14242 /* 14243 * If nodata, log and try the next primary; 14244 */ 14245 if (soacnt == 0 && (nscount == 0 || soacount != 0)) { 14246 dns_zone_log(zone, ISC_LOG_INFO, 14247 "refresh: NODATA response " 14248 "from primary %s (source %s)", 14249 primary, source); 14250 goto next_primary; 14251 } 14252 14253 /* 14254 * Only one soa at top of zone. 14255 */ 14256 if (soacnt != 1) { 14257 dns_zone_log(zone, ISC_LOG_INFO, 14258 "refresh: answer SOA count (%d) != 1 " 14259 "from primary %s (source %s)", 14260 soacnt, primary, source); 14261 goto next_primary; 14262 } 14263 14264 /* 14265 * Extract serial 14266 */ 14267 rdataset = NULL; 14268 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin, 14269 dns_rdatatype_soa, dns_rdatatype_none, 14270 NULL, &rdataset); 14271 if (result != ISC_R_SUCCESS) { 14272 dns_zone_log(zone, ISC_LOG_INFO, 14273 "refresh: unable to get SOA record " 14274 "from primary %s (source %s)", 14275 primary, source); 14276 goto next_primary; 14277 } 14278 14279 result = dns_rdataset_first(rdataset); 14280 if (result != ISC_R_SUCCESS) { 14281 dns_zone_log(zone, ISC_LOG_INFO, 14282 "refresh: dns_rdataset_first() failed"); 14283 goto next_primary; 14284 } 14285 14286 dns_rdataset_current(rdataset, &rdata); 14287 result = dns_rdata_tostruct(&rdata, &soa, NULL); 14288 RUNTIME_CHECK(result == ISC_R_SUCCESS); 14289 14290 serial = soa.serial; 14291 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 14292 unsigned int dbsoacount; 14293 result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount, 14294 NULL, &oldserial, NULL, NULL, NULL, 14295 NULL, NULL); 14296 RUNTIME_CHECK(result == ISC_R_SUCCESS); 14297 RUNTIME_CHECK(dbsoacount > 0U); 14298 zone_debuglog(zone, me, 1, "serial: new %u, old %u", serial, 14299 oldserial); 14300 } else { 14301 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded", 14302 serial); 14303 } 14304 14305 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) || 14306 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) || 14307 isc_serial_gt(serial, oldserial)) 14308 { 14309 if (dns_zonemgr_unreachable(zone->zmgr, &zone->primaryaddr, 14310 &zone->sourceaddr, &now)) 14311 { 14312 dns_zone_log(zone, ISC_LOG_INFO, 14313 "refresh: skipping %s as primary %s " 14314 "(source %s) is unreachable (cached)", 14315 (zone->type == dns_zone_secondary || 14316 zone->type == dns_zone_mirror || 14317 zone->type == dns_zone_redirect) 14318 ? "zone transfer" 14319 : "NS query", 14320 primary, source); 14321 goto next_primary; 14322 } 14323 tcp_transfer: 14324 isc_event_free(&event); 14325 dns_request_destroy(&zone->request); 14326 if (zone->type == dns_zone_secondary || 14327 zone->type == dns_zone_mirror || 14328 zone->type == dns_zone_redirect) 14329 { 14330 do_queue_xfrin = true; 14331 } else { 14332 INSIST(zone->type == dns_zone_stub); 14333 ns_query(zone, rdataset, NULL); 14334 } 14335 if (msg != NULL) { 14336 dns_message_detach(&msg); 14337 } 14338 } else if (isc_serial_eq(soa.serial, oldserial)) { 14339 isc_time_t expiretime; 14340 uint32_t expire; 14341 14342 /* 14343 * Compute the new expire time based on this response. 14344 */ 14345 expire = zone->expire; 14346 get_edns_expire(zone, msg, &expire); 14347 DNS_ZONE_TIME_ADD(&now, expire, &expiretime); 14348 14349 /* 14350 * Has the expire time improved? 14351 */ 14352 if (isc_time_compare(&expiretime, &zone->expiretime) > 0) { 14353 zone->expiretime = expiretime; 14354 if (zone->masterfile != NULL) { 14355 setmodtime(zone, &expiretime); 14356 } 14357 } 14358 14359 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 14360 zone->primariesok[zone->curprimary] = true; 14361 goto next_primary; 14362 } else { 14363 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER)) { 14364 dns_zone_log(zone, ISC_LOG_INFO, 14365 "serial number (%u) " 14366 "received from primary %s < ours (%u)", 14367 soa.serial, primary, oldserial); 14368 } else { 14369 zone_debuglog(zone, me, 1, "ahead"); 14370 } 14371 zone->primariesok[zone->curprimary] = true; 14372 goto next_primary; 14373 } 14374 if (msg != NULL) { 14375 dns_message_detach(&msg); 14376 } 14377 goto detach; 14378 14379next_primary: 14380 if (msg != NULL) { 14381 dns_message_detach(&msg); 14382 } 14383 isc_event_free(&event); 14384 dns_request_destroy(&zone->request); 14385 /* 14386 * Skip to next failed / untried primary. 14387 */ 14388 do { 14389 zone->curprimary++; 14390 } while (zone->curprimary < zone->primariescnt && 14391 zone->primariesok[zone->curprimary]); 14392 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 14393 if (zone->curprimary >= zone->primariescnt) { 14394 bool done = true; 14395 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 14396 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) 14397 { 14398 /* 14399 * Did we get a good answer from all the primaries? 14400 */ 14401 for (j = 0; j < zone->primariescnt; j++) { 14402 if (!zone->primariesok[j]) { 14403 { 14404 done = false; 14405 break; 14406 } 14407 } 14408 } 14409 } else { 14410 done = true; 14411 } 14412 if (!done) { 14413 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 14414 zone->curprimary = 0; 14415 /* 14416 * Find the next failed primary. 14417 */ 14418 while (zone->curprimary < zone->primariescnt && 14419 zone->primariesok[zone->curprimary]) 14420 { 14421 zone->curprimary++; 14422 } 14423 goto requeue; 14424 } 14425 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 14426 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 14427 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 14428 zone->refreshtime = now; 14429 } 14430 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 14431 zone_settimer(zone, &now); 14432 goto detach; 14433 } 14434 14435requeue: 14436 queue_soa_query(zone); 14437 goto detach; 14438 14439exiting: 14440 isc_event_free(&event); 14441 dns_request_destroy(&zone->request); 14442 goto detach; 14443 14444same_primary: 14445 if (msg != NULL) { 14446 dns_message_detach(&msg); 14447 } 14448 isc_event_free(&event); 14449 dns_request_destroy(&zone->request); 14450 queue_soa_query(zone); 14451 14452detach: 14453 UNLOCK_ZONE(zone); 14454 if (do_queue_xfrin) { 14455 queue_xfrin(zone); 14456 } 14457 dns_zone_idetach(&zone); 14458 return; 14459} 14460 14461static void 14462queue_soa_query(dns_zone_t *zone) { 14463 const char me[] = "queue_soa_query"; 14464 isc_event_t *e; 14465 dns_zone_t *dummy = NULL; 14466 isc_result_t result; 14467 14468 ENTER; 14469 /* 14470 * Locked by caller 14471 */ 14472 REQUIRE(LOCKED_ZONE(zone)); 14473 14474 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 14475 cancel_refresh(zone); 14476 return; 14477 } 14478 14479 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE, soa_query, 14480 zone, sizeof(isc_event_t)); 14481 14482 /* 14483 * Attach so that we won't clean up 14484 * until the event is delivered. 14485 */ 14486 zone_iattach(zone, &dummy); 14487 14488 e->ev_arg = zone; 14489 e->ev_sender = NULL; 14490 result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e); 14491 if (result != ISC_R_SUCCESS) { 14492 zone_idetach(&dummy); 14493 isc_event_free(&e); 14494 cancel_refresh(zone); 14495 } 14496} 14497 14498static void 14499soa_query(isc_task_t *task, isc_event_t *event) { 14500 const char me[] = "soa_query"; 14501 isc_result_t result = ISC_R_FAILURE; 14502 dns_message_t *message = NULL; 14503 dns_zone_t *zone = event->ev_arg; 14504 dns_zone_t *dummy = NULL; 14505 isc_netaddr_t primaryip; 14506 dns_tsigkey_t *key = NULL; 14507 dns_transport_t *transport = NULL; 14508 uint32_t options; 14509 bool cancel = true; 14510 int timeout; 14511 bool have_xfrsource = false, reqnsid, reqexpire; 14512 uint16_t udpsize = SEND_BUFFER_SIZE; 14513 bool do_queue_xfrin = false; 14514 14515 REQUIRE(DNS_ZONE_VALID(zone)); 14516 14517 UNUSED(task); 14518 14519 ENTER; 14520 14521 LOCK_ZONE(zone); 14522 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) || 14523 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || 14524 zone->view->requestmgr == NULL) 14525 { 14526 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 14527 cancel = false; 14528 } 14529 goto cleanup; 14530 } 14531 14532again: 14533 INSIST(zone->primariescnt > 0); 14534 INSIST(zone->curprimary < zone->primariescnt); 14535 14536 zone->primaryaddr = zone->primaries[zone->curprimary]; 14537 14538 isc_netaddr_fromsockaddr(&primaryip, &zone->primaryaddr); 14539 /* 14540 * First, look for a tsig key in the primaries statement, then 14541 * try for a server key. 14542 */ 14543 if ((zone->primarykeynames != NULL) && 14544 (zone->primarykeynames[zone->curprimary] != NULL)) 14545 { 14546 dns_view_t *view = dns_zone_getview(zone); 14547 dns_name_t *keyname = zone->primarykeynames[zone->curprimary]; 14548 result = dns_view_gettsig(view, keyname, &key); 14549 if (result != ISC_R_SUCCESS) { 14550 char namebuf[DNS_NAME_FORMATSIZE]; 14551 dns_name_format(keyname, namebuf, sizeof(namebuf)); 14552 dns_zone_log(zone, ISC_LOG_ERROR, 14553 "unable to find key: %s", namebuf); 14554 goto skip_primary; 14555 } 14556 } 14557 if (key == NULL) { 14558 result = dns_view_getpeertsig(zone->view, &primaryip, &key); 14559 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 14560 char addrbuf[ISC_NETADDR_FORMATSIZE]; 14561 isc_netaddr_format(&primaryip, addrbuf, 14562 sizeof(addrbuf)); 14563 dns_zone_log(zone, ISC_LOG_ERROR, 14564 "unable to find TSIG key for %s", addrbuf); 14565 goto skip_primary; 14566 } 14567 } 14568 14569 if ((zone->primarytlsnames != NULL) && 14570 (zone->primarytlsnames[zone->curprimary] != NULL)) 14571 { 14572 dns_view_t *view = dns_zone_getview(zone); 14573 dns_name_t *tlsname = zone->primarytlsnames[zone->curprimary]; 14574 result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname, 14575 &transport); 14576 if (result != ISC_R_SUCCESS) { 14577 char namebuf[DNS_NAME_FORMATSIZE]; 14578 dns_name_format(tlsname, namebuf, sizeof(namebuf)); 14579 dns_zone_log(zone, ISC_LOG_ERROR, 14580 "unable to find TLS configuration: %s", 14581 namebuf); 14582 goto skip_primary; 14583 } 14584 } 14585 14586 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? DNS_REQUESTOPT_TCP 14587 : 0; 14588 reqnsid = zone->view->requestnsid; 14589 reqexpire = zone->requestexpire; 14590 if (zone->view->peers != NULL) { 14591 dns_peer_t *peer = NULL; 14592 bool edns, usetcp; 14593 result = dns_peerlist_peerbyaddr(zone->view->peers, &primaryip, 14594 &peer); 14595 if (result == ISC_R_SUCCESS) { 14596 result = dns_peer_getsupportedns(peer, &edns); 14597 if (result == ISC_R_SUCCESS && !edns) { 14598 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14599 } 14600 result = dns_peer_gettransfersource(peer, 14601 &zone->sourceaddr); 14602 if (result == ISC_R_SUCCESS) { 14603 have_xfrsource = true; 14604 } 14605 if (zone->view->resolver != NULL) { 14606 udpsize = dns_resolver_getudpsize( 14607 zone->view->resolver); 14608 } 14609 (void)dns_peer_getudpsize(peer, &udpsize); 14610 (void)dns_peer_getrequestnsid(peer, &reqnsid); 14611 (void)dns_peer_getrequestexpire(peer, &reqexpire); 14612 result = dns_peer_getforcetcp(peer, &usetcp); 14613 if (result == ISC_R_SUCCESS && usetcp) { 14614 options |= DNS_REQUESTOPT_TCP; 14615 } 14616 } 14617 } 14618 14619 switch (isc_sockaddr_pf(&zone->primaryaddr)) { 14620 case PF_INET: 14621 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 14622 if (isc_sockaddr_equal(&zone->altxfrsource4, 14623 &zone->xfrsource4)) 14624 { 14625 goto skip_primary; 14626 } 14627 zone->sourceaddr = zone->altxfrsource4; 14628 } else if (!have_xfrsource) { 14629 zone->sourceaddr = zone->xfrsource4; 14630 } 14631 break; 14632 case PF_INET6: 14633 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 14634 if (isc_sockaddr_equal(&zone->altxfrsource6, 14635 &zone->xfrsource6)) 14636 { 14637 goto skip_primary; 14638 } 14639 zone->sourceaddr = zone->altxfrsource6; 14640 } else if (!have_xfrsource) { 14641 zone->sourceaddr = zone->xfrsource6; 14642 } 14643 break; 14644 default: 14645 result = ISC_R_NOTIMPLEMENTED; 14646 goto cleanup; 14647 } 14648 14649 /* 14650 * FIXME(OS): This is a bit hackish, but it enforces the SOA query to go 14651 * through the XFR channel instead of doing dns_request that doesn't 14652 * have DoT support yet. 14653 */ 14654 if (transport != NULL) { 14655 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 14656 do_queue_xfrin = true; 14657 cancel = false; 14658 result = ISC_R_SUCCESS; 14659 goto cleanup; 14660 } 14661 14662 result = create_query(zone, dns_rdatatype_soa, &zone->origin, &message); 14663 if (result != ISC_R_SUCCESS) { 14664 goto cleanup; 14665 } 14666 14667 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 14668 result = add_opt(message, udpsize, reqnsid, reqexpire); 14669 if (result != ISC_R_SUCCESS) { 14670 zone_debuglog(zone, me, 1, 14671 "unable to add opt record: %s", 14672 isc_result_totext(result)); 14673 } 14674 } 14675 14676 zone_iattach(zone, &dummy); 14677 timeout = 5; 14678 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) { 14679 timeout = 30; 14680 } 14681 result = dns_request_create( 14682 zone->view->requestmgr, message, &zone->sourceaddr, 14683 &zone->primaryaddr, options, key, timeout * 3 + 1, timeout, 2, 14684 zone->task, refresh_callback, zone, &zone->request); 14685 if (result != ISC_R_SUCCESS) { 14686 zone_idetach(&dummy); 14687 zone_debuglog(zone, me, 1, "dns_request_create() failed: %s", 14688 isc_result_totext(result)); 14689 goto skip_primary; 14690 } else { 14691 if (isc_sockaddr_pf(&zone->primaryaddr) == PF_INET) { 14692 inc_stats(zone, dns_zonestatscounter_soaoutv4); 14693 } else { 14694 inc_stats(zone, dns_zonestatscounter_soaoutv6); 14695 } 14696 } 14697 cancel = false; 14698cleanup: 14699 if (transport != NULL) { 14700 dns_transport_detach(&transport); 14701 } 14702 if (key != NULL) { 14703 dns_tsigkey_detach(&key); 14704 } 14705 if (result != ISC_R_SUCCESS) { 14706 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 14707 } 14708 if (message != NULL) { 14709 dns_message_detach(&message); 14710 } 14711 if (cancel) { 14712 cancel_refresh(zone); 14713 } 14714 isc_event_free(&event); 14715 UNLOCK_ZONE(zone); 14716 if (do_queue_xfrin) { 14717 queue_xfrin(zone); 14718 } 14719 dns_zone_idetach(&zone); 14720 return; 14721 14722skip_primary: 14723 if (transport != NULL) { 14724 dns_transport_detach(&transport); 14725 } 14726 if (key != NULL) { 14727 dns_tsigkey_detach(&key); 14728 } 14729 if (message != NULL) { 14730 dns_message_detach(&message); 14731 } 14732 /* 14733 * Skip to next failed / untried primary. 14734 */ 14735 do { 14736 zone->curprimary++; 14737 } while (zone->curprimary < zone->primariescnt && 14738 zone->primariesok[zone->curprimary]); 14739 if (zone->curprimary < zone->primariescnt) { 14740 goto again; 14741 } 14742 zone->curprimary = 0; 14743 goto cleanup; 14744} 14745 14746static void 14747ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { 14748 const char me[] = "ns_query"; 14749 isc_result_t result; 14750 dns_message_t *message = NULL; 14751 isc_netaddr_t primaryip; 14752 dns_tsigkey_t *key = NULL; 14753 dns_dbnode_t *node = NULL; 14754 int timeout; 14755 bool have_xfrsource = false; 14756 bool reqnsid; 14757 uint16_t udpsize = SEND_BUFFER_SIZE; 14758 struct stub_cb_args *cb_args; 14759 14760 REQUIRE(DNS_ZONE_VALID(zone)); 14761 REQUIRE(LOCKED_ZONE(zone)); 14762 REQUIRE((soardataset != NULL && stub == NULL) || 14763 (soardataset == NULL && stub != NULL)); 14764 REQUIRE(stub == NULL || DNS_STUB_VALID(stub)); 14765 14766 ENTER; 14767 14768 if (stub == NULL) { 14769 stub = isc_mem_get(zone->mctx, sizeof(*stub)); 14770 stub->magic = STUB_MAGIC; 14771 stub->mctx = zone->mctx; 14772 stub->zone = NULL; 14773 stub->db = NULL; 14774 stub->version = NULL; 14775 atomic_init(&stub->pending_requests, 0); 14776 14777 /* 14778 * Attach so that the zone won't disappear from under us. 14779 */ 14780 zone_iattach(zone, &stub->zone); 14781 14782 /* 14783 * If a db exists we will update it, otherwise we create a 14784 * new one and attach it to the zone once we have the NS 14785 * RRset and glue. 14786 */ 14787 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 14788 if (zone->db != NULL) { 14789 dns_db_attach(zone->db, &stub->db); 14790 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 14791 } else { 14792 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 14793 14794 INSIST(zone->db_argc >= 1); 14795 result = dns_db_create(zone->mctx, zone->db_argv[0], 14796 &zone->origin, dns_dbtype_stub, 14797 zone->rdclass, zone->db_argc - 1, 14798 zone->db_argv + 1, &stub->db); 14799 if (result != ISC_R_SUCCESS) { 14800 dns_zone_log(zone, ISC_LOG_ERROR, 14801 "refreshing stub: " 14802 "could not create " 14803 "database: %s", 14804 isc_result_totext(result)); 14805 goto cleanup; 14806 } 14807 dns_db_settask(stub->db, zone->task); 14808 } 14809 14810 result = dns_db_newversion(stub->db, &stub->version); 14811 if (result != ISC_R_SUCCESS) { 14812 dns_zone_log(zone, ISC_LOG_INFO, 14813 "refreshing stub: " 14814 "dns_db_newversion() failed: %s", 14815 isc_result_totext(result)); 14816 goto cleanup; 14817 } 14818 14819 /* 14820 * Update SOA record. 14821 */ 14822 result = dns_db_findnode(stub->db, &zone->origin, true, &node); 14823 if (result != ISC_R_SUCCESS) { 14824 dns_zone_log(zone, ISC_LOG_INFO, 14825 "refreshing stub: " 14826 "dns_db_findnode() failed: %s", 14827 isc_result_totext(result)); 14828 goto cleanup; 14829 } 14830 14831 result = dns_db_addrdataset(stub->db, node, stub->version, 0, 14832 soardataset, 0, NULL); 14833 dns_db_detachnode(stub->db, &node); 14834 if (result != ISC_R_SUCCESS) { 14835 dns_zone_log(zone, ISC_LOG_INFO, 14836 "refreshing stub: " 14837 "dns_db_addrdataset() failed: %s", 14838 isc_result_totext(result)); 14839 goto cleanup; 14840 } 14841 } 14842 14843 /* 14844 * XXX Optimisation: Create message when zone is setup and reuse. 14845 */ 14846 result = create_query(zone, dns_rdatatype_ns, &zone->origin, &message); 14847 INSIST(result == ISC_R_SUCCESS); 14848 14849 INSIST(zone->primariescnt > 0); 14850 INSIST(zone->curprimary < zone->primariescnt); 14851 zone->primaryaddr = zone->primaries[zone->curprimary]; 14852 14853 isc_netaddr_fromsockaddr(&primaryip, &zone->primaryaddr); 14854 /* 14855 * First, look for a tsig key in the primaries statement, then 14856 * try for a server key. 14857 */ 14858 if ((zone->primarykeynames != NULL) && 14859 (zone->primarykeynames[zone->curprimary] != NULL)) 14860 { 14861 dns_view_t *view = dns_zone_getview(zone); 14862 dns_name_t *keyname = zone->primarykeynames[zone->curprimary]; 14863 result = dns_view_gettsig(view, keyname, &key); 14864 if (result != ISC_R_SUCCESS) { 14865 char namebuf[DNS_NAME_FORMATSIZE]; 14866 dns_name_format(keyname, namebuf, sizeof(namebuf)); 14867 dns_zone_log(zone, ISC_LOG_ERROR, 14868 "unable to find key: %s", namebuf); 14869 } 14870 } 14871 if (key == NULL) { 14872 (void)dns_view_getpeertsig(zone->view, &primaryip, &key); 14873 } 14874 14875 /* FIXME(OS): Do we need the transport here too? Most probably yes */ 14876 14877 reqnsid = zone->view->requestnsid; 14878 if (zone->view->peers != NULL) { 14879 dns_peer_t *peer = NULL; 14880 bool edns; 14881 result = dns_peerlist_peerbyaddr(zone->view->peers, &primaryip, 14882 &peer); 14883 if (result == ISC_R_SUCCESS) { 14884 result = dns_peer_getsupportedns(peer, &edns); 14885 if (result == ISC_R_SUCCESS && !edns) { 14886 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 14887 } 14888 result = dns_peer_gettransfersource(peer, 14889 &zone->sourceaddr); 14890 if (result == ISC_R_SUCCESS) { 14891 have_xfrsource = true; 14892 } 14893 if (zone->view->resolver != NULL) { 14894 udpsize = dns_resolver_getudpsize( 14895 zone->view->resolver); 14896 } 14897 (void)dns_peer_getudpsize(peer, &udpsize); 14898 (void)dns_peer_getrequestnsid(peer, &reqnsid); 14899 } 14900 } 14901 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 14902 result = add_opt(message, udpsize, reqnsid, false); 14903 if (result != ISC_R_SUCCESS) { 14904 zone_debuglog(zone, me, 1, 14905 "unable to add opt record: %s", 14906 isc_result_totext(result)); 14907 } 14908 } 14909 14910 /* 14911 * Always use TCP so that we shouldn't truncate in additional section. 14912 */ 14913 switch (isc_sockaddr_pf(&zone->primaryaddr)) { 14914 case PF_INET: 14915 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 14916 zone->sourceaddr = zone->altxfrsource4; 14917 } else if (!have_xfrsource) { 14918 zone->sourceaddr = zone->xfrsource4; 14919 } 14920 break; 14921 case PF_INET6: 14922 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 14923 zone->sourceaddr = zone->altxfrsource6; 14924 } else if (!have_xfrsource) { 14925 zone->sourceaddr = zone->xfrsource6; 14926 } 14927 break; 14928 default: 14929 result = ISC_R_NOTIMPLEMENTED; 14930 POST(result); 14931 goto cleanup; 14932 } 14933 timeout = 5; 14934 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) { 14935 timeout = 30; 14936 } 14937 14938 /* 14939 * Save request parameters so we can reuse them later on 14940 * for resolving missing glue A/AAAA records. 14941 */ 14942 cb_args = isc_mem_get(zone->mctx, sizeof(*cb_args)); 14943 cb_args->stub = stub; 14944 cb_args->tsig_key = key; 14945 cb_args->udpsize = udpsize; 14946 cb_args->timeout = timeout; 14947 cb_args->reqnsid = reqnsid; 14948 14949 result = dns_request_create( 14950 zone->view->requestmgr, message, &zone->sourceaddr, 14951 &zone->primaryaddr, DNS_REQUESTOPT_TCP, key, timeout * 3 + 1, 14952 timeout, 2, zone->task, stub_callback, cb_args, &zone->request); 14953 if (result != ISC_R_SUCCESS) { 14954 zone_debuglog(zone, me, 1, "dns_request_create() failed: %s", 14955 isc_result_totext(result)); 14956 goto cleanup; 14957 } 14958 dns_message_detach(&message); 14959 goto unlock; 14960 14961cleanup: 14962 cancel_refresh(zone); 14963 stub->magic = 0; 14964 if (stub->version != NULL) { 14965 dns_db_closeversion(stub->db, &stub->version, false); 14966 } 14967 if (stub->db != NULL) { 14968 dns_db_detach(&stub->db); 14969 } 14970 if (stub->zone != NULL) { 14971 zone_idetach(&stub->zone); 14972 } 14973 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 14974 if (message != NULL) { 14975 dns_message_detach(&message); 14976 } 14977unlock: 14978 if (key != NULL) { 14979 dns_tsigkey_detach(&key); 14980 } 14981 return; 14982} 14983 14984/* 14985 * Shut the zone down. 14986 */ 14987static void 14988zone_shutdown(isc_task_t *task, isc_event_t *event) { 14989 dns_zone_t *zone = (dns_zone_t *)event->ev_arg; 14990 bool free_needed, linked = false; 14991 dns_zone_t *raw = NULL, *secure = NULL; 14992 dns_view_t *view = NULL, *prev_view = NULL; 14993 14994 UNUSED(task); 14995 REQUIRE(DNS_ZONE_VALID(zone)); 14996 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL); 14997 INSIST(isc_refcount_current(&zone->erefs) == 0); 14998 14999 zone_debuglog(zone, "zone_shutdown", 3, "shutting down"); 15000 15001 /* 15002 * If we were waiting for xfrin quota, step out of 15003 * the queue. 15004 * If there's no zone manager, we can't be waiting for the 15005 * xfrin quota 15006 */ 15007 if (zone->zmgr != NULL) { 15008 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 15009 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) { 15010 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone, 15011 statelink); 15012 linked = true; 15013 zone->statelist = NULL; 15014 } 15015 if (zone->statelist == &zone->zmgr->xfrin_in_progress) { 15016 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, 15017 statelink); 15018 zone->statelist = NULL; 15019 zmgr_resume_xfrs(zone->zmgr, false); 15020 } 15021 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 15022 } 15023 15024 /* 15025 * In task context, no locking required. See zone_xfrdone(). 15026 */ 15027 if (zone->xfr != NULL) { 15028 /* The final detach will happen in zone_xfrdone() */ 15029 dns_xfrin_shutdown(zone->xfr); 15030 } 15031 15032 /* Safe to release the zone now */ 15033 if (zone->zmgr != NULL) { 15034 dns_zonemgr_releasezone(zone->zmgr, zone); 15035 } 15036 15037 LOCK_ZONE(zone); 15038 INSIST(zone != zone->raw); 15039 15040 /* 15041 * Detach the views early, we don't need them anymore. However, we need 15042 * to detach them outside of the zone lock to break the lock loop 15043 * between view, adb and zone locks. 15044 */ 15045 view = zone->view; 15046 zone->view = NULL; 15047 prev_view = zone->prev_view; 15048 zone->prev_view = NULL; 15049 15050 if (linked) { 15051 isc_refcount_decrement(&zone->irefs); 15052 } 15053 if (zone->request != NULL) { 15054 dns_request_cancel(zone->request); 15055 } 15056 15057 if (zone->readio != NULL) { 15058 zonemgr_cancelio(zone->readio); 15059 } 15060 15061 if (zone->lctx != NULL) { 15062 dns_loadctx_cancel(zone->lctx); 15063 } 15064 15065 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 15066 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15067 { 15068 if (zone->writeio != NULL) { 15069 zonemgr_cancelio(zone->writeio); 15070 } 15071 15072 if (zone->dctx != NULL) { 15073 dns_dumpctx_cancel(zone->dctx); 15074 } 15075 } 15076 15077 checkds_cancel(zone); 15078 15079 notify_cancel(zone); 15080 15081 forward_cancel(zone); 15082 15083 if (zone->timer != NULL) { 15084 isc_timer_destroy(&zone->timer); 15085 isc_refcount_decrement(&zone->irefs); 15086 } 15087 15088 /* 15089 * We have now canceled everything set the flag to allow exit_check() 15090 * to succeed. We must not unlock between setting this flag and 15091 * calling exit_check(). 15092 */ 15093 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN); 15094 free_needed = exit_check(zone); 15095 /* 15096 * If a dump is in progress for the secure zone, defer detaching from 15097 * the raw zone as it may prevent the unsigned serial number from being 15098 * stored in the raw-format dump of the secure zone. In this scenario, 15099 * dump_done() takes care of cleaning up the zone->raw reference. 15100 */ 15101 if (inline_secure(zone) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 15102 raw = zone->raw; 15103 zone->raw = NULL; 15104 } 15105 if (inline_raw(zone)) { 15106 secure = zone->secure; 15107 zone->secure = NULL; 15108 } 15109 UNLOCK_ZONE(zone); 15110 15111 if (view != NULL) { 15112 dns_view_weakdetach(&view); 15113 } 15114 if (prev_view != NULL) { 15115 dns_view_weakdetach(&prev_view); 15116 } 15117 15118 if (raw != NULL) { 15119 dns_zone_detach(&raw); 15120 } 15121 if (secure != NULL) { 15122 dns_zone_idetach(&secure); 15123 } 15124 if (free_needed) { 15125 zone_free(zone); 15126 } 15127} 15128 15129static void 15130zone_timer(isc_task_t *task, isc_event_t *event) { 15131 const char me[] = "zone_timer"; 15132 dns_zone_t *zone = (dns_zone_t *)event->ev_arg; 15133 15134 UNUSED(task); 15135 REQUIRE(DNS_ZONE_VALID(zone)); 15136 15137 ENTER; 15138 15139 zone_maintenance(zone); 15140 15141 isc_event_free(&event); 15142} 15143 15144static void 15145zone_settimer(dns_zone_t *zone, isc_time_t *now) { 15146 const char me[] = "zone_settimer"; 15147 isc_time_t next; 15148 isc_result_t result; 15149 15150 REQUIRE(DNS_ZONE_VALID(zone)); 15151 REQUIRE(LOCKED_ZONE(zone)); 15152 ENTER; 15153 15154 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 15155 return; 15156 } 15157 15158 isc_time_settoepoch(&next); 15159 15160 switch (zone->type) { 15161 case dns_zone_redirect: 15162 if (zone->primaries != NULL) { 15163 goto treat_as_secondary; 15164 } 15165 FALLTHROUGH; 15166 case dns_zone_primary: 15167 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 15168 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) 15169 { 15170 next = zone->notifytime; 15171 } 15172 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 15173 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15174 { 15175 INSIST(!isc_time_isepoch(&zone->dumptime)); 15176 if (isc_time_isepoch(&next) || 15177 isc_time_compare(&zone->dumptime, &next) < 0) 15178 { 15179 next = zone->dumptime; 15180 } 15181 } 15182 if (zone->type == dns_zone_redirect) { 15183 break; 15184 } 15185 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) && 15186 !isc_time_isepoch(&zone->refreshkeytime)) 15187 { 15188 if (isc_time_isepoch(&next) || 15189 isc_time_compare(&zone->refreshkeytime, &next) < 0) 15190 { 15191 next = zone->refreshkeytime; 15192 } 15193 } 15194 if (!isc_time_isepoch(&zone->resigntime)) { 15195 if (isc_time_isepoch(&next) || 15196 isc_time_compare(&zone->resigntime, &next) < 0) 15197 { 15198 next = zone->resigntime; 15199 } 15200 } 15201 if (!isc_time_isepoch(&zone->keywarntime)) { 15202 if (isc_time_isepoch(&next) || 15203 isc_time_compare(&zone->keywarntime, &next) < 0) 15204 { 15205 next = zone->keywarntime; 15206 } 15207 } 15208 if (!isc_time_isepoch(&zone->signingtime)) { 15209 if (isc_time_isepoch(&next) || 15210 isc_time_compare(&zone->signingtime, &next) < 0) 15211 { 15212 next = zone->signingtime; 15213 } 15214 } 15215 if (!isc_time_isepoch(&zone->nsec3chaintime)) { 15216 if (isc_time_isepoch(&next) || 15217 isc_time_compare(&zone->nsec3chaintime, &next) < 0) 15218 { 15219 next = zone->nsec3chaintime; 15220 } 15221 } 15222 break; 15223 15224 case dns_zone_secondary: 15225 case dns_zone_mirror: 15226 treat_as_secondary: 15227 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 15228 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) 15229 { 15230 next = zone->notifytime; 15231 } 15232 FALLTHROUGH; 15233 case dns_zone_stub: 15234 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) && 15235 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOPRIMARIES) && 15236 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) && 15237 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) && 15238 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) && 15239 !isc_time_isepoch(&zone->refreshtime) && 15240 (isc_time_isepoch(&next) || 15241 isc_time_compare(&zone->refreshtime, &next) < 0)) 15242 { 15243 next = zone->refreshtime; 15244 } 15245 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 15246 !isc_time_isepoch(&zone->expiretime)) 15247 { 15248 if (isc_time_isepoch(&next) || 15249 isc_time_compare(&zone->expiretime, &next) < 0) 15250 { 15251 next = zone->expiretime; 15252 } 15253 } 15254 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 15255 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15256 { 15257 INSIST(!isc_time_isepoch(&zone->dumptime)); 15258 if (isc_time_isepoch(&next) || 15259 isc_time_compare(&zone->dumptime, &next) < 0) 15260 { 15261 next = zone->dumptime; 15262 } 15263 } 15264 break; 15265 15266 case dns_zone_key: 15267 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 15268 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) 15269 { 15270 INSIST(!isc_time_isepoch(&zone->dumptime)); 15271 if (isc_time_isepoch(&next) || 15272 isc_time_compare(&zone->dumptime, &next) < 0) 15273 { 15274 next = zone->dumptime; 15275 } 15276 } 15277 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) { 15278 if (isc_time_isepoch(&next) || 15279 (!isc_time_isepoch(&zone->refreshkeytime) && 15280 isc_time_compare(&zone->refreshkeytime, &next) < 15281 0)) 15282 { 15283 next = zone->refreshkeytime; 15284 } 15285 } 15286 break; 15287 15288 default: 15289 break; 15290 } 15291 15292 if (isc_time_isepoch(&next)) { 15293 zone_debuglog(zone, me, 10, "settimer inactive"); 15294 result = isc_timer_reset(zone->timer, isc_timertype_inactive, 15295 NULL, NULL, true); 15296 if (result != ISC_R_SUCCESS) { 15297 dns_zone_log(zone, ISC_LOG_ERROR, 15298 "could not deactivate zone timer: %s", 15299 isc_result_totext(result)); 15300 } 15301 } else { 15302 if (isc_time_compare(&next, now) <= 0) { 15303 next = *now; 15304 } 15305 result = isc_timer_reset(zone->timer, isc_timertype_once, &next, 15306 NULL, true); 15307 if (result != ISC_R_SUCCESS) { 15308 dns_zone_log(zone, ISC_LOG_ERROR, 15309 "could not reset zone timer: %s", 15310 isc_result_totext(result)); 15311 } 15312 } 15313} 15314 15315static void 15316cancel_refresh(dns_zone_t *zone) { 15317 const char me[] = "cancel_refresh"; 15318 isc_time_t now; 15319 15320 /* 15321 * 'zone' locked by caller. 15322 */ 15323 15324 REQUIRE(DNS_ZONE_VALID(zone)); 15325 REQUIRE(LOCKED_ZONE(zone)); 15326 15327 ENTER; 15328 15329 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 15330 TIME_NOW(&now); 15331 zone_settimer(zone, &now); 15332} 15333 15334static isc_result_t 15335notify_createmessage(dns_zone_t *zone, unsigned int flags, 15336 dns_message_t **messagep) { 15337 dns_db_t *zonedb = NULL; 15338 dns_dbnode_t *node = NULL; 15339 dns_dbversion_t *version = NULL; 15340 dns_message_t *message = NULL; 15341 dns_rdataset_t rdataset; 15342 dns_rdata_t rdata = DNS_RDATA_INIT; 15343 15344 dns_name_t *tempname = NULL; 15345 dns_rdata_t *temprdata = NULL; 15346 dns_rdatalist_t *temprdatalist = NULL; 15347 dns_rdataset_t *temprdataset = NULL; 15348 15349 isc_result_t result; 15350 isc_region_t r; 15351 isc_buffer_t *b = NULL; 15352 15353 REQUIRE(DNS_ZONE_VALID(zone)); 15354 REQUIRE(messagep != NULL && *messagep == NULL); 15355 15356 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message); 15357 15358 message->opcode = dns_opcode_notify; 15359 message->flags |= DNS_MESSAGEFLAG_AA; 15360 message->rdclass = zone->rdclass; 15361 15362 result = dns_message_gettempname(message, &tempname); 15363 if (result != ISC_R_SUCCESS) { 15364 goto cleanup; 15365 } 15366 15367 result = dns_message_gettemprdataset(message, &temprdataset); 15368 if (result != ISC_R_SUCCESS) { 15369 goto cleanup; 15370 } 15371 15372 /* 15373 * Make question. 15374 */ 15375 dns_name_clone(&zone->origin, tempname); 15376 dns_rdataset_makequestion(temprdataset, zone->rdclass, 15377 dns_rdatatype_soa); 15378 ISC_LIST_APPEND(tempname->list, temprdataset, link); 15379 dns_message_addname(message, tempname, DNS_SECTION_QUESTION); 15380 tempname = NULL; 15381 temprdataset = NULL; 15382 15383 if ((flags & DNS_NOTIFY_NOSOA) != 0) { 15384 goto done; 15385 } 15386 15387 result = dns_message_gettempname(message, &tempname); 15388 if (result != ISC_R_SUCCESS) { 15389 goto soa_cleanup; 15390 } 15391 result = dns_message_gettemprdata(message, &temprdata); 15392 if (result != ISC_R_SUCCESS) { 15393 goto soa_cleanup; 15394 } 15395 result = dns_message_gettemprdataset(message, &temprdataset); 15396 if (result != ISC_R_SUCCESS) { 15397 goto soa_cleanup; 15398 } 15399 result = dns_message_gettemprdatalist(message, &temprdatalist); 15400 if (result != ISC_R_SUCCESS) { 15401 goto soa_cleanup; 15402 } 15403 15404 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 15405 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */ 15406 dns_db_attach(zone->db, &zonedb); 15407 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 15408 15409 dns_name_clone(&zone->origin, tempname); 15410 dns_db_currentversion(zonedb, &version); 15411 result = dns_db_findnode(zonedb, tempname, false, &node); 15412 if (result != ISC_R_SUCCESS) { 15413 goto soa_cleanup; 15414 } 15415 15416 dns_rdataset_init(&rdataset); 15417 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, 15418 dns_rdatatype_none, 0, &rdataset, NULL); 15419 if (result != ISC_R_SUCCESS) { 15420 goto soa_cleanup; 15421 } 15422 result = dns_rdataset_first(&rdataset); 15423 if (result != ISC_R_SUCCESS) { 15424 goto soa_cleanup; 15425 } 15426 dns_rdataset_current(&rdataset, &rdata); 15427 dns_rdata_toregion(&rdata, &r); 15428 isc_buffer_allocate(zone->mctx, &b, r.length); 15429 isc_buffer_putmem(b, r.base, r.length); 15430 isc_buffer_usedregion(b, &r); 15431 dns_rdata_init(temprdata); 15432 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r); 15433 dns_message_takebuffer(message, &b); 15434 result = dns_rdataset_next(&rdataset); 15435 dns_rdataset_disassociate(&rdataset); 15436 if (result != ISC_R_NOMORE) { 15437 goto soa_cleanup; 15438 } 15439 temprdatalist->rdclass = rdata.rdclass; 15440 temprdatalist->type = rdata.type; 15441 temprdatalist->ttl = rdataset.ttl; 15442 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link); 15443 15444 result = dns_rdatalist_tordataset(temprdatalist, temprdataset); 15445 if (result != ISC_R_SUCCESS) { 15446 goto soa_cleanup; 15447 } 15448 15449 ISC_LIST_APPEND(tempname->list, temprdataset, link); 15450 dns_message_addname(message, tempname, DNS_SECTION_ANSWER); 15451 temprdatalist = NULL; 15452 temprdataset = NULL; 15453 temprdata = NULL; 15454 tempname = NULL; 15455 15456soa_cleanup: 15457 if (node != NULL) { 15458 dns_db_detachnode(zonedb, &node); 15459 } 15460 if (version != NULL) { 15461 dns_db_closeversion(zonedb, &version, false); 15462 } 15463 if (zonedb != NULL) { 15464 dns_db_detach(&zonedb); 15465 } 15466 if (tempname != NULL) { 15467 dns_message_puttempname(message, &tempname); 15468 } 15469 if (temprdata != NULL) { 15470 dns_message_puttemprdata(message, &temprdata); 15471 } 15472 if (temprdataset != NULL) { 15473 dns_message_puttemprdataset(message, &temprdataset); 15474 } 15475 if (temprdatalist != NULL) { 15476 dns_message_puttemprdatalist(message, &temprdatalist); 15477 } 15478 15479done: 15480 *messagep = message; 15481 return (ISC_R_SUCCESS); 15482 15483cleanup: 15484 if (tempname != NULL) { 15485 dns_message_puttempname(message, &tempname); 15486 } 15487 if (temprdataset != NULL) { 15488 dns_message_puttemprdataset(message, &temprdataset); 15489 } 15490 dns_message_detach(&message); 15491 return (result); 15492} 15493 15494isc_result_t 15495dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, 15496 isc_sockaddr_t *to, dns_message_t *msg) { 15497 unsigned int i; 15498 dns_rdata_soa_t soa; 15499 dns_rdataset_t *rdataset = NULL; 15500 dns_rdata_t rdata = DNS_RDATA_INIT; 15501 isc_result_t result; 15502 char fromtext[ISC_SOCKADDR_FORMATSIZE]; 15503 int match = 0; 15504 isc_netaddr_t netaddr; 15505 uint32_t serial = 0; 15506 bool have_serial = false; 15507 dns_tsigkey_t *tsigkey; 15508 const dns_name_t *tsig; 15509 15510 REQUIRE(DNS_ZONE_VALID(zone)); 15511 15512 /* 15513 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support 15514 * ROLLOVER. 15515 * 15516 * SOA: RFC1996 15517 * Check that 'from' is a valid notify source, (zone->primaries). 15518 * Return DNS_R_REFUSED if not. 15519 * 15520 * If the notify message contains a serial number check it 15521 * against the zones serial and return if <= current serial 15522 * 15523 * If a refresh check is progress, if so just record the 15524 * fact we received a NOTIFY and from where and return. 15525 * We will perform a new refresh check when the current one 15526 * completes. Return ISC_R_SUCCESS. 15527 * 15528 * Otherwise initiate a refresh check using 'from' as the 15529 * first address to check. Return ISC_R_SUCCESS. 15530 */ 15531 15532 isc_sockaddr_format(from, fromtext, sizeof(fromtext)); 15533 15534 /* 15535 * Notify messages are processed by the raw zone. 15536 */ 15537 LOCK_ZONE(zone); 15538 INSIST(zone != zone->raw); 15539 if (inline_secure(zone)) { 15540 result = dns_zone_notifyreceive(zone->raw, from, to, msg); 15541 UNLOCK_ZONE(zone); 15542 return (result); 15543 } 15544 /* 15545 * We only handle NOTIFY (SOA) at the present. 15546 */ 15547 if (isc_sockaddr_pf(from) == PF_INET) { 15548 inc_stats(zone, dns_zonestatscounter_notifyinv4); 15549 } else { 15550 inc_stats(zone, dns_zonestatscounter_notifyinv6); 15551 } 15552 if (msg->counts[DNS_SECTION_QUESTION] == 0 || 15553 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin, 15554 dns_rdatatype_soa, dns_rdatatype_none, NULL, 15555 NULL) != ISC_R_SUCCESS) 15556 { 15557 UNLOCK_ZONE(zone); 15558 if (msg->counts[DNS_SECTION_QUESTION] == 0) { 15559 dns_zone_log(zone, ISC_LOG_NOTICE, 15560 "NOTIFY with no " 15561 "question section from: %s", 15562 fromtext); 15563 return (DNS_R_FORMERR); 15564 } 15565 dns_zone_log(zone, ISC_LOG_NOTICE, 15566 "NOTIFY zone does not match"); 15567 return (DNS_R_NOTIMP); 15568 } 15569 15570 /* 15571 * If we are a primary zone just succeed. 15572 */ 15573 if (zone->type == dns_zone_primary) { 15574 UNLOCK_ZONE(zone); 15575 return (ISC_R_SUCCESS); 15576 } 15577 15578 isc_netaddr_fromsockaddr(&netaddr, from); 15579 for (i = 0; i < zone->primariescnt; i++) { 15580 if (isc_sockaddr_eqaddr(from, &zone->primaries[i])) { 15581 break; 15582 } 15583 if (zone->view->aclenv->match_mapped && 15584 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) && 15585 isc_sockaddr_pf(&zone->primaries[i]) == AF_INET) 15586 { 15587 isc_netaddr_t na1, na2; 15588 isc_netaddr_fromv4mapped(&na1, &netaddr); 15589 isc_netaddr_fromsockaddr(&na2, &zone->primaries[i]); 15590 if (isc_netaddr_equal(&na1, &na2)) { 15591 break; 15592 } 15593 } 15594 } 15595 15596 /* 15597 * Accept notify requests from non primaries if they are on 15598 * 'zone->notify_acl'. 15599 */ 15600 tsigkey = dns_message_gettsigkey(msg); 15601 tsig = dns_tsigkey_identity(tsigkey); 15602 if (i >= zone->primariescnt && zone->notify_acl != NULL && 15603 (dns_acl_match(&netaddr, tsig, zone->notify_acl, zone->view->aclenv, 15604 &match, NULL) == ISC_R_SUCCESS) && 15605 match > 0) 15606 { 15607 /* Accept notify. */ 15608 } else if (i >= zone->primariescnt) { 15609 UNLOCK_ZONE(zone); 15610 dns_zone_log(zone, ISC_LOG_INFO, 15611 "refused notify from non-primary: %s", fromtext); 15612 inc_stats(zone, dns_zonestatscounter_notifyrej); 15613 return (DNS_R_REFUSED); 15614 } 15615 15616 /* 15617 * If the zone is loaded and there are answers check the serial 15618 * to see if we need to do a refresh. Do not worry about this 15619 * check if we are a dialup zone as we use the notify request 15620 * to trigger a refresh check. 15621 */ 15622 if (msg->counts[DNS_SECTION_ANSWER] > 0 && 15623 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 15624 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) 15625 { 15626 result = dns_message_findname( 15627 msg, DNS_SECTION_ANSWER, &zone->origin, 15628 dns_rdatatype_soa, dns_rdatatype_none, NULL, &rdataset); 15629 if (result == ISC_R_SUCCESS) { 15630 result = dns_rdataset_first(rdataset); 15631 } 15632 if (result == ISC_R_SUCCESS) { 15633 uint32_t oldserial; 15634 unsigned int soacount; 15635 15636 dns_rdataset_current(rdataset, &rdata); 15637 result = dns_rdata_tostruct(&rdata, &soa, NULL); 15638 RUNTIME_CHECK(result == ISC_R_SUCCESS); 15639 serial = soa.serial; 15640 have_serial = true; 15641 /* 15642 * The following should safely be performed without DB 15643 * lock and succeed in this context. 15644 */ 15645 result = zone_get_from_db(zone, zone->db, NULL, 15646 &soacount, NULL, &oldserial, 15647 NULL, NULL, NULL, NULL, NULL); 15648 RUNTIME_CHECK(result == ISC_R_SUCCESS); 15649 RUNTIME_CHECK(soacount > 0U); 15650 if (isc_serial_le(serial, oldserial)) { 15651 dns_zone_log(zone, ISC_LOG_INFO, 15652 "notify from %s: " 15653 "zone is up to date", 15654 fromtext); 15655 UNLOCK_ZONE(zone); 15656 return (ISC_R_SUCCESS); 15657 } 15658 } 15659 } 15660 15661 /* 15662 * If we got this far and there was a refresh in progress just 15663 * let it complete. Record where we got the notify from so we 15664 * can perform a refresh check when the current one completes 15665 */ 15666 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { 15667 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 15668 zone->notifyfrom = *from; 15669 UNLOCK_ZONE(zone); 15670 if (have_serial) { 15671 dns_zone_log(zone, ISC_LOG_INFO, 15672 "notify from %s: serial %u: refresh in " 15673 "progress, refresh check queued", 15674 fromtext, serial); 15675 } else { 15676 dns_zone_log(zone, ISC_LOG_INFO, 15677 "notify from %s: refresh in progress, " 15678 "refresh check queued", 15679 fromtext); 15680 } 15681 return (ISC_R_SUCCESS); 15682 } 15683 if (have_serial) { 15684 dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: serial %u", 15685 fromtext, serial); 15686 } else { 15687 dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: no serial", 15688 fromtext); 15689 } 15690 zone->notifyfrom = *from; 15691 UNLOCK_ZONE(zone); 15692 15693 if (to != NULL) { 15694 dns_zonemgr_unreachabledel(zone->zmgr, from, to); 15695 } 15696 dns_zone_refresh(zone); 15697 return (ISC_R_SUCCESS); 15698} 15699 15700void 15701dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) { 15702 REQUIRE(DNS_ZONE_VALID(zone)); 15703 15704 LOCK_ZONE(zone); 15705 if (zone->notify_acl != NULL) { 15706 dns_acl_detach(&zone->notify_acl); 15707 } 15708 dns_acl_attach(acl, &zone->notify_acl); 15709 UNLOCK_ZONE(zone); 15710} 15711 15712void 15713dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) { 15714 REQUIRE(DNS_ZONE_VALID(zone)); 15715 15716 LOCK_ZONE(zone); 15717 if (zone->query_acl != NULL) { 15718 dns_acl_detach(&zone->query_acl); 15719 } 15720 dns_acl_attach(acl, &zone->query_acl); 15721 UNLOCK_ZONE(zone); 15722} 15723 15724void 15725dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) { 15726 REQUIRE(DNS_ZONE_VALID(zone)); 15727 15728 LOCK_ZONE(zone); 15729 if (zone->queryon_acl != NULL) { 15730 dns_acl_detach(&zone->queryon_acl); 15731 } 15732 dns_acl_attach(acl, &zone->queryon_acl); 15733 UNLOCK_ZONE(zone); 15734} 15735 15736void 15737dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) { 15738 REQUIRE(DNS_ZONE_VALID(zone)); 15739 15740 LOCK_ZONE(zone); 15741 if (zone->update_acl != NULL) { 15742 dns_acl_detach(&zone->update_acl); 15743 } 15744 dns_acl_attach(acl, &zone->update_acl); 15745 UNLOCK_ZONE(zone); 15746} 15747 15748void 15749dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) { 15750 REQUIRE(DNS_ZONE_VALID(zone)); 15751 15752 LOCK_ZONE(zone); 15753 if (zone->forward_acl != NULL) { 15754 dns_acl_detach(&zone->forward_acl); 15755 } 15756 dns_acl_attach(acl, &zone->forward_acl); 15757 UNLOCK_ZONE(zone); 15758} 15759 15760void 15761dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) { 15762 REQUIRE(DNS_ZONE_VALID(zone)); 15763 15764 LOCK_ZONE(zone); 15765 if (zone->xfr_acl != NULL) { 15766 dns_acl_detach(&zone->xfr_acl); 15767 } 15768 dns_acl_attach(acl, &zone->xfr_acl); 15769 UNLOCK_ZONE(zone); 15770} 15771 15772dns_acl_t * 15773dns_zone_getnotifyacl(dns_zone_t *zone) { 15774 REQUIRE(DNS_ZONE_VALID(zone)); 15775 15776 return (zone->notify_acl); 15777} 15778 15779dns_acl_t * 15780dns_zone_getqueryacl(dns_zone_t *zone) { 15781 REQUIRE(DNS_ZONE_VALID(zone)); 15782 15783 return (zone->query_acl); 15784} 15785 15786dns_acl_t * 15787dns_zone_getqueryonacl(dns_zone_t *zone) { 15788 REQUIRE(DNS_ZONE_VALID(zone)); 15789 15790 return (zone->queryon_acl); 15791} 15792 15793dns_acl_t * 15794dns_zone_getupdateacl(dns_zone_t *zone) { 15795 REQUIRE(DNS_ZONE_VALID(zone)); 15796 15797 return (zone->update_acl); 15798} 15799 15800dns_acl_t * 15801dns_zone_getforwardacl(dns_zone_t *zone) { 15802 REQUIRE(DNS_ZONE_VALID(zone)); 15803 15804 return (zone->forward_acl); 15805} 15806 15807dns_acl_t * 15808dns_zone_getxfracl(dns_zone_t *zone) { 15809 REQUIRE(DNS_ZONE_VALID(zone)); 15810 15811 return (zone->xfr_acl); 15812} 15813 15814void 15815dns_zone_clearupdateacl(dns_zone_t *zone) { 15816 REQUIRE(DNS_ZONE_VALID(zone)); 15817 15818 LOCK_ZONE(zone); 15819 if (zone->update_acl != NULL) { 15820 dns_acl_detach(&zone->update_acl); 15821 } 15822 UNLOCK_ZONE(zone); 15823} 15824 15825void 15826dns_zone_clearforwardacl(dns_zone_t *zone) { 15827 REQUIRE(DNS_ZONE_VALID(zone)); 15828 15829 LOCK_ZONE(zone); 15830 if (zone->forward_acl != NULL) { 15831 dns_acl_detach(&zone->forward_acl); 15832 } 15833 UNLOCK_ZONE(zone); 15834} 15835 15836void 15837dns_zone_clearnotifyacl(dns_zone_t *zone) { 15838 REQUIRE(DNS_ZONE_VALID(zone)); 15839 15840 LOCK_ZONE(zone); 15841 if (zone->notify_acl != NULL) { 15842 dns_acl_detach(&zone->notify_acl); 15843 } 15844 UNLOCK_ZONE(zone); 15845} 15846 15847void 15848dns_zone_clearqueryacl(dns_zone_t *zone) { 15849 REQUIRE(DNS_ZONE_VALID(zone)); 15850 15851 LOCK_ZONE(zone); 15852 if (zone->query_acl != NULL) { 15853 dns_acl_detach(&zone->query_acl); 15854 } 15855 UNLOCK_ZONE(zone); 15856} 15857 15858void 15859dns_zone_clearqueryonacl(dns_zone_t *zone) { 15860 REQUIRE(DNS_ZONE_VALID(zone)); 15861 15862 LOCK_ZONE(zone); 15863 if (zone->queryon_acl != NULL) { 15864 dns_acl_detach(&zone->queryon_acl); 15865 } 15866 UNLOCK_ZONE(zone); 15867} 15868 15869void 15870dns_zone_clearxfracl(dns_zone_t *zone) { 15871 REQUIRE(DNS_ZONE_VALID(zone)); 15872 15873 LOCK_ZONE(zone); 15874 if (zone->xfr_acl != NULL) { 15875 dns_acl_detach(&zone->xfr_acl); 15876 } 15877 UNLOCK_ZONE(zone); 15878} 15879 15880bool 15881dns_zone_getupdatedisabled(dns_zone_t *zone) { 15882 REQUIRE(DNS_ZONE_VALID(zone)); 15883 return (zone->update_disabled); 15884} 15885 15886void 15887dns_zone_setupdatedisabled(dns_zone_t *zone, bool state) { 15888 REQUIRE(DNS_ZONE_VALID(zone)); 15889 zone->update_disabled = state; 15890} 15891 15892bool 15893dns_zone_getzeronosoattl(dns_zone_t *zone) { 15894 REQUIRE(DNS_ZONE_VALID(zone)); 15895 return (zone->zero_no_soa_ttl); 15896} 15897 15898void 15899dns_zone_setzeronosoattl(dns_zone_t *zone, bool state) { 15900 REQUIRE(DNS_ZONE_VALID(zone)); 15901 zone->zero_no_soa_ttl = state; 15902} 15903 15904void 15905dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) { 15906 REQUIRE(DNS_ZONE_VALID(zone)); 15907 15908 zone->check_names = severity; 15909} 15910 15911dns_severity_t 15912dns_zone_getchecknames(dns_zone_t *zone) { 15913 REQUIRE(DNS_ZONE_VALID(zone)); 15914 15915 return (zone->check_names); 15916} 15917 15918void 15919dns_zone_setjournalsize(dns_zone_t *zone, int32_t size) { 15920 REQUIRE(DNS_ZONE_VALID(zone)); 15921 15922 zone->journalsize = size; 15923} 15924 15925int32_t 15926dns_zone_getjournalsize(dns_zone_t *zone) { 15927 REQUIRE(DNS_ZONE_VALID(zone)); 15928 15929 return (zone->journalsize); 15930} 15931 15932static void 15933zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) { 15934 isc_result_t result = ISC_R_FAILURE; 15935 isc_buffer_t buffer; 15936 15937 REQUIRE(buf != NULL); 15938 REQUIRE(length > 1U); 15939 15940 /* 15941 * Leave space for terminating '\0'. 15942 */ 15943 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 15944 if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) { 15945 if (dns_name_dynamic(&zone->origin)) { 15946 result = dns_name_totext(&zone->origin, true, &buffer); 15947 } 15948 if (result != ISC_R_SUCCESS && 15949 isc_buffer_availablelength(&buffer) >= 15950 (sizeof("<UNKNOWN>") - 1)) 15951 { 15952 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 15953 } 15954 15955 if (isc_buffer_availablelength(&buffer) > 0) { 15956 isc_buffer_putstr(&buffer, "/"); 15957 } 15958 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 15959 } 15960 15961 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 && 15962 strcmp(zone->view->name, "_default") != 0 && 15963 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) 15964 { 15965 isc_buffer_putstr(&buffer, "/"); 15966 isc_buffer_putstr(&buffer, zone->view->name); 15967 } 15968 if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer)) { 15969 isc_buffer_putstr(&buffer, " (signed)"); 15970 } 15971 if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer)) { 15972 isc_buffer_putstr(&buffer, " (unsigned)"); 15973 } 15974 15975 buf[isc_buffer_usedlength(&buffer)] = '\0'; 15976} 15977 15978static void 15979zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) { 15980 isc_result_t result = ISC_R_FAILURE; 15981 isc_buffer_t buffer; 15982 15983 REQUIRE(buf != NULL); 15984 REQUIRE(length > 1U); 15985 15986 /* 15987 * Leave space for terminating '\0'. 15988 */ 15989 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 15990 if (dns_name_dynamic(&zone->origin)) { 15991 result = dns_name_totext(&zone->origin, true, &buffer); 15992 } 15993 if (result != ISC_R_SUCCESS && 15994 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1)) 15995 { 15996 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 15997 } 15998 15999 buf[isc_buffer_usedlength(&buffer)] = '\0'; 16000} 16001 16002static void 16003zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) { 16004 isc_buffer_t buffer; 16005 16006 REQUIRE(buf != NULL); 16007 REQUIRE(length > 1U); 16008 16009 /* 16010 * Leave space for terminating '\0'. 16011 */ 16012 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 16013 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 16014 16015 buf[isc_buffer_usedlength(&buffer)] = '\0'; 16016} 16017 16018static void 16019zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) { 16020 isc_buffer_t buffer; 16021 16022 REQUIRE(buf != NULL); 16023 REQUIRE(length > 1U); 16024 16025 /* 16026 * Leave space for terminating '\0'. 16027 */ 16028 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 16029 16030 if (zone->view == NULL) { 16031 isc_buffer_putstr(&buffer, "_none"); 16032 } else if (strlen(zone->view->name) < 16033 isc_buffer_availablelength(&buffer)) 16034 { 16035 isc_buffer_putstr(&buffer, zone->view->name); 16036 } else { 16037 isc_buffer_putstr(&buffer, "_toolong"); 16038 } 16039 16040 buf[isc_buffer_usedlength(&buffer)] = '\0'; 16041} 16042 16043void 16044dns_zone_name(dns_zone_t *zone, char *buf, size_t length) { 16045 REQUIRE(DNS_ZONE_VALID(zone)); 16046 REQUIRE(buf != NULL); 16047 16048 LOCK_ZONE(zone); 16049 zone_namerd_tostr(zone, buf, length); 16050 UNLOCK_ZONE(zone); 16051} 16052 16053void 16054dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) { 16055 REQUIRE(DNS_ZONE_VALID(zone)); 16056 REQUIRE(buf != NULL); 16057 zone_name_tostr(zone, buf, length); 16058} 16059 16060void 16061dns_zone_logv(dns_zone_t *zone, isc_logcategory_t *category, int level, 16062 const char *prefix, const char *fmt, va_list ap) { 16063 char message[4096]; 16064 const char *zstr; 16065 16066 REQUIRE(DNS_ZONE_VALID(zone)); 16067 16068 if (!isc_log_wouldlog(dns_lctx, level)) { 16069 return; 16070 } 16071 16072 vsnprintf(message, sizeof(message), fmt, ap); 16073 16074 switch (zone->type) { 16075 case dns_zone_key: 16076 zstr = "managed-keys-zone"; 16077 break; 16078 case dns_zone_redirect: 16079 zstr = "redirect-zone"; 16080 break; 16081 default: 16082 zstr = "zone "; 16083 } 16084 16085 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, level, 16086 "%s%s%s%s: %s", (prefix != NULL ? prefix : ""), 16087 (prefix != NULL ? ": " : ""), zstr, zone->strnamerd, 16088 message); 16089} 16090 16091static void 16092notify_log(dns_zone_t *zone, int level, const char *fmt, ...) { 16093 va_list ap; 16094 16095 va_start(ap, fmt); 16096 dns_zone_logv(zone, DNS_LOGCATEGORY_NOTIFY, level, NULL, fmt, ap); 16097 va_end(ap); 16098} 16099 16100void 16101dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, int level, 16102 const char *fmt, ...) { 16103 va_list ap; 16104 16105 va_start(ap, fmt); 16106 dns_zone_logv(zone, category, level, NULL, fmt, ap); 16107 va_end(ap); 16108} 16109 16110void 16111dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) { 16112 va_list ap; 16113 16114 va_start(ap, fmt); 16115 dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, NULL, fmt, ap); 16116 va_end(ap); 16117} 16118 16119static void 16120zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel, const char *fmt, 16121 ...) { 16122 int level = ISC_LOG_DEBUG(debuglevel); 16123 va_list ap; 16124 16125 va_start(ap, fmt); 16126 dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, me, fmt, ap); 16127 va_end(ap); 16128} 16129 16130static void 16131dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...) { 16132 va_list ap; 16133 16134 va_start(ap, fmt); 16135 dns_zone_logv(zone, DNS_LOGCATEGORY_DNSSEC, level, NULL, fmt, ap); 16136 va_end(ap); 16137} 16138 16139static int 16140message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type) { 16141 isc_result_t result; 16142 dns_name_t *name; 16143 dns_rdataset_t *curr; 16144 int count = 0; 16145 16146 result = dns_message_firstname(msg, section); 16147 while (result == ISC_R_SUCCESS) { 16148 name = NULL; 16149 dns_message_currentname(msg, section, &name); 16150 16151 for (curr = ISC_LIST_TAIL(name->list); curr != NULL; 16152 curr = ISC_LIST_PREV(curr, link)) 16153 { 16154 if (curr->type == type) { 16155 count++; 16156 } 16157 } 16158 result = dns_message_nextname(msg, section); 16159 } 16160 16161 return (count); 16162} 16163 16164void 16165dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin) { 16166 REQUIRE(DNS_ZONE_VALID(zone)); 16167 16168 zone->maxxfrin = maxxfrin; 16169} 16170 16171uint32_t 16172dns_zone_getmaxxfrin(dns_zone_t *zone) { 16173 REQUIRE(DNS_ZONE_VALID(zone)); 16174 16175 return (zone->maxxfrin); 16176} 16177 16178void 16179dns_zone_setmaxxfrout(dns_zone_t *zone, uint32_t maxxfrout) { 16180 REQUIRE(DNS_ZONE_VALID(zone)); 16181 zone->maxxfrout = maxxfrout; 16182} 16183 16184uint32_t 16185dns_zone_getmaxxfrout(dns_zone_t *zone) { 16186 REQUIRE(DNS_ZONE_VALID(zone)); 16187 16188 return (zone->maxxfrout); 16189} 16190 16191dns_zonetype_t 16192dns_zone_gettype(dns_zone_t *zone) { 16193 REQUIRE(DNS_ZONE_VALID(zone)); 16194 16195 return (zone->type); 16196} 16197 16198const char * 16199dns_zonetype_name(dns_zonetype_t type) { 16200 switch (type) { 16201 case dns_zone_none: 16202 return ("none"); 16203 case dns_zone_primary: 16204 return ("primary"); 16205 case dns_zone_secondary: 16206 return ("secondary"); 16207 case dns_zone_mirror: 16208 return ("mirror"); 16209 case dns_zone_stub: 16210 return ("stub"); 16211 case dns_zone_staticstub: 16212 return ("static-stub"); 16213 case dns_zone_key: 16214 return ("key"); 16215 case dns_zone_dlz: 16216 return ("dlz"); 16217 case dns_zone_redirect: 16218 return ("redirect"); 16219 default: 16220 return ("unknown"); 16221 } 16222} 16223 16224dns_zonetype_t 16225dns_zone_getredirecttype(dns_zone_t *zone) { 16226 REQUIRE(DNS_ZONE_VALID(zone)); 16227 REQUIRE(zone->type == dns_zone_redirect); 16228 16229 return (zone->primaries == NULL ? dns_zone_primary 16230 : dns_zone_secondary); 16231} 16232 16233dns_name_t * 16234dns_zone_getorigin(dns_zone_t *zone) { 16235 REQUIRE(DNS_ZONE_VALID(zone)); 16236 16237 return (&zone->origin); 16238} 16239 16240void 16241dns_zone_settask(dns_zone_t *zone, isc_task_t *task) { 16242 REQUIRE(DNS_ZONE_VALID(zone)); 16243 16244 LOCK_ZONE(zone); 16245 if (zone->task != NULL) { 16246 isc_task_detach(&zone->task); 16247 } 16248 isc_task_attach(task, &zone->task); 16249 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 16250 if (zone->db != NULL) { 16251 dns_db_settask(zone->db, zone->task); 16252 } 16253 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 16254 UNLOCK_ZONE(zone); 16255} 16256 16257void 16258dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) { 16259 REQUIRE(DNS_ZONE_VALID(zone)); 16260 isc_task_attach(zone->task, target); 16261} 16262 16263void 16264dns_zone_setidlein(dns_zone_t *zone, uint32_t idlein) { 16265 REQUIRE(DNS_ZONE_VALID(zone)); 16266 16267 if (idlein == 0) { 16268 idlein = DNS_DEFAULT_IDLEIN; 16269 } 16270 zone->idlein = idlein; 16271} 16272 16273uint32_t 16274dns_zone_getidlein(dns_zone_t *zone) { 16275 REQUIRE(DNS_ZONE_VALID(zone)); 16276 16277 return (zone->idlein); 16278} 16279 16280void 16281dns_zone_setidleout(dns_zone_t *zone, uint32_t idleout) { 16282 REQUIRE(DNS_ZONE_VALID(zone)); 16283 16284 zone->idleout = idleout; 16285} 16286 16287uint32_t 16288dns_zone_getidleout(dns_zone_t *zone) { 16289 REQUIRE(DNS_ZONE_VALID(zone)); 16290 16291 return (zone->idleout); 16292} 16293 16294static void 16295notify_done(isc_task_t *task, isc_event_t *event) { 16296 dns_requestevent_t *revent = (dns_requestevent_t *)event; 16297 dns_notify_t *notify; 16298 isc_result_t result; 16299 dns_message_t *message = NULL; 16300 isc_buffer_t buf; 16301 char rcode[128]; 16302 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 16303 16304 UNUSED(task); 16305 16306 notify = event->ev_arg; 16307 REQUIRE(DNS_NOTIFY_VALID(notify)); 16308 INSIST(task == notify->zone->task); 16309 16310 isc_buffer_init(&buf, rcode, sizeof(rcode)); 16311 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 16312 dns_message_create(notify->zone->mctx, DNS_MESSAGE_INTENTPARSE, 16313 &message); 16314 16315 if (revent->result != ISC_R_SUCCESS) { 16316 result = revent->result; 16317 goto fail; 16318 } 16319 16320 result = dns_request_getresponse(revent->request, message, 16321 DNS_MESSAGEPARSE_PRESERVEORDER); 16322 if (result != ISC_R_SUCCESS) { 16323 goto fail; 16324 } 16325 16326 result = dns_rcode_totext(message->rcode, &buf); 16327 if (result == ISC_R_SUCCESS) { 16328 notify_log(notify->zone, ISC_LOG_DEBUG(3), 16329 "notify response from %s: %.*s", addrbuf, 16330 (int)buf.used, rcode); 16331 } 16332 16333 goto done; 16334 16335fail: 16336 notify_log(notify->zone, ISC_LOG_DEBUG(2), "notify to %s failed: %s", 16337 addrbuf, isc_result_totext(result)); 16338 if (result == ISC_R_TIMEDOUT) { 16339 notify_log(notify->zone, ISC_LOG_DEBUG(1), 16340 "notify to %s: retries exceeded", addrbuf); 16341 } 16342done: 16343 notify_destroy(notify, false); 16344 isc_event_free(&event); 16345 dns_message_detach(&message); 16346} 16347 16348struct secure_event { 16349 isc_event_t e; 16350 dns_db_t *db; 16351 uint32_t serial; 16352}; 16353 16354static void 16355update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) { 16356 UNUSED(arg); 16357 dns_zone_log(zone, level, "%s", message); 16358} 16359 16360static isc_result_t 16361sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal, 16362 uint32_t start, uint32_t end, dns_difftuple_t **soatuplep, 16363 dns_diff_t *diff) { 16364 isc_result_t result; 16365 dns_difftuple_t *tuple = NULL; 16366 dns_diffop_t op = DNS_DIFFOP_ADD; 16367 int n_soa = 0; 16368 16369 REQUIRE(soatuplep != NULL); 16370 16371 if (start == end) { 16372 return (DNS_R_UNCHANGED); 16373 } 16374 16375 CHECK(dns_journal_iter_init(journal, start, end, NULL)); 16376 for (result = dns_journal_first_rr(journal); result == ISC_R_SUCCESS; 16377 result = dns_journal_next_rr(journal)) 16378 { 16379 dns_name_t *name = NULL; 16380 uint32_t ttl; 16381 dns_rdata_t *rdata = NULL; 16382 dns_journal_current_rr(journal, &name, &ttl, &rdata); 16383 16384 if (rdata->type == dns_rdatatype_soa) { 16385 n_soa++; 16386 if (n_soa == 2) { 16387 /* 16388 * Save the latest raw SOA record. 16389 */ 16390 if (*soatuplep != NULL) { 16391 dns_difftuple_free(soatuplep); 16392 } 16393 CHECK(dns_difftuple_create( 16394 diff->mctx, DNS_DIFFOP_ADD, name, ttl, 16395 rdata, soatuplep)); 16396 } 16397 if (n_soa == 3) { 16398 n_soa = 1; 16399 } 16400 continue; 16401 } 16402 16403 /* Sanity. */ 16404 if (n_soa == 0) { 16405 dns_zone_log(raw, ISC_LOG_ERROR, 16406 "corrupt journal file: '%s'\n", 16407 raw->journal); 16408 return (ISC_R_FAILURE); 16409 } 16410 16411 if (zone->privatetype != 0 && rdata->type == zone->privatetype) 16412 { 16413 continue; 16414 } 16415 16416 if (rdata->type == dns_rdatatype_nsec || 16417 rdata->type == dns_rdatatype_rrsig || 16418 rdata->type == dns_rdatatype_nsec3 || 16419 rdata->type == dns_rdatatype_dnskey || 16420 rdata->type == dns_rdatatype_nsec3param) 16421 { 16422 continue; 16423 } 16424 16425 op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD; 16426 16427 CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata, 16428 &tuple)); 16429 dns_diff_appendminimal(diff, &tuple); 16430 } 16431 if (result == ISC_R_NOMORE) { 16432 result = ISC_R_SUCCESS; 16433 } 16434 16435failure: 16436 return (result); 16437} 16438 16439static isc_result_t 16440sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb, 16441 dns_dbversion_t *secver, dns_difftuple_t **soatuple, 16442 dns_diff_t *diff) { 16443 isc_result_t result; 16444 dns_db_t *rawdb = NULL; 16445 dns_dbversion_t *rawver = NULL; 16446 dns_difftuple_t *tuple = NULL, *next; 16447 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL; 16448 dns_rdata_soa_t oldsoa, newsoa; 16449 16450 REQUIRE(DNS_ZONE_VALID(seczone)); 16451 REQUIRE(soatuple != NULL && *soatuple == NULL); 16452 16453 if (!seczone->sourceserialset) { 16454 return (DNS_R_UNCHANGED); 16455 } 16456 16457 dns_db_attach(raw->db, &rawdb); 16458 dns_db_currentversion(rawdb, &rawver); 16459 result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL); 16460 dns_db_closeversion(rawdb, &rawver, false); 16461 dns_db_detach(&rawdb); 16462 16463 if (result != ISC_R_SUCCESS) { 16464 return (result); 16465 } 16466 16467 for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; tuple = next) { 16468 next = ISC_LIST_NEXT(tuple, link); 16469 if (tuple->rdata.type == dns_rdatatype_nsec || 16470 tuple->rdata.type == dns_rdatatype_rrsig || 16471 tuple->rdata.type == dns_rdatatype_dnskey || 16472 tuple->rdata.type == dns_rdatatype_nsec3 || 16473 tuple->rdata.type == dns_rdatatype_nsec3param) 16474 { 16475 ISC_LIST_UNLINK(diff->tuples, tuple, link); 16476 dns_difftuple_free(&tuple); 16477 continue; 16478 } 16479 if (tuple->rdata.type == dns_rdatatype_soa) { 16480 if (tuple->op == DNS_DIFFOP_DEL) { 16481 INSIST(oldtuple == NULL); 16482 oldtuple = tuple; 16483 } 16484 if (tuple->op == DNS_DIFFOP_ADD) { 16485 INSIST(newtuple == NULL); 16486 newtuple = tuple; 16487 } 16488 } 16489 } 16490 16491 if (oldtuple != NULL && newtuple != NULL) { 16492 result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL); 16493 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16494 16495 result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL); 16496 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16497 16498 /* 16499 * If the SOA records are the same except for the serial 16500 * remove them from the diff. 16501 */ 16502 if (oldtuple->ttl == newtuple->ttl && 16503 oldsoa.refresh == newsoa.refresh && 16504 oldsoa.retry == newsoa.retry && 16505 oldsoa.minimum == newsoa.minimum && 16506 oldsoa.expire == newsoa.expire && 16507 dns_name_equal(&oldsoa.origin, &newsoa.origin) && 16508 dns_name_equal(&oldsoa.contact, &newsoa.contact)) 16509 { 16510 ISC_LIST_UNLINK(diff->tuples, oldtuple, link); 16511 dns_difftuple_free(&oldtuple); 16512 ISC_LIST_UNLINK(diff->tuples, newtuple, link); 16513 dns_difftuple_free(&newtuple); 16514 } 16515 } 16516 16517 if (ISC_LIST_EMPTY(diff->tuples)) { 16518 return (DNS_R_UNCHANGED); 16519 } 16520 16521 /* 16522 * If there are still SOA records in the diff they can now be removed 16523 * saving the new SOA record. 16524 */ 16525 if (oldtuple != NULL) { 16526 ISC_LIST_UNLINK(diff->tuples, oldtuple, link); 16527 dns_difftuple_free(&oldtuple); 16528 } 16529 16530 if (newtuple != NULL) { 16531 ISC_LIST_UNLINK(diff->tuples, newtuple, link); 16532 *soatuple = newtuple; 16533 } 16534 16535 return (ISC_R_SUCCESS); 16536} 16537 16538static void 16539receive_secure_serial(isc_task_t *task, isc_event_t *event) { 16540 static char me[] = "receive_secure_serial"; 16541 isc_result_t result = ISC_R_SUCCESS; 16542 dns_journal_t *rjournal = NULL; 16543 dns_journal_t *sjournal = NULL; 16544 uint32_t start, end; 16545 dns_zone_t *zone; 16546 dns_difftuple_t *tuple = NULL, *soatuple = NULL; 16547 dns_update_log_t log = { update_log_cb, NULL }; 16548 uint32_t newserial = 0, desired = 0; 16549 isc_time_t timenow; 16550 int level = ISC_LOG_ERROR; 16551 16552 UNUSED(task); 16553 16554 zone = event->ev_arg; 16555 end = ((struct secure_event *)event)->serial; 16556 16557 ENTER; 16558 16559 LOCK_ZONE(zone); 16560 16561 /* 16562 * If we are already processing a receive secure serial event 16563 * for the zone, just queue the new one and exit. 16564 */ 16565 if (zone->rss_event != NULL && zone->rss_event != event) { 16566 ISC_LIST_APPEND(zone->rss_events, event, ev_link); 16567 UNLOCK_ZONE(zone); 16568 return; 16569 } 16570 16571nextevent: 16572 if (zone->rss_event != NULL) { 16573 INSIST(zone->rss_event == event); 16574 UNLOCK_ZONE(zone); 16575 } else { 16576 zone->rss_event = event; 16577 dns_diff_init(zone->mctx, &zone->rss_diff); 16578 16579 /* 16580 * zone->db may be NULL, if the load from disk failed. 16581 */ 16582 result = ISC_R_SUCCESS; 16583 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 16584 if (zone->db != NULL) { 16585 dns_db_attach(zone->db, &zone->rss_db); 16586 } else { 16587 result = ISC_R_FAILURE; 16588 } 16589 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 16590 16591 if (result == ISC_R_SUCCESS && zone->raw != NULL) { 16592 dns_zone_attach(zone->raw, &zone->rss_raw); 16593 } else { 16594 result = ISC_R_FAILURE; 16595 } 16596 16597 UNLOCK_ZONE(zone); 16598 16599 CHECK(result); 16600 16601 /* 16602 * We first attempt to sync the raw zone to the secure zone 16603 * by using the raw zone's journal, applying all the deltas 16604 * from the latest source-serial of the secure zone up to 16605 * the current serial number of the raw zone. 16606 * 16607 * If that fails, then we'll fall back to a direct comparison 16608 * between raw and secure zones. 16609 */ 16610 CHECK(dns_journal_open(zone->rss_raw->mctx, 16611 zone->rss_raw->journal, 16612 DNS_JOURNAL_WRITE, &rjournal)); 16613 16614 result = dns_journal_open(zone->mctx, zone->journal, 16615 DNS_JOURNAL_READ, &sjournal); 16616 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 16617 goto failure; 16618 } 16619 16620 if (!dns_journal_get_sourceserial(rjournal, &start)) { 16621 start = dns_journal_first_serial(rjournal); 16622 dns_journal_set_sourceserial(rjournal, start); 16623 } 16624 if (sjournal != NULL) { 16625 uint32_t serial; 16626 /* 16627 * We read the secure journal first, if that 16628 * exists use its value provided it is greater 16629 * that from the raw journal. 16630 */ 16631 if (dns_journal_get_sourceserial(sjournal, &serial)) { 16632 if (isc_serial_gt(serial, start)) { 16633 start = serial; 16634 } 16635 } 16636 dns_journal_destroy(&sjournal); 16637 } 16638 16639 dns_db_currentversion(zone->rss_db, &zone->rss_oldver); 16640 CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver)); 16641 16642 /* 16643 * Try to apply diffs from the raw zone's journal to the secure 16644 * zone. If that fails, we recover by syncing up the databases 16645 * directly. 16646 */ 16647 result = sync_secure_journal(zone, zone->rss_raw, rjournal, 16648 start, end, &soatuple, 16649 &zone->rss_diff); 16650 if (result == DNS_R_UNCHANGED) { 16651 goto failure; 16652 } else if (result != ISC_R_SUCCESS) { 16653 CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db, 16654 zone->rss_oldver, &soatuple, 16655 &zone->rss_diff)); 16656 } 16657 16658 CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db, 16659 zone->rss_newver)); 16660 16661 if (soatuple != NULL) { 16662 uint32_t oldserial; 16663 16664 CHECK(dns_db_createsoatuple( 16665 zone->rss_db, zone->rss_oldver, 16666 zone->rss_diff.mctx, DNS_DIFFOP_DEL, &tuple)); 16667 oldserial = dns_soa_getserial(&tuple->rdata); 16668 newserial = desired = 16669 dns_soa_getserial(&soatuple->rdata); 16670 if (!isc_serial_gt(newserial, oldserial)) { 16671 newserial = oldserial + 1; 16672 if (newserial == 0) { 16673 newserial++; 16674 } 16675 dns_soa_setserial(newserial, &soatuple->rdata); 16676 } 16677 CHECK(do_one_tuple(&tuple, zone->rss_db, 16678 zone->rss_newver, &zone->rss_diff)); 16679 CHECK(do_one_tuple(&soatuple, zone->rss_db, 16680 zone->rss_newver, &zone->rss_diff)); 16681 } else { 16682 CHECK(update_soa_serial(zone, zone->rss_db, 16683 zone->rss_newver, 16684 &zone->rss_diff, zone->mctx, 16685 zone->updatemethod)); 16686 } 16687 } 16688 result = dns_update_signaturesinc( 16689 &log, zone, zone->rss_db, zone->rss_oldver, zone->rss_newver, 16690 &zone->rss_diff, zone->sigvalidityinterval, &zone->rss_state); 16691 if (result == DNS_R_CONTINUE) { 16692 if (rjournal != NULL) { 16693 dns_journal_destroy(&rjournal); 16694 } 16695 isc_task_send(task, &event); 16696 return; 16697 } 16698 /* 16699 * If something went wrong while trying to update the secure zone and 16700 * the latter was already signed before, do not apply raw zone deltas 16701 * to it as that would break existing DNSSEC signatures. However, if 16702 * the secure zone was not yet signed (e.g. because no signing keys 16703 * were created for it), commence applying raw zone deltas to it so 16704 * that contents of the raw zone and the secure zone are kept in sync. 16705 */ 16706 if (result != ISC_R_SUCCESS && dns_db_issecure(zone->rss_db)) { 16707 goto failure; 16708 } 16709 16710 if (rjournal == NULL) { 16711 CHECK(dns_journal_open(zone->rss_raw->mctx, 16712 zone->rss_raw->journal, 16713 DNS_JOURNAL_WRITE, &rjournal)); 16714 } 16715 CHECK(zone_journal(zone, &zone->rss_diff, &end, 16716 "receive_secure_serial")); 16717 16718 dns_journal_set_sourceserial(rjournal, end); 16719 dns_journal_commit(rjournal); 16720 16721 LOCK_ZONE(zone); 16722 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 16723 16724 zone->sourceserial = end; 16725 zone->sourceserialset = true; 16726 zone_needdump(zone, DNS_DUMP_DELAY); 16727 16728 /* 16729 * Set resign time to make sure it is set to the earliest 16730 * signature expiration. 16731 */ 16732 set_resigntime(zone); 16733 TIME_NOW(&timenow); 16734 zone_settimer(zone, &timenow); 16735 UNLOCK_ZONE(zone); 16736 16737 dns_db_closeversion(zone->rss_db, &zone->rss_oldver, false); 16738 dns_db_closeversion(zone->rss_db, &zone->rss_newver, true); 16739 16740 if (newserial != 0) { 16741 dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)", 16742 newserial, desired); 16743 } 16744 16745failure: 16746 isc_event_free(&zone->rss_event); 16747 event = ISC_LIST_HEAD(zone->rss_events); 16748 16749 if (zone->rss_raw != NULL) { 16750 dns_zone_detach(&zone->rss_raw); 16751 } 16752 if (result != ISC_R_SUCCESS) { 16753 LOCK_ZONE(zone); 16754 set_resigntime(zone); 16755 TIME_NOW(&timenow); 16756 zone_settimer(zone, &timenow); 16757 UNLOCK_ZONE(zone); 16758 if (result == DNS_R_UNCHANGED) { 16759 level = ISC_LOG_INFO; 16760 } 16761 dns_zone_log(zone, level, "receive_secure_serial: %s", 16762 isc_result_totext(result)); 16763 } 16764 if (tuple != NULL) { 16765 dns_difftuple_free(&tuple); 16766 } 16767 if (soatuple != NULL) { 16768 dns_difftuple_free(&soatuple); 16769 } 16770 if (zone->rss_db != NULL) { 16771 if (zone->rss_oldver != NULL) { 16772 dns_db_closeversion(zone->rss_db, &zone->rss_oldver, 16773 false); 16774 } 16775 if (zone->rss_newver != NULL) { 16776 dns_db_closeversion(zone->rss_db, &zone->rss_newver, 16777 false); 16778 } 16779 dns_db_detach(&zone->rss_db); 16780 } 16781 INSIST(zone->rss_oldver == NULL); 16782 INSIST(zone->rss_newver == NULL); 16783 if (rjournal != NULL) { 16784 dns_journal_destroy(&rjournal); 16785 } 16786 dns_diff_clear(&zone->rss_diff); 16787 16788 if (event != NULL) { 16789 LOCK_ZONE(zone); 16790 isc_refcount_decrement(&zone->irefs); 16791 ISC_LIST_UNLINK(zone->rss_events, event, ev_link); 16792 goto nextevent; 16793 } 16794 16795 event = ISC_LIST_HEAD(zone->rss_post); 16796 while (event != NULL) { 16797 ISC_LIST_UNLINK(zone->rss_post, event, ev_link); 16798 rss_post(zone, event); 16799 event = ISC_LIST_HEAD(zone->rss_post); 16800 } 16801 16802 dns_zone_idetach(&zone); 16803} 16804 16805static isc_result_t 16806zone_send_secureserial(dns_zone_t *zone, uint32_t serial) { 16807 isc_event_t *e; 16808 dns_zone_t *dummy = NULL; 16809 16810 e = isc_event_allocate(zone->secure->mctx, zone, 16811 DNS_EVENT_ZONESECURESERIAL, 16812 receive_secure_serial, zone->secure, 16813 sizeof(struct secure_event)); 16814 ((struct secure_event *)e)->serial = serial; 16815 INSIST(LOCKED_ZONE(zone->secure)); 16816 zone_iattach(zone->secure, &dummy); 16817 isc_task_send(zone->secure->task, &e); 16818 16819 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); 16820 return (ISC_R_SUCCESS); 16821} 16822 16823static isc_result_t 16824checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 16825 dns_rdataset_t *rdataset, uint32_t oldserial) { 16826 dns_rdata_soa_t soa; 16827 dns_rdata_t rdata = DNS_RDATA_INIT; 16828 dns_rdatalist_t temprdatalist; 16829 dns_rdataset_t temprdataset; 16830 isc_buffer_t b; 16831 isc_result_t result; 16832 unsigned char buf[DNS_SOA_BUFFERSIZE]; 16833 dns_fixedname_t fixed; 16834 dns_name_t *name; 16835 16836 result = dns_rdataset_first(rdataset); 16837 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16838 dns_rdataset_current(rdataset, &rdata); 16839 result = dns_rdata_tostruct(&rdata, &soa, NULL); 16840 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16841 16842 if (isc_serial_gt(soa.serial, oldserial)) { 16843 return (dns_db_addrdataset(db, node, version, 0, rdataset, 0, 16844 NULL)); 16845 } 16846 /* 16847 * Always bump the serial. 16848 */ 16849 oldserial++; 16850 if (oldserial == 0) { 16851 oldserial++; 16852 } 16853 soa.serial = oldserial; 16854 16855 /* 16856 * Construct a replacement rdataset. 16857 */ 16858 dns_rdata_reset(&rdata); 16859 isc_buffer_init(&b, buf, sizeof(buf)); 16860 result = dns_rdata_fromstruct(&rdata, rdataset->rdclass, 16861 dns_rdatatype_soa, &soa, &b); 16862 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16863 dns_rdatalist_init(&temprdatalist); 16864 temprdatalist.rdclass = rdata.rdclass; 16865 temprdatalist.type = rdata.type; 16866 temprdatalist.ttl = rdataset->ttl; 16867 ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link); 16868 16869 dns_rdataset_init(&temprdataset); 16870 result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset); 16871 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16872 16873 name = dns_fixedname_initname(&fixed); 16874 result = dns_db_nodefullname(db, node, name); 16875 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16876 dns_rdataset_getownercase(rdataset, name); 16877 dns_rdataset_setownercase(&temprdataset, name); 16878 return (dns_db_addrdataset(db, node, version, 0, &temprdataset, 0, 16879 NULL)); 16880} 16881 16882/* 16883 * This function should populate an nsec3paramlist_t with the 16884 * nsecparam_t data from a zone. 16885 */ 16886static isc_result_t 16887save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) { 16888 isc_result_t result; 16889 dns_dbnode_t *node = NULL; 16890 dns_rdataset_t rdataset, prdataset; 16891 dns_dbversion_t *version = NULL; 16892 nsec3param_t *nsec3param = NULL; 16893 nsec3param_t *nsec3p = NULL; 16894 nsec3param_t *next; 16895 dns_db_t *db = NULL; 16896 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 16897 16898 REQUIRE(DNS_ZONE_VALID(zone)); 16899 REQUIRE(nsec3list != NULL); 16900 REQUIRE(ISC_LIST_EMPTY(*nsec3list)); 16901 16902 dns_rdataset_init(&rdataset); 16903 dns_rdataset_init(&prdataset); 16904 16905 dns_db_attach(zone->db, &db); 16906 CHECK(dns_db_getoriginnode(db, &node)); 16907 16908 dns_db_currentversion(db, &version); 16909 result = dns_db_findrdataset(db, node, version, 16910 dns_rdatatype_nsec3param, 16911 dns_rdatatype_none, 0, &rdataset, NULL); 16912 16913 if (result != ISC_R_SUCCESS) { 16914 goto getprivate; 16915 } 16916 16917 /* 16918 * Walk nsec3param rdataset making a list of parameters (note that 16919 * multiple simultaneous nsec3 chains are annoyingly legal -- this 16920 * is why we use an nsec3list, even though we will usually only 16921 * have one). 16922 */ 16923 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 16924 result = dns_rdataset_next(&rdataset)) 16925 { 16926 dns_rdata_t rdata = DNS_RDATA_INIT; 16927 dns_rdata_t private = DNS_RDATA_INIT; 16928 16929 dns_rdataset_current(&rdataset, &rdata); 16930 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 16931 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 16932 "looping through nsec3param data"); 16933 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t)); 16934 ISC_LINK_INIT(nsec3param, link); 16935 16936 /* 16937 * now transfer the data from the rdata to 16938 * the nsec3param 16939 */ 16940 dns_nsec3param_toprivate(&rdata, &private, zone->privatetype, 16941 nsec3param->data, 16942 sizeof(nsec3param->data)); 16943 nsec3param->length = private.length; 16944 ISC_LIST_APPEND(*nsec3list, nsec3param, link); 16945 } 16946 16947getprivate: 16948 result = dns_db_findrdataset(db, node, version, zone->privatetype, 16949 dns_rdatatype_none, 0, &prdataset, NULL); 16950 if (result != ISC_R_SUCCESS) { 16951 goto done; 16952 } 16953 16954 /* 16955 * walk private type records, converting them to nsec3 parameters 16956 * using dns_nsec3param_fromprivate(), do the right thing based on 16957 * CREATE and REMOVE flags 16958 */ 16959 for (result = dns_rdataset_first(&prdataset); result == ISC_R_SUCCESS; 16960 result = dns_rdataset_next(&prdataset)) 16961 { 16962 dns_rdata_t rdata = DNS_RDATA_INIT; 16963 dns_rdata_t private = DNS_RDATA_INIT; 16964 16965 dns_rdataset_current(&prdataset, &private); 16966 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 16967 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 16968 "looping through nsec3param private data"); 16969 16970 /* 16971 * Do we have a valid private record? 16972 */ 16973 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 16974 sizeof(buf))) 16975 { 16976 continue; 16977 } 16978 16979 /* 16980 * Remove any NSEC3PARAM records scheduled to be removed. 16981 */ 16982 if (NSEC3REMOVE(rdata.data[1])) { 16983 /* 16984 * Zero out the flags. 16985 */ 16986 rdata.data[1] = 0; 16987 16988 for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; 16989 nsec3p = next) 16990 { 16991 next = ISC_LIST_NEXT(nsec3p, link); 16992 16993 if (nsec3p->length == rdata.length + 1 && 16994 memcmp(rdata.data, nsec3p->data + 1, 16995 nsec3p->length - 1) == 0) 16996 { 16997 ISC_LIST_UNLINK(*nsec3list, nsec3p, 16998 link); 16999 isc_mem_put(zone->mctx, nsec3p, 17000 sizeof(nsec3param_t)); 17001 } 17002 } 17003 continue; 17004 } 17005 17006 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t)); 17007 ISC_LINK_INIT(nsec3param, link); 17008 17009 /* 17010 * Copy the remaining private records so the nsec/nsec3 17011 * chain gets created. 17012 */ 17013 INSIST(private.length <= sizeof(nsec3param->data)); 17014 memmove(nsec3param->data, private.data, private.length); 17015 nsec3param->length = private.length; 17016 ISC_LIST_APPEND(*nsec3list, nsec3param, link); 17017 } 17018 17019done: 17020 if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) { 17021 result = ISC_R_SUCCESS; 17022 } 17023 17024failure: 17025 if (node != NULL) { 17026 dns_db_detachnode(db, &node); 17027 } 17028 if (version != NULL) { 17029 dns_db_closeversion(db, &version, false); 17030 } 17031 if (db != NULL) { 17032 dns_db_detach(&db); 17033 } 17034 if (dns_rdataset_isassociated(&rdataset)) { 17035 dns_rdataset_disassociate(&rdataset); 17036 } 17037 if (dns_rdataset_isassociated(&prdataset)) { 17038 dns_rdataset_disassociate(&prdataset); 17039 } 17040 return (result); 17041} 17042 17043/* 17044 * Populate new zone db with private type records found by save_nsec3param(). 17045 */ 17046static isc_result_t 17047restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 17048 nsec3paramlist_t *nsec3list) { 17049 isc_result_t result = ISC_R_SUCCESS; 17050 dns_diff_t diff; 17051 dns_rdata_t rdata; 17052 nsec3param_t *nsec3p = NULL; 17053 nsec3param_t *next; 17054 17055 REQUIRE(DNS_ZONE_VALID(zone)); 17056 REQUIRE(!ISC_LIST_EMPTY(*nsec3list)); 17057 17058 dns_diff_init(zone->mctx, &diff); 17059 17060 /* 17061 * Loop through the list of private-type records, set the INITIAL 17062 * and CREATE flags, and the add the record to the apex of the tree 17063 * in db. 17064 */ 17065 for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; nsec3p = next) 17066 { 17067 next = ISC_LIST_NEXT(nsec3p, link); 17068 dns_rdata_init(&rdata); 17069 nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL; 17070 rdata.length = nsec3p->length; 17071 rdata.data = nsec3p->data; 17072 rdata.type = zone->privatetype; 17073 rdata.rdclass = zone->rdclass; 17074 result = update_one_rr(db, version, &diff, DNS_DIFFOP_ADD, 17075 &zone->origin, 0, &rdata); 17076 if (result != ISC_R_SUCCESS) { 17077 break; 17078 } 17079 } 17080 17081 dns_diff_clear(&diff); 17082 return (result); 17083} 17084 17085static isc_result_t 17086copy_non_dnssec_records(dns_db_t *db, dns_db_t *version, dns_db_t *rawdb, 17087 dns_dbiterator_t *dbiterator, unsigned int *oldserial) { 17088 dns_dbnode_t *rawnode = NULL, *node = NULL; 17089 dns_fixedname_t fixed; 17090 dns_name_t *name = dns_fixedname_initname(&fixed); 17091 dns_rdataset_t rdataset; 17092 dns_rdatasetiter_t *rdsit = NULL; 17093 isc_result_t result; 17094 17095 result = dns_dbiterator_current(dbiterator, &rawnode, name); 17096 if (result != ISC_R_SUCCESS) { 17097 return (ISC_R_SUCCESS); 17098 } 17099 17100 dns_dbiterator_pause(dbiterator); 17101 17102 result = dns_db_findnode(db, name, true, &node); 17103 if (result != ISC_R_SUCCESS) { 17104 goto cleanup; 17105 } 17106 17107 result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, 0, &rdsit); 17108 if (result != ISC_R_SUCCESS) { 17109 goto cleanup; 17110 } 17111 17112 dns_rdataset_init(&rdataset); 17113 17114 for (result = dns_rdatasetiter_first(rdsit); result == ISC_R_SUCCESS; 17115 result = dns_rdatasetiter_next(rdsit)) 17116 { 17117 dns_rdatasetiter_current(rdsit, &rdataset); 17118 if (rdataset.type == dns_rdatatype_nsec || 17119 rdataset.type == dns_rdatatype_rrsig || 17120 rdataset.type == dns_rdatatype_nsec3 || 17121 rdataset.type == dns_rdatatype_dnskey || 17122 rdataset.type == dns_rdatatype_nsec3param) 17123 { 17124 dns_rdataset_disassociate(&rdataset); 17125 continue; 17126 } 17127 if (rdataset.type == dns_rdatatype_soa && oldserial != NULL) { 17128 result = checkandaddsoa(db, node, version, &rdataset, 17129 *oldserial); 17130 } else { 17131 result = dns_db_addrdataset(db, node, version, 0, 17132 &rdataset, 0, NULL); 17133 } 17134 dns_rdataset_disassociate(&rdataset); 17135 if (result != ISC_R_SUCCESS) { 17136 goto cleanup; 17137 } 17138 } 17139 if (result == ISC_R_NOMORE) { 17140 result = ISC_R_SUCCESS; 17141 } 17142 17143cleanup: 17144 if (rdsit != NULL) { 17145 dns_rdatasetiter_destroy(&rdsit); 17146 } 17147 if (rawnode) { 17148 dns_db_detachnode(rawdb, &rawnode); 17149 } 17150 if (node) { 17151 dns_db_detachnode(db, &node); 17152 } 17153 return (result); 17154} 17155 17156static void 17157receive_secure_db(isc_task_t *task, isc_event_t *event) { 17158 isc_result_t result; 17159 dns_zone_t *zone; 17160 dns_db_t *rawdb, *db = NULL; 17161 dns_dbiterator_t *dbiterator = NULL; 17162 dns_dbversion_t *version = NULL; 17163 isc_time_t loadtime; 17164 unsigned int oldserial = 0, *oldserialp = NULL; 17165 nsec3paramlist_t nsec3list; 17166 isc_event_t *setnsec3param_event; 17167 dns_zone_t *dummy; 17168 17169 UNUSED(task); 17170 17171 ISC_LIST_INIT(nsec3list); 17172 17173 zone = event->ev_arg; 17174 rawdb = ((struct secure_event *)event)->db; 17175 isc_event_free(&event); 17176 17177 LOCK_ZONE(zone); 17178 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) { 17179 result = ISC_R_SHUTTINGDOWN; 17180 goto failure; 17181 } 17182 17183 TIME_NOW(&loadtime); 17184 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 17185 if (zone->db != NULL) { 17186 result = dns_db_getsoaserial(zone->db, NULL, &oldserial); 17187 if (result == ISC_R_SUCCESS) { 17188 oldserialp = &oldserial; 17189 } 17190 17191 /* 17192 * assemble nsec3parameters from the old zone, and set a flag 17193 * if any are found 17194 */ 17195 result = save_nsec3param(zone, &nsec3list); 17196 if (result != ISC_R_SUCCESS) { 17197 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17198 goto failure; 17199 } 17200 } 17201 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17202 17203 result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, 17204 dns_dbtype_zone, zone->rdclass, 17205 zone->db_argc - 1, zone->db_argv + 1, &db); 17206 if (result != ISC_R_SUCCESS) { 17207 goto failure; 17208 } 17209 17210 result = dns_db_setgluecachestats(db, zone->gluecachestats); 17211 if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { 17212 goto failure; 17213 } 17214 17215 result = dns_db_newversion(db, &version); 17216 if (result != ISC_R_SUCCESS) { 17217 goto failure; 17218 } 17219 17220 result = dns_db_createiterator(rawdb, 0, &dbiterator); 17221 if (result != ISC_R_SUCCESS) { 17222 goto failure; 17223 } 17224 17225 for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS; 17226 result = dns_dbiterator_next(dbiterator)) 17227 { 17228 result = copy_non_dnssec_records(db, version, rawdb, dbiterator, 17229 oldserialp); 17230 if (result != ISC_R_SUCCESS) { 17231 goto failure; 17232 } 17233 } 17234 dns_dbiterator_destroy(&dbiterator); 17235 if (result != ISC_R_NOMORE) { 17236 goto failure; 17237 } 17238 17239 /* 17240 * Call restore_nsec3param() to create private-type records from 17241 * the old nsec3 parameters and insert them into db 17242 */ 17243 if (!ISC_LIST_EMPTY(nsec3list)) { 17244 result = restore_nsec3param(zone, db, version, &nsec3list); 17245 if (result != ISC_R_SUCCESS) { 17246 goto failure; 17247 } 17248 } 17249 17250 dns_db_closeversion(db, &version, true); 17251 17252 /* 17253 * Lock hierarchy: zmgr, zone, raw. 17254 */ 17255 INSIST(zone != zone->raw); 17256 LOCK_ZONE(zone->raw); 17257 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 17258 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 17259 zone_needdump(zone, 0); /* XXXMPA */ 17260 UNLOCK_ZONE(zone->raw); 17261 17262 /* 17263 * Process any queued NSEC3PARAM change requests. 17264 */ 17265 while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) { 17266 setnsec3param_event = ISC_LIST_HEAD(zone->setnsec3param_queue); 17267 ISC_LIST_UNLINK(zone->setnsec3param_queue, setnsec3param_event, 17268 ev_link); 17269 dummy = NULL; 17270 zone_iattach(zone, &dummy); 17271 isc_task_send(zone->task, &setnsec3param_event); 17272 } 17273 17274failure: 17275 UNLOCK_ZONE(zone); 17276 if (dbiterator != NULL) { 17277 dns_dbiterator_destroy(&dbiterator); 17278 } 17279 if (result != ISC_R_SUCCESS) { 17280 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s", 17281 isc_result_totext(result)); 17282 } 17283 17284 while (!ISC_LIST_EMPTY(nsec3list)) { 17285 nsec3param_t *nsec3p; 17286 nsec3p = ISC_LIST_HEAD(nsec3list); 17287 ISC_LIST_UNLINK(nsec3list, nsec3p, link); 17288 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t)); 17289 } 17290 if (db != NULL) { 17291 if (version != NULL) { 17292 dns_db_closeversion(db, &version, false); 17293 } 17294 dns_db_detach(&db); 17295 } 17296 dns_db_detach(&rawdb); 17297 dns_zone_idetach(&zone); 17298 17299 INSIST(version == NULL); 17300} 17301 17302static isc_result_t 17303zone_send_securedb(dns_zone_t *zone, dns_db_t *db) { 17304 isc_event_t *e; 17305 dns_db_t *dummy = NULL; 17306 dns_zone_t *secure = NULL; 17307 17308 e = isc_event_allocate(zone->secure->mctx, zone, DNS_EVENT_ZONESECUREDB, 17309 receive_secure_db, zone->secure, 17310 sizeof(struct secure_event)); 17311 dns_db_attach(db, &dummy); 17312 ((struct secure_event *)e)->db = dummy; 17313 INSIST(LOCKED_ZONE(zone->secure)); 17314 zone_iattach(zone->secure, &secure); 17315 isc_task_send(zone->secure->task, &e); 17316 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); 17317 return (ISC_R_SUCCESS); 17318} 17319 17320isc_result_t 17321dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) { 17322 isc_result_t result; 17323 dns_zone_t *secure = NULL; 17324 17325 REQUIRE(DNS_ZONE_VALID(zone)); 17326again: 17327 LOCK_ZONE(zone); 17328 if (inline_raw(zone)) { 17329 secure = zone->secure; 17330 INSIST(secure != zone); 17331 TRYLOCK_ZONE(result, secure); 17332 if (result != ISC_R_SUCCESS) { 17333 UNLOCK_ZONE(zone); 17334 secure = NULL; 17335 isc_thread_yield(); 17336 goto again; 17337 } 17338 } 17339 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 17340 result = zone_replacedb(zone, db, dump); 17341 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 17342 if (secure != NULL) { 17343 UNLOCK_ZONE(secure); 17344 } 17345 UNLOCK_ZONE(zone); 17346 return (result); 17347} 17348 17349static isc_result_t 17350zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) { 17351 dns_dbversion_t *ver; 17352 isc_result_t result; 17353 unsigned int soacount = 0; 17354 unsigned int nscount = 0; 17355 17356 /* 17357 * 'zone' and 'zone->db' locked by caller. 17358 */ 17359 REQUIRE(DNS_ZONE_VALID(zone)); 17360 REQUIRE(LOCKED_ZONE(zone)); 17361 if (inline_raw(zone)) { 17362 REQUIRE(LOCKED_ZONE(zone->secure)); 17363 } 17364 17365 result = zone_get_from_db(zone, db, &nscount, &soacount, NULL, NULL, 17366 NULL, NULL, NULL, NULL, NULL); 17367 if (result == ISC_R_SUCCESS) { 17368 if (soacount != 1) { 17369 dns_zone_log(zone, ISC_LOG_ERROR, "has %d SOA records", 17370 soacount); 17371 result = DNS_R_BADZONE; 17372 } 17373 if (nscount == 0 && zone->type != dns_zone_key) { 17374 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records"); 17375 result = DNS_R_BADZONE; 17376 } 17377 if (result != ISC_R_SUCCESS) { 17378 return (result); 17379 } 17380 } else { 17381 dns_zone_log(zone, ISC_LOG_ERROR, 17382 "retrieving SOA and NS records failed: %s", 17383 isc_result_totext(result)); 17384 return (result); 17385 } 17386 17387 result = check_nsec3param(zone, db); 17388 if (result != ISC_R_SUCCESS) { 17389 return (result); 17390 } 17391 17392 ver = NULL; 17393 dns_db_currentversion(db, &ver); 17394 17395 /* 17396 * The initial version of a secondary zone is always dumped; 17397 * subsequent versions may be journaled instead if this 17398 * is enabled in the configuration. 17399 */ 17400 if (zone->db != NULL && zone->journal != NULL && 17401 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 17402 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) 17403 { 17404 uint32_t serial, oldserial; 17405 17406 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs"); 17407 17408 result = dns_db_getsoaserial(db, ver, &serial); 17409 if (result != ISC_R_SUCCESS) { 17410 dns_zone_log(zone, ISC_LOG_ERROR, 17411 "ixfr-from-differences: unable to get " 17412 "new serial"); 17413 goto fail; 17414 } 17415 17416 /* 17417 * This is checked in zone_postload() for primary zones. 17418 */ 17419 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, 17420 &oldserial, NULL, NULL, NULL, NULL, 17421 NULL); 17422 RUNTIME_CHECK(result == ISC_R_SUCCESS); 17423 RUNTIME_CHECK(soacount > 0U); 17424 if ((zone->type == dns_zone_secondary || 17425 (zone->type == dns_zone_redirect && 17426 zone->primaries != NULL)) && 17427 !isc_serial_gt(serial, oldserial)) 17428 { 17429 uint32_t serialmin, serialmax; 17430 serialmin = (oldserial + 1) & 0xffffffffU; 17431 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; 17432 dns_zone_log(zone, ISC_LOG_ERROR, 17433 "ixfr-from-differences: failed: " 17434 "new serial (%u) out of range [%u - %u]", 17435 serial, serialmin, serialmax); 17436 result = ISC_R_RANGE; 17437 goto fail; 17438 } 17439 17440 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL, 17441 zone->journal); 17442 if (result != ISC_R_SUCCESS) { 17443 char strbuf[ISC_STRERRORSIZE]; 17444 strerror_r(errno, strbuf, sizeof(strbuf)); 17445 dns_zone_log(zone, ISC_LOG_ERROR, 17446 "ixfr-from-differences: failed: " 17447 "%s", 17448 strbuf); 17449 goto fallback; 17450 } 17451 if (dump) { 17452 zone_needdump(zone, DNS_DUMP_DELAY); 17453 } else { 17454 zone_journal_compact(zone, zone->db, serial); 17455 } 17456 if (zone->type == dns_zone_primary && inline_raw(zone)) { 17457 zone_send_secureserial(zone, serial); 17458 } 17459 } else { 17460 fallback: 17461 if (dump && zone->masterfile != NULL) { 17462 /* 17463 * If DNS_ZONEFLG_FORCEXFER was set we don't want 17464 * to keep the old masterfile. 17465 */ 17466 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) && 17467 remove(zone->masterfile) < 0 && errno != ENOENT) 17468 { 17469 char strbuf[ISC_STRERRORSIZE]; 17470 strerror_r(errno, strbuf, sizeof(strbuf)); 17471 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17472 DNS_LOGMODULE_ZONE, 17473 ISC_LOG_WARNING, 17474 "unable to remove masterfile " 17475 "'%s': '%s'", 17476 zone->masterfile, strbuf); 17477 } 17478 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) { 17479 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY); 17480 } else { 17481 zone_needdump(zone, 0); 17482 } 17483 } 17484 if (dump && zone->journal != NULL) { 17485 /* 17486 * The in-memory database just changed, and 17487 * because 'dump' is set, it didn't change by 17488 * being loaded from disk. Also, we have not 17489 * journaled diffs for this change. 17490 * Therefore, the on-disk journal is missing 17491 * the deltas for this change. Since it can 17492 * no longer be used to bring the zone 17493 * up-to-date, it is useless and should be 17494 * removed. 17495 */ 17496 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17497 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 17498 "removing journal file"); 17499 if (remove(zone->journal) < 0 && errno != ENOENT) { 17500 char strbuf[ISC_STRERRORSIZE]; 17501 strerror_r(errno, strbuf, sizeof(strbuf)); 17502 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 17503 DNS_LOGMODULE_ZONE, 17504 ISC_LOG_WARNING, 17505 "unable to remove journal " 17506 "'%s': '%s'", 17507 zone->journal, strbuf); 17508 } 17509 } 17510 17511 if (inline_raw(zone)) { 17512 zone_send_securedb(zone, db); 17513 } 17514 } 17515 17516 dns_db_closeversion(db, &ver, false); 17517 17518 dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database"); 17519 17520 if (zone->db != NULL) { 17521 zone_detachdb(zone); 17522 } 17523 zone_attachdb(zone, db); 17524 dns_db_settask(zone->db, zone->task); 17525 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY); 17526 return (ISC_R_SUCCESS); 17527 17528fail: 17529 dns_db_closeversion(db, &ver, false); 17530 return (result); 17531} 17532 17533/* The caller must hold the dblock as a writer. */ 17534static void 17535zone_attachdb(dns_zone_t *zone, dns_db_t *db) { 17536 REQUIRE(zone->db == NULL && db != NULL); 17537 17538 dns_db_attach(db, &zone->db); 17539} 17540 17541/* The caller must hold the dblock as a writer. */ 17542static void 17543zone_detachdb(dns_zone_t *zone) { 17544 REQUIRE(zone->db != NULL); 17545 17546 dns_zone_rpz_disable_db(zone, zone->db); 17547 dns_zone_catz_disable_db(zone, zone->db); 17548 dns_db_detach(&zone->db); 17549} 17550 17551static void 17552zone_xfrdone(dns_zone_t *zone, isc_result_t result) { 17553 isc_time_t now; 17554 bool again = false; 17555 unsigned int soacount; 17556 unsigned int nscount; 17557 uint32_t serial, refresh, retry, expire, minimum, soattl; 17558 isc_result_t xfrresult = result; 17559 bool free_needed; 17560 dns_zone_t *secure = NULL; 17561 17562 REQUIRE(DNS_ZONE_VALID(zone)); 17563 17564 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 17565 "zone transfer finished: %s", isc_result_totext(result)); 17566 17567 /* 17568 * Obtaining a lock on the zone->secure (see zone_send_secureserial) 17569 * could result in a deadlock due to a LOR so we will spin if we 17570 * can't obtain both locks. 17571 */ 17572again: 17573 LOCK_ZONE(zone); 17574 if (inline_raw(zone)) { 17575 secure = zone->secure; 17576 INSIST(secure != zone); 17577 TRYLOCK_ZONE(result, secure); 17578 if (result != ISC_R_SUCCESS) { 17579 UNLOCK_ZONE(zone); 17580 secure = NULL; 17581 isc_thread_yield(); 17582 goto again; 17583 } 17584 } 17585 17586 INSIST(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)); 17587 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 17588 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 17589 17590 TIME_NOW(&now); 17591 switch (xfrresult) { 17592 case ISC_R_SUCCESS: 17593 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 17594 FALLTHROUGH; 17595 case DNS_R_UPTODATE: 17596 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER); 17597 /* 17598 * Has the zone expired underneath us? 17599 */ 17600 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 17601 if (zone->db == NULL) { 17602 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17603 goto same_primary; 17604 } 17605 17606 /* 17607 * Update the zone structure's data from the actual 17608 * SOA received. 17609 */ 17610 nscount = 0; 17611 soacount = 0; 17612 INSIST(zone->db != NULL); 17613 result = zone_get_from_db(zone, zone->db, &nscount, &soacount, 17614 &soattl, &serial, &refresh, &retry, 17615 &expire, &minimum, NULL); 17616 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17617 if (result == ISC_R_SUCCESS) { 17618 if (soacount != 1) { 17619 dns_zone_log(zone, ISC_LOG_ERROR, 17620 "transferred zone " 17621 "has %d SOA records", 17622 soacount); 17623 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) 17624 { 17625 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 17626 zone->retry = DNS_ZONE_DEFAULTRETRY; 17627 } 17628 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 17629 zone_unload(zone); 17630 goto next_primary; 17631 } 17632 if (nscount == 0) { 17633 dns_zone_log(zone, ISC_LOG_ERROR, 17634 "transferred zone " 17635 "has no NS records"); 17636 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) 17637 { 17638 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 17639 zone->retry = DNS_ZONE_DEFAULTRETRY; 17640 } 17641 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 17642 zone_unload(zone); 17643 goto next_primary; 17644 } 17645 zone->refresh = RANGE(refresh, zone->minrefresh, 17646 zone->maxrefresh); 17647 zone->retry = RANGE(retry, zone->minretry, 17648 zone->maxretry); 17649 zone->expire = RANGE(expire, 17650 zone->refresh + zone->retry, 17651 DNS_MAX_EXPIRE); 17652 zone->soattl = soattl; 17653 zone->minimum = minimum; 17654 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 17655 } 17656 17657 /* 17658 * Set our next update/expire times. 17659 */ 17660 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 17661 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 17662 zone->refreshtime = now; 17663 DNS_ZONE_TIME_ADD(&now, zone->expire, 17664 &zone->expiretime); 17665 } else { 17666 DNS_ZONE_JITTER_ADD(&now, zone->refresh, 17667 &zone->refreshtime); 17668 DNS_ZONE_TIME_ADD(&now, zone->expire, 17669 &zone->expiretime); 17670 } 17671 17672 /* 17673 * Set loadtime. 17674 */ 17675 zone->loadtime = now; 17676 17677 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) { 17678 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")]; 17679 if (zone->tsigkey != NULL) { 17680 char namebuf[DNS_NAME_FORMATSIZE]; 17681 dns_name_format(&zone->tsigkey->name, namebuf, 17682 sizeof(namebuf)); 17683 snprintf(buf, sizeof(buf), ": TSIG '%s'", 17684 namebuf); 17685 } else { 17686 buf[0] = '\0'; 17687 } 17688 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 17689 ISC_LOG_INFO, "transferred serial %u%s", 17690 serial, buf); 17691 if (inline_raw(zone)) { 17692 zone_send_secureserial(zone, serial); 17693 } 17694 } 17695 17696 /* 17697 * This is not necessary if we just performed a AXFR 17698 * however it is necessary for an IXFR / UPTODATE and 17699 * won't hurt with an AXFR. 17700 */ 17701 if (zone->masterfile != NULL || zone->journal != NULL) { 17702 unsigned int delay = DNS_DUMP_DELAY; 17703 17704 result = ISC_R_FAILURE; 17705 if (zone->journal != NULL) { 17706 result = isc_file_settime(zone->journal, &now); 17707 } 17708 if (result != ISC_R_SUCCESS && zone->masterfile != NULL) 17709 { 17710 result = isc_file_settime(zone->masterfile, 17711 &now); 17712 } 17713 17714 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) || 17715 result == ISC_R_FILENOTFOUND) 17716 { 17717 delay = 0; 17718 } 17719 17720 if ((result == ISC_R_SUCCESS || 17721 result == ISC_R_FILENOTFOUND) && 17722 zone->masterfile != NULL) 17723 { 17724 zone_needdump(zone, delay); 17725 } else if (result != ISC_R_SUCCESS) { 17726 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 17727 ISC_LOG_ERROR, 17728 "transfer: could not set file " 17729 "modification time of '%s': %s", 17730 zone->masterfile, 17731 isc_result_totext(result)); 17732 } 17733 } 17734 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY); 17735 inc_stats(zone, dns_zonestatscounter_xfrsuccess); 17736 break; 17737 17738 case DNS_R_BADIXFR: 17739 /* Force retry with AXFR. */ 17740 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOIXFR); 17741 goto same_primary; 17742 17743 case DNS_R_TOOMANYRECORDS: 17744 case DNS_R_VERIFYFAILURE: 17745 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 17746 inc_stats(zone, dns_zonestatscounter_xfrfail); 17747 break; 17748 17749 default: 17750 next_primary: 17751 /* 17752 * Skip to next failed / untried primary. 17753 */ 17754 do { 17755 zone->curprimary++; 17756 } while (zone->curprimary < zone->primariescnt && 17757 zone->primariesok[zone->curprimary]); 17758 same_primary: 17759 if (zone->curprimary >= zone->primariescnt) { 17760 zone->curprimary = 0; 17761 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 17762 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) 17763 { 17764 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 17765 DNS_ZONE_SETFLAG(zone, 17766 DNS_ZONEFLG_USEALTXFRSRC); 17767 while (zone->curprimary < zone->primariescnt && 17768 zone->primariesok[zone->curprimary]) 17769 { 17770 zone->curprimary++; 17771 } 17772 again = true; 17773 } else { 17774 DNS_ZONE_CLRFLAG(zone, 17775 DNS_ZONEFLG_USEALTXFRSRC); 17776 } 17777 } else { 17778 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 17779 again = true; 17780 } 17781 inc_stats(zone, dns_zonestatscounter_xfrfail); 17782 break; 17783 } 17784 zone_settimer(zone, &now); 17785 17786 /* 17787 * If creating the transfer object failed, zone->xfr is NULL. 17788 * Otherwise, we are called as the done callback of a zone 17789 * transfer object that just entered its shutting-down 17790 * state. Since we are no longer responsible for shutting 17791 * it down, we can detach our reference. 17792 */ 17793 if (zone->xfr != NULL) { 17794 dns_xfrin_detach(&zone->xfr); 17795 } 17796 17797 if (zone->tsigkey != NULL) { 17798 dns_tsigkey_detach(&zone->tsigkey); 17799 } 17800 17801 if (zone->transport != NULL) { 17802 dns_transport_detach(&zone->transport); 17803 } 17804 17805 /* 17806 * Handle any deferred journal compaction. 17807 */ 17808 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) { 17809 dns_db_t *db = NULL; 17810 if (dns_zone_getdb(zone, &db) == ISC_R_SUCCESS) { 17811 zone_journal_compact(zone, db, zone->compact_serial); 17812 dns_db_detach(&db); 17813 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 17814 } 17815 } 17816 17817 if (secure != NULL) { 17818 UNLOCK_ZONE(secure); 17819 } 17820 /* 17821 * This transfer finishing freed up a transfer quota slot. 17822 * Let any other zones waiting for quota have it. 17823 */ 17824 if (zone->zmgr != NULL && 17825 zone->statelist == &zone->zmgr->xfrin_in_progress) 17826 { 17827 UNLOCK_ZONE(zone); 17828 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 17829 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink); 17830 zone->statelist = NULL; 17831 zmgr_resume_xfrs(zone->zmgr, false); 17832 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 17833 LOCK_ZONE(zone); 17834 } 17835 17836 /* 17837 * Retry with a different server if necessary. 17838 */ 17839 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 17840 queue_soa_query(zone); 17841 } 17842 17843 isc_refcount_decrement(&zone->irefs); 17844 free_needed = exit_check(zone); 17845 UNLOCK_ZONE(zone); 17846 if (free_needed) { 17847 zone_free(zone); 17848 } 17849} 17850 17851static void 17852zone_loaddone(void *arg, isc_result_t result) { 17853 static char me[] = "zone_loaddone"; 17854 dns_load_t *load = arg; 17855 dns_zone_t *zone; 17856 isc_result_t tresult; 17857 dns_zone_t *secure = NULL; 17858 17859 REQUIRE(DNS_LOAD_VALID(load)); 17860 zone = load->zone; 17861 17862 ENTER; 17863 17864 /* 17865 * If zone loading failed, remove the update db callbacks prior 17866 * to calling the list of callbacks in the zone load structure. 17867 */ 17868 if (result != ISC_R_SUCCESS) { 17869 dns_zone_rpz_disable_db(zone, load->db); 17870 dns_zone_catz_disable_db(zone, load->db); 17871 } 17872 17873 tresult = dns_db_endload(load->db, &load->callbacks); 17874 if (tresult != ISC_R_SUCCESS && 17875 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)) 17876 { 17877 result = tresult; 17878 } 17879 17880 /* 17881 * Lock hierarchy: zmgr, zone, raw. 17882 */ 17883again: 17884 LOCK_ZONE(zone); 17885 INSIST(zone != zone->raw); 17886 if (inline_secure(zone)) { 17887 LOCK_ZONE(zone->raw); 17888 } else if (inline_raw(zone)) { 17889 secure = zone->secure; 17890 TRYLOCK_ZONE(tresult, secure); 17891 if (tresult != ISC_R_SUCCESS) { 17892 UNLOCK_ZONE(zone); 17893 secure = NULL; 17894 isc_thread_yield(); 17895 goto again; 17896 } 17897 } 17898 (void)zone_postload(zone, load->db, load->loadtime, result); 17899 zonemgr_putio(&zone->readio); 17900 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING); 17901 zone_idetach(&load->callbacks.zone); 17902 /* 17903 * Leave the zone frozen if the reload fails. 17904 */ 17905 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) && 17906 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW)) 17907 { 17908 zone->update_disabled = false; 17909 } 17910 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW); 17911 if (inline_secure(zone)) { 17912 UNLOCK_ZONE(zone->raw); 17913 } else if (secure != NULL) { 17914 UNLOCK_ZONE(secure); 17915 } 17916 UNLOCK_ZONE(zone); 17917 17918 load->magic = 0; 17919 dns_db_detach(&load->db); 17920 if (load->zone->lctx != NULL) { 17921 dns_loadctx_detach(&load->zone->lctx); 17922 } 17923 dns_zone_idetach(&load->zone); 17924 isc_mem_putanddetach(&load->mctx, load, sizeof(*load)); 17925} 17926 17927void 17928dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) { 17929 REQUIRE(DNS_ZONE_VALID(zone)); 17930 REQUIRE(table != NULL); 17931 REQUIRE(*table == NULL); 17932 17933 LOCK_ZONE(zone); 17934 if (zone->ssutable != NULL) { 17935 dns_ssutable_attach(zone->ssutable, table); 17936 } 17937 UNLOCK_ZONE(zone); 17938} 17939 17940void 17941dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) { 17942 REQUIRE(DNS_ZONE_VALID(zone)); 17943 17944 LOCK_ZONE(zone); 17945 if (zone->ssutable != NULL) { 17946 dns_ssutable_detach(&zone->ssutable); 17947 } 17948 if (table != NULL) { 17949 dns_ssutable_attach(table, &zone->ssutable); 17950 } 17951 UNLOCK_ZONE(zone); 17952} 17953 17954void 17955dns_zone_setsigvalidityinterval(dns_zone_t *zone, uint32_t interval) { 17956 REQUIRE(DNS_ZONE_VALID(zone)); 17957 17958 zone->sigvalidityinterval = interval; 17959} 17960 17961uint32_t 17962dns_zone_getsigvalidityinterval(dns_zone_t *zone) { 17963 REQUIRE(DNS_ZONE_VALID(zone)); 17964 17965 return (zone->sigvalidityinterval); 17966} 17967 17968void 17969dns_zone_setkeyvalidityinterval(dns_zone_t *zone, uint32_t interval) { 17970 REQUIRE(DNS_ZONE_VALID(zone)); 17971 17972 zone->keyvalidityinterval = interval; 17973} 17974 17975uint32_t 17976dns_zone_getkeyvalidityinterval(dns_zone_t *zone) { 17977 REQUIRE(DNS_ZONE_VALID(zone)); 17978 17979 return (zone->keyvalidityinterval); 17980} 17981 17982void 17983dns_zone_setsigresigninginterval(dns_zone_t *zone, uint32_t interval) { 17984 isc_time_t now; 17985 17986 REQUIRE(DNS_ZONE_VALID(zone)); 17987 17988 LOCK_ZONE(zone); 17989 zone->sigresigninginterval = interval; 17990 set_resigntime(zone); 17991 if (zone->task != NULL) { 17992 TIME_NOW(&now); 17993 zone_settimer(zone, &now); 17994 } 17995 UNLOCK_ZONE(zone); 17996} 17997 17998uint32_t 17999dns_zone_getsigresigninginterval(dns_zone_t *zone) { 18000 REQUIRE(DNS_ZONE_VALID(zone)); 18001 18002 return (zone->sigresigninginterval); 18003} 18004 18005static void 18006queue_xfrin(dns_zone_t *zone) { 18007 const char me[] = "queue_xfrin"; 18008 isc_result_t result; 18009 dns_zonemgr_t *zmgr = zone->zmgr; 18010 18011 ENTER; 18012 18013 INSIST(zone->statelist == NULL); 18014 18015 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18016 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink); 18017 isc_refcount_increment0(&zone->irefs); 18018 zone->statelist = &zmgr->waiting_for_xfrin; 18019 result = zmgr_start_xfrin_ifquota(zmgr, zone); 18020 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18021 18022 if (result == ISC_R_QUOTA) { 18023 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 18024 "zone transfer deferred due to quota"); 18025 } else if (result != ISC_R_SUCCESS) { 18026 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, 18027 "starting zone transfer: %s", 18028 isc_result_totext(result)); 18029 } 18030} 18031 18032/* 18033 * This event callback is called when a zone has received 18034 * any necessary zone transfer quota. This is the time 18035 * to go ahead and start the transfer. 18036 */ 18037static void 18038got_transfer_quota(isc_task_t *task, isc_event_t *event) { 18039 isc_result_t result = ISC_R_SUCCESS; 18040 dns_peer_t *peer = NULL; 18041 char primary[ISC_SOCKADDR_FORMATSIZE]; 18042 char source[ISC_SOCKADDR_FORMATSIZE]; 18043 dns_rdatatype_t xfrtype; 18044 dns_zone_t *zone = event->ev_arg; 18045 isc_netaddr_t primaryip; 18046 isc_sockaddr_t sourceaddr; 18047 isc_sockaddr_t primaryaddr; 18048 isc_time_t now; 18049 const char *soa_before = ""; 18050 bool loaded; 18051 isc_tlsctx_cache_t *zmgr_tlsctx_cache = NULL; 18052 18053 UNUSED(task); 18054 18055 INSIST(task == zone->task); 18056 18057 isc_event_free(&event); 18058 18059 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 18060 zone_xfrdone(zone, ISC_R_CANCELED); 18061 return; 18062 } 18063 18064 TIME_NOW(&now); 18065 18066 isc_sockaddr_format(&zone->primaryaddr, primary, sizeof(primary)); 18067 if (dns_zonemgr_unreachable(zone->zmgr, &zone->primaryaddr, 18068 &zone->sourceaddr, &now)) 18069 { 18070 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 18071 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 18072 "got_transfer_quota: skipping zone transfer as " 18073 "primary %s (source %s) is unreachable (cached)", 18074 primary, source); 18075 zone_xfrdone(zone, ISC_R_CANCELED); 18076 return; 18077 } 18078 18079 isc_netaddr_fromsockaddr(&primaryip, &zone->primaryaddr); 18080 (void)dns_peerlist_peerbyaddr(zone->view->peers, &primaryip, &peer); 18081 18082 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) { 18083 soa_before = "SOA before "; 18084 } 18085 /* 18086 * Decide whether we should request IXFR or AXFR. 18087 */ 18088 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 18089 loaded = (zone->db != NULL); 18090 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 18091 18092 if (!loaded) { 18093 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 18094 "no database exists yet, requesting AXFR of " 18095 "initial version from %s", 18096 primary); 18097 xfrtype = dns_rdatatype_axfr; 18098 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { 18099 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 18100 "forced reload, requesting AXFR of " 18101 "initial version from %s", 18102 primary); 18103 xfrtype = dns_rdatatype_axfr; 18104 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOIXFR)) { 18105 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1), 18106 "retrying with AXFR from %s due to " 18107 "previous IXFR failure", 18108 primary); 18109 xfrtype = dns_rdatatype_axfr; 18110 LOCK_ZONE(zone); 18111 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOIXFR); 18112 UNLOCK_ZONE(zone); 18113 } else { 18114 bool use_ixfr = true; 18115 if (peer != NULL) { 18116 result = dns_peer_getrequestixfr(peer, &use_ixfr); 18117 } 18118 if (peer == NULL || result != ISC_R_SUCCESS) { 18119 use_ixfr = zone->requestixfr; 18120 } 18121 if (!use_ixfr) { 18122 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18123 ISC_LOG_DEBUG(1), 18124 "IXFR disabled, " 18125 "requesting %sAXFR from %s", 18126 soa_before, primary); 18127 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) { 18128 xfrtype = dns_rdatatype_soa; 18129 } else { 18130 xfrtype = dns_rdatatype_axfr; 18131 } 18132 } else { 18133 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18134 ISC_LOG_DEBUG(1), 18135 "requesting IXFR from %s", primary); 18136 xfrtype = dns_rdatatype_ixfr; 18137 } 18138 } 18139 18140 /* 18141 * Determine if we should attempt to sign the request with TSIG. 18142 */ 18143 result = ISC_R_NOTFOUND; 18144 18145 /* 18146 * First, look for a tsig key in the primaries statement, then 18147 * try for a server key. 18148 */ 18149 if ((zone->primarykeynames != NULL) && 18150 (zone->primarykeynames[zone->curprimary] != NULL)) 18151 { 18152 dns_view_t *view = dns_zone_getview(zone); 18153 dns_name_t *keyname = zone->primarykeynames[zone->curprimary]; 18154 result = dns_view_gettsig(view, keyname, &zone->tsigkey); 18155 } 18156 if (result != ISC_R_SUCCESS) { 18157 INSIST(zone->tsigkey == NULL); 18158 result = dns_view_getpeertsig(zone->view, &primaryip, 18159 &zone->tsigkey); 18160 } 18161 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 18162 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, 18163 "could not get TSIG key for zone transfer: %s", 18164 isc_result_totext(result)); 18165 } 18166 18167 /* 18168 * Get the TLS transport for the primary, if configured. 18169 */ 18170 if ((zone->primarytlsnames != NULL) && 18171 (zone->primarytlsnames[zone->curprimary] != NULL)) 18172 { 18173 dns_view_t *view = dns_zone_getview(zone); 18174 dns_name_t *tlsname = zone->primarytlsnames[zone->curprimary]; 18175 result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname, 18176 &zone->transport); 18177 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 18178 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 18179 ISC_LOG_ERROR, 18180 "could not get TLS configuration for " 18181 "zone transfer: %s", 18182 isc_result_totext(result)); 18183 } 18184 } 18185 18186 LOCK_ZONE(zone); 18187 primaryaddr = zone->primaryaddr; 18188 sourceaddr = zone->sourceaddr; 18189 UNLOCK_ZONE(zone); 18190 INSIST(isc_sockaddr_pf(&primaryaddr) == isc_sockaddr_pf(&sourceaddr)); 18191 18192 if (zone->xfr != NULL) { 18193 dns_xfrin_detach(&zone->xfr); 18194 } 18195 18196 zmgr_tlsctx_attach(zone->zmgr, &zmgr_tlsctx_cache); 18197 18198 result = dns_xfrin_create(zone, xfrtype, &primaryaddr, &sourceaddr, 18199 zone->tsigkey, zone->transport, 18200 zmgr_tlsctx_cache, zone->mctx, 18201 zone->zmgr->netmgr, zone_xfrdone, &zone->xfr); 18202 18203 isc_tlsctx_cache_detach(&zmgr_tlsctx_cache); 18204 18205 /* 18206 * Any failure in this function is handled like a failed 18207 * zone transfer. This ensures that we get removed from 18208 * zmgr->xfrin_in_progress. 18209 */ 18210 if (result != ISC_R_SUCCESS) { 18211 zone_xfrdone(zone, result); 18212 return; 18213 } 18214 18215 LOCK_ZONE(zone); 18216 if (xfrtype == dns_rdatatype_axfr) { 18217 if (isc_sockaddr_pf(&primaryaddr) == PF_INET) { 18218 inc_stats(zone, dns_zonestatscounter_axfrreqv4); 18219 } else { 18220 inc_stats(zone, dns_zonestatscounter_axfrreqv6); 18221 } 18222 } else if (xfrtype == dns_rdatatype_ixfr) { 18223 if (isc_sockaddr_pf(&primaryaddr) == PF_INET) { 18224 inc_stats(zone, dns_zonestatscounter_ixfrreqv4); 18225 } else { 18226 inc_stats(zone, dns_zonestatscounter_ixfrreqv6); 18227 } 18228 } 18229 UNLOCK_ZONE(zone); 18230} 18231 18232/* 18233 * Update forwarding support. 18234 */ 18235 18236static void 18237forward_destroy(dns_forward_t *forward) { 18238 forward->magic = 0; 18239 if (forward->request != NULL) { 18240 dns_request_destroy(&forward->request); 18241 } 18242 if (forward->msgbuf != NULL) { 18243 isc_buffer_free(&forward->msgbuf); 18244 } 18245 if (forward->zone != NULL) { 18246 LOCK(&forward->zone->lock); 18247 if (ISC_LINK_LINKED(forward, link)) { 18248 ISC_LIST_UNLINK(forward->zone->forwards, forward, link); 18249 } 18250 UNLOCK(&forward->zone->lock); 18251 dns_zone_idetach(&forward->zone); 18252 } 18253 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward)); 18254} 18255 18256static isc_result_t 18257sendtoprimary(dns_forward_t *forward) { 18258 isc_result_t result; 18259 isc_sockaddr_t src; 18260 18261 LOCK_ZONE(forward->zone); 18262 18263 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) { 18264 UNLOCK_ZONE(forward->zone); 18265 return (ISC_R_CANCELED); 18266 } 18267 18268 if (forward->which >= forward->zone->primariescnt) { 18269 UNLOCK_ZONE(forward->zone); 18270 return (ISC_R_NOMORE); 18271 } 18272 18273 forward->addr = forward->zone->primaries[forward->which]; 18274 /* 18275 * Always use TCP regardless of whether the original update 18276 * used TCP. 18277 * XXX The timeout may but a bit small if we are far down a 18278 * transfer graph and have to try several primaries. 18279 */ 18280 switch (isc_sockaddr_pf(&forward->addr)) { 18281 case PF_INET: 18282 src = forward->zone->xfrsource4; 18283 break; 18284 case PF_INET6: 18285 src = forward->zone->xfrsource6; 18286 break; 18287 default: 18288 result = ISC_R_NOTIMPLEMENTED; 18289 goto unlock; 18290 } 18291 result = dns_request_createraw(forward->zone->view->requestmgr, 18292 forward->msgbuf, &src, &forward->addr, 18293 forward->options, 15 /* XXX */, 0, 0, 18294 forward->zone->task, forward_callback, 18295 forward, &forward->request); 18296 if (result == ISC_R_SUCCESS) { 18297 if (!ISC_LINK_LINKED(forward, link)) { 18298 ISC_LIST_APPEND(forward->zone->forwards, forward, link); 18299 } 18300 } 18301 18302unlock: 18303 UNLOCK_ZONE(forward->zone); 18304 return (result); 18305} 18306 18307static void 18308forward_callback(isc_task_t *task, isc_event_t *event) { 18309 const char me[] = "forward_callback"; 18310 dns_requestevent_t *revent = (dns_requestevent_t *)event; 18311 dns_message_t *msg = NULL; 18312 char primary[ISC_SOCKADDR_FORMATSIZE]; 18313 isc_result_t result; 18314 dns_forward_t *forward; 18315 dns_zone_t *zone; 18316 18317 UNUSED(task); 18318 18319 forward = revent->ev_arg; 18320 INSIST(DNS_FORWARD_VALID(forward)); 18321 zone = forward->zone; 18322 INSIST(DNS_ZONE_VALID(zone)); 18323 18324 ENTER; 18325 18326 isc_sockaddr_format(&forward->addr, primary, sizeof(primary)); 18327 18328 if (revent->result != ISC_R_SUCCESS) { 18329 dns_zone_log(zone, ISC_LOG_INFO, 18330 "could not forward dynamic update to %s: %s", 18331 primary, isc_result_totext(revent->result)); 18332 goto next_primary; 18333 } 18334 18335 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 18336 18337 result = dns_request_getresponse(revent->request, msg, 18338 DNS_MESSAGEPARSE_PRESERVEORDER | 18339 DNS_MESSAGEPARSE_CLONEBUFFER); 18340 if (result != ISC_R_SUCCESS) { 18341 goto next_primary; 18342 } 18343 18344 /* 18345 * Unexpected opcode. 18346 */ 18347 if (msg->opcode != dns_opcode_update) { 18348 char opcode[128]; 18349 isc_buffer_t rb; 18350 18351 isc_buffer_init(&rb, opcode, sizeof(opcode)); 18352 (void)dns_opcode_totext(msg->opcode, &rb); 18353 18354 dns_zone_log(zone, ISC_LOG_INFO, 18355 "forwarding dynamic update: " 18356 "unexpected opcode (%.*s) from %s", 18357 (int)rb.used, opcode, primary); 18358 goto next_primary; 18359 } 18360 18361 switch (msg->rcode) { 18362 /* 18363 * Pass these rcodes back to client. 18364 */ 18365 case dns_rcode_noerror: 18366 case dns_rcode_yxdomain: 18367 case dns_rcode_yxrrset: 18368 case dns_rcode_nxrrset: 18369 case dns_rcode_refused: 18370 case dns_rcode_nxdomain: { 18371 char rcode[128]; 18372 isc_buffer_t rb; 18373 18374 isc_buffer_init(&rb, rcode, sizeof(rcode)); 18375 (void)dns_rcode_totext(msg->rcode, &rb); 18376 dns_zone_log(zone, ISC_LOG_INFO, 18377 "forwarded dynamic update: " 18378 "primary %s returned: %.*s", 18379 primary, (int)rb.used, rcode); 18380 break; 18381 } 18382 18383 /* These should not occur if the primaries/zone are valid. */ 18384 case dns_rcode_notzone: 18385 case dns_rcode_notauth: { 18386 char rcode[128]; 18387 isc_buffer_t rb; 18388 18389 isc_buffer_init(&rb, rcode, sizeof(rcode)); 18390 (void)dns_rcode_totext(msg->rcode, &rb); 18391 dns_zone_log(zone, ISC_LOG_WARNING, 18392 "forwarding dynamic update: " 18393 "unexpected response: primary %s returned: %.*s", 18394 primary, (int)rb.used, rcode); 18395 goto next_primary; 18396 } 18397 18398 /* Try another server for these rcodes. */ 18399 case dns_rcode_formerr: 18400 case dns_rcode_servfail: 18401 case dns_rcode_notimp: 18402 case dns_rcode_badvers: 18403 default: 18404 goto next_primary; 18405 } 18406 18407 /* call callback */ 18408 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg); 18409 msg = NULL; 18410 dns_request_destroy(&forward->request); 18411 forward_destroy(forward); 18412 isc_event_free(&event); 18413 return; 18414 18415next_primary: 18416 if (msg != NULL) { 18417 dns_message_detach(&msg); 18418 } 18419 isc_event_free(&event); 18420 forward->which++; 18421 dns_request_destroy(&forward->request); 18422 result = sendtoprimary(forward); 18423 if (result != ISC_R_SUCCESS) { 18424 /* call callback */ 18425 dns_zone_log(zone, ISC_LOG_DEBUG(3), 18426 "exhausted dynamic update forwarder list"); 18427 (forward->callback)(forward->callback_arg, result, NULL); 18428 forward_destroy(forward); 18429 } 18430} 18431 18432isc_result_t 18433dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg, 18434 dns_updatecallback_t callback, void *callback_arg) { 18435 dns_forward_t *forward; 18436 isc_result_t result; 18437 isc_region_t *mr; 18438 18439 REQUIRE(DNS_ZONE_VALID(zone)); 18440 REQUIRE(msg != NULL); 18441 REQUIRE(callback != NULL); 18442 18443 forward = isc_mem_get(zone->mctx, sizeof(*forward)); 18444 18445 forward->request = NULL; 18446 forward->zone = NULL; 18447 forward->msgbuf = NULL; 18448 forward->which = 0; 18449 forward->mctx = 0; 18450 forward->callback = callback; 18451 forward->callback_arg = callback_arg; 18452 ISC_LINK_INIT(forward, link); 18453 forward->magic = FORWARD_MAGIC; 18454 forward->options = DNS_REQUESTOPT_TCP; 18455 /* 18456 * If we have a SIG(0) signed message we need to preserve the 18457 * query id as that is included in the SIG(0) computation. 18458 */ 18459 if (msg->sig0 != NULL) { 18460 forward->options |= DNS_REQUESTOPT_FIXEDID; 18461 } 18462 18463 mr = dns_message_getrawmessage(msg); 18464 if (mr == NULL) { 18465 result = ISC_R_UNEXPECTEDEND; 18466 goto cleanup; 18467 } 18468 18469 isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length); 18470 result = isc_buffer_copyregion(forward->msgbuf, mr); 18471 if (result != ISC_R_SUCCESS) { 18472 goto cleanup; 18473 } 18474 18475 isc_mem_attach(zone->mctx, &forward->mctx); 18476 dns_zone_iattach(zone, &forward->zone); 18477 result = sendtoprimary(forward); 18478 18479cleanup: 18480 if (result != ISC_R_SUCCESS) { 18481 forward_destroy(forward); 18482 } 18483 return (result); 18484} 18485 18486isc_result_t 18487dns_zone_next(dns_zone_t *zone, dns_zone_t **next) { 18488 REQUIRE(DNS_ZONE_VALID(zone)); 18489 REQUIRE(next != NULL && *next == NULL); 18490 18491 *next = ISC_LIST_NEXT(zone, link); 18492 if (*next == NULL) { 18493 return (ISC_R_NOMORE); 18494 } else { 18495 return (ISC_R_SUCCESS); 18496 } 18497} 18498 18499isc_result_t 18500dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) { 18501 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 18502 REQUIRE(first != NULL && *first == NULL); 18503 18504 *first = ISC_LIST_HEAD(zmgr->zones); 18505 if (*first == NULL) { 18506 return (ISC_R_NOMORE); 18507 } else { 18508 return (ISC_R_SUCCESS); 18509 } 18510} 18511 18512/*** 18513 *** Zone manager. 18514 ***/ 18515 18516#define KEYMGMT_OVERCOMMIT 3 18517#define KEYMGMT_BITS_MIN 2U 18518#define KEYMGMT_BITS_MAX 32U 18519 18520/* 18521 * WMM: Static hash functions copied from lib/dns/rbtdb.c. Should be moved to 18522 * lib/isc/hash.c when we refactor the hash table code. 18523 */ 18524#define GOLDEN_RATIO_32 0x61C88647 18525#define HASHSIZE(bits) (UINT64_C(1) << (bits)) 18526 18527static uint32_t 18528hash_index(uint32_t val, uint32_t bits) { 18529 return (val * GOLDEN_RATIO_32 >> (32 - bits)); 18530} 18531 18532static uint32_t 18533hash_bits_grow(uint32_t bits, uint32_t count) { 18534 uint32_t newbits = bits; 18535 while (count >= HASHSIZE(newbits) && newbits < KEYMGMT_BITS_MAX) { 18536 newbits++; 18537 } 18538 return (newbits); 18539} 18540 18541static uint32_t 18542hash_bits_shrink(uint32_t bits, uint32_t count) { 18543 uint32_t newbits = bits; 18544 while (count <= HASHSIZE(newbits) && newbits > KEYMGMT_BITS_MIN) { 18545 newbits--; 18546 } 18547 return (newbits); 18548} 18549 18550static void 18551zonemgr_keymgmt_init(dns_zonemgr_t *zmgr) { 18552 dns_keymgmt_t *mgmt = isc_mem_get(zmgr->mctx, sizeof(*mgmt)); 18553 uint32_t size; 18554 18555 *mgmt = (dns_keymgmt_t){ 18556 .bits = KEYMGMT_BITS_MIN, 18557 }; 18558 isc_mem_attach(zmgr->mctx, &mgmt->mctx); 18559 isc_rwlock_init(&mgmt->lock, 0, 0); 18560 18561 size = HASHSIZE(mgmt->bits); 18562 mgmt->table = isc_mem_get(mgmt->mctx, sizeof(*mgmt->table) * size); 18563 memset(mgmt->table, 0, size * sizeof(mgmt->table[0])); 18564 18565 atomic_init(&mgmt->count, 0); 18566 mgmt->magic = KEYMGMT_MAGIC; 18567 18568 zmgr->keymgmt = mgmt; 18569} 18570 18571static void 18572zonemgr_keymgmt_destroy(dns_zonemgr_t *zmgr) { 18573 dns_keymgmt_t *mgmt = zmgr->keymgmt; 18574 uint32_t size; 18575 18576 REQUIRE(DNS_KEYMGMT_VALID(mgmt)); 18577 18578 size = HASHSIZE(mgmt->bits); 18579 18580 RWLOCK(&mgmt->lock, isc_rwlocktype_write); 18581 INSIST(mgmt->count == 0); 18582 RWUNLOCK(&mgmt->lock, isc_rwlocktype_write); 18583 18584 mgmt->magic = 0; 18585 isc_rwlock_destroy(&mgmt->lock); 18586 isc_mem_put(mgmt->mctx, mgmt->table, size * sizeof(mgmt->table[0])); 18587 isc_mem_putanddetach(&mgmt->mctx, mgmt, sizeof(dns_keymgmt_t)); 18588} 18589 18590static void 18591zonemgr_keymgmt_resize(dns_zonemgr_t *zmgr) { 18592 dns_keyfileio_t **newtable; 18593 dns_keymgmt_t *mgmt = zmgr->keymgmt; 18594 uint32_t bits, newbits, count, size, newsize; 18595 bool grow; 18596 18597 REQUIRE(DNS_KEYMGMT_VALID(mgmt)); 18598 18599 RWLOCK(&mgmt->lock, isc_rwlocktype_read); 18600 count = atomic_load_relaxed(&mgmt->count); 18601 bits = mgmt->bits; 18602 RWUNLOCK(&mgmt->lock, isc_rwlocktype_read); 18603 18604 size = HASHSIZE(bits); 18605 INSIST(size > 0); 18606 18607 if (count >= (size * KEYMGMT_OVERCOMMIT)) { 18608 grow = true; 18609 } else if (count < (size / 2)) { 18610 grow = false; 18611 } else { 18612 /* No need to resize. */ 18613 return; 18614 } 18615 18616 if (grow) { 18617 newbits = hash_bits_grow(bits, count); 18618 } else { 18619 newbits = hash_bits_shrink(bits, count); 18620 } 18621 18622 if (newbits == bits) { 18623 /* 18624 * Bit values may stay the same if maximum or minimum is 18625 * reached. 18626 */ 18627 return; 18628 } 18629 18630 newsize = HASHSIZE(newbits); 18631 INSIST(newsize > 0); 18632 18633 RWLOCK(&mgmt->lock, isc_rwlocktype_write); 18634 18635 newtable = isc_mem_get(mgmt->mctx, sizeof(dns_keyfileio_t *) * newsize); 18636 memset(newtable, 0, sizeof(dns_keyfileio_t *) * newsize); 18637 18638 for (unsigned int i = 0; i < size; i++) { 18639 dns_keyfileio_t *kfio, *next; 18640 for (kfio = mgmt->table[i]; kfio != NULL; kfio = next) { 18641 uint32_t hash = hash_index(kfio->hashval, newbits); 18642 next = kfio->next; 18643 kfio->next = newtable[hash]; 18644 newtable[hash] = kfio; 18645 } 18646 mgmt->table[i] = NULL; 18647 } 18648 18649 isc_mem_put(mgmt->mctx, mgmt->table, sizeof(*mgmt->table) * size); 18650 mgmt->bits = newbits; 18651 mgmt->table = newtable; 18652 18653 RWUNLOCK(&mgmt->lock, isc_rwlocktype_write); 18654} 18655 18656static void 18657zonemgr_keymgmt_add(dns_zonemgr_t *zmgr, dns_zone_t *zone, 18658 dns_keyfileio_t **added) { 18659 dns_keymgmt_t *mgmt = zmgr->keymgmt; 18660 uint32_t hashval, hash; 18661 dns_keyfileio_t *kfio, *next; 18662 18663 REQUIRE(DNS_KEYMGMT_VALID(mgmt)); 18664 REQUIRE(added != NULL && *added == NULL); 18665 18666 RWLOCK(&mgmt->lock, isc_rwlocktype_write); 18667 18668 hashval = dns_name_hash(&zone->origin, false); 18669 hash = hash_index(hashval, mgmt->bits); 18670 18671 for (kfio = mgmt->table[hash]; kfio != NULL; kfio = next) { 18672 next = kfio->next; 18673 if (dns_name_equal(kfio->name, &zone->origin)) { 18674 /* Already in table, increment the counter. */ 18675 isc_refcount_increment(&kfio->references); 18676 break; 18677 } 18678 } 18679 18680 if (kfio == NULL) { 18681 /* No entry found, add it. */ 18682 kfio = isc_mem_get(mgmt->mctx, sizeof(*kfio)); 18683 *kfio = (dns_keyfileio_t){ 18684 .hashval = hashval, 18685 .next = mgmt->table[hash], 18686 .magic = KEYFILEIO_MAGIC, 18687 }; 18688 18689 isc_refcount_init(&kfio->references, 1); 18690 18691 kfio->name = dns_fixedname_initname(&kfio->fname); 18692 dns_name_copy(&zone->origin, kfio->name); 18693 18694 isc_mutex_init(&kfio->lock); 18695 18696 mgmt->table[hash] = kfio; 18697 18698 atomic_fetch_add_relaxed(&mgmt->count, 1); 18699 } 18700 18701 RWUNLOCK(&mgmt->lock, isc_rwlocktype_write); 18702 18703 *added = kfio; 18704 18705 /* 18706 * Call resize, that function will also check if resize is necessary. 18707 */ 18708 zonemgr_keymgmt_resize(zmgr); 18709} 18710 18711static void 18712zonemgr_keymgmt_delete(dns_zonemgr_t *zmgr, dns_zone_t *zone, 18713 dns_keyfileio_t **deleted) { 18714 dns_keymgmt_t *mgmt = zmgr->keymgmt; 18715 uint32_t hashval, hash; 18716 dns_keyfileio_t *kfio, *prev, *next; 18717 18718 REQUIRE(DNS_KEYMGMT_VALID(mgmt)); 18719 REQUIRE(deleted != NULL && DNS_KEYFILEIO_VALID(*deleted)); 18720 18721 RWLOCK(&mgmt->lock, isc_rwlocktype_write); 18722 18723 hashval = dns_name_hash(&zone->origin, false); 18724 hash = hash_index(hashval, mgmt->bits); 18725 18726 prev = NULL; 18727 for (kfio = mgmt->table[hash]; kfio != NULL; kfio = next) { 18728 next = kfio->next; 18729 if (dns_name_equal(kfio->name, &zone->origin)) { 18730 INSIST(kfio == *deleted); 18731 *deleted = NULL; 18732 18733 if (isc_refcount_decrement(&kfio->references) == 1) { 18734 if (prev == NULL) { 18735 mgmt->table[hash] = kfio->next; 18736 } else { 18737 prev->next = kfio->next; 18738 } 18739 18740 isc_refcount_destroy(&kfio->references); 18741 isc_mutex_destroy(&kfio->lock); 18742 isc_mem_put(mgmt->mctx, kfio, sizeof(*kfio)); 18743 18744 atomic_fetch_sub_relaxed(&mgmt->count, 1); 18745 } 18746 break; 18747 } 18748 18749 prev = kfio; 18750 } 18751 18752 RWUNLOCK(&mgmt->lock, isc_rwlocktype_write); 18753 18754 /* 18755 * Call resize, that function will also check if resize is necessary. 18756 */ 18757 zonemgr_keymgmt_resize(zmgr); 18758} 18759 18760isc_result_t 18761dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, 18762 isc_timermgr_t *timermgr, isc_nm_t *netmgr, 18763 dns_zonemgr_t **zmgrp) { 18764 dns_zonemgr_t *zmgr; 18765 isc_result_t result; 18766 18767 zmgr = isc_mem_get(mctx, sizeof(*zmgr)); 18768 zmgr->mctx = NULL; 18769 isc_refcount_init(&zmgr->refs, 1); 18770 isc_mem_attach(mctx, &zmgr->mctx); 18771 zmgr->taskmgr = taskmgr; 18772 zmgr->timermgr = timermgr; 18773 zmgr->netmgr = netmgr; 18774 zmgr->zonetasks = NULL; 18775 zmgr->loadtasks = NULL; 18776 zmgr->mctxpool = NULL; 18777 zmgr->task = NULL; 18778 zmgr->checkdsrl = NULL; 18779 zmgr->notifyrl = NULL; 18780 zmgr->refreshrl = NULL; 18781 zmgr->startupnotifyrl = NULL; 18782 zmgr->startuprefreshrl = NULL; 18783 ISC_LIST_INIT(zmgr->zones); 18784 ISC_LIST_INIT(zmgr->waiting_for_xfrin); 18785 ISC_LIST_INIT(zmgr->xfrin_in_progress); 18786 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable)); 18787 for (size_t i = 0; i < UNREACH_CACHE_SIZE; i++) { 18788 atomic_init(&zmgr->unreachable[i].expire, 0); 18789 } 18790 isc_rwlock_init(&zmgr->rwlock, 0, 0); 18791 18792 zmgr->transfersin = 10; 18793 zmgr->transfersperns = 2; 18794 18795 /* Unreachable lock. */ 18796 isc_rwlock_init(&zmgr->urlock, 0, 0); 18797 18798 /* Create a single task for queueing of SOA queries. */ 18799 result = isc_task_create(taskmgr, 1, &zmgr->task); 18800 if (result != ISC_R_SUCCESS) { 18801 goto free_urlock; 18802 } 18803 18804 isc_task_setname(zmgr->task, "zmgr", zmgr); 18805 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 18806 &zmgr->checkdsrl); 18807 if (result != ISC_R_SUCCESS) { 18808 goto free_task; 18809 } 18810 18811 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 18812 &zmgr->notifyrl); 18813 if (result != ISC_R_SUCCESS) { 18814 goto free_checkdsrl; 18815 } 18816 18817 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 18818 &zmgr->refreshrl); 18819 if (result != ISC_R_SUCCESS) { 18820 goto free_notifyrl; 18821 } 18822 18823 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 18824 &zmgr->startupnotifyrl); 18825 if (result != ISC_R_SUCCESS) { 18826 goto free_refreshrl; 18827 } 18828 18829 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 18830 &zmgr->startuprefreshrl); 18831 if (result != ISC_R_SUCCESS) { 18832 goto free_startupnotifyrl; 18833 } 18834 18835 /* Key file I/O locks. */ 18836 zonemgr_keymgmt_init(zmgr); 18837 18838 /* Default to 20 refresh queries / notifies / checkds per second. */ 18839 setrl(zmgr->checkdsrl, &zmgr->checkdsrate, 20); 18840 setrl(zmgr->notifyrl, &zmgr->notifyrate, 20); 18841 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20); 18842 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20); 18843 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20); 18844 isc_ratelimiter_setpushpop(zmgr->startupnotifyrl, true); 18845 isc_ratelimiter_setpushpop(zmgr->startuprefreshrl, true); 18846 18847 zmgr->iolimit = 1; 18848 zmgr->ioactive = 0; 18849 ISC_LIST_INIT(zmgr->high); 18850 ISC_LIST_INIT(zmgr->low); 18851 18852 isc_mutex_init(&zmgr->iolock); 18853 18854 zmgr->tlsctx_cache = NULL; 18855 isc_rwlock_init(&zmgr->tlsctx_cache_rwlock, 0, 0); 18856 18857 zmgr->magic = ZONEMGR_MAGIC; 18858 18859 *zmgrp = zmgr; 18860 return (ISC_R_SUCCESS); 18861 18862#if 0 18863 free_iolock: 18864 isc_mutex_destroy(&zmgr->iolock); 18865#endif /* if 0 */ 18866free_startupnotifyrl: 18867 isc_ratelimiter_detach(&zmgr->startupnotifyrl); 18868free_refreshrl: 18869 isc_ratelimiter_detach(&zmgr->refreshrl); 18870free_notifyrl: 18871 isc_ratelimiter_detach(&zmgr->notifyrl); 18872free_checkdsrl: 18873 isc_ratelimiter_detach(&zmgr->checkdsrl); 18874free_task: 18875 isc_task_detach(&zmgr->task); 18876free_urlock: 18877 isc_rwlock_destroy(&zmgr->urlock); 18878 isc_rwlock_destroy(&zmgr->rwlock); 18879 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); 18880 isc_mem_detach(&mctx); 18881 return (result); 18882} 18883 18884isc_result_t 18885dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) { 18886 isc_result_t result; 18887 isc_mem_t *mctx = NULL; 18888 dns_zone_t *zone = NULL; 18889 void *item; 18890 18891 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 18892 REQUIRE(zonep != NULL && *zonep == NULL); 18893 18894 if (zmgr->mctxpool == NULL) { 18895 return (ISC_R_FAILURE); 18896 } 18897 18898 item = isc_pool_get(zmgr->mctxpool); 18899 if (item == NULL) { 18900 return (ISC_R_FAILURE); 18901 } 18902 18903 isc_mem_attach((isc_mem_t *)item, &mctx); 18904 result = dns_zone_create(&zone, mctx); 18905 isc_mem_detach(&mctx); 18906 18907 if (result == ISC_R_SUCCESS) { 18908 *zonep = zone; 18909 } 18910 18911 return (result); 18912} 18913 18914isc_result_t 18915dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 18916 isc_result_t result; 18917 18918 REQUIRE(DNS_ZONE_VALID(zone)); 18919 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 18920 18921 if (zmgr->zonetasks == NULL) { 18922 return (ISC_R_FAILURE); 18923 } 18924 18925 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18926 LOCK_ZONE(zone); 18927 REQUIRE(zone->task == NULL); 18928 REQUIRE(zone->timer == NULL); 18929 REQUIRE(zone->zmgr == NULL); 18930 18931 isc_taskpool_gettask(zmgr->zonetasks, &zone->task); 18932 isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask); 18933 18934 /* 18935 * Set the task name. The tag will arbitrarily point to one 18936 * of the zones sharing the task (in practice, the one 18937 * to be managed last). 18938 */ 18939 isc_task_setname(zone->task, "zone", zone); 18940 isc_task_setname(zone->loadtask, "loadzone", zone); 18941 18942 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL, 18943 NULL, zone->task, zone_timer, zone, 18944 &zone->timer); 18945 18946 if (result != ISC_R_SUCCESS) { 18947 goto cleanup_tasks; 18948 } 18949 18950 /* 18951 * The timer "holds" a iref. 18952 */ 18953 isc_refcount_increment0(&zone->irefs); 18954 18955 zonemgr_keymgmt_add(zmgr, zone, &zone->kfio); 18956 INSIST(zone->kfio != NULL); 18957 18958 ISC_LIST_APPEND(zmgr->zones, zone, link); 18959 zone->zmgr = zmgr; 18960 isc_refcount_increment(&zmgr->refs); 18961 18962 goto unlock; 18963 18964cleanup_tasks: 18965 isc_task_detach(&zone->loadtask); 18966 isc_task_detach(&zone->task); 18967 18968unlock: 18969 UNLOCK_ZONE(zone); 18970 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18971 return (result); 18972} 18973 18974void 18975dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 18976 REQUIRE(DNS_ZONE_VALID(zone)); 18977 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 18978 REQUIRE(zone->zmgr == zmgr); 18979 18980 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18981 LOCK_ZONE(zone); 18982 18983 ISC_LIST_UNLINK(zmgr->zones, zone, link); 18984 18985 if (zone->kfio != NULL) { 18986 zonemgr_keymgmt_delete(zmgr, zone, &zone->kfio); 18987 ENSURE(zone->kfio == NULL); 18988 } 18989 18990 /* Detach below, outside of the write lock. */ 18991 zone->zmgr = NULL; 18992 18993 UNLOCK_ZONE(zone); 18994 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 18995 18996 dns_zonemgr_detach(&zmgr); 18997} 18998 18999void 19000dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) { 19001 REQUIRE(DNS_ZONEMGR_VALID(source)); 19002 REQUIRE(target != NULL && *target == NULL); 19003 19004 isc_refcount_increment(&source->refs); 19005 19006 *target = source; 19007} 19008 19009void 19010dns_zonemgr_detach(dns_zonemgr_t **zmgrp) { 19011 dns_zonemgr_t *zmgr; 19012 19013 REQUIRE(zmgrp != NULL); 19014 zmgr = *zmgrp; 19015 *zmgrp = NULL; 19016 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19017 19018 if (isc_refcount_decrement(&zmgr->refs) == 1) { 19019 zonemgr_free(zmgr); 19020 } 19021} 19022 19023isc_result_t 19024dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) { 19025 dns_zone_t *p; 19026 19027 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19028 19029 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19030 for (p = ISC_LIST_HEAD(zmgr->zones); p != NULL; 19031 p = ISC_LIST_NEXT(p, link)) 19032 { 19033 dns_zone_maintenance(p); 19034 } 19035 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19036 19037 /* 19038 * Recent configuration changes may have increased the 19039 * amount of available transfers quota. Make sure any 19040 * transfers currently blocked on quota get started if 19041 * possible. 19042 */ 19043 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19044 zmgr_resume_xfrs(zmgr, true); 19045 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19046 return (ISC_R_SUCCESS); 19047} 19048 19049void 19050dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) { 19051 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19052 19053 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19054 zmgr_resume_xfrs(zmgr, true); 19055 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 19056} 19057 19058void 19059dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) { 19060 dns_zone_t *zone; 19061 19062 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19063 19064 isc_ratelimiter_shutdown(zmgr->checkdsrl); 19065 isc_ratelimiter_shutdown(zmgr->notifyrl); 19066 isc_ratelimiter_shutdown(zmgr->refreshrl); 19067 isc_ratelimiter_shutdown(zmgr->startupnotifyrl); 19068 isc_ratelimiter_shutdown(zmgr->startuprefreshrl); 19069 19070 if (zmgr->task != NULL) { 19071 isc_task_destroy(&zmgr->task); 19072 } 19073 if (zmgr->zonetasks != NULL) { 19074 isc_taskpool_destroy(&zmgr->zonetasks); 19075 } 19076 if (zmgr->loadtasks != NULL) { 19077 isc_taskpool_destroy(&zmgr->loadtasks); 19078 } 19079 if (zmgr->mctxpool != NULL) { 19080 isc_pool_destroy(&zmgr->mctxpool); 19081 } 19082 19083 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19084 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 19085 zone = ISC_LIST_NEXT(zone, link)) 19086 { 19087 LOCK_ZONE(zone); 19088 forward_cancel(zone); 19089 UNLOCK_ZONE(zone); 19090 } 19091 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19092} 19093 19094static isc_result_t 19095mctxinit(void **target, void *arg) { 19096 isc_mem_t *mctx = NULL; 19097 19098 UNUSED(arg); 19099 19100 REQUIRE(target != NULL && *target == NULL); 19101 19102 isc_mem_create(&mctx); 19103 isc_mem_setname(mctx, "zonemgr-pool"); 19104 19105 *target = mctx; 19106 return (ISC_R_SUCCESS); 19107} 19108 19109static void 19110mctxfree(void **target) { 19111 isc_mem_t *mctx = *(isc_mem_t **)target; 19112 isc_mem_detach(&mctx); 19113 *target = NULL; 19114} 19115 19116#define ZONES_PER_TASK 100 19117#define ZONES_PER_MCTX 1000 19118 19119isc_result_t 19120dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) { 19121 isc_result_t result; 19122 int ntasks = num_zones / ZONES_PER_TASK; 19123 int nmctx = num_zones / ZONES_PER_MCTX; 19124 isc_taskpool_t *pool = NULL; 19125 isc_pool_t *mctxpool = NULL; 19126 19127 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19128 19129 /* 19130 * For anything fewer than 1000 zones we use 10 tasks in 19131 * the task pools. More than that, and we'll scale at one 19132 * task per 100 zones. Similarly, for anything smaller than 19133 * 2000 zones we use 2 memory contexts, then scale at 1:1000. 19134 */ 19135 if (ntasks < 10) { 19136 ntasks = 10; 19137 } 19138 if (nmctx < 2) { 19139 nmctx = 2; 19140 } 19141 19142 /* Create or resize the zone task pools. */ 19143 if (zmgr->zonetasks == NULL) { 19144 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks, 19145 2, false, &pool); 19146 } else { 19147 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, false, 19148 &pool); 19149 } 19150 19151 if (result == ISC_R_SUCCESS) { 19152 zmgr->zonetasks = pool; 19153 } 19154 19155 /* 19156 * We always set all tasks in the zone-load task pool to 19157 * privileged. This prevents other tasks in the system from 19158 * running while the server task manager is in privileged 19159 * mode. 19160 */ 19161 pool = NULL; 19162 if (zmgr->loadtasks == NULL) { 19163 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks, 19164 UINT_MAX, true, &pool); 19165 } else { 19166 result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, true, 19167 &pool); 19168 } 19169 19170 if (result == ISC_R_SUCCESS) { 19171 zmgr->loadtasks = pool; 19172 } 19173 19174 /* Create or resize the zone memory context pool. */ 19175 if (zmgr->mctxpool == NULL) { 19176 result = isc_pool_create(zmgr->mctx, nmctx, mctxfree, mctxinit, 19177 NULL, &mctxpool); 19178 } else { 19179 result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool); 19180 } 19181 19182 if (result == ISC_R_SUCCESS) { 19183 zmgr->mctxpool = mctxpool; 19184 } 19185 19186 return (result); 19187} 19188 19189static void 19190zonemgr_free(dns_zonemgr_t *zmgr) { 19191 isc_mem_t *mctx; 19192 19193 INSIST(ISC_LIST_EMPTY(zmgr->zones)); 19194 19195 zmgr->magic = 0; 19196 19197 isc_refcount_destroy(&zmgr->refs); 19198 isc_mutex_destroy(&zmgr->iolock); 19199 isc_ratelimiter_detach(&zmgr->checkdsrl); 19200 isc_ratelimiter_detach(&zmgr->notifyrl); 19201 isc_ratelimiter_detach(&zmgr->refreshrl); 19202 isc_ratelimiter_detach(&zmgr->startupnotifyrl); 19203 isc_ratelimiter_detach(&zmgr->startuprefreshrl); 19204 19205 isc_rwlock_destroy(&zmgr->urlock); 19206 isc_rwlock_destroy(&zmgr->rwlock); 19207 isc_rwlock_destroy(&zmgr->tlsctx_cache_rwlock); 19208 19209 zonemgr_keymgmt_destroy(zmgr); 19210 19211 mctx = zmgr->mctx; 19212 if (zmgr->tlsctx_cache != NULL) { 19213 isc_tlsctx_cache_detach(&zmgr->tlsctx_cache); 19214 } 19215 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); 19216 isc_mem_detach(&mctx); 19217} 19218 19219void 19220dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value) { 19221 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19222 19223 zmgr->transfersin = value; 19224} 19225 19226uint32_t 19227dns_zonemgr_gettransfersin(dns_zonemgr_t *zmgr) { 19228 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19229 19230 return (zmgr->transfersin); 19231} 19232 19233void 19234dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, uint32_t value) { 19235 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19236 19237 zmgr->transfersperns = value; 19238} 19239 19240uint32_t 19241dns_zonemgr_gettransfersperns(dns_zonemgr_t *zmgr) { 19242 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19243 19244 return (zmgr->transfersperns); 19245} 19246 19247isc_taskmgr_t * 19248dns_zonemgr_gettaskmgr(dns_zonemgr_t *zmgr) { 19249 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19250 19251 return (zmgr->taskmgr); 19252} 19253 19254isc_timermgr_t * 19255dns_zonemgr_gettimermgr(dns_zonemgr_t *zmgr) { 19256 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19257 19258 return (zmgr->timermgr); 19259} 19260 19261/* 19262 * Try to start a new incoming zone transfer to fill a quota 19263 * slot that was just vacated. 19264 * 19265 * Requires: 19266 * The zone manager is locked by the caller. 19267 */ 19268static void 19269zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi) { 19270 dns_zone_t *zone; 19271 dns_zone_t *next; 19272 19273 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); zone != NULL; 19274 zone = next) 19275 { 19276 isc_result_t result; 19277 next = ISC_LIST_NEXT(zone, statelink); 19278 result = zmgr_start_xfrin_ifquota(zmgr, zone); 19279 if (result == ISC_R_SUCCESS) { 19280 if (multi) { 19281 continue; 19282 } 19283 /* 19284 * We successfully filled the slot. We're done. 19285 */ 19286 break; 19287 } else if (result == ISC_R_QUOTA) { 19288 /* 19289 * Not enough quota. This is probably the per-server 19290 * quota, because we usually get called when a unit of 19291 * global quota has just been freed. Try the next 19292 * zone, it may succeed if it uses another primary. 19293 */ 19294 continue; 19295 } else { 19296 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, 19297 ISC_LOG_DEBUG(1), 19298 "starting zone transfer: %s", 19299 isc_result_totext(result)); 19300 break; 19301 } 19302 } 19303} 19304 19305/* 19306 * Try to start an incoming zone transfer for 'zone', quota permitting. 19307 * 19308 * Requires: 19309 * The zone manager is locked by the caller. 19310 * 19311 * Returns: 19312 * ISC_R_SUCCESS There was enough quota and we attempted to 19313 * start a transfer. zone_xfrdone() has been or will 19314 * be called. 19315 * ISC_R_QUOTA Not enough quota. 19316 * Others Failure. 19317 */ 19318static isc_result_t 19319zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 19320 dns_peer_t *peer = NULL; 19321 isc_netaddr_t primaryip; 19322 uint32_t nxfrsin, nxfrsperns; 19323 dns_zone_t *x; 19324 uint32_t maxtransfersin, maxtransfersperns; 19325 isc_event_t *e; 19326 19327 /* 19328 * If we are exiting just pretend we got quota so the zone will 19329 * be cleaned up in the zone's task context. 19330 */ 19331 LOCK_ZONE(zone); 19332 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 19333 UNLOCK_ZONE(zone); 19334 goto gotquota; 19335 } 19336 19337 /* 19338 * Find any configured information about the server we'd 19339 * like to transfer this zone from. 19340 */ 19341 isc_netaddr_fromsockaddr(&primaryip, &zone->primaryaddr); 19342 (void)dns_peerlist_peerbyaddr(zone->view->peers, &primaryip, &peer); 19343 UNLOCK_ZONE(zone); 19344 19345 /* 19346 * Determine the total maximum number of simultaneous 19347 * transfers allowed, and the maximum for this specific 19348 * primary. 19349 */ 19350 maxtransfersin = zmgr->transfersin; 19351 maxtransfersperns = zmgr->transfersperns; 19352 if (peer != NULL) { 19353 (void)dns_peer_gettransfers(peer, &maxtransfersperns); 19354 } 19355 19356 /* 19357 * Count the total number of transfers that are in progress, 19358 * and the number of transfers in progress from this primary. 19359 * We linearly scan a list of all transfers; if this turns 19360 * out to be too slow, we could hash on the primary address. 19361 */ 19362 nxfrsin = nxfrsperns = 0; 19363 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress); x != NULL; 19364 x = ISC_LIST_NEXT(x, statelink)) 19365 { 19366 isc_netaddr_t xip; 19367 19368 LOCK_ZONE(x); 19369 isc_netaddr_fromsockaddr(&xip, &x->primaryaddr); 19370 UNLOCK_ZONE(x); 19371 19372 nxfrsin++; 19373 if (isc_netaddr_equal(&xip, &primaryip)) { 19374 nxfrsperns++; 19375 } 19376 } 19377 19378 /* Enforce quota. */ 19379 if (nxfrsin >= maxtransfersin) { 19380 return (ISC_R_QUOTA); 19381 } 19382 19383 if (nxfrsperns >= maxtransfersperns) { 19384 return (ISC_R_QUOTA); 19385 } 19386 19387gotquota: 19388 /* 19389 * We have sufficient quota. Move the zone to the "xfrin_in_progress" 19390 * list and send it an event to let it start the actual transfer in the 19391 * context of its own task. 19392 */ 19393 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN, 19394 got_transfer_quota, zone, sizeof(isc_event_t)); 19395 19396 LOCK_ZONE(zone); 19397 INSIST(zone->statelist == &zmgr->waiting_for_xfrin); 19398 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink); 19399 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink); 19400 zone->statelist = &zmgr->xfrin_in_progress; 19401 isc_task_send(zone->task, &e); 19402 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 19403 "Transfer started."); 19404 UNLOCK_ZONE(zone); 19405 19406 return (ISC_R_SUCCESS); 19407} 19408 19409void 19410dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, uint32_t iolimit) { 19411 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19412 REQUIRE(iolimit > 0); 19413 19414 zmgr->iolimit = iolimit; 19415} 19416 19417uint32_t 19418dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) { 19419 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19420 19421 return (zmgr->iolimit); 19422} 19423 19424/* 19425 * Get permission to request a file handle from the OS. 19426 * An event will be sent to action when one is available. 19427 * There are two queues available (high and low), the high 19428 * queue will be serviced before the low one. 19429 * 19430 * zonemgr_putio() must be called after the event is delivered to 19431 * 'action'. 19432 */ 19433 19434static isc_result_t 19435zonemgr_getio(dns_zonemgr_t *zmgr, bool high, isc_task_t *task, 19436 isc_taskaction_t action, void *arg, dns_io_t **iop) { 19437 dns_io_t *io; 19438 bool queue; 19439 19440 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19441 REQUIRE(iop != NULL && *iop == NULL); 19442 19443 io = isc_mem_get(zmgr->mctx, sizeof(*io)); 19444 19445 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY, 19446 action, arg, sizeof(*io->event)); 19447 19448 io->zmgr = zmgr; 19449 io->high = high; 19450 io->task = NULL; 19451 isc_task_attach(task, &io->task); 19452 ISC_LINK_INIT(io, link); 19453 io->magic = IO_MAGIC; 19454 19455 LOCK(&zmgr->iolock); 19456 zmgr->ioactive++; 19457 queue = (zmgr->ioactive > zmgr->iolimit); 19458 if (queue) { 19459 if (io->high) { 19460 ISC_LIST_APPEND(zmgr->high, io, link); 19461 } else { 19462 ISC_LIST_APPEND(zmgr->low, io, link); 19463 } 19464 } 19465 UNLOCK(&zmgr->iolock); 19466 *iop = io; 19467 19468 if (!queue) { 19469 isc_task_send(io->task, &io->event); 19470 } 19471 return (ISC_R_SUCCESS); 19472} 19473 19474static void 19475zonemgr_putio(dns_io_t **iop) { 19476 dns_io_t *io; 19477 dns_io_t *next; 19478 dns_zonemgr_t *zmgr; 19479 19480 REQUIRE(iop != NULL); 19481 io = *iop; 19482 *iop = NULL; 19483 REQUIRE(DNS_IO_VALID(io)); 19484 19485 INSIST(!ISC_LINK_LINKED(io, link)); 19486 INSIST(io->event == NULL); 19487 19488 zmgr = io->zmgr; 19489 isc_task_detach(&io->task); 19490 io->magic = 0; 19491 isc_mem_put(zmgr->mctx, io, sizeof(*io)); 19492 19493 LOCK(&zmgr->iolock); 19494 INSIST(zmgr->ioactive > 0); 19495 zmgr->ioactive--; 19496 next = HEAD(zmgr->high); 19497 if (next == NULL) { 19498 next = HEAD(zmgr->low); 19499 } 19500 if (next != NULL) { 19501 if (next->high) { 19502 ISC_LIST_UNLINK(zmgr->high, next, link); 19503 } else { 19504 ISC_LIST_UNLINK(zmgr->low, next, link); 19505 } 19506 INSIST(next->event != NULL); 19507 } 19508 UNLOCK(&zmgr->iolock); 19509 if (next != NULL) { 19510 isc_task_send(next->task, &next->event); 19511 } 19512} 19513 19514static void 19515zonemgr_cancelio(dns_io_t *io) { 19516 bool send_event = false; 19517 19518 REQUIRE(DNS_IO_VALID(io)); 19519 19520 /* 19521 * If we are queued to be run then dequeue. 19522 */ 19523 LOCK(&io->zmgr->iolock); 19524 if (ISC_LINK_LINKED(io, link)) { 19525 if (io->high) { 19526 ISC_LIST_UNLINK(io->zmgr->high, io, link); 19527 } else { 19528 ISC_LIST_UNLINK(io->zmgr->low, io, link); 19529 } 19530 19531 send_event = true; 19532 INSIST(io->event != NULL); 19533 } 19534 UNLOCK(&io->zmgr->iolock); 19535 if (send_event) { 19536 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED; 19537 isc_task_send(io->task, &io->event); 19538 } 19539} 19540 19541static void 19542zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) { 19543 char *buf; 19544 int buflen; 19545 isc_result_t result; 19546 19547 buflen = strlen(path) + strlen(templat) + 2; 19548 19549 buf = isc_mem_get(zone->mctx, buflen); 19550 19551 result = isc_file_template(path, templat, buf, buflen); 19552 if (result != ISC_R_SUCCESS) { 19553 goto cleanup; 19554 } 19555 19556 result = isc_file_renameunique(path, buf); 19557 if (result != ISC_R_SUCCESS) { 19558 goto cleanup; 19559 } 19560 19561 dns_zone_log(zone, ISC_LOG_WARNING, 19562 "unable to load from '%s'; " 19563 "renaming file to '%s' for failure analysis and " 19564 "retransferring.", 19565 path, buf); 19566 19567cleanup: 19568 isc_mem_put(zone->mctx, buf, buflen); 19569} 19570 19571static void 19572setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) { 19573 isc_interval_t interval; 19574 uint32_t s, ns; 19575 uint32_t pertic; 19576 isc_result_t result; 19577 19578 if (value == 0) { 19579 value = 1; 19580 } 19581 19582 if (value == 1) { 19583 s = 1; 19584 ns = 0; 19585 pertic = 1; 19586 } else if (value <= 10) { 19587 s = 0; 19588 ns = 1000000000 / value; 19589 pertic = 1; 19590 } else { 19591 s = 0; 19592 ns = (1000000000 / value) * 10; 19593 pertic = 10; 19594 } 19595 19596 isc_interval_set(&interval, s, ns); 19597 19598 result = isc_ratelimiter_setinterval(rl, &interval); 19599 RUNTIME_CHECK(result == ISC_R_SUCCESS); 19600 isc_ratelimiter_setpertic(rl, pertic); 19601 19602 *rate = value; 19603} 19604 19605void 19606dns_zonemgr_setcheckdsrate(dns_zonemgr_t *zmgr, unsigned int value) { 19607 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19608 19609 setrl(zmgr->checkdsrl, &zmgr->checkdsrate, value); 19610} 19611 19612void 19613dns_zonemgr_setnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) { 19614 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19615 19616 setrl(zmgr->notifyrl, &zmgr->notifyrate, value); 19617} 19618 19619void 19620dns_zonemgr_setstartupnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) { 19621 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19622 19623 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value); 19624} 19625 19626void 19627dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) { 19628 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19629 19630 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value); 19631 /* XXXMPA separate out once we have the code to support this. */ 19632 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value); 19633} 19634 19635unsigned int 19636dns_zonemgr_getnotifyrate(dns_zonemgr_t *zmgr) { 19637 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19638 19639 return (zmgr->notifyrate); 19640} 19641 19642unsigned int 19643dns_zonemgr_getstartupnotifyrate(dns_zonemgr_t *zmgr) { 19644 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19645 19646 return (zmgr->startupnotifyrate); 19647} 19648 19649unsigned int 19650dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) { 19651 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19652 19653 return (zmgr->serialqueryrate); 19654} 19655 19656bool 19657dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 19658 isc_sockaddr_t *local, isc_time_t *now) { 19659 unsigned int i; 19660 uint32_t seconds = isc_time_seconds(now); 19661 uint32_t count = 0; 19662 19663 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19664 19665 RWLOCK(&zmgr->urlock, isc_rwlocktype_read); 19666 for (i = 0; i < UNREACH_CACHE_SIZE; i++) { 19667 if (atomic_load(&zmgr->unreachable[i].expire) >= seconds && 19668 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 19669 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 19670 { 19671 atomic_store_relaxed(&zmgr->unreachable[i].last, 19672 seconds); 19673 count = zmgr->unreachable[i].count; 19674 break; 19675 } 19676 } 19677 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read); 19678 return (i < UNREACH_CACHE_SIZE && count > 1U); 19679} 19680 19681void 19682dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 19683 isc_sockaddr_t *local) { 19684 unsigned int i; 19685 char primary[ISC_SOCKADDR_FORMATSIZE]; 19686 char source[ISC_SOCKADDR_FORMATSIZE]; 19687 19688 isc_sockaddr_format(remote, primary, sizeof(primary)); 19689 isc_sockaddr_format(local, source, sizeof(source)); 19690 19691 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19692 19693 RWLOCK(&zmgr->urlock, isc_rwlocktype_read); 19694 for (i = 0; i < UNREACH_CACHE_SIZE; i++) { 19695 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 19696 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 19697 { 19698 atomic_store_relaxed(&zmgr->unreachable[i].expire, 0); 19699 break; 19700 } 19701 } 19702 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read); 19703} 19704 19705void 19706dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 19707 isc_sockaddr_t *local, isc_time_t *now) { 19708 uint32_t seconds = isc_time_seconds(now); 19709 uint32_t expire = 0, last = seconds; 19710 unsigned int slot = UNREACH_CACHE_SIZE, oldest = 0; 19711 bool update_entry = true; 19712 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19713 19714 RWLOCK(&zmgr->urlock, isc_rwlocktype_write); 19715 for (unsigned int i = 0; i < UNREACH_CACHE_SIZE; i++) { 19716 /* Existing entry? */ 19717 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 19718 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 19719 { 19720 update_entry = false; 19721 slot = i; 19722 expire = atomic_load_relaxed( 19723 &zmgr->unreachable[i].expire); 19724 break; 19725 } 19726 /* Pick first empty slot? */ 19727 if (atomic_load_relaxed(&zmgr->unreachable[i].expire) < seconds) 19728 { 19729 slot = i; 19730 break; 19731 } 19732 /* The worst case, least recently used slot? */ 19733 if (atomic_load_relaxed(&zmgr->unreachable[i].last) < last) { 19734 last = atomic_load_relaxed(&zmgr->unreachable[i].last); 19735 oldest = i; 19736 } 19737 } 19738 19739 /* We haven't found any existing or free slots, use the oldest */ 19740 if (slot == UNREACH_CACHE_SIZE) { 19741 slot = oldest; 19742 } 19743 19744 if (expire < seconds) { 19745 /* Expired or new entry, reset count to 1 */ 19746 zmgr->unreachable[slot].count = 1; 19747 } else { 19748 zmgr->unreachable[slot].count++; 19749 } 19750 atomic_store_relaxed(&zmgr->unreachable[slot].expire, 19751 seconds + UNREACH_HOLD_TIME); 19752 atomic_store_relaxed(&zmgr->unreachable[slot].last, seconds); 19753 if (update_entry) { 19754 zmgr->unreachable[slot].remote = *remote; 19755 zmgr->unreachable[slot].local = *local; 19756 } 19757 19758 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write); 19759} 19760 19761void 19762dns_zone_forcereload(dns_zone_t *zone) { 19763 REQUIRE(DNS_ZONE_VALID(zone)); 19764 19765 if (zone->type == dns_zone_primary || 19766 (zone->type == dns_zone_redirect && zone->primaries == NULL)) 19767 { 19768 return; 19769 } 19770 19771 LOCK_ZONE(zone); 19772 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER); 19773 UNLOCK_ZONE(zone); 19774 dns_zone_refresh(zone); 19775} 19776 19777bool 19778dns_zone_isforced(dns_zone_t *zone) { 19779 REQUIRE(DNS_ZONE_VALID(zone)); 19780 19781 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)); 19782} 19783 19784isc_result_t 19785dns_zone_setstatistics(dns_zone_t *zone, bool on) { 19786 /* 19787 * This function is obsoleted. 19788 */ 19789 UNUSED(zone); 19790 UNUSED(on); 19791 return (ISC_R_NOTIMPLEMENTED); 19792} 19793 19794uint64_t * 19795dns_zone_getstatscounters(dns_zone_t *zone) { 19796 /* 19797 * This function is obsoleted. 19798 */ 19799 UNUSED(zone); 19800 return (NULL); 19801} 19802 19803void 19804dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) { 19805 REQUIRE(DNS_ZONE_VALID(zone)); 19806 REQUIRE(zone->stats == NULL); 19807 19808 LOCK_ZONE(zone); 19809 zone->stats = NULL; 19810 isc_stats_attach(stats, &zone->stats); 19811 UNLOCK_ZONE(zone); 19812} 19813 19814void 19815dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) { 19816 REQUIRE(DNS_ZONE_VALID(zone)); 19817 19818 LOCK_ZONE(zone); 19819 if (zone->requeststats_on && stats == NULL) { 19820 zone->requeststats_on = false; 19821 } else if (!zone->requeststats_on && stats != NULL) { 19822 if (zone->requeststats == NULL) { 19823 isc_stats_attach(stats, &zone->requeststats); 19824 } 19825 zone->requeststats_on = true; 19826 } 19827 UNLOCK_ZONE(zone); 19828} 19829 19830void 19831dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) { 19832 REQUIRE(DNS_ZONE_VALID(zone)); 19833 19834 LOCK_ZONE(zone); 19835 if (zone->requeststats_on && stats != NULL) { 19836 if (zone->rcvquerystats == NULL) { 19837 dns_stats_attach(stats, &zone->rcvquerystats); 19838 zone->requeststats_on = true; 19839 } 19840 } 19841 UNLOCK_ZONE(zone); 19842} 19843 19844void 19845dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats) { 19846 REQUIRE(DNS_ZONE_VALID(zone)); 19847 19848 LOCK_ZONE(zone); 19849 if (stats != NULL && zone->dnssecsignstats == NULL) { 19850 dns_stats_attach(stats, &zone->dnssecsignstats); 19851 } 19852 UNLOCK_ZONE(zone); 19853} 19854 19855dns_stats_t * 19856dns_zone_getdnssecsignstats(dns_zone_t *zone) { 19857 REQUIRE(DNS_ZONE_VALID(zone)); 19858 19859 return (zone->dnssecsignstats); 19860} 19861 19862isc_stats_t * 19863dns_zone_getrequeststats(dns_zone_t *zone) { 19864 /* 19865 * We don't lock zone for efficiency reason. This is not catastrophic 19866 * because requeststats must always be valid when requeststats_on is 19867 * true. 19868 * Some counters may be incremented while requeststats_on is becoming 19869 * false, or some cannot be incremented just after the statistics are 19870 * installed, but it shouldn't matter much in practice. 19871 */ 19872 if (zone->requeststats_on) { 19873 return (zone->requeststats); 19874 } else { 19875 return (NULL); 19876 } 19877} 19878 19879/* 19880 * Return the received query stats bucket 19881 * see note from dns_zone_getrequeststats() 19882 */ 19883dns_stats_t * 19884dns_zone_getrcvquerystats(dns_zone_t *zone) { 19885 if (zone->requeststats_on) { 19886 return (zone->rcvquerystats); 19887 } else { 19888 return (NULL); 19889 } 19890} 19891 19892void 19893dns_zone_dialup(dns_zone_t *zone) { 19894 REQUIRE(DNS_ZONE_VALID(zone)); 19895 19896 zone_debuglog(zone, "dns_zone_dialup", 3, "notify = %d, refresh = %d", 19897 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY), 19898 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)); 19899 19900 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) { 19901 dns_zone_notify(zone); 19902 } 19903 if (zone->type != dns_zone_primary && zone->primaries != NULL && 19904 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 19905 { 19906 dns_zone_refresh(zone); 19907 } 19908} 19909 19910void 19911dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) { 19912 REQUIRE(DNS_ZONE_VALID(zone)); 19913 19914 LOCK_ZONE(zone); 19915 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY | 19916 DNS_ZONEFLG_DIALREFRESH | 19917 DNS_ZONEFLG_NOREFRESH); 19918 switch (dialup) { 19919 case dns_dialuptype_no: 19920 break; 19921 case dns_dialuptype_yes: 19922 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY | 19923 DNS_ZONEFLG_DIALREFRESH | 19924 DNS_ZONEFLG_NOREFRESH)); 19925 break; 19926 case dns_dialuptype_notify: 19927 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 19928 break; 19929 case dns_dialuptype_notifypassive: 19930 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 19931 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 19932 break; 19933 case dns_dialuptype_refresh: 19934 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH); 19935 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 19936 break; 19937 case dns_dialuptype_passive: 19938 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 19939 break; 19940 default: 19941 UNREACHABLE(); 19942 } 19943 UNLOCK_ZONE(zone); 19944} 19945 19946isc_result_t 19947dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) { 19948 isc_result_t result = ISC_R_SUCCESS; 19949 19950 REQUIRE(DNS_ZONE_VALID(zone)); 19951 19952 LOCK_ZONE(zone); 19953 result = dns_zone_setstring(zone, &zone->keydirectory, directory); 19954 UNLOCK_ZONE(zone); 19955 19956 return (result); 19957} 19958 19959const char * 19960dns_zone_getkeydirectory(dns_zone_t *zone) { 19961 REQUIRE(DNS_ZONE_VALID(zone)); 19962 19963 return (zone->keydirectory); 19964} 19965 19966unsigned int 19967dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) { 19968 dns_zone_t *zone; 19969 unsigned int count = 0; 19970 19971 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 19972 19973 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 19974 switch (state) { 19975 case DNS_ZONESTATE_XFERRUNNING: 19976 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress); 19977 zone != NULL; zone = ISC_LIST_NEXT(zone, statelink)) 19978 { 19979 count++; 19980 } 19981 break; 19982 case DNS_ZONESTATE_XFERDEFERRED: 19983 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); 19984 zone != NULL; zone = ISC_LIST_NEXT(zone, statelink)) 19985 { 19986 count++; 19987 } 19988 break; 19989 case DNS_ZONESTATE_SOAQUERY: 19990 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 19991 zone = ISC_LIST_NEXT(zone, link)) 19992 { 19993 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { 19994 count++; 19995 } 19996 } 19997 break; 19998 case DNS_ZONESTATE_ANY: 19999 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 20000 zone = ISC_LIST_NEXT(zone, link)) 20001 { 20002 dns_view_t *view = zone->view; 20003 if (view != NULL && strcmp(view->name, "_bind") == 0) { 20004 continue; 20005 } 20006 count++; 20007 } 20008 break; 20009 case DNS_ZONESTATE_AUTOMATIC: 20010 for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL; 20011 zone = ISC_LIST_NEXT(zone, link)) 20012 { 20013 dns_view_t *view = zone->view; 20014 if (view != NULL && strcmp(view->name, "_bind") == 0) { 20015 continue; 20016 } 20017 if (zone->automatic) { 20018 count++; 20019 } 20020 } 20021 break; 20022 default: 20023 UNREACHABLE(); 20024 } 20025 20026 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 20027 20028 return (count); 20029} 20030 20031void 20032dns_zone_lock_keyfiles(dns_zone_t *zone) { 20033 REQUIRE(DNS_ZONE_VALID(zone)); 20034 20035 if (zone->kasp == NULL) { 20036 /* No need to lock, nothing is writing key files. */ 20037 return; 20038 } 20039 20040 REQUIRE(DNS_KEYFILEIO_VALID(zone->kfio)); 20041 isc_mutex_lock(&zone->kfio->lock); 20042} 20043 20044void 20045dns_zone_unlock_keyfiles(dns_zone_t *zone) { 20046 REQUIRE(DNS_ZONE_VALID(zone)); 20047 20048 if (zone->kasp == NULL) { 20049 /* No need to lock, nothing is writing key files. */ 20050 return; 20051 } 20052 20053 REQUIRE(DNS_KEYFILEIO_VALID(zone->kfio)); 20054 isc_mutex_unlock(&zone->kfio->lock); 20055} 20056 20057isc_result_t 20058dns_zone_checknames(dns_zone_t *zone, const dns_name_t *name, 20059 dns_rdata_t *rdata) { 20060 bool ok = true; 20061 bool fail = false; 20062 char namebuf[DNS_NAME_FORMATSIZE]; 20063 char namebuf2[DNS_NAME_FORMATSIZE]; 20064 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 20065 int level = ISC_LOG_WARNING; 20066 dns_name_t bad; 20067 20068 REQUIRE(DNS_ZONE_VALID(zone)); 20069 20070 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) && 20071 rdata->type != dns_rdatatype_nsec3) 20072 { 20073 return (ISC_R_SUCCESS); 20074 } 20075 20076 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) || 20077 rdata->type == dns_rdatatype_nsec3) 20078 { 20079 level = ISC_LOG_ERROR; 20080 fail = true; 20081 } 20082 20083 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, true); 20084 if (!ok) { 20085 dns_name_format(name, namebuf, sizeof(namebuf)); 20086 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 20087 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf, 20088 isc_result_totext(DNS_R_BADOWNERNAME)); 20089 if (fail) { 20090 return (DNS_R_BADOWNERNAME); 20091 } 20092 } 20093 20094 dns_name_init(&bad, NULL); 20095 ok = dns_rdata_checknames(rdata, name, &bad); 20096 if (!ok) { 20097 dns_name_format(name, namebuf, sizeof(namebuf)); 20098 dns_name_format(&bad, namebuf2, sizeof(namebuf2)); 20099 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 20100 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf, 20101 namebuf2, isc_result_totext(DNS_R_BADNAME)); 20102 if (fail) { 20103 return (DNS_R_BADNAME); 20104 } 20105 } 20106 20107 return (ISC_R_SUCCESS); 20108} 20109 20110void 20111dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) { 20112 REQUIRE(DNS_ZONE_VALID(zone)); 20113 zone->checkmx = checkmx; 20114} 20115 20116void 20117dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) { 20118 REQUIRE(DNS_ZONE_VALID(zone)); 20119 zone->checksrv = checksrv; 20120} 20121 20122void 20123dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) { 20124 REQUIRE(DNS_ZONE_VALID(zone)); 20125 zone->checkns = checkns; 20126} 20127 20128void 20129dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) { 20130 REQUIRE(DNS_ZONE_VALID(zone)); 20131 20132 LOCK_ZONE(zone); 20133 zone->isself = isself; 20134 zone->isselfarg = arg; 20135 UNLOCK_ZONE(zone); 20136} 20137 20138void 20139dns_zone_setnotifydelay(dns_zone_t *zone, uint32_t delay) { 20140 REQUIRE(DNS_ZONE_VALID(zone)); 20141 20142 LOCK_ZONE(zone); 20143 zone->notifydelay = delay; 20144 UNLOCK_ZONE(zone); 20145} 20146 20147uint32_t 20148dns_zone_getnotifydelay(dns_zone_t *zone) { 20149 REQUIRE(DNS_ZONE_VALID(zone)); 20150 20151 return (zone->notifydelay); 20152} 20153 20154isc_result_t 20155dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid, 20156 bool deleteit) { 20157 isc_result_t result; 20158 REQUIRE(DNS_ZONE_VALID(zone)); 20159 20160 dnssec_log(zone, ISC_LOG_NOTICE, 20161 "dns_zone_signwithkey(algorithm=%u, keyid=%u)", algorithm, 20162 keyid); 20163 LOCK_ZONE(zone); 20164 result = zone_signwithkey(zone, algorithm, keyid, deleteit); 20165 UNLOCK_ZONE(zone); 20166 20167 return (result); 20168} 20169 20170/* 20171 * Called when a dynamic update for an NSEC3PARAM record is received. 20172 * 20173 * If set, transform the NSEC3 salt into human-readable form so that it can be 20174 * logged. Then call zone_addnsec3chain(), passing NSEC3PARAM RDATA to it. 20175 */ 20176isc_result_t 20177dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 20178 isc_result_t result; 20179 char salt[255 * 2 + 1]; 20180 20181 REQUIRE(DNS_ZONE_VALID(zone)); 20182 20183 result = dns_nsec3param_salttotext(nsec3param, salt, sizeof(salt)); 20184 RUNTIME_CHECK(result == ISC_R_SUCCESS); 20185 dnssec_log(zone, ISC_LOG_NOTICE, 20186 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)", 20187 nsec3param->hash, nsec3param->iterations, salt); 20188 LOCK_ZONE(zone); 20189 result = zone_addnsec3chain(zone, nsec3param); 20190 UNLOCK_ZONE(zone); 20191 20192 return (result); 20193} 20194 20195void 20196dns_zone_setnodes(dns_zone_t *zone, uint32_t nodes) { 20197 REQUIRE(DNS_ZONE_VALID(zone)); 20198 20199 if (nodes == 0) { 20200 nodes = 1; 20201 } 20202 zone->nodes = nodes; 20203} 20204 20205void 20206dns_zone_setsignatures(dns_zone_t *zone, uint32_t signatures) { 20207 REQUIRE(DNS_ZONE_VALID(zone)); 20208 20209 /* 20210 * We treat signatures as a signed value so explicitly 20211 * limit its range here. 20212 */ 20213 if (signatures > INT32_MAX) { 20214 signatures = INT32_MAX; 20215 } else if (signatures == 0) { 20216 signatures = 1; 20217 } 20218 zone->signatures = signatures; 20219} 20220 20221uint32_t 20222dns_zone_getsignatures(dns_zone_t *zone) { 20223 REQUIRE(DNS_ZONE_VALID(zone)); 20224 return (zone->signatures); 20225} 20226 20227void 20228dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) { 20229 REQUIRE(DNS_ZONE_VALID(zone)); 20230 zone->privatetype = type; 20231} 20232 20233dns_rdatatype_t 20234dns_zone_getprivatetype(dns_zone_t *zone) { 20235 REQUIRE(DNS_ZONE_VALID(zone)); 20236 return (zone->privatetype); 20237} 20238 20239static isc_result_t 20240zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid, 20241 bool deleteit) { 20242 dns_signing_t *signing; 20243 dns_signing_t *current; 20244 isc_result_t result = ISC_R_SUCCESS; 20245 isc_time_t now; 20246 dns_db_t *db = NULL; 20247 20248 signing = isc_mem_get(zone->mctx, sizeof *signing); 20249 20250 signing->magic = 0; 20251 signing->db = NULL; 20252 signing->dbiterator = NULL; 20253 signing->algorithm = algorithm; 20254 signing->keyid = keyid; 20255 signing->deleteit = deleteit; 20256 signing->done = false; 20257 20258 TIME_NOW(&now); 20259 20260 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 20261 if (zone->db != NULL) { 20262 dns_db_attach(zone->db, &db); 20263 } 20264 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 20265 20266 if (db == NULL) { 20267 result = ISC_R_NOTFOUND; 20268 goto cleanup; 20269 } 20270 20271 dns_db_attach(db, &signing->db); 20272 20273 for (current = ISC_LIST_HEAD(zone->signing); current != NULL; 20274 current = ISC_LIST_NEXT(current, link)) 20275 { 20276 if (current->db == signing->db && 20277 current->algorithm == signing->algorithm && 20278 current->keyid == signing->keyid) 20279 { 20280 if (current->deleteit != signing->deleteit) { 20281 current->done = true; 20282 } else { 20283 goto cleanup; 20284 } 20285 } 20286 } 20287 20288 result = dns_db_createiterator(signing->db, 0, &signing->dbiterator); 20289 20290 if (result == ISC_R_SUCCESS) { 20291 result = dns_dbiterator_first(signing->dbiterator); 20292 } 20293 if (result == ISC_R_SUCCESS) { 20294 dns_dbiterator_pause(signing->dbiterator); 20295 ISC_LIST_INITANDAPPEND(zone->signing, signing, link); 20296 signing = NULL; 20297 if (isc_time_isepoch(&zone->signingtime)) { 20298 zone->signingtime = now; 20299 if (zone->task != NULL) { 20300 zone_settimer(zone, &now); 20301 } 20302 } 20303 } 20304 20305cleanup: 20306 if (signing != NULL) { 20307 if (signing->db != NULL) { 20308 dns_db_detach(&signing->db); 20309 } 20310 if (signing->dbiterator != NULL) { 20311 dns_dbiterator_destroy(&signing->dbiterator); 20312 } 20313 isc_mem_put(zone->mctx, signing, sizeof *signing); 20314 } 20315 if (db != NULL) { 20316 dns_db_detach(&db); 20317 } 20318 return (result); 20319} 20320 20321/* Called once; *timep should be set to the current time. */ 20322static isc_result_t 20323next_keyevent(dst_key_t *key, isc_stdtime_t *timep) { 20324 isc_result_t result; 20325 isc_stdtime_t now, then = 0, event; 20326 int i; 20327 20328 now = *timep; 20329 20330 for (i = 0; i <= DST_MAX_TIMES; i++) { 20331 result = dst_key_gettime(key, i, &event); 20332 if (result == ISC_R_SUCCESS && event > now && 20333 (then == 0 || event < then)) 20334 { 20335 then = event; 20336 } 20337 } 20338 20339 if (then != 0) { 20340 *timep = then; 20341 return (ISC_R_SUCCESS); 20342 } 20343 20344 return (ISC_R_NOTFOUND); 20345} 20346 20347static isc_result_t 20348rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 20349 const dns_rdata_t *rdata, bool *flag) { 20350 dns_rdataset_t rdataset; 20351 dns_dbnode_t *node = NULL; 20352 isc_result_t result; 20353 20354 dns_rdataset_init(&rdataset); 20355 if (rdata->type == dns_rdatatype_nsec3) { 20356 CHECK(dns_db_findnsec3node(db, name, false, &node)); 20357 } else { 20358 CHECK(dns_db_findnode(db, name, false, &node)); 20359 } 20360 result = dns_db_findrdataset(db, node, ver, rdata->type, 0, 20361 (isc_stdtime_t)0, &rdataset, NULL); 20362 if (result == ISC_R_NOTFOUND) { 20363 *flag = false; 20364 result = ISC_R_SUCCESS; 20365 goto failure; 20366 } 20367 20368 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 20369 result = dns_rdataset_next(&rdataset)) 20370 { 20371 dns_rdata_t myrdata = DNS_RDATA_INIT; 20372 dns_rdataset_current(&rdataset, &myrdata); 20373 if (!dns_rdata_compare(&myrdata, rdata)) { 20374 break; 20375 } 20376 } 20377 dns_rdataset_disassociate(&rdataset); 20378 if (result == ISC_R_SUCCESS) { 20379 *flag = true; 20380 } else if (result == ISC_R_NOMORE) { 20381 *flag = false; 20382 result = ISC_R_SUCCESS; 20383 } 20384 20385failure: 20386 if (node != NULL) { 20387 dns_db_detachnode(db, &node); 20388 } 20389 return (result); 20390} 20391 20392/* 20393 * Add records to signal the state of signing or of key removal. 20394 */ 20395static isc_result_t 20396add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, 20397 dns_dbversion_t *ver, dns_diff_t *diff, bool sign_all) { 20398 dns_difftuple_t *tuple, *newtuple = NULL; 20399 dns_rdata_dnskey_t dnskey; 20400 dns_rdata_t rdata = DNS_RDATA_INIT; 20401 bool flag; 20402 isc_region_t r; 20403 isc_result_t result = ISC_R_SUCCESS; 20404 uint16_t keyid; 20405 unsigned char buf[5]; 20406 dns_name_t *name = dns_db_origin(db); 20407 20408 for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; 20409 tuple = ISC_LIST_NEXT(tuple, link)) 20410 { 20411 if (tuple->rdata.type != dns_rdatatype_dnskey) { 20412 continue; 20413 } 20414 20415 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL); 20416 RUNTIME_CHECK(result == ISC_R_SUCCESS); 20417 if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK | 20418 DNS_KEYTYPE_NOAUTH)) != DNS_KEYOWNER_ZONE) 20419 { 20420 continue; 20421 } 20422 20423 dns_rdata_toregion(&tuple->rdata, &r); 20424 20425 keyid = dst_region_computeid(&r); 20426 20427 buf[0] = dnskey.algorithm; 20428 buf[1] = (keyid & 0xff00) >> 8; 20429 buf[2] = (keyid & 0xff); 20430 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1; 20431 buf[4] = 0; 20432 rdata.data = buf; 20433 rdata.length = sizeof(buf); 20434 rdata.type = privatetype; 20435 rdata.rdclass = tuple->rdata.rdclass; 20436 20437 if (sign_all || tuple->op == DNS_DIFFOP_DEL) { 20438 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 20439 if (flag) { 20440 continue; 20441 } 20442 20443 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, 20444 name, 0, &rdata, &newtuple)); 20445 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 20446 INSIST(newtuple == NULL); 20447 } 20448 20449 /* 20450 * Remove any record which says this operation has already 20451 * completed. 20452 */ 20453 buf[4] = 1; 20454 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 20455 if (flag) { 20456 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, 20457 name, 0, &rdata, &newtuple)); 20458 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 20459 INSIST(newtuple == NULL); 20460 } 20461 } 20462failure: 20463 return (result); 20464} 20465 20466/* 20467 * See if dns__zone_updatesigs() will update signature for RRset 'rrtype' at 20468 * the apex, and if not tickle them and cause to sign so that newly activated 20469 * keys are used. 20470 */ 20471static isc_result_t 20472tickle_apex_rrset(dns_rdatatype_t rrtype, dns_zone_t *zone, dns_db_t *db, 20473 dns_dbversion_t *ver, isc_stdtime_t now, dns_diff_t *diff, 20474 dns__zonediff_t *zonediff, dst_key_t **keys, 20475 unsigned int nkeys, isc_stdtime_t inception, 20476 isc_stdtime_t keyexpire, bool check_ksk, 20477 bool keyset_kskonly) { 20478 dns_difftuple_t *tuple; 20479 isc_result_t result; 20480 20481 for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; 20482 tuple = ISC_LIST_NEXT(tuple, link)) 20483 { 20484 if (tuple->rdata.type == rrtype && 20485 dns_name_equal(&tuple->name, &zone->origin)) 20486 { 20487 break; 20488 } 20489 } 20490 20491 if (tuple == NULL) { 20492 result = del_sigs(zone, db, ver, &zone->origin, rrtype, 20493 zonediff, keys, nkeys, now, false); 20494 if (result != ISC_R_SUCCESS) { 20495 dnssec_log(zone, ISC_LOG_ERROR, 20496 "sign_apex:del_sigs -> %s", 20497 isc_result_totext(result)); 20498 return (result); 20499 } 20500 result = add_sigs(db, ver, &zone->origin, zone, rrtype, 20501 zonediff->diff, keys, nkeys, zone->mctx, now, 20502 inception, keyexpire, check_ksk, 20503 keyset_kskonly); 20504 if (result != ISC_R_SUCCESS) { 20505 dnssec_log(zone, ISC_LOG_ERROR, 20506 "sign_apex:add_sigs -> %s", 20507 isc_result_totext(result)); 20508 return (result); 20509 } 20510 } 20511 20512 return (ISC_R_SUCCESS); 20513} 20514 20515static isc_result_t 20516sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 20517 isc_stdtime_t now, dns_diff_t *diff, dns__zonediff_t *zonediff) { 20518 isc_result_t result; 20519 isc_stdtime_t inception, soaexpire, keyexpire; 20520 bool check_ksk, keyset_kskonly; 20521 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 20522 unsigned int nkeys = 0, i; 20523 20524 result = dns__zone_findkeys(zone, db, ver, now, zone->mctx, 20525 DNS_MAXZONEKEYS, zone_keys, &nkeys); 20526 if (result != ISC_R_SUCCESS) { 20527 dnssec_log(zone, ISC_LOG_ERROR, 20528 "sign_apex:dns__zone_findkeys -> %s", 20529 isc_result_totext(result)); 20530 return (result); 20531 } 20532 20533 inception = now - 3600; /* Allow for clock skew. */ 20534 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 20535 20536 keyexpire = dns_zone_getkeyvalidityinterval(zone); 20537 if (keyexpire == 0) { 20538 keyexpire = soaexpire - 1; 20539 } else { 20540 keyexpire += now; 20541 } 20542 20543 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 20544 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 20545 20546 /* 20547 * See if dns__zone_updatesigs() will update DNSKEY/CDS/CDNSKEY 20548 * signature and if not cause them to sign so that newly activated 20549 * keys are used. 20550 */ 20551 result = tickle_apex_rrset(dns_rdatatype_dnskey, zone, db, ver, now, 20552 diff, zonediff, zone_keys, nkeys, inception, 20553 keyexpire, check_ksk, keyset_kskonly); 20554 if (result != ISC_R_SUCCESS) { 20555 goto failure; 20556 } 20557 result = tickle_apex_rrset(dns_rdatatype_cds, zone, db, ver, now, diff, 20558 zonediff, zone_keys, nkeys, inception, 20559 keyexpire, check_ksk, keyset_kskonly); 20560 if (result != ISC_R_SUCCESS) { 20561 goto failure; 20562 } 20563 result = tickle_apex_rrset(dns_rdatatype_cdnskey, zone, db, ver, now, 20564 diff, zonediff, zone_keys, nkeys, inception, 20565 keyexpire, check_ksk, keyset_kskonly); 20566 if (result != ISC_R_SUCCESS) { 20567 goto failure; 20568 } 20569 20570 result = dns__zone_updatesigs(diff, db, ver, zone_keys, nkeys, zone, 20571 inception, soaexpire, keyexpire, now, 20572 check_ksk, keyset_kskonly, zonediff); 20573 20574 if (result != ISC_R_SUCCESS) { 20575 dnssec_log(zone, ISC_LOG_ERROR, 20576 "sign_apex:dns__zone_updatesigs -> %s", 20577 isc_result_totext(result)); 20578 goto failure; 20579 } 20580 20581failure: 20582 for (i = 0; i < nkeys; i++) { 20583 dst_key_free(&zone_keys[i]); 20584 } 20585 return (result); 20586} 20587 20588static isc_result_t 20589clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 20590 dns_diff_t *diff) { 20591 isc_result_t result; 20592 dns_dbnode_t *node = NULL; 20593 dns_rdataset_t rdataset; 20594 20595 dns_rdataset_init(&rdataset); 20596 CHECK(dns_db_getoriginnode(db, &node)); 20597 20598 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 20599 dns_rdatatype_none, 0, &rdataset, NULL); 20600 if (dns_rdataset_isassociated(&rdataset)) { 20601 dns_rdataset_disassociate(&rdataset); 20602 } 20603 if (result != ISC_R_NOTFOUND) { 20604 goto failure; 20605 } 20606 20607 result = dns_nsec3param_deletechains(db, ver, zone, true, diff); 20608 20609failure: 20610 if (node != NULL) { 20611 dns_db_detachnode(db, &node); 20612 } 20613 return (result); 20614} 20615 20616/* 20617 * Given an RRSIG rdataset and an algorithm, determine whether there 20618 * are any signatures using that algorithm. 20619 */ 20620static bool 20621signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) { 20622 dns_rdata_t rdata = DNS_RDATA_INIT; 20623 dns_rdata_rrsig_t rrsig; 20624 isc_result_t result; 20625 20626 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig); 20627 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) { 20628 return (false); 20629 } 20630 20631 for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; 20632 result = dns_rdataset_next(rdataset)) 20633 { 20634 dns_rdataset_current(rdataset, &rdata); 20635 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 20636 RUNTIME_CHECK(result == ISC_R_SUCCESS); 20637 dns_rdata_reset(&rdata); 20638 if (rrsig.algorithm == alg) { 20639 return (true); 20640 } 20641 } 20642 20643 return (false); 20644} 20645 20646static isc_result_t 20647add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 20648 dns_diff_t *diff) { 20649 dns_name_t *origin; 20650 bool build_nsec3; 20651 isc_result_t result; 20652 20653 origin = dns_db_origin(db); 20654 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL, 20655 &build_nsec3)); 20656 if (build_nsec3) { 20657 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone_nsecttl(zone), 20658 false, zone->privatetype, diff)); 20659 } 20660 CHECK(updatesecure(db, ver, origin, zone_nsecttl(zone), true, diff)); 20661 20662failure: 20663 return (result); 20664} 20665 20666static void 20667dnssec_report(const char *format, ...) { 20668 va_list args; 20669 va_start(args, format); 20670 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_ZONE, 20671 ISC_LOG_INFO, format, args); 20672 va_end(args); 20673} 20674 20675static void 20676checkds_destroy(dns_checkds_t *checkds, bool locked) { 20677 isc_mem_t *mctx; 20678 20679 REQUIRE(DNS_CHECKDS_VALID(checkds)); 20680 20681 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 20682 "checkds: destroy DS query"); 20683 20684 if (checkds->zone != NULL) { 20685 if (!locked) { 20686 LOCK_ZONE(checkds->zone); 20687 } 20688 REQUIRE(LOCKED_ZONE(checkds->zone)); 20689 if (ISC_LINK_LINKED(checkds, link)) { 20690 ISC_LIST_UNLINK(checkds->zone->checkds_requests, 20691 checkds, link); 20692 } 20693 if (!locked) { 20694 UNLOCK_ZONE(checkds->zone); 20695 } 20696 if (locked) { 20697 zone_idetach(&checkds->zone); 20698 } else { 20699 dns_zone_idetach(&checkds->zone); 20700 } 20701 } 20702 if (checkds->request != NULL) { 20703 dns_request_destroy(&checkds->request); 20704 } 20705 if (checkds->key != NULL) { 20706 dns_tsigkey_detach(&checkds->key); 20707 } 20708 if (checkds->transport != NULL) { 20709 dns_transport_detach(&checkds->transport); 20710 } 20711 mctx = checkds->mctx; 20712 isc_mem_put(checkds->mctx, checkds, sizeof(*checkds)); 20713 isc_mem_detach(&mctx); 20714} 20715 20716static isc_result_t 20717make_dnskey(dst_key_t *key, unsigned char *buf, int bufsize, 20718 dns_rdata_t *target) { 20719 isc_result_t result; 20720 isc_buffer_t b; 20721 isc_region_t r; 20722 20723 isc_buffer_init(&b, buf, bufsize); 20724 result = dst_key_todns(key, &b); 20725 if (result != ISC_R_SUCCESS) { 20726 return (result); 20727 } 20728 20729 dns_rdata_reset(target); 20730 isc_buffer_usedregion(&b, &r); 20731 dns_rdata_fromregion(target, dst_key_class(key), dns_rdatatype_dnskey, 20732 &r); 20733 return (ISC_R_SUCCESS); 20734} 20735 20736static bool 20737do_checkds(dns_zone_t *zone, dst_key_t *key, isc_stdtime_t now, 20738 bool dspublish) { 20739 dns_kasp_t *kasp = dns_zone_getkasp(zone); 20740 const char *dir = dns_zone_getkeydirectory(zone); 20741 isc_result_t result; 20742 uint32_t count = 0; 20743 20744 if (dspublish) { 20745 (void)dst_key_getnum(key, DST_NUM_DSPUBCOUNT, &count); 20746 count += 1; 20747 dst_key_setnum(key, DST_NUM_DSPUBCOUNT, count); 20748 dns_zone_log(zone, ISC_LOG_DEBUG(3), 20749 "checkds: %u DS published " 20750 "for key %u", 20751 count, dst_key_id(key)); 20752 20753 if (count != zone->parentalscnt) { 20754 return false; 20755 } 20756 } else { 20757 (void)dst_key_getnum(key, DST_NUM_DSDELCOUNT, &count); 20758 count += 1; 20759 dst_key_setnum(key, DST_NUM_DSDELCOUNT, count); 20760 dns_zone_log(zone, ISC_LOG_DEBUG(3), 20761 "checkds: %u DS withdrawn " 20762 "for key %u", 20763 count, dst_key_id(key)); 20764 20765 if (count != zone->parentalscnt) { 20766 return false; 20767 } 20768 } 20769 20770 dns_zone_log(zone, ISC_LOG_DEBUG(3), 20771 "checkds: checkds %s for key " 20772 "%u", 20773 dspublish ? "published" : "withdrawn", dst_key_id(key)); 20774 20775 dns_zone_lock_keyfiles(zone); 20776 result = dns_keymgr_checkds_id(kasp, &zone->checkds_ok, dir, now, now, 20777 dspublish, dst_key_id(key), 20778 dst_key_alg(key)); 20779 dns_zone_unlock_keyfiles(zone); 20780 20781 if (result != ISC_R_SUCCESS) { 20782 dns_zone_log(zone, ISC_LOG_WARNING, 20783 "checkds: checkds for key %u failed: %s", 20784 dst_key_id(key), isc_result_totext(result)); 20785 return false; 20786 } 20787 20788 return true; 20789} 20790 20791static isc_result_t 20792validate_ds(dns_zone_t *zone, dns_message_t *message) { 20793 UNUSED(zone); 20794 UNUSED(message); 20795 20796 /* Get closest trust anchor */ 20797 20798 /* Check that trust anchor is (grand)parent of zone. */ 20799 20800 /* Find the DNSKEY signing the message. */ 20801 20802 /* Check that DNSKEY is in chain of trust. */ 20803 20804 /* Validate DS RRset. */ 20805 20806 return (ISC_R_SUCCESS); 20807} 20808 20809static void 20810checkds_done(isc_task_t *task, isc_event_t *event) { 20811 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 20812 char rcode[128]; 20813 dns_checkds_t *checkds; 20814 dns_zone_t *zone; 20815 dns_db_t *db = NULL; 20816 dns_dbversion_t *version = NULL; 20817 dns_dnsseckey_t *key; 20818 dns_dnsseckeylist_t keys; 20819 dns_kasp_t *kasp = NULL; 20820 dns_message_t *message = NULL; 20821 dns_rdataset_t *ds_rrset = NULL; 20822 dns_requestevent_t *revent = (dns_requestevent_t *)event; 20823 isc_buffer_t buf; 20824 isc_result_t result; 20825 isc_stdtime_t now; 20826 isc_time_t timenow; 20827 bool rekey = false; 20828 bool empty = false; 20829 20830 UNUSED(task); 20831 20832 checkds = event->ev_arg; 20833 REQUIRE(DNS_CHECKDS_VALID(checkds)); 20834 20835 zone = checkds->zone; 20836 INSIST(task == zone->task); 20837 20838 ISC_LIST_INIT(keys); 20839 20840 kasp = zone->kasp; 20841 INSIST(kasp != NULL); 20842 20843 isc_buffer_init(&buf, rcode, sizeof(rcode)); 20844 isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf)); 20845 20846 dns_zone_log(zone, ISC_LOG_DEBUG(1), "checkds: DS query to %s: done", 20847 addrbuf); 20848 20849 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &message); 20850 INSIST(message != NULL); 20851 20852 CHECK(revent->result); 20853 CHECK(dns_request_getresponse(revent->request, message, 20854 DNS_MESSAGEPARSE_PRESERVEORDER)); 20855 CHECK(dns_rcode_totext(message->rcode, &buf)); 20856 20857 dns_zone_log(zone, ISC_LOG_DEBUG(3), 20858 "checkds: DS response from %s: %.*s", addrbuf, 20859 (int)buf.used, rcode); 20860 20861 /* Validate response. */ 20862 CHECK(validate_ds(zone, message)); 20863 20864 /* Check RCODE. */ 20865 if (message->rcode != dns_rcode_noerror) { 20866 dns_zone_log(zone, ISC_LOG_NOTICE, 20867 "checkds: bad DS response from %s: %.*s", addrbuf, 20868 (int)buf.used, rcode); 20869 goto failure; 20870 } 20871 20872 /* Make sure that either AA or RA bit is set. */ 20873 if ((message->flags & DNS_MESSAGEFLAG_AA) == 0 && 20874 (message->flags & DNS_MESSAGEFLAG_RA) == 0) 20875 { 20876 dns_zone_log(zone, ISC_LOG_NOTICE, 20877 "checkds: bad DS response from %s: expected AA or " 20878 "RA bit set", 20879 addrbuf); 20880 goto failure; 20881 } 20882 20883 /* Lookup DS RRset. */ 20884 result = dns_message_firstname(message, DNS_SECTION_ANSWER); 20885 while (result == ISC_R_SUCCESS) { 20886 dns_name_t *name = NULL; 20887 dns_rdataset_t *rdataset; 20888 20889 dns_message_currentname(message, DNS_SECTION_ANSWER, &name); 20890 if (dns_name_compare(&zone->origin, name) != 0) { 20891 goto next; 20892 } 20893 20894 for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; 20895 rdataset = ISC_LIST_NEXT(rdataset, link)) 20896 { 20897 if (rdataset->type != dns_rdatatype_ds) { 20898 goto next; 20899 } 20900 20901 ds_rrset = rdataset; 20902 break; 20903 } 20904 20905 if (ds_rrset != NULL) { 20906 break; 20907 } 20908 20909 next: 20910 result = dns_message_nextname(message, DNS_SECTION_ANSWER); 20911 } 20912 20913 if (ds_rrset == NULL) { 20914 empty = true; 20915 dns_zone_log(zone, ISC_LOG_NOTICE, 20916 "checkds: empty DS response from %s", addrbuf); 20917 } 20918 20919 TIME_NOW(&timenow); 20920 now = isc_time_seconds(&timenow); 20921 20922 CHECK(dns_zone_getdb(zone, &db)); 20923 dns_db_currentversion(db, &version); 20924 20925 KASP_LOCK(kasp); 20926 LOCK_ZONE(zone); 20927 for (key = ISC_LIST_HEAD(zone->checkds_ok); key != NULL; 20928 key = ISC_LIST_NEXT(key, link)) 20929 { 20930 bool alldone = false, found = false; 20931 bool checkdspub = false, checkdsdel = false, ksk = false; 20932 dst_key_state_t ds_state = DST_KEY_STATE_NA; 20933 isc_stdtime_t published = 0, withdrawn = 0; 20934 isc_result_t ret = ISC_R_SUCCESS; 20935 20936 /* Is this key have the KSK role? */ 20937 (void)dst_key_role(key->key, &ksk, NULL); 20938 if (!ksk) { 20939 continue; 20940 } 20941 20942 /* Do we need to check the DS RRset for this key? */ 20943 (void)dst_key_getstate(key->key, DST_KEY_DS, &ds_state); 20944 (void)dst_key_gettime(key->key, DST_TIME_DSPUBLISH, &published); 20945 (void)dst_key_gettime(key->key, DST_TIME_DSDELETE, &withdrawn); 20946 20947 if (ds_state == DST_KEY_STATE_RUMOURED && published == 0) { 20948 checkdspub = true; 20949 } else if (ds_state == DST_KEY_STATE_UNRETENTIVE && 20950 withdrawn == 0) 20951 { 20952 checkdsdel = true; 20953 } 20954 if (!checkdspub && !checkdsdel) { 20955 continue; 20956 } 20957 20958 if (empty) { 20959 goto dswithdrawn; 20960 } 20961 20962 /* Find the appropriate DS record. */ 20963 ret = dns_rdataset_first(ds_rrset); 20964 while (ret == ISC_R_SUCCESS) { 20965 dns_rdata_ds_t ds; 20966 dns_rdata_t dnskey = DNS_RDATA_INIT; 20967 dns_rdata_t dsrdata = DNS_RDATA_INIT; 20968 dns_rdata_t rdata = DNS_RDATA_INIT; 20969 isc_result_t r; 20970 unsigned char dsbuf[DNS_DS_BUFFERSIZE]; 20971 unsigned char keybuf[DST_KEY_MAXSIZE]; 20972 20973 dns_rdataset_current(ds_rrset, &rdata); 20974 r = dns_rdata_tostruct(&rdata, &ds, NULL); 20975 if (r != ISC_R_SUCCESS) { 20976 goto nextds; 20977 } 20978 /* Check key tag and algorithm. */ 20979 if (dst_key_id(key->key) != ds.key_tag) { 20980 goto nextds; 20981 } 20982 if (dst_key_alg(key->key) != ds.algorithm) { 20983 goto nextds; 20984 } 20985 /* Derive DS from DNSKEY, see if the rdata is equal. */ 20986 make_dnskey(key->key, keybuf, sizeof(keybuf), &dnskey); 20987 r = dns_ds_buildrdata(&zone->origin, &dnskey, 20988 ds.digest_type, dsbuf, &dsrdata); 20989 if (r != ISC_R_SUCCESS) { 20990 goto nextds; 20991 } 20992 if (dns_rdata_compare(&rdata, &dsrdata) == 0) { 20993 found = true; 20994 if (checkdspub) { 20995 /* DS Published. */ 20996 alldone = do_checkds(zone, key->key, 20997 now, true); 20998 if (alldone) { 20999 rekey = true; 21000 } 21001 } 21002 } 21003 21004 nextds: 21005 ret = dns_rdataset_next(ds_rrset); 21006 } 21007 21008 dswithdrawn: 21009 /* DS withdrawn. */ 21010 if (checkdsdel && !found) { 21011 alldone = do_checkds(zone, key->key, now, false); 21012 if (alldone) { 21013 rekey = true; 21014 } 21015 } 21016 } 21017 UNLOCK_ZONE(zone); 21018 KASP_UNLOCK(kasp); 21019 21020 /* Rekey after checkds. */ 21021 if (rekey) { 21022 dns_zone_rekey(zone, false); 21023 } 21024 21025failure: 21026 if (result != ISC_R_SUCCESS) { 21027 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21028 "checkds: DS request failed: %s", 21029 isc_result_totext(result)); 21030 } 21031 21032 if (version != NULL) { 21033 dns_db_closeversion(db, &version, false); 21034 } 21035 if (db != NULL) { 21036 dns_db_detach(&db); 21037 } 21038 21039 while (!ISC_LIST_EMPTY(keys)) { 21040 key = ISC_LIST_HEAD(keys); 21041 ISC_LIST_UNLINK(keys, key, link); 21042 dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key); 21043 } 21044 21045 isc_event_free(&event); 21046 checkds_destroy(checkds, false); 21047 dns_message_detach(&message); 21048} 21049 21050static bool 21051checkds_isqueued(dns_zone_t *zone, isc_sockaddr_t *addr, dns_tsigkey_t *key, 21052 dns_transport_t *transport) { 21053 dns_checkds_t *checkds; 21054 21055 for (checkds = ISC_LIST_HEAD(zone->checkds_requests); checkds != NULL; 21056 checkds = ISC_LIST_NEXT(checkds, link)) 21057 { 21058 if (checkds->request != NULL) { 21059 continue; 21060 } 21061 if (addr != NULL && isc_sockaddr_equal(addr, &checkds->dst) && 21062 checkds->key == key && checkds->transport == transport) 21063 { 21064 return (true); 21065 } 21066 } 21067 return (false); 21068} 21069 21070static isc_result_t 21071checkds_create(isc_mem_t *mctx, unsigned int flags, dns_checkds_t **checkdsp) { 21072 dns_checkds_t *checkds; 21073 21074 REQUIRE(checkdsp != NULL && *checkdsp == NULL); 21075 21076 checkds = isc_mem_get(mctx, sizeof(*checkds)); 21077 *checkds = (dns_checkds_t){ 21078 .flags = flags, 21079 }; 21080 21081 isc_mem_attach(mctx, &checkds->mctx); 21082 isc_sockaddr_any(&checkds->dst); 21083 ISC_LINK_INIT(checkds, link); 21084 checkds->magic = CHECKDS_MAGIC; 21085 *checkdsp = checkds; 21086 return (ISC_R_SUCCESS); 21087} 21088 21089static isc_result_t 21090checkds_createmessage(dns_zone_t *zone, dns_message_t **messagep) { 21091 dns_message_t *message = NULL; 21092 21093 dns_name_t *tempname = NULL; 21094 dns_rdataset_t *temprdataset = NULL; 21095 21096 isc_result_t result; 21097 21098 REQUIRE(DNS_ZONE_VALID(zone)); 21099 REQUIRE(messagep != NULL && *messagep == NULL); 21100 21101 dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message); 21102 21103 message->opcode = dns_opcode_query; 21104 message->rdclass = zone->rdclass; 21105 message->flags |= DNS_MESSAGEFLAG_RD; 21106 21107 result = dns_message_gettempname(message, &tempname); 21108 if (result != ISC_R_SUCCESS) { 21109 goto cleanup; 21110 } 21111 21112 result = dns_message_gettemprdataset(message, &temprdataset); 21113 if (result != ISC_R_SUCCESS) { 21114 goto cleanup; 21115 } 21116 21117 /* 21118 * Make question. 21119 */ 21120 dns_name_init(tempname, NULL); 21121 dns_name_clone(&zone->origin, tempname); 21122 dns_rdataset_makequestion(temprdataset, zone->rdclass, 21123 dns_rdatatype_ds); 21124 ISC_LIST_APPEND(tempname->list, temprdataset, link); 21125 dns_message_addname(message, tempname, DNS_SECTION_QUESTION); 21126 tempname = NULL; 21127 temprdataset = NULL; 21128 21129 *messagep = message; 21130 return (ISC_R_SUCCESS); 21131 21132cleanup: 21133 if (tempname != NULL) { 21134 dns_message_puttempname(message, &tempname); 21135 } 21136 if (temprdataset != NULL) { 21137 dns_message_puttemprdataset(message, &temprdataset); 21138 } 21139 dns_message_detach(&message); 21140 return (result); 21141} 21142 21143static void 21144checkds_send_toaddr(isc_task_t *task, isc_event_t *event) { 21145 dns_checkds_t *checkds; 21146 isc_result_t result; 21147 dns_message_t *message = NULL; 21148 isc_netaddr_t dstip; 21149 dns_tsigkey_t *key = NULL; 21150 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 21151 isc_sockaddr_t src; 21152 unsigned int options, timeout; 21153 bool have_checkdssource = false; 21154 21155 checkds = event->ev_arg; 21156 REQUIRE(DNS_CHECKDS_VALID(checkds)); 21157 21158 UNUSED(task); 21159 21160 LOCK_ZONE(checkds->zone); 21161 21162 checkds->event = NULL; 21163 21164 if (DNS_ZONE_FLAG(checkds->zone, DNS_ZONEFLG_LOADED) == 0) { 21165 result = ISC_R_CANCELED; 21166 goto cleanup; 21167 } 21168 21169 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 || 21170 DNS_ZONE_FLAG(checkds->zone, DNS_ZONEFLG_EXITING) || 21171 checkds->zone->view->requestmgr == NULL || 21172 checkds->zone->db == NULL) 21173 { 21174 result = ISC_R_CANCELED; 21175 goto cleanup; 21176 } 21177 21178 /* 21179 * The raw IPv4 address should also exist. Don't send to the 21180 * mapped form. 21181 */ 21182 if (isc_sockaddr_pf(&checkds->dst) == PF_INET6 && 21183 IN6_IS_ADDR_V4MAPPED(&checkds->dst.type.sin6.sin6_addr)) 21184 { 21185 isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf)); 21186 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21187 "checkds: ignoring IPv6 mapped IPV4 address: %s", 21188 addrbuf); 21189 result = ISC_R_CANCELED; 21190 goto cleanup; 21191 } 21192 21193 result = checkds_createmessage(checkds->zone, &message); 21194 if (result != ISC_R_SUCCESS) { 21195 goto cleanup; 21196 } 21197 21198 isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf)); 21199 if (checkds->key != NULL) { 21200 /* Transfer ownership of key */ 21201 key = checkds->key; 21202 checkds->key = NULL; 21203 } else { 21204 isc_netaddr_fromsockaddr(&dstip, &checkds->dst); 21205 result = dns_view_getpeertsig(checkds->zone->view, &dstip, 21206 &key); 21207 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 21208 dns_zone_log(checkds->zone, ISC_LOG_ERROR, 21209 "checkds: DS query to %s not sent. " 21210 "Peer TSIG key lookup failure.", 21211 addrbuf); 21212 goto cleanup_message; 21213 } 21214 } 21215 21216 if (key != NULL) { 21217 char namebuf[DNS_NAME_FORMATSIZE]; 21218 21219 dns_name_format(&key->name, namebuf, sizeof(namebuf)); 21220 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21221 "checkds: sending DS query to %s : TSIG (%s)", 21222 addrbuf, namebuf); 21223 } else { 21224 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21225 "checkds: sending DS query to %s", addrbuf); 21226 } 21227 options = 0; 21228 if (checkds->zone->view->peers != NULL) { 21229 dns_peer_t *peer = NULL; 21230 bool usetcp = false; 21231 result = dns_peerlist_peerbyaddr(checkds->zone->view->peers, 21232 &dstip, &peer); 21233 if (result == ISC_R_SUCCESS) { 21234 result = dns_peer_getquerysource(peer, &src); 21235 if (result == ISC_R_SUCCESS) { 21236 have_checkdssource = true; 21237 } 21238 result = dns_peer_getforcetcp(peer, &usetcp); 21239 if (result == ISC_R_SUCCESS && usetcp) { 21240 options |= DNS_FETCHOPT_TCP; 21241 } 21242 } 21243 } 21244 switch (isc_sockaddr_pf(&checkds->dst)) { 21245 case PF_INET: 21246 if (!have_checkdssource) { 21247 src = checkds->zone->parentalsrc4; 21248 } 21249 break; 21250 case PF_INET6: 21251 if (!have_checkdssource) { 21252 src = checkds->zone->parentalsrc6; 21253 } 21254 break; 21255 default: 21256 result = ISC_R_NOTIMPLEMENTED; 21257 goto cleanup_key; 21258 } 21259 21260 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21261 "checkds: create request for DS query to %s", addrbuf); 21262 21263 timeout = 5; 21264 options |= DNS_REQUESTOPT_TCP; 21265 result = dns_request_create( 21266 checkds->zone->view->requestmgr, message, &src, &checkds->dst, 21267 options, key, timeout * 3 + 1, timeout, 2, checkds->zone->task, 21268 checkds_done, checkds, &checkds->request); 21269 if (result != ISC_R_SUCCESS) { 21270 dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3), 21271 "checkds: dns_request_create() to %s failed: %s", 21272 addrbuf, isc_result_totext(result)); 21273 } 21274 21275cleanup_key: 21276 if (key != NULL) { 21277 dns_tsigkey_detach(&key); 21278 } 21279cleanup_message: 21280 dns_message_detach(&message); 21281cleanup: 21282 UNLOCK_ZONE(checkds->zone); 21283 isc_event_free(&event); 21284 if (result != ISC_R_SUCCESS) { 21285 checkds_destroy(checkds, false); 21286 } 21287} 21288 21289static isc_result_t 21290checkds_send_queue(dns_checkds_t *checkds) { 21291 isc_event_t *e; 21292 isc_result_t result; 21293 21294 INSIST(checkds->event == NULL); 21295 e = isc_event_allocate(checkds->mctx, NULL, DNS_EVENT_CHECKDSSENDTOADDR, 21296 checkds_send_toaddr, checkds, 21297 sizeof(isc_event_t)); 21298 e->ev_arg = checkds; 21299 e->ev_sender = NULL; 21300 result = isc_ratelimiter_enqueue(checkds->zone->zmgr->checkdsrl, 21301 checkds->zone->task, &e); 21302 if (result != ISC_R_SUCCESS) { 21303 isc_event_free(&e); 21304 checkds->event = NULL; 21305 } 21306 return (result); 21307} 21308 21309static void 21310checkds_send(dns_zone_t *zone) { 21311 dns_view_t *view = dns_zone_getview(zone); 21312 isc_result_t result; 21313 unsigned int flags = 0; 21314 21315 /* 21316 * Zone lock held by caller. 21317 */ 21318 REQUIRE(LOCKED_ZONE(zone)); 21319 21320 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21321 "checkds: start sending DS queries to %u parentals", 21322 zone->parentalscnt); 21323 21324 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 21325 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21326 "checkds: abort, named exiting"); 21327 return; 21328 } 21329 21330 for (unsigned int i = 0; i < zone->parentalscnt; i++) { 21331 dns_tsigkey_t *key = NULL; 21332 dns_transport_t *transport = NULL; 21333 isc_sockaddr_t dst; 21334 dns_checkds_t *checkds = NULL; 21335 21336 if ((zone->parentalkeynames != NULL) && 21337 (zone->parentalkeynames[i] != NULL)) 21338 { 21339 dns_name_t *keyname = zone->parentalkeynames[i]; 21340 (void)dns_view_gettsig(view, keyname, &key); 21341 } 21342 21343 if ((zone->parentaltlsnames != NULL) && 21344 (zone->parentaltlsnames[i] != NULL)) 21345 { 21346 dns_name_t *tlsname = zone->parentaltlsnames[i]; 21347 (void)dns_view_gettransport(view, DNS_TRANSPORT_TLS, 21348 tlsname, &transport); 21349 dns_zone_logc( 21350 zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 21351 "got TLS configuration for zone transfer"); 21352 } 21353 21354 dst = zone->parentals[i]; 21355 21356 /* TODO: glue the transport to the checkds request */ 21357 21358 if (checkds_isqueued(zone, &dst, key, transport)) { 21359 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21360 "checkds: DS query to parent " 21361 "%d is queued", 21362 i); 21363 if (key != NULL) { 21364 dns_tsigkey_detach(&key); 21365 } 21366 if (transport != NULL) { 21367 dns_transport_detach(&transport); 21368 } 21369 continue; 21370 } 21371 21372 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21373 "checkds: create DS query for " 21374 "parent %d", 21375 i); 21376 21377 result = checkds_create(zone->mctx, flags, &checkds); 21378 if (result != ISC_R_SUCCESS) { 21379 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21380 "checkds: create DS query for " 21381 "parent %d failed", 21382 i); 21383 continue; 21384 } 21385 zone_iattach(zone, &checkds->zone); 21386 checkds->dst = dst; 21387 21388 INSIST(checkds->key == NULL); 21389 if (key != NULL) { 21390 checkds->key = key; 21391 key = NULL; 21392 } 21393 21394 INSIST(checkds->transport == NULL); 21395 if (transport != NULL) { 21396 checkds->transport = transport; 21397 transport = NULL; 21398 } 21399 21400 ISC_LIST_APPEND(zone->checkds_requests, checkds, link); 21401 result = checkds_send_queue(checkds); 21402 if (result != ISC_R_SUCCESS) { 21403 dns_zone_log(zone, ISC_LOG_DEBUG(3), 21404 "checkds: send DS query to " 21405 "parent %d failed", 21406 i); 21407 checkds_destroy(checkds, true); 21408 } 21409 } 21410} 21411 21412static void 21413zone_checkds(dns_zone_t *zone) { 21414 bool cdscheck = false; 21415 21416 for (dns_dnsseckey_t *key = ISC_LIST_HEAD(zone->checkds_ok); 21417 key != NULL; key = ISC_LIST_NEXT(key, link)) 21418 { 21419 dst_key_state_t ds_state = DST_KEY_STATE_NA; 21420 bool ksk = false; 21421 isc_stdtime_t published = 0, withdrawn = 0; 21422 21423 /* Is this key have the KSK role? */ 21424 (void)dst_key_role(key->key, &ksk, NULL); 21425 if (!ksk) { 21426 continue; 21427 } 21428 21429 /* Do we need to check the DS RRset? */ 21430 (void)dst_key_getstate(key->key, DST_KEY_DS, &ds_state); 21431 (void)dst_key_gettime(key->key, DST_TIME_DSPUBLISH, &published); 21432 (void)dst_key_gettime(key->key, DST_TIME_DSDELETE, &withdrawn); 21433 21434 if (ds_state == DST_KEY_STATE_RUMOURED && published == 0) { 21435 dst_key_setnum(key->key, DST_NUM_DSPUBCOUNT, 0); 21436 cdscheck = true; 21437 } else if (ds_state == DST_KEY_STATE_UNRETENTIVE && 21438 withdrawn == 0) 21439 { 21440 dst_key_setnum(key->key, DST_NUM_DSDELCOUNT, 0); 21441 cdscheck = true; 21442 } 21443 } 21444 21445 if (cdscheck) { 21446 /* Request the DS RRset. */ 21447 LOCK_ZONE(zone); 21448 checkds_send(zone); 21449 UNLOCK_ZONE(zone); 21450 } 21451} 21452 21453static void 21454zone_rekey(dns_zone_t *zone) { 21455 isc_result_t result; 21456 dns_db_t *db = NULL; 21457 dns_dbnode_t *node = NULL; 21458 dns_dbversion_t *ver = NULL; 21459 dns_rdataset_t cdsset, soaset, soasigs, keyset, keysigs, cdnskeyset; 21460 dns_dnsseckeylist_t dnskeys, keys, rmkeys; 21461 dns_dnsseckey_t *key = NULL; 21462 dns_diff_t diff, _sig_diff; 21463 dns_kasp_t *kasp; 21464 dns__zonediff_t zonediff; 21465 bool commit = false, newactive = false; 21466 bool newalg = false; 21467 bool fullsign; 21468 dns_ttl_t ttl = 3600; 21469 const char *dir = NULL; 21470 isc_mem_t *mctx = NULL; 21471 isc_stdtime_t now, nexttime = 0; 21472 isc_time_t timenow; 21473 isc_interval_t ival; 21474 char timebuf[80]; 21475 21476 REQUIRE(DNS_ZONE_VALID(zone)); 21477 21478 ISC_LIST_INIT(dnskeys); 21479 ISC_LIST_INIT(keys); 21480 ISC_LIST_INIT(rmkeys); 21481 dns_rdataset_init(&soaset); 21482 dns_rdataset_init(&soasigs); 21483 dns_rdataset_init(&keyset); 21484 dns_rdataset_init(&keysigs); 21485 dns_rdataset_init(&cdsset); 21486 dns_rdataset_init(&cdnskeyset); 21487 dir = dns_zone_getkeydirectory(zone); 21488 mctx = zone->mctx; 21489 dns_diff_init(mctx, &diff); 21490 dns_diff_init(mctx, &_sig_diff); 21491 zonediff_init(&zonediff, &_sig_diff); 21492 21493 CHECK(dns_zone_getdb(zone, &db)); 21494 CHECK(dns_db_newversion(db, &ver)); 21495 CHECK(dns_db_getoriginnode(db, &node)); 21496 21497 TIME_NOW(&timenow); 21498 now = isc_time_seconds(&timenow); 21499 21500 kasp = dns_zone_getkasp(zone); 21501 21502 dnssec_log(zone, ISC_LOG_INFO, "reconfiguring zone keys"); 21503 21504 /* Get the SOA record's TTL */ 21505 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 21506 dns_rdatatype_none, 0, &soaset, &soasigs)); 21507 ttl = soaset.ttl; 21508 dns_rdataset_disassociate(&soaset); 21509 21510 /* Get the DNSKEY rdataset */ 21511 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 21512 dns_rdatatype_none, 0, &keyset, &keysigs); 21513 if (result == ISC_R_SUCCESS) { 21514 ttl = keyset.ttl; 21515 21516 dns_zone_lock_keyfiles(zone); 21517 21518 result = dns_dnssec_keylistfromrdataset( 21519 &zone->origin, dir, mctx, &keyset, &keysigs, &soasigs, 21520 false, false, &dnskeys); 21521 21522 dns_zone_unlock_keyfiles(zone); 21523 21524 if (result != ISC_R_SUCCESS) { 21525 goto failure; 21526 } 21527 } else if (result != ISC_R_NOTFOUND) { 21528 goto failure; 21529 } 21530 21531 /* Get the CDS rdataset */ 21532 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cds, 21533 dns_rdatatype_none, 0, &cdsset, NULL); 21534 if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdsset)) { 21535 dns_rdataset_disassociate(&cdsset); 21536 } 21537 21538 /* Get the CDNSKEY rdataset */ 21539 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cdnskey, 21540 dns_rdatatype_none, 0, &cdnskeyset, NULL); 21541 if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdnskeyset)) { 21542 dns_rdataset_disassociate(&cdnskeyset); 21543 } 21544 21545 /* 21546 * True when called from "rndc sign". Indicates the zone should be 21547 * fully signed now. 21548 */ 21549 fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN); 21550 21551 KASP_LOCK(kasp); 21552 21553 dns_zone_lock_keyfiles(zone); 21554 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, now, mctx, 21555 &keys); 21556 dns_zone_unlock_keyfiles(zone); 21557 21558 if (result != ISC_R_SUCCESS) { 21559 dnssec_log(zone, ISC_LOG_DEBUG(1), 21560 "zone_rekey:dns_dnssec_findmatchingkeys failed: %s", 21561 isc_result_totext(result)); 21562 } 21563 21564 if (kasp != NULL) { 21565 /* 21566 * Check DS at parental agents. Clear ongoing checks. 21567 */ 21568 LOCK_ZONE(zone); 21569 checkds_cancel(zone); 21570 clear_keylist(&zone->checkds_ok, zone->mctx); 21571 ISC_LIST_INIT(zone->checkds_ok); 21572 UNLOCK_ZONE(zone); 21573 21574 result = dns_zone_getdnsseckeys(zone, db, ver, now, 21575 &zone->checkds_ok); 21576 21577 if (result == ISC_R_SUCCESS) { 21578 zone_checkds(zone); 21579 } else { 21580 dnssec_log(zone, 21581 (result == ISC_R_NOTFOUND) ? ISC_LOG_DEBUG(1) 21582 : ISC_LOG_ERROR, 21583 "zone_rekey:dns_zone_getdnsseckeys failed: " 21584 "%s", 21585 isc_result_totext(result)); 21586 } 21587 21588 if (result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND) { 21589 dns_zone_lock_keyfiles(zone); 21590 result = dns_keymgr_run(&zone->origin, zone->rdclass, 21591 dir, mctx, &keys, &dnskeys, 21592 kasp, now, &nexttime); 21593 dns_zone_unlock_keyfiles(zone); 21594 21595 if (result != ISC_R_SUCCESS) { 21596 dnssec_log(zone, ISC_LOG_ERROR, 21597 "zone_rekey:dns_dnssec_keymgr " 21598 "failed: %s", 21599 isc_result_totext(result)); 21600 KASP_UNLOCK(kasp); 21601 goto failure; 21602 } 21603 } 21604 } 21605 21606 KASP_UNLOCK(kasp); 21607 21608 if (result == ISC_R_SUCCESS) { 21609 bool cdsdel = false; 21610 bool cdnskeydel = false; 21611 bool sane_diff, sane_dnskey; 21612 isc_stdtime_t when; 21613 21614 /* 21615 * Publish CDS/CDNSKEY DELETE records if the zone is 21616 * transitioning from secure to insecure. 21617 */ 21618 if (kasp != NULL) { 21619 if (strcmp(dns_kasp_getname(kasp), "insecure") == 0) { 21620 cdsdel = true; 21621 cdnskeydel = true; 21622 } 21623 } else { 21624 /* Check if there is a CDS DELETE record. */ 21625 if (dns_rdataset_isassociated(&cdsset)) { 21626 for (result = dns_rdataset_first(&cdsset); 21627 result == ISC_R_SUCCESS; 21628 result = dns_rdataset_next(&cdsset)) 21629 { 21630 dns_rdata_t crdata = DNS_RDATA_INIT; 21631 dns_rdataset_current(&cdsset, &crdata); 21632 /* 21633 * CDS deletion record has this form 21634 * "0 0 0 00" which is 5 zero octets. 21635 */ 21636 if (crdata.length == 5U && 21637 memcmp(crdata.data, 21638 (unsigned char[5]){ 0, 0, 0, 21639 0, 0 }, 21640 5) == 0) 21641 { 21642 cdsdel = true; 21643 break; 21644 } 21645 } 21646 } 21647 21648 /* Check if there is a CDNSKEY DELETE record. */ 21649 if (dns_rdataset_isassociated(&cdnskeyset)) { 21650 for (result = dns_rdataset_first(&cdnskeyset); 21651 result == ISC_R_SUCCESS; 21652 result = dns_rdataset_next(&cdnskeyset)) 21653 { 21654 dns_rdata_t crdata = DNS_RDATA_INIT; 21655 dns_rdataset_current(&cdnskeyset, 21656 &crdata); 21657 /* 21658 * CDNSKEY deletion record has this form 21659 * "0 3 0 AA==" which is 2 zero octets, 21660 * a 3, and 2 zero octets. 21661 */ 21662 if (crdata.length == 5U && 21663 memcmp(crdata.data, 21664 (unsigned char[5]){ 0, 0, 3, 21665 0, 0 }, 21666 5) == 0) 21667 { 21668 cdnskeydel = true; 21669 break; 21670 } 21671 } 21672 } 21673 } 21674 21675 /* 21676 * Only update DNSKEY TTL if we have a policy. 21677 */ 21678 if (kasp != NULL) { 21679 ttl = dns_kasp_dnskeyttl(kasp); 21680 } 21681 21682 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys, 21683 &zone->origin, ttl, &diff, mctx, 21684 dnssec_report); 21685 /* 21686 * Keys couldn't be updated for some reason; 21687 * try again later. 21688 */ 21689 if (result != ISC_R_SUCCESS) { 21690 dnssec_log(zone, ISC_LOG_ERROR, 21691 "zone_rekey:couldn't update zone keys: %s", 21692 isc_result_totext(result)); 21693 goto failure; 21694 } 21695 21696 /* 21697 * Update CDS / CDNSKEY records. 21698 */ 21699 result = dns_dnssec_syncupdate(&dnskeys, &rmkeys, &cdsset, 21700 &cdnskeyset, now, ttl, &diff, 21701 mctx); 21702 if (result != ISC_R_SUCCESS) { 21703 dnssec_log(zone, ISC_LOG_ERROR, 21704 "zone_rekey:couldn't update CDS/CDNSKEY: %s", 21705 isc_result_totext(result)); 21706 goto failure; 21707 } 21708 21709 if (cdsdel || cdnskeydel) { 21710 /* 21711 * Only publish CDS/CDNSKEY DELETE records if there is 21712 * a KSK that can be used to verify the RRset. This 21713 * means there must be a key with the KSK role that is 21714 * published and is used for signing. 21715 */ 21716 bool allow = false; 21717 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 21718 key = ISC_LIST_NEXT(key, link)) 21719 { 21720 dst_key_t *dstk = key->key; 21721 21722 if (dst_key_is_published(dstk, now, &when) && 21723 dst_key_is_signing(dstk, DST_BOOL_KSK, now, 21724 &when)) 21725 { 21726 allow = true; 21727 break; 21728 } 21729 } 21730 if (cdsdel) { 21731 cdsdel = allow; 21732 } 21733 if (cdnskeydel) { 21734 cdnskeydel = allow; 21735 } 21736 } 21737 result = dns_dnssec_syncdelete( 21738 &cdsset, &cdnskeyset, &zone->origin, zone->rdclass, ttl, 21739 &diff, mctx, cdsdel, cdnskeydel); 21740 if (result != ISC_R_SUCCESS) { 21741 dnssec_log(zone, ISC_LOG_ERROR, 21742 "zone_rekey:couldn't update CDS/CDNSKEY " 21743 "DELETE records: %s", 21744 isc_result_totext(result)); 21745 goto failure; 21746 } 21747 21748 /* 21749 * See if any pre-existing keys have newly become active; 21750 * also, see if any new key is for a new algorithm, as in that 21751 * event, we need to sign the zone fully. (If there's a new 21752 * key, but it's for an already-existing algorithm, then 21753 * the zone signing can be handled incrementally.) 21754 */ 21755 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 21756 key = ISC_LIST_NEXT(key, link)) 21757 { 21758 if (!key->first_sign) { 21759 continue; 21760 } 21761 21762 newactive = true; 21763 21764 if (!dns_rdataset_isassociated(&keysigs)) { 21765 newalg = true; 21766 break; 21767 } 21768 21769 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) { 21770 /* 21771 * This isn't a new algorithm; clear 21772 * first_sign so we won't sign the 21773 * whole zone with this key later. 21774 */ 21775 key->first_sign = false; 21776 } else { 21777 newalg = true; 21778 break; 21779 } 21780 } 21781 21782 /* 21783 * A sane diff is one that is not empty, and that does not 21784 * introduce a zone with NSEC only DNSKEYs along with NSEC3 21785 * chains. 21786 */ 21787 sane_dnskey = dns_zone_check_dnskey_nsec3(zone, db, ver, &diff, 21788 NULL, 0); 21789 sane_diff = !ISC_LIST_EMPTY(diff.tuples) && sane_dnskey; 21790 if (!sane_dnskey) { 21791 dnssec_log(zone, ISC_LOG_ERROR, 21792 "NSEC only DNSKEYs and NSEC3 chains not " 21793 "allowed"); 21794 } 21795 21796 if (newactive || fullsign || sane_diff) { 21797 CHECK(dns_diff_apply(&diff, db, ver)); 21798 CHECK(clean_nsec3param(zone, db, ver, &diff)); 21799 CHECK(add_signing_records(db, zone->privatetype, ver, 21800 &diff, (newalg || fullsign))); 21801 CHECK(update_soa_serial(zone, db, ver, &diff, mctx, 21802 zone->updatemethod)); 21803 CHECK(add_chains(zone, db, ver, &diff)); 21804 CHECK(sign_apex(zone, db, ver, now, &diff, &zonediff)); 21805 CHECK(zone_journal(zone, zonediff.diff, NULL, 21806 "zone_rekey")); 21807 commit = true; 21808 } 21809 } 21810 21811 dns_db_closeversion(db, &ver, true); 21812 21813 LOCK_ZONE(zone); 21814 21815 if (commit) { 21816 dns_difftuple_t *tuple; 21817 dns_stats_t *dnssecsignstats = 21818 dns_zone_getdnssecsignstats(zone); 21819 21820 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 21821 21822 zone_needdump(zone, DNS_DUMP_DELAY); 21823 21824 zone_settimer(zone, &timenow); 21825 21826 /* Remove any signatures from removed keys. */ 21827 if (!ISC_LIST_EMPTY(rmkeys)) { 21828 for (key = ISC_LIST_HEAD(rmkeys); key != NULL; 21829 key = ISC_LIST_NEXT(key, link)) 21830 { 21831 result = zone_signwithkey( 21832 zone, dst_key_alg(key->key), 21833 dst_key_id(key->key), true); 21834 if (result != ISC_R_SUCCESS) { 21835 dnssec_log(zone, ISC_LOG_ERROR, 21836 "zone_signwithkey failed: " 21837 "%s", 21838 isc_result_totext(result)); 21839 } 21840 21841 /* Clear DNSSEC sign statistics. */ 21842 if (dnssecsignstats != NULL) { 21843 dns_dnssecsignstats_clear( 21844 dnssecsignstats, 21845 dst_key_id(key->key), 21846 dst_key_alg(key->key)); 21847 /* 21848 * Also clear the dnssec-sign 21849 * statistics of the revoked key id. 21850 */ 21851 dns_dnssecsignstats_clear( 21852 dnssecsignstats, 21853 dst_key_rid(key->key), 21854 dst_key_alg(key->key)); 21855 } 21856 } 21857 } 21858 21859 if (fullsign) { 21860 /* 21861 * "rndc sign" was called, so we now sign the zone 21862 * with all active keys, whether they're new or not. 21863 */ 21864 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 21865 key = ISC_LIST_NEXT(key, link)) 21866 { 21867 if (!key->force_sign && !key->hint_sign) { 21868 continue; 21869 } 21870 21871 result = zone_signwithkey( 21872 zone, dst_key_alg(key->key), 21873 dst_key_id(key->key), false); 21874 if (result != ISC_R_SUCCESS) { 21875 dnssec_log(zone, ISC_LOG_ERROR, 21876 "zone_signwithkey failed: " 21877 "%s", 21878 isc_result_totext(result)); 21879 } 21880 } 21881 } else if (newalg) { 21882 /* 21883 * We haven't been told to sign fully, but a new 21884 * algorithm was added to the DNSKEY. We sign 21885 * the full zone, but only with newly active 21886 * keys. 21887 */ 21888 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 21889 key = ISC_LIST_NEXT(key, link)) 21890 { 21891 if (!key->first_sign) { 21892 continue; 21893 } 21894 21895 result = zone_signwithkey( 21896 zone, dst_key_alg(key->key), 21897 dst_key_id(key->key), false); 21898 if (result != ISC_R_SUCCESS) { 21899 dnssec_log(zone, ISC_LOG_ERROR, 21900 "zone_signwithkey failed: " 21901 "%s", 21902 isc_result_totext(result)); 21903 } 21904 } 21905 } 21906 21907 /* 21908 * Clear fullsign flag, if it was set, so we don't do 21909 * another full signing next time. 21910 */ 21911 DNS_ZONEKEY_CLROPTION(zone, DNS_ZONEKEY_FULLSIGN); 21912 21913 /* 21914 * Cause the zone to add/delete NSEC3 chains for the 21915 * deferred NSEC3PARAM changes. 21916 */ 21917 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples); 21918 tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) 21919 { 21920 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 21921 dns_rdata_t rdata = DNS_RDATA_INIT; 21922 dns_rdata_nsec3param_t nsec3param; 21923 21924 if (tuple->rdata.type != zone->privatetype || 21925 tuple->op != DNS_DIFFOP_ADD) 21926 { 21927 continue; 21928 } 21929 21930 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata, 21931 buf, sizeof(buf))) 21932 { 21933 continue; 21934 } 21935 21936 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 21937 RUNTIME_CHECK(result == ISC_R_SUCCESS); 21938 if (nsec3param.flags == 0) { 21939 continue; 21940 } 21941 21942 result = zone_addnsec3chain(zone, &nsec3param); 21943 if (result != ISC_R_SUCCESS) { 21944 dnssec_log(zone, ISC_LOG_ERROR, 21945 "zone_addnsec3chain failed: %s", 21946 isc_result_totext(result)); 21947 } 21948 } 21949 21950 /* 21951 * Activate any NSEC3 chain updates that may have 21952 * been scheduled before this rekey. 21953 */ 21954 if (fullsign || newalg) { 21955 resume_addnsec3chain(zone); 21956 } 21957 21958 /* 21959 * Schedule the next resigning event 21960 */ 21961 set_resigntime(zone); 21962 } 21963 21964 isc_time_settoepoch(&zone->refreshkeytime); 21965 21966 /* 21967 * If keymgr provided a next time, use the calculated next rekey time. 21968 */ 21969 if (kasp != NULL) { 21970 isc_time_t timenext; 21971 uint32_t nexttime_seconds; 21972 21973 /* 21974 * Set the key refresh timer to the next scheduled key event 21975 * or to 'dnssec-loadkeys-interval' seconds in the future 21976 * if no next key event is scheduled (nexttime == 0). 21977 */ 21978 if (nexttime > 0) { 21979 nexttime_seconds = nexttime - now; 21980 } else { 21981 nexttime_seconds = zone->refreshkeyinterval; 21982 } 21983 21984 DNS_ZONE_TIME_ADD(&timenow, nexttime_seconds, &timenext); 21985 zone->refreshkeytime = timenext; 21986 zone_settimer(zone, &timenow); 21987 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 21988 21989 dnssec_log(zone, ISC_LOG_DEBUG(3), 21990 "next key event in %u seconds", nexttime_seconds); 21991 dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); 21992 } 21993 /* 21994 * If we're doing key maintenance, set the key refresh timer to 21995 * the next scheduled key event or to 'dnssec-loadkeys-interval' 21996 * seconds in the future, whichever is sooner. 21997 */ 21998 else if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 21999 { 22000 isc_time_t timethen; 22001 isc_stdtime_t then; 22002 22003 DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval, 22004 &timethen); 22005 zone->refreshkeytime = timethen; 22006 22007 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 22008 key = ISC_LIST_NEXT(key, link)) 22009 { 22010 then = now; 22011 result = next_keyevent(key->key, &then); 22012 if (result != ISC_R_SUCCESS) { 22013 continue; 22014 } 22015 22016 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 22017 if (isc_time_compare(&timethen, &zone->refreshkeytime) < 22018 0) 22019 { 22020 zone->refreshkeytime = timethen; 22021 } 22022 } 22023 22024 zone_settimer(zone, &timenow); 22025 22026 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 22027 dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); 22028 } 22029 UNLOCK_ZONE(zone); 22030 22031 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 22032 for (key = ISC_LIST_HEAD(dnskeys); key != NULL; 22033 key = ISC_LIST_NEXT(key, link)) 22034 { 22035 /* This debug log is used in the kasp system test */ 22036 char algbuf[DNS_SECALG_FORMATSIZE]; 22037 dns_secalg_format(dst_key_alg(key->key), algbuf, 22038 sizeof(algbuf)); 22039 dnssec_log(zone, ISC_LOG_DEBUG(3), 22040 "zone_rekey done: key %d/%s", 22041 dst_key_id(key->key), algbuf); 22042 } 22043 } 22044 22045 result = ISC_R_SUCCESS; 22046 22047failure: 22048 LOCK_ZONE(zone); 22049 if (result != ISC_R_SUCCESS) { 22050 /* 22051 * Something went wrong; try again in ten minutes or 22052 * after a key refresh interval, whichever is shorter. 22053 */ 22054 dnssec_log(zone, ISC_LOG_DEBUG(3), 22055 "zone_rekey failure: %s (retry in %u seconds)", 22056 isc_result_totext(result), 22057 ISC_MIN(zone->refreshkeyinterval, 600)); 22058 isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 22059 0); 22060 isc_time_nowplusinterval(&zone->refreshkeytime, &ival); 22061 } 22062 UNLOCK_ZONE(zone); 22063 22064 dns_diff_clear(&diff); 22065 dns_diff_clear(&_sig_diff); 22066 22067 clear_keylist(&dnskeys, mctx); 22068 clear_keylist(&keys, mctx); 22069 clear_keylist(&rmkeys, mctx); 22070 22071 if (ver != NULL) { 22072 dns_db_closeversion(db, &ver, false); 22073 } 22074 if (dns_rdataset_isassociated(&cdsset)) { 22075 dns_rdataset_disassociate(&cdsset); 22076 } 22077 if (dns_rdataset_isassociated(&keyset)) { 22078 dns_rdataset_disassociate(&keyset); 22079 } 22080 if (dns_rdataset_isassociated(&keysigs)) { 22081 dns_rdataset_disassociate(&keysigs); 22082 } 22083 if (dns_rdataset_isassociated(&soasigs)) { 22084 dns_rdataset_disassociate(&soasigs); 22085 } 22086 if (dns_rdataset_isassociated(&cdnskeyset)) { 22087 dns_rdataset_disassociate(&cdnskeyset); 22088 } 22089 if (node != NULL) { 22090 dns_db_detachnode(db, &node); 22091 } 22092 if (db != NULL) { 22093 dns_db_detach(&db); 22094 } 22095 22096 INSIST(ver == NULL); 22097} 22098 22099void 22100dns_zone_rekey(dns_zone_t *zone, bool fullsign) { 22101 isc_time_t now; 22102 22103 if (zone->type == dns_zone_primary && zone->task != NULL) { 22104 LOCK_ZONE(zone); 22105 22106 if (fullsign) { 22107 DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN); 22108 } 22109 22110 TIME_NOW(&now); 22111 zone->refreshkeytime = now; 22112 zone_settimer(zone, &now); 22113 22114 UNLOCK_ZONE(zone); 22115 } 22116} 22117 22118isc_result_t 22119dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 22120 unsigned int *errors) { 22121 isc_result_t result; 22122 dns_dbnode_t *node = NULL; 22123 22124 REQUIRE(DNS_ZONE_VALID(zone)); 22125 REQUIRE(errors != NULL); 22126 22127 result = dns_db_getoriginnode(db, &node); 22128 if (result != ISC_R_SUCCESS) { 22129 return (result); 22130 } 22131 result = zone_count_ns_rr(zone, db, node, version, NULL, errors, false); 22132 dns_db_detachnode(db, &node); 22133 return (result); 22134} 22135 22136isc_result_t 22137dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) { 22138 isc_result_t result; 22139 dns_dbnode_t *node = NULL; 22140 dns_rdataset_t dnskey, cds, cdnskey; 22141 unsigned char algorithms[256]; 22142 unsigned int i; 22143 bool empty = false; 22144 22145 enum { notexpected = 0, expected = 1, found = 2 }; 22146 22147 REQUIRE(DNS_ZONE_VALID(zone)); 22148 22149 result = dns_db_getoriginnode(db, &node); 22150 if (result != ISC_R_SUCCESS) { 22151 return (result); 22152 } 22153 22154 dns_rdataset_init(&cds); 22155 dns_rdataset_init(&dnskey); 22156 dns_rdataset_init(&cdnskey); 22157 22158 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds, 22159 dns_rdatatype_none, 0, &cds, NULL); 22160 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 22161 goto failure; 22162 } 22163 22164 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey, 22165 dns_rdatatype_none, 0, &cdnskey, NULL); 22166 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 22167 goto failure; 22168 } 22169 22170 if (!dns_rdataset_isassociated(&cds) && 22171 !dns_rdataset_isassociated(&cdnskey)) 22172 { 22173 result = ISC_R_SUCCESS; 22174 goto failure; 22175 } 22176 22177 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 22178 dns_rdatatype_none, 0, &dnskey, NULL); 22179 if (result == ISC_R_NOTFOUND) { 22180 empty = true; 22181 } else if (result != ISC_R_SUCCESS) { 22182 goto failure; 22183 } 22184 22185 /* 22186 * For each DNSSEC algorithm in the CDS RRset there must be 22187 * a matching DNSKEY record with the exception of a CDS deletion 22188 * record which must be by itself. 22189 */ 22190 if (dns_rdataset_isassociated(&cds)) { 22191 bool delete = false; 22192 memset(algorithms, notexpected, sizeof(algorithms)); 22193 for (result = dns_rdataset_first(&cds); result == ISC_R_SUCCESS; 22194 result = dns_rdataset_next(&cds)) 22195 { 22196 dns_rdata_t crdata = DNS_RDATA_INIT; 22197 dns_rdata_cds_t structcds; 22198 22199 dns_rdataset_current(&cds, &crdata); 22200 /* 22201 * CDS deletion record has this form "0 0 0 00" which 22202 * is 5 zero octets. 22203 */ 22204 if (crdata.length == 5U && 22205 memcmp(crdata.data, 22206 (unsigned char[5]){ 0, 0, 0, 0, 0 }, 5) == 0) 22207 { 22208 delete = true; 22209 continue; 22210 } 22211 22212 if (empty) { 22213 result = DNS_R_BADCDS; 22214 goto failure; 22215 } 22216 22217 CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL)); 22218 if (algorithms[structcds.algorithm] == 0) { 22219 algorithms[structcds.algorithm] = expected; 22220 } 22221 for (result = dns_rdataset_first(&dnskey); 22222 result == ISC_R_SUCCESS; 22223 result = dns_rdataset_next(&dnskey)) 22224 { 22225 dns_rdata_t rdata = DNS_RDATA_INIT; 22226 dns_rdata_dnskey_t structdnskey; 22227 22228 dns_rdataset_current(&dnskey, &rdata); 22229 CHECK(dns_rdata_tostruct(&rdata, &structdnskey, 22230 NULL)); 22231 22232 if (structdnskey.algorithm == 22233 structcds.algorithm) 22234 { 22235 algorithms[structcds.algorithm] = found; 22236 } 22237 } 22238 if (result != ISC_R_NOMORE) { 22239 goto failure; 22240 } 22241 } 22242 for (i = 0; i < sizeof(algorithms); i++) { 22243 if (delete) { 22244 if (algorithms[i] != notexpected) { 22245 result = DNS_R_BADCDS; 22246 goto failure; 22247 } 22248 } else if (algorithms[i] == expected) { 22249 result = DNS_R_BADCDS; 22250 goto failure; 22251 } 22252 } 22253 } 22254 22255 /* 22256 * For each DNSSEC algorithm in the CDNSKEY RRset there must be 22257 * a matching DNSKEY record with the exception of a CDNSKEY deletion 22258 * record which must be by itself. 22259 */ 22260 if (dns_rdataset_isassociated(&cdnskey)) { 22261 bool delete = false; 22262 memset(algorithms, notexpected, sizeof(algorithms)); 22263 for (result = dns_rdataset_first(&cdnskey); 22264 result == ISC_R_SUCCESS; 22265 result = dns_rdataset_next(&cdnskey)) 22266 { 22267 dns_rdata_t crdata = DNS_RDATA_INIT; 22268 dns_rdata_cdnskey_t structcdnskey; 22269 22270 dns_rdataset_current(&cdnskey, &crdata); 22271 /* 22272 * CDNSKEY deletion record has this form 22273 * "0 3 0 AA==" which is 2 zero octets, a 3, 22274 * and 2 zero octets. 22275 */ 22276 if (crdata.length == 5U && 22277 memcmp(crdata.data, 22278 (unsigned char[5]){ 0, 0, 3, 0, 0 }, 5) == 0) 22279 { 22280 delete = true; 22281 continue; 22282 } 22283 22284 if (empty) { 22285 result = DNS_R_BADCDNSKEY; 22286 goto failure; 22287 } 22288 22289 CHECK(dns_rdata_tostruct(&crdata, &structcdnskey, 22290 NULL)); 22291 if (algorithms[structcdnskey.algorithm] == 0) { 22292 algorithms[structcdnskey.algorithm] = expected; 22293 } 22294 for (result = dns_rdataset_first(&dnskey); 22295 result == ISC_R_SUCCESS; 22296 result = dns_rdataset_next(&dnskey)) 22297 { 22298 dns_rdata_t rdata = DNS_RDATA_INIT; 22299 dns_rdata_dnskey_t structdnskey; 22300 22301 dns_rdataset_current(&dnskey, &rdata); 22302 CHECK(dns_rdata_tostruct(&rdata, &structdnskey, 22303 NULL)); 22304 22305 if (structdnskey.algorithm == 22306 structcdnskey.algorithm) 22307 { 22308 algorithms[structcdnskey.algorithm] = 22309 found; 22310 } 22311 } 22312 if (result != ISC_R_NOMORE) { 22313 goto failure; 22314 } 22315 } 22316 for (i = 0; i < sizeof(algorithms); i++) { 22317 if (delete) { 22318 if (algorithms[i] != notexpected) { 22319 result = DNS_R_BADCDNSKEY; 22320 goto failure; 22321 } 22322 } else if (algorithms[i] == expected) { 22323 result = DNS_R_BADCDNSKEY; 22324 goto failure; 22325 } 22326 } 22327 } 22328 result = ISC_R_SUCCESS; 22329 22330failure: 22331 if (dns_rdataset_isassociated(&cds)) { 22332 dns_rdataset_disassociate(&cds); 22333 } 22334 if (dns_rdataset_isassociated(&dnskey)) { 22335 dns_rdataset_disassociate(&dnskey); 22336 } 22337 if (dns_rdataset_isassociated(&cdnskey)) { 22338 dns_rdataset_disassociate(&cdnskey); 22339 } 22340 dns_db_detachnode(db, &node); 22341 return (result); 22342} 22343 22344void 22345dns_zone_setautomatic(dns_zone_t *zone, bool automatic) { 22346 REQUIRE(DNS_ZONE_VALID(zone)); 22347 22348 LOCK_ZONE(zone); 22349 zone->automatic = automatic; 22350 UNLOCK_ZONE(zone); 22351} 22352 22353bool 22354dns_zone_getautomatic(dns_zone_t *zone) { 22355 REQUIRE(DNS_ZONE_VALID(zone)); 22356 return (zone->automatic); 22357} 22358 22359void 22360dns_zone_setadded(dns_zone_t *zone, bool added) { 22361 REQUIRE(DNS_ZONE_VALID(zone)); 22362 22363 LOCK_ZONE(zone); 22364 zone->added = added; 22365 UNLOCK_ZONE(zone); 22366} 22367 22368bool 22369dns_zone_getadded(dns_zone_t *zone) { 22370 REQUIRE(DNS_ZONE_VALID(zone)); 22371 return (zone->added); 22372} 22373 22374isc_result_t 22375dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db) { 22376 isc_time_t loadtime; 22377 isc_result_t result; 22378 dns_zone_t *secure = NULL; 22379 22380 TIME_NOW(&loadtime); 22381 22382 /* 22383 * Lock hierarchy: zmgr, zone, raw. 22384 */ 22385again: 22386 LOCK_ZONE(zone); 22387 INSIST(zone != zone->raw); 22388 if (inline_secure(zone)) { 22389 LOCK_ZONE(zone->raw); 22390 } else if (inline_raw(zone)) { 22391 secure = zone->secure; 22392 TRYLOCK_ZONE(result, secure); 22393 if (result != ISC_R_SUCCESS) { 22394 UNLOCK_ZONE(zone); 22395 secure = NULL; 22396 isc_thread_yield(); 22397 goto again; 22398 } 22399 } 22400 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 22401 if (inline_secure(zone)) { 22402 UNLOCK_ZONE(zone->raw); 22403 } else if (secure != NULL) { 22404 UNLOCK_ZONE(secure); 22405 } 22406 UNLOCK_ZONE(zone); 22407 return (result); 22408} 22409 22410isc_result_t 22411dns_zone_setrefreshkeyinterval(dns_zone_t *zone, uint32_t interval) { 22412 REQUIRE(DNS_ZONE_VALID(zone)); 22413 if (interval == 0) { 22414 return (ISC_R_RANGE); 22415 } 22416 /* Maximum value: 24 hours (3600 minutes) */ 22417 if (interval > (24 * 60)) { 22418 interval = (24 * 60); 22419 } 22420 /* Multiply by 60 for seconds */ 22421 zone->refreshkeyinterval = interval * 60; 22422 return (ISC_R_SUCCESS); 22423} 22424 22425void 22426dns_zone_setrequestixfr(dns_zone_t *zone, bool flag) { 22427 REQUIRE(DNS_ZONE_VALID(zone)); 22428 zone->requestixfr = flag; 22429} 22430 22431bool 22432dns_zone_getrequestixfr(dns_zone_t *zone) { 22433 REQUIRE(DNS_ZONE_VALID(zone)); 22434 return (zone->requestixfr); 22435} 22436 22437void 22438dns_zone_setixfrratio(dns_zone_t *zone, uint32_t ratio) { 22439 REQUIRE(DNS_ZONE_VALID(zone)); 22440 zone->ixfr_ratio = ratio; 22441} 22442 22443uint32_t 22444dns_zone_getixfrratio(dns_zone_t *zone) { 22445 REQUIRE(DNS_ZONE_VALID(zone)); 22446 return (zone->ixfr_ratio); 22447} 22448 22449void 22450dns_zone_setrequestexpire(dns_zone_t *zone, bool flag) { 22451 REQUIRE(DNS_ZONE_VALID(zone)); 22452 zone->requestexpire = flag; 22453} 22454 22455bool 22456dns_zone_getrequestexpire(dns_zone_t *zone) { 22457 REQUIRE(DNS_ZONE_VALID(zone)); 22458 return (zone->requestexpire); 22459} 22460 22461void 22462dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) { 22463 REQUIRE(DNS_ZONE_VALID(zone)); 22464 zone->updatemethod = method; 22465} 22466 22467dns_updatemethod_t 22468dns_zone_getserialupdatemethod(dns_zone_t *zone) { 22469 REQUIRE(DNS_ZONE_VALID(zone)); 22470 return (zone->updatemethod); 22471} 22472 22473/* 22474 * Lock hierarchy: zmgr, zone, raw. 22475 */ 22476isc_result_t 22477dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) { 22478 isc_result_t result; 22479 dns_zonemgr_t *zmgr; 22480 22481 REQUIRE(DNS_ZONE_VALID(zone)); 22482 REQUIRE(zone->zmgr != NULL); 22483 REQUIRE(zone->task != NULL); 22484 REQUIRE(zone->loadtask != NULL); 22485 REQUIRE(zone->raw == NULL); 22486 22487 REQUIRE(DNS_ZONE_VALID(raw)); 22488 REQUIRE(raw->zmgr == NULL); 22489 REQUIRE(raw->task == NULL); 22490 REQUIRE(raw->loadtask == NULL); 22491 REQUIRE(raw->secure == NULL); 22492 22493 REQUIRE(zone != raw); 22494 22495 /* 22496 * Lock hierarchy: zmgr, zone, raw. 22497 */ 22498 zmgr = zone->zmgr; 22499 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 22500 LOCK_ZONE(zone); 22501 LOCK_ZONE(raw); 22502 22503 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL, 22504 NULL, zone->task, zone_timer, raw, 22505 &raw->timer); 22506 if (result != ISC_R_SUCCESS) { 22507 goto unlock; 22508 } 22509 22510 /* 22511 * The timer "holds" a iref. 22512 */ 22513 isc_refcount_increment0(&raw->irefs); 22514 22515 /* dns_zone_attach(raw, &zone->raw); */ 22516 isc_refcount_increment(&raw->erefs); 22517 zone->raw = raw; 22518 22519 /* dns_zone_iattach(zone, &raw->secure); */ 22520 zone_iattach(zone, &raw->secure); 22521 22522 isc_task_attach(zone->task, &raw->task); 22523 isc_task_attach(zone->loadtask, &raw->loadtask); 22524 22525 ISC_LIST_APPEND(zmgr->zones, raw, link); 22526 raw->zmgr = zmgr; 22527 isc_refcount_increment(&zmgr->refs); 22528 22529unlock: 22530 UNLOCK_ZONE(raw); 22531 UNLOCK_ZONE(zone); 22532 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 22533 return (result); 22534} 22535 22536void 22537dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) { 22538 REQUIRE(DNS_ZONE_VALID(zone)); 22539 REQUIRE(raw != NULL && *raw == NULL); 22540 22541 LOCK(&zone->lock); 22542 INSIST(zone != zone->raw); 22543 if (zone->raw != NULL) { 22544 dns_zone_attach(zone->raw, raw); 22545 } 22546 UNLOCK(&zone->lock); 22547} 22548 22549struct keydone { 22550 isc_event_t event; 22551 bool all; 22552 unsigned char data[5]; 22553}; 22554 22555#define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL) 22556 22557static void 22558keydone(isc_task_t *task, isc_event_t *event) { 22559 const char *me = "keydone"; 22560 bool commit = false; 22561 isc_result_t result; 22562 dns_rdata_t rdata = DNS_RDATA_INIT; 22563 dns_dbversion_t *oldver = NULL, *newver = NULL; 22564 dns_zone_t *zone; 22565 dns_db_t *db = NULL; 22566 dns_dbnode_t *node = NULL; 22567 dns_rdataset_t rdataset; 22568 dns_diff_t diff; 22569 struct keydone *kd = (struct keydone *)event; 22570 dns_update_log_t log = { update_log_cb, NULL }; 22571 bool clear_pending = false; 22572 22573 UNUSED(task); 22574 22575 zone = event->ev_arg; 22576 INSIST(DNS_ZONE_VALID(zone)); 22577 22578 ENTER; 22579 22580 dns_rdataset_init(&rdataset); 22581 dns_diff_init(zone->mctx, &diff); 22582 22583 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 22584 if (zone->db != NULL) { 22585 dns_db_attach(zone->db, &db); 22586 } 22587 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 22588 if (db == NULL) { 22589 goto failure; 22590 } 22591 22592 dns_db_currentversion(db, &oldver); 22593 result = dns_db_newversion(db, &newver); 22594 if (result != ISC_R_SUCCESS) { 22595 dnssec_log(zone, ISC_LOG_ERROR, 22596 "keydone:dns_db_newversion -> %s", 22597 isc_result_totext(result)); 22598 goto failure; 22599 } 22600 22601 result = dns_db_getoriginnode(db, &node); 22602 if (result != ISC_R_SUCCESS) { 22603 goto failure; 22604 } 22605 22606 result = dns_db_findrdataset(db, node, newver, zone->privatetype, 22607 dns_rdatatype_none, 0, &rdataset, NULL); 22608 if (result == ISC_R_NOTFOUND) { 22609 INSIST(!dns_rdataset_isassociated(&rdataset)); 22610 goto failure; 22611 } 22612 if (result != ISC_R_SUCCESS) { 22613 INSIST(!dns_rdataset_isassociated(&rdataset)); 22614 goto failure; 22615 } 22616 22617 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 22618 result = dns_rdataset_next(&rdataset)) 22619 { 22620 bool found = false; 22621 22622 dns_rdataset_current(&rdataset, &rdata); 22623 22624 if (kd->all) { 22625 if (rdata.length == 5 && rdata.data[0] != 0 && 22626 rdata.data[3] == 0 && rdata.data[4] == 1) 22627 { 22628 found = true; 22629 } else if (rdata.data[0] == 0 && 22630 (rdata.data[2] & PENDINGFLAGS) != 0) 22631 { 22632 found = true; 22633 clear_pending = true; 22634 } 22635 } else if (rdata.length == 5 && 22636 memcmp(rdata.data, kd->data, 5) == 0) 22637 { 22638 found = true; 22639 } 22640 22641 if (found) { 22642 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL, 22643 &zone->origin, rdataset.ttl, 22644 &rdata)); 22645 } 22646 dns_rdata_reset(&rdata); 22647 } 22648 22649 if (!ISC_LIST_EMPTY(diff.tuples)) { 22650 /* Write changes to journal file. */ 22651 CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx, 22652 zone->updatemethod)); 22653 22654 result = dns_update_signatures(&log, zone, db, oldver, newver, 22655 &diff, 22656 zone->sigvalidityinterval); 22657 if (!clear_pending) { 22658 CHECK(result); 22659 } 22660 22661 CHECK(zone_journal(zone, &diff, NULL, "keydone")); 22662 commit = true; 22663 22664 LOCK_ZONE(zone); 22665 DNS_ZONE_SETFLAG(zone, 22666 DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY); 22667 zone_needdump(zone, 30); 22668 UNLOCK_ZONE(zone); 22669 } 22670 22671failure: 22672 if (dns_rdataset_isassociated(&rdataset)) { 22673 dns_rdataset_disassociate(&rdataset); 22674 } 22675 if (db != NULL) { 22676 if (node != NULL) { 22677 dns_db_detachnode(db, &node); 22678 } 22679 if (oldver != NULL) { 22680 dns_db_closeversion(db, &oldver, false); 22681 } 22682 if (newver != NULL) { 22683 dns_db_closeversion(db, &newver, commit); 22684 } 22685 dns_db_detach(&db); 22686 } 22687 dns_diff_clear(&diff); 22688 isc_event_free(&event); 22689 dns_zone_idetach(&zone); 22690 22691 INSIST(oldver == NULL); 22692 INSIST(newver == NULL); 22693} 22694 22695isc_result_t 22696dns_zone_keydone(dns_zone_t *zone, const char *keystr) { 22697 isc_result_t result = ISC_R_SUCCESS; 22698 isc_event_t *e; 22699 isc_buffer_t b; 22700 dns_zone_t *dummy = NULL; 22701 struct keydone *kd; 22702 22703 REQUIRE(DNS_ZONE_VALID(zone)); 22704 22705 LOCK_ZONE(zone); 22706 22707 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone, 22708 zone, sizeof(struct keydone)); 22709 22710 kd = (struct keydone *)e; 22711 if (strcasecmp(keystr, "all") == 0) { 22712 kd->all = true; 22713 } else { 22714 isc_textregion_t r; 22715 const char *algstr; 22716 dns_keytag_t keyid; 22717 dns_secalg_t alg; 22718 size_t n; 22719 22720 kd->all = false; 22721 22722 n = sscanf(keystr, "%hu/", &keyid); 22723 if (n == 0U) { 22724 CHECK(ISC_R_FAILURE); 22725 } 22726 22727 algstr = strchr(keystr, '/'); 22728 if (algstr != NULL) { 22729 algstr++; 22730 } else { 22731 CHECK(ISC_R_FAILURE); 22732 } 22733 22734 n = sscanf(algstr, "%hhu", &alg); 22735 if (n == 0U) { 22736 DE_CONST(algstr, r.base); 22737 r.length = strlen(algstr); 22738 CHECK(dns_secalg_fromtext(&alg, &r)); 22739 } 22740 22741 /* construct a private-type rdata */ 22742 isc_buffer_init(&b, kd->data, sizeof(kd->data)); 22743 isc_buffer_putuint8(&b, alg); 22744 isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8); 22745 isc_buffer_putuint8(&b, (keyid & 0xff)); 22746 isc_buffer_putuint8(&b, 0); 22747 isc_buffer_putuint8(&b, 1); 22748 } 22749 22750 zone_iattach(zone, &dummy); 22751 isc_task_send(zone->task, &e); 22752 22753failure: 22754 if (e != NULL) { 22755 isc_event_free(&e); 22756 } 22757 UNLOCK_ZONE(zone); 22758 return (result); 22759} 22760 22761/* 22762 * Called from the zone task's queue after the relevant event is posted by 22763 * dns_zone_setnsec3param(). 22764 */ 22765static void 22766setnsec3param(isc_task_t *task, isc_event_t *event) { 22767 const char *me = "setnsec3param"; 22768 dns_zone_t *zone = event->ev_arg; 22769 bool loadpending; 22770 22771 INSIST(DNS_ZONE_VALID(zone)); 22772 22773 UNUSED(task); 22774 22775 ENTER; 22776 22777 LOCK_ZONE(zone); 22778 loadpending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING); 22779 UNLOCK_ZONE(zone); 22780 22781 /* 22782 * If receive_secure_serial is still processing or we have a 22783 * queued event append rss_post queue. 22784 */ 22785 if (zone->rss_newver != NULL || ISC_LIST_HEAD(zone->rss_post) != NULL) { 22786 /* 22787 * Wait for receive_secure_serial() to finish processing. 22788 */ 22789 ISC_LIST_APPEND(zone->rss_post, event, ev_link); 22790 } else { 22791 bool rescheduled = false; 22792 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 22793 /* 22794 * The zone is not yet fully loaded. Reschedule the event to 22795 * be picked up later. This turns this function into a busy 22796 * wait, but it only happens at startup. 22797 */ 22798 if (zone->db == NULL && loadpending) { 22799 rescheduled = true; 22800 isc_task_send(task, &event); 22801 } 22802 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 22803 if (rescheduled) { 22804 return; 22805 } 22806 22807 rss_post(zone, event); 22808 } 22809 dns_zone_idetach(&zone); 22810} 22811 22812static void 22813salt2text(unsigned char *salt, uint8_t saltlen, unsigned char *text, 22814 unsigned int textlen) { 22815 isc_region_t r; 22816 isc_buffer_t buf; 22817 isc_result_t result; 22818 22819 r.base = salt; 22820 r.length = (unsigned int)saltlen; 22821 22822 isc_buffer_init(&buf, text, textlen); 22823 result = isc_hex_totext(&r, 2, "", &buf); 22824 if (result == ISC_R_SUCCESS) { 22825 text[saltlen * 2] = 0; 22826 } else { 22827 text[0] = 0; 22828 } 22829} 22830 22831/* 22832 * Check whether NSEC3 chain addition or removal specified by the private-type 22833 * record passed with the event was already queued (or even fully performed). 22834 * If not, modify the relevant private-type records at the zone apex and call 22835 * resume_addnsec3chain(). 22836 */ 22837static void 22838rss_post(dns_zone_t *zone, isc_event_t *event) { 22839 const char *me = "rss_post"; 22840 bool commit = false; 22841 isc_result_t result; 22842 dns_dbversion_t *oldver = NULL, *newver = NULL; 22843 dns_db_t *db = NULL; 22844 dns_dbnode_t *node = NULL; 22845 dns_rdataset_t prdataset, nrdataset; 22846 dns_diff_t diff; 22847 struct np3event *npe = (struct np3event *)event; 22848 nsec3param_t *np; 22849 dns_update_log_t log = { update_log_cb, NULL }; 22850 dns_rdata_t rdata; 22851 bool nseconly; 22852 bool exists = false; 22853 22854 ENTER; 22855 22856 np = &npe->params; 22857 22858 dns_rdataset_init(&prdataset); 22859 dns_rdataset_init(&nrdataset); 22860 dns_diff_init(zone->mctx, &diff); 22861 22862 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 22863 if (zone->db != NULL) { 22864 dns_db_attach(zone->db, &db); 22865 } 22866 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 22867 if (db == NULL) { 22868 goto failure; 22869 } 22870 22871 dns_db_currentversion(db, &oldver); 22872 result = dns_db_newversion(db, &newver); 22873 if (result != ISC_R_SUCCESS) { 22874 dnssec_log(zone, ISC_LOG_ERROR, 22875 "setnsec3param:dns_db_newversion -> %s", 22876 isc_result_totext(result)); 22877 goto failure; 22878 } 22879 22880 CHECK(dns_db_getoriginnode(db, &node)); 22881 22882 /* 22883 * Do we need to look up the NSEC3 parameters? 22884 */ 22885 if (np->lookup) { 22886 dns_rdata_nsec3param_t param; 22887 dns_rdata_t nrdata = DNS_RDATA_INIT; 22888 dns_rdata_t prdata = DNS_RDATA_INIT; 22889 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE]; 22890 unsigned char saltbuf[255]; 22891 isc_buffer_t b; 22892 22893 param.salt = NULL; 22894 result = dns__zone_lookup_nsec3param(zone, &np->rdata, ¶m, 22895 saltbuf, np->resalt); 22896 if (result == ISC_R_SUCCESS) { 22897 /* 22898 * Success because the NSEC3PARAM already exists, but 22899 * function returns void, so goto failure to clean up. 22900 */ 22901 goto failure; 22902 } 22903 if (result != DNS_R_NSEC3RESALT && result != ISC_R_NOTFOUND) { 22904 dnssec_log(zone, ISC_LOG_DEBUG(3), 22905 "setnsec3param:lookup nsec3param -> %s", 22906 isc_result_totext(result)); 22907 goto failure; 22908 } 22909 22910 INSIST(param.salt != NULL); 22911 22912 /* Update NSEC3 parameters. */ 22913 np->rdata.hash = param.hash; 22914 np->rdata.flags = param.flags; 22915 np->rdata.iterations = param.iterations; 22916 np->rdata.salt_length = param.salt_length; 22917 np->rdata.salt = param.salt; 22918 22919 isc_buffer_init(&b, nbuf, sizeof(nbuf)); 22920 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass, 22921 dns_rdatatype_nsec3param, &np->rdata, 22922 &b)); 22923 dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype, 22924 np->data, sizeof(np->data)); 22925 np->length = prdata.length; 22926 np->nsec = false; 22927 } 22928 22929 /* 22930 * Does a private-type record already exist for this chain? 22931 */ 22932 result = dns_db_findrdataset(db, node, newver, zone->privatetype, 22933 dns_rdatatype_none, 0, &prdataset, NULL); 22934 if (result == ISC_R_SUCCESS) { 22935 for (result = dns_rdataset_first(&prdataset); 22936 result == ISC_R_SUCCESS; 22937 result = dns_rdataset_next(&prdataset)) 22938 { 22939 dns_rdata_init(&rdata); 22940 dns_rdataset_current(&prdataset, &rdata); 22941 22942 if (np->length == rdata.length && 22943 memcmp(rdata.data, np->data, np->length) == 0) 22944 { 22945 exists = true; 22946 break; 22947 } 22948 } 22949 } else if (result != ISC_R_NOTFOUND) { 22950 INSIST(!dns_rdataset_isassociated(&prdataset)); 22951 goto failure; 22952 } 22953 22954 /* 22955 * Does the chain already exist? 22956 */ 22957 result = dns_db_findrdataset(db, node, newver, dns_rdatatype_nsec3param, 22958 dns_rdatatype_none, 0, &nrdataset, NULL); 22959 if (result == ISC_R_SUCCESS) { 22960 for (result = dns_rdataset_first(&nrdataset); 22961 result == ISC_R_SUCCESS; 22962 result = dns_rdataset_next(&nrdataset)) 22963 { 22964 dns_rdata_init(&rdata); 22965 dns_rdataset_current(&nrdataset, &rdata); 22966 22967 if (np->length == (rdata.length + 1) && 22968 memcmp(rdata.data, np->data + 1, np->length - 1) == 22969 0) 22970 { 22971 exists = true; 22972 break; 22973 } 22974 } 22975 } else if (result != ISC_R_NOTFOUND) { 22976 INSIST(!dns_rdataset_isassociated(&nrdataset)); 22977 goto failure; 22978 } 22979 22980 /* 22981 * We need to remove any existing NSEC3 chains if the supplied NSEC3 22982 * parameters are supposed to replace the current ones or if we are 22983 * switching to NSEC. 22984 */ 22985 if (!exists && np->replace && (np->length != 0 || np->nsec)) { 22986 CHECK(dns_nsec3param_deletechains(db, newver, zone, !np->nsec, 22987 &diff)); 22988 } 22989 22990 if (!exists && np->length != 0) { 22991 /* 22992 * We're creating an NSEC3 chain. Add the private-type record 22993 * passed in the event handler's argument to the zone apex. 22994 * 22995 * If the zone is not currently capable of supporting an NSEC3 22996 * chain (due to the DNSKEY RRset at the zone apex not existing 22997 * or containing at least one key using an NSEC-only 22998 * algorithm), add the INITIAL flag, so these parameters can be 22999 * used later when NSEC3 becomes available. 23000 */ 23001 dns_rdata_init(&rdata); 23002 23003 np->data[2] |= DNS_NSEC3FLAG_CREATE; 23004 result = dns_nsec_nseconly(db, newver, NULL, &nseconly); 23005 if (result == ISC_R_NOTFOUND || nseconly) { 23006 np->data[2] |= DNS_NSEC3FLAG_INITIAL; 23007 } 23008 23009 rdata.length = np->length; 23010 rdata.data = np->data; 23011 rdata.type = zone->privatetype; 23012 rdata.rdclass = zone->rdclass; 23013 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD, 23014 &zone->origin, 0, &rdata)); 23015 } 23016 23017 /* 23018 * If we changed anything in the zone, write changes to journal file 23019 * and set commit to true so that resume_addnsec3chain() will be 23020 * called below in order to kick off adding/removing relevant NSEC3 23021 * records. 23022 */ 23023 if (!ISC_LIST_EMPTY(diff.tuples)) { 23024 CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx, 23025 zone->updatemethod)); 23026 result = dns_update_signatures(&log, zone, db, oldver, newver, 23027 &diff, 23028 zone->sigvalidityinterval); 23029 if (result != ISC_R_NOTFOUND) { 23030 CHECK(result); 23031 } 23032 CHECK(zone_journal(zone, &diff, NULL, "setnsec3param")); 23033 commit = true; 23034 23035 LOCK_ZONE(zone); 23036 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 23037 zone_needdump(zone, 30); 23038 UNLOCK_ZONE(zone); 23039 } 23040 23041failure: 23042 if (dns_rdataset_isassociated(&prdataset)) { 23043 dns_rdataset_disassociate(&prdataset); 23044 } 23045 if (dns_rdataset_isassociated(&nrdataset)) { 23046 dns_rdataset_disassociate(&nrdataset); 23047 } 23048 if (node != NULL) { 23049 dns_db_detachnode(db, &node); 23050 } 23051 if (oldver != NULL) { 23052 dns_db_closeversion(db, &oldver, false); 23053 } 23054 if (newver != NULL) { 23055 dns_db_closeversion(db, &newver, commit); 23056 } 23057 if (db != NULL) { 23058 dns_db_detach(&db); 23059 } 23060 if (commit) { 23061 LOCK_ZONE(zone); 23062 resume_addnsec3chain(zone); 23063 UNLOCK_ZONE(zone); 23064 } 23065 dns_diff_clear(&diff); 23066 isc_event_free(&event); 23067 23068 INSIST(oldver == NULL); 23069 INSIST(newver == NULL); 23070} 23071 23072/* 23073 * Check if zone has NSEC3PARAM (and thus a chain) with the right parameters. 23074 * 23075 * If 'salt' is NULL, a match is found if the salt has the requested length, 23076 * otherwise the NSEC3 salt must match the requested salt value too. 23077 * 23078 * Returns ISC_R_SUCCESS, if a match is found, or an error if no match is 23079 * found, or if the db lookup failed. 23080 */ 23081isc_result_t 23082dns__zone_lookup_nsec3param(dns_zone_t *zone, dns_rdata_nsec3param_t *lookup, 23083 dns_rdata_nsec3param_t *param, 23084 unsigned char saltbuf[255], bool resalt) { 23085 isc_result_t result = ISC_R_UNEXPECTED; 23086 dns_dbnode_t *node = NULL; 23087 dns_db_t *db = NULL; 23088 dns_dbversion_t *version = NULL; 23089 dns_rdataset_t rdataset; 23090 dns_rdata_nsec3param_t nsec3param; 23091 dns_rdata_t rdata = DNS_RDATA_INIT; 23092 23093 REQUIRE(DNS_ZONE_VALID(zone)); 23094 23095 dns_rdataset_init(&rdataset); 23096 23097 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 23098 if (zone->db != NULL) { 23099 dns_db_attach(zone->db, &db); 23100 } 23101 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 23102 if (db == NULL) { 23103 result = ISC_R_FAILURE; 23104 goto setparam; 23105 } 23106 23107 result = dns_db_findnode(db, &zone->origin, false, &node); 23108 if (result != ISC_R_SUCCESS) { 23109 dns_zone_log(zone, ISC_LOG_ERROR, 23110 "dns__zone_lookup_nsec3param:" 23111 "dns_db_findnode -> %s", 23112 isc_result_totext(result)); 23113 result = ISC_R_FAILURE; 23114 goto setparam; 23115 } 23116 dns_db_currentversion(db, &version); 23117 23118 result = dns_db_findrdataset(db, node, version, 23119 dns_rdatatype_nsec3param, 23120 dns_rdatatype_none, 0, &rdataset, NULL); 23121 if (result != ISC_R_SUCCESS) { 23122 INSIST(!dns_rdataset_isassociated(&rdataset)); 23123 if (result != ISC_R_NOTFOUND) { 23124 dns_zone_log(zone, ISC_LOG_ERROR, 23125 "dns__zone_lookup_nsec3param:" 23126 "dns_db_findrdataset -> %s", 23127 isc_result_totext(result)); 23128 } 23129 goto setparam; 23130 } 23131 23132 for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; 23133 result = dns_rdataset_next(&rdataset)) 23134 { 23135 dns_rdataset_current(&rdataset, &rdata); 23136 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 23137 INSIST(result == ISC_R_SUCCESS); 23138 dns_rdata_reset(&rdata); 23139 23140 /* Check parameters. */ 23141 if (nsec3param.hash != lookup->hash) { 23142 continue; 23143 } 23144 if (nsec3param.iterations != lookup->iterations) { 23145 continue; 23146 } 23147 if (nsec3param.salt_length != lookup->salt_length) { 23148 continue; 23149 } 23150 if (lookup->salt != NULL) { 23151 if (memcmp(nsec3param.salt, lookup->salt, 23152 lookup->salt_length) != 0) 23153 { 23154 continue; 23155 } 23156 } 23157 /* Found a match. */ 23158 result = ISC_R_SUCCESS; 23159 param->hash = nsec3param.hash; 23160 param->flags = nsec3param.flags; 23161 param->iterations = nsec3param.iterations; 23162 param->salt_length = nsec3param.salt_length; 23163 param->salt = nsec3param.salt; 23164 break; 23165 } 23166 23167 if (result == ISC_R_NOMORE) { 23168 result = ISC_R_NOTFOUND; 23169 } 23170 23171setparam: 23172 if (result != ISC_R_SUCCESS) { 23173 /* Found no match. */ 23174 param->hash = lookup->hash; 23175 param->flags = lookup->flags; 23176 param->iterations = lookup->iterations; 23177 param->salt_length = lookup->salt_length; 23178 param->salt = lookup->salt; 23179 } 23180 23181 if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) { 23182 goto failure; 23183 } 23184 23185 if (param->salt_length == 0) { 23186 DE_CONST("-", param->salt); 23187 } else if (resalt || param->salt == NULL) { 23188 unsigned char *newsalt; 23189 unsigned char salttext[255 * 2 + 1]; 23190 do { 23191 /* Generate a new salt. */ 23192 result = dns_nsec3_generate_salt(saltbuf, 23193 param->salt_length); 23194 if (result != ISC_R_SUCCESS) { 23195 break; 23196 } 23197 newsalt = saltbuf; 23198 salt2text(newsalt, param->salt_length, salttext, 23199 sizeof(salttext)); 23200 dnssec_log(zone, ISC_LOG_INFO, "generated salt: %s", 23201 salttext); 23202 /* Check for salt conflict. */ 23203 if (param->salt != NULL && 23204 memcmp(newsalt, param->salt, param->salt_length) == 23205 0) 23206 { 23207 result = ISC_R_SUCCESS; 23208 } else { 23209 param->salt = newsalt; 23210 result = DNS_R_NSEC3RESALT; 23211 } 23212 } while (result == ISC_R_SUCCESS); 23213 23214 INSIST(result != ISC_R_SUCCESS); 23215 } 23216 23217failure: 23218 if (dns_rdataset_isassociated(&rdataset)) { 23219 dns_rdataset_disassociate(&rdataset); 23220 } 23221 if (node != NULL) { 23222 dns_db_detachnode(db, &node); 23223 } 23224 if (version != NULL) { 23225 dns_db_closeversion(db, &version, false); 23226 } 23227 if (db != NULL) { 23228 dns_db_detach(&db); 23229 } 23230 23231 return (result); 23232} 23233 23234/* 23235 * Called when an "rndc signing -nsec3param ..." command is received, or the 23236 * 'dnssec-policy' has changed. 23237 * 23238 * Allocate and prepare an nsec3param_t structure which holds information about 23239 * the NSEC3 changes requested for the zone: 23240 * 23241 * - if NSEC3 is to be disabled ("-nsec3param none"), only set the "nsec" 23242 * field of the structure to true and the "replace" field to the value 23243 * of the "replace" argument, leaving other fields initialized to zeros, to 23244 * signal that the zone should be signed using NSEC instead of NSEC3, 23245 * 23246 * - otherwise, prepare NSEC3PARAM RDATA that will eventually be inserted at 23247 * the zone apex, convert it to a private-type record and store the latter 23248 * in the "data" field of the nsec3param_t structure. 23249 * 23250 * Once the nsec3param_t structure is prepared, post an event to the zone's 23251 * task which will cause setnsec3param() to be called with the prepared 23252 * structure passed as an argument. 23253 */ 23254isc_result_t 23255dns_zone_setnsec3param(dns_zone_t *zone, uint8_t hash, uint8_t flags, 23256 uint16_t iter, uint8_t saltlen, unsigned char *salt, 23257 bool replace, bool resalt) { 23258 isc_result_t result = ISC_R_SUCCESS; 23259 dns_rdata_nsec3param_t param, lookup; 23260 dns_rdata_t nrdata = DNS_RDATA_INIT; 23261 dns_rdata_t prdata = DNS_RDATA_INIT; 23262 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE]; 23263 unsigned char saltbuf[255]; 23264 struct np3event *npe; 23265 nsec3param_t *np; 23266 dns_zone_t *dummy = NULL; 23267 isc_buffer_t b; 23268 isc_event_t *e = NULL; 23269 bool do_lookup = false; 23270 23271 REQUIRE(DNS_ZONE_VALID(zone)); 23272 23273 LOCK_ZONE(zone); 23274 23275 /* 23276 * First check if the requested NSEC3 parameters are already set, 23277 * if so, no need to set again. 23278 */ 23279 if (hash != 0) { 23280 lookup.hash = hash; 23281 lookup.flags = flags; 23282 lookup.iterations = iter; 23283 lookup.salt_length = saltlen; 23284 lookup.salt = salt; 23285 param.salt = NULL; 23286 result = dns__zone_lookup_nsec3param(zone, &lookup, ¶m, 23287 saltbuf, resalt); 23288 if (result == ISC_R_SUCCESS) { 23289 UNLOCK_ZONE(zone); 23290 return (ISC_R_SUCCESS); 23291 } 23292 /* 23293 * Schedule lookup if lookup above failed (may happen if zone 23294 * db is NULL for example). 23295 */ 23296 do_lookup = (param.salt == NULL) ? true : false; 23297 } 23298 23299 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM, 23300 setnsec3param, zone, sizeof(struct np3event)); 23301 23302 npe = (struct np3event *)e; 23303 np = &npe->params; 23304 np->replace = replace; 23305 np->resalt = resalt; 23306 np->lookup = do_lookup; 23307 if (hash == 0) { 23308 np->length = 0; 23309 np->nsec = true; 23310 dnssec_log(zone, ISC_LOG_DEBUG(3), "setnsec3param:nsec"); 23311 } else { 23312 param.common.rdclass = zone->rdclass; 23313 param.common.rdtype = dns_rdatatype_nsec3param; 23314 ISC_LINK_INIT(¶m.common, link); 23315 param.mctx = NULL; 23316 /* nsec3 specific param set in dns__zone_lookup_nsec3param() */ 23317 isc_buffer_init(&b, nbuf, sizeof(nbuf)); 23318 23319 if (param.salt != NULL) { 23320 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass, 23321 dns_rdatatype_nsec3param, 23322 ¶m, &b)); 23323 dns_nsec3param_toprivate(&nrdata, &prdata, 23324 zone->privatetype, np->data, 23325 sizeof(np->data)); 23326 np->length = prdata.length; 23327 } 23328 23329 np->rdata = param; 23330 np->nsec = false; 23331 23332 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { 23333 unsigned char salttext[255 * 2 + 1]; 23334 if (param.salt != NULL) { 23335 salt2text(param.salt, param.salt_length, 23336 salttext, sizeof(salttext)); 23337 } 23338 dnssec_log(zone, ISC_LOG_DEBUG(3), 23339 "setnsec3param:nsec3 %u %u %u %u:%s", 23340 param.hash, param.flags, param.iterations, 23341 param.salt_length, 23342 param.salt == NULL ? "unknown" 23343 : (char *)salttext); 23344 } 23345 } 23346 23347 /* 23348 * setnsec3param() will silently return early if the zone does not yet 23349 * have a database. Prevent that by queueing the event up if zone->db 23350 * is NULL. All events queued here are subsequently processed by 23351 * receive_secure_db() if it ever gets called or simply freed by 23352 * zone_free() otherwise. 23353 */ 23354 23355 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 23356 if (zone->db != NULL) { 23357 zone_iattach(zone, &dummy); 23358 isc_task_send(zone->task, &e); 23359 } else { 23360 ISC_LIST_APPEND(zone->setnsec3param_queue, e, ev_link); 23361 e = NULL; 23362 } 23363 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 23364 23365 result = ISC_R_SUCCESS; 23366 23367failure: 23368 if (e != NULL) { 23369 isc_event_free(&e); 23370 } 23371 UNLOCK_ZONE(zone); 23372 return (result); 23373} 23374 23375isc_result_t 23376dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) { 23377 REQUIRE(DNS_ZONE_VALID(zone)); 23378 REQUIRE(loadtime != NULL); 23379 23380 LOCK_ZONE(zone); 23381 *loadtime = zone->loadtime; 23382 UNLOCK_ZONE(zone); 23383 return (ISC_R_SUCCESS); 23384} 23385 23386isc_result_t 23387dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) { 23388 REQUIRE(DNS_ZONE_VALID(zone)); 23389 REQUIRE(expiretime != NULL); 23390 23391 LOCK_ZONE(zone); 23392 *expiretime = zone->expiretime; 23393 UNLOCK_ZONE(zone); 23394 return (ISC_R_SUCCESS); 23395} 23396 23397isc_result_t 23398dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) { 23399 REQUIRE(DNS_ZONE_VALID(zone)); 23400 REQUIRE(refreshtime != NULL); 23401 23402 LOCK_ZONE(zone); 23403 *refreshtime = zone->refreshtime; 23404 UNLOCK_ZONE(zone); 23405 return (ISC_R_SUCCESS); 23406} 23407 23408isc_result_t 23409dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) { 23410 REQUIRE(DNS_ZONE_VALID(zone)); 23411 REQUIRE(refreshkeytime != NULL); 23412 23413 LOCK_ZONE(zone); 23414 *refreshkeytime = zone->refreshkeytime; 23415 UNLOCK_ZONE(zone); 23416 return (ISC_R_SUCCESS); 23417} 23418 23419unsigned int 23420dns_zone_getincludes(dns_zone_t *zone, char ***includesp) { 23421 dns_include_t *include; 23422 char **array = NULL; 23423 unsigned int n = 0; 23424 23425 REQUIRE(DNS_ZONE_VALID(zone)); 23426 REQUIRE(includesp != NULL && *includesp == NULL); 23427 23428 LOCK_ZONE(zone); 23429 if (zone->nincludes == 0) { 23430 goto done; 23431 } 23432 23433 array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes); 23434 for (include = ISC_LIST_HEAD(zone->includes); include != NULL; 23435 include = ISC_LIST_NEXT(include, link)) 23436 { 23437 INSIST(n < zone->nincludes); 23438 array[n++] = isc_mem_strdup(zone->mctx, include->name); 23439 } 23440 INSIST(n == zone->nincludes); 23441 *includesp = array; 23442 23443done: 23444 UNLOCK_ZONE(zone); 23445 return (n); 23446} 23447 23448void 23449dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) { 23450 REQUIRE(DNS_ZONE_VALID(zone)); 23451 23452 zone->statlevel = level; 23453} 23454 23455dns_zonestat_level_t 23456dns_zone_getstatlevel(dns_zone_t *zone) { 23457 REQUIRE(DNS_ZONE_VALID(zone)); 23458 23459 return (zone->statlevel); 23460} 23461 23462static void 23463setserial(isc_task_t *task, isc_event_t *event) { 23464 uint32_t oldserial, desired; 23465 const char *me = "setserial"; 23466 bool commit = false; 23467 isc_result_t result; 23468 dns_dbversion_t *oldver = NULL, *newver = NULL; 23469 dns_zone_t *zone; 23470 dns_db_t *db = NULL; 23471 dns_diff_t diff; 23472 struct ssevent *sse = (struct ssevent *)event; 23473 dns_update_log_t log = { update_log_cb, NULL }; 23474 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL; 23475 23476 UNUSED(task); 23477 23478 zone = event->ev_arg; 23479 INSIST(DNS_ZONE_VALID(zone)); 23480 23481 ENTER; 23482 23483 if (zone->update_disabled) { 23484 goto disabled; 23485 } 23486 23487 desired = sse->serial; 23488 23489 dns_diff_init(zone->mctx, &diff); 23490 23491 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 23492 if (zone->db != NULL) { 23493 dns_db_attach(zone->db, &db); 23494 } 23495 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 23496 if (db == NULL) { 23497 goto failure; 23498 } 23499 23500 dns_db_currentversion(db, &oldver); 23501 result = dns_db_newversion(db, &newver); 23502 if (result != ISC_R_SUCCESS) { 23503 dns_zone_log(zone, ISC_LOG_ERROR, 23504 "setserial:dns_db_newversion -> %s", 23505 isc_result_totext(result)); 23506 goto failure; 23507 } 23508 23509 CHECK(dns_db_createsoatuple(db, oldver, diff.mctx, DNS_DIFFOP_DEL, 23510 &oldtuple)); 23511 CHECK(dns_difftuple_copy(oldtuple, &newtuple)); 23512 newtuple->op = DNS_DIFFOP_ADD; 23513 23514 oldserial = dns_soa_getserial(&oldtuple->rdata); 23515 if (desired == 0U) { 23516 desired = 1; 23517 } 23518 if (!isc_serial_gt(desired, oldserial)) { 23519 if (desired != oldserial) { 23520 dns_zone_log(zone, ISC_LOG_INFO, 23521 "setserial: desired serial (%u) " 23522 "out of range (%u-%u)", 23523 desired, oldserial + 1, 23524 (oldserial + 0x7fffffff)); 23525 } 23526 goto failure; 23527 } 23528 23529 dns_soa_setserial(desired, &newtuple->rdata); 23530 CHECK(do_one_tuple(&oldtuple, db, newver, &diff)); 23531 CHECK(do_one_tuple(&newtuple, db, newver, &diff)); 23532 result = dns_update_signatures(&log, zone, db, oldver, newver, &diff, 23533 zone->sigvalidityinterval); 23534 if (result != ISC_R_NOTFOUND) { 23535 CHECK(result); 23536 } 23537 23538 /* Write changes to journal file. */ 23539 CHECK(zone_journal(zone, &diff, NULL, "setserial")); 23540 commit = true; 23541 23542 LOCK_ZONE(zone); 23543 zone_needdump(zone, 30); 23544 UNLOCK_ZONE(zone); 23545 23546failure: 23547 if (oldtuple != NULL) { 23548 dns_difftuple_free(&oldtuple); 23549 } 23550 if (newtuple != NULL) { 23551 dns_difftuple_free(&newtuple); 23552 } 23553 if (oldver != NULL) { 23554 dns_db_closeversion(db, &oldver, false); 23555 } 23556 if (newver != NULL) { 23557 dns_db_closeversion(db, &newver, commit); 23558 } 23559 if (db != NULL) { 23560 dns_db_detach(&db); 23561 } 23562 dns_diff_clear(&diff); 23563 23564disabled: 23565 isc_event_free(&event); 23566 dns_zone_idetach(&zone); 23567 23568 INSIST(oldver == NULL); 23569 INSIST(newver == NULL); 23570} 23571 23572isc_result_t 23573dns_zone_setserial(dns_zone_t *zone, uint32_t serial) { 23574 isc_result_t result = ISC_R_SUCCESS; 23575 dns_zone_t *dummy = NULL; 23576 isc_event_t *e = NULL; 23577 struct ssevent *sse; 23578 23579 REQUIRE(DNS_ZONE_VALID(zone)); 23580 23581 LOCK_ZONE(zone); 23582 23583 if (!inline_secure(zone)) { 23584 if (!dns_zone_isdynamic(zone, true)) { 23585 result = DNS_R_NOTDYNAMIC; 23586 goto failure; 23587 } 23588 } 23589 23590 if (zone->update_disabled) { 23591 result = DNS_R_FROZEN; 23592 goto failure; 23593 } 23594 23595 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETSERIAL, setserial, 23596 zone, sizeof(struct ssevent)); 23597 23598 sse = (struct ssevent *)e; 23599 sse->serial = serial; 23600 23601 zone_iattach(zone, &dummy); 23602 isc_task_send(zone->task, &e); 23603 23604failure: 23605 if (e != NULL) { 23606 isc_event_free(&e); 23607 } 23608 UNLOCK_ZONE(zone); 23609 return (result); 23610} 23611 23612isc_stats_t * 23613dns_zone_getgluecachestats(dns_zone_t *zone) { 23614 REQUIRE(DNS_ZONE_VALID(zone)); 23615 23616 return (zone->gluecachestats); 23617} 23618 23619bool 23620dns_zone_isloaded(dns_zone_t *zone) { 23621 REQUIRE(DNS_ZONE_VALID(zone)); 23622 23623 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)); 23624} 23625 23626isc_result_t 23627dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver) { 23628 dns_dbversion_t *version = NULL; 23629 dns_keytable_t *secroots = NULL; 23630 isc_result_t result; 23631 dns_name_t *origin; 23632 23633 const char me[] = "dns_zone_verifydb"; 23634 23635 REQUIRE(DNS_ZONE_VALID(zone)); 23636 REQUIRE(db != NULL); 23637 23638 ENTER; 23639 23640 if (dns_zone_gettype(zone) != dns_zone_mirror) { 23641 return (ISC_R_SUCCESS); 23642 } 23643 23644 if (ver == NULL) { 23645 dns_db_currentversion(db, &version); 23646 } else { 23647 version = ver; 23648 } 23649 23650 if (zone->view != NULL) { 23651 result = dns_view_getsecroots(zone->view, &secroots); 23652 if (result != ISC_R_SUCCESS) { 23653 goto done; 23654 } 23655 } 23656 23657 origin = dns_db_origin(db); 23658 result = dns_zoneverify_dnssec(zone, db, version, origin, secroots, 23659 zone->mctx, true, false, dnssec_report); 23660 23661done: 23662 if (secroots != NULL) { 23663 dns_keytable_detach(&secroots); 23664 } 23665 23666 if (ver == NULL) { 23667 dns_db_closeversion(db, &version, false); 23668 } 23669 23670 if (result != ISC_R_SUCCESS) { 23671 dnssec_log(zone, ISC_LOG_ERROR, "zone verification failed: %s", 23672 isc_result_totext(result)); 23673 result = DNS_R_VERIFYFAILURE; 23674 } 23675 23676 return (result); 23677} 23678 23679static dns_ttl_t 23680zone_nsecttl(dns_zone_t *zone) { 23681 REQUIRE(DNS_ZONE_VALID(zone)); 23682 23683 return (ISC_MIN(zone->minimum, zone->soattl)); 23684} 23685 23686void 23687dns_zonemgr_set_tlsctx_cache(dns_zonemgr_t *zmgr, 23688 isc_tlsctx_cache_t *tlsctx_cache) { 23689 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 23690 REQUIRE(tlsctx_cache != NULL); 23691 23692 RWLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_write); 23693 23694 if (zmgr->tlsctx_cache != NULL) { 23695 isc_tlsctx_cache_detach(&zmgr->tlsctx_cache); 23696 } 23697 23698 isc_tlsctx_cache_attach(tlsctx_cache, &zmgr->tlsctx_cache); 23699 23700 RWUNLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_write); 23701} 23702 23703static void 23704zmgr_tlsctx_attach(dns_zonemgr_t *zmgr, isc_tlsctx_cache_t **ptlsctx_cache) { 23705 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 23706 REQUIRE(ptlsctx_cache != NULL && *ptlsctx_cache == NULL); 23707 23708 RWLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_read); 23709 23710 INSIST(zmgr->tlsctx_cache != NULL); 23711 isc_tlsctx_cache_attach(zmgr->tlsctx_cache, ptlsctx_cache); 23712 23713 RWUNLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_read); 23714} 23715