zone.c revision 279265
1/* 2 * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1999-2003 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id$ */ 19 20/*! \file */ 21 22#include <config.h> 23#include <errno.h> 24 25#include <isc/file.h> 26#include <isc/hex.h> 27#include <isc/mutex.h> 28#include <isc/pool.h> 29#include <isc/print.h> 30#include <isc/random.h> 31#include <isc/ratelimiter.h> 32#include <isc/refcount.h> 33#include <isc/rwlock.h> 34#include <isc/serial.h> 35#include <isc/stats.h> 36#include <isc/stdtime.h> 37#include <isc/strerror.h> 38#include <isc/string.h> 39#include <isc/taskpool.h> 40#include <isc/thread.h> 41#include <isc/timer.h> 42#include <isc/util.h> 43 44#include <dns/acache.h> 45#include <dns/acl.h> 46#include <dns/adb.h> 47#include <dns/callbacks.h> 48#include <dns/db.h> 49#include <dns/dbiterator.h> 50#include <dns/dnssec.h> 51#include <dns/events.h> 52#include <dns/journal.h> 53#include <dns/keydata.h> 54#include <dns/keytable.h> 55#include <dns/keyvalues.h> 56#include <dns/log.h> 57#include <dns/master.h> 58#include <dns/masterdump.h> 59#include <dns/message.h> 60#include <dns/name.h> 61#include <dns/nsec.h> 62#include <dns/nsec3.h> 63#include <dns/peer.h> 64#include <dns/private.h> 65#include <dns/rbt.h> 66#include <dns/rcode.h> 67#include <dns/rdata.h> 68#include <dns/rdataclass.h> 69#include <dns/rdatalist.h> 70#include <dns/rdataset.h> 71#include <dns/rdatasetiter.h> 72#include <dns/rdatastruct.h> 73#include <dns/rdatatype.h> 74#include <dns/request.h> 75#include <dns/resolver.h> 76#include <dns/result.h> 77#include <dns/rriterator.h> 78#include <dns/soa.h> 79#include <dns/ssu.h> 80#include <dns/stats.h> 81#include <dns/time.h> 82#include <dns/tsig.h> 83#include <dns/update.h> 84#include <dns/xfrin.h> 85#include <dns/zone.h> 86#include <dns/zt.h> 87 88#include <dst/dst.h> 89 90#define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E') 91#define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC) 92 93#define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y') 94#define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC) 95 96#define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b') 97#define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC) 98 99#define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r') 100#define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC) 101 102#define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd') 103#define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC) 104 105#define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w') 106#define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC) 107 108#define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O') 109#define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC) 110 111/*% 112 * Ensure 'a' is at least 'min' but not more than 'max'. 113 */ 114#define RANGE(a, min, max) \ 115 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max))) 116 117#define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) 118 119/*% 120 * Key flags 121 */ 122#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0) 123#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0) 124#define ALG(x) dst_key_alg(x) 125 126/* 127 * Default values. 128 */ 129#define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */ 130#define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */ 131#define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */ 132#define RESIGN_DELAY 3600 /*%< 1 hour */ 133 134#ifndef DNS_MAX_EXPIRE 135#define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */ 136#endif 137 138#ifndef DNS_DUMP_DELAY 139#define DNS_DUMP_DELAY 900 /*%< 15 minutes */ 140#endif 141 142typedef struct dns_notify dns_notify_t; 143typedef struct dns_stub dns_stub_t; 144typedef struct dns_load dns_load_t; 145typedef struct dns_forward dns_forward_t; 146typedef ISC_LIST(dns_forward_t) dns_forwardlist_t; 147typedef struct dns_io dns_io_t; 148typedef ISC_LIST(dns_io_t) dns_iolist_t; 149typedef struct dns_signing dns_signing_t; 150typedef ISC_LIST(dns_signing_t) dns_signinglist_t; 151typedef struct dns_nsec3chain dns_nsec3chain_t; 152typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t; 153typedef struct dns_keyfetch dns_keyfetch_t; 154typedef struct dns_asyncload dns_asyncload_t; 155 156#define DNS_ZONE_CHECKLOCK 157#ifdef DNS_ZONE_CHECKLOCK 158#define LOCK_ZONE(z) \ 159 do { LOCK(&(z)->lock); \ 160 INSIST((z)->locked == ISC_FALSE); \ 161 (z)->locked = ISC_TRUE; \ 162 } while (0) 163#define UNLOCK_ZONE(z) \ 164 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0) 165#define LOCKED_ZONE(z) ((z)->locked) 166#define TRYLOCK_ZONE(result, z) \ 167 do { \ 168 result = isc_mutex_trylock(&(z)->lock); \ 169 if (result == ISC_R_SUCCESS) { \ 170 INSIST((z)->locked == ISC_FALSE); \ 171 (z)->locked = ISC_TRUE; \ 172 } \ 173 } while (0) 174#else 175#define LOCK_ZONE(z) LOCK(&(z)->lock) 176#define UNLOCK_ZONE(z) UNLOCK(&(z)->lock) 177#define LOCKED_ZONE(z) ISC_TRUE 178#define TRYLOCK_ZONE(result, z) \ 179 do { result = isc_mutex_trylock(&(z)->lock); } while (0) 180#endif 181 182#ifdef ISC_RWLOCK_USEATOMIC 183#define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0) 184#define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l) 185#define ZONEDB_LOCK(l, t) RWLOCK((l), (t)) 186#define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t)) 187#else 188#define ZONEDB_INITLOCK(l) isc_mutex_init(l) 189#define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l) 190#define ZONEDB_LOCK(l, t) LOCK(l) 191#define ZONEDB_UNLOCK(l, t) UNLOCK(l) 192#endif 193 194struct dns_zone { 195 /* Unlocked */ 196 unsigned int magic; 197 isc_mutex_t lock; 198#ifdef DNS_ZONE_CHECKLOCK 199 isc_boolean_t locked; 200#endif 201 isc_mem_t *mctx; 202 isc_refcount_t erefs; 203 204#ifdef ISC_RWLOCK_USEATOMIC 205 isc_rwlock_t dblock; 206#else 207 isc_mutex_t dblock; 208#endif 209 dns_db_t *db; /* Locked by dblock */ 210 211 /* Locked */ 212 dns_zonemgr_t *zmgr; 213 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */ 214 isc_timer_t *timer; 215 unsigned int irefs; 216 dns_name_t origin; 217 char *masterfile; 218 dns_masterformat_t masterformat; 219 char *journal; 220 isc_int32_t journalsize; 221 dns_rdataclass_t rdclass; 222 dns_zonetype_t type; 223 unsigned int flags; 224 unsigned int options; 225 unsigned int db_argc; 226 char **db_argv; 227 isc_time_t expiretime; 228 isc_time_t refreshtime; 229 isc_time_t dumptime; 230 isc_time_t loadtime; 231 isc_time_t notifytime; 232 isc_time_t resigntime; 233 isc_time_t keywarntime; 234 isc_time_t signingtime; 235 isc_time_t nsec3chaintime; 236 isc_time_t refreshkeytime; 237 isc_uint32_t refreshkeyinterval; 238 isc_uint32_t refreshkeycount; 239 isc_uint32_t refresh; 240 isc_uint32_t retry; 241 isc_uint32_t expire; 242 isc_uint32_t minimum; 243 isc_stdtime_t key_expiry; 244 isc_stdtime_t log_key_expired_timer; 245 char *keydirectory; 246 247 isc_uint32_t maxrefresh; 248 isc_uint32_t minrefresh; 249 isc_uint32_t maxretry; 250 isc_uint32_t minretry; 251 252 isc_sockaddr_t *masters; 253 dns_name_t **masterkeynames; 254 isc_boolean_t *mastersok; 255 unsigned int masterscnt; 256 unsigned int curmaster; 257 isc_sockaddr_t masteraddr; 258 dns_notifytype_t notifytype; 259 isc_sockaddr_t *notify; 260 dns_name_t **notifykeynames; 261 unsigned int notifycnt; 262 isc_sockaddr_t notifyfrom; 263 isc_task_t *task; 264 isc_task_t *loadtask; 265 isc_sockaddr_t notifysrc4; 266 isc_sockaddr_t notifysrc6; 267 isc_sockaddr_t xfrsource4; 268 isc_sockaddr_t xfrsource6; 269 isc_sockaddr_t altxfrsource4; 270 isc_sockaddr_t altxfrsource6; 271 isc_sockaddr_t sourceaddr; 272 dns_xfrin_ctx_t *xfr; /* task locked */ 273 dns_tsigkey_t *tsigkey; /* key used for xfr */ 274 /* Access Control Lists */ 275 dns_acl_t *update_acl; 276 dns_acl_t *forward_acl; 277 dns_acl_t *notify_acl; 278 dns_acl_t *query_acl; 279 dns_acl_t *queryon_acl; 280 dns_acl_t *xfr_acl; 281 isc_boolean_t update_disabled; 282 isc_boolean_t zero_no_soa_ttl; 283 dns_severity_t check_names; 284 ISC_LIST(dns_notify_t) notifies; 285 dns_request_t *request; 286 dns_loadctx_t *lctx; 287 dns_io_t *readio; 288 dns_dumpctx_t *dctx; 289 dns_io_t *writeio; 290 isc_uint32_t maxxfrin; 291 isc_uint32_t maxxfrout; 292 isc_uint32_t idlein; 293 isc_uint32_t idleout; 294 isc_event_t ctlevent; 295 dns_ssutable_t *ssutable; 296 isc_uint32_t sigvalidityinterval; 297 isc_uint32_t sigresigninginterval; 298 dns_view_t *view; 299 dns_acache_t *acache; 300 dns_checkmxfunc_t checkmx; 301 dns_checksrvfunc_t checksrv; 302 dns_checknsfunc_t checkns; 303 /*% 304 * Zones in certain states such as "waiting for zone transfer" 305 * or "zone transfer in progress" are kept on per-state linked lists 306 * in the zone manager using the 'statelink' field. The 'statelist' 307 * field points at the list the zone is currently on. It the zone 308 * is not on any such list, statelist is NULL. 309 */ 310 ISC_LINK(dns_zone_t) statelink; 311 dns_zonelist_t *statelist; 312 /*% 313 * Statistics counters about zone management. 314 */ 315 isc_stats_t *stats; 316 /*% 317 * Optional per-zone statistics counters. Counted outside of this 318 * module. 319 */ 320 dns_zonestat_level_t statlevel; 321 isc_boolean_t requeststats_on; 322 isc_stats_t *requeststats; 323 dns_stats_t *rcvquerystats; 324 isc_uint32_t notifydelay; 325 dns_isselffunc_t isself; 326 void *isselfarg; 327 328 char * strnamerd; 329 char * strname; 330 char * strrdclass; 331 char * strviewname; 332 333 /*% 334 * Serial number for deferred journal compaction. 335 */ 336 isc_uint32_t compact_serial; 337 /*% 338 * Keys that are signing the zone for the first time. 339 */ 340 dns_signinglist_t signing; 341 dns_nsec3chainlist_t nsec3chain; 342 /*% 343 * Signing / re-signing quantum stopping parameters. 344 */ 345 isc_uint32_t signatures; 346 isc_uint32_t nodes; 347 dns_rdatatype_t privatetype; 348 349 /*% 350 * Autosigning/key-maintenance options 351 */ 352 isc_uint32_t keyopts; 353 354 /*% 355 * True if added by "rndc addzone" 356 */ 357 isc_boolean_t added; 358 359 /*% 360 * whether this is a response policy zone 361 */ 362 isc_boolean_t is_rpz; 363 364 /*% 365 * Serial number update method. 366 */ 367 dns_updatemethod_t updatemethod; 368 369 /*% 370 * whether ixfr is requested 371 */ 372 isc_boolean_t requestixfr; 373 374 /*% 375 * Outstanding forwarded UPDATE requests. 376 */ 377 dns_forwardlist_t forwards; 378 379 dns_zone_t *raw; 380 dns_zone_t *secure; 381 382 isc_boolean_t sourceserialset; 383 isc_uint32_t sourceserial; 384}; 385 386typedef struct { 387 dns_diff_t *diff; 388 isc_boolean_t offline; 389} zonediff_t; 390 391#define zonediff_init(z, d) \ 392 do { \ 393 zonediff_t *_z = (z); \ 394 (_z)->diff = (d); \ 395 (_z)->offline = ISC_FALSE; \ 396 } while (0) 397 398#define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0)) 399#define DNS_ZONE_SETFLAG(z,f) do { \ 400 INSIST(LOCKED_ZONE(z)); \ 401 (z)->flags |= (f); \ 402 } while (0) 403#define DNS_ZONE_CLRFLAG(z,f) do { \ 404 INSIST(LOCKED_ZONE(z)); \ 405 (z)->flags &= ~(f); \ 406 } while (0) 407 /* XXX MPA these may need to go back into zone.h */ 408#define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */ 409#define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */ 410#define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */ 411#define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */ 412#define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */ 413#define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */ 414#define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */ 415#define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */ 416#define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */ 417#define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are 418 * uptodate */ 419#define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify 420 * messages */ 421#define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on 422 * reload */ 423#define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a 424 * zone with no masters 425 * occurred */ 426#define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/ 427#define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set 428 * from SOA (if not set, we 429 * are still using 430 * default timer values) */ 431#define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */ 432#define DNS_ZONEFLG_NOREFRESH 0x00010000U 433#define DNS_ZONEFLG_DIALNOTIFY 0x00020000U 434#define DNS_ZONEFLG_DIALREFRESH 0x00040000U 435#define DNS_ZONEFLG_SHUTDOWN 0x00080000U 436#define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */ 437#define DNS_ZONEFLG_FLUSH 0x00200000U 438#define DNS_ZONEFLG_NOEDNS 0x00400000U 439#define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U 440#define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U 441#define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U 442#define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */ 443#define DNS_ZONEFLG_THAW 0x08000000U 444#define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */ 445#define DNS_ZONEFLG_NODELAY 0x20000000U 446#define DNS_ZONEFLG_SENDSECURE 0x40000000U 447 448#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0) 449#define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0) 450 451/* Flags for zone_load() */ 452#define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */ 453#define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful 454 load. */ 455 456#define UNREACH_CHACHE_SIZE 10U 457#define UNREACH_HOLD_TIME 600 /* 10 minutes */ 458 459#define CHECK(op) \ 460 do { result = (op); \ 461 if (result != ISC_R_SUCCESS) goto failure; \ 462 } while (0) 463 464struct dns_unreachable { 465 isc_sockaddr_t remote; 466 isc_sockaddr_t local; 467 isc_uint32_t expire; 468 isc_uint32_t last; 469 isc_uint32_t count; 470}; 471 472struct dns_zonemgr { 473 unsigned int magic; 474 isc_mem_t * mctx; 475 int refs; /* Locked by rwlock */ 476 isc_taskmgr_t * taskmgr; 477 isc_timermgr_t * timermgr; 478 isc_socketmgr_t * socketmgr; 479 isc_taskpool_t * zonetasks; 480 isc_taskpool_t * loadtasks; 481 isc_task_t * task; 482 isc_pool_t * mctxpool; 483 isc_ratelimiter_t * notifyrl; 484 isc_ratelimiter_t * refreshrl; 485 isc_rwlock_t rwlock; 486 isc_mutex_t iolock; 487 isc_rwlock_t urlock; 488 489 /* Locked by rwlock. */ 490 dns_zonelist_t zones; 491 dns_zonelist_t waiting_for_xfrin; 492 dns_zonelist_t xfrin_in_progress; 493 494 /* Configuration data. */ 495 isc_uint32_t transfersin; 496 isc_uint32_t transfersperns; 497 unsigned int serialqueryrate; 498 499 /* Locked by iolock */ 500 isc_uint32_t iolimit; 501 isc_uint32_t ioactive; 502 dns_iolist_t high; 503 dns_iolist_t low; 504 505 /* Locked by urlock. */ 506 /* LRU cache */ 507 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE]; 508}; 509 510/*% 511 * Hold notify state. 512 */ 513struct dns_notify { 514 unsigned int magic; 515 unsigned int flags; 516 isc_mem_t *mctx; 517 dns_zone_t *zone; 518 dns_adbfind_t *find; 519 dns_request_t *request; 520 dns_name_t ns; 521 isc_sockaddr_t dst; 522 dns_tsigkey_t *key; 523 ISC_LINK(dns_notify_t) link; 524}; 525 526#define DNS_NOTIFY_NOSOA 0x0001U 527 528/*% 529 * dns_stub holds state while performing a 'stub' transfer. 530 * 'db' is the zone's 'db' or a new one if this is the initial 531 * transfer. 532 */ 533 534struct dns_stub { 535 unsigned int magic; 536 isc_mem_t *mctx; 537 dns_zone_t *zone; 538 dns_db_t *db; 539 dns_dbversion_t *version; 540}; 541 542/*% 543 * Hold load state. 544 */ 545struct dns_load { 546 unsigned int magic; 547 isc_mem_t *mctx; 548 dns_zone_t *zone; 549 dns_db_t *db; 550 isc_time_t loadtime; 551 dns_rdatacallbacks_t callbacks; 552}; 553 554/*% 555 * Hold forward state. 556 */ 557struct dns_forward { 558 unsigned int magic; 559 isc_mem_t *mctx; 560 dns_zone_t *zone; 561 isc_buffer_t *msgbuf; 562 dns_request_t *request; 563 isc_uint32_t which; 564 isc_sockaddr_t addr; 565 dns_updatecallback_t callback; 566 void *callback_arg; 567 ISC_LINK(dns_forward_t) link; 568}; 569 570/*% 571 * Hold IO request state. 572 */ 573struct dns_io { 574 unsigned int magic; 575 dns_zonemgr_t *zmgr; 576 isc_boolean_t high; 577 isc_task_t *task; 578 ISC_LINK(dns_io_t) link; 579 isc_event_t *event; 580}; 581 582/*% 583 * Hold state for when we are signing a zone with a new 584 * DNSKEY as result of an update. 585 */ 586struct dns_signing { 587 unsigned int magic; 588 dns_db_t *db; 589 dns_dbiterator_t *dbiterator; 590 dns_secalg_t algorithm; 591 isc_uint16_t keyid; 592 isc_boolean_t delete; 593 isc_boolean_t done; 594 ISC_LINK(dns_signing_t) link; 595}; 596 597struct dns_nsec3chain { 598 unsigned int magic; 599 dns_db_t *db; 600 dns_dbiterator_t *dbiterator; 601 dns_rdata_nsec3param_t nsec3param; 602 unsigned char salt[255]; 603 isc_boolean_t done; 604 isc_boolean_t seen_nsec; 605 isc_boolean_t delete_nsec; 606 isc_boolean_t save_delete_nsec; 607 ISC_LINK(dns_nsec3chain_t) link; 608}; 609/*%< 610 * 'dbiterator' contains a iterator for the database. If we are creating 611 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are 612 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be 613 * iterated. 614 * 615 * 'nsec3param' contains the parameters of the NSEC3 chain being created 616 * or removed. 617 * 618 * 'salt' is buffer space and is referenced via 'nsec3param.salt'. 619 * 620 * 'seen_nsec' will be set to true if, while iterating the zone to create a 621 * NSEC3 chain, a NSEC record is seen. 622 * 623 * 'delete_nsec' will be set to true if, at the completion of the creation 624 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we 625 * are in the process of deleting the NSEC chain. 626 * 627 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec' 628 * so it can be recovered in the event of a error. 629 */ 630 631struct dns_keyfetch { 632 dns_fixedname_t name; 633 dns_rdataset_t keydataset; 634 dns_rdataset_t dnskeyset; 635 dns_rdataset_t dnskeysigset; 636 dns_zone_t *zone; 637 dns_db_t *db; 638 dns_fetch_t *fetch; 639}; 640 641/*% 642 * Hold state for an asynchronous load 643 */ 644struct dns_asyncload { 645 dns_zone_t *zone; 646 dns_zt_zoneloaded_t loaded; 647 void *loaded_arg; 648}; 649 650#define HOUR 3600 651#define DAY (24*HOUR) 652#define MONTH (30*DAY) 653 654#define SEND_BUFFER_SIZE 2048 655 656static void zone_settimer(dns_zone_t *, isc_time_t *); 657static void cancel_refresh(dns_zone_t *); 658static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel, 659 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5); 660static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...) 661 ISC_FORMAT_PRINTF(3, 4); 662static void queue_xfrin(dns_zone_t *zone); 663static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver, 664 dns_diff_t *diff, dns_diffop_t op, 665 dns_name_t *name, dns_ttl_t ttl, 666 dns_rdata_t *rdata); 667static void zone_unload(dns_zone_t *zone); 668static void zone_expire(dns_zone_t *zone); 669static void zone_iattach(dns_zone_t *source, dns_zone_t **target); 670static void zone_idetach(dns_zone_t **zonep); 671static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db, 672 isc_boolean_t dump); 673static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db); 674static inline void zone_detachdb(dns_zone_t *zone); 675static isc_result_t default_journal(dns_zone_t *zone); 676static void zone_xfrdone(dns_zone_t *zone, isc_result_t result); 677static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db, 678 isc_time_t loadtime, isc_result_t result); 679static void zone_needdump(dns_zone_t *zone, unsigned int delay); 680static void zone_shutdown(isc_task_t *, isc_event_t *); 681static void zone_loaddone(void *arg, isc_result_t result); 682static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone, 683 isc_time_t loadtime); 684static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length); 685static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length); 686static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length); 687static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length); 688static isc_result_t zone_send_secureserial(dns_zone_t *zone, 689 isc_uint32_t serial); 690 691#if 0 692/* ondestroy example */ 693static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event); 694#endif 695 696static void refresh_callback(isc_task_t *, isc_event_t *); 697static void stub_callback(isc_task_t *, isc_event_t *); 698static void queue_soa_query(dns_zone_t *zone); 699static void soa_query(isc_task_t *, isc_event_t *); 700static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, 701 dns_stub_t *stub); 702static int message_count(dns_message_t *msg, dns_section_t section, 703 dns_rdatatype_t type); 704static void notify_cancel(dns_zone_t *zone); 705static void notify_find_address(dns_notify_t *notify); 706static void notify_send(dns_notify_t *notify); 707static isc_result_t notify_createmessage(dns_zone_t *zone, 708 unsigned int flags, 709 dns_message_t **messagep); 710static void notify_done(isc_task_t *task, isc_event_t *event); 711static void notify_send_toaddr(isc_task_t *task, isc_event_t *event); 712static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t); 713static void got_transfer_quota(isc_task_t *task, isc_event_t *event); 714static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, 715 dns_zone_t *zone); 716static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi); 717static void zonemgr_free(dns_zonemgr_t *zmgr); 718static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high, 719 isc_task_t *task, isc_taskaction_t action, 720 void *arg, dns_io_t **iop); 721static void zonemgr_putio(dns_io_t **iop); 722static void zonemgr_cancelio(dns_io_t *io); 723 724static isc_result_t 725zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 726 unsigned int *soacount, isc_uint32_t *serial, 727 isc_uint32_t *refresh, isc_uint32_t *retry, 728 isc_uint32_t *expire, isc_uint32_t *minimum, 729 unsigned int *errors); 730 731static void zone_freedbargs(dns_zone_t *zone); 732static void forward_callback(isc_task_t *task, isc_event_t *event); 733static void zone_saveunique(dns_zone_t *zone, const char *path, 734 const char *templat); 735static void zone_maintenance(dns_zone_t *zone); 736static void zone_notify(dns_zone_t *zone, isc_time_t *now); 737static void dump_done(void *arg, isc_result_t result); 738static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, 739 isc_uint16_t keyid, isc_boolean_t delete); 740static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver, 741 dns_dbnode_t *node, dns_name_t *name, 742 dns_diff_t *diff); 743static void zone_rekey(dns_zone_t *zone); 744static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db); 745 746#define ENTER zone_debuglog(zone, me, 1, "enter") 747 748static const unsigned int dbargc_default = 1; 749static const char *dbargv_default[] = { "rbt" }; 750 751#define DNS_ZONE_JITTER_ADD(a, b, c) \ 752 do { \ 753 isc_interval_t _i; \ 754 isc_uint32_t _j; \ 755 _j = isc_random_jitter((b), (b)/4); \ 756 isc_interval_set(&_i, _j, 0); \ 757 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 758 dns_zone_log(zone, ISC_LOG_WARNING, \ 759 "epoch approaching: upgrade required: " \ 760 "now + %s failed", #b); \ 761 isc_interval_set(&_i, _j/2, 0); \ 762 (void)isc_time_add((a), &_i, (c)); \ 763 } \ 764 } while (0) 765 766#define DNS_ZONE_TIME_ADD(a, b, c) \ 767 do { \ 768 isc_interval_t _i; \ 769 isc_interval_set(&_i, (b), 0); \ 770 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 771 dns_zone_log(zone, ISC_LOG_WARNING, \ 772 "epoch approaching: upgrade required: " \ 773 "now + %s failed", #b); \ 774 isc_interval_set(&_i, (b)/2, 0); \ 775 (void)isc_time_add((a), &_i, (c)); \ 776 } \ 777 } while (0) 778 779typedef struct nsec3param nsec3param_t; 780struct nsec3param { 781 unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1]; 782 unsigned int length; 783 isc_boolean_t nsec; 784 isc_boolean_t replace; 785 ISC_LINK(nsec3param_t) link; 786}; 787typedef ISC_LIST(nsec3param_t) nsec3paramlist_t; 788struct np3event { 789 isc_event_t event; 790 nsec3param_t params; 791}; 792 793/*% 794 * Increment resolver-related statistics counters. Zone must be locked. 795 */ 796static inline void 797inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { 798 if (zone->stats != NULL) 799 isc_stats_increment(zone->stats, counter); 800} 801 802/*** 803 *** Public functions. 804 ***/ 805 806isc_result_t 807dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { 808 isc_result_t result; 809 dns_zone_t *zone; 810 isc_time_t now; 811 812 REQUIRE(zonep != NULL && *zonep == NULL); 813 REQUIRE(mctx != NULL); 814 815 TIME_NOW(&now); 816 zone = isc_mem_get(mctx, sizeof(*zone)); 817 if (zone == NULL) 818 return (ISC_R_NOMEMORY); 819 820 zone->mctx = NULL; 821 isc_mem_attach(mctx, &zone->mctx); 822 823 result = isc_mutex_init(&zone->lock); 824 if (result != ISC_R_SUCCESS) 825 goto free_zone; 826 827 result = ZONEDB_INITLOCK(&zone->dblock); 828 if (result != ISC_R_SUCCESS) 829 goto free_mutex; 830 831 /* XXX MPA check that all elements are initialised */ 832#ifdef DNS_ZONE_CHECKLOCK 833 zone->locked = ISC_FALSE; 834#endif 835 zone->db = NULL; 836 zone->zmgr = NULL; 837 ISC_LINK_INIT(zone, link); 838 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */ 839 if (result != ISC_R_SUCCESS) 840 goto free_dblock; 841 zone->irefs = 0; 842 dns_name_init(&zone->origin, NULL); 843 zone->strnamerd = NULL; 844 zone->strname = NULL; 845 zone->strrdclass = NULL; 846 zone->strviewname = NULL; 847 zone->masterfile = NULL; 848 zone->masterformat = dns_masterformat_none; 849 zone->keydirectory = NULL; 850 zone->journalsize = -1; 851 zone->journal = NULL; 852 zone->rdclass = dns_rdataclass_none; 853 zone->type = dns_zone_none; 854 zone->flags = 0; 855 zone->options = 0; 856 zone->keyopts = 0; 857 zone->db_argc = 0; 858 zone->db_argv = NULL; 859 isc_time_settoepoch(&zone->expiretime); 860 isc_time_settoepoch(&zone->refreshtime); 861 isc_time_settoepoch(&zone->dumptime); 862 isc_time_settoepoch(&zone->loadtime); 863 zone->notifytime = now; 864 isc_time_settoepoch(&zone->resigntime); 865 isc_time_settoepoch(&zone->keywarntime); 866 isc_time_settoepoch(&zone->signingtime); 867 isc_time_settoepoch(&zone->nsec3chaintime); 868 isc_time_settoepoch(&zone->refreshkeytime); 869 zone->refreshkeyinterval = 0; 870 zone->refreshkeycount = 0; 871 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 872 zone->retry = DNS_ZONE_DEFAULTRETRY; 873 zone->expire = 0; 874 zone->minimum = 0; 875 zone->maxrefresh = DNS_ZONE_MAXREFRESH; 876 zone->minrefresh = DNS_ZONE_MINREFRESH; 877 zone->maxretry = DNS_ZONE_MAXRETRY; 878 zone->minretry = DNS_ZONE_MINRETRY; 879 zone->masters = NULL; 880 zone->masterkeynames = NULL; 881 zone->mastersok = NULL; 882 zone->masterscnt = 0; 883 zone->curmaster = 0; 884 zone->notify = NULL; 885 zone->notifykeynames = NULL; 886 zone->notifytype = dns_notifytype_yes; 887 zone->notifycnt = 0; 888 zone->task = NULL; 889 zone->loadtask = NULL; 890 zone->update_acl = NULL; 891 zone->forward_acl = NULL; 892 zone->notify_acl = NULL; 893 zone->query_acl = NULL; 894 zone->queryon_acl = NULL; 895 zone->xfr_acl = NULL; 896 zone->update_disabled = ISC_FALSE; 897 zone->zero_no_soa_ttl = ISC_TRUE; 898 zone->check_names = dns_severity_ignore; 899 zone->request = NULL; 900 zone->lctx = NULL; 901 zone->readio = NULL; 902 zone->dctx = NULL; 903 zone->writeio = NULL; 904 zone->timer = NULL; 905 zone->idlein = DNS_DEFAULT_IDLEIN; 906 zone->idleout = DNS_DEFAULT_IDLEOUT; 907 zone->log_key_expired_timer = 0; 908 ISC_LIST_INIT(zone->notifies); 909 isc_sockaddr_any(&zone->notifysrc4); 910 isc_sockaddr_any6(&zone->notifysrc6); 911 isc_sockaddr_any(&zone->xfrsource4); 912 isc_sockaddr_any6(&zone->xfrsource6); 913 isc_sockaddr_any(&zone->altxfrsource4); 914 isc_sockaddr_any6(&zone->altxfrsource6); 915 zone->xfr = NULL; 916 zone->tsigkey = NULL; 917 zone->maxxfrin = MAX_XFER_TIME; 918 zone->maxxfrout = MAX_XFER_TIME; 919 zone->ssutable = NULL; 920 zone->sigvalidityinterval = 30 * 24 * 3600; 921 zone->sigresigninginterval = 7 * 24 * 3600; 922 zone->view = NULL; 923 zone->acache = NULL; 924 zone->checkmx = NULL; 925 zone->checksrv = NULL; 926 zone->checkns = NULL; 927 ISC_LINK_INIT(zone, statelink); 928 zone->statelist = NULL; 929 zone->stats = NULL; 930 zone->requeststats_on = ISC_FALSE; 931 zone->statlevel = dns_zonestat_none; 932 zone->requeststats = NULL; 933 zone->rcvquerystats = NULL; 934 zone->notifydelay = 5; 935 zone->isself = NULL; 936 zone->isselfarg = NULL; 937 ISC_LIST_INIT(zone->signing); 938 ISC_LIST_INIT(zone->nsec3chain); 939 zone->signatures = 10; 940 zone->nodes = 100; 941 zone->privatetype = (dns_rdatatype_t)0xffffU; 942 zone->added = ISC_FALSE; 943 zone->is_rpz = ISC_FALSE; 944 ISC_LIST_INIT(zone->forwards); 945 zone->raw = NULL; 946 zone->secure = NULL; 947 zone->sourceserial = 0; 948 zone->sourceserialset = ISC_FALSE; 949 950 zone->magic = ZONE_MAGIC; 951 952 /* Must be after magic is set. */ 953 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default); 954 if (result != ISC_R_SUCCESS) 955 goto free_erefs; 956 957 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL, 958 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, 959 NULL, NULL); 960 *zonep = zone; 961 return (ISC_R_SUCCESS); 962 963 free_erefs: 964 isc_refcount_decrement(&zone->erefs, NULL); 965 isc_refcount_destroy(&zone->erefs); 966 967 free_dblock: 968 ZONEDB_DESTROYLOCK(&zone->dblock); 969 970 free_mutex: 971 DESTROYLOCK(&zone->lock); 972 973 free_zone: 974 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone)); 975 return (result); 976} 977 978/* 979 * Free a zone. Because we require that there be no more 980 * outstanding events or references, no locking is necessary. 981 */ 982static void 983zone_free(dns_zone_t *zone) { 984 isc_mem_t *mctx = NULL; 985 dns_signing_t *signing; 986 dns_nsec3chain_t *nsec3chain; 987 988 REQUIRE(DNS_ZONE_VALID(zone)); 989 REQUIRE(isc_refcount_current(&zone->erefs) == 0); 990 REQUIRE(zone->irefs == 0); 991 REQUIRE(!LOCKED_ZONE(zone)); 992 REQUIRE(zone->timer == NULL); 993 REQUIRE(zone->zmgr == NULL); 994 995 /* 996 * Managed objects. Order is important. 997 */ 998 if (zone->request != NULL) 999 dns_request_destroy(&zone->request); /* XXXMPA */ 1000 INSIST(zone->readio == NULL); 1001 INSIST(zone->statelist == NULL); 1002 INSIST(zone->writeio == NULL); 1003 1004 if (zone->task != NULL) 1005 isc_task_detach(&zone->task); 1006 if (zone->loadtask != NULL) 1007 isc_task_detach(&zone->loadtask); 1008 1009 /* Unmanaged objects */ 1010 for (signing = ISC_LIST_HEAD(zone->signing); 1011 signing != NULL; 1012 signing = ISC_LIST_HEAD(zone->signing)) { 1013 ISC_LIST_UNLINK(zone->signing, signing, link); 1014 dns_db_detach(&signing->db); 1015 dns_dbiterator_destroy(&signing->dbiterator); 1016 isc_mem_put(zone->mctx, signing, sizeof *signing); 1017 } 1018 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 1019 nsec3chain != NULL; 1020 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) { 1021 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 1022 dns_db_detach(&nsec3chain->db); 1023 dns_dbiterator_destroy(&nsec3chain->dbiterator); 1024 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 1025 } 1026 if (zone->masterfile != NULL) 1027 isc_mem_free(zone->mctx, zone->masterfile); 1028 zone->masterfile = NULL; 1029 if (zone->keydirectory != NULL) 1030 isc_mem_free(zone->mctx, zone->keydirectory); 1031 zone->keydirectory = NULL; 1032 zone->journalsize = -1; 1033 if (zone->journal != NULL) 1034 isc_mem_free(zone->mctx, zone->journal); 1035 zone->journal = NULL; 1036 if (zone->stats != NULL) 1037 isc_stats_detach(&zone->stats); 1038 if (zone->requeststats != NULL) 1039 isc_stats_detach(&zone->requeststats); 1040 if(zone->rcvquerystats != NULL ) 1041 dns_stats_detach(&zone->rcvquerystats); 1042 if (zone->db != NULL) 1043 zone_detachdb(zone); 1044 if (zone->acache != NULL) 1045 dns_acache_detach(&zone->acache); 1046 zone_freedbargs(zone); 1047 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0) 1048 == ISC_R_SUCCESS); 1049 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) 1050 == ISC_R_SUCCESS); 1051 zone->check_names = dns_severity_ignore; 1052 if (zone->update_acl != NULL) 1053 dns_acl_detach(&zone->update_acl); 1054 if (zone->forward_acl != NULL) 1055 dns_acl_detach(&zone->forward_acl); 1056 if (zone->notify_acl != NULL) 1057 dns_acl_detach(&zone->notify_acl); 1058 if (zone->query_acl != NULL) 1059 dns_acl_detach(&zone->query_acl); 1060 if (zone->queryon_acl != NULL) 1061 dns_acl_detach(&zone->queryon_acl); 1062 if (zone->xfr_acl != NULL) 1063 dns_acl_detach(&zone->xfr_acl); 1064 if (dns_name_dynamic(&zone->origin)) 1065 dns_name_free(&zone->origin, zone->mctx); 1066 if (zone->strnamerd != NULL) 1067 isc_mem_free(zone->mctx, zone->strnamerd); 1068 if (zone->strname != NULL) 1069 isc_mem_free(zone->mctx, zone->strname); 1070 if (zone->strrdclass != NULL) 1071 isc_mem_free(zone->mctx, zone->strrdclass); 1072 if (zone->strviewname != NULL) 1073 isc_mem_free(zone->mctx, zone->strviewname); 1074 if (zone->ssutable != NULL) 1075 dns_ssutable_detach(&zone->ssutable); 1076 1077 /* last stuff */ 1078 ZONEDB_DESTROYLOCK(&zone->dblock); 1079 DESTROYLOCK(&zone->lock); 1080 isc_refcount_destroy(&zone->erefs); 1081 zone->magic = 0; 1082 mctx = zone->mctx; 1083 isc_mem_put(mctx, zone, sizeof(*zone)); 1084 isc_mem_detach(&mctx); 1085} 1086 1087/* 1088 * Returns ISC_TRUE iff this the signed side of an inline-signing zone. 1089 * Caller should hold zone lock. 1090 */ 1091static inline isc_boolean_t 1092inline_secure(dns_zone_t *zone) { 1093 REQUIRE(DNS_ZONE_VALID(zone)); 1094 if (zone->raw != NULL) 1095 return (ISC_TRUE); 1096 return (ISC_FALSE); 1097} 1098 1099/* 1100 * Returns ISC_TRUE iff this the unsigned side of an inline-signing zone 1101 * Caller should hold zone lock. 1102 */ 1103static inline isc_boolean_t 1104inline_raw(dns_zone_t *zone) { 1105 REQUIRE(DNS_ZONE_VALID(zone)); 1106 if (zone->secure != NULL) 1107 return (ISC_TRUE); 1108 return (ISC_FALSE); 1109} 1110 1111/* 1112 * Single shot. 1113 */ 1114void 1115dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) { 1116 char namebuf[1024]; 1117 1118 REQUIRE(DNS_ZONE_VALID(zone)); 1119 REQUIRE(rdclass != dns_rdataclass_none); 1120 1121 /* 1122 * Test and set. 1123 */ 1124 LOCK_ZONE(zone); 1125 REQUIRE(zone->rdclass == dns_rdataclass_none || 1126 zone->rdclass == rdclass); 1127 zone->rdclass = rdclass; 1128 1129 if (zone->strnamerd != NULL) 1130 isc_mem_free(zone->mctx, zone->strnamerd); 1131 if (zone->strrdclass != NULL) 1132 isc_mem_free(zone->mctx, zone->strrdclass); 1133 1134 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1135 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1136 zone_rdclass_tostr(zone, namebuf, sizeof namebuf); 1137 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf); 1138 1139 if (inline_secure(zone)) 1140 dns_zone_setclass(zone->raw, rdclass); 1141 UNLOCK_ZONE(zone); 1142} 1143 1144dns_rdataclass_t 1145dns_zone_getclass(dns_zone_t *zone) { 1146 REQUIRE(DNS_ZONE_VALID(zone)); 1147 1148 return (zone->rdclass); 1149} 1150 1151void 1152dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { 1153 REQUIRE(DNS_ZONE_VALID(zone)); 1154 1155 LOCK_ZONE(zone); 1156 zone->notifytype = notifytype; 1157 UNLOCK_ZONE(zone); 1158} 1159 1160isc_result_t 1161dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) { 1162 isc_result_t result; 1163 unsigned int soacount; 1164 1165 REQUIRE(DNS_ZONE_VALID(zone)); 1166 REQUIRE(serialp != NULL); 1167 1168 LOCK_ZONE(zone); 1169 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1170 if (zone->db != NULL) { 1171 result = zone_get_from_db(zone, zone->db, NULL, &soacount, 1172 serialp, NULL, NULL, NULL, NULL, 1173 NULL); 1174 if (result == ISC_R_SUCCESS && soacount == 0) 1175 result = ISC_R_FAILURE; 1176 } else 1177 result = DNS_R_NOTLOADED; 1178 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1179 UNLOCK_ZONE(zone); 1180 1181 return (result); 1182} 1183 1184isc_uint32_t 1185dns_zone_getserial(dns_zone_t *zone) { 1186 isc_result_t result; 1187 isc_uint32_t serial; 1188 1189 result = dns_zone_getserial2(zone, &serial); 1190 if (result != ISC_R_SUCCESS) 1191 serial = 0; /* XXX: not really correct, but no other choice */ 1192 1193 return (serial); 1194} 1195 1196/* 1197 * Single shot. 1198 */ 1199void 1200dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) { 1201 char namebuf[1024]; 1202 1203 REQUIRE(DNS_ZONE_VALID(zone)); 1204 REQUIRE(type != dns_zone_none); 1205 1206 /* 1207 * Test and set. 1208 */ 1209 LOCK_ZONE(zone); 1210 REQUIRE(zone->type == dns_zone_none || zone->type == type); 1211 zone->type = type; 1212 1213 if (zone->strnamerd != NULL) 1214 isc_mem_free(zone->mctx, zone->strnamerd); 1215 1216 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1217 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1218 UNLOCK_ZONE(zone); 1219} 1220 1221static void 1222zone_freedbargs(dns_zone_t *zone) { 1223 unsigned int i; 1224 1225 /* Free the old database argument list. */ 1226 if (zone->db_argv != NULL) { 1227 for (i = 0; i < zone->db_argc; i++) 1228 isc_mem_free(zone->mctx, zone->db_argv[i]); 1229 isc_mem_put(zone->mctx, zone->db_argv, 1230 zone->db_argc * sizeof(*zone->db_argv)); 1231 } 1232 zone->db_argc = 0; 1233 zone->db_argv = NULL; 1234} 1235 1236isc_result_t 1237dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) { 1238 size_t size = 0; 1239 unsigned int i; 1240 isc_result_t result = ISC_R_SUCCESS; 1241 void *mem; 1242 char **tmp, *tmp2; 1243 1244 REQUIRE(DNS_ZONE_VALID(zone)); 1245 REQUIRE(argv != NULL && *argv == NULL); 1246 1247 LOCK_ZONE(zone); 1248 size = (zone->db_argc + 1) * sizeof(char *); 1249 for (i = 0; i < zone->db_argc; i++) 1250 size += strlen(zone->db_argv[i]) + 1; 1251 mem = isc_mem_allocate(mctx, size); 1252 if (mem != NULL) { 1253 tmp = mem; 1254 tmp2 = mem; 1255 tmp2 += (zone->db_argc + 1) * sizeof(char *); 1256 for (i = 0; i < zone->db_argc; i++) { 1257 *tmp++ = tmp2; 1258 strcpy(tmp2, zone->db_argv[i]); 1259 tmp2 += strlen(tmp2) + 1; 1260 } 1261 *tmp = NULL; 1262 } else 1263 result = ISC_R_NOMEMORY; 1264 UNLOCK_ZONE(zone); 1265 *argv = mem; 1266 return (result); 1267} 1268 1269isc_result_t 1270dns_zone_setdbtype(dns_zone_t *zone, 1271 unsigned int dbargc, const char * const *dbargv) { 1272 isc_result_t result = ISC_R_SUCCESS; 1273 char **new = NULL; 1274 unsigned int i; 1275 1276 REQUIRE(DNS_ZONE_VALID(zone)); 1277 REQUIRE(dbargc >= 1); 1278 REQUIRE(dbargv != NULL); 1279 1280 LOCK_ZONE(zone); 1281 1282 /* Set up a new database argument list. */ 1283 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new)); 1284 if (new == NULL) 1285 goto nomem; 1286 for (i = 0; i < dbargc; i++) 1287 new[i] = NULL; 1288 for (i = 0; i < dbargc; i++) { 1289 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]); 1290 if (new[i] == NULL) 1291 goto nomem; 1292 } 1293 1294 /* Free the old list. */ 1295 zone_freedbargs(zone); 1296 1297 zone->db_argc = dbargc; 1298 zone->db_argv = new; 1299 result = ISC_R_SUCCESS; 1300 goto unlock; 1301 1302 nomem: 1303 if (new != NULL) { 1304 for (i = 0; i < dbargc; i++) 1305 if (new[i] != NULL) 1306 isc_mem_free(zone->mctx, new[i]); 1307 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new)); 1308 } 1309 result = ISC_R_NOMEMORY; 1310 1311 unlock: 1312 UNLOCK_ZONE(zone); 1313 return (result); 1314} 1315 1316void 1317dns_zone_setview(dns_zone_t *zone, dns_view_t *view) { 1318 char namebuf[1024]; 1319 REQUIRE(DNS_ZONE_VALID(zone)); 1320 1321 LOCK_ZONE(zone); 1322 if (zone->view != NULL) 1323 dns_view_weakdetach(&zone->view); 1324 dns_view_weakattach(view, &zone->view); 1325 1326 if (zone->strviewname != NULL) 1327 isc_mem_free(zone->mctx, zone->strviewname); 1328 if (zone->strnamerd != NULL) 1329 isc_mem_free(zone->mctx, zone->strnamerd); 1330 1331 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1332 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1333 zone_viewname_tostr(zone, namebuf, sizeof namebuf); 1334 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf); 1335 1336 if (inline_secure(zone)) 1337 dns_zone_setview(zone->raw, view); 1338 1339 UNLOCK_ZONE(zone); 1340} 1341 1342dns_view_t * 1343dns_zone_getview(dns_zone_t *zone) { 1344 REQUIRE(DNS_ZONE_VALID(zone)); 1345 1346 return (zone->view); 1347} 1348 1349 1350isc_result_t 1351dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) { 1352 isc_result_t result; 1353 char namebuf[1024]; 1354 1355 REQUIRE(DNS_ZONE_VALID(zone)); 1356 REQUIRE(origin != NULL); 1357 1358 LOCK_ZONE(zone); 1359 if (dns_name_dynamic(&zone->origin)) { 1360 dns_name_free(&zone->origin, zone->mctx); 1361 dns_name_init(&zone->origin, NULL); 1362 } 1363 result = dns_name_dup(origin, zone->mctx, &zone->origin); 1364 1365 if (zone->strnamerd != NULL) 1366 isc_mem_free(zone->mctx, zone->strnamerd); 1367 if (zone->strname != NULL) 1368 isc_mem_free(zone->mctx, zone->strname); 1369 1370 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1371 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1372 zone_name_tostr(zone, namebuf, sizeof namebuf); 1373 zone->strname = isc_mem_strdup(zone->mctx, namebuf); 1374 1375 if (result == ISC_R_SUCCESS && inline_secure(zone)) 1376 result = dns_zone_setorigin(zone->raw, origin); 1377 UNLOCK_ZONE(zone); 1378 return (result); 1379} 1380 1381void 1382dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) { 1383 REQUIRE(DNS_ZONE_VALID(zone)); 1384 REQUIRE(acache != NULL); 1385 1386 LOCK_ZONE(zone); 1387 if (zone->acache != NULL) 1388 dns_acache_detach(&zone->acache); 1389 dns_acache_attach(acache, &zone->acache); 1390 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1391 if (zone->db != NULL) { 1392 isc_result_t result; 1393 1394 /* 1395 * If the zone reuses an existing DB, the DB needs to be 1396 * set in the acache explicitly. We can safely ignore the 1397 * case where the DB is already set. If other error happens, 1398 * the acache will not work effectively. 1399 */ 1400 result = dns_acache_setdb(acache, zone->db); 1401 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { 1402 UNEXPECTED_ERROR(__FILE__, __LINE__, 1403 "dns_acache_setdb() failed: %s", 1404 isc_result_totext(result)); 1405 } 1406 } 1407 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1408 UNLOCK_ZONE(zone); 1409} 1410 1411static isc_result_t 1412dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) { 1413 char *copy; 1414 1415 if (value != NULL) { 1416 copy = isc_mem_strdup(zone->mctx, value); 1417 if (copy == NULL) 1418 return (ISC_R_NOMEMORY); 1419 } else { 1420 copy = NULL; 1421 } 1422 1423 if (*field != NULL) 1424 isc_mem_free(zone->mctx, *field); 1425 1426 *field = copy; 1427 return (ISC_R_SUCCESS); 1428} 1429 1430isc_result_t 1431dns_zone_setfile(dns_zone_t *zone, const char *file) { 1432 return (dns_zone_setfile2(zone, file, dns_masterformat_text)); 1433} 1434 1435isc_result_t 1436dns_zone_setfile2(dns_zone_t *zone, const char *file, 1437 dns_masterformat_t format) { 1438 isc_result_t result = ISC_R_SUCCESS; 1439 1440 REQUIRE(DNS_ZONE_VALID(zone)); 1441 1442 LOCK_ZONE(zone); 1443 result = dns_zone_setstring(zone, &zone->masterfile, file); 1444 if (result == ISC_R_SUCCESS) { 1445 zone->masterformat = format; 1446 result = default_journal(zone); 1447 } 1448 UNLOCK_ZONE(zone); 1449 1450 return (result); 1451} 1452 1453const char * 1454dns_zone_getfile(dns_zone_t *zone) { 1455 REQUIRE(DNS_ZONE_VALID(zone)); 1456 1457 return (zone->masterfile); 1458} 1459 1460static isc_result_t 1461default_journal(dns_zone_t *zone) { 1462 isc_result_t result; 1463 char *journal; 1464 1465 REQUIRE(DNS_ZONE_VALID(zone)); 1466 REQUIRE(LOCKED_ZONE(zone)); 1467 1468 if (zone->masterfile != NULL) { 1469 /* Calculate string length including '\0'. */ 1470 int len = strlen(zone->masterfile) + sizeof(".jnl"); 1471 journal = isc_mem_allocate(zone->mctx, len); 1472 if (journal == NULL) 1473 return (ISC_R_NOMEMORY); 1474 strcpy(journal, zone->masterfile); 1475 strcat(journal, ".jnl"); 1476 } else { 1477 journal = NULL; 1478 } 1479 result = dns_zone_setstring(zone, &zone->journal, journal); 1480 if (journal != NULL) 1481 isc_mem_free(zone->mctx, journal); 1482 return (result); 1483} 1484 1485isc_result_t 1486dns_zone_setjournal(dns_zone_t *zone, const char *journal) { 1487 isc_result_t result = ISC_R_SUCCESS; 1488 1489 REQUIRE(DNS_ZONE_VALID(zone)); 1490 1491 LOCK_ZONE(zone); 1492 result = dns_zone_setstring(zone, &zone->journal, journal); 1493 UNLOCK_ZONE(zone); 1494 1495 return (result); 1496} 1497 1498char * 1499dns_zone_getjournal(dns_zone_t *zone) { 1500 REQUIRE(DNS_ZONE_VALID(zone)); 1501 1502 return (zone->journal); 1503} 1504 1505/* 1506 * Return true iff the zone is "dynamic", in the sense that the zone's 1507 * master file (if any) is written by the server, rather than being 1508 * updated manually and read by the server. 1509 * 1510 * This is true for slave zones, stub zones, key zones, and zones that 1511 * allow dynamic updates either by having an update policy ("ssutable") 1512 * or an "allow-update" ACL with a value other than exactly "{ none; }". 1513 */ 1514isc_boolean_t 1515dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze) { 1516 REQUIRE(DNS_ZONE_VALID(zone)); 1517 1518 if (zone->type == dns_zone_slave || zone->type == dns_zone_stub || 1519 zone->type == dns_zone_key || 1520 (zone->type == dns_zone_redirect && zone->masters != NULL)) 1521 return (ISC_TRUE); 1522 1523 /* If !ignore_freeze, we need check whether updates are disabled. */ 1524 if (zone->type == dns_zone_master && 1525 (!zone->update_disabled || ignore_freeze) && 1526 ((zone->ssutable != NULL) || 1527 (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)))) 1528 return (ISC_TRUE); 1529 1530 return (ISC_FALSE); 1531 1532} 1533 1534/* 1535 * Set the response policy index and information for a zone. 1536 */ 1537isc_result_t 1538dns_zone_rpz_enable(dns_zone_t *zone) { 1539 /* 1540 * Only RBTDB zones can be used for response policy zones, 1541 * because only they have the code to load the create the summary data. 1542 * Only zones that are loaded instead of mmap()ed create the 1543 * summary data and so can be policy zones. 1544 */ 1545 if (strcmp(zone->db_argv[0], "rbt") != 0 && 1546 strcmp(zone->db_argv[0], "rbt64") != 0) 1547 return (ISC_R_NOTIMPLEMENTED); 1548 1549 zone->is_rpz = ISC_TRUE; 1550 1551 return (ISC_R_SUCCESS); 1552} 1553 1554isc_boolean_t 1555dns_zone_get_rpz(dns_zone_t *zone) { 1556 return (zone->is_rpz); 1557} 1558 1559/* 1560 * If a zone is a response policy zone, mark its new database. 1561 */ 1562isc_result_t 1563dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) { 1564#ifdef BIND9 1565 if (zone->is_rpz) 1566 return (dns_db_rpz_enabled(db, NULL)); 1567#endif 1568 return (ISC_R_SUCCESS); 1569} 1570 1571static isc_result_t 1572zone_load(dns_zone_t *zone, unsigned int flags) { 1573 isc_result_t result; 1574 isc_time_t now; 1575 isc_time_t loadtime, filetime; 1576 dns_db_t *db = NULL; 1577 isc_boolean_t rbt, hasraw; 1578 1579 REQUIRE(DNS_ZONE_VALID(zone)); 1580 1581 LOCK_ZONE(zone); 1582 hasraw = inline_secure(zone); 1583 if (hasraw) { 1584 result = zone_load(zone->raw, flags); 1585 if (result != ISC_R_SUCCESS) { 1586 UNLOCK_ZONE(zone); 1587 return(result); 1588 } 1589 LOCK_ZONE(zone->raw); 1590 } 1591 1592 TIME_NOW(&now); 1593 1594 INSIST(zone->type != dns_zone_none); 1595 1596 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { 1597 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) 1598 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 1599 result = DNS_R_CONTINUE; 1600 goto cleanup; 1601 } 1602 1603 INSIST(zone->db_argc >= 1); 1604 1605 rbt = strcmp(zone->db_argv[0], "rbt") == 0 || 1606 strcmp(zone->db_argv[0], "rbt64") == 0; 1607 1608 if (zone->db != NULL && zone->masterfile == NULL && rbt) { 1609 /* 1610 * The zone has no master file configured. 1611 */ 1612 result = ISC_R_SUCCESS; 1613 goto cleanup; 1614 } 1615 1616 if (zone->db != NULL && dns_zone_isdynamic(zone, ISC_FALSE)) { 1617 /* 1618 * This is a slave, stub, or dynamically updated 1619 * zone being reloaded. Do nothing - the database 1620 * we already have is guaranteed to be up-to-date. 1621 */ 1622 if (zone->type == dns_zone_master) 1623 result = DNS_R_DYNAMIC; 1624 else 1625 result = ISC_R_SUCCESS; 1626 goto cleanup; 1627 } 1628 1629 /* 1630 * Store the current time before the zone is loaded, so that if the 1631 * file changes between the time of the load and the time that 1632 * zone->loadtime is set, then the file will still be reloaded 1633 * the next time dns_zone_load is called. 1634 */ 1635 TIME_NOW(&loadtime); 1636 1637 /* 1638 * Don't do the load if the file that stores the zone is older 1639 * than the last time the zone was loaded. If the zone has not 1640 * been loaded yet, zone->loadtime will be the epoch. 1641 */ 1642 if (zone->masterfile != NULL) { 1643 /* 1644 * The file is already loaded. If we are just doing a 1645 * "rndc reconfig", we are done. 1646 */ 1647 if (!isc_time_isepoch(&zone->loadtime) && 1648 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) { 1649 result = ISC_R_SUCCESS; 1650 goto cleanup; 1651 } 1652 1653 result = isc_file_getmodtime(zone->masterfile, &filetime); 1654 if (result == ISC_R_SUCCESS) { 1655 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 1656 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) && 1657 isc_time_compare(&filetime, &zone->loadtime) <= 0) { 1658 dns_zone_log(zone, ISC_LOG_DEBUG(1), 1659 "skipping load: master file " 1660 "older than last load"); 1661 result = DNS_R_UPTODATE; 1662 goto cleanup; 1663 } 1664 loadtime = filetime; 1665 } 1666 } 1667 1668 /* 1669 * Built in zones (with the exception of empty zones) don't need 1670 * to be reloaded. 1671 */ 1672 if (zone->type == dns_zone_master && 1673 strcmp(zone->db_argv[0], "_builtin") == 0 && 1674 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) && 1675 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 1676 result = ISC_R_SUCCESS; 1677 goto cleanup; 1678 } 1679 1680 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub || 1681 (zone->type == dns_zone_redirect && zone->masters != NULL)) && 1682 rbt) { 1683 if (zone->masterfile == NULL || 1684 !isc_file_exists(zone->masterfile)) { 1685 if (zone->masterfile != NULL) { 1686 dns_zone_log(zone, ISC_LOG_DEBUG(1), 1687 "no master file"); 1688 } 1689 zone->refreshtime = now; 1690 if (zone->task != NULL) 1691 zone_settimer(zone, &now); 1692 result = ISC_R_SUCCESS; 1693 goto cleanup; 1694 } 1695 } 1696 1697 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load"); 1698 1699 result = dns_db_create(zone->mctx, zone->db_argv[0], 1700 &zone->origin, (zone->type == dns_zone_stub) ? 1701 dns_dbtype_stub : dns_dbtype_zone, 1702 zone->rdclass, 1703 zone->db_argc - 1, zone->db_argv + 1, 1704 &db); 1705 1706 if (result != ISC_R_SUCCESS) { 1707 dns_zone_log(zone, ISC_LOG_ERROR, 1708 "loading zone: creating database: %s", 1709 isc_result_totext(result)); 1710 goto cleanup; 1711 } 1712 dns_db_settask(db, zone->task); 1713 1714 if (! dns_db_ispersistent(db)) { 1715 if (zone->masterfile != NULL) { 1716 result = zone_startload(db, zone, loadtime); 1717 } else { 1718 result = DNS_R_NOMASTERFILE; 1719 if (zone->type == dns_zone_master || 1720 (zone->type == dns_zone_redirect && 1721 zone->masters == NULL)) { 1722 dns_zone_log(zone, ISC_LOG_ERROR, 1723 "loading zone: " 1724 "no master file configured"); 1725 goto cleanup; 1726 } 1727 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: " 1728 "no master file configured: continuing"); 1729 } 1730 } 1731 1732 if (result == DNS_R_CONTINUE) { 1733 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING); 1734 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) 1735 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 1736 goto cleanup; 1737 } 1738 1739 result = zone_postload(zone, db, loadtime, result); 1740 1741 cleanup: 1742 if (hasraw) 1743 UNLOCK_ZONE(zone->raw); 1744 UNLOCK_ZONE(zone); 1745 if (db != NULL) 1746 dns_db_detach(&db); 1747 return (result); 1748} 1749 1750isc_result_t 1751dns_zone_load(dns_zone_t *zone) { 1752 return (zone_load(zone, 0)); 1753} 1754 1755isc_result_t 1756dns_zone_loadnew(dns_zone_t *zone) { 1757 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT)); 1758} 1759 1760static void 1761zone_asyncload(isc_task_t *task, isc_event_t *event) { 1762 dns_asyncload_t *asl = event->ev_arg; 1763 dns_zone_t *zone = asl->zone; 1764 isc_result_t result = ISC_R_SUCCESS; 1765 1766 UNUSED(task); 1767 1768 REQUIRE(DNS_ZONE_VALID(zone)); 1769 1770 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) 1771 result = ISC_R_CANCELED; 1772 isc_event_free(&event); 1773 if (result == ISC_R_CANCELED || 1774 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) 1775 goto cleanup; 1776 1777 zone_load(zone, 0); 1778 1779 LOCK_ZONE(zone); 1780 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); 1781 UNLOCK_ZONE(zone); 1782 1783 /* Inform the zone table we've finished loading */ 1784 if (asl->loaded != NULL) 1785 (asl->loaded)(asl->loaded_arg, zone, task); 1786 1787 cleanup: 1788 isc_mem_put(zone->mctx, asl, sizeof (*asl)); 1789 dns_zone_idetach(&zone); 1790} 1791 1792isc_result_t 1793dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) { 1794 isc_event_t *e; 1795 dns_asyncload_t *asl = NULL; 1796 isc_result_t result = ISC_R_SUCCESS; 1797 1798 REQUIRE(DNS_ZONE_VALID(zone)); 1799 1800 if (zone->zmgr == NULL) 1801 return (ISC_R_FAILURE); 1802 1803 asl = isc_mem_get(zone->mctx, sizeof (*asl)); 1804 if (asl == NULL) 1805 CHECK(ISC_R_NOMEMORY); 1806 1807 asl->zone = NULL; 1808 asl->loaded = done; 1809 asl->loaded_arg = arg; 1810 1811 e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr, 1812 DNS_EVENT_ZONELOAD, 1813 zone_asyncload, asl, 1814 sizeof(isc_event_t)); 1815 if (e == NULL) 1816 CHECK(ISC_R_NOMEMORY); 1817 1818 LOCK_ZONE(zone); 1819 zone_iattach(zone, &asl->zone); 1820 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING); 1821 isc_task_send(zone->loadtask, &e); 1822 UNLOCK_ZONE(zone); 1823 1824 return (ISC_R_SUCCESS); 1825 1826 failure: 1827 if (asl != NULL) 1828 isc_mem_put(zone->mctx, asl, sizeof (*asl)); 1829 return (result); 1830} 1831 1832isc_boolean_t 1833dns__zone_loadpending(dns_zone_t *zone) { 1834 REQUIRE(DNS_ZONE_VALID(zone)); 1835 1836 return (ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))); 1837} 1838 1839isc_result_t 1840dns_zone_loadandthaw(dns_zone_t *zone) { 1841 isc_result_t result; 1842 1843 if (inline_raw(zone)) 1844 result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW); 1845 else 1846 result = zone_load(zone, DNS_ZONELOADFLAG_THAW); 1847 1848 switch (result) { 1849 case DNS_R_CONTINUE: 1850 /* Deferred thaw. */ 1851 break; 1852 case DNS_R_UPTODATE: 1853 case ISC_R_SUCCESS: 1854 case DNS_R_SEENINCLUDE: 1855 zone->update_disabled = ISC_FALSE; 1856 break; 1857 case DNS_R_NOMASTERFILE: 1858 zone->update_disabled = ISC_FALSE; 1859 break; 1860 default: 1861 /* Error, remain in disabled state. */ 1862 break; 1863 } 1864 return (result); 1865} 1866 1867static unsigned int 1868get_master_options(dns_zone_t *zone) { 1869 unsigned int options; 1870 1871 options = DNS_MASTER_ZONE; 1872 if (zone->type == dns_zone_slave || 1873 (zone->type == dns_zone_redirect && zone->masters == NULL)) 1874 options |= DNS_MASTER_SLAVE; 1875 if (zone->type == dns_zone_key) 1876 options |= DNS_MASTER_KEY; 1877 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) 1878 options |= DNS_MASTER_CHECKNS; 1879 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) 1880 options |= DNS_MASTER_FATALNS; 1881 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) 1882 options |= DNS_MASTER_CHECKNAMES; 1883 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) 1884 options |= DNS_MASTER_CHECKNAMESFAIL; 1885 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) 1886 options |= DNS_MASTER_CHECKMX; 1887 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) 1888 options |= DNS_MASTER_CHECKMXFAIL; 1889 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) 1890 options |= DNS_MASTER_CHECKWILDCARD; 1891 if (inline_secure(zone) || (zone->type == dns_zone_master && 1892 ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) || 1893 zone->ssutable != NULL))) 1894 options |= DNS_MASTER_RESIGN; 1895 return (options); 1896} 1897 1898static void 1899zone_gotreadhandle(isc_task_t *task, isc_event_t *event) { 1900 dns_load_t *load = event->ev_arg; 1901 isc_result_t result = ISC_R_SUCCESS; 1902 unsigned int options; 1903 1904 REQUIRE(DNS_LOAD_VALID(load)); 1905 1906 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) 1907 result = ISC_R_CANCELED; 1908 isc_event_free(&event); 1909 if (result == ISC_R_CANCELED) 1910 goto fail; 1911 1912 options = get_master_options(load->zone); 1913 1914 result = dns_master_loadfileinc3(load->zone->masterfile, 1915 dns_db_origin(load->db), 1916 dns_db_origin(load->db), 1917 load->zone->rdclass, options, 0, 1918 &load->callbacks, task, 1919 zone_loaddone, load, 1920 &load->zone->lctx, load->zone->mctx, 1921 load->zone->masterformat); 1922 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE && 1923 result != DNS_R_SEENINCLUDE) 1924 goto fail; 1925 return; 1926 1927 fail: 1928 zone_loaddone(load, result); 1929} 1930 1931static void 1932get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) { 1933 isc_result_t result; 1934 unsigned int soacount; 1935 1936 LOCK(&raw->lock); 1937 if (raw->db != NULL) { 1938 result = zone_get_from_db(raw, raw->db, NULL, &soacount, 1939 &rawdata->sourceserial, 1940 NULL, NULL, NULL, NULL, 1941 NULL); 1942 if (result == ISC_R_SUCCESS && soacount > 0U) 1943 rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET; 1944 } 1945 UNLOCK(&raw->lock); 1946} 1947 1948static void 1949zone_gotwritehandle(isc_task_t *task, isc_event_t *event) { 1950 const char me[] = "zone_gotwritehandle"; 1951 dns_zone_t *zone = event->ev_arg; 1952 isc_result_t result = ISC_R_SUCCESS; 1953 dns_dbversion_t *version = NULL; 1954 dns_masterrawheader_t rawdata; 1955 1956 REQUIRE(DNS_ZONE_VALID(zone)); 1957 INSIST(task == zone->task); 1958 ENTER; 1959 1960 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) 1961 result = ISC_R_CANCELED; 1962 isc_event_free(&event); 1963 if (result == ISC_R_CANCELED) 1964 goto fail; 1965 1966 LOCK_ZONE(zone); 1967 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1968 if (zone->db != NULL) { 1969 const dns_master_style_t *output_style; 1970 1971 dns_db_currentversion(zone->db, &version); 1972 dns_master_initrawheader(&rawdata); 1973 if (inline_secure(zone)) 1974 get_raw_serial(zone->raw, &rawdata); 1975 if (zone->type == dns_zone_key) 1976 output_style = &dns_master_style_keyzone; 1977 else 1978 output_style = &dns_master_style_default; 1979 result = dns_master_dumpinc3(zone->mctx, zone->db, version, 1980 output_style, zone->masterfile, 1981 zone->task, dump_done, zone, &zone->dctx, zone->masterformat, 1982 &rawdata); 1983 dns_db_closeversion(zone->db, &version, ISC_FALSE); 1984 } else 1985 result = ISC_R_CANCELED; 1986 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1987 UNLOCK_ZONE(zone); 1988 if (result != DNS_R_CONTINUE) 1989 goto fail; 1990 return; 1991 1992 fail: 1993 dump_done(zone, result); 1994} 1995 1996/* 1997 * Save the raw serial number for inline-signing zones. 1998 * (XXX: Other information from the header will be used 1999 * for other purposes in the future, but for now this is 2000 * all we're interested in.) 2001 */ 2002static void 2003zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { 2004 if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0) 2005 return; 2006 2007 zone->sourceserial = header->sourceserial; 2008 zone->sourceserialset = ISC_TRUE; 2009} 2010 2011void 2012dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { 2013 if (zone == NULL) 2014 return; 2015 2016 LOCK_ZONE(zone); 2017 zone_setrawdata(zone, header); 2018 UNLOCK_ZONE(zone); 2019} 2020 2021static isc_result_t 2022zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { 2023 dns_load_t *load; 2024 isc_result_t result; 2025 isc_result_t tresult; 2026 unsigned int options; 2027 2028 result = dns_zone_rpz_enable_db(zone, db); 2029 if (result != ISC_R_SUCCESS) 2030 return (result); 2031 options = get_master_options(zone); 2032 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) 2033 options |= DNS_MASTER_MANYERRORS; 2034 2035 if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) { 2036 load = isc_mem_get(zone->mctx, sizeof(*load)); 2037 if (load == NULL) 2038 return (ISC_R_NOMEMORY); 2039 2040 load->mctx = NULL; 2041 load->zone = NULL; 2042 load->db = NULL; 2043 load->loadtime = loadtime; 2044 load->magic = LOAD_MAGIC; 2045 2046 isc_mem_attach(zone->mctx, &load->mctx); 2047 zone_iattach(zone, &load->zone); 2048 dns_db_attach(db, &load->db); 2049 dns_rdatacallbacks_init(&load->callbacks); 2050 load->callbacks.rawdata = zone_setrawdata; 2051 zone_iattach(zone, &load->callbacks.zone); 2052 result = dns_db_beginload(db, &load->callbacks.add, 2053 &load->callbacks.add_private); 2054 if (result != ISC_R_SUCCESS) 2055 goto cleanup; 2056 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->loadtask, 2057 zone_gotreadhandle, load, 2058 &zone->readio); 2059 if (result != ISC_R_SUCCESS) { 2060 /* 2061 * We can't report multiple errors so ignore 2062 * the result of dns_db_endload(). 2063 */ 2064 (void)dns_db_endload(load->db, 2065 &load->callbacks.add_private); 2066 goto cleanup; 2067 } else 2068 result = DNS_R_CONTINUE; 2069 } else { 2070 dns_rdatacallbacks_t callbacks; 2071 2072 dns_rdatacallbacks_init(&callbacks); 2073 callbacks.rawdata = zone_setrawdata; 2074 zone_iattach(zone, &callbacks.zone); 2075 result = dns_db_beginload(db, &callbacks.add, 2076 &callbacks.add_private); 2077 if (result != ISC_R_SUCCESS) { 2078 zone_idetach(&callbacks.zone); 2079 return (result); 2080 } 2081 result = dns_master_loadfile3(zone->masterfile, 2082 &zone->origin, &zone->origin, 2083 zone->rdclass, options, 0, 2084 &callbacks, zone->mctx, 2085 zone->masterformat); 2086 tresult = dns_db_endload(db, &callbacks.add_private); 2087 if (result == ISC_R_SUCCESS) 2088 result = tresult; 2089 zone_idetach(&callbacks.zone); 2090 } 2091 2092 return (result); 2093 2094 cleanup: 2095 load->magic = 0; 2096 dns_db_detach(&load->db); 2097 zone_idetach(&load->zone); 2098 zone_idetach(&load->callbacks.zone); 2099 isc_mem_detach(&load->mctx); 2100 isc_mem_put(zone->mctx, load, sizeof(*load)); 2101 return (result); 2102} 2103 2104static isc_boolean_t 2105zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2106 dns_name_t *owner) 2107{ 2108 isc_result_t result; 2109 char ownerbuf[DNS_NAME_FORMATSIZE]; 2110 char namebuf[DNS_NAME_FORMATSIZE]; 2111 char altbuf[DNS_NAME_FORMATSIZE]; 2112 dns_fixedname_t fixed; 2113 dns_name_t *foundname; 2114 int level; 2115 2116 /* 2117 * "." means the services does not exist. 2118 */ 2119 if (dns_name_equal(name, dns_rootname)) 2120 return (ISC_TRUE); 2121 2122 /* 2123 * Outside of zone. 2124 */ 2125 if (!dns_name_issubdomain(name, &zone->origin)) { 2126 if (zone->checkmx != NULL) 2127 return ((zone->checkmx)(zone, name, owner)); 2128 return (ISC_TRUE); 2129 } 2130 2131 if (zone->type == dns_zone_master) 2132 level = ISC_LOG_ERROR; 2133 else 2134 level = ISC_LOG_WARNING; 2135 2136 dns_fixedname_init(&fixed); 2137 foundname = dns_fixedname_name(&fixed); 2138 2139 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 2140 0, 0, NULL, foundname, NULL, NULL); 2141 if (result == ISC_R_SUCCESS) 2142 return (ISC_TRUE); 2143 2144 if (result == DNS_R_NXRRSET) { 2145 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 2146 0, 0, NULL, foundname, NULL, NULL); 2147 if (result == ISC_R_SUCCESS) 2148 return (ISC_TRUE); 2149 } 2150 2151 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2152 dns_name_format(name, namebuf, sizeof namebuf); 2153 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2154 result == DNS_R_EMPTYNAME) { 2155 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) 2156 level = ISC_LOG_WARNING; 2157 dns_zone_log(zone, level, 2158 "%s/MX '%s' has no address records (A or AAAA)", 2159 ownerbuf, namebuf); 2160 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2161 } 2162 2163 if (result == DNS_R_CNAME) { 2164 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 2165 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2166 level = ISC_LOG_WARNING; 2167 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2168 dns_zone_log(zone, level, 2169 "%s/MX '%s' is a CNAME (illegal)", 2170 ownerbuf, namebuf); 2171 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2172 } 2173 2174 if (result == DNS_R_DNAME) { 2175 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 2176 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2177 level = ISC_LOG_WARNING; 2178 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { 2179 dns_name_format(foundname, altbuf, sizeof altbuf); 2180 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME" 2181 " '%s' (illegal)", ownerbuf, namebuf, 2182 altbuf); 2183 } 2184 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2185 } 2186 2187 if (zone->checkmx != NULL && result == DNS_R_DELEGATION) 2188 return ((zone->checkmx)(zone, name, owner)); 2189 2190 return (ISC_TRUE); 2191} 2192 2193static isc_boolean_t 2194zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2195 dns_name_t *owner) 2196{ 2197 isc_result_t result; 2198 char ownerbuf[DNS_NAME_FORMATSIZE]; 2199 char namebuf[DNS_NAME_FORMATSIZE]; 2200 char altbuf[DNS_NAME_FORMATSIZE]; 2201 dns_fixedname_t fixed; 2202 dns_name_t *foundname; 2203 int level; 2204 2205 /* 2206 * "." means the services does not exist. 2207 */ 2208 if (dns_name_equal(name, dns_rootname)) 2209 return (ISC_TRUE); 2210 2211 /* 2212 * Outside of zone. 2213 */ 2214 if (!dns_name_issubdomain(name, &zone->origin)) { 2215 if (zone->checksrv != NULL) 2216 return ((zone->checksrv)(zone, name, owner)); 2217 return (ISC_TRUE); 2218 } 2219 2220 if (zone->type == dns_zone_master) 2221 level = ISC_LOG_ERROR; 2222 else 2223 level = ISC_LOG_WARNING; 2224 2225 dns_fixedname_init(&fixed); 2226 foundname = dns_fixedname_name(&fixed); 2227 2228 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 2229 0, 0, NULL, foundname, NULL, NULL); 2230 if (result == ISC_R_SUCCESS) 2231 return (ISC_TRUE); 2232 2233 if (result == DNS_R_NXRRSET) { 2234 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 2235 0, 0, NULL, foundname, NULL, NULL); 2236 if (result == ISC_R_SUCCESS) 2237 return (ISC_TRUE); 2238 } 2239 2240 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2241 dns_name_format(name, namebuf, sizeof namebuf); 2242 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2243 result == DNS_R_EMPTYNAME) { 2244 dns_zone_log(zone, level, 2245 "%s/SRV '%s' has no address records (A or AAAA)", 2246 ownerbuf, namebuf); 2247 /* XXX950 make fatal for 9.5.0. */ 2248 return (ISC_TRUE); 2249 } 2250 2251 if (result == DNS_R_CNAME) { 2252 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 2253 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2254 level = ISC_LOG_WARNING; 2255 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2256 dns_zone_log(zone, level, 2257 "%s/SRV '%s' is a CNAME (illegal)", 2258 ownerbuf, namebuf); 2259 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2260 } 2261 2262 if (result == DNS_R_DNAME) { 2263 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 2264 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2265 level = ISC_LOG_WARNING; 2266 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { 2267 dns_name_format(foundname, altbuf, sizeof altbuf); 2268 dns_zone_log(zone, level, "%s/SRV '%s' is below a " 2269 "DNAME '%s' (illegal)", ownerbuf, namebuf, 2270 altbuf); 2271 } 2272 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2273 } 2274 2275 if (zone->checksrv != NULL && result == DNS_R_DELEGATION) 2276 return ((zone->checksrv)(zone, name, owner)); 2277 2278 return (ISC_TRUE); 2279} 2280 2281static isc_boolean_t 2282zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2283 dns_name_t *owner) 2284{ 2285 isc_boolean_t answer = ISC_TRUE; 2286 isc_result_t result, tresult; 2287 char ownerbuf[DNS_NAME_FORMATSIZE]; 2288 char namebuf[DNS_NAME_FORMATSIZE]; 2289 char altbuf[DNS_NAME_FORMATSIZE]; 2290 dns_fixedname_t fixed; 2291 dns_name_t *foundname; 2292 dns_rdataset_t a; 2293 dns_rdataset_t aaaa; 2294 int level; 2295 2296 /* 2297 * Outside of zone. 2298 */ 2299 if (!dns_name_issubdomain(name, &zone->origin)) { 2300 if (zone->checkns != NULL) 2301 return ((zone->checkns)(zone, name, owner, NULL, NULL)); 2302 return (ISC_TRUE); 2303 } 2304 2305 if (zone->type == dns_zone_master) 2306 level = ISC_LOG_ERROR; 2307 else 2308 level = ISC_LOG_WARNING; 2309 2310 dns_fixedname_init(&fixed); 2311 foundname = dns_fixedname_name(&fixed); 2312 dns_rdataset_init(&a); 2313 dns_rdataset_init(&aaaa); 2314 2315 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 2316 DNS_DBFIND_GLUEOK, 0, NULL, 2317 foundname, &a, NULL); 2318 2319 if (result == ISC_R_SUCCESS) { 2320 dns_rdataset_disassociate(&a); 2321 return (ISC_TRUE); 2322 } else if (result == DNS_R_DELEGATION) 2323 dns_rdataset_disassociate(&a); 2324 2325 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION || 2326 result == DNS_R_GLUE) { 2327 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 2328 DNS_DBFIND_GLUEOK, 0, NULL, 2329 foundname, &aaaa, NULL); 2330 if (tresult == ISC_R_SUCCESS) { 2331 dns_rdataset_disassociate(&aaaa); 2332 return (ISC_TRUE); 2333 } 2334 if (tresult == DNS_R_DELEGATION) 2335 dns_rdataset_disassociate(&aaaa); 2336 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) { 2337 /* 2338 * Check glue against child zone. 2339 */ 2340 if (zone->checkns != NULL) 2341 answer = (zone->checkns)(zone, name, owner, 2342 &a, &aaaa); 2343 if (dns_rdataset_isassociated(&a)) 2344 dns_rdataset_disassociate(&a); 2345 if (dns_rdataset_isassociated(&aaaa)) 2346 dns_rdataset_disassociate(&aaaa); 2347 return (answer); 2348 } 2349 } 2350 2351 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2352 dns_name_format(name, namebuf, sizeof namebuf); 2353 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2354 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) { 2355 const char *what; 2356 isc_boolean_t required = ISC_FALSE; 2357 if (dns_name_issubdomain(name, owner)) { 2358 what = "REQUIRED GLUE "; 2359 required = ISC_TRUE; 2360 } else if (result == DNS_R_DELEGATION) 2361 what = "SIBLING GLUE "; 2362 else 2363 what = ""; 2364 2365 if (result != DNS_R_DELEGATION || required || 2366 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) { 2367 dns_zone_log(zone, level, "%s/NS '%s' has no %s" 2368 "address records (A or AAAA)", 2369 ownerbuf, namebuf, what); 2370 /* 2371 * Log missing address record. 2372 */ 2373 if (result == DNS_R_DELEGATION && zone->checkns != NULL) 2374 (void)(zone->checkns)(zone, name, owner, 2375 &a, &aaaa); 2376 /* XXX950 make fatal for 9.5.0. */ 2377 /* answer = ISC_FALSE; */ 2378 } 2379 } else if (result == DNS_R_CNAME) { 2380 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)", 2381 ownerbuf, namebuf); 2382 /* XXX950 make fatal for 9.5.0. */ 2383 /* answer = ISC_FALSE; */ 2384 } else if (result == DNS_R_DNAME) { 2385 dns_name_format(foundname, altbuf, sizeof altbuf); 2386 dns_zone_log(zone, level, 2387 "%s/NS '%s' is below a DNAME '%s' (illegal)", 2388 ownerbuf, namebuf, altbuf); 2389 /* XXX950 make fatal for 9.5.0. */ 2390 /* answer = ISC_FALSE; */ 2391 } 2392 2393 if (dns_rdataset_isassociated(&a)) 2394 dns_rdataset_disassociate(&a); 2395 if (dns_rdataset_isassociated(&aaaa)) 2396 dns_rdataset_disassociate(&aaaa); 2397 return (answer); 2398} 2399 2400static isc_boolean_t 2401zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner, 2402 dns_rdataset_t *rdataset) 2403{ 2404 dns_rdataset_t tmprdataset; 2405 isc_result_t result; 2406 isc_boolean_t answer = ISC_TRUE; 2407 isc_boolean_t format = ISC_TRUE; 2408 int level = ISC_LOG_WARNING; 2409 char ownerbuf[DNS_NAME_FORMATSIZE]; 2410 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 2411 unsigned int count1 = 0; 2412 2413 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL)) 2414 level = ISC_LOG_ERROR; 2415 2416 dns_rdataset_init(&tmprdataset); 2417 for (result = dns_rdataset_first(rdataset); 2418 result == ISC_R_SUCCESS; 2419 result = dns_rdataset_next(rdataset)) { 2420 dns_rdata_t rdata1 = DNS_RDATA_INIT; 2421 unsigned int count2 = 0; 2422 2423 count1++; 2424 dns_rdataset_current(rdataset, &rdata1); 2425 dns_rdataset_clone(rdataset, &tmprdataset); 2426 for (result = dns_rdataset_first(&tmprdataset); 2427 result == ISC_R_SUCCESS; 2428 result = dns_rdataset_next(&tmprdataset)) { 2429 dns_rdata_t rdata2 = DNS_RDATA_INIT; 2430 count2++; 2431 if (count1 >= count2) 2432 continue; 2433 dns_rdataset_current(&tmprdataset, &rdata2); 2434 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) { 2435 if (format) { 2436 dns_name_format(owner, ownerbuf, 2437 sizeof ownerbuf); 2438 dns_rdatatype_format(rdata1.type, 2439 typebuf, 2440 sizeof(typebuf)); 2441 format = ISC_FALSE; 2442 } 2443 dns_zone_log(zone, level, "%s/%s has " 2444 "semantically identical records", 2445 ownerbuf, typebuf); 2446 if (level == ISC_LOG_ERROR) 2447 answer = ISC_FALSE; 2448 break; 2449 } 2450 } 2451 dns_rdataset_disassociate(&tmprdataset); 2452 if (!format) 2453 break; 2454 } 2455 return (answer); 2456} 2457 2458static isc_boolean_t 2459zone_check_dup(dns_zone_t *zone, dns_db_t *db) { 2460 dns_dbiterator_t *dbiterator = NULL; 2461 dns_dbnode_t *node = NULL; 2462 dns_fixedname_t fixed; 2463 dns_name_t *name; 2464 dns_rdataset_t rdataset; 2465 dns_rdatasetiter_t *rdsit = NULL; 2466 isc_boolean_t ok = ISC_TRUE; 2467 isc_result_t result; 2468 2469 dns_fixedname_init(&fixed); 2470 name = dns_fixedname_name(&fixed); 2471 dns_rdataset_init(&rdataset); 2472 2473 result = dns_db_createiterator(db, 0, &dbiterator); 2474 if (result != ISC_R_SUCCESS) 2475 return (ISC_TRUE); 2476 2477 for (result = dns_dbiterator_first(dbiterator); 2478 result == ISC_R_SUCCESS; 2479 result = dns_dbiterator_next(dbiterator)) { 2480 result = dns_dbiterator_current(dbiterator, &node, name); 2481 if (result != ISC_R_SUCCESS) 2482 continue; 2483 2484 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit); 2485 if (result != ISC_R_SUCCESS) 2486 continue; 2487 2488 for (result = dns_rdatasetiter_first(rdsit); 2489 result == ISC_R_SUCCESS; 2490 result = dns_rdatasetiter_next(rdsit)) { 2491 dns_rdatasetiter_current(rdsit, &rdataset); 2492 if (!zone_rrset_check_dup(zone, name, &rdataset)) 2493 ok = ISC_FALSE; 2494 dns_rdataset_disassociate(&rdataset); 2495 } 2496 dns_rdatasetiter_destroy(&rdsit); 2497 dns_db_detachnode(db, &node); 2498 } 2499 2500 if (node != NULL) 2501 dns_db_detachnode(db, &node); 2502 dns_dbiterator_destroy(&dbiterator); 2503 2504 return (ok); 2505} 2506 2507static isc_boolean_t 2508isspf(const dns_rdata_t *rdata) { 2509 char buf[1024]; 2510 const unsigned char *data = rdata->data; 2511 unsigned int rdl = rdata->length, i = 0, tl, len; 2512 2513 while (rdl > 0U) { 2514 len = tl = *data; 2515 ++data; 2516 --rdl; 2517 INSIST(tl <= rdl); 2518 if (len > sizeof(buf) - i - 1) 2519 len = sizeof(buf) - i - 1; 2520 memmove(buf + i, data, len); 2521 i += len; 2522 data += tl; 2523 rdl -= tl; 2524 } 2525 2526 if (i < 6U) 2527 return(ISC_FALSE); 2528 2529 buf[i] = 0; 2530 if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' ')) 2531 return (ISC_TRUE); 2532 return (ISC_FALSE); 2533} 2534 2535static isc_boolean_t 2536integrity_checks(dns_zone_t *zone, dns_db_t *db) { 2537 dns_dbiterator_t *dbiterator = NULL; 2538 dns_dbnode_t *node = NULL; 2539 dns_rdataset_t rdataset; 2540 dns_fixedname_t fixed; 2541 dns_fixedname_t fixedbottom; 2542 dns_rdata_mx_t mx; 2543 dns_rdata_ns_t ns; 2544 dns_rdata_in_srv_t srv; 2545 dns_rdata_t rdata; 2546 dns_name_t *name; 2547 dns_name_t *bottom; 2548 isc_result_t result; 2549 isc_boolean_t ok = ISC_TRUE, have_spf, have_txt; 2550 2551 dns_fixedname_init(&fixed); 2552 name = dns_fixedname_name(&fixed); 2553 dns_fixedname_init(&fixedbottom); 2554 bottom = dns_fixedname_name(&fixedbottom); 2555 dns_rdataset_init(&rdataset); 2556 dns_rdata_init(&rdata); 2557 2558 result = dns_db_createiterator(db, 0, &dbiterator); 2559 if (result != ISC_R_SUCCESS) 2560 return (ISC_TRUE); 2561 2562 result = dns_dbiterator_first(dbiterator); 2563 while (result == ISC_R_SUCCESS) { 2564 result = dns_dbiterator_current(dbiterator, &node, name); 2565 if (result != ISC_R_SUCCESS) 2566 goto cleanup; 2567 2568 /* 2569 * Is this name visible in the zone? 2570 */ 2571 if (!dns_name_issubdomain(name, &zone->origin) || 2572 (dns_name_countlabels(bottom) > 0 && 2573 dns_name_issubdomain(name, bottom))) 2574 goto next; 2575 2576 /* 2577 * Don't check the NS records at the origin. 2578 */ 2579 if (dns_name_equal(name, &zone->origin)) 2580 goto checkmx; 2581 2582 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns, 2583 0, 0, &rdataset, NULL); 2584 if (result != ISC_R_SUCCESS) 2585 goto checkmx; 2586 /* 2587 * Remember bottom of zone. 2588 */ 2589 dns_name_copy(name, bottom, NULL); 2590 2591 result = dns_rdataset_first(&rdataset); 2592 while (result == ISC_R_SUCCESS) { 2593 dns_rdataset_current(&rdataset, &rdata); 2594 result = dns_rdata_tostruct(&rdata, &ns, NULL); 2595 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2596 if (!zone_check_glue(zone, db, &ns.name, name)) 2597 ok = ISC_FALSE; 2598 dns_rdata_reset(&rdata); 2599 result = dns_rdataset_next(&rdataset); 2600 } 2601 dns_rdataset_disassociate(&rdataset); 2602 goto next; 2603 2604 checkmx: 2605 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx, 2606 0, 0, &rdataset, NULL); 2607 if (result != ISC_R_SUCCESS) 2608 goto checksrv; 2609 result = dns_rdataset_first(&rdataset); 2610 while (result == ISC_R_SUCCESS) { 2611 dns_rdataset_current(&rdataset, &rdata); 2612 result = dns_rdata_tostruct(&rdata, &mx, NULL); 2613 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2614 if (!zone_check_mx(zone, db, &mx.mx, name)) 2615 ok = ISC_FALSE; 2616 dns_rdata_reset(&rdata); 2617 result = dns_rdataset_next(&rdataset); 2618 } 2619 dns_rdataset_disassociate(&rdataset); 2620 2621 checksrv: 2622 if (zone->rdclass != dns_rdataclass_in) 2623 goto next; 2624 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv, 2625 0, 0, &rdataset, NULL); 2626 if (result != ISC_R_SUCCESS) 2627 goto checkspf; 2628 result = dns_rdataset_first(&rdataset); 2629 while (result == ISC_R_SUCCESS) { 2630 dns_rdataset_current(&rdataset, &rdata); 2631 result = dns_rdata_tostruct(&rdata, &srv, NULL); 2632 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2633 if (!zone_check_srv(zone, db, &srv.target, name)) 2634 ok = ISC_FALSE; 2635 dns_rdata_reset(&rdata); 2636 result = dns_rdataset_next(&rdataset); 2637 } 2638 dns_rdataset_disassociate(&rdataset); 2639 2640 checkspf: 2641 /* 2642 * Check if there is a type TXT spf record without a type SPF 2643 * RRset being present. 2644 */ 2645 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF)) 2646 goto next; 2647 if (zone->rdclass != dns_rdataclass_in) 2648 goto next; 2649 have_spf = have_txt = ISC_FALSE; 2650 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf, 2651 0, 0, &rdataset, NULL); 2652 if (result == ISC_R_SUCCESS) { 2653 dns_rdataset_disassociate(&rdataset); 2654 have_spf = ISC_TRUE; 2655 } 2656 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt, 2657 0, 0, &rdataset, NULL); 2658 if (result != ISC_R_SUCCESS) 2659 goto notxt; 2660 result = dns_rdataset_first(&rdataset); 2661 while (result == ISC_R_SUCCESS) { 2662 dns_rdataset_current(&rdataset, &rdata); 2663 have_txt = isspf(&rdata); 2664 dns_rdata_reset(&rdata); 2665 if (have_txt) 2666 break; 2667 result = dns_rdataset_next(&rdataset); 2668 } 2669 dns_rdataset_disassociate(&rdataset); 2670 2671 notxt: 2672 if (have_spf != have_txt) { 2673 char namebuf[DNS_NAME_FORMATSIZE]; 2674 const char *found = have_txt ? "TXT" : "SPF"; 2675 const char *need = have_txt ? "SPF" : "TXT"; 2676 2677 dns_name_format(name, namebuf, sizeof(namebuf)); 2678 dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found SPF/%s " 2679 "record but no SPF/%s record found, add " 2680 "matching type %s record", namebuf, found, 2681 need, need); 2682 } 2683 2684 next: 2685 dns_db_detachnode(db, &node); 2686 result = dns_dbiterator_next(dbiterator); 2687 } 2688 2689 cleanup: 2690 if (node != NULL) 2691 dns_db_detachnode(db, &node); 2692 dns_dbiterator_destroy(&dbiterator); 2693 2694 return (ok); 2695} 2696 2697/* 2698 * OpenSSL verification of RSA keys with exponent 3 is known to be 2699 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn 2700 * if they are in use. 2701 */ 2702static void 2703zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) { 2704 dns_dbnode_t *node = NULL; 2705 dns_dbversion_t *version = NULL; 2706 dns_rdata_dnskey_t dnskey; 2707 dns_rdata_t rdata = DNS_RDATA_INIT; 2708 dns_rdataset_t rdataset; 2709 isc_result_t result; 2710 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE; 2711 const char *algorithm; 2712 2713 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 2714 if (result != ISC_R_SUCCESS) 2715 goto cleanup; 2716 2717 dns_db_currentversion(db, &version); 2718 dns_rdataset_init(&rdataset); 2719 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 2720 dns_rdatatype_none, 0, &rdataset, NULL); 2721 if (result != ISC_R_SUCCESS) 2722 goto cleanup; 2723 2724 for (result = dns_rdataset_first(&rdataset); 2725 result == ISC_R_SUCCESS; 2726 result = dns_rdataset_next(&rdataset)) 2727 { 2728 dns_rdataset_current(&rdataset, &rdata); 2729 result = dns_rdata_tostruct(&rdata, &dnskey, NULL); 2730 INSIST(result == ISC_R_SUCCESS); 2731 2732 if ((dnskey.algorithm == DST_ALG_RSASHA1 || 2733 dnskey.algorithm == DST_ALG_RSAMD5) && 2734 dnskey.datalen > 1 && dnskey.data[0] == 1 && 2735 dnskey.data[1] == 3) 2736 { 2737 if (dnskey.algorithm == DST_ALG_RSASHA1) { 2738 logit = !foundrsa; 2739 foundrsa = ISC_TRUE; 2740 algorithm = "RSASHA1"; 2741 } else { 2742 logit = !foundmd5; 2743 foundmd5 = ISC_TRUE; 2744 algorithm = "RSAMD5"; 2745 } 2746 if (logit) 2747 dns_zone_log(zone, ISC_LOG_WARNING, 2748 "weak %s (%u) key found " 2749 "(exponent=3)", algorithm, 2750 dnskey.algorithm); 2751 if (foundrsa && foundmd5) 2752 break; 2753 } 2754 dns_rdata_reset(&rdata); 2755 } 2756 dns_rdataset_disassociate(&rdataset); 2757 2758 cleanup: 2759 if (node != NULL) 2760 dns_db_detachnode(db, &node); 2761 if (version != NULL) 2762 dns_db_closeversion(db, &version, ISC_FALSE); 2763} 2764 2765static void 2766resume_signingwithkey(dns_zone_t *zone) { 2767 dns_dbnode_t *node = NULL; 2768 dns_dbversion_t *version = NULL; 2769 dns_rdata_t rdata = DNS_RDATA_INIT; 2770 dns_rdataset_t rdataset; 2771 isc_result_t result; 2772 dns_db_t *db = NULL; 2773 2774 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 2775 if (zone->db != NULL) 2776 dns_db_attach(zone->db, &db); 2777 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 2778 if (db == NULL) 2779 goto cleanup; 2780 2781 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 2782 if (result != ISC_R_SUCCESS) 2783 goto cleanup; 2784 2785 dns_db_currentversion(db, &version); 2786 dns_rdataset_init(&rdataset); 2787 result = dns_db_findrdataset(db, node, version, 2788 zone->privatetype, 2789 dns_rdatatype_none, 0, 2790 &rdataset, NULL); 2791 if (result != ISC_R_SUCCESS) { 2792 INSIST(!dns_rdataset_isassociated(&rdataset)); 2793 goto cleanup; 2794 } 2795 2796 for (result = dns_rdataset_first(&rdataset); 2797 result == ISC_R_SUCCESS; 2798 result = dns_rdataset_next(&rdataset)) 2799 { 2800 dns_rdataset_current(&rdataset, &rdata); 2801 if (rdata.length != 5 || 2802 rdata.data[0] == 0 || rdata.data[4] != 0) { 2803 dns_rdata_reset(&rdata); 2804 continue; 2805 } 2806 2807 result = zone_signwithkey(zone, rdata.data[0], 2808 (rdata.data[1] << 8) | rdata.data[2], 2809 ISC_TF(rdata.data[3])); 2810 if (result != ISC_R_SUCCESS) { 2811 dns_zone_log(zone, ISC_LOG_ERROR, 2812 "zone_signwithkey failed: %s", 2813 dns_result_totext(result)); 2814 } 2815 dns_rdata_reset(&rdata); 2816 } 2817 dns_rdataset_disassociate(&rdataset); 2818 2819 cleanup: 2820 if (db != NULL) { 2821 if (node != NULL) 2822 dns_db_detachnode(db, &node); 2823 if (version != NULL) 2824 dns_db_closeversion(db, &version, ISC_FALSE); 2825 dns_db_detach(&db); 2826 } 2827} 2828 2829static isc_result_t 2830zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 2831 dns_nsec3chain_t *nsec3chain, *current; 2832 dns_dbversion_t *version = NULL; 2833 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; 2834 isc_result_t result; 2835 isc_time_t now; 2836 unsigned int options = 0; 2837 char saltbuf[255*2+1]; 2838 char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")]; 2839 dns_db_t *db = NULL; 2840 int i; 2841 2842 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 2843 if (zone->db != NULL) 2844 dns_db_attach(zone->db, &db); 2845 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 2846 2847 if (db == NULL) { 2848 result = ISC_R_SUCCESS; 2849 goto cleanup; 2850 } 2851 2852 dns_db_currentversion(db, &version); 2853 result = dns_nsec_nseconly(db, version, &nseconly); 2854 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 2855 dns_db_closeversion(db, &version, ISC_FALSE); 2856 if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) { 2857 result = ISC_R_SUCCESS; 2858 goto cleanup; 2859 } 2860 2861 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain); 2862 if (nsec3chain == NULL) { 2863 result = ISC_R_NOMEMORY; 2864 goto cleanup; 2865 } 2866 2867 nsec3chain->magic = 0; 2868 nsec3chain->done = ISC_FALSE; 2869 nsec3chain->db = NULL; 2870 nsec3chain->dbiterator = NULL; 2871 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass; 2872 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype; 2873 nsec3chain->nsec3param.hash = nsec3param->hash; 2874 nsec3chain->nsec3param.iterations = nsec3param->iterations; 2875 nsec3chain->nsec3param.flags = nsec3param->flags; 2876 nsec3chain->nsec3param.salt_length = nsec3param->salt_length; 2877 memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length); 2878 nsec3chain->nsec3param.salt = nsec3chain->salt; 2879 nsec3chain->seen_nsec = ISC_FALSE; 2880 nsec3chain->delete_nsec = ISC_FALSE; 2881 nsec3chain->save_delete_nsec = ISC_FALSE; 2882 2883 if (nsec3param->flags == 0) 2884 strlcpy(flags, "NONE", sizeof(flags)); 2885 else { 2886 flags[0] = '\0'; 2887 if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) 2888 strlcat(flags, "REMOVE", sizeof(flags)); 2889 if (nsec3param->flags & DNS_NSEC3FLAG_INITIAL) { 2890 if (flags[0] == '\0') 2891 strlcpy(flags, "INITIAL", sizeof(flags)); 2892 else 2893 strlcat(flags, "|INITIAL", sizeof(flags)); 2894 } 2895 if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) { 2896 if (flags[0] == '\0') 2897 strlcpy(flags, "CREATE", sizeof(flags)); 2898 else 2899 strlcat(flags, "|CREATE", sizeof(flags)); 2900 } 2901 if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) { 2902 if (flags[0] == '\0') 2903 strlcpy(flags, "NONSEC", sizeof(flags)); 2904 else 2905 strlcat(flags, "|NONSEC", sizeof(flags)); 2906 } 2907 if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) { 2908 if (flags[0] == '\0') 2909 strlcpy(flags, "OPTOUT", sizeof(flags)); 2910 else 2911 strlcat(flags, "|OPTOUT", sizeof(flags)); 2912 } 2913 } 2914 if (nsec3param->salt_length == 0) 2915 strlcpy(saltbuf, "-", sizeof(saltbuf)); 2916 else 2917 for (i = 0; i < nsec3param->salt_length; i++) 2918 sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]); 2919 dns_zone_log(zone, ISC_LOG_INFO, 2920 "zone_addnsec3chain(%u,%s,%u,%s)", 2921 nsec3param->hash, flags, nsec3param->iterations, 2922 saltbuf); 2923 2924 for (current = ISC_LIST_HEAD(zone->nsec3chain); 2925 current != NULL; 2926 current = ISC_LIST_NEXT(current, link)) { 2927 if (current->db == db && 2928 current->nsec3param.hash == nsec3param->hash && 2929 current->nsec3param.iterations == nsec3param->iterations && 2930 current->nsec3param.salt_length == nsec3param->salt_length 2931 && !memcmp(current->nsec3param.salt, nsec3param->salt, 2932 nsec3param->salt_length)) 2933 current->done = ISC_TRUE; 2934 } 2935 2936 dns_db_attach(db, &nsec3chain->db); 2937 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) 2938 options = DNS_DB_NONSEC3; 2939 result = dns_db_createiterator(nsec3chain->db, options, 2940 &nsec3chain->dbiterator); 2941 if (result == ISC_R_SUCCESS) 2942 dns_dbiterator_first(nsec3chain->dbiterator); 2943 if (result == ISC_R_SUCCESS) { 2944 dns_dbiterator_pause(nsec3chain->dbiterator); 2945 ISC_LIST_INITANDAPPEND(zone->nsec3chain, 2946 nsec3chain, link); 2947 nsec3chain = NULL; 2948 if (isc_time_isepoch(&zone->nsec3chaintime)) { 2949 TIME_NOW(&now); 2950 zone->nsec3chaintime = now; 2951 if (zone->task != NULL) 2952 zone_settimer(zone, &now); 2953 } 2954 } 2955 2956 if (nsec3chain != NULL) { 2957 if (nsec3chain->db != NULL) 2958 dns_db_detach(&nsec3chain->db); 2959 if (nsec3chain->dbiterator != NULL) 2960 dns_dbiterator_destroy(&nsec3chain->dbiterator); 2961 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 2962 } 2963 2964 cleanup: 2965 if (db != NULL) 2966 dns_db_detach(&db); 2967 return (result); 2968} 2969 2970static void 2971resume_addnsec3chain(dns_zone_t *zone) { 2972 dns_dbnode_t *node = NULL; 2973 dns_dbversion_t *version = NULL; 2974 dns_rdataset_t rdataset; 2975 isc_result_t result; 2976 dns_rdata_nsec3param_t nsec3param; 2977 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; 2978 dns_db_t *db = NULL; 2979 2980 if (zone->privatetype == 0) 2981 return; 2982 2983 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 2984 if (zone->db != NULL) 2985 dns_db_attach(zone->db, &db); 2986 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 2987 if (db == NULL) 2988 goto cleanup; 2989 2990 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 2991 if (result != ISC_R_SUCCESS) 2992 goto cleanup; 2993 2994 dns_db_currentversion(db, &version); 2995 2996 result = dns_nsec_nseconly(db, version, &nseconly); 2997 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 2998 2999 dns_rdataset_init(&rdataset); 3000 result = dns_db_findrdataset(db, node, version, 3001 zone->privatetype, dns_rdatatype_none, 3002 0, &rdataset, NULL); 3003 if (result != ISC_R_SUCCESS) { 3004 INSIST(!dns_rdataset_isassociated(&rdataset)); 3005 goto cleanup; 3006 } 3007 3008 for (result = dns_rdataset_first(&rdataset); 3009 result == ISC_R_SUCCESS; 3010 result = dns_rdataset_next(&rdataset)) 3011 { 3012 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 3013 dns_rdata_t rdata = DNS_RDATA_INIT; 3014 dns_rdata_t private = DNS_RDATA_INIT; 3015 3016 dns_rdataset_current(&rdataset, &private); 3017 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 3018 sizeof(buf))) 3019 continue; 3020 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 3021 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3022 if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) || 3023 ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok)) 3024 { 3025 result = zone_addnsec3chain(zone, &nsec3param); 3026 if (result != ISC_R_SUCCESS) { 3027 dns_zone_log(zone, ISC_LOG_ERROR, 3028 "zone_addnsec3chain failed: %s", 3029 dns_result_totext(result)); 3030 } 3031 } 3032 } 3033 dns_rdataset_disassociate(&rdataset); 3034 cleanup: 3035 if (db != NULL) { 3036 if (node != NULL) 3037 dns_db_detachnode(db, &node); 3038 if (version != NULL) 3039 dns_db_closeversion(db, &version, ISC_FALSE); 3040 dns_db_detach(&db); 3041 } 3042} 3043 3044static void 3045set_resigntime(dns_zone_t *zone) { 3046 dns_rdataset_t rdataset; 3047 dns_fixedname_t fixed; 3048 unsigned int resign; 3049 isc_result_t result; 3050 isc_uint32_t nanosecs; 3051 dns_db_t *db = NULL; 3052 3053 dns_rdataset_init(&rdataset); 3054 dns_fixedname_init(&fixed); 3055 3056 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3057 if (zone->db != NULL) 3058 dns_db_attach(zone->db, &db); 3059 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3060 if (db == NULL) { 3061 isc_time_settoepoch(&zone->resigntime); 3062 return; 3063 } 3064 3065 result = dns_db_getsigningtime(db, &rdataset, 3066 dns_fixedname_name(&fixed)); 3067 if (result != ISC_R_SUCCESS) { 3068 isc_time_settoepoch(&zone->resigntime); 3069 goto cleanup; 3070 } 3071 3072 resign = rdataset.resign - zone->sigresigninginterval; 3073 dns_rdataset_disassociate(&rdataset); 3074 isc_random_get(&nanosecs); 3075 nanosecs %= 1000000000; 3076 isc_time_set(&zone->resigntime, resign, nanosecs); 3077 cleanup: 3078 dns_db_detach(&db); 3079 return; 3080} 3081 3082static isc_result_t 3083check_nsec3param(dns_zone_t *zone, dns_db_t *db) { 3084 dns_dbnode_t *node = NULL; 3085 dns_rdataset_t rdataset; 3086 dns_dbversion_t *version = NULL; 3087 dns_rdata_nsec3param_t nsec3param; 3088 isc_boolean_t ok = ISC_FALSE; 3089 isc_result_t result; 3090 dns_rdata_t rdata = DNS_RDATA_INIT; 3091 isc_boolean_t dynamic = (zone->type == dns_zone_master) ? 3092 dns_zone_isdynamic(zone, ISC_FALSE) : ISC_FALSE; 3093 3094 dns_rdataset_init(&rdataset); 3095 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 3096 if (result != ISC_R_SUCCESS) { 3097 dns_zone_log(zone, ISC_LOG_ERROR, 3098 "nsec3param lookup failure: %s", 3099 dns_result_totext(result)); 3100 return (result); 3101 } 3102 dns_db_currentversion(db, &version); 3103 3104 result = dns_db_findrdataset(db, node, version, 3105 dns_rdatatype_nsec3param, 3106 dns_rdatatype_none, 0, &rdataset, NULL); 3107 if (result == ISC_R_NOTFOUND) { 3108 INSIST(!dns_rdataset_isassociated(&rdataset)); 3109 result = ISC_R_SUCCESS; 3110 goto cleanup; 3111 } 3112 if (result != ISC_R_SUCCESS) { 3113 INSIST(!dns_rdataset_isassociated(&rdataset)); 3114 dns_zone_log(zone, ISC_LOG_ERROR, 3115 "nsec3param lookup failure: %s", 3116 dns_result_totext(result)); 3117 goto cleanup; 3118 } 3119 3120 /* 3121 * For dynamic zones we must support every algorithm so we can 3122 * regenerate all the NSEC3 chains. 3123 * For non-dynamic zones we only need to find a supported algorithm. 3124 */ 3125 for (result = dns_rdataset_first(&rdataset); 3126 result == ISC_R_SUCCESS; 3127 result = dns_rdataset_next(&rdataset)) 3128 { 3129 dns_rdataset_current(&rdataset, &rdata); 3130 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 3131 dns_rdata_reset(&rdata); 3132 INSIST(result == ISC_R_SUCCESS); 3133 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) && 3134 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic) 3135 { 3136 dns_zone_log(zone, ISC_LOG_WARNING, 3137 "nsec3 test \"unknown\" hash algorithm found: %u", 3138 nsec3param.hash); 3139 ok = ISC_TRUE; 3140 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) { 3141 if (dynamic) { 3142 dns_zone_log(zone, ISC_LOG_ERROR, 3143 "unsupported nsec3 hash algorithm" 3144 " in dynamic zone: %u", 3145 nsec3param.hash); 3146 result = DNS_R_BADZONE; 3147 /* Stop second error message. */ 3148 ok = ISC_TRUE; 3149 break; 3150 } else 3151 dns_zone_log(zone, ISC_LOG_WARNING, 3152 "unsupported nsec3 hash algorithm: %u", 3153 nsec3param.hash); 3154 } else 3155 ok = ISC_TRUE; 3156 } 3157 if (result == ISC_R_NOMORE) 3158 result = ISC_R_SUCCESS; 3159 3160 if (!ok) { 3161 result = DNS_R_BADZONE; 3162 dns_zone_log(zone, ISC_LOG_ERROR, 3163 "no supported nsec3 hash algorithm"); 3164 } 3165 3166 cleanup: 3167 if (dns_rdataset_isassociated(&rdataset)) 3168 dns_rdataset_disassociate(&rdataset); 3169 dns_db_closeversion(db, &version, ISC_FALSE); 3170 dns_db_detachnode(db, &node); 3171 return (result); 3172} 3173 3174/* 3175 * Set the timer for refreshing the key zone to the soonest future time 3176 * of the set (current timer, keydata->refresh, keydata->addhd, 3177 * keydata->removehd). 3178 */ 3179static void 3180set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key, 3181 isc_stdtime_t now) 3182{ 3183 const char me[] = "set_refreshkeytimer"; 3184 isc_stdtime_t then; 3185 isc_time_t timenow, timethen; 3186 char timebuf[80]; 3187 3188 ENTER; 3189 then = key->refresh; 3190 if (key->addhd > now && key->addhd < then) 3191 then = key->addhd; 3192 if (key->removehd > now && key->removehd < then) 3193 then = key->removehd; 3194 3195 TIME_NOW(&timenow); 3196 if (then > now) 3197 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 3198 else 3199 timethen = timenow; 3200 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 || 3201 isc_time_compare(&timethen, &zone->refreshkeytime) < 0) 3202 zone->refreshkeytime = timethen; 3203 3204 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 3205 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf); 3206 zone_settimer(zone, &timenow); 3207} 3208 3209/* 3210 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone. 3211 * If the key zone is changed, set '*changed' to ISC_TRUE. 3212 */ 3213static isc_result_t 3214create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 3215 dns_diff_t *diff, dns_keytable_t *keytable, 3216 dns_keynode_t **keynodep, isc_boolean_t *changed) 3217{ 3218 const char me[] = "create_keydata"; 3219 isc_result_t result = ISC_R_SUCCESS; 3220 isc_buffer_t keyb, dstb; 3221 unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE]; 3222 dns_rdata_keydata_t keydata; 3223 dns_rdata_dnskey_t dnskey; 3224 dns_rdata_t rdata = DNS_RDATA_INIT; 3225 dns_keynode_t *keynode; 3226 isc_stdtime_t now; 3227 isc_region_t r; 3228 dst_key_t *key; 3229 3230 REQUIRE(keynodep != NULL); 3231 keynode = *keynodep; 3232 3233 ENTER; 3234 isc_stdtime_get(&now); 3235 3236 /* Loop in case there's more than one key. */ 3237 while (result == ISC_R_SUCCESS) { 3238 dns_keynode_t *nextnode = NULL; 3239 3240 key = dns_keynode_key(keynode); 3241 if (key == NULL) 3242 goto skip; 3243 3244 isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf)); 3245 CHECK(dst_key_todns(key, &dstb)); 3246 3247 /* Convert DST key to DNSKEY. */ 3248 dns_rdata_reset(&rdata); 3249 isc_buffer_usedregion(&dstb, &r); 3250 dns_rdata_fromregion(&rdata, dst_key_class(key), 3251 dns_rdatatype_dnskey, &r); 3252 3253 /* DSTKEY to KEYDATA. */ 3254 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL)); 3255 CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0, 3256 NULL)); 3257 3258 /* KEYDATA to rdata. */ 3259 dns_rdata_reset(&rdata); 3260 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 3261 CHECK(dns_rdata_fromstruct(&rdata, 3262 zone->rdclass, dns_rdatatype_keydata, 3263 &keydata, &keyb)); 3264 3265 /* Add rdata to zone. */ 3266 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, 3267 dst_key_name(key), 0, &rdata)); 3268 *changed = ISC_TRUE; 3269 /* Refresh new keys from the zone apex as soon as possible. */ 3270 set_refreshkeytimer(zone, &keydata, now); 3271 3272 skip: 3273 result = dns_keytable_nextkeynode(keytable, keynode, &nextnode); 3274 if (result != ISC_R_NOTFOUND) { 3275 dns_keytable_detachkeynode(keytable, &keynode); 3276 keynode = nextnode; 3277 } 3278 } 3279 3280 if (keynode != NULL) 3281 dns_keytable_detachkeynode(keytable, &keynode); 3282 *keynodep = NULL; 3283 3284 return (ISC_R_SUCCESS); 3285 3286 failure: 3287 return (result); 3288} 3289 3290/* 3291 * Remove from the key zone all the KEYDATA records found in rdataset. 3292 */ 3293static isc_result_t 3294delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 3295 dns_name_t *name, dns_rdataset_t *rdataset) 3296{ 3297 dns_rdata_t rdata = DNS_RDATA_INIT; 3298 isc_result_t result, uresult; 3299 3300 for (result = dns_rdataset_first(rdataset); 3301 result == ISC_R_SUCCESS; 3302 result = dns_rdataset_next(rdataset)) { 3303 dns_rdata_reset(&rdata); 3304 dns_rdataset_current(rdataset, &rdata); 3305 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, 3306 name, 0, &rdata); 3307 if (uresult != ISC_R_SUCCESS) 3308 return (uresult); 3309 } 3310 if (result == ISC_R_NOMORE) 3311 result = ISC_R_SUCCESS; 3312 return (result); 3313} 3314 3315/* 3316 * Compute the DNSSEC key ID for a DNSKEY record. 3317 */ 3318static isc_result_t 3319compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx, 3320 dns_keytag_t *tag) 3321{ 3322 isc_result_t result; 3323 dns_rdata_t rdata = DNS_RDATA_INIT; 3324 unsigned char data[4096]; 3325 isc_buffer_t buffer; 3326 dst_key_t *dstkey = NULL; 3327 3328 isc_buffer_init(&buffer, data, sizeof(data)); 3329 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 3330 dns_rdatatype_dnskey, dnskey, &buffer); 3331 3332 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey); 3333 if (result == ISC_R_SUCCESS) 3334 *tag = dst_key_id(dstkey); 3335 dst_key_free(&dstkey); 3336 3337 return (result); 3338} 3339 3340/* 3341 * Add key to the security roots. 3342 */ 3343static void 3344trust_key(dns_zone_t *zone, dns_name_t *keyname, 3345 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) { 3346 isc_result_t result; 3347 dns_rdata_t rdata = DNS_RDATA_INIT; 3348 unsigned char data[4096]; 3349 isc_buffer_t buffer; 3350 dns_keytable_t *sr = NULL; 3351 dst_key_t *dstkey = NULL; 3352 3353 /* Convert dnskey to DST key. */ 3354 isc_buffer_init(&buffer, data, sizeof(data)); 3355 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 3356 dns_rdatatype_dnskey, dnskey, &buffer); 3357 3358 result = dns_view_getsecroots(zone->view, &sr); 3359 if (result != ISC_R_SUCCESS) 3360 goto failure; 3361 3362 CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey)); 3363 CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey)); 3364 dns_keytable_detach(&sr); 3365 3366 failure: 3367 if (dstkey != NULL) 3368 dst_key_free(&dstkey); 3369 if (sr != NULL) 3370 dns_keytable_detach(&sr); 3371 return; 3372} 3373 3374/* 3375 * Add a null key to the security roots for so that all queries 3376 * to the zone will fail. 3377 */ 3378static void 3379fail_secure(dns_zone_t *zone, dns_name_t *keyname) { 3380 isc_result_t result; 3381 dns_keytable_t *sr = NULL; 3382 3383 result = dns_view_getsecroots(zone->view, &sr); 3384 if (result == ISC_R_SUCCESS) { 3385 dns_keytable_marksecure(sr, keyname); 3386 dns_keytable_detach(&sr); 3387 } 3388} 3389 3390/* 3391 * Scan a set of KEYDATA records from the key zone. The ones that are 3392 * valid (i.e., the add holddown timer has expired) become trusted keys. 3393 */ 3394static void 3395load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) { 3396 isc_result_t result; 3397 dns_rdata_t rdata = DNS_RDATA_INIT; 3398 dns_rdata_keydata_t keydata; 3399 dns_rdata_dnskey_t dnskey; 3400 isc_mem_t *mctx = zone->mctx; 3401 int trusted = 0, revoked = 0, pending = 0; 3402 isc_stdtime_t now; 3403 dns_keytable_t *sr = NULL; 3404 3405 isc_stdtime_get(&now); 3406 3407 result = dns_view_getsecroots(zone->view, &sr); 3408 if (result == ISC_R_SUCCESS) { 3409 dns_keytable_delete(sr, name); 3410 dns_keytable_detach(&sr); 3411 } 3412 3413 /* Now insert all the accepted trust anchors from this keydata set. */ 3414 for (result = dns_rdataset_first(rdataset); 3415 result == ISC_R_SUCCESS; 3416 result = dns_rdataset_next(rdataset)) { 3417 dns_rdata_reset(&rdata); 3418 dns_rdataset_current(rdataset, &rdata); 3419 3420 /* Convert rdata to keydata. */ 3421 result = dns_rdata_tostruct(&rdata, &keydata, NULL); 3422 if (result == ISC_R_UNEXPECTEDEND) 3423 continue; 3424 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3425 3426 /* Set the key refresh timer. */ 3427 set_refreshkeytimer(zone, &keydata, now); 3428 3429 /* If the removal timer is nonzero, this key was revoked. */ 3430 if (keydata.removehd != 0) { 3431 revoked++; 3432 continue; 3433 } 3434 3435 /* 3436 * If the add timer is still pending, this key is not 3437 * trusted yet. 3438 */ 3439 if (now < keydata.addhd) { 3440 pending++; 3441 continue; 3442 } 3443 3444 /* Convert keydata to dnskey. */ 3445 dns_keydata_todnskey(&keydata, &dnskey, NULL); 3446 3447 /* Add to keytables. */ 3448 trusted++; 3449 trust_key(zone, name, &dnskey, mctx); 3450 } 3451 3452 if (trusted == 0 && pending != 0) { 3453 char namebuf[DNS_NAME_FORMATSIZE]; 3454 dns_name_format(name, namebuf, sizeof namebuf); 3455 dns_zone_log(zone, ISC_LOG_ERROR, 3456 "No valid trust anchors for '%s'!", namebuf); 3457 dns_zone_log(zone, ISC_LOG_ERROR, 3458 "%d key(s) revoked, %d still pending", 3459 revoked, pending); 3460 dns_zone_log(zone, ISC_LOG_ERROR, 3461 "All queries to '%s' will fail", namebuf); 3462 fail_secure(zone, name); 3463 } 3464} 3465 3466static isc_result_t 3467do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, 3468 dns_diff_t *diff) 3469{ 3470 dns_diff_t temp_diff; 3471 isc_result_t result; 3472 3473 /* 3474 * Create a singleton diff. 3475 */ 3476 dns_diff_init(diff->mctx, &temp_diff); 3477 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); 3478 3479 /* 3480 * Apply it to the database. 3481 */ 3482 result = dns_diff_apply(&temp_diff, db, ver); 3483 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); 3484 if (result != ISC_R_SUCCESS) { 3485 dns_difftuple_free(tuple); 3486 return (result); 3487 } 3488 3489 /* 3490 * Merge it into the current pending journal entry. 3491 */ 3492 dns_diff_appendminimal(diff, tuple); 3493 3494 /* 3495 * Do not clear temp_diff. 3496 */ 3497 return (ISC_R_SUCCESS); 3498} 3499 3500static isc_result_t 3501update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 3502 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, 3503 dns_rdata_t *rdata) 3504{ 3505 dns_difftuple_t *tuple = NULL; 3506 isc_result_t result; 3507 result = dns_difftuple_create(diff->mctx, op, 3508 name, ttl, rdata, &tuple); 3509 if (result != ISC_R_SUCCESS) 3510 return (result); 3511 return (do_one_tuple(&tuple, db, ver, diff)); 3512} 3513 3514static isc_result_t 3515update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 3516 isc_mem_t *mctx, dns_updatemethod_t method) { 3517 dns_difftuple_t *deltuple = NULL; 3518 dns_difftuple_t *addtuple = NULL; 3519 isc_uint32_t serial; 3520 isc_result_t result; 3521 3522 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple)); 3523 CHECK(dns_difftuple_copy(deltuple, &addtuple)); 3524 addtuple->op = DNS_DIFFOP_ADD; 3525 3526 serial = dns_soa_getserial(&addtuple->rdata); 3527 serial = dns_update_soaserial(serial, method); 3528 dns_soa_setserial(serial, &addtuple->rdata); 3529 CHECK(do_one_tuple(&deltuple, db, ver, diff)); 3530 CHECK(do_one_tuple(&addtuple, db, ver, diff)); 3531 result = ISC_R_SUCCESS; 3532 3533 failure: 3534 if (addtuple != NULL) 3535 dns_difftuple_free(&addtuple); 3536 if (deltuple != NULL) 3537 dns_difftuple_free(&deltuple); 3538 return (result); 3539} 3540 3541/* 3542 * Write all transactions in 'diff' to the zone journal file. 3543 */ 3544static isc_result_t 3545zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial, 3546 const char *caller) 3547{ 3548 const char me[] = "zone_journal"; 3549 const char *journalfile; 3550 isc_result_t result = ISC_R_SUCCESS; 3551 dns_journal_t *journal = NULL; 3552 unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE; 3553 3554 ENTER; 3555 journalfile = dns_zone_getjournal(zone); 3556 if (journalfile != NULL) { 3557 result = dns_journal_open(zone->mctx, journalfile, mode, 3558 &journal); 3559 if (result != ISC_R_SUCCESS) { 3560 dns_zone_log(zone, ISC_LOG_ERROR, 3561 "%s:dns_journal_open -> %s", 3562 caller, dns_result_totext(result)); 3563 return (result); 3564 } 3565 3566 if (sourceserial != NULL) 3567 dns_journal_set_sourceserial(journal, *sourceserial); 3568 3569 result = dns_journal_write_transaction(journal, diff); 3570 if (result != ISC_R_SUCCESS) { 3571 dns_zone_log(zone, ISC_LOG_ERROR, 3572 "%s:dns_journal_write_transaction -> %s", 3573 caller, dns_result_totext(result)); 3574 } 3575 dns_journal_destroy(&journal); 3576 } 3577 3578 return (result); 3579} 3580 3581/* 3582 * Create an SOA record for a newly-created zone 3583 */ 3584static isc_result_t 3585add_soa(dns_zone_t *zone, dns_db_t *db) { 3586 isc_result_t result; 3587 dns_rdata_t rdata = DNS_RDATA_INIT; 3588 unsigned char buf[DNS_SOA_BUFFERSIZE]; 3589 dns_dbversion_t *ver = NULL; 3590 dns_diff_t diff; 3591 3592 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA"); 3593 3594 dns_diff_init(zone->mctx, &diff); 3595 result = dns_db_newversion(db, &ver); 3596 if (result != ISC_R_SUCCESS) { 3597 dns_zone_log(zone, ISC_LOG_ERROR, 3598 "add_soa:dns_db_newversion -> %s", 3599 dns_result_totext(result)); 3600 goto failure; 3601 } 3602 3603 /* Build SOA record */ 3604 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass, 3605 0, 0, 0, 0, 0, buf, &rdata); 3606 if (result != ISC_R_SUCCESS) { 3607 dns_zone_log(zone, ISC_LOG_ERROR, 3608 "add_soa:dns_soa_buildrdata -> %s", 3609 dns_result_totext(result)); 3610 goto failure; 3611 } 3612 3613 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD, 3614 &zone->origin, 0, &rdata); 3615 3616failure: 3617 dns_diff_clear(&diff); 3618 if (ver != NULL) 3619 dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS)); 3620 3621 return (result); 3622} 3623 3624/* 3625 * Synchronize the set of initializing keys found in managed-keys {} 3626 * statements with the set of trust anchors found in the managed-keys.bind 3627 * zone. If a domain is no longer named in managed-keys, delete all keys 3628 * from that domain from the key zone. If a domain is mentioned in in 3629 * managed-keys but there are no references to it in the key zone, load 3630 * the key zone with the initializing key(s) for that domain. 3631 */ 3632static isc_result_t 3633sync_keyzone(dns_zone_t *zone, dns_db_t *db) { 3634 isc_result_t result = ISC_R_SUCCESS; 3635 isc_boolean_t changed = ISC_FALSE; 3636 isc_boolean_t commit = ISC_FALSE; 3637 dns_rbtnodechain_t chain; 3638 dns_fixedname_t fn; 3639 dns_name_t foundname, *origin; 3640 dns_keynode_t *keynode = NULL; 3641 dns_view_t *view = zone->view; 3642 dns_keytable_t *sr = NULL; 3643 dns_dbversion_t *ver = NULL; 3644 dns_diff_t diff; 3645 dns_rriterator_t rrit; 3646 3647 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys"); 3648 3649 dns_name_init(&foundname, NULL); 3650 dns_fixedname_init(&fn); 3651 origin = dns_fixedname_name(&fn); 3652 3653 dns_diff_init(zone->mctx, &diff); 3654 3655 CHECK(dns_view_getsecroots(view, &sr)); 3656 3657 result = dns_db_newversion(db, &ver); 3658 if (result != ISC_R_SUCCESS) { 3659 dns_zone_log(zone, ISC_LOG_ERROR, 3660 "sync_keyzone:dns_db_newversion -> %s", 3661 dns_result_totext(result)); 3662 goto failure; 3663 } 3664 3665 /* 3666 * Walk the zone DB. If we find any keys whose names are no longer 3667 * in managed-keys (or *are* in trusted-keys, meaning they are 3668 * permanent and not RFC5011-maintained), delete them from the 3669 * zone. Otherwise call load_secroots(), which loads keys into 3670 * secroots as appropriate. 3671 */ 3672 dns_rriterator_init(&rrit, db, ver, 0); 3673 for (result = dns_rriterator_first(&rrit); 3674 result == ISC_R_SUCCESS; 3675 result = dns_rriterator_nextrrset(&rrit)) { 3676 dns_rdataset_t *rdataset = NULL; 3677 dns_name_t *rrname = NULL; 3678 isc_uint32_t ttl; 3679 3680 dns_rriterator_current(&rrit, &rrname, &ttl, 3681 &rdataset, NULL); 3682 if (!dns_rdataset_isassociated(rdataset)) { 3683 dns_rriterator_destroy(&rrit); 3684 goto failure; 3685 } 3686 3687 if (rdataset->type != dns_rdatatype_keydata) 3688 continue; 3689 3690 result = dns_keytable_find(sr, rrname, &keynode); 3691 if ((result != ISC_R_SUCCESS && 3692 result != DNS_R_PARTIALMATCH) || 3693 dns_keynode_managed(keynode) == ISC_FALSE) { 3694 CHECK(delete_keydata(db, ver, &diff, 3695 rrname, rdataset)); 3696 changed = ISC_TRUE; 3697 } else { 3698 load_secroots(zone, rrname, rdataset); 3699 } 3700 3701 if (keynode != NULL) 3702 dns_keytable_detachkeynode(sr, &keynode); 3703 } 3704 dns_rriterator_destroy(&rrit); 3705 3706 /* 3707 * Now walk secroots to find any managed keys that aren't 3708 * in the zone. If we find any, we add them to the zone. 3709 */ 3710 RWLOCK(&sr->rwlock, isc_rwlocktype_write); 3711 dns_rbtnodechain_init(&chain, zone->mctx); 3712 result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin); 3713 if (result == ISC_R_NOTFOUND) 3714 result = ISC_R_NOMORE; 3715 while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { 3716 dns_rbtnode_t *rbtnode = NULL; 3717 3718 dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode); 3719 if (rbtnode->data == NULL) 3720 goto skip; 3721 3722 dns_keytable_attachkeynode(sr, rbtnode->data, &keynode); 3723 if (dns_keynode_managed(keynode)) { 3724 dns_fixedname_t fname; 3725 dns_name_t *keyname; 3726 dst_key_t *key; 3727 3728 key = dns_keynode_key(keynode); 3729 dns_fixedname_init(&fname); 3730 3731 if (key == NULL) /* fail_secure() was called. */ 3732 goto skip; 3733 3734 keyname = dst_key_name(key); 3735 result = dns_db_find(db, keyname, ver, 3736 dns_rdatatype_keydata, 3737 DNS_DBFIND_NOWILD, 0, NULL, 3738 dns_fixedname_name(&fname), 3739 NULL, NULL); 3740 if (result != ISC_R_SUCCESS) 3741 result = create_keydata(zone, db, ver, &diff, 3742 sr, &keynode, &changed); 3743 if (result != ISC_R_SUCCESS) 3744 break; 3745 } 3746 skip: 3747 result = dns_rbtnodechain_next(&chain, &foundname, origin); 3748 if (keynode != NULL) 3749 dns_keytable_detachkeynode(sr, &keynode); 3750 } 3751 RWUNLOCK(&sr->rwlock, isc_rwlocktype_write); 3752 3753 if (result == ISC_R_NOMORE) 3754 result = ISC_R_SUCCESS; 3755 3756 if (changed) { 3757 /* Write changes to journal file. */ 3758 CHECK(update_soa_serial(db, ver, &diff, zone->mctx, 3759 zone->updatemethod)); 3760 CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone")); 3761 3762 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 3763 zone_needdump(zone, 30); 3764 commit = ISC_TRUE; 3765 } 3766 3767 failure: 3768 if (result != ISC_R_SUCCESS && 3769 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 3770 dns_zone_log(zone, ISC_LOG_ERROR, 3771 "unable to synchronize managed keys: %s", 3772 dns_result_totext(result)); 3773 isc_time_settoepoch(&zone->refreshkeytime); 3774 } 3775 if (keynode != NULL) 3776 dns_keytable_detachkeynode(sr, &keynode); 3777 if (sr != NULL) 3778 dns_keytable_detach(&sr); 3779 if (ver != NULL) 3780 dns_db_closeversion(db, &ver, commit); 3781 dns_diff_clear(&diff); 3782 3783 return (result); 3784} 3785 3786isc_result_t 3787dns_zone_synckeyzone(dns_zone_t *zone) { 3788 isc_result_t result; 3789 dns_db_t *db = NULL; 3790 3791 if (zone->type != dns_zone_key) 3792 return (DNS_R_BADZONE); 3793 3794 CHECK(dns_zone_getdb(zone, &db)); 3795 3796 LOCK_ZONE(zone); 3797 result = sync_keyzone(zone, db); 3798 UNLOCK_ZONE(zone); 3799 3800 failure: 3801 if (db != NULL) 3802 dns_db_detach(&db); 3803 return (result); 3804} 3805 3806static void 3807maybe_send_secure(dns_zone_t *zone) { 3808 isc_result_t result; 3809 3810 /* 3811 * We've finished loading, or else failed to load, an inline-signing 3812 * 'secure' zone. We now need information about the status of the 3813 * 'raw' zone. If we failed to load, then we need it to send a 3814 * copy of its database; if we succeeded, we need it to send its 3815 * serial number so that we can sync with it. If it has not yet 3816 * loaded, we set a flag so that it will send the necessary 3817 * information when it has finished loading. 3818 */ 3819 if (zone->raw->db != NULL) { 3820 if (zone->db != NULL) { 3821 isc_uint32_t serial; 3822 unsigned int soacount; 3823 3824 result = zone_get_from_db(zone->raw, zone->raw->db, 3825 NULL, &soacount, &serial, NULL, 3826 NULL, NULL, NULL, NULL); 3827 if (result == ISC_R_SUCCESS && soacount > 0U) 3828 zone_send_secureserial(zone->raw, serial); 3829 } else 3830 zone_send_securedb(zone->raw, zone->raw->db); 3831 3832 } else 3833 DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE); 3834} 3835 3836static isc_boolean_t 3837zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) { 3838 isc_result_t result; 3839 isc_boolean_t answer = ISC_FALSE; 3840 dns_diff_t diff; 3841 3842 dns_diff_init(mctx, &diff); 3843 result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL); 3844 if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples)) 3845 answer = ISC_TRUE; 3846 dns_diff_clear(&diff); 3847 return (answer); 3848} 3849 3850/* 3851 * The zone is presumed to be locked. 3852 * If this is a inline_raw zone the secure version is also locked. 3853 */ 3854static isc_result_t 3855zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, 3856 isc_result_t result) 3857{ 3858 unsigned int soacount = 0; 3859 unsigned int nscount = 0; 3860 unsigned int errors = 0; 3861 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum; 3862 isc_time_t now; 3863 isc_boolean_t needdump = ISC_FALSE; 3864 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE); 3865 isc_boolean_t nomaster = ISC_FALSE; 3866 unsigned int options; 3867 3868 INSIST(LOCKED_ZONE(zone)); 3869 if (inline_raw(zone)) 3870 INSIST(LOCKED_ZONE(zone->secure)); 3871 3872 TIME_NOW(&now); 3873 3874 /* 3875 * Initiate zone transfer? We may need a error code that 3876 * indicates that the "permanent" form does not exist. 3877 * XXX better error feedback to log. 3878 */ 3879 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { 3880 if (zone->type == dns_zone_slave || 3881 zone->type == dns_zone_stub || 3882 (zone->type == dns_zone_redirect && 3883 zone->masters == NULL)) { 3884 if (result == ISC_R_FILENOTFOUND) 3885 dns_zone_log(zone, ISC_LOG_DEBUG(1), 3886 "no master file"); 3887 else if (result != DNS_R_NOMASTERFILE) 3888 dns_zone_log(zone, ISC_LOG_ERROR, 3889 "loading from master file %s " 3890 "failed: %s", 3891 zone->masterfile, 3892 dns_result_totext(result)); 3893 } else if (zone->type == dns_zone_master && 3894 inline_secure(zone) && result == ISC_R_FILENOTFOUND) 3895 { 3896 dns_zone_log(zone, ISC_LOG_DEBUG(1), 3897 "no master file, requesting db"); 3898 maybe_send_secure(zone); 3899 } else { 3900 int level = ISC_LOG_ERROR; 3901 if (zone->type == dns_zone_key && 3902 result == ISC_R_FILENOTFOUND) 3903 level = ISC_LOG_DEBUG(1); 3904 dns_zone_log(zone, level, 3905 "loading from master file %s failed: %s", 3906 zone->masterfile, 3907 dns_result_totext(result)); 3908 nomaster = ISC_TRUE; 3909 } 3910 3911 if (zone->type != dns_zone_key) 3912 goto cleanup; 3913 } 3914 3915 dns_zone_log(zone, ISC_LOG_DEBUG(2), 3916 "number of nodes in database: %u", 3917 dns_db_nodecount(db)); 3918 3919 if (result == DNS_R_SEENINCLUDE) 3920 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 3921 else 3922 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 3923 3924 /* 3925 * If there's no master file for a key zone, then the zone is new: 3926 * create an SOA record. (We do this now, instead of later, so that 3927 * if there happens to be a journal file, we can roll forward from 3928 * a sane starting point.) 3929 */ 3930 if (nomaster && zone->type == dns_zone_key) { 3931 result = add_soa(zone, db); 3932 if (result != ISC_R_SUCCESS) 3933 goto cleanup; 3934 } 3935 3936 /* 3937 * Apply update log, if any, on initial load. 3938 */ 3939 if (zone->journal != NULL && 3940 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) && 3941 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 3942 { 3943 if (zone->type == dns_zone_master && 3944 (zone->update_acl != NULL || zone->ssutable != NULL)) 3945 options = DNS_JOURNALOPT_RESIGN; 3946 else 3947 options = 0; 3948 result = dns_journal_rollforward2(zone->mctx, db, options, 3949 0, zone->journal); 3950 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND && 3951 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL && 3952 result != ISC_R_RANGE) { 3953 dns_zone_log(zone, ISC_LOG_ERROR, 3954 "journal rollforward failed: %s", 3955 dns_result_totext(result)); 3956 goto cleanup; 3957 3958 3959 } 3960 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) { 3961 dns_zone_log(zone, ISC_LOG_ERROR, 3962 "journal rollforward failed: " 3963 "journal out of sync with zone"); 3964 goto cleanup; 3965 } 3966 dns_zone_log(zone, ISC_LOG_DEBUG(1), 3967 "journal rollforward completed " 3968 "successfully: %s", 3969 dns_result_totext(result)); 3970 if (result == ISC_R_SUCCESS) 3971 needdump = ISC_TRUE; 3972 } 3973 3974 /* 3975 * Obtain ns, soa and cname counts for top of zone. 3976 */ 3977 INSIST(db != NULL); 3978 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial, 3979 &refresh, &retry, &expire, &minimum, 3980 &errors); 3981 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) { 3982 dns_zone_log(zone, ISC_LOG_ERROR, 3983 "could not find NS and/or SOA records"); 3984 } 3985 3986 /* 3987 * Check to make sure the journal is up to date, and remove the 3988 * journal file if it isn't, as we wouldn't be able to apply 3989 * updates otherwise. 3990 */ 3991 if (zone->journal != NULL && dns_zone_isdynamic(zone, ISC_TRUE) && 3992 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) { 3993 isc_uint32_t jserial; 3994 dns_journal_t *journal = NULL; 3995 3996 result = dns_journal_open(zone->mctx, zone->journal, 3997 DNS_JOURNAL_READ, &journal); 3998 if (result == ISC_R_SUCCESS) { 3999 jserial = dns_journal_last_serial(journal); 4000 dns_journal_destroy(&journal); 4001 } else { 4002 jserial = serial; 4003 result = ISC_R_SUCCESS; 4004 } 4005 4006 if (jserial != serial) { 4007 dns_zone_log(zone, ISC_LOG_INFO, 4008 "journal file is out of date: " 4009 "removing journal file"); 4010 if (remove(zone->journal) < 0 && errno != ENOENT) { 4011 char strbuf[ISC_STRERRORSIZE]; 4012 isc__strerror(errno, strbuf, sizeof(strbuf)); 4013 isc_log_write(dns_lctx, 4014 DNS_LOGCATEGORY_GENERAL, 4015 DNS_LOGMODULE_ZONE, 4016 ISC_LOG_WARNING, 4017 "unable to remove journal " 4018 "'%s': '%s'", 4019 zone->journal, strbuf); 4020 } 4021 } 4022 } 4023 4024 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity"); 4025 4026 /* 4027 * Master / Slave / Stub zones require both NS and SOA records at 4028 * the top of the zone. 4029 */ 4030 4031 switch (zone->type) { 4032 case dns_zone_dlz: 4033 case dns_zone_master: 4034 case dns_zone_slave: 4035 case dns_zone_stub: 4036 case dns_zone_redirect: 4037 if (soacount != 1) { 4038 dns_zone_log(zone, ISC_LOG_ERROR, 4039 "has %d SOA records", soacount); 4040 result = DNS_R_BADZONE; 4041 } 4042 if (nscount == 0) { 4043 dns_zone_log(zone, ISC_LOG_ERROR, 4044 "has no NS records"); 4045 result = DNS_R_BADZONE; 4046 } 4047 if (result != ISC_R_SUCCESS) 4048 goto cleanup; 4049 if (zone->type == dns_zone_master && errors != 0) { 4050 result = DNS_R_BADZONE; 4051 goto cleanup; 4052 } 4053 if (zone->type != dns_zone_stub && 4054 zone->type != dns_zone_redirect) { 4055 result = check_nsec3param(zone, db); 4056 if (result != ISC_R_SUCCESS) 4057 goto cleanup; 4058 } 4059 if (zone->type == dns_zone_master && 4060 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) && 4061 !integrity_checks(zone, db)) { 4062 result = DNS_R_BADZONE; 4063 goto cleanup; 4064 } 4065 if (zone->type == dns_zone_master && 4066 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) && 4067 !zone_check_dup(zone, db)) { 4068 result = DNS_R_BADZONE; 4069 goto cleanup; 4070 } 4071 4072 if (zone->db != NULL) { 4073 unsigned int oldsoacount; 4074 4075 /* 4076 * This is checked in zone_replacedb() for slave zones 4077 * as they don't reload from disk. 4078 */ 4079 result = zone_get_from_db(zone, zone->db, NULL, 4080 &oldsoacount, &oldserial, 4081 NULL, NULL, NULL, NULL, 4082 NULL); 4083 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4084 RUNTIME_CHECK(soacount > 0U); 4085 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 4086 !isc_serial_gt(serial, oldserial)) { 4087 isc_uint32_t serialmin, serialmax; 4088 4089 INSIST(zone->type == dns_zone_master); 4090 4091 if (serial == oldserial && 4092 zone_unchanged(zone->db, db, zone->mctx)) { 4093 dns_zone_log(zone, ISC_LOG_INFO, 4094 "ixfr-from-differences: " 4095 "unchanged"); 4096 return(ISC_R_SUCCESS); 4097 } 4098 4099 serialmin = (oldserial + 1) & 0xffffffffU; 4100 serialmax = (oldserial + 0x7fffffffU) & 4101 0xffffffffU; 4102 dns_zone_log(zone, ISC_LOG_ERROR, 4103 "ixfr-from-differences: " 4104 "new serial (%u) out of range " 4105 "[%u - %u]", serial, serialmin, 4106 serialmax); 4107 result = DNS_R_BADZONE; 4108 goto cleanup; 4109 } else if (!isc_serial_ge(serial, oldserial)) 4110 dns_zone_log(zone, ISC_LOG_ERROR, 4111 "zone serial (%u/%u) has gone " 4112 "backwards", serial, oldserial); 4113 else if (serial == oldserial && !hasinclude && 4114 strcmp(zone->db_argv[0], "_builtin") != 0) 4115 dns_zone_log(zone, ISC_LOG_ERROR, 4116 "zone serial (%u) unchanged. " 4117 "zone may fail to transfer " 4118 "to slaves.", serial); 4119 } 4120 4121 if (zone->type == dns_zone_master && 4122 (zone->update_acl != NULL || zone->ssutable != NULL) && 4123 zone->sigresigninginterval < (3 * refresh) && 4124 dns_db_issecure(db)) 4125 { 4126 dns_zone_log(zone, ISC_LOG_WARNING, 4127 "sig-re-signing-interval less than " 4128 "3 * refresh."); 4129 } 4130 4131 zone->refresh = RANGE(refresh, 4132 zone->minrefresh, zone->maxrefresh); 4133 zone->retry = RANGE(retry, 4134 zone->minretry, zone->maxretry); 4135 zone->expire = RANGE(expire, zone->refresh + zone->retry, 4136 DNS_MAX_EXPIRE); 4137 zone->minimum = minimum; 4138 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 4139 4140 if (zone->type == dns_zone_slave || 4141 zone->type == dns_zone_stub || 4142 (zone->type == dns_zone_redirect && 4143 zone->masters != NULL)) { 4144 isc_time_t t; 4145 isc_uint32_t delay; 4146 4147 result = isc_file_getmodtime(zone->journal, &t); 4148 if (result != ISC_R_SUCCESS) 4149 result = isc_file_getmodtime(zone->masterfile, 4150 &t); 4151 if (result == ISC_R_SUCCESS) 4152 DNS_ZONE_TIME_ADD(&t, zone->expire, 4153 &zone->expiretime); 4154 else 4155 DNS_ZONE_TIME_ADD(&now, zone->retry, 4156 &zone->expiretime); 4157 4158 delay = isc_random_jitter(zone->retry, 4159 (zone->retry * 3) / 4); 4160 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime); 4161 if (isc_time_compare(&zone->refreshtime, 4162 &zone->expiretime) >= 0) 4163 zone->refreshtime = now; 4164 } 4165 4166 break; 4167 4168 case dns_zone_key: 4169 result = sync_keyzone(zone, db); 4170 if (result != ISC_R_SUCCESS) 4171 goto cleanup; 4172 break; 4173 4174 default: 4175 UNEXPECTED_ERROR(__FILE__, __LINE__, 4176 "unexpected zone type %d", zone->type); 4177 result = ISC_R_UNEXPECTED; 4178 goto cleanup; 4179 } 4180 4181 /* 4182 * Check for weak DNSKEY's. 4183 */ 4184 if (zone->type == dns_zone_master) 4185 zone_check_dnskeys(zone, db); 4186 4187 /* 4188 * Schedule DNSSEC key refresh. 4189 */ 4190 if (zone->type == dns_zone_master && 4191 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 4192 zone->refreshkeytime = now; 4193 4194#if 0 4195 /* destroy notification example. */ 4196 { 4197 isc_event_t *e = isc_event_allocate(zone->mctx, NULL, 4198 DNS_EVENT_DBDESTROYED, 4199 dns_zonemgr_dbdestroyed, 4200 zone, 4201 sizeof(isc_event_t)); 4202 dns_db_ondestroy(db, zone->task, &e); 4203 } 4204#endif 4205 4206 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 4207 if (zone->db != NULL) { 4208 result = zone_replacedb(zone, db, ISC_FALSE); 4209 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 4210 if (result != ISC_R_SUCCESS) 4211 goto cleanup; 4212 } else { 4213 zone_attachdb(zone, db); 4214 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 4215 DNS_ZONE_SETFLAG(zone, 4216 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY); 4217 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) && 4218 inline_raw(zone)) 4219 { 4220 if (zone->secure->db == NULL) 4221 zone_send_securedb(zone, db); 4222 else 4223 zone_send_secureserial(zone, serial); 4224 } 4225 } 4226 4227 /* 4228 * Finished loading inline-signing zone; need to get status 4229 * from the raw side now. 4230 */ 4231 if (zone->type == dns_zone_master && inline_secure(zone)) 4232 maybe_send_secure(zone); 4233 4234 4235 result = ISC_R_SUCCESS; 4236 4237 if (needdump) { 4238 if (zone->type == dns_zone_key) 4239 zone_needdump(zone, 30); 4240 else 4241 zone_needdump(zone, DNS_DUMP_DELAY); 4242 } 4243 4244 if (zone->task != NULL) { 4245 if (zone->type == dns_zone_master) { 4246 set_resigntime(zone); 4247 resume_signingwithkey(zone); 4248 resume_addnsec3chain(zone); 4249 } 4250 4251 if (zone->type == dns_zone_master && 4252 !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) && 4253 dns_zone_isdynamic(zone, ISC_FALSE) && 4254 dns_db_issecure(db)) { 4255 dns_name_t *name; 4256 dns_fixedname_t fixed; 4257 dns_rdataset_t next; 4258 4259 dns_rdataset_init(&next); 4260 dns_fixedname_init(&fixed); 4261 name = dns_fixedname_name(&fixed); 4262 4263 result = dns_db_getsigningtime(db, &next, name); 4264 if (result == ISC_R_SUCCESS) { 4265 isc_stdtime_t timenow; 4266 char namebuf[DNS_NAME_FORMATSIZE]; 4267 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 4268 4269 isc_stdtime_get(&timenow); 4270 dns_name_format(name, namebuf, sizeof(namebuf)); 4271 dns_rdatatype_format(next.covers, 4272 typebuf, sizeof(typebuf)); 4273 dns_zone_log(zone, ISC_LOG_DEBUG(3), 4274 "next resign: %s/%s in %d seconds", 4275 namebuf, typebuf, 4276 next.resign - timenow - 4277 zone->sigresigninginterval); 4278 dns_rdataset_disassociate(&next); 4279 } else 4280 dns_zone_log(zone, ISC_LOG_WARNING, 4281 "signed dynamic zone has no " 4282 "resign event scheduled"); 4283 } 4284 4285 zone_settimer(zone, &now); 4286 } 4287 4288 if (! dns_db_ispersistent(db)) 4289 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial, 4290 dns_db_issecure(db) ? " (DNSSEC signed)" : ""); 4291 4292 zone->loadtime = loadtime; 4293 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); 4294 return (result); 4295 4296 cleanup: 4297 if (zone->type == dns_zone_slave || 4298 zone->type == dns_zone_stub || 4299 zone->type == dns_zone_key || 4300 (zone->type == dns_zone_redirect && zone->masters != NULL)) { 4301 if (zone->journal != NULL) 4302 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX"); 4303 if (zone->masterfile != NULL) 4304 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX"); 4305 4306 /* Mark the zone for immediate refresh. */ 4307 zone->refreshtime = now; 4308 if (zone->task != NULL) 4309 zone_settimer(zone, &now); 4310 result = ISC_R_SUCCESS; 4311 } else if (zone->type == dns_zone_master || 4312 zone->type == dns_zone_redirect) { 4313 if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND)) 4314 dns_zone_log(zone, ISC_LOG_ERROR, 4315 "not loaded due to errors."); 4316 else if (zone->type == dns_zone_master) 4317 result = ISC_R_SUCCESS; 4318 } 4319 4320 return (result); 4321} 4322 4323static isc_boolean_t 4324exit_check(dns_zone_t *zone) { 4325 REQUIRE(LOCKED_ZONE(zone)); 4326 4327 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->irefs == 0) { 4328 /* 4329 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0. 4330 */ 4331 INSIST(isc_refcount_current(&zone->erefs) == 0); 4332 return (ISC_TRUE); 4333 } 4334 return (ISC_FALSE); 4335} 4336 4337static isc_boolean_t 4338zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 4339 dns_name_t *name, isc_boolean_t logit) 4340{ 4341 isc_result_t result; 4342 char namebuf[DNS_NAME_FORMATSIZE]; 4343 char altbuf[DNS_NAME_FORMATSIZE]; 4344 dns_fixedname_t fixed; 4345 dns_name_t *foundname; 4346 int level; 4347 4348 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) 4349 return (ISC_TRUE); 4350 4351 if (zone->type == dns_zone_master) 4352 level = ISC_LOG_ERROR; 4353 else 4354 level = ISC_LOG_WARNING; 4355 4356 dns_fixedname_init(&fixed); 4357 foundname = dns_fixedname_name(&fixed); 4358 4359 result = dns_db_find(db, name, version, dns_rdatatype_a, 4360 0, 0, NULL, foundname, NULL, NULL); 4361 if (result == ISC_R_SUCCESS) 4362 return (ISC_TRUE); 4363 4364 if (result == DNS_R_NXRRSET) { 4365 result = dns_db_find(db, name, version, dns_rdatatype_aaaa, 4366 0, 0, NULL, foundname, NULL, NULL); 4367 if (result == ISC_R_SUCCESS) 4368 return (ISC_TRUE); 4369 } 4370 4371 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 4372 result == DNS_R_EMPTYNAME) { 4373 if (logit) { 4374 dns_name_format(name, namebuf, sizeof namebuf); 4375 dns_zone_log(zone, level, "NS '%s' has no address " 4376 "records (A or AAAA)", namebuf); 4377 } 4378 return (ISC_FALSE); 4379 } 4380 4381 if (result == DNS_R_CNAME) { 4382 if (logit) { 4383 dns_name_format(name, namebuf, sizeof namebuf); 4384 dns_zone_log(zone, level, "NS '%s' is a CNAME " 4385 "(illegal)", namebuf); 4386 } 4387 return (ISC_FALSE); 4388 } 4389 4390 if (result == DNS_R_DNAME) { 4391 if (logit) { 4392 dns_name_format(name, namebuf, sizeof namebuf); 4393 dns_name_format(foundname, altbuf, sizeof altbuf); 4394 dns_zone_log(zone, level, "NS '%s' is below a DNAME " 4395 "'%s' (illegal)", namebuf, altbuf); 4396 } 4397 return (ISC_FALSE); 4398 } 4399 4400 return (ISC_TRUE); 4401} 4402 4403static isc_result_t 4404zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, 4405 dns_dbversion_t *version, unsigned int *nscount, 4406 unsigned int *errors, isc_boolean_t logit) 4407{ 4408 isc_result_t result; 4409 unsigned int count = 0; 4410 unsigned int ecount = 0; 4411 dns_rdataset_t rdataset; 4412 dns_rdata_t rdata; 4413 dns_rdata_ns_t ns; 4414 4415 dns_rdataset_init(&rdataset); 4416 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns, 4417 dns_rdatatype_none, 0, &rdataset, NULL); 4418 if (result == ISC_R_NOTFOUND) { 4419 INSIST(!dns_rdataset_isassociated(&rdataset)); 4420 goto success; 4421 } 4422 if (result != ISC_R_SUCCESS) { 4423 INSIST(!dns_rdataset_isassociated(&rdataset)); 4424 goto invalidate_rdataset; 4425 } 4426 4427 result = dns_rdataset_first(&rdataset); 4428 while (result == ISC_R_SUCCESS) { 4429 if (errors != NULL && zone->rdclass == dns_rdataclass_in && 4430 (zone->type == dns_zone_master || 4431 zone->type == dns_zone_slave)) { 4432 dns_rdata_init(&rdata); 4433 dns_rdataset_current(&rdataset, &rdata); 4434 result = dns_rdata_tostruct(&rdata, &ns, NULL); 4435 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4436 if (dns_name_issubdomain(&ns.name, &zone->origin) && 4437 !zone_check_ns(zone, db, version, &ns.name, logit)) 4438 ecount++; 4439 } 4440 count++; 4441 result = dns_rdataset_next(&rdataset); 4442 } 4443 dns_rdataset_disassociate(&rdataset); 4444 4445 success: 4446 if (nscount != NULL) 4447 *nscount = count; 4448 if (errors != NULL) 4449 *errors = ecount; 4450 4451 result = ISC_R_SUCCESS; 4452 4453 invalidate_rdataset: 4454 dns_rdataset_invalidate(&rdataset); 4455 4456 return (result); 4457} 4458 4459static isc_result_t 4460zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 4461 unsigned int *soacount, 4462 isc_uint32_t *serial, isc_uint32_t *refresh, 4463 isc_uint32_t *retry, isc_uint32_t *expire, 4464 isc_uint32_t *minimum) 4465{ 4466 isc_result_t result; 4467 unsigned int count; 4468 dns_rdataset_t rdataset; 4469 dns_rdata_t rdata = DNS_RDATA_INIT; 4470 dns_rdata_soa_t soa; 4471 4472 dns_rdataset_init(&rdataset); 4473 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, 4474 dns_rdatatype_none, 0, &rdataset, NULL); 4475 if (result == ISC_R_NOTFOUND) { 4476 INSIST(!dns_rdataset_isassociated(&rdataset)); 4477 if (soacount != NULL) 4478 *soacount = 0; 4479 if (serial != NULL) 4480 *serial = 0; 4481 if (refresh != NULL) 4482 *refresh = 0; 4483 if (retry != NULL) 4484 *retry = 0; 4485 if (expire != NULL) 4486 *expire = 0; 4487 if (minimum != NULL) 4488 *minimum = 0; 4489 result = ISC_R_SUCCESS; 4490 goto invalidate_rdataset; 4491 } 4492 if (result != ISC_R_SUCCESS) { 4493 INSIST(!dns_rdataset_isassociated(&rdataset)); 4494 goto invalidate_rdataset; 4495 } 4496 4497 count = 0; 4498 result = dns_rdataset_first(&rdataset); 4499 while (result == ISC_R_SUCCESS) { 4500 dns_rdata_init(&rdata); 4501 dns_rdataset_current(&rdataset, &rdata); 4502 count++; 4503 if (count == 1) { 4504 result = dns_rdata_tostruct(&rdata, &soa, NULL); 4505 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4506 } 4507 4508 result = dns_rdataset_next(&rdataset); 4509 dns_rdata_reset(&rdata); 4510 } 4511 dns_rdataset_disassociate(&rdataset); 4512 4513 if (soacount != NULL) 4514 *soacount = count; 4515 4516 if (count > 0) { 4517 if (serial != NULL) 4518 *serial = soa.serial; 4519 if (refresh != NULL) 4520 *refresh = soa.refresh; 4521 if (retry != NULL) 4522 *retry = soa.retry; 4523 if (expire != NULL) 4524 *expire = soa.expire; 4525 if (minimum != NULL) 4526 *minimum = soa.minimum; 4527 } else { 4528 if (soacount != NULL) 4529 *soacount = 0; 4530 if (serial != NULL) 4531 *serial = 0; 4532 if (refresh != NULL) 4533 *refresh = 0; 4534 if (retry != NULL) 4535 *retry = 0; 4536 if (expire != NULL) 4537 *expire = 0; 4538 if (minimum != NULL) 4539 *minimum = 0; 4540 } 4541 4542 result = ISC_R_SUCCESS; 4543 4544 invalidate_rdataset: 4545 dns_rdataset_invalidate(&rdataset); 4546 4547 return (result); 4548} 4549 4550/* 4551 * zone must be locked. 4552 */ 4553static isc_result_t 4554zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 4555 unsigned int *soacount, isc_uint32_t *serial, 4556 isc_uint32_t *refresh, isc_uint32_t *retry, 4557 isc_uint32_t *expire, isc_uint32_t *minimum, 4558 unsigned int *errors) 4559{ 4560 isc_result_t result; 4561 isc_result_t answer = ISC_R_SUCCESS; 4562 dns_dbversion_t *version = NULL; 4563 dns_dbnode_t *node; 4564 4565 REQUIRE(db != NULL); 4566 REQUIRE(zone != NULL); 4567 4568 dns_db_currentversion(db, &version); 4569 4570 node = NULL; 4571 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 4572 if (result != ISC_R_SUCCESS) { 4573 answer = result; 4574 goto closeversion; 4575 } 4576 4577 if (nscount != NULL || errors != NULL) { 4578 result = zone_count_ns_rr(zone, db, node, version, 4579 nscount, errors, ISC_TRUE); 4580 if (result != ISC_R_SUCCESS) 4581 answer = result; 4582 } 4583 4584 if (soacount != NULL || serial != NULL || refresh != NULL 4585 || retry != NULL || expire != NULL || minimum != NULL) { 4586 result = zone_load_soa_rr(db, node, version, soacount, 4587 serial, refresh, retry, expire, 4588 minimum); 4589 if (result != ISC_R_SUCCESS) 4590 answer = result; 4591 } 4592 4593 dns_db_detachnode(db, &node); 4594 closeversion: 4595 dns_db_closeversion(db, &version, ISC_FALSE); 4596 4597 return (answer); 4598} 4599 4600void 4601dns_zone_attach(dns_zone_t *source, dns_zone_t **target) { 4602 REQUIRE(DNS_ZONE_VALID(source)); 4603 REQUIRE(target != NULL && *target == NULL); 4604 isc_refcount_increment(&source->erefs, NULL); 4605 *target = source; 4606} 4607 4608void 4609dns_zone_detach(dns_zone_t **zonep) { 4610 dns_zone_t *zone; 4611 dns_zone_t *raw = NULL; 4612 dns_zone_t *secure = NULL; 4613 unsigned int refs; 4614 isc_boolean_t free_now = ISC_FALSE; 4615 4616 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 4617 4618 zone = *zonep; 4619 4620 isc_refcount_decrement(&zone->erefs, &refs); 4621 4622 if (refs == 0) { 4623 LOCK_ZONE(zone); 4624 /* 4625 * We just detached the last external reference. 4626 */ 4627 if (zone->task != NULL) { 4628 /* 4629 * This zone is being managed. Post 4630 * its control event and let it clean 4631 * up synchronously in the context of 4632 * its task. 4633 */ 4634 isc_event_t *ev = &zone->ctlevent; 4635 isc_task_send(zone->task, &ev); 4636 } else { 4637 /* 4638 * This zone is not being managed; it has 4639 * no task and can have no outstanding 4640 * events. Free it immediately. 4641 */ 4642 /* 4643 * Unmanaged zones should not have non-null views; 4644 * we have no way of detaching from the view here 4645 * without causing deadlock because this code is called 4646 * with the view already locked. 4647 */ 4648 INSIST(zone->view == NULL); 4649 free_now = ISC_TRUE; 4650 raw = zone->raw; 4651 zone->raw = NULL; 4652 secure = zone->secure; 4653 zone->secure = NULL; 4654 } 4655 UNLOCK_ZONE(zone); 4656 } 4657 *zonep = NULL; 4658 if (free_now) { 4659 if (raw != NULL) 4660 dns_zone_detach(&raw); 4661 if (secure != NULL) 4662 dns_zone_idetach(&secure); 4663 zone_free(zone); 4664 } 4665} 4666 4667void 4668dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) { 4669 REQUIRE(DNS_ZONE_VALID(source)); 4670 REQUIRE(target != NULL && *target == NULL); 4671 LOCK_ZONE(source); 4672 zone_iattach(source, target); 4673 UNLOCK_ZONE(source); 4674} 4675 4676static void 4677zone_iattach(dns_zone_t *source, dns_zone_t **target) { 4678 4679 /* 4680 * 'source' locked by caller. 4681 */ 4682 REQUIRE(LOCKED_ZONE(source)); 4683 REQUIRE(DNS_ZONE_VALID(source)); 4684 REQUIRE(target != NULL && *target == NULL); 4685 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0); 4686 source->irefs++; 4687 INSIST(source->irefs != 0); 4688 *target = source; 4689} 4690 4691static void 4692zone_idetach(dns_zone_t **zonep) { 4693 dns_zone_t *zone; 4694 4695 /* 4696 * 'zone' locked by caller. 4697 */ 4698 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 4699 zone = *zonep; 4700 REQUIRE(LOCKED_ZONE(*zonep)); 4701 *zonep = NULL; 4702 4703 INSIST(zone->irefs > 0); 4704 zone->irefs--; 4705 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0); 4706} 4707 4708void 4709dns_zone_idetach(dns_zone_t **zonep) { 4710 dns_zone_t *zone; 4711 isc_boolean_t free_needed; 4712 4713 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 4714 zone = *zonep; 4715 *zonep = NULL; 4716 4717 LOCK_ZONE(zone); 4718 INSIST(zone->irefs > 0); 4719 zone->irefs--; 4720 free_needed = exit_check(zone); 4721 UNLOCK_ZONE(zone); 4722 if (free_needed) 4723 zone_free(zone); 4724} 4725 4726isc_mem_t * 4727dns_zone_getmctx(dns_zone_t *zone) { 4728 REQUIRE(DNS_ZONE_VALID(zone)); 4729 4730 return (zone->mctx); 4731} 4732 4733dns_zonemgr_t * 4734dns_zone_getmgr(dns_zone_t *zone) { 4735 REQUIRE(DNS_ZONE_VALID(zone)); 4736 4737 return (zone->zmgr); 4738} 4739 4740void 4741dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) { 4742 REQUIRE(DNS_ZONE_VALID(zone)); 4743 4744 LOCK_ZONE(zone); 4745 if (value) 4746 DNS_ZONE_SETFLAG(zone, flags); 4747 else 4748 DNS_ZONE_CLRFLAG(zone, flags); 4749 UNLOCK_ZONE(zone); 4750} 4751 4752void 4753dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value) 4754{ 4755 REQUIRE(DNS_ZONE_VALID(zone)); 4756 4757 LOCK_ZONE(zone); 4758 if (value) 4759 zone->options |= option; 4760 else 4761 zone->options &= ~option; 4762 UNLOCK_ZONE(zone); 4763} 4764 4765unsigned int 4766dns_zone_getoptions(dns_zone_t *zone) { 4767 4768 REQUIRE(DNS_ZONE_VALID(zone)); 4769 4770 return (zone->options); 4771} 4772 4773void 4774dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value) 4775{ 4776 REQUIRE(DNS_ZONE_VALID(zone)); 4777 4778 LOCK_ZONE(zone); 4779 if (value) 4780 zone->keyopts |= keyopt; 4781 else 4782 zone->keyopts &= ~keyopt; 4783 UNLOCK_ZONE(zone); 4784} 4785 4786unsigned int 4787dns_zone_getkeyopts(dns_zone_t *zone) { 4788 4789 REQUIRE(DNS_ZONE_VALID(zone)); 4790 4791 return (zone->keyopts); 4792} 4793 4794isc_result_t 4795dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 4796 REQUIRE(DNS_ZONE_VALID(zone)); 4797 4798 LOCK_ZONE(zone); 4799 zone->xfrsource4 = *xfrsource; 4800 UNLOCK_ZONE(zone); 4801 4802 return (ISC_R_SUCCESS); 4803} 4804 4805isc_sockaddr_t * 4806dns_zone_getxfrsource4(dns_zone_t *zone) { 4807 REQUIRE(DNS_ZONE_VALID(zone)); 4808 return (&zone->xfrsource4); 4809} 4810 4811isc_result_t 4812dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 4813 REQUIRE(DNS_ZONE_VALID(zone)); 4814 4815 LOCK_ZONE(zone); 4816 zone->xfrsource6 = *xfrsource; 4817 UNLOCK_ZONE(zone); 4818 4819 return (ISC_R_SUCCESS); 4820} 4821 4822isc_sockaddr_t * 4823dns_zone_getxfrsource6(dns_zone_t *zone) { 4824 REQUIRE(DNS_ZONE_VALID(zone)); 4825 return (&zone->xfrsource6); 4826} 4827 4828isc_result_t 4829dns_zone_setaltxfrsource4(dns_zone_t *zone, 4830 const isc_sockaddr_t *altxfrsource) 4831{ 4832 REQUIRE(DNS_ZONE_VALID(zone)); 4833 4834 LOCK_ZONE(zone); 4835 zone->altxfrsource4 = *altxfrsource; 4836 UNLOCK_ZONE(zone); 4837 4838 return (ISC_R_SUCCESS); 4839} 4840 4841isc_sockaddr_t * 4842dns_zone_getaltxfrsource4(dns_zone_t *zone) { 4843 REQUIRE(DNS_ZONE_VALID(zone)); 4844 return (&zone->altxfrsource4); 4845} 4846 4847isc_result_t 4848dns_zone_setaltxfrsource6(dns_zone_t *zone, 4849 const isc_sockaddr_t *altxfrsource) 4850{ 4851 REQUIRE(DNS_ZONE_VALID(zone)); 4852 4853 LOCK_ZONE(zone); 4854 zone->altxfrsource6 = *altxfrsource; 4855 UNLOCK_ZONE(zone); 4856 4857 return (ISC_R_SUCCESS); 4858} 4859 4860isc_sockaddr_t * 4861dns_zone_getaltxfrsource6(dns_zone_t *zone) { 4862 REQUIRE(DNS_ZONE_VALID(zone)); 4863 return (&zone->altxfrsource6); 4864} 4865 4866isc_result_t 4867dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 4868 REQUIRE(DNS_ZONE_VALID(zone)); 4869 4870 LOCK_ZONE(zone); 4871 zone->notifysrc4 = *notifysrc; 4872 UNLOCK_ZONE(zone); 4873 4874 return (ISC_R_SUCCESS); 4875} 4876 4877isc_sockaddr_t * 4878dns_zone_getnotifysrc4(dns_zone_t *zone) { 4879 REQUIRE(DNS_ZONE_VALID(zone)); 4880 return (&zone->notifysrc4); 4881} 4882 4883isc_result_t 4884dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 4885 REQUIRE(DNS_ZONE_VALID(zone)); 4886 4887 LOCK_ZONE(zone); 4888 zone->notifysrc6 = *notifysrc; 4889 UNLOCK_ZONE(zone); 4890 4891 return (ISC_R_SUCCESS); 4892} 4893 4894isc_sockaddr_t * 4895dns_zone_getnotifysrc6(dns_zone_t *zone) { 4896 REQUIRE(DNS_ZONE_VALID(zone)); 4897 return (&zone->notifysrc6); 4898} 4899 4900static isc_boolean_t 4901same_addrs(const isc_sockaddr_t *old, const isc_sockaddr_t *new, 4902 isc_uint32_t count) 4903{ 4904 unsigned int i; 4905 4906 for (i = 0; i < count; i++) 4907 if (!isc_sockaddr_equal(&old[i], &new[i])) 4908 return (ISC_FALSE); 4909 return (ISC_TRUE); 4910} 4911 4912static isc_boolean_t 4913same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) { 4914 unsigned int i; 4915 4916 if (old == NULL && new == NULL) 4917 return (ISC_TRUE); 4918 if (old == NULL || new == NULL) 4919 return (ISC_FALSE); 4920 4921 for (i = 0; i < count; i++) { 4922 if (old[i] == NULL && new[i] == NULL) 4923 continue; 4924 if (old[i] == NULL || new[i] == NULL || 4925 !dns_name_equal(old[i], new[i])) 4926 return (ISC_FALSE); 4927 } 4928 return (ISC_TRUE); 4929} 4930 4931static void 4932clear_addresskeylist(isc_sockaddr_t **addrsp, dns_name_t ***keynamesp, 4933 unsigned int *countp, isc_mem_t *mctx) 4934{ 4935 unsigned int count; 4936 isc_sockaddr_t *addrs; 4937 dns_name_t **keynames; 4938 4939 REQUIRE(countp != NULL && addrsp != NULL && keynamesp != NULL); 4940 4941 count = *countp; 4942 *countp = 0; 4943 addrs = *addrsp; 4944 *addrsp = NULL; 4945 keynames = *keynamesp; 4946 *keynamesp = NULL; 4947 4948 if (addrs != NULL) 4949 isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t)); 4950 4951 if (keynames != NULL) { 4952 unsigned int i; 4953 for (i = 0; i < count; i++) { 4954 if (keynames[i] != NULL) { 4955 dns_name_free(keynames[i], mctx); 4956 isc_mem_put(mctx, keynames[i], 4957 sizeof(dns_name_t)); 4958 keynames[i] = NULL; 4959 } 4960 } 4961 isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *)); 4962 } 4963} 4964 4965static isc_result_t 4966set_addrkeylist(unsigned int count, 4967 const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp, 4968 dns_name_t **names, dns_name_t ***newnamesp, 4969 isc_mem_t *mctx) 4970{ 4971 isc_result_t result; 4972 isc_sockaddr_t *newaddrs = NULL; 4973 dns_name_t **newnames = NULL; 4974 unsigned int i; 4975 4976 REQUIRE(newaddrsp != NULL && *newaddrsp == NULL); 4977 REQUIRE(newnamesp != NULL && *newnamesp == NULL); 4978 4979 newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs)); 4980 if (newaddrs == NULL) 4981 return (ISC_R_NOMEMORY); 4982 memmove(newaddrs, addrs, count * sizeof(*newaddrs)); 4983 4984 newnames = NULL; 4985 if (names != NULL) { 4986 newnames = isc_mem_get(mctx, count * sizeof(*newnames)); 4987 if (newnames == NULL) { 4988 isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs)); 4989 return (ISC_R_NOMEMORY); 4990 } 4991 for (i = 0; i < count; i++) 4992 newnames[i] = NULL; 4993 for (i = 0; i < count; i++) { 4994 if (names[i] != NULL) { 4995 newnames[i] = isc_mem_get(mctx, 4996 sizeof(dns_name_t)); 4997 if (newnames[i] == NULL) 4998 goto allocfail; 4999 dns_name_init(newnames[i], NULL); 5000 result = dns_name_dup(names[i], mctx, 5001 newnames[i]); 5002 if (result != ISC_R_SUCCESS) { 5003 allocfail: 5004 for (i = 0; i < count; i++) 5005 if (newnames[i] != NULL) 5006 dns_name_free( 5007 newnames[i], 5008 mctx); 5009 isc_mem_put(mctx, newaddrs, 5010 count * sizeof(*newaddrs)); 5011 isc_mem_put(mctx, newnames, 5012 count * sizeof(*newnames)); 5013 return (ISC_R_NOMEMORY); 5014 } 5015 } 5016 } 5017 } 5018 5019 *newaddrsp = newaddrs; 5020 *newnamesp = newnames; 5021 return (ISC_R_SUCCESS); 5022} 5023 5024isc_result_t 5025dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, 5026 isc_uint32_t count) 5027{ 5028 return (dns_zone_setalsonotifywithkeys(zone, notify, NULL, count)); 5029} 5030 5031isc_result_t 5032dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify, 5033 dns_name_t **keynames, isc_uint32_t count) 5034{ 5035 isc_result_t result; 5036 isc_sockaddr_t *newaddrs = NULL; 5037 dns_name_t **newnames = NULL; 5038 5039 REQUIRE(DNS_ZONE_VALID(zone)); 5040 REQUIRE(count == 0 || notify != NULL); 5041 if (keynames != NULL) 5042 REQUIRE(count != 0); 5043 5044 LOCK_ZONE(zone); 5045 5046 if (count == zone->notifycnt && 5047 same_addrs(zone->notify, notify, count) && 5048 same_keynames(zone->notifykeynames, keynames, count)) 5049 goto unlock; 5050 5051 clear_addresskeylist(&zone->notify, &zone->notifykeynames, 5052 &zone->notifycnt, zone->mctx); 5053 5054 if (count == 0) 5055 goto unlock; 5056 5057 /* 5058 * Set up the notify and notifykey lists 5059 */ 5060 result = set_addrkeylist(count, notify, &newaddrs, 5061 keynames, &newnames, zone->mctx); 5062 if (result != ISC_R_SUCCESS) 5063 goto unlock; 5064 5065 /* 5066 * Everything is ok so attach to the zone. 5067 */ 5068 zone->notify = newaddrs; 5069 zone->notifykeynames = newnames; 5070 zone->notifycnt = count; 5071 unlock: 5072 UNLOCK_ZONE(zone); 5073 return (ISC_R_SUCCESS); 5074} 5075 5076isc_result_t 5077dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters, 5078 isc_uint32_t count) 5079{ 5080 isc_result_t result; 5081 5082 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count); 5083 return (result); 5084} 5085 5086isc_result_t 5087dns_zone_setmasterswithkeys(dns_zone_t *zone, 5088 const isc_sockaddr_t *masters, 5089 dns_name_t **keynames, 5090 isc_uint32_t count) 5091{ 5092 isc_result_t result = ISC_R_SUCCESS; 5093 isc_sockaddr_t *newaddrs = NULL; 5094 dns_name_t **newnames = NULL; 5095 isc_boolean_t *newok; 5096 unsigned int i; 5097 5098 REQUIRE(DNS_ZONE_VALID(zone)); 5099 REQUIRE(count == 0 || masters != NULL); 5100 if (keynames != NULL) { 5101 REQUIRE(count != 0); 5102 } 5103 5104 LOCK_ZONE(zone); 5105 /* 5106 * The refresh code assumes that 'masters' wouldn't change under it. 5107 * If it will change then kill off any current refresh in progress 5108 * and update the masters info. If it won't change then we can just 5109 * unlock and exit. 5110 */ 5111 if (count != zone->masterscnt || 5112 !same_addrs(zone->masters, masters, count) || 5113 !same_keynames(zone->masterkeynames, keynames, count)) { 5114 if (zone->request != NULL) 5115 dns_request_cancel(zone->request); 5116 } else 5117 goto unlock; 5118 5119 /* 5120 * This needs to happen before clear_addresskeylist() sets 5121 * zone->masterscnt to 0: 5122 */ 5123 if (zone->mastersok != NULL) { 5124 isc_mem_put(zone->mctx, zone->mastersok, 5125 zone->masterscnt * sizeof(isc_boolean_t)); 5126 zone->mastersok = NULL; 5127 } 5128 clear_addresskeylist(&zone->masters, &zone->masterkeynames, 5129 &zone->masterscnt, zone->mctx); 5130 /* 5131 * If count == 0, don't allocate any space for masters, mastersok or 5132 * keynames so internally, those pointers are NULL if count == 0 5133 */ 5134 if (count == 0) 5135 goto unlock; 5136 5137 /* 5138 * mastersok must contain count elements 5139 */ 5140 newok = isc_mem_get(zone->mctx, count * sizeof(*newok)); 5141 if (newok == NULL) { 5142 result = ISC_R_NOMEMORY; 5143 isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs)); 5144 goto unlock; 5145 }; 5146 for (i = 0; i < count; i++) 5147 newok[i] = ISC_FALSE; 5148 5149 /* 5150 * Now set up the masters and masterkey lists 5151 */ 5152 result = set_addrkeylist(count, masters, &newaddrs, 5153 keynames, &newnames, zone->mctx); 5154 if (result != ISC_R_SUCCESS) { 5155 isc_mem_put(zone->mctx, newok, count * sizeof(*newok)); 5156 goto unlock; 5157 } 5158 5159 /* 5160 * Everything is ok so attach to the zone. 5161 */ 5162 zone->curmaster = 0; 5163 zone->mastersok = newok; 5164 zone->masters = newaddrs; 5165 zone->masterkeynames = newnames; 5166 zone->masterscnt = count; 5167 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS); 5168 5169 unlock: 5170 UNLOCK_ZONE(zone); 5171 return (result); 5172} 5173 5174isc_result_t 5175dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) { 5176 isc_result_t result = ISC_R_SUCCESS; 5177 5178 REQUIRE(DNS_ZONE_VALID(zone)); 5179 5180 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 5181 if (zone->db == NULL) 5182 result = DNS_R_NOTLOADED; 5183 else 5184 dns_db_attach(zone->db, dpb); 5185 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 5186 5187 return (result); 5188} 5189 5190void 5191dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) { 5192 REQUIRE(DNS_ZONE_VALID(zone)); 5193 REQUIRE(zone->type == dns_zone_staticstub); 5194 5195 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 5196 REQUIRE(zone->db == NULL); 5197 dns_db_attach(db, &zone->db); 5198 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 5199} 5200 5201/* 5202 * Co-ordinates the starting of routine jobs. 5203 */ 5204 5205void 5206dns_zone_maintenance(dns_zone_t *zone) { 5207 const char me[] = "dns_zone_maintenance"; 5208 isc_time_t now; 5209 5210 REQUIRE(DNS_ZONE_VALID(zone)); 5211 ENTER; 5212 5213 LOCK_ZONE(zone); 5214 TIME_NOW(&now); 5215 zone_settimer(zone, &now); 5216 UNLOCK_ZONE(zone); 5217} 5218 5219static inline isc_boolean_t 5220was_dumping(dns_zone_t *zone) { 5221 isc_boolean_t dumping; 5222 5223 REQUIRE(LOCKED_ZONE(zone)); 5224 5225 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING); 5226 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 5227 if (!dumping) { 5228 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 5229 isc_time_settoepoch(&zone->dumptime); 5230 } 5231 return (dumping); 5232} 5233 5234static isc_result_t 5235find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 5236 isc_mem_t *mctx, unsigned int maxkeys, 5237 dst_key_t **keys, unsigned int *nkeys) 5238{ 5239 isc_result_t result; 5240 dns_dbnode_t *node = NULL; 5241 const char *directory = dns_zone_getkeydirectory(zone); 5242 5243 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); 5244 memset(keys, 0, sizeof(*keys) * maxkeys); 5245 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db), 5246 directory, mctx, maxkeys, keys, 5247 nkeys); 5248 if (result == ISC_R_NOTFOUND) 5249 result = ISC_R_SUCCESS; 5250 failure: 5251 if (node != NULL) 5252 dns_db_detachnode(db, &node); 5253 return (result); 5254} 5255 5256static isc_result_t 5257offline(dns_db_t *db, dns_dbversion_t *ver, zonediff_t *zonediff, 5258 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) 5259{ 5260 isc_result_t result; 5261 5262 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) 5263 return (ISC_R_SUCCESS); 5264 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, 5265 name, ttl, rdata); 5266 if (result != ISC_R_SUCCESS) 5267 return (result); 5268 rdata->flags |= DNS_RDATA_OFFLINE; 5269 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN, 5270 name, ttl, rdata); 5271 zonediff->offline = ISC_TRUE; 5272 return (result); 5273} 5274 5275static void 5276set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now) 5277{ 5278 unsigned int delta; 5279 char timebuf[80]; 5280 5281 zone->key_expiry = when; 5282 if (when <= now) { 5283 dns_zone_log(zone, ISC_LOG_ERROR, 5284 "DNSKEY RRSIG(s) have expired"); 5285 isc_time_settoepoch(&zone->keywarntime); 5286 } else if (when < now + 7 * 24 * 3600) { 5287 isc_time_t t; 5288 isc_time_set(&t, when, 0); 5289 isc_time_formattimestamp(&t, timebuf, 80); 5290 dns_zone_log(zone, ISC_LOG_WARNING, 5291 "DNSKEY RRSIG(s) will expire within 7 days: %s", 5292 timebuf); 5293 delta = when - now; 5294 delta--; /* loop prevention */ 5295 delta /= 24 * 3600; /* to whole days */ 5296 delta *= 24 * 3600; /* to seconds */ 5297 isc_time_set(&zone->keywarntime, when - delta, 0); 5298 } else { 5299 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0); 5300 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 5301 dns_zone_log(zone, ISC_LOG_NOTICE, 5302 "setting keywarntime to %s", timebuf); 5303 } 5304} 5305 5306/* 5307 * Helper function to del_sigs(). We don't want to delete RRSIGs that 5308 * have no new key. 5309 */ 5310static isc_boolean_t 5311delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys, 5312 isc_boolean_t *warn) 5313{ 5314 unsigned int i = 0; 5315 isc_boolean_t have_ksk = ISC_FALSE, have_zsk = ISC_FALSE; 5316 isc_boolean_t have_pksk = ISC_FALSE, have_pzsk = ISC_FALSE; 5317 5318 for (i = 0; i < nkeys; i++) { 5319 if (rrsig_ptr->algorithm != dst_key_alg(keys[i])) 5320 continue; 5321 if (dst_key_isprivate(keys[i])) { 5322 if (KSK(keys[i])) 5323 have_ksk = have_pksk = ISC_TRUE; 5324 else 5325 have_zsk = have_pzsk = ISC_TRUE; 5326 } else { 5327 if (KSK(keys[i])) 5328 have_ksk = ISC_TRUE; 5329 else 5330 have_zsk = ISC_TRUE; 5331 } 5332 } 5333 5334 if (have_zsk && have_ksk && !have_pzsk) 5335 *warn = ISC_TRUE; 5336 5337 /* 5338 * It's okay to delete a signature if there is an active key 5339 * with the same algorithm to replace it. 5340 */ 5341 if (have_pksk || have_pzsk) 5342 return (ISC_TRUE); 5343 5344 /* 5345 * Failing that, it is *not* okay to delete a signature 5346 * if the associated public key is still in the DNSKEY RRset 5347 */ 5348 for (i = 0; i < nkeys; i++) { 5349 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) && 5350 (rrsig_ptr->keyid == dst_key_id(keys[i]))) 5351 return (ISC_FALSE); 5352 } 5353 5354 /* 5355 * But if the key is gone, then go ahead. 5356 */ 5357 return (ISC_TRUE); 5358} 5359 5360/* 5361 * Delete expired RRsigs and any RRsigs we are about to re-sign. 5362 * See also update.c:del_keysigs(). 5363 */ 5364static isc_result_t 5365del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 5366 dns_rdatatype_t type, zonediff_t *zonediff, dst_key_t **keys, 5367 unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental) 5368{ 5369 isc_result_t result; 5370 dns_dbnode_t *node = NULL; 5371 dns_rdataset_t rdataset; 5372 unsigned int i; 5373 dns_rdata_rrsig_t rrsig; 5374 isc_boolean_t found, changed; 5375 isc_int64_t warn = 0, maybe = 0; 5376 5377 dns_rdataset_init(&rdataset); 5378 5379 if (type == dns_rdatatype_nsec3) 5380 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node); 5381 else 5382 result = dns_db_findnode(db, name, ISC_FALSE, &node); 5383 if (result == ISC_R_NOTFOUND) 5384 return (ISC_R_SUCCESS); 5385 if (result != ISC_R_SUCCESS) 5386 goto failure; 5387 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type, 5388 (isc_stdtime_t) 0, &rdataset, NULL); 5389 dns_db_detachnode(db, &node); 5390 5391 if (result == ISC_R_NOTFOUND) { 5392 INSIST(!dns_rdataset_isassociated(&rdataset)); 5393 return (ISC_R_SUCCESS); 5394 } 5395 if (result != ISC_R_SUCCESS) { 5396 INSIST(!dns_rdataset_isassociated(&rdataset)); 5397 goto failure; 5398 } 5399 5400 changed = ISC_FALSE; 5401 for (result = dns_rdataset_first(&rdataset); 5402 result == ISC_R_SUCCESS; 5403 result = dns_rdataset_next(&rdataset)) { 5404 dns_rdata_t rdata = DNS_RDATA_INIT; 5405 5406 dns_rdataset_current(&rdataset, &rdata); 5407 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 5408 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5409 5410 if (type != dns_rdatatype_dnskey) { 5411 isc_boolean_t warn = ISC_FALSE, deleted = ISC_FALSE; 5412 if (delsig_ok(&rrsig, keys, nkeys, &warn)) { 5413 result = update_one_rr(db, ver, zonediff->diff, 5414 DNS_DIFFOP_DELRESIGN, name, 5415 rdataset.ttl, &rdata); 5416 if (incremental) 5417 changed = ISC_TRUE; 5418 if (result != ISC_R_SUCCESS) 5419 break; 5420 deleted = ISC_TRUE; 5421 } 5422 if (warn) { 5423 /* 5424 * At this point, we've got an RRSIG, 5425 * which is signed by an inactive key. 5426 * An administrator needs to provide a new 5427 * key/alg, but until that time, we want to 5428 * keep the old RRSIG. Marking the key as 5429 * offline will prevent us spinning waiting 5430 * for the private part. 5431 */ 5432 if (incremental && !deleted) { 5433 result = offline(db, ver, zonediff, 5434 name, rdataset.ttl, 5435 &rdata); 5436 changed = ISC_TRUE; 5437 if (result != ISC_R_SUCCESS) 5438 break; 5439 } 5440 5441 /* 5442 * Log the key id and algorithm of 5443 * the inactive key with no replacement 5444 */ 5445 if (zone->log_key_expired_timer <= now) { 5446 char origin[DNS_NAME_FORMATSIZE]; 5447 char algbuf[DNS_NAME_FORMATSIZE]; 5448 dns_name_format(&zone->origin, origin, 5449 sizeof(origin)); 5450 dns_secalg_format(rrsig.algorithm, 5451 algbuf, 5452 sizeof(algbuf)); 5453 dns_zone_log(zone, ISC_LOG_WARNING, 5454 "Key %s/%s/%d " 5455 "missing or inactive " 5456 "and has no replacement: " 5457 "retaining signatures.", 5458 origin, algbuf, 5459 rrsig.keyid); 5460 zone->log_key_expired_timer = now + 5461 3600; 5462 } 5463 } 5464 continue; 5465 } 5466 5467 /* 5468 * RRSIG(DNSKEY) requires special processing. 5469 */ 5470 found = ISC_FALSE; 5471 for (i = 0; i < nkeys; i++) { 5472 if (rrsig.algorithm == dst_key_alg(keys[i]) && 5473 rrsig.keyid == dst_key_id(keys[i])) { 5474 found = ISC_TRUE; 5475 /* 5476 * Mark offline RRSIG(DNSKEY). 5477 * We want the earliest offline expire time 5478 * iff there is a new offline signature. 5479 */ 5480 if (!dst_key_inactive(keys[i]) && 5481 !dst_key_isprivate(keys[i])) 5482 { 5483 isc_int64_t timeexpire = 5484 dns_time64_from32(rrsig.timeexpire); 5485 if (warn != 0 && warn > timeexpire) 5486 warn = timeexpire; 5487 if (rdata.flags & DNS_RDATA_OFFLINE) { 5488 if (maybe == 0 || 5489 maybe > timeexpire) 5490 maybe = timeexpire; 5491 break; 5492 } 5493 if (warn == 0) 5494 warn = maybe; 5495 if (warn == 0 || warn > timeexpire) 5496 warn = timeexpire; 5497 result = offline(db, ver, zonediff, 5498 name, rdataset.ttl, 5499 &rdata); 5500 changed = ISC_TRUE; 5501 break; 5502 } 5503 result = update_one_rr(db, ver, zonediff->diff, 5504 DNS_DIFFOP_DELRESIGN, 5505 name, rdataset.ttl, 5506 &rdata); 5507 break; 5508 } 5509 } 5510 5511 /* 5512 * If there is not a matching DNSKEY then 5513 * delete the RRSIG. 5514 */ 5515 if (!found) 5516 result = update_one_rr(db, ver, zonediff->diff, 5517 DNS_DIFFOP_DELRESIGN, name, 5518 rdataset.ttl, &rdata); 5519 if (result != ISC_R_SUCCESS) 5520 break; 5521 } 5522 5523 if (changed && (rdataset.attributes & DNS_RDATASETATTR_RESIGN) != 0) 5524 dns_db_resigned(db, &rdataset, ver); 5525 5526 dns_rdataset_disassociate(&rdataset); 5527 if (result == ISC_R_NOMORE) 5528 result = ISC_R_SUCCESS; 5529 if (warn > 0) { 5530#if defined(STDTIME_ON_32BITS) 5531 isc_stdtime_t stdwarn = (isc_stdtime_t)warn; 5532 if (warn == stdwarn) 5533#endif 5534 set_key_expiry_warning(zone, (isc_stdtime_t)warn, now); 5535#if defined(STDTIME_ON_32BITS) 5536 else 5537 dns_zone_log(zone, ISC_LOG_ERROR, 5538 "key expiry warning time out of range"); 5539#endif 5540 } 5541 failure: 5542 if (node != NULL) 5543 dns_db_detachnode(db, &node); 5544 return (result); 5545} 5546 5547static isc_result_t 5548add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 5549 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, 5550 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception, 5551 isc_stdtime_t expire, isc_boolean_t check_ksk, 5552 isc_boolean_t keyset_kskonly) 5553{ 5554 isc_result_t result; 5555 dns_dbnode_t *node = NULL; 5556 dns_rdataset_t rdataset; 5557 dns_rdata_t sig_rdata = DNS_RDATA_INIT; 5558 unsigned char data[1024]; /* XXX */ 5559 isc_buffer_t buffer; 5560 unsigned int i, j; 5561 5562 dns_rdataset_init(&rdataset); 5563 isc_buffer_init(&buffer, data, sizeof(data)); 5564 5565 if (type == dns_rdatatype_nsec3) 5566 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node); 5567 else 5568 result = dns_db_findnode(db, name, ISC_FALSE, &node); 5569 if (result == ISC_R_NOTFOUND) 5570 return (ISC_R_SUCCESS); 5571 if (result != ISC_R_SUCCESS) 5572 goto failure; 5573 result = dns_db_findrdataset(db, node, ver, type, 0, 5574 (isc_stdtime_t) 0, &rdataset, NULL); 5575 dns_db_detachnode(db, &node); 5576 if (result == ISC_R_NOTFOUND) { 5577 INSIST(!dns_rdataset_isassociated(&rdataset)); 5578 return (ISC_R_SUCCESS); 5579 } 5580 if (result != ISC_R_SUCCESS) { 5581 INSIST(!dns_rdataset_isassociated(&rdataset)); 5582 goto failure; 5583 } 5584 5585 for (i = 0; i < nkeys; i++) { 5586 isc_boolean_t both = ISC_FALSE; 5587 5588 if (!dst_key_isprivate(keys[i])) 5589 continue; 5590 5591 if (check_ksk && !REVOKE(keys[i])) { 5592 isc_boolean_t have_ksk, have_nonksk; 5593 if (KSK(keys[i])) { 5594 have_ksk = ISC_TRUE; 5595 have_nonksk = ISC_FALSE; 5596 } else { 5597 have_ksk = ISC_FALSE; 5598 have_nonksk = ISC_TRUE; 5599 } 5600 for (j = 0; j < nkeys; j++) { 5601 if (j == i || ALG(keys[i]) != ALG(keys[j])) 5602 continue; 5603 if (REVOKE(keys[j])) 5604 continue; 5605 if (KSK(keys[j])) 5606 have_ksk = ISC_TRUE; 5607 else 5608 have_nonksk = ISC_TRUE; 5609 both = have_ksk && have_nonksk; 5610 if (both) 5611 break; 5612 } 5613 } 5614 if (both) { 5615 if (type == dns_rdatatype_dnskey) { 5616 if (!KSK(keys[i]) && keyset_kskonly) 5617 continue; 5618 } else if (KSK(keys[i])) 5619 continue; 5620 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) 5621 continue; 5622 5623 /* Calculate the signature, creating a RRSIG RDATA. */ 5624 isc_buffer_clear(&buffer); 5625 CHECK(dns_dnssec_sign(name, &rdataset, keys[i], 5626 &inception, &expire, 5627 mctx, &buffer, &sig_rdata)); 5628 /* Update the database and journal with the RRSIG. */ 5629 /* XXX inefficient - will cause dataset merging */ 5630 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, 5631 name, rdataset.ttl, &sig_rdata)); 5632 dns_rdata_reset(&sig_rdata); 5633 isc_buffer_init(&buffer, data, sizeof(data)); 5634 } 5635 5636 failure: 5637 if (dns_rdataset_isassociated(&rdataset)) 5638 dns_rdataset_disassociate(&rdataset); 5639 if (node != NULL) 5640 dns_db_detachnode(db, &node); 5641 return (result); 5642} 5643 5644static void 5645zone_resigninc(dns_zone_t *zone) { 5646 const char *me = "zone_resigninc"; 5647 dns_db_t *db = NULL; 5648 dns_dbversion_t *version = NULL; 5649 dns_diff_t _sig_diff; 5650 zonediff_t zonediff; 5651 dns_fixedname_t fixed; 5652 dns_name_t *name; 5653 dns_rdataset_t rdataset; 5654 dns_rdatatype_t covers; 5655 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 5656 isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE; 5657 isc_result_t result; 5658 isc_stdtime_t now, inception, soaexpire, expire, stop; 5659 isc_uint32_t jitter; 5660 unsigned int i; 5661 unsigned int nkeys = 0; 5662 unsigned int resign; 5663 5664 ENTER; 5665 5666 dns_rdataset_init(&rdataset); 5667 dns_fixedname_init(&fixed); 5668 dns_diff_init(zone->mctx, &_sig_diff); 5669 zonediff_init(&zonediff, &_sig_diff); 5670 5671 /* 5672 * Zone is frozen or automatic resigning is disabled. 5673 * Pause for 5 minutes. 5674 */ 5675 if (zone->update_disabled || 5676 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN)) 5677 { 5678 result = ISC_R_FAILURE; 5679 goto failure; 5680 } 5681 5682 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 5683 dns_db_attach(zone->db, &db); 5684 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 5685 5686 result = dns_db_newversion(db, &version); 5687 if (result != ISC_R_SUCCESS) { 5688 dns_zone_log(zone, ISC_LOG_ERROR, 5689 "zone_resigninc:dns_db_newversion -> %s", 5690 dns_result_totext(result)); 5691 goto failure; 5692 } 5693 5694 result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS, 5695 zone_keys, &nkeys); 5696 if (result != ISC_R_SUCCESS) { 5697 dns_zone_log(zone, ISC_LOG_ERROR, 5698 "zone_resigninc:find_zone_keys -> %s", 5699 dns_result_totext(result)); 5700 goto failure; 5701 } 5702 5703 isc_stdtime_get(&now); 5704 inception = now - 3600; /* Allow for clock skew. */ 5705 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 5706 /* 5707 * Spread out signatures over time if they happen to be 5708 * clumped. We don't do this for each add_sigs() call as 5709 * we still want some clustering to occur. 5710 */ 5711 isc_random_get(&jitter); 5712 expire = soaexpire - jitter % 3600; 5713 stop = now + 5; 5714 5715 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 5716 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 5717 5718 name = dns_fixedname_name(&fixed); 5719 result = dns_db_getsigningtime(db, &rdataset, name); 5720 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 5721 dns_zone_log(zone, ISC_LOG_ERROR, 5722 "zone_resigninc:dns_db_getsigningtime -> %s", 5723 dns_result_totext(result)); 5724 } 5725 5726 i = 0; 5727 while (result == ISC_R_SUCCESS) { 5728 resign = rdataset.resign - zone->sigresigninginterval; 5729 covers = rdataset.covers; 5730 dns_rdataset_disassociate(&rdataset); 5731 5732 /* 5733 * Stop if we hit the SOA as that means we have walked the 5734 * entire zone. The SOA record should always be the most 5735 * recent signature. 5736 */ 5737 /* XXXMPA increase number of RRsets signed pre call */ 5738 if (covers == dns_rdatatype_soa || i++ > zone->signatures || 5739 resign > stop) 5740 break; 5741 5742 result = del_sigs(zone, db, version, name, covers, &zonediff, 5743 zone_keys, nkeys, now, ISC_TRUE); 5744 if (result != ISC_R_SUCCESS) { 5745 dns_zone_log(zone, ISC_LOG_ERROR, 5746 "zone_resigninc:del_sigs -> %s", 5747 dns_result_totext(result)); 5748 break; 5749 } 5750 5751 result = add_sigs(db, version, name, covers, zonediff.diff, 5752 zone_keys, nkeys, zone->mctx, inception, 5753 expire, check_ksk, keyset_kskonly); 5754 if (result != ISC_R_SUCCESS) { 5755 dns_zone_log(zone, ISC_LOG_ERROR, 5756 "zone_resigninc:add_sigs -> %s", 5757 dns_result_totext(result)); 5758 break; 5759 } 5760 result = dns_db_getsigningtime(db, &rdataset, 5761 dns_fixedname_name(&fixed)); 5762 if (nkeys == 0 && result == ISC_R_NOTFOUND) { 5763 result = ISC_R_SUCCESS; 5764 break; 5765 } 5766 if (result != ISC_R_SUCCESS) 5767 dns_zone_log(zone, ISC_LOG_ERROR, 5768 "zone_resigninc:dns_db_getsigningtime -> %s", 5769 dns_result_totext(result)); 5770 } 5771 5772 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS) 5773 goto failure; 5774 5775 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 5776 &zonediff, zone_keys, nkeys, now, ISC_TRUE); 5777 if (result != ISC_R_SUCCESS) { 5778 dns_zone_log(zone, ISC_LOG_ERROR, 5779 "zone_resigninc:del_sigs -> %s", 5780 dns_result_totext(result)); 5781 goto failure; 5782 } 5783 5784 /* 5785 * Did we change anything in the zone? 5786 */ 5787 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 5788 /* 5789 * Commit the changes if any key has been marked as offline. */ 5790 if (zonediff.offline) 5791 dns_db_closeversion(db, &version, ISC_TRUE); 5792 goto failure; 5793 } 5794 5795 /* Increment SOA serial if we have made changes */ 5796 result = update_soa_serial(db, version, zonediff.diff, zone->mctx, 5797 zone->updatemethod); 5798 if (result != ISC_R_SUCCESS) { 5799 dns_zone_log(zone, ISC_LOG_ERROR, 5800 "zone_resigninc:update_soa_serial -> %s", 5801 dns_result_totext(result)); 5802 goto failure; 5803 } 5804 5805 /* 5806 * Generate maximum life time signatures so that the above loop 5807 * termination is sensible. 5808 */ 5809 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, 5810 zonediff.diff, zone_keys, nkeys, zone->mctx, 5811 inception, soaexpire, check_ksk, keyset_kskonly); 5812 if (result != ISC_R_SUCCESS) { 5813 dns_zone_log(zone, ISC_LOG_ERROR, 5814 "zone_resigninc:add_sigs -> %s", 5815 dns_result_totext(result)); 5816 goto failure; 5817 } 5818 5819 /* Write changes to journal file. */ 5820 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc")); 5821 5822 /* Everything has succeeded. Commit the changes. */ 5823 dns_db_closeversion(db, &version, ISC_TRUE); 5824 5825 failure: 5826 dns_diff_clear(&_sig_diff); 5827 for (i = 0; i < nkeys; i++) 5828 dst_key_free(&zone_keys[i]); 5829 if (version != NULL) { 5830 dns_db_closeversion(zone->db, &version, ISC_FALSE); 5831 dns_db_detach(&db); 5832 } else if (db != NULL) 5833 dns_db_detach(&db); 5834 if (result == ISC_R_SUCCESS) { 5835 set_resigntime(zone); 5836 LOCK_ZONE(zone); 5837 zone_needdump(zone, DNS_DUMP_DELAY); 5838 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 5839 UNLOCK_ZONE(zone); 5840 } else { 5841 /* 5842 * Something failed. Retry in 5 minutes. 5843 */ 5844 isc_interval_t ival; 5845 isc_interval_set(&ival, 300, 0); 5846 isc_time_nowplusinterval(&zone->resigntime, &ival); 5847 } 5848} 5849 5850static isc_result_t 5851next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname, 5852 dns_name_t *newname, isc_boolean_t bottom) 5853{ 5854 isc_result_t result; 5855 dns_dbiterator_t *dbit = NULL; 5856 dns_rdatasetiter_t *rdsit = NULL; 5857 dns_dbnode_t *node = NULL; 5858 5859 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit)); 5860 CHECK(dns_dbiterator_seek(dbit, oldname)); 5861 do { 5862 result = dns_dbiterator_next(dbit); 5863 if (result == ISC_R_NOMORE) 5864 CHECK(dns_dbiterator_first(dbit)); 5865 CHECK(dns_dbiterator_current(dbit, &node, newname)); 5866 if (bottom && dns_name_issubdomain(newname, oldname) && 5867 !dns_name_equal(newname, oldname)) { 5868 dns_db_detachnode(db, &node); 5869 continue; 5870 } 5871 /* 5872 * Is this node empty? 5873 */ 5874 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit)); 5875 result = dns_rdatasetiter_first(rdsit); 5876 dns_db_detachnode(db, &node); 5877 dns_rdatasetiter_destroy(&rdsit); 5878 if (result != ISC_R_NOMORE) 5879 break; 5880 } while (1); 5881 failure: 5882 if (node != NULL) 5883 dns_db_detachnode(db, &node); 5884 if (dbit != NULL) 5885 dns_dbiterator_destroy(&dbit); 5886 return (result); 5887} 5888 5889static isc_boolean_t 5890signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 5891 dns_rdatatype_t type, dst_key_t *key) 5892{ 5893 isc_result_t result; 5894 dns_rdataset_t rdataset; 5895 dns_rdata_t rdata = DNS_RDATA_INIT; 5896 dns_rdata_rrsig_t rrsig; 5897 5898 dns_rdataset_init(&rdataset); 5899 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig, 5900 type, 0, &rdataset, NULL); 5901 if (result != ISC_R_SUCCESS) { 5902 INSIST(!dns_rdataset_isassociated(&rdataset)); 5903 return (ISC_FALSE); 5904 } 5905 for (result = dns_rdataset_first(&rdataset); 5906 result == ISC_R_SUCCESS; 5907 result = dns_rdataset_next(&rdataset)) { 5908 dns_rdataset_current(&rdataset, &rdata); 5909 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 5910 INSIST(result == ISC_R_SUCCESS); 5911 if (rrsig.algorithm == dst_key_alg(key) && 5912 rrsig.keyid == dst_key_id(key)) { 5913 dns_rdataset_disassociate(&rdataset); 5914 return (ISC_TRUE); 5915 } 5916 dns_rdata_reset(&rdata); 5917 } 5918 dns_rdataset_disassociate(&rdataset); 5919 return (ISC_FALSE); 5920} 5921 5922static isc_result_t 5923add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 5924 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom, 5925 dns_diff_t *diff) 5926{ 5927 dns_fixedname_t fixed; 5928 dns_name_t *next; 5929 dns_rdata_t rdata = DNS_RDATA_INIT; 5930 isc_result_t result; 5931 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE]; 5932 5933 dns_fixedname_init(&fixed); 5934 next = dns_fixedname_name(&fixed); 5935 5936 CHECK(next_active(db, version, name, next, bottom)); 5937 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer, 5938 &rdata)); 5939 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl, 5940 &rdata)); 5941 failure: 5942 return (result); 5943} 5944 5945static isc_result_t 5946sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node, 5947 dns_dbversion_t *version, isc_boolean_t build_nsec3, 5948 isc_boolean_t build_nsec, dst_key_t *key, 5949 isc_stdtime_t inception, isc_stdtime_t expire, 5950 unsigned int minimum, isc_boolean_t is_ksk, 5951 isc_boolean_t keyset_kskonly, isc_boolean_t *delegation, 5952 dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx) 5953{ 5954 isc_result_t result; 5955 dns_rdatasetiter_t *iterator = NULL; 5956 dns_rdataset_t rdataset; 5957 dns_rdata_t rdata = DNS_RDATA_INIT; 5958 isc_buffer_t buffer; 5959 unsigned char data[1024]; 5960 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec, 5961 seen_nsec3, seen_ds; 5962 isc_boolean_t bottom; 5963 5964 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 5965 if (result != ISC_R_SUCCESS) { 5966 if (result == ISC_R_NOTFOUND) 5967 result = ISC_R_SUCCESS; 5968 return (result); 5969 } 5970 5971 dns_rdataset_init(&rdataset); 5972 isc_buffer_init(&buffer, data, sizeof(data)); 5973 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec = 5974 seen_nsec3 = seen_ds = ISC_FALSE; 5975 for (result = dns_rdatasetiter_first(iterator); 5976 result == ISC_R_SUCCESS; 5977 result = dns_rdatasetiter_next(iterator)) { 5978 dns_rdatasetiter_current(iterator, &rdataset); 5979 if (rdataset.type == dns_rdatatype_soa) 5980 seen_soa = ISC_TRUE; 5981 else if (rdataset.type == dns_rdatatype_ns) 5982 seen_ns = ISC_TRUE; 5983 else if (rdataset.type == dns_rdatatype_ds) 5984 seen_ds = ISC_TRUE; 5985 else if (rdataset.type == dns_rdatatype_dname) 5986 seen_dname = ISC_TRUE; 5987 else if (rdataset.type == dns_rdatatype_nsec) 5988 seen_nsec = ISC_TRUE; 5989 else if (rdataset.type == dns_rdatatype_nsec3) 5990 seen_nsec3 = ISC_TRUE; 5991 if (rdataset.type != dns_rdatatype_rrsig) 5992 seen_rr = ISC_TRUE; 5993 dns_rdataset_disassociate(&rdataset); 5994 } 5995 if (result != ISC_R_NOMORE) 5996 goto failure; 5997 if (seen_ns && !seen_soa) 5998 *delegation = ISC_TRUE; 5999 /* 6000 * Going from insecure to NSEC3. 6001 * Don't generate NSEC3 records for NSEC3 records. 6002 */ 6003 if (build_nsec3 && !seen_nsec3 && seen_rr) { 6004 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa; 6005 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum, 6006 unsecure, diff)); 6007 (*signatures)--; 6008 } 6009 /* 6010 * Going from insecure to NSEC. 6011 * Don't generate NSEC records for NSEC3 records. 6012 */ 6013 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) { 6014 /* Build and add NSEC. */ 6015 bottom = (seen_ns && !seen_soa) || seen_dname; 6016 /* 6017 * Build a NSEC record except at the origin. 6018 */ 6019 if (!dns_name_equal(name, dns_db_origin(db))) { 6020 CHECK(add_nsec(db, version, name, node, minimum, 6021 bottom, diff)); 6022 /* Count a NSEC generation as a signature generation. */ 6023 (*signatures)--; 6024 } 6025 } 6026 result = dns_rdatasetiter_first(iterator); 6027 while (result == ISC_R_SUCCESS) { 6028 dns_rdatasetiter_current(iterator, &rdataset); 6029 if (rdataset.type == dns_rdatatype_soa || 6030 rdataset.type == dns_rdatatype_rrsig) 6031 goto next_rdataset; 6032 if (rdataset.type == dns_rdatatype_dnskey) { 6033 if (!is_ksk && keyset_kskonly) 6034 goto next_rdataset; 6035 } else if (is_ksk) 6036 goto next_rdataset; 6037 if (*delegation && 6038 rdataset.type != dns_rdatatype_ds && 6039 rdataset.type != dns_rdatatype_nsec) 6040 goto next_rdataset; 6041 if (signed_with_key(db, node, version, rdataset.type, key)) 6042 goto next_rdataset; 6043 /* Calculate the signature, creating a RRSIG RDATA. */ 6044 isc_buffer_clear(&buffer); 6045 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception, 6046 &expire, mctx, &buffer, &rdata)); 6047 /* Update the database and journal with the RRSIG. */ 6048 /* XXX inefficient - will cause dataset merging */ 6049 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN, 6050 name, rdataset.ttl, &rdata)); 6051 dns_rdata_reset(&rdata); 6052 (*signatures)--; 6053 next_rdataset: 6054 dns_rdataset_disassociate(&rdataset); 6055 result = dns_rdatasetiter_next(iterator); 6056 } 6057 if (result == ISC_R_NOMORE) 6058 result = ISC_R_SUCCESS; 6059 if (seen_dname) 6060 *delegation = ISC_TRUE; 6061 failure: 6062 if (dns_rdataset_isassociated(&rdataset)) 6063 dns_rdataset_disassociate(&rdataset); 6064 if (iterator != NULL) 6065 dns_rdatasetiter_destroy(&iterator); 6066 return (result); 6067} 6068 6069/* 6070 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist. 6071 */ 6072static isc_result_t 6073updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 6074 dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff) 6075{ 6076 isc_result_t result; 6077 dns_rdataset_t rdataset; 6078 dns_dbnode_t *node = NULL; 6079 6080 CHECK(dns_db_getoriginnode(db, &node)); 6081 if (update_only) { 6082 dns_rdataset_init(&rdataset); 6083 result = dns_db_findrdataset(db, node, version, 6084 dns_rdatatype_nsec, 6085 dns_rdatatype_none, 6086 0, &rdataset, NULL); 6087 if (dns_rdataset_isassociated(&rdataset)) 6088 dns_rdataset_disassociate(&rdataset); 6089 if (result == ISC_R_NOTFOUND) 6090 goto success; 6091 if (result != ISC_R_SUCCESS) 6092 goto failure; 6093 } 6094 CHECK(delete_nsec(db, version, node, name, diff)); 6095 CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff)); 6096 success: 6097 result = ISC_R_SUCCESS; 6098 failure: 6099 if (node != NULL) 6100 dns_db_detachnode(db, &node); 6101 return (result); 6102} 6103 6104static isc_result_t 6105updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing, 6106 dns_dbversion_t *version, isc_boolean_t build_nsec3, 6107 dns_ttl_t minimum, dns_diff_t *diff) 6108{ 6109 isc_result_t result; 6110 dns_dbnode_t *node = NULL; 6111 dns_rdataset_t rdataset; 6112 dns_rdata_t rdata = DNS_RDATA_INIT; 6113 unsigned char data[5]; 6114 isc_boolean_t seen_done = ISC_FALSE; 6115 isc_boolean_t have_rr = ISC_FALSE; 6116 6117 dns_rdataset_init(&rdataset); 6118 result = dns_db_getoriginnode(signing->db, &node); 6119 if (result != ISC_R_SUCCESS) 6120 goto failure; 6121 6122 result = dns_db_findrdataset(signing->db, node, version, 6123 zone->privatetype, dns_rdatatype_none, 6124 0, &rdataset, NULL); 6125 if (result == ISC_R_NOTFOUND) { 6126 INSIST(!dns_rdataset_isassociated(&rdataset)); 6127 result = ISC_R_SUCCESS; 6128 goto failure; 6129 } 6130 if (result != ISC_R_SUCCESS) { 6131 INSIST(!dns_rdataset_isassociated(&rdataset)); 6132 goto failure; 6133 } 6134 for (result = dns_rdataset_first(&rdataset); 6135 result == ISC_R_SUCCESS; 6136 result = dns_rdataset_next(&rdataset)) { 6137 dns_rdataset_current(&rdataset, &rdata); 6138 /* 6139 * If we don't match the algorithm or keyid skip the record. 6140 */ 6141 if (rdata.length != 5 || 6142 rdata.data[0] != signing->algorithm || 6143 rdata.data[1] != ((signing->keyid >> 8) & 0xff) || 6144 rdata.data[2] != (signing->keyid & 0xff)) { 6145 have_rr = ISC_TRUE; 6146 dns_rdata_reset(&rdata); 6147 continue; 6148 } 6149 /* 6150 * We have a match. If we were signing (!signing->delete) 6151 * and we already have a record indicating that we have 6152 * finished signing (rdata.data[4] != 0) then keep it. 6153 * Otherwise it needs to be deleted as we have removed all 6154 * the signatures (signing->delete), so any record indicating 6155 * completion is now out of date, or we have finished signing 6156 * with the new record so we no longer need to remember that 6157 * we need to sign the zone with the matching key across a 6158 * nameserver re-start. 6159 */ 6160 if (!signing->delete && rdata.data[4] != 0) { 6161 seen_done = ISC_TRUE; 6162 have_rr = ISC_TRUE; 6163 } else 6164 CHECK(update_one_rr(signing->db, version, diff, 6165 DNS_DIFFOP_DEL, &zone->origin, 6166 rdataset.ttl, &rdata)); 6167 dns_rdata_reset(&rdata); 6168 } 6169 if (result == ISC_R_NOMORE) 6170 result = ISC_R_SUCCESS; 6171 if (!signing->delete && !seen_done) { 6172 /* 6173 * If we were signing then we need to indicate that we have 6174 * finished signing the zone with this key. If it is already 6175 * there we don't need to add it a second time. 6176 */ 6177 data[0] = signing->algorithm; 6178 data[1] = (signing->keyid >> 8) & 0xff; 6179 data[2] = signing->keyid & 0xff; 6180 data[3] = 0; 6181 data[4] = 1; 6182 rdata.length = sizeof(data); 6183 rdata.data = data; 6184 rdata.type = zone->privatetype; 6185 rdata.rdclass = dns_db_class(signing->db); 6186 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD, 6187 &zone->origin, rdataset.ttl, &rdata)); 6188 } else if (!have_rr) { 6189 dns_name_t *origin = dns_db_origin(signing->db); 6190 /* 6191 * Rebuild the NSEC/NSEC3 record for the origin as we no 6192 * longer have any private records. 6193 */ 6194 if (build_nsec3) 6195 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin, 6196 minimum, ISC_FALSE, diff)); 6197 CHECK(updatesecure(signing->db, version, origin, minimum, 6198 ISC_TRUE, diff)); 6199 } 6200 6201 failure: 6202 if (dns_rdataset_isassociated(&rdataset)) 6203 dns_rdataset_disassociate(&rdataset); 6204 if (node != NULL) 6205 dns_db_detachnode(signing->db, &node); 6206 return (result); 6207} 6208 6209/* 6210 * If 'active' is set then we are not done with the chain yet so only 6211 * delete the nsec3param record which indicates a full chain exists 6212 * (flags == 0). 6213 */ 6214static isc_result_t 6215fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain, 6216 isc_boolean_t active, dns_rdatatype_t privatetype, 6217 dns_diff_t *diff) 6218{ 6219 dns_dbnode_t *node = NULL; 6220 dns_name_t *name = dns_db_origin(db); 6221 dns_rdata_t rdata = DNS_RDATA_INIT; 6222 dns_rdataset_t rdataset; 6223 dns_rdata_nsec3param_t nsec3param; 6224 isc_result_t result; 6225 isc_buffer_t buffer; 6226 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE]; 6227 dns_ttl_t ttl = 0; 6228 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; 6229 6230 dns_rdataset_init(&rdataset); 6231 6232 result = dns_db_getoriginnode(db, &node); 6233 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6234 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 6235 0, 0, &rdataset, NULL); 6236 if (result == ISC_R_NOTFOUND) 6237 goto try_private; 6238 if (result != ISC_R_SUCCESS) 6239 goto failure; 6240 6241 /* 6242 * Preserve the existing ttl. 6243 */ 6244 ttl = rdataset.ttl; 6245 6246 /* 6247 * Delete all NSEC3PARAM records which match that in nsec3chain. 6248 */ 6249 for (result = dns_rdataset_first(&rdataset); 6250 result == ISC_R_SUCCESS; 6251 result = dns_rdataset_next(&rdataset)) { 6252 6253 dns_rdataset_current(&rdataset, &rdata); 6254 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 6255 6256 if (nsec3param.hash != chain->nsec3param.hash || 6257 (active && nsec3param.flags != 0) || 6258 nsec3param.iterations != chain->nsec3param.iterations || 6259 nsec3param.salt_length != chain->nsec3param.salt_length || 6260 memcmp(nsec3param.salt, chain->nsec3param.salt, 6261 nsec3param.salt_length)) { 6262 dns_rdata_reset(&rdata); 6263 continue; 6264 } 6265 6266 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, 6267 name, rdataset.ttl, &rdata)); 6268 dns_rdata_reset(&rdata); 6269 } 6270 if (result != ISC_R_NOMORE) 6271 goto failure; 6272 6273 dns_rdataset_disassociate(&rdataset); 6274 6275 try_private: 6276 6277 if (active) 6278 goto add; 6279 6280 result = dns_nsec_nseconly(db, ver, &nseconly); 6281 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 6282 6283 /* 6284 * Delete all private records which match that in nsec3chain. 6285 */ 6286 result = dns_db_findrdataset(db, node, ver, privatetype, 6287 0, 0, &rdataset, NULL); 6288 if (result == ISC_R_NOTFOUND) 6289 goto add; 6290 if (result != ISC_R_SUCCESS) 6291 goto failure; 6292 6293 for (result = dns_rdataset_first(&rdataset); 6294 result == ISC_R_SUCCESS; 6295 result = dns_rdataset_next(&rdataset)) { 6296 dns_rdata_t private = DNS_RDATA_INIT; 6297 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 6298 6299 dns_rdataset_current(&rdataset, &private); 6300 if (!dns_nsec3param_fromprivate(&private, &rdata, 6301 buf, sizeof(buf))) 6302 continue; 6303 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 6304 6305 if ((!nsec3ok && 6306 (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) || 6307 nsec3param.hash != chain->nsec3param.hash || 6308 nsec3param.iterations != chain->nsec3param.iterations || 6309 nsec3param.salt_length != chain->nsec3param.salt_length || 6310 memcmp(nsec3param.salt, chain->nsec3param.salt, 6311 nsec3param.salt_length)) { 6312 dns_rdata_reset(&rdata); 6313 continue; 6314 } 6315 6316 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, 6317 name, rdataset.ttl, &private)); 6318 dns_rdata_reset(&rdata); 6319 } 6320 if (result != ISC_R_NOMORE) 6321 goto failure; 6322 6323 add: 6324 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) { 6325 result = ISC_R_SUCCESS; 6326 goto failure; 6327 } 6328 6329 /* 6330 * Add a NSEC3PARAM record which matches that in nsec3chain but 6331 * with all flags bits cleared. 6332 * 6333 * Note: we do not clear chain->nsec3param.flags as this change 6334 * may be reversed. 6335 */ 6336 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf)); 6337 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), 6338 dns_rdatatype_nsec3param, 6339 &chain->nsec3param, &buffer)); 6340 rdata.data[1] = 0; /* Clear flag bits. */ 6341 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata)); 6342 6343 failure: 6344 dns_db_detachnode(db, &node); 6345 if (dns_rdataset_isassociated(&rdataset)) 6346 dns_rdataset_disassociate(&rdataset); 6347 return (result); 6348} 6349 6350static isc_result_t 6351delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 6352 dns_name_t *name, dns_diff_t *diff) 6353{ 6354 dns_rdataset_t rdataset; 6355 isc_result_t result; 6356 6357 dns_rdataset_init(&rdataset); 6358 6359 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 6360 0, 0, &rdataset, NULL); 6361 if (result == ISC_R_NOTFOUND) 6362 return (ISC_R_SUCCESS); 6363 if (result != ISC_R_SUCCESS) 6364 return (result); 6365 for (result = dns_rdataset_first(&rdataset); 6366 result == ISC_R_SUCCESS; 6367 result = dns_rdataset_next(&rdataset)) { 6368 dns_rdata_t rdata = DNS_RDATA_INIT; 6369 6370 dns_rdataset_current(&rdataset, &rdata); 6371 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 6372 rdataset.ttl, &rdata)); 6373 } 6374 if (result == ISC_R_NOMORE) 6375 result = ISC_R_SUCCESS; 6376 failure: 6377 dns_rdataset_disassociate(&rdataset); 6378 return (result); 6379} 6380 6381static isc_result_t 6382deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 6383 dns_name_t *name, const dns_rdata_nsec3param_t *param, 6384 dns_diff_t *diff) 6385{ 6386 dns_rdataset_t rdataset; 6387 dns_rdata_nsec3_t nsec3; 6388 isc_result_t result; 6389 6390 dns_rdataset_init(&rdataset); 6391 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 6392 0, 0, &rdataset, NULL); 6393 if (result == ISC_R_NOTFOUND) 6394 return (ISC_R_SUCCESS); 6395 if (result != ISC_R_SUCCESS) 6396 return (result); 6397 6398 for (result = dns_rdataset_first(&rdataset); 6399 result == ISC_R_SUCCESS; 6400 result = dns_rdataset_next(&rdataset)) { 6401 dns_rdata_t rdata = DNS_RDATA_INIT; 6402 6403 dns_rdataset_current(&rdataset, &rdata); 6404 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL)); 6405 if (nsec3.hash != param->hash || 6406 nsec3.iterations != param->iterations || 6407 nsec3.salt_length != param->salt_length || 6408 memcmp(nsec3.salt, param->salt, nsec3.salt_length)) 6409 continue; 6410 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 6411 rdataset.ttl, &rdata)); 6412 } 6413 if (result == ISC_R_NOMORE) 6414 result = ISC_R_SUCCESS; 6415 failure: 6416 dns_rdataset_disassociate(&rdataset); 6417 return (result); 6418} 6419 6420static isc_result_t 6421need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver, 6422 const dns_rdata_nsec3param_t *param, 6423 isc_boolean_t *answer) 6424{ 6425 dns_dbnode_t *node = NULL; 6426 dns_rdata_t rdata = DNS_RDATA_INIT; 6427 dns_rdata_nsec3param_t myparam; 6428 dns_rdataset_t rdataset; 6429 isc_result_t result; 6430 6431 *answer = ISC_FALSE; 6432 6433 result = dns_db_getoriginnode(db, &node); 6434 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6435 6436 dns_rdataset_init(&rdataset); 6437 6438 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 6439 0, 0, &rdataset, NULL); 6440 if (result == ISC_R_SUCCESS) { 6441 dns_rdataset_disassociate(&rdataset); 6442 dns_db_detachnode(db, &node); 6443 return (result); 6444 } 6445 if (result != ISC_R_NOTFOUND) { 6446 dns_db_detachnode(db, &node); 6447 return (result); 6448 } 6449 6450 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 6451 0, 0, &rdataset, NULL); 6452 if (result == ISC_R_NOTFOUND) { 6453 *answer = ISC_TRUE; 6454 dns_db_detachnode(db, &node); 6455 return (ISC_R_SUCCESS); 6456 } 6457 if (result != ISC_R_SUCCESS) { 6458 dns_db_detachnode(db, &node); 6459 return (result); 6460 } 6461 6462 for (result = dns_rdataset_first(&rdataset); 6463 result == ISC_R_SUCCESS; 6464 result = dns_rdataset_next(&rdataset)) { 6465 dns_rdataset_current(&rdataset, &rdata); 6466 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL)); 6467 dns_rdata_reset(&rdata); 6468 /* 6469 * Ignore any NSEC3PARAM removals. 6470 */ 6471 if (NSEC3REMOVE(myparam.flags)) 6472 continue; 6473 /* 6474 * Ignore the chain that we are in the process of deleting. 6475 */ 6476 if (myparam.hash == param->hash && 6477 myparam.iterations == param->iterations && 6478 myparam.salt_length == param->salt_length && 6479 !memcmp(myparam.salt, param->salt, myparam.salt_length)) 6480 continue; 6481 /* 6482 * Found an active NSEC3 chain. 6483 */ 6484 break; 6485 } 6486 if (result == ISC_R_NOMORE) { 6487 *answer = ISC_TRUE; 6488 result = ISC_R_SUCCESS; 6489 } 6490 6491 failure: 6492 if (dns_rdataset_isassociated(&rdataset)) 6493 dns_rdataset_disassociate(&rdataset); 6494 dns_db_detachnode(db, &node); 6495 return (result); 6496} 6497 6498static isc_result_t 6499update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, 6500 dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone, 6501 isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now, 6502 isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly, 6503 zonediff_t *zonediff) 6504{ 6505 dns_difftuple_t *tuple; 6506 isc_result_t result; 6507 6508 for (tuple = ISC_LIST_HEAD(diff->tuples); 6509 tuple != NULL; 6510 tuple = ISC_LIST_HEAD(diff->tuples)) { 6511 result = del_sigs(zone, db, version, &tuple->name, 6512 tuple->rdata.type, zonediff, 6513 zone_keys, nkeys, now, ISC_FALSE); 6514 if (result != ISC_R_SUCCESS) { 6515 dns_zone_log(zone, ISC_LOG_ERROR, 6516 "update_sigs:del_sigs -> %s", 6517 dns_result_totext(result)); 6518 return (result); 6519 } 6520 result = add_sigs(db, version, &tuple->name, 6521 tuple->rdata.type, zonediff->diff, 6522 zone_keys, nkeys, zone->mctx, inception, 6523 expire, check_ksk, keyset_kskonly); 6524 if (result != ISC_R_SUCCESS) { 6525 dns_zone_log(zone, ISC_LOG_ERROR, 6526 "update_sigs:add_sigs -> %s", 6527 dns_result_totext(result)); 6528 return (result); 6529 } 6530 6531 do { 6532 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link); 6533 while (next != NULL && 6534 (tuple->rdata.type != next->rdata.type || 6535 !dns_name_equal(&tuple->name, &next->name))) 6536 next = ISC_LIST_NEXT(next, link); 6537 ISC_LIST_UNLINK(diff->tuples, tuple, link); 6538 dns_diff_appendminimal(zonediff->diff, &tuple); 6539 INSIST(tuple == NULL); 6540 tuple = next; 6541 } while (tuple != NULL); 6542 } 6543 return (ISC_R_SUCCESS); 6544} 6545 6546/* 6547 * Incrementally build and sign a new NSEC3 chain using the parameters 6548 * requested. 6549 */ 6550static void 6551zone_nsec3chain(dns_zone_t *zone) { 6552 const char *me = "zone_nsec3chain"; 6553 dns_db_t *db = NULL; 6554 dns_dbnode_t *node = NULL; 6555 dns_dbversion_t *version = NULL; 6556 dns_diff_t _sig_diff; 6557 dns_diff_t nsec_diff; 6558 dns_diff_t nsec3_diff; 6559 dns_diff_t param_diff; 6560 zonediff_t zonediff; 6561 dns_fixedname_t fixed; 6562 dns_fixedname_t nextfixed; 6563 dns_name_t *name, *nextname; 6564 dns_rdataset_t rdataset; 6565 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain; 6566 dns_nsec3chainlist_t cleanup; 6567 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 6568 isc_int32_t signatures; 6569 isc_boolean_t check_ksk, keyset_kskonly; 6570 isc_boolean_t delegation; 6571 isc_boolean_t first; 6572 isc_result_t result; 6573 isc_stdtime_t now, inception, soaexpire, expire; 6574 isc_uint32_t jitter; 6575 unsigned int i; 6576 unsigned int nkeys = 0; 6577 isc_uint32_t nodes; 6578 isc_boolean_t unsecure = ISC_FALSE; 6579 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds; 6580 isc_boolean_t seen_nsec, seen_nsec3, seen_rr; 6581 dns_rdatasetiter_t *iterator = NULL; 6582 isc_boolean_t buildnsecchain; 6583 isc_boolean_t updatensec = ISC_FALSE; 6584 dns_rdatatype_t privatetype = zone->privatetype; 6585 6586 ENTER; 6587 6588 dns_rdataset_init(&rdataset); 6589 dns_fixedname_init(&fixed); 6590 name = dns_fixedname_name(&fixed); 6591 dns_fixedname_init(&nextfixed); 6592 nextname = dns_fixedname_name(&nextfixed); 6593 dns_diff_init(zone->mctx, ¶m_diff); 6594 dns_diff_init(zone->mctx, &nsec3_diff); 6595 dns_diff_init(zone->mctx, &nsec_diff); 6596 dns_diff_init(zone->mctx, &_sig_diff); 6597 zonediff_init(&zonediff, &_sig_diff); 6598 ISC_LIST_INIT(cleanup); 6599 6600 /* 6601 * Updates are disabled. Pause for 5 minutes. 6602 */ 6603 if (zone->update_disabled) { 6604 result = ISC_R_FAILURE; 6605 goto failure; 6606 } 6607 6608 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 6609 dns_db_attach(zone->db, &db); 6610 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 6611 6612 result = dns_db_newversion(db, &version); 6613 if (result != ISC_R_SUCCESS) { 6614 dns_zone_log(zone, ISC_LOG_ERROR, 6615 "zone_nsec3chain:dns_db_newversion -> %s", 6616 dns_result_totext(result)); 6617 goto failure; 6618 } 6619 6620 result = find_zone_keys(zone, db, version, zone->mctx, 6621 DNS_MAXZONEKEYS, zone_keys, &nkeys); 6622 if (result != ISC_R_SUCCESS) { 6623 dns_zone_log(zone, ISC_LOG_ERROR, 6624 "zone_nsec3chain:find_zone_keys -> %s", 6625 dns_result_totext(result)); 6626 goto failure; 6627 } 6628 6629 isc_stdtime_get(&now); 6630 inception = now - 3600; /* Allow for clock skew. */ 6631 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 6632 6633 /* 6634 * Spread out signatures over time if they happen to be 6635 * clumped. We don't do this for each add_sigs() call as 6636 * we still want some clustering to occur. 6637 */ 6638 isc_random_get(&jitter); 6639 expire = soaexpire - jitter % 3600; 6640 6641 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 6642 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 6643 6644 /* 6645 * We keep pulling nodes off each iterator in turn until 6646 * we have no more nodes to pull off or we reach the limits 6647 * for this quantum. 6648 */ 6649 nodes = zone->nodes; 6650 signatures = zone->signatures; 6651 LOCK_ZONE(zone); 6652 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 6653 UNLOCK_ZONE(zone); 6654 first = ISC_TRUE; 6655 6656 if (nsec3chain != NULL) 6657 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 6658 /* 6659 * Generate new NSEC3 chains first. 6660 */ 6661 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 6662 LOCK_ZONE(zone); 6663 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 6664 6665 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 6666 if (nsec3chain->done || nsec3chain->db != zone->db) { 6667 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 6668 ISC_LIST_APPEND(cleanup, nsec3chain, link); 6669 } 6670 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 6671 UNLOCK_ZONE(zone); 6672 if (ISC_LIST_TAIL(cleanup) == nsec3chain) 6673 goto next_addchain; 6674 6675 /* 6676 * Possible future db. 6677 */ 6678 if (nsec3chain->db != db) { 6679 goto next_addchain; 6680 } 6681 6682 if (NSEC3REMOVE(nsec3chain->nsec3param.flags)) 6683 goto next_addchain; 6684 6685 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 6686 6687 if (nsec3chain->delete_nsec) { 6688 delegation = ISC_FALSE; 6689 dns_dbiterator_pause(nsec3chain->dbiterator); 6690 CHECK(delete_nsec(db, version, node, name, &nsec_diff)); 6691 goto next_addnode; 6692 } 6693 /* 6694 * On the first pass we need to check if the current node 6695 * has not been obscured. 6696 */ 6697 delegation = ISC_FALSE; 6698 unsecure = ISC_FALSE; 6699 if (first) { 6700 dns_fixedname_t ffound; 6701 dns_name_t *found; 6702 dns_fixedname_init(&ffound); 6703 found = dns_fixedname_name(&ffound); 6704 result = dns_db_find(db, name, version, 6705 dns_rdatatype_soa, 6706 DNS_DBFIND_NOWILD, 0, NULL, found, 6707 NULL, NULL); 6708 if ((result == DNS_R_DELEGATION || 6709 result == DNS_R_DNAME) && 6710 !dns_name_equal(name, found)) { 6711 /* 6712 * Remember the obscuring name so that 6713 * we skip all obscured names. 6714 */ 6715 dns_name_copy(found, name, NULL); 6716 delegation = ISC_TRUE; 6717 goto next_addnode; 6718 } 6719 } 6720 6721 /* 6722 * Check to see if this is a bottom of zone node. 6723 */ 6724 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 6725 if (result == ISC_R_NOTFOUND) /* Empty node? */ 6726 goto next_addnode; 6727 if (result != ISC_R_SUCCESS) 6728 goto failure; 6729 6730 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = 6731 ISC_FALSE; 6732 for (result = dns_rdatasetiter_first(iterator); 6733 result == ISC_R_SUCCESS; 6734 result = dns_rdatasetiter_next(iterator)) { 6735 dns_rdatasetiter_current(iterator, &rdataset); 6736 INSIST(rdataset.type != dns_rdatatype_nsec3); 6737 if (rdataset.type == dns_rdatatype_soa) 6738 seen_soa = ISC_TRUE; 6739 else if (rdataset.type == dns_rdatatype_ns) 6740 seen_ns = ISC_TRUE; 6741 else if (rdataset.type == dns_rdatatype_dname) 6742 seen_dname = ISC_TRUE; 6743 else if (rdataset.type == dns_rdatatype_ds) 6744 seen_ds = ISC_TRUE; 6745 else if (rdataset.type == dns_rdatatype_nsec) 6746 seen_nsec = ISC_TRUE; 6747 dns_rdataset_disassociate(&rdataset); 6748 } 6749 dns_rdatasetiter_destroy(&iterator); 6750 /* 6751 * Is there a NSEC chain than needs to be cleaned up? 6752 */ 6753 if (seen_nsec) 6754 nsec3chain->seen_nsec = ISC_TRUE; 6755 if (seen_ns && !seen_soa && !seen_ds) 6756 unsecure = ISC_TRUE; 6757 if ((seen_ns && !seen_soa) || seen_dname) 6758 delegation = ISC_TRUE; 6759 6760 /* 6761 * Process one node. 6762 */ 6763 dns_dbiterator_pause(nsec3chain->dbiterator); 6764 result = dns_nsec3_addnsec3(db, version, name, 6765 &nsec3chain->nsec3param, 6766 zone->minimum, unsecure, 6767 &nsec3_diff); 6768 if (result != ISC_R_SUCCESS) { 6769 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6770 "dns_nsec3_addnsec3 -> %s", 6771 dns_result_totext(result)); 6772 goto failure; 6773 } 6774 6775 /* 6776 * Treat each call to dns_nsec3_addnsec3() as if it's cost is 6777 * two signatures. Additionally there will, in general, be 6778 * two signature generated below. 6779 * 6780 * If we are only changing the optout flag the cost is half 6781 * that of the cost of generating a completely new chain. 6782 */ 6783 signatures -= 4; 6784 6785 /* 6786 * Go onto next node. 6787 */ 6788 next_addnode: 6789 first = ISC_FALSE; 6790 dns_db_detachnode(db, &node); 6791 do { 6792 result = dns_dbiterator_next(nsec3chain->dbiterator); 6793 6794 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) { 6795 dns_dbiterator_pause(nsec3chain->dbiterator); 6796 CHECK(fixup_nsec3param(db, version, nsec3chain, 6797 ISC_FALSE, privatetype, 6798 ¶m_diff)); 6799 LOCK_ZONE(zone); 6800 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 6801 link); 6802 UNLOCK_ZONE(zone); 6803 ISC_LIST_APPEND(cleanup, nsec3chain, link); 6804 goto next_addchain; 6805 } 6806 if (result == ISC_R_NOMORE) { 6807 dns_dbiterator_pause(nsec3chain->dbiterator); 6808 if (nsec3chain->seen_nsec) { 6809 CHECK(fixup_nsec3param(db, version, 6810 nsec3chain, 6811 ISC_TRUE, 6812 privatetype, 6813 ¶m_diff)); 6814 nsec3chain->delete_nsec = ISC_TRUE; 6815 goto same_addchain; 6816 } 6817 CHECK(fixup_nsec3param(db, version, nsec3chain, 6818 ISC_FALSE, privatetype, 6819 ¶m_diff)); 6820 LOCK_ZONE(zone); 6821 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 6822 link); 6823 UNLOCK_ZONE(zone); 6824 ISC_LIST_APPEND(cleanup, nsec3chain, link); 6825 goto next_addchain; 6826 } else if (result != ISC_R_SUCCESS) { 6827 dns_zone_log(zone, ISC_LOG_ERROR, 6828 "zone_nsec3chain:" 6829 "dns_dbiterator_next -> %s", 6830 dns_result_totext(result)); 6831 goto failure; 6832 } else if (delegation) { 6833 dns_dbiterator_current(nsec3chain->dbiterator, 6834 &node, nextname); 6835 dns_db_detachnode(db, &node); 6836 if (!dns_name_issubdomain(nextname, name)) 6837 break; 6838 } else 6839 break; 6840 } while (1); 6841 continue; 6842 6843 same_addchain: 6844 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 6845 first = ISC_TRUE; 6846 continue; 6847 6848 next_addchain: 6849 dns_dbiterator_pause(nsec3chain->dbiterator); 6850 nsec3chain = nextnsec3chain; 6851 first = ISC_TRUE; 6852 if (nsec3chain != NULL) 6853 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 6854 } 6855 6856 /* 6857 * Process removals. 6858 */ 6859 LOCK_ZONE(zone); 6860 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 6861 UNLOCK_ZONE(zone); 6862 first = ISC_TRUE; 6863 buildnsecchain = ISC_FALSE; 6864 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 6865 LOCK_ZONE(zone); 6866 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 6867 UNLOCK_ZONE(zone); 6868 6869 if (nsec3chain->db != db) 6870 goto next_removechain; 6871 6872 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) 6873 goto next_removechain; 6874 6875 /* 6876 * Work out if we need to build a NSEC chain as a consequence 6877 * of removing this NSEC3 chain. 6878 */ 6879 if (first && !updatensec && 6880 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) 6881 { 6882 result = need_nsec_chain(db, version, 6883 &nsec3chain->nsec3param, 6884 &buildnsecchain); 6885 if (result != ISC_R_SUCCESS) { 6886 dns_zone_log(zone, ISC_LOG_ERROR, 6887 "zone_nsec3chain:" 6888 "need_nsec_chain -> %s", 6889 dns_result_totext(result)); 6890 goto failure; 6891 } 6892 } 6893 6894 if (first) 6895 dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:" 6896 "buildnsecchain = %u\n", buildnsecchain); 6897 6898 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 6899 delegation = ISC_FALSE; 6900 6901 if (!buildnsecchain) { 6902 /* 6903 * Delete the NSECPARAM record that matches this chain. 6904 */ 6905 if (first) { 6906 result = fixup_nsec3param(db, version, 6907 nsec3chain, 6908 ISC_TRUE, privatetype, 6909 ¶m_diff); 6910 if (result != ISC_R_SUCCESS) { 6911 dns_zone_log(zone, ISC_LOG_ERROR, 6912 "zone_nsec3chain:" 6913 "fixup_nsec3param -> %s", 6914 dns_result_totext(result)); 6915 goto failure; 6916 } 6917 } 6918 6919 /* 6920 * Delete the NSEC3 records. 6921 */ 6922 result = deletematchingnsec3(db, version, node, name, 6923 &nsec3chain->nsec3param, 6924 &nsec3_diff); 6925 if (result != ISC_R_SUCCESS) { 6926 dns_zone_log(zone, ISC_LOG_ERROR, 6927 "zone_nsec3chain:" 6928 "deletematchingnsec3 -> %s", 6929 dns_result_totext(result)); 6930 goto failure; 6931 } 6932 goto next_removenode; 6933 } 6934 6935 if (first) { 6936 dns_fixedname_t ffound; 6937 dns_name_t *found; 6938 dns_fixedname_init(&ffound); 6939 found = dns_fixedname_name(&ffound); 6940 result = dns_db_find(db, name, version, 6941 dns_rdatatype_soa, 6942 DNS_DBFIND_NOWILD, 0, NULL, found, 6943 NULL, NULL); 6944 if ((result == DNS_R_DELEGATION || 6945 result == DNS_R_DNAME) && 6946 !dns_name_equal(name, found)) { 6947 /* 6948 * Remember the obscuring name so that 6949 * we skip all obscured names. 6950 */ 6951 dns_name_copy(found, name, NULL); 6952 delegation = ISC_TRUE; 6953 goto next_removenode; 6954 } 6955 } 6956 6957 /* 6958 * Check to see if this is a bottom of zone node. 6959 */ 6960 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 6961 if (result == ISC_R_NOTFOUND) /* Empty node? */ 6962 goto next_removenode; 6963 if (result != ISC_R_SUCCESS) 6964 goto failure; 6965 6966 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec = 6967 seen_rr = ISC_FALSE; 6968 for (result = dns_rdatasetiter_first(iterator); 6969 result == ISC_R_SUCCESS; 6970 result = dns_rdatasetiter_next(iterator)) { 6971 dns_rdatasetiter_current(iterator, &rdataset); 6972 if (rdataset.type == dns_rdatatype_soa) 6973 seen_soa = ISC_TRUE; 6974 else if (rdataset.type == dns_rdatatype_ns) 6975 seen_ns = ISC_TRUE; 6976 else if (rdataset.type == dns_rdatatype_dname) 6977 seen_dname = ISC_TRUE; 6978 else if (rdataset.type == dns_rdatatype_nsec) 6979 seen_nsec = ISC_TRUE; 6980 else if (rdataset.type == dns_rdatatype_nsec3) 6981 seen_nsec3 = ISC_TRUE; 6982 if (rdataset.type != dns_rdatatype_rrsig) 6983 seen_rr = ISC_TRUE; 6984 dns_rdataset_disassociate(&rdataset); 6985 } 6986 dns_rdatasetiter_destroy(&iterator); 6987 6988 if (!seen_rr || seen_nsec3 || seen_nsec) 6989 goto next_removenode; 6990 if ((seen_ns && !seen_soa) || seen_dname) 6991 delegation = ISC_TRUE; 6992 6993 /* 6994 * Add a NSEC record except at the origin. 6995 */ 6996 if (!dns_name_equal(name, dns_db_origin(db))) { 6997 dns_dbiterator_pause(nsec3chain->dbiterator); 6998 CHECK(add_nsec(db, version, name, node, zone->minimum, 6999 delegation, &nsec_diff)); 7000 } 7001 7002 next_removenode: 7003 first = ISC_FALSE; 7004 dns_db_detachnode(db, &node); 7005 do { 7006 result = dns_dbiterator_next(nsec3chain->dbiterator); 7007 if (result == ISC_R_NOMORE && buildnsecchain) { 7008 /* 7009 * The NSEC chain should now be built. 7010 * We can now remove the NSEC3 chain. 7011 */ 7012 updatensec = ISC_TRUE; 7013 goto same_removechain; 7014 } 7015 if (result == ISC_R_NOMORE) { 7016 LOCK_ZONE(zone); 7017 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 7018 link); 7019 UNLOCK_ZONE(zone); 7020 ISC_LIST_APPEND(cleanup, nsec3chain, link); 7021 dns_dbiterator_pause(nsec3chain->dbiterator); 7022 result = fixup_nsec3param(db, version, 7023 nsec3chain, ISC_FALSE, 7024 privatetype, 7025 ¶m_diff); 7026 if (result != ISC_R_SUCCESS) { 7027 dns_zone_log(zone, ISC_LOG_ERROR, 7028 "zone_nsec3chain:" 7029 "fixup_nsec3param -> %s", 7030 dns_result_totext(result)); 7031 goto failure; 7032 } 7033 goto next_removechain; 7034 } else if (result != ISC_R_SUCCESS) { 7035 dns_zone_log(zone, ISC_LOG_ERROR, 7036 "zone_nsec3chain:" 7037 "dns_dbiterator_next -> %s", 7038 dns_result_totext(result)); 7039 goto failure; 7040 } else if (delegation) { 7041 dns_dbiterator_current(nsec3chain->dbiterator, 7042 &node, nextname); 7043 dns_db_detachnode(db, &node); 7044 if (!dns_name_issubdomain(nextname, name)) 7045 break; 7046 } else 7047 break; 7048 } while (1); 7049 continue; 7050 7051 same_removechain: 7052 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 7053 buildnsecchain = ISC_FALSE; 7054 first = ISC_TRUE; 7055 continue; 7056 7057 next_removechain: 7058 dns_dbiterator_pause(nsec3chain->dbiterator); 7059 nsec3chain = nextnsec3chain; 7060 first = ISC_TRUE; 7061 } 7062 7063 /* 7064 * We may need to update the NSEC/NSEC3 records for the zone apex. 7065 */ 7066 if (!ISC_LIST_EMPTY(param_diff.tuples)) { 7067 isc_boolean_t rebuild_nsec = ISC_FALSE, 7068 rebuild_nsec3 = ISC_FALSE; 7069 result = dns_db_getoriginnode(db, &node); 7070 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7071 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 7072 if (result != ISC_R_SUCCESS) { 7073 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7074 "dns_db_allrdatasets -> %s", 7075 dns_result_totext(result)); 7076 goto failure; 7077 } 7078 for (result = dns_rdatasetiter_first(iterator); 7079 result == ISC_R_SUCCESS; 7080 result = dns_rdatasetiter_next(iterator)) { 7081 dns_rdatasetiter_current(iterator, &rdataset); 7082 if (rdataset.type == dns_rdatatype_nsec) 7083 rebuild_nsec = ISC_TRUE; 7084 if (rdataset.type == dns_rdatatype_nsec3param) 7085 rebuild_nsec3 = ISC_TRUE; 7086 dns_rdataset_disassociate(&rdataset); 7087 } 7088 dns_rdatasetiter_destroy(&iterator); 7089 dns_db_detachnode(db, &node); 7090 7091 if (rebuild_nsec) { 7092 if (nsec3chain != NULL) 7093 dns_dbiterator_pause(nsec3chain->dbiterator); 7094 7095 result = updatesecure(db, version, &zone->origin, 7096 zone->minimum, ISC_TRUE, 7097 &nsec_diff); 7098 if (result != ISC_R_SUCCESS) { 7099 dns_zone_log(zone, ISC_LOG_ERROR, 7100 "zone_nsec3chain:" 7101 "updatesecure -> %s", 7102 dns_result_totext(result)); 7103 goto failure; 7104 } 7105 } 7106 7107 if (rebuild_nsec3) { 7108 if (nsec3chain != NULL) 7109 dns_dbiterator_pause(nsec3chain->dbiterator); 7110 7111 result = dns_nsec3_addnsec3s(db, version, 7112 dns_db_origin(db), 7113 zone->minimum, ISC_FALSE, 7114 &nsec3_diff); 7115 if (result != ISC_R_SUCCESS) { 7116 dns_zone_log(zone, ISC_LOG_ERROR, 7117 "zone_nsec3chain:" 7118 "dns_nsec3_addnsec3s -> %s", 7119 dns_result_totext(result)); 7120 goto failure; 7121 } 7122 } 7123 } 7124 7125 if (nsec3chain != NULL) 7126 dns_dbiterator_pause(nsec3chain->dbiterator); 7127 7128 /* 7129 * Add / update signatures for the NSEC3 records. 7130 */ 7131 if (nsec3chain != NULL) 7132 dns_dbiterator_pause(nsec3chain->dbiterator); 7133 result = update_sigs(&nsec3_diff, db, version, zone_keys, 7134 nkeys, zone, inception, expire, now, 7135 check_ksk, keyset_kskonly, &zonediff); 7136 if (result != ISC_R_SUCCESS) { 7137 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7138 "update_sigs -> %s", dns_result_totext(result)); 7139 goto failure; 7140 } 7141 7142 /* 7143 * We have changed the NSEC3PARAM or private RRsets 7144 * above so we need to update the signatures. 7145 */ 7146 result = update_sigs(¶m_diff, db, version, zone_keys, 7147 nkeys, zone, inception, expire, now, 7148 check_ksk, keyset_kskonly, &zonediff); 7149 if (result != ISC_R_SUCCESS) { 7150 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7151 "update_sigs -> %s", dns_result_totext(result)); 7152 goto failure; 7153 } 7154 7155 if (updatensec) { 7156 result = updatesecure(db, version, &zone->origin, 7157 zone->minimum, ISC_FALSE, &nsec_diff); 7158 if (result != ISC_R_SUCCESS) { 7159 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7160 "updatesecure -> %s", 7161 dns_result_totext(result)); 7162 goto failure; 7163 } 7164 } 7165 7166 result = update_sigs(&nsec_diff, db, version, zone_keys, 7167 nkeys, zone, inception, expire, now, 7168 check_ksk, keyset_kskonly, &zonediff); 7169 if (result != ISC_R_SUCCESS) { 7170 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7171 "update_sigs -> %s", dns_result_totext(result)); 7172 goto failure; 7173 } 7174 7175 /* 7176 * If we made no effective changes to the zone then we can just 7177 * cleanup otherwise we need to increment the serial. 7178 */ 7179 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 7180 /* 7181 * No need to call dns_db_closeversion() here as it is 7182 * called with commit = ISC_TRUE below. 7183 */ 7184 goto done; 7185 } 7186 7187 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 7188 &zonediff, zone_keys, nkeys, now, ISC_FALSE); 7189 if (result != ISC_R_SUCCESS) { 7190 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7191 "del_sigs -> %s", dns_result_totext(result)); 7192 goto failure; 7193 } 7194 7195 result = update_soa_serial(db, version, zonediff.diff, zone->mctx, 7196 zone->updatemethod); 7197 if (result != ISC_R_SUCCESS) { 7198 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7199 "update_soa_serial -> %s", 7200 dns_result_totext(result)); 7201 goto failure; 7202 } 7203 7204 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, 7205 zonediff.diff, zone_keys, nkeys, zone->mctx, 7206 inception, soaexpire, check_ksk, keyset_kskonly); 7207 if (result != ISC_R_SUCCESS) { 7208 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7209 "add_sigs -> %s", dns_result_totext(result)); 7210 goto failure; 7211 } 7212 7213 /* Write changes to journal file. */ 7214 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain")); 7215 7216 LOCK_ZONE(zone); 7217 zone_needdump(zone, DNS_DUMP_DELAY); 7218 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 7219 UNLOCK_ZONE(zone); 7220 7221 done: 7222 /* 7223 * Pause all iterators so that dns_db_closeversion() can succeed. 7224 */ 7225 LOCK_ZONE(zone); 7226 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 7227 nsec3chain != NULL; 7228 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 7229 dns_dbiterator_pause(nsec3chain->dbiterator); 7230 UNLOCK_ZONE(zone); 7231 7232 /* 7233 * Everything has succeeded. Commit the changes. 7234 * Unconditionally commit as zonediff.offline not checked above. 7235 */ 7236 dns_db_closeversion(db, &version, ISC_TRUE); 7237 7238 /* 7239 * Everything succeeded so we can clean these up now. 7240 */ 7241 nsec3chain = ISC_LIST_HEAD(cleanup); 7242 while (nsec3chain != NULL) { 7243 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 7244 dns_db_detach(&nsec3chain->db); 7245 dns_dbiterator_destroy(&nsec3chain->dbiterator); 7246 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 7247 nsec3chain = ISC_LIST_HEAD(cleanup); 7248 } 7249 7250 set_resigntime(zone); 7251 7252 failure: 7253 if (result != ISC_R_SUCCESS) 7254 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s", 7255 dns_result_totext(result)); 7256 /* 7257 * On error roll back the current nsec3chain. 7258 */ 7259 if (result != ISC_R_SUCCESS && nsec3chain != NULL) { 7260 if (nsec3chain->done) { 7261 dns_db_detach(&nsec3chain->db); 7262 dns_dbiterator_destroy(&nsec3chain->dbiterator); 7263 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 7264 } else { 7265 result = dns_dbiterator_first(nsec3chain->dbiterator); 7266 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7267 dns_dbiterator_pause(nsec3chain->dbiterator); 7268 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 7269 } 7270 } 7271 7272 /* 7273 * Rollback the cleanup list. 7274 */ 7275 nsec3chain = ISC_LIST_TAIL(cleanup); 7276 while (nsec3chain != NULL) { 7277 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 7278 if (nsec3chain->done) { 7279 dns_db_detach(&nsec3chain->db); 7280 dns_dbiterator_destroy(&nsec3chain->dbiterator); 7281 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 7282 } else { 7283 LOCK_ZONE(zone); 7284 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link); 7285 UNLOCK_ZONE(zone); 7286 result = dns_dbiterator_first(nsec3chain->dbiterator); 7287 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7288 dns_dbiterator_pause(nsec3chain->dbiterator); 7289 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 7290 } 7291 nsec3chain = ISC_LIST_TAIL(cleanup); 7292 } 7293 7294 LOCK_ZONE(zone); 7295 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 7296 nsec3chain != NULL; 7297 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 7298 dns_dbiterator_pause(nsec3chain->dbiterator); 7299 UNLOCK_ZONE(zone); 7300 7301 dns_diff_clear(¶m_diff); 7302 dns_diff_clear(&nsec3_diff); 7303 dns_diff_clear(&nsec_diff); 7304 dns_diff_clear(&_sig_diff); 7305 7306 if (iterator != NULL) 7307 dns_rdatasetiter_destroy(&iterator); 7308 7309 for (i = 0; i < nkeys; i++) 7310 dst_key_free(&zone_keys[i]); 7311 7312 if (node != NULL) 7313 dns_db_detachnode(db, &node); 7314 if (version != NULL) { 7315 dns_db_closeversion(db, &version, ISC_FALSE); 7316 dns_db_detach(&db); 7317 } else if (db != NULL) 7318 dns_db_detach(&db); 7319 7320 LOCK_ZONE(zone); 7321 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) { 7322 isc_interval_t i; 7323 if (zone->update_disabled || result != ISC_R_SUCCESS) 7324 isc_interval_set(&i, 60, 0); /* 1 minute */ 7325 else 7326 isc_interval_set(&i, 0, 10000000); /* 10 ms */ 7327 isc_time_nowplusinterval(&zone->nsec3chaintime, &i); 7328 } else 7329 isc_time_settoepoch(&zone->nsec3chaintime); 7330 UNLOCK_ZONE(zone); 7331} 7332 7333static isc_result_t 7334del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 7335 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm, 7336 isc_uint16_t keyid, dns_diff_t *diff) 7337{ 7338 dns_rdata_rrsig_t rrsig; 7339 dns_rdataset_t rdataset; 7340 dns_rdatasetiter_t *iterator = NULL; 7341 isc_result_t result; 7342 7343 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 7344 if (result != ISC_R_SUCCESS) { 7345 if (result == ISC_R_NOTFOUND) 7346 result = ISC_R_SUCCESS; 7347 return (result); 7348 } 7349 7350 dns_rdataset_init(&rdataset); 7351 for (result = dns_rdatasetiter_first(iterator); 7352 result == ISC_R_SUCCESS; 7353 result = dns_rdatasetiter_next(iterator)) { 7354 dns_rdatasetiter_current(iterator, &rdataset); 7355 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) { 7356 for (result = dns_rdataset_first(&rdataset); 7357 result == ISC_R_SUCCESS; 7358 result = dns_rdataset_next(&rdataset)) { 7359 dns_rdata_t rdata = DNS_RDATA_INIT; 7360 dns_rdataset_current(&rdataset, &rdata); 7361 CHECK(update_one_rr(db, version, diff, 7362 DNS_DIFFOP_DEL, name, 7363 rdataset.ttl, &rdata)); 7364 } 7365 if (result != ISC_R_NOMORE) 7366 goto failure; 7367 dns_rdataset_disassociate(&rdataset); 7368 continue; 7369 } 7370 if (rdataset.type != dns_rdatatype_rrsig) { 7371 dns_rdataset_disassociate(&rdataset); 7372 continue; 7373 } 7374 for (result = dns_rdataset_first(&rdataset); 7375 result == ISC_R_SUCCESS; 7376 result = dns_rdataset_next(&rdataset)) { 7377 dns_rdata_t rdata = DNS_RDATA_INIT; 7378 dns_rdataset_current(&rdataset, &rdata); 7379 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL)); 7380 if (rrsig.algorithm != algorithm || 7381 rrsig.keyid != keyid) 7382 continue; 7383 CHECK(update_one_rr(db, version, diff, 7384 DNS_DIFFOP_DELRESIGN, name, 7385 rdataset.ttl, &rdata)); 7386 } 7387 dns_rdataset_disassociate(&rdataset); 7388 if (result != ISC_R_NOMORE) 7389 break; 7390 } 7391 if (result == ISC_R_NOMORE) 7392 result = ISC_R_SUCCESS; 7393 failure: 7394 if (dns_rdataset_isassociated(&rdataset)) 7395 dns_rdataset_disassociate(&rdataset); 7396 dns_rdatasetiter_destroy(&iterator); 7397 return (result); 7398} 7399 7400/* 7401 * Incrementally sign the zone using the keys requested. 7402 * Builds the NSEC chain if required. 7403 */ 7404static void 7405zone_sign(dns_zone_t *zone) { 7406 const char *me = "zone_sign"; 7407 dns_db_t *db = NULL; 7408 dns_dbnode_t *node = NULL; 7409 dns_dbversion_t *version = NULL; 7410 dns_diff_t _sig_diff; 7411 dns_diff_t post_diff; 7412 zonediff_t zonediff; 7413 dns_fixedname_t fixed; 7414 dns_fixedname_t nextfixed; 7415 dns_name_t *name, *nextname; 7416 dns_rdataset_t rdataset; 7417 dns_signing_t *signing, *nextsigning; 7418 dns_signinglist_t cleanup; 7419 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 7420 isc_int32_t signatures; 7421 isc_boolean_t check_ksk, keyset_kskonly, is_ksk; 7422 isc_boolean_t commit = ISC_FALSE; 7423 isc_boolean_t delegation; 7424 isc_boolean_t build_nsec = ISC_FALSE; 7425 isc_boolean_t build_nsec3 = ISC_FALSE; 7426 isc_boolean_t first; 7427 isc_result_t result; 7428 isc_stdtime_t now, inception, soaexpire, expire; 7429 isc_uint32_t jitter; 7430 unsigned int i, j; 7431 unsigned int nkeys = 0; 7432 isc_uint32_t nodes; 7433 7434 ENTER; 7435 7436 dns_rdataset_init(&rdataset); 7437 dns_fixedname_init(&fixed); 7438 name = dns_fixedname_name(&fixed); 7439 dns_fixedname_init(&nextfixed); 7440 nextname = dns_fixedname_name(&nextfixed); 7441 dns_diff_init(zone->mctx, &_sig_diff); 7442 dns_diff_init(zone->mctx, &post_diff); 7443 zonediff_init(&zonediff, &_sig_diff); 7444 ISC_LIST_INIT(cleanup); 7445 7446 /* 7447 * Updates are disabled. Pause for 5 minutes. 7448 */ 7449 if (zone->update_disabled) { 7450 result = ISC_R_FAILURE; 7451 goto failure; 7452 } 7453 7454 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 7455 if (zone->db != NULL) 7456 dns_db_attach(zone->db, &db); 7457 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 7458 if (db == NULL) { 7459 result = ISC_R_FAILURE; 7460 goto failure; 7461 } 7462 7463 result = dns_db_newversion(db, &version); 7464 if (result != ISC_R_SUCCESS) { 7465 dns_zone_log(zone, ISC_LOG_ERROR, 7466 "zone_sign:dns_db_newversion -> %s", 7467 dns_result_totext(result)); 7468 goto failure; 7469 } 7470 7471 result = find_zone_keys(zone, db, version, zone->mctx, 7472 DNS_MAXZONEKEYS, zone_keys, &nkeys); 7473 if (result != ISC_R_SUCCESS) { 7474 dns_zone_log(zone, ISC_LOG_ERROR, 7475 "zone_sign:find_zone_keys -> %s", 7476 dns_result_totext(result)); 7477 goto failure; 7478 } 7479 7480 isc_stdtime_get(&now); 7481 inception = now - 3600; /* Allow for clock skew. */ 7482 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 7483 7484 /* 7485 * Spread out signatures over time if they happen to be 7486 * clumped. We don't do this for each add_sigs() call as 7487 * we still want some clustering to occur. 7488 */ 7489 isc_random_get(&jitter); 7490 expire = soaexpire - jitter % 3600; 7491 7492 /* 7493 * We keep pulling nodes off each iterator in turn until 7494 * we have no more nodes to pull off or we reach the limits 7495 * for this quantum. 7496 */ 7497 nodes = zone->nodes; 7498 signatures = zone->signatures; 7499 signing = ISC_LIST_HEAD(zone->signing); 7500 first = ISC_TRUE; 7501 7502 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 7503 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 7504 7505 /* Determine which type of chain to build */ 7506 CHECK(dns_private_chains(db, version, zone->privatetype, 7507 &build_nsec, &build_nsec3)); 7508 7509 /* If neither chain is found, default to NSEC */ 7510 if (!build_nsec && !build_nsec3) 7511 build_nsec = ISC_TRUE; 7512 7513 while (signing != NULL && nodes-- > 0 && signatures > 0) { 7514 nextsigning = ISC_LIST_NEXT(signing, link); 7515 7516 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 7517 if (signing->done || signing->db != zone->db) { 7518 /* 7519 * The zone has been reloaded. We will have 7520 * created new signings as part of the reload 7521 * process so we can destroy this one. 7522 */ 7523 ISC_LIST_UNLINK(zone->signing, signing, link); 7524 ISC_LIST_APPEND(cleanup, signing, link); 7525 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 7526 goto next_signing; 7527 } 7528 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 7529 7530 if (signing->db != db) 7531 goto next_signing; 7532 7533 delegation = ISC_FALSE; 7534 7535 if (first && signing->delete) { 7536 /* 7537 * Remove the key we are deleting from consideration. 7538 */ 7539 for (i = 0, j = 0; i < nkeys; i++) { 7540 /* 7541 * Find the key we want to remove. 7542 */ 7543 if (ALG(zone_keys[i]) == signing->algorithm && 7544 dst_key_id(zone_keys[i]) == signing->keyid) 7545 { 7546 if (KSK(zone_keys[i])) 7547 dst_key_free(&zone_keys[i]); 7548 continue; 7549 } 7550 zone_keys[j] = zone_keys[i]; 7551 j++; 7552 } 7553 nkeys = j; 7554 } 7555 7556 dns_dbiterator_current(signing->dbiterator, &node, name); 7557 7558 if (signing->delete) { 7559 dns_dbiterator_pause(signing->dbiterator); 7560 CHECK(del_sig(db, version, name, node, nkeys, 7561 signing->algorithm, signing->keyid, 7562 zonediff.diff)); 7563 } 7564 7565 /* 7566 * On the first pass we need to check if the current node 7567 * has not been obscured. 7568 */ 7569 if (first) { 7570 dns_fixedname_t ffound; 7571 dns_name_t *found; 7572 dns_fixedname_init(&ffound); 7573 found = dns_fixedname_name(&ffound); 7574 result = dns_db_find(db, name, version, 7575 dns_rdatatype_soa, 7576 DNS_DBFIND_NOWILD, 0, NULL, found, 7577 NULL, NULL); 7578 if ((result == DNS_R_DELEGATION || 7579 result == DNS_R_DNAME) && 7580 !dns_name_equal(name, found)) { 7581 /* 7582 * Remember the obscuring name so that 7583 * we skip all obscured names. 7584 */ 7585 dns_name_copy(found, name, NULL); 7586 delegation = ISC_TRUE; 7587 goto next_node; 7588 } 7589 } 7590 7591 /* 7592 * Process one node. 7593 */ 7594 dns_dbiterator_pause(signing->dbiterator); 7595 for (i = 0; i < nkeys; i++) { 7596 isc_boolean_t both = ISC_FALSE; 7597 7598 /* 7599 * Find the keys we want to sign with. 7600 */ 7601 if (!dst_key_isprivate(zone_keys[i])) 7602 continue; 7603 7604 /* 7605 * When adding look for the specific key. 7606 */ 7607 if (!signing->delete && 7608 (dst_key_alg(zone_keys[i]) != signing->algorithm || 7609 dst_key_id(zone_keys[i]) != signing->keyid)) 7610 continue; 7611 7612 /* 7613 * When deleting make sure we are properly signed 7614 * with the algorithm that was being removed. 7615 */ 7616 if (signing->delete && 7617 ALG(zone_keys[i]) != signing->algorithm) 7618 continue; 7619 7620 /* 7621 * Do we do KSK processing? 7622 */ 7623 if (check_ksk && !REVOKE(zone_keys[i])) { 7624 isc_boolean_t have_ksk, have_nonksk; 7625 if (KSK(zone_keys[i])) { 7626 have_ksk = ISC_TRUE; 7627 have_nonksk = ISC_FALSE; 7628 } else { 7629 have_ksk = ISC_FALSE; 7630 have_nonksk = ISC_TRUE; 7631 } 7632 for (j = 0; j < nkeys; j++) { 7633 if (j == i || 7634 ALG(zone_keys[i]) != 7635 ALG(zone_keys[j])) 7636 continue; 7637 if (REVOKE(zone_keys[j])) 7638 continue; 7639 if (KSK(zone_keys[j])) 7640 have_ksk = ISC_TRUE; 7641 else 7642 have_nonksk = ISC_TRUE; 7643 both = have_ksk && have_nonksk; 7644 if (both) 7645 break; 7646 } 7647 } 7648 if (both || REVOKE(zone_keys[i])) 7649 is_ksk = KSK(zone_keys[i]); 7650 else 7651 is_ksk = ISC_FALSE; 7652 7653 CHECK(sign_a_node(db, name, node, version, build_nsec3, 7654 build_nsec, zone_keys[i], inception, 7655 expire, zone->minimum, is_ksk, 7656 ISC_TF(both && keyset_kskonly), 7657 &delegation, zonediff.diff, 7658 &signatures, zone->mctx)); 7659 /* 7660 * If we are adding we are done. Look for other keys 7661 * of the same algorithm if deleting. 7662 */ 7663 if (!signing->delete) 7664 break; 7665 } 7666 7667 /* 7668 * Go onto next node. 7669 */ 7670 next_node: 7671 first = ISC_FALSE; 7672 dns_db_detachnode(db, &node); 7673 do { 7674 result = dns_dbiterator_next(signing->dbiterator); 7675 if (result == ISC_R_NOMORE) { 7676 ISC_LIST_UNLINK(zone->signing, signing, link); 7677 ISC_LIST_APPEND(cleanup, signing, link); 7678 dns_dbiterator_pause(signing->dbiterator); 7679 if (nkeys != 0 && build_nsec) { 7680 /* 7681 * We have finished regenerating the 7682 * zone with a zone signing key. 7683 * The NSEC chain is now complete and 7684 * there is a full set of signatures 7685 * for the zone. We can now clear the 7686 * OPT bit from the NSEC record. 7687 */ 7688 result = updatesecure(db, version, 7689 &zone->origin, 7690 zone->minimum, 7691 ISC_FALSE, 7692 &post_diff); 7693 if (result != ISC_R_SUCCESS) { 7694 dns_zone_log(zone, 7695 ISC_LOG_ERROR, 7696 "updatesecure -> %s", 7697 dns_result_totext(result)); 7698 goto failure; 7699 } 7700 } 7701 result = updatesignwithkey(zone, signing, 7702 version, 7703 build_nsec3, 7704 zone->minimum, 7705 &post_diff); 7706 if (result != ISC_R_SUCCESS) { 7707 dns_zone_log(zone, ISC_LOG_ERROR, 7708 "updatesignwithkey -> %s", 7709 dns_result_totext(result)); 7710 goto failure; 7711 } 7712 build_nsec = ISC_FALSE; 7713 goto next_signing; 7714 } else if (result != ISC_R_SUCCESS) { 7715 dns_zone_log(zone, ISC_LOG_ERROR, 7716 "zone_sign:dns_dbiterator_next -> %s", 7717 dns_result_totext(result)); 7718 goto failure; 7719 } else if (delegation) { 7720 dns_dbiterator_current(signing->dbiterator, 7721 &node, nextname); 7722 dns_db_detachnode(db, &node); 7723 if (!dns_name_issubdomain(nextname, name)) 7724 break; 7725 } else 7726 break; 7727 } while (1); 7728 continue; 7729 7730 next_signing: 7731 dns_dbiterator_pause(signing->dbiterator); 7732 signing = nextsigning; 7733 first = ISC_TRUE; 7734 } 7735 7736 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) { 7737 result = update_sigs(&post_diff, db, version, zone_keys, 7738 nkeys, zone, inception, expire, now, 7739 check_ksk, keyset_kskonly, &zonediff); 7740 if (result != ISC_R_SUCCESS) { 7741 dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:" 7742 "update_sigs -> %s", 7743 dns_result_totext(result)); 7744 goto failure; 7745 } 7746 } 7747 7748 /* 7749 * Have we changed anything? 7750 */ 7751 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 7752 if (zonediff.offline) 7753 commit = ISC_TRUE; 7754 result = ISC_R_SUCCESS; 7755 goto pauseall; 7756 } 7757 7758 commit = ISC_TRUE; 7759 7760 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 7761 &zonediff, zone_keys, nkeys, now, ISC_FALSE); 7762 if (result != ISC_R_SUCCESS) { 7763 dns_zone_log(zone, ISC_LOG_ERROR, 7764 "zone_sign:del_sigs -> %s", 7765 dns_result_totext(result)); 7766 goto failure; 7767 } 7768 7769 result = update_soa_serial(db, version, zonediff.diff, zone->mctx, 7770 zone->updatemethod); 7771 if (result != ISC_R_SUCCESS) { 7772 dns_zone_log(zone, ISC_LOG_ERROR, 7773 "zone_sign:update_soa_serial -> %s", 7774 dns_result_totext(result)); 7775 goto failure; 7776 } 7777 7778 /* 7779 * Generate maximum life time signatures so that the above loop 7780 * termination is sensible. 7781 */ 7782 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, 7783 zonediff.diff, zone_keys, nkeys, zone->mctx, 7784 inception, soaexpire, check_ksk, keyset_kskonly); 7785 if (result != ISC_R_SUCCESS) { 7786 dns_zone_log(zone, ISC_LOG_ERROR, 7787 "zone_sign:add_sigs -> %s", 7788 dns_result_totext(result)); 7789 goto failure; 7790 } 7791 7792 /* 7793 * Write changes to journal file. 7794 */ 7795 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign")); 7796 7797 pauseall: 7798 /* 7799 * Pause all iterators so that dns_db_closeversion() can succeed. 7800 */ 7801 for (signing = ISC_LIST_HEAD(zone->signing); 7802 signing != NULL; 7803 signing = ISC_LIST_NEXT(signing, link)) 7804 dns_dbiterator_pause(signing->dbiterator); 7805 7806 for (signing = ISC_LIST_HEAD(cleanup); 7807 signing != NULL; 7808 signing = ISC_LIST_NEXT(signing, link)) 7809 dns_dbiterator_pause(signing->dbiterator); 7810 7811 /* 7812 * Everything has succeeded. Commit the changes. 7813 */ 7814 dns_db_closeversion(db, &version, commit); 7815 7816 /* 7817 * Everything succeeded so we can clean these up now. 7818 */ 7819 signing = ISC_LIST_HEAD(cleanup); 7820 while (signing != NULL) { 7821 ISC_LIST_UNLINK(cleanup, signing, link); 7822 dns_db_detach(&signing->db); 7823 dns_dbiterator_destroy(&signing->dbiterator); 7824 isc_mem_put(zone->mctx, signing, sizeof *signing); 7825 signing = ISC_LIST_HEAD(cleanup); 7826 } 7827 7828 set_resigntime(zone); 7829 7830 if (commit) { 7831 LOCK_ZONE(zone); 7832 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 7833 zone_needdump(zone, DNS_DUMP_DELAY); 7834 UNLOCK_ZONE(zone); 7835 } 7836 7837 failure: 7838 /* 7839 * Rollback the cleanup list. 7840 */ 7841 signing = ISC_LIST_HEAD(cleanup); 7842 while (signing != NULL) { 7843 ISC_LIST_UNLINK(cleanup, signing, link); 7844 ISC_LIST_PREPEND(zone->signing, signing, link); 7845 dns_dbiterator_first(signing->dbiterator); 7846 dns_dbiterator_pause(signing->dbiterator); 7847 signing = ISC_LIST_HEAD(cleanup); 7848 } 7849 7850 for (signing = ISC_LIST_HEAD(zone->signing); 7851 signing != NULL; 7852 signing = ISC_LIST_NEXT(signing, link)) 7853 dns_dbiterator_pause(signing->dbiterator); 7854 7855 dns_diff_clear(&_sig_diff); 7856 7857 for (i = 0; i < nkeys; i++) 7858 dst_key_free(&zone_keys[i]); 7859 7860 if (node != NULL) 7861 dns_db_detachnode(db, &node); 7862 7863 if (version != NULL) { 7864 dns_db_closeversion(db, &version, ISC_FALSE); 7865 dns_db_detach(&db); 7866 } else if (db != NULL) 7867 dns_db_detach(&db); 7868 7869 if (ISC_LIST_HEAD(zone->signing) != NULL) { 7870 isc_interval_t i; 7871 if (zone->update_disabled || result != ISC_R_SUCCESS) 7872 isc_interval_set(&i, 60, 0); /* 1 minute */ 7873 else 7874 isc_interval_set(&i, 0, 10000000); /* 10 ms */ 7875 isc_time_nowplusinterval(&zone->signingtime, &i); 7876 } else 7877 isc_time_settoepoch(&zone->signingtime); 7878} 7879 7880static isc_result_t 7881normalize_key(dns_rdata_t *rr, dns_rdata_t *target, 7882 unsigned char *data, int size) { 7883 dns_rdata_dnskey_t dnskey; 7884 dns_rdata_keydata_t keydata; 7885 isc_buffer_t buf; 7886 isc_result_t result; 7887 7888 dns_rdata_reset(target); 7889 isc_buffer_init(&buf, data, size); 7890 7891 switch (rr->type) { 7892 case dns_rdatatype_dnskey: 7893 result = dns_rdata_tostruct(rr, &dnskey, NULL); 7894 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7895 dnskey.flags &= ~DNS_KEYFLAG_REVOKE; 7896 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 7897 &dnskey, &buf); 7898 break; 7899 case dns_rdatatype_keydata: 7900 result = dns_rdata_tostruct(rr, &keydata, NULL); 7901 if (result == ISC_R_UNEXPECTEDEND) 7902 return (result); 7903 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7904 dns_keydata_todnskey(&keydata, &dnskey, NULL); 7905 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 7906 &dnskey, &buf); 7907 break; 7908 default: 7909 INSIST(0); 7910 } 7911 return (ISC_R_SUCCESS); 7912} 7913 7914/* 7915 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or 7916 * a KEYDATA rdataset from the key zone. 7917 * 7918 * 'rr' contains either a DNSKEY record, or a KEYDATA record 7919 * 7920 * After normalizing keys to the same format (DNSKEY, with revoke bit 7921 * cleared), return ISC_TRUE if a key that matches 'rr' is found in 7922 * 'rdset', or ISC_FALSE if not. 7923 */ 7924 7925static isc_boolean_t 7926matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) { 7927 unsigned char data1[4096], data2[4096]; 7928 dns_rdata_t rdata, rdata1, rdata2; 7929 isc_result_t result; 7930 7931 dns_rdata_init(&rdata); 7932 dns_rdata_init(&rdata1); 7933 dns_rdata_init(&rdata2); 7934 7935 result = normalize_key(rr, &rdata1, data1, sizeof(data1)); 7936 if (result != ISC_R_SUCCESS) 7937 return (ISC_FALSE); 7938 7939 for (result = dns_rdataset_first(rdset); 7940 result == ISC_R_SUCCESS; 7941 result = dns_rdataset_next(rdset)) { 7942 dns_rdata_reset(&rdata); 7943 dns_rdataset_current(rdset, &rdata); 7944 result = normalize_key(&rdata, &rdata2, data2, sizeof(data2)); 7945 if (result != ISC_R_SUCCESS) 7946 continue; 7947 if (dns_rdata_compare(&rdata1, &rdata2) == 0) 7948 return (ISC_TRUE); 7949 } 7950 7951 return (ISC_FALSE); 7952} 7953 7954/* 7955 * Calculate the refresh interval for a keydata zone, per 7956 * RFC5011: MAX(1 hr, 7957 * MIN(15 days, 7958 * 1/2 * OrigTTL, 7959 * 1/2 * RRSigExpirationInterval)) 7960 * or for retries: MAX(1 hr, 7961 * MIN(1 day, 7962 * 1/10 * OrigTTL, 7963 * 1/10 * RRSigExpirationInterval)) 7964 */ 7965static inline isc_stdtime_t 7966refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) { 7967 isc_result_t result; 7968 isc_uint32_t t; 7969 dns_rdataset_t *rdset; 7970 dns_rdata_t sigrr = DNS_RDATA_INIT; 7971 dns_rdata_sig_t sig; 7972 isc_stdtime_t now; 7973 7974 isc_stdtime_get(&now); 7975 7976 if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) 7977 rdset = &kfetch->dnskeysigset; 7978 else 7979 return (now + HOUR); 7980 7981 result = dns_rdataset_first(rdset); 7982 if (result != ISC_R_SUCCESS) 7983 return (now + HOUR); 7984 7985 dns_rdataset_current(rdset, &sigrr); 7986 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 7987 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7988 7989 if (!retry) { 7990 t = sig.originalttl / 2; 7991 7992 if (isc_serial_gt(sig.timeexpire, now)) { 7993 isc_uint32_t exp = (sig.timeexpire - now) / 2; 7994 if (t > exp) 7995 t = exp; 7996 } 7997 7998 if (t > (15*DAY)) 7999 t = (15*DAY); 8000 8001 if (t < HOUR) 8002 t = HOUR; 8003 } else { 8004 t = sig.originalttl / 10; 8005 8006 if (isc_serial_gt(sig.timeexpire, now)) { 8007 isc_uint32_t exp = (sig.timeexpire - now) / 10; 8008 if (t > exp) 8009 t = exp; 8010 } 8011 8012 if (t > DAY) 8013 t = DAY; 8014 8015 if (t < HOUR) 8016 t = HOUR; 8017 } 8018 8019 return (now + t); 8020} 8021 8022/* 8023 * This routine is called when no changes are needed in a KEYDATA 8024 * record except to simply update the refresh timer. Caller should 8025 * hold zone lock. 8026 */ 8027static isc_result_t 8028minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) 8029{ 8030 isc_result_t result; 8031 isc_buffer_t keyb; 8032 unsigned char key_buf[4096]; 8033 dns_rdata_t rdata = DNS_RDATA_INIT; 8034 dns_rdata_keydata_t keydata; 8035 dns_name_t *name; 8036 dns_zone_t *zone = kfetch->zone; 8037 isc_stdtime_t now; 8038 8039 name = dns_fixedname_name(&kfetch->name); 8040 isc_stdtime_get(&now); 8041 8042 for (result = dns_rdataset_first(&kfetch->keydataset); 8043 result == ISC_R_SUCCESS; 8044 result = dns_rdataset_next(&kfetch->keydataset)) { 8045 dns_rdata_reset(&rdata); 8046 dns_rdataset_current(&kfetch->keydataset, &rdata); 8047 8048 /* Delete old version */ 8049 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL, 8050 name, 0, &rdata)); 8051 8052 /* Update refresh timer */ 8053 result = dns_rdata_tostruct(&rdata, &keydata, NULL); 8054 if (result == ISC_R_UNEXPECTEDEND) 8055 continue; 8056 if (result != ISC_R_SUCCESS) 8057 goto failure; 8058 keydata.refresh = refresh_time(kfetch, ISC_TRUE); 8059 set_refreshkeytimer(zone, &keydata, now); 8060 8061 dns_rdata_reset(&rdata); 8062 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 8063 CHECK(dns_rdata_fromstruct(&rdata, 8064 zone->rdclass, dns_rdatatype_keydata, 8065 &keydata, &keyb)); 8066 8067 /* Insert updated version */ 8068 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD, 8069 name, 0, &rdata)); 8070 } 8071 result = ISC_R_SUCCESS; 8072 failure: 8073 return (result); 8074} 8075 8076/* 8077 * Verify that DNSKEY set is signed by the key specified in 'keydata'. 8078 */ 8079static isc_boolean_t 8080revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) { 8081 isc_result_t result; 8082 dns_name_t *keyname; 8083 isc_mem_t *mctx; 8084 dns_rdata_t sigrr = DNS_RDATA_INIT; 8085 dns_rdata_t rr = DNS_RDATA_INIT; 8086 dns_rdata_rrsig_t sig; 8087 dns_rdata_dnskey_t dnskey; 8088 dst_key_t *dstkey = NULL; 8089 unsigned char key_buf[4096]; 8090 isc_buffer_t keyb; 8091 isc_boolean_t answer = ISC_FALSE; 8092 8093 REQUIRE(kfetch != NULL && keydata != NULL); 8094 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset)); 8095 8096 keyname = dns_fixedname_name(&kfetch->name); 8097 mctx = kfetch->zone->view->mctx; 8098 8099 /* Generate a key from keydata */ 8100 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 8101 dns_keydata_todnskey(keydata, &dnskey, NULL); 8102 dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey, 8103 &dnskey, &keyb); 8104 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey); 8105 if (result != ISC_R_SUCCESS) 8106 return (ISC_FALSE); 8107 8108 /* See if that key generated any of the signatures */ 8109 for (result = dns_rdataset_first(&kfetch->dnskeysigset); 8110 result == ISC_R_SUCCESS; 8111 result = dns_rdataset_next(&kfetch->dnskeysigset)) { 8112 dns_fixedname_t fixed; 8113 dns_fixedname_init(&fixed); 8114 8115 dns_rdata_reset(&sigrr); 8116 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr); 8117 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 8118 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8119 8120 if (dst_key_alg(dstkey) == sig.algorithm && 8121 (dst_key_id(dstkey) == sig.keyid || 8122 dst_key_rid(dstkey) == sig.keyid)) { 8123 result = dns_dnssec_verify2(keyname, 8124 &kfetch->dnskeyset, 8125 dstkey, ISC_FALSE, mctx, &sigrr, 8126 dns_fixedname_name(&fixed)); 8127 8128 dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3), 8129 "Confirm revoked DNSKEY is self-signed: " 8130 "%s", dns_result_totext(result)); 8131 8132 if (result == ISC_R_SUCCESS) { 8133 answer = ISC_TRUE; 8134 break; 8135 } 8136 } 8137 } 8138 8139 dst_key_free(&dstkey); 8140 return (answer); 8141} 8142 8143/* 8144 * A DNSKEY set has been fetched from the zone apex of a zone whose trust 8145 * anchors are being managed; scan the keyset, and update the key zone and the 8146 * local trust anchors according to RFC5011. 8147 */ 8148static void 8149keyfetch_done(isc_task_t *task, isc_event_t *event) { 8150 isc_result_t result, eresult; 8151 dns_fetchevent_t *devent; 8152 dns_keyfetch_t *kfetch; 8153 dns_zone_t *zone; 8154 isc_mem_t *mctx = NULL; 8155 dns_keytable_t *secroots = NULL; 8156 dns_dbversion_t *ver = NULL; 8157 dns_diff_t diff; 8158 isc_boolean_t alldone = ISC_FALSE; 8159 isc_boolean_t commit = ISC_FALSE; 8160 dns_name_t *keyname; 8161 dns_rdata_t sigrr = DNS_RDATA_INIT; 8162 dns_rdata_t dnskeyrr = DNS_RDATA_INIT; 8163 dns_rdata_t keydatarr = DNS_RDATA_INIT; 8164 dns_rdata_rrsig_t sig; 8165 dns_rdata_dnskey_t dnskey; 8166 dns_rdata_keydata_t keydata; 8167 isc_boolean_t initializing; 8168 char namebuf[DNS_NAME_FORMATSIZE]; 8169 unsigned char key_buf[4096]; 8170 isc_buffer_t keyb; 8171 dst_key_t *dstkey; 8172 isc_stdtime_t now; 8173 int pending = 0; 8174 isc_boolean_t secure; 8175 isc_boolean_t free_needed; 8176 8177 UNUSED(task); 8178 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE); 8179 INSIST(event->ev_arg != NULL); 8180 8181 kfetch = event->ev_arg; 8182 zone = kfetch->zone; 8183 isc_mem_attach(zone->mctx, &mctx); 8184 keyname = dns_fixedname_name(&kfetch->name); 8185 8186 devent = (dns_fetchevent_t *) event; 8187 eresult = devent->result; 8188 8189 /* Free resources which are not of interest */ 8190 if (devent->node != NULL) 8191 dns_db_detachnode(devent->db, &devent->node); 8192 if (devent->db != NULL) 8193 dns_db_detach(&devent->db); 8194 isc_event_free(&event); 8195 dns_resolver_destroyfetch(&kfetch->fetch); 8196 8197 LOCK_ZONE(zone); 8198 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) 8199 goto cleanup; 8200 8201 isc_stdtime_get(&now); 8202 dns_name_format(keyname, namebuf, sizeof(namebuf)); 8203 8204 result = dns_view_getsecroots(zone->view, &secroots); 8205 INSIST(result == ISC_R_SUCCESS); 8206 8207 dns_diff_init(mctx, &diff); 8208 8209 CHECK(dns_db_newversion(kfetch->db, &ver)); 8210 8211 zone->refreshkeycount--; 8212 alldone = ISC_TF(zone->refreshkeycount == 0); 8213 8214 if (alldone) 8215 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 8216 8217 /* Fetch failed */ 8218 if (eresult != ISC_R_SUCCESS || 8219 !dns_rdataset_isassociated(&kfetch->dnskeyset)) { 8220 dns_zone_log(zone, ISC_LOG_WARNING, 8221 "Unable to fetch DNSKEY set " 8222 "'%s': %s", namebuf, dns_result_totext(eresult)); 8223 CHECK(minimal_update(kfetch, ver, &diff)); 8224 goto done; 8225 } 8226 8227 /* No RRSIGs found */ 8228 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) { 8229 dns_zone_log(zone, ISC_LOG_WARNING, 8230 "No DNSKEY RRSIGs found for " 8231 "'%s': %s", namebuf, dns_result_totext(eresult)); 8232 CHECK(minimal_update(kfetch, ver, &diff)); 8233 goto done; 8234 } 8235 8236 /* 8237 * Validate the dnskeyset against the current trusted keys. 8238 */ 8239 for (result = dns_rdataset_first(&kfetch->dnskeysigset); 8240 result == ISC_R_SUCCESS; 8241 result = dns_rdataset_next(&kfetch->dnskeysigset)) { 8242 dns_keynode_t *keynode = NULL; 8243 8244 dns_rdata_reset(&sigrr); 8245 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr); 8246 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 8247 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8248 8249 result = dns_keytable_find(secroots, keyname, &keynode); 8250 while (result == ISC_R_SUCCESS) { 8251 dns_keynode_t *nextnode = NULL; 8252 dns_fixedname_t fixed; 8253 dns_fixedname_init(&fixed); 8254 8255 dstkey = dns_keynode_key(keynode); 8256 if (dstkey == NULL) /* fail_secure() was called */ 8257 break; 8258 8259 if (dst_key_alg(dstkey) == sig.algorithm && 8260 dst_key_id(dstkey) == sig.keyid) { 8261 result = dns_dnssec_verify2(keyname, 8262 &kfetch->dnskeyset, 8263 dstkey, ISC_FALSE, 8264 zone->view->mctx, &sigrr, 8265 dns_fixedname_name(&fixed)); 8266 8267 dns_zone_log(zone, ISC_LOG_DEBUG(3), 8268 "Verifying DNSKEY set for zone " 8269 "'%s': %s", namebuf, 8270 dns_result_totext(result)); 8271 8272 if (result == ISC_R_SUCCESS) { 8273 kfetch->dnskeyset.trust = 8274 dns_trust_secure; 8275 kfetch->dnskeysigset.trust = 8276 dns_trust_secure; 8277 dns_keytable_detachkeynode(secroots, 8278 &keynode); 8279 break; 8280 } 8281 } 8282 8283 result = dns_keytable_nextkeynode(secroots, 8284 keynode, &nextnode); 8285 dns_keytable_detachkeynode(secroots, &keynode); 8286 keynode = nextnode; 8287 } 8288 8289 if (kfetch->dnskeyset.trust == dns_trust_secure) 8290 break; 8291 } 8292 8293 /* 8294 * If we were not able to verify the answer using the current 8295 * trusted keys then all we can do is look at any revoked keys. 8296 */ 8297 secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure); 8298 8299 /* 8300 * First scan keydataset to find keys that are not in dnskeyset 8301 * - Missing keys which are not scheduled for removal, 8302 * log a warning 8303 * - Missing keys which are scheduled for removal and 8304 * the remove hold-down timer has completed should 8305 * be removed from the key zone 8306 * - Missing keys whose acceptance timers have not yet 8307 * completed, log a warning and reset the acceptance 8308 * timer to 30 days in the future 8309 * - All keys not being removed have their refresh timers 8310 * updated 8311 */ 8312 initializing = ISC_TRUE; 8313 for (result = dns_rdataset_first(&kfetch->keydataset); 8314 result == ISC_R_SUCCESS; 8315 result = dns_rdataset_next(&kfetch->keydataset)) { 8316 dns_rdata_reset(&keydatarr); 8317 dns_rdataset_current(&kfetch->keydataset, &keydatarr); 8318 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); 8319 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8320 8321 /* 8322 * If any keydata record has a nonzero add holddown, then 8323 * there was a pre-existing trust anchor for this domain; 8324 * that means we are *not* initializing it and shouldn't 8325 * automatically trust all the keys we find at the zone apex. 8326 */ 8327 initializing = initializing && ISC_TF(keydata.addhd == 0); 8328 8329 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) { 8330 isc_boolean_t deletekey = ISC_FALSE; 8331 8332 if (!secure) { 8333 if (now > keydata.removehd) 8334 deletekey = ISC_TRUE; 8335 } else if (now < keydata.addhd) { 8336 dns_zone_log(zone, ISC_LOG_WARNING, 8337 "Pending key unexpectedly missing " 8338 "from %s; restarting acceptance " 8339 "timer", namebuf); 8340 keydata.addhd = now + MONTH; 8341 keydata.refresh = refresh_time(kfetch, 8342 ISC_FALSE); 8343 } else if (keydata.addhd == 0) { 8344 keydata.addhd = now; 8345 } else if (keydata.removehd == 0) { 8346 dns_zone_log(zone, ISC_LOG_WARNING, 8347 "Active key unexpectedly missing " 8348 "from %s", namebuf); 8349 keydata.refresh = now + HOUR; 8350 } else if (now > keydata.removehd) { 8351 deletekey = ISC_TRUE; 8352 } else { 8353 keydata.refresh = refresh_time(kfetch, 8354 ISC_FALSE); 8355 } 8356 8357 if (secure || deletekey) { 8358 /* Delete old version */ 8359 CHECK(update_one_rr(kfetch->db, ver, &diff, 8360 DNS_DIFFOP_DEL, keyname, 0, 8361 &keydatarr)); 8362 } 8363 8364 if (!secure || deletekey) 8365 continue; 8366 8367 dns_rdata_reset(&keydatarr); 8368 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 8369 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 8370 dns_rdatatype_keydata, 8371 &keydata, &keyb); 8372 8373 /* Insert updated version */ 8374 CHECK(update_one_rr(kfetch->db, ver, &diff, 8375 DNS_DIFFOP_ADD, keyname, 0, 8376 &keydatarr)); 8377 8378 set_refreshkeytimer(zone, &keydata, now); 8379 } 8380 } 8381 8382 /* 8383 * Next scan dnskeyset: 8384 * - If new keys are found (i.e., lacking a match in keydataset) 8385 * add them to the key zone and set the acceptance timer 8386 * to 30 days in the future (or to immediately if we've 8387 * determined that we're initializing the zone for the 8388 * first time) 8389 * - Previously-known keys that have been revoked 8390 * must be scheduled for removal from the key zone (or, 8391 * if they hadn't been accepted as trust anchors yet 8392 * anyway, removed at once) 8393 * - Previously-known unrevoked keys whose acceptance timers 8394 * have completed are promoted to trust anchors 8395 * - All keys not being removed have their refresh 8396 * timers updated 8397 */ 8398 for (result = dns_rdataset_first(&kfetch->dnskeyset); 8399 result == ISC_R_SUCCESS; 8400 result = dns_rdataset_next(&kfetch->dnskeyset)) { 8401 isc_boolean_t revoked = ISC_FALSE; 8402 isc_boolean_t newkey = ISC_FALSE; 8403 isc_boolean_t updatekey = ISC_FALSE; 8404 isc_boolean_t deletekey = ISC_FALSE; 8405 isc_boolean_t trustkey = ISC_FALSE; 8406 8407 dns_rdata_reset(&dnskeyrr); 8408 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr); 8409 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 8410 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8411 8412 /* Skip ZSK's */ 8413 if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK)) 8414 continue; 8415 8416 revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE); 8417 8418 if (matchkey(&kfetch->keydataset, &dnskeyrr)) { 8419 dns_rdata_reset(&keydatarr); 8420 dns_rdataset_current(&kfetch->keydataset, &keydatarr); 8421 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); 8422 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8423 8424 if (revoked && revocable(kfetch, &keydata)) { 8425 if (keydata.addhd > now) { 8426 /* 8427 * Key wasn't trusted yet, and now 8428 * it's been revoked? Just remove it 8429 */ 8430 deletekey = ISC_TRUE; 8431 } else if (keydata.removehd == 0) { 8432 /* Remove from secroots */ 8433 dns_view_untrust(zone->view, keyname, 8434 &dnskey, mctx); 8435 8436 /* If initializing, delete now */ 8437 if (keydata.addhd == 0) 8438 deletekey = ISC_TRUE; 8439 else 8440 keydata.removehd = now + MONTH; 8441 } else if (keydata.removehd < now) { 8442 /* Scheduled for removal */ 8443 deletekey = ISC_TRUE; 8444 } 8445 } else if (revoked) { 8446 if (secure && keydata.removehd == 0) { 8447 dns_zone_log(zone, ISC_LOG_WARNING, 8448 "Active key for zone " 8449 "'%s' is revoked but " 8450 "did not self-sign; " 8451 "ignoring.", namebuf); 8452 continue; 8453 } 8454 } else if (secure) { 8455 if (keydata.removehd != 0) { 8456 /* 8457 * Key isn't revoked--but it 8458 * seems it used to be. 8459 * Remove it now and add it 8460 * back as if it were a fresh key. 8461 */ 8462 deletekey = ISC_TRUE; 8463 newkey = ISC_TRUE; 8464 } else if (keydata.addhd > now) 8465 pending++; 8466 else if (keydata.addhd == 0) 8467 keydata.addhd = now; 8468 8469 if (keydata.addhd <= now) 8470 trustkey = ISC_TRUE; 8471 } 8472 8473 if (!deletekey && !newkey) 8474 updatekey = ISC_TRUE; 8475 } else if (secure) { 8476 /* 8477 * Key wasn't in the key zone but it's 8478 * revoked now anyway, so just skip it 8479 */ 8480 if (revoked) 8481 continue; 8482 8483 /* Key wasn't in the key zone: add it */ 8484 newkey = ISC_TRUE; 8485 8486 if (initializing) { 8487 dns_keytag_t tag = 0; 8488 CHECK(compute_tag(keyname, &dnskey, 8489 mctx, &tag)); 8490 dns_zone_log(zone, ISC_LOG_WARNING, 8491 "Initializing automatic trust " 8492 "anchor management for zone '%s'; " 8493 "DNSKEY ID %d is now trusted, " 8494 "waiving the normal 30-day " 8495 "waiting period.", 8496 namebuf, tag); 8497 trustkey = ISC_TRUE; 8498 } 8499 } else { 8500 /* 8501 * No previously known key, and the key is not 8502 * secure, so skip it. 8503 */ 8504 continue; 8505 } 8506 8507 /* Delete old version */ 8508 if (deletekey || !newkey) 8509 CHECK(update_one_rr(kfetch->db, ver, &diff, 8510 DNS_DIFFOP_DEL, keyname, 0, 8511 &keydatarr)); 8512 8513 if (updatekey) { 8514 /* Set refresh timer */ 8515 keydata.refresh = refresh_time(kfetch, ISC_FALSE); 8516 dns_rdata_reset(&keydatarr); 8517 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 8518 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 8519 dns_rdatatype_keydata, 8520 &keydata, &keyb); 8521 8522 /* Insert updated version */ 8523 CHECK(update_one_rr(kfetch->db, ver, &diff, 8524 DNS_DIFFOP_ADD, keyname, 0, 8525 &keydatarr)); 8526 } else if (newkey) { 8527 /* Convert DNSKEY to KEYDATA */ 8528 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 8529 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8530 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0, 8531 NULL); 8532 keydata.addhd = initializing ? now : now + MONTH; 8533 keydata.refresh = refresh_time(kfetch, ISC_FALSE); 8534 dns_rdata_reset(&keydatarr); 8535 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 8536 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 8537 dns_rdatatype_keydata, 8538 &keydata, &keyb); 8539 8540 /* Insert into key zone */ 8541 CHECK(update_one_rr(kfetch->db, ver, &diff, 8542 DNS_DIFFOP_ADD, keyname, 0, 8543 &keydatarr)); 8544 } 8545 8546 if (trustkey) { 8547 /* Trust this key. */ 8548 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 8549 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8550 trust_key(zone, keyname, &dnskey, mctx); 8551 } 8552 8553 if (secure && !deletekey) 8554 set_refreshkeytimer(zone, &keydata, now); 8555 } 8556 8557 /* 8558 * RFC5011 says, "A trust point that has all of its trust anchors 8559 * revoked is considered deleted and is treated as if the trust 8560 * point was never configured." But if someone revoked their 8561 * active key before the standby was trusted, that would mean the 8562 * zone would suddenly be nonsecured. We avoid this by checking to 8563 * see if there's pending keydata. If so, we put a null key in 8564 * the security roots; then all queries to the zone will fail. 8565 */ 8566 if (pending != 0) 8567 fail_secure(zone, keyname); 8568 8569 done: 8570 8571 if (!ISC_LIST_EMPTY(diff.tuples)) { 8572 /* Write changes to journal file. */ 8573 CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx, 8574 zone->updatemethod)); 8575 CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done")); 8576 commit = ISC_TRUE; 8577 8578 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 8579 zone_needdump(zone, 30); 8580 } 8581 8582 failure: 8583 8584 dns_diff_clear(&diff); 8585 if (ver != NULL) 8586 dns_db_closeversion(kfetch->db, &ver, commit); 8587 8588 cleanup: 8589 dns_db_detach(&kfetch->db); 8590 8591 INSIST(zone->irefs > 0); 8592 zone->irefs--; 8593 kfetch->zone = NULL; 8594 8595 if (dns_rdataset_isassociated(&kfetch->keydataset)) 8596 dns_rdataset_disassociate(&kfetch->keydataset); 8597 if (dns_rdataset_isassociated(&kfetch->dnskeyset)) 8598 dns_rdataset_disassociate(&kfetch->dnskeyset); 8599 if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) 8600 dns_rdataset_disassociate(&kfetch->dnskeysigset); 8601 8602 dns_name_free(keyname, mctx); 8603 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t)); 8604 isc_mem_detach(&mctx); 8605 8606 if (secroots != NULL) 8607 dns_keytable_detach(&secroots); 8608 8609 free_needed = exit_check(zone); 8610 UNLOCK_ZONE(zone); 8611 if (free_needed) 8612 zone_free(zone); 8613} 8614 8615/* 8616 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY 8617 * records from the zone apex. 8618 */ 8619static void 8620zone_refreshkeys(dns_zone_t *zone) { 8621 const char me[] = "zone_refreshkeys"; 8622 isc_result_t result; 8623 dns_rriterator_t rrit; 8624 dns_db_t *db = NULL; 8625 dns_dbversion_t *ver = NULL; 8626 dns_diff_t diff; 8627 dns_rdata_t rdata = DNS_RDATA_INIT; 8628 dns_rdata_keydata_t kd; 8629 isc_stdtime_t now; 8630 isc_boolean_t commit = ISC_FALSE; 8631 isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE; 8632 8633 ENTER; 8634 REQUIRE(zone->db != NULL); 8635 8636 isc_stdtime_get(&now); 8637 8638 LOCK_ZONE(zone); 8639 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 8640 isc_time_settoepoch(&zone->refreshkeytime); 8641 UNLOCK_ZONE(zone); 8642 return; 8643 } 8644 8645 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8646 dns_db_attach(zone->db, &db); 8647 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8648 8649 dns_diff_init(zone->mctx, &diff); 8650 8651 CHECK(dns_db_newversion(db, &ver)); 8652 8653 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING); 8654 8655 dns_rriterator_init(&rrit, db, ver, 0); 8656 for (result = dns_rriterator_first(&rrit); 8657 result == ISC_R_SUCCESS; 8658 result = dns_rriterator_nextrrset(&rrit)) { 8659 isc_stdtime_t timer = 0xffffffff; 8660 dns_name_t *name = NULL, *kname = NULL; 8661 dns_rdataset_t *kdset = NULL; 8662 dns_keyfetch_t *kfetch; 8663 isc_uint32_t ttl; 8664 8665 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL); 8666 if (kdset == NULL || kdset->type != dns_rdatatype_keydata || 8667 !dns_rdataset_isassociated(kdset)) 8668 continue; 8669 8670 /* 8671 * Scan the stored keys looking for ones that need 8672 * removal or refreshing 8673 */ 8674 for (result = dns_rdataset_first(kdset); 8675 result == ISC_R_SUCCESS; 8676 result = dns_rdataset_next(kdset)) { 8677 dns_rdata_reset(&rdata); 8678 dns_rdataset_current(kdset, &rdata); 8679 result = dns_rdata_tostruct(&rdata, &kd, NULL); 8680 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8681 8682 /* Removal timer expired? */ 8683 if (kd.removehd != 0 && kd.removehd < now) { 8684 CHECK(update_one_rr(db, ver, &diff, 8685 DNS_DIFFOP_DEL, name, ttl, 8686 &rdata)); 8687 continue; 8688 } 8689 8690 /* Acceptance timer expired? */ 8691 if (kd.addhd != 0 && kd.addhd < now) 8692 timer = kd.addhd; 8693 8694 /* Or do we just need to refresh the keyset? */ 8695 if (timer > kd.refresh) 8696 timer = kd.refresh; 8697 } 8698 8699 if (timer > now) 8700 continue; 8701 8702 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t)); 8703 if (kfetch == NULL) { 8704 fetch_err = ISC_TRUE; 8705 goto failure; 8706 } 8707 8708 zone->refreshkeycount++; 8709 kfetch->zone = zone; 8710 zone->irefs++; 8711 INSIST(zone->irefs != 0); 8712 dns_fixedname_init(&kfetch->name); 8713 kname = dns_fixedname_name(&kfetch->name); 8714 dns_name_dup(name, zone->mctx, kname); 8715 dns_rdataset_init(&kfetch->dnskeyset); 8716 dns_rdataset_init(&kfetch->dnskeysigset); 8717 dns_rdataset_init(&kfetch->keydataset); 8718 dns_rdataset_clone(kdset, &kfetch->keydataset); 8719 kfetch->db = NULL; 8720 dns_db_attach(db, &kfetch->db); 8721 kfetch->fetch = NULL; 8722 8723 result = dns_resolver_createfetch(zone->view->resolver, 8724 kname, dns_rdatatype_dnskey, 8725 NULL, NULL, NULL, 8726 DNS_FETCHOPT_NOVALIDATE, 8727 zone->task, 8728 keyfetch_done, kfetch, 8729 &kfetch->dnskeyset, 8730 &kfetch->dnskeysigset, 8731 &kfetch->fetch); 8732 if (result == ISC_R_SUCCESS) 8733 fetching = ISC_TRUE; 8734 else { 8735 zone->refreshkeycount--; 8736 zone->irefs--; 8737 dns_db_detach(&kfetch->db); 8738 dns_rdataset_disassociate(&kfetch->keydataset); 8739 dns_name_free(kname, zone->mctx); 8740 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t)); 8741 dns_zone_log(zone, ISC_LOG_WARNING, 8742 "Failed to create fetch for " 8743 "DNSKEY update"); 8744 fetch_err = ISC_TRUE; 8745 } 8746 } 8747 if (!ISC_LIST_EMPTY(diff.tuples)) { 8748 CHECK(update_soa_serial(db, ver, &diff, zone->mctx, 8749 zone->updatemethod)); 8750 CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys")); 8751 commit = ISC_TRUE; 8752 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 8753 zone_needdump(zone, 30); 8754 } 8755 8756 failure: 8757 if (fetch_err) { 8758 /* 8759 * Error during a key fetch; retry in an hour. 8760 */ 8761 isc_time_t timenow, timethen; 8762 char timebuf[80]; 8763 8764 TIME_NOW(&timenow); 8765 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen); 8766 zone->refreshkeytime = timethen; 8767 zone_settimer(zone, &timenow); 8768 8769 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 8770 dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s", 8771 timebuf); 8772 8773 if (!fetching) 8774 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 8775 } 8776 8777 UNLOCK_ZONE(zone); 8778 8779 dns_diff_clear(&diff); 8780 if (ver != NULL) { 8781 dns_rriterator_destroy(&rrit); 8782 dns_db_closeversion(db, &ver, commit); 8783 } 8784 dns_db_detach(&db); 8785} 8786 8787static void 8788zone_maintenance(dns_zone_t *zone) { 8789 const char me[] = "zone_maintenance"; 8790 isc_time_t now; 8791 isc_result_t result; 8792 isc_boolean_t dumping; 8793 8794 REQUIRE(DNS_ZONE_VALID(zone)); 8795 ENTER; 8796 8797 /* 8798 * Are we pending load/reload? 8799 */ 8800 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) 8801 return; 8802 8803 /* 8804 * Configuring the view of this zone may have 8805 * failed, for example because the config file 8806 * had a syntax error. In that case, the view 8807 * adb or resolver will be NULL, and we had better not try 8808 * to do further maintenance on it. 8809 */ 8810 if (zone->view == NULL || zone->view->adb == NULL) 8811 return; 8812 8813 TIME_NOW(&now); 8814 8815 /* 8816 * Expire check. 8817 */ 8818 switch (zone->type) { 8819 case dns_zone_redirect: 8820 if (zone->masters == NULL) 8821 break; 8822 case dns_zone_slave: 8823 case dns_zone_stub: 8824 LOCK_ZONE(zone); 8825 if (isc_time_compare(&now, &zone->expiretime) >= 0 && 8826 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 8827 zone_expire(zone); 8828 zone->refreshtime = now; 8829 } 8830 UNLOCK_ZONE(zone); 8831 break; 8832 default: 8833 break; 8834 } 8835 8836 /* 8837 * Up to date check. 8838 */ 8839 switch (zone->type) { 8840 case dns_zone_redirect: 8841 if (zone->masters == NULL) 8842 break; 8843 case dns_zone_slave: 8844 case dns_zone_stub: 8845 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && 8846 isc_time_compare(&now, &zone->refreshtime) >= 0) 8847 dns_zone_refresh(zone); 8848 break; 8849 default: 8850 break; 8851 } 8852 8853 /* 8854 * Slaves send notifies before backing up to disk, masters after. 8855 */ 8856 if (zone->type == dns_zone_slave && 8857 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) && 8858 isc_time_compare(&now, &zone->notifytime) >= 0) 8859 zone_notify(zone, &now); 8860 8861 /* 8862 * Do we need to consolidate the backing store? 8863 */ 8864 switch (zone->type) { 8865 case dns_zone_master: 8866 case dns_zone_slave: 8867 case dns_zone_key: 8868 case dns_zone_redirect: 8869 case dns_zone_stub: 8870 LOCK_ZONE(zone); 8871 if (zone->masterfile != NULL && 8872 isc_time_compare(&now, &zone->dumptime) >= 0 && 8873 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 8874 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) { 8875 dumping = was_dumping(zone); 8876 } else 8877 dumping = ISC_TRUE; 8878 UNLOCK_ZONE(zone); 8879 if (!dumping) { 8880 result = zone_dump(zone, ISC_TRUE); /* task locked */ 8881 if (result != ISC_R_SUCCESS) 8882 dns_zone_log(zone, ISC_LOG_WARNING, 8883 "dump failed: %s", 8884 dns_result_totext(result)); 8885 } 8886 break; 8887 default: 8888 break; 8889 } 8890 8891 /* 8892 * Master/redirect zones send notifies now, if needed 8893 */ 8894 switch (zone->type) { 8895 case dns_zone_master: 8896 case dns_zone_redirect: 8897 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) && 8898 isc_time_compare(&now, &zone->notifytime) >= 0) 8899 zone_notify(zone, &now); 8900 default: 8901 break; 8902 } 8903 8904 /* 8905 * Do we need to refresh keys? 8906 */ 8907 switch (zone->type) { 8908 case dns_zone_key: 8909 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) { 8910 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 8911 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) { 8912 zone_refreshkeys(zone); 8913 } 8914 } 8915 break; 8916 case dns_zone_master: 8917 if (!isc_time_isepoch(&zone->refreshkeytime) && 8918 isc_time_compare(&now, &zone->refreshkeytime) >= 0) 8919 zone_rekey(zone); 8920 default: 8921 break; 8922 } 8923 8924 switch (zone->type) { 8925 case dns_zone_master: 8926 case dns_zone_redirect: 8927 case dns_zone_slave: 8928 /* 8929 * Do we need to sign/resign some RRsets? 8930 */ 8931 if (!isc_time_isepoch(&zone->signingtime) && 8932 isc_time_compare(&now, &zone->signingtime) >= 0) 8933 zone_sign(zone); 8934 else if (!isc_time_isepoch(&zone->resigntime) && 8935 isc_time_compare(&now, &zone->resigntime) >= 0) 8936 zone_resigninc(zone); 8937 else if (!isc_time_isepoch(&zone->nsec3chaintime) && 8938 isc_time_compare(&now, &zone->nsec3chaintime) >= 0) 8939 zone_nsec3chain(zone); 8940 /* 8941 * Do we need to issue a key expiry warning? 8942 */ 8943 if (!isc_time_isepoch(&zone->keywarntime) && 8944 isc_time_compare(&now, &zone->keywarntime) >= 0) 8945 set_key_expiry_warning(zone, zone->key_expiry, 8946 isc_time_seconds(&now)); 8947 break; 8948 8949 default: 8950 break; 8951 } 8952 zone_settimer(zone, &now); 8953} 8954 8955void 8956dns_zone_markdirty(dns_zone_t *zone) { 8957 isc_uint32_t serial; 8958 isc_result_t result = ISC_R_SUCCESS; 8959 dns_zone_t *secure = NULL; 8960 8961 /* 8962 * Obtaining a lock on the zone->secure (see zone_send_secureserial) 8963 * could result in a deadlock due to a LOR so we will spin if we 8964 * can't obtain the both locks. 8965 */ 8966 again: 8967 LOCK_ZONE(zone); 8968 if (zone->type == dns_zone_master) { 8969 if (inline_raw(zone)) { 8970 unsigned int soacount; 8971 secure = zone->secure; 8972 INSIST(secure != zone); 8973 TRYLOCK_ZONE(result, secure); 8974 if (result != ISC_R_SUCCESS) { 8975 UNLOCK_ZONE(zone); 8976 secure = NULL; 8977#ifdef ISC_PLATFORM_USETHREADS 8978 isc_thread_yield(); 8979#endif 8980 goto again; 8981 } 8982 8983 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8984 if (zone->db != NULL) { 8985 result = zone_get_from_db(zone, zone->db, NULL, 8986 &soacount, &serial, 8987 NULL, NULL, NULL, 8988 NULL, NULL); 8989 } else 8990 result = DNS_R_NOTLOADED; 8991 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8992 if (result == ISC_R_SUCCESS && soacount > 0U) 8993 zone_send_secureserial(zone, serial); 8994 } 8995 8996 /* XXXMPA make separate call back */ 8997 if (result == ISC_R_SUCCESS) 8998 set_resigntime(zone); 8999 } 9000 if (secure != NULL) 9001 UNLOCK_ZONE(secure); 9002 zone_needdump(zone, DNS_DUMP_DELAY); 9003 UNLOCK_ZONE(zone); 9004} 9005 9006void 9007dns_zone_expire(dns_zone_t *zone) { 9008 REQUIRE(DNS_ZONE_VALID(zone)); 9009 9010 LOCK_ZONE(zone); 9011 zone_expire(zone); 9012 UNLOCK_ZONE(zone); 9013} 9014 9015static void 9016zone_expire(dns_zone_t *zone) { 9017 /* 9018 * 'zone' locked by caller. 9019 */ 9020 9021 REQUIRE(LOCKED_ZONE(zone)); 9022 9023 dns_zone_log(zone, ISC_LOG_WARNING, "expired"); 9024 9025 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED); 9026 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 9027 zone->retry = DNS_ZONE_DEFAULTRETRY; 9028 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 9029 zone_unload(zone); 9030} 9031 9032void 9033dns_zone_refresh(dns_zone_t *zone) { 9034 isc_interval_t i; 9035 isc_uint32_t oldflags; 9036 unsigned int j; 9037 isc_result_t result; 9038 9039 REQUIRE(DNS_ZONE_VALID(zone)); 9040 9041 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 9042 return; 9043 9044 /* 9045 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation 9046 * in progress at a time. 9047 */ 9048 9049 LOCK_ZONE(zone); 9050 oldflags = zone->flags; 9051 if (zone->masterscnt == 0) { 9052 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS); 9053 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0) 9054 dns_zone_log(zone, ISC_LOG_ERROR, 9055 "cannot refresh: no masters"); 9056 goto unlock; 9057 } 9058 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 9059 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 9060 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 9061 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0) 9062 goto unlock; 9063 9064 /* 9065 * Set the next refresh time as if refresh check has failed. 9066 * Setting this to the retry time will do that. XXXMLG 9067 * If we are successful it will be reset using zone->refresh. 9068 */ 9069 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4), 9070 0); 9071 result = isc_time_nowplusinterval(&zone->refreshtime, &i); 9072 if (result != ISC_R_SUCCESS) 9073 dns_zone_log(zone, ISC_LOG_WARNING, 9074 "isc_time_nowplusinterval() failed: %s", 9075 dns_result_totext(result)); 9076 9077 /* 9078 * When lacking user-specified timer values from the SOA, 9079 * do exponential backoff of the retry time up to a 9080 * maximum of six hours. 9081 */ 9082 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) 9083 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600); 9084 9085 zone->curmaster = 0; 9086 for (j = 0; j < zone->masterscnt; j++) 9087 zone->mastersok[j] = ISC_FALSE; 9088 /* initiate soa query */ 9089 queue_soa_query(zone); 9090 unlock: 9091 UNLOCK_ZONE(zone); 9092} 9093 9094isc_result_t 9095dns_zone_flush(dns_zone_t *zone) { 9096 isc_result_t result = ISC_R_SUCCESS; 9097 isc_boolean_t dumping; 9098 9099 REQUIRE(DNS_ZONE_VALID(zone)); 9100 9101 LOCK_ZONE(zone); 9102 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH); 9103 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 9104 zone->masterfile != NULL) { 9105 result = ISC_R_ALREADYRUNNING; 9106 dumping = was_dumping(zone); 9107 } else 9108 dumping = ISC_TRUE; 9109 UNLOCK_ZONE(zone); 9110 if (!dumping) 9111 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */ 9112 return (result); 9113} 9114 9115isc_result_t 9116dns_zone_dump(dns_zone_t *zone) { 9117 isc_result_t result = ISC_R_ALREADYRUNNING; 9118 isc_boolean_t dumping; 9119 9120 REQUIRE(DNS_ZONE_VALID(zone)); 9121 9122 LOCK_ZONE(zone); 9123 dumping = was_dumping(zone); 9124 UNLOCK_ZONE(zone); 9125 if (!dumping) 9126 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */ 9127 return (result); 9128} 9129 9130static void 9131zone_needdump(dns_zone_t *zone, unsigned int delay) { 9132 const char me[] = "zone_needdump"; 9133 isc_time_t dumptime; 9134 isc_time_t now; 9135 9136 /* 9137 * 'zone' locked by caller 9138 */ 9139 9140 REQUIRE(DNS_ZONE_VALID(zone)); 9141 REQUIRE(LOCKED_ZONE(zone)); 9142 ENTER; 9143 9144 /* 9145 * Do we have a place to dump to and are we loaded? 9146 */ 9147 if (zone->masterfile == NULL || 9148 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) 9149 return; 9150 9151 TIME_NOW(&now); 9152 /* add some noise */ 9153 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime); 9154 9155 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 9156 if (isc_time_isepoch(&zone->dumptime) || 9157 isc_time_compare(&zone->dumptime, &dumptime) > 0) 9158 zone->dumptime = dumptime; 9159 if (zone->task != NULL) 9160 zone_settimer(zone, &now); 9161} 9162 9163static void 9164dump_done(void *arg, isc_result_t result) { 9165 const char me[] = "dump_done"; 9166 dns_zone_t *zone = arg; 9167 dns_db_t *db; 9168 dns_dbversion_t *version; 9169 isc_boolean_t again = ISC_FALSE; 9170 isc_boolean_t compact = ISC_FALSE; 9171 isc_uint32_t serial; 9172 isc_result_t tresult; 9173 9174 REQUIRE(DNS_ZONE_VALID(zone)); 9175 9176 ENTER; 9177 9178 if (result == ISC_R_SUCCESS && zone->journal != NULL && 9179 zone->journalsize != -1) { 9180 9181 /* 9182 * We don't own these, zone->dctx must stay valid. 9183 */ 9184 db = dns_dumpctx_db(zone->dctx); 9185 version = dns_dumpctx_version(zone->dctx); 9186 9187 tresult = dns_db_getsoaserial(db, version, &serial); 9188 /* 9189 * If there is a secure version of this zone 9190 * use its serial if it is less than ours. 9191 */ 9192 if (tresult == ISC_R_SUCCESS && inline_raw(zone) && 9193 zone->secure->db != NULL) 9194 { 9195 isc_uint32_t sserial; 9196 isc_result_t mresult; 9197 9198 mresult = dns_db_getsoaserial(zone->secure->db, 9199 NULL, &sserial); 9200 if (mresult == ISC_R_SUCCESS && 9201 isc_serial_lt(sserial, serial)) 9202 serial = sserial; 9203 } 9204 /* 9205 * Note: we are task locked here so we can test 9206 * zone->xfr safely. 9207 */ 9208 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) { 9209 tresult = dns_journal_compact(zone->mctx, 9210 zone->journal, 9211 serial, 9212 zone->journalsize); 9213 switch (tresult) { 9214 case ISC_R_SUCCESS: 9215 case ISC_R_NOSPACE: 9216 case ISC_R_NOTFOUND: 9217 dns_zone_log(zone, ISC_LOG_DEBUG(3), 9218 "dns_journal_compact: %s", 9219 dns_result_totext(tresult)); 9220 break; 9221 default: 9222 dns_zone_log(zone, ISC_LOG_ERROR, 9223 "dns_journal_compact failed: %s", 9224 dns_result_totext(tresult)); 9225 break; 9226 } 9227 } else if (tresult == ISC_R_SUCCESS) { 9228 compact = ISC_TRUE; 9229 zone->compact_serial = serial; 9230 } 9231 } 9232 9233 LOCK_ZONE(zone); 9234 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 9235 if (compact) 9236 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 9237 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) { 9238 /* 9239 * Try again in a short while. 9240 */ 9241 zone_needdump(zone, DNS_DUMP_DELAY); 9242 } else if (result == ISC_R_SUCCESS && 9243 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 9244 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 9245 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 9246 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 9247 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 9248 isc_time_settoepoch(&zone->dumptime); 9249 again = ISC_TRUE; 9250 } else if (result == ISC_R_SUCCESS) 9251 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 9252 9253 if (zone->dctx != NULL) 9254 dns_dumpctx_detach(&zone->dctx); 9255 zonemgr_putio(&zone->writeio); 9256 UNLOCK_ZONE(zone); 9257 if (again) 9258 (void)zone_dump(zone, ISC_FALSE); 9259 dns_zone_idetach(&zone); 9260} 9261 9262static isc_result_t 9263zone_dump(dns_zone_t *zone, isc_boolean_t compact) { 9264 const char me[] = "zone_dump"; 9265 isc_result_t result; 9266 dns_dbversion_t *version = NULL; 9267 isc_boolean_t again; 9268 dns_db_t *db = NULL; 9269 char *masterfile = NULL; 9270 dns_masterformat_t masterformat = dns_masterformat_none; 9271 9272/* 9273 * 'compact' MUST only be set if we are task locked. 9274 */ 9275 9276 REQUIRE(DNS_ZONE_VALID(zone)); 9277 ENTER; 9278 9279 redo: 9280 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9281 if (zone->db != NULL) 9282 dns_db_attach(zone->db, &db); 9283 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9284 LOCK_ZONE(zone); 9285 if (zone->masterfile != NULL) { 9286 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile); 9287 masterformat = zone->masterformat; 9288 } 9289 UNLOCK_ZONE(zone); 9290 if (db == NULL) { 9291 result = DNS_R_NOTLOADED; 9292 goto fail; 9293 } 9294 if (masterfile == NULL) { 9295 result = DNS_R_NOMASTERFILE; 9296 goto fail; 9297 } 9298 9299 if (compact && zone->type != dns_zone_stub) { 9300 dns_zone_t *dummy = NULL; 9301 LOCK_ZONE(zone); 9302 zone_iattach(zone, &dummy); 9303 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task, 9304 zone_gotwritehandle, zone, 9305 &zone->writeio); 9306 if (result != ISC_R_SUCCESS) 9307 zone_idetach(&dummy); 9308 else 9309 result = DNS_R_CONTINUE; 9310 UNLOCK_ZONE(zone); 9311 } else { 9312 const dns_master_style_t *output_style; 9313 9314 dns_masterrawheader_t rawdata; 9315 dns_db_currentversion(db, &version); 9316 dns_master_initrawheader(&rawdata); 9317 if (inline_secure(zone)) 9318 get_raw_serial(zone->raw, &rawdata); 9319 if (zone->type == dns_zone_key) 9320 output_style = &dns_master_style_keyzone; 9321 else 9322 output_style = &dns_master_style_default; 9323 result = dns_master_dump3(zone->mctx, db, version, 9324 output_style, masterfile, 9325 masterformat, &rawdata); 9326 dns_db_closeversion(db, &version, ISC_FALSE); 9327 } 9328 fail: 9329 if (db != NULL) 9330 dns_db_detach(&db); 9331 if (masterfile != NULL) 9332 isc_mem_free(zone->mctx, masterfile); 9333 masterfile = NULL; 9334 9335 if (result == DNS_R_CONTINUE) 9336 return (ISC_R_SUCCESS); /* XXXMPA */ 9337 9338 again = ISC_FALSE; 9339 LOCK_ZONE(zone); 9340 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 9341 if (result != ISC_R_SUCCESS) { 9342 /* 9343 * Try again in a short while. 9344 */ 9345 zone_needdump(zone, DNS_DUMP_DELAY); 9346 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 9347 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 9348 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 9349 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 9350 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 9351 isc_time_settoepoch(&zone->dumptime); 9352 again = ISC_TRUE; 9353 } else 9354 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 9355 UNLOCK_ZONE(zone); 9356 if (again) 9357 goto redo; 9358 9359 return (result); 9360} 9361 9362static isc_result_t 9363dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style, 9364 dns_masterformat_t format, const isc_uint32_t rawversion) 9365{ 9366 isc_result_t result; 9367 dns_dbversion_t *version = NULL; 9368 dns_db_t *db = NULL; 9369 dns_masterrawheader_t rawdata; 9370 9371 REQUIRE(DNS_ZONE_VALID(zone)); 9372 9373 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9374 if (zone->db != NULL) 9375 dns_db_attach(zone->db, &db); 9376 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9377 if (db == NULL) 9378 return (DNS_R_NOTLOADED); 9379 9380 dns_db_currentversion(db, &version); 9381 dns_master_initrawheader(&rawdata); 9382 if (rawversion == 0) 9383 rawdata.flags |= DNS_MASTERRAW_COMPAT; 9384 else if (inline_secure(zone)) 9385 get_raw_serial(zone->raw, &rawdata); 9386 else if (zone->sourceserialset) { 9387 rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET; 9388 rawdata.sourceserial = zone->sourceserial; 9389 } 9390 result = dns_master_dumptostream3(zone->mctx, db, version, style, 9391 format, &rawdata, fd); 9392 dns_db_closeversion(db, &version, ISC_FALSE); 9393 dns_db_detach(&db); 9394 return (result); 9395} 9396 9397isc_result_t 9398dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, 9399 const dns_master_style_t *style, 9400 const isc_uint32_t rawversion) 9401{ 9402 return (dumptostream(zone, fd, style, format, rawversion)); 9403} 9404 9405isc_result_t 9406dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, 9407 const dns_master_style_t *style) { 9408 return (dumptostream(zone, fd, style, format, DNS_RAWFORMAT_VERSION)); 9409} 9410 9411isc_result_t 9412dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) { 9413 return (dumptostream(zone, fd, &dns_master_style_default, 9414 dns_masterformat_text, 0)); 9415} 9416 9417isc_result_t 9418dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) { 9419 return (dumptostream(zone, fd, &dns_master_style_full, 9420 dns_masterformat_text, 0)); 9421} 9422 9423void 9424dns_zone_unload(dns_zone_t *zone) { 9425 REQUIRE(DNS_ZONE_VALID(zone)); 9426 9427 LOCK_ZONE(zone); 9428 zone_unload(zone); 9429 UNLOCK_ZONE(zone); 9430} 9431 9432static void 9433notify_cancel(dns_zone_t *zone) { 9434 dns_notify_t *notify; 9435 9436 /* 9437 * 'zone' locked by caller. 9438 */ 9439 9440 REQUIRE(LOCKED_ZONE(zone)); 9441 9442 for (notify = ISC_LIST_HEAD(zone->notifies); 9443 notify != NULL; 9444 notify = ISC_LIST_NEXT(notify, link)) { 9445 if (notify->find != NULL) 9446 dns_adb_cancelfind(notify->find); 9447 if (notify->request != NULL) 9448 dns_request_cancel(notify->request); 9449 } 9450} 9451 9452static void 9453forward_cancel(dns_zone_t *zone) { 9454 dns_forward_t *forward; 9455 9456 /* 9457 * 'zone' locked by caller. 9458 */ 9459 9460 REQUIRE(LOCKED_ZONE(zone)); 9461 9462 for (forward = ISC_LIST_HEAD(zone->forwards); 9463 forward != NULL; 9464 forward = ISC_LIST_NEXT(forward, link)) { 9465 if (forward->request != NULL) 9466 dns_request_cancel(forward->request); 9467 } 9468} 9469 9470static void 9471zone_unload(dns_zone_t *zone) { 9472 /* 9473 * 'zone' locked by caller. 9474 */ 9475 9476 REQUIRE(LOCKED_ZONE(zone)); 9477 9478 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 9479 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 9480 if (zone->writeio != NULL) 9481 zonemgr_cancelio(zone->writeio); 9482 9483 if (zone->dctx != NULL) 9484 dns_dumpctx_cancel(zone->dctx); 9485 } 9486 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 9487 zone_detachdb(zone); 9488 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 9489 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED); 9490 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 9491} 9492 9493void 9494dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) { 9495 REQUIRE(DNS_ZONE_VALID(zone)); 9496 REQUIRE(val > 0); 9497 9498 zone->minrefresh = val; 9499} 9500 9501void 9502dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) { 9503 REQUIRE(DNS_ZONE_VALID(zone)); 9504 REQUIRE(val > 0); 9505 9506 zone->maxrefresh = val; 9507} 9508 9509void 9510dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) { 9511 REQUIRE(DNS_ZONE_VALID(zone)); 9512 REQUIRE(val > 0); 9513 9514 zone->minretry = val; 9515} 9516 9517void 9518dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) { 9519 REQUIRE(DNS_ZONE_VALID(zone)); 9520 REQUIRE(val > 0); 9521 9522 zone->maxretry = val; 9523} 9524 9525static isc_boolean_t 9526notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) { 9527 dns_notify_t *notify; 9528 9529 for (notify = ISC_LIST_HEAD(zone->notifies); 9530 notify != NULL; 9531 notify = ISC_LIST_NEXT(notify, link)) { 9532 if (notify->request != NULL) 9533 continue; 9534 if (name != NULL && dns_name_dynamic(¬ify->ns) && 9535 dns_name_equal(name, ¬ify->ns)) 9536 return (ISC_TRUE); 9537 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst)) 9538 return (ISC_TRUE); 9539 } 9540 return (ISC_FALSE); 9541} 9542 9543static isc_boolean_t 9544notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) { 9545 dns_tsigkey_t *key = NULL; 9546 isc_sockaddr_t src; 9547 isc_sockaddr_t any; 9548 isc_boolean_t isself; 9549 isc_netaddr_t dstaddr; 9550 isc_result_t result; 9551 9552 if (zone->view == NULL || zone->isself == NULL) 9553 return (ISC_FALSE); 9554 9555 switch (isc_sockaddr_pf(dst)) { 9556 case PF_INET: 9557 src = zone->notifysrc4; 9558 isc_sockaddr_any(&any); 9559 break; 9560 case PF_INET6: 9561 src = zone->notifysrc6; 9562 isc_sockaddr_any6(&any); 9563 break; 9564 default: 9565 return (ISC_FALSE); 9566 } 9567 9568 /* 9569 * When sending from any the kernel will assign a source address 9570 * that matches the destination address. 9571 */ 9572 if (isc_sockaddr_eqaddr(&any, &src)) 9573 src = *dst; 9574 9575 isc_netaddr_fromsockaddr(&dstaddr, dst); 9576 result = dns_view_getpeertsig(zone->view, &dstaddr, &key); 9577 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) 9578 return (ISC_FALSE); 9579 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass, 9580 zone->isselfarg); 9581 if (key != NULL) 9582 dns_tsigkey_detach(&key); 9583 return (isself); 9584} 9585 9586static void 9587notify_destroy(dns_notify_t *notify, isc_boolean_t locked) { 9588 isc_mem_t *mctx; 9589 9590 /* 9591 * Caller holds zone lock. 9592 */ 9593 REQUIRE(DNS_NOTIFY_VALID(notify)); 9594 9595 if (notify->zone != NULL) { 9596 if (!locked) 9597 LOCK_ZONE(notify->zone); 9598 REQUIRE(LOCKED_ZONE(notify->zone)); 9599 if (ISC_LINK_LINKED(notify, link)) 9600 ISC_LIST_UNLINK(notify->zone->notifies, notify, link); 9601 if (!locked) 9602 UNLOCK_ZONE(notify->zone); 9603 if (locked) 9604 zone_idetach(¬ify->zone); 9605 else 9606 dns_zone_idetach(¬ify->zone); 9607 } 9608 if (notify->find != NULL) 9609 dns_adb_destroyfind(¬ify->find); 9610 if (notify->request != NULL) 9611 dns_request_destroy(¬ify->request); 9612 if (dns_name_dynamic(¬ify->ns)) 9613 dns_name_free(¬ify->ns, notify->mctx); 9614 if (notify->key != NULL) 9615 dns_tsigkey_detach(¬ify->key); 9616 mctx = notify->mctx; 9617 isc_mem_put(notify->mctx, notify, sizeof(*notify)); 9618 isc_mem_detach(&mctx); 9619} 9620 9621static isc_result_t 9622notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) { 9623 dns_notify_t *notify; 9624 9625 REQUIRE(notifyp != NULL && *notifyp == NULL); 9626 9627 notify = isc_mem_get(mctx, sizeof(*notify)); 9628 if (notify == NULL) 9629 return (ISC_R_NOMEMORY); 9630 9631 notify->mctx = NULL; 9632 isc_mem_attach(mctx, ¬ify->mctx); 9633 notify->flags = flags; 9634 notify->zone = NULL; 9635 notify->find = NULL; 9636 notify->request = NULL; 9637 notify->key = NULL; 9638 isc_sockaddr_any(¬ify->dst); 9639 dns_name_init(¬ify->ns, NULL); 9640 ISC_LINK_INIT(notify, link); 9641 notify->magic = NOTIFY_MAGIC; 9642 *notifyp = notify; 9643 return (ISC_R_SUCCESS); 9644} 9645 9646/* 9647 * XXXAG should check for DNS_ZONEFLG_EXITING 9648 */ 9649static void 9650process_adb_event(isc_task_t *task, isc_event_t *ev) { 9651 dns_notify_t *notify; 9652 isc_eventtype_t result; 9653 9654 UNUSED(task); 9655 9656 notify = ev->ev_arg; 9657 REQUIRE(DNS_NOTIFY_VALID(notify)); 9658 INSIST(task == notify->zone->task); 9659 result = ev->ev_type; 9660 isc_event_free(&ev); 9661 if (result == DNS_EVENT_ADBMOREADDRESSES) { 9662 dns_adb_destroyfind(¬ify->find); 9663 notify_find_address(notify); 9664 return; 9665 } 9666 if (result == DNS_EVENT_ADBNOMOREADDRESSES) { 9667 LOCK_ZONE(notify->zone); 9668 notify_send(notify); 9669 UNLOCK_ZONE(notify->zone); 9670 } 9671 notify_destroy(notify, ISC_FALSE); 9672} 9673 9674static void 9675notify_find_address(dns_notify_t *notify) { 9676 isc_result_t result; 9677 unsigned int options; 9678 9679 REQUIRE(DNS_NOTIFY_VALID(notify)); 9680 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET | 9681 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME; 9682 9683 if (notify->zone->view->adb == NULL) 9684 goto destroy; 9685 9686 result = dns_adb_createfind(notify->zone->view->adb, 9687 notify->zone->task, 9688 process_adb_event, notify, 9689 ¬ify->ns, dns_rootname, 0, 9690 options, 0, NULL, 9691 notify->zone->view->dstport, 9692 ¬ify->find); 9693 9694 /* Something failed? */ 9695 if (result != ISC_R_SUCCESS) 9696 goto destroy; 9697 9698 /* More addresses pending? */ 9699 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) 9700 return; 9701 9702 /* We have as many addresses as we can get. */ 9703 LOCK_ZONE(notify->zone); 9704 notify_send(notify); 9705 UNLOCK_ZONE(notify->zone); 9706 9707 destroy: 9708 notify_destroy(notify, ISC_FALSE); 9709} 9710 9711 9712static isc_result_t 9713notify_send_queue(dns_notify_t *notify) { 9714 isc_event_t *e; 9715 isc_result_t result; 9716 9717 e = isc_event_allocate(notify->mctx, NULL, 9718 DNS_EVENT_NOTIFYSENDTOADDR, 9719 notify_send_toaddr, 9720 notify, sizeof(isc_event_t)); 9721 if (e == NULL) 9722 return (ISC_R_NOMEMORY); 9723 e->ev_arg = notify; 9724 e->ev_sender = NULL; 9725 result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl, 9726 notify->zone->task, &e); 9727 if (result != ISC_R_SUCCESS) 9728 isc_event_free(&e); 9729 return (result); 9730} 9731 9732static void 9733notify_send_toaddr(isc_task_t *task, isc_event_t *event) { 9734 dns_notify_t *notify; 9735 isc_result_t result; 9736 dns_message_t *message = NULL; 9737 isc_netaddr_t dstip; 9738 dns_tsigkey_t *key = NULL; 9739 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 9740 isc_sockaddr_t src; 9741 int timeout; 9742 isc_boolean_t have_notifysource = ISC_FALSE; 9743 9744 notify = event->ev_arg; 9745 REQUIRE(DNS_NOTIFY_VALID(notify)); 9746 9747 UNUSED(task); 9748 9749 LOCK_ZONE(notify->zone); 9750 9751 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) { 9752 result = ISC_R_CANCELED; 9753 goto cleanup; 9754 } 9755 9756 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 || 9757 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) || 9758 notify->zone->view->requestmgr == NULL || 9759 notify->zone->db == NULL) { 9760 result = ISC_R_CANCELED; 9761 goto cleanup; 9762 } 9763 9764 /* 9765 * The raw IPv4 address should also exist. Don't send to the 9766 * mapped form. 9767 */ 9768 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 && 9769 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) { 9770 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 9771 notify_log(notify->zone, ISC_LOG_DEBUG(3), 9772 "notify: ignoring IPv6 mapped IPV4 address: %s", 9773 addrbuf); 9774 result = ISC_R_CANCELED; 9775 goto cleanup; 9776 } 9777 9778 result = notify_createmessage(notify->zone, notify->flags, &message); 9779 if (result != ISC_R_SUCCESS) 9780 goto cleanup; 9781 9782 if (notify->key != NULL) { 9783 /* Transfer ownership of key */ 9784 key = notify->key; 9785 notify->key = NULL; 9786 } else { 9787 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst); 9788 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 9789 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key); 9790 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 9791 notify_log(notify->zone, ISC_LOG_ERROR, 9792 "NOTIFY to %s not sent. " 9793 "Peer TSIG key lookup failure.", addrbuf); 9794 goto cleanup_message; 9795 } 9796 } 9797 9798 /* XXX: should we log the tsig key too? */ 9799 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s", 9800 addrbuf); 9801 if (notify->zone->view->peers != NULL) { 9802 dns_peer_t *peer = NULL; 9803 result = dns_peerlist_peerbyaddr(notify->zone->view->peers, 9804 &dstip, &peer); 9805 if (result == ISC_R_SUCCESS) { 9806 result = dns_peer_getnotifysource(peer, &src); 9807 if (result == ISC_R_SUCCESS) 9808 have_notifysource = ISC_TRUE; 9809 } 9810 } 9811 switch (isc_sockaddr_pf(¬ify->dst)) { 9812 case PF_INET: 9813 if (!have_notifysource) 9814 src = notify->zone->notifysrc4; 9815 break; 9816 case PF_INET6: 9817 if (!have_notifysource) 9818 src = notify->zone->notifysrc6; 9819 break; 9820 default: 9821 result = ISC_R_NOTIMPLEMENTED; 9822 goto cleanup_key; 9823 } 9824 timeout = 15; 9825 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) 9826 timeout = 30; 9827 result = dns_request_createvia2(notify->zone->view->requestmgr, 9828 message, &src, ¬ify->dst, 0, key, 9829 timeout * 3, timeout, 9830 notify->zone->task, notify_done, 9831 notify, ¬ify->request); 9832 if (result == ISC_R_SUCCESS) { 9833 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) { 9834 inc_stats(notify->zone, 9835 dns_zonestatscounter_notifyoutv4); 9836 } else { 9837 inc_stats(notify->zone, 9838 dns_zonestatscounter_notifyoutv6); 9839 } 9840 } 9841 9842 cleanup_key: 9843 if (key != NULL) 9844 dns_tsigkey_detach(&key); 9845 cleanup_message: 9846 dns_message_destroy(&message); 9847 cleanup: 9848 UNLOCK_ZONE(notify->zone); 9849 isc_event_free(&event); 9850 if (result != ISC_R_SUCCESS) 9851 notify_destroy(notify, ISC_FALSE); 9852} 9853 9854static void 9855notify_send(dns_notify_t *notify) { 9856 dns_adbaddrinfo_t *ai; 9857 isc_sockaddr_t dst; 9858 isc_result_t result; 9859 dns_notify_t *new = NULL; 9860 9861 /* 9862 * Zone lock held by caller. 9863 */ 9864 REQUIRE(DNS_NOTIFY_VALID(notify)); 9865 REQUIRE(LOCKED_ZONE(notify->zone)); 9866 9867 for (ai = ISC_LIST_HEAD(notify->find->list); 9868 ai != NULL; 9869 ai = ISC_LIST_NEXT(ai, publink)) { 9870 dst = ai->sockaddr; 9871 if (notify_isqueued(notify->zone, NULL, &dst)) 9872 continue; 9873 if (notify_isself(notify->zone, &dst)) 9874 continue; 9875 new = NULL; 9876 result = notify_create(notify->mctx, 9877 (notify->flags & DNS_NOTIFY_NOSOA), 9878 &new); 9879 if (result != ISC_R_SUCCESS) 9880 goto cleanup; 9881 zone_iattach(notify->zone, &new->zone); 9882 ISC_LIST_APPEND(new->zone->notifies, new, link); 9883 new->dst = dst; 9884 result = notify_send_queue(new); 9885 if (result != ISC_R_SUCCESS) 9886 goto cleanup; 9887 new = NULL; 9888 } 9889 9890 cleanup: 9891 if (new != NULL) 9892 notify_destroy(new, ISC_TRUE); 9893} 9894 9895void 9896dns_zone_notify(dns_zone_t *zone) { 9897 isc_time_t now; 9898 9899 REQUIRE(DNS_ZONE_VALID(zone)); 9900 9901 LOCK_ZONE(zone); 9902 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 9903 9904 TIME_NOW(&now); 9905 zone_settimer(zone, &now); 9906 UNLOCK_ZONE(zone); 9907} 9908 9909static void 9910zone_notify(dns_zone_t *zone, isc_time_t *now) { 9911 dns_dbnode_t *node = NULL; 9912 dns_db_t *zonedb = NULL; 9913 dns_dbversion_t *version = NULL; 9914 dns_name_t *origin = NULL; 9915 dns_name_t master; 9916 dns_rdata_ns_t ns; 9917 dns_rdata_soa_t soa; 9918 isc_uint32_t serial; 9919 dns_rdata_t rdata = DNS_RDATA_INIT; 9920 dns_rdataset_t nsrdset; 9921 dns_rdataset_t soardset; 9922 isc_result_t result; 9923 dns_notify_t *notify = NULL; 9924 unsigned int i; 9925 isc_sockaddr_t dst; 9926 isc_boolean_t isqueued; 9927 dns_notifytype_t notifytype; 9928 unsigned int flags = 0; 9929 isc_boolean_t loggednotify = ISC_FALSE; 9930 9931 REQUIRE(DNS_ZONE_VALID(zone)); 9932 9933 LOCK_ZONE(zone); 9934 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 9935 notifytype = zone->notifytype; 9936 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime); 9937 UNLOCK_ZONE(zone); 9938 9939 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 9940 return; 9941 9942 if (notifytype == dns_notifytype_no) 9943 return; 9944 9945 if (notifytype == dns_notifytype_masteronly && 9946 zone->type != dns_zone_master) 9947 return; 9948 9949 origin = &zone->origin; 9950 9951 /* 9952 * If the zone is dialup we are done as we don't want to send 9953 * the current soa so as to force a refresh query. 9954 */ 9955 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) 9956 flags |= DNS_NOTIFY_NOSOA; 9957 9958 /* 9959 * Get SOA RRset. 9960 */ 9961 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9962 if (zone->db != NULL) 9963 dns_db_attach(zone->db, &zonedb); 9964 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9965 if (zonedb == NULL) 9966 return; 9967 dns_db_currentversion(zonedb, &version); 9968 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node); 9969 if (result != ISC_R_SUCCESS) 9970 goto cleanup1; 9971 9972 dns_rdataset_init(&soardset); 9973 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, 9974 dns_rdatatype_none, 0, &soardset, NULL); 9975 if (result != ISC_R_SUCCESS) 9976 goto cleanup2; 9977 9978 /* 9979 * Find serial and master server's name. 9980 */ 9981 dns_name_init(&master, NULL); 9982 result = dns_rdataset_first(&soardset); 9983 if (result != ISC_R_SUCCESS) 9984 goto cleanup3; 9985 dns_rdataset_current(&soardset, &rdata); 9986 result = dns_rdata_tostruct(&rdata, &soa, NULL); 9987 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9988 dns_rdata_reset(&rdata); 9989 result = dns_name_dup(&soa.origin, zone->mctx, &master); 9990 serial = soa.serial; 9991 dns_rdataset_disassociate(&soardset); 9992 if (result != ISC_R_SUCCESS) 9993 goto cleanup3; 9994 9995 /* 9996 * Enqueue notify requests for 'also-notify' servers. 9997 */ 9998 LOCK_ZONE(zone); 9999 for (i = 0; i < zone->notifycnt; i++) { 10000 dns_tsigkey_t *key = NULL; 10001 10002 dst = zone->notify[i]; 10003 if (notify_isqueued(zone, NULL, &dst)) 10004 continue; 10005 10006 result = notify_create(zone->mctx, flags, ¬ify); 10007 if (result != ISC_R_SUCCESS) 10008 continue; 10009 10010 zone_iattach(zone, ¬ify->zone); 10011 notify->dst = dst; 10012 10013 if ((zone->notifykeynames != NULL) && 10014 (zone->notifykeynames[i] != NULL)) { 10015 dns_view_t *view = dns_zone_getview(zone); 10016 dns_name_t *keyname = zone->notifykeynames[i]; 10017 result = dns_view_gettsig(view, keyname, &key); 10018 if (result == ISC_R_SUCCESS) { 10019 notify->key = key; 10020 key = NULL; 10021 } 10022 } 10023 10024 ISC_LIST_APPEND(zone->notifies, notify, link); 10025 result = notify_send_queue(notify); 10026 if (result != ISC_R_SUCCESS) 10027 notify_destroy(notify, ISC_TRUE); 10028 if (!loggednotify) { 10029 notify_log(zone, ISC_LOG_INFO, 10030 "sending notifies (serial %u)", 10031 serial); 10032 loggednotify = ISC_TRUE; 10033 } 10034 notify = NULL; 10035 } 10036 UNLOCK_ZONE(zone); 10037 10038 if (notifytype == dns_notifytype_explicit) 10039 goto cleanup3; 10040 10041 /* 10042 * Process NS RRset to generate notifies. 10043 */ 10044 10045 dns_rdataset_init(&nsrdset); 10046 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns, 10047 dns_rdatatype_none, 0, &nsrdset, NULL); 10048 if (result != ISC_R_SUCCESS) 10049 goto cleanup3; 10050 10051 result = dns_rdataset_first(&nsrdset); 10052 while (result == ISC_R_SUCCESS) { 10053 dns_rdataset_current(&nsrdset, &rdata); 10054 result = dns_rdata_tostruct(&rdata, &ns, NULL); 10055 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10056 dns_rdata_reset(&rdata); 10057 /* 10058 * Don't notify the master server unless explicitly 10059 * configured to do so. 10060 */ 10061 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) && 10062 dns_name_compare(&master, &ns.name) == 0) { 10063 result = dns_rdataset_next(&nsrdset); 10064 continue; 10065 } 10066 10067 if (!loggednotify) { 10068 notify_log(zone, ISC_LOG_INFO, 10069 "sending notifies (serial %u)", 10070 serial); 10071 loggednotify = ISC_TRUE; 10072 } 10073 10074 LOCK_ZONE(zone); 10075 isqueued = notify_isqueued(zone, &ns.name, NULL); 10076 UNLOCK_ZONE(zone); 10077 if (isqueued) { 10078 result = dns_rdataset_next(&nsrdset); 10079 continue; 10080 } 10081 result = notify_create(zone->mctx, flags, ¬ify); 10082 if (result != ISC_R_SUCCESS) 10083 continue; 10084 dns_zone_iattach(zone, ¬ify->zone); 10085 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns); 10086 if (result != ISC_R_SUCCESS) { 10087 LOCK_ZONE(zone); 10088 notify_destroy(notify, ISC_TRUE); 10089 UNLOCK_ZONE(zone); 10090 continue; 10091 } 10092 LOCK_ZONE(zone); 10093 ISC_LIST_APPEND(zone->notifies, notify, link); 10094 UNLOCK_ZONE(zone); 10095 notify_find_address(notify); 10096 notify = NULL; 10097 result = dns_rdataset_next(&nsrdset); 10098 } 10099 dns_rdataset_disassociate(&nsrdset); 10100 10101 cleanup3: 10102 if (dns_name_dynamic(&master)) 10103 dns_name_free(&master, zone->mctx); 10104 cleanup2: 10105 dns_db_detachnode(zonedb, &node); 10106 cleanup1: 10107 dns_db_closeversion(zonedb, &version, ISC_FALSE); 10108 dns_db_detach(&zonedb); 10109} 10110 10111/*** 10112 *** Private 10113 ***/ 10114 10115static inline isc_result_t 10116save_nsrrset(dns_message_t *message, dns_name_t *name, 10117 dns_db_t *db, dns_dbversion_t *version) 10118{ 10119 dns_rdataset_t *nsrdataset = NULL; 10120 dns_rdataset_t *rdataset = NULL; 10121 dns_dbnode_t *node = NULL; 10122 dns_rdata_ns_t ns; 10123 isc_result_t result; 10124 dns_rdata_t rdata = DNS_RDATA_INIT; 10125 10126 /* 10127 * Extract NS RRset from message. 10128 */ 10129 result = dns_message_findname(message, DNS_SECTION_ANSWER, name, 10130 dns_rdatatype_ns, dns_rdatatype_none, 10131 NULL, &nsrdataset); 10132 if (result != ISC_R_SUCCESS) 10133 goto fail; 10134 10135 /* 10136 * Add NS rdataset. 10137 */ 10138 result = dns_db_findnode(db, name, ISC_TRUE, &node); 10139 if (result != ISC_R_SUCCESS) 10140 goto fail; 10141 result = dns_db_addrdataset(db, node, version, 0, 10142 nsrdataset, 0, NULL); 10143 dns_db_detachnode(db, &node); 10144 if (result != ISC_R_SUCCESS) 10145 goto fail; 10146 /* 10147 * Add glue rdatasets. 10148 */ 10149 for (result = dns_rdataset_first(nsrdataset); 10150 result == ISC_R_SUCCESS; 10151 result = dns_rdataset_next(nsrdataset)) { 10152 dns_rdataset_current(nsrdataset, &rdata); 10153 result = dns_rdata_tostruct(&rdata, &ns, NULL); 10154 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10155 dns_rdata_reset(&rdata); 10156 if (!dns_name_issubdomain(&ns.name, name)) 10157 continue; 10158 rdataset = NULL; 10159 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL, 10160 &ns.name, dns_rdatatype_aaaa, 10161 dns_rdatatype_none, NULL, 10162 &rdataset); 10163 if (result == ISC_R_SUCCESS) { 10164 result = dns_db_findnode(db, &ns.name, 10165 ISC_TRUE, &node); 10166 if (result != ISC_R_SUCCESS) 10167 goto fail; 10168 result = dns_db_addrdataset(db, node, version, 0, 10169 rdataset, 0, NULL); 10170 dns_db_detachnode(db, &node); 10171 if (result != ISC_R_SUCCESS) 10172 goto fail; 10173 } 10174 rdataset = NULL; 10175 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL, 10176 &ns.name, dns_rdatatype_a, 10177 dns_rdatatype_none, NULL, 10178 &rdataset); 10179 if (result == ISC_R_SUCCESS) { 10180 result = dns_db_findnode(db, &ns.name, 10181 ISC_TRUE, &node); 10182 if (result != ISC_R_SUCCESS) 10183 goto fail; 10184 result = dns_db_addrdataset(db, node, version, 0, 10185 rdataset, 0, NULL); 10186 dns_db_detachnode(db, &node); 10187 if (result != ISC_R_SUCCESS) 10188 goto fail; 10189 } 10190 } 10191 if (result != ISC_R_NOMORE) 10192 goto fail; 10193 10194 return (ISC_R_SUCCESS); 10195 10196fail: 10197 return (result); 10198} 10199 10200static void 10201stub_callback(isc_task_t *task, isc_event_t *event) { 10202 const char me[] = "stub_callback"; 10203 dns_requestevent_t *revent = (dns_requestevent_t *)event; 10204 dns_stub_t *stub = NULL; 10205 dns_message_t *msg = NULL; 10206 dns_zone_t *zone = NULL; 10207 char master[ISC_SOCKADDR_FORMATSIZE]; 10208 char source[ISC_SOCKADDR_FORMATSIZE]; 10209 isc_uint32_t nscnt, cnamecnt, refresh, retry, expire; 10210 isc_result_t result; 10211 isc_time_t now; 10212 isc_boolean_t exiting = ISC_FALSE; 10213 isc_interval_t i; 10214 unsigned int j, soacount; 10215 10216 stub = revent->ev_arg; 10217 INSIST(DNS_STUB_VALID(stub)); 10218 10219 UNUSED(task); 10220 10221 zone = stub->zone; 10222 10223 ENTER; 10224 10225 TIME_NOW(&now); 10226 10227 LOCK_ZONE(zone); 10228 10229 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 10230 zone_debuglog(zone, me, 1, "exiting"); 10231 exiting = ISC_TRUE; 10232 goto next_master; 10233 } 10234 10235 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 10236 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 10237 10238 if (revent->result != ISC_R_SUCCESS) { 10239 if (revent->result == ISC_R_TIMEDOUT && 10240 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 10241 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 10242 dns_zone_log(zone, ISC_LOG_DEBUG(1), 10243 "refreshing stub: timeout retrying " 10244 " without EDNS master %s (source %s)", 10245 master, source); 10246 goto same_master; 10247 } 10248 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr, 10249 &zone->sourceaddr, &now); 10250 dns_zone_log(zone, ISC_LOG_INFO, 10251 "could not refresh stub from master %s" 10252 " (source %s): %s", master, source, 10253 dns_result_totext(revent->result)); 10254 goto next_master; 10255 } 10256 10257 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 10258 if (result != ISC_R_SUCCESS) 10259 goto next_master; 10260 10261 result = dns_request_getresponse(revent->request, msg, 0); 10262 if (result != ISC_R_SUCCESS) 10263 goto next_master; 10264 10265 /* 10266 * Unexpected rcode. 10267 */ 10268 if (msg->rcode != dns_rcode_noerror) { 10269 char rcode[128]; 10270 isc_buffer_t rb; 10271 10272 isc_buffer_init(&rb, rcode, sizeof(rcode)); 10273 (void)dns_rcode_totext(msg->rcode, &rb); 10274 10275 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 10276 (msg->rcode == dns_rcode_servfail || 10277 msg->rcode == dns_rcode_notimp || 10278 msg->rcode == dns_rcode_formerr)) { 10279 dns_zone_log(zone, ISC_LOG_DEBUG(1), 10280 "refreshing stub: rcode (%.*s) retrying " 10281 "without EDNS master %s (source %s)", 10282 (int)rb.used, rcode, master, source); 10283 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 10284 goto same_master; 10285 } 10286 10287 dns_zone_log(zone, ISC_LOG_INFO, 10288 "refreshing stub: " 10289 "unexpected rcode (%.*s) from %s (source %s)", 10290 (int)rb.used, rcode, master, source); 10291 goto next_master; 10292 } 10293 10294 /* 10295 * We need complete messages. 10296 */ 10297 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 10298 if (dns_request_usedtcp(revent->request)) { 10299 dns_zone_log(zone, ISC_LOG_INFO, 10300 "refreshing stub: truncated TCP " 10301 "response from master %s (source %s)", 10302 master, source); 10303 goto next_master; 10304 } 10305 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 10306 goto same_master; 10307 } 10308 10309 /* 10310 * If non-auth log and next master. 10311 */ 10312 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 10313 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " 10314 "non-authoritative answer from " 10315 "master %s (source %s)", master, source); 10316 goto next_master; 10317 } 10318 10319 /* 10320 * Sanity checks. 10321 */ 10322 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 10323 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns); 10324 10325 if (cnamecnt != 0) { 10326 dns_zone_log(zone, ISC_LOG_INFO, 10327 "refreshing stub: unexpected CNAME response " 10328 "from master %s (source %s)", master, source); 10329 goto next_master; 10330 } 10331 10332 if (nscnt == 0) { 10333 dns_zone_log(zone, ISC_LOG_INFO, 10334 "refreshing stub: no NS records in response " 10335 "from master %s (source %s)", master, source); 10336 goto next_master; 10337 } 10338 10339 /* 10340 * Save answer. 10341 */ 10342 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version); 10343 if (result != ISC_R_SUCCESS) { 10344 dns_zone_log(zone, ISC_LOG_INFO, 10345 "refreshing stub: unable to save NS records " 10346 "from master %s (source %s)", master, source); 10347 goto next_master; 10348 } 10349 10350 /* 10351 * Tidy up. 10352 */ 10353 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE); 10354 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 10355 if (zone->db == NULL) 10356 zone_attachdb(zone, stub->db); 10357 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, 10358 &refresh, &retry, &expire, NULL, NULL); 10359 if (result == ISC_R_SUCCESS && soacount > 0U) { 10360 zone->refresh = RANGE(refresh, zone->minrefresh, 10361 zone->maxrefresh); 10362 zone->retry = RANGE(retry, zone->minretry, zone->maxretry); 10363 zone->expire = RANGE(expire, zone->refresh + zone->retry, 10364 DNS_MAX_EXPIRE); 10365 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 10366 } 10367 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 10368 dns_db_detach(&stub->db); 10369 10370 dns_message_destroy(&msg); 10371 isc_event_free(&event); 10372 dns_request_destroy(&zone->request); 10373 10374 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 10375 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 10376 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 10377 isc_interval_set(&i, zone->expire, 0); 10378 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); 10379 10380 if (zone->masterfile != NULL) 10381 zone_needdump(zone, 0); 10382 10383 zone_settimer(zone, &now); 10384 goto free_stub; 10385 10386 next_master: 10387 if (stub->version != NULL) 10388 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE); 10389 if (stub->db != NULL) 10390 dns_db_detach(&stub->db); 10391 if (msg != NULL) 10392 dns_message_destroy(&msg); 10393 isc_event_free(&event); 10394 dns_request_destroy(&zone->request); 10395 /* 10396 * Skip to next failed / untried master. 10397 */ 10398 do { 10399 zone->curmaster++; 10400 } while (zone->curmaster < zone->masterscnt && 10401 zone->mastersok[zone->curmaster]); 10402 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 10403 if (exiting || zone->curmaster >= zone->masterscnt) { 10404 isc_boolean_t done = ISC_TRUE; 10405 if (!exiting && 10406 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 10407 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 10408 /* 10409 * Did we get a good answer from all the masters? 10410 */ 10411 for (j = 0; j < zone->masterscnt; j++) 10412 if (zone->mastersok[j] == ISC_FALSE) { 10413 done = ISC_FALSE; 10414 break; 10415 } 10416 } else 10417 done = ISC_TRUE; 10418 if (!done) { 10419 zone->curmaster = 0; 10420 /* 10421 * Find the next failed master. 10422 */ 10423 while (zone->curmaster < zone->masterscnt && 10424 zone->mastersok[zone->curmaster]) 10425 zone->curmaster++; 10426 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 10427 } else { 10428 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 10429 10430 zone_settimer(zone, &now); 10431 goto free_stub; 10432 } 10433 } 10434 queue_soa_query(zone); 10435 goto free_stub; 10436 10437 same_master: 10438 if (msg != NULL) 10439 dns_message_destroy(&msg); 10440 isc_event_free(&event); 10441 dns_request_destroy(&zone->request); 10442 ns_query(zone, NULL, stub); 10443 UNLOCK_ZONE(zone); 10444 goto done; 10445 10446 free_stub: 10447 UNLOCK_ZONE(zone); 10448 stub->magic = 0; 10449 dns_zone_idetach(&stub->zone); 10450 INSIST(stub->db == NULL); 10451 INSIST(stub->version == NULL); 10452 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 10453 10454 done: 10455 INSIST(event == NULL); 10456 return; 10457} 10458 10459/* 10460 * An SOA query has finished (successfully or not). 10461 */ 10462static void 10463refresh_callback(isc_task_t *task, isc_event_t *event) { 10464 const char me[] = "refresh_callback"; 10465 dns_requestevent_t *revent = (dns_requestevent_t *)event; 10466 dns_zone_t *zone; 10467 dns_message_t *msg = NULL; 10468 isc_uint32_t soacnt, cnamecnt, soacount, nscount; 10469 isc_time_t now; 10470 char master[ISC_SOCKADDR_FORMATSIZE]; 10471 char source[ISC_SOCKADDR_FORMATSIZE]; 10472 dns_rdataset_t *rdataset = NULL; 10473 dns_rdata_t rdata = DNS_RDATA_INIT; 10474 dns_rdata_soa_t soa; 10475 isc_result_t result; 10476 isc_uint32_t serial, oldserial = 0; 10477 unsigned int j; 10478 isc_boolean_t do_queue_xfrin = ISC_FALSE; 10479 10480 zone = revent->ev_arg; 10481 INSIST(DNS_ZONE_VALID(zone)); 10482 10483 UNUSED(task); 10484 10485 ENTER; 10486 10487 TIME_NOW(&now); 10488 10489 LOCK_ZONE(zone); 10490 10491 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 10492 isc_event_free(&event); 10493 dns_request_destroy(&zone->request); 10494 goto detach; 10495 } 10496 10497 /* 10498 * if timeout log and next master; 10499 */ 10500 10501 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 10502 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 10503 10504 if (revent->result != ISC_R_SUCCESS) { 10505 if (revent->result == ISC_R_TIMEDOUT && 10506 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 10507 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 10508 dns_zone_log(zone, ISC_LOG_DEBUG(1), 10509 "refresh: timeout retrying without EDNS " 10510 "master %s (source %s)", master, source); 10511 goto same_master; 10512 } 10513 if (revent->result == ISC_R_TIMEDOUT && 10514 !dns_request_usedtcp(revent->request)) { 10515 dns_zone_log(zone, ISC_LOG_INFO, 10516 "refresh: retry limit for " 10517 "master %s exceeded (source %s)", 10518 master, source); 10519 /* Try with slave with TCP. */ 10520 if ((zone->type == dns_zone_slave || 10521 zone->type == dns_zone_redirect) && 10522 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) { 10523 if (!dns_zonemgr_unreachable(zone->zmgr, 10524 &zone->masteraddr, 10525 &zone->sourceaddr, 10526 &now)) 10527 { 10528 DNS_ZONE_SETFLAG(zone, 10529 DNS_ZONEFLG_SOABEFOREAXFR); 10530 goto tcp_transfer; 10531 } 10532 dns_zone_log(zone, ISC_LOG_DEBUG(1), 10533 "refresh: skipped tcp fallback " 10534 "as master %s (source %s) is " 10535 "unreachable (cached)", 10536 master, source); 10537 } 10538 } else 10539 dns_zone_log(zone, ISC_LOG_INFO, 10540 "refresh: failure trying master " 10541 "%s (source %s): %s", master, source, 10542 dns_result_totext(revent->result)); 10543 goto next_master; 10544 } 10545 10546 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 10547 if (result != ISC_R_SUCCESS) 10548 goto next_master; 10549 result = dns_request_getresponse(revent->request, msg, 0); 10550 if (result != ISC_R_SUCCESS) { 10551 dns_zone_log(zone, ISC_LOG_INFO, 10552 "refresh: failure trying master " 10553 "%s (source %s): %s", master, source, 10554 dns_result_totext(result)); 10555 goto next_master; 10556 } 10557 10558 /* 10559 * Unexpected rcode. 10560 */ 10561 if (msg->rcode != dns_rcode_noerror) { 10562 char rcode[128]; 10563 isc_buffer_t rb; 10564 10565 isc_buffer_init(&rb, rcode, sizeof(rcode)); 10566 (void)dns_rcode_totext(msg->rcode, &rb); 10567 10568 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 10569 (msg->rcode == dns_rcode_servfail || 10570 msg->rcode == dns_rcode_notimp || 10571 msg->rcode == dns_rcode_formerr)) { 10572 dns_zone_log(zone, ISC_LOG_DEBUG(1), 10573 "refresh: rcode (%.*s) retrying without " 10574 "EDNS master %s (source %s)", 10575 (int)rb.used, rcode, master, source); 10576 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 10577 goto same_master; 10578 } 10579 dns_zone_log(zone, ISC_LOG_INFO, 10580 "refresh: unexpected rcode (%.*s) from " 10581 "master %s (source %s)", (int)rb.used, rcode, 10582 master, source); 10583 /* 10584 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't. 10585 */ 10586 if (msg->rcode == dns_rcode_refused && 10587 (zone->type == dns_zone_slave || 10588 zone->type == dns_zone_redirect)) 10589 goto tcp_transfer; 10590 goto next_master; 10591 } 10592 10593 /* 10594 * If truncated punt to zone transfer which will query again. 10595 */ 10596 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 10597 if (zone->type == dns_zone_slave || 10598 zone->type == dns_zone_redirect) { 10599 dns_zone_log(zone, ISC_LOG_INFO, 10600 "refresh: truncated UDP answer, " 10601 "initiating TCP zone xfer " 10602 "for master %s (source %s)", 10603 master, source); 10604 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 10605 goto tcp_transfer; 10606 } else { 10607 INSIST(zone->type == dns_zone_stub); 10608 if (dns_request_usedtcp(revent->request)) { 10609 dns_zone_log(zone, ISC_LOG_INFO, 10610 "refresh: truncated TCP response " 10611 "from master %s (source %s)", 10612 master, source); 10613 goto next_master; 10614 } 10615 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 10616 goto same_master; 10617 } 10618 } 10619 10620 /* 10621 * if non-auth log and next master; 10622 */ 10623 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 10624 dns_zone_log(zone, ISC_LOG_INFO, 10625 "refresh: non-authoritative answer from " 10626 "master %s (source %s)", master, source); 10627 goto next_master; 10628 } 10629 10630 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 10631 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa); 10632 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns); 10633 soacount = message_count(msg, DNS_SECTION_AUTHORITY, 10634 dns_rdatatype_soa); 10635 10636 /* 10637 * There should not be a CNAME record at top of zone. 10638 */ 10639 if (cnamecnt != 0) { 10640 dns_zone_log(zone, ISC_LOG_INFO, 10641 "refresh: CNAME at top of zone " 10642 "in master %s (source %s)", master, source); 10643 goto next_master; 10644 } 10645 10646 /* 10647 * if referral log and next master; 10648 */ 10649 if (soacnt == 0 && soacount == 0 && nscount != 0) { 10650 dns_zone_log(zone, ISC_LOG_INFO, 10651 "refresh: referral response " 10652 "from master %s (source %s)", master, source); 10653 goto next_master; 10654 } 10655 10656 /* 10657 * if nodata log and next master; 10658 */ 10659 if (soacnt == 0 && (nscount == 0 || soacount != 0)) { 10660 dns_zone_log(zone, ISC_LOG_INFO, 10661 "refresh: NODATA response " 10662 "from master %s (source %s)", master, source); 10663 goto next_master; 10664 } 10665 10666 /* 10667 * Only one soa at top of zone. 10668 */ 10669 if (soacnt != 1) { 10670 dns_zone_log(zone, ISC_LOG_INFO, 10671 "refresh: answer SOA count (%d) != 1 " 10672 "from master %s (source %s)", 10673 soacnt, master, source); 10674 goto next_master; 10675 } 10676 10677 /* 10678 * Extract serial 10679 */ 10680 rdataset = NULL; 10681 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin, 10682 dns_rdatatype_soa, dns_rdatatype_none, 10683 NULL, &rdataset); 10684 if (result != ISC_R_SUCCESS) { 10685 dns_zone_log(zone, ISC_LOG_INFO, 10686 "refresh: unable to get SOA record " 10687 "from master %s (source %s)", master, source); 10688 goto next_master; 10689 } 10690 10691 result = dns_rdataset_first(rdataset); 10692 if (result != ISC_R_SUCCESS) { 10693 dns_zone_log(zone, ISC_LOG_INFO, 10694 "refresh: dns_rdataset_first() failed"); 10695 goto next_master; 10696 } 10697 10698 dns_rdataset_current(rdataset, &rdata); 10699 result = dns_rdata_tostruct(&rdata, &soa, NULL); 10700 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10701 10702 serial = soa.serial; 10703 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 10704 unsigned int soacount; 10705 result = zone_get_from_db(zone, zone->db, NULL, &soacount, 10706 &oldserial, NULL, NULL, NULL, NULL, 10707 NULL); 10708 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10709 RUNTIME_CHECK(soacount > 0U); 10710 zone_debuglog(zone, me, 1, "serial: new %u, old %u", 10711 serial, oldserial); 10712 } else 10713 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded", 10714 serial); 10715 10716 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) || 10717 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) || 10718 isc_serial_gt(serial, oldserial)) { 10719 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, 10720 &zone->sourceaddr, &now)) 10721 { 10722 dns_zone_log(zone, ISC_LOG_INFO, 10723 "refresh: skipping %s as master %s " 10724 "(source %s) is unreachable (cached)", 10725 (zone->type == dns_zone_slave || 10726 zone->type == dns_zone_redirect) ? 10727 "zone transfer" : "NS query", 10728 master, source); 10729 goto next_master; 10730 } 10731 tcp_transfer: 10732 isc_event_free(&event); 10733 dns_request_destroy(&zone->request); 10734 if (zone->type == dns_zone_slave || 10735 zone->type == dns_zone_redirect) { 10736 do_queue_xfrin = ISC_TRUE; 10737 } else { 10738 INSIST(zone->type == dns_zone_stub); 10739 ns_query(zone, rdataset, NULL); 10740 } 10741 if (msg != NULL) 10742 dns_message_destroy(&msg); 10743 } else if (isc_serial_eq(soa.serial, oldserial)) { 10744 if (zone->masterfile != NULL) { 10745 result = ISC_R_FAILURE; 10746 if (zone->journal != NULL) 10747 result = isc_file_settime(zone->journal, &now); 10748 if (result == ISC_R_SUCCESS && 10749 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 10750 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 10751 result = isc_file_settime(zone->masterfile, 10752 &now); 10753 } else if (result != ISC_R_SUCCESS) 10754 result = isc_file_settime(zone->masterfile, 10755 &now); 10756 /* Someone removed the file from underneath us! */ 10757 if (result == ISC_R_FILENOTFOUND) { 10758 zone_needdump(zone, DNS_DUMP_DELAY); 10759 } else if (result != ISC_R_SUCCESS) 10760 dns_zone_log(zone, ISC_LOG_ERROR, 10761 "refresh: could not set file " 10762 "modification time of '%s': %s", 10763 zone->masterfile, 10764 dns_result_totext(result)); 10765 } 10766 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 10767 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); 10768 zone->mastersok[zone->curmaster] = ISC_TRUE; 10769 goto next_master; 10770 } else { 10771 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER)) 10772 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) " 10773 "received from master %s < ours (%u)", 10774 soa.serial, master, oldserial); 10775 else 10776 zone_debuglog(zone, me, 1, "ahead"); 10777 zone->mastersok[zone->curmaster] = ISC_TRUE; 10778 goto next_master; 10779 } 10780 if (msg != NULL) 10781 dns_message_destroy(&msg); 10782 goto detach; 10783 10784 next_master: 10785 if (msg != NULL) 10786 dns_message_destroy(&msg); 10787 isc_event_free(&event); 10788 dns_request_destroy(&zone->request); 10789 /* 10790 * Skip to next failed / untried master. 10791 */ 10792 do { 10793 zone->curmaster++; 10794 } while (zone->curmaster < zone->masterscnt && 10795 zone->mastersok[zone->curmaster]); 10796 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 10797 if (zone->curmaster >= zone->masterscnt) { 10798 isc_boolean_t done = ISC_TRUE; 10799 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 10800 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 10801 /* 10802 * Did we get a good answer from all the masters? 10803 */ 10804 for (j = 0; j < zone->masterscnt; j++) 10805 if (zone->mastersok[j] == ISC_FALSE) { 10806 done = ISC_FALSE; 10807 break; 10808 } 10809 } else 10810 done = ISC_TRUE; 10811 if (!done) { 10812 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 10813 zone->curmaster = 0; 10814 /* 10815 * Find the next failed master. 10816 */ 10817 while (zone->curmaster < zone->masterscnt && 10818 zone->mastersok[zone->curmaster]) 10819 zone->curmaster++; 10820 goto requeue; 10821 } 10822 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 10823 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 10824 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 10825 zone->refreshtime = now; 10826 } 10827 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 10828 zone_settimer(zone, &now); 10829 goto detach; 10830 } 10831 10832 requeue: 10833 queue_soa_query(zone); 10834 goto detach; 10835 10836 same_master: 10837 if (msg != NULL) 10838 dns_message_destroy(&msg); 10839 isc_event_free(&event); 10840 dns_request_destroy(&zone->request); 10841 queue_soa_query(zone); 10842 10843 detach: 10844 UNLOCK_ZONE(zone); 10845 if (do_queue_xfrin) 10846 queue_xfrin(zone); 10847 dns_zone_idetach(&zone); 10848 return; 10849} 10850 10851static void 10852queue_soa_query(dns_zone_t *zone) { 10853 const char me[] = "queue_soa_query"; 10854 isc_event_t *e; 10855 dns_zone_t *dummy = NULL; 10856 isc_result_t result; 10857 10858 ENTER; 10859 /* 10860 * Locked by caller 10861 */ 10862 REQUIRE(LOCKED_ZONE(zone)); 10863 10864 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 10865 cancel_refresh(zone); 10866 return; 10867 } 10868 10869 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE, 10870 soa_query, zone, sizeof(isc_event_t)); 10871 if (e == NULL) { 10872 cancel_refresh(zone); 10873 return; 10874 } 10875 10876 /* 10877 * Attach so that we won't clean up 10878 * until the event is delivered. 10879 */ 10880 zone_iattach(zone, &dummy); 10881 10882 e->ev_arg = zone; 10883 e->ev_sender = NULL; 10884 result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e); 10885 if (result != ISC_R_SUCCESS) { 10886 zone_idetach(&dummy); 10887 isc_event_free(&e); 10888 cancel_refresh(zone); 10889 } 10890} 10891 10892static inline isc_result_t 10893create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, 10894 dns_message_t **messagep) 10895{ 10896 dns_message_t *message = NULL; 10897 dns_name_t *qname = NULL; 10898 dns_rdataset_t *qrdataset = NULL; 10899 isc_result_t result; 10900 10901 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, 10902 &message); 10903 if (result != ISC_R_SUCCESS) 10904 goto cleanup; 10905 10906 message->opcode = dns_opcode_query; 10907 message->rdclass = zone->rdclass; 10908 10909 result = dns_message_gettempname(message, &qname); 10910 if (result != ISC_R_SUCCESS) 10911 goto cleanup; 10912 10913 result = dns_message_gettemprdataset(message, &qrdataset); 10914 if (result != ISC_R_SUCCESS) 10915 goto cleanup; 10916 10917 /* 10918 * Make question. 10919 */ 10920 dns_name_init(qname, NULL); 10921 dns_name_clone(&zone->origin, qname); 10922 dns_rdataset_init(qrdataset); 10923 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype); 10924 ISC_LIST_APPEND(qname->list, qrdataset, link); 10925 dns_message_addname(message, qname, DNS_SECTION_QUESTION); 10926 10927 *messagep = message; 10928 return (ISC_R_SUCCESS); 10929 10930 cleanup: 10931 if (qname != NULL) 10932 dns_message_puttempname(message, &qname); 10933 if (qrdataset != NULL) 10934 dns_message_puttemprdataset(message, &qrdataset); 10935 if (message != NULL) 10936 dns_message_destroy(&message); 10937 return (result); 10938} 10939 10940static isc_result_t 10941add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) { 10942 dns_rdataset_t *rdataset = NULL; 10943 dns_rdatalist_t *rdatalist = NULL; 10944 dns_rdata_t *rdata = NULL; 10945 isc_result_t result; 10946 10947 result = dns_message_gettemprdatalist(message, &rdatalist); 10948 if (result != ISC_R_SUCCESS) 10949 goto cleanup; 10950 result = dns_message_gettemprdata(message, &rdata); 10951 if (result != ISC_R_SUCCESS) 10952 goto cleanup; 10953 result = dns_message_gettemprdataset(message, &rdataset); 10954 if (result != ISC_R_SUCCESS) 10955 goto cleanup; 10956 dns_rdataset_init(rdataset); 10957 10958 rdatalist->type = dns_rdatatype_opt; 10959 rdatalist->covers = 0; 10960 10961 /* 10962 * Set Maximum UDP buffer size. 10963 */ 10964 rdatalist->rdclass = udpsize; 10965 10966 /* 10967 * Set EXTENDED-RCODE, VERSION, DO and Z to 0. 10968 */ 10969 rdatalist->ttl = 0; 10970 10971 /* Set EDNS options if applicable */ 10972 if (reqnsid) { 10973 unsigned char data[4]; 10974 isc_buffer_t buf; 10975 10976 isc_buffer_init(&buf, data, sizeof(data)); 10977 isc_buffer_putuint16(&buf, DNS_OPT_NSID); 10978 isc_buffer_putuint16(&buf, 0); 10979 rdata->data = data; 10980 rdata->length = sizeof(data); 10981 } else { 10982 rdata->data = NULL; 10983 rdata->length = 0; 10984 } 10985 10986 rdata->rdclass = rdatalist->rdclass; 10987 rdata->type = rdatalist->type; 10988 rdata->flags = 0; 10989 10990 ISC_LIST_INIT(rdatalist->rdata); 10991 ISC_LIST_APPEND(rdatalist->rdata, rdata, link); 10992 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) 10993 == ISC_R_SUCCESS); 10994 10995 return (dns_message_setopt(message, rdataset)); 10996 10997 cleanup: 10998 if (rdatalist != NULL) 10999 dns_message_puttemprdatalist(message, &rdatalist); 11000 if (rdataset != NULL) 11001 dns_message_puttemprdataset(message, &rdataset); 11002 if (rdata != NULL) 11003 dns_message_puttemprdata(message, &rdata); 11004 11005 return (result); 11006} 11007 11008static void 11009soa_query(isc_task_t *task, isc_event_t *event) { 11010 const char me[] = "soa_query"; 11011 isc_result_t result = ISC_R_FAILURE; 11012 dns_message_t *message = NULL; 11013 dns_zone_t *zone = event->ev_arg; 11014 dns_zone_t *dummy = NULL; 11015 isc_netaddr_t masterip; 11016 dns_tsigkey_t *key = NULL; 11017 isc_uint32_t options; 11018 isc_boolean_t cancel = ISC_TRUE; 11019 int timeout; 11020 isc_boolean_t have_xfrsource, reqnsid; 11021 isc_uint16_t udpsize = SEND_BUFFER_SIZE; 11022 11023 REQUIRE(DNS_ZONE_VALID(zone)); 11024 11025 UNUSED(task); 11026 11027 ENTER; 11028 11029 LOCK_ZONE(zone); 11030 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) || 11031 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || 11032 zone->view->requestmgr == NULL) { 11033 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 11034 cancel = ISC_FALSE; 11035 goto cleanup; 11036 } 11037 11038 /* 11039 * XXX Optimisation: Create message when zone is setup and reuse. 11040 */ 11041 result = create_query(zone, dns_rdatatype_soa, &message); 11042 if (result != ISC_R_SUCCESS) 11043 goto cleanup; 11044 11045 again: 11046 INSIST(zone->masterscnt > 0); 11047 INSIST(zone->curmaster < zone->masterscnt); 11048 11049 zone->masteraddr = zone->masters[zone->curmaster]; 11050 11051 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 11052 /* 11053 * First, look for a tsig key in the master statement, then 11054 * try for a server key. 11055 */ 11056 if ((zone->masterkeynames != NULL) && 11057 (zone->masterkeynames[zone->curmaster] != NULL)) { 11058 dns_view_t *view = dns_zone_getview(zone); 11059 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 11060 result = dns_view_gettsig(view, keyname, &key); 11061 if (result != ISC_R_SUCCESS) { 11062 char namebuf[DNS_NAME_FORMATSIZE]; 11063 dns_name_format(keyname, namebuf, sizeof(namebuf)); 11064 dns_zone_log(zone, ISC_LOG_ERROR, 11065 "unable to find key: %s", namebuf); 11066 goto skip_master; 11067 } 11068 } 11069 if (key == NULL) { 11070 result = dns_view_getpeertsig(zone->view, &masterip, &key); 11071 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 11072 char addrbuf[ISC_NETADDR_FORMATSIZE]; 11073 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf)); 11074 dns_zone_log(zone, ISC_LOG_ERROR, 11075 "unable to find TSIG key for %s", addrbuf); 11076 goto skip_master; 11077 } 11078 } 11079 11080 have_xfrsource = ISC_FALSE; 11081 reqnsid = zone->view->requestnsid; 11082 if (zone->view->peers != NULL) { 11083 dns_peer_t *peer = NULL; 11084 isc_boolean_t edns; 11085 result = dns_peerlist_peerbyaddr(zone->view->peers, 11086 &masterip, &peer); 11087 if (result == ISC_R_SUCCESS) { 11088 result = dns_peer_getsupportedns(peer, &edns); 11089 if (result == ISC_R_SUCCESS && !edns) 11090 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 11091 result = dns_peer_gettransfersource(peer, 11092 &zone->sourceaddr); 11093 if (result == ISC_R_SUCCESS) 11094 have_xfrsource = ISC_TRUE; 11095 if (zone->view->resolver != NULL) 11096 udpsize = 11097 dns_resolver_getudpsize(zone->view->resolver); 11098 (void)dns_peer_getudpsize(peer, &udpsize); 11099 (void)dns_peer_getrequestnsid(peer, &reqnsid); 11100 } 11101 } 11102 11103 switch (isc_sockaddr_pf(&zone->masteraddr)) { 11104 case PF_INET: 11105 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 11106 if (isc_sockaddr_equal(&zone->altxfrsource4, 11107 &zone->xfrsource4)) 11108 goto skip_master; 11109 zone->sourceaddr = zone->altxfrsource4; 11110 } else if (!have_xfrsource) 11111 zone->sourceaddr = zone->xfrsource4; 11112 break; 11113 case PF_INET6: 11114 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 11115 if (isc_sockaddr_equal(&zone->altxfrsource6, 11116 &zone->xfrsource6)) 11117 goto skip_master; 11118 zone->sourceaddr = zone->altxfrsource6; 11119 } else if (!have_xfrsource) 11120 zone->sourceaddr = zone->xfrsource6; 11121 break; 11122 default: 11123 result = ISC_R_NOTIMPLEMENTED; 11124 goto cleanup; 11125 } 11126 11127 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? 11128 DNS_REQUESTOPT_TCP : 0; 11129 11130 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 11131 result = add_opt(message, udpsize, reqnsid); 11132 if (result != ISC_R_SUCCESS) 11133 zone_debuglog(zone, me, 1, 11134 "unable to add opt record: %s", 11135 dns_result_totext(result)); 11136 } 11137 11138 zone_iattach(zone, &dummy); 11139 timeout = 15; 11140 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 11141 timeout = 30; 11142 result = dns_request_createvia2(zone->view->requestmgr, message, 11143 &zone->sourceaddr, &zone->masteraddr, 11144 options, key, timeout * 3, timeout, 11145 zone->task, refresh_callback, zone, 11146 &zone->request); 11147 if (result != ISC_R_SUCCESS) { 11148 zone_idetach(&dummy); 11149 zone_debuglog(zone, me, 1, 11150 "dns_request_createvia2() failed: %s", 11151 dns_result_totext(result)); 11152 goto cleanup; 11153 } else { 11154 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET) 11155 inc_stats(zone, dns_zonestatscounter_soaoutv4); 11156 else 11157 inc_stats(zone, dns_zonestatscounter_soaoutv6); 11158 } 11159 cancel = ISC_FALSE; 11160 11161 cleanup: 11162 if (key != NULL) 11163 dns_tsigkey_detach(&key); 11164 if (result != ISC_R_SUCCESS) 11165 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 11166 if (message != NULL) 11167 dns_message_destroy(&message); 11168 if (cancel) 11169 cancel_refresh(zone); 11170 isc_event_free(&event); 11171 UNLOCK_ZONE(zone); 11172 dns_zone_idetach(&zone); 11173 return; 11174 11175 skip_master: 11176 if (key != NULL) 11177 dns_tsigkey_detach(&key); 11178 /* 11179 * Skip to next failed / untried master. 11180 */ 11181 do { 11182 zone->curmaster++; 11183 } while (zone->curmaster < zone->masterscnt && 11184 zone->mastersok[zone->curmaster]); 11185 if (zone->curmaster < zone->masterscnt) 11186 goto again; 11187 zone->curmaster = 0; 11188 goto cleanup; 11189} 11190 11191static void 11192ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { 11193 const char me[] = "ns_query"; 11194 isc_result_t result; 11195 dns_message_t *message = NULL; 11196 isc_netaddr_t masterip; 11197 dns_tsigkey_t *key = NULL; 11198 dns_dbnode_t *node = NULL; 11199 int timeout; 11200 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid; 11201 isc_uint16_t udpsize = SEND_BUFFER_SIZE; 11202 11203 REQUIRE(DNS_ZONE_VALID(zone)); 11204 REQUIRE(LOCKED_ZONE(zone)); 11205 REQUIRE((soardataset != NULL && stub == NULL) || 11206 (soardataset == NULL && stub != NULL)); 11207 REQUIRE(stub == NULL || DNS_STUB_VALID(stub)); 11208 11209 ENTER; 11210 11211 if (stub == NULL) { 11212 stub = isc_mem_get(zone->mctx, sizeof(*stub)); 11213 if (stub == NULL) 11214 goto cleanup; 11215 stub->magic = STUB_MAGIC; 11216 stub->mctx = zone->mctx; 11217 stub->zone = NULL; 11218 stub->db = NULL; 11219 stub->version = NULL; 11220 11221 /* 11222 * Attach so that the zone won't disappear from under us. 11223 */ 11224 zone_iattach(zone, &stub->zone); 11225 11226 /* 11227 * If a db exists we will update it, otherwise we create a 11228 * new one and attach it to the zone once we have the NS 11229 * RRset and glue. 11230 */ 11231 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 11232 if (zone->db != NULL) { 11233 dns_db_attach(zone->db, &stub->db); 11234 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11235 } else { 11236 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11237 11238 INSIST(zone->db_argc >= 1); 11239 result = dns_db_create(zone->mctx, zone->db_argv[0], 11240 &zone->origin, dns_dbtype_stub, 11241 zone->rdclass, 11242 zone->db_argc - 1, 11243 zone->db_argv + 1, 11244 &stub->db); 11245 if (result != ISC_R_SUCCESS) { 11246 dns_zone_log(zone, ISC_LOG_ERROR, 11247 "refreshing stub: " 11248 "could not create " 11249 "database: %s", 11250 dns_result_totext(result)); 11251 goto cleanup; 11252 } 11253 dns_db_settask(stub->db, zone->task); 11254 } 11255 11256 result = dns_db_newversion(stub->db, &stub->version); 11257 if (result != ISC_R_SUCCESS) { 11258 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " 11259 "dns_db_newversion() failed: %s", 11260 dns_result_totext(result)); 11261 goto cleanup; 11262 } 11263 11264 /* 11265 * Update SOA record. 11266 */ 11267 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE, 11268 &node); 11269 if (result != ISC_R_SUCCESS) { 11270 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " 11271 "dns_db_findnode() failed: %s", 11272 dns_result_totext(result)); 11273 goto cleanup; 11274 } 11275 11276 result = dns_db_addrdataset(stub->db, node, stub->version, 0, 11277 soardataset, 0, NULL); 11278 dns_db_detachnode(stub->db, &node); 11279 if (result != ISC_R_SUCCESS) { 11280 dns_zone_log(zone, ISC_LOG_INFO, 11281 "refreshing stub: " 11282 "dns_db_addrdataset() failed: %s", 11283 dns_result_totext(result)); 11284 goto cleanup; 11285 } 11286 } 11287 11288 /* 11289 * XXX Optimisation: Create message when zone is setup and reuse. 11290 */ 11291 result = create_query(zone, dns_rdatatype_ns, &message); 11292 INSIST(result == ISC_R_SUCCESS); 11293 11294 INSIST(zone->masterscnt > 0); 11295 INSIST(zone->curmaster < zone->masterscnt); 11296 zone->masteraddr = zone->masters[zone->curmaster]; 11297 11298 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 11299 /* 11300 * First, look for a tsig key in the master statement, then 11301 * try for a server key. 11302 */ 11303 if ((zone->masterkeynames != NULL) && 11304 (zone->masterkeynames[zone->curmaster] != NULL)) { 11305 dns_view_t *view = dns_zone_getview(zone); 11306 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 11307 result = dns_view_gettsig(view, keyname, &key); 11308 if (result != ISC_R_SUCCESS) { 11309 char namebuf[DNS_NAME_FORMATSIZE]; 11310 dns_name_format(keyname, namebuf, sizeof(namebuf)); 11311 dns_zone_log(zone, ISC_LOG_ERROR, 11312 "unable to find key: %s", namebuf); 11313 } 11314 } 11315 if (key == NULL) 11316 (void)dns_view_getpeertsig(zone->view, &masterip, &key); 11317 11318 reqnsid = zone->view->requestnsid; 11319 if (zone->view->peers != NULL) { 11320 dns_peer_t *peer = NULL; 11321 isc_boolean_t edns; 11322 result = dns_peerlist_peerbyaddr(zone->view->peers, 11323 &masterip, &peer); 11324 if (result == ISC_R_SUCCESS) { 11325 result = dns_peer_getsupportedns(peer, &edns); 11326 if (result == ISC_R_SUCCESS && !edns) 11327 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 11328 result = dns_peer_gettransfersource(peer, 11329 &zone->sourceaddr); 11330 if (result == ISC_R_SUCCESS) 11331 have_xfrsource = ISC_TRUE; 11332 if (zone->view->resolver != NULL) 11333 udpsize = 11334 dns_resolver_getudpsize(zone->view->resolver); 11335 (void)dns_peer_getudpsize(peer, &udpsize); 11336 (void)dns_peer_getrequestnsid(peer, &reqnsid); 11337 } 11338 11339 } 11340 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 11341 result = add_opt(message, udpsize, reqnsid); 11342 if (result != ISC_R_SUCCESS) 11343 zone_debuglog(zone, me, 1, 11344 "unable to add opt record: %s", 11345 dns_result_totext(result)); 11346 } 11347 11348 /* 11349 * Always use TCP so that we shouldn't truncate in additional section. 11350 */ 11351 switch (isc_sockaddr_pf(&zone->masteraddr)) { 11352 case PF_INET: 11353 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) 11354 zone->sourceaddr = zone->altxfrsource4; 11355 else if (!have_xfrsource) 11356 zone->sourceaddr = zone->xfrsource4; 11357 break; 11358 case PF_INET6: 11359 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) 11360 zone->sourceaddr = zone->altxfrsource6; 11361 else if (!have_xfrsource) 11362 zone->sourceaddr = zone->xfrsource6; 11363 break; 11364 default: 11365 result = ISC_R_NOTIMPLEMENTED; 11366 POST(result); 11367 goto cleanup; 11368 } 11369 timeout = 15; 11370 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 11371 timeout = 30; 11372 result = dns_request_createvia2(zone->view->requestmgr, message, 11373 &zone->sourceaddr, &zone->masteraddr, 11374 DNS_REQUESTOPT_TCP, key, timeout * 3, 11375 timeout, zone->task, stub_callback, 11376 stub, &zone->request); 11377 if (result != ISC_R_SUCCESS) { 11378 zone_debuglog(zone, me, 1, 11379 "dns_request_createvia() failed: %s", 11380 dns_result_totext(result)); 11381 goto cleanup; 11382 } 11383 dns_message_destroy(&message); 11384 goto unlock; 11385 11386 cleanup: 11387 cancel_refresh(zone); 11388 if (stub != NULL) { 11389 stub->magic = 0; 11390 if (stub->version != NULL) 11391 dns_db_closeversion(stub->db, &stub->version, 11392 ISC_FALSE); 11393 if (stub->db != NULL) 11394 dns_db_detach(&stub->db); 11395 if (stub->zone != NULL) 11396 zone_idetach(&stub->zone); 11397 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 11398 } 11399 if (message != NULL) 11400 dns_message_destroy(&message); 11401 unlock: 11402 if (key != NULL) 11403 dns_tsigkey_detach(&key); 11404 return; 11405} 11406 11407/* 11408 * Handle the control event. Note that although this event causes the zone 11409 * to shut down, it is not a shutdown event in the sense of the task library. 11410 */ 11411static void 11412zone_shutdown(isc_task_t *task, isc_event_t *event) { 11413 dns_zone_t *zone = (dns_zone_t *) event->ev_arg; 11414 isc_boolean_t free_needed, linked = ISC_FALSE; 11415 dns_zone_t *raw = NULL, *secure = NULL; 11416 11417 UNUSED(task); 11418 REQUIRE(DNS_ZONE_VALID(zone)); 11419 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL); 11420 INSIST(isc_refcount_current(&zone->erefs) == 0); 11421 11422 zone_debuglog(zone, "zone_shutdown", 3, "shutting down"); 11423 11424 /* 11425 * Stop things being restarted after we cancel them below. 11426 */ 11427 LOCK_ZONE(zone); 11428 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING); 11429 UNLOCK_ZONE(zone); 11430 11431 /* 11432 * If we were waiting for xfrin quota, step out of 11433 * the queue. 11434 * If there's no zone manager, we can't be waiting for the 11435 * xfrin quota 11436 */ 11437 if (zone->zmgr != NULL) { 11438 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 11439 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) { 11440 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone, 11441 statelink); 11442 linked = ISC_TRUE; 11443 zone->statelist = NULL; 11444 } 11445 if (zone->statelist == &zone->zmgr->xfrin_in_progress) { 11446 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, 11447 statelink); 11448 zone->statelist = NULL; 11449 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE); 11450 } 11451 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 11452 } 11453 11454 /* 11455 * In task context, no locking required. See zone_xfrdone(). 11456 */ 11457 if (zone->xfr != NULL) 11458 dns_xfrin_shutdown(zone->xfr); 11459 11460 /* Safe to release the zone now */ 11461 if (zone->zmgr != NULL) 11462 dns_zonemgr_releasezone(zone->zmgr, zone); 11463 11464 LOCK_ZONE(zone); 11465 if (linked) { 11466 INSIST(zone->irefs > 0); 11467 zone->irefs--; 11468 } 11469 if (zone->request != NULL) { 11470 dns_request_cancel(zone->request); 11471 } 11472 11473 if (zone->readio != NULL) 11474 zonemgr_cancelio(zone->readio); 11475 11476 if (zone->lctx != NULL) 11477 dns_loadctx_cancel(zone->lctx); 11478 11479 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 11480 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 11481 if (zone->writeio != NULL) 11482 zonemgr_cancelio(zone->writeio); 11483 11484 if (zone->dctx != NULL) 11485 dns_dumpctx_cancel(zone->dctx); 11486 } 11487 11488 notify_cancel(zone); 11489 11490 forward_cancel(zone); 11491 11492 if (zone->timer != NULL) { 11493 isc_timer_detach(&zone->timer); 11494 INSIST(zone->irefs > 0); 11495 zone->irefs--; 11496 } 11497 11498 if (zone->view != NULL) 11499 dns_view_weakdetach(&zone->view); 11500 11501 /* 11502 * We have now canceled everything set the flag to allow exit_check() 11503 * to succeed. We must not unlock between setting this flag and 11504 * calling exit_check(). 11505 */ 11506 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN); 11507 free_needed = exit_check(zone); 11508 if (inline_secure(zone)) { 11509 raw = zone->raw; 11510 zone->raw = NULL; 11511 } 11512 if (inline_raw(zone)) { 11513 secure = zone->secure; 11514 zone->secure = NULL; 11515 } 11516 UNLOCK_ZONE(zone); 11517 if (raw != NULL) 11518 dns_zone_detach(&raw); 11519 if (secure != NULL) 11520 dns_zone_idetach(&secure); 11521 if (free_needed) 11522 zone_free(zone); 11523} 11524 11525static void 11526zone_timer(isc_task_t *task, isc_event_t *event) { 11527 const char me[] = "zone_timer"; 11528 dns_zone_t *zone = (dns_zone_t *)event->ev_arg; 11529 11530 UNUSED(task); 11531 REQUIRE(DNS_ZONE_VALID(zone)); 11532 11533 ENTER; 11534 11535 zone_maintenance(zone); 11536 11537 isc_event_free(&event); 11538} 11539 11540static void 11541zone_settimer(dns_zone_t *zone, isc_time_t *now) { 11542 const char me[] = "zone_settimer"; 11543 isc_time_t next; 11544 isc_result_t result; 11545 11546 ENTER; 11547 REQUIRE(DNS_ZONE_VALID(zone)); 11548 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 11549 return; 11550 11551 isc_time_settoepoch(&next); 11552 11553 switch (zone->type) { 11554 case dns_zone_redirect: 11555 if (zone->masters != NULL) 11556 goto treat_as_slave; 11557 /* FALLTHROUGH */ 11558 11559 case dns_zone_master: 11560 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) 11561 next = zone->notifytime; 11562 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 11563 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 11564 INSIST(!isc_time_isepoch(&zone->dumptime)); 11565 if (isc_time_isepoch(&next) || 11566 isc_time_compare(&zone->dumptime, &next) < 0) 11567 next = zone->dumptime; 11568 } 11569 if (zone->type == dns_zone_redirect) 11570 break; 11571 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) && 11572 !isc_time_isepoch(&zone->refreshkeytime)) { 11573 if (isc_time_isepoch(&next) || 11574 isc_time_compare(&zone->refreshkeytime, &next) < 0) 11575 next = zone->refreshkeytime; 11576 } 11577 if (!isc_time_isepoch(&zone->resigntime)) { 11578 if (isc_time_isepoch(&next) || 11579 isc_time_compare(&zone->resigntime, &next) < 0) 11580 next = zone->resigntime; 11581 } 11582 if (!isc_time_isepoch(&zone->keywarntime)) { 11583 if (isc_time_isepoch(&next) || 11584 isc_time_compare(&zone->keywarntime, &next) < 0) 11585 next = zone->keywarntime; 11586 } 11587 if (!isc_time_isepoch(&zone->signingtime)) { 11588 if (isc_time_isepoch(&next) || 11589 isc_time_compare(&zone->signingtime, &next) < 0) 11590 next = zone->signingtime; 11591 } 11592 if (!isc_time_isepoch(&zone->nsec3chaintime)) { 11593 if (isc_time_isepoch(&next) || 11594 isc_time_compare(&zone->nsec3chaintime, &next) < 0) 11595 next = zone->nsec3chaintime; 11596 } 11597 break; 11598 11599 case dns_zone_slave: 11600 treat_as_slave: 11601 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) 11602 next = zone->notifytime; 11603 /* FALLTHROUGH */ 11604 11605 case dns_zone_stub: 11606 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) && 11607 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) && 11608 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) && 11609 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { 11610 INSIST(!isc_time_isepoch(&zone->refreshtime)); 11611 if (isc_time_isepoch(&next) || 11612 isc_time_compare(&zone->refreshtime, &next) < 0) 11613 next = zone->refreshtime; 11614 } 11615 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 11616 !isc_time_isepoch(&zone->expiretime)) { 11617 if (isc_time_isepoch(&next) || 11618 isc_time_compare(&zone->expiretime, &next) < 0) 11619 next = zone->expiretime; 11620 } 11621 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 11622 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 11623 INSIST(!isc_time_isepoch(&zone->dumptime)); 11624 if (isc_time_isepoch(&next) || 11625 isc_time_compare(&zone->dumptime, &next) < 0) 11626 next = zone->dumptime; 11627 } 11628 break; 11629 11630 case dns_zone_key: 11631 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 11632 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 11633 INSIST(!isc_time_isepoch(&zone->dumptime)); 11634 if (isc_time_isepoch(&next) || 11635 isc_time_compare(&zone->dumptime, &next) < 0) 11636 next = zone->dumptime; 11637 } 11638 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) { 11639 if (isc_time_isepoch(&next) || 11640 (!isc_time_isepoch(&zone->refreshkeytime) && 11641 isc_time_compare(&zone->refreshkeytime, &next) < 0)) 11642 next = zone->refreshkeytime; 11643 } 11644 break; 11645 11646 default: 11647 break; 11648 } 11649 11650 if (isc_time_isepoch(&next)) { 11651 zone_debuglog(zone, me, 10, "settimer inactive"); 11652 result = isc_timer_reset(zone->timer, isc_timertype_inactive, 11653 NULL, NULL, ISC_TRUE); 11654 if (result != ISC_R_SUCCESS) 11655 dns_zone_log(zone, ISC_LOG_ERROR, 11656 "could not deactivate zone timer: %s", 11657 isc_result_totext(result)); 11658 } else { 11659 if (isc_time_compare(&next, now) <= 0) 11660 next = *now; 11661 result = isc_timer_reset(zone->timer, isc_timertype_once, 11662 &next, NULL, ISC_TRUE); 11663 if (result != ISC_R_SUCCESS) 11664 dns_zone_log(zone, ISC_LOG_ERROR, 11665 "could not reset zone timer: %s", 11666 isc_result_totext(result)); 11667 } 11668} 11669 11670static void 11671cancel_refresh(dns_zone_t *zone) { 11672 const char me[] = "cancel_refresh"; 11673 isc_time_t now; 11674 11675 /* 11676 * 'zone' locked by caller. 11677 */ 11678 11679 REQUIRE(DNS_ZONE_VALID(zone)); 11680 REQUIRE(LOCKED_ZONE(zone)); 11681 11682 ENTER; 11683 11684 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 11685 TIME_NOW(&now); 11686 zone_settimer(zone, &now); 11687} 11688 11689static isc_result_t 11690notify_createmessage(dns_zone_t *zone, unsigned int flags, 11691 dns_message_t **messagep) 11692{ 11693 dns_db_t *zonedb = NULL; 11694 dns_dbnode_t *node = NULL; 11695 dns_dbversion_t *version = NULL; 11696 dns_message_t *message = NULL; 11697 dns_rdataset_t rdataset; 11698 dns_rdata_t rdata = DNS_RDATA_INIT; 11699 11700 dns_name_t *tempname = NULL; 11701 dns_rdata_t *temprdata = NULL; 11702 dns_rdatalist_t *temprdatalist = NULL; 11703 dns_rdataset_t *temprdataset = NULL; 11704 11705 isc_result_t result; 11706 isc_region_t r; 11707 isc_buffer_t *b = NULL; 11708 11709 REQUIRE(DNS_ZONE_VALID(zone)); 11710 REQUIRE(messagep != NULL && *messagep == NULL); 11711 11712 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, 11713 &message); 11714 if (result != ISC_R_SUCCESS) 11715 return (result); 11716 11717 message->opcode = dns_opcode_notify; 11718 message->flags |= DNS_MESSAGEFLAG_AA; 11719 message->rdclass = zone->rdclass; 11720 11721 result = dns_message_gettempname(message, &tempname); 11722 if (result != ISC_R_SUCCESS) 11723 goto cleanup; 11724 11725 result = dns_message_gettemprdataset(message, &temprdataset); 11726 if (result != ISC_R_SUCCESS) 11727 goto cleanup; 11728 11729 /* 11730 * Make question. 11731 */ 11732 dns_name_init(tempname, NULL); 11733 dns_name_clone(&zone->origin, tempname); 11734 dns_rdataset_init(temprdataset); 11735 dns_rdataset_makequestion(temprdataset, zone->rdclass, 11736 dns_rdatatype_soa); 11737 ISC_LIST_APPEND(tempname->list, temprdataset, link); 11738 dns_message_addname(message, tempname, DNS_SECTION_QUESTION); 11739 tempname = NULL; 11740 temprdataset = NULL; 11741 11742 if ((flags & DNS_NOTIFY_NOSOA) != 0) 11743 goto done; 11744 11745 result = dns_message_gettempname(message, &tempname); 11746 if (result != ISC_R_SUCCESS) 11747 goto soa_cleanup; 11748 result = dns_message_gettemprdata(message, &temprdata); 11749 if (result != ISC_R_SUCCESS) 11750 goto soa_cleanup; 11751 result = dns_message_gettemprdataset(message, &temprdataset); 11752 if (result != ISC_R_SUCCESS) 11753 goto soa_cleanup; 11754 result = dns_message_gettemprdatalist(message, &temprdatalist); 11755 if (result != ISC_R_SUCCESS) 11756 goto soa_cleanup; 11757 11758 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 11759 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */ 11760 dns_db_attach(zone->db, &zonedb); 11761 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11762 11763 dns_name_init(tempname, NULL); 11764 dns_name_clone(&zone->origin, tempname); 11765 dns_db_currentversion(zonedb, &version); 11766 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node); 11767 if (result != ISC_R_SUCCESS) 11768 goto soa_cleanup; 11769 11770 dns_rdataset_init(&rdataset); 11771 result = dns_db_findrdataset(zonedb, node, version, 11772 dns_rdatatype_soa, 11773 dns_rdatatype_none, 0, &rdataset, 11774 NULL); 11775 if (result != ISC_R_SUCCESS) 11776 goto soa_cleanup; 11777 result = dns_rdataset_first(&rdataset); 11778 if (result != ISC_R_SUCCESS) 11779 goto soa_cleanup; 11780 dns_rdataset_current(&rdataset, &rdata); 11781 dns_rdata_toregion(&rdata, &r); 11782 result = isc_buffer_allocate(zone->mctx, &b, r.length); 11783 if (result != ISC_R_SUCCESS) 11784 goto soa_cleanup; 11785 isc_buffer_putmem(b, r.base, r.length); 11786 isc_buffer_usedregion(b, &r); 11787 dns_rdata_init(temprdata); 11788 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r); 11789 dns_message_takebuffer(message, &b); 11790 result = dns_rdataset_next(&rdataset); 11791 dns_rdataset_disassociate(&rdataset); 11792 if (result != ISC_R_NOMORE) 11793 goto soa_cleanup; 11794 temprdatalist->rdclass = rdata.rdclass; 11795 temprdatalist->type = rdata.type; 11796 temprdatalist->covers = 0; 11797 temprdatalist->ttl = rdataset.ttl; 11798 ISC_LIST_INIT(temprdatalist->rdata); 11799 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link); 11800 11801 dns_rdataset_init(temprdataset); 11802 result = dns_rdatalist_tordataset(temprdatalist, temprdataset); 11803 if (result != ISC_R_SUCCESS) 11804 goto soa_cleanup; 11805 11806 ISC_LIST_APPEND(tempname->list, temprdataset, link); 11807 dns_message_addname(message, tempname, DNS_SECTION_ANSWER); 11808 temprdatalist = NULL; 11809 temprdataset = NULL; 11810 temprdata = NULL; 11811 tempname = NULL; 11812 11813 soa_cleanup: 11814 if (node != NULL) 11815 dns_db_detachnode(zonedb, &node); 11816 if (version != NULL) 11817 dns_db_closeversion(zonedb, &version, ISC_FALSE); 11818 if (zonedb != NULL) 11819 dns_db_detach(&zonedb); 11820 if (tempname != NULL) 11821 dns_message_puttempname(message, &tempname); 11822 if (temprdata != NULL) 11823 dns_message_puttemprdata(message, &temprdata); 11824 if (temprdataset != NULL) 11825 dns_message_puttemprdataset(message, &temprdataset); 11826 if (temprdatalist != NULL) 11827 dns_message_puttemprdatalist(message, &temprdatalist); 11828 11829 done: 11830 *messagep = message; 11831 return (ISC_R_SUCCESS); 11832 11833 cleanup: 11834 if (tempname != NULL) 11835 dns_message_puttempname(message, &tempname); 11836 if (temprdataset != NULL) 11837 dns_message_puttemprdataset(message, &temprdataset); 11838 dns_message_destroy(&message); 11839 return (result); 11840} 11841 11842isc_result_t 11843dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, 11844 dns_message_t *msg) 11845{ 11846 unsigned int i; 11847 dns_rdata_soa_t soa; 11848 dns_rdataset_t *rdataset = NULL; 11849 dns_rdata_t rdata = DNS_RDATA_INIT; 11850 isc_result_t result; 11851 char fromtext[ISC_SOCKADDR_FORMATSIZE]; 11852 int match = 0; 11853 isc_netaddr_t netaddr; 11854 isc_sockaddr_t local, remote; 11855 11856 REQUIRE(DNS_ZONE_VALID(zone)); 11857 11858 /* 11859 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support 11860 * ROLLOVER. 11861 * 11862 * SOA: RFC1996 11863 * Check that 'from' is a valid notify source, (zone->masters). 11864 * Return DNS_R_REFUSED if not. 11865 * 11866 * If the notify message contains a serial number check it 11867 * against the zones serial and return if <= current serial 11868 * 11869 * If a refresh check is progress, if so just record the 11870 * fact we received a NOTIFY and from where and return. 11871 * We will perform a new refresh check when the current one 11872 * completes. Return ISC_R_SUCCESS. 11873 * 11874 * Otherwise initiate a refresh check using 'from' as the 11875 * first address to check. Return ISC_R_SUCCESS. 11876 */ 11877 11878 isc_sockaddr_format(from, fromtext, sizeof(fromtext)); 11879 11880 /* 11881 * Notify messages are processed by the raw zone. 11882 */ 11883 LOCK_ZONE(zone); 11884 if (inline_secure(zone)) { 11885 result = dns_zone_notifyreceive(zone->raw, from, msg); 11886 UNLOCK_ZONE(zone); 11887 return (result); 11888 } 11889 /* 11890 * We only handle NOTIFY (SOA) at the present. 11891 */ 11892 if (isc_sockaddr_pf(from) == PF_INET) 11893 inc_stats(zone, dns_zonestatscounter_notifyinv4); 11894 else 11895 inc_stats(zone, dns_zonestatscounter_notifyinv6); 11896 if (msg->counts[DNS_SECTION_QUESTION] == 0 || 11897 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin, 11898 dns_rdatatype_soa, dns_rdatatype_none, 11899 NULL, NULL) != ISC_R_SUCCESS) { 11900 UNLOCK_ZONE(zone); 11901 if (msg->counts[DNS_SECTION_QUESTION] == 0) { 11902 dns_zone_log(zone, ISC_LOG_NOTICE, 11903 "NOTIFY with no " 11904 "question section from: %s", fromtext); 11905 return (DNS_R_FORMERR); 11906 } 11907 dns_zone_log(zone, ISC_LOG_NOTICE, 11908 "NOTIFY zone does not match"); 11909 return (DNS_R_NOTIMP); 11910 } 11911 11912 /* 11913 * If we are a master zone just succeed. 11914 */ 11915 if (zone->type == dns_zone_master) { 11916 UNLOCK_ZONE(zone); 11917 return (ISC_R_SUCCESS); 11918 } 11919 11920 isc_netaddr_fromsockaddr(&netaddr, from); 11921 for (i = 0; i < zone->masterscnt; i++) { 11922 if (isc_sockaddr_eqaddr(from, &zone->masters[i])) 11923 break; 11924 if (zone->view->aclenv.match_mapped && 11925 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) && 11926 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) { 11927 isc_netaddr_t na1, na2; 11928 isc_netaddr_fromv4mapped(&na1, &netaddr); 11929 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]); 11930 if (isc_netaddr_equal(&na1, &na2)) 11931 break; 11932 } 11933 } 11934 11935 /* 11936 * Accept notify requests from non masters if they are on 11937 * 'zone->notify_acl'. 11938 */ 11939 if (i >= zone->masterscnt && zone->notify_acl != NULL && 11940 dns_acl_match(&netaddr, NULL, zone->notify_acl, 11941 &zone->view->aclenv, 11942 &match, NULL) == ISC_R_SUCCESS && 11943 match > 0) 11944 { 11945 /* Accept notify. */ 11946 } else if (i >= zone->masterscnt) { 11947 UNLOCK_ZONE(zone); 11948 dns_zone_log(zone, ISC_LOG_INFO, 11949 "refused notify from non-master: %s", fromtext); 11950 inc_stats(zone, dns_zonestatscounter_notifyrej); 11951 return (DNS_R_REFUSED); 11952 } 11953 11954 /* 11955 * If the zone is loaded and there are answers check the serial 11956 * to see if we need to do a refresh. Do not worry about this 11957 * check if we are a dialup zone as we use the notify request 11958 * to trigger a refresh check. 11959 */ 11960 if (msg->counts[DNS_SECTION_ANSWER] > 0 && 11961 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 11962 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) { 11963 result = dns_message_findname(msg, DNS_SECTION_ANSWER, 11964 &zone->origin, 11965 dns_rdatatype_soa, 11966 dns_rdatatype_none, NULL, 11967 &rdataset); 11968 if (result == ISC_R_SUCCESS) 11969 result = dns_rdataset_first(rdataset); 11970 if (result == ISC_R_SUCCESS) { 11971 isc_uint32_t serial = 0, oldserial; 11972 unsigned int soacount; 11973 11974 dns_rdataset_current(rdataset, &rdata); 11975 result = dns_rdata_tostruct(&rdata, &soa, NULL); 11976 RUNTIME_CHECK(result == ISC_R_SUCCESS); 11977 serial = soa.serial; 11978 /* 11979 * The following should safely be performed without DB 11980 * lock and succeed in this context. 11981 */ 11982 result = zone_get_from_db(zone, zone->db, NULL, 11983 &soacount, &oldserial, NULL, 11984 NULL, NULL, NULL, NULL); 11985 RUNTIME_CHECK(result == ISC_R_SUCCESS); 11986 RUNTIME_CHECK(soacount > 0U); 11987 if (isc_serial_le(serial, oldserial)) { 11988 dns_zone_log(zone, 11989 ISC_LOG_INFO, 11990 "notify from %s: " 11991 "zone is up to date", 11992 fromtext); 11993 UNLOCK_ZONE(zone); 11994 return (ISC_R_SUCCESS); 11995 } 11996 } 11997 } 11998 11999 /* 12000 * If we got this far and there was a refresh in progress just 12001 * let it complete. Record where we got the notify from so we 12002 * can perform a refresh check when the current one completes 12003 */ 12004 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { 12005 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 12006 zone->notifyfrom = *from; 12007 UNLOCK_ZONE(zone); 12008 dns_zone_log(zone, ISC_LOG_INFO, 12009 "notify from %s: refresh in progress, " 12010 "refresh check queued", 12011 fromtext); 12012 return (ISC_R_SUCCESS); 12013 } 12014 zone->notifyfrom = *from; 12015 local = zone->masteraddr; 12016 remote = zone->sourceaddr; 12017 UNLOCK_ZONE(zone); 12018 dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote); 12019 dns_zone_refresh(zone); 12020 return (ISC_R_SUCCESS); 12021} 12022 12023void 12024dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) { 12025 12026 REQUIRE(DNS_ZONE_VALID(zone)); 12027 12028 LOCK_ZONE(zone); 12029 if (zone->notify_acl != NULL) 12030 dns_acl_detach(&zone->notify_acl); 12031 dns_acl_attach(acl, &zone->notify_acl); 12032 UNLOCK_ZONE(zone); 12033} 12034 12035void 12036dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) { 12037 12038 REQUIRE(DNS_ZONE_VALID(zone)); 12039 12040 LOCK_ZONE(zone); 12041 if (zone->query_acl != NULL) 12042 dns_acl_detach(&zone->query_acl); 12043 dns_acl_attach(acl, &zone->query_acl); 12044 UNLOCK_ZONE(zone); 12045} 12046 12047void 12048dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) { 12049 12050 REQUIRE(DNS_ZONE_VALID(zone)); 12051 12052 LOCK_ZONE(zone); 12053 if (zone->queryon_acl != NULL) 12054 dns_acl_detach(&zone->queryon_acl); 12055 dns_acl_attach(acl, &zone->queryon_acl); 12056 UNLOCK_ZONE(zone); 12057} 12058 12059void 12060dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) { 12061 12062 REQUIRE(DNS_ZONE_VALID(zone)); 12063 12064 LOCK_ZONE(zone); 12065 if (zone->update_acl != NULL) 12066 dns_acl_detach(&zone->update_acl); 12067 dns_acl_attach(acl, &zone->update_acl); 12068 UNLOCK_ZONE(zone); 12069} 12070 12071void 12072dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) { 12073 12074 REQUIRE(DNS_ZONE_VALID(zone)); 12075 12076 LOCK_ZONE(zone); 12077 if (zone->forward_acl != NULL) 12078 dns_acl_detach(&zone->forward_acl); 12079 dns_acl_attach(acl, &zone->forward_acl); 12080 UNLOCK_ZONE(zone); 12081} 12082 12083void 12084dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) { 12085 12086 REQUIRE(DNS_ZONE_VALID(zone)); 12087 12088 LOCK_ZONE(zone); 12089 if (zone->xfr_acl != NULL) 12090 dns_acl_detach(&zone->xfr_acl); 12091 dns_acl_attach(acl, &zone->xfr_acl); 12092 UNLOCK_ZONE(zone); 12093} 12094 12095dns_acl_t * 12096dns_zone_getnotifyacl(dns_zone_t *zone) { 12097 12098 REQUIRE(DNS_ZONE_VALID(zone)); 12099 12100 return (zone->notify_acl); 12101} 12102 12103dns_acl_t * 12104dns_zone_getqueryacl(dns_zone_t *zone) { 12105 12106 REQUIRE(DNS_ZONE_VALID(zone)); 12107 12108 return (zone->query_acl); 12109} 12110 12111dns_acl_t * 12112dns_zone_getqueryonacl(dns_zone_t *zone) { 12113 12114 REQUIRE(DNS_ZONE_VALID(zone)); 12115 12116 return (zone->queryon_acl); 12117} 12118 12119dns_acl_t * 12120dns_zone_getupdateacl(dns_zone_t *zone) { 12121 12122 REQUIRE(DNS_ZONE_VALID(zone)); 12123 12124 return (zone->update_acl); 12125} 12126 12127dns_acl_t * 12128dns_zone_getforwardacl(dns_zone_t *zone) { 12129 12130 REQUIRE(DNS_ZONE_VALID(zone)); 12131 12132 return (zone->forward_acl); 12133} 12134 12135dns_acl_t * 12136dns_zone_getxfracl(dns_zone_t *zone) { 12137 12138 REQUIRE(DNS_ZONE_VALID(zone)); 12139 12140 return (zone->xfr_acl); 12141} 12142 12143void 12144dns_zone_clearupdateacl(dns_zone_t *zone) { 12145 12146 REQUIRE(DNS_ZONE_VALID(zone)); 12147 12148 LOCK_ZONE(zone); 12149 if (zone->update_acl != NULL) 12150 dns_acl_detach(&zone->update_acl); 12151 UNLOCK_ZONE(zone); 12152} 12153 12154void 12155dns_zone_clearforwardacl(dns_zone_t *zone) { 12156 12157 REQUIRE(DNS_ZONE_VALID(zone)); 12158 12159 LOCK_ZONE(zone); 12160 if (zone->forward_acl != NULL) 12161 dns_acl_detach(&zone->forward_acl); 12162 UNLOCK_ZONE(zone); 12163} 12164 12165void 12166dns_zone_clearnotifyacl(dns_zone_t *zone) { 12167 12168 REQUIRE(DNS_ZONE_VALID(zone)); 12169 12170 LOCK_ZONE(zone); 12171 if (zone->notify_acl != NULL) 12172 dns_acl_detach(&zone->notify_acl); 12173 UNLOCK_ZONE(zone); 12174} 12175 12176void 12177dns_zone_clearqueryacl(dns_zone_t *zone) { 12178 12179 REQUIRE(DNS_ZONE_VALID(zone)); 12180 12181 LOCK_ZONE(zone); 12182 if (zone->query_acl != NULL) 12183 dns_acl_detach(&zone->query_acl); 12184 UNLOCK_ZONE(zone); 12185} 12186 12187void 12188dns_zone_clearqueryonacl(dns_zone_t *zone) { 12189 12190 REQUIRE(DNS_ZONE_VALID(zone)); 12191 12192 LOCK_ZONE(zone); 12193 if (zone->queryon_acl != NULL) 12194 dns_acl_detach(&zone->queryon_acl); 12195 UNLOCK_ZONE(zone); 12196} 12197 12198void 12199dns_zone_clearxfracl(dns_zone_t *zone) { 12200 12201 REQUIRE(DNS_ZONE_VALID(zone)); 12202 12203 LOCK_ZONE(zone); 12204 if (zone->xfr_acl != NULL) 12205 dns_acl_detach(&zone->xfr_acl); 12206 UNLOCK_ZONE(zone); 12207} 12208 12209isc_boolean_t 12210dns_zone_getupdatedisabled(dns_zone_t *zone) { 12211 REQUIRE(DNS_ZONE_VALID(zone)); 12212 return (zone->update_disabled); 12213 12214} 12215 12216void 12217dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) { 12218 REQUIRE(DNS_ZONE_VALID(zone)); 12219 zone->update_disabled = state; 12220} 12221 12222isc_boolean_t 12223dns_zone_getzeronosoattl(dns_zone_t *zone) { 12224 REQUIRE(DNS_ZONE_VALID(zone)); 12225 return (zone->zero_no_soa_ttl); 12226 12227} 12228 12229void 12230dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) { 12231 REQUIRE(DNS_ZONE_VALID(zone)); 12232 zone->zero_no_soa_ttl = state; 12233} 12234 12235void 12236dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) { 12237 12238 REQUIRE(DNS_ZONE_VALID(zone)); 12239 12240 zone->check_names = severity; 12241} 12242 12243dns_severity_t 12244dns_zone_getchecknames(dns_zone_t *zone) { 12245 12246 REQUIRE(DNS_ZONE_VALID(zone)); 12247 12248 return (zone->check_names); 12249} 12250 12251void 12252dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) { 12253 12254 REQUIRE(DNS_ZONE_VALID(zone)); 12255 12256 zone->journalsize = size; 12257} 12258 12259isc_int32_t 12260dns_zone_getjournalsize(dns_zone_t *zone) { 12261 12262 REQUIRE(DNS_ZONE_VALID(zone)); 12263 12264 return (zone->journalsize); 12265} 12266 12267static void 12268zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) { 12269 isc_result_t result = ISC_R_FAILURE; 12270 isc_buffer_t buffer; 12271 12272 REQUIRE(buf != NULL); 12273 REQUIRE(length > 1U); 12274 12275 /* 12276 * Leave space for terminating '\0'. 12277 */ 12278 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 12279 if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) { 12280 if (dns_name_dynamic(&zone->origin)) 12281 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); 12282 if (result != ISC_R_SUCCESS && 12283 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1)) 12284 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 12285 12286 if (isc_buffer_availablelength(&buffer) > 0) 12287 isc_buffer_putstr(&buffer, "/"); 12288 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 12289 } 12290 12291 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 && 12292 strcmp(zone->view->name, "_default") != 0 && 12293 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) { 12294 isc_buffer_putstr(&buffer, "/"); 12295 isc_buffer_putstr(&buffer, zone->view->name); 12296 } 12297 if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer)) 12298 isc_buffer_putstr(&buffer, " (signed)"); 12299 if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer)) 12300 isc_buffer_putstr(&buffer, " (unsigned)"); 12301 12302 buf[isc_buffer_usedlength(&buffer)] = '\0'; 12303} 12304 12305static void 12306zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) { 12307 isc_result_t result = ISC_R_FAILURE; 12308 isc_buffer_t buffer; 12309 12310 REQUIRE(buf != NULL); 12311 REQUIRE(length > 1U); 12312 12313 /* 12314 * Leave space for terminating '\0'. 12315 */ 12316 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 12317 if (dns_name_dynamic(&zone->origin)) 12318 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); 12319 if (result != ISC_R_SUCCESS && 12320 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1)) 12321 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 12322 12323 buf[isc_buffer_usedlength(&buffer)] = '\0'; 12324} 12325 12326static void 12327zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) { 12328 isc_buffer_t buffer; 12329 12330 REQUIRE(buf != NULL); 12331 REQUIRE(length > 1U); 12332 12333 /* 12334 * Leave space for terminating '\0'. 12335 */ 12336 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 12337 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 12338 12339 buf[isc_buffer_usedlength(&buffer)] = '\0'; 12340} 12341 12342static void 12343zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) { 12344 isc_buffer_t buffer; 12345 12346 REQUIRE(buf != NULL); 12347 REQUIRE(length > 1U); 12348 12349 12350 /* 12351 * Leave space for terminating '\0'. 12352 */ 12353 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 12354 12355 if (zone->view == NULL) { 12356 isc_buffer_putstr(&buffer, "_none"); 12357 } else if (strlen(zone->view->name) 12358 < isc_buffer_availablelength(&buffer)) { 12359 isc_buffer_putstr(&buffer, zone->view->name); 12360 } else { 12361 isc_buffer_putstr(&buffer, "_toolong"); 12362 } 12363 12364 buf[isc_buffer_usedlength(&buffer)] = '\0'; 12365} 12366 12367void 12368dns_zone_name(dns_zone_t *zone, char *buf, size_t length) { 12369 REQUIRE(DNS_ZONE_VALID(zone)); 12370 REQUIRE(buf != NULL); 12371 zone_namerd_tostr(zone, buf, length); 12372} 12373 12374static void 12375notify_log(dns_zone_t *zone, int level, const char *fmt, ...) { 12376 va_list ap; 12377 char message[4096]; 12378 12379 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 12380 return; 12381 12382 va_start(ap, fmt); 12383 vsnprintf(message, sizeof(message), fmt, ap); 12384 va_end(ap); 12385 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE, 12386 level, "zone %s: %s", zone->strnamerd, message); 12387} 12388 12389void 12390dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, 12391 int level, const char *fmt, ...) { 12392 va_list ap; 12393 char message[4096]; 12394 12395 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 12396 return; 12397 12398 va_start(ap, fmt); 12399 vsnprintf(message, sizeof(message), fmt, ap); 12400 va_end(ap); 12401 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, 12402 level, "%s%s: %s", (zone->type == dns_zone_key) ? 12403 "managed-keys-zone" : (zone->type == dns_zone_redirect) ? 12404 "redirect-zone" : "zone ", zone->strnamerd, message); 12405} 12406 12407void 12408dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) { 12409 va_list ap; 12410 char message[4096]; 12411 12412 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 12413 return; 12414 12415 va_start(ap, fmt); 12416 vsnprintf(message, sizeof(message), fmt, ap); 12417 va_end(ap); 12418 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, 12419 level, "%s%s: %s", (zone->type == dns_zone_key) ? 12420 "managed-keys-zone" : (zone->type == dns_zone_redirect) ? 12421 "redirect-zone" : "zone ", zone->strnamerd, message); 12422} 12423 12424static void 12425zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel, 12426 const char *fmt, ...) 12427{ 12428 va_list ap; 12429 char message[4096]; 12430 int level = ISC_LOG_DEBUG(debuglevel); 12431 const char *zstr; 12432 12433 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 12434 return; 12435 12436 va_start(ap, fmt); 12437 vsnprintf(message, sizeof(message), fmt, ap); 12438 va_end(ap); 12439 12440 switch (zone->type) { 12441 case dns_zone_key: 12442 zstr = "managed-keys-zone"; 12443 break; 12444 case dns_zone_redirect: 12445 zstr = "redirect-zone"; 12446 break; 12447 default: 12448 zstr = "zone"; 12449 } 12450 12451 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, 12452 level, "%s: %s %s: %s", me, zstr, zone->strnamerd, 12453 message); 12454} 12455 12456static int 12457message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type) 12458{ 12459 isc_result_t result; 12460 dns_name_t *name; 12461 dns_rdataset_t *curr; 12462 int count = 0; 12463 12464 result = dns_message_firstname(msg, section); 12465 while (result == ISC_R_SUCCESS) { 12466 name = NULL; 12467 dns_message_currentname(msg, section, &name); 12468 12469 for (curr = ISC_LIST_TAIL(name->list); curr != NULL; 12470 curr = ISC_LIST_PREV(curr, link)) { 12471 if (curr->type == type) 12472 count++; 12473 } 12474 result = dns_message_nextname(msg, section); 12475 } 12476 12477 return (count); 12478} 12479 12480void 12481dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) { 12482 REQUIRE(DNS_ZONE_VALID(zone)); 12483 12484 zone->maxxfrin = maxxfrin; 12485} 12486 12487isc_uint32_t 12488dns_zone_getmaxxfrin(dns_zone_t *zone) { 12489 REQUIRE(DNS_ZONE_VALID(zone)); 12490 12491 return (zone->maxxfrin); 12492} 12493 12494void 12495dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) { 12496 REQUIRE(DNS_ZONE_VALID(zone)); 12497 zone->maxxfrout = maxxfrout; 12498} 12499 12500isc_uint32_t 12501dns_zone_getmaxxfrout(dns_zone_t *zone) { 12502 REQUIRE(DNS_ZONE_VALID(zone)); 12503 12504 return (zone->maxxfrout); 12505} 12506 12507dns_zonetype_t 12508dns_zone_gettype(dns_zone_t *zone) { 12509 REQUIRE(DNS_ZONE_VALID(zone)); 12510 12511 return (zone->type); 12512} 12513 12514dns_name_t * 12515dns_zone_getorigin(dns_zone_t *zone) { 12516 REQUIRE(DNS_ZONE_VALID(zone)); 12517 12518 return (&zone->origin); 12519} 12520 12521void 12522dns_zone_settask(dns_zone_t *zone, isc_task_t *task) { 12523 REQUIRE(DNS_ZONE_VALID(zone)); 12524 12525 LOCK_ZONE(zone); 12526 if (zone->task != NULL) 12527 isc_task_detach(&zone->task); 12528 isc_task_attach(task, &zone->task); 12529 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12530 if (zone->db != NULL) 12531 dns_db_settask(zone->db, zone->task); 12532 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12533 UNLOCK_ZONE(zone); 12534} 12535 12536void 12537dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) { 12538 REQUIRE(DNS_ZONE_VALID(zone)); 12539 isc_task_attach(zone->task, target); 12540} 12541 12542void 12543dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) { 12544 REQUIRE(DNS_ZONE_VALID(zone)); 12545 12546 if (idlein == 0) 12547 idlein = DNS_DEFAULT_IDLEIN; 12548 zone->idlein = idlein; 12549} 12550 12551isc_uint32_t 12552dns_zone_getidlein(dns_zone_t *zone) { 12553 REQUIRE(DNS_ZONE_VALID(zone)); 12554 12555 return (zone->idlein); 12556} 12557 12558void 12559dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) { 12560 REQUIRE(DNS_ZONE_VALID(zone)); 12561 12562 zone->idleout = idleout; 12563} 12564 12565isc_uint32_t 12566dns_zone_getidleout(dns_zone_t *zone) { 12567 REQUIRE(DNS_ZONE_VALID(zone)); 12568 12569 return (zone->idleout); 12570} 12571 12572static void 12573notify_done(isc_task_t *task, isc_event_t *event) { 12574 dns_requestevent_t *revent = (dns_requestevent_t *)event; 12575 dns_notify_t *notify; 12576 isc_result_t result; 12577 dns_message_t *message = NULL; 12578 isc_buffer_t buf; 12579 char rcode[128]; 12580 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 12581 12582 UNUSED(task); 12583 12584 notify = event->ev_arg; 12585 REQUIRE(DNS_NOTIFY_VALID(notify)); 12586 INSIST(task == notify->zone->task); 12587 12588 isc_buffer_init(&buf, rcode, sizeof(rcode)); 12589 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 12590 12591 result = revent->result; 12592 if (result == ISC_R_SUCCESS) 12593 result = dns_message_create(notify->zone->mctx, 12594 DNS_MESSAGE_INTENTPARSE, &message); 12595 if (result == ISC_R_SUCCESS) 12596 result = dns_request_getresponse(revent->request, message, 12597 DNS_MESSAGEPARSE_PRESERVEORDER); 12598 if (result == ISC_R_SUCCESS) 12599 result = dns_rcode_totext(message->rcode, &buf); 12600 if (result == ISC_R_SUCCESS) 12601 notify_log(notify->zone, ISC_LOG_DEBUG(3), 12602 "notify response from %s: %.*s", 12603 addrbuf, (int)buf.used, rcode); 12604 else 12605 notify_log(notify->zone, ISC_LOG_DEBUG(2), 12606 "notify to %s failed: %s", addrbuf, 12607 dns_result_totext(result)); 12608 12609 /* 12610 * Old bind's return formerr if they see a soa record. Retry w/o 12611 * the soa if we see a formerr and had sent a SOA. 12612 */ 12613 isc_event_free(&event); 12614 if (message != NULL && message->rcode == dns_rcode_formerr && 12615 (notify->flags & DNS_NOTIFY_NOSOA) == 0) { 12616 notify->flags |= DNS_NOTIFY_NOSOA; 12617 dns_request_destroy(¬ify->request); 12618 result = notify_send_queue(notify); 12619 if (result != ISC_R_SUCCESS) 12620 notify_destroy(notify, ISC_FALSE); 12621 } else { 12622 if (result == ISC_R_TIMEDOUT) 12623 notify_log(notify->zone, ISC_LOG_DEBUG(1), 12624 "notify to %s: retries exceeded", addrbuf); 12625 notify_destroy(notify, ISC_FALSE); 12626 } 12627 if (message != NULL) 12628 dns_message_destroy(&message); 12629} 12630 12631struct secure_event { 12632 isc_event_t e; 12633 dns_db_t *db; 12634 isc_uint32_t serial; 12635}; 12636 12637static void 12638update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) { 12639 UNUSED(arg); 12640 dns_zone_log(zone, level, "%s", message); 12641} 12642 12643static isc_result_t 12644sync_secure_journal(dns_zone_t *zone, dns_journal_t *journal, 12645 isc_uint32_t start, isc_uint32_t end, 12646 dns_difftuple_t **soatuplep, dns_diff_t *diff) 12647{ 12648 isc_result_t result; 12649 dns_difftuple_t *tuple = NULL; 12650 dns_diffop_t op = DNS_DIFFOP_ADD; 12651 int n_soa = 0; 12652 12653 REQUIRE(soatuplep != NULL); 12654 12655 if (start == end) 12656 return (DNS_R_UNCHANGED); 12657 12658 CHECK(dns_journal_iter_init(journal, start, end)); 12659 for (result = dns_journal_first_rr(journal); 12660 result == ISC_R_SUCCESS; 12661 result = dns_journal_next_rr(journal)) 12662 { 12663 dns_name_t *name = NULL; 12664 isc_uint32_t ttl; 12665 dns_rdata_t *rdata = NULL; 12666 dns_journal_current_rr(journal, &name, &ttl, &rdata); 12667 12668 if (rdata->type == dns_rdatatype_soa) { 12669 n_soa++; 12670 if (n_soa == 2) { 12671 /* 12672 * Save the latest raw SOA record. 12673 */ 12674 if (*soatuplep != NULL) 12675 dns_difftuple_free(soatuplep); 12676 CHECK(dns_difftuple_create(diff->mctx, 12677 DNS_DIFFOP_ADD, 12678 name, ttl, rdata, 12679 soatuplep)); 12680 } 12681 if (n_soa == 3) 12682 n_soa = 1; 12683 continue; 12684 } 12685 12686 /* Sanity. */ 12687 if (n_soa == 0) { 12688 dns_zone_log(zone->raw, ISC_LOG_ERROR, 12689 "corrupt journal file: '%s'\n", 12690 zone->raw->journal); 12691 return (ISC_R_FAILURE); 12692 } 12693 12694 if (zone->privatetype != 0 && 12695 rdata->type == zone->privatetype) 12696 continue; 12697 12698 if (rdata->type == dns_rdatatype_nsec || 12699 rdata->type == dns_rdatatype_rrsig || 12700 rdata->type == dns_rdatatype_nsec3 || 12701 rdata->type == dns_rdatatype_dnskey || 12702 rdata->type == dns_rdatatype_nsec3param) 12703 continue; 12704 12705 op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD; 12706 12707 CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata, 12708 &tuple)); 12709 dns_diff_appendminimal(diff, &tuple); 12710 } 12711 if (result == ISC_R_NOMORE) 12712 result = ISC_R_SUCCESS; 12713 12714 failure: 12715 return(result); 12716} 12717 12718static isc_result_t 12719sync_secure_db(dns_zone_t *seczone, dns_db_t *secdb, 12720 dns_dbversion_t *secver, dns_difftuple_t **soatuple, 12721 dns_diff_t *diff) 12722{ 12723 isc_result_t result; 12724 dns_db_t *rawdb = NULL; 12725 dns_dbversion_t *rawver = NULL; 12726 dns_difftuple_t *tuple = NULL, *next; 12727 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL; 12728 dns_rdata_soa_t oldsoa, newsoa; 12729 12730 REQUIRE(DNS_ZONE_VALID(seczone)); 12731 REQUIRE(inline_secure(seczone)); 12732 REQUIRE(soatuple != NULL && *soatuple == NULL); 12733 12734 if (!seczone->sourceserialset) 12735 return (DNS_R_UNCHANGED); 12736 12737 dns_db_attach(seczone->raw->db, &rawdb); 12738 dns_db_currentversion(rawdb, &rawver); 12739 result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL); 12740 dns_db_closeversion(rawdb, &rawver, ISC_FALSE); 12741 dns_db_detach(&rawdb); 12742 12743 if (result != ISC_R_SUCCESS) 12744 return (result); 12745 12746 for (tuple = ISC_LIST_HEAD(diff->tuples); 12747 tuple != NULL; 12748 tuple = next) 12749 { 12750 next = ISC_LIST_NEXT(tuple, link); 12751 if (tuple->rdata.type == dns_rdatatype_nsec || 12752 tuple->rdata.type == dns_rdatatype_rrsig || 12753 tuple->rdata.type == dns_rdatatype_dnskey || 12754 tuple->rdata.type == dns_rdatatype_nsec3 || 12755 tuple->rdata.type == dns_rdatatype_nsec3param) 12756 { 12757 ISC_LIST_UNLINK(diff->tuples, tuple, link); 12758 dns_difftuple_free(&tuple); 12759 continue; 12760 } 12761 if (tuple->rdata.type == dns_rdatatype_soa) { 12762 if (tuple->op == DNS_DIFFOP_DEL) { 12763 INSIST(oldtuple == NULL); 12764 oldtuple = tuple; 12765 } 12766 if (tuple->op == DNS_DIFFOP_ADD) { 12767 INSIST(newtuple == NULL); 12768 newtuple = tuple; 12769 } 12770 } 12771 } 12772 12773 if (oldtuple != NULL && newtuple != NULL) { 12774 12775 result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL); 12776 RUNTIME_CHECK(result == ISC_R_SUCCESS); 12777 12778 result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL); 12779 RUNTIME_CHECK(result == ISC_R_SUCCESS); 12780 12781 /* 12782 * If the SOA records are the same except for the serial 12783 * remove them from the diff. 12784 */ 12785 if (oldsoa.refresh == newsoa.refresh && 12786 oldsoa.retry == newsoa.retry && 12787 oldsoa.minimum == newsoa.minimum && 12788 oldsoa.expire == newsoa.expire && 12789 dns_name_equal(&oldsoa.origin, &newsoa.origin) && 12790 dns_name_equal(&oldsoa.contact, &newsoa.contact)) { 12791 ISC_LIST_UNLINK(diff->tuples, oldtuple, link); 12792 dns_difftuple_free(&oldtuple); 12793 ISC_LIST_UNLINK(diff->tuples, newtuple, link); 12794 dns_difftuple_free(&newtuple); 12795 } 12796 } 12797 12798 if (ISC_LIST_EMPTY(diff->tuples)) 12799 return (DNS_R_UNCHANGED); 12800 12801 /* 12802 * If there are still SOA records in the diff they can now be removed 12803 * saving the new SOA record. 12804 */ 12805 if (oldtuple != NULL) { 12806 ISC_LIST_UNLINK(diff->tuples, oldtuple, link); 12807 dns_difftuple_free(&oldtuple); 12808 } 12809 12810 if (newtuple != NULL) { 12811 ISC_LIST_UNLINK(diff->tuples, newtuple, link); 12812 *soatuple = newtuple; 12813 } 12814 12815 return (ISC_R_SUCCESS); 12816} 12817 12818static void 12819receive_secure_serial(isc_task_t *task, isc_event_t *event) { 12820 static char me[] = "receive_secure_serial"; 12821 isc_result_t result; 12822 dns_journal_t *rjournal = NULL; 12823 isc_uint32_t start, end; 12824 dns_zone_t *zone; 12825 dns_db_t *db = NULL; 12826 dns_dbversion_t *newver = NULL, *oldver = NULL; 12827 dns_diff_t diff; 12828 dns_difftuple_t *tuple = NULL, *soatuple = NULL; 12829 dns_update_log_t log = { update_log_cb, NULL }; 12830 isc_time_t timenow; 12831 12832 zone = event->ev_arg; 12833 end = ((struct secure_event *)event)->serial; 12834 isc_event_free(&event); 12835 12836 ENTER; 12837 12838 LOCK_ZONE(zone); 12839 12840 dns_diff_init(zone->mctx, &diff); 12841 12842 UNUSED(task); 12843 12844 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12845 if (zone->db != NULL) 12846 dns_db_attach(zone->db, &db); 12847 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12848 12849 /* 12850 * zone->db may be NULL if the load from disk failed. 12851 */ 12852 if (db == NULL || !inline_secure(zone)) { 12853 result = ISC_R_FAILURE; 12854 goto failure; 12855 } 12856 12857 /* 12858 * We first attempt to sync the raw zone to the secure zone 12859 * by using the raw zone's journal, applying all the deltas 12860 * from the latest source-serial of the secure zone up to 12861 * the current serial number of the raw zone. 12862 * 12863 * If that fails, then we'll fall back to a direct comparison 12864 * between raw and secure zones. 12865 */ 12866 result = dns_journal_open(zone->raw->mctx, zone->raw->journal, 12867 DNS_JOURNAL_WRITE, &rjournal); 12868 if (result != ISC_R_SUCCESS) 12869 goto failure; 12870 else { 12871 dns_journal_t *sjournal = NULL; 12872 12873 result = dns_journal_open(zone->mctx, zone->journal, 12874 DNS_JOURNAL_READ, &sjournal); 12875 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) 12876 goto failure; 12877 12878 if (!dns_journal_get_sourceserial(rjournal, &start)) { 12879 start = dns_journal_first_serial(rjournal); 12880 dns_journal_set_sourceserial(rjournal, start); 12881 } 12882 if (sjournal != NULL) { 12883 isc_uint32_t serial; 12884 /* 12885 * We read the secure journal first, if that exists 12886 * use its value provided it is greater that from the 12887 * raw journal. 12888 */ 12889 if (dns_journal_get_sourceserial(sjournal, &serial)) { 12890 if (isc_serial_gt(serial, start)) 12891 start = serial; 12892 } 12893 dns_journal_destroy(&sjournal); 12894 } 12895 } 12896 12897 dns_db_currentversion(db, &oldver); 12898 CHECK(dns_db_newversion(db, &newver)); 12899 12900 /* 12901 * Try to apply diffs from the raw zone's journal to the secure 12902 * zone. If that fails, we recover by syncing up the databases 12903 * directly. 12904 */ 12905 result = sync_secure_journal(zone, rjournal, start, end, 12906 &soatuple, &diff); 12907 if (result == DNS_R_UNCHANGED) 12908 goto failure; 12909 else if (result != ISC_R_SUCCESS) 12910 CHECK(sync_secure_db(zone, db, oldver, &soatuple, &diff)); 12911 12912 CHECK(dns_diff_apply(&diff, db, newver)); 12913 12914 if (soatuple != NULL) { 12915 isc_uint32_t oldserial, newserial, desired; 12916 12917 CHECK(dns_db_createsoatuple(db, oldver, diff.mctx, 12918 DNS_DIFFOP_DEL, &tuple)); 12919 oldserial = dns_soa_getserial(&tuple->rdata); 12920 newserial = desired = dns_soa_getserial(&soatuple->rdata); 12921 if (!isc_serial_gt(newserial, oldserial)) { 12922 newserial = oldserial + 1; 12923 if (newserial == 0) 12924 newserial++; 12925 dns_soa_setserial(newserial, &soatuple->rdata); 12926 } 12927 CHECK(do_one_tuple(&tuple, db, newver, &diff)); 12928 CHECK(do_one_tuple(&soatuple, db, newver, &diff)); 12929 dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)", 12930 newserial, desired); 12931 } else 12932 CHECK(update_soa_serial(db, newver, &diff, zone->mctx, 12933 zone->updatemethod)); 12934 12935 CHECK(dns_update_signatures(&log, zone, db, oldver, newver, 12936 &diff, zone->sigvalidityinterval)); 12937 12938 CHECK(zone_journal(zone, &diff, &end, "receive_secure_serial")); 12939 12940 dns_journal_set_sourceserial(rjournal, end); 12941 dns_journal_commit(rjournal); 12942 12943 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12944 12945 zone->sourceserial = end; 12946 zone->sourceserialset = ISC_TRUE; 12947 zone_needdump(zone, DNS_DUMP_DELAY); 12948 12949 TIME_NOW(&timenow); 12950 zone_settimer(zone, &timenow); 12951 12952 dns_db_closeversion(db, &oldver, ISC_FALSE); 12953 dns_db_closeversion(db, &newver, ISC_TRUE); 12954 12955 failure: 12956 UNLOCK_ZONE(zone); 12957 if (result != ISC_R_SUCCESS) 12958 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s", 12959 dns_result_totext(result)); 12960 if (tuple != NULL) 12961 dns_difftuple_free(&tuple); 12962 if (soatuple != NULL) 12963 dns_difftuple_free(&soatuple); 12964 if (db != NULL) { 12965 if (oldver != NULL) 12966 dns_db_closeversion(db, &oldver, ISC_FALSE); 12967 if (newver != NULL) 12968 dns_db_closeversion(db, &newver, ISC_FALSE); 12969 dns_db_detach(&db); 12970 } 12971 if (rjournal != NULL) 12972 dns_journal_destroy(&rjournal); 12973 dns_diff_clear(&diff); 12974 dns_zone_idetach(&zone); 12975} 12976 12977static isc_result_t 12978zone_send_secureserial(dns_zone_t *zone, isc_uint32_t serial) { 12979 isc_event_t *e; 12980 dns_zone_t *dummy = NULL; 12981 12982 e = isc_event_allocate(zone->secure->mctx, zone, 12983 DNS_EVENT_ZONESECURESERIAL, 12984 receive_secure_serial, zone->secure, 12985 sizeof(struct secure_event)); 12986 if (e == NULL) 12987 return (ISC_R_NOMEMORY); 12988 ((struct secure_event *)e)->serial = serial; 12989 INSIST(LOCKED_ZONE(zone->secure)); 12990 zone_iattach(zone->secure, &dummy); 12991 isc_task_send(zone->secure->task, &e); 12992 12993 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); 12994 return (ISC_R_SUCCESS); 12995} 12996 12997static isc_result_t 12998checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 12999 dns_rdataset_t *rdataset, isc_uint32_t oldserial) 13000{ 13001 dns_rdata_soa_t soa; 13002 dns_rdata_t rdata = DNS_RDATA_INIT; 13003 dns_rdatalist_t temprdatalist; 13004 dns_rdataset_t temprdataset; 13005 isc_buffer_t b; 13006 isc_result_t result; 13007 unsigned char buf[DNS_SOA_BUFFERSIZE]; 13008 13009 result = dns_rdataset_first(rdataset); 13010 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13011 dns_rdataset_current(rdataset, &rdata); 13012 result = dns_rdata_tostruct(&rdata, &soa, NULL); 13013 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13014 13015 if (isc_serial_gt(soa.serial, oldserial)) 13016 return (dns_db_addrdataset(db, node, version, 0, rdataset, 0, 13017 NULL)); 13018 /* 13019 * Always bump the serial. 13020 */ 13021 oldserial++; 13022 if (oldserial == 0) 13023 oldserial++; 13024 soa.serial = oldserial; 13025 13026 /* 13027 * Construct a replacement rdataset. 13028 */ 13029 dns_rdata_reset(&rdata); 13030 isc_buffer_init(&b, buf, sizeof(buf)); 13031 result = dns_rdata_fromstruct(&rdata, rdataset->rdclass, 13032 dns_rdatatype_soa, &soa, &b); 13033 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13034 temprdatalist.rdclass = rdata.rdclass; 13035 temprdatalist.type = rdata.type; 13036 temprdatalist.covers = 0; 13037 temprdatalist.ttl = rdataset->ttl; 13038 ISC_LIST_INIT(temprdatalist.rdata); 13039 ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link); 13040 13041 dns_rdataset_init(&temprdataset); 13042 result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset); 13043 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13044 return (dns_db_addrdataset(db, node, version, 0, &temprdataset, 13045 0, NULL)); 13046} 13047 13048/* 13049 * This function should populate an nsec3paramlist_t with the 13050 * nsecparam_t data from a zone. 13051 */ 13052static isc_result_t 13053save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) { 13054 isc_result_t result; 13055 dns_dbnode_t *node = NULL; 13056 dns_rdataset_t rdataset, prdataset; 13057 dns_rdata_t rdata_in, prdata_in, prdata_out; 13058 dns_dbversion_t *version = NULL; 13059 nsec3param_t *nsec3param = NULL; 13060 nsec3param_t *nsec3p = NULL; 13061 nsec3param_t *next; 13062 dns_db_t *db = NULL; 13063 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 13064 13065 REQUIRE(DNS_ZONE_VALID(zone)); 13066 REQUIRE(nsec3list != NULL); 13067 REQUIRE(ISC_LIST_EMPTY(*nsec3list)); 13068 13069 dns_db_attach(zone->db, &db); 13070 CHECK(dns_db_getoriginnode(db, &node)); 13071 13072 dns_rdataset_init(&rdataset); 13073 dns_db_currentversion(db, &version); 13074 result = dns_db_findrdataset(db, node, version, 13075 dns_rdatatype_nsec3param, 13076 dns_rdatatype_none, 0, &rdataset, NULL); 13077 13078 if (result != ISC_R_SUCCESS) 13079 goto getprivate; 13080 13081 /* 13082 * walk nsec3param rdataset making a list of parameters (note that 13083 * multiple simultaneous nsec3 chains are annoyingly legal -- this 13084 * is why we use an nsec3list, even tho we will usually only have 13085 * one) 13086 */ 13087 for (result = dns_rdataset_first(&rdataset); 13088 result == ISC_R_SUCCESS; 13089 result = dns_rdataset_next(&rdataset)) 13090 { 13091 dns_rdata_init(&rdata_in); 13092 dns_rdataset_current(&rdataset, &rdata_in); 13093 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 13094 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 13095 "looping through nsec3param data"); 13096 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t)); 13097 if (nsec3param == NULL) 13098 CHECK(ISC_R_NOMEMORY); 13099 ISC_LINK_INIT(nsec3param, link); 13100 13101 /* 13102 * now transfer the data from the rdata to 13103 * the nsec3param 13104 */ 13105 dns_rdata_init(&prdata_out); 13106 dns_nsec3param_toprivate(&rdata_in, &prdata_out, 13107 zone->privatetype, nsec3param->data, 13108 sizeof(nsec3param->data)); 13109 nsec3param->length = prdata_out.length; 13110 ISC_LIST_APPEND(*nsec3list, nsec3param, link); 13111 } 13112 13113 getprivate: 13114 dns_rdataset_init(&prdataset); 13115 result = dns_db_findrdataset(db, node, version, zone->privatetype, 13116 dns_rdatatype_none, 0, &prdataset, NULL); 13117 if (result != ISC_R_SUCCESS) 13118 goto done; 13119 13120 /* 13121 * walk private type records, converting them to nsec3 parameters 13122 * using dns_nsec3param_fromprivate(), do the right thing based on 13123 * CREATE and REMOVE flags 13124 */ 13125 for (result = dns_rdataset_first(&prdataset); 13126 result == ISC_R_SUCCESS; 13127 result = dns_rdataset_next(&prdataset)) 13128 { 13129 dns_rdata_init(&prdata_in); 13130 dns_rdataset_current(&prdataset, &prdata_in); 13131 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 13132 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 13133 "looping through nsec3param private data"); 13134 13135 if (!dns_nsec3param_fromprivate(&prdata_in, &prdata_out, 13136 buf, sizeof(buf))) 13137 continue; 13138 13139 if ((prdata_out.data[1] & DNS_NSEC3FLAG_REMOVE) !=0) { 13140 prdata_out.data[1] = 0; 13141 13142 for (nsec3p = ISC_LIST_HEAD(*nsec3list); 13143 nsec3p != NULL; 13144 nsec3p = next) 13145 { 13146 next = ISC_LIST_NEXT(nsec3p, link); 13147 if (memcmp(prdata_out.data, nsec3p->data, 13148 sizeof(nsec3p->data)) == 0) { 13149 ISC_LIST_UNLINK(*nsec3list, 13150 nsec3p, link); 13151 isc_mem_put(zone->mctx, nsec3p, 13152 sizeof(nsec3param_t)); 13153 } 13154 } 13155 continue; 13156 } 13157 13158 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t)); 13159 if (nsec3param == NULL) 13160 CHECK(ISC_R_NOMEMORY); 13161 ISC_LINK_INIT(nsec3param, link); 13162 13163 dns_rdata_init(&prdata_out); 13164 dns_nsec3param_toprivate(&prdata_in, &prdata_out, 13165 zone->privatetype, nsec3param->data, 13166 sizeof(nsec3param->data)); 13167 nsec3param->length = prdata_out.length; 13168 ISC_LIST_APPEND(*nsec3list, nsec3param, link); 13169 } 13170 13171 done: 13172 if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) 13173 result = ISC_R_SUCCESS; 13174 13175 failure: 13176 if (node != NULL) 13177 dns_db_detachnode(db, &node); 13178 if (version != NULL) 13179 dns_db_closeversion(db, &version, ISC_FALSE); 13180 if (db != NULL) 13181 dns_db_detach(&db); 13182 if (dns_rdataset_isassociated(&rdataset)) 13183 dns_rdataset_disassociate(&rdataset); 13184 if (dns_rdataset_isassociated(&prdataset)) 13185 dns_rdataset_disassociate(&prdataset); 13186 return (result); 13187} 13188 13189/* 13190 * Walk the list of the nsec3 chains desired for the zone, converting 13191 * parameters to private type records using dns_nsec3param_toprivate(), 13192 * and insert them into the new zone db. 13193 */ 13194static isc_result_t 13195restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 13196 nsec3paramlist_t *nsec3list) 13197{ 13198 isc_result_t result; 13199 dns_diff_t diff; 13200 dns_rdata_t rdata; 13201 nsec3param_t *nsec3p = NULL; 13202 nsec3param_t *next; 13203 13204 REQUIRE(DNS_ZONE_VALID(zone)); 13205 REQUIRE(!ISC_LIST_EMPTY(*nsec3list)); 13206 13207 dns_diff_init(zone->mctx, &diff); 13208 13209 /* 13210 * Loop through the list of private-type records, set the INITIAL 13211 * and CREATE flags, and the add the record to the apex of the tree 13212 * in db. 13213 */ 13214 for (nsec3p = ISC_LIST_HEAD(*nsec3list); 13215 nsec3p != NULL; 13216 nsec3p = next) 13217 { 13218 next = ISC_LIST_NEXT(nsec3p, link); 13219 dns_rdata_init(&rdata); 13220 nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL; 13221 rdata.length = nsec3p->length; 13222 rdata.data = nsec3p->data; 13223 rdata.type = zone->privatetype; 13224 rdata.rdclass = zone->rdclass; 13225 CHECK(update_one_rr(db, version, &diff, DNS_DIFFOP_ADD, 13226 &zone->origin, 0, &rdata)); 13227 } 13228 13229 result = ISC_R_SUCCESS; 13230 13231failure: 13232 for (nsec3p = ISC_LIST_HEAD(*nsec3list); 13233 nsec3p != NULL; 13234 nsec3p = next) 13235 { 13236 next = ISC_LIST_NEXT(nsec3p, link); 13237 ISC_LIST_UNLINK(*nsec3list, nsec3p, link); 13238 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t)); 13239 } 13240 13241 dns_diff_clear(&diff); 13242 return (result); 13243} 13244 13245static void 13246receive_secure_db(isc_task_t *task, isc_event_t *event) { 13247 isc_result_t result; 13248 dns_zone_t *zone; 13249 dns_db_t *rawdb, *db = NULL; 13250 dns_dbnode_t *rawnode = NULL, *node = NULL; 13251 dns_fixedname_t fname; 13252 dns_name_t *name; 13253 dns_dbiterator_t *dbiterator = NULL; 13254 dns_rdatasetiter_t *rdsit = NULL; 13255 dns_rdataset_t rdataset; 13256 dns_dbversion_t *version = NULL; 13257 isc_time_t loadtime; 13258 unsigned int oldserial = 0; 13259 isc_boolean_t have_oldserial = ISC_FALSE; 13260 nsec3paramlist_t nsec3list; 13261 13262 UNUSED(task); 13263 13264 ISC_LIST_INIT(nsec3list); 13265 13266 zone = event->ev_arg; 13267 rawdb = ((struct secure_event *)event)->db; 13268 isc_event_free(&event); 13269 13270 dns_fixedname_init(&fname); 13271 name = dns_fixedname_name(&fname); 13272 dns_rdataset_init(&rdataset); 13273 13274 LOCK_ZONE(zone); 13275 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) { 13276 result = ISC_R_SHUTTINGDOWN; 13277 goto failure; 13278 } 13279 13280 TIME_NOW(&loadtime); 13281 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 13282 if (zone->db != NULL) { 13283 result = dns_db_getsoaserial(zone->db, NULL, &oldserial); 13284 if (result == ISC_R_SUCCESS) 13285 have_oldserial = ISC_TRUE; 13286 13287 /* 13288 * assemble nsec3parameters from the old zone, and set a flag 13289 * if any are found 13290 */ 13291 result = save_nsec3param(zone, &nsec3list); 13292 if (result != ISC_R_SUCCESS) { 13293 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 13294 goto failure; 13295 } 13296 } 13297 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 13298 13299 result = dns_db_create(zone->mctx, zone->db_argv[0], 13300 &zone->origin, dns_dbtype_zone, zone->rdclass, 13301 zone->db_argc - 1, zone->db_argv + 1, &db); 13302 if (result != ISC_R_SUCCESS) 13303 goto failure; 13304 13305 result = dns_db_newversion(db, &version); 13306 if (result != ISC_R_SUCCESS) 13307 goto failure; 13308 13309 result = dns_db_createiterator(rawdb, 0, &dbiterator); 13310 if (result != ISC_R_SUCCESS) 13311 goto failure; 13312 13313 for (result = dns_dbiterator_first(dbiterator); 13314 result == ISC_R_SUCCESS; 13315 result = dns_dbiterator_next(dbiterator)) { 13316 result = dns_dbiterator_current(dbiterator, &rawnode, name); 13317 if (result != ISC_R_SUCCESS) 13318 continue; 13319 13320 result = dns_db_findnode(db, name, ISC_TRUE, &node); 13321 if (result != ISC_R_SUCCESS) 13322 goto failure; 13323 13324 result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit); 13325 if (result != ISC_R_SUCCESS) 13326 goto failure; 13327 13328 for (result = dns_rdatasetiter_first(rdsit); 13329 result == ISC_R_SUCCESS; 13330 result = dns_rdatasetiter_next(rdsit)) { 13331 dns_rdatasetiter_current(rdsit, &rdataset); 13332 if (rdataset.type == dns_rdatatype_nsec || 13333 rdataset.type == dns_rdatatype_rrsig || 13334 rdataset.type == dns_rdatatype_nsec3 || 13335 rdataset.type == dns_rdatatype_dnskey || 13336 rdataset.type == dns_rdatatype_nsec3param) { 13337 dns_rdataset_disassociate(&rdataset); 13338 continue; 13339 } 13340 if (rdataset.type == dns_rdatatype_soa && 13341 have_oldserial) { 13342 result = checkandaddsoa(db, node, version, 13343 &rdataset, oldserial); 13344 } else 13345 result = dns_db_addrdataset(db, node, version, 13346 0, &rdataset, 0, 13347 NULL); 13348 if (result != ISC_R_SUCCESS) 13349 goto failure; 13350 13351 dns_rdataset_disassociate(&rdataset); 13352 } 13353 dns_rdatasetiter_destroy(&rdsit); 13354 dns_db_detachnode(rawdb, &rawnode); 13355 dns_db_detachnode(db, &node); 13356 } 13357 13358 /* 13359 * Call restore_nsec3param() to create private-type records from 13360 * the old nsec3 parameters and insert them into db 13361 */ 13362 if (!ISC_LIST_EMPTY(nsec3list)) 13363 restore_nsec3param(zone, db, version, &nsec3list); 13364 13365 dns_db_closeversion(db, &version, ISC_TRUE); 13366 13367 /* 13368 * Lock hierarchy: zmgr, zone, raw. 13369 */ 13370 INSIST(zone != zone->raw); 13371 LOCK_ZONE(zone->raw); 13372 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 13373 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 13374 zone_needdump(zone, 0); /* XXXMPA */ 13375 UNLOCK_ZONE(zone->raw); 13376 13377 failure: 13378 UNLOCK_ZONE(zone); 13379 if (result != ISC_R_SUCCESS) 13380 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s", 13381 dns_result_totext(result)); 13382 13383 if (dns_rdataset_isassociated(&rdataset)) 13384 dns_rdataset_disassociate(&rdataset); 13385 if (db != NULL) { 13386 if (node != NULL) 13387 dns_db_detachnode(db, &node); 13388 dns_db_detach(&db); 13389 } 13390 if (rawnode != NULL) 13391 dns_db_detachnode(rawdb, &rawnode); 13392 dns_db_detach(&rawdb); 13393 if (dbiterator != NULL) 13394 dns_dbiterator_destroy(&dbiterator); 13395 dns_zone_idetach(&zone); 13396} 13397 13398static isc_result_t 13399zone_send_securedb(dns_zone_t *zone, dns_db_t *db) { 13400 isc_event_t *e; 13401 dns_db_t *dummy = NULL; 13402 dns_zone_t *secure = NULL; 13403 13404 e = isc_event_allocate(zone->secure->mctx, zone, 13405 DNS_EVENT_ZONESECUREDB, 13406 receive_secure_db, zone->secure, 13407 sizeof(struct secure_event)); 13408 if (e == NULL) 13409 return (ISC_R_NOMEMORY); 13410 dns_db_attach(db, &dummy); 13411 ((struct secure_event *)e)->db = dummy; 13412 INSIST(LOCKED_ZONE(zone->secure)); 13413 zone_iattach(zone->secure, &secure); 13414 isc_task_send(zone->secure->task, &e); 13415 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); 13416 return (ISC_R_SUCCESS); 13417} 13418 13419isc_result_t 13420dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { 13421 isc_result_t result; 13422 dns_zone_t *secure = NULL; 13423 13424 REQUIRE(DNS_ZONE_VALID(zone)); 13425 again: 13426 LOCK_ZONE(zone); 13427 if (inline_raw(zone)) { 13428 secure = zone->secure; 13429 INSIST(secure != zone); 13430 TRYLOCK_ZONE(result, secure); 13431 if (result != ISC_R_SUCCESS) { 13432 UNLOCK_ZONE(zone); 13433 secure = NULL; 13434#if ISC_PLATFORM_USETHREADS 13435 isc_thread_yield(); 13436#endif 13437 goto again; 13438 } 13439 } 13440 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 13441 result = zone_replacedb(zone, db, dump); 13442 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 13443 if (secure != NULL) 13444 UNLOCK_ZONE(secure); 13445 UNLOCK_ZONE(zone); 13446 return (result); 13447} 13448 13449static isc_result_t 13450zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { 13451 dns_dbversion_t *ver; 13452 isc_result_t result; 13453 unsigned int soacount = 0; 13454 unsigned int nscount = 0; 13455 13456 /* 13457 * 'zone' and 'zonedb' locked by caller. 13458 */ 13459 REQUIRE(DNS_ZONE_VALID(zone)); 13460 REQUIRE(LOCKED_ZONE(zone)); 13461 if (inline_raw(zone)) 13462 REQUIRE(LOCKED_ZONE(zone->secure)); 13463 13464 result = zone_get_from_db(zone, db, &nscount, &soacount, 13465 NULL, NULL, NULL, NULL, NULL, NULL); 13466 if (result == ISC_R_SUCCESS) { 13467 if (soacount != 1) { 13468 dns_zone_log(zone, ISC_LOG_ERROR, 13469 "has %d SOA records", soacount); 13470 result = DNS_R_BADZONE; 13471 } 13472 if (nscount == 0 && zone->type != dns_zone_key) { 13473 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records"); 13474 result = DNS_R_BADZONE; 13475 } 13476 if (result != ISC_R_SUCCESS) 13477 return (result); 13478 } else { 13479 dns_zone_log(zone, ISC_LOG_ERROR, 13480 "retrieving SOA and NS records failed: %s", 13481 dns_result_totext(result)); 13482 return (result); 13483 } 13484 13485 result = check_nsec3param(zone, db); 13486 if (result != ISC_R_SUCCESS) 13487 return (result); 13488 13489 ver = NULL; 13490 dns_db_currentversion(db, &ver); 13491 13492 /* 13493 * The initial version of a slave zone is always dumped; 13494 * subsequent versions may be journaled instead if this 13495 * is enabled in the configuration. 13496 */ 13497 if (zone->db != NULL && zone->journal != NULL && 13498 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 13499 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) 13500 { 13501 isc_uint32_t serial, oldserial; 13502 unsigned int soacount; 13503 13504 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs"); 13505 13506 result = dns_db_getsoaserial(db, ver, &serial); 13507 if (result != ISC_R_SUCCESS) { 13508 dns_zone_log(zone, ISC_LOG_ERROR, 13509 "ixfr-from-differences: unable to get " 13510 "new serial"); 13511 goto fail; 13512 } 13513 13514 /* 13515 * This is checked in zone_postload() for master zones. 13516 */ 13517 result = zone_get_from_db(zone, zone->db, NULL, &soacount, 13518 &oldserial, NULL, NULL, NULL, NULL, 13519 NULL); 13520 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13521 RUNTIME_CHECK(soacount > 0U); 13522 if ((zone->type == dns_zone_slave || 13523 (zone->type == dns_zone_redirect && 13524 zone->masters != NULL)) 13525 && !isc_serial_gt(serial, oldserial)) { 13526 isc_uint32_t serialmin, serialmax; 13527 serialmin = (oldserial + 1) & 0xffffffffU; 13528 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; 13529 dns_zone_log(zone, ISC_LOG_ERROR, 13530 "ixfr-from-differences: failed: " 13531 "new serial (%u) out of range [%u - %u]", 13532 serial, serialmin, serialmax); 13533 result = ISC_R_RANGE; 13534 goto fail; 13535 } 13536 13537 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL, 13538 zone->journal); 13539 if (result != ISC_R_SUCCESS) 13540 goto fail; 13541 if (dump) 13542 zone_needdump(zone, DNS_DUMP_DELAY); 13543 else if (zone->journalsize != -1) { 13544 result = dns_journal_compact(zone->mctx, zone->journal, 13545 serial, zone->journalsize); 13546 switch (result) { 13547 case ISC_R_SUCCESS: 13548 case ISC_R_NOSPACE: 13549 case ISC_R_NOTFOUND: 13550 dns_zone_log(zone, ISC_LOG_DEBUG(3), 13551 "dns_journal_compact: %s", 13552 dns_result_totext(result)); 13553 break; 13554 default: 13555 dns_zone_log(zone, ISC_LOG_ERROR, 13556 "dns_journal_compact failed: %s", 13557 dns_result_totext(result)); 13558 break; 13559 } 13560 } 13561 if (zone->type == dns_zone_master && inline_raw(zone)) 13562 zone_send_secureserial(zone, serial); 13563 } else { 13564 if (dump && zone->masterfile != NULL) { 13565 /* 13566 * If DNS_ZONEFLG_FORCEXFER was set we don't want 13567 * to keep the old masterfile. 13568 */ 13569 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) && 13570 remove(zone->masterfile) < 0 && errno != ENOENT) { 13571 char strbuf[ISC_STRERRORSIZE]; 13572 isc__strerror(errno, strbuf, sizeof(strbuf)); 13573 isc_log_write(dns_lctx, 13574 DNS_LOGCATEGORY_GENERAL, 13575 DNS_LOGMODULE_ZONE, 13576 ISC_LOG_WARNING, 13577 "unable to remove masterfile " 13578 "'%s': '%s'", 13579 zone->masterfile, strbuf); 13580 } 13581 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) 13582 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY); 13583 else 13584 zone_needdump(zone, 0); 13585 } 13586 if (dump && zone->journal != NULL) { 13587 /* 13588 * The in-memory database just changed, and 13589 * because 'dump' is set, it didn't change by 13590 * being loaded from disk. Also, we have not 13591 * journaled diffs for this change. 13592 * Therefore, the on-disk journal is missing 13593 * the deltas for this change. Since it can 13594 * no longer be used to bring the zone 13595 * up-to-date, it is useless and should be 13596 * removed. 13597 */ 13598 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 13599 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 13600 "removing journal file"); 13601 if (remove(zone->journal) < 0 && errno != ENOENT) { 13602 char strbuf[ISC_STRERRORSIZE]; 13603 isc__strerror(errno, strbuf, sizeof(strbuf)); 13604 isc_log_write(dns_lctx, 13605 DNS_LOGCATEGORY_GENERAL, 13606 DNS_LOGMODULE_ZONE, 13607 ISC_LOG_WARNING, 13608 "unable to remove journal " 13609 "'%s': '%s'", 13610 zone->journal, strbuf); 13611 } 13612 } 13613 13614 if (inline_raw(zone)) 13615 zone_send_securedb(zone, db); 13616 } 13617 13618 dns_db_closeversion(db, &ver, ISC_FALSE); 13619 13620 dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database"); 13621 13622 if (zone->db != NULL) 13623 zone_detachdb(zone); 13624 zone_attachdb(zone, db); 13625 dns_db_settask(zone->db, zone->task); 13626 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY); 13627 return (ISC_R_SUCCESS); 13628 13629 fail: 13630 dns_db_closeversion(db, &ver, ISC_FALSE); 13631 return (result); 13632} 13633 13634/* The caller must hold the dblock as a writer. */ 13635static inline void 13636zone_attachdb(dns_zone_t *zone, dns_db_t *db) { 13637 REQUIRE(zone->db == NULL && db != NULL); 13638 13639 dns_db_attach(db, &zone->db); 13640 if (zone->acache != NULL) { 13641 isc_result_t result; 13642 result = dns_acache_setdb(zone->acache, db); 13643 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { 13644 UNEXPECTED_ERROR(__FILE__, __LINE__, 13645 "dns_acache_setdb() failed: %s", 13646 isc_result_totext(result)); 13647 } 13648 } 13649} 13650 13651/* The caller must hold the dblock as a writer. */ 13652static inline void 13653zone_detachdb(dns_zone_t *zone) { 13654 REQUIRE(zone->db != NULL); 13655 13656 if (zone->acache != NULL) 13657 (void)dns_acache_putdb(zone->acache, zone->db); 13658 dns_db_detach(&zone->db); 13659} 13660 13661static void 13662zone_xfrdone(dns_zone_t *zone, isc_result_t result) { 13663 isc_time_t now; 13664 isc_boolean_t again = ISC_FALSE; 13665 unsigned int soacount; 13666 unsigned int nscount; 13667 isc_uint32_t serial, refresh, retry, expire, minimum; 13668 isc_result_t xfrresult = result; 13669 isc_boolean_t free_needed; 13670 dns_zone_t *secure = NULL; 13671 13672 REQUIRE(DNS_ZONE_VALID(zone)); 13673 13674 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13675 "zone transfer finished: %s", dns_result_totext(result)); 13676 13677 /* 13678 * Obtaining a lock on the zone->secure (see zone_send_secureserial) 13679 * could result in a deadlock due to a LOR so we will spin if we 13680 * can't obtain the both locks. 13681 */ 13682 again: 13683 LOCK_ZONE(zone); 13684 if (inline_raw(zone)) { 13685 secure = zone->secure; 13686 INSIST(secure != zone); 13687 TRYLOCK_ZONE(result, secure); 13688 if (result != ISC_R_SUCCESS) { 13689 UNLOCK_ZONE(zone); 13690 secure = NULL; 13691#if ISC_PLATFORM_USETHREADS 13692 isc_thread_yield(); 13693#endif 13694 goto again; 13695 } 13696 } 13697 13698 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0); 13699 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 13700 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 13701 13702 TIME_NOW(&now); 13703 switch (result) { 13704 case ISC_R_SUCCESS: 13705 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 13706 /*FALLTHROUGH*/ 13707 case DNS_R_UPTODATE: 13708 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER); 13709 /* 13710 * Has the zone expired underneath us? 13711 */ 13712 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 13713 if (zone->db == NULL) { 13714 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 13715 goto same_master; 13716 } 13717 13718 /* 13719 * Update the zone structure's data from the actual 13720 * SOA received. 13721 */ 13722 nscount = 0; 13723 soacount = 0; 13724 INSIST(zone->db != NULL); 13725 result = zone_get_from_db(zone, zone->db, &nscount, 13726 &soacount, &serial, &refresh, 13727 &retry, &expire, &minimum, NULL); 13728 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 13729 if (result == ISC_R_SUCCESS) { 13730 if (soacount != 1) 13731 dns_zone_log(zone, ISC_LOG_ERROR, 13732 "transferred zone " 13733 "has %d SOA record%s", soacount, 13734 (soacount != 0) ? "s" : ""); 13735 if (nscount == 0) { 13736 dns_zone_log(zone, ISC_LOG_ERROR, 13737 "transferred zone " 13738 "has no NS records"); 13739 if (DNS_ZONE_FLAG(zone, 13740 DNS_ZONEFLG_HAVETIMERS)) { 13741 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 13742 zone->retry = DNS_ZONE_DEFAULTRETRY; 13743 } 13744 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 13745 zone_unload(zone); 13746 goto next_master; 13747 } 13748 zone->refresh = RANGE(refresh, zone->minrefresh, 13749 zone->maxrefresh); 13750 zone->retry = RANGE(retry, zone->minretry, 13751 zone->maxretry); 13752 zone->expire = RANGE(expire, 13753 zone->refresh + zone->retry, 13754 DNS_MAX_EXPIRE); 13755 zone->minimum = minimum; 13756 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 13757 } 13758 13759 /* 13760 * Set our next update/expire times. 13761 */ 13762 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 13763 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 13764 zone->refreshtime = now; 13765 DNS_ZONE_TIME_ADD(&now, zone->expire, 13766 &zone->expiretime); 13767 } else { 13768 DNS_ZONE_JITTER_ADD(&now, zone->refresh, 13769 &zone->refreshtime); 13770 DNS_ZONE_TIME_ADD(&now, zone->expire, 13771 &zone->expiretime); 13772 } 13773 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) { 13774 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")]; 13775 if (zone->tsigkey != NULL) { 13776 char namebuf[DNS_NAME_FORMATSIZE]; 13777 dns_name_format(&zone->tsigkey->name, namebuf, 13778 sizeof(namebuf)); 13779 snprintf(buf, sizeof(buf), ": TSIG '%s'", 13780 namebuf); 13781 } else 13782 buf[0] = '\0'; 13783 dns_zone_log(zone, ISC_LOG_INFO, 13784 "transferred serial %u%s", 13785 serial, buf); 13786 if (inline_raw(zone)) 13787 zone_send_secureserial(zone, serial); 13788 } 13789 13790 /* 13791 * This is not necessary if we just performed a AXFR 13792 * however it is necessary for an IXFR / UPTODATE and 13793 * won't hurt with an AXFR. 13794 */ 13795 if (zone->masterfile != NULL || zone->journal != NULL) { 13796 unsigned int delay = DNS_DUMP_DELAY; 13797 13798 result = ISC_R_FAILURE; 13799 if (zone->journal != NULL) 13800 result = isc_file_settime(zone->journal, &now); 13801 if (result != ISC_R_SUCCESS && 13802 zone->masterfile != NULL) 13803 result = isc_file_settime(zone->masterfile, 13804 &now); 13805 13806 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) || 13807 result == ISC_R_FILENOTFOUND) 13808 delay = 0; 13809 13810 if ((result == ISC_R_SUCCESS || 13811 result == ISC_R_FILENOTFOUND) && 13812 zone->masterfile != NULL) 13813 zone_needdump(zone, delay); 13814 else if (result != ISC_R_SUCCESS) 13815 dns_zone_log(zone, ISC_LOG_ERROR, 13816 "transfer: could not set file " 13817 "modification time of '%s': %s", 13818 zone->masterfile, 13819 dns_result_totext(result)); 13820 } 13821 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY); 13822 inc_stats(zone, dns_zonestatscounter_xfrsuccess); 13823 break; 13824 13825 case DNS_R_BADIXFR: 13826 /* Force retry with AXFR. */ 13827 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR); 13828 goto same_master; 13829 13830 default: 13831 next_master: 13832 /* 13833 * Skip to next failed / untried master. 13834 */ 13835 do { 13836 zone->curmaster++; 13837 } while (zone->curmaster < zone->masterscnt && 13838 zone->mastersok[zone->curmaster]); 13839 /* FALLTHROUGH */ 13840 same_master: 13841 if (zone->curmaster >= zone->masterscnt) { 13842 zone->curmaster = 0; 13843 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 13844 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 13845 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 13846 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 13847 while (zone->curmaster < zone->masterscnt && 13848 zone->mastersok[zone->curmaster]) 13849 zone->curmaster++; 13850 again = ISC_TRUE; 13851 } else 13852 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 13853 } else { 13854 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 13855 again = ISC_TRUE; 13856 } 13857 inc_stats(zone, dns_zonestatscounter_xfrfail); 13858 break; 13859 } 13860 zone_settimer(zone, &now); 13861 13862 /* 13863 * If creating the transfer object failed, zone->xfr is NULL. 13864 * Otherwise, we are called as the done callback of a zone 13865 * transfer object that just entered its shutting-down 13866 * state. Since we are no longer responsible for shutting 13867 * it down, we can detach our reference. 13868 */ 13869 if (zone->xfr != NULL) 13870 dns_xfrin_detach(&zone->xfr); 13871 13872 if (zone->tsigkey != NULL) 13873 dns_tsigkey_detach(&zone->tsigkey); 13874 13875 /* 13876 * Handle any deferred journal compaction. 13877 */ 13878 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) { 13879 result = dns_journal_compact(zone->mctx, zone->journal, 13880 zone->compact_serial, 13881 zone->journalsize); 13882 switch (result) { 13883 case ISC_R_SUCCESS: 13884 case ISC_R_NOSPACE: 13885 case ISC_R_NOTFOUND: 13886 dns_zone_log(zone, ISC_LOG_DEBUG(3), 13887 "dns_journal_compact: %s", 13888 dns_result_totext(result)); 13889 break; 13890 default: 13891 dns_zone_log(zone, ISC_LOG_ERROR, 13892 "dns_journal_compact failed: %s", 13893 dns_result_totext(result)); 13894 break; 13895 } 13896 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 13897 } 13898 13899 if (secure != NULL) 13900 UNLOCK_ZONE(secure); 13901 /* 13902 * This transfer finishing freed up a transfer quota slot. 13903 * Let any other zones waiting for quota have it. 13904 */ 13905 if (zone->zmgr != NULL && 13906 zone->statelist == &zone->zmgr->xfrin_in_progress) { 13907 UNLOCK_ZONE(zone); 13908 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 13909 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink); 13910 zone->statelist = NULL; 13911 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE); 13912 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 13913 LOCK_ZONE(zone); 13914 } 13915 13916 /* 13917 * Retry with a different server if necessary. 13918 */ 13919 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 13920 queue_soa_query(zone); 13921 13922 INSIST(zone->irefs > 0); 13923 zone->irefs--; 13924 free_needed = exit_check(zone); 13925 UNLOCK_ZONE(zone); 13926 if (free_needed) 13927 zone_free(zone); 13928} 13929 13930static void 13931zone_loaddone(void *arg, isc_result_t result) { 13932 static char me[] = "zone_loaddone"; 13933 dns_load_t *load = arg; 13934 dns_zone_t *zone; 13935 isc_result_t tresult; 13936 dns_zone_t *secure = NULL; 13937 13938 REQUIRE(DNS_LOAD_VALID(load)); 13939 zone = load->zone; 13940 13941 ENTER; 13942 13943 tresult = dns_db_endload(load->db, &load->callbacks.add_private); 13944 if (tresult != ISC_R_SUCCESS && 13945 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)) 13946 result = tresult; 13947 13948 /* 13949 * Lock hierarchy: zmgr, zone, raw. 13950 */ 13951 again: 13952 LOCK_ZONE(zone); 13953 if (inline_secure(zone)) 13954 LOCK_ZONE(zone->raw); 13955 else if (inline_raw(zone)) { 13956 secure = zone->secure; 13957 TRYLOCK_ZONE(result, secure); 13958 if (result != ISC_R_SUCCESS) { 13959 UNLOCK_ZONE(zone); 13960 secure = NULL; 13961#if ISC_PLATFORM_USETHREADS 13962 isc_thread_yield(); 13963#endif 13964 goto again; 13965 } 13966 } 13967 (void)zone_postload(zone, load->db, load->loadtime, result); 13968 zonemgr_putio(&zone->readio); 13969 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING); 13970 zone_idetach(&load->callbacks.zone); 13971 /* 13972 * Leave the zone frozen if the reload fails. 13973 */ 13974 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) && 13975 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW)) 13976 zone->update_disabled = ISC_FALSE; 13977 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW); 13978 if (inline_secure(zone)) 13979 UNLOCK_ZONE(zone->raw); 13980 else if (secure != NULL) 13981 UNLOCK_ZONE(secure); 13982 UNLOCK_ZONE(zone); 13983 13984 load->magic = 0; 13985 dns_db_detach(&load->db); 13986 if (load->zone->lctx != NULL) 13987 dns_loadctx_detach(&load->zone->lctx); 13988 dns_zone_idetach(&load->zone); 13989 isc_mem_putanddetach(&load->mctx, load, sizeof(*load)); 13990} 13991 13992void 13993dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) { 13994 REQUIRE(DNS_ZONE_VALID(zone)); 13995 REQUIRE(table != NULL); 13996 REQUIRE(*table == NULL); 13997 13998 LOCK_ZONE(zone); 13999 if (zone->ssutable != NULL) 14000 dns_ssutable_attach(zone->ssutable, table); 14001 UNLOCK_ZONE(zone); 14002} 14003 14004void 14005dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) { 14006 REQUIRE(DNS_ZONE_VALID(zone)); 14007 14008 LOCK_ZONE(zone); 14009 if (zone->ssutable != NULL) 14010 dns_ssutable_detach(&zone->ssutable); 14011 if (table != NULL) 14012 dns_ssutable_attach(table, &zone->ssutable); 14013 UNLOCK_ZONE(zone); 14014} 14015 14016void 14017dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) { 14018 REQUIRE(DNS_ZONE_VALID(zone)); 14019 14020 zone->sigvalidityinterval = interval; 14021} 14022 14023isc_uint32_t 14024dns_zone_getsigvalidityinterval(dns_zone_t *zone) { 14025 REQUIRE(DNS_ZONE_VALID(zone)); 14026 14027 return (zone->sigvalidityinterval); 14028} 14029 14030void 14031dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) { 14032 isc_time_t now; 14033 14034 REQUIRE(DNS_ZONE_VALID(zone)); 14035 14036 LOCK_ZONE(zone); 14037 zone->sigresigninginterval = interval; 14038 set_resigntime(zone); 14039 if (zone->task != NULL) { 14040 TIME_NOW(&now); 14041 zone_settimer(zone, &now); 14042 } 14043 UNLOCK_ZONE(zone); 14044} 14045 14046isc_uint32_t 14047dns_zone_getsigresigninginterval(dns_zone_t *zone) { 14048 REQUIRE(DNS_ZONE_VALID(zone)); 14049 14050 return (zone->sigresigninginterval); 14051} 14052 14053static void 14054queue_xfrin(dns_zone_t *zone) { 14055 const char me[] = "queue_xfrin"; 14056 isc_result_t result; 14057 dns_zonemgr_t *zmgr = zone->zmgr; 14058 14059 ENTER; 14060 14061 INSIST(zone->statelist == NULL); 14062 14063 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 14064 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink); 14065 LOCK_ZONE(zone); 14066 zone->irefs++; 14067 UNLOCK_ZONE(zone); 14068 zone->statelist = &zmgr->waiting_for_xfrin; 14069 result = zmgr_start_xfrin_ifquota(zmgr, zone); 14070 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 14071 14072 if (result == ISC_R_QUOTA) { 14073 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14074 "zone transfer deferred due to quota"); 14075 } else if (result != ISC_R_SUCCESS) { 14076 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, 14077 "starting zone transfer: %s", 14078 isc_result_totext(result)); 14079 } 14080} 14081 14082/* 14083 * This event callback is called when a zone has received 14084 * any necessary zone transfer quota. This is the time 14085 * to go ahead and start the transfer. 14086 */ 14087static void 14088got_transfer_quota(isc_task_t *task, isc_event_t *event) { 14089 isc_result_t result = ISC_R_SUCCESS; 14090 dns_peer_t *peer = NULL; 14091 char master[ISC_SOCKADDR_FORMATSIZE]; 14092 char source[ISC_SOCKADDR_FORMATSIZE]; 14093 dns_rdatatype_t xfrtype; 14094 dns_zone_t *zone = event->ev_arg; 14095 isc_netaddr_t masterip; 14096 isc_sockaddr_t sourceaddr; 14097 isc_sockaddr_t masteraddr; 14098 isc_time_t now; 14099 const char *soa_before = ""; 14100 isc_boolean_t loaded; 14101 14102 UNUSED(task); 14103 14104 INSIST(task == zone->task); 14105 14106 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 14107 result = ISC_R_CANCELED; 14108 goto cleanup; 14109 } 14110 14111 TIME_NOW(&now); 14112 14113 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 14114 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, 14115 &zone->sourceaddr, &now)) 14116 { 14117 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 14118 dns_zone_log(zone, ISC_LOG_INFO, 14119 "got_transfer_quota: skipping zone transfer as " 14120 "master %s (source %s) is unreachable (cached)", 14121 master, source); 14122 result = ISC_R_CANCELED; 14123 goto cleanup; 14124 } 14125 14126 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 14127 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer); 14128 14129 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) 14130 soa_before = "SOA before "; 14131 /* 14132 * Decide whether we should request IXFR or AXFR. 14133 */ 14134 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 14135 loaded = ISC_TF(zone->db != NULL); 14136 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 14137 14138 if (!loaded) { 14139 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14140 "no database exists yet, requesting AXFR of " 14141 "initial version from %s", master); 14142 xfrtype = dns_rdatatype_axfr; 14143 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { 14144 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14145 "forced reload, requesting AXFR of " 14146 "initial version from %s", master); 14147 xfrtype = dns_rdatatype_axfr; 14148 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) { 14149 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14150 "retrying with AXFR from %s due to " 14151 "previous IXFR failure", master); 14152 xfrtype = dns_rdatatype_axfr; 14153 LOCK_ZONE(zone); 14154 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR); 14155 UNLOCK_ZONE(zone); 14156 } else { 14157 isc_boolean_t use_ixfr = ISC_TRUE; 14158 if (peer != NULL) 14159 result = dns_peer_getrequestixfr(peer, &use_ixfr); 14160 if (peer == NULL || result != ISC_R_SUCCESS) 14161 use_ixfr = zone->requestixfr; 14162 if (use_ixfr == ISC_FALSE) { 14163 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14164 "IXFR disabled, requesting %sAXFR from %s", 14165 soa_before, master); 14166 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) 14167 xfrtype = dns_rdatatype_soa; 14168 else 14169 xfrtype = dns_rdatatype_axfr; 14170 } else { 14171 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14172 "requesting IXFR from %s", master); 14173 xfrtype = dns_rdatatype_ixfr; 14174 } 14175 } 14176 14177 /* 14178 * Determine if we should attempt to sign the request with TSIG. 14179 */ 14180 result = ISC_R_NOTFOUND; 14181 /* 14182 * First, look for a tsig key in the master statement, then 14183 * try for a server key. 14184 */ 14185 if ((zone->masterkeynames != NULL) && 14186 (zone->masterkeynames[zone->curmaster] != NULL)) { 14187 dns_view_t *view = dns_zone_getview(zone); 14188 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 14189 result = dns_view_gettsig(view, keyname, &zone->tsigkey); 14190 } 14191 if (zone->tsigkey == NULL) 14192 result = dns_view_getpeertsig(zone->view, &masterip, 14193 &zone->tsigkey); 14194 14195 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 14196 dns_zone_log(zone, ISC_LOG_ERROR, 14197 "could not get TSIG key for zone transfer: %s", 14198 isc_result_totext(result)); 14199 } 14200 14201 LOCK_ZONE(zone); 14202 masteraddr = zone->masteraddr; 14203 sourceaddr = zone->sourceaddr; 14204 UNLOCK_ZONE(zone); 14205 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr)); 14206 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr, 14207 zone->tsigkey, zone->mctx, 14208 zone->zmgr->timermgr, zone->zmgr->socketmgr, 14209 zone->task, zone_xfrdone, &zone->xfr); 14210 if (result == ISC_R_SUCCESS) { 14211 LOCK_ZONE(zone); 14212 if (xfrtype == dns_rdatatype_axfr) { 14213 if (isc_sockaddr_pf(&masteraddr) == PF_INET) 14214 inc_stats(zone, dns_zonestatscounter_axfrreqv4); 14215 else 14216 inc_stats(zone, dns_zonestatscounter_axfrreqv6); 14217 } else if (xfrtype == dns_rdatatype_ixfr) { 14218 if (isc_sockaddr_pf(&masteraddr) == PF_INET) 14219 inc_stats(zone, dns_zonestatscounter_ixfrreqv4); 14220 else 14221 inc_stats(zone, dns_zonestatscounter_ixfrreqv6); 14222 } 14223 UNLOCK_ZONE(zone); 14224 } 14225 cleanup: 14226 /* 14227 * Any failure in this function is handled like a failed 14228 * zone transfer. This ensures that we get removed from 14229 * zmgr->xfrin_in_progress. 14230 */ 14231 if (result != ISC_R_SUCCESS) 14232 zone_xfrdone(zone, result); 14233 14234 isc_event_free(&event); 14235} 14236 14237/* 14238 * Update forwarding support. 14239 */ 14240 14241static void 14242forward_destroy(dns_forward_t *forward) { 14243 14244 forward->magic = 0; 14245 if (forward->request != NULL) 14246 dns_request_destroy(&forward->request); 14247 if (forward->msgbuf != NULL) 14248 isc_buffer_free(&forward->msgbuf); 14249 if (forward->zone != NULL) { 14250 LOCK(&forward->zone->lock); 14251 if (ISC_LINK_LINKED(forward, link)) 14252 ISC_LIST_UNLINK(forward->zone->forwards, forward, link); 14253 UNLOCK(&forward->zone->lock); 14254 dns_zone_idetach(&forward->zone); 14255 } 14256 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward)); 14257} 14258 14259static isc_result_t 14260sendtomaster(dns_forward_t *forward) { 14261 isc_result_t result; 14262 isc_sockaddr_t src; 14263 14264 LOCK_ZONE(forward->zone); 14265 14266 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) { 14267 UNLOCK_ZONE(forward->zone); 14268 return (ISC_R_CANCELED); 14269 } 14270 14271 if (forward->which >= forward->zone->masterscnt) { 14272 UNLOCK_ZONE(forward->zone); 14273 return (ISC_R_NOMORE); 14274 } 14275 14276 forward->addr = forward->zone->masters[forward->which]; 14277 /* 14278 * Always use TCP regardless of whether the original update 14279 * used TCP. 14280 * XXX The timeout may but a bit small if we are far down a 14281 * transfer graph and the master has to try several masters. 14282 */ 14283 switch (isc_sockaddr_pf(&forward->addr)) { 14284 case PF_INET: 14285 src = forward->zone->xfrsource4; 14286 break; 14287 case PF_INET6: 14288 src = forward->zone->xfrsource6; 14289 break; 14290 default: 14291 result = ISC_R_NOTIMPLEMENTED; 14292 goto unlock; 14293 } 14294 result = dns_request_createraw(forward->zone->view->requestmgr, 14295 forward->msgbuf, 14296 &src, &forward->addr, 14297 DNS_REQUESTOPT_TCP, 15 /* XXX */, 14298 forward->zone->task, 14299 forward_callback, forward, 14300 &forward->request); 14301 if (result == ISC_R_SUCCESS) { 14302 if (!ISC_LINK_LINKED(forward, link)) 14303 ISC_LIST_APPEND(forward->zone->forwards, forward, link); 14304 } 14305 14306 unlock: 14307 UNLOCK_ZONE(forward->zone); 14308 return (result); 14309} 14310 14311static void 14312forward_callback(isc_task_t *task, isc_event_t *event) { 14313 const char me[] = "forward_callback"; 14314 dns_requestevent_t *revent = (dns_requestevent_t *)event; 14315 dns_message_t *msg = NULL; 14316 char master[ISC_SOCKADDR_FORMATSIZE]; 14317 isc_result_t result; 14318 dns_forward_t *forward; 14319 dns_zone_t *zone; 14320 14321 UNUSED(task); 14322 14323 forward = revent->ev_arg; 14324 INSIST(DNS_FORWARD_VALID(forward)); 14325 zone = forward->zone; 14326 INSIST(DNS_ZONE_VALID(zone)); 14327 14328 ENTER; 14329 14330 isc_sockaddr_format(&forward->addr, master, sizeof(master)); 14331 14332 if (revent->result != ISC_R_SUCCESS) { 14333 dns_zone_log(zone, ISC_LOG_INFO, 14334 "could not forward dynamic update to %s: %s", 14335 master, dns_result_totext(revent->result)); 14336 goto next_master; 14337 } 14338 14339 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 14340 if (result != ISC_R_SUCCESS) 14341 goto next_master; 14342 14343 result = dns_request_getresponse(revent->request, msg, 14344 DNS_MESSAGEPARSE_PRESERVEORDER | 14345 DNS_MESSAGEPARSE_CLONEBUFFER); 14346 if (result != ISC_R_SUCCESS) 14347 goto next_master; 14348 14349 switch (msg->rcode) { 14350 /* 14351 * Pass these rcodes back to client. 14352 */ 14353 case dns_rcode_noerror: 14354 case dns_rcode_yxdomain: 14355 case dns_rcode_yxrrset: 14356 case dns_rcode_nxrrset: 14357 case dns_rcode_refused: 14358 case dns_rcode_nxdomain: { 14359 char rcode[128]; 14360 isc_buffer_t rb; 14361 14362 isc_buffer_init(&rb, rcode, sizeof(rcode)); 14363 (void)dns_rcode_totext(msg->rcode, &rb); 14364 dns_zone_log(zone, ISC_LOG_INFO, 14365 "forwarded dynamic update: " 14366 "master %s returned: %.*s", 14367 master, (int)rb.used, rcode); 14368 break; 14369 } 14370 14371 /* These should not occur if the masters/zone are valid. */ 14372 case dns_rcode_notzone: 14373 case dns_rcode_notauth: { 14374 char rcode[128]; 14375 isc_buffer_t rb; 14376 14377 isc_buffer_init(&rb, rcode, sizeof(rcode)); 14378 (void)dns_rcode_totext(msg->rcode, &rb); 14379 dns_zone_log(zone, ISC_LOG_WARNING, 14380 "forwarding dynamic update: " 14381 "unexpected response: master %s returned: %.*s", 14382 master, (int)rb.used, rcode); 14383 goto next_master; 14384 } 14385 14386 /* Try another server for these rcodes. */ 14387 case dns_rcode_formerr: 14388 case dns_rcode_servfail: 14389 case dns_rcode_notimp: 14390 case dns_rcode_badvers: 14391 default: 14392 goto next_master; 14393 } 14394 14395 /* call callback */ 14396 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg); 14397 msg = NULL; 14398 dns_request_destroy(&forward->request); 14399 forward_destroy(forward); 14400 isc_event_free(&event); 14401 return; 14402 14403 next_master: 14404 if (msg != NULL) 14405 dns_message_destroy(&msg); 14406 isc_event_free(&event); 14407 forward->which++; 14408 dns_request_destroy(&forward->request); 14409 result = sendtomaster(forward); 14410 if (result != ISC_R_SUCCESS) { 14411 /* call callback */ 14412 dns_zone_log(zone, ISC_LOG_DEBUG(3), 14413 "exhausted dynamic update forwarder list"); 14414 (forward->callback)(forward->callback_arg, result, NULL); 14415 forward_destroy(forward); 14416 } 14417} 14418 14419isc_result_t 14420dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg, 14421 dns_updatecallback_t callback, void *callback_arg) 14422{ 14423 dns_forward_t *forward; 14424 isc_result_t result; 14425 isc_region_t *mr; 14426 14427 REQUIRE(DNS_ZONE_VALID(zone)); 14428 REQUIRE(msg != NULL); 14429 REQUIRE(callback != NULL); 14430 14431 forward = isc_mem_get(zone->mctx, sizeof(*forward)); 14432 if (forward == NULL) 14433 return (ISC_R_NOMEMORY); 14434 14435 forward->request = NULL; 14436 forward->zone = NULL; 14437 forward->msgbuf = NULL; 14438 forward->which = 0; 14439 forward->mctx = 0; 14440 forward->callback = callback; 14441 forward->callback_arg = callback_arg; 14442 ISC_LINK_INIT(forward, link); 14443 forward->magic = FORWARD_MAGIC; 14444 14445 mr = dns_message_getrawmessage(msg); 14446 if (mr == NULL) { 14447 result = ISC_R_UNEXPECTEDEND; 14448 goto cleanup; 14449 } 14450 14451 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length); 14452 if (result != ISC_R_SUCCESS) 14453 goto cleanup; 14454 result = isc_buffer_copyregion(forward->msgbuf, mr); 14455 if (result != ISC_R_SUCCESS) 14456 goto cleanup; 14457 14458 isc_mem_attach(zone->mctx, &forward->mctx); 14459 dns_zone_iattach(zone, &forward->zone); 14460 result = sendtomaster(forward); 14461 14462 cleanup: 14463 if (result != ISC_R_SUCCESS) { 14464 forward_destroy(forward); 14465 } 14466 return (result); 14467} 14468 14469isc_result_t 14470dns_zone_next(dns_zone_t *zone, dns_zone_t **next) { 14471 REQUIRE(DNS_ZONE_VALID(zone)); 14472 REQUIRE(next != NULL && *next == NULL); 14473 14474 *next = ISC_LIST_NEXT(zone, link); 14475 if (*next == NULL) 14476 return (ISC_R_NOMORE); 14477 else 14478 return (ISC_R_SUCCESS); 14479} 14480 14481isc_result_t 14482dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) { 14483 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14484 REQUIRE(first != NULL && *first == NULL); 14485 14486 *first = ISC_LIST_HEAD(zmgr->zones); 14487 if (*first == NULL) 14488 return (ISC_R_NOMORE); 14489 else 14490 return (ISC_R_SUCCESS); 14491} 14492 14493/*** 14494 *** Zone manager. 14495 ***/ 14496 14497isc_result_t 14498dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, 14499 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, 14500 dns_zonemgr_t **zmgrp) 14501{ 14502 dns_zonemgr_t *zmgr; 14503 isc_result_t result; 14504 isc_interval_t interval; 14505 14506 zmgr = isc_mem_get(mctx, sizeof(*zmgr)); 14507 if (zmgr == NULL) 14508 return (ISC_R_NOMEMORY); 14509 zmgr->mctx = NULL; 14510 zmgr->refs = 1; 14511 isc_mem_attach(mctx, &zmgr->mctx); 14512 zmgr->taskmgr = taskmgr; 14513 zmgr->timermgr = timermgr; 14514 zmgr->socketmgr = socketmgr; 14515 zmgr->zonetasks = NULL; 14516 zmgr->loadtasks = NULL; 14517 zmgr->mctxpool = NULL; 14518 zmgr->task = NULL; 14519 zmgr->notifyrl = NULL; 14520 zmgr->refreshrl = NULL; 14521 ISC_LIST_INIT(zmgr->zones); 14522 ISC_LIST_INIT(zmgr->waiting_for_xfrin); 14523 ISC_LIST_INIT(zmgr->xfrin_in_progress); 14524 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable)); 14525 result = isc_rwlock_init(&zmgr->rwlock, 0, 0); 14526 if (result != ISC_R_SUCCESS) 14527 goto free_mem; 14528 14529 zmgr->transfersin = 10; 14530 zmgr->transfersperns = 2; 14531 14532 /* Unreachable lock. */ 14533 result = isc_rwlock_init(&zmgr->urlock, 0, 0); 14534 if (result != ISC_R_SUCCESS) 14535 goto free_rwlock; 14536 14537 /* Create a single task for queueing of SOA queries. */ 14538 result = isc_task_create(taskmgr, 1, &zmgr->task); 14539 if (result != ISC_R_SUCCESS) 14540 goto free_urlock; 14541 14542 isc_task_setname(zmgr->task, "zmgr", zmgr); 14543 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 14544 &zmgr->notifyrl); 14545 if (result != ISC_R_SUCCESS) 14546 goto free_task; 14547 14548 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 14549 &zmgr->refreshrl); 14550 if (result != ISC_R_SUCCESS) 14551 goto free_notifyrl; 14552 14553 /* default to 20 refresh queries / notifies per second. */ 14554 isc_interval_set(&interval, 0, 1000000000/2); 14555 result = isc_ratelimiter_setinterval(zmgr->notifyrl, &interval); 14556 RUNTIME_CHECK(result == ISC_R_SUCCESS); 14557 isc_ratelimiter_setpertic(zmgr->notifyrl, 10); 14558 14559 result = isc_ratelimiter_setinterval(zmgr->refreshrl, &interval); 14560 RUNTIME_CHECK(result == ISC_R_SUCCESS); 14561 isc_ratelimiter_setpertic(zmgr->refreshrl, 10); 14562 14563 zmgr->iolimit = 1; 14564 zmgr->ioactive = 0; 14565 ISC_LIST_INIT(zmgr->high); 14566 ISC_LIST_INIT(zmgr->low); 14567 14568 result = isc_mutex_init(&zmgr->iolock); 14569 if (result != ISC_R_SUCCESS) 14570 goto free_refreshrl; 14571 14572 zmgr->magic = ZONEMGR_MAGIC; 14573 14574 *zmgrp = zmgr; 14575 return (ISC_R_SUCCESS); 14576 14577#if 0 14578 free_iolock: 14579 DESTROYLOCK(&zmgr->iolock); 14580#endif 14581 free_refreshrl: 14582 isc_ratelimiter_detach(&zmgr->refreshrl); 14583 free_notifyrl: 14584 isc_ratelimiter_detach(&zmgr->notifyrl); 14585 free_task: 14586 isc_task_detach(&zmgr->task); 14587 free_urlock: 14588 isc_rwlock_destroy(&zmgr->urlock); 14589 free_rwlock: 14590 isc_rwlock_destroy(&zmgr->rwlock); 14591 free_mem: 14592 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); 14593 isc_mem_detach(&mctx); 14594 return (result); 14595} 14596 14597isc_result_t 14598dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) { 14599 isc_result_t result; 14600 isc_mem_t *mctx = NULL; 14601 dns_zone_t *zone = NULL; 14602 void *item; 14603 14604 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14605 REQUIRE(zonep != NULL && *zonep == NULL); 14606 14607 if (zmgr->mctxpool == NULL) 14608 return (ISC_R_FAILURE); 14609 14610 item = isc_pool_get(zmgr->mctxpool); 14611 if (item == NULL) 14612 return (ISC_R_FAILURE); 14613 14614 isc_mem_attach((isc_mem_t *) item, &mctx); 14615 result = dns_zone_create(&zone, mctx); 14616 isc_mem_detach(&mctx); 14617 14618 if (result == ISC_R_SUCCESS) 14619 *zonep = zone; 14620 14621 return (result); 14622} 14623 14624isc_result_t 14625dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 14626 isc_result_t result; 14627 14628 REQUIRE(DNS_ZONE_VALID(zone)); 14629 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14630 14631 if (zmgr->zonetasks == NULL) 14632 return (ISC_R_FAILURE); 14633 14634 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 14635 LOCK_ZONE(zone); 14636 REQUIRE(zone->task == NULL); 14637 REQUIRE(zone->timer == NULL); 14638 REQUIRE(zone->zmgr == NULL); 14639 14640 isc_taskpool_gettask(zmgr->zonetasks, &zone->task); 14641 isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask); 14642 14643 /* 14644 * Set the task name. The tag will arbitrarily point to one 14645 * of the zones sharing the task (in practice, the one 14646 * to be managed last). 14647 */ 14648 isc_task_setname(zone->task, "zone", zone); 14649 isc_task_setname(zone->loadtask, "loadzone", zone); 14650 14651 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, 14652 NULL, NULL, 14653 zone->task, zone_timer, zone, 14654 &zone->timer); 14655 14656 if (result != ISC_R_SUCCESS) 14657 goto cleanup_tasks; 14658 14659 /* 14660 * The timer "holds" a iref. 14661 */ 14662 zone->irefs++; 14663 INSIST(zone->irefs != 0); 14664 14665 ISC_LIST_APPEND(zmgr->zones, zone, link); 14666 zone->zmgr = zmgr; 14667 zmgr->refs++; 14668 14669 goto unlock; 14670 14671 cleanup_tasks: 14672 isc_task_detach(&zone->loadtask); 14673 isc_task_detach(&zone->task); 14674 14675 unlock: 14676 UNLOCK_ZONE(zone); 14677 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 14678 return (result); 14679} 14680 14681void 14682dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 14683 isc_boolean_t free_now = ISC_FALSE; 14684 14685 REQUIRE(DNS_ZONE_VALID(zone)); 14686 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14687 REQUIRE(zone->zmgr == zmgr); 14688 14689 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 14690 LOCK_ZONE(zone); 14691 14692 ISC_LIST_UNLINK(zmgr->zones, zone, link); 14693 zone->zmgr = NULL; 14694 zmgr->refs--; 14695 if (zmgr->refs == 0) 14696 free_now = ISC_TRUE; 14697 14698 UNLOCK_ZONE(zone); 14699 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 14700 14701 if (free_now) 14702 zonemgr_free(zmgr); 14703 ENSURE(zone->zmgr == NULL); 14704} 14705 14706void 14707dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) { 14708 REQUIRE(DNS_ZONEMGR_VALID(source)); 14709 REQUIRE(target != NULL && *target == NULL); 14710 14711 RWLOCK(&source->rwlock, isc_rwlocktype_write); 14712 REQUIRE(source->refs > 0); 14713 source->refs++; 14714 INSIST(source->refs > 0); 14715 RWUNLOCK(&source->rwlock, isc_rwlocktype_write); 14716 *target = source; 14717} 14718 14719void 14720dns_zonemgr_detach(dns_zonemgr_t **zmgrp) { 14721 dns_zonemgr_t *zmgr; 14722 isc_boolean_t free_now = ISC_FALSE; 14723 14724 REQUIRE(zmgrp != NULL); 14725 zmgr = *zmgrp; 14726 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14727 14728 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 14729 zmgr->refs--; 14730 if (zmgr->refs == 0) 14731 free_now = ISC_TRUE; 14732 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 14733 14734 if (free_now) 14735 zonemgr_free(zmgr); 14736 *zmgrp = NULL; 14737} 14738 14739isc_result_t 14740dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) { 14741 dns_zone_t *p; 14742 14743 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14744 14745 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 14746 for (p = ISC_LIST_HEAD(zmgr->zones); 14747 p != NULL; 14748 p = ISC_LIST_NEXT(p, link)) 14749 { 14750 dns_zone_maintenance(p); 14751 } 14752 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 14753 14754 /* 14755 * Recent configuration changes may have increased the 14756 * amount of available transfers quota. Make sure any 14757 * transfers currently blocked on quota get started if 14758 * possible. 14759 */ 14760 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 14761 zmgr_resume_xfrs(zmgr, ISC_TRUE); 14762 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 14763 return (ISC_R_SUCCESS); 14764} 14765 14766void 14767dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) { 14768 14769 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14770 14771 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 14772 zmgr_resume_xfrs(zmgr, ISC_TRUE); 14773 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 14774} 14775 14776void 14777dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) { 14778 dns_zone_t *zone; 14779 14780 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14781 14782 isc_ratelimiter_shutdown(zmgr->notifyrl); 14783 isc_ratelimiter_shutdown(zmgr->refreshrl); 14784 14785 if (zmgr->task != NULL) 14786 isc_task_destroy(&zmgr->task); 14787 if (zmgr->zonetasks != NULL) 14788 isc_taskpool_destroy(&zmgr->zonetasks); 14789 if (zmgr->loadtasks != NULL) 14790 isc_taskpool_destroy(&zmgr->loadtasks); 14791 if (zmgr->mctxpool != NULL) 14792 isc_pool_destroy(&zmgr->mctxpool); 14793 14794 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 14795 for (zone = ISC_LIST_HEAD(zmgr->zones); 14796 zone != NULL; 14797 zone = ISC_LIST_NEXT(zone, link)) 14798 { 14799 LOCK_ZONE(zone); 14800 forward_cancel(zone); 14801 UNLOCK_ZONE(zone); 14802 } 14803 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 14804} 14805 14806static isc_result_t 14807mctxinit(void **target, void *arg) { 14808 isc_result_t result; 14809 isc_mem_t *mctx = NULL; 14810 14811 UNUSED(arg); 14812 14813 REQUIRE(target != NULL && *target == NULL); 14814 14815 result = isc_mem_create(0, 0, &mctx); 14816 if (result != ISC_R_SUCCESS) 14817 return (result); 14818 isc_mem_setname(mctx, "zonemgr-pool", NULL); 14819 14820 *target = mctx; 14821 return (ISC_R_SUCCESS); 14822} 14823 14824static void 14825mctxfree(void **target) { 14826 isc_mem_t *mctx = *(isc_mem_t **) target; 14827 isc_mem_detach(&mctx); 14828 *target = NULL; 14829} 14830 14831#define ZONES_PER_TASK 100 14832#define ZONES_PER_MCTX 1000 14833 14834isc_result_t 14835dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) { 14836 isc_result_t result; 14837 int ntasks = num_zones / ZONES_PER_TASK; 14838 int nmctx = num_zones / ZONES_PER_MCTX; 14839 isc_taskpool_t *pool = NULL; 14840 isc_pool_t *mctxpool = NULL; 14841 14842 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14843 14844 /* 14845 * For anything fewer than 1000 zones we use 10 tasks in 14846 * the task pools. More than that, and we'll scale at one 14847 * task per 100 zones. Similarly, for anything smaller than 14848 * 2000 zones we use 2 memory contexts, then scale at 1:1000. 14849 */ 14850 if (ntasks < 10) 14851 ntasks = 10; 14852 if (nmctx < 2) 14853 nmctx = 2; 14854 14855 /* Create or resize the zone task pools. */ 14856 if (zmgr->zonetasks == NULL) 14857 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, 14858 ntasks, 2, &pool); 14859 else 14860 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool); 14861 14862 if (result == ISC_R_SUCCESS) 14863 zmgr->zonetasks = pool; 14864 14865 pool = NULL; 14866 if (zmgr->loadtasks == NULL) 14867 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, 14868 ntasks, 2, &pool); 14869 else 14870 result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool); 14871 14872 if (result == ISC_R_SUCCESS) 14873 zmgr->loadtasks = pool; 14874 14875#ifdef BIND9 14876 /* 14877 * We always set all tasks in the zone-load task pool to 14878 * privileged. This prevents other tasks in the system from 14879 * running while the server task manager is in privileged 14880 * mode. 14881 * 14882 * NOTE: If we start using task privileges for any other 14883 * part of the system than zone tasks, then this will need to be 14884 * revisted. In that case we'd want to turn on privileges for 14885 * zone tasks only when we were loading, and turn them off the 14886 * rest of the time. For now, however, it's okay to just 14887 * set it and forget it. 14888 */ 14889 isc_taskpool_setprivilege(zmgr->loadtasks, ISC_TRUE); 14890#endif 14891 14892 /* Create or resize the zone memory context pool. */ 14893 if (zmgr->mctxpool == NULL) 14894 result = isc_pool_create(zmgr->mctx, nmctx, mctxfree, 14895 mctxinit, NULL, &mctxpool); 14896 else 14897 result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool); 14898 14899 if (result == ISC_R_SUCCESS) 14900 zmgr->mctxpool = mctxpool; 14901 14902 return (result); 14903} 14904 14905static void 14906zonemgr_free(dns_zonemgr_t *zmgr) { 14907 isc_mem_t *mctx; 14908 14909 INSIST(zmgr->refs == 0); 14910 INSIST(ISC_LIST_EMPTY(zmgr->zones)); 14911 14912 zmgr->magic = 0; 14913 14914 DESTROYLOCK(&zmgr->iolock); 14915 isc_ratelimiter_detach(&zmgr->notifyrl); 14916 isc_ratelimiter_detach(&zmgr->refreshrl); 14917 14918 isc_rwlock_destroy(&zmgr->urlock); 14919 isc_rwlock_destroy(&zmgr->rwlock); 14920 mctx = zmgr->mctx; 14921 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); 14922 isc_mem_detach(&mctx); 14923} 14924 14925void 14926dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) { 14927 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14928 14929 zmgr->transfersin = value; 14930} 14931 14932isc_uint32_t 14933dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) { 14934 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14935 14936 return (zmgr->transfersin); 14937} 14938 14939void 14940dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) { 14941 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14942 14943 zmgr->transfersperns = value; 14944} 14945 14946isc_uint32_t 14947dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) { 14948 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14949 14950 return (zmgr->transfersperns); 14951} 14952 14953/* 14954 * Try to start a new incoming zone transfer to fill a quota 14955 * slot that was just vacated. 14956 * 14957 * Requires: 14958 * The zone manager is locked by the caller. 14959 */ 14960static void 14961zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) { 14962 dns_zone_t *zone; 14963 dns_zone_t *next; 14964 14965 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); 14966 zone != NULL; 14967 zone = next) 14968 { 14969 isc_result_t result; 14970 next = ISC_LIST_NEXT(zone, statelink); 14971 result = zmgr_start_xfrin_ifquota(zmgr, zone); 14972 if (result == ISC_R_SUCCESS) { 14973 if (multi) 14974 continue; 14975 /* 14976 * We successfully filled the slot. We're done. 14977 */ 14978 break; 14979 } else if (result == ISC_R_QUOTA) { 14980 /* 14981 * Not enough quota. This is probably the per-server 14982 * quota, because we usually get called when a unit of 14983 * global quota has just been freed. Try the next 14984 * zone, it may succeed if it uses another master. 14985 */ 14986 continue; 14987 } else { 14988 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14989 "starting zone transfer: %s", 14990 isc_result_totext(result)); 14991 break; 14992 } 14993 } 14994} 14995 14996/* 14997 * Try to start an incoming zone transfer for 'zone', quota permitting. 14998 * 14999 * Requires: 15000 * The zone manager is locked by the caller. 15001 * 15002 * Returns: 15003 * ISC_R_SUCCESS There was enough quota and we attempted to 15004 * start a transfer. zone_xfrdone() has been or will 15005 * be called. 15006 * ISC_R_QUOTA Not enough quota. 15007 * Others Failure. 15008 */ 15009static isc_result_t 15010zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 15011 dns_peer_t *peer = NULL; 15012 isc_netaddr_t masterip; 15013 isc_uint32_t nxfrsin, nxfrsperns; 15014 dns_zone_t *x; 15015 isc_uint32_t maxtransfersin, maxtransfersperns; 15016 isc_event_t *e; 15017 15018 /* 15019 * If we are exiting just pretend we got quota so the zone will 15020 * be cleaned up in the zone's task context. 15021 */ 15022 LOCK_ZONE(zone); 15023 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 15024 UNLOCK_ZONE(zone); 15025 goto gotquota; 15026 } 15027 15028 /* 15029 * Find any configured information about the server we'd 15030 * like to transfer this zone from. 15031 */ 15032 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 15033 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer); 15034 UNLOCK_ZONE(zone); 15035 15036 /* 15037 * Determine the total maximum number of simultaneous 15038 * transfers allowed, and the maximum for this specific 15039 * master. 15040 */ 15041 maxtransfersin = zmgr->transfersin; 15042 maxtransfersperns = zmgr->transfersperns; 15043 if (peer != NULL) 15044 (void)dns_peer_gettransfers(peer, &maxtransfersperns); 15045 15046 /* 15047 * Count the total number of transfers that are in progress, 15048 * and the number of transfers in progress from this master. 15049 * We linearly scan a list of all transfers; if this turns 15050 * out to be too slow, we could hash on the master address. 15051 */ 15052 nxfrsin = nxfrsperns = 0; 15053 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress); 15054 x != NULL; 15055 x = ISC_LIST_NEXT(x, statelink)) 15056 { 15057 isc_netaddr_t xip; 15058 15059 LOCK_ZONE(x); 15060 isc_netaddr_fromsockaddr(&xip, &x->masteraddr); 15061 UNLOCK_ZONE(x); 15062 15063 nxfrsin++; 15064 if (isc_netaddr_equal(&xip, &masterip)) 15065 nxfrsperns++; 15066 } 15067 15068 /* Enforce quota. */ 15069 if (nxfrsin >= maxtransfersin) 15070 return (ISC_R_QUOTA); 15071 15072 if (nxfrsperns >= maxtransfersperns) 15073 return (ISC_R_QUOTA); 15074 15075 gotquota: 15076 /* 15077 * We have sufficient quota. Move the zone to the "xfrin_in_progress" 15078 * list and send it an event to let it start the actual transfer in the 15079 * context of its own task. 15080 */ 15081 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN, 15082 got_transfer_quota, zone, sizeof(isc_event_t)); 15083 if (e == NULL) 15084 return (ISC_R_NOMEMORY); 15085 15086 LOCK_ZONE(zone); 15087 INSIST(zone->statelist == &zmgr->waiting_for_xfrin); 15088 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink); 15089 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink); 15090 zone->statelist = &zmgr->xfrin_in_progress; 15091 isc_task_send(zone->task, &e); 15092 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started."); 15093 UNLOCK_ZONE(zone); 15094 15095 return (ISC_R_SUCCESS); 15096} 15097 15098void 15099dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) { 15100 15101 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15102 REQUIRE(iolimit > 0); 15103 15104 zmgr->iolimit = iolimit; 15105} 15106 15107isc_uint32_t 15108dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) { 15109 15110 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15111 15112 return (zmgr->iolimit); 15113} 15114 15115/* 15116 * Get permission to request a file handle from the OS. 15117 * An event will be sent to action when one is available. 15118 * There are two queues available (high and low), the high 15119 * queue will be serviced before the low one. 15120 * 15121 * zonemgr_putio() must be called after the event is delivered to 15122 * 'action'. 15123 */ 15124 15125static isc_result_t 15126zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high, 15127 isc_task_t *task, isc_taskaction_t action, void *arg, 15128 dns_io_t **iop) 15129{ 15130 dns_io_t *io; 15131 isc_boolean_t queue; 15132 15133 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15134 REQUIRE(iop != NULL && *iop == NULL); 15135 15136 io = isc_mem_get(zmgr->mctx, sizeof(*io)); 15137 if (io == NULL) 15138 return (ISC_R_NOMEMORY); 15139 15140 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY, 15141 action, arg, sizeof(*io->event)); 15142 if (io->event == NULL) { 15143 isc_mem_put(zmgr->mctx, io, sizeof(*io)); 15144 return (ISC_R_NOMEMORY); 15145 } 15146 15147 io->zmgr = zmgr; 15148 io->high = high; 15149 io->task = NULL; 15150 isc_task_attach(task, &io->task); 15151 ISC_LINK_INIT(io, link); 15152 io->magic = IO_MAGIC; 15153 15154 LOCK(&zmgr->iolock); 15155 zmgr->ioactive++; 15156 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit); 15157 if (queue) { 15158 if (io->high) 15159 ISC_LIST_APPEND(zmgr->high, io, link); 15160 else 15161 ISC_LIST_APPEND(zmgr->low, io, link); 15162 } 15163 UNLOCK(&zmgr->iolock); 15164 *iop = io; 15165 15166 if (!queue) 15167 isc_task_send(io->task, &io->event); 15168 return (ISC_R_SUCCESS); 15169} 15170 15171static void 15172zonemgr_putio(dns_io_t **iop) { 15173 dns_io_t *io; 15174 dns_io_t *next; 15175 dns_zonemgr_t *zmgr; 15176 15177 REQUIRE(iop != NULL); 15178 io = *iop; 15179 REQUIRE(DNS_IO_VALID(io)); 15180 15181 *iop = NULL; 15182 15183 INSIST(!ISC_LINK_LINKED(io, link)); 15184 INSIST(io->event == NULL); 15185 15186 zmgr = io->zmgr; 15187 isc_task_detach(&io->task); 15188 io->magic = 0; 15189 isc_mem_put(zmgr->mctx, io, sizeof(*io)); 15190 15191 LOCK(&zmgr->iolock); 15192 INSIST(zmgr->ioactive > 0); 15193 zmgr->ioactive--; 15194 next = HEAD(zmgr->high); 15195 if (next == NULL) 15196 next = HEAD(zmgr->low); 15197 if (next != NULL) { 15198 if (next->high) 15199 ISC_LIST_UNLINK(zmgr->high, next, link); 15200 else 15201 ISC_LIST_UNLINK(zmgr->low, next, link); 15202 INSIST(next->event != NULL); 15203 } 15204 UNLOCK(&zmgr->iolock); 15205 if (next != NULL) 15206 isc_task_send(next->task, &next->event); 15207} 15208 15209static void 15210zonemgr_cancelio(dns_io_t *io) { 15211 isc_boolean_t send_event = ISC_FALSE; 15212 15213 REQUIRE(DNS_IO_VALID(io)); 15214 15215 /* 15216 * If we are queued to be run then dequeue. 15217 */ 15218 LOCK(&io->zmgr->iolock); 15219 if (ISC_LINK_LINKED(io, link)) { 15220 if (io->high) 15221 ISC_LIST_UNLINK(io->zmgr->high, io, link); 15222 else 15223 ISC_LIST_UNLINK(io->zmgr->low, io, link); 15224 15225 send_event = ISC_TRUE; 15226 INSIST(io->event != NULL); 15227 } 15228 UNLOCK(&io->zmgr->iolock); 15229 if (send_event) { 15230 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED; 15231 isc_task_send(io->task, &io->event); 15232 } 15233} 15234 15235static void 15236zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) { 15237 char *buf; 15238 int buflen; 15239 isc_result_t result; 15240 15241 buflen = strlen(path) + strlen(templat) + 2; 15242 15243 buf = isc_mem_get(zone->mctx, buflen); 15244 if (buf == NULL) 15245 return; 15246 15247 result = isc_file_template(path, templat, buf, buflen); 15248 if (result != ISC_R_SUCCESS) 15249 goto cleanup; 15250 15251 result = isc_file_renameunique(path, buf); 15252 if (result != ISC_R_SUCCESS) 15253 goto cleanup; 15254 15255 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; " 15256 "renaming file to '%s' for failure analysis and " 15257 "retransferring.", path, buf); 15258 15259 cleanup: 15260 isc_mem_put(zone->mctx, buf, buflen); 15261} 15262 15263#if 0 15264/* Hook for ondestroy notification from a database. */ 15265 15266static void 15267dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) { 15268 dns_db_t *db = event->sender; 15269 UNUSED(task); 15270 15271 isc_event_free(&event); 15272 15273 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 15274 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 15275 "database (%p) destroyed", (void*) db); 15276} 15277#endif 15278 15279void 15280dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) { 15281 isc_interval_t interval; 15282 isc_uint32_t s, ns; 15283 isc_uint32_t pertic; 15284 isc_result_t result; 15285 15286 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15287 15288 if (value == 0) 15289 value = 1; 15290 15291 if (value == 1) { 15292 s = 1; 15293 ns = 0; 15294 pertic = 1; 15295 } else if (value <= 10) { 15296 s = 0; 15297 ns = 1000000000 / value; 15298 pertic = 1; 15299 } else { 15300 s = 0; 15301 ns = (1000000000 / value) * 10; 15302 pertic = 10; 15303 } 15304 15305 isc_interval_set(&interval, s, ns); 15306 15307 result = isc_ratelimiter_setinterval(zmgr->notifyrl, &interval); 15308 RUNTIME_CHECK(result == ISC_R_SUCCESS); 15309 isc_ratelimiter_setpertic(zmgr->notifyrl, pertic); 15310 15311 result = isc_ratelimiter_setinterval(zmgr->refreshrl, &interval); 15312 RUNTIME_CHECK(result == ISC_R_SUCCESS); 15313 isc_ratelimiter_setpertic(zmgr->refreshrl, pertic); 15314 15315 zmgr->serialqueryrate = value; 15316} 15317 15318unsigned int 15319dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) { 15320 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15321 15322 return (zmgr->serialqueryrate); 15323} 15324 15325isc_boolean_t 15326dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 15327 isc_sockaddr_t *local, isc_time_t *now) 15328{ 15329 unsigned int i; 15330 isc_rwlocktype_t locktype; 15331 isc_result_t result; 15332 isc_uint32_t seconds = isc_time_seconds(now); 15333 isc_uint32_t count = 0; 15334 15335 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15336 15337 locktype = isc_rwlocktype_read; 15338 RWLOCK(&zmgr->urlock, locktype); 15339 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { 15340 if (zmgr->unreachable[i].expire >= seconds && 15341 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 15342 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) { 15343 result = isc_rwlock_tryupgrade(&zmgr->urlock); 15344 if (result == ISC_R_SUCCESS) { 15345 locktype = isc_rwlocktype_write; 15346 zmgr->unreachable[i].last = seconds; 15347 count = zmgr->unreachable[i].count; 15348 } 15349 break; 15350 } 15351 } 15352 RWUNLOCK(&zmgr->urlock, locktype); 15353 return (ISC_TF(i < UNREACH_CHACHE_SIZE && count > 1U)); 15354} 15355 15356void 15357dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 15358 isc_sockaddr_t *local) 15359{ 15360 unsigned int i; 15361 isc_rwlocktype_t locktype; 15362 isc_result_t result; 15363 15364 char master[ISC_SOCKADDR_FORMATSIZE]; 15365 char source[ISC_SOCKADDR_FORMATSIZE]; 15366 15367 isc_sockaddr_format(remote, master, sizeof(master)); 15368 isc_sockaddr_format(local, source, sizeof(source)); 15369 15370 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15371 15372 locktype = isc_rwlocktype_read; 15373 RWLOCK(&zmgr->urlock, locktype); 15374 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { 15375 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 15376 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) { 15377 if (zmgr->unreachable[i].expire == 0) 15378 break; 15379 result = isc_rwlock_tryupgrade(&zmgr->urlock); 15380 if (result == ISC_R_SUCCESS) { 15381 locktype = isc_rwlocktype_write; 15382 zmgr->unreachable[i].expire = 0; 15383 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 15384 DNS_LOGMODULE_ZONE, ISC_LOG_INFO, 15385 "master %s (source %s) deleted " 15386 "from unreachable cache", 15387 master, source); 15388 } 15389 break; 15390 } 15391 } 15392 RWUNLOCK(&zmgr->urlock, locktype); 15393} 15394 15395void 15396dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 15397 isc_sockaddr_t *local, isc_time_t *now) 15398{ 15399 isc_uint32_t seconds = isc_time_seconds(now); 15400 isc_uint32_t last = seconds; 15401 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0; 15402 15403 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15404 15405 RWLOCK(&zmgr->urlock, isc_rwlocktype_write); 15406 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { 15407 /* Existing entry? */ 15408 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 15409 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 15410 break; 15411 /* Empty slot? */ 15412 if (zmgr->unreachable[i].expire < seconds) 15413 slot = i; 15414 /* Least recently used slot? */ 15415 if (zmgr->unreachable[i].last < last) { 15416 last = zmgr->unreachable[i].last; 15417 oldest = i; 15418 } 15419 } 15420 if (i < UNREACH_CHACHE_SIZE) { 15421 /* 15422 * Found a existing entry. Update the expire timer and 15423 * last usage timestamps. 15424 */ 15425 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME; 15426 zmgr->unreachable[i].last = seconds; 15427 if (zmgr->unreachable[i].expire < seconds) 15428 zmgr->unreachable[i].count = 1; 15429 else 15430 zmgr->unreachable[i].count++; 15431 } else if (slot != UNREACH_CHACHE_SIZE) { 15432 /* 15433 * Found a empty slot. Add a new entry to the cache. 15434 */ 15435 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME; 15436 zmgr->unreachable[slot].last = seconds; 15437 zmgr->unreachable[slot].remote = *remote; 15438 zmgr->unreachable[slot].local = *local; 15439 zmgr->unreachable[slot].count = 1; 15440 } else { 15441 /* 15442 * Replace the least recently used entry in the cache. 15443 */ 15444 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME; 15445 zmgr->unreachable[oldest].last = seconds; 15446 zmgr->unreachable[oldest].remote = *remote; 15447 zmgr->unreachable[oldest].local = *local; 15448 zmgr->unreachable[oldest].count = 1; 15449 } 15450 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write); 15451} 15452 15453void 15454dns_zone_forcereload(dns_zone_t *zone) { 15455 REQUIRE(DNS_ZONE_VALID(zone)); 15456 15457 if (zone->type == dns_zone_master || 15458 (zone->type == dns_zone_redirect && zone->masters == NULL)) 15459 return; 15460 15461 LOCK_ZONE(zone); 15462 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER); 15463 UNLOCK_ZONE(zone); 15464 dns_zone_refresh(zone); 15465} 15466 15467isc_boolean_t 15468dns_zone_isforced(dns_zone_t *zone) { 15469 REQUIRE(DNS_ZONE_VALID(zone)); 15470 15471 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)); 15472} 15473 15474isc_result_t 15475dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) { 15476 /* 15477 * This function is obsoleted. 15478 */ 15479 UNUSED(zone); 15480 UNUSED(on); 15481 return (ISC_R_NOTIMPLEMENTED); 15482} 15483 15484isc_uint64_t * 15485dns_zone_getstatscounters(dns_zone_t *zone) { 15486 /* 15487 * This function is obsoleted. 15488 */ 15489 UNUSED(zone); 15490 return (NULL); 15491} 15492 15493void 15494dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) { 15495 REQUIRE(DNS_ZONE_VALID(zone)); 15496 REQUIRE(zone->stats == NULL); 15497 15498 LOCK_ZONE(zone); 15499 zone->stats = NULL; 15500 isc_stats_attach(stats, &zone->stats); 15501 UNLOCK_ZONE(zone); 15502} 15503 15504void 15505dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) { 15506 15507 REQUIRE(DNS_ZONE_VALID(zone)); 15508 15509 LOCK_ZONE(zone); 15510 if (zone->requeststats_on && stats == NULL) 15511 zone->requeststats_on = ISC_FALSE; 15512 else if (!zone->requeststats_on && stats != NULL) { 15513 if (zone->requeststats == NULL) { 15514 isc_stats_attach(stats, &zone->requeststats); 15515 zone->requeststats_on = ISC_TRUE; 15516 } 15517 } 15518 UNLOCK_ZONE(zone); 15519} 15520 15521#ifdef NEWSTATS 15522void 15523dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) { 15524 15525 REQUIRE(DNS_ZONE_VALID(zone)); 15526 15527 LOCK_ZONE(zone); 15528 if (zone->requeststats_on && stats != NULL) { 15529 if (zone->rcvquerystats == NULL) { 15530 dns_stats_attach(stats, &zone->rcvquerystats); 15531 zone->requeststats_on = ISC_TRUE; 15532 } 15533 } 15534 UNLOCK_ZONE(zone); 15535} 15536#endif 15537 15538isc_stats_t * 15539dns_zone_getrequeststats(dns_zone_t *zone) { 15540 /* 15541 * We don't lock zone for efficiency reason. This is not catastrophic 15542 * because requeststats must always be valid when requeststats_on is 15543 * true. 15544 * Some counters may be incremented while requeststats_on is becoming 15545 * false, or some cannot be incremented just after the statistics are 15546 * installed, but it shouldn't matter much in practice. 15547 */ 15548 if (zone->requeststats_on) 15549 return (zone->requeststats); 15550 else 15551 return (NULL); 15552} 15553 15554#ifdef NEWSTATS 15555/* 15556 * Return the received query stats bucket 15557 * see note from dns_zone_getrequeststats() 15558 */ 15559dns_stats_t * 15560dns_zone_getrcvquerystats(dns_zone_t *zone) { 15561 if (zone->requeststats_on) 15562 return (zone->rcvquerystats); 15563 else 15564 return (NULL); 15565} 15566#endif 15567 15568void 15569dns_zone_dialup(dns_zone_t *zone) { 15570 15571 REQUIRE(DNS_ZONE_VALID(zone)); 15572 15573 zone_debuglog(zone, "dns_zone_dialup", 3, 15574 "notify = %d, refresh = %d", 15575 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY), 15576 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)); 15577 15578 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) 15579 dns_zone_notify(zone); 15580 if (zone->type != dns_zone_master && zone->masters != NULL && 15581 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 15582 dns_zone_refresh(zone); 15583} 15584 15585void 15586dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) { 15587 REQUIRE(DNS_ZONE_VALID(zone)); 15588 15589 LOCK_ZONE(zone); 15590 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY | 15591 DNS_ZONEFLG_DIALREFRESH | 15592 DNS_ZONEFLG_NOREFRESH); 15593 switch (dialup) { 15594 case dns_dialuptype_no: 15595 break; 15596 case dns_dialuptype_yes: 15597 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY | 15598 DNS_ZONEFLG_DIALREFRESH | 15599 DNS_ZONEFLG_NOREFRESH)); 15600 break; 15601 case dns_dialuptype_notify: 15602 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 15603 break; 15604 case dns_dialuptype_notifypassive: 15605 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 15606 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 15607 break; 15608 case dns_dialuptype_refresh: 15609 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH); 15610 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 15611 break; 15612 case dns_dialuptype_passive: 15613 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 15614 break; 15615 default: 15616 INSIST(0); 15617 } 15618 UNLOCK_ZONE(zone); 15619} 15620 15621isc_result_t 15622dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) { 15623 isc_result_t result = ISC_R_SUCCESS; 15624 15625 REQUIRE(DNS_ZONE_VALID(zone)); 15626 15627 LOCK_ZONE(zone); 15628 result = dns_zone_setstring(zone, &zone->keydirectory, directory); 15629 UNLOCK_ZONE(zone); 15630 15631 return (result); 15632} 15633 15634const char * 15635dns_zone_getkeydirectory(dns_zone_t *zone) { 15636 REQUIRE(DNS_ZONE_VALID(zone)); 15637 15638 return (zone->keydirectory); 15639} 15640 15641unsigned int 15642dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) { 15643 dns_zone_t *zone; 15644 unsigned int count = 0; 15645 15646 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15647 15648 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 15649 switch (state) { 15650 case DNS_ZONESTATE_XFERRUNNING: 15651 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress); 15652 zone != NULL; 15653 zone = ISC_LIST_NEXT(zone, statelink)) 15654 count++; 15655 break; 15656 case DNS_ZONESTATE_XFERDEFERRED: 15657 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); 15658 zone != NULL; 15659 zone = ISC_LIST_NEXT(zone, statelink)) 15660 count++; 15661 break; 15662 case DNS_ZONESTATE_SOAQUERY: 15663 for (zone = ISC_LIST_HEAD(zmgr->zones); 15664 zone != NULL; 15665 zone = ISC_LIST_NEXT(zone, link)) 15666 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) 15667 count++; 15668 break; 15669 case DNS_ZONESTATE_ANY: 15670 for (zone = ISC_LIST_HEAD(zmgr->zones); 15671 zone != NULL; 15672 zone = ISC_LIST_NEXT(zone, link)) { 15673 dns_view_t *view = zone->view; 15674 if (view != NULL && strcmp(view->name, "_bind") == 0) 15675 continue; 15676 count++; 15677 } 15678 break; 15679 default: 15680 INSIST(0); 15681 } 15682 15683 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 15684 15685 return (count); 15686} 15687 15688isc_result_t 15689dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) { 15690 isc_boolean_t ok = ISC_TRUE; 15691 isc_boolean_t fail = ISC_FALSE; 15692 char namebuf[DNS_NAME_FORMATSIZE]; 15693 char namebuf2[DNS_NAME_FORMATSIZE]; 15694 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 15695 int level = ISC_LOG_WARNING; 15696 dns_name_t bad; 15697 15698 REQUIRE(DNS_ZONE_VALID(zone)); 15699 15700 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) 15701 return (ISC_R_SUCCESS); 15702 15703 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) { 15704 level = ISC_LOG_ERROR; 15705 fail = ISC_TRUE; 15706 } 15707 15708 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE); 15709 if (!ok) { 15710 dns_name_format(name, namebuf, sizeof(namebuf)); 15711 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 15712 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf, 15713 dns_result_totext(DNS_R_BADOWNERNAME)); 15714 if (fail) 15715 return (DNS_R_BADOWNERNAME); 15716 } 15717 15718 dns_name_init(&bad, NULL); 15719 ok = dns_rdata_checknames(rdata, name, &bad); 15720 if (!ok) { 15721 dns_name_format(name, namebuf, sizeof(namebuf)); 15722 dns_name_format(&bad, namebuf2, sizeof(namebuf2)); 15723 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 15724 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf, 15725 namebuf2, dns_result_totext(DNS_R_BADNAME)); 15726 if (fail) 15727 return (DNS_R_BADNAME); 15728 } 15729 15730 return (ISC_R_SUCCESS); 15731} 15732 15733void 15734dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) { 15735 REQUIRE(DNS_ZONE_VALID(zone)); 15736 zone->checkmx = checkmx; 15737} 15738 15739void 15740dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) { 15741 REQUIRE(DNS_ZONE_VALID(zone)); 15742 zone->checksrv = checksrv; 15743} 15744 15745void 15746dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) { 15747 REQUIRE(DNS_ZONE_VALID(zone)); 15748 zone->checkns = checkns; 15749} 15750 15751void 15752dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) { 15753 REQUIRE(DNS_ZONE_VALID(zone)); 15754 15755 LOCK_ZONE(zone); 15756 zone->isself = isself; 15757 zone->isselfarg = arg; 15758 UNLOCK_ZONE(zone); 15759} 15760 15761void 15762dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) { 15763 REQUIRE(DNS_ZONE_VALID(zone)); 15764 15765 LOCK_ZONE(zone); 15766 zone->notifydelay = delay; 15767 UNLOCK_ZONE(zone); 15768} 15769 15770isc_uint32_t 15771dns_zone_getnotifydelay(dns_zone_t *zone) { 15772 REQUIRE(DNS_ZONE_VALID(zone)); 15773 15774 return (zone->notifydelay); 15775} 15776 15777isc_result_t 15778dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, 15779 isc_uint16_t keyid, isc_boolean_t delete) 15780{ 15781 isc_result_t result; 15782 REQUIRE(DNS_ZONE_VALID(zone)); 15783 15784 dns_zone_log(zone, ISC_LOG_NOTICE, 15785 "dns_zone_signwithkey(algorithm=%u, keyid=%u)", 15786 algorithm, keyid); 15787 LOCK_ZONE(zone); 15788 result = zone_signwithkey(zone, algorithm, keyid, delete); 15789 UNLOCK_ZONE(zone); 15790 15791 return (result); 15792} 15793 15794static const char *hex = "0123456789ABCDEF"; 15795 15796isc_result_t 15797dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 15798 isc_result_t result; 15799 char salt[255*2+1]; 15800 unsigned int i, j; 15801 15802 REQUIRE(DNS_ZONE_VALID(zone)); 15803 15804 if (nsec3param->salt_length != 0) { 15805 INSIST((nsec3param->salt_length * 2U) < sizeof(salt)); 15806 for (i = 0, j = 0; i < nsec3param->salt_length; i++) { 15807 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf]; 15808 salt[j++] = hex[nsec3param->salt[i] & 0xf]; 15809 } 15810 salt[j] = '\0'; 15811 } else 15812 strcpy(salt, "-"); 15813 dns_zone_log(zone, ISC_LOG_NOTICE, 15814 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)", 15815 nsec3param->hash, nsec3param->iterations, 15816 salt); 15817 LOCK_ZONE(zone); 15818 result = zone_addnsec3chain(zone, nsec3param); 15819 UNLOCK_ZONE(zone); 15820 15821 return (result); 15822} 15823 15824void 15825dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) { 15826 REQUIRE(DNS_ZONE_VALID(zone)); 15827 15828 if (nodes == 0) 15829 nodes = 1; 15830 zone->nodes = nodes; 15831} 15832 15833void 15834dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) { 15835 REQUIRE(DNS_ZONE_VALID(zone)); 15836 15837 /* 15838 * We treat signatures as a signed value so explicitly 15839 * limit its range here. 15840 */ 15841 if (signatures > ISC_INT32_MAX) 15842 signatures = ISC_INT32_MAX; 15843 else if (signatures == 0) 15844 signatures = 1; 15845 zone->signatures = signatures; 15846} 15847 15848void 15849dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) { 15850 REQUIRE(DNS_ZONE_VALID(zone)); 15851 zone->privatetype = type; 15852} 15853 15854dns_rdatatype_t 15855dns_zone_getprivatetype(dns_zone_t *zone) { 15856 REQUIRE(DNS_ZONE_VALID(zone)); 15857 return (zone->privatetype); 15858} 15859 15860static isc_result_t 15861zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid, 15862 isc_boolean_t delete) 15863{ 15864 dns_signing_t *signing; 15865 dns_signing_t *current; 15866 isc_result_t result = ISC_R_SUCCESS; 15867 isc_time_t now; 15868 dns_db_t *db = NULL; 15869 15870 signing = isc_mem_get(zone->mctx, sizeof *signing); 15871 if (signing == NULL) 15872 return (ISC_R_NOMEMORY); 15873 15874 signing->magic = 0; 15875 signing->db = NULL; 15876 signing->dbiterator = NULL; 15877 signing->algorithm = algorithm; 15878 signing->keyid = keyid; 15879 signing->delete = delete; 15880 signing->done = ISC_FALSE; 15881 15882 TIME_NOW(&now); 15883 15884 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 15885 if (zone->db != NULL) 15886 dns_db_attach(zone->db, &db); 15887 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 15888 15889 if (db == NULL) { 15890 result = ISC_R_NOTFOUND; 15891 goto cleanup; 15892 } 15893 15894 dns_db_attach(db, &signing->db); 15895 15896 for (current = ISC_LIST_HEAD(zone->signing); 15897 current != NULL; 15898 current = ISC_LIST_NEXT(current, link)) { 15899 if (current->db == signing->db && 15900 current->algorithm == signing->algorithm && 15901 current->keyid == signing->keyid) { 15902 if (current->delete != signing->delete) 15903 current->done = ISC_TRUE; 15904 else 15905 goto cleanup; 15906 } 15907 } 15908 15909 result = dns_db_createiterator(signing->db, 0, 15910 &signing->dbiterator); 15911 15912 if (result == ISC_R_SUCCESS) 15913 result = dns_dbiterator_first(signing->dbiterator); 15914 if (result == ISC_R_SUCCESS) { 15915 dns_dbiterator_pause(signing->dbiterator); 15916 ISC_LIST_INITANDAPPEND(zone->signing, signing, link); 15917 signing = NULL; 15918 if (isc_time_isepoch(&zone->signingtime)) { 15919 zone->signingtime = now; 15920 if (zone->task != NULL) 15921 zone_settimer(zone, &now); 15922 } 15923 } 15924 15925 cleanup: 15926 if (signing != NULL) { 15927 if (signing->db != NULL) 15928 dns_db_detach(&signing->db); 15929 if (signing->dbiterator != NULL) 15930 dns_dbiterator_destroy(&signing->dbiterator); 15931 isc_mem_put(zone->mctx, signing, sizeof *signing); 15932 } 15933 if (db != NULL) 15934 dns_db_detach(&db); 15935 return (result); 15936} 15937 15938static void 15939logmsg(const char *format, ...) { 15940 va_list args; 15941 va_start(args, format); 15942 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, 15943 ISC_LOG_DEBUG(1), format, args); 15944 va_end(args); 15945} 15946 15947static void 15948clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) { 15949 dns_dnsseckey_t *key; 15950 while (!ISC_LIST_EMPTY(*list)) { 15951 key = ISC_LIST_HEAD(*list); 15952 ISC_LIST_UNLINK(*list, key, link); 15953 dns_dnsseckey_destroy(mctx, &key); 15954 } 15955} 15956 15957/* Called once; *timep should be set to the current time. */ 15958static isc_result_t 15959next_keyevent(dst_key_t *key, isc_stdtime_t *timep) { 15960 isc_result_t result; 15961 isc_stdtime_t now, then = 0, event; 15962 int i; 15963 15964 now = *timep; 15965 15966 for (i = 0; i <= DST_MAX_TIMES; i++) { 15967 result = dst_key_gettime(key, i, &event); 15968 if (result == ISC_R_SUCCESS && event > now && 15969 (then == 0 || event < then)) 15970 then = event; 15971 } 15972 15973 if (then != 0) { 15974 *timep = then; 15975 return (ISC_R_SUCCESS); 15976 } 15977 15978 return (ISC_R_NOTFOUND); 15979} 15980 15981static isc_result_t 15982rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 15983 const dns_rdata_t *rdata, isc_boolean_t *flag) 15984{ 15985 dns_rdataset_t rdataset; 15986 dns_dbnode_t *node = NULL; 15987 isc_result_t result; 15988 15989 dns_rdataset_init(&rdataset); 15990 if (rdata->type == dns_rdatatype_nsec3) 15991 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node)); 15992 else 15993 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); 15994 result = dns_db_findrdataset(db, node, ver, rdata->type, 0, 15995 (isc_stdtime_t) 0, &rdataset, NULL); 15996 if (result == ISC_R_NOTFOUND) { 15997 *flag = ISC_FALSE; 15998 result = ISC_R_SUCCESS; 15999 goto failure; 16000 } 16001 16002 for (result = dns_rdataset_first(&rdataset); 16003 result == ISC_R_SUCCESS; 16004 result = dns_rdataset_next(&rdataset)) { 16005 dns_rdata_t myrdata = DNS_RDATA_INIT; 16006 dns_rdataset_current(&rdataset, &myrdata); 16007 if (!dns_rdata_compare(&myrdata, rdata)) 16008 break; 16009 } 16010 dns_rdataset_disassociate(&rdataset); 16011 if (result == ISC_R_SUCCESS) { 16012 *flag = ISC_TRUE; 16013 } else if (result == ISC_R_NOMORE) { 16014 *flag = ISC_FALSE; 16015 result = ISC_R_SUCCESS; 16016 } 16017 16018 failure: 16019 if (node != NULL) 16020 dns_db_detachnode(db, &node); 16021 return (result); 16022} 16023 16024/* 16025 * Add records to signal the state of signing or of key removal. 16026 */ 16027static isc_result_t 16028add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, 16029 dns_dbversion_t *ver, dns_diff_t *diff, 16030 isc_boolean_t sign_all) 16031{ 16032 dns_difftuple_t *tuple, *newtuple = NULL; 16033 dns_rdata_dnskey_t dnskey; 16034 dns_rdata_t rdata = DNS_RDATA_INIT; 16035 isc_boolean_t flag; 16036 isc_region_t r; 16037 isc_result_t result = ISC_R_SUCCESS; 16038 isc_uint16_t keyid; 16039 unsigned char buf[5]; 16040 dns_name_t *name = dns_db_origin(db); 16041 16042 for (tuple = ISC_LIST_HEAD(diff->tuples); 16043 tuple != NULL; 16044 tuple = ISC_LIST_NEXT(tuple, link)) { 16045 if (tuple->rdata.type != dns_rdatatype_dnskey) 16046 continue; 16047 16048 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL); 16049 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16050 if ((dnskey.flags & 16051 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH)) 16052 != DNS_KEYOWNER_ZONE) 16053 continue; 16054 16055 dns_rdata_toregion(&tuple->rdata, &r); 16056 16057 keyid = dst_region_computeid(&r, dnskey.algorithm); 16058 16059 buf[0] = dnskey.algorithm; 16060 buf[1] = (keyid & 0xff00) >> 8; 16061 buf[2] = (keyid & 0xff); 16062 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1; 16063 buf[4] = 0; 16064 rdata.data = buf; 16065 rdata.length = sizeof(buf); 16066 rdata.type = privatetype; 16067 rdata.rdclass = tuple->rdata.rdclass; 16068 16069 if (sign_all || tuple->op == DNS_DIFFOP_DEL) { 16070 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 16071 if (flag) 16072 continue; 16073 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, 16074 name, 0, &rdata, &newtuple)); 16075 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 16076 INSIST(newtuple == NULL); 16077 } 16078 16079 /* 16080 * Remove any record which says this operation has already 16081 * completed. 16082 */ 16083 buf[4] = 1; 16084 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 16085 if (flag) { 16086 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, 16087 name, 0, &rdata, &newtuple)); 16088 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 16089 INSIST(newtuple == NULL); 16090 } 16091 } 16092 failure: 16093 return (result); 16094} 16095 16096static isc_result_t 16097sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 16098 dns_diff_t *diff, zonediff_t *zonediff) 16099{ 16100 isc_result_t result; 16101 isc_stdtime_t now, inception, soaexpire; 16102 isc_boolean_t check_ksk, keyset_kskonly; 16103 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 16104 unsigned int nkeys = 0, i; 16105 dns_difftuple_t *tuple; 16106 16107 result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS, 16108 zone_keys, &nkeys); 16109 if (result != ISC_R_SUCCESS) { 16110 dns_zone_log(zone, ISC_LOG_ERROR, 16111 "sign_apex:find_zone_keys -> %s", 16112 dns_result_totext(result)); 16113 return (result); 16114 } 16115 16116 isc_stdtime_get(&now); 16117 inception = now - 3600; /* Allow for clock skew. */ 16118 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 16119 16120 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 16121 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 16122 16123 /* 16124 * See if update_sigs will update DNSKEY signature and if not 16125 * cause them to sign so that so that newly activated keys 16126 * are used. 16127 */ 16128 for (tuple = ISC_LIST_HEAD(diff->tuples); 16129 tuple != NULL; 16130 tuple = ISC_LIST_NEXT(tuple, link)) { 16131 if (tuple->rdata.type == dns_rdatatype_dnskey && 16132 dns_name_equal(&tuple->name, &zone->origin)) 16133 break; 16134 } 16135 16136 if (tuple == NULL) { 16137 result = del_sigs(zone, db, ver, &zone->origin, 16138 dns_rdatatype_dnskey, zonediff, 16139 zone_keys, nkeys, now, ISC_FALSE); 16140 if (result != ISC_R_SUCCESS) { 16141 dns_zone_log(zone, ISC_LOG_ERROR, 16142 "sign_apex:del_sigs -> %s", 16143 dns_result_totext(result)); 16144 goto failure; 16145 } 16146 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey, 16147 zonediff->diff, zone_keys, nkeys, zone->mctx, 16148 inception, soaexpire, check_ksk, 16149 keyset_kskonly); 16150 if (result != ISC_R_SUCCESS) { 16151 dns_zone_log(zone, ISC_LOG_ERROR, 16152 "sign_apex:add_sigs -> %s", 16153 dns_result_totext(result)); 16154 goto failure; 16155 } 16156 } 16157 16158 result = update_sigs(diff, db, ver, zone_keys, nkeys, zone, 16159 inception, soaexpire, now, check_ksk, 16160 keyset_kskonly, zonediff); 16161 16162 if (result != ISC_R_SUCCESS) { 16163 dns_zone_log(zone, ISC_LOG_ERROR, 16164 "sign_apex:update_sigs -> %s", 16165 dns_result_totext(result)); 16166 goto failure; 16167 } 16168 16169 failure: 16170 for (i = 0; i < nkeys; i++) 16171 dst_key_free(&zone_keys[i]); 16172 return (result); 16173} 16174 16175/* 16176 * Prevent the zone entering a inconsistent state where 16177 * NSEC only DNSKEYs are present with NSEC3 chains. 16178 * See update.c:check_dnssec() 16179 */ 16180static isc_boolean_t 16181dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 16182 dns_diff_t *diff) 16183{ 16184 isc_result_t result; 16185 dns_difftuple_t *tuple; 16186 isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE; 16187 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); 16188 16189 /* Scan the tuples for an NSEC-only DNSKEY */ 16190 for (tuple = ISC_LIST_HEAD(diff->tuples); 16191 tuple != NULL; 16192 tuple = ISC_LIST_NEXT(tuple, link)) { 16193 isc_uint8_t alg; 16194 if (tuple->rdata.type != dns_rdatatype_dnskey || 16195 tuple->op != DNS_DIFFOP_ADD) 16196 continue; 16197 16198 alg = tuple->rdata.data[3]; 16199 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 || 16200 alg == DST_ALG_DSA || alg == DST_ALG_ECC) { 16201 nseconly = ISC_TRUE; 16202 break; 16203 } 16204 } 16205 16206 /* Check existing DB for NSEC-only DNSKEY */ 16207 if (!nseconly) { 16208 result = dns_nsec_nseconly(db, ver, &nseconly); 16209 if (result == ISC_R_NOTFOUND) 16210 result = ISC_R_SUCCESS; 16211 CHECK(result); 16212 } 16213 16214 /* Check existing DB for NSEC3 */ 16215 if (!nsec3) 16216 CHECK(dns_nsec3_activex(db, ver, ISC_FALSE, 16217 privatetype, &nsec3)); 16218 16219 /* Refuse to allow NSEC3 with NSEC-only keys */ 16220 if (nseconly && nsec3) { 16221 dns_zone_log(zone, ISC_LOG_ERROR, 16222 "NSEC only DNSKEYs and NSEC3 chains not allowed"); 16223 goto failure; 16224 } 16225 16226 return (ISC_TRUE); 16227 16228 failure: 16229 return (ISC_FALSE); 16230} 16231 16232static isc_result_t 16233clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 16234 dns_diff_t *diff) 16235{ 16236 isc_result_t result; 16237 dns_dbnode_t *node = NULL; 16238 dns_rdataset_t rdataset; 16239 16240 dns_rdataset_init(&rdataset); 16241 CHECK(dns_db_getoriginnode(db, &node)); 16242 16243 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 16244 dns_rdatatype_none, 0, &rdataset, NULL); 16245 if (dns_rdataset_isassociated(&rdataset)) 16246 dns_rdataset_disassociate(&rdataset); 16247 if (result != ISC_R_NOTFOUND) 16248 goto failure; 16249 16250 result = dns_nsec3param_deletechains(db, ver, zone, ISC_TRUE, diff); 16251 16252 failure: 16253 if (node != NULL) 16254 dns_db_detachnode(db, &node); 16255 return (result); 16256} 16257 16258/* 16259 * Given an RRSIG rdataset and an algorithm, determine whether there 16260 * are any signatures using that algorithm. 16261 */ 16262static isc_boolean_t 16263signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) { 16264 dns_rdata_t rdata = DNS_RDATA_INIT; 16265 dns_rdata_rrsig_t rrsig; 16266 isc_result_t result; 16267 16268 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig); 16269 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) { 16270 return (ISC_FALSE); 16271 } 16272 16273 for (result = dns_rdataset_first(rdataset); 16274 result == ISC_R_SUCCESS; 16275 result = dns_rdataset_next(rdataset)) 16276 { 16277 dns_rdataset_current(rdataset, &rdata); 16278 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 16279 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16280 dns_rdata_reset(&rdata); 16281 if (rrsig.algorithm == alg) 16282 return (ISC_TRUE); 16283 } 16284 16285 return (ISC_FALSE); 16286} 16287 16288static isc_result_t 16289add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 16290 dns_diff_t *diff) 16291{ 16292 dns_name_t *origin; 16293 isc_boolean_t build_nsec3; 16294 isc_result_t result; 16295 16296 origin = dns_db_origin(db); 16297 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL, 16298 &build_nsec3)); 16299 if (build_nsec3) 16300 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum, 16301 ISC_FALSE, zone->privatetype, diff)); 16302 CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff)); 16303 16304 failure: 16305 return (result); 16306} 16307 16308static void 16309zone_rekey(dns_zone_t *zone) { 16310 isc_result_t result; 16311 dns_db_t *db = NULL; 16312 dns_dbnode_t *node = NULL; 16313 dns_dbversion_t *ver = NULL; 16314 dns_rdataset_t soaset, soasigs, keyset, keysigs; 16315 dns_dnsseckeylist_t dnskeys, keys, rmkeys; 16316 dns_dnsseckey_t *key; 16317 dns_diff_t diff, _sig_diff; 16318 zonediff_t zonediff; 16319 isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE; 16320 isc_boolean_t newalg = ISC_FALSE; 16321 isc_boolean_t fullsign; 16322 dns_ttl_t ttl = 3600; 16323 const char *dir; 16324 isc_mem_t *mctx; 16325 isc_stdtime_t now; 16326 isc_time_t timenow; 16327 isc_interval_t ival; 16328 char timebuf[80]; 16329 16330 REQUIRE(DNS_ZONE_VALID(zone)); 16331 16332 ISC_LIST_INIT(dnskeys); 16333 ISC_LIST_INIT(keys); 16334 ISC_LIST_INIT(rmkeys); 16335 dns_rdataset_init(&soaset); 16336 dns_rdataset_init(&soasigs); 16337 dns_rdataset_init(&keyset); 16338 dns_rdataset_init(&keysigs); 16339 dir = dns_zone_getkeydirectory(zone); 16340 mctx = zone->mctx; 16341 dns_diff_init(mctx, &diff); 16342 dns_diff_init(mctx, &_sig_diff); 16343 zonediff_init(&zonediff, &_sig_diff); 16344 16345 CHECK(dns_zone_getdb(zone, &db)); 16346 CHECK(dns_db_newversion(db, &ver)); 16347 CHECK(dns_db_getoriginnode(db, &node)); 16348 16349 TIME_NOW(&timenow); 16350 now = isc_time_seconds(&timenow); 16351 16352 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys"); 16353 16354 /* Get the SOA record's TTL */ 16355 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 16356 dns_rdatatype_none, 0, &soaset, &soasigs)); 16357 ttl = soaset.ttl; 16358 dns_rdataset_disassociate(&soaset); 16359 16360 /* Get the DNSKEY rdataset */ 16361 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 16362 dns_rdatatype_none, 0, &keyset, &keysigs); 16363 if (result == ISC_R_SUCCESS) { 16364 ttl = keyset.ttl; 16365 CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir, 16366 mctx, &keyset, 16367 &keysigs, &soasigs, 16368 ISC_FALSE, ISC_FALSE, 16369 &dnskeys)); 16370 } else if (result != ISC_R_NOTFOUND) 16371 goto failure; 16372 16373 /* 16374 * True when called from "rndc sign". Indicates the zone should be 16375 * fully signed now. 16376 */ 16377 fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0); 16378 16379 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys); 16380 if (result == ISC_R_SUCCESS) { 16381 isc_boolean_t check_ksk; 16382 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 16383 16384 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys, 16385 &zone->origin, ttl, &diff, 16386 ISC_TF(!check_ksk), 16387 mctx, logmsg); 16388 16389 /* Keys couldn't be updated for some reason; 16390 * try again later. */ 16391 if (result != ISC_R_SUCCESS) { 16392 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:" 16393 "couldn't update zone keys: %s", 16394 isc_result_totext(result)); 16395 goto failure; 16396 } 16397 16398 /* 16399 * See if any pre-existing keys have newly become active; 16400 * also, see if any new key is for a new algorithm, as in that 16401 * event, we need to sign the zone fully. (If there's a new 16402 * key, but it's for an already-existing algorithm, then 16403 * the zone signing can be handled incrementally.) 16404 */ 16405 for (key = ISC_LIST_HEAD(dnskeys); 16406 key != NULL; 16407 key = ISC_LIST_NEXT(key, link)) { 16408 if (!key->first_sign) 16409 continue; 16410 16411 newactive = ISC_TRUE; 16412 16413 if (!dns_rdataset_isassociated(&keysigs)) { 16414 newalg = ISC_TRUE; 16415 break; 16416 } 16417 16418 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) { 16419 /* 16420 * This isn't a new algorithm; clear 16421 * first_sign so we won't sign the 16422 * whole zone with this key later 16423 */ 16424 key->first_sign = ISC_FALSE; 16425 } else { 16426 newalg = ISC_TRUE; 16427 break; 16428 } 16429 } 16430 16431 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) && 16432 dnskey_sane(zone, db, ver, &diff)) { 16433 CHECK(dns_diff_apply(&diff, db, ver)); 16434 CHECK(clean_nsec3param(zone, db, ver, &diff)); 16435 CHECK(add_signing_records(db, zone->privatetype, 16436 ver, &diff, 16437 ISC_TF(newalg || fullsign))); 16438 CHECK(update_soa_serial(db, ver, &diff, mctx, 16439 zone->updatemethod)); 16440 CHECK(add_chains(zone, db, ver, &diff)); 16441 CHECK(sign_apex(zone, db, ver, &diff, &zonediff)); 16442 CHECK(zone_journal(zone, zonediff.diff, NULL, 16443 "zone_rekey")); 16444 commit = ISC_TRUE; 16445 } 16446 } 16447 16448 dns_db_closeversion(db, &ver, ISC_TRUE); 16449 16450 if (commit) { 16451 dns_difftuple_t *tuple; 16452 16453 LOCK_ZONE(zone); 16454 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 16455 16456 zone_needdump(zone, DNS_DUMP_DELAY); 16457 16458 zone_settimer(zone, &timenow); 16459 16460 /* Remove any signatures from removed keys. */ 16461 if (!ISC_LIST_EMPTY(rmkeys)) { 16462 for (key = ISC_LIST_HEAD(rmkeys); 16463 key != NULL; 16464 key = ISC_LIST_NEXT(key, link)) { 16465 result = zone_signwithkey(zone, 16466 dst_key_alg(key->key), 16467 dst_key_id(key->key), 16468 ISC_TRUE); 16469 if (result != ISC_R_SUCCESS) { 16470 dns_zone_log(zone, ISC_LOG_ERROR, 16471 "zone_signwithkey failed: %s", 16472 dns_result_totext(result)); 16473 } 16474 } 16475 } 16476 16477 if (fullsign) { 16478 /* 16479 * "rndc sign" was called, so we now sign the zone 16480 * with all active keys, whether they're new or not. 16481 */ 16482 for (key = ISC_LIST_HEAD(dnskeys); 16483 key != NULL; 16484 key = ISC_LIST_NEXT(key, link)) { 16485 if (!key->force_sign && !key->hint_sign) 16486 continue; 16487 16488 result = zone_signwithkey(zone, 16489 dst_key_alg(key->key), 16490 dst_key_id(key->key), 16491 ISC_FALSE); 16492 if (result != ISC_R_SUCCESS) { 16493 dns_zone_log(zone, ISC_LOG_ERROR, 16494 "zone_signwithkey failed: %s", 16495 dns_result_totext(result)); 16496 } 16497 } 16498 } else if (newalg) { 16499 /* 16500 * We haven't been told to sign fully, but a new 16501 * algorithm was added to the DNSKEY. We sign 16502 * the full zone, but only with newly active 16503 * keys. 16504 */ 16505 for (key = ISC_LIST_HEAD(dnskeys); 16506 key != NULL; 16507 key = ISC_LIST_NEXT(key, link)) { 16508 if (!key->first_sign) 16509 continue; 16510 16511 result = zone_signwithkey(zone, 16512 dst_key_alg(key->key), 16513 dst_key_id(key->key), 16514 ISC_FALSE); 16515 if (result != ISC_R_SUCCESS) { 16516 dns_zone_log(zone, ISC_LOG_ERROR, 16517 "zone_signwithkey failed: %s", 16518 dns_result_totext(result)); 16519 } 16520 } 16521 } 16522 16523 /* 16524 * Clear fullsign flag, if it was set, so we don't do 16525 * another full signing next time 16526 */ 16527 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN; 16528 16529 /* 16530 * Cause the zone to add/delete NSEC3 chains for the 16531 * deferred NSEC3PARAM changes. 16532 */ 16533 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples); 16534 tuple != NULL; 16535 tuple = ISC_LIST_NEXT(tuple, link)) { 16536 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 16537 dns_rdata_t rdata = DNS_RDATA_INIT; 16538 dns_rdata_nsec3param_t nsec3param; 16539 16540 if (tuple->rdata.type != zone->privatetype || 16541 tuple->op != DNS_DIFFOP_ADD) 16542 continue; 16543 16544 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata, 16545 buf, sizeof(buf))) 16546 continue; 16547 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 16548 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16549 if (nsec3param.flags == 0) 16550 continue; 16551 16552 result = zone_addnsec3chain(zone, &nsec3param); 16553 if (result != ISC_R_SUCCESS) { 16554 dns_zone_log(zone, ISC_LOG_ERROR, 16555 "zone_addnsec3chain failed: %s", 16556 dns_result_totext(result)); 16557 } 16558 } 16559 16560 /* 16561 * Activate any NSEC3 chain updates that may have 16562 * been scheduled before this rekey. 16563 */ 16564 if (fullsign || newalg) 16565 resume_addnsec3chain(zone); 16566 16567 /* 16568 * Schedule the next resigning event 16569 */ 16570 set_resigntime(zone); 16571 UNLOCK_ZONE(zone); 16572 } 16573 16574 isc_time_settoepoch(&zone->refreshkeytime); 16575 16576 /* 16577 * If we're doing key maintenance, set the key refresh timer to 16578 * the next scheduled key event or to 'dnssec-loadkeys-interval' 16579 * seconds in the future, whichever is sooner. 16580 */ 16581 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) { 16582 isc_time_t timethen; 16583 isc_stdtime_t then; 16584 16585 LOCK_ZONE(zone); 16586 DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval, 16587 &timethen); 16588 zone->refreshkeytime = timethen; 16589 UNLOCK_ZONE(zone); 16590 16591 for (key = ISC_LIST_HEAD(dnskeys); 16592 key != NULL; 16593 key = ISC_LIST_NEXT(key, link)) { 16594 then = now; 16595 result = next_keyevent(key->key, &then); 16596 if (result != ISC_R_SUCCESS) 16597 continue; 16598 16599 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 16600 LOCK_ZONE(zone); 16601 if (isc_time_compare(&timethen, 16602 &zone->refreshkeytime) < 0) { 16603 zone->refreshkeytime = timethen; 16604 } 16605 UNLOCK_ZONE(zone); 16606 } 16607 16608 zone_settimer(zone, &timenow); 16609 16610 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 16611 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); 16612 } 16613 16614 done: 16615 dns_diff_clear(&diff); 16616 dns_diff_clear(&_sig_diff); 16617 16618 clear_keylist(&dnskeys, mctx); 16619 clear_keylist(&keys, mctx); 16620 clear_keylist(&rmkeys, mctx); 16621 16622 if (ver != NULL) 16623 dns_db_closeversion(db, &ver, ISC_FALSE); 16624 if (dns_rdataset_isassociated(&keyset)) 16625 dns_rdataset_disassociate(&keyset); 16626 if (dns_rdataset_isassociated(&keysigs)) 16627 dns_rdataset_disassociate(&keysigs); 16628 if (dns_rdataset_isassociated(&soasigs)) 16629 dns_rdataset_disassociate(&soasigs); 16630 if (node != NULL) 16631 dns_db_detachnode(db, &node); 16632 if (db != NULL) 16633 dns_db_detach(&db); 16634 return; 16635 16636 failure: 16637 /* 16638 * Something went wrong; try again in ten minutes or 16639 * after a key refresh interval, whichever is shorter. 16640 */ 16641 isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 0); 16642 isc_time_nowplusinterval(&zone->refreshkeytime, &ival); 16643 goto done; 16644} 16645 16646void 16647dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) { 16648 isc_time_t now; 16649 16650 if (zone->type == dns_zone_master && zone->task != NULL) { 16651 LOCK_ZONE(zone); 16652 16653 if (fullsign) 16654 zone->keyopts |= DNS_ZONEKEY_FULLSIGN; 16655 16656 TIME_NOW(&now); 16657 zone->refreshkeytime = now; 16658 zone_settimer(zone, &now); 16659 16660 UNLOCK_ZONE(zone); 16661 } 16662} 16663 16664isc_result_t 16665dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 16666 unsigned int *errors) 16667{ 16668 isc_result_t result; 16669 dns_dbnode_t *node = NULL; 16670 16671 REQUIRE(DNS_ZONE_VALID(zone)); 16672 REQUIRE(errors != NULL); 16673 16674 result = dns_db_getoriginnode(db, &node); 16675 if (result != ISC_R_SUCCESS) 16676 return (result); 16677 result = zone_count_ns_rr(zone, db, node, version, NULL, errors, 16678 ISC_FALSE); 16679 dns_db_detachnode(db, &node); 16680 return (result); 16681} 16682 16683void 16684dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) { 16685 REQUIRE(DNS_ZONE_VALID(zone)); 16686 LOCK_ZONE(zone); 16687 zone->added = added; 16688 UNLOCK_ZONE(zone); 16689} 16690 16691isc_boolean_t 16692dns_zone_getadded(dns_zone_t *zone) { 16693 REQUIRE(DNS_ZONE_VALID(zone)); 16694 return (zone->added); 16695} 16696 16697isc_result_t 16698dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db) 16699{ 16700 isc_time_t loadtime; 16701 isc_result_t result; 16702 dns_zone_t *secure = NULL; 16703 16704 TIME_NOW(&loadtime); 16705 16706 /* 16707 * Lock hierarchy: zmgr, zone, raw. 16708 */ 16709 again: 16710 LOCK_ZONE(zone); 16711 if (inline_secure(zone)) 16712 LOCK_ZONE(zone->raw); 16713 else if (inline_raw(zone)) { 16714 secure = zone->secure; 16715 TRYLOCK_ZONE(result, secure); 16716 if (result != ISC_R_SUCCESS) { 16717 UNLOCK_ZONE(zone); 16718 secure = NULL; 16719#if ISC_PLATFORM_USETHREADS 16720 isc_thread_yield(); 16721#endif 16722 goto again; 16723 } 16724 } 16725 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 16726 if (inline_secure(zone)) 16727 UNLOCK_ZONE(zone->raw); 16728 else if (secure != NULL) 16729 UNLOCK_ZONE(secure); 16730 UNLOCK_ZONE(zone); 16731 return result; 16732} 16733 16734isc_result_t 16735dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval) { 16736 REQUIRE(DNS_ZONE_VALID(zone)); 16737 if (interval == 0) 16738 return (ISC_R_RANGE); 16739 /* Maximum value: 24 hours (3600 minutes) */ 16740 if (interval > (24 * 60)) 16741 interval = (24 * 60); 16742 /* Multiply by 60 for seconds */ 16743 zone->refreshkeyinterval = interval * 60; 16744 return (ISC_R_SUCCESS); 16745} 16746 16747void 16748dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t flag) { 16749 REQUIRE(DNS_ZONE_VALID(zone)); 16750 zone->requestixfr = flag; 16751} 16752 16753isc_boolean_t 16754dns_zone_getrequestixfr(dns_zone_t *zone) { 16755 REQUIRE(DNS_ZONE_VALID(zone)); 16756 return (zone->requestixfr); 16757} 16758 16759void 16760dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) { 16761 REQUIRE(DNS_ZONE_VALID(zone)); 16762 zone->updatemethod = method; 16763} 16764 16765dns_updatemethod_t 16766dns_zone_getserialupdatemethod(dns_zone_t *zone) { 16767 REQUIRE(DNS_ZONE_VALID(zone)); 16768 return(zone->updatemethod); 16769} 16770 16771/* 16772 * Lock hierarchy: zmgr, zone, raw. 16773 */ 16774isc_result_t 16775dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) { 16776 isc_result_t result; 16777 dns_zonemgr_t *zmgr; 16778 16779 REQUIRE(DNS_ZONE_VALID(zone)); 16780 REQUIRE(zone->zmgr != NULL); 16781 REQUIRE(zone->task != NULL); 16782 REQUIRE(zone->loadtask != NULL); 16783 REQUIRE(zone->raw == NULL); 16784 16785 REQUIRE(DNS_ZONE_VALID(raw)); 16786 REQUIRE(raw->zmgr == NULL); 16787 REQUIRE(raw->task == NULL); 16788 REQUIRE(raw->loadtask == NULL); 16789 REQUIRE(raw->secure == NULL); 16790 16791 /* 16792 * Lock hierarchy: zmgr, zone, raw. 16793 */ 16794 zmgr = zone->zmgr; 16795 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 16796 LOCK_ZONE(zone); 16797 LOCK_ZONE(raw); 16798 16799 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, 16800 NULL, NULL, zone->task, zone_timer, raw, 16801 &raw->timer); 16802 if (result != ISC_R_SUCCESS) 16803 goto unlock; 16804 16805 /* 16806 * The timer "holds" a iref. 16807 */ 16808 raw->irefs++; 16809 INSIST(raw->irefs != 0); 16810 16811 16812 /* dns_zone_attach(raw, &zone->raw); */ 16813 isc_refcount_increment(&raw->erefs, NULL); 16814 zone->raw = raw; 16815 16816 /* dns_zone_iattach(zone, &raw->secure); */ 16817 zone_iattach(zone, &raw->secure); 16818 16819 isc_task_attach(zone->task, &raw->task); 16820 isc_task_attach(zone->loadtask, &raw->loadtask); 16821 16822 ISC_LIST_APPEND(zmgr->zones, raw, link); 16823 raw->zmgr = zmgr; 16824 zmgr->refs++; 16825 16826 unlock: 16827 UNLOCK_ZONE(raw); 16828 UNLOCK_ZONE(zone); 16829 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 16830 return (result); 16831} 16832 16833void 16834dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) { 16835 REQUIRE(DNS_ZONE_VALID(zone)); 16836 REQUIRE(raw != NULL && *raw == NULL); 16837 16838 LOCK(&zone->lock); 16839 if (zone->raw != NULL) 16840 dns_zone_attach(zone->raw, raw); 16841 UNLOCK(&zone->lock); 16842} 16843 16844struct keydone { 16845 isc_event_t event; 16846 isc_boolean_t all; 16847 unsigned char data[5]; 16848}; 16849 16850#define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL) 16851 16852static void 16853keydone(isc_task_t *task, isc_event_t *event) { 16854 const char *me = "keydone"; 16855 isc_boolean_t commit = ISC_FALSE; 16856 isc_result_t result; 16857 dns_rdata_t rdata = DNS_RDATA_INIT; 16858 dns_dbversion_t *oldver = NULL, *newver = NULL; 16859 dns_zone_t *zone; 16860 dns_db_t *db = NULL; 16861 dns_dbnode_t *node = NULL; 16862 dns_rdataset_t rdataset; 16863 dns_diff_t diff; 16864 struct keydone *keydone = (struct keydone *)event; 16865 dns_update_log_t log = { update_log_cb, NULL }; 16866 isc_boolean_t clear_pending = ISC_FALSE; 16867 16868 UNUSED(task); 16869 16870 zone = event->ev_arg; 16871 INSIST(DNS_ZONE_VALID(zone)); 16872 16873 ENTER; 16874 16875 dns_rdataset_init(&rdataset); 16876 dns_diff_init(zone->mctx, &diff); 16877 16878 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 16879 if (zone->db != NULL) { 16880 dns_db_attach(zone->db, &db); 16881 dns_db_currentversion(db, &oldver); 16882 result = dns_db_newversion(db, &newver); 16883 if (result != ISC_R_SUCCESS) { 16884 dns_zone_log(zone, ISC_LOG_ERROR, 16885 "keydone:dns_db_newversion -> %s", 16886 dns_result_totext(result)); 16887 goto failure; 16888 } 16889 } 16890 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 16891 if (db == NULL) 16892 goto failure; 16893 16894 result = dns_db_getoriginnode(db, &node); 16895 if (result != ISC_R_SUCCESS) 16896 goto failure; 16897 16898 result = dns_db_findrdataset(db, node, newver, zone->privatetype, 16899 dns_rdatatype_none, 0, &rdataset, NULL); 16900 if (result == ISC_R_NOTFOUND) { 16901 INSIST(!dns_rdataset_isassociated(&rdataset)); 16902 goto failure; 16903 } 16904 if (result != ISC_R_SUCCESS) { 16905 INSIST(!dns_rdataset_isassociated(&rdataset)); 16906 goto failure; 16907 } 16908 16909 for (result = dns_rdataset_first(&rdataset); 16910 result == ISC_R_SUCCESS; 16911 result = dns_rdataset_next(&rdataset)) { 16912 isc_boolean_t found = ISC_FALSE; 16913 16914 dns_rdataset_current(&rdataset, &rdata); 16915 16916 if (keydone->all) { 16917 if (rdata.length == 5 && rdata.data[0] != 0 && 16918 rdata.data[3] == 0 && rdata.data[4] == 1) 16919 found = ISC_TRUE; 16920 else if (rdata.data[0] == 0 && 16921 (rdata.data[2] & PENDINGFLAGS) != 0) { 16922 found = ISC_TRUE; 16923 clear_pending = ISC_TRUE; 16924 } 16925 } else if (rdata.length == 5 && 16926 memcmp(rdata.data, keydone->data, 5) == 0) 16927 found = ISC_TRUE; 16928 16929 if (found) 16930 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL, 16931 &zone->origin, rdataset.ttl, 16932 &rdata)); 16933 dns_rdata_reset(&rdata); 16934 } 16935 16936 if (!ISC_LIST_EMPTY(diff.tuples)) { 16937 /* Write changes to journal file. */ 16938 CHECK(update_soa_serial(db, newver, &diff, zone->mctx, 16939 zone->updatemethod)); 16940 16941 result = dns_update_signatures(&log, zone, db, 16942 oldver, newver, &diff, 16943 zone->sigvalidityinterval); 16944 if (!clear_pending) 16945 CHECK(result); 16946 16947 CHECK(zone_journal(zone, &diff, NULL, "keydone")); 16948 commit = ISC_TRUE; 16949 16950 LOCK_ZONE(zone); 16951 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 16952 zone_needdump(zone, 30); 16953 UNLOCK_ZONE(zone); 16954 } 16955 16956 failure: 16957 if (dns_rdataset_isassociated(&rdataset)) 16958 dns_rdataset_disassociate(&rdataset); 16959 if (db != NULL) { 16960 if (node != NULL) 16961 dns_db_detachnode(db, &node); 16962 if (oldver != NULL) 16963 dns_db_closeversion(db, &oldver, ISC_FALSE); 16964 if (newver != NULL) 16965 dns_db_closeversion(db, &newver, commit); 16966 dns_db_detach(&db); 16967 } 16968 dns_diff_clear(&diff); 16969 isc_event_free(&event); 16970 dns_zone_idetach(&zone); 16971} 16972 16973isc_result_t 16974dns_zone_keydone(dns_zone_t *zone, const char *keystr) { 16975 isc_result_t result = ISC_R_SUCCESS; 16976 isc_event_t *e; 16977 isc_buffer_t b; 16978 dns_zone_t *dummy = NULL; 16979 struct keydone *kd; 16980 16981 REQUIRE(DNS_ZONE_VALID(zone)); 16982 16983 LOCK_ZONE(zone); 16984 16985 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone, 16986 zone, sizeof(struct keydone)); 16987 if (e == NULL) { 16988 result = ISC_R_NOMEMORY; 16989 goto failure; 16990 } 16991 16992 kd = (struct keydone *) e; 16993 if (strcasecmp(keystr, "all") == 0) 16994 kd->all = ISC_TRUE; 16995 else { 16996 isc_textregion_t r; 16997 char *algstr; 16998 dns_keytag_t keyid; 16999 dns_secalg_t alg; 17000 size_t n; 17001 17002 kd->all = ISC_FALSE; 17003 17004 n = sscanf(keystr, "%hd/", &keyid); 17005 if (n == 0U) 17006 CHECK(ISC_R_FAILURE); 17007 17008 algstr = strchr(keystr, '/'); 17009 if (algstr != NULL) 17010 algstr++; 17011 else 17012 CHECK(ISC_R_FAILURE); 17013 17014 n = sscanf(algstr, "%hhd", &alg); 17015 if (n == 0U) { 17016 DE_CONST(algstr, r.base); 17017 r.length = strlen(algstr); 17018 CHECK(dns_secalg_fromtext(&alg, &r)); 17019 } 17020 17021 /* construct a private-type rdata */ 17022 isc_buffer_init(&b, kd->data, sizeof(kd->data)); 17023 isc_buffer_putuint8(&b, alg); 17024 isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8); 17025 isc_buffer_putuint8(&b, (keyid & 0xff)); 17026 isc_buffer_putuint8(&b, 0); 17027 isc_buffer_putuint8(&b, 1); 17028 } 17029 17030 zone_iattach(zone, &dummy); 17031 isc_task_send(zone->task, &e); 17032 17033 failure: 17034 if (e != NULL) 17035 isc_event_free(&e); 17036 UNLOCK_ZONE(zone); 17037 return (result); 17038} 17039 17040static void 17041setnsec3param(isc_task_t *task, isc_event_t *event) { 17042 const char *me = "setnsec3param"; 17043 isc_boolean_t commit = ISC_FALSE; 17044 isc_result_t result; 17045 dns_dbversion_t *oldver = NULL, *newver = NULL; 17046 dns_zone_t *zone; 17047 dns_db_t *db = NULL; 17048 dns_dbnode_t *node = NULL; 17049 dns_rdataset_t prdataset, nrdataset; 17050 dns_diff_t diff; 17051 struct np3event *npe = (struct np3event *)event; 17052 nsec3param_t *np; 17053 dns_update_log_t log = { update_log_cb, NULL }; 17054 dns_rdata_t rdata; 17055 isc_boolean_t nseconly; 17056 isc_boolean_t exists = ISC_FALSE; 17057 17058 UNUSED(task); 17059 17060 zone = event->ev_arg; 17061 INSIST(DNS_ZONE_VALID(zone)); 17062 17063 ENTER; 17064 17065 np = &npe->params; 17066 17067 dns_rdataset_init(&prdataset); 17068 dns_rdataset_init(&nrdataset); 17069 dns_diff_init(zone->mctx, &diff); 17070 17071 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 17072 if (zone->db != NULL) { 17073 dns_db_attach(zone->db, &db); 17074 dns_db_currentversion(db, &oldver); 17075 result = dns_db_newversion(db, &newver); 17076 if (result != ISC_R_SUCCESS) { 17077 dns_zone_log(zone, ISC_LOG_ERROR, 17078 "setnsec3param:dns_db_newversion -> %s", 17079 dns_result_totext(result)); 17080 goto failure; 17081 } 17082 } 17083 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17084 if (db == NULL) 17085 goto failure; 17086 17087 CHECK(dns_db_getoriginnode(db, &node)); 17088 17089 /* 17090 * Does a private-type record already exist for this chain? 17091 */ 17092 result = dns_db_findrdataset(db, node, newver, zone->privatetype, 17093 dns_rdatatype_none, 0, &prdataset, NULL); 17094 if (result == ISC_R_SUCCESS) { 17095 for (result = dns_rdataset_first(&prdataset); 17096 result == ISC_R_SUCCESS; 17097 result = dns_rdataset_next(&prdataset)) { 17098 dns_rdata_init(&rdata); 17099 dns_rdataset_current(&prdataset, &rdata); 17100 17101 if (np->length == rdata.length && 17102 memcmp(rdata.data, np->data, np->length) == 0) { 17103 exists = ISC_TRUE; 17104 break; 17105 } 17106 } 17107 } else if (result != ISC_R_NOTFOUND) { 17108 INSIST(!dns_rdataset_isassociated(&prdataset)); 17109 goto failure; 17110 } 17111 17112 /* 17113 * Does the chain already exist? 17114 */ 17115 result = dns_db_findrdataset(db, node, newver, 17116 dns_rdatatype_nsec3param, 17117 dns_rdatatype_none, 0, &nrdataset, NULL); 17118 if (result == ISC_R_SUCCESS) { 17119 for (result = dns_rdataset_first(&nrdataset); 17120 result == ISC_R_SUCCESS; 17121 result = dns_rdataset_next(&nrdataset)) { 17122 dns_rdata_init(&rdata); 17123 dns_rdataset_current(&nrdataset, &rdata); 17124 17125 if (np->length == (rdata.length + 1) && 17126 memcmp(rdata.data, np->data + 1, 17127 np->length - 1) == 0) 17128 { 17129 exists = ISC_TRUE; 17130 break; 17131 } 17132 } 17133 } else if (result != ISC_R_NOTFOUND) { 17134 INSIST(!dns_rdataset_isassociated(&nrdataset)); 17135 goto failure; 17136 } 17137 17138 17139 /* 17140 * We need to remove any existing NSEC3 chains. 17141 */ 17142 if (!exists && np->replace && (np->length != 0 || np->nsec)) 17143 CHECK(dns_nsec3param_deletechains(db, newver, zone, 17144 !np->nsec, &diff)); 17145 17146 if (!exists && np->length != 0) { 17147 /* 17148 * We're creating an NSEC3 chain. 17149 * 17150 * If the zone is not currently capable of supporting 17151 * an NSEC3 chain, add the INITIAL flag, so these 17152 * parameters can be used later when NSEC3 becomes 17153 * available. 17154 */ 17155 dns_rdata_init(&rdata); 17156 17157 np->data[2] |= DNS_NSEC3FLAG_CREATE; 17158 result = dns_nsec_nseconly(db, newver, &nseconly); 17159 if (result == ISC_R_NOTFOUND || nseconly) 17160 np->data[2] |= DNS_NSEC3FLAG_INITIAL; 17161 17162 rdata.length = np->length; 17163 rdata.data = np->data; 17164 rdata.type = zone->privatetype; 17165 rdata.rdclass = zone->rdclass; 17166 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD, 17167 &zone->origin, 0, &rdata)); 17168 } 17169 17170 if (!ISC_LIST_EMPTY(diff.tuples)) { 17171 /* Write changes to journal file. */ 17172 CHECK(update_soa_serial(db, newver, &diff, zone->mctx, 17173 zone->updatemethod)); 17174 result = dns_update_signatures(&log, zone, db, 17175 oldver, newver, &diff, 17176 zone->sigvalidityinterval); 17177 if (result != ISC_R_NOTFOUND) 17178 CHECK(result); 17179 CHECK(zone_journal(zone, &diff, NULL, "setnsec3param")); 17180 commit = ISC_TRUE; 17181 17182 LOCK_ZONE(zone); 17183 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 17184 zone_needdump(zone, 30); 17185 UNLOCK_ZONE(zone); 17186 } 17187 17188 failure: 17189 if (dns_rdataset_isassociated(&prdataset)) 17190 dns_rdataset_disassociate(&prdataset); 17191 if (dns_rdataset_isassociated(&nrdataset)) 17192 dns_rdataset_disassociate(&nrdataset); 17193 if (node != NULL) 17194 dns_db_detachnode(db, &node); 17195 if (oldver != NULL) 17196 dns_db_closeversion(db, &oldver, ISC_FALSE); 17197 if (newver != NULL) 17198 dns_db_closeversion(db, &newver, commit); 17199 if (db != NULL) 17200 dns_db_detach(&db); 17201 if (commit) 17202 resume_addnsec3chain(zone); 17203 dns_diff_clear(&diff); 17204 isc_event_free(&event); 17205 dns_zone_idetach(&zone); 17206} 17207 17208isc_result_t 17209dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags, 17210 isc_uint16_t iter, isc_uint8_t saltlen, 17211 unsigned char *salt, isc_boolean_t replace) 17212{ 17213 isc_result_t result = ISC_R_SUCCESS; 17214 dns_rdata_nsec3param_t param; 17215 dns_rdata_t nrdata = DNS_RDATA_INIT; 17216 dns_rdata_t prdata = DNS_RDATA_INIT; 17217 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE]; 17218 struct np3event *npe; 17219 nsec3param_t *np; 17220 dns_zone_t *dummy = NULL; 17221 isc_buffer_t b; 17222 isc_event_t *e; 17223 17224 REQUIRE(DNS_ZONE_VALID(zone)); 17225 REQUIRE(salt != NULL); 17226 17227 LOCK_ZONE(zone); 17228 17229 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM, 17230 setnsec3param, zone, sizeof(struct np3event)); 17231 if (e == NULL) { 17232 result = ISC_R_NOMEMORY; 17233 goto failure; 17234 } 17235 17236 npe = (struct np3event *) e; 17237 np = &npe->params; 17238 17239 np->replace = replace; 17240 if (hash == 0) { 17241 np->length = 0; 17242 np->nsec = ISC_TRUE; 17243 } else { 17244 param.common.rdclass = zone->rdclass; 17245 param.common.rdtype = dns_rdatatype_nsec3param; 17246 ISC_LINK_INIT(¶m.common, link); 17247 param.mctx = NULL; 17248 param.hash = hash; 17249 param.flags = flags; 17250 param.iterations = iter; 17251 param.salt_length = saltlen; 17252 param.salt = salt; 17253 isc_buffer_init(&b, nbuf, sizeof(nbuf)); 17254 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass, 17255 dns_rdatatype_nsec3param, 17256 ¶m, &b)); 17257 dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype, 17258 np->data, sizeof(np->data)); 17259 np->length = prdata.length; 17260 } 17261 17262 zone_iattach(zone, &dummy); 17263 isc_task_send(zone->task, &e); 17264 17265 failure: 17266 if (e != NULL) 17267 isc_event_free(&e); 17268 UNLOCK_ZONE(zone); 17269 return (result); 17270} 17271 17272void 17273dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) { 17274 REQUIRE(DNS_ZONE_VALID(zone)); 17275 17276 zone->statlevel = level; 17277} 17278 17279dns_zonestat_level_t 17280dns_zone_getstatlevel(dns_zone_t *zone) { 17281 REQUIRE(DNS_ZONE_VALID(zone)); 17282 17283 return (zone->statlevel); 17284} 17285