1/* $NetBSD: zone.c,v 1.4.4.3 2012/12/15 05:40:00 riz Exp $ */ 2 3/* 4 * Copyright (C) 2004-2012 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/* Id */ 21 22/*! \file */ 23 24#include <config.h> 25#include <errno.h> 26 27#include <isc/file.h> 28#include <isc/hex.h> 29#include <isc/mutex.h> 30#include <isc/print.h> 31#include <isc/random.h> 32#include <isc/ratelimiter.h> 33#include <isc/refcount.h> 34#include <isc/rwlock.h> 35#include <isc/serial.h> 36#include <isc/stats.h> 37#include <isc/stdtime.h> 38#include <isc/strerror.h> 39#include <isc/string.h> 40#include <isc/taskpool.h> 41#include <isc/timer.h> 42#include <isc/util.h> 43 44#include <dns/acache.h> 45#include <dns/acl.h> 46#include <dns/adb.h> 47#include <dns/callbacks.h> 48#include <dns/db.h> 49#include <dns/dbiterator.h> 50#include <dns/dnssec.h> 51#include <dns/events.h> 52#include <dns/journal.h> 53#include <dns/keydata.h> 54#include <dns/keytable.h> 55#include <dns/keyvalues.h> 56#include <dns/log.h> 57#include <dns/master.h> 58#include <dns/masterdump.h> 59#include <dns/message.h> 60#include <dns/name.h> 61#include <dns/nsec.h> 62#include <dns/nsec3.h> 63#include <dns/peer.h> 64#include <dns/private.h> 65#include <dns/rbt.h> 66#include <dns/rcode.h> 67#include <dns/rdata.h> 68#include <dns/rdataclass.h> 69#include <dns/rdatalist.h> 70#include <dns/rdataset.h> 71#include <dns/rdatasetiter.h> 72#include <dns/rdatastruct.h> 73#include <dns/rdatatype.h> 74#include <dns/request.h> 75#include <dns/resolver.h> 76#include <dns/result.h> 77#include <dns/rriterator.h> 78#include <dns/soa.h> 79#include <dns/ssu.h> 80#include <dns/stats.h> 81#include <dns/time.h> 82#include <dns/tsig.h> 83#include <dns/update.h> 84#include <dns/xfrin.h> 85#include <dns/zone.h> 86#include <dns/zt.h> 87 88#include <dst/dst.h> 89 90#define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E') 91#define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC) 92 93#define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y') 94#define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC) 95 96#define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b') 97#define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC) 98 99#define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r') 100#define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC) 101 102#define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd') 103#define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC) 104 105#define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w') 106#define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC) 107 108#define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O') 109#define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC) 110 111/*% 112 * Ensure 'a' is at least 'min' but not more than 'max'. 113 */ 114#define RANGE(a, min, max) \ 115 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max))) 116 117#define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) 118 119/*% 120 * Key flags 121 */ 122#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0) 123#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0) 124#define ALG(x) dst_key_alg(x) 125 126/* 127 * Default values. 128 */ 129#define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */ 130#define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */ 131#define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */ 132#define RESIGN_DELAY 3600 /*%< 1 hour */ 133 134#ifndef DNS_MAX_EXPIRE 135#define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */ 136#endif 137 138#ifndef DNS_DUMP_DELAY 139#define DNS_DUMP_DELAY 900 /*%< 15 minutes */ 140#endif 141 142typedef struct dns_notify dns_notify_t; 143typedef struct dns_stub dns_stub_t; 144typedef struct dns_load dns_load_t; 145typedef struct dns_forward dns_forward_t; 146typedef ISC_LIST(dns_forward_t) dns_forwardlist_t; 147typedef struct dns_io dns_io_t; 148typedef ISC_LIST(dns_io_t) dns_iolist_t; 149typedef struct dns_signing dns_signing_t; 150typedef ISC_LIST(dns_signing_t) dns_signinglist_t; 151typedef struct dns_nsec3chain dns_nsec3chain_t; 152typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t; 153typedef struct dns_keyfetch dns_keyfetch_t; 154typedef struct dns_asyncload dns_asyncload_t; 155 156#define DNS_ZONE_CHECKLOCK 157#ifdef DNS_ZONE_CHECKLOCK 158#define LOCK_ZONE(z) \ 159 do { LOCK(&(z)->lock); \ 160 INSIST((z)->locked == ISC_FALSE); \ 161 (z)->locked = ISC_TRUE; \ 162 } while (/*CONSTCOND*/0) 163#define UNLOCK_ZONE(z) \ 164 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (/*CONSTCOND*/0) 165#define LOCKED_ZONE(z) ((z)->locked) 166#else 167#define LOCK_ZONE(z) LOCK(&(z)->lock) 168#define UNLOCK_ZONE(z) UNLOCK(&(z)->lock) 169#define LOCKED_ZONE(z) ISC_TRUE 170#endif 171 172#ifdef ISC_RWLOCK_USEATOMIC 173#define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0) 174#define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l) 175#define ZONEDB_LOCK(l, t) RWLOCK((l), (t)) 176#define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t)) 177#else 178#define ZONEDB_INITLOCK(l) isc_mutex_init(l) 179#define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l) 180#define ZONEDB_LOCK(l, t) LOCK(l) 181#define ZONEDB_UNLOCK(l, t) UNLOCK(l) 182#endif 183 184struct dns_zone { 185 /* Unlocked */ 186 unsigned int magic; 187 isc_mutex_t lock; 188#ifdef DNS_ZONE_CHECKLOCK 189 isc_boolean_t locked; 190#endif 191 isc_mem_t *mctx; 192 isc_refcount_t erefs; 193 194#ifdef ISC_RWLOCK_USEATOMIC 195 isc_rwlock_t dblock; 196#else 197 isc_mutex_t dblock; 198#endif 199 dns_db_t *db; /* Locked by dblock */ 200 201 /* Locked */ 202 dns_zonemgr_t *zmgr; 203 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */ 204 isc_timer_t *timer; 205 unsigned int irefs; 206 dns_name_t origin; 207 char *masterfile; 208 dns_masterformat_t masterformat; 209 char *journal; 210 isc_int32_t journalsize; 211 dns_rdataclass_t rdclass; 212 dns_zonetype_t type; 213 unsigned int flags; 214 unsigned int options; 215 unsigned int db_argc; 216 char **db_argv; 217 isc_time_t expiretime; 218 isc_time_t refreshtime; 219 isc_time_t dumptime; 220 isc_time_t loadtime; 221 isc_time_t notifytime; 222 isc_time_t resigntime; 223 isc_time_t keywarntime; 224 isc_time_t signingtime; 225 isc_time_t nsec3chaintime; 226 isc_time_t refreshkeytime; 227 isc_uint32_t refreshkeyinterval; 228 isc_uint32_t refreshkeycount; 229 isc_uint32_t refresh; 230 isc_uint32_t retry; 231 isc_uint32_t expire; 232 isc_uint32_t minimum; 233 isc_stdtime_t key_expiry; 234 isc_stdtime_t log_key_expired_timer; 235 char *keydirectory; 236 237 isc_uint32_t maxrefresh; 238 isc_uint32_t minrefresh; 239 isc_uint32_t maxretry; 240 isc_uint32_t minretry; 241 242 isc_sockaddr_t *masters; 243 dns_name_t **masterkeynames; 244 isc_boolean_t *mastersok; 245 unsigned int masterscnt; 246 unsigned int curmaster; 247 isc_sockaddr_t masteraddr; 248 dns_notifytype_t notifytype; 249 isc_sockaddr_t *notify; 250 dns_name_t **notifykeynames; 251 unsigned int notifycnt; 252 isc_sockaddr_t notifyfrom; 253 isc_task_t *task; 254 isc_task_t *loadtask; 255 isc_sockaddr_t notifysrc4; 256 isc_sockaddr_t notifysrc6; 257 isc_sockaddr_t xfrsource4; 258 isc_sockaddr_t xfrsource6; 259 isc_sockaddr_t altxfrsource4; 260 isc_sockaddr_t altxfrsource6; 261 isc_sockaddr_t sourceaddr; 262 dns_xfrin_ctx_t *xfr; /* task locked */ 263 dns_tsigkey_t *tsigkey; /* key used for xfr */ 264 /* Access Control Lists */ 265 dns_acl_t *update_acl; 266 dns_acl_t *forward_acl; 267 dns_acl_t *notify_acl; 268 dns_acl_t *query_acl; 269 dns_acl_t *queryon_acl; 270 dns_acl_t *xfr_acl; 271 isc_boolean_t update_disabled; 272 isc_boolean_t zero_no_soa_ttl; 273 dns_severity_t check_names; 274 ISC_LIST(dns_notify_t) notifies; 275 dns_request_t *request; 276 dns_loadctx_t *lctx; 277 dns_io_t *readio; 278 dns_dumpctx_t *dctx; 279 dns_io_t *writeio; 280 isc_uint32_t maxxfrin; 281 isc_uint32_t maxxfrout; 282 isc_uint32_t idlein; 283 isc_uint32_t idleout; 284 isc_event_t ctlevent; 285 dns_ssutable_t *ssutable; 286 isc_uint32_t sigvalidityinterval; 287 isc_uint32_t sigresigninginterval; 288 dns_view_t *view; 289 dns_acache_t *acache; 290 dns_checkmxfunc_t checkmx; 291 dns_checksrvfunc_t checksrv; 292 dns_checknsfunc_t checkns; 293 /*% 294 * Zones in certain states such as "waiting for zone transfer" 295 * or "zone transfer in progress" are kept on per-state linked lists 296 * in the zone manager using the 'statelink' field. The 'statelist' 297 * field points at the list the zone is currently on. It the zone 298 * is not on any such list, statelist is NULL. 299 */ 300 ISC_LINK(dns_zone_t) statelink; 301 dns_zonelist_t *statelist; 302 /*% 303 * Statistics counters about zone management. 304 */ 305 isc_stats_t *stats; 306 /*% 307 * Optional per-zone statistics counters. Counted outside of this 308 * module. 309 */ 310 isc_boolean_t requeststats_on; 311 isc_stats_t *requeststats; 312 isc_uint32_t notifydelay; 313 dns_isselffunc_t isself; 314 void *isselfarg; 315 316 char * strnamerd; 317 char * strname; 318 char * strrdclass; 319 char * strviewname; 320 321 /*% 322 * Serial number for deferred journal compaction. 323 */ 324 isc_uint32_t compact_serial; 325 /*% 326 * Keys that are signing the zone for the first time. 327 */ 328 dns_signinglist_t signing; 329 dns_nsec3chainlist_t nsec3chain; 330 /*% 331 * Signing / re-signing quantum stopping parameters. 332 */ 333 isc_uint32_t signatures; 334 isc_uint32_t nodes; 335 dns_rdatatype_t privatetype; 336 337 /*% 338 * Autosigning/key-maintenance options 339 */ 340 isc_uint32_t keyopts; 341 342 /*% 343 * True if added by "rndc addzone" 344 */ 345 isc_boolean_t added; 346 347 /*% 348 * whether a rpz radix was needed when last loaded 349 */ 350 isc_boolean_t rpz_zone; 351 352 /*% 353 * Serial number update method. 354 */ 355 dns_updatemethod_t updatemethod; 356 357 /*% 358 * whether ixfr is requested 359 */ 360 isc_boolean_t requestixfr; 361 362 /*% 363 * Outstanding forwarded UPDATE requests. 364 */ 365 dns_forwardlist_t forwards; 366 367 dns_zone_t *raw; 368 dns_zone_t *secure; 369 370 isc_boolean_t sourceserialset; 371 isc_uint32_t sourceserial; 372}; 373 374#define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0)) 375#define DNS_ZONE_SETFLAG(z,f) do { \ 376 INSIST(LOCKED_ZONE(z)); \ 377 (z)->flags |= (f); \ 378 } while (/*CONSTCOND*/0) 379#define DNS_ZONE_CLRFLAG(z,f) do { \ 380 INSIST(LOCKED_ZONE(z)); \ 381 (z)->flags &= ~(f); \ 382 } while (/*CONSTCOND*/0) 383 /* XXX MPA these may need to go back into zone.h */ 384#define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */ 385#define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */ 386#define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */ 387#define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */ 388#define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */ 389#define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */ 390#define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */ 391#define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */ 392#define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */ 393#define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are 394 * uptodate */ 395#define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify 396 * messages */ 397#define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on 398 * reload */ 399#define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a 400 * zone with no masters 401 * occurred */ 402#define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/ 403#define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set 404 * from SOA (if not set, we 405 * are still using 406 * default timer values) */ 407#define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */ 408#define DNS_ZONEFLG_NOREFRESH 0x00010000U 409#define DNS_ZONEFLG_DIALNOTIFY 0x00020000U 410#define DNS_ZONEFLG_DIALREFRESH 0x00040000U 411#define DNS_ZONEFLG_SHUTDOWN 0x00080000U 412#define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */ 413#define DNS_ZONEFLG_FLUSH 0x00200000U 414#define DNS_ZONEFLG_NOEDNS 0x00400000U 415#define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U 416#define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U 417#define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U 418#define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */ 419#define DNS_ZONEFLG_THAW 0x08000000U 420#define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */ 421#define DNS_ZONEFLG_NODELAY 0x20000000U 422#define DNS_ZONEFLG_SENDSECURE 0x40000000U 423 424#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0) 425#define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0) 426 427/* Flags for zone_load() */ 428#define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */ 429#define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful 430 load. */ 431 432#define UNREACH_CHACHE_SIZE 10U 433#define UNREACH_HOLD_TIME 600 /* 10 minutes */ 434 435#define CHECK(op) \ 436 do { result = (op); \ 437 if (result != ISC_R_SUCCESS) goto failure; \ 438 } while (/*CONSTCOND*/0) 439 440struct dns_unreachable { 441 isc_sockaddr_t remote; 442 isc_sockaddr_t local; 443 isc_uint32_t expire; 444 isc_uint32_t last; 445}; 446 447struct dns_zonemgr { 448 unsigned int magic; 449 isc_mem_t * mctx; 450 int refs; /* Locked by rwlock */ 451 isc_taskmgr_t * taskmgr; 452 isc_timermgr_t * timermgr; 453 isc_socketmgr_t * socketmgr; 454 isc_taskpool_t * zonetasks; 455 isc_taskpool_t * loadtasks; 456 isc_task_t * task; 457 isc_ratelimiter_t * rl; 458 isc_rwlock_t rwlock; 459 isc_mutex_t iolock; 460 isc_rwlock_t urlock; 461 462 /* Locked by rwlock. */ 463 dns_zonelist_t zones; 464 dns_zonelist_t waiting_for_xfrin; 465 dns_zonelist_t xfrin_in_progress; 466 467 /* Configuration data. */ 468 isc_uint32_t transfersin; 469 isc_uint32_t transfersperns; 470 unsigned int serialqueryrate; 471 472 /* Locked by iolock */ 473 isc_uint32_t iolimit; 474 isc_uint32_t ioactive; 475 dns_iolist_t high; 476 dns_iolist_t low; 477 478 /* Locked by urlock. */ 479 /* LRU cache */ 480 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE]; 481}; 482 483/*% 484 * Hold notify state. 485 */ 486struct dns_notify { 487 unsigned int magic; 488 unsigned int flags; 489 isc_mem_t *mctx; 490 dns_zone_t *zone; 491 dns_adbfind_t *find; 492 dns_request_t *request; 493 dns_name_t ns; 494 isc_sockaddr_t dst; 495 dns_tsigkey_t *key; 496 ISC_LINK(dns_notify_t) link; 497}; 498 499#define DNS_NOTIFY_NOSOA 0x0001U 500 501/*% 502 * dns_stub holds state while performing a 'stub' transfer. 503 * 'db' is the zone's 'db' or a new one if this is the initial 504 * transfer. 505 */ 506 507struct dns_stub { 508 unsigned int magic; 509 isc_mem_t *mctx; 510 dns_zone_t *zone; 511 dns_db_t *db; 512 dns_dbversion_t *version; 513}; 514 515/*% 516 * Hold load state. 517 */ 518struct dns_load { 519 unsigned int magic; 520 isc_mem_t *mctx; 521 dns_zone_t *zone; 522 dns_db_t *db; 523 isc_time_t loadtime; 524 dns_rdatacallbacks_t callbacks; 525}; 526 527/*% 528 * Hold forward state. 529 */ 530struct dns_forward { 531 unsigned int magic; 532 isc_mem_t *mctx; 533 dns_zone_t *zone; 534 isc_buffer_t *msgbuf; 535 dns_request_t *request; 536 isc_uint32_t which; 537 isc_sockaddr_t addr; 538 dns_updatecallback_t callback; 539 void *callback_arg; 540 ISC_LINK(dns_forward_t) link; 541}; 542 543/*% 544 * Hold IO request state. 545 */ 546struct dns_io { 547 unsigned int magic; 548 dns_zonemgr_t *zmgr; 549 isc_boolean_t high; 550 isc_task_t *task; 551 ISC_LINK(dns_io_t) link; 552 isc_event_t *event; 553}; 554 555/*% 556 * Hold state for when we are signing a zone with a new 557 * DNSKEY as result of an update. 558 */ 559struct dns_signing { 560 unsigned int magic; 561 dns_db_t *db; 562 dns_dbiterator_t *dbiterator; 563 dns_secalg_t algorithm; 564 isc_uint16_t keyid; 565 isc_boolean_t delete; 566 isc_boolean_t done; 567 ISC_LINK(dns_signing_t) link; 568}; 569 570struct dns_nsec3chain { 571 unsigned int magic; 572 dns_db_t *db; 573 dns_dbiterator_t *dbiterator; 574 dns_rdata_nsec3param_t nsec3param; 575 unsigned char salt[255]; 576 isc_boolean_t done; 577 isc_boolean_t seen_nsec; 578 isc_boolean_t delete_nsec; 579 isc_boolean_t save_delete_nsec; 580 ISC_LINK(dns_nsec3chain_t) link; 581}; 582/*%< 583 * 'dbiterator' contains a iterator for the database. If we are creating 584 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are 585 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be 586 * iterated. 587 * 588 * 'nsec3param' contains the parameters of the NSEC3 chain being created 589 * or removed. 590 * 591 * 'salt' is buffer space and is referenced via 'nsec3param.salt'. 592 * 593 * 'seen_nsec' will be set to true if, while iterating the zone to create a 594 * NSEC3 chain, a NSEC record is seen. 595 * 596 * 'delete_nsec' will be set to true if, at the completion of the creation 597 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we 598 * are in the process of deleting the NSEC chain. 599 * 600 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec' 601 * so it can be recovered in the event of a error. 602 */ 603 604struct dns_keyfetch { 605 dns_fixedname_t name; 606 dns_rdataset_t keydataset; 607 dns_rdataset_t dnskeyset; 608 dns_rdataset_t dnskeysigset; 609 dns_zone_t *zone; 610 dns_db_t *db; 611 dns_fetch_t *fetch; 612}; 613 614/*% 615 * Hold state for an asynchronous load 616 */ 617struct dns_asyncload { 618 dns_zone_t *zone; 619 dns_zt_zoneloaded_t loaded; 620 void *loaded_arg; 621}; 622 623#define HOUR 3600 624#define DAY (24*HOUR) 625#define MONTH (30*DAY) 626 627#define SEND_BUFFER_SIZE 2048 628 629static void zone_settimer(dns_zone_t *, isc_time_t *); 630static void cancel_refresh(dns_zone_t *); 631static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel, 632 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5); 633static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...) 634 ISC_FORMAT_PRINTF(3, 4); 635static void queue_xfrin(dns_zone_t *zone); 636static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver, 637 dns_diff_t *diff, dns_diffop_t op, 638 dns_name_t *name, dns_ttl_t ttl, 639 dns_rdata_t *rdata); 640static void zone_unload(dns_zone_t *zone); 641static void zone_expire(dns_zone_t *zone); 642static void zone_iattach(dns_zone_t *source, dns_zone_t **target); 643static void zone_idetach(dns_zone_t **zonep); 644static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db, 645 isc_boolean_t dump); 646static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db); 647static inline void zone_detachdb(dns_zone_t *zone); 648static isc_result_t default_journal(dns_zone_t *zone); 649static void zone_xfrdone(dns_zone_t *zone, isc_result_t result); 650static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db, 651 isc_time_t loadtime, isc_result_t result); 652static void zone_needdump(dns_zone_t *zone, unsigned int delay); 653static void zone_shutdown(isc_task_t *, isc_event_t *); 654static void zone_loaddone(void *arg, isc_result_t result); 655static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone, 656 isc_time_t loadtime); 657static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length); 658static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length); 659static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length); 660static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length); 661static isc_result_t zone_send_secureserial(dns_zone_t *zone, 662 isc_boolean_t secure_locked, 663 isc_uint32_t serial); 664 665#if 0 666/* ondestroy example */ 667static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event); 668#endif 669 670static void refresh_callback(isc_task_t *, isc_event_t *); 671static void stub_callback(isc_task_t *, isc_event_t *); 672static void queue_soa_query(dns_zone_t *zone); 673static void soa_query(isc_task_t *, isc_event_t *); 674static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, 675 dns_stub_t *stub); 676static int message_count(dns_message_t *msg, dns_section_t section, 677 dns_rdatatype_t type); 678static void notify_cancel(dns_zone_t *zone); 679static void notify_find_address(dns_notify_t *notify); 680static void notify_send(dns_notify_t *notify); 681static isc_result_t notify_createmessage(dns_zone_t *zone, 682 unsigned int flags, 683 dns_message_t **messagep); 684static void notify_done(isc_task_t *task, isc_event_t *event); 685static void notify_send_toaddr(isc_task_t *task, isc_event_t *event); 686static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t); 687static void got_transfer_quota(isc_task_t *task, isc_event_t *event); 688static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, 689 dns_zone_t *zone); 690static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi); 691static void zonemgr_free(dns_zonemgr_t *zmgr); 692static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high, 693 isc_task_t *task, isc_taskaction_t action, 694 void *arg, dns_io_t **iop); 695static void zonemgr_putio(dns_io_t **iop); 696static void zonemgr_cancelio(dns_io_t *io); 697 698static isc_result_t 699zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 700 unsigned int *soacount, isc_uint32_t *serial, 701 isc_uint32_t *refresh, isc_uint32_t *retry, 702 isc_uint32_t *expire, isc_uint32_t *minimum, 703 unsigned int *errors); 704 705static void zone_freedbargs(dns_zone_t *zone); 706static void forward_callback(isc_task_t *task, isc_event_t *event); 707static void zone_saveunique(dns_zone_t *zone, const char *path, 708 const char *templat); 709static void zone_maintenance(dns_zone_t *zone); 710static void zone_notify(dns_zone_t *zone, isc_time_t *now); 711static void dump_done(void *arg, isc_result_t result); 712static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, 713 isc_uint16_t keyid, isc_boolean_t delete); 714static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver, 715 dns_dbnode_t *node, dns_name_t *name, 716 dns_diff_t *diff); 717static void zone_rekey(dns_zone_t *zone); 718static isc_boolean_t delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, 719 dst_key_t **keys, unsigned int nkeys); 720static isc_result_t zone_send_securedb(dns_zone_t *zone, isc_boolean_t locked, 721 dns_db_t *db); 722 723#define ENTER zone_debuglog(zone, me, 1, "enter") 724 725static const unsigned int dbargc_default = 1; 726static const char *dbargv_default[] = { "rbt" }; 727 728#define DNS_ZONE_JITTER_ADD(a, b, c) \ 729 do { \ 730 isc_interval_t _i; \ 731 isc_uint32_t _j; \ 732 _j = isc_random_jitter((b), (b)/4); \ 733 isc_interval_set(&_i, _j, 0); \ 734 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 735 dns_zone_log(zone, ISC_LOG_WARNING, \ 736 "epoch approaching: upgrade required: " \ 737 "now + %s failed", #b); \ 738 isc_interval_set(&_i, _j/2, 0); \ 739 (void)isc_time_add((a), &_i, (c)); \ 740 } \ 741 } while (/*CONSTCOND*/0) 742 743#define DNS_ZONE_TIME_ADD(a, b, c) \ 744 do { \ 745 isc_interval_t _i; \ 746 isc_interval_set(&_i, (b), 0); \ 747 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 748 dns_zone_log(zone, ISC_LOG_WARNING, \ 749 "epoch approaching: upgrade required: " \ 750 "now + %s failed", #b); \ 751 isc_interval_set(&_i, (b)/2, 0); \ 752 (void)isc_time_add((a), &_i, (c)); \ 753 } \ 754 } while (/*CONSTCOND*/0) 755 756/*% 757 * Increment resolver-related statistics counters. Zone must be locked. 758 */ 759static inline void 760inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { 761 if (zone->stats != NULL) 762 isc_stats_increment(zone->stats, counter); 763} 764 765/*** 766 *** Public functions. 767 ***/ 768 769isc_result_t 770dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { 771 isc_result_t result; 772 dns_zone_t *zone; 773 isc_time_t now; 774 775 REQUIRE(zonep != NULL && *zonep == NULL); 776 REQUIRE(mctx != NULL); 777 778 TIME_NOW(&now); 779 zone = isc_mem_get(mctx, sizeof(*zone)); 780 if (zone == NULL) 781 return (ISC_R_NOMEMORY); 782 783 zone->mctx = NULL; 784 isc_mem_attach(mctx, &zone->mctx); 785 786 result = isc_mutex_init(&zone->lock); 787 if (result != ISC_R_SUCCESS) 788 goto free_zone; 789 790 result = ZONEDB_INITLOCK(&zone->dblock); 791 if (result != ISC_R_SUCCESS) 792 goto free_mutex; 793 794 /* XXX MPA check that all elements are initialised */ 795#ifdef DNS_ZONE_CHECKLOCK 796 zone->locked = ISC_FALSE; 797#endif 798 zone->db = NULL; 799 zone->zmgr = NULL; 800 ISC_LINK_INIT(zone, link); 801 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */ 802 if (result != ISC_R_SUCCESS) 803 goto free_dblock; 804 zone->irefs = 0; 805 dns_name_init(&zone->origin, NULL); 806 zone->strnamerd = NULL; 807 zone->strname = NULL; 808 zone->strrdclass = NULL; 809 zone->strviewname = NULL; 810 zone->masterfile = NULL; 811 zone->masterformat = dns_masterformat_none; 812 zone->keydirectory = NULL; 813 zone->journalsize = -1; 814 zone->journal = NULL; 815 zone->rdclass = dns_rdataclass_none; 816 zone->type = dns_zone_none; 817 zone->flags = 0; 818 zone->options = 0; 819 zone->keyopts = 0; 820 zone->db_argc = 0; 821 zone->db_argv = NULL; 822 isc_time_settoepoch(&zone->expiretime); 823 isc_time_settoepoch(&zone->refreshtime); 824 isc_time_settoepoch(&zone->dumptime); 825 isc_time_settoepoch(&zone->loadtime); 826 zone->notifytime = now; 827 isc_time_settoepoch(&zone->resigntime); 828 isc_time_settoepoch(&zone->keywarntime); 829 isc_time_settoepoch(&zone->signingtime); 830 isc_time_settoepoch(&zone->nsec3chaintime); 831 isc_time_settoepoch(&zone->refreshkeytime); 832 zone->refreshkeyinterval = 0; 833 zone->refreshkeycount = 0; 834 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 835 zone->retry = DNS_ZONE_DEFAULTRETRY; 836 zone->expire = 0; 837 zone->minimum = 0; 838 zone->maxrefresh = DNS_ZONE_MAXREFRESH; 839 zone->minrefresh = DNS_ZONE_MINREFRESH; 840 zone->maxretry = DNS_ZONE_MAXRETRY; 841 zone->minretry = DNS_ZONE_MINRETRY; 842 zone->masters = NULL; 843 zone->masterkeynames = NULL; 844 zone->mastersok = NULL; 845 zone->masterscnt = 0; 846 zone->curmaster = 0; 847 zone->notify = NULL; 848 zone->notifykeynames = NULL; 849 zone->notifytype = dns_notifytype_yes; 850 zone->notifycnt = 0; 851 zone->task = NULL; 852 zone->loadtask = NULL; 853 zone->update_acl = NULL; 854 zone->forward_acl = NULL; 855 zone->notify_acl = NULL; 856 zone->query_acl = NULL; 857 zone->queryon_acl = NULL; 858 zone->xfr_acl = NULL; 859 zone->update_disabled = ISC_FALSE; 860 zone->zero_no_soa_ttl = ISC_TRUE; 861 zone->check_names = dns_severity_ignore; 862 zone->request = NULL; 863 zone->lctx = NULL; 864 zone->readio = NULL; 865 zone->dctx = NULL; 866 zone->writeio = NULL; 867 zone->timer = NULL; 868 zone->idlein = DNS_DEFAULT_IDLEIN; 869 zone->idleout = DNS_DEFAULT_IDLEOUT; 870 zone->log_key_expired_timer = 0; 871 ISC_LIST_INIT(zone->notifies); 872 isc_sockaddr_any(&zone->notifysrc4); 873 isc_sockaddr_any6(&zone->notifysrc6); 874 isc_sockaddr_any(&zone->xfrsource4); 875 isc_sockaddr_any6(&zone->xfrsource6); 876 isc_sockaddr_any(&zone->altxfrsource4); 877 isc_sockaddr_any6(&zone->altxfrsource6); 878 zone->xfr = NULL; 879 zone->tsigkey = NULL; 880 zone->maxxfrin = MAX_XFER_TIME; 881 zone->maxxfrout = MAX_XFER_TIME; 882 zone->ssutable = NULL; 883 zone->sigvalidityinterval = 30 * 24 * 3600; 884 zone->sigresigninginterval = 7 * 24 * 3600; 885 zone->view = NULL; 886 zone->acache = NULL; 887 zone->checkmx = NULL; 888 zone->checksrv = NULL; 889 zone->checkns = NULL; 890 ISC_LINK_INIT(zone, statelink); 891 zone->statelist = NULL; 892 zone->stats = NULL; 893 zone->requeststats_on = ISC_FALSE; 894 zone->requeststats = NULL; 895 zone->notifydelay = 5; 896 zone->isself = NULL; 897 zone->isselfarg = NULL; 898 ISC_LIST_INIT(zone->signing); 899 ISC_LIST_INIT(zone->nsec3chain); 900 zone->signatures = 10; 901 zone->nodes = 100; 902 zone->privatetype = (dns_rdatatype_t)0xffffU; 903 zone->added = ISC_FALSE; 904 zone->rpz_zone = ISC_FALSE; 905 ISC_LIST_INIT(zone->forwards); 906 zone->raw = NULL; 907 zone->secure = NULL; 908 zone->sourceserial = 0; 909 zone->sourceserialset = ISC_FALSE; 910 911 zone->magic = ZONE_MAGIC; 912 913 /* Must be after magic is set. */ 914 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default); 915 if (result != ISC_R_SUCCESS) 916 goto free_erefs; 917 918 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL, 919 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, 920 NULL, NULL); 921 *zonep = zone; 922 return (ISC_R_SUCCESS); 923 924 free_erefs: 925 isc_refcount_decrement(&zone->erefs, NULL); 926 isc_refcount_destroy(&zone->erefs); 927 928 free_dblock: 929 ZONEDB_DESTROYLOCK(&zone->dblock); 930 931 free_mutex: 932 DESTROYLOCK(&zone->lock); 933 934 free_zone: 935 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone)); 936 return (result); 937} 938 939/* 940 * Free a zone. Because we require that there be no more 941 * outstanding events or references, no locking is necessary. 942 */ 943static void 944zone_free(dns_zone_t *zone) { 945 isc_mem_t *mctx = NULL; 946 dns_signing_t *signing; 947 dns_nsec3chain_t *nsec3chain; 948 949 REQUIRE(DNS_ZONE_VALID(zone)); 950 REQUIRE(isc_refcount_current(&zone->erefs) == 0); 951 REQUIRE(zone->irefs == 0); 952 REQUIRE(!LOCKED_ZONE(zone)); 953 REQUIRE(zone->timer == NULL); 954 955 /* 956 * Managed objects. Order is important. 957 */ 958 if (zone->request != NULL) 959 dns_request_destroy(&zone->request); /* XXXMPA */ 960 INSIST(zone->readio == NULL); 961 INSIST(zone->statelist == NULL); 962 INSIST(zone->writeio == NULL); 963 964 if (zone->task != NULL) 965 isc_task_detach(&zone->task); 966 if (zone->loadtask != NULL) 967 isc_task_detach(&zone->loadtask); 968 if (zone->zmgr != NULL) 969 dns_zonemgr_releasezone(zone->zmgr, zone); 970 971 /* Unmanaged objects */ 972 for (signing = ISC_LIST_HEAD(zone->signing); 973 signing != NULL; 974 signing = ISC_LIST_HEAD(zone->signing)) { 975 ISC_LIST_UNLINK(zone->signing, signing, link); 976 dns_db_detach(&signing->db); 977 dns_dbiterator_destroy(&signing->dbiterator); 978 isc_mem_put(zone->mctx, signing, sizeof *signing); 979 } 980 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 981 nsec3chain != NULL; 982 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) { 983 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 984 dns_db_detach(&nsec3chain->db); 985 dns_dbiterator_destroy(&nsec3chain->dbiterator); 986 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 987 } 988 if (zone->masterfile != NULL) 989 isc_mem_free(zone->mctx, zone->masterfile); 990 zone->masterfile = NULL; 991 if (zone->keydirectory != NULL) 992 isc_mem_free(zone->mctx, zone->keydirectory); 993 zone->keydirectory = NULL; 994 zone->journalsize = -1; 995 if (zone->journal != NULL) 996 isc_mem_free(zone->mctx, zone->journal); 997 zone->journal = NULL; 998 if (zone->stats != NULL) 999 isc_stats_detach(&zone->stats); 1000 if (zone->requeststats != NULL) 1001 isc_stats_detach(&zone->requeststats); 1002 if (zone->db != NULL) 1003 zone_detachdb(zone); 1004 if (zone->acache != NULL) 1005 dns_acache_detach(&zone->acache); 1006 zone_freedbargs(zone); 1007 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0) 1008 == ISC_R_SUCCESS); 1009 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) 1010 == ISC_R_SUCCESS); 1011 zone->check_names = dns_severity_ignore; 1012 if (zone->update_acl != NULL) 1013 dns_acl_detach(&zone->update_acl); 1014 if (zone->forward_acl != NULL) 1015 dns_acl_detach(&zone->forward_acl); 1016 if (zone->notify_acl != NULL) 1017 dns_acl_detach(&zone->notify_acl); 1018 if (zone->query_acl != NULL) 1019 dns_acl_detach(&zone->query_acl); 1020 if (zone->queryon_acl != NULL) 1021 dns_acl_detach(&zone->queryon_acl); 1022 if (zone->xfr_acl != NULL) 1023 dns_acl_detach(&zone->xfr_acl); 1024 if (dns_name_dynamic(&zone->origin)) 1025 dns_name_free(&zone->origin, zone->mctx); 1026 if (zone->strnamerd != NULL) 1027 isc_mem_free(zone->mctx, zone->strnamerd); 1028 if (zone->strname != NULL) 1029 isc_mem_free(zone->mctx, zone->strname); 1030 if (zone->strrdclass != NULL) 1031 isc_mem_free(zone->mctx, zone->strrdclass); 1032 if (zone->strviewname != NULL) 1033 isc_mem_free(zone->mctx, zone->strviewname); 1034 if (zone->ssutable != NULL) 1035 dns_ssutable_detach(&zone->ssutable); 1036 1037 /* last stuff */ 1038 ZONEDB_DESTROYLOCK(&zone->dblock); 1039 DESTROYLOCK(&zone->lock); 1040 isc_refcount_destroy(&zone->erefs); 1041 zone->magic = 0; 1042 mctx = zone->mctx; 1043 isc_mem_put(mctx, zone, sizeof(*zone)); 1044 isc_mem_detach(&mctx); 1045} 1046 1047/* 1048 * Returns ISC_TRUE iff this the signed side of an inline-signing zone 1049 */ 1050static inline isc_boolean_t 1051inline_secure(dns_zone_t *zone) { 1052 REQUIRE(DNS_ZONE_VALID(zone)); 1053 if (zone->raw != NULL) 1054 return (ISC_TRUE); 1055 return (ISC_FALSE); 1056} 1057 1058/* 1059 * Returns ISC_TRUE iff this the unsigned side of an inline-signing zone 1060 */ 1061static inline isc_boolean_t 1062inline_raw(dns_zone_t *zone) { 1063 REQUIRE(DNS_ZONE_VALID(zone)); 1064 if (zone->secure != NULL) 1065 return (ISC_TRUE); 1066 return (ISC_FALSE); 1067} 1068 1069/* 1070 * Single shot. 1071 */ 1072void 1073dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) { 1074 char namebuf[1024]; 1075 1076 REQUIRE(DNS_ZONE_VALID(zone)); 1077 REQUIRE(rdclass != dns_rdataclass_none); 1078 1079 /* 1080 * Test and set. 1081 */ 1082 LOCK_ZONE(zone); 1083 REQUIRE(zone->rdclass == dns_rdataclass_none || 1084 zone->rdclass == rdclass); 1085 zone->rdclass = rdclass; 1086 1087 if (zone->strnamerd != NULL) 1088 isc_mem_free(zone->mctx, zone->strnamerd); 1089 if (zone->strrdclass != NULL) 1090 isc_mem_free(zone->mctx, zone->strrdclass); 1091 1092 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1093 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1094 zone_rdclass_tostr(zone, namebuf, sizeof namebuf); 1095 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf); 1096 1097 if (inline_secure(zone)) 1098 dns_zone_setclass(zone->raw, rdclass); 1099 UNLOCK_ZONE(zone); 1100} 1101 1102dns_rdataclass_t 1103dns_zone_getclass(dns_zone_t *zone) { 1104 REQUIRE(DNS_ZONE_VALID(zone)); 1105 1106 return (zone->rdclass); 1107} 1108 1109void 1110dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { 1111 REQUIRE(DNS_ZONE_VALID(zone)); 1112 1113 LOCK_ZONE(zone); 1114 zone->notifytype = notifytype; 1115 UNLOCK_ZONE(zone); 1116} 1117 1118isc_result_t 1119dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) { 1120 isc_result_t result; 1121 1122 REQUIRE(DNS_ZONE_VALID(zone)); 1123 REQUIRE(serialp != NULL); 1124 1125 LOCK_ZONE(zone); 1126 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1127 if (zone->db != NULL) { 1128 result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp, 1129 NULL, NULL, NULL, NULL, NULL); 1130 } else 1131 result = DNS_R_NOTLOADED; 1132 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1133 UNLOCK_ZONE(zone); 1134 1135 return (result); 1136} 1137 1138isc_uint32_t 1139dns_zone_getserial(dns_zone_t *zone) { 1140 isc_result_t result; 1141 isc_uint32_t serial; 1142 1143 result = dns_zone_getserial2(zone, &serial); 1144 if (result != ISC_R_SUCCESS) 1145 serial = 0; /* XXX: not really correct, but no other choice */ 1146 1147 return (serial); 1148} 1149 1150/* 1151 * Single shot. 1152 */ 1153void 1154dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) { 1155 char namebuf[1024]; 1156 1157 REQUIRE(DNS_ZONE_VALID(zone)); 1158 REQUIRE(type != dns_zone_none); 1159 1160 /* 1161 * Test and set. 1162 */ 1163 LOCK_ZONE(zone); 1164 REQUIRE(zone->type == dns_zone_none || zone->type == type); 1165 zone->type = type; 1166 1167 if (zone->strnamerd != NULL) 1168 isc_mem_free(zone->mctx, zone->strnamerd); 1169 1170 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1171 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1172 UNLOCK_ZONE(zone); 1173} 1174 1175static void 1176zone_freedbargs(dns_zone_t *zone) { 1177 unsigned int i; 1178 1179 /* Free the old database argument list. */ 1180 if (zone->db_argv != NULL) { 1181 for (i = 0; i < zone->db_argc; i++) 1182 isc_mem_free(zone->mctx, zone->db_argv[i]); 1183 isc_mem_put(zone->mctx, zone->db_argv, 1184 zone->db_argc * sizeof(*zone->db_argv)); 1185 } 1186 zone->db_argc = 0; 1187 zone->db_argv = NULL; 1188} 1189 1190isc_result_t 1191dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) { 1192 size_t size = 0; 1193 unsigned int i; 1194 isc_result_t result = ISC_R_SUCCESS; 1195 void *mem; 1196 char **tmp, *tmp2; 1197 1198 REQUIRE(DNS_ZONE_VALID(zone)); 1199 REQUIRE(argv != NULL && *argv == NULL); 1200 1201 LOCK_ZONE(zone); 1202 size = (zone->db_argc + 1) * sizeof(char *); 1203 for (i = 0; i < zone->db_argc; i++) 1204 size += strlen(zone->db_argv[i]) + 1; 1205 mem = isc_mem_allocate(mctx, size); 1206 if (mem != NULL) { 1207 tmp = mem; 1208 tmp2 = mem; 1209 tmp2 += (zone->db_argc + 1) * sizeof(char *); 1210 for (i = 0; i < zone->db_argc; i++) { 1211 *tmp++ = tmp2; 1212 strcpy(tmp2, zone->db_argv[i]); 1213 tmp2 += strlen(tmp2) + 1; 1214 } 1215 *tmp = NULL; 1216 } else 1217 result = ISC_R_NOMEMORY; 1218 UNLOCK_ZONE(zone); 1219 *argv = mem; 1220 return (result); 1221} 1222 1223isc_result_t 1224dns_zone_setdbtype(dns_zone_t *zone, 1225 unsigned int dbargc, const char * const *dbargv) { 1226 isc_result_t result = ISC_R_SUCCESS; 1227 char **new = NULL; 1228 unsigned int i; 1229 1230 REQUIRE(DNS_ZONE_VALID(zone)); 1231 REQUIRE(dbargc >= 1); 1232 REQUIRE(dbargv != NULL); 1233 1234 LOCK_ZONE(zone); 1235 1236 /* Set up a new database argument list. */ 1237 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new)); 1238 if (new == NULL) 1239 goto nomem; 1240 for (i = 0; i < dbargc; i++) 1241 new[i] = NULL; 1242 for (i = 0; i < dbargc; i++) { 1243 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]); 1244 if (new[i] == NULL) 1245 goto nomem; 1246 } 1247 1248 /* Free the old list. */ 1249 zone_freedbargs(zone); 1250 1251 zone->db_argc = dbargc; 1252 zone->db_argv = new; 1253 result = ISC_R_SUCCESS; 1254 goto unlock; 1255 1256 nomem: 1257 if (new != NULL) { 1258 for (i = 0; i < dbargc; i++) 1259 if (new[i] != NULL) 1260 isc_mem_free(zone->mctx, new[i]); 1261 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new)); 1262 } 1263 result = ISC_R_NOMEMORY; 1264 1265 unlock: 1266 UNLOCK_ZONE(zone); 1267 return (result); 1268} 1269 1270void 1271dns_zone_setview(dns_zone_t *zone, dns_view_t *view) { 1272 char namebuf[1024]; 1273 REQUIRE(DNS_ZONE_VALID(zone)); 1274 1275 LOCK_ZONE(zone); 1276 if (zone->view != NULL) 1277 dns_view_weakdetach(&zone->view); 1278 dns_view_weakattach(view, &zone->view); 1279 1280 if (zone->strviewname != NULL) 1281 isc_mem_free(zone->mctx, zone->strviewname); 1282 if (zone->strnamerd != NULL) 1283 isc_mem_free(zone->mctx, zone->strnamerd); 1284 1285 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1286 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1287 zone_viewname_tostr(zone, namebuf, sizeof namebuf); 1288 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf); 1289 1290 if (inline_secure(zone)) 1291 dns_zone_setview(zone->raw, view); 1292 1293 UNLOCK_ZONE(zone); 1294} 1295 1296dns_view_t * 1297dns_zone_getview(dns_zone_t *zone) { 1298 REQUIRE(DNS_ZONE_VALID(zone)); 1299 1300 return (zone->view); 1301} 1302 1303 1304isc_result_t 1305dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) { 1306 isc_result_t result; 1307 char namebuf[1024]; 1308 1309 REQUIRE(DNS_ZONE_VALID(zone)); 1310 REQUIRE(origin != NULL); 1311 1312 LOCK_ZONE(zone); 1313 if (dns_name_dynamic(&zone->origin)) { 1314 dns_name_free(&zone->origin, zone->mctx); 1315 dns_name_init(&zone->origin, NULL); 1316 } 1317 result = dns_name_dup(origin, zone->mctx, &zone->origin); 1318 1319 if (zone->strnamerd != NULL) 1320 isc_mem_free(zone->mctx, zone->strnamerd); 1321 if (zone->strname != NULL) 1322 isc_mem_free(zone->mctx, zone->strname); 1323 1324 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1325 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1326 zone_name_tostr(zone, namebuf, sizeof namebuf); 1327 zone->strname = isc_mem_strdup(zone->mctx, namebuf); 1328 1329 if (result == ISC_R_SUCCESS && inline_secure(zone)) 1330 result = dns_zone_setorigin(zone->raw, origin); 1331 UNLOCK_ZONE(zone); 1332 return (result); 1333} 1334 1335void 1336dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) { 1337 REQUIRE(DNS_ZONE_VALID(zone)); 1338 REQUIRE(acache != NULL); 1339 1340 LOCK_ZONE(zone); 1341 if (zone->acache != NULL) 1342 dns_acache_detach(&zone->acache); 1343 dns_acache_attach(acache, &zone->acache); 1344 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1345 if (zone->db != NULL) { 1346 isc_result_t result; 1347 1348 /* 1349 * If the zone reuses an existing DB, the DB needs to be 1350 * set in the acache explicitly. We can safely ignore the 1351 * case where the DB is already set. If other error happens, 1352 * the acache will not work effectively. 1353 */ 1354 result = dns_acache_setdb(acache, zone->db); 1355 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { 1356 UNEXPECTED_ERROR(__FILE__, __LINE__, 1357 "dns_acache_setdb() failed: %s", 1358 isc_result_totext(result)); 1359 } 1360 } 1361 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1362 UNLOCK_ZONE(zone); 1363} 1364 1365static isc_result_t 1366dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) { 1367 char *copy; 1368 1369 if (value != NULL) { 1370 copy = isc_mem_strdup(zone->mctx, value); 1371 if (copy == NULL) 1372 return (ISC_R_NOMEMORY); 1373 } else { 1374 copy = NULL; 1375 } 1376 1377 if (*field != NULL) 1378 isc_mem_free(zone->mctx, *field); 1379 1380 *field = copy; 1381 return (ISC_R_SUCCESS); 1382} 1383 1384isc_result_t 1385dns_zone_setfile(dns_zone_t *zone, const char *file) { 1386 return (dns_zone_setfile2(zone, file, dns_masterformat_text)); 1387} 1388 1389isc_result_t 1390dns_zone_setfile2(dns_zone_t *zone, const char *file, 1391 dns_masterformat_t format) { 1392 isc_result_t result = ISC_R_SUCCESS; 1393 1394 REQUIRE(DNS_ZONE_VALID(zone)); 1395 1396 LOCK_ZONE(zone); 1397 result = dns_zone_setstring(zone, &zone->masterfile, file); 1398 if (result == ISC_R_SUCCESS) { 1399 zone->masterformat = format; 1400 result = default_journal(zone); 1401 } 1402 UNLOCK_ZONE(zone); 1403 1404 return (result); 1405} 1406 1407const char * 1408dns_zone_getfile(dns_zone_t *zone) { 1409 REQUIRE(DNS_ZONE_VALID(zone)); 1410 1411 return (zone->masterfile); 1412} 1413 1414static isc_result_t 1415default_journal(dns_zone_t *zone) { 1416 isc_result_t result; 1417 char *journal; 1418 1419 REQUIRE(DNS_ZONE_VALID(zone)); 1420 REQUIRE(LOCKED_ZONE(zone)); 1421 1422 if (zone->masterfile != NULL) { 1423 /* Calculate string length including '\0'. */ 1424 int len = strlen(zone->masterfile) + sizeof(".jnl"); 1425 journal = isc_mem_allocate(zone->mctx, len); 1426 if (journal == NULL) 1427 return (ISC_R_NOMEMORY); 1428 strcpy(journal, zone->masterfile); 1429 strcat(journal, ".jnl"); 1430 } else { 1431 journal = NULL; 1432 } 1433 result = dns_zone_setstring(zone, &zone->journal, journal); 1434 if (journal != NULL) 1435 isc_mem_free(zone->mctx, journal); 1436 return (result); 1437} 1438 1439isc_result_t 1440dns_zone_setjournal(dns_zone_t *zone, const char *journal) { 1441 isc_result_t result = ISC_R_SUCCESS; 1442 1443 REQUIRE(DNS_ZONE_VALID(zone)); 1444 1445 LOCK_ZONE(zone); 1446 result = dns_zone_setstring(zone, &zone->journal, journal); 1447 UNLOCK_ZONE(zone); 1448 1449 return (result); 1450} 1451 1452char * 1453dns_zone_getjournal(dns_zone_t *zone) { 1454 REQUIRE(DNS_ZONE_VALID(zone)); 1455 1456 return (zone->journal); 1457} 1458 1459/* 1460 * Return true iff the zone is "dynamic", in the sense that the zone's 1461 * master file (if any) is written by the server, rather than being 1462 * updated manually and read by the server. 1463 * 1464 * This is true for slave zones, stub zones, key zones, and zones that 1465 * allow dynamic updates either by having an update policy ("ssutable") 1466 * or an "allow-update" ACL with a value other than exactly "{ none; }". 1467 */ 1468isc_boolean_t 1469dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze) { 1470 REQUIRE(DNS_ZONE_VALID(zone)); 1471 1472 if (zone->type == dns_zone_slave || zone->type == dns_zone_stub || 1473 zone->type == dns_zone_key || 1474 (zone->type == dns_zone_redirect && zone->masters != NULL)) 1475 return (ISC_TRUE); 1476 1477 /* If !ignore_freeze, we need check whether updates are disabled. */ 1478 if (zone->type == dns_zone_master && 1479 (!zone->update_disabled || ignore_freeze) && 1480 ((zone->ssutable != NULL) || 1481 (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)))) 1482 return (ISC_TRUE); 1483 1484 return (ISC_FALSE); 1485 1486} 1487 1488static isc_result_t 1489zone_load(dns_zone_t *zone, unsigned int flags) { 1490 isc_result_t result; 1491 isc_time_t now; 1492 isc_time_t loadtime, filetime; 1493 dns_db_t *db = NULL; 1494 isc_boolean_t rbt; 1495 1496 REQUIRE(DNS_ZONE_VALID(zone)); 1497 1498 if (inline_secure(zone)) { 1499 result = zone_load(zone->raw, flags); 1500 if (result != ISC_R_SUCCESS) 1501 return(result); 1502 } 1503 1504 /* 1505 * Lock hierachy zmgr, raw, zone. 1506 */ 1507 if (inline_secure(zone)) 1508 LOCK_ZONE(zone->raw); 1509 LOCK_ZONE(zone); 1510 TIME_NOW(&now); 1511 1512 INSIST(zone->type != dns_zone_none); 1513 1514 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { 1515 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) 1516 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 1517 result = DNS_R_CONTINUE; 1518 goto cleanup; 1519 } 1520 1521 INSIST(zone->db_argc >= 1); 1522 1523 rbt = strcmp(zone->db_argv[0], "rbt") == 0 || 1524 strcmp(zone->db_argv[0], "rbt64") == 0; 1525 1526 if (zone->db != NULL && zone->masterfile == NULL && rbt) { 1527 /* 1528 * The zone has no master file configured. 1529 */ 1530 result = ISC_R_SUCCESS; 1531 goto cleanup; 1532 } 1533 1534 if (zone->db != NULL && dns_zone_isdynamic(zone, ISC_FALSE)) { 1535 /* 1536 * This is a slave, stub, or dynamically updated 1537 * zone being reloaded. Do nothing - the database 1538 * we already have is guaranteed to be up-to-date. 1539 */ 1540 if (zone->type == dns_zone_master) 1541 result = DNS_R_DYNAMIC; 1542 else 1543 result = ISC_R_SUCCESS; 1544 goto cleanup; 1545 } 1546 1547 /* 1548 * Store the current time before the zone is loaded, so that if the 1549 * file changes between the time of the load and the time that 1550 * zone->loadtime is set, then the file will still be reloaded 1551 * the next time dns_zone_load is called. 1552 */ 1553 TIME_NOW(&loadtime); 1554 1555 /* 1556 * Don't do the load if the file that stores the zone is older 1557 * than the last time the zone was loaded. If the zone has not 1558 * been loaded yet, zone->loadtime will be the epoch. 1559 */ 1560 if (zone->masterfile != NULL) { 1561 /* 1562 * The file is already loaded. If we are just doing a 1563 * "rndc reconfig", we are done. 1564 */ 1565 if (!isc_time_isepoch(&zone->loadtime) && 1566 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0 && 1567 zone->rpz_zone == dns_rpz_needed()) { 1568 result = ISC_R_SUCCESS; 1569 goto cleanup; 1570 } 1571 1572 result = isc_file_getmodtime(zone->masterfile, &filetime); 1573 if (result == ISC_R_SUCCESS) { 1574 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 1575 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) && 1576 isc_time_compare(&filetime, &zone->loadtime) <= 0 && 1577 zone->rpz_zone == dns_rpz_needed()) { 1578 dns_zone_log(zone, ISC_LOG_DEBUG(1), 1579 "skipping load: master file " 1580 "older than last load"); 1581 result = DNS_R_UPTODATE; 1582 goto cleanup; 1583 } 1584 loadtime = filetime; 1585 zone->rpz_zone = dns_rpz_needed(); 1586 } 1587 } 1588 1589 /* 1590 * Built in zones (with the exception of empty zones) don't need 1591 * to be reloaded. 1592 */ 1593 if (zone->type == dns_zone_master && 1594 strcmp(zone->db_argv[0], "_builtin") == 0 && 1595 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) && 1596 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 1597 result = ISC_R_SUCCESS; 1598 goto cleanup; 1599 } 1600 1601 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub || 1602 (zone->type == dns_zone_redirect && zone->masters != NULL)) && 1603 rbt) { 1604 if (zone->masterfile == NULL || 1605 !isc_file_exists(zone->masterfile)) { 1606 if (zone->masterfile != NULL) { 1607 dns_zone_log(zone, ISC_LOG_DEBUG(1), 1608 "no master file"); 1609 } 1610 zone->refreshtime = now; 1611 if (zone->task != NULL) 1612 zone_settimer(zone, &now); 1613 result = ISC_R_SUCCESS; 1614 goto cleanup; 1615 } 1616 } 1617 1618 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load"); 1619 1620 result = dns_db_create(zone->mctx, zone->db_argv[0], 1621 &zone->origin, (zone->type == dns_zone_stub) ? 1622 dns_dbtype_stub : dns_dbtype_zone, 1623 zone->rdclass, 1624 zone->db_argc - 1, zone->db_argv + 1, 1625 &db); 1626 1627 if (result != ISC_R_SUCCESS) { 1628 dns_zone_log(zone, ISC_LOG_ERROR, 1629 "loading zone: creating database: %s", 1630 isc_result_totext(result)); 1631 goto cleanup; 1632 } 1633 dns_db_settask(db, zone->task); 1634 1635 if (! dns_db_ispersistent(db)) { 1636 if (zone->masterfile != NULL) { 1637 result = zone_startload(db, zone, loadtime); 1638 } else { 1639 result = DNS_R_NOMASTERFILE; 1640 if (zone->type == dns_zone_master || 1641 (zone->type == dns_zone_redirect && 1642 zone->masters == NULL)) { 1643 dns_zone_log(zone, ISC_LOG_ERROR, 1644 "loading zone: " 1645 "no master file configured"); 1646 goto cleanup; 1647 } 1648 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: " 1649 "no master file configured: continuing"); 1650 } 1651 } 1652 1653 if (result == DNS_R_CONTINUE) { 1654 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING); 1655 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) 1656 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 1657 goto cleanup; 1658 } 1659 1660 result = zone_postload(zone, db, loadtime, result); 1661 1662 cleanup: 1663 UNLOCK_ZONE(zone); 1664 if (inline_secure(zone)) 1665 UNLOCK_ZONE(zone->raw); 1666 if (db != NULL) 1667 dns_db_detach(&db); 1668 return (result); 1669} 1670 1671isc_result_t 1672dns_zone_load(dns_zone_t *zone) { 1673 return (zone_load(zone, 0)); 1674} 1675 1676isc_result_t 1677dns_zone_loadnew(dns_zone_t *zone) { 1678 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT)); 1679} 1680 1681static void 1682zone_asyncload(isc_task_t *task, isc_event_t *event) { 1683 dns_asyncload_t *asl = event->ev_arg; 1684 dns_zone_t *zone = asl->zone; 1685 isc_result_t result = ISC_R_SUCCESS; 1686 1687 UNUSED(task); 1688 1689 REQUIRE(DNS_ZONE_VALID(zone)); 1690 1691 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) 1692 result = ISC_R_CANCELED; 1693 isc_event_free(&event); 1694 if (result == ISC_R_CANCELED || 1695 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) 1696 goto cleanup; 1697 1698 zone_load(zone, 0); 1699 1700 LOCK_ZONE(zone); 1701 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); 1702 UNLOCK_ZONE(zone); 1703 1704 /* Inform the zone table we've finished loading */ 1705 if (asl->loaded != NULL) 1706 (asl->loaded)(asl->loaded_arg, zone, task); 1707 1708 cleanup: 1709 isc_mem_put(zone->mctx, asl, sizeof (*asl)); 1710 dns_zone_idetach(&zone); 1711} 1712 1713isc_result_t 1714dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) { 1715 isc_event_t *e; 1716 dns_asyncload_t *asl = NULL; 1717 isc_result_t result = ISC_R_SUCCESS; 1718 1719 REQUIRE(DNS_ZONE_VALID(zone)); 1720 1721 if (zone->zmgr == NULL) 1722 return (ISC_R_FAILURE); 1723 1724 asl = isc_mem_get(zone->mctx, sizeof (*asl)); 1725 if (asl == NULL) 1726 CHECK(ISC_R_NOMEMORY); 1727 1728 asl->zone = NULL; 1729 asl->loaded = done; 1730 asl->loaded_arg = arg; 1731 1732 e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr, 1733 DNS_EVENT_ZONELOAD, 1734 zone_asyncload, asl, 1735 sizeof(isc_event_t)); 1736 if (e == NULL) 1737 CHECK(ISC_R_NOMEMORY); 1738 1739 LOCK_ZONE(zone); 1740 zone_iattach(zone, &asl->zone); 1741 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING); 1742 isc_task_send(zone->loadtask, &e); 1743 UNLOCK_ZONE(zone); 1744 1745 return (ISC_R_SUCCESS); 1746 1747 failure: 1748 if (asl != NULL) 1749 isc_mem_put(zone->mctx, asl, sizeof (*asl)); 1750 return (result); 1751} 1752 1753isc_boolean_t 1754dns__zone_loadpending(dns_zone_t *zone) { 1755 REQUIRE(DNS_ZONE_VALID(zone)); 1756 1757 return (ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))); 1758} 1759 1760isc_result_t 1761dns_zone_loadandthaw(dns_zone_t *zone) { 1762 isc_result_t result; 1763 1764 if (inline_raw(zone)) 1765 result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW); 1766 else 1767 result = zone_load(zone, DNS_ZONELOADFLAG_THAW); 1768 1769 switch (result) { 1770 case DNS_R_CONTINUE: 1771 /* Deferred thaw. */ 1772 break; 1773 case DNS_R_UPTODATE: 1774 case ISC_R_SUCCESS: 1775 case DNS_R_SEENINCLUDE: 1776 zone->update_disabled = ISC_FALSE; 1777 break; 1778 case DNS_R_NOMASTERFILE: 1779 zone->update_disabled = ISC_FALSE; 1780 break; 1781 default: 1782 /* Error, remain in disabled state. */ 1783 break; 1784 } 1785 return (result); 1786} 1787 1788static unsigned int 1789get_master_options(dns_zone_t *zone) { 1790 unsigned int options; 1791 1792 options = DNS_MASTER_ZONE; 1793 if (zone->type == dns_zone_slave || 1794 (zone->type == dns_zone_redirect && zone->masters == NULL)) 1795 options |= DNS_MASTER_SLAVE; 1796 if (zone->type == dns_zone_key) 1797 options |= DNS_MASTER_KEY; 1798 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) 1799 options |= DNS_MASTER_CHECKNS; 1800 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) 1801 options |= DNS_MASTER_FATALNS; 1802 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) 1803 options |= DNS_MASTER_CHECKNAMES; 1804 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) 1805 options |= DNS_MASTER_CHECKNAMESFAIL; 1806 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) 1807 options |= DNS_MASTER_CHECKMX; 1808 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) 1809 options |= DNS_MASTER_CHECKMXFAIL; 1810 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) 1811 options |= DNS_MASTER_CHECKWILDCARD; 1812 if (inline_secure(zone) || (zone->type == dns_zone_master && 1813 ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) || 1814 zone->ssutable != NULL))) 1815 options |= DNS_MASTER_RESIGN; 1816 return (options); 1817} 1818 1819static void 1820zone_gotreadhandle(isc_task_t *task, isc_event_t *event) { 1821 dns_load_t *load = event->ev_arg; 1822 isc_result_t result = ISC_R_SUCCESS; 1823 unsigned int options; 1824 1825 REQUIRE(DNS_LOAD_VALID(load)); 1826 1827 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) 1828 result = ISC_R_CANCELED; 1829 isc_event_free(&event); 1830 if (result == ISC_R_CANCELED) 1831 goto fail; 1832 1833 options = get_master_options(load->zone); 1834 1835 result = dns_master_loadfileinc3(load->zone->masterfile, 1836 dns_db_origin(load->db), 1837 dns_db_origin(load->db), 1838 load->zone->rdclass, options, 1839 load->zone->sigresigninginterval, 1840 &load->callbacks, task, 1841 zone_loaddone, load, 1842 &load->zone->lctx, load->zone->mctx, 1843 load->zone->masterformat); 1844 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE && 1845 result != DNS_R_SEENINCLUDE) 1846 goto fail; 1847 return; 1848 1849 fail: 1850 zone_loaddone(load, result); 1851} 1852 1853static void 1854get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) { 1855 isc_result_t result; 1856 1857 LOCK(&raw->lock); 1858 if (raw->db != NULL) { 1859 result = zone_get_from_db(raw, raw->db, NULL, NULL, 1860 &rawdata->sourceserial, 1861 NULL, NULL, NULL, NULL, 1862 NULL); 1863 if (result == ISC_R_SUCCESS) 1864 rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET; 1865 } 1866 UNLOCK(&raw->lock); 1867} 1868 1869static void 1870zone_gotwritehandle(isc_task_t *task, isc_event_t *event) { 1871 const char me[] = "zone_gotwritehandle"; 1872 dns_zone_t *zone = event->ev_arg; 1873 isc_result_t result = ISC_R_SUCCESS; 1874 dns_dbversion_t *version = NULL; 1875 dns_masterrawheader_t rawdata; 1876 1877 REQUIRE(DNS_ZONE_VALID(zone)); 1878 INSIST(task == zone->task); 1879 ENTER; 1880 1881 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) 1882 result = ISC_R_CANCELED; 1883 isc_event_free(&event); 1884 if (result == ISC_R_CANCELED) 1885 goto fail; 1886 1887 LOCK_ZONE(zone); 1888 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1889 if (zone->db != NULL) { 1890 dns_db_currentversion(zone->db, &version); 1891 dns_master_initrawheader(&rawdata); 1892 if (inline_secure(zone)) 1893 get_raw_serial(zone->raw, &rawdata); 1894 result = dns_master_dumpinc3(zone->mctx, zone->db, version, 1895 &dns_master_style_default, 1896 zone->masterfile, zone->task, 1897 dump_done, zone, &zone->dctx, 1898 zone->masterformat, &rawdata); 1899 dns_db_closeversion(zone->db, &version, ISC_FALSE); 1900 } else 1901 result = ISC_R_CANCELED; 1902 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1903 UNLOCK_ZONE(zone); 1904 if (result != DNS_R_CONTINUE) 1905 goto fail; 1906 return; 1907 1908 fail: 1909 dump_done(zone, result); 1910} 1911 1912/* 1913 * Save the raw serial number for inline-signing zones. 1914 * (XXX: Other information from the header will be used 1915 * for other purposes in the future, but for now this is 1916 * all we're interested in.) 1917 */ 1918static void 1919zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { 1920 if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0) 1921 return; 1922 1923 zone->sourceserial = header->sourceserial; 1924 zone->sourceserialset = ISC_TRUE; 1925} 1926 1927void 1928dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { 1929 if (zone == NULL) 1930 return; 1931 1932 LOCK_ZONE(zone); 1933 zone_setrawdata(zone, header); 1934 UNLOCK_ZONE(zone); 1935} 1936 1937static isc_result_t 1938zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { 1939 dns_load_t *load; 1940 isc_result_t result; 1941 isc_result_t tresult; 1942 unsigned int options; 1943 1944 options = get_master_options(zone); 1945 1946 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) 1947 options |= DNS_MASTER_MANYERRORS; 1948 1949 if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) { 1950 load = isc_mem_get(zone->mctx, sizeof(*load)); 1951 if (load == NULL) 1952 return (ISC_R_NOMEMORY); 1953 1954 load->mctx = NULL; 1955 load->zone = NULL; 1956 load->db = NULL; 1957 load->loadtime = loadtime; 1958 load->magic = LOAD_MAGIC; 1959 1960 isc_mem_attach(zone->mctx, &load->mctx); 1961 zone_iattach(zone, &load->zone); 1962 dns_db_attach(db, &load->db); 1963 dns_rdatacallbacks_init(&load->callbacks); 1964 load->callbacks.rawdata = zone_setrawdata; 1965 zone_iattach(zone, &load->callbacks.zone); 1966 result = dns_db_beginload(db, &load->callbacks.add, 1967 &load->callbacks.add_private); 1968 if (result != ISC_R_SUCCESS) 1969 goto cleanup; 1970 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->loadtask, 1971 zone_gotreadhandle, load, 1972 &zone->readio); 1973 if (result != ISC_R_SUCCESS) { 1974 /* 1975 * We can't report multiple errors so ignore 1976 * the result of dns_db_endload(). 1977 */ 1978 (void)dns_db_endload(load->db, 1979 &load->callbacks.add_private); 1980 goto cleanup; 1981 } else 1982 result = DNS_R_CONTINUE; 1983 } else { 1984 dns_rdatacallbacks_t callbacks; 1985 1986 dns_rdatacallbacks_init(&callbacks); 1987 callbacks.rawdata = zone_setrawdata; 1988 zone_iattach(zone, &callbacks.zone); 1989 result = dns_db_beginload(db, &callbacks.add, 1990 &callbacks.add_private); 1991 if (result != ISC_R_SUCCESS) { 1992 zone_idetach(&callbacks.zone); 1993 return (result); 1994 } 1995 result = dns_master_loadfile3(zone->masterfile, 1996 &zone->origin, &zone->origin, 1997 zone->rdclass, options, 1998 zone->sigresigninginterval, 1999 &callbacks, zone->mctx, 2000 zone->masterformat); 2001 tresult = dns_db_endload(db, &callbacks.add_private); 2002 if (result == ISC_R_SUCCESS) 2003 result = tresult; 2004 zone_idetach(&callbacks.zone); 2005 } 2006 2007 return (result); 2008 2009 cleanup: 2010 load->magic = 0; 2011 dns_db_detach(&load->db); 2012 zone_idetach(&load->zone); 2013 zone_idetach(&load->callbacks.zone); 2014 isc_mem_detach(&load->mctx); 2015 isc_mem_put(zone->mctx, load, sizeof(*load)); 2016 return (result); 2017} 2018 2019static isc_boolean_t 2020zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2021 dns_name_t *owner) 2022{ 2023 isc_result_t result; 2024 char ownerbuf[DNS_NAME_FORMATSIZE]; 2025 char namebuf[DNS_NAME_FORMATSIZE]; 2026 char altbuf[DNS_NAME_FORMATSIZE]; 2027 dns_fixedname_t fixed; 2028 dns_name_t *foundname; 2029 int level; 2030 2031 /* 2032 * "." means the services does not exist. 2033 */ 2034 if (dns_name_equal(name, dns_rootname)) 2035 return (ISC_TRUE); 2036 2037 /* 2038 * Outside of zone. 2039 */ 2040 if (!dns_name_issubdomain(name, &zone->origin)) { 2041 if (zone->checkmx != NULL) 2042 return ((zone->checkmx)(zone, name, owner)); 2043 return (ISC_TRUE); 2044 } 2045 2046 if (zone->type == dns_zone_master) 2047 level = ISC_LOG_ERROR; 2048 else 2049 level = ISC_LOG_WARNING; 2050 2051 dns_fixedname_init(&fixed); 2052 foundname = dns_fixedname_name(&fixed); 2053 2054 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 2055 0, 0, NULL, foundname, NULL, NULL); 2056 if (result == ISC_R_SUCCESS) 2057 return (ISC_TRUE); 2058 2059 if (result == DNS_R_NXRRSET) { 2060 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 2061 0, 0, NULL, foundname, NULL, NULL); 2062 if (result == ISC_R_SUCCESS) 2063 return (ISC_TRUE); 2064 } 2065 2066 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2067 dns_name_format(name, namebuf, sizeof namebuf); 2068 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2069 result == DNS_R_EMPTYNAME) { 2070 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) 2071 level = ISC_LOG_WARNING; 2072 dns_zone_log(zone, level, 2073 "%s/MX '%s' has no address records (A or AAAA)", 2074 ownerbuf, namebuf); 2075 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2076 } 2077 2078 if (result == DNS_R_CNAME) { 2079 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 2080 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2081 level = ISC_LOG_WARNING; 2082 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2083 dns_zone_log(zone, level, 2084 "%s/MX '%s' is a CNAME (illegal)", 2085 ownerbuf, namebuf); 2086 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2087 } 2088 2089 if (result == DNS_R_DNAME) { 2090 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 2091 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 2092 level = ISC_LOG_WARNING; 2093 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { 2094 dns_name_format(foundname, altbuf, sizeof altbuf); 2095 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME" 2096 " '%s' (illegal)", ownerbuf, namebuf, 2097 altbuf); 2098 } 2099 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2100 } 2101 2102 if (zone->checkmx != NULL && result == DNS_R_DELEGATION) 2103 return ((zone->checkmx)(zone, name, owner)); 2104 2105 return (ISC_TRUE); 2106} 2107 2108static isc_boolean_t 2109zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2110 dns_name_t *owner) 2111{ 2112 isc_result_t result; 2113 char ownerbuf[DNS_NAME_FORMATSIZE]; 2114 char namebuf[DNS_NAME_FORMATSIZE]; 2115 char altbuf[DNS_NAME_FORMATSIZE]; 2116 dns_fixedname_t fixed; 2117 dns_name_t *foundname; 2118 int level; 2119 2120 /* 2121 * "." means the services does not exist. 2122 */ 2123 if (dns_name_equal(name, dns_rootname)) 2124 return (ISC_TRUE); 2125 2126 /* 2127 * Outside of zone. 2128 */ 2129 if (!dns_name_issubdomain(name, &zone->origin)) { 2130 if (zone->checksrv != NULL) 2131 return ((zone->checksrv)(zone, name, owner)); 2132 return (ISC_TRUE); 2133 } 2134 2135 if (zone->type == dns_zone_master) 2136 level = ISC_LOG_ERROR; 2137 else 2138 level = ISC_LOG_WARNING; 2139 2140 dns_fixedname_init(&fixed); 2141 foundname = dns_fixedname_name(&fixed); 2142 2143 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 2144 0, 0, NULL, foundname, NULL, NULL); 2145 if (result == ISC_R_SUCCESS) 2146 return (ISC_TRUE); 2147 2148 if (result == DNS_R_NXRRSET) { 2149 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 2150 0, 0, NULL, foundname, NULL, NULL); 2151 if (result == ISC_R_SUCCESS) 2152 return (ISC_TRUE); 2153 } 2154 2155 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2156 dns_name_format(name, namebuf, sizeof namebuf); 2157 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2158 result == DNS_R_EMPTYNAME) { 2159 dns_zone_log(zone, level, 2160 "%s/SRV '%s' has no address records (A or AAAA)", 2161 ownerbuf, namebuf); 2162 /* XXX950 make fatal for 9.5.0. */ 2163 return (ISC_TRUE); 2164 } 2165 2166 if (result == DNS_R_CNAME) { 2167 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 2168 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2169 level = ISC_LOG_WARNING; 2170 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2171 dns_zone_log(zone, level, 2172 "%s/SRV '%s' is a CNAME (illegal)", 2173 ownerbuf, namebuf); 2174 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2175 } 2176 2177 if (result == DNS_R_DNAME) { 2178 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 2179 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 2180 level = ISC_LOG_WARNING; 2181 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { 2182 dns_name_format(foundname, altbuf, sizeof altbuf); 2183 dns_zone_log(zone, level, "%s/SRV '%s' is below a " 2184 "DNAME '%s' (illegal)", ownerbuf, namebuf, 2185 altbuf); 2186 } 2187 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 2188 } 2189 2190 if (zone->checksrv != NULL && result == DNS_R_DELEGATION) 2191 return ((zone->checksrv)(zone, name, owner)); 2192 2193 return (ISC_TRUE); 2194} 2195 2196static isc_boolean_t 2197zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 2198 dns_name_t *owner) 2199{ 2200 isc_boolean_t answer = ISC_TRUE; 2201 isc_result_t result, tresult; 2202 char ownerbuf[DNS_NAME_FORMATSIZE]; 2203 char namebuf[DNS_NAME_FORMATSIZE]; 2204 char altbuf[DNS_NAME_FORMATSIZE]; 2205 dns_fixedname_t fixed; 2206 dns_name_t *foundname; 2207 dns_rdataset_t a; 2208 dns_rdataset_t aaaa; 2209 int level; 2210 2211 /* 2212 * Outside of zone. 2213 */ 2214 if (!dns_name_issubdomain(name, &zone->origin)) { 2215 if (zone->checkns != NULL) 2216 return ((zone->checkns)(zone, name, owner, NULL, NULL)); 2217 return (ISC_TRUE); 2218 } 2219 2220 if (zone->type == dns_zone_master) 2221 level = ISC_LOG_ERROR; 2222 else 2223 level = ISC_LOG_WARNING; 2224 2225 dns_fixedname_init(&fixed); 2226 foundname = dns_fixedname_name(&fixed); 2227 dns_rdataset_init(&a); 2228 dns_rdataset_init(&aaaa); 2229 2230 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 2231 DNS_DBFIND_GLUEOK, 0, NULL, 2232 foundname, &a, NULL); 2233 2234 if (result == ISC_R_SUCCESS) { 2235 dns_rdataset_disassociate(&a); 2236 return (ISC_TRUE); 2237 } else if (result == DNS_R_DELEGATION) 2238 dns_rdataset_disassociate(&a); 2239 2240 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION || 2241 result == DNS_R_GLUE) { 2242 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 2243 DNS_DBFIND_GLUEOK, 0, NULL, 2244 foundname, &aaaa, NULL); 2245 if (tresult == ISC_R_SUCCESS) { 2246 dns_rdataset_disassociate(&aaaa); 2247 return (ISC_TRUE); 2248 } 2249 if (tresult == DNS_R_DELEGATION) 2250 dns_rdataset_disassociate(&aaaa); 2251 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) { 2252 /* 2253 * Check glue against child zone. 2254 */ 2255 if (zone->checkns != NULL) 2256 answer = (zone->checkns)(zone, name, owner, 2257 &a, &aaaa); 2258 if (dns_rdataset_isassociated(&a)) 2259 dns_rdataset_disassociate(&a); 2260 if (dns_rdataset_isassociated(&aaaa)) 2261 dns_rdataset_disassociate(&aaaa); 2262 return (answer); 2263 } 2264 } 2265 2266 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2267 dns_name_format(name, namebuf, sizeof namebuf); 2268 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2269 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) { 2270 const char *what; 2271 isc_boolean_t required = ISC_FALSE; 2272 if (dns_name_issubdomain(name, owner)) { 2273 what = "REQUIRED GLUE "; 2274 required = ISC_TRUE; 2275 } else if (result == DNS_R_DELEGATION) 2276 what = "SIBLING GLUE "; 2277 else 2278 what = ""; 2279 2280 if (result != DNS_R_DELEGATION || required || 2281 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) { 2282 dns_zone_log(zone, level, "%s/NS '%s' has no %s" 2283 "address records (A or AAAA)", 2284 ownerbuf, namebuf, what); 2285 /* 2286 * Log missing address record. 2287 */ 2288 if (result == DNS_R_DELEGATION && zone->checkns != NULL) 2289 (void)(zone->checkns)(zone, name, owner, 2290 &a, &aaaa); 2291 /* XXX950 make fatal for 9.5.0. */ 2292 /* answer = ISC_FALSE; */ 2293 } 2294 } else if (result == DNS_R_CNAME) { 2295 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)", 2296 ownerbuf, namebuf); 2297 /* XXX950 make fatal for 9.5.0. */ 2298 /* answer = ISC_FALSE; */ 2299 } else if (result == DNS_R_DNAME) { 2300 dns_name_format(foundname, altbuf, sizeof altbuf); 2301 dns_zone_log(zone, level, 2302 "%s/NS '%s' is below a DNAME '%s' (illegal)", 2303 ownerbuf, namebuf, altbuf); 2304 /* XXX950 make fatal for 9.5.0. */ 2305 /* answer = ISC_FALSE; */ 2306 } 2307 2308 if (dns_rdataset_isassociated(&a)) 2309 dns_rdataset_disassociate(&a); 2310 if (dns_rdataset_isassociated(&aaaa)) 2311 dns_rdataset_disassociate(&aaaa); 2312 return (answer); 2313} 2314 2315static isc_boolean_t 2316zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner, 2317 dns_rdataset_t *rdataset) 2318{ 2319 dns_rdataset_t tmprdataset; 2320 isc_result_t result; 2321 isc_boolean_t answer = ISC_TRUE; 2322 isc_boolean_t format = ISC_TRUE; 2323 int level = ISC_LOG_WARNING; 2324 char ownerbuf[DNS_NAME_FORMATSIZE]; 2325 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 2326 unsigned int count1 = 0; 2327 2328 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL)) 2329 level = ISC_LOG_ERROR; 2330 2331 dns_rdataset_init(&tmprdataset); 2332 for (result = dns_rdataset_first(rdataset); 2333 result == ISC_R_SUCCESS; 2334 result = dns_rdataset_next(rdataset)) { 2335 dns_rdata_t rdata1 = DNS_RDATA_INIT; 2336 unsigned int count2 = 0; 2337 2338 count1++; 2339 dns_rdataset_current(rdataset, &rdata1); 2340 dns_rdataset_clone(rdataset, &tmprdataset); 2341 for (result = dns_rdataset_first(&tmprdataset); 2342 result == ISC_R_SUCCESS; 2343 result = dns_rdataset_next(&tmprdataset)) { 2344 dns_rdata_t rdata2 = DNS_RDATA_INIT; 2345 count2++; 2346 if (count1 >= count2) 2347 continue; 2348 dns_rdataset_current(&tmprdataset, &rdata2); 2349 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) { 2350 if (format) { 2351 dns_name_format(owner, ownerbuf, 2352 sizeof ownerbuf); 2353 dns_rdatatype_format(rdata1.type, 2354 typebuf, 2355 sizeof(typebuf)); 2356 format = ISC_FALSE; 2357 } 2358 dns_zone_log(zone, level, "%s/%s has " 2359 "semantically identical records", 2360 ownerbuf, typebuf); 2361 if (level == ISC_LOG_ERROR) 2362 answer = ISC_FALSE; 2363 break; 2364 } 2365 } 2366 dns_rdataset_disassociate(&tmprdataset); 2367 if (!format) 2368 break; 2369 } 2370 return (answer); 2371} 2372 2373static isc_boolean_t 2374zone_check_dup(dns_zone_t *zone, dns_db_t *db) { 2375 dns_dbiterator_t *dbiterator = NULL; 2376 dns_dbnode_t *node = NULL; 2377 dns_fixedname_t fixed; 2378 dns_name_t *name; 2379 dns_rdataset_t rdataset; 2380 dns_rdatasetiter_t *rdsit = NULL; 2381 isc_boolean_t ok = ISC_TRUE; 2382 isc_result_t result; 2383 2384 dns_fixedname_init(&fixed); 2385 name = dns_fixedname_name(&fixed); 2386 dns_rdataset_init(&rdataset); 2387 2388 result = dns_db_createiterator(db, 0, &dbiterator); 2389 if (result != ISC_R_SUCCESS) 2390 return (ISC_TRUE); 2391 2392 for (result = dns_dbiterator_first(dbiterator); 2393 result == ISC_R_SUCCESS; 2394 result = dns_dbiterator_next(dbiterator)) { 2395 result = dns_dbiterator_current(dbiterator, &node, name); 2396 if (result != ISC_R_SUCCESS) 2397 continue; 2398 2399 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit); 2400 if (result != ISC_R_SUCCESS) 2401 continue; 2402 2403 for (result = dns_rdatasetiter_first(rdsit); 2404 result == ISC_R_SUCCESS; 2405 result = dns_rdatasetiter_next(rdsit)) { 2406 dns_rdatasetiter_current(rdsit, &rdataset); 2407 if (!zone_rrset_check_dup(zone, name, &rdataset)) 2408 ok = ISC_FALSE; 2409 dns_rdataset_disassociate(&rdataset); 2410 } 2411 dns_rdatasetiter_destroy(&rdsit); 2412 dns_db_detachnode(db, &node); 2413 } 2414 2415 if (node != NULL) 2416 dns_db_detachnode(db, &node); 2417 dns_dbiterator_destroy(&dbiterator); 2418 2419 return (ok); 2420} 2421 2422static isc_boolean_t 2423integrity_checks(dns_zone_t *zone, dns_db_t *db) { 2424 dns_dbiterator_t *dbiterator = NULL; 2425 dns_dbnode_t *node = NULL; 2426 dns_rdataset_t rdataset; 2427 dns_fixedname_t fixed; 2428 dns_fixedname_t fixedbottom; 2429 dns_rdata_mx_t mx; 2430 dns_rdata_ns_t ns; 2431 dns_rdata_in_srv_t srv; 2432 dns_rdata_t rdata; 2433 dns_name_t *name; 2434 dns_name_t *bottom; 2435 isc_result_t result; 2436 isc_boolean_t ok = ISC_TRUE; 2437 2438 dns_fixedname_init(&fixed); 2439 name = dns_fixedname_name(&fixed); 2440 dns_fixedname_init(&fixedbottom); 2441 bottom = dns_fixedname_name(&fixedbottom); 2442 dns_rdataset_init(&rdataset); 2443 dns_rdata_init(&rdata); 2444 2445 result = dns_db_createiterator(db, 0, &dbiterator); 2446 if (result != ISC_R_SUCCESS) 2447 return (ISC_TRUE); 2448 2449 result = dns_dbiterator_first(dbiterator); 2450 while (result == ISC_R_SUCCESS) { 2451 result = dns_dbiterator_current(dbiterator, &node, name); 2452 if (result != ISC_R_SUCCESS) 2453 goto cleanup; 2454 2455 /* 2456 * Is this name visible in the zone? 2457 */ 2458 if (!dns_name_issubdomain(name, &zone->origin) || 2459 (dns_name_countlabels(bottom) > 0 && 2460 dns_name_issubdomain(name, bottom))) 2461 goto next; 2462 2463 /* 2464 * Don't check the NS records at the origin. 2465 */ 2466 if (dns_name_equal(name, &zone->origin)) 2467 goto checkmx; 2468 2469 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns, 2470 0, 0, &rdataset, NULL); 2471 if (result != ISC_R_SUCCESS) 2472 goto checkmx; 2473 /* 2474 * Remember bottom of zone. 2475 */ 2476 dns_name_copy(name, bottom, NULL); 2477 2478 result = dns_rdataset_first(&rdataset); 2479 while (result == ISC_R_SUCCESS) { 2480 dns_rdataset_current(&rdataset, &rdata); 2481 result = dns_rdata_tostruct(&rdata, &ns, NULL); 2482 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2483 if (!zone_check_glue(zone, db, &ns.name, name)) 2484 ok = ISC_FALSE; 2485 dns_rdata_reset(&rdata); 2486 result = dns_rdataset_next(&rdataset); 2487 } 2488 dns_rdataset_disassociate(&rdataset); 2489 goto next; 2490 2491 checkmx: 2492 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx, 2493 0, 0, &rdataset, NULL); 2494 if (result != ISC_R_SUCCESS) 2495 goto checksrv; 2496 result = dns_rdataset_first(&rdataset); 2497 while (result == ISC_R_SUCCESS) { 2498 dns_rdataset_current(&rdataset, &rdata); 2499 result = dns_rdata_tostruct(&rdata, &mx, NULL); 2500 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2501 if (!zone_check_mx(zone, db, &mx.mx, name)) 2502 ok = ISC_FALSE; 2503 dns_rdata_reset(&rdata); 2504 result = dns_rdataset_next(&rdataset); 2505 } 2506 dns_rdataset_disassociate(&rdataset); 2507 2508 checksrv: 2509 if (zone->rdclass != dns_rdataclass_in) 2510 goto next; 2511 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv, 2512 0, 0, &rdataset, NULL); 2513 if (result != ISC_R_SUCCESS) 2514 goto next; 2515 result = dns_rdataset_first(&rdataset); 2516 while (result == ISC_R_SUCCESS) { 2517 dns_rdataset_current(&rdataset, &rdata); 2518 result = dns_rdata_tostruct(&rdata, &srv, NULL); 2519 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2520 if (!zone_check_srv(zone, db, &srv.target, name)) 2521 ok = ISC_FALSE; 2522 dns_rdata_reset(&rdata); 2523 result = dns_rdataset_next(&rdataset); 2524 } 2525 dns_rdataset_disassociate(&rdataset); 2526 2527 next: 2528 dns_db_detachnode(db, &node); 2529 result = dns_dbiterator_next(dbiterator); 2530 } 2531 2532 cleanup: 2533 if (node != NULL) 2534 dns_db_detachnode(db, &node); 2535 dns_dbiterator_destroy(&dbiterator); 2536 2537 return (ok); 2538} 2539 2540/* 2541 * OpenSSL verification of RSA keys with exponent 3 is known to be 2542 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn 2543 * if they are in use. 2544 */ 2545static void 2546zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) { 2547 dns_dbnode_t *node = NULL; 2548 dns_dbversion_t *version = NULL; 2549 dns_rdata_dnskey_t dnskey; 2550 dns_rdata_t rdata = DNS_RDATA_INIT; 2551 dns_rdataset_t rdataset; 2552 isc_result_t result; 2553 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE; 2554 const char *algorithm; 2555 2556 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 2557 if (result != ISC_R_SUCCESS) 2558 goto cleanup; 2559 2560 dns_db_currentversion(db, &version); 2561 dns_rdataset_init(&rdataset); 2562 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 2563 dns_rdatatype_none, 0, &rdataset, NULL); 2564 if (result != ISC_R_SUCCESS) 2565 goto cleanup; 2566 2567 for (result = dns_rdataset_first(&rdataset); 2568 result == ISC_R_SUCCESS; 2569 result = dns_rdataset_next(&rdataset)) 2570 { 2571 dns_rdataset_current(&rdataset, &rdata); 2572 result = dns_rdata_tostruct(&rdata, &dnskey, NULL); 2573 INSIST(result == ISC_R_SUCCESS); 2574 2575 if ((dnskey.algorithm == DST_ALG_RSASHA1 || 2576 dnskey.algorithm == DST_ALG_RSAMD5) && 2577 dnskey.datalen > 1 && dnskey.data[0] == 1 && 2578 dnskey.data[1] == 3) 2579 { 2580 if (dnskey.algorithm == DST_ALG_RSASHA1) { 2581 logit = !foundrsa; 2582 foundrsa = ISC_TRUE; 2583 algorithm = "RSASHA1"; 2584 } else { 2585 logit = !foundmd5; 2586 foundmd5 = ISC_TRUE; 2587 algorithm = "RSAMD5"; 2588 } 2589 if (logit) 2590 dns_zone_log(zone, ISC_LOG_WARNING, 2591 "weak %s (%u) key found " 2592 "(exponent=3)", algorithm, 2593 dnskey.algorithm); 2594 if (foundrsa && foundmd5) 2595 break; 2596 } 2597 dns_rdata_reset(&rdata); 2598 } 2599 dns_rdataset_disassociate(&rdataset); 2600 2601 cleanup: 2602 if (node != NULL) 2603 dns_db_detachnode(db, &node); 2604 if (version != NULL) 2605 dns_db_closeversion(db, &version, ISC_FALSE); 2606} 2607 2608static void 2609resume_signingwithkey(dns_zone_t *zone) { 2610 dns_dbnode_t *node = NULL; 2611 dns_dbversion_t *version = NULL; 2612 dns_rdata_t rdata = DNS_RDATA_INIT; 2613 dns_rdataset_t rdataset; 2614 isc_result_t result; 2615 2616 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node); 2617 if (result != ISC_R_SUCCESS) 2618 goto cleanup; 2619 2620 dns_db_currentversion(zone->db, &version); 2621 dns_rdataset_init(&rdataset); 2622 result = dns_db_findrdataset(zone->db, node, version, 2623 zone->privatetype, 2624 dns_rdatatype_none, 0, 2625 &rdataset, NULL); 2626 if (result != ISC_R_SUCCESS) { 2627 INSIST(!dns_rdataset_isassociated(&rdataset)); 2628 goto cleanup; 2629 } 2630 2631 for (result = dns_rdataset_first(&rdataset); 2632 result == ISC_R_SUCCESS; 2633 result = dns_rdataset_next(&rdataset)) 2634 { 2635 dns_rdataset_current(&rdataset, &rdata); 2636 if (rdata.length != 5 || 2637 rdata.data[0] == 0 || rdata.data[4] != 0) { 2638 dns_rdata_reset(&rdata); 2639 continue; 2640 } 2641 2642 result = zone_signwithkey(zone, rdata.data[0], 2643 (rdata.data[1] << 8) | rdata.data[2], 2644 ISC_TF(rdata.data[3])); 2645 if (result != ISC_R_SUCCESS) { 2646 dns_zone_log(zone, ISC_LOG_ERROR, 2647 "zone_signwithkey failed: %s", 2648 dns_result_totext(result)); 2649 } 2650 dns_rdata_reset(&rdata); 2651 } 2652 dns_rdataset_disassociate(&rdataset); 2653 2654 cleanup: 2655 if (node != NULL) 2656 dns_db_detachnode(zone->db, &node); 2657 if (version != NULL) 2658 dns_db_closeversion(zone->db, &version, ISC_FALSE); 2659} 2660 2661static isc_result_t 2662zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 2663 dns_nsec3chain_t *nsec3chain, *current; 2664 dns_dbversion_t *version = NULL; 2665 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; 2666 isc_result_t result; 2667 isc_time_t now; 2668 unsigned int options = 0; 2669 char saltbuf[255*2+1]; 2670 char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")]; 2671 int i; 2672 2673 dns_db_currentversion(zone->db, &version); 2674 result = dns_nsec_nseconly(zone->db, version, &nseconly); 2675 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 2676 dns_db_closeversion(zone->db, &version, ISC_FALSE); 2677 if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) 2678 return (ISC_R_SUCCESS); 2679 2680 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain); 2681 if (nsec3chain == NULL) 2682 return (ISC_R_NOMEMORY); 2683 2684 nsec3chain->magic = 0; 2685 nsec3chain->done = ISC_FALSE; 2686 nsec3chain->db = NULL; 2687 nsec3chain->dbiterator = NULL; 2688 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass; 2689 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype; 2690 nsec3chain->nsec3param.hash = nsec3param->hash; 2691 nsec3chain->nsec3param.iterations = nsec3param->iterations; 2692 nsec3chain->nsec3param.flags = nsec3param->flags; 2693 nsec3chain->nsec3param.salt_length = nsec3param->salt_length; 2694 memcpy(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length); 2695 nsec3chain->nsec3param.salt = nsec3chain->salt; 2696 nsec3chain->seen_nsec = ISC_FALSE; 2697 nsec3chain->delete_nsec = ISC_FALSE; 2698 nsec3chain->save_delete_nsec = ISC_FALSE; 2699 2700 if (nsec3param->flags == 0) 2701 strlcpy(flags, "NONE", sizeof(flags)); 2702 else { 2703 flags[0] = '\0'; 2704 if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) 2705 strlcat(flags, "REMOVE", sizeof(flags)); 2706 if (nsec3param->flags & DNS_NSEC3FLAG_INITIAL) { 2707 if (flags[0] == '\0') 2708 strlcpy(flags, "INITIAL", sizeof(flags)); 2709 else 2710 strlcat(flags, "|INITIAL", sizeof(flags)); 2711 } 2712 if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) { 2713 if (flags[0] == '\0') 2714 strlcpy(flags, "CREATE", sizeof(flags)); 2715 else 2716 strlcat(flags, "|CREATE", sizeof(flags)); 2717 } 2718 if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) { 2719 if (flags[0] == '\0') 2720 strlcpy(flags, "NONSEC", sizeof(flags)); 2721 else 2722 strlcat(flags, "|NONSEC", sizeof(flags)); 2723 } 2724 if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) { 2725 if (flags[0] == '\0') 2726 strlcpy(flags, "OPTOUT", sizeof(flags)); 2727 else 2728 strlcat(flags, "|OPTOUT", sizeof(flags)); 2729 } 2730 } 2731 if (nsec3param->salt_length == 0) 2732 strlcpy(saltbuf, "-", sizeof(saltbuf)); 2733 else 2734 for (i = 0; i < nsec3param->salt_length; i++) 2735 sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]); 2736 dns_zone_log(zone, ISC_LOG_INFO, 2737 "zone_addnsec3chain(%u,%s,%u,%s)", 2738 nsec3param->hash, flags, nsec3param->iterations, 2739 saltbuf); 2740 2741 for (current = ISC_LIST_HEAD(zone->nsec3chain); 2742 current != NULL; 2743 current = ISC_LIST_NEXT(current, link)) { 2744 if (current->db == zone->db && 2745 current->nsec3param.hash == nsec3param->hash && 2746 current->nsec3param.iterations == nsec3param->iterations && 2747 current->nsec3param.salt_length == nsec3param->salt_length 2748 && !memcmp(current->nsec3param.salt, nsec3param->salt, 2749 nsec3param->salt_length)) 2750 current->done = ISC_TRUE; 2751 } 2752 2753 if (zone->db != NULL) { 2754 dns_db_attach(zone->db, &nsec3chain->db); 2755 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) 2756 options = DNS_DB_NONSEC3; 2757 result = dns_db_createiterator(nsec3chain->db, options, 2758 &nsec3chain->dbiterator); 2759 if (result == ISC_R_SUCCESS) 2760 dns_dbiterator_first(nsec3chain->dbiterator); 2761 if (result == ISC_R_SUCCESS) { 2762 dns_dbiterator_pause(nsec3chain->dbiterator); 2763 ISC_LIST_INITANDAPPEND(zone->nsec3chain, 2764 nsec3chain, link); 2765 nsec3chain = NULL; 2766 if (isc_time_isepoch(&zone->nsec3chaintime)) { 2767 TIME_NOW(&now); 2768 zone->nsec3chaintime = now; 2769 if (zone->task != NULL) 2770 zone_settimer(zone, &now); 2771 } 2772 } 2773 } else 2774 result = ISC_R_NOTFOUND; 2775 2776 if (nsec3chain != NULL) { 2777 if (nsec3chain->db != NULL) 2778 dns_db_detach(&nsec3chain->db); 2779 if (nsec3chain->dbiterator != NULL) 2780 dns_dbiterator_destroy(&nsec3chain->dbiterator); 2781 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 2782 } 2783 return (result); 2784} 2785 2786static void 2787resume_addnsec3chain(dns_zone_t *zone) { 2788 dns_dbnode_t *node = NULL; 2789 dns_dbversion_t *version = NULL; 2790 dns_rdataset_t rdataset; 2791 isc_result_t result; 2792 dns_rdata_nsec3param_t nsec3param; 2793 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; 2794 2795 if (zone->privatetype == 0) 2796 return; 2797 2798 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node); 2799 if (result != ISC_R_SUCCESS) 2800 goto cleanup; 2801 2802 dns_db_currentversion(zone->db, &version); 2803 2804 result = dns_nsec_nseconly(zone->db, version, &nseconly); 2805 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 2806 2807 dns_rdataset_init(&rdataset); 2808 result = dns_db_findrdataset(zone->db, node, version, 2809 zone->privatetype, dns_rdatatype_none, 2810 0, &rdataset, NULL); 2811 if (result != ISC_R_SUCCESS) { 2812 INSIST(!dns_rdataset_isassociated(&rdataset)); 2813 goto cleanup; 2814 } 2815 2816 for (result = dns_rdataset_first(&rdataset); 2817 result == ISC_R_SUCCESS; 2818 result = dns_rdataset_next(&rdataset)) 2819 { 2820 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 2821 dns_rdata_t rdata = DNS_RDATA_INIT; 2822 dns_rdata_t private = DNS_RDATA_INIT; 2823 2824 dns_rdataset_current(&rdataset, &private); 2825 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 2826 sizeof(buf))) 2827 continue; 2828 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 2829 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2830 if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) || 2831 ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok)) 2832 { 2833 result = zone_addnsec3chain(zone, &nsec3param); 2834 if (result != ISC_R_SUCCESS) { 2835 dns_zone_log(zone, ISC_LOG_ERROR, 2836 "zone_addnsec3chain failed: %s", 2837 dns_result_totext(result)); 2838 } 2839 } 2840 } 2841 dns_rdataset_disassociate(&rdataset); 2842 cleanup: 2843 if (node != NULL) 2844 dns_db_detachnode(zone->db, &node); 2845 if (version != NULL) 2846 dns_db_closeversion(zone->db, &version, ISC_FALSE); 2847} 2848 2849static void 2850set_resigntime(dns_zone_t *zone) { 2851 dns_rdataset_t rdataset; 2852 dns_fixedname_t fixed; 2853 unsigned int resign; 2854 isc_result_t result; 2855 isc_uint32_t nanosecs; 2856 2857 dns_rdataset_init(&rdataset); 2858 dns_fixedname_init(&fixed); 2859 result = dns_db_getsigningtime(zone->db, &rdataset, 2860 dns_fixedname_name(&fixed)); 2861 if (result != ISC_R_SUCCESS) { 2862 isc_time_settoepoch(&zone->resigntime); 2863 return; 2864 } 2865 resign = rdataset.resign; 2866 dns_rdataset_disassociate(&rdataset); 2867 isc_random_get(&nanosecs); 2868 nanosecs %= 1000000000; 2869 isc_time_set(&zone->resigntime, resign, nanosecs); 2870} 2871 2872static isc_result_t 2873check_nsec3param(dns_zone_t *zone, dns_db_t *db) { 2874 dns_dbnode_t *node = NULL; 2875 dns_rdataset_t rdataset; 2876 dns_dbversion_t *version = NULL; 2877 dns_rdata_nsec3param_t nsec3param; 2878 isc_boolean_t ok = ISC_FALSE; 2879 isc_result_t result; 2880 dns_rdata_t rdata = DNS_RDATA_INIT; 2881 isc_boolean_t dynamic = (zone->type == dns_zone_master) ? 2882 dns_zone_isdynamic(zone, ISC_FALSE) : ISC_FALSE; 2883 2884 dns_rdataset_init(&rdataset); 2885 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 2886 if (result != ISC_R_SUCCESS) { 2887 dns_zone_log(zone, ISC_LOG_ERROR, 2888 "nsec3param lookup failure: %s", 2889 dns_result_totext(result)); 2890 return (result); 2891 } 2892 dns_db_currentversion(db, &version); 2893 2894 result = dns_db_findrdataset(db, node, version, 2895 dns_rdatatype_nsec3param, 2896 dns_rdatatype_none, 0, &rdataset, NULL); 2897 if (result == ISC_R_NOTFOUND) { 2898 INSIST(!dns_rdataset_isassociated(&rdataset)); 2899 result = ISC_R_SUCCESS; 2900 goto cleanup; 2901 } 2902 if (result != ISC_R_SUCCESS) { 2903 INSIST(!dns_rdataset_isassociated(&rdataset)); 2904 dns_zone_log(zone, ISC_LOG_ERROR, 2905 "nsec3param lookup failure: %s", 2906 dns_result_totext(result)); 2907 goto cleanup; 2908 } 2909 2910 /* 2911 * For dynamic zones we must support every algorithm so we can 2912 * regenerate all the NSEC3 chains. 2913 * For non-dynamic zones we only need to find a supported algorithm. 2914 */ 2915 for (result = dns_rdataset_first(&rdataset); 2916 result == ISC_R_SUCCESS; 2917 result = dns_rdataset_next(&rdataset)) 2918 { 2919 dns_rdataset_current(&rdataset, &rdata); 2920 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 2921 dns_rdata_reset(&rdata); 2922 INSIST(result == ISC_R_SUCCESS); 2923 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) && 2924 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic) 2925 { 2926 dns_zone_log(zone, ISC_LOG_WARNING, 2927 "nsec3 test \"unknown\" hash algorithm found: %u", 2928 nsec3param.hash); 2929 ok = ISC_TRUE; 2930 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) { 2931 if (dynamic) { 2932 dns_zone_log(zone, ISC_LOG_ERROR, 2933 "unsupported nsec3 hash algorithm" 2934 " in dynamic zone: %u", 2935 nsec3param.hash); 2936 result = DNS_R_BADZONE; 2937 /* Stop second error message. */ 2938 ok = ISC_TRUE; 2939 break; 2940 } else 2941 dns_zone_log(zone, ISC_LOG_WARNING, 2942 "unsupported nsec3 hash algorithm: %u", 2943 nsec3param.hash); 2944 } else 2945 ok = ISC_TRUE; 2946 } 2947 if (result == ISC_R_NOMORE) 2948 result = ISC_R_SUCCESS; 2949 2950 if (!ok) { 2951 result = DNS_R_BADZONE; 2952 dns_zone_log(zone, ISC_LOG_ERROR, 2953 "no supported nsec3 hash algorithm"); 2954 } 2955 2956 cleanup: 2957 if (dns_rdataset_isassociated(&rdataset)) 2958 dns_rdataset_disassociate(&rdataset); 2959 dns_db_closeversion(db, &version, ISC_FALSE); 2960 dns_db_detachnode(db, &node); 2961 return (result); 2962} 2963 2964/* 2965 * Set the timer for refreshing the key zone to the soonest future time 2966 * of the set (current timer, keydata->refresh, keydata->addhd, 2967 * keydata->removehd). 2968 */ 2969static void 2970set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key, 2971 isc_stdtime_t now) 2972{ 2973 const char me[] = "set_refreshkeytimer"; 2974 isc_stdtime_t then; 2975 isc_time_t timenow, timethen; 2976 char timebuf[80]; 2977 2978 ENTER; 2979 then = key->refresh; 2980 if (key->addhd > now && key->addhd < then) 2981 then = key->addhd; 2982 if (key->removehd > now && key->removehd < then) 2983 then = key->removehd; 2984 2985 TIME_NOW(&timenow); 2986 if (then > now) 2987 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 2988 else 2989 timethen = timenow; 2990 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 || 2991 isc_time_compare(&timethen, &zone->refreshkeytime) < 0) 2992 zone->refreshkeytime = timethen; 2993 2994 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 2995 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf); 2996 zone_settimer(zone, &timenow); 2997} 2998 2999/* 3000 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone. 3001 * If the key zone is changed, set '*changed' to ISC_TRUE. 3002 */ 3003static isc_result_t 3004create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 3005 dns_diff_t *diff, dns_keytable_t *keytable, 3006 dns_keynode_t **keynodep, isc_boolean_t *changed) 3007{ 3008 const char me[] = "create_keydata"; 3009 isc_result_t result = ISC_R_SUCCESS; 3010 isc_buffer_t keyb, dstb; 3011 unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE]; 3012 dns_rdata_keydata_t keydata; 3013 dns_rdata_dnskey_t dnskey; 3014 dns_rdata_t rdata = DNS_RDATA_INIT; 3015 dns_keynode_t *keynode; 3016 isc_stdtime_t now; 3017 isc_region_t r; 3018 dst_key_t *key; 3019 3020 REQUIRE(keynodep != NULL); 3021 keynode = *keynodep; 3022 3023 ENTER; 3024 isc_stdtime_get(&now); 3025 3026 /* Loop in case there's more than one key. */ 3027 while (result == ISC_R_SUCCESS) { 3028 dns_keynode_t *nextnode = NULL; 3029 3030 key = dns_keynode_key(keynode); 3031 if (key == NULL) 3032 goto skip; 3033 3034 isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf)); 3035 CHECK(dst_key_todns(key, &dstb)); 3036 3037 /* Convert DST key to DNSKEY. */ 3038 dns_rdata_reset(&rdata); 3039 isc_buffer_usedregion(&dstb, &r); 3040 dns_rdata_fromregion(&rdata, dst_key_class(key), 3041 dns_rdatatype_dnskey, &r); 3042 3043 /* DSTKEY to KEYDATA. */ 3044 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL)); 3045 CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0, 3046 NULL)); 3047 3048 /* KEYDATA to rdata. */ 3049 dns_rdata_reset(&rdata); 3050 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 3051 CHECK(dns_rdata_fromstruct(&rdata, 3052 zone->rdclass, dns_rdatatype_keydata, 3053 &keydata, &keyb)); 3054 3055 /* Add rdata to zone. */ 3056 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, 3057 dst_key_name(key), 0, &rdata)); 3058 *changed = ISC_TRUE; 3059 3060 skip: 3061 result = dns_keytable_nextkeynode(keytable, keynode, &nextnode); 3062 if (result != ISC_R_NOTFOUND) { 3063 dns_keytable_detachkeynode(keytable, &keynode); 3064 keynode = nextnode; 3065 } 3066 } 3067 3068 /* Refresh new keys from the zone apex as soon as possible. */ 3069 if (*changed) 3070 set_refreshkeytimer(zone, &keydata, now); 3071 3072 if (keynode != NULL) 3073 dns_keytable_detachkeynode(keytable, &keynode); 3074 *keynodep = NULL; 3075 3076 return (ISC_R_SUCCESS); 3077 3078 failure: 3079 return (result); 3080} 3081 3082/* 3083 * Remove from the key zone all the KEYDATA records found in rdataset. 3084 */ 3085static isc_result_t 3086delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 3087 dns_name_t *name, dns_rdataset_t *rdataset) 3088{ 3089 dns_rdata_t rdata = DNS_RDATA_INIT; 3090 isc_result_t result, uresult; 3091 3092 for (result = dns_rdataset_first(rdataset); 3093 result == ISC_R_SUCCESS; 3094 result = dns_rdataset_next(rdataset)) { 3095 dns_rdata_reset(&rdata); 3096 dns_rdataset_current(rdataset, &rdata); 3097 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, 3098 name, 0, &rdata); 3099 if (uresult != ISC_R_SUCCESS) 3100 return (uresult); 3101 } 3102 if (result == ISC_R_NOMORE) 3103 result = ISC_R_SUCCESS; 3104 return (result); 3105} 3106 3107/* 3108 * Compute the DNSSEC key ID for a DNSKEY record. 3109 */ 3110static isc_result_t 3111compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx, 3112 dns_keytag_t *tag) 3113{ 3114 isc_result_t result; 3115 dns_rdata_t rdata = DNS_RDATA_INIT; 3116 unsigned char data[4096]; 3117 isc_buffer_t buffer; 3118 dst_key_t *dstkey = NULL; 3119 3120 isc_buffer_init(&buffer, data, sizeof(data)); 3121 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 3122 dns_rdatatype_dnskey, dnskey, &buffer); 3123 3124 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey); 3125 if (result == ISC_R_SUCCESS) 3126 *tag = dst_key_id(dstkey); 3127 dst_key_free(&dstkey); 3128 3129 return (result); 3130} 3131 3132/* 3133 * Add key to the security roots. 3134 */ 3135static void 3136trust_key(dns_zone_t *zone, dns_name_t *keyname, 3137 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) { 3138 isc_result_t result; 3139 dns_rdata_t rdata = DNS_RDATA_INIT; 3140 unsigned char data[4096]; 3141 isc_buffer_t buffer; 3142 dns_keytable_t *sr = NULL; 3143 dst_key_t *dstkey = NULL; 3144 3145 /* Convert dnskey to DST key. */ 3146 isc_buffer_init(&buffer, data, sizeof(data)); 3147 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 3148 dns_rdatatype_dnskey, dnskey, &buffer); 3149 3150 result = dns_view_getsecroots(zone->view, &sr); 3151 if (result != ISC_R_SUCCESS) 3152 goto failure; 3153 3154 CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey)); 3155 CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey)); 3156 dns_keytable_detach(&sr); 3157 3158 failure: 3159 if (dstkey != NULL) 3160 dst_key_free(&dstkey); 3161 if (sr != NULL) 3162 dns_keytable_detach(&sr); 3163 return; 3164} 3165 3166/* 3167 * Add a null key to the security roots for so that all queries 3168 * to the zone will fail. 3169 */ 3170static void 3171fail_secure(dns_zone_t *zone, dns_name_t *keyname) { 3172 isc_result_t result; 3173 dns_keytable_t *sr = NULL; 3174 3175 result = dns_view_getsecroots(zone->view, &sr); 3176 if (result == ISC_R_SUCCESS) { 3177 dns_keytable_marksecure(sr, keyname); 3178 dns_keytable_detach(&sr); 3179 } 3180} 3181 3182/* 3183 * Scan a set of KEYDATA records from the key zone. The ones that are 3184 * valid (i.e., the add holddown timer has expired) become trusted keys. 3185 */ 3186static void 3187load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) { 3188 isc_result_t result; 3189 dns_rdata_t rdata = DNS_RDATA_INIT; 3190 dns_rdata_keydata_t keydata; 3191 dns_rdata_dnskey_t dnskey; 3192 isc_mem_t *mctx = zone->mctx; 3193 int trusted = 0, revoked = 0, pending = 0; 3194 isc_stdtime_t now; 3195 dns_keytable_t *sr = NULL; 3196 3197 isc_stdtime_get(&now); 3198 3199 result = dns_view_getsecroots(zone->view, &sr); 3200 if (result == ISC_R_SUCCESS) { 3201 dns_keytable_delete(sr, name); 3202 dns_keytable_detach(&sr); 3203 } 3204 3205 /* Now insert all the accepted trust anchors from this keydata set. */ 3206 for (result = dns_rdataset_first(rdataset); 3207 result == ISC_R_SUCCESS; 3208 result = dns_rdataset_next(rdataset)) { 3209 dns_rdata_reset(&rdata); 3210 dns_rdataset_current(rdataset, &rdata); 3211 3212 /* Convert rdata to keydata. */ 3213 dns_rdata_tostruct(&rdata, &keydata, NULL); 3214 3215 /* Set the key refresh timer. */ 3216 set_refreshkeytimer(zone, &keydata, now); 3217 3218 /* If the removal timer is nonzero, this key was revoked. */ 3219 if (keydata.removehd != 0) { 3220 revoked++; 3221 continue; 3222 } 3223 3224 /* 3225 * If the add timer is still pending, this key is not 3226 * trusted yet. 3227 */ 3228 if (now < keydata.addhd) { 3229 pending++; 3230 continue; 3231 } 3232 3233 /* Convert keydata to dnskey. */ 3234 dns_keydata_todnskey(&keydata, &dnskey, NULL); 3235 3236 /* Add to keytables. */ 3237 trusted++; 3238 trust_key(zone, name, &dnskey, mctx); 3239 } 3240 3241 if (trusted == 0 && pending != 0) { 3242 char namebuf[DNS_NAME_FORMATSIZE]; 3243 dns_name_format(name, namebuf, sizeof namebuf); 3244 dns_zone_log(zone, ISC_LOG_ERROR, 3245 "No valid trust anchors for '%s'!", namebuf); 3246 dns_zone_log(zone, ISC_LOG_ERROR, 3247 "%d key(s) revoked, %d still pending", 3248 revoked, pending); 3249 dns_zone_log(zone, ISC_LOG_ERROR, 3250 "All queries to '%s' will fail", namebuf); 3251 fail_secure(zone, name); 3252 } 3253} 3254 3255static isc_result_t 3256do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, 3257 dns_diff_t *diff) 3258{ 3259 dns_diff_t temp_diff; 3260 isc_result_t result; 3261 3262 /* 3263 * Create a singleton diff. 3264 */ 3265 dns_diff_init(diff->mctx, &temp_diff); 3266 temp_diff.resign = diff->resign; 3267 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); 3268 3269 /* 3270 * Apply it to the database. 3271 */ 3272 result = dns_diff_apply(&temp_diff, db, ver); 3273 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); 3274 if (result != ISC_R_SUCCESS) { 3275 dns_difftuple_free(tuple); 3276 return (result); 3277 } 3278 3279 /* 3280 * Merge it into the current pending journal entry. 3281 */ 3282 dns_diff_appendminimal(diff, tuple); 3283 3284 /* 3285 * Do not clear temp_diff. 3286 */ 3287 return (ISC_R_SUCCESS); 3288} 3289 3290static isc_result_t 3291update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 3292 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, 3293 dns_rdata_t *rdata) 3294{ 3295 dns_difftuple_t *tuple = NULL; 3296 isc_result_t result; 3297 result = dns_difftuple_create(diff->mctx, op, 3298 name, ttl, rdata, &tuple); 3299 if (result != ISC_R_SUCCESS) 3300 return (result); 3301 return (do_one_tuple(&tuple, db, ver, diff)); 3302} 3303 3304static isc_result_t 3305update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 3306 isc_mem_t *mctx, dns_updatemethod_t method) { 3307 dns_difftuple_t *deltuple = NULL; 3308 dns_difftuple_t *addtuple = NULL; 3309 isc_uint32_t serial; 3310 isc_result_t result; 3311 3312 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple)); 3313 CHECK(dns_difftuple_copy(deltuple, &addtuple)); 3314 addtuple->op = DNS_DIFFOP_ADD; 3315 3316 serial = dns_soa_getserial(&addtuple->rdata); 3317 serial = dns_update_soaserial(serial, method); 3318 dns_soa_setserial(serial, &addtuple->rdata); 3319 CHECK(do_one_tuple(&deltuple, db, ver, diff)); 3320 CHECK(do_one_tuple(&addtuple, db, ver, diff)); 3321 result = ISC_R_SUCCESS; 3322 3323 failure: 3324 if (addtuple != NULL) 3325 dns_difftuple_free(&addtuple); 3326 if (deltuple != NULL) 3327 dns_difftuple_free(&deltuple); 3328 return (result); 3329} 3330 3331/* 3332 * Write all transactions in 'diff' to the zone journal file. 3333 */ 3334static isc_result_t 3335zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial, 3336 const char *caller) 3337{ 3338 const char me[] = "zone_journal"; 3339 const char *journalfile; 3340 isc_result_t result = ISC_R_SUCCESS; 3341 dns_journal_t *journal = NULL; 3342 unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE; 3343 3344 ENTER; 3345 journalfile = dns_zone_getjournal(zone); 3346 if (journalfile != NULL) { 3347 result = dns_journal_open(zone->mctx, journalfile, mode, 3348 &journal); 3349 if (result != ISC_R_SUCCESS) { 3350 dns_zone_log(zone, ISC_LOG_ERROR, 3351 "%s:dns_journal_open -> %s", 3352 caller, dns_result_totext(result)); 3353 return (result); 3354 } 3355 3356 if (sourceserial != NULL) 3357 dns_journal_set_sourceserial(journal, *sourceserial); 3358 3359 result = dns_journal_write_transaction(journal, diff); 3360 if (result != ISC_R_SUCCESS) { 3361 dns_zone_log(zone, ISC_LOG_ERROR, 3362 "%s:dns_journal_write_transaction -> %s", 3363 caller, dns_result_totext(result)); 3364 } 3365 dns_journal_destroy(&journal); 3366 } 3367 3368 return (result); 3369} 3370 3371/* 3372 * Create an SOA record for a newly-created zone 3373 */ 3374static isc_result_t 3375add_soa(dns_zone_t *zone, dns_db_t *db) { 3376 isc_result_t result; 3377 dns_rdata_t rdata = DNS_RDATA_INIT; 3378 unsigned char buf[DNS_SOA_BUFFERSIZE]; 3379 dns_dbversion_t *ver = NULL; 3380 dns_diff_t diff; 3381 3382 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA"); 3383 3384 dns_diff_init(zone->mctx, &diff); 3385 result = dns_db_newversion(db, &ver); 3386 if (result != ISC_R_SUCCESS) { 3387 dns_zone_log(zone, ISC_LOG_ERROR, 3388 "add_soa:dns_db_newversion -> %s", 3389 dns_result_totext(result)); 3390 goto failure; 3391 } 3392 3393 /* Build SOA record */ 3394 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass, 3395 0, 0, 0, 0, 0, buf, &rdata); 3396 if (result != ISC_R_SUCCESS) { 3397 dns_zone_log(zone, ISC_LOG_ERROR, 3398 "add_soa:dns_soa_buildrdata -> %s", 3399 dns_result_totext(result)); 3400 goto failure; 3401 } 3402 3403 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD, 3404 &zone->origin, 0, &rdata); 3405 3406failure: 3407 dns_diff_clear(&diff); 3408 if (ver != NULL) 3409 dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS)); 3410 3411 return (result); 3412} 3413 3414/* 3415 * Synchronize the set of initializing keys found in managed-keys {} 3416 * statements with the set of trust anchors found in the managed-keys.bind 3417 * zone. If a domain is no longer named in managed-keys, delete all keys 3418 * from that domain from the key zone. If a domain is mentioned in in 3419 * managed-keys but there are no references to it in the key zone, load 3420 * the key zone with the initializing key(s) for that domain. 3421 */ 3422static isc_result_t 3423sync_keyzone(dns_zone_t *zone, dns_db_t *db) { 3424 isc_result_t result = ISC_R_SUCCESS; 3425 isc_boolean_t changed = ISC_FALSE; 3426 isc_boolean_t commit = ISC_FALSE; 3427 dns_rbtnodechain_t chain; 3428 dns_fixedname_t fn; 3429 dns_name_t foundname, *origin; 3430 dns_keynode_t *keynode = NULL; 3431 dns_view_t *view = zone->view; 3432 dns_keytable_t *sr = NULL; 3433 dns_dbversion_t *ver = NULL; 3434 dns_diff_t diff; 3435 dns_rriterator_t rrit; 3436 3437 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys"); 3438 3439 dns_name_init(&foundname, NULL); 3440 dns_fixedname_init(&fn); 3441 origin = dns_fixedname_name(&fn); 3442 3443 dns_diff_init(zone->mctx, &diff); 3444 3445 CHECK(dns_view_getsecroots(view, &sr)); 3446 3447 result = dns_db_newversion(db, &ver); 3448 if (result != ISC_R_SUCCESS) { 3449 dns_zone_log(zone, ISC_LOG_ERROR, 3450 "sync_keyzone:dns_db_newversion -> %s", 3451 dns_result_totext(result)); 3452 goto failure; 3453 } 3454 3455 /* 3456 * Walk the zone DB. If we find any keys whose names are no longer 3457 * in managed-keys (or *are* in trusted-keys, meaning they are 3458 * permanent and not RFC5011-maintained), delete them from the 3459 * zone. Otherwise call load_secroots(), which loads keys into 3460 * secroots as appropriate. 3461 */ 3462 dns_rriterator_init(&rrit, db, ver, 0); 3463 for (result = dns_rriterator_first(&rrit); 3464 result == ISC_R_SUCCESS; 3465 result = dns_rriterator_nextrrset(&rrit)) { 3466 dns_rdataset_t *rdataset = NULL; 3467 dns_name_t *rrname = NULL; 3468 isc_uint32_t ttl; 3469 3470 dns_rriterator_current(&rrit, &rrname, &ttl, 3471 &rdataset, NULL); 3472 if (!dns_rdataset_isassociated(rdataset)) { 3473 dns_rriterator_destroy(&rrit); 3474 goto failure; 3475 } 3476 3477 if (rdataset->type != dns_rdatatype_keydata) 3478 continue; 3479 3480 result = dns_keytable_find(sr, rrname, &keynode); 3481 if ((result != ISC_R_SUCCESS && 3482 result != DNS_R_PARTIALMATCH) || 3483 dns_keynode_managed(keynode) == ISC_FALSE) { 3484 CHECK(delete_keydata(db, ver, &diff, 3485 rrname, rdataset)); 3486 changed = ISC_TRUE; 3487 } else { 3488 load_secroots(zone, rrname, rdataset); 3489 } 3490 3491 if (keynode != NULL) 3492 dns_keytable_detachkeynode(sr, &keynode); 3493 } 3494 dns_rriterator_destroy(&rrit); 3495 3496 /* 3497 * Now walk secroots to find any managed keys that aren't 3498 * in the zone. If we find any, we add them to the zone. 3499 */ 3500 RWLOCK(&sr->rwlock, isc_rwlocktype_write); 3501 dns_rbtnodechain_init(&chain, zone->mctx); 3502 result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin); 3503 if (result == ISC_R_NOTFOUND) 3504 result = ISC_R_NOMORE; 3505 while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { 3506 dns_rbtnode_t *rbtnode = NULL; 3507 3508 dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode); 3509 if (rbtnode->data == NULL) 3510 goto skip; 3511 3512 dns_keytable_attachkeynode(sr, rbtnode->data, &keynode); 3513 if (dns_keynode_managed(keynode)) { 3514 dns_fixedname_t fname; 3515 dns_name_t *keyname; 3516 dst_key_t *key; 3517 3518 key = dns_keynode_key(keynode); 3519 dns_fixedname_init(&fname); 3520 3521 if (key == NULL) /* fail_secure() was called. */ 3522 goto skip; 3523 3524 keyname = dst_key_name(key); 3525 result = dns_db_find(db, keyname, ver, 3526 dns_rdatatype_keydata, 3527 DNS_DBFIND_NOWILD, 0, NULL, 3528 dns_fixedname_name(&fname), 3529 NULL, NULL); 3530 if (result != ISC_R_SUCCESS) 3531 result = create_keydata(zone, db, ver, &diff, 3532 sr, &keynode, &changed); 3533 if (result != ISC_R_SUCCESS) 3534 break; 3535 } 3536 skip: 3537 result = dns_rbtnodechain_next(&chain, &foundname, origin); 3538 if (keynode != NULL) 3539 dns_keytable_detachkeynode(sr, &keynode); 3540 } 3541 RWUNLOCK(&sr->rwlock, isc_rwlocktype_write); 3542 3543 if (result == ISC_R_NOMORE) 3544 result = ISC_R_SUCCESS; 3545 3546 if (changed) { 3547 /* Write changes to journal file. */ 3548 CHECK(update_soa_serial(db, ver, &diff, zone->mctx, 3549 zone->updatemethod)); 3550 CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone")); 3551 3552 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 3553 zone_needdump(zone, 30); 3554 commit = ISC_TRUE; 3555 } 3556 3557 failure: 3558 if (keynode != NULL) 3559 dns_keytable_detachkeynode(sr, &keynode); 3560 if (sr != NULL) 3561 dns_keytable_detach(&sr); 3562 if (ver != NULL) 3563 dns_db_closeversion(db, &ver, commit); 3564 dns_diff_clear(&diff); 3565 3566 return (result); 3567} 3568 3569isc_result_t 3570dns_zone_synckeyzone(dns_zone_t *zone) { 3571 isc_result_t result; 3572 dns_db_t *db = NULL; 3573 3574 if (zone->type != dns_zone_key) 3575 return (DNS_R_BADZONE); 3576 3577 CHECK(dns_zone_getdb(zone, &db)); 3578 3579 LOCK_ZONE(zone); 3580 result = sync_keyzone(zone, db); 3581 UNLOCK_ZONE(zone); 3582 3583 failure: 3584 if (db != NULL) 3585 dns_db_detach(&db); 3586 return (result); 3587} 3588 3589static void 3590maybe_send_secure(dns_zone_t *zone) { 3591 isc_result_t result; 3592 3593 /* 3594 * We've finished loading, or else failed to load, an inline-signing 3595 * 'secure' zone. We now need information about the status of the 3596 * 'raw' zone. If we failed to load, then we need it to send a 3597 * copy of its database; if we succeeded, we need it to send its 3598 * serial number so that we can sync with it. If it has not yet 3599 * loaded, we set a flag so that it will send the necessary 3600 * information when it has finished loading. 3601 */ 3602 if (zone->raw->db != NULL) { 3603 if (zone->db != NULL) { 3604 isc_uint32_t serial; 3605 result = zone_get_from_db(zone->raw, zone->raw->db, 3606 NULL, NULL, &serial, NULL, 3607 NULL, NULL, NULL, NULL); 3608 if (result == ISC_R_SUCCESS) 3609 zone_send_secureserial(zone->raw, ISC_TRUE, serial); 3610 } else 3611 zone_send_securedb(zone->raw, ISC_TRUE, zone->raw->db); 3612 3613 } else 3614 DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE); 3615} 3616 3617static isc_boolean_t 3618zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) { 3619 isc_result_t result; 3620 isc_boolean_t answer = ISC_FALSE; 3621 dns_diff_t diff; 3622 3623 dns_diff_init(mctx, &diff); 3624 result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL); 3625 if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples)) 3626 answer = ISC_TRUE; 3627 dns_diff_clear(&diff); 3628 return (answer); 3629} 3630 3631/* 3632 * The zone is presumed to be locked. 3633 */ 3634static isc_result_t 3635zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, 3636 isc_result_t result) 3637{ 3638 unsigned int soacount = 0; 3639 unsigned int nscount = 0; 3640 unsigned int errors = 0; 3641 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum; 3642 isc_time_t now; 3643 isc_boolean_t needdump = ISC_FALSE; 3644 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE); 3645 isc_boolean_t nomaster = ISC_FALSE; 3646 unsigned int options; 3647 3648 TIME_NOW(&now); 3649 3650 /* 3651 * Initiate zone transfer? We may need a error code that 3652 * indicates that the "permanent" form does not exist. 3653 * XXX better error feedback to log. 3654 */ 3655 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { 3656 if (zone->type == dns_zone_slave || 3657 zone->type == dns_zone_stub || 3658 (zone->type == dns_zone_redirect && 3659 zone->masters == NULL)) { 3660 if (result == ISC_R_FILENOTFOUND) 3661 dns_zone_log(zone, ISC_LOG_DEBUG(1), 3662 "no master file"); 3663 else if (result != DNS_R_NOMASTERFILE) 3664 dns_zone_log(zone, ISC_LOG_ERROR, 3665 "loading from master file %s " 3666 "failed: %s", 3667 zone->masterfile, 3668 dns_result_totext(result)); 3669 } else if (zone->type == dns_zone_master && 3670 inline_secure(zone) && result == ISC_R_FILENOTFOUND) 3671 { 3672 dns_zone_log(zone, ISC_LOG_DEBUG(1), 3673 "no master file, requesting db"); 3674 maybe_send_secure(zone); 3675 } else { 3676 int level = ISC_LOG_ERROR; 3677 if (zone->type == dns_zone_key && 3678 result == ISC_R_FILENOTFOUND) 3679 level = ISC_LOG_DEBUG(1); 3680 dns_zone_log(zone, level, 3681 "loading from master file %s failed: %s", 3682 zone->masterfile, 3683 dns_result_totext(result)); 3684 nomaster = ISC_TRUE; 3685 } 3686 3687 if (zone->type != dns_zone_key) 3688 goto cleanup; 3689 } 3690 3691 dns_zone_log(zone, ISC_LOG_DEBUG(2), 3692 "number of nodes in database: %u", 3693 dns_db_nodecount(db)); 3694 3695 if (result == DNS_R_SEENINCLUDE) 3696 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 3697 else 3698 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 3699 3700 /* 3701 * If there's no master file for a key zone, then the zone is new: 3702 * create an SOA record. (We do this now, instead of later, so that 3703 * if there happens to be a journal file, we can roll forward from 3704 * a sane starting point.) 3705 */ 3706 if (nomaster && zone->type == dns_zone_key) { 3707 result = add_soa(zone, db); 3708 if (result != ISC_R_SUCCESS) 3709 goto cleanup; 3710 } 3711 3712 /* 3713 * Apply update log, if any, on initial load. 3714 */ 3715 if (zone->journal != NULL && 3716 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) && 3717 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 3718 { 3719 if (zone->type == dns_zone_master && 3720 (zone->update_acl != NULL || zone->ssutable != NULL)) 3721 options = DNS_JOURNALOPT_RESIGN; 3722 else 3723 options = 0; 3724 result = dns_journal_rollforward2(zone->mctx, db, options, 3725 zone->sigresigninginterval, 3726 zone->journal); 3727 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND && 3728 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL && 3729 result != ISC_R_RANGE) { 3730 dns_zone_log(zone, ISC_LOG_ERROR, 3731 "journal rollforward failed: %s", 3732 dns_result_totext(result)); 3733 goto cleanup; 3734 3735 3736 } 3737 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) { 3738 dns_zone_log(zone, ISC_LOG_ERROR, 3739 "journal rollforward failed: " 3740 "journal out of sync with zone"); 3741 goto cleanup; 3742 } 3743 dns_zone_log(zone, ISC_LOG_DEBUG(1), 3744 "journal rollforward completed " 3745 "successfully: %s", 3746 dns_result_totext(result)); 3747 if (result == ISC_R_SUCCESS) 3748 needdump = ISC_TRUE; 3749 } 3750 3751 /* 3752 * Obtain ns, soa and cname counts for top of zone. 3753 */ 3754 INSIST(db != NULL); 3755 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial, 3756 &refresh, &retry, &expire, &minimum, 3757 &errors); 3758 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) { 3759 dns_zone_log(zone, ISC_LOG_ERROR, 3760 "could not find NS and/or SOA records"); 3761 } 3762 3763 /* 3764 * Check to make sure the journal is up to date, and remove the 3765 * journal file if it isn't, as we wouldn't be able to apply 3766 * updates otherwise. 3767 */ 3768 if (zone->journal != NULL && dns_zone_isdynamic(zone, ISC_TRUE) && 3769 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) { 3770 isc_uint32_t jserial; 3771 dns_journal_t *journal = NULL; 3772 3773 result = dns_journal_open(zone->mctx, zone->journal, 3774 DNS_JOURNAL_READ, &journal); 3775 if (result == ISC_R_SUCCESS) { 3776 jserial = dns_journal_last_serial(journal); 3777 dns_journal_destroy(&journal); 3778 } else { 3779 jserial = serial; 3780 result = ISC_R_SUCCESS; 3781 } 3782 3783 if (jserial != serial) { 3784 dns_zone_log(zone, ISC_LOG_INFO, 3785 "journal file is out of date: " 3786 "removing journal file"); 3787 if (remove(zone->journal) < 0 && errno != ENOENT) { 3788 char strbuf[ISC_STRERRORSIZE]; 3789 isc__strerror(errno, strbuf, sizeof(strbuf)); 3790 isc_log_write(dns_lctx, 3791 DNS_LOGCATEGORY_GENERAL, 3792 DNS_LOGMODULE_ZONE, 3793 ISC_LOG_WARNING, 3794 "unable to remove journal " 3795 "'%s': '%s'", 3796 zone->journal, strbuf); 3797 } 3798 } 3799 } 3800 3801 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity"); 3802 3803 /* 3804 * Master / Slave / Stub zones require both NS and SOA records at 3805 * the top of the zone. 3806 */ 3807 3808 switch (zone->type) { 3809 case dns_zone_dlz: 3810 case dns_zone_master: 3811 case dns_zone_slave: 3812 case dns_zone_stub: 3813 case dns_zone_redirect: 3814 if (soacount != 1) { 3815 dns_zone_log(zone, ISC_LOG_ERROR, 3816 "has %d SOA records", soacount); 3817 result = DNS_R_BADZONE; 3818 } 3819 if (nscount == 0) { 3820 dns_zone_log(zone, ISC_LOG_ERROR, 3821 "has no NS records"); 3822 result = DNS_R_BADZONE; 3823 } 3824 if (result != ISC_R_SUCCESS) 3825 goto cleanup; 3826 if (zone->type == dns_zone_master && errors != 0) { 3827 result = DNS_R_BADZONE; 3828 goto cleanup; 3829 } 3830 if (zone->type != dns_zone_stub && 3831 zone->type != dns_zone_redirect) { 3832 result = check_nsec3param(zone, db); 3833 if (result != ISC_R_SUCCESS) 3834 goto cleanup; 3835 } 3836 if (zone->type == dns_zone_master && 3837 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) && 3838 !integrity_checks(zone, db)) { 3839 result = DNS_R_BADZONE; 3840 goto cleanup; 3841 } 3842 if (zone->type == dns_zone_master && 3843 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) && 3844 !zone_check_dup(zone, db)) { 3845 result = DNS_R_BADZONE; 3846 goto cleanup; 3847 } 3848 3849 if (zone->db != NULL) { 3850 /* 3851 * This is checked in zone_replacedb() for slave zones 3852 * as they don't reload from disk. 3853 */ 3854 result = zone_get_from_db(zone, zone->db, NULL, NULL, 3855 &oldserial, NULL, NULL, NULL, 3856 NULL, NULL); 3857 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3858 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 3859 !isc_serial_gt(serial, oldserial)) { 3860 isc_uint32_t serialmin, serialmax; 3861 3862 INSIST(zone->type == dns_zone_master); 3863 3864 if (serial == oldserial && 3865 zone_unchanged(zone->db, db, zone->mctx)) { 3866 dns_zone_log(zone, ISC_LOG_INFO, 3867 "ixfr-from-differences: " 3868 "unchanged"); 3869 return(ISC_R_SUCCESS); 3870 } 3871 3872 serialmin = (oldserial + 1) & 0xffffffffU; 3873 serialmax = (oldserial + 0x7fffffffU) & 3874 0xffffffffU; 3875 dns_zone_log(zone, ISC_LOG_ERROR, 3876 "ixfr-from-differences: " 3877 "new serial (%u) out of range " 3878 "[%u - %u]", serial, serialmin, 3879 serialmax); 3880 result = DNS_R_BADZONE; 3881 goto cleanup; 3882 } else if (!isc_serial_ge(serial, oldserial)) 3883 dns_zone_log(zone, ISC_LOG_ERROR, 3884 "zone serial (%u/%u) has gone " 3885 "backwards", serial, oldserial); 3886 else if (serial == oldserial && !hasinclude && 3887 strcmp(zone->db_argv[0], "_builtin") != 0) 3888 dns_zone_log(zone, ISC_LOG_ERROR, 3889 "zone serial (%u) unchanged. " 3890 "zone may fail to transfer " 3891 "to slaves.", serial); 3892 } 3893 3894 if (zone->type == dns_zone_master && 3895 (zone->update_acl != NULL || zone->ssutable != NULL) && 3896 zone->sigresigninginterval < (3 * refresh) && 3897 dns_db_issecure(db)) 3898 { 3899 dns_zone_log(zone, ISC_LOG_WARNING, 3900 "sig-re-signing-interval less than " 3901 "3 * refresh."); 3902 } 3903 3904 zone->refresh = RANGE(refresh, 3905 zone->minrefresh, zone->maxrefresh); 3906 zone->retry = RANGE(retry, 3907 zone->minretry, zone->maxretry); 3908 zone->expire = RANGE(expire, zone->refresh + zone->retry, 3909 DNS_MAX_EXPIRE); 3910 zone->minimum = minimum; 3911 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 3912 3913 if (zone->type == dns_zone_slave || 3914 zone->type == dns_zone_stub || 3915 (zone->type == dns_zone_redirect && 3916 zone->masters != NULL)) { 3917 isc_time_t t; 3918 isc_uint32_t delay; 3919 3920 result = isc_file_getmodtime(zone->journal, &t); 3921 if (result != ISC_R_SUCCESS) 3922 result = isc_file_getmodtime(zone->masterfile, 3923 &t); 3924 if (result == ISC_R_SUCCESS) 3925 DNS_ZONE_TIME_ADD(&t, zone->expire, 3926 &zone->expiretime); 3927 else 3928 DNS_ZONE_TIME_ADD(&now, zone->retry, 3929 &zone->expiretime); 3930 3931 delay = isc_random_jitter(zone->retry, 3932 (zone->retry * 3) / 4); 3933 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime); 3934 if (isc_time_compare(&zone->refreshtime, 3935 &zone->expiretime) >= 0) 3936 zone->refreshtime = now; 3937 } 3938 3939 break; 3940 3941 case dns_zone_key: 3942 result = sync_keyzone(zone, db); 3943 if (result != ISC_R_SUCCESS) 3944 goto cleanup; 3945 break; 3946 3947 default: 3948 UNEXPECTED_ERROR(__FILE__, __LINE__, 3949 "unexpected zone type %d", zone->type); 3950 result = ISC_R_UNEXPECTED; 3951 goto cleanup; 3952 } 3953 3954 /* 3955 * Check for weak DNSKEY's. 3956 */ 3957 if (zone->type == dns_zone_master) 3958 zone_check_dnskeys(zone, db); 3959 3960 /* 3961 * Schedule DNSSEC key refresh. 3962 */ 3963 if (zone->type == dns_zone_master && 3964 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 3965 zone->refreshkeytime = now; 3966 3967#if 0 3968 /* destroy notification example. */ 3969 { 3970 isc_event_t *e = isc_event_allocate(zone->mctx, NULL, 3971 DNS_EVENT_DBDESTROYED, 3972 dns_zonemgr_dbdestroyed, 3973 zone, 3974 sizeof(isc_event_t)); 3975 dns_db_ondestroy(db, zone->task, &e); 3976 } 3977#endif 3978 3979 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 3980 if (zone->db != NULL) { 3981 result = zone_replacedb(zone, db, ISC_FALSE); 3982 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 3983 if (result != ISC_R_SUCCESS) 3984 goto cleanup; 3985 } else { 3986 zone_attachdb(zone, db); 3987 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 3988 DNS_ZONE_SETFLAG(zone, 3989 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY); 3990 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) && 3991 inline_raw(zone)) 3992 { 3993 if (zone->secure->db == NULL) 3994 zone_send_securedb(zone, ISC_FALSE, db); 3995 else 3996 zone_send_secureserial(zone, ISC_FALSE, serial); 3997 } 3998 } 3999 4000 /* 4001 * Finished loading inline-signing zone; need to get status 4002 * from the raw side now. 4003 */ 4004 if (zone->type == dns_zone_master && inline_secure(zone)) 4005 maybe_send_secure(zone); 4006 4007 4008 result = ISC_R_SUCCESS; 4009 4010 if (needdump) { 4011 if (zone->type == dns_zone_key) 4012 zone_needdump(zone, 30); 4013 else 4014 zone_needdump(zone, DNS_DUMP_DELAY); 4015 } 4016 4017 if (zone->task != NULL) { 4018 if (zone->type == dns_zone_master) { 4019 set_resigntime(zone); 4020 resume_signingwithkey(zone); 4021 resume_addnsec3chain(zone); 4022 } 4023 4024 if (zone->type == dns_zone_master && 4025 !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) && 4026 dns_zone_isdynamic(zone, ISC_FALSE) && 4027 dns_db_issecure(db)) { 4028 dns_name_t *name; 4029 dns_fixedname_t fixed; 4030 dns_rdataset_t next; 4031 4032 dns_rdataset_init(&next); 4033 dns_fixedname_init(&fixed); 4034 name = dns_fixedname_name(&fixed); 4035 4036 result = dns_db_getsigningtime(db, &next, name); 4037 if (result == ISC_R_SUCCESS) { 4038 isc_stdtime_t timenow; 4039 char namebuf[DNS_NAME_FORMATSIZE]; 4040 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 4041 4042 isc_stdtime_get(&timenow); 4043 dns_name_format(name, namebuf, sizeof(namebuf)); 4044 dns_rdatatype_format(next.covers, 4045 typebuf, sizeof(typebuf)); 4046 dns_zone_log(zone, ISC_LOG_DEBUG(3), 4047 "next resign: %s/%s in %d seconds", 4048 namebuf, typebuf, 4049 next.resign - timenow); 4050 dns_rdataset_disassociate(&next); 4051 } else 4052 dns_zone_log(zone, ISC_LOG_WARNING, 4053 "signed dynamic zone has no " 4054 "resign event scheduled"); 4055 } 4056 4057 zone_settimer(zone, &now); 4058 } 4059 4060 if (! dns_db_ispersistent(db)) 4061 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial, 4062 dns_db_issecure(db) ? " (DNSSEC signed)" : ""); 4063 4064 zone->loadtime = loadtime; 4065 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); 4066 return (result); 4067 4068 cleanup: 4069 if (zone->type == dns_zone_slave || 4070 zone->type == dns_zone_stub || 4071 zone->type == dns_zone_key || 4072 (zone->type == dns_zone_redirect && zone->masters != NULL)) { 4073 if (zone->journal != NULL) 4074 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX"); 4075 if (zone->masterfile != NULL) 4076 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX"); 4077 4078 /* Mark the zone for immediate refresh. */ 4079 zone->refreshtime = now; 4080 if (zone->task != NULL) 4081 zone_settimer(zone, &now); 4082 result = ISC_R_SUCCESS; 4083 } else if (zone->type == dns_zone_master || 4084 zone->type == dns_zone_redirect) { 4085 if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND)) 4086 dns_zone_log(zone, ISC_LOG_ERROR, 4087 "not loaded due to errors."); 4088 } 4089 4090 return (result); 4091} 4092 4093static isc_boolean_t 4094exit_check(dns_zone_t *zone) { 4095 4096 REQUIRE(LOCKED_ZONE(zone)); 4097 4098 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && 4099 zone->irefs == 0) 4100 { 4101 /* 4102 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0. 4103 */ 4104 INSIST(isc_refcount_current(&zone->erefs) == 0); 4105 return (ISC_TRUE); 4106 } 4107 return (ISC_FALSE); 4108} 4109 4110static isc_boolean_t 4111zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 4112 dns_name_t *name, isc_boolean_t logit) 4113{ 4114 isc_result_t result; 4115 char namebuf[DNS_NAME_FORMATSIZE]; 4116 char altbuf[DNS_NAME_FORMATSIZE]; 4117 dns_fixedname_t fixed; 4118 dns_name_t *foundname; 4119 int level; 4120 4121 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) 4122 return (ISC_TRUE); 4123 4124 if (zone->type == dns_zone_master) 4125 level = ISC_LOG_ERROR; 4126 else 4127 level = ISC_LOG_WARNING; 4128 4129 dns_fixedname_init(&fixed); 4130 foundname = dns_fixedname_name(&fixed); 4131 4132 result = dns_db_find(db, name, version, dns_rdatatype_a, 4133 0, 0, NULL, foundname, NULL, NULL); 4134 if (result == ISC_R_SUCCESS) 4135 return (ISC_TRUE); 4136 4137 if (result == DNS_R_NXRRSET) { 4138 result = dns_db_find(db, name, version, dns_rdatatype_aaaa, 4139 0, 0, NULL, foundname, NULL, NULL); 4140 if (result == ISC_R_SUCCESS) 4141 return (ISC_TRUE); 4142 } 4143 4144 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 4145 result == DNS_R_EMPTYNAME) { 4146 if (logit) { 4147 dns_name_format(name, namebuf, sizeof namebuf); 4148 dns_zone_log(zone, level, "NS '%s' has no address " 4149 "records (A or AAAA)", namebuf); 4150 } 4151 return (ISC_FALSE); 4152 } 4153 4154 if (result == DNS_R_CNAME) { 4155 if (logit) { 4156 dns_name_format(name, namebuf, sizeof namebuf); 4157 dns_zone_log(zone, level, "NS '%s' is a CNAME " 4158 "(illegal)", namebuf); 4159 } 4160 return (ISC_FALSE); 4161 } 4162 4163 if (result == DNS_R_DNAME) { 4164 if (logit) { 4165 dns_name_format(name, namebuf, sizeof namebuf); 4166 dns_name_format(foundname, altbuf, sizeof altbuf); 4167 dns_zone_log(zone, level, "NS '%s' is below a DNAME " 4168 "'%s' (illegal)", namebuf, altbuf); 4169 } 4170 return (ISC_FALSE); 4171 } 4172 4173 return (ISC_TRUE); 4174} 4175 4176static isc_result_t 4177zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, 4178 dns_dbversion_t *version, unsigned int *nscount, 4179 unsigned int *errors, isc_boolean_t logit) 4180{ 4181 isc_result_t result; 4182 unsigned int count = 0; 4183 unsigned int ecount = 0; 4184 dns_rdataset_t rdataset; 4185 dns_rdata_t rdata; 4186 dns_rdata_ns_t ns; 4187 4188 dns_rdataset_init(&rdataset); 4189 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns, 4190 dns_rdatatype_none, 0, &rdataset, NULL); 4191 if (result == ISC_R_NOTFOUND) { 4192 INSIST(!dns_rdataset_isassociated(&rdataset)); 4193 goto success; 4194 } 4195 if (result != ISC_R_SUCCESS) { 4196 INSIST(!dns_rdataset_isassociated(&rdataset)); 4197 goto invalidate_rdataset; 4198 } 4199 4200 result = dns_rdataset_first(&rdataset); 4201 while (result == ISC_R_SUCCESS) { 4202 if (errors != NULL && zone->rdclass == dns_rdataclass_in && 4203 (zone->type == dns_zone_master || 4204 zone->type == dns_zone_slave)) { 4205 dns_rdata_init(&rdata); 4206 dns_rdataset_current(&rdataset, &rdata); 4207 result = dns_rdata_tostruct(&rdata, &ns, NULL); 4208 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4209 if (dns_name_issubdomain(&ns.name, &zone->origin) && 4210 !zone_check_ns(zone, db, version, &ns.name, logit)) 4211 ecount++; 4212 } 4213 count++; 4214 result = dns_rdataset_next(&rdataset); 4215 } 4216 dns_rdataset_disassociate(&rdataset); 4217 4218 success: 4219 if (nscount != NULL) 4220 *nscount = count; 4221 if (errors != NULL) 4222 *errors = ecount; 4223 4224 result = ISC_R_SUCCESS; 4225 4226 invalidate_rdataset: 4227 dns_rdataset_invalidate(&rdataset); 4228 4229 return (result); 4230} 4231 4232static isc_result_t 4233zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 4234 unsigned int *soacount, 4235 isc_uint32_t *serial, isc_uint32_t *refresh, 4236 isc_uint32_t *retry, isc_uint32_t *expire, 4237 isc_uint32_t *minimum) 4238{ 4239 isc_result_t result; 4240 unsigned int count; 4241 dns_rdataset_t rdataset; 4242 dns_rdata_t rdata = DNS_RDATA_INIT; 4243 dns_rdata_soa_t soa; 4244 4245 dns_rdataset_init(&rdataset); 4246 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, 4247 dns_rdatatype_none, 0, &rdataset, NULL); 4248 if (result == ISC_R_NOTFOUND) { 4249 INSIST(!dns_rdataset_isassociated(&rdataset)); 4250 if (soacount != NULL) 4251 *soacount = 0; 4252 if (serial != NULL) 4253 *serial = 0; 4254 if (refresh != NULL) 4255 *refresh = 0; 4256 if (retry != NULL) 4257 *retry = 0; 4258 if (expire != NULL) 4259 *expire = 0; 4260 if (minimum != NULL) 4261 *minimum = 0; 4262 result = ISC_R_SUCCESS; 4263 goto invalidate_rdataset; 4264 } 4265 if (result != ISC_R_SUCCESS) { 4266 INSIST(!dns_rdataset_isassociated(&rdataset)); 4267 goto invalidate_rdataset; 4268 } 4269 4270 count = 0; 4271 result = dns_rdataset_first(&rdataset); 4272 while (result == ISC_R_SUCCESS) { 4273 dns_rdata_init(&rdata); 4274 dns_rdataset_current(&rdataset, &rdata); 4275 count++; 4276 if (count == 1) { 4277 result = dns_rdata_tostruct(&rdata, &soa, NULL); 4278 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4279 } 4280 4281 result = dns_rdataset_next(&rdataset); 4282 dns_rdata_reset(&rdata); 4283 } 4284 dns_rdataset_disassociate(&rdataset); 4285 4286 if (soacount != NULL) 4287 *soacount = count; 4288 4289 if (count > 0) { 4290 if (serial != NULL) 4291 *serial = soa.serial; 4292 if (refresh != NULL) 4293 *refresh = soa.refresh; 4294 if (retry != NULL) 4295 *retry = soa.retry; 4296 if (expire != NULL) 4297 *expire = soa.expire; 4298 if (minimum != NULL) 4299 *minimum = soa.minimum; 4300 } 4301 4302 result = ISC_R_SUCCESS; 4303 4304 invalidate_rdataset: 4305 dns_rdataset_invalidate(&rdataset); 4306 4307 return (result); 4308} 4309 4310/* 4311 * zone must be locked. 4312 */ 4313static isc_result_t 4314zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 4315 unsigned int *soacount, isc_uint32_t *serial, 4316 isc_uint32_t *refresh, isc_uint32_t *retry, 4317 isc_uint32_t *expire, isc_uint32_t *minimum, 4318 unsigned int *errors) 4319{ 4320 isc_result_t result; 4321 isc_result_t answer = ISC_R_SUCCESS; 4322 dns_dbversion_t *version = NULL; 4323 dns_dbnode_t *node; 4324 4325 REQUIRE(db != NULL); 4326 REQUIRE(zone != NULL); 4327 4328 dns_db_currentversion(db, &version); 4329 4330 node = NULL; 4331 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 4332 if (result != ISC_R_SUCCESS) { 4333 answer = result; 4334 goto closeversion; 4335 } 4336 4337 if (nscount != NULL || errors != NULL) { 4338 result = zone_count_ns_rr(zone, db, node, version, 4339 nscount, errors, ISC_TRUE); 4340 if (result != ISC_R_SUCCESS) 4341 answer = result; 4342 } 4343 4344 if (soacount != NULL || serial != NULL || refresh != NULL 4345 || retry != NULL || expire != NULL || minimum != NULL) { 4346 result = zone_load_soa_rr(db, node, version, soacount, 4347 serial, refresh, retry, expire, 4348 minimum); 4349 if (result != ISC_R_SUCCESS) 4350 answer = result; 4351 } 4352 4353 dns_db_detachnode(db, &node); 4354 closeversion: 4355 dns_db_closeversion(db, &version, ISC_FALSE); 4356 4357 return (answer); 4358} 4359 4360void 4361dns_zone_attach(dns_zone_t *source, dns_zone_t **target) { 4362 REQUIRE(DNS_ZONE_VALID(source)); 4363 REQUIRE(target != NULL && *target == NULL); 4364 isc_refcount_increment(&source->erefs, NULL); 4365 *target = source; 4366} 4367 4368void 4369dns_zone_detach(dns_zone_t **zonep) { 4370 dns_zone_t *zone; 4371 dns_zone_t *raw = NULL; 4372 dns_zone_t *secure = NULL; 4373 unsigned int refs; 4374 isc_boolean_t free_now = ISC_FALSE; 4375 4376 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 4377 4378 zone = *zonep; 4379 4380 isc_refcount_decrement(&zone->erefs, &refs); 4381 4382 if (refs == 0) { 4383 LOCK_ZONE(zone); 4384 /* 4385 * We just detached the last external reference. 4386 */ 4387 if (zone->task != NULL) { 4388 /* 4389 * This zone is being managed. Post 4390 * its control event and let it clean 4391 * up synchronously in the context of 4392 * its task. 4393 */ 4394 isc_event_t *ev = &zone->ctlevent; 4395 isc_task_send(zone->task, &ev); 4396 } else { 4397 /* 4398 * This zone is not being managed; it has 4399 * no task and can have no outstanding 4400 * events. Free it immediately. 4401 */ 4402 /* 4403 * Unmanaged zones should not have non-null views; 4404 * we have no way of detaching from the view here 4405 * without causing deadlock because this code is called 4406 * with the view already locked. 4407 */ 4408 INSIST(zone->view == NULL); 4409 free_now = ISC_TRUE; 4410 raw = zone->raw; 4411 zone->raw = NULL; 4412 secure = zone->secure; 4413 zone->secure = NULL; 4414 } 4415 UNLOCK_ZONE(zone); 4416 } 4417 *zonep = NULL; 4418 if (free_now) { 4419 if (raw != NULL) 4420 dns_zone_detach(&raw); 4421 if (secure != NULL) 4422 dns_zone_idetach(&secure); 4423 zone_free(zone); 4424 } 4425} 4426 4427void 4428dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) { 4429 REQUIRE(DNS_ZONE_VALID(source)); 4430 REQUIRE(target != NULL && *target == NULL); 4431 LOCK_ZONE(source); 4432 zone_iattach(source, target); 4433 UNLOCK_ZONE(source); 4434} 4435 4436static void 4437zone_iattach(dns_zone_t *source, dns_zone_t **target) { 4438 4439 /* 4440 * 'source' locked by caller. 4441 */ 4442 REQUIRE(LOCKED_ZONE(source)); 4443 REQUIRE(DNS_ZONE_VALID(source)); 4444 REQUIRE(target != NULL && *target == NULL); 4445 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0); 4446 source->irefs++; 4447 INSIST(source->irefs != 0); 4448 *target = source; 4449} 4450 4451static void 4452zone_idetach(dns_zone_t **zonep) { 4453 dns_zone_t *zone; 4454 4455 /* 4456 * 'zone' locked by caller. 4457 */ 4458 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 4459 zone = *zonep; 4460 REQUIRE(LOCKED_ZONE(*zonep)); 4461 *zonep = NULL; 4462 4463 INSIST(zone->irefs > 0); 4464 zone->irefs--; 4465 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0); 4466} 4467 4468void 4469dns_zone_idetach(dns_zone_t **zonep) { 4470 dns_zone_t *zone; 4471 isc_boolean_t free_needed; 4472 4473 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 4474 zone = *zonep; 4475 *zonep = NULL; 4476 4477 LOCK_ZONE(zone); 4478 INSIST(zone->irefs > 0); 4479 zone->irefs--; 4480 free_needed = exit_check(zone); 4481 UNLOCK_ZONE(zone); 4482 if (free_needed) 4483 zone_free(zone); 4484} 4485 4486isc_mem_t * 4487dns_zone_getmctx(dns_zone_t *zone) { 4488 REQUIRE(DNS_ZONE_VALID(zone)); 4489 4490 return (zone->mctx); 4491} 4492 4493dns_zonemgr_t * 4494dns_zone_getmgr(dns_zone_t *zone) { 4495 REQUIRE(DNS_ZONE_VALID(zone)); 4496 4497 return (zone->zmgr); 4498} 4499 4500void 4501dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) { 4502 REQUIRE(DNS_ZONE_VALID(zone)); 4503 4504 LOCK_ZONE(zone); 4505 if (value) 4506 DNS_ZONE_SETFLAG(zone, flags); 4507 else 4508 DNS_ZONE_CLRFLAG(zone, flags); 4509 UNLOCK_ZONE(zone); 4510} 4511 4512void 4513dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value) 4514{ 4515 REQUIRE(DNS_ZONE_VALID(zone)); 4516 4517 LOCK_ZONE(zone); 4518 if (value) 4519 zone->options |= option; 4520 else 4521 zone->options &= ~option; 4522 UNLOCK_ZONE(zone); 4523} 4524 4525unsigned int 4526dns_zone_getoptions(dns_zone_t *zone) { 4527 4528 REQUIRE(DNS_ZONE_VALID(zone)); 4529 4530 return (zone->options); 4531} 4532 4533void 4534dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value) 4535{ 4536 REQUIRE(DNS_ZONE_VALID(zone)); 4537 4538 LOCK_ZONE(zone); 4539 if (value) 4540 zone->keyopts |= keyopt; 4541 else 4542 zone->keyopts &= ~keyopt; 4543 UNLOCK_ZONE(zone); 4544} 4545 4546unsigned int 4547dns_zone_getkeyopts(dns_zone_t *zone) { 4548 4549 REQUIRE(DNS_ZONE_VALID(zone)); 4550 4551 return (zone->keyopts); 4552} 4553 4554isc_result_t 4555dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 4556 REQUIRE(DNS_ZONE_VALID(zone)); 4557 4558 LOCK_ZONE(zone); 4559 zone->xfrsource4 = *xfrsource; 4560 UNLOCK_ZONE(zone); 4561 4562 return (ISC_R_SUCCESS); 4563} 4564 4565isc_sockaddr_t * 4566dns_zone_getxfrsource4(dns_zone_t *zone) { 4567 REQUIRE(DNS_ZONE_VALID(zone)); 4568 return (&zone->xfrsource4); 4569} 4570 4571isc_result_t 4572dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 4573 REQUIRE(DNS_ZONE_VALID(zone)); 4574 4575 LOCK_ZONE(zone); 4576 zone->xfrsource6 = *xfrsource; 4577 UNLOCK_ZONE(zone); 4578 4579 return (ISC_R_SUCCESS); 4580} 4581 4582isc_sockaddr_t * 4583dns_zone_getxfrsource6(dns_zone_t *zone) { 4584 REQUIRE(DNS_ZONE_VALID(zone)); 4585 return (&zone->xfrsource6); 4586} 4587 4588isc_result_t 4589dns_zone_setaltxfrsource4(dns_zone_t *zone, 4590 const isc_sockaddr_t *altxfrsource) 4591{ 4592 REQUIRE(DNS_ZONE_VALID(zone)); 4593 4594 LOCK_ZONE(zone); 4595 zone->altxfrsource4 = *altxfrsource; 4596 UNLOCK_ZONE(zone); 4597 4598 return (ISC_R_SUCCESS); 4599} 4600 4601isc_sockaddr_t * 4602dns_zone_getaltxfrsource4(dns_zone_t *zone) { 4603 REQUIRE(DNS_ZONE_VALID(zone)); 4604 return (&zone->altxfrsource4); 4605} 4606 4607isc_result_t 4608dns_zone_setaltxfrsource6(dns_zone_t *zone, 4609 const isc_sockaddr_t *altxfrsource) 4610{ 4611 REQUIRE(DNS_ZONE_VALID(zone)); 4612 4613 LOCK_ZONE(zone); 4614 zone->altxfrsource6 = *altxfrsource; 4615 UNLOCK_ZONE(zone); 4616 4617 return (ISC_R_SUCCESS); 4618} 4619 4620isc_sockaddr_t * 4621dns_zone_getaltxfrsource6(dns_zone_t *zone) { 4622 REQUIRE(DNS_ZONE_VALID(zone)); 4623 return (&zone->altxfrsource6); 4624} 4625 4626isc_result_t 4627dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 4628 REQUIRE(DNS_ZONE_VALID(zone)); 4629 4630 LOCK_ZONE(zone); 4631 zone->notifysrc4 = *notifysrc; 4632 UNLOCK_ZONE(zone); 4633 4634 return (ISC_R_SUCCESS); 4635} 4636 4637isc_sockaddr_t * 4638dns_zone_getnotifysrc4(dns_zone_t *zone) { 4639 REQUIRE(DNS_ZONE_VALID(zone)); 4640 return (&zone->notifysrc4); 4641} 4642 4643isc_result_t 4644dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 4645 REQUIRE(DNS_ZONE_VALID(zone)); 4646 4647 LOCK_ZONE(zone); 4648 zone->notifysrc6 = *notifysrc; 4649 UNLOCK_ZONE(zone); 4650 4651 return (ISC_R_SUCCESS); 4652} 4653 4654isc_sockaddr_t * 4655dns_zone_getnotifysrc6(dns_zone_t *zone) { 4656 REQUIRE(DNS_ZONE_VALID(zone)); 4657 return (&zone->notifysrc6); 4658} 4659 4660static isc_boolean_t 4661same_addrs(const isc_sockaddr_t *old, const isc_sockaddr_t *new, 4662 isc_uint32_t count) 4663{ 4664 unsigned int i; 4665 4666 for (i = 0; i < count; i++) 4667 if (!isc_sockaddr_equal(&old[i], &new[i])) 4668 return (ISC_FALSE); 4669 return (ISC_TRUE); 4670} 4671 4672static isc_boolean_t 4673same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) { 4674 unsigned int i; 4675 4676 if (old == NULL && new == NULL) 4677 return (ISC_TRUE); 4678 if (old == NULL || new == NULL) 4679 return (ISC_FALSE); 4680 4681 for (i = 0; i < count; i++) { 4682 if (old[i] == NULL && new[i] == NULL) 4683 continue; 4684 if (old[i] == NULL || new[i] == NULL || 4685 !dns_name_equal(old[i], new[i])) 4686 return (ISC_FALSE); 4687 } 4688 return (ISC_TRUE); 4689} 4690 4691static void 4692clear_addresskeylist(isc_sockaddr_t **addrsp, dns_name_t ***keynamesp, 4693 unsigned int *countp, isc_mem_t *mctx) 4694{ 4695 unsigned int count; 4696 isc_sockaddr_t *addrs; 4697 dns_name_t **keynames; 4698 4699 REQUIRE(countp != NULL && addrsp != NULL && keynamesp != NULL); 4700 4701 count = *countp; 4702 *countp = 0; 4703 addrs = *addrsp; 4704 *addrsp = NULL; 4705 keynames = *keynamesp; 4706 *keynamesp = NULL; 4707 4708 if (addrs != NULL) 4709 isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t)); 4710 4711 if (keynames != NULL) { 4712 unsigned int i; 4713 for (i = 0; i < count; i++) { 4714 if (keynames[i] != NULL) { 4715 dns_name_free(keynames[i], mctx); 4716 isc_mem_put(mctx, keynames[i], 4717 sizeof(dns_name_t)); 4718 keynames[i] = NULL; 4719 } 4720 } 4721 isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *)); 4722 } 4723} 4724 4725static isc_result_t 4726set_addrkeylist(unsigned int count, 4727 const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp, 4728 dns_name_t **names, dns_name_t ***newnamesp, 4729 isc_mem_t *mctx) 4730{ 4731 isc_result_t result; 4732 isc_sockaddr_t *newaddrs = NULL; 4733 dns_name_t **newnames = NULL; 4734 unsigned int i; 4735 4736 REQUIRE(newaddrsp != NULL && *newaddrsp == NULL); 4737 REQUIRE(newnamesp != NULL && *newnamesp == NULL); 4738 4739 newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs)); 4740 if (newaddrs == NULL) 4741 return (ISC_R_NOMEMORY); 4742 memcpy(newaddrs, addrs, count * sizeof(*newaddrs)); 4743 4744 newnames = NULL; 4745 if (names != NULL) { 4746 newnames = isc_mem_get(mctx, count * sizeof(*newnames)); 4747 if (newnames == NULL) { 4748 isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs)); 4749 return (ISC_R_NOMEMORY); 4750 } 4751 for (i = 0; i < count; i++) 4752 newnames[i] = NULL; 4753 for (i = 0; i < count; i++) { 4754 if (names[i] != NULL) { 4755 newnames[i] = isc_mem_get(mctx, 4756 sizeof(dns_name_t)); 4757 if (newnames[i] == NULL) 4758 goto allocfail; 4759 dns_name_init(newnames[i], NULL); 4760 result = dns_name_dup(names[i], mctx, 4761 newnames[i]); 4762 if (result != ISC_R_SUCCESS) { 4763 allocfail: 4764 for (i = 0; i < count; i++) 4765 if (newnames[i] != NULL) 4766 dns_name_free( 4767 newnames[i], 4768 mctx); 4769 isc_mem_put(mctx, newaddrs, 4770 count * sizeof(*newaddrs)); 4771 isc_mem_put(mctx, newnames, 4772 count * sizeof(*newnames)); 4773 return (ISC_R_NOMEMORY); 4774 } 4775 } 4776 } 4777 } 4778 4779 *newaddrsp = newaddrs; 4780 *newnamesp = newnames; 4781 return (ISC_R_SUCCESS); 4782} 4783 4784isc_result_t 4785dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, 4786 isc_uint32_t count) 4787{ 4788 return (dns_zone_setalsonotifywithkeys(zone, notify, NULL, count)); 4789} 4790 4791isc_result_t 4792dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify, 4793 dns_name_t **keynames, isc_uint32_t count) 4794{ 4795 isc_result_t result; 4796 isc_sockaddr_t *newaddrs = NULL; 4797 dns_name_t **newnames = NULL; 4798 4799 REQUIRE(DNS_ZONE_VALID(zone)); 4800 REQUIRE(count == 0 || notify != NULL); 4801 if (keynames != NULL) 4802 REQUIRE(count != 0); 4803 4804 LOCK_ZONE(zone); 4805 4806 if (count == zone->notifycnt && 4807 same_addrs(zone->notify, notify, count) && 4808 same_keynames(zone->notifykeynames, keynames, count)) 4809 goto unlock; 4810 4811 clear_addresskeylist(&zone->notify, &zone->notifykeynames, 4812 &zone->notifycnt, zone->mctx); 4813 4814 if (count == 0) 4815 goto unlock; 4816 4817 /* 4818 * Set up the notify and notifykey lists 4819 */ 4820 result = set_addrkeylist(count, notify, &newaddrs, 4821 keynames, &newnames, zone->mctx); 4822 if (result != ISC_R_SUCCESS) 4823 goto unlock; 4824 4825 /* 4826 * Everything is ok so attach to the zone. 4827 */ 4828 zone->notify = newaddrs; 4829 zone->notifykeynames = newnames; 4830 zone->notifycnt = count; 4831 unlock: 4832 UNLOCK_ZONE(zone); 4833 return (ISC_R_SUCCESS); 4834} 4835 4836isc_result_t 4837dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters, 4838 isc_uint32_t count) 4839{ 4840 isc_result_t result; 4841 4842 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count); 4843 return (result); 4844} 4845 4846isc_result_t 4847dns_zone_setmasterswithkeys(dns_zone_t *zone, 4848 const isc_sockaddr_t *masters, 4849 dns_name_t **keynames, 4850 isc_uint32_t count) 4851{ 4852 isc_result_t result = ISC_R_SUCCESS; 4853 isc_sockaddr_t *newaddrs = NULL; 4854 dns_name_t **newnames = NULL; 4855 isc_boolean_t *newok; 4856 unsigned int i; 4857 4858 REQUIRE(DNS_ZONE_VALID(zone)); 4859 REQUIRE(count == 0 || masters != NULL); 4860 if (keynames != NULL) { 4861 REQUIRE(count != 0); 4862 } 4863 4864 LOCK_ZONE(zone); 4865 /* 4866 * The refresh code assumes that 'masters' wouldn't change under it. 4867 * If it will change then kill off any current refresh in progress 4868 * and update the masters info. If it won't change then we can just 4869 * unlock and exit. 4870 */ 4871 if (count != zone->masterscnt || 4872 !same_addrs(zone->masters, masters, count) || 4873 !same_keynames(zone->masterkeynames, keynames, count)) { 4874 if (zone->request != NULL) 4875 dns_request_cancel(zone->request); 4876 } else 4877 goto unlock; 4878 4879 /* 4880 * This needs to happen before clear_addresskeylist() sets 4881 * zone->masterscnt to 0: 4882 */ 4883 if (zone->mastersok != NULL) { 4884 isc_mem_put(zone->mctx, zone->mastersok, 4885 zone->masterscnt * sizeof(isc_boolean_t)); 4886 zone->mastersok = NULL; 4887 } 4888 clear_addresskeylist(&zone->masters, &zone->masterkeynames, 4889 &zone->masterscnt, zone->mctx); 4890 /* 4891 * If count == 0, don't allocate any space for masters, mastersok or 4892 * keynames so internally, those pointers are NULL if count == 0 4893 */ 4894 if (count == 0) 4895 goto unlock; 4896 4897 /* 4898 * mastersok must contain count elements 4899 */ 4900 newok = isc_mem_get(zone->mctx, count * sizeof(*newok)); 4901 if (newok == NULL) { 4902 result = ISC_R_NOMEMORY; 4903 isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs)); 4904 goto unlock; 4905 }; 4906 for (i = 0; i < count; i++) 4907 newok[i] = ISC_FALSE; 4908 4909 /* 4910 * Now set up the masters and masterkey lists 4911 */ 4912 result = set_addrkeylist(count, masters, &newaddrs, 4913 keynames, &newnames, zone->mctx); 4914 if (result != ISC_R_SUCCESS) { 4915 isc_mem_put(zone->mctx, newok, count * sizeof(*newok)); 4916 goto unlock; 4917 } 4918 4919 /* 4920 * Everything is ok so attach to the zone. 4921 */ 4922 zone->curmaster = 0; 4923 zone->mastersok = newok; 4924 zone->masters = newaddrs; 4925 zone->masterkeynames = newnames; 4926 zone->masterscnt = count; 4927 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS); 4928 4929 unlock: 4930 UNLOCK_ZONE(zone); 4931 return (result); 4932} 4933 4934isc_result_t 4935dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) { 4936 isc_result_t result = ISC_R_SUCCESS; 4937 4938 REQUIRE(DNS_ZONE_VALID(zone)); 4939 4940 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 4941 if (zone->db == NULL) 4942 result = DNS_R_NOTLOADED; 4943 else 4944 dns_db_attach(zone->db, dpb); 4945 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 4946 4947 return (result); 4948} 4949 4950void 4951dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) { 4952 REQUIRE(DNS_ZONE_VALID(zone)); 4953 REQUIRE(zone->type == dns_zone_staticstub); 4954 4955 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 4956 REQUIRE(zone->db == NULL); 4957 dns_db_attach(db, &zone->db); 4958 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 4959} 4960 4961/* 4962 * Co-ordinates the starting of routine jobs. 4963 */ 4964 4965void 4966dns_zone_maintenance(dns_zone_t *zone) { 4967 const char me[] = "dns_zone_maintenance"; 4968 isc_time_t now; 4969 4970 REQUIRE(DNS_ZONE_VALID(zone)); 4971 ENTER; 4972 4973 LOCK_ZONE(zone); 4974 TIME_NOW(&now); 4975 zone_settimer(zone, &now); 4976 UNLOCK_ZONE(zone); 4977} 4978 4979static inline isc_boolean_t 4980was_dumping(dns_zone_t *zone) { 4981 isc_boolean_t dumping; 4982 4983 REQUIRE(LOCKED_ZONE(zone)); 4984 4985 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING); 4986 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 4987 if (!dumping) { 4988 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 4989 isc_time_settoepoch(&zone->dumptime); 4990 } 4991 return (dumping); 4992} 4993 4994static isc_result_t 4995find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 4996 isc_mem_t *mctx, unsigned int maxkeys, 4997 dst_key_t **keys, unsigned int *nkeys) 4998{ 4999 isc_result_t result; 5000 dns_dbnode_t *node = NULL; 5001 const char *directory = dns_zone_getkeydirectory(zone); 5002 5003 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); 5004 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db), 5005 directory, mctx, maxkeys, keys, 5006 nkeys); 5007 if (result == ISC_R_NOTFOUND) 5008 result = ISC_R_SUCCESS; 5009 failure: 5010 if (node != NULL) 5011 dns_db_detachnode(db, &node); 5012 return (result); 5013} 5014 5015static isc_result_t 5016offline(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name, 5017 dns_ttl_t ttl, dns_rdata_t *rdata) 5018{ 5019 isc_result_t result; 5020 5021 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) 5022 return (ISC_R_SUCCESS); 5023 result = update_one_rr(db, ver, diff, DNS_DIFFOP_DELRESIGN, 5024 name, ttl, rdata); 5025 if (result != ISC_R_SUCCESS) 5026 return (result); 5027 rdata->flags |= DNS_RDATA_OFFLINE; 5028 result = update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, 5029 name, ttl, rdata); 5030 return (result); 5031} 5032 5033static void 5034set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now) 5035{ 5036 unsigned int delta; 5037 char timebuf[80]; 5038 5039 zone->key_expiry = when; 5040 if (when <= now) { 5041 dns_zone_log(zone, ISC_LOG_ERROR, 5042 "DNSKEY RRSIG(s) have expired"); 5043 isc_time_settoepoch(&zone->keywarntime); 5044 } else if (when < now + 7 * 24 * 3600) { 5045 isc_time_t t; 5046 isc_time_set(&t, when, 0); 5047 isc_time_formattimestamp(&t, timebuf, 80); 5048 dns_zone_log(zone, ISC_LOG_WARNING, 5049 "DNSKEY RRSIG(s) will expire within 7 days: %s", 5050 timebuf); 5051 delta = when - now; 5052 delta--; /* loop prevention */ 5053 delta /= 24 * 3600; /* to whole days */ 5054 delta *= 24 * 3600; /* to seconds */ 5055 isc_time_set(&zone->keywarntime, when - delta, 0); 5056 } else { 5057 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0); 5058 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 5059 dns_zone_log(zone, ISC_LOG_NOTICE, 5060 "setting keywarntime to %s", timebuf); 5061 } 5062} 5063 5064/* 5065 * Helper function to del_sigs(). We don't want to delete RRSIGs that 5066 * have no new key. 5067 */ 5068static isc_boolean_t 5069delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys) { 5070 unsigned int i = 0; 5071 5072 /* 5073 * It's okay to delete a signature if there is an active ZSK 5074 * with the same algorithm 5075 */ 5076 for (i = 0; i < nkeys; i++) { 5077 if (rrsig_ptr->algorithm == dst_key_alg(keys[i]) && 5078 (dst_key_isprivate(keys[i])) && !KSK(keys[i])) 5079 return (ISC_TRUE); 5080 } 5081 5082 /* 5083 * Failing that, it is *not* okay to delete a signature 5084 * if the associated public key is still in the DNSKEY RRset 5085 */ 5086 for (i = 0; i < nkeys; i++) { 5087 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) && 5088 (rrsig_ptr->keyid == dst_key_id(keys[i]))) 5089 return (ISC_FALSE); 5090 } 5091 5092 /* 5093 * But if the key is gone, then go ahead. 5094 */ 5095 return (ISC_TRUE); 5096} 5097 5098/* 5099 * Delete expired RRsigs and any RRsigs we are about to re-sign. 5100 * See also update.c:del_keysigs(). 5101 */ 5102static isc_result_t 5103del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 5104 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, 5105 unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental) 5106{ 5107 isc_result_t result; 5108 dns_dbnode_t *node = NULL; 5109 dns_rdataset_t rdataset; 5110 unsigned int i; 5111 dns_rdata_rrsig_t rrsig; 5112 isc_boolean_t found, changed; 5113 isc_int64_t warn = 0, maybe = 0; 5114 5115 dns_rdataset_init(&rdataset); 5116 5117 if (type == dns_rdatatype_nsec3) 5118 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node); 5119 else 5120 result = dns_db_findnode(db, name, ISC_FALSE, &node); 5121 if (result == ISC_R_NOTFOUND) 5122 return (ISC_R_SUCCESS); 5123 if (result != ISC_R_SUCCESS) 5124 goto failure; 5125 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type, 5126 (isc_stdtime_t) 0, &rdataset, NULL); 5127 dns_db_detachnode(db, &node); 5128 5129 if (result == ISC_R_NOTFOUND) { 5130 INSIST(!dns_rdataset_isassociated(&rdataset)); 5131 return (ISC_R_SUCCESS); 5132 } 5133 if (result != ISC_R_SUCCESS) { 5134 INSIST(!dns_rdataset_isassociated(&rdataset)); 5135 goto failure; 5136 } 5137 5138 changed = ISC_FALSE; 5139 for (result = dns_rdataset_first(&rdataset); 5140 result == ISC_R_SUCCESS; 5141 result = dns_rdataset_next(&rdataset)) { 5142 dns_rdata_t rdata = DNS_RDATA_INIT; 5143 5144 dns_rdataset_current(&rdataset, &rdata); 5145 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 5146 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5147 5148 if (type != dns_rdatatype_dnskey) { 5149 if (delsig_ok(&rrsig, keys, nkeys)) { 5150 result = update_one_rr(db, ver, diff, 5151 DNS_DIFFOP_DELRESIGN, name, 5152 rdataset.ttl, &rdata); 5153 if (incremental) 5154 changed = ISC_TRUE; 5155 if (result != ISC_R_SUCCESS) 5156 break; 5157 } else { 5158 /* 5159 * At this point, we've got an RRSIG, 5160 * which is signed by an inactive key. 5161 * An administrator needs to provide a new 5162 * key/alg, but until that time, we want to 5163 * keep the old RRSIG. Marking the key as 5164 * offline will prevent us spinning waiting 5165 * for the private part. 5166 */ 5167 if (incremental) { 5168 result = offline(db, ver, diff, name, 5169 rdataset.ttl, &rdata); 5170 changed = ISC_TRUE; 5171 if (result != ISC_R_SUCCESS) 5172 break; 5173 } 5174 5175 /* 5176 * Log the key id and algorithm of 5177 * the inactive key with no replacement 5178 */ 5179 if (zone->log_key_expired_timer <= now) { 5180 char origin[DNS_NAME_FORMATSIZE]; 5181 char algbuf[DNS_NAME_FORMATSIZE]; 5182 dns_name_format(&zone->origin, origin, 5183 sizeof(origin)); 5184 dns_secalg_format(rrsig.algorithm, 5185 algbuf, 5186 sizeof(algbuf)); 5187 dns_zone_log(zone, ISC_LOG_WARNING, 5188 "Key %s/%s/%d " 5189 "missing or inactive " 5190 "and has no replacement: " 5191 "retaining signatures.", 5192 origin, algbuf, 5193 rrsig.keyid); 5194 zone->log_key_expired_timer = now + 5195 3600; 5196 } 5197 } 5198 continue; 5199 } 5200 5201 /* 5202 * RRSIG(DNSKEY) requires special processing. 5203 */ 5204 found = ISC_FALSE; 5205 for (i = 0; i < nkeys; i++) { 5206 if (rrsig.algorithm == dst_key_alg(keys[i]) && 5207 rrsig.keyid == dst_key_id(keys[i])) { 5208 found = ISC_TRUE; 5209 /* 5210 * Mark offline RRSIG(DNSKEY). 5211 * We want the earliest offline expire time 5212 * iff there is a new offline signature. 5213 */ 5214 if (!dst_key_isprivate(keys[i])) { 5215 isc_int64_t timeexpire = 5216 dns_time64_from32(rrsig.timeexpire); 5217 if (warn != 0 && warn > timeexpire) 5218 warn = timeexpire; 5219 if (rdata.flags & DNS_RDATA_OFFLINE) { 5220 if (maybe == 0 || 5221 maybe > timeexpire) 5222 maybe = timeexpire; 5223 break; 5224 } 5225 if (warn == 0) 5226 warn = maybe; 5227 if (warn == 0 || warn > timeexpire) 5228 warn = timeexpire; 5229 result = offline(db, ver, diff, name, 5230 rdataset.ttl, &rdata); 5231 break; 5232 } 5233 result = update_one_rr(db, ver, diff, 5234 DNS_DIFFOP_DELRESIGN, 5235 name, rdataset.ttl, 5236 &rdata); 5237 break; 5238 } 5239 } 5240 5241 /* 5242 * If there is not a matching DNSKEY then 5243 * delete the RRSIG. 5244 */ 5245 if (!found) 5246 result = update_one_rr(db, ver, diff, 5247 DNS_DIFFOP_DELRESIGN, name, 5248 rdataset.ttl, &rdata); 5249 if (result != ISC_R_SUCCESS) 5250 break; 5251 } 5252 5253 if (changed && (rdataset.attributes & DNS_RDATASETATTR_RESIGN) != 0) 5254 dns_db_resigned(db, &rdataset, ver); 5255 5256 dns_rdataset_disassociate(&rdataset); 5257 if (result == ISC_R_NOMORE) 5258 result = ISC_R_SUCCESS; 5259 if (warn > 0) { 5260#if defined(STDTIME_ON_32BITS) 5261 isc_stdtime_t stdwarn = (isc_stdtime_t)warn; 5262 if (warn == stdwarn) 5263#endif 5264 set_key_expiry_warning(zone, (isc_stdtime_t)warn, now); 5265#if defined(STDTIME_ON_32BITS) 5266 else 5267 dns_zone_log(zone, ISC_LOG_ERROR, 5268 "key expiry warning time out of range"); 5269#endif 5270 } 5271 failure: 5272 if (node != NULL) 5273 dns_db_detachnode(db, &node); 5274 return (result); 5275} 5276 5277static isc_result_t 5278add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 5279 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, 5280 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception, 5281 isc_stdtime_t expire, isc_boolean_t check_ksk, 5282 isc_boolean_t keyset_kskonly) 5283{ 5284 isc_result_t result; 5285 dns_dbnode_t *node = NULL; 5286 dns_rdataset_t rdataset; 5287 dns_rdata_t sig_rdata = DNS_RDATA_INIT; 5288 unsigned char data[1024]; /* XXX */ 5289 isc_buffer_t buffer; 5290 unsigned int i, j; 5291 5292 dns_rdataset_init(&rdataset); 5293 isc_buffer_init(&buffer, data, sizeof(data)); 5294 5295 if (type == dns_rdatatype_nsec3) 5296 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node); 5297 else 5298 result = dns_db_findnode(db, name, ISC_FALSE, &node); 5299 if (result == ISC_R_NOTFOUND) 5300 return (ISC_R_SUCCESS); 5301 if (result != ISC_R_SUCCESS) 5302 goto failure; 5303 result = dns_db_findrdataset(db, node, ver, type, 0, 5304 (isc_stdtime_t) 0, &rdataset, NULL); 5305 dns_db_detachnode(db, &node); 5306 if (result == ISC_R_NOTFOUND) { 5307 INSIST(!dns_rdataset_isassociated(&rdataset)); 5308 return (ISC_R_SUCCESS); 5309 } 5310 if (result != ISC_R_SUCCESS) { 5311 INSIST(!dns_rdataset_isassociated(&rdataset)); 5312 goto failure; 5313 } 5314 5315 for (i = 0; i < nkeys; i++) { 5316 isc_boolean_t both = ISC_FALSE; 5317 5318 if (!dst_key_isprivate(keys[i])) 5319 continue; 5320 5321 if (check_ksk && !REVOKE(keys[i])) { 5322 isc_boolean_t have_ksk, have_nonksk; 5323 if (KSK(keys[i])) { 5324 have_ksk = ISC_TRUE; 5325 have_nonksk = ISC_FALSE; 5326 } else { 5327 have_ksk = ISC_FALSE; 5328 have_nonksk = ISC_TRUE; 5329 } 5330 for (j = 0; j < nkeys; j++) { 5331 if (j == i || ALG(keys[i]) != ALG(keys[j])) 5332 continue; 5333 if (REVOKE(keys[j])) 5334 continue; 5335 if (KSK(keys[j])) 5336 have_ksk = ISC_TRUE; 5337 else 5338 have_nonksk = ISC_TRUE; 5339 both = have_ksk && have_nonksk; 5340 if (both) 5341 break; 5342 } 5343 } 5344 if (both) { 5345 if (type == dns_rdatatype_dnskey) { 5346 if (!KSK(keys[i]) && keyset_kskonly) 5347 continue; 5348 } else if (KSK(keys[i])) 5349 continue; 5350 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) 5351 continue; 5352 5353 /* Calculate the signature, creating a RRSIG RDATA. */ 5354 isc_buffer_clear(&buffer); 5355 CHECK(dns_dnssec_sign(name, &rdataset, keys[i], 5356 &inception, &expire, 5357 mctx, &buffer, &sig_rdata)); 5358 /* Update the database and journal with the RRSIG. */ 5359 /* XXX inefficient - will cause dataset merging */ 5360 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, 5361 name, rdataset.ttl, &sig_rdata)); 5362 dns_rdata_reset(&sig_rdata); 5363 isc_buffer_init(&buffer, data, sizeof(data)); 5364 } 5365 5366 failure: 5367 if (dns_rdataset_isassociated(&rdataset)) 5368 dns_rdataset_disassociate(&rdataset); 5369 if (node != NULL) 5370 dns_db_detachnode(db, &node); 5371 return (result); 5372} 5373 5374static void 5375zone_resigninc(dns_zone_t *zone) { 5376 dns_db_t *db = NULL; 5377 dns_dbversion_t *version = NULL; 5378 dns_diff_t sig_diff; 5379 dns_fixedname_t fixed; 5380 dns_name_t *name; 5381 dns_rdataset_t rdataset; 5382 dns_rdatatype_t covers; 5383 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 5384 isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE; 5385 isc_result_t result; 5386 isc_stdtime_t now, inception, soaexpire, expire, stop; 5387 isc_uint32_t jitter; 5388 unsigned int i; 5389 unsigned int nkeys = 0; 5390 unsigned int resign; 5391 5392 dns_rdataset_init(&rdataset); 5393 dns_fixedname_init(&fixed); 5394 dns_diff_init(zone->mctx, &sig_diff); 5395 sig_diff.resign = zone->sigresigninginterval; 5396 5397 5398 /* 5399 * Zone is frozen or automatic resigning is disabled. 5400 * Pause for 5 minutes. 5401 */ 5402 if (zone->update_disabled || 5403 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN)) 5404 { 5405 result = ISC_R_FAILURE; 5406 goto failure; 5407 } 5408 5409 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 5410 dns_db_attach(zone->db, &db); 5411 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 5412 5413 result = dns_db_newversion(db, &version); 5414 if (result != ISC_R_SUCCESS) { 5415 dns_zone_log(zone, ISC_LOG_ERROR, 5416 "zone_resigninc:dns_db_newversion -> %s", 5417 dns_result_totext(result)); 5418 goto failure; 5419 } 5420 5421 result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS, 5422 zone_keys, &nkeys); 5423 if (result != ISC_R_SUCCESS) { 5424 dns_zone_log(zone, ISC_LOG_ERROR, 5425 "zone_resigninc:find_zone_keys -> %s", 5426 dns_result_totext(result)); 5427 goto failure; 5428 } 5429 5430 isc_stdtime_get(&now); 5431 inception = now - 3600; /* Allow for clock skew. */ 5432 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 5433 /* 5434 * Spread out signatures over time if they happen to be 5435 * clumped. We don't do this for each add_sigs() call as 5436 * we still want some clustering to occur. 5437 */ 5438 isc_random_get(&jitter); 5439 expire = soaexpire - jitter % 3600; 5440 stop = now + 5; 5441 5442 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 5443 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 5444 5445 name = dns_fixedname_name(&fixed); 5446 result = dns_db_getsigningtime(db, &rdataset, name); 5447 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 5448 dns_zone_log(zone, ISC_LOG_ERROR, 5449 "zone_resigninc:dns_db_getsigningtime -> %s", 5450 dns_result_totext(result)); 5451 } 5452 5453 i = 0; 5454 while (result == ISC_R_SUCCESS) { 5455 resign = rdataset.resign; 5456 covers = rdataset.covers; 5457 dns_rdataset_disassociate(&rdataset); 5458 5459 /* 5460 * Stop if we hit the SOA as that means we have walked the 5461 * entire zone. The SOA record should always be the most 5462 * recent signature. 5463 */ 5464 /* XXXMPA increase number of RRsets signed pre call */ 5465 if (covers == dns_rdatatype_soa || i++ > zone->signatures || 5466 resign > stop) 5467 break; 5468 5469 result = del_sigs(zone, db, version, name, covers, &sig_diff, 5470 zone_keys, nkeys, now, ISC_TRUE); 5471 if (result != ISC_R_SUCCESS) { 5472 dns_zone_log(zone, ISC_LOG_ERROR, 5473 "zone_resigninc:del_sigs -> %s", 5474 dns_result_totext(result)); 5475 break; 5476 } 5477 5478 result = add_sigs(db, version, name, covers, &sig_diff, 5479 zone_keys, nkeys, zone->mctx, inception, 5480 expire, check_ksk, keyset_kskonly); 5481 if (result != ISC_R_SUCCESS) { 5482 dns_zone_log(zone, ISC_LOG_ERROR, 5483 "zone_resigninc:add_sigs -> %s", 5484 dns_result_totext(result)); 5485 break; 5486 } 5487 result = dns_db_getsigningtime(db, &rdataset, 5488 dns_fixedname_name(&fixed)); 5489 if (nkeys == 0 && result == ISC_R_NOTFOUND) { 5490 result = ISC_R_SUCCESS; 5491 break; 5492 } 5493 if (result != ISC_R_SUCCESS) 5494 dns_zone_log(zone, ISC_LOG_ERROR, 5495 "zone_resigninc:dns_db_getsigningtime -> %s", 5496 dns_result_totext(result)); 5497 } 5498 5499 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS) 5500 goto failure; 5501 5502 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 5503 &sig_diff, zone_keys, nkeys, now, ISC_TRUE); 5504 if (result != ISC_R_SUCCESS) { 5505 dns_zone_log(zone, ISC_LOG_ERROR, 5506 "zone_resigninc:del_sigs -> %s", 5507 dns_result_totext(result)); 5508 goto failure; 5509 } 5510 5511 /* 5512 * Did we change anything in the zone? 5513 */ 5514 if (ISC_LIST_EMPTY(sig_diff.tuples)) 5515 goto failure; 5516 5517 /* Increment SOA serial if we have made changes */ 5518 result = update_soa_serial(db, version, &sig_diff, zone->mctx, 5519 zone->updatemethod); 5520 if (result != ISC_R_SUCCESS) { 5521 dns_zone_log(zone, ISC_LOG_ERROR, 5522 "zone_resigninc:update_soa_serial -> %s", 5523 dns_result_totext(result)); 5524 goto failure; 5525 } 5526 5527 /* 5528 * Generate maximum life time signatures so that the above loop 5529 * termination is sensible. 5530 */ 5531 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, 5532 &sig_diff, zone_keys, nkeys, zone->mctx, inception, 5533 soaexpire, check_ksk, keyset_kskonly); 5534 if (result != ISC_R_SUCCESS) { 5535 dns_zone_log(zone, ISC_LOG_ERROR, 5536 "zone_resigninc:add_sigs -> %s", 5537 dns_result_totext(result)); 5538 goto failure; 5539 } 5540 5541 /* Write changes to journal file. */ 5542 CHECK(zone_journal(zone, &sig_diff, NULL, "zone_resigninc")); 5543 5544 /* Everything has succeeded. Commit the changes. */ 5545 dns_db_closeversion(db, &version, ISC_TRUE); 5546 5547 failure: 5548 dns_diff_clear(&sig_diff); 5549 for (i = 0; i < nkeys; i++) 5550 dst_key_free(&zone_keys[i]); 5551 if (version != NULL) { 5552 dns_db_closeversion(zone->db, &version, ISC_FALSE); 5553 dns_db_detach(&db); 5554 } else if (db != NULL) 5555 dns_db_detach(&db); 5556 if (result == ISC_R_SUCCESS) { 5557 set_resigntime(zone); 5558 LOCK_ZONE(zone); 5559 zone_needdump(zone, DNS_DUMP_DELAY); 5560 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 5561 UNLOCK_ZONE(zone); 5562 } else { 5563 /* 5564 * Something failed. Retry in 5 minutes. 5565 */ 5566 isc_interval_t ival; 5567 isc_interval_set(&ival, 300, 0); 5568 isc_time_nowplusinterval(&zone->resigntime, &ival); 5569 } 5570} 5571 5572static isc_result_t 5573next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname, 5574 dns_name_t *newname, isc_boolean_t bottom) 5575{ 5576 isc_result_t result; 5577 dns_dbiterator_t *dbit = NULL; 5578 dns_rdatasetiter_t *rdsit = NULL; 5579 dns_dbnode_t *node = NULL; 5580 5581 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit)); 5582 CHECK(dns_dbiterator_seek(dbit, oldname)); 5583 do { 5584 result = dns_dbiterator_next(dbit); 5585 if (result == ISC_R_NOMORE) 5586 CHECK(dns_dbiterator_first(dbit)); 5587 CHECK(dns_dbiterator_current(dbit, &node, newname)); 5588 if (bottom && dns_name_issubdomain(newname, oldname) && 5589 !dns_name_equal(newname, oldname)) { 5590 dns_db_detachnode(db, &node); 5591 continue; 5592 } 5593 /* 5594 * Is this node empty? 5595 */ 5596 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit)); 5597 result = dns_rdatasetiter_first(rdsit); 5598 dns_db_detachnode(db, &node); 5599 dns_rdatasetiter_destroy(&rdsit); 5600 if (result != ISC_R_NOMORE) 5601 break; 5602 } while (1); 5603 failure: 5604 if (node != NULL) 5605 dns_db_detachnode(db, &node); 5606 if (dbit != NULL) 5607 dns_dbiterator_destroy(&dbit); 5608 return (result); 5609} 5610 5611static isc_boolean_t 5612signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 5613 dns_rdatatype_t type, dst_key_t *key) 5614{ 5615 isc_result_t result; 5616 dns_rdataset_t rdataset; 5617 dns_rdata_t rdata = DNS_RDATA_INIT; 5618 dns_rdata_rrsig_t rrsig; 5619 5620 dns_rdataset_init(&rdataset); 5621 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig, 5622 type, 0, &rdataset, NULL); 5623 if (result != ISC_R_SUCCESS) { 5624 INSIST(!dns_rdataset_isassociated(&rdataset)); 5625 return (ISC_FALSE); 5626 } 5627 for (result = dns_rdataset_first(&rdataset); 5628 result == ISC_R_SUCCESS; 5629 result = dns_rdataset_next(&rdataset)) { 5630 dns_rdataset_current(&rdataset, &rdata); 5631 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 5632 INSIST(result == ISC_R_SUCCESS); 5633 if (rrsig.algorithm == dst_key_alg(key) && 5634 rrsig.keyid == dst_key_id(key)) { 5635 dns_rdataset_disassociate(&rdataset); 5636 return (ISC_TRUE); 5637 } 5638 dns_rdata_reset(&rdata); 5639 } 5640 dns_rdataset_disassociate(&rdataset); 5641 return (ISC_FALSE); 5642} 5643 5644static isc_result_t 5645add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 5646 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom, 5647 dns_diff_t *diff) 5648{ 5649 dns_fixedname_t fixed; 5650 dns_name_t *next; 5651 dns_rdata_t rdata = DNS_RDATA_INIT; 5652 isc_result_t result; 5653 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE]; 5654 5655 dns_fixedname_init(&fixed); 5656 next = dns_fixedname_name(&fixed); 5657 5658 CHECK(next_active(db, version, name, next, bottom)); 5659 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer, 5660 &rdata)); 5661 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl, 5662 &rdata)); 5663 failure: 5664 return (result); 5665} 5666 5667static isc_result_t 5668sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node, 5669 dns_dbversion_t *version, isc_boolean_t build_nsec3, 5670 isc_boolean_t build_nsec, dst_key_t *key, 5671 isc_stdtime_t inception, isc_stdtime_t expire, 5672 unsigned int minimum, isc_boolean_t is_ksk, 5673 isc_boolean_t keyset_kskonly, isc_boolean_t *delegation, 5674 dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx) 5675{ 5676 isc_result_t result; 5677 dns_rdatasetiter_t *iterator = NULL; 5678 dns_rdataset_t rdataset; 5679 dns_rdata_t rdata = DNS_RDATA_INIT; 5680 isc_buffer_t buffer; 5681 unsigned char data[1024]; 5682 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec, 5683 seen_nsec3, seen_ds; 5684 isc_boolean_t bottom; 5685 5686 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 5687 if (result != ISC_R_SUCCESS) { 5688 if (result == ISC_R_NOTFOUND) 5689 result = ISC_R_SUCCESS; 5690 return (result); 5691 } 5692 5693 dns_rdataset_init(&rdataset); 5694 isc_buffer_init(&buffer, data, sizeof(data)); 5695 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec = 5696 seen_nsec3 = seen_ds = ISC_FALSE; 5697 for (result = dns_rdatasetiter_first(iterator); 5698 result == ISC_R_SUCCESS; 5699 result = dns_rdatasetiter_next(iterator)) { 5700 dns_rdatasetiter_current(iterator, &rdataset); 5701 if (rdataset.type == dns_rdatatype_soa) 5702 seen_soa = ISC_TRUE; 5703 else if (rdataset.type == dns_rdatatype_ns) 5704 seen_ns = ISC_TRUE; 5705 else if (rdataset.type == dns_rdatatype_ds) 5706 seen_ds = ISC_TRUE; 5707 else if (rdataset.type == dns_rdatatype_dname) 5708 seen_dname = ISC_TRUE; 5709 else if (rdataset.type == dns_rdatatype_nsec) 5710 seen_nsec = ISC_TRUE; 5711 else if (rdataset.type == dns_rdatatype_nsec3) 5712 seen_nsec3 = ISC_TRUE; 5713 if (rdataset.type != dns_rdatatype_rrsig) 5714 seen_rr = ISC_TRUE; 5715 dns_rdataset_disassociate(&rdataset); 5716 } 5717 if (result != ISC_R_NOMORE) 5718 goto failure; 5719 if (seen_ns && !seen_soa) 5720 *delegation = ISC_TRUE; 5721 /* 5722 * Going from insecure to NSEC3. 5723 * Don't generate NSEC3 records for NSEC3 records. 5724 */ 5725 if (build_nsec3 && !seen_nsec3 && seen_rr) { 5726 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa; 5727 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum, 5728 unsecure, diff)); 5729 (*signatures)--; 5730 } 5731 /* 5732 * Going from insecure to NSEC. 5733 * Don't generate NSEC records for NSEC3 records. 5734 */ 5735 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) { 5736 /* Build and add NSEC. */ 5737 bottom = (seen_ns && !seen_soa) || seen_dname; 5738 /* 5739 * Build a NSEC record except at the origin. 5740 */ 5741 if (!dns_name_equal(name, dns_db_origin(db))) { 5742 CHECK(add_nsec(db, version, name, node, minimum, 5743 bottom, diff)); 5744 /* Count a NSEC generation as a signature generation. */ 5745 (*signatures)--; 5746 } 5747 } 5748 result = dns_rdatasetiter_first(iterator); 5749 while (result == ISC_R_SUCCESS) { 5750 dns_rdatasetiter_current(iterator, &rdataset); 5751 if (rdataset.type == dns_rdatatype_soa || 5752 rdataset.type == dns_rdatatype_rrsig) 5753 goto next_rdataset; 5754 if (rdataset.type == dns_rdatatype_dnskey) { 5755 if (!is_ksk && keyset_kskonly) 5756 goto next_rdataset; 5757 } else if (is_ksk) 5758 goto next_rdataset; 5759 if (*delegation && 5760 rdataset.type != dns_rdatatype_ds && 5761 rdataset.type != dns_rdatatype_nsec) 5762 goto next_rdataset; 5763 if (signed_with_key(db, node, version, rdataset.type, key)) 5764 goto next_rdataset; 5765 /* Calculate the signature, creating a RRSIG RDATA. */ 5766 isc_buffer_clear(&buffer); 5767 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception, 5768 &expire, mctx, &buffer, &rdata)); 5769 /* Update the database and journal with the RRSIG. */ 5770 /* XXX inefficient - will cause dataset merging */ 5771 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN, 5772 name, rdataset.ttl, &rdata)); 5773 dns_rdata_reset(&rdata); 5774 (*signatures)--; 5775 next_rdataset: 5776 dns_rdataset_disassociate(&rdataset); 5777 result = dns_rdatasetiter_next(iterator); 5778 } 5779 if (result == ISC_R_NOMORE) 5780 result = ISC_R_SUCCESS; 5781 if (seen_dname) 5782 *delegation = ISC_TRUE; 5783 failure: 5784 if (dns_rdataset_isassociated(&rdataset)) 5785 dns_rdataset_disassociate(&rdataset); 5786 if (iterator != NULL) 5787 dns_rdatasetiter_destroy(&iterator); 5788 return (result); 5789} 5790 5791/* 5792 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist. 5793 */ 5794static isc_result_t 5795updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 5796 dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff) 5797{ 5798 isc_result_t result; 5799 dns_rdataset_t rdataset; 5800 dns_dbnode_t *node = NULL; 5801 5802 CHECK(dns_db_getoriginnode(db, &node)); 5803 if (update_only) { 5804 dns_rdataset_init(&rdataset); 5805 result = dns_db_findrdataset(db, node, version, 5806 dns_rdatatype_nsec, 5807 dns_rdatatype_none, 5808 0, &rdataset, NULL); 5809 if (dns_rdataset_isassociated(&rdataset)) 5810 dns_rdataset_disassociate(&rdataset); 5811 if (result == ISC_R_NOTFOUND) 5812 goto success; 5813 if (result != ISC_R_SUCCESS) 5814 goto failure; 5815 } 5816 CHECK(delete_nsec(db, version, node, name, diff)); 5817 CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff)); 5818 success: 5819 result = ISC_R_SUCCESS; 5820 failure: 5821 if (node != NULL) 5822 dns_db_detachnode(db, &node); 5823 return (result); 5824} 5825 5826static isc_result_t 5827updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing, 5828 dns_dbversion_t *version, isc_boolean_t build_nsec3, 5829 dns_ttl_t minimum, dns_diff_t *diff) 5830{ 5831 isc_result_t result; 5832 dns_dbnode_t *node = NULL; 5833 dns_rdataset_t rdataset; 5834 dns_rdata_t rdata = DNS_RDATA_INIT; 5835 unsigned char data[5]; 5836 isc_boolean_t seen_done = ISC_FALSE; 5837 isc_boolean_t have_rr = ISC_FALSE; 5838 5839 dns_rdataset_init(&rdataset); 5840 result = dns_db_getoriginnode(signing->db, &node); 5841 if (result != ISC_R_SUCCESS) 5842 goto failure; 5843 5844 result = dns_db_findrdataset(signing->db, node, version, 5845 zone->privatetype, dns_rdatatype_none, 5846 0, &rdataset, NULL); 5847 if (result == ISC_R_NOTFOUND) { 5848 INSIST(!dns_rdataset_isassociated(&rdataset)); 5849 result = ISC_R_SUCCESS; 5850 goto failure; 5851 } 5852 if (result != ISC_R_SUCCESS) { 5853 INSIST(!dns_rdataset_isassociated(&rdataset)); 5854 goto failure; 5855 } 5856 for (result = dns_rdataset_first(&rdataset); 5857 result == ISC_R_SUCCESS; 5858 result = dns_rdataset_next(&rdataset)) { 5859 dns_rdataset_current(&rdataset, &rdata); 5860 /* 5861 * If we don't match the algorithm or keyid skip the record. 5862 */ 5863 if (rdata.length != 5 || 5864 rdata.data[0] != signing->algorithm || 5865 rdata.data[1] != ((signing->keyid >> 8) & 0xff) || 5866 rdata.data[2] != (signing->keyid & 0xff)) { 5867 have_rr = ISC_TRUE; 5868 dns_rdata_reset(&rdata); 5869 continue; 5870 } 5871 /* 5872 * We have a match. If we were signing (!signing->delete) 5873 * and we already have a record indicating that we have 5874 * finished signing (rdata.data[4] != 0) then keep it. 5875 * Otherwise it needs to be deleted as we have removed all 5876 * the signatures (signing->delete), so any record indicating 5877 * completion is now out of date, or we have finished signing 5878 * with the new record so we no longer need to remember that 5879 * we need to sign the zone with the matching key across a 5880 * nameserver re-start. 5881 */ 5882 if (!signing->delete && rdata.data[4] != 0) { 5883 seen_done = ISC_TRUE; 5884 have_rr = ISC_TRUE; 5885 } else 5886 CHECK(update_one_rr(signing->db, version, diff, 5887 DNS_DIFFOP_DEL, &zone->origin, 5888 rdataset.ttl, &rdata)); 5889 dns_rdata_reset(&rdata); 5890 } 5891 if (result == ISC_R_NOMORE) 5892 result = ISC_R_SUCCESS; 5893 if (!signing->delete && !seen_done) { 5894 /* 5895 * If we were signing then we need to indicate that we have 5896 * finished signing the zone with this key. If it is already 5897 * there we don't need to add it a second time. 5898 */ 5899 data[0] = signing->algorithm; 5900 data[1] = (signing->keyid >> 8) & 0xff; 5901 data[2] = signing->keyid & 0xff; 5902 data[3] = 0; 5903 data[4] = 1; 5904 rdata.length = sizeof(data); 5905 rdata.data = data; 5906 rdata.type = zone->privatetype; 5907 rdata.rdclass = dns_db_class(signing->db); 5908 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD, 5909 &zone->origin, rdataset.ttl, &rdata)); 5910 } else if (!have_rr) { 5911 dns_name_t *origin = dns_db_origin(signing->db); 5912 /* 5913 * Rebuild the NSEC/NSEC3 record for the origin as we no 5914 * longer have any private records. 5915 */ 5916 if (build_nsec3) 5917 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin, 5918 minimum, ISC_FALSE, diff)); 5919 CHECK(updatesecure(signing->db, version, origin, minimum, 5920 ISC_TRUE, diff)); 5921 } 5922 5923 failure: 5924 if (dns_rdataset_isassociated(&rdataset)) 5925 dns_rdataset_disassociate(&rdataset); 5926 if (node != NULL) 5927 dns_db_detachnode(signing->db, &node); 5928 return (result); 5929} 5930 5931/* 5932 * If 'active' is set then we are not done with the chain yet so only 5933 * delete the nsec3param record which indicates a full chain exists 5934 * (flags == 0). 5935 */ 5936static isc_result_t 5937fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain, 5938 isc_boolean_t active, dns_rdatatype_t privatetype, 5939 dns_diff_t *diff) 5940{ 5941 dns_dbnode_t *node = NULL; 5942 dns_name_t *name = dns_db_origin(db); 5943 dns_rdata_t rdata = DNS_RDATA_INIT; 5944 dns_rdataset_t rdataset; 5945 dns_rdata_nsec3param_t nsec3param; 5946 isc_result_t result; 5947 isc_buffer_t buffer; 5948 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE]; 5949 dns_ttl_t ttl = 0; 5950 isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; 5951 5952 dns_rdataset_init(&rdataset); 5953 5954 result = dns_db_getoriginnode(db, &node); 5955 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5956 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 5957 0, 0, &rdataset, NULL); 5958 if (result == ISC_R_NOTFOUND) 5959 goto try_private; 5960 if (result != ISC_R_SUCCESS) 5961 goto failure; 5962 5963 /* 5964 * Preserve the existing ttl. 5965 */ 5966 ttl = rdataset.ttl; 5967 5968 /* 5969 * Delete all NSEC3PARAM records which match that in nsec3chain. 5970 */ 5971 for (result = dns_rdataset_first(&rdataset); 5972 result == ISC_R_SUCCESS; 5973 result = dns_rdataset_next(&rdataset)) { 5974 5975 dns_rdataset_current(&rdataset, &rdata); 5976 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 5977 5978 if (nsec3param.hash != chain->nsec3param.hash || 5979 (active && nsec3param.flags != 0) || 5980 nsec3param.iterations != chain->nsec3param.iterations || 5981 nsec3param.salt_length != chain->nsec3param.salt_length || 5982 memcmp(nsec3param.salt, chain->nsec3param.salt, 5983 nsec3param.salt_length)) { 5984 dns_rdata_reset(&rdata); 5985 continue; 5986 } 5987 5988 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, 5989 name, rdataset.ttl, &rdata)); 5990 dns_rdata_reset(&rdata); 5991 } 5992 if (result != ISC_R_NOMORE) 5993 goto failure; 5994 5995 dns_rdataset_disassociate(&rdataset); 5996 5997 try_private: 5998 5999 if (active) 6000 goto add; 6001 6002 result = dns_nsec_nseconly(db, ver, &nseconly); 6003 nsec3ok = (result == ISC_R_SUCCESS && !nseconly); 6004 6005 /* 6006 * Delete all private records which match that in nsec3chain. 6007 */ 6008 result = dns_db_findrdataset(db, node, ver, privatetype, 6009 0, 0, &rdataset, NULL); 6010 if (result == ISC_R_NOTFOUND) 6011 goto add; 6012 if (result != ISC_R_SUCCESS) 6013 goto failure; 6014 6015 for (result = dns_rdataset_first(&rdataset); 6016 result == ISC_R_SUCCESS; 6017 result = dns_rdataset_next(&rdataset)) { 6018 dns_rdata_t private = DNS_RDATA_INIT; 6019 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 6020 6021 dns_rdataset_current(&rdataset, &private); 6022 if (!dns_nsec3param_fromprivate(&private, &rdata, 6023 buf, sizeof(buf))) 6024 continue; 6025 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 6026 6027 if ((!nsec3ok && 6028 (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) || 6029 nsec3param.hash != chain->nsec3param.hash || 6030 nsec3param.iterations != chain->nsec3param.iterations || 6031 nsec3param.salt_length != chain->nsec3param.salt_length || 6032 memcmp(nsec3param.salt, chain->nsec3param.salt, 6033 nsec3param.salt_length)) { 6034 dns_rdata_reset(&rdata); 6035 continue; 6036 } 6037 6038 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, 6039 name, rdataset.ttl, &private)); 6040 dns_rdata_reset(&rdata); 6041 } 6042 if (result != ISC_R_NOMORE) 6043 goto failure; 6044 6045 add: 6046 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) { 6047 result = ISC_R_SUCCESS; 6048 goto failure; 6049 } 6050 6051 /* 6052 * Add a NSEC3PARAM record which matches that in nsec3chain but 6053 * with all flags bits cleared. 6054 * 6055 * Note: we do not clear chain->nsec3param.flags as this change 6056 * may be reversed. 6057 */ 6058 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf)); 6059 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), 6060 dns_rdatatype_nsec3param, 6061 &chain->nsec3param, &buffer)); 6062 rdata.data[1] = 0; /* Clear flag bits. */ 6063 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata)); 6064 6065 failure: 6066 dns_db_detachnode(db, &node); 6067 if (dns_rdataset_isassociated(&rdataset)) 6068 dns_rdataset_disassociate(&rdataset); 6069 return (result); 6070} 6071 6072static isc_result_t 6073delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 6074 dns_name_t *name, dns_diff_t *diff) 6075{ 6076 dns_rdataset_t rdataset; 6077 isc_result_t result; 6078 6079 dns_rdataset_init(&rdataset); 6080 6081 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 6082 0, 0, &rdataset, NULL); 6083 if (result == ISC_R_NOTFOUND) 6084 return (ISC_R_SUCCESS); 6085 if (result != ISC_R_SUCCESS) 6086 return (result); 6087 for (result = dns_rdataset_first(&rdataset); 6088 result == ISC_R_SUCCESS; 6089 result = dns_rdataset_next(&rdataset)) { 6090 dns_rdata_t rdata = DNS_RDATA_INIT; 6091 6092 dns_rdataset_current(&rdataset, &rdata); 6093 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 6094 rdataset.ttl, &rdata)); 6095 } 6096 if (result == ISC_R_NOMORE) 6097 result = ISC_R_SUCCESS; 6098 failure: 6099 dns_rdataset_disassociate(&rdataset); 6100 return (result); 6101} 6102 6103static isc_result_t 6104deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 6105 dns_name_t *name, const dns_rdata_nsec3param_t *param, 6106 dns_diff_t *diff) 6107{ 6108 dns_rdataset_t rdataset; 6109 dns_rdata_nsec3_t nsec3; 6110 isc_result_t result; 6111 6112 dns_rdataset_init(&rdataset); 6113 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 6114 0, 0, &rdataset, NULL); 6115 if (result == ISC_R_NOTFOUND) 6116 return (ISC_R_SUCCESS); 6117 if (result != ISC_R_SUCCESS) 6118 return (result); 6119 6120 for (result = dns_rdataset_first(&rdataset); 6121 result == ISC_R_SUCCESS; 6122 result = dns_rdataset_next(&rdataset)) { 6123 dns_rdata_t rdata = DNS_RDATA_INIT; 6124 6125 dns_rdataset_current(&rdataset, &rdata); 6126 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL)); 6127 if (nsec3.hash != param->hash || 6128 nsec3.iterations != param->iterations || 6129 nsec3.salt_length != param->salt_length || 6130 memcmp(nsec3.salt, param->salt, nsec3.salt_length)) 6131 continue; 6132 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 6133 rdataset.ttl, &rdata)); 6134 } 6135 if (result == ISC_R_NOMORE) 6136 result = ISC_R_SUCCESS; 6137 failure: 6138 dns_rdataset_disassociate(&rdataset); 6139 return (result); 6140} 6141 6142static isc_result_t 6143need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver, 6144 const dns_rdata_nsec3param_t *param, 6145 isc_boolean_t *answer) 6146{ 6147 dns_dbnode_t *node = NULL; 6148 dns_rdata_t rdata = DNS_RDATA_INIT; 6149 dns_rdata_nsec3param_t myparam; 6150 dns_rdataset_t rdataset; 6151 isc_result_t result; 6152 6153 *answer = ISC_FALSE; 6154 6155 result = dns_db_getoriginnode(db, &node); 6156 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6157 6158 dns_rdataset_init(&rdataset); 6159 6160 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 6161 0, 0, &rdataset, NULL); 6162 if (result == ISC_R_SUCCESS) { 6163 dns_rdataset_disassociate(&rdataset); 6164 dns_db_detachnode(db, &node); 6165 return (result); 6166 } 6167 if (result != ISC_R_NOTFOUND) { 6168 dns_db_detachnode(db, &node); 6169 return (result); 6170 } 6171 6172 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 6173 0, 0, &rdataset, NULL); 6174 if (result == ISC_R_NOTFOUND) { 6175 *answer = ISC_TRUE; 6176 dns_db_detachnode(db, &node); 6177 return (ISC_R_SUCCESS); 6178 } 6179 if (result != ISC_R_SUCCESS) { 6180 dns_db_detachnode(db, &node); 6181 return (result); 6182 } 6183 6184 for (result = dns_rdataset_first(&rdataset); 6185 result == ISC_R_SUCCESS; 6186 result = dns_rdataset_next(&rdataset)) { 6187 dns_rdataset_current(&rdataset, &rdata); 6188 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL)); 6189 dns_rdata_reset(&rdata); 6190 /* 6191 * Ignore any NSEC3PARAM removals. 6192 */ 6193 if (NSEC3REMOVE(myparam.flags)) 6194 continue; 6195 /* 6196 * Ignore the chain that we are in the process of deleting. 6197 */ 6198 if (myparam.hash == param->hash && 6199 myparam.iterations == param->iterations && 6200 myparam.salt_length == param->salt_length && 6201 !memcmp(myparam.salt, param->salt, myparam.salt_length)) 6202 continue; 6203 /* 6204 * Found an active NSEC3 chain. 6205 */ 6206 break; 6207 } 6208 if (result == ISC_R_NOMORE) { 6209 *answer = ISC_TRUE; 6210 result = ISC_R_SUCCESS; 6211 } 6212 6213 failure: 6214 if (dns_rdataset_isassociated(&rdataset)) 6215 dns_rdataset_disassociate(&rdataset); 6216 dns_db_detachnode(db, &node); 6217 return (result); 6218} 6219 6220static isc_result_t 6221update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, 6222 dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone, 6223 isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now, 6224 isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly, 6225 dns_diff_t *sig_diff) 6226{ 6227 dns_difftuple_t *tuple; 6228 isc_result_t result; 6229 6230 for (tuple = ISC_LIST_HEAD(diff->tuples); 6231 tuple != NULL; 6232 tuple = ISC_LIST_HEAD(diff->tuples)) { 6233 result = del_sigs(zone, db, version, &tuple->name, 6234 tuple->rdata.type, sig_diff, 6235 zone_keys, nkeys, now, ISC_FALSE); 6236 if (result != ISC_R_SUCCESS) { 6237 dns_zone_log(zone, ISC_LOG_ERROR, 6238 "update_sigs:del_sigs -> %s", 6239 dns_result_totext(result)); 6240 return (result); 6241 } 6242 result = add_sigs(db, version, &tuple->name, 6243 tuple->rdata.type, sig_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 "update_sigs:add_sigs -> %s", 6249 dns_result_totext(result)); 6250 return (result); 6251 } 6252 6253 do { 6254 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link); 6255 while (next != NULL && 6256 (tuple->rdata.type != next->rdata.type || 6257 !dns_name_equal(&tuple->name, &next->name))) 6258 next = ISC_LIST_NEXT(next, link); 6259 ISC_LIST_UNLINK(diff->tuples, tuple, link); 6260 dns_diff_appendminimal(sig_diff, &tuple); 6261 INSIST(tuple == NULL); 6262 tuple = next; 6263 } while (tuple != NULL); 6264 } 6265 return (ISC_R_SUCCESS); 6266} 6267 6268/* 6269 * Incrementally build and sign a new NSEC3 chain using the parameters 6270 * requested. 6271 */ 6272static void 6273zone_nsec3chain(dns_zone_t *zone) { 6274 dns_db_t *db = NULL; 6275 dns_dbnode_t *node = NULL; 6276 dns_dbversion_t *version = NULL; 6277 dns_diff_t sig_diff; 6278 dns_diff_t nsec_diff; 6279 dns_diff_t nsec3_diff; 6280 dns_diff_t param_diff; 6281 dns_fixedname_t fixed; 6282 dns_fixedname_t nextfixed; 6283 dns_name_t *name, *nextname; 6284 dns_rdataset_t rdataset; 6285 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain; 6286 dns_nsec3chainlist_t cleanup; 6287 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 6288 isc_int32_t signatures; 6289 isc_boolean_t check_ksk, keyset_kskonly; 6290 isc_boolean_t delegation; 6291 isc_boolean_t first; 6292 isc_result_t result; 6293 isc_stdtime_t now, inception, soaexpire, expire; 6294 isc_uint32_t jitter; 6295 unsigned int i; 6296 unsigned int nkeys = 0; 6297 isc_uint32_t nodes; 6298 isc_boolean_t unsecure = ISC_FALSE; 6299 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds; 6300 isc_boolean_t seen_nsec, seen_nsec3, seen_rr; 6301 dns_rdatasetiter_t *iterator = NULL; 6302 isc_boolean_t buildnsecchain; 6303 isc_boolean_t updatensec = ISC_FALSE; 6304 dns_rdatatype_t privatetype = zone->privatetype; 6305 6306 dns_rdataset_init(&rdataset); 6307 dns_fixedname_init(&fixed); 6308 name = dns_fixedname_name(&fixed); 6309 dns_fixedname_init(&nextfixed); 6310 nextname = dns_fixedname_name(&nextfixed); 6311 dns_diff_init(zone->mctx, ¶m_diff); 6312 dns_diff_init(zone->mctx, &nsec3_diff); 6313 dns_diff_init(zone->mctx, &nsec_diff); 6314 dns_diff_init(zone->mctx, &sig_diff); 6315 sig_diff.resign = zone->sigresigninginterval; 6316 ISC_LIST_INIT(cleanup); 6317 6318 /* 6319 * Updates are disabled. Pause for 5 minutes. 6320 */ 6321 if (zone->update_disabled) { 6322 result = ISC_R_FAILURE; 6323 goto failure; 6324 } 6325 6326 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 6327 dns_db_attach(zone->db, &db); 6328 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 6329 6330 result = dns_db_newversion(db, &version); 6331 if (result != ISC_R_SUCCESS) { 6332 dns_zone_log(zone, ISC_LOG_ERROR, 6333 "zone_nsec3chain:dns_db_newversion -> %s", 6334 dns_result_totext(result)); 6335 goto failure; 6336 } 6337 6338 result = find_zone_keys(zone, db, version, zone->mctx, 6339 DNS_MAXZONEKEYS, zone_keys, &nkeys); 6340 if (result != ISC_R_SUCCESS) { 6341 dns_zone_log(zone, ISC_LOG_ERROR, 6342 "zone_nsec3chain:find_zone_keys -> %s", 6343 dns_result_totext(result)); 6344 goto failure; 6345 } 6346 6347 isc_stdtime_get(&now); 6348 inception = now - 3600; /* Allow for clock skew. */ 6349 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 6350 6351 /* 6352 * Spread out signatures over time if they happen to be 6353 * clumped. We don't do this for each add_sigs() call as 6354 * we still want some clustering to occur. 6355 */ 6356 isc_random_get(&jitter); 6357 expire = soaexpire - jitter % 3600; 6358 6359 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 6360 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 6361 6362 /* 6363 * We keep pulling nodes off each iterator in turn until 6364 * we have no more nodes to pull off or we reach the limits 6365 * for this quantum. 6366 */ 6367 nodes = zone->nodes; 6368 signatures = zone->signatures; 6369 LOCK_ZONE(zone); 6370 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 6371 UNLOCK_ZONE(zone); 6372 first = ISC_TRUE; 6373 6374 if (nsec3chain != NULL) 6375 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 6376 /* 6377 * Generate new NSEC3 chains first. 6378 */ 6379 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 6380 LOCK_ZONE(zone); 6381 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 6382 6383 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 6384 if (nsec3chain->done || nsec3chain->db != zone->db) { 6385 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 6386 ISC_LIST_APPEND(cleanup, nsec3chain, link); 6387 } 6388 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 6389 UNLOCK_ZONE(zone); 6390 if (ISC_LIST_TAIL(cleanup) == nsec3chain) 6391 goto next_addchain; 6392 6393 /* 6394 * Possible future db. 6395 */ 6396 if (nsec3chain->db != db) { 6397 goto next_addchain; 6398 } 6399 6400 if (NSEC3REMOVE(nsec3chain->nsec3param.flags)) 6401 goto next_addchain; 6402 6403 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 6404 6405 if (nsec3chain->delete_nsec) { 6406 delegation = ISC_FALSE; 6407 dns_dbiterator_pause(nsec3chain->dbiterator); 6408 CHECK(delete_nsec(db, version, node, name, &nsec_diff)); 6409 goto next_addnode; 6410 } 6411 /* 6412 * On the first pass we need to check if the current node 6413 * has not been obscured. 6414 */ 6415 delegation = ISC_FALSE; 6416 unsecure = ISC_FALSE; 6417 if (first) { 6418 dns_fixedname_t ffound; 6419 dns_name_t *found; 6420 dns_fixedname_init(&ffound); 6421 found = dns_fixedname_name(&ffound); 6422 result = dns_db_find(db, name, version, 6423 dns_rdatatype_soa, 6424 DNS_DBFIND_NOWILD, 0, NULL, found, 6425 NULL, NULL); 6426 if ((result == DNS_R_DELEGATION || 6427 result == DNS_R_DNAME) && 6428 !dns_name_equal(name, found)) { 6429 /* 6430 * Remember the obscuring name so that 6431 * we skip all obscured names. 6432 */ 6433 dns_name_copy(found, name, NULL); 6434 delegation = ISC_TRUE; 6435 goto next_addnode; 6436 } 6437 } 6438 6439 /* 6440 * Check to see if this is a bottom of zone node. 6441 */ 6442 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 6443 if (result == ISC_R_NOTFOUND) /* Empty node? */ 6444 goto next_addnode; 6445 if (result != ISC_R_SUCCESS) 6446 goto failure; 6447 6448 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = 6449 ISC_FALSE; 6450 for (result = dns_rdatasetiter_first(iterator); 6451 result == ISC_R_SUCCESS; 6452 result = dns_rdatasetiter_next(iterator)) { 6453 dns_rdatasetiter_current(iterator, &rdataset); 6454 INSIST(rdataset.type != dns_rdatatype_nsec3); 6455 if (rdataset.type == dns_rdatatype_soa) 6456 seen_soa = ISC_TRUE; 6457 else if (rdataset.type == dns_rdatatype_ns) 6458 seen_ns = ISC_TRUE; 6459 else if (rdataset.type == dns_rdatatype_dname) 6460 seen_dname = ISC_TRUE; 6461 else if (rdataset.type == dns_rdatatype_ds) 6462 seen_ds = ISC_TRUE; 6463 else if (rdataset.type == dns_rdatatype_nsec) 6464 seen_nsec = ISC_TRUE; 6465 dns_rdataset_disassociate(&rdataset); 6466 } 6467 dns_rdatasetiter_destroy(&iterator); 6468 /* 6469 * Is there a NSEC chain than needs to be cleaned up? 6470 */ 6471 if (seen_nsec) 6472 nsec3chain->seen_nsec = ISC_TRUE; 6473 if (seen_ns && !seen_soa && !seen_ds) 6474 unsecure = ISC_TRUE; 6475 if ((seen_ns && !seen_soa) || seen_dname) 6476 delegation = ISC_TRUE; 6477 6478 /* 6479 * Process one node. 6480 */ 6481 dns_dbiterator_pause(nsec3chain->dbiterator); 6482 result = dns_nsec3_addnsec3(db, version, name, 6483 &nsec3chain->nsec3param, 6484 zone->minimum, unsecure, 6485 &nsec3_diff); 6486 if (result != ISC_R_SUCCESS) { 6487 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6488 "dns_nsec3_addnsec3 -> %s", 6489 dns_result_totext(result)); 6490 goto failure; 6491 } 6492 6493 /* 6494 * Treat each call to dns_nsec3_addnsec3() as if it's cost is 6495 * two signatures. Additionally there will, in general, be 6496 * two signature generated below. 6497 * 6498 * If we are only changing the optout flag the cost is half 6499 * that of the cost of generating a completely new chain. 6500 */ 6501 signatures -= 4; 6502 6503 /* 6504 * Go onto next node. 6505 */ 6506 next_addnode: 6507 first = ISC_FALSE; 6508 dns_db_detachnode(db, &node); 6509 do { 6510 result = dns_dbiterator_next(nsec3chain->dbiterator); 6511 6512 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) { 6513 CHECK(fixup_nsec3param(db, version, nsec3chain, 6514 ISC_FALSE, privatetype, 6515 ¶m_diff)); 6516 LOCK_ZONE(zone); 6517 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 6518 link); 6519 UNLOCK_ZONE(zone); 6520 ISC_LIST_APPEND(cleanup, nsec3chain, link); 6521 goto next_addchain; 6522 } 6523 if (result == ISC_R_NOMORE) { 6524 dns_dbiterator_pause(nsec3chain->dbiterator); 6525 if (nsec3chain->seen_nsec) { 6526 CHECK(fixup_nsec3param(db, version, 6527 nsec3chain, 6528 ISC_TRUE, 6529 privatetype, 6530 ¶m_diff)); 6531 nsec3chain->delete_nsec = ISC_TRUE; 6532 goto same_addchain; 6533 } 6534 CHECK(fixup_nsec3param(db, version, nsec3chain, 6535 ISC_FALSE, privatetype, 6536 ¶m_diff)); 6537 LOCK_ZONE(zone); 6538 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 6539 link); 6540 UNLOCK_ZONE(zone); 6541 ISC_LIST_APPEND(cleanup, nsec3chain, link); 6542 goto next_addchain; 6543 } else if (result != ISC_R_SUCCESS) { 6544 dns_zone_log(zone, ISC_LOG_ERROR, 6545 "zone_nsec3chain:" 6546 "dns_dbiterator_next -> %s", 6547 dns_result_totext(result)); 6548 goto failure; 6549 } else if (delegation) { 6550 dns_dbiterator_current(nsec3chain->dbiterator, 6551 &node, nextname); 6552 dns_db_detachnode(db, &node); 6553 if (!dns_name_issubdomain(nextname, name)) 6554 break; 6555 } else 6556 break; 6557 } while (1); 6558 continue; 6559 6560 same_addchain: 6561 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 6562 first = ISC_TRUE; 6563 continue; 6564 6565 next_addchain: 6566 dns_dbiterator_pause(nsec3chain->dbiterator); 6567 nsec3chain = nextnsec3chain; 6568 first = ISC_TRUE; 6569 if (nsec3chain != NULL) 6570 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 6571 } 6572 6573 /* 6574 * Process removals. 6575 */ 6576 LOCK_ZONE(zone); 6577 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 6578 UNLOCK_ZONE(zone); 6579 first = ISC_TRUE; 6580 buildnsecchain = ISC_FALSE; 6581 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 6582 LOCK_ZONE(zone); 6583 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 6584 UNLOCK_ZONE(zone); 6585 6586 if (nsec3chain->db != db) 6587 goto next_removechain; 6588 6589 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) 6590 goto next_removechain; 6591 6592 /* 6593 * Work out if we need to build a NSEC chain as a consequence 6594 * of removing this NSEC3 chain. 6595 */ 6596 if (first && !updatensec && 6597 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) 6598 { 6599 result = need_nsec_chain(db, version, 6600 &nsec3chain->nsec3param, 6601 &buildnsecchain); 6602 if (result != ISC_R_SUCCESS) { 6603 dns_zone_log(zone, ISC_LOG_ERROR, 6604 "zone_nsec3chain:" 6605 "need_nsec_chain -> %s", 6606 dns_result_totext(result)); 6607 goto failure; 6608 } 6609 } 6610 6611 if (first) 6612 dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:" 6613 "buildnsecchain = %u\n", buildnsecchain); 6614 6615 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 6616 delegation = ISC_FALSE; 6617 6618 if (!buildnsecchain) { 6619 /* 6620 * Delete the NSECPARAM record that matches this chain. 6621 */ 6622 if (first) { 6623 result = fixup_nsec3param(db, version, 6624 nsec3chain, 6625 ISC_TRUE, privatetype, 6626 ¶m_diff); 6627 if (result != ISC_R_SUCCESS) { 6628 dns_zone_log(zone, ISC_LOG_ERROR, 6629 "zone_nsec3chain:" 6630 "fixup_nsec3param -> %s", 6631 dns_result_totext(result)); 6632 goto failure; 6633 } 6634 } 6635 6636 /* 6637 * Delete the NSEC3 records. 6638 */ 6639 result = deletematchingnsec3(db, version, node, name, 6640 &nsec3chain->nsec3param, 6641 &nsec3_diff); 6642 if (result != ISC_R_SUCCESS) { 6643 dns_zone_log(zone, ISC_LOG_ERROR, 6644 "zone_nsec3chain:" 6645 "deletematchingnsec3 -> %s", 6646 dns_result_totext(result)); 6647 goto failure; 6648 } 6649 goto next_removenode; 6650 } 6651 6652 if (first) { 6653 dns_fixedname_t ffound; 6654 dns_name_t *found; 6655 dns_fixedname_init(&ffound); 6656 found = dns_fixedname_name(&ffound); 6657 result = dns_db_find(db, name, version, 6658 dns_rdatatype_soa, 6659 DNS_DBFIND_NOWILD, 0, NULL, found, 6660 NULL, NULL); 6661 if ((result == DNS_R_DELEGATION || 6662 result == DNS_R_DNAME) && 6663 !dns_name_equal(name, found)) { 6664 /* 6665 * Remember the obscuring name so that 6666 * we skip all obscured names. 6667 */ 6668 dns_name_copy(found, name, NULL); 6669 delegation = ISC_TRUE; 6670 goto next_removenode; 6671 } 6672 } 6673 6674 /* 6675 * Check to see if this is a bottom of zone node. 6676 */ 6677 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 6678 if (result == ISC_R_NOTFOUND) /* Empty node? */ 6679 goto next_removenode; 6680 if (result != ISC_R_SUCCESS) 6681 goto failure; 6682 6683 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec = 6684 seen_rr = ISC_FALSE; 6685 for (result = dns_rdatasetiter_first(iterator); 6686 result == ISC_R_SUCCESS; 6687 result = dns_rdatasetiter_next(iterator)) { 6688 dns_rdatasetiter_current(iterator, &rdataset); 6689 if (rdataset.type == dns_rdatatype_soa) 6690 seen_soa = ISC_TRUE; 6691 else if (rdataset.type == dns_rdatatype_ns) 6692 seen_ns = ISC_TRUE; 6693 else if (rdataset.type == dns_rdatatype_dname) 6694 seen_dname = ISC_TRUE; 6695 else if (rdataset.type == dns_rdatatype_nsec) 6696 seen_nsec = ISC_TRUE; 6697 else if (rdataset.type == dns_rdatatype_nsec3) 6698 seen_nsec3 = ISC_TRUE; 6699 if (rdataset.type != dns_rdatatype_rrsig) 6700 seen_rr = ISC_TRUE; 6701 dns_rdataset_disassociate(&rdataset); 6702 } 6703 dns_rdatasetiter_destroy(&iterator); 6704 6705 if (!seen_rr || seen_nsec3 || seen_nsec) 6706 goto next_removenode; 6707 if ((seen_ns && !seen_soa) || seen_dname) 6708 delegation = ISC_TRUE; 6709 6710 /* 6711 * Add a NSEC record except at the origin. 6712 */ 6713 if (!dns_name_equal(name, dns_db_origin(db))) { 6714 dns_dbiterator_pause(nsec3chain->dbiterator); 6715 CHECK(add_nsec(db, version, name, node, zone->minimum, 6716 delegation, &nsec_diff)); 6717 } 6718 6719 next_removenode: 6720 first = ISC_FALSE; 6721 dns_db_detachnode(db, &node); 6722 do { 6723 result = dns_dbiterator_next(nsec3chain->dbiterator); 6724 if (result == ISC_R_NOMORE && buildnsecchain) { 6725 /* 6726 * The NSEC chain should now be built. 6727 * We can now remove the NSEC3 chain. 6728 */ 6729 updatensec = ISC_TRUE; 6730 goto same_removechain; 6731 } 6732 if (result == ISC_R_NOMORE) { 6733 LOCK_ZONE(zone); 6734 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 6735 link); 6736 UNLOCK_ZONE(zone); 6737 ISC_LIST_APPEND(cleanup, nsec3chain, link); 6738 dns_dbiterator_pause(nsec3chain->dbiterator); 6739 result = fixup_nsec3param(db, version, 6740 nsec3chain, ISC_FALSE, 6741 privatetype, 6742 ¶m_diff); 6743 if (result != ISC_R_SUCCESS) { 6744 dns_zone_log(zone, ISC_LOG_ERROR, 6745 "zone_nsec3chain:" 6746 "fixup_nsec3param -> %s", 6747 dns_result_totext(result)); 6748 goto failure; 6749 } 6750 goto next_removechain; 6751 } else if (result != ISC_R_SUCCESS) { 6752 dns_zone_log(zone, ISC_LOG_ERROR, 6753 "zone_nsec3chain:" 6754 "dns_dbiterator_next -> %s", 6755 dns_result_totext(result)); 6756 goto failure; 6757 } else if (delegation) { 6758 dns_dbiterator_current(nsec3chain->dbiterator, 6759 &node, nextname); 6760 dns_db_detachnode(db, &node); 6761 if (!dns_name_issubdomain(nextname, name)) 6762 break; 6763 } else 6764 break; 6765 } while (1); 6766 continue; 6767 6768 same_removechain: 6769 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 6770 buildnsecchain = ISC_FALSE; 6771 first = ISC_TRUE; 6772 continue; 6773 6774 next_removechain: 6775 dns_dbiterator_pause(nsec3chain->dbiterator); 6776 nsec3chain = nextnsec3chain; 6777 first = ISC_TRUE; 6778 } 6779 6780 /* 6781 * We may need to update the NSEC/NSEC3 records for the zone apex. 6782 */ 6783 if (!ISC_LIST_EMPTY(param_diff.tuples)) { 6784 isc_boolean_t rebuild_nsec = ISC_FALSE, 6785 rebuild_nsec3 = ISC_FALSE; 6786 result = dns_db_getoriginnode(db, &node); 6787 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6788 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 6789 if (result != ISC_R_SUCCESS) { 6790 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6791 "dns_db_allrdatasets -> %s", 6792 dns_result_totext(result)); 6793 goto failure; 6794 } 6795 for (result = dns_rdatasetiter_first(iterator); 6796 result == ISC_R_SUCCESS; 6797 result = dns_rdatasetiter_next(iterator)) { 6798 dns_rdatasetiter_current(iterator, &rdataset); 6799 if (rdataset.type == dns_rdatatype_nsec) 6800 rebuild_nsec = ISC_TRUE; 6801 if (rdataset.type == dns_rdatatype_nsec3param) 6802 rebuild_nsec3 = ISC_TRUE; 6803 dns_rdataset_disassociate(&rdataset); 6804 } 6805 dns_rdatasetiter_destroy(&iterator); 6806 dns_db_detachnode(db, &node); 6807 6808 if (rebuild_nsec) { 6809 if (nsec3chain != NULL) 6810 dns_dbiterator_pause(nsec3chain->dbiterator); 6811 result = updatesecure(db, version, &zone->origin, 6812 zone->minimum, ISC_TRUE, 6813 &nsec_diff); 6814 if (result != ISC_R_SUCCESS) { 6815 dns_zone_log(zone, ISC_LOG_ERROR, 6816 "zone_nsec3chain:" 6817 "updatesecure -> %s", 6818 dns_result_totext(result)); 6819 goto failure; 6820 } 6821 } 6822 if (rebuild_nsec3) { 6823 result = dns_nsec3_addnsec3s(db, version, 6824 dns_db_origin(db), 6825 zone->minimum, ISC_FALSE, 6826 &nsec3_diff); 6827 if (result != ISC_R_SUCCESS) { 6828 dns_zone_log(zone, ISC_LOG_ERROR, 6829 "zone_nsec3chain:" 6830 "dns_nsec3_addnsec3s -> %s", 6831 dns_result_totext(result)); 6832 goto failure; 6833 } 6834 } 6835 } 6836 6837 /* 6838 * Add / update signatures for the NSEC3 records. 6839 */ 6840 result = update_sigs(&nsec3_diff, db, version, zone_keys, 6841 nkeys, zone, inception, expire, now, 6842 check_ksk, keyset_kskonly, &sig_diff); 6843 if (result != ISC_R_SUCCESS) { 6844 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6845 "update_sigs -> %s", dns_result_totext(result)); 6846 goto failure; 6847 } 6848 6849 /* 6850 * We have changed the NSEC3PARAM or private RRsets 6851 * above so we need to update the signatures. 6852 */ 6853 result = update_sigs(¶m_diff, db, version, zone_keys, 6854 nkeys, zone, inception, expire, now, 6855 check_ksk, keyset_kskonly, &sig_diff); 6856 if (result != ISC_R_SUCCESS) { 6857 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6858 "update_sigs -> %s", dns_result_totext(result)); 6859 goto failure; 6860 } 6861 6862 if (updatensec) { 6863 if (nsec3chain != NULL) 6864 dns_dbiterator_pause(nsec3chain->dbiterator); 6865 result = updatesecure(db, version, &zone->origin, 6866 zone->minimum, ISC_FALSE, &nsec_diff); 6867 if (result != ISC_R_SUCCESS) { 6868 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6869 "updatesecure -> %s", 6870 dns_result_totext(result)); 6871 goto failure; 6872 } 6873 } 6874 6875 result = update_sigs(&nsec_diff, db, version, zone_keys, 6876 nkeys, zone, inception, expire, now, 6877 check_ksk, keyset_kskonly, &sig_diff); 6878 if (result != ISC_R_SUCCESS) { 6879 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6880 "update_sigs -> %s", dns_result_totext(result)); 6881 goto failure; 6882 } 6883 6884 /* 6885 * If we made no effective changes to the zone then we can just 6886 * cleanup otherwise we need to increment the serial. 6887 */ 6888 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) 6889 goto done; 6890 6891 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 6892 &sig_diff, zone_keys, nkeys, now, ISC_FALSE); 6893 if (result != ISC_R_SUCCESS) { 6894 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6895 "del_sigs -> %s", dns_result_totext(result)); 6896 goto failure; 6897 } 6898 6899 result = update_soa_serial(db, version, &sig_diff, zone->mctx, 6900 zone->updatemethod); 6901 if (result != ISC_R_SUCCESS) { 6902 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6903 "update_soa_serial -> %s", 6904 dns_result_totext(result)); 6905 goto failure; 6906 } 6907 6908 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, 6909 &sig_diff, zone_keys, nkeys, zone->mctx, inception, 6910 soaexpire, check_ksk, keyset_kskonly); 6911 if (result != ISC_R_SUCCESS) { 6912 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6913 "add_sigs -> %s", dns_result_totext(result)); 6914 goto failure; 6915 } 6916 6917 /* Write changes to journal file. */ 6918 CHECK(zone_journal(zone, &sig_diff, NULL, "zone_nsec3chain")); 6919 6920 LOCK_ZONE(zone); 6921 zone_needdump(zone, DNS_DUMP_DELAY); 6922 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 6923 UNLOCK_ZONE(zone); 6924 6925 done: 6926 /* 6927 * Pause all iterators so that dns_db_closeversion() can succeed. 6928 */ 6929 LOCK_ZONE(zone); 6930 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 6931 nsec3chain != NULL; 6932 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 6933 dns_dbiterator_pause(nsec3chain->dbiterator); 6934 UNLOCK_ZONE(zone); 6935 6936 /* 6937 * Everything has succeeded. Commit the changes. 6938 */ 6939 dns_db_closeversion(db, &version, ISC_TRUE); 6940 6941 /* 6942 * Everything succeeded so we can clean these up now. 6943 */ 6944 nsec3chain = ISC_LIST_HEAD(cleanup); 6945 while (nsec3chain != NULL) { 6946 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 6947 dns_db_detach(&nsec3chain->db); 6948 dns_dbiterator_destroy(&nsec3chain->dbiterator); 6949 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 6950 nsec3chain = ISC_LIST_HEAD(cleanup); 6951 } 6952 6953 set_resigntime(zone); 6954 6955 failure: 6956 if (result != ISC_R_SUCCESS) 6957 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s", 6958 dns_result_totext(result)); 6959 /* 6960 * On error roll back the current nsec3chain. 6961 */ 6962 if (result != ISC_R_SUCCESS && nsec3chain != NULL) { 6963 if (nsec3chain->done) { 6964 dns_db_detach(&nsec3chain->db); 6965 dns_dbiterator_destroy(&nsec3chain->dbiterator); 6966 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 6967 } else { 6968 result = dns_dbiterator_first(nsec3chain->dbiterator); 6969 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6970 dns_dbiterator_pause(nsec3chain->dbiterator); 6971 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 6972 } 6973 } 6974 6975 /* 6976 * Rollback the cleanup list. 6977 */ 6978 nsec3chain = ISC_LIST_TAIL(cleanup); 6979 while (nsec3chain != NULL) { 6980 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 6981 if (nsec3chain->done) { 6982 dns_db_detach(&nsec3chain->db); 6983 dns_dbiterator_destroy(&nsec3chain->dbiterator); 6984 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 6985 } else { 6986 LOCK_ZONE(zone); 6987 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link); 6988 UNLOCK_ZONE(zone); 6989 result = dns_dbiterator_first(nsec3chain->dbiterator); 6990 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6991 dns_dbiterator_pause(nsec3chain->dbiterator); 6992 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 6993 } 6994 nsec3chain = ISC_LIST_TAIL(cleanup); 6995 } 6996 6997 LOCK_ZONE(zone); 6998 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 6999 nsec3chain != NULL; 7000 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 7001 dns_dbiterator_pause(nsec3chain->dbiterator); 7002 UNLOCK_ZONE(zone); 7003 7004 dns_diff_clear(¶m_diff); 7005 dns_diff_clear(&nsec3_diff); 7006 dns_diff_clear(&nsec_diff); 7007 dns_diff_clear(&sig_diff); 7008 7009 if (iterator != NULL) 7010 dns_rdatasetiter_destroy(&iterator); 7011 7012 for (i = 0; i < nkeys; i++) 7013 dst_key_free(&zone_keys[i]); 7014 7015 if (node != NULL) 7016 dns_db_detachnode(db, &node); 7017 if (version != NULL) { 7018 dns_db_closeversion(db, &version, ISC_FALSE); 7019 dns_db_detach(&db); 7020 } else if (db != NULL) 7021 dns_db_detach(&db); 7022 7023 LOCK_ZONE(zone); 7024 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) { 7025 isc_interval_t i; 7026 if (zone->update_disabled || result != ISC_R_SUCCESS) 7027 isc_interval_set(&i, 60, 0); /* 1 minute */ 7028 else 7029 isc_interval_set(&i, 0, 10000000); /* 10 ms */ 7030 isc_time_nowplusinterval(&zone->nsec3chaintime, &i); 7031 } else 7032 isc_time_settoepoch(&zone->nsec3chaintime); 7033 UNLOCK_ZONE(zone); 7034} 7035 7036static isc_result_t 7037del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 7038 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm, 7039 isc_uint16_t keyid, dns_diff_t *diff) 7040{ 7041 dns_rdata_rrsig_t rrsig; 7042 dns_rdataset_t rdataset; 7043 dns_rdatasetiter_t *iterator = NULL; 7044 isc_result_t result; 7045 7046 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 7047 if (result != ISC_R_SUCCESS) { 7048 if (result == ISC_R_NOTFOUND) 7049 result = ISC_R_SUCCESS; 7050 return (result); 7051 } 7052 7053 dns_rdataset_init(&rdataset); 7054 for (result = dns_rdatasetiter_first(iterator); 7055 result == ISC_R_SUCCESS; 7056 result = dns_rdatasetiter_next(iterator)) { 7057 dns_rdatasetiter_current(iterator, &rdataset); 7058 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) { 7059 for (result = dns_rdataset_first(&rdataset); 7060 result == ISC_R_SUCCESS; 7061 result = dns_rdataset_next(&rdataset)) { 7062 dns_rdata_t rdata = DNS_RDATA_INIT; 7063 dns_rdataset_current(&rdataset, &rdata); 7064 CHECK(update_one_rr(db, version, diff, 7065 DNS_DIFFOP_DEL, name, 7066 rdataset.ttl, &rdata)); 7067 } 7068 if (result != ISC_R_NOMORE) 7069 goto failure; 7070 dns_rdataset_disassociate(&rdataset); 7071 continue; 7072 } 7073 if (rdataset.type != dns_rdatatype_rrsig) { 7074 dns_rdataset_disassociate(&rdataset); 7075 continue; 7076 } 7077 for (result = dns_rdataset_first(&rdataset); 7078 result == ISC_R_SUCCESS; 7079 result = dns_rdataset_next(&rdataset)) { 7080 dns_rdata_t rdata = DNS_RDATA_INIT; 7081 dns_rdataset_current(&rdataset, &rdata); 7082 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL)); 7083 if (rrsig.algorithm != algorithm || 7084 rrsig.keyid != keyid) 7085 continue; 7086 CHECK(update_one_rr(db, version, diff, 7087 DNS_DIFFOP_DELRESIGN, name, 7088 rdataset.ttl, &rdata)); 7089 } 7090 dns_rdataset_disassociate(&rdataset); 7091 if (result != ISC_R_NOMORE) 7092 break; 7093 } 7094 if (result == ISC_R_NOMORE) 7095 result = ISC_R_SUCCESS; 7096 failure: 7097 if (dns_rdataset_isassociated(&rdataset)) 7098 dns_rdataset_disassociate(&rdataset); 7099 dns_rdatasetiter_destroy(&iterator); 7100 return (result); 7101} 7102 7103/* 7104 * Incrementally sign the zone using the keys requested. 7105 * Builds the NSEC chain if required. 7106 */ 7107static void 7108zone_sign(dns_zone_t *zone) { 7109 dns_db_t *db = NULL; 7110 dns_dbnode_t *node = NULL; 7111 dns_dbversion_t *version = NULL; 7112 dns_diff_t sig_diff; 7113 dns_diff_t post_diff; 7114 dns_fixedname_t fixed; 7115 dns_fixedname_t nextfixed; 7116 dns_name_t *name, *nextname; 7117 dns_rdataset_t rdataset; 7118 dns_signing_t *signing, *nextsigning; 7119 dns_signinglist_t cleanup; 7120 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 7121 isc_int32_t signatures; 7122 isc_boolean_t check_ksk, keyset_kskonly, is_ksk; 7123 isc_boolean_t commit = ISC_FALSE; 7124 isc_boolean_t delegation; 7125 isc_boolean_t build_nsec = ISC_FALSE; 7126 isc_boolean_t build_nsec3 = ISC_FALSE; 7127 isc_boolean_t first; 7128 isc_result_t result; 7129 isc_stdtime_t now, inception, soaexpire, expire; 7130 isc_uint32_t jitter; 7131 unsigned int i, j; 7132 unsigned int nkeys = 0; 7133 isc_uint32_t nodes; 7134 7135 dns_rdataset_init(&rdataset); 7136 dns_fixedname_init(&fixed); 7137 name = dns_fixedname_name(&fixed); 7138 dns_fixedname_init(&nextfixed); 7139 nextname = dns_fixedname_name(&nextfixed); 7140 dns_diff_init(zone->mctx, &sig_diff); 7141 sig_diff.resign = zone->sigresigninginterval; 7142 dns_diff_init(zone->mctx, &post_diff); 7143 ISC_LIST_INIT(cleanup); 7144 7145 /* 7146 * Updates are disabled. Pause for 5 minutes. 7147 */ 7148 if (zone->update_disabled) { 7149 result = ISC_R_FAILURE; 7150 goto failure; 7151 } 7152 7153 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 7154 dns_db_attach(zone->db, &db); 7155 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 7156 7157 result = dns_db_newversion(db, &version); 7158 if (result != ISC_R_SUCCESS) { 7159 dns_zone_log(zone, ISC_LOG_ERROR, 7160 "zone_sign:dns_db_newversion -> %s", 7161 dns_result_totext(result)); 7162 goto failure; 7163 } 7164 7165 result = find_zone_keys(zone, db, version, zone->mctx, 7166 DNS_MAXZONEKEYS, zone_keys, &nkeys); 7167 if (result != ISC_R_SUCCESS) { 7168 dns_zone_log(zone, ISC_LOG_ERROR, 7169 "zone_sign:find_zone_keys -> %s", 7170 dns_result_totext(result)); 7171 goto failure; 7172 } 7173 7174 isc_stdtime_get(&now); 7175 inception = now - 3600; /* Allow for clock skew. */ 7176 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 7177 7178 /* 7179 * Spread out signatures over time if they happen to be 7180 * clumped. We don't do this for each add_sigs() call as 7181 * we still want some clustering to occur. 7182 */ 7183 isc_random_get(&jitter); 7184 expire = soaexpire - jitter % 3600; 7185 7186 /* 7187 * We keep pulling nodes off each iterator in turn until 7188 * we have no more nodes to pull off or we reach the limits 7189 * for this quantum. 7190 */ 7191 nodes = zone->nodes; 7192 signatures = zone->signatures; 7193 signing = ISC_LIST_HEAD(zone->signing); 7194 first = ISC_TRUE; 7195 7196 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 7197 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 7198 7199 /* Determine which type of chain to build */ 7200 CHECK(dns_private_chains(db, version, zone->privatetype, 7201 &build_nsec, &build_nsec3)); 7202 7203 /* If neither chain is found, default to NSEC */ 7204 if (!build_nsec && !build_nsec3) 7205 build_nsec = ISC_TRUE; 7206 7207 while (signing != NULL && nodes-- > 0 && signatures > 0) { 7208 nextsigning = ISC_LIST_NEXT(signing, link); 7209 7210 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 7211 if (signing->done || signing->db != zone->db) { 7212 /* 7213 * The zone has been reloaded. We will have 7214 * created new signings as part of the reload 7215 * process so we can destroy this one. 7216 */ 7217 ISC_LIST_UNLINK(zone->signing, signing, link); 7218 ISC_LIST_APPEND(cleanup, signing, link); 7219 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 7220 goto next_signing; 7221 } 7222 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 7223 7224 if (signing->db != db) 7225 goto next_signing; 7226 7227 delegation = ISC_FALSE; 7228 7229 if (first && signing->delete) { 7230 /* 7231 * Remove the key we are deleting from consideration. 7232 */ 7233 for (i = 0, j = 0; i < nkeys; i++) { 7234 /* 7235 * Find the key we want to remove. 7236 */ 7237 if (ALG(zone_keys[i]) == signing->algorithm && 7238 dst_key_id(zone_keys[i]) == signing->keyid) 7239 { 7240 if (KSK(zone_keys[i])) 7241 dst_key_free(&zone_keys[i]); 7242 continue; 7243 } 7244 zone_keys[j] = zone_keys[i]; 7245 j++; 7246 } 7247 nkeys = j; 7248 } 7249 7250 dns_dbiterator_current(signing->dbiterator, &node, name); 7251 7252 if (signing->delete) { 7253 dns_dbiterator_pause(signing->dbiterator); 7254 CHECK(del_sig(db, version, name, node, nkeys, 7255 signing->algorithm, signing->keyid, 7256 &sig_diff)); 7257 } 7258 7259 /* 7260 * On the first pass we need to check if the current node 7261 * has not been obscured. 7262 */ 7263 if (first) { 7264 dns_fixedname_t ffound; 7265 dns_name_t *found; 7266 dns_fixedname_init(&ffound); 7267 found = dns_fixedname_name(&ffound); 7268 result = dns_db_find(db, name, version, 7269 dns_rdatatype_soa, 7270 DNS_DBFIND_NOWILD, 0, NULL, found, 7271 NULL, NULL); 7272 if ((result == DNS_R_DELEGATION || 7273 result == DNS_R_DNAME) && 7274 !dns_name_equal(name, found)) { 7275 /* 7276 * Remember the obscuring name so that 7277 * we skip all obscured names. 7278 */ 7279 dns_name_copy(found, name, NULL); 7280 delegation = ISC_TRUE; 7281 goto next_node; 7282 } 7283 } 7284 7285 /* 7286 * Process one node. 7287 */ 7288 dns_dbiterator_pause(signing->dbiterator); 7289 for (i = 0; i < nkeys; i++) { 7290 isc_boolean_t both = ISC_FALSE; 7291 7292 /* 7293 * Find the keys we want to sign with. 7294 */ 7295 if (!dst_key_isprivate(zone_keys[i])) 7296 continue; 7297 7298 /* 7299 * When adding look for the specific key. 7300 */ 7301 if (!signing->delete && 7302 (dst_key_alg(zone_keys[i]) != signing->algorithm || 7303 dst_key_id(zone_keys[i]) != signing->keyid)) 7304 continue; 7305 7306 /* 7307 * When deleting make sure we are properly signed 7308 * with the algorithm that was being removed. 7309 */ 7310 if (signing->delete && 7311 ALG(zone_keys[i]) != signing->algorithm) 7312 continue; 7313 7314 /* 7315 * Do we do KSK processing? 7316 */ 7317 if (check_ksk && !REVOKE(zone_keys[i])) { 7318 isc_boolean_t have_ksk, have_nonksk; 7319 if (KSK(zone_keys[i])) { 7320 have_ksk = ISC_TRUE; 7321 have_nonksk = ISC_FALSE; 7322 } else { 7323 have_ksk = ISC_FALSE; 7324 have_nonksk = ISC_TRUE; 7325 } 7326 for (j = 0; j < nkeys; j++) { 7327 if (j == i || 7328 ALG(zone_keys[i]) != 7329 ALG(zone_keys[j])) 7330 continue; 7331 if (REVOKE(zone_keys[j])) 7332 continue; 7333 if (KSK(zone_keys[j])) 7334 have_ksk = ISC_TRUE; 7335 else 7336 have_nonksk = ISC_TRUE; 7337 both = have_ksk && have_nonksk; 7338 if (both) 7339 break; 7340 } 7341 } 7342 if (both || REVOKE(zone_keys[i])) 7343 is_ksk = KSK(zone_keys[i]); 7344 else 7345 is_ksk = ISC_FALSE; 7346 7347 CHECK(sign_a_node(db, name, node, version, build_nsec3, 7348 build_nsec, zone_keys[i], inception, 7349 expire, zone->minimum, is_ksk, 7350 ISC_TF(both && keyset_kskonly), 7351 &delegation, &sig_diff, 7352 &signatures, zone->mctx)); 7353 /* 7354 * If we are adding we are done. Look for other keys 7355 * of the same algorithm if deleting. 7356 */ 7357 if (!signing->delete) 7358 break; 7359 } 7360 7361 /* 7362 * Go onto next node. 7363 */ 7364 next_node: 7365 first = ISC_FALSE; 7366 dns_db_detachnode(db, &node); 7367 do { 7368 result = dns_dbiterator_next(signing->dbiterator); 7369 if (result == ISC_R_NOMORE) { 7370 ISC_LIST_UNLINK(zone->signing, signing, link); 7371 ISC_LIST_APPEND(cleanup, signing, link); 7372 dns_dbiterator_pause(signing->dbiterator); 7373 if (nkeys != 0 && build_nsec) { 7374 /* 7375 * We have finished regenerating the 7376 * zone with a zone signing key. 7377 * The NSEC chain is now complete and 7378 * there is a full set of signatures 7379 * for the zone. We can now clear the 7380 * OPT bit from the NSEC record. 7381 */ 7382 result = updatesecure(db, version, 7383 &zone->origin, 7384 zone->minimum, 7385 ISC_FALSE, 7386 &post_diff); 7387 if (result != ISC_R_SUCCESS) { 7388 dns_zone_log(zone, 7389 ISC_LOG_ERROR, 7390 "updatesecure -> %s", 7391 dns_result_totext(result)); 7392 goto failure; 7393 } 7394 } 7395 result = updatesignwithkey(zone, signing, 7396 version, 7397 build_nsec3, 7398 zone->minimum, 7399 &post_diff); 7400 if (result != ISC_R_SUCCESS) { 7401 dns_zone_log(zone, ISC_LOG_ERROR, 7402 "updatesignwithkey -> %s", 7403 dns_result_totext(result)); 7404 goto failure; 7405 } 7406 build_nsec = ISC_FALSE; 7407 goto next_signing; 7408 } else if (result != ISC_R_SUCCESS) { 7409 dns_zone_log(zone, ISC_LOG_ERROR, 7410 "zone_sign:dns_dbiterator_next -> %s", 7411 dns_result_totext(result)); 7412 goto failure; 7413 } else if (delegation) { 7414 dns_dbiterator_current(signing->dbiterator, 7415 &node, nextname); 7416 dns_db_detachnode(db, &node); 7417 if (!dns_name_issubdomain(nextname, name)) 7418 break; 7419 } else 7420 break; 7421 } while (1); 7422 continue; 7423 7424 next_signing: 7425 dns_dbiterator_pause(signing->dbiterator); 7426 signing = nextsigning; 7427 first = ISC_TRUE; 7428 } 7429 7430 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) { 7431 result = update_sigs(&post_diff, db, version, zone_keys, 7432 nkeys, zone, inception, expire, now, 7433 check_ksk, keyset_kskonly, &sig_diff); 7434 if (result != ISC_R_SUCCESS) { 7435 dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:" 7436 "update_sigs -> %s", 7437 dns_result_totext(result)); 7438 goto failure; 7439 } 7440 } 7441 7442 /* 7443 * Have we changed anything? 7444 */ 7445 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) { 7446 result = ISC_R_SUCCESS; 7447 goto pauseall; 7448 } 7449 7450 commit = ISC_TRUE; 7451 7452 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 7453 &sig_diff, zone_keys, nkeys, now, ISC_FALSE); 7454 if (result != ISC_R_SUCCESS) { 7455 dns_zone_log(zone, ISC_LOG_ERROR, 7456 "zone_sign:del_sigs -> %s", 7457 dns_result_totext(result)); 7458 goto failure; 7459 } 7460 7461 result = update_soa_serial(db, version, &sig_diff, zone->mctx, 7462 zone->updatemethod); 7463 if (result != ISC_R_SUCCESS) { 7464 dns_zone_log(zone, ISC_LOG_ERROR, 7465 "zone_sign:update_soa_serial -> %s", 7466 dns_result_totext(result)); 7467 goto failure; 7468 } 7469 7470 /* 7471 * Generate maximum life time signatures so that the above loop 7472 * termination is sensible. 7473 */ 7474 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, 7475 &sig_diff, zone_keys, nkeys, zone->mctx, inception, 7476 soaexpire, check_ksk, keyset_kskonly); 7477 if (result != ISC_R_SUCCESS) { 7478 dns_zone_log(zone, ISC_LOG_ERROR, 7479 "zone_sign:add_sigs -> %s", 7480 dns_result_totext(result)); 7481 goto failure; 7482 } 7483 7484 /* 7485 * Write changes to journal file. 7486 */ 7487 CHECK(zone_journal(zone, &sig_diff, NULL, "zone_sign")); 7488 7489 pauseall: 7490 /* 7491 * Pause all iterators so that dns_db_closeversion() can succeed. 7492 */ 7493 for (signing = ISC_LIST_HEAD(zone->signing); 7494 signing != NULL; 7495 signing = ISC_LIST_NEXT(signing, link)) 7496 dns_dbiterator_pause(signing->dbiterator); 7497 7498 for (signing = ISC_LIST_HEAD(cleanup); 7499 signing != NULL; 7500 signing = ISC_LIST_NEXT(signing, link)) 7501 dns_dbiterator_pause(signing->dbiterator); 7502 7503 /* 7504 * Everything has succeeded. Commit the changes. 7505 */ 7506 dns_db_closeversion(db, &version, commit); 7507 7508 /* 7509 * Everything succeeded so we can clean these up now. 7510 */ 7511 signing = ISC_LIST_HEAD(cleanup); 7512 while (signing != NULL) { 7513 ISC_LIST_UNLINK(cleanup, signing, link); 7514 dns_db_detach(&signing->db); 7515 dns_dbiterator_destroy(&signing->dbiterator); 7516 isc_mem_put(zone->mctx, signing, sizeof *signing); 7517 signing = ISC_LIST_HEAD(cleanup); 7518 } 7519 7520 set_resigntime(zone); 7521 7522 if (commit) { 7523 LOCK_ZONE(zone); 7524 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 7525 zone_needdump(zone, DNS_DUMP_DELAY); 7526 UNLOCK_ZONE(zone); 7527 } 7528 7529 failure: 7530 /* 7531 * Rollback the cleanup list. 7532 */ 7533 signing = ISC_LIST_HEAD(cleanup); 7534 while (signing != NULL) { 7535 ISC_LIST_UNLINK(cleanup, signing, link); 7536 ISC_LIST_PREPEND(zone->signing, signing, link); 7537 dns_dbiterator_first(signing->dbiterator); 7538 dns_dbiterator_pause(signing->dbiterator); 7539 signing = ISC_LIST_HEAD(cleanup); 7540 } 7541 7542 for (signing = ISC_LIST_HEAD(zone->signing); 7543 signing != NULL; 7544 signing = ISC_LIST_NEXT(signing, link)) 7545 dns_dbiterator_pause(signing->dbiterator); 7546 7547 dns_diff_clear(&sig_diff); 7548 7549 for (i = 0; i < nkeys; i++) 7550 dst_key_free(&zone_keys[i]); 7551 7552 if (node != NULL) 7553 dns_db_detachnode(db, &node); 7554 7555 if (version != NULL) { 7556 dns_db_closeversion(db, &version, ISC_FALSE); 7557 dns_db_detach(&db); 7558 } else if (db != NULL) 7559 dns_db_detach(&db); 7560 7561 if (ISC_LIST_HEAD(zone->signing) != NULL) { 7562 isc_interval_t i; 7563 if (zone->update_disabled || result != ISC_R_SUCCESS) 7564 isc_interval_set(&i, 60, 0); /* 1 minute */ 7565 else 7566 isc_interval_set(&i, 0, 10000000); /* 10 ms */ 7567 isc_time_nowplusinterval(&zone->signingtime, &i); 7568 } else 7569 isc_time_settoepoch(&zone->signingtime); 7570} 7571 7572static void 7573normalize_key(dns_rdata_t *rr, dns_rdata_t *target, 7574 unsigned char *data, int size) { 7575 dns_rdata_dnskey_t dnskey; 7576 dns_rdata_keydata_t keydata; 7577 isc_buffer_t buf; 7578 7579 dns_rdata_reset(target); 7580 isc_buffer_init(&buf, data, size); 7581 7582 switch (rr->type) { 7583 case dns_rdatatype_dnskey: 7584 dns_rdata_tostruct(rr, &dnskey, NULL); 7585 dnskey.flags &= ~DNS_KEYFLAG_REVOKE; 7586 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 7587 &dnskey, &buf); 7588 break; 7589 case dns_rdatatype_keydata: 7590 dns_rdata_tostruct(rr, &keydata, NULL); 7591 dns_keydata_todnskey(&keydata, &dnskey, NULL); 7592 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 7593 &dnskey, &buf); 7594 break; 7595 default: 7596 INSIST(0); 7597 } 7598} 7599 7600/* 7601 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or 7602 * a KEYDATA rdataset from the key zone. 7603 * 7604 * 'rr' contains either a DNSKEY record, or a KEYDATA record 7605 * 7606 * After normalizing keys to the same format (DNSKEY, with revoke bit 7607 * cleared), return ISC_TRUE if a key that matches 'rr' is found in 7608 * 'rdset', or ISC_FALSE if not. 7609 */ 7610 7611static isc_boolean_t 7612matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) { 7613 unsigned char data1[4096], data2[4096]; 7614 dns_rdata_t rdata, rdata1, rdata2; 7615 isc_result_t result; 7616 7617 dns_rdata_init(&rdata); 7618 dns_rdata_init(&rdata1); 7619 dns_rdata_init(&rdata2); 7620 7621 normalize_key(rr, &rdata1, data1, sizeof(data1)); 7622 7623 for (result = dns_rdataset_first(rdset); 7624 result == ISC_R_SUCCESS; 7625 result = dns_rdataset_next(rdset)) { 7626 dns_rdata_reset(&rdata); 7627 dns_rdataset_current(rdset, &rdata); 7628 normalize_key(&rdata, &rdata2, data2, sizeof(data2)); 7629 if (dns_rdata_compare(&rdata1, &rdata2) == 0) 7630 return (ISC_TRUE); 7631 } 7632 7633 return (ISC_FALSE); 7634} 7635 7636/* 7637 * Calculate the refresh interval for a keydata zone, per 7638 * RFC5011: MAX(1 hr, 7639 * MIN(15 days, 7640 * 1/2 * OrigTTL, 7641 * 1/2 * RRSigExpirationInterval)) 7642 * or for retries: MAX(1 hr, 7643 * MIN(1 day, 7644 * 1/10 * OrigTTL, 7645 * 1/10 * RRSigExpirationInterval)) 7646 */ 7647static inline isc_stdtime_t 7648refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) { 7649 isc_result_t result; 7650 isc_uint32_t t; 7651 dns_rdataset_t *rdset; 7652 dns_rdata_t sigrr = DNS_RDATA_INIT; 7653 dns_rdata_sig_t sig; 7654 isc_stdtime_t now; 7655 7656 isc_stdtime_get(&now); 7657 7658 if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) 7659 rdset = &kfetch->dnskeysigset; 7660 else 7661 return (now + HOUR); 7662 7663 result = dns_rdataset_first(rdset); 7664 if (result != ISC_R_SUCCESS) 7665 return (now + HOUR); 7666 7667 dns_rdataset_current(rdset, &sigrr); 7668 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 7669 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7670 7671 if (!retry) { 7672 t = sig.originalttl / 2; 7673 7674 if (isc_serial_gt(sig.timeexpire, now)) { 7675 isc_uint32_t exp = (sig.timeexpire - now) / 2; 7676 if (t > exp) 7677 t = exp; 7678 } 7679 7680 if (t > (15*DAY)) 7681 t = (15*DAY); 7682 7683 if (t < HOUR) 7684 t = HOUR; 7685 } else { 7686 t = sig.originalttl / 10; 7687 7688 if (isc_serial_gt(sig.timeexpire, now)) { 7689 isc_uint32_t exp = (sig.timeexpire - now) / 10; 7690 if (t > exp) 7691 t = exp; 7692 } 7693 7694 if (t > DAY) 7695 t = DAY; 7696 7697 if (t < HOUR) 7698 t = HOUR; 7699 } 7700 7701 return (now + t); 7702} 7703 7704/* 7705 * This routine is called when no changes are needed in a KEYDATA 7706 * record except to simply update the refresh timer. Caller should 7707 * hold zone lock. 7708 */ 7709static isc_result_t 7710minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) 7711{ 7712 isc_result_t result; 7713 isc_buffer_t keyb; 7714 unsigned char key_buf[4096]; 7715 dns_rdata_t rdata = DNS_RDATA_INIT; 7716 dns_rdata_keydata_t keydata; 7717 dns_name_t *name; 7718 dns_zone_t *zone = kfetch->zone; 7719 isc_stdtime_t now; 7720 7721 name = dns_fixedname_name(&kfetch->name); 7722 isc_stdtime_get(&now); 7723 7724 for (result = dns_rdataset_first(&kfetch->keydataset); 7725 result == ISC_R_SUCCESS; 7726 result = dns_rdataset_next(&kfetch->keydataset)) { 7727 dns_rdata_reset(&rdata); 7728 dns_rdataset_current(&kfetch->keydataset, &rdata); 7729 7730 /* Delete old version */ 7731 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL, 7732 name, 0, &rdata)); 7733 7734 /* Update refresh timer */ 7735 CHECK(dns_rdata_tostruct(&rdata, &keydata, NULL)); 7736 keydata.refresh = refresh_time(kfetch, ISC_TRUE); 7737 set_refreshkeytimer(zone, &keydata, now); 7738 7739 dns_rdata_reset(&rdata); 7740 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 7741 CHECK(dns_rdata_fromstruct(&rdata, 7742 zone->rdclass, dns_rdatatype_keydata, 7743 &keydata, &keyb)); 7744 7745 /* Insert updated version */ 7746 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD, 7747 name, 0, &rdata)); 7748 } 7749 result = ISC_R_SUCCESS; 7750 failure: 7751 return (result); 7752} 7753 7754/* 7755 * Verify that DNSKEY set is signed by the key specified in 'keydata'. 7756 */ 7757static isc_boolean_t 7758revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) { 7759 isc_result_t result; 7760 dns_name_t *keyname; 7761 isc_mem_t *mctx; 7762 dns_rdata_t sigrr = DNS_RDATA_INIT; 7763 dns_rdata_t rr = DNS_RDATA_INIT; 7764 dns_rdata_rrsig_t sig; 7765 dns_rdata_dnskey_t dnskey; 7766 dst_key_t *dstkey = NULL; 7767 unsigned char key_buf[4096]; 7768 isc_buffer_t keyb; 7769 isc_boolean_t answer = ISC_FALSE; 7770 7771 REQUIRE(kfetch != NULL && keydata != NULL); 7772 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset)); 7773 7774 keyname = dns_fixedname_name(&kfetch->name); 7775 mctx = kfetch->zone->view->mctx; 7776 7777 /* Generate a key from keydata */ 7778 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 7779 dns_keydata_todnskey(keydata, &dnskey, NULL); 7780 dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey, 7781 &dnskey, &keyb); 7782 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey); 7783 if (result != ISC_R_SUCCESS) 7784 return (ISC_FALSE); 7785 7786 /* See if that key generated any of the signatures */ 7787 for (result = dns_rdataset_first(&kfetch->dnskeysigset); 7788 result == ISC_R_SUCCESS; 7789 result = dns_rdataset_next(&kfetch->dnskeysigset)) { 7790 dns_fixedname_t fixed; 7791 dns_fixedname_init(&fixed); 7792 7793 dns_rdata_reset(&sigrr); 7794 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr); 7795 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 7796 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7797 7798 if (dst_key_alg(dstkey) == sig.algorithm && 7799 (dst_key_id(dstkey) == sig.keyid || 7800 dst_key_rid(dstkey) == sig.keyid)) { 7801 result = dns_dnssec_verify2(keyname, 7802 &kfetch->dnskeyset, 7803 dstkey, ISC_FALSE, mctx, &sigrr, 7804 dns_fixedname_name(&fixed)); 7805 7806 dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3), 7807 "Confirm revoked DNSKEY is self-signed: " 7808 "%s", dns_result_totext(result)); 7809 7810 if (result == ISC_R_SUCCESS) { 7811 answer = ISC_TRUE; 7812 break; 7813 } 7814 } 7815 } 7816 7817 dst_key_free(&dstkey); 7818 return (answer); 7819} 7820 7821/* 7822 * A DNSKEY set has been fetched from the zone apex of a zone whose trust 7823 * anchors are being managed; scan the keyset, and update the key zone and the 7824 * local trust anchors according to RFC5011. 7825 */ 7826static void 7827keyfetch_done(isc_task_t *task, isc_event_t *event) { 7828 isc_result_t result, eresult; 7829 dns_fetchevent_t *devent; 7830 dns_keyfetch_t *kfetch; 7831 dns_zone_t *zone; 7832 isc_mem_t *mctx = NULL; 7833 dns_keytable_t *secroots = NULL; 7834 dns_dbversion_t *ver = NULL; 7835 dns_diff_t diff; 7836 isc_boolean_t alldone = ISC_FALSE; 7837 isc_boolean_t commit = ISC_FALSE; 7838 dns_name_t *keyname; 7839 dns_rdata_t sigrr = DNS_RDATA_INIT; 7840 dns_rdata_t dnskeyrr = DNS_RDATA_INIT; 7841 dns_rdata_t keydatarr = DNS_RDATA_INIT; 7842 dns_rdata_rrsig_t sig; 7843 dns_rdata_dnskey_t dnskey; 7844 dns_rdata_keydata_t keydata; 7845 isc_boolean_t initializing; 7846 char namebuf[DNS_NAME_FORMATSIZE]; 7847 unsigned char key_buf[4096]; 7848 isc_buffer_t keyb; 7849 dst_key_t *dstkey; 7850 isc_stdtime_t now; 7851 int pending = 0; 7852 isc_boolean_t secure; 7853 isc_boolean_t free_needed; 7854 7855 UNUSED(task); 7856 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE); 7857 INSIST(event->ev_arg != NULL); 7858 7859 kfetch = event->ev_arg; 7860 zone = kfetch->zone; 7861 isc_mem_attach(zone->mctx, &mctx); 7862 keyname = dns_fixedname_name(&kfetch->name); 7863 7864 devent = (dns_fetchevent_t *) event; 7865 eresult = devent->result; 7866 7867 /* Free resources which are not of interest */ 7868 if (devent->node != NULL) 7869 dns_db_detachnode(devent->db, &devent->node); 7870 if (devent->db != NULL) 7871 dns_db_detach(&devent->db); 7872 isc_event_free(&event); 7873 dns_resolver_destroyfetch(&kfetch->fetch); 7874 7875 LOCK_ZONE(zone); 7876 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) 7877 goto cleanup; 7878 7879 isc_stdtime_get(&now); 7880 dns_name_format(keyname, namebuf, sizeof(namebuf)); 7881 7882 result = dns_view_getsecroots(zone->view, &secroots); 7883 INSIST(result == ISC_R_SUCCESS); 7884 7885 dns_diff_init(mctx, &diff); 7886 diff.resign = zone->sigresigninginterval; 7887 7888 CHECK(dns_db_newversion(kfetch->db, &ver)); 7889 7890 zone->refreshkeycount--; 7891 alldone = ISC_TF(zone->refreshkeycount == 0); 7892 7893 if (alldone) 7894 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 7895 7896 /* Fetch failed */ 7897 if (eresult != ISC_R_SUCCESS || 7898 !dns_rdataset_isassociated(&kfetch->dnskeyset)) { 7899 dns_zone_log(zone, ISC_LOG_WARNING, 7900 "Unable to fetch DNSKEY set " 7901 "'%s': %s", namebuf, dns_result_totext(eresult)); 7902 CHECK(minimal_update(kfetch, ver, &diff)); 7903 goto done; 7904 } 7905 7906 /* No RRSIGs found */ 7907 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) { 7908 dns_zone_log(zone, ISC_LOG_WARNING, 7909 "No DNSKEY RRSIGs found for " 7910 "'%s': %s", namebuf, dns_result_totext(eresult)); 7911 CHECK(minimal_update(kfetch, ver, &diff)); 7912 goto done; 7913 } 7914 7915 /* 7916 * Validate the dnskeyset against the current trusted keys. 7917 */ 7918 for (result = dns_rdataset_first(&kfetch->dnskeysigset); 7919 result == ISC_R_SUCCESS; 7920 result = dns_rdataset_next(&kfetch->dnskeysigset)) { 7921 dns_keynode_t *keynode = NULL; 7922 7923 dns_rdata_reset(&sigrr); 7924 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr); 7925 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 7926 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7927 7928 result = dns_keytable_find(secroots, keyname, &keynode); 7929 while (result == ISC_R_SUCCESS) { 7930 dns_keynode_t *nextnode = NULL; 7931 dns_fixedname_t fixed; 7932 dns_fixedname_init(&fixed); 7933 7934 dstkey = dns_keynode_key(keynode); 7935 if (dstkey == NULL) /* fail_secure() was called */ 7936 break; 7937 7938 if (dst_key_alg(dstkey) == sig.algorithm && 7939 dst_key_id(dstkey) == sig.keyid) { 7940 result = dns_dnssec_verify2(keyname, 7941 &kfetch->dnskeyset, 7942 dstkey, ISC_FALSE, 7943 zone->view->mctx, &sigrr, 7944 dns_fixedname_name(&fixed)); 7945 7946 dns_zone_log(zone, ISC_LOG_DEBUG(3), 7947 "Verifying DNSKEY set for zone " 7948 "'%s': %s", namebuf, 7949 dns_result_totext(result)); 7950 7951 if (result == ISC_R_SUCCESS) { 7952 kfetch->dnskeyset.trust = 7953 dns_trust_secure; 7954 kfetch->dnskeysigset.trust = 7955 dns_trust_secure; 7956 dns_keytable_detachkeynode(secroots, 7957 &keynode); 7958 break; 7959 } 7960 } 7961 7962 result = dns_keytable_nextkeynode(secroots, 7963 keynode, &nextnode); 7964 dns_keytable_detachkeynode(secroots, &keynode); 7965 keynode = nextnode; 7966 } 7967 7968 if (kfetch->dnskeyset.trust == dns_trust_secure) 7969 break; 7970 } 7971 7972 /* 7973 * If we were not able to verify the answer using the current 7974 * trusted keys then all we can do is look at any revoked keys. 7975 */ 7976 secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure); 7977 7978 /* 7979 * First scan keydataset to find keys that are not in dnskeyset 7980 * - Missing keys which are not scheduled for removal, 7981 * log a warning 7982 * - Missing keys which are scheduled for removal and 7983 * the remove hold-down timer has completed should 7984 * be removed from the key zone 7985 * - Missing keys whose acceptance timers have not yet 7986 * completed, log a warning and reset the acceptance 7987 * timer to 30 days in the future 7988 * - All keys not being removed have their refresh timers 7989 * updated 7990 */ 7991 initializing = ISC_TRUE; 7992 for (result = dns_rdataset_first(&kfetch->keydataset); 7993 result == ISC_R_SUCCESS; 7994 result = dns_rdataset_next(&kfetch->keydataset)) { 7995 dns_rdata_reset(&keydatarr); 7996 dns_rdataset_current(&kfetch->keydataset, &keydatarr); 7997 dns_rdata_tostruct(&keydatarr, &keydata, NULL); 7998 7999 /* 8000 * If any keydata record has a nonzero add holddown, then 8001 * there was a pre-existing trust anchor for this domain; 8002 * that means we are *not* initializing it and shouldn't 8003 * automatically trust all the keys we find at the zone apex. 8004 */ 8005 initializing = initializing && ISC_TF(keydata.addhd == 0); 8006 8007 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) { 8008 isc_boolean_t deletekey = ISC_FALSE; 8009 8010 if (!secure) { 8011 if (now > keydata.removehd) 8012 deletekey = ISC_TRUE; 8013 } else if (now < keydata.addhd) { 8014 dns_zone_log(zone, ISC_LOG_WARNING, 8015 "Pending key unexpectedly missing " 8016 "from %s; restarting acceptance " 8017 "timer", namebuf); 8018 keydata.addhd = now + MONTH; 8019 keydata.refresh = refresh_time(kfetch, 8020 ISC_FALSE); 8021 } else if (keydata.addhd == 0) { 8022 keydata.addhd = now; 8023 } else if (keydata.removehd == 0) { 8024 dns_zone_log(zone, ISC_LOG_WARNING, 8025 "Active key unexpectedly missing " 8026 "from %s", namebuf); 8027 keydata.refresh = now + HOUR; 8028 } else if (now > keydata.removehd) { 8029 deletekey = ISC_TRUE; 8030 } else { 8031 keydata.refresh = refresh_time(kfetch, 8032 ISC_FALSE); 8033 } 8034 8035 if (secure || deletekey) { 8036 /* Delete old version */ 8037 CHECK(update_one_rr(kfetch->db, ver, &diff, 8038 DNS_DIFFOP_DEL, keyname, 0, 8039 &keydatarr)); 8040 } 8041 8042 if (!secure || deletekey) 8043 continue; 8044 8045 dns_rdata_reset(&keydatarr); 8046 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 8047 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 8048 dns_rdatatype_keydata, 8049 &keydata, &keyb); 8050 8051 /* Insert updated version */ 8052 CHECK(update_one_rr(kfetch->db, ver, &diff, 8053 DNS_DIFFOP_ADD, keyname, 0, 8054 &keydatarr)); 8055 8056 set_refreshkeytimer(zone, &keydata, now); 8057 } 8058 } 8059 8060 /* 8061 * Next scan dnskeyset: 8062 * - If new keys are found (i.e., lacking a match in keydataset) 8063 * add them to the key zone and set the acceptance timer 8064 * to 30 days in the future (or to immediately if we've 8065 * determined that we're initializing the zone for the 8066 * first time) 8067 * - Previously-known keys that have been revoked 8068 * must be scheduled for removal from the key zone (or, 8069 * if they hadn't been accepted as trust anchors yet 8070 * anyway, removed at once) 8071 * - Previously-known unrevoked keys whose acceptance timers 8072 * have completed are promoted to trust anchors 8073 * - All keys not being removed have their refresh 8074 * timers updated 8075 */ 8076 for (result = dns_rdataset_first(&kfetch->dnskeyset); 8077 result == ISC_R_SUCCESS; 8078 result = dns_rdataset_next(&kfetch->dnskeyset)) { 8079 isc_boolean_t revoked = ISC_FALSE; 8080 isc_boolean_t newkey = ISC_FALSE; 8081 isc_boolean_t updatekey = ISC_FALSE; 8082 isc_boolean_t deletekey = ISC_FALSE; 8083 isc_boolean_t trustkey = ISC_FALSE; 8084 8085 dns_rdata_reset(&dnskeyrr); 8086 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr); 8087 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 8088 8089 /* Skip ZSK's */ 8090 if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK)) 8091 continue; 8092 8093 revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE); 8094 8095 if (matchkey(&kfetch->keydataset, &dnskeyrr)) { 8096 dns_rdata_reset(&keydatarr); 8097 dns_rdataset_current(&kfetch->keydataset, &keydatarr); 8098 dns_rdata_tostruct(&keydatarr, &keydata, NULL); 8099 8100 if (revoked && revocable(kfetch, &keydata)) { 8101 if (keydata.addhd > now) { 8102 /* 8103 * Key wasn't trusted yet, and now 8104 * it's been revoked? Just remove it 8105 */ 8106 deletekey = ISC_TRUE; 8107 } else if (keydata.removehd == 0) { 8108 /* Remove from secroots */ 8109 dns_view_untrust(zone->view, keyname, 8110 &dnskey, mctx); 8111 8112 /* If initializing, delete now */ 8113 if (keydata.addhd == 0) 8114 deletekey = ISC_TRUE; 8115 else 8116 keydata.removehd = now + MONTH; 8117 } else if (keydata.removehd < now) { 8118 /* Scheduled for removal */ 8119 deletekey = ISC_TRUE; 8120 } 8121 } else if (revoked) { 8122 if (secure && keydata.removehd == 0) { 8123 dns_zone_log(zone, ISC_LOG_WARNING, 8124 "Active key for zone " 8125 "'%s' is revoked but " 8126 "did not self-sign; " 8127 "ignoring.", namebuf); 8128 continue; 8129 } 8130 } else if (secure) { 8131 if (keydata.removehd != 0) { 8132 /* 8133 * Key isn't revoked--but it 8134 * seems it used to be. 8135 * Remove it now and add it 8136 * back as if it were a fresh key. 8137 */ 8138 deletekey = ISC_TRUE; 8139 newkey = ISC_TRUE; 8140 } else if (keydata.addhd > now) 8141 pending++; 8142 else if (keydata.addhd == 0) 8143 keydata.addhd = now; 8144 8145 if (keydata.addhd <= now) 8146 trustkey = ISC_TRUE; 8147 } 8148 8149 if (!deletekey && !newkey) 8150 updatekey = ISC_TRUE; 8151 } else if (secure) { 8152 /* 8153 * Key wasn't in the key zone but it's 8154 * revoked now anyway, so just skip it 8155 */ 8156 if (revoked) 8157 continue; 8158 8159 /* Key wasn't in the key zone: add it */ 8160 newkey = ISC_TRUE; 8161 8162 if (initializing) { 8163 dns_keytag_t tag = 0; 8164 CHECK(compute_tag(keyname, &dnskey, 8165 mctx, &tag)); 8166 dns_zone_log(zone, ISC_LOG_WARNING, 8167 "Initializing automatic trust " 8168 "anchor management for zone '%s'; " 8169 "DNSKEY ID %d is now trusted, " 8170 "waiving the normal 30-day " 8171 "waiting period.", 8172 namebuf, tag); 8173 trustkey = ISC_TRUE; 8174 } 8175 } 8176 8177 /* Delete old version */ 8178 if (deletekey || !newkey) 8179 CHECK(update_one_rr(kfetch->db, ver, &diff, 8180 DNS_DIFFOP_DEL, keyname, 0, 8181 &keydatarr)); 8182 8183 if (updatekey) { 8184 /* Set refresh timer */ 8185 keydata.refresh = refresh_time(kfetch, ISC_FALSE); 8186 dns_rdata_reset(&keydatarr); 8187 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 8188 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 8189 dns_rdatatype_keydata, 8190 &keydata, &keyb); 8191 8192 /* Insert updated version */ 8193 CHECK(update_one_rr(kfetch->db, ver, &diff, 8194 DNS_DIFFOP_ADD, keyname, 0, 8195 &keydatarr)); 8196 } else if (newkey) { 8197 /* Convert DNSKEY to KEYDATA */ 8198 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 8199 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0, 8200 NULL); 8201 keydata.addhd = initializing ? now : now + MONTH; 8202 keydata.refresh = refresh_time(kfetch, ISC_FALSE); 8203 dns_rdata_reset(&keydatarr); 8204 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 8205 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 8206 dns_rdatatype_keydata, 8207 &keydata, &keyb); 8208 8209 /* Insert into key zone */ 8210 CHECK(update_one_rr(kfetch->db, ver, &diff, 8211 DNS_DIFFOP_ADD, keyname, 0, 8212 &keydatarr)); 8213 } 8214 8215 if (trustkey) { 8216 /* Trust this key. */ 8217 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 8218 trust_key(zone, keyname, &dnskey, mctx); 8219 } 8220 8221 if (!deletekey) 8222 set_refreshkeytimer(zone, &keydata, now); 8223 } 8224 8225 /* 8226 * RFC5011 says, "A trust point that has all of its trust anchors 8227 * revoked is considered deleted and is treated as if the trust 8228 * point was never configured." But if someone revoked their 8229 * active key before the standby was trusted, that would mean the 8230 * zone would suddenly be nonsecured. We avoid this by checking to 8231 * see if there's pending keydata. If so, we put a null key in 8232 * the security roots; then all queries to the zone will fail. 8233 */ 8234 if (pending != 0) 8235 fail_secure(zone, keyname); 8236 8237 done: 8238 8239 if (!ISC_LIST_EMPTY(diff.tuples)) { 8240 /* Write changes to journal file. */ 8241 CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx, 8242 zone->updatemethod)); 8243 CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done")); 8244 commit = ISC_TRUE; 8245 8246 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 8247 zone_needdump(zone, 30); 8248 } 8249 8250 failure: 8251 8252 dns_diff_clear(&diff); 8253 if (ver != NULL) 8254 dns_db_closeversion(kfetch->db, &ver, commit); 8255 8256 cleanup: 8257 dns_db_detach(&kfetch->db); 8258 8259 INSIST(zone->irefs > 0); 8260 zone->irefs--; 8261 kfetch->zone = NULL; 8262 8263 if (dns_rdataset_isassociated(&kfetch->keydataset)) 8264 dns_rdataset_disassociate(&kfetch->keydataset); 8265 if (dns_rdataset_isassociated(&kfetch->dnskeyset)) 8266 dns_rdataset_disassociate(&kfetch->dnskeyset); 8267 if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) 8268 dns_rdataset_disassociate(&kfetch->dnskeysigset); 8269 8270 dns_name_free(keyname, mctx); 8271 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t)); 8272 isc_mem_detach(&mctx); 8273 8274 if (secroots != NULL) 8275 dns_keytable_detach(&secroots); 8276 8277 free_needed = exit_check(zone); 8278 UNLOCK_ZONE(zone); 8279 if (free_needed) 8280 zone_free(zone); 8281} 8282 8283/* 8284 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY 8285 * records from the zone apex. 8286 */ 8287static void 8288zone_refreshkeys(dns_zone_t *zone) { 8289 const char me[] = "zone_refreshkeys"; 8290 isc_result_t result; 8291 dns_rriterator_t rrit; 8292 dns_db_t *db = NULL; 8293 dns_dbversion_t *ver = NULL; 8294 dns_diff_t diff; 8295 dns_rdata_t rdata = DNS_RDATA_INIT; 8296 dns_rdata_keydata_t kd; 8297 isc_stdtime_t now; 8298 isc_boolean_t commit = ISC_FALSE; 8299 isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE; 8300 8301 ENTER; 8302 REQUIRE(zone->db != NULL); 8303 8304 isc_stdtime_get(&now); 8305 8306 LOCK_ZONE(zone); 8307 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 8308 isc_time_settoepoch(&zone->refreshkeytime); 8309 UNLOCK_ZONE(zone); 8310 return; 8311 } 8312 8313 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8314 dns_db_attach(zone->db, &db); 8315 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8316 8317 dns_diff_init(zone->mctx, &diff); 8318 8319 CHECK(dns_db_newversion(db, &ver)); 8320 8321 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING); 8322 8323 dns_rriterator_init(&rrit, db, ver, 0); 8324 for (result = dns_rriterator_first(&rrit); 8325 result == ISC_R_SUCCESS; 8326 result = dns_rriterator_nextrrset(&rrit)) { 8327 isc_stdtime_t timer = 0xffffffff; 8328 dns_name_t *name = NULL, *kname = NULL; 8329 dns_rdataset_t *kdset = NULL; 8330 dns_keyfetch_t *kfetch; 8331 isc_uint32_t ttl; 8332 8333 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL); 8334 if (kdset == NULL || kdset->type != dns_rdatatype_keydata || 8335 !dns_rdataset_isassociated(kdset)) 8336 continue; 8337 8338 /* 8339 * Scan the stored keys looking for ones that need 8340 * removal or refreshing 8341 */ 8342 for (result = dns_rdataset_first(kdset); 8343 result == ISC_R_SUCCESS; 8344 result = dns_rdataset_next(kdset)) { 8345 dns_rdata_reset(&rdata); 8346 dns_rdataset_current(kdset, &rdata); 8347 result = dns_rdata_tostruct(&rdata, &kd, NULL); 8348 RUNTIME_CHECK(result == ISC_R_SUCCESS); 8349 8350 /* Removal timer expired? */ 8351 if (kd.removehd != 0 && kd.removehd < now) { 8352 CHECK(update_one_rr(db, ver, &diff, 8353 DNS_DIFFOP_DEL, name, ttl, 8354 &rdata)); 8355 continue; 8356 } 8357 8358 /* Acceptance timer expired? */ 8359 if (kd.addhd != 0 && kd.addhd < now) 8360 timer = kd.addhd; 8361 8362 /* Or do we just need to refresh the keyset? */ 8363 if (timer > kd.refresh) 8364 timer = kd.refresh; 8365 } 8366 8367 if (timer > now) 8368 continue; 8369 8370 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t)); 8371 if (kfetch == NULL) { 8372 fetch_err = ISC_TRUE; 8373 goto failure; 8374 } 8375 8376 zone->refreshkeycount++; 8377 kfetch->zone = zone; 8378 zone->irefs++; 8379 INSIST(zone->irefs != 0); 8380 dns_fixedname_init(&kfetch->name); 8381 kname = dns_fixedname_name(&kfetch->name); 8382 dns_name_dup(name, zone->mctx, kname); 8383 dns_rdataset_init(&kfetch->dnskeyset); 8384 dns_rdataset_init(&kfetch->dnskeysigset); 8385 dns_rdataset_init(&kfetch->keydataset); 8386 dns_rdataset_clone(kdset, &kfetch->keydataset); 8387 kfetch->db = NULL; 8388 dns_db_attach(db, &kfetch->db); 8389 kfetch->fetch = NULL; 8390 8391 result = dns_resolver_createfetch(zone->view->resolver, 8392 kname, dns_rdatatype_dnskey, 8393 NULL, NULL, NULL, 8394 DNS_FETCHOPT_NOVALIDATE, 8395 zone->task, 8396 keyfetch_done, kfetch, 8397 &kfetch->dnskeyset, 8398 &kfetch->dnskeysigset, 8399 &kfetch->fetch); 8400 if (result == ISC_R_SUCCESS) 8401 fetching = ISC_TRUE; 8402 else { 8403 zone->refreshkeycount--; 8404 zone->irefs--; 8405 dns_db_detach(&kfetch->db); 8406 dns_rdataset_disassociate(&kfetch->keydataset); 8407 dns_name_free(kname, zone->mctx); 8408 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t)); 8409 dns_zone_log(zone, ISC_LOG_WARNING, 8410 "Failed to create fetch for " 8411 "DNSKEY update"); 8412 fetch_err = ISC_TRUE; 8413 } 8414 } 8415 if (!ISC_LIST_EMPTY(diff.tuples)) { 8416 CHECK(update_soa_serial(db, ver, &diff, zone->mctx, 8417 zone->updatemethod)); 8418 CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys")); 8419 commit = ISC_TRUE; 8420 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 8421 zone_needdump(zone, 30); 8422 } 8423 8424 failure: 8425 if (fetch_err) { 8426 /* 8427 * Error during a key fetch; retry in an hour. 8428 */ 8429 isc_time_t timenow, timethen; 8430 char timebuf[80]; 8431 8432 TIME_NOW(&timenow); 8433 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen); 8434 zone->refreshkeytime = timethen; 8435 zone_settimer(zone, &timenow); 8436 8437 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 8438 dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s", 8439 timebuf); 8440 8441 if (!fetching) 8442 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 8443 } 8444 8445 UNLOCK_ZONE(zone); 8446 8447 dns_diff_clear(&diff); 8448 if (ver != NULL) { 8449 dns_rriterator_destroy(&rrit); 8450 dns_db_closeversion(db, &ver, commit); 8451 } 8452 dns_db_detach(&db); 8453} 8454 8455static void 8456zone_maintenance(dns_zone_t *zone) { 8457 const char me[] = "zone_maintenance"; 8458 isc_time_t now; 8459 isc_result_t result; 8460 isc_boolean_t dumping; 8461 8462 REQUIRE(DNS_ZONE_VALID(zone)); 8463 ENTER; 8464 8465 /* 8466 * Are we pending load/reload? 8467 */ 8468 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) 8469 return; 8470 8471 /* 8472 * Configuring the view of this zone may have 8473 * failed, for example because the config file 8474 * had a syntax error. In that case, the view 8475 * adb or resolver will be NULL, and we had better not try 8476 * to do further maintenance on it. 8477 */ 8478 if (zone->view == NULL || zone->view->adb == NULL) 8479 return; 8480 8481 TIME_NOW(&now); 8482 8483 /* 8484 * Expire check. 8485 */ 8486 switch (zone->type) { 8487 case dns_zone_redirect: 8488 if (zone->masters == NULL) 8489 break; 8490 case dns_zone_slave: 8491 case dns_zone_stub: 8492 LOCK_ZONE(zone); 8493 if (isc_time_compare(&now, &zone->expiretime) >= 0 && 8494 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 8495 zone_expire(zone); 8496 zone->refreshtime = now; 8497 } 8498 UNLOCK_ZONE(zone); 8499 break; 8500 default: 8501 break; 8502 } 8503 8504 /* 8505 * Up to date check. 8506 */ 8507 switch (zone->type) { 8508 case dns_zone_redirect: 8509 if (zone->masters == NULL) 8510 break; 8511 case dns_zone_slave: 8512 case dns_zone_stub: 8513 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && 8514 isc_time_compare(&now, &zone->refreshtime) >= 0) 8515 dns_zone_refresh(zone); 8516 break; 8517 default: 8518 break; 8519 } 8520 8521 /* 8522 * Do we need to consolidate the backing store? 8523 */ 8524 switch (zone->type) { 8525 case dns_zone_master: 8526 case dns_zone_slave: 8527 case dns_zone_key: 8528 case dns_zone_redirect: 8529 case dns_zone_stub: 8530 LOCK_ZONE(zone); 8531 if (zone->masterfile != NULL && 8532 isc_time_compare(&now, &zone->dumptime) >= 0 && 8533 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 8534 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) { 8535 dumping = was_dumping(zone); 8536 } else 8537 dumping = ISC_TRUE; 8538 UNLOCK_ZONE(zone); 8539 if (!dumping) { 8540 result = zone_dump(zone, ISC_TRUE); /* task locked */ 8541 if (result != ISC_R_SUCCESS) 8542 dns_zone_log(zone, ISC_LOG_WARNING, 8543 "dump failed: %s", 8544 dns_result_totext(result)); 8545 } 8546 break; 8547 default: 8548 break; 8549 } 8550 8551 /* 8552 * Do we need to refresh keys? 8553 */ 8554 switch (zone->type) { 8555 case dns_zone_key: 8556 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0 && 8557 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 8558 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) 8559 zone_refreshkeys(zone); 8560 break; 8561 case dns_zone_master: 8562 if (!isc_time_isepoch(&zone->refreshkeytime) && 8563 isc_time_compare(&now, &zone->refreshkeytime) >= 0) 8564 zone_rekey(zone); 8565 default: 8566 break; 8567 } 8568 8569 switch (zone->type) { 8570 case dns_zone_master: 8571 case dns_zone_redirect: 8572 case dns_zone_slave: 8573 /* 8574 * Do we need to send out notify messages? 8575 */ 8576 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) && 8577 isc_time_compare(&now, &zone->notifytime) >= 0) 8578 zone_notify(zone, &now); 8579 /* 8580 * Do we need to sign/resign some RRsets? 8581 */ 8582 if (!isc_time_isepoch(&zone->signingtime) && 8583 isc_time_compare(&now, &zone->signingtime) >= 0) 8584 zone_sign(zone); 8585 else if (!isc_time_isepoch(&zone->resigntime) && 8586 isc_time_compare(&now, &zone->resigntime) >= 0) 8587 zone_resigninc(zone); 8588 else if (!isc_time_isepoch(&zone->nsec3chaintime) && 8589 isc_time_compare(&now, &zone->nsec3chaintime) >= 0) 8590 zone_nsec3chain(zone); 8591 /* 8592 * Do we need to issue a key expiry warning. 8593 */ 8594 if (!isc_time_isepoch(&zone->keywarntime) && 8595 isc_time_compare(&now, &zone->keywarntime) >= 0) 8596 set_key_expiry_warning(zone, zone->key_expiry, 8597 isc_time_seconds(&now)); 8598 break; 8599 8600 default: 8601 break; 8602 } 8603 zone_settimer(zone, &now); 8604} 8605 8606void 8607dns_zone_markdirty(dns_zone_t *zone) { 8608 isc_uint32_t serial; 8609 isc_result_t result; 8610 8611 LOCK_ZONE(zone); 8612 if (zone->type == dns_zone_master) { 8613 if (inline_raw(zone)) { 8614 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8615 if (zone->db != NULL) { 8616 result = zone_get_from_db(zone, zone->db, NULL, 8617 NULL, &serial, NULL, 8618 NULL, NULL, NULL, 8619 NULL); 8620 } else 8621 result = DNS_R_NOTLOADED; 8622 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8623 if (result == ISC_R_SUCCESS) 8624 zone_send_secureserial(zone, ISC_FALSE, serial); 8625 } 8626 set_resigntime(zone); /* XXXMPA make separate call back */ 8627 } 8628 zone_needdump(zone, DNS_DUMP_DELAY); 8629 UNLOCK_ZONE(zone); 8630} 8631 8632void 8633dns_zone_expire(dns_zone_t *zone) { 8634 REQUIRE(DNS_ZONE_VALID(zone)); 8635 8636 LOCK_ZONE(zone); 8637 zone_expire(zone); 8638 UNLOCK_ZONE(zone); 8639} 8640 8641static void 8642zone_expire(dns_zone_t *zone) { 8643 /* 8644 * 'zone' locked by caller. 8645 */ 8646 8647 REQUIRE(LOCKED_ZONE(zone)); 8648 8649 dns_zone_log(zone, ISC_LOG_WARNING, "expired"); 8650 8651 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED); 8652 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 8653 zone->retry = DNS_ZONE_DEFAULTRETRY; 8654 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 8655 zone_unload(zone); 8656} 8657 8658void 8659dns_zone_refresh(dns_zone_t *zone) { 8660 isc_interval_t i; 8661 isc_uint32_t oldflags; 8662 unsigned int j; 8663 isc_result_t result; 8664 8665 REQUIRE(DNS_ZONE_VALID(zone)); 8666 8667 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 8668 return; 8669 8670 /* 8671 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation 8672 * in progress at a time. 8673 */ 8674 8675 LOCK_ZONE(zone); 8676 oldflags = zone->flags; 8677 if (zone->masterscnt == 0) { 8678 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS); 8679 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0) 8680 dns_zone_log(zone, ISC_LOG_ERROR, 8681 "cannot refresh: no masters"); 8682 goto unlock; 8683 } 8684 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 8685 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 8686 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 8687 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0) 8688 goto unlock; 8689 8690 /* 8691 * Set the next refresh time as if refresh check has failed. 8692 * Setting this to the retry time will do that. XXXMLG 8693 * If we are successful it will be reset using zone->refresh. 8694 */ 8695 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4), 8696 0); 8697 result = isc_time_nowplusinterval(&zone->refreshtime, &i); 8698 if (result != ISC_R_SUCCESS) 8699 dns_zone_log(zone, ISC_LOG_WARNING, 8700 "isc_time_nowplusinterval() failed: %s", 8701 dns_result_totext(result)); 8702 8703 /* 8704 * When lacking user-specified timer values from the SOA, 8705 * do exponential backoff of the retry time up to a 8706 * maximum of six hours. 8707 */ 8708 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) 8709 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600); 8710 8711 zone->curmaster = 0; 8712 for (j = 0; j < zone->masterscnt; j++) 8713 zone->mastersok[j] = ISC_FALSE; 8714 /* initiate soa query */ 8715 queue_soa_query(zone); 8716 unlock: 8717 UNLOCK_ZONE(zone); 8718} 8719 8720isc_result_t 8721dns_zone_flush(dns_zone_t *zone) { 8722 isc_result_t result = ISC_R_SUCCESS; 8723 isc_boolean_t dumping; 8724 8725 REQUIRE(DNS_ZONE_VALID(zone)); 8726 8727 LOCK_ZONE(zone); 8728 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH); 8729 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 8730 zone->masterfile != NULL) { 8731 result = ISC_R_ALREADYRUNNING; 8732 dumping = was_dumping(zone); 8733 } else 8734 dumping = ISC_TRUE; 8735 UNLOCK_ZONE(zone); 8736 if (!dumping) 8737 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */ 8738 return (result); 8739} 8740 8741isc_result_t 8742dns_zone_dump(dns_zone_t *zone) { 8743 isc_result_t result = ISC_R_ALREADYRUNNING; 8744 isc_boolean_t dumping; 8745 8746 REQUIRE(DNS_ZONE_VALID(zone)); 8747 8748 LOCK_ZONE(zone); 8749 dumping = was_dumping(zone); 8750 UNLOCK_ZONE(zone); 8751 if (!dumping) 8752 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */ 8753 return (result); 8754} 8755 8756static void 8757zone_needdump(dns_zone_t *zone, unsigned int delay) { 8758 isc_time_t dumptime; 8759 isc_time_t now; 8760 8761 /* 8762 * 'zone' locked by caller 8763 */ 8764 8765 REQUIRE(DNS_ZONE_VALID(zone)); 8766 REQUIRE(LOCKED_ZONE(zone)); 8767 8768 /* 8769 * Do we have a place to dump to and are we loaded? 8770 */ 8771 if (zone->masterfile == NULL || 8772 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) 8773 return; 8774 8775 TIME_NOW(&now); 8776 /* add some noise */ 8777 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime); 8778 8779 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 8780 if (isc_time_isepoch(&zone->dumptime) || 8781 isc_time_compare(&zone->dumptime, &dumptime) > 0) 8782 zone->dumptime = dumptime; 8783 if (zone->task != NULL) 8784 zone_settimer(zone, &now); 8785} 8786 8787static void 8788dump_done(void *arg, isc_result_t result) { 8789 const char me[] = "dump_done"; 8790 dns_zone_t *zone = arg; 8791 dns_db_t *db; 8792 dns_dbversion_t *version; 8793 isc_boolean_t again = ISC_FALSE; 8794 isc_boolean_t compact = ISC_FALSE; 8795 isc_uint32_t serial; 8796 isc_result_t tresult; 8797 8798 REQUIRE(DNS_ZONE_VALID(zone)); 8799 8800 ENTER; 8801 8802 if (result == ISC_R_SUCCESS && zone->journal != NULL && 8803 zone->journalsize != -1) { 8804 8805 /* 8806 * We don't own these, zone->dctx must stay valid. 8807 */ 8808 db = dns_dumpctx_db(zone->dctx); 8809 version = dns_dumpctx_version(zone->dctx); 8810 8811 tresult = dns_db_getsoaserial(db, version, &serial); 8812 /* 8813 * If there is a secure version of this zone 8814 * use its serial if it is less than ours. 8815 */ 8816 if (tresult == ISC_R_SUCCESS && inline_raw(zone) && 8817 zone->secure->db != NULL) 8818 { 8819 isc_uint32_t sserial; 8820 isc_result_t mresult; 8821 8822 mresult = dns_db_getsoaserial(zone->secure->db, 8823 NULL, &sserial); 8824 if (mresult == ISC_R_SUCCESS && 8825 isc_serial_lt(sserial, serial)) 8826 serial = sserial; 8827 } 8828 /* 8829 * Note: we are task locked here so we can test 8830 * zone->xfr safely. 8831 */ 8832 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) { 8833 tresult = dns_journal_compact(zone->mctx, 8834 zone->journal, 8835 serial, 8836 zone->journalsize); 8837 switch (tresult) { 8838 case ISC_R_SUCCESS: 8839 case ISC_R_NOSPACE: 8840 case ISC_R_NOTFOUND: 8841 dns_zone_log(zone, ISC_LOG_DEBUG(3), 8842 "dns_journal_compact: %s", 8843 dns_result_totext(tresult)); 8844 break; 8845 default: 8846 dns_zone_log(zone, ISC_LOG_ERROR, 8847 "dns_journal_compact failed: %s", 8848 dns_result_totext(tresult)); 8849 break; 8850 } 8851 } else if (tresult == ISC_R_SUCCESS) { 8852 compact = ISC_TRUE; 8853 zone->compact_serial = serial; 8854 } 8855 } 8856 8857 LOCK_ZONE(zone); 8858 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 8859 if (compact) 8860 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 8861 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) { 8862 /* 8863 * Try again in a short while. 8864 */ 8865 zone_needdump(zone, DNS_DUMP_DELAY); 8866 } else if (result == ISC_R_SUCCESS && 8867 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 8868 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 8869 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 8870 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 8871 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 8872 isc_time_settoepoch(&zone->dumptime); 8873 again = ISC_TRUE; 8874 } else if (result == ISC_R_SUCCESS) 8875 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 8876 8877 if (zone->dctx != NULL) 8878 dns_dumpctx_detach(&zone->dctx); 8879 zonemgr_putio(&zone->writeio); 8880 UNLOCK_ZONE(zone); 8881 if (again) 8882 (void)zone_dump(zone, ISC_FALSE); 8883 dns_zone_idetach(&zone); 8884} 8885 8886static isc_result_t 8887zone_dump(dns_zone_t *zone, isc_boolean_t compact) { 8888 const char me[] = "zone_dump"; 8889 isc_result_t result; 8890 dns_dbversion_t *version = NULL; 8891 isc_boolean_t again; 8892 dns_db_t *db = NULL; 8893 char *masterfile = NULL; 8894 dns_masterformat_t masterformat = dns_masterformat_none; 8895 8896/* 8897 * 'compact' MUST only be set if we are task locked. 8898 */ 8899 8900 REQUIRE(DNS_ZONE_VALID(zone)); 8901 ENTER; 8902 8903 redo: 8904 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8905 if (zone->db != NULL) 8906 dns_db_attach(zone->db, &db); 8907 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8908 LOCK_ZONE(zone); 8909 if (zone->masterfile != NULL) { 8910 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile); 8911 masterformat = zone->masterformat; 8912 } 8913 UNLOCK_ZONE(zone); 8914 if (db == NULL) { 8915 result = DNS_R_NOTLOADED; 8916 goto fail; 8917 } 8918 if (masterfile == NULL) { 8919 result = DNS_R_NOMASTERFILE; 8920 goto fail; 8921 } 8922 8923 if (compact && zone->type != dns_zone_stub) { 8924 dns_zone_t *dummy = NULL; 8925 LOCK_ZONE(zone); 8926 zone_iattach(zone, &dummy); 8927 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task, 8928 zone_gotwritehandle, zone, 8929 &zone->writeio); 8930 if (result != ISC_R_SUCCESS) 8931 zone_idetach(&dummy); 8932 else 8933 result = DNS_R_CONTINUE; 8934 UNLOCK_ZONE(zone); 8935 } else { 8936 dns_masterrawheader_t rawdata; 8937 dns_db_currentversion(db, &version); 8938 dns_master_initrawheader(&rawdata); 8939 if (inline_secure(zone)) 8940 get_raw_serial(zone->raw, &rawdata); 8941 result = dns_master_dump3(zone->mctx, db, version, 8942 &dns_master_style_default, 8943 masterfile, masterformat, 8944 &rawdata); 8945 dns_db_closeversion(db, &version, ISC_FALSE); 8946 } 8947 fail: 8948 if (db != NULL) 8949 dns_db_detach(&db); 8950 if (masterfile != NULL) 8951 isc_mem_free(zone->mctx, masterfile); 8952 masterfile = NULL; 8953 8954 if (result == DNS_R_CONTINUE) 8955 return (ISC_R_SUCCESS); /* XXXMPA */ 8956 8957 again = ISC_FALSE; 8958 LOCK_ZONE(zone); 8959 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 8960 if (result != ISC_R_SUCCESS) { 8961 /* 8962 * Try again in a short while. 8963 */ 8964 zone_needdump(zone, DNS_DUMP_DELAY); 8965 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 8966 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 8967 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 8968 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 8969 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 8970 isc_time_settoepoch(&zone->dumptime); 8971 again = ISC_TRUE; 8972 } else 8973 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 8974 UNLOCK_ZONE(zone); 8975 if (again) 8976 goto redo; 8977 8978 return (result); 8979} 8980 8981static isc_result_t 8982dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style, 8983 dns_masterformat_t format, const isc_uint32_t rawversion) 8984{ 8985 isc_result_t result; 8986 dns_dbversion_t *version = NULL; 8987 dns_db_t *db = NULL; 8988 dns_masterrawheader_t rawdata; 8989 8990 REQUIRE(DNS_ZONE_VALID(zone)); 8991 8992 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8993 if (zone->db != NULL) 8994 dns_db_attach(zone->db, &db); 8995 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8996 if (db == NULL) 8997 return (DNS_R_NOTLOADED); 8998 8999 dns_db_currentversion(db, &version); 9000 dns_master_initrawheader(&rawdata); 9001 if (rawversion == 0) 9002 rawdata.flags |= DNS_MASTERRAW_COMPAT; 9003 else if (inline_secure(zone)) 9004 get_raw_serial(zone->raw, &rawdata); 9005 else if (zone->sourceserialset) { 9006 rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET; 9007 rawdata.sourceserial = zone->sourceserial; 9008 } 9009 result = dns_master_dumptostream3(zone->mctx, db, version, style, 9010 format, &rawdata, fd); 9011 dns_db_closeversion(db, &version, ISC_FALSE); 9012 dns_db_detach(&db); 9013 return (result); 9014} 9015 9016isc_result_t 9017dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, 9018 const dns_master_style_t *style, 9019 const isc_uint32_t rawversion) 9020{ 9021 return (dumptostream(zone, fd, style, format, rawversion)); 9022} 9023 9024isc_result_t 9025dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, 9026 const dns_master_style_t *style) { 9027 return (dumptostream(zone, fd, style, format, DNS_RAWFORMAT_VERSION)); 9028} 9029 9030isc_result_t 9031dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) { 9032 return (dumptostream(zone, fd, &dns_master_style_default, 9033 dns_masterformat_text, 0)); 9034} 9035 9036isc_result_t 9037dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) { 9038 return (dumptostream(zone, fd, &dns_master_style_full, 9039 dns_masterformat_text, 0)); 9040} 9041 9042void 9043dns_zone_unload(dns_zone_t *zone) { 9044 REQUIRE(DNS_ZONE_VALID(zone)); 9045 9046 LOCK_ZONE(zone); 9047 zone_unload(zone); 9048 UNLOCK_ZONE(zone); 9049} 9050 9051static void 9052notify_cancel(dns_zone_t *zone) { 9053 dns_notify_t *notify; 9054 9055 /* 9056 * 'zone' locked by caller. 9057 */ 9058 9059 REQUIRE(LOCKED_ZONE(zone)); 9060 9061 for (notify = ISC_LIST_HEAD(zone->notifies); 9062 notify != NULL; 9063 notify = ISC_LIST_NEXT(notify, link)) { 9064 if (notify->find != NULL) 9065 dns_adb_cancelfind(notify->find); 9066 if (notify->request != NULL) 9067 dns_request_cancel(notify->request); 9068 } 9069} 9070 9071static void 9072forward_cancel(dns_zone_t *zone) { 9073 dns_forward_t *forward; 9074 9075 /* 9076 * 'zone' locked by caller. 9077 */ 9078 9079 REQUIRE(LOCKED_ZONE(zone)); 9080 9081 for (forward = ISC_LIST_HEAD(zone->forwards); 9082 forward != NULL; 9083 forward = ISC_LIST_NEXT(forward, link)) { 9084 if (forward->request != NULL) 9085 dns_request_cancel(forward->request); 9086 } 9087} 9088 9089static void 9090zone_unload(dns_zone_t *zone) { 9091 9092 /* 9093 * 'zone' locked by caller. 9094 */ 9095 9096 REQUIRE(LOCKED_ZONE(zone)); 9097 9098 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 9099 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 9100 if (zone->writeio != NULL) 9101 zonemgr_cancelio(zone->writeio); 9102 9103 if (zone->dctx != NULL) 9104 dns_dumpctx_cancel(zone->dctx); 9105 } 9106 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 9107 zone_detachdb(zone); 9108 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 9109 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED); 9110 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 9111} 9112 9113void 9114dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) { 9115 REQUIRE(DNS_ZONE_VALID(zone)); 9116 REQUIRE(val > 0); 9117 9118 zone->minrefresh = val; 9119} 9120 9121void 9122dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) { 9123 REQUIRE(DNS_ZONE_VALID(zone)); 9124 REQUIRE(val > 0); 9125 9126 zone->maxrefresh = val; 9127} 9128 9129void 9130dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) { 9131 REQUIRE(DNS_ZONE_VALID(zone)); 9132 REQUIRE(val > 0); 9133 9134 zone->minretry = val; 9135} 9136 9137void 9138dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) { 9139 REQUIRE(DNS_ZONE_VALID(zone)); 9140 REQUIRE(val > 0); 9141 9142 zone->maxretry = val; 9143} 9144 9145static isc_boolean_t 9146notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) { 9147 dns_notify_t *notify; 9148 9149 for (notify = ISC_LIST_HEAD(zone->notifies); 9150 notify != NULL; 9151 notify = ISC_LIST_NEXT(notify, link)) { 9152 if (notify->request != NULL) 9153 continue; 9154 if (name != NULL && dns_name_dynamic(¬ify->ns) && 9155 dns_name_equal(name, ¬ify->ns)) 9156 return (ISC_TRUE); 9157 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst)) 9158 return (ISC_TRUE); 9159 } 9160 return (ISC_FALSE); 9161} 9162 9163static isc_boolean_t 9164notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) { 9165 dns_tsigkey_t *key = NULL; 9166 isc_sockaddr_t src; 9167 isc_sockaddr_t any; 9168 isc_boolean_t isself; 9169 isc_netaddr_t dstaddr; 9170 isc_result_t result; 9171 9172 if (zone->view == NULL || zone->isself == NULL) 9173 return (ISC_FALSE); 9174 9175 switch (isc_sockaddr_pf(dst)) { 9176 case PF_INET: 9177 src = zone->notifysrc4; 9178 isc_sockaddr_any(&any); 9179 break; 9180 case PF_INET6: 9181 src = zone->notifysrc6; 9182 isc_sockaddr_any6(&any); 9183 break; 9184 default: 9185 return (ISC_FALSE); 9186 } 9187 9188 /* 9189 * When sending from any the kernel will assign a source address 9190 * that matches the destination address. 9191 */ 9192 if (isc_sockaddr_eqaddr(&any, &src)) 9193 src = *dst; 9194 9195 isc_netaddr_fromsockaddr(&dstaddr, dst); 9196 result = dns_view_getpeertsig(zone->view, &dstaddr, &key); 9197 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) 9198 return (ISC_FALSE); 9199 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass, 9200 zone->isselfarg); 9201 if (key != NULL) 9202 dns_tsigkey_detach(&key); 9203 return (isself); 9204} 9205 9206static void 9207notify_destroy(dns_notify_t *notify, isc_boolean_t locked) { 9208 isc_mem_t *mctx; 9209 9210 /* 9211 * Caller holds zone lock. 9212 */ 9213 REQUIRE(DNS_NOTIFY_VALID(notify)); 9214 9215 if (notify->zone != NULL) { 9216 if (!locked) 9217 LOCK_ZONE(notify->zone); 9218 REQUIRE(LOCKED_ZONE(notify->zone)); 9219 if (ISC_LINK_LINKED(notify, link)) 9220 ISC_LIST_UNLINK(notify->zone->notifies, notify, link); 9221 if (!locked) 9222 UNLOCK_ZONE(notify->zone); 9223 if (locked) 9224 zone_idetach(¬ify->zone); 9225 else 9226 dns_zone_idetach(¬ify->zone); 9227 } 9228 if (notify->find != NULL) 9229 dns_adb_destroyfind(¬ify->find); 9230 if (notify->request != NULL) 9231 dns_request_destroy(¬ify->request); 9232 if (dns_name_dynamic(¬ify->ns)) 9233 dns_name_free(¬ify->ns, notify->mctx); 9234 if (notify->key != NULL) 9235 dns_tsigkey_detach(¬ify->key); 9236 mctx = notify->mctx; 9237 isc_mem_put(notify->mctx, notify, sizeof(*notify)); 9238 isc_mem_detach(&mctx); 9239} 9240 9241static isc_result_t 9242notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) { 9243 dns_notify_t *notify; 9244 9245 REQUIRE(notifyp != NULL && *notifyp == NULL); 9246 9247 notify = isc_mem_get(mctx, sizeof(*notify)); 9248 if (notify == NULL) 9249 return (ISC_R_NOMEMORY); 9250 9251 notify->mctx = NULL; 9252 isc_mem_attach(mctx, ¬ify->mctx); 9253 notify->flags = flags; 9254 notify->zone = NULL; 9255 notify->find = NULL; 9256 notify->request = NULL; 9257 notify->key = NULL; 9258 isc_sockaddr_any(¬ify->dst); 9259 dns_name_init(¬ify->ns, NULL); 9260 ISC_LINK_INIT(notify, link); 9261 notify->magic = NOTIFY_MAGIC; 9262 *notifyp = notify; 9263 return (ISC_R_SUCCESS); 9264} 9265 9266/* 9267 * XXXAG should check for DNS_ZONEFLG_EXITING 9268 */ 9269static void 9270process_adb_event(isc_task_t *task, isc_event_t *ev) { 9271 dns_notify_t *notify; 9272 isc_eventtype_t result; 9273 9274 UNUSED(task); 9275 9276 notify = ev->ev_arg; 9277 REQUIRE(DNS_NOTIFY_VALID(notify)); 9278 INSIST(task == notify->zone->task); 9279 result = ev->ev_type; 9280 isc_event_free(&ev); 9281 if (result == DNS_EVENT_ADBMOREADDRESSES) { 9282 dns_adb_destroyfind(¬ify->find); 9283 notify_find_address(notify); 9284 return; 9285 } 9286 if (result == DNS_EVENT_ADBNOMOREADDRESSES) { 9287 LOCK_ZONE(notify->zone); 9288 notify_send(notify); 9289 UNLOCK_ZONE(notify->zone); 9290 } 9291 notify_destroy(notify, ISC_FALSE); 9292} 9293 9294static void 9295notify_find_address(dns_notify_t *notify) { 9296 isc_result_t result; 9297 unsigned int options; 9298 9299 REQUIRE(DNS_NOTIFY_VALID(notify)); 9300 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET | 9301 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME; 9302 9303 if (notify->zone->view->adb == NULL) 9304 goto destroy; 9305 9306 result = dns_adb_createfind(notify->zone->view->adb, 9307 notify->zone->task, 9308 process_adb_event, notify, 9309 ¬ify->ns, dns_rootname, 0, 9310 options, 0, NULL, 9311 notify->zone->view->dstport, 9312 ¬ify->find); 9313 9314 /* Something failed? */ 9315 if (result != ISC_R_SUCCESS) 9316 goto destroy; 9317 9318 /* More addresses pending? */ 9319 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) 9320 return; 9321 9322 /* We have as many addresses as we can get. */ 9323 LOCK_ZONE(notify->zone); 9324 notify_send(notify); 9325 UNLOCK_ZONE(notify->zone); 9326 9327 destroy: 9328 notify_destroy(notify, ISC_FALSE); 9329} 9330 9331 9332static isc_result_t 9333notify_send_queue(dns_notify_t *notify) { 9334 isc_event_t *e; 9335 isc_result_t result; 9336 9337 e = isc_event_allocate(notify->mctx, NULL, 9338 DNS_EVENT_NOTIFYSENDTOADDR, 9339 notify_send_toaddr, 9340 notify, sizeof(isc_event_t)); 9341 if (e == NULL) 9342 return (ISC_R_NOMEMORY); 9343 e->ev_arg = notify; 9344 e->ev_sender = NULL; 9345 result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl, 9346 notify->zone->task, &e); 9347 if (result != ISC_R_SUCCESS) 9348 isc_event_free(&e); 9349 return (result); 9350} 9351 9352static void 9353notify_send_toaddr(isc_task_t *task, isc_event_t *event) { 9354 dns_notify_t *notify; 9355 isc_result_t result; 9356 dns_message_t *message = NULL; 9357 isc_netaddr_t dstip; 9358 dns_tsigkey_t *key = NULL; 9359 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 9360 isc_sockaddr_t src; 9361 int timeout; 9362 isc_boolean_t have_notifysource = ISC_FALSE; 9363 9364 notify = event->ev_arg; 9365 REQUIRE(DNS_NOTIFY_VALID(notify)); 9366 9367 UNUSED(task); 9368 9369 LOCK_ZONE(notify->zone); 9370 9371 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) { 9372 result = ISC_R_CANCELED; 9373 goto cleanup; 9374 } 9375 9376 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 || 9377 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) || 9378 notify->zone->view->requestmgr == NULL || 9379 notify->zone->db == NULL) { 9380 result = ISC_R_CANCELED; 9381 goto cleanup; 9382 } 9383 9384 /* 9385 * The raw IPv4 address should also exist. Don't send to the 9386 * mapped form. 9387 */ 9388 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 && 9389 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) { 9390 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 9391 notify_log(notify->zone, ISC_LOG_DEBUG(3), 9392 "notify: ignoring IPv6 mapped IPV4 address: %s", 9393 addrbuf); 9394 result = ISC_R_CANCELED; 9395 goto cleanup; 9396 } 9397 9398 result = notify_createmessage(notify->zone, notify->flags, &message); 9399 if (result != ISC_R_SUCCESS) 9400 goto cleanup; 9401 9402 if (notify->key != NULL) { 9403 /* Transfer ownership of key */ 9404 key = notify->key; 9405 notify->key = NULL; 9406 } else { 9407 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst); 9408 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 9409 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key); 9410 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 9411 notify_log(notify->zone, ISC_LOG_ERROR, 9412 "NOTIFY to %s not sent. " 9413 "Peer TSIG key lookup failure.", addrbuf); 9414 goto cleanup_message; 9415 } 9416 } 9417 9418 /* XXX: should we log the tsig key too? */ 9419 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s", 9420 addrbuf); 9421 if (notify->zone->view->peers != NULL) { 9422 dns_peer_t *peer = NULL; 9423 result = dns_peerlist_peerbyaddr(notify->zone->view->peers, 9424 &dstip, &peer); 9425 if (result == ISC_R_SUCCESS) { 9426 result = dns_peer_getnotifysource(peer, &src); 9427 if (result == ISC_R_SUCCESS) 9428 have_notifysource = ISC_TRUE; 9429 } 9430 } 9431 switch (isc_sockaddr_pf(¬ify->dst)) { 9432 case PF_INET: 9433 if (!have_notifysource) 9434 src = notify->zone->notifysrc4; 9435 break; 9436 case PF_INET6: 9437 if (!have_notifysource) 9438 src = notify->zone->notifysrc6; 9439 break; 9440 default: 9441 result = ISC_R_NOTIMPLEMENTED; 9442 goto cleanup_key; 9443 } 9444 timeout = 15; 9445 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) 9446 timeout = 30; 9447 result = dns_request_createvia2(notify->zone->view->requestmgr, 9448 message, &src, ¬ify->dst, 0, key, 9449 timeout * 3, timeout, 9450 notify->zone->task, notify_done, 9451 notify, ¬ify->request); 9452 if (result == ISC_R_SUCCESS) { 9453 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) { 9454 inc_stats(notify->zone, 9455 dns_zonestatscounter_notifyoutv4); 9456 } else { 9457 inc_stats(notify->zone, 9458 dns_zonestatscounter_notifyoutv6); 9459 } 9460 } 9461 9462 cleanup_key: 9463 if (key != NULL) 9464 dns_tsigkey_detach(&key); 9465 cleanup_message: 9466 dns_message_destroy(&message); 9467 cleanup: 9468 UNLOCK_ZONE(notify->zone); 9469 if (result != ISC_R_SUCCESS) 9470 notify_destroy(notify, ISC_FALSE); 9471 isc_event_free(&event); 9472} 9473 9474static void 9475notify_send(dns_notify_t *notify) { 9476 dns_adbaddrinfo_t *ai; 9477 isc_sockaddr_t dst; 9478 isc_result_t result; 9479 dns_notify_t *new = NULL; 9480 9481 /* 9482 * Zone lock held by caller. 9483 */ 9484 REQUIRE(DNS_NOTIFY_VALID(notify)); 9485 REQUIRE(LOCKED_ZONE(notify->zone)); 9486 9487 for (ai = ISC_LIST_HEAD(notify->find->list); 9488 ai != NULL; 9489 ai = ISC_LIST_NEXT(ai, publink)) { 9490 dst = ai->sockaddr; 9491 if (notify_isqueued(notify->zone, NULL, &dst)) 9492 continue; 9493 if (notify_isself(notify->zone, &dst)) 9494 continue; 9495 new = NULL; 9496 result = notify_create(notify->mctx, 9497 (notify->flags & DNS_NOTIFY_NOSOA), 9498 &new); 9499 if (result != ISC_R_SUCCESS) 9500 goto cleanup; 9501 zone_iattach(notify->zone, &new->zone); 9502 ISC_LIST_APPEND(new->zone->notifies, new, link); 9503 new->dst = dst; 9504 result = notify_send_queue(new); 9505 if (result != ISC_R_SUCCESS) 9506 goto cleanup; 9507 new = NULL; 9508 } 9509 9510 cleanup: 9511 if (new != NULL) 9512 notify_destroy(new, ISC_TRUE); 9513} 9514 9515void 9516dns_zone_notify(dns_zone_t *zone) { 9517 isc_time_t now; 9518 9519 REQUIRE(DNS_ZONE_VALID(zone)); 9520 9521 LOCK_ZONE(zone); 9522 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 9523 9524 TIME_NOW(&now); 9525 zone_settimer(zone, &now); 9526 UNLOCK_ZONE(zone); 9527} 9528 9529static void 9530zone_notify(dns_zone_t *zone, isc_time_t *now) { 9531 dns_dbnode_t *node = NULL; 9532 dns_db_t *zonedb = NULL; 9533 dns_dbversion_t *version = NULL; 9534 dns_name_t *origin = NULL; 9535 dns_name_t master; 9536 dns_rdata_ns_t ns; 9537 dns_rdata_soa_t soa; 9538 isc_uint32_t serial; 9539 dns_rdata_t rdata = DNS_RDATA_INIT; 9540 dns_rdataset_t nsrdset; 9541 dns_rdataset_t soardset; 9542 isc_result_t result; 9543 dns_notify_t *notify = NULL; 9544 unsigned int i; 9545 isc_sockaddr_t dst; 9546 isc_boolean_t isqueued; 9547 dns_notifytype_t notifytype; 9548 unsigned int flags = 0; 9549 isc_boolean_t loggednotify = ISC_FALSE; 9550 9551 REQUIRE(DNS_ZONE_VALID(zone)); 9552 9553 LOCK_ZONE(zone); 9554 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 9555 notifytype = zone->notifytype; 9556 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime); 9557 UNLOCK_ZONE(zone); 9558 9559 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 9560 return; 9561 9562 if (notifytype == dns_notifytype_no) 9563 return; 9564 9565 if (notifytype == dns_notifytype_masteronly && 9566 zone->type != dns_zone_master) 9567 return; 9568 9569 origin = &zone->origin; 9570 9571 /* 9572 * If the zone is dialup we are done as we don't want to send 9573 * the current soa so as to force a refresh query. 9574 */ 9575 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) 9576 flags |= DNS_NOTIFY_NOSOA; 9577 9578 /* 9579 * Get SOA RRset. 9580 */ 9581 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9582 if (zone->db != NULL) 9583 dns_db_attach(zone->db, &zonedb); 9584 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9585 if (zonedb == NULL) 9586 return; 9587 dns_db_currentversion(zonedb, &version); 9588 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node); 9589 if (result != ISC_R_SUCCESS) 9590 goto cleanup1; 9591 9592 dns_rdataset_init(&soardset); 9593 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, 9594 dns_rdatatype_none, 0, &soardset, NULL); 9595 if (result != ISC_R_SUCCESS) 9596 goto cleanup2; 9597 9598 /* 9599 * Find serial and master server's name. 9600 */ 9601 dns_name_init(&master, NULL); 9602 result = dns_rdataset_first(&soardset); 9603 if (result != ISC_R_SUCCESS) 9604 goto cleanup3; 9605 dns_rdataset_current(&soardset, &rdata); 9606 result = dns_rdata_tostruct(&rdata, &soa, NULL); 9607 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9608 dns_rdata_reset(&rdata); 9609 result = dns_name_dup(&soa.origin, zone->mctx, &master); 9610 serial = soa.serial; 9611 dns_rdataset_disassociate(&soardset); 9612 if (result != ISC_R_SUCCESS) 9613 goto cleanup3; 9614 9615 /* 9616 * Enqueue notify requests for 'also-notify' servers. 9617 */ 9618 LOCK_ZONE(zone); 9619 for (i = 0; i < zone->notifycnt; i++) { 9620 dns_tsigkey_t *key = NULL; 9621 9622 dst = zone->notify[i]; 9623 if (notify_isqueued(zone, NULL, &dst)) 9624 continue; 9625 9626 result = notify_create(zone->mctx, flags, ¬ify); 9627 if (result != ISC_R_SUCCESS) 9628 continue; 9629 9630 zone_iattach(zone, ¬ify->zone); 9631 notify->dst = dst; 9632 9633 if ((zone->notifykeynames != NULL) && 9634 (zone->notifykeynames[i] != NULL)) { 9635 dns_view_t *view = dns_zone_getview(zone); 9636 dns_name_t *keyname = zone->notifykeynames[i]; 9637 result = dns_view_gettsig(view, keyname, &key); 9638 if (result == ISC_R_SUCCESS) { 9639 notify->key = key; 9640 key = NULL; 9641 } 9642 } 9643 9644 ISC_LIST_APPEND(zone->notifies, notify, link); 9645 result = notify_send_queue(notify); 9646 if (result != ISC_R_SUCCESS) 9647 notify_destroy(notify, ISC_TRUE); 9648 if (!loggednotify) { 9649 notify_log(zone, ISC_LOG_INFO, 9650 "sending notifies (serial %u)", 9651 serial); 9652 loggednotify = ISC_TRUE; 9653 } 9654 notify = NULL; 9655 } 9656 UNLOCK_ZONE(zone); 9657 9658 if (notifytype == dns_notifytype_explicit) 9659 goto cleanup3; 9660 9661 /* 9662 * Process NS RRset to generate notifies. 9663 */ 9664 9665 dns_rdataset_init(&nsrdset); 9666 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns, 9667 dns_rdatatype_none, 0, &nsrdset, NULL); 9668 if (result != ISC_R_SUCCESS) 9669 goto cleanup3; 9670 9671 result = dns_rdataset_first(&nsrdset); 9672 while (result == ISC_R_SUCCESS) { 9673 dns_rdataset_current(&nsrdset, &rdata); 9674 result = dns_rdata_tostruct(&rdata, &ns, NULL); 9675 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9676 dns_rdata_reset(&rdata); 9677 /* 9678 * Don't notify the master server unless explicitly 9679 * configured to do so. 9680 */ 9681 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) && 9682 dns_name_compare(&master, &ns.name) == 0) { 9683 result = dns_rdataset_next(&nsrdset); 9684 continue; 9685 } 9686 9687 if (!loggednotify) { 9688 notify_log(zone, ISC_LOG_INFO, 9689 "sending notifies (serial %u)", 9690 serial); 9691 loggednotify = ISC_TRUE; 9692 } 9693 9694 LOCK_ZONE(zone); 9695 isqueued = notify_isqueued(zone, &ns.name, NULL); 9696 UNLOCK_ZONE(zone); 9697 if (isqueued) { 9698 result = dns_rdataset_next(&nsrdset); 9699 continue; 9700 } 9701 result = notify_create(zone->mctx, flags, ¬ify); 9702 if (result != ISC_R_SUCCESS) 9703 continue; 9704 dns_zone_iattach(zone, ¬ify->zone); 9705 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns); 9706 if (result != ISC_R_SUCCESS) { 9707 LOCK_ZONE(zone); 9708 notify_destroy(notify, ISC_TRUE); 9709 UNLOCK_ZONE(zone); 9710 continue; 9711 } 9712 LOCK_ZONE(zone); 9713 ISC_LIST_APPEND(zone->notifies, notify, link); 9714 UNLOCK_ZONE(zone); 9715 notify_find_address(notify); 9716 notify = NULL; 9717 result = dns_rdataset_next(&nsrdset); 9718 } 9719 dns_rdataset_disassociate(&nsrdset); 9720 9721 cleanup3: 9722 if (dns_name_dynamic(&master)) 9723 dns_name_free(&master, zone->mctx); 9724 cleanup2: 9725 dns_db_detachnode(zonedb, &node); 9726 cleanup1: 9727 dns_db_closeversion(zonedb, &version, ISC_FALSE); 9728 dns_db_detach(&zonedb); 9729} 9730 9731/*** 9732 *** Private 9733 ***/ 9734 9735static inline isc_result_t 9736save_nsrrset(dns_message_t *message, dns_name_t *name, 9737 dns_db_t *db, dns_dbversion_t *version) 9738{ 9739 dns_rdataset_t *nsrdataset = NULL; 9740 dns_rdataset_t *rdataset = NULL; 9741 dns_dbnode_t *node = NULL; 9742 dns_rdata_ns_t ns; 9743 isc_result_t result; 9744 dns_rdata_t rdata = DNS_RDATA_INIT; 9745 9746 /* 9747 * Extract NS RRset from message. 9748 */ 9749 result = dns_message_findname(message, DNS_SECTION_ANSWER, name, 9750 dns_rdatatype_ns, dns_rdatatype_none, 9751 NULL, &nsrdataset); 9752 if (result != ISC_R_SUCCESS) 9753 goto fail; 9754 9755 /* 9756 * Add NS rdataset. 9757 */ 9758 result = dns_db_findnode(db, name, ISC_TRUE, &node); 9759 if (result != ISC_R_SUCCESS) 9760 goto fail; 9761 result = dns_db_addrdataset(db, node, version, 0, 9762 nsrdataset, 0, NULL); 9763 dns_db_detachnode(db, &node); 9764 if (result != ISC_R_SUCCESS) 9765 goto fail; 9766 /* 9767 * Add glue rdatasets. 9768 */ 9769 for (result = dns_rdataset_first(nsrdataset); 9770 result == ISC_R_SUCCESS; 9771 result = dns_rdataset_next(nsrdataset)) { 9772 dns_rdataset_current(nsrdataset, &rdata); 9773 result = dns_rdata_tostruct(&rdata, &ns, NULL); 9774 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9775 dns_rdata_reset(&rdata); 9776 if (!dns_name_issubdomain(&ns.name, name)) 9777 continue; 9778 rdataset = NULL; 9779 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL, 9780 &ns.name, dns_rdatatype_aaaa, 9781 dns_rdatatype_none, NULL, 9782 &rdataset); 9783 if (result == ISC_R_SUCCESS) { 9784 result = dns_db_findnode(db, &ns.name, 9785 ISC_TRUE, &node); 9786 if (result != ISC_R_SUCCESS) 9787 goto fail; 9788 result = dns_db_addrdataset(db, node, version, 0, 9789 rdataset, 0, NULL); 9790 dns_db_detachnode(db, &node); 9791 if (result != ISC_R_SUCCESS) 9792 goto fail; 9793 } 9794 rdataset = NULL; 9795 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL, 9796 &ns.name, dns_rdatatype_a, 9797 dns_rdatatype_none, NULL, 9798 &rdataset); 9799 if (result == ISC_R_SUCCESS) { 9800 result = dns_db_findnode(db, &ns.name, 9801 ISC_TRUE, &node); 9802 if (result != ISC_R_SUCCESS) 9803 goto fail; 9804 result = dns_db_addrdataset(db, node, version, 0, 9805 rdataset, 0, NULL); 9806 dns_db_detachnode(db, &node); 9807 if (result != ISC_R_SUCCESS) 9808 goto fail; 9809 } 9810 } 9811 if (result != ISC_R_NOMORE) 9812 goto fail; 9813 9814 return (ISC_R_SUCCESS); 9815 9816fail: 9817 return (result); 9818} 9819 9820static void 9821stub_callback(isc_task_t *task, isc_event_t *event) { 9822 const char me[] = "stub_callback"; 9823 dns_requestevent_t *revent = (dns_requestevent_t *)event; 9824 dns_stub_t *stub = NULL; 9825 dns_message_t *msg = NULL; 9826 dns_zone_t *zone = NULL; 9827 char master[ISC_SOCKADDR_FORMATSIZE]; 9828 char source[ISC_SOCKADDR_FORMATSIZE]; 9829 isc_uint32_t nscnt, cnamecnt, refresh, retry, expire; 9830 isc_result_t result; 9831 isc_time_t now; 9832 isc_boolean_t exiting = ISC_FALSE; 9833 isc_interval_t i; 9834 unsigned int j; 9835 9836 stub = revent->ev_arg; 9837 INSIST(DNS_STUB_VALID(stub)); 9838 9839 UNUSED(task); 9840 9841 zone = stub->zone; 9842 9843 ENTER; 9844 9845 TIME_NOW(&now); 9846 9847 LOCK_ZONE(zone); 9848 9849 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 9850 zone_debuglog(zone, me, 1, "exiting"); 9851 exiting = ISC_TRUE; 9852 goto next_master; 9853 } 9854 9855 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 9856 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 9857 9858 if (revent->result != ISC_R_SUCCESS) { 9859 if (revent->result == ISC_R_TIMEDOUT && 9860 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 9861 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 9862 dns_zone_log(zone, ISC_LOG_DEBUG(1), 9863 "refreshing stub: timeout retrying " 9864 " without EDNS master %s (source %s)", 9865 master, source); 9866 goto same_master; 9867 } 9868 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr, 9869 &zone->sourceaddr, &now); 9870 dns_zone_log(zone, ISC_LOG_INFO, 9871 "could not refresh stub from master %s" 9872 " (source %s): %s", master, source, 9873 dns_result_totext(revent->result)); 9874 goto next_master; 9875 } 9876 9877 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 9878 if (result != ISC_R_SUCCESS) 9879 goto next_master; 9880 9881 result = dns_request_getresponse(revent->request, msg, 0); 9882 if (result != ISC_R_SUCCESS) 9883 goto next_master; 9884 9885 /* 9886 * Unexpected rcode. 9887 */ 9888 if (msg->rcode != dns_rcode_noerror) { 9889 char rcode[128]; 9890 isc_buffer_t rb; 9891 9892 isc_buffer_init(&rb, rcode, sizeof(rcode)); 9893 (void)dns_rcode_totext(msg->rcode, &rb); 9894 9895 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 9896 (msg->rcode == dns_rcode_servfail || 9897 msg->rcode == dns_rcode_notimp || 9898 msg->rcode == dns_rcode_formerr)) { 9899 dns_zone_log(zone, ISC_LOG_DEBUG(1), 9900 "refreshing stub: rcode (%.*s) retrying " 9901 "without EDNS master %s (source %s)", 9902 (int)rb.used, rcode, master, source); 9903 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 9904 goto same_master; 9905 } 9906 9907 dns_zone_log(zone, ISC_LOG_INFO, 9908 "refreshing stub: " 9909 "unexpected rcode (%.*s) from %s (source %s)", 9910 (int)rb.used, rcode, master, source); 9911 goto next_master; 9912 } 9913 9914 /* 9915 * We need complete messages. 9916 */ 9917 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 9918 if (dns_request_usedtcp(revent->request)) { 9919 dns_zone_log(zone, ISC_LOG_INFO, 9920 "refreshing stub: truncated TCP " 9921 "response from master %s (source %s)", 9922 master, source); 9923 goto next_master; 9924 } 9925 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 9926 goto same_master; 9927 } 9928 9929 /* 9930 * If non-auth log and next master. 9931 */ 9932 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 9933 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " 9934 "non-authoritative answer from " 9935 "master %s (source %s)", master, source); 9936 goto next_master; 9937 } 9938 9939 /* 9940 * Sanity checks. 9941 */ 9942 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 9943 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns); 9944 9945 if (cnamecnt != 0) { 9946 dns_zone_log(zone, ISC_LOG_INFO, 9947 "refreshing stub: unexpected CNAME response " 9948 "from master %s (source %s)", master, source); 9949 goto next_master; 9950 } 9951 9952 if (nscnt == 0) { 9953 dns_zone_log(zone, ISC_LOG_INFO, 9954 "refreshing stub: no NS records in response " 9955 "from master %s (source %s)", master, source); 9956 goto next_master; 9957 } 9958 9959 /* 9960 * Save answer. 9961 */ 9962 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version); 9963 if (result != ISC_R_SUCCESS) { 9964 dns_zone_log(zone, ISC_LOG_INFO, 9965 "refreshing stub: unable to save NS records " 9966 "from master %s (source %s)", master, source); 9967 goto next_master; 9968 } 9969 9970 /* 9971 * Tidy up. 9972 */ 9973 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE); 9974 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 9975 if (zone->db == NULL) 9976 zone_attachdb(zone, stub->db); 9977 result = zone_get_from_db(zone, zone->db, NULL, NULL, NULL, &refresh, 9978 &retry, &expire, NULL, NULL); 9979 if (result == ISC_R_SUCCESS) { 9980 zone->refresh = RANGE(refresh, zone->minrefresh, 9981 zone->maxrefresh); 9982 zone->retry = RANGE(retry, zone->minretry, zone->maxretry); 9983 zone->expire = RANGE(expire, zone->refresh + zone->retry, 9984 DNS_MAX_EXPIRE); 9985 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 9986 } 9987 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 9988 dns_db_detach(&stub->db); 9989 9990 dns_message_destroy(&msg); 9991 isc_event_free(&event); 9992 dns_request_destroy(&zone->request); 9993 9994 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 9995 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 9996 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 9997 isc_interval_set(&i, zone->expire, 0); 9998 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); 9999 10000 if (zone->masterfile != NULL) 10001 zone_needdump(zone, 0); 10002 10003 zone_settimer(zone, &now); 10004 goto free_stub; 10005 10006 next_master: 10007 if (stub->version != NULL) 10008 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE); 10009 if (stub->db != NULL) 10010 dns_db_detach(&stub->db); 10011 if (msg != NULL) 10012 dns_message_destroy(&msg); 10013 isc_event_free(&event); 10014 dns_request_destroy(&zone->request); 10015 /* 10016 * Skip to next failed / untried master. 10017 */ 10018 do { 10019 zone->curmaster++; 10020 } while (zone->curmaster < zone->masterscnt && 10021 zone->mastersok[zone->curmaster]); 10022 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 10023 if (exiting || zone->curmaster >= zone->masterscnt) { 10024 isc_boolean_t done = ISC_TRUE; 10025 if (!exiting && 10026 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 10027 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 10028 /* 10029 * Did we get a good answer from all the masters? 10030 */ 10031 for (j = 0; j < zone->masterscnt; j++) 10032 if (zone->mastersok[j] == ISC_FALSE) { 10033 done = ISC_FALSE; 10034 break; 10035 } 10036 } else 10037 done = ISC_TRUE; 10038 if (!done) { 10039 zone->curmaster = 0; 10040 /* 10041 * Find the next failed master. 10042 */ 10043 while (zone->curmaster < zone->masterscnt && 10044 zone->mastersok[zone->curmaster]) 10045 zone->curmaster++; 10046 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 10047 } else { 10048 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 10049 10050 zone_settimer(zone, &now); 10051 goto free_stub; 10052 } 10053 } 10054 queue_soa_query(zone); 10055 goto free_stub; 10056 10057 same_master: 10058 if (msg != NULL) 10059 dns_message_destroy(&msg); 10060 isc_event_free(&event); 10061 dns_request_destroy(&zone->request); 10062 ns_query(zone, NULL, stub); 10063 UNLOCK_ZONE(zone); 10064 goto done; 10065 10066 free_stub: 10067 UNLOCK_ZONE(zone); 10068 stub->magic = 0; 10069 dns_zone_idetach(&stub->zone); 10070 INSIST(stub->db == NULL); 10071 INSIST(stub->version == NULL); 10072 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 10073 10074 done: 10075 INSIST(event == NULL); 10076 return; 10077} 10078 10079/* 10080 * An SOA query has finished (successfully or not). 10081 */ 10082static void 10083refresh_callback(isc_task_t *task, isc_event_t *event) { 10084 const char me[] = "refresh_callback"; 10085 dns_requestevent_t *revent = (dns_requestevent_t *)event; 10086 dns_zone_t *zone; 10087 dns_message_t *msg = NULL; 10088 isc_uint32_t soacnt, cnamecnt, soacount, nscount; 10089 isc_time_t now; 10090 char master[ISC_SOCKADDR_FORMATSIZE]; 10091 char source[ISC_SOCKADDR_FORMATSIZE]; 10092 dns_rdataset_t *rdataset = NULL; 10093 dns_rdata_t rdata = DNS_RDATA_INIT; 10094 dns_rdata_soa_t soa; 10095 isc_result_t result; 10096 isc_uint32_t serial, oldserial = 0; 10097 unsigned int j; 10098 isc_boolean_t do_queue_xfrin = ISC_FALSE; 10099 10100 zone = revent->ev_arg; 10101 INSIST(DNS_ZONE_VALID(zone)); 10102 10103 UNUSED(task); 10104 10105 ENTER; 10106 10107 TIME_NOW(&now); 10108 10109 LOCK_ZONE(zone); 10110 10111 /* 10112 * if timeout log and next master; 10113 */ 10114 10115 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 10116 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 10117 10118 if (revent->result != ISC_R_SUCCESS) { 10119 if (revent->result == ISC_R_TIMEDOUT && 10120 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 10121 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 10122 dns_zone_log(zone, ISC_LOG_DEBUG(1), 10123 "refresh: timeout retrying without EDNS " 10124 "master %s (source %s)", master, source); 10125 goto same_master; 10126 } 10127 if (revent->result == ISC_R_TIMEDOUT && 10128 !dns_request_usedtcp(revent->request)) { 10129 dns_zone_log(zone, ISC_LOG_INFO, 10130 "refresh: retry limit for " 10131 "master %s exceeded (source %s)", 10132 master, source); 10133 /* Try with slave with TCP. */ 10134 if ((zone->type == dns_zone_slave || 10135 zone->type == dns_zone_redirect) && 10136 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) { 10137 if (!dns_zonemgr_unreachable(zone->zmgr, 10138 &zone->masteraddr, 10139 &zone->sourceaddr, 10140 &now)) 10141 { 10142 DNS_ZONE_SETFLAG(zone, 10143 DNS_ZONEFLG_SOABEFOREAXFR); 10144 goto tcp_transfer; 10145 } 10146 dns_zone_log(zone, ISC_LOG_DEBUG(1), 10147 "refresh: skipped tcp fallback " 10148 "as master %s (source %s) is " 10149 "unreachable (cached)", 10150 master, source); 10151 } 10152 } else 10153 dns_zone_log(zone, ISC_LOG_INFO, 10154 "refresh: failure trying master " 10155 "%s (source %s): %s", master, source, 10156 dns_result_totext(revent->result)); 10157 goto next_master; 10158 } 10159 10160 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 10161 if (result != ISC_R_SUCCESS) 10162 goto next_master; 10163 result = dns_request_getresponse(revent->request, msg, 0); 10164 if (result != ISC_R_SUCCESS) { 10165 dns_zone_log(zone, ISC_LOG_INFO, 10166 "refresh: failure trying master " 10167 "%s (source %s): %s", master, source, 10168 dns_result_totext(result)); 10169 goto next_master; 10170 } 10171 10172 /* 10173 * Unexpected rcode. 10174 */ 10175 if (msg->rcode != dns_rcode_noerror) { 10176 char rcode[128]; 10177 isc_buffer_t rb; 10178 10179 isc_buffer_init(&rb, rcode, sizeof(rcode)); 10180 (void)dns_rcode_totext(msg->rcode, &rb); 10181 10182 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 10183 (msg->rcode == dns_rcode_servfail || 10184 msg->rcode == dns_rcode_notimp || 10185 msg->rcode == dns_rcode_formerr)) { 10186 dns_zone_log(zone, ISC_LOG_DEBUG(1), 10187 "refresh: rcode (%.*s) retrying without " 10188 "EDNS master %s (source %s)", 10189 (int)rb.used, rcode, master, source); 10190 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 10191 goto same_master; 10192 } 10193 dns_zone_log(zone, ISC_LOG_INFO, 10194 "refresh: unexpected rcode (%.*s) from " 10195 "master %s (source %s)", (int)rb.used, rcode, 10196 master, source); 10197 /* 10198 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't. 10199 */ 10200 if (msg->rcode == dns_rcode_refused && 10201 (zone->type == dns_zone_slave || 10202 zone->type == dns_zone_redirect)) 10203 goto tcp_transfer; 10204 goto next_master; 10205 } 10206 10207 /* 10208 * If truncated punt to zone transfer which will query again. 10209 */ 10210 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 10211 if (zone->type == dns_zone_slave || 10212 zone->type == dns_zone_redirect) { 10213 dns_zone_log(zone, ISC_LOG_INFO, 10214 "refresh: truncated UDP answer, " 10215 "initiating TCP zone xfer " 10216 "for master %s (source %s)", 10217 master, source); 10218 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 10219 goto tcp_transfer; 10220 } else { 10221 INSIST(zone->type == dns_zone_stub); 10222 if (dns_request_usedtcp(revent->request)) { 10223 dns_zone_log(zone, ISC_LOG_INFO, 10224 "refresh: truncated TCP response " 10225 "from master %s (source %s)", 10226 master, source); 10227 goto next_master; 10228 } 10229 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 10230 goto same_master; 10231 } 10232 } 10233 10234 /* 10235 * if non-auth log and next master; 10236 */ 10237 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 10238 dns_zone_log(zone, ISC_LOG_INFO, 10239 "refresh: non-authoritative answer from " 10240 "master %s (source %s)", master, source); 10241 goto next_master; 10242 } 10243 10244 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 10245 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa); 10246 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns); 10247 soacount = message_count(msg, DNS_SECTION_AUTHORITY, 10248 dns_rdatatype_soa); 10249 10250 /* 10251 * There should not be a CNAME record at top of zone. 10252 */ 10253 if (cnamecnt != 0) { 10254 dns_zone_log(zone, ISC_LOG_INFO, 10255 "refresh: CNAME at top of zone " 10256 "in master %s (source %s)", master, source); 10257 goto next_master; 10258 } 10259 10260 /* 10261 * if referral log and next master; 10262 */ 10263 if (soacnt == 0 && soacount == 0 && nscount != 0) { 10264 dns_zone_log(zone, ISC_LOG_INFO, 10265 "refresh: referral response " 10266 "from master %s (source %s)", master, source); 10267 goto next_master; 10268 } 10269 10270 /* 10271 * if nodata log and next master; 10272 */ 10273 if (soacnt == 0 && (nscount == 0 || soacount != 0)) { 10274 dns_zone_log(zone, ISC_LOG_INFO, 10275 "refresh: NODATA response " 10276 "from master %s (source %s)", master, source); 10277 goto next_master; 10278 } 10279 10280 /* 10281 * Only one soa at top of zone. 10282 */ 10283 if (soacnt != 1) { 10284 dns_zone_log(zone, ISC_LOG_INFO, 10285 "refresh: answer SOA count (%d) != 1 " 10286 "from master %s (source %s)", 10287 soacnt, master, source); 10288 goto next_master; 10289 } 10290 10291 /* 10292 * Extract serial 10293 */ 10294 rdataset = NULL; 10295 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin, 10296 dns_rdatatype_soa, dns_rdatatype_none, 10297 NULL, &rdataset); 10298 if (result != ISC_R_SUCCESS) { 10299 dns_zone_log(zone, ISC_LOG_INFO, 10300 "refresh: unable to get SOA record " 10301 "from master %s (source %s)", master, source); 10302 goto next_master; 10303 } 10304 10305 result = dns_rdataset_first(rdataset); 10306 if (result != ISC_R_SUCCESS) { 10307 dns_zone_log(zone, ISC_LOG_INFO, 10308 "refresh: dns_rdataset_first() failed"); 10309 goto next_master; 10310 } 10311 10312 dns_rdataset_current(rdataset, &rdata); 10313 result = dns_rdata_tostruct(&rdata, &soa, NULL); 10314 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10315 10316 serial = soa.serial; 10317 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 10318 result = zone_get_from_db(zone, zone->db, NULL, NULL, 10319 &oldserial, NULL, NULL, NULL, NULL, 10320 NULL); 10321 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10322 zone_debuglog(zone, me, 1, "serial: new %u, old %u", 10323 serial, oldserial); 10324 } else 10325 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded", 10326 serial); 10327 10328 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) || 10329 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) || 10330 isc_serial_gt(serial, oldserial)) { 10331 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, 10332 &zone->sourceaddr, &now)) 10333 { 10334 dns_zone_log(zone, ISC_LOG_INFO, 10335 "refresh: skipping %s as master %s " 10336 "(source %s) is unreachable (cached)", 10337 (zone->type == dns_zone_slave || 10338 zone->type == dns_zone_redirect) ? 10339 "zone transfer" : "NS query", 10340 master, source); 10341 goto next_master; 10342 } 10343 tcp_transfer: 10344 isc_event_free(&event); 10345 dns_request_destroy(&zone->request); 10346 if (zone->type == dns_zone_slave || 10347 zone->type == dns_zone_redirect) { 10348 do_queue_xfrin = ISC_TRUE; 10349 } else { 10350 INSIST(zone->type == dns_zone_stub); 10351 ns_query(zone, rdataset, NULL); 10352 } 10353 if (msg != NULL) 10354 dns_message_destroy(&msg); 10355 } else if (isc_serial_eq(soa.serial, oldserial)) { 10356 if (zone->masterfile != NULL) { 10357 result = ISC_R_FAILURE; 10358 if (zone->journal != NULL) 10359 result = isc_file_settime(zone->journal, &now); 10360 if (result == ISC_R_SUCCESS && 10361 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 10362 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 10363 result = isc_file_settime(zone->masterfile, 10364 &now); 10365 } else if (result != ISC_R_SUCCESS) 10366 result = isc_file_settime(zone->masterfile, 10367 &now); 10368 /* Someone removed the file from underneath us! */ 10369 if (result == ISC_R_FILENOTFOUND) { 10370 zone_needdump(zone, DNS_DUMP_DELAY); 10371 } else if (result != ISC_R_SUCCESS) 10372 dns_zone_log(zone, ISC_LOG_ERROR, 10373 "refresh: could not set file " 10374 "modification time of '%s': %s", 10375 zone->masterfile, 10376 dns_result_totext(result)); 10377 } 10378 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 10379 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); 10380 zone->mastersok[zone->curmaster] = ISC_TRUE; 10381 goto next_master; 10382 } else { 10383 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER)) 10384 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) " 10385 "received from master %s < ours (%u)", 10386 soa.serial, master, oldserial); 10387 else 10388 zone_debuglog(zone, me, 1, "ahead"); 10389 zone->mastersok[zone->curmaster] = ISC_TRUE; 10390 goto next_master; 10391 } 10392 if (msg != NULL) 10393 dns_message_destroy(&msg); 10394 goto detach; 10395 10396 next_master: 10397 if (msg != NULL) 10398 dns_message_destroy(&msg); 10399 isc_event_free(&event); 10400 dns_request_destroy(&zone->request); 10401 /* 10402 * Skip to next failed / untried master. 10403 */ 10404 do { 10405 zone->curmaster++; 10406 } while (zone->curmaster < zone->masterscnt && 10407 zone->mastersok[zone->curmaster]); 10408 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 10409 if (zone->curmaster >= zone->masterscnt) { 10410 isc_boolean_t done = ISC_TRUE; 10411 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 10412 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 10413 /* 10414 * Did we get a good answer from all the masters? 10415 */ 10416 for (j = 0; j < zone->masterscnt; j++) 10417 if (zone->mastersok[j] == ISC_FALSE) { 10418 done = ISC_FALSE; 10419 break; 10420 } 10421 } else 10422 done = ISC_TRUE; 10423 if (!done) { 10424 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 10425 zone->curmaster = 0; 10426 /* 10427 * Find the next failed master. 10428 */ 10429 while (zone->curmaster < zone->masterscnt && 10430 zone->mastersok[zone->curmaster]) 10431 zone->curmaster++; 10432 goto requeue; 10433 } 10434 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 10435 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 10436 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 10437 zone->refreshtime = now; 10438 } 10439 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 10440 zone_settimer(zone, &now); 10441 goto detach; 10442 } 10443 10444 requeue: 10445 queue_soa_query(zone); 10446 goto detach; 10447 10448 same_master: 10449 if (msg != NULL) 10450 dns_message_destroy(&msg); 10451 isc_event_free(&event); 10452 dns_request_destroy(&zone->request); 10453 queue_soa_query(zone); 10454 10455 detach: 10456 UNLOCK_ZONE(zone); 10457 if (do_queue_xfrin) 10458 queue_xfrin(zone); 10459 dns_zone_idetach(&zone); 10460 return; 10461} 10462 10463static void 10464queue_soa_query(dns_zone_t *zone) { 10465 const char me[] = "queue_soa_query"; 10466 isc_event_t *e; 10467 dns_zone_t *dummy = NULL; 10468 isc_result_t result; 10469 10470 ENTER; 10471 /* 10472 * Locked by caller 10473 */ 10474 REQUIRE(LOCKED_ZONE(zone)); 10475 10476 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 10477 cancel_refresh(zone); 10478 return; 10479 } 10480 10481 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE, 10482 soa_query, zone, sizeof(isc_event_t)); 10483 if (e == NULL) { 10484 cancel_refresh(zone); 10485 return; 10486 } 10487 10488 /* 10489 * Attach so that we won't clean up 10490 * until the event is delivered. 10491 */ 10492 zone_iattach(zone, &dummy); 10493 10494 e->ev_arg = zone; 10495 e->ev_sender = NULL; 10496 result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e); 10497 if (result != ISC_R_SUCCESS) { 10498 zone_idetach(&dummy); 10499 isc_event_free(&e); 10500 cancel_refresh(zone); 10501 } 10502} 10503 10504static inline isc_result_t 10505create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, 10506 dns_message_t **messagep) 10507{ 10508 dns_message_t *message = NULL; 10509 dns_name_t *qname = NULL; 10510 dns_rdataset_t *qrdataset = NULL; 10511 isc_result_t result; 10512 10513 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, 10514 &message); 10515 if (result != ISC_R_SUCCESS) 10516 goto cleanup; 10517 10518 message->opcode = dns_opcode_query; 10519 message->rdclass = zone->rdclass; 10520 10521 result = dns_message_gettempname(message, &qname); 10522 if (result != ISC_R_SUCCESS) 10523 goto cleanup; 10524 10525 result = dns_message_gettemprdataset(message, &qrdataset); 10526 if (result != ISC_R_SUCCESS) 10527 goto cleanup; 10528 10529 /* 10530 * Make question. 10531 */ 10532 dns_name_init(qname, NULL); 10533 dns_name_clone(&zone->origin, qname); 10534 dns_rdataset_init(qrdataset); 10535 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype); 10536 ISC_LIST_APPEND(qname->list, qrdataset, link); 10537 dns_message_addname(message, qname, DNS_SECTION_QUESTION); 10538 10539 *messagep = message; 10540 return (ISC_R_SUCCESS); 10541 10542 cleanup: 10543 if (qname != NULL) 10544 dns_message_puttempname(message, &qname); 10545 if (qrdataset != NULL) 10546 dns_message_puttemprdataset(message, &qrdataset); 10547 if (message != NULL) 10548 dns_message_destroy(&message); 10549 return (result); 10550} 10551 10552static isc_result_t 10553add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) { 10554 dns_rdataset_t *rdataset = NULL; 10555 dns_rdatalist_t *rdatalist = NULL; 10556 dns_rdata_t *rdata = NULL; 10557 isc_result_t result; 10558 10559 result = dns_message_gettemprdatalist(message, &rdatalist); 10560 if (result != ISC_R_SUCCESS) 10561 goto cleanup; 10562 result = dns_message_gettemprdata(message, &rdata); 10563 if (result != ISC_R_SUCCESS) 10564 goto cleanup; 10565 result = dns_message_gettemprdataset(message, &rdataset); 10566 if (result != ISC_R_SUCCESS) 10567 goto cleanup; 10568 dns_rdataset_init(rdataset); 10569 10570 rdatalist->type = dns_rdatatype_opt; 10571 rdatalist->covers = 0; 10572 10573 /* 10574 * Set Maximum UDP buffer size. 10575 */ 10576 rdatalist->rdclass = udpsize; 10577 10578 /* 10579 * Set EXTENDED-RCODE, VERSION, DO and Z to 0. 10580 */ 10581 rdatalist->ttl = 0; 10582 10583 /* Set EDNS options if applicable */ 10584 if (reqnsid) { 10585 unsigned char data[4]; 10586 isc_buffer_t buf; 10587 10588 isc_buffer_init(&buf, data, sizeof(data)); 10589 isc_buffer_putuint16(&buf, DNS_OPT_NSID); 10590 isc_buffer_putuint16(&buf, 0); 10591 rdata->data = data; 10592 rdata->length = sizeof(data); 10593 } else { 10594 rdata->data = NULL; 10595 rdata->length = 0; 10596 } 10597 10598 rdata->rdclass = rdatalist->rdclass; 10599 rdata->type = rdatalist->type; 10600 rdata->flags = 0; 10601 10602 ISC_LIST_INIT(rdatalist->rdata); 10603 ISC_LIST_APPEND(rdatalist->rdata, rdata, link); 10604 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) 10605 == ISC_R_SUCCESS); 10606 10607 return (dns_message_setopt(message, rdataset)); 10608 10609 cleanup: 10610 if (rdatalist != NULL) 10611 dns_message_puttemprdatalist(message, &rdatalist); 10612 if (rdataset != NULL) 10613 dns_message_puttemprdataset(message, &rdataset); 10614 if (rdata != NULL) 10615 dns_message_puttemprdata(message, &rdata); 10616 10617 return (result); 10618} 10619 10620static void 10621soa_query(isc_task_t *task, isc_event_t *event) { 10622 const char me[] = "soa_query"; 10623 isc_result_t result = ISC_R_FAILURE; 10624 dns_message_t *message = NULL; 10625 dns_zone_t *zone = event->ev_arg; 10626 dns_zone_t *dummy = NULL; 10627 isc_netaddr_t masterip; 10628 dns_tsigkey_t *key = NULL; 10629 isc_uint32_t options; 10630 isc_boolean_t cancel = ISC_TRUE; 10631 int timeout; 10632 isc_boolean_t have_xfrsource, reqnsid; 10633 isc_uint16_t udpsize = SEND_BUFFER_SIZE; 10634 10635 REQUIRE(DNS_ZONE_VALID(zone)); 10636 10637 UNUSED(task); 10638 10639 ENTER; 10640 10641 LOCK_ZONE(zone); 10642 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) || 10643 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || 10644 zone->view->requestmgr == NULL) { 10645 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 10646 cancel = ISC_FALSE; 10647 goto cleanup; 10648 } 10649 10650 /* 10651 * XXX Optimisation: Create message when zone is setup and reuse. 10652 */ 10653 result = create_query(zone, dns_rdatatype_soa, &message); 10654 if (result != ISC_R_SUCCESS) 10655 goto cleanup; 10656 10657 again: 10658 INSIST(zone->masterscnt > 0); 10659 INSIST(zone->curmaster < zone->masterscnt); 10660 10661 zone->masteraddr = zone->masters[zone->curmaster]; 10662 10663 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 10664 /* 10665 * First, look for a tsig key in the master statement, then 10666 * try for a server key. 10667 */ 10668 if ((zone->masterkeynames != NULL) && 10669 (zone->masterkeynames[zone->curmaster] != NULL)) { 10670 dns_view_t *view = dns_zone_getview(zone); 10671 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 10672 result = dns_view_gettsig(view, keyname, &key); 10673 if (result != ISC_R_SUCCESS) { 10674 char namebuf[DNS_NAME_FORMATSIZE]; 10675 dns_name_format(keyname, namebuf, sizeof(namebuf)); 10676 dns_zone_log(zone, ISC_LOG_ERROR, 10677 "unable to find key: %s", namebuf); 10678 goto skip_master; 10679 } 10680 } 10681 if (key == NULL) { 10682 result = dns_view_getpeertsig(zone->view, &masterip, &key); 10683 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 10684 char addrbuf[ISC_NETADDR_FORMATSIZE]; 10685 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf)); 10686 dns_zone_log(zone, ISC_LOG_ERROR, 10687 "unable to find TSIG key for %s", addrbuf); 10688 goto skip_master; 10689 } 10690 } 10691 10692 have_xfrsource = ISC_FALSE; 10693 reqnsid = zone->view->requestnsid; 10694 if (zone->view->peers != NULL) { 10695 dns_peer_t *peer = NULL; 10696 isc_boolean_t edns; 10697 result = dns_peerlist_peerbyaddr(zone->view->peers, 10698 &masterip, &peer); 10699 if (result == ISC_R_SUCCESS) { 10700 result = dns_peer_getsupportedns(peer, &edns); 10701 if (result == ISC_R_SUCCESS && !edns) 10702 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 10703 result = dns_peer_gettransfersource(peer, 10704 &zone->sourceaddr); 10705 if (result == ISC_R_SUCCESS) 10706 have_xfrsource = ISC_TRUE; 10707 if (zone->view->resolver != NULL) 10708 udpsize = 10709 dns_resolver_getudpsize(zone->view->resolver); 10710 (void)dns_peer_getudpsize(peer, &udpsize); 10711 (void)dns_peer_getrequestnsid(peer, &reqnsid); 10712 } 10713 } 10714 10715 switch (isc_sockaddr_pf(&zone->masteraddr)) { 10716 case PF_INET: 10717 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 10718 if (isc_sockaddr_equal(&zone->altxfrsource4, 10719 &zone->xfrsource4)) 10720 goto skip_master; 10721 zone->sourceaddr = zone->altxfrsource4; 10722 } else if (!have_xfrsource) 10723 zone->sourceaddr = zone->xfrsource4; 10724 break; 10725 case PF_INET6: 10726 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 10727 if (isc_sockaddr_equal(&zone->altxfrsource6, 10728 &zone->xfrsource6)) 10729 goto skip_master; 10730 zone->sourceaddr = zone->altxfrsource6; 10731 } else if (!have_xfrsource) 10732 zone->sourceaddr = zone->xfrsource6; 10733 break; 10734 default: 10735 result = ISC_R_NOTIMPLEMENTED; 10736 goto cleanup; 10737 } 10738 10739 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? 10740 DNS_REQUESTOPT_TCP : 0; 10741 10742 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 10743 result = add_opt(message, udpsize, reqnsid); 10744 if (result != ISC_R_SUCCESS) 10745 zone_debuglog(zone, me, 1, 10746 "unable to add opt record: %s", 10747 dns_result_totext(result)); 10748 } 10749 10750 zone_iattach(zone, &dummy); 10751 timeout = 15; 10752 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 10753 timeout = 30; 10754 result = dns_request_createvia2(zone->view->requestmgr, message, 10755 &zone->sourceaddr, &zone->masteraddr, 10756 options, key, timeout * 3, timeout, 10757 zone->task, refresh_callback, zone, 10758 &zone->request); 10759 if (result != ISC_R_SUCCESS) { 10760 zone_idetach(&dummy); 10761 zone_debuglog(zone, me, 1, 10762 "dns_request_createvia2() failed: %s", 10763 dns_result_totext(result)); 10764 goto cleanup; 10765 } else { 10766 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET) 10767 inc_stats(zone, dns_zonestatscounter_soaoutv4); 10768 else 10769 inc_stats(zone, dns_zonestatscounter_soaoutv6); 10770 } 10771 cancel = ISC_FALSE; 10772 10773 cleanup: 10774 if (key != NULL) 10775 dns_tsigkey_detach(&key); 10776 if (result != ISC_R_SUCCESS) 10777 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 10778 if (message != NULL) 10779 dns_message_destroy(&message); 10780 if (cancel) 10781 cancel_refresh(zone); 10782 isc_event_free(&event); 10783 UNLOCK_ZONE(zone); 10784 dns_zone_idetach(&zone); 10785 return; 10786 10787 skip_master: 10788 if (key != NULL) 10789 dns_tsigkey_detach(&key); 10790 /* 10791 * Skip to next failed / untried master. 10792 */ 10793 do { 10794 zone->curmaster++; 10795 } while (zone->curmaster < zone->masterscnt && 10796 zone->mastersok[zone->curmaster]); 10797 if (zone->curmaster < zone->masterscnt) 10798 goto again; 10799 zone->curmaster = 0; 10800 goto cleanup; 10801} 10802 10803static void 10804ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { 10805 const char me[] = "ns_query"; 10806 isc_result_t result; 10807 dns_message_t *message = NULL; 10808 isc_netaddr_t masterip; 10809 dns_tsigkey_t *key = NULL; 10810 dns_dbnode_t *node = NULL; 10811 int timeout; 10812 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid; 10813 isc_uint16_t udpsize = SEND_BUFFER_SIZE; 10814 10815 REQUIRE(DNS_ZONE_VALID(zone)); 10816 REQUIRE(LOCKED_ZONE(zone)); 10817 REQUIRE((soardataset != NULL && stub == NULL) || 10818 (soardataset == NULL && stub != NULL)); 10819 REQUIRE(stub == NULL || DNS_STUB_VALID(stub)); 10820 10821 ENTER; 10822 10823 if (stub == NULL) { 10824 stub = isc_mem_get(zone->mctx, sizeof(*stub)); 10825 if (stub == NULL) 10826 goto cleanup; 10827 stub->magic = STUB_MAGIC; 10828 stub->mctx = zone->mctx; 10829 stub->zone = NULL; 10830 stub->db = NULL; 10831 stub->version = NULL; 10832 10833 /* 10834 * Attach so that the zone won't disappear from under us. 10835 */ 10836 zone_iattach(zone, &stub->zone); 10837 10838 /* 10839 * If a db exists we will update it, otherwise we create a 10840 * new one and attach it to the zone once we have the NS 10841 * RRset and glue. 10842 */ 10843 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 10844 if (zone->db != NULL) { 10845 dns_db_attach(zone->db, &stub->db); 10846 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 10847 } else { 10848 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 10849 10850 INSIST(zone->db_argc >= 1); 10851 result = dns_db_create(zone->mctx, zone->db_argv[0], 10852 &zone->origin, dns_dbtype_stub, 10853 zone->rdclass, 10854 zone->db_argc - 1, 10855 zone->db_argv + 1, 10856 &stub->db); 10857 if (result != ISC_R_SUCCESS) { 10858 dns_zone_log(zone, ISC_LOG_ERROR, 10859 "refreshing stub: " 10860 "could not create " 10861 "database: %s", 10862 dns_result_totext(result)); 10863 goto cleanup; 10864 } 10865 dns_db_settask(stub->db, zone->task); 10866 } 10867 10868 result = dns_db_newversion(stub->db, &stub->version); 10869 if (result != ISC_R_SUCCESS) { 10870 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " 10871 "dns_db_newversion() failed: %s", 10872 dns_result_totext(result)); 10873 goto cleanup; 10874 } 10875 10876 /* 10877 * Update SOA record. 10878 */ 10879 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE, 10880 &node); 10881 if (result != ISC_R_SUCCESS) { 10882 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " 10883 "dns_db_findnode() failed: %s", 10884 dns_result_totext(result)); 10885 goto cleanup; 10886 } 10887 10888 result = dns_db_addrdataset(stub->db, node, stub->version, 0, 10889 soardataset, 0, NULL); 10890 dns_db_detachnode(stub->db, &node); 10891 if (result != ISC_R_SUCCESS) { 10892 dns_zone_log(zone, ISC_LOG_INFO, 10893 "refreshing stub: " 10894 "dns_db_addrdataset() failed: %s", 10895 dns_result_totext(result)); 10896 goto cleanup; 10897 } 10898 } 10899 10900 /* 10901 * XXX Optimisation: Create message when zone is setup and reuse. 10902 */ 10903 result = create_query(zone, dns_rdatatype_ns, &message); 10904 INSIST(result == ISC_R_SUCCESS); 10905 10906 INSIST(zone->masterscnt > 0); 10907 INSIST(zone->curmaster < zone->masterscnt); 10908 zone->masteraddr = zone->masters[zone->curmaster]; 10909 10910 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 10911 /* 10912 * First, look for a tsig key in the master statement, then 10913 * try for a server key. 10914 */ 10915 if ((zone->masterkeynames != NULL) && 10916 (zone->masterkeynames[zone->curmaster] != NULL)) { 10917 dns_view_t *view = dns_zone_getview(zone); 10918 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 10919 result = dns_view_gettsig(view, keyname, &key); 10920 if (result != ISC_R_SUCCESS) { 10921 char namebuf[DNS_NAME_FORMATSIZE]; 10922 dns_name_format(keyname, namebuf, sizeof(namebuf)); 10923 dns_zone_log(zone, ISC_LOG_ERROR, 10924 "unable to find key: %s", namebuf); 10925 } 10926 } 10927 if (key == NULL) 10928 (void)dns_view_getpeertsig(zone->view, &masterip, &key); 10929 10930 reqnsid = zone->view->requestnsid; 10931 if (zone->view->peers != NULL) { 10932 dns_peer_t *peer = NULL; 10933 isc_boolean_t edns; 10934 result = dns_peerlist_peerbyaddr(zone->view->peers, 10935 &masterip, &peer); 10936 if (result == ISC_R_SUCCESS) { 10937 result = dns_peer_getsupportedns(peer, &edns); 10938 if (result == ISC_R_SUCCESS && !edns) 10939 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 10940 result = dns_peer_gettransfersource(peer, 10941 &zone->sourceaddr); 10942 if (result == ISC_R_SUCCESS) 10943 have_xfrsource = ISC_TRUE; 10944 if (zone->view->resolver != NULL) 10945 udpsize = 10946 dns_resolver_getudpsize(zone->view->resolver); 10947 (void)dns_peer_getudpsize(peer, &udpsize); 10948 (void)dns_peer_getrequestnsid(peer, &reqnsid); 10949 } 10950 10951 } 10952 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 10953 result = add_opt(message, udpsize, reqnsid); 10954 if (result != ISC_R_SUCCESS) 10955 zone_debuglog(zone, me, 1, 10956 "unable to add opt record: %s", 10957 dns_result_totext(result)); 10958 } 10959 10960 /* 10961 * Always use TCP so that we shouldn't truncate in additional section. 10962 */ 10963 switch (isc_sockaddr_pf(&zone->masteraddr)) { 10964 case PF_INET: 10965 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) 10966 zone->sourceaddr = zone->altxfrsource4; 10967 else if (!have_xfrsource) 10968 zone->sourceaddr = zone->xfrsource4; 10969 break; 10970 case PF_INET6: 10971 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) 10972 zone->sourceaddr = zone->altxfrsource6; 10973 else if (!have_xfrsource) 10974 zone->sourceaddr = zone->xfrsource6; 10975 break; 10976 default: 10977 result = ISC_R_NOTIMPLEMENTED; 10978 POST(result); 10979 goto cleanup; 10980 } 10981 timeout = 15; 10982 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 10983 timeout = 30; 10984 result = dns_request_createvia2(zone->view->requestmgr, message, 10985 &zone->sourceaddr, &zone->masteraddr, 10986 DNS_REQUESTOPT_TCP, key, timeout * 3, 10987 timeout, zone->task, stub_callback, 10988 stub, &zone->request); 10989 if (result != ISC_R_SUCCESS) { 10990 zone_debuglog(zone, me, 1, 10991 "dns_request_createvia() failed: %s", 10992 dns_result_totext(result)); 10993 goto cleanup; 10994 } 10995 dns_message_destroy(&message); 10996 goto unlock; 10997 10998 cleanup: 10999 cancel_refresh(zone); 11000 if (stub != NULL) { 11001 stub->magic = 0; 11002 if (stub->version != NULL) 11003 dns_db_closeversion(stub->db, &stub->version, 11004 ISC_FALSE); 11005 if (stub->db != NULL) 11006 dns_db_detach(&stub->db); 11007 if (stub->zone != NULL) 11008 zone_idetach(&stub->zone); 11009 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 11010 } 11011 if (message != NULL) 11012 dns_message_destroy(&message); 11013 unlock: 11014 if (key != NULL) 11015 dns_tsigkey_detach(&key); 11016 return; 11017} 11018 11019/* 11020 * Handle the control event. Note that although this event causes the zone 11021 * to shut down, it is not a shutdown event in the sense of the task library. 11022 */ 11023static void 11024zone_shutdown(isc_task_t *task, isc_event_t *event) { 11025 dns_zone_t *zone = (dns_zone_t *) event->ev_arg; 11026 isc_boolean_t free_needed, linked = ISC_FALSE; 11027 dns_zone_t *raw = NULL, *secure = NULL; 11028 11029 UNUSED(task); 11030 REQUIRE(DNS_ZONE_VALID(zone)); 11031 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL); 11032 INSIST(isc_refcount_current(&zone->erefs) == 0); 11033 11034 zone_debuglog(zone, "zone_shutdown", 3, "shutting down"); 11035 11036 /* 11037 * Stop things being restarted after we cancel them below. 11038 */ 11039 LOCK_ZONE(zone); 11040 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING); 11041 UNLOCK_ZONE(zone); 11042 11043 /* 11044 * If we were waiting for xfrin quota, step out of 11045 * the queue. 11046 * If there's no zone manager, we can't be waiting for the 11047 * xfrin quota 11048 */ 11049 if (zone->zmgr != NULL) { 11050 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 11051 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) { 11052 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone, 11053 statelink); 11054 linked = ISC_TRUE; 11055 zone->statelist = NULL; 11056 } 11057 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 11058 } 11059 11060 /* 11061 * In task context, no locking required. See zone_xfrdone(). 11062 */ 11063 if (zone->xfr != NULL) 11064 dns_xfrin_shutdown(zone->xfr); 11065 11066 LOCK_ZONE(zone); 11067 if (linked) { 11068 INSIST(zone->irefs > 0); 11069 zone->irefs--; 11070 } 11071 if (zone->request != NULL) { 11072 dns_request_cancel(zone->request); 11073 } 11074 11075 if (zone->readio != NULL) 11076 zonemgr_cancelio(zone->readio); 11077 11078 if (zone->lctx != NULL) 11079 dns_loadctx_cancel(zone->lctx); 11080 11081 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 11082 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 11083 if (zone->writeio != NULL) 11084 zonemgr_cancelio(zone->writeio); 11085 11086 if (zone->dctx != NULL) 11087 dns_dumpctx_cancel(zone->dctx); 11088 } 11089 11090 notify_cancel(zone); 11091 11092 forward_cancel(zone); 11093 11094 if (zone->timer != NULL) { 11095 isc_timer_detach(&zone->timer); 11096 INSIST(zone->irefs > 0); 11097 zone->irefs--; 11098 } 11099 11100 if (zone->view != NULL) 11101 dns_view_weakdetach(&zone->view); 11102 11103 /* 11104 * We have now canceled everything set the flag to allow exit_check() 11105 * to succeed. We must not unlock between setting this flag and 11106 * calling exit_check(). 11107 */ 11108 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN); 11109 free_needed = exit_check(zone); 11110 if (inline_secure(zone)) { 11111 raw = zone->raw; 11112 zone->raw = NULL; 11113 } 11114 if (inline_raw(zone)) { 11115 secure = zone->secure; 11116 zone->secure = NULL; 11117 } 11118 UNLOCK_ZONE(zone); 11119 if (raw != NULL) 11120 dns_zone_detach(&raw); 11121 if (secure != NULL) 11122 dns_zone_idetach(&secure); 11123 if (free_needed) 11124 zone_free(zone); 11125} 11126 11127static void 11128zone_timer(isc_task_t *task, isc_event_t *event) { 11129 const char me[] = "zone_timer"; 11130 dns_zone_t *zone = (dns_zone_t *)event->ev_arg; 11131 11132 UNUSED(task); 11133 REQUIRE(DNS_ZONE_VALID(zone)); 11134 11135 ENTER; 11136 11137 zone_maintenance(zone); 11138 11139 isc_event_free(&event); 11140} 11141 11142static void 11143zone_settimer(dns_zone_t *zone, isc_time_t *now) { 11144 const char me[] = "zone_settimer"; 11145 isc_time_t next; 11146 isc_result_t result; 11147 11148 ENTER; 11149 REQUIRE(DNS_ZONE_VALID(zone)); 11150 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 11151 return; 11152 11153 isc_time_settoepoch(&next); 11154 11155 switch (zone->type) { 11156 case dns_zone_redirect: 11157 if (zone->masters != NULL) 11158 goto treat_as_slave; 11159 /* FALLTHROUGH */ 11160 11161 case dns_zone_master: 11162 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) 11163 next = zone->notifytime; 11164 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 11165 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 11166 INSIST(!isc_time_isepoch(&zone->dumptime)); 11167 if (isc_time_isepoch(&next) || 11168 isc_time_compare(&zone->dumptime, &next) < 0) 11169 next = zone->dumptime; 11170 } 11171 if (zone->type == dns_zone_redirect) 11172 break; 11173 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) && 11174 !isc_time_isepoch(&zone->refreshkeytime)) { 11175 if (isc_time_isepoch(&next) || 11176 isc_time_compare(&zone->refreshkeytime, &next) < 0) 11177 next = zone->refreshkeytime; 11178 } 11179 if (!isc_time_isepoch(&zone->resigntime)) { 11180 if (isc_time_isepoch(&next) || 11181 isc_time_compare(&zone->resigntime, &next) < 0) 11182 next = zone->resigntime; 11183 } 11184 if (!isc_time_isepoch(&zone->keywarntime)) { 11185 if (isc_time_isepoch(&next) || 11186 isc_time_compare(&zone->keywarntime, &next) < 0) 11187 next = zone->keywarntime; 11188 } 11189 if (!isc_time_isepoch(&zone->signingtime)) { 11190 if (isc_time_isepoch(&next) || 11191 isc_time_compare(&zone->signingtime, &next) < 0) 11192 next = zone->signingtime; 11193 } 11194 if (!isc_time_isepoch(&zone->nsec3chaintime)) { 11195 if (isc_time_isepoch(&next) || 11196 isc_time_compare(&zone->nsec3chaintime, &next) < 0) 11197 next = zone->nsec3chaintime; 11198 } 11199 break; 11200 11201 case dns_zone_slave: 11202 treat_as_slave: 11203 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) 11204 next = zone->notifytime; 11205 /* FALLTHROUGH */ 11206 11207 case dns_zone_stub: 11208 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) && 11209 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) && 11210 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) && 11211 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { 11212 INSIST(!isc_time_isepoch(&zone->refreshtime)); 11213 if (isc_time_isepoch(&next) || 11214 isc_time_compare(&zone->refreshtime, &next) < 0) 11215 next = zone->refreshtime; 11216 } 11217 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 11218 INSIST(!isc_time_isepoch(&zone->expiretime)); 11219 if (isc_time_isepoch(&next) || 11220 isc_time_compare(&zone->expiretime, &next) < 0) 11221 next = zone->expiretime; 11222 } 11223 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 11224 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 11225 INSIST(!isc_time_isepoch(&zone->dumptime)); 11226 if (isc_time_isepoch(&next) || 11227 isc_time_compare(&zone->dumptime, &next) < 0) 11228 next = zone->dumptime; 11229 } 11230 break; 11231 11232 case dns_zone_key: 11233 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 11234 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 11235 INSIST(!isc_time_isepoch(&zone->dumptime)); 11236 if (isc_time_isepoch(&next) || 11237 isc_time_compare(&zone->dumptime, &next) < 0) 11238 next = zone->dumptime; 11239 } 11240 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) { 11241 if (isc_time_isepoch(&next) || 11242 (!isc_time_isepoch(&zone->refreshkeytime) && 11243 isc_time_compare(&zone->refreshkeytime, &next) < 0)) 11244 next = zone->refreshkeytime; 11245 } 11246 break; 11247 11248 default: 11249 break; 11250 } 11251 11252 if (isc_time_isepoch(&next)) { 11253 zone_debuglog(zone, me, 10, "settimer inactive"); 11254 result = isc_timer_reset(zone->timer, isc_timertype_inactive, 11255 NULL, NULL, ISC_TRUE); 11256 if (result != ISC_R_SUCCESS) 11257 dns_zone_log(zone, ISC_LOG_ERROR, 11258 "could not deactivate zone timer: %s", 11259 isc_result_totext(result)); 11260 } else { 11261 if (isc_time_compare(&next, now) <= 0) 11262 next = *now; 11263 result = isc_timer_reset(zone->timer, isc_timertype_once, 11264 &next, NULL, ISC_TRUE); 11265 if (result != ISC_R_SUCCESS) 11266 dns_zone_log(zone, ISC_LOG_ERROR, 11267 "could not reset zone timer: %s", 11268 isc_result_totext(result)); 11269 } 11270} 11271 11272static void 11273cancel_refresh(dns_zone_t *zone) { 11274 const char me[] = "cancel_refresh"; 11275 isc_time_t now; 11276 11277 /* 11278 * 'zone' locked by caller. 11279 */ 11280 11281 REQUIRE(DNS_ZONE_VALID(zone)); 11282 REQUIRE(LOCKED_ZONE(zone)); 11283 11284 ENTER; 11285 11286 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 11287 TIME_NOW(&now); 11288 zone_settimer(zone, &now); 11289} 11290 11291static isc_result_t 11292notify_createmessage(dns_zone_t *zone, unsigned int flags, 11293 dns_message_t **messagep) 11294{ 11295 dns_db_t *zonedb = NULL; 11296 dns_dbnode_t *node = NULL; 11297 dns_dbversion_t *version = NULL; 11298 dns_message_t *message = NULL; 11299 dns_rdataset_t rdataset; 11300 dns_rdata_t rdata = DNS_RDATA_INIT; 11301 11302 dns_name_t *tempname = NULL; 11303 dns_rdata_t *temprdata = NULL; 11304 dns_rdatalist_t *temprdatalist = NULL; 11305 dns_rdataset_t *temprdataset = NULL; 11306 11307 isc_result_t result; 11308 isc_region_t r; 11309 isc_buffer_t *b = NULL; 11310 11311 REQUIRE(DNS_ZONE_VALID(zone)); 11312 REQUIRE(messagep != NULL && *messagep == NULL); 11313 11314 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, 11315 &message); 11316 if (result != ISC_R_SUCCESS) 11317 return (result); 11318 11319 message->opcode = dns_opcode_notify; 11320 message->flags |= DNS_MESSAGEFLAG_AA; 11321 message->rdclass = zone->rdclass; 11322 11323 result = dns_message_gettempname(message, &tempname); 11324 if (result != ISC_R_SUCCESS) 11325 goto cleanup; 11326 11327 result = dns_message_gettemprdataset(message, &temprdataset); 11328 if (result != ISC_R_SUCCESS) 11329 goto cleanup; 11330 11331 /* 11332 * Make question. 11333 */ 11334 dns_name_init(tempname, NULL); 11335 dns_name_clone(&zone->origin, tempname); 11336 dns_rdataset_init(temprdataset); 11337 dns_rdataset_makequestion(temprdataset, zone->rdclass, 11338 dns_rdatatype_soa); 11339 ISC_LIST_APPEND(tempname->list, temprdataset, link); 11340 dns_message_addname(message, tempname, DNS_SECTION_QUESTION); 11341 tempname = NULL; 11342 temprdataset = NULL; 11343 11344 if ((flags & DNS_NOTIFY_NOSOA) != 0) 11345 goto done; 11346 11347 result = dns_message_gettempname(message, &tempname); 11348 if (result != ISC_R_SUCCESS) 11349 goto soa_cleanup; 11350 result = dns_message_gettemprdata(message, &temprdata); 11351 if (result != ISC_R_SUCCESS) 11352 goto soa_cleanup; 11353 result = dns_message_gettemprdataset(message, &temprdataset); 11354 if (result != ISC_R_SUCCESS) 11355 goto soa_cleanup; 11356 result = dns_message_gettemprdatalist(message, &temprdatalist); 11357 if (result != ISC_R_SUCCESS) 11358 goto soa_cleanup; 11359 11360 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 11361 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */ 11362 dns_db_attach(zone->db, &zonedb); 11363 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11364 11365 dns_name_init(tempname, NULL); 11366 dns_name_clone(&zone->origin, tempname); 11367 dns_db_currentversion(zonedb, &version); 11368 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node); 11369 if (result != ISC_R_SUCCESS) 11370 goto soa_cleanup; 11371 11372 dns_rdataset_init(&rdataset); 11373 result = dns_db_findrdataset(zonedb, node, version, 11374 dns_rdatatype_soa, 11375 dns_rdatatype_none, 0, &rdataset, 11376 NULL); 11377 if (result != ISC_R_SUCCESS) 11378 goto soa_cleanup; 11379 result = dns_rdataset_first(&rdataset); 11380 if (result != ISC_R_SUCCESS) 11381 goto soa_cleanup; 11382 dns_rdataset_current(&rdataset, &rdata); 11383 dns_rdata_toregion(&rdata, &r); 11384 result = isc_buffer_allocate(zone->mctx, &b, r.length); 11385 if (result != ISC_R_SUCCESS) 11386 goto soa_cleanup; 11387 isc_buffer_putmem(b, r.base, r.length); 11388 isc_buffer_usedregion(b, &r); 11389 dns_rdata_init(temprdata); 11390 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r); 11391 dns_message_takebuffer(message, &b); 11392 result = dns_rdataset_next(&rdataset); 11393 dns_rdataset_disassociate(&rdataset); 11394 if (result != ISC_R_NOMORE) 11395 goto soa_cleanup; 11396 temprdatalist->rdclass = rdata.rdclass; 11397 temprdatalist->type = rdata.type; 11398 temprdatalist->covers = 0; 11399 temprdatalist->ttl = rdataset.ttl; 11400 ISC_LIST_INIT(temprdatalist->rdata); 11401 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link); 11402 11403 dns_rdataset_init(temprdataset); 11404 result = dns_rdatalist_tordataset(temprdatalist, temprdataset); 11405 if (result != ISC_R_SUCCESS) 11406 goto soa_cleanup; 11407 11408 ISC_LIST_APPEND(tempname->list, temprdataset, link); 11409 dns_message_addname(message, tempname, DNS_SECTION_ANSWER); 11410 temprdatalist = NULL; 11411 temprdataset = NULL; 11412 temprdata = NULL; 11413 tempname = NULL; 11414 11415 soa_cleanup: 11416 if (node != NULL) 11417 dns_db_detachnode(zonedb, &node); 11418 if (version != NULL) 11419 dns_db_closeversion(zonedb, &version, ISC_FALSE); 11420 if (zonedb != NULL) 11421 dns_db_detach(&zonedb); 11422 if (tempname != NULL) 11423 dns_message_puttempname(message, &tempname); 11424 if (temprdata != NULL) 11425 dns_message_puttemprdata(message, &temprdata); 11426 if (temprdataset != NULL) 11427 dns_message_puttemprdataset(message, &temprdataset); 11428 if (temprdatalist != NULL) 11429 dns_message_puttemprdatalist(message, &temprdatalist); 11430 11431 done: 11432 *messagep = message; 11433 return (ISC_R_SUCCESS); 11434 11435 cleanup: 11436 if (tempname != NULL) 11437 dns_message_puttempname(message, &tempname); 11438 if (temprdataset != NULL) 11439 dns_message_puttemprdataset(message, &temprdataset); 11440 dns_message_destroy(&message); 11441 return (result); 11442} 11443 11444isc_result_t 11445dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, 11446 dns_message_t *msg) 11447{ 11448 unsigned int i; 11449 dns_rdata_soa_t soa; 11450 dns_rdataset_t *rdataset = NULL; 11451 dns_rdata_t rdata = DNS_RDATA_INIT; 11452 isc_result_t result; 11453 char fromtext[ISC_SOCKADDR_FORMATSIZE]; 11454 int match = 0; 11455 isc_netaddr_t netaddr; 11456 isc_sockaddr_t local, remote; 11457 11458 REQUIRE(DNS_ZONE_VALID(zone)); 11459 11460 /* 11461 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support 11462 * ROLLOVER. 11463 * 11464 * SOA: RFC1996 11465 * Check that 'from' is a valid notify source, (zone->masters). 11466 * Return DNS_R_REFUSED if not. 11467 * 11468 * If the notify message contains a serial number check it 11469 * against the zones serial and return if <= current serial 11470 * 11471 * If a refresh check is progress, if so just record the 11472 * fact we received a NOTIFY and from where and return. 11473 * We will perform a new refresh check when the current one 11474 * completes. Return ISC_R_SUCCESS. 11475 * 11476 * Otherwise initiate a refresh check using 'from' as the 11477 * first address to check. Return ISC_R_SUCCESS. 11478 */ 11479 11480 isc_sockaddr_format(from, fromtext, sizeof(fromtext)); 11481 11482 /* 11483 * Notify messages are processed by the raw zone. 11484 */ 11485 LOCK_ZONE(zone); 11486 if (inline_secure(zone)) { 11487 result = dns_zone_notifyreceive(zone->raw, from, msg); 11488 UNLOCK_ZONE(zone); 11489 return (result); 11490 } 11491 /* 11492 * We only handle NOTIFY (SOA) at the present. 11493 */ 11494 if (isc_sockaddr_pf(from) == PF_INET) 11495 inc_stats(zone, dns_zonestatscounter_notifyinv4); 11496 else 11497 inc_stats(zone, dns_zonestatscounter_notifyinv6); 11498 if (msg->counts[DNS_SECTION_QUESTION] == 0 || 11499 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin, 11500 dns_rdatatype_soa, dns_rdatatype_none, 11501 NULL, NULL) != ISC_R_SUCCESS) { 11502 UNLOCK_ZONE(zone); 11503 if (msg->counts[DNS_SECTION_QUESTION] == 0) { 11504 dns_zone_log(zone, ISC_LOG_NOTICE, 11505 "NOTIFY with no " 11506 "question section from: %s", fromtext); 11507 return (DNS_R_FORMERR); 11508 } 11509 dns_zone_log(zone, ISC_LOG_NOTICE, 11510 "NOTIFY zone does not match"); 11511 return (DNS_R_NOTIMP); 11512 } 11513 11514 /* 11515 * If we are a master zone just succeed. 11516 */ 11517 if (zone->type == dns_zone_master) { 11518 UNLOCK_ZONE(zone); 11519 return (ISC_R_SUCCESS); 11520 } 11521 11522 isc_netaddr_fromsockaddr(&netaddr, from); 11523 for (i = 0; i < zone->masterscnt; i++) { 11524 if (isc_sockaddr_eqaddr(from, &zone->masters[i])) 11525 break; 11526 if (zone->view->aclenv.match_mapped && 11527 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) && 11528 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) { 11529 isc_netaddr_t na1, na2; 11530 isc_netaddr_fromv4mapped(&na1, &netaddr); 11531 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]); 11532 if (isc_netaddr_equal(&na1, &na2)) 11533 break; 11534 } 11535 } 11536 11537 /* 11538 * Accept notify requests from non masters if they are on 11539 * 'zone->notify_acl'. 11540 */ 11541 if (i >= zone->masterscnt && zone->notify_acl != NULL && 11542 dns_acl_match(&netaddr, NULL, zone->notify_acl, 11543 &zone->view->aclenv, 11544 &match, NULL) == ISC_R_SUCCESS && 11545 match > 0) 11546 { 11547 /* Accept notify. */ 11548 } else if (i >= zone->masterscnt) { 11549 UNLOCK_ZONE(zone); 11550 dns_zone_log(zone, ISC_LOG_INFO, 11551 "refused notify from non-master: %s", fromtext); 11552 inc_stats(zone, dns_zonestatscounter_notifyrej); 11553 return (DNS_R_REFUSED); 11554 } 11555 11556 /* 11557 * If the zone is loaded and there are answers check the serial 11558 * to see if we need to do a refresh. Do not worry about this 11559 * check if we are a dialup zone as we use the notify request 11560 * to trigger a refresh check. 11561 */ 11562 if (msg->counts[DNS_SECTION_ANSWER] > 0 && 11563 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 11564 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) { 11565 result = dns_message_findname(msg, DNS_SECTION_ANSWER, 11566 &zone->origin, 11567 dns_rdatatype_soa, 11568 dns_rdatatype_none, NULL, 11569 &rdataset); 11570 if (result == ISC_R_SUCCESS) 11571 result = dns_rdataset_first(rdataset); 11572 if (result == ISC_R_SUCCESS) { 11573 isc_uint32_t serial = 0, oldserial; 11574 11575 dns_rdataset_current(rdataset, &rdata); 11576 result = dns_rdata_tostruct(&rdata, &soa, NULL); 11577 RUNTIME_CHECK(result == ISC_R_SUCCESS); 11578 serial = soa.serial; 11579 /* 11580 * The following should safely be performed without DB 11581 * lock and succeed in this context. 11582 */ 11583 result = zone_get_from_db(zone, zone->db, NULL, NULL, 11584 &oldserial, NULL, NULL, NULL, 11585 NULL, NULL); 11586 RUNTIME_CHECK(result == ISC_R_SUCCESS); 11587 if (isc_serial_le(serial, oldserial)) { 11588 dns_zone_log(zone, 11589 ISC_LOG_INFO, 11590 "notify from %s: " 11591 "zone is up to date", 11592 fromtext); 11593 UNLOCK_ZONE(zone); 11594 return (ISC_R_SUCCESS); 11595 } 11596 } 11597 } 11598 11599 /* 11600 * If we got this far and there was a refresh in progress just 11601 * let it complete. Record where we got the notify from so we 11602 * can perform a refresh check when the current one completes 11603 */ 11604 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { 11605 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 11606 zone->notifyfrom = *from; 11607 UNLOCK_ZONE(zone); 11608 dns_zone_log(zone, ISC_LOG_INFO, 11609 "notify from %s: refresh in progress, " 11610 "refresh check queued", 11611 fromtext); 11612 return (ISC_R_SUCCESS); 11613 } 11614 zone->notifyfrom = *from; 11615 local = zone->masteraddr; 11616 remote = zone->sourceaddr; 11617 UNLOCK_ZONE(zone); 11618 dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote); 11619 dns_zone_refresh(zone); 11620 return (ISC_R_SUCCESS); 11621} 11622 11623void 11624dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) { 11625 11626 REQUIRE(DNS_ZONE_VALID(zone)); 11627 11628 LOCK_ZONE(zone); 11629 if (zone->notify_acl != NULL) 11630 dns_acl_detach(&zone->notify_acl); 11631 dns_acl_attach(acl, &zone->notify_acl); 11632 UNLOCK_ZONE(zone); 11633} 11634 11635void 11636dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) { 11637 11638 REQUIRE(DNS_ZONE_VALID(zone)); 11639 11640 LOCK_ZONE(zone); 11641 if (zone->query_acl != NULL) 11642 dns_acl_detach(&zone->query_acl); 11643 dns_acl_attach(acl, &zone->query_acl); 11644 UNLOCK_ZONE(zone); 11645} 11646 11647void 11648dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) { 11649 11650 REQUIRE(DNS_ZONE_VALID(zone)); 11651 11652 LOCK_ZONE(zone); 11653 if (zone->queryon_acl != NULL) 11654 dns_acl_detach(&zone->queryon_acl); 11655 dns_acl_attach(acl, &zone->queryon_acl); 11656 UNLOCK_ZONE(zone); 11657} 11658 11659void 11660dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) { 11661 11662 REQUIRE(DNS_ZONE_VALID(zone)); 11663 11664 LOCK_ZONE(zone); 11665 if (zone->update_acl != NULL) 11666 dns_acl_detach(&zone->update_acl); 11667 dns_acl_attach(acl, &zone->update_acl); 11668 UNLOCK_ZONE(zone); 11669} 11670 11671void 11672dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) { 11673 11674 REQUIRE(DNS_ZONE_VALID(zone)); 11675 11676 LOCK_ZONE(zone); 11677 if (zone->forward_acl != NULL) 11678 dns_acl_detach(&zone->forward_acl); 11679 dns_acl_attach(acl, &zone->forward_acl); 11680 UNLOCK_ZONE(zone); 11681} 11682 11683void 11684dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) { 11685 11686 REQUIRE(DNS_ZONE_VALID(zone)); 11687 11688 LOCK_ZONE(zone); 11689 if (zone->xfr_acl != NULL) 11690 dns_acl_detach(&zone->xfr_acl); 11691 dns_acl_attach(acl, &zone->xfr_acl); 11692 UNLOCK_ZONE(zone); 11693} 11694 11695dns_acl_t * 11696dns_zone_getnotifyacl(dns_zone_t *zone) { 11697 11698 REQUIRE(DNS_ZONE_VALID(zone)); 11699 11700 return (zone->notify_acl); 11701} 11702 11703dns_acl_t * 11704dns_zone_getqueryacl(dns_zone_t *zone) { 11705 11706 REQUIRE(DNS_ZONE_VALID(zone)); 11707 11708 return (zone->query_acl); 11709} 11710 11711dns_acl_t * 11712dns_zone_getqueryonacl(dns_zone_t *zone) { 11713 11714 REQUIRE(DNS_ZONE_VALID(zone)); 11715 11716 return (zone->queryon_acl); 11717} 11718 11719dns_acl_t * 11720dns_zone_getupdateacl(dns_zone_t *zone) { 11721 11722 REQUIRE(DNS_ZONE_VALID(zone)); 11723 11724 return (zone->update_acl); 11725} 11726 11727dns_acl_t * 11728dns_zone_getforwardacl(dns_zone_t *zone) { 11729 11730 REQUIRE(DNS_ZONE_VALID(zone)); 11731 11732 return (zone->forward_acl); 11733} 11734 11735dns_acl_t * 11736dns_zone_getxfracl(dns_zone_t *zone) { 11737 11738 REQUIRE(DNS_ZONE_VALID(zone)); 11739 11740 return (zone->xfr_acl); 11741} 11742 11743void 11744dns_zone_clearupdateacl(dns_zone_t *zone) { 11745 11746 REQUIRE(DNS_ZONE_VALID(zone)); 11747 11748 LOCK_ZONE(zone); 11749 if (zone->update_acl != NULL) 11750 dns_acl_detach(&zone->update_acl); 11751 UNLOCK_ZONE(zone); 11752} 11753 11754void 11755dns_zone_clearforwardacl(dns_zone_t *zone) { 11756 11757 REQUIRE(DNS_ZONE_VALID(zone)); 11758 11759 LOCK_ZONE(zone); 11760 if (zone->forward_acl != NULL) 11761 dns_acl_detach(&zone->forward_acl); 11762 UNLOCK_ZONE(zone); 11763} 11764 11765void 11766dns_zone_clearnotifyacl(dns_zone_t *zone) { 11767 11768 REQUIRE(DNS_ZONE_VALID(zone)); 11769 11770 LOCK_ZONE(zone); 11771 if (zone->notify_acl != NULL) 11772 dns_acl_detach(&zone->notify_acl); 11773 UNLOCK_ZONE(zone); 11774} 11775 11776void 11777dns_zone_clearqueryacl(dns_zone_t *zone) { 11778 11779 REQUIRE(DNS_ZONE_VALID(zone)); 11780 11781 LOCK_ZONE(zone); 11782 if (zone->query_acl != NULL) 11783 dns_acl_detach(&zone->query_acl); 11784 UNLOCK_ZONE(zone); 11785} 11786 11787void 11788dns_zone_clearqueryonacl(dns_zone_t *zone) { 11789 11790 REQUIRE(DNS_ZONE_VALID(zone)); 11791 11792 LOCK_ZONE(zone); 11793 if (zone->queryon_acl != NULL) 11794 dns_acl_detach(&zone->queryon_acl); 11795 UNLOCK_ZONE(zone); 11796} 11797 11798void 11799dns_zone_clearxfracl(dns_zone_t *zone) { 11800 11801 REQUIRE(DNS_ZONE_VALID(zone)); 11802 11803 LOCK_ZONE(zone); 11804 if (zone->xfr_acl != NULL) 11805 dns_acl_detach(&zone->xfr_acl); 11806 UNLOCK_ZONE(zone); 11807} 11808 11809isc_boolean_t 11810dns_zone_getupdatedisabled(dns_zone_t *zone) { 11811 REQUIRE(DNS_ZONE_VALID(zone)); 11812 return (zone->update_disabled); 11813 11814} 11815 11816void 11817dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) { 11818 REQUIRE(DNS_ZONE_VALID(zone)); 11819 zone->update_disabled = state; 11820} 11821 11822isc_boolean_t 11823dns_zone_getzeronosoattl(dns_zone_t *zone) { 11824 REQUIRE(DNS_ZONE_VALID(zone)); 11825 return (zone->zero_no_soa_ttl); 11826 11827} 11828 11829void 11830dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) { 11831 REQUIRE(DNS_ZONE_VALID(zone)); 11832 zone->zero_no_soa_ttl = state; 11833} 11834 11835void 11836dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) { 11837 11838 REQUIRE(DNS_ZONE_VALID(zone)); 11839 11840 zone->check_names = severity; 11841} 11842 11843dns_severity_t 11844dns_zone_getchecknames(dns_zone_t *zone) { 11845 11846 REQUIRE(DNS_ZONE_VALID(zone)); 11847 11848 return (zone->check_names); 11849} 11850 11851void 11852dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) { 11853 11854 REQUIRE(DNS_ZONE_VALID(zone)); 11855 11856 zone->journalsize = size; 11857} 11858 11859isc_int32_t 11860dns_zone_getjournalsize(dns_zone_t *zone) { 11861 11862 REQUIRE(DNS_ZONE_VALID(zone)); 11863 11864 return (zone->journalsize); 11865} 11866 11867static void 11868zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) { 11869 isc_result_t result = ISC_R_FAILURE; 11870 isc_buffer_t buffer; 11871 11872 REQUIRE(buf != NULL); 11873 REQUIRE(length > 1U); 11874 11875 /* 11876 * Leave space for terminating '\0'. 11877 */ 11878 isc_buffer_init(&buffer, buf, length - 1); 11879 if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) { 11880 if (dns_name_dynamic(&zone->origin)) 11881 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); 11882 if (result != ISC_R_SUCCESS && 11883 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1)) 11884 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 11885 11886 if (isc_buffer_availablelength(&buffer) > 0) 11887 isc_buffer_putstr(&buffer, "/"); 11888 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 11889 } 11890 11891 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 && 11892 strcmp(zone->view->name, "_default") != 0 && 11893 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) { 11894 isc_buffer_putstr(&buffer, "/"); 11895 isc_buffer_putstr(&buffer, zone->view->name); 11896 } 11897 if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer)) 11898 isc_buffer_putstr(&buffer, " (signed)"); 11899 if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer)) 11900 isc_buffer_putstr(&buffer, " (unsigned)"); 11901 11902 buf[isc_buffer_usedlength(&buffer)] = '\0'; 11903} 11904 11905static void 11906zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) { 11907 isc_result_t result = ISC_R_FAILURE; 11908 isc_buffer_t buffer; 11909 11910 REQUIRE(buf != NULL); 11911 REQUIRE(length > 1U); 11912 11913 /* 11914 * Leave space for terminating '\0'. 11915 */ 11916 isc_buffer_init(&buffer, buf, length - 1); 11917 if (dns_name_dynamic(&zone->origin)) 11918 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); 11919 if (result != ISC_R_SUCCESS && 11920 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1)) 11921 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 11922 11923 buf[isc_buffer_usedlength(&buffer)] = '\0'; 11924} 11925 11926static void 11927zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) { 11928 isc_buffer_t buffer; 11929 11930 REQUIRE(buf != NULL); 11931 REQUIRE(length > 1U); 11932 11933 /* 11934 * Leave space for terminating '\0'. 11935 */ 11936 isc_buffer_init(&buffer, buf, length - 1); 11937 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 11938 11939 buf[isc_buffer_usedlength(&buffer)] = '\0'; 11940} 11941 11942static void 11943zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) { 11944 isc_buffer_t buffer; 11945 11946 REQUIRE(buf != NULL); 11947 REQUIRE(length > 1U); 11948 11949 11950 /* 11951 * Leave space for terminating '\0'. 11952 */ 11953 isc_buffer_init(&buffer, buf, length - 1); 11954 11955 if (zone->view == NULL) { 11956 isc_buffer_putstr(&buffer, "_none"); 11957 } else if (strlen(zone->view->name) 11958 < isc_buffer_availablelength(&buffer)) { 11959 isc_buffer_putstr(&buffer, zone->view->name); 11960 } else { 11961 isc_buffer_putstr(&buffer, "_toolong"); 11962 } 11963 11964 buf[isc_buffer_usedlength(&buffer)] = '\0'; 11965} 11966 11967void 11968dns_zone_name(dns_zone_t *zone, char *buf, size_t length) { 11969 REQUIRE(DNS_ZONE_VALID(zone)); 11970 REQUIRE(buf != NULL); 11971 zone_namerd_tostr(zone, buf, length); 11972} 11973 11974static void 11975notify_log(dns_zone_t *zone, int level, const char *fmt, ...) { 11976 va_list ap; 11977 char message[4096]; 11978 11979 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 11980 return; 11981 11982 va_start(ap, fmt); 11983 vsnprintf(message, sizeof(message), fmt, ap); 11984 va_end(ap); 11985 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE, 11986 level, "zone %s: %s", zone->strnamerd, message); 11987} 11988 11989void 11990dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, 11991 int level, const char *fmt, ...) { 11992 va_list ap; 11993 char message[4096]; 11994 11995 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 11996 return; 11997 11998 va_start(ap, fmt); 11999 vsnprintf(message, sizeof(message), fmt, ap); 12000 va_end(ap); 12001 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, 12002 level, "%s%s: %s", (zone->type == dns_zone_key) ? 12003 "managed-keys-zone" : (zone->type == dns_zone_redirect) ? 12004 "redirect-zone" : "zone ", zone->strnamerd, message); 12005} 12006 12007void 12008dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) { 12009 va_list ap; 12010 char message[4096]; 12011 12012 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 12013 return; 12014 12015 va_start(ap, fmt); 12016 vsnprintf(message, sizeof(message), fmt, ap); 12017 va_end(ap); 12018 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, 12019 level, "%s%s: %s", (zone->type == dns_zone_key) ? 12020 "managed-keys-zone" : (zone->type == dns_zone_redirect) ? 12021 "redirect-zone" : "zone ", zone->strnamerd, message); 12022} 12023 12024static void 12025zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel, 12026 const char *fmt, ...) 12027{ 12028 va_list ap; 12029 char message[4096]; 12030 int level = ISC_LOG_DEBUG(debuglevel); 12031 12032 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 12033 return; 12034 12035 va_start(ap, fmt); 12036 vsnprintf(message, sizeof(message), fmt, ap); 12037 va_end(ap); 12038 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, 12039 level, "%s: %s %s: %s", me, zone->type != dns_zone_key ? 12040 "zone" : "managed-keys-zone", zone->strnamerd, message); 12041} 12042 12043static int 12044message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type) 12045{ 12046 isc_result_t result; 12047 dns_name_t *name; 12048 dns_rdataset_t *curr; 12049 int count = 0; 12050 12051 result = dns_message_firstname(msg, section); 12052 while (result == ISC_R_SUCCESS) { 12053 name = NULL; 12054 dns_message_currentname(msg, section, &name); 12055 12056 for (curr = ISC_LIST_TAIL(name->list); curr != NULL; 12057 curr = ISC_LIST_PREV(curr, link)) { 12058 if (curr->type == type) 12059 count++; 12060 } 12061 result = dns_message_nextname(msg, section); 12062 } 12063 12064 return (count); 12065} 12066 12067void 12068dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) { 12069 REQUIRE(DNS_ZONE_VALID(zone)); 12070 12071 zone->maxxfrin = maxxfrin; 12072} 12073 12074isc_uint32_t 12075dns_zone_getmaxxfrin(dns_zone_t *zone) { 12076 REQUIRE(DNS_ZONE_VALID(zone)); 12077 12078 return (zone->maxxfrin); 12079} 12080 12081void 12082dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) { 12083 REQUIRE(DNS_ZONE_VALID(zone)); 12084 zone->maxxfrout = maxxfrout; 12085} 12086 12087isc_uint32_t 12088dns_zone_getmaxxfrout(dns_zone_t *zone) { 12089 REQUIRE(DNS_ZONE_VALID(zone)); 12090 12091 return (zone->maxxfrout); 12092} 12093 12094dns_zonetype_t 12095dns_zone_gettype(dns_zone_t *zone) { 12096 REQUIRE(DNS_ZONE_VALID(zone)); 12097 12098 return (zone->type); 12099} 12100 12101dns_name_t * 12102dns_zone_getorigin(dns_zone_t *zone) { 12103 REQUIRE(DNS_ZONE_VALID(zone)); 12104 12105 return (&zone->origin); 12106} 12107 12108void 12109dns_zone_settask(dns_zone_t *zone, isc_task_t *task) { 12110 REQUIRE(DNS_ZONE_VALID(zone)); 12111 12112 LOCK_ZONE(zone); 12113 if (zone->task != NULL) 12114 isc_task_detach(&zone->task); 12115 isc_task_attach(task, &zone->task); 12116 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12117 if (zone->db != NULL) 12118 dns_db_settask(zone->db, zone->task); 12119 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12120 UNLOCK_ZONE(zone); 12121} 12122 12123void 12124dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) { 12125 REQUIRE(DNS_ZONE_VALID(zone)); 12126 isc_task_attach(zone->task, target); 12127} 12128 12129void 12130dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) { 12131 REQUIRE(DNS_ZONE_VALID(zone)); 12132 12133 if (idlein == 0) 12134 idlein = DNS_DEFAULT_IDLEIN; 12135 zone->idlein = idlein; 12136} 12137 12138isc_uint32_t 12139dns_zone_getidlein(dns_zone_t *zone) { 12140 REQUIRE(DNS_ZONE_VALID(zone)); 12141 12142 return (zone->idlein); 12143} 12144 12145void 12146dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) { 12147 REQUIRE(DNS_ZONE_VALID(zone)); 12148 12149 zone->idleout = idleout; 12150} 12151 12152isc_uint32_t 12153dns_zone_getidleout(dns_zone_t *zone) { 12154 REQUIRE(DNS_ZONE_VALID(zone)); 12155 12156 return (zone->idleout); 12157} 12158 12159static void 12160notify_done(isc_task_t *task, isc_event_t *event) { 12161 dns_requestevent_t *revent = (dns_requestevent_t *)event; 12162 dns_notify_t *notify; 12163 isc_result_t result; 12164 dns_message_t *message = NULL; 12165 isc_buffer_t buf; 12166 char rcode[128]; 12167 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 12168 12169 UNUSED(task); 12170 12171 notify = event->ev_arg; 12172 REQUIRE(DNS_NOTIFY_VALID(notify)); 12173 INSIST(task == notify->zone->task); 12174 12175 isc_buffer_init(&buf, rcode, sizeof(rcode)); 12176 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 12177 12178 result = revent->result; 12179 if (result == ISC_R_SUCCESS) 12180 result = dns_message_create(notify->zone->mctx, 12181 DNS_MESSAGE_INTENTPARSE, &message); 12182 if (result == ISC_R_SUCCESS) 12183 result = dns_request_getresponse(revent->request, message, 12184 DNS_MESSAGEPARSE_PRESERVEORDER); 12185 if (result == ISC_R_SUCCESS) 12186 result = dns_rcode_totext(message->rcode, &buf); 12187 if (result == ISC_R_SUCCESS) 12188 notify_log(notify->zone, ISC_LOG_DEBUG(3), 12189 "notify response from %s: %.*s", 12190 addrbuf, (int)buf.used, rcode); 12191 else 12192 notify_log(notify->zone, ISC_LOG_DEBUG(2), 12193 "notify to %s failed: %s", addrbuf, 12194 dns_result_totext(result)); 12195 12196 /* 12197 * Old bind's return formerr if they see a soa record. Retry w/o 12198 * the soa if we see a formerr and had sent a SOA. 12199 */ 12200 isc_event_free(&event); 12201 if (message != NULL && message->rcode == dns_rcode_formerr && 12202 (notify->flags & DNS_NOTIFY_NOSOA) == 0) { 12203 notify->flags |= DNS_NOTIFY_NOSOA; 12204 dns_request_destroy(¬ify->request); 12205 result = notify_send_queue(notify); 12206 if (result != ISC_R_SUCCESS) 12207 notify_destroy(notify, ISC_FALSE); 12208 } else { 12209 if (result == ISC_R_TIMEDOUT) 12210 notify_log(notify->zone, ISC_LOG_DEBUG(1), 12211 "notify to %s: retries exceeded", addrbuf); 12212 notify_destroy(notify, ISC_FALSE); 12213 } 12214 if (message != NULL) 12215 dns_message_destroy(&message); 12216} 12217 12218struct secure_event { 12219 isc_event_t e; 12220 dns_db_t *db; 12221 isc_uint32_t serial; 12222}; 12223 12224static void 12225update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) { 12226 UNUSED(arg); 12227 dns_zone_log(zone, level, "%s", message); 12228} 12229 12230static isc_result_t 12231sync_secure_journal(dns_zone_t *zone, dns_journal_t *journal, 12232 isc_uint32_t start, isc_uint32_t end, 12233 dns_difftuple_t **soatuplep, dns_diff_t *diff) 12234{ 12235 isc_result_t result; 12236 dns_difftuple_t *tuple = NULL; 12237 dns_diffop_t op = DNS_DIFFOP_ADD; 12238 int n_soa = 0; 12239 12240 REQUIRE(soatuplep != NULL); 12241 12242 if (start == end) 12243 return (DNS_R_UNCHANGED); 12244 12245 CHECK(dns_journal_iter_init(journal, start, end)); 12246 for (result = dns_journal_first_rr(journal); 12247 result == ISC_R_SUCCESS; 12248 result = dns_journal_next_rr(journal)) 12249 { 12250 dns_name_t *name = NULL; 12251 isc_uint32_t ttl; 12252 dns_rdata_t *rdata = NULL; 12253 dns_journal_current_rr(journal, &name, &ttl, &rdata); 12254 12255 if (rdata->type == dns_rdatatype_soa) { 12256 n_soa++; 12257 if (n_soa == 2) { 12258 /* 12259 * Save the latest raw SOA record. 12260 */ 12261 if (*soatuplep != NULL) 12262 dns_difftuple_free(soatuplep); 12263 CHECK(dns_difftuple_create(diff->mctx, 12264 DNS_DIFFOP_ADD, 12265 name, ttl, rdata, 12266 soatuplep)); 12267 } 12268 if (n_soa == 3) 12269 n_soa = 1; 12270 continue; 12271 } 12272 12273 /* Sanity. */ 12274 if (n_soa == 0) { 12275 dns_zone_log(zone->raw, ISC_LOG_ERROR, 12276 "corrupt journal file: '%s'\n", 12277 zone->raw->journal); 12278 return (ISC_R_FAILURE); 12279 } 12280 12281 if (zone->privatetype != 0 && 12282 rdata->type == zone->privatetype) 12283 continue; 12284 12285 if (rdata->type == dns_rdatatype_nsec || 12286 rdata->type == dns_rdatatype_rrsig || 12287 rdata->type == dns_rdatatype_nsec3 || 12288 rdata->type == dns_rdatatype_dnskey || 12289 rdata->type == dns_rdatatype_nsec3param) 12290 continue; 12291 12292 op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD; 12293 12294 CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata, 12295 &tuple)); 12296 dns_diff_appendminimal(diff, &tuple); 12297 } 12298 if (result == ISC_R_NOMORE) 12299 result = ISC_R_SUCCESS; 12300 12301 failure: 12302 return(result); 12303} 12304 12305static isc_result_t 12306sync_secure_db(dns_zone_t *seczone, dns_db_t *secdb, 12307 dns_dbversion_t *secver, dns_diff_t *diff) 12308{ 12309 isc_result_t result; 12310 dns_db_t *rawdb = NULL; 12311 dns_dbversion_t *rawver = NULL; 12312 dns_difftuple_t *tuple = NULL, *next; 12313 12314 REQUIRE(DNS_ZONE_VALID(seczone)); 12315 REQUIRE(inline_secure(seczone)); 12316 12317 if (!seczone->sourceserialset) 12318 return (DNS_R_UNCHANGED); 12319 12320 dns_db_attach(seczone->raw->db, &rawdb); 12321 dns_db_currentversion(rawdb, &rawver); 12322 result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL); 12323 dns_db_closeversion(rawdb, &rawver, ISC_FALSE); 12324 dns_db_detach(&rawdb); 12325 12326 if (result != ISC_R_SUCCESS) 12327 return (result); 12328 12329 for (tuple = ISC_LIST_HEAD(diff->tuples); 12330 tuple != NULL; 12331 tuple = next) 12332 { 12333 next = ISC_LIST_NEXT(tuple, link); 12334 if (tuple->rdata.type == dns_rdatatype_nsec || 12335 tuple->rdata.type == dns_rdatatype_rrsig || 12336 tuple->rdata.type == dns_rdatatype_dnskey || 12337 tuple->rdata.type == dns_rdatatype_nsec3 || 12338 tuple->rdata.type == dns_rdatatype_soa || 12339 tuple->rdata.type == dns_rdatatype_nsec3param) 12340 { 12341 ISC_LIST_UNLINK(diff->tuples, tuple, link); 12342 dns_difftuple_free(&tuple); 12343 } 12344 } 12345 12346 if (ISC_LIST_EMPTY(diff->tuples)) 12347 return (DNS_R_UNCHANGED); 12348 12349 return (ISC_R_SUCCESS); 12350} 12351 12352static void 12353receive_secure_serial(isc_task_t *task, isc_event_t *event) { 12354 isc_result_t result; 12355 dns_journal_t *rjournal = NULL; 12356 isc_uint32_t start, end; 12357 dns_zone_t *zone; 12358 dns_db_t *db = NULL; 12359 dns_dbnode_t *node = NULL; 12360 dns_dbversion_t *newver = NULL, *oldver = NULL; 12361 dns_diff_t diff; 12362 dns_difftuple_t *tuple = NULL, *soatuple = NULL; 12363 dns_update_log_t log = { update_log_cb, NULL }; 12364 isc_time_t timenow; 12365 12366 zone = event->ev_arg; 12367 end = ((struct secure_event *)event)->serial; 12368 isc_event_free(&event); 12369 12370 REQUIRE(inline_secure(zone)); 12371 12372 dns_diff_init(zone->mctx, &diff); 12373 12374 UNUSED(task); 12375 12376 /* 12377 * zone->db may be NULL if the load from disk failed. 12378 */ 12379 if (zone->db == NULL) { 12380 result = ISC_R_FAILURE; 12381 goto failure; 12382 } 12383 12384 /* 12385 * We first attempt to sync the raw zone to the secure zone 12386 * by using the raw zone's journal, applying all the deltas 12387 * from the latest source-serial of the secure zone up to 12388 * the current serial number of the raw zone. 12389 * 12390 * If that fails, then we'll fall back to a direct comparison 12391 * between raw and secure zones. 12392 */ 12393 result = dns_journal_open(zone->raw->mctx, zone->raw->journal, 12394 DNS_JOURNAL_WRITE, &rjournal); 12395 if (result != ISC_R_SUCCESS) 12396 goto failure; 12397 else { 12398 dns_journal_t *sjournal = NULL; 12399 12400 result = dns_journal_open(zone->raw->mctx, zone->journal, 12401 DNS_JOURNAL_READ, &sjournal); 12402 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) 12403 goto failure; 12404 12405 if (!dns_journal_get_sourceserial(rjournal, &start)) { 12406 start = dns_journal_first_serial(rjournal); 12407 dns_journal_set_sourceserial(rjournal, start); 12408 } 12409 if (sjournal != NULL) { 12410 isc_uint32_t serial; 12411 /* 12412 * We read the secure journal first, if that exists 12413 * use its value provided it is greater that from the 12414 * raw journal. 12415 */ 12416 if (dns_journal_get_sourceserial(sjournal, &serial)) { 12417 if (isc_serial_gt(serial, start)) 12418 start = serial; 12419 } 12420 dns_journal_destroy(&sjournal); 12421 } 12422 } 12423 12424 dns_db_attach(zone->db, &db); 12425 dns_db_currentversion(db, &oldver); 12426 CHECK(dns_db_newversion(db, &newver)); 12427 12428 /* 12429 * Try to apply diffs from the raw zone's journal to the secure 12430 * zone. If that fails, we recover by syncing up the databases 12431 * directly. 12432 */ 12433 result = sync_secure_journal(zone, rjournal, start, end, 12434 &soatuple, &diff); 12435 if (result == DNS_R_UNCHANGED) 12436 goto failure; 12437 else if (result != ISC_R_SUCCESS) { 12438 CHECK(sync_secure_db(zone, db, oldver, &diff)); 12439 } 12440 12441 CHECK(dns_diff_apply(&diff, db, newver)); 12442 12443 if (soatuple != NULL) { 12444 isc_uint32_t oldserial, newserial, desired; 12445 12446 CHECK(dns_db_createsoatuple(db, oldver, diff.mctx, 12447 DNS_DIFFOP_DEL, &tuple)); 12448 oldserial = dns_soa_getserial(&tuple->rdata); 12449 newserial = desired = dns_soa_getserial(&soatuple->rdata); 12450 if (!isc_serial_gt(newserial, oldserial)) { 12451 newserial = oldserial + 1; 12452 if (newserial == 0) 12453 newserial++; 12454 dns_soa_setserial(newserial, &soatuple->rdata); 12455 } 12456 CHECK(do_one_tuple(&tuple, db, newver, &diff)); 12457 CHECK(do_one_tuple(&soatuple, db, newver, &diff)); 12458 dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)", 12459 newserial, desired); 12460 } else 12461 CHECK(update_soa_serial(db, newver, &diff, zone->mctx, 12462 zone->updatemethod)); 12463 12464 CHECK(dns_update_signatures(&log, zone, db, oldver, newver, 12465 &diff, zone->sigvalidityinterval)); 12466 12467 CHECK(zone_journal(zone, &diff, &end, "receive_secure_serial")); 12468 12469 dns_journal_set_sourceserial(rjournal, end); 12470 dns_journal_commit(rjournal); 12471 12472 LOCK_ZONE(zone); 12473 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12474 12475 zone->sourceserial = end; 12476 zone->sourceserialset = ISC_TRUE; 12477 zone_needdump(zone, DNS_DUMP_DELAY); 12478 12479 TIME_NOW(&timenow); 12480 zone_settimer(zone, &timenow); 12481 12482 UNLOCK_ZONE(zone); 12483 12484 dns_db_closeversion(db, &oldver, ISC_FALSE); 12485 dns_db_closeversion(db, &newver, ISC_TRUE); 12486 12487 failure: 12488 if (result != ISC_R_SUCCESS) 12489 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s", 12490 dns_result_totext(result)); 12491 if (tuple != NULL) 12492 dns_difftuple_free(&tuple); 12493 if (soatuple != NULL) 12494 dns_difftuple_free(&soatuple); 12495 if (db != NULL) { 12496 if (oldver != NULL) 12497 dns_db_closeversion(db, &oldver, ISC_FALSE); 12498 if (newver != NULL) 12499 dns_db_closeversion(db, &newver, ISC_FALSE); 12500 if (node != NULL) 12501 dns_db_detachnode(db, &node); 12502 dns_db_detach(&db); 12503 } 12504 if (rjournal != NULL) 12505 dns_journal_destroy(&rjournal); 12506 dns_diff_clear(&diff); 12507 dns_zone_idetach(&zone); 12508} 12509 12510static isc_result_t 12511zone_send_secureserial(dns_zone_t *zone, isc_boolean_t locked, 12512 isc_uint32_t serial) 12513{ 12514 isc_event_t *e; 12515 dns_zone_t *dummy = NULL; 12516 12517 e = isc_event_allocate(zone->secure->mctx, zone, 12518 DNS_EVENT_ZONESECURESERIAL, 12519 receive_secure_serial, zone->secure, 12520 sizeof(struct secure_event)); 12521 if (e == NULL) 12522 return (ISC_R_NOMEMORY); 12523 ((struct secure_event *)e)->serial = serial; 12524 if (locked) 12525 zone_iattach(zone->secure, &dummy); 12526 else 12527 dns_zone_iattach(zone->secure, &dummy); 12528 isc_task_send(zone->secure->task, &e); 12529 12530 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); 12531 return (ISC_R_SUCCESS); 12532} 12533 12534static isc_result_t 12535checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 12536 dns_rdataset_t *rdataset, isc_uint32_t oldserial) 12537{ 12538 dns_rdata_soa_t soa; 12539 dns_rdata_t rdata = DNS_RDATA_INIT; 12540 dns_rdatalist_t temprdatalist; 12541 dns_rdataset_t temprdataset; 12542 isc_buffer_t b; 12543 isc_result_t result; 12544 unsigned char buf[DNS_SOA_BUFFERSIZE]; 12545 12546 result = dns_rdataset_first(rdataset); 12547 RUNTIME_CHECK(result == ISC_R_SUCCESS); 12548 dns_rdataset_current(rdataset, &rdata); 12549 dns_rdata_tostruct(&rdata, &soa, NULL); 12550 12551 if (isc_serial_gt(soa.serial, oldserial)) 12552 return (dns_db_addrdataset(db, node, version, 0, rdataset, 0, 12553 NULL)); 12554 /* 12555 * Always bump the serial. 12556 */ 12557 oldserial++; 12558 if (oldserial == 0) 12559 oldserial++; 12560 soa.serial = oldserial; 12561 12562 /* 12563 * Construct a replacement rdataset. 12564 */ 12565 dns_rdata_reset(&rdata); 12566 isc_buffer_init(&b, buf, sizeof(buf)); 12567 result = dns_rdata_fromstruct(&rdata, rdataset->rdclass, 12568 dns_rdatatype_soa, &soa, &b); 12569 RUNTIME_CHECK(result == ISC_R_SUCCESS); 12570 temprdatalist.rdclass = rdata.rdclass; 12571 temprdatalist.type = rdata.type; 12572 temprdatalist.covers = 0; 12573 temprdatalist.ttl = rdataset->ttl; 12574 ISC_LIST_INIT(temprdatalist.rdata); 12575 ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link); 12576 12577 dns_rdataset_init(&temprdataset); 12578 result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset); 12579 RUNTIME_CHECK(result == ISC_R_SUCCESS); 12580 return (dns_db_addrdataset(db, node, version, 0, &temprdataset, 12581 0, NULL)); 12582} 12583 12584static void 12585receive_secure_db(isc_task_t *task, isc_event_t *event) { 12586 isc_result_t result; 12587 dns_zone_t *zone; 12588 dns_db_t *rawdb, *db = NULL; 12589 dns_dbnode_t *rawnode = NULL, *node = NULL; 12590 dns_fixedname_t fname; 12591 dns_name_t *name; 12592 dns_dbiterator_t *dbiterator = NULL; 12593 dns_rdatasetiter_t *rdsit = NULL; 12594 dns_rdataset_t rdataset; 12595 dns_dbversion_t *version = NULL; 12596 isc_time_t loadtime; 12597 unsigned int oldserial = 0; 12598 isc_boolean_t have_oldserial = ISC_FALSE; 12599 12600 UNUSED(task); 12601 12602 zone = event->ev_arg; 12603 rawdb = ((struct secure_event *)event)->db; 12604 isc_event_free(&event); 12605 12606 REQUIRE(inline_secure(zone)); 12607 12608 dns_fixedname_init(&fname); 12609 name = dns_fixedname_name(&fname); 12610 dns_rdataset_init(&rdataset); 12611 12612 TIME_NOW(&loadtime); 12613 if (zone->db != NULL) { 12614 result = dns_db_getsoaserial(zone->db, NULL, &oldserial); 12615 if (result == ISC_R_SUCCESS) 12616 have_oldserial = ISC_TRUE; 12617 } 12618 12619 result = dns_db_create(zone->mctx, zone->db_argv[0], 12620 &zone->origin, dns_dbtype_zone, zone->rdclass, 12621 zone->db_argc - 1, zone->db_argv + 1, &db); 12622 if (result != ISC_R_SUCCESS) 12623 goto failure; 12624 12625 result = dns_db_newversion(db, &version); 12626 if (result != ISC_R_SUCCESS) 12627 goto failure; 12628 12629 result = dns_db_createiterator(rawdb, 0, &dbiterator); 12630 if (result != ISC_R_SUCCESS) 12631 goto failure; 12632 12633 for (result = dns_dbiterator_first(dbiterator); 12634 result == ISC_R_SUCCESS; 12635 result = dns_dbiterator_next(dbiterator)) { 12636 result = dns_dbiterator_current(dbiterator, &rawnode, name); 12637 if (result != ISC_R_SUCCESS) 12638 continue; 12639 12640 result = dns_db_findnode(db, name, ISC_TRUE, &node); 12641 if (result != ISC_R_SUCCESS) 12642 goto failure; 12643 12644 result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit); 12645 if (result != ISC_R_SUCCESS) 12646 goto failure; 12647 12648 for (result = dns_rdatasetiter_first(rdsit); 12649 result == ISC_R_SUCCESS; 12650 result = dns_rdatasetiter_next(rdsit)) { 12651 dns_rdatasetiter_current(rdsit, &rdataset); 12652 if (rdataset.type == dns_rdatatype_nsec || 12653 rdataset.type == dns_rdatatype_rrsig || 12654 rdataset.type == dns_rdatatype_nsec3 || 12655 rdataset.type == dns_rdatatype_dnskey || 12656 rdataset.type == dns_rdatatype_nsec3param) { 12657 dns_rdataset_disassociate(&rdataset); 12658 continue; 12659 } 12660 if (rdataset.type == dns_rdatatype_soa && 12661 have_oldserial) { 12662 result = checkandaddsoa(db, node, version, 12663 &rdataset, oldserial); 12664 } else 12665 result = dns_db_addrdataset(db, node, version, 12666 0, &rdataset, 0, 12667 NULL); 12668 if (result != ISC_R_SUCCESS) 12669 goto failure; 12670 12671 dns_rdataset_disassociate(&rdataset); 12672 } 12673 dns_rdatasetiter_destroy(&rdsit); 12674 dns_db_detachnode(rawdb, &rawnode); 12675 dns_db_detachnode(db, &node); 12676 } 12677 12678 dns_db_closeversion(db, &version, ISC_TRUE); 12679 /* 12680 * Lock hierachy zmgr, raw, zone. 12681 */ 12682 if (inline_secure(zone)) 12683 LOCK_ZONE(zone->raw); 12684 LOCK_ZONE(zone); 12685 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12686 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 12687 zone_needdump(zone, 0); /* XXXMPA */ 12688 UNLOCK_ZONE(zone); 12689 if (inline_secure(zone)) 12690 UNLOCK_ZONE(zone->raw); 12691 12692 failure: 12693 if (result != ISC_R_SUCCESS) 12694 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s", 12695 dns_result_totext(result)); 12696 12697 if (dns_rdataset_isassociated(&rdataset)) 12698 dns_rdataset_disassociate(&rdataset); 12699 if (db != NULL) { 12700 if (node != NULL) 12701 dns_db_detachnode(db, &node); 12702 dns_db_detach(&db); 12703 } 12704 if (rawnode != NULL) 12705 dns_db_detachnode(rawdb, &rawnode); 12706 dns_db_detach(&rawdb); 12707 if (dbiterator != NULL) 12708 dns_dbiterator_destroy(&dbiterator); 12709 dns_zone_idetach(&zone); 12710} 12711 12712static isc_result_t 12713zone_send_securedb(dns_zone_t *zone, isc_boolean_t locked, dns_db_t *db) { 12714 isc_event_t *e; 12715 dns_db_t *dummy = NULL; 12716 dns_zone_t *secure = NULL; 12717 12718 e = isc_event_allocate(zone->secure->mctx, zone, 12719 DNS_EVENT_ZONESECUREDB, 12720 receive_secure_db, zone->secure, 12721 sizeof(struct secure_event)); 12722 if (e == NULL) 12723 return (ISC_R_NOMEMORY); 12724 dns_db_attach(db, &dummy); 12725 ((struct secure_event *)e)->db = dummy; 12726 if (locked) 12727 zone_iattach(zone->secure, &secure); 12728 else 12729 dns_zone_iattach(zone->secure, &secure); 12730 12731 isc_task_send(zone->secure->task, &e); 12732 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); 12733 return (ISC_R_SUCCESS); 12734} 12735 12736isc_result_t 12737dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { 12738 isc_result_t result; 12739 12740 REQUIRE(DNS_ZONE_VALID(zone)); 12741 LOCK_ZONE(zone); 12742 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 12743 result = zone_replacedb(zone, db, dump); 12744 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 12745 UNLOCK_ZONE(zone); 12746 return (result); 12747} 12748 12749static isc_result_t 12750zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { 12751 dns_dbversion_t *ver; 12752 isc_result_t result; 12753 unsigned int soacount = 0; 12754 unsigned int nscount = 0; 12755 12756 /* 12757 * 'zone' and 'zonedb' locked by caller. 12758 */ 12759 REQUIRE(DNS_ZONE_VALID(zone)); 12760 REQUIRE(LOCKED_ZONE(zone)); 12761 12762 result = zone_get_from_db(zone, db, &nscount, &soacount, 12763 NULL, NULL, NULL, NULL, NULL, NULL); 12764 if (result == ISC_R_SUCCESS) { 12765 if (soacount != 1) { 12766 dns_zone_log(zone, ISC_LOG_ERROR, 12767 "has %d SOA records", soacount); 12768 result = DNS_R_BADZONE; 12769 } 12770 if (nscount == 0 && zone->type != dns_zone_key) { 12771 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records"); 12772 result = DNS_R_BADZONE; 12773 } 12774 if (result != ISC_R_SUCCESS) 12775 return (result); 12776 } else { 12777 dns_zone_log(zone, ISC_LOG_ERROR, 12778 "retrieving SOA and NS records failed: %s", 12779 dns_result_totext(result)); 12780 return (result); 12781 } 12782 12783 result = check_nsec3param(zone, db); 12784 if (result != ISC_R_SUCCESS) 12785 return (result); 12786 12787 ver = NULL; 12788 dns_db_currentversion(db, &ver); 12789 12790 /* 12791 * The initial version of a slave zone is always dumped; 12792 * subsequent versions may be journaled instead if this 12793 * is enabled in the configuration. 12794 */ 12795 if (zone->db != NULL && zone->journal != NULL && 12796 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 12797 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) 12798 { 12799 isc_uint32_t serial, oldserial; 12800 12801 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs"); 12802 12803 result = dns_db_getsoaserial(db, ver, &serial); 12804 if (result != ISC_R_SUCCESS) { 12805 dns_zone_log(zone, ISC_LOG_ERROR, 12806 "ixfr-from-differences: unable to get " 12807 "new serial"); 12808 goto fail; 12809 } 12810 12811 /* 12812 * This is checked in zone_postload() for master zones. 12813 */ 12814 result = zone_get_from_db(zone, zone->db, NULL, NULL, 12815 &oldserial, NULL, NULL, NULL, NULL, 12816 NULL); 12817 RUNTIME_CHECK(result == ISC_R_SUCCESS); 12818 if ((zone->type == dns_zone_slave || 12819 (zone->type == dns_zone_redirect && 12820 zone->masters != NULL)) 12821 && !isc_serial_gt(serial, oldserial)) { 12822 isc_uint32_t serialmin, serialmax; 12823 serialmin = (oldserial + 1) & 0xffffffffU; 12824 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; 12825 dns_zone_log(zone, ISC_LOG_ERROR, 12826 "ixfr-from-differences: failed: " 12827 "new serial (%u) out of range [%u - %u]", 12828 serial, serialmin, serialmax); 12829 result = ISC_R_RANGE; 12830 goto fail; 12831 } 12832 12833 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL, 12834 zone->journal); 12835 if (result != ISC_R_SUCCESS) 12836 goto fail; 12837 if (dump) 12838 zone_needdump(zone, DNS_DUMP_DELAY); 12839 else if (zone->journalsize != -1) { 12840 result = dns_journal_compact(zone->mctx, zone->journal, 12841 serial, zone->journalsize); 12842 switch (result) { 12843 case ISC_R_SUCCESS: 12844 case ISC_R_NOSPACE: 12845 case ISC_R_NOTFOUND: 12846 dns_zone_log(zone, ISC_LOG_DEBUG(3), 12847 "dns_journal_compact: %s", 12848 dns_result_totext(result)); 12849 break; 12850 default: 12851 dns_zone_log(zone, ISC_LOG_ERROR, 12852 "dns_journal_compact failed: %s", 12853 dns_result_totext(result)); 12854 break; 12855 } 12856 } 12857 if (zone->type == dns_zone_master && inline_raw(zone)) 12858 zone_send_secureserial(zone, ISC_FALSE, serial); 12859 } else { 12860 if (dump && zone->masterfile != NULL) { 12861 /* 12862 * If DNS_ZONEFLG_FORCEXFER was set we don't want 12863 * to keep the old masterfile. 12864 */ 12865 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) && 12866 remove(zone->masterfile) < 0 && errno != ENOENT) { 12867 char strbuf[ISC_STRERRORSIZE]; 12868 isc__strerror(errno, strbuf, sizeof(strbuf)); 12869 isc_log_write(dns_lctx, 12870 DNS_LOGCATEGORY_GENERAL, 12871 DNS_LOGMODULE_ZONE, 12872 ISC_LOG_WARNING, 12873 "unable to remove masterfile " 12874 "'%s': '%s'", 12875 zone->masterfile, strbuf); 12876 } 12877 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) 12878 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY); 12879 else 12880 zone_needdump(zone, 0); 12881 } 12882 if (dump && zone->journal != NULL) { 12883 /* 12884 * The in-memory database just changed, and 12885 * because 'dump' is set, it didn't change by 12886 * being loaded from disk. Also, we have not 12887 * journaled diffs for this change. 12888 * Therefore, the on-disk journal is missing 12889 * the deltas for this change. Since it can 12890 * no longer be used to bring the zone 12891 * up-to-date, it is useless and should be 12892 * removed. 12893 */ 12894 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 12895 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 12896 "removing journal file"); 12897 if (remove(zone->journal) < 0 && errno != ENOENT) { 12898 char strbuf[ISC_STRERRORSIZE]; 12899 isc__strerror(errno, strbuf, sizeof(strbuf)); 12900 isc_log_write(dns_lctx, 12901 DNS_LOGCATEGORY_GENERAL, 12902 DNS_LOGMODULE_ZONE, 12903 ISC_LOG_WARNING, 12904 "unable to remove journal " 12905 "'%s': '%s'", 12906 zone->journal, strbuf); 12907 } 12908 } 12909 12910 if (inline_raw(zone)) 12911 zone_send_securedb(zone, ISC_FALSE, db); 12912 } 12913 12914 dns_db_closeversion(db, &ver, ISC_FALSE); 12915 12916 dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database"); 12917 12918 if (zone->db != NULL) 12919 zone_detachdb(zone); 12920 zone_attachdb(zone, db); 12921 dns_db_settask(zone->db, zone->task); 12922 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY); 12923 return (ISC_R_SUCCESS); 12924 12925 fail: 12926 dns_db_closeversion(db, &ver, ISC_FALSE); 12927 return (result); 12928} 12929 12930/* The caller must hold the dblock as a writer. */ 12931static inline void 12932zone_attachdb(dns_zone_t *zone, dns_db_t *db) { 12933 REQUIRE(zone->db == NULL && db != NULL); 12934 12935 dns_db_attach(db, &zone->db); 12936 if (zone->acache != NULL) { 12937 isc_result_t result; 12938 result = dns_acache_setdb(zone->acache, db); 12939 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { 12940 UNEXPECTED_ERROR(__FILE__, __LINE__, 12941 "dns_acache_setdb() failed: %s", 12942 isc_result_totext(result)); 12943 } 12944 } 12945} 12946 12947/* The caller must hold the dblock as a writer. */ 12948static inline void 12949zone_detachdb(dns_zone_t *zone) { 12950 REQUIRE(zone->db != NULL); 12951 12952 if (zone->acache != NULL) 12953 (void)dns_acache_putdb(zone->acache, zone->db); 12954 dns_db_detach(&zone->db); 12955} 12956 12957static void 12958zone_xfrdone(dns_zone_t *zone, isc_result_t result) { 12959 isc_time_t now; 12960 isc_boolean_t again = ISC_FALSE; 12961 unsigned int soacount; 12962 unsigned int nscount; 12963 isc_uint32_t serial, refresh, retry, expire, minimum; 12964 isc_result_t xfrresult = result; 12965 isc_boolean_t free_needed; 12966 12967 REQUIRE(DNS_ZONE_VALID(zone)); 12968 12969 dns_zone_log(zone, ISC_LOG_DEBUG(1), 12970 "zone transfer finished: %s", dns_result_totext(result)); 12971 12972 LOCK_ZONE(zone); 12973 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0); 12974 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 12975 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 12976 12977 TIME_NOW(&now); 12978 switch (result) { 12979 case ISC_R_SUCCESS: 12980 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 12981 /*FALLTHROUGH*/ 12982 case DNS_R_UPTODATE: 12983 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER); 12984 /* 12985 * Has the zone expired underneath us? 12986 */ 12987 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 12988 if (zone->db == NULL) { 12989 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 12990 goto same_master; 12991 } 12992 12993 /* 12994 * Update the zone structure's data from the actual 12995 * SOA received. 12996 */ 12997 nscount = 0; 12998 soacount = 0; 12999 INSIST(zone->db != NULL); 13000 result = zone_get_from_db(zone, zone->db, &nscount, 13001 &soacount, &serial, &refresh, 13002 &retry, &expire, &minimum, NULL); 13003 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 13004 if (result == ISC_R_SUCCESS) { 13005 if (soacount != 1) 13006 dns_zone_log(zone, ISC_LOG_ERROR, 13007 "transferred zone " 13008 "has %d SOA record%s", soacount, 13009 (soacount != 0) ? "s" : ""); 13010 if (nscount == 0) { 13011 dns_zone_log(zone, ISC_LOG_ERROR, 13012 "transferred zone " 13013 "has no NS records"); 13014 if (DNS_ZONE_FLAG(zone, 13015 DNS_ZONEFLG_HAVETIMERS)) { 13016 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 13017 zone->retry = DNS_ZONE_DEFAULTRETRY; 13018 } 13019 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 13020 zone_unload(zone); 13021 goto next_master; 13022 } 13023 zone->refresh = RANGE(refresh, zone->minrefresh, 13024 zone->maxrefresh); 13025 zone->retry = RANGE(retry, zone->minretry, 13026 zone->maxretry); 13027 zone->expire = RANGE(expire, 13028 zone->refresh + zone->retry, 13029 DNS_MAX_EXPIRE); 13030 zone->minimum = minimum; 13031 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 13032 } 13033 13034 /* 13035 * Set our next update/expire times. 13036 */ 13037 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 13038 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 13039 zone->refreshtime = now; 13040 DNS_ZONE_TIME_ADD(&now, zone->expire, 13041 &zone->expiretime); 13042 } else { 13043 DNS_ZONE_JITTER_ADD(&now, zone->refresh, 13044 &zone->refreshtime); 13045 DNS_ZONE_TIME_ADD(&now, zone->expire, 13046 &zone->expiretime); 13047 } 13048 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) { 13049 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")]; 13050 if (zone->tsigkey != NULL) { 13051 char namebuf[DNS_NAME_FORMATSIZE]; 13052 dns_name_format(&zone->tsigkey->name, namebuf, 13053 sizeof(namebuf)); 13054 snprintf(buf, sizeof(buf), ": TSIG '%s'", 13055 namebuf); 13056 } else 13057 buf[0] = '\0'; 13058 dns_zone_log(zone, ISC_LOG_INFO, 13059 "transferred serial %u%s", 13060 serial, buf); 13061 if (inline_raw(zone)) 13062 zone_send_secureserial(zone, ISC_FALSE, serial); 13063 } 13064 13065 /* 13066 * This is not necessary if we just performed a AXFR 13067 * however it is necessary for an IXFR / UPTODATE and 13068 * won't hurt with an AXFR. 13069 */ 13070 if (zone->masterfile != NULL || zone->journal != NULL) { 13071 result = ISC_R_FAILURE; 13072 if (zone->journal != NULL) 13073 result = isc_file_settime(zone->journal, &now); 13074 if (result != ISC_R_SUCCESS && 13075 zone->masterfile != NULL) 13076 result = isc_file_settime(zone->masterfile, 13077 &now); 13078 /* Someone removed the file from underneath us! */ 13079 if (result == ISC_R_FILENOTFOUND && 13080 zone->masterfile != NULL) { 13081 unsigned int delay = DNS_DUMP_DELAY; 13082 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY)) 13083 delay = 0; 13084 zone_needdump(zone, delay); 13085 } else if (result != ISC_R_SUCCESS) 13086 dns_zone_log(zone, ISC_LOG_ERROR, 13087 "transfer: could not set file " 13088 "modification time of '%s': %s", 13089 zone->masterfile, 13090 dns_result_totext(result)); 13091 } 13092 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY); 13093 inc_stats(zone, dns_zonestatscounter_xfrsuccess); 13094 break; 13095 13096 case DNS_R_BADIXFR: 13097 /* Force retry with AXFR. */ 13098 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR); 13099 goto same_master; 13100 13101 default: 13102 next_master: 13103 /* 13104 * Skip to next failed / untried master. 13105 */ 13106 do { 13107 zone->curmaster++; 13108 } while (zone->curmaster < zone->masterscnt && 13109 zone->mastersok[zone->curmaster]); 13110 /* FALLTHROUGH */ 13111 same_master: 13112 if (zone->curmaster >= zone->masterscnt) { 13113 zone->curmaster = 0; 13114 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 13115 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 13116 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 13117 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 13118 while (zone->curmaster < zone->masterscnt && 13119 zone->mastersok[zone->curmaster]) 13120 zone->curmaster++; 13121 again = ISC_TRUE; 13122 } else 13123 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 13124 } else { 13125 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 13126 again = ISC_TRUE; 13127 } 13128 inc_stats(zone, dns_zonestatscounter_xfrfail); 13129 break; 13130 } 13131 zone_settimer(zone, &now); 13132 13133 /* 13134 * If creating the transfer object failed, zone->xfr is NULL. 13135 * Otherwise, we are called as the done callback of a zone 13136 * transfer object that just entered its shutting-down 13137 * state. Since we are no longer responsible for shutting 13138 * it down, we can detach our reference. 13139 */ 13140 if (zone->xfr != NULL) 13141 dns_xfrin_detach(&zone->xfr); 13142 13143 if (zone->tsigkey != NULL) 13144 dns_tsigkey_detach(&zone->tsigkey); 13145 13146 /* 13147 * Handle any deferred journal compaction. 13148 */ 13149 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) { 13150 result = dns_journal_compact(zone->mctx, zone->journal, 13151 zone->compact_serial, 13152 zone->journalsize); 13153 switch (result) { 13154 case ISC_R_SUCCESS: 13155 case ISC_R_NOSPACE: 13156 case ISC_R_NOTFOUND: 13157 dns_zone_log(zone, ISC_LOG_DEBUG(3), 13158 "dns_journal_compact: %s", 13159 dns_result_totext(result)); 13160 break; 13161 default: 13162 dns_zone_log(zone, ISC_LOG_ERROR, 13163 "dns_journal_compact failed: %s", 13164 dns_result_totext(result)); 13165 break; 13166 } 13167 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 13168 } 13169 13170 /* 13171 * This transfer finishing freed up a transfer quota slot. 13172 * Let any other zones waiting for quota have it. 13173 */ 13174 UNLOCK_ZONE(zone); 13175 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 13176 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink); 13177 zone->statelist = NULL; 13178 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE); 13179 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 13180 LOCK_ZONE(zone); 13181 13182 /* 13183 * Retry with a different server if necessary. 13184 */ 13185 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 13186 queue_soa_query(zone); 13187 13188 INSIST(zone->irefs > 0); 13189 zone->irefs--; 13190 free_needed = exit_check(zone); 13191 UNLOCK_ZONE(zone); 13192 if (free_needed) 13193 zone_free(zone); 13194} 13195 13196static void 13197zone_loaddone(void *arg, isc_result_t result) { 13198 static char me[] = "zone_loaddone"; 13199 dns_load_t *load = arg; 13200 dns_zone_t *zone; 13201 isc_result_t tresult; 13202 13203 REQUIRE(DNS_LOAD_VALID(load)); 13204 zone = load->zone; 13205 13206 ENTER; 13207 13208 tresult = dns_db_endload(load->db, &load->callbacks.add_private); 13209 if (tresult != ISC_R_SUCCESS && 13210 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)) 13211 result = tresult; 13212 13213 /* 13214 * Lock hierachy zmgr, raw, zone. 13215 */ 13216 if (inline_secure(zone)) 13217 LOCK_ZONE(zone->raw); 13218 LOCK_ZONE(load->zone); 13219 (void)zone_postload(load->zone, load->db, load->loadtime, result); 13220 zonemgr_putio(&load->zone->readio); 13221 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING); 13222 zone_idetach(&load->callbacks.zone); 13223 /* 13224 * Leave the zone frozen if the reload fails. 13225 */ 13226 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) && 13227 DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW)) 13228 zone->update_disabled = ISC_FALSE; 13229 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW); 13230 UNLOCK_ZONE(load->zone); 13231 if (inline_secure(zone)) 13232 UNLOCK_ZONE(zone->raw); 13233 13234 load->magic = 0; 13235 dns_db_detach(&load->db); 13236 if (load->zone->lctx != NULL) 13237 dns_loadctx_detach(&load->zone->lctx); 13238 dns_zone_idetach(&load->zone); 13239 isc_mem_putanddetach(&load->mctx, load, sizeof(*load)); 13240} 13241 13242void 13243dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) { 13244 REQUIRE(DNS_ZONE_VALID(zone)); 13245 REQUIRE(table != NULL); 13246 REQUIRE(*table == NULL); 13247 13248 LOCK_ZONE(zone); 13249 if (zone->ssutable != NULL) 13250 dns_ssutable_attach(zone->ssutable, table); 13251 UNLOCK_ZONE(zone); 13252} 13253 13254void 13255dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) { 13256 REQUIRE(DNS_ZONE_VALID(zone)); 13257 13258 LOCK_ZONE(zone); 13259 if (zone->ssutable != NULL) 13260 dns_ssutable_detach(&zone->ssutable); 13261 if (table != NULL) 13262 dns_ssutable_attach(table, &zone->ssutable); 13263 UNLOCK_ZONE(zone); 13264} 13265 13266void 13267dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) { 13268 REQUIRE(DNS_ZONE_VALID(zone)); 13269 13270 zone->sigvalidityinterval = interval; 13271} 13272 13273isc_uint32_t 13274dns_zone_getsigvalidityinterval(dns_zone_t *zone) { 13275 REQUIRE(DNS_ZONE_VALID(zone)); 13276 13277 return (zone->sigvalidityinterval); 13278} 13279 13280void 13281dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) { 13282 REQUIRE(DNS_ZONE_VALID(zone)); 13283 13284 zone->sigresigninginterval = interval; 13285} 13286 13287isc_uint32_t 13288dns_zone_getsigresigninginterval(dns_zone_t *zone) { 13289 REQUIRE(DNS_ZONE_VALID(zone)); 13290 13291 return (zone->sigresigninginterval); 13292} 13293 13294static void 13295queue_xfrin(dns_zone_t *zone) { 13296 const char me[] = "queue_xfrin"; 13297 isc_result_t result; 13298 dns_zonemgr_t *zmgr = zone->zmgr; 13299 13300 ENTER; 13301 13302 INSIST(zone->statelist == NULL); 13303 13304 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 13305 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink); 13306 LOCK_ZONE(zone); 13307 zone->irefs++; 13308 UNLOCK_ZONE(zone); 13309 zone->statelist = &zmgr->waiting_for_xfrin; 13310 result = zmgr_start_xfrin_ifquota(zmgr, zone); 13311 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 13312 13313 if (result == ISC_R_QUOTA) { 13314 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 13315 "zone transfer deferred due to quota"); 13316 } else if (result != ISC_R_SUCCESS) { 13317 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, 13318 "starting zone transfer: %s", 13319 isc_result_totext(result)); 13320 } 13321} 13322 13323/* 13324 * This event callback is called when a zone has received 13325 * any necessary zone transfer quota. This is the time 13326 * to go ahead and start the transfer. 13327 */ 13328static void 13329got_transfer_quota(isc_task_t *task, isc_event_t *event) { 13330 isc_result_t result = ISC_R_SUCCESS; 13331 dns_peer_t *peer = NULL; 13332 char master[ISC_SOCKADDR_FORMATSIZE]; 13333 char source[ISC_SOCKADDR_FORMATSIZE]; 13334 dns_rdatatype_t xfrtype; 13335 dns_zone_t *zone = event->ev_arg; 13336 isc_netaddr_t masterip; 13337 isc_sockaddr_t sourceaddr; 13338 isc_sockaddr_t masteraddr; 13339 isc_time_t now; 13340 const char *soa_before = ""; 13341 13342 UNUSED(task); 13343 13344 INSIST(task == zone->task); 13345 13346 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 13347 result = ISC_R_CANCELED; 13348 goto cleanup; 13349 } 13350 13351 TIME_NOW(&now); 13352 13353 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 13354 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, 13355 &zone->sourceaddr, &now)) 13356 { 13357 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 13358 dns_zone_log(zone, ISC_LOG_INFO, 13359 "got_transfer_quota: skipping zone transfer as " 13360 "master %s (source %s) is unreachable (cached)", 13361 master, source); 13362 result = ISC_R_CANCELED; 13363 goto cleanup; 13364 } 13365 13366 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 13367 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer); 13368 13369 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) 13370 soa_before = "SOA before "; 13371 /* 13372 * Decide whether we should request IXFR or AXFR. 13373 */ 13374 if (zone->db == NULL) { 13375 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13376 "no database exists yet, requesting AXFR of " 13377 "initial version from %s", master); 13378 xfrtype = dns_rdatatype_axfr; 13379 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { 13380 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13381 "forced reload, requesting AXFR of " 13382 "initial version from %s", master); 13383 xfrtype = dns_rdatatype_axfr; 13384 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) { 13385 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13386 "retrying with AXFR from %s due to " 13387 "previous IXFR failure", master); 13388 xfrtype = dns_rdatatype_axfr; 13389 LOCK_ZONE(zone); 13390 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR); 13391 UNLOCK_ZONE(zone); 13392 } else { 13393 isc_boolean_t use_ixfr = ISC_TRUE; 13394 if (peer != NULL) 13395 result = dns_peer_getrequestixfr(peer, &use_ixfr); 13396 if (peer == NULL || result != ISC_R_SUCCESS) 13397 use_ixfr = zone->requestixfr; 13398 if (use_ixfr == ISC_FALSE) { 13399 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13400 "IXFR disabled, requesting %sAXFR from %s", 13401 soa_before, master); 13402 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) 13403 xfrtype = dns_rdatatype_soa; 13404 else 13405 xfrtype = dns_rdatatype_axfr; 13406 } else { 13407 dns_zone_log(zone, ISC_LOG_DEBUG(1), 13408 "requesting IXFR from %s", master); 13409 xfrtype = dns_rdatatype_ixfr; 13410 } 13411 } 13412 13413 /* 13414 * Determine if we should attempt to sign the request with TSIG. 13415 */ 13416 result = ISC_R_NOTFOUND; 13417 /* 13418 * First, look for a tsig key in the master statement, then 13419 * try for a server key. 13420 */ 13421 if ((zone->masterkeynames != NULL) && 13422 (zone->masterkeynames[zone->curmaster] != NULL)) { 13423 dns_view_t *view = dns_zone_getview(zone); 13424 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 13425 result = dns_view_gettsig(view, keyname, &zone->tsigkey); 13426 } 13427 if (zone->tsigkey == NULL) 13428 result = dns_view_getpeertsig(zone->view, &masterip, 13429 &zone->tsigkey); 13430 13431 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 13432 dns_zone_log(zone, ISC_LOG_ERROR, 13433 "could not get TSIG key for zone transfer: %s", 13434 isc_result_totext(result)); 13435 } 13436 13437 LOCK_ZONE(zone); 13438 masteraddr = zone->masteraddr; 13439 sourceaddr = zone->sourceaddr; 13440 UNLOCK_ZONE(zone); 13441 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr)); 13442 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr, 13443 zone->tsigkey, zone->mctx, 13444 zone->zmgr->timermgr, zone->zmgr->socketmgr, 13445 zone->task, zone_xfrdone, &zone->xfr); 13446 if (result == ISC_R_SUCCESS) { 13447 LOCK_ZONE(zone); 13448 if (xfrtype == dns_rdatatype_axfr) { 13449 if (isc_sockaddr_pf(&masteraddr) == PF_INET) 13450 inc_stats(zone, dns_zonestatscounter_axfrreqv4); 13451 else 13452 inc_stats(zone, dns_zonestatscounter_axfrreqv6); 13453 } else if (xfrtype == dns_rdatatype_ixfr) { 13454 if (isc_sockaddr_pf(&masteraddr) == PF_INET) 13455 inc_stats(zone, dns_zonestatscounter_ixfrreqv4); 13456 else 13457 inc_stats(zone, dns_zonestatscounter_ixfrreqv6); 13458 } 13459 UNLOCK_ZONE(zone); 13460 } 13461 cleanup: 13462 /* 13463 * Any failure in this function is handled like a failed 13464 * zone transfer. This ensures that we get removed from 13465 * zmgr->xfrin_in_progress. 13466 */ 13467 if (result != ISC_R_SUCCESS) 13468 zone_xfrdone(zone, result); 13469 13470 isc_event_free(&event); 13471} 13472 13473/* 13474 * Update forwarding support. 13475 */ 13476 13477static void 13478forward_destroy(dns_forward_t *forward) { 13479 13480 forward->magic = 0; 13481 if (forward->request != NULL) 13482 dns_request_destroy(&forward->request); 13483 if (forward->msgbuf != NULL) 13484 isc_buffer_free(&forward->msgbuf); 13485 if (forward->zone != NULL) { 13486 LOCK(&forward->zone->lock); 13487 if (ISC_LINK_LINKED(forward, link)) 13488 ISC_LIST_UNLINK(forward->zone->forwards, forward, link); 13489 UNLOCK(&forward->zone->lock); 13490 dns_zone_idetach(&forward->zone); 13491 } 13492 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward)); 13493} 13494 13495static isc_result_t 13496sendtomaster(dns_forward_t *forward) { 13497 isc_result_t result; 13498 isc_sockaddr_t src; 13499 13500 LOCK_ZONE(forward->zone); 13501 13502 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) { 13503 UNLOCK_ZONE(forward->zone); 13504 return (ISC_R_CANCELED); 13505 } 13506 13507 if (forward->which >= forward->zone->masterscnt) { 13508 UNLOCK_ZONE(forward->zone); 13509 return (ISC_R_NOMORE); 13510 } 13511 13512 forward->addr = forward->zone->masters[forward->which]; 13513 /* 13514 * Always use TCP regardless of whether the original update 13515 * used TCP. 13516 * XXX The timeout may but a bit small if we are far down a 13517 * transfer graph and the master has to try several masters. 13518 */ 13519 switch (isc_sockaddr_pf(&forward->addr)) { 13520 case PF_INET: 13521 src = forward->zone->xfrsource4; 13522 break; 13523 case PF_INET6: 13524 src = forward->zone->xfrsource6; 13525 break; 13526 default: 13527 result = ISC_R_NOTIMPLEMENTED; 13528 goto unlock; 13529 } 13530 result = dns_request_createraw(forward->zone->view->requestmgr, 13531 forward->msgbuf, 13532 &src, &forward->addr, 13533 DNS_REQUESTOPT_TCP, 15 /* XXX */, 13534 forward->zone->task, 13535 forward_callback, forward, 13536 &forward->request); 13537 if (result == ISC_R_SUCCESS) { 13538 if (!ISC_LINK_LINKED(forward, link)) 13539 ISC_LIST_APPEND(forward->zone->forwards, forward, link); 13540 } 13541 13542 unlock: 13543 UNLOCK_ZONE(forward->zone); 13544 return (result); 13545} 13546 13547static void 13548forward_callback(isc_task_t *task, isc_event_t *event) { 13549 const char me[] = "forward_callback"; 13550 dns_requestevent_t *revent = (dns_requestevent_t *)event; 13551 dns_message_t *msg = NULL; 13552 char master[ISC_SOCKADDR_FORMATSIZE]; 13553 isc_result_t result; 13554 dns_forward_t *forward; 13555 dns_zone_t *zone; 13556 13557 UNUSED(task); 13558 13559 forward = revent->ev_arg; 13560 INSIST(DNS_FORWARD_VALID(forward)); 13561 zone = forward->zone; 13562 INSIST(DNS_ZONE_VALID(zone)); 13563 13564 ENTER; 13565 13566 isc_sockaddr_format(&forward->addr, master, sizeof(master)); 13567 13568 if (revent->result != ISC_R_SUCCESS) { 13569 dns_zone_log(zone, ISC_LOG_INFO, 13570 "could not forward dynamic update to %s: %s", 13571 master, dns_result_totext(revent->result)); 13572 goto next_master; 13573 } 13574 13575 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 13576 if (result != ISC_R_SUCCESS) 13577 goto next_master; 13578 13579 result = dns_request_getresponse(revent->request, msg, 13580 DNS_MESSAGEPARSE_PRESERVEORDER | 13581 DNS_MESSAGEPARSE_CLONEBUFFER); 13582 if (result != ISC_R_SUCCESS) 13583 goto next_master; 13584 13585 switch (msg->rcode) { 13586 /* 13587 * Pass these rcodes back to client. 13588 */ 13589 case dns_rcode_noerror: 13590 case dns_rcode_yxdomain: 13591 case dns_rcode_yxrrset: 13592 case dns_rcode_nxrrset: 13593 case dns_rcode_refused: 13594 case dns_rcode_nxdomain: 13595 break; 13596 13597 /* These should not occur if the masters/zone are valid. */ 13598 case dns_rcode_notzone: 13599 case dns_rcode_notauth: { 13600 char rcode[128]; 13601 isc_buffer_t rb; 13602 13603 isc_buffer_init(&rb, rcode, sizeof(rcode)); 13604 (void)dns_rcode_totext(msg->rcode, &rb); 13605 dns_zone_log(zone, ISC_LOG_WARNING, 13606 "forwarding dynamic update: " 13607 "unexpected response: master %s returned: %.*s", 13608 master, (int)rb.used, rcode); 13609 goto next_master; 13610 } 13611 13612 /* Try another server for these rcodes. */ 13613 case dns_rcode_formerr: 13614 case dns_rcode_servfail: 13615 case dns_rcode_notimp: 13616 case dns_rcode_badvers: 13617 default: 13618 goto next_master; 13619 } 13620 13621 /* call callback */ 13622 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg); 13623 msg = NULL; 13624 dns_request_destroy(&forward->request); 13625 forward_destroy(forward); 13626 isc_event_free(&event); 13627 return; 13628 13629 next_master: 13630 if (msg != NULL) 13631 dns_message_destroy(&msg); 13632 isc_event_free(&event); 13633 forward->which++; 13634 dns_request_destroy(&forward->request); 13635 result = sendtomaster(forward); 13636 if (result != ISC_R_SUCCESS) { 13637 /* call callback */ 13638 dns_zone_log(zone, ISC_LOG_DEBUG(3), 13639 "exhausted dynamic update forwarder list"); 13640 (forward->callback)(forward->callback_arg, result, NULL); 13641 forward_destroy(forward); 13642 } 13643} 13644 13645isc_result_t 13646dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg, 13647 dns_updatecallback_t callback, void *callback_arg) 13648{ 13649 dns_forward_t *forward; 13650 isc_result_t result; 13651 isc_region_t *mr; 13652 13653 REQUIRE(DNS_ZONE_VALID(zone)); 13654 REQUIRE(msg != NULL); 13655 REQUIRE(callback != NULL); 13656 13657 forward = isc_mem_get(zone->mctx, sizeof(*forward)); 13658 if (forward == NULL) 13659 return (ISC_R_NOMEMORY); 13660 13661 forward->request = NULL; 13662 forward->zone = NULL; 13663 forward->msgbuf = NULL; 13664 forward->which = 0; 13665 forward->mctx = 0; 13666 forward->callback = callback; 13667 forward->callback_arg = callback_arg; 13668 ISC_LINK_INIT(forward, link); 13669 forward->magic = FORWARD_MAGIC; 13670 13671 mr = dns_message_getrawmessage(msg); 13672 if (mr == NULL) { 13673 result = ISC_R_UNEXPECTEDEND; 13674 goto cleanup; 13675 } 13676 13677 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length); 13678 if (result != ISC_R_SUCCESS) 13679 goto cleanup; 13680 result = isc_buffer_copyregion(forward->msgbuf, mr); 13681 if (result != ISC_R_SUCCESS) 13682 goto cleanup; 13683 13684 isc_mem_attach(zone->mctx, &forward->mctx); 13685 dns_zone_iattach(zone, &forward->zone); 13686 result = sendtomaster(forward); 13687 13688 cleanup: 13689 if (result != ISC_R_SUCCESS) { 13690 forward_destroy(forward); 13691 } 13692 return (result); 13693} 13694 13695isc_result_t 13696dns_zone_next(dns_zone_t *zone, dns_zone_t **next) { 13697 REQUIRE(DNS_ZONE_VALID(zone)); 13698 REQUIRE(next != NULL && *next == NULL); 13699 13700 *next = ISC_LIST_NEXT(zone, link); 13701 if (*next == NULL) 13702 return (ISC_R_NOMORE); 13703 else 13704 return (ISC_R_SUCCESS); 13705} 13706 13707isc_result_t 13708dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) { 13709 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13710 REQUIRE(first != NULL && *first == NULL); 13711 13712 *first = ISC_LIST_HEAD(zmgr->zones); 13713 if (*first == NULL) 13714 return (ISC_R_NOMORE); 13715 else 13716 return (ISC_R_SUCCESS); 13717} 13718 13719/*** 13720 *** Zone manager. 13721 ***/ 13722 13723isc_result_t 13724dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, 13725 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, 13726 dns_zonemgr_t **zmgrp) 13727{ 13728 dns_zonemgr_t *zmgr; 13729 isc_result_t result; 13730 isc_interval_t interval; 13731 13732 zmgr = isc_mem_get(mctx, sizeof(*zmgr)); 13733 if (zmgr == NULL) 13734 return (ISC_R_NOMEMORY); 13735 zmgr->mctx = NULL; 13736 zmgr->refs = 1; 13737 isc_mem_attach(mctx, &zmgr->mctx); 13738 zmgr->taskmgr = taskmgr; 13739 zmgr->timermgr = timermgr; 13740 zmgr->socketmgr = socketmgr; 13741 zmgr->zonetasks = NULL; 13742 zmgr->loadtasks = NULL; 13743 zmgr->task = NULL; 13744 zmgr->rl = NULL; 13745 ISC_LIST_INIT(zmgr->zones); 13746 ISC_LIST_INIT(zmgr->waiting_for_xfrin); 13747 ISC_LIST_INIT(zmgr->xfrin_in_progress); 13748 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable)); 13749 result = isc_rwlock_init(&zmgr->rwlock, 0, 0); 13750 if (result != ISC_R_SUCCESS) 13751 goto free_mem; 13752 13753 zmgr->transfersin = 10; 13754 zmgr->transfersperns = 2; 13755 13756 /* Unreachable lock. */ 13757 result = isc_rwlock_init(&zmgr->urlock, 0, 0); 13758 if (result != ISC_R_SUCCESS) 13759 goto free_rwlock; 13760 13761 /* Create a single task for queueing of SOA queries. */ 13762 result = isc_task_create(taskmgr, 1, &zmgr->task); 13763 if (result != ISC_R_SUCCESS) 13764 goto free_urlock; 13765 13766 isc_task_setname(zmgr->task, "zmgr", zmgr); 13767 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 13768 &zmgr->rl); 13769 if (result != ISC_R_SUCCESS) 13770 goto free_task; 13771 13772 /* default to 20 refresh queries / notifies per second. */ 13773 isc_interval_set(&interval, 0, 1000000000/2); 13774 result = isc_ratelimiter_setinterval(zmgr->rl, &interval); 13775 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13776 isc_ratelimiter_setpertic(zmgr->rl, 10); 13777 13778 zmgr->iolimit = 1; 13779 zmgr->ioactive = 0; 13780 ISC_LIST_INIT(zmgr->high); 13781 ISC_LIST_INIT(zmgr->low); 13782 13783 result = isc_mutex_init(&zmgr->iolock); 13784 if (result != ISC_R_SUCCESS) 13785 goto free_rl; 13786 13787 zmgr->magic = ZONEMGR_MAGIC; 13788 13789 *zmgrp = zmgr; 13790 return (ISC_R_SUCCESS); 13791 13792#if 0 13793 free_iolock: 13794 DESTROYLOCK(&zmgr->iolock); 13795#endif 13796 free_rl: 13797 isc_ratelimiter_detach(&zmgr->rl); 13798 free_task: 13799 isc_task_detach(&zmgr->task); 13800 free_urlock: 13801 isc_rwlock_destroy(&zmgr->urlock); 13802 free_rwlock: 13803 isc_rwlock_destroy(&zmgr->rwlock); 13804 free_mem: 13805 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); 13806 isc_mem_detach(&mctx); 13807 return (result); 13808} 13809 13810isc_result_t 13811dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 13812 isc_result_t result; 13813 13814 REQUIRE(DNS_ZONE_VALID(zone)); 13815 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13816 13817 if (zmgr->zonetasks == NULL) 13818 return (ISC_R_FAILURE); 13819 13820 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 13821 LOCK_ZONE(zone); 13822 REQUIRE(zone->task == NULL); 13823 REQUIRE(zone->timer == NULL); 13824 REQUIRE(zone->zmgr == NULL); 13825 13826 isc_taskpool_gettask(zmgr->zonetasks, &zone->task); 13827 isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask); 13828 13829 /* 13830 * Set the task name. The tag will arbitrarily point to one 13831 * of the zones sharing the task (in practice, the one 13832 * to be managed last). 13833 */ 13834 isc_task_setname(zone->task, "zone", zone); 13835 isc_task_setname(zone->loadtask, "loadzone", zone); 13836 13837 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, 13838 NULL, NULL, 13839 zone->task, zone_timer, zone, 13840 &zone->timer); 13841 13842 if (result != ISC_R_SUCCESS) 13843 goto cleanup_tasks; 13844 13845 /* 13846 * The timer "holds" a iref. 13847 */ 13848 zone->irefs++; 13849 INSIST(zone->irefs != 0); 13850 13851 ISC_LIST_APPEND(zmgr->zones, zone, link); 13852 zone->zmgr = zmgr; 13853 zmgr->refs++; 13854 13855 goto unlock; 13856 13857 cleanup_tasks: 13858 isc_task_detach(&zone->loadtask); 13859 isc_task_detach(&zone->task); 13860 13861 unlock: 13862 UNLOCK_ZONE(zone); 13863 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 13864 return (result); 13865} 13866 13867void 13868dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 13869 isc_boolean_t free_now = ISC_FALSE; 13870 13871 REQUIRE(DNS_ZONE_VALID(zone)); 13872 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13873 REQUIRE(zone->zmgr == zmgr); 13874 13875 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 13876 LOCK_ZONE(zone); 13877 13878 ISC_LIST_UNLINK(zmgr->zones, zone, link); 13879 zone->zmgr = NULL; 13880 zmgr->refs--; 13881 if (zmgr->refs == 0) 13882 free_now = ISC_TRUE; 13883 13884 UNLOCK_ZONE(zone); 13885 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 13886 13887 if (free_now) 13888 zonemgr_free(zmgr); 13889 ENSURE(zone->zmgr == NULL); 13890} 13891 13892void 13893dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) { 13894 REQUIRE(DNS_ZONEMGR_VALID(source)); 13895 REQUIRE(target != NULL && *target == NULL); 13896 13897 RWLOCK(&source->rwlock, isc_rwlocktype_write); 13898 REQUIRE(source->refs > 0); 13899 source->refs++; 13900 INSIST(source->refs > 0); 13901 RWUNLOCK(&source->rwlock, isc_rwlocktype_write); 13902 *target = source; 13903} 13904 13905void 13906dns_zonemgr_detach(dns_zonemgr_t **zmgrp) { 13907 dns_zonemgr_t *zmgr; 13908 isc_boolean_t free_now = ISC_FALSE; 13909 13910 REQUIRE(zmgrp != NULL); 13911 zmgr = *zmgrp; 13912 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13913 13914 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 13915 zmgr->refs--; 13916 if (zmgr->refs == 0) 13917 free_now = ISC_TRUE; 13918 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 13919 13920 if (free_now) 13921 zonemgr_free(zmgr); 13922 *zmgrp = NULL; 13923} 13924 13925isc_result_t 13926dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) { 13927 dns_zone_t *p; 13928 13929 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13930 13931 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 13932 for (p = ISC_LIST_HEAD(zmgr->zones); 13933 p != NULL; 13934 p = ISC_LIST_NEXT(p, link)) 13935 { 13936 dns_zone_maintenance(p); 13937 } 13938 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 13939 13940 /* 13941 * Recent configuration changes may have increased the 13942 * amount of available transfers quota. Make sure any 13943 * transfers currently blocked on quota get started if 13944 * possible. 13945 */ 13946 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 13947 zmgr_resume_xfrs(zmgr, ISC_TRUE); 13948 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 13949 return (ISC_R_SUCCESS); 13950} 13951 13952void 13953dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) { 13954 13955 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13956 13957 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 13958 zmgr_resume_xfrs(zmgr, ISC_TRUE); 13959 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 13960} 13961 13962void 13963dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) { 13964 dns_zone_t *zone; 13965 13966 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13967 13968 isc_ratelimiter_shutdown(zmgr->rl); 13969 13970 if (zmgr->task != NULL) 13971 isc_task_destroy(&zmgr->task); 13972 if (zmgr->zonetasks != NULL) 13973 isc_taskpool_destroy(&zmgr->zonetasks); 13974 if (zmgr->loadtasks != NULL) 13975 isc_taskpool_destroy(&zmgr->loadtasks); 13976 13977 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 13978 for (zone = ISC_LIST_HEAD(zmgr->zones); 13979 zone != NULL; 13980 zone = ISC_LIST_NEXT(zone, link)) 13981 { 13982 LOCK_ZONE(zone); 13983 forward_cancel(zone); 13984 UNLOCK_ZONE(zone); 13985 } 13986 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 13987} 13988 13989isc_result_t 13990dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) { 13991 isc_result_t result; 13992 int ntasks = num_zones / 100; 13993 isc_taskpool_t *pool = NULL; 13994 13995 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13996 13997 /* 13998 * For anything fewer than 1000 zones we use 10 tasks in 13999 * the task pools. More than that, and we'll scale at one 14000 * task per 100 zones. 14001 */ 14002 if (ntasks < 10) 14003 ntasks = 10; 14004 14005 /* Create or resize the zone task pools. */ 14006 if (zmgr->zonetasks == NULL) 14007 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, 14008 ntasks, 2, &pool); 14009 else 14010 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool); 14011 14012 if (result == ISC_R_SUCCESS) 14013 zmgr->zonetasks = pool; 14014 14015 pool = NULL; 14016 if (zmgr->loadtasks == NULL) 14017 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, 14018 ntasks, 2, &pool); 14019 else 14020 result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool); 14021 14022 if (result == ISC_R_SUCCESS) 14023 zmgr->loadtasks = pool; 14024 14025#ifdef BIND9 14026 /* 14027 * We always set all tasks in the zone-load task pool to 14028 * privileged. This prevents other tasks in the system from 14029 * running while the server task manager is in privileged 14030 * mode. 14031 * 14032 * NOTE: If we start using task privileges for any other 14033 * part of the system than zone tasks, then this will need to be 14034 * revisted. In that case we'd want to turn on privileges for 14035 * zone tasks only when we were loading, and turn them off the 14036 * rest of the time. For now, however, it's okay to just 14037 * set it and forget it. 14038 */ 14039 isc_taskpool_setprivilege(zmgr->loadtasks, ISC_TRUE); 14040#endif 14041 14042 return (result); 14043} 14044 14045static void 14046zonemgr_free(dns_zonemgr_t *zmgr) { 14047 isc_mem_t *mctx; 14048 14049 INSIST(zmgr->refs == 0); 14050 INSIST(ISC_LIST_EMPTY(zmgr->zones)); 14051 14052 zmgr->magic = 0; 14053 14054 DESTROYLOCK(&zmgr->iolock); 14055 isc_ratelimiter_detach(&zmgr->rl); 14056 14057 isc_rwlock_destroy(&zmgr->urlock); 14058 isc_rwlock_destroy(&zmgr->rwlock); 14059 mctx = zmgr->mctx; 14060 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); 14061 isc_mem_detach(&mctx); 14062} 14063 14064void 14065dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) { 14066 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14067 14068 zmgr->transfersin = value; 14069} 14070 14071isc_uint32_t 14072dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) { 14073 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14074 14075 return (zmgr->transfersin); 14076} 14077 14078void 14079dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) { 14080 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14081 14082 zmgr->transfersperns = value; 14083} 14084 14085isc_uint32_t 14086dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) { 14087 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14088 14089 return (zmgr->transfersperns); 14090} 14091 14092/* 14093 * Try to start a new incoming zone transfer to fill a quota 14094 * slot that was just vacated. 14095 * 14096 * Requires: 14097 * The zone manager is locked by the caller. 14098 */ 14099static void 14100zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) { 14101 dns_zone_t *zone; 14102 dns_zone_t *next; 14103 14104 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); 14105 zone != NULL; 14106 zone = next) 14107 { 14108 isc_result_t result; 14109 next = ISC_LIST_NEXT(zone, statelink); 14110 result = zmgr_start_xfrin_ifquota(zmgr, zone); 14111 if (result == ISC_R_SUCCESS) { 14112 if (multi) 14113 continue; 14114 /* 14115 * We successfully filled the slot. We're done. 14116 */ 14117 break; 14118 } else if (result == ISC_R_QUOTA) { 14119 /* 14120 * Not enough quota. This is probably the per-server 14121 * quota, because we usually get called when a unit of 14122 * global quota has just been freed. Try the next 14123 * zone, it may succeed if it uses another master. 14124 */ 14125 continue; 14126 } else { 14127 dns_zone_log(zone, ISC_LOG_DEBUG(1), 14128 "starting zone transfer: %s", 14129 isc_result_totext(result)); 14130 break; 14131 } 14132 } 14133} 14134 14135/* 14136 * Try to start an incoming zone transfer for 'zone', quota permitting. 14137 * 14138 * Requires: 14139 * The zone manager is locked by the caller. 14140 * 14141 * Returns: 14142 * ISC_R_SUCCESS There was enough quota and we attempted to 14143 * start a transfer. zone_xfrdone() has been or will 14144 * be called. 14145 * ISC_R_QUOTA Not enough quota. 14146 * Others Failure. 14147 */ 14148static isc_result_t 14149zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 14150 dns_peer_t *peer = NULL; 14151 isc_netaddr_t masterip; 14152 isc_uint32_t nxfrsin, nxfrsperns; 14153 dns_zone_t *x; 14154 isc_uint32_t maxtransfersin, maxtransfersperns; 14155 isc_event_t *e; 14156 14157 /* 14158 * If we are exiting just pretend we got quota so the zone will 14159 * be cleaned up in the zone's task context. 14160 */ 14161 LOCK_ZONE(zone); 14162 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 14163 UNLOCK_ZONE(zone); 14164 goto gotquota; 14165 } 14166 14167 /* 14168 * Find any configured information about the server we'd 14169 * like to transfer this zone from. 14170 */ 14171 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 14172 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer); 14173 UNLOCK_ZONE(zone); 14174 14175 /* 14176 * Determine the total maximum number of simultaneous 14177 * transfers allowed, and the maximum for this specific 14178 * master. 14179 */ 14180 maxtransfersin = zmgr->transfersin; 14181 maxtransfersperns = zmgr->transfersperns; 14182 if (peer != NULL) 14183 (void)dns_peer_gettransfers(peer, &maxtransfersperns); 14184 14185 /* 14186 * Count the total number of transfers that are in progress, 14187 * and the number of transfers in progress from this master. 14188 * We linearly scan a list of all transfers; if this turns 14189 * out to be too slow, we could hash on the master address. 14190 */ 14191 nxfrsin = nxfrsperns = 0; 14192 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress); 14193 x != NULL; 14194 x = ISC_LIST_NEXT(x, statelink)) 14195 { 14196 isc_netaddr_t xip; 14197 14198 LOCK_ZONE(x); 14199 isc_netaddr_fromsockaddr(&xip, &x->masteraddr); 14200 UNLOCK_ZONE(x); 14201 14202 nxfrsin++; 14203 if (isc_netaddr_equal(&xip, &masterip)) 14204 nxfrsperns++; 14205 } 14206 14207 /* Enforce quota. */ 14208 if (nxfrsin >= maxtransfersin) 14209 return (ISC_R_QUOTA); 14210 14211 if (nxfrsperns >= maxtransfersperns) 14212 return (ISC_R_QUOTA); 14213 14214 gotquota: 14215 /* 14216 * We have sufficient quota. Move the zone to the "xfrin_in_progress" 14217 * list and send it an event to let it start the actual transfer in the 14218 * context of its own task. 14219 */ 14220 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN, 14221 got_transfer_quota, zone, sizeof(isc_event_t)); 14222 if (e == NULL) 14223 return (ISC_R_NOMEMORY); 14224 14225 LOCK_ZONE(zone); 14226 INSIST(zone->statelist == &zmgr->waiting_for_xfrin); 14227 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink); 14228 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink); 14229 zone->statelist = &zmgr->xfrin_in_progress; 14230 isc_task_send(zone->task, &e); 14231 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started."); 14232 UNLOCK_ZONE(zone); 14233 14234 return (ISC_R_SUCCESS); 14235} 14236 14237void 14238dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) { 14239 14240 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14241 REQUIRE(iolimit > 0); 14242 14243 zmgr->iolimit = iolimit; 14244} 14245 14246isc_uint32_t 14247dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) { 14248 14249 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14250 14251 return (zmgr->iolimit); 14252} 14253 14254/* 14255 * Get permission to request a file handle from the OS. 14256 * An event will be sent to action when one is available. 14257 * There are two queues available (high and low), the high 14258 * queue will be serviced before the low one. 14259 * 14260 * zonemgr_putio() must be called after the event is delivered to 14261 * 'action'. 14262 */ 14263 14264static isc_result_t 14265zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high, 14266 isc_task_t *task, isc_taskaction_t action, void *arg, 14267 dns_io_t **iop) 14268{ 14269 dns_io_t *io; 14270 isc_boolean_t queue; 14271 14272 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14273 REQUIRE(iop != NULL && *iop == NULL); 14274 14275 io = isc_mem_get(zmgr->mctx, sizeof(*io)); 14276 if (io == NULL) 14277 return (ISC_R_NOMEMORY); 14278 14279 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY, 14280 action, arg, sizeof(*io->event)); 14281 if (io->event == NULL) { 14282 isc_mem_put(zmgr->mctx, io, sizeof(*io)); 14283 return (ISC_R_NOMEMORY); 14284 } 14285 14286 io->zmgr = zmgr; 14287 io->high = high; 14288 io->task = NULL; 14289 isc_task_attach(task, &io->task); 14290 ISC_LINK_INIT(io, link); 14291 io->magic = IO_MAGIC; 14292 14293 LOCK(&zmgr->iolock); 14294 zmgr->ioactive++; 14295 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit); 14296 if (queue) { 14297 if (io->high) 14298 ISC_LIST_APPEND(zmgr->high, io, link); 14299 else 14300 ISC_LIST_APPEND(zmgr->low, io, link); 14301 } 14302 UNLOCK(&zmgr->iolock); 14303 *iop = io; 14304 14305 if (!queue) 14306 isc_task_send(io->task, &io->event); 14307 return (ISC_R_SUCCESS); 14308} 14309 14310static void 14311zonemgr_putio(dns_io_t **iop) { 14312 dns_io_t *io; 14313 dns_io_t *next; 14314 dns_zonemgr_t *zmgr; 14315 14316 REQUIRE(iop != NULL); 14317 io = *iop; 14318 REQUIRE(DNS_IO_VALID(io)); 14319 14320 *iop = NULL; 14321 14322 INSIST(!ISC_LINK_LINKED(io, link)); 14323 INSIST(io->event == NULL); 14324 14325 zmgr = io->zmgr; 14326 isc_task_detach(&io->task); 14327 io->magic = 0; 14328 isc_mem_put(zmgr->mctx, io, sizeof(*io)); 14329 14330 LOCK(&zmgr->iolock); 14331 INSIST(zmgr->ioactive > 0); 14332 zmgr->ioactive--; 14333 next = HEAD(zmgr->high); 14334 if (next == NULL) 14335 next = HEAD(zmgr->low); 14336 if (next != NULL) { 14337 if (next->high) 14338 ISC_LIST_UNLINK(zmgr->high, next, link); 14339 else 14340 ISC_LIST_UNLINK(zmgr->low, next, link); 14341 INSIST(next->event != NULL); 14342 } 14343 UNLOCK(&zmgr->iolock); 14344 if (next != NULL) 14345 isc_task_send(next->task, &next->event); 14346} 14347 14348static void 14349zonemgr_cancelio(dns_io_t *io) { 14350 isc_boolean_t send_event = ISC_FALSE; 14351 14352 REQUIRE(DNS_IO_VALID(io)); 14353 14354 /* 14355 * If we are queued to be run then dequeue. 14356 */ 14357 LOCK(&io->zmgr->iolock); 14358 if (ISC_LINK_LINKED(io, link)) { 14359 if (io->high) 14360 ISC_LIST_UNLINK(io->zmgr->high, io, link); 14361 else 14362 ISC_LIST_UNLINK(io->zmgr->low, io, link); 14363 14364 send_event = ISC_TRUE; 14365 INSIST(io->event != NULL); 14366 } 14367 UNLOCK(&io->zmgr->iolock); 14368 if (send_event) { 14369 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED; 14370 isc_task_send(io->task, &io->event); 14371 } 14372} 14373 14374static void 14375zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) { 14376 char *buf; 14377 int buflen; 14378 isc_result_t result; 14379 14380 buflen = strlen(path) + strlen(templat) + 2; 14381 14382 buf = isc_mem_get(zone->mctx, buflen); 14383 if (buf == NULL) 14384 return; 14385 14386 result = isc_file_template(path, templat, buf, buflen); 14387 if (result != ISC_R_SUCCESS) 14388 goto cleanup; 14389 14390 result = isc_file_renameunique(path, buf); 14391 if (result != ISC_R_SUCCESS) 14392 goto cleanup; 14393 14394 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; " 14395 "renaming file to '%s' for failure analysis and " 14396 "retransferring.", path, buf); 14397 14398 cleanup: 14399 isc_mem_put(zone->mctx, buf, buflen); 14400} 14401 14402#if 0 14403/* Hook for ondestroy notification from a database. */ 14404 14405static void 14406dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) { 14407 dns_db_t *db = event->sender; 14408 UNUSED(task); 14409 14410 isc_event_free(&event); 14411 14412 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 14413 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 14414 "database (%p) destroyed", (void*) db); 14415} 14416#endif 14417 14418void 14419dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) { 14420 isc_interval_t interval; 14421 isc_uint32_t s, ns; 14422 isc_uint32_t pertic; 14423 isc_result_t result; 14424 14425 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14426 14427 if (value == 0) 14428 value = 1; 14429 14430 if (value == 1) { 14431 s = 1; 14432 ns = 0; 14433 pertic = 1; 14434 } else if (value <= 10) { 14435 s = 0; 14436 ns = 1000000000 / value; 14437 pertic = 1; 14438 } else { 14439 s = 0; 14440 ns = (1000000000 / value) * 10; 14441 pertic = 10; 14442 } 14443 14444 isc_interval_set(&interval, s, ns); 14445 result = isc_ratelimiter_setinterval(zmgr->rl, &interval); 14446 RUNTIME_CHECK(result == ISC_R_SUCCESS); 14447 isc_ratelimiter_setpertic(zmgr->rl, pertic); 14448 14449 zmgr->serialqueryrate = value; 14450} 14451 14452unsigned int 14453dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) { 14454 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14455 14456 return (zmgr->serialqueryrate); 14457} 14458 14459isc_boolean_t 14460dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 14461 isc_sockaddr_t *local, isc_time_t *now) 14462{ 14463 unsigned int i; 14464 isc_rwlocktype_t locktype; 14465 isc_result_t result; 14466 isc_uint32_t seconds = isc_time_seconds(now); 14467 14468 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14469 14470 locktype = isc_rwlocktype_read; 14471 RWLOCK(&zmgr->urlock, locktype); 14472 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { 14473 if (zmgr->unreachable[i].expire >= seconds && 14474 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 14475 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) { 14476 result = isc_rwlock_tryupgrade(&zmgr->urlock); 14477 if (result == ISC_R_SUCCESS) { 14478 locktype = isc_rwlocktype_write; 14479 zmgr->unreachable[i].last = seconds; 14480 } 14481 break; 14482 } 14483 } 14484 RWUNLOCK(&zmgr->urlock, locktype); 14485 return (ISC_TF(i < UNREACH_CHACHE_SIZE)); 14486} 14487 14488void 14489dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 14490 isc_sockaddr_t *local) 14491{ 14492 unsigned int i; 14493 isc_rwlocktype_t locktype; 14494 isc_result_t result; 14495 14496 char master[ISC_SOCKADDR_FORMATSIZE]; 14497 char source[ISC_SOCKADDR_FORMATSIZE]; 14498 14499 isc_sockaddr_format(remote, master, sizeof(master)); 14500 isc_sockaddr_format(local, source, sizeof(source)); 14501 14502 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14503 14504 locktype = isc_rwlocktype_read; 14505 RWLOCK(&zmgr->urlock, locktype); 14506 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { 14507 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 14508 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) { 14509 result = isc_rwlock_tryupgrade(&zmgr->urlock); 14510 if (result == ISC_R_SUCCESS) { 14511 locktype = isc_rwlocktype_write; 14512 zmgr->unreachable[i].expire = 0; 14513 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 14514 DNS_LOGMODULE_ZONE, ISC_LOG_INFO, 14515 "master %s (source %s) deleted " 14516 "from unreachable cache", 14517 master, source); 14518 } 14519 break; 14520 } 14521 } 14522 RWUNLOCK(&zmgr->urlock, locktype); 14523} 14524 14525void 14526dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 14527 isc_sockaddr_t *local, isc_time_t *now) 14528{ 14529 isc_uint32_t seconds = isc_time_seconds(now); 14530 isc_uint32_t last = seconds; 14531 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0; 14532 14533 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14534 14535 RWLOCK(&zmgr->urlock, isc_rwlocktype_write); 14536 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { 14537 /* Existing entry? */ 14538 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 14539 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 14540 break; 14541 /* Empty slot? */ 14542 if (zmgr->unreachable[i].expire < seconds) 14543 slot = i; 14544 /* Least recently used slot? */ 14545 if (zmgr->unreachable[i].last < last) { 14546 last = zmgr->unreachable[i].last; 14547 oldest = i; 14548 } 14549 } 14550 if (i < UNREACH_CHACHE_SIZE) { 14551 /* 14552 * Found a existing entry. Update the expire timer and 14553 * last usage timestamps. 14554 */ 14555 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME; 14556 zmgr->unreachable[i].last = seconds; 14557 } else if (slot != UNREACH_CHACHE_SIZE) { 14558 /* 14559 * Found a empty slot. Add a new entry to the cache. 14560 */ 14561 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME; 14562 zmgr->unreachable[slot].last = seconds; 14563 zmgr->unreachable[slot].remote = *remote; 14564 zmgr->unreachable[slot].local = *local; 14565 } else { 14566 /* 14567 * Replace the least recently used entry in the cache. 14568 */ 14569 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME; 14570 zmgr->unreachable[oldest].last = seconds; 14571 zmgr->unreachable[oldest].remote = *remote; 14572 zmgr->unreachable[oldest].local = *local; 14573 } 14574 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write); 14575} 14576 14577void 14578dns_zone_forcereload(dns_zone_t *zone) { 14579 REQUIRE(DNS_ZONE_VALID(zone)); 14580 14581 if (zone->type == dns_zone_master || 14582 (zone->type == dns_zone_redirect && zone->masters == NULL)) 14583 return; 14584 14585 LOCK_ZONE(zone); 14586 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER); 14587 UNLOCK_ZONE(zone); 14588 dns_zone_refresh(zone); 14589} 14590 14591isc_boolean_t 14592dns_zone_isforced(dns_zone_t *zone) { 14593 REQUIRE(DNS_ZONE_VALID(zone)); 14594 14595 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)); 14596} 14597 14598isc_result_t 14599dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) { 14600 /* 14601 * This function is obsoleted. 14602 */ 14603 UNUSED(zone); 14604 UNUSED(on); 14605 return (ISC_R_NOTIMPLEMENTED); 14606} 14607 14608isc_uint64_t * 14609dns_zone_getstatscounters(dns_zone_t *zone) { 14610 /* 14611 * This function is obsoleted. 14612 */ 14613 UNUSED(zone); 14614 return (NULL); 14615} 14616 14617void 14618dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) { 14619 REQUIRE(DNS_ZONE_VALID(zone)); 14620 REQUIRE(zone->stats == NULL); 14621 14622 LOCK_ZONE(zone); 14623 zone->stats = NULL; 14624 isc_stats_attach(stats, &zone->stats); 14625 UNLOCK_ZONE(zone); 14626} 14627 14628void 14629dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) { 14630 REQUIRE(DNS_ZONE_VALID(zone)); 14631 14632 LOCK_ZONE(zone); 14633 if (zone->requeststats_on && stats == NULL) 14634 zone->requeststats_on = ISC_FALSE; 14635 else if (!zone->requeststats_on && stats != NULL) { 14636 if (zone->requeststats == NULL) { 14637 isc_stats_attach(stats, &zone->requeststats); 14638 zone->requeststats_on = ISC_TRUE; 14639 } 14640 } 14641 UNLOCK_ZONE(zone); 14642 14643 return; 14644} 14645 14646isc_stats_t * 14647dns_zone_getrequeststats(dns_zone_t *zone) { 14648 /* 14649 * We don't lock zone for efficiency reason. This is not catastrophic 14650 * because requeststats must always be valid when requeststats_on is 14651 * true. 14652 * Some counters may be incremented while requeststats_on is becoming 14653 * false, or some cannot be incremented just after the statistics are 14654 * installed, but it shouldn't matter much in practice. 14655 */ 14656 if (zone->requeststats_on) 14657 return (zone->requeststats); 14658 else 14659 return (NULL); 14660} 14661 14662void 14663dns_zone_dialup(dns_zone_t *zone) { 14664 14665 REQUIRE(DNS_ZONE_VALID(zone)); 14666 14667 zone_debuglog(zone, "dns_zone_dialup", 3, 14668 "notify = %d, refresh = %d", 14669 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY), 14670 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)); 14671 14672 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) 14673 dns_zone_notify(zone); 14674 if (zone->type != dns_zone_master && zone->masters != NULL && 14675 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 14676 dns_zone_refresh(zone); 14677} 14678 14679void 14680dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) { 14681 REQUIRE(DNS_ZONE_VALID(zone)); 14682 14683 LOCK_ZONE(zone); 14684 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY | 14685 DNS_ZONEFLG_DIALREFRESH | 14686 DNS_ZONEFLG_NOREFRESH); 14687 switch (dialup) { 14688 case dns_dialuptype_no: 14689 break; 14690 case dns_dialuptype_yes: 14691 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY | 14692 DNS_ZONEFLG_DIALREFRESH | 14693 DNS_ZONEFLG_NOREFRESH)); 14694 break; 14695 case dns_dialuptype_notify: 14696 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 14697 break; 14698 case dns_dialuptype_notifypassive: 14699 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 14700 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 14701 break; 14702 case dns_dialuptype_refresh: 14703 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH); 14704 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 14705 break; 14706 case dns_dialuptype_passive: 14707 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 14708 break; 14709 default: 14710 INSIST(0); 14711 } 14712 UNLOCK_ZONE(zone); 14713} 14714 14715isc_result_t 14716dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) { 14717 isc_result_t result = ISC_R_SUCCESS; 14718 14719 REQUIRE(DNS_ZONE_VALID(zone)); 14720 14721 LOCK_ZONE(zone); 14722 result = dns_zone_setstring(zone, &zone->keydirectory, directory); 14723 UNLOCK_ZONE(zone); 14724 14725 return (result); 14726} 14727 14728const char * 14729dns_zone_getkeydirectory(dns_zone_t *zone) { 14730 REQUIRE(DNS_ZONE_VALID(zone)); 14731 14732 return (zone->keydirectory); 14733} 14734 14735unsigned int 14736dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) { 14737 dns_zone_t *zone; 14738 unsigned int count = 0; 14739 14740 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 14741 14742 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 14743 switch (state) { 14744 case DNS_ZONESTATE_XFERRUNNING: 14745 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress); 14746 zone != NULL; 14747 zone = ISC_LIST_NEXT(zone, statelink)) 14748 count++; 14749 break; 14750 case DNS_ZONESTATE_XFERDEFERRED: 14751 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); 14752 zone != NULL; 14753 zone = ISC_LIST_NEXT(zone, statelink)) 14754 count++; 14755 break; 14756 case DNS_ZONESTATE_SOAQUERY: 14757 for (zone = ISC_LIST_HEAD(zmgr->zones); 14758 zone != NULL; 14759 zone = ISC_LIST_NEXT(zone, link)) 14760 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) 14761 count++; 14762 break; 14763 case DNS_ZONESTATE_ANY: 14764 for (zone = ISC_LIST_HEAD(zmgr->zones); 14765 zone != NULL; 14766 zone = ISC_LIST_NEXT(zone, link)) { 14767 dns_view_t *view = zone->view; 14768 if (view != NULL && strcmp(view->name, "_bind") == 0) 14769 continue; 14770 count++; 14771 } 14772 break; 14773 default: 14774 INSIST(0); 14775 } 14776 14777 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 14778 14779 return (count); 14780} 14781 14782isc_result_t 14783dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) { 14784 isc_boolean_t ok = ISC_TRUE; 14785 isc_boolean_t fail = ISC_FALSE; 14786 char namebuf[DNS_NAME_FORMATSIZE]; 14787 char namebuf2[DNS_NAME_FORMATSIZE]; 14788 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 14789 int level = ISC_LOG_WARNING; 14790 dns_name_t bad; 14791 14792 REQUIRE(DNS_ZONE_VALID(zone)); 14793 14794 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) 14795 return (ISC_R_SUCCESS); 14796 14797 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) { 14798 level = ISC_LOG_ERROR; 14799 fail = ISC_TRUE; 14800 } 14801 14802 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE); 14803 if (!ok) { 14804 dns_name_format(name, namebuf, sizeof(namebuf)); 14805 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 14806 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf, 14807 dns_result_totext(DNS_R_BADOWNERNAME)); 14808 if (fail) 14809 return (DNS_R_BADOWNERNAME); 14810 } 14811 14812 dns_name_init(&bad, NULL); 14813 ok = dns_rdata_checknames(rdata, name, &bad); 14814 if (!ok) { 14815 dns_name_format(name, namebuf, sizeof(namebuf)); 14816 dns_name_format(&bad, namebuf2, sizeof(namebuf2)); 14817 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 14818 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf, 14819 namebuf2, dns_result_totext(DNS_R_BADNAME)); 14820 if (fail) 14821 return (DNS_R_BADNAME); 14822 } 14823 14824 return (ISC_R_SUCCESS); 14825} 14826 14827void 14828dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) { 14829 REQUIRE(DNS_ZONE_VALID(zone)); 14830 zone->checkmx = checkmx; 14831} 14832 14833void 14834dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) { 14835 REQUIRE(DNS_ZONE_VALID(zone)); 14836 zone->checksrv = checksrv; 14837} 14838 14839void 14840dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) { 14841 REQUIRE(DNS_ZONE_VALID(zone)); 14842 zone->checkns = checkns; 14843} 14844 14845void 14846dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) { 14847 REQUIRE(DNS_ZONE_VALID(zone)); 14848 14849 LOCK_ZONE(zone); 14850 zone->isself = isself; 14851 zone->isselfarg = arg; 14852 UNLOCK_ZONE(zone); 14853} 14854 14855void 14856dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) { 14857 REQUIRE(DNS_ZONE_VALID(zone)); 14858 14859 LOCK_ZONE(zone); 14860 zone->notifydelay = delay; 14861 UNLOCK_ZONE(zone); 14862} 14863 14864isc_uint32_t 14865dns_zone_getnotifydelay(dns_zone_t *zone) { 14866 REQUIRE(DNS_ZONE_VALID(zone)); 14867 14868 return (zone->notifydelay); 14869} 14870 14871isc_result_t 14872dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, 14873 isc_uint16_t keyid, isc_boolean_t delete) 14874{ 14875 isc_result_t result; 14876 REQUIRE(DNS_ZONE_VALID(zone)); 14877 14878 dns_zone_log(zone, ISC_LOG_NOTICE, 14879 "dns_zone_signwithkey(algorithm=%u, keyid=%u)", 14880 algorithm, keyid); 14881 LOCK_ZONE(zone); 14882 result = zone_signwithkey(zone, algorithm, keyid, delete); 14883 UNLOCK_ZONE(zone); 14884 14885 return (result); 14886} 14887 14888static const char *hex = "0123456789ABCDEF"; 14889 14890isc_result_t 14891dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 14892 isc_result_t result; 14893 char salt[255*2+1]; 14894 unsigned int i, j; 14895 14896 REQUIRE(DNS_ZONE_VALID(zone)); 14897 14898 if (nsec3param->salt_length != 0) { 14899 INSIST((nsec3param->salt_length * 2U) < sizeof(salt)); 14900 for (i = 0, j = 0; i < nsec3param->salt_length; i++) { 14901 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf]; 14902 salt[j++] = hex[nsec3param->salt[i] & 0xf]; 14903 } 14904 salt[j] = '\0'; 14905 } else 14906 strcpy(salt, "-"); 14907 dns_zone_log(zone, ISC_LOG_NOTICE, 14908 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)", 14909 nsec3param->hash, nsec3param->iterations, 14910 salt); 14911 LOCK_ZONE(zone); 14912 result = zone_addnsec3chain(zone, nsec3param); 14913 UNLOCK_ZONE(zone); 14914 14915 return (result); 14916} 14917 14918void 14919dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) { 14920 REQUIRE(DNS_ZONE_VALID(zone)); 14921 14922 if (nodes == 0) 14923 nodes = 1; 14924 zone->nodes = nodes; 14925} 14926 14927void 14928dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) { 14929 REQUIRE(DNS_ZONE_VALID(zone)); 14930 14931 /* 14932 * We treat signatures as a signed value so explicitly 14933 * limit its range here. 14934 */ 14935 if (signatures > ISC_INT32_MAX) 14936 signatures = ISC_INT32_MAX; 14937 else if (signatures == 0) 14938 signatures = 1; 14939 zone->signatures = signatures; 14940} 14941 14942void 14943dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) { 14944 REQUIRE(DNS_ZONE_VALID(zone)); 14945 zone->privatetype = type; 14946} 14947 14948dns_rdatatype_t 14949dns_zone_getprivatetype(dns_zone_t *zone) { 14950 REQUIRE(DNS_ZONE_VALID(zone)); 14951 return (zone->privatetype); 14952} 14953 14954static isc_result_t 14955zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid, 14956 isc_boolean_t delete) 14957{ 14958 dns_signing_t *signing; 14959 dns_signing_t *current; 14960 isc_result_t result = ISC_R_SUCCESS; 14961 isc_time_t now; 14962 14963 signing = isc_mem_get(zone->mctx, sizeof *signing); 14964 if (signing == NULL) 14965 return (ISC_R_NOMEMORY); 14966 14967 signing->magic = 0; 14968 signing->db = NULL; 14969 signing->dbiterator = NULL; 14970 signing->algorithm = algorithm; 14971 signing->keyid = keyid; 14972 signing->delete = delete; 14973 signing->done = ISC_FALSE; 14974 14975 TIME_NOW(&now); 14976 14977 for (current = ISC_LIST_HEAD(zone->signing); 14978 current != NULL; 14979 current = ISC_LIST_NEXT(current, link)) { 14980 if (current->db == zone->db && 14981 current->algorithm == signing->algorithm && 14982 current->keyid == signing->keyid) { 14983 if (current->delete != signing->delete) 14984 current->done = ISC_TRUE; 14985 else 14986 goto cleanup; 14987 } 14988 } 14989 14990 if (zone->db != NULL) { 14991 dns_db_attach(zone->db, &signing->db); 14992 result = dns_db_createiterator(signing->db, 0, 14993 &signing->dbiterator); 14994 14995 if (result == ISC_R_SUCCESS) 14996 result = dns_dbiterator_first(signing->dbiterator); 14997 if (result == ISC_R_SUCCESS) { 14998 dns_dbiterator_pause(signing->dbiterator); 14999 ISC_LIST_INITANDAPPEND(zone->signing, signing, link); 15000 signing = NULL; 15001 if (isc_time_isepoch(&zone->signingtime)) { 15002 zone->signingtime = now; 15003 if (zone->task != NULL) 15004 zone_settimer(zone, &now); 15005 } 15006 } 15007 } else 15008 result = ISC_R_NOTFOUND; 15009 15010 cleanup: 15011 if (signing != NULL) { 15012 if (signing->db != NULL) 15013 dns_db_detach(&signing->db); 15014 if (signing->dbiterator != NULL) 15015 dns_dbiterator_destroy(&signing->dbiterator); 15016 isc_mem_put(zone->mctx, signing, sizeof *signing); 15017 } 15018 return (result); 15019} 15020 15021static void 15022logmsg(const char *format, ...) { 15023 va_list args; 15024 va_start(args, format); 15025 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, 15026 ISC_LOG_DEBUG(1), format, args); 15027 va_end(args); 15028} 15029 15030static void 15031clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) { 15032 dns_dnsseckey_t *key; 15033 while (!ISC_LIST_EMPTY(*list)) { 15034 key = ISC_LIST_HEAD(*list); 15035 ISC_LIST_UNLINK(*list, key, link); 15036 dns_dnsseckey_destroy(mctx, &key); 15037 } 15038} 15039 15040/* Called once; *timep should be set to the current time. */ 15041static isc_result_t 15042next_keyevent(dst_key_t *key, isc_stdtime_t *timep) { 15043 isc_result_t result; 15044 isc_stdtime_t now, then = 0, event; 15045 int i; 15046 15047 now = *timep; 15048 15049 for (i = 0; i <= DST_MAX_TIMES; i++) { 15050 result = dst_key_gettime(key, i, &event); 15051 if (result == ISC_R_SUCCESS && event > now && 15052 (then == 0 || event < then)) 15053 then = event; 15054 } 15055 15056 if (then != 0) { 15057 *timep = then; 15058 return (ISC_R_SUCCESS); 15059 } 15060 15061 return (ISC_R_NOTFOUND); 15062} 15063 15064static isc_result_t 15065rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 15066 const dns_rdata_t *rdata, isc_boolean_t *flag) 15067{ 15068 dns_rdataset_t rdataset; 15069 dns_dbnode_t *node = NULL; 15070 isc_result_t result; 15071 15072 dns_rdataset_init(&rdataset); 15073 if (rdata->type == dns_rdatatype_nsec3) 15074 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node)); 15075 else 15076 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); 15077 result = dns_db_findrdataset(db, node, ver, rdata->type, 0, 15078 (isc_stdtime_t) 0, &rdataset, NULL); 15079 if (result == ISC_R_NOTFOUND) { 15080 *flag = ISC_FALSE; 15081 result = ISC_R_SUCCESS; 15082 goto failure; 15083 } 15084 15085 for (result = dns_rdataset_first(&rdataset); 15086 result == ISC_R_SUCCESS; 15087 result = dns_rdataset_next(&rdataset)) { 15088 dns_rdata_t myrdata = DNS_RDATA_INIT; 15089 dns_rdataset_current(&rdataset, &myrdata); 15090 if (!dns_rdata_compare(&myrdata, rdata)) 15091 break; 15092 } 15093 dns_rdataset_disassociate(&rdataset); 15094 if (result == ISC_R_SUCCESS) { 15095 *flag = ISC_TRUE; 15096 } else if (result == ISC_R_NOMORE) { 15097 *flag = ISC_FALSE; 15098 result = ISC_R_SUCCESS; 15099 } 15100 15101 failure: 15102 if (node != NULL) 15103 dns_db_detachnode(db, &node); 15104 return (result); 15105} 15106 15107/* 15108 * Add records to signal the state of signing or of key removal. 15109 */ 15110static isc_result_t 15111add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, 15112 dns_dbversion_t *ver, dns_diff_t *diff, 15113 isc_boolean_t sign_all) 15114{ 15115 dns_difftuple_t *tuple, *newtuple = NULL; 15116 dns_rdata_dnskey_t dnskey; 15117 dns_rdata_t rdata = DNS_RDATA_INIT; 15118 isc_boolean_t flag; 15119 isc_region_t r; 15120 isc_result_t result = ISC_R_SUCCESS; 15121 isc_uint16_t keyid; 15122 unsigned char buf[5]; 15123 dns_name_t *name = dns_db_origin(db); 15124 15125 for (tuple = ISC_LIST_HEAD(diff->tuples); 15126 tuple != NULL; 15127 tuple = ISC_LIST_NEXT(tuple, link)) { 15128 if (tuple->rdata.type != dns_rdatatype_dnskey) 15129 continue; 15130 15131 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL); 15132 RUNTIME_CHECK(result == ISC_R_SUCCESS); 15133 if ((dnskey.flags & 15134 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH)) 15135 != DNS_KEYOWNER_ZONE) 15136 continue; 15137 15138 dns_rdata_toregion(&tuple->rdata, &r); 15139 15140 keyid = dst_region_computeid(&r, dnskey.algorithm); 15141 15142 buf[0] = dnskey.algorithm; 15143 buf[1] = (keyid & 0xff00) >> 8; 15144 buf[2] = (keyid & 0xff); 15145 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1; 15146 buf[4] = 0; 15147 rdata.data = buf; 15148 rdata.length = sizeof(buf); 15149 rdata.type = privatetype; 15150 rdata.rdclass = tuple->rdata.rdclass; 15151 15152 if (sign_all || tuple->op == DNS_DIFFOP_DEL) { 15153 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 15154 if (flag) 15155 continue; 15156 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, 15157 name, 0, &rdata, &newtuple)); 15158 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 15159 INSIST(newtuple == NULL); 15160 } 15161 15162 /* 15163 * Remove any record which says this operation has already 15164 * completed. 15165 */ 15166 buf[4] = 1; 15167 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 15168 if (flag) { 15169 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, 15170 name, 0, &rdata, &newtuple)); 15171 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 15172 INSIST(newtuple == NULL); 15173 } 15174 } 15175 failure: 15176 return (result); 15177} 15178 15179static isc_result_t 15180sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 15181 dns_diff_t *diff, dns_diff_t *sig_diff) 15182{ 15183 isc_result_t result; 15184 isc_stdtime_t now, inception, soaexpire; 15185 isc_boolean_t check_ksk, keyset_kskonly; 15186 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 15187 unsigned int nkeys = 0, i; 15188 dns_difftuple_t *tuple; 15189 15190 result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS, 15191 zone_keys, &nkeys); 15192 if (result != ISC_R_SUCCESS) { 15193 dns_zone_log(zone, ISC_LOG_ERROR, 15194 "sign_apex:find_zone_keys -> %s", 15195 dns_result_totext(result)); 15196 return (result); 15197 } 15198 15199 isc_stdtime_get(&now); 15200 inception = now - 3600; /* Allow for clock skew. */ 15201 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 15202 15203 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 15204 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 15205 15206 /* 15207 * See if update_sigs will update DNSKEY signature and if not 15208 * cause them to sign so that so that newly activated keys 15209 * are used. 15210 */ 15211 for (tuple = ISC_LIST_HEAD(diff->tuples); 15212 tuple != NULL; 15213 tuple = ISC_LIST_NEXT(tuple, link)) { 15214 if (tuple->rdata.type == dns_rdatatype_dnskey && 15215 dns_name_equal(&tuple->name, &zone->origin)) 15216 break; 15217 } 15218 15219 if (tuple == NULL) { 15220 result = del_sigs(zone, db, ver, &zone->origin, 15221 dns_rdatatype_dnskey, sig_diff, 15222 zone_keys, nkeys, now, ISC_FALSE); 15223 if (result != ISC_R_SUCCESS) { 15224 dns_zone_log(zone, ISC_LOG_ERROR, 15225 "sign_apex:del_sigs -> %s", 15226 dns_result_totext(result)); 15227 goto failure; 15228 } 15229 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey, 15230 sig_diff, zone_keys, nkeys, zone->mctx, 15231 inception, soaexpire, check_ksk, 15232 keyset_kskonly); 15233 if (result != ISC_R_SUCCESS) { 15234 dns_zone_log(zone, ISC_LOG_ERROR, 15235 "sign_apex:add_sigs -> %s", 15236 dns_result_totext(result)); 15237 goto failure; 15238 } 15239 } 15240 15241 result = update_sigs(diff, db, ver, zone_keys, nkeys, zone, 15242 inception, soaexpire, now, check_ksk, 15243 keyset_kskonly, sig_diff); 15244 15245 if (result != ISC_R_SUCCESS) { 15246 dns_zone_log(zone, ISC_LOG_ERROR, 15247 "sign_apex:update_sigs -> %s", 15248 dns_result_totext(result)); 15249 goto failure; 15250 } 15251 15252 failure: 15253 for (i = 0; i < nkeys; i++) 15254 dst_key_free(&zone_keys[i]); 15255 return (result); 15256} 15257 15258/* 15259 * Prevent the zone entering a inconsistent state where 15260 * NSEC only DNSKEYs are present with NSEC3 chains. 15261 * See update.c:check_dnssec() 15262 */ 15263static isc_boolean_t 15264dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 15265 dns_diff_t *diff) 15266{ 15267 isc_result_t result; 15268 dns_difftuple_t *tuple; 15269 isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE; 15270 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); 15271 15272 /* Scan the tuples for an NSEC-only DNSKEY */ 15273 for (tuple = ISC_LIST_HEAD(diff->tuples); 15274 tuple != NULL; 15275 tuple = ISC_LIST_NEXT(tuple, link)) { 15276 isc_uint8_t alg; 15277 if (tuple->rdata.type != dns_rdatatype_dnskey || 15278 tuple->op != DNS_DIFFOP_ADD) 15279 continue; 15280 15281 alg = tuple->rdata.data[3]; 15282 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 || 15283 alg == DST_ALG_DSA || alg == DST_ALG_ECC) { 15284 nseconly = ISC_TRUE; 15285 break; 15286 } 15287 } 15288 15289 /* Check existing DB for NSEC-only DNSKEY */ 15290 if (!nseconly) { 15291 result = dns_nsec_nseconly(db, ver, &nseconly); 15292 if (result == ISC_R_NOTFOUND) 15293 result = ISC_R_SUCCESS; 15294 CHECK(result); 15295 } 15296 15297 /* Check existing DB for NSEC3 */ 15298 if (!nsec3) 15299 CHECK(dns_nsec3_activex(db, ver, ISC_FALSE, 15300 privatetype, &nsec3)); 15301 15302 /* Refuse to allow NSEC3 with NSEC-only keys */ 15303 if (nseconly && nsec3) { 15304 dns_zone_log(zone, ISC_LOG_ERROR, 15305 "NSEC only DNSKEYs and NSEC3 chains not allowed"); 15306 goto failure; 15307 } 15308 15309 return (ISC_TRUE); 15310 15311 failure: 15312 return (ISC_FALSE); 15313} 15314 15315static isc_result_t 15316clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 15317 dns_diff_t *diff) 15318{ 15319 isc_result_t result; 15320 dns_dbnode_t *node = NULL; 15321 dns_rdataset_t rdataset; 15322 15323 dns_rdataset_init(&rdataset); 15324 CHECK(dns_db_getoriginnode(db, &node)); 15325 15326 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 15327 dns_rdatatype_none, 0, &rdataset, NULL); 15328 if (dns_rdataset_isassociated(&rdataset)) 15329 dns_rdataset_disassociate(&rdataset); 15330 if (result != ISC_R_NOTFOUND) 15331 goto failure; 15332 15333 result = dns_nsec3param_deletechains(db, ver, zone, ISC_TRUE, diff); 15334 15335 failure: 15336 if (node != NULL) 15337 dns_db_detachnode(db, &node); 15338 return (result); 15339} 15340 15341/* 15342 * Given an RRSIG rdataset and an algorithm, determine whether there 15343 * are any signatures using that algorithm. 15344 */ 15345static isc_boolean_t 15346signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) { 15347 dns_rdata_t rdata = DNS_RDATA_INIT; 15348 dns_rdata_rrsig_t rrsig; 15349 isc_result_t result; 15350 15351 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig); 15352 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) { 15353 return (ISC_FALSE); 15354 } 15355 15356 for (result = dns_rdataset_first(rdataset); 15357 result == ISC_R_SUCCESS; 15358 result = dns_rdataset_next(rdataset)) 15359 { 15360 dns_rdataset_current(rdataset, &rdata); 15361 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 15362 RUNTIME_CHECK(result == ISC_R_SUCCESS); 15363 dns_rdata_reset(&rdata); 15364 if (rrsig.algorithm == alg) 15365 return (ISC_TRUE); 15366 } 15367 15368 return (ISC_FALSE); 15369} 15370 15371static isc_result_t 15372add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 15373 dns_diff_t *diff) 15374{ 15375 dns_name_t *origin; 15376 isc_boolean_t build_nsec3; 15377 isc_result_t result; 15378 15379 origin = dns_db_origin(db); 15380 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL, 15381 &build_nsec3)); 15382 if (build_nsec3) 15383 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum, 15384 ISC_FALSE, zone->privatetype, diff)); 15385 CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff)); 15386 15387 failure: 15388 return (result); 15389} 15390 15391static void 15392zone_rekey(dns_zone_t *zone) { 15393 isc_result_t result; 15394 dns_db_t *db = NULL; 15395 dns_dbnode_t *node = NULL; 15396 dns_dbversion_t *ver = NULL; 15397 dns_rdataset_t soaset, soasigs, keyset, keysigs; 15398 dns_dnsseckeylist_t dnskeys, keys, rmkeys; 15399 dns_dnsseckey_t *key; 15400 dns_diff_t diff, sig_diff; 15401 isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE; 15402 isc_boolean_t newalg = ISC_FALSE; 15403 isc_boolean_t fullsign; 15404 dns_ttl_t ttl = 3600; 15405 const char *dir; 15406 isc_mem_t *mctx; 15407 isc_stdtime_t now; 15408 isc_time_t timenow; 15409 isc_interval_t ival; 15410 char timebuf[80]; 15411 15412 REQUIRE(DNS_ZONE_VALID(zone)); 15413 15414 ISC_LIST_INIT(dnskeys); 15415 ISC_LIST_INIT(keys); 15416 ISC_LIST_INIT(rmkeys); 15417 dns_rdataset_init(&soaset); 15418 dns_rdataset_init(&soasigs); 15419 dns_rdataset_init(&keyset); 15420 dns_rdataset_init(&keysigs); 15421 dir = dns_zone_getkeydirectory(zone); 15422 mctx = zone->mctx; 15423 dns_diff_init(mctx, &diff); 15424 dns_diff_init(mctx, &sig_diff); 15425 sig_diff.resign = zone->sigresigninginterval; 15426 15427 CHECK(dns_zone_getdb(zone, &db)); 15428 CHECK(dns_db_newversion(db, &ver)); 15429 CHECK(dns_db_getoriginnode(db, &node)); 15430 15431 TIME_NOW(&timenow); 15432 now = isc_time_seconds(&timenow); 15433 15434 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys"); 15435 15436 /* Get the SOA record's TTL */ 15437 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 15438 dns_rdatatype_none, 0, &soaset, &soasigs)); 15439 ttl = soaset.ttl; 15440 dns_rdataset_disassociate(&soaset); 15441 15442 /* Get the DNSKEY rdataset */ 15443 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 15444 dns_rdatatype_none, 0, &keyset, &keysigs); 15445 if (result == ISC_R_SUCCESS) { 15446 ttl = keyset.ttl; 15447 CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir, 15448 mctx, &keyset, 15449 &keysigs, &soasigs, 15450 ISC_FALSE, ISC_FALSE, 15451 &dnskeys)); 15452 } else if (result != ISC_R_NOTFOUND) 15453 goto failure; 15454 15455 /* 15456 * True when called from "rndc sign". Indicates the zone should be 15457 * fully signed now. 15458 */ 15459 fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0); 15460 15461 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys); 15462 if (result == ISC_R_SUCCESS) { 15463 isc_boolean_t check_ksk; 15464 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 15465 15466 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys, 15467 &zone->origin, ttl, &diff, 15468 ISC_TF(!check_ksk), 15469 mctx, logmsg); 15470 15471 /* Keys couldn't be updated for some reason; 15472 * try again later. */ 15473 if (result != ISC_R_SUCCESS) { 15474 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:" 15475 "couldn't update zone keys: %s", 15476 isc_result_totext(result)); 15477 goto failure; 15478 } 15479 15480 /* 15481 * See if any pre-existing keys have newly become active; 15482 * also, see if any new key is for a new algorithm, as in that 15483 * event, we need to sign the zone fully. (If there's a new 15484 * key, but it's for an already-existing algorithm, then 15485 * the zone signing can be handled incrementally.) 15486 */ 15487 for (key = ISC_LIST_HEAD(dnskeys); 15488 key != NULL; 15489 key = ISC_LIST_NEXT(key, link)) { 15490 if (!key->first_sign) 15491 continue; 15492 15493 newactive = ISC_TRUE; 15494 15495 if (!dns_rdataset_isassociated(&keysigs)) { 15496 newalg = ISC_TRUE; 15497 break; 15498 } 15499 15500 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) { 15501 /* 15502 * This isn't a new algorithm; clear 15503 * first_sign so we won't sign the 15504 * whole zone with this key later 15505 */ 15506 key->first_sign = ISC_FALSE; 15507 } else { 15508 newalg = ISC_TRUE; 15509 break; 15510 } 15511 } 15512 15513 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) && 15514 dnskey_sane(zone, db, ver, &diff)) { 15515 CHECK(dns_diff_apply(&diff, db, ver)); 15516 CHECK(clean_nsec3param(zone, db, ver, &diff)); 15517 CHECK(add_signing_records(db, zone->privatetype, 15518 ver, &diff, 15519 ISC_TF(newalg || fullsign))); 15520 CHECK(update_soa_serial(db, ver, &diff, mctx, 15521 zone->updatemethod)); 15522 CHECK(add_chains(zone, db, ver, &diff)); 15523 CHECK(sign_apex(zone, db, ver, &diff, &sig_diff)); 15524 CHECK(zone_journal(zone, &sig_diff, NULL, 15525 "zone_rekey")); 15526 commit = ISC_TRUE; 15527 } 15528 } 15529 15530 dns_db_closeversion(db, &ver, commit); 15531 15532 if (commit) { 15533 dns_difftuple_t *tuple; 15534 15535 LOCK_ZONE(zone); 15536 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 15537 15538 zone_needdump(zone, DNS_DUMP_DELAY); 15539 15540 zone_settimer(zone, &timenow); 15541 15542 /* Remove any signatures from removed keys. */ 15543 if (!ISC_LIST_EMPTY(rmkeys)) { 15544 for (key = ISC_LIST_HEAD(rmkeys); 15545 key != NULL; 15546 key = ISC_LIST_NEXT(key, link)) { 15547 result = zone_signwithkey(zone, 15548 dst_key_alg(key->key), 15549 dst_key_id(key->key), 15550 ISC_TRUE); 15551 if (result != ISC_R_SUCCESS) { 15552 dns_zone_log(zone, ISC_LOG_ERROR, 15553 "zone_signwithkey failed: %s", 15554 dns_result_totext(result)); 15555 } 15556 } 15557 } 15558 15559 if (fullsign) { 15560 /* 15561 * "rndc sign" was called, so we now sign the zone 15562 * with all active keys, whether they're new or not. 15563 */ 15564 for (key = ISC_LIST_HEAD(dnskeys); 15565 key != NULL; 15566 key = ISC_LIST_NEXT(key, link)) { 15567 if (!key->force_sign && !key->hint_sign) 15568 continue; 15569 15570 result = zone_signwithkey(zone, 15571 dst_key_alg(key->key), 15572 dst_key_id(key->key), 15573 ISC_FALSE); 15574 if (result != ISC_R_SUCCESS) { 15575 dns_zone_log(zone, ISC_LOG_ERROR, 15576 "zone_signwithkey failed: %s", 15577 dns_result_totext(result)); 15578 } 15579 } 15580 } else if (newalg) { 15581 /* 15582 * We haven't been told to sign fully, but a new 15583 * algorithm was added to the DNSKEY. We sign 15584 * the full zone, but only with newly active 15585 * keys. 15586 */ 15587 for (key = ISC_LIST_HEAD(dnskeys); 15588 key != NULL; 15589 key = ISC_LIST_NEXT(key, link)) { 15590 if (!key->first_sign) 15591 continue; 15592 15593 result = zone_signwithkey(zone, 15594 dst_key_alg(key->key), 15595 dst_key_id(key->key), 15596 ISC_FALSE); 15597 if (result != ISC_R_SUCCESS) { 15598 dns_zone_log(zone, ISC_LOG_ERROR, 15599 "zone_signwithkey failed: %s", 15600 dns_result_totext(result)); 15601 } 15602 } 15603 } 15604 15605 /* 15606 * Clear fullsign flag, if it was set, so we don't do 15607 * another full signing next time 15608 */ 15609 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN; 15610 15611 /* 15612 * Cause the zone to add/delete NSEC3 chains for the 15613 * deferred NSEC3PARAM changes. 15614 */ 15615 for (tuple = ISC_LIST_HEAD(sig_diff.tuples); 15616 tuple != NULL; 15617 tuple = ISC_LIST_NEXT(tuple, link)) { 15618 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 15619 dns_rdata_t rdata = DNS_RDATA_INIT; 15620 dns_rdata_nsec3param_t nsec3param; 15621 15622 if (tuple->rdata.type != zone->privatetype || 15623 tuple->op != DNS_DIFFOP_ADD) 15624 continue; 15625 15626 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata, 15627 buf, sizeof(buf))) 15628 continue; 15629 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 15630 RUNTIME_CHECK(result == ISC_R_SUCCESS); 15631 if (nsec3param.flags == 0) 15632 continue; 15633 15634 result = zone_addnsec3chain(zone, &nsec3param); 15635 if (result != ISC_R_SUCCESS) { 15636 dns_zone_log(zone, ISC_LOG_ERROR, 15637 "zone_addnsec3chain failed: %s", 15638 dns_result_totext(result)); 15639 } 15640 } 15641 15642 /* 15643 * Activate any NSEC3 chain updates that may have 15644 * been scheduled before this rekey. 15645 */ 15646 if (fullsign || newalg) 15647 resume_addnsec3chain(zone); 15648 15649 /* 15650 * Schedule the next resigning event 15651 */ 15652 set_resigntime(zone); 15653 UNLOCK_ZONE(zone); 15654 } 15655 15656 isc_time_settoepoch(&zone->refreshkeytime); 15657 15658 /* 15659 * If we're doing key maintenance, set the key refresh timer to 15660 * the next scheduled key event or to 'dnssec-loadkeys-interval' 15661 * seconds in the future, whichever is sooner. 15662 */ 15663 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) { 15664 isc_time_t timethen; 15665 isc_stdtime_t then; 15666 15667 LOCK_ZONE(zone); 15668 DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval, 15669 &timethen); 15670 zone->refreshkeytime = timethen; 15671 UNLOCK_ZONE(zone); 15672 15673 for (key = ISC_LIST_HEAD(dnskeys); 15674 key != NULL; 15675 key = ISC_LIST_NEXT(key, link)) { 15676 then = now; 15677 result = next_keyevent(key->key, &then); 15678 if (result != ISC_R_SUCCESS) 15679 continue; 15680 15681 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 15682 LOCK_ZONE(zone); 15683 if (isc_time_compare(&timethen, 15684 &zone->refreshkeytime) < 0) { 15685 zone->refreshkeytime = timethen; 15686 } 15687 UNLOCK_ZONE(zone); 15688 } 15689 15690 zone_settimer(zone, &timenow); 15691 15692 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 15693 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); 15694 } 15695 15696 done: 15697 dns_diff_clear(&diff); 15698 dns_diff_clear(&sig_diff); 15699 15700 clear_keylist(&dnskeys, mctx); 15701 clear_keylist(&keys, mctx); 15702 clear_keylist(&rmkeys, mctx); 15703 15704 if (ver != NULL) 15705 dns_db_closeversion(db, &ver, ISC_FALSE); 15706 if (dns_rdataset_isassociated(&keyset)) 15707 dns_rdataset_disassociate(&keyset); 15708 if (dns_rdataset_isassociated(&keysigs)) 15709 dns_rdataset_disassociate(&keysigs); 15710 if (dns_rdataset_isassociated(&soasigs)) 15711 dns_rdataset_disassociate(&soasigs); 15712 if (node != NULL) 15713 dns_db_detachnode(db, &node); 15714 if (db != NULL) 15715 dns_db_detach(&db); 15716 return; 15717 15718 failure: 15719 /* 15720 * Something went wrong; try again in ten minutes or 15721 * after a key refresh interval, whichever is shorter. 15722 */ 15723 isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 0); 15724 isc_time_nowplusinterval(&zone->refreshkeytime, &ival); 15725 goto done; 15726} 15727 15728void 15729dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) { 15730 isc_time_t now; 15731 15732 if (zone->type == dns_zone_master && zone->task != NULL) { 15733 LOCK_ZONE(zone); 15734 15735 if (fullsign) 15736 zone->keyopts |= DNS_ZONEKEY_FULLSIGN; 15737 15738 TIME_NOW(&now); 15739 zone->refreshkeytime = now; 15740 zone_settimer(zone, &now); 15741 15742 UNLOCK_ZONE(zone); 15743 } 15744} 15745 15746isc_result_t 15747dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 15748 unsigned int *errors) 15749{ 15750 isc_result_t result; 15751 dns_dbnode_t *node = NULL; 15752 15753 REQUIRE(DNS_ZONE_VALID(zone)); 15754 REQUIRE(errors != NULL); 15755 15756 result = dns_db_getoriginnode(db, &node); 15757 if (result != ISC_R_SUCCESS) 15758 return (result); 15759 result = zone_count_ns_rr(zone, db, node, version, NULL, errors, 15760 ISC_FALSE); 15761 dns_db_detachnode(db, &node); 15762 return (result); 15763} 15764 15765void 15766dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) { 15767 REQUIRE(DNS_ZONE_VALID(zone)); 15768 LOCK_ZONE(zone); 15769 zone->added = added; 15770 UNLOCK_ZONE(zone); 15771} 15772 15773isc_boolean_t 15774dns_zone_getadded(dns_zone_t *zone) { 15775 REQUIRE(DNS_ZONE_VALID(zone)); 15776 return (zone->added); 15777} 15778 15779isc_result_t 15780dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db) 15781{ 15782 isc_time_t loadtime; 15783 isc_result_t result; 15784 TIME_NOW(&loadtime); 15785 15786 /* 15787 * Lock hierachy zmgr, raw, zone. 15788 */ 15789 if (inline_secure(zone)) 15790 LOCK_ZONE(zone->raw); 15791 LOCK_ZONE(zone); 15792 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 15793 UNLOCK_ZONE(zone); 15794 if (inline_secure(zone)) 15795 UNLOCK_ZONE(zone->raw); 15796 return result; 15797} 15798 15799isc_result_t 15800dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval) { 15801 REQUIRE(DNS_ZONE_VALID(zone)); 15802 if (interval == 0) 15803 return (ISC_R_RANGE); 15804 /* Maximum value: 24 hours (3600 minutes) */ 15805 if (interval > (24 * 60)) 15806 interval = (24 * 60); 15807 /* Multiply by 60 for seconds */ 15808 zone->refreshkeyinterval = interval * 60; 15809 return (ISC_R_SUCCESS); 15810} 15811 15812void 15813dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t b) { 15814 REQUIRE(DNS_ZONE_VALID(zone)); 15815 zone->requestixfr = b; 15816} 15817 15818isc_boolean_t 15819dns_zone_getrequestixfr(dns_zone_t *zone) { 15820 REQUIRE(DNS_ZONE_VALID(zone)); 15821 return (zone->requestixfr); 15822} 15823 15824void 15825dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) { 15826 REQUIRE(DNS_ZONE_VALID(zone)); 15827 zone->updatemethod = method; 15828} 15829 15830dns_updatemethod_t 15831dns_zone_getserialupdatemethod(dns_zone_t *zone) { 15832 REQUIRE(DNS_ZONE_VALID(zone)); 15833 return(zone->updatemethod); 15834} 15835 15836/* 15837 * Lock hierachy zmgr, raw, zone. 15838 */ 15839isc_result_t 15840dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) { 15841 isc_result_t result; 15842 dns_zonemgr_t *zmgr; 15843 15844 REQUIRE(DNS_ZONE_VALID(zone)); 15845 REQUIRE(zone->zmgr != NULL); 15846 REQUIRE(zone->task != NULL); 15847 REQUIRE(zone->loadtask != NULL); 15848 REQUIRE(zone->raw == NULL); 15849 15850 REQUIRE(DNS_ZONE_VALID(raw)); 15851 REQUIRE(raw->zmgr == NULL); 15852 REQUIRE(raw->task == NULL); 15853 REQUIRE(raw->loadtask == NULL); 15854 REQUIRE(raw->secure == NULL); 15855 15856 zmgr = zone->zmgr; 15857 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 15858 LOCK_ZONE(raw); 15859 LOCK_ZONE(zone); 15860 15861 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, 15862 NULL, NULL, zone->task, zone_timer, raw, 15863 &raw->timer); 15864 if (result != ISC_R_SUCCESS) 15865 goto unlock; 15866 15867 /* 15868 * The timer "holds" a iref. 15869 */ 15870 raw->irefs++; 15871 INSIST(raw->irefs != 0); 15872 15873 15874 /* dns_zone_attach(raw, &zone->raw); */ 15875 isc_refcount_increment(&raw->erefs, NULL); 15876 zone->raw = raw; 15877 15878 /* dns_zone_iattach(zone, &raw->secure); */ 15879 zone_iattach(zone, &raw->secure); 15880 15881 isc_task_attach(zone->task, &raw->task); 15882 isc_task_attach(zone->loadtask, &raw->loadtask); 15883 15884 ISC_LIST_APPEND(zmgr->zones, raw, link); 15885 raw->zmgr = zmgr; 15886 zmgr->refs++; 15887 15888 unlock: 15889 UNLOCK_ZONE(zone); 15890 UNLOCK_ZONE(raw); 15891 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 15892 return (result); 15893} 15894 15895void 15896dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) { 15897 REQUIRE(DNS_ZONE_VALID(zone)); 15898 REQUIRE(raw != NULL && *raw == NULL); 15899 15900 LOCK(&zone->lock); 15901 if (zone->raw != NULL) 15902 dns_zone_attach(zone->raw, raw); 15903 UNLOCK(&zone->lock); 15904} 15905 15906struct keydone { 15907 isc_event_t event; 15908 isc_boolean_t all; 15909 unsigned char data[5]; 15910}; 15911 15912#define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL) 15913 15914static void 15915keydone(isc_task_t *task, isc_event_t *event) { 15916 const char *me = "keydone"; 15917 isc_boolean_t commit = ISC_FALSE; 15918 isc_result_t result; 15919 dns_rdata_t rdata = DNS_RDATA_INIT; 15920 dns_dbversion_t *oldver = NULL, *newver = NULL; 15921 dns_zone_t *zone; 15922 dns_db_t *db = NULL; 15923 dns_dbnode_t *node = NULL; 15924 dns_rdataset_t rdataset; 15925 dns_diff_t diff; 15926 struct keydone *keydone = (struct keydone *)event; 15927 dns_update_log_t log = { update_log_cb, NULL }; 15928 isc_boolean_t clear_pending = ISC_FALSE; 15929 15930 UNUSED(task); 15931 15932 zone = event->ev_arg; 15933 INSIST(DNS_ZONE_VALID(zone)); 15934 15935 ENTER; 15936 15937 dns_rdataset_init(&rdataset); 15938 dns_diff_init(zone->mctx, &diff); 15939 15940 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 15941 if (zone->db != NULL) { 15942 dns_db_attach(zone->db, &db); 15943 dns_db_currentversion(db, &oldver); 15944 result = dns_db_newversion(db, &newver); 15945 if (result != ISC_R_SUCCESS) { 15946 dns_zone_log(zone, ISC_LOG_ERROR, 15947 "keydone:dns_db_newversion -> %s", 15948 dns_result_totext(result)); 15949 goto failure; 15950 } 15951 } 15952 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 15953 if (db == NULL) 15954 goto failure; 15955 15956 result = dns_db_getoriginnode(db, &node); 15957 if (result != ISC_R_SUCCESS) 15958 goto failure; 15959 15960 result = dns_db_findrdataset(db, node, newver, zone->privatetype, 15961 dns_rdatatype_none, 0, &rdataset, NULL); 15962 if (result == ISC_R_NOTFOUND) { 15963 INSIST(!dns_rdataset_isassociated(&rdataset)); 15964 goto failure; 15965 } 15966 if (result != ISC_R_SUCCESS) { 15967 INSIST(!dns_rdataset_isassociated(&rdataset)); 15968 goto failure; 15969 } 15970 15971 for (result = dns_rdataset_first(&rdataset); 15972 result == ISC_R_SUCCESS; 15973 result = dns_rdataset_next(&rdataset)) { 15974 isc_boolean_t found = ISC_FALSE; 15975 15976 dns_rdataset_current(&rdataset, &rdata); 15977 15978 if (keydone->all) { 15979 if (rdata.length == 5 && rdata.data[0] != 0 && 15980 rdata.data[3] == 0 && rdata.data[4] == 1) 15981 found = ISC_TRUE; 15982 else if (rdata.data[0] == 0 && 15983 (rdata.data[2] & PENDINGFLAGS) != 0) { 15984 found = ISC_TRUE; 15985 clear_pending = ISC_TRUE; 15986 } 15987 } else if (rdata.length == 5 && 15988 memcmp(rdata.data, keydone->data, 5) == 0) 15989 found = ISC_TRUE; 15990 15991 if (found) 15992 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL, 15993 &zone->origin, rdataset.ttl, 15994 &rdata)); 15995 dns_rdata_reset(&rdata); 15996 } 15997 15998 if (!ISC_LIST_EMPTY(diff.tuples)) { 15999 /* Write changes to journal file. */ 16000 CHECK(update_soa_serial(db, newver, &diff, zone->mctx, 16001 zone->updatemethod)); 16002 16003 result = dns_update_signatures(&log, zone, db, 16004 oldver, newver, &diff, 16005 zone->sigvalidityinterval); 16006 if (!clear_pending) 16007 CHECK(result); 16008 16009 CHECK(zone_journal(zone, &diff, NULL, "keydone")); 16010 commit = ISC_TRUE; 16011 16012 LOCK_ZONE(zone); 16013 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 16014 zone_needdump(zone, 30); 16015 UNLOCK_ZONE(zone); 16016 } 16017 16018 failure: 16019 if (dns_rdataset_isassociated(&rdataset)) 16020 dns_rdataset_disassociate(&rdataset); 16021 if (db != NULL) { 16022 if (node != NULL) 16023 dns_db_detachnode(db, &node); 16024 if (oldver != NULL) 16025 dns_db_closeversion(db, &oldver, ISC_FALSE); 16026 if (newver != NULL) 16027 dns_db_closeversion(db, &newver, commit); 16028 dns_db_detach(&db); 16029 } 16030 dns_diff_clear(&diff); 16031 isc_event_free(&event); 16032 dns_zone_idetach(&zone); 16033} 16034 16035isc_result_t 16036dns_zone_keydone(dns_zone_t *zone, const char *keystr) { 16037 isc_result_t result = ISC_R_SUCCESS; 16038 isc_event_t *e; 16039 isc_buffer_t b; 16040 dns_zone_t *dummy = NULL; 16041 struct keydone *kd; 16042 16043 REQUIRE(DNS_ZONE_VALID(zone)); 16044 16045 LOCK_ZONE(zone); 16046 16047 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone, 16048 zone, sizeof(struct keydone)); 16049 if (e == NULL) { 16050 result = ISC_R_NOMEMORY; 16051 goto failure; 16052 } 16053 16054 kd = (struct keydone *) e; 16055 if (strcasecmp(keystr, "all") == 0) 16056 kd->all = ISC_TRUE; 16057 else { 16058 isc_textregion_t r; 16059 char *algstr; 16060 dns_keytag_t keyid; 16061 dns_secalg_t alg; 16062 size_t n; 16063 16064 kd->all = ISC_FALSE; 16065 16066 n = sscanf(keystr, "%hd/", &keyid); 16067 if (n == 0U) 16068 CHECK(ISC_R_FAILURE); 16069 16070 algstr = strchr(keystr, '/'); 16071 if (algstr != NULL) 16072 algstr++; 16073 else 16074 CHECK(ISC_R_FAILURE); 16075 16076 n = sscanf(algstr, "%hhd", &alg); 16077 if (n == 0U) { 16078 DE_CONST(algstr, r.base); 16079 r.length = strlen(algstr); 16080 CHECK(dns_secalg_fromtext(&alg, &r)); 16081 } 16082 16083 /* construct a private-type rdata */ 16084 isc_buffer_init(&b, kd->data, sizeof(kd->data)); 16085 isc_buffer_putuint8(&b, alg); 16086 isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8); 16087 isc_buffer_putuint8(&b, (keyid & 0xff)); 16088 isc_buffer_putuint8(&b, 0); 16089 isc_buffer_putuint8(&b, 1); 16090 } 16091 16092 zone_iattach(zone, &dummy); 16093 isc_task_send(zone->task, &e); 16094 16095 failure: 16096 if (e != NULL) 16097 isc_event_free(&e); 16098 UNLOCK_ZONE(zone); 16099 return (result); 16100} 16101 16102struct nsec3param { 16103 isc_event_t event; 16104 unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1]; 16105 unsigned int length; 16106 isc_boolean_t nsec; 16107 isc_boolean_t replace; 16108}; 16109 16110static void 16111setnsec3param(isc_task_t *task, isc_event_t *event) { 16112 const char *me = "setnsec3param"; 16113 isc_boolean_t commit = ISC_FALSE; 16114 isc_result_t result; 16115 dns_dbversion_t *oldver = NULL, *newver = NULL; 16116 dns_zone_t *zone; 16117 dns_db_t *db = NULL; 16118 dns_dbnode_t *node = NULL; 16119 dns_rdataset_t prdataset, nrdataset; 16120 dns_diff_t diff; 16121 struct nsec3param *np = (struct nsec3param *)event; 16122 dns_update_log_t log = { update_log_cb, NULL }; 16123 dns_rdata_t rdata; 16124 isc_boolean_t nseconly; 16125 isc_boolean_t exists = ISC_FALSE; 16126 16127 UNUSED(task); 16128 16129 zone = event->ev_arg; 16130 INSIST(DNS_ZONE_VALID(zone)); 16131 16132 ENTER; 16133 16134 dns_rdataset_init(&prdataset); 16135 dns_rdataset_init(&nrdataset); 16136 dns_diff_init(zone->mctx, &diff); 16137 16138 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 16139 if (zone->db != NULL) { 16140 dns_db_attach(zone->db, &db); 16141 dns_db_currentversion(db, &oldver); 16142 result = dns_db_newversion(db, &newver); 16143 if (result != ISC_R_SUCCESS) { 16144 dns_zone_log(zone, ISC_LOG_ERROR, 16145 "setnsec3param:dns_db_newversion -> %s", 16146 dns_result_totext(result)); 16147 goto failure; 16148 } 16149 } 16150 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 16151 if (db == NULL) 16152 goto failure; 16153 16154 CHECK(dns_db_getoriginnode(db, &node)); 16155 16156 /* 16157 * Does a private-type record already exist for this chain? 16158 */ 16159 result = dns_db_findrdataset(db, node, newver, zone->privatetype, 16160 dns_rdatatype_none, 0, &prdataset, NULL); 16161 if (result == ISC_R_SUCCESS) { 16162 for (result = dns_rdataset_first(&prdataset); 16163 result == ISC_R_SUCCESS; 16164 result = dns_rdataset_next(&prdataset)) { 16165 dns_rdata_init(&rdata); 16166 dns_rdataset_current(&prdataset, &rdata); 16167 16168 if (np->length == rdata.length && 16169 memcmp(rdata.data, np->data, np->length) == 0) { 16170 exists = ISC_TRUE; 16171 break; 16172 } 16173 } 16174 } else if (result != ISC_R_NOTFOUND) { 16175 INSIST(!dns_rdataset_isassociated(&prdataset)); 16176 goto failure; 16177 } 16178 16179 /* 16180 * Does the chain already exist? 16181 */ 16182 result = dns_db_findrdataset(db, node, newver, 16183 dns_rdatatype_nsec3param, 16184 dns_rdatatype_none, 0, &nrdataset, NULL); 16185 if (result == ISC_R_SUCCESS) { 16186 for (result = dns_rdataset_first(&nrdataset); 16187 result == ISC_R_SUCCESS; 16188 result = dns_rdataset_next(&nrdataset)) { 16189 dns_rdata_init(&rdata); 16190 dns_rdataset_current(&nrdataset, &rdata); 16191 16192 if (np->length == (rdata.length + 1) && 16193 memcmp(rdata.data, np->data + 1, 16194 np->length - 1) == 0) 16195 { 16196 exists = ISC_TRUE; 16197 break; 16198 } 16199 } 16200 } else if (result != ISC_R_NOTFOUND) { 16201 INSIST(!dns_rdataset_isassociated(&nrdataset)); 16202 goto failure; 16203 } 16204 16205 16206 /* 16207 * We need to remove any existing NSEC3 chains. 16208 */ 16209 if (!exists && np->replace && (np->length != 0 || np->nsec)) 16210 CHECK(dns_nsec3param_deletechains(db, newver, zone, 16211 !np->nsec, &diff)); 16212 16213 if (!exists && np->length != 0) { 16214 /* 16215 * We're creating an NSEC3 chain. 16216 * 16217 * If the zone is not currently capable of supporting 16218 * an NSEC3 chain, add the INITIAL flag, so these 16219 * parameters can be used later when NSEC3 becomes 16220 * available. 16221 */ 16222 dns_rdata_init(&rdata); 16223 16224 np->data[2] |= DNS_NSEC3FLAG_CREATE; 16225 result = dns_nsec_nseconly(db, newver, &nseconly); 16226 if (result == ISC_R_NOTFOUND || nseconly) 16227 np->data[2] |= DNS_NSEC3FLAG_INITIAL; 16228 16229 rdata.length = np->length; 16230 rdata.data = np->data; 16231 rdata.type = zone->privatetype; 16232 rdata.rdclass = zone->rdclass; 16233 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD, 16234 &zone->origin, 0, &rdata)); 16235 } 16236 16237 if (!ISC_LIST_EMPTY(diff.tuples)) { 16238 /* Write changes to journal file. */ 16239 CHECK(update_soa_serial(db, newver, &diff, zone->mctx, 16240 zone->updatemethod)); 16241 result = dns_update_signatures(&log, zone, db, 16242 oldver, newver, &diff, 16243 zone->sigvalidityinterval); 16244 if (result != ISC_R_NOTFOUND) 16245 CHECK(result); 16246 CHECK(zone_journal(zone, &diff, NULL, "setnsec3param")); 16247 commit = ISC_TRUE; 16248 16249 LOCK_ZONE(zone); 16250 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 16251 zone_needdump(zone, 30); 16252 UNLOCK_ZONE(zone); 16253 } 16254 16255 failure: 16256 if (dns_rdataset_isassociated(&prdataset)) 16257 dns_rdataset_disassociate(&prdataset); 16258 if (dns_rdataset_isassociated(&nrdataset)) 16259 dns_rdataset_disassociate(&nrdataset); 16260 if (node != NULL) 16261 dns_db_detachnode(db, &node); 16262 if (oldver != NULL) 16263 dns_db_closeversion(db, &oldver, ISC_FALSE); 16264 if (newver != NULL) 16265 dns_db_closeversion(db, &newver, commit); 16266 if (db != NULL) 16267 dns_db_detach(&db); 16268 if (commit) 16269 resume_addnsec3chain(zone); 16270 dns_diff_clear(&diff); 16271 isc_event_free(&event); 16272 dns_zone_idetach(&zone); 16273} 16274 16275isc_result_t 16276dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags, 16277 isc_uint8_t iter, isc_uint8_t saltlen, 16278 unsigned char *salt, isc_boolean_t replace) 16279{ 16280 isc_result_t result = ISC_R_SUCCESS; 16281 dns_rdata_nsec3param_t param; 16282 dns_rdata_t nrdata = DNS_RDATA_INIT; 16283 dns_rdata_t prdata = DNS_RDATA_INIT; 16284 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE]; 16285 struct nsec3param *np; 16286 dns_zone_t *dummy = NULL; 16287 isc_buffer_t b; 16288 isc_event_t *e; 16289 16290 REQUIRE(DNS_ZONE_VALID(zone)); 16291 REQUIRE(salt != NULL); 16292 16293 LOCK_ZONE(zone); 16294 16295 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM, 16296 setnsec3param, zone, sizeof(struct nsec3param)); 16297 if (e == NULL) { 16298 result = ISC_R_NOMEMORY; 16299 goto failure; 16300 } 16301 16302 np = (struct nsec3param *) e; 16303 np->replace = replace; 16304 if (hash == 0) { 16305 np->length = 0; 16306 np->nsec = ISC_TRUE; 16307 } else { 16308 param.common.rdclass = zone->rdclass; 16309 param.common.rdtype = dns_rdatatype_nsec3param; 16310 ISC_LINK_INIT(¶m.common, link); 16311 param.mctx = NULL; 16312 param.hash = hash; 16313 param.flags = flags; 16314 param.iterations = iter; 16315 param.salt_length = saltlen; 16316 param.salt = salt; 16317 isc_buffer_init(&b, nbuf, sizeof(nbuf)); 16318 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass, 16319 dns_rdatatype_nsec3param, 16320 ¶m, &b)); 16321 dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype, 16322 np->data, sizeof(np->data)); 16323 np->length = prdata.length; 16324 } 16325 16326 zone_iattach(zone, &dummy); 16327 isc_task_send(zone->task, &e); 16328 16329 failure: 16330 if (e != NULL) 16331 isc_event_free(&e); 16332 UNLOCK_ZONE(zone); 16333 return (result); 16334} 16335