1 /* $NetBSD: zone.c,v 1.14 2015/07/08 17:28:59 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-2003 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 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/dlz.h> 51 #include <dns/dnssec.h> 52 #include <dns/events.h> 53 #include <dns/journal.h> 54 #include <dns/keydata.h> 55 #include <dns/keytable.h> 56 #include <dns/keyvalues.h> 57 #include <dns/log.h> 58 #include <dns/master.h> 59 #include <dns/masterdump.h> 60 #include <dns/message.h> 61 #include <dns/name.h> 62 #include <dns/nsec.h> 63 #include <dns/nsec3.h> 64 #include <dns/peer.h> 65 #include <dns/private.h> 66 #include <dns/rbt.h> 67 #include <dns/rcode.h> 68 #include <dns/rdata.h> 69 #include <dns/rdataclass.h> 70 #include <dns/rdatalist.h> 71 #include <dns/rdataset.h> 72 #include <dns/rdatasetiter.h> 73 #include <dns/rdatastruct.h> 74 #include <dns/rdatatype.h> 75 #include <dns/request.h> 76 #include <dns/resolver.h> 77 #include <dns/result.h> 78 #include <dns/rriterator.h> 79 #include <dns/soa.h> 80 #include <dns/ssu.h> 81 #include <dns/stats.h> 82 #include <dns/time.h> 83 #include <dns/tsig.h> 84 #include <dns/update.h> 85 #include <dns/xfrin.h> 86 #include <dns/zone.h> 87 #include <dns/zt.h> 88 89 #include <dst/dst.h> 90 91 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E') 92 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC) 93 94 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y') 95 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC) 96 97 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b') 98 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC) 99 100 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r') 101 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC) 102 103 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd') 104 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC) 105 106 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w') 107 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC) 108 109 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O') 110 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC) 111 112 /*% 113 * Ensure 'a' is at least 'min' but not more than 'max'. 114 */ 115 #define RANGE(a, min, max) \ 116 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max))) 117 118 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) 119 120 /*% 121 * Key flags 122 */ 123 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0) 124 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0) 125 #define ALG(x) dst_key_alg(x) 126 127 /* 128 * Default values. 129 */ 130 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */ 131 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */ 132 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */ 133 #define RESIGN_DELAY 3600 /*%< 1 hour */ 134 135 #ifndef DNS_MAX_EXPIRE 136 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */ 137 #endif 138 139 #ifndef DNS_DUMP_DELAY 140 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */ 141 #endif 142 143 typedef struct dns_notify dns_notify_t; 144 typedef struct dns_stub dns_stub_t; 145 typedef struct dns_load dns_load_t; 146 typedef struct dns_forward dns_forward_t; 147 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t; 148 typedef struct dns_io dns_io_t; 149 typedef ISC_LIST(dns_io_t) dns_iolist_t; 150 typedef struct dns_signing dns_signing_t; 151 typedef ISC_LIST(dns_signing_t) dns_signinglist_t; 152 typedef struct dns_nsec3chain dns_nsec3chain_t; 153 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t; 154 typedef struct dns_keyfetch dns_keyfetch_t; 155 typedef struct dns_asyncload dns_asyncload_t; 156 typedef struct dns_include dns_include_t; 157 158 #define DNS_ZONE_CHECKLOCK 159 #ifdef DNS_ZONE_CHECKLOCK 160 #define LOCK_ZONE(z) \ 161 do { LOCK(&(z)->lock); \ 162 INSIST((z)->locked == ISC_FALSE); \ 163 (z)->locked = ISC_TRUE; \ 164 } while (/*CONSTCOND*/0) 165 #define UNLOCK_ZONE(z) \ 166 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (/*CONSTCOND*/0) 167 #define LOCKED_ZONE(z) ((z)->locked) 168 #define TRYLOCK_ZONE(result, z) \ 169 do { \ 170 result = isc_mutex_trylock(&(z)->lock); \ 171 if (result == ISC_R_SUCCESS) { \ 172 INSIST((z)->locked == ISC_FALSE); \ 173 (z)->locked = ISC_TRUE; \ 174 } \ 175 } while (/*CONSTCOND*/0) 176 #else 177 #define LOCK_ZONE(z) LOCK(&(z)->lock) 178 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock) 179 #define LOCKED_ZONE(z) ISC_TRUE 180 #define TRYLOCK_ZONE(result, z) \ 181 do { result = isc_mutex_trylock(&(z)->lock); } while (/*CONSTCOND*/0) 182 #endif 183 184 #ifdef ISC_RWLOCK_USEATOMIC 185 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0) 186 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l) 187 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t)) 188 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t)) 189 #else 190 #define ZONEDB_INITLOCK(l) isc_mutex_init(l) 191 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l) 192 #define ZONEDB_LOCK(l, t) LOCK(l) 193 #define ZONEDB_UNLOCK(l, t) UNLOCK(l) 194 #endif 195 196 struct dns_zone { 197 /* Unlocked */ 198 unsigned int magic; 199 isc_mutex_t lock; 200 #ifdef DNS_ZONE_CHECKLOCK 201 isc_boolean_t locked; 202 #endif 203 isc_mem_t *mctx; 204 isc_refcount_t erefs; 205 206 #ifdef ISC_RWLOCK_USEATOMIC 207 isc_rwlock_t dblock; 208 #else 209 isc_mutex_t dblock; 210 #endif 211 dns_db_t *db; /* Locked by dblock */ 212 213 /* Locked */ 214 dns_zonemgr_t *zmgr; 215 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */ 216 isc_timer_t *timer; 217 unsigned int irefs; 218 dns_name_t origin; 219 char *masterfile; 220 ISC_LIST(dns_include_t) includes; /* Include files */ 221 ISC_LIST(dns_include_t) newincludes; /* Loading */ 222 unsigned int nincludes; 223 dns_masterformat_t masterformat; 224 char *journal; 225 isc_int32_t journalsize; 226 dns_rdataclass_t rdclass; 227 dns_zonetype_t type; 228 unsigned int flags; 229 unsigned int options; 230 unsigned int options2; 231 unsigned int db_argc; 232 char **db_argv; 233 isc_time_t expiretime; 234 isc_time_t refreshtime; 235 isc_time_t dumptime; 236 isc_time_t loadtime; 237 isc_time_t notifytime; 238 isc_time_t resigntime; 239 isc_time_t keywarntime; 240 isc_time_t signingtime; 241 isc_time_t nsec3chaintime; 242 isc_time_t refreshkeytime; 243 isc_uint32_t refreshkeyinterval; 244 isc_uint32_t refreshkeycount; 245 isc_uint32_t refresh; 246 isc_uint32_t retry; 247 isc_uint32_t expire; 248 isc_uint32_t minimum; 249 isc_stdtime_t key_expiry; 250 isc_stdtime_t log_key_expired_timer; 251 char *keydirectory; 252 253 isc_uint32_t maxrefresh; 254 isc_uint32_t minrefresh; 255 isc_uint32_t maxretry; 256 isc_uint32_t minretry; 257 258 isc_sockaddr_t *masters; 259 isc_dscp_t *masterdscps; 260 dns_name_t **masterkeynames; 261 isc_boolean_t *mastersok; 262 unsigned int masterscnt; 263 unsigned int curmaster; 264 isc_sockaddr_t masteraddr; 265 dns_notifytype_t notifytype; 266 isc_sockaddr_t *notify; 267 dns_name_t **notifykeynames; 268 isc_dscp_t *notifydscp; 269 unsigned int notifycnt; 270 isc_sockaddr_t notifyfrom; 271 isc_task_t *task; 272 isc_task_t *loadtask; 273 isc_sockaddr_t notifysrc4; 274 isc_sockaddr_t notifysrc6; 275 isc_sockaddr_t xfrsource4; 276 isc_sockaddr_t xfrsource6; 277 isc_sockaddr_t altxfrsource4; 278 isc_sockaddr_t altxfrsource6; 279 isc_sockaddr_t sourceaddr; 280 isc_dscp_t notifysrc4dscp; 281 isc_dscp_t notifysrc6dscp; 282 isc_dscp_t xfrsource4dscp; 283 isc_dscp_t xfrsource6dscp; 284 isc_dscp_t altxfrsource4dscp; 285 isc_dscp_t altxfrsource6dscp; 286 dns_xfrin_ctx_t *xfr; /* task locked */ 287 dns_tsigkey_t *tsigkey; /* key used for xfr */ 288 /* Access Control Lists */ 289 dns_acl_t *update_acl; 290 dns_acl_t *forward_acl; 291 dns_acl_t *notify_acl; 292 dns_acl_t *query_acl; 293 dns_acl_t *queryon_acl; 294 dns_acl_t *xfr_acl; 295 isc_boolean_t update_disabled; 296 isc_boolean_t zero_no_soa_ttl; 297 dns_severity_t check_names; 298 ISC_LIST(dns_notify_t) notifies; 299 dns_request_t *request; 300 dns_loadctx_t *lctx; 301 dns_io_t *readio; 302 dns_dumpctx_t *dctx; 303 dns_io_t *writeio; 304 isc_uint32_t maxxfrin; 305 isc_uint32_t maxxfrout; 306 isc_uint32_t idlein; 307 isc_uint32_t idleout; 308 isc_event_t ctlevent; 309 dns_ssutable_t *ssutable; 310 isc_uint32_t sigvalidityinterval; 311 isc_uint32_t sigresigninginterval; 312 dns_view_t *view; 313 dns_acache_t *acache; 314 dns_checkmxfunc_t checkmx; 315 dns_checksrvfunc_t checksrv; 316 dns_checknsfunc_t checkns; 317 /*% 318 * Zones in certain states such as "waiting for zone transfer" 319 * or "zone transfer in progress" are kept on per-state linked lists 320 * in the zone manager using the 'statelink' field. The 'statelist' 321 * field points at the list the zone is currently on. It the zone 322 * is not on any such list, statelist is NULL. 323 */ 324 ISC_LINK(dns_zone_t) statelink; 325 dns_zonelist_t *statelist; 326 /*% 327 * Statistics counters about zone management. 328 */ 329 isc_stats_t *stats; 330 /*% 331 * Optional per-zone statistics counters. Counted outside of this 332 * module. 333 */ 334 dns_zonestat_level_t statlevel; 335 isc_boolean_t requeststats_on; 336 isc_stats_t *requeststats; 337 dns_stats_t *rcvquerystats; 338 isc_uint32_t notifydelay; 339 dns_isselffunc_t isself; 340 void *isselfarg; 341 342 char * strnamerd; 343 char * strname; 344 char * strrdclass; 345 char * strviewname; 346 347 /*% 348 * Serial number for deferred journal compaction. 349 */ 350 isc_uint32_t compact_serial; 351 /*% 352 * Keys that are signing the zone for the first time. 353 */ 354 dns_signinglist_t signing; 355 dns_nsec3chainlist_t nsec3chain; 356 /*% 357 * Signing / re-signing quantum stopping parameters. 358 */ 359 isc_uint32_t signatures; 360 isc_uint32_t nodes; 361 dns_rdatatype_t privatetype; 362 363 /*% 364 * Autosigning/key-maintenance options 365 */ 366 isc_uint32_t keyopts; 367 368 /*% 369 * True if added by "rndc addzone" 370 */ 371 isc_boolean_t added; 372 373 /*% 374 * response policy data to be relayed to the database 375 */ 376 dns_rpz_zones_t *rpzs; 377 dns_rpz_num_t rpz_num; 378 379 /*% 380 * Serial number update method. 381 */ 382 dns_updatemethod_t updatemethod; 383 384 /*% 385 * whether ixfr is requested 386 */ 387 isc_boolean_t requestixfr; 388 389 /*% 390 * Outstanding forwarded UPDATE requests. 391 */ 392 dns_forwardlist_t forwards; 393 394 dns_zone_t *raw; 395 dns_zone_t *secure; 396 397 isc_boolean_t sourceserialset; 398 isc_uint32_t sourceserial; 399 400 /*% 401 * maximum zone ttl 402 */ 403 dns_ttl_t maxttl; 404 405 }; 406 407 typedef struct { 408 dns_diff_t *diff; 409 isc_boolean_t offline; 410 } zonediff_t; 411 412 #define zonediff_init(z, d) \ 413 do { \ 414 zonediff_t *_z = (z); \ 415 (_z)->diff = (d); \ 416 (_z)->offline = ISC_FALSE; \ 417 } while (/*CONSTCOND*/0) 418 419 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0)) 420 #define DNS_ZONE_SETFLAG(z,f) do { \ 421 INSIST(LOCKED_ZONE(z)); \ 422 (z)->flags |= (f); \ 423 } while (/*CONSTCOND*/0) 424 #define DNS_ZONE_CLRFLAG(z,f) do { \ 425 INSIST(LOCKED_ZONE(z)); \ 426 (z)->flags &= ~(f); \ 427 } while (/*CONSTCOND*/0) 428 /* XXX MPA these may need to go back into zone.h */ 429 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */ 430 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */ 431 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */ 432 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */ 433 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */ 434 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */ 435 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */ 436 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */ 437 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */ 438 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are 439 * uptodate */ 440 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify 441 * messages */ 442 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on 443 * reload */ 444 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a 445 * zone with no masters 446 * occurred */ 447 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/ 448 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set 449 * from SOA (if not set, we 450 * are still using 451 * default timer values) */ 452 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */ 453 #define DNS_ZONEFLG_NOREFRESH 0x00010000U 454 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U 455 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U 456 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U 457 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */ 458 #define DNS_ZONEFLG_FLUSH 0x00200000U 459 #define DNS_ZONEFLG_NOEDNS 0x00400000U 460 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U 461 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U 462 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U 463 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */ 464 #define DNS_ZONEFLG_THAW 0x08000000U 465 #define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */ 466 #define DNS_ZONEFLG_NODELAY 0x20000000U 467 #define DNS_ZONEFLG_SENDSECURE 0x40000000U 468 #define DNS_ZONEFLG_NEEDSTARTUPNOTIFY 0x80000000U /*%< need to send out notify 469 * due to the zone just 470 * being loaded for the 471 * first time. */ 472 473 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0) 474 #define DNS_ZONE_OPTION2(z,o) (((z)->options2 & (o)) != 0) 475 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0) 476 477 /* Flags for zone_load() */ 478 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */ 479 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful 480 load. */ 481 482 #define UNREACH_CHACHE_SIZE 10U 483 #define UNREACH_HOLD_TIME 600 /* 10 minutes */ 484 485 #define CHECK(op) \ 486 do { result = (op); \ 487 if (result != ISC_R_SUCCESS) goto failure; \ 488 } while (/*CONSTCOND*/0) 489 490 struct dns_unreachable { 491 isc_sockaddr_t remote; 492 isc_sockaddr_t local; 493 isc_uint32_t expire; 494 isc_uint32_t last; 495 isc_uint32_t count; 496 }; 497 498 struct dns_zonemgr { 499 unsigned int magic; 500 isc_mem_t * mctx; 501 int refs; /* Locked by rwlock */ 502 isc_taskmgr_t * taskmgr; 503 isc_timermgr_t * timermgr; 504 isc_socketmgr_t * socketmgr; 505 isc_taskpool_t * zonetasks; 506 isc_taskpool_t * loadtasks; 507 isc_task_t * task; 508 isc_pool_t * mctxpool; 509 isc_ratelimiter_t * notifyrl; 510 isc_ratelimiter_t * refreshrl; 511 isc_ratelimiter_t * startupnotifyrl; 512 isc_ratelimiter_t * startuprefreshrl; 513 isc_rwlock_t rwlock; 514 isc_mutex_t iolock; 515 isc_rwlock_t urlock; 516 517 /* Locked by rwlock. */ 518 dns_zonelist_t zones; 519 dns_zonelist_t waiting_for_xfrin; 520 dns_zonelist_t xfrin_in_progress; 521 522 /* Configuration data. */ 523 isc_uint32_t transfersin; 524 isc_uint32_t transfersperns; 525 unsigned int notifyrate; 526 unsigned int startupnotifyrate; 527 unsigned int serialqueryrate; 528 unsigned int startupserialqueryrate; 529 530 /* Locked by iolock */ 531 isc_uint32_t iolimit; 532 isc_uint32_t ioactive; 533 dns_iolist_t high; 534 dns_iolist_t low; 535 536 /* Locked by urlock. */ 537 /* LRU cache */ 538 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE]; 539 }; 540 541 /*% 542 * Hold notify state. 543 */ 544 struct dns_notify { 545 unsigned int magic; 546 unsigned int flags; 547 isc_mem_t *mctx; 548 dns_zone_t *zone; 549 dns_adbfind_t *find; 550 dns_request_t *request; 551 dns_name_t ns; 552 isc_sockaddr_t dst; 553 dns_tsigkey_t *key; 554 isc_dscp_t dscp; 555 ISC_LINK(dns_notify_t) link; 556 isc_event_t *event; 557 }; 558 559 #define DNS_NOTIFY_NOSOA 0x0001U 560 #define DNS_NOTIFY_STARTUP 0x0002U 561 562 /*% 563 * dns_stub holds state while performing a 'stub' transfer. 564 * 'db' is the zone's 'db' or a new one if this is the initial 565 * transfer. 566 */ 567 568 struct dns_stub { 569 unsigned int magic; 570 isc_mem_t *mctx; 571 dns_zone_t *zone; 572 dns_db_t *db; 573 dns_dbversion_t *version; 574 }; 575 576 /*% 577 * Hold load state. 578 */ 579 struct dns_load { 580 unsigned int magic; 581 isc_mem_t *mctx; 582 dns_zone_t *zone; 583 dns_db_t *db; 584 isc_time_t loadtime; 585 dns_rdatacallbacks_t callbacks; 586 }; 587 588 /*% 589 * Hold forward state. 590 */ 591 struct dns_forward { 592 unsigned int magic; 593 isc_mem_t *mctx; 594 dns_zone_t *zone; 595 isc_buffer_t *msgbuf; 596 dns_request_t *request; 597 isc_uint32_t which; 598 isc_sockaddr_t addr; 599 dns_updatecallback_t callback; 600 void *callback_arg; 601 unsigned int options; 602 ISC_LINK(dns_forward_t) link; 603 }; 604 605 /*% 606 * Hold IO request state. 607 */ 608 struct dns_io { 609 unsigned int magic; 610 dns_zonemgr_t *zmgr; 611 isc_boolean_t high; 612 isc_task_t *task; 613 ISC_LINK(dns_io_t) link; 614 isc_event_t *event; 615 }; 616 617 /*% 618 * Hold state for when we are signing a zone with a new 619 * DNSKEY as result of an update. 620 */ 621 struct dns_signing { 622 unsigned int magic; 623 dns_db_t *db; 624 dns_dbiterator_t *dbiterator; 625 dns_secalg_t algorithm; 626 isc_uint16_t keyid; 627 isc_boolean_t delete; 628 isc_boolean_t done; 629 ISC_LINK(dns_signing_t) link; 630 }; 631 632 struct dns_nsec3chain { 633 unsigned int magic; 634 dns_db_t *db; 635 dns_dbiterator_t *dbiterator; 636 dns_rdata_nsec3param_t nsec3param; 637 unsigned char salt[255]; 638 isc_boolean_t done; 639 isc_boolean_t seen_nsec; 640 isc_boolean_t delete_nsec; 641 isc_boolean_t save_delete_nsec; 642 ISC_LINK(dns_nsec3chain_t) link; 643 }; 644 /*%< 645 * 'dbiterator' contains a iterator for the database. If we are creating 646 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are 647 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be 648 * iterated. 649 * 650 * 'nsec3param' contains the parameters of the NSEC3 chain being created 651 * or removed. 652 * 653 * 'salt' is buffer space and is referenced via 'nsec3param.salt'. 654 * 655 * 'seen_nsec' will be set to true if, while iterating the zone to create a 656 * NSEC3 chain, a NSEC record is seen. 657 * 658 * 'delete_nsec' will be set to true if, at the completion of the creation 659 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we 660 * are in the process of deleting the NSEC chain. 661 * 662 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec' 663 * so it can be recovered in the event of a error. 664 */ 665 666 struct dns_keyfetch { 667 dns_fixedname_t name; 668 dns_rdataset_t keydataset; 669 dns_rdataset_t dnskeyset; 670 dns_rdataset_t dnskeysigset; 671 dns_zone_t *zone; 672 dns_db_t *db; 673 dns_fetch_t *fetch; 674 }; 675 676 /*% 677 * Hold state for an asynchronous load 678 */ 679 struct dns_asyncload { 680 dns_zone_t *zone; 681 dns_zt_zoneloaded_t loaded; 682 void *loaded_arg; 683 }; 684 685 /*% 686 * Reference to an include file encountered during loading 687 */ 688 struct dns_include { 689 char *name; 690 isc_time_t filetime; 691 ISC_LINK(dns_include_t) link; 692 }; 693 694 #define HOUR 3600 695 #define DAY (24*HOUR) 696 #define MONTH (30*DAY) 697 698 /* 699 * These can be overridden by the -T mkeytimers option on the command 700 * line, so that we can test with shorter periods than specified in 701 * RFC 5011. 702 */ 703 unsigned int dns_zone_mkey_hour = HOUR; 704 unsigned int dns_zone_mkey_day = (24 * HOUR); 705 unsigned int dns_zone_mkey_month = (30 * DAY); 706 707 708 #define SEND_BUFFER_SIZE 2048 709 710 static void zone_settimer(dns_zone_t *, isc_time_t *); 711 static void cancel_refresh(dns_zone_t *); 712 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel, 713 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5); 714 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...) 715 ISC_FORMAT_PRINTF(3, 4); 716 static void queue_xfrin(dns_zone_t *zone); 717 static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver, 718 dns_diff_t *diff, dns_diffop_t op, 719 dns_name_t *name, dns_ttl_t ttl, 720 dns_rdata_t *rdata); 721 static void zone_unload(dns_zone_t *zone); 722 static void zone_expire(dns_zone_t *zone); 723 static void zone_iattach(dns_zone_t *source, dns_zone_t **target); 724 static void zone_idetach(dns_zone_t **zonep); 725 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db, 726 isc_boolean_t dump); 727 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db); 728 static inline void zone_detachdb(dns_zone_t *zone); 729 static isc_result_t default_journal(dns_zone_t *zone); 730 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result); 731 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db, 732 isc_time_t loadtime, isc_result_t result); 733 static void zone_needdump(dns_zone_t *zone, unsigned int delay); 734 static void zone_shutdown(isc_task_t *, isc_event_t *); 735 static void zone_loaddone(void *arg, isc_result_t result); 736 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone, 737 isc_time_t loadtime); 738 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length); 739 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length); 740 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length); 741 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length); 742 static isc_result_t zone_send_secureserial(dns_zone_t *zone, 743 isc_uint32_t serial); 744 745 #if 0 746 /* ondestroy example */ 747 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event); 748 #endif 749 750 static void refresh_callback(isc_task_t *, isc_event_t *); 751 static void stub_callback(isc_task_t *, isc_event_t *); 752 static void queue_soa_query(dns_zone_t *zone); 753 static void soa_query(isc_task_t *, isc_event_t *); 754 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, 755 dns_stub_t *stub); 756 static int message_count(dns_message_t *msg, dns_section_t section, 757 dns_rdatatype_t type); 758 static void notify_cancel(dns_zone_t *zone); 759 static void notify_find_address(dns_notify_t *notify); 760 static void notify_send(dns_notify_t *notify); 761 static isc_result_t notify_createmessage(dns_zone_t *zone, 762 unsigned int flags, 763 dns_message_t **messagep); 764 static void notify_done(isc_task_t *task, isc_event_t *event); 765 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event); 766 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t); 767 static void got_transfer_quota(isc_task_t *task, isc_event_t *event); 768 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, 769 dns_zone_t *zone); 770 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi); 771 static void zonemgr_free(dns_zonemgr_t *zmgr); 772 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high, 773 isc_task_t *task, isc_taskaction_t action, 774 void *arg, dns_io_t **iop); 775 static void zonemgr_putio(dns_io_t **iop); 776 static void zonemgr_cancelio(dns_io_t *io); 777 778 static isc_result_t 779 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 780 unsigned int *soacount, isc_uint32_t *serial, 781 isc_uint32_t *refresh, isc_uint32_t *retry, 782 isc_uint32_t *expire, isc_uint32_t *minimum, 783 unsigned int *errors); 784 785 static void zone_freedbargs(dns_zone_t *zone); 786 static void forward_callback(isc_task_t *task, isc_event_t *event); 787 static void zone_saveunique(dns_zone_t *zone, const char *path, 788 const char *templat); 789 static void zone_maintenance(dns_zone_t *zone); 790 static void zone_notify(dns_zone_t *zone, isc_time_t *now); 791 static void dump_done(void *arg, isc_result_t result); 792 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, 793 isc_uint16_t keyid, isc_boolean_t delete); 794 static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver, 795 dns_dbnode_t *node, dns_name_t *name, 796 dns_diff_t *diff); 797 static void zone_rekey(dns_zone_t *zone); 798 static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db); 799 static void setrl(isc_ratelimiter_t *rl, unsigned int *rate, 800 unsigned int value); 801 802 #define ENTER zone_debuglog(zone, me, 1, "enter") 803 804 static const unsigned int dbargc_default = 1; 805 static const char *dbargv_default[] = { "rbt" }; 806 807 #define DNS_ZONE_JITTER_ADD(a, b, c) \ 808 do { \ 809 isc_interval_t _i; \ 810 isc_uint32_t _j; \ 811 _j = isc_random_jitter((b), (b)/4); \ 812 isc_interval_set(&_i, _j, 0); \ 813 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 814 dns_zone_log(zone, ISC_LOG_WARNING, \ 815 "epoch approaching: upgrade required: " \ 816 "now + %s failed", #b); \ 817 isc_interval_set(&_i, _j/2, 0); \ 818 (void)isc_time_add((a), &_i, (c)); \ 819 } \ 820 } while (/*CONSTCOND*/0) 821 822 #define DNS_ZONE_TIME_ADD(a, b, c) \ 823 do { \ 824 isc_interval_t _i; \ 825 isc_interval_set(&_i, (b), 0); \ 826 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 827 dns_zone_log(zone, ISC_LOG_WARNING, \ 828 "epoch approaching: upgrade required: " \ 829 "now + %s failed", #b); \ 830 isc_interval_set(&_i, (b)/2, 0); \ 831 (void)isc_time_add((a), &_i, (c)); \ 832 } \ 833 } while (/*CONSTCOND*/0) 834 835 typedef struct nsec3param nsec3param_t; 836 struct nsec3param { 837 unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1]; 838 unsigned int length; 839 isc_boolean_t nsec; 840 isc_boolean_t replace; 841 ISC_LINK(nsec3param_t) link; 842 }; 843 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t; 844 struct np3event { 845 isc_event_t event; 846 nsec3param_t params; 847 }; 848 849 /*% 850 * Increment resolver-related statistics counters. Zone must be locked. 851 */ 852 static inline void 853 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { 854 if (zone->stats != NULL) 855 isc_stats_increment(zone->stats, counter); 856 } 857 858 /*** 859 *** Public functions. 860 ***/ 861 862 isc_result_t 863 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { 864 isc_result_t result; 865 dns_zone_t *zone; 866 isc_time_t now; 867 868 REQUIRE(zonep != NULL && *zonep == NULL); 869 REQUIRE(mctx != NULL); 870 871 TIME_NOW(&now); 872 zone = isc_mem_get(mctx, sizeof(*zone)); 873 if (zone == NULL) 874 return (ISC_R_NOMEMORY); 875 876 zone->mctx = NULL; 877 isc_mem_attach(mctx, &zone->mctx); 878 879 result = isc_mutex_init(&zone->lock); 880 if (result != ISC_R_SUCCESS) 881 goto free_zone; 882 883 result = ZONEDB_INITLOCK(&zone->dblock); 884 if (result != ISC_R_SUCCESS) 885 goto free_mutex; 886 887 /* XXX MPA check that all elements are initialised */ 888 #ifdef DNS_ZONE_CHECKLOCK 889 zone->locked = ISC_FALSE; 890 #endif 891 zone->db = NULL; 892 zone->zmgr = NULL; 893 ISC_LINK_INIT(zone, link); 894 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */ 895 if (result != ISC_R_SUCCESS) 896 goto free_dblock; 897 zone->irefs = 0; 898 dns_name_init(&zone->origin, NULL); 899 zone->strnamerd = NULL; 900 zone->strname = NULL; 901 zone->strrdclass = NULL; 902 zone->strviewname = NULL; 903 zone->masterfile = NULL; 904 ISC_LIST_INIT(zone->includes); 905 ISC_LIST_INIT(zone->newincludes); 906 zone->nincludes = 0; 907 zone->masterformat = dns_masterformat_none; 908 zone->keydirectory = NULL; 909 zone->journalsize = -1; 910 zone->journal = NULL; 911 zone->rdclass = dns_rdataclass_none; 912 zone->type = dns_zone_none; 913 zone->flags = 0; 914 zone->options = 0; 915 zone->keyopts = 0; 916 zone->db_argc = 0; 917 zone->db_argv = NULL; 918 isc_time_settoepoch(&zone->expiretime); 919 isc_time_settoepoch(&zone->refreshtime); 920 isc_time_settoepoch(&zone->dumptime); 921 isc_time_settoepoch(&zone->loadtime); 922 zone->notifytime = now; 923 isc_time_settoepoch(&zone->resigntime); 924 isc_time_settoepoch(&zone->keywarntime); 925 isc_time_settoepoch(&zone->signingtime); 926 isc_time_settoepoch(&zone->nsec3chaintime); 927 isc_time_settoepoch(&zone->refreshkeytime); 928 zone->refreshkeyinterval = 0; 929 zone->refreshkeycount = 0; 930 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 931 zone->retry = DNS_ZONE_DEFAULTRETRY; 932 zone->expire = 0; 933 zone->minimum = 0; 934 zone->maxrefresh = DNS_ZONE_MAXREFRESH; 935 zone->minrefresh = DNS_ZONE_MINREFRESH; 936 zone->maxretry = DNS_ZONE_MAXRETRY; 937 zone->minretry = DNS_ZONE_MINRETRY; 938 zone->masters = NULL; 939 zone->masterdscps = NULL; 940 zone->masterkeynames = NULL; 941 zone->mastersok = NULL; 942 zone->masterscnt = 0; 943 zone->curmaster = 0; 944 zone->maxttl = 0; 945 zone->notify = NULL; 946 zone->notifykeynames = NULL; 947 zone->notifydscp = NULL; 948 zone->notifytype = dns_notifytype_yes; 949 zone->notifycnt = 0; 950 zone->task = NULL; 951 zone->loadtask = NULL; 952 zone->update_acl = NULL; 953 zone->forward_acl = NULL; 954 zone->notify_acl = NULL; 955 zone->query_acl = NULL; 956 zone->queryon_acl = NULL; 957 zone->xfr_acl = NULL; 958 zone->update_disabled = ISC_FALSE; 959 zone->zero_no_soa_ttl = ISC_TRUE; 960 zone->check_names = dns_severity_ignore; 961 zone->request = NULL; 962 zone->lctx = NULL; 963 zone->readio = NULL; 964 zone->dctx = NULL; 965 zone->writeio = NULL; 966 zone->timer = NULL; 967 zone->idlein = DNS_DEFAULT_IDLEIN; 968 zone->idleout = DNS_DEFAULT_IDLEOUT; 969 zone->log_key_expired_timer = 0; 970 ISC_LIST_INIT(zone->notifies); 971 isc_sockaddr_any(&zone->notifysrc4); 972 isc_sockaddr_any6(&zone->notifysrc6); 973 isc_sockaddr_any(&zone->xfrsource4); 974 isc_sockaddr_any6(&zone->xfrsource6); 975 isc_sockaddr_any(&zone->altxfrsource4); 976 isc_sockaddr_any6(&zone->altxfrsource6); 977 zone->notifysrc4dscp = -1; 978 zone->notifysrc6dscp = -1; 979 zone->xfrsource4dscp = -1; 980 zone->xfrsource6dscp = -1; 981 zone->altxfrsource4dscp = -1; 982 zone->altxfrsource6dscp = -1; 983 zone->xfr = NULL; 984 zone->tsigkey = NULL; 985 zone->maxxfrin = MAX_XFER_TIME; 986 zone->maxxfrout = MAX_XFER_TIME; 987 zone->ssutable = NULL; 988 zone->sigvalidityinterval = 30 * 24 * 3600; 989 zone->sigresigninginterval = 7 * 24 * 3600; 990 zone->view = NULL; 991 zone->acache = NULL; 992 zone->checkmx = NULL; 993 zone->checksrv = NULL; 994 zone->checkns = NULL; 995 ISC_LINK_INIT(zone, statelink); 996 zone->statelist = NULL; 997 zone->stats = NULL; 998 zone->requeststats_on = ISC_FALSE; 999 zone->statlevel = dns_zonestat_none; 1000 zone->requeststats = NULL; 1001 zone->rcvquerystats = NULL; 1002 zone->notifydelay = 5; 1003 zone->isself = NULL; 1004 zone->isselfarg = NULL; 1005 ISC_LIST_INIT(zone->signing); 1006 ISC_LIST_INIT(zone->nsec3chain); 1007 zone->signatures = 10; 1008 zone->nodes = 100; 1009 zone->privatetype = (dns_rdatatype_t)0xffffU; 1010 zone->added = ISC_FALSE; 1011 zone->rpzs = NULL; 1012 zone->rpz_num = DNS_RPZ_INVALID_NUM; 1013 ISC_LIST_INIT(zone->forwards); 1014 zone->raw = NULL; 1015 zone->secure = NULL; 1016 zone->sourceserial = 0; 1017 zone->sourceserialset = ISC_FALSE; 1018 1019 zone->magic = ZONE_MAGIC; 1020 1021 /* Must be after magic is set. */ 1022 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default); 1023 if (result != ISC_R_SUCCESS) 1024 goto free_erefs; 1025 1026 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL, 1027 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, 1028 NULL, NULL); 1029 *zonep = zone; 1030 return (ISC_R_SUCCESS); 1031 1032 free_erefs: 1033 isc_refcount_decrement(&zone->erefs, NULL); 1034 isc_refcount_destroy(&zone->erefs); 1035 1036 free_dblock: 1037 ZONEDB_DESTROYLOCK(&zone->dblock); 1038 1039 free_mutex: 1040 DESTROYLOCK(&zone->lock); 1041 1042 free_zone: 1043 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone)); 1044 return (result); 1045 } 1046 1047 /* 1048 * Free a zone. Because we require that there be no more 1049 * outstanding events or references, no locking is necessary. 1050 */ 1051 static void 1052 zone_free(dns_zone_t *zone) { 1053 isc_mem_t *mctx = NULL; 1054 dns_signing_t *signing; 1055 dns_nsec3chain_t *nsec3chain; 1056 dns_include_t *include; 1057 1058 REQUIRE(DNS_ZONE_VALID(zone)); 1059 REQUIRE(isc_refcount_current(&zone->erefs) == 0); 1060 REQUIRE(zone->irefs == 0); 1061 REQUIRE(!LOCKED_ZONE(zone)); 1062 REQUIRE(zone->timer == NULL); 1063 REQUIRE(zone->zmgr == NULL); 1064 1065 /* 1066 * Managed objects. Order is important. 1067 */ 1068 if (zone->request != NULL) 1069 dns_request_destroy(&zone->request); /* XXXMPA */ 1070 INSIST(zone->readio == NULL); 1071 INSIST(zone->statelist == NULL); 1072 INSIST(zone->writeio == NULL); 1073 1074 if (zone->task != NULL) 1075 isc_task_detach(&zone->task); 1076 if (zone->loadtask != NULL) 1077 isc_task_detach(&zone->loadtask); 1078 1079 /* Unmanaged objects */ 1080 for (signing = ISC_LIST_HEAD(zone->signing); 1081 signing != NULL; 1082 signing = ISC_LIST_HEAD(zone->signing)) { 1083 ISC_LIST_UNLINK(zone->signing, signing, link); 1084 dns_db_detach(&signing->db); 1085 dns_dbiterator_destroy(&signing->dbiterator); 1086 isc_mem_put(zone->mctx, signing, sizeof *signing); 1087 } 1088 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 1089 nsec3chain != NULL; 1090 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) { 1091 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 1092 dns_db_detach(&nsec3chain->db); 1093 dns_dbiterator_destroy(&nsec3chain->dbiterator); 1094 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 1095 } 1096 for (include = ISC_LIST_HEAD(zone->includes); 1097 include != NULL; 1098 include = ISC_LIST_HEAD(zone->includes)) { 1099 ISC_LIST_UNLINK(zone->includes, include, link); 1100 isc_mem_free(zone->mctx, include->name); 1101 isc_mem_put(zone->mctx, include, sizeof *include); 1102 } 1103 for (include = ISC_LIST_HEAD(zone->newincludes); 1104 include != NULL; 1105 include = ISC_LIST_HEAD(zone->newincludes)) { 1106 ISC_LIST_UNLINK(zone->newincludes, include, link); 1107 isc_mem_free(zone->mctx, include->name); 1108 isc_mem_put(zone->mctx, include, sizeof *include); 1109 } 1110 if (zone->masterfile != NULL) 1111 isc_mem_free(zone->mctx, zone->masterfile); 1112 zone->masterfile = NULL; 1113 if (zone->keydirectory != NULL) 1114 isc_mem_free(zone->mctx, zone->keydirectory); 1115 zone->keydirectory = NULL; 1116 zone->journalsize = -1; 1117 if (zone->journal != NULL) 1118 isc_mem_free(zone->mctx, zone->journal); 1119 zone->journal = NULL; 1120 if (zone->stats != NULL) 1121 isc_stats_detach(&zone->stats); 1122 if (zone->requeststats != NULL) 1123 isc_stats_detach(&zone->requeststats); 1124 if (zone->rcvquerystats != NULL) 1125 dns_stats_detach(&zone->rcvquerystats); 1126 if (zone->db != NULL) 1127 zone_detachdb(zone); 1128 if (zone->acache != NULL) 1129 dns_acache_detach(&zone->acache); 1130 if (zone->rpzs != NULL) { 1131 REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones); 1132 dns_rpz_detach_rpzs(&zone->rpzs); 1133 zone->rpz_num = DNS_RPZ_INVALID_NUM; 1134 } 1135 zone_freedbargs(zone); 1136 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0) 1137 == ISC_R_SUCCESS); 1138 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) 1139 == ISC_R_SUCCESS); 1140 zone->check_names = dns_severity_ignore; 1141 if (zone->update_acl != NULL) 1142 dns_acl_detach(&zone->update_acl); 1143 if (zone->forward_acl != NULL) 1144 dns_acl_detach(&zone->forward_acl); 1145 if (zone->notify_acl != NULL) 1146 dns_acl_detach(&zone->notify_acl); 1147 if (zone->query_acl != NULL) 1148 dns_acl_detach(&zone->query_acl); 1149 if (zone->queryon_acl != NULL) 1150 dns_acl_detach(&zone->queryon_acl); 1151 if (zone->xfr_acl != NULL) 1152 dns_acl_detach(&zone->xfr_acl); 1153 if (dns_name_dynamic(&zone->origin)) 1154 dns_name_free(&zone->origin, zone->mctx); 1155 if (zone->strnamerd != NULL) 1156 isc_mem_free(zone->mctx, zone->strnamerd); 1157 if (zone->strname != NULL) 1158 isc_mem_free(zone->mctx, zone->strname); 1159 if (zone->strrdclass != NULL) 1160 isc_mem_free(zone->mctx, zone->strrdclass); 1161 if (zone->strviewname != NULL) 1162 isc_mem_free(zone->mctx, zone->strviewname); 1163 if (zone->ssutable != NULL) 1164 dns_ssutable_detach(&zone->ssutable); 1165 1166 /* last stuff */ 1167 ZONEDB_DESTROYLOCK(&zone->dblock); 1168 DESTROYLOCK(&zone->lock); 1169 isc_refcount_destroy(&zone->erefs); 1170 zone->magic = 0; 1171 mctx = zone->mctx; 1172 isc_mem_put(mctx, zone, sizeof(*zone)); 1173 isc_mem_detach(&mctx); 1174 } 1175 1176 /* 1177 * Returns ISC_TRUE iff this the signed side of an inline-signing zone. 1178 * Caller should hold zone lock. 1179 */ 1180 static inline isc_boolean_t 1181 inline_secure(dns_zone_t *zone) { 1182 REQUIRE(DNS_ZONE_VALID(zone)); 1183 if (zone->raw != NULL) 1184 return (ISC_TRUE); 1185 return (ISC_FALSE); 1186 } 1187 1188 /* 1189 * Returns ISC_TRUE iff this the unsigned side of an inline-signing zone 1190 * Caller should hold zone lock. 1191 */ 1192 static inline isc_boolean_t 1193 inline_raw(dns_zone_t *zone) { 1194 REQUIRE(DNS_ZONE_VALID(zone)); 1195 if (zone->secure != NULL) 1196 return (ISC_TRUE); 1197 return (ISC_FALSE); 1198 } 1199 1200 /* 1201 * Single shot. 1202 */ 1203 void 1204 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) { 1205 char namebuf[1024]; 1206 1207 REQUIRE(DNS_ZONE_VALID(zone)); 1208 REQUIRE(rdclass != dns_rdataclass_none); 1209 1210 /* 1211 * Test and set. 1212 */ 1213 LOCK_ZONE(zone); 1214 INSIST(zone != zone->raw); 1215 REQUIRE(zone->rdclass == dns_rdataclass_none || 1216 zone->rdclass == rdclass); 1217 zone->rdclass = rdclass; 1218 1219 if (zone->strnamerd != NULL) 1220 isc_mem_free(zone->mctx, zone->strnamerd); 1221 if (zone->strrdclass != NULL) 1222 isc_mem_free(zone->mctx, zone->strrdclass); 1223 1224 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1225 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1226 zone_rdclass_tostr(zone, namebuf, sizeof namebuf); 1227 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf); 1228 1229 if (inline_secure(zone)) 1230 dns_zone_setclass(zone->raw, rdclass); 1231 UNLOCK_ZONE(zone); 1232 } 1233 1234 dns_rdataclass_t 1235 dns_zone_getclass(dns_zone_t *zone) { 1236 REQUIRE(DNS_ZONE_VALID(zone)); 1237 1238 return (zone->rdclass); 1239 } 1240 1241 void 1242 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { 1243 REQUIRE(DNS_ZONE_VALID(zone)); 1244 1245 LOCK_ZONE(zone); 1246 zone->notifytype = notifytype; 1247 UNLOCK_ZONE(zone); 1248 } 1249 1250 isc_result_t 1251 dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) { 1252 isc_result_t result; 1253 unsigned int soacount; 1254 1255 REQUIRE(DNS_ZONE_VALID(zone)); 1256 REQUIRE(serialp != NULL); 1257 1258 LOCK_ZONE(zone); 1259 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1260 if (zone->db != NULL) { 1261 result = zone_get_from_db(zone, zone->db, NULL, &soacount, 1262 serialp, NULL, NULL, NULL, NULL, 1263 NULL); 1264 if (result == ISC_R_SUCCESS && soacount == 0) 1265 result = ISC_R_FAILURE; 1266 } else 1267 result = DNS_R_NOTLOADED; 1268 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1269 UNLOCK_ZONE(zone); 1270 1271 return (result); 1272 } 1273 1274 isc_uint32_t 1275 dns_zone_getserial(dns_zone_t *zone) { 1276 isc_result_t result; 1277 isc_uint32_t serial; 1278 1279 result = dns_zone_getserial2(zone, &serial); 1280 if (result != ISC_R_SUCCESS) 1281 serial = 0; /* XXX: not really correct, but no other choice */ 1282 1283 return (serial); 1284 } 1285 1286 /* 1287 * Single shot. 1288 */ 1289 void 1290 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) { 1291 char namebuf[1024]; 1292 1293 REQUIRE(DNS_ZONE_VALID(zone)); 1294 REQUIRE(type != dns_zone_none); 1295 1296 /* 1297 * Test and set. 1298 */ 1299 LOCK_ZONE(zone); 1300 REQUIRE(zone->type == dns_zone_none || zone->type == type); 1301 zone->type = type; 1302 1303 if (zone->strnamerd != NULL) 1304 isc_mem_free(zone->mctx, zone->strnamerd); 1305 1306 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1307 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1308 UNLOCK_ZONE(zone); 1309 } 1310 1311 static void 1312 zone_freedbargs(dns_zone_t *zone) { 1313 unsigned int i; 1314 1315 /* Free the old database argument list. */ 1316 if (zone->db_argv != NULL) { 1317 for (i = 0; i < zone->db_argc; i++) 1318 isc_mem_free(zone->mctx, zone->db_argv[i]); 1319 isc_mem_put(zone->mctx, zone->db_argv, 1320 zone->db_argc * sizeof(*zone->db_argv)); 1321 } 1322 zone->db_argc = 0; 1323 zone->db_argv = NULL; 1324 } 1325 1326 isc_result_t 1327 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) { 1328 size_t size = 0; 1329 unsigned int i; 1330 isc_result_t result = ISC_R_SUCCESS; 1331 void *mem; 1332 char **tmp, *tmp2; 1333 1334 REQUIRE(DNS_ZONE_VALID(zone)); 1335 REQUIRE(argv != NULL && *argv == NULL); 1336 1337 LOCK_ZONE(zone); 1338 size = (zone->db_argc + 1) * sizeof(char *); 1339 for (i = 0; i < zone->db_argc; i++) 1340 size += strlen(zone->db_argv[i]) + 1; 1341 mem = isc_mem_allocate(mctx, size); 1342 if (mem != NULL) { 1343 tmp = mem; 1344 tmp2 = mem; 1345 tmp2 += (zone->db_argc + 1) * sizeof(char *); 1346 for (i = 0; i < zone->db_argc; i++) { 1347 *tmp++ = tmp2; 1348 strcpy(tmp2, zone->db_argv[i]); 1349 tmp2 += strlen(tmp2) + 1; 1350 } 1351 *tmp = NULL; 1352 } else 1353 result = ISC_R_NOMEMORY; 1354 UNLOCK_ZONE(zone); 1355 *argv = mem; 1356 return (result); 1357 } 1358 1359 isc_result_t 1360 dns_zone_setdbtype(dns_zone_t *zone, 1361 unsigned int dbargc, const char * const *dbargv) { 1362 isc_result_t result = ISC_R_SUCCESS; 1363 char **new = NULL; 1364 unsigned int i; 1365 1366 REQUIRE(DNS_ZONE_VALID(zone)); 1367 REQUIRE(dbargc >= 1); 1368 REQUIRE(dbargv != NULL); 1369 1370 LOCK_ZONE(zone); 1371 1372 /* Set up a new database argument list. */ 1373 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new)); 1374 if (new == NULL) 1375 goto nomem; 1376 for (i = 0; i < dbargc; i++) 1377 new[i] = NULL; 1378 for (i = 0; i < dbargc; i++) { 1379 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]); 1380 if (new[i] == NULL) 1381 goto nomem; 1382 } 1383 1384 /* Free the old list. */ 1385 zone_freedbargs(zone); 1386 1387 zone->db_argc = dbargc; 1388 zone->db_argv = new; 1389 result = ISC_R_SUCCESS; 1390 goto unlock; 1391 1392 nomem: 1393 if (new != NULL) { 1394 for (i = 0; i < dbargc; i++) 1395 if (new[i] != NULL) 1396 isc_mem_free(zone->mctx, new[i]); 1397 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new)); 1398 } 1399 result = ISC_R_NOMEMORY; 1400 1401 unlock: 1402 UNLOCK_ZONE(zone); 1403 return (result); 1404 } 1405 1406 void 1407 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) { 1408 char namebuf[1024]; 1409 REQUIRE(DNS_ZONE_VALID(zone)); 1410 1411 LOCK_ZONE(zone); 1412 INSIST(zone != zone->raw); 1413 if (zone->view != NULL) 1414 dns_view_weakdetach(&zone->view); 1415 dns_view_weakattach(view, &zone->view); 1416 1417 if (zone->strviewname != NULL) 1418 isc_mem_free(zone->mctx, zone->strviewname); 1419 if (zone->strnamerd != NULL) 1420 isc_mem_free(zone->mctx, zone->strnamerd); 1421 1422 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1423 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1424 zone_viewname_tostr(zone, namebuf, sizeof namebuf); 1425 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf); 1426 1427 if (inline_secure(zone)) 1428 dns_zone_setview(zone->raw, view); 1429 1430 UNLOCK_ZONE(zone); 1431 } 1432 1433 dns_view_t * 1434 dns_zone_getview(dns_zone_t *zone) { 1435 REQUIRE(DNS_ZONE_VALID(zone)); 1436 1437 return (zone->view); 1438 } 1439 1440 1441 isc_result_t 1442 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) { 1443 isc_result_t result; 1444 char namebuf[1024]; 1445 1446 REQUIRE(DNS_ZONE_VALID(zone)); 1447 REQUIRE(origin != NULL); 1448 1449 LOCK_ZONE(zone); 1450 INSIST(zone != zone->raw); 1451 if (dns_name_dynamic(&zone->origin)) { 1452 dns_name_free(&zone->origin, zone->mctx); 1453 dns_name_init(&zone->origin, NULL); 1454 } 1455 result = dns_name_dup(origin, zone->mctx, &zone->origin); 1456 1457 if (zone->strnamerd != NULL) 1458 isc_mem_free(zone->mctx, zone->strnamerd); 1459 if (zone->strname != NULL) 1460 isc_mem_free(zone->mctx, zone->strname); 1461 1462 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1463 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1464 zone_name_tostr(zone, namebuf, sizeof namebuf); 1465 zone->strname = isc_mem_strdup(zone->mctx, namebuf); 1466 1467 if (result == ISC_R_SUCCESS && inline_secure(zone)) 1468 result = dns_zone_setorigin(zone->raw, origin); 1469 UNLOCK_ZONE(zone); 1470 return (result); 1471 } 1472 1473 void 1474 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) { 1475 REQUIRE(DNS_ZONE_VALID(zone)); 1476 REQUIRE(acache != NULL); 1477 1478 LOCK_ZONE(zone); 1479 if (zone->acache != NULL) 1480 dns_acache_detach(&zone->acache); 1481 dns_acache_attach(acache, &zone->acache); 1482 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1483 if (zone->db != NULL) { 1484 isc_result_t result; 1485 1486 /* 1487 * If the zone reuses an existing DB, the DB needs to be 1488 * set in the acache explicitly. We can safely ignore the 1489 * case where the DB is already set. If other error happens, 1490 * the acache will not work effectively. 1491 */ 1492 result = dns_acache_setdb(acache, zone->db); 1493 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { 1494 UNEXPECTED_ERROR(__FILE__, __LINE__, 1495 "dns_acache_setdb() failed: %s", 1496 isc_result_totext(result)); 1497 } 1498 } 1499 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1500 UNLOCK_ZONE(zone); 1501 } 1502 1503 static isc_result_t 1504 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) { 1505 char *copy; 1506 1507 if (value != NULL) { 1508 copy = isc_mem_strdup(zone->mctx, value); 1509 if (copy == NULL) 1510 return (ISC_R_NOMEMORY); 1511 } else { 1512 copy = NULL; 1513 } 1514 1515 if (*field != NULL) 1516 isc_mem_free(zone->mctx, *field); 1517 1518 *field = copy; 1519 return (ISC_R_SUCCESS); 1520 } 1521 1522 isc_result_t 1523 dns_zone_setfile(dns_zone_t *zone, const char *file) { 1524 return (dns_zone_setfile2(zone, file, dns_masterformat_text)); 1525 } 1526 1527 isc_result_t 1528 dns_zone_setfile2(dns_zone_t *zone, const char *file, 1529 dns_masterformat_t format) { 1530 isc_result_t result = ISC_R_SUCCESS; 1531 1532 REQUIRE(DNS_ZONE_VALID(zone)); 1533 1534 LOCK_ZONE(zone); 1535 result = dns_zone_setstring(zone, &zone->masterfile, file); 1536 if (result == ISC_R_SUCCESS) { 1537 zone->masterformat = format; 1538 result = default_journal(zone); 1539 } 1540 UNLOCK_ZONE(zone); 1541 1542 return (result); 1543 } 1544 1545 const char * 1546 dns_zone_getfile(dns_zone_t *zone) { 1547 REQUIRE(DNS_ZONE_VALID(zone)); 1548 1549 return (zone->masterfile); 1550 } 1551 1552 dns_ttl_t 1553 dns_zone_getmaxttl(dns_zone_t *zone) { 1554 REQUIRE(DNS_ZONE_VALID(zone)); 1555 1556 return (zone->maxttl); 1557 } 1558 1559 void 1560 dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) { 1561 REQUIRE(DNS_ZONE_VALID(zone)); 1562 1563 LOCK_ZONE(zone); 1564 if (maxttl != 0) 1565 zone->options2 |= DNS_ZONEOPT2_CHECKTTL; 1566 else 1567 zone->options2 &= ~DNS_ZONEOPT2_CHECKTTL; 1568 zone->maxttl = maxttl; 1569 UNLOCK_ZONE(zone); 1570 1571 return; 1572 } 1573 1574 static isc_result_t 1575 default_journal(dns_zone_t *zone) { 1576 isc_result_t result; 1577 char *journal; 1578 1579 REQUIRE(DNS_ZONE_VALID(zone)); 1580 REQUIRE(LOCKED_ZONE(zone)); 1581 1582 if (zone->masterfile != NULL) { 1583 /* Calculate string length including '\0'. */ 1584 int len = strlen(zone->masterfile) + sizeof(".jnl"); 1585 journal = isc_mem_allocate(zone->mctx, len); 1586 if (journal == NULL) 1587 return (ISC_R_NOMEMORY); 1588 strcpy(journal, zone->masterfile); 1589 strcat(journal, ".jnl"); 1590 } else { 1591 journal = NULL; 1592 } 1593 result = dns_zone_setstring(zone, &zone->journal, journal); 1594 if (journal != NULL) 1595 isc_mem_free(zone->mctx, journal); 1596 return (result); 1597 } 1598 1599 isc_result_t 1600 dns_zone_setjournal(dns_zone_t *zone, const char *journal) { 1601 isc_result_t result = ISC_R_SUCCESS; 1602 1603 REQUIRE(DNS_ZONE_VALID(zone)); 1604 1605 LOCK_ZONE(zone); 1606 result = dns_zone_setstring(zone, &zone->journal, journal); 1607 UNLOCK_ZONE(zone); 1608 1609 return (result); 1610 } 1611 1612 char * 1613 dns_zone_getjournal(dns_zone_t *zone) { 1614 REQUIRE(DNS_ZONE_VALID(zone)); 1615 1616 return (zone->journal); 1617 } 1618 1619 /* 1620 * Return true iff the zone is "dynamic", in the sense that the zone's 1621 * master file (if any) is written by the server, rather than being 1622 * updated manually and read by the server. 1623 * 1624 * This is true for slave zones, stub zones, key zones, and zones that 1625 * allow dynamic updates either by having an update policy ("ssutable") 1626 * or an "allow-update" ACL with a value other than exactly "{ none; }". 1627 */ 1628 isc_boolean_t 1629 dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze) { 1630 REQUIRE(DNS_ZONE_VALID(zone)); 1631 1632 if (zone->type == dns_zone_slave || zone->type == dns_zone_stub || 1633 zone->type == dns_zone_key || 1634 (zone->type == dns_zone_redirect && zone->masters != NULL)) 1635 return (ISC_TRUE); 1636 1637 /* If !ignore_freeze, we need check whether updates are disabled. */ 1638 if (zone->type == dns_zone_master && 1639 (!zone->update_disabled || ignore_freeze) && 1640 ((zone->ssutable != NULL) || 1641 (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)))) 1642 return (ISC_TRUE); 1643 1644 return (ISC_FALSE); 1645 1646 } 1647 1648 /* 1649 * Set the response policy index and information for a zone. 1650 */ 1651 isc_result_t 1652 dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs, 1653 dns_rpz_num_t rpz_num) 1654 { 1655 /* 1656 * Only RBTDB zones can be used for response policy zones, 1657 * because only they have the code to load the create the summary data. 1658 * Only zones that are loaded instead of mmap()ed create the 1659 * summary data and so can be policy zones. 1660 */ 1661 if (strcmp(zone->db_argv[0], "rbt") != 0 && 1662 strcmp(zone->db_argv[0], "rbt64") != 0) 1663 return (ISC_R_NOTIMPLEMENTED); 1664 1665 /* 1666 * This must happen only once or be redundant. 1667 */ 1668 LOCK_ZONE(zone); 1669 if (zone->rpzs != NULL) { 1670 REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num); 1671 } else { 1672 REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM); 1673 dns_rpz_attach_rpzs(rpzs, &zone->rpzs); 1674 zone->rpz_num = rpz_num; 1675 } 1676 rpzs->defined |= DNS_RPZ_ZBIT(rpz_num); 1677 UNLOCK_ZONE(zone); 1678 1679 return (ISC_R_SUCCESS); 1680 } 1681 1682 dns_rpz_num_t 1683 dns_zone_get_rpz_num(dns_zone_t *zone) { 1684 return (zone->rpz_num); 1685 } 1686 1687 /* 1688 * If a zone is a response policy zone, mark its new database. 1689 */ 1690 void 1691 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) { 1692 if (zone->rpz_num != DNS_RPZ_INVALID_NUM) { 1693 REQUIRE(zone->rpzs != NULL); 1694 dns_db_rpz_attach(db, zone->rpzs, zone->rpz_num); 1695 } 1696 } 1697 1698 static isc_boolean_t 1699 zone_touched(dns_zone_t *zone) { 1700 isc_result_t result; 1701 isc_time_t modtime; 1702 dns_include_t *include; 1703 1704 REQUIRE(DNS_ZONE_VALID(zone)); 1705 1706 result = isc_file_getmodtime(zone->masterfile, &modtime); 1707 if (result != ISC_R_SUCCESS || 1708 isc_time_compare(&modtime, &zone->loadtime) > 0) 1709 { 1710 zone->loadtime = modtime; 1711 return (ISC_TRUE); 1712 } 1713 1714 for (include = ISC_LIST_HEAD(zone->includes); 1715 include != NULL; 1716 include = ISC_LIST_NEXT(include, link)) 1717 { 1718 result = isc_file_getmodtime(include->name, &modtime); 1719 if (result != ISC_R_SUCCESS || 1720 isc_time_compare(&modtime, &include->filetime) > 0) 1721 return (ISC_TRUE); 1722 } 1723 1724 1725 return (ISC_FALSE); 1726 } 1727 1728 static isc_result_t 1729 zone_load(dns_zone_t *zone, unsigned int flags, isc_boolean_t locked) { 1730 isc_result_t result; 1731 isc_time_t now; 1732 isc_time_t loadtime; 1733 dns_db_t *db = NULL; 1734 isc_boolean_t rbt, hasraw; 1735 1736 REQUIRE(DNS_ZONE_VALID(zone)); 1737 1738 if (!locked) 1739 LOCK_ZONE(zone); 1740 1741 INSIST(zone != zone->raw); 1742 hasraw = inline_secure(zone); 1743 if (hasraw) { 1744 result = zone_load(zone->raw, flags, ISC_FALSE); 1745 if (result != ISC_R_SUCCESS) { 1746 if (!locked) 1747 UNLOCK_ZONE(zone); 1748 return(result); 1749 } 1750 LOCK_ZONE(zone->raw); 1751 } 1752 1753 TIME_NOW(&now); 1754 1755 INSIST(zone->type != dns_zone_none); 1756 1757 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { 1758 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) 1759 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 1760 result = DNS_R_CONTINUE; 1761 goto cleanup; 1762 } 1763 1764 INSIST(zone->db_argc >= 1); 1765 1766 rbt = strcmp(zone->db_argv[0], "rbt") == 0 || 1767 strcmp(zone->db_argv[0], "rbt64") == 0; 1768 1769 if (zone->db != NULL && zone->masterfile == NULL && rbt) { 1770 /* 1771 * The zone has no master file configured. 1772 */ 1773 result = ISC_R_SUCCESS; 1774 goto cleanup; 1775 } 1776 1777 if (zone->db != NULL && dns_zone_isdynamic(zone, ISC_FALSE)) { 1778 /* 1779 * This is a slave, stub, or dynamically updated 1780 * zone being reloaded. Do nothing - the database 1781 * we already have is guaranteed to be up-to-date. 1782 */ 1783 if (zone->type == dns_zone_master) 1784 result = DNS_R_DYNAMIC; 1785 else 1786 result = ISC_R_SUCCESS; 1787 goto cleanup; 1788 } 1789 1790 /* 1791 * Store the current time before the zone is loaded, so that if the 1792 * file changes between the time of the load and the time that 1793 * zone->loadtime is set, then the file will still be reloaded 1794 * the next time dns_zone_load is called. 1795 */ 1796 TIME_NOW(&loadtime); 1797 1798 /* 1799 * Don't do the load if the file that stores the zone is older 1800 * than the last time the zone was loaded. If the zone has not 1801 * been loaded yet, zone->loadtime will be the epoch. 1802 */ 1803 if (zone->masterfile != NULL) { 1804 /* 1805 * The file is already loaded. If we are just doing a 1806 * "rndc reconfig", we are done. 1807 */ 1808 if (!isc_time_isepoch(&zone->loadtime) && 1809 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) { 1810 result = ISC_R_SUCCESS; 1811 goto cleanup; 1812 } 1813 1814 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 1815 !zone_touched(zone)) 1816 { 1817 dns_zone_log(zone, ISC_LOG_DEBUG(1), 1818 "skipping load: master file " 1819 "older than last load"); 1820 result = DNS_R_UPTODATE; 1821 goto cleanup; 1822 } 1823 } 1824 1825 /* 1826 * Built in zones (with the exception of empty zones) don't need 1827 * to be reloaded. 1828 */ 1829 if (zone->type == dns_zone_master && 1830 strcmp(zone->db_argv[0], "_builtin") == 0 && 1831 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) && 1832 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 1833 result = ISC_R_SUCCESS; 1834 goto cleanup; 1835 } 1836 1837 /* 1838 * Zones associated with a DLZ don't need to be loaded either, 1839 * but we need to associate the database with the zone object. 1840 */ 1841 if (strcmp(zone->db_argv[0], "dlz") == 0) { 1842 dns_dlzdb_t *dlzdb; 1843 dns_dlzfindzone_t findzone; 1844 1845 for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched); 1846 dlzdb != NULL; 1847 dlzdb = ISC_LIST_NEXT(dlzdb, link)) 1848 { 1849 INSIST(DNS_DLZ_VALID(dlzdb)); 1850 if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0) 1851 break; 1852 } 1853 1854 if (dlzdb == NULL) { 1855 dns_zone_log(zone, ISC_LOG_ERROR, 1856 "DLZ %s does not exist or is set " 1857 "to 'search yes;'", zone->db_argv[1]); 1858 result = ISC_R_NOTFOUND; 1859 goto cleanup; 1860 } 1861 1862 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 1863 /* ask SDLZ driver if the zone is supported */ 1864 findzone = dlzdb->implementation->methods->findzone; 1865 result = (*findzone)(dlzdb->implementation->driverarg, 1866 dlzdb->dbdata, dlzdb->mctx, 1867 zone->view->rdclass, &zone->origin, 1868 NULL, NULL, &db); 1869 if (result != ISC_R_NOTFOUND) { 1870 if (zone->db != NULL) 1871 zone_detachdb(zone); 1872 zone_attachdb(zone, db); 1873 dns_db_detach(&db); 1874 result = ISC_R_SUCCESS; 1875 } 1876 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 1877 1878 if (result == ISC_R_SUCCESS) { 1879 if (dlzdb->configure_callback == NULL) 1880 goto cleanup; 1881 1882 result = (*dlzdb->configure_callback)(zone->view, 1883 dlzdb, zone); 1884 if (result != ISC_R_SUCCESS) 1885 dns_zone_log(zone, ISC_LOG_ERROR, 1886 "DLZ configuration callback: %s", 1887 isc_result_totext(result)); 1888 } 1889 goto cleanup; 1890 } 1891 1892 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub || 1893 (zone->type == dns_zone_redirect && zone->masters != NULL)) && 1894 rbt) { 1895 if (zone->masterfile == NULL || 1896 !isc_file_exists(zone->masterfile)) { 1897 if (zone->masterfile != NULL) { 1898 dns_zone_log(zone, ISC_LOG_DEBUG(1), 1899 "no master file"); 1900 } 1901 zone->refreshtime = now; 1902 if (zone->task != NULL) 1903 zone_settimer(zone, &now); 1904 result = ISC_R_SUCCESS; 1905 goto cleanup; 1906 } 1907 } 1908 1909 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load"); 1910 1911 result = dns_db_create(zone->mctx, zone->db_argv[0], 1912 &zone->origin, (zone->type == dns_zone_stub) ? 1913 dns_dbtype_stub : dns_dbtype_zone, 1914 zone->rdclass, 1915 zone->db_argc - 1, zone->db_argv + 1, 1916 &db); 1917 1918 if (result != ISC_R_SUCCESS) { 1919 dns_zone_log(zone, ISC_LOG_ERROR, 1920 "loading zone: creating database: %s", 1921 isc_result_totext(result)); 1922 goto cleanup; 1923 } 1924 dns_db_settask(db, zone->task); 1925 1926 if (! dns_db_ispersistent(db)) { 1927 if (zone->masterfile != NULL) { 1928 result = zone_startload(db, zone, loadtime); 1929 } else { 1930 result = DNS_R_NOMASTERFILE; 1931 if (zone->type == dns_zone_master || 1932 (zone->type == dns_zone_redirect && 1933 zone->masters == NULL)) { 1934 dns_zone_log(zone, ISC_LOG_ERROR, 1935 "loading zone: " 1936 "no master file configured"); 1937 goto cleanup; 1938 } 1939 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: " 1940 "no master file configured: continuing"); 1941 } 1942 } 1943 1944 if (result == DNS_R_CONTINUE) { 1945 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING); 1946 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) 1947 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 1948 goto cleanup; 1949 } 1950 1951 result = zone_postload(zone, db, loadtime, result); 1952 1953 cleanup: 1954 if (hasraw) 1955 UNLOCK_ZONE(zone->raw); 1956 if (!locked) 1957 UNLOCK_ZONE(zone); 1958 if (db != NULL) 1959 dns_db_detach(&db); 1960 return (result); 1961 } 1962 1963 isc_result_t 1964 dns_zone_load(dns_zone_t *zone) { 1965 return (zone_load(zone, 0, ISC_FALSE)); 1966 } 1967 1968 isc_result_t 1969 dns_zone_loadnew(dns_zone_t *zone) { 1970 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT, ISC_FALSE)); 1971 } 1972 1973 static void 1974 zone_asyncload(isc_task_t *task, isc_event_t *event) { 1975 dns_asyncload_t *asl = event->ev_arg; 1976 dns_zone_t *zone = asl->zone; 1977 isc_result_t result = ISC_R_SUCCESS; 1978 isc_boolean_t load_pending; 1979 1980 UNUSED(task); 1981 1982 REQUIRE(DNS_ZONE_VALID(zone)); 1983 1984 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) 1985 result = ISC_R_CANCELED; 1986 isc_event_free(&event); 1987 1988 if (result == ISC_R_CANCELED) 1989 goto cleanup; 1990 1991 /* Make sure load is still pending */ 1992 LOCK_ZONE(zone); 1993 load_pending = ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)); 1994 1995 if (!load_pending) { 1996 UNLOCK_ZONE(zone); 1997 goto cleanup; 1998 } 1999 2000 zone_load(zone, 0, ISC_TRUE); 2001 2002 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); 2003 UNLOCK_ZONE(zone); 2004 2005 /* Inform the zone table we've finished loading */ 2006 if (asl->loaded != NULL) 2007 (asl->loaded)(asl->loaded_arg, zone, task); 2008 2009 cleanup: 2010 isc_mem_put(zone->mctx, asl, sizeof (*asl)); 2011 dns_zone_idetach(&zone); 2012 } 2013 2014 isc_result_t 2015 dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) { 2016 isc_event_t *e; 2017 dns_asyncload_t *asl = NULL; 2018 isc_result_t result = ISC_R_SUCCESS; 2019 2020 REQUIRE(DNS_ZONE_VALID(zone)); 2021 2022 if (zone->zmgr == NULL) 2023 return (ISC_R_FAILURE); 2024 2025 /* If we already have a load pending, stop now */ 2026 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) 2027 return (ISC_R_ALREADYRUNNING); 2028 2029 asl = isc_mem_get(zone->mctx, sizeof (*asl)); 2030 if (asl == NULL) 2031 CHECK(ISC_R_NOMEMORY); 2032 2033 asl->zone = NULL; 2034 asl->loaded = done; 2035 asl->loaded_arg = arg; 2036 2037 e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr, 2038 DNS_EVENT_ZONELOAD, 2039 zone_asyncload, asl, 2040 sizeof(isc_event_t)); 2041 if (e == NULL) 2042 CHECK(ISC_R_NOMEMORY); 2043 2044 LOCK_ZONE(zone); 2045 zone_iattach(zone, &asl->zone); 2046 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING); 2047 isc_task_send(zone->loadtask, &e); 2048 UNLOCK_ZONE(zone); 2049 2050 return (ISC_R_SUCCESS); 2051 2052 failure: 2053 if (asl != NULL) 2054 isc_mem_put(zone->mctx, asl, sizeof (*asl)); 2055 return (result); 2056 } 2057 2058 isc_boolean_t 2059 dns__zone_loadpending(dns_zone_t *zone) { 2060 REQUIRE(DNS_ZONE_VALID(zone)); 2061 2062 return (ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))); 2063 } 2064 2065 isc_result_t 2066 dns_zone_loadandthaw(dns_zone_t *zone) { 2067 isc_result_t result; 2068 2069 if (inline_raw(zone)) 2070 result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW, 2071 ISC_FALSE); 2072 else 2073 result = zone_load(zone, DNS_ZONELOADFLAG_THAW, ISC_FALSE); 2074 2075 switch (result) { 2076 case DNS_R_CONTINUE: 2077 /* Deferred thaw. */ 2078 break; 2079 case DNS_R_UPTODATE: 2080 case ISC_R_SUCCESS: 2081 case DNS_R_SEENINCLUDE: 2082 zone->update_disabled = ISC_FALSE; 2083 break; 2084 case DNS_R_NOMASTERFILE: 2085 zone->update_disabled = ISC_FALSE; 2086 break; 2087 default: 2088 /* Error, remain in disabled state. */ 2089 break; 2090 } 2091 return (result); 2092 } 2093 2094 static unsigned int 2095 get_master_options(dns_zone_t *zone) { 2096 unsigned int options; 2097 2098 options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN; 2099 if (zone->type == dns_zone_slave || 2100 (zone->type == dns_zone_redirect && zone->masters == NULL)) 2101 options |= DNS_MASTER_SLAVE; 2102 if (zone->type == dns_zone_key) 2103 options |= DNS_MASTER_KEY; 2104 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) 2105 options |= DNS_MASTER_CHECKNS; 2106 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) 2107 options |= DNS_MASTER_FATALNS; 2108 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) 2109 options |= DNS_MASTER_CHECKNAMES; 2110 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) 2111 options |= DNS_MASTER_CHECKNAMESFAIL; 2112 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) 2113 options |= DNS_MASTER_CHECKMX; 2114 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) 2115 options |= DNS_MASTER_CHECKMXFAIL; 2116 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) 2117 options |= DNS_MASTER_CHECKWILDCARD; 2118 if (DNS_ZONE_OPTION2(zone, DNS_ZONEOPT2_CHECKTTL)) 2119 options |= DNS_MASTER_CHECKTTL; 2120 return (options); 2121 } 2122 2123 static void 2124 zone_registerinclude(const char *filename, void *arg) { 2125 isc_result_t result; 2126 dns_zone_t *zone = (dns_zone_t *) arg; 2127 dns_include_t *inc = NULL; 2128 2129 REQUIRE(DNS_ZONE_VALID(zone)); 2130 2131 if (filename == NULL) 2132 return; 2133 2134 /* 2135 * Suppress duplicates. 2136 */ 2137 for (inc = ISC_LIST_HEAD(zone->newincludes); 2138 inc != NULL; 2139 inc = ISC_LIST_NEXT(inc, link)) 2140 if (strcmp(filename, inc->name) == 0) 2141 return; 2142 2143 inc = isc_mem_get(zone->mctx, sizeof(dns_include_t)); 2144 if (inc == NULL) 2145 return; 2146 inc->name = isc_mem_strdup(zone->mctx, filename); 2147 if (inc->name == NULL) { 2148 isc_mem_put(zone->mctx, inc, sizeof(dns_include_t)); 2149 return; 2150 } 2151 ISC_LINK_INIT(inc, link); 2152 2153 result = isc_file_getmodtime(filename, &inc->filetime); 2154 if (result != ISC_R_SUCCESS) 2155 isc_time_settoepoch(&inc->filetime); 2156 2157 ISC_LIST_APPEND(zone->newincludes, inc, link); 2158 } 2159 2160 static void 2161 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) { 2162 dns_load_t *load = event->ev_arg; 2163 isc_result_t result = ISC_R_SUCCESS; 2164 unsigned int options; 2165 2166 REQUIRE(DNS_LOAD_VALID(load)); 2167 2168 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) 2169 result = ISC_R_CANCELED; 2170 isc_event_free(&event); 2171 if (result == ISC_R_CANCELED) 2172 goto fail; 2173 2174 options = get_master_options(load->zone); 2175 2176 result = dns_master_loadfileinc5(load->zone->masterfile, 2177 dns_db_origin(load->db), 2178 dns_db_origin(load->db), 2179 load->zone->rdclass, options, 0, 2180 &load->callbacks, task, 2181 zone_loaddone, load, 2182 &load->zone->lctx, 2183 zone_registerinclude, 2184 load->zone, load->zone->mctx, 2185 load->zone->masterformat, 2186 load->zone->maxttl); 2187 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE && 2188 result != DNS_R_SEENINCLUDE) 2189 goto fail; 2190 return; 2191 2192 fail: 2193 zone_loaddone(load, result); 2194 } 2195 2196 static void 2197 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) { 2198 isc_result_t result; 2199 unsigned int soacount; 2200 2201 LOCK(&raw->lock); 2202 if (raw->db != NULL) { 2203 result = zone_get_from_db(raw, raw->db, NULL, &soacount, 2204 &rawdata->sourceserial, 2205 NULL, NULL, NULL, NULL, 2206 NULL); 2207 if (result == ISC_R_SUCCESS && soacount > 0U) 2208 rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET; 2209 } 2210 UNLOCK(&raw->lock); 2211 } 2212 2213 static void 2214 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) { 2215 const char me[] = "zone_gotwritehandle"; 2216 dns_zone_t *zone = event->ev_arg; 2217 isc_result_t result = ISC_R_SUCCESS; 2218 dns_dbversion_t *version = NULL; 2219 dns_masterrawheader_t rawdata; 2220 2221 REQUIRE(DNS_ZONE_VALID(zone)); 2222 INSIST(task == zone->task); 2223 ENTER; 2224 2225 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) 2226 result = ISC_R_CANCELED; 2227 isc_event_free(&event); 2228 if (result == ISC_R_CANCELED) 2229 goto fail; 2230 2231 LOCK_ZONE(zone); 2232 INSIST(zone != zone->raw); 2233 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 2234 if (zone->db != NULL) { 2235 const dns_master_style_t *output_style; 2236 2237 dns_db_currentversion(zone->db, &version); 2238 dns_master_initrawheader(&rawdata); 2239 if (inline_secure(zone)) 2240 get_raw_serial(zone->raw, &rawdata); 2241 if (zone->type == dns_zone_key) 2242 output_style = &dns_master_style_keyzone; 2243 else 2244 output_style = &dns_master_style_default; 2245 result = dns_master_dumpinc3(zone->mctx, zone->db, version, 2246 output_style, zone->masterfile, 2247 zone->task, dump_done, zone, &zone->dctx, zone->masterformat, 2248 &rawdata); 2249 dns_db_closeversion(zone->db, &version, ISC_FALSE); 2250 } else 2251 result = ISC_R_CANCELED; 2252 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 2253 UNLOCK_ZONE(zone); 2254 if (result != DNS_R_CONTINUE) 2255 goto fail; 2256 return; 2257 2258 fail: 2259 dump_done(zone, result); 2260 } 2261 2262 /* 2263 * Save the raw serial number for inline-signing zones. 2264 * (XXX: Other information from the header will be used 2265 * for other purposes in the future, but for now this is 2266 * all we're interested in.) 2267 */ 2268 static void 2269 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { 2270 if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0) 2271 return; 2272 2273 zone->sourceserial = header->sourceserial; 2274 zone->sourceserialset = ISC_TRUE; 2275 } 2276 2277 void 2278 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { 2279 if (zone == NULL) 2280 return; 2281 2282 LOCK_ZONE(zone); 2283 zone_setrawdata(zone, header); 2284 UNLOCK_ZONE(zone); 2285 } 2286 2287 static isc_result_t 2288 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { 2289 dns_load_t *load; 2290 isc_result_t result; 2291 isc_result_t tresult; 2292 unsigned int options; 2293 2294 dns_zone_rpz_enable_db(zone, db); 2295 options = get_master_options(zone); 2296 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) 2297 options |= DNS_MASTER_MANYERRORS; 2298 2299 if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) { 2300 load = isc_mem_get(zone->mctx, sizeof(*load)); 2301 if (load == NULL) 2302 return (ISC_R_NOMEMORY); 2303 2304 load->mctx = NULL; 2305 load->zone = NULL; 2306 load->db = NULL; 2307 load->loadtime = loadtime; 2308 load->magic = LOAD_MAGIC; 2309 2310 isc_mem_attach(zone->mctx, &load->mctx); 2311 zone_iattach(zone, &load->zone); 2312 dns_db_attach(db, &load->db); 2313 dns_rdatacallbacks_init(&load->callbacks); 2314 load->callbacks.rawdata = zone_setrawdata; 2315 zone_iattach(zone, &load->callbacks.zone); 2316 result = dns_db_beginload(db, &load->callbacks); 2317 if (result != ISC_R_SUCCESS) 2318 goto cleanup; 2319 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->loadtask, 2320 zone_gotreadhandle, load, 2321 &zone->readio); 2322 if (result != ISC_R_SUCCESS) { 2323 /* 2324 * We can't report multiple errors so ignore 2325 * the result of dns_db_endload(). 2326 */ 2327 (void)dns_db_endload(load->db, &load->callbacks); 2328 goto cleanup; 2329 } else 2330 result = DNS_R_CONTINUE; 2331 } else { 2332 dns_rdatacallbacks_t callbacks; 2333 2334 dns_rdatacallbacks_init(&callbacks); 2335 callbacks.rawdata = zone_setrawdata; 2336 zone_iattach(zone, &callbacks.zone); 2337 result = dns_db_beginload(db, &callbacks); 2338 if (result != ISC_R_SUCCESS) { 2339 zone_idetach(&callbacks.zone); 2340 return (result); 2341 } 2342 result = dns_master_loadfile5(zone->masterfile, 2343 &zone->origin, &zone->origin, 2344 zone->rdclass, options, 0, 2345 &callbacks, 2346 zone_registerinclude, 2347 zone, zone->mctx, 2348 zone->masterformat, 2349 zone->maxttl); 2350 tresult = dns_db_endload(db, &callbacks); 2351 if (result == ISC_R_SUCCESS) 2352 result = tresult; 2353 zone_idetach(&callbacks.zone); 2354 } 2355 2356 return (result); 2357 2358 cleanup: 2359 load->magic = 0; 2360 dns_db_detach(&load->db); 2361 zone_idetach(&load->zone); 2362 zone_idetach(&load->callbacks.zone); 2363 isc_mem_detach(&load->mctx); 2364 isc_mem_put(zone->mctx, load, sizeof(*load)); 2365 return (result); 2366 } 2367 2368 static isc_boolean_t 2369 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2370 dns_name_t *owner) 2371 { 2372 isc_result_t result; 2373 char ownerbuf[DNS_NAME_FORMATSIZE]; 2374 char namebuf[DNS_NAME_FORMATSIZE]; 2375 char altbuf[DNS_NAME_FORMATSIZE]; 2376 dns_fixedname_t fixed; 2377 dns_name_t *foundname; 2378 int level; 2379 2380 /* 2381 * "." means the services does not exist. 2382 */ 2383 if (dns_name_equal(name, dns_rootname)) 2384 return (ISC_TRUE); 2385 2386 /* 2387 * Outside of zone. 2388 */ 2389 if (!dns_name_issubdomain(name, &zone->origin)) { 2390 if (zone->checkmx != NULL) 2391 return ((zone->checkmx)(zone, name, owner)); 2392 return (ISC_TRUE); 2393 } 2394 2395 if (zone->type == dns_zone_master) 2396 level = ISC_LOG_ERROR; 2397 else 2398 level = ISC_LOG_WARNING; 2399 2400 dns_fixedname_init(&fixed); 2401 foundname = dns_fixedname_name(&fixed); 2402 2403 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 2404 0, 0, NULL, foundname, NULL, NULL); 2405 if (result == ISC_R_SUCCESS) 2406 return (ISC_TRUE); 2407 2408 if (result == DNS_R_NXRRSET) { 2409 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 2410 0, 0, NULL, foundname, NULL, NULL); 2411 if (result == ISC_R_SUCCESS) 2412 return (ISC_TRUE); 2413 } 2414 2415 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2416 dns_name_format(name, namebuf, sizeof namebuf); 2417 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2418 result == DNS_R_EMPTYNAME) { 2419 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) 2420 level = ISC_LOG_WARNING; 2421 dns_zone_log(zone, level, 2422 "%s/MX '%s' has no address records (A or AAAA)", 2423 ownerbuf, namebuf); 2424 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2425 } 2426 2427 if (result == DNS_R_CNAME) { 2428 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 2429 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2430 level = ISC_LOG_WARNING; 2431 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2432 dns_zone_log(zone, level, 2433 "%s/MX '%s' is a CNAME (illegal)", 2434 ownerbuf, namebuf); 2435 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2436 } 2437 2438 if (result == DNS_R_DNAME) { 2439 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 2440 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2441 level = ISC_LOG_WARNING; 2442 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { 2443 dns_name_format(foundname, altbuf, sizeof altbuf); 2444 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME" 2445 " '%s' (illegal)", ownerbuf, namebuf, 2446 altbuf); 2447 } 2448 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2449 } 2450 2451 if (zone->checkmx != NULL && result == DNS_R_DELEGATION) 2452 return ((zone->checkmx)(zone, name, owner)); 2453 2454 return (ISC_TRUE); 2455 } 2456 2457 static isc_boolean_t 2458 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2459 dns_name_t *owner) 2460 { 2461 isc_result_t result; 2462 char ownerbuf[DNS_NAME_FORMATSIZE]; 2463 char namebuf[DNS_NAME_FORMATSIZE]; 2464 char altbuf[DNS_NAME_FORMATSIZE]; 2465 dns_fixedname_t fixed; 2466 dns_name_t *foundname; 2467 int level; 2468 2469 /* 2470 * "." means the services does not exist. 2471 */ 2472 if (dns_name_equal(name, dns_rootname)) 2473 return (ISC_TRUE); 2474 2475 /* 2476 * Outside of zone. 2477 */ 2478 if (!dns_name_issubdomain(name, &zone->origin)) { 2479 if (zone->checksrv != NULL) 2480 return ((zone->checksrv)(zone, name, owner)); 2481 return (ISC_TRUE); 2482 } 2483 2484 if (zone->type == dns_zone_master) 2485 level = ISC_LOG_ERROR; 2486 else 2487 level = ISC_LOG_WARNING; 2488 2489 dns_fixedname_init(&fixed); 2490 foundname = dns_fixedname_name(&fixed); 2491 2492 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 2493 0, 0, NULL, foundname, NULL, NULL); 2494 if (result == ISC_R_SUCCESS) 2495 return (ISC_TRUE); 2496 2497 if (result == DNS_R_NXRRSET) { 2498 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 2499 0, 0, NULL, foundname, NULL, NULL); 2500 if (result == ISC_R_SUCCESS) 2501 return (ISC_TRUE); 2502 } 2503 2504 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2505 dns_name_format(name, namebuf, sizeof namebuf); 2506 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2507 result == DNS_R_EMPTYNAME) { 2508 dns_zone_log(zone, level, 2509 "%s/SRV '%s' has no address records (A or AAAA)", 2510 ownerbuf, namebuf); 2511 /* XXX950 make fatal for 9.5.0. */ 2512 return (ISC_TRUE); 2513 } 2514 2515 if (result == DNS_R_CNAME) { 2516 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 2517 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2518 level = ISC_LOG_WARNING; 2519 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2520 dns_zone_log(zone, level, 2521 "%s/SRV '%s' is a CNAME (illegal)", 2522 ownerbuf, namebuf); 2523 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2524 } 2525 2526 if (result == DNS_R_DNAME) { 2527 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 2528 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2529 level = ISC_LOG_WARNING; 2530 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { 2531 dns_name_format(foundname, altbuf, sizeof altbuf); 2532 dns_zone_log(zone, level, "%s/SRV '%s' is below a " 2533 "DNAME '%s' (illegal)", ownerbuf, namebuf, 2534 altbuf); 2535 } 2536 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2537 } 2538 2539 if (zone->checksrv != NULL && result == DNS_R_DELEGATION) 2540 return ((zone->checksrv)(zone, name, owner)); 2541 2542 return (ISC_TRUE); 2543 } 2544 2545 static isc_boolean_t 2546 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2547 dns_name_t *owner) 2548 { 2549 isc_boolean_t answer = ISC_TRUE; 2550 isc_result_t result, tresult; 2551 char ownerbuf[DNS_NAME_FORMATSIZE]; 2552 char namebuf[DNS_NAME_FORMATSIZE]; 2553 char altbuf[DNS_NAME_FORMATSIZE]; 2554 dns_fixedname_t fixed; 2555 dns_name_t *foundname; 2556 dns_rdataset_t a; 2557 dns_rdataset_t aaaa; 2558 int level; 2559 2560 /* 2561 * Outside of zone. 2562 */ 2563 if (!dns_name_issubdomain(name, &zone->origin)) { 2564 if (zone->checkns != NULL) 2565 return ((zone->checkns)(zone, name, owner, NULL, NULL)); 2566 return (ISC_TRUE); 2567 } 2568 2569 if (zone->type == dns_zone_master) 2570 level = ISC_LOG_ERROR; 2571 else 2572 level = ISC_LOG_WARNING; 2573 2574 dns_fixedname_init(&fixed); 2575 foundname = dns_fixedname_name(&fixed); 2576 dns_rdataset_init(&a); 2577 dns_rdataset_init(&aaaa); 2578 2579 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 2580 DNS_DBFIND_GLUEOK, 0, NULL, 2581 foundname, &a, NULL); 2582 2583 if (result == ISC_R_SUCCESS) { 2584 dns_rdataset_disassociate(&a); 2585 return (ISC_TRUE); 2586 } else if (result == DNS_R_DELEGATION) 2587 dns_rdataset_disassociate(&a); 2588 2589 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION || 2590 result == DNS_R_GLUE) { 2591 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 2592 DNS_DBFIND_GLUEOK, 0, NULL, 2593 foundname, &aaaa, NULL); 2594 if (tresult == ISC_R_SUCCESS) { 2595 if (dns_rdataset_isassociated(&a)) 2596 dns_rdataset_disassociate(&a); 2597 dns_rdataset_disassociate(&aaaa); 2598 return (ISC_TRUE); 2599 } 2600 if (tresult == DNS_R_DELEGATION) 2601 dns_rdataset_disassociate(&aaaa); 2602 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) { 2603 /* 2604 * Check glue against child zone. 2605 */ 2606 if (zone->checkns != NULL) 2607 answer = (zone->checkns)(zone, name, owner, 2608 &a, &aaaa); 2609 if (dns_rdataset_isassociated(&a)) 2610 dns_rdataset_disassociate(&a); 2611 if (dns_rdataset_isassociated(&aaaa)) 2612 dns_rdataset_disassociate(&aaaa); 2613 return (answer); 2614 } 2615 } 2616 2617 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2618 dns_name_format(name, namebuf, sizeof namebuf); 2619 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2620 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) { 2621 const char *what; 2622 isc_boolean_t required = ISC_FALSE; 2623 if (dns_name_issubdomain(name, owner)) { 2624 what = "REQUIRED GLUE "; 2625 required = ISC_TRUE; 2626 } else if (result == DNS_R_DELEGATION) 2627 what = "SIBLING GLUE "; 2628 else 2629 what = ""; 2630 2631 if (result != DNS_R_DELEGATION || required || 2632 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) { 2633 dns_zone_log(zone, level, "%s/NS '%s' has no %s" 2634 "address records (A or AAAA)", 2635 ownerbuf, namebuf, what); 2636 /* 2637 * Log missing address record. 2638 */ 2639 if (result == DNS_R_DELEGATION && zone->checkns != NULL) 2640 (void)(zone->checkns)(zone, name, owner, 2641 &a, &aaaa); 2642 /* XXX950 make fatal for 9.5.0. */ 2643 /* answer = ISC_FALSE; */ 2644 } 2645 } else if (result == DNS_R_CNAME) { 2646 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)", 2647 ownerbuf, namebuf); 2648 /* XXX950 make fatal for 9.5.0. */ 2649 /* answer = ISC_FALSE; */ 2650 } else if (result == DNS_R_DNAME) { 2651 dns_name_format(foundname, altbuf, sizeof altbuf); 2652 dns_zone_log(zone, level, 2653 "%s/NS '%s' is below a DNAME '%s' (illegal)", 2654 ownerbuf, namebuf, altbuf); 2655 /* XXX950 make fatal for 9.5.0. */ 2656 /* answer = ISC_FALSE; */ 2657 } 2658 2659 if (dns_rdataset_isassociated(&a)) 2660 dns_rdataset_disassociate(&a); 2661 if (dns_rdataset_isassociated(&aaaa)) 2662 dns_rdataset_disassociate(&aaaa); 2663 return (answer); 2664 } 2665 2666 static isc_boolean_t 2667 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner, 2668 dns_rdataset_t *rdataset) 2669 { 2670 dns_rdataset_t tmprdataset; 2671 isc_result_t result; 2672 isc_boolean_t answer = ISC_TRUE; 2673 isc_boolean_t format = ISC_TRUE; 2674 int level = ISC_LOG_WARNING; 2675 char ownerbuf[DNS_NAME_FORMATSIZE]; 2676 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 2677 unsigned int count1 = 0; 2678 2679 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL)) 2680 level = ISC_LOG_ERROR; 2681 2682 dns_rdataset_init(&tmprdataset); 2683 for (result = dns_rdataset_first(rdataset); 2684 result == ISC_R_SUCCESS; 2685 result = dns_rdataset_next(rdataset)) { 2686 dns_rdata_t rdata1 = DNS_RDATA_INIT; 2687 unsigned int count2 = 0; 2688 2689 count1++; 2690 dns_rdataset_current(rdataset, &rdata1); 2691 dns_rdataset_clone(rdataset, &tmprdataset); 2692 for (result = dns_rdataset_first(&tmprdataset); 2693 result == ISC_R_SUCCESS; 2694 result = dns_rdataset_next(&tmprdataset)) { 2695 dns_rdata_t rdata2 = DNS_RDATA_INIT; 2696 count2++; 2697 if (count1 >= count2) 2698 continue; 2699 dns_rdataset_current(&tmprdataset, &rdata2); 2700 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) { 2701 if (format) { 2702 dns_name_format(owner, ownerbuf, 2703 sizeof ownerbuf); 2704 dns_rdatatype_format(rdata1.type, 2705 typebuf, 2706 sizeof(typebuf)); 2707 format = ISC_FALSE; 2708 } 2709 dns_zone_log(zone, level, "%s/%s has " 2710 "semantically identical records", 2711 ownerbuf, typebuf); 2712 if (level == ISC_LOG_ERROR) 2713 answer = ISC_FALSE; 2714 break; 2715 } 2716 } 2717 dns_rdataset_disassociate(&tmprdataset); 2718 if (!format) 2719 break; 2720 } 2721 return (answer); 2722 } 2723 2724 static isc_boolean_t 2725 zone_check_dup(dns_zone_t *zone, dns_db_t *db) { 2726 dns_dbiterator_t *dbiterator = NULL; 2727 dns_dbnode_t *node = NULL; 2728 dns_fixedname_t fixed; 2729 dns_name_t *name; 2730 dns_rdataset_t rdataset; 2731 dns_rdatasetiter_t *rdsit = NULL; 2732 isc_boolean_t ok = ISC_TRUE; 2733 isc_result_t result; 2734 2735 dns_fixedname_init(&fixed); 2736 name = dns_fixedname_name(&fixed); 2737 dns_rdataset_init(&rdataset); 2738 2739 result = dns_db_createiterator(db, 0, &dbiterator); 2740 if (result != ISC_R_SUCCESS) 2741 return (ISC_TRUE); 2742 2743 for (result = dns_dbiterator_first(dbiterator); 2744 result == ISC_R_SUCCESS; 2745 result = dns_dbiterator_next(dbiterator)) { 2746 result = dns_dbiterator_current(dbiterator, &node, name); 2747 if (result != ISC_R_SUCCESS) 2748 continue; 2749 2750 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit); 2751 if (result != ISC_R_SUCCESS) 2752 continue; 2753 2754 for (result = dns_rdatasetiter_first(rdsit); 2755 result == ISC_R_SUCCESS; 2756 result = dns_rdatasetiter_next(rdsit)) { 2757 dns_rdatasetiter_current(rdsit, &rdataset); 2758 if (!zone_rrset_check_dup(zone, name, &rdataset)) 2759 ok = ISC_FALSE; 2760 dns_rdataset_disassociate(&rdataset); 2761 } 2762 dns_rdatasetiter_destroy(&rdsit); 2763 dns_db_detachnode(db, &node); 2764 } 2765 2766 if (node != NULL) 2767 dns_db_detachnode(db, &node); 2768 dns_dbiterator_destroy(&dbiterator); 2769 2770 return (ok); 2771 } 2772 2773 static isc_boolean_t 2774 isspf(const dns_rdata_t *rdata) { 2775 char buf[1024]; 2776 const unsigned char *data = rdata->data; 2777 unsigned int rdl = rdata->length, i = 0, tl, len; 2778 2779 while (rdl > 0U) { 2780 len = tl = *data; 2781 ++data; 2782 --rdl; 2783 INSIST(tl <= rdl); 2784 if (len > sizeof(buf) - i - 1) 2785 len = sizeof(buf) - i - 1; 2786 memmove(buf + i, data, len); 2787 i += len; 2788 data += tl; 2789 rdl -= tl; 2790 } 2791 2792 if (i < 6U) 2793 return(ISC_FALSE); 2794 2795 buf[i] = 0; 2796 if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' ')) 2797 return (ISC_TRUE); 2798 return (ISC_FALSE); 2799 } 2800 2801 static isc_boolean_t 2802 integrity_checks(dns_zone_t *zone, dns_db_t *db) { 2803 dns_dbiterator_t *dbiterator = NULL; 2804 dns_dbnode_t *node = NULL; 2805 dns_rdataset_t rdataset; 2806 dns_fixedname_t fixed; 2807 dns_fixedname_t fixedbottom; 2808 dns_rdata_mx_t mx; 2809 dns_rdata_ns_t ns; 2810 dns_rdata_in_srv_t srv; 2811 dns_rdata_t rdata; 2812 dns_name_t *name; 2813 dns_name_t *bottom; 2814 isc_result_t result; 2815 isc_boolean_t ok = ISC_TRUE, have_spf, have_txt; 2816 2817 dns_fixedname_init(&fixed); 2818 name = dns_fixedname_name(&fixed); 2819 dns_fixedname_init(&fixedbottom); 2820 bottom = dns_fixedname_name(&fixedbottom); 2821 dns_rdataset_init(&rdataset); 2822 dns_rdata_init(&rdata); 2823 2824 result = dns_db_createiterator(db, 0, &dbiterator); 2825 if (result != ISC_R_SUCCESS) 2826 return (ISC_TRUE); 2827 2828 result = dns_dbiterator_first(dbiterator); 2829 while (result == ISC_R_SUCCESS) { 2830 result = dns_dbiterator_current(dbiterator, &node, name); 2831 if (result != ISC_R_SUCCESS) 2832 goto cleanup; 2833 2834 /* 2835 * Is this name visible in the zone? 2836 */ 2837 if (!dns_name_issubdomain(name, &zone->origin) || 2838 (dns_name_countlabels(bottom) > 0 && 2839 dns_name_issubdomain(name, bottom))) 2840 goto next; 2841 2842 /* 2843 * Don't check the NS records at the origin. 2844 */ 2845 if (dns_name_equal(name, &zone->origin)) 2846 goto checkmx; 2847 2848 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns, 2849 0, 0, &rdataset, NULL); 2850 if (result != ISC_R_SUCCESS) 2851 goto checkmx; 2852 /* 2853 * Remember bottom of zone. 2854 */ 2855 dns_name_copy(name, bottom, NULL); 2856 2857 result = dns_rdataset_first(&rdataset); 2858 while (result == ISC_R_SUCCESS) { 2859 dns_rdataset_current(&rdataset, &rdata); 2860 result = dns_rdata_tostruct(&rdata, &ns, NULL); 2861 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2862 if (!zone_check_glue(zone, db, &ns.name, name)) 2863 ok = ISC_FALSE; 2864 dns_rdata_reset(&rdata); 2865 result = dns_rdataset_next(&rdataset); 2866 } 2867 dns_rdataset_disassociate(&rdataset); 2868 goto next; 2869 2870 checkmx: 2871 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx, 2872 0, 0, &rdataset, NULL); 2873 if (result != ISC_R_SUCCESS) 2874 goto checksrv; 2875 result = dns_rdataset_first(&rdataset); 2876 while (result == ISC_R_SUCCESS) { 2877 dns_rdataset_current(&rdataset, &rdata); 2878 result = dns_rdata_tostruct(&rdata, &mx, NULL); 2879 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2880 if (!zone_check_mx(zone, db, &mx.mx, name)) 2881 ok = ISC_FALSE; 2882 dns_rdata_reset(&rdata); 2883 result = dns_rdataset_next(&rdataset); 2884 } 2885 dns_rdataset_disassociate(&rdataset); 2886 2887 checksrv: 2888 if (zone->rdclass != dns_rdataclass_in) 2889 goto next; 2890 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv, 2891 0, 0, &rdataset, NULL); 2892 if (result != ISC_R_SUCCESS) 2893 goto checkspf; 2894 result = dns_rdataset_first(&rdataset); 2895 while (result == ISC_R_SUCCESS) { 2896 dns_rdataset_current(&rdataset, &rdata); 2897 result = dns_rdata_tostruct(&rdata, &srv, NULL); 2898 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2899 if (!zone_check_srv(zone, db, &srv.target, name)) 2900 ok = ISC_FALSE; 2901 dns_rdata_reset(&rdata); 2902 result = dns_rdataset_next(&rdataset); 2903 } 2904 dns_rdataset_disassociate(&rdataset); 2905 2906 checkspf: 2907 /* 2908 * Check if there is a type SPF record without an 2909 * SPF-formatted type TXT record also being present. 2910 */ 2911 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF)) 2912 goto next; 2913 if (zone->rdclass != dns_rdataclass_in) 2914 goto next; 2915 have_spf = have_txt = ISC_FALSE; 2916 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf, 2917 0, 0, &rdataset, NULL); 2918 if (result == ISC_R_SUCCESS) { 2919 dns_rdataset_disassociate(&rdataset); 2920 have_spf = ISC_TRUE; 2921 } 2922 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt, 2923 0, 0, &rdataset, NULL); 2924 if (result != ISC_R_SUCCESS) 2925 goto notxt; 2926 result = dns_rdataset_first(&rdataset); 2927 while (result == ISC_R_SUCCESS) { 2928 dns_rdataset_current(&rdataset, &rdata); 2929 have_txt = isspf(&rdata); 2930 dns_rdata_reset(&rdata); 2931 if (have_txt) 2932 break; 2933 result = dns_rdataset_next(&rdataset); 2934 } 2935 dns_rdataset_disassociate(&rdataset); 2936 2937 notxt: 2938 if (have_spf && !have_txt) { 2939 char namebuf[DNS_NAME_FORMATSIZE]; 2940 2941 dns_name_format(name, namebuf, sizeof(namebuf)); 2942 dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found type " 2943 "SPF record but no SPF TXT record found, " 2944 "add matching type TXT record", namebuf); 2945 } 2946 2947 next: 2948 dns_db_detachnode(db, &node); 2949 result = dns_dbiterator_next(dbiterator); 2950 } 2951 2952 cleanup: 2953 if (node != NULL) 2954 dns_db_detachnode(db, &node); 2955 dns_dbiterator_destroy(&dbiterator); 2956 2957 return (ok); 2958 } 2959 2960 /* 2961 * OpenSSL verification of RSA keys with exponent 3 is known to be 2962 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn 2963 * if they are in use. 2964 */ 2965 static void 2966 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) { 2967 dns_dbnode_t *node = NULL; 2968 dns_dbversion_t *version = NULL; 2969 dns_rdata_dnskey_t dnskey; 2970 dns_rdata_t rdata = DNS_RDATA_INIT; 2971 dns_rdataset_t rdataset; 2972 isc_result_t result; 2973 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE; 2974 const char *algorithm; 2975 2976 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 2977 if (result != ISC_R_SUCCESS) 2978 goto cleanup; 2979 2980 dns_db_currentversion(db, &version); 2981 dns_rdataset_init(&rdataset); 2982 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 2983 dns_rdatatype_none, 0, &rdataset, NULL); 2984 if (result != ISC_R_SUCCESS) 2985 goto cleanup; 2986 2987 for (result = dns_rdataset_first(&rdataset); 2988 result == ISC_R_SUCCESS; 2989 result = dns_rdataset_next(&rdataset)) 2990 { 2991 dns_rdataset_current(&rdataset, &rdata); 2992 result = dns_rdata_tostruct(&rdata, &dnskey, NULL); 2993 INSIST(result == ISC_R_SUCCESS); 2994 2995 if ((dnskey.algorithm == DST_ALG_RSASHA1 || 2996 dnskey.algorithm == DST_ALG_RSAMD5) && 2997 dnskey.datalen > 1 && dnskey.data[0] == 1 && 2998 dnskey.data[1] == 3) 2999 { 3000 if (dnskey.algorithm == DST_ALG_RSASHA1) { 3001 logit = !foundrsa; 3002 foundrsa = ISC_TRUE; 3003 algorithm = "RSASHA1"; 3004 } else { 3005 logit = !foundmd5; 3006 foundmd5 = ISC_TRUE; 3007 algorithm = "RSAMD5"; 3008 } 3009 if (logit) 3010 dns_zone_log(zone, ISC_LOG_WARNING, 3011 "weak %s (%u) key found " 3012 "(exponent=3)", algorithm, 3013 dnskey.algorithm); 3014 if (foundrsa && foundmd5) 3015 break; 3016 } 3017 dns_rdata_reset(&rdata); 3018 } 3019 dns_rdataset_disassociate(&rdataset); 3020 3021 cleanup: 3022 if (node != NULL) 3023 dns_db_detachnode(db, &node); 3024 if (version != NULL) 3025 dns_db_closeversion(db, &version, ISC_FALSE); 3026 } 3027 3028 static void 3029 resume_signingwithkey(dns_zone_t *zone) { 3030 dns_dbnode_t *node = NULL; 3031 dns_dbversion_t *version = NULL; 3032 dns_rdata_t rdata = DNS_RDATA_INIT; 3033 dns_rdataset_t rdataset; 3034 isc_result_t result; 3035 dns_db_t *db = NULL; 3036 3037 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3038 if (zone->db != NULL) 3039 dns_db_attach(zone->db, &db); 3040 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3041 if (db == NULL) 3042 goto cleanup; 3043 3044 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 3045 if (result != ISC_R_SUCCESS) 3046 goto cleanup; 3047 3048 dns_db_currentversion(db, &version); 3049 dns_rdataset_init(&rdataset); 3050 result = dns_db_findrdataset(db, node, version, 3051 zone->privatetype, 3052 dns_rdatatype_none, 0, 3053 &rdataset, NULL); 3054 if (result != ISC_R_SUCCESS) { 3055 INSIST(!dns_rdataset_isassociated(&rdataset)); 3056 goto cleanup; 3057 } 3058 3059 for (result = dns_rdataset_first(&rdataset); 3060 result == ISC_R_SUCCESS; 3061 result = dns_rdataset_next(&rdataset)) 3062 { 3063 dns_rdataset_current(&rdataset, &rdata); 3064 if (rdata.length != 5 || 3065 rdata.data[0] == 0 || rdata.data[4] != 0) { 3066 dns_rdata_reset(&rdata); 3067 continue; 3068 } 3069 3070 result = zone_signwithkey(zone, rdata.data[0], 3071 (rdata.data[1] << 8) | rdata.data[2], 3072 ISC_TF(rdata.data[3])); 3073 if (result != ISC_R_SUCCESS) { 3074 dns_zone_log(zone, ISC_LOG_ERROR, 3075 "zone_signwithkey failed: %s", 3076 dns_result_totext(result)); 3077 } 3078 dns_rdata_reset(&rdata); 3079 } 3080 dns_rdataset_disassociate(&rdataset); 3081 3082 cleanup: 3083 if (db != NULL) { 3084 if (node != NULL) 3085 dns_db_detachnode(db, &node); 3086 if (version != NULL) 3087 dns_db_closeversion(db, &version, ISC_FALSE); 3088 dns_db_detach(&db); 3089 } 3090 } 3091 3092 static isc_result_t 3093 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 3094 dns_nsec3chain_t *nsec3chain, *current; 3095 dns_dbversion_t *version = NULL; 3096 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; 3097 isc_result_t result; 3098 isc_time_t now; 3099 unsigned int options = 0; 3100 char saltbuf[255*2+1]; 3101 char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")]; 3102 dns_db_t *db = NULL; 3103 int i; 3104 3105 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3106 if (zone->db != NULL) 3107 dns_db_attach(zone->db, &db); 3108 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3109 3110 if (db == NULL) { 3111 result = ISC_R_SUCCESS; 3112 goto cleanup; 3113 } 3114 3115 dns_db_currentversion(db, &version); 3116 result = dns_nsec_nseconly(db, version, &nseconly); 3117 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 3118 dns_db_closeversion(db, &version, ISC_FALSE); 3119 if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) { 3120 result = ISC_R_SUCCESS; 3121 goto cleanup; 3122 } 3123 3124 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain); 3125 if (nsec3chain == NULL) { 3126 result = ISC_R_NOMEMORY; 3127 goto cleanup; 3128 } 3129 3130 nsec3chain->magic = 0; 3131 nsec3chain->done = ISC_FALSE; 3132 nsec3chain->db = NULL; 3133 nsec3chain->dbiterator = NULL; 3134 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass; 3135 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype; 3136 nsec3chain->nsec3param.hash = nsec3param->hash; 3137 nsec3chain->nsec3param.iterations = nsec3param->iterations; 3138 nsec3chain->nsec3param.flags = nsec3param->flags; 3139 nsec3chain->nsec3param.salt_length = nsec3param->salt_length; 3140 memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length); 3141 nsec3chain->nsec3param.salt = nsec3chain->salt; 3142 nsec3chain->seen_nsec = ISC_FALSE; 3143 nsec3chain->delete_nsec = ISC_FALSE; 3144 nsec3chain->save_delete_nsec = ISC_FALSE; 3145 3146 if (nsec3param->flags == 0) 3147 strlcpy(flags, "NONE", sizeof(flags)); 3148 else { 3149 flags[0] = '\0'; 3150 if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) 3151 strlcat(flags, "REMOVE", sizeof(flags)); 3152 if (nsec3param->flags & DNS_NSEC3FLAG_INITIAL) { 3153 if (flags[0] == '\0') 3154 strlcpy(flags, "INITIAL", sizeof(flags)); 3155 else 3156 strlcat(flags, "|INITIAL", sizeof(flags)); 3157 } 3158 if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) { 3159 if (flags[0] == '\0') 3160 strlcpy(flags, "CREATE", sizeof(flags)); 3161 else 3162 strlcat(flags, "|CREATE", sizeof(flags)); 3163 } 3164 if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) { 3165 if (flags[0] == '\0') 3166 strlcpy(flags, "NONSEC", sizeof(flags)); 3167 else 3168 strlcat(flags, "|NONSEC", sizeof(flags)); 3169 } 3170 if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) { 3171 if (flags[0] == '\0') 3172 strlcpy(flags, "OPTOUT", sizeof(flags)); 3173 else 3174 strlcat(flags, "|OPTOUT", sizeof(flags)); 3175 } 3176 } 3177 if (nsec3param->salt_length == 0) 3178 strlcpy(saltbuf, "-", sizeof(saltbuf)); 3179 else 3180 for (i = 0; i < nsec3param->salt_length; i++) 3181 sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]); 3182 dns_zone_log(zone, ISC_LOG_INFO, 3183 "zone_addnsec3chain(%u,%s,%u,%s)", 3184 nsec3param->hash, flags, nsec3param->iterations, 3185 saltbuf); 3186 3187 for (current = ISC_LIST_HEAD(zone->nsec3chain); 3188 current != NULL; 3189 current = ISC_LIST_NEXT(current, link)) { 3190 if (current->db == db && 3191 current->nsec3param.hash == nsec3param->hash && 3192 current->nsec3param.iterations == nsec3param->iterations && 3193 current->nsec3param.salt_length == nsec3param->salt_length 3194 && !memcmp(current->nsec3param.salt, nsec3param->salt, 3195 nsec3param->salt_length)) 3196 current->done = ISC_TRUE; 3197 } 3198 3199 dns_db_attach(db, &nsec3chain->db); 3200 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) 3201 options = DNS_DB_NONSEC3; 3202 result = dns_db_createiterator(nsec3chain->db, options, 3203 &nsec3chain->dbiterator); 3204 if (result == ISC_R_SUCCESS) 3205 dns_dbiterator_first(nsec3chain->dbiterator); 3206 if (result == ISC_R_SUCCESS) { 3207 dns_dbiterator_pause(nsec3chain->dbiterator); 3208 ISC_LIST_INITANDAPPEND(zone->nsec3chain, 3209 nsec3chain, link); 3210 nsec3chain = NULL; 3211 if (isc_time_isepoch(&zone->nsec3chaintime)) { 3212 TIME_NOW(&now); 3213 zone->nsec3chaintime = now; 3214 if (zone->task != NULL) 3215 zone_settimer(zone, &now); 3216 } 3217 } 3218 3219 if (nsec3chain != NULL) { 3220 if (nsec3chain->db != NULL) 3221 dns_db_detach(&nsec3chain->db); 3222 if (nsec3chain->dbiterator != NULL) 3223 dns_dbiterator_destroy(&nsec3chain->dbiterator); 3224 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 3225 } 3226 3227 cleanup: 3228 if (db != NULL) 3229 dns_db_detach(&db); 3230 return (result); 3231 } 3232 3233 static void 3234 resume_addnsec3chain(dns_zone_t *zone) { 3235 dns_dbnode_t *node = NULL; 3236 dns_dbversion_t *version = NULL; 3237 dns_rdataset_t rdataset; 3238 isc_result_t result; 3239 dns_rdata_nsec3param_t nsec3param; 3240 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; 3241 dns_db_t *db = NULL; 3242 3243 if (zone->privatetype == 0) 3244 return; 3245 3246 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3247 if (zone->db != NULL) 3248 dns_db_attach(zone->db, &db); 3249 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3250 if (db == NULL) 3251 goto cleanup; 3252 3253 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 3254 if (result != ISC_R_SUCCESS) 3255 goto cleanup; 3256 3257 dns_db_currentversion(db, &version); 3258 3259 result = dns_nsec_nseconly(db, version, &nseconly); 3260 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 3261 3262 dns_rdataset_init(&rdataset); 3263 result = dns_db_findrdataset(db, node, version, 3264 zone->privatetype, dns_rdatatype_none, 3265 0, &rdataset, NULL); 3266 if (result != ISC_R_SUCCESS) { 3267 INSIST(!dns_rdataset_isassociated(&rdataset)); 3268 goto cleanup; 3269 } 3270 3271 for (result = dns_rdataset_first(&rdataset); 3272 result == ISC_R_SUCCESS; 3273 result = dns_rdataset_next(&rdataset)) 3274 { 3275 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 3276 dns_rdata_t rdata = DNS_RDATA_INIT; 3277 dns_rdata_t private = DNS_RDATA_INIT; 3278 3279 dns_rdataset_current(&rdataset, &private); 3280 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 3281 sizeof(buf))) 3282 continue; 3283 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 3284 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3285 if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) || 3286 ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok)) 3287 { 3288 result = zone_addnsec3chain(zone, &nsec3param); 3289 if (result != ISC_R_SUCCESS) { 3290 dns_zone_log(zone, ISC_LOG_ERROR, 3291 "zone_addnsec3chain failed: %s", 3292 dns_result_totext(result)); 3293 } 3294 } 3295 } 3296 dns_rdataset_disassociate(&rdataset); 3297 cleanup: 3298 if (db != NULL) { 3299 if (node != NULL) 3300 dns_db_detachnode(db, &node); 3301 if (version != NULL) 3302 dns_db_closeversion(db, &version, ISC_FALSE); 3303 dns_db_detach(&db); 3304 } 3305 } 3306 3307 static void 3308 set_resigntime(dns_zone_t *zone) { 3309 dns_rdataset_t rdataset; 3310 dns_fixedname_t fixed; 3311 unsigned int resign; 3312 isc_result_t result; 3313 isc_uint32_t nanosecs; 3314 dns_db_t *db = NULL; 3315 3316 /* We only re-sign zones that can be dynamically updated */ 3317 if (zone->update_disabled) 3318 return; 3319 3320 if (!inline_secure(zone) && (zone->type != dns_zone_master || 3321 (zone->ssutable == NULL && 3322 (zone->update_acl == NULL || dns_acl_isnone(zone->update_acl))))) 3323 return; 3324 3325 dns_rdataset_init(&rdataset); 3326 dns_fixedname_init(&fixed); 3327 3328 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 3329 if (zone->db != NULL) 3330 dns_db_attach(zone->db, &db); 3331 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 3332 if (db == NULL) { 3333 isc_time_settoepoch(&zone->resigntime); 3334 return; 3335 } 3336 3337 result = dns_db_getsigningtime(db, &rdataset, 3338 dns_fixedname_name(&fixed)); 3339 if (result != ISC_R_SUCCESS) { 3340 isc_time_settoepoch(&zone->resigntime); 3341 goto cleanup; 3342 } 3343 3344 resign = rdataset.resign - zone->sigresigninginterval; 3345 dns_rdataset_disassociate(&rdataset); 3346 isc_random_get(&nanosecs); 3347 nanosecs %= 1000000000; 3348 isc_time_set(&zone->resigntime, resign, nanosecs); 3349 cleanup: 3350 dns_db_detach(&db); 3351 return; 3352 } 3353 3354 static isc_result_t 3355 check_nsec3param(dns_zone_t *zone, dns_db_t *db) { 3356 dns_dbnode_t *node = NULL; 3357 dns_rdataset_t rdataset; 3358 dns_dbversion_t *version = NULL; 3359 dns_rdata_nsec3param_t nsec3param; 3360 isc_boolean_t ok = ISC_FALSE; 3361 isc_result_t result; 3362 dns_rdata_t rdata = DNS_RDATA_INIT; 3363 isc_boolean_t dynamic = (zone->type == dns_zone_master) ? 3364 dns_zone_isdynamic(zone, ISC_FALSE) : ISC_FALSE; 3365 3366 dns_rdataset_init(&rdataset); 3367 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 3368 if (result != ISC_R_SUCCESS) { 3369 dns_zone_log(zone, ISC_LOG_ERROR, 3370 "nsec3param lookup failure: %s", 3371 dns_result_totext(result)); 3372 return (result); 3373 } 3374 dns_db_currentversion(db, &version); 3375 3376 result = dns_db_findrdataset(db, node, version, 3377 dns_rdatatype_nsec3param, 3378 dns_rdatatype_none, 0, &rdataset, NULL); 3379 if (result == ISC_R_NOTFOUND) { 3380 INSIST(!dns_rdataset_isassociated(&rdataset)); 3381 result = ISC_R_SUCCESS; 3382 goto cleanup; 3383 } 3384 if (result != ISC_R_SUCCESS) { 3385 INSIST(!dns_rdataset_isassociated(&rdataset)); 3386 dns_zone_log(zone, ISC_LOG_ERROR, 3387 "nsec3param lookup failure: %s", 3388 dns_result_totext(result)); 3389 goto cleanup; 3390 } 3391 3392 /* 3393 * For dynamic zones we must support every algorithm so we can 3394 * regenerate all the NSEC3 chains. 3395 * For non-dynamic zones we only need to find a supported algorithm. 3396 */ 3397 for (result = dns_rdataset_first(&rdataset); 3398 result == ISC_R_SUCCESS; 3399 result = dns_rdataset_next(&rdataset)) 3400 { 3401 dns_rdataset_current(&rdataset, &rdata); 3402 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 3403 dns_rdata_reset(&rdata); 3404 INSIST(result == ISC_R_SUCCESS); 3405 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) && 3406 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic) 3407 { 3408 dns_zone_log(zone, ISC_LOG_WARNING, 3409 "nsec3 test \"unknown\" hash algorithm found: %u", 3410 nsec3param.hash); 3411 ok = ISC_TRUE; 3412 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) { 3413 if (dynamic) { 3414 dns_zone_log(zone, ISC_LOG_ERROR, 3415 "unsupported nsec3 hash algorithm" 3416 " in dynamic zone: %u", 3417 nsec3param.hash); 3418 result = DNS_R_BADZONE; 3419 /* Stop second error message. */ 3420 ok = ISC_TRUE; 3421 break; 3422 } else 3423 dns_zone_log(zone, ISC_LOG_WARNING, 3424 "unsupported nsec3 hash algorithm: %u", 3425 nsec3param.hash); 3426 } else 3427 ok = ISC_TRUE; 3428 } 3429 if (result == ISC_R_NOMORE) 3430 result = ISC_R_SUCCESS; 3431 3432 if (!ok) { 3433 result = DNS_R_BADZONE; 3434 dns_zone_log(zone, ISC_LOG_ERROR, 3435 "no supported nsec3 hash algorithm"); 3436 } 3437 3438 cleanup: 3439 if (dns_rdataset_isassociated(&rdataset)) 3440 dns_rdataset_disassociate(&rdataset); 3441 dns_db_closeversion(db, &version, ISC_FALSE); 3442 dns_db_detachnode(db, &node); 3443 return (result); 3444 } 3445 3446 /* 3447 * Set the timer for refreshing the key zone to the soonest future time 3448 * of the set (current timer, keydata->refresh, keydata->addhd, 3449 * keydata->removehd). 3450 */ 3451 static void 3452 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key, 3453 isc_stdtime_t now, isc_boolean_t force) 3454 { 3455 const char me[] = "set_refreshkeytimer"; 3456 isc_stdtime_t then; 3457 isc_time_t timenow, timethen; 3458 char timebuf[80]; 3459 3460 ENTER; 3461 then = key->refresh; 3462 if (force) 3463 then = now; 3464 if (key->addhd > now && key->addhd < then) 3465 then = key->addhd; 3466 if (key->removehd > now && key->removehd < then) 3467 then = key->removehd; 3468 3469 TIME_NOW(&timenow); 3470 if (then > now) 3471 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 3472 else 3473 timethen = timenow; 3474 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 || 3475 isc_time_compare(&timethen, &zone->refreshkeytime) < 0) 3476 zone->refreshkeytime = timethen; 3477 3478 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 3479 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf); 3480 zone_settimer(zone, &timenow); 3481 } 3482 3483 /* 3484 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone. 3485 * If the key zone is changed, set '*changed' to ISC_TRUE. 3486 */ 3487 static isc_result_t 3488 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 3489 dns_diff_t *diff, dns_keytable_t *keytable, 3490 dns_keynode_t **keynodep, isc_boolean_t *changed) 3491 { 3492 const char me[] = "create_keydata"; 3493 isc_result_t result = ISC_R_SUCCESS; 3494 isc_buffer_t keyb, dstb; 3495 unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE]; 3496 dns_rdata_keydata_t keydata; 3497 dns_rdata_dnskey_t dnskey; 3498 dns_rdata_t rdata = DNS_RDATA_INIT; 3499 dns_keynode_t *keynode; 3500 isc_stdtime_t now; 3501 isc_region_t r; 3502 dst_key_t *key; 3503 3504 REQUIRE(keynodep != NULL); 3505 keynode = *keynodep; 3506 3507 ENTER; 3508 isc_stdtime_get(&now); 3509 3510 /* Loop in case there's more than one key. */ 3511 while (result == ISC_R_SUCCESS) { 3512 dns_keynode_t *nextnode = NULL; 3513 3514 key = dns_keynode_key(keynode); 3515 if (key == NULL) 3516 goto skip; 3517 3518 isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf)); 3519 CHECK(dst_key_todns(key, &dstb)); 3520 3521 /* Convert DST key to DNSKEY. */ 3522 dns_rdata_reset(&rdata); 3523 isc_buffer_usedregion(&dstb, &r); 3524 dns_rdata_fromregion(&rdata, dst_key_class(key), 3525 dns_rdatatype_dnskey, &r); 3526 3527 /* DSTKEY to KEYDATA. */ 3528 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL)); 3529 CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0, 3530 NULL)); 3531 3532 /* KEYDATA to rdata. */ 3533 dns_rdata_reset(&rdata); 3534 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 3535 CHECK(dns_rdata_fromstruct(&rdata, 3536 zone->rdclass, dns_rdatatype_keydata, 3537 &keydata, &keyb)); 3538 3539 /* Add rdata to zone. */ 3540 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, 3541 dst_key_name(key), 0, &rdata)); 3542 *changed = ISC_TRUE; 3543 3544 /* Refresh new keys from the zone apex as soon as possible. */ 3545 set_refreshkeytimer(zone, &keydata, now, ISC_TRUE); 3546 3547 skip: 3548 result = dns_keytable_nextkeynode(keytable, keynode, &nextnode); 3549 if (result != ISC_R_NOTFOUND) { 3550 dns_keytable_detachkeynode(keytable, &keynode); 3551 keynode = nextnode; 3552 } 3553 } 3554 3555 if (keynode != NULL) 3556 dns_keytable_detachkeynode(keytable, &keynode); 3557 *keynodep = NULL; 3558 3559 return (ISC_R_SUCCESS); 3560 3561 failure: 3562 return (result); 3563 } 3564 3565 /* 3566 * Remove from the key zone all the KEYDATA records found in rdataset. 3567 */ 3568 static isc_result_t 3569 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 3570 dns_name_t *name, dns_rdataset_t *rdataset) 3571 { 3572 dns_rdata_t rdata = DNS_RDATA_INIT; 3573 isc_result_t result, uresult; 3574 3575 for (result = dns_rdataset_first(rdataset); 3576 result == ISC_R_SUCCESS; 3577 result = dns_rdataset_next(rdataset)) { 3578 dns_rdata_reset(&rdata); 3579 dns_rdataset_current(rdataset, &rdata); 3580 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, 3581 name, 0, &rdata); 3582 if (uresult != ISC_R_SUCCESS) 3583 return (uresult); 3584 } 3585 if (result == ISC_R_NOMORE) 3586 result = ISC_R_SUCCESS; 3587 return (result); 3588 } 3589 3590 /* 3591 * Compute the DNSSEC key ID for a DNSKEY record. 3592 */ 3593 static isc_result_t 3594 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx, 3595 dns_keytag_t *tag) 3596 { 3597 isc_result_t result; 3598 dns_rdata_t rdata = DNS_RDATA_INIT; 3599 unsigned char data[4096]; 3600 isc_buffer_t buffer; 3601 dst_key_t *dstkey = NULL; 3602 3603 isc_buffer_init(&buffer, data, sizeof(data)); 3604 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 3605 dns_rdatatype_dnskey, dnskey, &buffer); 3606 3607 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey); 3608 if (result == ISC_R_SUCCESS) 3609 *tag = dst_key_id(dstkey); 3610 dst_key_free(&dstkey); 3611 3612 return (result); 3613 } 3614 3615 /* 3616 * Add key to the security roots. 3617 */ 3618 static void 3619 trust_key(dns_zone_t *zone, dns_name_t *keyname, 3620 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) { 3621 isc_result_t result; 3622 dns_rdata_t rdata = DNS_RDATA_INIT; 3623 unsigned char data[4096]; 3624 isc_buffer_t buffer; 3625 dns_keytable_t *sr = NULL; 3626 dst_key_t *dstkey = NULL; 3627 3628 /* Convert dnskey to DST key. */ 3629 isc_buffer_init(&buffer, data, sizeof(data)); 3630 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 3631 dns_rdatatype_dnskey, dnskey, &buffer); 3632 3633 result = dns_view_getsecroots(zone->view, &sr); 3634 if (result != ISC_R_SUCCESS) 3635 goto failure; 3636 3637 CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey)); 3638 CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey)); 3639 dns_keytable_detach(&sr); 3640 3641 failure: 3642 if (dstkey != NULL) 3643 dst_key_free(&dstkey); 3644 if (sr != NULL) 3645 dns_keytable_detach(&sr); 3646 return; 3647 } 3648 3649 /* 3650 * Add a null key to the security roots for so that all queries 3651 * to the zone will fail. 3652 */ 3653 static void 3654 fail_secure(dns_zone_t *zone, dns_name_t *keyname) { 3655 isc_result_t result; 3656 dns_keytable_t *sr = NULL; 3657 3658 result = dns_view_getsecroots(zone->view, &sr); 3659 if (result == ISC_R_SUCCESS) { 3660 dns_keytable_marksecure(sr, keyname); 3661 dns_keytable_detach(&sr); 3662 } 3663 } 3664 3665 /* 3666 * Scan a set of KEYDATA records from the key zone. The ones that are 3667 * valid (i.e., the add holddown timer has expired) become trusted keys. 3668 */ 3669 static void 3670 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) { 3671 isc_result_t result; 3672 dns_rdata_t rdata = DNS_RDATA_INIT; 3673 dns_rdata_keydata_t keydata; 3674 dns_rdata_dnskey_t dnskey; 3675 isc_mem_t *mctx = zone->mctx; 3676 int trusted = 0, revoked = 0, pending = 0; 3677 isc_stdtime_t now; 3678 dns_keytable_t *sr = NULL; 3679 3680 isc_stdtime_get(&now); 3681 3682 result = dns_view_getsecroots(zone->view, &sr); 3683 if (result == ISC_R_SUCCESS) { 3684 dns_keytable_delete(sr, name); 3685 dns_keytable_detach(&sr); 3686 } 3687 3688 /* Now insert all the accepted trust anchors from this keydata set. */ 3689 for (result = dns_rdataset_first(rdataset); 3690 result == ISC_R_SUCCESS; 3691 result = dns_rdataset_next(rdataset)) { 3692 dns_rdata_reset(&rdata); 3693 dns_rdataset_current(rdataset, &rdata); 3694 3695 /* Convert rdata to keydata. */ 3696 result = dns_rdata_tostruct(&rdata, &keydata, NULL); 3697 if (result == ISC_R_UNEXPECTEDEND) 3698 continue; 3699 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3700 3701 /* Set the key refresh timer to force a fast refresh. */ 3702 set_refreshkeytimer(zone, &keydata, now, ISC_TRUE); 3703 3704 /* If the removal timer is nonzero, this key was revoked. */ 3705 if (keydata.removehd != 0) { 3706 revoked++; 3707 continue; 3708 } 3709 3710 /* 3711 * If the add timer is still pending, this key is not 3712 * trusted yet. 3713 */ 3714 if (now < keydata.addhd) { 3715 pending++; 3716 continue; 3717 } 3718 3719 /* Convert keydata to dnskey. */ 3720 dns_keydata_todnskey(&keydata, &dnskey, NULL); 3721 3722 /* Add to keytables. */ 3723 trusted++; 3724 trust_key(zone, name, &dnskey, mctx); 3725 } 3726 3727 if (trusted == 0 && pending != 0) { 3728 char namebuf[DNS_NAME_FORMATSIZE]; 3729 dns_name_format(name, namebuf, sizeof namebuf); 3730 dns_zone_log(zone, ISC_LOG_ERROR, 3731 "No valid trust anchors for '%s'!", namebuf); 3732 dns_zone_log(zone, ISC_LOG_ERROR, 3733 "%d key(s) revoked, %d still pending", 3734 revoked, pending); 3735 dns_zone_log(zone, ISC_LOG_ERROR, 3736 "All queries to '%s' will fail", namebuf); 3737 fail_secure(zone, name); 3738 } 3739 } 3740 3741 static isc_result_t 3742 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, 3743 dns_diff_t *diff) 3744 { 3745 dns_diff_t temp_diff; 3746 isc_result_t result; 3747 3748 /* 3749 * Create a singleton diff. 3750 */ 3751 dns_diff_init(diff->mctx, &temp_diff); 3752 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); 3753 3754 /* 3755 * Apply it to the database. 3756 */ 3757 result = dns_diff_apply(&temp_diff, db, ver); 3758 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); 3759 if (result != ISC_R_SUCCESS) { 3760 dns_difftuple_free(tuple); 3761 return (result); 3762 } 3763 3764 /* 3765 * Merge it into the current pending journal entry. 3766 */ 3767 dns_diff_appendminimal(diff, tuple); 3768 3769 /* 3770 * Do not clear temp_diff. 3771 */ 3772 return (ISC_R_SUCCESS); 3773 } 3774 3775 static isc_result_t 3776 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 3777 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, 3778 dns_rdata_t *rdata) 3779 { 3780 dns_difftuple_t *tuple = NULL; 3781 isc_result_t result; 3782 result = dns_difftuple_create(diff->mctx, op, 3783 name, ttl, rdata, &tuple); 3784 if (result != ISC_R_SUCCESS) 3785 return (result); 3786 return (do_one_tuple(&tuple, db, ver, diff)); 3787 } 3788 3789 static isc_result_t 3790 update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 3791 isc_mem_t *mctx, dns_updatemethod_t method) { 3792 dns_difftuple_t *deltuple = NULL; 3793 dns_difftuple_t *addtuple = NULL; 3794 isc_uint32_t serial; 3795 isc_result_t result; 3796 3797 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple)); 3798 CHECK(dns_difftuple_copy(deltuple, &addtuple)); 3799 addtuple->op = DNS_DIFFOP_ADD; 3800 3801 serial = dns_soa_getserial(&addtuple->rdata); 3802 serial = dns_update_soaserial(serial, method); 3803 dns_soa_setserial(serial, &addtuple->rdata); 3804 CHECK(do_one_tuple(&deltuple, db, ver, diff)); 3805 CHECK(do_one_tuple(&addtuple, db, ver, diff)); 3806 result = ISC_R_SUCCESS; 3807 3808 failure: 3809 if (addtuple != NULL) 3810 dns_difftuple_free(&addtuple); 3811 if (deltuple != NULL) 3812 dns_difftuple_free(&deltuple); 3813 return (result); 3814 } 3815 3816 /* 3817 * Write all transactions in 'diff' to the zone journal file. 3818 */ 3819 static isc_result_t 3820 zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial, 3821 const char *caller) 3822 { 3823 const char me[] = "zone_journal"; 3824 const char *journalfile; 3825 isc_result_t result = ISC_R_SUCCESS; 3826 dns_journal_t *journal = NULL; 3827 unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE; 3828 3829 ENTER; 3830 journalfile = dns_zone_getjournal(zone); 3831 if (journalfile != NULL) { 3832 result = dns_journal_open(zone->mctx, journalfile, mode, 3833 &journal); 3834 if (result != ISC_R_SUCCESS) { 3835 dns_zone_log(zone, ISC_LOG_ERROR, 3836 "%s:dns_journal_open -> %s", 3837 caller, dns_result_totext(result)); 3838 return (result); 3839 } 3840 3841 if (sourceserial != NULL) 3842 dns_journal_set_sourceserial(journal, *sourceserial); 3843 3844 result = dns_journal_write_transaction(journal, diff); 3845 if (result != ISC_R_SUCCESS) { 3846 dns_zone_log(zone, ISC_LOG_ERROR, 3847 "%s:dns_journal_write_transaction -> %s", 3848 caller, dns_result_totext(result)); 3849 } 3850 dns_journal_destroy(&journal); 3851 } 3852 3853 return (result); 3854 } 3855 3856 /* 3857 * Create an SOA record for a newly-created zone 3858 */ 3859 static isc_result_t 3860 add_soa(dns_zone_t *zone, dns_db_t *db) { 3861 isc_result_t result; 3862 dns_rdata_t rdata = DNS_RDATA_INIT; 3863 unsigned char buf[DNS_SOA_BUFFERSIZE]; 3864 dns_dbversion_t *ver = NULL; 3865 dns_diff_t diff; 3866 3867 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA"); 3868 3869 dns_diff_init(zone->mctx, &diff); 3870 result = dns_db_newversion(db, &ver); 3871 if (result != ISC_R_SUCCESS) { 3872 dns_zone_log(zone, ISC_LOG_ERROR, 3873 "add_soa:dns_db_newversion -> %s", 3874 dns_result_totext(result)); 3875 goto failure; 3876 } 3877 3878 /* Build SOA record */ 3879 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass, 3880 0, 0, 0, 0, 0, buf, &rdata); 3881 if (result != ISC_R_SUCCESS) { 3882 dns_zone_log(zone, ISC_LOG_ERROR, 3883 "add_soa:dns_soa_buildrdata -> %s", 3884 dns_result_totext(result)); 3885 goto failure; 3886 } 3887 3888 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD, 3889 &zone->origin, 0, &rdata); 3890 3891 failure: 3892 dns_diff_clear(&diff); 3893 if (ver != NULL) 3894 dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS)); 3895 3896 INSIST(ver == NULL); 3897 3898 return (result); 3899 } 3900 3901 /* 3902 * Synchronize the set of initializing keys found in managed-keys {} 3903 * statements with the set of trust anchors found in the managed-keys.bind 3904 * zone. If a domain is no longer named in managed-keys, delete all keys 3905 * from that domain from the key zone. If a domain is mentioned in in 3906 * managed-keys but there are no references to it in the key zone, load 3907 * the key zone with the initializing key(s) for that domain. 3908 */ 3909 static isc_result_t 3910 sync_keyzone(dns_zone_t *zone, dns_db_t *db) { 3911 isc_result_t result = ISC_R_SUCCESS; 3912 isc_boolean_t changed = ISC_FALSE; 3913 isc_boolean_t commit = ISC_FALSE; 3914 dns_rbtnodechain_t chain; 3915 dns_fixedname_t fn; 3916 dns_name_t foundname, *origin; 3917 dns_keynode_t *keynode = NULL; 3918 dns_view_t *view = zone->view; 3919 dns_keytable_t *sr = NULL; 3920 dns_dbversion_t *ver = NULL; 3921 dns_diff_t diff; 3922 dns_rriterator_t rrit; 3923 3924 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys"); 3925 3926 dns_name_init(&foundname, NULL); 3927 dns_fixedname_init(&fn); 3928 origin = dns_fixedname_name(&fn); 3929 3930 dns_diff_init(zone->mctx, &diff); 3931 3932 CHECK(dns_view_getsecroots(view, &sr)); 3933 3934 result = dns_db_newversion(db, &ver); 3935 if (result != ISC_R_SUCCESS) { 3936 dns_zone_log(zone, ISC_LOG_ERROR, 3937 "sync_keyzone:dns_db_newversion -> %s", 3938 dns_result_totext(result)); 3939 goto failure; 3940 } 3941 3942 /* 3943 * Walk the zone DB. If we find any keys whose names are no longer 3944 * in managed-keys (or *are* in trusted-keys, meaning they are 3945 * permanent and not RFC5011-maintained), delete them from the 3946 * zone. Otherwise call load_secroots(), which loads keys into 3947 * secroots as appropriate. 3948 */ 3949 dns_rriterator_init(&rrit, db, ver, 0); 3950 for (result = dns_rriterator_first(&rrit); 3951 result == ISC_R_SUCCESS; 3952 result = dns_rriterator_nextrrset(&rrit)) { 3953 dns_rdataset_t *rdataset = NULL; 3954 dns_name_t *rrname = NULL; 3955 isc_uint32_t ttl; 3956 3957 dns_rriterator_current(&rrit, &rrname, &ttl, 3958 &rdataset, NULL); 3959 if (!dns_rdataset_isassociated(rdataset)) { 3960 dns_rriterator_destroy(&rrit); 3961 goto failure; 3962 } 3963 3964 if (rdataset->type != dns_rdatatype_keydata) 3965 continue; 3966 3967 result = dns_keytable_find(sr, rrname, &keynode); 3968 if ((result != ISC_R_SUCCESS && 3969 result != DNS_R_PARTIALMATCH) || 3970 dns_keynode_managed(keynode) == ISC_FALSE) 3971 { 3972 CHECK(delete_keydata(db, ver, &diff, 3973 rrname, rdataset)); 3974 changed = ISC_TRUE; 3975 } else { 3976 load_secroots(zone, rrname, rdataset); 3977 } 3978 3979 if (keynode != NULL) 3980 dns_keytable_detachkeynode(sr, &keynode); 3981 } 3982 dns_rriterator_destroy(&rrit); 3983 3984 /* 3985 * Now walk secroots to find any managed keys that aren't 3986 * in the zone. If we find any, we add them to the zone. 3987 */ 3988 RWLOCK(&sr->rwlock, isc_rwlocktype_write); 3989 dns_rbtnodechain_init(&chain, zone->mctx); 3990 result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin); 3991 if (result == ISC_R_NOTFOUND) 3992 result = ISC_R_NOMORE; 3993 while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { 3994 dns_rbtnode_t *rbtnode = NULL; 3995 3996 dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode); 3997 if (rbtnode->data == NULL) 3998 goto skip; 3999 4000 dns_keytable_attachkeynode(sr, rbtnode->data, &keynode); 4001 if (dns_keynode_managed(keynode)) { 4002 dns_fixedname_t fname; 4003 dns_name_t *keyname; 4004 dst_key_t *key; 4005 4006 key = dns_keynode_key(keynode); 4007 dns_fixedname_init(&fname); 4008 4009 if (key == NULL) /* fail_secure() was called. */ 4010 goto skip; 4011 4012 keyname = dst_key_name(key); 4013 result = dns_db_find(db, keyname, ver, 4014 dns_rdatatype_keydata, 4015 DNS_DBFIND_NOWILD, 0, NULL, 4016 dns_fixedname_name(&fname), 4017 NULL, NULL); 4018 if (result != ISC_R_SUCCESS) 4019 result = create_keydata(zone, db, ver, &diff, 4020 sr, &keynode, &changed); 4021 if (result != ISC_R_SUCCESS) 4022 break; 4023 } 4024 skip: 4025 result = dns_rbtnodechain_next(&chain, &foundname, origin); 4026 if (keynode != NULL) 4027 dns_keytable_detachkeynode(sr, &keynode); 4028 } 4029 RWUNLOCK(&sr->rwlock, isc_rwlocktype_write); 4030 4031 if (result == ISC_R_NOMORE) 4032 result = ISC_R_SUCCESS; 4033 4034 if (changed) { 4035 /* Write changes to journal file. */ 4036 CHECK(update_soa_serial(db, ver, &diff, zone->mctx, 4037 zone->updatemethod)); 4038 CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone")); 4039 4040 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 4041 zone_needdump(zone, 30); 4042 commit = ISC_TRUE; 4043 } 4044 4045 failure: 4046 if (result != ISC_R_SUCCESS && 4047 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 4048 dns_zone_log(zone, ISC_LOG_ERROR, 4049 "unable to synchronize managed keys: %s", 4050 dns_result_totext(result)); 4051 isc_time_settoepoch(&zone->refreshkeytime); 4052 } 4053 if (keynode != NULL) 4054 dns_keytable_detachkeynode(sr, &keynode); 4055 if (sr != NULL) 4056 dns_keytable_detach(&sr); 4057 if (ver != NULL) 4058 dns_db_closeversion(db, &ver, commit); 4059 dns_diff_clear(&diff); 4060 4061 INSIST(ver == NULL); 4062 4063 return (result); 4064 } 4065 4066 isc_result_t 4067 dns_zone_synckeyzone(dns_zone_t *zone) { 4068 isc_result_t result; 4069 dns_db_t *db = NULL; 4070 4071 if (zone->type != dns_zone_key) 4072 return (DNS_R_BADZONE); 4073 4074 CHECK(dns_zone_getdb(zone, &db)); 4075 4076 LOCK_ZONE(zone); 4077 result = sync_keyzone(zone, db); 4078 UNLOCK_ZONE(zone); 4079 4080 failure: 4081 if (db != NULL) 4082 dns_db_detach(&db); 4083 return (result); 4084 } 4085 4086 static void 4087 maybe_send_secure(dns_zone_t *zone) { 4088 isc_result_t result; 4089 4090 /* 4091 * We've finished loading, or else failed to load, an inline-signing 4092 * 'secure' zone. We now need information about the status of the 4093 * 'raw' zone. If we failed to load, then we need it to send a 4094 * copy of its database; if we succeeded, we need it to send its 4095 * serial number so that we can sync with it. If it has not yet 4096 * loaded, we set a flag so that it will send the necessary 4097 * information when it has finished loading. 4098 */ 4099 if (zone->raw->db != NULL) { 4100 if (zone->db != NULL) { 4101 isc_uint32_t serial; 4102 unsigned int soacount; 4103 4104 result = zone_get_from_db(zone->raw, zone->raw->db, 4105 NULL, &soacount, &serial, NULL, 4106 NULL, NULL, NULL, NULL); 4107 if (result == ISC_R_SUCCESS && soacount > 0U) 4108 zone_send_secureserial(zone->raw, serial); 4109 } else 4110 zone_send_securedb(zone->raw, zone->raw->db); 4111 4112 } else 4113 DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE); 4114 } 4115 4116 static isc_boolean_t 4117 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) { 4118 isc_result_t result; 4119 isc_boolean_t answer = ISC_FALSE; 4120 dns_diff_t diff; 4121 4122 dns_diff_init(mctx, &diff); 4123 result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL); 4124 if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples)) 4125 answer = ISC_TRUE; 4126 dns_diff_clear(&diff); 4127 return (answer); 4128 } 4129 4130 /* 4131 * The zone is presumed to be locked. 4132 * If this is a inline_raw zone the secure version is also locked. 4133 */ 4134 static isc_result_t 4135 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, 4136 isc_result_t result) 4137 { 4138 unsigned int soacount = 0; 4139 unsigned int nscount = 0; 4140 unsigned int errors = 0; 4141 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum; 4142 isc_time_t now; 4143 isc_boolean_t needdump = ISC_FALSE; 4144 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE); 4145 isc_boolean_t nomaster = ISC_FALSE; 4146 unsigned int options; 4147 dns_include_t *inc; 4148 4149 INSIST(LOCKED_ZONE(zone)); 4150 if (inline_raw(zone)) 4151 INSIST(LOCKED_ZONE(zone->secure)); 4152 4153 TIME_NOW(&now); 4154 4155 /* 4156 * Initiate zone transfer? We may need a error code that 4157 * indicates that the "permanent" form does not exist. 4158 * XXX better error feedback to log. 4159 */ 4160 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { 4161 if (zone->type == dns_zone_slave || 4162 zone->type == dns_zone_stub || 4163 (zone->type == dns_zone_redirect && 4164 zone->masters == NULL)) { 4165 if (result == ISC_R_FILENOTFOUND) 4166 dns_zone_log(zone, ISC_LOG_DEBUG(1), 4167 "no master file"); 4168 else if (result != DNS_R_NOMASTERFILE) 4169 dns_zone_log(zone, ISC_LOG_ERROR, 4170 "loading from master file %s " 4171 "failed: %s", 4172 zone->masterfile, 4173 dns_result_totext(result)); 4174 } else if (zone->type == dns_zone_master && 4175 inline_secure(zone) && result == ISC_R_FILENOTFOUND) 4176 { 4177 dns_zone_log(zone, ISC_LOG_DEBUG(1), 4178 "no master file, requesting db"); 4179 maybe_send_secure(zone); 4180 } else { 4181 int level = ISC_LOG_ERROR; 4182 if (zone->type == dns_zone_key && 4183 result == ISC_R_FILENOTFOUND) 4184 level = ISC_LOG_DEBUG(1); 4185 dns_zone_log(zone, level, 4186 "loading from master file %s failed: %s", 4187 zone->masterfile, 4188 dns_result_totext(result)); 4189 nomaster = ISC_TRUE; 4190 } 4191 4192 if (zone->type != dns_zone_key) 4193 goto cleanup; 4194 } 4195 4196 dns_zone_log(zone, ISC_LOG_DEBUG(2), 4197 "number of nodes in database: %u", 4198 dns_db_nodecount(db)); 4199 4200 if (result == DNS_R_SEENINCLUDE) 4201 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 4202 else 4203 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 4204 4205 /* 4206 * If there's no master file for a key zone, then the zone is new: 4207 * create an SOA record. (We do this now, instead of later, so that 4208 * if there happens to be a journal file, we can roll forward from 4209 * a sane starting point.) 4210 */ 4211 if (nomaster && zone->type == dns_zone_key) { 4212 result = add_soa(zone, db); 4213 if (result != ISC_R_SUCCESS) 4214 goto cleanup; 4215 } 4216 4217 /* 4218 * Apply update log, if any, on initial load. 4219 */ 4220 if (zone->journal != NULL && 4221 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) && 4222 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 4223 { 4224 if (zone->type == dns_zone_master && 4225 (zone->update_acl != NULL || zone->ssutable != NULL)) 4226 options = DNS_JOURNALOPT_RESIGN; 4227 else 4228 options = 0; 4229 result = dns_journal_rollforward(zone->mctx, db, options, 4230 zone->journal); 4231 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND && 4232 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL && 4233 result != ISC_R_RANGE) { 4234 dns_zone_log(zone, ISC_LOG_ERROR, 4235 "journal rollforward failed: %s", 4236 dns_result_totext(result)); 4237 goto cleanup; 4238 4239 4240 } 4241 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) { 4242 dns_zone_log(zone, ISC_LOG_ERROR, 4243 "journal rollforward failed: " 4244 "journal out of sync with zone"); 4245 goto cleanup; 4246 } 4247 dns_zone_log(zone, ISC_LOG_DEBUG(1), 4248 "journal rollforward completed " 4249 "successfully: %s", 4250 dns_result_totext(result)); 4251 if (result == ISC_R_SUCCESS) 4252 needdump = ISC_TRUE; 4253 } 4254 4255 /* 4256 * Obtain ns, soa and cname counts for top of zone. 4257 */ 4258 INSIST(db != NULL); 4259 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial, 4260 &refresh, &retry, &expire, &minimum, 4261 &errors); 4262 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) { 4263 dns_zone_log(zone, ISC_LOG_ERROR, 4264 "could not find NS and/or SOA records"); 4265 } 4266 4267 /* 4268 * Check to make sure the journal is up to date, and remove the 4269 * journal file if it isn't, as we wouldn't be able to apply 4270 * updates otherwise. 4271 */ 4272 if (zone->journal != NULL && dns_zone_isdynamic(zone, ISC_TRUE) && 4273 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) { 4274 isc_uint32_t jserial; 4275 dns_journal_t *journal = NULL; 4276 4277 result = dns_journal_open(zone->mctx, zone->journal, 4278 DNS_JOURNAL_READ, &journal); 4279 if (result == ISC_R_SUCCESS) { 4280 jserial = dns_journal_last_serial(journal); 4281 dns_journal_destroy(&journal); 4282 } else { 4283 jserial = serial; 4284 result = ISC_R_SUCCESS; 4285 } 4286 4287 if (jserial != serial) { 4288 dns_zone_log(zone, ISC_LOG_INFO, 4289 "journal file is out of date: " 4290 "removing journal file"); 4291 if (remove(zone->journal) < 0 && errno != ENOENT) { 4292 char strbuf[ISC_STRERRORSIZE]; 4293 isc__strerror(errno, strbuf, sizeof(strbuf)); 4294 isc_log_write(dns_lctx, 4295 DNS_LOGCATEGORY_GENERAL, 4296 DNS_LOGMODULE_ZONE, 4297 ISC_LOG_WARNING, 4298 "unable to remove journal " 4299 "'%s': '%s'", 4300 zone->journal, strbuf); 4301 } 4302 } 4303 } 4304 4305 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity"); 4306 4307 /* 4308 * Master / Slave / Stub zones require both NS and SOA records at 4309 * the top of the zone. 4310 */ 4311 4312 switch (zone->type) { 4313 case dns_zone_dlz: 4314 case dns_zone_master: 4315 case dns_zone_slave: 4316 case dns_zone_stub: 4317 case dns_zone_redirect: 4318 if (soacount != 1) { 4319 dns_zone_log(zone, ISC_LOG_ERROR, 4320 "has %d SOA records", soacount); 4321 result = DNS_R_BADZONE; 4322 } 4323 if (nscount == 0) { 4324 dns_zone_log(zone, ISC_LOG_ERROR, 4325 "has no NS records"); 4326 result = DNS_R_BADZONE; 4327 } 4328 if (result != ISC_R_SUCCESS) 4329 goto cleanup; 4330 if (zone->type == dns_zone_master && errors != 0) { 4331 result = DNS_R_BADZONE; 4332 goto cleanup; 4333 } 4334 if (zone->type != dns_zone_stub && 4335 zone->type != dns_zone_redirect) { 4336 result = check_nsec3param(zone, db); 4337 if (result != ISC_R_SUCCESS) 4338 goto cleanup; 4339 } 4340 if (zone->type == dns_zone_master && 4341 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) && 4342 !integrity_checks(zone, db)) { 4343 result = DNS_R_BADZONE; 4344 goto cleanup; 4345 } 4346 if (zone->type == dns_zone_master && 4347 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) && 4348 !zone_check_dup(zone, db)) { 4349 result = DNS_R_BADZONE; 4350 goto cleanup; 4351 } 4352 4353 if (zone->db != NULL) { 4354 unsigned int oldsoacount; 4355 4356 /* 4357 * This is checked in zone_replacedb() for slave zones 4358 * as they don't reload from disk. 4359 */ 4360 result = zone_get_from_db(zone, zone->db, NULL, 4361 &oldsoacount, &oldserial, 4362 NULL, NULL, NULL, NULL, 4363 NULL); 4364 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4365 RUNTIME_CHECK(soacount > 0U); 4366 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 4367 !isc_serial_gt(serial, oldserial)) { 4368 isc_uint32_t serialmin, serialmax; 4369 4370 INSIST(zone->type == dns_zone_master); 4371 4372 if (serial == oldserial && 4373 zone_unchanged(zone->db, db, zone->mctx)) { 4374 dns_zone_log(zone, ISC_LOG_INFO, 4375 "ixfr-from-differences: " 4376 "unchanged"); 4377 return(ISC_R_SUCCESS); 4378 } 4379 4380 serialmin = (oldserial + 1) & 0xffffffffU; 4381 serialmax = (oldserial + 0x7fffffffU) & 4382 0xffffffffU; 4383 dns_zone_log(zone, ISC_LOG_ERROR, 4384 "ixfr-from-differences: " 4385 "new serial (%u) out of range " 4386 "[%u - %u]", serial, serialmin, 4387 serialmax); 4388 result = DNS_R_BADZONE; 4389 goto cleanup; 4390 } else if (!isc_serial_ge(serial, oldserial)) 4391 dns_zone_log(zone, ISC_LOG_ERROR, 4392 "zone serial (%u/%u) has gone " 4393 "backwards", serial, oldserial); 4394 else if (serial == oldserial && !hasinclude && 4395 strcmp(zone->db_argv[0], "_builtin") != 0) 4396 dns_zone_log(zone, ISC_LOG_ERROR, 4397 "zone serial (%u) unchanged. " 4398 "zone may fail to transfer " 4399 "to slaves.", serial); 4400 } 4401 4402 if (zone->type == dns_zone_master && 4403 (zone->update_acl != NULL || zone->ssutable != NULL) && 4404 zone->sigresigninginterval < (3 * refresh) && 4405 dns_db_issecure(db)) 4406 { 4407 dns_zone_log(zone, ISC_LOG_WARNING, 4408 "sig-re-signing-interval less than " 4409 "3 * refresh."); 4410 } 4411 4412 zone->refresh = RANGE(refresh, 4413 zone->minrefresh, zone->maxrefresh); 4414 zone->retry = RANGE(retry, 4415 zone->minretry, zone->maxretry); 4416 zone->expire = RANGE(expire, zone->refresh + zone->retry, 4417 DNS_MAX_EXPIRE); 4418 zone->minimum = minimum; 4419 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 4420 4421 if (zone->type == dns_zone_slave || 4422 zone->type == dns_zone_stub || 4423 (zone->type == dns_zone_redirect && 4424 zone->masters != NULL)) { 4425 isc_time_t t; 4426 isc_uint32_t delay; 4427 4428 result = isc_file_getmodtime(zone->journal, &t); 4429 if (result != ISC_R_SUCCESS) 4430 result = isc_file_getmodtime(zone->masterfile, 4431 &t); 4432 if (result == ISC_R_SUCCESS) 4433 DNS_ZONE_TIME_ADD(&t, zone->expire, 4434 &zone->expiretime); 4435 else 4436 DNS_ZONE_TIME_ADD(&now, zone->retry, 4437 &zone->expiretime); 4438 4439 delay = isc_random_jitter(zone->retry, 4440 (zone->retry * 3) / 4); 4441 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime); 4442 if (isc_time_compare(&zone->refreshtime, 4443 &zone->expiretime) >= 0) 4444 zone->refreshtime = now; 4445 } 4446 4447 break; 4448 4449 case dns_zone_key: 4450 result = sync_keyzone(zone, db); 4451 if (result != ISC_R_SUCCESS) 4452 goto cleanup; 4453 break; 4454 4455 default: 4456 UNEXPECTED_ERROR(__FILE__, __LINE__, 4457 "unexpected zone type %d", zone->type); 4458 result = ISC_R_UNEXPECTED; 4459 goto cleanup; 4460 } 4461 4462 /* 4463 * Check for weak DNSKEY's. 4464 */ 4465 if (zone->type == dns_zone_master) 4466 zone_check_dnskeys(zone, db); 4467 4468 /* 4469 * Schedule DNSSEC key refresh. 4470 */ 4471 if (zone->type == dns_zone_master && 4472 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 4473 zone->refreshkeytime = now; 4474 4475 #if 0 4476 /* destroy notification example. */ 4477 { 4478 isc_event_t *e = isc_event_allocate(zone->mctx, NULL, 4479 DNS_EVENT_DBDESTROYED, 4480 dns_zonemgr_dbdestroyed, 4481 zone, 4482 sizeof(isc_event_t)); 4483 dns_db_ondestroy(db, zone->task, &e); 4484 } 4485 #endif 4486 4487 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 4488 if (zone->db != NULL) { 4489 result = zone_replacedb(zone, db, ISC_FALSE); 4490 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 4491 if (result != ISC_R_SUCCESS) 4492 goto cleanup; 4493 } else { 4494 result = dns_db_rpz_ready(db); 4495 if (result != ISC_R_SUCCESS) 4496 goto cleanup; 4497 zone_attachdb(zone, db); 4498 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 4499 DNS_ZONE_SETFLAG(zone, 4500 DNS_ZONEFLG_LOADED| 4501 DNS_ZONEFLG_NEEDSTARTUPNOTIFY); 4502 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) && 4503 inline_raw(zone)) 4504 { 4505 if (zone->secure->db == NULL) 4506 zone_send_securedb(zone, db); 4507 else 4508 zone_send_secureserial(zone, serial); 4509 } 4510 } 4511 4512 /* 4513 * Finished loading inline-signing zone; need to get status 4514 * from the raw side now. 4515 */ 4516 if (zone->type == dns_zone_master && inline_secure(zone)) 4517 maybe_send_secure(zone); 4518 4519 4520 result = ISC_R_SUCCESS; 4521 4522 if (needdump) { 4523 if (zone->type == dns_zone_key) 4524 zone_needdump(zone, 30); 4525 else 4526 zone_needdump(zone, DNS_DUMP_DELAY); 4527 } 4528 4529 if (zone->task != NULL) { 4530 if (zone->type == dns_zone_master) { 4531 set_resigntime(zone); 4532 resume_signingwithkey(zone); 4533 resume_addnsec3chain(zone); 4534 } 4535 4536 if (zone->type == dns_zone_master && 4537 !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) && 4538 dns_zone_isdynamic(zone, ISC_FALSE) && 4539 dns_db_issecure(db)) { 4540 dns_name_t *name; 4541 dns_fixedname_t fixed; 4542 dns_rdataset_t next; 4543 4544 dns_rdataset_init(&next); 4545 dns_fixedname_init(&fixed); 4546 name = dns_fixedname_name(&fixed); 4547 4548 result = dns_db_getsigningtime(db, &next, name); 4549 if (result == ISC_R_SUCCESS) { 4550 isc_stdtime_t timenow; 4551 char namebuf[DNS_NAME_FORMATSIZE]; 4552 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 4553 4554 isc_stdtime_get(&timenow); 4555 dns_name_format(name, namebuf, sizeof(namebuf)); 4556 dns_rdatatype_format(next.covers, 4557 typebuf, sizeof(typebuf)); 4558 dns_zone_log(zone, ISC_LOG_DEBUG(3), 4559 "next resign: %s/%s in %d seconds", 4560 namebuf, typebuf, 4561 next.resign - timenow - 4562 zone->sigresigninginterval); 4563 dns_rdataset_disassociate(&next); 4564 } else 4565 dns_zone_log(zone, ISC_LOG_WARNING, 4566 "signed dynamic zone has no " 4567 "resign event scheduled"); 4568 } 4569 4570 zone_settimer(zone, &now); 4571 } 4572 4573 /* 4574 * Clear old include list. 4575 */ 4576 for (inc = ISC_LIST_HEAD(zone->includes); 4577 inc != NULL; 4578 inc = ISC_LIST_HEAD(zone->includes)) { 4579 ISC_LIST_UNLINK(zone->includes, inc, link); 4580 isc_mem_free(zone->mctx, inc->name); 4581 isc_mem_put(zone->mctx, inc, sizeof(*inc)); 4582 } 4583 zone->nincludes = 0; 4584 4585 /* 4586 * Transfer new include list. 4587 */ 4588 for (inc = ISC_LIST_HEAD(zone->newincludes); 4589 inc != NULL; 4590 inc = ISC_LIST_HEAD(zone->newincludes)) { 4591 ISC_LIST_UNLINK(zone->newincludes, inc, link); 4592 ISC_LIST_APPEND(zone->includes, inc, link); 4593 zone->nincludes++; 4594 } 4595 4596 if (! dns_db_ispersistent(db)) 4597 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial, 4598 dns_db_issecure(db) ? " (DNSSEC signed)" : ""); 4599 4600 zone->loadtime = loadtime; 4601 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); 4602 return (result); 4603 4604 cleanup: 4605 for (inc = ISC_LIST_HEAD(zone->newincludes); 4606 inc != NULL; 4607 inc = ISC_LIST_HEAD(zone->newincludes)) { 4608 ISC_LIST_UNLINK(zone->newincludes, inc, link); 4609 isc_mem_free(zone->mctx, inc->name); 4610 isc_mem_put(zone->mctx, inc, sizeof(*inc)); 4611 } 4612 if (zone->type == dns_zone_slave || 4613 zone->type == dns_zone_stub || 4614 zone->type == dns_zone_key || 4615 (zone->type == dns_zone_redirect && zone->masters != NULL)) { 4616 if (zone->journal != NULL) 4617 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX"); 4618 if (zone->masterfile != NULL) 4619 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX"); 4620 4621 /* Mark the zone for immediate refresh. */ 4622 zone->refreshtime = now; 4623 if (zone->task != NULL) 4624 zone_settimer(zone, &now); 4625 result = ISC_R_SUCCESS; 4626 } else if (zone->type == dns_zone_master || 4627 zone->type == dns_zone_redirect) { 4628 if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND)) 4629 dns_zone_log(zone, ISC_LOG_ERROR, 4630 "not loaded due to errors."); 4631 else if (zone->type == dns_zone_master) 4632 result = ISC_R_SUCCESS; 4633 } 4634 4635 return (result); 4636 } 4637 4638 static isc_boolean_t 4639 exit_check(dns_zone_t *zone) { 4640 REQUIRE(LOCKED_ZONE(zone)); 4641 4642 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->irefs == 0) { 4643 /* 4644 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0. 4645 */ 4646 INSIST(isc_refcount_current(&zone->erefs) == 0); 4647 return (ISC_TRUE); 4648 } 4649 return (ISC_FALSE); 4650 } 4651 4652 static isc_boolean_t 4653 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 4654 dns_name_t *name, isc_boolean_t logit) 4655 { 4656 isc_result_t result; 4657 char namebuf[DNS_NAME_FORMATSIZE]; 4658 char altbuf[DNS_NAME_FORMATSIZE]; 4659 dns_fixedname_t fixed; 4660 dns_name_t *foundname; 4661 int level; 4662 4663 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) 4664 return (ISC_TRUE); 4665 4666 if (zone->type == dns_zone_master) 4667 level = ISC_LOG_ERROR; 4668 else 4669 level = ISC_LOG_WARNING; 4670 4671 dns_fixedname_init(&fixed); 4672 foundname = dns_fixedname_name(&fixed); 4673 4674 result = dns_db_find(db, name, version, dns_rdatatype_a, 4675 0, 0, NULL, foundname, NULL, NULL); 4676 if (result == ISC_R_SUCCESS) 4677 return (ISC_TRUE); 4678 4679 if (result == DNS_R_NXRRSET) { 4680 result = dns_db_find(db, name, version, dns_rdatatype_aaaa, 4681 0, 0, NULL, foundname, NULL, NULL); 4682 if (result == ISC_R_SUCCESS) 4683 return (ISC_TRUE); 4684 } 4685 4686 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 4687 result == DNS_R_EMPTYNAME) { 4688 if (logit) { 4689 dns_name_format(name, namebuf, sizeof namebuf); 4690 dns_zone_log(zone, level, "NS '%s' has no address " 4691 "records (A or AAAA)", namebuf); 4692 } 4693 return (ISC_FALSE); 4694 } 4695 4696 if (result == DNS_R_CNAME) { 4697 if (logit) { 4698 dns_name_format(name, namebuf, sizeof namebuf); 4699 dns_zone_log(zone, level, "NS '%s' is a CNAME " 4700 "(illegal)", namebuf); 4701 } 4702 return (ISC_FALSE); 4703 } 4704 4705 if (result == DNS_R_DNAME) { 4706 if (logit) { 4707 dns_name_format(name, namebuf, sizeof namebuf); 4708 dns_name_format(foundname, altbuf, sizeof altbuf); 4709 dns_zone_log(zone, level, "NS '%s' is below a DNAME " 4710 "'%s' (illegal)", namebuf, altbuf); 4711 } 4712 return (ISC_FALSE); 4713 } 4714 4715 return (ISC_TRUE); 4716 } 4717 4718 static isc_result_t 4719 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, 4720 dns_dbversion_t *version, unsigned int *nscount, 4721 unsigned int *errors, isc_boolean_t logit) 4722 { 4723 isc_result_t result; 4724 unsigned int count = 0; 4725 unsigned int ecount = 0; 4726 dns_rdataset_t rdataset; 4727 dns_rdata_t rdata; 4728 dns_rdata_ns_t ns; 4729 4730 dns_rdataset_init(&rdataset); 4731 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns, 4732 dns_rdatatype_none, 0, &rdataset, NULL); 4733 if (result == ISC_R_NOTFOUND) { 4734 INSIST(!dns_rdataset_isassociated(&rdataset)); 4735 goto success; 4736 } 4737 if (result != ISC_R_SUCCESS) { 4738 INSIST(!dns_rdataset_isassociated(&rdataset)); 4739 goto invalidate_rdataset; 4740 } 4741 4742 result = dns_rdataset_first(&rdataset); 4743 while (result == ISC_R_SUCCESS) { 4744 if (errors != NULL && zone->rdclass == dns_rdataclass_in && 4745 (zone->type == dns_zone_master || 4746 zone->type == dns_zone_slave)) { 4747 dns_rdata_init(&rdata); 4748 dns_rdataset_current(&rdataset, &rdata); 4749 result = dns_rdata_tostruct(&rdata, &ns, NULL); 4750 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4751 if (dns_name_issubdomain(&ns.name, &zone->origin) && 4752 !zone_check_ns(zone, db, version, &ns.name, logit)) 4753 ecount++; 4754 } 4755 count++; 4756 result = dns_rdataset_next(&rdataset); 4757 } 4758 dns_rdataset_disassociate(&rdataset); 4759 4760 success: 4761 if (nscount != NULL) 4762 *nscount = count; 4763 if (errors != NULL) 4764 *errors = ecount; 4765 4766 result = ISC_R_SUCCESS; 4767 4768 invalidate_rdataset: 4769 dns_rdataset_invalidate(&rdataset); 4770 4771 return (result); 4772 } 4773 4774 static isc_result_t 4775 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 4776 unsigned int *soacount, 4777 isc_uint32_t *serial, isc_uint32_t *refresh, 4778 isc_uint32_t *retry, isc_uint32_t *expire, 4779 isc_uint32_t *minimum) 4780 { 4781 isc_result_t result; 4782 unsigned int count; 4783 dns_rdataset_t rdataset; 4784 dns_rdata_t rdata = DNS_RDATA_INIT; 4785 dns_rdata_soa_t soa; 4786 4787 dns_rdataset_init(&rdataset); 4788 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, 4789 dns_rdatatype_none, 0, &rdataset, NULL); 4790 if (result == ISC_R_NOTFOUND) { 4791 INSIST(!dns_rdataset_isassociated(&rdataset)); 4792 if (soacount != NULL) 4793 *soacount = 0; 4794 if (serial != NULL) 4795 *serial = 0; 4796 if (refresh != NULL) 4797 *refresh = 0; 4798 if (retry != NULL) 4799 *retry = 0; 4800 if (expire != NULL) 4801 *expire = 0; 4802 if (minimum != NULL) 4803 *minimum = 0; 4804 result = ISC_R_SUCCESS; 4805 goto invalidate_rdataset; 4806 } 4807 if (result != ISC_R_SUCCESS) { 4808 INSIST(!dns_rdataset_isassociated(&rdataset)); 4809 goto invalidate_rdataset; 4810 } 4811 4812 count = 0; 4813 result = dns_rdataset_first(&rdataset); 4814 while (result == ISC_R_SUCCESS) { 4815 dns_rdata_init(&rdata); 4816 dns_rdataset_current(&rdataset, &rdata); 4817 count++; 4818 if (count == 1) { 4819 result = dns_rdata_tostruct(&rdata, &soa, NULL); 4820 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4821 } 4822 4823 result = dns_rdataset_next(&rdataset); 4824 dns_rdata_reset(&rdata); 4825 } 4826 dns_rdataset_disassociate(&rdataset); 4827 4828 if (soacount != NULL) 4829 *soacount = count; 4830 4831 if (count > 0) { 4832 if (serial != NULL) 4833 *serial = soa.serial; 4834 if (refresh != NULL) 4835 *refresh = soa.refresh; 4836 if (retry != NULL) 4837 *retry = soa.retry; 4838 if (expire != NULL) 4839 *expire = soa.expire; 4840 if (minimum != NULL) 4841 *minimum = soa.minimum; 4842 } else { 4843 if (soacount != NULL) 4844 *soacount = 0; 4845 if (serial != NULL) 4846 *serial = 0; 4847 if (refresh != NULL) 4848 *refresh = 0; 4849 if (retry != NULL) 4850 *retry = 0; 4851 if (expire != NULL) 4852 *expire = 0; 4853 if (minimum != NULL) 4854 *minimum = 0; 4855 } 4856 4857 result = ISC_R_SUCCESS; 4858 4859 invalidate_rdataset: 4860 dns_rdataset_invalidate(&rdataset); 4861 4862 return (result); 4863 } 4864 4865 /* 4866 * zone must be locked. 4867 */ 4868 static isc_result_t 4869 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 4870 unsigned int *soacount, isc_uint32_t *serial, 4871 isc_uint32_t *refresh, isc_uint32_t *retry, 4872 isc_uint32_t *expire, isc_uint32_t *minimum, 4873 unsigned int *errors) 4874 { 4875 isc_result_t result; 4876 isc_result_t answer = ISC_R_SUCCESS; 4877 dns_dbversion_t *version = NULL; 4878 dns_dbnode_t *node; 4879 4880 REQUIRE(db != NULL); 4881 REQUIRE(zone != NULL); 4882 4883 dns_db_currentversion(db, &version); 4884 4885 if (nscount != NULL) 4886 *nscount = 0; 4887 if (soacount != NULL) 4888 *soacount = 0; 4889 if (serial != NULL) 4890 *serial = 0; 4891 if (refresh != NULL) 4892 *refresh = 0; 4893 if (retry != NULL) 4894 *retry = 0; 4895 if (expire != NULL) 4896 *expire = 0; 4897 if (errors != NULL) 4898 *errors = 0; 4899 4900 node = NULL; 4901 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 4902 if (result != ISC_R_SUCCESS) { 4903 answer = result; 4904 goto closeversion; 4905 } 4906 4907 if (nscount != NULL || errors != NULL) { 4908 result = zone_count_ns_rr(zone, db, node, version, 4909 nscount, errors, ISC_TRUE); 4910 if (result != ISC_R_SUCCESS) 4911 answer = result; 4912 } 4913 4914 if (soacount != NULL || serial != NULL || refresh != NULL 4915 || retry != NULL || expire != NULL || minimum != NULL) { 4916 result = zone_load_soa_rr(db, node, version, soacount, 4917 serial, refresh, retry, expire, 4918 minimum); 4919 if (result != ISC_R_SUCCESS) 4920 answer = result; 4921 } 4922 4923 dns_db_detachnode(db, &node); 4924 closeversion: 4925 dns_db_closeversion(db, &version, ISC_FALSE); 4926 4927 return (answer); 4928 } 4929 4930 void 4931 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) { 4932 REQUIRE(DNS_ZONE_VALID(source)); 4933 REQUIRE(target != NULL && *target == NULL); 4934 isc_refcount_increment(&source->erefs, NULL); 4935 *target = source; 4936 } 4937 4938 void 4939 dns_zone_detach(dns_zone_t **zonep) { 4940 dns_zone_t *zone; 4941 dns_zone_t *raw = NULL; 4942 dns_zone_t *secure = NULL; 4943 unsigned int refs; 4944 isc_boolean_t free_now = ISC_FALSE; 4945 4946 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 4947 4948 zone = *zonep; 4949 4950 isc_refcount_decrement(&zone->erefs, &refs); 4951 4952 if (refs == 0) { 4953 LOCK_ZONE(zone); 4954 INSIST(zone != zone->raw); 4955 /* 4956 * We just detached the last external reference. 4957 */ 4958 if (zone->task != NULL) { 4959 /* 4960 * This zone is being managed. Post 4961 * its control event and let it clean 4962 * up synchronously in the context of 4963 * its task. 4964 */ 4965 isc_event_t *ev = &zone->ctlevent; 4966 isc_task_send(zone->task, &ev); 4967 } else { 4968 /* 4969 * This zone is not being managed; it has 4970 * no task and can have no outstanding 4971 * events. Free it immediately. 4972 */ 4973 /* 4974 * Unmanaged zones should not have non-null views; 4975 * we have no way of detaching from the view here 4976 * without causing deadlock because this code is called 4977 * with the view already locked. 4978 */ 4979 INSIST(zone->view == NULL); 4980 free_now = ISC_TRUE; 4981 raw = zone->raw; 4982 zone->raw = NULL; 4983 secure = zone->secure; 4984 zone->secure = NULL; 4985 } 4986 UNLOCK_ZONE(zone); 4987 } 4988 *zonep = NULL; 4989 if (free_now) { 4990 if (raw != NULL) 4991 dns_zone_detach(&raw); 4992 if (secure != NULL) 4993 dns_zone_idetach(&secure); 4994 zone_free(zone); 4995 } 4996 } 4997 4998 void 4999 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) { 5000 REQUIRE(DNS_ZONE_VALID(source)); 5001 REQUIRE(target != NULL && *target == NULL); 5002 LOCK_ZONE(source); 5003 zone_iattach(source, target); 5004 UNLOCK_ZONE(source); 5005 } 5006 5007 static void 5008 zone_iattach(dns_zone_t *source, dns_zone_t **target) { 5009 5010 /* 5011 * 'source' locked by caller. 5012 */ 5013 REQUIRE(LOCKED_ZONE(source)); 5014 REQUIRE(DNS_ZONE_VALID(source)); 5015 REQUIRE(target != NULL && *target == NULL); 5016 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0); 5017 source->irefs++; 5018 INSIST(source->irefs != 0); 5019 *target = source; 5020 } 5021 5022 static void 5023 zone_idetach(dns_zone_t **zonep) { 5024 dns_zone_t *zone; 5025 5026 /* 5027 * 'zone' locked by caller. 5028 */ 5029 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 5030 zone = *zonep; 5031 REQUIRE(LOCKED_ZONE(*zonep)); 5032 *zonep = NULL; 5033 5034 INSIST(zone->irefs > 0); 5035 zone->irefs--; 5036 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0); 5037 } 5038 5039 void 5040 dns_zone_idetach(dns_zone_t **zonep) { 5041 dns_zone_t *zone; 5042 isc_boolean_t free_needed; 5043 5044 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 5045 zone = *zonep; 5046 *zonep = NULL; 5047 5048 LOCK_ZONE(zone); 5049 INSIST(zone->irefs > 0); 5050 zone->irefs--; 5051 free_needed = exit_check(zone); 5052 UNLOCK_ZONE(zone); 5053 if (free_needed) 5054 zone_free(zone); 5055 } 5056 5057 isc_mem_t * 5058 dns_zone_getmctx(dns_zone_t *zone) { 5059 REQUIRE(DNS_ZONE_VALID(zone)); 5060 5061 return (zone->mctx); 5062 } 5063 5064 dns_zonemgr_t * 5065 dns_zone_getmgr(dns_zone_t *zone) { 5066 REQUIRE(DNS_ZONE_VALID(zone)); 5067 5068 return (zone->zmgr); 5069 } 5070 5071 void 5072 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) { 5073 REQUIRE(DNS_ZONE_VALID(zone)); 5074 5075 LOCK_ZONE(zone); 5076 if (value) 5077 DNS_ZONE_SETFLAG(zone, flags); 5078 else 5079 DNS_ZONE_CLRFLAG(zone, flags); 5080 UNLOCK_ZONE(zone); 5081 } 5082 5083 void 5084 dns_zone_setoption(dns_zone_t *zone, unsigned int option, 5085 isc_boolean_t value) 5086 { 5087 REQUIRE(DNS_ZONE_VALID(zone)); 5088 5089 LOCK_ZONE(zone); 5090 if (value) 5091 zone->options |= option; 5092 else 5093 zone->options &= ~option; 5094 UNLOCK_ZONE(zone); 5095 } 5096 5097 void 5098 dns_zone_setoption2(dns_zone_t *zone, unsigned int option, 5099 isc_boolean_t value) 5100 { 5101 REQUIRE(DNS_ZONE_VALID(zone)); 5102 5103 LOCK_ZONE(zone); 5104 if (value) 5105 zone->options2 |= option; 5106 else 5107 zone->options2 &= ~option; 5108 UNLOCK_ZONE(zone); 5109 } 5110 5111 unsigned int 5112 dns_zone_getoptions(dns_zone_t *zone) { 5113 REQUIRE(DNS_ZONE_VALID(zone)); 5114 5115 return (zone->options); 5116 } 5117 5118 unsigned int 5119 dns_zone_getoptions2(dns_zone_t *zone) { 5120 REQUIRE(DNS_ZONE_VALID(zone)); 5121 5122 return (zone->options2); 5123 } 5124 5125 void 5126 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value) 5127 { 5128 REQUIRE(DNS_ZONE_VALID(zone)); 5129 5130 LOCK_ZONE(zone); 5131 if (value) 5132 zone->keyopts |= keyopt; 5133 else 5134 zone->keyopts &= ~keyopt; 5135 UNLOCK_ZONE(zone); 5136 } 5137 5138 unsigned int 5139 dns_zone_getkeyopts(dns_zone_t *zone) { 5140 5141 REQUIRE(DNS_ZONE_VALID(zone)); 5142 5143 return (zone->keyopts); 5144 } 5145 5146 isc_result_t 5147 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 5148 REQUIRE(DNS_ZONE_VALID(zone)); 5149 5150 LOCK_ZONE(zone); 5151 zone->xfrsource4 = *xfrsource; 5152 UNLOCK_ZONE(zone); 5153 5154 return (ISC_R_SUCCESS); 5155 } 5156 5157 isc_sockaddr_t * 5158 dns_zone_getxfrsource4(dns_zone_t *zone) { 5159 REQUIRE(DNS_ZONE_VALID(zone)); 5160 return (&zone->xfrsource4); 5161 } 5162 5163 isc_result_t 5164 dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) { 5165 REQUIRE(DNS_ZONE_VALID(zone)); 5166 5167 LOCK_ZONE(zone); 5168 zone->xfrsource4dscp = dscp; 5169 UNLOCK_ZONE(zone); 5170 5171 return (ISC_R_SUCCESS); 5172 } 5173 5174 isc_dscp_t 5175 dns_zone_getxfrsource4dscp(dns_zone_t *zone) { 5176 REQUIRE(DNS_ZONE_VALID(zone)); 5177 return (zone->xfrsource4dscp); 5178 } 5179 5180 isc_result_t 5181 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 5182 REQUIRE(DNS_ZONE_VALID(zone)); 5183 5184 LOCK_ZONE(zone); 5185 zone->xfrsource6 = *xfrsource; 5186 UNLOCK_ZONE(zone); 5187 5188 return (ISC_R_SUCCESS); 5189 } 5190 5191 isc_sockaddr_t * 5192 dns_zone_getxfrsource6(dns_zone_t *zone) { 5193 REQUIRE(DNS_ZONE_VALID(zone)); 5194 return (&zone->xfrsource6); 5195 } 5196 5197 isc_dscp_t 5198 dns_zone_getxfrsource6dscp(dns_zone_t *zone) { 5199 REQUIRE(DNS_ZONE_VALID(zone)); 5200 return (zone->xfrsource6dscp); 5201 } 5202 5203 isc_result_t 5204 dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) { 5205 REQUIRE(DNS_ZONE_VALID(zone)); 5206 5207 LOCK_ZONE(zone); 5208 zone->xfrsource6dscp = dscp; 5209 UNLOCK_ZONE(zone); 5210 5211 return (ISC_R_SUCCESS); 5212 } 5213 5214 isc_result_t 5215 dns_zone_setaltxfrsource4(dns_zone_t *zone, 5216 const isc_sockaddr_t *altxfrsource) 5217 { 5218 REQUIRE(DNS_ZONE_VALID(zone)); 5219 5220 LOCK_ZONE(zone); 5221 zone->altxfrsource4 = *altxfrsource; 5222 UNLOCK_ZONE(zone); 5223 5224 return (ISC_R_SUCCESS); 5225 } 5226 5227 isc_sockaddr_t * 5228 dns_zone_getaltxfrsource4(dns_zone_t *zone) { 5229 REQUIRE(DNS_ZONE_VALID(zone)); 5230 return (&zone->altxfrsource4); 5231 } 5232 5233 isc_result_t 5234 dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) { 5235 REQUIRE(DNS_ZONE_VALID(zone)); 5236 5237 LOCK_ZONE(zone); 5238 zone->altxfrsource4dscp = dscp; 5239 UNLOCK_ZONE(zone); 5240 5241 return (ISC_R_SUCCESS); 5242 } 5243 5244 isc_dscp_t 5245 dns_zone_getaltxfrsource4dscp(dns_zone_t *zone) { 5246 REQUIRE(DNS_ZONE_VALID(zone)); 5247 return (zone->altxfrsource4dscp); 5248 } 5249 5250 isc_result_t 5251 dns_zone_setaltxfrsource6(dns_zone_t *zone, 5252 const isc_sockaddr_t *altxfrsource) 5253 { 5254 REQUIRE(DNS_ZONE_VALID(zone)); 5255 5256 LOCK_ZONE(zone); 5257 zone->altxfrsource6 = *altxfrsource; 5258 UNLOCK_ZONE(zone); 5259 5260 return (ISC_R_SUCCESS); 5261 } 5262 5263 isc_sockaddr_t * 5264 dns_zone_getaltxfrsource6(dns_zone_t *zone) { 5265 REQUIRE(DNS_ZONE_VALID(zone)); 5266 return (&zone->altxfrsource6); 5267 } 5268 5269 isc_result_t 5270 dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) { 5271 REQUIRE(DNS_ZONE_VALID(zone)); 5272 5273 LOCK_ZONE(zone); 5274 zone->altxfrsource6dscp = dscp; 5275 UNLOCK_ZONE(zone); 5276 5277 return (ISC_R_SUCCESS); 5278 } 5279 5280 isc_dscp_t 5281 dns_zone_getaltxfrsource6dscp(dns_zone_t *zone) { 5282 REQUIRE(DNS_ZONE_VALID(zone)); 5283 return (zone->altxfrsource6dscp); 5284 } 5285 5286 isc_result_t 5287 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 5288 REQUIRE(DNS_ZONE_VALID(zone)); 5289 5290 LOCK_ZONE(zone); 5291 zone->notifysrc4 = *notifysrc; 5292 UNLOCK_ZONE(zone); 5293 5294 return (ISC_R_SUCCESS); 5295 } 5296 5297 isc_sockaddr_t * 5298 dns_zone_getnotifysrc4(dns_zone_t *zone) { 5299 REQUIRE(DNS_ZONE_VALID(zone)); 5300 return (&zone->notifysrc4); 5301 } 5302 5303 isc_result_t 5304 dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp) { 5305 REQUIRE(DNS_ZONE_VALID(zone)); 5306 5307 LOCK_ZONE(zone); 5308 zone->notifysrc4dscp = dscp; 5309 UNLOCK_ZONE(zone); 5310 5311 return (ISC_R_SUCCESS); 5312 } 5313 5314 isc_dscp_t 5315 dns_zone_getnotifysrc4dscp(dns_zone_t *zone) { 5316 REQUIRE(DNS_ZONE_VALID(zone)); 5317 return (zone->notifysrc4dscp); 5318 } 5319 5320 isc_result_t 5321 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 5322 REQUIRE(DNS_ZONE_VALID(zone)); 5323 5324 LOCK_ZONE(zone); 5325 zone->notifysrc6 = *notifysrc; 5326 UNLOCK_ZONE(zone); 5327 5328 return (ISC_R_SUCCESS); 5329 } 5330 5331 isc_sockaddr_t * 5332 dns_zone_getnotifysrc6(dns_zone_t *zone) { 5333 REQUIRE(DNS_ZONE_VALID(zone)); 5334 return (&zone->notifysrc6); 5335 } 5336 5337 static isc_boolean_t 5338 same_addrs(const isc_sockaddr_t *old, const isc_sockaddr_t *new, 5339 isc_uint32_t count) 5340 { 5341 unsigned int i; 5342 5343 for (i = 0; i < count; i++) 5344 if (!isc_sockaddr_equal(&old[i], &new[i])) 5345 return (ISC_FALSE); 5346 return (ISC_TRUE); 5347 } 5348 5349 static isc_boolean_t 5350 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) { 5351 unsigned int i; 5352 5353 if (old == NULL && new == NULL) 5354 return (ISC_TRUE); 5355 if (old == NULL || new == NULL) 5356 return (ISC_FALSE); 5357 5358 for (i = 0; i < count; i++) { 5359 if (old[i] == NULL && new[i] == NULL) 5360 continue; 5361 if (old[i] == NULL || new[i] == NULL || 5362 !dns_name_equal(old[i], new[i])) 5363 return (ISC_FALSE); 5364 } 5365 return (ISC_TRUE); 5366 } 5367 5368 static void 5369 clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp, 5370 dns_name_t ***keynamesp, unsigned int *countp, 5371 isc_mem_t *mctx) 5372 { 5373 unsigned int count; 5374 isc_sockaddr_t *addrs; 5375 isc_dscp_t *dscps; 5376 dns_name_t **keynames; 5377 5378 REQUIRE(countp != NULL && addrsp != NULL && dscpsp != NULL && 5379 keynamesp != NULL); 5380 5381 count = *countp; 5382 *countp = 0; 5383 addrs = *addrsp; 5384 *addrsp = NULL; 5385 dscps = *dscpsp; 5386 *dscpsp = NULL; 5387 keynames = *keynamesp; 5388 *keynamesp = NULL; 5389 5390 if (addrs != NULL) 5391 isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t)); 5392 5393 if (dscps != NULL) 5394 isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t)); 5395 5396 if (keynames != NULL) { 5397 unsigned int i; 5398 for (i = 0; i < count; i++) { 5399 if (keynames[i] != NULL) { 5400 dns_name_free(keynames[i], mctx); 5401 isc_mem_put(mctx, keynames[i], 5402 sizeof(dns_name_t)); 5403 keynames[i] = NULL; 5404 } 5405 } 5406 isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *)); 5407 } 5408 } 5409 5410 static isc_result_t 5411 set_addrkeylist(unsigned int count, 5412 const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp, 5413 const isc_dscp_t *dscp, isc_dscp_t **newdscpp, 5414 dns_name_t **names, dns_name_t ***newnamesp, 5415 isc_mem_t *mctx) 5416 { 5417 isc_result_t result; 5418 isc_sockaddr_t *newaddrs = NULL; 5419 isc_dscp_t *newdscp = NULL; 5420 dns_name_t **newnames = NULL; 5421 unsigned int i; 5422 5423 REQUIRE(newaddrsp != NULL && *newaddrsp == NULL); 5424 REQUIRE(newdscpp != NULL && *newdscpp == NULL); 5425 REQUIRE(newnamesp != NULL && *newnamesp == NULL); 5426 5427 newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs)); 5428 if (newaddrs == NULL) 5429 return (ISC_R_NOMEMORY); 5430 memmove(newaddrs, addrs, count * sizeof(*newaddrs)); 5431 5432 if (dscp != NULL) { 5433 newdscp = isc_mem_get(mctx, count * sizeof(*newdscp)); 5434 if (newdscp == NULL) { 5435 isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs)); 5436 return (ISC_R_NOMEMORY); 5437 } 5438 memmove(newdscp, dscp, count * sizeof(*newdscp)); 5439 } else 5440 newdscp = NULL; 5441 5442 if (names != NULL) { 5443 newnames = isc_mem_get(mctx, count * sizeof(*newnames)); 5444 if (newnames == NULL) { 5445 if (newdscp != NULL) 5446 isc_mem_put(mctx, newdscp, 5447 count * sizeof(*newdscp)); 5448 isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs)); 5449 return (ISC_R_NOMEMORY); 5450 } 5451 for (i = 0; i < count; i++) 5452 newnames[i] = NULL; 5453 for (i = 0; i < count; i++) { 5454 if (names[i] != NULL) { 5455 newnames[i] = isc_mem_get(mctx, 5456 sizeof(dns_name_t)); 5457 if (newnames[i] == NULL) 5458 goto allocfail; 5459 dns_name_init(newnames[i], NULL); 5460 result = dns_name_dup(names[i], mctx, 5461 newnames[i]); 5462 if (result != ISC_R_SUCCESS) { 5463 allocfail: 5464 for (i = 0; i < count; i++) 5465 if (newnames[i] != NULL) 5466 dns_name_free( 5467 newnames[i], 5468 mctx); 5469 isc_mem_put(mctx, newaddrs, 5470 count * sizeof(*newaddrs)); 5471 isc_mem_put(mctx, newdscp, 5472 count * sizeof(*newdscp)); 5473 isc_mem_put(mctx, newnames, 5474 count * sizeof(*newnames)); 5475 return (ISC_R_NOMEMORY); 5476 } 5477 } 5478 } 5479 } else 5480 newnames = NULL; 5481 5482 *newdscpp = newdscp; 5483 *newaddrsp = newaddrs; 5484 *newnamesp = newnames; 5485 return (ISC_R_SUCCESS); 5486 } 5487 5488 isc_result_t 5489 dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp) { 5490 REQUIRE(DNS_ZONE_VALID(zone)); 5491 5492 LOCK_ZONE(zone); 5493 zone->notifysrc6dscp = dscp; 5494 UNLOCK_ZONE(zone); 5495 5496 return (ISC_R_SUCCESS); 5497 } 5498 5499 isc_dscp_t 5500 dns_zone_getnotifysrc6dscp(dns_zone_t *zone) { 5501 REQUIRE(DNS_ZONE_VALID(zone)); 5502 return (zone->notifysrc6dscp); 5503 } 5504 5505 isc_result_t 5506 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, 5507 isc_uint32_t count) 5508 { 5509 return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, NULL, 5510 count)); 5511 } 5512 5513 isc_result_t 5514 dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify, 5515 dns_name_t **keynames, isc_uint32_t count) 5516 { 5517 return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, keynames, 5518 count)); 5519 } 5520 5521 isc_result_t 5522 dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify, 5523 const isc_dscp_t *dscps, dns_name_t **keynames, 5524 isc_uint32_t count) 5525 { 5526 isc_result_t result; 5527 isc_sockaddr_t *newaddrs = NULL; 5528 isc_dscp_t *newdscps = NULL; 5529 dns_name_t **newnames = NULL; 5530 5531 REQUIRE(DNS_ZONE_VALID(zone)); 5532 REQUIRE(count == 0 || notify != NULL); 5533 if (keynames != NULL) 5534 REQUIRE(count != 0); 5535 5536 LOCK_ZONE(zone); 5537 5538 if (count == zone->notifycnt && 5539 same_addrs(zone->notify, notify, count) && 5540 same_keynames(zone->notifykeynames, keynames, count)) 5541 goto unlock; 5542 5543 clear_addresskeylist(&zone->notify, &zone->notifydscp, 5544 &zone->notifykeynames, &zone->notifycnt, 5545 zone->mctx); 5546 5547 if (count == 0) 5548 goto unlock; 5549 5550 /* 5551 * Set up the notify and notifykey lists 5552 */ 5553 result = set_addrkeylist(count, notify, &newaddrs, dscps, &newdscps, 5554 keynames, &newnames, zone->mctx); 5555 if (result != ISC_R_SUCCESS) 5556 goto unlock; 5557 5558 /* 5559 * Everything is ok so attach to the zone. 5560 */ 5561 zone->notify = newaddrs; 5562 zone->notifydscp = newdscps; 5563 zone->notifykeynames = newnames; 5564 zone->notifycnt = count; 5565 unlock: 5566 UNLOCK_ZONE(zone); 5567 return (ISC_R_SUCCESS); 5568 } 5569 5570 isc_result_t 5571 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters, 5572 isc_uint32_t count) 5573 { 5574 isc_result_t result; 5575 5576 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count); 5577 return (result); 5578 } 5579 5580 isc_result_t 5581 dns_zone_setmasterswithkeys(dns_zone_t *zone, 5582 const isc_sockaddr_t *masters, 5583 dns_name_t **keynames, 5584 isc_uint32_t count) 5585 { 5586 isc_result_t result = ISC_R_SUCCESS; 5587 isc_sockaddr_t *newaddrs = NULL; 5588 isc_dscp_t *newdscps = NULL; 5589 dns_name_t **newnames = NULL; 5590 isc_boolean_t *newok; 5591 unsigned int i; 5592 5593 REQUIRE(DNS_ZONE_VALID(zone)); 5594 REQUIRE(count == 0 || masters != NULL); 5595 if (keynames != NULL) { 5596 REQUIRE(count != 0); 5597 } 5598 5599 LOCK_ZONE(zone); 5600 /* 5601 * The refresh code assumes that 'masters' wouldn't change under it. 5602 * If it will change then kill off any current refresh in progress 5603 * and update the masters info. If it won't change then we can just 5604 * unlock and exit. 5605 */ 5606 if (count != zone->masterscnt || 5607 !same_addrs(zone->masters, masters, count) || 5608 !same_keynames(zone->masterkeynames, keynames, count)) { 5609 if (zone->request != NULL) 5610 dns_request_cancel(zone->request); 5611 } else 5612 goto unlock; 5613 5614 /* 5615 * This needs to happen before clear_addresskeylist() sets 5616 * zone->masterscnt to 0: 5617 */ 5618 if (zone->mastersok != NULL) { 5619 isc_mem_put(zone->mctx, zone->mastersok, 5620 zone->masterscnt * sizeof(isc_boolean_t)); 5621 zone->mastersok = NULL; 5622 } 5623 clear_addresskeylist(&zone->masters, &zone->masterdscps, 5624 &zone->masterkeynames, &zone->masterscnt, 5625 zone->mctx); 5626 /* 5627 * If count == 0, don't allocate any space for masters, mastersok or 5628 * keynames so internally, those pointers are NULL if count == 0 5629 */ 5630 if (count == 0) 5631 goto unlock; 5632 5633 /* 5634 * mastersok must contain count elements 5635 */ 5636 newok = isc_mem_get(zone->mctx, count * sizeof(*newok)); 5637 if (newok == NULL) { 5638 result = ISC_R_NOMEMORY; 5639 isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs)); 5640 goto unlock; 5641 }; 5642 for (i = 0; i < count; i++) 5643 newok[i] = ISC_FALSE; 5644 5645 /* 5646 * Now set up the masters and masterkey lists 5647 */ 5648 result = set_addrkeylist(count, masters, &newaddrs, NULL, &newdscps, 5649 keynames, &newnames, zone->mctx); 5650 INSIST(newdscps == NULL); 5651 if (result != ISC_R_SUCCESS) { 5652 isc_mem_put(zone->mctx, newok, count * sizeof(*newok)); 5653 goto unlock; 5654 } 5655 5656 /* 5657 * Everything is ok so attach to the zone. 5658 */ 5659 zone->curmaster = 0; 5660 zone->mastersok = newok; 5661 zone->masters = newaddrs; 5662 zone->masterdscps = newdscps; 5663 zone->masterkeynames = newnames; 5664 zone->masterscnt = count; 5665 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS); 5666 5667 unlock: 5668 UNLOCK_ZONE(zone); 5669 return (result); 5670 } 5671 5672 isc_result_t 5673 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) { 5674 isc_result_t result = ISC_R_SUCCESS; 5675 5676 REQUIRE(DNS_ZONE_VALID(zone)); 5677 5678 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 5679 if (zone->db == NULL) 5680 result = DNS_R_NOTLOADED; 5681 else 5682 dns_db_attach(zone->db, dpb); 5683 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 5684 5685 return (result); 5686 } 5687 5688 void 5689 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) { 5690 REQUIRE(DNS_ZONE_VALID(zone)); 5691 REQUIRE(zone->type == dns_zone_staticstub); 5692 5693 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 5694 REQUIRE(zone->db == NULL); 5695 dns_db_attach(db, &zone->db); 5696 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 5697 } 5698 5699 /* 5700 * Co-ordinates the starting of routine jobs. 5701 */ 5702 void 5703 dns_zone_maintenance(dns_zone_t *zone) { 5704 const char me[] = "dns_zone_maintenance"; 5705 isc_time_t now; 5706 5707 REQUIRE(DNS_ZONE_VALID(zone)); 5708 ENTER; 5709 5710 LOCK_ZONE(zone); 5711 TIME_NOW(&now); 5712 zone_settimer(zone, &now); 5713 UNLOCK_ZONE(zone); 5714 } 5715 5716 static inline isc_boolean_t 5717 was_dumping(dns_zone_t *zone) { 5718 isc_boolean_t dumping; 5719 5720 REQUIRE(LOCKED_ZONE(zone)); 5721 5722 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING); 5723 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 5724 if (!dumping) { 5725 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 5726 isc_time_settoepoch(&zone->dumptime); 5727 } 5728 return (dumping); 5729 } 5730 5731 static isc_result_t 5732 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 5733 isc_mem_t *mctx, unsigned int maxkeys, 5734 dst_key_t **keys, unsigned int *nkeys) 5735 { 5736 isc_result_t result; 5737 dns_dbnode_t *node = NULL; 5738 const char *directory = dns_zone_getkeydirectory(zone); 5739 5740 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); 5741 memset(keys, 0, sizeof(*keys) * maxkeys); 5742 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db), 5743 directory, mctx, maxkeys, keys, 5744 nkeys); 5745 if (result == ISC_R_NOTFOUND) 5746 result = ISC_R_SUCCESS; 5747 failure: 5748 if (node != NULL) 5749 dns_db_detachnode(db, &node); 5750 return (result); 5751 } 5752 5753 static isc_result_t 5754 offline(dns_db_t *db, dns_dbversion_t *ver, zonediff_t *zonediff, 5755 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) 5756 { 5757 isc_result_t result; 5758 5759 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) 5760 return (ISC_R_SUCCESS); 5761 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, 5762 name, ttl, rdata); 5763 if (result != ISC_R_SUCCESS) 5764 return (result); 5765 rdata->flags |= DNS_RDATA_OFFLINE; 5766 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN, 5767 name, ttl, rdata); 5768 zonediff->offline = ISC_TRUE; 5769 return (result); 5770 } 5771 5772 static void 5773 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now) 5774 { 5775 unsigned int delta; 5776 char timebuf[80]; 5777 5778 zone->key_expiry = when; 5779 if (when <= now) { 5780 dns_zone_log(zone, ISC_LOG_ERROR, 5781 "DNSKEY RRSIG(s) have expired"); 5782 isc_time_settoepoch(&zone->keywarntime); 5783 } else if (when < now + 7 * 24 * 3600) { 5784 isc_time_t t; 5785 isc_time_set(&t, when, 0); 5786 isc_time_formattimestamp(&t, timebuf, 80); 5787 dns_zone_log(zone, ISC_LOG_WARNING, 5788 "DNSKEY RRSIG(s) will expire within 7 days: %s", 5789 timebuf); 5790 delta = when - now; 5791 delta--; /* loop prevention */ 5792 delta /= 24 * 3600; /* to whole days */ 5793 delta *= 24 * 3600; /* to seconds */ 5794 isc_time_set(&zone->keywarntime, when - delta, 0); 5795 } else { 5796 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0); 5797 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 5798 dns_zone_log(zone, ISC_LOG_NOTICE, 5799 "setting keywarntime to %s", timebuf); 5800 } 5801 } 5802 5803 /* 5804 * Helper function to del_sigs(). We don't want to delete RRSIGs that 5805 * have no new key. 5806 */ 5807 static isc_boolean_t 5808 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys, 5809 isc_boolean_t *warn) 5810 { 5811 unsigned int i = 0; 5812 isc_boolean_t have_ksk = ISC_FALSE, have_zsk = ISC_FALSE; 5813 isc_boolean_t have_pksk = ISC_FALSE, have_pzsk = ISC_FALSE; 5814 5815 for (i = 0; i < nkeys; i++) { 5816 if (rrsig_ptr->algorithm != dst_key_alg(keys[i])) 5817 continue; 5818 if (dst_key_isprivate(keys[i])) { 5819 if (KSK(keys[i])) 5820 have_ksk = have_pksk = ISC_TRUE; 5821 else 5822 have_zsk = have_pzsk = ISC_TRUE; 5823 } else { 5824 if (KSK(keys[i])) 5825 have_ksk = ISC_TRUE; 5826 else 5827 have_zsk = ISC_TRUE; 5828 } 5829 } 5830 5831 if (have_zsk && have_ksk && !have_pzsk) 5832 *warn = ISC_TRUE; 5833 5834 /* 5835 * It's okay to delete a signature if there is an active key 5836 * with the same algorithm to replace it. 5837 */ 5838 if (have_pksk || have_pzsk) 5839 return (ISC_TRUE); 5840 5841 /* 5842 * Failing that, it is *not* okay to delete a signature 5843 * if the associated public key is still in the DNSKEY RRset 5844 */ 5845 for (i = 0; i < nkeys; i++) { 5846 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) && 5847 (rrsig_ptr->keyid == dst_key_id(keys[i]))) 5848 return (ISC_FALSE); 5849 } 5850 5851 /* 5852 * But if the key is gone, then go ahead. 5853 */ 5854 return (ISC_TRUE); 5855 } 5856 5857 /* 5858 * Delete expired RRsigs and any RRsigs we are about to re-sign. 5859 * See also update.c:del_keysigs(). 5860 */ 5861 static isc_result_t 5862 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 5863 dns_rdatatype_t type, zonediff_t *zonediff, dst_key_t **keys, 5864 unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental) 5865 { 5866 isc_result_t result; 5867 dns_dbnode_t *node = NULL; 5868 dns_rdataset_t rdataset; 5869 unsigned int i; 5870 dns_rdata_rrsig_t rrsig; 5871 isc_boolean_t found; 5872 isc_int64_t timewarn = 0, timemaybe = 0; 5873 5874 dns_rdataset_init(&rdataset); 5875 5876 if (type == dns_rdatatype_nsec3) 5877 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node); 5878 else 5879 result = dns_db_findnode(db, name, ISC_FALSE, &node); 5880 if (result == ISC_R_NOTFOUND) 5881 return (ISC_R_SUCCESS); 5882 if (result != ISC_R_SUCCESS) 5883 goto failure; 5884 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type, 5885 (isc_stdtime_t) 0, &rdataset, NULL); 5886 dns_db_detachnode(db, &node); 5887 5888 if (result == ISC_R_NOTFOUND) { 5889 INSIST(!dns_rdataset_isassociated(&rdataset)); 5890 return (ISC_R_SUCCESS); 5891 } 5892 if (result != ISC_R_SUCCESS) { 5893 INSIST(!dns_rdataset_isassociated(&rdataset)); 5894 goto failure; 5895 } 5896 5897 for (result = dns_rdataset_first(&rdataset); 5898 result == ISC_R_SUCCESS; 5899 result = dns_rdataset_next(&rdataset)) { 5900 dns_rdata_t rdata = DNS_RDATA_INIT; 5901 5902 dns_rdataset_current(&rdataset, &rdata); 5903 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 5904 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5905 5906 if (type != dns_rdatatype_dnskey) { 5907 isc_boolean_t warn = ISC_FALSE, deleted = ISC_FALSE; 5908 if (delsig_ok(&rrsig, keys, nkeys, &warn)) { 5909 result = update_one_rr(db, ver, zonediff->diff, 5910 DNS_DIFFOP_DELRESIGN, name, 5911 rdataset.ttl, &rdata); 5912 if (result != ISC_R_SUCCESS) 5913 break; 5914 deleted = ISC_TRUE; 5915 } 5916 if (warn) { 5917 /* 5918 * At this point, we've got an RRSIG, 5919 * which is signed by an inactive key. 5920 * An administrator needs to provide a new 5921 * key/alg, but until that time, we want to 5922 * keep the old RRSIG. Marking the key as 5923 * offline will prevent us spinning waiting 5924 * for the private part. 5925 */ 5926 if (incremental && !deleted) { 5927 result = offline(db, ver, zonediff, 5928 name, rdataset.ttl, 5929 &rdata); 5930 if (result != ISC_R_SUCCESS) 5931 break; 5932 } 5933 5934 /* 5935 * Log the key id and algorithm of 5936 * the inactive key with no replacement 5937 */ 5938 if (zone->log_key_expired_timer <= now) { 5939 char origin[DNS_NAME_FORMATSIZE]; 5940 char algbuf[DNS_NAME_FORMATSIZE]; 5941 dns_name_format(&zone->origin, origin, 5942 sizeof(origin)); 5943 dns_secalg_format(rrsig.algorithm, 5944 algbuf, 5945 sizeof(algbuf)); 5946 dns_zone_log(zone, ISC_LOG_WARNING, 5947 "Key %s/%s/%d " 5948 "missing or inactive " 5949 "and has no replacement: " 5950 "retaining signatures.", 5951 origin, algbuf, 5952 rrsig.keyid); 5953 zone->log_key_expired_timer = now + 5954 3600; 5955 } 5956 } 5957 continue; 5958 } 5959 5960 /* 5961 * RRSIG(DNSKEY) requires special processing. 5962 */ 5963 found = ISC_FALSE; 5964 for (i = 0; i < nkeys; i++) { 5965 if (rrsig.algorithm == dst_key_alg(keys[i]) && 5966 rrsig.keyid == dst_key_id(keys[i])) { 5967 found = ISC_TRUE; 5968 /* 5969 * Mark offline RRSIG(DNSKEY). 5970 * We want the earliest offline expire time 5971 * iff there is a new offline signature. 5972 */ 5973 if (!dst_key_inactive(keys[i]) && 5974 !dst_key_isprivate(keys[i])) 5975 { 5976 isc_int64_t timeexpire = 5977 dns_time64_from32(rrsig.timeexpire); 5978 if (timewarn != 0 && 5979 timewarn > timeexpire) 5980 timewarn = timeexpire; 5981 if (rdata.flags & DNS_RDATA_OFFLINE) { 5982 if (timemaybe == 0 || 5983 timemaybe > timeexpire) 5984 timemaybe = timeexpire; 5985 break; 5986 } 5987 if (timewarn == 0) 5988 timewarn = timemaybe; 5989 if (timewarn == 0 || 5990 timewarn > timeexpire) 5991 timewarn = timeexpire; 5992 result = offline(db, ver, zonediff, 5993 name, rdataset.ttl, 5994 &rdata); 5995 break; 5996 } 5997 result = update_one_rr(db, ver, zonediff->diff, 5998 DNS_DIFFOP_DELRESIGN, 5999 name, rdataset.ttl, 6000 &rdata); 6001 break; 6002 } 6003 } 6004 6005 /* 6006 * If there is not a matching DNSKEY then 6007 * delete the RRSIG. 6008 */ 6009 if (!found) 6010 result = update_one_rr(db, ver, zonediff->diff, 6011 DNS_DIFFOP_DELRESIGN, name, 6012 rdataset.ttl, &rdata); 6013 if (result != ISC_R_SUCCESS) 6014 break; 6015 } 6016 6017 dns_rdataset_disassociate(&rdataset); 6018 if (result == ISC_R_NOMORE) 6019 result = ISC_R_SUCCESS; 6020 if (timewarn > 0) { 6021 #if defined(STDTIME_ON_32BITS) 6022 isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn; 6023 if (timewarn == stdwarn) 6024 #endif 6025 set_key_expiry_warning(zone, (isc_stdtime_t)timewarn, 6026 now); 6027 #if defined(STDTIME_ON_32BITS) 6028 else 6029 dns_zone_log(zone, ISC_LOG_ERROR, 6030 "key expiry warning time out of range"); 6031 #endif 6032 } 6033 failure: 6034 if (node != NULL) 6035 dns_db_detachnode(db, &node); 6036 return (result); 6037 } 6038 6039 static isc_result_t 6040 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 6041 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, 6042 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception, 6043 isc_stdtime_t expire, isc_boolean_t check_ksk, 6044 isc_boolean_t keyset_kskonly) 6045 { 6046 isc_result_t result; 6047 dns_dbnode_t *node = NULL; 6048 dns_rdataset_t rdataset; 6049 dns_rdata_t sig_rdata = DNS_RDATA_INIT; 6050 unsigned char data[1024]; /* XXX */ 6051 isc_buffer_t buffer; 6052 unsigned int i, j; 6053 6054 dns_rdataset_init(&rdataset); 6055 isc_buffer_init(&buffer, data, sizeof(data)); 6056 6057 if (type == dns_rdatatype_nsec3) 6058 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node); 6059 else 6060 result = dns_db_findnode(db, name, ISC_FALSE, &node); 6061 if (result == ISC_R_NOTFOUND) 6062 return (ISC_R_SUCCESS); 6063 if (result != ISC_R_SUCCESS) 6064 goto failure; 6065 result = dns_db_findrdataset(db, node, ver, type, 0, 6066 (isc_stdtime_t) 0, &rdataset, NULL); 6067 dns_db_detachnode(db, &node); 6068 if (result == ISC_R_NOTFOUND) { 6069 INSIST(!dns_rdataset_isassociated(&rdataset)); 6070 return (ISC_R_SUCCESS); 6071 } 6072 if (result != ISC_R_SUCCESS) { 6073 INSIST(!dns_rdataset_isassociated(&rdataset)); 6074 goto failure; 6075 } 6076 6077 for (i = 0; i < nkeys; i++) { 6078 isc_boolean_t both = ISC_FALSE; 6079 6080 if (!dst_key_isprivate(keys[i])) 6081 continue; 6082 6083 if (check_ksk && !REVOKE(keys[i])) { 6084 isc_boolean_t have_ksk, have_nonksk; 6085 if (KSK(keys[i])) { 6086 have_ksk = ISC_TRUE; 6087 have_nonksk = ISC_FALSE; 6088 } else { 6089 have_ksk = ISC_FALSE; 6090 have_nonksk = ISC_TRUE; 6091 } 6092 for (j = 0; j < nkeys; j++) { 6093 if (j == i || ALG(keys[i]) != ALG(keys[j])) 6094 continue; 6095 if (REVOKE(keys[j])) 6096 continue; 6097 if (KSK(keys[j])) 6098 have_ksk = ISC_TRUE; 6099 else 6100 have_nonksk = ISC_TRUE; 6101 both = have_ksk && have_nonksk; 6102 if (both) 6103 break; 6104 } 6105 } 6106 if (both) { 6107 if (type == dns_rdatatype_dnskey) { 6108 if (!KSK(keys[i]) && keyset_kskonly) 6109 continue; 6110 } else if (KSK(keys[i])) 6111 continue; 6112 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) 6113 continue; 6114 6115 /* Calculate the signature, creating a RRSIG RDATA. */ 6116 isc_buffer_clear(&buffer); 6117 CHECK(dns_dnssec_sign(name, &rdataset, keys[i], 6118 &inception, &expire, 6119 mctx, &buffer, &sig_rdata)); 6120 /* Update the database and journal with the RRSIG. */ 6121 /* XXX inefficient - will cause dataset merging */ 6122 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, 6123 name, rdataset.ttl, &sig_rdata)); 6124 dns_rdata_reset(&sig_rdata); 6125 isc_buffer_init(&buffer, data, sizeof(data)); 6126 } 6127 6128 failure: 6129 if (dns_rdataset_isassociated(&rdataset)) 6130 dns_rdataset_disassociate(&rdataset); 6131 if (node != NULL) 6132 dns_db_detachnode(db, &node); 6133 return (result); 6134 } 6135 6136 static void 6137 zone_resigninc(dns_zone_t *zone) { 6138 const char *me = "zone_resigninc"; 6139 dns_db_t *db = NULL; 6140 dns_dbversion_t *version = NULL; 6141 dns_diff_t _sig_diff; 6142 zonediff_t zonediff; 6143 dns_fixedname_t fixed; 6144 dns_name_t *name; 6145 dns_rdataset_t rdataset; 6146 dns_rdatatype_t covers; 6147 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 6148 isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE; 6149 isc_result_t result; 6150 isc_stdtime_t now, inception, soaexpire, expire, stop; 6151 isc_uint32_t jitter; 6152 unsigned int i; 6153 unsigned int nkeys = 0; 6154 unsigned int resign; 6155 6156 ENTER; 6157 6158 dns_rdataset_init(&rdataset); 6159 dns_fixedname_init(&fixed); 6160 dns_diff_init(zone->mctx, &_sig_diff); 6161 zonediff_init(&zonediff, &_sig_diff); 6162 6163 /* 6164 * Zone is frozen or automatic resigning is disabled. 6165 * Pause for 5 minutes. 6166 */ 6167 if (zone->update_disabled || 6168 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN)) 6169 { 6170 result = ISC_R_FAILURE; 6171 goto failure; 6172 } 6173 6174 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 6175 dns_db_attach(zone->db, &db); 6176 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 6177 6178 result = dns_db_newversion(db, &version); 6179 if (result != ISC_R_SUCCESS) { 6180 dns_zone_log(zone, ISC_LOG_ERROR, 6181 "zone_resigninc:dns_db_newversion -> %s", 6182 dns_result_totext(result)); 6183 goto failure; 6184 } 6185 6186 result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS, 6187 zone_keys, &nkeys); 6188 if (result != ISC_R_SUCCESS) { 6189 dns_zone_log(zone, ISC_LOG_ERROR, 6190 "zone_resigninc:find_zone_keys -> %s", 6191 dns_result_totext(result)); 6192 goto failure; 6193 } 6194 6195 isc_stdtime_get(&now); 6196 inception = now - 3600; /* Allow for clock skew. */ 6197 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 6198 /* 6199 * Spread out signatures over time if they happen to be 6200 * clumped. We don't do this for each add_sigs() call as 6201 * we still want some clustering to occur. 6202 */ 6203 isc_random_get(&jitter); 6204 expire = soaexpire - jitter % 3600; 6205 stop = now + 5; 6206 6207 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 6208 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 6209 6210 name = dns_fixedname_name(&fixed); 6211 result = dns_db_getsigningtime(db, &rdataset, name); 6212 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 6213 dns_zone_log(zone, ISC_LOG_ERROR, 6214 "zone_resigninc:dns_db_getsigningtime -> %s", 6215 dns_result_totext(result)); 6216 } 6217 6218 i = 0; 6219 while (result == ISC_R_SUCCESS) { 6220 resign = rdataset.resign - zone->sigresigninginterval; 6221 covers = rdataset.covers; 6222 dns_rdataset_disassociate(&rdataset); 6223 6224 /* 6225 * Stop if we hit the SOA as that means we have walked the 6226 * entire zone. The SOA record should always be the most 6227 * recent signature. 6228 */ 6229 /* XXXMPA increase number of RRsets signed pre call */ 6230 if (covers == dns_rdatatype_soa || i++ > zone->signatures || 6231 resign > stop) 6232 break; 6233 6234 result = del_sigs(zone, db, version, name, covers, &zonediff, 6235 zone_keys, nkeys, now, ISC_TRUE); 6236 if (result != ISC_R_SUCCESS) { 6237 dns_zone_log(zone, ISC_LOG_ERROR, 6238 "zone_resigninc:del_sigs -> %s", 6239 dns_result_totext(result)); 6240 break; 6241 } 6242 6243 result = add_sigs(db, version, name, covers, zonediff.diff, 6244 zone_keys, nkeys, zone->mctx, inception, 6245 expire, check_ksk, keyset_kskonly); 6246 if (result != ISC_R_SUCCESS) { 6247 dns_zone_log(zone, ISC_LOG_ERROR, 6248 "zone_resigninc:add_sigs -> %s", 6249 dns_result_totext(result)); 6250 break; 6251 } 6252 result = dns_db_getsigningtime(db, &rdataset, name); 6253 if (nkeys == 0 && result == ISC_R_NOTFOUND) { 6254 result = ISC_R_SUCCESS; 6255 break; 6256 } 6257 if (result != ISC_R_SUCCESS) 6258 dns_zone_log(zone, ISC_LOG_ERROR, 6259 "zone_resigninc:dns_db_getsigningtime -> %s", 6260 dns_result_totext(result)); 6261 } 6262 6263 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS) 6264 goto failure; 6265 6266 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 6267 &zonediff, zone_keys, nkeys, now, ISC_TRUE); 6268 if (result != ISC_R_SUCCESS) { 6269 dns_zone_log(zone, ISC_LOG_ERROR, 6270 "zone_resigninc:del_sigs -> %s", 6271 dns_result_totext(result)); 6272 goto failure; 6273 } 6274 6275 /* 6276 * Did we change anything in the zone? 6277 */ 6278 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 6279 /* 6280 * Commit the changes if any key has been marked as offline. */ 6281 if (zonediff.offline) 6282 dns_db_closeversion(db, &version, ISC_TRUE); 6283 goto failure; 6284 } 6285 6286 /* Increment SOA serial if we have made changes */ 6287 result = update_soa_serial(db, version, zonediff.diff, zone->mctx, 6288 zone->updatemethod); 6289 if (result != ISC_R_SUCCESS) { 6290 dns_zone_log(zone, ISC_LOG_ERROR, 6291 "zone_resigninc:update_soa_serial -> %s", 6292 dns_result_totext(result)); 6293 goto failure; 6294 } 6295 6296 /* 6297 * Generate maximum life time signatures so that the above loop 6298 * termination is sensible. 6299 */ 6300 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, 6301 zonediff.diff, zone_keys, nkeys, zone->mctx, 6302 inception, soaexpire, check_ksk, keyset_kskonly); 6303 if (result != ISC_R_SUCCESS) { 6304 dns_zone_log(zone, ISC_LOG_ERROR, 6305 "zone_resigninc:add_sigs -> %s", 6306 dns_result_totext(result)); 6307 goto failure; 6308 } 6309 6310 /* Write changes to journal file. */ 6311 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc")); 6312 6313 /* Everything has succeeded. Commit the changes. */ 6314 dns_db_closeversion(db, &version, ISC_TRUE); 6315 6316 failure: 6317 dns_diff_clear(&_sig_diff); 6318 for (i = 0; i < nkeys; i++) 6319 dst_key_free(&zone_keys[i]); 6320 if (version != NULL) { 6321 dns_db_closeversion(zone->db, &version, ISC_FALSE); 6322 dns_db_detach(&db); 6323 } else if (db != NULL) 6324 dns_db_detach(&db); 6325 if (result == ISC_R_SUCCESS) { 6326 set_resigntime(zone); 6327 LOCK_ZONE(zone); 6328 zone_needdump(zone, DNS_DUMP_DELAY); 6329 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 6330 UNLOCK_ZONE(zone); 6331 } else { 6332 /* 6333 * Something failed. Retry in 5 minutes. 6334 */ 6335 isc_interval_t ival; 6336 isc_interval_set(&ival, 300, 0); 6337 isc_time_nowplusinterval(&zone->resigntime, &ival); 6338 } 6339 6340 INSIST(version == NULL); 6341 } 6342 6343 static isc_result_t 6344 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname, 6345 dns_name_t *newname, isc_boolean_t bottom) 6346 { 6347 isc_result_t result; 6348 dns_dbiterator_t *dbit = NULL; 6349 dns_rdatasetiter_t *rdsit = NULL; 6350 dns_dbnode_t *node = NULL; 6351 6352 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit)); 6353 CHECK(dns_dbiterator_seek(dbit, oldname)); 6354 do { 6355 result = dns_dbiterator_next(dbit); 6356 if (result == ISC_R_NOMORE) 6357 CHECK(dns_dbiterator_first(dbit)); 6358 CHECK(dns_dbiterator_current(dbit, &node, newname)); 6359 if (bottom && dns_name_issubdomain(newname, oldname) && 6360 !dns_name_equal(newname, oldname)) { 6361 dns_db_detachnode(db, &node); 6362 continue; 6363 } 6364 /* 6365 * Is this node empty? 6366 */ 6367 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit)); 6368 result = dns_rdatasetiter_first(rdsit); 6369 dns_db_detachnode(db, &node); 6370 dns_rdatasetiter_destroy(&rdsit); 6371 if (result != ISC_R_NOMORE) 6372 break; 6373 } while (1); 6374 failure: 6375 if (node != NULL) 6376 dns_db_detachnode(db, &node); 6377 if (dbit != NULL) 6378 dns_dbiterator_destroy(&dbit); 6379 return (result); 6380 } 6381 6382 static isc_boolean_t 6383 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 6384 dns_rdatatype_t type, dst_key_t *key) 6385 { 6386 isc_result_t result; 6387 dns_rdataset_t rdataset; 6388 dns_rdata_t rdata = DNS_RDATA_INIT; 6389 dns_rdata_rrsig_t rrsig; 6390 6391 dns_rdataset_init(&rdataset); 6392 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig, 6393 type, 0, &rdataset, NULL); 6394 if (result != ISC_R_SUCCESS) { 6395 INSIST(!dns_rdataset_isassociated(&rdataset)); 6396 return (ISC_FALSE); 6397 } 6398 for (result = dns_rdataset_first(&rdataset); 6399 result == ISC_R_SUCCESS; 6400 result = dns_rdataset_next(&rdataset)) { 6401 dns_rdataset_current(&rdataset, &rdata); 6402 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 6403 INSIST(result == ISC_R_SUCCESS); 6404 if (rrsig.algorithm == dst_key_alg(key) && 6405 rrsig.keyid == dst_key_id(key)) { 6406 dns_rdataset_disassociate(&rdataset); 6407 return (ISC_TRUE); 6408 } 6409 dns_rdata_reset(&rdata); 6410 } 6411 dns_rdataset_disassociate(&rdataset); 6412 return (ISC_FALSE); 6413 } 6414 6415 static isc_result_t 6416 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 6417 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom, 6418 dns_diff_t *diff) 6419 { 6420 dns_fixedname_t fixed; 6421 dns_name_t *next; 6422 dns_rdata_t rdata = DNS_RDATA_INIT; 6423 isc_result_t result; 6424 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE]; 6425 6426 dns_fixedname_init(&fixed); 6427 next = dns_fixedname_name(&fixed); 6428 6429 CHECK(next_active(db, version, name, next, bottom)); 6430 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer, 6431 &rdata)); 6432 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl, 6433 &rdata)); 6434 failure: 6435 return (result); 6436 } 6437 6438 static isc_result_t 6439 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node, 6440 dns_dbversion_t *version, isc_boolean_t build_nsec3, 6441 isc_boolean_t build_nsec, dst_key_t *key, 6442 isc_stdtime_t inception, isc_stdtime_t expire, 6443 unsigned int minimum, isc_boolean_t is_ksk, 6444 isc_boolean_t keyset_kskonly, isc_boolean_t *delegation, 6445 dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx) 6446 { 6447 isc_result_t result; 6448 dns_rdatasetiter_t *iterator = NULL; 6449 dns_rdataset_t rdataset; 6450 dns_rdata_t rdata = DNS_RDATA_INIT; 6451 isc_buffer_t buffer; 6452 unsigned char data[1024]; 6453 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec, 6454 seen_nsec3, seen_ds; 6455 isc_boolean_t bottom; 6456 6457 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 6458 if (result != ISC_R_SUCCESS) { 6459 if (result == ISC_R_NOTFOUND) 6460 result = ISC_R_SUCCESS; 6461 return (result); 6462 } 6463 6464 dns_rdataset_init(&rdataset); 6465 isc_buffer_init(&buffer, data, sizeof(data)); 6466 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec = 6467 seen_nsec3 = seen_ds = ISC_FALSE; 6468 for (result = dns_rdatasetiter_first(iterator); 6469 result == ISC_R_SUCCESS; 6470 result = dns_rdatasetiter_next(iterator)) { 6471 dns_rdatasetiter_current(iterator, &rdataset); 6472 if (rdataset.type == dns_rdatatype_soa) 6473 seen_soa = ISC_TRUE; 6474 else if (rdataset.type == dns_rdatatype_ns) 6475 seen_ns = ISC_TRUE; 6476 else if (rdataset.type == dns_rdatatype_ds) 6477 seen_ds = ISC_TRUE; 6478 else if (rdataset.type == dns_rdatatype_dname) 6479 seen_dname = ISC_TRUE; 6480 else if (rdataset.type == dns_rdatatype_nsec) 6481 seen_nsec = ISC_TRUE; 6482 else if (rdataset.type == dns_rdatatype_nsec3) 6483 seen_nsec3 = ISC_TRUE; 6484 if (rdataset.type != dns_rdatatype_rrsig) 6485 seen_rr = ISC_TRUE; 6486 dns_rdataset_disassociate(&rdataset); 6487 } 6488 if (result != ISC_R_NOMORE) 6489 goto failure; 6490 if (seen_ns && !seen_soa) 6491 *delegation = ISC_TRUE; 6492 /* 6493 * Going from insecure to NSEC3. 6494 * Don't generate NSEC3 records for NSEC3 records. 6495 */ 6496 if (build_nsec3 && !seen_nsec3 && seen_rr) { 6497 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa; 6498 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum, 6499 unsecure, diff)); 6500 (*signatures)--; 6501 } 6502 /* 6503 * Going from insecure to NSEC. 6504 * Don't generate NSEC records for NSEC3 records. 6505 */ 6506 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) { 6507 /* Build and add NSEC. */ 6508 bottom = (seen_ns && !seen_soa) || seen_dname; 6509 /* 6510 * Build a NSEC record except at the origin. 6511 */ 6512 if (!dns_name_equal(name, dns_db_origin(db))) { 6513 CHECK(add_nsec(db, version, name, node, minimum, 6514 bottom, diff)); 6515 /* Count a NSEC generation as a signature generation. */ 6516 (*signatures)--; 6517 } 6518 } 6519 result = dns_rdatasetiter_first(iterator); 6520 while (result == ISC_R_SUCCESS) { 6521 dns_rdatasetiter_current(iterator, &rdataset); 6522 if (rdataset.type == dns_rdatatype_soa || 6523 rdataset.type == dns_rdatatype_rrsig) 6524 goto next_rdataset; 6525 if (rdataset.type == dns_rdatatype_dnskey) { 6526 if (!is_ksk && keyset_kskonly) 6527 goto next_rdataset; 6528 } else if (is_ksk) 6529 goto next_rdataset; 6530 if (*delegation && 6531 rdataset.type != dns_rdatatype_ds && 6532 rdataset.type != dns_rdatatype_nsec) 6533 goto next_rdataset; 6534 if (signed_with_key(db, node, version, rdataset.type, key)) 6535 goto next_rdataset; 6536 /* Calculate the signature, creating a RRSIG RDATA. */ 6537 isc_buffer_clear(&buffer); 6538 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception, 6539 &expire, mctx, &buffer, &rdata)); 6540 /* Update the database and journal with the RRSIG. */ 6541 /* XXX inefficient - will cause dataset merging */ 6542 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN, 6543 name, rdataset.ttl, &rdata)); 6544 dns_rdata_reset(&rdata); 6545 (*signatures)--; 6546 next_rdataset: 6547 dns_rdataset_disassociate(&rdataset); 6548 result = dns_rdatasetiter_next(iterator); 6549 } 6550 if (result == ISC_R_NOMORE) 6551 result = ISC_R_SUCCESS; 6552 if (seen_dname) 6553 *delegation = ISC_TRUE; 6554 failure: 6555 if (dns_rdataset_isassociated(&rdataset)) 6556 dns_rdataset_disassociate(&rdataset); 6557 if (iterator != NULL) 6558 dns_rdatasetiter_destroy(&iterator); 6559 return (result); 6560 } 6561 6562 /* 6563 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist. 6564 */ 6565 static isc_result_t 6566 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 6567 dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff) 6568 { 6569 isc_result_t result; 6570 dns_rdataset_t rdataset; 6571 dns_dbnode_t *node = NULL; 6572 6573 CHECK(dns_db_getoriginnode(db, &node)); 6574 if (update_only) { 6575 dns_rdataset_init(&rdataset); 6576 result = dns_db_findrdataset(db, node, version, 6577 dns_rdatatype_nsec, 6578 dns_rdatatype_none, 6579 0, &rdataset, NULL); 6580 if (dns_rdataset_isassociated(&rdataset)) 6581 dns_rdataset_disassociate(&rdataset); 6582 if (result == ISC_R_NOTFOUND) 6583 goto success; 6584 if (result != ISC_R_SUCCESS) 6585 goto failure; 6586 } 6587 CHECK(delete_nsec(db, version, node, name, diff)); 6588 CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff)); 6589 success: 6590 result = ISC_R_SUCCESS; 6591 failure: 6592 if (node != NULL) 6593 dns_db_detachnode(db, &node); 6594 return (result); 6595 } 6596 6597 static isc_result_t 6598 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing, 6599 dns_dbversion_t *version, isc_boolean_t build_nsec3, 6600 dns_ttl_t minimum, dns_diff_t *diff) 6601 { 6602 isc_result_t result; 6603 dns_dbnode_t *node = NULL; 6604 dns_rdataset_t rdataset; 6605 dns_rdata_t rdata = DNS_RDATA_INIT; 6606 unsigned char data[5]; 6607 isc_boolean_t seen_done = ISC_FALSE; 6608 isc_boolean_t have_rr = ISC_FALSE; 6609 6610 dns_rdataset_init(&rdataset); 6611 result = dns_db_getoriginnode(signing->db, &node); 6612 if (result != ISC_R_SUCCESS) 6613 goto failure; 6614 6615 result = dns_db_findrdataset(signing->db, node, version, 6616 zone->privatetype, dns_rdatatype_none, 6617 0, &rdataset, NULL); 6618 if (result == ISC_R_NOTFOUND) { 6619 INSIST(!dns_rdataset_isassociated(&rdataset)); 6620 result = ISC_R_SUCCESS; 6621 goto failure; 6622 } 6623 if (result != ISC_R_SUCCESS) { 6624 INSIST(!dns_rdataset_isassociated(&rdataset)); 6625 goto failure; 6626 } 6627 for (result = dns_rdataset_first(&rdataset); 6628 result == ISC_R_SUCCESS; 6629 result = dns_rdataset_next(&rdataset)) { 6630 dns_rdataset_current(&rdataset, &rdata); 6631 /* 6632 * If we don't match the algorithm or keyid skip the record. 6633 */ 6634 if (rdata.length != 5 || 6635 rdata.data[0] != signing->algorithm || 6636 rdata.data[1] != ((signing->keyid >> 8) & 0xff) || 6637 rdata.data[2] != (signing->keyid & 0xff)) { 6638 have_rr = ISC_TRUE; 6639 dns_rdata_reset(&rdata); 6640 continue; 6641 } 6642 /* 6643 * We have a match. If we were signing (!signing->delete) 6644 * and we already have a record indicating that we have 6645 * finished signing (rdata.data[4] != 0) then keep it. 6646 * Otherwise it needs to be deleted as we have removed all 6647 * the signatures (signing->delete), so any record indicating 6648 * completion is now out of date, or we have finished signing 6649 * with the new record so we no longer need to remember that 6650 * we need to sign the zone with the matching key across a 6651 * nameserver re-start. 6652 */ 6653 if (!signing->delete && rdata.data[4] != 0) { 6654 seen_done = ISC_TRUE; 6655 have_rr = ISC_TRUE; 6656 } else 6657 CHECK(update_one_rr(signing->db, version, diff, 6658 DNS_DIFFOP_DEL, &zone->origin, 6659 rdataset.ttl, &rdata)); 6660 dns_rdata_reset(&rdata); 6661 } 6662 if (result == ISC_R_NOMORE) 6663 result = ISC_R_SUCCESS; 6664 if (!signing->delete && !seen_done) { 6665 /* 6666 * If we were signing then we need to indicate that we have 6667 * finished signing the zone with this key. If it is already 6668 * there we don't need to add it a second time. 6669 */ 6670 data[0] = signing->algorithm; 6671 data[1] = (signing->keyid >> 8) & 0xff; 6672 data[2] = signing->keyid & 0xff; 6673 data[3] = 0; 6674 data[4] = 1; 6675 rdata.length = sizeof(data); 6676 rdata.data = data; 6677 rdata.type = zone->privatetype; 6678 rdata.rdclass = dns_db_class(signing->db); 6679 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD, 6680 &zone->origin, rdataset.ttl, &rdata)); 6681 } else if (!have_rr) { 6682 dns_name_t *origin = dns_db_origin(signing->db); 6683 /* 6684 * Rebuild the NSEC/NSEC3 record for the origin as we no 6685 * longer have any private records. 6686 */ 6687 if (build_nsec3) 6688 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin, 6689 minimum, ISC_FALSE, diff)); 6690 CHECK(updatesecure(signing->db, version, origin, minimum, 6691 ISC_TRUE, diff)); 6692 } 6693 6694 failure: 6695 if (dns_rdataset_isassociated(&rdataset)) 6696 dns_rdataset_disassociate(&rdataset); 6697 if (node != NULL) 6698 dns_db_detachnode(signing->db, &node); 6699 return (result); 6700 } 6701 6702 /* 6703 * If 'active' is set then we are not done with the chain yet so only 6704 * delete the nsec3param record which indicates a full chain exists 6705 * (flags == 0). 6706 */ 6707 static isc_result_t 6708 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain, 6709 isc_boolean_t active, dns_rdatatype_t privatetype, 6710 dns_diff_t *diff) 6711 { 6712 dns_dbnode_t *node = NULL; 6713 dns_name_t *name = dns_db_origin(db); 6714 dns_rdata_t rdata = DNS_RDATA_INIT; 6715 dns_rdataset_t rdataset; 6716 dns_rdata_nsec3param_t nsec3param; 6717 isc_result_t result; 6718 isc_buffer_t buffer; 6719 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE]; 6720 dns_ttl_t ttl = 0; 6721 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; 6722 6723 dns_rdataset_init(&rdataset); 6724 6725 result = dns_db_getoriginnode(db, &node); 6726 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6727 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 6728 0, 0, &rdataset, NULL); 6729 if (result == ISC_R_NOTFOUND) 6730 goto try_private; 6731 if (result != ISC_R_SUCCESS) 6732 goto failure; 6733 6734 /* 6735 * Preserve the existing ttl. 6736 */ 6737 ttl = rdataset.ttl; 6738 6739 /* 6740 * Delete all NSEC3PARAM records which match that in nsec3chain. 6741 */ 6742 for (result = dns_rdataset_first(&rdataset); 6743 result == ISC_R_SUCCESS; 6744 result = dns_rdataset_next(&rdataset)) { 6745 6746 dns_rdataset_current(&rdataset, &rdata); 6747 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 6748 6749 if (nsec3param.hash != chain->nsec3param.hash || 6750 (active && nsec3param.flags != 0) || 6751 nsec3param.iterations != chain->nsec3param.iterations || 6752 nsec3param.salt_length != chain->nsec3param.salt_length || 6753 memcmp(nsec3param.salt, chain->nsec3param.salt, 6754 nsec3param.salt_length)) { 6755 dns_rdata_reset(&rdata); 6756 continue; 6757 } 6758 6759 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, 6760 name, rdataset.ttl, &rdata)); 6761 dns_rdata_reset(&rdata); 6762 } 6763 if (result != ISC_R_NOMORE) 6764 goto failure; 6765 6766 dns_rdataset_disassociate(&rdataset); 6767 6768 try_private: 6769 6770 if (active) 6771 goto add; 6772 6773 result = dns_nsec_nseconly(db, ver, &nseconly); 6774 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 6775 6776 /* 6777 * Delete all private records which match that in nsec3chain. 6778 */ 6779 result = dns_db_findrdataset(db, node, ver, privatetype, 6780 0, 0, &rdataset, NULL); 6781 if (result == ISC_R_NOTFOUND) 6782 goto add; 6783 if (result != ISC_R_SUCCESS) 6784 goto failure; 6785 6786 for (result = dns_rdataset_first(&rdataset); 6787 result == ISC_R_SUCCESS; 6788 result = dns_rdataset_next(&rdataset)) { 6789 dns_rdata_t private = DNS_RDATA_INIT; 6790 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 6791 6792 dns_rdataset_current(&rdataset, &private); 6793 if (!dns_nsec3param_fromprivate(&private, &rdata, 6794 buf, sizeof(buf))) 6795 continue; 6796 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 6797 6798 if ((!nsec3ok && 6799 (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) || 6800 nsec3param.hash != chain->nsec3param.hash || 6801 nsec3param.iterations != chain->nsec3param.iterations || 6802 nsec3param.salt_length != chain->nsec3param.salt_length || 6803 memcmp(nsec3param.salt, chain->nsec3param.salt, 6804 nsec3param.salt_length)) { 6805 dns_rdata_reset(&rdata); 6806 continue; 6807 } 6808 6809 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, 6810 name, rdataset.ttl, &private)); 6811 dns_rdata_reset(&rdata); 6812 } 6813 if (result != ISC_R_NOMORE) 6814 goto failure; 6815 6816 add: 6817 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) { 6818 result = ISC_R_SUCCESS; 6819 goto failure; 6820 } 6821 6822 /* 6823 * Add a NSEC3PARAM record which matches that in nsec3chain but 6824 * with all flags bits cleared. 6825 * 6826 * Note: we do not clear chain->nsec3param.flags as this change 6827 * may be reversed. 6828 */ 6829 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf)); 6830 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), 6831 dns_rdatatype_nsec3param, 6832 &chain->nsec3param, &buffer)); 6833 rdata.data[1] = 0; /* Clear flag bits. */ 6834 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata)); 6835 6836 failure: 6837 dns_db_detachnode(db, &node); 6838 if (dns_rdataset_isassociated(&rdataset)) 6839 dns_rdataset_disassociate(&rdataset); 6840 return (result); 6841 } 6842 6843 static isc_result_t 6844 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 6845 dns_name_t *name, dns_diff_t *diff) 6846 { 6847 dns_rdataset_t rdataset; 6848 isc_result_t result; 6849 6850 dns_rdataset_init(&rdataset); 6851 6852 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 6853 0, 0, &rdataset, NULL); 6854 if (result == ISC_R_NOTFOUND) 6855 return (ISC_R_SUCCESS); 6856 if (result != ISC_R_SUCCESS) 6857 return (result); 6858 for (result = dns_rdataset_first(&rdataset); 6859 result == ISC_R_SUCCESS; 6860 result = dns_rdataset_next(&rdataset)) { 6861 dns_rdata_t rdata = DNS_RDATA_INIT; 6862 6863 dns_rdataset_current(&rdataset, &rdata); 6864 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 6865 rdataset.ttl, &rdata)); 6866 } 6867 if (result == ISC_R_NOMORE) 6868 result = ISC_R_SUCCESS; 6869 failure: 6870 dns_rdataset_disassociate(&rdataset); 6871 return (result); 6872 } 6873 6874 static isc_result_t 6875 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 6876 dns_name_t *name, const dns_rdata_nsec3param_t *param, 6877 dns_diff_t *diff) 6878 { 6879 dns_rdataset_t rdataset; 6880 dns_rdata_nsec3_t nsec3; 6881 isc_result_t result; 6882 6883 dns_rdataset_init(&rdataset); 6884 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 6885 0, 0, &rdataset, NULL); 6886 if (result == ISC_R_NOTFOUND) 6887 return (ISC_R_SUCCESS); 6888 if (result != ISC_R_SUCCESS) 6889 return (result); 6890 6891 for (result = dns_rdataset_first(&rdataset); 6892 result == ISC_R_SUCCESS; 6893 result = dns_rdataset_next(&rdataset)) { 6894 dns_rdata_t rdata = DNS_RDATA_INIT; 6895 6896 dns_rdataset_current(&rdataset, &rdata); 6897 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL)); 6898 if (nsec3.hash != param->hash || 6899 nsec3.iterations != param->iterations || 6900 nsec3.salt_length != param->salt_length || 6901 memcmp(nsec3.salt, param->salt, nsec3.salt_length)) 6902 continue; 6903 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 6904 rdataset.ttl, &rdata)); 6905 } 6906 if (result == ISC_R_NOMORE) 6907 result = ISC_R_SUCCESS; 6908 failure: 6909 dns_rdataset_disassociate(&rdataset); 6910 return (result); 6911 } 6912 6913 static isc_result_t 6914 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver, 6915 const dns_rdata_nsec3param_t *param, 6916 isc_boolean_t *answer) 6917 { 6918 dns_dbnode_t *node = NULL; 6919 dns_rdata_t rdata = DNS_RDATA_INIT; 6920 dns_rdata_nsec3param_t myparam; 6921 dns_rdataset_t rdataset; 6922 isc_result_t result; 6923 6924 *answer = ISC_FALSE; 6925 6926 result = dns_db_getoriginnode(db, &node); 6927 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6928 6929 dns_rdataset_init(&rdataset); 6930 6931 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 6932 0, 0, &rdataset, NULL); 6933 if (result == ISC_R_SUCCESS) { 6934 dns_rdataset_disassociate(&rdataset); 6935 dns_db_detachnode(db, &node); 6936 return (result); 6937 } 6938 if (result != ISC_R_NOTFOUND) { 6939 dns_db_detachnode(db, &node); 6940 return (result); 6941 } 6942 6943 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 6944 0, 0, &rdataset, NULL); 6945 if (result == ISC_R_NOTFOUND) { 6946 *answer = ISC_TRUE; 6947 dns_db_detachnode(db, &node); 6948 return (ISC_R_SUCCESS); 6949 } 6950 if (result != ISC_R_SUCCESS) { 6951 dns_db_detachnode(db, &node); 6952 return (result); 6953 } 6954 6955 for (result = dns_rdataset_first(&rdataset); 6956 result == ISC_R_SUCCESS; 6957 result = dns_rdataset_next(&rdataset)) { 6958 dns_rdataset_current(&rdataset, &rdata); 6959 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL)); 6960 dns_rdata_reset(&rdata); 6961 /* 6962 * Ignore any NSEC3PARAM removals. 6963 */ 6964 if (NSEC3REMOVE(myparam.flags)) 6965 continue; 6966 /* 6967 * Ignore the chain that we are in the process of deleting. 6968 */ 6969 if (myparam.hash == param->hash && 6970 myparam.iterations == param->iterations && 6971 myparam.salt_length == param->salt_length && 6972 !memcmp(myparam.salt, param->salt, myparam.salt_length)) 6973 continue; 6974 /* 6975 * Found an active NSEC3 chain. 6976 */ 6977 break; 6978 } 6979 if (result == ISC_R_NOMORE) { 6980 *answer = ISC_TRUE; 6981 result = ISC_R_SUCCESS; 6982 } 6983 6984 failure: 6985 if (dns_rdataset_isassociated(&rdataset)) 6986 dns_rdataset_disassociate(&rdataset); 6987 dns_db_detachnode(db, &node); 6988 return (result); 6989 } 6990 6991 static isc_result_t 6992 update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, 6993 dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone, 6994 isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now, 6995 isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly, 6996 zonediff_t *zonediff) 6997 { 6998 dns_difftuple_t *tuple; 6999 isc_result_t result; 7000 7001 for (tuple = ISC_LIST_HEAD(diff->tuples); 7002 tuple != NULL; 7003 tuple = ISC_LIST_HEAD(diff->tuples)) { 7004 result = del_sigs(zone, db, version, &tuple->name, 7005 tuple->rdata.type, zonediff, 7006 zone_keys, nkeys, now, ISC_FALSE); 7007 if (result != ISC_R_SUCCESS) { 7008 dns_zone_log(zone, ISC_LOG_ERROR, 7009 "update_sigs:del_sigs -> %s", 7010 dns_result_totext(result)); 7011 return (result); 7012 } 7013 result = add_sigs(db, version, &tuple->name, 7014 tuple->rdata.type, zonediff->diff, 7015 zone_keys, nkeys, zone->mctx, inception, 7016 expire, check_ksk, keyset_kskonly); 7017 if (result != ISC_R_SUCCESS) { 7018 dns_zone_log(zone, ISC_LOG_ERROR, 7019 "update_sigs:add_sigs -> %s", 7020 dns_result_totext(result)); 7021 return (result); 7022 } 7023 7024 do { 7025 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link); 7026 while (next != NULL && 7027 (tuple->rdata.type != next->rdata.type || 7028 !dns_name_equal(&tuple->name, &next->name))) 7029 next = ISC_LIST_NEXT(next, link); 7030 ISC_LIST_UNLINK(diff->tuples, tuple, link); 7031 dns_diff_appendminimal(zonediff->diff, &tuple); 7032 INSIST(tuple == NULL); 7033 tuple = next; 7034 } while (tuple != NULL); 7035 } 7036 return (ISC_R_SUCCESS); 7037 } 7038 7039 /* 7040 * Incrementally build and sign a new NSEC3 chain using the parameters 7041 * requested. 7042 */ 7043 static void 7044 zone_nsec3chain(dns_zone_t *zone) { 7045 const char *me = "zone_nsec3chain"; 7046 dns_db_t *db = NULL; 7047 dns_dbnode_t *node = NULL; 7048 dns_dbversion_t *version = NULL; 7049 dns_diff_t _sig_diff; 7050 dns_diff_t nsec_diff; 7051 dns_diff_t nsec3_diff; 7052 dns_diff_t param_diff; 7053 zonediff_t zonediff; 7054 dns_fixedname_t fixed; 7055 dns_fixedname_t nextfixed; 7056 dns_name_t *name, *nextname; 7057 dns_rdataset_t rdataset; 7058 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain; 7059 dns_nsec3chainlist_t cleanup; 7060 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 7061 isc_int32_t signatures; 7062 isc_boolean_t check_ksk, keyset_kskonly; 7063 isc_boolean_t delegation; 7064 isc_boolean_t first; 7065 isc_result_t result; 7066 isc_stdtime_t now, inception, soaexpire, expire; 7067 isc_uint32_t jitter; 7068 unsigned int i; 7069 unsigned int nkeys = 0; 7070 isc_uint32_t nodes; 7071 isc_boolean_t unsecure = ISC_FALSE; 7072 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds; 7073 isc_boolean_t seen_nsec, seen_nsec3, seen_rr; 7074 dns_rdatasetiter_t *iterator = NULL; 7075 isc_boolean_t buildnsecchain; 7076 isc_boolean_t updatensec = ISC_FALSE; 7077 dns_rdatatype_t privatetype = zone->privatetype; 7078 7079 ENTER; 7080 7081 dns_rdataset_init(&rdataset); 7082 dns_fixedname_init(&fixed); 7083 name = dns_fixedname_name(&fixed); 7084 dns_fixedname_init(&nextfixed); 7085 nextname = dns_fixedname_name(&nextfixed); 7086 dns_diff_init(zone->mctx, ¶m_diff); 7087 dns_diff_init(zone->mctx, &nsec3_diff); 7088 dns_diff_init(zone->mctx, &nsec_diff); 7089 dns_diff_init(zone->mctx, &_sig_diff); 7090 zonediff_init(&zonediff, &_sig_diff); 7091 ISC_LIST_INIT(cleanup); 7092 7093 /* 7094 * Updates are disabled. Pause for 5 minutes. 7095 */ 7096 if (zone->update_disabled) { 7097 result = ISC_R_FAILURE; 7098 goto failure; 7099 } 7100 7101 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 7102 dns_db_attach(zone->db, &db); 7103 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 7104 7105 result = dns_db_newversion(db, &version); 7106 if (result != ISC_R_SUCCESS) { 7107 dns_zone_log(zone, ISC_LOG_ERROR, 7108 "zone_nsec3chain:dns_db_newversion -> %s", 7109 dns_result_totext(result)); 7110 goto failure; 7111 } 7112 7113 result = find_zone_keys(zone, db, version, zone->mctx, 7114 DNS_MAXZONEKEYS, zone_keys, &nkeys); 7115 if (result != ISC_R_SUCCESS) { 7116 dns_zone_log(zone, ISC_LOG_ERROR, 7117 "zone_nsec3chain:find_zone_keys -> %s", 7118 dns_result_totext(result)); 7119 goto failure; 7120 } 7121 7122 isc_stdtime_get(&now); 7123 inception = now - 3600; /* Allow for clock skew. */ 7124 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 7125 7126 /* 7127 * Spread out signatures over time if they happen to be 7128 * clumped. We don't do this for each add_sigs() call as 7129 * we still want some clustering to occur. 7130 */ 7131 isc_random_get(&jitter); 7132 expire = soaexpire - jitter % 3600; 7133 7134 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 7135 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 7136 7137 /* 7138 * We keep pulling nodes off each iterator in turn until 7139 * we have no more nodes to pull off or we reach the limits 7140 * for this quantum. 7141 */ 7142 nodes = zone->nodes; 7143 signatures = zone->signatures; 7144 LOCK_ZONE(zone); 7145 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 7146 UNLOCK_ZONE(zone); 7147 first = ISC_TRUE; 7148 7149 if (nsec3chain != NULL) 7150 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 7151 /* 7152 * Generate new NSEC3 chains first. 7153 */ 7154 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 7155 LOCK_ZONE(zone); 7156 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 7157 7158 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 7159 if (nsec3chain->done || nsec3chain->db != zone->db) { 7160 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 7161 ISC_LIST_APPEND(cleanup, nsec3chain, link); 7162 } 7163 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 7164 UNLOCK_ZONE(zone); 7165 if (ISC_LIST_TAIL(cleanup) == nsec3chain) 7166 goto next_addchain; 7167 7168 /* 7169 * Possible future db. 7170 */ 7171 if (nsec3chain->db != db) { 7172 goto next_addchain; 7173 } 7174 7175 if (NSEC3REMOVE(nsec3chain->nsec3param.flags)) 7176 goto next_addchain; 7177 7178 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 7179 7180 if (nsec3chain->delete_nsec) { 7181 delegation = ISC_FALSE; 7182 dns_dbiterator_pause(nsec3chain->dbiterator); 7183 CHECK(delete_nsec(db, version, node, name, &nsec_diff)); 7184 goto next_addnode; 7185 } 7186 /* 7187 * On the first pass we need to check if the current node 7188 * has not been obscured. 7189 */ 7190 delegation = ISC_FALSE; 7191 unsecure = ISC_FALSE; 7192 if (first) { 7193 dns_fixedname_t ffound; 7194 dns_name_t *found; 7195 dns_fixedname_init(&ffound); 7196 found = dns_fixedname_name(&ffound); 7197 result = dns_db_find(db, name, version, 7198 dns_rdatatype_soa, 7199 DNS_DBFIND_NOWILD, 0, NULL, found, 7200 NULL, NULL); 7201 if ((result == DNS_R_DELEGATION || 7202 result == DNS_R_DNAME) && 7203 !dns_name_equal(name, found)) { 7204 /* 7205 * Remember the obscuring name so that 7206 * we skip all obscured names. 7207 */ 7208 dns_name_copy(found, name, NULL); 7209 delegation = ISC_TRUE; 7210 goto next_addnode; 7211 } 7212 } 7213 7214 /* 7215 * Check to see if this is a bottom of zone node. 7216 */ 7217 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 7218 if (result == ISC_R_NOTFOUND) /* Empty node? */ 7219 goto next_addnode; 7220 if (result != ISC_R_SUCCESS) 7221 goto failure; 7222 7223 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = 7224 ISC_FALSE; 7225 for (result = dns_rdatasetiter_first(iterator); 7226 result == ISC_R_SUCCESS; 7227 result = dns_rdatasetiter_next(iterator)) { 7228 dns_rdatasetiter_current(iterator, &rdataset); 7229 INSIST(rdataset.type != dns_rdatatype_nsec3); 7230 if (rdataset.type == dns_rdatatype_soa) 7231 seen_soa = ISC_TRUE; 7232 else if (rdataset.type == dns_rdatatype_ns) 7233 seen_ns = ISC_TRUE; 7234 else if (rdataset.type == dns_rdatatype_dname) 7235 seen_dname = ISC_TRUE; 7236 else if (rdataset.type == dns_rdatatype_ds) 7237 seen_ds = ISC_TRUE; 7238 else if (rdataset.type == dns_rdatatype_nsec) 7239 seen_nsec = ISC_TRUE; 7240 dns_rdataset_disassociate(&rdataset); 7241 } 7242 dns_rdatasetiter_destroy(&iterator); 7243 /* 7244 * Is there a NSEC chain than needs to be cleaned up? 7245 */ 7246 if (seen_nsec) 7247 nsec3chain->seen_nsec = ISC_TRUE; 7248 if (seen_ns && !seen_soa && !seen_ds) 7249 unsecure = ISC_TRUE; 7250 if ((seen_ns && !seen_soa) || seen_dname) 7251 delegation = ISC_TRUE; 7252 7253 /* 7254 * Process one node. 7255 */ 7256 dns_dbiterator_pause(nsec3chain->dbiterator); 7257 result = dns_nsec3_addnsec3(db, version, name, 7258 &nsec3chain->nsec3param, 7259 zone->minimum, unsecure, 7260 &nsec3_diff); 7261 if (result != ISC_R_SUCCESS) { 7262 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7263 "dns_nsec3_addnsec3 -> %s", 7264 dns_result_totext(result)); 7265 goto failure; 7266 } 7267 7268 /* 7269 * Treat each call to dns_nsec3_addnsec3() as if it's cost is 7270 * two signatures. Additionally there will, in general, be 7271 * two signature generated below. 7272 * 7273 * If we are only changing the optout flag the cost is half 7274 * that of the cost of generating a completely new chain. 7275 */ 7276 signatures -= 4; 7277 7278 /* 7279 * Go onto next node. 7280 */ 7281 next_addnode: 7282 first = ISC_FALSE; 7283 dns_db_detachnode(db, &node); 7284 do { 7285 result = dns_dbiterator_next(nsec3chain->dbiterator); 7286 7287 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) { 7288 dns_dbiterator_pause(nsec3chain->dbiterator); 7289 CHECK(fixup_nsec3param(db, version, nsec3chain, 7290 ISC_FALSE, privatetype, 7291 ¶m_diff)); 7292 LOCK_ZONE(zone); 7293 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 7294 link); 7295 UNLOCK_ZONE(zone); 7296 ISC_LIST_APPEND(cleanup, nsec3chain, link); 7297 goto next_addchain; 7298 } 7299 if (result == ISC_R_NOMORE) { 7300 dns_dbiterator_pause(nsec3chain->dbiterator); 7301 if (nsec3chain->seen_nsec) { 7302 CHECK(fixup_nsec3param(db, version, 7303 nsec3chain, 7304 ISC_TRUE, 7305 privatetype, 7306 ¶m_diff)); 7307 nsec3chain->delete_nsec = ISC_TRUE; 7308 goto same_addchain; 7309 } 7310 CHECK(fixup_nsec3param(db, version, nsec3chain, 7311 ISC_FALSE, privatetype, 7312 ¶m_diff)); 7313 LOCK_ZONE(zone); 7314 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 7315 link); 7316 UNLOCK_ZONE(zone); 7317 ISC_LIST_APPEND(cleanup, nsec3chain, link); 7318 goto next_addchain; 7319 } else if (result != ISC_R_SUCCESS) { 7320 dns_zone_log(zone, ISC_LOG_ERROR, 7321 "zone_nsec3chain:" 7322 "dns_dbiterator_next -> %s", 7323 dns_result_totext(result)); 7324 goto failure; 7325 } else if (delegation) { 7326 dns_dbiterator_current(nsec3chain->dbiterator, 7327 &node, nextname); 7328 dns_db_detachnode(db, &node); 7329 if (!dns_name_issubdomain(nextname, name)) 7330 break; 7331 } else 7332 break; 7333 } while (1); 7334 continue; 7335 7336 same_addchain: 7337 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 7338 first = ISC_TRUE; 7339 continue; 7340 7341 next_addchain: 7342 dns_dbiterator_pause(nsec3chain->dbiterator); 7343 nsec3chain = nextnsec3chain; 7344 first = ISC_TRUE; 7345 if (nsec3chain != NULL) 7346 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 7347 } 7348 7349 /* 7350 * Process removals. 7351 */ 7352 LOCK_ZONE(zone); 7353 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 7354 UNLOCK_ZONE(zone); 7355 first = ISC_TRUE; 7356 buildnsecchain = ISC_FALSE; 7357 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 7358 LOCK_ZONE(zone); 7359 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 7360 UNLOCK_ZONE(zone); 7361 7362 if (nsec3chain->db != db) 7363 goto next_removechain; 7364 7365 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) 7366 goto next_removechain; 7367 7368 /* 7369 * Work out if we need to build a NSEC chain as a consequence 7370 * of removing this NSEC3 chain. 7371 */ 7372 if (first && !updatensec && 7373 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) 7374 { 7375 result = need_nsec_chain(db, version, 7376 &nsec3chain->nsec3param, 7377 &buildnsecchain); 7378 if (result != ISC_R_SUCCESS) { 7379 dns_zone_log(zone, ISC_LOG_ERROR, 7380 "zone_nsec3chain:" 7381 "need_nsec_chain -> %s", 7382 dns_result_totext(result)); 7383 goto failure; 7384 } 7385 } 7386 7387 if (first) 7388 dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:" 7389 "buildnsecchain = %u\n", buildnsecchain); 7390 7391 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 7392 delegation = ISC_FALSE; 7393 7394 if (!buildnsecchain) { 7395 /* 7396 * Delete the NSECPARAM record that matches this chain. 7397 */ 7398 if (first) { 7399 result = fixup_nsec3param(db, version, 7400 nsec3chain, 7401 ISC_TRUE, privatetype, 7402 ¶m_diff); 7403 if (result != ISC_R_SUCCESS) { 7404 dns_zone_log(zone, ISC_LOG_ERROR, 7405 "zone_nsec3chain:" 7406 "fixup_nsec3param -> %s", 7407 dns_result_totext(result)); 7408 goto failure; 7409 } 7410 } 7411 7412 /* 7413 * Delete the NSEC3 records. 7414 */ 7415 result = deletematchingnsec3(db, version, node, name, 7416 &nsec3chain->nsec3param, 7417 &nsec3_diff); 7418 if (result != ISC_R_SUCCESS) { 7419 dns_zone_log(zone, ISC_LOG_ERROR, 7420 "zone_nsec3chain:" 7421 "deletematchingnsec3 -> %s", 7422 dns_result_totext(result)); 7423 goto failure; 7424 } 7425 goto next_removenode; 7426 } 7427 7428 if (first) { 7429 dns_fixedname_t ffound; 7430 dns_name_t *found; 7431 dns_fixedname_init(&ffound); 7432 found = dns_fixedname_name(&ffound); 7433 result = dns_db_find(db, name, version, 7434 dns_rdatatype_soa, 7435 DNS_DBFIND_NOWILD, 0, NULL, found, 7436 NULL, NULL); 7437 if ((result == DNS_R_DELEGATION || 7438 result == DNS_R_DNAME) && 7439 !dns_name_equal(name, found)) { 7440 /* 7441 * Remember the obscuring name so that 7442 * we skip all obscured names. 7443 */ 7444 dns_name_copy(found, name, NULL); 7445 delegation = ISC_TRUE; 7446 goto next_removenode; 7447 } 7448 } 7449 7450 /* 7451 * Check to see if this is a bottom of zone node. 7452 */ 7453 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 7454 if (result == ISC_R_NOTFOUND) /* Empty node? */ 7455 goto next_removenode; 7456 if (result != ISC_R_SUCCESS) 7457 goto failure; 7458 7459 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec = 7460 seen_rr = ISC_FALSE; 7461 for (result = dns_rdatasetiter_first(iterator); 7462 result == ISC_R_SUCCESS; 7463 result = dns_rdatasetiter_next(iterator)) { 7464 dns_rdatasetiter_current(iterator, &rdataset); 7465 if (rdataset.type == dns_rdatatype_soa) 7466 seen_soa = ISC_TRUE; 7467 else if (rdataset.type == dns_rdatatype_ns) 7468 seen_ns = ISC_TRUE; 7469 else if (rdataset.type == dns_rdatatype_dname) 7470 seen_dname = ISC_TRUE; 7471 else if (rdataset.type == dns_rdatatype_nsec) 7472 seen_nsec = ISC_TRUE; 7473 else if (rdataset.type == dns_rdatatype_nsec3) 7474 seen_nsec3 = ISC_TRUE; 7475 if (rdataset.type != dns_rdatatype_rrsig) 7476 seen_rr = ISC_TRUE; 7477 dns_rdataset_disassociate(&rdataset); 7478 } 7479 dns_rdatasetiter_destroy(&iterator); 7480 7481 if (!seen_rr || seen_nsec3 || seen_nsec) 7482 goto next_removenode; 7483 if ((seen_ns && !seen_soa) || seen_dname) 7484 delegation = ISC_TRUE; 7485 7486 /* 7487 * Add a NSEC record except at the origin. 7488 */ 7489 if (!dns_name_equal(name, dns_db_origin(db))) { 7490 dns_dbiterator_pause(nsec3chain->dbiterator); 7491 CHECK(add_nsec(db, version, name, node, zone->minimum, 7492 delegation, &nsec_diff)); 7493 } 7494 7495 next_removenode: 7496 first = ISC_FALSE; 7497 dns_db_detachnode(db, &node); 7498 do { 7499 result = dns_dbiterator_next(nsec3chain->dbiterator); 7500 if (result == ISC_R_NOMORE && buildnsecchain) { 7501 /* 7502 * The NSEC chain should now be built. 7503 * We can now remove the NSEC3 chain. 7504 */ 7505 updatensec = ISC_TRUE; 7506 goto same_removechain; 7507 } 7508 if (result == ISC_R_NOMORE) { 7509 LOCK_ZONE(zone); 7510 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 7511 link); 7512 UNLOCK_ZONE(zone); 7513 ISC_LIST_APPEND(cleanup, nsec3chain, link); 7514 dns_dbiterator_pause(nsec3chain->dbiterator); 7515 result = fixup_nsec3param(db, version, 7516 nsec3chain, ISC_FALSE, 7517 privatetype, 7518 ¶m_diff); 7519 if (result != ISC_R_SUCCESS) { 7520 dns_zone_log(zone, ISC_LOG_ERROR, 7521 "zone_nsec3chain:" 7522 "fixup_nsec3param -> %s", 7523 dns_result_totext(result)); 7524 goto failure; 7525 } 7526 goto next_removechain; 7527 } else if (result != ISC_R_SUCCESS) { 7528 dns_zone_log(zone, ISC_LOG_ERROR, 7529 "zone_nsec3chain:" 7530 "dns_dbiterator_next -> %s", 7531 dns_result_totext(result)); 7532 goto failure; 7533 } else if (delegation) { 7534 dns_dbiterator_current(nsec3chain->dbiterator, 7535 &node, nextname); 7536 dns_db_detachnode(db, &node); 7537 if (!dns_name_issubdomain(nextname, name)) 7538 break; 7539 } else 7540 break; 7541 } while (1); 7542 continue; 7543 7544 same_removechain: 7545 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 7546 buildnsecchain = ISC_FALSE; 7547 first = ISC_TRUE; 7548 continue; 7549 7550 next_removechain: 7551 dns_dbiterator_pause(nsec3chain->dbiterator); 7552 nsec3chain = nextnsec3chain; 7553 first = ISC_TRUE; 7554 } 7555 7556 /* 7557 * We may need to update the NSEC/NSEC3 records for the zone apex. 7558 */ 7559 if (!ISC_LIST_EMPTY(param_diff.tuples)) { 7560 isc_boolean_t rebuild_nsec = ISC_FALSE, 7561 rebuild_nsec3 = ISC_FALSE; 7562 result = dns_db_getoriginnode(db, &node); 7563 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7564 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 7565 if (result != ISC_R_SUCCESS) { 7566 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7567 "dns_db_allrdatasets -> %s", 7568 dns_result_totext(result)); 7569 goto failure; 7570 } 7571 for (result = dns_rdatasetiter_first(iterator); 7572 result == ISC_R_SUCCESS; 7573 result = dns_rdatasetiter_next(iterator)) { 7574 dns_rdatasetiter_current(iterator, &rdataset); 7575 if (rdataset.type == dns_rdatatype_nsec) 7576 rebuild_nsec = ISC_TRUE; 7577 if (rdataset.type == dns_rdatatype_nsec3param) 7578 rebuild_nsec3 = ISC_TRUE; 7579 dns_rdataset_disassociate(&rdataset); 7580 } 7581 dns_rdatasetiter_destroy(&iterator); 7582 dns_db_detachnode(db, &node); 7583 7584 if (rebuild_nsec) { 7585 if (nsec3chain != NULL) 7586 dns_dbiterator_pause(nsec3chain->dbiterator); 7587 7588 result = updatesecure(db, version, &zone->origin, 7589 zone->minimum, ISC_TRUE, 7590 &nsec_diff); 7591 if (result != ISC_R_SUCCESS) { 7592 dns_zone_log(zone, ISC_LOG_ERROR, 7593 "zone_nsec3chain:" 7594 "updatesecure -> %s", 7595 dns_result_totext(result)); 7596 goto failure; 7597 } 7598 } 7599 7600 if (rebuild_nsec3) { 7601 if (nsec3chain != NULL) 7602 dns_dbiterator_pause(nsec3chain->dbiterator); 7603 7604 result = dns_nsec3_addnsec3s(db, version, 7605 dns_db_origin(db), 7606 zone->minimum, ISC_FALSE, 7607 &nsec3_diff); 7608 if (result != ISC_R_SUCCESS) { 7609 dns_zone_log(zone, ISC_LOG_ERROR, 7610 "zone_nsec3chain:" 7611 "dns_nsec3_addnsec3s -> %s", 7612 dns_result_totext(result)); 7613 goto failure; 7614 } 7615 } 7616 } 7617 7618 if (nsec3chain != NULL) 7619 dns_dbiterator_pause(nsec3chain->dbiterator); 7620 7621 /* 7622 * Add / update signatures for the NSEC3 records. 7623 */ 7624 if (nsec3chain != NULL) 7625 dns_dbiterator_pause(nsec3chain->dbiterator); 7626 result = update_sigs(&nsec3_diff, db, version, zone_keys, 7627 nkeys, zone, inception, expire, now, 7628 check_ksk, keyset_kskonly, &zonediff); 7629 if (result != ISC_R_SUCCESS) { 7630 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7631 "update_sigs -> %s", dns_result_totext(result)); 7632 goto failure; 7633 } 7634 7635 /* 7636 * We have changed the NSEC3PARAM or private RRsets 7637 * above so we need to update the signatures. 7638 */ 7639 result = update_sigs(¶m_diff, db, version, zone_keys, 7640 nkeys, zone, inception, expire, now, 7641 check_ksk, keyset_kskonly, &zonediff); 7642 if (result != ISC_R_SUCCESS) { 7643 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7644 "update_sigs -> %s", dns_result_totext(result)); 7645 goto failure; 7646 } 7647 7648 if (updatensec) { 7649 result = updatesecure(db, version, &zone->origin, 7650 zone->minimum, ISC_FALSE, &nsec_diff); 7651 if (result != ISC_R_SUCCESS) { 7652 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7653 "updatesecure -> %s", 7654 dns_result_totext(result)); 7655 goto failure; 7656 } 7657 } 7658 7659 result = update_sigs(&nsec_diff, db, version, zone_keys, 7660 nkeys, zone, inception, expire, now, 7661 check_ksk, keyset_kskonly, &zonediff); 7662 if (result != ISC_R_SUCCESS) { 7663 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7664 "update_sigs -> %s", dns_result_totext(result)); 7665 goto failure; 7666 } 7667 7668 /* 7669 * If we made no effective changes to the zone then we can just 7670 * cleanup otherwise we need to increment the serial. 7671 */ 7672 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 7673 /* 7674 * No need to call dns_db_closeversion() here as it is 7675 * called with commit = ISC_TRUE below. 7676 */ 7677 goto done; 7678 } 7679 7680 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 7681 &zonediff, zone_keys, nkeys, now, ISC_FALSE); 7682 if (result != ISC_R_SUCCESS) { 7683 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7684 "del_sigs -> %s", dns_result_totext(result)); 7685 goto failure; 7686 } 7687 7688 result = update_soa_serial(db, version, zonediff.diff, zone->mctx, 7689 zone->updatemethod); 7690 if (result != ISC_R_SUCCESS) { 7691 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7692 "update_soa_serial -> %s", 7693 dns_result_totext(result)); 7694 goto failure; 7695 } 7696 7697 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, 7698 zonediff.diff, zone_keys, nkeys, zone->mctx, 7699 inception, soaexpire, check_ksk, keyset_kskonly); 7700 if (result != ISC_R_SUCCESS) { 7701 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 7702 "add_sigs -> %s", dns_result_totext(result)); 7703 goto failure; 7704 } 7705 7706 /* Write changes to journal file. */ 7707 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain")); 7708 7709 LOCK_ZONE(zone); 7710 zone_needdump(zone, DNS_DUMP_DELAY); 7711 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 7712 UNLOCK_ZONE(zone); 7713 7714 done: 7715 /* 7716 * Pause all iterators so that dns_db_closeversion() can succeed. 7717 */ 7718 LOCK_ZONE(zone); 7719 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 7720 nsec3chain != NULL; 7721 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 7722 dns_dbiterator_pause(nsec3chain->dbiterator); 7723 UNLOCK_ZONE(zone); 7724 7725 /* 7726 * Everything has succeeded. Commit the changes. 7727 * Unconditionally commit as zonediff.offline not checked above. 7728 */ 7729 dns_db_closeversion(db, &version, ISC_TRUE); 7730 7731 /* 7732 * Everything succeeded so we can clean these up now. 7733 */ 7734 nsec3chain = ISC_LIST_HEAD(cleanup); 7735 while (nsec3chain != NULL) { 7736 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 7737 dns_db_detach(&nsec3chain->db); 7738 dns_dbiterator_destroy(&nsec3chain->dbiterator); 7739 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 7740 nsec3chain = ISC_LIST_HEAD(cleanup); 7741 } 7742 7743 set_resigntime(zone); 7744 7745 failure: 7746 if (result != ISC_R_SUCCESS) 7747 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s", 7748 dns_result_totext(result)); 7749 /* 7750 * On error roll back the current nsec3chain. 7751 */ 7752 if (result != ISC_R_SUCCESS && nsec3chain != NULL) { 7753 if (nsec3chain->done) { 7754 dns_db_detach(&nsec3chain->db); 7755 dns_dbiterator_destroy(&nsec3chain->dbiterator); 7756 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 7757 } else { 7758 result = dns_dbiterator_first(nsec3chain->dbiterator); 7759 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7760 dns_dbiterator_pause(nsec3chain->dbiterator); 7761 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 7762 } 7763 } 7764 7765 /* 7766 * Rollback the cleanup list. 7767 */ 7768 nsec3chain = ISC_LIST_TAIL(cleanup); 7769 while (nsec3chain != NULL) { 7770 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 7771 if (nsec3chain->done) { 7772 dns_db_detach(&nsec3chain->db); 7773 dns_dbiterator_destroy(&nsec3chain->dbiterator); 7774 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 7775 } else { 7776 LOCK_ZONE(zone); 7777 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link); 7778 UNLOCK_ZONE(zone); 7779 result = dns_dbiterator_first(nsec3chain->dbiterator); 7780 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7781 dns_dbiterator_pause(nsec3chain->dbiterator); 7782 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 7783 } 7784 nsec3chain = ISC_LIST_TAIL(cleanup); 7785 } 7786 7787 LOCK_ZONE(zone); 7788 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 7789 nsec3chain != NULL; 7790 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 7791 dns_dbiterator_pause(nsec3chain->dbiterator); 7792 UNLOCK_ZONE(zone); 7793 7794 dns_diff_clear(¶m_diff); 7795 dns_diff_clear(&nsec3_diff); 7796 dns_diff_clear(&nsec_diff); 7797 dns_diff_clear(&_sig_diff); 7798 7799 if (iterator != NULL) 7800 dns_rdatasetiter_destroy(&iterator); 7801 7802 for (i = 0; i < nkeys; i++) 7803 dst_key_free(&zone_keys[i]); 7804 7805 if (node != NULL) 7806 dns_db_detachnode(db, &node); 7807 if (version != NULL) { 7808 dns_db_closeversion(db, &version, ISC_FALSE); 7809 dns_db_detach(&db); 7810 } else if (db != NULL) 7811 dns_db_detach(&db); 7812 7813 LOCK_ZONE(zone); 7814 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) { 7815 isc_interval_t interval; 7816 if (zone->update_disabled || result != ISC_R_SUCCESS) 7817 isc_interval_set(&interval, 60, 0); /* 1 minute */ 7818 else 7819 isc_interval_set(&interval, 0, 10000000); /* 10 ms */ 7820 isc_time_nowplusinterval(&zone->nsec3chaintime, &interval); 7821 } else 7822 isc_time_settoepoch(&zone->nsec3chaintime); 7823 UNLOCK_ZONE(zone); 7824 7825 INSIST(version == NULL); 7826 } 7827 7828 static isc_result_t 7829 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 7830 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm, 7831 isc_uint16_t keyid, dns_diff_t *diff) 7832 { 7833 dns_rdata_rrsig_t rrsig; 7834 dns_rdataset_t rdataset; 7835 dns_rdatasetiter_t *iterator = NULL; 7836 isc_result_t result; 7837 7838 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 7839 if (result != ISC_R_SUCCESS) { 7840 if (result == ISC_R_NOTFOUND) 7841 result = ISC_R_SUCCESS; 7842 return (result); 7843 } 7844 7845 dns_rdataset_init(&rdataset); 7846 for (result = dns_rdatasetiter_first(iterator); 7847 result == ISC_R_SUCCESS; 7848 result = dns_rdatasetiter_next(iterator)) { 7849 dns_rdatasetiter_current(iterator, &rdataset); 7850 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) { 7851 for (result = dns_rdataset_first(&rdataset); 7852 result == ISC_R_SUCCESS; 7853 result = dns_rdataset_next(&rdataset)) { 7854 dns_rdata_t rdata = DNS_RDATA_INIT; 7855 dns_rdataset_current(&rdataset, &rdata); 7856 CHECK(update_one_rr(db, version, diff, 7857 DNS_DIFFOP_DEL, name, 7858 rdataset.ttl, &rdata)); 7859 } 7860 if (result != ISC_R_NOMORE) 7861 goto failure; 7862 dns_rdataset_disassociate(&rdataset); 7863 continue; 7864 } 7865 if (rdataset.type != dns_rdatatype_rrsig) { 7866 dns_rdataset_disassociate(&rdataset); 7867 continue; 7868 } 7869 for (result = dns_rdataset_first(&rdataset); 7870 result == ISC_R_SUCCESS; 7871 result = dns_rdataset_next(&rdataset)) { 7872 dns_rdata_t rdata = DNS_RDATA_INIT; 7873 dns_rdataset_current(&rdataset, &rdata); 7874 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL)); 7875 if (rrsig.algorithm != algorithm || 7876 rrsig.keyid != keyid) 7877 continue; 7878 CHECK(update_one_rr(db, version, diff, 7879 DNS_DIFFOP_DELRESIGN, name, 7880 rdataset.ttl, &rdata)); 7881 } 7882 dns_rdataset_disassociate(&rdataset); 7883 if (result != ISC_R_NOMORE) 7884 break; 7885 } 7886 if (result == ISC_R_NOMORE) 7887 result = ISC_R_SUCCESS; 7888 failure: 7889 if (dns_rdataset_isassociated(&rdataset)) 7890 dns_rdataset_disassociate(&rdataset); 7891 dns_rdatasetiter_destroy(&iterator); 7892 return (result); 7893 } 7894 7895 /* 7896 * Incrementally sign the zone using the keys requested. 7897 * Builds the NSEC chain if required. 7898 */ 7899 static void 7900 zone_sign(dns_zone_t *zone) { 7901 const char *me = "zone_sign"; 7902 dns_db_t *db = NULL; 7903 dns_dbnode_t *node = NULL; 7904 dns_dbversion_t *version = NULL; 7905 dns_diff_t _sig_diff; 7906 dns_diff_t post_diff; 7907 zonediff_t zonediff; 7908 dns_fixedname_t fixed; 7909 dns_fixedname_t nextfixed; 7910 dns_name_t *name, *nextname; 7911 dns_rdataset_t rdataset; 7912 dns_signing_t *signing, *nextsigning; 7913 dns_signinglist_t cleanup; 7914 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 7915 isc_int32_t signatures; 7916 isc_boolean_t check_ksk, keyset_kskonly, is_ksk; 7917 isc_boolean_t commit = ISC_FALSE; 7918 isc_boolean_t delegation; 7919 isc_boolean_t build_nsec = ISC_FALSE; 7920 isc_boolean_t build_nsec3 = ISC_FALSE; 7921 isc_boolean_t first; 7922 isc_result_t result; 7923 isc_stdtime_t now, inception, soaexpire, expire; 7924 isc_uint32_t jitter; 7925 unsigned int i, j; 7926 unsigned int nkeys = 0; 7927 isc_uint32_t nodes; 7928 7929 ENTER; 7930 7931 dns_rdataset_init(&rdataset); 7932 dns_fixedname_init(&fixed); 7933 name = dns_fixedname_name(&fixed); 7934 dns_fixedname_init(&nextfixed); 7935 nextname = dns_fixedname_name(&nextfixed); 7936 dns_diff_init(zone->mctx, &_sig_diff); 7937 dns_diff_init(zone->mctx, &post_diff); 7938 zonediff_init(&zonediff, &_sig_diff); 7939 ISC_LIST_INIT(cleanup); 7940 7941 /* 7942 * Updates are disabled. Pause for 5 minutes. 7943 */ 7944 if (zone->update_disabled) { 7945 result = ISC_R_FAILURE; 7946 goto failure; 7947 } 7948 7949 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 7950 if (zone->db != NULL) 7951 dns_db_attach(zone->db, &db); 7952 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 7953 if (db == NULL) { 7954 result = ISC_R_FAILURE; 7955 goto failure; 7956 } 7957 7958 result = dns_db_newversion(db, &version); 7959 if (result != ISC_R_SUCCESS) { 7960 dns_zone_log(zone, ISC_LOG_ERROR, 7961 "zone_sign:dns_db_newversion -> %s", 7962 dns_result_totext(result)); 7963 goto failure; 7964 } 7965 7966 result = find_zone_keys(zone, db, version, zone->mctx, 7967 DNS_MAXZONEKEYS, zone_keys, &nkeys); 7968 if (result != ISC_R_SUCCESS) { 7969 dns_zone_log(zone, ISC_LOG_ERROR, 7970 "zone_sign:find_zone_keys -> %s", 7971 dns_result_totext(result)); 7972 goto failure; 7973 } 7974 7975 isc_stdtime_get(&now); 7976 inception = now - 3600; /* Allow for clock skew. */ 7977 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 7978 7979 /* 7980 * Spread out signatures over time if they happen to be 7981 * clumped. We don't do this for each add_sigs() call as 7982 * we still want some clustering to occur. 7983 */ 7984 isc_random_get(&jitter); 7985 expire = soaexpire - jitter % 3600; 7986 7987 /* 7988 * We keep pulling nodes off each iterator in turn until 7989 * we have no more nodes to pull off or we reach the limits 7990 * for this quantum. 7991 */ 7992 nodes = zone->nodes; 7993 signatures = zone->signatures; 7994 signing = ISC_LIST_HEAD(zone->signing); 7995 first = ISC_TRUE; 7996 7997 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 7998 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 7999 8000 /* Determine which type of chain to build */ 8001 CHECK(dns_private_chains(db, version, zone->privatetype, 8002 &build_nsec, &build_nsec3)); 8003 8004 /* If neither chain is found, default to NSEC */ 8005 if (!build_nsec && !build_nsec3) 8006 build_nsec = ISC_TRUE; 8007 8008 while (signing != NULL && nodes-- > 0 && signatures > 0) { 8009 nextsigning = ISC_LIST_NEXT(signing, link); 8010 8011 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8012 if (signing->done || signing->db != zone->db) { 8013 /* 8014 * The zone has been reloaded. We will have 8015 * created new signings as part of the reload 8016 * process so we can destroy this one. 8017 */ 8018 ISC_LIST_UNLINK(zone->signing, signing, link); 8019 ISC_LIST_APPEND(cleanup, signing, link); 8020 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8021 goto next_signing; 8022 } 8023 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8024 8025 if (signing->db != db) 8026 goto next_signing; 8027 8028 delegation = ISC_FALSE; 8029 8030 if (first && signing->delete) { 8031 /* 8032 * Remove the key we are deleting from consideration. 8033 */ 8034 for (i = 0, j = 0; i < nkeys; i++) { 8035 /* 8036 * Find the key we want to remove. 8037 */ 8038 if (ALG(zone_keys[i]) == signing->algorithm && 8039 dst_key_id(zone_keys[i]) == signing->keyid) 8040 { 8041 if (KSK(zone_keys[i])) 8042 dst_key_free(&zone_keys[i]); 8043 continue; 8044 } 8045 zone_keys[j] = zone_keys[i]; 8046 j++; 8047 } 8048 nkeys = j; 8049 } 8050 8051 dns_dbiterator_current(signing->dbiterator, &node, name); 8052 8053 if (signing->delete) { 8054 dns_dbiterator_pause(signing->dbiterator); 8055 CHECK(del_sig(db, version, name, node, nkeys, 8056 signing->algorithm, signing->keyid, 8057 zonediff.diff)); 8058 } 8059 8060 /* 8061 * On the first pass we need to check if the current node 8062 * has not been obscured. 8063 */ 8064 if (first) { 8065 dns_fixedname_t ffound; 8066 dns_name_t *found; 8067 dns_fixedname_init(&ffound); 8068 found = dns_fixedname_name(&ffound); 8069 result = dns_db_find(db, name, version, 8070 dns_rdatatype_soa, 8071 DNS_DBFIND_NOWILD, 0, NULL, found, 8072 NULL, NULL); 8073 if ((result == DNS_R_DELEGATION || 8074 result == DNS_R_DNAME) && 8075 !dns_name_equal(name, found)) { 8076 /* 8077 * Remember the obscuring name so that 8078 * we skip all obscured names. 8079 */ 8080 dns_name_copy(found, name, NULL); 8081 delegation = ISC_TRUE; 8082 goto next_node; 8083 } 8084 } 8085 8086 /* 8087 * Process one node. 8088 */ 8089 dns_dbiterator_pause(signing->dbiterator); 8090 for (i = 0; i < nkeys; i++) { 8091 isc_boolean_t both = ISC_FALSE; 8092 8093 /* 8094 * Find the keys we want to sign with. 8095 */ 8096 if (!dst_key_isprivate(zone_keys[i])) 8097 continue; 8098 8099 /* 8100 * When adding look for the specific key. 8101 */ 8102 if (!signing->delete && 8103 (dst_key_alg(zone_keys[i]) != signing->algorithm || 8104 dst_key_id(zone_keys[i]) != signing->keyid)) 8105 continue; 8106 8107 /* 8108 * When deleting make sure we are properly signed 8109 * with the algorithm that was being removed. 8110 */ 8111 if (signing->delete && 8112 ALG(zone_keys[i]) != signing->algorithm) 8113 continue; 8114 8115 /* 8116 * Do we do KSK processing? 8117 */ 8118 if (check_ksk && !REVOKE(zone_keys[i])) { 8119 isc_boolean_t have_ksk, have_nonksk; 8120 if (KSK(zone_keys[i])) { 8121 have_ksk = ISC_TRUE; 8122 have_nonksk = ISC_FALSE; 8123 } else { 8124 have_ksk = ISC_FALSE; 8125 have_nonksk = ISC_TRUE; 8126 } 8127 for (j = 0; j < nkeys; j++) { 8128 if (j == i || 8129 ALG(zone_keys[i]) != 8130 ALG(zone_keys[j])) 8131 continue; 8132 if (REVOKE(zone_keys[j])) 8133 continue; 8134 if (KSK(zone_keys[j])) 8135 have_ksk = ISC_TRUE; 8136 else 8137 have_nonksk = ISC_TRUE; 8138 both = have_ksk && have_nonksk; 8139 if (both) 8140 break; 8141 } 8142 } 8143 if (both || REVOKE(zone_keys[i])) 8144 is_ksk = KSK(zone_keys[i]); 8145 else 8146 is_ksk = ISC_FALSE; 8147 8148 CHECK(sign_a_node(db, name, node, version, build_nsec3, 8149 build_nsec, zone_keys[i], inception, 8150 expire, zone->minimum, is_ksk, 8151 ISC_TF(both && keyset_kskonly), 8152 &delegation, zonediff.diff, 8153 &signatures, zone->mctx)); 8154 /* 8155 * If we are adding we are done. Look for other keys 8156 * of the same algorithm if deleting. 8157 */ 8158 if (!signing->delete) 8159 break; 8160 } 8161 8162 /* 8163 * Go onto next node. 8164 */ 8165 next_node: 8166 first = ISC_FALSE; 8167 dns_db_detachnode(db, &node); 8168 do { 8169 result = dns_dbiterator_next(signing->dbiterator); 8170 if (result == ISC_R_NOMORE) { 8171 ISC_LIST_UNLINK(zone->signing, signing, link); 8172 ISC_LIST_APPEND(cleanup, signing, link); 8173 dns_dbiterator_pause(signing->dbiterator); 8174 if (nkeys != 0 && build_nsec) { 8175 /* 8176 * We have finished regenerating the 8177 * zone with a zone signing key. 8178 * The NSEC chain is now complete and 8179 * there is a full set of signatures 8180 * for the zone. We can now clear the 8181 * OPT bit from the NSEC record. 8182 */ 8183 result = updatesecure(db, version, 8184 &zone->origin, 8185 zone->minimum, 8186 ISC_FALSE, 8187 &post_diff); 8188 if (result != ISC_R_SUCCESS) { 8189 dns_zone_log(zone, 8190 ISC_LOG_ERROR, 8191 "updatesecure -> %s", 8192 dns_result_totext(result)); 8193 goto failure; 8194 } 8195 } 8196 result = updatesignwithkey(zone, signing, 8197 version, 8198 build_nsec3, 8199 zone->minimum, 8200 &post_diff); 8201 if (result != ISC_R_SUCCESS) { 8202 dns_zone_log(zone, ISC_LOG_ERROR, 8203 "updatesignwithkey -> %s", 8204 dns_result_totext(result)); 8205 goto failure; 8206 } 8207 build_nsec = ISC_FALSE; 8208 goto next_signing; 8209 } else if (result != ISC_R_SUCCESS) { 8210 dns_zone_log(zone, ISC_LOG_ERROR, 8211 "zone_sign:dns_dbiterator_next -> %s", 8212 dns_result_totext(result)); 8213 goto failure; 8214 } else if (delegation) { 8215 dns_dbiterator_current(signing->dbiterator, 8216 &node, nextname); 8217 dns_db_detachnode(db, &node); 8218 if (!dns_name_issubdomain(nextname, name)) 8219 break; 8220 } else 8221 break; 8222 } while (1); 8223 continue; 8224 8225 next_signing: 8226 dns_dbiterator_pause(signing->dbiterator); 8227 signing = nextsigning; 8228 first = ISC_TRUE; 8229 } 8230 8231 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) { 8232 result = update_sigs(&post_diff, db, version, zone_keys, 8233 nkeys, zone, inception, expire, now, 8234 check_ksk, keyset_kskonly, &zonediff); 8235 if (result != ISC_R_SUCCESS) { 8236 dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:" 8237 "update_sigs -> %s", 8238 dns_result_totext(result)); 8239 goto failure; 8240 } 8241 } 8242 8243 /* 8244 * Have we changed anything? 8245 */ 8246 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { 8247 if (zonediff.offline) 8248 commit = ISC_TRUE; 8249 result = ISC_R_SUCCESS; 8250 goto pauseall; 8251 } 8252 8253 commit = ISC_TRUE; 8254 8255 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 8256 &zonediff, zone_keys, nkeys, now, ISC_FALSE); 8257 if (result != ISC_R_SUCCESS) { 8258 dns_zone_log(zone, ISC_LOG_ERROR, 8259 "zone_sign:del_sigs -> %s", 8260 dns_result_totext(result)); 8261 goto failure; 8262 } 8263 8264 result = update_soa_serial(db, version, zonediff.diff, zone->mctx, 8265 zone->updatemethod); 8266 if (result != ISC_R_SUCCESS) { 8267 dns_zone_log(zone, ISC_LOG_ERROR, 8268 "zone_sign:update_soa_serial -> %s", 8269 dns_result_totext(result)); 8270 goto failure; 8271 } 8272 8273 /* 8274 * Generate maximum life time signatures so that the above loop 8275 * termination is sensible. 8276 */ 8277 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, 8278 zonediff.diff, zone_keys, nkeys, zone->mctx, 8279 inception, soaexpire, check_ksk, keyset_kskonly); 8280 if (result != ISC_R_SUCCESS) { 8281 dns_zone_log(zone, ISC_LOG_ERROR, 8282 "zone_sign:add_sigs -> %s", 8283 dns_result_totext(result)); 8284 goto failure; 8285 } 8286 8287 /* 8288 * Write changes to journal file. 8289 */ 8290 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign")); 8291 8292 pauseall: 8293 /* 8294 * Pause all iterators so that dns_db_closeversion() can succeed. 8295 */ 8296 for (signing = ISC_LIST_HEAD(zone->signing); 8297 signing != NULL; 8298 signing = ISC_LIST_NEXT(signing, link)) 8299 dns_dbiterator_pause(signing->dbiterator); 8300 8301 for (signing = ISC_LIST_HEAD(cleanup); 8302 signing != NULL; 8303 signing = ISC_LIST_NEXT(signing, link)) 8304 dns_dbiterator_pause(signing->dbiterator); 8305 8306 /* 8307 * Everything has succeeded. Commit the changes. 8308 */ 8309 dns_db_closeversion(db, &version, commit); 8310 8311 /* 8312 * Everything succeeded so we can clean these up now. 8313 */ 8314 signing = ISC_LIST_HEAD(cleanup); 8315 while (signing != NULL) { 8316 ISC_LIST_UNLINK(cleanup, signing, link); 8317 dns_db_detach(&signing->db); 8318 dns_dbiterator_destroy(&signing->dbiterator); 8319 isc_mem_put(zone->mctx, signing, sizeof *signing); 8320 signing = ISC_LIST_HEAD(cleanup); 8321 } 8322 8323 set_resigntime(zone); 8324 8325 if (commit) { 8326 LOCK_ZONE(zone); 8327 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 8328 zone_needdump(zone, DNS_DUMP_DELAY); 8329 UNLOCK_ZONE(zone); 8330 } 8331 8332 failure: 8333 /* 8334 * Rollback the cleanup list. 8335 */ 8336 signing = ISC_LIST_HEAD(cleanup); 8337 while (signing != NULL) { 8338 ISC_LIST_UNLINK(cleanup, signing, link); 8339 ISC_LIST_PREPEND(zone->signing, signing, link); 8340 dns_dbiterator_first(signing->dbiterator); 8341 dns_dbiterator_pause(signing->dbiterator); 8342 signing = ISC_LIST_HEAD(cleanup); 8343 } 8344 8345 for (signing = ISC_LIST_HEAD(zone->signing); 8346 signing != NULL; 8347 signing = ISC_LIST_NEXT(signing, link)) 8348 dns_dbiterator_pause(signing->dbiterator); 8349 8350 dns_diff_clear(&_sig_diff); 8351 8352 for (i = 0; i < nkeys; i++) 8353 dst_key_free(&zone_keys[i]); 8354 8355 if (node != NULL) 8356 dns_db_detachnode(db, &node); 8357 8358 if (version != NULL) { 8359 dns_db_closeversion(db, &version, ISC_FALSE); 8360 dns_db_detach(&db); 8361 } else if (db != NULL) 8362 dns_db_detach(&db); 8363 8364 if (ISC_LIST_HEAD(zone->signing) != NULL) { 8365 isc_interval_t interval; 8366 if (zone->update_disabled || result != ISC_R_SUCCESS) 8367 isc_interval_set(&interval, 60, 0); /* 1 minute */ 8368 else 8369 isc_interval_set(&interval, 0, 10000000); /* 10 ms */ 8370 isc_time_nowplusinterval(&zone->signingtime, &interval); 8371 } else 8372 isc_time_settoepoch(&zone->signingtime); 8373 8374 INSIST(version == NULL); 8375 } 8376 8377 static isc_result_t 8378 normalize_key(dns_rdata_t *rr, dns_rdata_t *target, 8379 unsigned char *data, int size) 8380 { 8381 dns_rdata_dnskey_t dnskey; 8382 dns_rdata_keydata_t keydata; 8383 isc_buffer_t buf; 8384 isc_result_t result; 8385 8386 dns_rdata_reset(target); 8387 isc_buffer_init(&buf, data, size); 8388 8389 switch (rr->type) { 8390 case dns_rdatatype_dnskey: 8391 result = dns_rdata_tostruct(rr, &dnskey, NULL); 8392 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8393 dnskey.flags &= ~DNS_KEYFLAG_REVOKE; 8394 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 8395 &dnskey, &buf); 8396 break; 8397 case dns_rdatatype_keydata: 8398 result = dns_rdata_tostruct(rr, &keydata, NULL); 8399 if (result == ISC_R_UNEXPECTEDEND) 8400 return (result); 8401 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8402 dns_keydata_todnskey(&keydata, &dnskey, NULL); 8403 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 8404 &dnskey, &buf); 8405 break; 8406 default: 8407 INSIST(0); 8408 } 8409 return (ISC_R_SUCCESS); 8410 } 8411 8412 /* 8413 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or 8414 * a KEYDATA rdataset from the key zone. 8415 * 8416 * 'rr' contains either a DNSKEY record, or a KEYDATA record 8417 * 8418 * After normalizing keys to the same format (DNSKEY, with revoke bit 8419 * cleared), return ISC_TRUE if a key that matches 'rr' is found in 8420 * 'rdset', or ISC_FALSE if not. 8421 */ 8422 8423 static isc_boolean_t 8424 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) { 8425 unsigned char data1[4096], data2[4096]; 8426 dns_rdata_t rdata, rdata1, rdata2; 8427 isc_result_t result; 8428 8429 dns_rdata_init(&rdata); 8430 dns_rdata_init(&rdata1); 8431 dns_rdata_init(&rdata2); 8432 8433 result = normalize_key(rr, &rdata1, data1, sizeof(data1)); 8434 if (result != ISC_R_SUCCESS) 8435 return (ISC_FALSE); 8436 8437 for (result = dns_rdataset_first(rdset); 8438 result == ISC_R_SUCCESS; 8439 result = dns_rdataset_next(rdset)) { 8440 dns_rdata_reset(&rdata); 8441 dns_rdataset_current(rdset, &rdata); 8442 result = normalize_key(&rdata, &rdata2, data2, sizeof(data2)); 8443 if (result != ISC_R_SUCCESS) 8444 continue; 8445 if (dns_rdata_compare(&rdata1, &rdata2) == 0) 8446 return (ISC_TRUE); 8447 } 8448 8449 return (ISC_FALSE); 8450 } 8451 8452 /* 8453 * Calculate the refresh interval for a keydata zone, per 8454 * RFC5011: MAX(1 hr, 8455 * MIN(15 days, 8456 * 1/2 * OrigTTL, 8457 * 1/2 * RRSigExpirationInterval)) 8458 * or for retries: MAX(1 hr, 8459 * MIN(1 day, 8460 * 1/10 * OrigTTL, 8461 * 1/10 * RRSigExpirationInterval)) 8462 */ 8463 static inline isc_stdtime_t 8464 refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) { 8465 isc_result_t result; 8466 isc_uint32_t t; 8467 dns_rdataset_t *rdset; 8468 dns_rdata_t sigrr = DNS_RDATA_INIT; 8469 dns_rdata_sig_t sig; 8470 isc_stdtime_t now; 8471 8472 isc_stdtime_get(&now); 8473 8474 if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) 8475 rdset = &kfetch->dnskeysigset; 8476 else 8477 return (now + dns_zone_mkey_hour); 8478 8479 result = dns_rdataset_first(rdset); 8480 if (result != ISC_R_SUCCESS) 8481 return (now + dns_zone_mkey_hour); 8482 8483 dns_rdataset_current(rdset, &sigrr); 8484 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 8485 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8486 8487 if (!retry) { 8488 t = sig.originalttl / 2; 8489 8490 if (isc_serial_gt(sig.timeexpire, now)) { 8491 isc_uint32_t exp = (sig.timeexpire - now) / 2; 8492 if (t > exp) 8493 t = exp; 8494 } 8495 8496 if (t > (15 * dns_zone_mkey_day)) 8497 t = (15 * dns_zone_mkey_day); 8498 8499 if (t < dns_zone_mkey_hour) 8500 t = dns_zone_mkey_hour; 8501 } else { 8502 t = sig.originalttl / 10; 8503 8504 if (isc_serial_gt(sig.timeexpire, now)) { 8505 isc_uint32_t exp = (sig.timeexpire - now) / 10; 8506 if (t > exp) 8507 t = exp; 8508 } 8509 8510 if (t > dns_zone_mkey_day) 8511 t = dns_zone_mkey_day; 8512 8513 if (t < dns_zone_mkey_hour) 8514 t = dns_zone_mkey_hour; 8515 } 8516 8517 return (now + t); 8518 } 8519 8520 /* 8521 * This routine is called when no changes are needed in a KEYDATA 8522 * record except to simply update the refresh timer. Caller should 8523 * hold zone lock. 8524 */ 8525 static isc_result_t 8526 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) 8527 { 8528 isc_result_t result; 8529 isc_buffer_t keyb; 8530 unsigned char key_buf[4096]; 8531 dns_rdata_t rdata = DNS_RDATA_INIT; 8532 dns_rdata_keydata_t keydata; 8533 dns_name_t *name; 8534 dns_zone_t *zone = kfetch->zone; 8535 isc_stdtime_t now; 8536 8537 name = dns_fixedname_name(&kfetch->name); 8538 isc_stdtime_get(&now); 8539 8540 for (result = dns_rdataset_first(&kfetch->keydataset); 8541 result == ISC_R_SUCCESS; 8542 result = dns_rdataset_next(&kfetch->keydataset)) { 8543 dns_rdata_reset(&rdata); 8544 dns_rdataset_current(&kfetch->keydataset, &rdata); 8545 8546 /* Delete old version */ 8547 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL, 8548 name, 0, &rdata)); 8549 8550 /* Update refresh timer */ 8551 result = dns_rdata_tostruct(&rdata, &keydata, NULL); 8552 if (result == ISC_R_UNEXPECTEDEND) 8553 continue; 8554 if (result != ISC_R_SUCCESS) 8555 goto failure; 8556 keydata.refresh = refresh_time(kfetch, ISC_TRUE); 8557 set_refreshkeytimer(zone, &keydata, now, ISC_FALSE); 8558 8559 dns_rdata_reset(&rdata); 8560 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 8561 CHECK(dns_rdata_fromstruct(&rdata, 8562 zone->rdclass, dns_rdatatype_keydata, 8563 &keydata, &keyb)); 8564 8565 /* Insert updated version */ 8566 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD, 8567 name, 0, &rdata)); 8568 } 8569 result = ISC_R_SUCCESS; 8570 failure: 8571 return (result); 8572 } 8573 8574 /* 8575 * Verify that DNSKEY set is signed by the key specified in 'keydata'. 8576 */ 8577 static isc_boolean_t 8578 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) { 8579 isc_result_t result; 8580 dns_name_t *keyname; 8581 isc_mem_t *mctx; 8582 dns_rdata_t sigrr = DNS_RDATA_INIT; 8583 dns_rdata_t rr = DNS_RDATA_INIT; 8584 dns_rdata_rrsig_t sig; 8585 dns_rdata_dnskey_t dnskey; 8586 dst_key_t *dstkey = NULL; 8587 unsigned char key_buf[4096]; 8588 isc_buffer_t keyb; 8589 isc_boolean_t answer = ISC_FALSE; 8590 8591 REQUIRE(kfetch != NULL && keydata != NULL); 8592 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset)); 8593 8594 keyname = dns_fixedname_name(&kfetch->name); 8595 mctx = kfetch->zone->view->mctx; 8596 8597 /* Generate a key from keydata */ 8598 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 8599 dns_keydata_todnskey(keydata, &dnskey, NULL); 8600 dns_rdata_fromstruct(&rr, keydata->common.rdclass, 8601 dns_rdatatype_dnskey, &dnskey, &keyb); 8602 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey); 8603 if (result != ISC_R_SUCCESS) 8604 return (ISC_FALSE); 8605 8606 /* See if that key generated any of the signatures */ 8607 for (result = dns_rdataset_first(&kfetch->dnskeysigset); 8608 result == ISC_R_SUCCESS; 8609 result = dns_rdataset_next(&kfetch->dnskeysigset)) 8610 { 8611 dns_fixedname_t fixed; 8612 dns_fixedname_init(&fixed); 8613 8614 dns_rdata_reset(&sigrr); 8615 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr); 8616 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 8617 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8618 8619 if (dst_key_alg(dstkey) == sig.algorithm && 8620 dst_key_rid(dstkey) == sig.keyid) 8621 { 8622 result = dns_dnssec_verify2(keyname, 8623 &kfetch->dnskeyset, 8624 dstkey, ISC_FALSE, mctx, &sigrr, 8625 dns_fixedname_name(&fixed)); 8626 8627 dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3), 8628 "Confirm revoked DNSKEY is self-signed: " 8629 "%s", dns_result_totext(result)); 8630 8631 if (result == ISC_R_SUCCESS) { 8632 answer = ISC_TRUE; 8633 break; 8634 } 8635 } 8636 } 8637 8638 dst_key_free(&dstkey); 8639 return (answer); 8640 } 8641 8642 /* 8643 * A DNSKEY set has been fetched from the zone apex of a zone whose trust 8644 * anchors are being managed; scan the keyset, and update the key zone and the 8645 * local trust anchors according to RFC5011. 8646 */ 8647 static void 8648 keyfetch_done(isc_task_t *task, isc_event_t *event) { 8649 isc_result_t result, eresult; 8650 dns_fetchevent_t *devent; 8651 dns_keyfetch_t *kfetch; 8652 dns_zone_t *zone; 8653 isc_mem_t *mctx = NULL; 8654 dns_keytable_t *secroots = NULL; 8655 dns_dbversion_t *ver = NULL; 8656 dns_diff_t diff; 8657 isc_boolean_t alldone = ISC_FALSE; 8658 isc_boolean_t commit = ISC_FALSE; 8659 dns_name_t *keyname; 8660 dns_rdata_t sigrr = DNS_RDATA_INIT; 8661 dns_rdata_t dnskeyrr = DNS_RDATA_INIT; 8662 dns_rdata_t keydatarr = DNS_RDATA_INIT; 8663 dns_rdata_rrsig_t sig; 8664 dns_rdata_dnskey_t dnskey; 8665 dns_rdata_keydata_t keydata; 8666 isc_boolean_t initializing; 8667 char namebuf[DNS_NAME_FORMATSIZE]; 8668 unsigned char key_buf[4096]; 8669 isc_buffer_t keyb; 8670 dst_key_t *dstkey; 8671 isc_stdtime_t now; 8672 int pending = 0; 8673 isc_boolean_t secure; 8674 isc_boolean_t free_needed; 8675 8676 UNUSED(task); 8677 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE); 8678 INSIST(event->ev_arg != NULL); 8679 8680 kfetch = event->ev_arg; 8681 zone = kfetch->zone; 8682 isc_mem_attach(zone->mctx, &mctx); 8683 keyname = dns_fixedname_name(&kfetch->name); 8684 8685 devent = (dns_fetchevent_t *) event; 8686 eresult = devent->result; 8687 8688 /* Free resources which are not of interest */ 8689 if (devent->node != NULL) 8690 dns_db_detachnode(devent->db, &devent->node); 8691 if (devent->db != NULL) 8692 dns_db_detach(&devent->db); 8693 isc_event_free(&event); 8694 dns_resolver_destroyfetch(&kfetch->fetch); 8695 8696 LOCK_ZONE(zone); 8697 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) 8698 goto cleanup; 8699 8700 isc_stdtime_get(&now); 8701 dns_name_format(keyname, namebuf, sizeof(namebuf)); 8702 8703 result = dns_view_getsecroots(zone->view, &secroots); 8704 INSIST(result == ISC_R_SUCCESS); 8705 8706 dns_diff_init(mctx, &diff); 8707 8708 CHECK(dns_db_newversion(kfetch->db, &ver)); 8709 8710 zone->refreshkeycount--; 8711 alldone = ISC_TF(zone->refreshkeycount == 0); 8712 8713 if (alldone) 8714 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 8715 8716 /* Fetch failed */ 8717 if (eresult != ISC_R_SUCCESS || 8718 !dns_rdataset_isassociated(&kfetch->dnskeyset)) { 8719 dns_zone_log(zone, ISC_LOG_WARNING, 8720 "Unable to fetch DNSKEY set " 8721 "'%s': %s", namebuf, dns_result_totext(eresult)); 8722 CHECK(minimal_update(kfetch, ver, &diff)); 8723 goto done; 8724 } 8725 8726 /* No RRSIGs found */ 8727 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) { 8728 dns_zone_log(zone, ISC_LOG_WARNING, 8729 "No DNSKEY RRSIGs found for " 8730 "'%s': %s", namebuf, dns_result_totext(eresult)); 8731 CHECK(minimal_update(kfetch, ver, &diff)); 8732 goto done; 8733 } 8734 8735 /* 8736 * Clear any cached trust level, as we need to run validation 8737 * over again; trusted keys might have changed. 8738 */ 8739 kfetch->dnskeyset.trust = kfetch->dnskeysigset.trust = dns_trust_none; 8740 8741 /* 8742 * Validate the dnskeyset against the current trusted keys. 8743 */ 8744 for (result = dns_rdataset_first(&kfetch->dnskeysigset); 8745 result == ISC_R_SUCCESS; 8746 result = dns_rdataset_next(&kfetch->dnskeysigset)) { 8747 dns_keynode_t *keynode = NULL; 8748 8749 dns_rdata_reset(&sigrr); 8750 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr); 8751 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 8752 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8753 8754 result = dns_keytable_find(secroots, keyname, &keynode); 8755 while (result == ISC_R_SUCCESS) { 8756 dns_keynode_t *nextnode = NULL; 8757 dns_fixedname_t fixed; 8758 dns_fixedname_init(&fixed); 8759 8760 dstkey = dns_keynode_key(keynode); 8761 if (dstkey == NULL) /* fail_secure() was called */ 8762 break; 8763 8764 if (dst_key_alg(dstkey) == sig.algorithm && 8765 dst_key_id(dstkey) == sig.keyid) { 8766 result = dns_dnssec_verify2(keyname, 8767 &kfetch->dnskeyset, 8768 dstkey, ISC_FALSE, 8769 zone->view->mctx, &sigrr, 8770 dns_fixedname_name(&fixed)); 8771 8772 dns_zone_log(zone, ISC_LOG_DEBUG(3), 8773 "Verifying DNSKEY set for zone " 8774 "'%s' using key %d/%d: %s", 8775 namebuf, sig.keyid, sig.algorithm, 8776 dns_result_totext(result)); 8777 8778 if (result == ISC_R_SUCCESS) { 8779 kfetch->dnskeyset.trust = 8780 dns_trust_secure; 8781 kfetch->dnskeysigset.trust = 8782 dns_trust_secure; 8783 break; 8784 } 8785 } 8786 8787 result = dns_keytable_nextkeynode(secroots, 8788 keynode, &nextnode); 8789 dns_keytable_detachkeynode(secroots, &keynode); 8790 keynode = nextnode; 8791 } 8792 8793 if (keynode != NULL) 8794 dns_keytable_detachkeynode(secroots, &keynode); 8795 8796 if (kfetch->dnskeyset.trust == dns_trust_secure) 8797 break; 8798 } 8799 8800 /* 8801 * If we were not able to verify the answer using the current 8802 * trusted keys then all we can do is look at any revoked keys. 8803 */ 8804 secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure); 8805 8806 /* 8807 * First scan keydataset to find keys that are not in dnskeyset 8808 * - Missing keys which are not scheduled for removal, 8809 * log a warning 8810 * - Missing keys which are scheduled for removal and 8811 * the remove hold-down timer has completed should 8812 * be removed from the key zone 8813 * - Missing keys whose acceptance timers have not yet 8814 * completed, log a warning and reset the acceptance 8815 * timer to 30 days in the future 8816 * - All keys not being removed have their refresh timers 8817 * updated 8818 */ 8819 initializing = ISC_TRUE; 8820 for (result = dns_rdataset_first(&kfetch->keydataset); 8821 result == ISC_R_SUCCESS; 8822 result = dns_rdataset_next(&kfetch->keydataset)) { 8823 dns_rdata_reset(&keydatarr); 8824 dns_rdataset_current(&kfetch->keydataset, &keydatarr); 8825 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); 8826 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8827 8828 /* 8829 * If any keydata record has a nonzero add holddown, then 8830 * there was a pre-existing trust anchor for this domain; 8831 * that means we are *not* initializing it and shouldn't 8832 * automatically trust all the keys we find at the zone apex. 8833 */ 8834 initializing = initializing && ISC_TF(keydata.addhd == 0); 8835 8836 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) { 8837 isc_boolean_t deletekey = ISC_FALSE; 8838 8839 if (!secure) { 8840 if (keydata.removehd != 0 && 8841 keydata.removehd <= now) 8842 deletekey = ISC_TRUE; 8843 } else if (keydata.addhd == 0) { 8844 deletekey = ISC_TRUE; 8845 } else if (keydata.addhd > now) { 8846 dns_zone_log(zone, ISC_LOG_WARNING, 8847 "Pending key unexpectedly missing " 8848 "from %s; restarting acceptance " 8849 "timer", namebuf); 8850 if (keydata.addhd < now + dns_zone_mkey_month) 8851 keydata.addhd = 8852 now + dns_zone_mkey_month; 8853 keydata.refresh = refresh_time(kfetch, 8854 ISC_FALSE); 8855 } else if (keydata.removehd == 0) { 8856 dns_zone_log(zone, ISC_LOG_WARNING, 8857 "Active key unexpectedly missing " 8858 "from %s", namebuf); 8859 keydata.refresh = now + dns_zone_mkey_hour; 8860 } else if (keydata.removehd <= now) { 8861 deletekey = ISC_TRUE; 8862 } else { 8863 keydata.refresh = refresh_time(kfetch, 8864 ISC_FALSE); 8865 } 8866 8867 if (secure || deletekey) { 8868 /* Delete old version */ 8869 CHECK(update_one_rr(kfetch->db, ver, &diff, 8870 DNS_DIFFOP_DEL, keyname, 0, 8871 &keydatarr)); 8872 } 8873 8874 if (!secure || deletekey) 8875 continue; 8876 8877 dns_rdata_reset(&keydatarr); 8878 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 8879 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 8880 dns_rdatatype_keydata, 8881 &keydata, &keyb); 8882 8883 /* Insert updated version */ 8884 CHECK(update_one_rr(kfetch->db, ver, &diff, 8885 DNS_DIFFOP_ADD, keyname, 0, 8886 &keydatarr)); 8887 8888 set_refreshkeytimer(zone, &keydata, now, ISC_FALSE); 8889 } 8890 } 8891 8892 /* 8893 * Next scan dnskeyset: 8894 * - If new keys are found (i.e., lacking a match in keydataset) 8895 * add them to the key zone and set the acceptance timer 8896 * to 30 days in the future (or to immediately if we've 8897 * determined that we're initializing the zone for the 8898 * first time) 8899 * - Previously-known keys that have been revoked 8900 * must be scheduled for removal from the key zone (or, 8901 * if they hadn't been accepted as trust anchors yet 8902 * anyway, removed at once) 8903 * - Previously-known unrevoked keys whose acceptance timers 8904 * have completed are promoted to trust anchors 8905 * - All keys not being removed have their refresh 8906 * timers updated 8907 */ 8908 for (result = dns_rdataset_first(&kfetch->dnskeyset); 8909 result == ISC_R_SUCCESS; 8910 result = dns_rdataset_next(&kfetch->dnskeyset)) 8911 { 8912 isc_boolean_t revoked = ISC_FALSE; 8913 isc_boolean_t newkey = ISC_FALSE; 8914 isc_boolean_t updatekey = ISC_FALSE; 8915 isc_boolean_t deletekey = ISC_FALSE; 8916 isc_boolean_t trustkey = ISC_FALSE; 8917 8918 dns_rdata_reset(&dnskeyrr); 8919 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr); 8920 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 8921 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8922 8923 /* Skip ZSK's */ 8924 if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK)) 8925 continue; 8926 8927 revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE); 8928 8929 if (matchkey(&kfetch->keydataset, &dnskeyrr)) { 8930 dns_rdata_reset(&keydatarr); 8931 dns_rdataset_current(&kfetch->keydataset, &keydatarr); 8932 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); 8933 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8934 8935 if (revoked && revocable(kfetch, &keydata)) { 8936 if (keydata.addhd > now) { 8937 /* 8938 * Key wasn't trusted yet, and now 8939 * it's been revoked? Just remove it 8940 */ 8941 deletekey = ISC_TRUE; 8942 } else if (keydata.removehd == 0) { 8943 /* Remove from secroots */ 8944 dns_view_untrust(zone->view, keyname, 8945 &dnskey, mctx); 8946 8947 /* But ensure there's a null key */ 8948 fail_secure(zone, keyname); 8949 8950 /* If initializing, delete now */ 8951 if (keydata.addhd == 0) 8952 deletekey = ISC_TRUE; 8953 else { 8954 keydata.removehd = now + 8955 dns_zone_mkey_month; 8956 keydata.flags |= 8957 DNS_KEYFLAG_REVOKE; 8958 } 8959 } else if (keydata.removehd < now) { 8960 /* Scheduled for removal */ 8961 deletekey = ISC_TRUE; 8962 } 8963 } else if (revoked && keydata.removehd == 0) { 8964 dns_zone_log(zone, ISC_LOG_WARNING, 8965 "Active key for zone " 8966 "'%s' is revoked but " 8967 "did not self-sign; " 8968 "ignoring.", namebuf); 8969 continue; 8970 } else if (secure) { 8971 if (keydata.removehd != 0) { 8972 /* 8973 * Key isn't revoked--but it 8974 * seems it used to be. 8975 * Remove it now and add it 8976 * back as if it were a fresh key, 8977 * with a 30 day acceptance timer. 8978 */ 8979 deletekey = ISC_TRUE; 8980 newkey = ISC_TRUE; 8981 keydata.removehd = 0; 8982 keydata.addhd = 8983 now + dns_zone_mkey_month; 8984 } else if (keydata.addhd > now) 8985 pending++; 8986 else if (keydata.addhd == 0) 8987 keydata.addhd = now; 8988 8989 if (keydata.addhd <= now) 8990 trustkey = ISC_TRUE; 8991 } else if (keydata.addhd > now) { 8992 /* 8993 * Not secure, and key is pending: 8994 * reset the acceptance timer 8995 */ 8996 pending++; 8997 keydata.addhd = now + dns_zone_mkey_month; 8998 } 8999 9000 if (!deletekey && !newkey) 9001 updatekey = ISC_TRUE; 9002 } else if (secure) { 9003 /* 9004 * Key wasn't in the key zone but it's 9005 * revoked now anyway, so just skip it 9006 */ 9007 if (revoked) 9008 continue; 9009 9010 /* Key wasn't in the key zone: add it */ 9011 newkey = ISC_TRUE; 9012 9013 if (initializing) { 9014 dns_keytag_t tag = 0; 9015 CHECK(compute_tag(keyname, &dnskey, 9016 mctx, &tag)); 9017 dns_zone_log(zone, ISC_LOG_WARNING, 9018 "Initializing automatic trust " 9019 "anchor management for zone '%s'; " 9020 "DNSKEY ID %d is now trusted, " 9021 "waiving the normal 30-day " 9022 "waiting period.", 9023 namebuf, tag); 9024 trustkey = ISC_TRUE; 9025 } 9026 } else { 9027 /* 9028 * No previously known key, and the key is not 9029 * secure, so skip it. 9030 */ 9031 continue; 9032 } 9033 9034 /* Delete old version */ 9035 if (deletekey || !newkey) 9036 CHECK(update_one_rr(kfetch->db, ver, &diff, 9037 DNS_DIFFOP_DEL, keyname, 0, 9038 &keydatarr)); 9039 9040 if (updatekey) { 9041 /* Set refresh timer */ 9042 keydata.refresh = refresh_time(kfetch, ISC_FALSE); 9043 dns_rdata_reset(&keydatarr); 9044 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 9045 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 9046 dns_rdatatype_keydata, 9047 &keydata, &keyb); 9048 9049 /* Insert updated version */ 9050 CHECK(update_one_rr(kfetch->db, ver, &diff, 9051 DNS_DIFFOP_ADD, keyname, 0, 9052 &keydatarr)); 9053 } else if (newkey) { 9054 /* Convert DNSKEY to KEYDATA */ 9055 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 9056 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9057 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0, 9058 NULL); 9059 keydata.addhd = initializing 9060 ? now : now + dns_zone_mkey_month; 9061 keydata.refresh = refresh_time(kfetch, ISC_FALSE); 9062 dns_rdata_reset(&keydatarr); 9063 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 9064 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 9065 dns_rdatatype_keydata, 9066 &keydata, &keyb); 9067 9068 /* Insert into key zone */ 9069 CHECK(update_one_rr(kfetch->db, ver, &diff, 9070 DNS_DIFFOP_ADD, keyname, 0, 9071 &keydatarr)); 9072 } 9073 9074 if (trustkey) { 9075 /* Trust this key. */ 9076 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 9077 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9078 trust_key(zone, keyname, &dnskey, mctx); 9079 } 9080 9081 if (secure && !deletekey) { 9082 INSIST(newkey || updatekey); 9083 set_refreshkeytimer(zone, &keydata, now, ISC_FALSE); 9084 } 9085 } 9086 9087 /* 9088 * RFC5011 says, "A trust point that has all of its trust anchors 9089 * revoked is considered deleted and is treated as if the trust 9090 * point was never configured." But if someone revoked their 9091 * active key before the standby was trusted, that would mean the 9092 * zone would suddenly be nonsecured. We avoid this by checking to 9093 * see if there's pending keydata. If so, we put a null key in 9094 * the security roots; then all queries to the zone will fail. 9095 */ 9096 if (pending != 0) 9097 fail_secure(zone, keyname); 9098 9099 done: 9100 9101 if (!ISC_LIST_EMPTY(diff.tuples)) { 9102 /* Write changes to journal file. */ 9103 CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx, 9104 zone->updatemethod)); 9105 CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done")); 9106 commit = ISC_TRUE; 9107 9108 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 9109 zone_needdump(zone, 30); 9110 } 9111 9112 failure: 9113 9114 dns_diff_clear(&diff); 9115 if (ver != NULL) 9116 dns_db_closeversion(kfetch->db, &ver, commit); 9117 9118 cleanup: 9119 dns_db_detach(&kfetch->db); 9120 9121 INSIST(zone->irefs > 0); 9122 zone->irefs--; 9123 kfetch->zone = NULL; 9124 9125 if (dns_rdataset_isassociated(&kfetch->keydataset)) 9126 dns_rdataset_disassociate(&kfetch->keydataset); 9127 if (dns_rdataset_isassociated(&kfetch->dnskeyset)) 9128 dns_rdataset_disassociate(&kfetch->dnskeyset); 9129 if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) 9130 dns_rdataset_disassociate(&kfetch->dnskeysigset); 9131 9132 dns_name_free(keyname, mctx); 9133 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t)); 9134 isc_mem_detach(&mctx); 9135 9136 if (secroots != NULL) 9137 dns_keytable_detach(&secroots); 9138 9139 free_needed = exit_check(zone); 9140 UNLOCK_ZONE(zone); 9141 if (free_needed) 9142 zone_free(zone); 9143 9144 INSIST(ver == NULL); 9145 } 9146 9147 /* 9148 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY 9149 * records from the zone apex. 9150 */ 9151 static void 9152 zone_refreshkeys(dns_zone_t *zone) { 9153 const char me[] = "zone_refreshkeys"; 9154 isc_result_t result; 9155 dns_rriterator_t rrit; 9156 dns_db_t *db = NULL; 9157 dns_dbversion_t *ver = NULL; 9158 dns_diff_t diff; 9159 dns_rdata_t rdata = DNS_RDATA_INIT; 9160 dns_rdata_keydata_t kd; 9161 isc_stdtime_t now; 9162 isc_boolean_t commit = ISC_FALSE; 9163 isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE; 9164 9165 ENTER; 9166 REQUIRE(zone->db != NULL); 9167 9168 isc_stdtime_get(&now); 9169 9170 LOCK_ZONE(zone); 9171 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 9172 isc_time_settoepoch(&zone->refreshkeytime); 9173 UNLOCK_ZONE(zone); 9174 return; 9175 } 9176 9177 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9178 dns_db_attach(zone->db, &db); 9179 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9180 9181 dns_diff_init(zone->mctx, &diff); 9182 9183 CHECK(dns_db_newversion(db, &ver)); 9184 9185 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING); 9186 9187 dns_rriterator_init(&rrit, db, ver, 0); 9188 for (result = dns_rriterator_first(&rrit); 9189 result == ISC_R_SUCCESS; 9190 result = dns_rriterator_nextrrset(&rrit)) { 9191 isc_stdtime_t timer = 0xffffffff; 9192 dns_name_t *name = NULL, *kname = NULL; 9193 dns_rdataset_t *kdset = NULL; 9194 dns_keyfetch_t *kfetch; 9195 isc_uint32_t ttl; 9196 9197 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL); 9198 if (kdset == NULL || kdset->type != dns_rdatatype_keydata || 9199 !dns_rdataset_isassociated(kdset)) 9200 continue; 9201 9202 /* 9203 * Scan the stored keys looking for ones that need 9204 * removal or refreshing 9205 */ 9206 for (result = dns_rdataset_first(kdset); 9207 result == ISC_R_SUCCESS; 9208 result = dns_rdataset_next(kdset)) { 9209 dns_rdata_reset(&rdata); 9210 dns_rdataset_current(kdset, &rdata); 9211 result = dns_rdata_tostruct(&rdata, &kd, NULL); 9212 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9213 9214 /* Removal timer expired? */ 9215 if (kd.removehd != 0 && kd.removehd < now) { 9216 CHECK(update_one_rr(db, ver, &diff, 9217 DNS_DIFFOP_DEL, name, ttl, 9218 &rdata)); 9219 continue; 9220 } 9221 9222 /* Acceptance timer expired? */ 9223 if (kd.addhd != 0 && kd.addhd < now) 9224 timer = kd.addhd; 9225 9226 /* Or do we just need to refresh the keyset? */ 9227 if (timer > kd.refresh) 9228 timer = kd.refresh; 9229 } 9230 9231 if (timer > now) 9232 continue; 9233 9234 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t)); 9235 if (kfetch == NULL) { 9236 fetch_err = ISC_TRUE; 9237 goto failure; 9238 } 9239 9240 zone->refreshkeycount++; 9241 kfetch->zone = zone; 9242 zone->irefs++; 9243 INSIST(zone->irefs != 0); 9244 dns_fixedname_init(&kfetch->name); 9245 kname = dns_fixedname_name(&kfetch->name); 9246 dns_name_dup(name, zone->mctx, kname); 9247 dns_rdataset_init(&kfetch->dnskeyset); 9248 dns_rdataset_init(&kfetch->dnskeysigset); 9249 dns_rdataset_init(&kfetch->keydataset); 9250 dns_rdataset_clone(kdset, &kfetch->keydataset); 9251 kfetch->db = NULL; 9252 dns_db_attach(db, &kfetch->db); 9253 kfetch->fetch = NULL; 9254 9255 result = dns_resolver_createfetch(zone->view->resolver, 9256 kname, dns_rdatatype_dnskey, 9257 NULL, NULL, NULL, 9258 DNS_FETCHOPT_NOVALIDATE, 9259 zone->task, 9260 keyfetch_done, kfetch, 9261 &kfetch->dnskeyset, 9262 &kfetch->dnskeysigset, 9263 &kfetch->fetch); 9264 if (result == ISC_R_SUCCESS) 9265 fetching = ISC_TRUE; 9266 else { 9267 zone->refreshkeycount--; 9268 zone->irefs--; 9269 dns_db_detach(&kfetch->db); 9270 dns_rdataset_disassociate(&kfetch->keydataset); 9271 dns_name_free(kname, zone->mctx); 9272 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t)); 9273 dns_zone_log(zone, ISC_LOG_WARNING, 9274 "Failed to create fetch for " 9275 "DNSKEY update"); 9276 fetch_err = ISC_TRUE; 9277 } 9278 } 9279 if (!ISC_LIST_EMPTY(diff.tuples)) { 9280 CHECK(update_soa_serial(db, ver, &diff, zone->mctx, 9281 zone->updatemethod)); 9282 CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys")); 9283 commit = ISC_TRUE; 9284 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 9285 zone_needdump(zone, 30); 9286 } 9287 9288 failure: 9289 if (fetch_err) { 9290 /* 9291 * Error during a key fetch; retry in an hour. 9292 */ 9293 isc_time_t timenow, timethen; 9294 char timebuf[80]; 9295 9296 TIME_NOW(&timenow); 9297 DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen); 9298 zone->refreshkeytime = timethen; 9299 zone_settimer(zone, &timenow); 9300 9301 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 9302 dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s", 9303 timebuf); 9304 9305 if (!fetching) 9306 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 9307 } 9308 9309 UNLOCK_ZONE(zone); 9310 9311 dns_diff_clear(&diff); 9312 if (ver != NULL) { 9313 dns_rriterator_destroy(&rrit); 9314 dns_db_closeversion(db, &ver, commit); 9315 } 9316 dns_db_detach(&db); 9317 9318 INSIST(ver == NULL); 9319 } 9320 9321 static void 9322 zone_maintenance(dns_zone_t *zone) { 9323 const char me[] = "zone_maintenance"; 9324 isc_time_t now; 9325 isc_result_t result; 9326 isc_boolean_t dumping; 9327 9328 REQUIRE(DNS_ZONE_VALID(zone)); 9329 ENTER; 9330 9331 /* 9332 * Are we pending load/reload? 9333 */ 9334 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) 9335 return; 9336 9337 /* 9338 * Configuring the view of this zone may have 9339 * failed, for example because the config file 9340 * had a syntax error. In that case, the view 9341 * adb or resolver will be NULL, and we had better not try 9342 * to do further maintenance on it. 9343 */ 9344 if (zone->view == NULL || zone->view->adb == NULL) 9345 return; 9346 9347 TIME_NOW(&now); 9348 9349 /* 9350 * Expire check. 9351 */ 9352 switch (zone->type) { 9353 case dns_zone_redirect: 9354 if (zone->masters == NULL) 9355 break; 9356 case dns_zone_slave: 9357 case dns_zone_stub: 9358 LOCK_ZONE(zone); 9359 if (isc_time_compare(&now, &zone->expiretime) >= 0 && 9360 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 9361 zone_expire(zone); 9362 zone->refreshtime = now; 9363 } 9364 UNLOCK_ZONE(zone); 9365 break; 9366 default: 9367 break; 9368 } 9369 9370 /* 9371 * Up to date check. 9372 */ 9373 switch (zone->type) { 9374 case dns_zone_redirect: 9375 if (zone->masters == NULL) 9376 break; 9377 case dns_zone_slave: 9378 case dns_zone_stub: 9379 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && 9380 isc_time_compare(&now, &zone->refreshtime) >= 0) 9381 dns_zone_refresh(zone); 9382 break; 9383 default: 9384 break; 9385 } 9386 9387 /* 9388 * Slaves send notifies before backing up to disk, masters after. 9389 */ 9390 if (zone->type == dns_zone_slave && 9391 (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 9392 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) && 9393 isc_time_compare(&now, &zone->notifytime) >= 0) 9394 zone_notify(zone, &now); 9395 9396 /* 9397 * Do we need to consolidate the backing store? 9398 */ 9399 switch (zone->type) { 9400 case dns_zone_master: 9401 case dns_zone_slave: 9402 case dns_zone_key: 9403 case dns_zone_redirect: 9404 case dns_zone_stub: 9405 LOCK_ZONE(zone); 9406 if (zone->masterfile != NULL && 9407 isc_time_compare(&now, &zone->dumptime) >= 0 && 9408 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 9409 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) { 9410 dumping = was_dumping(zone); 9411 } else 9412 dumping = ISC_TRUE; 9413 UNLOCK_ZONE(zone); 9414 if (!dumping) { 9415 result = zone_dump(zone, ISC_TRUE); /* task locked */ 9416 if (result != ISC_R_SUCCESS) 9417 dns_zone_log(zone, ISC_LOG_WARNING, 9418 "dump failed: %s", 9419 dns_result_totext(result)); 9420 } 9421 break; 9422 default: 9423 break; 9424 } 9425 9426 /* 9427 * Master/redirect zones send notifies now, if needed 9428 */ 9429 switch (zone->type) { 9430 case dns_zone_master: 9431 case dns_zone_redirect: 9432 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 9433 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))&& 9434 isc_time_compare(&now, &zone->notifytime) >= 0) 9435 zone_notify(zone, &now); 9436 default: 9437 break; 9438 } 9439 9440 /* 9441 * Do we need to refresh keys? 9442 */ 9443 switch (zone->type) { 9444 case dns_zone_key: 9445 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) { 9446 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 9447 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) { 9448 zone_refreshkeys(zone); 9449 } 9450 } 9451 break; 9452 case dns_zone_master: 9453 if (!isc_time_isepoch(&zone->refreshkeytime) && 9454 isc_time_compare(&now, &zone->refreshkeytime) >= 0) 9455 zone_rekey(zone); 9456 default: 9457 break; 9458 } 9459 9460 switch (zone->type) { 9461 case dns_zone_master: 9462 case dns_zone_redirect: 9463 case dns_zone_slave: 9464 /* 9465 * Do we need to sign/resign some RRsets? 9466 */ 9467 if (!isc_time_isepoch(&zone->signingtime) && 9468 isc_time_compare(&now, &zone->signingtime) >= 0) 9469 zone_sign(zone); 9470 else if (!isc_time_isepoch(&zone->resigntime) && 9471 isc_time_compare(&now, &zone->resigntime) >= 0) 9472 zone_resigninc(zone); 9473 else if (!isc_time_isepoch(&zone->nsec3chaintime) && 9474 isc_time_compare(&now, &zone->nsec3chaintime) >= 0) 9475 zone_nsec3chain(zone); 9476 /* 9477 * Do we need to issue a key expiry warning? 9478 */ 9479 if (!isc_time_isepoch(&zone->keywarntime) && 9480 isc_time_compare(&now, &zone->keywarntime) >= 0) 9481 set_key_expiry_warning(zone, zone->key_expiry, 9482 isc_time_seconds(&now)); 9483 break; 9484 9485 default: 9486 break; 9487 } 9488 zone_settimer(zone, &now); 9489 } 9490 9491 void 9492 dns_zone_markdirty(dns_zone_t *zone) { 9493 isc_uint32_t serial; 9494 isc_result_t result = ISC_R_SUCCESS; 9495 dns_zone_t *secure = NULL; 9496 9497 /* 9498 * Obtaining a lock on the zone->secure (see zone_send_secureserial) 9499 * could result in a deadlock due to a LOR so we will spin if we 9500 * can't obtain the both locks. 9501 */ 9502 again: 9503 LOCK_ZONE(zone); 9504 if (zone->type == dns_zone_master) { 9505 if (inline_raw(zone)) { 9506 unsigned int soacount; 9507 secure = zone->secure; 9508 INSIST(secure != zone); 9509 TRYLOCK_ZONE(result, secure); 9510 if (result != ISC_R_SUCCESS) { 9511 UNLOCK_ZONE(zone); 9512 secure = NULL; 9513 #ifdef ISC_PLATFORM_USETHREADS 9514 isc_thread_yield(); 9515 #endif 9516 goto again; 9517 } 9518 9519 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9520 if (zone->db != NULL) { 9521 result = zone_get_from_db(zone, zone->db, NULL, 9522 &soacount, &serial, 9523 NULL, NULL, NULL, 9524 NULL, NULL); 9525 } else 9526 result = DNS_R_NOTLOADED; 9527 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9528 if (result == ISC_R_SUCCESS && soacount > 0U) 9529 zone_send_secureserial(zone, serial); 9530 } 9531 9532 /* XXXMPA make separate call back */ 9533 if (result == ISC_R_SUCCESS) 9534 set_resigntime(zone); 9535 } 9536 if (secure != NULL) 9537 UNLOCK_ZONE(secure); 9538 zone_needdump(zone, DNS_DUMP_DELAY); 9539 UNLOCK_ZONE(zone); 9540 } 9541 9542 void 9543 dns_zone_expire(dns_zone_t *zone) { 9544 REQUIRE(DNS_ZONE_VALID(zone)); 9545 9546 LOCK_ZONE(zone); 9547 zone_expire(zone); 9548 UNLOCK_ZONE(zone); 9549 } 9550 9551 static void 9552 zone_expire(dns_zone_t *zone) { 9553 /* 9554 * 'zone' locked by caller. 9555 */ 9556 9557 REQUIRE(LOCKED_ZONE(zone)); 9558 9559 dns_zone_log(zone, ISC_LOG_WARNING, "expired"); 9560 9561 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED); 9562 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 9563 zone->retry = DNS_ZONE_DEFAULTRETRY; 9564 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 9565 zone_unload(zone); 9566 } 9567 9568 void 9569 dns_zone_refresh(dns_zone_t *zone) { 9570 isc_interval_t i; 9571 isc_uint32_t oldflags; 9572 unsigned int j; 9573 isc_result_t result; 9574 9575 REQUIRE(DNS_ZONE_VALID(zone)); 9576 9577 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 9578 return; 9579 9580 /* 9581 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation 9582 * in progress at a time. 9583 */ 9584 9585 LOCK_ZONE(zone); 9586 oldflags = zone->flags; 9587 if (zone->masterscnt == 0) { 9588 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS); 9589 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0) 9590 dns_zone_log(zone, ISC_LOG_ERROR, 9591 "cannot refresh: no masters"); 9592 goto unlock; 9593 } 9594 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 9595 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 9596 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 9597 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0) 9598 goto unlock; 9599 9600 /* 9601 * Set the next refresh time as if refresh check has failed. 9602 * Setting this to the retry time will do that. XXXMLG 9603 * If we are successful it will be reset using zone->refresh. 9604 */ 9605 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4), 9606 0); 9607 result = isc_time_nowplusinterval(&zone->refreshtime, &i); 9608 if (result != ISC_R_SUCCESS) 9609 dns_zone_log(zone, ISC_LOG_WARNING, 9610 "isc_time_nowplusinterval() failed: %s", 9611 dns_result_totext(result)); 9612 9613 /* 9614 * When lacking user-specified timer values from the SOA, 9615 * do exponential backoff of the retry time up to a 9616 * maximum of six hours. 9617 */ 9618 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) 9619 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600); 9620 9621 zone->curmaster = 0; 9622 for (j = 0; j < zone->masterscnt; j++) 9623 zone->mastersok[j] = ISC_FALSE; 9624 /* initiate soa query */ 9625 queue_soa_query(zone); 9626 unlock: 9627 UNLOCK_ZONE(zone); 9628 } 9629 9630 isc_result_t 9631 dns_zone_flush(dns_zone_t *zone) { 9632 isc_result_t result = ISC_R_SUCCESS; 9633 isc_boolean_t dumping; 9634 9635 REQUIRE(DNS_ZONE_VALID(zone)); 9636 9637 LOCK_ZONE(zone); 9638 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH); 9639 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 9640 zone->masterfile != NULL) { 9641 result = ISC_R_ALREADYRUNNING; 9642 dumping = was_dumping(zone); 9643 } else 9644 dumping = ISC_TRUE; 9645 UNLOCK_ZONE(zone); 9646 if (!dumping) 9647 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */ 9648 return (result); 9649 } 9650 9651 isc_result_t 9652 dns_zone_dump(dns_zone_t *zone) { 9653 isc_result_t result = ISC_R_ALREADYRUNNING; 9654 isc_boolean_t dumping; 9655 9656 REQUIRE(DNS_ZONE_VALID(zone)); 9657 9658 LOCK_ZONE(zone); 9659 dumping = was_dumping(zone); 9660 UNLOCK_ZONE(zone); 9661 if (!dumping) 9662 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */ 9663 return (result); 9664 } 9665 9666 static void 9667 zone_needdump(dns_zone_t *zone, unsigned int delay) { 9668 const char me[] = "zone_needdump"; 9669 isc_time_t dumptime; 9670 isc_time_t now; 9671 9672 /* 9673 * 'zone' locked by caller 9674 */ 9675 9676 REQUIRE(DNS_ZONE_VALID(zone)); 9677 REQUIRE(LOCKED_ZONE(zone)); 9678 ENTER; 9679 9680 /* 9681 * Do we have a place to dump to and are we loaded? 9682 */ 9683 if (zone->masterfile == NULL || 9684 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) 9685 return; 9686 9687 TIME_NOW(&now); 9688 /* add some noise */ 9689 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime); 9690 9691 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 9692 if (isc_time_isepoch(&zone->dumptime) || 9693 isc_time_compare(&zone->dumptime, &dumptime) > 0) 9694 zone->dumptime = dumptime; 9695 if (zone->task != NULL) 9696 zone_settimer(zone, &now); 9697 } 9698 9699 static void 9700 dump_done(void *arg, isc_result_t result) { 9701 const char me[] = "dump_done"; 9702 dns_zone_t *zone = arg; 9703 dns_db_t *db; 9704 dns_dbversion_t *version; 9705 isc_boolean_t again = ISC_FALSE; 9706 isc_boolean_t compact = ISC_FALSE; 9707 isc_uint32_t serial; 9708 isc_result_t tresult; 9709 9710 REQUIRE(DNS_ZONE_VALID(zone)); 9711 9712 ENTER; 9713 9714 if (result == ISC_R_SUCCESS && zone->journal != NULL && 9715 zone->journalsize != -1) { 9716 9717 /* 9718 * We don't own these, zone->dctx must stay valid. 9719 */ 9720 db = dns_dumpctx_db(zone->dctx); 9721 version = dns_dumpctx_version(zone->dctx); 9722 9723 tresult = dns_db_getsoaserial(db, version, &serial); 9724 /* 9725 * If there is a secure version of this zone 9726 * use its serial if it is less than ours. 9727 */ 9728 if (tresult == ISC_R_SUCCESS && inline_raw(zone) && 9729 zone->secure->db != NULL) 9730 { 9731 isc_uint32_t sserial; 9732 isc_result_t mresult; 9733 9734 mresult = dns_db_getsoaserial(zone->secure->db, 9735 NULL, &sserial); 9736 if (mresult == ISC_R_SUCCESS && 9737 isc_serial_lt(sserial, serial)) 9738 serial = sserial; 9739 } 9740 /* 9741 * Note: we are task locked here so we can test 9742 * zone->xfr safely. 9743 */ 9744 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) { 9745 tresult = dns_journal_compact(zone->mctx, 9746 zone->journal, 9747 serial, 9748 zone->journalsize); 9749 switch (tresult) { 9750 case ISC_R_SUCCESS: 9751 case ISC_R_NOSPACE: 9752 case ISC_R_NOTFOUND: 9753 dns_zone_log(zone, ISC_LOG_DEBUG(3), 9754 "dns_journal_compact: %s", 9755 dns_result_totext(tresult)); 9756 break; 9757 default: 9758 dns_zone_log(zone, ISC_LOG_ERROR, 9759 "dns_journal_compact failed: %s", 9760 dns_result_totext(tresult)); 9761 break; 9762 } 9763 } else if (tresult == ISC_R_SUCCESS) { 9764 compact = ISC_TRUE; 9765 zone->compact_serial = serial; 9766 } 9767 } 9768 9769 LOCK_ZONE(zone); 9770 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 9771 if (compact) 9772 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 9773 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) { 9774 /* 9775 * Try again in a short while. 9776 */ 9777 zone_needdump(zone, DNS_DUMP_DELAY); 9778 } else if (result == ISC_R_SUCCESS && 9779 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 9780 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 9781 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 9782 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 9783 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 9784 isc_time_settoepoch(&zone->dumptime); 9785 again = ISC_TRUE; 9786 } else if (result == ISC_R_SUCCESS) 9787 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 9788 9789 if (zone->dctx != NULL) 9790 dns_dumpctx_detach(&zone->dctx); 9791 zonemgr_putio(&zone->writeio); 9792 UNLOCK_ZONE(zone); 9793 if (again) 9794 (void)zone_dump(zone, ISC_FALSE); 9795 dns_zone_idetach(&zone); 9796 } 9797 9798 static isc_result_t 9799 zone_dump(dns_zone_t *zone, isc_boolean_t compact) { 9800 const char me[] = "zone_dump"; 9801 isc_result_t result; 9802 dns_dbversion_t *version = NULL; 9803 isc_boolean_t again; 9804 dns_db_t *db = NULL; 9805 char *masterfile = NULL; 9806 dns_masterformat_t masterformat = dns_masterformat_none; 9807 9808 /* 9809 * 'compact' MUST only be set if we are task locked. 9810 */ 9811 9812 REQUIRE(DNS_ZONE_VALID(zone)); 9813 ENTER; 9814 9815 redo: 9816 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9817 if (zone->db != NULL) 9818 dns_db_attach(zone->db, &db); 9819 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9820 LOCK_ZONE(zone); 9821 if (zone->masterfile != NULL) { 9822 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile); 9823 masterformat = zone->masterformat; 9824 } 9825 UNLOCK_ZONE(zone); 9826 if (db == NULL) { 9827 result = DNS_R_NOTLOADED; 9828 goto fail; 9829 } 9830 if (masterfile == NULL) { 9831 result = DNS_R_NOMASTERFILE; 9832 goto fail; 9833 } 9834 9835 if (compact && zone->type != dns_zone_stub) { 9836 dns_zone_t *dummy = NULL; 9837 LOCK_ZONE(zone); 9838 zone_iattach(zone, &dummy); 9839 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task, 9840 zone_gotwritehandle, zone, 9841 &zone->writeio); 9842 if (result != ISC_R_SUCCESS) 9843 zone_idetach(&dummy); 9844 else 9845 result = DNS_R_CONTINUE; 9846 UNLOCK_ZONE(zone); 9847 } else { 9848 const dns_master_style_t *output_style; 9849 9850 dns_masterrawheader_t rawdata; 9851 dns_db_currentversion(db, &version); 9852 dns_master_initrawheader(&rawdata); 9853 if (inline_secure(zone)) 9854 get_raw_serial(zone->raw, &rawdata); 9855 if (zone->type == dns_zone_key) 9856 output_style = &dns_master_style_keyzone; 9857 else 9858 output_style = &dns_master_style_default; 9859 result = dns_master_dump3(zone->mctx, db, version, 9860 output_style, masterfile, 9861 masterformat, &rawdata); 9862 dns_db_closeversion(db, &version, ISC_FALSE); 9863 } 9864 fail: 9865 if (db != NULL) 9866 dns_db_detach(&db); 9867 if (masterfile != NULL) 9868 isc_mem_free(zone->mctx, masterfile); 9869 masterfile = NULL; 9870 9871 if (result == DNS_R_CONTINUE) 9872 return (ISC_R_SUCCESS); /* XXXMPA */ 9873 9874 again = ISC_FALSE; 9875 LOCK_ZONE(zone); 9876 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 9877 if (result != ISC_R_SUCCESS) { 9878 /* 9879 * Try again in a short while. 9880 */ 9881 zone_needdump(zone, DNS_DUMP_DELAY); 9882 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 9883 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 9884 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 9885 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 9886 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 9887 isc_time_settoepoch(&zone->dumptime); 9888 again = ISC_TRUE; 9889 } else 9890 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 9891 UNLOCK_ZONE(zone); 9892 if (again) 9893 goto redo; 9894 9895 return (result); 9896 } 9897 9898 static isc_result_t 9899 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style, 9900 dns_masterformat_t format, const isc_uint32_t rawversion) 9901 { 9902 isc_result_t result; 9903 dns_dbversion_t *version = NULL; 9904 dns_db_t *db = NULL; 9905 dns_masterrawheader_t rawdata; 9906 9907 REQUIRE(DNS_ZONE_VALID(zone)); 9908 9909 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9910 if (zone->db != NULL) 9911 dns_db_attach(zone->db, &db); 9912 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9913 if (db == NULL) 9914 return (DNS_R_NOTLOADED); 9915 9916 dns_db_currentversion(db, &version); 9917 dns_master_initrawheader(&rawdata); 9918 if (rawversion == 0) 9919 rawdata.flags |= DNS_MASTERRAW_COMPAT; 9920 else if (inline_secure(zone)) 9921 get_raw_serial(zone->raw, &rawdata); 9922 else if (zone->sourceserialset) { 9923 rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET; 9924 rawdata.sourceserial = zone->sourceserial; 9925 } 9926 result = dns_master_dumptostream3(zone->mctx, db, version, style, 9927 format, &rawdata, fd); 9928 dns_db_closeversion(db, &version, ISC_FALSE); 9929 dns_db_detach(&db); 9930 return (result); 9931 } 9932 9933 isc_result_t 9934 dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, 9935 const dns_master_style_t *style, 9936 const isc_uint32_t rawversion) 9937 { 9938 return (dumptostream(zone, fd, style, format, rawversion)); 9939 } 9940 9941 isc_result_t 9942 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, 9943 const dns_master_style_t *style) { 9944 return (dumptostream(zone, fd, style, format, DNS_RAWFORMAT_VERSION)); 9945 } 9946 9947 isc_result_t 9948 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) { 9949 return (dumptostream(zone, fd, &dns_master_style_default, 9950 dns_masterformat_text, 0)); 9951 } 9952 9953 isc_result_t 9954 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) { 9955 return (dumptostream(zone, fd, &dns_master_style_full, 9956 dns_masterformat_text, 0)); 9957 } 9958 9959 void 9960 dns_zone_unload(dns_zone_t *zone) { 9961 REQUIRE(DNS_ZONE_VALID(zone)); 9962 9963 LOCK_ZONE(zone); 9964 zone_unload(zone); 9965 UNLOCK_ZONE(zone); 9966 } 9967 9968 static void 9969 notify_cancel(dns_zone_t *zone) { 9970 dns_notify_t *notify; 9971 9972 /* 9973 * 'zone' locked by caller. 9974 */ 9975 9976 REQUIRE(LOCKED_ZONE(zone)); 9977 9978 for (notify = ISC_LIST_HEAD(zone->notifies); 9979 notify != NULL; 9980 notify = ISC_LIST_NEXT(notify, link)) { 9981 if (notify->find != NULL) 9982 dns_adb_cancelfind(notify->find); 9983 if (notify->request != NULL) 9984 dns_request_cancel(notify->request); 9985 } 9986 } 9987 9988 static void 9989 forward_cancel(dns_zone_t *zone) { 9990 dns_forward_t *forward; 9991 9992 /* 9993 * 'zone' locked by caller. 9994 */ 9995 9996 REQUIRE(LOCKED_ZONE(zone)); 9997 9998 for (forward = ISC_LIST_HEAD(zone->forwards); 9999 forward != NULL; 10000 forward = ISC_LIST_NEXT(forward, link)) { 10001 if (forward->request != NULL) 10002 dns_request_cancel(forward->request); 10003 } 10004 } 10005 10006 static void 10007 zone_unload(dns_zone_t *zone) { 10008 /* 10009 * 'zone' locked by caller. 10010 */ 10011 10012 REQUIRE(LOCKED_ZONE(zone)); 10013 10014 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 10015 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 10016 if (zone->writeio != NULL) 10017 zonemgr_cancelio(zone->writeio); 10018 10019 if (zone->dctx != NULL) 10020 dns_dumpctx_cancel(zone->dctx); 10021 } 10022 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 10023 zone_detachdb(zone); 10024 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 10025 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED); 10026 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 10027 } 10028 10029 void 10030 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) { 10031 REQUIRE(DNS_ZONE_VALID(zone)); 10032 REQUIRE(val > 0); 10033 10034 zone->minrefresh = val; 10035 } 10036 10037 void 10038 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) { 10039 REQUIRE(DNS_ZONE_VALID(zone)); 10040 REQUIRE(val > 0); 10041 10042 zone->maxrefresh = val; 10043 } 10044 10045 void 10046 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) { 10047 REQUIRE(DNS_ZONE_VALID(zone)); 10048 REQUIRE(val > 0); 10049 10050 zone->minretry = val; 10051 } 10052 10053 void 10054 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) { 10055 REQUIRE(DNS_ZONE_VALID(zone)); 10056 REQUIRE(val > 0); 10057 10058 zone->maxretry = val; 10059 } 10060 10061 static isc_boolean_t 10062 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name, 10063 isc_sockaddr_t *addr, dns_tsigkey_t *key) 10064 { 10065 dns_notify_t *notify; 10066 dns_zonemgr_t *zmgr; 10067 isc_result_t result; 10068 10069 for (notify = ISC_LIST_HEAD(zone->notifies); 10070 notify != NULL; 10071 notify = ISC_LIST_NEXT(notify, link)) { 10072 if (notify->request != NULL) 10073 continue; 10074 if ((flags & DNS_NOTIFY_STARTUP) == 0) 10075 notify->flags &= ~DNS_NOTIFY_STARTUP; 10076 if (name != NULL && dns_name_dynamic(¬ify->ns) && 10077 dns_name_equal(name, ¬ify->ns)) 10078 goto requeue; 10079 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst) && 10080 notify->key == key) 10081 goto requeue; 10082 } 10083 return (ISC_FALSE); 10084 10085 requeue: 10086 /* 10087 * If we are enqueued on the startup ratelimiter and this is 10088 * not a startup notify, re-enqueue on the normal notify 10089 * ratelimiter. 10090 */ 10091 if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0) { 10092 zmgr = notify->zone->zmgr; 10093 result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl, 10094 notify->event); 10095 if (result != ISC_R_SUCCESS) 10096 return (ISC_TRUE); 10097 result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl, 10098 notify->zone->task, 10099 ¬ify->event); 10100 if (result != ISC_R_SUCCESS) { 10101 isc_event_free(¬ify->event); 10102 return (ISC_FALSE); 10103 } 10104 } 10105 10106 return (ISC_TRUE); 10107 } 10108 10109 static isc_boolean_t 10110 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) { 10111 dns_tsigkey_t *key = NULL; 10112 isc_sockaddr_t src; 10113 isc_sockaddr_t any; 10114 isc_boolean_t isself; 10115 isc_netaddr_t dstaddr; 10116 isc_result_t result; 10117 10118 if (zone->view == NULL || zone->isself == NULL) 10119 return (ISC_FALSE); 10120 10121 switch (isc_sockaddr_pf(dst)) { 10122 case PF_INET: 10123 src = zone->notifysrc4; 10124 isc_sockaddr_any(&any); 10125 break; 10126 case PF_INET6: 10127 src = zone->notifysrc6; 10128 isc_sockaddr_any6(&any); 10129 break; 10130 default: 10131 return (ISC_FALSE); 10132 } 10133 10134 /* 10135 * When sending from any the kernel will assign a source address 10136 * that matches the destination address. 10137 */ 10138 if (isc_sockaddr_eqaddr(&any, &src)) 10139 src = *dst; 10140 10141 isc_netaddr_fromsockaddr(&dstaddr, dst); 10142 result = dns_view_getpeertsig(zone->view, &dstaddr, &key); 10143 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) 10144 return (ISC_FALSE); 10145 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass, 10146 zone->isselfarg); 10147 if (key != NULL) 10148 dns_tsigkey_detach(&key); 10149 return (isself); 10150 } 10151 10152 static void 10153 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) { 10154 isc_mem_t *mctx; 10155 10156 /* 10157 * Caller holds zone lock. 10158 */ 10159 REQUIRE(DNS_NOTIFY_VALID(notify)); 10160 10161 if (notify->zone != NULL) { 10162 if (!locked) 10163 LOCK_ZONE(notify->zone); 10164 REQUIRE(LOCKED_ZONE(notify->zone)); 10165 if (ISC_LINK_LINKED(notify, link)) 10166 ISC_LIST_UNLINK(notify->zone->notifies, notify, link); 10167 if (!locked) 10168 UNLOCK_ZONE(notify->zone); 10169 if (locked) 10170 zone_idetach(¬ify->zone); 10171 else 10172 dns_zone_idetach(¬ify->zone); 10173 } 10174 if (notify->find != NULL) 10175 dns_adb_destroyfind(¬ify->find); 10176 if (notify->request != NULL) 10177 dns_request_destroy(¬ify->request); 10178 if (dns_name_dynamic(¬ify->ns)) 10179 dns_name_free(¬ify->ns, notify->mctx); 10180 if (notify->key != NULL) 10181 dns_tsigkey_detach(¬ify->key); 10182 mctx = notify->mctx; 10183 isc_mem_put(notify->mctx, notify, sizeof(*notify)); 10184 isc_mem_detach(&mctx); 10185 } 10186 10187 static isc_result_t 10188 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) { 10189 dns_notify_t *notify; 10190 10191 REQUIRE(notifyp != NULL && *notifyp == NULL); 10192 10193 notify = isc_mem_get(mctx, sizeof(*notify)); 10194 if (notify == NULL) 10195 return (ISC_R_NOMEMORY); 10196 10197 notify->mctx = NULL; 10198 isc_mem_attach(mctx, ¬ify->mctx); 10199 notify->flags = flags; 10200 notify->zone = NULL; 10201 notify->find = NULL; 10202 notify->request = NULL; 10203 notify->key = NULL; 10204 notify->event = NULL; 10205 isc_sockaddr_any(¬ify->dst); 10206 dns_name_init(¬ify->ns, NULL); 10207 ISC_LINK_INIT(notify, link); 10208 notify->magic = NOTIFY_MAGIC; 10209 *notifyp = notify; 10210 return (ISC_R_SUCCESS); 10211 } 10212 10213 /* 10214 * XXXAG should check for DNS_ZONEFLG_EXITING 10215 */ 10216 static void 10217 process_adb_event(isc_task_t *task, isc_event_t *ev) { 10218 dns_notify_t *notify; 10219 isc_eventtype_t result; 10220 10221 UNUSED(task); 10222 10223 notify = ev->ev_arg; 10224 REQUIRE(DNS_NOTIFY_VALID(notify)); 10225 INSIST(task == notify->zone->task); 10226 result = ev->ev_type; 10227 isc_event_free(&ev); 10228 if (result == DNS_EVENT_ADBMOREADDRESSES) { 10229 dns_adb_destroyfind(¬ify->find); 10230 notify_find_address(notify); 10231 return; 10232 } 10233 if (result == DNS_EVENT_ADBNOMOREADDRESSES) { 10234 LOCK_ZONE(notify->zone); 10235 notify_send(notify); 10236 UNLOCK_ZONE(notify->zone); 10237 } 10238 notify_destroy(notify, ISC_FALSE); 10239 } 10240 10241 static void 10242 notify_find_address(dns_notify_t *notify) { 10243 isc_result_t result; 10244 unsigned int options; 10245 10246 REQUIRE(DNS_NOTIFY_VALID(notify)); 10247 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET | 10248 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME; 10249 10250 if (notify->zone->view->adb == NULL) 10251 goto destroy; 10252 10253 result = dns_adb_createfind(notify->zone->view->adb, 10254 notify->zone->task, 10255 process_adb_event, notify, 10256 ¬ify->ns, dns_rootname, 0, 10257 options, 0, NULL, 10258 notify->zone->view->dstport, 10259 ¬ify->find); 10260 10261 /* Something failed? */ 10262 if (result != ISC_R_SUCCESS) 10263 goto destroy; 10264 10265 /* More addresses pending? */ 10266 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) 10267 return; 10268 10269 /* We have as many addresses as we can get. */ 10270 LOCK_ZONE(notify->zone); 10271 notify_send(notify); 10272 UNLOCK_ZONE(notify->zone); 10273 10274 destroy: 10275 notify_destroy(notify, ISC_FALSE); 10276 } 10277 10278 10279 static isc_result_t 10280 notify_send_queue(dns_notify_t *notify, isc_boolean_t startup) { 10281 isc_event_t *e; 10282 isc_result_t result; 10283 10284 INSIST(notify->event == NULL); 10285 e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR, 10286 notify_send_toaddr, notify, sizeof(isc_event_t)); 10287 if (e == NULL) 10288 return (ISC_R_NOMEMORY); 10289 if (startup) 10290 notify->event = e; 10291 e->ev_arg = notify; 10292 e->ev_sender = NULL; 10293 result = isc_ratelimiter_enqueue(startup 10294 ? notify->zone->zmgr->startupnotifyrl 10295 : notify->zone->zmgr->notifyrl, 10296 notify->zone->task, &e); 10297 if (result != ISC_R_SUCCESS) { 10298 isc_event_free(&e); 10299 notify->event = NULL; 10300 } 10301 return (result); 10302 } 10303 10304 static void 10305 notify_send_toaddr(isc_task_t *task, isc_event_t *event) { 10306 dns_notify_t *notify; 10307 isc_result_t result; 10308 dns_message_t *message = NULL; 10309 isc_netaddr_t dstip; 10310 dns_tsigkey_t *key = NULL; 10311 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 10312 isc_sockaddr_t src; 10313 int timeout; 10314 isc_boolean_t have_notifysource = ISC_FALSE; 10315 isc_boolean_t have_notifydscp = ISC_FALSE; 10316 isc_dscp_t dscp = -1; 10317 10318 notify = event->ev_arg; 10319 REQUIRE(DNS_NOTIFY_VALID(notify)); 10320 10321 UNUSED(task); 10322 10323 LOCK_ZONE(notify->zone); 10324 10325 notify->event = NULL; 10326 10327 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) { 10328 result = ISC_R_CANCELED; 10329 goto cleanup; 10330 } 10331 10332 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 || 10333 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) || 10334 notify->zone->view->requestmgr == NULL || 10335 notify->zone->db == NULL) { 10336 result = ISC_R_CANCELED; 10337 goto cleanup; 10338 } 10339 10340 /* 10341 * The raw IPv4 address should also exist. Don't send to the 10342 * mapped form. 10343 */ 10344 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 && 10345 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) { 10346 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 10347 notify_log(notify->zone, ISC_LOG_DEBUG(3), 10348 "notify: ignoring IPv6 mapped IPV4 address: %s", 10349 addrbuf); 10350 result = ISC_R_CANCELED; 10351 goto cleanup; 10352 } 10353 10354 result = notify_createmessage(notify->zone, notify->flags, &message); 10355 if (result != ISC_R_SUCCESS) 10356 goto cleanup; 10357 10358 if (notify->key != NULL) { 10359 /* Transfer ownership of key */ 10360 key = notify->key; 10361 notify->key = NULL; 10362 } else { 10363 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst); 10364 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 10365 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key); 10366 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 10367 notify_log(notify->zone, ISC_LOG_ERROR, 10368 "NOTIFY to %s not sent. " 10369 "Peer TSIG key lookup failure.", addrbuf); 10370 goto cleanup_message; 10371 } 10372 } 10373 10374 /* XXX: should we log the tsig key too? */ 10375 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s", 10376 addrbuf); 10377 if (notify->zone->view->peers != NULL) { 10378 dns_peer_t *peer = NULL; 10379 result = dns_peerlist_peerbyaddr(notify->zone->view->peers, 10380 &dstip, &peer); 10381 if (result == ISC_R_SUCCESS) { 10382 result = dns_peer_getnotifysource(peer, &src); 10383 if (result == ISC_R_SUCCESS) 10384 have_notifysource = ISC_TRUE; 10385 dns_peer_getnotifydscp(peer, &dscp); 10386 if (dscp != -1) 10387 have_notifydscp = ISC_TRUE; 10388 } 10389 } 10390 switch (isc_sockaddr_pf(¬ify->dst)) { 10391 case PF_INET: 10392 if (!have_notifysource) 10393 src = notify->zone->notifysrc4; 10394 if (!have_notifydscp) 10395 dscp = notify->zone->notifysrc4dscp; 10396 break; 10397 case PF_INET6: 10398 if (!have_notifysource) 10399 src = notify->zone->notifysrc6; 10400 if (!have_notifydscp) 10401 dscp = notify->zone->notifysrc6dscp; 10402 break; 10403 default: 10404 result = ISC_R_NOTIMPLEMENTED; 10405 goto cleanup_key; 10406 } 10407 timeout = 15; 10408 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) 10409 timeout = 30; 10410 result = dns_request_createvia4(notify->zone->view->requestmgr, 10411 message, &src, ¬ify->dst, dscp, 10412 0, key, timeout * 3, timeout, 0, 10413 notify->zone->task, notify_done, 10414 notify, ¬ify->request); 10415 if (result == ISC_R_SUCCESS) { 10416 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) { 10417 inc_stats(notify->zone, 10418 dns_zonestatscounter_notifyoutv4); 10419 } else { 10420 inc_stats(notify->zone, 10421 dns_zonestatscounter_notifyoutv6); 10422 } 10423 } 10424 10425 cleanup_key: 10426 if (key != NULL) 10427 dns_tsigkey_detach(&key); 10428 cleanup_message: 10429 dns_message_destroy(&message); 10430 cleanup: 10431 UNLOCK_ZONE(notify->zone); 10432 isc_event_free(&event); 10433 if (result != ISC_R_SUCCESS) 10434 notify_destroy(notify, ISC_FALSE); 10435 } 10436 10437 static void 10438 notify_send(dns_notify_t *notify) { 10439 dns_adbaddrinfo_t *ai; 10440 isc_sockaddr_t dst; 10441 isc_result_t result; 10442 dns_notify_t *new = NULL; 10443 unsigned int flags; 10444 isc_boolean_t startup; 10445 10446 /* 10447 * Zone lock held by caller. 10448 */ 10449 REQUIRE(DNS_NOTIFY_VALID(notify)); 10450 REQUIRE(LOCKED_ZONE(notify->zone)); 10451 10452 for (ai = ISC_LIST_HEAD(notify->find->list); 10453 ai != NULL; 10454 ai = ISC_LIST_NEXT(ai, publink)) { 10455 dst = ai->sockaddr; 10456 if (notify_isqueued(notify->zone, notify->flags, NULL, &dst, 10457 NULL)) 10458 continue; 10459 if (notify_isself(notify->zone, &dst)) 10460 continue; 10461 new = NULL; 10462 flags = notify->flags & DNS_NOTIFY_NOSOA; 10463 result = notify_create(notify->mctx, flags, &new); 10464 if (result != ISC_R_SUCCESS) 10465 goto cleanup; 10466 zone_iattach(notify->zone, &new->zone); 10467 ISC_LIST_APPEND(new->zone->notifies, new, link); 10468 new->dst = dst; 10469 startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0); 10470 result = notify_send_queue(new, startup); 10471 if (result != ISC_R_SUCCESS) 10472 goto cleanup; 10473 new = NULL; 10474 } 10475 10476 cleanup: 10477 if (new != NULL) 10478 notify_destroy(new, ISC_TRUE); 10479 } 10480 10481 void 10482 dns_zone_notify(dns_zone_t *zone) { 10483 isc_time_t now; 10484 10485 REQUIRE(DNS_ZONE_VALID(zone)); 10486 10487 LOCK_ZONE(zone); 10488 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 10489 10490 TIME_NOW(&now); 10491 zone_settimer(zone, &now); 10492 UNLOCK_ZONE(zone); 10493 } 10494 10495 static void 10496 zone_notify(dns_zone_t *zone, isc_time_t *now) { 10497 dns_dbnode_t *node = NULL; 10498 dns_db_t *zonedb = NULL; 10499 dns_dbversion_t *version = NULL; 10500 dns_name_t *origin = NULL; 10501 dns_name_t master; 10502 dns_rdata_ns_t ns; 10503 dns_rdata_soa_t soa; 10504 isc_uint32_t serial; 10505 dns_rdata_t rdata = DNS_RDATA_INIT; 10506 dns_rdataset_t nsrdset; 10507 dns_rdataset_t soardset; 10508 isc_result_t result; 10509 unsigned int i; 10510 isc_sockaddr_t dst; 10511 isc_boolean_t isqueued; 10512 dns_notifytype_t notifytype; 10513 unsigned int flags = 0; 10514 isc_boolean_t loggednotify = ISC_FALSE; 10515 isc_boolean_t startup; 10516 10517 REQUIRE(DNS_ZONE_VALID(zone)); 10518 10519 LOCK_ZONE(zone); 10520 startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 10521 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 10522 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY); 10523 notifytype = zone->notifytype; 10524 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime); 10525 UNLOCK_ZONE(zone); 10526 10527 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 10528 return; 10529 10530 if (notifytype == dns_notifytype_no) 10531 return; 10532 10533 if (notifytype == dns_notifytype_masteronly && 10534 zone->type != dns_zone_master) 10535 return; 10536 10537 origin = &zone->origin; 10538 10539 /* 10540 * If the zone is dialup we are done as we don't want to send 10541 * the current soa so as to force a refresh query. 10542 */ 10543 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) 10544 flags |= DNS_NOTIFY_NOSOA; 10545 10546 /* 10547 * Record that this was a notify due to starting up. 10548 */ 10549 if (startup) 10550 flags |= DNS_NOTIFY_STARTUP; 10551 10552 /* 10553 * Get SOA RRset. 10554 */ 10555 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 10556 if (zone->db != NULL) 10557 dns_db_attach(zone->db, &zonedb); 10558 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 10559 if (zonedb == NULL) 10560 return; 10561 dns_db_currentversion(zonedb, &version); 10562 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node); 10563 if (result != ISC_R_SUCCESS) 10564 goto cleanup1; 10565 10566 dns_rdataset_init(&soardset); 10567 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, 10568 dns_rdatatype_none, 0, &soardset, NULL); 10569 if (result != ISC_R_SUCCESS) 10570 goto cleanup2; 10571 10572 /* 10573 * Find serial and master server's name. 10574 */ 10575 dns_name_init(&master, NULL); 10576 result = dns_rdataset_first(&soardset); 10577 if (result != ISC_R_SUCCESS) 10578 goto cleanup3; 10579 dns_rdataset_current(&soardset, &rdata); 10580 result = dns_rdata_tostruct(&rdata, &soa, NULL); 10581 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10582 dns_rdata_reset(&rdata); 10583 result = dns_name_dup(&soa.origin, zone->mctx, &master); 10584 serial = soa.serial; 10585 dns_rdataset_disassociate(&soardset); 10586 if (result != ISC_R_SUCCESS) 10587 goto cleanup3; 10588 10589 /* 10590 * Enqueue notify requests for 'also-notify' servers. 10591 */ 10592 LOCK_ZONE(zone); 10593 for (i = 0; i < zone->notifycnt; i++) { 10594 dns_tsigkey_t *key = NULL; 10595 dns_notify_t *notify = NULL; 10596 10597 if ((zone->notifykeynames != NULL) && 10598 (zone->notifykeynames[i] != NULL)) { 10599 dns_view_t *view = dns_zone_getview(zone); 10600 dns_name_t *keyname = zone->notifykeynames[i]; 10601 (void)dns_view_gettsig(view, keyname, &key); 10602 } 10603 10604 dst = zone->notify[i]; 10605 if (notify_isqueued(zone, flags, NULL, &dst, key)) { 10606 if (key != NULL) 10607 dns_tsigkey_detach(&key); 10608 continue; 10609 } 10610 10611 result = notify_create(zone->mctx, flags, ¬ify); 10612 if (result != ISC_R_SUCCESS) { 10613 if (key != NULL) 10614 dns_tsigkey_detach(&key); 10615 continue; 10616 } 10617 10618 zone_iattach(zone, ¬ify->zone); 10619 notify->dst = dst; 10620 10621 INSIST(notify->key == NULL); 10622 10623 if (key != NULL) { 10624 notify->key = key; 10625 key = NULL; 10626 } 10627 10628 ISC_LIST_APPEND(zone->notifies, notify, link); 10629 result = notify_send_queue(notify, startup); 10630 if (result != ISC_R_SUCCESS) 10631 notify_destroy(notify, ISC_TRUE); 10632 if (!loggednotify) { 10633 notify_log(zone, ISC_LOG_INFO, 10634 "sending notifies (serial %u)", 10635 serial); 10636 loggednotify = ISC_TRUE; 10637 } 10638 } 10639 UNLOCK_ZONE(zone); 10640 10641 if (notifytype == dns_notifytype_explicit) 10642 goto cleanup3; 10643 10644 /* 10645 * Process NS RRset to generate notifies. 10646 */ 10647 10648 dns_rdataset_init(&nsrdset); 10649 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns, 10650 dns_rdatatype_none, 0, &nsrdset, NULL); 10651 if (result != ISC_R_SUCCESS) 10652 goto cleanup3; 10653 10654 result = dns_rdataset_first(&nsrdset); 10655 while (result == ISC_R_SUCCESS) { 10656 dns_notify_t *notify = NULL; 10657 10658 dns_rdataset_current(&nsrdset, &rdata); 10659 result = dns_rdata_tostruct(&rdata, &ns, NULL); 10660 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10661 dns_rdata_reset(&rdata); 10662 /* 10663 * Don't notify the master server unless explicitly 10664 * configured to do so. 10665 */ 10666 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) && 10667 dns_name_compare(&master, &ns.name) == 0) { 10668 result = dns_rdataset_next(&nsrdset); 10669 continue; 10670 } 10671 10672 if (!loggednotify) { 10673 notify_log(zone, ISC_LOG_INFO, 10674 "sending notifies (serial %u)", 10675 serial); 10676 loggednotify = ISC_TRUE; 10677 } 10678 10679 LOCK_ZONE(zone); 10680 isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL); 10681 UNLOCK_ZONE(zone); 10682 if (isqueued) { 10683 result = dns_rdataset_next(&nsrdset); 10684 continue; 10685 } 10686 result = notify_create(zone->mctx, flags, ¬ify); 10687 if (result != ISC_R_SUCCESS) 10688 continue; 10689 dns_zone_iattach(zone, ¬ify->zone); 10690 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns); 10691 if (result != ISC_R_SUCCESS) { 10692 LOCK_ZONE(zone); 10693 notify_destroy(notify, ISC_TRUE); 10694 UNLOCK_ZONE(zone); 10695 continue; 10696 } 10697 LOCK_ZONE(zone); 10698 ISC_LIST_APPEND(zone->notifies, notify, link); 10699 UNLOCK_ZONE(zone); 10700 notify_find_address(notify); 10701 result = dns_rdataset_next(&nsrdset); 10702 } 10703 dns_rdataset_disassociate(&nsrdset); 10704 10705 cleanup3: 10706 if (dns_name_dynamic(&master)) 10707 dns_name_free(&master, zone->mctx); 10708 cleanup2: 10709 dns_db_detachnode(zonedb, &node); 10710 cleanup1: 10711 dns_db_closeversion(zonedb, &version, ISC_FALSE); 10712 dns_db_detach(&zonedb); 10713 } 10714 10715 /*** 10716 *** Private 10717 ***/ 10718 10719 static inline isc_result_t 10720 save_nsrrset(dns_message_t *message, dns_name_t *name, 10721 dns_db_t *db, dns_dbversion_t *version) 10722 { 10723 dns_rdataset_t *nsrdataset = NULL; 10724 dns_rdataset_t *rdataset = NULL; 10725 dns_dbnode_t *node = NULL; 10726 dns_rdata_ns_t ns; 10727 isc_result_t result; 10728 dns_rdata_t rdata = DNS_RDATA_INIT; 10729 10730 /* 10731 * Extract NS RRset from message. 10732 */ 10733 result = dns_message_findname(message, DNS_SECTION_ANSWER, name, 10734 dns_rdatatype_ns, dns_rdatatype_none, 10735 NULL, &nsrdataset); 10736 if (result != ISC_R_SUCCESS) 10737 goto fail; 10738 10739 /* 10740 * Add NS rdataset. 10741 */ 10742 result = dns_db_findnode(db, name, ISC_TRUE, &node); 10743 if (result != ISC_R_SUCCESS) 10744 goto fail; 10745 result = dns_db_addrdataset(db, node, version, 0, 10746 nsrdataset, 0, NULL); 10747 dns_db_detachnode(db, &node); 10748 if (result != ISC_R_SUCCESS) 10749 goto fail; 10750 /* 10751 * Add glue rdatasets. 10752 */ 10753 for (result = dns_rdataset_first(nsrdataset); 10754 result == ISC_R_SUCCESS; 10755 result = dns_rdataset_next(nsrdataset)) { 10756 dns_rdataset_current(nsrdataset, &rdata); 10757 result = dns_rdata_tostruct(&rdata, &ns, NULL); 10758 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10759 dns_rdata_reset(&rdata); 10760 if (!dns_name_issubdomain(&ns.name, name)) 10761 continue; 10762 rdataset = NULL; 10763 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL, 10764 &ns.name, dns_rdatatype_aaaa, 10765 dns_rdatatype_none, NULL, 10766 &rdataset); 10767 if (result == ISC_R_SUCCESS) { 10768 result = dns_db_findnode(db, &ns.name, 10769 ISC_TRUE, &node); 10770 if (result != ISC_R_SUCCESS) 10771 goto fail; 10772 result = dns_db_addrdataset(db, node, version, 0, 10773 rdataset, 0, NULL); 10774 dns_db_detachnode(db, &node); 10775 if (result != ISC_R_SUCCESS) 10776 goto fail; 10777 } 10778 rdataset = NULL; 10779 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL, 10780 &ns.name, dns_rdatatype_a, 10781 dns_rdatatype_none, NULL, 10782 &rdataset); 10783 if (result == ISC_R_SUCCESS) { 10784 result = dns_db_findnode(db, &ns.name, 10785 ISC_TRUE, &node); 10786 if (result != ISC_R_SUCCESS) 10787 goto fail; 10788 result = dns_db_addrdataset(db, node, version, 0, 10789 rdataset, 0, NULL); 10790 dns_db_detachnode(db, &node); 10791 if (result != ISC_R_SUCCESS) 10792 goto fail; 10793 } 10794 } 10795 if (result != ISC_R_NOMORE) 10796 goto fail; 10797 10798 return (ISC_R_SUCCESS); 10799 10800 fail: 10801 return (result); 10802 } 10803 10804 static void 10805 stub_callback(isc_task_t *task, isc_event_t *event) { 10806 const char me[] = "stub_callback"; 10807 dns_requestevent_t *revent = (dns_requestevent_t *)event; 10808 dns_stub_t *stub = NULL; 10809 dns_message_t *msg = NULL; 10810 dns_zone_t *zone = NULL; 10811 char master[ISC_SOCKADDR_FORMATSIZE]; 10812 char source[ISC_SOCKADDR_FORMATSIZE]; 10813 isc_uint32_t nscnt, cnamecnt, refresh, retry, expire; 10814 isc_result_t result; 10815 isc_time_t now; 10816 isc_boolean_t exiting = ISC_FALSE; 10817 isc_interval_t i; 10818 unsigned int j, soacount; 10819 10820 stub = revent->ev_arg; 10821 INSIST(DNS_STUB_VALID(stub)); 10822 10823 UNUSED(task); 10824 10825 zone = stub->zone; 10826 10827 ENTER; 10828 10829 TIME_NOW(&now); 10830 10831 LOCK_ZONE(zone); 10832 10833 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 10834 zone_debuglog(zone, me, 1, "exiting"); 10835 exiting = ISC_TRUE; 10836 goto next_master; 10837 } 10838 10839 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 10840 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 10841 10842 if (revent->result != ISC_R_SUCCESS) { 10843 if (revent->result == ISC_R_TIMEDOUT && 10844 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 10845 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 10846 dns_zone_log(zone, ISC_LOG_DEBUG(1), 10847 "refreshing stub: timeout retrying " 10848 " without EDNS master %s (source %s)", 10849 master, source); 10850 goto same_master; 10851 } 10852 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr, 10853 &zone->sourceaddr, &now); 10854 dns_zone_log(zone, ISC_LOG_INFO, 10855 "could not refresh stub from master %s" 10856 " (source %s): %s", master, source, 10857 dns_result_totext(revent->result)); 10858 goto next_master; 10859 } 10860 10861 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 10862 if (result != ISC_R_SUCCESS) 10863 goto next_master; 10864 10865 result = dns_request_getresponse(revent->request, msg, 0); 10866 if (result != ISC_R_SUCCESS) 10867 goto next_master; 10868 10869 /* 10870 * Unexpected rcode. 10871 */ 10872 if (msg->rcode != dns_rcode_noerror) { 10873 char rcode[128]; 10874 isc_buffer_t rb; 10875 10876 isc_buffer_init(&rb, rcode, sizeof(rcode)); 10877 (void)dns_rcode_totext(msg->rcode, &rb); 10878 10879 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 10880 (msg->rcode == dns_rcode_servfail || 10881 msg->rcode == dns_rcode_notimp || 10882 msg->rcode == dns_rcode_formerr)) { 10883 dns_zone_log(zone, ISC_LOG_DEBUG(1), 10884 "refreshing stub: rcode (%.*s) retrying " 10885 "without EDNS master %s (source %s)", 10886 (int)rb.used, rcode, master, source); 10887 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 10888 goto same_master; 10889 } 10890 10891 dns_zone_log(zone, ISC_LOG_INFO, 10892 "refreshing stub: " 10893 "unexpected rcode (%.*s) from %s (source %s)", 10894 (int)rb.used, rcode, master, source); 10895 goto next_master; 10896 } 10897 10898 /* 10899 * We need complete messages. 10900 */ 10901 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 10902 if (dns_request_usedtcp(revent->request)) { 10903 dns_zone_log(zone, ISC_LOG_INFO, 10904 "refreshing stub: truncated TCP " 10905 "response from master %s (source %s)", 10906 master, source); 10907 goto next_master; 10908 } 10909 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 10910 goto same_master; 10911 } 10912 10913 /* 10914 * If non-auth log and next master. 10915 */ 10916 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 10917 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " 10918 "non-authoritative answer from " 10919 "master %s (source %s)", master, source); 10920 goto next_master; 10921 } 10922 10923 /* 10924 * Sanity checks. 10925 */ 10926 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 10927 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns); 10928 10929 if (cnamecnt != 0) { 10930 dns_zone_log(zone, ISC_LOG_INFO, 10931 "refreshing stub: unexpected CNAME response " 10932 "from master %s (source %s)", master, source); 10933 goto next_master; 10934 } 10935 10936 if (nscnt == 0) { 10937 dns_zone_log(zone, ISC_LOG_INFO, 10938 "refreshing stub: no NS records in response " 10939 "from master %s (source %s)", master, source); 10940 goto next_master; 10941 } 10942 10943 /* 10944 * Save answer. 10945 */ 10946 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version); 10947 if (result != ISC_R_SUCCESS) { 10948 dns_zone_log(zone, ISC_LOG_INFO, 10949 "refreshing stub: unable to save NS records " 10950 "from master %s (source %s)", master, source); 10951 goto next_master; 10952 } 10953 10954 /* 10955 * Tidy up. 10956 */ 10957 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE); 10958 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 10959 if (zone->db == NULL) 10960 zone_attachdb(zone, stub->db); 10961 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, 10962 &refresh, &retry, &expire, NULL, NULL); 10963 if (result == ISC_R_SUCCESS && soacount > 0U) { 10964 zone->refresh = RANGE(refresh, zone->minrefresh, 10965 zone->maxrefresh); 10966 zone->retry = RANGE(retry, zone->minretry, zone->maxretry); 10967 zone->expire = RANGE(expire, zone->refresh + zone->retry, 10968 DNS_MAX_EXPIRE); 10969 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 10970 } 10971 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 10972 dns_db_detach(&stub->db); 10973 10974 dns_message_destroy(&msg); 10975 isc_event_free(&event); 10976 dns_request_destroy(&zone->request); 10977 10978 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 10979 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 10980 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 10981 isc_interval_set(&i, zone->expire, 0); 10982 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); 10983 10984 if (zone->masterfile != NULL) 10985 zone_needdump(zone, 0); 10986 10987 zone_settimer(zone, &now); 10988 goto free_stub; 10989 10990 next_master: 10991 if (stub->version != NULL) 10992 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE); 10993 if (stub->db != NULL) 10994 dns_db_detach(&stub->db); 10995 if (msg != NULL) 10996 dns_message_destroy(&msg); 10997 isc_event_free(&event); 10998 dns_request_destroy(&zone->request); 10999 /* 11000 * Skip to next failed / untried master. 11001 */ 11002 do { 11003 zone->curmaster++; 11004 } while (zone->curmaster < zone->masterscnt && 11005 zone->mastersok[zone->curmaster]); 11006 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 11007 if (exiting || zone->curmaster >= zone->masterscnt) { 11008 isc_boolean_t done = ISC_TRUE; 11009 if (!exiting && 11010 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 11011 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 11012 /* 11013 * Did we get a good answer from all the masters? 11014 */ 11015 for (j = 0; j < zone->masterscnt; j++) 11016 if (zone->mastersok[j] == ISC_FALSE) { 11017 done = ISC_FALSE; 11018 break; 11019 } 11020 } else 11021 done = ISC_TRUE; 11022 if (!done) { 11023 zone->curmaster = 0; 11024 /* 11025 * Find the next failed master. 11026 */ 11027 while (zone->curmaster < zone->masterscnt && 11028 zone->mastersok[zone->curmaster]) 11029 zone->curmaster++; 11030 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 11031 } else { 11032 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 11033 11034 zone_settimer(zone, &now); 11035 goto free_stub; 11036 } 11037 } 11038 queue_soa_query(zone); 11039 goto free_stub; 11040 11041 same_master: 11042 if (msg != NULL) 11043 dns_message_destroy(&msg); 11044 isc_event_free(&event); 11045 dns_request_destroy(&zone->request); 11046 ns_query(zone, NULL, stub); 11047 UNLOCK_ZONE(zone); 11048 goto done; 11049 11050 free_stub: 11051 UNLOCK_ZONE(zone); 11052 stub->magic = 0; 11053 dns_zone_idetach(&stub->zone); 11054 INSIST(stub->db == NULL); 11055 INSIST(stub->version == NULL); 11056 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 11057 11058 done: 11059 INSIST(event == NULL); 11060 return; 11061 } 11062 11063 /* 11064 * An SOA query has finished (successfully or not). 11065 */ 11066 static void 11067 refresh_callback(isc_task_t *task, isc_event_t *event) { 11068 const char me[] = "refresh_callback"; 11069 dns_requestevent_t *revent = (dns_requestevent_t *)event; 11070 dns_zone_t *zone; 11071 dns_message_t *msg = NULL; 11072 isc_uint32_t soacnt, cnamecnt, soacount, nscount; 11073 isc_time_t now; 11074 char master[ISC_SOCKADDR_FORMATSIZE]; 11075 char source[ISC_SOCKADDR_FORMATSIZE]; 11076 dns_rdataset_t *rdataset = NULL; 11077 dns_rdata_t rdata = DNS_RDATA_INIT; 11078 dns_rdata_soa_t soa; 11079 isc_result_t result; 11080 isc_uint32_t serial, oldserial = 0; 11081 unsigned int j; 11082 isc_boolean_t do_queue_xfrin = ISC_FALSE; 11083 11084 zone = revent->ev_arg; 11085 INSIST(DNS_ZONE_VALID(zone)); 11086 11087 UNUSED(task); 11088 11089 ENTER; 11090 11091 TIME_NOW(&now); 11092 11093 LOCK_ZONE(zone); 11094 11095 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11096 isc_event_free(&event); 11097 dns_request_destroy(&zone->request); 11098 goto detach; 11099 } 11100 11101 /* 11102 * if timeout log and next master; 11103 */ 11104 11105 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 11106 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 11107 11108 if (revent->result != ISC_R_SUCCESS) { 11109 if (revent->result == ISC_R_TIMEDOUT && 11110 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 11111 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 11112 dns_zone_log(zone, ISC_LOG_DEBUG(1), 11113 "refresh: timeout retrying without EDNS " 11114 "master %s (source %s)", master, source); 11115 goto same_master; 11116 } 11117 if (revent->result == ISC_R_TIMEDOUT && 11118 !dns_request_usedtcp(revent->request)) { 11119 dns_zone_log(zone, ISC_LOG_INFO, 11120 "refresh: retry limit for " 11121 "master %s exceeded (source %s)", 11122 master, source); 11123 /* Try with slave with TCP. */ 11124 if ((zone->type == dns_zone_slave || 11125 zone->type == dns_zone_redirect) && 11126 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) { 11127 if (!dns_zonemgr_unreachable(zone->zmgr, 11128 &zone->masteraddr, 11129 &zone->sourceaddr, 11130 &now)) 11131 { 11132 DNS_ZONE_SETFLAG(zone, 11133 DNS_ZONEFLG_SOABEFOREAXFR); 11134 goto tcp_transfer; 11135 } 11136 dns_zone_log(zone, ISC_LOG_DEBUG(1), 11137 "refresh: skipped tcp fallback " 11138 "as master %s (source %s) is " 11139 "unreachable (cached)", 11140 master, source); 11141 } 11142 } else 11143 dns_zone_log(zone, ISC_LOG_INFO, 11144 "refresh: failure trying master " 11145 "%s (source %s): %s", master, source, 11146 dns_result_totext(revent->result)); 11147 goto next_master; 11148 } 11149 11150 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 11151 if (result != ISC_R_SUCCESS) 11152 goto next_master; 11153 result = dns_request_getresponse(revent->request, msg, 0); 11154 if (result != ISC_R_SUCCESS) { 11155 dns_zone_log(zone, ISC_LOG_INFO, 11156 "refresh: failure trying master " 11157 "%s (source %s): %s", master, source, 11158 dns_result_totext(result)); 11159 goto next_master; 11160 } 11161 11162 /* 11163 * Unexpected rcode. 11164 */ 11165 if (msg->rcode != dns_rcode_noerror) { 11166 char rcode[128]; 11167 isc_buffer_t rb; 11168 11169 isc_buffer_init(&rb, rcode, sizeof(rcode)); 11170 (void)dns_rcode_totext(msg->rcode, &rb); 11171 11172 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 11173 (msg->rcode == dns_rcode_servfail || 11174 msg->rcode == dns_rcode_notimp || 11175 msg->rcode == dns_rcode_formerr)) { 11176 dns_zone_log(zone, ISC_LOG_DEBUG(1), 11177 "refresh: rcode (%.*s) retrying without " 11178 "EDNS master %s (source %s)", 11179 (int)rb.used, rcode, master, source); 11180 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 11181 goto same_master; 11182 } 11183 dns_zone_log(zone, ISC_LOG_INFO, 11184 "refresh: unexpected rcode (%.*s) from " 11185 "master %s (source %s)", (int)rb.used, rcode, 11186 master, source); 11187 /* 11188 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't. 11189 */ 11190 if (msg->rcode == dns_rcode_refused && 11191 (zone->type == dns_zone_slave || 11192 zone->type == dns_zone_redirect)) 11193 goto tcp_transfer; 11194 goto next_master; 11195 } 11196 11197 /* 11198 * If truncated punt to zone transfer which will query again. 11199 */ 11200 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 11201 if (zone->type == dns_zone_slave || 11202 zone->type == dns_zone_redirect) { 11203 dns_zone_log(zone, ISC_LOG_INFO, 11204 "refresh: truncated UDP answer, " 11205 "initiating TCP zone xfer " 11206 "for master %s (source %s)", 11207 master, source); 11208 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 11209 goto tcp_transfer; 11210 } else { 11211 INSIST(zone->type == dns_zone_stub); 11212 if (dns_request_usedtcp(revent->request)) { 11213 dns_zone_log(zone, ISC_LOG_INFO, 11214 "refresh: truncated TCP response " 11215 "from master %s (source %s)", 11216 master, source); 11217 goto next_master; 11218 } 11219 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 11220 goto same_master; 11221 } 11222 } 11223 11224 /* 11225 * if non-auth log and next master; 11226 */ 11227 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 11228 dns_zone_log(zone, ISC_LOG_INFO, 11229 "refresh: non-authoritative answer from " 11230 "master %s (source %s)", master, source); 11231 goto next_master; 11232 } 11233 11234 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 11235 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa); 11236 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns); 11237 soacount = message_count(msg, DNS_SECTION_AUTHORITY, 11238 dns_rdatatype_soa); 11239 11240 /* 11241 * There should not be a CNAME record at top of zone. 11242 */ 11243 if (cnamecnt != 0) { 11244 dns_zone_log(zone, ISC_LOG_INFO, 11245 "refresh: CNAME at top of zone " 11246 "in master %s (source %s)", master, source); 11247 goto next_master; 11248 } 11249 11250 /* 11251 * if referral log and next master; 11252 */ 11253 if (soacnt == 0 && soacount == 0 && nscount != 0) { 11254 dns_zone_log(zone, ISC_LOG_INFO, 11255 "refresh: referral response " 11256 "from master %s (source %s)", master, source); 11257 goto next_master; 11258 } 11259 11260 /* 11261 * if nodata log and next master; 11262 */ 11263 if (soacnt == 0 && (nscount == 0 || soacount != 0)) { 11264 dns_zone_log(zone, ISC_LOG_INFO, 11265 "refresh: NODATA response " 11266 "from master %s (source %s)", master, source); 11267 goto next_master; 11268 } 11269 11270 /* 11271 * Only one soa at top of zone. 11272 */ 11273 if (soacnt != 1) { 11274 dns_zone_log(zone, ISC_LOG_INFO, 11275 "refresh: answer SOA count (%d) != 1 " 11276 "from master %s (source %s)", 11277 soacnt, master, source); 11278 goto next_master; 11279 } 11280 11281 /* 11282 * Extract serial 11283 */ 11284 rdataset = NULL; 11285 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin, 11286 dns_rdatatype_soa, dns_rdatatype_none, 11287 NULL, &rdataset); 11288 if (result != ISC_R_SUCCESS) { 11289 dns_zone_log(zone, ISC_LOG_INFO, 11290 "refresh: unable to get SOA record " 11291 "from master %s (source %s)", master, source); 11292 goto next_master; 11293 } 11294 11295 result = dns_rdataset_first(rdataset); 11296 if (result != ISC_R_SUCCESS) { 11297 dns_zone_log(zone, ISC_LOG_INFO, 11298 "refresh: dns_rdataset_first() failed"); 11299 goto next_master; 11300 } 11301 11302 dns_rdataset_current(rdataset, &rdata); 11303 result = dns_rdata_tostruct(&rdata, &soa, NULL); 11304 RUNTIME_CHECK(result == ISC_R_SUCCESS); 11305 11306 serial = soa.serial; 11307 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 11308 unsigned int dbsoacount; 11309 result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount, 11310 &oldserial, NULL, NULL, NULL, NULL, 11311 NULL); 11312 RUNTIME_CHECK(result == ISC_R_SUCCESS); 11313 RUNTIME_CHECK(dbsoacount > 0U); 11314 zone_debuglog(zone, me, 1, "serial: new %u, old %u", 11315 serial, oldserial); 11316 } else 11317 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded", 11318 serial); 11319 11320 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) || 11321 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) || 11322 isc_serial_gt(serial, oldserial)) { 11323 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, 11324 &zone->sourceaddr, &now)) 11325 { 11326 dns_zone_log(zone, ISC_LOG_INFO, 11327 "refresh: skipping %s as master %s " 11328 "(source %s) is unreachable (cached)", 11329 (zone->type == dns_zone_slave || 11330 zone->type == dns_zone_redirect) ? 11331 "zone transfer" : "NS query", 11332 master, source); 11333 goto next_master; 11334 } 11335 tcp_transfer: 11336 isc_event_free(&event); 11337 dns_request_destroy(&zone->request); 11338 if (zone->type == dns_zone_slave || 11339 zone->type == dns_zone_redirect) { 11340 do_queue_xfrin = ISC_TRUE; 11341 } else { 11342 INSIST(zone->type == dns_zone_stub); 11343 ns_query(zone, rdataset, NULL); 11344 } 11345 if (msg != NULL) 11346 dns_message_destroy(&msg); 11347 } else if (isc_serial_eq(soa.serial, oldserial)) { 11348 if (zone->masterfile != NULL) { 11349 result = ISC_R_FAILURE; 11350 if (zone->journal != NULL) 11351 result = isc_file_settime(zone->journal, &now); 11352 if (result == ISC_R_SUCCESS && 11353 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 11354 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 11355 result = isc_file_settime(zone->masterfile, 11356 &now); 11357 } else if (result != ISC_R_SUCCESS) 11358 result = isc_file_settime(zone->masterfile, 11359 &now); 11360 /* Someone removed the file from underneath us! */ 11361 if (result == ISC_R_FILENOTFOUND) { 11362 zone_needdump(zone, DNS_DUMP_DELAY); 11363 } else if (result != ISC_R_SUCCESS) 11364 dns_zone_log(zone, ISC_LOG_ERROR, 11365 "refresh: could not set file " 11366 "modification time of '%s': %s", 11367 zone->masterfile, 11368 dns_result_totext(result)); 11369 } 11370 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 11371 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); 11372 zone->mastersok[zone->curmaster] = ISC_TRUE; 11373 goto next_master; 11374 } else { 11375 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER)) 11376 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) " 11377 "received from master %s < ours (%u)", 11378 soa.serial, master, oldserial); 11379 else 11380 zone_debuglog(zone, me, 1, "ahead"); 11381 zone->mastersok[zone->curmaster] = ISC_TRUE; 11382 goto next_master; 11383 } 11384 if (msg != NULL) 11385 dns_message_destroy(&msg); 11386 goto detach; 11387 11388 next_master: 11389 if (msg != NULL) 11390 dns_message_destroy(&msg); 11391 isc_event_free(&event); 11392 dns_request_destroy(&zone->request); 11393 /* 11394 * Skip to next failed / untried master. 11395 */ 11396 do { 11397 zone->curmaster++; 11398 } while (zone->curmaster < zone->masterscnt && 11399 zone->mastersok[zone->curmaster]); 11400 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 11401 if (zone->curmaster >= zone->masterscnt) { 11402 isc_boolean_t done = ISC_TRUE; 11403 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 11404 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 11405 /* 11406 * Did we get a good answer from all the masters? 11407 */ 11408 for (j = 0; j < zone->masterscnt; j++) 11409 if (zone->mastersok[j] == ISC_FALSE) { 11410 done = ISC_FALSE; 11411 break; 11412 } 11413 } else 11414 done = ISC_TRUE; 11415 if (!done) { 11416 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 11417 zone->curmaster = 0; 11418 /* 11419 * Find the next failed master. 11420 */ 11421 while (zone->curmaster < zone->masterscnt && 11422 zone->mastersok[zone->curmaster]) 11423 zone->curmaster++; 11424 goto requeue; 11425 } 11426 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 11427 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 11428 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 11429 zone->refreshtime = now; 11430 } 11431 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 11432 zone_settimer(zone, &now); 11433 goto detach; 11434 } 11435 11436 requeue: 11437 queue_soa_query(zone); 11438 goto detach; 11439 11440 same_master: 11441 if (msg != NULL) 11442 dns_message_destroy(&msg); 11443 isc_event_free(&event); 11444 dns_request_destroy(&zone->request); 11445 queue_soa_query(zone); 11446 11447 detach: 11448 UNLOCK_ZONE(zone); 11449 if (do_queue_xfrin) 11450 queue_xfrin(zone); 11451 dns_zone_idetach(&zone); 11452 return; 11453 } 11454 11455 static void 11456 queue_soa_query(dns_zone_t *zone) { 11457 const char me[] = "queue_soa_query"; 11458 isc_event_t *e; 11459 dns_zone_t *dummy = NULL; 11460 isc_result_t result; 11461 11462 ENTER; 11463 /* 11464 * Locked by caller 11465 */ 11466 REQUIRE(LOCKED_ZONE(zone)); 11467 11468 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 11469 cancel_refresh(zone); 11470 return; 11471 } 11472 11473 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE, 11474 soa_query, zone, sizeof(isc_event_t)); 11475 if (e == NULL) { 11476 cancel_refresh(zone); 11477 return; 11478 } 11479 11480 /* 11481 * Attach so that we won't clean up 11482 * until the event is delivered. 11483 */ 11484 zone_iattach(zone, &dummy); 11485 11486 e->ev_arg = zone; 11487 e->ev_sender = NULL; 11488 result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e); 11489 if (result != ISC_R_SUCCESS) { 11490 zone_idetach(&dummy); 11491 isc_event_free(&e); 11492 cancel_refresh(zone); 11493 } 11494 } 11495 11496 static inline isc_result_t 11497 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, 11498 dns_message_t **messagep) 11499 { 11500 dns_message_t *message = NULL; 11501 dns_name_t *qname = NULL; 11502 dns_rdataset_t *qrdataset = NULL; 11503 isc_result_t result; 11504 11505 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, 11506 &message); 11507 if (result != ISC_R_SUCCESS) 11508 goto cleanup; 11509 11510 message->opcode = dns_opcode_query; 11511 message->rdclass = zone->rdclass; 11512 11513 result = dns_message_gettempname(message, &qname); 11514 if (result != ISC_R_SUCCESS) 11515 goto cleanup; 11516 11517 result = dns_message_gettemprdataset(message, &qrdataset); 11518 if (result != ISC_R_SUCCESS) 11519 goto cleanup; 11520 11521 /* 11522 * Make question. 11523 */ 11524 dns_name_init(qname, NULL); 11525 dns_name_clone(&zone->origin, qname); 11526 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype); 11527 ISC_LIST_APPEND(qname->list, qrdataset, link); 11528 dns_message_addname(message, qname, DNS_SECTION_QUESTION); 11529 11530 *messagep = message; 11531 return (ISC_R_SUCCESS); 11532 11533 cleanup: 11534 if (qname != NULL) 11535 dns_message_puttempname(message, &qname); 11536 if (qrdataset != NULL) 11537 dns_message_puttemprdataset(message, &qrdataset); 11538 if (message != NULL) 11539 dns_message_destroy(&message); 11540 return (result); 11541 } 11542 11543 static isc_result_t 11544 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) { 11545 isc_result_t result; 11546 dns_rdataset_t *rdataset = NULL; 11547 dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS]; 11548 int count = 0; 11549 11550 /* Set EDNS options if applicable */ 11551 if (reqnsid) { 11552 INSIST(count < DNS_EDNSOPTIONS); 11553 ednsopts[count].code = DNS_OPT_NSID; 11554 ednsopts[count].length = 0; 11555 ednsopts[count].value = NULL; 11556 count++; 11557 } 11558 result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0, 11559 ednsopts, count); 11560 if (result != ISC_R_SUCCESS) 11561 return (result); 11562 11563 return (dns_message_setopt(message, rdataset)); 11564 } 11565 11566 static void 11567 soa_query(isc_task_t *task, isc_event_t *event) { 11568 const char me[] = "soa_query"; 11569 isc_result_t result = ISC_R_FAILURE; 11570 dns_message_t *message = NULL; 11571 dns_zone_t *zone = event->ev_arg; 11572 dns_zone_t *dummy = NULL; 11573 isc_netaddr_t masterip; 11574 dns_tsigkey_t *key = NULL; 11575 isc_uint32_t options; 11576 isc_boolean_t cancel = ISC_TRUE; 11577 int timeout; 11578 isc_boolean_t have_xfrsource, have_xfrdscp, reqnsid; 11579 isc_uint16_t udpsize = SEND_BUFFER_SIZE; 11580 isc_dscp_t dscp = -1; 11581 11582 REQUIRE(DNS_ZONE_VALID(zone)); 11583 11584 UNUSED(task); 11585 11586 ENTER; 11587 11588 LOCK_ZONE(zone); 11589 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) || 11590 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || 11591 zone->view->requestmgr == NULL) { 11592 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 11593 cancel = ISC_FALSE; 11594 goto cleanup; 11595 } 11596 11597 again: 11598 result = create_query(zone, dns_rdatatype_soa, &message); 11599 if (result != ISC_R_SUCCESS) 11600 goto cleanup; 11601 11602 INSIST(zone->masterscnt > 0); 11603 INSIST(zone->curmaster < zone->masterscnt); 11604 11605 zone->masteraddr = zone->masters[zone->curmaster]; 11606 11607 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 11608 /* 11609 * First, look for a tsig key in the master statement, then 11610 * try for a server key. 11611 */ 11612 if ((zone->masterkeynames != NULL) && 11613 (zone->masterkeynames[zone->curmaster] != NULL)) { 11614 dns_view_t *view = dns_zone_getview(zone); 11615 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 11616 result = dns_view_gettsig(view, keyname, &key); 11617 if (result != ISC_R_SUCCESS) { 11618 char namebuf[DNS_NAME_FORMATSIZE]; 11619 dns_name_format(keyname, namebuf, sizeof(namebuf)); 11620 dns_zone_log(zone, ISC_LOG_ERROR, 11621 "unable to find key: %s", namebuf); 11622 goto skip_master; 11623 } 11624 } 11625 if (key == NULL) { 11626 result = dns_view_getpeertsig(zone->view, &masterip, &key); 11627 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 11628 char addrbuf[ISC_NETADDR_FORMATSIZE]; 11629 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf)); 11630 dns_zone_log(zone, ISC_LOG_ERROR, 11631 "unable to find TSIG key for %s", addrbuf); 11632 goto skip_master; 11633 } 11634 } 11635 11636 have_xfrsource = have_xfrdscp = ISC_FALSE; 11637 reqnsid = zone->view->requestnsid; 11638 if (zone->view->peers != NULL) { 11639 dns_peer_t *peer = NULL; 11640 isc_boolean_t edns; 11641 result = dns_peerlist_peerbyaddr(zone->view->peers, 11642 &masterip, &peer); 11643 if (result == ISC_R_SUCCESS) { 11644 result = dns_peer_getsupportedns(peer, &edns); 11645 if (result == ISC_R_SUCCESS && !edns) 11646 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 11647 result = dns_peer_gettransfersource(peer, 11648 &zone->sourceaddr); 11649 if (result == ISC_R_SUCCESS) 11650 have_xfrsource = ISC_TRUE; 11651 (void)dns_peer_gettransferdscp(peer, &dscp); 11652 if (dscp != -1) 11653 have_xfrdscp = ISC_TRUE; 11654 if (zone->view->resolver != NULL) 11655 udpsize = 11656 dns_resolver_getudpsize(zone->view->resolver); 11657 (void)dns_peer_getudpsize(peer, &udpsize); 11658 (void)dns_peer_getrequestnsid(peer, &reqnsid); 11659 } 11660 } 11661 11662 switch (isc_sockaddr_pf(&zone->masteraddr)) { 11663 case PF_INET: 11664 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 11665 if (isc_sockaddr_equal(&zone->altxfrsource4, 11666 &zone->xfrsource4)) 11667 goto skip_master; 11668 zone->sourceaddr = zone->altxfrsource4; 11669 if (!have_xfrdscp) 11670 dscp = zone->altxfrsource4dscp; 11671 } else if (!have_xfrsource) { 11672 zone->sourceaddr = zone->xfrsource4; 11673 if (!have_xfrdscp) 11674 dscp = zone->xfrsource4dscp; 11675 } 11676 break; 11677 case PF_INET6: 11678 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 11679 if (isc_sockaddr_equal(&zone->altxfrsource6, 11680 &zone->xfrsource6)) 11681 goto skip_master; 11682 zone->sourceaddr = zone->altxfrsource6; 11683 if (!have_xfrdscp) 11684 dscp = zone->altxfrsource6dscp; 11685 } else if (!have_xfrsource) { 11686 zone->sourceaddr = zone->xfrsource6; 11687 if (!have_xfrdscp) 11688 dscp = zone->xfrsource6dscp; 11689 } 11690 break; 11691 default: 11692 result = ISC_R_NOTIMPLEMENTED; 11693 goto cleanup; 11694 } 11695 11696 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? 11697 DNS_REQUESTOPT_TCP : 0; 11698 11699 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 11700 result = add_opt(message, udpsize, reqnsid); 11701 if (result != ISC_R_SUCCESS) 11702 zone_debuglog(zone, me, 1, 11703 "unable to add opt record: %s", 11704 dns_result_totext(result)); 11705 } 11706 11707 zone_iattach(zone, &dummy); 11708 timeout = 15; 11709 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 11710 timeout = 30; 11711 result = dns_request_createvia4(zone->view->requestmgr, message, 11712 &zone->sourceaddr, &zone->masteraddr, 11713 dscp, options, key, timeout * 3, 11714 timeout, 0, zone->task, 11715 refresh_callback, zone, &zone->request); 11716 if (result != ISC_R_SUCCESS) { 11717 zone_idetach(&dummy); 11718 zone_debuglog(zone, me, 1, 11719 "dns_request_createvia4() failed: %s", 11720 dns_result_totext(result)); 11721 goto skip_master; 11722 } else { 11723 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET) 11724 inc_stats(zone, dns_zonestatscounter_soaoutv4); 11725 else 11726 inc_stats(zone, dns_zonestatscounter_soaoutv6); 11727 } 11728 cancel = ISC_FALSE; 11729 11730 cleanup: 11731 if (key != NULL) 11732 dns_tsigkey_detach(&key); 11733 if (result != ISC_R_SUCCESS) 11734 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 11735 if (message != NULL) 11736 dns_message_destroy(&message); 11737 if (cancel) 11738 cancel_refresh(zone); 11739 isc_event_free(&event); 11740 UNLOCK_ZONE(zone); 11741 dns_zone_idetach(&zone); 11742 return; 11743 11744 skip_master: 11745 if (key != NULL) 11746 dns_tsigkey_detach(&key); 11747 dns_message_destroy(&message); 11748 /* 11749 * Skip to next failed / untried master. 11750 */ 11751 do { 11752 zone->curmaster++; 11753 } while (zone->curmaster < zone->masterscnt && 11754 zone->mastersok[zone->curmaster]); 11755 if (zone->curmaster < zone->masterscnt) 11756 goto again; 11757 zone->curmaster = 0; 11758 goto cleanup; 11759 } 11760 11761 static void 11762 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { 11763 const char me[] = "ns_query"; 11764 isc_result_t result; 11765 dns_message_t *message = NULL; 11766 isc_netaddr_t masterip; 11767 dns_tsigkey_t *key = NULL; 11768 dns_dbnode_t *node = NULL; 11769 int timeout; 11770 isc_boolean_t have_xfrsource = ISC_FALSE, have_xfrdscp = ISC_FALSE; 11771 isc_boolean_t reqnsid; 11772 isc_uint16_t udpsize = SEND_BUFFER_SIZE; 11773 isc_dscp_t dscp = -1; 11774 11775 REQUIRE(DNS_ZONE_VALID(zone)); 11776 REQUIRE(LOCKED_ZONE(zone)); 11777 REQUIRE((soardataset != NULL && stub == NULL) || 11778 (soardataset == NULL && stub != NULL)); 11779 REQUIRE(stub == NULL || DNS_STUB_VALID(stub)); 11780 11781 ENTER; 11782 11783 if (stub == NULL) { 11784 stub = isc_mem_get(zone->mctx, sizeof(*stub)); 11785 if (stub == NULL) 11786 goto cleanup; 11787 stub->magic = STUB_MAGIC; 11788 stub->mctx = zone->mctx; 11789 stub->zone = NULL; 11790 stub->db = NULL; 11791 stub->version = NULL; 11792 11793 /* 11794 * Attach so that the zone won't disappear from under us. 11795 */ 11796 zone_iattach(zone, &stub->zone); 11797 11798 /* 11799 * If a db exists we will update it, otherwise we create a 11800 * new one and attach it to the zone once we have the NS 11801 * RRset and glue. 11802 */ 11803 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 11804 if (zone->db != NULL) { 11805 dns_db_attach(zone->db, &stub->db); 11806 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11807 } else { 11808 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11809 11810 INSIST(zone->db_argc >= 1); 11811 result = dns_db_create(zone->mctx, zone->db_argv[0], 11812 &zone->origin, dns_dbtype_stub, 11813 zone->rdclass, 11814 zone->db_argc - 1, 11815 zone->db_argv + 1, 11816 &stub->db); 11817 if (result != ISC_R_SUCCESS) { 11818 dns_zone_log(zone, ISC_LOG_ERROR, 11819 "refreshing stub: " 11820 "could not create " 11821 "database: %s", 11822 dns_result_totext(result)); 11823 goto cleanup; 11824 } 11825 dns_db_settask(stub->db, zone->task); 11826 } 11827 11828 result = dns_db_newversion(stub->db, &stub->version); 11829 if (result != ISC_R_SUCCESS) { 11830 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " 11831 "dns_db_newversion() failed: %s", 11832 dns_result_totext(result)); 11833 goto cleanup; 11834 } 11835 11836 /* 11837 * Update SOA record. 11838 */ 11839 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE, 11840 &node); 11841 if (result != ISC_R_SUCCESS) { 11842 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " 11843 "dns_db_findnode() failed: %s", 11844 dns_result_totext(result)); 11845 goto cleanup; 11846 } 11847 11848 result = dns_db_addrdataset(stub->db, node, stub->version, 0, 11849 soardataset, 0, NULL); 11850 dns_db_detachnode(stub->db, &node); 11851 if (result != ISC_R_SUCCESS) { 11852 dns_zone_log(zone, ISC_LOG_INFO, 11853 "refreshing stub: " 11854 "dns_db_addrdataset() failed: %s", 11855 dns_result_totext(result)); 11856 goto cleanup; 11857 } 11858 } 11859 11860 /* 11861 * XXX Optimisation: Create message when zone is setup and reuse. 11862 */ 11863 result = create_query(zone, dns_rdatatype_ns, &message); 11864 INSIST(result == ISC_R_SUCCESS); 11865 11866 INSIST(zone->masterscnt > 0); 11867 INSIST(zone->curmaster < zone->masterscnt); 11868 zone->masteraddr = zone->masters[zone->curmaster]; 11869 11870 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 11871 /* 11872 * First, look for a tsig key in the master statement, then 11873 * try for a server key. 11874 */ 11875 if ((zone->masterkeynames != NULL) && 11876 (zone->masterkeynames[zone->curmaster] != NULL)) { 11877 dns_view_t *view = dns_zone_getview(zone); 11878 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 11879 result = dns_view_gettsig(view, keyname, &key); 11880 if (result != ISC_R_SUCCESS) { 11881 char namebuf[DNS_NAME_FORMATSIZE]; 11882 dns_name_format(keyname, namebuf, sizeof(namebuf)); 11883 dns_zone_log(zone, ISC_LOG_ERROR, 11884 "unable to find key: %s", namebuf); 11885 } 11886 } 11887 if (key == NULL) 11888 (void)dns_view_getpeertsig(zone->view, &masterip, &key); 11889 11890 reqnsid = zone->view->requestnsid; 11891 if (zone->view->peers != NULL) { 11892 dns_peer_t *peer = NULL; 11893 isc_boolean_t edns; 11894 result = dns_peerlist_peerbyaddr(zone->view->peers, 11895 &masterip, &peer); 11896 if (result == ISC_R_SUCCESS) { 11897 result = dns_peer_getsupportedns(peer, &edns); 11898 if (result == ISC_R_SUCCESS && !edns) 11899 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 11900 result = dns_peer_gettransfersource(peer, 11901 &zone->sourceaddr); 11902 if (result == ISC_R_SUCCESS) 11903 have_xfrsource = ISC_TRUE; 11904 result = dns_peer_gettransferdscp(peer, &dscp); 11905 if (result == ISC_R_SUCCESS && dscp != -1) 11906 have_xfrdscp = ISC_TRUE; 11907 if (zone->view->resolver != NULL) 11908 udpsize = 11909 dns_resolver_getudpsize(zone->view->resolver); 11910 (void)dns_peer_getudpsize(peer, &udpsize); 11911 (void)dns_peer_getrequestnsid(peer, &reqnsid); 11912 } 11913 11914 } 11915 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 11916 result = add_opt(message, udpsize, reqnsid); 11917 if (result != ISC_R_SUCCESS) 11918 zone_debuglog(zone, me, 1, 11919 "unable to add opt record: %s", 11920 dns_result_totext(result)); 11921 } 11922 11923 /* 11924 * Always use TCP so that we shouldn't truncate in additional section. 11925 */ 11926 switch (isc_sockaddr_pf(&zone->masteraddr)) { 11927 case PF_INET: 11928 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 11929 zone->sourceaddr = zone->altxfrsource4; 11930 if (!have_xfrdscp) 11931 dscp = zone->altxfrsource4dscp; 11932 } else if (!have_xfrsource) { 11933 zone->sourceaddr = zone->xfrsource4; 11934 if (!have_xfrdscp) 11935 dscp = zone->xfrsource4dscp; 11936 } 11937 break; 11938 case PF_INET6: 11939 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 11940 zone->sourceaddr = zone->altxfrsource6; 11941 if (!have_xfrdscp) 11942 dscp = zone->altxfrsource6dscp; 11943 } else if (!have_xfrsource) { 11944 zone->sourceaddr = zone->xfrsource6; 11945 if (!have_xfrdscp) 11946 dscp = zone->xfrsource6dscp; 11947 } 11948 break; 11949 default: 11950 result = ISC_R_NOTIMPLEMENTED; 11951 POST(result); 11952 goto cleanup; 11953 } 11954 timeout = 15; 11955 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 11956 timeout = 30; 11957 result = dns_request_createvia4(zone->view->requestmgr, message, 11958 &zone->sourceaddr, &zone->masteraddr, 11959 dscp, DNS_REQUESTOPT_TCP, key, 11960 timeout * 3, timeout, 0, zone->task, 11961 stub_callback, stub, &zone->request); 11962 if (result != ISC_R_SUCCESS) { 11963 zone_debuglog(zone, me, 1, 11964 "dns_request_createvia() failed: %s", 11965 dns_result_totext(result)); 11966 goto cleanup; 11967 } 11968 dns_message_destroy(&message); 11969 goto unlock; 11970 11971 cleanup: 11972 cancel_refresh(zone); 11973 if (stub != NULL) { 11974 stub->magic = 0; 11975 if (stub->version != NULL) 11976 dns_db_closeversion(stub->db, &stub->version, 11977 ISC_FALSE); 11978 if (stub->db != NULL) 11979 dns_db_detach(&stub->db); 11980 if (stub->zone != NULL) 11981 zone_idetach(&stub->zone); 11982 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 11983 } 11984 if (message != NULL) 11985 dns_message_destroy(&message); 11986 unlock: 11987 if (key != NULL) 11988 dns_tsigkey_detach(&key); 11989 return; 11990 } 11991 11992 /* 11993 * Handle the control event. Note that although this event causes the zone 11994 * to shut down, it is not a shutdown event in the sense of the task library. 11995 */ 11996 static void 11997 zone_shutdown(isc_task_t *task, isc_event_t *event) { 11998 dns_zone_t *zone = (dns_zone_t *) event->ev_arg; 11999 isc_boolean_t free_needed, linked = ISC_FALSE; 12000 dns_zone_t *raw = NULL, *secure = NULL; 12001 12002 UNUSED(task); 12003 REQUIRE(DNS_ZONE_VALID(zone)); 12004 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL); 12005 INSIST(isc_refcount_current(&zone->erefs) == 0); 12006 12007 zone_debuglog(zone, "zone_shutdown", 3, "shutting down"); 12008 12009 /* 12010 * Stop things being restarted after we cancel them below. 12011 */ 12012 LOCK_ZONE(zone); 12013 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING); 12014 UNLOCK_ZONE(zone); 12015 12016 /* 12017 * If we were waiting for xfrin quota, step out of 12018 * the queue. 12019 * If there's no zone manager, we can't be waiting for the 12020 * xfrin quota 12021 */ 12022 if (zone->zmgr != NULL) { 12023 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 12024 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) { 12025 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone, 12026 statelink); 12027 linked = ISC_TRUE; 12028 zone->statelist = NULL; 12029 } 12030 if (zone->statelist == &zone->zmgr->xfrin_in_progress) { 12031 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, 12032 statelink); 12033 zone->statelist = NULL; 12034 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE); 12035 } 12036 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 12037 } 12038 12039 /* 12040 * In task context, no locking required. See zone_xfrdone(). 12041 */ 12042 if (zone->xfr != NULL) 12043 dns_xfrin_shutdown(zone->xfr); 12044 12045 /* Safe to release the zone now */ 12046 if (zone->zmgr != NULL) 12047 dns_zonemgr_releasezone(zone->zmgr, zone); 12048 12049 LOCK_ZONE(zone); 12050 INSIST(zone != zone->raw); 12051 if (linked) { 12052 INSIST(zone->irefs > 0); 12053 zone->irefs--; 12054 } 12055 if (zone->request != NULL) { 12056 dns_request_cancel(zone->request); 12057 } 12058 12059 if (zone->readio != NULL) 12060 zonemgr_cancelio(zone->readio); 12061 12062 if (zone->lctx != NULL) 12063 dns_loadctx_cancel(zone->lctx); 12064 12065 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 12066 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 12067 if (zone->writeio != NULL) 12068 zonemgr_cancelio(zone->writeio); 12069 12070 if (zone->dctx != NULL) 12071 dns_dumpctx_cancel(zone->dctx); 12072 } 12073 12074 notify_cancel(zone); 12075 12076 forward_cancel(zone); 12077 12078 if (zone->timer != NULL) { 12079 isc_timer_detach(&zone->timer); 12080 INSIST(zone->irefs > 0); 12081 zone->irefs--; 12082 } 12083 12084 if (zone->view != NULL) 12085 dns_view_weakdetach(&zone->view); 12086 12087 /* 12088 * We have now canceled everything set the flag to allow exit_check() 12089 * to succeed. We must not unlock between setting this flag and 12090 * calling exit_check(). 12091 */ 12092 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN); 12093 free_needed = exit_check(zone); 12094 if (inline_secure(zone)) { 12095 raw = zone->raw; 12096 zone->raw = NULL; 12097 } 12098 if (inline_raw(zone)) { 12099 secure = zone->secure; 12100 zone->secure = NULL; 12101 } 12102 UNLOCK_ZONE(zone); 12103 if (raw != NULL) 12104 dns_zone_detach(&raw); 12105 if (secure != NULL) 12106 dns_zone_idetach(&secure); 12107 if (free_needed) 12108 zone_free(zone); 12109 } 12110 12111 static void 12112 zone_timer(isc_task_t *task, isc_event_t *event) { 12113 const char me[] = "zone_timer"; 12114 dns_zone_t *zone = (dns_zone_t *)event->ev_arg; 12115 12116 UNUSED(task); 12117 REQUIRE(DNS_ZONE_VALID(zone)); 12118 12119 ENTER; 12120 12121 zone_maintenance(zone); 12122 12123 isc_event_free(&event); 12124 } 12125 12126 static void 12127 zone_settimer(dns_zone_t *zone, isc_time_t *now) { 12128 const char me[] = "zone_settimer"; 12129 isc_time_t next; 12130 isc_result_t result; 12131 12132 REQUIRE(DNS_ZONE_VALID(zone)); 12133 ENTER; 12134 12135 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 12136 return; 12137 12138 isc_time_settoepoch(&next); 12139 12140 switch (zone->type) { 12141 case dns_zone_redirect: 12142 if (zone->masters != NULL) 12143 goto treat_as_slave; 12144 /* FALLTHROUGH */ 12145 12146 case dns_zone_master: 12147 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) || 12148 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) 12149 next = zone->notifytime; 12150 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 12151 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 12152 INSIST(!isc_time_isepoch(&zone->dumptime)); 12153 if (isc_time_isepoch(&next) || 12154 isc_time_compare(&zone->dumptime, &next) < 0) 12155 next = zone->dumptime; 12156 } 12157 if (zone->type == dns_zone_redirect) 12158 break; 12159 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) && 12160 !isc_time_isepoch(&zone->refreshkeytime)) { 12161 if (isc_time_isepoch(&next) || 12162 isc_time_compare(&zone->refreshkeytime, &next) < 0) 12163 next = zone->refreshkeytime; 12164 } 12165 if (!isc_time_isepoch(&zone->resigntime)) { 12166 if (isc_time_isepoch(&next) || 12167 isc_time_compare(&zone->resigntime, &next) < 0) 12168 next = zone->resigntime; 12169 } 12170 if (!isc_time_isepoch(&zone->keywarntime)) { 12171 if (isc_time_isepoch(&next) || 12172 isc_time_compare(&zone->keywarntime, &next) < 0) 12173 next = zone->keywarntime; 12174 } 12175 if (!isc_time_isepoch(&zone->signingtime)) { 12176 if (isc_time_isepoch(&next) || 12177 isc_time_compare(&zone->signingtime, &next) < 0) 12178 next = zone->signingtime; 12179 } 12180 if (!isc_time_isepoch(&zone->nsec3chaintime)) { 12181 if (isc_time_isepoch(&next) || 12182 isc_time_compare(&zone->nsec3chaintime, &next) < 0) 12183 next = zone->nsec3chaintime; 12184 } 12185 break; 12186 12187 case dns_zone_slave: 12188 treat_as_slave: 12189 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) 12190 next = zone->notifytime; 12191 /* FALLTHROUGH */ 12192 12193 case dns_zone_stub: 12194 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) && 12195 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) && 12196 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) && 12197 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) && 12198 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) && 12199 !isc_time_isepoch(&zone->refreshtime) && 12200 (isc_time_isepoch(&next) || 12201 isc_time_compare(&zone->refreshtime, &next) < 0)) 12202 next = zone->refreshtime; 12203 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 12204 !isc_time_isepoch(&zone->expiretime)) { 12205 if (isc_time_isepoch(&next) || 12206 isc_time_compare(&zone->expiretime, &next) < 0) 12207 next = zone->expiretime; 12208 } 12209 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 12210 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 12211 INSIST(!isc_time_isepoch(&zone->dumptime)); 12212 if (isc_time_isepoch(&next) || 12213 isc_time_compare(&zone->dumptime, &next) < 0) 12214 next = zone->dumptime; 12215 } 12216 break; 12217 12218 case dns_zone_key: 12219 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 12220 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 12221 INSIST(!isc_time_isepoch(&zone->dumptime)); 12222 if (isc_time_isepoch(&next) || 12223 isc_time_compare(&zone->dumptime, &next) < 0) 12224 next = zone->dumptime; 12225 } 12226 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) { 12227 if (isc_time_isepoch(&next) || 12228 (!isc_time_isepoch(&zone->refreshkeytime) && 12229 isc_time_compare(&zone->refreshkeytime, &next) < 0)) 12230 next = zone->refreshkeytime; 12231 } 12232 break; 12233 12234 default: 12235 break; 12236 } 12237 12238 if (isc_time_isepoch(&next)) { 12239 zone_debuglog(zone, me, 10, "settimer inactive"); 12240 result = isc_timer_reset(zone->timer, isc_timertype_inactive, 12241 NULL, NULL, ISC_TRUE); 12242 if (result != ISC_R_SUCCESS) 12243 dns_zone_log(zone, ISC_LOG_ERROR, 12244 "could not deactivate zone timer: %s", 12245 isc_result_totext(result)); 12246 } else { 12247 if (isc_time_compare(&next, now) <= 0) 12248 next = *now; 12249 result = isc_timer_reset(zone->timer, isc_timertype_once, 12250 &next, NULL, ISC_TRUE); 12251 if (result != ISC_R_SUCCESS) 12252 dns_zone_log(zone, ISC_LOG_ERROR, 12253 "could not reset zone timer: %s", 12254 isc_result_totext(result)); 12255 } 12256 } 12257 12258 static void 12259 cancel_refresh(dns_zone_t *zone) { 12260 const char me[] = "cancel_refresh"; 12261 isc_time_t now; 12262 12263 /* 12264 * 'zone' locked by caller. 12265 */ 12266 12267 REQUIRE(DNS_ZONE_VALID(zone)); 12268 REQUIRE(LOCKED_ZONE(zone)); 12269 12270 ENTER; 12271 12272 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 12273 TIME_NOW(&now); 12274 zone_settimer(zone, &now); 12275 } 12276 12277 static isc_result_t 12278 notify_createmessage(dns_zone_t *zone, unsigned int flags, 12279 dns_message_t **messagep) 12280 { 12281 dns_db_t *zonedb = NULL; 12282 dns_dbnode_t *node = NULL; 12283 dns_dbversion_t *version = NULL; 12284 dns_message_t *message = NULL; 12285 dns_rdataset_t rdataset; 12286 dns_rdata_t rdata = DNS_RDATA_INIT; 12287 12288 dns_name_t *tempname = NULL; 12289 dns_rdata_t *temprdata = NULL; 12290 dns_rdatalist_t *temprdatalist = NULL; 12291 dns_rdataset_t *temprdataset = NULL; 12292 12293 isc_result_t result; 12294 isc_region_t r; 12295 isc_buffer_t *b = NULL; 12296 12297 REQUIRE(DNS_ZONE_VALID(zone)); 12298 REQUIRE(messagep != NULL && *messagep == NULL); 12299 12300 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, 12301 &message); 12302 if (result != ISC_R_SUCCESS) 12303 return (result); 12304 12305 message->opcode = dns_opcode_notify; 12306 message->flags |= DNS_MESSAGEFLAG_AA; 12307 message->rdclass = zone->rdclass; 12308 12309 result = dns_message_gettempname(message, &tempname); 12310 if (result != ISC_R_SUCCESS) 12311 goto cleanup; 12312 12313 result = dns_message_gettemprdataset(message, &temprdataset); 12314 if (result != ISC_R_SUCCESS) 12315 goto cleanup; 12316 12317 /* 12318 * Make question. 12319 */ 12320 dns_name_init(tempname, NULL); 12321 dns_name_clone(&zone->origin, tempname); 12322 dns_rdataset_makequestion(temprdataset, zone->rdclass, 12323 dns_rdatatype_soa); 12324 ISC_LIST_APPEND(tempname->list, temprdataset, link); 12325 dns_message_addname(message, tempname, DNS_SECTION_QUESTION); 12326 tempname = NULL; 12327 temprdataset = NULL; 12328 12329 if ((flags & DNS_NOTIFY_NOSOA) != 0) 12330 goto done; 12331 12332 result = dns_message_gettempname(message, &tempname); 12333 if (result != ISC_R_SUCCESS) 12334 goto soa_cleanup; 12335 result = dns_message_gettemprdata(message, &temprdata); 12336 if (result != ISC_R_SUCCESS) 12337 goto soa_cleanup; 12338 result = dns_message_gettemprdataset(message, &temprdataset); 12339 if (result != ISC_R_SUCCESS) 12340 goto soa_cleanup; 12341 result = dns_message_gettemprdatalist(message, &temprdatalist); 12342 if (result != ISC_R_SUCCESS) 12343 goto soa_cleanup; 12344 12345 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12346 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */ 12347 dns_db_attach(zone->db, &zonedb); 12348 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12349 12350 dns_name_init(tempname, NULL); 12351 dns_name_clone(&zone->origin, tempname); 12352 dns_db_currentversion(zonedb, &version); 12353 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node); 12354 if (result != ISC_R_SUCCESS) 12355 goto soa_cleanup; 12356 12357 dns_rdataset_init(&rdataset); 12358 result = dns_db_findrdataset(zonedb, node, version, 12359 dns_rdatatype_soa, 12360 dns_rdatatype_none, 0, &rdataset, 12361 NULL); 12362 if (result != ISC_R_SUCCESS) 12363 goto soa_cleanup; 12364 result = dns_rdataset_first(&rdataset); 12365 if (result != ISC_R_SUCCESS) 12366 goto soa_cleanup; 12367 dns_rdataset_current(&rdataset, &rdata); 12368 dns_rdata_toregion(&rdata, &r); 12369 result = isc_buffer_allocate(zone->mctx, &b, r.length); 12370 if (result != ISC_R_SUCCESS) 12371 goto soa_cleanup; 12372 isc_buffer_putmem(b, r.base, r.length); 12373 isc_buffer_usedregion(b, &r); 12374 dns_rdata_init(temprdata); 12375 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r); 12376 dns_message_takebuffer(message, &b); 12377 result = dns_rdataset_next(&rdataset); 12378 dns_rdataset_disassociate(&rdataset); 12379 if (result != ISC_R_NOMORE) 12380 goto soa_cleanup; 12381 temprdatalist->rdclass = rdata.rdclass; 12382 temprdatalist->type = rdata.type; 12383 temprdatalist->covers = 0; 12384 temprdatalist->ttl = rdataset.ttl; 12385 ISC_LIST_INIT(temprdatalist->rdata); 12386 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link); 12387 12388 result = dns_rdatalist_tordataset(temprdatalist, temprdataset); 12389 if (result != ISC_R_SUCCESS) 12390 goto soa_cleanup; 12391 12392 ISC_LIST_APPEND(tempname->list, temprdataset, link); 12393 dns_message_addname(message, tempname, DNS_SECTION_ANSWER); 12394 temprdatalist = NULL; 12395 temprdataset = NULL; 12396 temprdata = NULL; 12397 tempname = NULL; 12398 12399 soa_cleanup: 12400 if (node != NULL) 12401 dns_db_detachnode(zonedb, &node); 12402 if (version != NULL) 12403 dns_db_closeversion(zonedb, &version, ISC_FALSE); 12404 if (zonedb != NULL) 12405 dns_db_detach(&zonedb); 12406 if (tempname != NULL) 12407 dns_message_puttempname(message, &tempname); 12408 if (temprdata != NULL) 12409 dns_message_puttemprdata(message, &temprdata); 12410 if (temprdataset != NULL) 12411 dns_message_puttemprdataset(message, &temprdataset); 12412 if (temprdatalist != NULL) 12413 dns_message_puttemprdatalist(message, &temprdatalist); 12414 12415 done: 12416 *messagep = message; 12417 return (ISC_R_SUCCESS); 12418 12419 cleanup: 12420 if (tempname != NULL) 12421 dns_message_puttempname(message, &tempname); 12422 if (temprdataset != NULL) 12423 dns_message_puttemprdataset(message, &temprdataset); 12424 dns_message_destroy(&message); 12425 return (result); 12426 } 12427 12428 isc_result_t 12429 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, 12430 dns_message_t *msg) 12431 { 12432 unsigned int i; 12433 dns_rdata_soa_t soa; 12434 dns_rdataset_t *rdataset = NULL; 12435 dns_rdata_t rdata = DNS_RDATA_INIT; 12436 isc_result_t result; 12437 char fromtext[ISC_SOCKADDR_FORMATSIZE]; 12438 int match = 0; 12439 isc_netaddr_t netaddr; 12440 isc_sockaddr_t local, remote; 12441 isc_uint32_t serial = 0; 12442 isc_boolean_t have_serial = ISC_FALSE; 12443 dns_tsigkey_t *tsigkey; 12444 dns_name_t *tsig; 12445 12446 REQUIRE(DNS_ZONE_VALID(zone)); 12447 12448 /* 12449 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support 12450 * ROLLOVER. 12451 * 12452 * SOA: RFC1996 12453 * Check that 'from' is a valid notify source, (zone->masters). 12454 * Return DNS_R_REFUSED if not. 12455 * 12456 * If the notify message contains a serial number check it 12457 * against the zones serial and return if <= current serial 12458 * 12459 * If a refresh check is progress, if so just record the 12460 * fact we received a NOTIFY and from where and return. 12461 * We will perform a new refresh check when the current one 12462 * completes. Return ISC_R_SUCCESS. 12463 * 12464 * Otherwise initiate a refresh check using 'from' as the 12465 * first address to check. Return ISC_R_SUCCESS. 12466 */ 12467 12468 isc_sockaddr_format(from, fromtext, sizeof(fromtext)); 12469 12470 /* 12471 * Notify messages are processed by the raw zone. 12472 */ 12473 LOCK_ZONE(zone); 12474 INSIST(zone != zone->raw); 12475 if (inline_secure(zone)) { 12476 result = dns_zone_notifyreceive(zone->raw, from, msg); 12477 UNLOCK_ZONE(zone); 12478 return (result); 12479 } 12480 /* 12481 * We only handle NOTIFY (SOA) at the present. 12482 */ 12483 if (isc_sockaddr_pf(from) == PF_INET) 12484 inc_stats(zone, dns_zonestatscounter_notifyinv4); 12485 else 12486 inc_stats(zone, dns_zonestatscounter_notifyinv6); 12487 if (msg->counts[DNS_SECTION_QUESTION] == 0 || 12488 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin, 12489 dns_rdatatype_soa, dns_rdatatype_none, 12490 NULL, NULL) != ISC_R_SUCCESS) { 12491 UNLOCK_ZONE(zone); 12492 if (msg->counts[DNS_SECTION_QUESTION] == 0) { 12493 dns_zone_log(zone, ISC_LOG_NOTICE, 12494 "NOTIFY with no " 12495 "question section from: %s", fromtext); 12496 return (DNS_R_FORMERR); 12497 } 12498 dns_zone_log(zone, ISC_LOG_NOTICE, 12499 "NOTIFY zone does not match"); 12500 return (DNS_R_NOTIMP); 12501 } 12502 12503 /* 12504 * If we are a master zone just succeed. 12505 */ 12506 if (zone->type == dns_zone_master) { 12507 UNLOCK_ZONE(zone); 12508 return (ISC_R_SUCCESS); 12509 } 12510 12511 isc_netaddr_fromsockaddr(&netaddr, from); 12512 for (i = 0; i < zone->masterscnt; i++) { 12513 if (isc_sockaddr_eqaddr(from, &zone->masters[i])) 12514 break; 12515 if (zone->view->aclenv.match_mapped && 12516 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) && 12517 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) { 12518 isc_netaddr_t na1, na2; 12519 isc_netaddr_fromv4mapped(&na1, &netaddr); 12520 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]); 12521 if (isc_netaddr_equal(&na1, &na2)) 12522 break; 12523 } 12524 } 12525 12526 /* 12527 * Accept notify requests from non masters if they are on 12528 * 'zone->notify_acl'. 12529 */ 12530 tsigkey = dns_message_gettsigkey(msg); 12531 tsig = dns_tsigkey_identity(tsigkey); 12532 if (i >= zone->masterscnt && zone->notify_acl != NULL && 12533 dns_acl_match(&netaddr, tsig, zone->notify_acl, 12534 &zone->view->aclenv, 12535 &match, NULL) == ISC_R_SUCCESS && 12536 match > 0) 12537 { 12538 /* Accept notify. */ 12539 } else if (i >= zone->masterscnt) { 12540 UNLOCK_ZONE(zone); 12541 dns_zone_log(zone, ISC_LOG_INFO, 12542 "refused notify from non-master: %s", fromtext); 12543 inc_stats(zone, dns_zonestatscounter_notifyrej); 12544 return (DNS_R_REFUSED); 12545 } 12546 12547 /* 12548 * If the zone is loaded and there are answers check the serial 12549 * to see if we need to do a refresh. Do not worry about this 12550 * check if we are a dialup zone as we use the notify request 12551 * to trigger a refresh check. 12552 */ 12553 if (msg->counts[DNS_SECTION_ANSWER] > 0 && 12554 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 12555 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) { 12556 result = dns_message_findname(msg, DNS_SECTION_ANSWER, 12557 &zone->origin, 12558 dns_rdatatype_soa, 12559 dns_rdatatype_none, NULL, 12560 &rdataset); 12561 if (result == ISC_R_SUCCESS) 12562 result = dns_rdataset_first(rdataset); 12563 if (result == ISC_R_SUCCESS) { 12564 isc_uint32_t oldserial; 12565 unsigned int soacount; 12566 12567 dns_rdataset_current(rdataset, &rdata); 12568 result = dns_rdata_tostruct(&rdata, &soa, NULL); 12569 RUNTIME_CHECK(result == ISC_R_SUCCESS); 12570 serial = soa.serial; 12571 have_serial = ISC_TRUE; 12572 /* 12573 * The following should safely be performed without DB 12574 * lock and succeed in this context. 12575 */ 12576 result = zone_get_from_db(zone, zone->db, NULL, 12577 &soacount, &oldserial, NULL, 12578 NULL, NULL, NULL, NULL); 12579 RUNTIME_CHECK(result == ISC_R_SUCCESS); 12580 RUNTIME_CHECK(soacount > 0U); 12581 if (isc_serial_le(serial, oldserial)) { 12582 dns_zone_log(zone, 12583 ISC_LOG_INFO, 12584 "notify from %s: " 12585 "zone is up to date", 12586 fromtext); 12587 UNLOCK_ZONE(zone); 12588 return (ISC_R_SUCCESS); 12589 } 12590 } 12591 } 12592 12593 /* 12594 * If we got this far and there was a refresh in progress just 12595 * let it complete. Record where we got the notify from so we 12596 * can perform a refresh check when the current one completes 12597 */ 12598 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { 12599 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 12600 zone->notifyfrom = *from; 12601 UNLOCK_ZONE(zone); 12602 if (have_serial) 12603 dns_zone_log(zone, ISC_LOG_INFO, 12604 "notify from %s: serial %u: refresh in " 12605 "progress, refresh check queued", 12606 fromtext, serial); 12607 else 12608 dns_zone_log(zone, ISC_LOG_INFO, 12609 "notify from %s: refresh in progress, " 12610 "refresh check queued", fromtext); 12611 return (ISC_R_SUCCESS); 12612 } 12613 if (have_serial) 12614 dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: serial %u", 12615 fromtext, serial); 12616 else 12617 dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: no serial", 12618 fromtext); 12619 zone->notifyfrom = *from; 12620 local = zone->masteraddr; 12621 remote = zone->sourceaddr; 12622 UNLOCK_ZONE(zone); 12623 dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote); 12624 dns_zone_refresh(zone); 12625 return (ISC_R_SUCCESS); 12626 } 12627 12628 void 12629 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) { 12630 12631 REQUIRE(DNS_ZONE_VALID(zone)); 12632 12633 LOCK_ZONE(zone); 12634 if (zone->notify_acl != NULL) 12635 dns_acl_detach(&zone->notify_acl); 12636 dns_acl_attach(acl, &zone->notify_acl); 12637 UNLOCK_ZONE(zone); 12638 } 12639 12640 void 12641 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) { 12642 12643 REQUIRE(DNS_ZONE_VALID(zone)); 12644 12645 LOCK_ZONE(zone); 12646 if (zone->query_acl != NULL) 12647 dns_acl_detach(&zone->query_acl); 12648 dns_acl_attach(acl, &zone->query_acl); 12649 UNLOCK_ZONE(zone); 12650 } 12651 12652 void 12653 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) { 12654 12655 REQUIRE(DNS_ZONE_VALID(zone)); 12656 12657 LOCK_ZONE(zone); 12658 if (zone->queryon_acl != NULL) 12659 dns_acl_detach(&zone->queryon_acl); 12660 dns_acl_attach(acl, &zone->queryon_acl); 12661 UNLOCK_ZONE(zone); 12662 } 12663 12664 void 12665 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) { 12666 12667 REQUIRE(DNS_ZONE_VALID(zone)); 12668 12669 LOCK_ZONE(zone); 12670 if (zone->update_acl != NULL) 12671 dns_acl_detach(&zone->update_acl); 12672 dns_acl_attach(acl, &zone->update_acl); 12673 UNLOCK_ZONE(zone); 12674 } 12675 12676 void 12677 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) { 12678 12679 REQUIRE(DNS_ZONE_VALID(zone)); 12680 12681 LOCK_ZONE(zone); 12682 if (zone->forward_acl != NULL) 12683 dns_acl_detach(&zone->forward_acl); 12684 dns_acl_attach(acl, &zone->forward_acl); 12685 UNLOCK_ZONE(zone); 12686 } 12687 12688 void 12689 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) { 12690 12691 REQUIRE(DNS_ZONE_VALID(zone)); 12692 12693 LOCK_ZONE(zone); 12694 if (zone->xfr_acl != NULL) 12695 dns_acl_detach(&zone->xfr_acl); 12696 dns_acl_attach(acl, &zone->xfr_acl); 12697 UNLOCK_ZONE(zone); 12698 } 12699 12700 dns_acl_t * 12701 dns_zone_getnotifyacl(dns_zone_t *zone) { 12702 12703 REQUIRE(DNS_ZONE_VALID(zone)); 12704 12705 return (zone->notify_acl); 12706 } 12707 12708 dns_acl_t * 12709 dns_zone_getqueryacl(dns_zone_t *zone) { 12710 12711 REQUIRE(DNS_ZONE_VALID(zone)); 12712 12713 return (zone->query_acl); 12714 } 12715 12716 dns_acl_t * 12717 dns_zone_getqueryonacl(dns_zone_t *zone) { 12718 12719 REQUIRE(DNS_ZONE_VALID(zone)); 12720 12721 return (zone->queryon_acl); 12722 } 12723 12724 dns_acl_t * 12725 dns_zone_getupdateacl(dns_zone_t *zone) { 12726 12727 REQUIRE(DNS_ZONE_VALID(zone)); 12728 12729 return (zone->update_acl); 12730 } 12731 12732 dns_acl_t * 12733 dns_zone_getforwardacl(dns_zone_t *zone) { 12734 12735 REQUIRE(DNS_ZONE_VALID(zone)); 12736 12737 return (zone->forward_acl); 12738 } 12739 12740 dns_acl_t * 12741 dns_zone_getxfracl(dns_zone_t *zone) { 12742 12743 REQUIRE(DNS_ZONE_VALID(zone)); 12744 12745 return (zone->xfr_acl); 12746 } 12747 12748 void 12749 dns_zone_clearupdateacl(dns_zone_t *zone) { 12750 12751 REQUIRE(DNS_ZONE_VALID(zone)); 12752 12753 LOCK_ZONE(zone); 12754 if (zone->update_acl != NULL) 12755 dns_acl_detach(&zone->update_acl); 12756 UNLOCK_ZONE(zone); 12757 } 12758 12759 void 12760 dns_zone_clearforwardacl(dns_zone_t *zone) { 12761 12762 REQUIRE(DNS_ZONE_VALID(zone)); 12763 12764 LOCK_ZONE(zone); 12765 if (zone->forward_acl != NULL) 12766 dns_acl_detach(&zone->forward_acl); 12767 UNLOCK_ZONE(zone); 12768 } 12769 12770 void 12771 dns_zone_clearnotifyacl(dns_zone_t *zone) { 12772 12773 REQUIRE(DNS_ZONE_VALID(zone)); 12774 12775 LOCK_ZONE(zone); 12776 if (zone->notify_acl != NULL) 12777 dns_acl_detach(&zone->notify_acl); 12778 UNLOCK_ZONE(zone); 12779 } 12780 12781 void 12782 dns_zone_clearqueryacl(dns_zone_t *zone) { 12783 12784 REQUIRE(DNS_ZONE_VALID(zone)); 12785 12786 LOCK_ZONE(zone); 12787 if (zone->query_acl != NULL) 12788 dns_acl_detach(&zone->query_acl); 12789 UNLOCK_ZONE(zone); 12790 } 12791 12792 void 12793 dns_zone_clearqueryonacl(dns_zone_t *zone) { 12794 12795 REQUIRE(DNS_ZONE_VALID(zone)); 12796 12797 LOCK_ZONE(zone); 12798 if (zone->queryon_acl != NULL) 12799 dns_acl_detach(&zone->queryon_acl); 12800 UNLOCK_ZONE(zone); 12801 } 12802 12803 void 12804 dns_zone_clearxfracl(dns_zone_t *zone) { 12805 12806 REQUIRE(DNS_ZONE_VALID(zone)); 12807 12808 LOCK_ZONE(zone); 12809 if (zone->xfr_acl != NULL) 12810 dns_acl_detach(&zone->xfr_acl); 12811 UNLOCK_ZONE(zone); 12812 } 12813 12814 isc_boolean_t 12815 dns_zone_getupdatedisabled(dns_zone_t *zone) { 12816 REQUIRE(DNS_ZONE_VALID(zone)); 12817 return (zone->update_disabled); 12818 12819 } 12820 12821 void 12822 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) { 12823 REQUIRE(DNS_ZONE_VALID(zone)); 12824 zone->update_disabled = state; 12825 } 12826 12827 isc_boolean_t 12828 dns_zone_getzeronosoattl(dns_zone_t *zone) { 12829 REQUIRE(DNS_ZONE_VALID(zone)); 12830 return (zone->zero_no_soa_ttl); 12831 12832 } 12833 12834 void 12835 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) { 12836 REQUIRE(DNS_ZONE_VALID(zone)); 12837 zone->zero_no_soa_ttl = state; 12838 } 12839 12840 void 12841 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) { 12842 12843 REQUIRE(DNS_ZONE_VALID(zone)); 12844 12845 zone->check_names = severity; 12846 } 12847 12848 dns_severity_t 12849 dns_zone_getchecknames(dns_zone_t *zone) { 12850 12851 REQUIRE(DNS_ZONE_VALID(zone)); 12852 12853 return (zone->check_names); 12854 } 12855 12856 void 12857 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) { 12858 12859 REQUIRE(DNS_ZONE_VALID(zone)); 12860 12861 zone->journalsize = size; 12862 } 12863 12864 isc_int32_t 12865 dns_zone_getjournalsize(dns_zone_t *zone) { 12866 12867 REQUIRE(DNS_ZONE_VALID(zone)); 12868 12869 return (zone->journalsize); 12870 } 12871 12872 static void 12873 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) { 12874 isc_result_t result = ISC_R_FAILURE; 12875 isc_buffer_t buffer; 12876 12877 REQUIRE(buf != NULL); 12878 REQUIRE(length > 1U); 12879 12880 /* 12881 * Leave space for terminating '\0'. 12882 */ 12883 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 12884 if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) { 12885 if (dns_name_dynamic(&zone->origin)) 12886 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); 12887 if (result != ISC_R_SUCCESS && 12888 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1)) 12889 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 12890 12891 if (isc_buffer_availablelength(&buffer) > 0) 12892 isc_buffer_putstr(&buffer, "/"); 12893 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 12894 } 12895 12896 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 && 12897 strcmp(zone->view->name, "_default") != 0 && 12898 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) { 12899 isc_buffer_putstr(&buffer, "/"); 12900 isc_buffer_putstr(&buffer, zone->view->name); 12901 } 12902 if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer)) 12903 isc_buffer_putstr(&buffer, " (signed)"); 12904 if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer)) 12905 isc_buffer_putstr(&buffer, " (unsigned)"); 12906 12907 buf[isc_buffer_usedlength(&buffer)] = '\0'; 12908 } 12909 12910 static void 12911 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) { 12912 isc_result_t result = ISC_R_FAILURE; 12913 isc_buffer_t buffer; 12914 12915 REQUIRE(buf != NULL); 12916 REQUIRE(length > 1U); 12917 12918 /* 12919 * Leave space for terminating '\0'. 12920 */ 12921 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 12922 if (dns_name_dynamic(&zone->origin)) 12923 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); 12924 if (result != ISC_R_SUCCESS && 12925 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1)) 12926 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 12927 12928 buf[isc_buffer_usedlength(&buffer)] = '\0'; 12929 } 12930 12931 static void 12932 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) { 12933 isc_buffer_t buffer; 12934 12935 REQUIRE(buf != NULL); 12936 REQUIRE(length > 1U); 12937 12938 /* 12939 * Leave space for terminating '\0'. 12940 */ 12941 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 12942 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 12943 12944 buf[isc_buffer_usedlength(&buffer)] = '\0'; 12945 } 12946 12947 static void 12948 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) { 12949 isc_buffer_t buffer; 12950 12951 REQUIRE(buf != NULL); 12952 REQUIRE(length > 1U); 12953 12954 12955 /* 12956 * Leave space for terminating '\0'. 12957 */ 12958 isc_buffer_init(&buffer, buf, (unsigned int)length - 1); 12959 12960 if (zone->view == NULL) { 12961 isc_buffer_putstr(&buffer, "_none"); 12962 } else if (strlen(zone->view->name) 12963 < isc_buffer_availablelength(&buffer)) { 12964 isc_buffer_putstr(&buffer, zone->view->name); 12965 } else { 12966 isc_buffer_putstr(&buffer, "_toolong"); 12967 } 12968 12969 buf[isc_buffer_usedlength(&buffer)] = '\0'; 12970 } 12971 12972 void 12973 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) { 12974 REQUIRE(DNS_ZONE_VALID(zone)); 12975 REQUIRE(buf != NULL); 12976 zone_namerd_tostr(zone, buf, length); 12977 } 12978 12979 static void 12980 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) { 12981 va_list ap; 12982 char message[4096]; 12983 12984 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 12985 return; 12986 12987 va_start(ap, fmt); 12988 vsnprintf(message, sizeof(message), fmt, ap); 12989 va_end(ap); 12990 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE, 12991 level, "zone %s: %s", zone->strnamerd, message); 12992 } 12993 12994 void 12995 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, 12996 int level, const char *fmt, ...) { 12997 va_list ap; 12998 char message[4096]; 12999 13000 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 13001 return; 13002 13003 va_start(ap, fmt); 13004 vsnprintf(message, sizeof(message), fmt, ap); 13005 va_end(ap); 13006 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, 13007 level, "%s%s: %s", (zone->type == dns_zone_key) ? 13008 "managed-keys-zone" : (zone->type == dns_zone_redirect) ? 13009 "redirect-zone" : "zone ", zone->strnamerd, message); 13010 } 13011 13012 void 13013 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) { 13014 va_list ap; 13015 char message[4096]; 13016 13017 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 13018 return; 13019 13020 va_start(ap, fmt); 13021 vsnprintf(message, sizeof(message), fmt, ap); 13022 va_end(ap); 13023 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, 13024 level, "%s%s: %s", (zone->type == dns_zone_key) ? 13025 "managed-keys-zone" : (zone->type == dns_zone_redirect) ? 13026 "redirect-zone" : "zone ", zone->strnamerd, message); 13027 } 13028 13029 static void 13030 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel, 13031 const char *fmt, ...) 13032 { 13033 va_list ap; 13034 char message[4096]; 13035 int level = ISC_LOG_DEBUG(debuglevel); 13036 const char *zstr; 13037 13038 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 13039 return; 13040 13041 va_start(ap, fmt); 13042 vsnprintf(message, sizeof(message), fmt, ap); 13043 va_end(ap); 13044 13045 switch (zone->type) { 13046 case dns_zone_key: 13047 zstr = "managed-keys-zone"; 13048 break; 13049 case dns_zone_redirect: 13050 zstr = "redirect-zone"; 13051 break; 13052 default: 13053 zstr = "zone"; 13054 } 13055 13056 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, 13057 level, "%s: %s %s: %s", me, zstr, zone->strnamerd, 13058 message); 13059 } 13060 13061 static int 13062 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type) 13063 { 13064 isc_result_t result; 13065 dns_name_t *name; 13066 dns_rdataset_t *curr; 13067 int count = 0; 13068 13069 result = dns_message_firstname(msg, section); 13070 while (result == ISC_R_SUCCESS) { 13071 name = NULL; 13072 dns_message_currentname(msg, section, &name); 13073 13074 for (curr = ISC_LIST_TAIL(name->list); curr != NULL; 13075 curr = ISC_LIST_PREV(curr, link)) { 13076 if (curr->type == type) 13077 count++; 13078 } 13079 result = dns_message_nextname(msg, section); 13080 } 13081 13082 return (count); 13083 } 13084 13085 void 13086 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) { 13087 REQUIRE(DNS_ZONE_VALID(zone)); 13088 13089 zone->maxxfrin = maxxfrin; 13090 } 13091 13092 isc_uint32_t 13093 dns_zone_getmaxxfrin(dns_zone_t *zone) { 13094 REQUIRE(DNS_ZONE_VALID(zone)); 13095 13096 return (zone->maxxfrin); 13097 } 13098 13099 void 13100 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) { 13101 REQUIRE(DNS_ZONE_VALID(zone)); 13102 zone->maxxfrout = maxxfrout; 13103 } 13104 13105 isc_uint32_t 13106 dns_zone_getmaxxfrout(dns_zone_t *zone) { 13107 REQUIRE(DNS_ZONE_VALID(zone)); 13108 13109 return (zone->maxxfrout); 13110 } 13111 13112 dns_zonetype_t 13113 dns_zone_gettype(dns_zone_t *zone) { 13114 REQUIRE(DNS_ZONE_VALID(zone)); 13115 13116 return (zone->type); 13117 } 13118 13119 dns_name_t * 13120 dns_zone_getorigin(dns_zone_t *zone) { 13121 REQUIRE(DNS_ZONE_VALID(zone)); 13122 13123 return (&zone->origin); 13124 } 13125 13126 void 13127 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) { 13128 REQUIRE(DNS_ZONE_VALID(zone)); 13129 13130 LOCK_ZONE(zone); 13131 if (zone->task != NULL) 13132 isc_task_detach(&zone->task); 13133 isc_task_attach(task, &zone->task); 13134 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 13135 if (zone->db != NULL) 13136 dns_db_settask(zone->db, zone->task); 13137 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 13138 UNLOCK_ZONE(zone); 13139 } 13140 13141 void 13142 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) { 13143 REQUIRE(DNS_ZONE_VALID(zone)); 13144 isc_task_attach(zone->task, target); 13145 } 13146 13147 void 13148 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) { 13149 REQUIRE(DNS_ZONE_VALID(zone)); 13150 13151 if (idlein == 0) 13152 idlein = DNS_DEFAULT_IDLEIN; 13153 zone->idlein = idlein; 13154 } 13155 13156 isc_uint32_t 13157 dns_zone_getidlein(dns_zone_t *zone) { 13158 REQUIRE(DNS_ZONE_VALID(zone)); 13159 13160 return (zone->idlein); 13161 } 13162 13163 void 13164 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) { 13165 REQUIRE(DNS_ZONE_VALID(zone)); 13166 13167 zone->idleout = idleout; 13168 } 13169 13170 isc_uint32_t 13171 dns_zone_getidleout(dns_zone_t *zone) { 13172 REQUIRE(DNS_ZONE_VALID(zone)); 13173 13174 return (zone->idleout); 13175 } 13176 13177 static void 13178 notify_done(isc_task_t *task, isc_event_t *event) { 13179 dns_requestevent_t *revent = (dns_requestevent_t *)event; 13180 dns_notify_t *notify; 13181 isc_result_t result; 13182 dns_message_t *message = NULL; 13183 isc_buffer_t buf; 13184 char rcode[128]; 13185 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 13186 13187 UNUSED(task); 13188 13189 notify = event->ev_arg; 13190 REQUIRE(DNS_NOTIFY_VALID(notify)); 13191 INSIST(task == notify->zone->task); 13192 13193 isc_buffer_init(&buf, rcode, sizeof(rcode)); 13194 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 13195 13196 result = revent->result; 13197 if (result == ISC_R_SUCCESS) 13198 result = dns_message_create(notify->zone->mctx, 13199 DNS_MESSAGE_INTENTPARSE, &message); 13200 if (result == ISC_R_SUCCESS) 13201 result = dns_request_getresponse(revent->request, message, 13202 DNS_MESSAGEPARSE_PRESERVEORDER); 13203 if (result == ISC_R_SUCCESS) 13204 result = dns_rcode_totext(message->rcode, &buf); 13205 if (result == ISC_R_SUCCESS) 13206 notify_log(notify->zone, ISC_LOG_DEBUG(3), 13207 "notify response from %s: %.*s", 13208 addrbuf, (int)buf.used, rcode); 13209 else 13210 notify_log(notify->zone, ISC_LOG_DEBUG(2), 13211 "notify to %s failed: %s", addrbuf, 13212 dns_result_totext(result)); 13213 13214 /* 13215 * Old bind's return formerr if they see a soa record. Retry w/o 13216 * the soa if we see a formerr and had sent a SOA. 13217 */ 13218 isc_event_free(&event); 13219 if (message != NULL && message->rcode == dns_rcode_formerr && 13220 (notify->flags & DNS_NOTIFY_NOSOA) == 0) { 13221 isc_boolean_t startup; 13222 13223 notify->flags |= DNS_NOTIFY_NOSOA; 13224 dns_request_destroy(¬ify->request); 13225 startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0); 13226 result = notify_send_queue(notify, startup); 13227 if (result != ISC_R_SUCCESS) 13228 notify_destroy(notify, ISC_FALSE); 13229 } else { 13230 if (result == ISC_R_TIMEDOUT) 13231 notify_log(notify->zone, ISC_LOG_DEBUG(1), 13232 "notify to %s: retries exceeded", addrbuf); 13233 notify_destroy(notify, ISC_FALSE); 13234 } 13235 if (message != NULL) 13236 dns_message_destroy(&message); 13237 } 13238 13239 struct secure_event { 13240 isc_event_t e; 13241 dns_db_t *db; 13242 isc_uint32_t serial; 13243 }; 13244 13245 static void 13246 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) { 13247 UNUSED(arg); 13248 dns_zone_log(zone, level, "%s", message); 13249 } 13250 13251 static isc_result_t 13252 sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal, 13253 isc_uint32_t start, isc_uint32_t end, 13254 dns_difftuple_t **soatuplep, dns_diff_t *diff) 13255 { 13256 isc_result_t result; 13257 dns_difftuple_t *tuple = NULL; 13258 dns_diffop_t op = DNS_DIFFOP_ADD; 13259 int n_soa = 0; 13260 13261 REQUIRE(soatuplep != NULL); 13262 13263 if (start == end) 13264 return (DNS_R_UNCHANGED); 13265 13266 CHECK(dns_journal_iter_init(journal, start, end)); 13267 for (result = dns_journal_first_rr(journal); 13268 result == ISC_R_SUCCESS; 13269 result = dns_journal_next_rr(journal)) 13270 { 13271 dns_name_t *name = NULL; 13272 isc_uint32_t ttl; 13273 dns_rdata_t *rdata = NULL; 13274 dns_journal_current_rr(journal, &name, &ttl, &rdata); 13275 13276 if (rdata->type == dns_rdatatype_soa) { 13277 n_soa++; 13278 if (n_soa == 2) { 13279 /* 13280 * Save the latest raw SOA record. 13281 */ 13282 if (*soatuplep != NULL) 13283 dns_difftuple_free(soatuplep); 13284 CHECK(dns_difftuple_create(diff->mctx, 13285 DNS_DIFFOP_ADD, 13286 name, ttl, rdata, 13287 soatuplep)); 13288 } 13289 if (n_soa == 3) 13290 n_soa = 1; 13291 continue; 13292 } 13293 13294 /* Sanity. */ 13295 if (n_soa == 0) { 13296 dns_zone_log(raw, ISC_LOG_ERROR, 13297 "corrupt journal file: '%s'\n", 13298 raw->journal); 13299 return (ISC_R_FAILURE); 13300 } 13301 13302 if (zone->privatetype != 0 && 13303 rdata->type == zone->privatetype) 13304 continue; 13305 13306 if (rdata->type == dns_rdatatype_nsec || 13307 rdata->type == dns_rdatatype_rrsig || 13308 rdata->type == dns_rdatatype_nsec3 || 13309 rdata->type == dns_rdatatype_dnskey || 13310 rdata->type == dns_rdatatype_nsec3param) 13311 continue; 13312 13313 op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD; 13314 13315 CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata, 13316 &tuple)); 13317 dns_diff_appendminimal(diff, &tuple); 13318 } 13319 if (result == ISC_R_NOMORE) 13320 result = ISC_R_SUCCESS; 13321 13322 failure: 13323 return(result); 13324 } 13325 13326 static isc_result_t 13327 sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb, 13328 dns_dbversion_t *secver, dns_difftuple_t **soatuple, 13329 dns_diff_t *diff) 13330 { 13331 isc_result_t result; 13332 dns_db_t *rawdb = NULL; 13333 dns_dbversion_t *rawver = NULL; 13334 dns_difftuple_t *tuple = NULL, *next; 13335 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL; 13336 dns_rdata_soa_t oldsoa, newsoa; 13337 13338 REQUIRE(DNS_ZONE_VALID(seczone)); 13339 REQUIRE(soatuple != NULL && *soatuple == NULL); 13340 13341 if (!seczone->sourceserialset) 13342 return (DNS_R_UNCHANGED); 13343 13344 dns_db_attach(raw->db, &rawdb); 13345 dns_db_currentversion(rawdb, &rawver); 13346 result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL); 13347 dns_db_closeversion(rawdb, &rawver, ISC_FALSE); 13348 dns_db_detach(&rawdb); 13349 13350 if (result != ISC_R_SUCCESS) 13351 return (result); 13352 13353 for (tuple = ISC_LIST_HEAD(diff->tuples); 13354 tuple != NULL; 13355 tuple = next) 13356 { 13357 next = ISC_LIST_NEXT(tuple, link); 13358 if (tuple->rdata.type == dns_rdatatype_nsec || 13359 tuple->rdata.type == dns_rdatatype_rrsig || 13360 tuple->rdata.type == dns_rdatatype_dnskey || 13361 tuple->rdata.type == dns_rdatatype_nsec3 || 13362 tuple->rdata.type == dns_rdatatype_nsec3param) 13363 { 13364 ISC_LIST_UNLINK(diff->tuples, tuple, link); 13365 dns_difftuple_free(&tuple); 13366 continue; 13367 } 13368 if (tuple->rdata.type == dns_rdatatype_soa) { 13369 if (tuple->op == DNS_DIFFOP_DEL) { 13370 INSIST(oldtuple == NULL); 13371 oldtuple = tuple; 13372 } 13373 if (tuple->op == DNS_DIFFOP_ADD) { 13374 INSIST(newtuple == NULL); 13375 newtuple = tuple; 13376 } 13377 } 13378 } 13379 13380 if (oldtuple != NULL && newtuple != NULL) { 13381 13382 result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL); 13383 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13384 13385 result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL); 13386 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13387 13388 /* 13389 * If the SOA records are the same except for the serial 13390 * remove them from the diff. 13391 */ 13392 if (oldsoa.refresh == newsoa.refresh && 13393 oldsoa.retry == newsoa.retry && 13394 oldsoa.minimum == newsoa.minimum && 13395 oldsoa.expire == newsoa.expire && 13396 dns_name_equal(&oldsoa.origin, &newsoa.origin) && 13397 dns_name_equal(&oldsoa.contact, &newsoa.contact)) { 13398 ISC_LIST_UNLINK(diff->tuples, oldtuple, link); 13399 dns_difftuple_free(&oldtuple); 13400 ISC_LIST_UNLINK(diff->tuples, newtuple, link); 13401 dns_difftuple_free(&newtuple); 13402 } 13403 } 13404 13405 if (ISC_LIST_EMPTY(diff->tuples)) 13406 return (DNS_R_UNCHANGED); 13407 13408 /* 13409 * If there are still SOA records in the diff they can now be removed 13410 * saving the new SOA record. 13411 */ 13412 if (oldtuple != NULL) { 13413 ISC_LIST_UNLINK(diff->tuples, oldtuple, link); 13414 dns_difftuple_free(&oldtuple); 13415 } 13416 13417 if (newtuple != NULL) { 13418 ISC_LIST_UNLINK(diff->tuples, newtuple, link); 13419 *soatuple = newtuple; 13420 } 13421 13422 return (ISC_R_SUCCESS); 13423 } 13424 13425 static void 13426 receive_secure_serial(isc_task_t *task, isc_event_t *event) { 13427 static char me[] = "receive_secure_serial"; 13428 isc_result_t result; 13429 dns_journal_t *rjournal = NULL; 13430 isc_uint32_t start, end; 13431 dns_zone_t *zone, *raw = NULL; 13432 dns_db_t *db = NULL; 13433 dns_dbversion_t *newver = NULL, *oldver = NULL; 13434 dns_diff_t diff; 13435 dns_difftuple_t *tuple = NULL, *soatuple = NULL; 13436 dns_update_log_t log = { update_log_cb, NULL }; 13437 isc_time_t timenow; 13438 13439 zone = event->ev_arg; 13440 end = ((struct secure_event *)event)->serial; 13441 isc_event_free(&event); 13442 13443 ENTER; 13444 13445 LOCK_ZONE(zone); 13446 13447 dns_diff_init(zone->mctx, &diff); 13448 13449 UNUSED(task); 13450 13451 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 13452 if (zone->db != NULL) 13453 dns_db_attach(zone->db, &db); 13454 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 13455 13456 if (zone->raw != NULL) 13457 dns_zone_attach(zone->raw, &raw); 13458 UNLOCK_ZONE(zone); 13459 13460 /* 13461 * zone->db may be NULL if the load from disk failed. 13462 */ 13463 if (db == NULL || raw == NULL) { 13464 result = ISC_R_FAILURE; 13465 goto failure; 13466 } 13467 13468 /* 13469 * We first attempt to sync the raw zone to the secure zone 13470 * by using the raw zone's journal, applying all the deltas 13471 * from the latest source-serial of the secure zone up to 13472 * the current serial number of the raw zone. 13473 * 13474 * If that fails, then we'll fall back to a direct comparison 13475 * between raw and secure zones. 13476 */ 13477 result = dns_journal_open(raw->mctx, raw->journal, 13478 DNS_JOURNAL_WRITE, &rjournal); 13479 if (result != ISC_R_SUCCESS) 13480 goto failure; 13481 else { 13482 dns_journal_t *sjournal = NULL; 13483 13484 result = dns_journal_open(zone->mctx, zone->journal, 13485 DNS_JOURNAL_READ, &sjournal); 13486 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) 13487 goto failure; 13488 13489 if (!dns_journal_get_sourceserial(rjournal, &start)) { 13490 start = dns_journal_first_serial(rjournal); 13491 dns_journal_set_sourceserial(rjournal, start); 13492 } 13493 if (sjournal != NULL) { 13494 isc_uint32_t serial; 13495 /* 13496 * We read the secure journal first, if that exists 13497 * use its value provided it is greater that from the 13498 * raw journal. 13499 */ 13500 if (dns_journal_get_sourceserial(sjournal, &serial)) { 13501 if (isc_serial_gt(serial, start)) 13502 start = serial; 13503 } 13504 dns_journal_destroy(&sjournal); 13505 } 13506 } 13507 13508 dns_db_currentversion(db, &oldver); 13509 CHECK(dns_db_newversion(db, &newver)); 13510 13511 /* 13512 * Try to apply diffs from the raw zone's journal to the secure 13513 * zone. If that fails, we recover by syncing up the databases 13514 * directly. 13515 */ 13516 result = sync_secure_journal(zone, raw, rjournal, start, end, 13517 &soatuple, &diff); 13518 if (result == DNS_R_UNCHANGED) 13519 goto failure; 13520 else if (result != ISC_R_SUCCESS) 13521 CHECK(sync_secure_db(zone, raw, db, oldver, &soatuple, &diff)); 13522 13523 CHECK(dns_diff_apply(&diff, db, newver)); 13524 13525 if (soatuple != NULL) { 13526 isc_uint32_t oldserial, newserial, desired; 13527 13528 CHECK(dns_db_createsoatuple(db, oldver, diff.mctx, 13529 DNS_DIFFOP_DEL, &tuple)); 13530 oldserial = dns_soa_getserial(&tuple->rdata); 13531 newserial = desired = dns_soa_getserial(&soatuple->rdata); 13532 if (!isc_serial_gt(newserial, oldserial)) { 13533 newserial = oldserial + 1; 13534 if (newserial == 0) 13535 newserial++; 13536 dns_soa_setserial(newserial, &soatuple->rdata); 13537 } 13538 CHECK(do_one_tuple(&tuple, db, newver, &diff)); 13539 CHECK(do_one_tuple(&soatuple, db, newver, &diff)); 13540 dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)", 13541 newserial, desired); 13542 } else 13543 CHECK(update_soa_serial(db, newver, &diff, zone->mctx, 13544 zone->updatemethod)); 13545 13546 CHECK(dns_update_signatures(&log, zone, db, oldver, newver, 13547 &diff, zone->sigvalidityinterval)); 13548 13549 CHECK(zone_journal(zone, &diff, &end, "receive_secure_serial")); 13550 13551 dns_journal_set_sourceserial(rjournal, end); 13552 dns_journal_commit(rjournal); 13553 13554 LOCK_ZONE(zone); 13555 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 13556 13557 zone->sourceserial = end; 13558 zone->sourceserialset = ISC_TRUE; 13559 zone_needdump(zone, DNS_DUMP_DELAY); 13560 13561 TIME_NOW(&timenow); 13562 zone_settimer(zone, &timenow); 13563 UNLOCK_ZONE(zone); 13564 13565 dns_db_closeversion(db, &oldver, ISC_FALSE); 13566 dns_db_closeversion(db, &newver, ISC_TRUE); 13567 13568 failure: 13569 if (raw != NULL) 13570 dns_zone_detach(&raw); 13571 if (result != ISC_R_SUCCESS) 13572 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s", 13573 dns_result_totext(result)); 13574 if (tuple != NULL) 13575 dns_difftuple_free(&tuple); 13576 if (soatuple != NULL) 13577 dns_difftuple_free(&soatuple); 13578 if (db != NULL) { 13579 if (oldver != NULL) 13580 dns_db_closeversion(db, &oldver, ISC_FALSE); 13581 if (newver != NULL) 13582 dns_db_closeversion(db, &newver, ISC_FALSE); 13583 dns_db_detach(&db); 13584 } 13585 if (rjournal != NULL) 13586 dns_journal_destroy(&rjournal); 13587 dns_diff_clear(&diff); 13588 dns_zone_idetach(&zone); 13589 13590 INSIST(oldver == NULL); 13591 INSIST(newver == NULL); 13592 } 13593 13594 static isc_result_t 13595 zone_send_secureserial(dns_zone_t *zone, isc_uint32_t serial) { 13596 isc_event_t *e; 13597 dns_zone_t *dummy = NULL; 13598 13599 e = isc_event_allocate(zone->secure->mctx, zone, 13600 DNS_EVENT_ZONESECURESERIAL, 13601 receive_secure_serial, zone->secure, 13602 sizeof(struct secure_event)); 13603 if (e == NULL) 13604 return (ISC_R_NOMEMORY); 13605 ((struct secure_event *)e)->serial = serial; 13606 INSIST(LOCKED_ZONE(zone->secure)); 13607 zone_iattach(zone->secure, &dummy); 13608 isc_task_send(zone->secure->task, &e); 13609 13610 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); 13611 return (ISC_R_SUCCESS); 13612 } 13613 13614 static isc_result_t 13615 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 13616 dns_rdataset_t *rdataset, isc_uint32_t oldserial) 13617 { 13618 dns_rdata_soa_t soa; 13619 dns_rdata_t rdata = DNS_RDATA_INIT; 13620 dns_rdatalist_t temprdatalist; 13621 dns_rdataset_t temprdataset; 13622 isc_buffer_t b; 13623 isc_result_t result; 13624 unsigned char buf[DNS_SOA_BUFFERSIZE]; 13625 13626 result = dns_rdataset_first(rdataset); 13627 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13628 dns_rdataset_current(rdataset, &rdata); 13629 result = dns_rdata_tostruct(&rdata, &soa, NULL); 13630 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13631 13632 if (isc_serial_gt(soa.serial, oldserial)) 13633 return (dns_db_addrdataset(db, node, version, 0, rdataset, 0, 13634 NULL)); 13635 /* 13636 * Always bump the serial. 13637 */ 13638 oldserial++; 13639 if (oldserial == 0) 13640 oldserial++; 13641 soa.serial = oldserial; 13642 13643 /* 13644 * Construct a replacement rdataset. 13645 */ 13646 dns_rdata_reset(&rdata); 13647 isc_buffer_init(&b, buf, sizeof(buf)); 13648 result = dns_rdata_fromstruct(&rdata, rdataset->rdclass, 13649 dns_rdatatype_soa, &soa, &b); 13650 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13651 temprdatalist.rdclass = rdata.rdclass; 13652 temprdatalist.type = rdata.type; 13653 temprdatalist.covers = 0; 13654 temprdatalist.ttl = rdataset->ttl; 13655 ISC_LIST_INIT(temprdatalist.rdata); 13656 ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link); 13657 13658 dns_rdataset_init(&temprdataset); 13659 result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset); 13660 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13661 return (dns_db_addrdataset(db, node, version, 0, &temprdataset, 13662 0, NULL)); 13663 } 13664 13665 /* 13666 * This function should populate an nsec3paramlist_t with the 13667 * nsecparam_t data from a zone. 13668 */ 13669 static isc_result_t 13670 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) { 13671 isc_result_t result; 13672 dns_dbnode_t *node = NULL; 13673 dns_rdataset_t rdataset, prdataset; 13674 dns_dbversion_t *version = NULL; 13675 nsec3param_t *nsec3param = NULL; 13676 nsec3param_t *nsec3p = NULL; 13677 nsec3param_t *next; 13678 dns_db_t *db = NULL; 13679 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 13680 13681 REQUIRE(DNS_ZONE_VALID(zone)); 13682 REQUIRE(nsec3list != NULL); 13683 REQUIRE(ISC_LIST_EMPTY(*nsec3list)); 13684 13685 dns_rdataset_init(&rdataset); 13686 dns_rdataset_init(&prdataset); 13687 13688 dns_db_attach(zone->db, &db); 13689 CHECK(dns_db_getoriginnode(db, &node)); 13690 13691 dns_db_currentversion(db, &version); 13692 result = dns_db_findrdataset(db, node, version, 13693 dns_rdatatype_nsec3param, 13694 dns_rdatatype_none, 0, &rdataset, NULL); 13695 13696 if (result != ISC_R_SUCCESS) 13697 goto getprivate; 13698 13699 /* 13700 * walk nsec3param rdataset making a list of parameters (note that 13701 * multiple simultaneous nsec3 chains are annoyingly legal -- this 13702 * is why we use an nsec3list, even tho we will usually only have 13703 * one) 13704 */ 13705 for (result = dns_rdataset_first(&rdataset); 13706 result == ISC_R_SUCCESS; 13707 result = dns_rdataset_next(&rdataset)) 13708 { 13709 dns_rdata_t rdata = DNS_RDATA_INIT; 13710 dns_rdata_t private = DNS_RDATA_INIT; 13711 13712 dns_rdataset_current(&rdataset, &rdata); 13713 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 13714 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 13715 "looping through nsec3param data"); 13716 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t)); 13717 if (nsec3param == NULL) 13718 CHECK(ISC_R_NOMEMORY); 13719 ISC_LINK_INIT(nsec3param, link); 13720 13721 /* 13722 * now transfer the data from the rdata to 13723 * the nsec3param 13724 */ 13725 dns_nsec3param_toprivate(&rdata, &private, 13726 zone->privatetype, nsec3param->data, 13727 sizeof(nsec3param->data)); 13728 nsec3param->length = private.length; 13729 ISC_LIST_APPEND(*nsec3list, nsec3param, link); 13730 } 13731 13732 getprivate: 13733 result = dns_db_findrdataset(db, node, version, zone->privatetype, 13734 dns_rdatatype_none, 0, &prdataset, NULL); 13735 if (result != ISC_R_SUCCESS) 13736 goto done; 13737 13738 /* 13739 * walk private type records, converting them to nsec3 parameters 13740 * using dns_nsec3param_fromprivate(), do the right thing based on 13741 * CREATE and REMOVE flags 13742 */ 13743 for (result = dns_rdataset_first(&prdataset); 13744 result == ISC_R_SUCCESS; 13745 result = dns_rdataset_next(&prdataset)) 13746 { 13747 dns_rdata_t rdata = DNS_RDATA_INIT; 13748 dns_rdata_t private = DNS_RDATA_INIT; 13749 13750 dns_rdataset_current(&prdataset, &private); 13751 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 13752 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 13753 "looping through nsec3param private data"); 13754 13755 /* 13756 * Do we have a valid private record? 13757 */ 13758 if (!dns_nsec3param_fromprivate(&private, &rdata, 13759 buf, sizeof(buf))) 13760 continue; 13761 13762 /* 13763 * Remove any NSEC3PARAM records scheduled to be removed. 13764 */ 13765 if (NSEC3REMOVE(rdata.data[1])) { 13766 /* 13767 * Zero out the flags. 13768 */ 13769 rdata.data[1] = 0; 13770 13771 for (nsec3p = ISC_LIST_HEAD(*nsec3list); 13772 nsec3p != NULL; 13773 nsec3p = next) 13774 { 13775 next = ISC_LIST_NEXT(nsec3p, link); 13776 13777 if (nsec3p->length == rdata.length + 1 && 13778 memcmp(rdata.data, nsec3p->data + 1, 13779 nsec3p->length - 1) == 0) { 13780 ISC_LIST_UNLINK(*nsec3list, 13781 nsec3p, link); 13782 isc_mem_put(zone->mctx, nsec3p, 13783 sizeof(nsec3param_t)); 13784 } 13785 } 13786 continue; 13787 } 13788 13789 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t)); 13790 if (nsec3param == NULL) 13791 CHECK(ISC_R_NOMEMORY); 13792 ISC_LINK_INIT(nsec3param, link); 13793 13794 /* 13795 * Copy the remaining private records so the nsec/nsec3 13796 * chain gets created. 13797 */ 13798 INSIST(private.length <= sizeof(nsec3param->data)); 13799 memmove(nsec3param->data, private.data, private.length); 13800 nsec3param->length = private.length; 13801 ISC_LIST_APPEND(*nsec3list, nsec3param, link); 13802 } 13803 13804 done: 13805 if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) 13806 result = ISC_R_SUCCESS; 13807 13808 failure: 13809 if (node != NULL) 13810 dns_db_detachnode(db, &node); 13811 if (version != NULL) 13812 dns_db_closeversion(db, &version, ISC_FALSE); 13813 if (db != NULL) 13814 dns_db_detach(&db); 13815 if (dns_rdataset_isassociated(&rdataset)) 13816 dns_rdataset_disassociate(&rdataset); 13817 if (dns_rdataset_isassociated(&prdataset)) 13818 dns_rdataset_disassociate(&prdataset); 13819 return (result); 13820 } 13821 13822 /* 13823 * Walk the list of the nsec3 chains desired for the zone, converting 13824 * parameters to private type records using dns_nsec3param_toprivate(), 13825 * and insert them into the new zone db. 13826 */ 13827 static isc_result_t 13828 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 13829 nsec3paramlist_t *nsec3list) 13830 { 13831 isc_result_t result; 13832 dns_diff_t diff; 13833 dns_rdata_t rdata; 13834 nsec3param_t *nsec3p = NULL; 13835 nsec3param_t *next; 13836 13837 REQUIRE(DNS_ZONE_VALID(zone)); 13838 REQUIRE(!ISC_LIST_EMPTY(*nsec3list)); 13839 13840 dns_diff_init(zone->mctx, &diff); 13841 13842 /* 13843 * Loop through the list of private-type records, set the INITIAL 13844 * and CREATE flags, and the add the record to the apex of the tree 13845 * in db. 13846 */ 13847 for (nsec3p = ISC_LIST_HEAD(*nsec3list); 13848 nsec3p != NULL; 13849 nsec3p = next) 13850 { 13851 next = ISC_LIST_NEXT(nsec3p, link); 13852 dns_rdata_init(&rdata); 13853 nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL; 13854 rdata.length = nsec3p->length; 13855 rdata.data = nsec3p->data; 13856 rdata.type = zone->privatetype; 13857 rdata.rdclass = zone->rdclass; 13858 CHECK(update_one_rr(db, version, &diff, DNS_DIFFOP_ADD, 13859 &zone->origin, 0, &rdata)); 13860 } 13861 13862 result = ISC_R_SUCCESS; 13863 13864 failure: 13865 for (nsec3p = ISC_LIST_HEAD(*nsec3list); 13866 nsec3p != NULL; 13867 nsec3p = next) 13868 { 13869 next = ISC_LIST_NEXT(nsec3p, link); 13870 ISC_LIST_UNLINK(*nsec3list, nsec3p, link); 13871 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t)); 13872 } 13873 13874 dns_diff_clear(&diff); 13875 return (result); 13876 } 13877 13878 static void 13879 receive_secure_db(isc_task_t *task, isc_event_t *event) { 13880 isc_result_t result; 13881 dns_zone_t *zone; 13882 dns_db_t *rawdb, *db = NULL; 13883 dns_dbnode_t *rawnode = NULL, *node = NULL; 13884 dns_fixedname_t fname; 13885 dns_name_t *name; 13886 dns_dbiterator_t *dbiterator = NULL; 13887 dns_rdatasetiter_t *rdsit = NULL; 13888 dns_rdataset_t rdataset; 13889 dns_dbversion_t *version = NULL; 13890 isc_time_t loadtime; 13891 unsigned int oldserial = 0; 13892 isc_boolean_t have_oldserial = ISC_FALSE; 13893 nsec3paramlist_t nsec3list; 13894 13895 UNUSED(task); 13896 13897 ISC_LIST_INIT(nsec3list); 13898 13899 zone = event->ev_arg; 13900 rawdb = ((struct secure_event *)event)->db; 13901 isc_event_free(&event); 13902 13903 dns_fixedname_init(&fname); 13904 name = dns_fixedname_name(&fname); 13905 dns_rdataset_init(&rdataset); 13906 13907 LOCK_ZONE(zone); 13908 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) { 13909 result = ISC_R_SHUTTINGDOWN; 13910 goto failure; 13911 } 13912 13913 TIME_NOW(&loadtime); 13914 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 13915 if (zone->db != NULL) { 13916 result = dns_db_getsoaserial(zone->db, NULL, &oldserial); 13917 if (result == ISC_R_SUCCESS) 13918 have_oldserial = ISC_TRUE; 13919 13920 /* 13921 * assemble nsec3parameters from the old zone, and set a flag 13922 * if any are found 13923 */ 13924 result = save_nsec3param(zone, &nsec3list); 13925 if (result != ISC_R_SUCCESS) { 13926 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 13927 goto failure; 13928 } 13929 } 13930 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 13931 13932 result = dns_db_create(zone->mctx, zone->db_argv[0], 13933 &zone->origin, dns_dbtype_zone, zone->rdclass, 13934 zone->db_argc - 1, zone->db_argv + 1, &db); 13935 if (result != ISC_R_SUCCESS) 13936 goto failure; 13937 13938 result = dns_db_newversion(db, &version); 13939 if (result != ISC_R_SUCCESS) 13940 goto failure; 13941 13942 result = dns_db_createiterator(rawdb, 0, &dbiterator); 13943 if (result != ISC_R_SUCCESS) 13944 goto failure; 13945 13946 for (result = dns_dbiterator_first(dbiterator); 13947 result == ISC_R_SUCCESS; 13948 result = dns_dbiterator_next(dbiterator)) { 13949 result = dns_dbiterator_current(dbiterator, &rawnode, name); 13950 if (result != ISC_R_SUCCESS) 13951 continue; 13952 13953 result = dns_db_findnode(db, name, ISC_TRUE, &node); 13954 if (result != ISC_R_SUCCESS) 13955 goto failure; 13956 13957 result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit); 13958 if (result != ISC_R_SUCCESS) 13959 goto failure; 13960 13961 for (result = dns_rdatasetiter_first(rdsit); 13962 result == ISC_R_SUCCESS; 13963 result = dns_rdatasetiter_next(rdsit)) { 13964 dns_rdatasetiter_current(rdsit, &rdataset); 13965 if (rdataset.type == dns_rdatatype_nsec || 13966 rdataset.type == dns_rdatatype_rrsig || 13967 rdataset.type == dns_rdatatype_nsec3 || 13968 rdataset.type == dns_rdatatype_dnskey || 13969 rdataset.type == dns_rdatatype_nsec3param) { 13970 dns_rdataset_disassociate(&rdataset); 13971 continue; 13972 } 13973 if (rdataset.type == dns_rdatatype_soa && 13974 have_oldserial) { 13975 result = checkandaddsoa(db, node, version, 13976 &rdataset, oldserial); 13977 } else 13978 result = dns_db_addrdataset(db, node, version, 13979 0, &rdataset, 0, 13980 NULL); 13981 if (result != ISC_R_SUCCESS) 13982 goto failure; 13983 13984 dns_rdataset_disassociate(&rdataset); 13985 } 13986 dns_rdatasetiter_destroy(&rdsit); 13987 dns_db_detachnode(rawdb, &rawnode); 13988 dns_db_detachnode(db, &node); 13989 } 13990 13991 /* 13992 * Call restore_nsec3param() to create private-type records from 13993 * the old nsec3 parameters and insert them into db 13994 */ 13995 if (!ISC_LIST_EMPTY(nsec3list)) 13996 restore_nsec3param(zone, db, version, &nsec3list); 13997 13998 dns_db_closeversion(db, &version, ISC_TRUE); 13999 14000 /* 14001 * Lock hierarchy: zmgr, zone, raw. 14002 */ 14003 INSIST(zone != zone->raw); 14004 LOCK_ZONE(zone->raw); 14005 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 14006 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 14007 zone_needdump(zone, 0); /* XXXMPA */ 14008 UNLOCK_ZONE(zone->raw); 14009 14010 failure: 14011 UNLOCK_ZONE(zone); 14012 if (result != ISC_R_SUCCESS) 14013 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s", 14014 dns_result_totext(result)); 14015 14016 while (!ISC_LIST_EMPTY(nsec3list)) { 14017 nsec3param_t *nsec3p; 14018 nsec3p = ISC_LIST_HEAD(nsec3list); 14019 ISC_LIST_UNLINK(nsec3list, nsec3p, link); 14020 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t)); 14021 } 14022 if (dns_rdataset_isassociated(&rdataset)) 14023 dns_rdataset_disassociate(&rdataset); 14024 if (db != NULL) { 14025 if (node != NULL) 14026 dns_db_detachnode(db, &node); 14027 if (version != NULL) 14028 dns_db_closeversion(db, &version, ISC_FALSE); 14029 dns_db_detach(&db); 14030 } 14031 if (rawnode != NULL) 14032 dns_db_detachnode(rawdb, &rawnode); 14033 dns_db_detach(&rawdb); 14034 if (dbiterator != NULL) 14035 dns_dbiterator_destroy(&dbiterator); 14036 dns_zone_idetach(&zone); 14037 14038 INSIST(version == NULL); 14039 } 14040 14041 static isc_result_t 14042 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) { 14043 isc_event_t *e; 14044 dns_db_t *dummy = NULL; 14045 dns_zone_t *secure = NULL; 14046 14047 e = isc_event_allocate(zone->secure->mctx, zone, 14048 DNS_EVENT_ZONESECUREDB, 14049 receive_secure_db, zone->secure, 14050 sizeof(struct secure_event)); 14051 if (e == NULL) 14052 return (ISC_R_NOMEMORY); 14053 dns_db_attach(db, &dummy); 14054 ((struct secure_event *)e)->db = dummy; 14055 INSIST(LOCKED_ZONE(zone->secure)); 14056 zone_iattach(zone->secure, &secure); 14057 isc_task_send(zone->secure->task, &e); 14058 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); 14059 return (ISC_R_SUCCESS); 14060 } 14061 14062 isc_result_t 14063 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { 14064 isc_result_t result; 14065 dns_zone_t *secure = NULL; 14066 14067 REQUIRE(DNS_ZONE_VALID(zone)); 14068 again: 14069 LOCK_ZONE(zone); 14070 if (inline_raw(zone)) { 14071 secure = zone->secure; 14072 INSIST(secure != zone); 14073 TRYLOCK_ZONE(result, secure); 14074 if (result != ISC_R_SUCCESS) { 14075 UNLOCK_ZONE(zone); 14076 secure = NULL; 14077 #if ISC_PLATFORM_USETHREADS 14078 isc_thread_yield(); 14079 #endif 14080 goto again; 14081 } 14082 } 14083 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 14084 result = zone_replacedb(zone, db, dump); 14085 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 14086 if (secure != NULL) 14087 UNLOCK_ZONE(secure); 14088 UNLOCK_ZONE(zone); 14089 return (result); 14090 } 14091 14092 static isc_result_t 14093 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { 14094 dns_dbversion_t *ver; 14095 isc_result_t result; 14096 unsigned int soacount = 0; 14097 unsigned int nscount = 0; 14098 14099 /* 14100 * 'zone' and 'zonedb' locked by caller. 14101 */ 14102 REQUIRE(DNS_ZONE_VALID(zone)); 14103 REQUIRE(LOCKED_ZONE(zone)); 14104 if (inline_raw(zone)) 14105 REQUIRE(LOCKED_ZONE(zone->secure)); 14106 14107 result = dns_db_rpz_ready(db); 14108 if (result != ISC_R_SUCCESS) 14109 return (result); 14110 14111 result = zone_get_from_db(zone, db, &nscount, &soacount, 14112 NULL, NULL, NULL, NULL, NULL, NULL); 14113 if (result == ISC_R_SUCCESS) { 14114 if (soacount != 1) { 14115 dns_zone_log(zone, ISC_LOG_ERROR, 14116 "has %d SOA records", soacount); 14117 result = DNS_R_BADZONE; 14118 } 14119 if (nscount == 0 && zone->type != dns_zone_key) { 14120 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records"); 14121 result = DNS_R_BADZONE; 14122 } 14123 if (result != ISC_R_SUCCESS) 14124 return (result); 14125 } else { 14126 dns_zone_log(zone, ISC_LOG_ERROR, 14127 "retrieving SOA and NS records failed: %s", 14128 dns_result_totext(result)); 14129 return (result); 14130 } 14131 14132 result = check_nsec3param(zone, db); 14133 if (result != ISC_R_SUCCESS) 14134 return (result); 14135 14136 ver = NULL; 14137 dns_db_currentversion(db, &ver); 14138 14139 /* 14140 * The initial version of a slave zone is always dumped; 14141 * subsequent versions may be journaled instead if this 14142 * is enabled in the configuration. 14143 */ 14144 if (zone->db != NULL && zone->journal != NULL && 14145 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 14146 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) 14147 { 14148 isc_uint32_t serial, oldserial; 14149 14150 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs"); 14151 14152 result = dns_db_getsoaserial(db, ver, &serial); 14153 if (result != ISC_R_SUCCESS) { 14154 dns_zone_log(zone, ISC_LOG_ERROR, 14155 "ixfr-from-differences: unable to get " 14156 "new serial"); 14157 goto fail; 14158 } 14159 14160 /* 14161 * This is checked in zone_postload() for master zones. 14162 */ 14163 result = zone_get_from_db(zone, zone->db, NULL, &soacount, 14164 &oldserial, NULL, NULL, NULL, NULL, 14165 NULL); 14166 RUNTIME_CHECK(result == ISC_R_SUCCESS); 14167 RUNTIME_CHECK(soacount > 0U); 14168 if ((zone->type == dns_zone_slave || 14169 (zone->type == dns_zone_redirect && 14170 zone->masters != NULL)) 14171 && !isc_serial_gt(serial, oldserial)) { 14172 isc_uint32_t serialmin, serialmax; 14173 serialmin = (oldserial + 1) & 0xffffffffU; 14174 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; 14175 dns_zone_log(zone, ISC_LOG_ERROR, 14176 "ixfr-from-differences: failed: " 14177 "new serial (%u) out of range [%u - %u]", 14178 serial, serialmin, serialmax); 14179 result = ISC_R_RANGE; 14180 goto fail; 14181 } 14182 14183 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL, 14184 zone->journal); 14185 if (result != ISC_R_SUCCESS) 14186 goto fail; 14187 if (dump) 14188 zone_needdump(zone, DNS_DUMP_DELAY); 14189 else if (zone->journalsize != -1) { 14190 result = dns_journal_compact(zone->mctx, zone->journal, 14191 serial, zone->journalsize); 14192 switch (result) { 14193 case ISC_R_SUCCESS: 14194 case ISC_R_NOSPACE: 14195 case ISC_R_NOTFOUND: 14196 dns_zone_log(zone, ISC_LOG_DEBUG(3), 14197 "dns_journal_compact: %s", 14198 dns_result_totext(result)); 14199 break; 14200 default: 14201 dns_zone_log(zone, ISC_LOG_ERROR, 14202 "dns_journal_compact failed: %s", 14203 dns_result_totext(result)); 14204 break; 14205 } 14206 } 14207 if (zone->type == dns_zone_master && inline_raw(zone)) 14208 zone_send_secureserial(zone, serial); 14209 } else { 14210 if (dump && zone->masterfile != NULL) { 14211 /* 14212 * If DNS_ZONEFLG_FORCEXFER was set we don't want 14213 * to keep the old masterfile. 14214 */ 14215 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) && 14216 remove(zone->masterfile) < 0 && errno != ENOENT) { 14217 char strbuf[ISC_STRERRORSIZE]; 14218 isc__strerror(errno, strbuf, sizeof(strbuf)); 14219 isc_log_write(dns_lctx, 14220 DNS_LOGCATEGORY_GENERAL, 14221 DNS_LOGMODULE_ZONE, 14222 ISC_LOG_WARNING, 14223 "unable to remove masterfile " 14224 "'%s': '%s'", 14225 zone->masterfile, strbuf); 14226 } 14227 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) 14228 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY); 14229 else 14230 zone_needdump(zone, 0); 14231 } 14232 if (dump && zone->journal != NULL) { 14233 /* 14234 * The in-memory database just changed, and 14235 * because 'dump' is set, it didn't change by 14236 * being loaded from disk. Also, we have not 14237 * journaled diffs for this change. 14238 * Therefore, the on-disk journal is missing 14239 * the deltas for this change. Since it can 14240 * no longer be used to bring the zone 14241 * up-to-date, it is useless and should be 14242 * removed. 14243 */ 14244 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 14245 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 14246 "removing journal file"); 14247 if (remove(zone->journal) < 0 && errno != ENOENT) { 14248 char strbuf[ISC_STRERRORSIZE]; 14249 isc__strerror(errno, strbuf, sizeof(strbuf)); 14250 isc_log_write(dns_lctx, 14251 DNS_LOGCATEGORY_GENERAL, 14252 DNS_LOGMODULE_ZONE, 14253 ISC_LOG_WARNING, 14254 "unable to remove journal " 14255 "'%s': '%s'", 14256 zone->journal, strbuf); 14257 } 14258 } 14259 14260 if (inline_raw(zone)) 14261 zone_send_securedb(zone, db); 14262 } 14263 14264 dns_db_closeversion(db, &ver, ISC_FALSE); 14265 14266 dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database"); 14267 14268 if (zone->db != NULL) 14269 zone_detachdb(zone); 14270 zone_attachdb(zone, db); 14271 dns_db_settask(zone->db, zone->task); 14272 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY); 14273 return (ISC_R_SUCCESS); 14274 14275 fail: 14276 dns_db_closeversion(db, &ver, ISC_FALSE); 14277 return (result); 14278 } 14279 14280 /* The caller must hold the dblock as a writer. */ 14281 static inline void 14282 zone_attachdb(dns_zone_t *zone, dns_db_t *db) { 14283 REQUIRE(zone->db == NULL && db != NULL); 14284 14285 dns_db_attach(db, &zone->db); 14286 if (zone->acache != NULL) { 14287 isc_result_t result; 14288 result = dns_acache_setdb(zone->acache, db); 14289 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { 14290 UNEXPECTED_ERROR(__FILE__, __LINE__, 14291 "dns_acache_setdb() failed: %s", 14292 isc_result_totext(result)); 14293 } 14294 } 14295 } 14296 14297 /* The caller must hold the dblock as a writer. */ 14298 static inline void 14299 zone_detachdb(dns_zone_t *zone) { 14300 REQUIRE(zone->db != NULL); 14301 14302 if (zone->acache != NULL) 14303 (void)dns_acache_putdb(zone->acache, zone->db); 14304 dns_db_detach(&zone->db); 14305 } 14306 14307 static void 14308 zone_xfrdone(dns_zone_t *zone, isc_result_t result) { 14309 isc_time_t now; 14310 isc_boolean_t again = ISC_FALSE; 14311 unsigned int soacount; 14312 unsigned int nscount; 14313 isc_uint32_t serial, refresh, retry, expire, minimum; 14314 isc_result_t xfrresult = result; 14315 isc_boolean_t free_needed; 14316 dns_zone_t *secure = NULL; 14317 14318 REQUIRE(DNS_ZONE_VALID(zone)); 14319 14320 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14321 "zone transfer finished: %s", dns_result_totext(result)); 14322 14323 /* 14324 * Obtaining a lock on the zone->secure (see zone_send_secureserial) 14325 * could result in a deadlock due to a LOR so we will spin if we 14326 * can't obtain the both locks. 14327 */ 14328 again: 14329 LOCK_ZONE(zone); 14330 if (inline_raw(zone)) { 14331 secure = zone->secure; 14332 INSIST(secure != zone); 14333 TRYLOCK_ZONE(result, secure); 14334 if (result != ISC_R_SUCCESS) { 14335 UNLOCK_ZONE(zone); 14336 secure = NULL; 14337 #if ISC_PLATFORM_USETHREADS 14338 isc_thread_yield(); 14339 #endif 14340 goto again; 14341 } 14342 } 14343 14344 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0); 14345 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 14346 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 14347 14348 TIME_NOW(&now); 14349 switch (result) { 14350 case ISC_R_SUCCESS: 14351 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 14352 /*FALLTHROUGH*/ 14353 case DNS_R_UPTODATE: 14354 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER); 14355 /* 14356 * Has the zone expired underneath us? 14357 */ 14358 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 14359 if (zone->db == NULL) { 14360 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 14361 goto same_master; 14362 } 14363 14364 /* 14365 * Update the zone structure's data from the actual 14366 * SOA received. 14367 */ 14368 nscount = 0; 14369 soacount = 0; 14370 INSIST(zone->db != NULL); 14371 result = zone_get_from_db(zone, zone->db, &nscount, 14372 &soacount, &serial, &refresh, 14373 &retry, &expire, &minimum, NULL); 14374 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 14375 if (result == ISC_R_SUCCESS) { 14376 if (soacount != 1) 14377 dns_zone_log(zone, ISC_LOG_ERROR, 14378 "transferred zone " 14379 "has %d SOA record%s", soacount, 14380 (soacount != 0) ? "s" : ""); 14381 if (nscount == 0) { 14382 dns_zone_log(zone, ISC_LOG_ERROR, 14383 "transferred zone " 14384 "has no NS records"); 14385 if (DNS_ZONE_FLAG(zone, 14386 DNS_ZONEFLG_HAVETIMERS)) { 14387 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 14388 zone->retry = DNS_ZONE_DEFAULTRETRY; 14389 } 14390 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 14391 zone_unload(zone); 14392 goto next_master; 14393 } 14394 zone->refresh = RANGE(refresh, zone->minrefresh, 14395 zone->maxrefresh); 14396 zone->retry = RANGE(retry, zone->minretry, 14397 zone->maxretry); 14398 zone->expire = RANGE(expire, 14399 zone->refresh + zone->retry, 14400 DNS_MAX_EXPIRE); 14401 zone->minimum = minimum; 14402 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 14403 } 14404 14405 /* 14406 * Set our next update/expire times. 14407 */ 14408 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 14409 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 14410 zone->refreshtime = now; 14411 DNS_ZONE_TIME_ADD(&now, zone->expire, 14412 &zone->expiretime); 14413 } else { 14414 DNS_ZONE_JITTER_ADD(&now, zone->refresh, 14415 &zone->refreshtime); 14416 DNS_ZONE_TIME_ADD(&now, zone->expire, 14417 &zone->expiretime); 14418 } 14419 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) { 14420 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")]; 14421 if (zone->tsigkey != NULL) { 14422 char namebuf[DNS_NAME_FORMATSIZE]; 14423 dns_name_format(&zone->tsigkey->name, namebuf, 14424 sizeof(namebuf)); 14425 snprintf(buf, sizeof(buf), ": TSIG '%s'", 14426 namebuf); 14427 } else 14428 buf[0] = '\0'; 14429 dns_zone_log(zone, ISC_LOG_INFO, 14430 "transferred serial %u%s", 14431 serial, buf); 14432 if (inline_raw(zone)) 14433 zone_send_secureserial(zone, serial); 14434 } 14435 14436 /* 14437 * This is not necessary if we just performed a AXFR 14438 * however it is necessary for an IXFR / UPTODATE and 14439 * won't hurt with an AXFR. 14440 */ 14441 if (zone->masterfile != NULL || zone->journal != NULL) { 14442 unsigned int delay = DNS_DUMP_DELAY; 14443 14444 result = ISC_R_FAILURE; 14445 if (zone->journal != NULL) 14446 result = isc_file_settime(zone->journal, &now); 14447 if (result != ISC_R_SUCCESS && 14448 zone->masterfile != NULL) 14449 result = isc_file_settime(zone->masterfile, 14450 &now); 14451 14452 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) || 14453 result == ISC_R_FILENOTFOUND) 14454 delay = 0; 14455 14456 if ((result == ISC_R_SUCCESS || 14457 result == ISC_R_FILENOTFOUND) && 14458 zone->masterfile != NULL) 14459 zone_needdump(zone, delay); 14460 else if (result != ISC_R_SUCCESS) 14461 dns_zone_log(zone, ISC_LOG_ERROR, 14462 "transfer: could not set file " 14463 "modification time of '%s': %s", 14464 zone->masterfile, 14465 dns_result_totext(result)); 14466 } 14467 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY); 14468 inc_stats(zone, dns_zonestatscounter_xfrsuccess); 14469 break; 14470 14471 case DNS_R_BADIXFR: 14472 /* Force retry with AXFR. */ 14473 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR); 14474 goto same_master; 14475 14476 default: 14477 next_master: 14478 /* 14479 * Skip to next failed / untried master. 14480 */ 14481 do { 14482 zone->curmaster++; 14483 } while (zone->curmaster < zone->masterscnt && 14484 zone->mastersok[zone->curmaster]); 14485 /* FALLTHROUGH */ 14486 same_master: 14487 if (zone->curmaster >= zone->masterscnt) { 14488 zone->curmaster = 0; 14489 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 14490 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 14491 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 14492 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 14493 while (zone->curmaster < zone->masterscnt && 14494 zone->mastersok[zone->curmaster]) 14495 zone->curmaster++; 14496 again = ISC_TRUE; 14497 } else 14498 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 14499 } else { 14500 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 14501 again = ISC_TRUE; 14502 } 14503 inc_stats(zone, dns_zonestatscounter_xfrfail); 14504 break; 14505 } 14506 zone_settimer(zone, &now); 14507 14508 /* 14509 * If creating the transfer object failed, zone->xfr is NULL. 14510 * Otherwise, we are called as the done callback of a zone 14511 * transfer object that just entered its shutting-down 14512 * state. Since we are no longer responsible for shutting 14513 * it down, we can detach our reference. 14514 */ 14515 if (zone->xfr != NULL) 14516 dns_xfrin_detach(&zone->xfr); 14517 14518 if (zone->tsigkey != NULL) 14519 dns_tsigkey_detach(&zone->tsigkey); 14520 14521 /* 14522 * Handle any deferred journal compaction. 14523 */ 14524 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) { 14525 result = dns_journal_compact(zone->mctx, zone->journal, 14526 zone->compact_serial, 14527 zone->journalsize); 14528 switch (result) { 14529 case ISC_R_SUCCESS: 14530 case ISC_R_NOSPACE: 14531 case ISC_R_NOTFOUND: 14532 dns_zone_log(zone, ISC_LOG_DEBUG(3), 14533 "dns_journal_compact: %s", 14534 dns_result_totext(result)); 14535 break; 14536 default: 14537 dns_zone_log(zone, ISC_LOG_ERROR, 14538 "dns_journal_compact failed: %s", 14539 dns_result_totext(result)); 14540 break; 14541 } 14542 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 14543 } 14544 14545 if (secure != NULL) 14546 UNLOCK_ZONE(secure); 14547 /* 14548 * This transfer finishing freed up a transfer quota slot. 14549 * Let any other zones waiting for quota have it. 14550 */ 14551 if (zone->zmgr != NULL && 14552 zone->statelist == &zone->zmgr->xfrin_in_progress) { 14553 UNLOCK_ZONE(zone); 14554 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 14555 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink); 14556 zone->statelist = NULL; 14557 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE); 14558 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 14559 LOCK_ZONE(zone); 14560 } 14561 14562 /* 14563 * Retry with a different server if necessary. 14564 */ 14565 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 14566 queue_soa_query(zone); 14567 14568 INSIST(zone->irefs > 0); 14569 zone->irefs--; 14570 free_needed = exit_check(zone); 14571 UNLOCK_ZONE(zone); 14572 if (free_needed) 14573 zone_free(zone); 14574 } 14575 14576 static void 14577 zone_loaddone(void *arg, isc_result_t result) { 14578 static char me[] = "zone_loaddone"; 14579 dns_load_t *load = arg; 14580 dns_zone_t *zone; 14581 isc_result_t tresult; 14582 dns_zone_t *secure = NULL; 14583 14584 REQUIRE(DNS_LOAD_VALID(load)); 14585 zone = load->zone; 14586 14587 ENTER; 14588 14589 tresult = dns_db_endload(load->db, &load->callbacks); 14590 if (tresult != ISC_R_SUCCESS && 14591 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)) 14592 result = tresult; 14593 14594 /* 14595 * Lock hierarchy: zmgr, zone, raw. 14596 */ 14597 again: 14598 LOCK_ZONE(zone); 14599 INSIST(zone != zone->raw); 14600 if (inline_secure(zone)) 14601 LOCK_ZONE(zone->raw); 14602 else if (inline_raw(zone)) { 14603 secure = zone->secure; 14604 TRYLOCK_ZONE(result, secure); 14605 if (result != ISC_R_SUCCESS) { 14606 UNLOCK_ZONE(zone); 14607 secure = NULL; 14608 #if ISC_PLATFORM_USETHREADS 14609 isc_thread_yield(); 14610 #endif 14611 goto again; 14612 } 14613 } 14614 (void)zone_postload(zone, load->db, load->loadtime, result); 14615 zonemgr_putio(&zone->readio); 14616 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING); 14617 zone_idetach(&load->callbacks.zone); 14618 /* 14619 * Leave the zone frozen if the reload fails. 14620 */ 14621 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) && 14622 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW)) 14623 zone->update_disabled = ISC_FALSE; 14624 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW); 14625 if (inline_secure(zone)) 14626 UNLOCK_ZONE(zone->raw); 14627 else if (secure != NULL) 14628 UNLOCK_ZONE(secure); 14629 UNLOCK_ZONE(zone); 14630 14631 load->magic = 0; 14632 dns_db_detach(&load->db); 14633 if (load->zone->lctx != NULL) 14634 dns_loadctx_detach(&load->zone->lctx); 14635 dns_zone_idetach(&load->zone); 14636 isc_mem_putanddetach(&load->mctx, load, sizeof(*load)); 14637 } 14638 14639 void 14640 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) { 14641 REQUIRE(DNS_ZONE_VALID(zone)); 14642 REQUIRE(table != NULL); 14643 REQUIRE(*table == NULL); 14644 14645 LOCK_ZONE(zone); 14646 if (zone->ssutable != NULL) 14647 dns_ssutable_attach(zone->ssutable, table); 14648 UNLOCK_ZONE(zone); 14649 } 14650 14651 void 14652 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) { 14653 REQUIRE(DNS_ZONE_VALID(zone)); 14654 14655 LOCK_ZONE(zone); 14656 if (zone->ssutable != NULL) 14657 dns_ssutable_detach(&zone->ssutable); 14658 if (table != NULL) 14659 dns_ssutable_attach(table, &zone->ssutable); 14660 UNLOCK_ZONE(zone); 14661 } 14662 14663 void 14664 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) { 14665 REQUIRE(DNS_ZONE_VALID(zone)); 14666 14667 zone->sigvalidityinterval = interval; 14668 } 14669 14670 isc_uint32_t 14671 dns_zone_getsigvalidityinterval(dns_zone_t *zone) { 14672 REQUIRE(DNS_ZONE_VALID(zone)); 14673 14674 return (zone->sigvalidityinterval); 14675 } 14676 14677 void 14678 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) { 14679 isc_time_t now; 14680 14681 REQUIRE(DNS_ZONE_VALID(zone)); 14682 14683 LOCK_ZONE(zone); 14684 zone->sigresigninginterval = interval; 14685 set_resigntime(zone); 14686 if (zone->task != NULL) { 14687 TIME_NOW(&now); 14688 zone_settimer(zone, &now); 14689 } 14690 UNLOCK_ZONE(zone); 14691 } 14692 14693 isc_uint32_t 14694 dns_zone_getsigresigninginterval(dns_zone_t *zone) { 14695 REQUIRE(DNS_ZONE_VALID(zone)); 14696 14697 return (zone->sigresigninginterval); 14698 } 14699 14700 static void 14701 queue_xfrin(dns_zone_t *zone) { 14702 const char me[] = "queue_xfrin"; 14703 isc_result_t result; 14704 dns_zonemgr_t *zmgr = zone->zmgr; 14705 14706 ENTER; 14707 14708 INSIST(zone->statelist == NULL); 14709 14710 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 14711 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink); 14712 LOCK_ZONE(zone); 14713 zone->irefs++; 14714 UNLOCK_ZONE(zone); 14715 zone->statelist = &zmgr->waiting_for_xfrin; 14716 result = zmgr_start_xfrin_ifquota(zmgr, zone); 14717 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 14718 14719 if (result == ISC_R_QUOTA) { 14720 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 14721 "zone transfer deferred due to quota"); 14722 } else if (result != ISC_R_SUCCESS) { 14723 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, 14724 "starting zone transfer: %s", 14725 isc_result_totext(result)); 14726 } 14727 } 14728 14729 /* 14730 * This event callback is called when a zone has received 14731 * any necessary zone transfer quota. This is the time 14732 * to go ahead and start the transfer. 14733 */ 14734 static void 14735 got_transfer_quota(isc_task_t *task, isc_event_t *event) { 14736 isc_result_t result = ISC_R_SUCCESS; 14737 dns_peer_t *peer = NULL; 14738 char master[ISC_SOCKADDR_FORMATSIZE]; 14739 char source[ISC_SOCKADDR_FORMATSIZE]; 14740 dns_rdatatype_t xfrtype; 14741 dns_zone_t *zone = event->ev_arg; 14742 isc_netaddr_t masterip; 14743 isc_sockaddr_t sourceaddr; 14744 isc_sockaddr_t masteraddr; 14745 isc_time_t now; 14746 const char *soa_before = ""; 14747 isc_dscp_t dscp = -1; 14748 isc_boolean_t loaded; 14749 14750 UNUSED(task); 14751 14752 INSIST(task == zone->task); 14753 14754 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 14755 result = ISC_R_CANCELED; 14756 goto cleanup; 14757 } 14758 14759 TIME_NOW(&now); 14760 14761 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 14762 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, 14763 &zone->sourceaddr, &now)) 14764 { 14765 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 14766 dns_zone_log(zone, ISC_LOG_INFO, 14767 "got_transfer_quota: skipping zone transfer as " 14768 "master %s (source %s) is unreachable (cached)", 14769 master, source); 14770 result = ISC_R_CANCELED; 14771 goto cleanup; 14772 } 14773 14774 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 14775 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer); 14776 14777 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) 14778 soa_before = "SOA before "; 14779 /* 14780 * Decide whether we should request IXFR or AXFR. 14781 */ 14782 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 14783 loaded = ISC_TF(zone->db != NULL); 14784 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 14785 14786 if (!loaded) { 14787 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14788 "no database exists yet, requesting AXFR of " 14789 "initial version from %s", master); 14790 xfrtype = dns_rdatatype_axfr; 14791 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { 14792 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14793 "forced reload, requesting AXFR of " 14794 "initial version from %s", master); 14795 xfrtype = dns_rdatatype_axfr; 14796 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) { 14797 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14798 "retrying with AXFR from %s due to " 14799 "previous IXFR failure", master); 14800 xfrtype = dns_rdatatype_axfr; 14801 LOCK_ZONE(zone); 14802 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR); 14803 UNLOCK_ZONE(zone); 14804 } else { 14805 isc_boolean_t use_ixfr = ISC_TRUE; 14806 if (peer != NULL) 14807 result = dns_peer_getrequestixfr(peer, &use_ixfr); 14808 if (peer == NULL || result != ISC_R_SUCCESS) 14809 use_ixfr = zone->requestixfr; 14810 if (use_ixfr == ISC_FALSE) { 14811 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14812 "IXFR disabled, requesting %sAXFR from %s", 14813 soa_before, master); 14814 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) 14815 xfrtype = dns_rdatatype_soa; 14816 else 14817 xfrtype = dns_rdatatype_axfr; 14818 } else { 14819 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14820 "requesting IXFR from %s", master); 14821 xfrtype = dns_rdatatype_ixfr; 14822 } 14823 } 14824 14825 /* 14826 * Determine if we should attempt to sign the request with TSIG. 14827 */ 14828 result = ISC_R_NOTFOUND; 14829 14830 /* 14831 * First, look for a tsig key in the master statement, then 14832 * try for a server key. 14833 */ 14834 if ((zone->masterkeynames != NULL) && 14835 (zone->masterkeynames[zone->curmaster] != NULL)) { 14836 dns_view_t *view = dns_zone_getview(zone); 14837 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 14838 result = dns_view_gettsig(view, keyname, &zone->tsigkey); 14839 } 14840 if (zone->tsigkey == NULL) 14841 result = dns_view_getpeertsig(zone->view, &masterip, 14842 &zone->tsigkey); 14843 14844 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 14845 dns_zone_log(zone, ISC_LOG_ERROR, 14846 "could not get TSIG key for zone transfer: %s", 14847 isc_result_totext(result)); 14848 } 14849 14850 if (zone->masterdscps != NULL) 14851 dscp = zone->masterdscps[zone->curmaster]; 14852 14853 LOCK_ZONE(zone); 14854 masteraddr = zone->masteraddr; 14855 sourceaddr = zone->sourceaddr; 14856 switch (isc_sockaddr_pf(&masteraddr)) { 14857 case PF_INET: 14858 if (dscp == -1) 14859 dscp = zone->xfrsource4dscp; 14860 break; 14861 case PF_INET6: 14862 if (dscp == -1) 14863 dscp = zone->xfrsource6dscp; 14864 break; 14865 default: 14866 INSIST(0); 14867 }; 14868 UNLOCK_ZONE(zone); 14869 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr)); 14870 result = dns_xfrin_create3(zone, xfrtype, &masteraddr, &sourceaddr, 14871 dscp, zone->tsigkey, zone->mctx, 14872 zone->zmgr->timermgr, zone->zmgr->socketmgr, 14873 zone->task, zone_xfrdone, &zone->xfr); 14874 if (result == ISC_R_SUCCESS) { 14875 LOCK_ZONE(zone); 14876 if (xfrtype == dns_rdatatype_axfr) { 14877 if (isc_sockaddr_pf(&masteraddr) == PF_INET) 14878 inc_stats(zone, dns_zonestatscounter_axfrreqv4); 14879 else 14880 inc_stats(zone, dns_zonestatscounter_axfrreqv6); 14881 } else if (xfrtype == dns_rdatatype_ixfr) { 14882 if (isc_sockaddr_pf(&masteraddr) == PF_INET) 14883 inc_stats(zone, dns_zonestatscounter_ixfrreqv4); 14884 else 14885 inc_stats(zone, dns_zonestatscounter_ixfrreqv6); 14886 } 14887 UNLOCK_ZONE(zone); 14888 } 14889 cleanup: 14890 /* 14891 * Any failure in this function is handled like a failed 14892 * zone transfer. This ensures that we get removed from 14893 * zmgr->xfrin_in_progress. 14894 */ 14895 if (result != ISC_R_SUCCESS) 14896 zone_xfrdone(zone, result); 14897 14898 isc_event_free(&event); 14899 } 14900 14901 /* 14902 * Update forwarding support. 14903 */ 14904 14905 static void 14906 forward_destroy(dns_forward_t *forward) { 14907 14908 forward->magic = 0; 14909 if (forward->request != NULL) 14910 dns_request_destroy(&forward->request); 14911 if (forward->msgbuf != NULL) 14912 isc_buffer_free(&forward->msgbuf); 14913 if (forward->zone != NULL) { 14914 LOCK(&forward->zone->lock); 14915 if (ISC_LINK_LINKED(forward, link)) 14916 ISC_LIST_UNLINK(forward->zone->forwards, forward, link); 14917 UNLOCK(&forward->zone->lock); 14918 dns_zone_idetach(&forward->zone); 14919 } 14920 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward)); 14921 } 14922 14923 static isc_result_t 14924 sendtomaster(dns_forward_t *forward) { 14925 isc_result_t result; 14926 isc_sockaddr_t src; 14927 isc_dscp_t dscp = -1; 14928 14929 LOCK_ZONE(forward->zone); 14930 14931 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) { 14932 UNLOCK_ZONE(forward->zone); 14933 return (ISC_R_CANCELED); 14934 } 14935 14936 if (forward->which >= forward->zone->masterscnt) { 14937 UNLOCK_ZONE(forward->zone); 14938 return (ISC_R_NOMORE); 14939 } 14940 14941 forward->addr = forward->zone->masters[forward->which]; 14942 /* 14943 * Always use TCP regardless of whether the original update 14944 * used TCP. 14945 * XXX The timeout may but a bit small if we are far down a 14946 * transfer graph and the master has to try several masters. 14947 */ 14948 switch (isc_sockaddr_pf(&forward->addr)) { 14949 case PF_INET: 14950 src = forward->zone->xfrsource4; 14951 dscp = forward->zone->xfrsource4dscp; 14952 break; 14953 case PF_INET6: 14954 src = forward->zone->xfrsource6; 14955 dscp = forward->zone->xfrsource6dscp; 14956 break; 14957 default: 14958 result = ISC_R_NOTIMPLEMENTED; 14959 goto unlock; 14960 } 14961 result = dns_request_createraw4(forward->zone->view->requestmgr, 14962 forward->msgbuf, 14963 &src, &forward->addr, dscp, 14964 forward->options, 15 /* XXX */, 14965 0, 0, forward->zone->task, 14966 forward_callback, forward, 14967 &forward->request); 14968 if (result == ISC_R_SUCCESS) { 14969 if (!ISC_LINK_LINKED(forward, link)) 14970 ISC_LIST_APPEND(forward->zone->forwards, forward, link); 14971 } 14972 14973 unlock: 14974 UNLOCK_ZONE(forward->zone); 14975 return (result); 14976 } 14977 14978 static void 14979 forward_callback(isc_task_t *task, isc_event_t *event) { 14980 const char me[] = "forward_callback"; 14981 dns_requestevent_t *revent = (dns_requestevent_t *)event; 14982 dns_message_t *msg = NULL; 14983 char master[ISC_SOCKADDR_FORMATSIZE]; 14984 isc_result_t result; 14985 dns_forward_t *forward; 14986 dns_zone_t *zone; 14987 14988 UNUSED(task); 14989 14990 forward = revent->ev_arg; 14991 INSIST(DNS_FORWARD_VALID(forward)); 14992 zone = forward->zone; 14993 INSIST(DNS_ZONE_VALID(zone)); 14994 14995 ENTER; 14996 14997 isc_sockaddr_format(&forward->addr, master, sizeof(master)); 14998 14999 if (revent->result != ISC_R_SUCCESS) { 15000 dns_zone_log(zone, ISC_LOG_INFO, 15001 "could not forward dynamic update to %s: %s", 15002 master, dns_result_totext(revent->result)); 15003 goto next_master; 15004 } 15005 15006 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 15007 if (result != ISC_R_SUCCESS) 15008 goto next_master; 15009 15010 result = dns_request_getresponse(revent->request, msg, 15011 DNS_MESSAGEPARSE_PRESERVEORDER | 15012 DNS_MESSAGEPARSE_CLONEBUFFER); 15013 if (result != ISC_R_SUCCESS) 15014 goto next_master; 15015 15016 switch (msg->rcode) { 15017 /* 15018 * Pass these rcodes back to client. 15019 */ 15020 case dns_rcode_noerror: 15021 case dns_rcode_yxdomain: 15022 case dns_rcode_yxrrset: 15023 case dns_rcode_nxrrset: 15024 case dns_rcode_refused: 15025 case dns_rcode_nxdomain: { 15026 char rcode[128]; 15027 isc_buffer_t rb; 15028 15029 isc_buffer_init(&rb, rcode, sizeof(rcode)); 15030 (void)dns_rcode_totext(msg->rcode, &rb); 15031 dns_zone_log(zone, ISC_LOG_INFO, 15032 "forwarded dynamic update: " 15033 "master %s returned: %.*s", 15034 master, (int)rb.used, rcode); 15035 break; 15036 } 15037 15038 /* These should not occur if the masters/zone are valid. */ 15039 case dns_rcode_notzone: 15040 case dns_rcode_notauth: { 15041 char rcode[128]; 15042 isc_buffer_t rb; 15043 15044 isc_buffer_init(&rb, rcode, sizeof(rcode)); 15045 (void)dns_rcode_totext(msg->rcode, &rb); 15046 dns_zone_log(zone, ISC_LOG_WARNING, 15047 "forwarding dynamic update: " 15048 "unexpected response: master %s returned: %.*s", 15049 master, (int)rb.used, rcode); 15050 goto next_master; 15051 } 15052 15053 /* Try another server for these rcodes. */ 15054 case dns_rcode_formerr: 15055 case dns_rcode_servfail: 15056 case dns_rcode_notimp: 15057 case dns_rcode_badvers: 15058 default: 15059 goto next_master; 15060 } 15061 15062 /* call callback */ 15063 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg); 15064 msg = NULL; 15065 dns_request_destroy(&forward->request); 15066 forward_destroy(forward); 15067 isc_event_free(&event); 15068 return; 15069 15070 next_master: 15071 if (msg != NULL) 15072 dns_message_destroy(&msg); 15073 isc_event_free(&event); 15074 forward->which++; 15075 dns_request_destroy(&forward->request); 15076 result = sendtomaster(forward); 15077 if (result != ISC_R_SUCCESS) { 15078 /* call callback */ 15079 dns_zone_log(zone, ISC_LOG_DEBUG(3), 15080 "exhausted dynamic update forwarder list"); 15081 (forward->callback)(forward->callback_arg, result, NULL); 15082 forward_destroy(forward); 15083 } 15084 } 15085 15086 isc_result_t 15087 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg, 15088 dns_updatecallback_t callback, void *callback_arg) 15089 { 15090 dns_forward_t *forward; 15091 isc_result_t result; 15092 isc_region_t *mr; 15093 15094 REQUIRE(DNS_ZONE_VALID(zone)); 15095 REQUIRE(msg != NULL); 15096 REQUIRE(callback != NULL); 15097 15098 forward = isc_mem_get(zone->mctx, sizeof(*forward)); 15099 if (forward == NULL) 15100 return (ISC_R_NOMEMORY); 15101 15102 forward->request = NULL; 15103 forward->zone = NULL; 15104 forward->msgbuf = NULL; 15105 forward->which = 0; 15106 forward->mctx = 0; 15107 forward->callback = callback; 15108 forward->callback_arg = callback_arg; 15109 ISC_LINK_INIT(forward, link); 15110 forward->magic = FORWARD_MAGIC; 15111 forward->options = DNS_REQUESTOPT_TCP; 15112 /* 15113 * If we have a SIG(0) signed message we need to preserve the 15114 * query id as that is included in the SIG(0) computation. 15115 */ 15116 if (msg->sig0 != NULL) 15117 forward->options |= DNS_REQUESTOPT_FIXEDID; 15118 15119 mr = dns_message_getrawmessage(msg); 15120 if (mr == NULL) { 15121 result = ISC_R_UNEXPECTEDEND; 15122 goto cleanup; 15123 } 15124 15125 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length); 15126 if (result != ISC_R_SUCCESS) 15127 goto cleanup; 15128 result = isc_buffer_copyregion(forward->msgbuf, mr); 15129 if (result != ISC_R_SUCCESS) 15130 goto cleanup; 15131 15132 isc_mem_attach(zone->mctx, &forward->mctx); 15133 dns_zone_iattach(zone, &forward->zone); 15134 result = sendtomaster(forward); 15135 15136 cleanup: 15137 if (result != ISC_R_SUCCESS) { 15138 forward_destroy(forward); 15139 } 15140 return (result); 15141 } 15142 15143 isc_result_t 15144 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) { 15145 REQUIRE(DNS_ZONE_VALID(zone)); 15146 REQUIRE(next != NULL && *next == NULL); 15147 15148 *next = ISC_LIST_NEXT(zone, link); 15149 if (*next == NULL) 15150 return (ISC_R_NOMORE); 15151 else 15152 return (ISC_R_SUCCESS); 15153 } 15154 15155 isc_result_t 15156 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) { 15157 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15158 REQUIRE(first != NULL && *first == NULL); 15159 15160 *first = ISC_LIST_HEAD(zmgr->zones); 15161 if (*first == NULL) 15162 return (ISC_R_NOMORE); 15163 else 15164 return (ISC_R_SUCCESS); 15165 } 15166 15167 /*** 15168 *** Zone manager. 15169 ***/ 15170 15171 isc_result_t 15172 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, 15173 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, 15174 dns_zonemgr_t **zmgrp) 15175 { 15176 dns_zonemgr_t *zmgr; 15177 isc_result_t result; 15178 15179 zmgr = isc_mem_get(mctx, sizeof(*zmgr)); 15180 if (zmgr == NULL) 15181 return (ISC_R_NOMEMORY); 15182 zmgr->mctx = NULL; 15183 zmgr->refs = 1; 15184 isc_mem_attach(mctx, &zmgr->mctx); 15185 zmgr->taskmgr = taskmgr; 15186 zmgr->timermgr = timermgr; 15187 zmgr->socketmgr = socketmgr; 15188 zmgr->zonetasks = NULL; 15189 zmgr->loadtasks = NULL; 15190 zmgr->mctxpool = NULL; 15191 zmgr->task = NULL; 15192 zmgr->notifyrl = NULL; 15193 zmgr->refreshrl = NULL; 15194 zmgr->startupnotifyrl = NULL; 15195 zmgr->startuprefreshrl = NULL; 15196 ISC_LIST_INIT(zmgr->zones); 15197 ISC_LIST_INIT(zmgr->waiting_for_xfrin); 15198 ISC_LIST_INIT(zmgr->xfrin_in_progress); 15199 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable)); 15200 result = isc_rwlock_init(&zmgr->rwlock, 0, 0); 15201 if (result != ISC_R_SUCCESS) 15202 goto free_mem; 15203 15204 zmgr->transfersin = 10; 15205 zmgr->transfersperns = 2; 15206 15207 /* Unreachable lock. */ 15208 result = isc_rwlock_init(&zmgr->urlock, 0, 0); 15209 if (result != ISC_R_SUCCESS) 15210 goto free_rwlock; 15211 15212 /* Create a single task for queueing of SOA queries. */ 15213 result = isc_task_create(taskmgr, 1, &zmgr->task); 15214 if (result != ISC_R_SUCCESS) 15215 goto free_urlock; 15216 15217 isc_task_setname(zmgr->task, "zmgr", zmgr); 15218 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 15219 &zmgr->notifyrl); 15220 if (result != ISC_R_SUCCESS) 15221 goto free_task; 15222 15223 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 15224 &zmgr->refreshrl); 15225 if (result != ISC_R_SUCCESS) 15226 goto free_notifyrl; 15227 15228 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 15229 &zmgr->startupnotifyrl); 15230 if (result != ISC_R_SUCCESS) 15231 goto free_refreshrl; 15232 15233 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 15234 &zmgr->startuprefreshrl); 15235 if (result != ISC_R_SUCCESS) 15236 goto free_startupnotifyrl; 15237 15238 /* default to 20 refresh queries / notifies per second. */ 15239 setrl(zmgr->notifyrl, &zmgr->notifyrate, 20); 15240 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20); 15241 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20); 15242 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20); 15243 15244 zmgr->iolimit = 1; 15245 zmgr->ioactive = 0; 15246 ISC_LIST_INIT(zmgr->high); 15247 ISC_LIST_INIT(zmgr->low); 15248 15249 result = isc_mutex_init(&zmgr->iolock); 15250 if (result != ISC_R_SUCCESS) 15251 goto free_startuprefreshrl; 15252 15253 zmgr->magic = ZONEMGR_MAGIC; 15254 15255 *zmgrp = zmgr; 15256 return (ISC_R_SUCCESS); 15257 15258 #if 0 15259 free_iolock: 15260 DESTROYLOCK(&zmgr->iolock); 15261 #endif 15262 free_startuprefreshrl: 15263 isc_ratelimiter_detach(&zmgr->startuprefreshrl); 15264 free_startupnotifyrl: 15265 isc_ratelimiter_detach(&zmgr->startupnotifyrl); 15266 free_refreshrl: 15267 isc_ratelimiter_detach(&zmgr->refreshrl); 15268 free_notifyrl: 15269 isc_ratelimiter_detach(&zmgr->notifyrl); 15270 free_task: 15271 isc_task_detach(&zmgr->task); 15272 free_urlock: 15273 isc_rwlock_destroy(&zmgr->urlock); 15274 free_rwlock: 15275 isc_rwlock_destroy(&zmgr->rwlock); 15276 free_mem: 15277 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); 15278 isc_mem_detach(&mctx); 15279 return (result); 15280 } 15281 15282 isc_result_t 15283 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) { 15284 isc_result_t result; 15285 isc_mem_t *mctx = NULL; 15286 dns_zone_t *zone = NULL; 15287 void *item; 15288 15289 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15290 REQUIRE(zonep != NULL && *zonep == NULL); 15291 15292 if (zmgr->mctxpool == NULL) 15293 return (ISC_R_FAILURE); 15294 15295 item = isc_pool_get(zmgr->mctxpool); 15296 if (item == NULL) 15297 return (ISC_R_FAILURE); 15298 15299 isc_mem_attach((isc_mem_t *) item, &mctx); 15300 result = dns_zone_create(&zone, mctx); 15301 isc_mem_detach(&mctx); 15302 15303 if (result == ISC_R_SUCCESS) 15304 *zonep = zone; 15305 15306 return (result); 15307 } 15308 15309 isc_result_t 15310 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 15311 isc_result_t result; 15312 15313 REQUIRE(DNS_ZONE_VALID(zone)); 15314 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15315 15316 if (zmgr->zonetasks == NULL) 15317 return (ISC_R_FAILURE); 15318 15319 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 15320 LOCK_ZONE(zone); 15321 REQUIRE(zone->task == NULL); 15322 REQUIRE(zone->timer == NULL); 15323 REQUIRE(zone->zmgr == NULL); 15324 15325 isc_taskpool_gettask(zmgr->zonetasks, &zone->task); 15326 isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask); 15327 15328 /* 15329 * Set the task name. The tag will arbitrarily point to one 15330 * of the zones sharing the task (in practice, the one 15331 * to be managed last). 15332 */ 15333 isc_task_setname(zone->task, "zone", zone); 15334 isc_task_setname(zone->loadtask, "loadzone", zone); 15335 15336 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, 15337 NULL, NULL, 15338 zone->task, zone_timer, zone, 15339 &zone->timer); 15340 15341 if (result != ISC_R_SUCCESS) 15342 goto cleanup_tasks; 15343 15344 /* 15345 * The timer "holds" a iref. 15346 */ 15347 zone->irefs++; 15348 INSIST(zone->irefs != 0); 15349 15350 ISC_LIST_APPEND(zmgr->zones, zone, link); 15351 zone->zmgr = zmgr; 15352 zmgr->refs++; 15353 15354 goto unlock; 15355 15356 cleanup_tasks: 15357 isc_task_detach(&zone->loadtask); 15358 isc_task_detach(&zone->task); 15359 15360 unlock: 15361 UNLOCK_ZONE(zone); 15362 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 15363 return (result); 15364 } 15365 15366 void 15367 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 15368 isc_boolean_t free_now = ISC_FALSE; 15369 15370 REQUIRE(DNS_ZONE_VALID(zone)); 15371 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15372 REQUIRE(zone->zmgr == zmgr); 15373 15374 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 15375 LOCK_ZONE(zone); 15376 15377 ISC_LIST_UNLINK(zmgr->zones, zone, link); 15378 zone->zmgr = NULL; 15379 zmgr->refs--; 15380 if (zmgr->refs == 0) 15381 free_now = ISC_TRUE; 15382 15383 UNLOCK_ZONE(zone); 15384 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 15385 15386 if (free_now) 15387 zonemgr_free(zmgr); 15388 ENSURE(zone->zmgr == NULL); 15389 } 15390 15391 void 15392 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) { 15393 REQUIRE(DNS_ZONEMGR_VALID(source)); 15394 REQUIRE(target != NULL && *target == NULL); 15395 15396 RWLOCK(&source->rwlock, isc_rwlocktype_write); 15397 REQUIRE(source->refs > 0); 15398 source->refs++; 15399 INSIST(source->refs > 0); 15400 RWUNLOCK(&source->rwlock, isc_rwlocktype_write); 15401 *target = source; 15402 } 15403 15404 void 15405 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) { 15406 dns_zonemgr_t *zmgr; 15407 isc_boolean_t free_now = ISC_FALSE; 15408 15409 REQUIRE(zmgrp != NULL); 15410 zmgr = *zmgrp; 15411 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15412 15413 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 15414 zmgr->refs--; 15415 if (zmgr->refs == 0) 15416 free_now = ISC_TRUE; 15417 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 15418 15419 if (free_now) 15420 zonemgr_free(zmgr); 15421 *zmgrp = NULL; 15422 } 15423 15424 isc_result_t 15425 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) { 15426 dns_zone_t *p; 15427 15428 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15429 15430 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 15431 for (p = ISC_LIST_HEAD(zmgr->zones); 15432 p != NULL; 15433 p = ISC_LIST_NEXT(p, link)) 15434 { 15435 dns_zone_maintenance(p); 15436 } 15437 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 15438 15439 /* 15440 * Recent configuration changes may have increased the 15441 * amount of available transfers quota. Make sure any 15442 * transfers currently blocked on quota get started if 15443 * possible. 15444 */ 15445 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 15446 zmgr_resume_xfrs(zmgr, ISC_TRUE); 15447 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 15448 return (ISC_R_SUCCESS); 15449 } 15450 15451 void 15452 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) { 15453 15454 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15455 15456 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 15457 zmgr_resume_xfrs(zmgr, ISC_TRUE); 15458 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 15459 } 15460 15461 void 15462 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) { 15463 dns_zone_t *zone; 15464 15465 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15466 15467 isc_ratelimiter_shutdown(zmgr->notifyrl); 15468 isc_ratelimiter_shutdown(zmgr->refreshrl); 15469 isc_ratelimiter_shutdown(zmgr->startupnotifyrl); 15470 isc_ratelimiter_shutdown(zmgr->startuprefreshrl); 15471 15472 if (zmgr->task != NULL) 15473 isc_task_destroy(&zmgr->task); 15474 if (zmgr->zonetasks != NULL) 15475 isc_taskpool_destroy(&zmgr->zonetasks); 15476 if (zmgr->loadtasks != NULL) 15477 isc_taskpool_destroy(&zmgr->loadtasks); 15478 if (zmgr->mctxpool != NULL) 15479 isc_pool_destroy(&zmgr->mctxpool); 15480 15481 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 15482 for (zone = ISC_LIST_HEAD(zmgr->zones); 15483 zone != NULL; 15484 zone = ISC_LIST_NEXT(zone, link)) 15485 { 15486 LOCK_ZONE(zone); 15487 forward_cancel(zone); 15488 UNLOCK_ZONE(zone); 15489 } 15490 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 15491 } 15492 15493 static isc_result_t 15494 mctxinit(void **target, void *arg) { 15495 isc_result_t result; 15496 isc_mem_t *mctx = NULL; 15497 15498 UNUSED(arg); 15499 15500 REQUIRE(target != NULL && *target == NULL); 15501 15502 result = isc_mem_create(0, 0, &mctx); 15503 if (result != ISC_R_SUCCESS) 15504 return (result); 15505 isc_mem_setname(mctx, "zonemgr-pool", NULL); 15506 15507 *target = mctx; 15508 return (ISC_R_SUCCESS); 15509 } 15510 15511 static void 15512 mctxfree(void **target) { 15513 isc_mem_t *mctx = *(isc_mem_t **) target; 15514 isc_mem_detach(&mctx); 15515 *target = NULL; 15516 } 15517 15518 #define ZONES_PER_TASK 100 15519 #define ZONES_PER_MCTX 1000 15520 15521 isc_result_t 15522 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) { 15523 isc_result_t result; 15524 int ntasks = num_zones / ZONES_PER_TASK; 15525 int nmctx = num_zones / ZONES_PER_MCTX; 15526 isc_taskpool_t *pool = NULL; 15527 isc_pool_t *mctxpool = NULL; 15528 15529 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15530 15531 /* 15532 * For anything fewer than 1000 zones we use 10 tasks in 15533 * the task pools. More than that, and we'll scale at one 15534 * task per 100 zones. Similarly, for anything smaller than 15535 * 2000 zones we use 2 memory contexts, then scale at 1:1000. 15536 */ 15537 if (ntasks < 10) 15538 ntasks = 10; 15539 if (nmctx < 2) 15540 nmctx = 2; 15541 15542 /* Create or resize the zone task pools. */ 15543 if (zmgr->zonetasks == NULL) 15544 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, 15545 ntasks, 2, &pool); 15546 else 15547 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool); 15548 15549 if (result == ISC_R_SUCCESS) 15550 zmgr->zonetasks = pool; 15551 15552 pool = NULL; 15553 if (zmgr->loadtasks == NULL) 15554 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, 15555 ntasks, 2, &pool); 15556 else 15557 result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool); 15558 15559 if (result == ISC_R_SUCCESS) 15560 zmgr->loadtasks = pool; 15561 15562 /* 15563 * We always set all tasks in the zone-load task pool to 15564 * privileged. This prevents other tasks in the system from 15565 * running while the server task manager is in privileged 15566 * mode. 15567 * 15568 * NOTE: If we start using task privileges for any other 15569 * part of the system than zone tasks, then this will need to be 15570 * revisted. In that case we'd want to turn on privileges for 15571 * zone tasks only when we were loading, and turn them off the 15572 * rest of the time. For now, however, it's okay to just 15573 * set it and forget it. 15574 */ 15575 isc_taskpool_setprivilege(zmgr->loadtasks, ISC_TRUE); 15576 15577 /* Create or resize the zone memory context pool. */ 15578 if (zmgr->mctxpool == NULL) 15579 result = isc_pool_create(zmgr->mctx, nmctx, mctxfree, 15580 mctxinit, NULL, &mctxpool); 15581 else 15582 result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool); 15583 15584 if (result == ISC_R_SUCCESS) 15585 zmgr->mctxpool = mctxpool; 15586 15587 return (result); 15588 } 15589 15590 static void 15591 zonemgr_free(dns_zonemgr_t *zmgr) { 15592 isc_mem_t *mctx; 15593 15594 INSIST(zmgr->refs == 0); 15595 INSIST(ISC_LIST_EMPTY(zmgr->zones)); 15596 15597 zmgr->magic = 0; 15598 15599 DESTROYLOCK(&zmgr->iolock); 15600 isc_ratelimiter_detach(&zmgr->notifyrl); 15601 isc_ratelimiter_detach(&zmgr->refreshrl); 15602 isc_ratelimiter_detach(&zmgr->startupnotifyrl); 15603 isc_ratelimiter_detach(&zmgr->startuprefreshrl); 15604 15605 isc_rwlock_destroy(&zmgr->urlock); 15606 isc_rwlock_destroy(&zmgr->rwlock); 15607 mctx = zmgr->mctx; 15608 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); 15609 isc_mem_detach(&mctx); 15610 } 15611 15612 void 15613 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) { 15614 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15615 15616 zmgr->transfersin = value; 15617 } 15618 15619 isc_uint32_t 15620 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) { 15621 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15622 15623 return (zmgr->transfersin); 15624 } 15625 15626 void 15627 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) { 15628 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15629 15630 zmgr->transfersperns = value; 15631 } 15632 15633 isc_uint32_t 15634 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) { 15635 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15636 15637 return (zmgr->transfersperns); 15638 } 15639 15640 /* 15641 * Try to start a new incoming zone transfer to fill a quota 15642 * slot that was just vacated. 15643 * 15644 * Requires: 15645 * The zone manager is locked by the caller. 15646 */ 15647 static void 15648 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) { 15649 dns_zone_t *zone; 15650 dns_zone_t *next; 15651 15652 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); 15653 zone != NULL; 15654 zone = next) 15655 { 15656 isc_result_t result; 15657 next = ISC_LIST_NEXT(zone, statelink); 15658 result = zmgr_start_xfrin_ifquota(zmgr, zone); 15659 if (result == ISC_R_SUCCESS) { 15660 if (multi) 15661 continue; 15662 /* 15663 * We successfully filled the slot. We're done. 15664 */ 15665 break; 15666 } else if (result == ISC_R_QUOTA) { 15667 /* 15668 * Not enough quota. This is probably the per-server 15669 * quota, because we usually get called when a unit of 15670 * global quota has just been freed. Try the next 15671 * zone, it may succeed if it uses another master. 15672 */ 15673 continue; 15674 } else { 15675 dns_zone_log(zone, ISC_LOG_DEBUG(1), 15676 "starting zone transfer: %s", 15677 isc_result_totext(result)); 15678 break; 15679 } 15680 } 15681 } 15682 15683 /* 15684 * Try to start an incoming zone transfer for 'zone', quota permitting. 15685 * 15686 * Requires: 15687 * The zone manager is locked by the caller. 15688 * 15689 * Returns: 15690 * ISC_R_SUCCESS There was enough quota and we attempted to 15691 * start a transfer. zone_xfrdone() has been or will 15692 * be called. 15693 * ISC_R_QUOTA Not enough quota. 15694 * Others Failure. 15695 */ 15696 static isc_result_t 15697 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 15698 dns_peer_t *peer = NULL; 15699 isc_netaddr_t masterip; 15700 isc_uint32_t nxfrsin, nxfrsperns; 15701 dns_zone_t *x; 15702 isc_uint32_t maxtransfersin, maxtransfersperns; 15703 isc_event_t *e; 15704 15705 /* 15706 * If we are exiting just pretend we got quota so the zone will 15707 * be cleaned up in the zone's task context. 15708 */ 15709 LOCK_ZONE(zone); 15710 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 15711 UNLOCK_ZONE(zone); 15712 goto gotquota; 15713 } 15714 15715 /* 15716 * Find any configured information about the server we'd 15717 * like to transfer this zone from. 15718 */ 15719 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 15720 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer); 15721 UNLOCK_ZONE(zone); 15722 15723 /* 15724 * Determine the total maximum number of simultaneous 15725 * transfers allowed, and the maximum for this specific 15726 * master. 15727 */ 15728 maxtransfersin = zmgr->transfersin; 15729 maxtransfersperns = zmgr->transfersperns; 15730 if (peer != NULL) 15731 (void)dns_peer_gettransfers(peer, &maxtransfersperns); 15732 15733 /* 15734 * Count the total number of transfers that are in progress, 15735 * and the number of transfers in progress from this master. 15736 * We linearly scan a list of all transfers; if this turns 15737 * out to be too slow, we could hash on the master address. 15738 */ 15739 nxfrsin = nxfrsperns = 0; 15740 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress); 15741 x != NULL; 15742 x = ISC_LIST_NEXT(x, statelink)) 15743 { 15744 isc_netaddr_t xip; 15745 15746 LOCK_ZONE(x); 15747 isc_netaddr_fromsockaddr(&xip, &x->masteraddr); 15748 UNLOCK_ZONE(x); 15749 15750 nxfrsin++; 15751 if (isc_netaddr_equal(&xip, &masterip)) 15752 nxfrsperns++; 15753 } 15754 15755 /* Enforce quota. */ 15756 if (nxfrsin >= maxtransfersin) 15757 return (ISC_R_QUOTA); 15758 15759 if (nxfrsperns >= maxtransfersperns) 15760 return (ISC_R_QUOTA); 15761 15762 gotquota: 15763 /* 15764 * We have sufficient quota. Move the zone to the "xfrin_in_progress" 15765 * list and send it an event to let it start the actual transfer in the 15766 * context of its own task. 15767 */ 15768 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN, 15769 got_transfer_quota, zone, sizeof(isc_event_t)); 15770 if (e == NULL) 15771 return (ISC_R_NOMEMORY); 15772 15773 LOCK_ZONE(zone); 15774 INSIST(zone->statelist == &zmgr->waiting_for_xfrin); 15775 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink); 15776 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink); 15777 zone->statelist = &zmgr->xfrin_in_progress; 15778 isc_task_send(zone->task, &e); 15779 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started."); 15780 UNLOCK_ZONE(zone); 15781 15782 return (ISC_R_SUCCESS); 15783 } 15784 15785 void 15786 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) { 15787 15788 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15789 REQUIRE(iolimit > 0); 15790 15791 zmgr->iolimit = iolimit; 15792 } 15793 15794 isc_uint32_t 15795 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) { 15796 15797 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15798 15799 return (zmgr->iolimit); 15800 } 15801 15802 /* 15803 * Get permission to request a file handle from the OS. 15804 * An event will be sent to action when one is available. 15805 * There are two queues available (high and low), the high 15806 * queue will be serviced before the low one. 15807 * 15808 * zonemgr_putio() must be called after the event is delivered to 15809 * 'action'. 15810 */ 15811 15812 static isc_result_t 15813 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high, 15814 isc_task_t *task, isc_taskaction_t action, void *arg, 15815 dns_io_t **iop) 15816 { 15817 dns_io_t *io; 15818 isc_boolean_t queue; 15819 15820 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 15821 REQUIRE(iop != NULL && *iop == NULL); 15822 15823 io = isc_mem_get(zmgr->mctx, sizeof(*io)); 15824 if (io == NULL) 15825 return (ISC_R_NOMEMORY); 15826 15827 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY, 15828 action, arg, sizeof(*io->event)); 15829 if (io->event == NULL) { 15830 isc_mem_put(zmgr->mctx, io, sizeof(*io)); 15831 return (ISC_R_NOMEMORY); 15832 } 15833 15834 io->zmgr = zmgr; 15835 io->high = high; 15836 io->task = NULL; 15837 isc_task_attach(task, &io->task); 15838 ISC_LINK_INIT(io, link); 15839 io->magic = IO_MAGIC; 15840 15841 LOCK(&zmgr->iolock); 15842 zmgr->ioactive++; 15843 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit); 15844 if (queue) { 15845 if (io->high) 15846 ISC_LIST_APPEND(zmgr->high, io, link); 15847 else 15848 ISC_LIST_APPEND(zmgr->low, io, link); 15849 } 15850 UNLOCK(&zmgr->iolock); 15851 *iop = io; 15852 15853 if (!queue) 15854 isc_task_send(io->task, &io->event); 15855 return (ISC_R_SUCCESS); 15856 } 15857 15858 static void 15859 zonemgr_putio(dns_io_t **iop) { 15860 dns_io_t *io; 15861 dns_io_t *next; 15862 dns_zonemgr_t *zmgr; 15863 15864 REQUIRE(iop != NULL); 15865 io = *iop; 15866 REQUIRE(DNS_IO_VALID(io)); 15867 15868 *iop = NULL; 15869 15870 INSIST(!ISC_LINK_LINKED(io, link)); 15871 INSIST(io->event == NULL); 15872 15873 zmgr = io->zmgr; 15874 isc_task_detach(&io->task); 15875 io->magic = 0; 15876 isc_mem_put(zmgr->mctx, io, sizeof(*io)); 15877 15878 LOCK(&zmgr->iolock); 15879 INSIST(zmgr->ioactive > 0); 15880 zmgr->ioactive--; 15881 next = HEAD(zmgr->high); 15882 if (next == NULL) 15883 next = HEAD(zmgr->low); 15884 if (next != NULL) { 15885 if (next->high) 15886 ISC_LIST_UNLINK(zmgr->high, next, link); 15887 else 15888 ISC_LIST_UNLINK(zmgr->low, next, link); 15889 INSIST(next->event != NULL); 15890 } 15891 UNLOCK(&zmgr->iolock); 15892 if (next != NULL) 15893 isc_task_send(next->task, &next->event); 15894 } 15895 15896 static void 15897 zonemgr_cancelio(dns_io_t *io) { 15898 isc_boolean_t send_event = ISC_FALSE; 15899 15900 REQUIRE(DNS_IO_VALID(io)); 15901 15902 /* 15903 * If we are queued to be run then dequeue. 15904 */ 15905 LOCK(&io->zmgr->iolock); 15906 if (ISC_LINK_LINKED(io, link)) { 15907 if (io->high) 15908 ISC_LIST_UNLINK(io->zmgr->high, io, link); 15909 else 15910 ISC_LIST_UNLINK(io->zmgr->low, io, link); 15911 15912 send_event = ISC_TRUE; 15913 INSIST(io->event != NULL); 15914 } 15915 UNLOCK(&io->zmgr->iolock); 15916 if (send_event) { 15917 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED; 15918 isc_task_send(io->task, &io->event); 15919 } 15920 } 15921 15922 static void 15923 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) { 15924 char *buf; 15925 int buflen; 15926 isc_result_t result; 15927 15928 buflen = strlen(path) + strlen(templat) + 2; 15929 15930 buf = isc_mem_get(zone->mctx, buflen); 15931 if (buf == NULL) 15932 return; 15933 15934 result = isc_file_template(path, templat, buf, buflen); 15935 if (result != ISC_R_SUCCESS) 15936 goto cleanup; 15937 15938 result = isc_file_renameunique(path, buf); 15939 if (result != ISC_R_SUCCESS) 15940 goto cleanup; 15941 15942 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; " 15943 "renaming file to '%s' for failure analysis and " 15944 "retransferring.", path, buf); 15945 15946 cleanup: 15947 isc_mem_put(zone->mctx, buf, buflen); 15948 } 15949 15950 #if 0 15951 /* Hook for ondestroy notification from a database. */ 15952 15953 static void 15954 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) { 15955 dns_db_t *db = event->sender; 15956 UNUSED(task); 15957 15958 isc_event_free(&event); 15959 15960 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 15961 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 15962 "database (%p) destroyed", (void*) db); 15963 } 15964 #endif 15965 15966 static void 15967 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) { 15968 isc_interval_t interval; 15969 isc_uint32_t s, ns; 15970 isc_uint32_t pertic; 15971 isc_result_t result; 15972 15973 if (value == 0) 15974 value = 1; 15975 15976 if (value == 1) { 15977 s = 1; 15978 ns = 0; 15979 pertic = 1; 15980 } else if (value <= 10) { 15981 s = 0; 15982 ns = 1000000000 / value; 15983 pertic = 1; 15984 } else { 15985 s = 0; 15986 ns = (1000000000 / value) * 10; 15987 pertic = 10; 15988 } 15989 15990 isc_interval_set(&interval, s, ns); 15991 15992 result = isc_ratelimiter_setinterval(rl, &interval); 15993 RUNTIME_CHECK(result == ISC_R_SUCCESS); 15994 isc_ratelimiter_setpertic(rl, pertic); 15995 15996 *rate = value; 15997 } 15998 15999 void 16000 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) { 16001 16002 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 16003 16004 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value); 16005 16006 /* Seperately controlled in BIND 9.11.x */ 16007 setrl(zmgr->notifyrl, &zmgr->notifyrate, 20); 16008 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20); 16009 16010 /* XXXMPA seperate out once we have the code to support this. */ 16011 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value); 16012 } 16013 16014 unsigned int 16015 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) { 16016 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 16017 16018 return (zmgr->serialqueryrate); 16019 } 16020 16021 isc_boolean_t 16022 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 16023 isc_sockaddr_t *local, isc_time_t *now) 16024 { 16025 unsigned int i; 16026 isc_rwlocktype_t locktype; 16027 isc_result_t result; 16028 isc_uint32_t seconds = isc_time_seconds(now); 16029 isc_uint32_t count = 0; 16030 16031 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 16032 16033 locktype = isc_rwlocktype_read; 16034 RWLOCK(&zmgr->urlock, locktype); 16035 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { 16036 if (zmgr->unreachable[i].expire >= seconds && 16037 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 16038 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) { 16039 result = isc_rwlock_tryupgrade(&zmgr->urlock); 16040 if (result == ISC_R_SUCCESS) { 16041 locktype = isc_rwlocktype_write; 16042 zmgr->unreachable[i].last = seconds; 16043 count = zmgr->unreachable[i].count; 16044 } 16045 break; 16046 } 16047 } 16048 RWUNLOCK(&zmgr->urlock, locktype); 16049 return (ISC_TF(i < UNREACH_CHACHE_SIZE && count > 1U)); 16050 } 16051 16052 void 16053 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 16054 isc_sockaddr_t *local) 16055 { 16056 unsigned int i; 16057 isc_rwlocktype_t locktype; 16058 isc_result_t result; 16059 16060 char master[ISC_SOCKADDR_FORMATSIZE]; 16061 char source[ISC_SOCKADDR_FORMATSIZE]; 16062 16063 isc_sockaddr_format(remote, master, sizeof(master)); 16064 isc_sockaddr_format(local, source, sizeof(source)); 16065 16066 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 16067 16068 locktype = isc_rwlocktype_read; 16069 RWLOCK(&zmgr->urlock, locktype); 16070 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { 16071 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 16072 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) { 16073 if (zmgr->unreachable[i].expire == 0) 16074 break; 16075 result = isc_rwlock_tryupgrade(&zmgr->urlock); 16076 if (result == ISC_R_SUCCESS) { 16077 locktype = isc_rwlocktype_write; 16078 zmgr->unreachable[i].expire = 0; 16079 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 16080 DNS_LOGMODULE_ZONE, ISC_LOG_INFO, 16081 "master %s (source %s) deleted " 16082 "from unreachable cache", 16083 master, source); 16084 } 16085 break; 16086 } 16087 } 16088 RWUNLOCK(&zmgr->urlock, locktype); 16089 } 16090 16091 void 16092 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 16093 isc_sockaddr_t *local, isc_time_t *now) 16094 { 16095 isc_uint32_t seconds = isc_time_seconds(now); 16096 isc_uint32_t last = seconds; 16097 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0; 16098 16099 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 16100 16101 RWLOCK(&zmgr->urlock, isc_rwlocktype_write); 16102 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { 16103 /* Existing entry? */ 16104 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 16105 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 16106 break; 16107 /* Empty slot? */ 16108 if (zmgr->unreachable[i].expire < seconds) 16109 slot = i; 16110 /* Least recently used slot? */ 16111 if (zmgr->unreachable[i].last < last) { 16112 last = zmgr->unreachable[i].last; 16113 oldest = i; 16114 } 16115 } 16116 if (i < UNREACH_CHACHE_SIZE) { 16117 /* 16118 * Found a existing entry. Update the expire timer and 16119 * last usage timestamps. 16120 */ 16121 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME; 16122 zmgr->unreachable[i].last = seconds; 16123 if (zmgr->unreachable[i].expire < seconds) 16124 zmgr->unreachable[i].count = 1; 16125 else 16126 zmgr->unreachable[i].count++; 16127 } else if (slot != UNREACH_CHACHE_SIZE) { 16128 /* 16129 * Found a empty slot. Add a new entry to the cache. 16130 */ 16131 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME; 16132 zmgr->unreachable[slot].last = seconds; 16133 zmgr->unreachable[slot].remote = *remote; 16134 zmgr->unreachable[slot].local = *local; 16135 zmgr->unreachable[slot].count = 1; 16136 } else { 16137 /* 16138 * Replace the least recently used entry in the cache. 16139 */ 16140 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME; 16141 zmgr->unreachable[oldest].last = seconds; 16142 zmgr->unreachable[oldest].remote = *remote; 16143 zmgr->unreachable[oldest].local = *local; 16144 zmgr->unreachable[oldest].count = 1; 16145 } 16146 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write); 16147 } 16148 16149 void 16150 dns_zone_forcereload(dns_zone_t *zone) { 16151 REQUIRE(DNS_ZONE_VALID(zone)); 16152 16153 if (zone->type == dns_zone_master || 16154 (zone->type == dns_zone_redirect && zone->masters == NULL)) 16155 return; 16156 16157 LOCK_ZONE(zone); 16158 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER); 16159 UNLOCK_ZONE(zone); 16160 dns_zone_refresh(zone); 16161 } 16162 16163 isc_boolean_t 16164 dns_zone_isforced(dns_zone_t *zone) { 16165 REQUIRE(DNS_ZONE_VALID(zone)); 16166 16167 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)); 16168 } 16169 16170 isc_result_t 16171 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) { 16172 /* 16173 * This function is obsoleted. 16174 */ 16175 UNUSED(zone); 16176 UNUSED(on); 16177 return (ISC_R_NOTIMPLEMENTED); 16178 } 16179 16180 isc_uint64_t * 16181 dns_zone_getstatscounters(dns_zone_t *zone) { 16182 /* 16183 * This function is obsoleted. 16184 */ 16185 UNUSED(zone); 16186 return (NULL); 16187 } 16188 16189 void 16190 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) { 16191 REQUIRE(DNS_ZONE_VALID(zone)); 16192 REQUIRE(zone->stats == NULL); 16193 16194 LOCK_ZONE(zone); 16195 zone->stats = NULL; 16196 isc_stats_attach(stats, &zone->stats); 16197 UNLOCK_ZONE(zone); 16198 } 16199 16200 void 16201 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) { 16202 16203 REQUIRE(DNS_ZONE_VALID(zone)); 16204 16205 LOCK_ZONE(zone); 16206 if (zone->requeststats_on && stats == NULL) 16207 zone->requeststats_on = ISC_FALSE; 16208 else if (!zone->requeststats_on && stats != NULL) { 16209 if (zone->requeststats == NULL) { 16210 isc_stats_attach(stats, &zone->requeststats); 16211 zone->requeststats_on = ISC_TRUE; 16212 } 16213 } 16214 UNLOCK_ZONE(zone); 16215 } 16216 16217 void 16218 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) { 16219 16220 REQUIRE(DNS_ZONE_VALID(zone)); 16221 16222 LOCK_ZONE(zone); 16223 if (zone->requeststats_on && stats != NULL) { 16224 if (zone->rcvquerystats == NULL) { 16225 dns_stats_attach(stats, &zone->rcvquerystats); 16226 zone->requeststats_on = ISC_TRUE; 16227 } 16228 } 16229 UNLOCK_ZONE(zone); 16230 } 16231 16232 isc_stats_t * 16233 dns_zone_getrequeststats(dns_zone_t *zone) { 16234 /* 16235 * We don't lock zone for efficiency reason. This is not catastrophic 16236 * because requeststats must always be valid when requeststats_on is 16237 * true. 16238 * Some counters may be incremented while requeststats_on is becoming 16239 * false, or some cannot be incremented just after the statistics are 16240 * installed, but it shouldn't matter much in practice. 16241 */ 16242 if (zone->requeststats_on) 16243 return (zone->requeststats); 16244 else 16245 return (NULL); 16246 } 16247 16248 /* 16249 * Return the received query stats bucket 16250 * see note from dns_zone_getrequeststats() 16251 */ 16252 dns_stats_t * 16253 dns_zone_getrcvquerystats(dns_zone_t *zone) { 16254 if (zone->requeststats_on) 16255 return (zone->rcvquerystats); 16256 else 16257 return (NULL); 16258 } 16259 16260 void 16261 dns_zone_dialup(dns_zone_t *zone) { 16262 16263 REQUIRE(DNS_ZONE_VALID(zone)); 16264 16265 zone_debuglog(zone, "dns_zone_dialup", 3, 16266 "notify = %d, refresh = %d", 16267 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY), 16268 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)); 16269 16270 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) 16271 dns_zone_notify(zone); 16272 if (zone->type != dns_zone_master && zone->masters != NULL && 16273 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 16274 dns_zone_refresh(zone); 16275 } 16276 16277 void 16278 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) { 16279 REQUIRE(DNS_ZONE_VALID(zone)); 16280 16281 LOCK_ZONE(zone); 16282 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY | 16283 DNS_ZONEFLG_DIALREFRESH | 16284 DNS_ZONEFLG_NOREFRESH); 16285 switch (dialup) { 16286 case dns_dialuptype_no: 16287 break; 16288 case dns_dialuptype_yes: 16289 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY | 16290 DNS_ZONEFLG_DIALREFRESH | 16291 DNS_ZONEFLG_NOREFRESH)); 16292 break; 16293 case dns_dialuptype_notify: 16294 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 16295 break; 16296 case dns_dialuptype_notifypassive: 16297 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 16298 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 16299 break; 16300 case dns_dialuptype_refresh: 16301 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH); 16302 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 16303 break; 16304 case dns_dialuptype_passive: 16305 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 16306 break; 16307 default: 16308 INSIST(0); 16309 } 16310 UNLOCK_ZONE(zone); 16311 } 16312 16313 isc_result_t 16314 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) { 16315 isc_result_t result = ISC_R_SUCCESS; 16316 16317 REQUIRE(DNS_ZONE_VALID(zone)); 16318 16319 LOCK_ZONE(zone); 16320 result = dns_zone_setstring(zone, &zone->keydirectory, directory); 16321 UNLOCK_ZONE(zone); 16322 16323 return (result); 16324 } 16325 16326 const char * 16327 dns_zone_getkeydirectory(dns_zone_t *zone) { 16328 REQUIRE(DNS_ZONE_VALID(zone)); 16329 16330 return (zone->keydirectory); 16331 } 16332 16333 unsigned int 16334 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) { 16335 dns_zone_t *zone; 16336 unsigned int count = 0; 16337 16338 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 16339 16340 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 16341 switch (state) { 16342 case DNS_ZONESTATE_XFERRUNNING: 16343 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress); 16344 zone != NULL; 16345 zone = ISC_LIST_NEXT(zone, statelink)) 16346 count++; 16347 break; 16348 case DNS_ZONESTATE_XFERDEFERRED: 16349 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); 16350 zone != NULL; 16351 zone = ISC_LIST_NEXT(zone, statelink)) 16352 count++; 16353 break; 16354 case DNS_ZONESTATE_SOAQUERY: 16355 for (zone = ISC_LIST_HEAD(zmgr->zones); 16356 zone != NULL; 16357 zone = ISC_LIST_NEXT(zone, link)) 16358 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) 16359 count++; 16360 break; 16361 case DNS_ZONESTATE_ANY: 16362 for (zone = ISC_LIST_HEAD(zmgr->zones); 16363 zone != NULL; 16364 zone = ISC_LIST_NEXT(zone, link)) { 16365 dns_view_t *view = zone->view; 16366 if (view != NULL && strcmp(view->name, "_bind") == 0) 16367 continue; 16368 count++; 16369 } 16370 break; 16371 default: 16372 INSIST(0); 16373 } 16374 16375 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 16376 16377 return (count); 16378 } 16379 16380 isc_result_t 16381 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) { 16382 isc_boolean_t ok = ISC_TRUE; 16383 isc_boolean_t fail = ISC_FALSE; 16384 char namebuf[DNS_NAME_FORMATSIZE]; 16385 char namebuf2[DNS_NAME_FORMATSIZE]; 16386 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 16387 int level = ISC_LOG_WARNING; 16388 dns_name_t bad; 16389 16390 REQUIRE(DNS_ZONE_VALID(zone)); 16391 16392 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) && 16393 rdata->type != dns_rdatatype_nsec3) 16394 return (ISC_R_SUCCESS); 16395 16396 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) || 16397 rdata->type == dns_rdatatype_nsec3) { 16398 level = ISC_LOG_ERROR; 16399 fail = ISC_TRUE; 16400 } 16401 16402 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE); 16403 if (!ok) { 16404 dns_name_format(name, namebuf, sizeof(namebuf)); 16405 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 16406 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf, 16407 dns_result_totext(DNS_R_BADOWNERNAME)); 16408 if (fail) 16409 return (DNS_R_BADOWNERNAME); 16410 } 16411 16412 dns_name_init(&bad, NULL); 16413 ok = dns_rdata_checknames(rdata, name, &bad); 16414 if (!ok) { 16415 dns_name_format(name, namebuf, sizeof(namebuf)); 16416 dns_name_format(&bad, namebuf2, sizeof(namebuf2)); 16417 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 16418 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf, 16419 namebuf2, dns_result_totext(DNS_R_BADNAME)); 16420 if (fail) 16421 return (DNS_R_BADNAME); 16422 } 16423 16424 return (ISC_R_SUCCESS); 16425 } 16426 16427 void 16428 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) { 16429 REQUIRE(DNS_ZONE_VALID(zone)); 16430 zone->checkmx = checkmx; 16431 } 16432 16433 void 16434 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) { 16435 REQUIRE(DNS_ZONE_VALID(zone)); 16436 zone->checksrv = checksrv; 16437 } 16438 16439 void 16440 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) { 16441 REQUIRE(DNS_ZONE_VALID(zone)); 16442 zone->checkns = checkns; 16443 } 16444 16445 void 16446 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) { 16447 REQUIRE(DNS_ZONE_VALID(zone)); 16448 16449 LOCK_ZONE(zone); 16450 zone->isself = isself; 16451 zone->isselfarg = arg; 16452 UNLOCK_ZONE(zone); 16453 } 16454 16455 void 16456 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) { 16457 REQUIRE(DNS_ZONE_VALID(zone)); 16458 16459 LOCK_ZONE(zone); 16460 zone->notifydelay = delay; 16461 UNLOCK_ZONE(zone); 16462 } 16463 16464 isc_uint32_t 16465 dns_zone_getnotifydelay(dns_zone_t *zone) { 16466 REQUIRE(DNS_ZONE_VALID(zone)); 16467 16468 return (zone->notifydelay); 16469 } 16470 16471 isc_result_t 16472 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, 16473 isc_uint16_t keyid, isc_boolean_t delete) 16474 { 16475 isc_result_t result; 16476 REQUIRE(DNS_ZONE_VALID(zone)); 16477 16478 dns_zone_log(zone, ISC_LOG_NOTICE, 16479 "dns_zone_signwithkey(algorithm=%u, keyid=%u)", 16480 algorithm, keyid); 16481 LOCK_ZONE(zone); 16482 result = zone_signwithkey(zone, algorithm, keyid, delete); 16483 UNLOCK_ZONE(zone); 16484 16485 return (result); 16486 } 16487 16488 static const char *hex = "0123456789ABCDEF"; 16489 16490 isc_result_t 16491 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 16492 isc_result_t result; 16493 char salt[255*2+1]; 16494 unsigned int i, j; 16495 16496 REQUIRE(DNS_ZONE_VALID(zone)); 16497 16498 if (nsec3param->salt_length != 0) { 16499 INSIST((nsec3param->salt_length * 2U) < sizeof(salt)); 16500 for (i = 0, j = 0; i < nsec3param->salt_length; i++) { 16501 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf]; 16502 salt[j++] = hex[nsec3param->salt[i] & 0xf]; 16503 } 16504 salt[j] = '\0'; 16505 } else 16506 strcpy(salt, "-"); 16507 dns_zone_log(zone, ISC_LOG_NOTICE, 16508 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)", 16509 nsec3param->hash, nsec3param->iterations, 16510 salt); 16511 LOCK_ZONE(zone); 16512 result = zone_addnsec3chain(zone, nsec3param); 16513 UNLOCK_ZONE(zone); 16514 16515 return (result); 16516 } 16517 16518 void 16519 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) { 16520 REQUIRE(DNS_ZONE_VALID(zone)); 16521 16522 if (nodes == 0) 16523 nodes = 1; 16524 zone->nodes = nodes; 16525 } 16526 16527 void 16528 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) { 16529 REQUIRE(DNS_ZONE_VALID(zone)); 16530 16531 /* 16532 * We treat signatures as a signed value so explicitly 16533 * limit its range here. 16534 */ 16535 if (signatures > ISC_INT32_MAX) 16536 signatures = ISC_INT32_MAX; 16537 else if (signatures == 0) 16538 signatures = 1; 16539 zone->signatures = signatures; 16540 } 16541 16542 void 16543 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) { 16544 REQUIRE(DNS_ZONE_VALID(zone)); 16545 zone->privatetype = type; 16546 } 16547 16548 dns_rdatatype_t 16549 dns_zone_getprivatetype(dns_zone_t *zone) { 16550 REQUIRE(DNS_ZONE_VALID(zone)); 16551 return (zone->privatetype); 16552 } 16553 16554 static isc_result_t 16555 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid, 16556 isc_boolean_t delete) 16557 { 16558 dns_signing_t *signing; 16559 dns_signing_t *current; 16560 isc_result_t result = ISC_R_SUCCESS; 16561 isc_time_t now; 16562 dns_db_t *db = NULL; 16563 16564 signing = isc_mem_get(zone->mctx, sizeof *signing); 16565 if (signing == NULL) 16566 return (ISC_R_NOMEMORY); 16567 16568 signing->magic = 0; 16569 signing->db = NULL; 16570 signing->dbiterator = NULL; 16571 signing->algorithm = algorithm; 16572 signing->keyid = keyid; 16573 signing->delete = delete; 16574 signing->done = ISC_FALSE; 16575 16576 TIME_NOW(&now); 16577 16578 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 16579 if (zone->db != NULL) 16580 dns_db_attach(zone->db, &db); 16581 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 16582 16583 if (db == NULL) { 16584 result = ISC_R_NOTFOUND; 16585 goto cleanup; 16586 } 16587 16588 dns_db_attach(db, &signing->db); 16589 16590 for (current = ISC_LIST_HEAD(zone->signing); 16591 current != NULL; 16592 current = ISC_LIST_NEXT(current, link)) { 16593 if (current->db == signing->db && 16594 current->algorithm == signing->algorithm && 16595 current->keyid == signing->keyid) { 16596 if (current->delete != signing->delete) 16597 current->done = ISC_TRUE; 16598 else 16599 goto cleanup; 16600 } 16601 } 16602 16603 result = dns_db_createiterator(signing->db, 0, 16604 &signing->dbiterator); 16605 16606 if (result == ISC_R_SUCCESS) 16607 result = dns_dbiterator_first(signing->dbiterator); 16608 if (result == ISC_R_SUCCESS) { 16609 dns_dbiterator_pause(signing->dbiterator); 16610 ISC_LIST_INITANDAPPEND(zone->signing, signing, link); 16611 signing = NULL; 16612 if (isc_time_isepoch(&zone->signingtime)) { 16613 zone->signingtime = now; 16614 if (zone->task != NULL) 16615 zone_settimer(zone, &now); 16616 } 16617 } 16618 16619 cleanup: 16620 if (signing != NULL) { 16621 if (signing->db != NULL) 16622 dns_db_detach(&signing->db); 16623 if (signing->dbiterator != NULL) 16624 dns_dbiterator_destroy(&signing->dbiterator); 16625 isc_mem_put(zone->mctx, signing, sizeof *signing); 16626 } 16627 if (db != NULL) 16628 dns_db_detach(&db); 16629 return (result); 16630 } 16631 16632 static void 16633 logmsg(const char *format, ...) { 16634 va_list args; 16635 va_start(args, format); 16636 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, 16637 ISC_LOG_DEBUG(1), format, args); 16638 va_end(args); 16639 } 16640 16641 static void 16642 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) { 16643 dns_dnsseckey_t *key; 16644 while (!ISC_LIST_EMPTY(*list)) { 16645 key = ISC_LIST_HEAD(*list); 16646 ISC_LIST_UNLINK(*list, key, link); 16647 dns_dnsseckey_destroy(mctx, &key); 16648 } 16649 } 16650 16651 /* Called once; *timep should be set to the current time. */ 16652 static isc_result_t 16653 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) { 16654 isc_result_t result; 16655 isc_stdtime_t now, then = 0, event; 16656 int i; 16657 16658 now = *timep; 16659 16660 for (i = 0; i <= DST_MAX_TIMES; i++) { 16661 result = dst_key_gettime(key, i, &event); 16662 if (result == ISC_R_SUCCESS && event > now && 16663 (then == 0 || event < then)) 16664 then = event; 16665 } 16666 16667 if (then != 0) { 16668 *timep = then; 16669 return (ISC_R_SUCCESS); 16670 } 16671 16672 return (ISC_R_NOTFOUND); 16673 } 16674 16675 static isc_result_t 16676 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 16677 const dns_rdata_t *rdata, isc_boolean_t *flag) 16678 { 16679 dns_rdataset_t rdataset; 16680 dns_dbnode_t *node = NULL; 16681 isc_result_t result; 16682 16683 dns_rdataset_init(&rdataset); 16684 if (rdata->type == dns_rdatatype_nsec3) 16685 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node)); 16686 else 16687 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); 16688 result = dns_db_findrdataset(db, node, ver, rdata->type, 0, 16689 (isc_stdtime_t) 0, &rdataset, NULL); 16690 if (result == ISC_R_NOTFOUND) { 16691 *flag = ISC_FALSE; 16692 result = ISC_R_SUCCESS; 16693 goto failure; 16694 } 16695 16696 for (result = dns_rdataset_first(&rdataset); 16697 result == ISC_R_SUCCESS; 16698 result = dns_rdataset_next(&rdataset)) { 16699 dns_rdata_t myrdata = DNS_RDATA_INIT; 16700 dns_rdataset_current(&rdataset, &myrdata); 16701 if (!dns_rdata_compare(&myrdata, rdata)) 16702 break; 16703 } 16704 dns_rdataset_disassociate(&rdataset); 16705 if (result == ISC_R_SUCCESS) { 16706 *flag = ISC_TRUE; 16707 } else if (result == ISC_R_NOMORE) { 16708 *flag = ISC_FALSE; 16709 result = ISC_R_SUCCESS; 16710 } 16711 16712 failure: 16713 if (node != NULL) 16714 dns_db_detachnode(db, &node); 16715 return (result); 16716 } 16717 16718 /* 16719 * Add records to signal the state of signing or of key removal. 16720 */ 16721 static isc_result_t 16722 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, 16723 dns_dbversion_t *ver, dns_diff_t *diff, 16724 isc_boolean_t sign_all) 16725 { 16726 dns_difftuple_t *tuple, *newtuple = NULL; 16727 dns_rdata_dnskey_t dnskey; 16728 dns_rdata_t rdata = DNS_RDATA_INIT; 16729 isc_boolean_t flag; 16730 isc_region_t r; 16731 isc_result_t result = ISC_R_SUCCESS; 16732 isc_uint16_t keyid; 16733 unsigned char buf[5]; 16734 dns_name_t *name = dns_db_origin(db); 16735 16736 for (tuple = ISC_LIST_HEAD(diff->tuples); 16737 tuple != NULL; 16738 tuple = ISC_LIST_NEXT(tuple, link)) { 16739 if (tuple->rdata.type != dns_rdatatype_dnskey) 16740 continue; 16741 16742 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL); 16743 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16744 if ((dnskey.flags & 16745 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH)) 16746 != DNS_KEYOWNER_ZONE) 16747 continue; 16748 16749 dns_rdata_toregion(&tuple->rdata, &r); 16750 16751 keyid = dst_region_computeid(&r, dnskey.algorithm); 16752 16753 buf[0] = dnskey.algorithm; 16754 buf[1] = (keyid & 0xff00) >> 8; 16755 buf[2] = (keyid & 0xff); 16756 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1; 16757 buf[4] = 0; 16758 rdata.data = buf; 16759 rdata.length = sizeof(buf); 16760 rdata.type = privatetype; 16761 rdata.rdclass = tuple->rdata.rdclass; 16762 16763 if (sign_all || tuple->op == DNS_DIFFOP_DEL) { 16764 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 16765 if (flag) 16766 continue; 16767 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, 16768 name, 0, &rdata, &newtuple)); 16769 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 16770 INSIST(newtuple == NULL); 16771 } 16772 16773 /* 16774 * Remove any record which says this operation has already 16775 * completed. 16776 */ 16777 buf[4] = 1; 16778 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 16779 if (flag) { 16780 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, 16781 name, 0, &rdata, &newtuple)); 16782 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 16783 INSIST(newtuple == NULL); 16784 } 16785 } 16786 failure: 16787 return (result); 16788 } 16789 16790 static isc_result_t 16791 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 16792 dns_diff_t *diff, zonediff_t *zonediff) 16793 { 16794 isc_result_t result; 16795 isc_stdtime_t now, inception, soaexpire; 16796 isc_boolean_t check_ksk, keyset_kskonly; 16797 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 16798 unsigned int nkeys = 0, i; 16799 dns_difftuple_t *tuple; 16800 16801 result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS, 16802 zone_keys, &nkeys); 16803 if (result != ISC_R_SUCCESS) { 16804 dns_zone_log(zone, ISC_LOG_ERROR, 16805 "sign_apex:find_zone_keys -> %s", 16806 dns_result_totext(result)); 16807 return (result); 16808 } 16809 16810 isc_stdtime_get(&now); 16811 inception = now - 3600; /* Allow for clock skew. */ 16812 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 16813 16814 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 16815 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 16816 16817 /* 16818 * See if update_sigs will update DNSKEY signature and if not 16819 * cause them to sign so that so that newly activated keys 16820 * are used. 16821 */ 16822 for (tuple = ISC_LIST_HEAD(diff->tuples); 16823 tuple != NULL; 16824 tuple = ISC_LIST_NEXT(tuple, link)) { 16825 if (tuple->rdata.type == dns_rdatatype_dnskey && 16826 dns_name_equal(&tuple->name, &zone->origin)) 16827 break; 16828 } 16829 16830 if (tuple == NULL) { 16831 result = del_sigs(zone, db, ver, &zone->origin, 16832 dns_rdatatype_dnskey, zonediff, 16833 zone_keys, nkeys, now, ISC_FALSE); 16834 if (result != ISC_R_SUCCESS) { 16835 dns_zone_log(zone, ISC_LOG_ERROR, 16836 "sign_apex:del_sigs -> %s", 16837 dns_result_totext(result)); 16838 goto failure; 16839 } 16840 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey, 16841 zonediff->diff, zone_keys, nkeys, zone->mctx, 16842 inception, soaexpire, check_ksk, 16843 keyset_kskonly); 16844 if (result != ISC_R_SUCCESS) { 16845 dns_zone_log(zone, ISC_LOG_ERROR, 16846 "sign_apex:add_sigs -> %s", 16847 dns_result_totext(result)); 16848 goto failure; 16849 } 16850 } 16851 16852 result = update_sigs(diff, db, ver, zone_keys, nkeys, zone, 16853 inception, soaexpire, now, check_ksk, 16854 keyset_kskonly, zonediff); 16855 16856 if (result != ISC_R_SUCCESS) { 16857 dns_zone_log(zone, ISC_LOG_ERROR, 16858 "sign_apex:update_sigs -> %s", 16859 dns_result_totext(result)); 16860 goto failure; 16861 } 16862 16863 failure: 16864 for (i = 0; i < nkeys; i++) 16865 dst_key_free(&zone_keys[i]); 16866 return (result); 16867 } 16868 16869 /* 16870 * Prevent the zone entering a inconsistent state where 16871 * NSEC only DNSKEYs are present with NSEC3 chains. 16872 * See update.c:check_dnssec() 16873 */ 16874 static isc_boolean_t 16875 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 16876 dns_diff_t *diff) 16877 { 16878 isc_result_t result; 16879 dns_difftuple_t *tuple; 16880 isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE; 16881 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); 16882 16883 /* Scan the tuples for an NSEC-only DNSKEY */ 16884 for (tuple = ISC_LIST_HEAD(diff->tuples); 16885 tuple != NULL; 16886 tuple = ISC_LIST_NEXT(tuple, link)) { 16887 isc_uint8_t alg; 16888 if (tuple->rdata.type != dns_rdatatype_dnskey || 16889 tuple->op != DNS_DIFFOP_ADD) 16890 continue; 16891 16892 alg = tuple->rdata.data[3]; 16893 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 || 16894 alg == DST_ALG_DSA || alg == DST_ALG_ECC) { 16895 nseconly = ISC_TRUE; 16896 break; 16897 } 16898 } 16899 16900 /* Check existing DB for NSEC-only DNSKEY */ 16901 if (!nseconly) { 16902 result = dns_nsec_nseconly(db, ver, &nseconly); 16903 if (result == ISC_R_NOTFOUND) 16904 result = ISC_R_SUCCESS; 16905 CHECK(result); 16906 } 16907 16908 /* Check existing DB for NSEC3 */ 16909 if (!nsec3) 16910 CHECK(dns_nsec3_activex(db, ver, ISC_FALSE, 16911 privatetype, &nsec3)); 16912 16913 /* Refuse to allow NSEC3 with NSEC-only keys */ 16914 if (nseconly && nsec3) { 16915 dns_zone_log(zone, ISC_LOG_ERROR, 16916 "NSEC only DNSKEYs and NSEC3 chains not allowed"); 16917 goto failure; 16918 } 16919 16920 return (ISC_TRUE); 16921 16922 failure: 16923 return (ISC_FALSE); 16924 } 16925 16926 static isc_result_t 16927 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 16928 dns_diff_t *diff) 16929 { 16930 isc_result_t result; 16931 dns_dbnode_t *node = NULL; 16932 dns_rdataset_t rdataset; 16933 16934 dns_rdataset_init(&rdataset); 16935 CHECK(dns_db_getoriginnode(db, &node)); 16936 16937 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 16938 dns_rdatatype_none, 0, &rdataset, NULL); 16939 if (dns_rdataset_isassociated(&rdataset)) 16940 dns_rdataset_disassociate(&rdataset); 16941 if (result != ISC_R_NOTFOUND) 16942 goto failure; 16943 16944 result = dns_nsec3param_deletechains(db, ver, zone, ISC_TRUE, diff); 16945 16946 failure: 16947 if (node != NULL) 16948 dns_db_detachnode(db, &node); 16949 return (result); 16950 } 16951 16952 /* 16953 * Given an RRSIG rdataset and an algorithm, determine whether there 16954 * are any signatures using that algorithm. 16955 */ 16956 static isc_boolean_t 16957 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) { 16958 dns_rdata_t rdata = DNS_RDATA_INIT; 16959 dns_rdata_rrsig_t rrsig; 16960 isc_result_t result; 16961 16962 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig); 16963 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) { 16964 return (ISC_FALSE); 16965 } 16966 16967 for (result = dns_rdataset_first(rdataset); 16968 result == ISC_R_SUCCESS; 16969 result = dns_rdataset_next(rdataset)) 16970 { 16971 dns_rdataset_current(rdataset, &rdata); 16972 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 16973 RUNTIME_CHECK(result == ISC_R_SUCCESS); 16974 dns_rdata_reset(&rdata); 16975 if (rrsig.algorithm == alg) 16976 return (ISC_TRUE); 16977 } 16978 16979 return (ISC_FALSE); 16980 } 16981 16982 static isc_result_t 16983 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 16984 dns_diff_t *diff) 16985 { 16986 dns_name_t *origin; 16987 isc_boolean_t build_nsec3; 16988 isc_result_t result; 16989 16990 origin = dns_db_origin(db); 16991 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL, 16992 &build_nsec3)); 16993 if (build_nsec3) 16994 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum, 16995 ISC_FALSE, zone->privatetype, diff)); 16996 CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff)); 16997 16998 failure: 16999 return (result); 17000 } 17001 17002 static void 17003 zone_rekey(dns_zone_t *zone) { 17004 isc_result_t result; 17005 dns_db_t *db = NULL; 17006 dns_dbnode_t *node = NULL; 17007 dns_dbversion_t *ver = NULL; 17008 dns_rdataset_t soaset, soasigs, keyset, keysigs; 17009 dns_dnsseckeylist_t dnskeys, keys, rmkeys; 17010 dns_dnsseckey_t *key; 17011 dns_diff_t diff, _sig_diff; 17012 zonediff_t zonediff; 17013 isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE; 17014 isc_boolean_t newalg = ISC_FALSE; 17015 isc_boolean_t fullsign; 17016 dns_ttl_t ttl = 3600; 17017 const char *dir; 17018 isc_mem_t *mctx; 17019 isc_stdtime_t now; 17020 isc_time_t timenow; 17021 isc_interval_t ival; 17022 char timebuf[80]; 17023 17024 REQUIRE(DNS_ZONE_VALID(zone)); 17025 17026 ISC_LIST_INIT(dnskeys); 17027 ISC_LIST_INIT(keys); 17028 ISC_LIST_INIT(rmkeys); 17029 dns_rdataset_init(&soaset); 17030 dns_rdataset_init(&soasigs); 17031 dns_rdataset_init(&keyset); 17032 dns_rdataset_init(&keysigs); 17033 dir = dns_zone_getkeydirectory(zone); 17034 mctx = zone->mctx; 17035 dns_diff_init(mctx, &diff); 17036 dns_diff_init(mctx, &_sig_diff); 17037 zonediff_init(&zonediff, &_sig_diff); 17038 17039 CHECK(dns_zone_getdb(zone, &db)); 17040 CHECK(dns_db_newversion(db, &ver)); 17041 CHECK(dns_db_getoriginnode(db, &node)); 17042 17043 TIME_NOW(&timenow); 17044 now = isc_time_seconds(&timenow); 17045 17046 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys"); 17047 17048 /* Get the SOA record's TTL */ 17049 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 17050 dns_rdatatype_none, 0, &soaset, &soasigs)); 17051 ttl = soaset.ttl; 17052 dns_rdataset_disassociate(&soaset); 17053 17054 /* Get the DNSKEY rdataset */ 17055 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 17056 dns_rdatatype_none, 0, &keyset, &keysigs); 17057 if (result == ISC_R_SUCCESS) { 17058 ttl = keyset.ttl; 17059 CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir, 17060 mctx, &keyset, 17061 &keysigs, &soasigs, 17062 ISC_FALSE, ISC_FALSE, 17063 &dnskeys)); 17064 } else if (result != ISC_R_NOTFOUND) 17065 goto failure; 17066 17067 /* 17068 * True when called from "rndc sign". Indicates the zone should be 17069 * fully signed now. 17070 */ 17071 fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0); 17072 17073 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys); 17074 if (result == ISC_R_SUCCESS) { 17075 isc_boolean_t check_ksk; 17076 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 17077 17078 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys, 17079 &zone->origin, ttl, &diff, 17080 ISC_TF(!check_ksk), 17081 mctx, logmsg); 17082 17083 /* Keys couldn't be updated for some reason; 17084 * try again later. */ 17085 if (result != ISC_R_SUCCESS) { 17086 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:" 17087 "couldn't update zone keys: %s", 17088 isc_result_totext(result)); 17089 goto failure; 17090 } 17091 17092 /* 17093 * See if any pre-existing keys have newly become active; 17094 * also, see if any new key is for a new algorithm, as in that 17095 * event, we need to sign the zone fully. (If there's a new 17096 * key, but it's for an already-existing algorithm, then 17097 * the zone signing can be handled incrementally.) 17098 */ 17099 for (key = ISC_LIST_HEAD(dnskeys); 17100 key != NULL; 17101 key = ISC_LIST_NEXT(key, link)) { 17102 if (!key->first_sign) 17103 continue; 17104 17105 newactive = ISC_TRUE; 17106 17107 if (!dns_rdataset_isassociated(&keysigs)) { 17108 newalg = ISC_TRUE; 17109 break; 17110 } 17111 17112 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) { 17113 /* 17114 * This isn't a new algorithm; clear 17115 * first_sign so we won't sign the 17116 * whole zone with this key later 17117 */ 17118 key->first_sign = ISC_FALSE; 17119 } else { 17120 newalg = ISC_TRUE; 17121 break; 17122 } 17123 } 17124 17125 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) && 17126 dnskey_sane(zone, db, ver, &diff)) { 17127 CHECK(dns_diff_apply(&diff, db, ver)); 17128 CHECK(clean_nsec3param(zone, db, ver, &diff)); 17129 CHECK(add_signing_records(db, zone->privatetype, 17130 ver, &diff, 17131 ISC_TF(newalg || fullsign))); 17132 CHECK(update_soa_serial(db, ver, &diff, mctx, 17133 zone->updatemethod)); 17134 CHECK(add_chains(zone, db, ver, &diff)); 17135 CHECK(sign_apex(zone, db, ver, &diff, &zonediff)); 17136 CHECK(zone_journal(zone, zonediff.diff, NULL, 17137 "zone_rekey")); 17138 commit = ISC_TRUE; 17139 } 17140 } 17141 17142 dns_db_closeversion(db, &ver, ISC_TRUE); 17143 17144 if (commit) { 17145 dns_difftuple_t *tuple; 17146 17147 LOCK_ZONE(zone); 17148 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 17149 17150 zone_needdump(zone, DNS_DUMP_DELAY); 17151 17152 zone_settimer(zone, &timenow); 17153 17154 /* Remove any signatures from removed keys. */ 17155 if (!ISC_LIST_EMPTY(rmkeys)) { 17156 for (key = ISC_LIST_HEAD(rmkeys); 17157 key != NULL; 17158 key = ISC_LIST_NEXT(key, link)) { 17159 result = zone_signwithkey(zone, 17160 dst_key_alg(key->key), 17161 dst_key_id(key->key), 17162 ISC_TRUE); 17163 if (result != ISC_R_SUCCESS) { 17164 dns_zone_log(zone, ISC_LOG_ERROR, 17165 "zone_signwithkey failed: %s", 17166 dns_result_totext(result)); 17167 } 17168 } 17169 } 17170 17171 if (fullsign) { 17172 /* 17173 * "rndc sign" was called, so we now sign the zone 17174 * with all active keys, whether they're new or not. 17175 */ 17176 for (key = ISC_LIST_HEAD(dnskeys); 17177 key != NULL; 17178 key = ISC_LIST_NEXT(key, link)) { 17179 if (!key->force_sign && !key->hint_sign) 17180 continue; 17181 17182 result = zone_signwithkey(zone, 17183 dst_key_alg(key->key), 17184 dst_key_id(key->key), 17185 ISC_FALSE); 17186 if (result != ISC_R_SUCCESS) { 17187 dns_zone_log(zone, ISC_LOG_ERROR, 17188 "zone_signwithkey failed: %s", 17189 dns_result_totext(result)); 17190 } 17191 } 17192 } else if (newalg) { 17193 /* 17194 * We haven't been told to sign fully, but a new 17195 * algorithm was added to the DNSKEY. We sign 17196 * the full zone, but only with newly active 17197 * keys. 17198 */ 17199 for (key = ISC_LIST_HEAD(dnskeys); 17200 key != NULL; 17201 key = ISC_LIST_NEXT(key, link)) { 17202 if (!key->first_sign) 17203 continue; 17204 17205 result = zone_signwithkey(zone, 17206 dst_key_alg(key->key), 17207 dst_key_id(key->key), 17208 ISC_FALSE); 17209 if (result != ISC_R_SUCCESS) { 17210 dns_zone_log(zone, ISC_LOG_ERROR, 17211 "zone_signwithkey failed: %s", 17212 dns_result_totext(result)); 17213 } 17214 } 17215 } 17216 17217 /* 17218 * Clear fullsign flag, if it was set, so we don't do 17219 * another full signing next time 17220 */ 17221 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN; 17222 17223 /* 17224 * Cause the zone to add/delete NSEC3 chains for the 17225 * deferred NSEC3PARAM changes. 17226 */ 17227 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples); 17228 tuple != NULL; 17229 tuple = ISC_LIST_NEXT(tuple, link)) { 17230 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 17231 dns_rdata_t rdata = DNS_RDATA_INIT; 17232 dns_rdata_nsec3param_t nsec3param; 17233 17234 if (tuple->rdata.type != zone->privatetype || 17235 tuple->op != DNS_DIFFOP_ADD) 17236 continue; 17237 17238 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata, 17239 buf, sizeof(buf))) 17240 continue; 17241 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 17242 RUNTIME_CHECK(result == ISC_R_SUCCESS); 17243 if (nsec3param.flags == 0) 17244 continue; 17245 17246 result = zone_addnsec3chain(zone, &nsec3param); 17247 if (result != ISC_R_SUCCESS) { 17248 dns_zone_log(zone, ISC_LOG_ERROR, 17249 "zone_addnsec3chain failed: %s", 17250 dns_result_totext(result)); 17251 } 17252 } 17253 17254 /* 17255 * Activate any NSEC3 chain updates that may have 17256 * been scheduled before this rekey. 17257 */ 17258 if (fullsign || newalg) 17259 resume_addnsec3chain(zone); 17260 17261 /* 17262 * Schedule the next resigning event 17263 */ 17264 set_resigntime(zone); 17265 UNLOCK_ZONE(zone); 17266 } 17267 17268 isc_time_settoepoch(&zone->refreshkeytime); 17269 17270 /* 17271 * If we're doing key maintenance, set the key refresh timer to 17272 * the next scheduled key event or to 'dnssec-loadkeys-interval' 17273 * seconds in the future, whichever is sooner. 17274 */ 17275 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) { 17276 isc_time_t timethen; 17277 isc_stdtime_t then; 17278 17279 LOCK_ZONE(zone); 17280 DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval, 17281 &timethen); 17282 zone->refreshkeytime = timethen; 17283 UNLOCK_ZONE(zone); 17284 17285 for (key = ISC_LIST_HEAD(dnskeys); 17286 key != NULL; 17287 key = ISC_LIST_NEXT(key, link)) { 17288 then = now; 17289 result = next_keyevent(key->key, &then); 17290 if (result != ISC_R_SUCCESS) 17291 continue; 17292 17293 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 17294 LOCK_ZONE(zone); 17295 if (isc_time_compare(&timethen, 17296 &zone->refreshkeytime) < 0) { 17297 zone->refreshkeytime = timethen; 17298 } 17299 UNLOCK_ZONE(zone); 17300 } 17301 17302 zone_settimer(zone, &timenow); 17303 17304 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 17305 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); 17306 } 17307 17308 done: 17309 dns_diff_clear(&diff); 17310 dns_diff_clear(&_sig_diff); 17311 17312 clear_keylist(&dnskeys, mctx); 17313 clear_keylist(&keys, mctx); 17314 clear_keylist(&rmkeys, mctx); 17315 17316 if (ver != NULL) 17317 dns_db_closeversion(db, &ver, ISC_FALSE); 17318 if (dns_rdataset_isassociated(&keyset)) 17319 dns_rdataset_disassociate(&keyset); 17320 if (dns_rdataset_isassociated(&keysigs)) 17321 dns_rdataset_disassociate(&keysigs); 17322 if (dns_rdataset_isassociated(&soasigs)) 17323 dns_rdataset_disassociate(&soasigs); 17324 if (node != NULL) 17325 dns_db_detachnode(db, &node); 17326 if (db != NULL) 17327 dns_db_detach(&db); 17328 17329 INSIST(ver == NULL); 17330 return; 17331 17332 failure: 17333 /* 17334 * Something went wrong; try again in ten minutes or 17335 * after a key refresh interval, whichever is shorter. 17336 */ 17337 isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 0); 17338 isc_time_nowplusinterval(&zone->refreshkeytime, &ival); 17339 goto done; 17340 } 17341 17342 void 17343 dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) { 17344 isc_time_t now; 17345 17346 if (zone->type == dns_zone_master && zone->task != NULL) { 17347 LOCK_ZONE(zone); 17348 17349 if (fullsign) 17350 zone->keyopts |= DNS_ZONEKEY_FULLSIGN; 17351 17352 TIME_NOW(&now); 17353 zone->refreshkeytime = now; 17354 zone_settimer(zone, &now); 17355 17356 UNLOCK_ZONE(zone); 17357 } 17358 } 17359 17360 isc_result_t 17361 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 17362 unsigned int *errors) 17363 { 17364 isc_result_t result; 17365 dns_dbnode_t *node = NULL; 17366 17367 REQUIRE(DNS_ZONE_VALID(zone)); 17368 REQUIRE(errors != NULL); 17369 17370 result = dns_db_getoriginnode(db, &node); 17371 if (result != ISC_R_SUCCESS) 17372 return (result); 17373 result = zone_count_ns_rr(zone, db, node, version, NULL, errors, 17374 ISC_FALSE); 17375 dns_db_detachnode(db, &node); 17376 return (result); 17377 } 17378 17379 void 17380 dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) { 17381 REQUIRE(DNS_ZONE_VALID(zone)); 17382 17383 LOCK_ZONE(zone); 17384 zone->added = added; 17385 UNLOCK_ZONE(zone); 17386 } 17387 17388 isc_boolean_t 17389 dns_zone_getadded(dns_zone_t *zone) { 17390 REQUIRE(DNS_ZONE_VALID(zone)); 17391 return (zone->added); 17392 } 17393 17394 isc_result_t 17395 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db) 17396 { 17397 isc_time_t loadtime; 17398 isc_result_t result; 17399 dns_zone_t *secure = NULL; 17400 17401 TIME_NOW(&loadtime); 17402 17403 /* 17404 * Lock hierarchy: zmgr, zone, raw. 17405 */ 17406 again: 17407 LOCK_ZONE(zone); 17408 INSIST(zone != zone->raw); 17409 if (inline_secure(zone)) 17410 LOCK_ZONE(zone->raw); 17411 else if (inline_raw(zone)) { 17412 secure = zone->secure; 17413 TRYLOCK_ZONE(result, secure); 17414 if (result != ISC_R_SUCCESS) { 17415 UNLOCK_ZONE(zone); 17416 secure = NULL; 17417 #if ISC_PLATFORM_USETHREADS 17418 isc_thread_yield(); 17419 #endif 17420 goto again; 17421 } 17422 } 17423 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 17424 if (inline_secure(zone)) 17425 UNLOCK_ZONE(zone->raw); 17426 else if (secure != NULL) 17427 UNLOCK_ZONE(secure); 17428 UNLOCK_ZONE(zone); 17429 return result; 17430 } 17431 17432 isc_result_t 17433 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval) { 17434 REQUIRE(DNS_ZONE_VALID(zone)); 17435 if (interval == 0) 17436 return (ISC_R_RANGE); 17437 /* Maximum value: 24 hours (3600 minutes) */ 17438 if (interval > (24 * 60)) 17439 interval = (24 * 60); 17440 /* Multiply by 60 for seconds */ 17441 zone->refreshkeyinterval = interval * 60; 17442 return (ISC_R_SUCCESS); 17443 } 17444 17445 void 17446 dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t flag) { 17447 REQUIRE(DNS_ZONE_VALID(zone)); 17448 zone->requestixfr = flag; 17449 } 17450 17451 isc_boolean_t 17452 dns_zone_getrequestixfr(dns_zone_t *zone) { 17453 REQUIRE(DNS_ZONE_VALID(zone)); 17454 return (zone->requestixfr); 17455 } 17456 17457 void 17458 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) { 17459 REQUIRE(DNS_ZONE_VALID(zone)); 17460 zone->updatemethod = method; 17461 } 17462 17463 dns_updatemethod_t 17464 dns_zone_getserialupdatemethod(dns_zone_t *zone) { 17465 REQUIRE(DNS_ZONE_VALID(zone)); 17466 return(zone->updatemethod); 17467 } 17468 17469 /* 17470 * Lock hierarchy: zmgr, zone, raw. 17471 */ 17472 isc_result_t 17473 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) { 17474 isc_result_t result; 17475 dns_zonemgr_t *zmgr; 17476 17477 REQUIRE(DNS_ZONE_VALID(zone)); 17478 REQUIRE(zone->zmgr != NULL); 17479 REQUIRE(zone->task != NULL); 17480 REQUIRE(zone->loadtask != NULL); 17481 REQUIRE(zone->raw == NULL); 17482 17483 REQUIRE(DNS_ZONE_VALID(raw)); 17484 REQUIRE(raw->zmgr == NULL); 17485 REQUIRE(raw->task == NULL); 17486 REQUIRE(raw->loadtask == NULL); 17487 REQUIRE(raw->secure == NULL); 17488 17489 REQUIRE(zone != raw); 17490 17491 /* 17492 * Lock hierarchy: zmgr, zone, raw. 17493 */ 17494 zmgr = zone->zmgr; 17495 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 17496 LOCK_ZONE(zone); 17497 LOCK_ZONE(raw); 17498 17499 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, 17500 NULL, NULL, zone->task, zone_timer, raw, 17501 &raw->timer); 17502 if (result != ISC_R_SUCCESS) 17503 goto unlock; 17504 17505 /* 17506 * The timer "holds" a iref. 17507 */ 17508 raw->irefs++; 17509 INSIST(raw->irefs != 0); 17510 17511 17512 /* dns_zone_attach(raw, &zone->raw); */ 17513 isc_refcount_increment(&raw->erefs, NULL); 17514 zone->raw = raw; 17515 17516 /* dns_zone_iattach(zone, &raw->secure); */ 17517 zone_iattach(zone, &raw->secure); 17518 17519 isc_task_attach(zone->task, &raw->task); 17520 isc_task_attach(zone->loadtask, &raw->loadtask); 17521 17522 ISC_LIST_APPEND(zmgr->zones, raw, link); 17523 raw->zmgr = zmgr; 17524 zmgr->refs++; 17525 17526 unlock: 17527 UNLOCK_ZONE(raw); 17528 UNLOCK_ZONE(zone); 17529 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 17530 return (result); 17531 } 17532 17533 void 17534 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) { 17535 REQUIRE(DNS_ZONE_VALID(zone)); 17536 REQUIRE(raw != NULL && *raw == NULL); 17537 17538 LOCK(&zone->lock); 17539 INSIST(zone != zone->raw); 17540 if (zone->raw != NULL) 17541 dns_zone_attach(zone->raw, raw); 17542 UNLOCK(&zone->lock); 17543 } 17544 17545 struct keydone { 17546 isc_event_t event; 17547 isc_boolean_t all; 17548 unsigned char data[5]; 17549 }; 17550 17551 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL) 17552 17553 static void 17554 keydone(isc_task_t *task, isc_event_t *event) { 17555 const char *me = "keydone"; 17556 isc_boolean_t commit = ISC_FALSE; 17557 isc_result_t result; 17558 dns_rdata_t rdata = DNS_RDATA_INIT; 17559 dns_dbversion_t *oldver = NULL, *newver = NULL; 17560 dns_zone_t *zone; 17561 dns_db_t *db = NULL; 17562 dns_dbnode_t *node = NULL; 17563 dns_rdataset_t rdataset; 17564 dns_diff_t diff; 17565 struct keydone *keydone = (struct keydone *)event; 17566 dns_update_log_t log = { update_log_cb, NULL }; 17567 isc_boolean_t clear_pending = ISC_FALSE; 17568 17569 UNUSED(task); 17570 17571 zone = event->ev_arg; 17572 INSIST(DNS_ZONE_VALID(zone)); 17573 17574 ENTER; 17575 17576 dns_rdataset_init(&rdataset); 17577 dns_diff_init(zone->mctx, &diff); 17578 17579 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 17580 if (zone->db != NULL) { 17581 dns_db_attach(zone->db, &db); 17582 dns_db_currentversion(db, &oldver); 17583 result = dns_db_newversion(db, &newver); 17584 if (result != ISC_R_SUCCESS) { 17585 dns_zone_log(zone, ISC_LOG_ERROR, 17586 "keydone:dns_db_newversion -> %s", 17587 dns_result_totext(result)); 17588 goto failure; 17589 } 17590 } 17591 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17592 if (db == NULL) 17593 goto failure; 17594 17595 result = dns_db_getoriginnode(db, &node); 17596 if (result != ISC_R_SUCCESS) 17597 goto failure; 17598 17599 result = dns_db_findrdataset(db, node, newver, zone->privatetype, 17600 dns_rdatatype_none, 0, &rdataset, NULL); 17601 if (result == ISC_R_NOTFOUND) { 17602 INSIST(!dns_rdataset_isassociated(&rdataset)); 17603 goto failure; 17604 } 17605 if (result != ISC_R_SUCCESS) { 17606 INSIST(!dns_rdataset_isassociated(&rdataset)); 17607 goto failure; 17608 } 17609 17610 for (result = dns_rdataset_first(&rdataset); 17611 result == ISC_R_SUCCESS; 17612 result = dns_rdataset_next(&rdataset)) { 17613 isc_boolean_t found = ISC_FALSE; 17614 17615 dns_rdataset_current(&rdataset, &rdata); 17616 17617 if (keydone->all) { 17618 if (rdata.length == 5 && rdata.data[0] != 0 && 17619 rdata.data[3] == 0 && rdata.data[4] == 1) 17620 found = ISC_TRUE; 17621 else if (rdata.data[0] == 0 && 17622 (rdata.data[2] & PENDINGFLAGS) != 0) { 17623 found = ISC_TRUE; 17624 clear_pending = ISC_TRUE; 17625 } 17626 } else if (rdata.length == 5 && 17627 memcmp(rdata.data, keydone->data, 5) == 0) 17628 found = ISC_TRUE; 17629 17630 if (found) 17631 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL, 17632 &zone->origin, rdataset.ttl, 17633 &rdata)); 17634 dns_rdata_reset(&rdata); 17635 } 17636 17637 if (!ISC_LIST_EMPTY(diff.tuples)) { 17638 /* Write changes to journal file. */ 17639 CHECK(update_soa_serial(db, newver, &diff, zone->mctx, 17640 zone->updatemethod)); 17641 17642 result = dns_update_signatures(&log, zone, db, 17643 oldver, newver, &diff, 17644 zone->sigvalidityinterval); 17645 if (!clear_pending) 17646 CHECK(result); 17647 17648 CHECK(zone_journal(zone, &diff, NULL, "keydone")); 17649 commit = ISC_TRUE; 17650 17651 LOCK_ZONE(zone); 17652 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 17653 zone_needdump(zone, 30); 17654 UNLOCK_ZONE(zone); 17655 } 17656 17657 failure: 17658 if (dns_rdataset_isassociated(&rdataset)) 17659 dns_rdataset_disassociate(&rdataset); 17660 if (db != NULL) { 17661 if (node != NULL) 17662 dns_db_detachnode(db, &node); 17663 if (oldver != NULL) 17664 dns_db_closeversion(db, &oldver, ISC_FALSE); 17665 if (newver != NULL) 17666 dns_db_closeversion(db, &newver, commit); 17667 dns_db_detach(&db); 17668 } 17669 dns_diff_clear(&diff); 17670 isc_event_free(&event); 17671 dns_zone_idetach(&zone); 17672 17673 INSIST(oldver == NULL); 17674 INSIST(newver == NULL); 17675 } 17676 17677 isc_result_t 17678 dns_zone_keydone(dns_zone_t *zone, const char *keystr) { 17679 isc_result_t result = ISC_R_SUCCESS; 17680 isc_event_t *e; 17681 isc_buffer_t b; 17682 dns_zone_t *dummy = NULL; 17683 struct keydone *kd; 17684 17685 REQUIRE(DNS_ZONE_VALID(zone)); 17686 17687 LOCK_ZONE(zone); 17688 17689 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone, 17690 zone, sizeof(struct keydone)); 17691 if (e == NULL) { 17692 result = ISC_R_NOMEMORY; 17693 goto failure; 17694 } 17695 17696 kd = (struct keydone *) e; 17697 if (strcasecmp(keystr, "all") == 0) 17698 kd->all = ISC_TRUE; 17699 else { 17700 isc_textregion_t r; 17701 char *algstr; 17702 dns_keytag_t keyid; 17703 dns_secalg_t alg; 17704 size_t n; 17705 17706 kd->all = ISC_FALSE; 17707 17708 n = sscanf(keystr, "%hd/", &keyid); 17709 if (n == 0U) 17710 CHECK(ISC_R_FAILURE); 17711 17712 algstr = strchr(keystr, '/'); 17713 if (algstr != NULL) 17714 algstr++; 17715 else 17716 CHECK(ISC_R_FAILURE); 17717 17718 n = sscanf(algstr, "%hhd", &alg); 17719 if (n == 0U) { 17720 DE_CONST(algstr, r.base); 17721 r.length = strlen(algstr); 17722 CHECK(dns_secalg_fromtext(&alg, &r)); 17723 } 17724 17725 /* construct a private-type rdata */ 17726 isc_buffer_init(&b, kd->data, sizeof(kd->data)); 17727 isc_buffer_putuint8(&b, alg); 17728 isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8); 17729 isc_buffer_putuint8(&b, (keyid & 0xff)); 17730 isc_buffer_putuint8(&b, 0); 17731 isc_buffer_putuint8(&b, 1); 17732 } 17733 17734 zone_iattach(zone, &dummy); 17735 isc_task_send(zone->task, &e); 17736 17737 failure: 17738 if (e != NULL) 17739 isc_event_free(&e); 17740 UNLOCK_ZONE(zone); 17741 return (result); 17742 } 17743 17744 static void 17745 setnsec3param(isc_task_t *task, isc_event_t *event) { 17746 const char *me = "setnsec3param"; 17747 isc_boolean_t commit = ISC_FALSE; 17748 isc_result_t result; 17749 dns_dbversion_t *oldver = NULL, *newver = NULL; 17750 dns_zone_t *zone; 17751 dns_db_t *db = NULL; 17752 dns_dbnode_t *node = NULL; 17753 dns_rdataset_t prdataset, nrdataset; 17754 dns_diff_t diff; 17755 struct np3event *npe = (struct np3event *)event; 17756 nsec3param_t *np; 17757 dns_update_log_t log = { update_log_cb, NULL }; 17758 dns_rdata_t rdata; 17759 isc_boolean_t nseconly; 17760 isc_boolean_t exists = ISC_FALSE; 17761 17762 UNUSED(task); 17763 17764 zone = event->ev_arg; 17765 INSIST(DNS_ZONE_VALID(zone)); 17766 17767 ENTER; 17768 17769 np = &npe->params; 17770 17771 dns_rdataset_init(&prdataset); 17772 dns_rdataset_init(&nrdataset); 17773 dns_diff_init(zone->mctx, &diff); 17774 17775 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 17776 if (zone->db != NULL) { 17777 dns_db_attach(zone->db, &db); 17778 dns_db_currentversion(db, &oldver); 17779 result = dns_db_newversion(db, &newver); 17780 if (result != ISC_R_SUCCESS) { 17781 dns_zone_log(zone, ISC_LOG_ERROR, 17782 "setnsec3param:dns_db_newversion -> %s", 17783 dns_result_totext(result)); 17784 goto failure; 17785 } 17786 } 17787 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 17788 if (db == NULL) 17789 goto failure; 17790 17791 CHECK(dns_db_getoriginnode(db, &node)); 17792 17793 /* 17794 * Does a private-type record already exist for this chain? 17795 */ 17796 result = dns_db_findrdataset(db, node, newver, zone->privatetype, 17797 dns_rdatatype_none, 0, &prdataset, NULL); 17798 if (result == ISC_R_SUCCESS) { 17799 for (result = dns_rdataset_first(&prdataset); 17800 result == ISC_R_SUCCESS; 17801 result = dns_rdataset_next(&prdataset)) { 17802 dns_rdata_init(&rdata); 17803 dns_rdataset_current(&prdataset, &rdata); 17804 17805 if (np->length == rdata.length && 17806 memcmp(rdata.data, np->data, np->length) == 0) { 17807 exists = ISC_TRUE; 17808 break; 17809 } 17810 } 17811 } else if (result != ISC_R_NOTFOUND) { 17812 INSIST(!dns_rdataset_isassociated(&prdataset)); 17813 goto failure; 17814 } 17815 17816 /* 17817 * Does the chain already exist? 17818 */ 17819 result = dns_db_findrdataset(db, node, newver, 17820 dns_rdatatype_nsec3param, 17821 dns_rdatatype_none, 0, &nrdataset, NULL); 17822 if (result == ISC_R_SUCCESS) { 17823 for (result = dns_rdataset_first(&nrdataset); 17824 result == ISC_R_SUCCESS; 17825 result = dns_rdataset_next(&nrdataset)) { 17826 dns_rdata_init(&rdata); 17827 dns_rdataset_current(&nrdataset, &rdata); 17828 17829 if (np->length == (rdata.length + 1) && 17830 memcmp(rdata.data, np->data + 1, 17831 np->length - 1) == 0) 17832 { 17833 exists = ISC_TRUE; 17834 break; 17835 } 17836 } 17837 } else if (result != ISC_R_NOTFOUND) { 17838 INSIST(!dns_rdataset_isassociated(&nrdataset)); 17839 goto failure; 17840 } 17841 17842 17843 /* 17844 * We need to remove any existing NSEC3 chains. 17845 */ 17846 if (!exists && np->replace && (np->length != 0 || np->nsec)) 17847 CHECK(dns_nsec3param_deletechains(db, newver, zone, 17848 !np->nsec, &diff)); 17849 17850 if (!exists && np->length != 0) { 17851 /* 17852 * We're creating an NSEC3 chain. 17853 * 17854 * If the zone is not currently capable of supporting 17855 * an NSEC3 chain, add the INITIAL flag, so these 17856 * parameters can be used later when NSEC3 becomes 17857 * available. 17858 */ 17859 dns_rdata_init(&rdata); 17860 17861 np->data[2] |= DNS_NSEC3FLAG_CREATE; 17862 result = dns_nsec_nseconly(db, newver, &nseconly); 17863 if (result == ISC_R_NOTFOUND || nseconly) 17864 np->data[2] |= DNS_NSEC3FLAG_INITIAL; 17865 17866 rdata.length = np->length; 17867 rdata.data = np->data; 17868 rdata.type = zone->privatetype; 17869 rdata.rdclass = zone->rdclass; 17870 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD, 17871 &zone->origin, 0, &rdata)); 17872 } 17873 17874 if (!ISC_LIST_EMPTY(diff.tuples)) { 17875 /* Write changes to journal file. */ 17876 CHECK(update_soa_serial(db, newver, &diff, zone->mctx, 17877 zone->updatemethod)); 17878 result = dns_update_signatures(&log, zone, db, 17879 oldver, newver, &diff, 17880 zone->sigvalidityinterval); 17881 if (result != ISC_R_NOTFOUND) 17882 CHECK(result); 17883 CHECK(zone_journal(zone, &diff, NULL, "setnsec3param")); 17884 commit = ISC_TRUE; 17885 17886 LOCK_ZONE(zone); 17887 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 17888 zone_needdump(zone, 30); 17889 UNLOCK_ZONE(zone); 17890 } 17891 17892 failure: 17893 if (dns_rdataset_isassociated(&prdataset)) 17894 dns_rdataset_disassociate(&prdataset); 17895 if (dns_rdataset_isassociated(&nrdataset)) 17896 dns_rdataset_disassociate(&nrdataset); 17897 if (node != NULL) 17898 dns_db_detachnode(db, &node); 17899 if (oldver != NULL) 17900 dns_db_closeversion(db, &oldver, ISC_FALSE); 17901 if (newver != NULL) 17902 dns_db_closeversion(db, &newver, commit); 17903 if (db != NULL) 17904 dns_db_detach(&db); 17905 if (commit) 17906 resume_addnsec3chain(zone); 17907 dns_diff_clear(&diff); 17908 isc_event_free(&event); 17909 dns_zone_idetach(&zone); 17910 17911 INSIST(oldver == NULL); 17912 INSIST(newver == NULL); 17913 } 17914 17915 isc_result_t 17916 dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags, 17917 isc_uint16_t iter, isc_uint8_t saltlen, 17918 unsigned char *salt, isc_boolean_t replace) 17919 { 17920 isc_result_t result = ISC_R_SUCCESS; 17921 dns_rdata_nsec3param_t param; 17922 dns_rdata_t nrdata = DNS_RDATA_INIT; 17923 dns_rdata_t prdata = DNS_RDATA_INIT; 17924 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE]; 17925 struct np3event *npe; 17926 nsec3param_t *np; 17927 dns_zone_t *dummy = NULL; 17928 isc_buffer_t b; 17929 isc_event_t *e; 17930 17931 REQUIRE(DNS_ZONE_VALID(zone)); 17932 REQUIRE(salt != NULL); 17933 17934 LOCK_ZONE(zone); 17935 17936 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM, 17937 setnsec3param, zone, sizeof(struct np3event)); 17938 if (e == NULL) { 17939 result = ISC_R_NOMEMORY; 17940 goto failure; 17941 } 17942 17943 npe = (struct np3event *) e; 17944 np = &npe->params; 17945 17946 np->replace = replace; 17947 if (hash == 0) { 17948 np->length = 0; 17949 np->nsec = ISC_TRUE; 17950 } else { 17951 param.common.rdclass = zone->rdclass; 17952 param.common.rdtype = dns_rdatatype_nsec3param; 17953 ISC_LINK_INIT(¶m.common, link); 17954 param.mctx = NULL; 17955 param.hash = hash; 17956 param.flags = flags; 17957 param.iterations = iter; 17958 param.salt_length = saltlen; 17959 param.salt = salt; 17960 isc_buffer_init(&b, nbuf, sizeof(nbuf)); 17961 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass, 17962 dns_rdatatype_nsec3param, 17963 ¶m, &b)); 17964 dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype, 17965 np->data, sizeof(np->data)); 17966 np->length = prdata.length; 17967 } 17968 17969 zone_iattach(zone, &dummy); 17970 isc_task_send(zone->task, &e); 17971 17972 failure: 17973 if (e != NULL) 17974 isc_event_free(&e); 17975 UNLOCK_ZONE(zone); 17976 return (result); 17977 } 17978 17979 isc_result_t 17980 dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) { 17981 REQUIRE(DNS_ZONE_VALID(zone)); 17982 REQUIRE(loadtime != NULL); 17983 17984 LOCK_ZONE(zone); 17985 *loadtime = zone->loadtime; 17986 UNLOCK_ZONE(zone); 17987 return (ISC_R_SUCCESS); 17988 } 17989 17990 isc_result_t 17991 dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) { 17992 REQUIRE(DNS_ZONE_VALID(zone)); 17993 REQUIRE(expiretime != NULL); 17994 17995 LOCK_ZONE(zone); 17996 *expiretime = zone->expiretime; 17997 UNLOCK_ZONE(zone); 17998 return (ISC_R_SUCCESS); 17999 } 18000 18001 isc_result_t 18002 dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) { 18003 REQUIRE(DNS_ZONE_VALID(zone)); 18004 REQUIRE(refreshtime != NULL); 18005 18006 LOCK_ZONE(zone); 18007 *refreshtime = zone->refreshtime; 18008 UNLOCK_ZONE(zone); 18009 return (ISC_R_SUCCESS); 18010 } 18011 18012 isc_result_t 18013 dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) { 18014 REQUIRE(DNS_ZONE_VALID(zone)); 18015 REQUIRE(refreshkeytime != NULL); 18016 18017 LOCK_ZONE(zone); 18018 *refreshkeytime = zone->refreshkeytime; 18019 UNLOCK_ZONE(zone); 18020 return (ISC_R_SUCCESS); 18021 } 18022 18023 unsigned int 18024 dns_zone_getincludes(dns_zone_t *zone, char ***includesp) { 18025 dns_include_t *include; 18026 char **array = NULL; 18027 unsigned int n = 0; 18028 18029 REQUIRE(DNS_ZONE_VALID(zone)); 18030 REQUIRE(includesp != NULL && *includesp == NULL); 18031 18032 LOCK_ZONE(zone); 18033 if (zone->nincludes == 0) 18034 goto done; 18035 18036 array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes); 18037 if (array == NULL) 18038 goto done; 18039 for (include = ISC_LIST_HEAD(zone->includes); 18040 include != NULL; 18041 include = ISC_LIST_NEXT(include, link)) { 18042 INSIST(n < zone->nincludes); 18043 array[n++] = isc_mem_strdup(zone->mctx, include->name); 18044 } 18045 INSIST(n == zone->nincludes); 18046 *includesp = array; 18047 18048 done: 18049 UNLOCK_ZONE(zone); 18050 return (n); 18051 } 18052 18053 void 18054 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) { 18055 REQUIRE(DNS_ZONE_VALID(zone)); 18056 18057 zone->statlevel = level; 18058 } 18059 18060 dns_zonestat_level_t 18061 dns_zone_getstatlevel(dns_zone_t *zone) { 18062 REQUIRE(DNS_ZONE_VALID(zone)); 18063 18064 return (zone->statlevel); 18065 } 18066