1/* 2 * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1999-2003 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id$ */ 19 20/*! \file */ 21 22#include <config.h> 23#include <errno.h> 24 25#include <isc/file.h> 26#include <isc/mutex.h> 27#include <isc/print.h> 28#include <isc/random.h> 29#include <isc/ratelimiter.h> 30#include <isc/refcount.h> 31#include <isc/rwlock.h> 32#include <isc/serial.h> 33#include <isc/strerror.h> 34#include <isc/stats.h> 35#include <isc/stdtime.h> 36#include <isc/string.h> 37#include <isc/taskpool.h> 38#include <isc/timer.h> 39#include <isc/util.h> 40 41#include <dns/acache.h> 42#include <dns/acl.h> 43#include <dns/adb.h> 44#include <dns/callbacks.h> 45#include <dns/db.h> 46#include <dns/dbiterator.h> 47#include <dns/dnssec.h> 48#include <dns/events.h> 49#include <dns/journal.h> 50#include <dns/keydata.h> 51#include <dns/keytable.h> 52#include <dns/keyvalues.h> 53#include <dns/log.h> 54#include <dns/master.h> 55#include <dns/masterdump.h> 56#include <dns/message.h> 57#include <dns/name.h> 58#include <dns/nsec.h> 59#include <dns/nsec3.h> 60#include <dns/peer.h> 61#include <dns/private.h> 62#include <dns/rbt.h> 63#include <dns/rcode.h> 64#include <dns/rdataclass.h> 65#include <dns/rdatalist.h> 66#include <dns/rdataset.h> 67#include <dns/rdatasetiter.h> 68#include <dns/rdatastruct.h> 69#include <dns/rdatatype.h> 70#include <dns/request.h> 71#include <dns/resolver.h> 72#include <dns/result.h> 73#include <dns/rriterator.h> 74#include <dns/soa.h> 75#include <dns/ssu.h> 76#include <dns/stats.h> 77#include <dns/time.h> 78#include <dns/tsig.h> 79#include <dns/xfrin.h> 80#include <dns/zone.h> 81 82#include <dst/dst.h> 83 84#define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E') 85#define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC) 86 87#define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y') 88#define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC) 89 90#define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b') 91#define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC) 92 93#define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r') 94#define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC) 95 96#define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd') 97#define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC) 98 99#define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w') 100#define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC) 101 102#define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O') 103#define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC) 104 105/*% 106 * Ensure 'a' is at least 'min' but not more than 'max'. 107 */ 108#define RANGE(a, min, max) \ 109 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max))) 110 111#define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) 112 113/*% 114 * Key flags 115 */ 116#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0) 117#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0) 118#define ALG(x) dst_key_alg(x) 119 120/* 121 * Default values. 122 */ 123#define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */ 124#define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */ 125#define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */ 126#define RESIGN_DELAY 3600 /*%< 1 hour */ 127 128#ifndef DNS_MAX_EXPIRE 129#define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */ 130#endif 131 132#ifndef DNS_DUMP_DELAY 133#define DNS_DUMP_DELAY 900 /*%< 15 minutes */ 134#endif 135 136typedef struct dns_notify dns_notify_t; 137typedef struct dns_stub dns_stub_t; 138typedef struct dns_load dns_load_t; 139typedef struct dns_forward dns_forward_t; 140typedef ISC_LIST(dns_forward_t) dns_forwardlist_t; 141typedef struct dns_io dns_io_t; 142typedef ISC_LIST(dns_io_t) dns_iolist_t; 143typedef struct dns_signing dns_signing_t; 144typedef ISC_LIST(dns_signing_t) dns_signinglist_t; 145typedef struct dns_nsec3chain dns_nsec3chain_t; 146typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t; 147typedef struct dns_keyfetch dns_keyfetch_t; 148 149#define DNS_ZONE_CHECKLOCK 150#ifdef DNS_ZONE_CHECKLOCK 151#define LOCK_ZONE(z) \ 152 do { LOCK(&(z)->lock); \ 153 INSIST((z)->locked == ISC_FALSE); \ 154 (z)->locked = ISC_TRUE; \ 155 } while (0) 156#define UNLOCK_ZONE(z) \ 157 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0) 158#define LOCKED_ZONE(z) ((z)->locked) 159#else 160#define LOCK_ZONE(z) LOCK(&(z)->lock) 161#define UNLOCK_ZONE(z) UNLOCK(&(z)->lock) 162#define LOCKED_ZONE(z) ISC_TRUE 163#endif 164 165#ifdef ISC_RWLOCK_USEATOMIC 166#define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0) 167#define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l) 168#define ZONEDB_LOCK(l, t) RWLOCK((l), (t)) 169#define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t)) 170#else 171#define ZONEDB_INITLOCK(l) isc_mutex_init(l) 172#define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l) 173#define ZONEDB_LOCK(l, t) LOCK(l) 174#define ZONEDB_UNLOCK(l, t) UNLOCK(l) 175#endif 176 177struct dns_zone { 178 /* Unlocked */ 179 unsigned int magic; 180 isc_mutex_t lock; 181#ifdef DNS_ZONE_CHECKLOCK 182 isc_boolean_t locked; 183#endif 184 isc_mem_t *mctx; 185 isc_refcount_t erefs; 186 187#ifdef ISC_RWLOCK_USEATOMIC 188 isc_rwlock_t dblock; 189#else 190 isc_mutex_t dblock; 191#endif 192 dns_db_t *db; /* Locked by dblock */ 193 194 /* Locked */ 195 dns_zonemgr_t *zmgr; 196 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */ 197 isc_timer_t *timer; 198 unsigned int irefs; 199 dns_name_t origin; 200 char *masterfile; 201 dns_masterformat_t masterformat; 202 char *journal; 203 isc_int32_t journalsize; 204 dns_rdataclass_t rdclass; 205 dns_zonetype_t type; 206 unsigned int flags; 207 unsigned int options; 208 unsigned int db_argc; 209 char **db_argv; 210 isc_time_t expiretime; 211 isc_time_t refreshtime; 212 isc_time_t dumptime; 213 isc_time_t loadtime; 214 isc_time_t notifytime; 215 isc_time_t resigntime; 216 isc_time_t keywarntime; 217 isc_time_t signingtime; 218 isc_time_t nsec3chaintime; 219 isc_time_t refreshkeytime; 220 isc_uint32_t refreshkeycount; 221 isc_uint32_t refresh; 222 isc_uint32_t retry; 223 isc_uint32_t expire; 224 isc_uint32_t minimum; 225 isc_stdtime_t key_expiry; 226 isc_stdtime_t log_key_expired_timer; 227 char *keydirectory; 228 229 isc_uint32_t maxrefresh; 230 isc_uint32_t minrefresh; 231 isc_uint32_t maxretry; 232 isc_uint32_t minretry; 233 234 isc_sockaddr_t *masters; 235 dns_name_t **masterkeynames; 236 isc_boolean_t *mastersok; 237 unsigned int masterscnt; 238 unsigned int curmaster; 239 isc_sockaddr_t masteraddr; 240 dns_notifytype_t notifytype; 241 isc_sockaddr_t *notify; 242 unsigned int notifycnt; 243 isc_sockaddr_t notifyfrom; 244 isc_task_t *task; 245 isc_sockaddr_t notifysrc4; 246 isc_sockaddr_t notifysrc6; 247 isc_sockaddr_t xfrsource4; 248 isc_sockaddr_t xfrsource6; 249 isc_sockaddr_t altxfrsource4; 250 isc_sockaddr_t altxfrsource6; 251 isc_sockaddr_t sourceaddr; 252 dns_xfrin_ctx_t *xfr; /* task locked */ 253 dns_tsigkey_t *tsigkey; /* key used for xfr */ 254 /* Access Control Lists */ 255 dns_acl_t *update_acl; 256 dns_acl_t *forward_acl; 257 dns_acl_t *notify_acl; 258 dns_acl_t *query_acl; 259 dns_acl_t *queryon_acl; 260 dns_acl_t *xfr_acl; 261 isc_boolean_t update_disabled; 262 isc_boolean_t zero_no_soa_ttl; 263 dns_severity_t check_names; 264 ISC_LIST(dns_notify_t) notifies; 265 dns_request_t *request; 266 dns_loadctx_t *lctx; 267 dns_io_t *readio; 268 dns_dumpctx_t *dctx; 269 dns_io_t *writeio; 270 isc_uint32_t maxxfrin; 271 isc_uint32_t maxxfrout; 272 isc_uint32_t idlein; 273 isc_uint32_t idleout; 274 isc_event_t ctlevent; 275 dns_ssutable_t *ssutable; 276 isc_uint32_t sigvalidityinterval; 277 isc_uint32_t sigresigninginterval; 278 dns_view_t *view; 279 dns_acache_t *acache; 280 dns_checkmxfunc_t checkmx; 281 dns_checksrvfunc_t checksrv; 282 dns_checknsfunc_t checkns; 283 /*% 284 * Zones in certain states such as "waiting for zone transfer" 285 * or "zone transfer in progress" are kept on per-state linked lists 286 * in the zone manager using the 'statelink' field. The 'statelist' 287 * field points at the list the zone is currently on. It the zone 288 * is not on any such list, statelist is NULL. 289 */ 290 ISC_LINK(dns_zone_t) statelink; 291 dns_zonelist_t *statelist; 292 /*% 293 * Statistics counters about zone management. 294 */ 295 isc_stats_t *stats; 296 /*% 297 * Optional per-zone statistics counters. Counted outside of this 298 * module. 299 */ 300 isc_boolean_t requeststats_on; 301 isc_stats_t *requeststats; 302 isc_uint32_t notifydelay; 303 dns_isselffunc_t isself; 304 void *isselfarg; 305 306 char * strnamerd; 307 char * strname; 308 char * strrdclass; 309 char * strviewname; 310 311 /*% 312 * Serial number for deferred journal compaction. 313 */ 314 isc_uint32_t compact_serial; 315 /*% 316 * Keys that are signing the zone for the first time. 317 */ 318 dns_signinglist_t signing; 319 dns_nsec3chainlist_t nsec3chain; 320 /*% 321 * Signing / re-signing quantum stopping parameters. 322 */ 323 isc_uint32_t signatures; 324 isc_uint32_t nodes; 325 dns_rdatatype_t privatetype; 326 327 /*% 328 * Autosigning/key-maintenance options 329 */ 330 isc_uint32_t keyopts; 331 332 /*% 333 * True if added by "rndc addzone" 334 */ 335 isc_boolean_t added; 336 337 /*% 338 * whether a rpz radix was needed when last loaded 339 */ 340 isc_boolean_t rpz_zone; 341 342 /*% 343 * Outstanding forwarded UPDATE requests. 344 */ 345 dns_forwardlist_t forwards; 346}; 347 348#define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0)) 349#define DNS_ZONE_SETFLAG(z,f) do { \ 350 INSIST(LOCKED_ZONE(z)); \ 351 (z)->flags |= (f); \ 352 } while (0) 353#define DNS_ZONE_CLRFLAG(z,f) do { \ 354 INSIST(LOCKED_ZONE(z)); \ 355 (z)->flags &= ~(f); \ 356 } while (0) 357 /* XXX MPA these may need to go back into zone.h */ 358#define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */ 359#define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */ 360#define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */ 361#define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */ 362#define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */ 363#define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */ 364#define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */ 365#define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */ 366#define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */ 367#define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are 368 * uptodate */ 369#define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify 370 * messages */ 371#define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on 372 * reload */ 373#define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a 374 * zone with no masters 375 * occurred */ 376#define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/ 377#define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set 378 * from SOA (if not set, we 379 * are still using 380 * default timer values) */ 381#define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */ 382#define DNS_ZONEFLG_NOREFRESH 0x00010000U 383#define DNS_ZONEFLG_DIALNOTIFY 0x00020000U 384#define DNS_ZONEFLG_DIALREFRESH 0x00040000U 385#define DNS_ZONEFLG_SHUTDOWN 0x00080000U 386#define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */ 387#define DNS_ZONEFLG_FLUSH 0x00200000U 388#define DNS_ZONEFLG_NOEDNS 0x00400000U 389#define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U 390#define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U 391#define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U 392#define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */ 393#define DNS_ZONEFLG_THAW 0x08000000U 394/* #define DNS_ZONEFLG_XXXXX 0x10000000U XXXMPA unused. */ 395#define DNS_ZONEFLG_NODELAY 0x20000000U 396 397#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0) 398#define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0) 399 400/* Flags for zone_load() */ 401#define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */ 402#define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful 403 load. */ 404 405#define UNREACH_CHACHE_SIZE 10U 406#define UNREACH_HOLD_TIME 600 /* 10 minutes */ 407 408#define CHECK(op) \ 409 do { result = (op); \ 410 if (result != ISC_R_SUCCESS) goto failure; \ 411 } while (0) 412 413struct dns_unreachable { 414 isc_sockaddr_t remote; 415 isc_sockaddr_t local; 416 isc_uint32_t expire; 417 isc_uint32_t last; 418}; 419 420struct dns_zonemgr { 421 unsigned int magic; 422 isc_mem_t * mctx; 423 int refs; /* Locked by rwlock */ 424 isc_taskmgr_t * taskmgr; 425 isc_timermgr_t * timermgr; 426 isc_socketmgr_t * socketmgr; 427 isc_taskpool_t * zonetasks; 428 isc_task_t * task; 429 isc_ratelimiter_t * rl; 430 isc_rwlock_t rwlock; 431 isc_mutex_t iolock; 432 isc_rwlock_t urlock; 433 434 /* Locked by rwlock. */ 435 dns_zonelist_t zones; 436 dns_zonelist_t waiting_for_xfrin; 437 dns_zonelist_t xfrin_in_progress; 438 439 /* Configuration data. */ 440 isc_uint32_t transfersin; 441 isc_uint32_t transfersperns; 442 unsigned int serialqueryrate; 443 444 /* Locked by iolock */ 445 isc_uint32_t iolimit; 446 isc_uint32_t ioactive; 447 dns_iolist_t high; 448 dns_iolist_t low; 449 450 /* Locked by urlock. */ 451 /* LRU cache */ 452 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE]; 453}; 454 455/*% 456 * Hold notify state. 457 */ 458struct dns_notify { 459 unsigned int magic; 460 unsigned int flags; 461 isc_mem_t *mctx; 462 dns_zone_t *zone; 463 dns_adbfind_t *find; 464 dns_request_t *request; 465 dns_name_t ns; 466 isc_sockaddr_t dst; 467 ISC_LINK(dns_notify_t) link; 468}; 469 470#define DNS_NOTIFY_NOSOA 0x0001U 471 472/*% 473 * dns_stub holds state while performing a 'stub' transfer. 474 * 'db' is the zone's 'db' or a new one if this is the initial 475 * transfer. 476 */ 477 478struct dns_stub { 479 unsigned int magic; 480 isc_mem_t *mctx; 481 dns_zone_t *zone; 482 dns_db_t *db; 483 dns_dbversion_t *version; 484}; 485 486/*% 487 * Hold load state. 488 */ 489struct dns_load { 490 unsigned int magic; 491 isc_mem_t *mctx; 492 dns_zone_t *zone; 493 dns_db_t *db; 494 isc_time_t loadtime; 495 dns_rdatacallbacks_t callbacks; 496}; 497 498/*% 499 * Hold forward state. 500 */ 501struct dns_forward { 502 unsigned int magic; 503 isc_mem_t *mctx; 504 dns_zone_t *zone; 505 isc_buffer_t *msgbuf; 506 dns_request_t *request; 507 isc_uint32_t which; 508 isc_sockaddr_t addr; 509 dns_updatecallback_t callback; 510 void *callback_arg; 511 ISC_LINK(dns_forward_t) link; 512}; 513 514/*% 515 * Hold IO request state. 516 */ 517struct dns_io { 518 unsigned int magic; 519 dns_zonemgr_t *zmgr; 520 isc_boolean_t high; 521 isc_task_t *task; 522 ISC_LINK(dns_io_t) link; 523 isc_event_t *event; 524}; 525 526/*% 527 * Hold state for when we are signing a zone with a new 528 * DNSKEY as result of an update. 529 */ 530struct dns_signing { 531 unsigned int magic; 532 dns_db_t *db; 533 dns_dbiterator_t *dbiterator; 534 dns_secalg_t algorithm; 535 isc_uint16_t keyid; 536 isc_boolean_t delete; 537 isc_boolean_t done; 538 ISC_LINK(dns_signing_t) link; 539}; 540 541struct dns_nsec3chain { 542 unsigned int magic; 543 dns_db_t *db; 544 dns_dbiterator_t *dbiterator; 545 dns_rdata_nsec3param_t nsec3param; 546 unsigned char salt[255]; 547 isc_boolean_t done; 548 isc_boolean_t seen_nsec; 549 isc_boolean_t delete_nsec; 550 isc_boolean_t save_delete_nsec; 551 ISC_LINK(dns_nsec3chain_t) link; 552}; 553/*%< 554 * 'dbiterator' contains a iterator for the database. If we are creating 555 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are 556 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be 557 * iterated. 558 * 559 * 'nsec3param' contains the parameters of the NSEC3 chain being created 560 * or removed. 561 * 562 * 'salt' is buffer space and is referenced via 'nsec3param.salt'. 563 * 564 * 'seen_nsec' will be set to true if, while iterating the zone to create a 565 * NSEC3 chain, a NSEC record is seen. 566 * 567 * 'delete_nsec' will be set to true if, at the completion of the creation 568 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we 569 * are in the process of deleting the NSEC chain. 570 * 571 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec' 572 * so it can be recovered in the event of a error. 573 */ 574 575struct dns_keyfetch { 576 dns_fixedname_t name; 577 dns_rdataset_t keydataset; 578 dns_rdataset_t dnskeyset; 579 dns_rdataset_t dnskeysigset; 580 dns_zone_t *zone; 581 dns_db_t *db; 582 dns_fetch_t *fetch; 583}; 584 585#define HOUR 3600 586#define DAY (24*HOUR) 587#define MONTH (30*DAY) 588 589#define SEND_BUFFER_SIZE 2048 590 591static void zone_settimer(dns_zone_t *, isc_time_t *); 592static void cancel_refresh(dns_zone_t *); 593static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel, 594 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5); 595static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...) 596 ISC_FORMAT_PRINTF(3, 4); 597static void queue_xfrin(dns_zone_t *zone); 598static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver, 599 dns_diff_t *diff, dns_diffop_t op, 600 dns_name_t *name, dns_ttl_t ttl, 601 dns_rdata_t *rdata); 602static void zone_unload(dns_zone_t *zone); 603static void zone_expire(dns_zone_t *zone); 604static void zone_iattach(dns_zone_t *source, dns_zone_t **target); 605static void zone_idetach(dns_zone_t **zonep); 606static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db, 607 isc_boolean_t dump); 608static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db); 609static inline void zone_detachdb(dns_zone_t *zone); 610static isc_result_t default_journal(dns_zone_t *zone); 611static void zone_xfrdone(dns_zone_t *zone, isc_result_t result); 612static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db, 613 isc_time_t loadtime, isc_result_t result); 614static void zone_needdump(dns_zone_t *zone, unsigned int delay); 615static void zone_shutdown(isc_task_t *, isc_event_t *); 616static void zone_loaddone(void *arg, isc_result_t result); 617static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone, 618 isc_time_t loadtime); 619static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length); 620static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length); 621static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length); 622static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length); 623 624#if 0 625/* ondestroy example */ 626static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event); 627#endif 628 629static void refresh_callback(isc_task_t *, isc_event_t *); 630static void stub_callback(isc_task_t *, isc_event_t *); 631static void queue_soa_query(dns_zone_t *zone); 632static void soa_query(isc_task_t *, isc_event_t *); 633static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, 634 dns_stub_t *stub); 635static int message_count(dns_message_t *msg, dns_section_t section, 636 dns_rdatatype_t type); 637static void notify_cancel(dns_zone_t *zone); 638static void notify_find_address(dns_notify_t *notify); 639static void notify_send(dns_notify_t *notify); 640static isc_result_t notify_createmessage(dns_zone_t *zone, 641 unsigned int flags, 642 dns_message_t **messagep); 643static void notify_done(isc_task_t *task, isc_event_t *event); 644static void notify_send_toaddr(isc_task_t *task, isc_event_t *event); 645static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t); 646static void got_transfer_quota(isc_task_t *task, isc_event_t *event); 647static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, 648 dns_zone_t *zone); 649static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi); 650static void zonemgr_free(dns_zonemgr_t *zmgr); 651static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high, 652 isc_task_t *task, isc_taskaction_t action, 653 void *arg, dns_io_t **iop); 654static void zonemgr_putio(dns_io_t **iop); 655static void zonemgr_cancelio(dns_io_t *io); 656 657static isc_result_t 658zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 659 unsigned int *soacount, isc_uint32_t *serial, 660 isc_uint32_t *refresh, isc_uint32_t *retry, 661 isc_uint32_t *expire, isc_uint32_t *minimum, 662 unsigned int *errors); 663 664static void zone_freedbargs(dns_zone_t *zone); 665static void forward_callback(isc_task_t *task, isc_event_t *event); 666static void zone_saveunique(dns_zone_t *zone, const char *path, 667 const char *templat); 668static void zone_maintenance(dns_zone_t *zone); 669static void zone_notify(dns_zone_t *zone, isc_time_t *now); 670static void dump_done(void *arg, isc_result_t result); 671static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, 672 isc_uint16_t keyid, isc_boolean_t delete); 673static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver, 674 dns_dbnode_t *node, dns_name_t *name, 675 dns_diff_t *diff); 676static void zone_rekey(dns_zone_t *zone); 677static isc_boolean_t delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, 678 dst_key_t **keys, unsigned int nkeys); 679 680#define ENTER zone_debuglog(zone, me, 1, "enter") 681 682static const unsigned int dbargc_default = 1; 683static const char *dbargv_default[] = { "rbt" }; 684 685#define DNS_ZONE_JITTER_ADD(a, b, c) \ 686 do { \ 687 isc_interval_t _i; \ 688 isc_uint32_t _j; \ 689 _j = isc_random_jitter((b), (b)/4); \ 690 isc_interval_set(&_i, _j, 0); \ 691 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 692 dns_zone_log(zone, ISC_LOG_WARNING, \ 693 "epoch approaching: upgrade required: " \ 694 "now + %s failed", #b); \ 695 isc_interval_set(&_i, _j/2, 0); \ 696 (void)isc_time_add((a), &_i, (c)); \ 697 } \ 698 } while (0) 699 700#define DNS_ZONE_TIME_ADD(a, b, c) \ 701 do { \ 702 isc_interval_t _i; \ 703 isc_interval_set(&_i, (b), 0); \ 704 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \ 705 dns_zone_log(zone, ISC_LOG_WARNING, \ 706 "epoch approaching: upgrade required: " \ 707 "now + %s failed", #b); \ 708 isc_interval_set(&_i, (b)/2, 0); \ 709 (void)isc_time_add((a), &_i, (c)); \ 710 } \ 711 } while (0) 712 713/*% 714 * Increment resolver-related statistics counters. Zone must be locked. 715 */ 716static inline void 717inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { 718 if (zone->stats != NULL) 719 isc_stats_increment(zone->stats, counter); 720} 721 722/*** 723 *** Public functions. 724 ***/ 725 726isc_result_t 727dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { 728 isc_result_t result; 729 dns_zone_t *zone; 730 isc_time_t now; 731 732 REQUIRE(zonep != NULL && *zonep == NULL); 733 REQUIRE(mctx != NULL); 734 735 TIME_NOW(&now); 736 zone = isc_mem_get(mctx, sizeof(*zone)); 737 if (zone == NULL) 738 return (ISC_R_NOMEMORY); 739 740 zone->mctx = NULL; 741 isc_mem_attach(mctx, &zone->mctx); 742 743 result = isc_mutex_init(&zone->lock); 744 if (result != ISC_R_SUCCESS) 745 goto free_zone; 746 747 result = ZONEDB_INITLOCK(&zone->dblock); 748 if (result != ISC_R_SUCCESS) 749 goto free_mutex; 750 751 /* XXX MPA check that all elements are initialised */ 752#ifdef DNS_ZONE_CHECKLOCK 753 zone->locked = ISC_FALSE; 754#endif 755 zone->db = NULL; 756 zone->zmgr = NULL; 757 ISC_LINK_INIT(zone, link); 758 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */ 759 if (result != ISC_R_SUCCESS) 760 goto free_dblock; 761 zone->irefs = 0; 762 dns_name_init(&zone->origin, NULL); 763 zone->strnamerd = NULL; 764 zone->strname = NULL; 765 zone->strrdclass = NULL; 766 zone->strviewname = NULL; 767 zone->masterfile = NULL; 768 zone->masterformat = dns_masterformat_none; 769 zone->keydirectory = NULL; 770 zone->journalsize = -1; 771 zone->journal = NULL; 772 zone->rdclass = dns_rdataclass_none; 773 zone->type = dns_zone_none; 774 zone->flags = 0; 775 zone->options = 0; 776 zone->keyopts = 0; 777 zone->db_argc = 0; 778 zone->db_argv = NULL; 779 isc_time_settoepoch(&zone->expiretime); 780 isc_time_settoepoch(&zone->refreshtime); 781 isc_time_settoepoch(&zone->dumptime); 782 isc_time_settoepoch(&zone->loadtime); 783 zone->notifytime = now; 784 isc_time_settoepoch(&zone->resigntime); 785 isc_time_settoepoch(&zone->keywarntime); 786 isc_time_settoepoch(&zone->signingtime); 787 isc_time_settoepoch(&zone->nsec3chaintime); 788 isc_time_settoepoch(&zone->refreshkeytime); 789 zone->refreshkeycount = 0; 790 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 791 zone->retry = DNS_ZONE_DEFAULTRETRY; 792 zone->expire = 0; 793 zone->minimum = 0; 794 zone->maxrefresh = DNS_ZONE_MAXREFRESH; 795 zone->minrefresh = DNS_ZONE_MINREFRESH; 796 zone->maxretry = DNS_ZONE_MAXRETRY; 797 zone->minretry = DNS_ZONE_MINRETRY; 798 zone->masters = NULL; 799 zone->masterkeynames = NULL; 800 zone->mastersok = NULL; 801 zone->masterscnt = 0; 802 zone->curmaster = 0; 803 zone->notify = NULL; 804 zone->notifytype = dns_notifytype_yes; 805 zone->notifycnt = 0; 806 zone->task = NULL; 807 zone->update_acl = NULL; 808 zone->forward_acl = NULL; 809 zone->notify_acl = NULL; 810 zone->query_acl = NULL; 811 zone->queryon_acl = NULL; 812 zone->xfr_acl = NULL; 813 zone->update_disabled = ISC_FALSE; 814 zone->zero_no_soa_ttl = ISC_TRUE; 815 zone->check_names = dns_severity_ignore; 816 zone->request = NULL; 817 zone->lctx = NULL; 818 zone->readio = NULL; 819 zone->dctx = NULL; 820 zone->writeio = NULL; 821 zone->timer = NULL; 822 zone->idlein = DNS_DEFAULT_IDLEIN; 823 zone->idleout = DNS_DEFAULT_IDLEOUT; 824 zone->log_key_expired_timer = 0; 825 ISC_LIST_INIT(zone->notifies); 826 isc_sockaddr_any(&zone->notifysrc4); 827 isc_sockaddr_any6(&zone->notifysrc6); 828 isc_sockaddr_any(&zone->xfrsource4); 829 isc_sockaddr_any6(&zone->xfrsource6); 830 isc_sockaddr_any(&zone->altxfrsource4); 831 isc_sockaddr_any6(&zone->altxfrsource6); 832 zone->xfr = NULL; 833 zone->tsigkey = NULL; 834 zone->maxxfrin = MAX_XFER_TIME; 835 zone->maxxfrout = MAX_XFER_TIME; 836 zone->ssutable = NULL; 837 zone->sigvalidityinterval = 30 * 24 * 3600; 838 zone->sigresigninginterval = 7 * 24 * 3600; 839 zone->view = NULL; 840 zone->acache = NULL; 841 zone->checkmx = NULL; 842 zone->checksrv = NULL; 843 zone->checkns = NULL; 844 ISC_LINK_INIT(zone, statelink); 845 zone->statelist = NULL; 846 zone->stats = NULL; 847 zone->requeststats_on = ISC_FALSE; 848 zone->requeststats = NULL; 849 zone->notifydelay = 5; 850 zone->isself = NULL; 851 zone->isselfarg = NULL; 852 ISC_LIST_INIT(zone->signing); 853 ISC_LIST_INIT(zone->nsec3chain); 854 zone->signatures = 10; 855 zone->nodes = 100; 856 zone->privatetype = (dns_rdatatype_t)0xffffU; 857 zone->added = ISC_FALSE; 858 zone->rpz_zone = ISC_FALSE; 859 ISC_LIST_INIT(zone->forwards); 860 861 zone->magic = ZONE_MAGIC; 862 863 /* Must be after magic is set. */ 864 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default); 865 if (result != ISC_R_SUCCESS) 866 goto free_erefs; 867 868 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL, 869 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, 870 NULL, NULL); 871 *zonep = zone; 872 return (ISC_R_SUCCESS); 873 874 free_erefs: 875 isc_refcount_decrement(&zone->erefs, NULL); 876 isc_refcount_destroy(&zone->erefs); 877 878 free_dblock: 879 ZONEDB_DESTROYLOCK(&zone->dblock); 880 881 free_mutex: 882 DESTROYLOCK(&zone->lock); 883 884 free_zone: 885 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone)); 886 return (result); 887} 888 889/* 890 * Free a zone. Because we require that there be no more 891 * outstanding events or references, no locking is necessary. 892 */ 893static void 894zone_free(dns_zone_t *zone) { 895 isc_mem_t *mctx = NULL; 896 dns_signing_t *signing; 897 dns_nsec3chain_t *nsec3chain; 898 899 REQUIRE(DNS_ZONE_VALID(zone)); 900 REQUIRE(isc_refcount_current(&zone->erefs) == 0); 901 REQUIRE(zone->irefs == 0); 902 REQUIRE(!LOCKED_ZONE(zone)); 903 REQUIRE(zone->timer == NULL); 904 905 /* 906 * Managed objects. Order is important. 907 */ 908 if (zone->request != NULL) 909 dns_request_destroy(&zone->request); /* XXXMPA */ 910 INSIST(zone->readio == NULL); 911 INSIST(zone->statelist == NULL); 912 INSIST(zone->writeio == NULL); 913 914 if (zone->task != NULL) 915 isc_task_detach(&zone->task); 916 if (zone->zmgr != NULL) 917 dns_zonemgr_releasezone(zone->zmgr, zone); 918 919 /* Unmanaged objects */ 920 for (signing = ISC_LIST_HEAD(zone->signing); 921 signing != NULL; 922 signing = ISC_LIST_HEAD(zone->signing)) { 923 ISC_LIST_UNLINK(zone->signing, signing, link); 924 dns_db_detach(&signing->db); 925 dns_dbiterator_destroy(&signing->dbiterator); 926 isc_mem_put(zone->mctx, signing, sizeof *signing); 927 } 928 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 929 nsec3chain != NULL; 930 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) { 931 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 932 dns_db_detach(&nsec3chain->db); 933 dns_dbiterator_destroy(&nsec3chain->dbiterator); 934 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 935 } 936 if (zone->masterfile != NULL) 937 isc_mem_free(zone->mctx, zone->masterfile); 938 zone->masterfile = NULL; 939 if (zone->keydirectory != NULL) 940 isc_mem_free(zone->mctx, zone->keydirectory); 941 zone->keydirectory = NULL; 942 zone->journalsize = -1; 943 if (zone->journal != NULL) 944 isc_mem_free(zone->mctx, zone->journal); 945 zone->journal = NULL; 946 if (zone->stats != NULL) 947 isc_stats_detach(&zone->stats); 948 if (zone->requeststats != NULL) 949 isc_stats_detach(&zone->requeststats); 950 if (zone->db != NULL) 951 zone_detachdb(zone); 952 if (zone->acache != NULL) 953 dns_acache_detach(&zone->acache); 954 zone_freedbargs(zone); 955 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0) 956 == ISC_R_SUCCESS); 957 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) 958 == ISC_R_SUCCESS); 959 zone->check_names = dns_severity_ignore; 960 if (zone->update_acl != NULL) 961 dns_acl_detach(&zone->update_acl); 962 if (zone->forward_acl != NULL) 963 dns_acl_detach(&zone->forward_acl); 964 if (zone->notify_acl != NULL) 965 dns_acl_detach(&zone->notify_acl); 966 if (zone->query_acl != NULL) 967 dns_acl_detach(&zone->query_acl); 968 if (zone->queryon_acl != NULL) 969 dns_acl_detach(&zone->queryon_acl); 970 if (zone->xfr_acl != NULL) 971 dns_acl_detach(&zone->xfr_acl); 972 if (dns_name_dynamic(&zone->origin)) 973 dns_name_free(&zone->origin, zone->mctx); 974 if (zone->strnamerd != NULL) 975 isc_mem_free(zone->mctx, zone->strnamerd); 976 if (zone->strname != NULL) 977 isc_mem_free(zone->mctx, zone->strname); 978 if (zone->strrdclass != NULL) 979 isc_mem_free(zone->mctx, zone->strrdclass); 980 if (zone->strviewname != NULL) 981 isc_mem_free(zone->mctx, zone->strviewname); 982 if (zone->ssutable != NULL) 983 dns_ssutable_detach(&zone->ssutable); 984 985 /* last stuff */ 986 ZONEDB_DESTROYLOCK(&zone->dblock); 987 DESTROYLOCK(&zone->lock); 988 isc_refcount_destroy(&zone->erefs); 989 zone->magic = 0; 990 mctx = zone->mctx; 991 isc_mem_put(mctx, zone, sizeof(*zone)); 992 isc_mem_detach(&mctx); 993} 994 995/* 996 * Single shot. 997 */ 998void 999dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) { 1000 char namebuf[1024]; 1001 1002 REQUIRE(DNS_ZONE_VALID(zone)); 1003 REQUIRE(rdclass != dns_rdataclass_none); 1004 1005 /* 1006 * Test and set. 1007 */ 1008 LOCK_ZONE(zone); 1009 REQUIRE(zone->rdclass == dns_rdataclass_none || 1010 zone->rdclass == rdclass); 1011 zone->rdclass = rdclass; 1012 1013 if (zone->strnamerd != NULL) 1014 isc_mem_free(zone->mctx, zone->strnamerd); 1015 if (zone->strrdclass != NULL) 1016 isc_mem_free(zone->mctx, zone->strrdclass); 1017 1018 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1019 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1020 zone_rdclass_tostr(zone, namebuf, sizeof namebuf); 1021 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf); 1022 1023 UNLOCK_ZONE(zone); 1024} 1025 1026dns_rdataclass_t 1027dns_zone_getclass(dns_zone_t *zone) { 1028 REQUIRE(DNS_ZONE_VALID(zone)); 1029 1030 return (zone->rdclass); 1031} 1032 1033void 1034dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { 1035 REQUIRE(DNS_ZONE_VALID(zone)); 1036 1037 LOCK_ZONE(zone); 1038 zone->notifytype = notifytype; 1039 UNLOCK_ZONE(zone); 1040} 1041 1042isc_result_t 1043dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) { 1044 isc_result_t result; 1045 1046 REQUIRE(DNS_ZONE_VALID(zone)); 1047 REQUIRE(serialp != NULL); 1048 1049 LOCK_ZONE(zone); 1050 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1051 if (zone->db != NULL) { 1052 result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp, 1053 NULL, NULL, NULL, NULL, NULL); 1054 } else 1055 result = DNS_R_NOTLOADED; 1056 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1057 UNLOCK_ZONE(zone); 1058 1059 return (result); 1060} 1061 1062isc_uint32_t 1063dns_zone_getserial(dns_zone_t *zone) { 1064 isc_result_t result; 1065 isc_uint32_t serial; 1066 1067 result = dns_zone_getserial2(zone, &serial); 1068 if (result != ISC_R_SUCCESS) 1069 serial = 0; /* XXX: not really correct, but no other choice */ 1070 1071 return (serial); 1072} 1073 1074/* 1075 * Single shot. 1076 */ 1077void 1078dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) { 1079 1080 REQUIRE(DNS_ZONE_VALID(zone)); 1081 REQUIRE(type != dns_zone_none); 1082 1083 /* 1084 * Test and set. 1085 */ 1086 LOCK_ZONE(zone); 1087 REQUIRE(zone->type == dns_zone_none || zone->type == type); 1088 zone->type = type; 1089 UNLOCK_ZONE(zone); 1090} 1091 1092static void 1093zone_freedbargs(dns_zone_t *zone) { 1094 unsigned int i; 1095 1096 /* Free the old database argument list. */ 1097 if (zone->db_argv != NULL) { 1098 for (i = 0; i < zone->db_argc; i++) 1099 isc_mem_free(zone->mctx, zone->db_argv[i]); 1100 isc_mem_put(zone->mctx, zone->db_argv, 1101 zone->db_argc * sizeof(*zone->db_argv)); 1102 } 1103 zone->db_argc = 0; 1104 zone->db_argv = NULL; 1105} 1106 1107isc_result_t 1108dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) { 1109 size_t size = 0; 1110 unsigned int i; 1111 isc_result_t result = ISC_R_SUCCESS; 1112 void *mem; 1113 char **tmp, *tmp2; 1114 1115 REQUIRE(DNS_ZONE_VALID(zone)); 1116 REQUIRE(argv != NULL && *argv == NULL); 1117 1118 LOCK_ZONE(zone); 1119 size = (zone->db_argc + 1) * sizeof(char *); 1120 for (i = 0; i < zone->db_argc; i++) 1121 size += strlen(zone->db_argv[i]) + 1; 1122 mem = isc_mem_allocate(mctx, size); 1123 if (mem != NULL) { 1124 tmp = mem; 1125 tmp2 = mem; 1126 tmp2 += (zone->db_argc + 1) * sizeof(char *); 1127 for (i = 0; i < zone->db_argc; i++) { 1128 *tmp++ = tmp2; 1129 strcpy(tmp2, zone->db_argv[i]); 1130 tmp2 += strlen(tmp2) + 1; 1131 } 1132 *tmp = NULL; 1133 } else 1134 result = ISC_R_NOMEMORY; 1135 UNLOCK_ZONE(zone); 1136 *argv = mem; 1137 return (result); 1138} 1139 1140isc_result_t 1141dns_zone_setdbtype(dns_zone_t *zone, 1142 unsigned int dbargc, const char * const *dbargv) { 1143 isc_result_t result = ISC_R_SUCCESS; 1144 char **new = NULL; 1145 unsigned int i; 1146 1147 REQUIRE(DNS_ZONE_VALID(zone)); 1148 REQUIRE(dbargc >= 1); 1149 REQUIRE(dbargv != NULL); 1150 1151 LOCK_ZONE(zone); 1152 1153 /* Set up a new database argument list. */ 1154 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new)); 1155 if (new == NULL) 1156 goto nomem; 1157 for (i = 0; i < dbargc; i++) 1158 new[i] = NULL; 1159 for (i = 0; i < dbargc; i++) { 1160 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]); 1161 if (new[i] == NULL) 1162 goto nomem; 1163 } 1164 1165 /* Free the old list. */ 1166 zone_freedbargs(zone); 1167 1168 zone->db_argc = dbargc; 1169 zone->db_argv = new; 1170 result = ISC_R_SUCCESS; 1171 goto unlock; 1172 1173 nomem: 1174 if (new != NULL) { 1175 for (i = 0; i < dbargc; i++) 1176 if (new[i] != NULL) 1177 isc_mem_free(zone->mctx, new[i]); 1178 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new)); 1179 } 1180 result = ISC_R_NOMEMORY; 1181 1182 unlock: 1183 UNLOCK_ZONE(zone); 1184 return (result); 1185} 1186 1187void 1188dns_zone_setview(dns_zone_t *zone, dns_view_t *view) { 1189 char namebuf[1024]; 1190 REQUIRE(DNS_ZONE_VALID(zone)); 1191 1192 LOCK_ZONE(zone); 1193 if (zone->view != NULL) 1194 dns_view_weakdetach(&zone->view); 1195 dns_view_weakattach(view, &zone->view); 1196 1197 if (zone->strviewname != NULL) 1198 isc_mem_free(zone->mctx, zone->strviewname); 1199 if (zone->strnamerd != NULL) 1200 isc_mem_free(zone->mctx, zone->strnamerd); 1201 1202 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1203 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1204 zone_viewname_tostr(zone, namebuf, sizeof namebuf); 1205 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf); 1206 1207 UNLOCK_ZONE(zone); 1208} 1209 1210 1211dns_view_t * 1212dns_zone_getview(dns_zone_t *zone) { 1213 REQUIRE(DNS_ZONE_VALID(zone)); 1214 1215 return (zone->view); 1216} 1217 1218 1219isc_result_t 1220dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) { 1221 isc_result_t result; 1222 char namebuf[1024]; 1223 1224 REQUIRE(DNS_ZONE_VALID(zone)); 1225 REQUIRE(origin != NULL); 1226 1227 LOCK_ZONE(zone); 1228 if (dns_name_dynamic(&zone->origin)) { 1229 dns_name_free(&zone->origin, zone->mctx); 1230 dns_name_init(&zone->origin, NULL); 1231 } 1232 result = dns_name_dup(origin, zone->mctx, &zone->origin); 1233 1234 if (zone->strnamerd != NULL) 1235 isc_mem_free(zone->mctx, zone->strnamerd); 1236 if (zone->strname != NULL) 1237 isc_mem_free(zone->mctx, zone->strname); 1238 1239 zone_namerd_tostr(zone, namebuf, sizeof namebuf); 1240 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); 1241 zone_name_tostr(zone, namebuf, sizeof namebuf); 1242 zone->strname = isc_mem_strdup(zone->mctx, namebuf); 1243 1244 UNLOCK_ZONE(zone); 1245 return (result); 1246} 1247 1248void 1249dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) { 1250 REQUIRE(DNS_ZONE_VALID(zone)); 1251 REQUIRE(acache != NULL); 1252 1253 LOCK_ZONE(zone); 1254 if (zone->acache != NULL) 1255 dns_acache_detach(&zone->acache); 1256 dns_acache_attach(acache, &zone->acache); 1257 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1258 if (zone->db != NULL) { 1259 isc_result_t result; 1260 1261 /* 1262 * If the zone reuses an existing DB, the DB needs to be 1263 * set in the acache explicitly. We can safely ignore the 1264 * case where the DB is already set. If other error happens, 1265 * the acache will not work effectively. 1266 */ 1267 result = dns_acache_setdb(acache, zone->db); 1268 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { 1269 UNEXPECTED_ERROR(__FILE__, __LINE__, 1270 "dns_acache_setdb() failed: %s", 1271 isc_result_totext(result)); 1272 } 1273 } 1274 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1275 UNLOCK_ZONE(zone); 1276} 1277 1278static isc_result_t 1279dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) { 1280 char *copy; 1281 1282 if (value != NULL) { 1283 copy = isc_mem_strdup(zone->mctx, value); 1284 if (copy == NULL) 1285 return (ISC_R_NOMEMORY); 1286 } else { 1287 copy = NULL; 1288 } 1289 1290 if (*field != NULL) 1291 isc_mem_free(zone->mctx, *field); 1292 1293 *field = copy; 1294 return (ISC_R_SUCCESS); 1295} 1296 1297isc_result_t 1298dns_zone_setfile(dns_zone_t *zone, const char *file) { 1299 return (dns_zone_setfile2(zone, file, dns_masterformat_text)); 1300} 1301 1302isc_result_t 1303dns_zone_setfile2(dns_zone_t *zone, const char *file, 1304 dns_masterformat_t format) { 1305 isc_result_t result = ISC_R_SUCCESS; 1306 1307 REQUIRE(DNS_ZONE_VALID(zone)); 1308 1309 LOCK_ZONE(zone); 1310 result = dns_zone_setstring(zone, &zone->masterfile, file); 1311 if (result == ISC_R_SUCCESS) { 1312 zone->masterformat = format; 1313 result = default_journal(zone); 1314 } 1315 UNLOCK_ZONE(zone); 1316 1317 return (result); 1318} 1319 1320const char * 1321dns_zone_getfile(dns_zone_t *zone) { 1322 REQUIRE(DNS_ZONE_VALID(zone)); 1323 1324 return (zone->masterfile); 1325} 1326 1327static isc_result_t 1328default_journal(dns_zone_t *zone) { 1329 isc_result_t result; 1330 char *journal; 1331 1332 REQUIRE(DNS_ZONE_VALID(zone)); 1333 REQUIRE(LOCKED_ZONE(zone)); 1334 1335 if (zone->masterfile != NULL) { 1336 /* Calculate string length including '\0'. */ 1337 int len = strlen(zone->masterfile) + sizeof(".jnl"); 1338 journal = isc_mem_allocate(zone->mctx, len); 1339 if (journal == NULL) 1340 return (ISC_R_NOMEMORY); 1341 strcpy(journal, zone->masterfile); 1342 strcat(journal, ".jnl"); 1343 } else { 1344 journal = NULL; 1345 } 1346 result = dns_zone_setstring(zone, &zone->journal, journal); 1347 if (journal != NULL) 1348 isc_mem_free(zone->mctx, journal); 1349 return (result); 1350} 1351 1352isc_result_t 1353dns_zone_setjournal(dns_zone_t *zone, const char *journal) { 1354 isc_result_t result = ISC_R_SUCCESS; 1355 1356 REQUIRE(DNS_ZONE_VALID(zone)); 1357 1358 LOCK_ZONE(zone); 1359 result = dns_zone_setstring(zone, &zone->journal, journal); 1360 UNLOCK_ZONE(zone); 1361 1362 return (result); 1363} 1364 1365char * 1366dns_zone_getjournal(dns_zone_t *zone) { 1367 REQUIRE(DNS_ZONE_VALID(zone)); 1368 1369 return (zone->journal); 1370} 1371 1372/* 1373 * Return true iff the zone is "dynamic", in the sense that the zone's 1374 * master file (if any) is written by the server, rather than being 1375 * updated manually and read by the server. 1376 * 1377 * This is true for slave zones, stub zones, key zones, and zones that 1378 * allow dynamic updates either by having an update policy ("ssutable") 1379 * or an "allow-update" ACL with a value other than exactly "{ none; }". 1380 */ 1381static isc_boolean_t 1382zone_isdynamic(dns_zone_t *zone) { 1383 REQUIRE(DNS_ZONE_VALID(zone)); 1384 1385 return (ISC_TF(zone->type == dns_zone_slave || 1386 zone->type == dns_zone_stub || 1387 zone->type == dns_zone_key || 1388 (!zone->update_disabled && zone->ssutable != NULL) || 1389 (!zone->update_disabled && zone->update_acl != NULL && 1390 !dns_acl_isnone(zone->update_acl)))); 1391} 1392 1393 1394static isc_result_t 1395zone_load(dns_zone_t *zone, unsigned int flags) { 1396 isc_result_t result; 1397 isc_time_t now; 1398 isc_time_t loadtime, filetime; 1399 dns_db_t *db = NULL; 1400 isc_boolean_t rbt; 1401 1402 REQUIRE(DNS_ZONE_VALID(zone)); 1403 1404 LOCK_ZONE(zone); 1405 TIME_NOW(&now); 1406 1407 INSIST(zone->type != dns_zone_none); 1408 1409 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { 1410 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) 1411 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 1412 result = DNS_R_CONTINUE; 1413 goto cleanup; 1414 } 1415 1416 1417 INSIST(zone->db_argc >= 1); 1418 1419 rbt = strcmp(zone->db_argv[0], "rbt") == 0 || 1420 strcmp(zone->db_argv[0], "rbt64") == 0; 1421 1422 if (zone->db != NULL && zone->masterfile == NULL && rbt) { 1423 /* 1424 * The zone has no master file configured. 1425 */ 1426 result = ISC_R_SUCCESS; 1427 goto cleanup; 1428 } 1429 1430 if (zone->db != NULL && zone_isdynamic(zone)) { 1431 /* 1432 * This is a slave, stub, or dynamically updated 1433 * zone being reloaded. Do nothing - the database 1434 * we already have is guaranteed to be up-to-date. 1435 */ 1436 if (zone->type == dns_zone_master) 1437 result = DNS_R_DYNAMIC; 1438 else 1439 result = ISC_R_SUCCESS; 1440 goto cleanup; 1441 } 1442 1443 /* 1444 * Store the current time before the zone is loaded, so that if the 1445 * file changes between the time of the load and the time that 1446 * zone->loadtime is set, then the file will still be reloaded 1447 * the next time dns_zone_load is called. 1448 */ 1449 TIME_NOW(&loadtime); 1450 1451 /* 1452 * Don't do the load if the file that stores the zone is older 1453 * than the last time the zone was loaded. If the zone has not 1454 * been loaded yet, zone->loadtime will be the epoch. 1455 */ 1456 if (zone->masterfile != NULL) { 1457 /* 1458 * The file is already loaded. If we are just doing a 1459 * "rndc reconfig", we are done. 1460 */ 1461 if (!isc_time_isepoch(&zone->loadtime) && 1462 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0 && 1463 zone->rpz_zone == dns_rpz_needed()) { 1464 result = ISC_R_SUCCESS; 1465 goto cleanup; 1466 } 1467 1468 result = isc_file_getmodtime(zone->masterfile, &filetime); 1469 if (result == ISC_R_SUCCESS) { 1470 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 1471 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) && 1472 isc_time_compare(&filetime, &zone->loadtime) <= 0 && 1473 zone->rpz_zone == dns_rpz_needed()) { 1474 dns_zone_log(zone, ISC_LOG_DEBUG(1), 1475 "skipping load: master file " 1476 "older than last load"); 1477 result = DNS_R_UPTODATE; 1478 goto cleanup; 1479 } 1480 loadtime = filetime; 1481 zone->rpz_zone = dns_rpz_needed(); 1482 } 1483 } 1484 1485 /* 1486 * Built in zones (with the exception of empty zones) don't need 1487 * to be reloaded. 1488 */ 1489 if (zone->type == dns_zone_master && 1490 strcmp(zone->db_argv[0], "_builtin") == 0 && 1491 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) && 1492 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 1493 result = ISC_R_SUCCESS; 1494 goto cleanup; 1495 } 1496 1497 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) && 1498 rbt) { 1499 if (zone->masterfile == NULL || 1500 !isc_file_exists(zone->masterfile)) { 1501 if (zone->masterfile != NULL) { 1502 dns_zone_log(zone, ISC_LOG_DEBUG(1), 1503 "no master file"); 1504 } 1505 zone->refreshtime = now; 1506 if (zone->task != NULL) 1507 zone_settimer(zone, &now); 1508 result = ISC_R_SUCCESS; 1509 goto cleanup; 1510 } 1511 } 1512 1513 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load"); 1514 1515 result = dns_db_create(zone->mctx, zone->db_argv[0], 1516 &zone->origin, (zone->type == dns_zone_stub) ? 1517 dns_dbtype_stub : dns_dbtype_zone, 1518 zone->rdclass, 1519 zone->db_argc - 1, zone->db_argv + 1, 1520 &db); 1521 1522 if (result != ISC_R_SUCCESS) { 1523 dns_zone_log(zone, ISC_LOG_ERROR, 1524 "loading zone: creating database: %s", 1525 isc_result_totext(result)); 1526 goto cleanup; 1527 } 1528 dns_db_settask(db, zone->task); 1529 1530 if (! dns_db_ispersistent(db)) { 1531 if (zone->masterfile != NULL) { 1532 result = zone_startload(db, zone, loadtime); 1533 } else { 1534 result = DNS_R_NOMASTERFILE; 1535 if (zone->type == dns_zone_master) { 1536 dns_zone_log(zone, ISC_LOG_ERROR, 1537 "loading zone: " 1538 "no master file configured"); 1539 goto cleanup; 1540 } 1541 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: " 1542 "no master file configured: continuing"); 1543 } 1544 } 1545 1546 if (result == DNS_R_CONTINUE) { 1547 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING); 1548 if ((flags & DNS_ZONELOADFLAG_THAW) != 0) 1549 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW); 1550 goto cleanup; 1551 } 1552 1553 result = zone_postload(zone, db, loadtime, result); 1554 1555 cleanup: 1556 UNLOCK_ZONE(zone); 1557 if (db != NULL) 1558 dns_db_detach(&db); 1559 return (result); 1560} 1561 1562isc_result_t 1563dns_zone_load(dns_zone_t *zone) { 1564 return (zone_load(zone, 0)); 1565} 1566 1567isc_result_t 1568dns_zone_loadnew(dns_zone_t *zone) { 1569 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT)); 1570} 1571 1572isc_result_t 1573dns_zone_loadandthaw(dns_zone_t *zone) { 1574 isc_result_t result; 1575 1576 result = zone_load(zone, DNS_ZONELOADFLAG_THAW); 1577 switch (result) { 1578 case DNS_R_CONTINUE: 1579 /* Deferred thaw. */ 1580 break; 1581 case ISC_R_SUCCESS: 1582 case DNS_R_UPTODATE: 1583 case DNS_R_SEENINCLUDE: 1584 zone->update_disabled = ISC_FALSE; 1585 break; 1586 case DNS_R_NOMASTERFILE: 1587 zone->update_disabled = ISC_FALSE; 1588 break; 1589 default: 1590 /* Error, remain in disabled state. */ 1591 break; 1592 } 1593 return (result); 1594} 1595 1596static unsigned int 1597get_master_options(dns_zone_t *zone) { 1598 unsigned int options; 1599 1600 options = DNS_MASTER_ZONE; 1601 if (zone->type == dns_zone_slave) 1602 options |= DNS_MASTER_SLAVE; 1603 if (zone->type == dns_zone_key) 1604 options |= DNS_MASTER_KEY; 1605 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) 1606 options |= DNS_MASTER_CHECKNS; 1607 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) 1608 options |= DNS_MASTER_FATALNS; 1609 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) 1610 options |= DNS_MASTER_CHECKNAMES; 1611 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) 1612 options |= DNS_MASTER_CHECKNAMESFAIL; 1613 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) 1614 options |= DNS_MASTER_CHECKMX; 1615 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) 1616 options |= DNS_MASTER_CHECKMXFAIL; 1617 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) 1618 options |= DNS_MASTER_CHECKWILDCARD; 1619 if (zone->type == dns_zone_master && 1620 ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) || 1621 zone->ssutable != NULL)) 1622 options |= DNS_MASTER_RESIGN; 1623 return (options); 1624} 1625 1626static void 1627zone_gotreadhandle(isc_task_t *task, isc_event_t *event) { 1628 dns_load_t *load = event->ev_arg; 1629 isc_result_t result = ISC_R_SUCCESS; 1630 unsigned int options; 1631 1632 REQUIRE(DNS_LOAD_VALID(load)); 1633 1634 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) 1635 result = ISC_R_CANCELED; 1636 isc_event_free(&event); 1637 if (result == ISC_R_CANCELED) 1638 goto fail; 1639 1640 options = get_master_options(load->zone); 1641 1642 result = dns_master_loadfileinc3(load->zone->masterfile, 1643 dns_db_origin(load->db), 1644 dns_db_origin(load->db), 1645 load->zone->rdclass, 1646 options, 1647 load->zone->sigresigninginterval, 1648 &load->callbacks, task, 1649 zone_loaddone, load, 1650 &load->zone->lctx, load->zone->mctx, 1651 load->zone->masterformat); 1652 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE && 1653 result != DNS_R_SEENINCLUDE) 1654 goto fail; 1655 return; 1656 1657 fail: 1658 zone_loaddone(load, result); 1659} 1660 1661static void 1662zone_gotwritehandle(isc_task_t *task, isc_event_t *event) { 1663 const char me[] = "zone_gotwritehandle"; 1664 dns_zone_t *zone = event->ev_arg; 1665 isc_result_t result = ISC_R_SUCCESS; 1666 dns_dbversion_t *version = NULL; 1667 1668 REQUIRE(DNS_ZONE_VALID(zone)); 1669 INSIST(task == zone->task); 1670 ENTER; 1671 1672 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) 1673 result = ISC_R_CANCELED; 1674 isc_event_free(&event); 1675 if (result == ISC_R_CANCELED) 1676 goto fail; 1677 1678 LOCK_ZONE(zone); 1679 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 1680 if (zone->db != NULL) { 1681 dns_db_currentversion(zone->db, &version); 1682 result = dns_master_dumpinc2(zone->mctx, zone->db, version, 1683 &dns_master_style_default, 1684 zone->masterfile, zone->task, 1685 dump_done, zone, &zone->dctx, 1686 zone->masterformat); 1687 dns_db_closeversion(zone->db, &version, ISC_FALSE); 1688 } else 1689 result = ISC_R_CANCELED; 1690 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 1691 UNLOCK_ZONE(zone); 1692 if (result != DNS_R_CONTINUE) 1693 goto fail; 1694 return; 1695 1696 fail: 1697 dump_done(zone, result); 1698} 1699 1700static isc_result_t 1701zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { 1702 dns_load_t *load; 1703 isc_result_t result; 1704 isc_result_t tresult; 1705 unsigned int options; 1706 1707 options = get_master_options(zone); 1708 1709 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) 1710 options |= DNS_MASTER_MANYERRORS; 1711 1712 if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) { 1713 load = isc_mem_get(zone->mctx, sizeof(*load)); 1714 if (load == NULL) 1715 return (ISC_R_NOMEMORY); 1716 1717 load->mctx = NULL; 1718 load->zone = NULL; 1719 load->db = NULL; 1720 load->loadtime = loadtime; 1721 load->magic = LOAD_MAGIC; 1722 1723 isc_mem_attach(zone->mctx, &load->mctx); 1724 zone_iattach(zone, &load->zone); 1725 dns_db_attach(db, &load->db); 1726 dns_rdatacallbacks_init(&load->callbacks); 1727 result = dns_db_beginload(db, &load->callbacks.add, 1728 &load->callbacks.add_private); 1729 if (result != ISC_R_SUCCESS) 1730 goto cleanup; 1731 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task, 1732 zone_gotreadhandle, load, 1733 &zone->readio); 1734 if (result != ISC_R_SUCCESS) { 1735 /* 1736 * We can't report multiple errors so ignore 1737 * the result of dns_db_endload(). 1738 */ 1739 (void)dns_db_endload(load->db, 1740 &load->callbacks.add_private); 1741 goto cleanup; 1742 } else 1743 result = DNS_R_CONTINUE; 1744 } else { 1745 dns_rdatacallbacks_t callbacks; 1746 1747 dns_rdatacallbacks_init(&callbacks); 1748 result = dns_db_beginload(db, &callbacks.add, 1749 &callbacks.add_private); 1750 if (result != ISC_R_SUCCESS) 1751 return (result); 1752 result = dns_master_loadfile3(zone->masterfile, &zone->origin, 1753 &zone->origin, zone->rdclass, 1754 options, zone->sigresigninginterval, 1755 &callbacks, zone->mctx, 1756 zone->masterformat); 1757 tresult = dns_db_endload(db, &callbacks.add_private); 1758 if (result == ISC_R_SUCCESS) 1759 result = tresult; 1760 } 1761 1762 return (result); 1763 1764 cleanup: 1765 load->magic = 0; 1766 dns_db_detach(&load->db); 1767 zone_idetach(&load->zone); 1768 isc_mem_detach(&load->mctx); 1769 isc_mem_put(zone->mctx, load, sizeof(*load)); 1770 return (result); 1771} 1772 1773static isc_boolean_t 1774zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 1775 dns_name_t *owner) 1776{ 1777 isc_result_t result; 1778 char ownerbuf[DNS_NAME_FORMATSIZE]; 1779 char namebuf[DNS_NAME_FORMATSIZE]; 1780 char altbuf[DNS_NAME_FORMATSIZE]; 1781 dns_fixedname_t fixed; 1782 dns_name_t *foundname; 1783 int level; 1784 1785 /* 1786 * "." means the services does not exist. 1787 */ 1788 if (dns_name_equal(name, dns_rootname)) 1789 return (ISC_TRUE); 1790 1791 /* 1792 * Outside of zone. 1793 */ 1794 if (!dns_name_issubdomain(name, &zone->origin)) { 1795 if (zone->checkmx != NULL) 1796 return ((zone->checkmx)(zone, name, owner)); 1797 return (ISC_TRUE); 1798 } 1799 1800 if (zone->type == dns_zone_master) 1801 level = ISC_LOG_ERROR; 1802 else 1803 level = ISC_LOG_WARNING; 1804 1805 dns_fixedname_init(&fixed); 1806 foundname = dns_fixedname_name(&fixed); 1807 1808 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 1809 0, 0, NULL, foundname, NULL, NULL); 1810 if (result == ISC_R_SUCCESS) 1811 return (ISC_TRUE); 1812 1813 if (result == DNS_R_NXRRSET) { 1814 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 1815 0, 0, NULL, foundname, NULL, NULL); 1816 if (result == ISC_R_SUCCESS) 1817 return (ISC_TRUE); 1818 } 1819 1820 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 1821 dns_name_format(name, namebuf, sizeof namebuf); 1822 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 1823 result == DNS_R_EMPTYNAME) { 1824 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) 1825 level = ISC_LOG_WARNING; 1826 dns_zone_log(zone, level, 1827 "%s/MX '%s' has no address records (A or AAAA)", 1828 ownerbuf, namebuf); 1829 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 1830 } 1831 1832 if (result == DNS_R_CNAME) { 1833 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 1834 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 1835 level = ISC_LOG_WARNING; 1836 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 1837 dns_zone_log(zone, level, 1838 "%s/MX '%s' is a CNAME (illegal)", 1839 ownerbuf, namebuf); 1840 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 1841 } 1842 1843 if (result == DNS_R_DNAME) { 1844 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || 1845 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) 1846 level = ISC_LOG_WARNING; 1847 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { 1848 dns_name_format(foundname, altbuf, sizeof altbuf); 1849 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME" 1850 " '%s' (illegal)", ownerbuf, namebuf, 1851 altbuf); 1852 } 1853 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 1854 } 1855 1856 if (zone->checkmx != NULL && result == DNS_R_DELEGATION) 1857 return ((zone->checkmx)(zone, name, owner)); 1858 1859 return (ISC_TRUE); 1860} 1861 1862static isc_boolean_t 1863zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 1864 dns_name_t *owner) 1865{ 1866 isc_result_t result; 1867 char ownerbuf[DNS_NAME_FORMATSIZE]; 1868 char namebuf[DNS_NAME_FORMATSIZE]; 1869 char altbuf[DNS_NAME_FORMATSIZE]; 1870 dns_fixedname_t fixed; 1871 dns_name_t *foundname; 1872 int level; 1873 1874 /* 1875 * "." means the services does not exist. 1876 */ 1877 if (dns_name_equal(name, dns_rootname)) 1878 return (ISC_TRUE); 1879 1880 /* 1881 * Outside of zone. 1882 */ 1883 if (!dns_name_issubdomain(name, &zone->origin)) { 1884 if (zone->checksrv != NULL) 1885 return ((zone->checksrv)(zone, name, owner)); 1886 return (ISC_TRUE); 1887 } 1888 1889 if (zone->type == dns_zone_master) 1890 level = ISC_LOG_ERROR; 1891 else 1892 level = ISC_LOG_WARNING; 1893 1894 dns_fixedname_init(&fixed); 1895 foundname = dns_fixedname_name(&fixed); 1896 1897 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 1898 0, 0, NULL, foundname, NULL, NULL); 1899 if (result == ISC_R_SUCCESS) 1900 return (ISC_TRUE); 1901 1902 if (result == DNS_R_NXRRSET) { 1903 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 1904 0, 0, NULL, foundname, NULL, NULL); 1905 if (result == ISC_R_SUCCESS) 1906 return (ISC_TRUE); 1907 } 1908 1909 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 1910 dns_name_format(name, namebuf, sizeof namebuf); 1911 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 1912 result == DNS_R_EMPTYNAME) { 1913 dns_zone_log(zone, level, 1914 "%s/SRV '%s' has no address records (A or AAAA)", 1915 ownerbuf, namebuf); 1916 /* XXX950 make fatal for 9.5.0. */ 1917 return (ISC_TRUE); 1918 } 1919 1920 if (result == DNS_R_CNAME) { 1921 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 1922 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 1923 level = ISC_LOG_WARNING; 1924 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 1925 dns_zone_log(zone, level, 1926 "%s/SRV '%s' is a CNAME (illegal)", 1927 ownerbuf, namebuf); 1928 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 1929 } 1930 1931 if (result == DNS_R_DNAME) { 1932 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || 1933 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) 1934 level = ISC_LOG_WARNING; 1935 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { 1936 dns_name_format(foundname, altbuf, sizeof altbuf); 1937 dns_zone_log(zone, level, "%s/SRV '%s' is below a " 1938 "DNAME '%s' (illegal)", ownerbuf, namebuf, 1939 altbuf); 1940 } 1941 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); 1942 } 1943 1944 if (zone->checksrv != NULL && result == DNS_R_DELEGATION) 1945 return ((zone->checksrv)(zone, name, owner)); 1946 1947 return (ISC_TRUE); 1948} 1949 1950static isc_boolean_t 1951zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, 1952 dns_name_t *owner) 1953{ 1954 isc_boolean_t answer = ISC_TRUE; 1955 isc_result_t result, tresult; 1956 char ownerbuf[DNS_NAME_FORMATSIZE]; 1957 char namebuf[DNS_NAME_FORMATSIZE]; 1958 char altbuf[DNS_NAME_FORMATSIZE]; 1959 dns_fixedname_t fixed; 1960 dns_name_t *foundname; 1961 dns_rdataset_t a; 1962 dns_rdataset_t aaaa; 1963 int level; 1964 1965 /* 1966 * Outside of zone. 1967 */ 1968 if (!dns_name_issubdomain(name, &zone->origin)) { 1969 if (zone->checkns != NULL) 1970 return ((zone->checkns)(zone, name, owner, NULL, NULL)); 1971 return (ISC_TRUE); 1972 } 1973 1974 if (zone->type == dns_zone_master) 1975 level = ISC_LOG_ERROR; 1976 else 1977 level = ISC_LOG_WARNING; 1978 1979 dns_fixedname_init(&fixed); 1980 foundname = dns_fixedname_name(&fixed); 1981 dns_rdataset_init(&a); 1982 dns_rdataset_init(&aaaa); 1983 1984 result = dns_db_find(db, name, NULL, dns_rdatatype_a, 1985 DNS_DBFIND_GLUEOK, 0, NULL, 1986 foundname, &a, NULL); 1987 1988 if (result == ISC_R_SUCCESS) { 1989 dns_rdataset_disassociate(&a); 1990 return (ISC_TRUE); 1991 } else if (result == DNS_R_DELEGATION) 1992 dns_rdataset_disassociate(&a); 1993 1994 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION || 1995 result == DNS_R_GLUE) { 1996 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 1997 DNS_DBFIND_GLUEOK, 0, NULL, 1998 foundname, &aaaa, NULL); 1999 if (tresult == ISC_R_SUCCESS) { 2000 dns_rdataset_disassociate(&aaaa); 2001 return (ISC_TRUE); 2002 } 2003 if (tresult == DNS_R_DELEGATION) 2004 dns_rdataset_disassociate(&aaaa); 2005 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) { 2006 /* 2007 * Check glue against child zone. 2008 */ 2009 if (zone->checkns != NULL) 2010 answer = (zone->checkns)(zone, name, owner, 2011 &a, &aaaa); 2012 if (dns_rdataset_isassociated(&a)) 2013 dns_rdataset_disassociate(&a); 2014 if (dns_rdataset_isassociated(&aaaa)) 2015 dns_rdataset_disassociate(&aaaa); 2016 return (answer); 2017 } 2018 } 2019 2020 dns_name_format(owner, ownerbuf, sizeof ownerbuf); 2021 dns_name_format(name, namebuf, sizeof namebuf); 2022 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 2023 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) { 2024 const char *what; 2025 isc_boolean_t required = ISC_FALSE; 2026 if (dns_name_issubdomain(name, owner)) { 2027 what = "REQUIRED GLUE "; 2028 required = ISC_TRUE; 2029 } else if (result == DNS_R_DELEGATION) 2030 what = "SIBLING GLUE "; 2031 else 2032 what = ""; 2033 2034 if (result != DNS_R_DELEGATION || required || 2035 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) { 2036 dns_zone_log(zone, level, "%s/NS '%s' has no %s" 2037 "address records (A or AAAA)", 2038 ownerbuf, namebuf, what); 2039 /* 2040 * Log missing address record. 2041 */ 2042 if (result == DNS_R_DELEGATION && zone->checkns != NULL) 2043 (void)(zone->checkns)(zone, name, owner, 2044 &a, &aaaa); 2045 /* XXX950 make fatal for 9.5.0. */ 2046 /* answer = ISC_FALSE; */ 2047 } 2048 } else if (result == DNS_R_CNAME) { 2049 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)", 2050 ownerbuf, namebuf); 2051 /* XXX950 make fatal for 9.5.0. */ 2052 /* answer = ISC_FALSE; */ 2053 } else if (result == DNS_R_DNAME) { 2054 dns_name_format(foundname, altbuf, sizeof altbuf); 2055 dns_zone_log(zone, level, 2056 "%s/NS '%s' is below a DNAME '%s' (illegal)", 2057 ownerbuf, namebuf, altbuf); 2058 /* XXX950 make fatal for 9.5.0. */ 2059 /* answer = ISC_FALSE; */ 2060 } 2061 2062 if (dns_rdataset_isassociated(&a)) 2063 dns_rdataset_disassociate(&a); 2064 if (dns_rdataset_isassociated(&aaaa)) 2065 dns_rdataset_disassociate(&aaaa); 2066 return (answer); 2067} 2068 2069static isc_boolean_t 2070zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner, 2071 dns_rdataset_t *rdataset) 2072{ 2073 dns_rdataset_t tmprdataset; 2074 isc_result_t result; 2075 isc_boolean_t answer = ISC_TRUE; 2076 isc_boolean_t format = ISC_TRUE; 2077 int level = ISC_LOG_WARNING; 2078 char ownerbuf[DNS_NAME_FORMATSIZE]; 2079 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 2080 unsigned int count1 = 0; 2081 2082 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL)) 2083 level = ISC_LOG_ERROR; 2084 2085 dns_rdataset_init(&tmprdataset); 2086 for (result = dns_rdataset_first(rdataset); 2087 result == ISC_R_SUCCESS; 2088 result = dns_rdataset_next(rdataset)) { 2089 dns_rdata_t rdata1 = DNS_RDATA_INIT; 2090 unsigned int count2 = 0; 2091 2092 count1++; 2093 dns_rdataset_current(rdataset, &rdata1); 2094 dns_rdataset_clone(rdataset, &tmprdataset); 2095 for (result = dns_rdataset_first(&tmprdataset); 2096 result == ISC_R_SUCCESS; 2097 result = dns_rdataset_next(&tmprdataset)) { 2098 dns_rdata_t rdata2 = DNS_RDATA_INIT; 2099 count2++; 2100 if (count1 >= count2) 2101 continue; 2102 dns_rdataset_current(&tmprdataset, &rdata2); 2103 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) { 2104 if (format) { 2105 dns_name_format(owner, ownerbuf, 2106 sizeof ownerbuf); 2107 dns_rdatatype_format(rdata1.type, 2108 typebuf, 2109 sizeof(typebuf)); 2110 format = ISC_FALSE; 2111 } 2112 dns_zone_log(zone, level, "%s/%s has " 2113 "semantically identical records", 2114 ownerbuf, typebuf); 2115 if (level == ISC_LOG_ERROR) 2116 answer = ISC_FALSE; 2117 break; 2118 } 2119 } 2120 dns_rdataset_disassociate(&tmprdataset); 2121 if (!format) 2122 break; 2123 } 2124 return (answer); 2125} 2126 2127static isc_boolean_t 2128zone_check_dup(dns_zone_t *zone, dns_db_t *db) { 2129 dns_dbiterator_t *dbiterator = NULL; 2130 dns_dbnode_t *node = NULL; 2131 dns_fixedname_t fixed; 2132 dns_name_t *name; 2133 dns_rdataset_t rdataset; 2134 dns_rdatasetiter_t *rdsit = NULL; 2135 isc_boolean_t ok = ISC_TRUE; 2136 isc_result_t result; 2137 2138 dns_fixedname_init(&fixed); 2139 name = dns_fixedname_name(&fixed); 2140 dns_rdataset_init(&rdataset); 2141 2142 result = dns_db_createiterator(db, 0, &dbiterator); 2143 if (result != ISC_R_SUCCESS) 2144 return (ISC_TRUE); 2145 2146 for (result = dns_dbiterator_first(dbiterator); 2147 result == ISC_R_SUCCESS; 2148 result = dns_dbiterator_next(dbiterator)) { 2149 result = dns_dbiterator_current(dbiterator, &node, name); 2150 if (result != ISC_R_SUCCESS) 2151 continue; 2152 2153 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit); 2154 if (result != ISC_R_SUCCESS) 2155 continue; 2156 2157 for (result = dns_rdatasetiter_first(rdsit); 2158 result == ISC_R_SUCCESS; 2159 result = dns_rdatasetiter_next(rdsit)) { 2160 dns_rdatasetiter_current(rdsit, &rdataset); 2161 if (!zone_rrset_check_dup(zone, name, &rdataset)) 2162 ok = ISC_FALSE; 2163 dns_rdataset_disassociate(&rdataset); 2164 } 2165 dns_rdatasetiter_destroy(&rdsit); 2166 dns_db_detachnode(db, &node); 2167 } 2168 2169 if (node != NULL) 2170 dns_db_detachnode(db, &node); 2171 dns_dbiterator_destroy(&dbiterator); 2172 2173 return (ok); 2174} 2175 2176static isc_boolean_t 2177integrity_checks(dns_zone_t *zone, dns_db_t *db) { 2178 dns_dbiterator_t *dbiterator = NULL; 2179 dns_dbnode_t *node = NULL; 2180 dns_rdataset_t rdataset; 2181 dns_fixedname_t fixed; 2182 dns_fixedname_t fixedbottom; 2183 dns_rdata_mx_t mx; 2184 dns_rdata_ns_t ns; 2185 dns_rdata_in_srv_t srv; 2186 dns_rdata_t rdata; 2187 dns_name_t *name; 2188 dns_name_t *bottom; 2189 isc_result_t result; 2190 isc_boolean_t ok = ISC_TRUE; 2191 2192 dns_fixedname_init(&fixed); 2193 name = dns_fixedname_name(&fixed); 2194 dns_fixedname_init(&fixedbottom); 2195 bottom = dns_fixedname_name(&fixedbottom); 2196 dns_rdataset_init(&rdataset); 2197 dns_rdata_init(&rdata); 2198 2199 result = dns_db_createiterator(db, 0, &dbiterator); 2200 if (result != ISC_R_SUCCESS) 2201 return (ISC_TRUE); 2202 2203 result = dns_dbiterator_first(dbiterator); 2204 while (result == ISC_R_SUCCESS) { 2205 result = dns_dbiterator_current(dbiterator, &node, name); 2206 if (result != ISC_R_SUCCESS) 2207 goto cleanup; 2208 2209 /* 2210 * Is this name visible in the zone? 2211 */ 2212 if (!dns_name_issubdomain(name, &zone->origin) || 2213 (dns_name_countlabels(bottom) > 0 && 2214 dns_name_issubdomain(name, bottom))) 2215 goto next; 2216 2217 /* 2218 * Don't check the NS records at the origin. 2219 */ 2220 if (dns_name_equal(name, &zone->origin)) 2221 goto checkmx; 2222 2223 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns, 2224 0, 0, &rdataset, NULL); 2225 if (result != ISC_R_SUCCESS) 2226 goto checkmx; 2227 /* 2228 * Remember bottom of zone. 2229 */ 2230 dns_name_copy(name, bottom, NULL); 2231 2232 result = dns_rdataset_first(&rdataset); 2233 while (result == ISC_R_SUCCESS) { 2234 dns_rdataset_current(&rdataset, &rdata); 2235 result = dns_rdata_tostruct(&rdata, &ns, NULL); 2236 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2237 if (!zone_check_glue(zone, db, &ns.name, name)) 2238 ok = ISC_FALSE; 2239 dns_rdata_reset(&rdata); 2240 result = dns_rdataset_next(&rdataset); 2241 } 2242 dns_rdataset_disassociate(&rdataset); 2243 goto next; 2244 2245 checkmx: 2246 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx, 2247 0, 0, &rdataset, NULL); 2248 if (result != ISC_R_SUCCESS) 2249 goto checksrv; 2250 result = dns_rdataset_first(&rdataset); 2251 while (result == ISC_R_SUCCESS) { 2252 dns_rdataset_current(&rdataset, &rdata); 2253 result = dns_rdata_tostruct(&rdata, &mx, NULL); 2254 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2255 if (!zone_check_mx(zone, db, &mx.mx, name)) 2256 ok = ISC_FALSE; 2257 dns_rdata_reset(&rdata); 2258 result = dns_rdataset_next(&rdataset); 2259 } 2260 dns_rdataset_disassociate(&rdataset); 2261 2262 checksrv: 2263 if (zone->rdclass != dns_rdataclass_in) 2264 goto next; 2265 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv, 2266 0, 0, &rdataset, NULL); 2267 if (result != ISC_R_SUCCESS) 2268 goto next; 2269 result = dns_rdataset_first(&rdataset); 2270 while (result == ISC_R_SUCCESS) { 2271 dns_rdataset_current(&rdataset, &rdata); 2272 result = dns_rdata_tostruct(&rdata, &srv, NULL); 2273 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2274 if (!zone_check_srv(zone, db, &srv.target, name)) 2275 ok = ISC_FALSE; 2276 dns_rdata_reset(&rdata); 2277 result = dns_rdataset_next(&rdataset); 2278 } 2279 dns_rdataset_disassociate(&rdataset); 2280 2281 next: 2282 dns_db_detachnode(db, &node); 2283 result = dns_dbiterator_next(dbiterator); 2284 } 2285 2286 cleanup: 2287 if (node != NULL) 2288 dns_db_detachnode(db, &node); 2289 dns_dbiterator_destroy(&dbiterator); 2290 2291 return (ok); 2292} 2293 2294/* 2295 * OpenSSL verification of RSA keys with exponent 3 is known to be 2296 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn 2297 * if they are in use. 2298 */ 2299static void 2300zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) { 2301 dns_dbnode_t *node = NULL; 2302 dns_dbversion_t *version = NULL; 2303 dns_rdata_dnskey_t dnskey; 2304 dns_rdata_t rdata = DNS_RDATA_INIT; 2305 dns_rdataset_t rdataset; 2306 isc_result_t result; 2307 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE; 2308 const char *algorithm; 2309 2310 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 2311 if (result != ISC_R_SUCCESS) 2312 goto cleanup; 2313 2314 dns_db_currentversion(db, &version); 2315 dns_rdataset_init(&rdataset); 2316 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, 2317 dns_rdatatype_none, 0, &rdataset, NULL); 2318 if (result != ISC_R_SUCCESS) 2319 goto cleanup; 2320 2321 for (result = dns_rdataset_first(&rdataset); 2322 result == ISC_R_SUCCESS; 2323 result = dns_rdataset_next(&rdataset)) 2324 { 2325 dns_rdataset_current(&rdataset, &rdata); 2326 result = dns_rdata_tostruct(&rdata, &dnskey, NULL); 2327 INSIST(result == ISC_R_SUCCESS); 2328 2329 if ((dnskey.algorithm == DST_ALG_RSASHA1 || 2330 dnskey.algorithm == DST_ALG_RSAMD5) && 2331 dnskey.datalen > 1 && dnskey.data[0] == 1 && 2332 dnskey.data[1] == 3) 2333 { 2334 if (dnskey.algorithm == DST_ALG_RSASHA1) { 2335 logit = !foundrsa; 2336 foundrsa = ISC_TRUE; 2337 algorithm = "RSASHA1"; 2338 } else { 2339 logit = !foundmd5; 2340 foundmd5 = ISC_TRUE; 2341 algorithm = "RSAMD5"; 2342 } 2343 if (logit) 2344 dns_zone_log(zone, ISC_LOG_WARNING, 2345 "weak %s (%u) key found " 2346 "(exponent=3)", algorithm, 2347 dnskey.algorithm); 2348 if (foundrsa && foundmd5) 2349 break; 2350 } 2351 dns_rdata_reset(&rdata); 2352 } 2353 dns_rdataset_disassociate(&rdataset); 2354 2355 cleanup: 2356 if (node != NULL) 2357 dns_db_detachnode(db, &node); 2358 if (version != NULL) 2359 dns_db_closeversion(db, &version, ISC_FALSE); 2360} 2361 2362static void 2363resume_signingwithkey(dns_zone_t *zone) { 2364 dns_dbnode_t *node = NULL; 2365 dns_dbversion_t *version = NULL; 2366 dns_rdata_t rdata = DNS_RDATA_INIT; 2367 dns_rdataset_t rdataset; 2368 isc_result_t result; 2369 2370 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node); 2371 if (result != ISC_R_SUCCESS) 2372 goto cleanup; 2373 2374 dns_db_currentversion(zone->db, &version); 2375 dns_rdataset_init(&rdataset); 2376 result = dns_db_findrdataset(zone->db, node, version, 2377 zone->privatetype, 2378 dns_rdatatype_none, 0, 2379 &rdataset, NULL); 2380 if (result != ISC_R_SUCCESS) { 2381 INSIST(!dns_rdataset_isassociated(&rdataset)); 2382 goto cleanup; 2383 } 2384 2385 for (result = dns_rdataset_first(&rdataset); 2386 result == ISC_R_SUCCESS; 2387 result = dns_rdataset_next(&rdataset)) 2388 { 2389 dns_rdataset_current(&rdataset, &rdata); 2390 if (rdata.length != 5 || 2391 rdata.data[0] == 0 || rdata.data[4] != 0) { 2392 dns_rdata_reset(&rdata); 2393 continue; 2394 } 2395 2396 result = zone_signwithkey(zone, rdata.data[0], 2397 (rdata.data[1] << 8) | rdata.data[2], 2398 ISC_TF(rdata.data[3])); 2399 if (result != ISC_R_SUCCESS) { 2400 dns_zone_log(zone, ISC_LOG_ERROR, 2401 "zone_signwithkey failed: %s", 2402 dns_result_totext(result)); 2403 } 2404 dns_rdata_reset(&rdata); 2405 } 2406 dns_rdataset_disassociate(&rdataset); 2407 2408 cleanup: 2409 if (node != NULL) 2410 dns_db_detachnode(zone->db, &node); 2411 if (version != NULL) 2412 dns_db_closeversion(zone->db, &version, ISC_FALSE); 2413} 2414 2415static isc_result_t 2416zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 2417 dns_nsec3chain_t *nsec3chain, *current; 2418 isc_result_t result; 2419 isc_time_t now; 2420 unsigned int options = 0; 2421 char saltbuf[255*2+1]; 2422 char flags[sizeof("REMOVE|CREATE|NONSEC|OPTOUT")]; 2423 int i; 2424 2425 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain); 2426 if (nsec3chain == NULL) 2427 return (ISC_R_NOMEMORY); 2428 2429 nsec3chain->magic = 0; 2430 nsec3chain->done = ISC_FALSE; 2431 nsec3chain->db = NULL; 2432 nsec3chain->dbiterator = NULL; 2433 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass; 2434 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype; 2435 nsec3chain->nsec3param.hash = nsec3param->hash; 2436 nsec3chain->nsec3param.iterations = nsec3param->iterations; 2437 nsec3chain->nsec3param.flags = nsec3param->flags; 2438 nsec3chain->nsec3param.salt_length = nsec3param->salt_length; 2439 memcpy(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length); 2440 nsec3chain->nsec3param.salt = nsec3chain->salt; 2441 nsec3chain->seen_nsec = ISC_FALSE; 2442 nsec3chain->delete_nsec = ISC_FALSE; 2443 nsec3chain->save_delete_nsec = ISC_FALSE; 2444 2445 if (nsec3param->flags == 0) 2446 strlcpy(flags, "NONE", sizeof(flags)); 2447 else { 2448 flags[0] = '\0'; 2449 if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) 2450 strlcat(flags, "REMOVE", sizeof(flags)); 2451 if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) { 2452 if (flags[0] == '\0') 2453 strlcpy(flags, "CREATE", sizeof(flags)); 2454 else 2455 strlcat(flags, "|CREATE", sizeof(flags)); 2456 } 2457 if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) { 2458 if (flags[0] == '\0') 2459 strlcpy(flags, "NONSEC", sizeof(flags)); 2460 else 2461 strlcat(flags, "|NONSEC", sizeof(flags)); 2462 } 2463 if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) { 2464 if (flags[0] == '\0') 2465 strlcpy(flags, "OPTOUT", sizeof(flags)); 2466 else 2467 strlcat(flags, "|OPTOUT", sizeof(flags)); 2468 } 2469 } 2470 if (nsec3param->salt_length == 0) 2471 strlcpy(saltbuf, "-", sizeof(saltbuf)); 2472 else 2473 for (i = 0; i < nsec3param->salt_length; i++) 2474 sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]); 2475 dns_zone_log(zone, ISC_LOG_INFO, 2476 "zone_addnsec3chain(%u,%s,%u,%s)", 2477 nsec3param->hash, flags, nsec3param->iterations, 2478 saltbuf); 2479 for (current = ISC_LIST_HEAD(zone->nsec3chain); 2480 current != NULL; 2481 current = ISC_LIST_NEXT(current, link)) { 2482 if (current->db == zone->db && 2483 current->nsec3param.hash == nsec3param->hash && 2484 current->nsec3param.iterations == nsec3param->iterations && 2485 current->nsec3param.salt_length == nsec3param->salt_length 2486 && !memcmp(current->nsec3param.salt, nsec3param->salt, 2487 nsec3param->salt_length)) 2488 current->done = ISC_TRUE; 2489 } 2490 2491 if (zone->db != NULL) { 2492 dns_db_attach(zone->db, &nsec3chain->db); 2493 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) 2494 options = DNS_DB_NONSEC3; 2495 result = dns_db_createiterator(nsec3chain->db, options, 2496 &nsec3chain->dbiterator); 2497 if (result == ISC_R_SUCCESS) 2498 dns_dbiterator_first(nsec3chain->dbiterator); 2499 if (result == ISC_R_SUCCESS) { 2500 dns_dbiterator_pause(nsec3chain->dbiterator); 2501 ISC_LIST_INITANDAPPEND(zone->nsec3chain, 2502 nsec3chain, link); 2503 nsec3chain = NULL; 2504 if (isc_time_isepoch(&zone->nsec3chaintime)) { 2505 TIME_NOW(&now); 2506 zone->nsec3chaintime = now; 2507 if (zone->task != NULL) 2508 zone_settimer(zone, &now); 2509 } 2510 } 2511 } else 2512 result = ISC_R_NOTFOUND; 2513 2514 if (nsec3chain != NULL) { 2515 if (nsec3chain->db != NULL) 2516 dns_db_detach(&nsec3chain->db); 2517 if (nsec3chain->dbiterator != NULL) 2518 dns_dbiterator_destroy(&nsec3chain->dbiterator); 2519 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 2520 } 2521 return (result); 2522} 2523 2524static void 2525resume_addnsec3chain(dns_zone_t *zone) { 2526 dns_dbnode_t *node = NULL; 2527 dns_dbversion_t *version = NULL; 2528 dns_rdataset_t rdataset; 2529 isc_result_t result; 2530 dns_rdata_nsec3param_t nsec3param; 2531 2532 if (zone->privatetype == 0) 2533 return; 2534 2535 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node); 2536 if (result != ISC_R_SUCCESS) 2537 goto cleanup; 2538 2539 dns_db_currentversion(zone->db, &version); 2540 dns_rdataset_init(&rdataset); 2541 result = dns_db_findrdataset(zone->db, node, version, 2542 zone->privatetype, dns_rdatatype_none, 2543 0, &rdataset, NULL); 2544 if (result != ISC_R_SUCCESS) { 2545 INSIST(!dns_rdataset_isassociated(&rdataset)); 2546 goto cleanup; 2547 } 2548 2549 for (result = dns_rdataset_first(&rdataset); 2550 result == ISC_R_SUCCESS; 2551 result = dns_rdataset_next(&rdataset)) 2552 { 2553 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 2554 dns_rdata_t rdata = DNS_RDATA_INIT; 2555 dns_rdata_t private = DNS_RDATA_INIT; 2556 2557 dns_rdataset_current(&rdataset, &private); 2558 if (!dns_nsec3param_fromprivate(&private, &rdata, buf, 2559 sizeof(buf))) 2560 continue; 2561 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 2562 RUNTIME_CHECK(result == ISC_R_SUCCESS); 2563 if ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 || 2564 (nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) { 2565 result = zone_addnsec3chain(zone, &nsec3param); 2566 if (result != ISC_R_SUCCESS) { 2567 dns_zone_log(zone, ISC_LOG_ERROR, 2568 "zone_addnsec3chain failed: %s", 2569 dns_result_totext(result)); 2570 } 2571 } 2572 } 2573 dns_rdataset_disassociate(&rdataset); 2574 cleanup: 2575 if (node != NULL) 2576 dns_db_detachnode(zone->db, &node); 2577 if (version != NULL) 2578 dns_db_closeversion(zone->db, &version, ISC_FALSE); 2579} 2580 2581static void 2582set_resigntime(dns_zone_t *zone) { 2583 dns_rdataset_t rdataset; 2584 dns_fixedname_t fixed; 2585 unsigned int resign; 2586 isc_result_t result; 2587 isc_uint32_t nanosecs; 2588 2589 dns_rdataset_init(&rdataset); 2590 dns_fixedname_init(&fixed); 2591 result = dns_db_getsigningtime(zone->db, &rdataset, 2592 dns_fixedname_name(&fixed)); 2593 if (result != ISC_R_SUCCESS) { 2594 isc_time_settoepoch(&zone->resigntime); 2595 return; 2596 } 2597 resign = rdataset.resign; 2598 dns_rdataset_disassociate(&rdataset); 2599 isc_random_get(&nanosecs); 2600 nanosecs %= 1000000000; 2601 isc_time_set(&zone->resigntime, resign, nanosecs); 2602} 2603 2604static isc_result_t 2605check_nsec3param(dns_zone_t *zone, dns_db_t *db) { 2606 dns_dbnode_t *node = NULL; 2607 dns_rdataset_t rdataset; 2608 dns_dbversion_t *version = NULL; 2609 dns_rdata_nsec3param_t nsec3param; 2610 isc_boolean_t ok = ISC_FALSE; 2611 isc_result_t result; 2612 dns_rdata_t rdata = DNS_RDATA_INIT; 2613 isc_boolean_t dynamic = (zone->type == dns_zone_master) ? 2614 zone_isdynamic(zone) : ISC_FALSE; 2615 2616 dns_rdataset_init(&rdataset); 2617 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 2618 if (result != ISC_R_SUCCESS) { 2619 dns_zone_log(zone, ISC_LOG_ERROR, 2620 "nsec3param lookup failure: %s", 2621 dns_result_totext(result)); 2622 return (result); 2623 } 2624 dns_db_currentversion(db, &version); 2625 2626 result = dns_db_findrdataset(db, node, version, 2627 dns_rdatatype_nsec3param, 2628 dns_rdatatype_none, 0, &rdataset, NULL); 2629 if (result == ISC_R_NOTFOUND) { 2630 INSIST(!dns_rdataset_isassociated(&rdataset)); 2631 result = ISC_R_SUCCESS; 2632 goto cleanup; 2633 } 2634 if (result != ISC_R_SUCCESS) { 2635 INSIST(!dns_rdataset_isassociated(&rdataset)); 2636 dns_zone_log(zone, ISC_LOG_ERROR, 2637 "nsec3param lookup failure: %s", 2638 dns_result_totext(result)); 2639 goto cleanup; 2640 } 2641 2642 /* 2643 * For dynamic zones we must support every algorithm so we can 2644 * regenerate all the NSEC3 chains. 2645 * For non-dynamic zones we only need to find a supported algorithm. 2646 */ 2647 for (result = dns_rdataset_first(&rdataset); 2648 result == ISC_R_SUCCESS; 2649 result = dns_rdataset_next(&rdataset)) 2650 { 2651 dns_rdataset_current(&rdataset, &rdata); 2652 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 2653 dns_rdata_reset(&rdata); 2654 INSIST(result == ISC_R_SUCCESS); 2655 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) && 2656 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic) 2657 { 2658 dns_zone_log(zone, ISC_LOG_WARNING, 2659 "nsec3 test \"unknown\" hash algorithm found: %u", 2660 nsec3param.hash); 2661 ok = ISC_TRUE; 2662 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) { 2663 if (dynamic) { 2664 dns_zone_log(zone, ISC_LOG_ERROR, 2665 "unsupported nsec3 hash algorithm" 2666 " in dynamic zone: %u", 2667 nsec3param.hash); 2668 result = DNS_R_BADZONE; 2669 /* Stop second error message. */ 2670 ok = ISC_TRUE; 2671 break; 2672 } else 2673 dns_zone_log(zone, ISC_LOG_WARNING, 2674 "unsupported nsec3 hash algorithm: %u", 2675 nsec3param.hash); 2676 } else 2677 ok = ISC_TRUE; 2678 } 2679 if (result == ISC_R_NOMORE) 2680 result = ISC_R_SUCCESS; 2681 2682 if (!ok) { 2683 result = DNS_R_BADZONE; 2684 dns_zone_log(zone, ISC_LOG_ERROR, 2685 "no supported nsec3 hash algorithm"); 2686 } 2687 2688 cleanup: 2689 if (dns_rdataset_isassociated(&rdataset)) 2690 dns_rdataset_disassociate(&rdataset); 2691 dns_db_closeversion(db, &version, ISC_FALSE); 2692 dns_db_detachnode(db, &node); 2693 return (result); 2694} 2695 2696/* 2697 * Set the timer for refreshing the key zone to the soonest future time 2698 * of the set (current timer, keydata->refresh, keydata->addhd, 2699 * keydata->removehd). 2700 */ 2701static void 2702set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key, 2703 isc_stdtime_t now) 2704{ 2705 const char me[] = "set_refreshkeytimer"; 2706 isc_stdtime_t then; 2707 isc_time_t timenow, timethen; 2708 char timebuf[80]; 2709 2710 ENTER; 2711 then = key->refresh; 2712 if (key->addhd > now && key->addhd < then) 2713 then = key->addhd; 2714 if (key->removehd > now && key->removehd < then) 2715 then = key->removehd; 2716 2717 TIME_NOW(&timenow); 2718 if (then > now) 2719 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 2720 else 2721 timethen = timenow; 2722 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 || 2723 isc_time_compare(&timethen, &zone->refreshkeytime) < 0) 2724 zone->refreshkeytime = timethen; 2725 2726 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 2727 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf); 2728 zone_settimer(zone, &timenow); 2729} 2730 2731/* 2732 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone. 2733 * If the key zone is changed, set '*changed' to ISC_TRUE. 2734 */ 2735static isc_result_t 2736create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 2737 dns_diff_t *diff, dns_keytable_t *keytable, 2738 dns_keynode_t **keynodep, isc_boolean_t *changed) 2739{ 2740 const char me[] = "create_keydata"; 2741 isc_result_t result = ISC_R_SUCCESS; 2742 isc_buffer_t keyb, dstb; 2743 unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE]; 2744 dns_rdata_keydata_t keydata; 2745 dns_rdata_dnskey_t dnskey; 2746 dns_rdata_t rdata = DNS_RDATA_INIT; 2747 dns_keynode_t *keynode; 2748 isc_stdtime_t now; 2749 isc_region_t r; 2750 dst_key_t *key; 2751 2752 REQUIRE(keynodep != NULL); 2753 keynode = *keynodep; 2754 2755 ENTER; 2756 isc_stdtime_get(&now); 2757 2758 /* Loop in case there's more than one key. */ 2759 while (result == ISC_R_SUCCESS) { 2760 dns_keynode_t *nextnode = NULL; 2761 2762 key = dns_keynode_key(keynode); 2763 if (key == NULL) 2764 goto skip; 2765 2766 isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf)); 2767 CHECK(dst_key_todns(key, &dstb)); 2768 2769 /* Convert DST key to DNSKEY. */ 2770 dns_rdata_reset(&rdata); 2771 isc_buffer_usedregion(&dstb, &r); 2772 dns_rdata_fromregion(&rdata, dst_key_class(key), 2773 dns_rdatatype_dnskey, &r); 2774 2775 /* DSTKEY to KEYDATA. */ 2776 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL)); 2777 CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0, 2778 NULL)); 2779 2780 /* KEYDATA to rdata. */ 2781 dns_rdata_reset(&rdata); 2782 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 2783 CHECK(dns_rdata_fromstruct(&rdata, 2784 zone->rdclass, dns_rdatatype_keydata, 2785 &keydata, &keyb)); 2786 2787 /* Add rdata to zone. */ 2788 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, 2789 dst_key_name(key), 0, &rdata)); 2790 *changed = ISC_TRUE; 2791 2792 skip: 2793 result = dns_keytable_nextkeynode(keytable, keynode, &nextnode); 2794 if (result != ISC_R_NOTFOUND) { 2795 dns_keytable_detachkeynode(keytable, &keynode); 2796 keynode = nextnode; 2797 } 2798 } 2799 2800 /* Refresh new keys from the zone apex as soon as possible. */ 2801 if (*changed) 2802 set_refreshkeytimer(zone, &keydata, now); 2803 2804 if (keynode != NULL) 2805 dns_keytable_detachkeynode(keytable, &keynode); 2806 *keynodep = NULL; 2807 2808 return (ISC_R_SUCCESS); 2809 2810 failure: 2811 return (result); 2812} 2813 2814/* 2815 * Remove from the key zone all the KEYDATA records found in rdataset. 2816 */ 2817static isc_result_t 2818delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 2819 dns_name_t *name, dns_rdataset_t *rdataset) 2820{ 2821 dns_rdata_t rdata = DNS_RDATA_INIT; 2822 isc_result_t result, uresult; 2823 2824 for (result = dns_rdataset_first(rdataset); 2825 result == ISC_R_SUCCESS; 2826 result = dns_rdataset_next(rdataset)) { 2827 dns_rdata_reset(&rdata); 2828 dns_rdataset_current(rdataset, &rdata); 2829 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, 2830 name, 0, &rdata); 2831 if (uresult != ISC_R_SUCCESS) 2832 return (uresult); 2833 } 2834 if (result == ISC_R_NOMORE) 2835 result = ISC_R_SUCCESS; 2836 return (result); 2837} 2838 2839/* 2840 * Compute the DNSSEC key ID for a DNSKEY record. 2841 */ 2842static isc_result_t 2843compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx, 2844 dns_keytag_t *tag) 2845{ 2846 isc_result_t result; 2847 dns_rdata_t rdata = DNS_RDATA_INIT; 2848 unsigned char data[4096]; 2849 isc_buffer_t buffer; 2850 dst_key_t *dstkey = NULL; 2851 2852 isc_buffer_init(&buffer, data, sizeof(data)); 2853 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 2854 dns_rdatatype_dnskey, dnskey, &buffer); 2855 2856 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey); 2857 if (result == ISC_R_SUCCESS) 2858 *tag = dst_key_id(dstkey); 2859 dst_key_free(&dstkey); 2860 2861 return (result); 2862} 2863 2864/* 2865 * Add key to the security roots. 2866 */ 2867static void 2868trust_key(dns_zone_t *zone, dns_name_t *keyname, 2869 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) { 2870 isc_result_t result; 2871 dns_rdata_t rdata = DNS_RDATA_INIT; 2872 unsigned char data[4096]; 2873 isc_buffer_t buffer; 2874 dns_keytable_t *sr = NULL; 2875 dst_key_t *dstkey = NULL; 2876 2877 /* Convert dnskey to DST key. */ 2878 isc_buffer_init(&buffer, data, sizeof(data)); 2879 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass, 2880 dns_rdatatype_dnskey, dnskey, &buffer); 2881 2882 result = dns_view_getsecroots(zone->view, &sr); 2883 if (result != ISC_R_SUCCESS) 2884 goto failure; 2885 2886 CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey)); 2887 CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey)); 2888 dns_keytable_detach(&sr); 2889 2890 failure: 2891 if (dstkey != NULL) 2892 dst_key_free(&dstkey); 2893 if (sr != NULL) 2894 dns_keytable_detach(&sr); 2895 return; 2896} 2897 2898/* 2899 * Add a null key to the security roots for so that all queries 2900 * to the zone will fail. 2901 */ 2902static void 2903fail_secure(dns_zone_t *zone, dns_name_t *keyname) { 2904 isc_result_t result; 2905 dns_keytable_t *sr = NULL; 2906 2907 result = dns_view_getsecroots(zone->view, &sr); 2908 if (result == ISC_R_SUCCESS) { 2909 dns_keytable_marksecure(sr, keyname); 2910 dns_keytable_detach(&sr); 2911 } 2912} 2913 2914/* 2915 * Scan a set of KEYDATA records from the key zone. The ones that are 2916 * valid (i.e., the add holddown timer has expired) become trusted keys. 2917 */ 2918static void 2919load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) { 2920 isc_result_t result; 2921 dns_rdata_t rdata = DNS_RDATA_INIT; 2922 dns_rdata_keydata_t keydata; 2923 dns_rdata_dnskey_t dnskey; 2924 isc_mem_t *mctx = zone->mctx; 2925 int trusted = 0, revoked = 0, pending = 0; 2926 isc_stdtime_t now; 2927 dns_keytable_t *sr = NULL; 2928 2929 isc_stdtime_get(&now); 2930 2931 result = dns_view_getsecroots(zone->view, &sr); 2932 if (result == ISC_R_SUCCESS) { 2933 dns_keytable_delete(sr, name); 2934 dns_keytable_detach(&sr); 2935 } 2936 2937 /* Now insert all the accepted trust anchors from this keydata set. */ 2938 for (result = dns_rdataset_first(rdataset); 2939 result == ISC_R_SUCCESS; 2940 result = dns_rdataset_next(rdataset)) { 2941 dns_rdata_reset(&rdata); 2942 dns_rdataset_current(rdataset, &rdata); 2943 2944 /* Convert rdata to keydata. */ 2945 dns_rdata_tostruct(&rdata, &keydata, NULL); 2946 2947 /* Set the key refresh timer. */ 2948 set_refreshkeytimer(zone, &keydata, now); 2949 2950 /* If the removal timer is nonzero, this key was revoked. */ 2951 if (keydata.removehd != 0) { 2952 revoked++; 2953 continue; 2954 } 2955 2956 /* 2957 * If the add timer is still pending, this key is not 2958 * trusted yet. 2959 */ 2960 if (now < keydata.addhd) { 2961 pending++; 2962 continue; 2963 } 2964 2965 /* Convert keydata to dnskey. */ 2966 dns_keydata_todnskey(&keydata, &dnskey, NULL); 2967 2968 /* Add to keytables. */ 2969 trusted++; 2970 trust_key(zone, name, &dnskey, mctx); 2971 } 2972 2973 if (trusted == 0 && pending != 0) { 2974 char namebuf[DNS_NAME_FORMATSIZE]; 2975 dns_name_format(name, namebuf, sizeof namebuf); 2976 dns_zone_log(zone, ISC_LOG_ERROR, 2977 "No valid trust anchors for '%s'!", namebuf); 2978 dns_zone_log(zone, ISC_LOG_ERROR, 2979 "%d key(s) revoked, %d still pending", 2980 revoked, pending); 2981 dns_zone_log(zone, ISC_LOG_ERROR, 2982 "All queries to '%s' will fail", namebuf); 2983 fail_secure(zone, name); 2984 } 2985} 2986 2987static isc_result_t 2988do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver, 2989 dns_diff_t *diff) 2990{ 2991 dns_diff_t temp_diff; 2992 isc_result_t result; 2993 2994 /* 2995 * Create a singleton diff. 2996 */ 2997 dns_diff_init(diff->mctx, &temp_diff); 2998 temp_diff.resign = diff->resign; 2999 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); 3000 3001 /* 3002 * Apply it to the database. 3003 */ 3004 result = dns_diff_apply(&temp_diff, db, ver); 3005 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); 3006 if (result != ISC_R_SUCCESS) { 3007 dns_difftuple_free(tuple); 3008 return (result); 3009 } 3010 3011 /* 3012 * Merge it into the current pending journal entry. 3013 */ 3014 dns_diff_appendminimal(diff, tuple); 3015 3016 /* 3017 * Do not clear temp_diff. 3018 */ 3019 return (ISC_R_SUCCESS); 3020} 3021 3022static isc_result_t 3023update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, 3024 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, 3025 dns_rdata_t *rdata) 3026{ 3027 dns_difftuple_t *tuple = NULL; 3028 isc_result_t result; 3029 result = dns_difftuple_create(diff->mctx, op, 3030 name, ttl, rdata, &tuple); 3031 if (result != ISC_R_SUCCESS) 3032 return (result); 3033 return (do_one_tuple(&tuple, db, ver, diff)); 3034} 3035 3036static isc_result_t 3037increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver, 3038 dns_diff_t *diff, isc_mem_t *mctx) { 3039 dns_difftuple_t *deltuple = NULL; 3040 dns_difftuple_t *addtuple = NULL; 3041 isc_uint32_t serial; 3042 isc_result_t result; 3043 3044 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple)); 3045 CHECK(dns_difftuple_copy(deltuple, &addtuple)); 3046 addtuple->op = DNS_DIFFOP_ADD; 3047 3048 serial = dns_soa_getserial(&addtuple->rdata); 3049 3050 /* RFC1982 */ 3051 serial = (serial + 1) & 0xFFFFFFFF; 3052 if (serial == 0) 3053 serial = 1; 3054 3055 dns_soa_setserial(serial, &addtuple->rdata); 3056 CHECK(do_one_tuple(&deltuple, db, ver, diff)); 3057 CHECK(do_one_tuple(&addtuple, db, ver, diff)); 3058 result = ISC_R_SUCCESS; 3059 3060 failure: 3061 if (addtuple != NULL) 3062 dns_difftuple_free(&addtuple); 3063 if (deltuple != NULL) 3064 dns_difftuple_free(&deltuple); 3065 return (result); 3066} 3067 3068/* 3069 * Write all transactions in 'diff' to the zone journal file. 3070 */ 3071static isc_result_t 3072zone_journal(dns_zone_t *zone, dns_diff_t *diff, const char *caller) { 3073 const char me[] = "zone_journal"; 3074 const char *journalfile; 3075 isc_result_t result = ISC_R_SUCCESS; 3076 dns_journal_t *journal = NULL; 3077 3078 ENTER; 3079 journalfile = dns_zone_getjournal(zone); 3080 if (journalfile != NULL) { 3081 result = dns_journal_open(zone->mctx, journalfile, 3082 ISC_TRUE, &journal); 3083 if (result != ISC_R_SUCCESS) { 3084 dns_zone_log(zone, ISC_LOG_ERROR, 3085 "%s:dns_journal_open -> %s\n", 3086 caller, dns_result_totext(result)); 3087 return (result); 3088 } 3089 3090 result = dns_journal_write_transaction(journal, diff); 3091 dns_journal_destroy(&journal); 3092 if (result != ISC_R_SUCCESS) { 3093 dns_zone_log(zone, ISC_LOG_ERROR, 3094 "%s:dns_journal_write_transaction -> %s\n", 3095 caller, dns_result_totext(result)); 3096 return (result); 3097 } 3098 } 3099 return (result); 3100} 3101 3102/* 3103 * Create an SOA record for a newly-created zone 3104 */ 3105static isc_result_t 3106add_soa(dns_zone_t *zone, dns_db_t *db) { 3107 isc_result_t result; 3108 dns_rdata_t rdata = DNS_RDATA_INIT; 3109 unsigned char buf[DNS_SOA_BUFFERSIZE]; 3110 dns_dbversion_t *ver = NULL; 3111 dns_diff_t diff; 3112 3113 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA"); 3114 3115 dns_diff_init(zone->mctx, &diff); 3116 result = dns_db_newversion(db, &ver); 3117 if (result != ISC_R_SUCCESS) { 3118 dns_zone_log(zone, ISC_LOG_ERROR, 3119 "add_soa:dns_db_newversion -> %s\n", 3120 dns_result_totext(result)); 3121 goto failure; 3122 } 3123 3124 /* Build SOA record */ 3125 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass, 3126 0, 0, 0, 0, 0, buf, &rdata); 3127 if (result != ISC_R_SUCCESS) { 3128 dns_zone_log(zone, ISC_LOG_ERROR, 3129 "add_soa:dns_soa_buildrdata -> %s\n", 3130 dns_result_totext(result)); 3131 goto failure; 3132 } 3133 3134 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD, 3135 &zone->origin, 0, &rdata); 3136 3137failure: 3138 dns_diff_clear(&diff); 3139 if (ver != NULL) 3140 dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS)); 3141 3142 return (result); 3143} 3144 3145/* 3146 * Synchronize the set of initializing keys found in managed-keys {} 3147 * statements with the set of trust anchors found in the managed-keys.bind 3148 * zone. If a domain is no longer named in managed-keys, delete all keys 3149 * from that domain from the key zone. If a domain is mentioned in in 3150 * managed-keys but there are no references to it in the key zone, load 3151 * the key zone with the initializing key(s) for that domain. 3152 */ 3153static isc_result_t 3154sync_keyzone(dns_zone_t *zone, dns_db_t *db) { 3155 isc_result_t result = ISC_R_SUCCESS; 3156 isc_boolean_t changed = ISC_FALSE; 3157 isc_boolean_t commit = ISC_FALSE; 3158 dns_rbtnodechain_t chain; 3159 dns_fixedname_t fn; 3160 dns_name_t foundname, *origin; 3161 dns_keynode_t *keynode = NULL; 3162 dns_view_t *view = zone->view; 3163 dns_keytable_t *sr = NULL; 3164 dns_dbversion_t *ver = NULL; 3165 dns_diff_t diff; 3166 dns_rriterator_t rrit; 3167 3168 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys"); 3169 3170 dns_name_init(&foundname, NULL); 3171 dns_fixedname_init(&fn); 3172 origin = dns_fixedname_name(&fn); 3173 3174 dns_diff_init(zone->mctx, &diff); 3175 3176 CHECK(dns_view_getsecroots(view, &sr)); 3177 3178 result = dns_db_newversion(db, &ver); 3179 if (result != ISC_R_SUCCESS) { 3180 dns_zone_log(zone, ISC_LOG_ERROR, 3181 "sync_keyzone:dns_db_newversion -> %s\n", 3182 dns_result_totext(result)); 3183 goto failure; 3184 } 3185 3186 /* 3187 * Walk the zone DB. If we find any keys whose names are no longer 3188 * in managed-keys (or *are* in trusted-keys, meaning they are 3189 * permanent and not RFC5011-maintained), delete them from the 3190 * zone. Otherwise call load_secroots(), which loads keys into 3191 * secroots as appropriate. 3192 */ 3193 dns_rriterator_init(&rrit, db, ver, 0); 3194 for (result = dns_rriterator_first(&rrit); 3195 result == ISC_R_SUCCESS; 3196 result = dns_rriterator_nextrrset(&rrit)) { 3197 dns_rdataset_t *rdataset = NULL; 3198 dns_name_t *rrname = NULL; 3199 isc_uint32_t ttl; 3200 3201 dns_rriterator_current(&rrit, &rrname, &ttl, 3202 &rdataset, NULL); 3203 if (!dns_rdataset_isassociated(rdataset)) { 3204 dns_rriterator_destroy(&rrit); 3205 goto failure; 3206 } 3207 3208 if (rdataset->type != dns_rdatatype_keydata) 3209 continue; 3210 3211 result = dns_keytable_find(sr, rrname, &keynode); 3212 if ((result != ISC_R_SUCCESS && 3213 result != DNS_R_PARTIALMATCH) || 3214 dns_keynode_managed(keynode) == ISC_FALSE) { 3215 CHECK(delete_keydata(db, ver, &diff, 3216 rrname, rdataset)); 3217 changed = ISC_TRUE; 3218 } else { 3219 load_secroots(zone, rrname, rdataset); 3220 } 3221 3222 if (keynode != NULL) 3223 dns_keytable_detachkeynode(sr, &keynode); 3224 } 3225 dns_rriterator_destroy(&rrit); 3226 3227 /* 3228 * Now walk secroots to find any managed keys that aren't 3229 * in the zone. If we find any, we add them to the zone. 3230 */ 3231 RWLOCK(&sr->rwlock, isc_rwlocktype_write); 3232 dns_rbtnodechain_init(&chain, zone->mctx); 3233 result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin); 3234 if (result == ISC_R_NOTFOUND) 3235 result = ISC_R_NOMORE; 3236 while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { 3237 dns_rbtnode_t *rbtnode = NULL; 3238 3239 dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode); 3240 if (rbtnode->data == NULL) 3241 goto skip; 3242 3243 dns_keytable_attachkeynode(sr, rbtnode->data, &keynode); 3244 if (dns_keynode_managed(keynode)) { 3245 dns_fixedname_t fname; 3246 dns_name_t *keyname; 3247 dst_key_t *key; 3248 3249 key = dns_keynode_key(keynode); 3250 dns_fixedname_init(&fname); 3251 3252 if (key == NULL) /* fail_secure() was called. */ 3253 goto skip; 3254 3255 keyname = dst_key_name(key); 3256 result = dns_db_find(db, keyname, ver, 3257 dns_rdatatype_keydata, 3258 DNS_DBFIND_NOWILD, 0, NULL, 3259 dns_fixedname_name(&fname), 3260 NULL, NULL); 3261 if (result != ISC_R_SUCCESS) 3262 result = create_keydata(zone, db, ver, &diff, 3263 sr, &keynode, &changed); 3264 if (result != ISC_R_SUCCESS) 3265 break; 3266 } 3267 skip: 3268 result = dns_rbtnodechain_next(&chain, &foundname, origin); 3269 if (keynode != NULL) 3270 dns_keytable_detachkeynode(sr, &keynode); 3271 } 3272 RWUNLOCK(&sr->rwlock, isc_rwlocktype_write); 3273 3274 if (result == ISC_R_NOMORE) 3275 result = ISC_R_SUCCESS; 3276 3277 if (changed) { 3278 /* Write changes to journal file. */ 3279 CHECK(increment_soa_serial(db, ver, &diff, zone->mctx)); 3280 CHECK(zone_journal(zone, &diff, "sync_keyzone")); 3281 3282 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 3283 zone_needdump(zone, 30); 3284 commit = ISC_TRUE; 3285 } 3286 3287 failure: 3288 if (keynode != NULL) 3289 dns_keytable_detachkeynode(sr, &keynode); 3290 if (sr != NULL) 3291 dns_keytable_detach(&sr); 3292 if (ver != NULL) 3293 dns_db_closeversion(db, &ver, commit); 3294 dns_diff_clear(&diff); 3295 3296 return (result); 3297} 3298 3299static isc_result_t 3300zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, 3301 isc_result_t result) 3302{ 3303 unsigned int soacount = 0; 3304 unsigned int nscount = 0; 3305 unsigned int errors = 0; 3306 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum; 3307 isc_time_t now; 3308 isc_boolean_t needdump = ISC_FALSE; 3309 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE); 3310 isc_boolean_t nomaster = ISC_FALSE; 3311 unsigned int options; 3312 3313 TIME_NOW(&now); 3314 3315 /* 3316 * Initiate zone transfer? We may need a error code that 3317 * indicates that the "permanent" form does not exist. 3318 * XXX better error feedback to log. 3319 */ 3320 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { 3321 if (zone->type == dns_zone_slave || 3322 zone->type == dns_zone_stub) { 3323 if (result == ISC_R_FILENOTFOUND) 3324 dns_zone_log(zone, ISC_LOG_DEBUG(1), 3325 "no master file"); 3326 else if (result != DNS_R_NOMASTERFILE) 3327 dns_zone_log(zone, ISC_LOG_ERROR, 3328 "loading from master file %s " 3329 "failed: %s", 3330 zone->masterfile, 3331 dns_result_totext(result)); 3332 } else { 3333 int level = ISC_LOG_ERROR; 3334 if (zone->type == dns_zone_key && 3335 result == ISC_R_FILENOTFOUND) 3336 level = ISC_LOG_DEBUG(1); 3337 dns_zone_log(zone, level, 3338 "loading from master file %s failed: %s", 3339 zone->masterfile, 3340 dns_result_totext(result)); 3341 nomaster = ISC_TRUE; 3342 } 3343 3344 if (zone->type != dns_zone_key) 3345 goto cleanup; 3346 } 3347 3348 dns_zone_log(zone, ISC_LOG_DEBUG(2), 3349 "number of nodes in database: %u", 3350 dns_db_nodecount(db)); 3351 3352 if (result == DNS_R_SEENINCLUDE) 3353 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 3354 else 3355 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE); 3356 3357 /* 3358 * If there's no master file for a key zone, then the zone is new: 3359 * create an SOA record. (We do this now, instead of later, so that 3360 * if there happens to be a journal file, we can roll forward from 3361 * a sane starting point.) 3362 */ 3363 if (nomaster && zone->type == dns_zone_key) { 3364 result = add_soa(zone, db); 3365 if (result != ISC_R_SUCCESS) 3366 goto cleanup; 3367 } 3368 3369 /* 3370 * Apply update log, if any, on initial load. 3371 */ 3372 if (zone->journal != NULL && 3373 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) && 3374 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 3375 { 3376 if (zone->type == dns_zone_master && 3377 (zone->update_acl != NULL || zone->ssutable != NULL)) 3378 options = DNS_JOURNALOPT_RESIGN; 3379 else 3380 options = 0; 3381 result = dns_journal_rollforward2(zone->mctx, db, options, 3382 zone->sigresigninginterval, 3383 zone->journal); 3384 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND && 3385 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL && 3386 result != ISC_R_RANGE) { 3387 dns_zone_log(zone, ISC_LOG_ERROR, 3388 "journal rollforward failed: %s", 3389 dns_result_totext(result)); 3390 goto cleanup; 3391 } 3392 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) { 3393 dns_zone_log(zone, ISC_LOG_ERROR, 3394 "journal rollforward failed: " 3395 "journal out of sync with zone"); 3396 goto cleanup; 3397 } 3398 dns_zone_log(zone, ISC_LOG_DEBUG(1), 3399 "journal rollforward completed " 3400 "successfully: %s", 3401 dns_result_totext(result)); 3402 if (result == ISC_R_SUCCESS) 3403 needdump = ISC_TRUE; 3404 } 3405 3406 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity"); 3407 /* 3408 * Obtain ns, soa and cname counts for top of zone. 3409 */ 3410 INSIST(db != NULL); 3411 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial, 3412 &refresh, &retry, &expire, &minimum, 3413 &errors); 3414 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) { 3415 dns_zone_log(zone, ISC_LOG_ERROR, 3416 "could not find NS and/or SOA records"); 3417 } 3418 3419 /* 3420 * Master / Slave / Stub zones require both NS and SOA records at 3421 * the top of the zone. 3422 */ 3423 3424 switch (zone->type) { 3425 case dns_zone_dlz: 3426 case dns_zone_master: 3427 case dns_zone_slave: 3428 case dns_zone_stub: 3429 if (soacount != 1) { 3430 dns_zone_log(zone, ISC_LOG_ERROR, 3431 "has %d SOA records", soacount); 3432 result = DNS_R_BADZONE; 3433 } 3434 if (nscount == 0) { 3435 dns_zone_log(zone, ISC_LOG_ERROR, 3436 "has no NS records"); 3437 result = DNS_R_BADZONE; 3438 } 3439 if (result != ISC_R_SUCCESS) 3440 goto cleanup; 3441 if (zone->type == dns_zone_master && errors != 0) { 3442 result = DNS_R_BADZONE; 3443 goto cleanup; 3444 } 3445 if (zone->type != dns_zone_stub) { 3446 result = check_nsec3param(zone, db); 3447 if (result != ISC_R_SUCCESS) 3448 goto cleanup; 3449 } 3450 if (zone->type == dns_zone_master && 3451 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) && 3452 !integrity_checks(zone, db)) { 3453 result = DNS_R_BADZONE; 3454 goto cleanup; 3455 } 3456 3457 if (zone->type == dns_zone_master && 3458 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) && 3459 !zone_check_dup(zone, db)) { 3460 result = DNS_R_BADZONE; 3461 goto cleanup; 3462 } 3463 3464 if (zone->db != NULL) { 3465 /* 3466 * This is checked in zone_replacedb() for slave zones 3467 * as they don't reload from disk. 3468 */ 3469 result = zone_get_from_db(zone, zone->db, NULL, NULL, 3470 &oldserial, NULL, NULL, NULL, 3471 NULL, NULL); 3472 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3473 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 3474 !isc_serial_gt(serial, oldserial)) { 3475 isc_uint32_t serialmin, serialmax; 3476 3477 INSIST(zone->type == dns_zone_master); 3478 3479 serialmin = (oldserial + 1) & 0xffffffffU; 3480 serialmax = (oldserial + 0x7fffffffU) & 3481 0xffffffffU; 3482 dns_zone_log(zone, ISC_LOG_ERROR, 3483 "ixfr-from-differences: " 3484 "new serial (%u) out of range " 3485 "[%u - %u]", serial, serialmin, 3486 serialmax); 3487 result = DNS_R_BADZONE; 3488 goto cleanup; 3489 } else if (!isc_serial_ge(serial, oldserial)) 3490 dns_zone_log(zone, ISC_LOG_ERROR, 3491 "zone serial (%u/%u) has gone " 3492 "backwards", serial, oldserial); 3493 else if (serial == oldserial && !hasinclude && 3494 strcmp(zone->db_argv[0], "_builtin") != 0) 3495 dns_zone_log(zone, ISC_LOG_ERROR, 3496 "zone serial (%u) unchanged. " 3497 "zone may fail to transfer " 3498 "to slaves.", serial); 3499 } 3500 3501 if (zone->type == dns_zone_master && 3502 (zone->update_acl != NULL || zone->ssutable != NULL) && 3503 zone->sigresigninginterval < (3 * refresh) && 3504 dns_db_issecure(db)) 3505 { 3506 dns_zone_log(zone, ISC_LOG_WARNING, 3507 "sig-re-signing-interval less than " 3508 "3 * refresh."); 3509 } 3510 3511 zone->refresh = RANGE(refresh, 3512 zone->minrefresh, zone->maxrefresh); 3513 zone->retry = RANGE(retry, 3514 zone->minretry, zone->maxretry); 3515 zone->expire = RANGE(expire, zone->refresh + zone->retry, 3516 DNS_MAX_EXPIRE); 3517 zone->minimum = minimum; 3518 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 3519 3520 if (zone->type == dns_zone_slave || 3521 zone->type == dns_zone_stub) { 3522 isc_time_t t; 3523 isc_uint32_t delay; 3524 3525 result = isc_file_getmodtime(zone->journal, &t); 3526 if (result != ISC_R_SUCCESS) 3527 result = isc_file_getmodtime(zone->masterfile, 3528 &t); 3529 if (result == ISC_R_SUCCESS) 3530 DNS_ZONE_TIME_ADD(&t, zone->expire, 3531 &zone->expiretime); 3532 else 3533 DNS_ZONE_TIME_ADD(&now, zone->retry, 3534 &zone->expiretime); 3535 3536 delay = isc_random_jitter(zone->retry, 3537 (zone->retry * 3) / 4); 3538 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime); 3539 if (isc_time_compare(&zone->refreshtime, 3540 &zone->expiretime) >= 0) 3541 zone->refreshtime = now; 3542 } 3543 break; 3544 3545 case dns_zone_key: 3546 result = sync_keyzone(zone, db); 3547 if (result != ISC_R_SUCCESS) 3548 goto cleanup; 3549 break; 3550 3551 default: 3552 UNEXPECTED_ERROR(__FILE__, __LINE__, 3553 "unexpected zone type %d", zone->type); 3554 result = ISC_R_UNEXPECTED; 3555 goto cleanup; 3556 } 3557 3558 /* 3559 * Check for weak DNSKEY's. 3560 */ 3561 if (zone->type == dns_zone_master) 3562 zone_check_dnskeys(zone, db); 3563 3564 /* 3565 * Schedule DNSSEC key refresh. 3566 */ 3567 if (zone->type == dns_zone_master && 3568 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) 3569 zone->refreshkeytime = now; 3570 3571#if 0 3572 /* destroy notification example. */ 3573 { 3574 isc_event_t *e = isc_event_allocate(zone->mctx, NULL, 3575 DNS_EVENT_DBDESTROYED, 3576 dns_zonemgr_dbdestroyed, 3577 zone, 3578 sizeof(isc_event_t)); 3579 dns_db_ondestroy(db, zone->task, &e); 3580 } 3581#endif 3582 3583 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 3584 if (zone->db != NULL) { 3585 result = zone_replacedb(zone, db, ISC_FALSE); 3586 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 3587 if (result != ISC_R_SUCCESS) 3588 goto cleanup; 3589 } else { 3590 zone_attachdb(zone, db); 3591 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 3592 DNS_ZONE_SETFLAG(zone, 3593 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY); 3594 } 3595 3596 result = ISC_R_SUCCESS; 3597 3598 if (needdump) { 3599 if (zone->type == dns_zone_key) 3600 zone_needdump(zone, 30); 3601 else 3602 zone_needdump(zone, DNS_DUMP_DELAY); 3603 } 3604 3605 if (zone->task != NULL) { 3606 if (zone->type == dns_zone_master) { 3607 set_resigntime(zone); 3608 resume_signingwithkey(zone); 3609 resume_addnsec3chain(zone); 3610 } 3611 3612 if (zone->type == dns_zone_master && 3613 zone_isdynamic(zone) && 3614 dns_db_issecure(db)) { 3615 dns_name_t *name; 3616 dns_fixedname_t fixed; 3617 dns_rdataset_t next; 3618 3619 dns_rdataset_init(&next); 3620 dns_fixedname_init(&fixed); 3621 name = dns_fixedname_name(&fixed); 3622 3623 result = dns_db_getsigningtime(db, &next, name); 3624 if (result == ISC_R_SUCCESS) { 3625 isc_stdtime_t timenow; 3626 char namebuf[DNS_NAME_FORMATSIZE]; 3627 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 3628 3629 isc_stdtime_get(&timenow); 3630 dns_name_format(name, namebuf, sizeof(namebuf)); 3631 dns_rdatatype_format(next.covers, 3632 typebuf, sizeof(typebuf)); 3633 dns_zone_log(zone, ISC_LOG_DEBUG(3), 3634 "next resign: %s/%s in %d seconds", 3635 namebuf, typebuf, 3636 next.resign - timenow); 3637 dns_rdataset_disassociate(&next); 3638 } else 3639 dns_zone_log(zone, ISC_LOG_WARNING, 3640 "signed dynamic zone has no " 3641 "resign event scheduled"); 3642 } 3643 3644 zone_settimer(zone, &now); 3645 } 3646 3647 if (! dns_db_ispersistent(db)) 3648 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial, 3649 dns_db_issecure(db) ? " (DNSSEC signed)" : ""); 3650 3651 zone->loadtime = loadtime; 3652 return (result); 3653 3654 cleanup: 3655 if (zone->type == dns_zone_slave || 3656 zone->type == dns_zone_stub || 3657 zone->type == dns_zone_key) { 3658 if (zone->journal != NULL) 3659 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX"); 3660 if (zone->masterfile != NULL) 3661 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX"); 3662 3663 /* Mark the zone for immediate refresh. */ 3664 zone->refreshtime = now; 3665 if (zone->task != NULL) 3666 zone_settimer(zone, &now); 3667 result = ISC_R_SUCCESS; 3668 } else if (zone->type == dns_zone_master) 3669 dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors."); 3670 return (result); 3671} 3672 3673static isc_boolean_t 3674exit_check(dns_zone_t *zone) { 3675 3676 REQUIRE(LOCKED_ZONE(zone)); 3677 3678 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && 3679 zone->irefs == 0) 3680 { 3681 /* 3682 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0. 3683 */ 3684 INSIST(isc_refcount_current(&zone->erefs) == 0); 3685 return (ISC_TRUE); 3686 } 3687 return (ISC_FALSE); 3688} 3689 3690static isc_boolean_t 3691zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 3692 dns_name_t *name, isc_boolean_t logit) 3693{ 3694 isc_result_t result; 3695 char namebuf[DNS_NAME_FORMATSIZE]; 3696 char altbuf[DNS_NAME_FORMATSIZE]; 3697 dns_fixedname_t fixed; 3698 dns_name_t *foundname; 3699 int level; 3700 3701 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) 3702 return (ISC_TRUE); 3703 3704 if (zone->type == dns_zone_master) 3705 level = ISC_LOG_ERROR; 3706 else 3707 level = ISC_LOG_WARNING; 3708 3709 dns_fixedname_init(&fixed); 3710 foundname = dns_fixedname_name(&fixed); 3711 3712 result = dns_db_find(db, name, version, dns_rdatatype_a, 3713 0, 0, NULL, foundname, NULL, NULL); 3714 if (result == ISC_R_SUCCESS) 3715 return (ISC_TRUE); 3716 3717 if (result == DNS_R_NXRRSET) { 3718 result = dns_db_find(db, name, version, dns_rdatatype_aaaa, 3719 0, 0, NULL, foundname, NULL, NULL); 3720 if (result == ISC_R_SUCCESS) 3721 return (ISC_TRUE); 3722 } 3723 3724 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || 3725 result == DNS_R_EMPTYNAME) { 3726 if (logit) { 3727 dns_name_format(name, namebuf, sizeof namebuf); 3728 dns_zone_log(zone, level, "NS '%s' has no address " 3729 "records (A or AAAA)", namebuf); 3730 } 3731 return (ISC_FALSE); 3732 } 3733 3734 if (result == DNS_R_CNAME) { 3735 if (logit) { 3736 dns_name_format(name, namebuf, sizeof namebuf); 3737 dns_zone_log(zone, level, "NS '%s' is a CNAME " 3738 "(illegal)", namebuf); 3739 } 3740 return (ISC_FALSE); 3741 } 3742 3743 if (result == DNS_R_DNAME) { 3744 if (logit) { 3745 dns_name_format(name, namebuf, sizeof namebuf); 3746 dns_name_format(foundname, altbuf, sizeof altbuf); 3747 dns_zone_log(zone, level, "NS '%s' is below a DNAME " 3748 "'%s' (illegal)", namebuf, altbuf); 3749 } 3750 return (ISC_FALSE); 3751 } 3752 3753 return (ISC_TRUE); 3754} 3755 3756static isc_result_t 3757zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, 3758 dns_dbversion_t *version, unsigned int *nscount, 3759 unsigned int *errors, isc_boolean_t logit) 3760{ 3761 isc_result_t result; 3762 unsigned int count = 0; 3763 unsigned int ecount = 0; 3764 dns_rdataset_t rdataset; 3765 dns_rdata_t rdata; 3766 dns_rdata_ns_t ns; 3767 3768 dns_rdataset_init(&rdataset); 3769 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns, 3770 dns_rdatatype_none, 0, &rdataset, NULL); 3771 if (result == ISC_R_NOTFOUND) { 3772 INSIST(!dns_rdataset_isassociated(&rdataset)); 3773 goto success; 3774 } 3775 if (result != ISC_R_SUCCESS) { 3776 INSIST(!dns_rdataset_isassociated(&rdataset)); 3777 goto invalidate_rdataset; 3778 } 3779 3780 result = dns_rdataset_first(&rdataset); 3781 while (result == ISC_R_SUCCESS) { 3782 if (errors != NULL && zone->rdclass == dns_rdataclass_in && 3783 (zone->type == dns_zone_master || 3784 zone->type == dns_zone_slave)) { 3785 dns_rdata_init(&rdata); 3786 dns_rdataset_current(&rdataset, &rdata); 3787 result = dns_rdata_tostruct(&rdata, &ns, NULL); 3788 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3789 if (dns_name_issubdomain(&ns.name, &zone->origin) && 3790 !zone_check_ns(zone, db, version, &ns.name, logit)) 3791 ecount++; 3792 } 3793 count++; 3794 result = dns_rdataset_next(&rdataset); 3795 } 3796 dns_rdataset_disassociate(&rdataset); 3797 3798 success: 3799 if (nscount != NULL) 3800 *nscount = count; 3801 if (errors != NULL) 3802 *errors = ecount; 3803 3804 result = ISC_R_SUCCESS; 3805 3806 invalidate_rdataset: 3807 dns_rdataset_invalidate(&rdataset); 3808 3809 return (result); 3810} 3811 3812static isc_result_t 3813zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 3814 unsigned int *soacount, 3815 isc_uint32_t *serial, isc_uint32_t *refresh, 3816 isc_uint32_t *retry, isc_uint32_t *expire, 3817 isc_uint32_t *minimum) 3818{ 3819 isc_result_t result; 3820 unsigned int count; 3821 dns_rdataset_t rdataset; 3822 dns_rdata_t rdata = DNS_RDATA_INIT; 3823 dns_rdata_soa_t soa; 3824 3825 dns_rdataset_init(&rdataset); 3826 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, 3827 dns_rdatatype_none, 0, &rdataset, NULL); 3828 if (result == ISC_R_NOTFOUND) { 3829 INSIST(!dns_rdataset_isassociated(&rdataset)); 3830 if (soacount != NULL) 3831 *soacount = 0; 3832 if (serial != NULL) 3833 *serial = 0; 3834 if (refresh != NULL) 3835 *refresh = 0; 3836 if (retry != NULL) 3837 *retry = 0; 3838 if (expire != NULL) 3839 *expire = 0; 3840 if (minimum != NULL) 3841 *minimum = 0; 3842 result = ISC_R_SUCCESS; 3843 goto invalidate_rdataset; 3844 } 3845 if (result != ISC_R_SUCCESS) { 3846 INSIST(!dns_rdataset_isassociated(&rdataset)); 3847 goto invalidate_rdataset; 3848 } 3849 3850 count = 0; 3851 result = dns_rdataset_first(&rdataset); 3852 while (result == ISC_R_SUCCESS) { 3853 dns_rdata_init(&rdata); 3854 dns_rdataset_current(&rdataset, &rdata); 3855 count++; 3856 if (count == 1) { 3857 result = dns_rdata_tostruct(&rdata, &soa, NULL); 3858 RUNTIME_CHECK(result == ISC_R_SUCCESS); 3859 } 3860 3861 result = dns_rdataset_next(&rdataset); 3862 dns_rdata_reset(&rdata); 3863 } 3864 dns_rdataset_disassociate(&rdataset); 3865 3866 if (soacount != NULL) 3867 *soacount = count; 3868 3869 if (count > 0) { 3870 if (serial != NULL) 3871 *serial = soa.serial; 3872 if (refresh != NULL) 3873 *refresh = soa.refresh; 3874 if (retry != NULL) 3875 *retry = soa.retry; 3876 if (expire != NULL) 3877 *expire = soa.expire; 3878 if (minimum != NULL) 3879 *minimum = soa.minimum; 3880 } 3881 3882 result = ISC_R_SUCCESS; 3883 3884 invalidate_rdataset: 3885 dns_rdataset_invalidate(&rdataset); 3886 3887 return (result); 3888} 3889 3890/* 3891 * zone must be locked. 3892 */ 3893static isc_result_t 3894zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, 3895 unsigned int *soacount, isc_uint32_t *serial, 3896 isc_uint32_t *refresh, isc_uint32_t *retry, 3897 isc_uint32_t *expire, isc_uint32_t *minimum, 3898 unsigned int *errors) 3899{ 3900 isc_result_t result; 3901 isc_result_t answer = ISC_R_SUCCESS; 3902 dns_dbversion_t *version = NULL; 3903 dns_dbnode_t *node; 3904 3905 REQUIRE(db != NULL); 3906 REQUIRE(zone != NULL); 3907 3908 dns_db_currentversion(db, &version); 3909 3910 node = NULL; 3911 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); 3912 if (result != ISC_R_SUCCESS) { 3913 answer = result; 3914 goto closeversion; 3915 } 3916 3917 if (nscount != NULL || errors != NULL) { 3918 result = zone_count_ns_rr(zone, db, node, version, 3919 nscount, errors, ISC_TRUE); 3920 if (result != ISC_R_SUCCESS) 3921 answer = result; 3922 } 3923 3924 if (soacount != NULL || serial != NULL || refresh != NULL 3925 || retry != NULL || expire != NULL || minimum != NULL) { 3926 result = zone_load_soa_rr(db, node, version, soacount, 3927 serial, refresh, retry, expire, 3928 minimum); 3929 if (result != ISC_R_SUCCESS) 3930 answer = result; 3931 } 3932 3933 dns_db_detachnode(db, &node); 3934 closeversion: 3935 dns_db_closeversion(db, &version, ISC_FALSE); 3936 3937 return (answer); 3938} 3939 3940void 3941dns_zone_attach(dns_zone_t *source, dns_zone_t **target) { 3942 REQUIRE(DNS_ZONE_VALID(source)); 3943 REQUIRE(target != NULL && *target == NULL); 3944 isc_refcount_increment(&source->erefs, NULL); 3945 *target = source; 3946} 3947 3948void 3949dns_zone_detach(dns_zone_t **zonep) { 3950 dns_zone_t *zone; 3951 unsigned int refs; 3952 isc_boolean_t free_now = ISC_FALSE; 3953 3954 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 3955 3956 zone = *zonep; 3957 3958 isc_refcount_decrement(&zone->erefs, &refs); 3959 3960 if (refs == 0) { 3961 LOCK_ZONE(zone); 3962 /* 3963 * We just detached the last external reference. 3964 */ 3965 if (zone->task != NULL) { 3966 /* 3967 * This zone is being managed. Post 3968 * its control event and let it clean 3969 * up synchronously in the context of 3970 * its task. 3971 */ 3972 isc_event_t *ev = &zone->ctlevent; 3973 isc_task_send(zone->task, &ev); 3974 } else { 3975 /* 3976 * This zone is not being managed; it has 3977 * no task and can have no outstanding 3978 * events. Free it immediately. 3979 */ 3980 /* 3981 * Unmanaged zones should not have non-null views; 3982 * we have no way of detaching from the view here 3983 * without causing deadlock because this code is called 3984 * with the view already locked. 3985 */ 3986 INSIST(zone->view == NULL); 3987 free_now = ISC_TRUE; 3988 } 3989 UNLOCK_ZONE(zone); 3990 } 3991 *zonep = NULL; 3992 if (free_now) 3993 zone_free(zone); 3994} 3995 3996void 3997dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) { 3998 REQUIRE(DNS_ZONE_VALID(source)); 3999 REQUIRE(target != NULL && *target == NULL); 4000 LOCK_ZONE(source); 4001 zone_iattach(source, target); 4002 UNLOCK_ZONE(source); 4003} 4004 4005isc_result_t 4006dns_zone_synckeyzone(dns_zone_t *zone) { 4007 isc_result_t result; 4008 dns_db_t *db = NULL; 4009 4010 if (zone->type != dns_zone_key) 4011 return (DNS_R_BADZONE); 4012 4013 CHECK(dns_zone_getdb(zone, &db)); 4014 4015 LOCK_ZONE(zone); 4016 result = sync_keyzone(zone, db); 4017 UNLOCK_ZONE(zone); 4018 4019 failure: 4020 if (db != NULL) 4021 dns_db_detach(&db); 4022 return (result); 4023} 4024 4025static void 4026zone_iattach(dns_zone_t *source, dns_zone_t **target) { 4027 4028 /* 4029 * 'source' locked by caller. 4030 */ 4031 REQUIRE(LOCKED_ZONE(source)); 4032 REQUIRE(DNS_ZONE_VALID(source)); 4033 REQUIRE(target != NULL && *target == NULL); 4034 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0); 4035 source->irefs++; 4036 INSIST(source->irefs != 0); 4037 *target = source; 4038} 4039 4040static void 4041zone_idetach(dns_zone_t **zonep) { 4042 dns_zone_t *zone; 4043 4044 /* 4045 * 'zone' locked by caller. 4046 */ 4047 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 4048 zone = *zonep; 4049 REQUIRE(LOCKED_ZONE(*zonep)); 4050 *zonep = NULL; 4051 4052 INSIST(zone->irefs > 0); 4053 zone->irefs--; 4054 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0); 4055} 4056 4057void 4058dns_zone_idetach(dns_zone_t **zonep) { 4059 dns_zone_t *zone; 4060 isc_boolean_t free_needed; 4061 4062 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); 4063 zone = *zonep; 4064 *zonep = NULL; 4065 4066 LOCK_ZONE(zone); 4067 INSIST(zone->irefs > 0); 4068 zone->irefs--; 4069 free_needed = exit_check(zone); 4070 UNLOCK_ZONE(zone); 4071 if (free_needed) 4072 zone_free(zone); 4073} 4074 4075isc_mem_t * 4076dns_zone_getmctx(dns_zone_t *zone) { 4077 REQUIRE(DNS_ZONE_VALID(zone)); 4078 4079 return (zone->mctx); 4080} 4081 4082dns_zonemgr_t * 4083dns_zone_getmgr(dns_zone_t *zone) { 4084 REQUIRE(DNS_ZONE_VALID(zone)); 4085 4086 return (zone->zmgr); 4087} 4088 4089void 4090dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) { 4091 REQUIRE(DNS_ZONE_VALID(zone)); 4092 4093 LOCK_ZONE(zone); 4094 if (value) 4095 DNS_ZONE_SETFLAG(zone, flags); 4096 else 4097 DNS_ZONE_CLRFLAG(zone, flags); 4098 UNLOCK_ZONE(zone); 4099} 4100 4101void 4102dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value) 4103{ 4104 REQUIRE(DNS_ZONE_VALID(zone)); 4105 4106 LOCK_ZONE(zone); 4107 if (value) 4108 zone->options |= option; 4109 else 4110 zone->options &= ~option; 4111 UNLOCK_ZONE(zone); 4112} 4113 4114unsigned int 4115dns_zone_getoptions(dns_zone_t *zone) { 4116 4117 REQUIRE(DNS_ZONE_VALID(zone)); 4118 4119 return (zone->options); 4120} 4121 4122void 4123dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value) 4124{ 4125 REQUIRE(DNS_ZONE_VALID(zone)); 4126 4127 LOCK_ZONE(zone); 4128 if (value) 4129 zone->keyopts |= keyopt; 4130 else 4131 zone->keyopts &= ~keyopt; 4132 UNLOCK_ZONE(zone); 4133} 4134 4135unsigned int 4136dns_zone_getkeyopts(dns_zone_t *zone) { 4137 4138 REQUIRE(DNS_ZONE_VALID(zone)); 4139 4140 return (zone->keyopts); 4141} 4142 4143isc_result_t 4144dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 4145 REQUIRE(DNS_ZONE_VALID(zone)); 4146 4147 LOCK_ZONE(zone); 4148 zone->xfrsource4 = *xfrsource; 4149 UNLOCK_ZONE(zone); 4150 4151 return (ISC_R_SUCCESS); 4152} 4153 4154isc_sockaddr_t * 4155dns_zone_getxfrsource4(dns_zone_t *zone) { 4156 REQUIRE(DNS_ZONE_VALID(zone)); 4157 return (&zone->xfrsource4); 4158} 4159 4160isc_result_t 4161dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { 4162 REQUIRE(DNS_ZONE_VALID(zone)); 4163 4164 LOCK_ZONE(zone); 4165 zone->xfrsource6 = *xfrsource; 4166 UNLOCK_ZONE(zone); 4167 4168 return (ISC_R_SUCCESS); 4169} 4170 4171isc_sockaddr_t * 4172dns_zone_getxfrsource6(dns_zone_t *zone) { 4173 REQUIRE(DNS_ZONE_VALID(zone)); 4174 return (&zone->xfrsource6); 4175} 4176 4177isc_result_t 4178dns_zone_setaltxfrsource4(dns_zone_t *zone, 4179 const isc_sockaddr_t *altxfrsource) 4180{ 4181 REQUIRE(DNS_ZONE_VALID(zone)); 4182 4183 LOCK_ZONE(zone); 4184 zone->altxfrsource4 = *altxfrsource; 4185 UNLOCK_ZONE(zone); 4186 4187 return (ISC_R_SUCCESS); 4188} 4189 4190isc_sockaddr_t * 4191dns_zone_getaltxfrsource4(dns_zone_t *zone) { 4192 REQUIRE(DNS_ZONE_VALID(zone)); 4193 return (&zone->altxfrsource4); 4194} 4195 4196isc_result_t 4197dns_zone_setaltxfrsource6(dns_zone_t *zone, 4198 const isc_sockaddr_t *altxfrsource) 4199{ 4200 REQUIRE(DNS_ZONE_VALID(zone)); 4201 4202 LOCK_ZONE(zone); 4203 zone->altxfrsource6 = *altxfrsource; 4204 UNLOCK_ZONE(zone); 4205 4206 return (ISC_R_SUCCESS); 4207} 4208 4209isc_sockaddr_t * 4210dns_zone_getaltxfrsource6(dns_zone_t *zone) { 4211 REQUIRE(DNS_ZONE_VALID(zone)); 4212 return (&zone->altxfrsource6); 4213} 4214 4215isc_result_t 4216dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 4217 REQUIRE(DNS_ZONE_VALID(zone)); 4218 4219 LOCK_ZONE(zone); 4220 zone->notifysrc4 = *notifysrc; 4221 UNLOCK_ZONE(zone); 4222 4223 return (ISC_R_SUCCESS); 4224} 4225 4226isc_sockaddr_t * 4227dns_zone_getnotifysrc4(dns_zone_t *zone) { 4228 REQUIRE(DNS_ZONE_VALID(zone)); 4229 return (&zone->notifysrc4); 4230} 4231 4232isc_result_t 4233dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { 4234 REQUIRE(DNS_ZONE_VALID(zone)); 4235 4236 LOCK_ZONE(zone); 4237 zone->notifysrc6 = *notifysrc; 4238 UNLOCK_ZONE(zone); 4239 4240 return (ISC_R_SUCCESS); 4241} 4242 4243isc_sockaddr_t * 4244dns_zone_getnotifysrc6(dns_zone_t *zone) { 4245 REQUIRE(DNS_ZONE_VALID(zone)); 4246 return (&zone->notifysrc6); 4247} 4248 4249isc_result_t 4250dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, 4251 isc_uint32_t count) 4252{ 4253 isc_sockaddr_t *new; 4254 4255 REQUIRE(DNS_ZONE_VALID(zone)); 4256 REQUIRE(count == 0 || notify != NULL); 4257 4258 LOCK_ZONE(zone); 4259 if (zone->notify != NULL) { 4260 isc_mem_put(zone->mctx, zone->notify, 4261 zone->notifycnt * sizeof(*new)); 4262 zone->notify = NULL; 4263 zone->notifycnt = 0; 4264 } 4265 if (count != 0) { 4266 new = isc_mem_get(zone->mctx, count * sizeof(*new)); 4267 if (new == NULL) { 4268 UNLOCK_ZONE(zone); 4269 return (ISC_R_NOMEMORY); 4270 } 4271 memcpy(new, notify, count * sizeof(*new)); 4272 zone->notify = new; 4273 zone->notifycnt = count; 4274 } 4275 UNLOCK_ZONE(zone); 4276 return (ISC_R_SUCCESS); 4277} 4278 4279isc_result_t 4280dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters, 4281 isc_uint32_t count) 4282{ 4283 isc_result_t result; 4284 4285 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count); 4286 return (result); 4287} 4288 4289static isc_boolean_t 4290same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new, 4291 isc_uint32_t count) 4292{ 4293 unsigned int i; 4294 4295 for (i = 0; i < count; i++) 4296 if (!isc_sockaddr_equal(&old[i], &new[i])) 4297 return (ISC_FALSE); 4298 return (ISC_TRUE); 4299} 4300 4301static isc_boolean_t 4302same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) { 4303 unsigned int i; 4304 4305 if (old == NULL && new == NULL) 4306 return (ISC_TRUE); 4307 if (old == NULL || new == NULL) 4308 return (ISC_FALSE); 4309 4310 for (i = 0; i < count; i++) { 4311 if (old[i] == NULL && new[i] == NULL) 4312 continue; 4313 if (old[i] == NULL || new[i] == NULL || 4314 !dns_name_equal(old[i], new[i])) 4315 return (ISC_FALSE); 4316 } 4317 return (ISC_TRUE); 4318} 4319 4320isc_result_t 4321dns_zone_setmasterswithkeys(dns_zone_t *zone, 4322 const isc_sockaddr_t *masters, 4323 dns_name_t **keynames, 4324 isc_uint32_t count) 4325{ 4326 isc_sockaddr_t *new; 4327 isc_result_t result = ISC_R_SUCCESS; 4328 dns_name_t **newname; 4329 isc_boolean_t *newok; 4330 unsigned int i; 4331 4332 REQUIRE(DNS_ZONE_VALID(zone)); 4333 REQUIRE(count == 0 || masters != NULL); 4334 if (keynames != NULL) { 4335 REQUIRE(count != 0); 4336 } 4337 4338 LOCK_ZONE(zone); 4339 /* 4340 * The refresh code assumes that 'masters' wouldn't change under it. 4341 * If it will change then kill off any current refresh in progress 4342 * and update the masters info. If it won't change then we can just 4343 * unlock and exit. 4344 */ 4345 if (count != zone->masterscnt || 4346 !same_masters(zone->masters, masters, count) || 4347 !same_keynames(zone->masterkeynames, keynames, count)) { 4348 if (zone->request != NULL) 4349 dns_request_cancel(zone->request); 4350 } else 4351 goto unlock; 4352 if (zone->masters != NULL) { 4353 isc_mem_put(zone->mctx, zone->masters, 4354 zone->masterscnt * sizeof(*new)); 4355 zone->masters = NULL; 4356 } 4357 if (zone->masterkeynames != NULL) { 4358 for (i = 0; i < zone->masterscnt; i++) { 4359 if (zone->masterkeynames[i] != NULL) { 4360 dns_name_free(zone->masterkeynames[i], 4361 zone->mctx); 4362 isc_mem_put(zone->mctx, 4363 zone->masterkeynames[i], 4364 sizeof(dns_name_t)); 4365 zone->masterkeynames[i] = NULL; 4366 } 4367 } 4368 isc_mem_put(zone->mctx, zone->masterkeynames, 4369 zone->masterscnt * sizeof(dns_name_t *)); 4370 zone->masterkeynames = NULL; 4371 } 4372 if (zone->mastersok != NULL) { 4373 isc_mem_put(zone->mctx, zone->mastersok, 4374 zone->masterscnt * sizeof(isc_boolean_t)); 4375 zone->mastersok = NULL; 4376 } 4377 zone->masterscnt = 0; 4378 /* 4379 * If count == 0, don't allocate any space for masters, mastersok or 4380 * keynames so internally, those pointers are NULL if count == 0 4381 */ 4382 if (count == 0) 4383 goto unlock; 4384 4385 /* 4386 * masters must contain count elements! 4387 */ 4388 new = isc_mem_get(zone->mctx, count * sizeof(*new)); 4389 if (new == NULL) { 4390 result = ISC_R_NOMEMORY; 4391 goto unlock; 4392 } 4393 memcpy(new, masters, count * sizeof(*new)); 4394 4395 /* 4396 * Similarly for mastersok. 4397 */ 4398 newok = isc_mem_get(zone->mctx, count * sizeof(*newok)); 4399 if (newok == NULL) { 4400 result = ISC_R_NOMEMORY; 4401 isc_mem_put(zone->mctx, new, count * sizeof(*new)); 4402 goto unlock; 4403 }; 4404 for (i = 0; i < count; i++) 4405 newok[i] = ISC_FALSE; 4406 4407 /* 4408 * if keynames is non-NULL, it must contain count elements! 4409 */ 4410 newname = NULL; 4411 if (keynames != NULL) { 4412 newname = isc_mem_get(zone->mctx, count * sizeof(*newname)); 4413 if (newname == NULL) { 4414 result = ISC_R_NOMEMORY; 4415 isc_mem_put(zone->mctx, new, count * sizeof(*new)); 4416 isc_mem_put(zone->mctx, newok, count * sizeof(*newok)); 4417 goto unlock; 4418 } 4419 for (i = 0; i < count; i++) 4420 newname[i] = NULL; 4421 for (i = 0; i < count; i++) { 4422 if (keynames[i] != NULL) { 4423 newname[i] = isc_mem_get(zone->mctx, 4424 sizeof(dns_name_t)); 4425 if (newname[i] == NULL) 4426 goto allocfail; 4427 dns_name_init(newname[i], NULL); 4428 result = dns_name_dup(keynames[i], zone->mctx, 4429 newname[i]); 4430 if (result != ISC_R_SUCCESS) { 4431 allocfail: 4432 for (i = 0; i < count; i++) 4433 if (newname[i] != NULL) 4434 dns_name_free( 4435 newname[i], 4436 zone->mctx); 4437 isc_mem_put(zone->mctx, new, 4438 count * sizeof(*new)); 4439 isc_mem_put(zone->mctx, newok, 4440 count * sizeof(*newok)); 4441 isc_mem_put(zone->mctx, newname, 4442 count * sizeof(*newname)); 4443 goto unlock; 4444 } 4445 } 4446 } 4447 } 4448 4449 /* 4450 * Everything is ok so attach to the zone. 4451 */ 4452 zone->curmaster = 0; 4453 zone->masters = new; 4454 zone->mastersok = newok; 4455 zone->masterkeynames = newname; 4456 zone->masterscnt = count; 4457 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS); 4458 4459 unlock: 4460 UNLOCK_ZONE(zone); 4461 return (result); 4462} 4463 4464isc_result_t 4465dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) { 4466 isc_result_t result = ISC_R_SUCCESS; 4467 4468 REQUIRE(DNS_ZONE_VALID(zone)); 4469 4470 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 4471 if (zone->db == NULL) 4472 result = DNS_R_NOTLOADED; 4473 else 4474 dns_db_attach(zone->db, dpb); 4475 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 4476 4477 return (result); 4478} 4479 4480void 4481dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) { 4482 REQUIRE(DNS_ZONE_VALID(zone)); 4483 REQUIRE(zone->type == dns_zone_staticstub); 4484 4485 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 4486 REQUIRE(zone->db == NULL); 4487 dns_db_attach(db, &zone->db); 4488 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 4489} 4490 4491/* 4492 * Co-ordinates the starting of routine jobs. 4493 */ 4494 4495void 4496dns_zone_maintenance(dns_zone_t *zone) { 4497 const char me[] = "dns_zone_maintenance"; 4498 isc_time_t now; 4499 4500 REQUIRE(DNS_ZONE_VALID(zone)); 4501 ENTER; 4502 4503 LOCK_ZONE(zone); 4504 TIME_NOW(&now); 4505 zone_settimer(zone, &now); 4506 UNLOCK_ZONE(zone); 4507} 4508 4509static inline isc_boolean_t 4510was_dumping(dns_zone_t *zone) { 4511 isc_boolean_t dumping; 4512 4513 REQUIRE(LOCKED_ZONE(zone)); 4514 4515 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING); 4516 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 4517 if (!dumping) { 4518 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 4519 isc_time_settoepoch(&zone->dumptime); 4520 } 4521 return (dumping); 4522} 4523 4524static isc_result_t 4525find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 4526 isc_mem_t *mctx, unsigned int maxkeys, 4527 dst_key_t **keys, unsigned int *nkeys) 4528{ 4529 isc_result_t result; 4530 dns_dbnode_t *node = NULL; 4531 const char *directory = dns_zone_getkeydirectory(zone); 4532 4533 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); 4534 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db), 4535 directory, mctx, maxkeys, keys, 4536 nkeys); 4537 if (result == ISC_R_NOTFOUND) 4538 result = ISC_R_SUCCESS; 4539 failure: 4540 if (node != NULL) 4541 dns_db_detachnode(db, &node); 4542 return (result); 4543} 4544 4545static isc_result_t 4546offline(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name, 4547 dns_ttl_t ttl, dns_rdata_t *rdata) 4548{ 4549 isc_result_t result; 4550 4551 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) 4552 return (ISC_R_SUCCESS); 4553 result = update_one_rr(db, ver, diff, DNS_DIFFOP_DELRESIGN, 4554 name, ttl, rdata); 4555 if (result != ISC_R_SUCCESS) 4556 return (result); 4557 rdata->flags |= DNS_RDATA_OFFLINE; 4558 result = update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, 4559 name, ttl, rdata); 4560 return (result); 4561} 4562 4563static void 4564set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now) 4565{ 4566 unsigned int delta; 4567 char timebuf[80]; 4568 4569 zone->key_expiry = when; 4570 if (when <= now) { 4571 dns_zone_log(zone, ISC_LOG_ERROR, 4572 "DNSKEY RRSIG(s) have expired"); 4573 isc_time_settoepoch(&zone->keywarntime); 4574 } else if (when < now + 7 * 24 * 3600) { 4575 isc_time_t t; 4576 isc_time_set(&t, when, 0); 4577 isc_time_formattimestamp(&t, timebuf, 80); 4578 dns_zone_log(zone, ISC_LOG_WARNING, 4579 "DNSKEY RRSIG(s) will expire within 7 days: %s", 4580 timebuf); 4581 delta = when - now; 4582 delta--; /* loop prevention */ 4583 delta /= 24 * 3600; /* to whole days */ 4584 delta *= 24 * 3600; /* to seconds */ 4585 isc_time_set(&zone->keywarntime, when - delta, 0); 4586 } else { 4587 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0); 4588 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 4589 dns_zone_log(zone, ISC_LOG_NOTICE, 4590 "setting keywarntime to %s", timebuf); 4591 } 4592} 4593 4594/* 4595 * Helper function to del_sigs(). We don't want to delete RRSIGs that 4596 * have no new key. 4597 */ 4598static isc_boolean_t 4599delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys) { 4600 unsigned int i = 0; 4601 4602 /* 4603 * It's okay to delete a signature if there is an active ZSK 4604 * with the same algorithm 4605 */ 4606 for (i = 0; i < nkeys; i++) { 4607 if (rrsig_ptr->algorithm == dst_key_alg(keys[i]) && 4608 (dst_key_isprivate(keys[i])) && !KSK(keys[i])) 4609 return (ISC_TRUE); 4610 } 4611 4612 /* 4613 * Failing that, it is *not* okay to delete a signature 4614 * if the associated public key is still in the DNSKEY RRset 4615 */ 4616 for (i = 0; i < nkeys; i++) { 4617 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) && 4618 (rrsig_ptr->keyid == dst_key_id(keys[i]))) 4619 return (ISC_FALSE); 4620 } 4621 4622 /* 4623 * But if the key is gone, then go ahead. 4624 */ 4625 return (ISC_TRUE); 4626} 4627 4628/* 4629 * Delete expired RRsigs and any RRsigs we are about to re-sign. 4630 * See also update.c:del_keysigs(). 4631 */ 4632static isc_result_t 4633del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 4634 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, 4635 unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental) 4636{ 4637 isc_result_t result; 4638 dns_dbnode_t *node = NULL; 4639 dns_rdataset_t rdataset; 4640 unsigned int i; 4641 dns_rdata_rrsig_t rrsig; 4642 isc_boolean_t found, changed; 4643 isc_int64_t warn = 0, maybe = 0; 4644 4645 dns_rdataset_init(&rdataset); 4646 4647 if (type == dns_rdatatype_nsec3) 4648 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node); 4649 else 4650 result = dns_db_findnode(db, name, ISC_FALSE, &node); 4651 if (result == ISC_R_NOTFOUND) 4652 return (ISC_R_SUCCESS); 4653 if (result != ISC_R_SUCCESS) 4654 goto failure; 4655 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type, 4656 (isc_stdtime_t) 0, &rdataset, NULL); 4657 dns_db_detachnode(db, &node); 4658 4659 if (result == ISC_R_NOTFOUND) { 4660 INSIST(!dns_rdataset_isassociated(&rdataset)); 4661 return (ISC_R_SUCCESS); 4662 } 4663 if (result != ISC_R_SUCCESS) { 4664 INSIST(!dns_rdataset_isassociated(&rdataset)); 4665 goto failure; 4666 } 4667 4668 changed = ISC_FALSE; 4669 for (result = dns_rdataset_first(&rdataset); 4670 result == ISC_R_SUCCESS; 4671 result = dns_rdataset_next(&rdataset)) { 4672 dns_rdata_t rdata = DNS_RDATA_INIT; 4673 4674 dns_rdataset_current(&rdataset, &rdata); 4675 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 4676 RUNTIME_CHECK(result == ISC_R_SUCCESS); 4677 4678 if (type != dns_rdatatype_dnskey) { 4679 if (delsig_ok(&rrsig, keys, nkeys)) { 4680 result = update_one_rr(db, ver, diff, 4681 DNS_DIFFOP_DELRESIGN, name, 4682 rdataset.ttl, &rdata); 4683 if (incremental) 4684 changed = ISC_TRUE; 4685 if (result != ISC_R_SUCCESS) 4686 break; 4687 } else { 4688 /* 4689 * At this point, we've got an RRSIG, 4690 * which is signed by an inactive key. 4691 * An administrator needs to provide a new 4692 * key/alg, but until that time, we want to 4693 * keep the old RRSIG. Marking the key as 4694 * offline will prevent us spinning waiting 4695 * for the private part. 4696 */ 4697 if (incremental) { 4698 result = offline(db, ver, diff, name, 4699 rdataset.ttl, &rdata); 4700 changed = ISC_TRUE; 4701 if (result != ISC_R_SUCCESS) 4702 break; 4703 } 4704 4705 /* 4706 * Log the key id and algorithm of 4707 * the inactive key with no replacement 4708 */ 4709 if (zone->log_key_expired_timer <= now) { 4710 char origin[DNS_NAME_FORMATSIZE]; 4711 char algbuf[DNS_NAME_FORMATSIZE]; 4712 dns_name_format(&zone->origin, origin, 4713 sizeof(origin)); 4714 dns_secalg_format(rrsig.algorithm, 4715 algbuf, 4716 sizeof(algbuf)); 4717 dns_zone_log(zone, ISC_LOG_WARNING, 4718 "Key %s/%s/%d " 4719 "missing or inactive " 4720 "and has no replacement: " 4721 "retaining signatures.", 4722 origin, algbuf, 4723 rrsig.keyid); 4724 zone->log_key_expired_timer = now + 4725 3600; 4726 } 4727 } 4728 continue; 4729 } 4730 4731 /* 4732 * RRSIG(DNSKEY) requires special processing. 4733 */ 4734 found = ISC_FALSE; 4735 for (i = 0; i < nkeys; i++) { 4736 if (rrsig.algorithm == dst_key_alg(keys[i]) && 4737 rrsig.keyid == dst_key_id(keys[i])) { 4738 found = ISC_TRUE; 4739 /* 4740 * Mark offline RRSIG(DNSKEY). 4741 * We want the earliest offline expire time 4742 * iff there is a new offline signature. 4743 */ 4744 if (!dst_key_isprivate(keys[i])) { 4745 isc_int64_t timeexpire = 4746 dns_time64_from32(rrsig.timeexpire); 4747 if (warn != 0 && warn > timeexpire) 4748 warn = timeexpire; 4749 if (rdata.flags & DNS_RDATA_OFFLINE) { 4750 if (maybe == 0 || 4751 maybe > timeexpire) 4752 maybe = timeexpire; 4753 break; 4754 } 4755 if (warn == 0) 4756 warn = maybe; 4757 if (warn == 0 || warn > timeexpire) 4758 warn = timeexpire; 4759 result = offline(db, ver, diff, name, 4760 rdataset.ttl, &rdata); 4761 break; 4762 } 4763 result = update_one_rr(db, ver, diff, 4764 DNS_DIFFOP_DELRESIGN, 4765 name, rdataset.ttl, 4766 &rdata); 4767 break; 4768 } 4769 } 4770 4771 /* 4772 * If there is not a matching DNSKEY then 4773 * delete the RRSIG. 4774 */ 4775 if (!found) 4776 result = update_one_rr(db, ver, diff, 4777 DNS_DIFFOP_DELRESIGN, name, 4778 rdataset.ttl, &rdata); 4779 if (result != ISC_R_SUCCESS) 4780 break; 4781 } 4782 4783 if (changed && (rdataset.attributes & DNS_RDATASETATTR_RESIGN) != 0) 4784 dns_db_resigned(db, &rdataset, ver); 4785 4786 dns_rdataset_disassociate(&rdataset); 4787 if (result == ISC_R_NOMORE) 4788 result = ISC_R_SUCCESS; 4789 if (warn > 0) { 4790#if defined(STDTIME_ON_32BITS) 4791 isc_stdtime_t stdwarn = (isc_stdtime_t)warn; 4792 if (warn == stdwarn) 4793#endif 4794 set_key_expiry_warning(zone, (isc_stdtime_t)warn, now); 4795#if defined(STDTIME_ON_32BITS) 4796 else 4797 dns_zone_log(zone, ISC_LOG_ERROR, 4798 "key expiry warning time out of range"); 4799#endif 4800 } 4801 failure: 4802 if (node != NULL) 4803 dns_db_detachnode(db, &node); 4804 return (result); 4805} 4806 4807static isc_result_t 4808add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 4809 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, 4810 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception, 4811 isc_stdtime_t expire, isc_boolean_t check_ksk, 4812 isc_boolean_t keyset_kskonly) 4813{ 4814 isc_result_t result; 4815 dns_dbnode_t *node = NULL; 4816 dns_rdataset_t rdataset; 4817 dns_rdata_t sig_rdata = DNS_RDATA_INIT; 4818 unsigned char data[1024]; /* XXX */ 4819 isc_buffer_t buffer; 4820 unsigned int i, j; 4821 4822 dns_rdataset_init(&rdataset); 4823 isc_buffer_init(&buffer, data, sizeof(data)); 4824 4825 if (type == dns_rdatatype_nsec3) 4826 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node); 4827 else 4828 result = dns_db_findnode(db, name, ISC_FALSE, &node); 4829 if (result == ISC_R_NOTFOUND) 4830 return (ISC_R_SUCCESS); 4831 if (result != ISC_R_SUCCESS) 4832 goto failure; 4833 result = dns_db_findrdataset(db, node, ver, type, 0, 4834 (isc_stdtime_t) 0, &rdataset, NULL); 4835 dns_db_detachnode(db, &node); 4836 if (result == ISC_R_NOTFOUND) { 4837 INSIST(!dns_rdataset_isassociated(&rdataset)); 4838 return (ISC_R_SUCCESS); 4839 } 4840 if (result != ISC_R_SUCCESS) { 4841 INSIST(!dns_rdataset_isassociated(&rdataset)); 4842 goto failure; 4843 } 4844 4845 for (i = 0; i < nkeys; i++) { 4846 isc_boolean_t both = ISC_FALSE; 4847 4848 if (!dst_key_isprivate(keys[i])) 4849 continue; 4850 4851 if (check_ksk && !REVOKE(keys[i])) { 4852 isc_boolean_t have_ksk, have_nonksk; 4853 if (KSK(keys[i])) { 4854 have_ksk = ISC_TRUE; 4855 have_nonksk = ISC_FALSE; 4856 } else { 4857 have_ksk = ISC_FALSE; 4858 have_nonksk = ISC_TRUE; 4859 } 4860 for (j = 0; j < nkeys; j++) { 4861 if (j == i || ALG(keys[i]) != ALG(keys[j])) 4862 continue; 4863 if (REVOKE(keys[j])) 4864 continue; 4865 if (KSK(keys[j])) 4866 have_ksk = ISC_TRUE; 4867 else 4868 have_nonksk = ISC_TRUE; 4869 both = have_ksk && have_nonksk; 4870 if (both) 4871 break; 4872 } 4873 } 4874 if (both) { 4875 if (type == dns_rdatatype_dnskey) { 4876 if (!KSK(keys[i]) && keyset_kskonly) 4877 continue; 4878 } else if (KSK(keys[i])) 4879 continue; 4880 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) 4881 continue; 4882 4883 /* Calculate the signature, creating a RRSIG RDATA. */ 4884 isc_buffer_clear(&buffer); 4885 CHECK(dns_dnssec_sign(name, &rdataset, keys[i], 4886 &inception, &expire, 4887 mctx, &buffer, &sig_rdata)); 4888 /* Update the database and journal with the RRSIG. */ 4889 /* XXX inefficient - will cause dataset merging */ 4890 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, 4891 name, rdataset.ttl, &sig_rdata)); 4892 dns_rdata_reset(&sig_rdata); 4893 isc_buffer_init(&buffer, data, sizeof(data)); 4894 } 4895 4896 failure: 4897 if (dns_rdataset_isassociated(&rdataset)) 4898 dns_rdataset_disassociate(&rdataset); 4899 if (node != NULL) 4900 dns_db_detachnode(db, &node); 4901 return (result); 4902} 4903 4904static void 4905zone_resigninc(dns_zone_t *zone) { 4906 dns_db_t *db = NULL; 4907 dns_dbversion_t *version = NULL; 4908 dns_diff_t sig_diff; 4909 dns_fixedname_t fixed; 4910 dns_name_t *name; 4911 dns_rdataset_t rdataset; 4912 dns_rdatatype_t covers; 4913 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 4914 isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE; 4915 isc_result_t result; 4916 isc_stdtime_t now, inception, soaexpire, expire, stop; 4917 isc_uint32_t jitter; 4918 unsigned int i; 4919 unsigned int nkeys = 0; 4920 unsigned int resign; 4921 4922 dns_rdataset_init(&rdataset); 4923 dns_fixedname_init(&fixed); 4924 dns_diff_init(zone->mctx, &sig_diff); 4925 sig_diff.resign = zone->sigresigninginterval; 4926 4927 /* 4928 * Updates are disabled. Pause for 5 minutes. 4929 */ 4930 if (zone->update_disabled) { 4931 result = ISC_R_FAILURE; 4932 goto failure; 4933 } 4934 4935 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 4936 dns_db_attach(zone->db, &db); 4937 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 4938 4939 result = dns_db_newversion(db, &version); 4940 if (result != ISC_R_SUCCESS) { 4941 dns_zone_log(zone, ISC_LOG_ERROR, 4942 "zone_resigninc:dns_db_newversion -> %s\n", 4943 dns_result_totext(result)); 4944 goto failure; 4945 } 4946 4947 result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS, 4948 zone_keys, &nkeys); 4949 if (result != ISC_R_SUCCESS) { 4950 dns_zone_log(zone, ISC_LOG_ERROR, 4951 "zone_resigninc:find_zone_keys -> %s\n", 4952 dns_result_totext(result)); 4953 goto failure; 4954 } 4955 4956 isc_stdtime_get(&now); 4957 inception = now - 3600; /* Allow for clock skew. */ 4958 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 4959 /* 4960 * Spread out signatures over time if they happen to be 4961 * clumped. We don't do this for each add_sigs() call as 4962 * we still want some clustering to occur. 4963 */ 4964 isc_random_get(&jitter); 4965 expire = soaexpire - jitter % 3600; 4966 stop = now + 5; 4967 4968 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 4969 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 4970 4971 name = dns_fixedname_name(&fixed); 4972 result = dns_db_getsigningtime(db, &rdataset, name); 4973 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 4974 dns_zone_log(zone, ISC_LOG_ERROR, 4975 "zone_resigninc:dns_db_getsigningtime -> %s\n", 4976 dns_result_totext(result)); 4977 } 4978 4979 i = 0; 4980 while (result == ISC_R_SUCCESS) { 4981 resign = rdataset.resign; 4982 covers = rdataset.covers; 4983 dns_rdataset_disassociate(&rdataset); 4984 4985 /* 4986 * Stop if we hit the SOA as that means we have walked the 4987 * entire zone. The SOA record should always be the most 4988 * recent signature. 4989 */ 4990 /* XXXMPA increase number of RRsets signed pre call */ 4991 if (covers == dns_rdatatype_soa || i++ > zone->signatures || 4992 resign > stop) 4993 break; 4994 4995 result = del_sigs(zone, db, version, name, covers, &sig_diff, 4996 zone_keys, nkeys, now, ISC_TRUE); 4997 if (result != ISC_R_SUCCESS) { 4998 dns_zone_log(zone, ISC_LOG_ERROR, 4999 "zone_resigninc:del_sigs -> %s\n", 5000 dns_result_totext(result)); 5001 break; 5002 } 5003 5004 result = add_sigs(db, version, name, covers, &sig_diff, 5005 zone_keys, nkeys, zone->mctx, inception, 5006 expire, check_ksk, keyset_kskonly); 5007 if (result != ISC_R_SUCCESS) { 5008 dns_zone_log(zone, ISC_LOG_ERROR, 5009 "zone_resigninc:add_sigs -> %s\n", 5010 dns_result_totext(result)); 5011 break; 5012 } 5013 result = dns_db_getsigningtime(db, &rdataset, 5014 dns_fixedname_name(&fixed)); 5015 if (nkeys == 0 && result == ISC_R_NOTFOUND) { 5016 result = ISC_R_SUCCESS; 5017 break; 5018 } 5019 if (result != ISC_R_SUCCESS) 5020 dns_zone_log(zone, ISC_LOG_ERROR, 5021 "zone_resigninc:dns_db_getsigningtime -> %s\n", 5022 dns_result_totext(result)); 5023 } 5024 5025 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS) 5026 goto failure; 5027 5028 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 5029 &sig_diff, zone_keys, nkeys, now, ISC_TRUE); 5030 if (result != ISC_R_SUCCESS) { 5031 dns_zone_log(zone, ISC_LOG_ERROR, 5032 "zone_resigninc:del_sigs -> %s\n", 5033 dns_result_totext(result)); 5034 goto failure; 5035 } 5036 5037 /* 5038 * Did we change anything in the zone? 5039 */ 5040 if (ISC_LIST_EMPTY(sig_diff.tuples)) 5041 goto failure; 5042 5043 /* Increment SOA serial if we have made changes */ 5044 result = increment_soa_serial(db, version, &sig_diff, zone->mctx); 5045 if (result != ISC_R_SUCCESS) { 5046 dns_zone_log(zone, ISC_LOG_ERROR, 5047 "zone_resigninc:increment_soa_serial -> %s\n", 5048 dns_result_totext(result)); 5049 goto failure; 5050 } 5051 5052 /* 5053 * Generate maximum life time signatures so that the above loop 5054 * termination is sensible. 5055 */ 5056 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, 5057 &sig_diff, zone_keys, nkeys, zone->mctx, inception, 5058 soaexpire, check_ksk, keyset_kskonly); 5059 if (result != ISC_R_SUCCESS) { 5060 dns_zone_log(zone, ISC_LOG_ERROR, 5061 "zone_resigninc:add_sigs -> %s\n", 5062 dns_result_totext(result)); 5063 goto failure; 5064 } 5065 5066 /* Write changes to journal file. */ 5067 CHECK(zone_journal(zone, &sig_diff, "zone_resigninc")); 5068 5069 /* Everything has succeeded. Commit the changes. */ 5070 dns_db_closeversion(db, &version, ISC_TRUE); 5071 5072 failure: 5073 dns_diff_clear(&sig_diff); 5074 for (i = 0; i < nkeys; i++) 5075 dst_key_free(&zone_keys[i]); 5076 if (version != NULL) { 5077 dns_db_closeversion(zone->db, &version, ISC_FALSE); 5078 dns_db_detach(&db); 5079 } else if (db != NULL) 5080 dns_db_detach(&db); 5081 if (result == ISC_R_SUCCESS) { 5082 set_resigntime(zone); 5083 LOCK_ZONE(zone); 5084 zone_needdump(zone, DNS_DUMP_DELAY); 5085 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 5086 UNLOCK_ZONE(zone); 5087 } else { 5088 /* 5089 * Something failed. Retry in 5 minutes. 5090 */ 5091 isc_interval_t ival; 5092 isc_interval_set(&ival, 300, 0); 5093 isc_time_nowplusinterval(&zone->resigntime, &ival); 5094 } 5095} 5096 5097static isc_result_t 5098next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname, 5099 dns_name_t *newname, isc_boolean_t bottom) 5100{ 5101 isc_result_t result; 5102 dns_dbiterator_t *dbit = NULL; 5103 dns_rdatasetiter_t *rdsit = NULL; 5104 dns_dbnode_t *node = NULL; 5105 5106 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit)); 5107 CHECK(dns_dbiterator_seek(dbit, oldname)); 5108 do { 5109 result = dns_dbiterator_next(dbit); 5110 if (result == ISC_R_NOMORE) 5111 CHECK(dns_dbiterator_first(dbit)); 5112 CHECK(dns_dbiterator_current(dbit, &node, newname)); 5113 if (bottom && dns_name_issubdomain(newname, oldname) && 5114 !dns_name_equal(newname, oldname)) { 5115 dns_db_detachnode(db, &node); 5116 continue; 5117 } 5118 /* 5119 * Is this node empty? 5120 */ 5121 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit)); 5122 result = dns_rdatasetiter_first(rdsit); 5123 dns_db_detachnode(db, &node); 5124 dns_rdatasetiter_destroy(&rdsit); 5125 if (result != ISC_R_NOMORE) 5126 break; 5127 } while (1); 5128 failure: 5129 if (node != NULL) 5130 dns_db_detachnode(db, &node); 5131 if (dbit != NULL) 5132 dns_dbiterator_destroy(&dbit); 5133 return (result); 5134} 5135 5136static isc_boolean_t 5137signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, 5138 dns_rdatatype_t type, dst_key_t *key) 5139{ 5140 isc_result_t result; 5141 dns_rdataset_t rdataset; 5142 dns_rdata_t rdata = DNS_RDATA_INIT; 5143 dns_rdata_rrsig_t rrsig; 5144 5145 dns_rdataset_init(&rdataset); 5146 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig, 5147 type, 0, &rdataset, NULL); 5148 if (result != ISC_R_SUCCESS) { 5149 INSIST(!dns_rdataset_isassociated(&rdataset)); 5150 return (ISC_FALSE); 5151 } 5152 for (result = dns_rdataset_first(&rdataset); 5153 result == ISC_R_SUCCESS; 5154 result = dns_rdataset_next(&rdataset)) { 5155 dns_rdataset_current(&rdataset, &rdata); 5156 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 5157 INSIST(result == ISC_R_SUCCESS); 5158 if (rrsig.algorithm == dst_key_alg(key) && 5159 rrsig.keyid == dst_key_id(key)) { 5160 dns_rdataset_disassociate(&rdataset); 5161 return (ISC_TRUE); 5162 } 5163 dns_rdata_reset(&rdata); 5164 } 5165 dns_rdataset_disassociate(&rdataset); 5166 return (ISC_FALSE); 5167} 5168 5169static isc_result_t 5170add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 5171 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom, 5172 dns_diff_t *diff) 5173{ 5174 dns_fixedname_t fixed; 5175 dns_name_t *next; 5176 dns_rdata_t rdata = DNS_RDATA_INIT; 5177 isc_result_t result; 5178 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE]; 5179 5180 dns_fixedname_init(&fixed); 5181 next = dns_fixedname_name(&fixed); 5182 5183 CHECK(next_active(db, version, name, next, bottom)); 5184 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer, 5185 &rdata)); 5186 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl, 5187 &rdata)); 5188 failure: 5189 return (result); 5190} 5191 5192static isc_result_t 5193sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node, 5194 dns_dbversion_t *version, isc_boolean_t build_nsec3, 5195 isc_boolean_t build_nsec, dst_key_t *key, 5196 isc_stdtime_t inception, isc_stdtime_t expire, 5197 unsigned int minimum, isc_boolean_t is_ksk, 5198 isc_boolean_t keyset_kskonly, isc_boolean_t *delegation, 5199 dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx) 5200{ 5201 isc_result_t result; 5202 dns_rdatasetiter_t *iterator = NULL; 5203 dns_rdataset_t rdataset; 5204 dns_rdata_t rdata = DNS_RDATA_INIT; 5205 isc_buffer_t buffer; 5206 unsigned char data[1024]; 5207 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec, 5208 seen_nsec3, seen_ds; 5209 isc_boolean_t bottom; 5210 5211 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 5212 if (result != ISC_R_SUCCESS) { 5213 if (result == ISC_R_NOTFOUND) 5214 result = ISC_R_SUCCESS; 5215 return (result); 5216 } 5217 5218 dns_rdataset_init(&rdataset); 5219 isc_buffer_init(&buffer, data, sizeof(data)); 5220 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec = 5221 seen_nsec3 = seen_ds = ISC_FALSE; 5222 for (result = dns_rdatasetiter_first(iterator); 5223 result == ISC_R_SUCCESS; 5224 result = dns_rdatasetiter_next(iterator)) { 5225 dns_rdatasetiter_current(iterator, &rdataset); 5226 if (rdataset.type == dns_rdatatype_soa) 5227 seen_soa = ISC_TRUE; 5228 else if (rdataset.type == dns_rdatatype_ns) 5229 seen_ns = ISC_TRUE; 5230 else if (rdataset.type == dns_rdatatype_ds) 5231 seen_ds = ISC_TRUE; 5232 else if (rdataset.type == dns_rdatatype_dname) 5233 seen_dname = ISC_TRUE; 5234 else if (rdataset.type == dns_rdatatype_nsec) 5235 seen_nsec = ISC_TRUE; 5236 else if (rdataset.type == dns_rdatatype_nsec3) 5237 seen_nsec3 = ISC_TRUE; 5238 if (rdataset.type != dns_rdatatype_rrsig) 5239 seen_rr = ISC_TRUE; 5240 dns_rdataset_disassociate(&rdataset); 5241 } 5242 if (result != ISC_R_NOMORE) 5243 goto failure; 5244 if (seen_ns && !seen_soa) 5245 *delegation = ISC_TRUE; 5246 /* 5247 * Going from insecure to NSEC3. 5248 * Don't generate NSEC3 records for NSEC3 records. 5249 */ 5250 if (build_nsec3 && !seen_nsec3 && seen_rr) { 5251 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa; 5252 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum, 5253 unsecure, diff)); 5254 (*signatures)--; 5255 } 5256 /* 5257 * Going from insecure to NSEC. 5258 * Don't generate NSEC records for NSEC3 records. 5259 */ 5260 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) { 5261 /* Build and add NSEC. */ 5262 bottom = (seen_ns && !seen_soa) || seen_dname; 5263 /* 5264 * Build a NSEC record except at the origin. 5265 */ 5266 if (!dns_name_equal(name, dns_db_origin(db))) { 5267 CHECK(add_nsec(db, version, name, node, minimum, 5268 bottom, diff)); 5269 /* Count a NSEC generation as a signature generation. */ 5270 (*signatures)--; 5271 } 5272 } 5273 result = dns_rdatasetiter_first(iterator); 5274 while (result == ISC_R_SUCCESS) { 5275 dns_rdatasetiter_current(iterator, &rdataset); 5276 if (rdataset.type == dns_rdatatype_soa || 5277 rdataset.type == dns_rdatatype_rrsig) 5278 goto next_rdataset; 5279 if (rdataset.type == dns_rdatatype_dnskey) { 5280 if (!is_ksk && keyset_kskonly) 5281 goto next_rdataset; 5282 } else if (is_ksk) 5283 goto next_rdataset; 5284 if (*delegation && 5285 rdataset.type != dns_rdatatype_ds && 5286 rdataset.type != dns_rdatatype_nsec) 5287 goto next_rdataset; 5288 if (signed_with_key(db, node, version, rdataset.type, key)) 5289 goto next_rdataset; 5290 /* Calculate the signature, creating a RRSIG RDATA. */ 5291 isc_buffer_clear(&buffer); 5292 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception, 5293 &expire, mctx, &buffer, &rdata)); 5294 /* Update the database and journal with the RRSIG. */ 5295 /* XXX inefficient - will cause dataset merging */ 5296 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN, 5297 name, rdataset.ttl, &rdata)); 5298 dns_rdata_reset(&rdata); 5299 (*signatures)--; 5300 next_rdataset: 5301 dns_rdataset_disassociate(&rdataset); 5302 result = dns_rdatasetiter_next(iterator); 5303 } 5304 if (result == ISC_R_NOMORE) 5305 result = ISC_R_SUCCESS; 5306 if (seen_dname) 5307 *delegation = ISC_TRUE; 5308 failure: 5309 if (dns_rdataset_isassociated(&rdataset)) 5310 dns_rdataset_disassociate(&rdataset); 5311 if (iterator != NULL) 5312 dns_rdatasetiter_destroy(&iterator); 5313 return (result); 5314} 5315 5316/* 5317 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist. 5318 */ 5319static isc_result_t 5320updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 5321 dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff) 5322{ 5323 isc_result_t result; 5324 dns_rdataset_t rdataset; 5325 dns_dbnode_t *node = NULL; 5326 5327 CHECK(dns_db_getoriginnode(db, &node)); 5328 if (update_only) { 5329 dns_rdataset_init(&rdataset); 5330 result = dns_db_findrdataset(db, node, version, 5331 dns_rdatatype_nsec, 5332 dns_rdatatype_none, 5333 0, &rdataset, NULL); 5334 if (dns_rdataset_isassociated(&rdataset)) 5335 dns_rdataset_disassociate(&rdataset); 5336 if (result == ISC_R_NOTFOUND) 5337 goto success; 5338 if (result != ISC_R_SUCCESS) 5339 goto failure; 5340 } 5341 CHECK(delete_nsec(db, version, node, name, diff)); 5342 CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff)); 5343 success: 5344 result = ISC_R_SUCCESS; 5345 failure: 5346 if (node != NULL) 5347 dns_db_detachnode(db, &node); 5348 return (result); 5349} 5350 5351static isc_result_t 5352updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing, 5353 dns_dbversion_t *version, isc_boolean_t build_nsec3, 5354 dns_ttl_t minimum, dns_diff_t *diff) 5355{ 5356 isc_result_t result; 5357 dns_dbnode_t *node = NULL; 5358 dns_rdataset_t rdataset; 5359 dns_rdata_t rdata = DNS_RDATA_INIT; 5360 unsigned char data[5]; 5361 isc_boolean_t seen_done = ISC_FALSE; 5362 isc_boolean_t have_rr = ISC_FALSE; 5363 5364 dns_rdataset_init(&rdataset); 5365 result = dns_db_getoriginnode(signing->db, &node); 5366 if (result != ISC_R_SUCCESS) 5367 goto failure; 5368 5369 result = dns_db_findrdataset(signing->db, node, version, 5370 zone->privatetype, dns_rdatatype_none, 5371 0, &rdataset, NULL); 5372 if (result == ISC_R_NOTFOUND) { 5373 INSIST(!dns_rdataset_isassociated(&rdataset)); 5374 result = ISC_R_SUCCESS; 5375 goto failure; 5376 } 5377 if (result != ISC_R_SUCCESS) { 5378 INSIST(!dns_rdataset_isassociated(&rdataset)); 5379 goto failure; 5380 } 5381 for (result = dns_rdataset_first(&rdataset); 5382 result == ISC_R_SUCCESS; 5383 result = dns_rdataset_next(&rdataset)) { 5384 dns_rdataset_current(&rdataset, &rdata); 5385 /* 5386 * If we don't match the algorithm or keyid skip the record. 5387 */ 5388 if (rdata.length != 5 || 5389 rdata.data[0] != signing->algorithm || 5390 rdata.data[1] != ((signing->keyid >> 8) & 0xff) || 5391 rdata.data[2] != (signing->keyid & 0xff)) { 5392 have_rr = ISC_TRUE; 5393 dns_rdata_reset(&rdata); 5394 continue; 5395 } 5396 /* 5397 * We have a match. If we were signing (!signing->delete) 5398 * and we already have a record indicating that we have 5399 * finished signing (rdata.data[4] != 0) then keep it. 5400 * Otherwise it needs to be deleted as we have removed all 5401 * the signatures (signing->delete), so any record indicating 5402 * completion is now out of date, or we have finished signing 5403 * with the new record so we no longer need to remember that 5404 * we need to sign the zone with the matching key across a 5405 * nameserver re-start. 5406 */ 5407 if (!signing->delete && rdata.data[4] != 0) { 5408 seen_done = ISC_TRUE; 5409 have_rr = ISC_TRUE; 5410 } else 5411 CHECK(update_one_rr(signing->db, version, diff, 5412 DNS_DIFFOP_DEL, &zone->origin, 5413 rdataset.ttl, &rdata)); 5414 dns_rdata_reset(&rdata); 5415 } 5416 if (result == ISC_R_NOMORE) 5417 result = ISC_R_SUCCESS; 5418 if (!signing->delete && !seen_done) { 5419 /* 5420 * If we were signing then we need to indicate that we have 5421 * finished signing the zone with this key. If it is already 5422 * there we don't need to add it a second time. 5423 */ 5424 data[0] = signing->algorithm; 5425 data[1] = (signing->keyid >> 8) & 0xff; 5426 data[2] = signing->keyid & 0xff; 5427 data[3] = 0; 5428 data[4] = 1; 5429 rdata.length = sizeof(data); 5430 rdata.data = data; 5431 rdata.type = zone->privatetype; 5432 rdata.rdclass = dns_db_class(signing->db); 5433 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD, 5434 &zone->origin, rdataset.ttl, &rdata)); 5435 } else if (!have_rr) { 5436 dns_name_t *origin = dns_db_origin(signing->db); 5437 /* 5438 * Rebuild the NSEC/NSEC3 record for the origin as we no 5439 * longer have any private records. 5440 */ 5441 if (build_nsec3) 5442 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin, 5443 minimum, ISC_FALSE, diff)); 5444 CHECK(updatesecure(signing->db, version, origin, minimum, 5445 ISC_TRUE, diff)); 5446 } 5447 5448 failure: 5449 if (dns_rdataset_isassociated(&rdataset)) 5450 dns_rdataset_disassociate(&rdataset); 5451 if (node != NULL) 5452 dns_db_detachnode(signing->db, &node); 5453 return (result); 5454} 5455 5456/* 5457 * If 'active' is set then we are not done with the chain yet so only 5458 * delete the nsec3param record which indicates a full chain exists 5459 * (flags == 0). 5460 */ 5461static isc_result_t 5462fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain, 5463 isc_boolean_t active, dns_rdatatype_t privatetype, 5464 dns_diff_t *diff) 5465{ 5466 dns_dbnode_t *node = NULL; 5467 dns_name_t *name = dns_db_origin(db); 5468 dns_rdata_t rdata = DNS_RDATA_INIT; 5469 dns_rdataset_t rdataset; 5470 dns_rdata_nsec3param_t nsec3param; 5471 isc_result_t result; 5472 isc_buffer_t buffer; 5473 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE]; 5474 dns_ttl_t ttl = 0; 5475 5476 dns_rdataset_init(&rdataset); 5477 5478 result = dns_db_getoriginnode(db, &node); 5479 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5480 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 5481 0, 0, &rdataset, NULL); 5482 if (result == ISC_R_NOTFOUND) 5483 goto try_private; 5484 if (result != ISC_R_SUCCESS) 5485 goto failure; 5486 5487 /* 5488 * Preserve the existing ttl. 5489 */ 5490 ttl = rdataset.ttl; 5491 5492 /* 5493 * Delete all NSEC3PARAM records which match that in nsec3chain. 5494 */ 5495 for (result = dns_rdataset_first(&rdataset); 5496 result == ISC_R_SUCCESS; 5497 result = dns_rdataset_next(&rdataset)) { 5498 5499 dns_rdataset_current(&rdataset, &rdata); 5500 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 5501 5502 if (nsec3param.hash != chain->nsec3param.hash || 5503 (active && nsec3param.flags != 0) || 5504 nsec3param.iterations != chain->nsec3param.iterations || 5505 nsec3param.salt_length != chain->nsec3param.salt_length || 5506 memcmp(nsec3param.salt, chain->nsec3param.salt, 5507 nsec3param.salt_length)) { 5508 dns_rdata_reset(&rdata); 5509 continue; 5510 } 5511 5512 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, 5513 name, rdataset.ttl, &rdata)); 5514 dns_rdata_reset(&rdata); 5515 } 5516 if (result != ISC_R_NOMORE) 5517 goto failure; 5518 5519 dns_rdataset_disassociate(&rdataset); 5520 5521 try_private: 5522 5523 if (active) 5524 goto add; 5525 /* 5526 * Delete all private records which match that in nsec3chain. 5527 */ 5528 result = dns_db_findrdataset(db, node, ver, privatetype, 5529 0, 0, &rdataset, NULL); 5530 if (result == ISC_R_NOTFOUND) 5531 goto add; 5532 if (result != ISC_R_SUCCESS) 5533 goto failure; 5534 5535 for (result = dns_rdataset_first(&rdataset); 5536 result == ISC_R_SUCCESS; 5537 result = dns_rdataset_next(&rdataset)) { 5538 dns_rdata_t private = DNS_RDATA_INIT; 5539 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 5540 5541 dns_rdataset_current(&rdataset, &private); 5542 if (!dns_nsec3param_fromprivate(&private, &rdata, 5543 buf, sizeof(buf))) 5544 continue; 5545 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); 5546 5547 if (nsec3param.hash != chain->nsec3param.hash || 5548 nsec3param.iterations != chain->nsec3param.iterations || 5549 nsec3param.salt_length != chain->nsec3param.salt_length || 5550 memcmp(nsec3param.salt, chain->nsec3param.salt, 5551 nsec3param.salt_length)) { 5552 dns_rdata_reset(&rdata); 5553 continue; 5554 } 5555 5556 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, 5557 name, rdataset.ttl, &private)); 5558 dns_rdata_reset(&rdata); 5559 } 5560 if (result != ISC_R_NOMORE) 5561 goto failure; 5562 5563 add: 5564 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) { 5565 result = ISC_R_SUCCESS; 5566 goto failure; 5567 } 5568 5569 /* 5570 * Add a NSEC3PARAM record which matches that in nsec3chain but 5571 * with all flags bits cleared. 5572 * 5573 * Note: we do not clear chain->nsec3param.flags as this change 5574 * may be reversed. 5575 */ 5576 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf)); 5577 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), 5578 dns_rdatatype_nsec3param, 5579 &chain->nsec3param, &buffer)); 5580 rdata.data[1] = 0; /* Clear flag bits. */ 5581 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata)); 5582 5583 failure: 5584 dns_db_detachnode(db, &node); 5585 if (dns_rdataset_isassociated(&rdataset)) 5586 dns_rdataset_disassociate(&rdataset); 5587 return (result); 5588} 5589 5590static isc_result_t 5591delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 5592 dns_name_t *name, dns_diff_t *diff) 5593{ 5594 dns_rdataset_t rdataset; 5595 isc_result_t result; 5596 5597 dns_rdataset_init(&rdataset); 5598 5599 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 5600 0, 0, &rdataset, NULL); 5601 if (result == ISC_R_NOTFOUND) 5602 return (ISC_R_SUCCESS); 5603 if (result != ISC_R_SUCCESS) 5604 return (result); 5605 for (result = dns_rdataset_first(&rdataset); 5606 result == ISC_R_SUCCESS; 5607 result = dns_rdataset_next(&rdataset)) { 5608 dns_rdata_t rdata = DNS_RDATA_INIT; 5609 5610 dns_rdataset_current(&rdataset, &rdata); 5611 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 5612 rdataset.ttl, &rdata)); 5613 } 5614 if (result == ISC_R_NOMORE) 5615 result = ISC_R_SUCCESS; 5616 failure: 5617 dns_rdataset_disassociate(&rdataset); 5618 return (result); 5619} 5620 5621static isc_result_t 5622deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, 5623 dns_name_t *name, const dns_rdata_nsec3param_t *param, 5624 dns_diff_t *diff) 5625{ 5626 dns_rdataset_t rdataset; 5627 dns_rdata_nsec3_t nsec3; 5628 isc_result_t result; 5629 5630 dns_rdataset_init(&rdataset); 5631 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 5632 0, 0, &rdataset, NULL); 5633 if (result == ISC_R_NOTFOUND) 5634 return (ISC_R_SUCCESS); 5635 if (result != ISC_R_SUCCESS) 5636 return (result); 5637 5638 for (result = dns_rdataset_first(&rdataset); 5639 result == ISC_R_SUCCESS; 5640 result = dns_rdataset_next(&rdataset)) { 5641 dns_rdata_t rdata = DNS_RDATA_INIT; 5642 5643 dns_rdataset_current(&rdataset, &rdata); 5644 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL)); 5645 if (nsec3.hash != param->hash || 5646 nsec3.iterations != param->iterations || 5647 nsec3.salt_length != param->salt_length || 5648 memcmp(nsec3.salt, param->salt, nsec3.salt_length)) 5649 continue; 5650 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 5651 rdataset.ttl, &rdata)); 5652 } 5653 if (result == ISC_R_NOMORE) 5654 result = ISC_R_SUCCESS; 5655 failure: 5656 dns_rdataset_disassociate(&rdataset); 5657 return (result); 5658} 5659 5660static isc_result_t 5661need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver, 5662 const dns_rdata_nsec3param_t *param, 5663 isc_boolean_t *answer) 5664{ 5665 dns_dbnode_t *node = NULL; 5666 dns_rdata_t rdata = DNS_RDATA_INIT; 5667 dns_rdata_nsec3param_t myparam; 5668 dns_rdataset_t rdataset; 5669 isc_result_t result; 5670 5671 *answer = ISC_FALSE; 5672 5673 result = dns_db_getoriginnode(db, &node); 5674 RUNTIME_CHECK(result == ISC_R_SUCCESS); 5675 5676 dns_rdataset_init(&rdataset); 5677 5678 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 5679 0, 0, &rdataset, NULL); 5680 if (result == ISC_R_SUCCESS) { 5681 dns_rdataset_disassociate(&rdataset); 5682 dns_db_detachnode(db, &node); 5683 return (result); 5684 } 5685 if (result != ISC_R_NOTFOUND) { 5686 dns_db_detachnode(db, &node); 5687 return (result); 5688 } 5689 5690 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 5691 0, 0, &rdataset, NULL); 5692 if (result == ISC_R_NOTFOUND) { 5693 *answer = ISC_TRUE; 5694 dns_db_detachnode(db, &node); 5695 return (ISC_R_SUCCESS); 5696 } 5697 if (result != ISC_R_SUCCESS) { 5698 dns_db_detachnode(db, &node); 5699 return (result); 5700 } 5701 5702 for (result = dns_rdataset_first(&rdataset); 5703 result == ISC_R_SUCCESS; 5704 result = dns_rdataset_next(&rdataset)) { 5705 dns_rdataset_current(&rdataset, &rdata); 5706 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL)); 5707 dns_rdata_reset(&rdata); 5708 /* 5709 * Ignore any NSEC3PARAM removals. 5710 */ 5711 if (NSEC3REMOVE(myparam.flags)) 5712 continue; 5713 /* 5714 * Ignore the chain that we are in the process of deleting. 5715 */ 5716 if (myparam.hash == param->hash && 5717 myparam.iterations == param->iterations && 5718 myparam.salt_length == param->salt_length && 5719 !memcmp(myparam.salt, param->salt, myparam.salt_length)) 5720 continue; 5721 /* 5722 * Found an active NSEC3 chain. 5723 */ 5724 break; 5725 } 5726 if (result == ISC_R_NOMORE) { 5727 *answer = ISC_TRUE; 5728 result = ISC_R_SUCCESS; 5729 } 5730 5731 failure: 5732 if (dns_rdataset_isassociated(&rdataset)) 5733 dns_rdataset_disassociate(&rdataset); 5734 dns_db_detachnode(db, &node); 5735 return (result); 5736} 5737 5738static isc_result_t 5739update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, 5740 dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone, 5741 isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now, 5742 isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly, 5743 dns_diff_t *sig_diff) 5744{ 5745 dns_difftuple_t *tuple; 5746 isc_result_t result; 5747 5748 for (tuple = ISC_LIST_HEAD(diff->tuples); 5749 tuple != NULL; 5750 tuple = ISC_LIST_HEAD(diff->tuples)) { 5751 result = del_sigs(zone, db, version, &tuple->name, 5752 tuple->rdata.type, sig_diff, 5753 zone_keys, nkeys, now, ISC_FALSE); 5754 if (result != ISC_R_SUCCESS) { 5755 dns_zone_log(zone, ISC_LOG_ERROR, 5756 "update_sigs:del_sigs -> %s\n", 5757 dns_result_totext(result)); 5758 return (result); 5759 } 5760 result = add_sigs(db, version, &tuple->name, 5761 tuple->rdata.type, sig_diff, 5762 zone_keys, nkeys, zone->mctx, inception, 5763 expire, check_ksk, keyset_kskonly); 5764 if (result != ISC_R_SUCCESS) { 5765 dns_zone_log(zone, ISC_LOG_ERROR, 5766 "update_sigs:add_sigs -> %s\n", 5767 dns_result_totext(result)); 5768 return (result); 5769 } 5770 5771 do { 5772 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link); 5773 while (next != NULL && 5774 (tuple->rdata.type != next->rdata.type || 5775 !dns_name_equal(&tuple->name, &next->name))) 5776 next = ISC_LIST_NEXT(next, link); 5777 ISC_LIST_UNLINK(diff->tuples, tuple, link); 5778 dns_diff_appendminimal(sig_diff, &tuple); 5779 INSIST(tuple == NULL); 5780 tuple = next; 5781 } while (tuple != NULL); 5782 } 5783 return (ISC_R_SUCCESS); 5784} 5785 5786/* 5787 * Incrementally build and sign a new NSEC3 chain using the parameters 5788 * requested. 5789 */ 5790static void 5791zone_nsec3chain(dns_zone_t *zone) { 5792 dns_db_t *db = NULL; 5793 dns_dbnode_t *node = NULL; 5794 dns_dbversion_t *version = NULL; 5795 dns_diff_t sig_diff; 5796 dns_diff_t nsec_diff; 5797 dns_diff_t nsec3_diff; 5798 dns_diff_t param_diff; 5799 dns_fixedname_t fixed; 5800 dns_fixedname_t nextfixed; 5801 dns_name_t *name, *nextname; 5802 dns_rdataset_t rdataset; 5803 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain; 5804 dns_nsec3chainlist_t cleanup; 5805 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 5806 isc_int32_t signatures; 5807 isc_boolean_t check_ksk, keyset_kskonly; 5808 isc_boolean_t delegation; 5809 isc_boolean_t first; 5810 isc_result_t result; 5811 isc_stdtime_t now, inception, soaexpire, expire; 5812 isc_uint32_t jitter; 5813 unsigned int i; 5814 unsigned int nkeys = 0; 5815 isc_uint32_t nodes; 5816 isc_boolean_t unsecure = ISC_FALSE; 5817 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds; 5818 isc_boolean_t seen_nsec, seen_nsec3, seen_rr; 5819 dns_rdatasetiter_t *iterator = NULL; 5820 isc_boolean_t buildnsecchain; 5821 isc_boolean_t updatensec = ISC_FALSE; 5822 dns_rdatatype_t privatetype = zone->privatetype; 5823 5824 dns_rdataset_init(&rdataset); 5825 dns_fixedname_init(&fixed); 5826 name = dns_fixedname_name(&fixed); 5827 dns_fixedname_init(&nextfixed); 5828 nextname = dns_fixedname_name(&nextfixed); 5829 dns_diff_init(zone->mctx, ¶m_diff); 5830 dns_diff_init(zone->mctx, &nsec3_diff); 5831 dns_diff_init(zone->mctx, &nsec_diff); 5832 dns_diff_init(zone->mctx, &sig_diff); 5833 sig_diff.resign = zone->sigresigninginterval; 5834 ISC_LIST_INIT(cleanup); 5835 5836 /* 5837 * Updates are disabled. Pause for 5 minutes. 5838 */ 5839 if (zone->update_disabled) { 5840 result = ISC_R_FAILURE; 5841 goto failure; 5842 } 5843 5844 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 5845 dns_db_attach(zone->db, &db); 5846 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 5847 5848 result = dns_db_newversion(db, &version); 5849 if (result != ISC_R_SUCCESS) { 5850 dns_zone_log(zone, ISC_LOG_ERROR, 5851 "zone_nsec3chain:dns_db_newversion -> %s\n", 5852 dns_result_totext(result)); 5853 goto failure; 5854 } 5855 5856 result = find_zone_keys(zone, db, version, zone->mctx, 5857 DNS_MAXZONEKEYS, zone_keys, &nkeys); 5858 if (result != ISC_R_SUCCESS) { 5859 dns_zone_log(zone, ISC_LOG_ERROR, 5860 "zone_nsec3chain:find_zone_keys -> %s\n", 5861 dns_result_totext(result)); 5862 goto failure; 5863 } 5864 5865 isc_stdtime_get(&now); 5866 inception = now - 3600; /* Allow for clock skew. */ 5867 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 5868 5869 /* 5870 * Spread out signatures over time if they happen to be 5871 * clumped. We don't do this for each add_sigs() call as 5872 * we still want some clustering to occur. 5873 */ 5874 isc_random_get(&jitter); 5875 expire = soaexpire - jitter % 3600; 5876 5877 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 5878 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 5879 5880 /* 5881 * We keep pulling nodes off each iterator in turn until 5882 * we have no more nodes to pull off or we reach the limits 5883 * for this quantum. 5884 */ 5885 nodes = zone->nodes; 5886 signatures = zone->signatures; 5887 LOCK_ZONE(zone); 5888 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 5889 UNLOCK_ZONE(zone); 5890 first = ISC_TRUE; 5891 5892 if (nsec3chain != NULL) 5893 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 5894 /* 5895 * Generate new NSEC3 chains first. 5896 */ 5897 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 5898 LOCK_ZONE(zone); 5899 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 5900 5901 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 5902 if (nsec3chain->done || nsec3chain->db != zone->db) { 5903 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link); 5904 ISC_LIST_APPEND(cleanup, nsec3chain, link); 5905 } 5906 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 5907 UNLOCK_ZONE(zone); 5908 if (ISC_LIST_TAIL(cleanup) == nsec3chain) 5909 goto next_addchain; 5910 5911 /* 5912 * Possible future db. 5913 */ 5914 if (nsec3chain->db != db) { 5915 goto next_addchain; 5916 } 5917 5918 if (NSEC3REMOVE(nsec3chain->nsec3param.flags)) 5919 goto next_addchain; 5920 5921 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 5922 5923 if (nsec3chain->delete_nsec) { 5924 delegation = ISC_FALSE; 5925 dns_dbiterator_pause(nsec3chain->dbiterator); 5926 CHECK(delete_nsec(db, version, node, name, &nsec_diff)); 5927 goto next_addnode; 5928 } 5929 /* 5930 * On the first pass we need to check if the current node 5931 * has not been obscured. 5932 */ 5933 delegation = ISC_FALSE; 5934 unsecure = ISC_FALSE; 5935 if (first) { 5936 dns_fixedname_t ffound; 5937 dns_name_t *found; 5938 dns_fixedname_init(&ffound); 5939 found = dns_fixedname_name(&ffound); 5940 result = dns_db_find(db, name, version, 5941 dns_rdatatype_soa, 5942 DNS_DBFIND_NOWILD, 0, NULL, found, 5943 NULL, NULL); 5944 if ((result == DNS_R_DELEGATION || 5945 result == DNS_R_DNAME) && 5946 !dns_name_equal(name, found)) { 5947 /* 5948 * Remember the obscuring name so that 5949 * we skip all obscured names. 5950 */ 5951 dns_name_copy(found, name, NULL); 5952 delegation = ISC_TRUE; 5953 goto next_addnode; 5954 } 5955 } 5956 5957 /* 5958 * Check to see if this is a bottom of zone node. 5959 */ 5960 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 5961 if (result == ISC_R_NOTFOUND) /* Empty node? */ 5962 goto next_addnode; 5963 if (result != ISC_R_SUCCESS) 5964 goto failure; 5965 5966 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = 5967 ISC_FALSE; 5968 for (result = dns_rdatasetiter_first(iterator); 5969 result == ISC_R_SUCCESS; 5970 result = dns_rdatasetiter_next(iterator)) { 5971 dns_rdatasetiter_current(iterator, &rdataset); 5972 INSIST(rdataset.type != dns_rdatatype_nsec3); 5973 if (rdataset.type == dns_rdatatype_soa) 5974 seen_soa = ISC_TRUE; 5975 else if (rdataset.type == dns_rdatatype_ns) 5976 seen_ns = ISC_TRUE; 5977 else if (rdataset.type == dns_rdatatype_dname) 5978 seen_dname = ISC_TRUE; 5979 else if (rdataset.type == dns_rdatatype_ds) 5980 seen_ds = ISC_TRUE; 5981 else if (rdataset.type == dns_rdatatype_nsec) 5982 seen_nsec = ISC_TRUE; 5983 dns_rdataset_disassociate(&rdataset); 5984 } 5985 dns_rdatasetiter_destroy(&iterator); 5986 /* 5987 * Is there a NSEC chain than needs to be cleaned up? 5988 */ 5989 if (seen_nsec) 5990 nsec3chain->seen_nsec = ISC_TRUE; 5991 if (seen_ns && !seen_soa && !seen_ds) 5992 unsecure = ISC_TRUE; 5993 if ((seen_ns && !seen_soa) || seen_dname) 5994 delegation = ISC_TRUE; 5995 5996 /* 5997 * Process one node. 5998 */ 5999 dns_dbiterator_pause(nsec3chain->dbiterator); 6000 result = dns_nsec3_addnsec3(db, version, name, 6001 &nsec3chain->nsec3param, 6002 zone->minimum, unsecure, 6003 &nsec3_diff); 6004 if (result != ISC_R_SUCCESS) { 6005 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6006 "dns_nsec3_addnsec3 -> %s\n", 6007 dns_result_totext(result)); 6008 goto failure; 6009 } 6010 6011 /* 6012 * Treat each call to dns_nsec3_addnsec3() as if it's cost is 6013 * two signatures. Additionally there will, in general, be 6014 * two signature generated below. 6015 * 6016 * If we are only changing the optout flag the cost is half 6017 * that of the cost of generating a completely new chain. 6018 */ 6019 signatures -= 4; 6020 6021 /* 6022 * Go onto next node. 6023 */ 6024 next_addnode: 6025 first = ISC_FALSE; 6026 dns_db_detachnode(db, &node); 6027 do { 6028 result = dns_dbiterator_next(nsec3chain->dbiterator); 6029 6030 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) { 6031 CHECK(fixup_nsec3param(db, version, nsec3chain, 6032 ISC_FALSE, privatetype, 6033 ¶m_diff)); 6034 LOCK_ZONE(zone); 6035 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 6036 link); 6037 UNLOCK_ZONE(zone); 6038 ISC_LIST_APPEND(cleanup, nsec3chain, link); 6039 goto next_addchain; 6040 } 6041 if (result == ISC_R_NOMORE) { 6042 dns_dbiterator_pause(nsec3chain->dbiterator); 6043 if (nsec3chain->seen_nsec) { 6044 CHECK(fixup_nsec3param(db, version, 6045 nsec3chain, 6046 ISC_TRUE, 6047 privatetype, 6048 ¶m_diff)); 6049 nsec3chain->delete_nsec = ISC_TRUE; 6050 goto same_addchain; 6051 } 6052 CHECK(fixup_nsec3param(db, version, nsec3chain, 6053 ISC_FALSE, privatetype, 6054 ¶m_diff)); 6055 LOCK_ZONE(zone); 6056 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 6057 link); 6058 UNLOCK_ZONE(zone); 6059 ISC_LIST_APPEND(cleanup, nsec3chain, link); 6060 goto next_addchain; 6061 } else if (result != ISC_R_SUCCESS) { 6062 dns_zone_log(zone, ISC_LOG_ERROR, 6063 "zone_nsec3chain:" 6064 "dns_dbiterator_next -> %s\n", 6065 dns_result_totext(result)); 6066 goto failure; 6067 } else if (delegation) { 6068 dns_dbiterator_current(nsec3chain->dbiterator, 6069 &node, nextname); 6070 dns_db_detachnode(db, &node); 6071 if (!dns_name_issubdomain(nextname, name)) 6072 break; 6073 } else 6074 break; 6075 } while (1); 6076 continue; 6077 6078 same_addchain: 6079 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 6080 first = ISC_TRUE; 6081 continue; 6082 6083 next_addchain: 6084 dns_dbiterator_pause(nsec3chain->dbiterator); 6085 nsec3chain = nextnsec3chain; 6086 first = ISC_TRUE; 6087 if (nsec3chain != NULL) 6088 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; 6089 } 6090 6091 /* 6092 * Process removals. 6093 */ 6094 LOCK_ZONE(zone); 6095 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 6096 UNLOCK_ZONE(zone); 6097 first = ISC_TRUE; 6098 buildnsecchain = ISC_FALSE; 6099 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) { 6100 LOCK_ZONE(zone); 6101 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link); 6102 UNLOCK_ZONE(zone); 6103 6104 if (nsec3chain->db != db) 6105 goto next_removechain; 6106 6107 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) 6108 goto next_removechain; 6109 6110 /* 6111 * Work out if we need to build a NSEC chain as a consequence 6112 * of removing this NSEC3 chain. 6113 */ 6114 if (first && !updatensec && 6115 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) { 6116 result = need_nsec_chain(db, version, 6117 &nsec3chain->nsec3param, 6118 &buildnsecchain); 6119 if (result != ISC_R_SUCCESS) { 6120 dns_zone_log(zone, ISC_LOG_ERROR, 6121 "zone_nsec3chain:" 6122 "need_nsec_chain -> %s\n", 6123 dns_result_totext(result)); 6124 goto failure; 6125 } 6126 } 6127 6128 if (first) 6129 dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:" 6130 "buildnsecchain = %u\n", buildnsecchain); 6131 6132 dns_dbiterator_current(nsec3chain->dbiterator, &node, name); 6133 delegation = ISC_FALSE; 6134 6135 if (!buildnsecchain) { 6136 /* 6137 * Delete the NSECPARAM record that matches this chain. 6138 */ 6139 if (first) { 6140 result = fixup_nsec3param(db, version, 6141 nsec3chain, 6142 ISC_TRUE, privatetype, 6143 ¶m_diff); 6144 if (result != ISC_R_SUCCESS) { 6145 dns_zone_log(zone, ISC_LOG_ERROR, 6146 "zone_nsec3chain:" 6147 "fixup_nsec3param -> %s\n", 6148 dns_result_totext(result)); 6149 goto failure; 6150 } 6151 } 6152 6153 /* 6154 * Delete the NSEC3 records. 6155 */ 6156 result = deletematchingnsec3(db, version, node, name, 6157 &nsec3chain->nsec3param, 6158 &nsec3_diff); 6159 if (result != ISC_R_SUCCESS) { 6160 dns_zone_log(zone, ISC_LOG_ERROR, 6161 "zone_nsec3chain:" 6162 "deletematchingnsec3 -> %s\n", 6163 dns_result_totext(result)); 6164 goto failure; 6165 } 6166 goto next_removenode; 6167 } 6168 6169 if (first) { 6170 dns_fixedname_t ffound; 6171 dns_name_t *found; 6172 dns_fixedname_init(&ffound); 6173 found = dns_fixedname_name(&ffound); 6174 result = dns_db_find(db, name, version, 6175 dns_rdatatype_soa, 6176 DNS_DBFIND_NOWILD, 0, NULL, found, 6177 NULL, NULL); 6178 if ((result == DNS_R_DELEGATION || 6179 result == DNS_R_DNAME) && 6180 !dns_name_equal(name, found)) { 6181 /* 6182 * Remember the obscuring name so that 6183 * we skip all obscured names. 6184 */ 6185 dns_name_copy(found, name, NULL); 6186 delegation = ISC_TRUE; 6187 goto next_removenode; 6188 } 6189 } 6190 6191 /* 6192 * Check to see if this is a bottom of zone node. 6193 */ 6194 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 6195 if (result == ISC_R_NOTFOUND) /* Empty node? */ 6196 goto next_removenode; 6197 if (result != ISC_R_SUCCESS) 6198 goto failure; 6199 6200 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec = 6201 seen_rr = ISC_FALSE; 6202 for (result = dns_rdatasetiter_first(iterator); 6203 result == ISC_R_SUCCESS; 6204 result = dns_rdatasetiter_next(iterator)) { 6205 dns_rdatasetiter_current(iterator, &rdataset); 6206 if (rdataset.type == dns_rdatatype_soa) 6207 seen_soa = ISC_TRUE; 6208 else if (rdataset.type == dns_rdatatype_ns) 6209 seen_ns = ISC_TRUE; 6210 else if (rdataset.type == dns_rdatatype_dname) 6211 seen_dname = ISC_TRUE; 6212 else if (rdataset.type == dns_rdatatype_nsec) 6213 seen_nsec = ISC_TRUE; 6214 else if (rdataset.type == dns_rdatatype_nsec3) 6215 seen_nsec3 = ISC_TRUE; 6216 if (rdataset.type != dns_rdatatype_rrsig) 6217 seen_rr = ISC_TRUE; 6218 dns_rdataset_disassociate(&rdataset); 6219 } 6220 dns_rdatasetiter_destroy(&iterator); 6221 6222 if (!seen_rr || seen_nsec3 || seen_nsec) 6223 goto next_removenode; 6224 if ((seen_ns && !seen_soa) || seen_dname) 6225 delegation = ISC_TRUE; 6226 6227 /* 6228 * Add a NSEC record except at the origin. 6229 */ 6230 if (!dns_name_equal(name, dns_db_origin(db))) { 6231 dns_dbiterator_pause(nsec3chain->dbiterator); 6232 CHECK(add_nsec(db, version, name, node, zone->minimum, 6233 delegation, &nsec_diff)); 6234 } 6235 6236 next_removenode: 6237 first = ISC_FALSE; 6238 dns_db_detachnode(db, &node); 6239 do { 6240 result = dns_dbiterator_next(nsec3chain->dbiterator); 6241 if (result == ISC_R_NOMORE && buildnsecchain) { 6242 /* 6243 * The NSEC chain should now be built. 6244 * We can now remove the NSEC3 chain. 6245 */ 6246 updatensec = ISC_TRUE; 6247 goto same_removechain; 6248 } 6249 if (result == ISC_R_NOMORE) { 6250 LOCK_ZONE(zone); 6251 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, 6252 link); 6253 UNLOCK_ZONE(zone); 6254 ISC_LIST_APPEND(cleanup, nsec3chain, link); 6255 dns_dbiterator_pause(nsec3chain->dbiterator); 6256 result = fixup_nsec3param(db, version, 6257 nsec3chain, ISC_FALSE, 6258 privatetype, 6259 ¶m_diff); 6260 if (result != ISC_R_SUCCESS) { 6261 dns_zone_log(zone, ISC_LOG_ERROR, 6262 "zone_nsec3chain:" 6263 "fixup_nsec3param -> %s\n", 6264 dns_result_totext(result)); 6265 goto failure; 6266 } 6267 goto next_removechain; 6268 } else if (result != ISC_R_SUCCESS) { 6269 dns_zone_log(zone, ISC_LOG_ERROR, 6270 "zone_nsec3chain:" 6271 "dns_dbiterator_next -> %s\n", 6272 dns_result_totext(result)); 6273 goto failure; 6274 } else if (delegation) { 6275 dns_dbiterator_current(nsec3chain->dbiterator, 6276 &node, nextname); 6277 dns_db_detachnode(db, &node); 6278 if (!dns_name_issubdomain(nextname, name)) 6279 break; 6280 } else 6281 break; 6282 } while (1); 6283 continue; 6284 6285 same_removechain: 6286 CHECK(dns_dbiterator_first(nsec3chain->dbiterator)); 6287 buildnsecchain = ISC_FALSE; 6288 first = ISC_TRUE; 6289 continue; 6290 6291 next_removechain: 6292 dns_dbiterator_pause(nsec3chain->dbiterator); 6293 nsec3chain = nextnsec3chain; 6294 first = ISC_TRUE; 6295 } 6296 6297 /* 6298 * We may need to update the NSEC/NSEC3 records for the zone apex. 6299 */ 6300 if (!ISC_LIST_EMPTY(param_diff.tuples)) { 6301 isc_boolean_t rebuild_nsec = ISC_FALSE, 6302 rebuild_nsec3 = ISC_FALSE; 6303 result = dns_db_getoriginnode(db, &node); 6304 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6305 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 6306 if (result != ISC_R_SUCCESS) { 6307 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6308 "dns_db_allrdatasets -> %s\n", 6309 dns_result_totext(result)); 6310 goto failure; 6311 } 6312 for (result = dns_rdatasetiter_first(iterator); 6313 result == ISC_R_SUCCESS; 6314 result = dns_rdatasetiter_next(iterator)) { 6315 dns_rdatasetiter_current(iterator, &rdataset); 6316 if (rdataset.type == dns_rdatatype_nsec) 6317 rebuild_nsec = ISC_TRUE; 6318 if (rdataset.type == dns_rdatatype_nsec3param) 6319 rebuild_nsec3 = ISC_TRUE; 6320 dns_rdataset_disassociate(&rdataset); 6321 } 6322 dns_rdatasetiter_destroy(&iterator); 6323 dns_db_detachnode(db, &node); 6324 6325 if (rebuild_nsec) { 6326 if (nsec3chain != NULL) 6327 dns_dbiterator_pause(nsec3chain->dbiterator); 6328 result = updatesecure(db, version, &zone->origin, 6329 zone->minimum, ISC_TRUE, 6330 &nsec_diff); 6331 if (result != ISC_R_SUCCESS) { 6332 dns_zone_log(zone, ISC_LOG_ERROR, 6333 "zone_nsec3chain:" 6334 "updatesecure -> %s\n", 6335 dns_result_totext(result)); 6336 goto failure; 6337 } 6338 } 6339 if (rebuild_nsec3) { 6340 result = dns_nsec3_addnsec3s(db, version, 6341 dns_db_origin(db), 6342 zone->minimum, ISC_FALSE, 6343 &nsec3_diff); 6344 if (result != ISC_R_SUCCESS) { 6345 dns_zone_log(zone, ISC_LOG_ERROR, 6346 "zone_nsec3chain:" 6347 "dns_nsec3_addnsec3s -> %s\n", 6348 dns_result_totext(result)); 6349 goto failure; 6350 } 6351 } 6352 } 6353 6354 /* 6355 * Add / update signatures for the NSEC3 records. 6356 */ 6357 result = update_sigs(&nsec3_diff, db, version, zone_keys, 6358 nkeys, zone, inception, expire, now, 6359 check_ksk, keyset_kskonly, &sig_diff); 6360 if (result != ISC_R_SUCCESS) { 6361 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6362 "update_sigs -> %s\n", dns_result_totext(result)); 6363 goto failure; 6364 } 6365 6366 /* 6367 * We have changed the NSEC3PARAM or private RRsets 6368 * above so we need to update the signatures. 6369 */ 6370 result = update_sigs(¶m_diff, db, version, zone_keys, 6371 nkeys, zone, inception, expire, now, 6372 check_ksk, keyset_kskonly, &sig_diff); 6373 if (result != ISC_R_SUCCESS) { 6374 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6375 "update_sigs -> %s\n", dns_result_totext(result)); 6376 goto failure; 6377 } 6378 6379 if (updatensec) { 6380 if (nsec3chain != NULL) 6381 dns_dbiterator_pause(nsec3chain->dbiterator); 6382 result = updatesecure(db, version, &zone->origin, 6383 zone->minimum, ISC_FALSE, &nsec_diff); 6384 if (result != ISC_R_SUCCESS) { 6385 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6386 "updatesecure -> %s\n", 6387 dns_result_totext(result)); 6388 goto failure; 6389 } 6390 } 6391 6392 result = update_sigs(&nsec_diff, db, version, zone_keys, 6393 nkeys, zone, inception, expire, now, 6394 check_ksk, keyset_kskonly, &sig_diff); 6395 if (result != ISC_R_SUCCESS) { 6396 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6397 "update_sigs -> %s\n", dns_result_totext(result)); 6398 goto failure; 6399 } 6400 6401 /* 6402 * If we made no effective changes to the zone then we can just 6403 * cleanup otherwise we need to increment the serial. 6404 */ 6405 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) 6406 goto done; 6407 6408 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 6409 &sig_diff, zone_keys, nkeys, now, ISC_FALSE); 6410 if (result != ISC_R_SUCCESS) { 6411 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6412 "del_sigs -> %s\n", dns_result_totext(result)); 6413 goto failure; 6414 } 6415 6416 result = increment_soa_serial(db, version, &sig_diff, zone->mctx); 6417 if (result != ISC_R_SUCCESS) { 6418 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6419 "increment_soa_serial -> %s\n", 6420 dns_result_totext(result)); 6421 goto failure; 6422 } 6423 6424 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, 6425 &sig_diff, zone_keys, nkeys, zone->mctx, inception, 6426 soaexpire, check_ksk, keyset_kskonly); 6427 if (result != ISC_R_SUCCESS) { 6428 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" 6429 "add_sigs -> %s\n", dns_result_totext(result)); 6430 goto failure; 6431 } 6432 6433 /* Write changes to journal file. */ 6434 CHECK(zone_journal(zone, &sig_diff, "zone_nsec3chain")); 6435 6436 LOCK_ZONE(zone); 6437 zone_needdump(zone, DNS_DUMP_DELAY); 6438 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 6439 UNLOCK_ZONE(zone); 6440 6441 done: 6442 /* 6443 * Pause all iterators so that dns_db_closeversion() can succeed. 6444 */ 6445 LOCK_ZONE(zone); 6446 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 6447 nsec3chain != NULL; 6448 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 6449 dns_dbiterator_pause(nsec3chain->dbiterator); 6450 UNLOCK_ZONE(zone); 6451 6452 /* 6453 * Everything has succeeded. Commit the changes. 6454 */ 6455 dns_db_closeversion(db, &version, ISC_TRUE); 6456 6457 /* 6458 * Everything succeeded so we can clean these up now. 6459 */ 6460 nsec3chain = ISC_LIST_HEAD(cleanup); 6461 while (nsec3chain != NULL) { 6462 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 6463 dns_db_detach(&nsec3chain->db); 6464 dns_dbiterator_destroy(&nsec3chain->dbiterator); 6465 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 6466 nsec3chain = ISC_LIST_HEAD(cleanup); 6467 } 6468 6469 set_resigntime(zone); 6470 6471 failure: 6472 if (result != ISC_R_SUCCESS) 6473 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s\n", 6474 dns_result_totext(result)); 6475 /* 6476 * On error roll back the current nsec3chain. 6477 */ 6478 if (result != ISC_R_SUCCESS && nsec3chain != NULL) { 6479 if (nsec3chain->done) { 6480 dns_db_detach(&nsec3chain->db); 6481 dns_dbiterator_destroy(&nsec3chain->dbiterator); 6482 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 6483 } else { 6484 result = dns_dbiterator_first(nsec3chain->dbiterator); 6485 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6486 dns_dbiterator_pause(nsec3chain->dbiterator); 6487 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 6488 } 6489 } 6490 6491 /* 6492 * Rollback the cleanup list. 6493 */ 6494 nsec3chain = ISC_LIST_TAIL(cleanup); 6495 while (nsec3chain != NULL) { 6496 ISC_LIST_UNLINK(cleanup, nsec3chain, link); 6497 if (nsec3chain->done) { 6498 dns_db_detach(&nsec3chain->db); 6499 dns_dbiterator_destroy(&nsec3chain->dbiterator); 6500 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain); 6501 } else { 6502 LOCK_ZONE(zone); 6503 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link); 6504 UNLOCK_ZONE(zone); 6505 result = dns_dbiterator_first(nsec3chain->dbiterator); 6506 RUNTIME_CHECK(result == ISC_R_SUCCESS); 6507 dns_dbiterator_pause(nsec3chain->dbiterator); 6508 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec; 6509 } 6510 nsec3chain = ISC_LIST_TAIL(cleanup); 6511 } 6512 6513 LOCK_ZONE(zone); 6514 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); 6515 nsec3chain != NULL; 6516 nsec3chain = ISC_LIST_NEXT(nsec3chain, link)) 6517 dns_dbiterator_pause(nsec3chain->dbiterator); 6518 UNLOCK_ZONE(zone); 6519 6520 dns_diff_clear(¶m_diff); 6521 dns_diff_clear(&nsec3_diff); 6522 dns_diff_clear(&nsec_diff); 6523 dns_diff_clear(&sig_diff); 6524 6525 if (iterator != NULL) 6526 dns_rdatasetiter_destroy(&iterator); 6527 6528 for (i = 0; i < nkeys; i++) 6529 dst_key_free(&zone_keys[i]); 6530 6531 if (node != NULL) 6532 dns_db_detachnode(db, &node); 6533 if (version != NULL) { 6534 dns_db_closeversion(db, &version, ISC_FALSE); 6535 dns_db_detach(&db); 6536 } else if (db != NULL) 6537 dns_db_detach(&db); 6538 6539 LOCK_ZONE(zone); 6540 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) { 6541 isc_interval_t i; 6542 if (zone->update_disabled || result != ISC_R_SUCCESS) 6543 isc_interval_set(&i, 60, 0); /* 1 minute */ 6544 else 6545 isc_interval_set(&i, 0, 10000000); /* 10 ms */ 6546 isc_time_nowplusinterval(&zone->nsec3chaintime, &i); 6547 } else 6548 isc_time_settoepoch(&zone->nsec3chaintime); 6549 UNLOCK_ZONE(zone); 6550} 6551 6552static isc_result_t 6553del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, 6554 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm, 6555 isc_uint16_t keyid, dns_diff_t *diff) 6556{ 6557 dns_rdata_rrsig_t rrsig; 6558 dns_rdataset_t rdataset; 6559 dns_rdatasetiter_t *iterator = NULL; 6560 isc_result_t result; 6561 6562 result = dns_db_allrdatasets(db, node, version, 0, &iterator); 6563 if (result != ISC_R_SUCCESS) { 6564 if (result == ISC_R_NOTFOUND) 6565 result = ISC_R_SUCCESS; 6566 return (result); 6567 } 6568 6569 dns_rdataset_init(&rdataset); 6570 for (result = dns_rdatasetiter_first(iterator); 6571 result == ISC_R_SUCCESS; 6572 result = dns_rdatasetiter_next(iterator)) { 6573 dns_rdatasetiter_current(iterator, &rdataset); 6574 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) { 6575 for (result = dns_rdataset_first(&rdataset); 6576 result == ISC_R_SUCCESS; 6577 result = dns_rdataset_next(&rdataset)) { 6578 dns_rdata_t rdata = DNS_RDATA_INIT; 6579 dns_rdataset_current(&rdataset, &rdata); 6580 CHECK(update_one_rr(db, version, diff, 6581 DNS_DIFFOP_DEL, name, 6582 rdataset.ttl, &rdata)); 6583 } 6584 if (result != ISC_R_NOMORE) 6585 goto failure; 6586 dns_rdataset_disassociate(&rdataset); 6587 continue; 6588 } 6589 if (rdataset.type != dns_rdatatype_rrsig) { 6590 dns_rdataset_disassociate(&rdataset); 6591 continue; 6592 } 6593 for (result = dns_rdataset_first(&rdataset); 6594 result == ISC_R_SUCCESS; 6595 result = dns_rdataset_next(&rdataset)) { 6596 dns_rdata_t rdata = DNS_RDATA_INIT; 6597 dns_rdataset_current(&rdataset, &rdata); 6598 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL)); 6599 if (rrsig.algorithm != algorithm || 6600 rrsig.keyid != keyid) 6601 continue; 6602 CHECK(update_one_rr(db, version, diff, 6603 DNS_DIFFOP_DELRESIGN, name, 6604 rdataset.ttl, &rdata)); 6605 } 6606 dns_rdataset_disassociate(&rdataset); 6607 if (result != ISC_R_NOMORE) 6608 break; 6609 } 6610 if (result == ISC_R_NOMORE) 6611 result = ISC_R_SUCCESS; 6612 failure: 6613 if (dns_rdataset_isassociated(&rdataset)) 6614 dns_rdataset_disassociate(&rdataset); 6615 dns_rdatasetiter_destroy(&iterator); 6616 return (result); 6617} 6618 6619/* 6620 * Incrementally sign the zone using the keys requested. 6621 * Builds the NSEC chain if required. 6622 */ 6623static void 6624zone_sign(dns_zone_t *zone) { 6625 dns_db_t *db = NULL; 6626 dns_dbnode_t *node = NULL; 6627 dns_dbversion_t *version = NULL; 6628 dns_diff_t sig_diff; 6629 dns_diff_t post_diff; 6630 dns_fixedname_t fixed; 6631 dns_fixedname_t nextfixed; 6632 dns_name_t *name, *nextname; 6633 dns_rdataset_t rdataset; 6634 dns_signing_t *signing, *nextsigning; 6635 dns_signinglist_t cleanup; 6636 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 6637 isc_int32_t signatures; 6638 isc_boolean_t check_ksk, keyset_kskonly, is_ksk; 6639 isc_boolean_t commit = ISC_FALSE; 6640 isc_boolean_t delegation; 6641 isc_boolean_t build_nsec = ISC_FALSE; 6642 isc_boolean_t build_nsec3 = ISC_FALSE; 6643 isc_boolean_t first; 6644 isc_result_t result; 6645 isc_stdtime_t now, inception, soaexpire, expire; 6646 isc_uint32_t jitter; 6647 unsigned int i, j; 6648 unsigned int nkeys = 0; 6649 isc_uint32_t nodes; 6650 6651 dns_rdataset_init(&rdataset); 6652 dns_fixedname_init(&fixed); 6653 name = dns_fixedname_name(&fixed); 6654 dns_fixedname_init(&nextfixed); 6655 nextname = dns_fixedname_name(&nextfixed); 6656 dns_diff_init(zone->mctx, &sig_diff); 6657 sig_diff.resign = zone->sigresigninginterval; 6658 dns_diff_init(zone->mctx, &post_diff); 6659 ISC_LIST_INIT(cleanup); 6660 6661 /* 6662 * Updates are disabled. Pause for 5 minutes. 6663 */ 6664 if (zone->update_disabled) { 6665 result = ISC_R_FAILURE; 6666 goto failure; 6667 } 6668 6669 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 6670 dns_db_attach(zone->db, &db); 6671 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 6672 6673 result = dns_db_newversion(db, &version); 6674 if (result != ISC_R_SUCCESS) { 6675 dns_zone_log(zone, ISC_LOG_ERROR, 6676 "zone_sign:dns_db_newversion -> %s\n", 6677 dns_result_totext(result)); 6678 goto failure; 6679 } 6680 6681 result = find_zone_keys(zone, db, version, zone->mctx, 6682 DNS_MAXZONEKEYS, zone_keys, &nkeys); 6683 if (result != ISC_R_SUCCESS) { 6684 dns_zone_log(zone, ISC_LOG_ERROR, 6685 "zone_sign:find_zone_keys -> %s\n", 6686 dns_result_totext(result)); 6687 goto failure; 6688 } 6689 6690 isc_stdtime_get(&now); 6691 inception = now - 3600; /* Allow for clock skew. */ 6692 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 6693 6694 /* 6695 * Spread out signatures over time if they happen to be 6696 * clumped. We don't do this for each add_sigs() call as 6697 * we still want some clustering to occur. 6698 */ 6699 isc_random_get(&jitter); 6700 expire = soaexpire - jitter % 3600; 6701 6702 /* 6703 * We keep pulling nodes off each iterator in turn until 6704 * we have no more nodes to pull off or we reach the limits 6705 * for this quantum. 6706 */ 6707 nodes = zone->nodes; 6708 signatures = zone->signatures; 6709 signing = ISC_LIST_HEAD(zone->signing); 6710 first = ISC_TRUE; 6711 6712 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 6713 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 6714 6715 /* Determine which type of chain to build */ 6716 CHECK(dns_private_chains(db, version, zone->privatetype, 6717 &build_nsec, &build_nsec3)); 6718 6719 /* If neither chain is found, default to NSEC */ 6720 if (!build_nsec && !build_nsec3) 6721 build_nsec = ISC_TRUE; 6722 6723 while (signing != NULL && nodes-- > 0 && signatures > 0) { 6724 nextsigning = ISC_LIST_NEXT(signing, link); 6725 6726 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 6727 if (signing->done || signing->db != zone->db) { 6728 /* 6729 * The zone has been reloaded. We will have 6730 * created new signings as part of the reload 6731 * process so we can destroy this one. 6732 */ 6733 ISC_LIST_UNLINK(zone->signing, signing, link); 6734 ISC_LIST_APPEND(cleanup, signing, link); 6735 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 6736 goto next_signing; 6737 } 6738 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 6739 6740 if (signing->db != db) 6741 goto next_signing; 6742 6743 delegation = ISC_FALSE; 6744 6745 if (first && signing->delete) { 6746 /* 6747 * Remove the key we are deleting from consideration. 6748 */ 6749 for (i = 0, j = 0; i < nkeys; i++) { 6750 /* 6751 * Find the key we want to remove. 6752 */ 6753 if (ALG(zone_keys[i]) == signing->algorithm && 6754 dst_key_id(zone_keys[i]) == signing->keyid) 6755 { 6756 if (KSK(zone_keys[i])) 6757 dst_key_free(&zone_keys[i]); 6758 continue; 6759 } 6760 zone_keys[j] = zone_keys[i]; 6761 j++; 6762 } 6763 nkeys = j; 6764 } 6765 6766 dns_dbiterator_current(signing->dbiterator, &node, name); 6767 6768 if (signing->delete) { 6769 dns_dbiterator_pause(signing->dbiterator); 6770 CHECK(del_sig(db, version, name, node, nkeys, 6771 signing->algorithm, signing->keyid, 6772 &sig_diff)); 6773 } 6774 6775 /* 6776 * On the first pass we need to check if the current node 6777 * has not been obscured. 6778 */ 6779 if (first) { 6780 dns_fixedname_t ffound; 6781 dns_name_t *found; 6782 dns_fixedname_init(&ffound); 6783 found = dns_fixedname_name(&ffound); 6784 result = dns_db_find(db, name, version, 6785 dns_rdatatype_soa, 6786 DNS_DBFIND_NOWILD, 0, NULL, found, 6787 NULL, NULL); 6788 if ((result == DNS_R_DELEGATION || 6789 result == DNS_R_DNAME) && 6790 !dns_name_equal(name, found)) { 6791 /* 6792 * Remember the obscuring name so that 6793 * we skip all obscured names. 6794 */ 6795 dns_name_copy(found, name, NULL); 6796 delegation = ISC_TRUE; 6797 goto next_node; 6798 } 6799 } 6800 6801 /* 6802 * Process one node. 6803 */ 6804 dns_dbiterator_pause(signing->dbiterator); 6805 for (i = 0; i < nkeys; i++) { 6806 isc_boolean_t both = ISC_FALSE; 6807 6808 /* 6809 * Find the keys we want to sign with. 6810 */ 6811 if (!dst_key_isprivate(zone_keys[i])) 6812 continue; 6813 6814 /* 6815 * When adding look for the specific key. 6816 */ 6817 if (!signing->delete && 6818 (dst_key_alg(zone_keys[i]) != signing->algorithm || 6819 dst_key_id(zone_keys[i]) != signing->keyid)) 6820 continue; 6821 6822 /* 6823 * When deleting make sure we are properly signed 6824 * with the algorithm that was being removed. 6825 */ 6826 if (signing->delete && 6827 ALG(zone_keys[i]) != signing->algorithm) 6828 continue; 6829 6830 /* 6831 * Do we do KSK processing? 6832 */ 6833 if (check_ksk && !REVOKE(zone_keys[i])) { 6834 isc_boolean_t have_ksk, have_nonksk; 6835 if (KSK(zone_keys[i])) { 6836 have_ksk = ISC_TRUE; 6837 have_nonksk = ISC_FALSE; 6838 } else { 6839 have_ksk = ISC_FALSE; 6840 have_nonksk = ISC_TRUE; 6841 } 6842 for (j = 0; j < nkeys; j++) { 6843 if (j == i || 6844 ALG(zone_keys[i]) != 6845 ALG(zone_keys[j])) 6846 continue; 6847 if (REVOKE(zone_keys[j])) 6848 continue; 6849 if (KSK(zone_keys[j])) 6850 have_ksk = ISC_TRUE; 6851 else 6852 have_nonksk = ISC_TRUE; 6853 both = have_ksk && have_nonksk; 6854 if (both) 6855 break; 6856 } 6857 } 6858 if (both || REVOKE(zone_keys[i])) 6859 is_ksk = KSK(zone_keys[i]); 6860 else 6861 is_ksk = ISC_FALSE; 6862 6863 CHECK(sign_a_node(db, name, node, version, build_nsec3, 6864 build_nsec, zone_keys[i], inception, 6865 expire, zone->minimum, is_ksk, 6866 ISC_TF(both && keyset_kskonly), 6867 &delegation, &sig_diff, 6868 &signatures, zone->mctx)); 6869 /* 6870 * If we are adding we are done. Look for other keys 6871 * of the same algorithm if deleting. 6872 */ 6873 if (!signing->delete) 6874 break; 6875 } 6876 6877 /* 6878 * Go onto next node. 6879 */ 6880 next_node: 6881 first = ISC_FALSE; 6882 dns_db_detachnode(db, &node); 6883 do { 6884 result = dns_dbiterator_next(signing->dbiterator); 6885 if (result == ISC_R_NOMORE) { 6886 ISC_LIST_UNLINK(zone->signing, signing, link); 6887 ISC_LIST_APPEND(cleanup, signing, link); 6888 dns_dbiterator_pause(signing->dbiterator); 6889 if (nkeys != 0 && build_nsec) { 6890 /* 6891 * We have finished regenerating the 6892 * zone with a zone signing key. 6893 * The NSEC chain is now complete and 6894 * there is a full set of signatures 6895 * for the zone. We can now clear the 6896 * OPT bit from the NSEC record. 6897 */ 6898 result = updatesecure(db, version, 6899 &zone->origin, 6900 zone->minimum, 6901 ISC_FALSE, 6902 &post_diff); 6903 if (result != ISC_R_SUCCESS) { 6904 dns_zone_log(zone, 6905 ISC_LOG_ERROR, 6906 "updatesecure -> %s\n", 6907 dns_result_totext(result)); 6908 goto failure; 6909 } 6910 } 6911 result = updatesignwithkey(zone, signing, 6912 version, 6913 build_nsec3, 6914 zone->minimum, 6915 &post_diff); 6916 if (result != ISC_R_SUCCESS) { 6917 dns_zone_log(zone, ISC_LOG_ERROR, 6918 "updatesignwithkey " 6919 "-> %s\n", 6920 dns_result_totext(result)); 6921 goto failure; 6922 } 6923 build_nsec = ISC_FALSE; 6924 goto next_signing; 6925 } else if (result != ISC_R_SUCCESS) { 6926 dns_zone_log(zone, ISC_LOG_ERROR, 6927 "zone_sign:dns_dbiterator_next -> %s\n", 6928 dns_result_totext(result)); 6929 goto failure; 6930 } else if (delegation) { 6931 dns_dbiterator_current(signing->dbiterator, 6932 &node, nextname); 6933 dns_db_detachnode(db, &node); 6934 if (!dns_name_issubdomain(nextname, name)) 6935 break; 6936 } else 6937 break; 6938 } while (1); 6939 continue; 6940 6941 next_signing: 6942 dns_dbiterator_pause(signing->dbiterator); 6943 signing = nextsigning; 6944 first = ISC_TRUE; 6945 } 6946 6947 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) { 6948 result = update_sigs(&post_diff, db, version, zone_keys, 6949 nkeys, zone, inception, expire, now, 6950 check_ksk, keyset_kskonly, &sig_diff); 6951 if (result != ISC_R_SUCCESS) { 6952 dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:" 6953 "update_sigs -> %s\n", 6954 dns_result_totext(result)); 6955 goto failure; 6956 } 6957 } 6958 6959 /* 6960 * Have we changed anything? 6961 */ 6962 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) { 6963 result = ISC_R_SUCCESS; 6964 goto pauseall; 6965 } 6966 6967 commit = ISC_TRUE; 6968 6969 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, 6970 &sig_diff, zone_keys, nkeys, now, ISC_FALSE); 6971 if (result != ISC_R_SUCCESS) { 6972 dns_zone_log(zone, ISC_LOG_ERROR, 6973 "zone_sign:del_sigs -> %s\n", 6974 dns_result_totext(result)); 6975 goto failure; 6976 } 6977 6978 result = increment_soa_serial(db, version, &sig_diff, zone->mctx); 6979 if (result != ISC_R_SUCCESS) { 6980 dns_zone_log(zone, ISC_LOG_ERROR, 6981 "zone_sign:increment_soa_serial -> %s\n", 6982 dns_result_totext(result)); 6983 goto failure; 6984 } 6985 6986 /* 6987 * Generate maximum life time signatures so that the above loop 6988 * termination is sensible. 6989 */ 6990 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, 6991 &sig_diff, zone_keys, nkeys, zone->mctx, inception, 6992 soaexpire, check_ksk, keyset_kskonly); 6993 if (result != ISC_R_SUCCESS) { 6994 dns_zone_log(zone, ISC_LOG_ERROR, 6995 "zone_sign:add_sigs -> %s\n", 6996 dns_result_totext(result)); 6997 goto failure; 6998 } 6999 7000 /* 7001 * Write changes to journal file. 7002 */ 7003 CHECK(zone_journal(zone, &sig_diff, "zone_sign")); 7004 7005 pauseall: 7006 /* 7007 * Pause all iterators so that dns_db_closeversion() can succeed. 7008 */ 7009 for (signing = ISC_LIST_HEAD(zone->signing); 7010 signing != NULL; 7011 signing = ISC_LIST_NEXT(signing, link)) 7012 dns_dbiterator_pause(signing->dbiterator); 7013 7014 for (signing = ISC_LIST_HEAD(cleanup); 7015 signing != NULL; 7016 signing = ISC_LIST_NEXT(signing, link)) 7017 dns_dbiterator_pause(signing->dbiterator); 7018 7019 /* 7020 * Everything has succeeded. Commit the changes. 7021 */ 7022 dns_db_closeversion(db, &version, commit); 7023 7024 /* 7025 * Everything succeeded so we can clean these up now. 7026 */ 7027 signing = ISC_LIST_HEAD(cleanup); 7028 while (signing != NULL) { 7029 ISC_LIST_UNLINK(cleanup, signing, link); 7030 dns_db_detach(&signing->db); 7031 dns_dbiterator_destroy(&signing->dbiterator); 7032 isc_mem_put(zone->mctx, signing, sizeof *signing); 7033 signing = ISC_LIST_HEAD(cleanup); 7034 } 7035 7036 set_resigntime(zone); 7037 7038 if (commit) { 7039 LOCK_ZONE(zone); 7040 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 7041 zone_needdump(zone, DNS_DUMP_DELAY); 7042 UNLOCK_ZONE(zone); 7043 } 7044 7045 failure: 7046 /* 7047 * Rollback the cleanup list. 7048 */ 7049 signing = ISC_LIST_HEAD(cleanup); 7050 while (signing != NULL) { 7051 ISC_LIST_UNLINK(cleanup, signing, link); 7052 ISC_LIST_PREPEND(zone->signing, signing, link); 7053 dns_dbiterator_first(signing->dbiterator); 7054 dns_dbiterator_pause(signing->dbiterator); 7055 signing = ISC_LIST_HEAD(cleanup); 7056 } 7057 7058 for (signing = ISC_LIST_HEAD(zone->signing); 7059 signing != NULL; 7060 signing = ISC_LIST_NEXT(signing, link)) 7061 dns_dbiterator_pause(signing->dbiterator); 7062 7063 dns_diff_clear(&sig_diff); 7064 7065 for (i = 0; i < nkeys; i++) 7066 dst_key_free(&zone_keys[i]); 7067 7068 if (node != NULL) 7069 dns_db_detachnode(db, &node); 7070 7071 if (version != NULL) { 7072 dns_db_closeversion(db, &version, ISC_FALSE); 7073 dns_db_detach(&db); 7074 } else if (db != NULL) 7075 dns_db_detach(&db); 7076 7077 if (ISC_LIST_HEAD(zone->signing) != NULL) { 7078 isc_interval_t i; 7079 if (zone->update_disabled || result != ISC_R_SUCCESS) 7080 isc_interval_set(&i, 60, 0); /* 1 minute */ 7081 else 7082 isc_interval_set(&i, 0, 10000000); /* 10 ms */ 7083 isc_time_nowplusinterval(&zone->signingtime, &i); 7084 } else 7085 isc_time_settoepoch(&zone->signingtime); 7086} 7087 7088static void 7089normalize_key(dns_rdata_t *rr, dns_rdata_t *target, 7090 unsigned char *data, int size) { 7091 dns_rdata_dnskey_t dnskey; 7092 dns_rdata_keydata_t keydata; 7093 isc_buffer_t buf; 7094 7095 dns_rdata_reset(target); 7096 isc_buffer_init(&buf, data, size); 7097 7098 switch (rr->type) { 7099 case dns_rdatatype_dnskey: 7100 dns_rdata_tostruct(rr, &dnskey, NULL); 7101 dnskey.flags &= ~DNS_KEYFLAG_REVOKE; 7102 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 7103 &dnskey, &buf); 7104 break; 7105 case dns_rdatatype_keydata: 7106 dns_rdata_tostruct(rr, &keydata, NULL); 7107 dns_keydata_todnskey(&keydata, &dnskey, NULL); 7108 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, 7109 &dnskey, &buf); 7110 break; 7111 default: 7112 INSIST(0); 7113 } 7114} 7115 7116/* 7117 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or 7118 * a KEYDATA rdataset from the key zone. 7119 * 7120 * 'rr' contains either a DNSKEY record, or a KEYDATA record 7121 * 7122 * After normalizing keys to the same format (DNSKEY, with revoke bit 7123 * cleared), return ISC_TRUE if a key that matches 'rr' is found in 7124 * 'rdset', or ISC_FALSE if not. 7125 */ 7126 7127static isc_boolean_t 7128matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) { 7129 unsigned char data1[4096], data2[4096]; 7130 dns_rdata_t rdata, rdata1, rdata2; 7131 isc_result_t result; 7132 7133 dns_rdata_init(&rdata); 7134 dns_rdata_init(&rdata1); 7135 dns_rdata_init(&rdata2); 7136 7137 normalize_key(rr, &rdata1, data1, sizeof(data1)); 7138 7139 for (result = dns_rdataset_first(rdset); 7140 result == ISC_R_SUCCESS; 7141 result = dns_rdataset_next(rdset)) { 7142 dns_rdata_reset(&rdata); 7143 dns_rdataset_current(rdset, &rdata); 7144 normalize_key(&rdata, &rdata2, data2, sizeof(data2)); 7145 if (dns_rdata_compare(&rdata1, &rdata2) == 0) 7146 return (ISC_TRUE); 7147 } 7148 7149 return (ISC_FALSE); 7150} 7151 7152/* 7153 * Calculate the refresh interval for a keydata zone, per 7154 * RFC5011: MAX(1 hr, 7155 * MIN(15 days, 7156 * 1/2 * OrigTTL, 7157 * 1/2 * RRSigExpirationInterval)) 7158 * or for retries: MAX(1 hr, 7159 * MIN(1 day, 7160 * 1/10 * OrigTTL, 7161 * 1/10 * RRSigExpirationInterval)) 7162 */ 7163static inline isc_stdtime_t 7164refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) { 7165 isc_result_t result; 7166 isc_uint32_t t; 7167 dns_rdataset_t *rdset; 7168 dns_rdata_t sigrr = DNS_RDATA_INIT; 7169 dns_rdata_sig_t sig; 7170 isc_stdtime_t now; 7171 7172 isc_stdtime_get(&now); 7173 7174 if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) 7175 rdset = &kfetch->dnskeysigset; 7176 else 7177 return (now + HOUR); 7178 7179 result = dns_rdataset_first(rdset); 7180 if (result != ISC_R_SUCCESS) 7181 return (now + HOUR); 7182 7183 dns_rdataset_current(rdset, &sigrr); 7184 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 7185 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7186 7187 if (!retry) { 7188 t = sig.originalttl / 2; 7189 7190 if (isc_serial_gt(sig.timeexpire, now)) { 7191 isc_uint32_t exp = (sig.timeexpire - now) / 2; 7192 if (t > exp) 7193 t = exp; 7194 } 7195 7196 if (t > (15*DAY)) 7197 t = (15*DAY); 7198 7199 if (t < HOUR) 7200 t = HOUR; 7201 } else { 7202 t = sig.originalttl / 10; 7203 7204 if (isc_serial_gt(sig.timeexpire, now)) { 7205 isc_uint32_t exp = (sig.timeexpire - now) / 10; 7206 if (t > exp) 7207 t = exp; 7208 } 7209 7210 if (t > DAY) 7211 t = DAY; 7212 7213 if (t < HOUR) 7214 t = HOUR; 7215 } 7216 7217 return (now + t); 7218} 7219 7220/* 7221 * This routine is called when no changes are needed in a KEYDATA 7222 * record except to simply update the refresh timer. Caller should 7223 * hold zone lock. 7224 */ 7225static isc_result_t 7226minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) 7227{ 7228 isc_result_t result; 7229 isc_buffer_t keyb; 7230 unsigned char key_buf[4096]; 7231 dns_rdata_t rdata = DNS_RDATA_INIT; 7232 dns_rdata_keydata_t keydata; 7233 dns_name_t *name; 7234 dns_zone_t *zone = kfetch->zone; 7235 isc_stdtime_t now; 7236 7237 name = dns_fixedname_name(&kfetch->name); 7238 isc_stdtime_get(&now); 7239 7240 for (result = dns_rdataset_first(&kfetch->keydataset); 7241 result == ISC_R_SUCCESS; 7242 result = dns_rdataset_next(&kfetch->keydataset)) { 7243 dns_rdata_reset(&rdata); 7244 dns_rdataset_current(&kfetch->keydataset, &rdata); 7245 7246 /* Delete old version */ 7247 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL, 7248 name, 0, &rdata)); 7249 7250 /* Update refresh timer */ 7251 CHECK(dns_rdata_tostruct(&rdata, &keydata, NULL)); 7252 keydata.refresh = refresh_time(kfetch, ISC_TRUE); 7253 set_refreshkeytimer(zone, &keydata, now); 7254 7255 dns_rdata_reset(&rdata); 7256 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 7257 CHECK(dns_rdata_fromstruct(&rdata, 7258 zone->rdclass, dns_rdatatype_keydata, 7259 &keydata, &keyb)); 7260 7261 /* Insert updated version */ 7262 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD, 7263 name, 0, &rdata)); 7264 } 7265 result = ISC_R_SUCCESS; 7266 failure: 7267 return (result); 7268} 7269 7270/* 7271 * Verify that DNSKEY set is signed by the key specified in 'keydata'. 7272 */ 7273static isc_boolean_t 7274revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) { 7275 isc_result_t result; 7276 dns_name_t *keyname; 7277 isc_mem_t *mctx; 7278 dns_rdata_t sigrr = DNS_RDATA_INIT; 7279 dns_rdata_t rr = DNS_RDATA_INIT; 7280 dns_rdata_rrsig_t sig; 7281 dns_rdata_dnskey_t dnskey; 7282 dst_key_t *dstkey = NULL; 7283 unsigned char key_buf[4096]; 7284 isc_buffer_t keyb; 7285 isc_boolean_t answer = ISC_FALSE; 7286 7287 REQUIRE(kfetch != NULL && keydata != NULL); 7288 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset)); 7289 7290 keyname = dns_fixedname_name(&kfetch->name); 7291 mctx = kfetch->zone->view->mctx; 7292 7293 /* Generate a key from keydata */ 7294 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 7295 dns_keydata_todnskey(keydata, &dnskey, NULL); 7296 dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey, 7297 &dnskey, &keyb); 7298 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey); 7299 if (result != ISC_R_SUCCESS) 7300 return (ISC_FALSE); 7301 7302 /* See if that key generated any of the signatures */ 7303 for (result = dns_rdataset_first(&kfetch->dnskeysigset); 7304 result == ISC_R_SUCCESS; 7305 result = dns_rdataset_next(&kfetch->dnskeysigset)) { 7306 dns_fixedname_t fixed; 7307 dns_fixedname_init(&fixed); 7308 7309 dns_rdata_reset(&sigrr); 7310 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr); 7311 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 7312 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7313 7314 if (dst_key_alg(dstkey) == sig.algorithm && 7315 (dst_key_id(dstkey) == sig.keyid || 7316 dst_key_rid(dstkey) == sig.keyid)) { 7317 result = dns_dnssec_verify2(keyname, 7318 &kfetch->dnskeyset, 7319 dstkey, ISC_FALSE, mctx, &sigrr, 7320 dns_fixedname_name(&fixed)); 7321 7322 dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3), 7323 "Confirm revoked DNSKEY is self-signed: " 7324 "%s", dns_result_totext(result)); 7325 7326 if (result == ISC_R_SUCCESS) { 7327 answer = ISC_TRUE; 7328 break; 7329 } 7330 } 7331 } 7332 7333 dst_key_free(&dstkey); 7334 return (answer); 7335} 7336 7337/* 7338 * A DNSKEY set has been fetched from the zone apex of a zone whose trust 7339 * anchors are being managed; scan the keyset, and update the key zone and the 7340 * local trust anchors according to RFC5011. 7341 */ 7342static void 7343keyfetch_done(isc_task_t *task, isc_event_t *event) { 7344 isc_result_t result, eresult; 7345 dns_fetchevent_t *devent; 7346 dns_keyfetch_t *kfetch; 7347 dns_zone_t *zone; 7348 isc_mem_t *mctx = NULL; 7349 dns_keytable_t *secroots = NULL; 7350 dns_dbversion_t *ver = NULL; 7351 dns_diff_t diff; 7352 isc_boolean_t alldone = ISC_FALSE; 7353 isc_boolean_t commit = ISC_FALSE; 7354 dns_name_t *keyname; 7355 dns_rdata_t sigrr = DNS_RDATA_INIT; 7356 dns_rdata_t dnskeyrr = DNS_RDATA_INIT; 7357 dns_rdata_t keydatarr = DNS_RDATA_INIT; 7358 dns_rdata_rrsig_t sig; 7359 dns_rdata_dnskey_t dnskey; 7360 dns_rdata_keydata_t keydata; 7361 isc_boolean_t initializing; 7362 char namebuf[DNS_NAME_FORMATSIZE]; 7363 unsigned char key_buf[4096]; 7364 isc_buffer_t keyb; 7365 dst_key_t *dstkey; 7366 isc_stdtime_t now; 7367 int pending = 0; 7368 isc_boolean_t secure; 7369 isc_boolean_t free_needed; 7370 7371 UNUSED(task); 7372 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE); 7373 INSIST(event->ev_arg != NULL); 7374 7375 kfetch = event->ev_arg; 7376 zone = kfetch->zone; 7377 isc_mem_attach(zone->mctx, &mctx); 7378 keyname = dns_fixedname_name(&kfetch->name); 7379 7380 devent = (dns_fetchevent_t *) event; 7381 eresult = devent->result; 7382 7383 /* Free resources which are not of interest */ 7384 if (devent->node != NULL) 7385 dns_db_detachnode(devent->db, &devent->node); 7386 if (devent->db != NULL) 7387 dns_db_detach(&devent->db); 7388 isc_event_free(&event); 7389 dns_resolver_destroyfetch(&kfetch->fetch); 7390 7391 LOCK_ZONE(zone); 7392 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) 7393 goto cleanup; 7394 7395 isc_stdtime_get(&now); 7396 dns_name_format(keyname, namebuf, sizeof(namebuf)); 7397 7398 result = dns_view_getsecroots(zone->view, &secroots); 7399 INSIST(result == ISC_R_SUCCESS); 7400 7401 dns_diff_init(mctx, &diff); 7402 diff.resign = zone->sigresigninginterval; 7403 7404 CHECK(dns_db_newversion(kfetch->db, &ver)); 7405 7406 zone->refreshkeycount--; 7407 alldone = ISC_TF(zone->refreshkeycount == 0); 7408 7409 if (alldone) 7410 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 7411 7412 /* Fetch failed */ 7413 if (eresult != ISC_R_SUCCESS || 7414 !dns_rdataset_isassociated(&kfetch->dnskeyset)) { 7415 dns_zone_log(zone, ISC_LOG_WARNING, 7416 "Unable to fetch DNSKEY set " 7417 "'%s': %s", namebuf, dns_result_totext(eresult)); 7418 CHECK(minimal_update(kfetch, ver, &diff)); 7419 goto done; 7420 } 7421 7422 /* No RRSIGs found */ 7423 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) { 7424 dns_zone_log(zone, ISC_LOG_WARNING, 7425 "No DNSKEY RRSIGs found for " 7426 "'%s': %s", namebuf, dns_result_totext(eresult)); 7427 CHECK(minimal_update(kfetch, ver, &diff)); 7428 goto done; 7429 } 7430 7431 /* 7432 * Validate the dnskeyset against the current trusted keys. 7433 */ 7434 for (result = dns_rdataset_first(&kfetch->dnskeysigset); 7435 result == ISC_R_SUCCESS; 7436 result = dns_rdataset_next(&kfetch->dnskeysigset)) { 7437 dns_keynode_t *keynode = NULL; 7438 7439 dns_rdata_reset(&sigrr); 7440 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr); 7441 result = dns_rdata_tostruct(&sigrr, &sig, NULL); 7442 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7443 7444 result = dns_keytable_find(secroots, keyname, &keynode); 7445 while (result == ISC_R_SUCCESS) { 7446 dns_keynode_t *nextnode = NULL; 7447 dns_fixedname_t fixed; 7448 dns_fixedname_init(&fixed); 7449 7450 dstkey = dns_keynode_key(keynode); 7451 if (dstkey == NULL) /* fail_secure() was called */ 7452 break; 7453 7454 if (dst_key_alg(dstkey) == sig.algorithm && 7455 dst_key_id(dstkey) == sig.keyid) { 7456 result = dns_dnssec_verify2(keyname, 7457 &kfetch->dnskeyset, 7458 dstkey, ISC_FALSE, 7459 zone->view->mctx, &sigrr, 7460 dns_fixedname_name(&fixed)); 7461 7462 dns_zone_log(zone, ISC_LOG_DEBUG(3), 7463 "Verifying DNSKEY set for zone " 7464 "'%s': %s", namebuf, 7465 dns_result_totext(result)); 7466 7467 if (result == ISC_R_SUCCESS) { 7468 kfetch->dnskeyset.trust = 7469 dns_trust_secure; 7470 kfetch->dnskeysigset.trust = 7471 dns_trust_secure; 7472 dns_keytable_detachkeynode(secroots, 7473 &keynode); 7474 break; 7475 } 7476 } 7477 7478 result = dns_keytable_nextkeynode(secroots, 7479 keynode, &nextnode); 7480 dns_keytable_detachkeynode(secroots, &keynode); 7481 keynode = nextnode; 7482 } 7483 7484 if (kfetch->dnskeyset.trust == dns_trust_secure) 7485 break; 7486 } 7487 7488 /* 7489 * If we were not able to verify the answer using the current 7490 * trusted keys then all we can do is look at any revoked keys. 7491 */ 7492 secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure); 7493 7494 /* 7495 * First scan keydataset to find keys that are not in dnskeyset 7496 * - Missing keys which are not scheduled for removal, 7497 * log a warning 7498 * - Missing keys which are scheduled for removal and 7499 * the remove hold-down timer has completed should 7500 * be removed from the key zone 7501 * - Missing keys whose acceptance timers have not yet 7502 * completed, log a warning and reset the acceptance 7503 * timer to 30 days in the future 7504 * - All keys not being removed have their refresh timers 7505 * updated 7506 */ 7507 initializing = ISC_TRUE; 7508 for (result = dns_rdataset_first(&kfetch->keydataset); 7509 result == ISC_R_SUCCESS; 7510 result = dns_rdataset_next(&kfetch->keydataset)) { 7511 dns_rdata_reset(&keydatarr); 7512 dns_rdataset_current(&kfetch->keydataset, &keydatarr); 7513 dns_rdata_tostruct(&keydatarr, &keydata, NULL); 7514 7515 /* 7516 * If any keydata record has a nonzero add holddown, then 7517 * there was a pre-existing trust anchor for this domain; 7518 * that means we are *not* initializing it and shouldn't 7519 * automatically trust all the keys we find at the zone apex. 7520 */ 7521 initializing = initializing && ISC_TF(keydata.addhd == 0); 7522 7523 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) { 7524 isc_boolean_t deletekey = ISC_FALSE; 7525 7526 if (!secure) { 7527 if (now > keydata.removehd) 7528 deletekey = ISC_TRUE; 7529 } else if (now < keydata.addhd) { 7530 dns_zone_log(zone, ISC_LOG_WARNING, 7531 "Pending key unexpectedly missing " 7532 "from %s; restarting acceptance " 7533 "timer", namebuf); 7534 keydata.addhd = now + MONTH; 7535 keydata.refresh = refresh_time(kfetch, 7536 ISC_FALSE); 7537 } else if (keydata.addhd == 0) { 7538 keydata.addhd = now; 7539 } else if (keydata.removehd == 0) { 7540 dns_zone_log(zone, ISC_LOG_WARNING, 7541 "Active key unexpectedly missing " 7542 "from %s", namebuf); 7543 keydata.refresh = now + HOUR; 7544 } else if (now > keydata.removehd) { 7545 deletekey = ISC_TRUE; 7546 } else { 7547 keydata.refresh = refresh_time(kfetch, 7548 ISC_FALSE); 7549 } 7550 7551 if (secure || deletekey) { 7552 /* Delete old version */ 7553 CHECK(update_one_rr(kfetch->db, ver, &diff, 7554 DNS_DIFFOP_DEL, keyname, 0, 7555 &keydatarr)); 7556 } 7557 7558 if (!secure || deletekey) 7559 continue; 7560 7561 dns_rdata_reset(&keydatarr); 7562 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 7563 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 7564 dns_rdatatype_keydata, 7565 &keydata, &keyb); 7566 7567 /* Insert updated version */ 7568 CHECK(update_one_rr(kfetch->db, ver, &diff, 7569 DNS_DIFFOP_ADD, keyname, 0, 7570 &keydatarr)); 7571 7572 set_refreshkeytimer(zone, &keydata, now); 7573 } 7574 } 7575 7576 /* 7577 * Next scan dnskeyset: 7578 * - If new keys are found (i.e., lacking a match in keydataset) 7579 * add them to the key zone and set the acceptance timer 7580 * to 30 days in the future (or to immediately if we've 7581 * determined that we're initializing the zone for the 7582 * first time) 7583 * - Previously-known keys that have been revoked 7584 * must be scheduled for removal from the key zone (or, 7585 * if they hadn't been accepted as trust anchors yet 7586 * anyway, removed at once) 7587 * - Previously-known unrevoked keys whose acceptance timers 7588 * have completed are promoted to trust anchors 7589 * - All keys not being removed have their refresh 7590 * timers updated 7591 */ 7592 for (result = dns_rdataset_first(&kfetch->dnskeyset); 7593 result == ISC_R_SUCCESS; 7594 result = dns_rdataset_next(&kfetch->dnskeyset)) { 7595 isc_boolean_t revoked = ISC_FALSE; 7596 isc_boolean_t newkey = ISC_FALSE; 7597 isc_boolean_t updatekey = ISC_FALSE; 7598 isc_boolean_t deletekey = ISC_FALSE; 7599 isc_boolean_t trustkey = ISC_FALSE; 7600 7601 dns_rdata_reset(&dnskeyrr); 7602 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr); 7603 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 7604 7605 /* Skip ZSK's */ 7606 if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK)) 7607 continue; 7608 7609 revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE); 7610 7611 if (matchkey(&kfetch->keydataset, &dnskeyrr)) { 7612 dns_rdata_reset(&keydatarr); 7613 dns_rdataset_current(&kfetch->keydataset, &keydatarr); 7614 dns_rdata_tostruct(&keydatarr, &keydata, NULL); 7615 7616 if (revoked && revocable(kfetch, &keydata)) { 7617 if (keydata.addhd > now) { 7618 /* 7619 * Key wasn't trusted yet, and now 7620 * it's been revoked? Just remove it 7621 */ 7622 deletekey = ISC_TRUE; 7623 } else if (keydata.removehd == 0) { 7624 /* Remove from secroots */ 7625 dns_view_untrust(zone->view, keyname, 7626 &dnskey, mctx); 7627 7628 /* If initializing, delete now */ 7629 if (keydata.addhd == 0) 7630 deletekey = ISC_TRUE; 7631 else 7632 keydata.removehd = now + MONTH; 7633 } else if (keydata.removehd < now) { 7634 /* Scheduled for removal */ 7635 deletekey = ISC_TRUE; 7636 } 7637 } else if (revoked) { 7638 if (secure && keydata.removehd == 0) { 7639 dns_zone_log(zone, ISC_LOG_WARNING, 7640 "Active key for zone " 7641 "'%s' is revoked but " 7642 "did not self-sign; " 7643 "ignoring.", namebuf); 7644 continue; 7645 } 7646 } else if (secure) { 7647 if (keydata.removehd != 0) { 7648 /* 7649 * Key isn't revoked--but it 7650 * seems it used to be. 7651 * Remove it now and add it 7652 * back as if it were a fresh key. 7653 */ 7654 deletekey = ISC_TRUE; 7655 newkey = ISC_TRUE; 7656 } else if (keydata.addhd > now) 7657 pending++; 7658 else if (keydata.addhd == 0) 7659 keydata.addhd = now; 7660 7661 if (keydata.addhd <= now) 7662 trustkey = ISC_TRUE; 7663 } 7664 7665 if (!deletekey && !newkey) 7666 updatekey = ISC_TRUE; 7667 } else if (secure) { 7668 /* 7669 * Key wasn't in the key zone but it's 7670 * revoked now anyway, so just skip it 7671 */ 7672 if (revoked) 7673 continue; 7674 7675 /* Key wasn't in the key zone: add it */ 7676 newkey = ISC_TRUE; 7677 7678 if (initializing) { 7679 dns_keytag_t tag = 0; 7680 CHECK(compute_tag(keyname, &dnskey, 7681 mctx, &tag)); 7682 dns_zone_log(zone, ISC_LOG_WARNING, 7683 "Initializing automatic trust " 7684 "anchor management for zone '%s'; " 7685 "DNSKEY ID %d is now trusted, " 7686 "waiving the normal 30-day " 7687 "waiting period.", 7688 namebuf, tag); 7689 trustkey = ISC_TRUE; 7690 } 7691 } 7692 7693 /* Delete old version */ 7694 if (deletekey || !newkey) 7695 CHECK(update_one_rr(kfetch->db, ver, &diff, 7696 DNS_DIFFOP_DEL, keyname, 0, 7697 &keydatarr)); 7698 7699 if (updatekey) { 7700 /* Set refresh timer */ 7701 keydata.refresh = refresh_time(kfetch, ISC_FALSE); 7702 dns_rdata_reset(&keydatarr); 7703 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 7704 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 7705 dns_rdatatype_keydata, 7706 &keydata, &keyb); 7707 7708 /* Insert updated version */ 7709 CHECK(update_one_rr(kfetch->db, ver, &diff, 7710 DNS_DIFFOP_ADD, keyname, 0, 7711 &keydatarr)); 7712 } else if (newkey) { 7713 /* Convert DNSKEY to KEYDATA */ 7714 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 7715 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0, 7716 NULL); 7717 keydata.addhd = initializing ? now : now + MONTH; 7718 keydata.refresh = refresh_time(kfetch, ISC_FALSE); 7719 dns_rdata_reset(&keydatarr); 7720 isc_buffer_init(&keyb, key_buf, sizeof(key_buf)); 7721 dns_rdata_fromstruct(&keydatarr, zone->rdclass, 7722 dns_rdatatype_keydata, 7723 &keydata, &keyb); 7724 7725 /* Insert into key zone */ 7726 CHECK(update_one_rr(kfetch->db, ver, &diff, 7727 DNS_DIFFOP_ADD, keyname, 0, 7728 &keydatarr)); 7729 } 7730 7731 if (trustkey) { 7732 /* Trust this key. */ 7733 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); 7734 trust_key(zone, keyname, &dnskey, mctx); 7735 } 7736 7737 if (!deletekey) 7738 set_refreshkeytimer(zone, &keydata, now); 7739 } 7740 7741 /* 7742 * RFC5011 says, "A trust point that has all of its trust anchors 7743 * revoked is considered deleted and is treated as if the trust 7744 * point was never configured." But if someone revoked their 7745 * active key before the standby was trusted, that would mean the 7746 * zone would suddenly be nonsecured. We avoid this by checking to 7747 * see if there's pending keydata. If so, we put a null key in 7748 * the security roots; then all queries to the zone will fail. 7749 */ 7750 if (pending != 0) 7751 fail_secure(zone, keyname); 7752 7753 done: 7754 7755 if (!ISC_LIST_EMPTY(diff.tuples)) { 7756 /* Write changes to journal file. */ 7757 CHECK(increment_soa_serial(kfetch->db, ver, &diff, mctx)); 7758 CHECK(zone_journal(zone, &diff, "keyfetch_done")); 7759 commit = ISC_TRUE; 7760 7761 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 7762 zone_needdump(zone, 30); 7763 } 7764 7765 failure: 7766 7767 dns_diff_clear(&diff); 7768 if (ver != NULL) 7769 dns_db_closeversion(kfetch->db, &ver, commit); 7770 7771 cleanup: 7772 dns_db_detach(&kfetch->db); 7773 7774 INSIST(zone->irefs > 0); 7775 zone->irefs--; 7776 kfetch->zone = NULL; 7777 7778 if (dns_rdataset_isassociated(&kfetch->keydataset)) 7779 dns_rdataset_disassociate(&kfetch->keydataset); 7780 if (dns_rdataset_isassociated(&kfetch->dnskeyset)) 7781 dns_rdataset_disassociate(&kfetch->dnskeyset); 7782 if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) 7783 dns_rdataset_disassociate(&kfetch->dnskeysigset); 7784 7785 dns_name_free(keyname, mctx); 7786 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t)); 7787 isc_mem_detach(&mctx); 7788 7789 if (secroots != NULL) 7790 dns_keytable_detach(&secroots); 7791 7792 free_needed = exit_check(zone); 7793 UNLOCK_ZONE(zone); 7794 if (free_needed) 7795 zone_free(zone); 7796} 7797 7798/* 7799 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY 7800 * records from the zone apex. 7801 */ 7802static void 7803zone_refreshkeys(dns_zone_t *zone) { 7804 const char me[] = "zone_refreshkeys"; 7805 isc_result_t result; 7806 dns_rriterator_t rrit; 7807 dns_db_t *db = NULL; 7808 dns_dbversion_t *ver = NULL; 7809 dns_diff_t diff; 7810 dns_rdata_t rdata = DNS_RDATA_INIT; 7811 dns_rdata_keydata_t kd; 7812 isc_stdtime_t now; 7813 isc_boolean_t commit = ISC_FALSE; 7814 isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE; 7815 7816 ENTER; 7817 REQUIRE(zone->db != NULL); 7818 7819 isc_stdtime_get(&now); 7820 7821 LOCK_ZONE(zone); 7822 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 7823 isc_time_settoepoch(&zone->refreshkeytime); 7824 UNLOCK_ZONE(zone); 7825 return; 7826 } 7827 7828 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 7829 dns_db_attach(zone->db, &db); 7830 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 7831 7832 dns_diff_init(zone->mctx, &diff); 7833 7834 CHECK(dns_db_newversion(db, &ver)); 7835 7836 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING); 7837 7838 dns_rriterator_init(&rrit, db, ver, 0); 7839 for (result = dns_rriterator_first(&rrit); 7840 result == ISC_R_SUCCESS; 7841 result = dns_rriterator_nextrrset(&rrit)) { 7842 isc_stdtime_t timer = 0xffffffff; 7843 dns_name_t *name = NULL, *kname = NULL; 7844 dns_rdataset_t *kdset = NULL; 7845 dns_keyfetch_t *kfetch; 7846 isc_uint32_t ttl; 7847 7848 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL); 7849 if (kdset == NULL || kdset->type != dns_rdatatype_keydata || 7850 !dns_rdataset_isassociated(kdset)) 7851 continue; 7852 7853 /* 7854 * Scan the stored keys looking for ones that need 7855 * removal or refreshing 7856 */ 7857 for (result = dns_rdataset_first(kdset); 7858 result == ISC_R_SUCCESS; 7859 result = dns_rdataset_next(kdset)) { 7860 dns_rdata_reset(&rdata); 7861 dns_rdataset_current(kdset, &rdata); 7862 result = dns_rdata_tostruct(&rdata, &kd, NULL); 7863 RUNTIME_CHECK(result == ISC_R_SUCCESS); 7864 7865 /* Removal timer expired? */ 7866 if (kd.removehd != 0 && kd.removehd < now) { 7867 CHECK(update_one_rr(db, ver, &diff, 7868 DNS_DIFFOP_DEL, name, ttl, 7869 &rdata)); 7870 continue; 7871 } 7872 7873 /* Acceptance timer expired? */ 7874 if (kd.addhd != 0 && kd.addhd < now) 7875 timer = kd.addhd; 7876 7877 /* Or do we just need to refresh the keyset? */ 7878 if (timer > kd.refresh) 7879 timer = kd.refresh; 7880 } 7881 7882 if (timer > now) 7883 continue; 7884 7885 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t)); 7886 if (kfetch == NULL) { 7887 fetch_err = ISC_TRUE; 7888 goto failure; 7889 } 7890 7891 zone->refreshkeycount++; 7892 kfetch->zone = zone; 7893 zone->irefs++; 7894 INSIST(zone->irefs != 0); 7895 dns_fixedname_init(&kfetch->name); 7896 kname = dns_fixedname_name(&kfetch->name); 7897 dns_name_dup(name, zone->mctx, kname); 7898 dns_rdataset_init(&kfetch->dnskeyset); 7899 dns_rdataset_init(&kfetch->dnskeysigset); 7900 dns_rdataset_init(&kfetch->keydataset); 7901 dns_rdataset_clone(kdset, &kfetch->keydataset); 7902 kfetch->db = NULL; 7903 dns_db_attach(db, &kfetch->db); 7904 kfetch->fetch = NULL; 7905 7906 result = dns_resolver_createfetch(zone->view->resolver, 7907 kname, dns_rdatatype_dnskey, 7908 NULL, NULL, NULL, 7909 DNS_FETCHOPT_NOVALIDATE, 7910 zone->task, 7911 keyfetch_done, kfetch, 7912 &kfetch->dnskeyset, 7913 &kfetch->dnskeysigset, 7914 &kfetch->fetch); 7915 if (result == ISC_R_SUCCESS) 7916 fetching = ISC_TRUE; 7917 else { 7918 zone->refreshkeycount--; 7919 zone->irefs--; 7920 dns_db_detach(&kfetch->db); 7921 dns_rdataset_disassociate(&kfetch->keydataset); 7922 dns_name_free(kname, zone->mctx); 7923 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t)); 7924 dns_zone_log(zone, ISC_LOG_WARNING, 7925 "Failed to create fetch for " 7926 "DNSKEY update"); 7927 fetch_err = ISC_TRUE; 7928 } 7929 } 7930 if (!ISC_LIST_EMPTY(diff.tuples)) { 7931 CHECK(increment_soa_serial(db, ver, &diff, zone->mctx)); 7932 CHECK(zone_journal(zone, &diff, "zone_refreshkeys")); 7933 commit = ISC_TRUE; 7934 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); 7935 zone_needdump(zone, 30); 7936 } 7937 7938 failure: 7939 if (fetch_err) { 7940 /* 7941 * Error during a key fetch; retry in an hour. 7942 */ 7943 isc_time_t timenow, timethen; 7944 char timebuf[80]; 7945 7946 TIME_NOW(&timenow); 7947 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen); 7948 zone->refreshkeytime = timethen; 7949 zone_settimer(zone, &timenow); 7950 7951 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 7952 dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s", 7953 timebuf); 7954 7955 if (!fetching) 7956 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); 7957 } 7958 7959 UNLOCK_ZONE(zone); 7960 7961 dns_diff_clear(&diff); 7962 if (ver != NULL) { 7963 dns_rriterator_destroy(&rrit); 7964 dns_db_closeversion(db, &ver, commit); 7965 } 7966 dns_db_detach(&db); 7967} 7968 7969static void 7970zone_maintenance(dns_zone_t *zone) { 7971 const char me[] = "zone_maintenance"; 7972 isc_time_t now; 7973 isc_result_t result; 7974 isc_boolean_t dumping; 7975 7976 REQUIRE(DNS_ZONE_VALID(zone)); 7977 ENTER; 7978 7979 /* 7980 * Configuring the view of this zone may have 7981 * failed, for example because the config file 7982 * had a syntax error. In that case, the view 7983 * db or resolver will be NULL, and we had better not try 7984 * to do maintenance on it. 7985 */ 7986 if (zone->view == NULL || zone->view->adb == NULL) 7987 return; 7988 7989 TIME_NOW(&now); 7990 7991 /* 7992 * Expire check. 7993 */ 7994 switch (zone->type) { 7995 case dns_zone_slave: 7996 case dns_zone_stub: 7997 LOCK_ZONE(zone); 7998 if (isc_time_compare(&now, &zone->expiretime) >= 0 && 7999 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 8000 zone_expire(zone); 8001 zone->refreshtime = now; 8002 } 8003 UNLOCK_ZONE(zone); 8004 break; 8005 default: 8006 break; 8007 } 8008 8009 /* 8010 * Up to date check. 8011 */ 8012 switch (zone->type) { 8013 case dns_zone_slave: 8014 case dns_zone_stub: 8015 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && 8016 isc_time_compare(&now, &zone->refreshtime) >= 0) 8017 dns_zone_refresh(zone); 8018 break; 8019 default: 8020 break; 8021 } 8022 8023 /* 8024 * Do we need to consolidate the backing store? 8025 */ 8026 switch (zone->type) { 8027 case dns_zone_master: 8028 case dns_zone_slave: 8029 case dns_zone_key: 8030 LOCK_ZONE(zone); 8031 if (zone->masterfile != NULL && 8032 isc_time_compare(&now, &zone->dumptime) >= 0 && 8033 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 8034 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) { 8035 dumping = was_dumping(zone); 8036 } else 8037 dumping = ISC_TRUE; 8038 UNLOCK_ZONE(zone); 8039 if (!dumping) { 8040 result = zone_dump(zone, ISC_TRUE); /* task locked */ 8041 if (result != ISC_R_SUCCESS) 8042 dns_zone_log(zone, ISC_LOG_WARNING, 8043 "dump failed: %s", 8044 dns_result_totext(result)); 8045 } 8046 break; 8047 default: 8048 break; 8049 } 8050 8051 /* 8052 * Do we need to refresh keys? 8053 */ 8054 switch (zone->type) { 8055 case dns_zone_key: 8056 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0 && 8057 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 8058 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) 8059 zone_refreshkeys(zone); 8060 break; 8061 case dns_zone_master: 8062 if (!isc_time_isepoch(&zone->refreshkeytime) && 8063 isc_time_compare(&now, &zone->refreshkeytime) >= 0) 8064 zone_rekey(zone); 8065 default: 8066 break; 8067 } 8068 8069 switch (zone->type) { 8070 case dns_zone_master: 8071 case dns_zone_slave: 8072 /* 8073 * Do we need to send out notify messages? 8074 */ 8075 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) && 8076 isc_time_compare(&now, &zone->notifytime) >= 0) 8077 zone_notify(zone, &now); 8078 /* 8079 * Do we need to sign/resign some RRsets? 8080 */ 8081 if (!isc_time_isepoch(&zone->signingtime) && 8082 isc_time_compare(&now, &zone->signingtime) >= 0) 8083 zone_sign(zone); 8084 else if (!isc_time_isepoch(&zone->resigntime) && 8085 isc_time_compare(&now, &zone->resigntime) >= 0) 8086 zone_resigninc(zone); 8087 else if (!isc_time_isepoch(&zone->nsec3chaintime) && 8088 isc_time_compare(&now, &zone->nsec3chaintime) >= 0) 8089 zone_nsec3chain(zone); 8090 /* 8091 * Do we need to issue a key expiry warning. 8092 */ 8093 if (!isc_time_isepoch(&zone->keywarntime) && 8094 isc_time_compare(&now, &zone->keywarntime) >= 0) 8095 set_key_expiry_warning(zone, zone->key_expiry, 8096 isc_time_seconds(&now)); 8097 break; 8098 default: 8099 break; 8100 } 8101 zone_settimer(zone, &now); 8102} 8103 8104void 8105dns_zone_markdirty(dns_zone_t *zone) { 8106 8107 LOCK_ZONE(zone); 8108 if (zone->type == dns_zone_master) 8109 set_resigntime(zone); /* XXXMPA make separate call back */ 8110 zone_needdump(zone, DNS_DUMP_DELAY); 8111 UNLOCK_ZONE(zone); 8112} 8113 8114void 8115dns_zone_expire(dns_zone_t *zone) { 8116 REQUIRE(DNS_ZONE_VALID(zone)); 8117 8118 LOCK_ZONE(zone); 8119 zone_expire(zone); 8120 UNLOCK_ZONE(zone); 8121} 8122 8123static void 8124zone_expire(dns_zone_t *zone) { 8125 /* 8126 * 'zone' locked by caller. 8127 */ 8128 8129 REQUIRE(LOCKED_ZONE(zone)); 8130 8131 dns_zone_log(zone, ISC_LOG_WARNING, "expired"); 8132 8133 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED); 8134 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 8135 zone->retry = DNS_ZONE_DEFAULTRETRY; 8136 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 8137 zone_unload(zone); 8138} 8139 8140void 8141dns_zone_refresh(dns_zone_t *zone) { 8142 isc_interval_t i; 8143 isc_uint32_t oldflags; 8144 unsigned int j; 8145 isc_result_t result; 8146 8147 REQUIRE(DNS_ZONE_VALID(zone)); 8148 8149 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 8150 return; 8151 8152 /* 8153 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation 8154 * in progress at a time. 8155 */ 8156 8157 LOCK_ZONE(zone); 8158 oldflags = zone->flags; 8159 if (zone->masterscnt == 0) { 8160 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS); 8161 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0) 8162 dns_zone_log(zone, ISC_LOG_ERROR, 8163 "cannot refresh: no masters"); 8164 goto unlock; 8165 } 8166 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 8167 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 8168 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 8169 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0) 8170 goto unlock; 8171 8172 /* 8173 * Set the next refresh time as if refresh check has failed. 8174 * Setting this to the retry time will do that. XXXMLG 8175 * If we are successful it will be reset using zone->refresh. 8176 */ 8177 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4), 8178 0); 8179 result = isc_time_nowplusinterval(&zone->refreshtime, &i); 8180 if (result != ISC_R_SUCCESS) 8181 dns_zone_log(zone, ISC_LOG_WARNING, 8182 "isc_time_nowplusinterval() failed: %s", 8183 dns_result_totext(result)); 8184 8185 /* 8186 * When lacking user-specified timer values from the SOA, 8187 * do exponential backoff of the retry time up to a 8188 * maximum of six hours. 8189 */ 8190 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) 8191 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600); 8192 8193 zone->curmaster = 0; 8194 for (j = 0; j < zone->masterscnt; j++) 8195 zone->mastersok[j] = ISC_FALSE; 8196 /* initiate soa query */ 8197 queue_soa_query(zone); 8198 unlock: 8199 UNLOCK_ZONE(zone); 8200} 8201 8202isc_result_t 8203dns_zone_flush(dns_zone_t *zone) { 8204 isc_result_t result = ISC_R_SUCCESS; 8205 isc_boolean_t dumping; 8206 8207 REQUIRE(DNS_ZONE_VALID(zone)); 8208 8209 LOCK_ZONE(zone); 8210 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH); 8211 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 8212 zone->masterfile != NULL) { 8213 result = ISC_R_ALREADYRUNNING; 8214 dumping = was_dumping(zone); 8215 } else 8216 dumping = ISC_TRUE; 8217 UNLOCK_ZONE(zone); 8218 if (!dumping) 8219 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */ 8220 return (result); 8221} 8222 8223isc_result_t 8224dns_zone_dump(dns_zone_t *zone) { 8225 isc_result_t result = ISC_R_ALREADYRUNNING; 8226 isc_boolean_t dumping; 8227 8228 REQUIRE(DNS_ZONE_VALID(zone)); 8229 8230 LOCK_ZONE(zone); 8231 dumping = was_dumping(zone); 8232 UNLOCK_ZONE(zone); 8233 if (!dumping) 8234 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */ 8235 return (result); 8236} 8237 8238static void 8239zone_needdump(dns_zone_t *zone, unsigned int delay) { 8240 isc_time_t dumptime; 8241 isc_time_t now; 8242 8243 /* 8244 * 'zone' locked by caller 8245 */ 8246 8247 REQUIRE(DNS_ZONE_VALID(zone)); 8248 REQUIRE(LOCKED_ZONE(zone)); 8249 8250 /* 8251 * Do we have a place to dump to and are we loaded? 8252 */ 8253 if (zone->masterfile == NULL || 8254 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) 8255 return; 8256 8257 TIME_NOW(&now); 8258 /* add some noise */ 8259 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime); 8260 8261 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 8262 if (isc_time_isepoch(&zone->dumptime) || 8263 isc_time_compare(&zone->dumptime, &dumptime) > 0) 8264 zone->dumptime = dumptime; 8265 if (zone->task != NULL) 8266 zone_settimer(zone, &now); 8267} 8268 8269static void 8270dump_done(void *arg, isc_result_t result) { 8271 const char me[] = "dump_done"; 8272 dns_zone_t *zone = arg; 8273 dns_db_t *db; 8274 dns_dbversion_t *version; 8275 isc_boolean_t again = ISC_FALSE; 8276 isc_boolean_t compact = ISC_FALSE; 8277 isc_uint32_t serial; 8278 isc_result_t tresult; 8279 8280 REQUIRE(DNS_ZONE_VALID(zone)); 8281 8282 ENTER; 8283 8284 if (result == ISC_R_SUCCESS && zone->journal != NULL && 8285 zone->journalsize != -1) { 8286 8287 /* 8288 * We don't own these, zone->dctx must stay valid. 8289 */ 8290 db = dns_dumpctx_db(zone->dctx); 8291 version = dns_dumpctx_version(zone->dctx); 8292 8293 tresult = dns_db_getsoaserial(db, version, &serial); 8294 /* 8295 * Note: we are task locked here so we can test 8296 * zone->xfr safely. 8297 */ 8298 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) { 8299 tresult = dns_journal_compact(zone->mctx, 8300 zone->journal, 8301 serial, 8302 zone->journalsize); 8303 switch (tresult) { 8304 case ISC_R_SUCCESS: 8305 case ISC_R_NOSPACE: 8306 case ISC_R_NOTFOUND: 8307 dns_zone_log(zone, ISC_LOG_DEBUG(3), 8308 "dns_journal_compact: %s", 8309 dns_result_totext(tresult)); 8310 break; 8311 default: 8312 dns_zone_log(zone, ISC_LOG_ERROR, 8313 "dns_journal_compact failed: %s", 8314 dns_result_totext(tresult)); 8315 break; 8316 } 8317 } else if (tresult == ISC_R_SUCCESS) { 8318 compact = ISC_TRUE; 8319 zone->compact_serial = serial; 8320 } 8321 } 8322 8323 LOCK_ZONE(zone); 8324 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 8325 if (compact) 8326 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 8327 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) { 8328 /* 8329 * Try again in a short while. 8330 */ 8331 zone_needdump(zone, DNS_DUMP_DELAY); 8332 } else if (result == ISC_R_SUCCESS && 8333 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 8334 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 8335 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 8336 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 8337 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 8338 isc_time_settoepoch(&zone->dumptime); 8339 again = ISC_TRUE; 8340 } else if (result == ISC_R_SUCCESS) 8341 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 8342 8343 if (zone->dctx != NULL) 8344 dns_dumpctx_detach(&zone->dctx); 8345 zonemgr_putio(&zone->writeio); 8346 UNLOCK_ZONE(zone); 8347 if (again) 8348 (void)zone_dump(zone, ISC_FALSE); 8349 dns_zone_idetach(&zone); 8350} 8351 8352static isc_result_t 8353zone_dump(dns_zone_t *zone, isc_boolean_t compact) { 8354 const char me[] = "zone_dump"; 8355 isc_result_t result; 8356 dns_dbversion_t *version = NULL; 8357 isc_boolean_t again; 8358 dns_db_t *db = NULL; 8359 char *masterfile = NULL; 8360 dns_masterformat_t masterformat = dns_masterformat_none; 8361 8362/* 8363 * 'compact' MUST only be set if we are task locked. 8364 */ 8365 8366 REQUIRE(DNS_ZONE_VALID(zone)); 8367 ENTER; 8368 8369 redo: 8370 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8371 if (zone->db != NULL) 8372 dns_db_attach(zone->db, &db); 8373 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8374 LOCK_ZONE(zone); 8375 if (zone->masterfile != NULL) { 8376 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile); 8377 masterformat = zone->masterformat; 8378 } 8379 UNLOCK_ZONE(zone); 8380 if (db == NULL) { 8381 result = DNS_R_NOTLOADED; 8382 goto fail; 8383 } 8384 if (masterfile == NULL) { 8385 result = DNS_R_NOMASTERFILE; 8386 goto fail; 8387 } 8388 8389 if (compact) { 8390 dns_zone_t *dummy = NULL; 8391 LOCK_ZONE(zone); 8392 zone_iattach(zone, &dummy); 8393 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task, 8394 zone_gotwritehandle, zone, 8395 &zone->writeio); 8396 if (result != ISC_R_SUCCESS) 8397 zone_idetach(&dummy); 8398 else 8399 result = DNS_R_CONTINUE; 8400 UNLOCK_ZONE(zone); 8401 } else { 8402 dns_db_currentversion(db, &version); 8403 result = dns_master_dump2(zone->mctx, db, version, 8404 &dns_master_style_default, 8405 masterfile, masterformat); 8406 dns_db_closeversion(db, &version, ISC_FALSE); 8407 } 8408 fail: 8409 if (db != NULL) 8410 dns_db_detach(&db); 8411 if (masterfile != NULL) 8412 isc_mem_free(zone->mctx, masterfile); 8413 masterfile = NULL; 8414 8415 if (result == DNS_R_CONTINUE) 8416 return (ISC_R_SUCCESS); /* XXXMPA */ 8417 8418 again = ISC_FALSE; 8419 LOCK_ZONE(zone); 8420 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING); 8421 if (result != ISC_R_SUCCESS) { 8422 /* 8423 * Try again in a short while. 8424 */ 8425 zone_needdump(zone, DNS_DUMP_DELAY); 8426 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) && 8427 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 8428 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 8429 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 8430 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING); 8431 isc_time_settoepoch(&zone->dumptime); 8432 again = ISC_TRUE; 8433 } else 8434 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH); 8435 UNLOCK_ZONE(zone); 8436 if (again) 8437 goto redo; 8438 8439 return (result); 8440} 8441 8442static isc_result_t 8443dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style, 8444 dns_masterformat_t format) 8445{ 8446 isc_result_t result; 8447 dns_dbversion_t *version = NULL; 8448 dns_db_t *db = NULL; 8449 8450 REQUIRE(DNS_ZONE_VALID(zone)); 8451 8452 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 8453 if (zone->db != NULL) 8454 dns_db_attach(zone->db, &db); 8455 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 8456 if (db == NULL) 8457 return (DNS_R_NOTLOADED); 8458 8459 dns_db_currentversion(db, &version); 8460 result = dns_master_dumptostream2(zone->mctx, db, version, style, 8461 format, fd); 8462 dns_db_closeversion(db, &version, ISC_FALSE); 8463 dns_db_detach(&db); 8464 return (result); 8465} 8466 8467isc_result_t 8468dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, 8469 const dns_master_style_t *style) { 8470 return dumptostream(zone, fd, style, format); 8471} 8472 8473isc_result_t 8474dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) { 8475 return dumptostream(zone, fd, &dns_master_style_default, 8476 dns_masterformat_text); 8477} 8478 8479isc_result_t 8480dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) { 8481 return dumptostream(zone, fd, &dns_master_style_full, 8482 dns_masterformat_text); 8483} 8484 8485void 8486dns_zone_unload(dns_zone_t *zone) { 8487 REQUIRE(DNS_ZONE_VALID(zone)); 8488 8489 LOCK_ZONE(zone); 8490 zone_unload(zone); 8491 UNLOCK_ZONE(zone); 8492} 8493 8494static void 8495notify_cancel(dns_zone_t *zone) { 8496 dns_notify_t *notify; 8497 8498 /* 8499 * 'zone' locked by caller. 8500 */ 8501 8502 REQUIRE(LOCKED_ZONE(zone)); 8503 8504 for (notify = ISC_LIST_HEAD(zone->notifies); 8505 notify != NULL; 8506 notify = ISC_LIST_NEXT(notify, link)) { 8507 if (notify->find != NULL) 8508 dns_adb_cancelfind(notify->find); 8509 if (notify->request != NULL) 8510 dns_request_cancel(notify->request); 8511 } 8512} 8513 8514static void 8515forward_cancel(dns_zone_t *zone) { 8516 dns_forward_t *forward; 8517 8518 /* 8519 * 'zone' locked by caller. 8520 */ 8521 8522 REQUIRE(LOCKED_ZONE(zone)); 8523 8524 for (forward = ISC_LIST_HEAD(zone->forwards); 8525 forward != NULL; 8526 forward = ISC_LIST_NEXT(forward, link)) { 8527 if (forward->request != NULL) 8528 dns_request_cancel(forward->request); 8529 } 8530} 8531 8532static void 8533zone_unload(dns_zone_t *zone) { 8534 8535 /* 8536 * 'zone' locked by caller. 8537 */ 8538 8539 REQUIRE(LOCKED_ZONE(zone)); 8540 8541 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 8542 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 8543 if (zone->writeio != NULL) 8544 zonemgr_cancelio(zone->writeio); 8545 8546 if (zone->dctx != NULL) 8547 dns_dumpctx_cancel(zone->dctx); 8548 } 8549 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 8550 zone_detachdb(zone); 8551 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 8552 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED); 8553 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); 8554} 8555 8556void 8557dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) { 8558 REQUIRE(DNS_ZONE_VALID(zone)); 8559 REQUIRE(val > 0); 8560 8561 zone->minrefresh = val; 8562} 8563 8564void 8565dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) { 8566 REQUIRE(DNS_ZONE_VALID(zone)); 8567 REQUIRE(val > 0); 8568 8569 zone->maxrefresh = val; 8570} 8571 8572void 8573dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) { 8574 REQUIRE(DNS_ZONE_VALID(zone)); 8575 REQUIRE(val > 0); 8576 8577 zone->minretry = val; 8578} 8579 8580void 8581dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) { 8582 REQUIRE(DNS_ZONE_VALID(zone)); 8583 REQUIRE(val > 0); 8584 8585 zone->maxretry = val; 8586} 8587 8588static isc_boolean_t 8589notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) { 8590 dns_notify_t *notify; 8591 8592 for (notify = ISC_LIST_HEAD(zone->notifies); 8593 notify != NULL; 8594 notify = ISC_LIST_NEXT(notify, link)) { 8595 if (notify->request != NULL) 8596 continue; 8597 if (name != NULL && dns_name_dynamic(¬ify->ns) && 8598 dns_name_equal(name, ¬ify->ns)) 8599 return (ISC_TRUE); 8600 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst)) 8601 return (ISC_TRUE); 8602 } 8603 return (ISC_FALSE); 8604} 8605 8606static isc_boolean_t 8607notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) { 8608 dns_tsigkey_t *key = NULL; 8609 isc_sockaddr_t src; 8610 isc_sockaddr_t any; 8611 isc_boolean_t isself; 8612 isc_netaddr_t dstaddr; 8613 isc_result_t result; 8614 8615 if (zone->view == NULL || zone->isself == NULL) 8616 return (ISC_FALSE); 8617 8618 switch (isc_sockaddr_pf(dst)) { 8619 case PF_INET: 8620 src = zone->notifysrc4; 8621 isc_sockaddr_any(&any); 8622 break; 8623 case PF_INET6: 8624 src = zone->notifysrc6; 8625 isc_sockaddr_any6(&any); 8626 break; 8627 default: 8628 return (ISC_FALSE); 8629 } 8630 8631 /* 8632 * When sending from any the kernel will assign a source address 8633 * that matches the destination address. 8634 */ 8635 if (isc_sockaddr_eqaddr(&any, &src)) 8636 src = *dst; 8637 8638 isc_netaddr_fromsockaddr(&dstaddr, dst); 8639 result = dns_view_getpeertsig(zone->view, &dstaddr, &key); 8640 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) 8641 return (ISC_FALSE); 8642 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass, 8643 zone->isselfarg); 8644 if (key != NULL) 8645 dns_tsigkey_detach(&key); 8646 return (isself); 8647} 8648 8649static void 8650notify_destroy(dns_notify_t *notify, isc_boolean_t locked) { 8651 isc_mem_t *mctx; 8652 8653 /* 8654 * Caller holds zone lock. 8655 */ 8656 REQUIRE(DNS_NOTIFY_VALID(notify)); 8657 8658 if (notify->zone != NULL) { 8659 if (!locked) 8660 LOCK_ZONE(notify->zone); 8661 REQUIRE(LOCKED_ZONE(notify->zone)); 8662 if (ISC_LINK_LINKED(notify, link)) 8663 ISC_LIST_UNLINK(notify->zone->notifies, notify, link); 8664 if (!locked) 8665 UNLOCK_ZONE(notify->zone); 8666 if (locked) 8667 zone_idetach(¬ify->zone); 8668 else 8669 dns_zone_idetach(¬ify->zone); 8670 } 8671 if (notify->find != NULL) 8672 dns_adb_destroyfind(¬ify->find); 8673 if (notify->request != NULL) 8674 dns_request_destroy(¬ify->request); 8675 if (dns_name_dynamic(¬ify->ns)) 8676 dns_name_free(¬ify->ns, notify->mctx); 8677 mctx = notify->mctx; 8678 isc_mem_put(notify->mctx, notify, sizeof(*notify)); 8679 isc_mem_detach(&mctx); 8680} 8681 8682static isc_result_t 8683notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) { 8684 dns_notify_t *notify; 8685 8686 REQUIRE(notifyp != NULL && *notifyp == NULL); 8687 8688 notify = isc_mem_get(mctx, sizeof(*notify)); 8689 if (notify == NULL) 8690 return (ISC_R_NOMEMORY); 8691 8692 notify->mctx = NULL; 8693 isc_mem_attach(mctx, ¬ify->mctx); 8694 notify->flags = flags; 8695 notify->zone = NULL; 8696 notify->find = NULL; 8697 notify->request = NULL; 8698 isc_sockaddr_any(¬ify->dst); 8699 dns_name_init(¬ify->ns, NULL); 8700 ISC_LINK_INIT(notify, link); 8701 notify->magic = NOTIFY_MAGIC; 8702 *notifyp = notify; 8703 return (ISC_R_SUCCESS); 8704} 8705 8706/* 8707 * XXXAG should check for DNS_ZONEFLG_EXITING 8708 */ 8709static void 8710process_adb_event(isc_task_t *task, isc_event_t *ev) { 8711 dns_notify_t *notify; 8712 isc_eventtype_t result; 8713 8714 UNUSED(task); 8715 8716 notify = ev->ev_arg; 8717 REQUIRE(DNS_NOTIFY_VALID(notify)); 8718 INSIST(task == notify->zone->task); 8719 result = ev->ev_type; 8720 isc_event_free(&ev); 8721 if (result == DNS_EVENT_ADBMOREADDRESSES) { 8722 dns_adb_destroyfind(¬ify->find); 8723 notify_find_address(notify); 8724 return; 8725 } 8726 if (result == DNS_EVENT_ADBNOMOREADDRESSES) { 8727 LOCK_ZONE(notify->zone); 8728 notify_send(notify); 8729 UNLOCK_ZONE(notify->zone); 8730 } 8731 notify_destroy(notify, ISC_FALSE); 8732} 8733 8734static void 8735notify_find_address(dns_notify_t *notify) { 8736 isc_result_t result; 8737 unsigned int options; 8738 8739 REQUIRE(DNS_NOTIFY_VALID(notify)); 8740 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET | 8741 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME; 8742 8743 if (notify->zone->view->adb == NULL) 8744 goto destroy; 8745 8746 result = dns_adb_createfind(notify->zone->view->adb, 8747 notify->zone->task, 8748 process_adb_event, notify, 8749 ¬ify->ns, dns_rootname, 0, 8750 options, 0, NULL, 8751 notify->zone->view->dstport, 8752 ¬ify->find); 8753 8754 /* Something failed? */ 8755 if (result != ISC_R_SUCCESS) 8756 goto destroy; 8757 8758 /* More addresses pending? */ 8759 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) 8760 return; 8761 8762 /* We have as many addresses as we can get. */ 8763 LOCK_ZONE(notify->zone); 8764 notify_send(notify); 8765 UNLOCK_ZONE(notify->zone); 8766 8767 destroy: 8768 notify_destroy(notify, ISC_FALSE); 8769} 8770 8771 8772static isc_result_t 8773notify_send_queue(dns_notify_t *notify) { 8774 isc_event_t *e; 8775 isc_result_t result; 8776 8777 e = isc_event_allocate(notify->mctx, NULL, 8778 DNS_EVENT_NOTIFYSENDTOADDR, 8779 notify_send_toaddr, 8780 notify, sizeof(isc_event_t)); 8781 if (e == NULL) 8782 return (ISC_R_NOMEMORY); 8783 e->ev_arg = notify; 8784 e->ev_sender = NULL; 8785 result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl, 8786 notify->zone->task, &e); 8787 if (result != ISC_R_SUCCESS) 8788 isc_event_free(&e); 8789 return (result); 8790} 8791 8792static void 8793notify_send_toaddr(isc_task_t *task, isc_event_t *event) { 8794 dns_notify_t *notify; 8795 isc_result_t result; 8796 dns_message_t *message = NULL; 8797 isc_netaddr_t dstip; 8798 dns_tsigkey_t *key = NULL; 8799 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 8800 isc_sockaddr_t src; 8801 int timeout; 8802 isc_boolean_t have_notifysource = ISC_FALSE; 8803 8804 notify = event->ev_arg; 8805 REQUIRE(DNS_NOTIFY_VALID(notify)); 8806 8807 UNUSED(task); 8808 8809 LOCK_ZONE(notify->zone); 8810 8811 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) { 8812 result = ISC_R_CANCELED; 8813 goto cleanup; 8814 } 8815 8816 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 || 8817 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) || 8818 notify->zone->view->requestmgr == NULL || 8819 notify->zone->db == NULL) { 8820 result = ISC_R_CANCELED; 8821 goto cleanup; 8822 } 8823 8824 /* 8825 * The raw IPv4 address should also exist. Don't send to the 8826 * mapped form. 8827 */ 8828 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 && 8829 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) { 8830 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 8831 notify_log(notify->zone, ISC_LOG_DEBUG(3), 8832 "notify: ignoring IPv6 mapped IPV4 address: %s", 8833 addrbuf); 8834 result = ISC_R_CANCELED; 8835 goto cleanup; 8836 } 8837 8838 result = notify_createmessage(notify->zone, notify->flags, &message); 8839 if (result != ISC_R_SUCCESS) 8840 goto cleanup; 8841 8842 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst); 8843 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 8844 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key); 8845 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 8846 notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not " 8847 "sent. Peer TSIG key lookup failure.", addrbuf); 8848 goto cleanup_message; 8849 } 8850 8851 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s", 8852 addrbuf); 8853 if (notify->zone->view->peers != NULL) { 8854 dns_peer_t *peer = NULL; 8855 result = dns_peerlist_peerbyaddr(notify->zone->view->peers, 8856 &dstip, &peer); 8857 if (result == ISC_R_SUCCESS) { 8858 result = dns_peer_getnotifysource(peer, &src); 8859 if (result == ISC_R_SUCCESS) 8860 have_notifysource = ISC_TRUE; 8861 } 8862 } 8863 switch (isc_sockaddr_pf(¬ify->dst)) { 8864 case PF_INET: 8865 if (!have_notifysource) 8866 src = notify->zone->notifysrc4; 8867 break; 8868 case PF_INET6: 8869 if (!have_notifysource) 8870 src = notify->zone->notifysrc6; 8871 break; 8872 default: 8873 result = ISC_R_NOTIMPLEMENTED; 8874 goto cleanup_key; 8875 } 8876 timeout = 15; 8877 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) 8878 timeout = 30; 8879 result = dns_request_createvia2(notify->zone->view->requestmgr, 8880 message, &src, ¬ify->dst, 0, key, 8881 timeout * 3, timeout, 8882 notify->zone->task, notify_done, 8883 notify, ¬ify->request); 8884 if (result == ISC_R_SUCCESS) { 8885 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) { 8886 inc_stats(notify->zone, 8887 dns_zonestatscounter_notifyoutv4); 8888 } else { 8889 inc_stats(notify->zone, 8890 dns_zonestatscounter_notifyoutv6); 8891 } 8892 } 8893 8894 cleanup_key: 8895 if (key != NULL) 8896 dns_tsigkey_detach(&key); 8897 cleanup_message: 8898 dns_message_destroy(&message); 8899 cleanup: 8900 UNLOCK_ZONE(notify->zone); 8901 if (result != ISC_R_SUCCESS) 8902 notify_destroy(notify, ISC_FALSE); 8903 isc_event_free(&event); 8904} 8905 8906static void 8907notify_send(dns_notify_t *notify) { 8908 dns_adbaddrinfo_t *ai; 8909 isc_sockaddr_t dst; 8910 isc_result_t result; 8911 dns_notify_t *new = NULL; 8912 8913 /* 8914 * Zone lock held by caller. 8915 */ 8916 REQUIRE(DNS_NOTIFY_VALID(notify)); 8917 REQUIRE(LOCKED_ZONE(notify->zone)); 8918 8919 for (ai = ISC_LIST_HEAD(notify->find->list); 8920 ai != NULL; 8921 ai = ISC_LIST_NEXT(ai, publink)) { 8922 dst = ai->sockaddr; 8923 if (notify_isqueued(notify->zone, NULL, &dst)) 8924 continue; 8925 if (notify_isself(notify->zone, &dst)) 8926 continue; 8927 new = NULL; 8928 result = notify_create(notify->mctx, 8929 (notify->flags & DNS_NOTIFY_NOSOA), 8930 &new); 8931 if (result != ISC_R_SUCCESS) 8932 goto cleanup; 8933 zone_iattach(notify->zone, &new->zone); 8934 ISC_LIST_APPEND(new->zone->notifies, new, link); 8935 new->dst = dst; 8936 result = notify_send_queue(new); 8937 if (result != ISC_R_SUCCESS) 8938 goto cleanup; 8939 new = NULL; 8940 } 8941 8942 cleanup: 8943 if (new != NULL) 8944 notify_destroy(new, ISC_TRUE); 8945} 8946 8947void 8948dns_zone_notify(dns_zone_t *zone) { 8949 isc_time_t now; 8950 8951 REQUIRE(DNS_ZONE_VALID(zone)); 8952 8953 LOCK_ZONE(zone); 8954 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 8955 8956 TIME_NOW(&now); 8957 zone_settimer(zone, &now); 8958 UNLOCK_ZONE(zone); 8959} 8960 8961static void 8962zone_notify(dns_zone_t *zone, isc_time_t *now) { 8963 dns_dbnode_t *node = NULL; 8964 dns_db_t *zonedb = NULL; 8965 dns_dbversion_t *version = NULL; 8966 dns_name_t *origin = NULL; 8967 dns_name_t master; 8968 dns_rdata_ns_t ns; 8969 dns_rdata_soa_t soa; 8970 isc_uint32_t serial; 8971 dns_rdata_t rdata = DNS_RDATA_INIT; 8972 dns_rdataset_t nsrdset; 8973 dns_rdataset_t soardset; 8974 isc_result_t result; 8975 dns_notify_t *notify = NULL; 8976 unsigned int i; 8977 isc_sockaddr_t dst; 8978 isc_boolean_t isqueued; 8979 dns_notifytype_t notifytype; 8980 unsigned int flags = 0; 8981 isc_boolean_t loggednotify = ISC_FALSE; 8982 8983 REQUIRE(DNS_ZONE_VALID(zone)); 8984 8985 LOCK_ZONE(zone); 8986 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 8987 notifytype = zone->notifytype; 8988 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime); 8989 UNLOCK_ZONE(zone); 8990 8991 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) 8992 return; 8993 8994 if (notifytype == dns_notifytype_no) 8995 return; 8996 8997 if (notifytype == dns_notifytype_masteronly && 8998 zone->type != dns_zone_master) 8999 return; 9000 9001 origin = &zone->origin; 9002 9003 /* 9004 * If the zone is dialup we are done as we don't want to send 9005 * the current soa so as to force a refresh query. 9006 */ 9007 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) 9008 flags |= DNS_NOTIFY_NOSOA; 9009 9010 /* 9011 * Get SOA RRset. 9012 */ 9013 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 9014 if (zone->db != NULL) 9015 dns_db_attach(zone->db, &zonedb); 9016 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 9017 if (zonedb == NULL) 9018 return; 9019 dns_db_currentversion(zonedb, &version); 9020 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node); 9021 if (result != ISC_R_SUCCESS) 9022 goto cleanup1; 9023 9024 dns_rdataset_init(&soardset); 9025 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, 9026 dns_rdatatype_none, 0, &soardset, NULL); 9027 if (result != ISC_R_SUCCESS) 9028 goto cleanup2; 9029 9030 /* 9031 * Find serial and master server's name. 9032 */ 9033 dns_name_init(&master, NULL); 9034 result = dns_rdataset_first(&soardset); 9035 if (result != ISC_R_SUCCESS) 9036 goto cleanup3; 9037 dns_rdataset_current(&soardset, &rdata); 9038 result = dns_rdata_tostruct(&rdata, &soa, NULL); 9039 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9040 dns_rdata_reset(&rdata); 9041 result = dns_name_dup(&soa.origin, zone->mctx, &master); 9042 serial = soa.serial; 9043 dns_rdataset_disassociate(&soardset); 9044 if (result != ISC_R_SUCCESS) 9045 goto cleanup3; 9046 9047 /* 9048 * Enqueue notify requests for 'also-notify' servers. 9049 */ 9050 LOCK_ZONE(zone); 9051 for (i = 0; i < zone->notifycnt; i++) { 9052 dst = zone->notify[i]; 9053 if (notify_isqueued(zone, NULL, &dst)) 9054 continue; 9055 result = notify_create(zone->mctx, flags, ¬ify); 9056 if (result != ISC_R_SUCCESS) 9057 continue; 9058 zone_iattach(zone, ¬ify->zone); 9059 notify->dst = dst; 9060 ISC_LIST_APPEND(zone->notifies, notify, link); 9061 result = notify_send_queue(notify); 9062 if (result != ISC_R_SUCCESS) 9063 notify_destroy(notify, ISC_TRUE); 9064 if (!loggednotify) { 9065 notify_log(zone, ISC_LOG_INFO, 9066 "sending notifies (serial %u)", 9067 serial); 9068 loggednotify = ISC_TRUE; 9069 } 9070 notify = NULL; 9071 } 9072 UNLOCK_ZONE(zone); 9073 9074 if (notifytype == dns_notifytype_explicit) 9075 goto cleanup3; 9076 9077 /* 9078 * Process NS RRset to generate notifies. 9079 */ 9080 9081 dns_rdataset_init(&nsrdset); 9082 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns, 9083 dns_rdatatype_none, 0, &nsrdset, NULL); 9084 if (result != ISC_R_SUCCESS) 9085 goto cleanup3; 9086 9087 result = dns_rdataset_first(&nsrdset); 9088 while (result == ISC_R_SUCCESS) { 9089 dns_rdataset_current(&nsrdset, &rdata); 9090 result = dns_rdata_tostruct(&rdata, &ns, NULL); 9091 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9092 dns_rdata_reset(&rdata); 9093 /* 9094 * Don't notify the master server unless explicitly 9095 * configured to do so. 9096 */ 9097 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) && 9098 dns_name_compare(&master, &ns.name) == 0) { 9099 result = dns_rdataset_next(&nsrdset); 9100 continue; 9101 } 9102 9103 if (!loggednotify) { 9104 notify_log(zone, ISC_LOG_INFO, 9105 "sending notifies (serial %u)", 9106 serial); 9107 loggednotify = ISC_TRUE; 9108 } 9109 9110 LOCK_ZONE(zone); 9111 isqueued = notify_isqueued(zone, &ns.name, NULL); 9112 UNLOCK_ZONE(zone); 9113 if (isqueued) { 9114 result = dns_rdataset_next(&nsrdset); 9115 continue; 9116 } 9117 result = notify_create(zone->mctx, flags, ¬ify); 9118 if (result != ISC_R_SUCCESS) 9119 continue; 9120 dns_zone_iattach(zone, ¬ify->zone); 9121 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns); 9122 if (result != ISC_R_SUCCESS) { 9123 LOCK_ZONE(zone); 9124 notify_destroy(notify, ISC_TRUE); 9125 UNLOCK_ZONE(zone); 9126 continue; 9127 } 9128 LOCK_ZONE(zone); 9129 ISC_LIST_APPEND(zone->notifies, notify, link); 9130 UNLOCK_ZONE(zone); 9131 notify_find_address(notify); 9132 notify = NULL; 9133 result = dns_rdataset_next(&nsrdset); 9134 } 9135 dns_rdataset_disassociate(&nsrdset); 9136 9137 cleanup3: 9138 if (dns_name_dynamic(&master)) 9139 dns_name_free(&master, zone->mctx); 9140 cleanup2: 9141 dns_db_detachnode(zonedb, &node); 9142 cleanup1: 9143 dns_db_closeversion(zonedb, &version, ISC_FALSE); 9144 dns_db_detach(&zonedb); 9145} 9146 9147/*** 9148 *** Private 9149 ***/ 9150 9151static inline isc_result_t 9152save_nsrrset(dns_message_t *message, dns_name_t *name, 9153 dns_db_t *db, dns_dbversion_t *version) 9154{ 9155 dns_rdataset_t *nsrdataset = NULL; 9156 dns_rdataset_t *rdataset = NULL; 9157 dns_dbnode_t *node = NULL; 9158 dns_rdata_ns_t ns; 9159 isc_result_t result; 9160 dns_rdata_t rdata = DNS_RDATA_INIT; 9161 9162 /* 9163 * Extract NS RRset from message. 9164 */ 9165 result = dns_message_findname(message, DNS_SECTION_ANSWER, name, 9166 dns_rdatatype_ns, dns_rdatatype_none, 9167 NULL, &nsrdataset); 9168 if (result != ISC_R_SUCCESS) 9169 goto fail; 9170 9171 /* 9172 * Add NS rdataset. 9173 */ 9174 result = dns_db_findnode(db, name, ISC_TRUE, &node); 9175 if (result != ISC_R_SUCCESS) 9176 goto fail; 9177 result = dns_db_addrdataset(db, node, version, 0, 9178 nsrdataset, 0, NULL); 9179 dns_db_detachnode(db, &node); 9180 if (result != ISC_R_SUCCESS) 9181 goto fail; 9182 /* 9183 * Add glue rdatasets. 9184 */ 9185 for (result = dns_rdataset_first(nsrdataset); 9186 result == ISC_R_SUCCESS; 9187 result = dns_rdataset_next(nsrdataset)) { 9188 dns_rdataset_current(nsrdataset, &rdata); 9189 result = dns_rdata_tostruct(&rdata, &ns, NULL); 9190 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9191 dns_rdata_reset(&rdata); 9192 if (!dns_name_issubdomain(&ns.name, name)) 9193 continue; 9194 rdataset = NULL; 9195 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL, 9196 &ns.name, dns_rdatatype_aaaa, 9197 dns_rdatatype_none, NULL, 9198 &rdataset); 9199 if (result == ISC_R_SUCCESS) { 9200 result = dns_db_findnode(db, &ns.name, 9201 ISC_TRUE, &node); 9202 if (result != ISC_R_SUCCESS) 9203 goto fail; 9204 result = dns_db_addrdataset(db, node, version, 0, 9205 rdataset, 0, NULL); 9206 dns_db_detachnode(db, &node); 9207 if (result != ISC_R_SUCCESS) 9208 goto fail; 9209 } 9210 rdataset = NULL; 9211 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL, 9212 &ns.name, dns_rdatatype_a, 9213 dns_rdatatype_none, NULL, 9214 &rdataset); 9215 if (result == ISC_R_SUCCESS) { 9216 result = dns_db_findnode(db, &ns.name, 9217 ISC_TRUE, &node); 9218 if (result != ISC_R_SUCCESS) 9219 goto fail; 9220 result = dns_db_addrdataset(db, node, version, 0, 9221 rdataset, 0, NULL); 9222 dns_db_detachnode(db, &node); 9223 if (result != ISC_R_SUCCESS) 9224 goto fail; 9225 } 9226 } 9227 if (result != ISC_R_NOMORE) 9228 goto fail; 9229 9230 return (ISC_R_SUCCESS); 9231 9232fail: 9233 return (result); 9234} 9235 9236static void 9237stub_callback(isc_task_t *task, isc_event_t *event) { 9238 const char me[] = "stub_callback"; 9239 dns_requestevent_t *revent = (dns_requestevent_t *)event; 9240 dns_stub_t *stub = NULL; 9241 dns_message_t *msg = NULL; 9242 dns_zone_t *zone = NULL; 9243 char master[ISC_SOCKADDR_FORMATSIZE]; 9244 char source[ISC_SOCKADDR_FORMATSIZE]; 9245 isc_uint32_t nscnt, cnamecnt; 9246 isc_result_t result; 9247 isc_time_t now; 9248 isc_boolean_t exiting = ISC_FALSE; 9249 isc_interval_t i; 9250 unsigned int j; 9251 9252 stub = revent->ev_arg; 9253 INSIST(DNS_STUB_VALID(stub)); 9254 9255 UNUSED(task); 9256 9257 zone = stub->zone; 9258 9259 ENTER; 9260 9261 TIME_NOW(&now); 9262 9263 LOCK_ZONE(zone); 9264 9265 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 9266 zone_debuglog(zone, me, 1, "exiting"); 9267 exiting = ISC_TRUE; 9268 goto next_master; 9269 } 9270 9271 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 9272 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 9273 9274 if (revent->result != ISC_R_SUCCESS) { 9275 if (revent->result == ISC_R_TIMEDOUT && 9276 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 9277 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 9278 dns_zone_log(zone, ISC_LOG_DEBUG(1), 9279 "refreshing stub: timeout retrying " 9280 " without EDNS master %s (source %s)", 9281 master, source); 9282 goto same_master; 9283 } 9284 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr, 9285 &zone->sourceaddr, &now); 9286 dns_zone_log(zone, ISC_LOG_INFO, 9287 "could not refresh stub from master %s" 9288 " (source %s): %s", master, source, 9289 dns_result_totext(revent->result)); 9290 goto next_master; 9291 } 9292 9293 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 9294 if (result != ISC_R_SUCCESS) 9295 goto next_master; 9296 9297 result = dns_request_getresponse(revent->request, msg, 0); 9298 if (result != ISC_R_SUCCESS) 9299 goto next_master; 9300 9301 /* 9302 * Unexpected rcode. 9303 */ 9304 if (msg->rcode != dns_rcode_noerror) { 9305 char rcode[128]; 9306 isc_buffer_t rb; 9307 9308 isc_buffer_init(&rb, rcode, sizeof(rcode)); 9309 (void)dns_rcode_totext(msg->rcode, &rb); 9310 9311 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 9312 (msg->rcode == dns_rcode_servfail || 9313 msg->rcode == dns_rcode_notimp || 9314 msg->rcode == dns_rcode_formerr)) { 9315 dns_zone_log(zone, ISC_LOG_DEBUG(1), 9316 "refreshing stub: rcode (%.*s) retrying " 9317 "without EDNS master %s (source %s)", 9318 (int)rb.used, rcode, master, source); 9319 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 9320 goto same_master; 9321 } 9322 9323 dns_zone_log(zone, ISC_LOG_INFO, 9324 "refreshing stub: " 9325 "unexpected rcode (%.*s) from %s (source %s)", 9326 (int)rb.used, rcode, master, source); 9327 goto next_master; 9328 } 9329 9330 /* 9331 * We need complete messages. 9332 */ 9333 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 9334 if (dns_request_usedtcp(revent->request)) { 9335 dns_zone_log(zone, ISC_LOG_INFO, 9336 "refreshing stub: truncated TCP " 9337 "response from master %s (source %s)", 9338 master, source); 9339 goto next_master; 9340 } 9341 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 9342 goto same_master; 9343 } 9344 9345 /* 9346 * If non-auth log and next master. 9347 */ 9348 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 9349 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " 9350 "non-authoritative answer from " 9351 "master %s (source %s)", master, source); 9352 goto next_master; 9353 } 9354 9355 /* 9356 * Sanity checks. 9357 */ 9358 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 9359 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns); 9360 9361 if (cnamecnt != 0) { 9362 dns_zone_log(zone, ISC_LOG_INFO, 9363 "refreshing stub: unexpected CNAME response " 9364 "from master %s (source %s)", master, source); 9365 goto next_master; 9366 } 9367 9368 if (nscnt == 0) { 9369 dns_zone_log(zone, ISC_LOG_INFO, 9370 "refreshing stub: no NS records in response " 9371 "from master %s (source %s)", master, source); 9372 goto next_master; 9373 } 9374 9375 /* 9376 * Save answer. 9377 */ 9378 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version); 9379 if (result != ISC_R_SUCCESS) { 9380 dns_zone_log(zone, ISC_LOG_INFO, 9381 "refreshing stub: unable to save NS records " 9382 "from master %s (source %s)", master, source); 9383 goto next_master; 9384 } 9385 9386 /* 9387 * Tidy up. 9388 */ 9389 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE); 9390 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 9391 if (zone->db == NULL) 9392 zone_attachdb(zone, stub->db); 9393 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 9394 dns_db_detach(&stub->db); 9395 9396 if (zone->masterfile != NULL) 9397 zone_needdump(zone, 0); 9398 9399 dns_message_destroy(&msg); 9400 isc_event_free(&event); 9401 dns_request_destroy(&zone->request); 9402 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 9403 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 9404 isc_interval_set(&i, zone->expire, 0); 9405 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); 9406 zone_settimer(zone, &now); 9407 goto free_stub; 9408 9409 next_master: 9410 if (stub->version != NULL) 9411 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE); 9412 if (stub->db != NULL) 9413 dns_db_detach(&stub->db); 9414 if (msg != NULL) 9415 dns_message_destroy(&msg); 9416 isc_event_free(&event); 9417 dns_request_destroy(&zone->request); 9418 /* 9419 * Skip to next failed / untried master. 9420 */ 9421 do { 9422 zone->curmaster++; 9423 } while (zone->curmaster < zone->masterscnt && 9424 zone->mastersok[zone->curmaster]); 9425 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 9426 if (exiting || zone->curmaster >= zone->masterscnt) { 9427 isc_boolean_t done = ISC_TRUE; 9428 if (!exiting && 9429 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 9430 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 9431 /* 9432 * Did we get a good answer from all the masters? 9433 */ 9434 for (j = 0; j < zone->masterscnt; j++) 9435 if (zone->mastersok[j] == ISC_FALSE) { 9436 done = ISC_FALSE; 9437 break; 9438 } 9439 } else 9440 done = ISC_TRUE; 9441 if (!done) { 9442 zone->curmaster = 0; 9443 /* 9444 * Find the next failed master. 9445 */ 9446 while (zone->curmaster < zone->masterscnt && 9447 zone->mastersok[zone->curmaster]) 9448 zone->curmaster++; 9449 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 9450 } else { 9451 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 9452 9453 zone_settimer(zone, &now); 9454 goto free_stub; 9455 } 9456 } 9457 queue_soa_query(zone); 9458 goto free_stub; 9459 9460 same_master: 9461 if (msg != NULL) 9462 dns_message_destroy(&msg); 9463 isc_event_free(&event); 9464 dns_request_destroy(&zone->request); 9465 ns_query(zone, NULL, stub); 9466 UNLOCK_ZONE(zone); 9467 goto done; 9468 9469 free_stub: 9470 UNLOCK_ZONE(zone); 9471 stub->magic = 0; 9472 dns_zone_idetach(&stub->zone); 9473 INSIST(stub->db == NULL); 9474 INSIST(stub->version == NULL); 9475 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 9476 9477 done: 9478 INSIST(event == NULL); 9479 return; 9480} 9481 9482/* 9483 * An SOA query has finished (successfully or not). 9484 */ 9485static void 9486refresh_callback(isc_task_t *task, isc_event_t *event) { 9487 const char me[] = "refresh_callback"; 9488 dns_requestevent_t *revent = (dns_requestevent_t *)event; 9489 dns_zone_t *zone; 9490 dns_message_t *msg = NULL; 9491 isc_uint32_t soacnt, cnamecnt, soacount, nscount; 9492 isc_time_t now; 9493 char master[ISC_SOCKADDR_FORMATSIZE]; 9494 char source[ISC_SOCKADDR_FORMATSIZE]; 9495 dns_rdataset_t *rdataset = NULL; 9496 dns_rdata_t rdata = DNS_RDATA_INIT; 9497 dns_rdata_soa_t soa; 9498 isc_result_t result; 9499 isc_uint32_t serial, oldserial = 0; 9500 unsigned int j; 9501 isc_boolean_t do_queue_xfrin = ISC_FALSE; 9502 9503 zone = revent->ev_arg; 9504 INSIST(DNS_ZONE_VALID(zone)); 9505 9506 UNUSED(task); 9507 9508 ENTER; 9509 9510 TIME_NOW(&now); 9511 9512 LOCK_ZONE(zone); 9513 9514 /* 9515 * if timeout log and next master; 9516 */ 9517 9518 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 9519 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 9520 9521 if (revent->result != ISC_R_SUCCESS) { 9522 if (revent->result == ISC_R_TIMEDOUT && 9523 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 9524 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 9525 dns_zone_log(zone, ISC_LOG_DEBUG(1), 9526 "refresh: timeout retrying without EDNS " 9527 "master %s (source %s)", master, source); 9528 goto same_master; 9529 } 9530 if (revent->result == ISC_R_TIMEDOUT && 9531 !dns_request_usedtcp(revent->request)) { 9532 dns_zone_log(zone, ISC_LOG_INFO, 9533 "refresh: retry limit for " 9534 "master %s exceeded (source %s)", 9535 master, source); 9536 /* Try with slave with TCP. */ 9537 if (zone->type == dns_zone_slave && 9538 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) { 9539 if (!dns_zonemgr_unreachable(zone->zmgr, 9540 &zone->masteraddr, 9541 &zone->sourceaddr, 9542 &now)) 9543 { 9544 DNS_ZONE_SETFLAG(zone, 9545 DNS_ZONEFLG_SOABEFOREAXFR); 9546 goto tcp_transfer; 9547 } 9548 dns_zone_log(zone, ISC_LOG_DEBUG(1), 9549 "refresh: skipped tcp fallback " 9550 "as master %s (source %s) is " 9551 "unreachable (cached)", 9552 master, source); 9553 } 9554 } else 9555 dns_zone_log(zone, ISC_LOG_INFO, 9556 "refresh: failure trying master " 9557 "%s (source %s): %s", master, source, 9558 dns_result_totext(revent->result)); 9559 goto next_master; 9560 } 9561 9562 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 9563 if (result != ISC_R_SUCCESS) 9564 goto next_master; 9565 result = dns_request_getresponse(revent->request, msg, 0); 9566 if (result != ISC_R_SUCCESS) { 9567 dns_zone_log(zone, ISC_LOG_INFO, 9568 "refresh: failure trying master " 9569 "%s (source %s): %s", master, source, 9570 dns_result_totext(result)); 9571 goto next_master; 9572 } 9573 9574 /* 9575 * Unexpected rcode. 9576 */ 9577 if (msg->rcode != dns_rcode_noerror) { 9578 char rcode[128]; 9579 isc_buffer_t rb; 9580 9581 isc_buffer_init(&rb, rcode, sizeof(rcode)); 9582 (void)dns_rcode_totext(msg->rcode, &rb); 9583 9584 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) && 9585 (msg->rcode == dns_rcode_servfail || 9586 msg->rcode == dns_rcode_notimp || 9587 msg->rcode == dns_rcode_formerr)) { 9588 dns_zone_log(zone, ISC_LOG_DEBUG(1), 9589 "refresh: rcode (%.*s) retrying without " 9590 "EDNS master %s (source %s)", 9591 (int)rb.used, rcode, master, source); 9592 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 9593 goto same_master; 9594 } 9595 dns_zone_log(zone, ISC_LOG_INFO, 9596 "refresh: unexpected rcode (%.*s) from " 9597 "master %s (source %s)", (int)rb.used, rcode, 9598 master, source); 9599 /* 9600 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't. 9601 */ 9602 if (msg->rcode == dns_rcode_refused && 9603 zone->type == dns_zone_slave) 9604 goto tcp_transfer; 9605 goto next_master; 9606 } 9607 9608 /* 9609 * If truncated punt to zone transfer which will query again. 9610 */ 9611 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 9612 if (zone->type == dns_zone_slave) { 9613 dns_zone_log(zone, ISC_LOG_INFO, 9614 "refresh: truncated UDP answer, " 9615 "initiating TCP zone xfer " 9616 "for master %s (source %s)", 9617 master, source); 9618 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 9619 goto tcp_transfer; 9620 } else { 9621 INSIST(zone->type == dns_zone_stub); 9622 if (dns_request_usedtcp(revent->request)) { 9623 dns_zone_log(zone, ISC_LOG_INFO, 9624 "refresh: truncated TCP response " 9625 "from master %s (source %s)", 9626 master, source); 9627 goto next_master; 9628 } 9629 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); 9630 goto same_master; 9631 } 9632 } 9633 9634 /* 9635 * if non-auth log and next master; 9636 */ 9637 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) { 9638 dns_zone_log(zone, ISC_LOG_INFO, 9639 "refresh: non-authoritative answer from " 9640 "master %s (source %s)", master, source); 9641 goto next_master; 9642 } 9643 9644 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname); 9645 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa); 9646 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns); 9647 soacount = message_count(msg, DNS_SECTION_AUTHORITY, 9648 dns_rdatatype_soa); 9649 9650 /* 9651 * There should not be a CNAME record at top of zone. 9652 */ 9653 if (cnamecnt != 0) { 9654 dns_zone_log(zone, ISC_LOG_INFO, 9655 "refresh: CNAME at top of zone " 9656 "in master %s (source %s)", master, source); 9657 goto next_master; 9658 } 9659 9660 /* 9661 * if referral log and next master; 9662 */ 9663 if (soacnt == 0 && soacount == 0 && nscount != 0) { 9664 dns_zone_log(zone, ISC_LOG_INFO, 9665 "refresh: referral response " 9666 "from master %s (source %s)", master, source); 9667 goto next_master; 9668 } 9669 9670 /* 9671 * if nodata log and next master; 9672 */ 9673 if (soacnt == 0 && (nscount == 0 || soacount != 0)) { 9674 dns_zone_log(zone, ISC_LOG_INFO, 9675 "refresh: NODATA response " 9676 "from master %s (source %s)", master, source); 9677 goto next_master; 9678 } 9679 9680 /* 9681 * Only one soa at top of zone. 9682 */ 9683 if (soacnt != 1) { 9684 dns_zone_log(zone, ISC_LOG_INFO, 9685 "refresh: answer SOA count (%d) != 1 " 9686 "from master %s (source %s)", 9687 soacnt, master, source); 9688 goto next_master; 9689 } 9690 9691 /* 9692 * Extract serial 9693 */ 9694 rdataset = NULL; 9695 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin, 9696 dns_rdatatype_soa, dns_rdatatype_none, 9697 NULL, &rdataset); 9698 if (result != ISC_R_SUCCESS) { 9699 dns_zone_log(zone, ISC_LOG_INFO, 9700 "refresh: unable to get SOA record " 9701 "from master %s (source %s)", master, source); 9702 goto next_master; 9703 } 9704 9705 result = dns_rdataset_first(rdataset); 9706 if (result != ISC_R_SUCCESS) { 9707 dns_zone_log(zone, ISC_LOG_INFO, 9708 "refresh: dns_rdataset_first() failed"); 9709 goto next_master; 9710 } 9711 9712 dns_rdataset_current(rdataset, &rdata); 9713 result = dns_rdata_tostruct(&rdata, &soa, NULL); 9714 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9715 9716 serial = soa.serial; 9717 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 9718 result = zone_get_from_db(zone, zone->db, NULL, NULL, 9719 &oldserial, NULL, NULL, NULL, NULL, 9720 NULL); 9721 RUNTIME_CHECK(result == ISC_R_SUCCESS); 9722 zone_debuglog(zone, me, 1, "serial: new %u, old %u", 9723 serial, oldserial); 9724 } else 9725 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded", 9726 serial); 9727 9728 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) || 9729 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) || 9730 isc_serial_gt(serial, oldserial)) { 9731 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, 9732 &zone->sourceaddr, &now)) 9733 { 9734 dns_zone_log(zone, ISC_LOG_INFO, 9735 "refresh: skipping %s as master %s " 9736 "(source %s) is unreachable (cached)", 9737 zone->type == dns_zone_slave ? 9738 "zone transfer" : "NS query", 9739 master, source); 9740 goto next_master; 9741 } 9742 tcp_transfer: 9743 isc_event_free(&event); 9744 dns_request_destroy(&zone->request); 9745 if (zone->type == dns_zone_slave) { 9746 do_queue_xfrin = ISC_TRUE; 9747 } else { 9748 INSIST(zone->type == dns_zone_stub); 9749 ns_query(zone, rdataset, NULL); 9750 } 9751 if (msg != NULL) 9752 dns_message_destroy(&msg); 9753 } else if (isc_serial_eq(soa.serial, oldserial)) { 9754 if (zone->masterfile != NULL) { 9755 result = ISC_R_FAILURE; 9756 if (zone->journal != NULL) 9757 result = isc_file_settime(zone->journal, &now); 9758 if (result == ISC_R_SUCCESS && 9759 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 9760 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 9761 result = isc_file_settime(zone->masterfile, 9762 &now); 9763 } else if (result != ISC_R_SUCCESS) 9764 result = isc_file_settime(zone->masterfile, 9765 &now); 9766 /* Someone removed the file from underneath us! */ 9767 if (result == ISC_R_FILENOTFOUND) { 9768 zone_needdump(zone, DNS_DUMP_DELAY); 9769 } else if (result != ISC_R_SUCCESS) 9770 dns_zone_log(zone, ISC_LOG_ERROR, 9771 "refresh: could not set file " 9772 "modification time of '%s': %s", 9773 zone->masterfile, 9774 dns_result_totext(result)); 9775 } 9776 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); 9777 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); 9778 zone->mastersok[zone->curmaster] = ISC_TRUE; 9779 goto next_master; 9780 } else { 9781 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER)) 9782 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) " 9783 "received from master %s < ours (%u)", 9784 soa.serial, master, oldserial); 9785 else 9786 zone_debuglog(zone, me, 1, "ahead"); 9787 zone->mastersok[zone->curmaster] = ISC_TRUE; 9788 goto next_master; 9789 } 9790 if (msg != NULL) 9791 dns_message_destroy(&msg); 9792 goto detach; 9793 9794 next_master: 9795 if (msg != NULL) 9796 dns_message_destroy(&msg); 9797 isc_event_free(&event); 9798 dns_request_destroy(&zone->request); 9799 /* 9800 * Skip to next failed / untried master. 9801 */ 9802 do { 9803 zone->curmaster++; 9804 } while (zone->curmaster < zone->masterscnt && 9805 zone->mastersok[zone->curmaster]); 9806 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS); 9807 if (zone->curmaster >= zone->masterscnt) { 9808 isc_boolean_t done = ISC_TRUE; 9809 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 9810 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 9811 /* 9812 * Did we get a good answer from all the masters? 9813 */ 9814 for (j = 0; j < zone->masterscnt; j++) 9815 if (zone->mastersok[j] == ISC_FALSE) { 9816 done = ISC_FALSE; 9817 break; 9818 } 9819 } else 9820 done = ISC_TRUE; 9821 if (!done) { 9822 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 9823 zone->curmaster = 0; 9824 /* 9825 * Find the next failed master. 9826 */ 9827 while (zone->curmaster < zone->masterscnt && 9828 zone->mastersok[zone->curmaster]) 9829 zone->curmaster++; 9830 goto requeue; 9831 } 9832 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 9833 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 9834 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 9835 zone->refreshtime = now; 9836 } 9837 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 9838 zone_settimer(zone, &now); 9839 goto detach; 9840 } 9841 9842 requeue: 9843 queue_soa_query(zone); 9844 goto detach; 9845 9846 same_master: 9847 if (msg != NULL) 9848 dns_message_destroy(&msg); 9849 isc_event_free(&event); 9850 dns_request_destroy(&zone->request); 9851 queue_soa_query(zone); 9852 9853 detach: 9854 UNLOCK_ZONE(zone); 9855 if (do_queue_xfrin) 9856 queue_xfrin(zone); 9857 dns_zone_idetach(&zone); 9858 return; 9859} 9860 9861static void 9862queue_soa_query(dns_zone_t *zone) { 9863 const char me[] = "queue_soa_query"; 9864 isc_event_t *e; 9865 dns_zone_t *dummy = NULL; 9866 isc_result_t result; 9867 9868 ENTER; 9869 /* 9870 * Locked by caller 9871 */ 9872 REQUIRE(LOCKED_ZONE(zone)); 9873 9874 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 9875 cancel_refresh(zone); 9876 return; 9877 } 9878 9879 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE, 9880 soa_query, zone, sizeof(isc_event_t)); 9881 if (e == NULL) { 9882 cancel_refresh(zone); 9883 return; 9884 } 9885 9886 /* 9887 * Attach so that we won't clean up 9888 * until the event is delivered. 9889 */ 9890 zone_iattach(zone, &dummy); 9891 9892 e->ev_arg = zone; 9893 e->ev_sender = NULL; 9894 result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e); 9895 if (result != ISC_R_SUCCESS) { 9896 zone_idetach(&dummy); 9897 isc_event_free(&e); 9898 cancel_refresh(zone); 9899 } 9900} 9901 9902static inline isc_result_t 9903create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, 9904 dns_message_t **messagep) 9905{ 9906 dns_message_t *message = NULL; 9907 dns_name_t *qname = NULL; 9908 dns_rdataset_t *qrdataset = NULL; 9909 isc_result_t result; 9910 9911 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, 9912 &message); 9913 if (result != ISC_R_SUCCESS) 9914 goto cleanup; 9915 9916 message->opcode = dns_opcode_query; 9917 message->rdclass = zone->rdclass; 9918 9919 result = dns_message_gettempname(message, &qname); 9920 if (result != ISC_R_SUCCESS) 9921 goto cleanup; 9922 9923 result = dns_message_gettemprdataset(message, &qrdataset); 9924 if (result != ISC_R_SUCCESS) 9925 goto cleanup; 9926 9927 /* 9928 * Make question. 9929 */ 9930 dns_name_init(qname, NULL); 9931 dns_name_clone(&zone->origin, qname); 9932 dns_rdataset_init(qrdataset); 9933 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype); 9934 ISC_LIST_APPEND(qname->list, qrdataset, link); 9935 dns_message_addname(message, qname, DNS_SECTION_QUESTION); 9936 9937 *messagep = message; 9938 return (ISC_R_SUCCESS); 9939 9940 cleanup: 9941 if (qname != NULL) 9942 dns_message_puttempname(message, &qname); 9943 if (qrdataset != NULL) 9944 dns_message_puttemprdataset(message, &qrdataset); 9945 if (message != NULL) 9946 dns_message_destroy(&message); 9947 return (result); 9948} 9949 9950static isc_result_t 9951add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) { 9952 dns_rdataset_t *rdataset = NULL; 9953 dns_rdatalist_t *rdatalist = NULL; 9954 dns_rdata_t *rdata = NULL; 9955 isc_result_t result; 9956 9957 result = dns_message_gettemprdatalist(message, &rdatalist); 9958 if (result != ISC_R_SUCCESS) 9959 goto cleanup; 9960 result = dns_message_gettemprdata(message, &rdata); 9961 if (result != ISC_R_SUCCESS) 9962 goto cleanup; 9963 result = dns_message_gettemprdataset(message, &rdataset); 9964 if (result != ISC_R_SUCCESS) 9965 goto cleanup; 9966 dns_rdataset_init(rdataset); 9967 9968 rdatalist->type = dns_rdatatype_opt; 9969 rdatalist->covers = 0; 9970 9971 /* 9972 * Set Maximum UDP buffer size. 9973 */ 9974 rdatalist->rdclass = udpsize; 9975 9976 /* 9977 * Set EXTENDED-RCODE, VERSION, DO and Z to 0. 9978 */ 9979 rdatalist->ttl = 0; 9980 9981 /* Set EDNS options if applicable */ 9982 if (reqnsid) { 9983 unsigned char data[4]; 9984 isc_buffer_t buf; 9985 9986 isc_buffer_init(&buf, data, sizeof(data)); 9987 isc_buffer_putuint16(&buf, DNS_OPT_NSID); 9988 isc_buffer_putuint16(&buf, 0); 9989 rdata->data = data; 9990 rdata->length = sizeof(data); 9991 } else { 9992 rdata->data = NULL; 9993 rdata->length = 0; 9994 } 9995 9996 rdata->rdclass = rdatalist->rdclass; 9997 rdata->type = rdatalist->type; 9998 rdata->flags = 0; 9999 10000 ISC_LIST_INIT(rdatalist->rdata); 10001 ISC_LIST_APPEND(rdatalist->rdata, rdata, link); 10002 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) 10003 == ISC_R_SUCCESS); 10004 10005 return (dns_message_setopt(message, rdataset)); 10006 10007 cleanup: 10008 if (rdatalist != NULL) 10009 dns_message_puttemprdatalist(message, &rdatalist); 10010 if (rdataset != NULL) 10011 dns_message_puttemprdataset(message, &rdataset); 10012 if (rdata != NULL) 10013 dns_message_puttemprdata(message, &rdata); 10014 10015 return (result); 10016} 10017 10018static void 10019soa_query(isc_task_t *task, isc_event_t *event) { 10020 const char me[] = "soa_query"; 10021 isc_result_t result = ISC_R_FAILURE; 10022 dns_message_t *message = NULL; 10023 dns_zone_t *zone = event->ev_arg; 10024 dns_zone_t *dummy = NULL; 10025 isc_netaddr_t masterip; 10026 dns_tsigkey_t *key = NULL; 10027 isc_uint32_t options; 10028 isc_boolean_t cancel = ISC_TRUE; 10029 int timeout; 10030 isc_boolean_t have_xfrsource, reqnsid; 10031 isc_uint16_t udpsize = SEND_BUFFER_SIZE; 10032 10033 REQUIRE(DNS_ZONE_VALID(zone)); 10034 10035 UNUSED(task); 10036 10037 ENTER; 10038 10039 LOCK_ZONE(zone); 10040 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) || 10041 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || 10042 zone->view->requestmgr == NULL) { 10043 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 10044 cancel = ISC_FALSE; 10045 goto cleanup; 10046 } 10047 10048 /* 10049 * XXX Optimisation: Create message when zone is setup and reuse. 10050 */ 10051 result = create_query(zone, dns_rdatatype_soa, &message); 10052 if (result != ISC_R_SUCCESS) 10053 goto cleanup; 10054 10055 again: 10056 INSIST(zone->masterscnt > 0); 10057 INSIST(zone->curmaster < zone->masterscnt); 10058 10059 zone->masteraddr = zone->masters[zone->curmaster]; 10060 10061 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 10062 /* 10063 * First, look for a tsig key in the master statement, then 10064 * try for a server key. 10065 */ 10066 if ((zone->masterkeynames != NULL) && 10067 (zone->masterkeynames[zone->curmaster] != NULL)) { 10068 dns_view_t *view = dns_zone_getview(zone); 10069 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 10070 result = dns_view_gettsig(view, keyname, &key); 10071 if (result != ISC_R_SUCCESS) { 10072 char namebuf[DNS_NAME_FORMATSIZE]; 10073 dns_name_format(keyname, namebuf, sizeof(namebuf)); 10074 dns_zone_log(zone, ISC_LOG_ERROR, 10075 "unable to find key: %s", namebuf); 10076 goto skip_master; 10077 } 10078 } 10079 if (key == NULL) { 10080 result = dns_view_getpeertsig(zone->view, &masterip, &key); 10081 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 10082 char addrbuf[ISC_NETADDR_FORMATSIZE]; 10083 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf)); 10084 dns_zone_log(zone, ISC_LOG_ERROR, 10085 "unable to find TSIG key for %s", addrbuf); 10086 goto skip_master; 10087 } 10088 } 10089 10090 have_xfrsource = ISC_FALSE; 10091 reqnsid = zone->view->requestnsid; 10092 if (zone->view->peers != NULL) { 10093 dns_peer_t *peer = NULL; 10094 isc_boolean_t edns; 10095 result = dns_peerlist_peerbyaddr(zone->view->peers, 10096 &masterip, &peer); 10097 if (result == ISC_R_SUCCESS) { 10098 result = dns_peer_getsupportedns(peer, &edns); 10099 if (result == ISC_R_SUCCESS && !edns) 10100 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 10101 result = dns_peer_gettransfersource(peer, 10102 &zone->sourceaddr); 10103 if (result == ISC_R_SUCCESS) 10104 have_xfrsource = ISC_TRUE; 10105 if (zone->view->resolver != NULL) 10106 udpsize = 10107 dns_resolver_getudpsize(zone->view->resolver); 10108 (void)dns_peer_getudpsize(peer, &udpsize); 10109 (void)dns_peer_getrequestnsid(peer, &reqnsid); 10110 } 10111 } 10112 10113 switch (isc_sockaddr_pf(&zone->masteraddr)) { 10114 case PF_INET: 10115 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 10116 if (isc_sockaddr_equal(&zone->altxfrsource4, 10117 &zone->xfrsource4)) 10118 goto skip_master; 10119 zone->sourceaddr = zone->altxfrsource4; 10120 } else if (!have_xfrsource) 10121 zone->sourceaddr = zone->xfrsource4; 10122 break; 10123 case PF_INET6: 10124 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 10125 if (isc_sockaddr_equal(&zone->altxfrsource6, 10126 &zone->xfrsource6)) 10127 goto skip_master; 10128 zone->sourceaddr = zone->altxfrsource6; 10129 } else if (!have_xfrsource) 10130 zone->sourceaddr = zone->xfrsource6; 10131 break; 10132 default: 10133 result = ISC_R_NOTIMPLEMENTED; 10134 goto cleanup; 10135 } 10136 10137 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? 10138 DNS_REQUESTOPT_TCP : 0; 10139 10140 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 10141 result = add_opt(message, udpsize, reqnsid); 10142 if (result != ISC_R_SUCCESS) 10143 zone_debuglog(zone, me, 1, 10144 "unable to add opt record: %s", 10145 dns_result_totext(result)); 10146 } 10147 10148 zone_iattach(zone, &dummy); 10149 timeout = 15; 10150 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 10151 timeout = 30; 10152 result = dns_request_createvia2(zone->view->requestmgr, message, 10153 &zone->sourceaddr, &zone->masteraddr, 10154 options, key, timeout * 3, timeout, 10155 zone->task, refresh_callback, zone, 10156 &zone->request); 10157 if (result != ISC_R_SUCCESS) { 10158 zone_idetach(&dummy); 10159 zone_debuglog(zone, me, 1, 10160 "dns_request_createvia2() failed: %s", 10161 dns_result_totext(result)); 10162 goto cleanup; 10163 } else { 10164 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET) 10165 inc_stats(zone, dns_zonestatscounter_soaoutv4); 10166 else 10167 inc_stats(zone, dns_zonestatscounter_soaoutv6); 10168 } 10169 cancel = ISC_FALSE; 10170 10171 cleanup: 10172 if (key != NULL) 10173 dns_tsigkey_detach(&key); 10174 if (result != ISC_R_SUCCESS) 10175 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 10176 if (message != NULL) 10177 dns_message_destroy(&message); 10178 if (cancel) 10179 cancel_refresh(zone); 10180 isc_event_free(&event); 10181 UNLOCK_ZONE(zone); 10182 dns_zone_idetach(&zone); 10183 return; 10184 10185 skip_master: 10186 if (key != NULL) 10187 dns_tsigkey_detach(&key); 10188 /* 10189 * Skip to next failed / untried master. 10190 */ 10191 do { 10192 zone->curmaster++; 10193 } while (zone->curmaster < zone->masterscnt && 10194 zone->mastersok[zone->curmaster]); 10195 if (zone->curmaster < zone->masterscnt) 10196 goto again; 10197 zone->curmaster = 0; 10198 goto cleanup; 10199} 10200 10201static void 10202ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { 10203 const char me[] = "ns_query"; 10204 isc_result_t result; 10205 dns_message_t *message = NULL; 10206 isc_netaddr_t masterip; 10207 dns_tsigkey_t *key = NULL; 10208 dns_dbnode_t *node = NULL; 10209 int timeout; 10210 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid; 10211 isc_uint16_t udpsize = SEND_BUFFER_SIZE; 10212 10213 REQUIRE(DNS_ZONE_VALID(zone)); 10214 REQUIRE(LOCKED_ZONE(zone)); 10215 REQUIRE((soardataset != NULL && stub == NULL) || 10216 (soardataset == NULL && stub != NULL)); 10217 REQUIRE(stub == NULL || DNS_STUB_VALID(stub)); 10218 10219 ENTER; 10220 10221 if (stub == NULL) { 10222 stub = isc_mem_get(zone->mctx, sizeof(*stub)); 10223 if (stub == NULL) 10224 goto cleanup; 10225 stub->magic = STUB_MAGIC; 10226 stub->mctx = zone->mctx; 10227 stub->zone = NULL; 10228 stub->db = NULL; 10229 stub->version = NULL; 10230 10231 /* 10232 * Attach so that the zone won't disappear from under us. 10233 */ 10234 zone_iattach(zone, &stub->zone); 10235 10236 /* 10237 * If a db exists we will update it, otherwise we create a 10238 * new one and attach it to the zone once we have the NS 10239 * RRset and glue. 10240 */ 10241 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 10242 if (zone->db != NULL) { 10243 dns_db_attach(zone->db, &stub->db); 10244 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 10245 } else { 10246 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 10247 10248 INSIST(zone->db_argc >= 1); 10249 result = dns_db_create(zone->mctx, zone->db_argv[0], 10250 &zone->origin, dns_dbtype_stub, 10251 zone->rdclass, 10252 zone->db_argc - 1, 10253 zone->db_argv + 1, 10254 &stub->db); 10255 if (result != ISC_R_SUCCESS) { 10256 dns_zone_log(zone, ISC_LOG_ERROR, 10257 "refreshing stub: " 10258 "could not create " 10259 "database: %s", 10260 dns_result_totext(result)); 10261 goto cleanup; 10262 } 10263 dns_db_settask(stub->db, zone->task); 10264 } 10265 10266 result = dns_db_newversion(stub->db, &stub->version); 10267 if (result != ISC_R_SUCCESS) { 10268 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " 10269 "dns_db_newversion() failed: %s", 10270 dns_result_totext(result)); 10271 goto cleanup; 10272 } 10273 10274 /* 10275 * Update SOA record. 10276 */ 10277 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE, 10278 &node); 10279 if (result != ISC_R_SUCCESS) { 10280 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: " 10281 "dns_db_findnode() failed: %s", 10282 dns_result_totext(result)); 10283 goto cleanup; 10284 } 10285 10286 result = dns_db_addrdataset(stub->db, node, stub->version, 0, 10287 soardataset, 0, NULL); 10288 dns_db_detachnode(stub->db, &node); 10289 if (result != ISC_R_SUCCESS) { 10290 dns_zone_log(zone, ISC_LOG_INFO, 10291 "refreshing stub: " 10292 "dns_db_addrdataset() failed: %s", 10293 dns_result_totext(result)); 10294 goto cleanup; 10295 } 10296 } 10297 10298 /* 10299 * XXX Optimisation: Create message when zone is setup and reuse. 10300 */ 10301 result = create_query(zone, dns_rdatatype_ns, &message); 10302 INSIST(result == ISC_R_SUCCESS); 10303 10304 INSIST(zone->masterscnt > 0); 10305 INSIST(zone->curmaster < zone->masterscnt); 10306 zone->masteraddr = zone->masters[zone->curmaster]; 10307 10308 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 10309 /* 10310 * First, look for a tsig key in the master statement, then 10311 * try for a server key. 10312 */ 10313 if ((zone->masterkeynames != NULL) && 10314 (zone->masterkeynames[zone->curmaster] != NULL)) { 10315 dns_view_t *view = dns_zone_getview(zone); 10316 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 10317 result = dns_view_gettsig(view, keyname, &key); 10318 if (result != ISC_R_SUCCESS) { 10319 char namebuf[DNS_NAME_FORMATSIZE]; 10320 dns_name_format(keyname, namebuf, sizeof(namebuf)); 10321 dns_zone_log(zone, ISC_LOG_ERROR, 10322 "unable to find key: %s", namebuf); 10323 } 10324 } 10325 if (key == NULL) 10326 (void)dns_view_getpeertsig(zone->view, &masterip, &key); 10327 10328 reqnsid = zone->view->requestnsid; 10329 if (zone->view->peers != NULL) { 10330 dns_peer_t *peer = NULL; 10331 isc_boolean_t edns; 10332 result = dns_peerlist_peerbyaddr(zone->view->peers, 10333 &masterip, &peer); 10334 if (result == ISC_R_SUCCESS) { 10335 result = dns_peer_getsupportedns(peer, &edns); 10336 if (result == ISC_R_SUCCESS && !edns) 10337 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); 10338 result = dns_peer_gettransfersource(peer, 10339 &zone->sourceaddr); 10340 if (result == ISC_R_SUCCESS) 10341 have_xfrsource = ISC_TRUE; 10342 if (zone->view->resolver != NULL) 10343 udpsize = 10344 dns_resolver_getudpsize(zone->view->resolver); 10345 (void)dns_peer_getudpsize(peer, &udpsize); 10346 (void)dns_peer_getrequestnsid(peer, &reqnsid); 10347 } 10348 10349 } 10350 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { 10351 result = add_opt(message, udpsize, reqnsid); 10352 if (result != ISC_R_SUCCESS) 10353 zone_debuglog(zone, me, 1, 10354 "unable to add opt record: %s", 10355 dns_result_totext(result)); 10356 } 10357 10358 /* 10359 * Always use TCP so that we shouldn't truncate in additional section. 10360 */ 10361 switch (isc_sockaddr_pf(&zone->masteraddr)) { 10362 case PF_INET: 10363 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) 10364 zone->sourceaddr = zone->altxfrsource4; 10365 else if (!have_xfrsource) 10366 zone->sourceaddr = zone->xfrsource4; 10367 break; 10368 case PF_INET6: 10369 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) 10370 zone->sourceaddr = zone->altxfrsource6; 10371 else if (!have_xfrsource) 10372 zone->sourceaddr = zone->xfrsource6; 10373 break; 10374 default: 10375 result = ISC_R_NOTIMPLEMENTED; 10376 POST(result); 10377 goto cleanup; 10378 } 10379 timeout = 15; 10380 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 10381 timeout = 30; 10382 result = dns_request_createvia2(zone->view->requestmgr, message, 10383 &zone->sourceaddr, &zone->masteraddr, 10384 DNS_REQUESTOPT_TCP, key, timeout * 3, 10385 timeout, zone->task, stub_callback, 10386 stub, &zone->request); 10387 if (result != ISC_R_SUCCESS) { 10388 zone_debuglog(zone, me, 1, 10389 "dns_request_createvia() failed: %s", 10390 dns_result_totext(result)); 10391 goto cleanup; 10392 } 10393 dns_message_destroy(&message); 10394 goto unlock; 10395 10396 cleanup: 10397 cancel_refresh(zone); 10398 if (stub != NULL) { 10399 stub->magic = 0; 10400 if (stub->version != NULL) 10401 dns_db_closeversion(stub->db, &stub->version, 10402 ISC_FALSE); 10403 if (stub->db != NULL) 10404 dns_db_detach(&stub->db); 10405 if (stub->zone != NULL) 10406 zone_idetach(&stub->zone); 10407 isc_mem_put(stub->mctx, stub, sizeof(*stub)); 10408 } 10409 if (message != NULL) 10410 dns_message_destroy(&message); 10411 unlock: 10412 if (key != NULL) 10413 dns_tsigkey_detach(&key); 10414 return; 10415} 10416 10417/* 10418 * Handle the control event. Note that although this event causes the zone 10419 * to shut down, it is not a shutdown event in the sense of the task library. 10420 */ 10421static void 10422zone_shutdown(isc_task_t *task, isc_event_t *event) { 10423 dns_zone_t *zone = (dns_zone_t *) event->ev_arg; 10424 isc_boolean_t free_needed, linked = ISC_FALSE; 10425 10426 UNUSED(task); 10427 REQUIRE(DNS_ZONE_VALID(zone)); 10428 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL); 10429 INSIST(isc_refcount_current(&zone->erefs) == 0); 10430 10431 zone_debuglog(zone, "zone_shutdown", 3, "shutting down"); 10432 10433 /* 10434 * Stop things being restarted after we cancel them below. 10435 */ 10436 LOCK_ZONE(zone); 10437 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING); 10438 UNLOCK_ZONE(zone); 10439 10440 /* 10441 * If we were waiting for xfrin quota, step out of 10442 * the queue. 10443 * If there's no zone manager, we can't be waiting for the 10444 * xfrin quota 10445 */ 10446 if (zone->zmgr != NULL) { 10447 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 10448 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) { 10449 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone, 10450 statelink); 10451 linked = ISC_TRUE; 10452 zone->statelist = NULL; 10453 } 10454 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 10455 } 10456 10457 /* 10458 * In task context, no locking required. See zone_xfrdone(). 10459 */ 10460 if (zone->xfr != NULL) 10461 dns_xfrin_shutdown(zone->xfr); 10462 10463 LOCK_ZONE(zone); 10464 if (linked) { 10465 INSIST(zone->irefs > 0); 10466 zone->irefs--; 10467 } 10468 if (zone->request != NULL) { 10469 dns_request_cancel(zone->request); 10470 } 10471 10472 if (zone->readio != NULL) 10473 zonemgr_cancelio(zone->readio); 10474 10475 if (zone->lctx != NULL) 10476 dns_loadctx_cancel(zone->lctx); 10477 10478 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || 10479 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 10480 if (zone->writeio != NULL) 10481 zonemgr_cancelio(zone->writeio); 10482 10483 if (zone->dctx != NULL) 10484 dns_dumpctx_cancel(zone->dctx); 10485 } 10486 10487 notify_cancel(zone); 10488 10489 forward_cancel(zone); 10490 10491 if (zone->timer != NULL) { 10492 isc_timer_detach(&zone->timer); 10493 INSIST(zone->irefs > 0); 10494 zone->irefs--; 10495 } 10496 10497 if (zone->view != NULL) 10498 dns_view_weakdetach(&zone->view); 10499 10500 /* 10501 * We have now canceled everything set the flag to allow exit_check() 10502 * to succeed. We must not unlock between setting this flag and 10503 * calling exit_check(). 10504 */ 10505 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN); 10506 free_needed = exit_check(zone); 10507 UNLOCK_ZONE(zone); 10508 if (free_needed) 10509 zone_free(zone); 10510} 10511 10512static void 10513zone_timer(isc_task_t *task, isc_event_t *event) { 10514 const char me[] = "zone_timer"; 10515 dns_zone_t *zone = (dns_zone_t *)event->ev_arg; 10516 10517 UNUSED(task); 10518 REQUIRE(DNS_ZONE_VALID(zone)); 10519 10520 ENTER; 10521 10522 zone_maintenance(zone); 10523 10524 isc_event_free(&event); 10525} 10526 10527static void 10528zone_settimer(dns_zone_t *zone, isc_time_t *now) { 10529 const char me[] = "zone_settimer"; 10530 isc_time_t next; 10531 isc_result_t result; 10532 10533 ENTER; 10534 REQUIRE(DNS_ZONE_VALID(zone)); 10535 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 10536 return; 10537 10538 isc_time_settoepoch(&next); 10539 10540 switch (zone->type) { 10541 case dns_zone_master: 10542 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) 10543 next = zone->notifytime; 10544 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 10545 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 10546 INSIST(!isc_time_isepoch(&zone->dumptime)); 10547 if (isc_time_isepoch(&next) || 10548 isc_time_compare(&zone->dumptime, &next) < 0) 10549 next = zone->dumptime; 10550 } 10551 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) && 10552 !isc_time_isepoch(&zone->refreshkeytime)) { 10553 if (isc_time_isepoch(&next) || 10554 isc_time_compare(&zone->refreshkeytime, &next) < 0) 10555 next = zone->refreshkeytime; 10556 } 10557 if (!isc_time_isepoch(&zone->resigntime)) { 10558 if (isc_time_isepoch(&next) || 10559 isc_time_compare(&zone->resigntime, &next) < 0) 10560 next = zone->resigntime; 10561 } 10562 if (!isc_time_isepoch(&zone->keywarntime)) { 10563 if (isc_time_isepoch(&next) || 10564 isc_time_compare(&zone->keywarntime, &next) < 0) 10565 next = zone->keywarntime; 10566 } 10567 if (!isc_time_isepoch(&zone->signingtime)) { 10568 if (isc_time_isepoch(&next) || 10569 isc_time_compare(&zone->signingtime, &next) < 0) 10570 next = zone->signingtime; 10571 } 10572 if (!isc_time_isepoch(&zone->nsec3chaintime)) { 10573 if (isc_time_isepoch(&next) || 10574 isc_time_compare(&zone->nsec3chaintime, &next) < 0) 10575 next = zone->nsec3chaintime; 10576 } 10577 break; 10578 10579 case dns_zone_slave: 10580 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) 10581 next = zone->notifytime; 10582 /*FALLTHROUGH*/ 10583 10584 case dns_zone_stub: 10585 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) && 10586 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) && 10587 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) && 10588 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) { 10589 INSIST(!isc_time_isepoch(&zone->refreshtime)); 10590 if (isc_time_isepoch(&next) || 10591 isc_time_compare(&zone->refreshtime, &next) < 0) 10592 next = zone->refreshtime; 10593 } 10594 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { 10595 INSIST(!isc_time_isepoch(&zone->expiretime)); 10596 if (isc_time_isepoch(&next) || 10597 isc_time_compare(&zone->expiretime, &next) < 0) 10598 next = zone->expiretime; 10599 } 10600 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 10601 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 10602 INSIST(!isc_time_isepoch(&zone->dumptime)); 10603 if (isc_time_isepoch(&next) || 10604 isc_time_compare(&zone->dumptime, &next) < 0) 10605 next = zone->dumptime; 10606 } 10607 break; 10608 10609 case dns_zone_key: 10610 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && 10611 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { 10612 INSIST(!isc_time_isepoch(&zone->dumptime)); 10613 if (isc_time_isepoch(&next) || 10614 isc_time_compare(&zone->dumptime, &next) < 0) 10615 next = zone->dumptime; 10616 } 10617 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) { 10618 if (isc_time_isepoch(&next) || 10619 (!isc_time_isepoch(&zone->refreshkeytime) && 10620 isc_time_compare(&zone->refreshkeytime, &next) < 0)) 10621 next = zone->refreshkeytime; 10622 } 10623 break; 10624 10625 default: 10626 break; 10627 } 10628 10629 if (isc_time_isepoch(&next)) { 10630 zone_debuglog(zone, me, 10, "settimer inactive"); 10631 result = isc_timer_reset(zone->timer, isc_timertype_inactive, 10632 NULL, NULL, ISC_TRUE); 10633 if (result != ISC_R_SUCCESS) 10634 dns_zone_log(zone, ISC_LOG_ERROR, 10635 "could not deactivate zone timer: %s", 10636 isc_result_totext(result)); 10637 } else { 10638 if (isc_time_compare(&next, now) <= 0) 10639 next = *now; 10640 result = isc_timer_reset(zone->timer, isc_timertype_once, 10641 &next, NULL, ISC_TRUE); 10642 if (result != ISC_R_SUCCESS) 10643 dns_zone_log(zone, ISC_LOG_ERROR, 10644 "could not reset zone timer: %s", 10645 isc_result_totext(result)); 10646 } 10647} 10648 10649static void 10650cancel_refresh(dns_zone_t *zone) { 10651 const char me[] = "cancel_refresh"; 10652 isc_time_t now; 10653 10654 /* 10655 * 'zone' locked by caller. 10656 */ 10657 10658 REQUIRE(DNS_ZONE_VALID(zone)); 10659 REQUIRE(LOCKED_ZONE(zone)); 10660 10661 ENTER; 10662 10663 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 10664 TIME_NOW(&now); 10665 zone_settimer(zone, &now); 10666} 10667 10668static isc_result_t 10669notify_createmessage(dns_zone_t *zone, unsigned int flags, 10670 dns_message_t **messagep) 10671{ 10672 dns_db_t *zonedb = NULL; 10673 dns_dbnode_t *node = NULL; 10674 dns_dbversion_t *version = NULL; 10675 dns_message_t *message = NULL; 10676 dns_rdataset_t rdataset; 10677 dns_rdata_t rdata = DNS_RDATA_INIT; 10678 10679 dns_name_t *tempname = NULL; 10680 dns_rdata_t *temprdata = NULL; 10681 dns_rdatalist_t *temprdatalist = NULL; 10682 dns_rdataset_t *temprdataset = NULL; 10683 10684 isc_result_t result; 10685 isc_region_t r; 10686 isc_buffer_t *b = NULL; 10687 10688 REQUIRE(DNS_ZONE_VALID(zone)); 10689 REQUIRE(messagep != NULL && *messagep == NULL); 10690 10691 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, 10692 &message); 10693 if (result != ISC_R_SUCCESS) 10694 return (result); 10695 10696 message->opcode = dns_opcode_notify; 10697 message->flags |= DNS_MESSAGEFLAG_AA; 10698 message->rdclass = zone->rdclass; 10699 10700 result = dns_message_gettempname(message, &tempname); 10701 if (result != ISC_R_SUCCESS) 10702 goto cleanup; 10703 10704 result = dns_message_gettemprdataset(message, &temprdataset); 10705 if (result != ISC_R_SUCCESS) 10706 goto cleanup; 10707 10708 /* 10709 * Make question. 10710 */ 10711 dns_name_init(tempname, NULL); 10712 dns_name_clone(&zone->origin, tempname); 10713 dns_rdataset_init(temprdataset); 10714 dns_rdataset_makequestion(temprdataset, zone->rdclass, 10715 dns_rdatatype_soa); 10716 ISC_LIST_APPEND(tempname->list, temprdataset, link); 10717 dns_message_addname(message, tempname, DNS_SECTION_QUESTION); 10718 tempname = NULL; 10719 temprdataset = NULL; 10720 10721 if ((flags & DNS_NOTIFY_NOSOA) != 0) 10722 goto done; 10723 10724 result = dns_message_gettempname(message, &tempname); 10725 if (result != ISC_R_SUCCESS) 10726 goto soa_cleanup; 10727 result = dns_message_gettemprdata(message, &temprdata); 10728 if (result != ISC_R_SUCCESS) 10729 goto soa_cleanup; 10730 result = dns_message_gettemprdataset(message, &temprdataset); 10731 if (result != ISC_R_SUCCESS) 10732 goto soa_cleanup; 10733 result = dns_message_gettemprdatalist(message, &temprdatalist); 10734 if (result != ISC_R_SUCCESS) 10735 goto soa_cleanup; 10736 10737 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 10738 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */ 10739 dns_db_attach(zone->db, &zonedb); 10740 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 10741 10742 dns_name_init(tempname, NULL); 10743 dns_name_clone(&zone->origin, tempname); 10744 dns_db_currentversion(zonedb, &version); 10745 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node); 10746 if (result != ISC_R_SUCCESS) 10747 goto soa_cleanup; 10748 10749 dns_rdataset_init(&rdataset); 10750 result = dns_db_findrdataset(zonedb, node, version, 10751 dns_rdatatype_soa, 10752 dns_rdatatype_none, 0, &rdataset, 10753 NULL); 10754 if (result != ISC_R_SUCCESS) 10755 goto soa_cleanup; 10756 result = dns_rdataset_first(&rdataset); 10757 if (result != ISC_R_SUCCESS) 10758 goto soa_cleanup; 10759 dns_rdataset_current(&rdataset, &rdata); 10760 dns_rdata_toregion(&rdata, &r); 10761 result = isc_buffer_allocate(zone->mctx, &b, r.length); 10762 if (result != ISC_R_SUCCESS) 10763 goto soa_cleanup; 10764 isc_buffer_putmem(b, r.base, r.length); 10765 isc_buffer_usedregion(b, &r); 10766 dns_rdata_init(temprdata); 10767 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r); 10768 dns_message_takebuffer(message, &b); 10769 result = dns_rdataset_next(&rdataset); 10770 dns_rdataset_disassociate(&rdataset); 10771 if (result != ISC_R_NOMORE) 10772 goto soa_cleanup; 10773 temprdatalist->rdclass = rdata.rdclass; 10774 temprdatalist->type = rdata.type; 10775 temprdatalist->covers = 0; 10776 temprdatalist->ttl = rdataset.ttl; 10777 ISC_LIST_INIT(temprdatalist->rdata); 10778 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link); 10779 10780 dns_rdataset_init(temprdataset); 10781 result = dns_rdatalist_tordataset(temprdatalist, temprdataset); 10782 if (result != ISC_R_SUCCESS) 10783 goto soa_cleanup; 10784 10785 ISC_LIST_APPEND(tempname->list, temprdataset, link); 10786 dns_message_addname(message, tempname, DNS_SECTION_ANSWER); 10787 temprdatalist = NULL; 10788 temprdataset = NULL; 10789 temprdata = NULL; 10790 tempname = NULL; 10791 10792 soa_cleanup: 10793 if (node != NULL) 10794 dns_db_detachnode(zonedb, &node); 10795 if (version != NULL) 10796 dns_db_closeversion(zonedb, &version, ISC_FALSE); 10797 if (zonedb != NULL) 10798 dns_db_detach(&zonedb); 10799 if (tempname != NULL) 10800 dns_message_puttempname(message, &tempname); 10801 if (temprdata != NULL) 10802 dns_message_puttemprdata(message, &temprdata); 10803 if (temprdataset != NULL) 10804 dns_message_puttemprdataset(message, &temprdataset); 10805 if (temprdatalist != NULL) 10806 dns_message_puttemprdatalist(message, &temprdatalist); 10807 10808 done: 10809 *messagep = message; 10810 return (ISC_R_SUCCESS); 10811 10812 cleanup: 10813 if (tempname != NULL) 10814 dns_message_puttempname(message, &tempname); 10815 if (temprdataset != NULL) 10816 dns_message_puttemprdataset(message, &temprdataset); 10817 dns_message_destroy(&message); 10818 return (result); 10819} 10820 10821isc_result_t 10822dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, 10823 dns_message_t *msg) 10824{ 10825 unsigned int i; 10826 dns_rdata_soa_t soa; 10827 dns_rdataset_t *rdataset = NULL; 10828 dns_rdata_t rdata = DNS_RDATA_INIT; 10829 isc_result_t result; 10830 char fromtext[ISC_SOCKADDR_FORMATSIZE]; 10831 int match = 0; 10832 isc_netaddr_t netaddr; 10833 isc_sockaddr_t local, remote; 10834 10835 REQUIRE(DNS_ZONE_VALID(zone)); 10836 10837 /* 10838 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support 10839 * ROLLOVER. 10840 * 10841 * SOA: RFC1996 10842 * Check that 'from' is a valid notify source, (zone->masters). 10843 * Return DNS_R_REFUSED if not. 10844 * 10845 * If the notify message contains a serial number check it 10846 * against the zones serial and return if <= current serial 10847 * 10848 * If a refresh check is progress, if so just record the 10849 * fact we received a NOTIFY and from where and return. 10850 * We will perform a new refresh check when the current one 10851 * completes. Return ISC_R_SUCCESS. 10852 * 10853 * Otherwise initiate a refresh check using 'from' as the 10854 * first address to check. Return ISC_R_SUCCESS. 10855 */ 10856 10857 isc_sockaddr_format(from, fromtext, sizeof(fromtext)); 10858 10859 /* 10860 * We only handle NOTIFY (SOA) at the present. 10861 */ 10862 LOCK_ZONE(zone); 10863 if (isc_sockaddr_pf(from) == PF_INET) 10864 inc_stats(zone, dns_zonestatscounter_notifyinv4); 10865 else 10866 inc_stats(zone, dns_zonestatscounter_notifyinv6); 10867 if (msg->counts[DNS_SECTION_QUESTION] == 0 || 10868 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin, 10869 dns_rdatatype_soa, dns_rdatatype_none, 10870 NULL, NULL) != ISC_R_SUCCESS) { 10871 UNLOCK_ZONE(zone); 10872 if (msg->counts[DNS_SECTION_QUESTION] == 0) { 10873 dns_zone_log(zone, ISC_LOG_NOTICE, 10874 "NOTIFY with no " 10875 "question section from: %s", fromtext); 10876 return (DNS_R_FORMERR); 10877 } 10878 dns_zone_log(zone, ISC_LOG_NOTICE, 10879 "NOTIFY zone does not match"); 10880 return (DNS_R_NOTIMP); 10881 } 10882 10883 /* 10884 * If we are a master zone just succeed. 10885 */ 10886 if (zone->type == dns_zone_master) { 10887 UNLOCK_ZONE(zone); 10888 return (ISC_R_SUCCESS); 10889 } 10890 10891 isc_netaddr_fromsockaddr(&netaddr, from); 10892 for (i = 0; i < zone->masterscnt; i++) { 10893 if (isc_sockaddr_eqaddr(from, &zone->masters[i])) 10894 break; 10895 if (zone->view->aclenv.match_mapped && 10896 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) && 10897 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) { 10898 isc_netaddr_t na1, na2; 10899 isc_netaddr_fromv4mapped(&na1, &netaddr); 10900 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]); 10901 if (isc_netaddr_equal(&na1, &na2)) 10902 break; 10903 } 10904 } 10905 10906 /* 10907 * Accept notify requests from non masters if they are on 10908 * 'zone->notify_acl'. 10909 */ 10910 if (i >= zone->masterscnt && zone->notify_acl != NULL && 10911 dns_acl_match(&netaddr, NULL, zone->notify_acl, 10912 &zone->view->aclenv, 10913 &match, NULL) == ISC_R_SUCCESS && 10914 match > 0) 10915 { 10916 /* Accept notify. */ 10917 } else if (i >= zone->masterscnt) { 10918 UNLOCK_ZONE(zone); 10919 dns_zone_log(zone, ISC_LOG_INFO, 10920 "refused notify from non-master: %s", fromtext); 10921 inc_stats(zone, dns_zonestatscounter_notifyrej); 10922 return (DNS_R_REFUSED); 10923 } 10924 10925 /* 10926 * If the zone is loaded and there are answers check the serial 10927 * to see if we need to do a refresh. Do not worry about this 10928 * check if we are a dialup zone as we use the notify request 10929 * to trigger a refresh check. 10930 */ 10931 if (msg->counts[DNS_SECTION_ANSWER] > 0 && 10932 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && 10933 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) { 10934 result = dns_message_findname(msg, DNS_SECTION_ANSWER, 10935 &zone->origin, 10936 dns_rdatatype_soa, 10937 dns_rdatatype_none, NULL, 10938 &rdataset); 10939 if (result == ISC_R_SUCCESS) 10940 result = dns_rdataset_first(rdataset); 10941 if (result == ISC_R_SUCCESS) { 10942 isc_uint32_t serial = 0, oldserial; 10943 10944 dns_rdataset_current(rdataset, &rdata); 10945 result = dns_rdata_tostruct(&rdata, &soa, NULL); 10946 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10947 serial = soa.serial; 10948 /* 10949 * The following should safely be performed without DB 10950 * lock and succeed in this context. 10951 */ 10952 result = zone_get_from_db(zone, zone->db, NULL, NULL, 10953 &oldserial, NULL, NULL, NULL, 10954 NULL, NULL); 10955 RUNTIME_CHECK(result == ISC_R_SUCCESS); 10956 if (isc_serial_le(serial, oldserial)) { 10957 dns_zone_log(zone, 10958 ISC_LOG_INFO, 10959 "notify from %s: " 10960 "zone is up to date", 10961 fromtext); 10962 UNLOCK_ZONE(zone); 10963 return (ISC_R_SUCCESS); 10964 } 10965 } 10966 } 10967 10968 /* 10969 * If we got this far and there was a refresh in progress just 10970 * let it complete. Record where we got the notify from so we 10971 * can perform a refresh check when the current one completes 10972 */ 10973 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) { 10974 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 10975 zone->notifyfrom = *from; 10976 UNLOCK_ZONE(zone); 10977 dns_zone_log(zone, ISC_LOG_INFO, 10978 "notify from %s: refresh in progress, " 10979 "refresh check queued", 10980 fromtext); 10981 return (ISC_R_SUCCESS); 10982 } 10983 zone->notifyfrom = *from; 10984 local = zone->masteraddr; 10985 remote = zone->sourceaddr; 10986 UNLOCK_ZONE(zone); 10987 dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote); 10988 dns_zone_refresh(zone); 10989 return (ISC_R_SUCCESS); 10990} 10991 10992void 10993dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) { 10994 10995 REQUIRE(DNS_ZONE_VALID(zone)); 10996 10997 LOCK_ZONE(zone); 10998 if (zone->notify_acl != NULL) 10999 dns_acl_detach(&zone->notify_acl); 11000 dns_acl_attach(acl, &zone->notify_acl); 11001 UNLOCK_ZONE(zone); 11002} 11003 11004void 11005dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) { 11006 11007 REQUIRE(DNS_ZONE_VALID(zone)); 11008 11009 LOCK_ZONE(zone); 11010 if (zone->query_acl != NULL) 11011 dns_acl_detach(&zone->query_acl); 11012 dns_acl_attach(acl, &zone->query_acl); 11013 UNLOCK_ZONE(zone); 11014} 11015 11016void 11017dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) { 11018 11019 REQUIRE(DNS_ZONE_VALID(zone)); 11020 11021 LOCK_ZONE(zone); 11022 if (zone->queryon_acl != NULL) 11023 dns_acl_detach(&zone->queryon_acl); 11024 dns_acl_attach(acl, &zone->queryon_acl); 11025 UNLOCK_ZONE(zone); 11026} 11027 11028void 11029dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) { 11030 11031 REQUIRE(DNS_ZONE_VALID(zone)); 11032 11033 LOCK_ZONE(zone); 11034 if (zone->update_acl != NULL) 11035 dns_acl_detach(&zone->update_acl); 11036 dns_acl_attach(acl, &zone->update_acl); 11037 UNLOCK_ZONE(zone); 11038} 11039 11040void 11041dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) { 11042 11043 REQUIRE(DNS_ZONE_VALID(zone)); 11044 11045 LOCK_ZONE(zone); 11046 if (zone->forward_acl != NULL) 11047 dns_acl_detach(&zone->forward_acl); 11048 dns_acl_attach(acl, &zone->forward_acl); 11049 UNLOCK_ZONE(zone); 11050} 11051 11052void 11053dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) { 11054 11055 REQUIRE(DNS_ZONE_VALID(zone)); 11056 11057 LOCK_ZONE(zone); 11058 if (zone->xfr_acl != NULL) 11059 dns_acl_detach(&zone->xfr_acl); 11060 dns_acl_attach(acl, &zone->xfr_acl); 11061 UNLOCK_ZONE(zone); 11062} 11063 11064dns_acl_t * 11065dns_zone_getnotifyacl(dns_zone_t *zone) { 11066 11067 REQUIRE(DNS_ZONE_VALID(zone)); 11068 11069 return (zone->notify_acl); 11070} 11071 11072dns_acl_t * 11073dns_zone_getqueryacl(dns_zone_t *zone) { 11074 11075 REQUIRE(DNS_ZONE_VALID(zone)); 11076 11077 return (zone->query_acl); 11078} 11079 11080dns_acl_t * 11081dns_zone_getqueryonacl(dns_zone_t *zone) { 11082 11083 REQUIRE(DNS_ZONE_VALID(zone)); 11084 11085 return (zone->queryon_acl); 11086} 11087 11088dns_acl_t * 11089dns_zone_getupdateacl(dns_zone_t *zone) { 11090 11091 REQUIRE(DNS_ZONE_VALID(zone)); 11092 11093 return (zone->update_acl); 11094} 11095 11096dns_acl_t * 11097dns_zone_getforwardacl(dns_zone_t *zone) { 11098 11099 REQUIRE(DNS_ZONE_VALID(zone)); 11100 11101 return (zone->forward_acl); 11102} 11103 11104dns_acl_t * 11105dns_zone_getxfracl(dns_zone_t *zone) { 11106 11107 REQUIRE(DNS_ZONE_VALID(zone)); 11108 11109 return (zone->xfr_acl); 11110} 11111 11112void 11113dns_zone_clearupdateacl(dns_zone_t *zone) { 11114 11115 REQUIRE(DNS_ZONE_VALID(zone)); 11116 11117 LOCK_ZONE(zone); 11118 if (zone->update_acl != NULL) 11119 dns_acl_detach(&zone->update_acl); 11120 UNLOCK_ZONE(zone); 11121} 11122 11123void 11124dns_zone_clearforwardacl(dns_zone_t *zone) { 11125 11126 REQUIRE(DNS_ZONE_VALID(zone)); 11127 11128 LOCK_ZONE(zone); 11129 if (zone->forward_acl != NULL) 11130 dns_acl_detach(&zone->forward_acl); 11131 UNLOCK_ZONE(zone); 11132} 11133 11134void 11135dns_zone_clearnotifyacl(dns_zone_t *zone) { 11136 11137 REQUIRE(DNS_ZONE_VALID(zone)); 11138 11139 LOCK_ZONE(zone); 11140 if (zone->notify_acl != NULL) 11141 dns_acl_detach(&zone->notify_acl); 11142 UNLOCK_ZONE(zone); 11143} 11144 11145void 11146dns_zone_clearqueryacl(dns_zone_t *zone) { 11147 11148 REQUIRE(DNS_ZONE_VALID(zone)); 11149 11150 LOCK_ZONE(zone); 11151 if (zone->query_acl != NULL) 11152 dns_acl_detach(&zone->query_acl); 11153 UNLOCK_ZONE(zone); 11154} 11155 11156void 11157dns_zone_clearqueryonacl(dns_zone_t *zone) { 11158 11159 REQUIRE(DNS_ZONE_VALID(zone)); 11160 11161 LOCK_ZONE(zone); 11162 if (zone->queryon_acl != NULL) 11163 dns_acl_detach(&zone->queryon_acl); 11164 UNLOCK_ZONE(zone); 11165} 11166 11167void 11168dns_zone_clearxfracl(dns_zone_t *zone) { 11169 11170 REQUIRE(DNS_ZONE_VALID(zone)); 11171 11172 LOCK_ZONE(zone); 11173 if (zone->xfr_acl != NULL) 11174 dns_acl_detach(&zone->xfr_acl); 11175 UNLOCK_ZONE(zone); 11176} 11177 11178isc_boolean_t 11179dns_zone_getupdatedisabled(dns_zone_t *zone) { 11180 REQUIRE(DNS_ZONE_VALID(zone)); 11181 return (zone->update_disabled); 11182 11183} 11184 11185void 11186dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) { 11187 REQUIRE(DNS_ZONE_VALID(zone)); 11188 zone->update_disabled = state; 11189} 11190 11191isc_boolean_t 11192dns_zone_getzeronosoattl(dns_zone_t *zone) { 11193 REQUIRE(DNS_ZONE_VALID(zone)); 11194 return (zone->zero_no_soa_ttl); 11195 11196} 11197 11198void 11199dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) { 11200 REQUIRE(DNS_ZONE_VALID(zone)); 11201 zone->zero_no_soa_ttl = state; 11202} 11203 11204void 11205dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) { 11206 11207 REQUIRE(DNS_ZONE_VALID(zone)); 11208 11209 zone->check_names = severity; 11210} 11211 11212dns_severity_t 11213dns_zone_getchecknames(dns_zone_t *zone) { 11214 11215 REQUIRE(DNS_ZONE_VALID(zone)); 11216 11217 return (zone->check_names); 11218} 11219 11220void 11221dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) { 11222 11223 REQUIRE(DNS_ZONE_VALID(zone)); 11224 11225 zone->journalsize = size; 11226} 11227 11228isc_int32_t 11229dns_zone_getjournalsize(dns_zone_t *zone) { 11230 11231 REQUIRE(DNS_ZONE_VALID(zone)); 11232 11233 return (zone->journalsize); 11234} 11235 11236static void 11237zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) { 11238 isc_result_t result = ISC_R_FAILURE; 11239 isc_buffer_t buffer; 11240 11241 REQUIRE(buf != NULL); 11242 REQUIRE(length > 1U); 11243 11244 /* 11245 * Leave space for terminating '\0'. 11246 */ 11247 isc_buffer_init(&buffer, buf, length - 1); 11248 if (dns_name_dynamic(&zone->origin)) 11249 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); 11250 if (result != ISC_R_SUCCESS && 11251 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1)) 11252 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 11253 11254 if (isc_buffer_availablelength(&buffer) > 0) 11255 isc_buffer_putstr(&buffer, "/"); 11256 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 11257 11258 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 && 11259 strcmp(zone->view->name, "_default") != 0 && 11260 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) { 11261 isc_buffer_putstr(&buffer, "/"); 11262 isc_buffer_putstr(&buffer, zone->view->name); 11263 } 11264 11265 buf[isc_buffer_usedlength(&buffer)] = '\0'; 11266} 11267 11268static void 11269zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) { 11270 isc_result_t result = ISC_R_FAILURE; 11271 isc_buffer_t buffer; 11272 11273 REQUIRE(buf != NULL); 11274 REQUIRE(length > 1U); 11275 11276 /* 11277 * Leave space for terminating '\0'. 11278 */ 11279 isc_buffer_init(&buffer, buf, length - 1); 11280 if (dns_name_dynamic(&zone->origin)) 11281 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); 11282 if (result != ISC_R_SUCCESS && 11283 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1)) 11284 isc_buffer_putstr(&buffer, "<UNKNOWN>"); 11285 11286 buf[isc_buffer_usedlength(&buffer)] = '\0'; 11287} 11288 11289static void 11290zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) { 11291 isc_buffer_t buffer; 11292 11293 REQUIRE(buf != NULL); 11294 REQUIRE(length > 1U); 11295 11296 /* 11297 * Leave space for terminating '\0'. 11298 */ 11299 isc_buffer_init(&buffer, buf, length - 1); 11300 (void)dns_rdataclass_totext(zone->rdclass, &buffer); 11301 11302 buf[isc_buffer_usedlength(&buffer)] = '\0'; 11303} 11304 11305static void 11306zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) { 11307 isc_buffer_t buffer; 11308 11309 REQUIRE(buf != NULL); 11310 REQUIRE(length > 1U); 11311 11312 11313 /* 11314 * Leave space for terminating '\0'. 11315 */ 11316 isc_buffer_init(&buffer, buf, length - 1); 11317 11318 if (zone->view == NULL) { 11319 isc_buffer_putstr(&buffer, "_none"); 11320 } else if (strlen(zone->view->name) 11321 < isc_buffer_availablelength(&buffer)) { 11322 isc_buffer_putstr(&buffer, zone->view->name); 11323 } else { 11324 isc_buffer_putstr(&buffer, "_toolong"); 11325 } 11326 11327 buf[isc_buffer_usedlength(&buffer)] = '\0'; 11328} 11329 11330void 11331dns_zone_name(dns_zone_t *zone, char *buf, size_t length) { 11332 REQUIRE(DNS_ZONE_VALID(zone)); 11333 REQUIRE(buf != NULL); 11334 zone_namerd_tostr(zone, buf, length); 11335} 11336 11337static void 11338notify_log(dns_zone_t *zone, int level, const char *fmt, ...) { 11339 va_list ap; 11340 char message[4096]; 11341 11342 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 11343 return; 11344 11345 va_start(ap, fmt); 11346 vsnprintf(message, sizeof(message), fmt, ap); 11347 va_end(ap); 11348 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE, 11349 level, "zone %s: %s", zone->strnamerd, message); 11350} 11351 11352void 11353dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, 11354 int level, const char *fmt, ...) { 11355 va_list ap; 11356 char message[4096]; 11357 11358 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 11359 return; 11360 11361 va_start(ap, fmt); 11362 vsnprintf(message, sizeof(message), fmt, ap); 11363 va_end(ap); 11364 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, 11365 level, "%s %s: %s", (zone->type == dns_zone_key) ? 11366 "managed-keys-zone" : "zone", zone->strnamerd, message); 11367} 11368 11369void 11370dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) { 11371 va_list ap; 11372 char message[4096]; 11373 11374 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 11375 return; 11376 11377 va_start(ap, fmt); 11378 vsnprintf(message, sizeof(message), fmt, ap); 11379 va_end(ap); 11380 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, 11381 level, "%s %s: %s", (zone->type == dns_zone_key) ? 11382 "managed-keys-zone" : "zone", zone->strnamerd, message); 11383} 11384 11385static void 11386zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel, 11387 const char *fmt, ...) 11388{ 11389 va_list ap; 11390 char message[4096]; 11391 int level = ISC_LOG_DEBUG(debuglevel); 11392 11393 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) 11394 return; 11395 11396 va_start(ap, fmt); 11397 vsnprintf(message, sizeof(message), fmt, ap); 11398 va_end(ap); 11399 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, 11400 level, "%s: %s %s: %s", me, zone->type != dns_zone_key ? 11401 "zone" : "managed-keys-zone", zone->strnamerd, message); 11402} 11403 11404static int 11405message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type) 11406{ 11407 isc_result_t result; 11408 dns_name_t *name; 11409 dns_rdataset_t *curr; 11410 int count = 0; 11411 11412 result = dns_message_firstname(msg, section); 11413 while (result == ISC_R_SUCCESS) { 11414 name = NULL; 11415 dns_message_currentname(msg, section, &name); 11416 11417 for (curr = ISC_LIST_TAIL(name->list); curr != NULL; 11418 curr = ISC_LIST_PREV(curr, link)) { 11419 if (curr->type == type) 11420 count++; 11421 } 11422 result = dns_message_nextname(msg, section); 11423 } 11424 11425 return (count); 11426} 11427 11428void 11429dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) { 11430 REQUIRE(DNS_ZONE_VALID(zone)); 11431 11432 zone->maxxfrin = maxxfrin; 11433} 11434 11435isc_uint32_t 11436dns_zone_getmaxxfrin(dns_zone_t *zone) { 11437 REQUIRE(DNS_ZONE_VALID(zone)); 11438 11439 return (zone->maxxfrin); 11440} 11441 11442void 11443dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) { 11444 REQUIRE(DNS_ZONE_VALID(zone)); 11445 zone->maxxfrout = maxxfrout; 11446} 11447 11448isc_uint32_t 11449dns_zone_getmaxxfrout(dns_zone_t *zone) { 11450 REQUIRE(DNS_ZONE_VALID(zone)); 11451 11452 return (zone->maxxfrout); 11453} 11454 11455dns_zonetype_t 11456dns_zone_gettype(dns_zone_t *zone) { 11457 REQUIRE(DNS_ZONE_VALID(zone)); 11458 11459 return (zone->type); 11460} 11461 11462dns_name_t * 11463dns_zone_getorigin(dns_zone_t *zone) { 11464 REQUIRE(DNS_ZONE_VALID(zone)); 11465 11466 return (&zone->origin); 11467} 11468 11469void 11470dns_zone_settask(dns_zone_t *zone, isc_task_t *task) { 11471 REQUIRE(DNS_ZONE_VALID(zone)); 11472 11473 LOCK_ZONE(zone); 11474 if (zone->task != NULL) 11475 isc_task_detach(&zone->task); 11476 isc_task_attach(task, &zone->task); 11477 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 11478 if (zone->db != NULL) 11479 dns_db_settask(zone->db, zone->task); 11480 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11481 UNLOCK_ZONE(zone); 11482} 11483 11484void 11485dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) { 11486 REQUIRE(DNS_ZONE_VALID(zone)); 11487 isc_task_attach(zone->task, target); 11488} 11489 11490void 11491dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) { 11492 REQUIRE(DNS_ZONE_VALID(zone)); 11493 11494 if (idlein == 0) 11495 idlein = DNS_DEFAULT_IDLEIN; 11496 zone->idlein = idlein; 11497} 11498 11499isc_uint32_t 11500dns_zone_getidlein(dns_zone_t *zone) { 11501 REQUIRE(DNS_ZONE_VALID(zone)); 11502 11503 return (zone->idlein); 11504} 11505 11506void 11507dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) { 11508 REQUIRE(DNS_ZONE_VALID(zone)); 11509 11510 zone->idleout = idleout; 11511} 11512 11513isc_uint32_t 11514dns_zone_getidleout(dns_zone_t *zone) { 11515 REQUIRE(DNS_ZONE_VALID(zone)); 11516 11517 return (zone->idleout); 11518} 11519 11520static void 11521notify_done(isc_task_t *task, isc_event_t *event) { 11522 dns_requestevent_t *revent = (dns_requestevent_t *)event; 11523 dns_notify_t *notify; 11524 isc_result_t result; 11525 dns_message_t *message = NULL; 11526 isc_buffer_t buf; 11527 char rcode[128]; 11528 char addrbuf[ISC_SOCKADDR_FORMATSIZE]; 11529 11530 UNUSED(task); 11531 11532 notify = event->ev_arg; 11533 REQUIRE(DNS_NOTIFY_VALID(notify)); 11534 INSIST(task == notify->zone->task); 11535 11536 isc_buffer_init(&buf, rcode, sizeof(rcode)); 11537 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); 11538 11539 result = revent->result; 11540 if (result == ISC_R_SUCCESS) 11541 result = dns_message_create(notify->zone->mctx, 11542 DNS_MESSAGE_INTENTPARSE, &message); 11543 if (result == ISC_R_SUCCESS) 11544 result = dns_request_getresponse(revent->request, message, 11545 DNS_MESSAGEPARSE_PRESERVEORDER); 11546 if (result == ISC_R_SUCCESS) 11547 result = dns_rcode_totext(message->rcode, &buf); 11548 if (result == ISC_R_SUCCESS) 11549 notify_log(notify->zone, ISC_LOG_DEBUG(3), 11550 "notify response from %s: %.*s", 11551 addrbuf, (int)buf.used, rcode); 11552 else 11553 notify_log(notify->zone, ISC_LOG_DEBUG(2), 11554 "notify to %s failed: %s", addrbuf, 11555 dns_result_totext(result)); 11556 11557 /* 11558 * Old bind's return formerr if they see a soa record. Retry w/o 11559 * the soa if we see a formerr and had sent a SOA. 11560 */ 11561 isc_event_free(&event); 11562 if (message != NULL && message->rcode == dns_rcode_formerr && 11563 (notify->flags & DNS_NOTIFY_NOSOA) == 0) { 11564 notify->flags |= DNS_NOTIFY_NOSOA; 11565 dns_request_destroy(¬ify->request); 11566 result = notify_send_queue(notify); 11567 if (result != ISC_R_SUCCESS) 11568 notify_destroy(notify, ISC_FALSE); 11569 } else { 11570 if (result == ISC_R_TIMEDOUT) 11571 notify_log(notify->zone, ISC_LOG_DEBUG(1), 11572 "notify to %s: retries exceeded", addrbuf); 11573 notify_destroy(notify, ISC_FALSE); 11574 } 11575 if (message != NULL) 11576 dns_message_destroy(&message); 11577} 11578 11579isc_result_t 11580dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { 11581 isc_result_t result; 11582 11583 REQUIRE(DNS_ZONE_VALID(zone)); 11584 LOCK_ZONE(zone); 11585 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); 11586 result = zone_replacedb(zone, db, dump); 11587 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); 11588 UNLOCK_ZONE(zone); 11589 return (result); 11590} 11591 11592static isc_result_t 11593zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { 11594 dns_dbversion_t *ver; 11595 isc_result_t result; 11596 unsigned int soacount = 0; 11597 unsigned int nscount = 0; 11598 11599 /* 11600 * 'zone' and 'zonedb' locked by caller. 11601 */ 11602 REQUIRE(DNS_ZONE_VALID(zone)); 11603 REQUIRE(LOCKED_ZONE(zone)); 11604 11605 result = zone_get_from_db(zone, db, &nscount, &soacount, 11606 NULL, NULL, NULL, NULL, NULL, NULL); 11607 if (result == ISC_R_SUCCESS) { 11608 if (soacount != 1) { 11609 dns_zone_log(zone, ISC_LOG_ERROR, 11610 "has %d SOA records", soacount); 11611 result = DNS_R_BADZONE; 11612 } 11613 if (nscount == 0 && zone->type != dns_zone_key) { 11614 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records"); 11615 result = DNS_R_BADZONE; 11616 } 11617 if (result != ISC_R_SUCCESS) 11618 return (result); 11619 } else { 11620 dns_zone_log(zone, ISC_LOG_ERROR, 11621 "retrieving SOA and NS records failed: %s", 11622 dns_result_totext(result)); 11623 return (result); 11624 } 11625 11626 result = check_nsec3param(zone, db); 11627 if (result != ISC_R_SUCCESS) 11628 return (result); 11629 11630 ver = NULL; 11631 dns_db_currentversion(db, &ver); 11632 11633 /* 11634 * The initial version of a slave zone is always dumped; 11635 * subsequent versions may be journaled instead if this 11636 * is enabled in the configuration. 11637 */ 11638 if (zone->db != NULL && zone->journal != NULL && 11639 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && 11640 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { 11641 isc_uint32_t serial, oldserial; 11642 11643 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs"); 11644 11645 result = dns_db_getsoaserial(db, ver, &serial); 11646 if (result != ISC_R_SUCCESS) { 11647 dns_zone_log(zone, ISC_LOG_ERROR, 11648 "ixfr-from-differences: unable to get " 11649 "new serial"); 11650 goto fail; 11651 } 11652 11653 /* 11654 * This is checked in zone_postload() for master zones. 11655 */ 11656 result = zone_get_from_db(zone, zone->db, NULL, NULL, 11657 &oldserial, NULL, NULL, NULL, NULL, 11658 NULL); 11659 RUNTIME_CHECK(result == ISC_R_SUCCESS); 11660 if (zone->type == dns_zone_slave && 11661 !isc_serial_gt(serial, oldserial)) { 11662 isc_uint32_t serialmin, serialmax; 11663 serialmin = (oldserial + 1) & 0xffffffffU; 11664 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; 11665 dns_zone_log(zone, ISC_LOG_ERROR, 11666 "ixfr-from-differences: failed: " 11667 "new serial (%u) out of range [%u - %u]", 11668 serial, serialmin, serialmax); 11669 result = ISC_R_RANGE; 11670 goto fail; 11671 } 11672 11673 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL, 11674 zone->journal); 11675 if (result != ISC_R_SUCCESS) 11676 goto fail; 11677 if (dump) 11678 zone_needdump(zone, DNS_DUMP_DELAY); 11679 else if (zone->journalsize != -1) { 11680 result = dns_journal_compact(zone->mctx, zone->journal, 11681 serial, zone->journalsize); 11682 switch (result) { 11683 case ISC_R_SUCCESS: 11684 case ISC_R_NOSPACE: 11685 case ISC_R_NOTFOUND: 11686 dns_zone_log(zone, ISC_LOG_DEBUG(3), 11687 "dns_journal_compact: %s", 11688 dns_result_totext(result)); 11689 break; 11690 default: 11691 dns_zone_log(zone, ISC_LOG_ERROR, 11692 "dns_journal_compact failed: %s", 11693 dns_result_totext(result)); 11694 break; 11695 } 11696 } 11697 } else { 11698 if (dump && zone->masterfile != NULL) { 11699 /* 11700 * If DNS_ZONEFLG_FORCEXFER was set we don't want 11701 * to keep the old masterfile. 11702 */ 11703 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) && 11704 remove(zone->masterfile) < 0 && errno != ENOENT) { 11705 char strbuf[ISC_STRERRORSIZE]; 11706 isc__strerror(errno, strbuf, sizeof(strbuf)); 11707 isc_log_write(dns_lctx, 11708 DNS_LOGCATEGORY_GENERAL, 11709 DNS_LOGMODULE_ZONE, 11710 ISC_LOG_WARNING, 11711 "unable to remove masterfile " 11712 "'%s': '%s'", 11713 zone->masterfile, strbuf); 11714 } 11715 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) 11716 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY); 11717 else 11718 zone_needdump(zone, 0); 11719 } 11720 if (dump && zone->journal != NULL) { 11721 /* 11722 * The in-memory database just changed, and 11723 * because 'dump' is set, it didn't change by 11724 * being loaded from disk. Also, we have not 11725 * journaled diffs for this change. 11726 * Therefore, the on-disk journal is missing 11727 * the deltas for this change. Since it can 11728 * no longer be used to bring the zone 11729 * up-to-date, it is useless and should be 11730 * removed. 11731 */ 11732 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 11733 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 11734 "removing journal file"); 11735 if (remove(zone->journal) < 0 && errno != ENOENT) { 11736 char strbuf[ISC_STRERRORSIZE]; 11737 isc__strerror(errno, strbuf, sizeof(strbuf)); 11738 isc_log_write(dns_lctx, 11739 DNS_LOGCATEGORY_GENERAL, 11740 DNS_LOGMODULE_ZONE, 11741 ISC_LOG_WARNING, 11742 "unable to remove journal " 11743 "'%s': '%s'", 11744 zone->journal, strbuf); 11745 } 11746 } 11747 } 11748 11749 dns_db_closeversion(db, &ver, ISC_FALSE); 11750 11751 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 11752 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 11753 "replacing zone database"); 11754 11755 if (zone->db != NULL) 11756 zone_detachdb(zone); 11757 zone_attachdb(zone, db); 11758 dns_db_settask(zone->db, zone->task); 11759 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY); 11760 return (ISC_R_SUCCESS); 11761 11762 fail: 11763 dns_db_closeversion(db, &ver, ISC_FALSE); 11764 return (result); 11765} 11766 11767/* The caller must hold the dblock as a writer. */ 11768static inline void 11769zone_attachdb(dns_zone_t *zone, dns_db_t *db) { 11770 REQUIRE(zone->db == NULL && db != NULL); 11771 11772 dns_db_attach(db, &zone->db); 11773 if (zone->acache != NULL) { 11774 isc_result_t result; 11775 result = dns_acache_setdb(zone->acache, db); 11776 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { 11777 UNEXPECTED_ERROR(__FILE__, __LINE__, 11778 "dns_acache_setdb() failed: %s", 11779 isc_result_totext(result)); 11780 } 11781 } 11782} 11783 11784/* The caller must hold the dblock as a writer. */ 11785static inline void 11786zone_detachdb(dns_zone_t *zone) { 11787 REQUIRE(zone->db != NULL); 11788 11789 if (zone->acache != NULL) 11790 (void)dns_acache_putdb(zone->acache, zone->db); 11791 dns_db_detach(&zone->db); 11792} 11793 11794static void 11795zone_xfrdone(dns_zone_t *zone, isc_result_t result) { 11796 isc_time_t now; 11797 isc_boolean_t again = ISC_FALSE; 11798 unsigned int soacount; 11799 unsigned int nscount; 11800 isc_uint32_t serial, refresh, retry, expire, minimum; 11801 isc_result_t xfrresult = result; 11802 isc_boolean_t free_needed; 11803 11804 REQUIRE(DNS_ZONE_VALID(zone)); 11805 11806 dns_zone_log(zone, ISC_LOG_DEBUG(1), 11807 "zone transfer finished: %s", dns_result_totext(result)); 11808 11809 LOCK_ZONE(zone); 11810 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0); 11811 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); 11812 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); 11813 11814 TIME_NOW(&now); 11815 switch (result) { 11816 case ISC_R_SUCCESS: 11817 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 11818 /*FALLTHROUGH*/ 11819 case DNS_R_UPTODATE: 11820 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER); 11821 /* 11822 * Has the zone expired underneath us? 11823 */ 11824 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); 11825 if (zone->db == NULL) { 11826 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11827 goto same_master; 11828 } 11829 11830 /* 11831 * Update the zone structure's data from the actual 11832 * SOA received. 11833 */ 11834 nscount = 0; 11835 soacount = 0; 11836 INSIST(zone->db != NULL); 11837 result = zone_get_from_db(zone, zone->db, &nscount, 11838 &soacount, &serial, &refresh, 11839 &retry, &expire, &minimum, NULL); 11840 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); 11841 if (result == ISC_R_SUCCESS) { 11842 if (soacount != 1) 11843 dns_zone_log(zone, ISC_LOG_ERROR, 11844 "transferred zone " 11845 "has %d SOA record%s", soacount, 11846 (soacount != 0) ? "s" : ""); 11847 if (nscount == 0) { 11848 dns_zone_log(zone, ISC_LOG_ERROR, 11849 "transferred zone " 11850 "has no NS records"); 11851 if (DNS_ZONE_FLAG(zone, 11852 DNS_ZONEFLG_HAVETIMERS)) { 11853 zone->refresh = DNS_ZONE_DEFAULTREFRESH; 11854 zone->retry = DNS_ZONE_DEFAULTRETRY; 11855 } 11856 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 11857 zone_unload(zone); 11858 goto next_master; 11859 } 11860 zone->refresh = RANGE(refresh, zone->minrefresh, 11861 zone->maxrefresh); 11862 zone->retry = RANGE(retry, zone->minretry, 11863 zone->maxretry); 11864 zone->expire = RANGE(expire, 11865 zone->refresh + zone->retry, 11866 DNS_MAX_EXPIRE); 11867 zone->minimum = minimum; 11868 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); 11869 } 11870 11871 /* 11872 * Set our next update/expire times. 11873 */ 11874 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) { 11875 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH); 11876 zone->refreshtime = now; 11877 DNS_ZONE_TIME_ADD(&now, zone->expire, 11878 &zone->expiretime); 11879 } else { 11880 DNS_ZONE_JITTER_ADD(&now, zone->refresh, 11881 &zone->refreshtime); 11882 DNS_ZONE_TIME_ADD(&now, zone->expire, 11883 &zone->expiretime); 11884 } 11885 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) { 11886 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")]; 11887 if (zone->tsigkey != NULL) { 11888 char namebuf[DNS_NAME_FORMATSIZE]; 11889 dns_name_format(&zone->tsigkey->name, namebuf, 11890 sizeof(namebuf)); 11891 snprintf(buf, sizeof(buf), ": TSIG '%s'", 11892 namebuf); 11893 } else 11894 buf[0] = '\0'; 11895 dns_zone_log(zone, ISC_LOG_INFO, 11896 "transferred serial %u%s", 11897 serial, buf); 11898 } 11899 11900 /* 11901 * This is not necessary if we just performed a AXFR 11902 * however it is necessary for an IXFR / UPTODATE and 11903 * won't hurt with an AXFR. 11904 */ 11905 if (zone->masterfile != NULL || zone->journal != NULL) { 11906 result = ISC_R_FAILURE; 11907 if (zone->journal != NULL) 11908 result = isc_file_settime(zone->journal, &now); 11909 if (result != ISC_R_SUCCESS && 11910 zone->masterfile != NULL) 11911 result = isc_file_settime(zone->masterfile, 11912 &now); 11913 /* Someone removed the file from underneath us! */ 11914 if (result == ISC_R_FILENOTFOUND && 11915 zone->masterfile != NULL) { 11916 unsigned int delay = DNS_DUMP_DELAY; 11917 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY)) 11918 delay = 0; 11919 zone_needdump(zone, delay); 11920 } else if (result != ISC_R_SUCCESS) 11921 dns_zone_log(zone, ISC_LOG_ERROR, 11922 "transfer: could not set file " 11923 "modification time of '%s': %s", 11924 zone->masterfile, 11925 dns_result_totext(result)); 11926 } 11927 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY); 11928 inc_stats(zone, dns_zonestatscounter_xfrsuccess); 11929 break; 11930 11931 case DNS_R_BADIXFR: 11932 /* Force retry with AXFR. */ 11933 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR); 11934 goto same_master; 11935 11936 default: 11937 next_master: 11938 /* 11939 * Skip to next failed / untried master. 11940 */ 11941 do { 11942 zone->curmaster++; 11943 } while (zone->curmaster < zone->masterscnt && 11944 zone->mastersok[zone->curmaster]); 11945 /* FALLTHROUGH */ 11946 same_master: 11947 if (zone->curmaster >= zone->masterscnt) { 11948 zone->curmaster = 0; 11949 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) && 11950 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) { 11951 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 11952 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 11953 while (zone->curmaster < zone->masterscnt && 11954 zone->mastersok[zone->curmaster]) 11955 zone->curmaster++; 11956 again = ISC_TRUE; 11957 } else 11958 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); 11959 } else { 11960 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH); 11961 again = ISC_TRUE; 11962 } 11963 inc_stats(zone, dns_zonestatscounter_xfrfail); 11964 break; 11965 } 11966 zone_settimer(zone, &now); 11967 11968 /* 11969 * If creating the transfer object failed, zone->xfr is NULL. 11970 * Otherwise, we are called as the done callback of a zone 11971 * transfer object that just entered its shutting-down 11972 * state. Since we are no longer responsible for shutting 11973 * it down, we can detach our reference. 11974 */ 11975 if (zone->xfr != NULL) 11976 dns_xfrin_detach(&zone->xfr); 11977 11978 if (zone->tsigkey != NULL) 11979 dns_tsigkey_detach(&zone->tsigkey); 11980 11981 /* 11982 * Handle any deferred journal compaction. 11983 */ 11984 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) { 11985 result = dns_journal_compact(zone->mctx, zone->journal, 11986 zone->compact_serial, 11987 zone->journalsize); 11988 switch (result) { 11989 case ISC_R_SUCCESS: 11990 case ISC_R_NOSPACE: 11991 case ISC_R_NOTFOUND: 11992 dns_zone_log(zone, ISC_LOG_DEBUG(3), 11993 "dns_journal_compact: %s", 11994 dns_result_totext(result)); 11995 break; 11996 default: 11997 dns_zone_log(zone, ISC_LOG_ERROR, 11998 "dns_journal_compact failed: %s", 11999 dns_result_totext(result)); 12000 break; 12001 } 12002 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT); 12003 } 12004 12005 /* 12006 * This transfer finishing freed up a transfer quota slot. 12007 * Let any other zones waiting for quota have it. 12008 */ 12009 UNLOCK_ZONE(zone); 12010 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 12011 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink); 12012 zone->statelist = NULL; 12013 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE); 12014 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); 12015 LOCK_ZONE(zone); 12016 12017 /* 12018 * Retry with a different server if necessary. 12019 */ 12020 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) 12021 queue_soa_query(zone); 12022 12023 INSIST(zone->irefs > 0); 12024 zone->irefs--; 12025 free_needed = exit_check(zone); 12026 UNLOCK_ZONE(zone); 12027 if (free_needed) 12028 zone_free(zone); 12029} 12030 12031static void 12032zone_loaddone(void *arg, isc_result_t result) { 12033 static char me[] = "zone_loaddone"; 12034 dns_load_t *load = arg; 12035 dns_zone_t *zone; 12036 isc_result_t tresult; 12037 12038 REQUIRE(DNS_LOAD_VALID(load)); 12039 zone = load->zone; 12040 12041 ENTER; 12042 12043 tresult = dns_db_endload(load->db, &load->callbacks.add_private); 12044 if (tresult != ISC_R_SUCCESS && 12045 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)) 12046 result = tresult; 12047 12048 LOCK_ZONE(load->zone); 12049 (void)zone_postload(load->zone, load->db, load->loadtime, result); 12050 zonemgr_putio(&load->zone->readio); 12051 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING); 12052 /* 12053 * Leave the zone frozen if the reload fails. 12054 */ 12055 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) && 12056 DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW)) 12057 zone->update_disabled = ISC_FALSE; 12058 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW); 12059 UNLOCK_ZONE(load->zone); 12060 12061 load->magic = 0; 12062 dns_db_detach(&load->db); 12063 if (load->zone->lctx != NULL) 12064 dns_loadctx_detach(&load->zone->lctx); 12065 dns_zone_idetach(&load->zone); 12066 isc_mem_putanddetach(&load->mctx, load, sizeof(*load)); 12067} 12068 12069void 12070dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) { 12071 REQUIRE(DNS_ZONE_VALID(zone)); 12072 REQUIRE(table != NULL); 12073 REQUIRE(*table == NULL); 12074 12075 LOCK_ZONE(zone); 12076 if (zone->ssutable != NULL) 12077 dns_ssutable_attach(zone->ssutable, table); 12078 UNLOCK_ZONE(zone); 12079} 12080 12081void 12082dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) { 12083 REQUIRE(DNS_ZONE_VALID(zone)); 12084 12085 LOCK_ZONE(zone); 12086 if (zone->ssutable != NULL) 12087 dns_ssutable_detach(&zone->ssutable); 12088 if (table != NULL) 12089 dns_ssutable_attach(table, &zone->ssutable); 12090 UNLOCK_ZONE(zone); 12091} 12092 12093void 12094dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) { 12095 REQUIRE(DNS_ZONE_VALID(zone)); 12096 12097 zone->sigvalidityinterval = interval; 12098} 12099 12100isc_uint32_t 12101dns_zone_getsigvalidityinterval(dns_zone_t *zone) { 12102 REQUIRE(DNS_ZONE_VALID(zone)); 12103 12104 return (zone->sigvalidityinterval); 12105} 12106 12107void 12108dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) { 12109 REQUIRE(DNS_ZONE_VALID(zone)); 12110 12111 zone->sigresigninginterval = interval; 12112} 12113 12114isc_uint32_t 12115dns_zone_getsigresigninginterval(dns_zone_t *zone) { 12116 REQUIRE(DNS_ZONE_VALID(zone)); 12117 12118 return (zone->sigresigninginterval); 12119} 12120 12121static void 12122queue_xfrin(dns_zone_t *zone) { 12123 const char me[] = "queue_xfrin"; 12124 isc_result_t result; 12125 dns_zonemgr_t *zmgr = zone->zmgr; 12126 12127 ENTER; 12128 12129 INSIST(zone->statelist == NULL); 12130 12131 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 12132 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink); 12133 LOCK_ZONE(zone); 12134 zone->irefs++; 12135 UNLOCK_ZONE(zone); 12136 zone->statelist = &zmgr->waiting_for_xfrin; 12137 result = zmgr_start_xfrin_ifquota(zmgr, zone); 12138 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 12139 12140 if (result == ISC_R_QUOTA) { 12141 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO, 12142 "zone transfer deferred due to quota"); 12143 } else if (result != ISC_R_SUCCESS) { 12144 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR, 12145 "starting zone transfer: %s", 12146 isc_result_totext(result)); 12147 } 12148} 12149 12150/* 12151 * This event callback is called when a zone has received 12152 * any necessary zone transfer quota. This is the time 12153 * to go ahead and start the transfer. 12154 */ 12155static void 12156got_transfer_quota(isc_task_t *task, isc_event_t *event) { 12157 isc_result_t result; 12158 dns_peer_t *peer = NULL; 12159 char master[ISC_SOCKADDR_FORMATSIZE]; 12160 char source[ISC_SOCKADDR_FORMATSIZE]; 12161 dns_rdatatype_t xfrtype; 12162 dns_zone_t *zone = event->ev_arg; 12163 isc_netaddr_t masterip; 12164 isc_sockaddr_t sourceaddr; 12165 isc_sockaddr_t masteraddr; 12166 isc_time_t now; 12167 const char *soa_before = ""; 12168 12169 UNUSED(task); 12170 12171 INSIST(task == zone->task); 12172 12173 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 12174 result = ISC_R_CANCELED; 12175 goto cleanup; 12176 } 12177 12178 TIME_NOW(&now); 12179 12180 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); 12181 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, 12182 &zone->sourceaddr, &now)) 12183 { 12184 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); 12185 dns_zone_log(zone, ISC_LOG_INFO, 12186 "got_transfer_quota: skipping zone transfer as " 12187 "master %s (source %s) is unreachable (cached)", 12188 master, source); 12189 result = ISC_R_CANCELED; 12190 goto cleanup; 12191 } 12192 12193 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 12194 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer); 12195 12196 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) 12197 soa_before = "SOA before "; 12198 /* 12199 * Decide whether we should request IXFR or AXFR. 12200 */ 12201 if (zone->db == NULL) { 12202 dns_zone_log(zone, ISC_LOG_DEBUG(1), 12203 "no database exists yet, requesting AXFR of " 12204 "initial version from %s", master); 12205 xfrtype = dns_rdatatype_axfr; 12206 } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) { 12207 dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences " 12208 "set, requesting %sAXFR from %s", soa_before, 12209 master); 12210 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) 12211 xfrtype = dns_rdatatype_soa; 12212 else 12213 xfrtype = dns_rdatatype_axfr; 12214 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { 12215 dns_zone_log(zone, ISC_LOG_DEBUG(1), 12216 "forced reload, requesting AXFR of " 12217 "initial version from %s", master); 12218 xfrtype = dns_rdatatype_axfr; 12219 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) { 12220 dns_zone_log(zone, ISC_LOG_DEBUG(1), 12221 "retrying with AXFR from %s due to " 12222 "previous IXFR failure", master); 12223 xfrtype = dns_rdatatype_axfr; 12224 LOCK_ZONE(zone); 12225 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR); 12226 UNLOCK_ZONE(zone); 12227 } else { 12228 isc_boolean_t use_ixfr = ISC_TRUE; 12229 if (peer != NULL && 12230 dns_peer_getrequestixfr(peer, &use_ixfr) == 12231 ISC_R_SUCCESS) { 12232 ; /* Using peer setting */ 12233 } else { 12234 use_ixfr = zone->view->requestixfr; 12235 } 12236 if (use_ixfr == ISC_FALSE) { 12237 dns_zone_log(zone, ISC_LOG_DEBUG(1), 12238 "IXFR disabled, requesting %sAXFR from %s", 12239 soa_before, master); 12240 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) 12241 xfrtype = dns_rdatatype_soa; 12242 else 12243 xfrtype = dns_rdatatype_axfr; 12244 } else { 12245 dns_zone_log(zone, ISC_LOG_DEBUG(1), 12246 "requesting IXFR from %s", master); 12247 xfrtype = dns_rdatatype_ixfr; 12248 } 12249 } 12250 12251 /* 12252 * Determine if we should attempt to sign the request with TSIG. 12253 */ 12254 result = ISC_R_NOTFOUND; 12255 /* 12256 * First, look for a tsig key in the master statement, then 12257 * try for a server key. 12258 */ 12259 if ((zone->masterkeynames != NULL) && 12260 (zone->masterkeynames[zone->curmaster] != NULL)) { 12261 dns_view_t *view = dns_zone_getview(zone); 12262 dns_name_t *keyname = zone->masterkeynames[zone->curmaster]; 12263 result = dns_view_gettsig(view, keyname, &zone->tsigkey); 12264 } 12265 if (zone->tsigkey == NULL) 12266 result = dns_view_getpeertsig(zone->view, &masterip, 12267 &zone->tsigkey); 12268 12269 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { 12270 dns_zone_log(zone, ISC_LOG_ERROR, 12271 "could not get TSIG key for zone transfer: %s", 12272 isc_result_totext(result)); 12273 } 12274 12275 LOCK_ZONE(zone); 12276 masteraddr = zone->masteraddr; 12277 sourceaddr = zone->sourceaddr; 12278 UNLOCK_ZONE(zone); 12279 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr)); 12280 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr, 12281 zone->tsigkey, zone->mctx, 12282 zone->zmgr->timermgr, zone->zmgr->socketmgr, 12283 zone->task, zone_xfrdone, &zone->xfr); 12284 if (result == ISC_R_SUCCESS) { 12285 LOCK_ZONE(zone); 12286 if (xfrtype == dns_rdatatype_axfr) { 12287 if (isc_sockaddr_pf(&masteraddr) == PF_INET) 12288 inc_stats(zone, dns_zonestatscounter_axfrreqv4); 12289 else 12290 inc_stats(zone, dns_zonestatscounter_axfrreqv6); 12291 } else if (xfrtype == dns_rdatatype_ixfr) { 12292 if (isc_sockaddr_pf(&masteraddr) == PF_INET) 12293 inc_stats(zone, dns_zonestatscounter_ixfrreqv4); 12294 else 12295 inc_stats(zone, dns_zonestatscounter_ixfrreqv6); 12296 } 12297 UNLOCK_ZONE(zone); 12298 } 12299 cleanup: 12300 /* 12301 * Any failure in this function is handled like a failed 12302 * zone transfer. This ensures that we get removed from 12303 * zmgr->xfrin_in_progress. 12304 */ 12305 if (result != ISC_R_SUCCESS) 12306 zone_xfrdone(zone, result); 12307 12308 isc_event_free(&event); 12309} 12310 12311/* 12312 * Update forwarding support. 12313 */ 12314 12315static void 12316forward_destroy(dns_forward_t *forward) { 12317 12318 forward->magic = 0; 12319 if (forward->request != NULL) 12320 dns_request_destroy(&forward->request); 12321 if (forward->msgbuf != NULL) 12322 isc_buffer_free(&forward->msgbuf); 12323 if (forward->zone != NULL) { 12324 LOCK(&forward->zone->lock); 12325 if (ISC_LINK_LINKED(forward, link)) 12326 ISC_LIST_UNLINK(forward->zone->forwards, forward, link); 12327 UNLOCK(&forward->zone->lock); 12328 dns_zone_idetach(&forward->zone); 12329 } 12330 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward)); 12331} 12332 12333static isc_result_t 12334sendtomaster(dns_forward_t *forward) { 12335 isc_result_t result; 12336 isc_sockaddr_t src; 12337 12338 LOCK_ZONE(forward->zone); 12339 12340 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) { 12341 UNLOCK_ZONE(forward->zone); 12342 return (ISC_R_CANCELED); 12343 } 12344 12345 if (forward->which >= forward->zone->masterscnt) { 12346 UNLOCK_ZONE(forward->zone); 12347 return (ISC_R_NOMORE); 12348 } 12349 12350 forward->addr = forward->zone->masters[forward->which]; 12351 /* 12352 * Always use TCP regardless of whether the original update 12353 * used TCP. 12354 * XXX The timeout may but a bit small if we are far down a 12355 * transfer graph and the master has to try several masters. 12356 */ 12357 switch (isc_sockaddr_pf(&forward->addr)) { 12358 case PF_INET: 12359 src = forward->zone->xfrsource4; 12360 break; 12361 case PF_INET6: 12362 src = forward->zone->xfrsource6; 12363 break; 12364 default: 12365 result = ISC_R_NOTIMPLEMENTED; 12366 goto unlock; 12367 } 12368 result = dns_request_createraw(forward->zone->view->requestmgr, 12369 forward->msgbuf, 12370 &src, &forward->addr, 12371 DNS_REQUESTOPT_TCP, 15 /* XXX */, 12372 forward->zone->task, 12373 forward_callback, forward, 12374 &forward->request); 12375 if (result == ISC_R_SUCCESS) { 12376 if (!ISC_LINK_LINKED(forward, link)) 12377 ISC_LIST_APPEND(forward->zone->forwards, forward, link); 12378 } 12379 12380 unlock: 12381 UNLOCK_ZONE(forward->zone); 12382 return (result); 12383} 12384 12385static void 12386forward_callback(isc_task_t *task, isc_event_t *event) { 12387 const char me[] = "forward_callback"; 12388 dns_requestevent_t *revent = (dns_requestevent_t *)event; 12389 dns_message_t *msg = NULL; 12390 char master[ISC_SOCKADDR_FORMATSIZE]; 12391 isc_result_t result; 12392 dns_forward_t *forward; 12393 dns_zone_t *zone; 12394 12395 UNUSED(task); 12396 12397 forward = revent->ev_arg; 12398 INSIST(DNS_FORWARD_VALID(forward)); 12399 zone = forward->zone; 12400 INSIST(DNS_ZONE_VALID(zone)); 12401 12402 ENTER; 12403 12404 isc_sockaddr_format(&forward->addr, master, sizeof(master)); 12405 12406 if (revent->result != ISC_R_SUCCESS) { 12407 dns_zone_log(zone, ISC_LOG_INFO, 12408 "could not forward dynamic update to %s: %s", 12409 master, dns_result_totext(revent->result)); 12410 goto next_master; 12411 } 12412 12413 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); 12414 if (result != ISC_R_SUCCESS) 12415 goto next_master; 12416 12417 result = dns_request_getresponse(revent->request, msg, 12418 DNS_MESSAGEPARSE_PRESERVEORDER | 12419 DNS_MESSAGEPARSE_CLONEBUFFER); 12420 if (result != ISC_R_SUCCESS) 12421 goto next_master; 12422 12423 switch (msg->rcode) { 12424 /* 12425 * Pass these rcodes back to client. 12426 */ 12427 case dns_rcode_noerror: 12428 case dns_rcode_yxdomain: 12429 case dns_rcode_yxrrset: 12430 case dns_rcode_nxrrset: 12431 case dns_rcode_refused: 12432 case dns_rcode_nxdomain: 12433 break; 12434 12435 /* These should not occur if the masters/zone are valid. */ 12436 case dns_rcode_notzone: 12437 case dns_rcode_notauth: { 12438 char rcode[128]; 12439 isc_buffer_t rb; 12440 12441 isc_buffer_init(&rb, rcode, sizeof(rcode)); 12442 (void)dns_rcode_totext(msg->rcode, &rb); 12443 dns_zone_log(zone, ISC_LOG_WARNING, 12444 "forwarding dynamic update: " 12445 "unexpected response: master %s returned: %.*s", 12446 master, (int)rb.used, rcode); 12447 goto next_master; 12448 } 12449 12450 /* Try another server for these rcodes. */ 12451 case dns_rcode_formerr: 12452 case dns_rcode_servfail: 12453 case dns_rcode_notimp: 12454 case dns_rcode_badvers: 12455 default: 12456 goto next_master; 12457 } 12458 12459 /* call callback */ 12460 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg); 12461 msg = NULL; 12462 dns_request_destroy(&forward->request); 12463 forward_destroy(forward); 12464 isc_event_free(&event); 12465 return; 12466 12467 next_master: 12468 if (msg != NULL) 12469 dns_message_destroy(&msg); 12470 isc_event_free(&event); 12471 forward->which++; 12472 dns_request_destroy(&forward->request); 12473 result = sendtomaster(forward); 12474 if (result != ISC_R_SUCCESS) { 12475 /* call callback */ 12476 dns_zone_log(zone, ISC_LOG_DEBUG(3), 12477 "exhausted dynamic update forwarder list"); 12478 (forward->callback)(forward->callback_arg, result, NULL); 12479 forward_destroy(forward); 12480 } 12481} 12482 12483isc_result_t 12484dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg, 12485 dns_updatecallback_t callback, void *callback_arg) 12486{ 12487 dns_forward_t *forward; 12488 isc_result_t result; 12489 isc_region_t *mr; 12490 12491 REQUIRE(DNS_ZONE_VALID(zone)); 12492 REQUIRE(msg != NULL); 12493 REQUIRE(callback != NULL); 12494 12495 forward = isc_mem_get(zone->mctx, sizeof(*forward)); 12496 if (forward == NULL) 12497 return (ISC_R_NOMEMORY); 12498 12499 forward->request = NULL; 12500 forward->zone = NULL; 12501 forward->msgbuf = NULL; 12502 forward->which = 0; 12503 forward->mctx = 0; 12504 forward->callback = callback; 12505 forward->callback_arg = callback_arg; 12506 ISC_LINK_INIT(forward, link); 12507 forward->magic = FORWARD_MAGIC; 12508 12509 mr = dns_message_getrawmessage(msg); 12510 if (mr == NULL) { 12511 result = ISC_R_UNEXPECTEDEND; 12512 goto cleanup; 12513 } 12514 12515 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length); 12516 if (result != ISC_R_SUCCESS) 12517 goto cleanup; 12518 result = isc_buffer_copyregion(forward->msgbuf, mr); 12519 if (result != ISC_R_SUCCESS) 12520 goto cleanup; 12521 12522 isc_mem_attach(zone->mctx, &forward->mctx); 12523 dns_zone_iattach(zone, &forward->zone); 12524 result = sendtomaster(forward); 12525 12526 cleanup: 12527 if (result != ISC_R_SUCCESS) { 12528 forward_destroy(forward); 12529 } 12530 return (result); 12531} 12532 12533isc_result_t 12534dns_zone_next(dns_zone_t *zone, dns_zone_t **next) { 12535 REQUIRE(DNS_ZONE_VALID(zone)); 12536 REQUIRE(next != NULL && *next == NULL); 12537 12538 *next = ISC_LIST_NEXT(zone, link); 12539 if (*next == NULL) 12540 return (ISC_R_NOMORE); 12541 else 12542 return (ISC_R_SUCCESS); 12543} 12544 12545isc_result_t 12546dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) { 12547 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 12548 REQUIRE(first != NULL && *first == NULL); 12549 12550 *first = ISC_LIST_HEAD(zmgr->zones); 12551 if (*first == NULL) 12552 return (ISC_R_NOMORE); 12553 else 12554 return (ISC_R_SUCCESS); 12555} 12556 12557/*** 12558 *** Zone manager. 12559 ***/ 12560 12561isc_result_t 12562dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, 12563 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, 12564 dns_zonemgr_t **zmgrp) 12565{ 12566 dns_zonemgr_t *zmgr; 12567 isc_result_t result; 12568 isc_interval_t interval; 12569 12570 zmgr = isc_mem_get(mctx, sizeof(*zmgr)); 12571 if (zmgr == NULL) 12572 return (ISC_R_NOMEMORY); 12573 zmgr->mctx = NULL; 12574 zmgr->refs = 1; 12575 isc_mem_attach(mctx, &zmgr->mctx); 12576 zmgr->taskmgr = taskmgr; 12577 zmgr->timermgr = timermgr; 12578 zmgr->socketmgr = socketmgr; 12579 zmgr->zonetasks = NULL; 12580 zmgr->task = NULL; 12581 zmgr->rl = NULL; 12582 ISC_LIST_INIT(zmgr->zones); 12583 ISC_LIST_INIT(zmgr->waiting_for_xfrin); 12584 ISC_LIST_INIT(zmgr->xfrin_in_progress); 12585 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable)); 12586 result = isc_rwlock_init(&zmgr->rwlock, 0, 0); 12587 if (result != ISC_R_SUCCESS) 12588 goto free_mem; 12589 12590 zmgr->transfersin = 10; 12591 zmgr->transfersperns = 2; 12592 12593 /* Unreachable lock. */ 12594 result = isc_rwlock_init(&zmgr->urlock, 0, 0); 12595 if (result != ISC_R_SUCCESS) 12596 goto free_rwlock; 12597 12598 /* Create a single task for queueing of SOA queries. */ 12599 result = isc_task_create(taskmgr, 1, &zmgr->task); 12600 if (result != ISC_R_SUCCESS) 12601 goto free_urlock; 12602 12603 isc_task_setname(zmgr->task, "zmgr", zmgr); 12604 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, 12605 &zmgr->rl); 12606 if (result != ISC_R_SUCCESS) 12607 goto free_task; 12608 12609 /* default to 20 refresh queries / notifies per second. */ 12610 isc_interval_set(&interval, 0, 1000000000/2); 12611 result = isc_ratelimiter_setinterval(zmgr->rl, &interval); 12612 RUNTIME_CHECK(result == ISC_R_SUCCESS); 12613 isc_ratelimiter_setpertic(zmgr->rl, 10); 12614 12615 zmgr->iolimit = 1; 12616 zmgr->ioactive = 0; 12617 ISC_LIST_INIT(zmgr->high); 12618 ISC_LIST_INIT(zmgr->low); 12619 12620 result = isc_mutex_init(&zmgr->iolock); 12621 if (result != ISC_R_SUCCESS) 12622 goto free_rl; 12623 12624 zmgr->magic = ZONEMGR_MAGIC; 12625 12626 *zmgrp = zmgr; 12627 return (ISC_R_SUCCESS); 12628 12629#if 0 12630 free_iolock: 12631 DESTROYLOCK(&zmgr->iolock); 12632#endif 12633 free_rl: 12634 isc_ratelimiter_detach(&zmgr->rl); 12635 free_task: 12636 isc_task_detach(&zmgr->task); 12637 free_urlock: 12638 isc_rwlock_destroy(&zmgr->urlock); 12639 free_rwlock: 12640 isc_rwlock_destroy(&zmgr->rwlock); 12641 free_mem: 12642 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); 12643 isc_mem_detach(&mctx); 12644 return (result); 12645} 12646 12647isc_result_t 12648dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 12649 isc_result_t result; 12650 12651 REQUIRE(DNS_ZONE_VALID(zone)); 12652 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 12653 12654 if (zmgr->zonetasks == NULL) 12655 return (ISC_R_FAILURE); 12656 12657 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 12658 LOCK_ZONE(zone); 12659 REQUIRE(zone->task == NULL); 12660 REQUIRE(zone->timer == NULL); 12661 REQUIRE(zone->zmgr == NULL); 12662 12663 isc_taskpool_gettask(zmgr->zonetasks, &zone->task); 12664 12665 /* 12666 * Set the task name. The tag will arbitrarily point to one 12667 * of the zones sharing the task (in practice, the one 12668 * to be managed last). 12669 */ 12670 isc_task_setname(zone->task, "zone", zone); 12671 12672 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, 12673 NULL, NULL, 12674 zone->task, zone_timer, zone, 12675 &zone->timer); 12676 12677 if (result != ISC_R_SUCCESS) 12678 goto cleanup_task; 12679 12680 /* 12681 * The timer "holds" a iref. 12682 */ 12683 zone->irefs++; 12684 INSIST(zone->irefs != 0); 12685 12686 ISC_LIST_APPEND(zmgr->zones, zone, link); 12687 zone->zmgr = zmgr; 12688 zmgr->refs++; 12689 12690 goto unlock; 12691 12692 cleanup_task: 12693 isc_task_detach(&zone->task); 12694 12695 unlock: 12696 UNLOCK_ZONE(zone); 12697 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 12698 return (result); 12699} 12700 12701void 12702dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 12703 isc_boolean_t free_now = ISC_FALSE; 12704 12705 REQUIRE(DNS_ZONE_VALID(zone)); 12706 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 12707 REQUIRE(zone->zmgr == zmgr); 12708 12709 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 12710 LOCK_ZONE(zone); 12711 12712 ISC_LIST_UNLINK(zmgr->zones, zone, link); 12713 zone->zmgr = NULL; 12714 zmgr->refs--; 12715 if (zmgr->refs == 0) 12716 free_now = ISC_TRUE; 12717 12718 UNLOCK_ZONE(zone); 12719 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 12720 12721 if (free_now) 12722 zonemgr_free(zmgr); 12723 ENSURE(zone->zmgr == NULL); 12724} 12725 12726void 12727dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) { 12728 REQUIRE(DNS_ZONEMGR_VALID(source)); 12729 REQUIRE(target != NULL && *target == NULL); 12730 12731 RWLOCK(&source->rwlock, isc_rwlocktype_write); 12732 REQUIRE(source->refs > 0); 12733 source->refs++; 12734 INSIST(source->refs > 0); 12735 RWUNLOCK(&source->rwlock, isc_rwlocktype_write); 12736 *target = source; 12737} 12738 12739void 12740dns_zonemgr_detach(dns_zonemgr_t **zmgrp) { 12741 dns_zonemgr_t *zmgr; 12742 isc_boolean_t free_now = ISC_FALSE; 12743 12744 REQUIRE(zmgrp != NULL); 12745 zmgr = *zmgrp; 12746 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 12747 12748 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 12749 zmgr->refs--; 12750 if (zmgr->refs == 0) 12751 free_now = ISC_TRUE; 12752 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 12753 12754 if (free_now) 12755 zonemgr_free(zmgr); 12756 *zmgrp = NULL; 12757} 12758 12759isc_result_t 12760dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) { 12761 dns_zone_t *p; 12762 12763 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 12764 12765 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 12766 for (p = ISC_LIST_HEAD(zmgr->zones); 12767 p != NULL; 12768 p = ISC_LIST_NEXT(p, link)) 12769 { 12770 dns_zone_maintenance(p); 12771 } 12772 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 12773 12774 /* 12775 * Recent configuration changes may have increased the 12776 * amount of available transfers quota. Make sure any 12777 * transfers currently blocked on quota get started if 12778 * possible. 12779 */ 12780 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 12781 zmgr_resume_xfrs(zmgr, ISC_TRUE); 12782 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 12783 return (ISC_R_SUCCESS); 12784} 12785 12786void 12787dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) { 12788 12789 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 12790 12791 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); 12792 zmgr_resume_xfrs(zmgr, ISC_TRUE); 12793 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); 12794} 12795 12796void 12797dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) { 12798 dns_zone_t *zone; 12799 12800 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 12801 12802 isc_ratelimiter_shutdown(zmgr->rl); 12803 12804 if (zmgr->task != NULL) 12805 isc_task_destroy(&zmgr->task); 12806 if (zmgr->zonetasks != NULL) 12807 isc_taskpool_destroy(&zmgr->zonetasks); 12808 12809 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 12810 for (zone = ISC_LIST_HEAD(zmgr->zones); 12811 zone != NULL; 12812 zone = ISC_LIST_NEXT(zone, link)) 12813 { 12814 LOCK_ZONE(zone); 12815 forward_cancel(zone); 12816 UNLOCK_ZONE(zone); 12817 } 12818 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 12819} 12820 12821isc_result_t 12822dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) { 12823 isc_result_t result; 12824 int ntasks = num_zones / 100; 12825 isc_taskpool_t *pool = NULL; 12826 12827 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 12828 12829 /* 12830 * For anything fewer than 1000 zones we use 10 tasks in 12831 * the task pool. More than that, and we'll scale at one 12832 * task per 100 zones. 12833 */ 12834 if (ntasks < 10) 12835 ntasks = 10; 12836 12837 /* Create or resize the zone task pool. */ 12838 if (zmgr->zonetasks == NULL) 12839 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, 12840 ntasks, 2, &pool); 12841 else 12842 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool); 12843 12844 if (result == ISC_R_SUCCESS) 12845 zmgr->zonetasks = pool; 12846 12847 return (result); 12848} 12849 12850static void 12851zonemgr_free(dns_zonemgr_t *zmgr) { 12852 isc_mem_t *mctx; 12853 12854 INSIST(zmgr->refs == 0); 12855 INSIST(ISC_LIST_EMPTY(zmgr->zones)); 12856 12857 zmgr->magic = 0; 12858 12859 DESTROYLOCK(&zmgr->iolock); 12860 isc_ratelimiter_detach(&zmgr->rl); 12861 12862 isc_rwlock_destroy(&zmgr->urlock); 12863 isc_rwlock_destroy(&zmgr->rwlock); 12864 mctx = zmgr->mctx; 12865 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); 12866 isc_mem_detach(&mctx); 12867} 12868 12869void 12870dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) { 12871 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 12872 12873 zmgr->transfersin = value; 12874} 12875 12876isc_uint32_t 12877dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) { 12878 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 12879 12880 return (zmgr->transfersin); 12881} 12882 12883void 12884dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) { 12885 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 12886 12887 zmgr->transfersperns = value; 12888} 12889 12890isc_uint32_t 12891dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) { 12892 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 12893 12894 return (zmgr->transfersperns); 12895} 12896 12897/* 12898 * Try to start a new incoming zone transfer to fill a quota 12899 * slot that was just vacated. 12900 * 12901 * Requires: 12902 * The zone manager is locked by the caller. 12903 */ 12904static void 12905zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) { 12906 dns_zone_t *zone; 12907 dns_zone_t *next; 12908 12909 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); 12910 zone != NULL; 12911 zone = next) 12912 { 12913 isc_result_t result; 12914 next = ISC_LIST_NEXT(zone, statelink); 12915 result = zmgr_start_xfrin_ifquota(zmgr, zone); 12916 if (result == ISC_R_SUCCESS) { 12917 if (multi) 12918 continue; 12919 /* 12920 * We successfully filled the slot. We're done. 12921 */ 12922 break; 12923 } else if (result == ISC_R_QUOTA) { 12924 /* 12925 * Not enough quota. This is probably the per-server 12926 * quota, because we usually get called when a unit of 12927 * global quota has just been freed. Try the next 12928 * zone, it may succeed if it uses another master. 12929 */ 12930 continue; 12931 } else { 12932 dns_zone_log(zone, ISC_LOG_DEBUG(1), 12933 "starting zone transfer: %s", 12934 isc_result_totext(result)); 12935 break; 12936 } 12937 } 12938} 12939 12940/* 12941 * Try to start an incoming zone transfer for 'zone', quota permitting. 12942 * 12943 * Requires: 12944 * The zone manager is locked by the caller. 12945 * 12946 * Returns: 12947 * ISC_R_SUCCESS There was enough quota and we attempted to 12948 * start a transfer. zone_xfrdone() has been or will 12949 * be called. 12950 * ISC_R_QUOTA Not enough quota. 12951 * Others Failure. 12952 */ 12953static isc_result_t 12954zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) { 12955 dns_peer_t *peer = NULL; 12956 isc_netaddr_t masterip; 12957 isc_uint32_t nxfrsin, nxfrsperns; 12958 dns_zone_t *x; 12959 isc_uint32_t maxtransfersin, maxtransfersperns; 12960 isc_event_t *e; 12961 12962 /* 12963 * If we are exiting just pretend we got quota so the zone will 12964 * be cleaned up in the zone's task context. 12965 */ 12966 LOCK_ZONE(zone); 12967 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { 12968 UNLOCK_ZONE(zone); 12969 goto gotquota; 12970 } 12971 12972 /* 12973 * Find any configured information about the server we'd 12974 * like to transfer this zone from. 12975 */ 12976 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr); 12977 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer); 12978 UNLOCK_ZONE(zone); 12979 12980 /* 12981 * Determine the total maximum number of simultaneous 12982 * transfers allowed, and the maximum for this specific 12983 * master. 12984 */ 12985 maxtransfersin = zmgr->transfersin; 12986 maxtransfersperns = zmgr->transfersperns; 12987 if (peer != NULL) 12988 (void)dns_peer_gettransfers(peer, &maxtransfersperns); 12989 12990 /* 12991 * Count the total number of transfers that are in progress, 12992 * and the number of transfers in progress from this master. 12993 * We linearly scan a list of all transfers; if this turns 12994 * out to be too slow, we could hash on the master address. 12995 */ 12996 nxfrsin = nxfrsperns = 0; 12997 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress); 12998 x != NULL; 12999 x = ISC_LIST_NEXT(x, statelink)) 13000 { 13001 isc_netaddr_t xip; 13002 13003 LOCK_ZONE(x); 13004 isc_netaddr_fromsockaddr(&xip, &x->masteraddr); 13005 UNLOCK_ZONE(x); 13006 13007 nxfrsin++; 13008 if (isc_netaddr_equal(&xip, &masterip)) 13009 nxfrsperns++; 13010 } 13011 13012 /* Enforce quota. */ 13013 if (nxfrsin >= maxtransfersin) 13014 return (ISC_R_QUOTA); 13015 13016 if (nxfrsperns >= maxtransfersperns) 13017 return (ISC_R_QUOTA); 13018 13019 gotquota: 13020 /* 13021 * We have sufficient quota. Move the zone to the "xfrin_in_progress" 13022 * list and send it an event to let it start the actual transfer in the 13023 * context of its own task. 13024 */ 13025 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN, 13026 got_transfer_quota, zone, sizeof(isc_event_t)); 13027 if (e == NULL) 13028 return (ISC_R_NOMEMORY); 13029 13030 LOCK_ZONE(zone); 13031 INSIST(zone->statelist == &zmgr->waiting_for_xfrin); 13032 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink); 13033 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink); 13034 zone->statelist = &zmgr->xfrin_in_progress; 13035 isc_task_send(zone->task, &e); 13036 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started."); 13037 UNLOCK_ZONE(zone); 13038 13039 return (ISC_R_SUCCESS); 13040} 13041 13042void 13043dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) { 13044 13045 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13046 REQUIRE(iolimit > 0); 13047 13048 zmgr->iolimit = iolimit; 13049} 13050 13051isc_uint32_t 13052dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) { 13053 13054 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13055 13056 return (zmgr->iolimit); 13057} 13058 13059/* 13060 * Get permission to request a file handle from the OS. 13061 * An event will be sent to action when one is available. 13062 * There are two queues available (high and low), the high 13063 * queue will be serviced before the low one. 13064 * 13065 * zonemgr_putio() must be called after the event is delivered to 13066 * 'action'. 13067 */ 13068 13069static isc_result_t 13070zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high, 13071 isc_task_t *task, isc_taskaction_t action, void *arg, 13072 dns_io_t **iop) 13073{ 13074 dns_io_t *io; 13075 isc_boolean_t queue; 13076 13077 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13078 REQUIRE(iop != NULL && *iop == NULL); 13079 13080 io = isc_mem_get(zmgr->mctx, sizeof(*io)); 13081 if (io == NULL) 13082 return (ISC_R_NOMEMORY); 13083 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY, 13084 action, arg, sizeof(*io->event)); 13085 if (io->event == NULL) { 13086 isc_mem_put(zmgr->mctx, io, sizeof(*io)); 13087 return (ISC_R_NOMEMORY); 13088 } 13089 io->zmgr = zmgr; 13090 io->high = high; 13091 io->task = NULL; 13092 isc_task_attach(task, &io->task); 13093 ISC_LINK_INIT(io, link); 13094 io->magic = IO_MAGIC; 13095 13096 LOCK(&zmgr->iolock); 13097 zmgr->ioactive++; 13098 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit); 13099 if (queue) { 13100 if (io->high) 13101 ISC_LIST_APPEND(zmgr->high, io, link); 13102 else 13103 ISC_LIST_APPEND(zmgr->low, io, link); 13104 } 13105 UNLOCK(&zmgr->iolock); 13106 *iop = io; 13107 13108 if (!queue) { 13109 isc_task_send(io->task, &io->event); 13110 } 13111 return (ISC_R_SUCCESS); 13112} 13113 13114static void 13115zonemgr_putio(dns_io_t **iop) { 13116 dns_io_t *io; 13117 dns_io_t *next; 13118 dns_zonemgr_t *zmgr; 13119 13120 REQUIRE(iop != NULL); 13121 io = *iop; 13122 REQUIRE(DNS_IO_VALID(io)); 13123 13124 *iop = NULL; 13125 13126 INSIST(!ISC_LINK_LINKED(io, link)); 13127 INSIST(io->event == NULL); 13128 13129 zmgr = io->zmgr; 13130 isc_task_detach(&io->task); 13131 io->magic = 0; 13132 isc_mem_put(zmgr->mctx, io, sizeof(*io)); 13133 13134 LOCK(&zmgr->iolock); 13135 INSIST(zmgr->ioactive > 0); 13136 zmgr->ioactive--; 13137 next = HEAD(zmgr->high); 13138 if (next == NULL) 13139 next = HEAD(zmgr->low); 13140 if (next != NULL) { 13141 if (next->high) 13142 ISC_LIST_UNLINK(zmgr->high, next, link); 13143 else 13144 ISC_LIST_UNLINK(zmgr->low, next, link); 13145 INSIST(next->event != NULL); 13146 } 13147 UNLOCK(&zmgr->iolock); 13148 if (next != NULL) 13149 isc_task_send(next->task, &next->event); 13150} 13151 13152static void 13153zonemgr_cancelio(dns_io_t *io) { 13154 isc_boolean_t send_event = ISC_FALSE; 13155 13156 REQUIRE(DNS_IO_VALID(io)); 13157 13158 /* 13159 * If we are queued to be run then dequeue. 13160 */ 13161 LOCK(&io->zmgr->iolock); 13162 if (ISC_LINK_LINKED(io, link)) { 13163 if (io->high) 13164 ISC_LIST_UNLINK(io->zmgr->high, io, link); 13165 else 13166 ISC_LIST_UNLINK(io->zmgr->low, io, link); 13167 13168 send_event = ISC_TRUE; 13169 INSIST(io->event != NULL); 13170 } 13171 UNLOCK(&io->zmgr->iolock); 13172 if (send_event) { 13173 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED; 13174 isc_task_send(io->task, &io->event); 13175 } 13176} 13177 13178static void 13179zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) { 13180 char *buf; 13181 int buflen; 13182 isc_result_t result; 13183 13184 buflen = strlen(path) + strlen(templat) + 2; 13185 13186 buf = isc_mem_get(zone->mctx, buflen); 13187 if (buf == NULL) 13188 return; 13189 13190 result = isc_file_template(path, templat, buf, buflen); 13191 if (result != ISC_R_SUCCESS) 13192 goto cleanup; 13193 13194 result = isc_file_renameunique(path, buf); 13195 if (result != ISC_R_SUCCESS) 13196 goto cleanup; 13197 13198 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; " 13199 "renaming file to '%s' for failure analysis and " 13200 "retransferring.", path, buf); 13201 13202 cleanup: 13203 isc_mem_put(zone->mctx, buf, buflen); 13204} 13205 13206#if 0 13207/* Hook for ondestroy notification from a database. */ 13208 13209static void 13210dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) { 13211 dns_db_t *db = event->sender; 13212 UNUSED(task); 13213 13214 isc_event_free(&event); 13215 13216 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 13217 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), 13218 "database (%p) destroyed", (void*) db); 13219} 13220#endif 13221 13222void 13223dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) { 13224 isc_interval_t interval; 13225 isc_uint32_t s, ns; 13226 isc_uint32_t pertic; 13227 isc_result_t result; 13228 13229 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13230 13231 if (value == 0) 13232 value = 1; 13233 13234 if (value == 1) { 13235 s = 1; 13236 ns = 0; 13237 pertic = 1; 13238 } else if (value <= 10) { 13239 s = 0; 13240 ns = 1000000000 / value; 13241 pertic = 1; 13242 } else { 13243 s = 0; 13244 ns = (1000000000 / value) * 10; 13245 pertic = 10; 13246 } 13247 13248 isc_interval_set(&interval, s, ns); 13249 result = isc_ratelimiter_setinterval(zmgr->rl, &interval); 13250 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13251 isc_ratelimiter_setpertic(zmgr->rl, pertic); 13252 13253 zmgr->serialqueryrate = value; 13254} 13255 13256unsigned int 13257dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) { 13258 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13259 13260 return (zmgr->serialqueryrate); 13261} 13262 13263isc_boolean_t 13264dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 13265 isc_sockaddr_t *local, isc_time_t *now) 13266{ 13267 unsigned int i; 13268 isc_rwlocktype_t locktype; 13269 isc_result_t result; 13270 isc_uint32_t seconds = isc_time_seconds(now); 13271 13272 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13273 13274 locktype = isc_rwlocktype_read; 13275 RWLOCK(&zmgr->urlock, locktype); 13276 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { 13277 if (zmgr->unreachable[i].expire >= seconds && 13278 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 13279 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) { 13280 result = isc_rwlock_tryupgrade(&zmgr->urlock); 13281 if (result == ISC_R_SUCCESS) { 13282 locktype = isc_rwlocktype_write; 13283 zmgr->unreachable[i].last = seconds; 13284 } 13285 break; 13286 } 13287 } 13288 RWUNLOCK(&zmgr->urlock, locktype); 13289 return (ISC_TF(i < UNREACH_CHACHE_SIZE)); 13290} 13291 13292void 13293dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 13294 isc_sockaddr_t *local) 13295{ 13296 unsigned int i; 13297 isc_rwlocktype_t locktype; 13298 isc_result_t result; 13299 13300 char master[ISC_SOCKADDR_FORMATSIZE]; 13301 char source[ISC_SOCKADDR_FORMATSIZE]; 13302 13303 isc_sockaddr_format(remote, master, sizeof(master)); 13304 isc_sockaddr_format(local, source, sizeof(source)); 13305 13306 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13307 13308 locktype = isc_rwlocktype_read; 13309 RWLOCK(&zmgr->urlock, locktype); 13310 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { 13311 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 13312 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) { 13313 result = isc_rwlock_tryupgrade(&zmgr->urlock); 13314 if (result == ISC_R_SUCCESS) { 13315 locktype = isc_rwlocktype_write; 13316 zmgr->unreachable[i].expire = 0; 13317 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, 13318 DNS_LOGMODULE_ZONE, ISC_LOG_INFO, 13319 "master %s (source %s) deleted " 13320 "from unreachable cache", 13321 master, source); 13322 } 13323 break; 13324 } 13325 } 13326 RWUNLOCK(&zmgr->urlock, locktype); 13327} 13328 13329void 13330dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, 13331 isc_sockaddr_t *local, isc_time_t *now) 13332{ 13333 isc_uint32_t seconds = isc_time_seconds(now); 13334 isc_uint32_t last = seconds; 13335 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0; 13336 13337 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13338 13339 RWLOCK(&zmgr->urlock, isc_rwlocktype_write); 13340 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { 13341 /* Existing entry? */ 13342 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && 13343 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) 13344 break; 13345 /* Empty slot? */ 13346 if (zmgr->unreachable[i].expire < seconds) 13347 slot = i; 13348 /* Least recently used slot? */ 13349 if (zmgr->unreachable[i].last < last) { 13350 last = zmgr->unreachable[i].last; 13351 oldest = i; 13352 } 13353 } 13354 if (i < UNREACH_CHACHE_SIZE) { 13355 /* 13356 * Found a existing entry. Update the expire timer and 13357 * last usage timestamps. 13358 */ 13359 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME; 13360 zmgr->unreachable[i].last = seconds; 13361 } else if (slot != UNREACH_CHACHE_SIZE) { 13362 /* 13363 * Found a empty slot. Add a new entry to the cache. 13364 */ 13365 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME; 13366 zmgr->unreachable[slot].last = seconds; 13367 zmgr->unreachable[slot].remote = *remote; 13368 zmgr->unreachable[slot].local = *local; 13369 } else { 13370 /* 13371 * Replace the least recently used entry in the cache. 13372 */ 13373 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME; 13374 zmgr->unreachable[oldest].last = seconds; 13375 zmgr->unreachable[oldest].remote = *remote; 13376 zmgr->unreachable[oldest].local = *local; 13377 } 13378 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write); 13379} 13380 13381void 13382dns_zone_forcereload(dns_zone_t *zone) { 13383 REQUIRE(DNS_ZONE_VALID(zone)); 13384 13385 if (zone->type == dns_zone_master) 13386 return; 13387 13388 LOCK_ZONE(zone); 13389 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER); 13390 UNLOCK_ZONE(zone); 13391 dns_zone_refresh(zone); 13392} 13393 13394isc_boolean_t 13395dns_zone_isforced(dns_zone_t *zone) { 13396 REQUIRE(DNS_ZONE_VALID(zone)); 13397 13398 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)); 13399} 13400 13401isc_result_t 13402dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) { 13403 /* 13404 * This function is obsoleted. 13405 */ 13406 UNUSED(zone); 13407 UNUSED(on); 13408 return (ISC_R_NOTIMPLEMENTED); 13409} 13410 13411isc_uint64_t * 13412dns_zone_getstatscounters(dns_zone_t *zone) { 13413 /* 13414 * This function is obsoleted. 13415 */ 13416 UNUSED(zone); 13417 return (NULL); 13418} 13419 13420void 13421dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) { 13422 REQUIRE(DNS_ZONE_VALID(zone)); 13423 REQUIRE(zone->stats == NULL); 13424 13425 LOCK_ZONE(zone); 13426 zone->stats = NULL; 13427 isc_stats_attach(stats, &zone->stats); 13428 UNLOCK_ZONE(zone); 13429} 13430 13431void 13432dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) { 13433 REQUIRE(DNS_ZONE_VALID(zone)); 13434 13435 LOCK_ZONE(zone); 13436 if (zone->requeststats_on && stats == NULL) 13437 zone->requeststats_on = ISC_FALSE; 13438 else if (!zone->requeststats_on && stats != NULL) { 13439 if (zone->requeststats == NULL) { 13440 isc_stats_attach(stats, &zone->requeststats); 13441 zone->requeststats_on = ISC_TRUE; 13442 } 13443 } 13444 UNLOCK_ZONE(zone); 13445 13446 return; 13447} 13448 13449isc_stats_t * 13450dns_zone_getrequeststats(dns_zone_t *zone) { 13451 /* 13452 * We don't lock zone for efficiency reason. This is not catastrophic 13453 * because requeststats must always be valid when requeststats_on is 13454 * true. 13455 * Some counters may be incremented while requeststats_on is becoming 13456 * false, or some cannot be incremented just after the statistics are 13457 * installed, but it shouldn't matter much in practice. 13458 */ 13459 if (zone->requeststats_on) 13460 return (zone->requeststats); 13461 else 13462 return (NULL); 13463} 13464 13465void 13466dns_zone_dialup(dns_zone_t *zone) { 13467 13468 REQUIRE(DNS_ZONE_VALID(zone)); 13469 13470 zone_debuglog(zone, "dns_zone_dialup", 3, 13471 "notify = %d, refresh = %d", 13472 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY), 13473 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)); 13474 13475 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) 13476 dns_zone_notify(zone); 13477 if (zone->type != dns_zone_master && 13478 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) 13479 dns_zone_refresh(zone); 13480} 13481 13482void 13483dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) { 13484 REQUIRE(DNS_ZONE_VALID(zone)); 13485 13486 LOCK_ZONE(zone); 13487 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY | 13488 DNS_ZONEFLG_DIALREFRESH | 13489 DNS_ZONEFLG_NOREFRESH); 13490 switch (dialup) { 13491 case dns_dialuptype_no: 13492 break; 13493 case dns_dialuptype_yes: 13494 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY | 13495 DNS_ZONEFLG_DIALREFRESH | 13496 DNS_ZONEFLG_NOREFRESH)); 13497 break; 13498 case dns_dialuptype_notify: 13499 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 13500 break; 13501 case dns_dialuptype_notifypassive: 13502 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY); 13503 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 13504 break; 13505 case dns_dialuptype_refresh: 13506 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH); 13507 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 13508 break; 13509 case dns_dialuptype_passive: 13510 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH); 13511 break; 13512 default: 13513 INSIST(0); 13514 } 13515 UNLOCK_ZONE(zone); 13516} 13517 13518isc_result_t 13519dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) { 13520 isc_result_t result = ISC_R_SUCCESS; 13521 13522 REQUIRE(DNS_ZONE_VALID(zone)); 13523 13524 LOCK_ZONE(zone); 13525 result = dns_zone_setstring(zone, &zone->keydirectory, directory); 13526 UNLOCK_ZONE(zone); 13527 13528 return (result); 13529} 13530 13531const char * 13532dns_zone_getkeydirectory(dns_zone_t *zone) { 13533 REQUIRE(DNS_ZONE_VALID(zone)); 13534 13535 return (zone->keydirectory); 13536} 13537 13538unsigned int 13539dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) { 13540 dns_zone_t *zone; 13541 unsigned int count = 0; 13542 13543 REQUIRE(DNS_ZONEMGR_VALID(zmgr)); 13544 13545 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); 13546 switch (state) { 13547 case DNS_ZONESTATE_XFERRUNNING: 13548 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress); 13549 zone != NULL; 13550 zone = ISC_LIST_NEXT(zone, statelink)) 13551 count++; 13552 break; 13553 case DNS_ZONESTATE_XFERDEFERRED: 13554 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); 13555 zone != NULL; 13556 zone = ISC_LIST_NEXT(zone, statelink)) 13557 count++; 13558 break; 13559 case DNS_ZONESTATE_SOAQUERY: 13560 for (zone = ISC_LIST_HEAD(zmgr->zones); 13561 zone != NULL; 13562 zone = ISC_LIST_NEXT(zone, link)) 13563 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) 13564 count++; 13565 break; 13566 case DNS_ZONESTATE_ANY: 13567 for (zone = ISC_LIST_HEAD(zmgr->zones); 13568 zone != NULL; 13569 zone = ISC_LIST_NEXT(zone, link)) { 13570 dns_view_t *view = zone->view; 13571 if (view != NULL && strcmp(view->name, "_bind") == 0) 13572 continue; 13573 count++; 13574 } 13575 break; 13576 default: 13577 INSIST(0); 13578 } 13579 13580 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); 13581 13582 return (count); 13583} 13584 13585isc_result_t 13586dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) { 13587 isc_boolean_t ok = ISC_TRUE; 13588 isc_boolean_t fail = ISC_FALSE; 13589 char namebuf[DNS_NAME_FORMATSIZE]; 13590 char namebuf2[DNS_NAME_FORMATSIZE]; 13591 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 13592 int level = ISC_LOG_WARNING; 13593 dns_name_t bad; 13594 13595 REQUIRE(DNS_ZONE_VALID(zone)); 13596 13597 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) 13598 return (ISC_R_SUCCESS); 13599 13600 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) { 13601 level = ISC_LOG_ERROR; 13602 fail = ISC_TRUE; 13603 } 13604 13605 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE); 13606 if (!ok) { 13607 dns_name_format(name, namebuf, sizeof(namebuf)); 13608 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 13609 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf, 13610 dns_result_totext(DNS_R_BADOWNERNAME)); 13611 if (fail) 13612 return (DNS_R_BADOWNERNAME); 13613 } 13614 13615 dns_name_init(&bad, NULL); 13616 ok = dns_rdata_checknames(rdata, name, &bad); 13617 if (!ok) { 13618 dns_name_format(name, namebuf, sizeof(namebuf)); 13619 dns_name_format(&bad, namebuf2, sizeof(namebuf2)); 13620 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); 13621 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf, 13622 namebuf2, dns_result_totext(DNS_R_BADNAME)); 13623 if (fail) 13624 return (DNS_R_BADNAME); 13625 } 13626 13627 return (ISC_R_SUCCESS); 13628} 13629 13630void 13631dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) { 13632 REQUIRE(DNS_ZONE_VALID(zone)); 13633 zone->checkmx = checkmx; 13634} 13635 13636void 13637dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) { 13638 REQUIRE(DNS_ZONE_VALID(zone)); 13639 zone->checksrv = checksrv; 13640} 13641 13642void 13643dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) { 13644 REQUIRE(DNS_ZONE_VALID(zone)); 13645 zone->checkns = checkns; 13646} 13647 13648void 13649dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) { 13650 REQUIRE(DNS_ZONE_VALID(zone)); 13651 13652 LOCK_ZONE(zone); 13653 zone->isself = isself; 13654 zone->isselfarg = arg; 13655 UNLOCK_ZONE(zone); 13656} 13657 13658void 13659dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) { 13660 REQUIRE(DNS_ZONE_VALID(zone)); 13661 13662 LOCK_ZONE(zone); 13663 zone->notifydelay = delay; 13664 UNLOCK_ZONE(zone); 13665} 13666 13667isc_uint32_t 13668dns_zone_getnotifydelay(dns_zone_t *zone) { 13669 REQUIRE(DNS_ZONE_VALID(zone)); 13670 13671 return (zone->notifydelay); 13672} 13673 13674isc_result_t 13675dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, 13676 isc_uint16_t keyid, isc_boolean_t delete) 13677{ 13678 isc_result_t result; 13679 REQUIRE(DNS_ZONE_VALID(zone)); 13680 13681 dns_zone_log(zone, ISC_LOG_NOTICE, 13682 "dns_zone_signwithkey(algorithm=%u, keyid=%u)", 13683 algorithm, keyid); 13684 LOCK_ZONE(zone); 13685 result = zone_signwithkey(zone, algorithm, keyid, delete); 13686 UNLOCK_ZONE(zone); 13687 13688 return (result); 13689} 13690 13691static const char *hex = "0123456789ABCDEF"; 13692 13693isc_result_t 13694dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { 13695 isc_result_t result; 13696 char salt[255*2+1]; 13697 unsigned int i, j; 13698 13699 REQUIRE(DNS_ZONE_VALID(zone)); 13700 13701 if (nsec3param->salt_length != 0) { 13702 INSIST((nsec3param->salt_length * 2U) < sizeof(salt)); 13703 for (i = 0, j = 0; i < nsec3param->salt_length; i++) { 13704 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf]; 13705 salt[j++] = hex[nsec3param->salt[i] & 0xf]; 13706 } 13707 salt[j] = '\0'; 13708 } else 13709 strcpy(salt, "-"); 13710 dns_zone_log(zone, ISC_LOG_NOTICE, 13711 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)", 13712 nsec3param->hash, nsec3param->iterations, 13713 salt); 13714 LOCK_ZONE(zone); 13715 result = zone_addnsec3chain(zone, nsec3param); 13716 UNLOCK_ZONE(zone); 13717 13718 return (result); 13719} 13720 13721void 13722dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) { 13723 REQUIRE(DNS_ZONE_VALID(zone)); 13724 13725 if (nodes == 0) 13726 nodes = 1; 13727 zone->nodes = nodes; 13728} 13729 13730void 13731dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) { 13732 REQUIRE(DNS_ZONE_VALID(zone)); 13733 13734 /* 13735 * We treat signatures as a signed value so explicitly 13736 * limit its range here. 13737 */ 13738 if (signatures > ISC_INT32_MAX) 13739 signatures = ISC_INT32_MAX; 13740 else if (signatures == 0) 13741 signatures = 1; 13742 zone->signatures = signatures; 13743} 13744 13745void 13746dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) { 13747 REQUIRE(DNS_ZONE_VALID(zone)); 13748 zone->privatetype = type; 13749} 13750 13751dns_rdatatype_t 13752dns_zone_getprivatetype(dns_zone_t *zone) { 13753 REQUIRE(DNS_ZONE_VALID(zone)); 13754 return (zone->privatetype); 13755} 13756 13757static isc_result_t 13758zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid, 13759 isc_boolean_t delete) 13760{ 13761 dns_signing_t *signing; 13762 dns_signing_t *current; 13763 isc_result_t result = ISC_R_SUCCESS; 13764 isc_time_t now; 13765 13766 signing = isc_mem_get(zone->mctx, sizeof *signing); 13767 if (signing == NULL) 13768 return (ISC_R_NOMEMORY); 13769 13770 signing->magic = 0; 13771 signing->db = NULL; 13772 signing->dbiterator = NULL; 13773 signing->algorithm = algorithm; 13774 signing->keyid = keyid; 13775 signing->delete = delete; 13776 signing->done = ISC_FALSE; 13777 13778 TIME_NOW(&now); 13779 13780 for (current = ISC_LIST_HEAD(zone->signing); 13781 current != NULL; 13782 current = ISC_LIST_NEXT(current, link)) { 13783 if (current->db == zone->db && 13784 current->algorithm == signing->algorithm && 13785 current->keyid == signing->keyid) { 13786 if (current->delete != signing->delete) 13787 current->done = ISC_TRUE; 13788 else 13789 goto cleanup; 13790 } 13791 } 13792 13793 if (zone->db != NULL) { 13794 dns_db_attach(zone->db, &signing->db); 13795 result = dns_db_createiterator(signing->db, 0, 13796 &signing->dbiterator); 13797 13798 if (result == ISC_R_SUCCESS) 13799 result = dns_dbiterator_first(signing->dbiterator); 13800 if (result == ISC_R_SUCCESS) { 13801 dns_dbiterator_pause(signing->dbiterator); 13802 ISC_LIST_INITANDAPPEND(zone->signing, signing, link); 13803 signing = NULL; 13804 if (isc_time_isepoch(&zone->signingtime)) { 13805 zone->signingtime = now; 13806 if (zone->task != NULL) 13807 zone_settimer(zone, &now); 13808 } 13809 } 13810 } else 13811 result = ISC_R_NOTFOUND; 13812 13813 cleanup: 13814 if (signing != NULL) { 13815 if (signing->db != NULL) 13816 dns_db_detach(&signing->db); 13817 if (signing->dbiterator != NULL) 13818 dns_dbiterator_destroy(&signing->dbiterator); 13819 isc_mem_put(zone->mctx, signing, sizeof *signing); 13820 } 13821 return (result); 13822} 13823 13824static void 13825logmsg(const char *format, ...) { 13826 va_list args; 13827 va_start(args, format); 13828 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, 13829 ISC_LOG_DEBUG(1), format, args); 13830 va_end(args); 13831} 13832 13833static void 13834clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) { 13835 dns_dnsseckey_t *key; 13836 while (!ISC_LIST_EMPTY(*list)) { 13837 key = ISC_LIST_HEAD(*list); 13838 ISC_LIST_UNLINK(*list, key, link); 13839 dns_dnsseckey_destroy(mctx, &key); 13840 } 13841} 13842 13843/* Called once; *timep should be set to the current time. */ 13844static isc_result_t 13845next_keyevent(dst_key_t *key, isc_stdtime_t *timep) { 13846 isc_result_t result; 13847 isc_stdtime_t now, then = 0, event; 13848 int i; 13849 13850 now = *timep; 13851 13852 for (i = 0; i <= DST_MAX_TIMES; i++) { 13853 result = dst_key_gettime(key, i, &event); 13854 if (result == ISC_R_SUCCESS && event > now && 13855 (then == 0 || event < then)) 13856 then = event; 13857 } 13858 13859 if (then != 0) { 13860 *timep = then; 13861 return (ISC_R_SUCCESS); 13862 } 13863 13864 return (ISC_R_NOTFOUND); 13865} 13866 13867static isc_result_t 13868rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, 13869 const dns_rdata_t *rdata, isc_boolean_t *flag) 13870{ 13871 dns_rdataset_t rdataset; 13872 dns_dbnode_t *node = NULL; 13873 isc_result_t result; 13874 13875 dns_rdataset_init(&rdataset); 13876 if (rdata->type == dns_rdatatype_nsec3) 13877 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node)); 13878 else 13879 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); 13880 result = dns_db_findrdataset(db, node, ver, rdata->type, 0, 13881 (isc_stdtime_t) 0, &rdataset, NULL); 13882 if (result == ISC_R_NOTFOUND) { 13883 *flag = ISC_FALSE; 13884 result = ISC_R_SUCCESS; 13885 goto failure; 13886 } 13887 13888 for (result = dns_rdataset_first(&rdataset); 13889 result == ISC_R_SUCCESS; 13890 result = dns_rdataset_next(&rdataset)) { 13891 dns_rdata_t myrdata = DNS_RDATA_INIT; 13892 dns_rdataset_current(&rdataset, &myrdata); 13893 if (!dns_rdata_compare(&myrdata, rdata)) 13894 break; 13895 } 13896 dns_rdataset_disassociate(&rdataset); 13897 if (result == ISC_R_SUCCESS) { 13898 *flag = ISC_TRUE; 13899 } else if (result == ISC_R_NOMORE) { 13900 *flag = ISC_FALSE; 13901 result = ISC_R_SUCCESS; 13902 } 13903 13904 failure: 13905 if (node != NULL) 13906 dns_db_detachnode(db, &node); 13907 return (result); 13908} 13909 13910/* 13911 * Add records to signal the state of signing or of key removal. 13912 */ 13913static isc_result_t 13914add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, 13915 dns_dbversion_t *ver, dns_diff_t *diff, 13916 isc_boolean_t sign_all) 13917{ 13918 dns_difftuple_t *tuple, *newtuple = NULL; 13919 dns_rdata_dnskey_t dnskey; 13920 dns_rdata_t rdata = DNS_RDATA_INIT; 13921 isc_boolean_t flag; 13922 isc_region_t r; 13923 isc_result_t result = ISC_R_SUCCESS; 13924 isc_uint16_t keyid; 13925 unsigned char buf[5]; 13926 dns_name_t *name = dns_db_origin(db); 13927 13928 for (tuple = ISC_LIST_HEAD(diff->tuples); 13929 tuple != NULL; 13930 tuple = ISC_LIST_NEXT(tuple, link)) { 13931 if (tuple->rdata.type != dns_rdatatype_dnskey) 13932 continue; 13933 13934 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL); 13935 RUNTIME_CHECK(result == ISC_R_SUCCESS); 13936 if ((dnskey.flags & 13937 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH)) 13938 != DNS_KEYOWNER_ZONE) 13939 continue; 13940 13941 dns_rdata_toregion(&tuple->rdata, &r); 13942 13943 keyid = dst_region_computeid(&r, dnskey.algorithm); 13944 13945 buf[0] = dnskey.algorithm; 13946 buf[1] = (keyid & 0xff00) >> 8; 13947 buf[2] = (keyid & 0xff); 13948 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1; 13949 buf[4] = 0; 13950 rdata.data = buf; 13951 rdata.length = sizeof(buf); 13952 rdata.type = privatetype; 13953 rdata.rdclass = tuple->rdata.rdclass; 13954 13955 if (sign_all || tuple->op == DNS_DIFFOP_DEL) { 13956 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 13957 if (flag) 13958 continue; 13959 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, 13960 name, 0, &rdata, &newtuple)); 13961 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 13962 INSIST(newtuple == NULL); 13963 } 13964 13965 /* 13966 * Remove any record which says this operation has already 13967 * completed. 13968 */ 13969 buf[4] = 1; 13970 CHECK(rr_exists(db, ver, name, &rdata, &flag)); 13971 if (flag) { 13972 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, 13973 name, 0, &rdata, &newtuple)); 13974 CHECK(do_one_tuple(&newtuple, db, ver, diff)); 13975 INSIST(newtuple == NULL); 13976 } 13977 } 13978 failure: 13979 return (result); 13980} 13981 13982static isc_result_t 13983sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 13984 dns_diff_t *diff, dns_diff_t *sig_diff) 13985{ 13986 isc_result_t result; 13987 isc_stdtime_t now, inception, soaexpire; 13988 isc_boolean_t check_ksk, keyset_kskonly; 13989 dst_key_t *zone_keys[DNS_MAXZONEKEYS]; 13990 unsigned int nkeys = 0, i; 13991 dns_difftuple_t *tuple; 13992 13993 result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS, 13994 zone_keys, &nkeys); 13995 if (result != ISC_R_SUCCESS) { 13996 dns_zone_log(zone, ISC_LOG_ERROR, 13997 "sign_apex:find_zone_keys -> %s\n", 13998 dns_result_totext(result)); 13999 return (result); 14000 } 14001 14002 isc_stdtime_get(&now); 14003 inception = now - 3600; /* Allow for clock skew. */ 14004 soaexpire = now + dns_zone_getsigvalidityinterval(zone); 14005 14006 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 14007 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY); 14008 14009 /* 14010 * See if update_sigs will update DNSKEY signature and if not 14011 * cause them to sign so that so that newly activated keys 14012 * are used. 14013 */ 14014 for (tuple = ISC_LIST_HEAD(diff->tuples); 14015 tuple != NULL; 14016 tuple = ISC_LIST_NEXT(tuple, link)) { 14017 if (tuple->rdata.type == dns_rdatatype_dnskey && 14018 dns_name_equal(&tuple->name, &zone->origin)) 14019 break; 14020 } 14021 14022 if (tuple == NULL) { 14023 result = del_sigs(zone, db, ver, &zone->origin, 14024 dns_rdatatype_dnskey, sig_diff, 14025 zone_keys, nkeys, now, ISC_FALSE); 14026 if (result != ISC_R_SUCCESS) { 14027 dns_zone_log(zone, ISC_LOG_ERROR, 14028 "sign_apex:del_sigs -> %s\n", 14029 dns_result_totext(result)); 14030 goto failure; 14031 } 14032 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey, 14033 sig_diff, zone_keys, nkeys, zone->mctx, 14034 inception, soaexpire, check_ksk, 14035 keyset_kskonly); 14036 if (result != ISC_R_SUCCESS) { 14037 dns_zone_log(zone, ISC_LOG_ERROR, 14038 "sign_apex:add_sigs -> %s\n", 14039 dns_result_totext(result)); 14040 goto failure; 14041 } 14042 } 14043 14044 result = update_sigs(diff, db, ver, zone_keys, nkeys, zone, 14045 inception, soaexpire, now, check_ksk, 14046 keyset_kskonly, sig_diff); 14047 14048 if (result != ISC_R_SUCCESS) { 14049 dns_zone_log(zone, ISC_LOG_ERROR, 14050 "sign_apex:update_sigs -> %s\n", 14051 dns_result_totext(result)); 14052 goto failure; 14053 } 14054 14055 failure: 14056 for (i = 0; i < nkeys; i++) 14057 dst_key_free(&zone_keys[i]); 14058 return (result); 14059} 14060 14061/* 14062 * Prevent the zone entering a inconsistent state where 14063 * NSEC only DNSKEYs are present with NSEC3 chains. 14064 * See update.c:check_dnssec() 14065 */ 14066static isc_boolean_t 14067dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 14068 dns_diff_t *diff) 14069{ 14070 isc_result_t result; 14071 dns_difftuple_t *tuple; 14072 isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE; 14073 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone); 14074 14075 /* Scan the tuples for an NSEC-only DNSKEY */ 14076 for (tuple = ISC_LIST_HEAD(diff->tuples); 14077 tuple != NULL; 14078 tuple = ISC_LIST_NEXT(tuple, link)) { 14079 isc_uint8_t alg; 14080 if (tuple->rdata.type != dns_rdatatype_dnskey || 14081 tuple->op != DNS_DIFFOP_ADD) 14082 continue; 14083 14084 alg = tuple->rdata.data[3]; 14085 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 || 14086 alg == DST_ALG_DSA || alg == DST_ALG_ECC) { 14087 nseconly = ISC_TRUE; 14088 break; 14089 } 14090 } 14091 14092 /* Check existing DB for NSEC-only DNSKEY */ 14093 if (!nseconly) 14094 CHECK(dns_nsec_nseconly(db, ver, &nseconly)); 14095 14096 /* Check existing DB for NSEC3 */ 14097 if (!nsec3) 14098 CHECK(dns_nsec3_activex(db, ver, ISC_FALSE, 14099 privatetype, &nsec3)); 14100 14101 /* Refuse to allow NSEC3 with NSEC-only keys */ 14102 if (nseconly && nsec3) { 14103 dns_zone_log(zone, ISC_LOG_ERROR, 14104 "NSEC only DNSKEYs and NSEC3 chains not allowed"); 14105 goto failure; 14106 } 14107 14108 return (ISC_TRUE); 14109 14110 failure: 14111 return (ISC_FALSE); 14112} 14113 14114static isc_result_t 14115clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 14116 dns_diff_t *diff) 14117{ 14118 isc_result_t result; 14119 dns_dbnode_t *node = NULL; 14120 dns_rdataset_t rdataset; 14121 14122 dns_rdataset_init(&rdataset); 14123 CHECK(dns_db_getoriginnode(db, &node)); 14124 14125 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 14126 dns_rdatatype_none, 0, &rdataset, NULL); 14127 if (dns_rdataset_isassociated(&rdataset)) 14128 dns_rdataset_disassociate(&rdataset); 14129 if (result != ISC_R_NOTFOUND) 14130 goto failure; 14131 14132 result = dns_nsec3param_deletechains(db, ver, zone, diff); 14133 14134 failure: 14135 if (node != NULL) 14136 dns_db_detachnode(db, &node); 14137 return (result); 14138} 14139 14140/* 14141 * Given an RRSIG rdataset and an algorithm, determine whether there 14142 * are any signatures using that algorithm. 14143 */ 14144static isc_boolean_t 14145signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) { 14146 dns_rdata_t rdata = DNS_RDATA_INIT; 14147 dns_rdata_rrsig_t rrsig; 14148 isc_result_t result; 14149 14150 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig); 14151 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) { 14152 return (ISC_FALSE); 14153 } 14154 14155 for (result = dns_rdataset_first(rdataset); 14156 result == ISC_R_SUCCESS; 14157 result = dns_rdataset_next(rdataset)) 14158 { 14159 dns_rdataset_current(rdataset, &rdata); 14160 result = dns_rdata_tostruct(&rdata, &rrsig, NULL); 14161 RUNTIME_CHECK(result == ISC_R_SUCCESS); 14162 dns_rdata_reset(&rdata); 14163 if (rrsig.algorithm == alg) 14164 return (ISC_TRUE); 14165 } 14166 14167 return (ISC_FALSE); 14168} 14169 14170static isc_result_t 14171add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, 14172 dns_diff_t *diff) 14173{ 14174 dns_name_t *origin; 14175 isc_boolean_t build_nsec3; 14176 isc_result_t result; 14177 14178 origin = dns_db_origin(db); 14179 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL, 14180 &build_nsec3)); 14181 if (build_nsec3) 14182 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum, 14183 ISC_FALSE, zone->privatetype, diff)); 14184 CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff)); 14185 14186 failure: 14187 return (result); 14188} 14189 14190static void 14191zone_rekey(dns_zone_t *zone) { 14192 isc_result_t result; 14193 dns_db_t *db = NULL; 14194 dns_dbnode_t *node = NULL; 14195 dns_dbversion_t *ver = NULL; 14196 dns_rdataset_t soaset, soasigs, keyset, keysigs; 14197 dns_dnsseckeylist_t dnskeys, keys, rmkeys; 14198 dns_dnsseckey_t *key; 14199 dns_diff_t diff, sig_diff; 14200 isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE; 14201 isc_boolean_t newalg = ISC_FALSE; 14202 isc_boolean_t fullsign; 14203 dns_ttl_t ttl = 3600; 14204 const char *dir; 14205 isc_mem_t *mctx; 14206 isc_stdtime_t now; 14207 isc_time_t timenow; 14208 isc_interval_t ival; 14209 char timebuf[80]; 14210 14211 REQUIRE(DNS_ZONE_VALID(zone)); 14212 14213 ISC_LIST_INIT(dnskeys); 14214 ISC_LIST_INIT(keys); 14215 ISC_LIST_INIT(rmkeys); 14216 dns_rdataset_init(&soaset); 14217 dns_rdataset_init(&soasigs); 14218 dns_rdataset_init(&keyset); 14219 dns_rdataset_init(&keysigs); 14220 dir = dns_zone_getkeydirectory(zone); 14221 mctx = zone->mctx; 14222 dns_diff_init(mctx, &diff); 14223 dns_diff_init(mctx, &sig_diff); 14224 sig_diff.resign = zone->sigresigninginterval; 14225 14226 CHECK(dns_zone_getdb(zone, &db)); 14227 CHECK(dns_db_newversion(db, &ver)); 14228 CHECK(dns_db_getoriginnode(db, &node)); 14229 14230 TIME_NOW(&timenow); 14231 now = isc_time_seconds(&timenow); 14232 14233 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys"); 14234 14235 /* Get the SOA record's TTL */ 14236 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 14237 dns_rdatatype_none, 0, &soaset, &soasigs)); 14238 ttl = soaset.ttl; 14239 dns_rdataset_disassociate(&soaset); 14240 14241 /* Get the DNSKEY rdataset */ 14242 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, 14243 dns_rdatatype_none, 0, &keyset, &keysigs); 14244 if (result == ISC_R_SUCCESS) { 14245 ttl = keyset.ttl; 14246 result = dns_dnssec_keylistfromrdataset(&zone->origin, dir, 14247 mctx, &keyset, 14248 &keysigs, &soasigs, 14249 ISC_FALSE, ISC_FALSE, 14250 &dnskeys); 14251 /* Can't get keys for some reason; try again later. */ 14252 if (result != ISC_R_SUCCESS) 14253 goto trylater; 14254 } else if (result != ISC_R_NOTFOUND) 14255 goto failure; 14256 14257 /* 14258 * True when called from "rndc sign". Indicates the zone should be 14259 * fully signed now. 14260 */ 14261 fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0); 14262 14263 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys); 14264 if (result == ISC_R_SUCCESS) { 14265 isc_boolean_t check_ksk; 14266 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK); 14267 14268 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys, 14269 &zone->origin, ttl, &diff, 14270 ISC_TF(!check_ksk), 14271 mctx, logmsg); 14272 14273 /* Keys couldn't be updated for some reason; 14274 * try again later. */ 14275 if (result != ISC_R_SUCCESS) { 14276 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:" 14277 "couldn't update zone keys: %s", 14278 isc_result_totext(result)); 14279 goto trylater; 14280 } 14281 14282 /* 14283 * See if any pre-existing keys have newly become active; 14284 * also, see if any new key is for a new algorithm, as in that 14285 * event, we need to sign the zone fully. (If there's a new 14286 * key, but it's for an already-existing algorithm, then 14287 * the zone signing can be handled incrementally.) 14288 */ 14289 for (key = ISC_LIST_HEAD(dnskeys); 14290 key != NULL; 14291 key = ISC_LIST_NEXT(key, link)) { 14292 if (!key->first_sign) 14293 continue; 14294 14295 newactive = ISC_TRUE; 14296 14297 if (!dns_rdataset_isassociated(&keysigs)) { 14298 newalg = ISC_TRUE; 14299 break; 14300 } 14301 14302 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) { 14303 /* 14304 * This isn't a new algorithm; clear 14305 * first_sign so we won't sign the 14306 * whole zone with this key later 14307 */ 14308 key->first_sign = ISC_FALSE; 14309 } else { 14310 newalg = ISC_TRUE; 14311 break; 14312 } 14313 } 14314 14315 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) && 14316 dnskey_sane(zone, db, ver, &diff)) { 14317 CHECK(dns_diff_apply(&diff, db, ver)); 14318 CHECK(clean_nsec3param(zone, db, ver, &diff)); 14319 CHECK(add_signing_records(db, zone->privatetype, 14320 ver, &diff, 14321 ISC_TF(newalg || fullsign))); 14322 CHECK(increment_soa_serial(db, ver, &diff, mctx)); 14323 CHECK(add_chains(zone, db, ver, &diff)); 14324 CHECK(sign_apex(zone, db, ver, &diff, &sig_diff)); 14325 CHECK(zone_journal(zone, &sig_diff, "zone_rekey")); 14326 commit = ISC_TRUE; 14327 } 14328 } 14329 14330 dns_db_closeversion(db, &ver, commit); 14331 14332 if (commit) { 14333 dns_difftuple_t *tuple; 14334 14335 LOCK_ZONE(zone); 14336 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); 14337 14338 zone_needdump(zone, DNS_DUMP_DELAY); 14339 14340 zone_settimer(zone, &timenow); 14341 14342 /* Remove any signatures from removed keys. */ 14343 if (!ISC_LIST_EMPTY(rmkeys)) { 14344 for (key = ISC_LIST_HEAD(rmkeys); 14345 key != NULL; 14346 key = ISC_LIST_NEXT(key, link)) { 14347 result = zone_signwithkey(zone, 14348 dst_key_alg(key->key), 14349 dst_key_id(key->key), 14350 ISC_TRUE); 14351 if (result != ISC_R_SUCCESS) { 14352 dns_zone_log(zone, ISC_LOG_ERROR, 14353 "zone_signwithkey failed: %s", 14354 dns_result_totext(result)); 14355 } 14356 } 14357 } 14358 14359 if (fullsign) { 14360 /* 14361 * "rndc sign" was called, so we now sign the zone 14362 * with all active keys, whether they're new or not. 14363 */ 14364 for (key = ISC_LIST_HEAD(dnskeys); 14365 key != NULL; 14366 key = ISC_LIST_NEXT(key, link)) { 14367 if (!key->force_sign && !key->hint_sign) 14368 continue; 14369 14370 result = zone_signwithkey(zone, 14371 dst_key_alg(key->key), 14372 dst_key_id(key->key), 14373 ISC_FALSE); 14374 if (result != ISC_R_SUCCESS) { 14375 dns_zone_log(zone, ISC_LOG_ERROR, 14376 "zone_signwithkey failed: %s", 14377 dns_result_totext(result)); 14378 } 14379 } 14380 } else if (newalg) { 14381 /* 14382 * We haven't been told to sign fully, but a new 14383 * algorithm was added to the DNSKEY. We sign 14384 * the full zone, but only with newly active 14385 * keys. 14386 */ 14387 for (key = ISC_LIST_HEAD(dnskeys); 14388 key != NULL; 14389 key = ISC_LIST_NEXT(key, link)) { 14390 if (!key->first_sign) 14391 continue; 14392 14393 result = zone_signwithkey(zone, 14394 dst_key_alg(key->key), 14395 dst_key_id(key->key), 14396 ISC_FALSE); 14397 if (result != ISC_R_SUCCESS) { 14398 dns_zone_log(zone, ISC_LOG_ERROR, 14399 "zone_signwithkey failed: %s", 14400 dns_result_totext(result)); 14401 } 14402 } 14403 } 14404 14405 /* 14406 * Clear fullsign flag, if it was set, so we don't do 14407 * another full signing next time 14408 */ 14409 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN; 14410 14411 /* 14412 * Cause the zone to add/delete NSEC3 chains for the 14413 * deferred NSEC3PARAM changes. 14414 */ 14415 for (tuple = ISC_LIST_HEAD(sig_diff.tuples); 14416 tuple != NULL; 14417 tuple = ISC_LIST_NEXT(tuple, link)) { 14418 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; 14419 dns_rdata_t rdata = DNS_RDATA_INIT; 14420 dns_rdata_nsec3param_t nsec3param; 14421 14422 if (tuple->rdata.type != zone->privatetype || 14423 tuple->op != DNS_DIFFOP_ADD) 14424 continue; 14425 14426 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata, 14427 buf, sizeof(buf))) 14428 continue; 14429 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); 14430 RUNTIME_CHECK(result == ISC_R_SUCCESS); 14431 if (nsec3param.flags == 0) 14432 continue; 14433 14434 result = zone_addnsec3chain(zone, &nsec3param); 14435 if (result != ISC_R_SUCCESS) { 14436 dns_zone_log(zone, ISC_LOG_ERROR, 14437 "zone_addnsec3chain failed: %s", 14438 dns_result_totext(result)); 14439 } 14440 } 14441 14442 /* 14443 * Schedule the next resigning event 14444 */ 14445 set_resigntime(zone); 14446 UNLOCK_ZONE(zone); 14447 } 14448 14449 isc_time_settoepoch(&zone->refreshkeytime); 14450 14451 /* 14452 * If we're doing key maintenance, set the key refresh timer to 14453 * the next scheduled key event or to one hour in the future, 14454 * whichever is sooner. 14455 */ 14456 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) { 14457 isc_time_t timethen; 14458 isc_stdtime_t then; 14459 14460 LOCK_ZONE(zone); 14461 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen); 14462 zone->refreshkeytime = timethen; 14463 UNLOCK_ZONE(zone); 14464 14465 for (key = ISC_LIST_HEAD(dnskeys); 14466 key != NULL; 14467 key = ISC_LIST_NEXT(key, link)) { 14468 then = now; 14469 result = next_keyevent(key->key, &then); 14470 if (result != ISC_R_SUCCESS) 14471 continue; 14472 14473 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen); 14474 LOCK_ZONE(zone); 14475 if (isc_time_compare(&timethen, 14476 &zone->refreshkeytime) < 0) { 14477 zone->refreshkeytime = timethen; 14478 } 14479 UNLOCK_ZONE(zone); 14480 } 14481 14482 zone_settimer(zone, &timenow); 14483 14484 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); 14485 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); 14486 } 14487 14488 failure: 14489 dns_diff_clear(&diff); 14490 dns_diff_clear(&sig_diff); 14491 14492 clear_keylist(&dnskeys, mctx); 14493 clear_keylist(&keys, mctx); 14494 clear_keylist(&rmkeys, mctx); 14495 14496 if (ver != NULL) 14497 dns_db_closeversion(db, &ver, ISC_FALSE); 14498 if (dns_rdataset_isassociated(&keyset)) 14499 dns_rdataset_disassociate(&keyset); 14500 if (dns_rdataset_isassociated(&keysigs)) 14501 dns_rdataset_disassociate(&keysigs); 14502 if (dns_rdataset_isassociated(&soasigs)) 14503 dns_rdataset_disassociate(&soasigs); 14504 if (node != NULL) 14505 dns_db_detachnode(db, &node); 14506 if (db != NULL) 14507 dns_db_detach(&db); 14508 return; 14509 14510 trylater: 14511 isc_interval_set(&ival, HOUR, 0); 14512 isc_time_nowplusinterval(&zone->refreshkeytime, &ival); 14513 goto failure; 14514} 14515 14516void 14517dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) { 14518 isc_time_t now; 14519 14520 if (zone->type == dns_zone_master && zone->task != NULL) { 14521 LOCK_ZONE(zone); 14522 14523 if (fullsign) 14524 zone->keyopts |= DNS_ZONEKEY_FULLSIGN; 14525 14526 TIME_NOW(&now); 14527 zone->refreshkeytime = now; 14528 zone_settimer(zone, &now); 14529 14530 UNLOCK_ZONE(zone); 14531 } 14532} 14533 14534isc_result_t 14535dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, 14536 unsigned int *errors) 14537{ 14538 isc_result_t result; 14539 dns_dbnode_t *node = NULL; 14540 14541 REQUIRE(DNS_ZONE_VALID(zone)); 14542 REQUIRE(errors != NULL); 14543 14544 result = dns_db_getoriginnode(db, &node); 14545 if (result != ISC_R_SUCCESS) 14546 return (result); 14547 result = zone_count_ns_rr(zone, db, node, version, NULL, errors, 14548 ISC_FALSE); 14549 dns_db_detachnode(db, &node); 14550 return (result); 14551} 14552 14553void 14554dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) { 14555 REQUIRE(DNS_ZONE_VALID(zone)); 14556 LOCK_ZONE(zone); 14557 zone->added = added; 14558 UNLOCK_ZONE(zone); 14559} 14560 14561isc_boolean_t 14562dns_zone_getadded(dns_zone_t *zone) { 14563 REQUIRE(DNS_ZONE_VALID(zone)); 14564 return (zone->added); 14565} 14566 14567isc_result_t 14568dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db) 14569{ 14570 isc_time_t loadtime; 14571 isc_result_t result; 14572 TIME_NOW(&loadtime); 14573 14574 LOCK_ZONE(zone); 14575 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); 14576 UNLOCK_ZONE(zone); 14577 return result; 14578} 14579