xref: /minix/external/bsd/bind/dist/lib/dns/zone.c (revision 00b67f09)
1 /*	$NetBSD: zone.c,v 1.14 2015/07/08 17:28:59 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2004-2015  Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (C) 1999-2003  Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*! \file */
21 
22 #include <config.h>
23 #include <errno.h>
24 
25 #include <isc/file.h>
26 #include <isc/hex.h>
27 #include <isc/mutex.h>
28 #include <isc/pool.h>
29 #include <isc/print.h>
30 #include <isc/random.h>
31 #include <isc/ratelimiter.h>
32 #include <isc/refcount.h>
33 #include <isc/rwlock.h>
34 #include <isc/serial.h>
35 #include <isc/stats.h>
36 #include <isc/stdtime.h>
37 #include <isc/strerror.h>
38 #include <isc/string.h>
39 #include <isc/taskpool.h>
40 #include <isc/thread.h>
41 #include <isc/timer.h>
42 #include <isc/util.h>
43 
44 #include <dns/acache.h>
45 #include <dns/acl.h>
46 #include <dns/adb.h>
47 #include <dns/callbacks.h>
48 #include <dns/db.h>
49 #include <dns/dbiterator.h>
50 #include <dns/dlz.h>
51 #include <dns/dnssec.h>
52 #include <dns/events.h>
53 #include <dns/journal.h>
54 #include <dns/keydata.h>
55 #include <dns/keytable.h>
56 #include <dns/keyvalues.h>
57 #include <dns/log.h>
58 #include <dns/master.h>
59 #include <dns/masterdump.h>
60 #include <dns/message.h>
61 #include <dns/name.h>
62 #include <dns/nsec.h>
63 #include <dns/nsec3.h>
64 #include <dns/peer.h>
65 #include <dns/private.h>
66 #include <dns/rbt.h>
67 #include <dns/rcode.h>
68 #include <dns/rdata.h>
69 #include <dns/rdataclass.h>
70 #include <dns/rdatalist.h>
71 #include <dns/rdataset.h>
72 #include <dns/rdatasetiter.h>
73 #include <dns/rdatastruct.h>
74 #include <dns/rdatatype.h>
75 #include <dns/request.h>
76 #include <dns/resolver.h>
77 #include <dns/result.h>
78 #include <dns/rriterator.h>
79 #include <dns/soa.h>
80 #include <dns/ssu.h>
81 #include <dns/stats.h>
82 #include <dns/time.h>
83 #include <dns/tsig.h>
84 #include <dns/update.h>
85 #include <dns/xfrin.h>
86 #include <dns/zone.h>
87 #include <dns/zt.h>
88 
89 #include <dst/dst.h>
90 
91 #define ZONE_MAGIC			ISC_MAGIC('Z', 'O', 'N', 'E')
92 #define DNS_ZONE_VALID(zone)		ISC_MAGIC_VALID(zone, ZONE_MAGIC)
93 
94 #define NOTIFY_MAGIC			ISC_MAGIC('N', 't', 'f', 'y')
95 #define DNS_NOTIFY_VALID(notify)	ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
96 
97 #define STUB_MAGIC			ISC_MAGIC('S', 't', 'u', 'b')
98 #define DNS_STUB_VALID(stub)		ISC_MAGIC_VALID(stub, STUB_MAGIC)
99 
100 #define ZONEMGR_MAGIC			ISC_MAGIC('Z', 'm', 'g', 'r')
101 #define DNS_ZONEMGR_VALID(stub)		ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
102 
103 #define LOAD_MAGIC			ISC_MAGIC('L', 'o', 'a', 'd')
104 #define DNS_LOAD_VALID(load)		ISC_MAGIC_VALID(load, LOAD_MAGIC)
105 
106 #define FORWARD_MAGIC			ISC_MAGIC('F', 'o', 'r', 'w')
107 #define DNS_FORWARD_VALID(load)		ISC_MAGIC_VALID(load, FORWARD_MAGIC)
108 
109 #define IO_MAGIC			ISC_MAGIC('Z', 'm', 'I', 'O')
110 #define DNS_IO_VALID(load)		ISC_MAGIC_VALID(load, IO_MAGIC)
111 
112 /*%
113  * Ensure 'a' is at least 'min' but not more than 'max'.
114  */
115 #define RANGE(a, min, max) \
116 		(((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
117 
118 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
119 
120 /*%
121  * Key flags
122  */
123 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
124 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
125 #define ALG(x) dst_key_alg(x)
126 
127 /*
128  * Default values.
129  */
130 #define DNS_DEFAULT_IDLEIN 3600		/*%< 1 hour */
131 #define DNS_DEFAULT_IDLEOUT 3600	/*%< 1 hour */
132 #define MAX_XFER_TIME (2*3600)		/*%< Documented default is 2 hours */
133 #define RESIGN_DELAY 3600		/*%< 1 hour */
134 
135 #ifndef DNS_MAX_EXPIRE
136 #define DNS_MAX_EXPIRE	14515200	/*%< 24 weeks */
137 #endif
138 
139 #ifndef DNS_DUMP_DELAY
140 #define DNS_DUMP_DELAY 900		/*%< 15 minutes */
141 #endif
142 
143 typedef struct dns_notify dns_notify_t;
144 typedef struct dns_stub dns_stub_t;
145 typedef struct dns_load dns_load_t;
146 typedef struct dns_forward dns_forward_t;
147 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
148 typedef struct dns_io dns_io_t;
149 typedef ISC_LIST(dns_io_t) dns_iolist_t;
150 typedef struct dns_signing dns_signing_t;
151 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
152 typedef struct dns_nsec3chain dns_nsec3chain_t;
153 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
154 typedef struct dns_keyfetch dns_keyfetch_t;
155 typedef struct dns_asyncload dns_asyncload_t;
156 typedef struct dns_include dns_include_t;
157 
158 #define DNS_ZONE_CHECKLOCK
159 #ifdef DNS_ZONE_CHECKLOCK
160 #define LOCK_ZONE(z) \
161 	 do { LOCK(&(z)->lock); \
162 	      INSIST((z)->locked == ISC_FALSE); \
163 	     (z)->locked = ISC_TRUE; \
164 		} while (/*CONSTCOND*/0)
165 #define UNLOCK_ZONE(z) \
166 	do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (/*CONSTCOND*/0)
167 #define LOCKED_ZONE(z) ((z)->locked)
168 #define TRYLOCK_ZONE(result, z) \
169 	do { \
170 	      result = isc_mutex_trylock(&(z)->lock); \
171 	      if (result == ISC_R_SUCCESS) {  \
172 		     INSIST((z)->locked == ISC_FALSE); \
173 		     (z)->locked = ISC_TRUE; \
174 	      } \
175 	} while (/*CONSTCOND*/0)
176 #else
177 #define LOCK_ZONE(z) LOCK(&(z)->lock)
178 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
179 #define LOCKED_ZONE(z) ISC_TRUE
180 #define TRYLOCK_ZONE(result, z) \
181 	do { result = isc_mutex_trylock(&(z)->lock); } while (/*CONSTCOND*/0)
182 #endif
183 
184 #ifdef ISC_RWLOCK_USEATOMIC
185 #define ZONEDB_INITLOCK(l)	isc_rwlock_init((l), 0, 0)
186 #define ZONEDB_DESTROYLOCK(l)	isc_rwlock_destroy(l)
187 #define ZONEDB_LOCK(l, t)	RWLOCK((l), (t))
188 #define ZONEDB_UNLOCK(l, t)	RWUNLOCK((l), (t))
189 #else
190 #define ZONEDB_INITLOCK(l)	isc_mutex_init(l)
191 #define ZONEDB_DESTROYLOCK(l)	DESTROYLOCK(l)
192 #define ZONEDB_LOCK(l, t)	LOCK(l)
193 #define ZONEDB_UNLOCK(l, t)	UNLOCK(l)
194 #endif
195 
196 struct dns_zone {
197 	/* Unlocked */
198 	unsigned int		magic;
199 	isc_mutex_t		lock;
200 #ifdef DNS_ZONE_CHECKLOCK
201 	isc_boolean_t		locked;
202 #endif
203 	isc_mem_t		*mctx;
204 	isc_refcount_t		erefs;
205 
206 #ifdef ISC_RWLOCK_USEATOMIC
207 	isc_rwlock_t		dblock;
208 #else
209 	isc_mutex_t		dblock;
210 #endif
211 	dns_db_t		*db;		/* Locked by dblock */
212 
213 	/* Locked */
214 	dns_zonemgr_t		*zmgr;
215 	ISC_LINK(dns_zone_t)	link;		/* Used by zmgr. */
216 	isc_timer_t		*timer;
217 	unsigned int		irefs;
218 	dns_name_t		origin;
219 	char			*masterfile;
220 	ISC_LIST(dns_include_t)	includes;	/* Include files */
221 	ISC_LIST(dns_include_t)	newincludes;	/* Loading */
222 	unsigned int		nincludes;
223 	dns_masterformat_t	masterformat;
224 	char			*journal;
225 	isc_int32_t		journalsize;
226 	dns_rdataclass_t	rdclass;
227 	dns_zonetype_t		type;
228 	unsigned int		flags;
229 	unsigned int		options;
230 	unsigned int		options2;
231 	unsigned int		db_argc;
232 	char			**db_argv;
233 	isc_time_t		expiretime;
234 	isc_time_t		refreshtime;
235 	isc_time_t		dumptime;
236 	isc_time_t		loadtime;
237 	isc_time_t		notifytime;
238 	isc_time_t		resigntime;
239 	isc_time_t		keywarntime;
240 	isc_time_t		signingtime;
241 	isc_time_t		nsec3chaintime;
242 	isc_time_t		refreshkeytime;
243 	isc_uint32_t		refreshkeyinterval;
244 	isc_uint32_t		refreshkeycount;
245 	isc_uint32_t		refresh;
246 	isc_uint32_t		retry;
247 	isc_uint32_t		expire;
248 	isc_uint32_t		minimum;
249 	isc_stdtime_t		key_expiry;
250 	isc_stdtime_t		log_key_expired_timer;
251 	char			*keydirectory;
252 
253 	isc_uint32_t		maxrefresh;
254 	isc_uint32_t		minrefresh;
255 	isc_uint32_t		maxretry;
256 	isc_uint32_t		minretry;
257 
258 	isc_sockaddr_t		*masters;
259 	isc_dscp_t		*masterdscps;
260 	dns_name_t		**masterkeynames;
261 	isc_boolean_t		*mastersok;
262 	unsigned int		masterscnt;
263 	unsigned int		curmaster;
264 	isc_sockaddr_t		masteraddr;
265 	dns_notifytype_t	notifytype;
266 	isc_sockaddr_t		*notify;
267 	dns_name_t		**notifykeynames;
268 	isc_dscp_t		*notifydscp;
269 	unsigned int		notifycnt;
270 	isc_sockaddr_t		notifyfrom;
271 	isc_task_t		*task;
272 	isc_task_t		*loadtask;
273 	isc_sockaddr_t		notifysrc4;
274 	isc_sockaddr_t		notifysrc6;
275 	isc_sockaddr_t		xfrsource4;
276 	isc_sockaddr_t		xfrsource6;
277 	isc_sockaddr_t		altxfrsource4;
278 	isc_sockaddr_t		altxfrsource6;
279 	isc_sockaddr_t		sourceaddr;
280 	isc_dscp_t		notifysrc4dscp;
281 	isc_dscp_t		notifysrc6dscp;
282 	isc_dscp_t		xfrsource4dscp;
283 	isc_dscp_t		xfrsource6dscp;
284 	isc_dscp_t		altxfrsource4dscp;
285 	isc_dscp_t		altxfrsource6dscp;
286 	dns_xfrin_ctx_t		*xfr;		/* task locked */
287 	dns_tsigkey_t		*tsigkey;	/* key used for xfr */
288 	/* Access Control Lists */
289 	dns_acl_t		*update_acl;
290 	dns_acl_t		*forward_acl;
291 	dns_acl_t		*notify_acl;
292 	dns_acl_t		*query_acl;
293 	dns_acl_t		*queryon_acl;
294 	dns_acl_t		*xfr_acl;
295 	isc_boolean_t		update_disabled;
296 	isc_boolean_t		zero_no_soa_ttl;
297 	dns_severity_t		check_names;
298 	ISC_LIST(dns_notify_t)	notifies;
299 	dns_request_t		*request;
300 	dns_loadctx_t		*lctx;
301 	dns_io_t		*readio;
302 	dns_dumpctx_t		*dctx;
303 	dns_io_t		*writeio;
304 	isc_uint32_t		maxxfrin;
305 	isc_uint32_t		maxxfrout;
306 	isc_uint32_t		idlein;
307 	isc_uint32_t		idleout;
308 	isc_event_t		ctlevent;
309 	dns_ssutable_t		*ssutable;
310 	isc_uint32_t		sigvalidityinterval;
311 	isc_uint32_t		sigresigninginterval;
312 	dns_view_t		*view;
313 	dns_acache_t		*acache;
314 	dns_checkmxfunc_t	checkmx;
315 	dns_checksrvfunc_t	checksrv;
316 	dns_checknsfunc_t	checkns;
317 	/*%
318 	 * Zones in certain states such as "waiting for zone transfer"
319 	 * or "zone transfer in progress" are kept on per-state linked lists
320 	 * in the zone manager using the 'statelink' field.  The 'statelist'
321 	 * field points at the list the zone is currently on.  It the zone
322 	 * is not on any such list, statelist is NULL.
323 	 */
324 	ISC_LINK(dns_zone_t)	statelink;
325 	dns_zonelist_t		*statelist;
326 	/*%
327 	 * Statistics counters about zone management.
328 	 */
329 	isc_stats_t		*stats;
330 	/*%
331 	 * Optional per-zone statistics counters.  Counted outside of this
332 	 * module.
333 	 */
334 	dns_zonestat_level_t	statlevel;
335 	isc_boolean_t		requeststats_on;
336 	isc_stats_t		*requeststats;
337 	dns_stats_t		*rcvquerystats;
338 	isc_uint32_t		notifydelay;
339 	dns_isselffunc_t	isself;
340 	void			*isselfarg;
341 
342 	char *			strnamerd;
343 	char *			strname;
344 	char *			strrdclass;
345 	char *			strviewname;
346 
347 	/*%
348 	 * Serial number for deferred journal compaction.
349 	 */
350 	isc_uint32_t		compact_serial;
351 	/*%
352 	 * Keys that are signing the zone for the first time.
353 	 */
354 	dns_signinglist_t	signing;
355 	dns_nsec3chainlist_t	nsec3chain;
356 	/*%
357 	 * Signing / re-signing quantum stopping parameters.
358 	 */
359 	isc_uint32_t		signatures;
360 	isc_uint32_t		nodes;
361 	dns_rdatatype_t		privatetype;
362 
363 	/*%
364 	 * Autosigning/key-maintenance options
365 	 */
366 	isc_uint32_t		keyopts;
367 
368 	/*%
369 	 * True if added by "rndc addzone"
370 	 */
371 	isc_boolean_t           added;
372 
373 	/*%
374 	 * response policy data to be relayed to the database
375 	 */
376 	dns_rpz_zones_t		*rpzs;
377 	dns_rpz_num_t		rpz_num;
378 
379 	/*%
380 	 * Serial number update method.
381 	 */
382 	dns_updatemethod_t	updatemethod;
383 
384 	/*%
385 	 * whether ixfr is requested
386 	 */
387 	isc_boolean_t		requestixfr;
388 
389 	/*%
390 	 * Outstanding forwarded UPDATE requests.
391 	 */
392 	dns_forwardlist_t	forwards;
393 
394 	dns_zone_t		*raw;
395 	dns_zone_t		*secure;
396 
397 	isc_boolean_t		sourceserialset;
398 	isc_uint32_t		sourceserial;
399 
400 	/*%
401 	 * maximum zone ttl
402 	 */
403 	dns_ttl_t		maxttl;
404 
405 };
406 
407 typedef struct {
408 	dns_diff_t	*diff;
409 	isc_boolean_t	offline;
410 } zonediff_t;
411 
412 #define zonediff_init(z, d) \
413 	do { \
414 		zonediff_t *_z = (z); \
415 		(_z)->diff = (d); \
416 		(_z)->offline = ISC_FALSE; \
417 	} while (/*CONSTCOND*/0)
418 
419 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
420 #define DNS_ZONE_SETFLAG(z,f) do { \
421 		INSIST(LOCKED_ZONE(z)); \
422 		(z)->flags |= (f); \
423 		} while (/*CONSTCOND*/0)
424 #define DNS_ZONE_CLRFLAG(z,f) do { \
425 		INSIST(LOCKED_ZONE(z)); \
426 		(z)->flags &= ~(f); \
427 		} while (/*CONSTCOND*/0)
428 	/* XXX MPA these may need to go back into zone.h */
429 #define DNS_ZONEFLG_REFRESH	0x00000001U	/*%< refresh check in progress */
430 #define DNS_ZONEFLG_NEEDDUMP	0x00000002U	/*%< zone need consolidation */
431 #define DNS_ZONEFLG_USEVC	0x00000004U	/*%< use tcp for refresh query */
432 #define DNS_ZONEFLG_DUMPING	0x00000008U	/*%< a dump is in progress */
433 #define DNS_ZONEFLG_HASINCLUDE	0x00000010U	/*%< $INCLUDE in zone file */
434 #define DNS_ZONEFLG_LOADED	0x00000020U	/*%< database has loaded */
435 #define DNS_ZONEFLG_EXITING	0x00000040U	/*%< zone is being destroyed */
436 #define DNS_ZONEFLG_EXPIRED	0x00000080U	/*%< zone has expired */
437 #define DNS_ZONEFLG_NEEDREFRESH	0x00000100U	/*%< refresh check needed */
438 #define DNS_ZONEFLG_UPTODATE	0x00000200U	/*%< zone contents are
439 						 * uptodate */
440 #define DNS_ZONEFLG_NEEDNOTIFY	0x00000400U	/*%< need to send out notify
441 						 * messages */
442 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U	/*%< generate a journal diff on
443 						 * reload */
444 #define DNS_ZONEFLG_NOMASTERS	0x00001000U	/*%< an attempt to refresh a
445 						 * zone with no masters
446 						 * occurred */
447 #define DNS_ZONEFLG_LOADING	0x00002000U	/*%< load from disk in progress*/
448 #define DNS_ZONEFLG_HAVETIMERS	0x00004000U	/*%< timer values have been set
449 						 * from SOA (if not set, we
450 						 * are still using
451 						 * default timer values) */
452 #define DNS_ZONEFLG_FORCEXFER	0x00008000U	/*%< Force a zone xfer */
453 #define DNS_ZONEFLG_NOREFRESH	0x00010000U
454 #define DNS_ZONEFLG_DIALNOTIFY	0x00020000U
455 #define DNS_ZONEFLG_DIALREFRESH	0x00040000U
456 #define DNS_ZONEFLG_SHUTDOWN	0x00080000U
457 #define DNS_ZONEFLAG_NOIXFR	0x00100000U	/*%< IXFR failed, force AXFR */
458 #define DNS_ZONEFLG_FLUSH	0x00200000U
459 #define DNS_ZONEFLG_NOEDNS	0x00400000U
460 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
461 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
462 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
463 #define DNS_ZONEFLG_REFRESHING	0x04000000U	/*%< Refreshing keydata */
464 #define DNS_ZONEFLG_THAW	0x08000000U
465 #define DNS_ZONEFLG_LOADPENDING	0x10000000U	/*%< Loading scheduled */
466 #define DNS_ZONEFLG_NODELAY	0x20000000U
467 #define DNS_ZONEFLG_SENDSECURE  0x40000000U
468 #define DNS_ZONEFLG_NEEDSTARTUPNOTIFY 0x80000000U /*%< need to send out notify
469 						   *   due to the zone just
470 						   *   being loaded for the
471 						   *   first time.  */
472 
473 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
474 #define DNS_ZONE_OPTION2(z,o) (((z)->options2 & (o)) != 0)
475 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
476 
477 /* Flags for zone_load() */
478 #define DNS_ZONELOADFLAG_NOSTAT	0x00000001U	/* Do not stat() master files */
479 #define DNS_ZONELOADFLAG_THAW	0x00000002U	/* Thaw the zone on successful
480 						   load. */
481 
482 #define UNREACH_CHACHE_SIZE	10U
483 #define UNREACH_HOLD_TIME	600	/* 10 minutes */
484 
485 #define CHECK(op) \
486 	do { result = (op); \
487 		if (result != ISC_R_SUCCESS) goto failure; \
488 	} while (/*CONSTCOND*/0)
489 
490 struct dns_unreachable {
491 	isc_sockaddr_t	remote;
492 	isc_sockaddr_t	local;
493 	isc_uint32_t	expire;
494 	isc_uint32_t	last;
495 	isc_uint32_t	count;
496 };
497 
498 struct dns_zonemgr {
499 	unsigned int		magic;
500 	isc_mem_t *		mctx;
501 	int			refs;		/* Locked by rwlock */
502 	isc_taskmgr_t *		taskmgr;
503 	isc_timermgr_t *	timermgr;
504 	isc_socketmgr_t *	socketmgr;
505 	isc_taskpool_t *	zonetasks;
506 	isc_taskpool_t *	loadtasks;
507 	isc_task_t *		task;
508 	isc_pool_t *		mctxpool;
509 	isc_ratelimiter_t *	notifyrl;
510 	isc_ratelimiter_t *	refreshrl;
511 	isc_ratelimiter_t *	startupnotifyrl;
512 	isc_ratelimiter_t *	startuprefreshrl;
513 	isc_rwlock_t		rwlock;
514 	isc_mutex_t		iolock;
515 	isc_rwlock_t		urlock;
516 
517 	/* Locked by rwlock. */
518 	dns_zonelist_t		zones;
519 	dns_zonelist_t		waiting_for_xfrin;
520 	dns_zonelist_t		xfrin_in_progress;
521 
522 	/* Configuration data. */
523 	isc_uint32_t		transfersin;
524 	isc_uint32_t		transfersperns;
525 	unsigned int		notifyrate;
526 	unsigned int		startupnotifyrate;
527 	unsigned int		serialqueryrate;
528 	unsigned int		startupserialqueryrate;
529 
530 	/* Locked by iolock */
531 	isc_uint32_t		iolimit;
532 	isc_uint32_t		ioactive;
533 	dns_iolist_t		high;
534 	dns_iolist_t		low;
535 
536 	/* Locked by urlock. */
537 	/* LRU cache */
538 	struct dns_unreachable	unreachable[UNREACH_CHACHE_SIZE];
539 };
540 
541 /*%
542  * Hold notify state.
543  */
544 struct dns_notify {
545 	unsigned int		magic;
546 	unsigned int		flags;
547 	isc_mem_t		*mctx;
548 	dns_zone_t		*zone;
549 	dns_adbfind_t		*find;
550 	dns_request_t		*request;
551 	dns_name_t		ns;
552 	isc_sockaddr_t		dst;
553 	dns_tsigkey_t		*key;
554 	isc_dscp_t		dscp;
555 	ISC_LINK(dns_notify_t)	link;
556 	isc_event_t		*event;
557 };
558 
559 #define DNS_NOTIFY_NOSOA	0x0001U
560 #define DNS_NOTIFY_STARTUP	0x0002U
561 
562 /*%
563  *	dns_stub holds state while performing a 'stub' transfer.
564  *	'db' is the zone's 'db' or a new one if this is the initial
565  *	transfer.
566  */
567 
568 struct dns_stub {
569 	unsigned int		magic;
570 	isc_mem_t		*mctx;
571 	dns_zone_t		*zone;
572 	dns_db_t		*db;
573 	dns_dbversion_t		*version;
574 };
575 
576 /*%
577  *	Hold load state.
578  */
579 struct dns_load {
580 	unsigned int		magic;
581 	isc_mem_t		*mctx;
582 	dns_zone_t		*zone;
583 	dns_db_t		*db;
584 	isc_time_t		loadtime;
585 	dns_rdatacallbacks_t	callbacks;
586 };
587 
588 /*%
589  *	Hold forward state.
590  */
591 struct dns_forward {
592 	unsigned int		magic;
593 	isc_mem_t		*mctx;
594 	dns_zone_t		*zone;
595 	isc_buffer_t		*msgbuf;
596 	dns_request_t		*request;
597 	isc_uint32_t		which;
598 	isc_sockaddr_t		addr;
599 	dns_updatecallback_t	callback;
600 	void			*callback_arg;
601 	unsigned int		options;
602 	ISC_LINK(dns_forward_t)	link;
603 };
604 
605 /*%
606  *	Hold IO request state.
607  */
608 struct dns_io {
609 	unsigned int	magic;
610 	dns_zonemgr_t	*zmgr;
611 	isc_boolean_t	high;
612 	isc_task_t	*task;
613 	ISC_LINK(dns_io_t) link;
614 	isc_event_t	*event;
615 };
616 
617 /*%
618  *	Hold state for when we are signing a zone with a new
619  *	DNSKEY as result of an update.
620  */
621 struct dns_signing {
622 	unsigned int		magic;
623 	dns_db_t		*db;
624 	dns_dbiterator_t	*dbiterator;
625 	dns_secalg_t		algorithm;
626 	isc_uint16_t		keyid;
627 	isc_boolean_t		delete;
628 	isc_boolean_t		done;
629 	ISC_LINK(dns_signing_t)	link;
630 };
631 
632 struct dns_nsec3chain {
633 	unsigned int			magic;
634 	dns_db_t			*db;
635 	dns_dbiterator_t		*dbiterator;
636 	dns_rdata_nsec3param_t		nsec3param;
637 	unsigned char			salt[255];
638 	isc_boolean_t			done;
639 	isc_boolean_t			seen_nsec;
640 	isc_boolean_t			delete_nsec;
641 	isc_boolean_t			save_delete_nsec;
642 	ISC_LINK(dns_nsec3chain_t)	link;
643 };
644 /*%<
645  * 'dbiterator' contains a iterator for the database.  If we are creating
646  * a NSEC3 chain only the non-NSEC3 nodes will be iterated.  If we are
647  * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
648  * iterated.
649  *
650  * 'nsec3param' contains the parameters of the NSEC3 chain being created
651  * or removed.
652  *
653  * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
654  *
655  * 'seen_nsec' will be set to true if, while iterating the zone to create a
656  * NSEC3 chain, a NSEC record is seen.
657  *
658  * 'delete_nsec' will be set to true if, at the completion of the creation
659  * of a NSEC3 chain, 'seen_nsec' is true.  If 'delete_nsec' is true then we
660  * are in the process of deleting the NSEC chain.
661  *
662  * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
663  * so it can be recovered in the event of a error.
664  */
665 
666 struct dns_keyfetch {
667 	dns_fixedname_t name;
668 	dns_rdataset_t keydataset;
669 	dns_rdataset_t dnskeyset;
670 	dns_rdataset_t dnskeysigset;
671 	dns_zone_t *zone;
672 	dns_db_t *db;
673 	dns_fetch_t *fetch;
674 };
675 
676 /*%
677  * Hold state for an asynchronous load
678  */
679 struct dns_asyncload {
680 	dns_zone_t *zone;
681 	dns_zt_zoneloaded_t loaded;
682 	void *loaded_arg;
683 };
684 
685 /*%
686  * Reference to an include file encountered during loading
687  */
688 struct dns_include {
689 	char *name;
690 	isc_time_t filetime;
691 	ISC_LINK(dns_include_t)	link;
692 };
693 
694 #define HOUR 3600
695 #define DAY (24*HOUR)
696 #define MONTH (30*DAY)
697 
698 /*
699  * These can be overridden by the -T mkeytimers option on the command
700  * line, so that we can test with shorter periods than specified in
701  * RFC 5011.
702  */
703 unsigned int dns_zone_mkey_hour = HOUR;
704 unsigned int dns_zone_mkey_day = (24 * HOUR);
705 unsigned int dns_zone_mkey_month = (30 * DAY);
706 
707 
708 #define SEND_BUFFER_SIZE 2048
709 
710 static void zone_settimer(dns_zone_t *, isc_time_t *);
711 static void cancel_refresh(dns_zone_t *);
712 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
713 			  const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
714 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
715      ISC_FORMAT_PRINTF(3, 4);
716 static void queue_xfrin(dns_zone_t *zone);
717 static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
718 				  dns_diff_t *diff, dns_diffop_t op,
719 				  dns_name_t *name, dns_ttl_t ttl,
720 				  dns_rdata_t *rdata);
721 static void zone_unload(dns_zone_t *zone);
722 static void zone_expire(dns_zone_t *zone);
723 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
724 static void zone_idetach(dns_zone_t **zonep);
725 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
726 				   isc_boolean_t dump);
727 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
728 static inline void zone_detachdb(dns_zone_t *zone);
729 static isc_result_t default_journal(dns_zone_t *zone);
730 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
731 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
732 				  isc_time_t loadtime, isc_result_t result);
733 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
734 static void zone_shutdown(isc_task_t *, isc_event_t *);
735 static void zone_loaddone(void *arg, isc_result_t result);
736 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
737 				   isc_time_t loadtime);
738 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
739 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
740 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
741 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
742 static isc_result_t zone_send_secureserial(dns_zone_t *zone,
743 					   isc_uint32_t serial);
744 
745 #if 0
746 /* ondestroy example */
747 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
748 #endif
749 
750 static void refresh_callback(isc_task_t *, isc_event_t *);
751 static void stub_callback(isc_task_t *, isc_event_t *);
752 static void queue_soa_query(dns_zone_t *zone);
753 static void soa_query(isc_task_t *, isc_event_t *);
754 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
755 		     dns_stub_t *stub);
756 static int message_count(dns_message_t *msg, dns_section_t section,
757 			 dns_rdatatype_t type);
758 static void notify_cancel(dns_zone_t *zone);
759 static void notify_find_address(dns_notify_t *notify);
760 static void notify_send(dns_notify_t *notify);
761 static isc_result_t notify_createmessage(dns_zone_t *zone,
762 					 unsigned int flags,
763 					 dns_message_t **messagep);
764 static void notify_done(isc_task_t *task, isc_event_t *event);
765 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
766 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
767 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
768 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
769 					     dns_zone_t *zone);
770 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
771 static void zonemgr_free(dns_zonemgr_t *zmgr);
772 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
773 				  isc_task_t *task, isc_taskaction_t action,
774 				  void *arg, dns_io_t **iop);
775 static void zonemgr_putio(dns_io_t **iop);
776 static void zonemgr_cancelio(dns_io_t *io);
777 
778 static isc_result_t
779 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
780 		 unsigned int *soacount, isc_uint32_t *serial,
781 		 isc_uint32_t *refresh, isc_uint32_t *retry,
782 		 isc_uint32_t *expire, isc_uint32_t *minimum,
783 		 unsigned int *errors);
784 
785 static void zone_freedbargs(dns_zone_t *zone);
786 static void forward_callback(isc_task_t *task, isc_event_t *event);
787 static void zone_saveunique(dns_zone_t *zone, const char *path,
788 			    const char *templat);
789 static void zone_maintenance(dns_zone_t *zone);
790 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
791 static void dump_done(void *arg, isc_result_t result);
792 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
793 				     isc_uint16_t keyid, isc_boolean_t delete);
794 static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
795 				dns_dbnode_t *node, dns_name_t *name,
796 				dns_diff_t *diff);
797 static void zone_rekey(dns_zone_t *zone);
798 static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db);
799 static void setrl(isc_ratelimiter_t *rl, unsigned int *rate,
800 		  unsigned int value);
801 
802 #define ENTER zone_debuglog(zone, me, 1, "enter")
803 
804 static const unsigned int dbargc_default = 1;
805 static const char *dbargv_default[] = { "rbt" };
806 
807 #define DNS_ZONE_JITTER_ADD(a, b, c) \
808 	do { \
809 		isc_interval_t _i; \
810 		isc_uint32_t _j; \
811 		_j = isc_random_jitter((b), (b)/4); \
812 		isc_interval_set(&_i, _j, 0); \
813 		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
814 			dns_zone_log(zone, ISC_LOG_WARNING, \
815 				     "epoch approaching: upgrade required: " \
816 				     "now + %s failed", #b); \
817 			isc_interval_set(&_i, _j/2, 0); \
818 			(void)isc_time_add((a), &_i, (c)); \
819 		} \
820 	} while (/*CONSTCOND*/0)
821 
822 #define DNS_ZONE_TIME_ADD(a, b, c) \
823 	do { \
824 		isc_interval_t _i; \
825 		isc_interval_set(&_i, (b), 0); \
826 		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
827 			dns_zone_log(zone, ISC_LOG_WARNING, \
828 				     "epoch approaching: upgrade required: " \
829 				     "now + %s failed", #b); \
830 			isc_interval_set(&_i, (b)/2, 0); \
831 			(void)isc_time_add((a), &_i, (c)); \
832 		} \
833 	} while (/*CONSTCOND*/0)
834 
835 typedef struct nsec3param nsec3param_t;
836 struct nsec3param {
837 	unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
838 	unsigned int length;
839 	isc_boolean_t nsec;
840 	isc_boolean_t replace;
841 	ISC_LINK(nsec3param_t)	link;
842 };
843 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t;
844 struct np3event {
845 	isc_event_t event;
846 	nsec3param_t params;
847 };
848 
849 /*%
850  * Increment resolver-related statistics counters.  Zone must be locked.
851  */
852 static inline void
inc_stats(dns_zone_t * zone,isc_statscounter_t counter)853 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
854 	if (zone->stats != NULL)
855 		isc_stats_increment(zone->stats, counter);
856 }
857 
858 /***
859  ***	Public functions.
860  ***/
861 
862 isc_result_t
dns_zone_create(dns_zone_t ** zonep,isc_mem_t * mctx)863 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
864 	isc_result_t result;
865 	dns_zone_t *zone;
866 	isc_time_t now;
867 
868 	REQUIRE(zonep != NULL && *zonep == NULL);
869 	REQUIRE(mctx != NULL);
870 
871 	TIME_NOW(&now);
872 	zone = isc_mem_get(mctx, sizeof(*zone));
873 	if (zone == NULL)
874 		return (ISC_R_NOMEMORY);
875 
876 	zone->mctx = NULL;
877 	isc_mem_attach(mctx, &zone->mctx);
878 
879 	result = isc_mutex_init(&zone->lock);
880 	if (result != ISC_R_SUCCESS)
881 		goto free_zone;
882 
883 	result = ZONEDB_INITLOCK(&zone->dblock);
884 	if (result != ISC_R_SUCCESS)
885 		goto free_mutex;
886 
887 	/* XXX MPA check that all elements are initialised */
888 #ifdef DNS_ZONE_CHECKLOCK
889 	zone->locked = ISC_FALSE;
890 #endif
891 	zone->db = NULL;
892 	zone->zmgr = NULL;
893 	ISC_LINK_INIT(zone, link);
894 	result = isc_refcount_init(&zone->erefs, 1);	/* Implicit attach. */
895 	if (result != ISC_R_SUCCESS)
896 		goto free_dblock;
897 	zone->irefs = 0;
898 	dns_name_init(&zone->origin, NULL);
899 	zone->strnamerd = NULL;
900 	zone->strname = NULL;
901 	zone->strrdclass = NULL;
902 	zone->strviewname = NULL;
903 	zone->masterfile = NULL;
904 	ISC_LIST_INIT(zone->includes);
905 	ISC_LIST_INIT(zone->newincludes);
906 	zone->nincludes = 0;
907 	zone->masterformat = dns_masterformat_none;
908 	zone->keydirectory = NULL;
909 	zone->journalsize = -1;
910 	zone->journal = NULL;
911 	zone->rdclass = dns_rdataclass_none;
912 	zone->type = dns_zone_none;
913 	zone->flags = 0;
914 	zone->options = 0;
915 	zone->keyopts = 0;
916 	zone->db_argc = 0;
917 	zone->db_argv = NULL;
918 	isc_time_settoepoch(&zone->expiretime);
919 	isc_time_settoepoch(&zone->refreshtime);
920 	isc_time_settoepoch(&zone->dumptime);
921 	isc_time_settoepoch(&zone->loadtime);
922 	zone->notifytime = now;
923 	isc_time_settoepoch(&zone->resigntime);
924 	isc_time_settoepoch(&zone->keywarntime);
925 	isc_time_settoepoch(&zone->signingtime);
926 	isc_time_settoepoch(&zone->nsec3chaintime);
927 	isc_time_settoepoch(&zone->refreshkeytime);
928 	zone->refreshkeyinterval = 0;
929 	zone->refreshkeycount = 0;
930 	zone->refresh = DNS_ZONE_DEFAULTREFRESH;
931 	zone->retry = DNS_ZONE_DEFAULTRETRY;
932 	zone->expire = 0;
933 	zone->minimum = 0;
934 	zone->maxrefresh = DNS_ZONE_MAXREFRESH;
935 	zone->minrefresh = DNS_ZONE_MINREFRESH;
936 	zone->maxretry = DNS_ZONE_MAXRETRY;
937 	zone->minretry = DNS_ZONE_MINRETRY;
938 	zone->masters = NULL;
939 	zone->masterdscps = NULL;
940 	zone->masterkeynames = NULL;
941 	zone->mastersok = NULL;
942 	zone->masterscnt = 0;
943 	zone->curmaster = 0;
944 	zone->maxttl = 0;
945 	zone->notify = NULL;
946 	zone->notifykeynames = NULL;
947 	zone->notifydscp = NULL;
948 	zone->notifytype = dns_notifytype_yes;
949 	zone->notifycnt = 0;
950 	zone->task = NULL;
951 	zone->loadtask = NULL;
952 	zone->update_acl = NULL;
953 	zone->forward_acl = NULL;
954 	zone->notify_acl = NULL;
955 	zone->query_acl = NULL;
956 	zone->queryon_acl = NULL;
957 	zone->xfr_acl = NULL;
958 	zone->update_disabled = ISC_FALSE;
959 	zone->zero_no_soa_ttl = ISC_TRUE;
960 	zone->check_names = dns_severity_ignore;
961 	zone->request = NULL;
962 	zone->lctx = NULL;
963 	zone->readio = NULL;
964 	zone->dctx = NULL;
965 	zone->writeio = NULL;
966 	zone->timer = NULL;
967 	zone->idlein = DNS_DEFAULT_IDLEIN;
968 	zone->idleout = DNS_DEFAULT_IDLEOUT;
969 	zone->log_key_expired_timer = 0;
970 	ISC_LIST_INIT(zone->notifies);
971 	isc_sockaddr_any(&zone->notifysrc4);
972 	isc_sockaddr_any6(&zone->notifysrc6);
973 	isc_sockaddr_any(&zone->xfrsource4);
974 	isc_sockaddr_any6(&zone->xfrsource6);
975 	isc_sockaddr_any(&zone->altxfrsource4);
976 	isc_sockaddr_any6(&zone->altxfrsource6);
977 	zone->notifysrc4dscp = -1;
978 	zone->notifysrc6dscp = -1;
979 	zone->xfrsource4dscp = -1;
980 	zone->xfrsource6dscp = -1;
981 	zone->altxfrsource4dscp = -1;
982 	zone->altxfrsource6dscp = -1;
983 	zone->xfr = NULL;
984 	zone->tsigkey = NULL;
985 	zone->maxxfrin = MAX_XFER_TIME;
986 	zone->maxxfrout = MAX_XFER_TIME;
987 	zone->ssutable = NULL;
988 	zone->sigvalidityinterval = 30 * 24 * 3600;
989 	zone->sigresigninginterval = 7 * 24 * 3600;
990 	zone->view = NULL;
991 	zone->acache = NULL;
992 	zone->checkmx = NULL;
993 	zone->checksrv = NULL;
994 	zone->checkns = NULL;
995 	ISC_LINK_INIT(zone, statelink);
996 	zone->statelist = NULL;
997 	zone->stats = NULL;
998 	zone->requeststats_on = ISC_FALSE;
999 	zone->statlevel = dns_zonestat_none;
1000 	zone->requeststats = NULL;
1001 	zone->rcvquerystats = NULL;
1002 	zone->notifydelay = 5;
1003 	zone->isself = NULL;
1004 	zone->isselfarg = NULL;
1005 	ISC_LIST_INIT(zone->signing);
1006 	ISC_LIST_INIT(zone->nsec3chain);
1007 	zone->signatures = 10;
1008 	zone->nodes = 100;
1009 	zone->privatetype = (dns_rdatatype_t)0xffffU;
1010 	zone->added = ISC_FALSE;
1011 	zone->rpzs = NULL;
1012 	zone->rpz_num = DNS_RPZ_INVALID_NUM;
1013 	ISC_LIST_INIT(zone->forwards);
1014 	zone->raw = NULL;
1015 	zone->secure = NULL;
1016 	zone->sourceserial = 0;
1017 	zone->sourceserialset = ISC_FALSE;
1018 
1019 	zone->magic = ZONE_MAGIC;
1020 
1021 	/* Must be after magic is set. */
1022 	result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
1023 	if (result != ISC_R_SUCCESS)
1024 		goto free_erefs;
1025 
1026 	ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
1027 		       DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
1028 		       NULL, NULL);
1029 	*zonep = zone;
1030 	return (ISC_R_SUCCESS);
1031 
1032  free_erefs:
1033 	isc_refcount_decrement(&zone->erefs, NULL);
1034 	isc_refcount_destroy(&zone->erefs);
1035 
1036  free_dblock:
1037 	ZONEDB_DESTROYLOCK(&zone->dblock);
1038 
1039  free_mutex:
1040 	DESTROYLOCK(&zone->lock);
1041 
1042  free_zone:
1043 	isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
1044 	return (result);
1045 }
1046 
1047 /*
1048  * Free a zone.  Because we require that there be no more
1049  * outstanding events or references, no locking is necessary.
1050  */
1051 static void
zone_free(dns_zone_t * zone)1052 zone_free(dns_zone_t *zone) {
1053 	isc_mem_t *mctx = NULL;
1054 	dns_signing_t *signing;
1055 	dns_nsec3chain_t *nsec3chain;
1056 	dns_include_t *include;
1057 
1058 	REQUIRE(DNS_ZONE_VALID(zone));
1059 	REQUIRE(isc_refcount_current(&zone->erefs) == 0);
1060 	REQUIRE(zone->irefs == 0);
1061 	REQUIRE(!LOCKED_ZONE(zone));
1062 	REQUIRE(zone->timer == NULL);
1063 	REQUIRE(zone->zmgr == NULL);
1064 
1065 	/*
1066 	 * Managed objects.  Order is important.
1067 	 */
1068 	if (zone->request != NULL)
1069 		dns_request_destroy(&zone->request); /* XXXMPA */
1070 	INSIST(zone->readio == NULL);
1071 	INSIST(zone->statelist == NULL);
1072 	INSIST(zone->writeio == NULL);
1073 
1074 	if (zone->task != NULL)
1075 		isc_task_detach(&zone->task);
1076 	if (zone->loadtask != NULL)
1077 		isc_task_detach(&zone->loadtask);
1078 
1079 	/* Unmanaged objects */
1080 	for (signing = ISC_LIST_HEAD(zone->signing);
1081 	     signing != NULL;
1082 	     signing = ISC_LIST_HEAD(zone->signing)) {
1083 		ISC_LIST_UNLINK(zone->signing, signing, link);
1084 		dns_db_detach(&signing->db);
1085 		dns_dbiterator_destroy(&signing->dbiterator);
1086 		isc_mem_put(zone->mctx, signing, sizeof *signing);
1087 	}
1088 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
1089 	     nsec3chain != NULL;
1090 	     nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
1091 		ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
1092 		dns_db_detach(&nsec3chain->db);
1093 		dns_dbiterator_destroy(&nsec3chain->dbiterator);
1094 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
1095 	}
1096 	for (include = ISC_LIST_HEAD(zone->includes);
1097 	     include != NULL;
1098 	     include = ISC_LIST_HEAD(zone->includes)) {
1099 		ISC_LIST_UNLINK(zone->includes, include, link);
1100 		isc_mem_free(zone->mctx, include->name);
1101 		isc_mem_put(zone->mctx, include, sizeof *include);
1102 	}
1103 	for (include = ISC_LIST_HEAD(zone->newincludes);
1104 	     include != NULL;
1105 	     include = ISC_LIST_HEAD(zone->newincludes)) {
1106 		ISC_LIST_UNLINK(zone->newincludes, include, link);
1107 		isc_mem_free(zone->mctx, include->name);
1108 		isc_mem_put(zone->mctx, include, sizeof *include);
1109 	}
1110 	if (zone->masterfile != NULL)
1111 		isc_mem_free(zone->mctx, zone->masterfile);
1112 	zone->masterfile = NULL;
1113 	if (zone->keydirectory != NULL)
1114 		isc_mem_free(zone->mctx, zone->keydirectory);
1115 	zone->keydirectory = NULL;
1116 	zone->journalsize = -1;
1117 	if (zone->journal != NULL)
1118 		isc_mem_free(zone->mctx, zone->journal);
1119 	zone->journal = NULL;
1120 	if (zone->stats != NULL)
1121 		isc_stats_detach(&zone->stats);
1122 	if (zone->requeststats != NULL)
1123 		isc_stats_detach(&zone->requeststats);
1124 	if (zone->rcvquerystats != NULL)
1125 		dns_stats_detach(&zone->rcvquerystats);
1126 	if (zone->db != NULL)
1127 		zone_detachdb(zone);
1128 	if (zone->acache != NULL)
1129 		dns_acache_detach(&zone->acache);
1130 	if (zone->rpzs != NULL) {
1131 		REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones);
1132 		dns_rpz_detach_rpzs(&zone->rpzs);
1133 		zone->rpz_num = DNS_RPZ_INVALID_NUM;
1134 	}
1135 	zone_freedbargs(zone);
1136 	RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
1137 		      == ISC_R_SUCCESS);
1138 	RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
1139 		      == ISC_R_SUCCESS);
1140 	zone->check_names = dns_severity_ignore;
1141 	if (zone->update_acl != NULL)
1142 		dns_acl_detach(&zone->update_acl);
1143 	if (zone->forward_acl != NULL)
1144 		dns_acl_detach(&zone->forward_acl);
1145 	if (zone->notify_acl != NULL)
1146 		dns_acl_detach(&zone->notify_acl);
1147 	if (zone->query_acl != NULL)
1148 		dns_acl_detach(&zone->query_acl);
1149 	if (zone->queryon_acl != NULL)
1150 		dns_acl_detach(&zone->queryon_acl);
1151 	if (zone->xfr_acl != NULL)
1152 		dns_acl_detach(&zone->xfr_acl);
1153 	if (dns_name_dynamic(&zone->origin))
1154 		dns_name_free(&zone->origin, zone->mctx);
1155 	if (zone->strnamerd != NULL)
1156 		isc_mem_free(zone->mctx, zone->strnamerd);
1157 	if (zone->strname != NULL)
1158 		isc_mem_free(zone->mctx, zone->strname);
1159 	if (zone->strrdclass != NULL)
1160 		isc_mem_free(zone->mctx, zone->strrdclass);
1161 	if (zone->strviewname != NULL)
1162 		isc_mem_free(zone->mctx, zone->strviewname);
1163 	if (zone->ssutable != NULL)
1164 		dns_ssutable_detach(&zone->ssutable);
1165 
1166 	/* last stuff */
1167 	ZONEDB_DESTROYLOCK(&zone->dblock);
1168 	DESTROYLOCK(&zone->lock);
1169 	isc_refcount_destroy(&zone->erefs);
1170 	zone->magic = 0;
1171 	mctx = zone->mctx;
1172 	isc_mem_put(mctx, zone, sizeof(*zone));
1173 	isc_mem_detach(&mctx);
1174 }
1175 
1176 /*
1177  * Returns ISC_TRUE iff this the signed side of an inline-signing zone.
1178  * Caller should hold zone lock.
1179  */
1180 static inline isc_boolean_t
inline_secure(dns_zone_t * zone)1181 inline_secure(dns_zone_t *zone) {
1182 	REQUIRE(DNS_ZONE_VALID(zone));
1183 	if (zone->raw != NULL)
1184 		return (ISC_TRUE);
1185 	return (ISC_FALSE);
1186 }
1187 
1188 /*
1189  * Returns ISC_TRUE iff this the unsigned side of an inline-signing zone
1190  * Caller should hold zone lock.
1191  */
1192 static inline isc_boolean_t
inline_raw(dns_zone_t * zone)1193 inline_raw(dns_zone_t *zone) {
1194 	REQUIRE(DNS_ZONE_VALID(zone));
1195 	if (zone->secure != NULL)
1196 		return (ISC_TRUE);
1197 	return (ISC_FALSE);
1198 }
1199 
1200 /*
1201  *	Single shot.
1202  */
1203 void
dns_zone_setclass(dns_zone_t * zone,dns_rdataclass_t rdclass)1204 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
1205 	char namebuf[1024];
1206 
1207 	REQUIRE(DNS_ZONE_VALID(zone));
1208 	REQUIRE(rdclass != dns_rdataclass_none);
1209 
1210 	/*
1211 	 * Test and set.
1212 	 */
1213 	LOCK_ZONE(zone);
1214 	INSIST(zone != zone->raw);
1215 	REQUIRE(zone->rdclass == dns_rdataclass_none ||
1216 		zone->rdclass == rdclass);
1217 	zone->rdclass = rdclass;
1218 
1219 	if (zone->strnamerd != NULL)
1220 		isc_mem_free(zone->mctx, zone->strnamerd);
1221 	if (zone->strrdclass != NULL)
1222 		isc_mem_free(zone->mctx, zone->strrdclass);
1223 
1224 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1225 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1226 	zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
1227 	zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
1228 
1229 	if (inline_secure(zone))
1230 		dns_zone_setclass(zone->raw, rdclass);
1231 	UNLOCK_ZONE(zone);
1232 }
1233 
1234 dns_rdataclass_t
dns_zone_getclass(dns_zone_t * zone)1235 dns_zone_getclass(dns_zone_t *zone) {
1236 	REQUIRE(DNS_ZONE_VALID(zone));
1237 
1238 	return (zone->rdclass);
1239 }
1240 
1241 void
dns_zone_setnotifytype(dns_zone_t * zone,dns_notifytype_t notifytype)1242 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
1243 	REQUIRE(DNS_ZONE_VALID(zone));
1244 
1245 	LOCK_ZONE(zone);
1246 	zone->notifytype = notifytype;
1247 	UNLOCK_ZONE(zone);
1248 }
1249 
1250 isc_result_t
dns_zone_getserial2(dns_zone_t * zone,isc_uint32_t * serialp)1251 dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
1252 	isc_result_t result;
1253 	unsigned int soacount;
1254 
1255 	REQUIRE(DNS_ZONE_VALID(zone));
1256 	REQUIRE(serialp != NULL);
1257 
1258 	LOCK_ZONE(zone);
1259 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1260 	if (zone->db != NULL) {
1261 		result = zone_get_from_db(zone, zone->db, NULL, &soacount,
1262 					  serialp, NULL, NULL, NULL, NULL,
1263 					  NULL);
1264 		if (result == ISC_R_SUCCESS && soacount == 0)
1265 			result = ISC_R_FAILURE;
1266 	} else
1267 		result = DNS_R_NOTLOADED;
1268 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1269 	UNLOCK_ZONE(zone);
1270 
1271 	return (result);
1272 }
1273 
1274 isc_uint32_t
dns_zone_getserial(dns_zone_t * zone)1275 dns_zone_getserial(dns_zone_t *zone) {
1276 	isc_result_t result;
1277 	isc_uint32_t serial;
1278 
1279 	result = dns_zone_getserial2(zone, &serial);
1280 	if (result != ISC_R_SUCCESS)
1281 		serial = 0; /* XXX: not really correct, but no other choice */
1282 
1283 	return (serial);
1284 }
1285 
1286 /*
1287  *	Single shot.
1288  */
1289 void
dns_zone_settype(dns_zone_t * zone,dns_zonetype_t type)1290 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
1291 	char namebuf[1024];
1292 
1293 	REQUIRE(DNS_ZONE_VALID(zone));
1294 	REQUIRE(type != dns_zone_none);
1295 
1296 	/*
1297 	 * Test and set.
1298 	 */
1299 	LOCK_ZONE(zone);
1300 	REQUIRE(zone->type == dns_zone_none || zone->type == type);
1301 	zone->type = type;
1302 
1303 	if (zone->strnamerd != NULL)
1304 		isc_mem_free(zone->mctx, zone->strnamerd);
1305 
1306 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1307 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1308 	UNLOCK_ZONE(zone);
1309 }
1310 
1311 static void
zone_freedbargs(dns_zone_t * zone)1312 zone_freedbargs(dns_zone_t *zone) {
1313 	unsigned int i;
1314 
1315 	/* Free the old database argument list. */
1316 	if (zone->db_argv != NULL) {
1317 		for (i = 0; i < zone->db_argc; i++)
1318 			isc_mem_free(zone->mctx, zone->db_argv[i]);
1319 		isc_mem_put(zone->mctx, zone->db_argv,
1320 			    zone->db_argc * sizeof(*zone->db_argv));
1321 	}
1322 	zone->db_argc = 0;
1323 	zone->db_argv = NULL;
1324 }
1325 
1326 isc_result_t
dns_zone_getdbtype(dns_zone_t * zone,char *** argv,isc_mem_t * mctx)1327 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1328 	size_t size = 0;
1329 	unsigned int i;
1330 	isc_result_t result = ISC_R_SUCCESS;
1331 	void *mem;
1332 	char **tmp, *tmp2;
1333 
1334 	REQUIRE(DNS_ZONE_VALID(zone));
1335 	REQUIRE(argv != NULL && *argv == NULL);
1336 
1337 	LOCK_ZONE(zone);
1338 	size = (zone->db_argc + 1) * sizeof(char *);
1339 	for (i = 0; i < zone->db_argc; i++)
1340 		size += strlen(zone->db_argv[i]) + 1;
1341 	mem = isc_mem_allocate(mctx, size);
1342 	if (mem != NULL) {
1343 		tmp = mem;
1344 		tmp2 = mem;
1345 		tmp2 += (zone->db_argc + 1) * sizeof(char *);
1346 		for (i = 0; i < zone->db_argc; i++) {
1347 			*tmp++ = tmp2;
1348 			strcpy(tmp2, zone->db_argv[i]);
1349 			tmp2 += strlen(tmp2) + 1;
1350 		}
1351 		*tmp = NULL;
1352 	} else
1353 		result = ISC_R_NOMEMORY;
1354 	UNLOCK_ZONE(zone);
1355 	*argv = mem;
1356 	return (result);
1357 }
1358 
1359 isc_result_t
dns_zone_setdbtype(dns_zone_t * zone,unsigned int dbargc,const char * const * dbargv)1360 dns_zone_setdbtype(dns_zone_t *zone,
1361 		   unsigned int dbargc, const char * const *dbargv) {
1362 	isc_result_t result = ISC_R_SUCCESS;
1363 	char **new = NULL;
1364 	unsigned int i;
1365 
1366 	REQUIRE(DNS_ZONE_VALID(zone));
1367 	REQUIRE(dbargc >= 1);
1368 	REQUIRE(dbargv != NULL);
1369 
1370 	LOCK_ZONE(zone);
1371 
1372 	/* Set up a new database argument list. */
1373 	new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
1374 	if (new == NULL)
1375 		goto nomem;
1376 	for (i = 0; i < dbargc; i++)
1377 		new[i] = NULL;
1378 	for (i = 0; i < dbargc; i++) {
1379 		new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1380 		if (new[i] == NULL)
1381 			goto nomem;
1382 	}
1383 
1384 	/* Free the old list. */
1385 	zone_freedbargs(zone);
1386 
1387 	zone->db_argc = dbargc;
1388 	zone->db_argv = new;
1389 	result = ISC_R_SUCCESS;
1390 	goto unlock;
1391 
1392  nomem:
1393 	if (new != NULL) {
1394 		for (i = 0; i < dbargc; i++)
1395 			if (new[i] != NULL)
1396 				isc_mem_free(zone->mctx, new[i]);
1397 		isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
1398 	}
1399 	result = ISC_R_NOMEMORY;
1400 
1401  unlock:
1402 	UNLOCK_ZONE(zone);
1403 	return (result);
1404 }
1405 
1406 void
dns_zone_setview(dns_zone_t * zone,dns_view_t * view)1407 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1408 	char namebuf[1024];
1409 	REQUIRE(DNS_ZONE_VALID(zone));
1410 
1411 	LOCK_ZONE(zone);
1412 	INSIST(zone != zone->raw);
1413 	if (zone->view != NULL)
1414 		dns_view_weakdetach(&zone->view);
1415 	dns_view_weakattach(view, &zone->view);
1416 
1417 	if (zone->strviewname != NULL)
1418 		isc_mem_free(zone->mctx, zone->strviewname);
1419 	if (zone->strnamerd != NULL)
1420 		isc_mem_free(zone->mctx, zone->strnamerd);
1421 
1422 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1423 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1424 	zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1425 	zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1426 
1427 	if (inline_secure(zone))
1428 		dns_zone_setview(zone->raw, view);
1429 
1430 	UNLOCK_ZONE(zone);
1431 }
1432 
1433 dns_view_t *
dns_zone_getview(dns_zone_t * zone)1434 dns_zone_getview(dns_zone_t *zone) {
1435 	REQUIRE(DNS_ZONE_VALID(zone));
1436 
1437 	return (zone->view);
1438 }
1439 
1440 
1441 isc_result_t
dns_zone_setorigin(dns_zone_t * zone,const dns_name_t * origin)1442 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1443 	isc_result_t result;
1444 	char namebuf[1024];
1445 
1446 	REQUIRE(DNS_ZONE_VALID(zone));
1447 	REQUIRE(origin != NULL);
1448 
1449 	LOCK_ZONE(zone);
1450 	INSIST(zone != zone->raw);
1451 	if (dns_name_dynamic(&zone->origin)) {
1452 		dns_name_free(&zone->origin, zone->mctx);
1453 		dns_name_init(&zone->origin, NULL);
1454 	}
1455 	result = dns_name_dup(origin, zone->mctx, &zone->origin);
1456 
1457 	if (zone->strnamerd != NULL)
1458 		isc_mem_free(zone->mctx, zone->strnamerd);
1459 	if (zone->strname != NULL)
1460 		isc_mem_free(zone->mctx, zone->strname);
1461 
1462 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1463 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1464 	zone_name_tostr(zone, namebuf, sizeof namebuf);
1465 	zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1466 
1467 	if (result == ISC_R_SUCCESS && inline_secure(zone))
1468 		result = dns_zone_setorigin(zone->raw, origin);
1469 	UNLOCK_ZONE(zone);
1470 	return (result);
1471 }
1472 
1473 void
dns_zone_setacache(dns_zone_t * zone,dns_acache_t * acache)1474 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
1475 	REQUIRE(DNS_ZONE_VALID(zone));
1476 	REQUIRE(acache != NULL);
1477 
1478 	LOCK_ZONE(zone);
1479 	if (zone->acache != NULL)
1480 		dns_acache_detach(&zone->acache);
1481 	dns_acache_attach(acache, &zone->acache);
1482 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1483 	if (zone->db != NULL) {
1484 		isc_result_t result;
1485 
1486 		/*
1487 		 * If the zone reuses an existing DB, the DB needs to be
1488 		 * set in the acache explicitly.  We can safely ignore the
1489 		 * case where the DB is already set.  If other error happens,
1490 		 * the acache will not work effectively.
1491 		 */
1492 		result = dns_acache_setdb(acache, zone->db);
1493 		if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
1494 			UNEXPECTED_ERROR(__FILE__, __LINE__,
1495 					 "dns_acache_setdb() failed: %s",
1496 					 isc_result_totext(result));
1497 		}
1498 	}
1499 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1500 	UNLOCK_ZONE(zone);
1501 }
1502 
1503 static isc_result_t
dns_zone_setstring(dns_zone_t * zone,char ** field,const char * value)1504 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1505 	char *copy;
1506 
1507 	if (value != NULL) {
1508 		copy = isc_mem_strdup(zone->mctx, value);
1509 		if (copy == NULL)
1510 			return (ISC_R_NOMEMORY);
1511 	} else {
1512 		copy = NULL;
1513 	}
1514 
1515 	if (*field != NULL)
1516 		isc_mem_free(zone->mctx, *field);
1517 
1518 	*field = copy;
1519 	return (ISC_R_SUCCESS);
1520 }
1521 
1522 isc_result_t
dns_zone_setfile(dns_zone_t * zone,const char * file)1523 dns_zone_setfile(dns_zone_t *zone, const char *file) {
1524 	return (dns_zone_setfile2(zone, file, dns_masterformat_text));
1525 }
1526 
1527 isc_result_t
dns_zone_setfile2(dns_zone_t * zone,const char * file,dns_masterformat_t format)1528 dns_zone_setfile2(dns_zone_t *zone, const char *file,
1529 		  dns_masterformat_t format) {
1530 	isc_result_t result = ISC_R_SUCCESS;
1531 
1532 	REQUIRE(DNS_ZONE_VALID(zone));
1533 
1534 	LOCK_ZONE(zone);
1535 	result = dns_zone_setstring(zone, &zone->masterfile, file);
1536 	if (result == ISC_R_SUCCESS) {
1537 		zone->masterformat = format;
1538 		result = default_journal(zone);
1539 	}
1540 	UNLOCK_ZONE(zone);
1541 
1542 	return (result);
1543 }
1544 
1545 const char *
dns_zone_getfile(dns_zone_t * zone)1546 dns_zone_getfile(dns_zone_t *zone) {
1547 	REQUIRE(DNS_ZONE_VALID(zone));
1548 
1549 	return (zone->masterfile);
1550 }
1551 
1552 dns_ttl_t
dns_zone_getmaxttl(dns_zone_t * zone)1553 dns_zone_getmaxttl(dns_zone_t *zone) {
1554 	REQUIRE(DNS_ZONE_VALID(zone));
1555 
1556 	return (zone->maxttl);
1557 }
1558 
1559 void
dns_zone_setmaxttl(dns_zone_t * zone,dns_ttl_t maxttl)1560 dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) {
1561 	REQUIRE(DNS_ZONE_VALID(zone));
1562 
1563 	LOCK_ZONE(zone);
1564 	if (maxttl != 0)
1565 		zone->options2 |= DNS_ZONEOPT2_CHECKTTL;
1566 	else
1567 		zone->options2 &= ~DNS_ZONEOPT2_CHECKTTL;
1568 	zone->maxttl = maxttl;
1569 	UNLOCK_ZONE(zone);
1570 
1571 	return;
1572 }
1573 
1574 static isc_result_t
default_journal(dns_zone_t * zone)1575 default_journal(dns_zone_t *zone) {
1576 	isc_result_t result;
1577 	char *journal;
1578 
1579 	REQUIRE(DNS_ZONE_VALID(zone));
1580 	REQUIRE(LOCKED_ZONE(zone));
1581 
1582 	if (zone->masterfile != NULL) {
1583 		/* Calculate string length including '\0'. */
1584 		int len = strlen(zone->masterfile) + sizeof(".jnl");
1585 		journal = isc_mem_allocate(zone->mctx, len);
1586 		if (journal == NULL)
1587 			return (ISC_R_NOMEMORY);
1588 		strcpy(journal, zone->masterfile);
1589 		strcat(journal, ".jnl");
1590 	} else {
1591 		journal = NULL;
1592 	}
1593 	result = dns_zone_setstring(zone, &zone->journal, journal);
1594 	if (journal != NULL)
1595 		isc_mem_free(zone->mctx, journal);
1596 	return (result);
1597 }
1598 
1599 isc_result_t
dns_zone_setjournal(dns_zone_t * zone,const char * journal)1600 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1601 	isc_result_t result = ISC_R_SUCCESS;
1602 
1603 	REQUIRE(DNS_ZONE_VALID(zone));
1604 
1605 	LOCK_ZONE(zone);
1606 	result = dns_zone_setstring(zone, &zone->journal, journal);
1607 	UNLOCK_ZONE(zone);
1608 
1609 	return (result);
1610 }
1611 
1612 char *
dns_zone_getjournal(dns_zone_t * zone)1613 dns_zone_getjournal(dns_zone_t *zone) {
1614 	REQUIRE(DNS_ZONE_VALID(zone));
1615 
1616 	return (zone->journal);
1617 }
1618 
1619 /*
1620  * Return true iff the zone is "dynamic", in the sense that the zone's
1621  * master file (if any) is written by the server, rather than being
1622  * updated manually and read by the server.
1623  *
1624  * This is true for slave zones, stub zones, key zones, and zones that
1625  * allow dynamic updates either by having an update policy ("ssutable")
1626  * or an "allow-update" ACL with a value other than exactly "{ none; }".
1627  */
1628 isc_boolean_t
dns_zone_isdynamic(dns_zone_t * zone,isc_boolean_t ignore_freeze)1629 dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze) {
1630 	REQUIRE(DNS_ZONE_VALID(zone));
1631 
1632 	if (zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
1633 	    zone->type == dns_zone_key ||
1634 	    (zone->type == dns_zone_redirect && zone->masters != NULL))
1635 		return (ISC_TRUE);
1636 
1637 	/* If !ignore_freeze, we need check whether updates are disabled.  */
1638 	if (zone->type == dns_zone_master &&
1639 	    (!zone->update_disabled || ignore_freeze) &&
1640 	    ((zone->ssutable != NULL) ||
1641 	     (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl))))
1642 		return (ISC_TRUE);
1643 
1644 	return (ISC_FALSE);
1645 
1646 }
1647 
1648 /*
1649  * Set the response policy index and information for a zone.
1650  */
1651 isc_result_t
dns_zone_rpz_enable(dns_zone_t * zone,dns_rpz_zones_t * rpzs,dns_rpz_num_t rpz_num)1652 dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs,
1653 		    dns_rpz_num_t rpz_num)
1654 {
1655 	/*
1656 	 * Only RBTDB zones can be used for response policy zones,
1657 	 * because only they have the code to load the create the summary data.
1658 	 * Only zones that are loaded instead of mmap()ed create the
1659 	 * summary data and so can be policy zones.
1660 	 */
1661 	if (strcmp(zone->db_argv[0], "rbt") != 0 &&
1662 	    strcmp(zone->db_argv[0], "rbt64") != 0)
1663 		return (ISC_R_NOTIMPLEMENTED);
1664 
1665 	/*
1666 	 * This must happen only once or be redundant.
1667 	 */
1668 	LOCK_ZONE(zone);
1669 	if (zone->rpzs != NULL) {
1670 		REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num);
1671 	} else {
1672 		REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM);
1673 		dns_rpz_attach_rpzs(rpzs, &zone->rpzs);
1674 		zone->rpz_num = rpz_num;
1675 	}
1676 	rpzs->defined |= DNS_RPZ_ZBIT(rpz_num);
1677 	UNLOCK_ZONE(zone);
1678 
1679 	return (ISC_R_SUCCESS);
1680 }
1681 
1682 dns_rpz_num_t
dns_zone_get_rpz_num(dns_zone_t * zone)1683 dns_zone_get_rpz_num(dns_zone_t *zone) {
1684 	return (zone->rpz_num);
1685 }
1686 
1687 /*
1688  * If a zone is a response policy zone, mark its new database.
1689  */
1690 void
dns_zone_rpz_enable_db(dns_zone_t * zone,dns_db_t * db)1691 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) {
1692 	if (zone->rpz_num != DNS_RPZ_INVALID_NUM) {
1693 		REQUIRE(zone->rpzs != NULL);
1694 		dns_db_rpz_attach(db, zone->rpzs, zone->rpz_num);
1695 	}
1696 }
1697 
1698 static isc_boolean_t
zone_touched(dns_zone_t * zone)1699 zone_touched(dns_zone_t *zone) {
1700 	isc_result_t result;
1701 	isc_time_t modtime;
1702 	dns_include_t *include;
1703 
1704 	REQUIRE(DNS_ZONE_VALID(zone));
1705 
1706 	result = isc_file_getmodtime(zone->masterfile, &modtime);
1707 	if (result != ISC_R_SUCCESS ||
1708 	    isc_time_compare(&modtime, &zone->loadtime) > 0)
1709 	{
1710 		zone->loadtime = modtime;
1711 		return (ISC_TRUE);
1712 	}
1713 
1714 	for (include = ISC_LIST_HEAD(zone->includes);
1715 	     include != NULL;
1716 	     include = ISC_LIST_NEXT(include, link))
1717 	{
1718 		result = isc_file_getmodtime(include->name, &modtime);
1719 		if (result != ISC_R_SUCCESS ||
1720 		    isc_time_compare(&modtime, &include->filetime) > 0)
1721 			return (ISC_TRUE);
1722 	}
1723 
1724 
1725 	return (ISC_FALSE);
1726 }
1727 
1728 static isc_result_t
zone_load(dns_zone_t * zone,unsigned int flags,isc_boolean_t locked)1729 zone_load(dns_zone_t *zone, unsigned int flags, isc_boolean_t locked) {
1730 	isc_result_t result;
1731 	isc_time_t now;
1732 	isc_time_t loadtime;
1733 	dns_db_t *db = NULL;
1734 	isc_boolean_t rbt, hasraw;
1735 
1736 	REQUIRE(DNS_ZONE_VALID(zone));
1737 
1738 	if (!locked)
1739 		LOCK_ZONE(zone);
1740 
1741 	INSIST(zone != zone->raw);
1742 	hasraw = inline_secure(zone);
1743 	if (hasraw) {
1744 		result = zone_load(zone->raw, flags, ISC_FALSE);
1745 		if (result != ISC_R_SUCCESS) {
1746 			if (!locked)
1747 				UNLOCK_ZONE(zone);
1748 			return(result);
1749 		}
1750 		LOCK_ZONE(zone->raw);
1751 	}
1752 
1753 	TIME_NOW(&now);
1754 
1755 	INSIST(zone->type != dns_zone_none);
1756 
1757 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1758 		if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1759 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1760 		result = DNS_R_CONTINUE;
1761 		goto cleanup;
1762 	}
1763 
1764 	INSIST(zone->db_argc >= 1);
1765 
1766 	rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
1767 	      strcmp(zone->db_argv[0], "rbt64") == 0;
1768 
1769 	if (zone->db != NULL && zone->masterfile == NULL && rbt) {
1770 		/*
1771 		 * The zone has no master file configured.
1772 		 */
1773 		result = ISC_R_SUCCESS;
1774 		goto cleanup;
1775 	}
1776 
1777 	if (zone->db != NULL && dns_zone_isdynamic(zone, ISC_FALSE)) {
1778 		/*
1779 		 * This is a slave, stub, or dynamically updated
1780 		 * zone being reloaded.  Do nothing - the database
1781 		 * we already have is guaranteed to be up-to-date.
1782 		 */
1783 		if (zone->type == dns_zone_master)
1784 			result = DNS_R_DYNAMIC;
1785 		else
1786 			result = ISC_R_SUCCESS;
1787 		goto cleanup;
1788 	}
1789 
1790 	/*
1791 	 * Store the current time before the zone is loaded, so that if the
1792 	 * file changes between the time of the load and the time that
1793 	 * zone->loadtime is set, then the file will still be reloaded
1794 	 * the next time dns_zone_load is called.
1795 	 */
1796 	TIME_NOW(&loadtime);
1797 
1798 	/*
1799 	 * Don't do the load if the file that stores the zone is older
1800 	 * than the last time the zone was loaded.  If the zone has not
1801 	 * been loaded yet, zone->loadtime will be the epoch.
1802 	 */
1803 	if (zone->masterfile != NULL) {
1804 		/*
1805 		 * The file is already loaded.	If we are just doing a
1806 		 * "rndc reconfig", we are done.
1807 		 */
1808 		if (!isc_time_isepoch(&zone->loadtime) &&
1809 		    (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
1810 			result = ISC_R_SUCCESS;
1811 			goto cleanup;
1812 		}
1813 
1814 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1815 		    !zone_touched(zone))
1816 		{
1817 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
1818 				     "skipping load: master file "
1819 				     "older than last load");
1820 			result = DNS_R_UPTODATE;
1821 			goto cleanup;
1822 		}
1823 	}
1824 
1825 	/*
1826 	 * Built in zones (with the exception of empty zones) don't need
1827 	 * to be reloaded.
1828 	 */
1829 	if (zone->type == dns_zone_master &&
1830 	    strcmp(zone->db_argv[0], "_builtin") == 0 &&
1831 	    (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
1832 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1833 		result = ISC_R_SUCCESS;
1834 		goto cleanup;
1835 	}
1836 
1837 	/*
1838 	 * Zones associated with a DLZ don't need to be loaded either,
1839 	 * but we need to associate the database with the zone object.
1840 	 */
1841 	if (strcmp(zone->db_argv[0], "dlz") == 0) {
1842 		dns_dlzdb_t *dlzdb;
1843 		dns_dlzfindzone_t findzone;
1844 
1845 		for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched);
1846 		     dlzdb != NULL;
1847 		     dlzdb = ISC_LIST_NEXT(dlzdb, link))
1848 		{
1849 			INSIST(DNS_DLZ_VALID(dlzdb));
1850 			if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0)
1851 				break;
1852 		}
1853 
1854 		if (dlzdb == NULL) {
1855 			dns_zone_log(zone, ISC_LOG_ERROR,
1856 				     "DLZ %s does not exist or is set "
1857 				     "to 'search yes;'", zone->db_argv[1]);
1858 			result = ISC_R_NOTFOUND;
1859 			goto cleanup;
1860 		}
1861 
1862 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
1863 		/* ask SDLZ driver if the zone is supported */
1864 		findzone = dlzdb->implementation->methods->findzone;
1865 		result = (*findzone)(dlzdb->implementation->driverarg,
1866 				     dlzdb->dbdata, dlzdb->mctx,
1867 				     zone->view->rdclass, &zone->origin,
1868 				     NULL, NULL, &db);
1869 		if (result != ISC_R_NOTFOUND) {
1870 			if (zone->db != NULL)
1871 				zone_detachdb(zone);
1872 			zone_attachdb(zone, db);
1873 			dns_db_detach(&db);
1874 			result = ISC_R_SUCCESS;
1875 		}
1876 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
1877 
1878 		if (result == ISC_R_SUCCESS) {
1879 			if (dlzdb->configure_callback == NULL)
1880 				goto cleanup;
1881 
1882 			result = (*dlzdb->configure_callback)(zone->view,
1883 							      dlzdb, zone);
1884 			if (result != ISC_R_SUCCESS)
1885 				dns_zone_log(zone, ISC_LOG_ERROR,
1886 					     "DLZ configuration callback: %s",
1887 					     isc_result_totext(result));
1888 		}
1889 		goto cleanup;
1890 	}
1891 
1892 	if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
1893 	     (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
1894 	    rbt) {
1895 		if (zone->masterfile == NULL ||
1896 		    !isc_file_exists(zone->masterfile)) {
1897 			if (zone->masterfile != NULL) {
1898 				dns_zone_log(zone, ISC_LOG_DEBUG(1),
1899 					     "no master file");
1900 			}
1901 			zone->refreshtime = now;
1902 			if (zone->task != NULL)
1903 				zone_settimer(zone, &now);
1904 			result = ISC_R_SUCCESS;
1905 			goto cleanup;
1906 		}
1907 	}
1908 
1909 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1910 
1911 	result = dns_db_create(zone->mctx, zone->db_argv[0],
1912 			       &zone->origin, (zone->type == dns_zone_stub) ?
1913 			       dns_dbtype_stub : dns_dbtype_zone,
1914 			       zone->rdclass,
1915 			       zone->db_argc - 1, zone->db_argv + 1,
1916 			       &db);
1917 
1918 	if (result != ISC_R_SUCCESS) {
1919 		dns_zone_log(zone, ISC_LOG_ERROR,
1920 			     "loading zone: creating database: %s",
1921 			     isc_result_totext(result));
1922 		goto cleanup;
1923 	}
1924 	dns_db_settask(db, zone->task);
1925 
1926 	if (! dns_db_ispersistent(db)) {
1927 		if (zone->masterfile != NULL) {
1928 			result = zone_startload(db, zone, loadtime);
1929 		} else {
1930 			result = DNS_R_NOMASTERFILE;
1931 			if (zone->type == dns_zone_master ||
1932 			    (zone->type == dns_zone_redirect &&
1933 			     zone->masters == NULL)) {
1934 				dns_zone_log(zone, ISC_LOG_ERROR,
1935 					     "loading zone: "
1936 					     "no master file configured");
1937 				goto cleanup;
1938 			}
1939 			dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1940 				     "no master file configured: continuing");
1941 		}
1942 	}
1943 
1944 	if (result == DNS_R_CONTINUE) {
1945 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1946 		if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1947 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1948 		goto cleanup;
1949 	}
1950 
1951 	result = zone_postload(zone, db, loadtime, result);
1952 
1953  cleanup:
1954 	if (hasraw)
1955 		UNLOCK_ZONE(zone->raw);
1956 	if (!locked)
1957 		UNLOCK_ZONE(zone);
1958 	if (db != NULL)
1959 		dns_db_detach(&db);
1960 	return (result);
1961 }
1962 
1963 isc_result_t
dns_zone_load(dns_zone_t * zone)1964 dns_zone_load(dns_zone_t *zone) {
1965 	return (zone_load(zone, 0, ISC_FALSE));
1966 }
1967 
1968 isc_result_t
dns_zone_loadnew(dns_zone_t * zone)1969 dns_zone_loadnew(dns_zone_t *zone) {
1970 	return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT, ISC_FALSE));
1971 }
1972 
1973 static void
zone_asyncload(isc_task_t * task,isc_event_t * event)1974 zone_asyncload(isc_task_t *task, isc_event_t *event) {
1975 	dns_asyncload_t *asl = event->ev_arg;
1976 	dns_zone_t *zone = asl->zone;
1977 	isc_result_t result = ISC_R_SUCCESS;
1978 	isc_boolean_t load_pending;
1979 
1980 	UNUSED(task);
1981 
1982 	REQUIRE(DNS_ZONE_VALID(zone));
1983 
1984 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1985 		result = ISC_R_CANCELED;
1986 	isc_event_free(&event);
1987 
1988 	if (result == ISC_R_CANCELED)
1989 		goto cleanup;
1990 
1991 	/* Make sure load is still pending */
1992 	LOCK_ZONE(zone);
1993 	load_pending = ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING));
1994 
1995 	if (!load_pending) {
1996 		UNLOCK_ZONE(zone);
1997 		goto cleanup;
1998 	}
1999 
2000 	zone_load(zone, 0, ISC_TRUE);
2001 
2002 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
2003 	UNLOCK_ZONE(zone);
2004 
2005 	/* Inform the zone table we've finished loading */
2006 	if (asl->loaded != NULL)
2007 		(asl->loaded)(asl->loaded_arg, zone, task);
2008 
2009  cleanup:
2010 	isc_mem_put(zone->mctx, asl, sizeof (*asl));
2011 	dns_zone_idetach(&zone);
2012 }
2013 
2014 isc_result_t
dns_zone_asyncload(dns_zone_t * zone,dns_zt_zoneloaded_t done,void * arg)2015 dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) {
2016 	isc_event_t *e;
2017 	dns_asyncload_t *asl = NULL;
2018 	isc_result_t result = ISC_R_SUCCESS;
2019 
2020 	REQUIRE(DNS_ZONE_VALID(zone));
2021 
2022 	if (zone->zmgr == NULL)
2023 		return (ISC_R_FAILURE);
2024 
2025 	/* If we already have a load pending, stop now */
2026 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
2027 		return (ISC_R_ALREADYRUNNING);
2028 
2029 	asl = isc_mem_get(zone->mctx, sizeof (*asl));
2030 	if (asl == NULL)
2031 		CHECK(ISC_R_NOMEMORY);
2032 
2033 	asl->zone = NULL;
2034 	asl->loaded = done;
2035 	asl->loaded_arg = arg;
2036 
2037 	e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr,
2038 			       DNS_EVENT_ZONELOAD,
2039 			       zone_asyncload, asl,
2040 			       sizeof(isc_event_t));
2041 	if (e == NULL)
2042 		CHECK(ISC_R_NOMEMORY);
2043 
2044 	LOCK_ZONE(zone);
2045 	zone_iattach(zone, &asl->zone);
2046 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING);
2047 	isc_task_send(zone->loadtask, &e);
2048 	UNLOCK_ZONE(zone);
2049 
2050 	return (ISC_R_SUCCESS);
2051 
2052   failure:
2053 	if (asl != NULL)
2054 		isc_mem_put(zone->mctx, asl, sizeof (*asl));
2055 	return (result);
2056 }
2057 
2058 isc_boolean_t
dns__zone_loadpending(dns_zone_t * zone)2059 dns__zone_loadpending(dns_zone_t *zone) {
2060 	REQUIRE(DNS_ZONE_VALID(zone));
2061 
2062 	return (ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)));
2063 }
2064 
2065 isc_result_t
dns_zone_loadandthaw(dns_zone_t * zone)2066 dns_zone_loadandthaw(dns_zone_t *zone) {
2067 	isc_result_t result;
2068 
2069 	if (inline_raw(zone))
2070 		result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW,
2071 				   ISC_FALSE);
2072 	else
2073 		result = zone_load(zone, DNS_ZONELOADFLAG_THAW, ISC_FALSE);
2074 
2075 	switch (result) {
2076 	case DNS_R_CONTINUE:
2077 		/* Deferred thaw. */
2078 		break;
2079 	case DNS_R_UPTODATE:
2080 	case ISC_R_SUCCESS:
2081 	case DNS_R_SEENINCLUDE:
2082 		zone->update_disabled = ISC_FALSE;
2083 		break;
2084 	case DNS_R_NOMASTERFILE:
2085 		zone->update_disabled = ISC_FALSE;
2086 		break;
2087 	default:
2088 		/* Error, remain in disabled state. */
2089 		break;
2090 	}
2091 	return (result);
2092 }
2093 
2094 static unsigned int
get_master_options(dns_zone_t * zone)2095 get_master_options(dns_zone_t *zone) {
2096 	unsigned int options;
2097 
2098 	options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN;
2099 	if (zone->type == dns_zone_slave ||
2100 	    (zone->type == dns_zone_redirect && zone->masters == NULL))
2101 		options |= DNS_MASTER_SLAVE;
2102 	if (zone->type == dns_zone_key)
2103 		options |= DNS_MASTER_KEY;
2104 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
2105 		options |= DNS_MASTER_CHECKNS;
2106 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
2107 		options |= DNS_MASTER_FATALNS;
2108 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
2109 		options |= DNS_MASTER_CHECKNAMES;
2110 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
2111 		options |= DNS_MASTER_CHECKNAMESFAIL;
2112 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
2113 		options |= DNS_MASTER_CHECKMX;
2114 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
2115 		options |= DNS_MASTER_CHECKMXFAIL;
2116 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
2117 		options |= DNS_MASTER_CHECKWILDCARD;
2118 	if (DNS_ZONE_OPTION2(zone, DNS_ZONEOPT2_CHECKTTL))
2119 		options |= DNS_MASTER_CHECKTTL;
2120 	return (options);
2121 }
2122 
2123 static void
zone_registerinclude(const char * filename,void * arg)2124 zone_registerinclude(const char *filename, void *arg) {
2125 	isc_result_t result;
2126 	dns_zone_t *zone = (dns_zone_t *) arg;
2127 	dns_include_t *inc = NULL;
2128 
2129 	REQUIRE(DNS_ZONE_VALID(zone));
2130 
2131 	if (filename == NULL)
2132 		return;
2133 
2134 	/*
2135 	 * Suppress duplicates.
2136 	 */
2137 	for (inc = ISC_LIST_HEAD(zone->newincludes);
2138 	     inc != NULL;
2139 	     inc = ISC_LIST_NEXT(inc, link))
2140 		if (strcmp(filename, inc->name) == 0)
2141 			return;
2142 
2143 	inc = isc_mem_get(zone->mctx, sizeof(dns_include_t));
2144 	if (inc == NULL)
2145 		return;
2146 	inc->name = isc_mem_strdup(zone->mctx, filename);
2147 	if (inc->name == NULL) {
2148 		isc_mem_put(zone->mctx, inc, sizeof(dns_include_t));
2149 		return;
2150 	}
2151 	ISC_LINK_INIT(inc, link);
2152 
2153 	result = isc_file_getmodtime(filename, &inc->filetime);
2154 	if (result != ISC_R_SUCCESS)
2155 		isc_time_settoepoch(&inc->filetime);
2156 
2157 	ISC_LIST_APPEND(zone->newincludes, inc, link);
2158 }
2159 
2160 static void
zone_gotreadhandle(isc_task_t * task,isc_event_t * event)2161 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
2162 	dns_load_t *load = event->ev_arg;
2163 	isc_result_t result = ISC_R_SUCCESS;
2164 	unsigned int options;
2165 
2166 	REQUIRE(DNS_LOAD_VALID(load));
2167 
2168 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
2169 		result = ISC_R_CANCELED;
2170 	isc_event_free(&event);
2171 	if (result == ISC_R_CANCELED)
2172 		goto fail;
2173 
2174 	options = get_master_options(load->zone);
2175 
2176 	result = dns_master_loadfileinc5(load->zone->masterfile,
2177 					 dns_db_origin(load->db),
2178 					 dns_db_origin(load->db),
2179 					 load->zone->rdclass, options, 0,
2180 					 &load->callbacks, task,
2181 					 zone_loaddone, load,
2182 					 &load->zone->lctx,
2183 					 zone_registerinclude,
2184 					 load->zone, load->zone->mctx,
2185 					 load->zone->masterformat,
2186 					 load->zone->maxttl);
2187 	if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
2188 	    result != DNS_R_SEENINCLUDE)
2189 		goto fail;
2190 	return;
2191 
2192  fail:
2193 	zone_loaddone(load, result);
2194 }
2195 
2196 static void
get_raw_serial(dns_zone_t * raw,dns_masterrawheader_t * rawdata)2197 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
2198 	isc_result_t result;
2199 	unsigned int soacount;
2200 
2201 	LOCK(&raw->lock);
2202 	if (raw->db != NULL) {
2203 		result = zone_get_from_db(raw, raw->db, NULL, &soacount,
2204 					  &rawdata->sourceserial,
2205 					  NULL, NULL, NULL, NULL,
2206 					  NULL);
2207 		if (result == ISC_R_SUCCESS && soacount > 0U)
2208 			rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
2209 	}
2210 	UNLOCK(&raw->lock);
2211 }
2212 
2213 static void
zone_gotwritehandle(isc_task_t * task,isc_event_t * event)2214 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
2215 	const char me[] = "zone_gotwritehandle";
2216 	dns_zone_t *zone = event->ev_arg;
2217 	isc_result_t result = ISC_R_SUCCESS;
2218 	dns_dbversion_t *version = NULL;
2219 	dns_masterrawheader_t rawdata;
2220 
2221 	REQUIRE(DNS_ZONE_VALID(zone));
2222 	INSIST(task == zone->task);
2223 	ENTER;
2224 
2225 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
2226 		result = ISC_R_CANCELED;
2227 	isc_event_free(&event);
2228 	if (result == ISC_R_CANCELED)
2229 		goto fail;
2230 
2231 	LOCK_ZONE(zone);
2232 	INSIST(zone != zone->raw);
2233 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2234 	if (zone->db != NULL) {
2235 		const dns_master_style_t *output_style;
2236 
2237 		dns_db_currentversion(zone->db, &version);
2238 		dns_master_initrawheader(&rawdata);
2239 		if (inline_secure(zone))
2240 			get_raw_serial(zone->raw, &rawdata);
2241 		if (zone->type == dns_zone_key)
2242 			output_style = &dns_master_style_keyzone;
2243 		else
2244 			output_style = &dns_master_style_default;
2245 		result = dns_master_dumpinc3(zone->mctx, zone->db, version,
2246 					     output_style, zone->masterfile,
2247 					     zone->task, dump_done, zone,						     &zone->dctx, zone->masterformat,
2248 					     &rawdata);
2249 		dns_db_closeversion(zone->db, &version, ISC_FALSE);
2250 	} else
2251 		result = ISC_R_CANCELED;
2252 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2253 	UNLOCK_ZONE(zone);
2254 	if (result != DNS_R_CONTINUE)
2255 		goto fail;
2256 	return;
2257 
2258  fail:
2259 	dump_done(zone, result);
2260 }
2261 
2262 /*
2263  * Save the raw serial number for inline-signing zones.
2264  * (XXX: Other information from the header will be used
2265  * for other purposes in the future, but for now this is
2266  * all we're interested in.)
2267  */
2268 static void
zone_setrawdata(dns_zone_t * zone,dns_masterrawheader_t * header)2269 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
2270 	if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0)
2271 		return;
2272 
2273 	zone->sourceserial = header->sourceserial;
2274 	zone->sourceserialset = ISC_TRUE;
2275 }
2276 
2277 void
dns_zone_setrawdata(dns_zone_t * zone,dns_masterrawheader_t * header)2278 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
2279 	if (zone == NULL)
2280 		return;
2281 
2282 	LOCK_ZONE(zone);
2283 	zone_setrawdata(zone, header);
2284 	UNLOCK_ZONE(zone);
2285 }
2286 
2287 static isc_result_t
zone_startload(dns_db_t * db,dns_zone_t * zone,isc_time_t loadtime)2288 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
2289 	dns_load_t *load;
2290 	isc_result_t result;
2291 	isc_result_t tresult;
2292 	unsigned int options;
2293 
2294 	dns_zone_rpz_enable_db(zone, db);
2295 	options = get_master_options(zone);
2296 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
2297 		options |= DNS_MASTER_MANYERRORS;
2298 
2299 	if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) {
2300 		load = isc_mem_get(zone->mctx, sizeof(*load));
2301 		if (load == NULL)
2302 			return (ISC_R_NOMEMORY);
2303 
2304 		load->mctx = NULL;
2305 		load->zone = NULL;
2306 		load->db = NULL;
2307 		load->loadtime = loadtime;
2308 		load->magic = LOAD_MAGIC;
2309 
2310 		isc_mem_attach(zone->mctx, &load->mctx);
2311 		zone_iattach(zone, &load->zone);
2312 		dns_db_attach(db, &load->db);
2313 		dns_rdatacallbacks_init(&load->callbacks);
2314 		load->callbacks.rawdata = zone_setrawdata;
2315 		zone_iattach(zone, &load->callbacks.zone);
2316 		result = dns_db_beginload(db, &load->callbacks);
2317 		if (result != ISC_R_SUCCESS)
2318 			goto cleanup;
2319 		result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->loadtask,
2320 				       zone_gotreadhandle, load,
2321 				       &zone->readio);
2322 		if (result != ISC_R_SUCCESS) {
2323 			/*
2324 			 * We can't report multiple errors so ignore
2325 			 * the result of dns_db_endload().
2326 			 */
2327 			(void)dns_db_endload(load->db, &load->callbacks);
2328 			goto cleanup;
2329 		} else
2330 			result = DNS_R_CONTINUE;
2331 	} else {
2332 		dns_rdatacallbacks_t callbacks;
2333 
2334 		dns_rdatacallbacks_init(&callbacks);
2335 		callbacks.rawdata = zone_setrawdata;
2336 		zone_iattach(zone, &callbacks.zone);
2337 		result = dns_db_beginload(db, &callbacks);
2338 		if (result != ISC_R_SUCCESS) {
2339 			zone_idetach(&callbacks.zone);
2340 			return (result);
2341 		}
2342 		result = dns_master_loadfile5(zone->masterfile,
2343 					      &zone->origin, &zone->origin,
2344 					      zone->rdclass, options, 0,
2345 					      &callbacks,
2346 					      zone_registerinclude,
2347 					      zone, zone->mctx,
2348 					      zone->masterformat,
2349 					      zone->maxttl);
2350 		tresult = dns_db_endload(db, &callbacks);
2351 		if (result == ISC_R_SUCCESS)
2352 			result = tresult;
2353 		zone_idetach(&callbacks.zone);
2354 	}
2355 
2356 	return (result);
2357 
2358  cleanup:
2359 	load->magic = 0;
2360 	dns_db_detach(&load->db);
2361 	zone_idetach(&load->zone);
2362 	zone_idetach(&load->callbacks.zone);
2363 	isc_mem_detach(&load->mctx);
2364 	isc_mem_put(zone->mctx, load, sizeof(*load));
2365 	return (result);
2366 }
2367 
2368 static isc_boolean_t
zone_check_mx(dns_zone_t * zone,dns_db_t * db,dns_name_t * name,dns_name_t * owner)2369 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2370 	      dns_name_t *owner)
2371 {
2372 	isc_result_t result;
2373 	char ownerbuf[DNS_NAME_FORMATSIZE];
2374 	char namebuf[DNS_NAME_FORMATSIZE];
2375 	char altbuf[DNS_NAME_FORMATSIZE];
2376 	dns_fixedname_t fixed;
2377 	dns_name_t *foundname;
2378 	int level;
2379 
2380 	/*
2381 	 * "." means the services does not exist.
2382 	 */
2383 	if (dns_name_equal(name, dns_rootname))
2384 		return (ISC_TRUE);
2385 
2386 	/*
2387 	 * Outside of zone.
2388 	 */
2389 	if (!dns_name_issubdomain(name, &zone->origin)) {
2390 		if (zone->checkmx != NULL)
2391 			return ((zone->checkmx)(zone, name, owner));
2392 		return (ISC_TRUE);
2393 	}
2394 
2395 	if (zone->type == dns_zone_master)
2396 		level = ISC_LOG_ERROR;
2397 	else
2398 		level = ISC_LOG_WARNING;
2399 
2400 	dns_fixedname_init(&fixed);
2401 	foundname = dns_fixedname_name(&fixed);
2402 
2403 	result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2404 			     0, 0, NULL, foundname, NULL, NULL);
2405 	if (result == ISC_R_SUCCESS)
2406 		return (ISC_TRUE);
2407 
2408 	if (result == DNS_R_NXRRSET) {
2409 		result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2410 				     0, 0, NULL, foundname, NULL, NULL);
2411 		if (result == ISC_R_SUCCESS)
2412 			return (ISC_TRUE);
2413 	}
2414 
2415 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2416 	dns_name_format(name, namebuf, sizeof namebuf);
2417 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2418 	    result == DNS_R_EMPTYNAME) {
2419 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
2420 			level = ISC_LOG_WARNING;
2421 		dns_zone_log(zone, level,
2422 			     "%s/MX '%s' has no address records (A or AAAA)",
2423 			     ownerbuf, namebuf);
2424 		return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2425 	}
2426 
2427 	if (result == DNS_R_CNAME) {
2428 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
2429 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2430 			level = ISC_LOG_WARNING;
2431 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2432 			dns_zone_log(zone, level,
2433 				     "%s/MX '%s' is a CNAME (illegal)",
2434 				     ownerbuf, namebuf);
2435 		return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2436 	}
2437 
2438 	if (result == DNS_R_DNAME) {
2439 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
2440 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2441 			level = ISC_LOG_WARNING;
2442 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
2443 			dns_name_format(foundname, altbuf, sizeof altbuf);
2444 			dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
2445 				     " '%s' (illegal)", ownerbuf, namebuf,
2446 				     altbuf);
2447 		}
2448 		return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2449 	}
2450 
2451 	if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
2452 		return ((zone->checkmx)(zone, name, owner));
2453 
2454 	return (ISC_TRUE);
2455 }
2456 
2457 static isc_boolean_t
zone_check_srv(dns_zone_t * zone,dns_db_t * db,dns_name_t * name,dns_name_t * owner)2458 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2459 	       dns_name_t *owner)
2460 {
2461 	isc_result_t result;
2462 	char ownerbuf[DNS_NAME_FORMATSIZE];
2463 	char namebuf[DNS_NAME_FORMATSIZE];
2464 	char altbuf[DNS_NAME_FORMATSIZE];
2465 	dns_fixedname_t fixed;
2466 	dns_name_t *foundname;
2467 	int level;
2468 
2469 	/*
2470 	 * "." means the services does not exist.
2471 	 */
2472 	if (dns_name_equal(name, dns_rootname))
2473 		return (ISC_TRUE);
2474 
2475 	/*
2476 	 * Outside of zone.
2477 	 */
2478 	if (!dns_name_issubdomain(name, &zone->origin)) {
2479 		if (zone->checksrv != NULL)
2480 			return ((zone->checksrv)(zone, name, owner));
2481 		return (ISC_TRUE);
2482 	}
2483 
2484 	if (zone->type == dns_zone_master)
2485 		level = ISC_LOG_ERROR;
2486 	else
2487 		level = ISC_LOG_WARNING;
2488 
2489 	dns_fixedname_init(&fixed);
2490 	foundname = dns_fixedname_name(&fixed);
2491 
2492 	result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2493 			     0, 0, NULL, foundname, NULL, NULL);
2494 	if (result == ISC_R_SUCCESS)
2495 		return (ISC_TRUE);
2496 
2497 	if (result == DNS_R_NXRRSET) {
2498 		result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2499 				     0, 0, NULL, foundname, NULL, NULL);
2500 		if (result == ISC_R_SUCCESS)
2501 			return (ISC_TRUE);
2502 	}
2503 
2504 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2505 	dns_name_format(name, namebuf, sizeof namebuf);
2506 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2507 	    result == DNS_R_EMPTYNAME) {
2508 		dns_zone_log(zone, level,
2509 			     "%s/SRV '%s' has no address records (A or AAAA)",
2510 			     ownerbuf, namebuf);
2511 		/* XXX950 make fatal for 9.5.0. */
2512 		return (ISC_TRUE);
2513 	}
2514 
2515 	if (result == DNS_R_CNAME) {
2516 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
2517 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2518 			level = ISC_LOG_WARNING;
2519 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2520 			dns_zone_log(zone, level,
2521 				     "%s/SRV '%s' is a CNAME (illegal)",
2522 				     ownerbuf, namebuf);
2523 		return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2524 	}
2525 
2526 	if (result == DNS_R_DNAME) {
2527 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
2528 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2529 			level = ISC_LOG_WARNING;
2530 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
2531 			dns_name_format(foundname, altbuf, sizeof altbuf);
2532 			dns_zone_log(zone, level, "%s/SRV '%s' is below a "
2533 				     "DNAME '%s' (illegal)", ownerbuf, namebuf,
2534 				     altbuf);
2535 		}
2536 		return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
2537 	}
2538 
2539 	if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
2540 		return ((zone->checksrv)(zone, name, owner));
2541 
2542 	return (ISC_TRUE);
2543 }
2544 
2545 static isc_boolean_t
zone_check_glue(dns_zone_t * zone,dns_db_t * db,dns_name_t * name,dns_name_t * owner)2546 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2547 		dns_name_t *owner)
2548 {
2549 	isc_boolean_t answer = ISC_TRUE;
2550 	isc_result_t result, tresult;
2551 	char ownerbuf[DNS_NAME_FORMATSIZE];
2552 	char namebuf[DNS_NAME_FORMATSIZE];
2553 	char altbuf[DNS_NAME_FORMATSIZE];
2554 	dns_fixedname_t fixed;
2555 	dns_name_t *foundname;
2556 	dns_rdataset_t a;
2557 	dns_rdataset_t aaaa;
2558 	int level;
2559 
2560 	/*
2561 	 * Outside of zone.
2562 	 */
2563 	if (!dns_name_issubdomain(name, &zone->origin)) {
2564 		if (zone->checkns != NULL)
2565 			return ((zone->checkns)(zone, name, owner, NULL, NULL));
2566 		return (ISC_TRUE);
2567 	}
2568 
2569 	if (zone->type == dns_zone_master)
2570 		level = ISC_LOG_ERROR;
2571 	else
2572 		level = ISC_LOG_WARNING;
2573 
2574 	dns_fixedname_init(&fixed);
2575 	foundname = dns_fixedname_name(&fixed);
2576 	dns_rdataset_init(&a);
2577 	dns_rdataset_init(&aaaa);
2578 
2579 	result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2580 			     DNS_DBFIND_GLUEOK, 0, NULL,
2581 			     foundname, &a, NULL);
2582 
2583 	if (result == ISC_R_SUCCESS) {
2584 		dns_rdataset_disassociate(&a);
2585 		return (ISC_TRUE);
2586 	} else if (result == DNS_R_DELEGATION)
2587 		dns_rdataset_disassociate(&a);
2588 
2589 	if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
2590 	    result == DNS_R_GLUE) {
2591 		tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2592 				     DNS_DBFIND_GLUEOK, 0, NULL,
2593 				     foundname, &aaaa, NULL);
2594 		if (tresult == ISC_R_SUCCESS) {
2595 			if (dns_rdataset_isassociated(&a))
2596 				dns_rdataset_disassociate(&a);
2597 			dns_rdataset_disassociate(&aaaa);
2598 			return (ISC_TRUE);
2599 		}
2600 		if (tresult == DNS_R_DELEGATION)
2601 			dns_rdataset_disassociate(&aaaa);
2602 		if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
2603 			/*
2604 			 * Check glue against child zone.
2605 			 */
2606 			if (zone->checkns != NULL)
2607 				answer = (zone->checkns)(zone, name, owner,
2608 							 &a, &aaaa);
2609 			if (dns_rdataset_isassociated(&a))
2610 				dns_rdataset_disassociate(&a);
2611 			if (dns_rdataset_isassociated(&aaaa))
2612 				dns_rdataset_disassociate(&aaaa);
2613 			return (answer);
2614 		}
2615 	}
2616 
2617 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2618 	dns_name_format(name, namebuf, sizeof namebuf);
2619 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2620 	    result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
2621 		const char *what;
2622 		isc_boolean_t required = ISC_FALSE;
2623 		if (dns_name_issubdomain(name, owner)) {
2624 			what = "REQUIRED GLUE ";
2625 			required = ISC_TRUE;
2626 		 } else if (result == DNS_R_DELEGATION)
2627 			what = "SIBLING GLUE ";
2628 		else
2629 			what = "";
2630 
2631 		if (result != DNS_R_DELEGATION || required ||
2632 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
2633 			dns_zone_log(zone, level, "%s/NS '%s' has no %s"
2634 				     "address records (A or AAAA)",
2635 				     ownerbuf, namebuf, what);
2636 			/*
2637 			 * Log missing address record.
2638 			 */
2639 			if (result == DNS_R_DELEGATION && zone->checkns != NULL)
2640 				(void)(zone->checkns)(zone, name, owner,
2641 						      &a, &aaaa);
2642 			/* XXX950 make fatal for 9.5.0. */
2643 			/* answer = ISC_FALSE; */
2644 		}
2645 	} else if (result == DNS_R_CNAME) {
2646 		dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
2647 			     ownerbuf, namebuf);
2648 		/* XXX950 make fatal for 9.5.0. */
2649 		/* answer = ISC_FALSE; */
2650 	} else if (result == DNS_R_DNAME) {
2651 		dns_name_format(foundname, altbuf, sizeof altbuf);
2652 		dns_zone_log(zone, level,
2653 			     "%s/NS '%s' is below a DNAME '%s' (illegal)",
2654 			     ownerbuf, namebuf, altbuf);
2655 		/* XXX950 make fatal for 9.5.0. */
2656 		/* answer = ISC_FALSE; */
2657 	}
2658 
2659 	if (dns_rdataset_isassociated(&a))
2660 		dns_rdataset_disassociate(&a);
2661 	if (dns_rdataset_isassociated(&aaaa))
2662 		dns_rdataset_disassociate(&aaaa);
2663 	return (answer);
2664 }
2665 
2666 static isc_boolean_t
zone_rrset_check_dup(dns_zone_t * zone,dns_name_t * owner,dns_rdataset_t * rdataset)2667 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
2668 		     dns_rdataset_t *rdataset)
2669 {
2670 	dns_rdataset_t tmprdataset;
2671 	isc_result_t result;
2672 	isc_boolean_t answer = ISC_TRUE;
2673 	isc_boolean_t format = ISC_TRUE;
2674 	int level = ISC_LOG_WARNING;
2675 	char ownerbuf[DNS_NAME_FORMATSIZE];
2676 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
2677 	unsigned int count1 = 0;
2678 
2679 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL))
2680 		level = ISC_LOG_ERROR;
2681 
2682 	dns_rdataset_init(&tmprdataset);
2683 	for (result = dns_rdataset_first(rdataset);
2684 	     result == ISC_R_SUCCESS;
2685 	     result = dns_rdataset_next(rdataset)) {
2686 		dns_rdata_t rdata1 = DNS_RDATA_INIT;
2687 		unsigned int count2 = 0;
2688 
2689 		count1++;
2690 		dns_rdataset_current(rdataset, &rdata1);
2691 		dns_rdataset_clone(rdataset, &tmprdataset);
2692 		for (result = dns_rdataset_first(&tmprdataset);
2693 		     result == ISC_R_SUCCESS;
2694 		     result = dns_rdataset_next(&tmprdataset)) {
2695 			dns_rdata_t rdata2 = DNS_RDATA_INIT;
2696 			count2++;
2697 			if (count1 >= count2)
2698 				continue;
2699 			dns_rdataset_current(&tmprdataset, &rdata2);
2700 			if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
2701 				if (format) {
2702 					dns_name_format(owner, ownerbuf,
2703 							sizeof ownerbuf);
2704 					dns_rdatatype_format(rdata1.type,
2705 							     typebuf,
2706 							     sizeof(typebuf));
2707 					format = ISC_FALSE;
2708 				}
2709 				dns_zone_log(zone, level, "%s/%s has "
2710 					     "semantically identical records",
2711 					     ownerbuf, typebuf);
2712 				if (level == ISC_LOG_ERROR)
2713 					answer = ISC_FALSE;
2714 				break;
2715 			}
2716 		}
2717 		dns_rdataset_disassociate(&tmprdataset);
2718 		if (!format)
2719 			break;
2720 	}
2721 	return (answer);
2722 }
2723 
2724 static isc_boolean_t
zone_check_dup(dns_zone_t * zone,dns_db_t * db)2725 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
2726 	dns_dbiterator_t *dbiterator = NULL;
2727 	dns_dbnode_t *node = NULL;
2728 	dns_fixedname_t fixed;
2729 	dns_name_t *name;
2730 	dns_rdataset_t rdataset;
2731 	dns_rdatasetiter_t *rdsit = NULL;
2732 	isc_boolean_t ok = ISC_TRUE;
2733 	isc_result_t result;
2734 
2735 	dns_fixedname_init(&fixed);
2736 	name = dns_fixedname_name(&fixed);
2737 	dns_rdataset_init(&rdataset);
2738 
2739 	result = dns_db_createiterator(db, 0, &dbiterator);
2740 	if (result != ISC_R_SUCCESS)
2741 		return (ISC_TRUE);
2742 
2743 	for (result = dns_dbiterator_first(dbiterator);
2744 	     result == ISC_R_SUCCESS;
2745 	     result = dns_dbiterator_next(dbiterator)) {
2746 		result = dns_dbiterator_current(dbiterator, &node, name);
2747 		if (result != ISC_R_SUCCESS)
2748 			continue;
2749 
2750 		result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
2751 		if (result != ISC_R_SUCCESS)
2752 			continue;
2753 
2754 		for (result = dns_rdatasetiter_first(rdsit);
2755 		     result == ISC_R_SUCCESS;
2756 		     result = dns_rdatasetiter_next(rdsit)) {
2757 			dns_rdatasetiter_current(rdsit, &rdataset);
2758 			if (!zone_rrset_check_dup(zone, name, &rdataset))
2759 				ok = ISC_FALSE;
2760 			dns_rdataset_disassociate(&rdataset);
2761 		}
2762 		dns_rdatasetiter_destroy(&rdsit);
2763 		dns_db_detachnode(db, &node);
2764 	}
2765 
2766 	if (node != NULL)
2767 		dns_db_detachnode(db, &node);
2768 	dns_dbiterator_destroy(&dbiterator);
2769 
2770 	return (ok);
2771 }
2772 
2773 static isc_boolean_t
isspf(const dns_rdata_t * rdata)2774 isspf(const dns_rdata_t *rdata) {
2775 	char buf[1024];
2776 	const unsigned char *data = rdata->data;
2777 	unsigned int rdl = rdata->length, i = 0, tl, len;
2778 
2779 	while (rdl > 0U) {
2780 		len = tl = *data;
2781 		++data;
2782 		--rdl;
2783 		INSIST(tl <= rdl);
2784 		if (len > sizeof(buf) - i - 1)
2785 			len = sizeof(buf) - i - 1;
2786 		memmove(buf + i, data, len);
2787 		i += len;
2788 		data += tl;
2789 		rdl -= tl;
2790 	}
2791 
2792 	if (i < 6U)
2793 		return(ISC_FALSE);
2794 
2795 	buf[i] = 0;
2796 	if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' '))
2797 		return (ISC_TRUE);
2798 	return (ISC_FALSE);
2799 }
2800 
2801 static isc_boolean_t
integrity_checks(dns_zone_t * zone,dns_db_t * db)2802 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
2803 	dns_dbiterator_t *dbiterator = NULL;
2804 	dns_dbnode_t *node = NULL;
2805 	dns_rdataset_t rdataset;
2806 	dns_fixedname_t fixed;
2807 	dns_fixedname_t fixedbottom;
2808 	dns_rdata_mx_t mx;
2809 	dns_rdata_ns_t ns;
2810 	dns_rdata_in_srv_t srv;
2811 	dns_rdata_t rdata;
2812 	dns_name_t *name;
2813 	dns_name_t *bottom;
2814 	isc_result_t result;
2815 	isc_boolean_t ok = ISC_TRUE, have_spf, have_txt;
2816 
2817 	dns_fixedname_init(&fixed);
2818 	name = dns_fixedname_name(&fixed);
2819 	dns_fixedname_init(&fixedbottom);
2820 	bottom = dns_fixedname_name(&fixedbottom);
2821 	dns_rdataset_init(&rdataset);
2822 	dns_rdata_init(&rdata);
2823 
2824 	result = dns_db_createiterator(db, 0, &dbiterator);
2825 	if (result != ISC_R_SUCCESS)
2826 		return (ISC_TRUE);
2827 
2828 	result = dns_dbiterator_first(dbiterator);
2829 	while (result == ISC_R_SUCCESS) {
2830 		result = dns_dbiterator_current(dbiterator, &node, name);
2831 		if (result != ISC_R_SUCCESS)
2832 			goto cleanup;
2833 
2834 		/*
2835 		 * Is this name visible in the zone?
2836 		 */
2837 		if (!dns_name_issubdomain(name, &zone->origin) ||
2838 		    (dns_name_countlabels(bottom) > 0 &&
2839 		     dns_name_issubdomain(name, bottom)))
2840 			goto next;
2841 
2842 		/*
2843 		 * Don't check the NS records at the origin.
2844 		 */
2845 		if (dns_name_equal(name, &zone->origin))
2846 			goto checkmx;
2847 
2848 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
2849 					     0, 0, &rdataset, NULL);
2850 		if (result != ISC_R_SUCCESS)
2851 			goto checkmx;
2852 		/*
2853 		 * Remember bottom of zone.
2854 		 */
2855 		dns_name_copy(name, bottom, NULL);
2856 
2857 		result = dns_rdataset_first(&rdataset);
2858 		while (result == ISC_R_SUCCESS) {
2859 			dns_rdataset_current(&rdataset, &rdata);
2860 			result = dns_rdata_tostruct(&rdata, &ns, NULL);
2861 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
2862 			if (!zone_check_glue(zone, db, &ns.name, name))
2863 				ok = ISC_FALSE;
2864 			dns_rdata_reset(&rdata);
2865 			result = dns_rdataset_next(&rdataset);
2866 		}
2867 		dns_rdataset_disassociate(&rdataset);
2868 		goto next;
2869 
2870  checkmx:
2871 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
2872 					     0, 0, &rdataset, NULL);
2873 		if (result != ISC_R_SUCCESS)
2874 			goto checksrv;
2875 		result = dns_rdataset_first(&rdataset);
2876 		while (result == ISC_R_SUCCESS) {
2877 			dns_rdataset_current(&rdataset, &rdata);
2878 			result = dns_rdata_tostruct(&rdata, &mx, NULL);
2879 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
2880 			if (!zone_check_mx(zone, db, &mx.mx, name))
2881 				ok = ISC_FALSE;
2882 			dns_rdata_reset(&rdata);
2883 			result = dns_rdataset_next(&rdataset);
2884 		}
2885 		dns_rdataset_disassociate(&rdataset);
2886 
2887  checksrv:
2888 		if (zone->rdclass != dns_rdataclass_in)
2889 			goto next;
2890 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
2891 					     0, 0, &rdataset, NULL);
2892 		if (result != ISC_R_SUCCESS)
2893 			goto checkspf;
2894 		result = dns_rdataset_first(&rdataset);
2895 		while (result == ISC_R_SUCCESS) {
2896 			dns_rdataset_current(&rdataset, &rdata);
2897 			result = dns_rdata_tostruct(&rdata, &srv, NULL);
2898 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
2899 			if (!zone_check_srv(zone, db, &srv.target, name))
2900 				ok = ISC_FALSE;
2901 			dns_rdata_reset(&rdata);
2902 			result = dns_rdataset_next(&rdataset);
2903 		}
2904 		dns_rdataset_disassociate(&rdataset);
2905 
2906  checkspf:
2907 		/*
2908 		 * Check if there is a type SPF record without an
2909 		 * SPF-formatted type TXT record also being present.
2910 		 */
2911 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF))
2912 			goto next;
2913 		if (zone->rdclass != dns_rdataclass_in)
2914 			goto next;
2915 		have_spf = have_txt = ISC_FALSE;
2916 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
2917 					     0, 0, &rdataset, NULL);
2918 		if (result == ISC_R_SUCCESS) {
2919 			dns_rdataset_disassociate(&rdataset);
2920 			have_spf = ISC_TRUE;
2921 		}
2922 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
2923 					     0, 0, &rdataset, NULL);
2924 		if (result != ISC_R_SUCCESS)
2925 			goto notxt;
2926 		result = dns_rdataset_first(&rdataset);
2927 		while (result == ISC_R_SUCCESS) {
2928 			dns_rdataset_current(&rdataset, &rdata);
2929 			have_txt = isspf(&rdata);
2930 			dns_rdata_reset(&rdata);
2931 			if (have_txt)
2932 				break;
2933 			result = dns_rdataset_next(&rdataset);
2934 		}
2935 		dns_rdataset_disassociate(&rdataset);
2936 
2937  notxt:
2938 		if (have_spf && !have_txt) {
2939 			char namebuf[DNS_NAME_FORMATSIZE];
2940 
2941 			dns_name_format(name, namebuf, sizeof(namebuf));
2942 			dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found type "
2943 				     "SPF record but no SPF TXT record found, "
2944 				     "add matching type TXT record", namebuf);
2945 		}
2946 
2947  next:
2948 		dns_db_detachnode(db, &node);
2949 		result = dns_dbiterator_next(dbiterator);
2950 	}
2951 
2952  cleanup:
2953 	if (node != NULL)
2954 		dns_db_detachnode(db, &node);
2955 	dns_dbiterator_destroy(&dbiterator);
2956 
2957 	return (ok);
2958 }
2959 
2960 /*
2961  * OpenSSL verification of RSA keys with exponent 3 is known to be
2962  * broken prior OpenSSL 0.9.8c/0.9.7k.	Look for such keys and warn
2963  * if they are in use.
2964  */
2965 static void
zone_check_dnskeys(dns_zone_t * zone,dns_db_t * db)2966 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
2967 	dns_dbnode_t *node = NULL;
2968 	dns_dbversion_t *version = NULL;
2969 	dns_rdata_dnskey_t dnskey;
2970 	dns_rdata_t rdata = DNS_RDATA_INIT;
2971 	dns_rdataset_t rdataset;
2972 	isc_result_t result;
2973 	isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
2974 	const char *algorithm;
2975 
2976 	result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2977 	if (result != ISC_R_SUCCESS)
2978 		goto cleanup;
2979 
2980 	dns_db_currentversion(db, &version);
2981 	dns_rdataset_init(&rdataset);
2982 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
2983 				     dns_rdatatype_none, 0, &rdataset, NULL);
2984 	if (result != ISC_R_SUCCESS)
2985 		goto cleanup;
2986 
2987 	for (result = dns_rdataset_first(&rdataset);
2988 	     result == ISC_R_SUCCESS;
2989 	     result = dns_rdataset_next(&rdataset))
2990 	{
2991 		dns_rdataset_current(&rdataset, &rdata);
2992 		result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
2993 		INSIST(result == ISC_R_SUCCESS);
2994 
2995 		if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
2996 		     dnskey.algorithm == DST_ALG_RSAMD5) &&
2997 		     dnskey.datalen > 1 && dnskey.data[0] == 1 &&
2998 		     dnskey.data[1] == 3)
2999 		{
3000 			if (dnskey.algorithm == DST_ALG_RSASHA1) {
3001 				logit = !foundrsa;
3002 				foundrsa = ISC_TRUE;
3003 				algorithm = "RSASHA1";
3004 			} else {
3005 				logit = !foundmd5;
3006 				foundmd5 = ISC_TRUE;
3007 				algorithm = "RSAMD5";
3008 			}
3009 			if (logit)
3010 				dns_zone_log(zone, ISC_LOG_WARNING,
3011 					     "weak %s (%u) key found "
3012 					     "(exponent=3)", algorithm,
3013 					     dnskey.algorithm);
3014 			if (foundrsa && foundmd5)
3015 				break;
3016 		}
3017 		dns_rdata_reset(&rdata);
3018 	}
3019 	dns_rdataset_disassociate(&rdataset);
3020 
3021  cleanup:
3022 	if (node != NULL)
3023 		dns_db_detachnode(db, &node);
3024 	if (version != NULL)
3025 		dns_db_closeversion(db, &version, ISC_FALSE);
3026 }
3027 
3028 static void
resume_signingwithkey(dns_zone_t * zone)3029 resume_signingwithkey(dns_zone_t *zone) {
3030 	dns_dbnode_t *node = NULL;
3031 	dns_dbversion_t *version = NULL;
3032 	dns_rdata_t rdata = DNS_RDATA_INIT;
3033 	dns_rdataset_t rdataset;
3034 	isc_result_t result;
3035 	dns_db_t *db = NULL;
3036 
3037 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3038 	if (zone->db != NULL)
3039 		dns_db_attach(zone->db, &db);
3040 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3041 	if (db == NULL)
3042 		goto cleanup;
3043 
3044 	result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
3045 	if (result != ISC_R_SUCCESS)
3046 		goto cleanup;
3047 
3048 	dns_db_currentversion(db, &version);
3049 	dns_rdataset_init(&rdataset);
3050 	result = dns_db_findrdataset(db, node, version,
3051 				     zone->privatetype,
3052 				     dns_rdatatype_none, 0,
3053 				     &rdataset, NULL);
3054 	if (result != ISC_R_SUCCESS) {
3055 		INSIST(!dns_rdataset_isassociated(&rdataset));
3056 		goto cleanup;
3057 	}
3058 
3059 	for (result = dns_rdataset_first(&rdataset);
3060 	     result == ISC_R_SUCCESS;
3061 	     result = dns_rdataset_next(&rdataset))
3062 	{
3063 		dns_rdataset_current(&rdataset, &rdata);
3064 		if (rdata.length != 5 ||
3065 		    rdata.data[0] == 0 || rdata.data[4] != 0) {
3066 			dns_rdata_reset(&rdata);
3067 			continue;
3068 		}
3069 
3070 		result = zone_signwithkey(zone, rdata.data[0],
3071 					  (rdata.data[1] << 8) | rdata.data[2],
3072 					  ISC_TF(rdata.data[3]));
3073 		if (result != ISC_R_SUCCESS) {
3074 			dns_zone_log(zone, ISC_LOG_ERROR,
3075 				     "zone_signwithkey failed: %s",
3076 				     dns_result_totext(result));
3077 		}
3078 		dns_rdata_reset(&rdata);
3079 	}
3080 	dns_rdataset_disassociate(&rdataset);
3081 
3082  cleanup:
3083 	if (db != NULL) {
3084 		if (node != NULL)
3085 			dns_db_detachnode(db, &node);
3086 		if (version != NULL)
3087 			dns_db_closeversion(db, &version, ISC_FALSE);
3088 		dns_db_detach(&db);
3089 	}
3090 }
3091 
3092 static isc_result_t
zone_addnsec3chain(dns_zone_t * zone,dns_rdata_nsec3param_t * nsec3param)3093 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
3094 	dns_nsec3chain_t *nsec3chain, *current;
3095 	dns_dbversion_t *version = NULL;
3096 	isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
3097 	isc_result_t result;
3098 	isc_time_t now;
3099 	unsigned int options = 0;
3100 	char saltbuf[255*2+1];
3101 	char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
3102 	dns_db_t *db = NULL;
3103 	int i;
3104 
3105 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3106 	if (zone->db != NULL)
3107 		dns_db_attach(zone->db, &db);
3108 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3109 
3110 	if (db == NULL) {
3111 		result = ISC_R_SUCCESS;
3112 		goto cleanup;
3113 	}
3114 
3115 	dns_db_currentversion(db, &version);
3116 	result = dns_nsec_nseconly(db, version, &nseconly);
3117 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
3118 	dns_db_closeversion(db, &version, ISC_FALSE);
3119 	if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) {
3120 		result = ISC_R_SUCCESS;
3121 		goto cleanup;
3122 	}
3123 
3124 	nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
3125 	if (nsec3chain == NULL) {
3126 		result = ISC_R_NOMEMORY;
3127 		goto cleanup;
3128 	}
3129 
3130 	nsec3chain->magic = 0;
3131 	nsec3chain->done = ISC_FALSE;
3132 	nsec3chain->db = NULL;
3133 	nsec3chain->dbiterator = NULL;
3134 	nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
3135 	nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
3136 	nsec3chain->nsec3param.hash = nsec3param->hash;
3137 	nsec3chain->nsec3param.iterations = nsec3param->iterations;
3138 	nsec3chain->nsec3param.flags = nsec3param->flags;
3139 	nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
3140 	memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
3141 	nsec3chain->nsec3param.salt = nsec3chain->salt;
3142 	nsec3chain->seen_nsec = ISC_FALSE;
3143 	nsec3chain->delete_nsec = ISC_FALSE;
3144 	nsec3chain->save_delete_nsec = ISC_FALSE;
3145 
3146 	if (nsec3param->flags == 0)
3147 		strlcpy(flags, "NONE", sizeof(flags));
3148 	else {
3149 		flags[0] = '\0';
3150 		if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE)
3151 			strlcat(flags, "REMOVE", sizeof(flags));
3152 		if (nsec3param->flags & DNS_NSEC3FLAG_INITIAL) {
3153 			if (flags[0] == '\0')
3154 				strlcpy(flags, "INITIAL", sizeof(flags));
3155 			else
3156 				strlcat(flags, "|INITIAL", sizeof(flags));
3157 		}
3158 		if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) {
3159 			if (flags[0] == '\0')
3160 				strlcpy(flags, "CREATE", sizeof(flags));
3161 			else
3162 				strlcat(flags, "|CREATE", sizeof(flags));
3163 		}
3164 		if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) {
3165 			if (flags[0] == '\0')
3166 				strlcpy(flags, "NONSEC", sizeof(flags));
3167 			else
3168 				strlcat(flags, "|NONSEC", sizeof(flags));
3169 		}
3170 		if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) {
3171 			if (flags[0] == '\0')
3172 				strlcpy(flags, "OPTOUT", sizeof(flags));
3173 			else
3174 				strlcat(flags, "|OPTOUT", sizeof(flags));
3175 		}
3176 	}
3177 	if (nsec3param->salt_length == 0)
3178 		strlcpy(saltbuf, "-", sizeof(saltbuf));
3179 	else
3180 		for (i = 0; i < nsec3param->salt_length; i++)
3181 			sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]);
3182 	dns_zone_log(zone, ISC_LOG_INFO,
3183 		     "zone_addnsec3chain(%u,%s,%u,%s)",
3184 		      nsec3param->hash, flags, nsec3param->iterations,
3185 		      saltbuf);
3186 
3187 	for (current = ISC_LIST_HEAD(zone->nsec3chain);
3188 	     current != NULL;
3189 	     current = ISC_LIST_NEXT(current, link)) {
3190 		if (current->db == db &&
3191 		    current->nsec3param.hash == nsec3param->hash &&
3192 		    current->nsec3param.iterations == nsec3param->iterations &&
3193 		    current->nsec3param.salt_length == nsec3param->salt_length
3194 		    && !memcmp(current->nsec3param.salt, nsec3param->salt,
3195 			       nsec3param->salt_length))
3196 			current->done = ISC_TRUE;
3197 	}
3198 
3199 	dns_db_attach(db, &nsec3chain->db);
3200 	if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
3201 		options = DNS_DB_NONSEC3;
3202 	result = dns_db_createiterator(nsec3chain->db, options,
3203 				       &nsec3chain->dbiterator);
3204 	if (result == ISC_R_SUCCESS)
3205 		dns_dbiterator_first(nsec3chain->dbiterator);
3206 	if (result == ISC_R_SUCCESS) {
3207 		dns_dbiterator_pause(nsec3chain->dbiterator);
3208 		ISC_LIST_INITANDAPPEND(zone->nsec3chain,
3209 				       nsec3chain, link);
3210 		nsec3chain = NULL;
3211 		if (isc_time_isepoch(&zone->nsec3chaintime)) {
3212 			TIME_NOW(&now);
3213 			zone->nsec3chaintime = now;
3214 			if (zone->task != NULL)
3215 				zone_settimer(zone, &now);
3216 		}
3217 	}
3218 
3219 	if (nsec3chain != NULL) {
3220 		if (nsec3chain->db != NULL)
3221 			dns_db_detach(&nsec3chain->db);
3222 		if (nsec3chain->dbiterator != NULL)
3223 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
3224 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
3225 	}
3226 
3227  cleanup:
3228 	if (db != NULL)
3229 		dns_db_detach(&db);
3230 	return (result);
3231 }
3232 
3233 static void
resume_addnsec3chain(dns_zone_t * zone)3234 resume_addnsec3chain(dns_zone_t *zone) {
3235 	dns_dbnode_t *node = NULL;
3236 	dns_dbversion_t *version = NULL;
3237 	dns_rdataset_t rdataset;
3238 	isc_result_t result;
3239 	dns_rdata_nsec3param_t nsec3param;
3240 	isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
3241 	dns_db_t *db = NULL;
3242 
3243 	if (zone->privatetype == 0)
3244 		return;
3245 
3246 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3247 	if (zone->db != NULL)
3248 		dns_db_attach(zone->db, &db);
3249 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3250 	if (db == NULL)
3251 		goto cleanup;
3252 
3253 	result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
3254 	if (result != ISC_R_SUCCESS)
3255 		goto cleanup;
3256 
3257 	dns_db_currentversion(db, &version);
3258 
3259 	result = dns_nsec_nseconly(db, version, &nseconly);
3260 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
3261 
3262 	dns_rdataset_init(&rdataset);
3263 	result = dns_db_findrdataset(db, node, version,
3264 				     zone->privatetype, dns_rdatatype_none,
3265 				     0, &rdataset, NULL);
3266 	if (result != ISC_R_SUCCESS) {
3267 		INSIST(!dns_rdataset_isassociated(&rdataset));
3268 		goto cleanup;
3269 	}
3270 
3271 	for (result = dns_rdataset_first(&rdataset);
3272 	     result == ISC_R_SUCCESS;
3273 	     result = dns_rdataset_next(&rdataset))
3274 	{
3275 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
3276 		dns_rdata_t rdata = DNS_RDATA_INIT;
3277 		dns_rdata_t private = DNS_RDATA_INIT;
3278 
3279 		dns_rdataset_current(&rdataset, &private);
3280 		if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
3281 						sizeof(buf)))
3282 			continue;
3283 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
3284 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
3285 		if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) ||
3286 		    ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok))
3287 		{
3288 			result = zone_addnsec3chain(zone, &nsec3param);
3289 			if (result != ISC_R_SUCCESS) {
3290 				dns_zone_log(zone, ISC_LOG_ERROR,
3291 					     "zone_addnsec3chain failed: %s",
3292 					     dns_result_totext(result));
3293 			}
3294 		}
3295 	}
3296 	dns_rdataset_disassociate(&rdataset);
3297  cleanup:
3298 	if (db != NULL) {
3299 		if (node != NULL)
3300 			dns_db_detachnode(db, &node);
3301 		if (version != NULL)
3302 			dns_db_closeversion(db, &version, ISC_FALSE);
3303 		dns_db_detach(&db);
3304 	}
3305 }
3306 
3307 static void
set_resigntime(dns_zone_t * zone)3308 set_resigntime(dns_zone_t *zone) {
3309 	dns_rdataset_t rdataset;
3310 	dns_fixedname_t fixed;
3311 	unsigned int resign;
3312 	isc_result_t result;
3313 	isc_uint32_t nanosecs;
3314 	dns_db_t *db = NULL;
3315 
3316 	/* We only re-sign zones that can be dynamically updated */
3317 	if (zone->update_disabled)
3318 		return;
3319 
3320 	if (!inline_secure(zone) && (zone->type != dns_zone_master ||
3321 	    (zone->ssutable == NULL &&
3322 	     (zone->update_acl == NULL || dns_acl_isnone(zone->update_acl)))))
3323 		return;
3324 
3325 	dns_rdataset_init(&rdataset);
3326 	dns_fixedname_init(&fixed);
3327 
3328 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3329 	if (zone->db != NULL)
3330 		dns_db_attach(zone->db, &db);
3331 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3332 	if (db == NULL) {
3333 		isc_time_settoepoch(&zone->resigntime);
3334 		return;
3335 	}
3336 
3337 	result = dns_db_getsigningtime(db, &rdataset,
3338 				       dns_fixedname_name(&fixed));
3339 	if (result != ISC_R_SUCCESS) {
3340 		isc_time_settoepoch(&zone->resigntime);
3341 		goto cleanup;
3342 	}
3343 
3344 	resign = rdataset.resign - zone->sigresigninginterval;
3345 	dns_rdataset_disassociate(&rdataset);
3346 	isc_random_get(&nanosecs);
3347 	nanosecs %= 1000000000;
3348 	isc_time_set(&zone->resigntime, resign, nanosecs);
3349  cleanup:
3350 	dns_db_detach(&db);
3351 	return;
3352 }
3353 
3354 static isc_result_t
check_nsec3param(dns_zone_t * zone,dns_db_t * db)3355 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
3356 	dns_dbnode_t *node = NULL;
3357 	dns_rdataset_t rdataset;
3358 	dns_dbversion_t *version = NULL;
3359 	dns_rdata_nsec3param_t nsec3param;
3360 	isc_boolean_t ok = ISC_FALSE;
3361 	isc_result_t result;
3362 	dns_rdata_t rdata = DNS_RDATA_INIT;
3363 	isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
3364 				dns_zone_isdynamic(zone, ISC_FALSE) : ISC_FALSE;
3365 
3366 	dns_rdataset_init(&rdataset);
3367 	result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
3368 	if (result != ISC_R_SUCCESS) {
3369 		dns_zone_log(zone, ISC_LOG_ERROR,
3370 			     "nsec3param lookup failure: %s",
3371 			     dns_result_totext(result));
3372 		return (result);
3373 	}
3374 	dns_db_currentversion(db, &version);
3375 
3376 	result = dns_db_findrdataset(db, node, version,
3377 				     dns_rdatatype_nsec3param,
3378 				     dns_rdatatype_none, 0, &rdataset, NULL);
3379 	if (result == ISC_R_NOTFOUND) {
3380 		INSIST(!dns_rdataset_isassociated(&rdataset));
3381 		result = ISC_R_SUCCESS;
3382 		goto cleanup;
3383 	}
3384 	if (result != ISC_R_SUCCESS) {
3385 		INSIST(!dns_rdataset_isassociated(&rdataset));
3386 		dns_zone_log(zone, ISC_LOG_ERROR,
3387 			     "nsec3param lookup failure: %s",
3388 			     dns_result_totext(result));
3389 		goto cleanup;
3390 	}
3391 
3392 	/*
3393 	 * For dynamic zones we must support every algorithm so we can
3394 	 * regenerate all the NSEC3 chains.
3395 	 * For non-dynamic zones we only need to find a supported algorithm.
3396 	 */
3397 	for (result = dns_rdataset_first(&rdataset);
3398 	     result == ISC_R_SUCCESS;
3399 	     result = dns_rdataset_next(&rdataset))
3400 	{
3401 		dns_rdataset_current(&rdataset, &rdata);
3402 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
3403 		dns_rdata_reset(&rdata);
3404 		INSIST(result == ISC_R_SUCCESS);
3405 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
3406 		    nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
3407 		{
3408 			dns_zone_log(zone, ISC_LOG_WARNING,
3409 			     "nsec3 test \"unknown\" hash algorithm found: %u",
3410 				     nsec3param.hash);
3411 			ok = ISC_TRUE;
3412 		} else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
3413 			if (dynamic) {
3414 				dns_zone_log(zone, ISC_LOG_ERROR,
3415 					     "unsupported nsec3 hash algorithm"
3416 					     " in dynamic zone: %u",
3417 					     nsec3param.hash);
3418 				result = DNS_R_BADZONE;
3419 				/* Stop second error message. */
3420 				ok = ISC_TRUE;
3421 				break;
3422 			} else
3423 				dns_zone_log(zone, ISC_LOG_WARNING,
3424 				     "unsupported nsec3 hash algorithm: %u",
3425 					     nsec3param.hash);
3426 		} else
3427 			ok = ISC_TRUE;
3428 	}
3429 	if (result == ISC_R_NOMORE)
3430 		result = ISC_R_SUCCESS;
3431 
3432 	if (!ok) {
3433 		result = DNS_R_BADZONE;
3434 		dns_zone_log(zone, ISC_LOG_ERROR,
3435 			     "no supported nsec3 hash algorithm");
3436 	}
3437 
3438  cleanup:
3439 	if (dns_rdataset_isassociated(&rdataset))
3440 		dns_rdataset_disassociate(&rdataset);
3441 	dns_db_closeversion(db, &version, ISC_FALSE);
3442 	dns_db_detachnode(db, &node);
3443 	return (result);
3444 }
3445 
3446 /*
3447  * Set the timer for refreshing the key zone to the soonest future time
3448  * of the set (current timer, keydata->refresh, keydata->addhd,
3449  * keydata->removehd).
3450  */
3451 static void
set_refreshkeytimer(dns_zone_t * zone,dns_rdata_keydata_t * key,isc_stdtime_t now,isc_boolean_t force)3452 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
3453 		    isc_stdtime_t now, isc_boolean_t force)
3454 {
3455 	const char me[] = "set_refreshkeytimer";
3456 	isc_stdtime_t then;
3457 	isc_time_t timenow, timethen;
3458 	char timebuf[80];
3459 
3460 	ENTER;
3461 	then = key->refresh;
3462 	if (force)
3463 		then = now;
3464 	if (key->addhd > now && key->addhd < then)
3465 		then = key->addhd;
3466 	if (key->removehd > now && key->removehd < then)
3467 		then = key->removehd;
3468 
3469 	TIME_NOW(&timenow);
3470 	if (then > now)
3471 		DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
3472 	else
3473 		timethen = timenow;
3474 	if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
3475 	    isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
3476 		zone->refreshkeytime = timethen;
3477 
3478 	isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
3479 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
3480 	zone_settimer(zone, &timenow);
3481 }
3482 
3483 /*
3484  * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
3485  * If the key zone is changed, set '*changed' to ISC_TRUE.
3486  */
3487 static isc_result_t
create_keydata(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff,dns_keytable_t * keytable,dns_keynode_t ** keynodep,isc_boolean_t * changed)3488 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
3489 	       dns_diff_t *diff, dns_keytable_t *keytable,
3490 	       dns_keynode_t **keynodep, isc_boolean_t *changed)
3491 {
3492 	const char me[] = "create_keydata";
3493 	isc_result_t result = ISC_R_SUCCESS;
3494 	isc_buffer_t keyb, dstb;
3495 	unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
3496 	dns_rdata_keydata_t keydata;
3497 	dns_rdata_dnskey_t dnskey;
3498 	dns_rdata_t rdata = DNS_RDATA_INIT;
3499 	dns_keynode_t *keynode;
3500 	isc_stdtime_t now;
3501 	isc_region_t r;
3502 	dst_key_t *key;
3503 
3504 	REQUIRE(keynodep != NULL);
3505 	keynode = *keynodep;
3506 
3507 	ENTER;
3508 	isc_stdtime_get(&now);
3509 
3510 	/* Loop in case there's more than one key. */
3511 	while (result == ISC_R_SUCCESS) {
3512 		dns_keynode_t *nextnode = NULL;
3513 
3514 		key = dns_keynode_key(keynode);
3515 		if (key == NULL)
3516 			goto skip;
3517 
3518 		isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
3519 		CHECK(dst_key_todns(key, &dstb));
3520 
3521 		/* Convert DST key to DNSKEY. */
3522 		dns_rdata_reset(&rdata);
3523 		isc_buffer_usedregion(&dstb, &r);
3524 		dns_rdata_fromregion(&rdata, dst_key_class(key),
3525 				     dns_rdatatype_dnskey, &r);
3526 
3527 		/* DSTKEY to KEYDATA. */
3528 		CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
3529 		CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
3530 					     NULL));
3531 
3532 		/* KEYDATA to rdata. */
3533 		dns_rdata_reset(&rdata);
3534 		isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
3535 		CHECK(dns_rdata_fromstruct(&rdata,
3536 					   zone->rdclass, dns_rdatatype_keydata,
3537 					   &keydata, &keyb));
3538 
3539 		/* Add rdata to zone. */
3540 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
3541 				    dst_key_name(key), 0, &rdata));
3542 		*changed = ISC_TRUE;
3543 
3544 		/* Refresh new keys from the zone apex as soon as possible. */
3545 		set_refreshkeytimer(zone, &keydata, now, ISC_TRUE);
3546 
3547  skip:
3548 		result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
3549 		if (result != ISC_R_NOTFOUND) {
3550 			dns_keytable_detachkeynode(keytable, &keynode);
3551 			keynode = nextnode;
3552 		}
3553 	}
3554 
3555 	if (keynode != NULL)
3556 		dns_keytable_detachkeynode(keytable, &keynode);
3557 	*keynodep = NULL;
3558 
3559 	return (ISC_R_SUCCESS);
3560 
3561   failure:
3562 	return (result);
3563 }
3564 
3565 /*
3566  * Remove from the key zone all the KEYDATA records found in rdataset.
3567  */
3568 static isc_result_t
delete_keydata(dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff,dns_name_t * name,dns_rdataset_t * rdataset)3569 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3570 	       dns_name_t *name, dns_rdataset_t *rdataset)
3571 {
3572 	dns_rdata_t rdata = DNS_RDATA_INIT;
3573 	isc_result_t result, uresult;
3574 
3575 	for (result = dns_rdataset_first(rdataset);
3576 	     result == ISC_R_SUCCESS;
3577 	     result = dns_rdataset_next(rdataset)) {
3578 		dns_rdata_reset(&rdata);
3579 		dns_rdataset_current(rdataset, &rdata);
3580 		uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
3581 					name, 0, &rdata);
3582 		if (uresult != ISC_R_SUCCESS)
3583 			return (uresult);
3584 	}
3585 	if (result == ISC_R_NOMORE)
3586 		result = ISC_R_SUCCESS;
3587 	return (result);
3588 }
3589 
3590 /*
3591  * Compute the DNSSEC key ID for a DNSKEY record.
3592  */
3593 static isc_result_t
compute_tag(dns_name_t * name,dns_rdata_dnskey_t * dnskey,isc_mem_t * mctx,dns_keytag_t * tag)3594 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
3595 	    dns_keytag_t *tag)
3596 {
3597 	isc_result_t result;
3598 	dns_rdata_t rdata = DNS_RDATA_INIT;
3599 	unsigned char data[4096];
3600 	isc_buffer_t buffer;
3601 	dst_key_t *dstkey = NULL;
3602 
3603 	isc_buffer_init(&buffer, data, sizeof(data));
3604 	dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
3605 			     dns_rdatatype_dnskey, dnskey, &buffer);
3606 
3607 	result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
3608 	if (result == ISC_R_SUCCESS)
3609 		*tag = dst_key_id(dstkey);
3610 	dst_key_free(&dstkey);
3611 
3612 	return (result);
3613 }
3614 
3615 /*
3616  * Add key to the security roots.
3617  */
3618 static void
trust_key(dns_zone_t * zone,dns_name_t * keyname,dns_rdata_dnskey_t * dnskey,isc_mem_t * mctx)3619 trust_key(dns_zone_t *zone, dns_name_t *keyname,
3620 	  dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) {
3621 	isc_result_t result;
3622 	dns_rdata_t rdata = DNS_RDATA_INIT;
3623 	unsigned char data[4096];
3624 	isc_buffer_t buffer;
3625 	dns_keytable_t *sr = NULL;
3626 	dst_key_t *dstkey = NULL;
3627 
3628 	/* Convert dnskey to DST key. */
3629 	isc_buffer_init(&buffer, data, sizeof(data));
3630 	dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
3631 			     dns_rdatatype_dnskey, dnskey, &buffer);
3632 
3633 	result = dns_view_getsecroots(zone->view, &sr);
3634 	if (result != ISC_R_SUCCESS)
3635 		goto failure;
3636 
3637 	CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
3638 	CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey));
3639 	dns_keytable_detach(&sr);
3640 
3641   failure:
3642 	if (dstkey != NULL)
3643 		dst_key_free(&dstkey);
3644 	if (sr != NULL)
3645 		dns_keytable_detach(&sr);
3646 	return;
3647 }
3648 
3649 /*
3650  * Add a null key to the security roots for so that all queries
3651  * to the zone will fail.
3652  */
3653 static void
fail_secure(dns_zone_t * zone,dns_name_t * keyname)3654 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
3655 	isc_result_t result;
3656 	dns_keytable_t *sr = NULL;
3657 
3658 	result = dns_view_getsecroots(zone->view, &sr);
3659 	if (result == ISC_R_SUCCESS) {
3660 		dns_keytable_marksecure(sr, keyname);
3661 		dns_keytable_detach(&sr);
3662 	}
3663 }
3664 
3665 /*
3666  * Scan a set of KEYDATA records from the key zone.  The ones that are
3667  * valid (i.e., the add holddown timer has expired) become trusted keys.
3668  */
3669 static void
load_secroots(dns_zone_t * zone,dns_name_t * name,dns_rdataset_t * rdataset)3670 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
3671 	isc_result_t result;
3672 	dns_rdata_t rdata = DNS_RDATA_INIT;
3673 	dns_rdata_keydata_t keydata;
3674 	dns_rdata_dnskey_t dnskey;
3675 	isc_mem_t *mctx = zone->mctx;
3676 	int trusted = 0, revoked = 0, pending = 0;
3677 	isc_stdtime_t now;
3678 	dns_keytable_t *sr = NULL;
3679 
3680 	isc_stdtime_get(&now);
3681 
3682 	result = dns_view_getsecroots(zone->view, &sr);
3683 	if (result == ISC_R_SUCCESS) {
3684 		dns_keytable_delete(sr, name);
3685 		dns_keytable_detach(&sr);
3686 	}
3687 
3688 	/* Now insert all the accepted trust anchors from this keydata set. */
3689 	for (result = dns_rdataset_first(rdataset);
3690 	     result == ISC_R_SUCCESS;
3691 	     result = dns_rdataset_next(rdataset)) {
3692 		dns_rdata_reset(&rdata);
3693 		dns_rdataset_current(rdataset, &rdata);
3694 
3695 		/* Convert rdata to keydata. */
3696 		result = dns_rdata_tostruct(&rdata, &keydata, NULL);
3697 		if (result == ISC_R_UNEXPECTEDEND)
3698 			continue;
3699 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
3700 
3701 		/* Set the key refresh timer to force a fast refresh. */
3702 		set_refreshkeytimer(zone, &keydata, now, ISC_TRUE);
3703 
3704 		/* If the removal timer is nonzero, this key was revoked. */
3705 		if (keydata.removehd != 0) {
3706 			revoked++;
3707 			continue;
3708 		}
3709 
3710 		/*
3711 		 * If the add timer is still pending, this key is not
3712 		 * trusted yet.
3713 		 */
3714 		if (now < keydata.addhd) {
3715 			pending++;
3716 			continue;
3717 		}
3718 
3719 		/* Convert keydata to dnskey. */
3720 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
3721 
3722 		/* Add to keytables. */
3723 		trusted++;
3724 		trust_key(zone, name, &dnskey, mctx);
3725 	}
3726 
3727 	if (trusted == 0 && pending != 0) {
3728 		char namebuf[DNS_NAME_FORMATSIZE];
3729 		dns_name_format(name, namebuf, sizeof namebuf);
3730 		dns_zone_log(zone, ISC_LOG_ERROR,
3731 			     "No valid trust anchors for '%s'!", namebuf);
3732 		dns_zone_log(zone, ISC_LOG_ERROR,
3733 			     "%d key(s) revoked, %d still pending",
3734 			     revoked, pending);
3735 		dns_zone_log(zone, ISC_LOG_ERROR,
3736 			     "All queries to '%s' will fail", namebuf);
3737 		fail_secure(zone, name);
3738 	}
3739 }
3740 
3741 static isc_result_t
do_one_tuple(dns_difftuple_t ** tuple,dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff)3742 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
3743 	     dns_diff_t *diff)
3744 {
3745 	dns_diff_t temp_diff;
3746 	isc_result_t result;
3747 
3748 	/*
3749 	 * Create a singleton diff.
3750 	 */
3751 	dns_diff_init(diff->mctx, &temp_diff);
3752 	ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
3753 
3754 	/*
3755 	 * Apply it to the database.
3756 	 */
3757 	result = dns_diff_apply(&temp_diff, db, ver);
3758 	ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
3759 	if (result != ISC_R_SUCCESS) {
3760 		dns_difftuple_free(tuple);
3761 		return (result);
3762 	}
3763 
3764 	/*
3765 	 * Merge it into the current pending journal entry.
3766 	 */
3767 	dns_diff_appendminimal(diff, tuple);
3768 
3769 	/*
3770 	 * Do not clear temp_diff.
3771 	 */
3772 	return (ISC_R_SUCCESS);
3773 }
3774 
3775 static isc_result_t
update_one_rr(dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff,dns_diffop_t op,dns_name_t * name,dns_ttl_t ttl,dns_rdata_t * rdata)3776 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3777 	      dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
3778 	      dns_rdata_t *rdata)
3779 {
3780 	dns_difftuple_t *tuple = NULL;
3781 	isc_result_t result;
3782 	result = dns_difftuple_create(diff->mctx, op,
3783 				      name, ttl, rdata, &tuple);
3784 	if (result != ISC_R_SUCCESS)
3785 		return (result);
3786 	return (do_one_tuple(&tuple, db, ver, diff));
3787 }
3788 
3789 static isc_result_t
update_soa_serial(dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff,isc_mem_t * mctx,dns_updatemethod_t method)3790 update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3791 		  isc_mem_t *mctx, dns_updatemethod_t method) {
3792 	dns_difftuple_t *deltuple = NULL;
3793 	dns_difftuple_t *addtuple = NULL;
3794 	isc_uint32_t serial;
3795 	isc_result_t result;
3796 
3797 	CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
3798 	CHECK(dns_difftuple_copy(deltuple, &addtuple));
3799 	addtuple->op = DNS_DIFFOP_ADD;
3800 
3801 	serial = dns_soa_getserial(&addtuple->rdata);
3802 	serial = dns_update_soaserial(serial, method);
3803 	dns_soa_setserial(serial, &addtuple->rdata);
3804 	CHECK(do_one_tuple(&deltuple, db, ver, diff));
3805 	CHECK(do_one_tuple(&addtuple, db, ver, diff));
3806 	result = ISC_R_SUCCESS;
3807 
3808 	failure:
3809 	if (addtuple != NULL)
3810 		dns_difftuple_free(&addtuple);
3811 	if (deltuple != NULL)
3812 		dns_difftuple_free(&deltuple);
3813 	return (result);
3814 }
3815 
3816 /*
3817  * Write all transactions in 'diff' to the zone journal file.
3818  */
3819 static isc_result_t
zone_journal(dns_zone_t * zone,dns_diff_t * diff,isc_uint32_t * sourceserial,const char * caller)3820 zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial,
3821 	     const char *caller)
3822 {
3823 	const char me[] = "zone_journal";
3824 	const char *journalfile;
3825 	isc_result_t result = ISC_R_SUCCESS;
3826 	dns_journal_t *journal = NULL;
3827 	unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE;
3828 
3829 	ENTER;
3830 	journalfile = dns_zone_getjournal(zone);
3831 	if (journalfile != NULL) {
3832 		result = dns_journal_open(zone->mctx, journalfile, mode,
3833 					  &journal);
3834 		if (result != ISC_R_SUCCESS) {
3835 			dns_zone_log(zone, ISC_LOG_ERROR,
3836 				     "%s:dns_journal_open -> %s",
3837 				     caller, dns_result_totext(result));
3838 			return (result);
3839 		}
3840 
3841 		if (sourceserial != NULL)
3842 			dns_journal_set_sourceserial(journal, *sourceserial);
3843 
3844 		result = dns_journal_write_transaction(journal, diff);
3845 		if (result != ISC_R_SUCCESS) {
3846 			dns_zone_log(zone, ISC_LOG_ERROR,
3847 				     "%s:dns_journal_write_transaction -> %s",
3848 				     caller, dns_result_totext(result));
3849 		}
3850 		dns_journal_destroy(&journal);
3851 	}
3852 
3853 	return (result);
3854 }
3855 
3856 /*
3857  * Create an SOA record for a newly-created zone
3858  */
3859 static isc_result_t
add_soa(dns_zone_t * zone,dns_db_t * db)3860 add_soa(dns_zone_t *zone, dns_db_t *db) {
3861 	isc_result_t result;
3862 	dns_rdata_t rdata = DNS_RDATA_INIT;
3863 	unsigned char buf[DNS_SOA_BUFFERSIZE];
3864 	dns_dbversion_t *ver = NULL;
3865 	dns_diff_t diff;
3866 
3867 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
3868 
3869 	dns_diff_init(zone->mctx, &diff);
3870 	result = dns_db_newversion(db, &ver);
3871 	if (result != ISC_R_SUCCESS) {
3872 		dns_zone_log(zone, ISC_LOG_ERROR,
3873 			     "add_soa:dns_db_newversion -> %s",
3874 			     dns_result_totext(result));
3875 		goto failure;
3876 	}
3877 
3878 	/* Build SOA record */
3879 	result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
3880 				    0, 0, 0, 0, 0, buf, &rdata);
3881 	if (result != ISC_R_SUCCESS) {
3882 		dns_zone_log(zone, ISC_LOG_ERROR,
3883 			     "add_soa:dns_soa_buildrdata -> %s",
3884 			     dns_result_totext(result));
3885 		goto failure;
3886 	}
3887 
3888 	result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
3889 			       &zone->origin, 0, &rdata);
3890 
3891 failure:
3892 	dns_diff_clear(&diff);
3893 	if (ver != NULL)
3894 		dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS));
3895 
3896 	INSIST(ver == NULL);
3897 
3898 	return (result);
3899 }
3900 
3901 /*
3902  * Synchronize the set of initializing keys found in managed-keys {}
3903  * statements with the set of trust anchors found in the managed-keys.bind
3904  * zone.  If a domain is no longer named in managed-keys, delete all keys
3905  * from that domain from the key zone.	If a domain is mentioned in in
3906  * managed-keys but there are no references to it in the key zone, load
3907  * the key zone with the initializing key(s) for that domain.
3908  */
3909 static isc_result_t
sync_keyzone(dns_zone_t * zone,dns_db_t * db)3910 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
3911 	isc_result_t result = ISC_R_SUCCESS;
3912 	isc_boolean_t changed = ISC_FALSE;
3913 	isc_boolean_t commit = ISC_FALSE;
3914 	dns_rbtnodechain_t chain;
3915 	dns_fixedname_t fn;
3916 	dns_name_t foundname, *origin;
3917 	dns_keynode_t *keynode = NULL;
3918 	dns_view_t *view = zone->view;
3919 	dns_keytable_t *sr = NULL;
3920 	dns_dbversion_t *ver = NULL;
3921 	dns_diff_t diff;
3922 	dns_rriterator_t rrit;
3923 
3924 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
3925 
3926 	dns_name_init(&foundname, NULL);
3927 	dns_fixedname_init(&fn);
3928 	origin = dns_fixedname_name(&fn);
3929 
3930 	dns_diff_init(zone->mctx, &diff);
3931 
3932 	CHECK(dns_view_getsecroots(view, &sr));
3933 
3934 	result = dns_db_newversion(db, &ver);
3935 	if (result != ISC_R_SUCCESS) {
3936 		dns_zone_log(zone, ISC_LOG_ERROR,
3937 			     "sync_keyzone:dns_db_newversion -> %s",
3938 			     dns_result_totext(result));
3939 		goto failure;
3940 	}
3941 
3942 	/*
3943 	 * Walk the zone DB.  If we find any keys whose names are no longer
3944 	 * in managed-keys (or *are* in trusted-keys, meaning they are
3945 	 * permanent and not RFC5011-maintained), delete them from the
3946 	 * zone.  Otherwise call load_secroots(), which loads keys into
3947 	 * secroots as appropriate.
3948 	 */
3949 	dns_rriterator_init(&rrit, db, ver, 0);
3950 	for (result = dns_rriterator_first(&rrit);
3951 	     result == ISC_R_SUCCESS;
3952 	     result = dns_rriterator_nextrrset(&rrit)) {
3953 		dns_rdataset_t *rdataset = NULL;
3954 		dns_name_t *rrname = NULL;
3955 		isc_uint32_t ttl;
3956 
3957 		dns_rriterator_current(&rrit, &rrname, &ttl,
3958 				       &rdataset, NULL);
3959 		if (!dns_rdataset_isassociated(rdataset)) {
3960 			dns_rriterator_destroy(&rrit);
3961 			goto failure;
3962 		}
3963 
3964 		if (rdataset->type != dns_rdatatype_keydata)
3965 			continue;
3966 
3967 		result = dns_keytable_find(sr, rrname, &keynode);
3968 		if ((result != ISC_R_SUCCESS &&
3969 		     result != DNS_R_PARTIALMATCH) ||
3970 		    dns_keynode_managed(keynode) == ISC_FALSE)
3971 		{
3972 			CHECK(delete_keydata(db, ver, &diff,
3973 					     rrname, rdataset));
3974 			changed = ISC_TRUE;
3975 		} else {
3976 			load_secroots(zone, rrname, rdataset);
3977 		}
3978 
3979 		if (keynode != NULL)
3980 			dns_keytable_detachkeynode(sr, &keynode);
3981 	}
3982 	dns_rriterator_destroy(&rrit);
3983 
3984 	/*
3985 	 * Now walk secroots to find any managed keys that aren't
3986 	 * in the zone.  If we find any, we add them to the zone.
3987 	 */
3988 	RWLOCK(&sr->rwlock, isc_rwlocktype_write);
3989 	dns_rbtnodechain_init(&chain, zone->mctx);
3990 	result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin);
3991 	if (result == ISC_R_NOTFOUND)
3992 		result = ISC_R_NOMORE;
3993 	while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
3994 		dns_rbtnode_t *rbtnode = NULL;
3995 
3996 		dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode);
3997 		if (rbtnode->data == NULL)
3998 			goto skip;
3999 
4000 		dns_keytable_attachkeynode(sr, rbtnode->data, &keynode);
4001 		if (dns_keynode_managed(keynode)) {
4002 			dns_fixedname_t fname;
4003 			dns_name_t *keyname;
4004 			dst_key_t *key;
4005 
4006 			key = dns_keynode_key(keynode);
4007 			dns_fixedname_init(&fname);
4008 
4009 			if (key == NULL)   /* fail_secure() was called. */
4010 				goto skip;
4011 
4012 			keyname = dst_key_name(key);
4013 			result = dns_db_find(db, keyname, ver,
4014 					     dns_rdatatype_keydata,
4015 					     DNS_DBFIND_NOWILD, 0, NULL,
4016 					     dns_fixedname_name(&fname),
4017 					     NULL, NULL);
4018 			if (result != ISC_R_SUCCESS)
4019 				result = create_keydata(zone, db, ver, &diff,
4020 							sr, &keynode, &changed);
4021 			if (result != ISC_R_SUCCESS)
4022 				break;
4023 		}
4024   skip:
4025 		result = dns_rbtnodechain_next(&chain, &foundname, origin);
4026 		if (keynode != NULL)
4027 			dns_keytable_detachkeynode(sr, &keynode);
4028 	}
4029 	RWUNLOCK(&sr->rwlock, isc_rwlocktype_write);
4030 
4031 	if (result == ISC_R_NOMORE)
4032 		result = ISC_R_SUCCESS;
4033 
4034 	if (changed) {
4035 		/* Write changes to journal file. */
4036 		CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
4037 					zone->updatemethod));
4038 		CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone"));
4039 
4040 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
4041 		zone_needdump(zone, 30);
4042 		commit = ISC_TRUE;
4043 	}
4044 
4045  failure:
4046 	if (result != ISC_R_SUCCESS &&
4047 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
4048 		dns_zone_log(zone, ISC_LOG_ERROR,
4049 			     "unable to synchronize managed keys: %s",
4050 			     dns_result_totext(result));
4051 		isc_time_settoepoch(&zone->refreshkeytime);
4052 	}
4053 	if (keynode != NULL)
4054 		dns_keytable_detachkeynode(sr, &keynode);
4055 	if (sr != NULL)
4056 		dns_keytable_detach(&sr);
4057 	if (ver != NULL)
4058 		dns_db_closeversion(db, &ver, commit);
4059 	dns_diff_clear(&diff);
4060 
4061 	INSIST(ver == NULL);
4062 
4063 	return (result);
4064 }
4065 
4066 isc_result_t
dns_zone_synckeyzone(dns_zone_t * zone)4067 dns_zone_synckeyzone(dns_zone_t *zone) {
4068 	isc_result_t result;
4069 	dns_db_t *db = NULL;
4070 
4071 	if (zone->type != dns_zone_key)
4072 		return (DNS_R_BADZONE);
4073 
4074 	CHECK(dns_zone_getdb(zone, &db));
4075 
4076 	LOCK_ZONE(zone);
4077 	result = sync_keyzone(zone, db);
4078 	UNLOCK_ZONE(zone);
4079 
4080  failure:
4081 	if (db != NULL)
4082 		dns_db_detach(&db);
4083 	return (result);
4084 }
4085 
4086 static void
maybe_send_secure(dns_zone_t * zone)4087 maybe_send_secure(dns_zone_t *zone) {
4088 	isc_result_t result;
4089 
4090 	/*
4091 	 * We've finished loading, or else failed to load, an inline-signing
4092 	 * 'secure' zone.  We now need information about the status of the
4093 	 * 'raw' zone.  If we failed to load, then we need it to send a
4094 	 * copy of its database; if we succeeded, we need it to send its
4095 	 * serial number so that we can sync with it.  If it has not yet
4096 	 * loaded, we set a flag so that it will send the necessary
4097 	 * information when it has finished loading.
4098 	 */
4099 	if (zone->raw->db != NULL) {
4100 		if (zone->db != NULL) {
4101 			isc_uint32_t serial;
4102 			unsigned int soacount;
4103 
4104 			result = zone_get_from_db(zone->raw, zone->raw->db,
4105 						  NULL, &soacount, &serial, NULL,
4106 						  NULL, NULL, NULL, NULL);
4107 			if (result == ISC_R_SUCCESS && soacount > 0U)
4108 				zone_send_secureserial(zone->raw, serial);
4109 		} else
4110 			zone_send_securedb(zone->raw, zone->raw->db);
4111 
4112 	} else
4113 		DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
4114 }
4115 
4116 static isc_boolean_t
zone_unchanged(dns_db_t * db1,dns_db_t * db2,isc_mem_t * mctx)4117 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
4118 	isc_result_t result;
4119 	isc_boolean_t answer = ISC_FALSE;
4120 	dns_diff_t diff;
4121 
4122 	dns_diff_init(mctx, &diff);
4123 	result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
4124 	if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples))
4125 		answer = ISC_TRUE;
4126 	dns_diff_clear(&diff);
4127 	return (answer);
4128 }
4129 
4130 /*
4131  * The zone is presumed to be locked.
4132  * If this is a inline_raw zone the secure version is also locked.
4133  */
4134 static isc_result_t
zone_postload(dns_zone_t * zone,dns_db_t * db,isc_time_t loadtime,isc_result_t result)4135 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
4136 	      isc_result_t result)
4137 {
4138 	unsigned int soacount = 0;
4139 	unsigned int nscount = 0;
4140 	unsigned int errors = 0;
4141 	isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
4142 	isc_time_t now;
4143 	isc_boolean_t needdump = ISC_FALSE;
4144 	isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
4145 	isc_boolean_t nomaster = ISC_FALSE;
4146 	unsigned int options;
4147 	dns_include_t *inc;
4148 
4149 	INSIST(LOCKED_ZONE(zone));
4150 	if (inline_raw(zone))
4151 		INSIST(LOCKED_ZONE(zone->secure));
4152 
4153 	TIME_NOW(&now);
4154 
4155 	/*
4156 	 * Initiate zone transfer?  We may need a error code that
4157 	 * indicates that the "permanent" form does not exist.
4158 	 * XXX better error feedback to log.
4159 	 */
4160 	if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
4161 		if (zone->type == dns_zone_slave ||
4162 		    zone->type == dns_zone_stub ||
4163 		    (zone->type == dns_zone_redirect &&
4164 		     zone->masters == NULL)) {
4165 			if (result == ISC_R_FILENOTFOUND)
4166 				dns_zone_log(zone, ISC_LOG_DEBUG(1),
4167 					     "no master file");
4168 			else if (result != DNS_R_NOMASTERFILE)
4169 				dns_zone_log(zone, ISC_LOG_ERROR,
4170 					     "loading from master file %s "
4171 					     "failed: %s",
4172 					     zone->masterfile,
4173 					     dns_result_totext(result));
4174 		} else if (zone->type == dns_zone_master &&
4175 			   inline_secure(zone) && result == ISC_R_FILENOTFOUND)
4176 		{
4177 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
4178 				     "no master file, requesting db");
4179 			maybe_send_secure(zone);
4180 		} else {
4181 			int level = ISC_LOG_ERROR;
4182 			if (zone->type == dns_zone_key &&
4183 			    result == ISC_R_FILENOTFOUND)
4184 				level = ISC_LOG_DEBUG(1);
4185 			dns_zone_log(zone, level,
4186 				     "loading from master file %s failed: %s",
4187 				     zone->masterfile,
4188 				     dns_result_totext(result));
4189 			nomaster = ISC_TRUE;
4190 		}
4191 
4192 		if (zone->type != dns_zone_key)
4193 			goto cleanup;
4194 	}
4195 
4196 	dns_zone_log(zone, ISC_LOG_DEBUG(2),
4197 		     "number of nodes in database: %u",
4198 		     dns_db_nodecount(db));
4199 
4200 	if (result == DNS_R_SEENINCLUDE)
4201 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
4202 	else
4203 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
4204 
4205 	/*
4206 	 * If there's no master file for a key zone, then the zone is new:
4207 	 * create an SOA record.  (We do this now, instead of later, so that
4208 	 * if there happens to be a journal file, we can roll forward from
4209 	 * a sane starting point.)
4210 	 */
4211 	if (nomaster && zone->type == dns_zone_key) {
4212 		result = add_soa(zone, db);
4213 		if (result != ISC_R_SUCCESS)
4214 			goto cleanup;
4215 	}
4216 
4217 	/*
4218 	 * Apply update log, if any, on initial load.
4219 	 */
4220 	if (zone->journal != NULL &&
4221 	    ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
4222 	    ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
4223 	{
4224 		if (zone->type == dns_zone_master &&
4225 		    (zone->update_acl != NULL || zone->ssutable != NULL))
4226 			options = DNS_JOURNALOPT_RESIGN;
4227 		else
4228 			options = 0;
4229 		result = dns_journal_rollforward(zone->mctx, db, options,
4230 						 zone->journal);
4231 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
4232 		    result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
4233 		    result != ISC_R_RANGE) {
4234 			dns_zone_log(zone, ISC_LOG_ERROR,
4235 				     "journal rollforward failed: %s",
4236 				     dns_result_totext(result));
4237 			goto cleanup;
4238 
4239 
4240 		}
4241 		if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
4242 			dns_zone_log(zone, ISC_LOG_ERROR,
4243 				     "journal rollforward failed: "
4244 				     "journal out of sync with zone");
4245 			goto cleanup;
4246 		}
4247 		dns_zone_log(zone, ISC_LOG_DEBUG(1),
4248 			     "journal rollforward completed "
4249 			     "successfully: %s",
4250 			     dns_result_totext(result));
4251 		if (result == ISC_R_SUCCESS)
4252 			needdump = ISC_TRUE;
4253 	}
4254 
4255 	/*
4256 	 * Obtain ns, soa and cname counts for top of zone.
4257 	 */
4258 	INSIST(db != NULL);
4259 	result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
4260 				  &refresh, &retry, &expire, &minimum,
4261 				  &errors);
4262 	if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
4263 		dns_zone_log(zone, ISC_LOG_ERROR,
4264 			     "could not find NS and/or SOA records");
4265 	}
4266 
4267 	/*
4268 	 * Check to make sure the journal is up to date, and remove the
4269 	 * journal file if it isn't, as we wouldn't be able to apply
4270 	 * updates otherwise.
4271 	 */
4272 	if (zone->journal != NULL && dns_zone_isdynamic(zone, ISC_TRUE) &&
4273 	    ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
4274 		isc_uint32_t jserial;
4275 		dns_journal_t *journal = NULL;
4276 
4277 		result = dns_journal_open(zone->mctx, zone->journal,
4278 					  DNS_JOURNAL_READ, &journal);
4279 		if (result == ISC_R_SUCCESS) {
4280 			jserial = dns_journal_last_serial(journal);
4281 			dns_journal_destroy(&journal);
4282 		} else {
4283 			jserial = serial;
4284 			result = ISC_R_SUCCESS;
4285 		}
4286 
4287 		if (jserial != serial) {
4288 			dns_zone_log(zone, ISC_LOG_INFO,
4289 				     "journal file is out of date: "
4290 				     "removing journal file");
4291 			if (remove(zone->journal) < 0 && errno != ENOENT) {
4292 				char strbuf[ISC_STRERRORSIZE];
4293 				isc__strerror(errno, strbuf, sizeof(strbuf));
4294 				isc_log_write(dns_lctx,
4295 					      DNS_LOGCATEGORY_GENERAL,
4296 					      DNS_LOGMODULE_ZONE,
4297 					      ISC_LOG_WARNING,
4298 					      "unable to remove journal "
4299 					      "'%s': '%s'",
4300 					      zone->journal, strbuf);
4301 			}
4302 		}
4303 	}
4304 
4305 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity");
4306 
4307 	/*
4308 	 * Master / Slave / Stub zones require both NS and SOA records at
4309 	 * the top of the zone.
4310 	 */
4311 
4312 	switch (zone->type) {
4313 	case dns_zone_dlz:
4314 	case dns_zone_master:
4315 	case dns_zone_slave:
4316 	case dns_zone_stub:
4317 	case dns_zone_redirect:
4318 		if (soacount != 1) {
4319 			dns_zone_log(zone, ISC_LOG_ERROR,
4320 				     "has %d SOA records", soacount);
4321 			result = DNS_R_BADZONE;
4322 		}
4323 		if (nscount == 0) {
4324 			dns_zone_log(zone, ISC_LOG_ERROR,
4325 				     "has no NS records");
4326 			result = DNS_R_BADZONE;
4327 		}
4328 		if (result != ISC_R_SUCCESS)
4329 			goto cleanup;
4330 		if (zone->type == dns_zone_master && errors != 0) {
4331 			result = DNS_R_BADZONE;
4332 			goto cleanup;
4333 		}
4334 		if (zone->type != dns_zone_stub &&
4335 		    zone->type != dns_zone_redirect) {
4336 			result = check_nsec3param(zone, db);
4337 			if (result != ISC_R_SUCCESS)
4338 				goto cleanup;
4339 		}
4340 		if (zone->type == dns_zone_master &&
4341 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
4342 		    !integrity_checks(zone, db)) {
4343 			result = DNS_R_BADZONE;
4344 			goto cleanup;
4345 		}
4346 		if (zone->type == dns_zone_master &&
4347 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
4348 		    !zone_check_dup(zone, db)) {
4349 			result = DNS_R_BADZONE;
4350 			goto cleanup;
4351 		}
4352 
4353 		if (zone->db != NULL) {
4354 			unsigned int oldsoacount;
4355 
4356 			/*
4357 			 * This is checked in zone_replacedb() for slave zones
4358 			 * as they don't reload from disk.
4359 			 */
4360 			result = zone_get_from_db(zone, zone->db, NULL,
4361 						  &oldsoacount, &oldserial,
4362 						  NULL, NULL, NULL, NULL,
4363 						  NULL);
4364 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
4365 			RUNTIME_CHECK(soacount > 0U);
4366 			if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
4367 			    !isc_serial_gt(serial, oldserial)) {
4368 				isc_uint32_t serialmin, serialmax;
4369 
4370 				INSIST(zone->type == dns_zone_master);
4371 
4372 				if (serial == oldserial &&
4373 				    zone_unchanged(zone->db, db, zone->mctx)) {
4374 					dns_zone_log(zone, ISC_LOG_INFO,
4375 						     "ixfr-from-differences: "
4376 						     "unchanged");
4377 					return(ISC_R_SUCCESS);
4378 				}
4379 
4380 				serialmin = (oldserial + 1) & 0xffffffffU;
4381 				serialmax = (oldserial + 0x7fffffffU) &
4382 					     0xffffffffU;
4383 				dns_zone_log(zone, ISC_LOG_ERROR,
4384 					     "ixfr-from-differences: "
4385 					     "new serial (%u) out of range "
4386 					     "[%u - %u]", serial, serialmin,
4387 					     serialmax);
4388 				result = DNS_R_BADZONE;
4389 				goto cleanup;
4390 			} else if (!isc_serial_ge(serial, oldserial))
4391 				dns_zone_log(zone, ISC_LOG_ERROR,
4392 					     "zone serial (%u/%u) has gone "
4393 					     "backwards", serial, oldserial);
4394 			else if (serial == oldserial && !hasinclude &&
4395 				 strcmp(zone->db_argv[0], "_builtin") != 0)
4396 				dns_zone_log(zone, ISC_LOG_ERROR,
4397 					     "zone serial (%u) unchanged. "
4398 					     "zone may fail to transfer "
4399 					     "to slaves.", serial);
4400 		}
4401 
4402 		if (zone->type == dns_zone_master &&
4403 		    (zone->update_acl != NULL || zone->ssutable != NULL) &&
4404 		    zone->sigresigninginterval < (3 * refresh) &&
4405 		    dns_db_issecure(db))
4406 		{
4407 			dns_zone_log(zone, ISC_LOG_WARNING,
4408 				     "sig-re-signing-interval less than "
4409 				     "3 * refresh.");
4410 		}
4411 
4412 		zone->refresh = RANGE(refresh,
4413 				      zone->minrefresh, zone->maxrefresh);
4414 		zone->retry = RANGE(retry,
4415 				    zone->minretry, zone->maxretry);
4416 		zone->expire = RANGE(expire, zone->refresh + zone->retry,
4417 				     DNS_MAX_EXPIRE);
4418 		zone->minimum = minimum;
4419 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
4420 
4421 		if (zone->type == dns_zone_slave ||
4422 		    zone->type == dns_zone_stub ||
4423 		    (zone->type == dns_zone_redirect &&
4424 		     zone->masters != NULL)) {
4425 			isc_time_t t;
4426 			isc_uint32_t delay;
4427 
4428 			result = isc_file_getmodtime(zone->journal, &t);
4429 			if (result != ISC_R_SUCCESS)
4430 				result = isc_file_getmodtime(zone->masterfile,
4431 							     &t);
4432 			if (result == ISC_R_SUCCESS)
4433 				DNS_ZONE_TIME_ADD(&t, zone->expire,
4434 						  &zone->expiretime);
4435 			else
4436 				DNS_ZONE_TIME_ADD(&now, zone->retry,
4437 						  &zone->expiretime);
4438 
4439 			delay = isc_random_jitter(zone->retry,
4440 						  (zone->retry * 3) / 4);
4441 			DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
4442 			if (isc_time_compare(&zone->refreshtime,
4443 					     &zone->expiretime) >= 0)
4444 				zone->refreshtime = now;
4445 		}
4446 
4447 		break;
4448 
4449 	case dns_zone_key:
4450 		result = sync_keyzone(zone, db);
4451 		if (result != ISC_R_SUCCESS)
4452 			goto cleanup;
4453 		break;
4454 
4455 	default:
4456 		UNEXPECTED_ERROR(__FILE__, __LINE__,
4457 				 "unexpected zone type %d", zone->type);
4458 		result = ISC_R_UNEXPECTED;
4459 		goto cleanup;
4460 	}
4461 
4462 	/*
4463 	 * Check for weak DNSKEY's.
4464 	 */
4465 	if (zone->type == dns_zone_master)
4466 		zone_check_dnskeys(zone, db);
4467 
4468 	/*
4469 	 * Schedule DNSSEC key refresh.
4470 	 */
4471 	if (zone->type == dns_zone_master &&
4472 	    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
4473 		zone->refreshkeytime = now;
4474 
4475 #if 0
4476 	/* destroy notification example. */
4477 	{
4478 		isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
4479 						    DNS_EVENT_DBDESTROYED,
4480 						    dns_zonemgr_dbdestroyed,
4481 						    zone,
4482 						    sizeof(isc_event_t));
4483 		dns_db_ondestroy(db, zone->task, &e);
4484 	}
4485 #endif
4486 
4487 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
4488 	if (zone->db != NULL) {
4489 		result = zone_replacedb(zone, db, ISC_FALSE);
4490 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4491 		if (result != ISC_R_SUCCESS)
4492 			goto cleanup;
4493 	} else {
4494 		result = dns_db_rpz_ready(db);
4495 		if (result != ISC_R_SUCCESS)
4496 			goto cleanup;
4497 		zone_attachdb(zone, db);
4498 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4499 		DNS_ZONE_SETFLAG(zone,
4500 				 DNS_ZONEFLG_LOADED|
4501 				 DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
4502 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
4503 		    inline_raw(zone))
4504 		{
4505 			if (zone->secure->db == NULL)
4506 				zone_send_securedb(zone, db);
4507 			else
4508 				zone_send_secureserial(zone, serial);
4509 		}
4510 	}
4511 
4512 	/*
4513 	 * Finished loading inline-signing zone; need to get status
4514 	 * from the raw side now.
4515 	 */
4516 	if (zone->type == dns_zone_master && inline_secure(zone))
4517 		maybe_send_secure(zone);
4518 
4519 
4520 	result = ISC_R_SUCCESS;
4521 
4522 	if (needdump) {
4523 		if (zone->type == dns_zone_key)
4524 			zone_needdump(zone, 30);
4525 		else
4526 			zone_needdump(zone, DNS_DUMP_DELAY);
4527 	}
4528 
4529 	if (zone->task != NULL) {
4530 		if (zone->type == dns_zone_master) {
4531 			set_resigntime(zone);
4532 			resume_signingwithkey(zone);
4533 			resume_addnsec3chain(zone);
4534 		}
4535 
4536 		if (zone->type == dns_zone_master &&
4537 		    !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
4538 		    dns_zone_isdynamic(zone, ISC_FALSE) &&
4539 		    dns_db_issecure(db)) {
4540 			dns_name_t *name;
4541 			dns_fixedname_t fixed;
4542 			dns_rdataset_t next;
4543 
4544 			dns_rdataset_init(&next);
4545 			dns_fixedname_init(&fixed);
4546 			name = dns_fixedname_name(&fixed);
4547 
4548 			result = dns_db_getsigningtime(db, &next, name);
4549 			if (result == ISC_R_SUCCESS) {
4550 				isc_stdtime_t timenow;
4551 				char namebuf[DNS_NAME_FORMATSIZE];
4552 				char typebuf[DNS_RDATATYPE_FORMATSIZE];
4553 
4554 				isc_stdtime_get(&timenow);
4555 				dns_name_format(name, namebuf, sizeof(namebuf));
4556 				dns_rdatatype_format(next.covers,
4557 						     typebuf, sizeof(typebuf));
4558 				dns_zone_log(zone, ISC_LOG_DEBUG(3),
4559 					     "next resign: %s/%s in %d seconds",
4560 					     namebuf, typebuf,
4561 					     next.resign - timenow -
4562 					     zone->sigresigninginterval);
4563 				dns_rdataset_disassociate(&next);
4564 			} else
4565 				dns_zone_log(zone, ISC_LOG_WARNING,
4566 					     "signed dynamic zone has no "
4567 					     "resign event scheduled");
4568 		}
4569 
4570 		zone_settimer(zone, &now);
4571 	}
4572 
4573 	/*
4574 	 * Clear old include list.
4575 	 */
4576 	for (inc = ISC_LIST_HEAD(zone->includes);
4577 	     inc != NULL;
4578 	     inc = ISC_LIST_HEAD(zone->includes)) {
4579 		ISC_LIST_UNLINK(zone->includes, inc, link);
4580 		isc_mem_free(zone->mctx, inc->name);
4581 		isc_mem_put(zone->mctx, inc, sizeof(*inc));
4582 	}
4583 	zone->nincludes = 0;
4584 
4585 	/*
4586 	 * Transfer new include list.
4587 	 */
4588 	for (inc = ISC_LIST_HEAD(zone->newincludes);
4589 	     inc != NULL;
4590 	     inc = ISC_LIST_HEAD(zone->newincludes)) {
4591 		ISC_LIST_UNLINK(zone->newincludes, inc, link);
4592 		ISC_LIST_APPEND(zone->includes, inc, link);
4593 		zone->nincludes++;
4594 	}
4595 
4596 	if (! dns_db_ispersistent(db))
4597 		dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
4598 			     dns_db_issecure(db) ? " (DNSSEC signed)" : "");
4599 
4600 	zone->loadtime = loadtime;
4601 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
4602 	return (result);
4603 
4604  cleanup:
4605 	for (inc = ISC_LIST_HEAD(zone->newincludes);
4606 	     inc != NULL;
4607 	     inc = ISC_LIST_HEAD(zone->newincludes)) {
4608 		ISC_LIST_UNLINK(zone->newincludes, inc, link);
4609 		isc_mem_free(zone->mctx, inc->name);
4610 		isc_mem_put(zone->mctx, inc, sizeof(*inc));
4611 	}
4612 	if (zone->type == dns_zone_slave ||
4613 	    zone->type == dns_zone_stub ||
4614 	    zone->type == dns_zone_key ||
4615 	    (zone->type == dns_zone_redirect && zone->masters != NULL)) {
4616 		if (zone->journal != NULL)
4617 			zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
4618 		if (zone->masterfile != NULL)
4619 			zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
4620 
4621 		/* Mark the zone for immediate refresh. */
4622 		zone->refreshtime = now;
4623 		if (zone->task != NULL)
4624 			zone_settimer(zone, &now);
4625 		result = ISC_R_SUCCESS;
4626 	} else if (zone->type == dns_zone_master ||
4627 		   zone->type == dns_zone_redirect) {
4628 		if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND))
4629 			dns_zone_log(zone, ISC_LOG_ERROR,
4630 				     "not loaded due to errors.");
4631 		else if (zone->type == dns_zone_master)
4632 			result = ISC_R_SUCCESS;
4633 	}
4634 
4635 	return (result);
4636 }
4637 
4638 static isc_boolean_t
exit_check(dns_zone_t * zone)4639 exit_check(dns_zone_t *zone) {
4640 	REQUIRE(LOCKED_ZONE(zone));
4641 
4642 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->irefs == 0) {
4643 		/*
4644 		 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
4645 		 */
4646 		INSIST(isc_refcount_current(&zone->erefs) == 0);
4647 		return (ISC_TRUE);
4648 	}
4649 	return (ISC_FALSE);
4650 }
4651 
4652 static isc_boolean_t
zone_check_ns(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * version,dns_name_t * name,isc_boolean_t logit)4653 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
4654 	      dns_name_t *name, isc_boolean_t logit)
4655 {
4656 	isc_result_t result;
4657 	char namebuf[DNS_NAME_FORMATSIZE];
4658 	char altbuf[DNS_NAME_FORMATSIZE];
4659 	dns_fixedname_t fixed;
4660 	dns_name_t *foundname;
4661 	int level;
4662 
4663 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
4664 		return (ISC_TRUE);
4665 
4666 	if (zone->type == dns_zone_master)
4667 		level = ISC_LOG_ERROR;
4668 	else
4669 		level = ISC_LOG_WARNING;
4670 
4671 	dns_fixedname_init(&fixed);
4672 	foundname = dns_fixedname_name(&fixed);
4673 
4674 	result = dns_db_find(db, name, version, dns_rdatatype_a,
4675 			     0, 0, NULL, foundname, NULL, NULL);
4676 	if (result == ISC_R_SUCCESS)
4677 		return (ISC_TRUE);
4678 
4679 	if (result == DNS_R_NXRRSET) {
4680 		result = dns_db_find(db, name, version, dns_rdatatype_aaaa,
4681 				     0, 0, NULL, foundname, NULL, NULL);
4682 		if (result == ISC_R_SUCCESS)
4683 			return (ISC_TRUE);
4684 	}
4685 
4686 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
4687 	    result == DNS_R_EMPTYNAME) {
4688 		if (logit) {
4689 			dns_name_format(name, namebuf, sizeof namebuf);
4690 			dns_zone_log(zone, level, "NS '%s' has no address "
4691 				     "records (A or AAAA)", namebuf);
4692 		}
4693 		return (ISC_FALSE);
4694 	}
4695 
4696 	if (result == DNS_R_CNAME) {
4697 		if (logit) {
4698 			dns_name_format(name, namebuf, sizeof namebuf);
4699 			dns_zone_log(zone, level, "NS '%s' is a CNAME "
4700 				     "(illegal)", namebuf);
4701 		}
4702 		return (ISC_FALSE);
4703 	}
4704 
4705 	if (result == DNS_R_DNAME) {
4706 		if (logit) {
4707 			dns_name_format(name, namebuf, sizeof namebuf);
4708 			dns_name_format(foundname, altbuf, sizeof altbuf);
4709 			dns_zone_log(zone, level, "NS '%s' is below a DNAME "
4710 				     "'%s' (illegal)", namebuf, altbuf);
4711 		}
4712 		return (ISC_FALSE);
4713 	}
4714 
4715 	return (ISC_TRUE);
4716 }
4717 
4718 static isc_result_t
zone_count_ns_rr(dns_zone_t * zone,dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,unsigned int * nscount,unsigned int * errors,isc_boolean_t logit)4719 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
4720 		 dns_dbversion_t *version, unsigned int *nscount,
4721 		 unsigned int *errors, isc_boolean_t logit)
4722 {
4723 	isc_result_t result;
4724 	unsigned int count = 0;
4725 	unsigned int ecount = 0;
4726 	dns_rdataset_t rdataset;
4727 	dns_rdata_t rdata;
4728 	dns_rdata_ns_t ns;
4729 
4730 	dns_rdataset_init(&rdataset);
4731 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
4732 				     dns_rdatatype_none, 0, &rdataset, NULL);
4733 	if (result == ISC_R_NOTFOUND) {
4734 		INSIST(!dns_rdataset_isassociated(&rdataset));
4735 		goto success;
4736 	}
4737 	if (result != ISC_R_SUCCESS) {
4738 		INSIST(!dns_rdataset_isassociated(&rdataset));
4739 		goto invalidate_rdataset;
4740 	}
4741 
4742 	result = dns_rdataset_first(&rdataset);
4743 	while (result == ISC_R_SUCCESS) {
4744 		if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
4745 		    (zone->type == dns_zone_master ||
4746 		     zone->type == dns_zone_slave)) {
4747 			dns_rdata_init(&rdata);
4748 			dns_rdataset_current(&rdataset, &rdata);
4749 			result = dns_rdata_tostruct(&rdata, &ns, NULL);
4750 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
4751 			if (dns_name_issubdomain(&ns.name, &zone->origin) &&
4752 			    !zone_check_ns(zone, db, version, &ns.name, logit))
4753 				ecount++;
4754 		}
4755 		count++;
4756 		result = dns_rdataset_next(&rdataset);
4757 	}
4758 	dns_rdataset_disassociate(&rdataset);
4759 
4760  success:
4761 	if (nscount != NULL)
4762 		*nscount = count;
4763 	if (errors != NULL)
4764 		*errors = ecount;
4765 
4766 	result = ISC_R_SUCCESS;
4767 
4768  invalidate_rdataset:
4769 	dns_rdataset_invalidate(&rdataset);
4770 
4771 	return (result);
4772 }
4773 
4774 static isc_result_t
zone_load_soa_rr(dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,unsigned int * soacount,isc_uint32_t * serial,isc_uint32_t * refresh,isc_uint32_t * retry,isc_uint32_t * expire,isc_uint32_t * minimum)4775 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
4776 		 unsigned int *soacount,
4777 		 isc_uint32_t *serial, isc_uint32_t *refresh,
4778 		 isc_uint32_t *retry, isc_uint32_t *expire,
4779 		 isc_uint32_t *minimum)
4780 {
4781 	isc_result_t result;
4782 	unsigned int count;
4783 	dns_rdataset_t rdataset;
4784 	dns_rdata_t rdata = DNS_RDATA_INIT;
4785 	dns_rdata_soa_t soa;
4786 
4787 	dns_rdataset_init(&rdataset);
4788 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
4789 				     dns_rdatatype_none, 0, &rdataset, NULL);
4790 	if (result == ISC_R_NOTFOUND) {
4791 		INSIST(!dns_rdataset_isassociated(&rdataset));
4792 		if (soacount != NULL)
4793 			*soacount = 0;
4794 		if (serial != NULL)
4795 			*serial = 0;
4796 		if (refresh != NULL)
4797 			*refresh = 0;
4798 		if (retry != NULL)
4799 			*retry = 0;
4800 		if (expire != NULL)
4801 			*expire = 0;
4802 		if (minimum != NULL)
4803 			*minimum = 0;
4804 		result = ISC_R_SUCCESS;
4805 		goto invalidate_rdataset;
4806 	}
4807 	if (result != ISC_R_SUCCESS) {
4808 		INSIST(!dns_rdataset_isassociated(&rdataset));
4809 		goto invalidate_rdataset;
4810 	}
4811 
4812 	count = 0;
4813 	result = dns_rdataset_first(&rdataset);
4814 	while (result == ISC_R_SUCCESS) {
4815 		dns_rdata_init(&rdata);
4816 		dns_rdataset_current(&rdataset, &rdata);
4817 		count++;
4818 		if (count == 1) {
4819 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
4820 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
4821 		}
4822 
4823 		result = dns_rdataset_next(&rdataset);
4824 		dns_rdata_reset(&rdata);
4825 	}
4826 	dns_rdataset_disassociate(&rdataset);
4827 
4828 	if (soacount != NULL)
4829 		*soacount = count;
4830 
4831 	if (count > 0) {
4832 		if (serial != NULL)
4833 			*serial = soa.serial;
4834 		if (refresh != NULL)
4835 			*refresh = soa.refresh;
4836 		if (retry != NULL)
4837 			*retry = soa.retry;
4838 		if (expire != NULL)
4839 			*expire = soa.expire;
4840 		if (minimum != NULL)
4841 			*minimum = soa.minimum;
4842 	} else {
4843 		if (soacount != NULL)
4844 			*soacount = 0;
4845 		if (serial != NULL)
4846 			*serial = 0;
4847 		if (refresh != NULL)
4848 			*refresh = 0;
4849 		if (retry != NULL)
4850 			*retry = 0;
4851 		if (expire != NULL)
4852 			*expire = 0;
4853 		if (minimum != NULL)
4854 			*minimum = 0;
4855 	}
4856 
4857 	result = ISC_R_SUCCESS;
4858 
4859  invalidate_rdataset:
4860 	dns_rdataset_invalidate(&rdataset);
4861 
4862 	return (result);
4863 }
4864 
4865 /*
4866  * zone must be locked.
4867  */
4868 static isc_result_t
zone_get_from_db(dns_zone_t * zone,dns_db_t * db,unsigned int * nscount,unsigned int * soacount,isc_uint32_t * serial,isc_uint32_t * refresh,isc_uint32_t * retry,isc_uint32_t * expire,isc_uint32_t * minimum,unsigned int * errors)4869 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
4870 		 unsigned int *soacount, isc_uint32_t *serial,
4871 		 isc_uint32_t *refresh, isc_uint32_t *retry,
4872 		 isc_uint32_t *expire, isc_uint32_t *minimum,
4873 		 unsigned int *errors)
4874 {
4875 	isc_result_t result;
4876 	isc_result_t answer = ISC_R_SUCCESS;
4877 	dns_dbversion_t *version = NULL;
4878 	dns_dbnode_t *node;
4879 
4880 	REQUIRE(db != NULL);
4881 	REQUIRE(zone != NULL);
4882 
4883 	dns_db_currentversion(db, &version);
4884 
4885 	if (nscount != NULL)
4886 		*nscount = 0;
4887 	if (soacount != NULL)
4888 		*soacount = 0;
4889 	if (serial != NULL)
4890 		*serial = 0;
4891 	if (refresh != NULL)
4892 		*refresh = 0;
4893 	if (retry != NULL)
4894 		*retry = 0;
4895 	if (expire != NULL)
4896 		*expire = 0;
4897 	if (errors != NULL)
4898 		*errors = 0;
4899 
4900 	node = NULL;
4901 	result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
4902 	if (result != ISC_R_SUCCESS) {
4903 		answer = result;
4904 		goto closeversion;
4905 	}
4906 
4907 	if (nscount != NULL || errors != NULL) {
4908 		result = zone_count_ns_rr(zone, db, node, version,
4909 					  nscount, errors, ISC_TRUE);
4910 		if (result != ISC_R_SUCCESS)
4911 			answer = result;
4912 	}
4913 
4914 	if (soacount != NULL || serial != NULL || refresh != NULL
4915 	    || retry != NULL || expire != NULL || minimum != NULL) {
4916 		result = zone_load_soa_rr(db, node, version, soacount,
4917 					  serial, refresh, retry, expire,
4918 					  minimum);
4919 		if (result != ISC_R_SUCCESS)
4920 			answer = result;
4921 	}
4922 
4923 	dns_db_detachnode(db, &node);
4924  closeversion:
4925 	dns_db_closeversion(db, &version, ISC_FALSE);
4926 
4927 	return (answer);
4928 }
4929 
4930 void
dns_zone_attach(dns_zone_t * source,dns_zone_t ** target)4931 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
4932 	REQUIRE(DNS_ZONE_VALID(source));
4933 	REQUIRE(target != NULL && *target == NULL);
4934 	isc_refcount_increment(&source->erefs, NULL);
4935 	*target = source;
4936 }
4937 
4938 void
dns_zone_detach(dns_zone_t ** zonep)4939 dns_zone_detach(dns_zone_t **zonep) {
4940 	dns_zone_t *zone;
4941 	dns_zone_t *raw = NULL;
4942 	dns_zone_t *secure = NULL;
4943 	unsigned int refs;
4944 	isc_boolean_t free_now = ISC_FALSE;
4945 
4946 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4947 
4948 	zone = *zonep;
4949 
4950 	isc_refcount_decrement(&zone->erefs, &refs);
4951 
4952 	if (refs == 0) {
4953 		LOCK_ZONE(zone);
4954 		INSIST(zone != zone->raw);
4955 		/*
4956 		 * We just detached the last external reference.
4957 		 */
4958 		if (zone->task != NULL) {
4959 			/*
4960 			 * This zone is being managed.	Post
4961 			 * its control event and let it clean
4962 			 * up synchronously in the context of
4963 			 * its task.
4964 			 */
4965 			isc_event_t *ev = &zone->ctlevent;
4966 			isc_task_send(zone->task, &ev);
4967 		} else {
4968 			/*
4969 			 * This zone is not being managed; it has
4970 			 * no task and can have no outstanding
4971 			 * events.  Free it immediately.
4972 			 */
4973 			/*
4974 			 * Unmanaged zones should not have non-null views;
4975 			 * we have no way of detaching from the view here
4976 			 * without causing deadlock because this code is called
4977 			 * with the view already locked.
4978 			 */
4979 			INSIST(zone->view == NULL);
4980 			free_now = ISC_TRUE;
4981 			raw = zone->raw;
4982 			zone->raw = NULL;
4983 			secure = zone->secure;
4984 			zone->secure = NULL;
4985 		}
4986 		UNLOCK_ZONE(zone);
4987 	}
4988 	*zonep = NULL;
4989 	if (free_now) {
4990 		if (raw != NULL)
4991 			dns_zone_detach(&raw);
4992 		if (secure != NULL)
4993 			dns_zone_idetach(&secure);
4994 		zone_free(zone);
4995 	}
4996 }
4997 
4998 void
dns_zone_iattach(dns_zone_t * source,dns_zone_t ** target)4999 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
5000 	REQUIRE(DNS_ZONE_VALID(source));
5001 	REQUIRE(target != NULL && *target == NULL);
5002 	LOCK_ZONE(source);
5003 	zone_iattach(source, target);
5004 	UNLOCK_ZONE(source);
5005 }
5006 
5007 static void
zone_iattach(dns_zone_t * source,dns_zone_t ** target)5008 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
5009 
5010 	/*
5011 	 * 'source' locked by caller.
5012 	 */
5013 	REQUIRE(LOCKED_ZONE(source));
5014 	REQUIRE(DNS_ZONE_VALID(source));
5015 	REQUIRE(target != NULL && *target == NULL);
5016 	INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
5017 	source->irefs++;
5018 	INSIST(source->irefs != 0);
5019 	*target = source;
5020 }
5021 
5022 static void
zone_idetach(dns_zone_t ** zonep)5023 zone_idetach(dns_zone_t **zonep) {
5024 	dns_zone_t *zone;
5025 
5026 	/*
5027 	 * 'zone' locked by caller.
5028 	 */
5029 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
5030 	zone = *zonep;
5031 	REQUIRE(LOCKED_ZONE(*zonep));
5032 	*zonep = NULL;
5033 
5034 	INSIST(zone->irefs > 0);
5035 	zone->irefs--;
5036 	INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
5037 }
5038 
5039 void
dns_zone_idetach(dns_zone_t ** zonep)5040 dns_zone_idetach(dns_zone_t **zonep) {
5041 	dns_zone_t *zone;
5042 	isc_boolean_t free_needed;
5043 
5044 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
5045 	zone = *zonep;
5046 	*zonep = NULL;
5047 
5048 	LOCK_ZONE(zone);
5049 	INSIST(zone->irefs > 0);
5050 	zone->irefs--;
5051 	free_needed = exit_check(zone);
5052 	UNLOCK_ZONE(zone);
5053 	if (free_needed)
5054 		zone_free(zone);
5055 }
5056 
5057 isc_mem_t *
dns_zone_getmctx(dns_zone_t * zone)5058 dns_zone_getmctx(dns_zone_t *zone) {
5059 	REQUIRE(DNS_ZONE_VALID(zone));
5060 
5061 	return (zone->mctx);
5062 }
5063 
5064 dns_zonemgr_t *
dns_zone_getmgr(dns_zone_t * zone)5065 dns_zone_getmgr(dns_zone_t *zone) {
5066 	REQUIRE(DNS_ZONE_VALID(zone));
5067 
5068 	return (zone->zmgr);
5069 }
5070 
5071 void
dns_zone_setflag(dns_zone_t * zone,unsigned int flags,isc_boolean_t value)5072 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
5073 	REQUIRE(DNS_ZONE_VALID(zone));
5074 
5075 	LOCK_ZONE(zone);
5076 	if (value)
5077 		DNS_ZONE_SETFLAG(zone, flags);
5078 	else
5079 		DNS_ZONE_CLRFLAG(zone, flags);
5080 	UNLOCK_ZONE(zone);
5081 }
5082 
5083 void
dns_zone_setoption(dns_zone_t * zone,unsigned int option,isc_boolean_t value)5084 dns_zone_setoption(dns_zone_t *zone, unsigned int option,
5085 		   isc_boolean_t value)
5086 {
5087 	REQUIRE(DNS_ZONE_VALID(zone));
5088 
5089 	LOCK_ZONE(zone);
5090 	if (value)
5091 		zone->options |= option;
5092 	else
5093 		zone->options &= ~option;
5094 	UNLOCK_ZONE(zone);
5095 }
5096 
5097 void
dns_zone_setoption2(dns_zone_t * zone,unsigned int option,isc_boolean_t value)5098 dns_zone_setoption2(dns_zone_t *zone, unsigned int option,
5099 		    isc_boolean_t value)
5100 {
5101 	REQUIRE(DNS_ZONE_VALID(zone));
5102 
5103 	LOCK_ZONE(zone);
5104 	if (value)
5105 		zone->options2 |= option;
5106 	else
5107 		zone->options2 &= ~option;
5108 	UNLOCK_ZONE(zone);
5109 }
5110 
5111 unsigned int
dns_zone_getoptions(dns_zone_t * zone)5112 dns_zone_getoptions(dns_zone_t *zone) {
5113 	REQUIRE(DNS_ZONE_VALID(zone));
5114 
5115 	return (zone->options);
5116 }
5117 
5118 unsigned int
dns_zone_getoptions2(dns_zone_t * zone)5119 dns_zone_getoptions2(dns_zone_t *zone) {
5120 	REQUIRE(DNS_ZONE_VALID(zone));
5121 
5122 	return (zone->options2);
5123 }
5124 
5125 void
dns_zone_setkeyopt(dns_zone_t * zone,unsigned int keyopt,isc_boolean_t value)5126 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value)
5127 {
5128 	REQUIRE(DNS_ZONE_VALID(zone));
5129 
5130 	LOCK_ZONE(zone);
5131 	if (value)
5132 		zone->keyopts |= keyopt;
5133 	else
5134 		zone->keyopts &= ~keyopt;
5135 	UNLOCK_ZONE(zone);
5136 }
5137 
5138 unsigned int
dns_zone_getkeyopts(dns_zone_t * zone)5139 dns_zone_getkeyopts(dns_zone_t *zone) {
5140 
5141 	REQUIRE(DNS_ZONE_VALID(zone));
5142 
5143 	return (zone->keyopts);
5144 }
5145 
5146 isc_result_t
dns_zone_setxfrsource4(dns_zone_t * zone,const isc_sockaddr_t * xfrsource)5147 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
5148 	REQUIRE(DNS_ZONE_VALID(zone));
5149 
5150 	LOCK_ZONE(zone);
5151 	zone->xfrsource4 = *xfrsource;
5152 	UNLOCK_ZONE(zone);
5153 
5154 	return (ISC_R_SUCCESS);
5155 }
5156 
5157 isc_sockaddr_t *
dns_zone_getxfrsource4(dns_zone_t * zone)5158 dns_zone_getxfrsource4(dns_zone_t *zone) {
5159 	REQUIRE(DNS_ZONE_VALID(zone));
5160 	return (&zone->xfrsource4);
5161 }
5162 
5163 isc_result_t
dns_zone_setxfrsource4dscp(dns_zone_t * zone,isc_dscp_t dscp)5164 dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5165 	REQUIRE(DNS_ZONE_VALID(zone));
5166 
5167 	LOCK_ZONE(zone);
5168 	zone->xfrsource4dscp = dscp;
5169 	UNLOCK_ZONE(zone);
5170 
5171 	return (ISC_R_SUCCESS);
5172 }
5173 
5174 isc_dscp_t
dns_zone_getxfrsource4dscp(dns_zone_t * zone)5175 dns_zone_getxfrsource4dscp(dns_zone_t *zone) {
5176 	REQUIRE(DNS_ZONE_VALID(zone));
5177 	return (zone->xfrsource4dscp);
5178 }
5179 
5180 isc_result_t
dns_zone_setxfrsource6(dns_zone_t * zone,const isc_sockaddr_t * xfrsource)5181 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
5182 	REQUIRE(DNS_ZONE_VALID(zone));
5183 
5184 	LOCK_ZONE(zone);
5185 	zone->xfrsource6 = *xfrsource;
5186 	UNLOCK_ZONE(zone);
5187 
5188 	return (ISC_R_SUCCESS);
5189 }
5190 
5191 isc_sockaddr_t *
dns_zone_getxfrsource6(dns_zone_t * zone)5192 dns_zone_getxfrsource6(dns_zone_t *zone) {
5193 	REQUIRE(DNS_ZONE_VALID(zone));
5194 	return (&zone->xfrsource6);
5195 }
5196 
5197 isc_dscp_t
dns_zone_getxfrsource6dscp(dns_zone_t * zone)5198 dns_zone_getxfrsource6dscp(dns_zone_t *zone) {
5199 	REQUIRE(DNS_ZONE_VALID(zone));
5200 	return (zone->xfrsource6dscp);
5201 }
5202 
5203 isc_result_t
dns_zone_setxfrsource6dscp(dns_zone_t * zone,isc_dscp_t dscp)5204 dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5205 	REQUIRE(DNS_ZONE_VALID(zone));
5206 
5207 	LOCK_ZONE(zone);
5208 	zone->xfrsource6dscp = dscp;
5209 	UNLOCK_ZONE(zone);
5210 
5211 	return (ISC_R_SUCCESS);
5212 }
5213 
5214 isc_result_t
dns_zone_setaltxfrsource4(dns_zone_t * zone,const isc_sockaddr_t * altxfrsource)5215 dns_zone_setaltxfrsource4(dns_zone_t *zone,
5216 			  const isc_sockaddr_t *altxfrsource)
5217 {
5218 	REQUIRE(DNS_ZONE_VALID(zone));
5219 
5220 	LOCK_ZONE(zone);
5221 	zone->altxfrsource4 = *altxfrsource;
5222 	UNLOCK_ZONE(zone);
5223 
5224 	return (ISC_R_SUCCESS);
5225 }
5226 
5227 isc_sockaddr_t *
dns_zone_getaltxfrsource4(dns_zone_t * zone)5228 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
5229 	REQUIRE(DNS_ZONE_VALID(zone));
5230 	return (&zone->altxfrsource4);
5231 }
5232 
5233 isc_result_t
dns_zone_setaltxfrsource4dscp(dns_zone_t * zone,isc_dscp_t dscp)5234 dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5235 	REQUIRE(DNS_ZONE_VALID(zone));
5236 
5237 	LOCK_ZONE(zone);
5238 	zone->altxfrsource4dscp = dscp;
5239 	UNLOCK_ZONE(zone);
5240 
5241 	return (ISC_R_SUCCESS);
5242 }
5243 
5244 isc_dscp_t
dns_zone_getaltxfrsource4dscp(dns_zone_t * zone)5245 dns_zone_getaltxfrsource4dscp(dns_zone_t *zone) {
5246 	REQUIRE(DNS_ZONE_VALID(zone));
5247 	return (zone->altxfrsource4dscp);
5248 }
5249 
5250 isc_result_t
dns_zone_setaltxfrsource6(dns_zone_t * zone,const isc_sockaddr_t * altxfrsource)5251 dns_zone_setaltxfrsource6(dns_zone_t *zone,
5252 			  const isc_sockaddr_t *altxfrsource)
5253 {
5254 	REQUIRE(DNS_ZONE_VALID(zone));
5255 
5256 	LOCK_ZONE(zone);
5257 	zone->altxfrsource6 = *altxfrsource;
5258 	UNLOCK_ZONE(zone);
5259 
5260 	return (ISC_R_SUCCESS);
5261 }
5262 
5263 isc_sockaddr_t *
dns_zone_getaltxfrsource6(dns_zone_t * zone)5264 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
5265 	REQUIRE(DNS_ZONE_VALID(zone));
5266 	return (&zone->altxfrsource6);
5267 }
5268 
5269 isc_result_t
dns_zone_setaltxfrsource6dscp(dns_zone_t * zone,isc_dscp_t dscp)5270 dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5271 	REQUIRE(DNS_ZONE_VALID(zone));
5272 
5273 	LOCK_ZONE(zone);
5274 	zone->altxfrsource6dscp = dscp;
5275 	UNLOCK_ZONE(zone);
5276 
5277 	return (ISC_R_SUCCESS);
5278 }
5279 
5280 isc_dscp_t
dns_zone_getaltxfrsource6dscp(dns_zone_t * zone)5281 dns_zone_getaltxfrsource6dscp(dns_zone_t *zone) {
5282 	REQUIRE(DNS_ZONE_VALID(zone));
5283 	return (zone->altxfrsource6dscp);
5284 }
5285 
5286 isc_result_t
dns_zone_setnotifysrc4(dns_zone_t * zone,const isc_sockaddr_t * notifysrc)5287 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
5288 	REQUIRE(DNS_ZONE_VALID(zone));
5289 
5290 	LOCK_ZONE(zone);
5291 	zone->notifysrc4 = *notifysrc;
5292 	UNLOCK_ZONE(zone);
5293 
5294 	return (ISC_R_SUCCESS);
5295 }
5296 
5297 isc_sockaddr_t *
dns_zone_getnotifysrc4(dns_zone_t * zone)5298 dns_zone_getnotifysrc4(dns_zone_t *zone) {
5299 	REQUIRE(DNS_ZONE_VALID(zone));
5300 	return (&zone->notifysrc4);
5301 }
5302 
5303 isc_result_t
dns_zone_setnotifysrc4dscp(dns_zone_t * zone,isc_dscp_t dscp)5304 dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5305 	REQUIRE(DNS_ZONE_VALID(zone));
5306 
5307 	LOCK_ZONE(zone);
5308 	zone->notifysrc4dscp = dscp;
5309 	UNLOCK_ZONE(zone);
5310 
5311 	return (ISC_R_SUCCESS);
5312 }
5313 
5314 isc_dscp_t
dns_zone_getnotifysrc4dscp(dns_zone_t * zone)5315 dns_zone_getnotifysrc4dscp(dns_zone_t *zone) {
5316 	REQUIRE(DNS_ZONE_VALID(zone));
5317 	return (zone->notifysrc4dscp);
5318 }
5319 
5320 isc_result_t
dns_zone_setnotifysrc6(dns_zone_t * zone,const isc_sockaddr_t * notifysrc)5321 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
5322 	REQUIRE(DNS_ZONE_VALID(zone));
5323 
5324 	LOCK_ZONE(zone);
5325 	zone->notifysrc6 = *notifysrc;
5326 	UNLOCK_ZONE(zone);
5327 
5328 	return (ISC_R_SUCCESS);
5329 }
5330 
5331 isc_sockaddr_t *
dns_zone_getnotifysrc6(dns_zone_t * zone)5332 dns_zone_getnotifysrc6(dns_zone_t *zone) {
5333 	REQUIRE(DNS_ZONE_VALID(zone));
5334 	return (&zone->notifysrc6);
5335 }
5336 
5337 static isc_boolean_t
same_addrs(const isc_sockaddr_t * old,const isc_sockaddr_t * new,isc_uint32_t count)5338 same_addrs(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
5339 	     isc_uint32_t count)
5340 {
5341 	unsigned int i;
5342 
5343 	for (i = 0; i < count; i++)
5344 		if (!isc_sockaddr_equal(&old[i], &new[i]))
5345 			return (ISC_FALSE);
5346 	return (ISC_TRUE);
5347 }
5348 
5349 static isc_boolean_t
same_keynames(dns_name_t ** old,dns_name_t ** new,isc_uint32_t count)5350 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
5351 	unsigned int i;
5352 
5353 	if (old == NULL && new == NULL)
5354 		return (ISC_TRUE);
5355 	if (old == NULL || new == NULL)
5356 		return (ISC_FALSE);
5357 
5358 	for (i = 0; i < count; i++) {
5359 		if (old[i] == NULL && new[i] == NULL)
5360 			continue;
5361 		if (old[i] == NULL || new[i] == NULL ||
5362 		     !dns_name_equal(old[i], new[i]))
5363 			return (ISC_FALSE);
5364 	}
5365 	return (ISC_TRUE);
5366 }
5367 
5368 static void
clear_addresskeylist(isc_sockaddr_t ** addrsp,isc_dscp_t ** dscpsp,dns_name_t *** keynamesp,unsigned int * countp,isc_mem_t * mctx)5369 clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
5370 		     dns_name_t ***keynamesp, unsigned int *countp,
5371 		     isc_mem_t *mctx)
5372 {
5373 	unsigned int count;
5374 	isc_sockaddr_t *addrs;
5375 	isc_dscp_t *dscps;
5376 	dns_name_t **keynames;
5377 
5378 	REQUIRE(countp != NULL && addrsp != NULL && dscpsp != NULL &&
5379 		keynamesp != NULL);
5380 
5381 	count = *countp;
5382 	*countp = 0;
5383 	addrs = *addrsp;
5384 	*addrsp = NULL;
5385 	dscps = *dscpsp;
5386 	*dscpsp = NULL;
5387 	keynames = *keynamesp;
5388 	*keynamesp = NULL;
5389 
5390 	if (addrs != NULL)
5391 		isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
5392 
5393 	if (dscps != NULL)
5394 		isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t));
5395 
5396 	if (keynames != NULL) {
5397 		unsigned int i;
5398 		for (i = 0; i < count; i++) {
5399 			if (keynames[i] != NULL) {
5400 				dns_name_free(keynames[i], mctx);
5401 				isc_mem_put(mctx, keynames[i],
5402 					    sizeof(dns_name_t));
5403 				keynames[i] = NULL;
5404 			}
5405 		}
5406 		isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
5407 	}
5408 }
5409 
5410 static isc_result_t
set_addrkeylist(unsigned int count,const isc_sockaddr_t * addrs,isc_sockaddr_t ** newaddrsp,const isc_dscp_t * dscp,isc_dscp_t ** newdscpp,dns_name_t ** names,dns_name_t *** newnamesp,isc_mem_t * mctx)5411 set_addrkeylist(unsigned int count,
5412 		const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp,
5413 		const isc_dscp_t *dscp, isc_dscp_t **newdscpp,
5414 		dns_name_t **names, dns_name_t ***newnamesp,
5415 		isc_mem_t *mctx)
5416 {
5417 	isc_result_t result;
5418 	isc_sockaddr_t *newaddrs = NULL;
5419 	isc_dscp_t *newdscp = NULL;
5420 	dns_name_t **newnames = NULL;
5421 	unsigned int i;
5422 
5423 	REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
5424 	REQUIRE(newdscpp != NULL && *newdscpp == NULL);
5425 	REQUIRE(newnamesp != NULL && *newnamesp == NULL);
5426 
5427 	newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
5428 	if (newaddrs == NULL)
5429 		return (ISC_R_NOMEMORY);
5430 	memmove(newaddrs, addrs, count * sizeof(*newaddrs));
5431 
5432 	if (dscp != NULL) {
5433 		newdscp = isc_mem_get(mctx, count * sizeof(*newdscp));
5434 		if (newdscp == NULL) {
5435 			isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
5436 			return (ISC_R_NOMEMORY);
5437 		}
5438 		memmove(newdscp, dscp, count * sizeof(*newdscp));
5439 	} else
5440 		newdscp = NULL;
5441 
5442 	if (names != NULL) {
5443 		newnames = isc_mem_get(mctx, count * sizeof(*newnames));
5444 		if (newnames == NULL) {
5445 			if (newdscp != NULL)
5446 				isc_mem_put(mctx, newdscp,
5447 					    count * sizeof(*newdscp));
5448 			isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
5449 			return (ISC_R_NOMEMORY);
5450 		}
5451 		for (i = 0; i < count; i++)
5452 			newnames[i] = NULL;
5453 		for (i = 0; i < count; i++) {
5454 			if (names[i] != NULL) {
5455 				newnames[i] = isc_mem_get(mctx,
5456 							 sizeof(dns_name_t));
5457 				if (newnames[i] == NULL)
5458 					goto allocfail;
5459 				dns_name_init(newnames[i], NULL);
5460 				result = dns_name_dup(names[i], mctx,
5461 						      newnames[i]);
5462 				if (result != ISC_R_SUCCESS) {
5463 				allocfail:
5464 					for (i = 0; i < count; i++)
5465 						if (newnames[i] != NULL)
5466 							dns_name_free(
5467 							       newnames[i],
5468 							       mctx);
5469 					isc_mem_put(mctx, newaddrs,
5470 						    count * sizeof(*newaddrs));
5471 					isc_mem_put(mctx, newdscp,
5472 						    count * sizeof(*newdscp));
5473 					isc_mem_put(mctx, newnames,
5474 						    count * sizeof(*newnames));
5475 					return (ISC_R_NOMEMORY);
5476 				}
5477 			}
5478 		}
5479 	} else
5480 		newnames = NULL;
5481 
5482 	*newdscpp = newdscp;
5483 	*newaddrsp = newaddrs;
5484 	*newnamesp = newnames;
5485 	return (ISC_R_SUCCESS);
5486 }
5487 
5488 isc_result_t
dns_zone_setnotifysrc6dscp(dns_zone_t * zone,isc_dscp_t dscp)5489 dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5490 	REQUIRE(DNS_ZONE_VALID(zone));
5491 
5492 	LOCK_ZONE(zone);
5493 	zone->notifysrc6dscp = dscp;
5494 	UNLOCK_ZONE(zone);
5495 
5496 	return (ISC_R_SUCCESS);
5497 }
5498 
5499 isc_dscp_t
dns_zone_getnotifysrc6dscp(dns_zone_t * zone)5500 dns_zone_getnotifysrc6dscp(dns_zone_t *zone) {
5501 	REQUIRE(DNS_ZONE_VALID(zone));
5502 	return (zone->notifysrc6dscp);
5503 }
5504 
5505 isc_result_t
dns_zone_setalsonotify(dns_zone_t * zone,const isc_sockaddr_t * notify,isc_uint32_t count)5506 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
5507 		       isc_uint32_t count)
5508 {
5509 	return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, NULL,
5510 					       count));
5511 }
5512 
5513 isc_result_t
dns_zone_setalsonotifywithkeys(dns_zone_t * zone,const isc_sockaddr_t * notify,dns_name_t ** keynames,isc_uint32_t count)5514 dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
5515 			       dns_name_t **keynames, isc_uint32_t count)
5516 {
5517 	return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, keynames,
5518 					       count));
5519 }
5520 
5521 isc_result_t
dns_zone_setalsonotifydscpkeys(dns_zone_t * zone,const isc_sockaddr_t * notify,const isc_dscp_t * dscps,dns_name_t ** keynames,isc_uint32_t count)5522 dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
5523 			       const isc_dscp_t *dscps, dns_name_t **keynames,
5524 			       isc_uint32_t count)
5525 {
5526 	isc_result_t result;
5527 	isc_sockaddr_t *newaddrs = NULL;
5528 	isc_dscp_t *newdscps = NULL;
5529 	dns_name_t **newnames = NULL;
5530 
5531 	REQUIRE(DNS_ZONE_VALID(zone));
5532 	REQUIRE(count == 0 || notify != NULL);
5533 	if (keynames != NULL)
5534 		REQUIRE(count != 0);
5535 
5536 	LOCK_ZONE(zone);
5537 
5538 	if (count == zone->notifycnt &&
5539 	    same_addrs(zone->notify, notify, count) &&
5540 	    same_keynames(zone->notifykeynames, keynames, count))
5541 		goto unlock;
5542 
5543 	clear_addresskeylist(&zone->notify, &zone->notifydscp,
5544 			     &zone->notifykeynames, &zone->notifycnt,
5545 			     zone->mctx);
5546 
5547 	if (count == 0)
5548 		goto unlock;
5549 
5550 	/*
5551 	 * Set up the notify and notifykey lists
5552 	 */
5553 	result = set_addrkeylist(count, notify, &newaddrs, dscps, &newdscps,
5554 				 keynames, &newnames, zone->mctx);
5555 	if (result != ISC_R_SUCCESS)
5556 		goto unlock;
5557 
5558 	/*
5559 	 * Everything is ok so attach to the zone.
5560 	 */
5561 	zone->notify = newaddrs;
5562 	zone->notifydscp = newdscps;
5563 	zone->notifykeynames = newnames;
5564 	zone->notifycnt = count;
5565  unlock:
5566 	UNLOCK_ZONE(zone);
5567 	return (ISC_R_SUCCESS);
5568 }
5569 
5570 isc_result_t
dns_zone_setmasters(dns_zone_t * zone,const isc_sockaddr_t * masters,isc_uint32_t count)5571 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
5572 		    isc_uint32_t count)
5573 {
5574 	isc_result_t result;
5575 
5576 	result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
5577 	return (result);
5578 }
5579 
5580 isc_result_t
dns_zone_setmasterswithkeys(dns_zone_t * zone,const isc_sockaddr_t * masters,dns_name_t ** keynames,isc_uint32_t count)5581 dns_zone_setmasterswithkeys(dns_zone_t *zone,
5582 			    const isc_sockaddr_t *masters,
5583 			    dns_name_t **keynames,
5584 			    isc_uint32_t count)
5585 {
5586 	isc_result_t result = ISC_R_SUCCESS;
5587 	isc_sockaddr_t *newaddrs = NULL;
5588 	isc_dscp_t *newdscps = NULL;
5589 	dns_name_t **newnames = NULL;
5590 	isc_boolean_t *newok;
5591 	unsigned int i;
5592 
5593 	REQUIRE(DNS_ZONE_VALID(zone));
5594 	REQUIRE(count == 0 || masters != NULL);
5595 	if (keynames != NULL) {
5596 		REQUIRE(count != 0);
5597 	}
5598 
5599 	LOCK_ZONE(zone);
5600 	/*
5601 	 * The refresh code assumes that 'masters' wouldn't change under it.
5602 	 * If it will change then kill off any current refresh in progress
5603 	 * and update the masters info.  If it won't change then we can just
5604 	 * unlock and exit.
5605 	 */
5606 	if (count != zone->masterscnt ||
5607 	    !same_addrs(zone->masters, masters, count) ||
5608 	    !same_keynames(zone->masterkeynames, keynames, count)) {
5609 		if (zone->request != NULL)
5610 			dns_request_cancel(zone->request);
5611 	} else
5612 		goto unlock;
5613 
5614 	/*
5615 	 * This needs to happen before clear_addresskeylist() sets
5616 	 * zone->masterscnt to 0:
5617 	 */
5618 	if (zone->mastersok != NULL) {
5619 		isc_mem_put(zone->mctx, zone->mastersok,
5620 			    zone->masterscnt * sizeof(isc_boolean_t));
5621 		zone->mastersok = NULL;
5622 	}
5623 	clear_addresskeylist(&zone->masters, &zone->masterdscps,
5624 			     &zone->masterkeynames, &zone->masterscnt,
5625 			     zone->mctx);
5626 	/*
5627 	 * If count == 0, don't allocate any space for masters, mastersok or
5628 	 * keynames so internally, those pointers are NULL if count == 0
5629 	 */
5630 	if (count == 0)
5631 		goto unlock;
5632 
5633 	/*
5634 	 * mastersok must contain count elements
5635 	 */
5636 	newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
5637 	if (newok == NULL) {
5638 		result = ISC_R_NOMEMORY;
5639 		isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs));
5640 		goto unlock;
5641 	};
5642 	for (i = 0; i < count; i++)
5643 		newok[i] = ISC_FALSE;
5644 
5645 	/*
5646 	 * Now set up the masters and masterkey lists
5647 	 */
5648 	result = set_addrkeylist(count, masters, &newaddrs, NULL, &newdscps,
5649 				 keynames, &newnames, zone->mctx);
5650 	INSIST(newdscps == NULL);
5651 	if (result != ISC_R_SUCCESS) {
5652 		isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
5653 		goto unlock;
5654 	}
5655 
5656 	/*
5657 	 * Everything is ok so attach to the zone.
5658 	 */
5659 	zone->curmaster = 0;
5660 	zone->mastersok = newok;
5661 	zone->masters = newaddrs;
5662 	zone->masterdscps = newdscps;
5663 	zone->masterkeynames = newnames;
5664 	zone->masterscnt = count;
5665 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
5666 
5667  unlock:
5668 	UNLOCK_ZONE(zone);
5669 	return (result);
5670 }
5671 
5672 isc_result_t
dns_zone_getdb(dns_zone_t * zone,dns_db_t ** dpb)5673 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
5674 	isc_result_t result = ISC_R_SUCCESS;
5675 
5676 	REQUIRE(DNS_ZONE_VALID(zone));
5677 
5678 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5679 	if (zone->db == NULL)
5680 		result = DNS_R_NOTLOADED;
5681 	else
5682 		dns_db_attach(zone->db, dpb);
5683 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5684 
5685 	return (result);
5686 }
5687 
5688 void
dns_zone_setdb(dns_zone_t * zone,dns_db_t * db)5689 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
5690 	REQUIRE(DNS_ZONE_VALID(zone));
5691 	REQUIRE(zone->type == dns_zone_staticstub);
5692 
5693 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
5694 	REQUIRE(zone->db == NULL);
5695 	dns_db_attach(db, &zone->db);
5696 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
5697 }
5698 
5699 /*
5700  * Co-ordinates the starting of routine jobs.
5701  */
5702 void
dns_zone_maintenance(dns_zone_t * zone)5703 dns_zone_maintenance(dns_zone_t *zone) {
5704 	const char me[] = "dns_zone_maintenance";
5705 	isc_time_t now;
5706 
5707 	REQUIRE(DNS_ZONE_VALID(zone));
5708 	ENTER;
5709 
5710 	LOCK_ZONE(zone);
5711 	TIME_NOW(&now);
5712 	zone_settimer(zone, &now);
5713 	UNLOCK_ZONE(zone);
5714 }
5715 
5716 static inline isc_boolean_t
was_dumping(dns_zone_t * zone)5717 was_dumping(dns_zone_t *zone) {
5718 	isc_boolean_t dumping;
5719 
5720 	REQUIRE(LOCKED_ZONE(zone));
5721 
5722 	dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
5723 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
5724 	if (!dumping) {
5725 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
5726 		isc_time_settoepoch(&zone->dumptime);
5727 	}
5728 	return (dumping);
5729 }
5730 
5731 static isc_result_t
find_zone_keys(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,isc_mem_t * mctx,unsigned int maxkeys,dst_key_t ** keys,unsigned int * nkeys)5732 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
5733 	       isc_mem_t *mctx, unsigned int maxkeys,
5734 	       dst_key_t **keys, unsigned int *nkeys)
5735 {
5736 	isc_result_t result;
5737 	dns_dbnode_t *node = NULL;
5738 	const char *directory = dns_zone_getkeydirectory(zone);
5739 
5740 	CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
5741 	memset(keys, 0, sizeof(*keys) * maxkeys);
5742 	result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
5743 					  directory, mctx, maxkeys, keys,
5744 					  nkeys);
5745 	if (result == ISC_R_NOTFOUND)
5746 		result = ISC_R_SUCCESS;
5747  failure:
5748 	if (node != NULL)
5749 		dns_db_detachnode(db, &node);
5750 	return (result);
5751 }
5752 
5753 static isc_result_t
offline(dns_db_t * db,dns_dbversion_t * ver,zonediff_t * zonediff,dns_name_t * name,dns_ttl_t ttl,dns_rdata_t * rdata)5754 offline(dns_db_t *db, dns_dbversion_t *ver, zonediff_t *zonediff,
5755 	dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
5756 {
5757 	isc_result_t result;
5758 
5759 	if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
5760 		return (ISC_R_SUCCESS);
5761 	result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
5762 			       name, ttl, rdata);
5763 	if (result != ISC_R_SUCCESS)
5764 		return (result);
5765 	rdata->flags |= DNS_RDATA_OFFLINE;
5766 	result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
5767 			       name, ttl, rdata);
5768 	zonediff->offline = ISC_TRUE;
5769 	return (result);
5770 }
5771 
5772 static void
set_key_expiry_warning(dns_zone_t * zone,isc_stdtime_t when,isc_stdtime_t now)5773 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
5774 {
5775 	unsigned int delta;
5776 	char timebuf[80];
5777 
5778 	zone->key_expiry = when;
5779 	if (when <= now) {
5780 		dns_zone_log(zone, ISC_LOG_ERROR,
5781 			     "DNSKEY RRSIG(s) have expired");
5782 		isc_time_settoepoch(&zone->keywarntime);
5783 	} else if (when < now + 7 * 24 * 3600) {
5784 		isc_time_t t;
5785 		isc_time_set(&t, when, 0);
5786 		isc_time_formattimestamp(&t, timebuf, 80);
5787 		dns_zone_log(zone, ISC_LOG_WARNING,
5788 			     "DNSKEY RRSIG(s) will expire within 7 days: %s",
5789 			     timebuf);
5790 		delta = when - now;
5791 		delta--;		/* loop prevention */
5792 		delta /= 24 * 3600;	/* to whole days */
5793 		delta *= 24 * 3600;	/* to seconds */
5794 		isc_time_set(&zone->keywarntime, when - delta, 0);
5795 	}  else {
5796 		isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
5797 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
5798 		dns_zone_log(zone, ISC_LOG_NOTICE,
5799 			     "setting keywarntime to %s", timebuf);
5800 	}
5801 }
5802 
5803 /*
5804  * Helper function to del_sigs(). We don't want to delete RRSIGs that
5805  * have no new key.
5806  */
5807 static isc_boolean_t
delsig_ok(dns_rdata_rrsig_t * rrsig_ptr,dst_key_t ** keys,unsigned int nkeys,isc_boolean_t * warn)5808 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
5809 	  isc_boolean_t *warn)
5810 {
5811 	unsigned int i = 0;
5812 	isc_boolean_t have_ksk = ISC_FALSE, have_zsk = ISC_FALSE;
5813 	isc_boolean_t have_pksk = ISC_FALSE, have_pzsk = ISC_FALSE;
5814 
5815 	for (i = 0; i < nkeys; i++) {
5816 		if (rrsig_ptr->algorithm != dst_key_alg(keys[i]))
5817 			continue;
5818 		if (dst_key_isprivate(keys[i])) {
5819 			if (KSK(keys[i]))
5820 				have_ksk = have_pksk = ISC_TRUE;
5821 			else
5822 				have_zsk = have_pzsk = ISC_TRUE;
5823 		} else {
5824 			if (KSK(keys[i]))
5825 				have_ksk = ISC_TRUE;
5826 			else
5827 				have_zsk = ISC_TRUE;
5828 		}
5829 	}
5830 
5831 	if (have_zsk && have_ksk && !have_pzsk)
5832 		*warn = ISC_TRUE;
5833 
5834 	/*
5835 	 * It's okay to delete a signature if there is an active key
5836 	 * with the same algorithm to replace it.
5837 	 */
5838 	if (have_pksk || have_pzsk)
5839 		return (ISC_TRUE);
5840 
5841 	/*
5842 	 * Failing that, it is *not* okay to delete a signature
5843 	 * if the associated public key is still in the DNSKEY RRset
5844 	 */
5845 	for (i = 0; i < nkeys; i++) {
5846 		if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
5847 		    (rrsig_ptr->keyid == dst_key_id(keys[i])))
5848 			return (ISC_FALSE);
5849 	}
5850 
5851 	/*
5852 	 * But if the key is gone, then go ahead.
5853 	 */
5854 	return (ISC_TRUE);
5855 }
5856 
5857 /*
5858  * Delete expired RRsigs and any RRsigs we are about to re-sign.
5859  * See also update.c:del_keysigs().
5860  */
5861 static isc_result_t
del_sigs(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,dns_name_t * name,dns_rdatatype_t type,zonediff_t * zonediff,dst_key_t ** keys,unsigned int nkeys,isc_stdtime_t now,isc_boolean_t incremental)5862 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
5863 	 dns_rdatatype_t type, zonediff_t *zonediff, dst_key_t **keys,
5864 	 unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental)
5865 {
5866 	isc_result_t result;
5867 	dns_dbnode_t *node = NULL;
5868 	dns_rdataset_t rdataset;
5869 	unsigned int i;
5870 	dns_rdata_rrsig_t rrsig;
5871 	isc_boolean_t found;
5872 	isc_int64_t timewarn = 0, timemaybe = 0;
5873 
5874 	dns_rdataset_init(&rdataset);
5875 
5876 	if (type == dns_rdatatype_nsec3)
5877 		result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
5878 	else
5879 		result = dns_db_findnode(db, name, ISC_FALSE, &node);
5880 	if (result == ISC_R_NOTFOUND)
5881 		return (ISC_R_SUCCESS);
5882 	if (result != ISC_R_SUCCESS)
5883 		goto failure;
5884 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
5885 				     (isc_stdtime_t) 0, &rdataset, NULL);
5886 	dns_db_detachnode(db, &node);
5887 
5888 	if (result == ISC_R_NOTFOUND) {
5889 		INSIST(!dns_rdataset_isassociated(&rdataset));
5890 		return (ISC_R_SUCCESS);
5891 	}
5892 	if (result != ISC_R_SUCCESS) {
5893 		INSIST(!dns_rdataset_isassociated(&rdataset));
5894 		goto failure;
5895 	}
5896 
5897 	for (result = dns_rdataset_first(&rdataset);
5898 	     result == ISC_R_SUCCESS;
5899 	     result = dns_rdataset_next(&rdataset)) {
5900 		dns_rdata_t rdata = DNS_RDATA_INIT;
5901 
5902 		dns_rdataset_current(&rdataset, &rdata);
5903 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
5904 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
5905 
5906 		if (type != dns_rdatatype_dnskey) {
5907 			isc_boolean_t warn = ISC_FALSE, deleted = ISC_FALSE;
5908 			if (delsig_ok(&rrsig, keys, nkeys, &warn)) {
5909 				result = update_one_rr(db, ver, zonediff->diff,
5910 					       DNS_DIFFOP_DELRESIGN, name,
5911 					       rdataset.ttl, &rdata);
5912 				if (result != ISC_R_SUCCESS)
5913 					break;
5914 				deleted = ISC_TRUE;
5915 			}
5916 			if (warn) {
5917 				/*
5918 				 * At this point, we've got an RRSIG,
5919 				 * which is signed by an inactive key.
5920 				 * An administrator needs to provide a new
5921 				 * key/alg, but until that time, we want to
5922 				 * keep the old RRSIG.  Marking the key as
5923 				 * offline will prevent us spinning waiting
5924 				 * for the private part.
5925 				 */
5926 				if (incremental && !deleted) {
5927 					result = offline(db, ver, zonediff,
5928 							 name, rdataset.ttl,
5929 							 &rdata);
5930 					if (result != ISC_R_SUCCESS)
5931 						break;
5932 				}
5933 
5934 				/*
5935 				 * Log the key id and algorithm of
5936 				 * the inactive key with no replacement
5937 				 */
5938 				if (zone->log_key_expired_timer <= now) {
5939 					char origin[DNS_NAME_FORMATSIZE];
5940 					char algbuf[DNS_NAME_FORMATSIZE];
5941 					dns_name_format(&zone->origin, origin,
5942 							sizeof(origin));
5943 					dns_secalg_format(rrsig.algorithm,
5944 							  algbuf,
5945 							  sizeof(algbuf));
5946 					dns_zone_log(zone, ISC_LOG_WARNING,
5947 						     "Key %s/%s/%d "
5948 						     "missing or inactive "
5949 						     "and has no replacement: "
5950 						     "retaining signatures.",
5951 						     origin, algbuf,
5952 						     rrsig.keyid);
5953 					zone->log_key_expired_timer = now +
5954 									3600;
5955 				}
5956 			}
5957 			continue;
5958 		}
5959 
5960 		/*
5961 		 * RRSIG(DNSKEY) requires special processing.
5962 		 */
5963 		found = ISC_FALSE;
5964 		for (i = 0; i < nkeys; i++) {
5965 			if (rrsig.algorithm == dst_key_alg(keys[i]) &&
5966 			    rrsig.keyid == dst_key_id(keys[i])) {
5967 				found = ISC_TRUE;
5968 				/*
5969 				 * Mark offline RRSIG(DNSKEY).
5970 				 * We want the earliest offline expire time
5971 				 * iff there is a new offline signature.
5972 				 */
5973 				if (!dst_key_inactive(keys[i]) &&
5974 				    !dst_key_isprivate(keys[i]))
5975 				{
5976 					isc_int64_t timeexpire =
5977 					   dns_time64_from32(rrsig.timeexpire);
5978 					if (timewarn != 0 &&
5979 					    timewarn > timeexpire)
5980 						timewarn = timeexpire;
5981 					if (rdata.flags & DNS_RDATA_OFFLINE) {
5982 						if (timemaybe == 0 ||
5983 						    timemaybe > timeexpire)
5984 							timemaybe = timeexpire;
5985 						break;
5986 					}
5987 					if (timewarn == 0)
5988 						timewarn = timemaybe;
5989 					if (timewarn == 0 ||
5990 					    timewarn > timeexpire)
5991 						timewarn = timeexpire;
5992 					result = offline(db, ver, zonediff,
5993 							 name, rdataset.ttl,
5994 							 &rdata);
5995 					break;
5996 				}
5997 				result = update_one_rr(db, ver, zonediff->diff,
5998 						       DNS_DIFFOP_DELRESIGN,
5999 						       name, rdataset.ttl,
6000 						       &rdata);
6001 				break;
6002 			}
6003 		}
6004 
6005 		/*
6006 		 * If there is not a matching DNSKEY then
6007 		 * delete the RRSIG.
6008 		 */
6009 		if (!found)
6010 			result = update_one_rr(db, ver, zonediff->diff,
6011 					       DNS_DIFFOP_DELRESIGN, name,
6012 					       rdataset.ttl, &rdata);
6013 		if (result != ISC_R_SUCCESS)
6014 			break;
6015 	}
6016 
6017 	dns_rdataset_disassociate(&rdataset);
6018 	if (result == ISC_R_NOMORE)
6019 		result = ISC_R_SUCCESS;
6020 	if (timewarn > 0) {
6021 #if defined(STDTIME_ON_32BITS)
6022 		isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn;
6023 		if (timewarn == stdwarn)
6024 #endif
6025 			set_key_expiry_warning(zone, (isc_stdtime_t)timewarn,
6026 					       now);
6027 #if defined(STDTIME_ON_32BITS)
6028 		else
6029 			dns_zone_log(zone, ISC_LOG_ERROR,
6030 				     "key expiry warning time out of range");
6031 #endif
6032 	}
6033  failure:
6034 	if (node != NULL)
6035 		dns_db_detachnode(db, &node);
6036 	return (result);
6037 }
6038 
6039 static isc_result_t
add_sigs(dns_db_t * db,dns_dbversion_t * ver,dns_name_t * name,dns_rdatatype_t type,dns_diff_t * diff,dst_key_t ** keys,unsigned int nkeys,isc_mem_t * mctx,isc_stdtime_t inception,isc_stdtime_t expire,isc_boolean_t check_ksk,isc_boolean_t keyset_kskonly)6040 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
6041 	 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
6042 	 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
6043 	 isc_stdtime_t expire, isc_boolean_t check_ksk,
6044 	 isc_boolean_t keyset_kskonly)
6045 {
6046 	isc_result_t result;
6047 	dns_dbnode_t *node = NULL;
6048 	dns_rdataset_t rdataset;
6049 	dns_rdata_t sig_rdata = DNS_RDATA_INIT;
6050 	unsigned char data[1024]; /* XXX */
6051 	isc_buffer_t buffer;
6052 	unsigned int i, j;
6053 
6054 	dns_rdataset_init(&rdataset);
6055 	isc_buffer_init(&buffer, data, sizeof(data));
6056 
6057 	if (type == dns_rdatatype_nsec3)
6058 		result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
6059 	else
6060 		result = dns_db_findnode(db, name, ISC_FALSE, &node);
6061 	if (result == ISC_R_NOTFOUND)
6062 		return (ISC_R_SUCCESS);
6063 	if (result != ISC_R_SUCCESS)
6064 		goto failure;
6065 	result = dns_db_findrdataset(db, node, ver, type, 0,
6066 				     (isc_stdtime_t) 0, &rdataset, NULL);
6067 	dns_db_detachnode(db, &node);
6068 	if (result == ISC_R_NOTFOUND) {
6069 		INSIST(!dns_rdataset_isassociated(&rdataset));
6070 		return (ISC_R_SUCCESS);
6071 	}
6072 	if (result != ISC_R_SUCCESS) {
6073 		INSIST(!dns_rdataset_isassociated(&rdataset));
6074 		goto failure;
6075 	}
6076 
6077 	for (i = 0; i < nkeys; i++) {
6078 		isc_boolean_t both = ISC_FALSE;
6079 
6080 		if (!dst_key_isprivate(keys[i]))
6081 			continue;
6082 
6083 		if (check_ksk && !REVOKE(keys[i])) {
6084 			isc_boolean_t have_ksk, have_nonksk;
6085 			if (KSK(keys[i])) {
6086 				have_ksk = ISC_TRUE;
6087 				have_nonksk = ISC_FALSE;
6088 			} else {
6089 				have_ksk = ISC_FALSE;
6090 				have_nonksk = ISC_TRUE;
6091 			}
6092 			for (j = 0; j < nkeys; j++) {
6093 				if (j == i || ALG(keys[i]) != ALG(keys[j]))
6094 					continue;
6095 				if (REVOKE(keys[j]))
6096 					continue;
6097 				if (KSK(keys[j]))
6098 					have_ksk = ISC_TRUE;
6099 				else
6100 					have_nonksk = ISC_TRUE;
6101 				both = have_ksk && have_nonksk;
6102 				if (both)
6103 					break;
6104 			}
6105 		}
6106 		if (both) {
6107 			if (type == dns_rdatatype_dnskey) {
6108 				if (!KSK(keys[i]) && keyset_kskonly)
6109 					continue;
6110 			} else if (KSK(keys[i]))
6111 				continue;
6112 		} else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey)
6113 				continue;
6114 
6115 		/* Calculate the signature, creating a RRSIG RDATA. */
6116 		isc_buffer_clear(&buffer);
6117 		CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
6118 				      &inception, &expire,
6119 				      mctx, &buffer, &sig_rdata));
6120 		/* Update the database and journal with the RRSIG. */
6121 		/* XXX inefficient - will cause dataset merging */
6122 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
6123 				    name, rdataset.ttl, &sig_rdata));
6124 		dns_rdata_reset(&sig_rdata);
6125 		isc_buffer_init(&buffer, data, sizeof(data));
6126 	}
6127 
6128  failure:
6129 	if (dns_rdataset_isassociated(&rdataset))
6130 		dns_rdataset_disassociate(&rdataset);
6131 	if (node != NULL)
6132 		dns_db_detachnode(db, &node);
6133 	return (result);
6134 }
6135 
6136 static void
zone_resigninc(dns_zone_t * zone)6137 zone_resigninc(dns_zone_t *zone) {
6138 	const char *me = "zone_resigninc";
6139 	dns_db_t *db = NULL;
6140 	dns_dbversion_t *version = NULL;
6141 	dns_diff_t _sig_diff;
6142 	zonediff_t zonediff;
6143 	dns_fixedname_t fixed;
6144 	dns_name_t *name;
6145 	dns_rdataset_t rdataset;
6146 	dns_rdatatype_t covers;
6147 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
6148 	isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE;
6149 	isc_result_t result;
6150 	isc_stdtime_t now, inception, soaexpire, expire, stop;
6151 	isc_uint32_t jitter;
6152 	unsigned int i;
6153 	unsigned int nkeys = 0;
6154 	unsigned int resign;
6155 
6156 	ENTER;
6157 
6158 	dns_rdataset_init(&rdataset);
6159 	dns_fixedname_init(&fixed);
6160 	dns_diff_init(zone->mctx, &_sig_diff);
6161 	zonediff_init(&zonediff, &_sig_diff);
6162 
6163 	/*
6164 	 * Zone is frozen or automatic resigning is disabled.
6165 	 * Pause for 5 minutes.
6166 	 */
6167 	if (zone->update_disabled ||
6168 	    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN))
6169 	{
6170 		result = ISC_R_FAILURE;
6171 		goto failure;
6172 	}
6173 
6174 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6175 	dns_db_attach(zone->db, &db);
6176 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6177 
6178 	result = dns_db_newversion(db, &version);
6179 	if (result != ISC_R_SUCCESS) {
6180 		dns_zone_log(zone, ISC_LOG_ERROR,
6181 			     "zone_resigninc:dns_db_newversion -> %s",
6182 			     dns_result_totext(result));
6183 		goto failure;
6184 	}
6185 
6186 	result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS,
6187 				zone_keys, &nkeys);
6188 	if (result != ISC_R_SUCCESS) {
6189 		dns_zone_log(zone, ISC_LOG_ERROR,
6190 			     "zone_resigninc:find_zone_keys -> %s",
6191 			     dns_result_totext(result));
6192 		goto failure;
6193 	}
6194 
6195 	isc_stdtime_get(&now);
6196 	inception = now - 3600;	/* Allow for clock skew. */
6197 	soaexpire = now + dns_zone_getsigvalidityinterval(zone);
6198 	/*
6199 	 * Spread out signatures over time if they happen to be
6200 	 * clumped.  We don't do this for each add_sigs() call as
6201 	 * we still want some clustering to occur.
6202 	 */
6203 	isc_random_get(&jitter);
6204 	expire = soaexpire - jitter % 3600;
6205 	stop = now + 5;
6206 
6207 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
6208 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
6209 
6210 	name = dns_fixedname_name(&fixed);
6211 	result = dns_db_getsigningtime(db, &rdataset, name);
6212 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
6213 		dns_zone_log(zone, ISC_LOG_ERROR,
6214 			     "zone_resigninc:dns_db_getsigningtime -> %s",
6215 			     dns_result_totext(result));
6216 	}
6217 
6218 	i = 0;
6219 	while (result == ISC_R_SUCCESS) {
6220 		resign = rdataset.resign - zone->sigresigninginterval;
6221 		covers = rdataset.covers;
6222 		dns_rdataset_disassociate(&rdataset);
6223 
6224 		/*
6225 		 * Stop if we hit the SOA as that means we have walked the
6226 		 * entire zone.  The SOA record should always be the most
6227 		 * recent signature.
6228 		 */
6229 		/* XXXMPA increase number of RRsets signed pre call */
6230 		if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
6231 		    resign > stop)
6232 			break;
6233 
6234 		result = del_sigs(zone, db, version, name, covers, &zonediff,
6235 				  zone_keys, nkeys, now, ISC_TRUE);
6236 		if (result != ISC_R_SUCCESS) {
6237 			dns_zone_log(zone, ISC_LOG_ERROR,
6238 				     "zone_resigninc:del_sigs -> %s",
6239 				     dns_result_totext(result));
6240 			break;
6241 		}
6242 
6243 		result = add_sigs(db, version, name, covers, zonediff.diff,
6244 				  zone_keys, nkeys, zone->mctx, inception,
6245 				  expire, check_ksk, keyset_kskonly);
6246 		if (result != ISC_R_SUCCESS) {
6247 			dns_zone_log(zone, ISC_LOG_ERROR,
6248 				     "zone_resigninc:add_sigs -> %s",
6249 				     dns_result_totext(result));
6250 			break;
6251 		}
6252 		result	= dns_db_getsigningtime(db, &rdataset, name);
6253 		if (nkeys == 0 && result == ISC_R_NOTFOUND) {
6254 			result = ISC_R_SUCCESS;
6255 			break;
6256 		}
6257 		if (result != ISC_R_SUCCESS)
6258 			dns_zone_log(zone, ISC_LOG_ERROR,
6259 			     "zone_resigninc:dns_db_getsigningtime -> %s",
6260 				     dns_result_totext(result));
6261 	}
6262 
6263 	if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
6264 		goto failure;
6265 
6266 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
6267 			  &zonediff, zone_keys, nkeys, now, ISC_TRUE);
6268 	if (result != ISC_R_SUCCESS) {
6269 		dns_zone_log(zone, ISC_LOG_ERROR,
6270 			     "zone_resigninc:del_sigs -> %s",
6271 			     dns_result_totext(result));
6272 		goto failure;
6273 	}
6274 
6275 	/*
6276 	 * Did we change anything in the zone?
6277 	 */
6278 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
6279 		/*
6280 		 * Commit the changes if any key has been marked as offline.			 */
6281 		if (zonediff.offline)
6282 			dns_db_closeversion(db, &version, ISC_TRUE);
6283 		goto failure;
6284 	}
6285 
6286 	/* Increment SOA serial if we have made changes */
6287 	result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
6288 				   zone->updatemethod);
6289 	if (result != ISC_R_SUCCESS) {
6290 		dns_zone_log(zone, ISC_LOG_ERROR,
6291 			     "zone_resigninc:update_soa_serial -> %s",
6292 			     dns_result_totext(result));
6293 		goto failure;
6294 	}
6295 
6296 	/*
6297 	 * Generate maximum life time signatures so that the above loop
6298 	 * termination is sensible.
6299 	 */
6300 	result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
6301 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
6302 			  inception, soaexpire, check_ksk, keyset_kskonly);
6303 	if (result != ISC_R_SUCCESS) {
6304 		dns_zone_log(zone, ISC_LOG_ERROR,
6305 			     "zone_resigninc:add_sigs -> %s",
6306 			     dns_result_totext(result));
6307 		goto failure;
6308 	}
6309 
6310 	/* Write changes to journal file. */
6311 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc"));
6312 
6313 	/* Everything has succeeded. Commit the changes. */
6314 	dns_db_closeversion(db, &version, ISC_TRUE);
6315 
6316  failure:
6317 	dns_diff_clear(&_sig_diff);
6318 	for (i = 0; i < nkeys; i++)
6319 		dst_key_free(&zone_keys[i]);
6320 	if (version != NULL) {
6321 		dns_db_closeversion(zone->db, &version, ISC_FALSE);
6322 		dns_db_detach(&db);
6323 	} else if (db != NULL)
6324 		dns_db_detach(&db);
6325 	if (result == ISC_R_SUCCESS) {
6326 		set_resigntime(zone);
6327 		LOCK_ZONE(zone);
6328 		zone_needdump(zone, DNS_DUMP_DELAY);
6329 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6330 		UNLOCK_ZONE(zone);
6331 	} else {
6332 		/*
6333 		 * Something failed.  Retry in 5 minutes.
6334 		 */
6335 		isc_interval_t ival;
6336 		isc_interval_set(&ival, 300, 0);
6337 		isc_time_nowplusinterval(&zone->resigntime, &ival);
6338 	}
6339 
6340 	INSIST(version == NULL);
6341 }
6342 
6343 static isc_result_t
next_active(dns_db_t * db,dns_dbversion_t * version,dns_name_t * oldname,dns_name_t * newname,isc_boolean_t bottom)6344 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
6345 	    dns_name_t *newname, isc_boolean_t bottom)
6346 {
6347 	isc_result_t result;
6348 	dns_dbiterator_t *dbit = NULL;
6349 	dns_rdatasetiter_t *rdsit = NULL;
6350 	dns_dbnode_t *node = NULL;
6351 
6352 	CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
6353 	CHECK(dns_dbiterator_seek(dbit, oldname));
6354 	do {
6355 		result = dns_dbiterator_next(dbit);
6356 		if (result == ISC_R_NOMORE)
6357 			CHECK(dns_dbiterator_first(dbit));
6358 		CHECK(dns_dbiterator_current(dbit, &node, newname));
6359 		if (bottom && dns_name_issubdomain(newname, oldname) &&
6360 		    !dns_name_equal(newname, oldname)) {
6361 			dns_db_detachnode(db, &node);
6362 			continue;
6363 		}
6364 		/*
6365 		 * Is this node empty?
6366 		 */
6367 		CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
6368 		result = dns_rdatasetiter_first(rdsit);
6369 		dns_db_detachnode(db, &node);
6370 		dns_rdatasetiter_destroy(&rdsit);
6371 		if (result != ISC_R_NOMORE)
6372 			break;
6373 	} while (1);
6374  failure:
6375 	if (node != NULL)
6376 		dns_db_detachnode(db, &node);
6377 	if (dbit != NULL)
6378 		dns_dbiterator_destroy(&dbit);
6379 	return (result);
6380 }
6381 
6382 static isc_boolean_t
signed_with_key(dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,dns_rdatatype_t type,dst_key_t * key)6383 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
6384 		dns_rdatatype_t type, dst_key_t *key)
6385 {
6386 	isc_result_t result;
6387 	dns_rdataset_t rdataset;
6388 	dns_rdata_t rdata = DNS_RDATA_INIT;
6389 	dns_rdata_rrsig_t rrsig;
6390 
6391 	dns_rdataset_init(&rdataset);
6392 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
6393 				     type, 0, &rdataset, NULL);
6394 	if (result != ISC_R_SUCCESS) {
6395 		INSIST(!dns_rdataset_isassociated(&rdataset));
6396 		return (ISC_FALSE);
6397 	}
6398 	for (result = dns_rdataset_first(&rdataset);
6399 	     result == ISC_R_SUCCESS;
6400 	     result = dns_rdataset_next(&rdataset)) {
6401 		dns_rdataset_current(&rdataset, &rdata);
6402 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
6403 		INSIST(result == ISC_R_SUCCESS);
6404 		if (rrsig.algorithm == dst_key_alg(key) &&
6405 		    rrsig.keyid == dst_key_id(key)) {
6406 			dns_rdataset_disassociate(&rdataset);
6407 			return (ISC_TRUE);
6408 		}
6409 		dns_rdata_reset(&rdata);
6410 	}
6411 	dns_rdataset_disassociate(&rdataset);
6412 	return (ISC_FALSE);
6413 }
6414 
6415 static isc_result_t
add_nsec(dns_db_t * db,dns_dbversion_t * version,dns_name_t * name,dns_dbnode_t * node,dns_ttl_t ttl,isc_boolean_t bottom,dns_diff_t * diff)6416 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
6417 	 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
6418 	 dns_diff_t *diff)
6419 {
6420 	dns_fixedname_t fixed;
6421 	dns_name_t *next;
6422 	dns_rdata_t rdata = DNS_RDATA_INIT;
6423 	isc_result_t result;
6424 	unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
6425 
6426 	dns_fixedname_init(&fixed);
6427 	next = dns_fixedname_name(&fixed);
6428 
6429 	CHECK(next_active(db, version, name, next, bottom));
6430 	CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
6431 				  &rdata));
6432 	CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
6433 			    &rdata));
6434  failure:
6435 	return (result);
6436 }
6437 
6438 static isc_result_t
sign_a_node(dns_db_t * db,dns_name_t * name,dns_dbnode_t * node,dns_dbversion_t * version,isc_boolean_t build_nsec3,isc_boolean_t build_nsec,dst_key_t * key,isc_stdtime_t inception,isc_stdtime_t expire,unsigned int minimum,isc_boolean_t is_ksk,isc_boolean_t keyset_kskonly,isc_boolean_t * delegation,dns_diff_t * diff,isc_int32_t * signatures,isc_mem_t * mctx)6439 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
6440 	    dns_dbversion_t *version, isc_boolean_t build_nsec3,
6441 	    isc_boolean_t build_nsec, dst_key_t *key,
6442 	    isc_stdtime_t inception, isc_stdtime_t expire,
6443 	    unsigned int minimum, isc_boolean_t is_ksk,
6444 	    isc_boolean_t keyset_kskonly, isc_boolean_t *delegation,
6445 	    dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx)
6446 {
6447 	isc_result_t result;
6448 	dns_rdatasetiter_t *iterator = NULL;
6449 	dns_rdataset_t rdataset;
6450 	dns_rdata_t rdata = DNS_RDATA_INIT;
6451 	isc_buffer_t buffer;
6452 	unsigned char data[1024];
6453 	isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
6454 		      seen_nsec3, seen_ds;
6455 	isc_boolean_t bottom;
6456 
6457 	result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6458 	if (result != ISC_R_SUCCESS) {
6459 		if (result == ISC_R_NOTFOUND)
6460 			result = ISC_R_SUCCESS;
6461 		return (result);
6462 	}
6463 
6464 	dns_rdataset_init(&rdataset);
6465 	isc_buffer_init(&buffer, data, sizeof(data));
6466 	seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
6467 	seen_nsec3 = seen_ds = ISC_FALSE;
6468 	for (result = dns_rdatasetiter_first(iterator);
6469 	     result == ISC_R_SUCCESS;
6470 	     result = dns_rdatasetiter_next(iterator)) {
6471 		dns_rdatasetiter_current(iterator, &rdataset);
6472 		if (rdataset.type == dns_rdatatype_soa)
6473 			seen_soa = ISC_TRUE;
6474 		else if (rdataset.type == dns_rdatatype_ns)
6475 			seen_ns = ISC_TRUE;
6476 		else if (rdataset.type == dns_rdatatype_ds)
6477 			seen_ds = ISC_TRUE;
6478 		else if (rdataset.type == dns_rdatatype_dname)
6479 			seen_dname = ISC_TRUE;
6480 		else if (rdataset.type == dns_rdatatype_nsec)
6481 			seen_nsec = ISC_TRUE;
6482 		else if (rdataset.type == dns_rdatatype_nsec3)
6483 			seen_nsec3 = ISC_TRUE;
6484 		if (rdataset.type != dns_rdatatype_rrsig)
6485 			seen_rr = ISC_TRUE;
6486 		dns_rdataset_disassociate(&rdataset);
6487 	}
6488 	if (result != ISC_R_NOMORE)
6489 		goto failure;
6490 	if (seen_ns && !seen_soa)
6491 		*delegation = ISC_TRUE;
6492 	/*
6493 	 * Going from insecure to NSEC3.
6494 	 * Don't generate NSEC3 records for NSEC3 records.
6495 	 */
6496 	if (build_nsec3 && !seen_nsec3 && seen_rr) {
6497 		isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
6498 		CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
6499 					  unsecure, diff));
6500 		(*signatures)--;
6501 	}
6502 	/*
6503 	 * Going from insecure to NSEC.
6504 	 * Don't generate NSEC records for NSEC3 records.
6505 	 */
6506 	if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
6507 		/* Build and add NSEC. */
6508 		bottom = (seen_ns && !seen_soa) || seen_dname;
6509 		/*
6510 		 * Build a NSEC record except at the origin.
6511 		 */
6512 		if (!dns_name_equal(name, dns_db_origin(db))) {
6513 			CHECK(add_nsec(db, version, name, node, minimum,
6514 				       bottom, diff));
6515 			/* Count a NSEC generation as a signature generation. */
6516 			(*signatures)--;
6517 		}
6518 	}
6519 	result = dns_rdatasetiter_first(iterator);
6520 	while (result == ISC_R_SUCCESS) {
6521 		dns_rdatasetiter_current(iterator, &rdataset);
6522 		if (rdataset.type == dns_rdatatype_soa ||
6523 		    rdataset.type == dns_rdatatype_rrsig)
6524 			goto next_rdataset;
6525 		if (rdataset.type == dns_rdatatype_dnskey) {
6526 			if (!is_ksk && keyset_kskonly)
6527 				goto next_rdataset;
6528 		} else if (is_ksk)
6529 			goto next_rdataset;
6530 		if (*delegation &&
6531 		    rdataset.type != dns_rdatatype_ds &&
6532 		    rdataset.type != dns_rdatatype_nsec)
6533 			goto next_rdataset;
6534 		if (signed_with_key(db, node, version, rdataset.type, key))
6535 			goto next_rdataset;
6536 		/* Calculate the signature, creating a RRSIG RDATA. */
6537 		isc_buffer_clear(&buffer);
6538 		CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
6539 				      &expire, mctx, &buffer, &rdata));
6540 		/* Update the database and journal with the RRSIG. */
6541 		/* XXX inefficient - will cause dataset merging */
6542 		CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
6543 				    name, rdataset.ttl, &rdata));
6544 		dns_rdata_reset(&rdata);
6545 		(*signatures)--;
6546  next_rdataset:
6547 		dns_rdataset_disassociate(&rdataset);
6548 		result = dns_rdatasetiter_next(iterator);
6549 	}
6550 	if (result == ISC_R_NOMORE)
6551 		result = ISC_R_SUCCESS;
6552 	if (seen_dname)
6553 		*delegation = ISC_TRUE;
6554  failure:
6555 	if (dns_rdataset_isassociated(&rdataset))
6556 		dns_rdataset_disassociate(&rdataset);
6557 	if (iterator != NULL)
6558 		dns_rdatasetiter_destroy(&iterator);
6559 	return (result);
6560 }
6561 
6562 /*
6563  * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
6564  */
6565 static isc_result_t
updatesecure(dns_db_t * db,dns_dbversion_t * version,dns_name_t * name,dns_ttl_t minimum,isc_boolean_t update_only,dns_diff_t * diff)6566 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
6567 	     dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff)
6568 {
6569 	isc_result_t result;
6570 	dns_rdataset_t rdataset;
6571 	dns_dbnode_t *node = NULL;
6572 
6573 	CHECK(dns_db_getoriginnode(db, &node));
6574 	if (update_only) {
6575 		dns_rdataset_init(&rdataset);
6576 		result = dns_db_findrdataset(db, node, version,
6577 					     dns_rdatatype_nsec,
6578 					     dns_rdatatype_none,
6579 					     0, &rdataset, NULL);
6580 		if (dns_rdataset_isassociated(&rdataset))
6581 			dns_rdataset_disassociate(&rdataset);
6582 		if (result == ISC_R_NOTFOUND)
6583 			goto success;
6584 		if (result != ISC_R_SUCCESS)
6585 			goto failure;
6586 	}
6587 	CHECK(delete_nsec(db, version, node, name, diff));
6588 	CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff));
6589  success:
6590 	result = ISC_R_SUCCESS;
6591  failure:
6592 	if (node != NULL)
6593 		dns_db_detachnode(db, &node);
6594 	return (result);
6595 }
6596 
6597 static isc_result_t
updatesignwithkey(dns_zone_t * zone,dns_signing_t * signing,dns_dbversion_t * version,isc_boolean_t build_nsec3,dns_ttl_t minimum,dns_diff_t * diff)6598 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
6599 		  dns_dbversion_t *version, isc_boolean_t build_nsec3,
6600 		  dns_ttl_t minimum, dns_diff_t *diff)
6601 {
6602 	isc_result_t result;
6603 	dns_dbnode_t *node = NULL;
6604 	dns_rdataset_t rdataset;
6605 	dns_rdata_t rdata = DNS_RDATA_INIT;
6606 	unsigned char data[5];
6607 	isc_boolean_t seen_done = ISC_FALSE;
6608 	isc_boolean_t have_rr = ISC_FALSE;
6609 
6610 	dns_rdataset_init(&rdataset);
6611 	result = dns_db_getoriginnode(signing->db, &node);
6612 	if (result != ISC_R_SUCCESS)
6613 		goto failure;
6614 
6615 	result = dns_db_findrdataset(signing->db, node, version,
6616 				     zone->privatetype, dns_rdatatype_none,
6617 				     0, &rdataset, NULL);
6618 	if (result == ISC_R_NOTFOUND) {
6619 		INSIST(!dns_rdataset_isassociated(&rdataset));
6620 		result = ISC_R_SUCCESS;
6621 		goto failure;
6622 	}
6623 	if (result != ISC_R_SUCCESS) {
6624 		INSIST(!dns_rdataset_isassociated(&rdataset));
6625 		goto failure;
6626 	}
6627 	for (result = dns_rdataset_first(&rdataset);
6628 	     result == ISC_R_SUCCESS;
6629 	     result = dns_rdataset_next(&rdataset)) {
6630 		dns_rdataset_current(&rdataset, &rdata);
6631 		/*
6632 		 * If we don't match the algorithm or keyid skip the record.
6633 		 */
6634 		if (rdata.length != 5 ||
6635 		    rdata.data[0] != signing->algorithm ||
6636 		    rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
6637 		    rdata.data[2] != (signing->keyid & 0xff)) {
6638 			have_rr = ISC_TRUE;
6639 			dns_rdata_reset(&rdata);
6640 			continue;
6641 		}
6642 		/*
6643 		 * We have a match.  If we were signing (!signing->delete)
6644 		 * and we already have a record indicating that we have
6645 		 * finished signing (rdata.data[4] != 0) then keep it.
6646 		 * Otherwise it needs to be deleted as we have removed all
6647 		 * the signatures (signing->delete), so any record indicating
6648 		 * completion is now out of date, or we have finished signing
6649 		 * with the new record so we no longer need to remember that
6650 		 * we need to sign the zone with the matching key across a
6651 		 * nameserver re-start.
6652 		 */
6653 		if (!signing->delete && rdata.data[4] != 0) {
6654 			seen_done = ISC_TRUE;
6655 			have_rr = ISC_TRUE;
6656 		} else
6657 			CHECK(update_one_rr(signing->db, version, diff,
6658 					    DNS_DIFFOP_DEL, &zone->origin,
6659 					    rdataset.ttl, &rdata));
6660 		dns_rdata_reset(&rdata);
6661 	}
6662 	if (result == ISC_R_NOMORE)
6663 		result = ISC_R_SUCCESS;
6664 	if (!signing->delete && !seen_done) {
6665 		/*
6666 		 * If we were signing then we need to indicate that we have
6667 		 * finished signing the zone with this key.  If it is already
6668 		 * there we don't need to add it a second time.
6669 		 */
6670 		data[0] = signing->algorithm;
6671 		data[1] = (signing->keyid >> 8) & 0xff;
6672 		data[2] = signing->keyid & 0xff;
6673 		data[3] = 0;
6674 		data[4] = 1;
6675 		rdata.length = sizeof(data);
6676 		rdata.data = data;
6677 		rdata.type = zone->privatetype;
6678 		rdata.rdclass = dns_db_class(signing->db);
6679 		CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
6680 				    &zone->origin, rdataset.ttl, &rdata));
6681 	} else if (!have_rr) {
6682 		dns_name_t *origin = dns_db_origin(signing->db);
6683 		/*
6684 		 * Rebuild the NSEC/NSEC3 record for the origin as we no
6685 		 * longer have any private records.
6686 		 */
6687 		if (build_nsec3)
6688 			CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
6689 						  minimum, ISC_FALSE, diff));
6690 		CHECK(updatesecure(signing->db, version, origin, minimum,
6691 				   ISC_TRUE, diff));
6692 	}
6693 
6694  failure:
6695 	if (dns_rdataset_isassociated(&rdataset))
6696 		dns_rdataset_disassociate(&rdataset);
6697 	if (node != NULL)
6698 		dns_db_detachnode(signing->db, &node);
6699 	return (result);
6700 }
6701 
6702 /*
6703  * If 'active' is set then we are not done with the chain yet so only
6704  * delete the nsec3param record which indicates a full chain exists
6705  * (flags == 0).
6706  */
6707 static isc_result_t
fixup_nsec3param(dns_db_t * db,dns_dbversion_t * ver,dns_nsec3chain_t * chain,isc_boolean_t active,dns_rdatatype_t privatetype,dns_diff_t * diff)6708 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
6709 		 isc_boolean_t active, dns_rdatatype_t privatetype,
6710 		 dns_diff_t *diff)
6711 {
6712 	dns_dbnode_t *node = NULL;
6713 	dns_name_t *name = dns_db_origin(db);
6714 	dns_rdata_t rdata = DNS_RDATA_INIT;
6715 	dns_rdataset_t rdataset;
6716 	dns_rdata_nsec3param_t nsec3param;
6717 	isc_result_t result;
6718 	isc_buffer_t buffer;
6719 	unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
6720 	dns_ttl_t ttl = 0;
6721 	isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE;
6722 
6723 	dns_rdataset_init(&rdataset);
6724 
6725 	result = dns_db_getoriginnode(db, &node);
6726 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
6727 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
6728 				     0, 0, &rdataset, NULL);
6729 	if (result == ISC_R_NOTFOUND)
6730 		goto try_private;
6731 	if (result != ISC_R_SUCCESS)
6732 		goto failure;
6733 
6734 	/*
6735 	 * Preserve the existing ttl.
6736 	 */
6737 	ttl = rdataset.ttl;
6738 
6739 	/*
6740 	 * Delete all NSEC3PARAM records which match that in nsec3chain.
6741 	 */
6742 	for (result = dns_rdataset_first(&rdataset);
6743 	     result == ISC_R_SUCCESS;
6744 	     result = dns_rdataset_next(&rdataset)) {
6745 
6746 		dns_rdataset_current(&rdataset, &rdata);
6747 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
6748 
6749 		if (nsec3param.hash != chain->nsec3param.hash ||
6750 		    (active && nsec3param.flags != 0) ||
6751 		    nsec3param.iterations != chain->nsec3param.iterations ||
6752 		    nsec3param.salt_length != chain->nsec3param.salt_length ||
6753 		    memcmp(nsec3param.salt, chain->nsec3param.salt,
6754 			   nsec3param.salt_length)) {
6755 			dns_rdata_reset(&rdata);
6756 			continue;
6757 		}
6758 
6759 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
6760 				    name, rdataset.ttl, &rdata));
6761 		dns_rdata_reset(&rdata);
6762 	}
6763 	if (result != ISC_R_NOMORE)
6764 		goto failure;
6765 
6766 	dns_rdataset_disassociate(&rdataset);
6767 
6768  try_private:
6769 
6770 	if (active)
6771 		goto add;
6772 
6773 	result = dns_nsec_nseconly(db, ver, &nseconly);
6774 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
6775 
6776 	/*
6777 	 * Delete all private records which match that in nsec3chain.
6778 	 */
6779 	result = dns_db_findrdataset(db, node, ver, privatetype,
6780 				     0, 0, &rdataset, NULL);
6781 	if (result == ISC_R_NOTFOUND)
6782 		goto add;
6783 	if (result != ISC_R_SUCCESS)
6784 		goto failure;
6785 
6786 	for (result = dns_rdataset_first(&rdataset);
6787 	     result == ISC_R_SUCCESS;
6788 	     result = dns_rdataset_next(&rdataset)) {
6789 		dns_rdata_t private = DNS_RDATA_INIT;
6790 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
6791 
6792 		dns_rdataset_current(&rdataset, &private);
6793 		if (!dns_nsec3param_fromprivate(&private, &rdata,
6794 						buf, sizeof(buf)))
6795 			continue;
6796 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
6797 
6798 		if ((!nsec3ok &&
6799 		     (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) ||
6800 		    nsec3param.hash != chain->nsec3param.hash ||
6801 		    nsec3param.iterations != chain->nsec3param.iterations ||
6802 		    nsec3param.salt_length != chain->nsec3param.salt_length ||
6803 		    memcmp(nsec3param.salt, chain->nsec3param.salt,
6804 			   nsec3param.salt_length)) {
6805 			dns_rdata_reset(&rdata);
6806 			continue;
6807 		}
6808 
6809 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
6810 				    name, rdataset.ttl, &private));
6811 		dns_rdata_reset(&rdata);
6812 	}
6813 	if (result != ISC_R_NOMORE)
6814 		goto failure;
6815 
6816   add:
6817 	if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
6818 		result = ISC_R_SUCCESS;
6819 		goto failure;
6820 	}
6821 
6822 	/*
6823 	 * Add a NSEC3PARAM record which matches that in nsec3chain but
6824 	 * with all flags bits cleared.
6825 	 *
6826 	 * Note: we do not clear chain->nsec3param.flags as this change
6827 	 * may be reversed.
6828 	 */
6829 	isc_buffer_init(&buffer, &parambuf, sizeof(parambuf));
6830 	CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
6831 				   dns_rdatatype_nsec3param,
6832 				   &chain->nsec3param, &buffer));
6833 	rdata.data[1] = 0;	/* Clear flag bits. */
6834 	CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
6835 
6836   failure:
6837 	dns_db_detachnode(db, &node);
6838 	if (dns_rdataset_isassociated(&rdataset))
6839 		dns_rdataset_disassociate(&rdataset);
6840 	return (result);
6841 }
6842 
6843 static isc_result_t
delete_nsec(dns_db_t * db,dns_dbversion_t * ver,dns_dbnode_t * node,dns_name_t * name,dns_diff_t * diff)6844 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
6845 	    dns_name_t *name, dns_diff_t *diff)
6846 {
6847 	dns_rdataset_t rdataset;
6848 	isc_result_t result;
6849 
6850 	dns_rdataset_init(&rdataset);
6851 
6852 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
6853 				     0, 0, &rdataset, NULL);
6854 	if (result == ISC_R_NOTFOUND)
6855 		return (ISC_R_SUCCESS);
6856 	if (result != ISC_R_SUCCESS)
6857 		return (result);
6858 	for (result = dns_rdataset_first(&rdataset);
6859 	     result == ISC_R_SUCCESS;
6860 	     result = dns_rdataset_next(&rdataset)) {
6861 		dns_rdata_t rdata = DNS_RDATA_INIT;
6862 
6863 		dns_rdataset_current(&rdataset, &rdata);
6864 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
6865 				    rdataset.ttl, &rdata));
6866 	}
6867 	if (result == ISC_R_NOMORE)
6868 		result = ISC_R_SUCCESS;
6869  failure:
6870 	dns_rdataset_disassociate(&rdataset);
6871 	return (result);
6872 }
6873 
6874 static isc_result_t
deletematchingnsec3(dns_db_t * db,dns_dbversion_t * ver,dns_dbnode_t * node,dns_name_t * name,const dns_rdata_nsec3param_t * param,dns_diff_t * diff)6875 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
6876 		    dns_name_t *name, const dns_rdata_nsec3param_t *param,
6877 		    dns_diff_t *diff)
6878 {
6879 	dns_rdataset_t rdataset;
6880 	dns_rdata_nsec3_t nsec3;
6881 	isc_result_t result;
6882 
6883 	dns_rdataset_init(&rdataset);
6884 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
6885 				     0, 0, &rdataset, NULL);
6886 	if (result == ISC_R_NOTFOUND)
6887 		return (ISC_R_SUCCESS);
6888 	if (result != ISC_R_SUCCESS)
6889 		return (result);
6890 
6891 	for (result = dns_rdataset_first(&rdataset);
6892 	     result == ISC_R_SUCCESS;
6893 	     result = dns_rdataset_next(&rdataset)) {
6894 		dns_rdata_t rdata = DNS_RDATA_INIT;
6895 
6896 		dns_rdataset_current(&rdataset, &rdata);
6897 		CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
6898 		if (nsec3.hash != param->hash ||
6899 		    nsec3.iterations != param->iterations ||
6900 		    nsec3.salt_length != param->salt_length ||
6901 		    memcmp(nsec3.salt, param->salt, nsec3.salt_length))
6902 			continue;
6903 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
6904 				    rdataset.ttl, &rdata));
6905 	}
6906 	if (result == ISC_R_NOMORE)
6907 		result = ISC_R_SUCCESS;
6908  failure:
6909 	dns_rdataset_disassociate(&rdataset);
6910 	return (result);
6911 }
6912 
6913 static isc_result_t
need_nsec_chain(dns_db_t * db,dns_dbversion_t * ver,const dns_rdata_nsec3param_t * param,isc_boolean_t * answer)6914 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
6915 		const dns_rdata_nsec3param_t *param,
6916 		isc_boolean_t *answer)
6917 {
6918 	dns_dbnode_t *node = NULL;
6919 	dns_rdata_t rdata = DNS_RDATA_INIT;
6920 	dns_rdata_nsec3param_t myparam;
6921 	dns_rdataset_t rdataset;
6922 	isc_result_t result;
6923 
6924 	*answer = ISC_FALSE;
6925 
6926 	result = dns_db_getoriginnode(db, &node);
6927 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
6928 
6929 	dns_rdataset_init(&rdataset);
6930 
6931 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
6932 				     0, 0, &rdataset, NULL);
6933 	if (result == ISC_R_SUCCESS) {
6934 		dns_rdataset_disassociate(&rdataset);
6935 		dns_db_detachnode(db, &node);
6936 		return (result);
6937 	}
6938 	if (result != ISC_R_NOTFOUND) {
6939 		dns_db_detachnode(db, &node);
6940 		return (result);
6941 	}
6942 
6943 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
6944 				     0, 0, &rdataset, NULL);
6945 	if (result == ISC_R_NOTFOUND) {
6946 		*answer = ISC_TRUE;
6947 		dns_db_detachnode(db, &node);
6948 		return (ISC_R_SUCCESS);
6949 	}
6950 	if (result != ISC_R_SUCCESS) {
6951 		dns_db_detachnode(db, &node);
6952 		return (result);
6953 	}
6954 
6955 	for (result = dns_rdataset_first(&rdataset);
6956 	     result == ISC_R_SUCCESS;
6957 	     result = dns_rdataset_next(&rdataset)) {
6958 		dns_rdataset_current(&rdataset, &rdata);
6959 		CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
6960 		dns_rdata_reset(&rdata);
6961 		/*
6962 		 * Ignore any NSEC3PARAM removals.
6963 		 */
6964 		if (NSEC3REMOVE(myparam.flags))
6965 			continue;
6966 		/*
6967 		 * Ignore the chain that we are in the process of deleting.
6968 		 */
6969 		if (myparam.hash == param->hash &&
6970 		    myparam.iterations == param->iterations &&
6971 		    myparam.salt_length == param->salt_length &&
6972 		    !memcmp(myparam.salt, param->salt, myparam.salt_length))
6973 			continue;
6974 		/*
6975 		 * Found an active NSEC3 chain.
6976 		 */
6977 		break;
6978 	}
6979 	if (result == ISC_R_NOMORE) {
6980 		*answer = ISC_TRUE;
6981 		result = ISC_R_SUCCESS;
6982 	}
6983 
6984  failure:
6985 	if (dns_rdataset_isassociated(&rdataset))
6986 		dns_rdataset_disassociate(&rdataset);
6987 	dns_db_detachnode(db, &node);
6988 	return (result);
6989 }
6990 
6991 static isc_result_t
update_sigs(dns_diff_t * diff,dns_db_t * db,dns_dbversion_t * version,dst_key_t * zone_keys[],unsigned int nkeys,dns_zone_t * zone,isc_stdtime_t inception,isc_stdtime_t expire,isc_stdtime_t now,isc_boolean_t check_ksk,isc_boolean_t keyset_kskonly,zonediff_t * zonediff)6992 update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
6993 	    dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone,
6994 	    isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now,
6995 	    isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly,
6996 	    zonediff_t *zonediff)
6997 {
6998 	dns_difftuple_t *tuple;
6999 	isc_result_t result;
7000 
7001 	for (tuple = ISC_LIST_HEAD(diff->tuples);
7002 	     tuple != NULL;
7003 	     tuple = ISC_LIST_HEAD(diff->tuples)) {
7004 		result = del_sigs(zone, db, version, &tuple->name,
7005 				  tuple->rdata.type, zonediff,
7006 				  zone_keys, nkeys, now, ISC_FALSE);
7007 		if (result != ISC_R_SUCCESS) {
7008 			dns_zone_log(zone, ISC_LOG_ERROR,
7009 				     "update_sigs:del_sigs -> %s",
7010 				     dns_result_totext(result));
7011 			return (result);
7012 		}
7013 		result = add_sigs(db, version, &tuple->name,
7014 				  tuple->rdata.type, zonediff->diff,
7015 				  zone_keys, nkeys, zone->mctx, inception,
7016 				  expire, check_ksk, keyset_kskonly);
7017 		if (result != ISC_R_SUCCESS) {
7018 			dns_zone_log(zone, ISC_LOG_ERROR,
7019 				     "update_sigs:add_sigs -> %s",
7020 				     dns_result_totext(result));
7021 			return (result);
7022 		}
7023 
7024 		do {
7025 			dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
7026 			while (next != NULL &&
7027 			       (tuple->rdata.type != next->rdata.type ||
7028 				!dns_name_equal(&tuple->name, &next->name)))
7029 				next = ISC_LIST_NEXT(next, link);
7030 			ISC_LIST_UNLINK(diff->tuples, tuple, link);
7031 			dns_diff_appendminimal(zonediff->diff, &tuple);
7032 			INSIST(tuple == NULL);
7033 			tuple = next;
7034 		} while (tuple != NULL);
7035 	}
7036 	return (ISC_R_SUCCESS);
7037 }
7038 
7039 /*
7040  * Incrementally build and sign a new NSEC3 chain using the parameters
7041  * requested.
7042  */
7043 static void
zone_nsec3chain(dns_zone_t * zone)7044 zone_nsec3chain(dns_zone_t *zone) {
7045 	const char *me = "zone_nsec3chain";
7046 	dns_db_t *db = NULL;
7047 	dns_dbnode_t *node = NULL;
7048 	dns_dbversion_t *version = NULL;
7049 	dns_diff_t _sig_diff;
7050 	dns_diff_t nsec_diff;
7051 	dns_diff_t nsec3_diff;
7052 	dns_diff_t param_diff;
7053 	zonediff_t zonediff;
7054 	dns_fixedname_t fixed;
7055 	dns_fixedname_t nextfixed;
7056 	dns_name_t *name, *nextname;
7057 	dns_rdataset_t rdataset;
7058 	dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
7059 	dns_nsec3chainlist_t cleanup;
7060 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
7061 	isc_int32_t signatures;
7062 	isc_boolean_t check_ksk, keyset_kskonly;
7063 	isc_boolean_t delegation;
7064 	isc_boolean_t first;
7065 	isc_result_t result;
7066 	isc_stdtime_t now, inception, soaexpire, expire;
7067 	isc_uint32_t jitter;
7068 	unsigned int i;
7069 	unsigned int nkeys = 0;
7070 	isc_uint32_t nodes;
7071 	isc_boolean_t unsecure = ISC_FALSE;
7072 	isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
7073 	isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
7074 	dns_rdatasetiter_t *iterator = NULL;
7075 	isc_boolean_t buildnsecchain;
7076 	isc_boolean_t updatensec = ISC_FALSE;
7077 	dns_rdatatype_t privatetype = zone->privatetype;
7078 
7079 	ENTER;
7080 
7081 	dns_rdataset_init(&rdataset);
7082 	dns_fixedname_init(&fixed);
7083 	name = dns_fixedname_name(&fixed);
7084 	dns_fixedname_init(&nextfixed);
7085 	nextname = dns_fixedname_name(&nextfixed);
7086 	dns_diff_init(zone->mctx, &param_diff);
7087 	dns_diff_init(zone->mctx, &nsec3_diff);
7088 	dns_diff_init(zone->mctx, &nsec_diff);
7089 	dns_diff_init(zone->mctx, &_sig_diff);
7090 	zonediff_init(&zonediff, &_sig_diff);
7091 	ISC_LIST_INIT(cleanup);
7092 
7093 	/*
7094 	 * Updates are disabled.  Pause for 5 minutes.
7095 	 */
7096 	if (zone->update_disabled) {
7097 		result = ISC_R_FAILURE;
7098 		goto failure;
7099 	}
7100 
7101 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7102 	dns_db_attach(zone->db, &db);
7103 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7104 
7105 	result = dns_db_newversion(db, &version);
7106 	if (result != ISC_R_SUCCESS) {
7107 		dns_zone_log(zone, ISC_LOG_ERROR,
7108 			     "zone_nsec3chain:dns_db_newversion -> %s",
7109 			     dns_result_totext(result));
7110 		goto failure;
7111 	}
7112 
7113 	result = find_zone_keys(zone, db, version, zone->mctx,
7114 				DNS_MAXZONEKEYS, zone_keys, &nkeys);
7115 	if (result != ISC_R_SUCCESS) {
7116 		dns_zone_log(zone, ISC_LOG_ERROR,
7117 			     "zone_nsec3chain:find_zone_keys -> %s",
7118 			     dns_result_totext(result));
7119 		goto failure;
7120 	}
7121 
7122 	isc_stdtime_get(&now);
7123 	inception = now - 3600;	/* Allow for clock skew. */
7124 	soaexpire = now + dns_zone_getsigvalidityinterval(zone);
7125 
7126 	/*
7127 	 * Spread out signatures over time if they happen to be
7128 	 * clumped.  We don't do this for each add_sigs() call as
7129 	 * we still want some clustering to occur.
7130 	 */
7131 	isc_random_get(&jitter);
7132 	expire = soaexpire - jitter % 3600;
7133 
7134 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
7135 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
7136 
7137 	/*
7138 	 * We keep pulling nodes off each iterator in turn until
7139 	 * we have no more nodes to pull off or we reach the limits
7140 	 * for this quantum.
7141 	 */
7142 	nodes = zone->nodes;
7143 	signatures = zone->signatures;
7144 	LOCK_ZONE(zone);
7145 	nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7146 	UNLOCK_ZONE(zone);
7147 	first = ISC_TRUE;
7148 
7149 	if (nsec3chain != NULL)
7150 		nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
7151 	/*
7152 	 * Generate new NSEC3 chains first.
7153 	 */
7154 	while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
7155 		LOCK_ZONE(zone);
7156 		nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
7157 
7158 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7159 		if (nsec3chain->done || nsec3chain->db != zone->db) {
7160 			ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
7161 			ISC_LIST_APPEND(cleanup, nsec3chain, link);
7162 		}
7163 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7164 		UNLOCK_ZONE(zone);
7165 		if (ISC_LIST_TAIL(cleanup) == nsec3chain)
7166 			goto next_addchain;
7167 
7168 		/*
7169 		 * Possible future db.
7170 		 */
7171 		if (nsec3chain->db != db) {
7172 			goto next_addchain;
7173 		}
7174 
7175 		if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
7176 			goto next_addchain;
7177 
7178 		dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
7179 
7180 		if (nsec3chain->delete_nsec) {
7181 			delegation = ISC_FALSE;
7182 			dns_dbiterator_pause(nsec3chain->dbiterator);
7183 			CHECK(delete_nsec(db, version, node, name, &nsec_diff));
7184 			goto next_addnode;
7185 		}
7186 		/*
7187 		 * On the first pass we need to check if the current node
7188 		 * has not been obscured.
7189 		 */
7190 		delegation = ISC_FALSE;
7191 		unsecure = ISC_FALSE;
7192 		if (first) {
7193 			dns_fixedname_t ffound;
7194 			dns_name_t *found;
7195 			dns_fixedname_init(&ffound);
7196 			found = dns_fixedname_name(&ffound);
7197 			result = dns_db_find(db, name, version,
7198 					     dns_rdatatype_soa,
7199 					     DNS_DBFIND_NOWILD, 0, NULL, found,
7200 					     NULL, NULL);
7201 			if ((result == DNS_R_DELEGATION ||
7202 			    result == DNS_R_DNAME) &&
7203 			    !dns_name_equal(name, found)) {
7204 				/*
7205 				 * Remember the obscuring name so that
7206 				 * we skip all obscured names.
7207 				 */
7208 				dns_name_copy(found, name, NULL);
7209 				delegation = ISC_TRUE;
7210 				goto next_addnode;
7211 			}
7212 		}
7213 
7214 		/*
7215 		 * Check to see if this is a bottom of zone node.
7216 		 */
7217 		result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7218 		if (result == ISC_R_NOTFOUND)	/* Empty node? */
7219 			goto next_addnode;
7220 		if (result != ISC_R_SUCCESS)
7221 			goto failure;
7222 
7223 		seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
7224 			ISC_FALSE;
7225 		for (result = dns_rdatasetiter_first(iterator);
7226 		     result == ISC_R_SUCCESS;
7227 		     result = dns_rdatasetiter_next(iterator)) {
7228 			dns_rdatasetiter_current(iterator, &rdataset);
7229 			INSIST(rdataset.type != dns_rdatatype_nsec3);
7230 			if (rdataset.type == dns_rdatatype_soa)
7231 				seen_soa = ISC_TRUE;
7232 			else if (rdataset.type == dns_rdatatype_ns)
7233 				seen_ns = ISC_TRUE;
7234 			else if (rdataset.type == dns_rdatatype_dname)
7235 				seen_dname = ISC_TRUE;
7236 			else if (rdataset.type == dns_rdatatype_ds)
7237 				seen_ds = ISC_TRUE;
7238 			else if (rdataset.type == dns_rdatatype_nsec)
7239 				seen_nsec = ISC_TRUE;
7240 			dns_rdataset_disassociate(&rdataset);
7241 		}
7242 		dns_rdatasetiter_destroy(&iterator);
7243 		/*
7244 		 * Is there a NSEC chain than needs to be cleaned up?
7245 		 */
7246 		if (seen_nsec)
7247 			nsec3chain->seen_nsec = ISC_TRUE;
7248 		if (seen_ns && !seen_soa && !seen_ds)
7249 			unsecure = ISC_TRUE;
7250 		if ((seen_ns && !seen_soa) || seen_dname)
7251 			delegation = ISC_TRUE;
7252 
7253 		/*
7254 		 * Process one node.
7255 		 */
7256 		dns_dbiterator_pause(nsec3chain->dbiterator);
7257 		result = dns_nsec3_addnsec3(db, version, name,
7258 					    &nsec3chain->nsec3param,
7259 					    zone->minimum, unsecure,
7260 					    &nsec3_diff);
7261 		if (result != ISC_R_SUCCESS) {
7262 			dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7263 				     "dns_nsec3_addnsec3 -> %s",
7264 				     dns_result_totext(result));
7265 			goto failure;
7266 		}
7267 
7268 		/*
7269 		 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
7270 		 * two signatures.  Additionally there will, in general, be
7271 		 * two signature generated below.
7272 		 *
7273 		 * If we are only changing the optout flag the cost is half
7274 		 * that of the cost of generating a completely new chain.
7275 		 */
7276 		signatures -= 4;
7277 
7278 		/*
7279 		 * Go onto next node.
7280 		 */
7281  next_addnode:
7282 		first = ISC_FALSE;
7283 		dns_db_detachnode(db, &node);
7284 		do {
7285 			result = dns_dbiterator_next(nsec3chain->dbiterator);
7286 
7287 			if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
7288 				dns_dbiterator_pause(nsec3chain->dbiterator);
7289 				CHECK(fixup_nsec3param(db, version, nsec3chain,
7290 						       ISC_FALSE, privatetype,
7291 						       &param_diff));
7292 				LOCK_ZONE(zone);
7293 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
7294 						link);
7295 				UNLOCK_ZONE(zone);
7296 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
7297 				goto next_addchain;
7298 			}
7299 			if (result == ISC_R_NOMORE) {
7300 				dns_dbiterator_pause(nsec3chain->dbiterator);
7301 				if (nsec3chain->seen_nsec) {
7302 					CHECK(fixup_nsec3param(db, version,
7303 							       nsec3chain,
7304 							       ISC_TRUE,
7305 							       privatetype,
7306 							       &param_diff));
7307 					nsec3chain->delete_nsec = ISC_TRUE;
7308 					goto same_addchain;
7309 				}
7310 				CHECK(fixup_nsec3param(db, version, nsec3chain,
7311 						       ISC_FALSE, privatetype,
7312 						       &param_diff));
7313 				LOCK_ZONE(zone);
7314 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
7315 						link);
7316 				UNLOCK_ZONE(zone);
7317 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
7318 				goto next_addchain;
7319 			} else if (result != ISC_R_SUCCESS) {
7320 				dns_zone_log(zone, ISC_LOG_ERROR,
7321 					     "zone_nsec3chain:"
7322 					     "dns_dbiterator_next -> %s",
7323 					     dns_result_totext(result));
7324 				goto failure;
7325 			} else if (delegation) {
7326 				dns_dbiterator_current(nsec3chain->dbiterator,
7327 						       &node, nextname);
7328 				dns_db_detachnode(db, &node);
7329 				if (!dns_name_issubdomain(nextname, name))
7330 					break;
7331 			} else
7332 				break;
7333 		} while (1);
7334 		continue;
7335 
7336  same_addchain:
7337 		CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
7338 		first = ISC_TRUE;
7339 		continue;
7340 
7341  next_addchain:
7342 		dns_dbiterator_pause(nsec3chain->dbiterator);
7343 		nsec3chain = nextnsec3chain;
7344 		first = ISC_TRUE;
7345 		if (nsec3chain != NULL)
7346 			nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
7347 	}
7348 
7349 	/*
7350 	 * Process removals.
7351 	 */
7352 	LOCK_ZONE(zone);
7353 	nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7354 	UNLOCK_ZONE(zone);
7355 	first = ISC_TRUE;
7356 	buildnsecchain = ISC_FALSE;
7357 	while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
7358 		LOCK_ZONE(zone);
7359 		nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
7360 		UNLOCK_ZONE(zone);
7361 
7362 		if (nsec3chain->db != db)
7363 			goto next_removechain;
7364 
7365 		if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
7366 			goto next_removechain;
7367 
7368 		/*
7369 		 * Work out if we need to build a NSEC chain as a consequence
7370 		 * of removing this NSEC3 chain.
7371 		 */
7372 		if (first && !updatensec &&
7373 		    (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
7374 		{
7375 			result = need_nsec_chain(db, version,
7376 						 &nsec3chain->nsec3param,
7377 						 &buildnsecchain);
7378 			if (result != ISC_R_SUCCESS) {
7379 				dns_zone_log(zone, ISC_LOG_ERROR,
7380 					     "zone_nsec3chain:"
7381 					     "need_nsec_chain -> %s",
7382 					     dns_result_totext(result));
7383 				goto failure;
7384 			}
7385 		}
7386 
7387 		if (first)
7388 			dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:"
7389 				     "buildnsecchain = %u\n", buildnsecchain);
7390 
7391 		dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
7392 		delegation = ISC_FALSE;
7393 
7394 		if (!buildnsecchain) {
7395 			/*
7396 			 * Delete the NSECPARAM record that matches this chain.
7397 			 */
7398 			if (first) {
7399 				result = fixup_nsec3param(db, version,
7400 							  nsec3chain,
7401 							  ISC_TRUE, privatetype,
7402 							  &param_diff);
7403 				if (result != ISC_R_SUCCESS) {
7404 					dns_zone_log(zone, ISC_LOG_ERROR,
7405 						     "zone_nsec3chain:"
7406 						     "fixup_nsec3param -> %s",
7407 						     dns_result_totext(result));
7408 					goto failure;
7409 				}
7410 			}
7411 
7412 			/*
7413 			 *  Delete the NSEC3 records.
7414 			 */
7415 			result = deletematchingnsec3(db, version, node, name,
7416 						     &nsec3chain->nsec3param,
7417 						     &nsec3_diff);
7418 			if (result != ISC_R_SUCCESS) {
7419 				dns_zone_log(zone, ISC_LOG_ERROR,
7420 					     "zone_nsec3chain:"
7421 					     "deletematchingnsec3 -> %s",
7422 					     dns_result_totext(result));
7423 				goto failure;
7424 			}
7425 			goto next_removenode;
7426 		}
7427 
7428 		if (first) {
7429 			dns_fixedname_t ffound;
7430 			dns_name_t *found;
7431 			dns_fixedname_init(&ffound);
7432 			found = dns_fixedname_name(&ffound);
7433 			result = dns_db_find(db, name, version,
7434 					     dns_rdatatype_soa,
7435 					     DNS_DBFIND_NOWILD, 0, NULL, found,
7436 					     NULL, NULL);
7437 			if ((result == DNS_R_DELEGATION ||
7438 			     result == DNS_R_DNAME) &&
7439 			    !dns_name_equal(name, found)) {
7440 				/*
7441 				 * Remember the obscuring name so that
7442 				 * we skip all obscured names.
7443 				 */
7444 				dns_name_copy(found, name, NULL);
7445 				delegation = ISC_TRUE;
7446 				goto next_removenode;
7447 			}
7448 		}
7449 
7450 		/*
7451 		 * Check to see if this is a bottom of zone node.
7452 		 */
7453 		result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7454 		if (result == ISC_R_NOTFOUND)	/* Empty node? */
7455 			goto next_removenode;
7456 		if (result != ISC_R_SUCCESS)
7457 			goto failure;
7458 
7459 		seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
7460 			seen_rr = ISC_FALSE;
7461 		for (result = dns_rdatasetiter_first(iterator);
7462 		     result == ISC_R_SUCCESS;
7463 		     result = dns_rdatasetiter_next(iterator)) {
7464 			dns_rdatasetiter_current(iterator, &rdataset);
7465 			if (rdataset.type == dns_rdatatype_soa)
7466 				seen_soa = ISC_TRUE;
7467 			else if (rdataset.type == dns_rdatatype_ns)
7468 				seen_ns = ISC_TRUE;
7469 			else if (rdataset.type == dns_rdatatype_dname)
7470 				seen_dname = ISC_TRUE;
7471 			else if (rdataset.type == dns_rdatatype_nsec)
7472 				seen_nsec = ISC_TRUE;
7473 			else if (rdataset.type == dns_rdatatype_nsec3)
7474 				seen_nsec3 = ISC_TRUE;
7475 			if (rdataset.type != dns_rdatatype_rrsig)
7476 				seen_rr = ISC_TRUE;
7477 			dns_rdataset_disassociate(&rdataset);
7478 		}
7479 		dns_rdatasetiter_destroy(&iterator);
7480 
7481 		if (!seen_rr || seen_nsec3 || seen_nsec)
7482 			goto next_removenode;
7483 		if ((seen_ns && !seen_soa) || seen_dname)
7484 			delegation = ISC_TRUE;
7485 
7486 		/*
7487 		 * Add a NSEC record except at the origin.
7488 		 */
7489 		if (!dns_name_equal(name, dns_db_origin(db))) {
7490 			dns_dbiterator_pause(nsec3chain->dbiterator);
7491 			CHECK(add_nsec(db, version, name, node, zone->minimum,
7492 				       delegation, &nsec_diff));
7493 		}
7494 
7495  next_removenode:
7496 		first = ISC_FALSE;
7497 		dns_db_detachnode(db, &node);
7498 		do {
7499 			result = dns_dbiterator_next(nsec3chain->dbiterator);
7500 			if (result == ISC_R_NOMORE && buildnsecchain) {
7501 				/*
7502 				 * The NSEC chain should now be built.
7503 				 * We can now remove the NSEC3 chain.
7504 				 */
7505 				updatensec = ISC_TRUE;
7506 				goto same_removechain;
7507 			}
7508 			if (result == ISC_R_NOMORE) {
7509 				LOCK_ZONE(zone);
7510 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
7511 						link);
7512 				UNLOCK_ZONE(zone);
7513 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
7514 				dns_dbiterator_pause(nsec3chain->dbiterator);
7515 				result = fixup_nsec3param(db, version,
7516 							  nsec3chain, ISC_FALSE,
7517 							  privatetype,
7518 							  &param_diff);
7519 				if (result != ISC_R_SUCCESS) {
7520 					dns_zone_log(zone, ISC_LOG_ERROR,
7521 						     "zone_nsec3chain:"
7522 						     "fixup_nsec3param -> %s",
7523 						     dns_result_totext(result));
7524 					goto failure;
7525 				}
7526 				goto next_removechain;
7527 			} else if (result != ISC_R_SUCCESS) {
7528 				dns_zone_log(zone, ISC_LOG_ERROR,
7529 					     "zone_nsec3chain:"
7530 					     "dns_dbiterator_next -> %s",
7531 					     dns_result_totext(result));
7532 				goto failure;
7533 			} else if (delegation) {
7534 				dns_dbiterator_current(nsec3chain->dbiterator,
7535 						       &node, nextname);
7536 				dns_db_detachnode(db, &node);
7537 				if (!dns_name_issubdomain(nextname, name))
7538 					break;
7539 			} else
7540 				break;
7541 		} while (1);
7542 		continue;
7543 
7544  same_removechain:
7545 		CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
7546 		buildnsecchain = ISC_FALSE;
7547 		first = ISC_TRUE;
7548 		continue;
7549 
7550  next_removechain:
7551 		dns_dbiterator_pause(nsec3chain->dbiterator);
7552 		nsec3chain = nextnsec3chain;
7553 		first = ISC_TRUE;
7554 	}
7555 
7556 	/*
7557 	 * We may need to update the NSEC/NSEC3 records for the zone apex.
7558 	 */
7559 	if (!ISC_LIST_EMPTY(param_diff.tuples)) {
7560 		isc_boolean_t rebuild_nsec = ISC_FALSE,
7561 			      rebuild_nsec3 = ISC_FALSE;
7562 		result = dns_db_getoriginnode(db, &node);
7563 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
7564 		result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7565 		if (result != ISC_R_SUCCESS) {
7566 			dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7567 				     "dns_db_allrdatasets -> %s",
7568 				     dns_result_totext(result));
7569 			goto failure;
7570 		}
7571 		for (result = dns_rdatasetiter_first(iterator);
7572 		     result == ISC_R_SUCCESS;
7573 		     result = dns_rdatasetiter_next(iterator)) {
7574 			dns_rdatasetiter_current(iterator, &rdataset);
7575 			if (rdataset.type == dns_rdatatype_nsec)
7576 				rebuild_nsec = ISC_TRUE;
7577 			if (rdataset.type == dns_rdatatype_nsec3param)
7578 				rebuild_nsec3 = ISC_TRUE;
7579 			dns_rdataset_disassociate(&rdataset);
7580 		}
7581 		dns_rdatasetiter_destroy(&iterator);
7582 		dns_db_detachnode(db, &node);
7583 
7584 		if (rebuild_nsec) {
7585 			if (nsec3chain != NULL)
7586 				dns_dbiterator_pause(nsec3chain->dbiterator);
7587 
7588 			result = updatesecure(db, version, &zone->origin,
7589 					      zone->minimum, ISC_TRUE,
7590 					      &nsec_diff);
7591 			if (result != ISC_R_SUCCESS) {
7592 				dns_zone_log(zone, ISC_LOG_ERROR,
7593 					     "zone_nsec3chain:"
7594 					     "updatesecure -> %s",
7595 					     dns_result_totext(result));
7596 				goto failure;
7597 			}
7598 		}
7599 
7600 		if (rebuild_nsec3) {
7601 			if (nsec3chain != NULL)
7602 				dns_dbiterator_pause(nsec3chain->dbiterator);
7603 
7604 			result = dns_nsec3_addnsec3s(db, version,
7605 						     dns_db_origin(db),
7606 						     zone->minimum, ISC_FALSE,
7607 						     &nsec3_diff);
7608 			if (result != ISC_R_SUCCESS) {
7609 				dns_zone_log(zone, ISC_LOG_ERROR,
7610 					     "zone_nsec3chain:"
7611 					     "dns_nsec3_addnsec3s -> %s",
7612 					     dns_result_totext(result));
7613 				goto failure;
7614 			}
7615 		}
7616 	}
7617 
7618 	if (nsec3chain != NULL)
7619 		dns_dbiterator_pause(nsec3chain->dbiterator);
7620 
7621 	/*
7622 	 * Add / update signatures for the NSEC3 records.
7623 	 */
7624 	if (nsec3chain != NULL)
7625 		dns_dbiterator_pause(nsec3chain->dbiterator);
7626 	result = update_sigs(&nsec3_diff, db, version, zone_keys,
7627 			     nkeys, zone, inception, expire, now,
7628 			     check_ksk, keyset_kskonly, &zonediff);
7629 	if (result != ISC_R_SUCCESS) {
7630 		dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7631 			     "update_sigs -> %s", dns_result_totext(result));
7632 		goto failure;
7633 	}
7634 
7635 	/*
7636 	 * We have changed the NSEC3PARAM or private RRsets
7637 	 * above so we need to update the signatures.
7638 	 */
7639 	result = update_sigs(&param_diff, db, version, zone_keys,
7640 			     nkeys, zone, inception, expire, now,
7641 			     check_ksk, keyset_kskonly, &zonediff);
7642 	if (result != ISC_R_SUCCESS) {
7643 		dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7644 			     "update_sigs -> %s", dns_result_totext(result));
7645 		goto failure;
7646 	}
7647 
7648 	if (updatensec) {
7649 		result = updatesecure(db, version, &zone->origin,
7650 				      zone->minimum, ISC_FALSE, &nsec_diff);
7651 		if (result != ISC_R_SUCCESS) {
7652 			dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7653 				     "updatesecure -> %s",
7654 				     dns_result_totext(result));
7655 			goto failure;
7656 		}
7657 	}
7658 
7659 	result = update_sigs(&nsec_diff, db, version, zone_keys,
7660 			     nkeys, zone, inception, expire, now,
7661 			     check_ksk, keyset_kskonly, &zonediff);
7662 	if (result != ISC_R_SUCCESS) {
7663 		dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7664 			     "update_sigs -> %s", dns_result_totext(result));
7665 		goto failure;
7666 	}
7667 
7668 	/*
7669 	 * If we made no effective changes to the zone then we can just
7670 	 * cleanup otherwise we need to increment the serial.
7671 	 */
7672 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
7673 		/*
7674 		 * No need to call dns_db_closeversion() here as it is
7675 		 * called with commit = ISC_TRUE below.
7676 		 */
7677 		goto done;
7678 	}
7679 
7680 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
7681 			  &zonediff, zone_keys, nkeys, now, ISC_FALSE);
7682 	if (result != ISC_R_SUCCESS) {
7683 		dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7684 			     "del_sigs -> %s", dns_result_totext(result));
7685 		goto failure;
7686 	}
7687 
7688 	result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
7689 				   zone->updatemethod);
7690 	if (result != ISC_R_SUCCESS) {
7691 		dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7692 			     "update_soa_serial -> %s",
7693 			     dns_result_totext(result));
7694 		goto failure;
7695 	}
7696 
7697 	result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
7698 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
7699 			  inception, soaexpire, check_ksk, keyset_kskonly);
7700 	if (result != ISC_R_SUCCESS) {
7701 		dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7702 			     "add_sigs -> %s", dns_result_totext(result));
7703 		goto failure;
7704 	}
7705 
7706 	/* Write changes to journal file. */
7707 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain"));
7708 
7709 	LOCK_ZONE(zone);
7710 	zone_needdump(zone, DNS_DUMP_DELAY);
7711 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
7712 	UNLOCK_ZONE(zone);
7713 
7714  done:
7715 	/*
7716 	 * Pause all iterators so that dns_db_closeversion() can succeed.
7717 	 */
7718 	LOCK_ZONE(zone);
7719 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7720 	     nsec3chain != NULL;
7721 	     nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
7722 		dns_dbiterator_pause(nsec3chain->dbiterator);
7723 	UNLOCK_ZONE(zone);
7724 
7725 	/*
7726 	 * Everything has succeeded. Commit the changes.
7727 	 * Unconditionally commit as zonediff.offline not checked above.
7728 	 */
7729 	dns_db_closeversion(db, &version, ISC_TRUE);
7730 
7731 	/*
7732 	 * Everything succeeded so we can clean these up now.
7733 	 */
7734 	nsec3chain = ISC_LIST_HEAD(cleanup);
7735 	while (nsec3chain != NULL) {
7736 		ISC_LIST_UNLINK(cleanup, nsec3chain, link);
7737 		dns_db_detach(&nsec3chain->db);
7738 		dns_dbiterator_destroy(&nsec3chain->dbiterator);
7739 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7740 		nsec3chain = ISC_LIST_HEAD(cleanup);
7741 	}
7742 
7743 	set_resigntime(zone);
7744 
7745  failure:
7746 	if (result != ISC_R_SUCCESS)
7747 		dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
7748 			     dns_result_totext(result));
7749 	/*
7750 	 * On error roll back the current nsec3chain.
7751 	 */
7752 	if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
7753 		if (nsec3chain->done) {
7754 			dns_db_detach(&nsec3chain->db);
7755 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
7756 			isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7757 		} else {
7758 			result = dns_dbiterator_first(nsec3chain->dbiterator);
7759 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
7760 			dns_dbiterator_pause(nsec3chain->dbiterator);
7761 			nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
7762 		}
7763 	}
7764 
7765 	/*
7766 	 * Rollback the cleanup list.
7767 	 */
7768 	nsec3chain = ISC_LIST_TAIL(cleanup);
7769 	while (nsec3chain != NULL) {
7770 		ISC_LIST_UNLINK(cleanup, nsec3chain, link);
7771 		if (nsec3chain->done) {
7772 			dns_db_detach(&nsec3chain->db);
7773 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
7774 			isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
7775 		} else {
7776 			LOCK_ZONE(zone);
7777 			ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
7778 			UNLOCK_ZONE(zone);
7779 			result = dns_dbiterator_first(nsec3chain->dbiterator);
7780 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
7781 			dns_dbiterator_pause(nsec3chain->dbiterator);
7782 			nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
7783 		}
7784 		nsec3chain = ISC_LIST_TAIL(cleanup);
7785 	}
7786 
7787 	LOCK_ZONE(zone);
7788 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7789 	     nsec3chain != NULL;
7790 	     nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
7791 		dns_dbiterator_pause(nsec3chain->dbiterator);
7792 	UNLOCK_ZONE(zone);
7793 
7794 	dns_diff_clear(&param_diff);
7795 	dns_diff_clear(&nsec3_diff);
7796 	dns_diff_clear(&nsec_diff);
7797 	dns_diff_clear(&_sig_diff);
7798 
7799 	if (iterator != NULL)
7800 		dns_rdatasetiter_destroy(&iterator);
7801 
7802 	for (i = 0; i < nkeys; i++)
7803 		dst_key_free(&zone_keys[i]);
7804 
7805 	if (node != NULL)
7806 		dns_db_detachnode(db, &node);
7807 	if (version != NULL) {
7808 		dns_db_closeversion(db, &version, ISC_FALSE);
7809 		dns_db_detach(&db);
7810 	} else if (db != NULL)
7811 		dns_db_detach(&db);
7812 
7813 	LOCK_ZONE(zone);
7814 	if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
7815 		isc_interval_t interval;
7816 		if (zone->update_disabled || result != ISC_R_SUCCESS)
7817 			isc_interval_set(&interval, 60, 0);	  /* 1 minute */
7818 		else
7819 			isc_interval_set(&interval, 0, 10000000); /* 10 ms */
7820 		isc_time_nowplusinterval(&zone->nsec3chaintime, &interval);
7821 	} else
7822 		isc_time_settoepoch(&zone->nsec3chaintime);
7823 	UNLOCK_ZONE(zone);
7824 
7825 	INSIST(version == NULL);
7826 }
7827 
7828 static isc_result_t
del_sig(dns_db_t * db,dns_dbversion_t * version,dns_name_t * name,dns_dbnode_t * node,unsigned int nkeys,dns_secalg_t algorithm,isc_uint16_t keyid,dns_diff_t * diff)7829 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
7830 	dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
7831 	isc_uint16_t keyid, dns_diff_t *diff)
7832 {
7833 	dns_rdata_rrsig_t rrsig;
7834 	dns_rdataset_t rdataset;
7835 	dns_rdatasetiter_t *iterator = NULL;
7836 	isc_result_t result;
7837 
7838 	result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7839 	if (result != ISC_R_SUCCESS) {
7840 		if (result == ISC_R_NOTFOUND)
7841 			result = ISC_R_SUCCESS;
7842 		return (result);
7843 	}
7844 
7845 	dns_rdataset_init(&rdataset);
7846 	for (result = dns_rdatasetiter_first(iterator);
7847 	     result == ISC_R_SUCCESS;
7848 	     result = dns_rdatasetiter_next(iterator)) {
7849 		dns_rdatasetiter_current(iterator, &rdataset);
7850 		if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
7851 			for (result = dns_rdataset_first(&rdataset);
7852 			     result == ISC_R_SUCCESS;
7853 			     result = dns_rdataset_next(&rdataset)) {
7854 				dns_rdata_t rdata = DNS_RDATA_INIT;
7855 				dns_rdataset_current(&rdataset, &rdata);
7856 				CHECK(update_one_rr(db, version, diff,
7857 						    DNS_DIFFOP_DEL, name,
7858 						    rdataset.ttl, &rdata));
7859 			}
7860 			if (result != ISC_R_NOMORE)
7861 				goto failure;
7862 			dns_rdataset_disassociate(&rdataset);
7863 			continue;
7864 		}
7865 		if (rdataset.type != dns_rdatatype_rrsig) {
7866 			dns_rdataset_disassociate(&rdataset);
7867 			continue;
7868 		}
7869 		for (result = dns_rdataset_first(&rdataset);
7870 		     result == ISC_R_SUCCESS;
7871 		     result = dns_rdataset_next(&rdataset)) {
7872 			dns_rdata_t rdata = DNS_RDATA_INIT;
7873 			dns_rdataset_current(&rdataset, &rdata);
7874 			CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
7875 			if (rrsig.algorithm != algorithm ||
7876 			    rrsig.keyid != keyid)
7877 				continue;
7878 			CHECK(update_one_rr(db, version, diff,
7879 					    DNS_DIFFOP_DELRESIGN, name,
7880 					    rdataset.ttl, &rdata));
7881 		}
7882 		dns_rdataset_disassociate(&rdataset);
7883 		if (result != ISC_R_NOMORE)
7884 			break;
7885 	}
7886 	if (result == ISC_R_NOMORE)
7887 		result = ISC_R_SUCCESS;
7888  failure:
7889 	if (dns_rdataset_isassociated(&rdataset))
7890 		dns_rdataset_disassociate(&rdataset);
7891 	dns_rdatasetiter_destroy(&iterator);
7892 	return (result);
7893 }
7894 
7895 /*
7896  * Incrementally sign the zone using the keys requested.
7897  * Builds the NSEC chain if required.
7898  */
7899 static void
zone_sign(dns_zone_t * zone)7900 zone_sign(dns_zone_t *zone) {
7901 	const char *me = "zone_sign";
7902 	dns_db_t *db = NULL;
7903 	dns_dbnode_t *node = NULL;
7904 	dns_dbversion_t *version = NULL;
7905 	dns_diff_t _sig_diff;
7906 	dns_diff_t post_diff;
7907 	zonediff_t zonediff;
7908 	dns_fixedname_t fixed;
7909 	dns_fixedname_t nextfixed;
7910 	dns_name_t *name, *nextname;
7911 	dns_rdataset_t rdataset;
7912 	dns_signing_t *signing, *nextsigning;
7913 	dns_signinglist_t cleanup;
7914 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
7915 	isc_int32_t signatures;
7916 	isc_boolean_t check_ksk, keyset_kskonly, is_ksk;
7917 	isc_boolean_t commit = ISC_FALSE;
7918 	isc_boolean_t delegation;
7919 	isc_boolean_t build_nsec = ISC_FALSE;
7920 	isc_boolean_t build_nsec3 = ISC_FALSE;
7921 	isc_boolean_t first;
7922 	isc_result_t result;
7923 	isc_stdtime_t now, inception, soaexpire, expire;
7924 	isc_uint32_t jitter;
7925 	unsigned int i, j;
7926 	unsigned int nkeys = 0;
7927 	isc_uint32_t nodes;
7928 
7929 	ENTER;
7930 
7931 	dns_rdataset_init(&rdataset);
7932 	dns_fixedname_init(&fixed);
7933 	name = dns_fixedname_name(&fixed);
7934 	dns_fixedname_init(&nextfixed);
7935 	nextname = dns_fixedname_name(&nextfixed);
7936 	dns_diff_init(zone->mctx, &_sig_diff);
7937 	dns_diff_init(zone->mctx, &post_diff);
7938 	zonediff_init(&zonediff, &_sig_diff);
7939 	ISC_LIST_INIT(cleanup);
7940 
7941 	/*
7942 	 * Updates are disabled.  Pause for 5 minutes.
7943 	 */
7944 	if (zone->update_disabled) {
7945 		result = ISC_R_FAILURE;
7946 		goto failure;
7947 	}
7948 
7949 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7950 	if (zone->db != NULL)
7951 		dns_db_attach(zone->db, &db);
7952 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7953 	if (db == NULL) {
7954 		result = ISC_R_FAILURE;
7955 		goto failure;
7956 	}
7957 
7958 	result = dns_db_newversion(db, &version);
7959 	if (result != ISC_R_SUCCESS) {
7960 		dns_zone_log(zone, ISC_LOG_ERROR,
7961 			     "zone_sign:dns_db_newversion -> %s",
7962 			     dns_result_totext(result));
7963 		goto failure;
7964 	}
7965 
7966 	result = find_zone_keys(zone, db, version, zone->mctx,
7967 				DNS_MAXZONEKEYS, zone_keys, &nkeys);
7968 	if (result != ISC_R_SUCCESS) {
7969 		dns_zone_log(zone, ISC_LOG_ERROR,
7970 			     "zone_sign:find_zone_keys -> %s",
7971 			     dns_result_totext(result));
7972 		goto failure;
7973 	}
7974 
7975 	isc_stdtime_get(&now);
7976 	inception = now - 3600;	/* Allow for clock skew. */
7977 	soaexpire = now + dns_zone_getsigvalidityinterval(zone);
7978 
7979 	/*
7980 	 * Spread out signatures over time if they happen to be
7981 	 * clumped.  We don't do this for each add_sigs() call as
7982 	 * we still want some clustering to occur.
7983 	 */
7984 	isc_random_get(&jitter);
7985 	expire = soaexpire - jitter % 3600;
7986 
7987 	/*
7988 	 * We keep pulling nodes off each iterator in turn until
7989 	 * we have no more nodes to pull off or we reach the limits
7990 	 * for this quantum.
7991 	 */
7992 	nodes = zone->nodes;
7993 	signatures = zone->signatures;
7994 	signing = ISC_LIST_HEAD(zone->signing);
7995 	first = ISC_TRUE;
7996 
7997 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
7998 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
7999 
8000 	/* Determine which type of chain to build */
8001 	CHECK(dns_private_chains(db, version, zone->privatetype,
8002 				 &build_nsec, &build_nsec3));
8003 
8004 	/* If neither chain is found, default to NSEC */
8005 	if (!build_nsec && !build_nsec3)
8006 		build_nsec = ISC_TRUE;
8007 
8008 	while (signing != NULL && nodes-- > 0 && signatures > 0) {
8009 		nextsigning = ISC_LIST_NEXT(signing, link);
8010 
8011 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8012 		if (signing->done || signing->db != zone->db) {
8013 			/*
8014 			 * The zone has been reloaded.	We will have
8015 			 * created new signings as part of the reload
8016 			 * process so we can destroy this one.
8017 			 */
8018 			ISC_LIST_UNLINK(zone->signing, signing, link);
8019 			ISC_LIST_APPEND(cleanup, signing, link);
8020 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8021 			goto next_signing;
8022 		}
8023 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8024 
8025 		if (signing->db != db)
8026 			goto next_signing;
8027 
8028 		delegation = ISC_FALSE;
8029 
8030 		if (first && signing->delete) {
8031 			/*
8032 			 * Remove the key we are deleting from consideration.
8033 			 */
8034 			for (i = 0, j = 0; i < nkeys; i++) {
8035 				/*
8036 				 * Find the key we want to remove.
8037 				 */
8038 				if (ALG(zone_keys[i]) == signing->algorithm &&
8039 				    dst_key_id(zone_keys[i]) == signing->keyid)
8040 				{
8041 					if (KSK(zone_keys[i]))
8042 						dst_key_free(&zone_keys[i]);
8043 					continue;
8044 				}
8045 				zone_keys[j] = zone_keys[i];
8046 				j++;
8047 			}
8048 			nkeys = j;
8049 		}
8050 
8051 		dns_dbiterator_current(signing->dbiterator, &node, name);
8052 
8053 		if (signing->delete) {
8054 			dns_dbiterator_pause(signing->dbiterator);
8055 			CHECK(del_sig(db, version, name, node, nkeys,
8056 				      signing->algorithm, signing->keyid,
8057 				      zonediff.diff));
8058 		}
8059 
8060 		/*
8061 		 * On the first pass we need to check if the current node
8062 		 * has not been obscured.
8063 		 */
8064 		if (first) {
8065 			dns_fixedname_t ffound;
8066 			dns_name_t *found;
8067 			dns_fixedname_init(&ffound);
8068 			found = dns_fixedname_name(&ffound);
8069 			result = dns_db_find(db, name, version,
8070 					     dns_rdatatype_soa,
8071 					     DNS_DBFIND_NOWILD, 0, NULL, found,
8072 					     NULL, NULL);
8073 			if ((result == DNS_R_DELEGATION ||
8074 			    result == DNS_R_DNAME) &&
8075 			    !dns_name_equal(name, found)) {
8076 				/*
8077 				 * Remember the obscuring name so that
8078 				 * we skip all obscured names.
8079 				 */
8080 				dns_name_copy(found, name, NULL);
8081 				delegation = ISC_TRUE;
8082 				goto next_node;
8083 			}
8084 		}
8085 
8086 		/*
8087 		 * Process one node.
8088 		 */
8089 		dns_dbiterator_pause(signing->dbiterator);
8090 		for (i = 0; i < nkeys; i++) {
8091 			isc_boolean_t both = ISC_FALSE;
8092 
8093 			/*
8094 			 * Find the keys we want to sign with.
8095 			 */
8096 			if (!dst_key_isprivate(zone_keys[i]))
8097 				continue;
8098 
8099 			/*
8100 			 * When adding look for the specific key.
8101 			 */
8102 			if (!signing->delete &&
8103 			    (dst_key_alg(zone_keys[i]) != signing->algorithm ||
8104 			     dst_key_id(zone_keys[i]) != signing->keyid))
8105 				continue;
8106 
8107 			/*
8108 			 * When deleting make sure we are properly signed
8109 			 * with the algorithm that was being removed.
8110 			 */
8111 			if (signing->delete &&
8112 			    ALG(zone_keys[i]) != signing->algorithm)
8113 				continue;
8114 
8115 			/*
8116 			 * Do we do KSK processing?
8117 			 */
8118 			if (check_ksk && !REVOKE(zone_keys[i])) {
8119 				isc_boolean_t have_ksk, have_nonksk;
8120 				if (KSK(zone_keys[i])) {
8121 					have_ksk = ISC_TRUE;
8122 					have_nonksk = ISC_FALSE;
8123 				} else {
8124 					have_ksk = ISC_FALSE;
8125 					have_nonksk = ISC_TRUE;
8126 				}
8127 				for (j = 0; j < nkeys; j++) {
8128 					if (j == i ||
8129 					    ALG(zone_keys[i]) !=
8130 					    ALG(zone_keys[j]))
8131 						continue;
8132 					if (REVOKE(zone_keys[j]))
8133 						continue;
8134 					if (KSK(zone_keys[j]))
8135 						have_ksk = ISC_TRUE;
8136 					else
8137 						have_nonksk = ISC_TRUE;
8138 					both = have_ksk && have_nonksk;
8139 					if (both)
8140 						break;
8141 				}
8142 			}
8143 			if (both || REVOKE(zone_keys[i]))
8144 				is_ksk = KSK(zone_keys[i]);
8145 			else
8146 				is_ksk = ISC_FALSE;
8147 
8148 			CHECK(sign_a_node(db, name, node, version, build_nsec3,
8149 					  build_nsec, zone_keys[i], inception,
8150 					  expire, zone->minimum, is_ksk,
8151 					  ISC_TF(both && keyset_kskonly),
8152 					  &delegation, zonediff.diff,
8153 					  &signatures, zone->mctx));
8154 			/*
8155 			 * If we are adding we are done.  Look for other keys
8156 			 * of the same algorithm if deleting.
8157 			 */
8158 			if (!signing->delete)
8159 				break;
8160 		}
8161 
8162 		/*
8163 		 * Go onto next node.
8164 		 */
8165  next_node:
8166 		first = ISC_FALSE;
8167 		dns_db_detachnode(db, &node);
8168 		do {
8169 			result = dns_dbiterator_next(signing->dbiterator);
8170 			if (result == ISC_R_NOMORE) {
8171 				ISC_LIST_UNLINK(zone->signing, signing, link);
8172 				ISC_LIST_APPEND(cleanup, signing, link);
8173 				dns_dbiterator_pause(signing->dbiterator);
8174 				if (nkeys != 0 && build_nsec) {
8175 					/*
8176 					 * We have finished regenerating the
8177 					 * zone with a zone signing key.
8178 					 * The NSEC chain is now complete and
8179 					 * there is a full set of signatures
8180 					 * for the zone.  We can now clear the
8181 					 * OPT bit from the NSEC record.
8182 					 */
8183 					result = updatesecure(db, version,
8184 							      &zone->origin,
8185 							      zone->minimum,
8186 							      ISC_FALSE,
8187 							      &post_diff);
8188 					if (result != ISC_R_SUCCESS) {
8189 						dns_zone_log(zone,
8190 							     ISC_LOG_ERROR,
8191 						    "updatesecure -> %s",
8192 						    dns_result_totext(result));
8193 						goto failure;
8194 					}
8195 				}
8196 				result = updatesignwithkey(zone, signing,
8197 							   version,
8198 							   build_nsec3,
8199 							   zone->minimum,
8200 							   &post_diff);
8201 				if (result != ISC_R_SUCCESS) {
8202 					dns_zone_log(zone, ISC_LOG_ERROR,
8203 						     "updatesignwithkey -> %s",
8204 						     dns_result_totext(result));
8205 					goto failure;
8206 				}
8207 				build_nsec = ISC_FALSE;
8208 				goto next_signing;
8209 			} else if (result != ISC_R_SUCCESS) {
8210 				dns_zone_log(zone, ISC_LOG_ERROR,
8211 					"zone_sign:dns_dbiterator_next -> %s",
8212 					     dns_result_totext(result));
8213 				goto failure;
8214 			} else if (delegation) {
8215 				dns_dbiterator_current(signing->dbiterator,
8216 						       &node, nextname);
8217 				dns_db_detachnode(db, &node);
8218 				if (!dns_name_issubdomain(nextname, name))
8219 					break;
8220 			} else
8221 				break;
8222 		} while (1);
8223 		continue;
8224 
8225  next_signing:
8226 		dns_dbiterator_pause(signing->dbiterator);
8227 		signing = nextsigning;
8228 		first = ISC_TRUE;
8229 	}
8230 
8231 	if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
8232 		result = update_sigs(&post_diff, db, version, zone_keys,
8233 				     nkeys, zone, inception, expire, now,
8234 				     check_ksk, keyset_kskonly, &zonediff);
8235 		if (result != ISC_R_SUCCESS) {
8236 			dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
8237 				     "update_sigs -> %s",
8238 				     dns_result_totext(result));
8239 			goto failure;
8240 		}
8241 	}
8242 
8243 	/*
8244 	 * Have we changed anything?
8245 	 */
8246 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
8247 		if (zonediff.offline)
8248 			commit = ISC_TRUE;
8249 		result = ISC_R_SUCCESS;
8250 		goto pauseall;
8251 	}
8252 
8253 	commit = ISC_TRUE;
8254 
8255 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
8256 			  &zonediff, zone_keys, nkeys, now, ISC_FALSE);
8257 	if (result != ISC_R_SUCCESS) {
8258 		dns_zone_log(zone, ISC_LOG_ERROR,
8259 			     "zone_sign:del_sigs -> %s",
8260 			     dns_result_totext(result));
8261 		goto failure;
8262 	}
8263 
8264 	result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
8265 				   zone->updatemethod);
8266 	if (result != ISC_R_SUCCESS) {
8267 		dns_zone_log(zone, ISC_LOG_ERROR,
8268 			     "zone_sign:update_soa_serial -> %s",
8269 			     dns_result_totext(result));
8270 		goto failure;
8271 	}
8272 
8273 	/*
8274 	 * Generate maximum life time signatures so that the above loop
8275 	 * termination is sensible.
8276 	 */
8277 	result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
8278 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
8279 			  inception, soaexpire, check_ksk, keyset_kskonly);
8280 	if (result != ISC_R_SUCCESS) {
8281 		dns_zone_log(zone, ISC_LOG_ERROR,
8282 			     "zone_sign:add_sigs -> %s",
8283 			     dns_result_totext(result));
8284 		goto failure;
8285 	}
8286 
8287 	/*
8288 	 * Write changes to journal file.
8289 	 */
8290 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign"));
8291 
8292  pauseall:
8293 	/*
8294 	 * Pause all iterators so that dns_db_closeversion() can succeed.
8295 	 */
8296 	for (signing = ISC_LIST_HEAD(zone->signing);
8297 	     signing != NULL;
8298 	     signing = ISC_LIST_NEXT(signing, link))
8299 		dns_dbiterator_pause(signing->dbiterator);
8300 
8301 	for (signing = ISC_LIST_HEAD(cleanup);
8302 	     signing != NULL;
8303 	     signing = ISC_LIST_NEXT(signing, link))
8304 		dns_dbiterator_pause(signing->dbiterator);
8305 
8306 	/*
8307 	 * Everything has succeeded. Commit the changes.
8308 	 */
8309 	dns_db_closeversion(db, &version, commit);
8310 
8311 	/*
8312 	 * Everything succeeded so we can clean these up now.
8313 	 */
8314 	signing = ISC_LIST_HEAD(cleanup);
8315 	while (signing != NULL) {
8316 		ISC_LIST_UNLINK(cleanup, signing, link);
8317 		dns_db_detach(&signing->db);
8318 		dns_dbiterator_destroy(&signing->dbiterator);
8319 		isc_mem_put(zone->mctx, signing, sizeof *signing);
8320 		signing = ISC_LIST_HEAD(cleanup);
8321 	}
8322 
8323 	set_resigntime(zone);
8324 
8325 	if (commit) {
8326 		LOCK_ZONE(zone);
8327 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
8328 		zone_needdump(zone, DNS_DUMP_DELAY);
8329 		UNLOCK_ZONE(zone);
8330 	}
8331 
8332  failure:
8333 	/*
8334 	 * Rollback the cleanup list.
8335 	 */
8336 	signing = ISC_LIST_HEAD(cleanup);
8337 	while (signing != NULL) {
8338 		ISC_LIST_UNLINK(cleanup, signing, link);
8339 		ISC_LIST_PREPEND(zone->signing, signing, link);
8340 		dns_dbiterator_first(signing->dbiterator);
8341 		dns_dbiterator_pause(signing->dbiterator);
8342 		signing = ISC_LIST_HEAD(cleanup);
8343 	}
8344 
8345 	for (signing = ISC_LIST_HEAD(zone->signing);
8346 	     signing != NULL;
8347 	     signing = ISC_LIST_NEXT(signing, link))
8348 		dns_dbiterator_pause(signing->dbiterator);
8349 
8350 	dns_diff_clear(&_sig_diff);
8351 
8352 	for (i = 0; i < nkeys; i++)
8353 		dst_key_free(&zone_keys[i]);
8354 
8355 	if (node != NULL)
8356 		dns_db_detachnode(db, &node);
8357 
8358 	if (version != NULL) {
8359 		dns_db_closeversion(db, &version, ISC_FALSE);
8360 		dns_db_detach(&db);
8361 	} else if (db != NULL)
8362 		dns_db_detach(&db);
8363 
8364 	if (ISC_LIST_HEAD(zone->signing) != NULL) {
8365 		isc_interval_t interval;
8366 		if (zone->update_disabled || result != ISC_R_SUCCESS)
8367 			isc_interval_set(&interval, 60, 0);	  /* 1 minute */
8368 		else
8369 			isc_interval_set(&interval, 0, 10000000); /* 10 ms */
8370 		isc_time_nowplusinterval(&zone->signingtime, &interval);
8371 	} else
8372 		isc_time_settoepoch(&zone->signingtime);
8373 
8374 	INSIST(version == NULL);
8375 }
8376 
8377 static isc_result_t
normalize_key(dns_rdata_t * rr,dns_rdata_t * target,unsigned char * data,int size)8378 normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
8379 	      unsigned char *data, int size)
8380 {
8381 	dns_rdata_dnskey_t dnskey;
8382 	dns_rdata_keydata_t keydata;
8383 	isc_buffer_t buf;
8384 	isc_result_t result;
8385 
8386 	dns_rdata_reset(target);
8387 	isc_buffer_init(&buf, data, size);
8388 
8389 	switch (rr->type) {
8390 	    case dns_rdatatype_dnskey:
8391 		result = dns_rdata_tostruct(rr, &dnskey, NULL);
8392 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
8393 		dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
8394 		dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
8395 				     &dnskey, &buf);
8396 		break;
8397 	    case dns_rdatatype_keydata:
8398 		result = dns_rdata_tostruct(rr, &keydata, NULL);
8399 		if (result == ISC_R_UNEXPECTEDEND)
8400 			return (result);
8401 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
8402 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
8403 		dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
8404 				     &dnskey, &buf);
8405 		break;
8406 	    default:
8407 		INSIST(0);
8408 	}
8409 	return (ISC_R_SUCCESS);
8410 }
8411 
8412 /*
8413  * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
8414  * a KEYDATA rdataset from the key zone.
8415  *
8416  * 'rr' contains either a DNSKEY record, or a KEYDATA record
8417  *
8418  * After normalizing keys to the same format (DNSKEY, with revoke bit
8419  * cleared), return ISC_TRUE if a key that matches 'rr' is found in
8420  * 'rdset', or ISC_FALSE if not.
8421  */
8422 
8423 static isc_boolean_t
matchkey(dns_rdataset_t * rdset,dns_rdata_t * rr)8424 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
8425 	unsigned char data1[4096], data2[4096];
8426 	dns_rdata_t rdata, rdata1, rdata2;
8427 	isc_result_t result;
8428 
8429 	dns_rdata_init(&rdata);
8430 	dns_rdata_init(&rdata1);
8431 	dns_rdata_init(&rdata2);
8432 
8433 	result = normalize_key(rr, &rdata1, data1, sizeof(data1));
8434 	if (result != ISC_R_SUCCESS)
8435 		return (ISC_FALSE);
8436 
8437 	for (result = dns_rdataset_first(rdset);
8438 	     result == ISC_R_SUCCESS;
8439 	     result = dns_rdataset_next(rdset)) {
8440 		dns_rdata_reset(&rdata);
8441 		dns_rdataset_current(rdset, &rdata);
8442 		result = normalize_key(&rdata, &rdata2, data2, sizeof(data2));
8443 		if (result != ISC_R_SUCCESS)
8444 			continue;
8445 		if (dns_rdata_compare(&rdata1, &rdata2) == 0)
8446 			return (ISC_TRUE);
8447 	}
8448 
8449 	return (ISC_FALSE);
8450 }
8451 
8452 /*
8453  * Calculate the refresh interval for a keydata zone, per
8454  * RFC5011: MAX(1 hr,
8455  *		MIN(15 days,
8456  *		    1/2 * OrigTTL,
8457  *		    1/2 * RRSigExpirationInterval))
8458  * or for retries: MAX(1 hr,
8459  *		       MIN(1 day,
8460  *			   1/10 * OrigTTL,
8461  *			   1/10 * RRSigExpirationInterval))
8462  */
8463 static inline isc_stdtime_t
refresh_time(dns_keyfetch_t * kfetch,isc_boolean_t retry)8464 refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
8465 	isc_result_t result;
8466 	isc_uint32_t t;
8467 	dns_rdataset_t *rdset;
8468 	dns_rdata_t sigrr = DNS_RDATA_INIT;
8469 	dns_rdata_sig_t sig;
8470 	isc_stdtime_t now;
8471 
8472 	isc_stdtime_get(&now);
8473 
8474 	if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
8475 		rdset = &kfetch->dnskeysigset;
8476 	else
8477 		return (now + dns_zone_mkey_hour);
8478 
8479 	result = dns_rdataset_first(rdset);
8480 	if (result != ISC_R_SUCCESS)
8481 		return (now + dns_zone_mkey_hour);
8482 
8483 	dns_rdataset_current(rdset, &sigrr);
8484 	result = dns_rdata_tostruct(&sigrr, &sig, NULL);
8485 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
8486 
8487 	if (!retry) {
8488 		t = sig.originalttl / 2;
8489 
8490 		if (isc_serial_gt(sig.timeexpire, now)) {
8491 			isc_uint32_t exp = (sig.timeexpire - now) / 2;
8492 			if (t > exp)
8493 				t = exp;
8494 		}
8495 
8496 		if (t > (15 * dns_zone_mkey_day))
8497 			t = (15 * dns_zone_mkey_day);
8498 
8499 		if (t < dns_zone_mkey_hour)
8500 			t = dns_zone_mkey_hour;
8501 	} else {
8502 		t = sig.originalttl / 10;
8503 
8504 		if (isc_serial_gt(sig.timeexpire, now)) {
8505 			isc_uint32_t exp = (sig.timeexpire - now) / 10;
8506 			if (t > exp)
8507 				t = exp;
8508 		}
8509 
8510 		if (t > dns_zone_mkey_day)
8511 			t = dns_zone_mkey_day;
8512 
8513 		if (t < dns_zone_mkey_hour)
8514 			t = dns_zone_mkey_hour;
8515 	}
8516 
8517 	return (now + t);
8518 }
8519 
8520 /*
8521  * This routine is called when no changes are needed in a KEYDATA
8522  * record except to simply update the refresh timer.  Caller should
8523  * hold zone lock.
8524  */
8525 static isc_result_t
minimal_update(dns_keyfetch_t * kfetch,dns_dbversion_t * ver,dns_diff_t * diff)8526 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
8527 {
8528 	isc_result_t result;
8529 	isc_buffer_t keyb;
8530 	unsigned char key_buf[4096];
8531 	dns_rdata_t rdata = DNS_RDATA_INIT;
8532 	dns_rdata_keydata_t keydata;
8533 	dns_name_t *name;
8534 	dns_zone_t *zone = kfetch->zone;
8535 	isc_stdtime_t now;
8536 
8537 	name = dns_fixedname_name(&kfetch->name);
8538 	isc_stdtime_get(&now);
8539 
8540 	for (result = dns_rdataset_first(&kfetch->keydataset);
8541 	     result == ISC_R_SUCCESS;
8542 	     result = dns_rdataset_next(&kfetch->keydataset)) {
8543 		dns_rdata_reset(&rdata);
8544 		dns_rdataset_current(&kfetch->keydataset, &rdata);
8545 
8546 		/* Delete old version */
8547 		CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
8548 				    name, 0, &rdata));
8549 
8550 		/* Update refresh timer */
8551 		result = dns_rdata_tostruct(&rdata, &keydata, NULL);
8552 		if (result == ISC_R_UNEXPECTEDEND)
8553 			continue;
8554 		if (result != ISC_R_SUCCESS)
8555 			goto failure;
8556 		keydata.refresh = refresh_time(kfetch, ISC_TRUE);
8557 		set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
8558 
8559 		dns_rdata_reset(&rdata);
8560 		isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8561 		CHECK(dns_rdata_fromstruct(&rdata,
8562 					   zone->rdclass, dns_rdatatype_keydata,
8563 					   &keydata, &keyb));
8564 
8565 		/* Insert updated version */
8566 		CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
8567 				    name, 0, &rdata));
8568 	}
8569 	result = ISC_R_SUCCESS;
8570   failure:
8571 	return (result);
8572 }
8573 
8574 /*
8575  * Verify that DNSKEY set is signed by the key specified in 'keydata'.
8576  */
8577 static isc_boolean_t
revocable(dns_keyfetch_t * kfetch,dns_rdata_keydata_t * keydata)8578 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
8579 	isc_result_t result;
8580 	dns_name_t *keyname;
8581 	isc_mem_t *mctx;
8582 	dns_rdata_t sigrr = DNS_RDATA_INIT;
8583 	dns_rdata_t rr = DNS_RDATA_INIT;
8584 	dns_rdata_rrsig_t sig;
8585 	dns_rdata_dnskey_t dnskey;
8586 	dst_key_t *dstkey = NULL;
8587 	unsigned char key_buf[4096];
8588 	isc_buffer_t keyb;
8589 	isc_boolean_t answer = ISC_FALSE;
8590 
8591 	REQUIRE(kfetch != NULL && keydata != NULL);
8592 	REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
8593 
8594 	keyname = dns_fixedname_name(&kfetch->name);
8595 	mctx = kfetch->zone->view->mctx;
8596 
8597 	/* Generate a key from keydata */
8598 	isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8599 	dns_keydata_todnskey(keydata, &dnskey, NULL);
8600 	dns_rdata_fromstruct(&rr, keydata->common.rdclass,
8601 			     dns_rdatatype_dnskey, &dnskey, &keyb);
8602 	result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
8603 	if (result != ISC_R_SUCCESS)
8604 		return (ISC_FALSE);
8605 
8606 	/* See if that key generated any of the signatures */
8607 	for (result = dns_rdataset_first(&kfetch->dnskeysigset);
8608 	     result == ISC_R_SUCCESS;
8609 	     result = dns_rdataset_next(&kfetch->dnskeysigset))
8610 	{
8611 		dns_fixedname_t fixed;
8612 		dns_fixedname_init(&fixed);
8613 
8614 		dns_rdata_reset(&sigrr);
8615 		dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
8616 		result = dns_rdata_tostruct(&sigrr, &sig, NULL);
8617 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
8618 
8619 		if (dst_key_alg(dstkey) == sig.algorithm &&
8620 		    dst_key_rid(dstkey) == sig.keyid)
8621 		{
8622 			result = dns_dnssec_verify2(keyname,
8623 					    &kfetch->dnskeyset,
8624 					    dstkey, ISC_FALSE, mctx, &sigrr,
8625 					    dns_fixedname_name(&fixed));
8626 
8627 			dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3),
8628 				     "Confirm revoked DNSKEY is self-signed: "
8629 				     "%s", dns_result_totext(result));
8630 
8631 			if (result == ISC_R_SUCCESS) {
8632 				answer = ISC_TRUE;
8633 				break;
8634 			}
8635 		}
8636 	}
8637 
8638 	dst_key_free(&dstkey);
8639 	return (answer);
8640 }
8641 
8642 /*
8643  * A DNSKEY set has been fetched from the zone apex of a zone whose trust
8644  * anchors are being managed; scan the keyset, and update the key zone and the
8645  * local trust anchors according to RFC5011.
8646  */
8647 static void
keyfetch_done(isc_task_t * task,isc_event_t * event)8648 keyfetch_done(isc_task_t *task, isc_event_t *event) {
8649 	isc_result_t result, eresult;
8650 	dns_fetchevent_t *devent;
8651 	dns_keyfetch_t *kfetch;
8652 	dns_zone_t *zone;
8653 	isc_mem_t *mctx = NULL;
8654 	dns_keytable_t *secroots = NULL;
8655 	dns_dbversion_t *ver = NULL;
8656 	dns_diff_t diff;
8657 	isc_boolean_t alldone = ISC_FALSE;
8658 	isc_boolean_t commit = ISC_FALSE;
8659 	dns_name_t *keyname;
8660 	dns_rdata_t sigrr = DNS_RDATA_INIT;
8661 	dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
8662 	dns_rdata_t keydatarr = DNS_RDATA_INIT;
8663 	dns_rdata_rrsig_t sig;
8664 	dns_rdata_dnskey_t dnskey;
8665 	dns_rdata_keydata_t keydata;
8666 	isc_boolean_t initializing;
8667 	char namebuf[DNS_NAME_FORMATSIZE];
8668 	unsigned char key_buf[4096];
8669 	isc_buffer_t keyb;
8670 	dst_key_t *dstkey;
8671 	isc_stdtime_t now;
8672 	int pending = 0;
8673 	isc_boolean_t secure;
8674 	isc_boolean_t free_needed;
8675 
8676 	UNUSED(task);
8677 	INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
8678 	INSIST(event->ev_arg != NULL);
8679 
8680 	kfetch = event->ev_arg;
8681 	zone = kfetch->zone;
8682 	isc_mem_attach(zone->mctx, &mctx);
8683 	keyname = dns_fixedname_name(&kfetch->name);
8684 
8685 	devent = (dns_fetchevent_t *) event;
8686 	eresult = devent->result;
8687 
8688 	/* Free resources which are not of interest */
8689 	if (devent->node != NULL)
8690 		dns_db_detachnode(devent->db, &devent->node);
8691 	if (devent->db != NULL)
8692 		dns_db_detach(&devent->db);
8693 	isc_event_free(&event);
8694 	dns_resolver_destroyfetch(&kfetch->fetch);
8695 
8696 	LOCK_ZONE(zone);
8697 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL)
8698 		goto cleanup;
8699 
8700 	isc_stdtime_get(&now);
8701 	dns_name_format(keyname, namebuf, sizeof(namebuf));
8702 
8703 	result = dns_view_getsecroots(zone->view, &secroots);
8704 	INSIST(result == ISC_R_SUCCESS);
8705 
8706 	dns_diff_init(mctx, &diff);
8707 
8708 	CHECK(dns_db_newversion(kfetch->db, &ver));
8709 
8710 	zone->refreshkeycount--;
8711 	alldone = ISC_TF(zone->refreshkeycount == 0);
8712 
8713 	if (alldone)
8714 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
8715 
8716 	/* Fetch failed */
8717 	if (eresult != ISC_R_SUCCESS ||
8718 	    !dns_rdataset_isassociated(&kfetch->dnskeyset)) {
8719 		dns_zone_log(zone, ISC_LOG_WARNING,
8720 			     "Unable to fetch DNSKEY set "
8721 			     "'%s': %s", namebuf, dns_result_totext(eresult));
8722 		CHECK(minimal_update(kfetch, ver, &diff));
8723 		goto done;
8724 	}
8725 
8726 	/* No RRSIGs found */
8727 	if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
8728 		dns_zone_log(zone, ISC_LOG_WARNING,
8729 			     "No DNSKEY RRSIGs found for "
8730 			     "'%s': %s", namebuf, dns_result_totext(eresult));
8731 		CHECK(minimal_update(kfetch, ver, &diff));
8732 		goto done;
8733 	}
8734 
8735 	/*
8736 	 * Clear any cached trust level, as we need to run validation
8737 	 * over again; trusted keys might have changed.
8738 	 */
8739 	kfetch->dnskeyset.trust = kfetch->dnskeysigset.trust = dns_trust_none;
8740 
8741 	/*
8742 	 * Validate the dnskeyset against the current trusted keys.
8743 	 */
8744 	for (result = dns_rdataset_first(&kfetch->dnskeysigset);
8745 	     result == ISC_R_SUCCESS;
8746 	     result = dns_rdataset_next(&kfetch->dnskeysigset)) {
8747 		dns_keynode_t *keynode = NULL;
8748 
8749 		dns_rdata_reset(&sigrr);
8750 		dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
8751 		result = dns_rdata_tostruct(&sigrr, &sig, NULL);
8752 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
8753 
8754 		result = dns_keytable_find(secroots, keyname, &keynode);
8755 		while (result == ISC_R_SUCCESS) {
8756 			dns_keynode_t *nextnode = NULL;
8757 			dns_fixedname_t fixed;
8758 			dns_fixedname_init(&fixed);
8759 
8760 			dstkey = dns_keynode_key(keynode);
8761 			if (dstkey == NULL) /* fail_secure() was called */
8762 				break;
8763 
8764 			if (dst_key_alg(dstkey) == sig.algorithm &&
8765 			    dst_key_id(dstkey) == sig.keyid) {
8766 				result = dns_dnssec_verify2(keyname,
8767 						    &kfetch->dnskeyset,
8768 						    dstkey, ISC_FALSE,
8769 						    zone->view->mctx, &sigrr,
8770 						    dns_fixedname_name(&fixed));
8771 
8772 				dns_zone_log(zone, ISC_LOG_DEBUG(3),
8773 					     "Verifying DNSKEY set for zone "
8774 					     "'%s' using key %d/%d: %s",
8775 					     namebuf, sig.keyid, sig.algorithm,
8776 					     dns_result_totext(result));
8777 
8778 				if (result == ISC_R_SUCCESS) {
8779 					kfetch->dnskeyset.trust =
8780 						dns_trust_secure;
8781 					kfetch->dnskeysigset.trust =
8782 						dns_trust_secure;
8783 					break;
8784 				}
8785 			}
8786 
8787 			result = dns_keytable_nextkeynode(secroots,
8788 							  keynode, &nextnode);
8789 			dns_keytable_detachkeynode(secroots, &keynode);
8790 			keynode = nextnode;
8791 		}
8792 
8793 		if (keynode != NULL)
8794 			dns_keytable_detachkeynode(secroots, &keynode);
8795 
8796 		if (kfetch->dnskeyset.trust == dns_trust_secure)
8797 			break;
8798 	}
8799 
8800 	/*
8801 	 * If we were not able to verify the answer using the current
8802 	 * trusted keys then all we can do is look at any revoked keys.
8803 	 */
8804 	secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure);
8805 
8806 	/*
8807 	 * First scan keydataset to find keys that are not in dnskeyset
8808 	 *   - Missing keys which are not scheduled for removal,
8809 	 *     log a warning
8810 	 *   - Missing keys which are scheduled for removal and
8811 	 *     the remove hold-down timer has completed should
8812 	 *     be removed from the key zone
8813 	 *   - Missing keys whose acceptance timers have not yet
8814 	 *     completed, log a warning and reset the acceptance
8815 	 *     timer to 30 days in the future
8816 	 *   - All keys not being removed have their refresh timers
8817 	 *     updated
8818 	 */
8819 	initializing = ISC_TRUE;
8820 	for (result = dns_rdataset_first(&kfetch->keydataset);
8821 	     result == ISC_R_SUCCESS;
8822 	     result = dns_rdataset_next(&kfetch->keydataset)) {
8823 		dns_rdata_reset(&keydatarr);
8824 		dns_rdataset_current(&kfetch->keydataset, &keydatarr);
8825 		result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
8826 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
8827 
8828 		/*
8829 		 * If any keydata record has a nonzero add holddown, then
8830 		 * there was a pre-existing trust anchor for this domain;
8831 		 * that means we are *not* initializing it and shouldn't
8832 		 * automatically trust all the keys we find at the zone apex.
8833 		 */
8834 		initializing = initializing && ISC_TF(keydata.addhd == 0);
8835 
8836 		if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
8837 			isc_boolean_t deletekey = ISC_FALSE;
8838 
8839 			if (!secure) {
8840 				if (keydata.removehd != 0 &&
8841 				    keydata.removehd <= now)
8842 					deletekey = ISC_TRUE;
8843 			} else if (keydata.addhd == 0) {
8844 				deletekey = ISC_TRUE;
8845 			} else if (keydata.addhd > now) {
8846 				dns_zone_log(zone, ISC_LOG_WARNING,
8847 					     "Pending key unexpectedly missing "
8848 					     "from %s; restarting acceptance "
8849 					     "timer", namebuf);
8850 				if (keydata.addhd < now + dns_zone_mkey_month)
8851 					keydata.addhd =
8852 						now + dns_zone_mkey_month;
8853 				keydata.refresh = refresh_time(kfetch,
8854 							       ISC_FALSE);
8855 			} else if (keydata.removehd == 0) {
8856 				dns_zone_log(zone, ISC_LOG_WARNING,
8857 					     "Active key unexpectedly missing "
8858 					     "from %s", namebuf);
8859 				keydata.refresh = now + dns_zone_mkey_hour;
8860 			} else if (keydata.removehd <= now) {
8861 				deletekey = ISC_TRUE;
8862 			} else {
8863 				keydata.refresh = refresh_time(kfetch,
8864 							       ISC_FALSE);
8865 			}
8866 
8867 			if (secure || deletekey) {
8868 				/* Delete old version */
8869 				CHECK(update_one_rr(kfetch->db, ver, &diff,
8870 						    DNS_DIFFOP_DEL, keyname, 0,
8871 						    &keydatarr));
8872 			}
8873 
8874 			if (!secure || deletekey)
8875 				continue;
8876 
8877 			dns_rdata_reset(&keydatarr);
8878 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
8879 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
8880 					     dns_rdatatype_keydata,
8881 					     &keydata, &keyb);
8882 
8883 			/* Insert updated version */
8884 			CHECK(update_one_rr(kfetch->db, ver, &diff,
8885 					    DNS_DIFFOP_ADD, keyname, 0,
8886 					    &keydatarr));
8887 
8888 			set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
8889 		}
8890 	}
8891 
8892 	/*
8893 	 * Next scan dnskeyset:
8894 	 *   - If new keys are found (i.e., lacking a match in keydataset)
8895 	 *     add them to the key zone and set the acceptance timer
8896 	 *     to 30 days in the future (or to immediately if we've
8897 	 *     determined that we're initializing the zone for the
8898 	 *     first time)
8899 	 *   - Previously-known keys that have been revoked
8900 	 *     must be scheduled for removal from the key zone (or,
8901 	 *     if they hadn't been accepted as trust anchors yet
8902 	 *     anyway, removed at once)
8903 	 *   - Previously-known unrevoked keys whose acceptance timers
8904 	 *     have completed are promoted to trust anchors
8905 	 *   - All keys not being removed have their refresh
8906 	 *     timers updated
8907 	 */
8908 	for (result = dns_rdataset_first(&kfetch->dnskeyset);
8909 	     result == ISC_R_SUCCESS;
8910 	     result = dns_rdataset_next(&kfetch->dnskeyset))
8911 	{
8912 		isc_boolean_t revoked = ISC_FALSE;
8913 		isc_boolean_t newkey = ISC_FALSE;
8914 		isc_boolean_t updatekey = ISC_FALSE;
8915 		isc_boolean_t deletekey = ISC_FALSE;
8916 		isc_boolean_t trustkey = ISC_FALSE;
8917 
8918 		dns_rdata_reset(&dnskeyrr);
8919 		dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
8920 		result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
8921 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
8922 
8923 		/* Skip ZSK's */
8924 		if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK))
8925 			continue;
8926 
8927 		revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE);
8928 
8929 		if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
8930 			dns_rdata_reset(&keydatarr);
8931 			dns_rdataset_current(&kfetch->keydataset, &keydatarr);
8932 			result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
8933 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
8934 
8935 			if (revoked && revocable(kfetch, &keydata)) {
8936 				if (keydata.addhd > now) {
8937 					/*
8938 					 * Key wasn't trusted yet, and now
8939 					 * it's been revoked?  Just remove it
8940 					 */
8941 					deletekey = ISC_TRUE;
8942 				} else if (keydata.removehd == 0) {
8943 					/* Remove from secroots */
8944 					dns_view_untrust(zone->view, keyname,
8945 							 &dnskey, mctx);
8946 
8947 					/* But ensure there's a null key */
8948 					fail_secure(zone, keyname);
8949 
8950 					/* If initializing, delete now */
8951 					if (keydata.addhd == 0)
8952 						deletekey = ISC_TRUE;
8953 					else {
8954 						keydata.removehd = now +
8955 							dns_zone_mkey_month;
8956 						keydata.flags |=
8957 							DNS_KEYFLAG_REVOKE;
8958 					}
8959 				} else if (keydata.removehd < now) {
8960 					/* Scheduled for removal */
8961 					deletekey = ISC_TRUE;
8962 				}
8963 			} else if (revoked && keydata.removehd == 0) {
8964 				dns_zone_log(zone, ISC_LOG_WARNING,
8965 					     "Active key for zone "
8966 					     "'%s' is revoked but "
8967 					     "did not self-sign; "
8968 					     "ignoring.", namebuf);
8969 					continue;
8970 			} else if (secure) {
8971 				if (keydata.removehd != 0) {
8972 					/*
8973 					 * Key isn't revoked--but it
8974 					 * seems it used to be.
8975 					 * Remove it now and add it
8976 					 * back as if it were a fresh key,
8977 					 * with a 30 day acceptance timer.
8978 					 */
8979 					deletekey = ISC_TRUE;
8980 					newkey = ISC_TRUE;
8981 					keydata.removehd = 0;
8982 					keydata.addhd =
8983 						now + dns_zone_mkey_month;
8984 				} else if (keydata.addhd > now)
8985 					pending++;
8986 				else if (keydata.addhd == 0)
8987 					keydata.addhd = now;
8988 
8989 				if (keydata.addhd <= now)
8990 					trustkey = ISC_TRUE;
8991 			} else if (keydata.addhd > now) {
8992 				/*
8993 				 * Not secure, and key is pending:
8994 				 * reset the acceptance timer
8995 				 */
8996 				pending++;
8997 				keydata.addhd = now + dns_zone_mkey_month;
8998 			}
8999 
9000 			if (!deletekey && !newkey)
9001 				updatekey = ISC_TRUE;
9002 		} else if (secure) {
9003 			/*
9004 			 * Key wasn't in the key zone but it's
9005 			 * revoked now anyway, so just skip it
9006 			 */
9007 			if (revoked)
9008 				continue;
9009 
9010 			/* Key wasn't in the key zone: add it */
9011 			newkey = ISC_TRUE;
9012 
9013 			if (initializing) {
9014 				dns_keytag_t tag = 0;
9015 				CHECK(compute_tag(keyname, &dnskey,
9016 						  mctx, &tag));
9017 				dns_zone_log(zone, ISC_LOG_WARNING,
9018 					     "Initializing automatic trust "
9019 					     "anchor management for zone '%s'; "
9020 					     "DNSKEY ID %d is now trusted, "
9021 					     "waiving the normal 30-day "
9022 					     "waiting period.",
9023 					     namebuf, tag);
9024 				trustkey = ISC_TRUE;
9025 			}
9026 		} else {
9027 			/*
9028 			 * No previously known key, and the key is not
9029 			 * secure, so skip it.
9030 			 */
9031 			continue;
9032 		}
9033 
9034 		/* Delete old version */
9035 		if (deletekey || !newkey)
9036 			CHECK(update_one_rr(kfetch->db, ver, &diff,
9037 					    DNS_DIFFOP_DEL, keyname, 0,
9038 					    &keydatarr));
9039 
9040 		if (updatekey) {
9041 			/* Set refresh timer */
9042 			keydata.refresh = refresh_time(kfetch, ISC_FALSE);
9043 			dns_rdata_reset(&keydatarr);
9044 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
9045 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
9046 					     dns_rdatatype_keydata,
9047 					     &keydata, &keyb);
9048 
9049 			/* Insert updated version */
9050 			CHECK(update_one_rr(kfetch->db, ver, &diff,
9051 					    DNS_DIFFOP_ADD, keyname, 0,
9052 					    &keydatarr));
9053 		} else if (newkey) {
9054 			/* Convert DNSKEY to KEYDATA */
9055 			result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
9056 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
9057 			dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
9058 					       NULL);
9059 			keydata.addhd = initializing
9060 					 ? now : now + dns_zone_mkey_month;
9061 			keydata.refresh = refresh_time(kfetch, ISC_FALSE);
9062 			dns_rdata_reset(&keydatarr);
9063 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
9064 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
9065 					     dns_rdatatype_keydata,
9066 					     &keydata, &keyb);
9067 
9068 			/* Insert into key zone */
9069 			CHECK(update_one_rr(kfetch->db, ver, &diff,
9070 					    DNS_DIFFOP_ADD, keyname, 0,
9071 					    &keydatarr));
9072 		}
9073 
9074 		if (trustkey) {
9075 			/* Trust this key. */
9076 			result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
9077 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
9078 			trust_key(zone, keyname, &dnskey, mctx);
9079 		}
9080 
9081 		if (secure && !deletekey) {
9082 			INSIST(newkey || updatekey);
9083 			set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
9084 		}
9085 	}
9086 
9087 	/*
9088 	 * RFC5011 says, "A trust point that has all of its trust anchors
9089 	 * revoked is considered deleted and is treated as if the trust
9090 	 * point was never configured."  But if someone revoked their
9091 	 * active key before the standby was trusted, that would mean the
9092 	 * zone would suddenly be nonsecured.  We avoid this by checking to
9093 	 * see if there's pending keydata.  If so, we put a null key in
9094 	 * the security roots; then all queries to the zone will fail.
9095 	 */
9096 	if (pending != 0)
9097 		fail_secure(zone, keyname);
9098 
9099  done:
9100 
9101 	if (!ISC_LIST_EMPTY(diff.tuples)) {
9102 		/* Write changes to journal file. */
9103 		CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx,
9104 					zone->updatemethod));
9105 		CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done"));
9106 		commit = ISC_TRUE;
9107 
9108 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
9109 		zone_needdump(zone, 30);
9110 	}
9111 
9112  failure:
9113 
9114 	dns_diff_clear(&diff);
9115 	if (ver != NULL)
9116 		dns_db_closeversion(kfetch->db, &ver, commit);
9117 
9118  cleanup:
9119 	dns_db_detach(&kfetch->db);
9120 
9121 	INSIST(zone->irefs > 0);
9122 	zone->irefs--;
9123 	kfetch->zone = NULL;
9124 
9125 	if (dns_rdataset_isassociated(&kfetch->keydataset))
9126 		dns_rdataset_disassociate(&kfetch->keydataset);
9127 	if (dns_rdataset_isassociated(&kfetch->dnskeyset))
9128 		dns_rdataset_disassociate(&kfetch->dnskeyset);
9129 	if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
9130 		dns_rdataset_disassociate(&kfetch->dnskeysigset);
9131 
9132 	dns_name_free(keyname, mctx);
9133 	isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
9134 	isc_mem_detach(&mctx);
9135 
9136 	if (secroots != NULL)
9137 		dns_keytable_detach(&secroots);
9138 
9139 	free_needed = exit_check(zone);
9140 	UNLOCK_ZONE(zone);
9141 	if (free_needed)
9142 		zone_free(zone);
9143 
9144 	INSIST(ver == NULL);
9145 }
9146 
9147 /*
9148  * Refresh the data in the key zone.  Initiate a fetch to get new DNSKEY
9149  * records from the zone apex.
9150  */
9151 static void
zone_refreshkeys(dns_zone_t * zone)9152 zone_refreshkeys(dns_zone_t *zone) {
9153 	const char me[] = "zone_refreshkeys";
9154 	isc_result_t result;
9155 	dns_rriterator_t rrit;
9156 	dns_db_t *db = NULL;
9157 	dns_dbversion_t *ver = NULL;
9158 	dns_diff_t diff;
9159 	dns_rdata_t rdata = DNS_RDATA_INIT;
9160 	dns_rdata_keydata_t kd;
9161 	isc_stdtime_t now;
9162 	isc_boolean_t commit = ISC_FALSE;
9163 	isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE;
9164 
9165 	ENTER;
9166 	REQUIRE(zone->db != NULL);
9167 
9168 	isc_stdtime_get(&now);
9169 
9170 	LOCK_ZONE(zone);
9171 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
9172 		isc_time_settoepoch(&zone->refreshkeytime);
9173 		UNLOCK_ZONE(zone);
9174 		return;
9175 	}
9176 
9177 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9178 	dns_db_attach(zone->db, &db);
9179 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9180 
9181 	dns_diff_init(zone->mctx, &diff);
9182 
9183 	CHECK(dns_db_newversion(db, &ver));
9184 
9185 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
9186 
9187 	dns_rriterator_init(&rrit, db, ver, 0);
9188 	for (result = dns_rriterator_first(&rrit);
9189 	     result == ISC_R_SUCCESS;
9190 	     result = dns_rriterator_nextrrset(&rrit)) {
9191 		isc_stdtime_t timer = 0xffffffff;
9192 		dns_name_t *name = NULL, *kname = NULL;
9193 		dns_rdataset_t *kdset = NULL;
9194 		dns_keyfetch_t *kfetch;
9195 		isc_uint32_t ttl;
9196 
9197 		dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
9198 		if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
9199 		    !dns_rdataset_isassociated(kdset))
9200 			continue;
9201 
9202 		/*
9203 		 * Scan the stored keys looking for ones that need
9204 		 * removal or refreshing
9205 		 */
9206 		for (result = dns_rdataset_first(kdset);
9207 		     result == ISC_R_SUCCESS;
9208 		     result = dns_rdataset_next(kdset)) {
9209 			dns_rdata_reset(&rdata);
9210 			dns_rdataset_current(kdset, &rdata);
9211 			result = dns_rdata_tostruct(&rdata, &kd, NULL);
9212 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
9213 
9214 			/* Removal timer expired? */
9215 			if (kd.removehd != 0 && kd.removehd < now) {
9216 				CHECK(update_one_rr(db, ver, &diff,
9217 						    DNS_DIFFOP_DEL, name, ttl,
9218 						    &rdata));
9219 				continue;
9220 			}
9221 
9222 			/* Acceptance timer expired? */
9223 			if (kd.addhd != 0 && kd.addhd < now)
9224 				timer = kd.addhd;
9225 
9226 			/* Or do we just need to refresh the keyset? */
9227 			if (timer > kd.refresh)
9228 				timer = kd.refresh;
9229 		}
9230 
9231 		if (timer > now)
9232 			continue;
9233 
9234 		kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
9235 		if (kfetch == NULL) {
9236 			fetch_err = ISC_TRUE;
9237 			goto failure;
9238 		}
9239 
9240 		zone->refreshkeycount++;
9241 		kfetch->zone = zone;
9242 		zone->irefs++;
9243 		INSIST(zone->irefs != 0);
9244 		dns_fixedname_init(&kfetch->name);
9245 		kname = dns_fixedname_name(&kfetch->name);
9246 		dns_name_dup(name, zone->mctx, kname);
9247 		dns_rdataset_init(&kfetch->dnskeyset);
9248 		dns_rdataset_init(&kfetch->dnskeysigset);
9249 		dns_rdataset_init(&kfetch->keydataset);
9250 		dns_rdataset_clone(kdset, &kfetch->keydataset);
9251 		kfetch->db = NULL;
9252 		dns_db_attach(db, &kfetch->db);
9253 		kfetch->fetch = NULL;
9254 
9255 		result = dns_resolver_createfetch(zone->view->resolver,
9256 						  kname, dns_rdatatype_dnskey,
9257 						  NULL, NULL, NULL,
9258 						  DNS_FETCHOPT_NOVALIDATE,
9259 						  zone->task,
9260 						  keyfetch_done, kfetch,
9261 						  &kfetch->dnskeyset,
9262 						  &kfetch->dnskeysigset,
9263 						  &kfetch->fetch);
9264 		if (result == ISC_R_SUCCESS)
9265 			fetching = ISC_TRUE;
9266 		else {
9267 			zone->refreshkeycount--;
9268 			zone->irefs--;
9269 			dns_db_detach(&kfetch->db);
9270 			dns_rdataset_disassociate(&kfetch->keydataset);
9271 			dns_name_free(kname, zone->mctx);
9272 			isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
9273 			dns_zone_log(zone, ISC_LOG_WARNING,
9274 				     "Failed to create fetch for "
9275 				     "DNSKEY update");
9276 			fetch_err = ISC_TRUE;
9277 		}
9278 	}
9279 	if (!ISC_LIST_EMPTY(diff.tuples)) {
9280 		CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
9281 					zone->updatemethod));
9282 		CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys"));
9283 		commit = ISC_TRUE;
9284 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
9285 		zone_needdump(zone, 30);
9286 	}
9287 
9288   failure:
9289 	if (fetch_err) {
9290 		/*
9291 		 * Error during a key fetch; retry in an hour.
9292 		 */
9293 		isc_time_t timenow, timethen;
9294 		char timebuf[80];
9295 
9296 		TIME_NOW(&timenow);
9297 		DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen);
9298 		zone->refreshkeytime = timethen;
9299 		zone_settimer(zone, &timenow);
9300 
9301 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
9302 		dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
9303 			     timebuf);
9304 
9305 		if (!fetching)
9306 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
9307 	}
9308 
9309 	UNLOCK_ZONE(zone);
9310 
9311 	dns_diff_clear(&diff);
9312 	if (ver != NULL) {
9313 		dns_rriterator_destroy(&rrit);
9314 		dns_db_closeversion(db, &ver, commit);
9315 	}
9316 	dns_db_detach(&db);
9317 
9318 	INSIST(ver == NULL);
9319 }
9320 
9321 static void
zone_maintenance(dns_zone_t * zone)9322 zone_maintenance(dns_zone_t *zone) {
9323 	const char me[] = "zone_maintenance";
9324 	isc_time_t now;
9325 	isc_result_t result;
9326 	isc_boolean_t dumping;
9327 
9328 	REQUIRE(DNS_ZONE_VALID(zone));
9329 	ENTER;
9330 
9331 	/*
9332 	 * Are we pending load/reload?
9333 	 */
9334 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))
9335 		return;
9336 
9337 	/*
9338 	 * Configuring the view of this zone may have
9339 	 * failed, for example because the config file
9340 	 * had a syntax error.	In that case, the view
9341 	 * adb or resolver will be NULL, and we had better not try
9342 	 * to do further maintenance on it.
9343 	 */
9344 	if (zone->view == NULL || zone->view->adb == NULL)
9345 		return;
9346 
9347 	TIME_NOW(&now);
9348 
9349 	/*
9350 	 * Expire check.
9351 	 */
9352 	switch (zone->type) {
9353 	case dns_zone_redirect:
9354 		if (zone->masters == NULL)
9355 			break;
9356 	case dns_zone_slave:
9357 	case dns_zone_stub:
9358 		LOCK_ZONE(zone);
9359 		if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
9360 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
9361 			zone_expire(zone);
9362 			zone->refreshtime = now;
9363 		}
9364 		UNLOCK_ZONE(zone);
9365 		break;
9366 	default:
9367 		break;
9368 	}
9369 
9370 	/*
9371 	 * Up to date check.
9372 	 */
9373 	switch (zone->type) {
9374 	case dns_zone_redirect:
9375 		if (zone->masters == NULL)
9376 			break;
9377 	case dns_zone_slave:
9378 	case dns_zone_stub:
9379 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
9380 		    isc_time_compare(&now, &zone->refreshtime) >= 0)
9381 			dns_zone_refresh(zone);
9382 		break;
9383 	default:
9384 		break;
9385 	}
9386 
9387 	/*
9388 	 * Slaves send notifies before backing up to disk, masters after.
9389 	 */
9390 	if (zone->type == dns_zone_slave &&
9391 	    (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
9392 	     DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
9393 	    isc_time_compare(&now, &zone->notifytime) >= 0)
9394 		zone_notify(zone, &now);
9395 
9396 	/*
9397 	 * Do we need to consolidate the backing store?
9398 	 */
9399 	switch (zone->type) {
9400 	case dns_zone_master:
9401 	case dns_zone_slave:
9402 	case dns_zone_key:
9403 	case dns_zone_redirect:
9404 	case dns_zone_stub:
9405 		LOCK_ZONE(zone);
9406 		if (zone->masterfile != NULL &&
9407 		    isc_time_compare(&now, &zone->dumptime) >= 0 &&
9408 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
9409 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
9410 			dumping = was_dumping(zone);
9411 		} else
9412 			dumping = ISC_TRUE;
9413 		UNLOCK_ZONE(zone);
9414 		if (!dumping) {
9415 			result = zone_dump(zone, ISC_TRUE); /* task locked */
9416 			if (result != ISC_R_SUCCESS)
9417 				dns_zone_log(zone, ISC_LOG_WARNING,
9418 					     "dump failed: %s",
9419 					     dns_result_totext(result));
9420 		}
9421 		break;
9422 	default:
9423 		break;
9424 	}
9425 
9426 	/*
9427 	 * Master/redirect zones send notifies now, if needed
9428 	 */
9429 	switch (zone->type) {
9430 	case dns_zone_master:
9431 	case dns_zone_redirect:
9432 		if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
9433 		     DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))&&
9434 		    isc_time_compare(&now, &zone->notifytime) >= 0)
9435 			zone_notify(zone, &now);
9436 	default:
9437 		break;
9438 	}
9439 
9440 	/*
9441 	 * Do we need to refresh keys?
9442 	 */
9443 	switch (zone->type) {
9444 	case dns_zone_key:
9445 		if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
9446 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
9447 			    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
9448 				zone_refreshkeys(zone);
9449 			}
9450 		}
9451 		break;
9452 	case dns_zone_master:
9453 		if (!isc_time_isepoch(&zone->refreshkeytime) &&
9454 		    isc_time_compare(&now, &zone->refreshkeytime) >= 0)
9455 			zone_rekey(zone);
9456 	default:
9457 		break;
9458 	}
9459 
9460 	switch (zone->type) {
9461 	case dns_zone_master:
9462 	case dns_zone_redirect:
9463 	case dns_zone_slave:
9464 		/*
9465 		 * Do we need to sign/resign some RRsets?
9466 		 */
9467 		if (!isc_time_isepoch(&zone->signingtime) &&
9468 		    isc_time_compare(&now, &zone->signingtime) >= 0)
9469 			zone_sign(zone);
9470 		else if (!isc_time_isepoch(&zone->resigntime) &&
9471 		    isc_time_compare(&now, &zone->resigntime) >= 0)
9472 			zone_resigninc(zone);
9473 		else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
9474 			isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
9475 			zone_nsec3chain(zone);
9476 		/*
9477 		 * Do we need to issue a key expiry warning?
9478 		 */
9479 		if (!isc_time_isepoch(&zone->keywarntime) &&
9480 		    isc_time_compare(&now, &zone->keywarntime) >= 0)
9481 			set_key_expiry_warning(zone, zone->key_expiry,
9482 					       isc_time_seconds(&now));
9483 		break;
9484 
9485 	default:
9486 		break;
9487 	}
9488 	zone_settimer(zone, &now);
9489 }
9490 
9491 void
dns_zone_markdirty(dns_zone_t * zone)9492 dns_zone_markdirty(dns_zone_t *zone) {
9493 	isc_uint32_t serial;
9494 	isc_result_t result = ISC_R_SUCCESS;
9495 	dns_zone_t *secure = NULL;
9496 
9497 	/*
9498 	 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
9499 	 * could result in a deadlock due to a LOR so we will spin if we
9500 	 * can't obtain the both locks.
9501 	 */
9502  again:
9503 	LOCK_ZONE(zone);
9504 	if (zone->type == dns_zone_master) {
9505 		if (inline_raw(zone)) {
9506 			unsigned int soacount;
9507 			secure = zone->secure;
9508 			INSIST(secure != zone);
9509 			TRYLOCK_ZONE(result, secure);
9510 			if (result != ISC_R_SUCCESS) {
9511 				UNLOCK_ZONE(zone);
9512 				secure = NULL;
9513 #ifdef ISC_PLATFORM_USETHREADS
9514 				isc_thread_yield();
9515 #endif
9516 				goto again;
9517 			}
9518 
9519 			ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9520 			if (zone->db != NULL) {
9521 				result = zone_get_from_db(zone, zone->db, NULL,
9522 							  &soacount, &serial,
9523 							  NULL, NULL, NULL,
9524 							  NULL, NULL);
9525 			} else
9526 				result = DNS_R_NOTLOADED;
9527 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9528 			if (result == ISC_R_SUCCESS && soacount > 0U)
9529 				zone_send_secureserial(zone, serial);
9530 		}
9531 
9532 		/* XXXMPA make separate call back */
9533 		if (result == ISC_R_SUCCESS)
9534 			set_resigntime(zone);
9535 	}
9536 	if (secure != NULL)
9537 		UNLOCK_ZONE(secure);
9538 	zone_needdump(zone, DNS_DUMP_DELAY);
9539 	UNLOCK_ZONE(zone);
9540 }
9541 
9542 void
dns_zone_expire(dns_zone_t * zone)9543 dns_zone_expire(dns_zone_t *zone) {
9544 	REQUIRE(DNS_ZONE_VALID(zone));
9545 
9546 	LOCK_ZONE(zone);
9547 	zone_expire(zone);
9548 	UNLOCK_ZONE(zone);
9549 }
9550 
9551 static void
zone_expire(dns_zone_t * zone)9552 zone_expire(dns_zone_t *zone) {
9553 	/*
9554 	 * 'zone' locked by caller.
9555 	 */
9556 
9557 	REQUIRE(LOCKED_ZONE(zone));
9558 
9559 	dns_zone_log(zone, ISC_LOG_WARNING, "expired");
9560 
9561 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
9562 	zone->refresh = DNS_ZONE_DEFAULTREFRESH;
9563 	zone->retry = DNS_ZONE_DEFAULTRETRY;
9564 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9565 	zone_unload(zone);
9566 }
9567 
9568 void
dns_zone_refresh(dns_zone_t * zone)9569 dns_zone_refresh(dns_zone_t *zone) {
9570 	isc_interval_t i;
9571 	isc_uint32_t oldflags;
9572 	unsigned int j;
9573 	isc_result_t result;
9574 
9575 	REQUIRE(DNS_ZONE_VALID(zone));
9576 
9577 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
9578 		return;
9579 
9580 	/*
9581 	 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
9582 	 * in progress at a time.
9583 	 */
9584 
9585 	LOCK_ZONE(zone);
9586 	oldflags = zone->flags;
9587 	if (zone->masterscnt == 0) {
9588 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
9589 		if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
9590 			dns_zone_log(zone, ISC_LOG_ERROR,
9591 				     "cannot refresh: no masters");
9592 		goto unlock;
9593 	}
9594 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
9595 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
9596 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9597 	if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
9598 		goto unlock;
9599 
9600 	/*
9601 	 * Set the next refresh time as if refresh check has failed.
9602 	 * Setting this to the retry time will do that.  XXXMLG
9603 	 * If we are successful it will be reset using zone->refresh.
9604 	 */
9605 	isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
9606 			 0);
9607 	result = isc_time_nowplusinterval(&zone->refreshtime, &i);
9608 	if (result != ISC_R_SUCCESS)
9609 		dns_zone_log(zone, ISC_LOG_WARNING,
9610 			     "isc_time_nowplusinterval() failed: %s",
9611 			     dns_result_totext(result));
9612 
9613 	/*
9614 	 * When lacking user-specified timer values from the SOA,
9615 	 * do exponential backoff of the retry time up to a
9616 	 * maximum of six hours.
9617 	 */
9618 	if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
9619 		zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
9620 
9621 	zone->curmaster = 0;
9622 	for (j = 0; j < zone->masterscnt; j++)
9623 		zone->mastersok[j] = ISC_FALSE;
9624 	/* initiate soa query */
9625 	queue_soa_query(zone);
9626  unlock:
9627 	UNLOCK_ZONE(zone);
9628 }
9629 
9630 isc_result_t
dns_zone_flush(dns_zone_t * zone)9631 dns_zone_flush(dns_zone_t *zone) {
9632 	isc_result_t result = ISC_R_SUCCESS;
9633 	isc_boolean_t dumping;
9634 
9635 	REQUIRE(DNS_ZONE_VALID(zone));
9636 
9637 	LOCK_ZONE(zone);
9638 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
9639 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9640 	    zone->masterfile != NULL) {
9641 		result = ISC_R_ALREADYRUNNING;
9642 		dumping = was_dumping(zone);
9643 	} else
9644 		dumping = ISC_TRUE;
9645 	UNLOCK_ZONE(zone);
9646 	if (!dumping)
9647 		result = zone_dump(zone, ISC_FALSE);	/* Unknown task. */
9648 	return (result);
9649 }
9650 
9651 isc_result_t
dns_zone_dump(dns_zone_t * zone)9652 dns_zone_dump(dns_zone_t *zone) {
9653 	isc_result_t result = ISC_R_ALREADYRUNNING;
9654 	isc_boolean_t dumping;
9655 
9656 	REQUIRE(DNS_ZONE_VALID(zone));
9657 
9658 	LOCK_ZONE(zone);
9659 	dumping = was_dumping(zone);
9660 	UNLOCK_ZONE(zone);
9661 	if (!dumping)
9662 		result = zone_dump(zone, ISC_FALSE);	/* Unknown task. */
9663 	return (result);
9664 }
9665 
9666 static void
zone_needdump(dns_zone_t * zone,unsigned int delay)9667 zone_needdump(dns_zone_t *zone, unsigned int delay) {
9668 	const char me[] = "zone_needdump";
9669 	isc_time_t dumptime;
9670 	isc_time_t now;
9671 
9672 	/*
9673 	 * 'zone' locked by caller
9674 	 */
9675 
9676 	REQUIRE(DNS_ZONE_VALID(zone));
9677 	REQUIRE(LOCKED_ZONE(zone));
9678 	ENTER;
9679 
9680 	/*
9681 	 * Do we have a place to dump to and are we loaded?
9682 	 */
9683 	if (zone->masterfile == NULL ||
9684 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
9685 		return;
9686 
9687 	TIME_NOW(&now);
9688 	/* add some noise */
9689 	DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
9690 
9691 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9692 	if (isc_time_isepoch(&zone->dumptime) ||
9693 	    isc_time_compare(&zone->dumptime, &dumptime) > 0)
9694 		zone->dumptime = dumptime;
9695 	if (zone->task != NULL)
9696 		zone_settimer(zone, &now);
9697 }
9698 
9699 static void
dump_done(void * arg,isc_result_t result)9700 dump_done(void *arg, isc_result_t result) {
9701 	const char me[] = "dump_done";
9702 	dns_zone_t *zone = arg;
9703 	dns_db_t *db;
9704 	dns_dbversion_t *version;
9705 	isc_boolean_t again = ISC_FALSE;
9706 	isc_boolean_t compact = ISC_FALSE;
9707 	isc_uint32_t serial;
9708 	isc_result_t tresult;
9709 
9710 	REQUIRE(DNS_ZONE_VALID(zone));
9711 
9712 	ENTER;
9713 
9714 	if (result == ISC_R_SUCCESS && zone->journal != NULL &&
9715 	    zone->journalsize != -1) {
9716 
9717 		/*
9718 		 * We don't own these, zone->dctx must stay valid.
9719 		 */
9720 		db = dns_dumpctx_db(zone->dctx);
9721 		version = dns_dumpctx_version(zone->dctx);
9722 
9723 		tresult = dns_db_getsoaserial(db, version, &serial);
9724 		/*
9725 		 * If there is a secure version of this zone
9726 		 * use its serial if it is less than ours.
9727 		 */
9728 		if (tresult == ISC_R_SUCCESS && inline_raw(zone) &&
9729 		    zone->secure->db != NULL)
9730 		{
9731 			isc_uint32_t sserial;
9732 			isc_result_t mresult;
9733 
9734 			mresult = dns_db_getsoaserial(zone->secure->db,
9735 						      NULL, &sserial);
9736 			if (mresult == ISC_R_SUCCESS &&
9737 			    isc_serial_lt(sserial, serial))
9738 				serial = sserial;
9739 		}
9740 		/*
9741 		 * Note: we are task locked here so we can test
9742 		 * zone->xfr safely.
9743 		 */
9744 		if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
9745 			tresult = dns_journal_compact(zone->mctx,
9746 						      zone->journal,
9747 						      serial,
9748 						      zone->journalsize);
9749 			switch (tresult) {
9750 			case ISC_R_SUCCESS:
9751 			case ISC_R_NOSPACE:
9752 			case ISC_R_NOTFOUND:
9753 				dns_zone_log(zone, ISC_LOG_DEBUG(3),
9754 					     "dns_journal_compact: %s",
9755 					     dns_result_totext(tresult));
9756 				break;
9757 			default:
9758 				dns_zone_log(zone, ISC_LOG_ERROR,
9759 					     "dns_journal_compact failed: %s",
9760 					     dns_result_totext(tresult));
9761 				break;
9762 			}
9763 		} else if (tresult == ISC_R_SUCCESS) {
9764 			compact = ISC_TRUE;
9765 			zone->compact_serial = serial;
9766 		}
9767 	}
9768 
9769 	LOCK_ZONE(zone);
9770 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
9771 	if (compact)
9772 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
9773 	if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
9774 		/*
9775 		 * Try again in a short while.
9776 		 */
9777 		zone_needdump(zone, DNS_DUMP_DELAY);
9778 	} else if (result == ISC_R_SUCCESS &&
9779 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
9780 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9781 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
9782 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9783 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
9784 		isc_time_settoepoch(&zone->dumptime);
9785 		again = ISC_TRUE;
9786 	} else if (result == ISC_R_SUCCESS)
9787 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
9788 
9789 	if (zone->dctx != NULL)
9790 		dns_dumpctx_detach(&zone->dctx);
9791 	zonemgr_putio(&zone->writeio);
9792 	UNLOCK_ZONE(zone);
9793 	if (again)
9794 		(void)zone_dump(zone, ISC_FALSE);
9795 	dns_zone_idetach(&zone);
9796 }
9797 
9798 static isc_result_t
zone_dump(dns_zone_t * zone,isc_boolean_t compact)9799 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
9800 	const char me[] = "zone_dump";
9801 	isc_result_t result;
9802 	dns_dbversion_t *version = NULL;
9803 	isc_boolean_t again;
9804 	dns_db_t *db = NULL;
9805 	char *masterfile = NULL;
9806 	dns_masterformat_t masterformat = dns_masterformat_none;
9807 
9808 /*
9809  * 'compact' MUST only be set if we are task locked.
9810  */
9811 
9812 	REQUIRE(DNS_ZONE_VALID(zone));
9813 	ENTER;
9814 
9815  redo:
9816 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9817 	if (zone->db != NULL)
9818 		dns_db_attach(zone->db, &db);
9819 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9820 	LOCK_ZONE(zone);
9821 	if (zone->masterfile != NULL) {
9822 		masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
9823 		masterformat = zone->masterformat;
9824 	}
9825 	UNLOCK_ZONE(zone);
9826 	if (db == NULL) {
9827 		result = DNS_R_NOTLOADED;
9828 		goto fail;
9829 	}
9830 	if (masterfile == NULL) {
9831 		result = DNS_R_NOMASTERFILE;
9832 		goto fail;
9833 	}
9834 
9835 	if (compact && zone->type != dns_zone_stub) {
9836 		dns_zone_t *dummy = NULL;
9837 		LOCK_ZONE(zone);
9838 		zone_iattach(zone, &dummy);
9839 		result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
9840 				       zone_gotwritehandle, zone,
9841 				       &zone->writeio);
9842 		if (result != ISC_R_SUCCESS)
9843 			zone_idetach(&dummy);
9844 		else
9845 			result = DNS_R_CONTINUE;
9846 		UNLOCK_ZONE(zone);
9847 	} else {
9848 		const dns_master_style_t *output_style;
9849 
9850 		dns_masterrawheader_t rawdata;
9851 		dns_db_currentversion(db, &version);
9852 		dns_master_initrawheader(&rawdata);
9853 		if (inline_secure(zone))
9854 			get_raw_serial(zone->raw, &rawdata);
9855 		if (zone->type == dns_zone_key)
9856 			output_style = &dns_master_style_keyzone;
9857 		else
9858 			output_style = &dns_master_style_default;
9859 		result = dns_master_dump3(zone->mctx, db, version,
9860 					  output_style, masterfile,
9861 					  masterformat, &rawdata);
9862 		dns_db_closeversion(db, &version, ISC_FALSE);
9863 	}
9864  fail:
9865 	if (db != NULL)
9866 		dns_db_detach(&db);
9867 	if (masterfile != NULL)
9868 		isc_mem_free(zone->mctx, masterfile);
9869 	masterfile = NULL;
9870 
9871 	if (result == DNS_R_CONTINUE)
9872 		return (ISC_R_SUCCESS); /* XXXMPA */
9873 
9874 	again = ISC_FALSE;
9875 	LOCK_ZONE(zone);
9876 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
9877 	if (result != ISC_R_SUCCESS) {
9878 		/*
9879 		 * Try again in a short while.
9880 		 */
9881 		zone_needdump(zone, DNS_DUMP_DELAY);
9882 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
9883 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9884 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
9885 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
9886 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
9887 		isc_time_settoepoch(&zone->dumptime);
9888 		again = ISC_TRUE;
9889 	} else
9890 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
9891 	UNLOCK_ZONE(zone);
9892 	if (again)
9893 		goto redo;
9894 
9895 	return (result);
9896 }
9897 
9898 static isc_result_t
dumptostream(dns_zone_t * zone,FILE * fd,const dns_master_style_t * style,dns_masterformat_t format,const isc_uint32_t rawversion)9899 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
9900 	     dns_masterformat_t format, const isc_uint32_t rawversion)
9901 {
9902 	isc_result_t result;
9903 	dns_dbversion_t *version = NULL;
9904 	dns_db_t *db = NULL;
9905 	dns_masterrawheader_t rawdata;
9906 
9907 	REQUIRE(DNS_ZONE_VALID(zone));
9908 
9909 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9910 	if (zone->db != NULL)
9911 		dns_db_attach(zone->db, &db);
9912 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9913 	if (db == NULL)
9914 		return (DNS_R_NOTLOADED);
9915 
9916 	dns_db_currentversion(db, &version);
9917 	dns_master_initrawheader(&rawdata);
9918 	if (rawversion == 0)
9919 		rawdata.flags |= DNS_MASTERRAW_COMPAT;
9920 	else if (inline_secure(zone))
9921 		get_raw_serial(zone->raw, &rawdata);
9922 	else if (zone->sourceserialset) {
9923 		rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
9924 		rawdata.sourceserial = zone->sourceserial;
9925 	}
9926 	result = dns_master_dumptostream3(zone->mctx, db, version, style,
9927 					  format, &rawdata, fd);
9928 	dns_db_closeversion(db, &version, ISC_FALSE);
9929 	dns_db_detach(&db);
9930 	return (result);
9931 }
9932 
9933 isc_result_t
dns_zone_dumptostream3(dns_zone_t * zone,FILE * fd,dns_masterformat_t format,const dns_master_style_t * style,const isc_uint32_t rawversion)9934 dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
9935 		       const dns_master_style_t *style,
9936 		       const isc_uint32_t rawversion)
9937 {
9938 	return (dumptostream(zone, fd, style, format, rawversion));
9939 }
9940 
9941 isc_result_t
dns_zone_dumptostream2(dns_zone_t * zone,FILE * fd,dns_masterformat_t format,const dns_master_style_t * style)9942 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
9943 		       const dns_master_style_t *style) {
9944 	return (dumptostream(zone, fd, style, format, DNS_RAWFORMAT_VERSION));
9945 }
9946 
9947 isc_result_t
dns_zone_dumptostream(dns_zone_t * zone,FILE * fd)9948 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
9949 	return (dumptostream(zone, fd, &dns_master_style_default,
9950 			     dns_masterformat_text, 0));
9951 }
9952 
9953 isc_result_t
dns_zone_fulldumptostream(dns_zone_t * zone,FILE * fd)9954 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
9955 	return (dumptostream(zone, fd, &dns_master_style_full,
9956 			     dns_masterformat_text, 0));
9957 }
9958 
9959 void
dns_zone_unload(dns_zone_t * zone)9960 dns_zone_unload(dns_zone_t *zone) {
9961 	REQUIRE(DNS_ZONE_VALID(zone));
9962 
9963 	LOCK_ZONE(zone);
9964 	zone_unload(zone);
9965 	UNLOCK_ZONE(zone);
9966 }
9967 
9968 static void
notify_cancel(dns_zone_t * zone)9969 notify_cancel(dns_zone_t *zone) {
9970 	dns_notify_t *notify;
9971 
9972 	/*
9973 	 * 'zone' locked by caller.
9974 	 */
9975 
9976 	REQUIRE(LOCKED_ZONE(zone));
9977 
9978 	for (notify = ISC_LIST_HEAD(zone->notifies);
9979 	     notify != NULL;
9980 	     notify = ISC_LIST_NEXT(notify, link)) {
9981 		if (notify->find != NULL)
9982 			dns_adb_cancelfind(notify->find);
9983 		if (notify->request != NULL)
9984 			dns_request_cancel(notify->request);
9985 	}
9986 }
9987 
9988 static void
forward_cancel(dns_zone_t * zone)9989 forward_cancel(dns_zone_t *zone) {
9990 	dns_forward_t *forward;
9991 
9992 	/*
9993 	 * 'zone' locked by caller.
9994 	 */
9995 
9996 	REQUIRE(LOCKED_ZONE(zone));
9997 
9998 	for (forward = ISC_LIST_HEAD(zone->forwards);
9999 	     forward != NULL;
10000 	     forward = ISC_LIST_NEXT(forward, link)) {
10001 		if (forward->request != NULL)
10002 			dns_request_cancel(forward->request);
10003 	}
10004 }
10005 
10006 static void
zone_unload(dns_zone_t * zone)10007 zone_unload(dns_zone_t *zone) {
10008 	/*
10009 	 * 'zone' locked by caller.
10010 	 */
10011 
10012 	REQUIRE(LOCKED_ZONE(zone));
10013 
10014 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
10015 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10016 		if (zone->writeio != NULL)
10017 			zonemgr_cancelio(zone->writeio);
10018 
10019 		if (zone->dctx != NULL)
10020 			dns_dumpctx_cancel(zone->dctx);
10021 	}
10022 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
10023 	zone_detachdb(zone);
10024 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
10025 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
10026 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
10027 }
10028 
10029 void
dns_zone_setminrefreshtime(dns_zone_t * zone,isc_uint32_t val)10030 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
10031 	REQUIRE(DNS_ZONE_VALID(zone));
10032 	REQUIRE(val > 0);
10033 
10034 	zone->minrefresh = val;
10035 }
10036 
10037 void
dns_zone_setmaxrefreshtime(dns_zone_t * zone,isc_uint32_t val)10038 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
10039 	REQUIRE(DNS_ZONE_VALID(zone));
10040 	REQUIRE(val > 0);
10041 
10042 	zone->maxrefresh = val;
10043 }
10044 
10045 void
dns_zone_setminretrytime(dns_zone_t * zone,isc_uint32_t val)10046 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
10047 	REQUIRE(DNS_ZONE_VALID(zone));
10048 	REQUIRE(val > 0);
10049 
10050 	zone->minretry = val;
10051 }
10052 
10053 void
dns_zone_setmaxretrytime(dns_zone_t * zone,isc_uint32_t val)10054 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
10055 	REQUIRE(DNS_ZONE_VALID(zone));
10056 	REQUIRE(val > 0);
10057 
10058 	zone->maxretry = val;
10059 }
10060 
10061 static isc_boolean_t
notify_isqueued(dns_zone_t * zone,unsigned int flags,dns_name_t * name,isc_sockaddr_t * addr,dns_tsigkey_t * key)10062 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
10063 		isc_sockaddr_t *addr, dns_tsigkey_t *key)
10064 {
10065 	dns_notify_t *notify;
10066 	dns_zonemgr_t *zmgr;
10067 	isc_result_t result;
10068 
10069 	for (notify = ISC_LIST_HEAD(zone->notifies);
10070 	     notify != NULL;
10071 	     notify = ISC_LIST_NEXT(notify, link)) {
10072 		if (notify->request != NULL)
10073 			continue;
10074 		if ((flags & DNS_NOTIFY_STARTUP) == 0)
10075 			notify->flags &= ~DNS_NOTIFY_STARTUP;
10076 		if (name != NULL && dns_name_dynamic(&notify->ns) &&
10077 		    dns_name_equal(name, &notify->ns))
10078 			goto requeue;
10079 		if (addr != NULL && isc_sockaddr_equal(addr, &notify->dst) &&
10080 		    notify->key == key)
10081 			goto requeue;
10082 	}
10083 	return (ISC_FALSE);
10084 
10085 requeue:
10086 	/*
10087 	 * If we are enqueued on the startup ratelimiter and this is
10088 	 * not a startup notify, re-enqueue on the normal notify
10089 	 * ratelimiter.
10090 	 */
10091 	if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0) {
10092 		zmgr = notify->zone->zmgr;
10093 		result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl,
10094 						 notify->event);
10095 		if (result != ISC_R_SUCCESS)
10096 			return (ISC_TRUE);
10097 		result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
10098 						 notify->zone->task,
10099 						 &notify->event);
10100 		if (result != ISC_R_SUCCESS) {
10101 			isc_event_free(&notify->event);
10102 			return (ISC_FALSE);
10103 		}
10104 	}
10105 
10106 	return (ISC_TRUE);
10107 }
10108 
10109 static isc_boolean_t
notify_isself(dns_zone_t * zone,isc_sockaddr_t * dst)10110 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
10111 	dns_tsigkey_t *key = NULL;
10112 	isc_sockaddr_t src;
10113 	isc_sockaddr_t any;
10114 	isc_boolean_t isself;
10115 	isc_netaddr_t dstaddr;
10116 	isc_result_t result;
10117 
10118 	if (zone->view == NULL || zone->isself == NULL)
10119 		return (ISC_FALSE);
10120 
10121 	switch (isc_sockaddr_pf(dst)) {
10122 	case PF_INET:
10123 		src = zone->notifysrc4;
10124 		isc_sockaddr_any(&any);
10125 		break;
10126 	case PF_INET6:
10127 		src = zone->notifysrc6;
10128 		isc_sockaddr_any6(&any);
10129 		break;
10130 	default:
10131 		return (ISC_FALSE);
10132 	}
10133 
10134 	/*
10135 	 * When sending from any the kernel will assign a source address
10136 	 * that matches the destination address.
10137 	 */
10138 	if (isc_sockaddr_eqaddr(&any, &src))
10139 		src = *dst;
10140 
10141 	isc_netaddr_fromsockaddr(&dstaddr, dst);
10142 	result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
10143 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
10144 		return (ISC_FALSE);
10145 	isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
10146 				zone->isselfarg);
10147 	if (key != NULL)
10148 		dns_tsigkey_detach(&key);
10149 	return (isself);
10150 }
10151 
10152 static void
notify_destroy(dns_notify_t * notify,isc_boolean_t locked)10153 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
10154 	isc_mem_t *mctx;
10155 
10156 	/*
10157 	 * Caller holds zone lock.
10158 	 */
10159 	REQUIRE(DNS_NOTIFY_VALID(notify));
10160 
10161 	if (notify->zone != NULL) {
10162 		if (!locked)
10163 			LOCK_ZONE(notify->zone);
10164 		REQUIRE(LOCKED_ZONE(notify->zone));
10165 		if (ISC_LINK_LINKED(notify, link))
10166 			ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
10167 		if (!locked)
10168 			UNLOCK_ZONE(notify->zone);
10169 		if (locked)
10170 			zone_idetach(&notify->zone);
10171 		else
10172 			dns_zone_idetach(&notify->zone);
10173 	}
10174 	if (notify->find != NULL)
10175 		dns_adb_destroyfind(&notify->find);
10176 	if (notify->request != NULL)
10177 		dns_request_destroy(&notify->request);
10178 	if (dns_name_dynamic(&notify->ns))
10179 		dns_name_free(&notify->ns, notify->mctx);
10180 	if (notify->key != NULL)
10181 		dns_tsigkey_detach(&notify->key);
10182 	mctx = notify->mctx;
10183 	isc_mem_put(notify->mctx, notify, sizeof(*notify));
10184 	isc_mem_detach(&mctx);
10185 }
10186 
10187 static isc_result_t
notify_create(isc_mem_t * mctx,unsigned int flags,dns_notify_t ** notifyp)10188 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
10189 	dns_notify_t *notify;
10190 
10191 	REQUIRE(notifyp != NULL && *notifyp == NULL);
10192 
10193 	notify = isc_mem_get(mctx, sizeof(*notify));
10194 	if (notify == NULL)
10195 		return (ISC_R_NOMEMORY);
10196 
10197 	notify->mctx = NULL;
10198 	isc_mem_attach(mctx, &notify->mctx);
10199 	notify->flags = flags;
10200 	notify->zone = NULL;
10201 	notify->find = NULL;
10202 	notify->request = NULL;
10203 	notify->key = NULL;
10204 	notify->event = NULL;
10205 	isc_sockaddr_any(&notify->dst);
10206 	dns_name_init(&notify->ns, NULL);
10207 	ISC_LINK_INIT(notify, link);
10208 	notify->magic = NOTIFY_MAGIC;
10209 	*notifyp = notify;
10210 	return (ISC_R_SUCCESS);
10211 }
10212 
10213 /*
10214  * XXXAG should check for DNS_ZONEFLG_EXITING
10215  */
10216 static void
process_adb_event(isc_task_t * task,isc_event_t * ev)10217 process_adb_event(isc_task_t *task, isc_event_t *ev) {
10218 	dns_notify_t *notify;
10219 	isc_eventtype_t result;
10220 
10221 	UNUSED(task);
10222 
10223 	notify = ev->ev_arg;
10224 	REQUIRE(DNS_NOTIFY_VALID(notify));
10225 	INSIST(task == notify->zone->task);
10226 	result = ev->ev_type;
10227 	isc_event_free(&ev);
10228 	if (result == DNS_EVENT_ADBMOREADDRESSES) {
10229 		dns_adb_destroyfind(&notify->find);
10230 		notify_find_address(notify);
10231 		return;
10232 	}
10233 	if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
10234 		LOCK_ZONE(notify->zone);
10235 		notify_send(notify);
10236 		UNLOCK_ZONE(notify->zone);
10237 	}
10238 	notify_destroy(notify, ISC_FALSE);
10239 }
10240 
10241 static void
notify_find_address(dns_notify_t * notify)10242 notify_find_address(dns_notify_t *notify) {
10243 	isc_result_t result;
10244 	unsigned int options;
10245 
10246 	REQUIRE(DNS_NOTIFY_VALID(notify));
10247 	options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
10248 		  DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
10249 
10250 	if (notify->zone->view->adb == NULL)
10251 		goto destroy;
10252 
10253 	result = dns_adb_createfind(notify->zone->view->adb,
10254 				    notify->zone->task,
10255 				    process_adb_event, notify,
10256 				    &notify->ns, dns_rootname, 0,
10257 				    options, 0, NULL,
10258 				    notify->zone->view->dstport,
10259 				    &notify->find);
10260 
10261 	/* Something failed? */
10262 	if (result != ISC_R_SUCCESS)
10263 		goto destroy;
10264 
10265 	/* More addresses pending? */
10266 	if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
10267 		return;
10268 
10269 	/* We have as many addresses as we can get. */
10270 	LOCK_ZONE(notify->zone);
10271 	notify_send(notify);
10272 	UNLOCK_ZONE(notify->zone);
10273 
10274  destroy:
10275 	notify_destroy(notify, ISC_FALSE);
10276 }
10277 
10278 
10279 static isc_result_t
notify_send_queue(dns_notify_t * notify,isc_boolean_t startup)10280 notify_send_queue(dns_notify_t *notify, isc_boolean_t startup) {
10281 	isc_event_t *e;
10282 	isc_result_t result;
10283 
10284 	INSIST(notify->event == NULL);
10285 	e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR,
10286 			       notify_send_toaddr, notify, sizeof(isc_event_t));
10287 	if (e == NULL)
10288 		return (ISC_R_NOMEMORY);
10289 	if (startup)
10290 		notify->event = e;
10291 	e->ev_arg = notify;
10292 	e->ev_sender = NULL;
10293 	result = isc_ratelimiter_enqueue(startup
10294 					  ? notify->zone->zmgr->startupnotifyrl
10295 					  : notify->zone->zmgr->notifyrl,
10296 					 notify->zone->task, &e);
10297 	if (result != ISC_R_SUCCESS) {
10298 		isc_event_free(&e);
10299 		notify->event = NULL;
10300 	}
10301 	return (result);
10302 }
10303 
10304 static void
notify_send_toaddr(isc_task_t * task,isc_event_t * event)10305 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
10306 	dns_notify_t *notify;
10307 	isc_result_t result;
10308 	dns_message_t *message = NULL;
10309 	isc_netaddr_t dstip;
10310 	dns_tsigkey_t *key = NULL;
10311 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
10312 	isc_sockaddr_t src;
10313 	int timeout;
10314 	isc_boolean_t have_notifysource = ISC_FALSE;
10315 	isc_boolean_t have_notifydscp = ISC_FALSE;
10316 	isc_dscp_t dscp = -1;
10317 
10318 	notify = event->ev_arg;
10319 	REQUIRE(DNS_NOTIFY_VALID(notify));
10320 
10321 	UNUSED(task);
10322 
10323 	LOCK_ZONE(notify->zone);
10324 
10325 	notify->event = NULL;
10326 
10327 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
10328 		result = ISC_R_CANCELED;
10329 		goto cleanup;
10330 	}
10331 
10332 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
10333 	    DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
10334 	    notify->zone->view->requestmgr == NULL ||
10335 	    notify->zone->db == NULL) {
10336 		result = ISC_R_CANCELED;
10337 		goto cleanup;
10338 	}
10339 
10340 	/*
10341 	 * The raw IPv4 address should also exist.  Don't send to the
10342 	 * mapped form.
10343 	 */
10344 	if (isc_sockaddr_pf(&notify->dst) == PF_INET6 &&
10345 	    IN6_IS_ADDR_V4MAPPED(&notify->dst.type.sin6.sin6_addr)) {
10346 		isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
10347 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
10348 			   "notify: ignoring IPv6 mapped IPV4 address: %s",
10349 			   addrbuf);
10350 		result = ISC_R_CANCELED;
10351 		goto cleanup;
10352 	}
10353 
10354 	result = notify_createmessage(notify->zone, notify->flags, &message);
10355 	if (result != ISC_R_SUCCESS)
10356 		goto cleanup;
10357 
10358 	if (notify->key != NULL) {
10359 		/* Transfer ownership of key */
10360 		key = notify->key;
10361 		notify->key = NULL;
10362 	} else {
10363 		isc_netaddr_fromsockaddr(&dstip, &notify->dst);
10364 		isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
10365 		result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
10366 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
10367 			notify_log(notify->zone, ISC_LOG_ERROR,
10368 				   "NOTIFY to %s not sent. "
10369 				   "Peer TSIG key lookup failure.", addrbuf);
10370 			goto cleanup_message;
10371 		}
10372 	}
10373 
10374 	/* XXX: should we log the tsig key too? */
10375 	notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
10376 		   addrbuf);
10377 	if (notify->zone->view->peers != NULL) {
10378 		dns_peer_t *peer = NULL;
10379 		result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
10380 						 &dstip, &peer);
10381 		if (result == ISC_R_SUCCESS) {
10382 			result = dns_peer_getnotifysource(peer, &src);
10383 			if (result == ISC_R_SUCCESS)
10384 				have_notifysource = ISC_TRUE;
10385 			dns_peer_getnotifydscp(peer, &dscp);
10386 			if (dscp != -1)
10387 				have_notifydscp = ISC_TRUE;
10388 		}
10389 	}
10390 	switch (isc_sockaddr_pf(&notify->dst)) {
10391 	case PF_INET:
10392 		if (!have_notifysource)
10393 			src = notify->zone->notifysrc4;
10394 		if (!have_notifydscp)
10395 			dscp = notify->zone->notifysrc4dscp;
10396 		break;
10397 	case PF_INET6:
10398 		if (!have_notifysource)
10399 			src = notify->zone->notifysrc6;
10400 		if (!have_notifydscp)
10401 			dscp = notify->zone->notifysrc6dscp;
10402 		break;
10403 	default:
10404 		result = ISC_R_NOTIMPLEMENTED;
10405 		goto cleanup_key;
10406 	}
10407 	timeout = 15;
10408 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
10409 		timeout = 30;
10410 	result = dns_request_createvia4(notify->zone->view->requestmgr,
10411 					message, &src, &notify->dst, dscp,
10412 					0, key, timeout * 3, timeout, 0,
10413 					notify->zone->task, notify_done,
10414 					notify, &notify->request);
10415 	if (result == ISC_R_SUCCESS) {
10416 		if (isc_sockaddr_pf(&notify->dst) == AF_INET) {
10417 			inc_stats(notify->zone,
10418 				  dns_zonestatscounter_notifyoutv4);
10419 		} else {
10420 			inc_stats(notify->zone,
10421 				  dns_zonestatscounter_notifyoutv6);
10422 		}
10423 	}
10424 
10425  cleanup_key:
10426 	if (key != NULL)
10427 		dns_tsigkey_detach(&key);
10428  cleanup_message:
10429 	dns_message_destroy(&message);
10430  cleanup:
10431 	UNLOCK_ZONE(notify->zone);
10432 	isc_event_free(&event);
10433 	if (result != ISC_R_SUCCESS)
10434 		notify_destroy(notify, ISC_FALSE);
10435 }
10436 
10437 static void
notify_send(dns_notify_t * notify)10438 notify_send(dns_notify_t *notify) {
10439 	dns_adbaddrinfo_t *ai;
10440 	isc_sockaddr_t dst;
10441 	isc_result_t result;
10442 	dns_notify_t *new = NULL;
10443 	unsigned int flags;
10444 	isc_boolean_t startup;
10445 
10446 	/*
10447 	 * Zone lock held by caller.
10448 	 */
10449 	REQUIRE(DNS_NOTIFY_VALID(notify));
10450 	REQUIRE(LOCKED_ZONE(notify->zone));
10451 
10452 	for (ai = ISC_LIST_HEAD(notify->find->list);
10453 	     ai != NULL;
10454 	     ai = ISC_LIST_NEXT(ai, publink)) {
10455 		dst = ai->sockaddr;
10456 		if (notify_isqueued(notify->zone, notify->flags, NULL, &dst,
10457 				    NULL))
10458 			continue;
10459 		if (notify_isself(notify->zone, &dst))
10460 			continue;
10461 		new = NULL;
10462 		flags = notify->flags & DNS_NOTIFY_NOSOA;
10463 		result = notify_create(notify->mctx, flags, &new);
10464 		if (result != ISC_R_SUCCESS)
10465 			goto cleanup;
10466 		zone_iattach(notify->zone, &new->zone);
10467 		ISC_LIST_APPEND(new->zone->notifies, new, link);
10468 		new->dst = dst;
10469 		startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0);
10470 		result = notify_send_queue(new, startup);
10471 		if (result != ISC_R_SUCCESS)
10472 			goto cleanup;
10473 		new = NULL;
10474 	}
10475 
10476  cleanup:
10477 	if (new != NULL)
10478 		notify_destroy(new, ISC_TRUE);
10479 }
10480 
10481 void
dns_zone_notify(dns_zone_t * zone)10482 dns_zone_notify(dns_zone_t *zone) {
10483 	isc_time_t now;
10484 
10485 	REQUIRE(DNS_ZONE_VALID(zone));
10486 
10487 	LOCK_ZONE(zone);
10488 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
10489 
10490 	TIME_NOW(&now);
10491 	zone_settimer(zone, &now);
10492 	UNLOCK_ZONE(zone);
10493 }
10494 
10495 static void
zone_notify(dns_zone_t * zone,isc_time_t * now)10496 zone_notify(dns_zone_t *zone, isc_time_t *now) {
10497 	dns_dbnode_t *node = NULL;
10498 	dns_db_t *zonedb = NULL;
10499 	dns_dbversion_t *version = NULL;
10500 	dns_name_t *origin = NULL;
10501 	dns_name_t master;
10502 	dns_rdata_ns_t ns;
10503 	dns_rdata_soa_t soa;
10504 	isc_uint32_t serial;
10505 	dns_rdata_t rdata = DNS_RDATA_INIT;
10506 	dns_rdataset_t nsrdset;
10507 	dns_rdataset_t soardset;
10508 	isc_result_t result;
10509 	unsigned int i;
10510 	isc_sockaddr_t dst;
10511 	isc_boolean_t isqueued;
10512 	dns_notifytype_t notifytype;
10513 	unsigned int flags = 0;
10514 	isc_boolean_t loggednotify = ISC_FALSE;
10515 	isc_boolean_t startup;
10516 
10517 	REQUIRE(DNS_ZONE_VALID(zone));
10518 
10519 	LOCK_ZONE(zone);
10520 	startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
10521 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
10522 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
10523 	notifytype = zone->notifytype;
10524 	DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
10525 	UNLOCK_ZONE(zone);
10526 
10527 	if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
10528 		return;
10529 
10530 	if (notifytype == dns_notifytype_no)
10531 		return;
10532 
10533 	if (notifytype == dns_notifytype_masteronly &&
10534 	    zone->type != dns_zone_master)
10535 		return;
10536 
10537 	origin = &zone->origin;
10538 
10539 	/*
10540 	 * If the zone is dialup we are done as we don't want to send
10541 	 * the current soa so as to force a refresh query.
10542 	 */
10543 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
10544 		flags |= DNS_NOTIFY_NOSOA;
10545 
10546 	/*
10547 	 * Record that this was a notify due to starting up.
10548 	 */
10549 	if (startup)
10550 		flags |= DNS_NOTIFY_STARTUP;
10551 
10552 	/*
10553 	 * Get SOA RRset.
10554 	 */
10555 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10556 	if (zone->db != NULL)
10557 		dns_db_attach(zone->db, &zonedb);
10558 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10559 	if (zonedb == NULL)
10560 		return;
10561 	dns_db_currentversion(zonedb, &version);
10562 	result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
10563 	if (result != ISC_R_SUCCESS)
10564 		goto cleanup1;
10565 
10566 	dns_rdataset_init(&soardset);
10567 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
10568 				     dns_rdatatype_none, 0, &soardset, NULL);
10569 	if (result != ISC_R_SUCCESS)
10570 		goto cleanup2;
10571 
10572 	/*
10573 	 * Find serial and master server's name.
10574 	 */
10575 	dns_name_init(&master, NULL);
10576 	result = dns_rdataset_first(&soardset);
10577 	if (result != ISC_R_SUCCESS)
10578 		goto cleanup3;
10579 	dns_rdataset_current(&soardset, &rdata);
10580 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
10581 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
10582 	dns_rdata_reset(&rdata);
10583 	result = dns_name_dup(&soa.origin, zone->mctx, &master);
10584 	serial = soa.serial;
10585 	dns_rdataset_disassociate(&soardset);
10586 	if (result != ISC_R_SUCCESS)
10587 		goto cleanup3;
10588 
10589 	/*
10590 	 * Enqueue notify requests for 'also-notify' servers.
10591 	 */
10592 	LOCK_ZONE(zone);
10593 	for (i = 0; i < zone->notifycnt; i++) {
10594 		dns_tsigkey_t *key = NULL;
10595 		dns_notify_t *notify = NULL;
10596 
10597 		if ((zone->notifykeynames != NULL) &&
10598 		    (zone->notifykeynames[i] != NULL)) {
10599 			dns_view_t *view = dns_zone_getview(zone);
10600 			dns_name_t *keyname = zone->notifykeynames[i];
10601 			(void)dns_view_gettsig(view, keyname, &key);
10602 		}
10603 
10604 		dst = zone->notify[i];
10605 		if (notify_isqueued(zone, flags, NULL, &dst, key)) {
10606 			if (key != NULL)
10607 				dns_tsigkey_detach(&key);
10608 			continue;
10609 		}
10610 
10611 		result = notify_create(zone->mctx, flags, &notify);
10612 		if (result != ISC_R_SUCCESS) {
10613 			if (key != NULL)
10614 				dns_tsigkey_detach(&key);
10615 			continue;
10616 		}
10617 
10618 		zone_iattach(zone, &notify->zone);
10619 		notify->dst = dst;
10620 
10621 		INSIST(notify->key == NULL);
10622 
10623 		if (key != NULL) {
10624 			notify->key = key;
10625 			key = NULL;
10626 		}
10627 
10628 		ISC_LIST_APPEND(zone->notifies, notify, link);
10629 		result = notify_send_queue(notify, startup);
10630 		if (result != ISC_R_SUCCESS)
10631 			notify_destroy(notify, ISC_TRUE);
10632 		if (!loggednotify) {
10633 			notify_log(zone, ISC_LOG_INFO,
10634 				   "sending notifies (serial %u)",
10635 				   serial);
10636 			loggednotify = ISC_TRUE;
10637 		}
10638 	}
10639 	UNLOCK_ZONE(zone);
10640 
10641 	if (notifytype == dns_notifytype_explicit)
10642 		goto cleanup3;
10643 
10644 	/*
10645 	 * Process NS RRset to generate notifies.
10646 	 */
10647 
10648 	dns_rdataset_init(&nsrdset);
10649 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
10650 				     dns_rdatatype_none, 0, &nsrdset, NULL);
10651 	if (result != ISC_R_SUCCESS)
10652 		goto cleanup3;
10653 
10654 	result = dns_rdataset_first(&nsrdset);
10655 	while (result == ISC_R_SUCCESS) {
10656 		dns_notify_t *notify = NULL;
10657 
10658 		dns_rdataset_current(&nsrdset, &rdata);
10659 		result = dns_rdata_tostruct(&rdata, &ns, NULL);
10660 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
10661 		dns_rdata_reset(&rdata);
10662 		/*
10663 		 * Don't notify the master server unless explicitly
10664 		 * configured to do so.
10665 		 */
10666 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
10667 		    dns_name_compare(&master, &ns.name) == 0) {
10668 			result = dns_rdataset_next(&nsrdset);
10669 			continue;
10670 		}
10671 
10672 		if (!loggednotify) {
10673 			notify_log(zone, ISC_LOG_INFO,
10674 				   "sending notifies (serial %u)",
10675 				   serial);
10676 			loggednotify = ISC_TRUE;
10677 		}
10678 
10679 		LOCK_ZONE(zone);
10680 		isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL);
10681 		UNLOCK_ZONE(zone);
10682 		if (isqueued) {
10683 			result = dns_rdataset_next(&nsrdset);
10684 			continue;
10685 		}
10686 		result = notify_create(zone->mctx, flags, &notify);
10687 		if (result != ISC_R_SUCCESS)
10688 			continue;
10689 		dns_zone_iattach(zone, &notify->zone);
10690 		result = dns_name_dup(&ns.name, zone->mctx, &notify->ns);
10691 		if (result != ISC_R_SUCCESS) {
10692 			LOCK_ZONE(zone);
10693 			notify_destroy(notify, ISC_TRUE);
10694 			UNLOCK_ZONE(zone);
10695 			continue;
10696 		}
10697 		LOCK_ZONE(zone);
10698 		ISC_LIST_APPEND(zone->notifies, notify, link);
10699 		UNLOCK_ZONE(zone);
10700 		notify_find_address(notify);
10701 		result = dns_rdataset_next(&nsrdset);
10702 	}
10703 	dns_rdataset_disassociate(&nsrdset);
10704 
10705  cleanup3:
10706 	if (dns_name_dynamic(&master))
10707 		dns_name_free(&master, zone->mctx);
10708  cleanup2:
10709 	dns_db_detachnode(zonedb, &node);
10710  cleanup1:
10711 	dns_db_closeversion(zonedb, &version, ISC_FALSE);
10712 	dns_db_detach(&zonedb);
10713 }
10714 
10715 /***
10716  *** Private
10717  ***/
10718 
10719 static inline isc_result_t
save_nsrrset(dns_message_t * message,dns_name_t * name,dns_db_t * db,dns_dbversion_t * version)10720 save_nsrrset(dns_message_t *message, dns_name_t *name,
10721 	     dns_db_t *db, dns_dbversion_t *version)
10722 {
10723 	dns_rdataset_t *nsrdataset = NULL;
10724 	dns_rdataset_t *rdataset = NULL;
10725 	dns_dbnode_t *node = NULL;
10726 	dns_rdata_ns_t ns;
10727 	isc_result_t result;
10728 	dns_rdata_t rdata = DNS_RDATA_INIT;
10729 
10730 	/*
10731 	 * Extract NS RRset from message.
10732 	 */
10733 	result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
10734 				      dns_rdatatype_ns, dns_rdatatype_none,
10735 				      NULL, &nsrdataset);
10736 	if (result != ISC_R_SUCCESS)
10737 		goto fail;
10738 
10739 	/*
10740 	 * Add NS rdataset.
10741 	 */
10742 	result = dns_db_findnode(db, name, ISC_TRUE, &node);
10743 	if (result != ISC_R_SUCCESS)
10744 		goto fail;
10745 	result = dns_db_addrdataset(db, node, version, 0,
10746 				    nsrdataset, 0, NULL);
10747 	dns_db_detachnode(db, &node);
10748 	if (result != ISC_R_SUCCESS)
10749 		goto fail;
10750 	/*
10751 	 * Add glue rdatasets.
10752 	 */
10753 	for (result = dns_rdataset_first(nsrdataset);
10754 	     result == ISC_R_SUCCESS;
10755 	     result = dns_rdataset_next(nsrdataset)) {
10756 		dns_rdataset_current(nsrdataset, &rdata);
10757 		result = dns_rdata_tostruct(&rdata, &ns, NULL);
10758 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
10759 		dns_rdata_reset(&rdata);
10760 		if (!dns_name_issubdomain(&ns.name, name))
10761 			continue;
10762 		rdataset = NULL;
10763 		result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
10764 					      &ns.name, dns_rdatatype_aaaa,
10765 					      dns_rdatatype_none, NULL,
10766 					      &rdataset);
10767 		if (result == ISC_R_SUCCESS) {
10768 			result = dns_db_findnode(db, &ns.name,
10769 						 ISC_TRUE, &node);
10770 			if (result != ISC_R_SUCCESS)
10771 				goto fail;
10772 			result = dns_db_addrdataset(db, node, version, 0,
10773 						    rdataset, 0, NULL);
10774 			dns_db_detachnode(db, &node);
10775 			if (result != ISC_R_SUCCESS)
10776 				goto fail;
10777 		}
10778 		rdataset = NULL;
10779 		result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
10780 					      &ns.name, dns_rdatatype_a,
10781 					      dns_rdatatype_none, NULL,
10782 					      &rdataset);
10783 		if (result == ISC_R_SUCCESS) {
10784 			result = dns_db_findnode(db, &ns.name,
10785 						 ISC_TRUE, &node);
10786 			if (result != ISC_R_SUCCESS)
10787 				goto fail;
10788 			result = dns_db_addrdataset(db, node, version, 0,
10789 						    rdataset, 0, NULL);
10790 			dns_db_detachnode(db, &node);
10791 			if (result != ISC_R_SUCCESS)
10792 				goto fail;
10793 		}
10794 	}
10795 	if (result != ISC_R_NOMORE)
10796 		goto fail;
10797 
10798 	return (ISC_R_SUCCESS);
10799 
10800 fail:
10801 	return (result);
10802 }
10803 
10804 static void
stub_callback(isc_task_t * task,isc_event_t * event)10805 stub_callback(isc_task_t *task, isc_event_t *event) {
10806 	const char me[] = "stub_callback";
10807 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
10808 	dns_stub_t *stub = NULL;
10809 	dns_message_t *msg = NULL;
10810 	dns_zone_t *zone = NULL;
10811 	char master[ISC_SOCKADDR_FORMATSIZE];
10812 	char source[ISC_SOCKADDR_FORMATSIZE];
10813 	isc_uint32_t nscnt, cnamecnt, refresh, retry, expire;
10814 	isc_result_t result;
10815 	isc_time_t now;
10816 	isc_boolean_t exiting = ISC_FALSE;
10817 	isc_interval_t i;
10818 	unsigned int j, soacount;
10819 
10820 	stub = revent->ev_arg;
10821 	INSIST(DNS_STUB_VALID(stub));
10822 
10823 	UNUSED(task);
10824 
10825 	zone = stub->zone;
10826 
10827 	ENTER;
10828 
10829 	TIME_NOW(&now);
10830 
10831 	LOCK_ZONE(zone);
10832 
10833 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10834 		zone_debuglog(zone, me, 1, "exiting");
10835 		exiting = ISC_TRUE;
10836 		goto next_master;
10837 	}
10838 
10839 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
10840 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
10841 
10842 	if (revent->result != ISC_R_SUCCESS) {
10843 		if (revent->result == ISC_R_TIMEDOUT &&
10844 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10845 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10846 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
10847 				     "refreshing stub: timeout retrying "
10848 				     " without EDNS master %s (source %s)",
10849 				     master, source);
10850 			goto same_master;
10851 		}
10852 		dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
10853 					   &zone->sourceaddr, &now);
10854 		dns_zone_log(zone, ISC_LOG_INFO,
10855 			     "could not refresh stub from master %s"
10856 			     " (source %s): %s", master, source,
10857 			     dns_result_totext(revent->result));
10858 		goto next_master;
10859 	}
10860 
10861 	result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
10862 	if (result != ISC_R_SUCCESS)
10863 		goto next_master;
10864 
10865 	result = dns_request_getresponse(revent->request, msg, 0);
10866 	if (result != ISC_R_SUCCESS)
10867 		goto next_master;
10868 
10869 	/*
10870 	 * Unexpected rcode.
10871 	 */
10872 	if (msg->rcode != dns_rcode_noerror) {
10873 		char rcode[128];
10874 		isc_buffer_t rb;
10875 
10876 		isc_buffer_init(&rb, rcode, sizeof(rcode));
10877 		(void)dns_rcode_totext(msg->rcode, &rb);
10878 
10879 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
10880 		    (msg->rcode == dns_rcode_servfail ||
10881 		     msg->rcode == dns_rcode_notimp ||
10882 		     msg->rcode == dns_rcode_formerr)) {
10883 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
10884 				     "refreshing stub: rcode (%.*s) retrying "
10885 				     "without EDNS master %s (source %s)",
10886 				     (int)rb.used, rcode, master, source);
10887 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10888 			goto same_master;
10889 		}
10890 
10891 		dns_zone_log(zone, ISC_LOG_INFO,
10892 			     "refreshing stub: "
10893 			     "unexpected rcode (%.*s) from %s (source %s)",
10894 			     (int)rb.used, rcode, master, source);
10895 		goto next_master;
10896 	}
10897 
10898 	/*
10899 	 * We need complete messages.
10900 	 */
10901 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
10902 		if (dns_request_usedtcp(revent->request)) {
10903 			dns_zone_log(zone, ISC_LOG_INFO,
10904 				     "refreshing stub: truncated TCP "
10905 				     "response from master %s (source %s)",
10906 				     master, source);
10907 			goto next_master;
10908 		}
10909 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
10910 		goto same_master;
10911 	}
10912 
10913 	/*
10914 	 * If non-auth log and next master.
10915 	 */
10916 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
10917 		dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10918 			     "non-authoritative answer from "
10919 			     "master %s (source %s)", master, source);
10920 		goto next_master;
10921 	}
10922 
10923 	/*
10924 	 * Sanity checks.
10925 	 */
10926 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
10927 	nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
10928 
10929 	if (cnamecnt != 0) {
10930 		dns_zone_log(zone, ISC_LOG_INFO,
10931 			     "refreshing stub: unexpected CNAME response "
10932 			     "from master %s (source %s)", master, source);
10933 		goto next_master;
10934 	}
10935 
10936 	if (nscnt == 0) {
10937 		dns_zone_log(zone, ISC_LOG_INFO,
10938 			     "refreshing stub: no NS records in response "
10939 			     "from master %s (source %s)", master, source);
10940 		goto next_master;
10941 	}
10942 
10943 	/*
10944 	 * Save answer.
10945 	 */
10946 	result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
10947 	if (result != ISC_R_SUCCESS) {
10948 		dns_zone_log(zone, ISC_LOG_INFO,
10949 			     "refreshing stub: unable to save NS records "
10950 			     "from master %s (source %s)", master, source);
10951 		goto next_master;
10952 	}
10953 
10954 	/*
10955 	 * Tidy up.
10956 	 */
10957 	dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
10958 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
10959 	if (zone->db == NULL)
10960 		zone_attachdb(zone, stub->db);
10961 	result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
10962 				  &refresh, &retry, &expire, NULL, NULL);
10963 	if (result == ISC_R_SUCCESS && soacount > 0U) {
10964 		zone->refresh = RANGE(refresh, zone->minrefresh,
10965 				      zone->maxrefresh);
10966 		zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
10967 		zone->expire = RANGE(expire, zone->refresh + zone->retry,
10968 				     DNS_MAX_EXPIRE);
10969 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
10970 	}
10971 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
10972 	dns_db_detach(&stub->db);
10973 
10974 	dns_message_destroy(&msg);
10975 	isc_event_free(&event);
10976 	dns_request_destroy(&zone->request);
10977 
10978 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10979 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
10980 	DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
10981 	isc_interval_set(&i, zone->expire, 0);
10982 	DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
10983 
10984 	if (zone->masterfile != NULL)
10985 		zone_needdump(zone, 0);
10986 
10987 	zone_settimer(zone, &now);
10988 	goto free_stub;
10989 
10990  next_master:
10991 	if (stub->version != NULL)
10992 		dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
10993 	if (stub->db != NULL)
10994 		dns_db_detach(&stub->db);
10995 	if (msg != NULL)
10996 		dns_message_destroy(&msg);
10997 	isc_event_free(&event);
10998 	dns_request_destroy(&zone->request);
10999 	/*
11000 	 * Skip to next failed / untried master.
11001 	 */
11002 	do {
11003 		zone->curmaster++;
11004 	} while (zone->curmaster < zone->masterscnt &&
11005 		 zone->mastersok[zone->curmaster]);
11006 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
11007 	if (exiting || zone->curmaster >= zone->masterscnt) {
11008 		isc_boolean_t done = ISC_TRUE;
11009 		if (!exiting &&
11010 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
11011 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11012 			/*
11013 			 * Did we get a good answer from all the masters?
11014 			 */
11015 			for (j = 0; j < zone->masterscnt; j++)
11016 				if (zone->mastersok[j] == ISC_FALSE) {
11017 					done = ISC_FALSE;
11018 					break;
11019 				}
11020 		} else
11021 			done = ISC_TRUE;
11022 		if (!done) {
11023 			zone->curmaster = 0;
11024 			/*
11025 			 * Find the next failed master.
11026 			 */
11027 			while (zone->curmaster < zone->masterscnt &&
11028 			       zone->mastersok[zone->curmaster])
11029 				zone->curmaster++;
11030 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11031 		} else {
11032 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11033 
11034 			zone_settimer(zone, &now);
11035 			goto free_stub;
11036 		}
11037 	}
11038 	queue_soa_query(zone);
11039 	goto free_stub;
11040 
11041  same_master:
11042 	if (msg != NULL)
11043 		dns_message_destroy(&msg);
11044 	isc_event_free(&event);
11045 	dns_request_destroy(&zone->request);
11046 	ns_query(zone, NULL, stub);
11047 	UNLOCK_ZONE(zone);
11048 	goto done;
11049 
11050  free_stub:
11051 	UNLOCK_ZONE(zone);
11052 	stub->magic = 0;
11053 	dns_zone_idetach(&stub->zone);
11054 	INSIST(stub->db == NULL);
11055 	INSIST(stub->version == NULL);
11056 	isc_mem_put(stub->mctx, stub, sizeof(*stub));
11057 
11058  done:
11059 	INSIST(event == NULL);
11060 	return;
11061 }
11062 
11063 /*
11064  * An SOA query has finished (successfully or not).
11065  */
11066 static void
refresh_callback(isc_task_t * task,isc_event_t * event)11067 refresh_callback(isc_task_t *task, isc_event_t *event) {
11068 	const char me[] = "refresh_callback";
11069 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
11070 	dns_zone_t *zone;
11071 	dns_message_t *msg = NULL;
11072 	isc_uint32_t soacnt, cnamecnt, soacount, nscount;
11073 	isc_time_t now;
11074 	char master[ISC_SOCKADDR_FORMATSIZE];
11075 	char source[ISC_SOCKADDR_FORMATSIZE];
11076 	dns_rdataset_t *rdataset = NULL;
11077 	dns_rdata_t rdata = DNS_RDATA_INIT;
11078 	dns_rdata_soa_t soa;
11079 	isc_result_t result;
11080 	isc_uint32_t serial, oldserial = 0;
11081 	unsigned int j;
11082 	isc_boolean_t do_queue_xfrin = ISC_FALSE;
11083 
11084 	zone = revent->ev_arg;
11085 	INSIST(DNS_ZONE_VALID(zone));
11086 
11087 	UNUSED(task);
11088 
11089 	ENTER;
11090 
11091 	TIME_NOW(&now);
11092 
11093 	LOCK_ZONE(zone);
11094 
11095 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
11096 		isc_event_free(&event);
11097 		dns_request_destroy(&zone->request);
11098 		goto detach;
11099 	}
11100 
11101 	/*
11102 	 * if timeout log and next master;
11103 	 */
11104 
11105 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
11106 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
11107 
11108 	if (revent->result != ISC_R_SUCCESS) {
11109 		if (revent->result == ISC_R_TIMEDOUT &&
11110 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
11111 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11112 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
11113 				     "refresh: timeout retrying without EDNS "
11114 				     "master %s (source %s)", master, source);
11115 			goto same_master;
11116 		}
11117 		if (revent->result == ISC_R_TIMEDOUT &&
11118 		    !dns_request_usedtcp(revent->request)) {
11119 			dns_zone_log(zone, ISC_LOG_INFO,
11120 				     "refresh: retry limit for "
11121 				     "master %s exceeded (source %s)",
11122 				     master, source);
11123 			/* Try with slave with TCP. */
11124 			if ((zone->type == dns_zone_slave ||
11125 			     zone->type == dns_zone_redirect) &&
11126 			    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
11127 				if (!dns_zonemgr_unreachable(zone->zmgr,
11128 							     &zone->masteraddr,
11129 							     &zone->sourceaddr,
11130 							     &now))
11131 				{
11132 					DNS_ZONE_SETFLAG(zone,
11133 						     DNS_ZONEFLG_SOABEFOREAXFR);
11134 					goto tcp_transfer;
11135 				}
11136 				dns_zone_log(zone, ISC_LOG_DEBUG(1),
11137 					     "refresh: skipped tcp fallback "
11138 					     "as master %s (source %s) is "
11139 					     "unreachable (cached)",
11140 					      master, source);
11141 			}
11142 		} else
11143 			dns_zone_log(zone, ISC_LOG_INFO,
11144 				     "refresh: failure trying master "
11145 				     "%s (source %s): %s", master, source,
11146 				     dns_result_totext(revent->result));
11147 		goto next_master;
11148 	}
11149 
11150 	result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
11151 	if (result != ISC_R_SUCCESS)
11152 		goto next_master;
11153 	result = dns_request_getresponse(revent->request, msg, 0);
11154 	if (result != ISC_R_SUCCESS) {
11155 		dns_zone_log(zone, ISC_LOG_INFO,
11156 			     "refresh: failure trying master "
11157 			     "%s (source %s): %s", master, source,
11158 			     dns_result_totext(result));
11159 		goto next_master;
11160 	}
11161 
11162 	/*
11163 	 * Unexpected rcode.
11164 	 */
11165 	if (msg->rcode != dns_rcode_noerror) {
11166 		char rcode[128];
11167 		isc_buffer_t rb;
11168 
11169 		isc_buffer_init(&rb, rcode, sizeof(rcode));
11170 		(void)dns_rcode_totext(msg->rcode, &rb);
11171 
11172 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
11173 		    (msg->rcode == dns_rcode_servfail ||
11174 		     msg->rcode == dns_rcode_notimp ||
11175 		     msg->rcode == dns_rcode_formerr)) {
11176 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
11177 				     "refresh: rcode (%.*s) retrying without "
11178 				     "EDNS master %s (source %s)",
11179 				     (int)rb.used, rcode, master, source);
11180 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11181 			goto same_master;
11182 		}
11183 		dns_zone_log(zone, ISC_LOG_INFO,
11184 			     "refresh: unexpected rcode (%.*s) from "
11185 			     "master %s (source %s)", (int)rb.used, rcode,
11186 			     master, source);
11187 		/*
11188 		 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
11189 		 */
11190 		if (msg->rcode == dns_rcode_refused &&
11191 		    (zone->type == dns_zone_slave ||
11192 		     zone->type == dns_zone_redirect))
11193 			goto tcp_transfer;
11194 		goto next_master;
11195 	}
11196 
11197 	/*
11198 	 * If truncated punt to zone transfer which will query again.
11199 	 */
11200 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
11201 		if (zone->type == dns_zone_slave ||
11202 		    zone->type == dns_zone_redirect) {
11203 			dns_zone_log(zone, ISC_LOG_INFO,
11204 				     "refresh: truncated UDP answer, "
11205 				     "initiating TCP zone xfer "
11206 				     "for master %s (source %s)",
11207 				     master, source);
11208 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
11209 			goto tcp_transfer;
11210 		} else {
11211 			INSIST(zone->type == dns_zone_stub);
11212 			if (dns_request_usedtcp(revent->request)) {
11213 				dns_zone_log(zone, ISC_LOG_INFO,
11214 					     "refresh: truncated TCP response "
11215 					     "from master %s (source %s)",
11216 					     master, source);
11217 				goto next_master;
11218 			}
11219 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
11220 			goto same_master;
11221 		}
11222 	}
11223 
11224 	/*
11225 	 * if non-auth log and next master;
11226 	 */
11227 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
11228 		dns_zone_log(zone, ISC_LOG_INFO,
11229 			     "refresh: non-authoritative answer from "
11230 			     "master %s (source %s)", master, source);
11231 		goto next_master;
11232 	}
11233 
11234 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
11235 	soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
11236 	nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
11237 	soacount = message_count(msg, DNS_SECTION_AUTHORITY,
11238 				 dns_rdatatype_soa);
11239 
11240 	/*
11241 	 * There should not be a CNAME record at top of zone.
11242 	 */
11243 	if (cnamecnt != 0) {
11244 		dns_zone_log(zone, ISC_LOG_INFO,
11245 			     "refresh: CNAME at top of zone "
11246 			     "in master %s (source %s)", master, source);
11247 		goto next_master;
11248 	}
11249 
11250 	/*
11251 	 * if referral log and next master;
11252 	 */
11253 	if (soacnt == 0 && soacount == 0 && nscount != 0) {
11254 		dns_zone_log(zone, ISC_LOG_INFO,
11255 			     "refresh: referral response "
11256 			     "from master %s (source %s)", master, source);
11257 		goto next_master;
11258 	}
11259 
11260 	/*
11261 	 * if nodata log and next master;
11262 	 */
11263 	if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
11264 		dns_zone_log(zone, ISC_LOG_INFO,
11265 			     "refresh: NODATA response "
11266 			     "from master %s (source %s)", master, source);
11267 		goto next_master;
11268 	}
11269 
11270 	/*
11271 	 * Only one soa at top of zone.
11272 	 */
11273 	if (soacnt != 1) {
11274 		dns_zone_log(zone, ISC_LOG_INFO,
11275 			     "refresh: answer SOA count (%d) != 1 "
11276 			     "from master %s (source %s)",
11277 			     soacnt, master, source);
11278 		goto next_master;
11279 	}
11280 
11281 	/*
11282 	 * Extract serial
11283 	 */
11284 	rdataset = NULL;
11285 	result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
11286 				      dns_rdatatype_soa, dns_rdatatype_none,
11287 				      NULL, &rdataset);
11288 	if (result != ISC_R_SUCCESS) {
11289 		dns_zone_log(zone, ISC_LOG_INFO,
11290 			     "refresh: unable to get SOA record "
11291 			     "from master %s (source %s)", master, source);
11292 		goto next_master;
11293 	}
11294 
11295 	result = dns_rdataset_first(rdataset);
11296 	if (result != ISC_R_SUCCESS) {
11297 		dns_zone_log(zone, ISC_LOG_INFO,
11298 			     "refresh: dns_rdataset_first() failed");
11299 		goto next_master;
11300 	}
11301 
11302 	dns_rdataset_current(rdataset, &rdata);
11303 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
11304 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
11305 
11306 	serial = soa.serial;
11307 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
11308 		unsigned int dbsoacount;
11309 		result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount,
11310 					  &oldserial, NULL, NULL, NULL, NULL,
11311 					  NULL);
11312 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
11313 		RUNTIME_CHECK(dbsoacount > 0U);
11314 		zone_debuglog(zone, me, 1, "serial: new %u, old %u",
11315 			      serial, oldserial);
11316 	} else
11317 		zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
11318 			      serial);
11319 
11320 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
11321 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
11322 	    isc_serial_gt(serial, oldserial)) {
11323 		if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
11324 					    &zone->sourceaddr, &now))
11325 		{
11326 			dns_zone_log(zone, ISC_LOG_INFO,
11327 				     "refresh: skipping %s as master %s "
11328 				     "(source %s) is unreachable (cached)",
11329 				     (zone->type == dns_zone_slave ||
11330 				      zone->type == dns_zone_redirect) ?
11331 				     "zone transfer" : "NS query",
11332 				     master, source);
11333 			goto next_master;
11334 		}
11335  tcp_transfer:
11336 		isc_event_free(&event);
11337 		dns_request_destroy(&zone->request);
11338 		if (zone->type == dns_zone_slave ||
11339 		    zone->type == dns_zone_redirect) {
11340 			do_queue_xfrin = ISC_TRUE;
11341 		} else {
11342 			INSIST(zone->type == dns_zone_stub);
11343 			ns_query(zone, rdataset, NULL);
11344 		}
11345 		if (msg != NULL)
11346 			dns_message_destroy(&msg);
11347 	} else if (isc_serial_eq(soa.serial, oldserial)) {
11348 		if (zone->masterfile != NULL) {
11349 			result = ISC_R_FAILURE;
11350 			if (zone->journal != NULL)
11351 				result = isc_file_settime(zone->journal, &now);
11352 			if (result == ISC_R_SUCCESS &&
11353 			    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11354 			    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11355 				result = isc_file_settime(zone->masterfile,
11356 							  &now);
11357 			} else if (result != ISC_R_SUCCESS)
11358 				result = isc_file_settime(zone->masterfile,
11359 							  &now);
11360 			/* Someone removed the file from underneath us! */
11361 			if (result == ISC_R_FILENOTFOUND) {
11362 				zone_needdump(zone, DNS_DUMP_DELAY);
11363 			} else if (result != ISC_R_SUCCESS)
11364 				dns_zone_log(zone, ISC_LOG_ERROR,
11365 					     "refresh: could not set file "
11366 					     "modification time of '%s': %s",
11367 					     zone->masterfile,
11368 					     dns_result_totext(result));
11369 		}
11370 		DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
11371 		DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
11372 		zone->mastersok[zone->curmaster] = ISC_TRUE;
11373 		goto next_master;
11374 	} else {
11375 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
11376 			dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
11377 				     "received from master %s < ours (%u)",
11378 				     soa.serial, master, oldserial);
11379 		else
11380 			zone_debuglog(zone, me, 1, "ahead");
11381 		zone->mastersok[zone->curmaster] = ISC_TRUE;
11382 		goto next_master;
11383 	}
11384 	if (msg != NULL)
11385 		dns_message_destroy(&msg);
11386 	goto detach;
11387 
11388  next_master:
11389 	if (msg != NULL)
11390 		dns_message_destroy(&msg);
11391 	isc_event_free(&event);
11392 	dns_request_destroy(&zone->request);
11393 	/*
11394 	 * Skip to next failed / untried master.
11395 	 */
11396 	do {
11397 		zone->curmaster++;
11398 	} while (zone->curmaster < zone->masterscnt &&
11399 		 zone->mastersok[zone->curmaster]);
11400 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
11401 	if (zone->curmaster >= zone->masterscnt) {
11402 		isc_boolean_t done = ISC_TRUE;
11403 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
11404 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11405 			/*
11406 			 * Did we get a good answer from all the masters?
11407 			 */
11408 			for (j = 0; j < zone->masterscnt; j++)
11409 				if (zone->mastersok[j] == ISC_FALSE) {
11410 					done = ISC_FALSE;
11411 					break;
11412 				}
11413 		} else
11414 			done = ISC_TRUE;
11415 		if (!done) {
11416 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11417 			zone->curmaster = 0;
11418 			/*
11419 			 * Find the next failed master.
11420 			 */
11421 			while (zone->curmaster < zone->masterscnt &&
11422 			       zone->mastersok[zone->curmaster])
11423 				zone->curmaster++;
11424 			goto requeue;
11425 		}
11426 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11427 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
11428 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
11429 			zone->refreshtime = now;
11430 		}
11431 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11432 		zone_settimer(zone, &now);
11433 		goto detach;
11434 	}
11435 
11436  requeue:
11437 	queue_soa_query(zone);
11438 	goto detach;
11439 
11440  same_master:
11441 	if (msg != NULL)
11442 		dns_message_destroy(&msg);
11443 	isc_event_free(&event);
11444 	dns_request_destroy(&zone->request);
11445 	queue_soa_query(zone);
11446 
11447  detach:
11448 	UNLOCK_ZONE(zone);
11449 	if (do_queue_xfrin)
11450 		queue_xfrin(zone);
11451 	dns_zone_idetach(&zone);
11452 	return;
11453 }
11454 
11455 static void
queue_soa_query(dns_zone_t * zone)11456 queue_soa_query(dns_zone_t *zone) {
11457 	const char me[] = "queue_soa_query";
11458 	isc_event_t *e;
11459 	dns_zone_t *dummy = NULL;
11460 	isc_result_t result;
11461 
11462 	ENTER;
11463 	/*
11464 	 * Locked by caller
11465 	 */
11466 	REQUIRE(LOCKED_ZONE(zone));
11467 
11468 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
11469 		cancel_refresh(zone);
11470 		return;
11471 	}
11472 
11473 	e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
11474 			       soa_query, zone, sizeof(isc_event_t));
11475 	if (e == NULL) {
11476 		cancel_refresh(zone);
11477 		return;
11478 	}
11479 
11480 	/*
11481 	 * Attach so that we won't clean up
11482 	 * until the event is delivered.
11483 	 */
11484 	zone_iattach(zone, &dummy);
11485 
11486 	e->ev_arg = zone;
11487 	e->ev_sender = NULL;
11488 	result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e);
11489 	if (result != ISC_R_SUCCESS) {
11490 		zone_idetach(&dummy);
11491 		isc_event_free(&e);
11492 		cancel_refresh(zone);
11493 	}
11494 }
11495 
11496 static inline isc_result_t
create_query(dns_zone_t * zone,dns_rdatatype_t rdtype,dns_message_t ** messagep)11497 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
11498 	     dns_message_t **messagep)
11499 {
11500 	dns_message_t *message = NULL;
11501 	dns_name_t *qname = NULL;
11502 	dns_rdataset_t *qrdataset = NULL;
11503 	isc_result_t result;
11504 
11505 	result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
11506 				    &message);
11507 	if (result != ISC_R_SUCCESS)
11508 		goto cleanup;
11509 
11510 	message->opcode = dns_opcode_query;
11511 	message->rdclass = zone->rdclass;
11512 
11513 	result = dns_message_gettempname(message, &qname);
11514 	if (result != ISC_R_SUCCESS)
11515 		goto cleanup;
11516 
11517 	result = dns_message_gettemprdataset(message, &qrdataset);
11518 	if (result != ISC_R_SUCCESS)
11519 		goto cleanup;
11520 
11521 	/*
11522 	 * Make question.
11523 	 */
11524 	dns_name_init(qname, NULL);
11525 	dns_name_clone(&zone->origin, qname);
11526 	dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
11527 	ISC_LIST_APPEND(qname->list, qrdataset, link);
11528 	dns_message_addname(message, qname, DNS_SECTION_QUESTION);
11529 
11530 	*messagep = message;
11531 	return (ISC_R_SUCCESS);
11532 
11533  cleanup:
11534 	if (qname != NULL)
11535 		dns_message_puttempname(message, &qname);
11536 	if (qrdataset != NULL)
11537 		dns_message_puttemprdataset(message, &qrdataset);
11538 	if (message != NULL)
11539 		dns_message_destroy(&message);
11540 	return (result);
11541 }
11542 
11543 static isc_result_t
add_opt(dns_message_t * message,isc_uint16_t udpsize,isc_boolean_t reqnsid)11544 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
11545 	isc_result_t result;
11546 	dns_rdataset_t *rdataset = NULL;
11547 	dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
11548 	int count = 0;
11549 
11550 	/* Set EDNS options if applicable */
11551 	if (reqnsid) {
11552 		INSIST(count < DNS_EDNSOPTIONS);
11553 		ednsopts[count].code = DNS_OPT_NSID;
11554 		ednsopts[count].length = 0;
11555 		ednsopts[count].value = NULL;
11556 		count++;
11557 	}
11558 	result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0,
11559 				      ednsopts, count);
11560 	if (result != ISC_R_SUCCESS)
11561 		return (result);
11562 
11563 	return (dns_message_setopt(message, rdataset));
11564 }
11565 
11566 static void
soa_query(isc_task_t * task,isc_event_t * event)11567 soa_query(isc_task_t *task, isc_event_t *event) {
11568 	const char me[] = "soa_query";
11569 	isc_result_t result = ISC_R_FAILURE;
11570 	dns_message_t *message = NULL;
11571 	dns_zone_t *zone = event->ev_arg;
11572 	dns_zone_t *dummy = NULL;
11573 	isc_netaddr_t masterip;
11574 	dns_tsigkey_t *key = NULL;
11575 	isc_uint32_t options;
11576 	isc_boolean_t cancel = ISC_TRUE;
11577 	int timeout;
11578 	isc_boolean_t have_xfrsource, have_xfrdscp, reqnsid;
11579 	isc_uint16_t udpsize = SEND_BUFFER_SIZE;
11580 	isc_dscp_t dscp = -1;
11581 
11582 	REQUIRE(DNS_ZONE_VALID(zone));
11583 
11584 	UNUSED(task);
11585 
11586 	ENTER;
11587 
11588 	LOCK_ZONE(zone);
11589 	if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
11590 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
11591 	    zone->view->requestmgr == NULL) {
11592 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
11593 			cancel = ISC_FALSE;
11594 		goto cleanup;
11595 	}
11596 
11597  again:
11598 	result = create_query(zone, dns_rdatatype_soa, &message);
11599 	if (result != ISC_R_SUCCESS)
11600 		goto cleanup;
11601 
11602 	INSIST(zone->masterscnt > 0);
11603 	INSIST(zone->curmaster < zone->masterscnt);
11604 
11605 	zone->masteraddr = zone->masters[zone->curmaster];
11606 
11607 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
11608 	/*
11609 	 * First, look for a tsig key in the master statement, then
11610 	 * try for a server key.
11611 	 */
11612 	if ((zone->masterkeynames != NULL) &&
11613 	    (zone->masterkeynames[zone->curmaster] != NULL)) {
11614 		dns_view_t *view = dns_zone_getview(zone);
11615 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
11616 		result = dns_view_gettsig(view, keyname, &key);
11617 		if (result != ISC_R_SUCCESS) {
11618 			char namebuf[DNS_NAME_FORMATSIZE];
11619 			dns_name_format(keyname, namebuf, sizeof(namebuf));
11620 			dns_zone_log(zone, ISC_LOG_ERROR,
11621 				     "unable to find key: %s", namebuf);
11622 			goto skip_master;
11623 		}
11624 	}
11625 	if (key == NULL) {
11626 		result = dns_view_getpeertsig(zone->view, &masterip, &key);
11627 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
11628 			char addrbuf[ISC_NETADDR_FORMATSIZE];
11629 			isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
11630 			dns_zone_log(zone, ISC_LOG_ERROR,
11631 				     "unable to find TSIG key for %s", addrbuf);
11632 			goto skip_master;
11633 		}
11634 	}
11635 
11636 	have_xfrsource = have_xfrdscp = ISC_FALSE;
11637 	reqnsid = zone->view->requestnsid;
11638 	if (zone->view->peers != NULL) {
11639 		dns_peer_t *peer = NULL;
11640 		isc_boolean_t edns;
11641 		result = dns_peerlist_peerbyaddr(zone->view->peers,
11642 						 &masterip, &peer);
11643 		if (result == ISC_R_SUCCESS) {
11644 			result = dns_peer_getsupportedns(peer, &edns);
11645 			if (result == ISC_R_SUCCESS && !edns)
11646 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11647 			result = dns_peer_gettransfersource(peer,
11648 							    &zone->sourceaddr);
11649 			if (result == ISC_R_SUCCESS)
11650 				have_xfrsource = ISC_TRUE;
11651 			(void)dns_peer_gettransferdscp(peer, &dscp);
11652 			if (dscp != -1)
11653 				have_xfrdscp = ISC_TRUE;
11654 			if (zone->view->resolver != NULL)
11655 				udpsize =
11656 				  dns_resolver_getudpsize(zone->view->resolver);
11657 			(void)dns_peer_getudpsize(peer, &udpsize);
11658 			(void)dns_peer_getrequestnsid(peer, &reqnsid);
11659 		}
11660 	}
11661 
11662 	switch (isc_sockaddr_pf(&zone->masteraddr)) {
11663 	case PF_INET:
11664 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11665 			if (isc_sockaddr_equal(&zone->altxfrsource4,
11666 					       &zone->xfrsource4))
11667 				goto skip_master;
11668 			zone->sourceaddr = zone->altxfrsource4;
11669 			if (!have_xfrdscp)
11670 				dscp = zone->altxfrsource4dscp;
11671 		} else if (!have_xfrsource) {
11672 			zone->sourceaddr = zone->xfrsource4;
11673 			if (!have_xfrdscp)
11674 				dscp = zone->xfrsource4dscp;
11675 		}
11676 		break;
11677 	case PF_INET6:
11678 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11679 			if (isc_sockaddr_equal(&zone->altxfrsource6,
11680 					       &zone->xfrsource6))
11681 				goto skip_master;
11682 			zone->sourceaddr = zone->altxfrsource6;
11683 			if (!have_xfrdscp)
11684 				dscp = zone->altxfrsource6dscp;
11685 		} else if (!have_xfrsource) {
11686 			zone->sourceaddr = zone->xfrsource6;
11687 			if (!have_xfrdscp)
11688 				dscp = zone->xfrsource6dscp;
11689 		}
11690 		break;
11691 	default:
11692 		result = ISC_R_NOTIMPLEMENTED;
11693 		goto cleanup;
11694 	}
11695 
11696 	options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
11697 		  DNS_REQUESTOPT_TCP : 0;
11698 
11699 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
11700 		result = add_opt(message, udpsize, reqnsid);
11701 		if (result != ISC_R_SUCCESS)
11702 			zone_debuglog(zone, me, 1,
11703 				      "unable to add opt record: %s",
11704 				      dns_result_totext(result));
11705 	}
11706 
11707 	zone_iattach(zone, &dummy);
11708 	timeout = 15;
11709 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11710 		timeout = 30;
11711 	result = dns_request_createvia4(zone->view->requestmgr, message,
11712 					&zone->sourceaddr, &zone->masteraddr,
11713 					dscp, options, key, timeout * 3,
11714 					timeout, 0, zone->task,
11715 					refresh_callback, zone, &zone->request);
11716 	if (result != ISC_R_SUCCESS) {
11717 		zone_idetach(&dummy);
11718 		zone_debuglog(zone, me, 1,
11719 			      "dns_request_createvia4() failed: %s",
11720 			      dns_result_totext(result));
11721 		goto skip_master;
11722 	} else {
11723 		if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
11724 			inc_stats(zone, dns_zonestatscounter_soaoutv4);
11725 		else
11726 			inc_stats(zone, dns_zonestatscounter_soaoutv6);
11727 	}
11728 	cancel = ISC_FALSE;
11729 
11730  cleanup:
11731 	if (key != NULL)
11732 		dns_tsigkey_detach(&key);
11733 	if (result != ISC_R_SUCCESS)
11734 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11735 	if (message != NULL)
11736 		dns_message_destroy(&message);
11737 	if (cancel)
11738 		cancel_refresh(zone);
11739 	isc_event_free(&event);
11740 	UNLOCK_ZONE(zone);
11741 	dns_zone_idetach(&zone);
11742 	return;
11743 
11744  skip_master:
11745 	if (key != NULL)
11746 		dns_tsigkey_detach(&key);
11747 	dns_message_destroy(&message);
11748 	/*
11749 	 * Skip to next failed / untried master.
11750 	 */
11751 	do {
11752 		zone->curmaster++;
11753 	} while (zone->curmaster < zone->masterscnt &&
11754 		 zone->mastersok[zone->curmaster]);
11755 	if (zone->curmaster < zone->masterscnt)
11756 		goto again;
11757 	zone->curmaster = 0;
11758 	goto cleanup;
11759 }
11760 
11761 static void
ns_query(dns_zone_t * zone,dns_rdataset_t * soardataset,dns_stub_t * stub)11762 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
11763 	const char me[] = "ns_query";
11764 	isc_result_t result;
11765 	dns_message_t *message = NULL;
11766 	isc_netaddr_t masterip;
11767 	dns_tsigkey_t *key = NULL;
11768 	dns_dbnode_t *node = NULL;
11769 	int timeout;
11770 	isc_boolean_t have_xfrsource = ISC_FALSE, have_xfrdscp = ISC_FALSE;
11771 	isc_boolean_t reqnsid;
11772 	isc_uint16_t udpsize = SEND_BUFFER_SIZE;
11773 	isc_dscp_t dscp = -1;
11774 
11775 	REQUIRE(DNS_ZONE_VALID(zone));
11776 	REQUIRE(LOCKED_ZONE(zone));
11777 	REQUIRE((soardataset != NULL && stub == NULL) ||
11778 		(soardataset == NULL && stub != NULL));
11779 	REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
11780 
11781 	ENTER;
11782 
11783 	if (stub == NULL) {
11784 		stub = isc_mem_get(zone->mctx, sizeof(*stub));
11785 		if (stub == NULL)
11786 			goto cleanup;
11787 		stub->magic = STUB_MAGIC;
11788 		stub->mctx = zone->mctx;
11789 		stub->zone = NULL;
11790 		stub->db = NULL;
11791 		stub->version = NULL;
11792 
11793 		/*
11794 		 * Attach so that the zone won't disappear from under us.
11795 		 */
11796 		zone_iattach(zone, &stub->zone);
11797 
11798 		/*
11799 		 * If a db exists we will update it, otherwise we create a
11800 		 * new one and attach it to the zone once we have the NS
11801 		 * RRset and glue.
11802 		 */
11803 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11804 		if (zone->db != NULL) {
11805 			dns_db_attach(zone->db, &stub->db);
11806 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11807 		} else {
11808 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11809 
11810 			INSIST(zone->db_argc >= 1);
11811 			result = dns_db_create(zone->mctx, zone->db_argv[0],
11812 					       &zone->origin, dns_dbtype_stub,
11813 					       zone->rdclass,
11814 					       zone->db_argc - 1,
11815 					       zone->db_argv + 1,
11816 					       &stub->db);
11817 			if (result != ISC_R_SUCCESS) {
11818 				dns_zone_log(zone, ISC_LOG_ERROR,
11819 					     "refreshing stub: "
11820 					     "could not create "
11821 					     "database: %s",
11822 					     dns_result_totext(result));
11823 				goto cleanup;
11824 			}
11825 			dns_db_settask(stub->db, zone->task);
11826 		}
11827 
11828 		result = dns_db_newversion(stub->db, &stub->version);
11829 		if (result != ISC_R_SUCCESS) {
11830 			dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
11831 				     "dns_db_newversion() failed: %s",
11832 				     dns_result_totext(result));
11833 			goto cleanup;
11834 		}
11835 
11836 		/*
11837 		 * Update SOA record.
11838 		 */
11839 		result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
11840 					 &node);
11841 		if (result != ISC_R_SUCCESS) {
11842 			dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
11843 				     "dns_db_findnode() failed: %s",
11844 				     dns_result_totext(result));
11845 			goto cleanup;
11846 		}
11847 
11848 		result = dns_db_addrdataset(stub->db, node, stub->version, 0,
11849 					    soardataset, 0, NULL);
11850 		dns_db_detachnode(stub->db, &node);
11851 		if (result != ISC_R_SUCCESS) {
11852 			dns_zone_log(zone, ISC_LOG_INFO,
11853 				     "refreshing stub: "
11854 				     "dns_db_addrdataset() failed: %s",
11855 				     dns_result_totext(result));
11856 			goto cleanup;
11857 		}
11858 	}
11859 
11860 	/*
11861 	 * XXX Optimisation: Create message when zone is setup and reuse.
11862 	 */
11863 	result = create_query(zone, dns_rdatatype_ns, &message);
11864 	INSIST(result == ISC_R_SUCCESS);
11865 
11866 	INSIST(zone->masterscnt > 0);
11867 	INSIST(zone->curmaster < zone->masterscnt);
11868 	zone->masteraddr = zone->masters[zone->curmaster];
11869 
11870 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
11871 	/*
11872 	 * First, look for a tsig key in the master statement, then
11873 	 * try for a server key.
11874 	 */
11875 	if ((zone->masterkeynames != NULL) &&
11876 	    (zone->masterkeynames[zone->curmaster] != NULL)) {
11877 		dns_view_t *view = dns_zone_getview(zone);
11878 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
11879 		result = dns_view_gettsig(view, keyname, &key);
11880 		if (result != ISC_R_SUCCESS) {
11881 			char namebuf[DNS_NAME_FORMATSIZE];
11882 			dns_name_format(keyname, namebuf, sizeof(namebuf));
11883 			dns_zone_log(zone, ISC_LOG_ERROR,
11884 				     "unable to find key: %s", namebuf);
11885 		}
11886 	}
11887 	if (key == NULL)
11888 		(void)dns_view_getpeertsig(zone->view, &masterip, &key);
11889 
11890 	reqnsid = zone->view->requestnsid;
11891 	if (zone->view->peers != NULL) {
11892 		dns_peer_t *peer = NULL;
11893 		isc_boolean_t edns;
11894 		result = dns_peerlist_peerbyaddr(zone->view->peers,
11895 						 &masterip, &peer);
11896 		if (result == ISC_R_SUCCESS) {
11897 			result = dns_peer_getsupportedns(peer, &edns);
11898 			if (result == ISC_R_SUCCESS && !edns)
11899 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11900 			result = dns_peer_gettransfersource(peer,
11901 							    &zone->sourceaddr);
11902 			if (result == ISC_R_SUCCESS)
11903 				have_xfrsource = ISC_TRUE;
11904 			result = dns_peer_gettransferdscp(peer, &dscp);
11905 			if (result == ISC_R_SUCCESS && dscp != -1)
11906 				have_xfrdscp = ISC_TRUE;
11907 			if (zone->view->resolver != NULL)
11908 				udpsize =
11909 				  dns_resolver_getudpsize(zone->view->resolver);
11910 			(void)dns_peer_getudpsize(peer, &udpsize);
11911 			(void)dns_peer_getrequestnsid(peer, &reqnsid);
11912 		}
11913 
11914 	}
11915 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
11916 		result = add_opt(message, udpsize, reqnsid);
11917 		if (result != ISC_R_SUCCESS)
11918 			zone_debuglog(zone, me, 1,
11919 				      "unable to add opt record: %s",
11920 				      dns_result_totext(result));
11921 	}
11922 
11923 	/*
11924 	 * Always use TCP so that we shouldn't truncate in additional section.
11925 	 */
11926 	switch (isc_sockaddr_pf(&zone->masteraddr)) {
11927 	case PF_INET:
11928 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11929 			zone->sourceaddr = zone->altxfrsource4;
11930 			if (!have_xfrdscp)
11931 				dscp = zone->altxfrsource4dscp;
11932 		} else if (!have_xfrsource) {
11933 			zone->sourceaddr = zone->xfrsource4;
11934 			if (!have_xfrdscp)
11935 				dscp = zone->xfrsource4dscp;
11936 		}
11937 		break;
11938 	case PF_INET6:
11939 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11940 			zone->sourceaddr = zone->altxfrsource6;
11941 			if (!have_xfrdscp)
11942 				dscp = zone->altxfrsource6dscp;
11943 		} else if (!have_xfrsource) {
11944 			zone->sourceaddr = zone->xfrsource6;
11945 			if (!have_xfrdscp)
11946 				dscp = zone->xfrsource6dscp;
11947 		}
11948 		break;
11949 	default:
11950 		result = ISC_R_NOTIMPLEMENTED;
11951 		POST(result);
11952 		goto cleanup;
11953 	}
11954 	timeout = 15;
11955 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
11956 		timeout = 30;
11957 	result = dns_request_createvia4(zone->view->requestmgr, message,
11958 					&zone->sourceaddr, &zone->masteraddr,
11959 					dscp, DNS_REQUESTOPT_TCP, key,
11960 					timeout * 3, timeout, 0, zone->task,
11961 					stub_callback, stub, &zone->request);
11962 	if (result != ISC_R_SUCCESS) {
11963 		zone_debuglog(zone, me, 1,
11964 			      "dns_request_createvia() failed: %s",
11965 			      dns_result_totext(result));
11966 		goto cleanup;
11967 	}
11968 	dns_message_destroy(&message);
11969 	goto unlock;
11970 
11971  cleanup:
11972 	cancel_refresh(zone);
11973 	if (stub != NULL) {
11974 		stub->magic = 0;
11975 		if (stub->version != NULL)
11976 			dns_db_closeversion(stub->db, &stub->version,
11977 					    ISC_FALSE);
11978 		if (stub->db != NULL)
11979 			dns_db_detach(&stub->db);
11980 		if (stub->zone != NULL)
11981 			zone_idetach(&stub->zone);
11982 		isc_mem_put(stub->mctx, stub, sizeof(*stub));
11983 	}
11984 	if (message != NULL)
11985 		dns_message_destroy(&message);
11986  unlock:
11987 	if (key != NULL)
11988 		dns_tsigkey_detach(&key);
11989 	return;
11990 }
11991 
11992 /*
11993  * Handle the control event.  Note that although this event causes the zone
11994  * to shut down, it is not a shutdown event in the sense of the task library.
11995  */
11996 static void
zone_shutdown(isc_task_t * task,isc_event_t * event)11997 zone_shutdown(isc_task_t *task, isc_event_t *event) {
11998 	dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
11999 	isc_boolean_t free_needed, linked = ISC_FALSE;
12000 	dns_zone_t *raw = NULL, *secure = NULL;
12001 
12002 	UNUSED(task);
12003 	REQUIRE(DNS_ZONE_VALID(zone));
12004 	INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
12005 	INSIST(isc_refcount_current(&zone->erefs) == 0);
12006 
12007 	zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
12008 
12009 	/*
12010 	 * Stop things being restarted after we cancel them below.
12011 	 */
12012 	LOCK_ZONE(zone);
12013 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
12014 	UNLOCK_ZONE(zone);
12015 
12016 	/*
12017 	 * If we were waiting for xfrin quota, step out of
12018 	 * the queue.
12019 	 * If there's no zone manager, we can't be waiting for the
12020 	 * xfrin quota
12021 	 */
12022 	if (zone->zmgr != NULL) {
12023 		RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
12024 		if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
12025 			ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
12026 					statelink);
12027 			linked = ISC_TRUE;
12028 			zone->statelist = NULL;
12029 		}
12030 		if (zone->statelist == &zone->zmgr->xfrin_in_progress) {
12031 			ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone,
12032 					statelink);
12033 			zone->statelist = NULL;
12034 			zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
12035 		}
12036 		RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
12037 	}
12038 
12039 	/*
12040 	 * In task context, no locking required.  See zone_xfrdone().
12041 	 */
12042 	if (zone->xfr != NULL)
12043 		dns_xfrin_shutdown(zone->xfr);
12044 
12045 	/* Safe to release the zone now */
12046 	if (zone->zmgr != NULL)
12047 		dns_zonemgr_releasezone(zone->zmgr, zone);
12048 
12049 	LOCK_ZONE(zone);
12050 	INSIST(zone != zone->raw);
12051 	if (linked) {
12052 		INSIST(zone->irefs > 0);
12053 		zone->irefs--;
12054 	}
12055 	if (zone->request != NULL) {
12056 		dns_request_cancel(zone->request);
12057 	}
12058 
12059 	if (zone->readio != NULL)
12060 		zonemgr_cancelio(zone->readio);
12061 
12062 	if (zone->lctx != NULL)
12063 		dns_loadctx_cancel(zone->lctx);
12064 
12065 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
12066 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
12067 		if (zone->writeio != NULL)
12068 			zonemgr_cancelio(zone->writeio);
12069 
12070 		if (zone->dctx != NULL)
12071 			dns_dumpctx_cancel(zone->dctx);
12072 	}
12073 
12074 	notify_cancel(zone);
12075 
12076 	forward_cancel(zone);
12077 
12078 	if (zone->timer != NULL) {
12079 		isc_timer_detach(&zone->timer);
12080 		INSIST(zone->irefs > 0);
12081 		zone->irefs--;
12082 	}
12083 
12084 	if (zone->view != NULL)
12085 		dns_view_weakdetach(&zone->view);
12086 
12087 	/*
12088 	 * We have now canceled everything set the flag to allow exit_check()
12089 	 * to succeed.	We must not unlock between setting this flag and
12090 	 * calling exit_check().
12091 	 */
12092 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
12093 	free_needed = exit_check(zone);
12094 	if (inline_secure(zone)) {
12095 		raw = zone->raw;
12096 		zone->raw = NULL;
12097 	}
12098 	if (inline_raw(zone)) {
12099 		secure = zone->secure;
12100 		zone->secure = NULL;
12101 	}
12102 	UNLOCK_ZONE(zone);
12103 	if (raw != NULL)
12104 		dns_zone_detach(&raw);
12105 	if (secure != NULL)
12106 		dns_zone_idetach(&secure);
12107 	if (free_needed)
12108 		zone_free(zone);
12109 }
12110 
12111 static void
zone_timer(isc_task_t * task,isc_event_t * event)12112 zone_timer(isc_task_t *task, isc_event_t *event) {
12113 	const char me[] = "zone_timer";
12114 	dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
12115 
12116 	UNUSED(task);
12117 	REQUIRE(DNS_ZONE_VALID(zone));
12118 
12119 	ENTER;
12120 
12121 	zone_maintenance(zone);
12122 
12123 	isc_event_free(&event);
12124 }
12125 
12126 static void
zone_settimer(dns_zone_t * zone,isc_time_t * now)12127 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
12128 	const char me[] = "zone_settimer";
12129 	isc_time_t next;
12130 	isc_result_t result;
12131 
12132 	REQUIRE(DNS_ZONE_VALID(zone));
12133 	ENTER;
12134 
12135 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
12136 		return;
12137 
12138 	isc_time_settoepoch(&next);
12139 
12140 	switch (zone->type) {
12141 	case dns_zone_redirect:
12142 		if (zone->masters != NULL)
12143 			goto treat_as_slave;
12144 		/* FALLTHROUGH */
12145 
12146 	case dns_zone_master:
12147 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
12148 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
12149 			next = zone->notifytime;
12150 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
12151 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
12152 			INSIST(!isc_time_isepoch(&zone->dumptime));
12153 			if (isc_time_isepoch(&next) ||
12154 			    isc_time_compare(&zone->dumptime, &next) < 0)
12155 				next = zone->dumptime;
12156 		}
12157 		if (zone->type == dns_zone_redirect)
12158 			break;
12159 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
12160 		    !isc_time_isepoch(&zone->refreshkeytime)) {
12161 			if (isc_time_isepoch(&next) ||
12162 			    isc_time_compare(&zone->refreshkeytime, &next) < 0)
12163 				next = zone->refreshkeytime;
12164 		}
12165 		if (!isc_time_isepoch(&zone->resigntime)) {
12166 			if (isc_time_isepoch(&next) ||
12167 			    isc_time_compare(&zone->resigntime, &next) < 0)
12168 				next = zone->resigntime;
12169 		}
12170 		if (!isc_time_isepoch(&zone->keywarntime)) {
12171 			if (isc_time_isepoch(&next) ||
12172 			    isc_time_compare(&zone->keywarntime, &next) < 0)
12173 				next = zone->keywarntime;
12174 		}
12175 		if (!isc_time_isepoch(&zone->signingtime)) {
12176 			if (isc_time_isepoch(&next) ||
12177 			    isc_time_compare(&zone->signingtime, &next) < 0)
12178 				next = zone->signingtime;
12179 		}
12180 		if (!isc_time_isepoch(&zone->nsec3chaintime)) {
12181 			if (isc_time_isepoch(&next) ||
12182 			    isc_time_compare(&zone->nsec3chaintime, &next) < 0)
12183 				next = zone->nsec3chaintime;
12184 		}
12185 		break;
12186 
12187 	case dns_zone_slave:
12188 	treat_as_slave:
12189 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
12190 			next = zone->notifytime;
12191 		/* FALLTHROUGH */
12192 
12193 	case dns_zone_stub:
12194 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
12195 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
12196 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
12197 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) &&
12198 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) &&
12199 		    !isc_time_isepoch(&zone->refreshtime) &&
12200 		    (isc_time_isepoch(&next) ||
12201 		     isc_time_compare(&zone->refreshtime, &next) < 0))
12202 			next = zone->refreshtime;
12203 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
12204 		    !isc_time_isepoch(&zone->expiretime)) {
12205 			if (isc_time_isepoch(&next) ||
12206 			     isc_time_compare(&zone->expiretime, &next) < 0)
12207 				next = zone->expiretime;
12208 		}
12209 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
12210 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
12211 			INSIST(!isc_time_isepoch(&zone->dumptime));
12212 			if (isc_time_isepoch(&next) ||
12213 			    isc_time_compare(&zone->dumptime, &next) < 0)
12214 				next = zone->dumptime;
12215 		}
12216 		break;
12217 
12218 	case dns_zone_key:
12219 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
12220 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
12221 			INSIST(!isc_time_isepoch(&zone->dumptime));
12222 			if (isc_time_isepoch(&next) ||
12223 			    isc_time_compare(&zone->dumptime, &next) < 0)
12224 				next = zone->dumptime;
12225 		}
12226 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
12227 			if (isc_time_isepoch(&next) ||
12228 			    (!isc_time_isepoch(&zone->refreshkeytime) &&
12229 			    isc_time_compare(&zone->refreshkeytime, &next) < 0))
12230 				next = zone->refreshkeytime;
12231 		}
12232 		break;
12233 
12234 	default:
12235 		break;
12236 	}
12237 
12238 	if (isc_time_isepoch(&next)) {
12239 		zone_debuglog(zone, me, 10, "settimer inactive");
12240 		result = isc_timer_reset(zone->timer, isc_timertype_inactive,
12241 					  NULL, NULL, ISC_TRUE);
12242 		if (result != ISC_R_SUCCESS)
12243 			dns_zone_log(zone, ISC_LOG_ERROR,
12244 				     "could not deactivate zone timer: %s",
12245 				     isc_result_totext(result));
12246 	} else {
12247 		if (isc_time_compare(&next, now) <= 0)
12248 			next = *now;
12249 		result = isc_timer_reset(zone->timer, isc_timertype_once,
12250 					 &next, NULL, ISC_TRUE);
12251 		if (result != ISC_R_SUCCESS)
12252 			dns_zone_log(zone, ISC_LOG_ERROR,
12253 				     "could not reset zone timer: %s",
12254 				     isc_result_totext(result));
12255 	}
12256 }
12257 
12258 static void
cancel_refresh(dns_zone_t * zone)12259 cancel_refresh(dns_zone_t *zone) {
12260 	const char me[] = "cancel_refresh";
12261 	isc_time_t now;
12262 
12263 	/*
12264 	 * 'zone' locked by caller.
12265 	 */
12266 
12267 	REQUIRE(DNS_ZONE_VALID(zone));
12268 	REQUIRE(LOCKED_ZONE(zone));
12269 
12270 	ENTER;
12271 
12272 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
12273 	TIME_NOW(&now);
12274 	zone_settimer(zone, &now);
12275 }
12276 
12277 static isc_result_t
notify_createmessage(dns_zone_t * zone,unsigned int flags,dns_message_t ** messagep)12278 notify_createmessage(dns_zone_t *zone, unsigned int flags,
12279 		     dns_message_t **messagep)
12280 {
12281 	dns_db_t *zonedb = NULL;
12282 	dns_dbnode_t *node = NULL;
12283 	dns_dbversion_t *version = NULL;
12284 	dns_message_t *message = NULL;
12285 	dns_rdataset_t rdataset;
12286 	dns_rdata_t rdata = DNS_RDATA_INIT;
12287 
12288 	dns_name_t *tempname = NULL;
12289 	dns_rdata_t *temprdata = NULL;
12290 	dns_rdatalist_t *temprdatalist = NULL;
12291 	dns_rdataset_t *temprdataset = NULL;
12292 
12293 	isc_result_t result;
12294 	isc_region_t r;
12295 	isc_buffer_t *b = NULL;
12296 
12297 	REQUIRE(DNS_ZONE_VALID(zone));
12298 	REQUIRE(messagep != NULL && *messagep == NULL);
12299 
12300 	result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
12301 				    &message);
12302 	if (result != ISC_R_SUCCESS)
12303 		return (result);
12304 
12305 	message->opcode = dns_opcode_notify;
12306 	message->flags |= DNS_MESSAGEFLAG_AA;
12307 	message->rdclass = zone->rdclass;
12308 
12309 	result = dns_message_gettempname(message, &tempname);
12310 	if (result != ISC_R_SUCCESS)
12311 		goto cleanup;
12312 
12313 	result = dns_message_gettemprdataset(message, &temprdataset);
12314 	if (result != ISC_R_SUCCESS)
12315 		goto cleanup;
12316 
12317 	/*
12318 	 * Make question.
12319 	 */
12320 	dns_name_init(tempname, NULL);
12321 	dns_name_clone(&zone->origin, tempname);
12322 	dns_rdataset_makequestion(temprdataset, zone->rdclass,
12323 				  dns_rdatatype_soa);
12324 	ISC_LIST_APPEND(tempname->list, temprdataset, link);
12325 	dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
12326 	tempname = NULL;
12327 	temprdataset = NULL;
12328 
12329 	if ((flags & DNS_NOTIFY_NOSOA) != 0)
12330 		goto done;
12331 
12332 	result = dns_message_gettempname(message, &tempname);
12333 	if (result != ISC_R_SUCCESS)
12334 		goto soa_cleanup;
12335 	result = dns_message_gettemprdata(message, &temprdata);
12336 	if (result != ISC_R_SUCCESS)
12337 		goto soa_cleanup;
12338 	result = dns_message_gettemprdataset(message, &temprdataset);
12339 	if (result != ISC_R_SUCCESS)
12340 		goto soa_cleanup;
12341 	result = dns_message_gettemprdatalist(message, &temprdatalist);
12342 	if (result != ISC_R_SUCCESS)
12343 		goto soa_cleanup;
12344 
12345 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
12346 	INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
12347 	dns_db_attach(zone->db, &zonedb);
12348 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
12349 
12350 	dns_name_init(tempname, NULL);
12351 	dns_name_clone(&zone->origin, tempname);
12352 	dns_db_currentversion(zonedb, &version);
12353 	result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
12354 	if (result != ISC_R_SUCCESS)
12355 		goto soa_cleanup;
12356 
12357 	dns_rdataset_init(&rdataset);
12358 	result = dns_db_findrdataset(zonedb, node, version,
12359 				     dns_rdatatype_soa,
12360 				     dns_rdatatype_none, 0, &rdataset,
12361 				     NULL);
12362 	if (result != ISC_R_SUCCESS)
12363 		goto soa_cleanup;
12364 	result = dns_rdataset_first(&rdataset);
12365 	if (result != ISC_R_SUCCESS)
12366 		goto soa_cleanup;
12367 	dns_rdataset_current(&rdataset, &rdata);
12368 	dns_rdata_toregion(&rdata, &r);
12369 	result = isc_buffer_allocate(zone->mctx, &b, r.length);
12370 	if (result != ISC_R_SUCCESS)
12371 		goto soa_cleanup;
12372 	isc_buffer_putmem(b, r.base, r.length);
12373 	isc_buffer_usedregion(b, &r);
12374 	dns_rdata_init(temprdata);
12375 	dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
12376 	dns_message_takebuffer(message, &b);
12377 	result = dns_rdataset_next(&rdataset);
12378 	dns_rdataset_disassociate(&rdataset);
12379 	if (result != ISC_R_NOMORE)
12380 		goto soa_cleanup;
12381 	temprdatalist->rdclass = rdata.rdclass;
12382 	temprdatalist->type = rdata.type;
12383 	temprdatalist->covers = 0;
12384 	temprdatalist->ttl = rdataset.ttl;
12385 	ISC_LIST_INIT(temprdatalist->rdata);
12386 	ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
12387 
12388 	result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
12389 	if (result != ISC_R_SUCCESS)
12390 		goto soa_cleanup;
12391 
12392 	ISC_LIST_APPEND(tempname->list, temprdataset, link);
12393 	dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
12394 	temprdatalist = NULL;
12395 	temprdataset = NULL;
12396 	temprdata = NULL;
12397 	tempname = NULL;
12398 
12399  soa_cleanup:
12400 	if (node != NULL)
12401 		dns_db_detachnode(zonedb, &node);
12402 	if (version != NULL)
12403 		dns_db_closeversion(zonedb, &version, ISC_FALSE);
12404 	if (zonedb != NULL)
12405 		dns_db_detach(&zonedb);
12406 	if (tempname != NULL)
12407 		dns_message_puttempname(message, &tempname);
12408 	if (temprdata != NULL)
12409 		dns_message_puttemprdata(message, &temprdata);
12410 	if (temprdataset != NULL)
12411 		dns_message_puttemprdataset(message, &temprdataset);
12412 	if (temprdatalist != NULL)
12413 		dns_message_puttemprdatalist(message, &temprdatalist);
12414 
12415  done:
12416 	*messagep = message;
12417 	return (ISC_R_SUCCESS);
12418 
12419  cleanup:
12420 	if (tempname != NULL)
12421 		dns_message_puttempname(message, &tempname);
12422 	if (temprdataset != NULL)
12423 		dns_message_puttemprdataset(message, &temprdataset);
12424 	dns_message_destroy(&message);
12425 	return (result);
12426 }
12427 
12428 isc_result_t
dns_zone_notifyreceive(dns_zone_t * zone,isc_sockaddr_t * from,dns_message_t * msg)12429 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
12430 		       dns_message_t *msg)
12431 {
12432 	unsigned int i;
12433 	dns_rdata_soa_t soa;
12434 	dns_rdataset_t *rdataset = NULL;
12435 	dns_rdata_t rdata = DNS_RDATA_INIT;
12436 	isc_result_t result;
12437 	char fromtext[ISC_SOCKADDR_FORMATSIZE];
12438 	int match = 0;
12439 	isc_netaddr_t netaddr;
12440 	isc_sockaddr_t local, remote;
12441 	isc_uint32_t serial = 0;
12442 	isc_boolean_t have_serial = ISC_FALSE;
12443 	dns_tsigkey_t *tsigkey;
12444 	dns_name_t *tsig;
12445 
12446 	REQUIRE(DNS_ZONE_VALID(zone));
12447 
12448 	/*
12449 	 * If type != T_SOA return DNS_R_NOTIMP.  We don't yet support
12450 	 * ROLLOVER.
12451 	 *
12452 	 * SOA:	RFC1996
12453 	 * Check that 'from' is a valid notify source, (zone->masters).
12454 	 *	Return DNS_R_REFUSED if not.
12455 	 *
12456 	 * If the notify message contains a serial number check it
12457 	 * against the zones serial and return if <= current serial
12458 	 *
12459 	 * If a refresh check is progress, if so just record the
12460 	 * fact we received a NOTIFY and from where and return.
12461 	 * We will perform a new refresh check when the current one
12462 	 * completes. Return ISC_R_SUCCESS.
12463 	 *
12464 	 * Otherwise initiate a refresh check using 'from' as the
12465 	 * first address to check.  Return ISC_R_SUCCESS.
12466 	 */
12467 
12468 	isc_sockaddr_format(from, fromtext, sizeof(fromtext));
12469 
12470 	/*
12471 	 * Notify messages are processed by the raw zone.
12472 	 */
12473 	LOCK_ZONE(zone);
12474 	INSIST(zone != zone->raw);
12475 	if (inline_secure(zone)) {
12476 		result = dns_zone_notifyreceive(zone->raw, from, msg);
12477 		UNLOCK_ZONE(zone);
12478 		return (result);
12479 	}
12480 	/*
12481 	 *  We only handle NOTIFY (SOA) at the present.
12482 	 */
12483 	if (isc_sockaddr_pf(from) == PF_INET)
12484 		inc_stats(zone, dns_zonestatscounter_notifyinv4);
12485 	else
12486 		inc_stats(zone, dns_zonestatscounter_notifyinv6);
12487 	if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
12488 	    dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
12489 				 dns_rdatatype_soa, dns_rdatatype_none,
12490 				 NULL, NULL) != ISC_R_SUCCESS) {
12491 		UNLOCK_ZONE(zone);
12492 		if (msg->counts[DNS_SECTION_QUESTION] == 0) {
12493 			dns_zone_log(zone, ISC_LOG_NOTICE,
12494 				     "NOTIFY with no "
12495 				     "question section from: %s", fromtext);
12496 			return (DNS_R_FORMERR);
12497 		}
12498 		dns_zone_log(zone, ISC_LOG_NOTICE,
12499 			     "NOTIFY zone does not match");
12500 		return (DNS_R_NOTIMP);
12501 	}
12502 
12503 	/*
12504 	 * If we are a master zone just succeed.
12505 	 */
12506 	if (zone->type == dns_zone_master) {
12507 		UNLOCK_ZONE(zone);
12508 		return (ISC_R_SUCCESS);
12509 	}
12510 
12511 	isc_netaddr_fromsockaddr(&netaddr, from);
12512 	for (i = 0; i < zone->masterscnt; i++) {
12513 		if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
12514 			break;
12515 		if (zone->view->aclenv.match_mapped &&
12516 		    IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
12517 		    isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
12518 			isc_netaddr_t na1, na2;
12519 			isc_netaddr_fromv4mapped(&na1, &netaddr);
12520 			isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
12521 			if (isc_netaddr_equal(&na1, &na2))
12522 				break;
12523 		}
12524 	}
12525 
12526 	/*
12527 	 * Accept notify requests from non masters if they are on
12528 	 * 'zone->notify_acl'.
12529 	 */
12530 	tsigkey = dns_message_gettsigkey(msg);
12531 	tsig = dns_tsigkey_identity(tsigkey);
12532 	if (i >= zone->masterscnt && zone->notify_acl != NULL &&
12533 	    dns_acl_match(&netaddr, tsig, zone->notify_acl,
12534 			  &zone->view->aclenv,
12535 			  &match, NULL) == ISC_R_SUCCESS &&
12536 	    match > 0)
12537 	{
12538 		/* Accept notify. */
12539 	} else if (i >= zone->masterscnt) {
12540 		UNLOCK_ZONE(zone);
12541 		dns_zone_log(zone, ISC_LOG_INFO,
12542 			     "refused notify from non-master: %s", fromtext);
12543 		inc_stats(zone, dns_zonestatscounter_notifyrej);
12544 		return (DNS_R_REFUSED);
12545 	}
12546 
12547 	/*
12548 	 * If the zone is loaded and there are answers check the serial
12549 	 * to see if we need to do a refresh.  Do not worry about this
12550 	 * check if we are a dialup zone as we use the notify request
12551 	 * to trigger a refresh check.
12552 	 */
12553 	if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
12554 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
12555 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
12556 		result = dns_message_findname(msg, DNS_SECTION_ANSWER,
12557 					      &zone->origin,
12558 					      dns_rdatatype_soa,
12559 					      dns_rdatatype_none, NULL,
12560 					      &rdataset);
12561 		if (result == ISC_R_SUCCESS)
12562 			result = dns_rdataset_first(rdataset);
12563 		if (result == ISC_R_SUCCESS) {
12564 			isc_uint32_t oldserial;
12565 			unsigned int soacount;
12566 
12567 			dns_rdataset_current(rdataset, &rdata);
12568 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
12569 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
12570 			serial = soa.serial;
12571 			have_serial = ISC_TRUE;
12572 			/*
12573 			 * The following should safely be performed without DB
12574 			 * lock and succeed in this context.
12575 			 */
12576 			result = zone_get_from_db(zone, zone->db, NULL,
12577 						  &soacount, &oldserial, NULL,
12578 						  NULL, NULL, NULL, NULL);
12579 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
12580 			RUNTIME_CHECK(soacount > 0U);
12581 			if (isc_serial_le(serial, oldserial)) {
12582 				dns_zone_log(zone,
12583 					     ISC_LOG_INFO,
12584 					     "notify from %s: "
12585 					     "zone is up to date",
12586 					     fromtext);
12587 				UNLOCK_ZONE(zone);
12588 				return (ISC_R_SUCCESS);
12589 			}
12590 		}
12591 	}
12592 
12593 	/*
12594 	 * If we got this far and there was a refresh in progress just
12595 	 * let it complete.  Record where we got the notify from so we
12596 	 * can perform a refresh check when the current one completes
12597 	 */
12598 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
12599 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
12600 		zone->notifyfrom = *from;
12601 		UNLOCK_ZONE(zone);
12602 		if (have_serial)
12603 			dns_zone_log(zone, ISC_LOG_INFO,
12604 				     "notify from %s: serial %u: refresh in "
12605 				     "progress, refresh check queued",
12606 				      fromtext, serial);
12607 		else
12608 			dns_zone_log(zone, ISC_LOG_INFO,
12609 				     "notify from %s: refresh in progress, "
12610 				     "refresh check queued", fromtext);
12611 		return (ISC_R_SUCCESS);
12612 	}
12613 	if (have_serial)
12614 		dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: serial %u",
12615 			     fromtext, serial);
12616 	else
12617 		dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: no serial",
12618 			     fromtext);
12619 	zone->notifyfrom = *from;
12620 	local = zone->masteraddr;
12621 	remote = zone->sourceaddr;
12622 	UNLOCK_ZONE(zone);
12623 	dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote);
12624 	dns_zone_refresh(zone);
12625 	return (ISC_R_SUCCESS);
12626 }
12627 
12628 void
dns_zone_setnotifyacl(dns_zone_t * zone,dns_acl_t * acl)12629 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
12630 
12631 	REQUIRE(DNS_ZONE_VALID(zone));
12632 
12633 	LOCK_ZONE(zone);
12634 	if (zone->notify_acl != NULL)
12635 		dns_acl_detach(&zone->notify_acl);
12636 	dns_acl_attach(acl, &zone->notify_acl);
12637 	UNLOCK_ZONE(zone);
12638 }
12639 
12640 void
dns_zone_setqueryacl(dns_zone_t * zone,dns_acl_t * acl)12641 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
12642 
12643 	REQUIRE(DNS_ZONE_VALID(zone));
12644 
12645 	LOCK_ZONE(zone);
12646 	if (zone->query_acl != NULL)
12647 		dns_acl_detach(&zone->query_acl);
12648 	dns_acl_attach(acl, &zone->query_acl);
12649 	UNLOCK_ZONE(zone);
12650 }
12651 
12652 void
dns_zone_setqueryonacl(dns_zone_t * zone,dns_acl_t * acl)12653 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
12654 
12655 	REQUIRE(DNS_ZONE_VALID(zone));
12656 
12657 	LOCK_ZONE(zone);
12658 	if (zone->queryon_acl != NULL)
12659 		dns_acl_detach(&zone->queryon_acl);
12660 	dns_acl_attach(acl, &zone->queryon_acl);
12661 	UNLOCK_ZONE(zone);
12662 }
12663 
12664 void
dns_zone_setupdateacl(dns_zone_t * zone,dns_acl_t * acl)12665 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
12666 
12667 	REQUIRE(DNS_ZONE_VALID(zone));
12668 
12669 	LOCK_ZONE(zone);
12670 	if (zone->update_acl != NULL)
12671 		dns_acl_detach(&zone->update_acl);
12672 	dns_acl_attach(acl, &zone->update_acl);
12673 	UNLOCK_ZONE(zone);
12674 }
12675 
12676 void
dns_zone_setforwardacl(dns_zone_t * zone,dns_acl_t * acl)12677 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
12678 
12679 	REQUIRE(DNS_ZONE_VALID(zone));
12680 
12681 	LOCK_ZONE(zone);
12682 	if (zone->forward_acl != NULL)
12683 		dns_acl_detach(&zone->forward_acl);
12684 	dns_acl_attach(acl, &zone->forward_acl);
12685 	UNLOCK_ZONE(zone);
12686 }
12687 
12688 void
dns_zone_setxfracl(dns_zone_t * zone,dns_acl_t * acl)12689 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
12690 
12691 	REQUIRE(DNS_ZONE_VALID(zone));
12692 
12693 	LOCK_ZONE(zone);
12694 	if (zone->xfr_acl != NULL)
12695 		dns_acl_detach(&zone->xfr_acl);
12696 	dns_acl_attach(acl, &zone->xfr_acl);
12697 	UNLOCK_ZONE(zone);
12698 }
12699 
12700 dns_acl_t *
dns_zone_getnotifyacl(dns_zone_t * zone)12701 dns_zone_getnotifyacl(dns_zone_t *zone) {
12702 
12703 	REQUIRE(DNS_ZONE_VALID(zone));
12704 
12705 	return (zone->notify_acl);
12706 }
12707 
12708 dns_acl_t *
dns_zone_getqueryacl(dns_zone_t * zone)12709 dns_zone_getqueryacl(dns_zone_t *zone) {
12710 
12711 	REQUIRE(DNS_ZONE_VALID(zone));
12712 
12713 	return (zone->query_acl);
12714 }
12715 
12716 dns_acl_t *
dns_zone_getqueryonacl(dns_zone_t * zone)12717 dns_zone_getqueryonacl(dns_zone_t *zone) {
12718 
12719 	REQUIRE(DNS_ZONE_VALID(zone));
12720 
12721 	return (zone->queryon_acl);
12722 }
12723 
12724 dns_acl_t *
dns_zone_getupdateacl(dns_zone_t * zone)12725 dns_zone_getupdateacl(dns_zone_t *zone) {
12726 
12727 	REQUIRE(DNS_ZONE_VALID(zone));
12728 
12729 	return (zone->update_acl);
12730 }
12731 
12732 dns_acl_t *
dns_zone_getforwardacl(dns_zone_t * zone)12733 dns_zone_getforwardacl(dns_zone_t *zone) {
12734 
12735 	REQUIRE(DNS_ZONE_VALID(zone));
12736 
12737 	return (zone->forward_acl);
12738 }
12739 
12740 dns_acl_t *
dns_zone_getxfracl(dns_zone_t * zone)12741 dns_zone_getxfracl(dns_zone_t *zone) {
12742 
12743 	REQUIRE(DNS_ZONE_VALID(zone));
12744 
12745 	return (zone->xfr_acl);
12746 }
12747 
12748 void
dns_zone_clearupdateacl(dns_zone_t * zone)12749 dns_zone_clearupdateacl(dns_zone_t *zone) {
12750 
12751 	REQUIRE(DNS_ZONE_VALID(zone));
12752 
12753 	LOCK_ZONE(zone);
12754 	if (zone->update_acl != NULL)
12755 		dns_acl_detach(&zone->update_acl);
12756 	UNLOCK_ZONE(zone);
12757 }
12758 
12759 void
dns_zone_clearforwardacl(dns_zone_t * zone)12760 dns_zone_clearforwardacl(dns_zone_t *zone) {
12761 
12762 	REQUIRE(DNS_ZONE_VALID(zone));
12763 
12764 	LOCK_ZONE(zone);
12765 	if (zone->forward_acl != NULL)
12766 		dns_acl_detach(&zone->forward_acl);
12767 	UNLOCK_ZONE(zone);
12768 }
12769 
12770 void
dns_zone_clearnotifyacl(dns_zone_t * zone)12771 dns_zone_clearnotifyacl(dns_zone_t *zone) {
12772 
12773 	REQUIRE(DNS_ZONE_VALID(zone));
12774 
12775 	LOCK_ZONE(zone);
12776 	if (zone->notify_acl != NULL)
12777 		dns_acl_detach(&zone->notify_acl);
12778 	UNLOCK_ZONE(zone);
12779 }
12780 
12781 void
dns_zone_clearqueryacl(dns_zone_t * zone)12782 dns_zone_clearqueryacl(dns_zone_t *zone) {
12783 
12784 	REQUIRE(DNS_ZONE_VALID(zone));
12785 
12786 	LOCK_ZONE(zone);
12787 	if (zone->query_acl != NULL)
12788 		dns_acl_detach(&zone->query_acl);
12789 	UNLOCK_ZONE(zone);
12790 }
12791 
12792 void
dns_zone_clearqueryonacl(dns_zone_t * zone)12793 dns_zone_clearqueryonacl(dns_zone_t *zone) {
12794 
12795 	REQUIRE(DNS_ZONE_VALID(zone));
12796 
12797 	LOCK_ZONE(zone);
12798 	if (zone->queryon_acl != NULL)
12799 		dns_acl_detach(&zone->queryon_acl);
12800 	UNLOCK_ZONE(zone);
12801 }
12802 
12803 void
dns_zone_clearxfracl(dns_zone_t * zone)12804 dns_zone_clearxfracl(dns_zone_t *zone) {
12805 
12806 	REQUIRE(DNS_ZONE_VALID(zone));
12807 
12808 	LOCK_ZONE(zone);
12809 	if (zone->xfr_acl != NULL)
12810 		dns_acl_detach(&zone->xfr_acl);
12811 	UNLOCK_ZONE(zone);
12812 }
12813 
12814 isc_boolean_t
dns_zone_getupdatedisabled(dns_zone_t * zone)12815 dns_zone_getupdatedisabled(dns_zone_t *zone) {
12816 	REQUIRE(DNS_ZONE_VALID(zone));
12817 	return (zone->update_disabled);
12818 
12819 }
12820 
12821 void
dns_zone_setupdatedisabled(dns_zone_t * zone,isc_boolean_t state)12822 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
12823 	REQUIRE(DNS_ZONE_VALID(zone));
12824 	zone->update_disabled = state;
12825 }
12826 
12827 isc_boolean_t
dns_zone_getzeronosoattl(dns_zone_t * zone)12828 dns_zone_getzeronosoattl(dns_zone_t *zone) {
12829 	REQUIRE(DNS_ZONE_VALID(zone));
12830 	return (zone->zero_no_soa_ttl);
12831 
12832 }
12833 
12834 void
dns_zone_setzeronosoattl(dns_zone_t * zone,isc_boolean_t state)12835 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
12836 	REQUIRE(DNS_ZONE_VALID(zone));
12837 	zone->zero_no_soa_ttl = state;
12838 }
12839 
12840 void
dns_zone_setchecknames(dns_zone_t * zone,dns_severity_t severity)12841 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
12842 
12843 	REQUIRE(DNS_ZONE_VALID(zone));
12844 
12845 	zone->check_names = severity;
12846 }
12847 
12848 dns_severity_t
dns_zone_getchecknames(dns_zone_t * zone)12849 dns_zone_getchecknames(dns_zone_t *zone) {
12850 
12851 	REQUIRE(DNS_ZONE_VALID(zone));
12852 
12853 	return (zone->check_names);
12854 }
12855 
12856 void
dns_zone_setjournalsize(dns_zone_t * zone,isc_int32_t size)12857 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
12858 
12859 	REQUIRE(DNS_ZONE_VALID(zone));
12860 
12861 	zone->journalsize = size;
12862 }
12863 
12864 isc_int32_t
dns_zone_getjournalsize(dns_zone_t * zone)12865 dns_zone_getjournalsize(dns_zone_t *zone) {
12866 
12867 	REQUIRE(DNS_ZONE_VALID(zone));
12868 
12869 	return (zone->journalsize);
12870 }
12871 
12872 static void
zone_namerd_tostr(dns_zone_t * zone,char * buf,size_t length)12873 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
12874 	isc_result_t result = ISC_R_FAILURE;
12875 	isc_buffer_t buffer;
12876 
12877 	REQUIRE(buf != NULL);
12878 	REQUIRE(length > 1U);
12879 
12880 	/*
12881 	 * Leave space for terminating '\0'.
12882 	 */
12883 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12884 	if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
12885 		if (dns_name_dynamic(&zone->origin))
12886 			result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
12887 		if (result != ISC_R_SUCCESS &&
12888 		    isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
12889 			isc_buffer_putstr(&buffer, "<UNKNOWN>");
12890 
12891 		if (isc_buffer_availablelength(&buffer) > 0)
12892 			isc_buffer_putstr(&buffer, "/");
12893 		(void)dns_rdataclass_totext(zone->rdclass, &buffer);
12894 	}
12895 
12896 	if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
12897 	    strcmp(zone->view->name, "_default") != 0 &&
12898 	    strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
12899 		isc_buffer_putstr(&buffer, "/");
12900 		isc_buffer_putstr(&buffer, zone->view->name);
12901 	}
12902 	if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer))
12903 		isc_buffer_putstr(&buffer, " (signed)");
12904 	if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer))
12905 		isc_buffer_putstr(&buffer, " (unsigned)");
12906 
12907 	buf[isc_buffer_usedlength(&buffer)] = '\0';
12908 }
12909 
12910 static void
zone_name_tostr(dns_zone_t * zone,char * buf,size_t length)12911 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
12912 	isc_result_t result = ISC_R_FAILURE;
12913 	isc_buffer_t buffer;
12914 
12915 	REQUIRE(buf != NULL);
12916 	REQUIRE(length > 1U);
12917 
12918 	/*
12919 	 * Leave space for terminating '\0'.
12920 	 */
12921 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12922 	if (dns_name_dynamic(&zone->origin))
12923 		result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
12924 	if (result != ISC_R_SUCCESS &&
12925 	    isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
12926 		isc_buffer_putstr(&buffer, "<UNKNOWN>");
12927 
12928 	buf[isc_buffer_usedlength(&buffer)] = '\0';
12929 }
12930 
12931 static void
zone_rdclass_tostr(dns_zone_t * zone,char * buf,size_t length)12932 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
12933 	isc_buffer_t buffer;
12934 
12935 	REQUIRE(buf != NULL);
12936 	REQUIRE(length > 1U);
12937 
12938 	/*
12939 	 * Leave space for terminating '\0'.
12940 	 */
12941 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12942 	(void)dns_rdataclass_totext(zone->rdclass, &buffer);
12943 
12944 	buf[isc_buffer_usedlength(&buffer)] = '\0';
12945 }
12946 
12947 static void
zone_viewname_tostr(dns_zone_t * zone,char * buf,size_t length)12948 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
12949 	isc_buffer_t buffer;
12950 
12951 	REQUIRE(buf != NULL);
12952 	REQUIRE(length > 1U);
12953 
12954 
12955 	/*
12956 	 * Leave space for terminating '\0'.
12957 	 */
12958 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
12959 
12960 	if (zone->view == NULL) {
12961 		isc_buffer_putstr(&buffer, "_none");
12962 	} else if (strlen(zone->view->name)
12963 		   < isc_buffer_availablelength(&buffer)) {
12964 		isc_buffer_putstr(&buffer, zone->view->name);
12965 	} else {
12966 		isc_buffer_putstr(&buffer, "_toolong");
12967 	}
12968 
12969 	buf[isc_buffer_usedlength(&buffer)] = '\0';
12970 }
12971 
12972 void
dns_zone_name(dns_zone_t * zone,char * buf,size_t length)12973 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
12974 	REQUIRE(DNS_ZONE_VALID(zone));
12975 	REQUIRE(buf != NULL);
12976 	zone_namerd_tostr(zone, buf, length);
12977 }
12978 
12979 static void
notify_log(dns_zone_t * zone,int level,const char * fmt,...)12980 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
12981 	va_list ap;
12982 	char message[4096];
12983 
12984 	if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
12985 		return;
12986 
12987 	va_start(ap, fmt);
12988 	vsnprintf(message, sizeof(message), fmt, ap);
12989 	va_end(ap);
12990 	isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
12991 		      level, "zone %s: %s", zone->strnamerd, message);
12992 }
12993 
12994 void
dns_zone_logc(dns_zone_t * zone,isc_logcategory_t * category,int level,const char * fmt,...)12995 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
12996 	      int level, const char *fmt, ...) {
12997 	va_list ap;
12998 	char message[4096];
12999 
13000 	if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
13001 		return;
13002 
13003 	va_start(ap, fmt);
13004 	vsnprintf(message, sizeof(message), fmt, ap);
13005 	va_end(ap);
13006 	isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
13007 		      level, "%s%s: %s", (zone->type == dns_zone_key) ?
13008 		      "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
13009 		      "redirect-zone" : "zone ", zone->strnamerd, message);
13010 }
13011 
13012 void
dns_zone_log(dns_zone_t * zone,int level,const char * fmt,...)13013 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
13014 	va_list ap;
13015 	char message[4096];
13016 
13017 	if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
13018 		return;
13019 
13020 	va_start(ap, fmt);
13021 	vsnprintf(message, sizeof(message), fmt, ap);
13022 	va_end(ap);
13023 	isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
13024 		      level, "%s%s: %s", (zone->type == dns_zone_key) ?
13025 		      "managed-keys-zone" : (zone->type == dns_zone_redirect) ?
13026 		      "redirect-zone" : "zone ", zone->strnamerd, message);
13027 }
13028 
13029 static void
zone_debuglog(dns_zone_t * zone,const char * me,int debuglevel,const char * fmt,...)13030 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
13031 	      const char *fmt, ...)
13032 {
13033 	va_list ap;
13034 	char message[4096];
13035 	int level = ISC_LOG_DEBUG(debuglevel);
13036 	const char *zstr;
13037 
13038 	if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
13039 		return;
13040 
13041 	va_start(ap, fmt);
13042 	vsnprintf(message, sizeof(message), fmt, ap);
13043 	va_end(ap);
13044 
13045 	switch (zone->type) {
13046 	case dns_zone_key:
13047 		zstr = "managed-keys-zone";
13048 		break;
13049 	case dns_zone_redirect:
13050 		zstr = "redirect-zone";
13051 		break;
13052 	default:
13053 		zstr = "zone";
13054 	}
13055 
13056 	isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
13057 		      level, "%s: %s %s: %s", me, zstr, zone->strnamerd,
13058 		      message);
13059 }
13060 
13061 static int
message_count(dns_message_t * msg,dns_section_t section,dns_rdatatype_t type)13062 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
13063 {
13064 	isc_result_t result;
13065 	dns_name_t *name;
13066 	dns_rdataset_t *curr;
13067 	int count = 0;
13068 
13069 	result = dns_message_firstname(msg, section);
13070 	while (result == ISC_R_SUCCESS) {
13071 		name = NULL;
13072 		dns_message_currentname(msg, section, &name);
13073 
13074 		for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
13075 		     curr = ISC_LIST_PREV(curr, link)) {
13076 			if (curr->type == type)
13077 				count++;
13078 		}
13079 		result = dns_message_nextname(msg, section);
13080 	}
13081 
13082 	return (count);
13083 }
13084 
13085 void
dns_zone_setmaxxfrin(dns_zone_t * zone,isc_uint32_t maxxfrin)13086 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
13087 	REQUIRE(DNS_ZONE_VALID(zone));
13088 
13089 	zone->maxxfrin = maxxfrin;
13090 }
13091 
13092 isc_uint32_t
dns_zone_getmaxxfrin(dns_zone_t * zone)13093 dns_zone_getmaxxfrin(dns_zone_t *zone) {
13094 	REQUIRE(DNS_ZONE_VALID(zone));
13095 
13096 	return (zone->maxxfrin);
13097 }
13098 
13099 void
dns_zone_setmaxxfrout(dns_zone_t * zone,isc_uint32_t maxxfrout)13100 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
13101 	REQUIRE(DNS_ZONE_VALID(zone));
13102 	zone->maxxfrout = maxxfrout;
13103 }
13104 
13105 isc_uint32_t
dns_zone_getmaxxfrout(dns_zone_t * zone)13106 dns_zone_getmaxxfrout(dns_zone_t *zone) {
13107 	REQUIRE(DNS_ZONE_VALID(zone));
13108 
13109 	return (zone->maxxfrout);
13110 }
13111 
13112 dns_zonetype_t
dns_zone_gettype(dns_zone_t * zone)13113 dns_zone_gettype(dns_zone_t *zone) {
13114 	REQUIRE(DNS_ZONE_VALID(zone));
13115 
13116 	return (zone->type);
13117 }
13118 
13119 dns_name_t *
dns_zone_getorigin(dns_zone_t * zone)13120 dns_zone_getorigin(dns_zone_t *zone) {
13121 	REQUIRE(DNS_ZONE_VALID(zone));
13122 
13123 	return (&zone->origin);
13124 }
13125 
13126 void
dns_zone_settask(dns_zone_t * zone,isc_task_t * task)13127 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
13128 	REQUIRE(DNS_ZONE_VALID(zone));
13129 
13130 	LOCK_ZONE(zone);
13131 	if (zone->task != NULL)
13132 		isc_task_detach(&zone->task);
13133 	isc_task_attach(task, &zone->task);
13134 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13135 	if (zone->db != NULL)
13136 		dns_db_settask(zone->db, zone->task);
13137 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13138 	UNLOCK_ZONE(zone);
13139 }
13140 
13141 void
dns_zone_gettask(dns_zone_t * zone,isc_task_t ** target)13142 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
13143 	REQUIRE(DNS_ZONE_VALID(zone));
13144 	isc_task_attach(zone->task, target);
13145 }
13146 
13147 void
dns_zone_setidlein(dns_zone_t * zone,isc_uint32_t idlein)13148 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
13149 	REQUIRE(DNS_ZONE_VALID(zone));
13150 
13151 	if (idlein == 0)
13152 		idlein = DNS_DEFAULT_IDLEIN;
13153 	zone->idlein = idlein;
13154 }
13155 
13156 isc_uint32_t
dns_zone_getidlein(dns_zone_t * zone)13157 dns_zone_getidlein(dns_zone_t *zone) {
13158 	REQUIRE(DNS_ZONE_VALID(zone));
13159 
13160 	return (zone->idlein);
13161 }
13162 
13163 void
dns_zone_setidleout(dns_zone_t * zone,isc_uint32_t idleout)13164 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
13165 	REQUIRE(DNS_ZONE_VALID(zone));
13166 
13167 	zone->idleout = idleout;
13168 }
13169 
13170 isc_uint32_t
dns_zone_getidleout(dns_zone_t * zone)13171 dns_zone_getidleout(dns_zone_t *zone) {
13172 	REQUIRE(DNS_ZONE_VALID(zone));
13173 
13174 	return (zone->idleout);
13175 }
13176 
13177 static void
notify_done(isc_task_t * task,isc_event_t * event)13178 notify_done(isc_task_t *task, isc_event_t *event) {
13179 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
13180 	dns_notify_t *notify;
13181 	isc_result_t result;
13182 	dns_message_t *message = NULL;
13183 	isc_buffer_t buf;
13184 	char rcode[128];
13185 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
13186 
13187 	UNUSED(task);
13188 
13189 	notify = event->ev_arg;
13190 	REQUIRE(DNS_NOTIFY_VALID(notify));
13191 	INSIST(task == notify->zone->task);
13192 
13193 	isc_buffer_init(&buf, rcode, sizeof(rcode));
13194 	isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
13195 
13196 	result = revent->result;
13197 	if (result == ISC_R_SUCCESS)
13198 		result = dns_message_create(notify->zone->mctx,
13199 					    DNS_MESSAGE_INTENTPARSE, &message);
13200 	if (result == ISC_R_SUCCESS)
13201 		result = dns_request_getresponse(revent->request, message,
13202 					DNS_MESSAGEPARSE_PRESERVEORDER);
13203 	if (result == ISC_R_SUCCESS)
13204 		result = dns_rcode_totext(message->rcode, &buf);
13205 	if (result == ISC_R_SUCCESS)
13206 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
13207 			   "notify response from %s: %.*s",
13208 			   addrbuf, (int)buf.used, rcode);
13209 	else
13210 		notify_log(notify->zone, ISC_LOG_DEBUG(2),
13211 			   "notify to %s failed: %s", addrbuf,
13212 			   dns_result_totext(result));
13213 
13214 	/*
13215 	 * Old bind's return formerr if they see a soa record.	Retry w/o
13216 	 * the soa if we see a formerr and had sent a SOA.
13217 	 */
13218 	isc_event_free(&event);
13219 	if (message != NULL && message->rcode == dns_rcode_formerr &&
13220 	    (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
13221 		isc_boolean_t startup;
13222 
13223 		notify->flags |= DNS_NOTIFY_NOSOA;
13224 		dns_request_destroy(&notify->request);
13225 		startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0);
13226 		result = notify_send_queue(notify, startup);
13227 		if (result != ISC_R_SUCCESS)
13228 			notify_destroy(notify, ISC_FALSE);
13229 	} else {
13230 		if (result == ISC_R_TIMEDOUT)
13231 			notify_log(notify->zone, ISC_LOG_DEBUG(1),
13232 				   "notify to %s: retries exceeded", addrbuf);
13233 		notify_destroy(notify, ISC_FALSE);
13234 	}
13235 	if (message != NULL)
13236 		dns_message_destroy(&message);
13237 }
13238 
13239 struct secure_event {
13240 	isc_event_t e;
13241 	dns_db_t *db;
13242 	isc_uint32_t serial;
13243 };
13244 
13245 static void
update_log_cb(void * arg,dns_zone_t * zone,int level,const char * message)13246 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
13247 	UNUSED(arg);
13248 	dns_zone_log(zone, level, "%s", message);
13249 }
13250 
13251 static isc_result_t
sync_secure_journal(dns_zone_t * zone,dns_zone_t * raw,dns_journal_t * journal,isc_uint32_t start,isc_uint32_t end,dns_difftuple_t ** soatuplep,dns_diff_t * diff)13252 sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
13253 		    isc_uint32_t start, isc_uint32_t end,
13254 		    dns_difftuple_t **soatuplep, dns_diff_t *diff)
13255 {
13256 	isc_result_t result;
13257 	dns_difftuple_t *tuple = NULL;
13258 	dns_diffop_t op = DNS_DIFFOP_ADD;
13259 	int n_soa = 0;
13260 
13261 	REQUIRE(soatuplep != NULL);
13262 
13263 	if (start == end)
13264 		return (DNS_R_UNCHANGED);
13265 
13266 	CHECK(dns_journal_iter_init(journal, start, end));
13267 	for (result = dns_journal_first_rr(journal);
13268 	     result == ISC_R_SUCCESS;
13269 	     result = dns_journal_next_rr(journal))
13270 	{
13271 		dns_name_t *name = NULL;
13272 		isc_uint32_t ttl;
13273 		dns_rdata_t *rdata = NULL;
13274 		dns_journal_current_rr(journal, &name, &ttl, &rdata);
13275 
13276 		if (rdata->type == dns_rdatatype_soa) {
13277 			n_soa++;
13278 			if (n_soa == 2) {
13279 				/*
13280 				 * Save the latest raw SOA record.
13281 				 */
13282 				if (*soatuplep != NULL)
13283 					dns_difftuple_free(soatuplep);
13284 				CHECK(dns_difftuple_create(diff->mctx,
13285 							   DNS_DIFFOP_ADD,
13286 							   name, ttl, rdata,
13287 							   soatuplep));
13288 			}
13289 			if (n_soa == 3)
13290 				n_soa = 1;
13291 			continue;
13292 		}
13293 
13294 		/* Sanity. */
13295 		if (n_soa == 0) {
13296 			dns_zone_log(raw, ISC_LOG_ERROR,
13297 				     "corrupt journal file: '%s'\n",
13298 				     raw->journal);
13299 			return (ISC_R_FAILURE);
13300 		}
13301 
13302 		if (zone->privatetype != 0 &&
13303 		    rdata->type == zone->privatetype)
13304 			continue;
13305 
13306 		if (rdata->type == dns_rdatatype_nsec ||
13307 		    rdata->type == dns_rdatatype_rrsig ||
13308 		    rdata->type == dns_rdatatype_nsec3 ||
13309 		    rdata->type == dns_rdatatype_dnskey ||
13310 		    rdata->type == dns_rdatatype_nsec3param)
13311 			continue;
13312 
13313 		op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
13314 
13315 		CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
13316 					   &tuple));
13317 		dns_diff_appendminimal(diff, &tuple);
13318 	}
13319 	if (result == ISC_R_NOMORE)
13320 		result = ISC_R_SUCCESS;
13321 
13322  failure:
13323 	return(result);
13324 }
13325 
13326 static isc_result_t
sync_secure_db(dns_zone_t * seczone,dns_zone_t * raw,dns_db_t * secdb,dns_dbversion_t * secver,dns_difftuple_t ** soatuple,dns_diff_t * diff)13327 sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb,
13328 	       dns_dbversion_t *secver, dns_difftuple_t **soatuple,
13329 	       dns_diff_t *diff)
13330 {
13331 	isc_result_t result;
13332 	dns_db_t *rawdb = NULL;
13333 	dns_dbversion_t *rawver = NULL;
13334 	dns_difftuple_t *tuple = NULL, *next;
13335 	dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
13336 	dns_rdata_soa_t oldsoa, newsoa;
13337 
13338 	REQUIRE(DNS_ZONE_VALID(seczone));
13339 	REQUIRE(soatuple != NULL && *soatuple == NULL);
13340 
13341 	if (!seczone->sourceserialset)
13342 		return (DNS_R_UNCHANGED);
13343 
13344 	dns_db_attach(raw->db, &rawdb);
13345 	dns_db_currentversion(rawdb, &rawver);
13346 	result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
13347 	dns_db_closeversion(rawdb, &rawver, ISC_FALSE);
13348 	dns_db_detach(&rawdb);
13349 
13350 	if (result != ISC_R_SUCCESS)
13351 		return (result);
13352 
13353 	for (tuple = ISC_LIST_HEAD(diff->tuples);
13354 	     tuple != NULL;
13355 	     tuple = next)
13356 	{
13357 		next = ISC_LIST_NEXT(tuple, link);
13358 		if (tuple->rdata.type == dns_rdatatype_nsec ||
13359 		    tuple->rdata.type == dns_rdatatype_rrsig ||
13360 		    tuple->rdata.type == dns_rdatatype_dnskey ||
13361 		    tuple->rdata.type == dns_rdatatype_nsec3 ||
13362 		    tuple->rdata.type == dns_rdatatype_nsec3param)
13363 		{
13364 			ISC_LIST_UNLINK(diff->tuples, tuple, link);
13365 			dns_difftuple_free(&tuple);
13366 			continue;
13367 		}
13368 		if (tuple->rdata.type == dns_rdatatype_soa) {
13369 			if (tuple->op == DNS_DIFFOP_DEL) {
13370 				INSIST(oldtuple == NULL);
13371 				oldtuple = tuple;
13372 			}
13373 			if (tuple->op == DNS_DIFFOP_ADD) {
13374 				INSIST(newtuple == NULL);
13375 				newtuple = tuple;
13376 			}
13377 		}
13378 	}
13379 
13380 	if (oldtuple != NULL && newtuple != NULL) {
13381 
13382 		result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL);
13383 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
13384 
13385 		result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL);
13386 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
13387 
13388 		/*
13389 		 * If the SOA records are the same except for the serial
13390 		 * remove them from the diff.
13391 		 */
13392 		if (oldsoa.refresh == newsoa.refresh &&
13393 		    oldsoa.retry == newsoa.retry &&
13394 		    oldsoa.minimum == newsoa.minimum &&
13395 		    oldsoa.expire == newsoa.expire &&
13396 		    dns_name_equal(&oldsoa.origin, &newsoa.origin) &&
13397 		    dns_name_equal(&oldsoa.contact, &newsoa.contact)) {
13398 			ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
13399 			dns_difftuple_free(&oldtuple);
13400 			ISC_LIST_UNLINK(diff->tuples, newtuple, link);
13401 			dns_difftuple_free(&newtuple);
13402 		}
13403 	}
13404 
13405 	if (ISC_LIST_EMPTY(diff->tuples))
13406 		return (DNS_R_UNCHANGED);
13407 
13408 	/*
13409 	 * If there are still SOA records in the diff they can now be removed
13410 	 * saving the new SOA record.
13411 	 */
13412 	if (oldtuple != NULL) {
13413 		ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
13414 		dns_difftuple_free(&oldtuple);
13415 	}
13416 
13417 	if (newtuple != NULL) {
13418 		ISC_LIST_UNLINK(diff->tuples, newtuple, link);
13419 		*soatuple = newtuple;
13420 	}
13421 
13422 	return (ISC_R_SUCCESS);
13423 }
13424 
13425 static void
receive_secure_serial(isc_task_t * task,isc_event_t * event)13426 receive_secure_serial(isc_task_t *task, isc_event_t *event) {
13427 	static char me[] = "receive_secure_serial";
13428 	isc_result_t result;
13429 	dns_journal_t *rjournal = NULL;
13430 	isc_uint32_t start, end;
13431 	dns_zone_t *zone, *raw = NULL;
13432 	dns_db_t *db = NULL;
13433 	dns_dbversion_t *newver = NULL, *oldver = NULL;
13434 	dns_diff_t diff;
13435 	dns_difftuple_t *tuple = NULL, *soatuple = NULL;
13436 	dns_update_log_t log = { update_log_cb, NULL };
13437 	isc_time_t timenow;
13438 
13439 	zone = event->ev_arg;
13440 	end = ((struct secure_event *)event)->serial;
13441 	isc_event_free(&event);
13442 
13443 	ENTER;
13444 
13445 	LOCK_ZONE(zone);
13446 
13447 	dns_diff_init(zone->mctx, &diff);
13448 
13449 	UNUSED(task);
13450 
13451 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13452 	if (zone->db != NULL)
13453 		dns_db_attach(zone->db, &db);
13454 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13455 
13456 	if (zone->raw != NULL)
13457 		dns_zone_attach(zone->raw, &raw);
13458 	UNLOCK_ZONE(zone);
13459 
13460 	/*
13461 	 * zone->db may be NULL if the load from disk failed.
13462 	 */
13463 	if (db == NULL || raw == NULL) {
13464 		result = ISC_R_FAILURE;
13465 		goto failure;
13466 	}
13467 
13468 	/*
13469 	 * We first attempt to sync the raw zone to the secure zone
13470 	 * by using the raw zone's journal, applying all the deltas
13471 	 * from the latest source-serial of the secure zone up to
13472 	 * the current serial number of the raw zone.
13473 	 *
13474 	 * If that fails, then we'll fall back to a direct comparison
13475 	 * between raw and secure zones.
13476 	 */
13477 	result = dns_journal_open(raw->mctx, raw->journal,
13478 				  DNS_JOURNAL_WRITE, &rjournal);
13479 	if (result != ISC_R_SUCCESS)
13480 		goto failure;
13481 	else {
13482 		dns_journal_t *sjournal = NULL;
13483 
13484 		result = dns_journal_open(zone->mctx, zone->journal,
13485 					  DNS_JOURNAL_READ, &sjournal);
13486 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
13487 			goto failure;
13488 
13489 		if (!dns_journal_get_sourceserial(rjournal, &start)) {
13490 			start = dns_journal_first_serial(rjournal);
13491 			dns_journal_set_sourceserial(rjournal, start);
13492 		}
13493 		if (sjournal != NULL) {
13494 			isc_uint32_t serial;
13495 			/*
13496 			 * We read the secure journal first, if that exists
13497 			 * use its value provided it is greater that from the
13498 			 * raw journal.
13499 			 */
13500 			if (dns_journal_get_sourceserial(sjournal, &serial)) {
13501 				if (isc_serial_gt(serial, start))
13502 					start = serial;
13503 			}
13504 			dns_journal_destroy(&sjournal);
13505 		}
13506 	}
13507 
13508 	dns_db_currentversion(db, &oldver);
13509 	CHECK(dns_db_newversion(db, &newver));
13510 
13511 	/*
13512 	 * Try to apply diffs from the raw zone's journal to the secure
13513 	 * zone.  If that fails, we recover by syncing up the databases
13514 	 * directly.
13515 	 */
13516 	result = sync_secure_journal(zone, raw, rjournal, start, end,
13517 				     &soatuple, &diff);
13518 	if (result == DNS_R_UNCHANGED)
13519 		goto failure;
13520 	else if (result != ISC_R_SUCCESS)
13521 		CHECK(sync_secure_db(zone, raw, db, oldver, &soatuple, &diff));
13522 
13523 	CHECK(dns_diff_apply(&diff, db, newver));
13524 
13525 	if (soatuple != NULL) {
13526 		isc_uint32_t oldserial, newserial, desired;
13527 
13528 		CHECK(dns_db_createsoatuple(db, oldver, diff.mctx,
13529 					    DNS_DIFFOP_DEL, &tuple));
13530 		oldserial = dns_soa_getserial(&tuple->rdata);
13531 		newserial = desired = dns_soa_getserial(&soatuple->rdata);
13532 		if (!isc_serial_gt(newserial, oldserial)) {
13533 			newserial = oldserial + 1;
13534 			if (newserial == 0)
13535 				newserial++;
13536 			dns_soa_setserial(newserial, &soatuple->rdata);
13537 		}
13538 		CHECK(do_one_tuple(&tuple, db, newver, &diff));
13539 		CHECK(do_one_tuple(&soatuple, db, newver, &diff));
13540 		dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)",
13541 			     newserial, desired);
13542 	} else
13543 		CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
13544 					zone->updatemethod));
13545 
13546 	CHECK(dns_update_signatures(&log, zone, db, oldver, newver,
13547 				    &diff, zone->sigvalidityinterval));
13548 
13549 	CHECK(zone_journal(zone, &diff, &end, "receive_secure_serial"));
13550 
13551 	dns_journal_set_sourceserial(rjournal, end);
13552 	dns_journal_commit(rjournal);
13553 
13554 	LOCK_ZONE(zone);
13555 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
13556 
13557 	zone->sourceserial = end;
13558 	zone->sourceserialset = ISC_TRUE;
13559 	zone_needdump(zone, DNS_DUMP_DELAY);
13560 
13561 	TIME_NOW(&timenow);
13562 	zone_settimer(zone, &timenow);
13563 	UNLOCK_ZONE(zone);
13564 
13565 	dns_db_closeversion(db, &oldver, ISC_FALSE);
13566 	dns_db_closeversion(db, &newver, ISC_TRUE);
13567 
13568  failure:
13569 	if (raw != NULL)
13570 		dns_zone_detach(&raw);
13571 	if (result != ISC_R_SUCCESS)
13572 		dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s",
13573 			     dns_result_totext(result));
13574 	if (tuple != NULL)
13575 		dns_difftuple_free(&tuple);
13576 	if (soatuple != NULL)
13577 		dns_difftuple_free(&soatuple);
13578 	if (db != NULL) {
13579 		if (oldver != NULL)
13580 			dns_db_closeversion(db, &oldver, ISC_FALSE);
13581 		if (newver != NULL)
13582 			dns_db_closeversion(db, &newver, ISC_FALSE);
13583 		dns_db_detach(&db);
13584 	}
13585 	if (rjournal != NULL)
13586 		dns_journal_destroy(&rjournal);
13587 	dns_diff_clear(&diff);
13588 	dns_zone_idetach(&zone);
13589 
13590 	INSIST(oldver == NULL);
13591 	INSIST(newver == NULL);
13592 }
13593 
13594 static isc_result_t
zone_send_secureserial(dns_zone_t * zone,isc_uint32_t serial)13595 zone_send_secureserial(dns_zone_t *zone, isc_uint32_t serial) {
13596 	isc_event_t *e;
13597 	dns_zone_t *dummy = NULL;
13598 
13599 	e = isc_event_allocate(zone->secure->mctx, zone,
13600 			       DNS_EVENT_ZONESECURESERIAL,
13601 			       receive_secure_serial, zone->secure,
13602 			       sizeof(struct secure_event));
13603 	if (e == NULL)
13604 		return (ISC_R_NOMEMORY);
13605 	((struct secure_event *)e)->serial = serial;
13606 	INSIST(LOCKED_ZONE(zone->secure));
13607 	zone_iattach(zone->secure, &dummy);
13608 	isc_task_send(zone->secure->task, &e);
13609 
13610 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
13611 	return (ISC_R_SUCCESS);
13612 }
13613 
13614 static isc_result_t
checkandaddsoa(dns_db_t * db,dns_dbnode_t * node,dns_dbversion_t * version,dns_rdataset_t * rdataset,isc_uint32_t oldserial)13615 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
13616 	       dns_rdataset_t *rdataset, isc_uint32_t oldserial)
13617 {
13618 	dns_rdata_soa_t soa;
13619 	dns_rdata_t rdata = DNS_RDATA_INIT;
13620 	dns_rdatalist_t temprdatalist;
13621 	dns_rdataset_t temprdataset;
13622 	isc_buffer_t b;
13623 	isc_result_t result;
13624 	unsigned char buf[DNS_SOA_BUFFERSIZE];
13625 
13626 	result = dns_rdataset_first(rdataset);
13627 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
13628 	dns_rdataset_current(rdataset, &rdata);
13629 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
13630 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
13631 
13632 	if (isc_serial_gt(soa.serial, oldserial))
13633 		return (dns_db_addrdataset(db, node, version, 0, rdataset, 0,
13634 					   NULL));
13635 	/*
13636 	 * Always bump the serial.
13637 	 */
13638 	oldserial++;
13639 	if (oldserial == 0)
13640 		oldserial++;
13641 	soa.serial = oldserial;
13642 
13643 	/*
13644 	 * Construct a replacement rdataset.
13645 	 */
13646 	dns_rdata_reset(&rdata);
13647 	isc_buffer_init(&b, buf, sizeof(buf));
13648 	result = dns_rdata_fromstruct(&rdata, rdataset->rdclass,
13649 				      dns_rdatatype_soa, &soa, &b);
13650 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
13651 	temprdatalist.rdclass = rdata.rdclass;
13652 	temprdatalist.type = rdata.type;
13653 	temprdatalist.covers = 0;
13654 	temprdatalist.ttl = rdataset->ttl;
13655 	ISC_LIST_INIT(temprdatalist.rdata);
13656 	ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link);
13657 
13658 	dns_rdataset_init(&temprdataset);
13659 	result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
13660 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
13661 	return (dns_db_addrdataset(db, node, version, 0, &temprdataset,
13662 				   0, NULL));
13663 }
13664 
13665 /*
13666  * This function should populate an nsec3paramlist_t with the
13667  * nsecparam_t data from a zone.
13668  */
13669 static isc_result_t
save_nsec3param(dns_zone_t * zone,nsec3paramlist_t * nsec3list)13670 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
13671 	isc_result_t result;
13672 	dns_dbnode_t *node = NULL;
13673 	dns_rdataset_t rdataset, prdataset;
13674 	dns_dbversion_t *version = NULL;
13675 	nsec3param_t *nsec3param = NULL;
13676 	nsec3param_t *nsec3p = NULL;
13677 	nsec3param_t *next;
13678 	dns_db_t *db = NULL;
13679 	unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
13680 
13681 	REQUIRE(DNS_ZONE_VALID(zone));
13682 	REQUIRE(nsec3list != NULL);
13683 	REQUIRE(ISC_LIST_EMPTY(*nsec3list));
13684 
13685 	dns_rdataset_init(&rdataset);
13686 	dns_rdataset_init(&prdataset);
13687 
13688 	dns_db_attach(zone->db, &db);
13689 	CHECK(dns_db_getoriginnode(db, &node));
13690 
13691 	dns_db_currentversion(db, &version);
13692 	result = dns_db_findrdataset(db, node, version,
13693 				     dns_rdatatype_nsec3param,
13694 				     dns_rdatatype_none, 0, &rdataset, NULL);
13695 
13696 	if (result != ISC_R_SUCCESS)
13697 		goto getprivate;
13698 
13699 	/*
13700 	 * walk nsec3param rdataset making a list of parameters (note that
13701 	 * multiple simultaneous nsec3 chains are annoyingly legal -- this
13702 	 * is why we use an nsec3list, even tho we will usually only have
13703 	 * one)
13704 	 */
13705 	for (result = dns_rdataset_first(&rdataset);
13706 	     result == ISC_R_SUCCESS;
13707 	     result = dns_rdataset_next(&rdataset))
13708 	{
13709 		dns_rdata_t rdata = DNS_RDATA_INIT;
13710 		dns_rdata_t private = DNS_RDATA_INIT;
13711 
13712 		dns_rdataset_current(&rdataset, &rdata);
13713 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13714 			      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13715 			      "looping through nsec3param data");
13716 		nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
13717 		if (nsec3param == NULL)
13718 			CHECK(ISC_R_NOMEMORY);
13719 		ISC_LINK_INIT(nsec3param, link);
13720 
13721 		/*
13722 		 * now transfer the data from the rdata to
13723 		 * the nsec3param
13724 		 */
13725 		dns_nsec3param_toprivate(&rdata, &private,
13726 					 zone->privatetype, nsec3param->data,
13727 					 sizeof(nsec3param->data));
13728 		nsec3param->length = private.length;
13729 		ISC_LIST_APPEND(*nsec3list, nsec3param, link);
13730 	}
13731 
13732  getprivate:
13733 	result = dns_db_findrdataset(db, node, version, zone->privatetype,
13734 				     dns_rdatatype_none, 0, &prdataset, NULL);
13735 	if (result != ISC_R_SUCCESS)
13736 		goto done;
13737 
13738 	/*
13739 	 * walk private type records, converting them to nsec3 parameters
13740 	 * using dns_nsec3param_fromprivate(), do the right thing based on
13741 	 * CREATE and REMOVE flags
13742 	 */
13743 	for (result = dns_rdataset_first(&prdataset);
13744 	     result == ISC_R_SUCCESS;
13745 	     result = dns_rdataset_next(&prdataset))
13746 	{
13747 		dns_rdata_t rdata = DNS_RDATA_INIT;
13748 		dns_rdata_t private = DNS_RDATA_INIT;
13749 
13750 		dns_rdataset_current(&prdataset, &private);
13751 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13752 			      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13753 			      "looping through nsec3param private data");
13754 
13755 		/*
13756 		 * Do we have a valid private record?
13757 		 */
13758 		if (!dns_nsec3param_fromprivate(&private, &rdata,
13759 						buf, sizeof(buf)))
13760 			continue;
13761 
13762 		/*
13763 		 * Remove any NSEC3PARAM records scheduled to be removed.
13764 		 */
13765 		if (NSEC3REMOVE(rdata.data[1])) {
13766 			/*
13767 			 * Zero out the flags.
13768 			 */
13769 			rdata.data[1] = 0;
13770 
13771 			for (nsec3p = ISC_LIST_HEAD(*nsec3list);
13772 			     nsec3p != NULL;
13773 			     nsec3p = next)
13774 			{
13775 				next = ISC_LIST_NEXT(nsec3p, link);
13776 
13777 				if (nsec3p->length == rdata.length + 1 &&
13778 				    memcmp(rdata.data, nsec3p->data + 1,
13779 					   nsec3p->length - 1) == 0) {
13780 					ISC_LIST_UNLINK(*nsec3list,
13781 							nsec3p, link);
13782 					isc_mem_put(zone->mctx, nsec3p,
13783 						    sizeof(nsec3param_t));
13784 				}
13785 			}
13786 			continue;
13787 		}
13788 
13789 		nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
13790 		if (nsec3param == NULL)
13791 			CHECK(ISC_R_NOMEMORY);
13792 		ISC_LINK_INIT(nsec3param, link);
13793 
13794 		/*
13795 		 * Copy the remaining private records so the nsec/nsec3
13796 		 * chain gets created.
13797 		 */
13798 		INSIST(private.length <= sizeof(nsec3param->data));
13799 		memmove(nsec3param->data, private.data, private.length);
13800 		nsec3param->length = private.length;
13801 		ISC_LIST_APPEND(*nsec3list, nsec3param, link);
13802 	}
13803 
13804  done:
13805 	if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND)
13806 		result = ISC_R_SUCCESS;
13807 
13808  failure:
13809 	if (node != NULL)
13810 		dns_db_detachnode(db, &node);
13811 	if (version != NULL)
13812 		dns_db_closeversion(db, &version, ISC_FALSE);
13813 	if (db != NULL)
13814 		dns_db_detach(&db);
13815 	if (dns_rdataset_isassociated(&rdataset))
13816 		dns_rdataset_disassociate(&rdataset);
13817 	if (dns_rdataset_isassociated(&prdataset))
13818 		dns_rdataset_disassociate(&prdataset);
13819 	return (result);
13820 }
13821 
13822 /*
13823  * Walk the list of the nsec3 chains desired for the zone, converting
13824  * parameters to private type records using dns_nsec3param_toprivate(),
13825  * and insert them into the new zone db.
13826  */
13827 static isc_result_t
restore_nsec3param(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * version,nsec3paramlist_t * nsec3list)13828 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
13829 		   nsec3paramlist_t *nsec3list)
13830 {
13831 	isc_result_t result;
13832 	dns_diff_t diff;
13833 	dns_rdata_t rdata;
13834 	nsec3param_t *nsec3p = NULL;
13835 	nsec3param_t *next;
13836 
13837 	REQUIRE(DNS_ZONE_VALID(zone));
13838 	REQUIRE(!ISC_LIST_EMPTY(*nsec3list));
13839 
13840 	dns_diff_init(zone->mctx, &diff);
13841 
13842 	/*
13843 	 * Loop through the list of private-type records, set the INITIAL
13844 	 * and CREATE flags, and the add the record to the apex of the tree
13845 	 * in db.
13846 	 */
13847 	for (nsec3p = ISC_LIST_HEAD(*nsec3list);
13848 	     nsec3p != NULL;
13849 	     nsec3p = next)
13850 	{
13851 		next = ISC_LIST_NEXT(nsec3p, link);
13852 		dns_rdata_init(&rdata);
13853 		nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL;
13854 		rdata.length = nsec3p->length;
13855 		rdata.data = nsec3p->data;
13856 		rdata.type = zone->privatetype;
13857 		rdata.rdclass = zone->rdclass;
13858 		CHECK(update_one_rr(db, version, &diff, DNS_DIFFOP_ADD,
13859 				    &zone->origin, 0, &rdata));
13860 	}
13861 
13862 	result = ISC_R_SUCCESS;
13863 
13864 failure:
13865 	for (nsec3p = ISC_LIST_HEAD(*nsec3list);
13866 	     nsec3p != NULL;
13867 	     nsec3p = next)
13868 	{
13869 		next = ISC_LIST_NEXT(nsec3p, link);
13870 		ISC_LIST_UNLINK(*nsec3list, nsec3p, link);
13871 		isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
13872 	}
13873 
13874 	dns_diff_clear(&diff);
13875 	return (result);
13876 }
13877 
13878 static void
receive_secure_db(isc_task_t * task,isc_event_t * event)13879 receive_secure_db(isc_task_t *task, isc_event_t *event) {
13880 	isc_result_t result;
13881 	dns_zone_t *zone;
13882 	dns_db_t *rawdb, *db = NULL;
13883 	dns_dbnode_t *rawnode = NULL, *node = NULL;
13884 	dns_fixedname_t fname;
13885 	dns_name_t *name;
13886 	dns_dbiterator_t *dbiterator = NULL;
13887 	dns_rdatasetiter_t *rdsit = NULL;
13888 	dns_rdataset_t rdataset;
13889 	dns_dbversion_t *version = NULL;
13890 	isc_time_t loadtime;
13891 	unsigned int oldserial = 0;
13892 	isc_boolean_t have_oldserial = ISC_FALSE;
13893 	nsec3paramlist_t nsec3list;
13894 
13895 	UNUSED(task);
13896 
13897 	ISC_LIST_INIT(nsec3list);
13898 
13899 	zone = event->ev_arg;
13900 	rawdb = ((struct secure_event *)event)->db;
13901 	isc_event_free(&event);
13902 
13903 	dns_fixedname_init(&fname);
13904 	name = dns_fixedname_name(&fname);
13905 	dns_rdataset_init(&rdataset);
13906 
13907 	LOCK_ZONE(zone);
13908 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) {
13909 		result = ISC_R_SHUTTINGDOWN;
13910 		goto failure;
13911 	}
13912 
13913 	TIME_NOW(&loadtime);
13914 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13915 	if (zone->db != NULL) {
13916 		result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
13917 		if (result == ISC_R_SUCCESS)
13918 			have_oldserial = ISC_TRUE;
13919 
13920 		/*
13921 		 * assemble nsec3parameters from the old zone, and set a flag
13922 		 * if any are found
13923 		 */
13924 		result = save_nsec3param(zone, &nsec3list);
13925 		if (result != ISC_R_SUCCESS) {
13926 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13927 			goto failure;
13928 		}
13929 	}
13930 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13931 
13932 	result = dns_db_create(zone->mctx, zone->db_argv[0],
13933 			       &zone->origin, dns_dbtype_zone, zone->rdclass,
13934 			       zone->db_argc - 1, zone->db_argv + 1, &db);
13935 	if (result != ISC_R_SUCCESS)
13936 		goto failure;
13937 
13938 	result = dns_db_newversion(db, &version);
13939 	if (result != ISC_R_SUCCESS)
13940 		goto failure;
13941 
13942 	result = dns_db_createiterator(rawdb, 0, &dbiterator);
13943 	if (result != ISC_R_SUCCESS)
13944 		goto failure;
13945 
13946 	for (result = dns_dbiterator_first(dbiterator);
13947 	     result == ISC_R_SUCCESS;
13948 	     result = dns_dbiterator_next(dbiterator)) {
13949 		result = dns_dbiterator_current(dbiterator, &rawnode, name);
13950 		if (result != ISC_R_SUCCESS)
13951 			continue;
13952 
13953 		result = dns_db_findnode(db, name, ISC_TRUE, &node);
13954 		if (result != ISC_R_SUCCESS)
13955 			goto failure;
13956 
13957 		result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit);
13958 		if (result != ISC_R_SUCCESS)
13959 			goto failure;
13960 
13961 		for (result = dns_rdatasetiter_first(rdsit);
13962 		     result == ISC_R_SUCCESS;
13963 		     result = dns_rdatasetiter_next(rdsit)) {
13964 			dns_rdatasetiter_current(rdsit, &rdataset);
13965 			if (rdataset.type == dns_rdatatype_nsec ||
13966 			    rdataset.type == dns_rdatatype_rrsig ||
13967 			    rdataset.type == dns_rdatatype_nsec3 ||
13968 			    rdataset.type == dns_rdatatype_dnskey ||
13969 			    rdataset.type == dns_rdatatype_nsec3param) {
13970 				dns_rdataset_disassociate(&rdataset);
13971 				continue;
13972 			}
13973 			if (rdataset.type == dns_rdatatype_soa &&
13974 			    have_oldserial) {
13975 				result = checkandaddsoa(db, node, version,
13976 							&rdataset, oldserial);
13977 			} else
13978 				result = dns_db_addrdataset(db, node, version,
13979 							    0, &rdataset, 0,
13980 							    NULL);
13981 			if (result != ISC_R_SUCCESS)
13982 				goto failure;
13983 
13984 			dns_rdataset_disassociate(&rdataset);
13985 		}
13986 		dns_rdatasetiter_destroy(&rdsit);
13987 		dns_db_detachnode(rawdb, &rawnode);
13988 		dns_db_detachnode(db, &node);
13989 	}
13990 
13991 	/*
13992 	 * Call restore_nsec3param() to create private-type records from
13993 	 * the old nsec3 parameters and insert them into db
13994 	 */
13995 	if (!ISC_LIST_EMPTY(nsec3list))
13996 		restore_nsec3param(zone, db, version, &nsec3list);
13997 
13998 	dns_db_closeversion(db, &version, ISC_TRUE);
13999 
14000 	/*
14001 	 * Lock hierarchy: zmgr, zone, raw.
14002 	 */
14003 	INSIST(zone != zone->raw);
14004 	LOCK_ZONE(zone->raw);
14005 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
14006 	result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
14007 	zone_needdump(zone, 0); /* XXXMPA */
14008 	UNLOCK_ZONE(zone->raw);
14009 
14010  failure:
14011 	UNLOCK_ZONE(zone);
14012 	if (result != ISC_R_SUCCESS)
14013 		dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
14014 			     dns_result_totext(result));
14015 
14016 	while (!ISC_LIST_EMPTY(nsec3list)) {
14017 		nsec3param_t *nsec3p;
14018 		nsec3p = ISC_LIST_HEAD(nsec3list);
14019 		ISC_LIST_UNLINK(nsec3list, nsec3p, link);
14020 		isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
14021 	}
14022 	if (dns_rdataset_isassociated(&rdataset))
14023 		dns_rdataset_disassociate(&rdataset);
14024 	if (db != NULL) {
14025 		if (node != NULL)
14026 			dns_db_detachnode(db, &node);
14027 		if (version != NULL)
14028 			dns_db_closeversion(db, &version, ISC_FALSE);
14029 		dns_db_detach(&db);
14030 	}
14031 	if (rawnode != NULL)
14032 		dns_db_detachnode(rawdb, &rawnode);
14033 	dns_db_detach(&rawdb);
14034 	if (dbiterator != NULL)
14035 		dns_dbiterator_destroy(&dbiterator);
14036 	dns_zone_idetach(&zone);
14037 
14038 	INSIST(version == NULL);
14039 }
14040 
14041 static isc_result_t
zone_send_securedb(dns_zone_t * zone,dns_db_t * db)14042 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) {
14043 	isc_event_t *e;
14044 	dns_db_t *dummy = NULL;
14045 	dns_zone_t *secure = NULL;
14046 
14047 	e = isc_event_allocate(zone->secure->mctx, zone,
14048 			       DNS_EVENT_ZONESECUREDB,
14049 			       receive_secure_db, zone->secure,
14050 			       sizeof(struct secure_event));
14051 	if (e == NULL)
14052 		return (ISC_R_NOMEMORY);
14053 	dns_db_attach(db, &dummy);
14054 	((struct secure_event *)e)->db = dummy;
14055 	INSIST(LOCKED_ZONE(zone->secure));
14056 	zone_iattach(zone->secure, &secure);
14057 	isc_task_send(zone->secure->task, &e);
14058 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
14059 	return (ISC_R_SUCCESS);
14060 }
14061 
14062 isc_result_t
dns_zone_replacedb(dns_zone_t * zone,dns_db_t * db,isc_boolean_t dump)14063 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
14064 	isc_result_t result;
14065 	dns_zone_t *secure = NULL;
14066 
14067 	REQUIRE(DNS_ZONE_VALID(zone));
14068  again:
14069 	LOCK_ZONE(zone);
14070 	if (inline_raw(zone)) {
14071 		secure = zone->secure;
14072 		INSIST(secure != zone);
14073 		TRYLOCK_ZONE(result, secure);
14074 		if (result != ISC_R_SUCCESS) {
14075 			UNLOCK_ZONE(zone);
14076 			secure = NULL;
14077 #if ISC_PLATFORM_USETHREADS
14078 			isc_thread_yield();
14079 #endif
14080 			goto again;
14081 		}
14082 	}
14083 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
14084 	result = zone_replacedb(zone, db, dump);
14085 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
14086 	if (secure != NULL)
14087 		UNLOCK_ZONE(secure);
14088 	UNLOCK_ZONE(zone);
14089 	return (result);
14090 }
14091 
14092 static isc_result_t
zone_replacedb(dns_zone_t * zone,dns_db_t * db,isc_boolean_t dump)14093 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
14094 	dns_dbversion_t *ver;
14095 	isc_result_t result;
14096 	unsigned int soacount = 0;
14097 	unsigned int nscount = 0;
14098 
14099 	/*
14100 	 * 'zone' and 'zonedb' locked by caller.
14101 	 */
14102 	REQUIRE(DNS_ZONE_VALID(zone));
14103 	REQUIRE(LOCKED_ZONE(zone));
14104 	if (inline_raw(zone))
14105 		REQUIRE(LOCKED_ZONE(zone->secure));
14106 
14107 	result = dns_db_rpz_ready(db);
14108 	if (result != ISC_R_SUCCESS)
14109 		return (result);
14110 
14111 	result = zone_get_from_db(zone, db, &nscount, &soacount,
14112 				  NULL, NULL, NULL, NULL, NULL, NULL);
14113 	if (result == ISC_R_SUCCESS) {
14114 		if (soacount != 1) {
14115 			dns_zone_log(zone, ISC_LOG_ERROR,
14116 				     "has %d SOA records", soacount);
14117 			result = DNS_R_BADZONE;
14118 		}
14119 		if (nscount == 0 && zone->type != dns_zone_key) {
14120 			dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
14121 			result = DNS_R_BADZONE;
14122 		}
14123 		if (result != ISC_R_SUCCESS)
14124 			return (result);
14125 	} else {
14126 		dns_zone_log(zone, ISC_LOG_ERROR,
14127 			    "retrieving SOA and NS records failed: %s",
14128 			    dns_result_totext(result));
14129 		return (result);
14130 	}
14131 
14132 	result = check_nsec3param(zone, db);
14133 	if (result != ISC_R_SUCCESS)
14134 		return (result);
14135 
14136 	ver = NULL;
14137 	dns_db_currentversion(db, &ver);
14138 
14139 	/*
14140 	 * The initial version of a slave zone is always dumped;
14141 	 * subsequent versions may be journaled instead if this
14142 	 * is enabled in the configuration.
14143 	 */
14144 	if (zone->db != NULL && zone->journal != NULL &&
14145 	    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
14146 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
14147 	{
14148 		isc_uint32_t serial, oldserial;
14149 
14150 		dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
14151 
14152 		result = dns_db_getsoaserial(db, ver, &serial);
14153 		if (result != ISC_R_SUCCESS) {
14154 			dns_zone_log(zone, ISC_LOG_ERROR,
14155 				     "ixfr-from-differences: unable to get "
14156 				     "new serial");
14157 			goto fail;
14158 		}
14159 
14160 		/*
14161 		 * This is checked in zone_postload() for master zones.
14162 		 */
14163 		result = zone_get_from_db(zone, zone->db, NULL, &soacount,
14164 					  &oldserial, NULL, NULL, NULL, NULL,
14165 					  NULL);
14166 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
14167 		RUNTIME_CHECK(soacount > 0U);
14168 		if ((zone->type == dns_zone_slave ||
14169 		     (zone->type == dns_zone_redirect &&
14170 		      zone->masters != NULL))
14171 		    && !isc_serial_gt(serial, oldserial)) {
14172 			isc_uint32_t serialmin, serialmax;
14173 			serialmin = (oldserial + 1) & 0xffffffffU;
14174 			serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
14175 			dns_zone_log(zone, ISC_LOG_ERROR,
14176 				     "ixfr-from-differences: failed: "
14177 				     "new serial (%u) out of range [%u - %u]",
14178 				     serial, serialmin, serialmax);
14179 			result = ISC_R_RANGE;
14180 			goto fail;
14181 		}
14182 
14183 		result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
14184 				     zone->journal);
14185 		if (result != ISC_R_SUCCESS)
14186 			goto fail;
14187 		if (dump)
14188 			zone_needdump(zone, DNS_DUMP_DELAY);
14189 		else if (zone->journalsize != -1) {
14190 			result = dns_journal_compact(zone->mctx, zone->journal,
14191 						     serial, zone->journalsize);
14192 			switch (result) {
14193 			case ISC_R_SUCCESS:
14194 			case ISC_R_NOSPACE:
14195 			case ISC_R_NOTFOUND:
14196 				dns_zone_log(zone, ISC_LOG_DEBUG(3),
14197 					     "dns_journal_compact: %s",
14198 					     dns_result_totext(result));
14199 				break;
14200 			default:
14201 				dns_zone_log(zone, ISC_LOG_ERROR,
14202 					     "dns_journal_compact failed: %s",
14203 					     dns_result_totext(result));
14204 				break;
14205 			}
14206 		}
14207 		if (zone->type == dns_zone_master && inline_raw(zone))
14208 			zone_send_secureserial(zone, serial);
14209 	} else {
14210 		if (dump && zone->masterfile != NULL) {
14211 			/*
14212 			 * If DNS_ZONEFLG_FORCEXFER was set we don't want
14213 			 * to keep the old masterfile.
14214 			 */
14215 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
14216 			    remove(zone->masterfile) < 0 && errno != ENOENT) {
14217 				char strbuf[ISC_STRERRORSIZE];
14218 				isc__strerror(errno, strbuf, sizeof(strbuf));
14219 				isc_log_write(dns_lctx,
14220 					      DNS_LOGCATEGORY_GENERAL,
14221 					      DNS_LOGMODULE_ZONE,
14222 					      ISC_LOG_WARNING,
14223 					      "unable to remove masterfile "
14224 					      "'%s': '%s'",
14225 					      zone->masterfile, strbuf);
14226 			}
14227 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
14228 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
14229 			else
14230 				zone_needdump(zone, 0);
14231 		}
14232 		if (dump && zone->journal != NULL) {
14233 			/*
14234 			 * The in-memory database just changed, and
14235 			 * because 'dump' is set, it didn't change by
14236 			 * being loaded from disk.  Also, we have not
14237 			 * journaled diffs for this change.
14238 			 * Therefore, the on-disk journal is missing
14239 			 * the deltas for this change.	Since it can
14240 			 * no longer be used to bring the zone
14241 			 * up-to-date, it is useless and should be
14242 			 * removed.
14243 			 */
14244 			isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
14245 				      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
14246 				      "removing journal file");
14247 			if (remove(zone->journal) < 0 && errno != ENOENT) {
14248 				char strbuf[ISC_STRERRORSIZE];
14249 				isc__strerror(errno, strbuf, sizeof(strbuf));
14250 				isc_log_write(dns_lctx,
14251 					      DNS_LOGCATEGORY_GENERAL,
14252 					      DNS_LOGMODULE_ZONE,
14253 					      ISC_LOG_WARNING,
14254 					      "unable to remove journal "
14255 					      "'%s': '%s'",
14256 					      zone->journal, strbuf);
14257 			}
14258 		}
14259 
14260 		if (inline_raw(zone))
14261 			zone_send_securedb(zone, db);
14262 	}
14263 
14264 	dns_db_closeversion(db, &ver, ISC_FALSE);
14265 
14266 	dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database");
14267 
14268 	if (zone->db != NULL)
14269 		zone_detachdb(zone);
14270 	zone_attachdb(zone, db);
14271 	dns_db_settask(zone->db, zone->task);
14272 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
14273 	return (ISC_R_SUCCESS);
14274 
14275  fail:
14276 	dns_db_closeversion(db, &ver, ISC_FALSE);
14277 	return (result);
14278 }
14279 
14280 /* The caller must hold the dblock as a writer. */
14281 static inline void
zone_attachdb(dns_zone_t * zone,dns_db_t * db)14282 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
14283 	REQUIRE(zone->db == NULL && db != NULL);
14284 
14285 	dns_db_attach(db, &zone->db);
14286 	if (zone->acache != NULL) {
14287 		isc_result_t result;
14288 		result = dns_acache_setdb(zone->acache, db);
14289 		if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
14290 			UNEXPECTED_ERROR(__FILE__, __LINE__,
14291 					 "dns_acache_setdb() failed: %s",
14292 					 isc_result_totext(result));
14293 		}
14294 	}
14295 }
14296 
14297 /* The caller must hold the dblock as a writer. */
14298 static inline void
zone_detachdb(dns_zone_t * zone)14299 zone_detachdb(dns_zone_t *zone) {
14300 	REQUIRE(zone->db != NULL);
14301 
14302 	if (zone->acache != NULL)
14303 		(void)dns_acache_putdb(zone->acache, zone->db);
14304 	dns_db_detach(&zone->db);
14305 }
14306 
14307 static void
zone_xfrdone(dns_zone_t * zone,isc_result_t result)14308 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
14309 	isc_time_t now;
14310 	isc_boolean_t again = ISC_FALSE;
14311 	unsigned int soacount;
14312 	unsigned int nscount;
14313 	isc_uint32_t serial, refresh, retry, expire, minimum;
14314 	isc_result_t xfrresult = result;
14315 	isc_boolean_t free_needed;
14316 	dns_zone_t *secure = NULL;
14317 
14318 	REQUIRE(DNS_ZONE_VALID(zone));
14319 
14320 	dns_zone_log(zone, ISC_LOG_DEBUG(1),
14321 		     "zone transfer finished: %s", dns_result_totext(result));
14322 
14323 	/*
14324 	 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
14325 	 * could result in a deadlock due to a LOR so we will spin if we
14326 	 * can't obtain the both locks.
14327 	 */
14328  again:
14329 	LOCK_ZONE(zone);
14330 	if (inline_raw(zone)) {
14331 		secure = zone->secure;
14332 		INSIST(secure != zone);
14333 		TRYLOCK_ZONE(result, secure);
14334 		if (result != ISC_R_SUCCESS) {
14335 			UNLOCK_ZONE(zone);
14336 			secure = NULL;
14337 #if ISC_PLATFORM_USETHREADS
14338 			isc_thread_yield();
14339 #endif
14340 			goto again;
14341 		}
14342 	}
14343 
14344 	INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
14345 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
14346 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
14347 
14348 	TIME_NOW(&now);
14349 	switch (result) {
14350 	case ISC_R_SUCCESS:
14351 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
14352 		/*FALLTHROUGH*/
14353 	case DNS_R_UPTODATE:
14354 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
14355 		/*
14356 		 * Has the zone expired underneath us?
14357 		 */
14358 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
14359 		if (zone->db == NULL) {
14360 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14361 			goto same_master;
14362 		}
14363 
14364 		/*
14365 		 * Update the zone structure's data from the actual
14366 		 * SOA received.
14367 		 */
14368 		nscount = 0;
14369 		soacount = 0;
14370 		INSIST(zone->db != NULL);
14371 		result = zone_get_from_db(zone, zone->db, &nscount,
14372 					  &soacount, &serial, &refresh,
14373 					  &retry, &expire, &minimum, NULL);
14374 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14375 		if (result == ISC_R_SUCCESS) {
14376 			if (soacount != 1)
14377 				dns_zone_log(zone, ISC_LOG_ERROR,
14378 					     "transferred zone "
14379 					     "has %d SOA record%s", soacount,
14380 					     (soacount != 0) ? "s" : "");
14381 			if (nscount == 0) {
14382 				dns_zone_log(zone, ISC_LOG_ERROR,
14383 					     "transferred zone "
14384 					     "has no NS records");
14385 				if (DNS_ZONE_FLAG(zone,
14386 						  DNS_ZONEFLG_HAVETIMERS)) {
14387 					zone->refresh = DNS_ZONE_DEFAULTREFRESH;
14388 					zone->retry = DNS_ZONE_DEFAULTRETRY;
14389 				}
14390 				DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
14391 				zone_unload(zone);
14392 				goto next_master;
14393 			}
14394 			zone->refresh = RANGE(refresh, zone->minrefresh,
14395 					      zone->maxrefresh);
14396 			zone->retry = RANGE(retry, zone->minretry,
14397 					    zone->maxretry);
14398 			zone->expire = RANGE(expire,
14399 					     zone->refresh + zone->retry,
14400 					     DNS_MAX_EXPIRE);
14401 			zone->minimum = minimum;
14402 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
14403 		}
14404 
14405 		/*
14406 		 * Set our next update/expire times.
14407 		 */
14408 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
14409 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
14410 			zone->refreshtime = now;
14411 			DNS_ZONE_TIME_ADD(&now, zone->expire,
14412 					  &zone->expiretime);
14413 		} else {
14414 			DNS_ZONE_JITTER_ADD(&now, zone->refresh,
14415 					    &zone->refreshtime);
14416 			DNS_ZONE_TIME_ADD(&now, zone->expire,
14417 					  &zone->expiretime);
14418 		}
14419 		if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
14420 			char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
14421 			if (zone->tsigkey != NULL) {
14422 				char namebuf[DNS_NAME_FORMATSIZE];
14423 				dns_name_format(&zone->tsigkey->name, namebuf,
14424 						sizeof(namebuf));
14425 				snprintf(buf, sizeof(buf), ": TSIG '%s'",
14426 					 namebuf);
14427 			} else
14428 				buf[0] = '\0';
14429 			dns_zone_log(zone, ISC_LOG_INFO,
14430 				     "transferred serial %u%s",
14431 				     serial, buf);
14432 			if (inline_raw(zone))
14433 				zone_send_secureserial(zone, serial);
14434 		}
14435 
14436 		/*
14437 		 * This is not necessary if we just performed a AXFR
14438 		 * however it is necessary for an IXFR / UPTODATE and
14439 		 * won't hurt with an AXFR.
14440 		 */
14441 		if (zone->masterfile != NULL || zone->journal != NULL) {
14442 			unsigned int delay = DNS_DUMP_DELAY;
14443 
14444 			result = ISC_R_FAILURE;
14445 			if (zone->journal != NULL)
14446 				result = isc_file_settime(zone->journal, &now);
14447 			if (result != ISC_R_SUCCESS &&
14448 			    zone->masterfile != NULL)
14449 				result = isc_file_settime(zone->masterfile,
14450 							  &now);
14451 
14452 			if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
14453 			    result == ISC_R_FILENOTFOUND)
14454 				delay = 0;
14455 
14456 			if ((result == ISC_R_SUCCESS ||
14457 			    result == ISC_R_FILENOTFOUND) &&
14458 			    zone->masterfile != NULL)
14459 				zone_needdump(zone, delay);
14460 			else if (result != ISC_R_SUCCESS)
14461 				dns_zone_log(zone, ISC_LOG_ERROR,
14462 					     "transfer: could not set file "
14463 					     "modification time of '%s': %s",
14464 					     zone->masterfile,
14465 					     dns_result_totext(result));
14466 		}
14467 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
14468 		inc_stats(zone, dns_zonestatscounter_xfrsuccess);
14469 		break;
14470 
14471 	case DNS_R_BADIXFR:
14472 		/* Force retry with AXFR. */
14473 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
14474 		goto same_master;
14475 
14476 	default:
14477 	next_master:
14478 		/*
14479 		 * Skip to next failed / untried master.
14480 		 */
14481 		do {
14482 			zone->curmaster++;
14483 		} while (zone->curmaster < zone->masterscnt &&
14484 			 zone->mastersok[zone->curmaster]);
14485 		/* FALLTHROUGH */
14486 	same_master:
14487 		if (zone->curmaster >= zone->masterscnt) {
14488 			zone->curmaster = 0;
14489 			if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
14490 			    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
14491 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
14492 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
14493 				while (zone->curmaster < zone->masterscnt &&
14494 				       zone->mastersok[zone->curmaster])
14495 					zone->curmaster++;
14496 				again = ISC_TRUE;
14497 			} else
14498 				DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
14499 		} else {
14500 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
14501 			again = ISC_TRUE;
14502 		}
14503 		inc_stats(zone, dns_zonestatscounter_xfrfail);
14504 		break;
14505 	}
14506 	zone_settimer(zone, &now);
14507 
14508 	/*
14509 	 * If creating the transfer object failed, zone->xfr is NULL.
14510 	 * Otherwise, we are called as the done callback of a zone
14511 	 * transfer object that just entered its shutting-down
14512 	 * state.  Since we are no longer responsible for shutting
14513 	 * it down, we can detach our reference.
14514 	 */
14515 	if (zone->xfr != NULL)
14516 		dns_xfrin_detach(&zone->xfr);
14517 
14518 	if (zone->tsigkey != NULL)
14519 		dns_tsigkey_detach(&zone->tsigkey);
14520 
14521 	/*
14522 	 * Handle any deferred journal compaction.
14523 	 */
14524 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
14525 		result = dns_journal_compact(zone->mctx, zone->journal,
14526 					     zone->compact_serial,
14527 					     zone->journalsize);
14528 		switch (result) {
14529 		case ISC_R_SUCCESS:
14530 		case ISC_R_NOSPACE:
14531 		case ISC_R_NOTFOUND:
14532 			dns_zone_log(zone, ISC_LOG_DEBUG(3),
14533 				     "dns_journal_compact: %s",
14534 				     dns_result_totext(result));
14535 			break;
14536 		default:
14537 			dns_zone_log(zone, ISC_LOG_ERROR,
14538 				     "dns_journal_compact failed: %s",
14539 				     dns_result_totext(result));
14540 			break;
14541 		}
14542 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
14543 	}
14544 
14545 	if (secure != NULL)
14546 		UNLOCK_ZONE(secure);
14547 	/*
14548 	 * This transfer finishing freed up a transfer quota slot.
14549 	 * Let any other zones waiting for quota have it.
14550 	 */
14551 	if (zone->zmgr != NULL &&
14552 	    zone->statelist == &zone->zmgr->xfrin_in_progress) {
14553 		UNLOCK_ZONE(zone);
14554 		RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
14555 		ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
14556 		zone->statelist = NULL;
14557 		zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
14558 		RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
14559 		LOCK_ZONE(zone);
14560 	}
14561 
14562 	/*
14563 	 * Retry with a different server if necessary.
14564 	 */
14565 	if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
14566 		queue_soa_query(zone);
14567 
14568 	INSIST(zone->irefs > 0);
14569 	zone->irefs--;
14570 	free_needed = exit_check(zone);
14571 	UNLOCK_ZONE(zone);
14572 	if (free_needed)
14573 		zone_free(zone);
14574 }
14575 
14576 static void
zone_loaddone(void * arg,isc_result_t result)14577 zone_loaddone(void *arg, isc_result_t result) {
14578 	static char me[] = "zone_loaddone";
14579 	dns_load_t *load = arg;
14580 	dns_zone_t *zone;
14581 	isc_result_t tresult;
14582 	dns_zone_t *secure = NULL;
14583 
14584 	REQUIRE(DNS_LOAD_VALID(load));
14585 	zone = load->zone;
14586 
14587 	ENTER;
14588 
14589 	tresult = dns_db_endload(load->db, &load->callbacks);
14590 	if (tresult != ISC_R_SUCCESS &&
14591 	    (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
14592 		result = tresult;
14593 
14594 	/*
14595 	 * Lock hierarchy: zmgr, zone, raw.
14596 	 */
14597  again:
14598 	LOCK_ZONE(zone);
14599 	INSIST(zone != zone->raw);
14600 	if (inline_secure(zone))
14601 		LOCK_ZONE(zone->raw);
14602 	else if (inline_raw(zone)) {
14603 		secure = zone->secure;
14604 		TRYLOCK_ZONE(result, secure);
14605 		if (result != ISC_R_SUCCESS) {
14606 			UNLOCK_ZONE(zone);
14607 			secure = NULL;
14608 #if ISC_PLATFORM_USETHREADS
14609 			isc_thread_yield();
14610 #endif
14611 			goto again;
14612 		}
14613 	}
14614 	(void)zone_postload(zone, load->db, load->loadtime, result);
14615 	zonemgr_putio(&zone->readio);
14616 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING);
14617 	zone_idetach(&load->callbacks.zone);
14618 	/*
14619 	 * Leave the zone frozen if the reload fails.
14620 	 */
14621 	if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
14622 	     DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW))
14623 		zone->update_disabled = ISC_FALSE;
14624 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW);
14625 	if (inline_secure(zone))
14626 		UNLOCK_ZONE(zone->raw);
14627 	else if (secure != NULL)
14628 		UNLOCK_ZONE(secure);
14629 	UNLOCK_ZONE(zone);
14630 
14631 	load->magic = 0;
14632 	dns_db_detach(&load->db);
14633 	if (load->zone->lctx != NULL)
14634 		dns_loadctx_detach(&load->zone->lctx);
14635 	dns_zone_idetach(&load->zone);
14636 	isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
14637 }
14638 
14639 void
dns_zone_getssutable(dns_zone_t * zone,dns_ssutable_t ** table)14640 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
14641 	REQUIRE(DNS_ZONE_VALID(zone));
14642 	REQUIRE(table != NULL);
14643 	REQUIRE(*table == NULL);
14644 
14645 	LOCK_ZONE(zone);
14646 	if (zone->ssutable != NULL)
14647 		dns_ssutable_attach(zone->ssutable, table);
14648 	UNLOCK_ZONE(zone);
14649 }
14650 
14651 void
dns_zone_setssutable(dns_zone_t * zone,dns_ssutable_t * table)14652 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
14653 	REQUIRE(DNS_ZONE_VALID(zone));
14654 
14655 	LOCK_ZONE(zone);
14656 	if (zone->ssutable != NULL)
14657 		dns_ssutable_detach(&zone->ssutable);
14658 	if (table != NULL)
14659 		dns_ssutable_attach(table, &zone->ssutable);
14660 	UNLOCK_ZONE(zone);
14661 }
14662 
14663 void
dns_zone_setsigvalidityinterval(dns_zone_t * zone,isc_uint32_t interval)14664 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
14665 	REQUIRE(DNS_ZONE_VALID(zone));
14666 
14667 	zone->sigvalidityinterval = interval;
14668 }
14669 
14670 isc_uint32_t
dns_zone_getsigvalidityinterval(dns_zone_t * zone)14671 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
14672 	REQUIRE(DNS_ZONE_VALID(zone));
14673 
14674 	return (zone->sigvalidityinterval);
14675 }
14676 
14677 void
dns_zone_setsigresigninginterval(dns_zone_t * zone,isc_uint32_t interval)14678 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
14679 	isc_time_t now;
14680 
14681 	REQUIRE(DNS_ZONE_VALID(zone));
14682 
14683 	LOCK_ZONE(zone);
14684 	zone->sigresigninginterval = interval;
14685 	set_resigntime(zone);
14686 	if (zone->task != NULL) {
14687 		TIME_NOW(&now);
14688 		zone_settimer(zone, &now);
14689 	}
14690 	UNLOCK_ZONE(zone);
14691 }
14692 
14693 isc_uint32_t
dns_zone_getsigresigninginterval(dns_zone_t * zone)14694 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
14695 	REQUIRE(DNS_ZONE_VALID(zone));
14696 
14697 	return (zone->sigresigninginterval);
14698 }
14699 
14700 static void
queue_xfrin(dns_zone_t * zone)14701 queue_xfrin(dns_zone_t *zone) {
14702 	const char me[] = "queue_xfrin";
14703 	isc_result_t result;
14704 	dns_zonemgr_t *zmgr = zone->zmgr;
14705 
14706 	ENTER;
14707 
14708 	INSIST(zone->statelist == NULL);
14709 
14710 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14711 	ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
14712 	LOCK_ZONE(zone);
14713 	zone->irefs++;
14714 	UNLOCK_ZONE(zone);
14715 	zone->statelist = &zmgr->waiting_for_xfrin;
14716 	result = zmgr_start_xfrin_ifquota(zmgr, zone);
14717 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
14718 
14719 	if (result == ISC_R_QUOTA) {
14720 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
14721 			      "zone transfer deferred due to quota");
14722 	} else if (result != ISC_R_SUCCESS) {
14723 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
14724 			      "starting zone transfer: %s",
14725 			      isc_result_totext(result));
14726 	}
14727 }
14728 
14729 /*
14730  * This event callback is called when a zone has received
14731  * any necessary zone transfer quota.  This is the time
14732  * to go ahead and start the transfer.
14733  */
14734 static void
got_transfer_quota(isc_task_t * task,isc_event_t * event)14735 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
14736 	isc_result_t result = ISC_R_SUCCESS;
14737 	dns_peer_t *peer = NULL;
14738 	char master[ISC_SOCKADDR_FORMATSIZE];
14739 	char source[ISC_SOCKADDR_FORMATSIZE];
14740 	dns_rdatatype_t xfrtype;
14741 	dns_zone_t *zone = event->ev_arg;
14742 	isc_netaddr_t masterip;
14743 	isc_sockaddr_t sourceaddr;
14744 	isc_sockaddr_t masteraddr;
14745 	isc_time_t now;
14746 	const char *soa_before = "";
14747 	isc_dscp_t dscp = -1;
14748 	isc_boolean_t loaded;
14749 
14750 	UNUSED(task);
14751 
14752 	INSIST(task == zone->task);
14753 
14754 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
14755 		result = ISC_R_CANCELED;
14756 		goto cleanup;
14757 	}
14758 
14759 	TIME_NOW(&now);
14760 
14761 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
14762 	if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
14763 				    &zone->sourceaddr, &now))
14764 	{
14765 		isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
14766 		dns_zone_log(zone, ISC_LOG_INFO,
14767 			     "got_transfer_quota: skipping zone transfer as "
14768 			     "master %s (source %s) is unreachable (cached)",
14769 			     master, source);
14770 		result = ISC_R_CANCELED;
14771 		goto cleanup;
14772 	}
14773 
14774 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
14775 	(void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
14776 
14777 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
14778 		soa_before = "SOA before ";
14779 	/*
14780 	 * Decide whether we should request IXFR or AXFR.
14781 	 */
14782 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
14783 	loaded = ISC_TF(zone->db != NULL);
14784 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14785 
14786 	if (!loaded) {
14787 		dns_zone_log(zone, ISC_LOG_DEBUG(1),
14788 			     "no database exists yet, requesting AXFR of "
14789 			     "initial version from %s", master);
14790 		xfrtype = dns_rdatatype_axfr;
14791 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
14792 		dns_zone_log(zone, ISC_LOG_DEBUG(1),
14793 			     "forced reload, requesting AXFR of "
14794 			     "initial version from %s", master);
14795 		xfrtype = dns_rdatatype_axfr;
14796 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
14797 		dns_zone_log(zone, ISC_LOG_DEBUG(1),
14798 			     "retrying with AXFR from %s due to "
14799 			     "previous IXFR failure", master);
14800 		xfrtype = dns_rdatatype_axfr;
14801 		LOCK_ZONE(zone);
14802 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
14803 		UNLOCK_ZONE(zone);
14804 	} else {
14805 		isc_boolean_t use_ixfr = ISC_TRUE;
14806 		if (peer != NULL)
14807 			result = dns_peer_getrequestixfr(peer, &use_ixfr);
14808 		if (peer == NULL || result != ISC_R_SUCCESS)
14809 			use_ixfr = zone->requestixfr;
14810 		if (use_ixfr == ISC_FALSE) {
14811 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
14812 				     "IXFR disabled, requesting %sAXFR from %s",
14813 				     soa_before, master);
14814 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
14815 				xfrtype = dns_rdatatype_soa;
14816 			else
14817 				xfrtype = dns_rdatatype_axfr;
14818 		} else {
14819 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
14820 				     "requesting IXFR from %s", master);
14821 			xfrtype = dns_rdatatype_ixfr;
14822 		}
14823 	}
14824 
14825 	/*
14826 	 * Determine if we should attempt to sign the request with TSIG.
14827 	 */
14828 	result = ISC_R_NOTFOUND;
14829 
14830 	/*
14831 	 * First, look for a tsig key in the master statement, then
14832 	 * try for a server key.
14833 	 */
14834 	if ((zone->masterkeynames != NULL) &&
14835 	    (zone->masterkeynames[zone->curmaster] != NULL)) {
14836 		dns_view_t *view = dns_zone_getview(zone);
14837 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
14838 		result = dns_view_gettsig(view, keyname, &zone->tsigkey);
14839 	}
14840 	if (zone->tsigkey == NULL)
14841 		result = dns_view_getpeertsig(zone->view, &masterip,
14842 					      &zone->tsigkey);
14843 
14844 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
14845 		dns_zone_log(zone, ISC_LOG_ERROR,
14846 			     "could not get TSIG key for zone transfer: %s",
14847 			     isc_result_totext(result));
14848 	}
14849 
14850 	if (zone->masterdscps != NULL)
14851 	    dscp = zone->masterdscps[zone->curmaster];
14852 
14853 	LOCK_ZONE(zone);
14854 	masteraddr = zone->masteraddr;
14855 	sourceaddr = zone->sourceaddr;
14856 	switch (isc_sockaddr_pf(&masteraddr)) {
14857 	case PF_INET:
14858 		if (dscp == -1)
14859 			dscp = zone->xfrsource4dscp;
14860 		break;
14861 	case PF_INET6:
14862 		if (dscp == -1)
14863 			dscp = zone->xfrsource6dscp;
14864 		break;
14865 	default:
14866 		INSIST(0);
14867 	};
14868 	UNLOCK_ZONE(zone);
14869 	INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
14870 	result = dns_xfrin_create3(zone, xfrtype, &masteraddr, &sourceaddr,
14871 				   dscp, zone->tsigkey, zone->mctx,
14872 				   zone->zmgr->timermgr, zone->zmgr->socketmgr,
14873 				   zone->task, zone_xfrdone, &zone->xfr);
14874 	if (result == ISC_R_SUCCESS) {
14875 		LOCK_ZONE(zone);
14876 		if (xfrtype == dns_rdatatype_axfr) {
14877 			if (isc_sockaddr_pf(&masteraddr) == PF_INET)
14878 				inc_stats(zone, dns_zonestatscounter_axfrreqv4);
14879 			else
14880 				inc_stats(zone, dns_zonestatscounter_axfrreqv6);
14881 		} else if (xfrtype == dns_rdatatype_ixfr) {
14882 			if (isc_sockaddr_pf(&masteraddr) == PF_INET)
14883 				inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
14884 			else
14885 				inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
14886 		}
14887 		UNLOCK_ZONE(zone);
14888 	}
14889  cleanup:
14890 	/*
14891 	 * Any failure in this function is handled like a failed
14892 	 * zone transfer.  This ensures that we get removed from
14893 	 * zmgr->xfrin_in_progress.
14894 	 */
14895 	if (result != ISC_R_SUCCESS)
14896 		zone_xfrdone(zone, result);
14897 
14898 	isc_event_free(&event);
14899 }
14900 
14901 /*
14902  * Update forwarding support.
14903  */
14904 
14905 static void
forward_destroy(dns_forward_t * forward)14906 forward_destroy(dns_forward_t *forward) {
14907 
14908 	forward->magic = 0;
14909 	if (forward->request != NULL)
14910 		dns_request_destroy(&forward->request);
14911 	if (forward->msgbuf != NULL)
14912 		isc_buffer_free(&forward->msgbuf);
14913 	if (forward->zone != NULL) {
14914 		LOCK(&forward->zone->lock);
14915 		if (ISC_LINK_LINKED(forward, link))
14916 			ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
14917 		UNLOCK(&forward->zone->lock);
14918 		dns_zone_idetach(&forward->zone);
14919 	}
14920 	isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
14921 }
14922 
14923 static isc_result_t
sendtomaster(dns_forward_t * forward)14924 sendtomaster(dns_forward_t *forward) {
14925 	isc_result_t result;
14926 	isc_sockaddr_t src;
14927 	isc_dscp_t dscp = -1;
14928 
14929 	LOCK_ZONE(forward->zone);
14930 
14931 	if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
14932 		UNLOCK_ZONE(forward->zone);
14933 		return (ISC_R_CANCELED);
14934 	}
14935 
14936 	if (forward->which >= forward->zone->masterscnt) {
14937 		UNLOCK_ZONE(forward->zone);
14938 		return (ISC_R_NOMORE);
14939 	}
14940 
14941 	forward->addr = forward->zone->masters[forward->which];
14942 	/*
14943 	 * Always use TCP regardless of whether the original update
14944 	 * used TCP.
14945 	 * XXX The timeout may but a bit small if we are far down a
14946 	 * transfer graph and the master has to try several masters.
14947 	 */
14948 	switch (isc_sockaddr_pf(&forward->addr)) {
14949 	case PF_INET:
14950 		src = forward->zone->xfrsource4;
14951 		dscp = forward->zone->xfrsource4dscp;
14952 		break;
14953 	case PF_INET6:
14954 		src = forward->zone->xfrsource6;
14955 		dscp = forward->zone->xfrsource6dscp;
14956 		break;
14957 	default:
14958 		result = ISC_R_NOTIMPLEMENTED;
14959 		goto unlock;
14960 	}
14961 	result = dns_request_createraw4(forward->zone->view->requestmgr,
14962 					forward->msgbuf,
14963 					&src, &forward->addr, dscp,
14964 					forward->options, 15 /* XXX */,
14965 					0, 0, forward->zone->task,
14966 					forward_callback, forward,
14967 					&forward->request);
14968 	if (result == ISC_R_SUCCESS) {
14969 		if (!ISC_LINK_LINKED(forward, link))
14970 			ISC_LIST_APPEND(forward->zone->forwards, forward, link);
14971 	}
14972 
14973  unlock:
14974 	UNLOCK_ZONE(forward->zone);
14975 	return (result);
14976 }
14977 
14978 static void
forward_callback(isc_task_t * task,isc_event_t * event)14979 forward_callback(isc_task_t *task, isc_event_t *event) {
14980 	const char me[] = "forward_callback";
14981 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
14982 	dns_message_t *msg = NULL;
14983 	char master[ISC_SOCKADDR_FORMATSIZE];
14984 	isc_result_t result;
14985 	dns_forward_t *forward;
14986 	dns_zone_t *zone;
14987 
14988 	UNUSED(task);
14989 
14990 	forward = revent->ev_arg;
14991 	INSIST(DNS_FORWARD_VALID(forward));
14992 	zone = forward->zone;
14993 	INSIST(DNS_ZONE_VALID(zone));
14994 
14995 	ENTER;
14996 
14997 	isc_sockaddr_format(&forward->addr, master, sizeof(master));
14998 
14999 	if (revent->result != ISC_R_SUCCESS) {
15000 		dns_zone_log(zone, ISC_LOG_INFO,
15001 			     "could not forward dynamic update to %s: %s",
15002 			     master, dns_result_totext(revent->result));
15003 		goto next_master;
15004 	}
15005 
15006 	result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
15007 	if (result != ISC_R_SUCCESS)
15008 		goto next_master;
15009 
15010 	result = dns_request_getresponse(revent->request, msg,
15011 					 DNS_MESSAGEPARSE_PRESERVEORDER |
15012 					 DNS_MESSAGEPARSE_CLONEBUFFER);
15013 	if (result != ISC_R_SUCCESS)
15014 		goto next_master;
15015 
15016 	switch (msg->rcode) {
15017 	/*
15018 	 * Pass these rcodes back to client.
15019 	 */
15020 	case dns_rcode_noerror:
15021 	case dns_rcode_yxdomain:
15022 	case dns_rcode_yxrrset:
15023 	case dns_rcode_nxrrset:
15024 	case dns_rcode_refused:
15025 	case dns_rcode_nxdomain: {
15026 		char rcode[128];
15027 		isc_buffer_t rb;
15028 
15029 		isc_buffer_init(&rb, rcode, sizeof(rcode));
15030 		(void)dns_rcode_totext(msg->rcode, &rb);
15031 		dns_zone_log(zone, ISC_LOG_INFO,
15032 			     "forwarded dynamic update: "
15033 			     "master %s returned: %.*s",
15034 			     master, (int)rb.used, rcode);
15035 		break;
15036 	}
15037 
15038 	/* These should not occur if the masters/zone are valid. */
15039 	case dns_rcode_notzone:
15040 	case dns_rcode_notauth: {
15041 		char rcode[128];
15042 		isc_buffer_t rb;
15043 
15044 		isc_buffer_init(&rb, rcode, sizeof(rcode));
15045 		(void)dns_rcode_totext(msg->rcode, &rb);
15046 		dns_zone_log(zone, ISC_LOG_WARNING,
15047 			     "forwarding dynamic update: "
15048 			     "unexpected response: master %s returned: %.*s",
15049 			     master, (int)rb.used, rcode);
15050 		goto next_master;
15051 	}
15052 
15053 	/* Try another server for these rcodes. */
15054 	case dns_rcode_formerr:
15055 	case dns_rcode_servfail:
15056 	case dns_rcode_notimp:
15057 	case dns_rcode_badvers:
15058 	default:
15059 		goto next_master;
15060 	}
15061 
15062 	/* call callback */
15063 	(forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
15064 	msg = NULL;
15065 	dns_request_destroy(&forward->request);
15066 	forward_destroy(forward);
15067 	isc_event_free(&event);
15068 	return;
15069 
15070  next_master:
15071 	if (msg != NULL)
15072 		dns_message_destroy(&msg);
15073 	isc_event_free(&event);
15074 	forward->which++;
15075 	dns_request_destroy(&forward->request);
15076 	result = sendtomaster(forward);
15077 	if (result != ISC_R_SUCCESS) {
15078 		/* call callback */
15079 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
15080 			     "exhausted dynamic update forwarder list");
15081 		(forward->callback)(forward->callback_arg, result, NULL);
15082 		forward_destroy(forward);
15083 	}
15084 }
15085 
15086 isc_result_t
dns_zone_forwardupdate(dns_zone_t * zone,dns_message_t * msg,dns_updatecallback_t callback,void * callback_arg)15087 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
15088 		       dns_updatecallback_t callback, void *callback_arg)
15089 {
15090 	dns_forward_t *forward;
15091 	isc_result_t result;
15092 	isc_region_t *mr;
15093 
15094 	REQUIRE(DNS_ZONE_VALID(zone));
15095 	REQUIRE(msg != NULL);
15096 	REQUIRE(callback != NULL);
15097 
15098 	forward = isc_mem_get(zone->mctx, sizeof(*forward));
15099 	if (forward == NULL)
15100 		return (ISC_R_NOMEMORY);
15101 
15102 	forward->request = NULL;
15103 	forward->zone = NULL;
15104 	forward->msgbuf = NULL;
15105 	forward->which = 0;
15106 	forward->mctx = 0;
15107 	forward->callback = callback;
15108 	forward->callback_arg = callback_arg;
15109 	ISC_LINK_INIT(forward, link);
15110 	forward->magic = FORWARD_MAGIC;
15111 	forward->options = DNS_REQUESTOPT_TCP;
15112 	/*
15113 	 * If we have a SIG(0) signed message we need to preserve the
15114 	 * query id as that is included in the SIG(0) computation.
15115 	 */
15116 	if (msg->sig0 != NULL)
15117 		forward->options |= DNS_REQUESTOPT_FIXEDID;
15118 
15119 	mr = dns_message_getrawmessage(msg);
15120 	if (mr == NULL) {
15121 		result = ISC_R_UNEXPECTEDEND;
15122 		goto cleanup;
15123 	}
15124 
15125 	result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
15126 	if (result != ISC_R_SUCCESS)
15127 		goto cleanup;
15128 	result = isc_buffer_copyregion(forward->msgbuf, mr);
15129 	if (result != ISC_R_SUCCESS)
15130 		goto cleanup;
15131 
15132 	isc_mem_attach(zone->mctx, &forward->mctx);
15133 	dns_zone_iattach(zone, &forward->zone);
15134 	result = sendtomaster(forward);
15135 
15136  cleanup:
15137 	if (result != ISC_R_SUCCESS) {
15138 		forward_destroy(forward);
15139 	}
15140 	return (result);
15141 }
15142 
15143 isc_result_t
dns_zone_next(dns_zone_t * zone,dns_zone_t ** next)15144 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
15145 	REQUIRE(DNS_ZONE_VALID(zone));
15146 	REQUIRE(next != NULL && *next == NULL);
15147 
15148 	*next = ISC_LIST_NEXT(zone, link);
15149 	if (*next == NULL)
15150 		return (ISC_R_NOMORE);
15151 	else
15152 		return (ISC_R_SUCCESS);
15153 }
15154 
15155 isc_result_t
dns_zone_first(dns_zonemgr_t * zmgr,dns_zone_t ** first)15156 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
15157 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15158 	REQUIRE(first != NULL && *first == NULL);
15159 
15160 	*first = ISC_LIST_HEAD(zmgr->zones);
15161 	if (*first == NULL)
15162 		return (ISC_R_NOMORE);
15163 	else
15164 		return (ISC_R_SUCCESS);
15165 }
15166 
15167 /***
15168  ***	Zone manager.
15169  ***/
15170 
15171 isc_result_t
dns_zonemgr_create(isc_mem_t * mctx,isc_taskmgr_t * taskmgr,isc_timermgr_t * timermgr,isc_socketmgr_t * socketmgr,dns_zonemgr_t ** zmgrp)15172 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
15173 		   isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
15174 		   dns_zonemgr_t **zmgrp)
15175 {
15176 	dns_zonemgr_t *zmgr;
15177 	isc_result_t result;
15178 
15179 	zmgr = isc_mem_get(mctx, sizeof(*zmgr));
15180 	if (zmgr == NULL)
15181 		return (ISC_R_NOMEMORY);
15182 	zmgr->mctx = NULL;
15183 	zmgr->refs = 1;
15184 	isc_mem_attach(mctx, &zmgr->mctx);
15185 	zmgr->taskmgr = taskmgr;
15186 	zmgr->timermgr = timermgr;
15187 	zmgr->socketmgr = socketmgr;
15188 	zmgr->zonetasks = NULL;
15189 	zmgr->loadtasks = NULL;
15190 	zmgr->mctxpool = NULL;
15191 	zmgr->task = NULL;
15192 	zmgr->notifyrl = NULL;
15193 	zmgr->refreshrl = NULL;
15194 	zmgr->startupnotifyrl = NULL;
15195 	zmgr->startuprefreshrl = NULL;
15196 	ISC_LIST_INIT(zmgr->zones);
15197 	ISC_LIST_INIT(zmgr->waiting_for_xfrin);
15198 	ISC_LIST_INIT(zmgr->xfrin_in_progress);
15199 	memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
15200 	result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
15201 	if (result != ISC_R_SUCCESS)
15202 		goto free_mem;
15203 
15204 	zmgr->transfersin = 10;
15205 	zmgr->transfersperns = 2;
15206 
15207 	/* Unreachable lock. */
15208 	result = isc_rwlock_init(&zmgr->urlock, 0, 0);
15209 	if (result != ISC_R_SUCCESS)
15210 		goto free_rwlock;
15211 
15212 	/* Create a single task for queueing of SOA queries. */
15213 	result = isc_task_create(taskmgr, 1, &zmgr->task);
15214 	if (result != ISC_R_SUCCESS)
15215 		goto free_urlock;
15216 
15217 	isc_task_setname(zmgr->task, "zmgr", zmgr);
15218 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
15219 					&zmgr->notifyrl);
15220 	if (result != ISC_R_SUCCESS)
15221 		goto free_task;
15222 
15223 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
15224 					&zmgr->refreshrl);
15225 	if (result != ISC_R_SUCCESS)
15226 		goto free_notifyrl;
15227 
15228 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
15229 					&zmgr->startupnotifyrl);
15230 	if (result != ISC_R_SUCCESS)
15231 		goto free_refreshrl;
15232 
15233 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
15234 					&zmgr->startuprefreshrl);
15235 	if (result != ISC_R_SUCCESS)
15236 		goto free_startupnotifyrl;
15237 
15238 	/* default to 20 refresh queries / notifies per second. */
15239 	setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
15240 	setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
15241 	setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20);
15242 	setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20);
15243 
15244 	zmgr->iolimit = 1;
15245 	zmgr->ioactive = 0;
15246 	ISC_LIST_INIT(zmgr->high);
15247 	ISC_LIST_INIT(zmgr->low);
15248 
15249 	result = isc_mutex_init(&zmgr->iolock);
15250 	if (result != ISC_R_SUCCESS)
15251 		goto free_startuprefreshrl;
15252 
15253 	zmgr->magic = ZONEMGR_MAGIC;
15254 
15255 	*zmgrp = zmgr;
15256 	return (ISC_R_SUCCESS);
15257 
15258 #if 0
15259  free_iolock:
15260 	DESTROYLOCK(&zmgr->iolock);
15261 #endif
15262  free_startuprefreshrl:
15263 	isc_ratelimiter_detach(&zmgr->startuprefreshrl);
15264  free_startupnotifyrl:
15265 	isc_ratelimiter_detach(&zmgr->startupnotifyrl);
15266  free_refreshrl:
15267 	isc_ratelimiter_detach(&zmgr->refreshrl);
15268  free_notifyrl:
15269 	isc_ratelimiter_detach(&zmgr->notifyrl);
15270  free_task:
15271 	isc_task_detach(&zmgr->task);
15272  free_urlock:
15273 	isc_rwlock_destroy(&zmgr->urlock);
15274  free_rwlock:
15275 	isc_rwlock_destroy(&zmgr->rwlock);
15276  free_mem:
15277 	isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
15278 	isc_mem_detach(&mctx);
15279 	return (result);
15280 }
15281 
15282 isc_result_t
dns_zonemgr_createzone(dns_zonemgr_t * zmgr,dns_zone_t ** zonep)15283 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
15284 	isc_result_t result;
15285 	isc_mem_t *mctx = NULL;
15286 	dns_zone_t *zone = NULL;
15287 	void *item;
15288 
15289 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15290 	REQUIRE(zonep != NULL && *zonep == NULL);
15291 
15292 	if (zmgr->mctxpool == NULL)
15293 		return (ISC_R_FAILURE);
15294 
15295 	item = isc_pool_get(zmgr->mctxpool);
15296 	if (item == NULL)
15297 		return (ISC_R_FAILURE);
15298 
15299 	isc_mem_attach((isc_mem_t *) item, &mctx);
15300 	result = dns_zone_create(&zone, mctx);
15301 	isc_mem_detach(&mctx);
15302 
15303 	if (result == ISC_R_SUCCESS)
15304 		*zonep = zone;
15305 
15306 	return (result);
15307 }
15308 
15309 isc_result_t
dns_zonemgr_managezone(dns_zonemgr_t * zmgr,dns_zone_t * zone)15310 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
15311 	isc_result_t result;
15312 
15313 	REQUIRE(DNS_ZONE_VALID(zone));
15314 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15315 
15316 	if (zmgr->zonetasks == NULL)
15317 		return (ISC_R_FAILURE);
15318 
15319 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15320 	LOCK_ZONE(zone);
15321 	REQUIRE(zone->task == NULL);
15322 	REQUIRE(zone->timer == NULL);
15323 	REQUIRE(zone->zmgr == NULL);
15324 
15325 	isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
15326 	isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
15327 
15328 	/*
15329 	 * Set the task name.  The tag will arbitrarily point to one
15330 	 * of the zones sharing the task (in practice, the one
15331 	 * to be managed last).
15332 	 */
15333 	isc_task_setname(zone->task, "zone", zone);
15334 	isc_task_setname(zone->loadtask, "loadzone", zone);
15335 
15336 	result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
15337 				  NULL, NULL,
15338 				  zone->task, zone_timer, zone,
15339 				  &zone->timer);
15340 
15341 	if (result != ISC_R_SUCCESS)
15342 		goto cleanup_tasks;
15343 
15344 	/*
15345 	 * The timer "holds" a iref.
15346 	 */
15347 	zone->irefs++;
15348 	INSIST(zone->irefs != 0);
15349 
15350 	ISC_LIST_APPEND(zmgr->zones, zone, link);
15351 	zone->zmgr = zmgr;
15352 	zmgr->refs++;
15353 
15354 	goto unlock;
15355 
15356  cleanup_tasks:
15357 	isc_task_detach(&zone->loadtask);
15358 	isc_task_detach(&zone->task);
15359 
15360  unlock:
15361 	UNLOCK_ZONE(zone);
15362 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15363 	return (result);
15364 }
15365 
15366 void
dns_zonemgr_releasezone(dns_zonemgr_t * zmgr,dns_zone_t * zone)15367 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
15368 	isc_boolean_t free_now = ISC_FALSE;
15369 
15370 	REQUIRE(DNS_ZONE_VALID(zone));
15371 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15372 	REQUIRE(zone->zmgr == zmgr);
15373 
15374 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15375 	LOCK_ZONE(zone);
15376 
15377 	ISC_LIST_UNLINK(zmgr->zones, zone, link);
15378 	zone->zmgr = NULL;
15379 	zmgr->refs--;
15380 	if (zmgr->refs == 0)
15381 		free_now = ISC_TRUE;
15382 
15383 	UNLOCK_ZONE(zone);
15384 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15385 
15386 	if (free_now)
15387 		zonemgr_free(zmgr);
15388 	ENSURE(zone->zmgr == NULL);
15389 }
15390 
15391 void
dns_zonemgr_attach(dns_zonemgr_t * source,dns_zonemgr_t ** target)15392 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
15393 	REQUIRE(DNS_ZONEMGR_VALID(source));
15394 	REQUIRE(target != NULL && *target == NULL);
15395 
15396 	RWLOCK(&source->rwlock, isc_rwlocktype_write);
15397 	REQUIRE(source->refs > 0);
15398 	source->refs++;
15399 	INSIST(source->refs > 0);
15400 	RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
15401 	*target = source;
15402 }
15403 
15404 void
dns_zonemgr_detach(dns_zonemgr_t ** zmgrp)15405 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
15406 	dns_zonemgr_t *zmgr;
15407 	isc_boolean_t free_now = ISC_FALSE;
15408 
15409 	REQUIRE(zmgrp != NULL);
15410 	zmgr = *zmgrp;
15411 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15412 
15413 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15414 	zmgr->refs--;
15415 	if (zmgr->refs == 0)
15416 		free_now = ISC_TRUE;
15417 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15418 
15419 	if (free_now)
15420 		zonemgr_free(zmgr);
15421 	*zmgrp = NULL;
15422 }
15423 
15424 isc_result_t
dns_zonemgr_forcemaint(dns_zonemgr_t * zmgr)15425 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
15426 	dns_zone_t *p;
15427 
15428 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15429 
15430 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15431 	for (p = ISC_LIST_HEAD(zmgr->zones);
15432 	     p != NULL;
15433 	     p = ISC_LIST_NEXT(p, link))
15434 	{
15435 		dns_zone_maintenance(p);
15436 	}
15437 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15438 
15439 	/*
15440 	 * Recent configuration changes may have increased the
15441 	 * amount of available transfers quota.  Make sure any
15442 	 * transfers currently blocked on quota get started if
15443 	 * possible.
15444 	 */
15445 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15446 	zmgr_resume_xfrs(zmgr, ISC_TRUE);
15447 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15448 	return (ISC_R_SUCCESS);
15449 }
15450 
15451 void
dns_zonemgr_resumexfrs(dns_zonemgr_t * zmgr)15452 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
15453 
15454 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15455 
15456 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15457 	zmgr_resume_xfrs(zmgr, ISC_TRUE);
15458 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15459 }
15460 
15461 void
dns_zonemgr_shutdown(dns_zonemgr_t * zmgr)15462 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
15463 	dns_zone_t *zone;
15464 
15465 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15466 
15467 	isc_ratelimiter_shutdown(zmgr->notifyrl);
15468 	isc_ratelimiter_shutdown(zmgr->refreshrl);
15469 	isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
15470 	isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
15471 
15472 	if (zmgr->task != NULL)
15473 		isc_task_destroy(&zmgr->task);
15474 	if (zmgr->zonetasks != NULL)
15475 		isc_taskpool_destroy(&zmgr->zonetasks);
15476 	if (zmgr->loadtasks != NULL)
15477 		isc_taskpool_destroy(&zmgr->loadtasks);
15478 	if (zmgr->mctxpool != NULL)
15479 		isc_pool_destroy(&zmgr->mctxpool);
15480 
15481 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15482 	for (zone = ISC_LIST_HEAD(zmgr->zones);
15483 	     zone != NULL;
15484 	     zone = ISC_LIST_NEXT(zone, link))
15485 	{
15486 		LOCK_ZONE(zone);
15487 		forward_cancel(zone);
15488 		UNLOCK_ZONE(zone);
15489 	}
15490 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
15491 }
15492 
15493 static isc_result_t
mctxinit(void ** target,void * arg)15494 mctxinit(void **target, void *arg) {
15495 	isc_result_t result;
15496 	isc_mem_t *mctx = NULL;
15497 
15498 	UNUSED(arg);
15499 
15500 	REQUIRE(target != NULL && *target == NULL);
15501 
15502 	result = isc_mem_create(0, 0, &mctx);
15503 	if (result != ISC_R_SUCCESS)
15504 		return (result);
15505 	isc_mem_setname(mctx, "zonemgr-pool", NULL);
15506 
15507 	*target = mctx;
15508 	return (ISC_R_SUCCESS);
15509 }
15510 
15511 static void
mctxfree(void ** target)15512 mctxfree(void **target) {
15513 	isc_mem_t *mctx = *(isc_mem_t **) target;
15514 	isc_mem_detach(&mctx);
15515 	*target = NULL;
15516 }
15517 
15518 #define ZONES_PER_TASK 100
15519 #define ZONES_PER_MCTX 1000
15520 
15521 isc_result_t
dns_zonemgr_setsize(dns_zonemgr_t * zmgr,int num_zones)15522 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
15523 	isc_result_t result;
15524 	int ntasks = num_zones / ZONES_PER_TASK;
15525 	int nmctx = num_zones / ZONES_PER_MCTX;
15526 	isc_taskpool_t *pool = NULL;
15527 	isc_pool_t *mctxpool = NULL;
15528 
15529 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15530 
15531 	/*
15532 	 * For anything fewer than 1000 zones we use 10 tasks in
15533 	 * the task pools.  More than that, and we'll scale at one
15534 	 * task per 100 zones.  Similarly, for anything smaller than
15535 	 * 2000 zones we use 2 memory contexts, then scale at 1:1000.
15536 	 */
15537 	if (ntasks < 10)
15538 		ntasks = 10;
15539 	if (nmctx < 2)
15540 		nmctx = 2;
15541 
15542 	/* Create or resize the zone task pools. */
15543 	if (zmgr->zonetasks == NULL)
15544 		result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
15545 					     ntasks, 2, &pool);
15546 	else
15547 		result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
15548 
15549 	if (result == ISC_R_SUCCESS)
15550 		zmgr->zonetasks = pool;
15551 
15552 	pool = NULL;
15553 	if (zmgr->loadtasks == NULL)
15554 		result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
15555 					     ntasks, 2, &pool);
15556 	else
15557 		result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool);
15558 
15559 	if (result == ISC_R_SUCCESS)
15560 		zmgr->loadtasks = pool;
15561 
15562 	/*
15563 	 * We always set all tasks in the zone-load task pool to
15564 	 * privileged.  This prevents other tasks in the system from
15565 	 * running while the server task manager is in privileged
15566 	 * mode.
15567 	 *
15568 	 * NOTE: If we start using task privileges for any other
15569 	 * part of the system than zone tasks, then this will need to be
15570 	 * revisted.  In that case we'd want to turn on privileges for
15571 	 * zone tasks only when we were loading, and turn them off the
15572 	 * rest of the time.  For now, however, it's okay to just
15573 	 * set it and forget it.
15574 	 */
15575 	isc_taskpool_setprivilege(zmgr->loadtasks, ISC_TRUE);
15576 
15577 	/* Create or resize the zone memory context pool. */
15578 	if (zmgr->mctxpool == NULL)
15579 		result = isc_pool_create(zmgr->mctx, nmctx, mctxfree,
15580 					 mctxinit, NULL, &mctxpool);
15581 	else
15582 		result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
15583 
15584 	if (result == ISC_R_SUCCESS)
15585 		zmgr->mctxpool = mctxpool;
15586 
15587 	return (result);
15588 }
15589 
15590 static void
zonemgr_free(dns_zonemgr_t * zmgr)15591 zonemgr_free(dns_zonemgr_t *zmgr) {
15592 	isc_mem_t *mctx;
15593 
15594 	INSIST(zmgr->refs == 0);
15595 	INSIST(ISC_LIST_EMPTY(zmgr->zones));
15596 
15597 	zmgr->magic = 0;
15598 
15599 	DESTROYLOCK(&zmgr->iolock);
15600 	isc_ratelimiter_detach(&zmgr->notifyrl);
15601 	isc_ratelimiter_detach(&zmgr->refreshrl);
15602 	isc_ratelimiter_detach(&zmgr->startupnotifyrl);
15603 	isc_ratelimiter_detach(&zmgr->startuprefreshrl);
15604 
15605 	isc_rwlock_destroy(&zmgr->urlock);
15606 	isc_rwlock_destroy(&zmgr->rwlock);
15607 	mctx = zmgr->mctx;
15608 	isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
15609 	isc_mem_detach(&mctx);
15610 }
15611 
15612 void
dns_zonemgr_settransfersin(dns_zonemgr_t * zmgr,isc_uint32_t value)15613 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
15614 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15615 
15616 	zmgr->transfersin = value;
15617 }
15618 
15619 isc_uint32_t
dns_zonemgr_getttransfersin(dns_zonemgr_t * zmgr)15620 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
15621 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15622 
15623 	return (zmgr->transfersin);
15624 }
15625 
15626 void
dns_zonemgr_settransfersperns(dns_zonemgr_t * zmgr,isc_uint32_t value)15627 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
15628 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15629 
15630 	zmgr->transfersperns = value;
15631 }
15632 
15633 isc_uint32_t
dns_zonemgr_getttransfersperns(dns_zonemgr_t * zmgr)15634 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
15635 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15636 
15637 	return (zmgr->transfersperns);
15638 }
15639 
15640 /*
15641  * Try to start a new incoming zone transfer to fill a quota
15642  * slot that was just vacated.
15643  *
15644  * Requires:
15645  *	The zone manager is locked by the caller.
15646  */
15647 static void
zmgr_resume_xfrs(dns_zonemgr_t * zmgr,isc_boolean_t multi)15648 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
15649 	dns_zone_t *zone;
15650 	dns_zone_t *next;
15651 
15652 	for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
15653 	     zone != NULL;
15654 	     zone = next)
15655 	{
15656 		isc_result_t result;
15657 		next = ISC_LIST_NEXT(zone, statelink);
15658 		result = zmgr_start_xfrin_ifquota(zmgr, zone);
15659 		if (result == ISC_R_SUCCESS) {
15660 			if (multi)
15661 				continue;
15662 			/*
15663 			 * We successfully filled the slot.  We're done.
15664 			 */
15665 			break;
15666 		} else if (result == ISC_R_QUOTA) {
15667 			/*
15668 			 * Not enough quota.  This is probably the per-server
15669 			 * quota, because we usually get called when a unit of
15670 			 * global quota has just been freed.  Try the next
15671 			 * zone, it may succeed if it uses another master.
15672 			 */
15673 			continue;
15674 		} else {
15675 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
15676 				     "starting zone transfer: %s",
15677 				     isc_result_totext(result));
15678 			break;
15679 		}
15680 	}
15681 }
15682 
15683 /*
15684  * Try to start an incoming zone transfer for 'zone', quota permitting.
15685  *
15686  * Requires:
15687  *	The zone manager is locked by the caller.
15688  *
15689  * Returns:
15690  *	ISC_R_SUCCESS	There was enough quota and we attempted to
15691  *			start a transfer.  zone_xfrdone() has been or will
15692  *			be called.
15693  *	ISC_R_QUOTA	Not enough quota.
15694  *	Others		Failure.
15695  */
15696 static isc_result_t
zmgr_start_xfrin_ifquota(dns_zonemgr_t * zmgr,dns_zone_t * zone)15697 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
15698 	dns_peer_t *peer = NULL;
15699 	isc_netaddr_t masterip;
15700 	isc_uint32_t nxfrsin, nxfrsperns;
15701 	dns_zone_t *x;
15702 	isc_uint32_t maxtransfersin, maxtransfersperns;
15703 	isc_event_t *e;
15704 
15705 	/*
15706 	 * If we are exiting just pretend we got quota so the zone will
15707 	 * be cleaned up in the zone's task context.
15708 	 */
15709 	LOCK_ZONE(zone);
15710 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
15711 		UNLOCK_ZONE(zone);
15712 		goto gotquota;
15713 	}
15714 
15715 	/*
15716 	 * Find any configured information about the server we'd
15717 	 * like to transfer this zone from.
15718 	 */
15719 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
15720 	(void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
15721 	UNLOCK_ZONE(zone);
15722 
15723 	/*
15724 	 * Determine the total maximum number of simultaneous
15725 	 * transfers allowed, and the maximum for this specific
15726 	 * master.
15727 	 */
15728 	maxtransfersin = zmgr->transfersin;
15729 	maxtransfersperns = zmgr->transfersperns;
15730 	if (peer != NULL)
15731 		(void)dns_peer_gettransfers(peer, &maxtransfersperns);
15732 
15733 	/*
15734 	 * Count the total number of transfers that are in progress,
15735 	 * and the number of transfers in progress from this master.
15736 	 * We linearly scan a list of all transfers; if this turns
15737 	 * out to be too slow, we could hash on the master address.
15738 	 */
15739 	nxfrsin = nxfrsperns = 0;
15740 	for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
15741 	     x != NULL;
15742 	     x = ISC_LIST_NEXT(x, statelink))
15743 	{
15744 		isc_netaddr_t xip;
15745 
15746 		LOCK_ZONE(x);
15747 		isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
15748 		UNLOCK_ZONE(x);
15749 
15750 		nxfrsin++;
15751 		if (isc_netaddr_equal(&xip, &masterip))
15752 			nxfrsperns++;
15753 	}
15754 
15755 	/* Enforce quota. */
15756 	if (nxfrsin >= maxtransfersin)
15757 		return (ISC_R_QUOTA);
15758 
15759 	if (nxfrsperns >= maxtransfersperns)
15760 		return (ISC_R_QUOTA);
15761 
15762  gotquota:
15763 	/*
15764 	 * We have sufficient quota.  Move the zone to the "xfrin_in_progress"
15765 	 * list and send it an event to let it start the actual transfer in the
15766 	 * context of its own task.
15767 	 */
15768 	e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
15769 			       got_transfer_quota, zone, sizeof(isc_event_t));
15770 	if (e == NULL)
15771 		return (ISC_R_NOMEMORY);
15772 
15773 	LOCK_ZONE(zone);
15774 	INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
15775 	ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
15776 	ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
15777 	zone->statelist = &zmgr->xfrin_in_progress;
15778 	isc_task_send(zone->task, &e);
15779 	dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
15780 	UNLOCK_ZONE(zone);
15781 
15782 	return (ISC_R_SUCCESS);
15783 }
15784 
15785 void
dns_zonemgr_setiolimit(dns_zonemgr_t * zmgr,isc_uint32_t iolimit)15786 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
15787 
15788 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15789 	REQUIRE(iolimit > 0);
15790 
15791 	zmgr->iolimit = iolimit;
15792 }
15793 
15794 isc_uint32_t
dns_zonemgr_getiolimit(dns_zonemgr_t * zmgr)15795 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
15796 
15797 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15798 
15799 	return (zmgr->iolimit);
15800 }
15801 
15802 /*
15803  * Get permission to request a file handle from the OS.
15804  * An event will be sent to action when one is available.
15805  * There are two queues available (high and low), the high
15806  * queue will be serviced before the low one.
15807  *
15808  * zonemgr_putio() must be called after the event is delivered to
15809  * 'action'.
15810  */
15811 
15812 static isc_result_t
zonemgr_getio(dns_zonemgr_t * zmgr,isc_boolean_t high,isc_task_t * task,isc_taskaction_t action,void * arg,dns_io_t ** iop)15813 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
15814 	      isc_task_t *task, isc_taskaction_t action, void *arg,
15815 	      dns_io_t **iop)
15816 {
15817 	dns_io_t *io;
15818 	isc_boolean_t queue;
15819 
15820 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
15821 	REQUIRE(iop != NULL && *iop == NULL);
15822 
15823 	io = isc_mem_get(zmgr->mctx, sizeof(*io));
15824 	if (io == NULL)
15825 		return (ISC_R_NOMEMORY);
15826 
15827 	io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
15828 				       action, arg, sizeof(*io->event));
15829 	if (io->event == NULL) {
15830 		isc_mem_put(zmgr->mctx, io, sizeof(*io));
15831 		return (ISC_R_NOMEMORY);
15832 	}
15833 
15834 	io->zmgr = zmgr;
15835 	io->high = high;
15836 	io->task = NULL;
15837 	isc_task_attach(task, &io->task);
15838 	ISC_LINK_INIT(io, link);
15839 	io->magic = IO_MAGIC;
15840 
15841 	LOCK(&zmgr->iolock);
15842 	zmgr->ioactive++;
15843 	queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
15844 	if (queue) {
15845 		if (io->high)
15846 			ISC_LIST_APPEND(zmgr->high, io, link);
15847 		else
15848 			ISC_LIST_APPEND(zmgr->low, io, link);
15849 	}
15850 	UNLOCK(&zmgr->iolock);
15851 	*iop = io;
15852 
15853 	if (!queue)
15854 		isc_task_send(io->task, &io->event);
15855 	return (ISC_R_SUCCESS);
15856 }
15857 
15858 static void
zonemgr_putio(dns_io_t ** iop)15859 zonemgr_putio(dns_io_t **iop) {
15860 	dns_io_t *io;
15861 	dns_io_t *next;
15862 	dns_zonemgr_t *zmgr;
15863 
15864 	REQUIRE(iop != NULL);
15865 	io = *iop;
15866 	REQUIRE(DNS_IO_VALID(io));
15867 
15868 	*iop = NULL;
15869 
15870 	INSIST(!ISC_LINK_LINKED(io, link));
15871 	INSIST(io->event == NULL);
15872 
15873 	zmgr = io->zmgr;
15874 	isc_task_detach(&io->task);
15875 	io->magic = 0;
15876 	isc_mem_put(zmgr->mctx, io, sizeof(*io));
15877 
15878 	LOCK(&zmgr->iolock);
15879 	INSIST(zmgr->ioactive > 0);
15880 	zmgr->ioactive--;
15881 	next = HEAD(zmgr->high);
15882 	if (next == NULL)
15883 		next = HEAD(zmgr->low);
15884 	if (next != NULL) {
15885 		if (next->high)
15886 			ISC_LIST_UNLINK(zmgr->high, next, link);
15887 		else
15888 			ISC_LIST_UNLINK(zmgr->low, next, link);
15889 		INSIST(next->event != NULL);
15890 	}
15891 	UNLOCK(&zmgr->iolock);
15892 	if (next != NULL)
15893 		isc_task_send(next->task, &next->event);
15894 }
15895 
15896 static void
zonemgr_cancelio(dns_io_t * io)15897 zonemgr_cancelio(dns_io_t *io) {
15898 	isc_boolean_t send_event = ISC_FALSE;
15899 
15900 	REQUIRE(DNS_IO_VALID(io));
15901 
15902 	/*
15903 	 * If we are queued to be run then dequeue.
15904 	 */
15905 	LOCK(&io->zmgr->iolock);
15906 	if (ISC_LINK_LINKED(io, link)) {
15907 		if (io->high)
15908 			ISC_LIST_UNLINK(io->zmgr->high, io, link);
15909 		else
15910 			ISC_LIST_UNLINK(io->zmgr->low, io, link);
15911 
15912 		send_event = ISC_TRUE;
15913 		INSIST(io->event != NULL);
15914 	}
15915 	UNLOCK(&io->zmgr->iolock);
15916 	if (send_event) {
15917 		io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
15918 		isc_task_send(io->task, &io->event);
15919 	}
15920 }
15921 
15922 static void
zone_saveunique(dns_zone_t * zone,const char * path,const char * templat)15923 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
15924 	char *buf;
15925 	int buflen;
15926 	isc_result_t result;
15927 
15928 	buflen = strlen(path) + strlen(templat) + 2;
15929 
15930 	buf = isc_mem_get(zone->mctx, buflen);
15931 	if (buf == NULL)
15932 		return;
15933 
15934 	result = isc_file_template(path, templat, buf, buflen);
15935 	if (result != ISC_R_SUCCESS)
15936 		goto cleanup;
15937 
15938 	result = isc_file_renameunique(path, buf);
15939 	if (result != ISC_R_SUCCESS)
15940 		goto cleanup;
15941 
15942 	dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
15943 		     "renaming file to '%s' for failure analysis and "
15944 		     "retransferring.", path, buf);
15945 
15946  cleanup:
15947 	isc_mem_put(zone->mctx, buf, buflen);
15948 }
15949 
15950 #if 0
15951 /* Hook for ondestroy notification from a database. */
15952 
15953 static void
15954 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
15955 	dns_db_t *db = event->sender;
15956 	UNUSED(task);
15957 
15958 	isc_event_free(&event);
15959 
15960 	isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
15961 		      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
15962 		      "database (%p) destroyed", (void*) db);
15963 }
15964 #endif
15965 
15966 static void
setrl(isc_ratelimiter_t * rl,unsigned int * rate,unsigned int value)15967 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
15968 	isc_interval_t interval;
15969 	isc_uint32_t s, ns;
15970 	isc_uint32_t pertic;
15971 	isc_result_t result;
15972 
15973 	if (value == 0)
15974 		value = 1;
15975 
15976 	if (value == 1) {
15977 		s = 1;
15978 		ns = 0;
15979 		pertic = 1;
15980 	} else if (value <= 10) {
15981 		s = 0;
15982 		ns = 1000000000 / value;
15983 		pertic = 1;
15984 	} else {
15985 		s = 0;
15986 		ns = (1000000000 / value) * 10;
15987 		pertic = 10;
15988 	}
15989 
15990 	isc_interval_set(&interval, s, ns);
15991 
15992 	result = isc_ratelimiter_setinterval(rl, &interval);
15993 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
15994 	isc_ratelimiter_setpertic(rl, pertic);
15995 
15996 	*rate = value;
15997 }
15998 
15999 void
dns_zonemgr_setserialqueryrate(dns_zonemgr_t * zmgr,unsigned int value)16000 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
16001 
16002 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16003 
16004 	setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value);
16005 
16006 	/* Seperately controlled in BIND 9.11.x */
16007 	setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
16008 	setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
16009 
16010 	/* XXXMPA seperate out once we have the code to support this. */
16011 	setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value);
16012 }
16013 
16014 unsigned int
dns_zonemgr_getserialqueryrate(dns_zonemgr_t * zmgr)16015 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
16016 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16017 
16018 	return (zmgr->serialqueryrate);
16019 }
16020 
16021 isc_boolean_t
dns_zonemgr_unreachable(dns_zonemgr_t * zmgr,isc_sockaddr_t * remote,isc_sockaddr_t * local,isc_time_t * now)16022 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
16023 			isc_sockaddr_t *local, isc_time_t *now)
16024 {
16025 	unsigned int i;
16026 	isc_rwlocktype_t locktype;
16027 	isc_result_t result;
16028 	isc_uint32_t seconds = isc_time_seconds(now);
16029 	isc_uint32_t count = 0;
16030 
16031 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16032 
16033 	locktype = isc_rwlocktype_read;
16034 	RWLOCK(&zmgr->urlock, locktype);
16035 	for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
16036 		if (zmgr->unreachable[i].expire >= seconds &&
16037 		    isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
16038 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
16039 			result = isc_rwlock_tryupgrade(&zmgr->urlock);
16040 			if (result == ISC_R_SUCCESS) {
16041 				locktype = isc_rwlocktype_write;
16042 				zmgr->unreachable[i].last = seconds;
16043 				count = zmgr->unreachable[i].count;
16044 			}
16045 			break;
16046 		}
16047 	}
16048 	RWUNLOCK(&zmgr->urlock, locktype);
16049 	return (ISC_TF(i < UNREACH_CHACHE_SIZE && count > 1U));
16050 }
16051 
16052 void
dns_zonemgr_unreachabledel(dns_zonemgr_t * zmgr,isc_sockaddr_t * remote,isc_sockaddr_t * local)16053 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
16054 			   isc_sockaddr_t *local)
16055 {
16056 	unsigned int i;
16057 	isc_rwlocktype_t locktype;
16058 	isc_result_t result;
16059 
16060 	char master[ISC_SOCKADDR_FORMATSIZE];
16061 	char source[ISC_SOCKADDR_FORMATSIZE];
16062 
16063 	isc_sockaddr_format(remote, master, sizeof(master));
16064 	isc_sockaddr_format(local, source, sizeof(source));
16065 
16066 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16067 
16068 	locktype = isc_rwlocktype_read;
16069 	RWLOCK(&zmgr->urlock, locktype);
16070 	for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
16071 		if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
16072 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
16073 			if (zmgr->unreachable[i].expire == 0)
16074 				break;
16075 			result = isc_rwlock_tryupgrade(&zmgr->urlock);
16076 			if (result == ISC_R_SUCCESS) {
16077 				locktype = isc_rwlocktype_write;
16078 				zmgr->unreachable[i].expire = 0;
16079 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
16080 					      DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
16081 					      "master %s (source %s) deleted "
16082 					      "from unreachable cache",
16083 					      master, source);
16084 			}
16085 			break;
16086 		}
16087 	}
16088 	RWUNLOCK(&zmgr->urlock, locktype);
16089 }
16090 
16091 void
dns_zonemgr_unreachableadd(dns_zonemgr_t * zmgr,isc_sockaddr_t * remote,isc_sockaddr_t * local,isc_time_t * now)16092 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
16093 			   isc_sockaddr_t *local, isc_time_t *now)
16094 {
16095 	isc_uint32_t seconds = isc_time_seconds(now);
16096 	isc_uint32_t last = seconds;
16097 	unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
16098 
16099 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16100 
16101 	RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
16102 	for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
16103 		/* Existing entry? */
16104 		if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
16105 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
16106 			break;
16107 		/* Empty slot? */
16108 		if (zmgr->unreachable[i].expire < seconds)
16109 			slot = i;
16110 		/* Least recently used slot? */
16111 		if (zmgr->unreachable[i].last < last) {
16112 			last = zmgr->unreachable[i].last;
16113 			oldest = i;
16114 		}
16115 	}
16116 	if (i < UNREACH_CHACHE_SIZE) {
16117 		/*
16118 		 * Found a existing entry.  Update the expire timer and
16119 		 * last usage timestamps.
16120 		 */
16121 		zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
16122 		zmgr->unreachable[i].last = seconds;
16123 		if (zmgr->unreachable[i].expire < seconds)
16124 			zmgr->unreachable[i].count = 1;
16125 		else
16126 			zmgr->unreachable[i].count++;
16127 	} else if (slot != UNREACH_CHACHE_SIZE) {
16128 		/*
16129 		 * Found a empty slot. Add a new entry to the cache.
16130 		 */
16131 		zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
16132 		zmgr->unreachable[slot].last = seconds;
16133 		zmgr->unreachable[slot].remote = *remote;
16134 		zmgr->unreachable[slot].local = *local;
16135 		zmgr->unreachable[slot].count = 1;
16136 	} else {
16137 		/*
16138 		 * Replace the least recently used entry in the cache.
16139 		 */
16140 		zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
16141 		zmgr->unreachable[oldest].last = seconds;
16142 		zmgr->unreachable[oldest].remote = *remote;
16143 		zmgr->unreachable[oldest].local = *local;
16144 		zmgr->unreachable[oldest].count = 1;
16145 	}
16146 	RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
16147 }
16148 
16149 void
dns_zone_forcereload(dns_zone_t * zone)16150 dns_zone_forcereload(dns_zone_t *zone) {
16151 	REQUIRE(DNS_ZONE_VALID(zone));
16152 
16153 	if (zone->type == dns_zone_master ||
16154 	    (zone->type == dns_zone_redirect && zone->masters == NULL))
16155 		return;
16156 
16157 	LOCK_ZONE(zone);
16158 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
16159 	UNLOCK_ZONE(zone);
16160 	dns_zone_refresh(zone);
16161 }
16162 
16163 isc_boolean_t
dns_zone_isforced(dns_zone_t * zone)16164 dns_zone_isforced(dns_zone_t *zone) {
16165 	REQUIRE(DNS_ZONE_VALID(zone));
16166 
16167 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
16168 }
16169 
16170 isc_result_t
dns_zone_setstatistics(dns_zone_t * zone,isc_boolean_t on)16171 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
16172 	/*
16173 	 * This function is obsoleted.
16174 	 */
16175 	UNUSED(zone);
16176 	UNUSED(on);
16177 	return (ISC_R_NOTIMPLEMENTED);
16178 }
16179 
16180 isc_uint64_t *
dns_zone_getstatscounters(dns_zone_t * zone)16181 dns_zone_getstatscounters(dns_zone_t *zone) {
16182 	/*
16183 	 * This function is obsoleted.
16184 	 */
16185 	UNUSED(zone);
16186 	return (NULL);
16187 }
16188 
16189 void
dns_zone_setstats(dns_zone_t * zone,isc_stats_t * stats)16190 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
16191 	REQUIRE(DNS_ZONE_VALID(zone));
16192 	REQUIRE(zone->stats == NULL);
16193 
16194 	LOCK_ZONE(zone);
16195 	zone->stats = NULL;
16196 	isc_stats_attach(stats, &zone->stats);
16197 	UNLOCK_ZONE(zone);
16198 }
16199 
16200 void
dns_zone_setrequeststats(dns_zone_t * zone,isc_stats_t * stats)16201 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
16202 
16203 	REQUIRE(DNS_ZONE_VALID(zone));
16204 
16205 	LOCK_ZONE(zone);
16206 	if (zone->requeststats_on && stats == NULL)
16207 		zone->requeststats_on = ISC_FALSE;
16208 	else if (!zone->requeststats_on && stats != NULL) {
16209 		if (zone->requeststats == NULL) {
16210 			isc_stats_attach(stats, &zone->requeststats);
16211 			zone->requeststats_on = ISC_TRUE;
16212 		}
16213 	}
16214 	UNLOCK_ZONE(zone);
16215 }
16216 
16217 void
dns_zone_setrcvquerystats(dns_zone_t * zone,dns_stats_t * stats)16218 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
16219 
16220 	REQUIRE(DNS_ZONE_VALID(zone));
16221 
16222 	LOCK_ZONE(zone);
16223 	if (zone->requeststats_on && stats != NULL) {
16224 		if (zone->rcvquerystats == NULL) {
16225 			dns_stats_attach(stats, &zone->rcvquerystats);
16226 			zone->requeststats_on = ISC_TRUE;
16227 		}
16228 	}
16229 	UNLOCK_ZONE(zone);
16230 }
16231 
16232 isc_stats_t *
dns_zone_getrequeststats(dns_zone_t * zone)16233 dns_zone_getrequeststats(dns_zone_t *zone) {
16234 	/*
16235 	 * We don't lock zone for efficiency reason.  This is not catastrophic
16236 	 * because requeststats must always be valid when requeststats_on is
16237 	 * true.
16238 	 * Some counters may be incremented while requeststats_on is becoming
16239 	 * false, or some cannot be incremented just after the statistics are
16240 	 * installed, but it shouldn't matter much in practice.
16241 	 */
16242 	if (zone->requeststats_on)
16243 		return (zone->requeststats);
16244 	else
16245 		return (NULL);
16246 }
16247 
16248 /*
16249  * Return the received query stats bucket
16250  * see note from dns_zone_getrequeststats()
16251  */
16252 dns_stats_t *
dns_zone_getrcvquerystats(dns_zone_t * zone)16253 dns_zone_getrcvquerystats(dns_zone_t *zone) {
16254 	if (zone->requeststats_on)
16255 		return (zone->rcvquerystats);
16256 	else
16257 		return (NULL);
16258 }
16259 
16260 void
dns_zone_dialup(dns_zone_t * zone)16261 dns_zone_dialup(dns_zone_t *zone) {
16262 
16263 	REQUIRE(DNS_ZONE_VALID(zone));
16264 
16265 	zone_debuglog(zone, "dns_zone_dialup", 3,
16266 		      "notify = %d, refresh = %d",
16267 		      DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
16268 		      DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
16269 
16270 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
16271 		dns_zone_notify(zone);
16272 	if (zone->type != dns_zone_master && zone->masters != NULL &&
16273 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
16274 		dns_zone_refresh(zone);
16275 }
16276 
16277 void
dns_zone_setdialup(dns_zone_t * zone,dns_dialuptype_t dialup)16278 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
16279 	REQUIRE(DNS_ZONE_VALID(zone));
16280 
16281 	LOCK_ZONE(zone);
16282 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
16283 			 DNS_ZONEFLG_DIALREFRESH |
16284 			 DNS_ZONEFLG_NOREFRESH);
16285 	switch (dialup) {
16286 	case dns_dialuptype_no:
16287 		break;
16288 	case dns_dialuptype_yes:
16289 		DNS_ZONE_SETFLAG(zone,	(DNS_ZONEFLG_DIALNOTIFY |
16290 				 DNS_ZONEFLG_DIALREFRESH |
16291 				 DNS_ZONEFLG_NOREFRESH));
16292 		break;
16293 	case dns_dialuptype_notify:
16294 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
16295 		break;
16296 	case dns_dialuptype_notifypassive:
16297 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
16298 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
16299 		break;
16300 	case dns_dialuptype_refresh:
16301 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
16302 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
16303 		break;
16304 	case dns_dialuptype_passive:
16305 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
16306 		break;
16307 	default:
16308 		INSIST(0);
16309 	}
16310 	UNLOCK_ZONE(zone);
16311 }
16312 
16313 isc_result_t
dns_zone_setkeydirectory(dns_zone_t * zone,const char * directory)16314 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
16315 	isc_result_t result = ISC_R_SUCCESS;
16316 
16317 	REQUIRE(DNS_ZONE_VALID(zone));
16318 
16319 	LOCK_ZONE(zone);
16320 	result = dns_zone_setstring(zone, &zone->keydirectory, directory);
16321 	UNLOCK_ZONE(zone);
16322 
16323 	return (result);
16324 }
16325 
16326 const char *
dns_zone_getkeydirectory(dns_zone_t * zone)16327 dns_zone_getkeydirectory(dns_zone_t *zone) {
16328 	REQUIRE(DNS_ZONE_VALID(zone));
16329 
16330 	return (zone->keydirectory);
16331 }
16332 
16333 unsigned int
dns_zonemgr_getcount(dns_zonemgr_t * zmgr,int state)16334 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
16335 	dns_zone_t *zone;
16336 	unsigned int count = 0;
16337 
16338 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16339 
16340 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
16341 	switch (state) {
16342 	case DNS_ZONESTATE_XFERRUNNING:
16343 		for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
16344 		     zone != NULL;
16345 		     zone = ISC_LIST_NEXT(zone, statelink))
16346 			count++;
16347 		break;
16348 	case DNS_ZONESTATE_XFERDEFERRED:
16349 		for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
16350 		     zone != NULL;
16351 		     zone = ISC_LIST_NEXT(zone, statelink))
16352 			count++;
16353 		break;
16354 	case DNS_ZONESTATE_SOAQUERY:
16355 		for (zone = ISC_LIST_HEAD(zmgr->zones);
16356 		     zone != NULL;
16357 		     zone = ISC_LIST_NEXT(zone, link))
16358 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
16359 				count++;
16360 		break;
16361 	case DNS_ZONESTATE_ANY:
16362 		for (zone = ISC_LIST_HEAD(zmgr->zones);
16363 		     zone != NULL;
16364 		     zone = ISC_LIST_NEXT(zone, link)) {
16365 			dns_view_t *view = zone->view;
16366 			if (view != NULL && strcmp(view->name, "_bind") == 0)
16367 				continue;
16368 			count++;
16369 		}
16370 		break;
16371 	default:
16372 		INSIST(0);
16373 	}
16374 
16375 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
16376 
16377 	return (count);
16378 }
16379 
16380 isc_result_t
dns_zone_checknames(dns_zone_t * zone,dns_name_t * name,dns_rdata_t * rdata)16381 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
16382 	isc_boolean_t ok = ISC_TRUE;
16383 	isc_boolean_t fail = ISC_FALSE;
16384 	char namebuf[DNS_NAME_FORMATSIZE];
16385 	char namebuf2[DNS_NAME_FORMATSIZE];
16386 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
16387 	int level = ISC_LOG_WARNING;
16388 	dns_name_t bad;
16389 
16390 	REQUIRE(DNS_ZONE_VALID(zone));
16391 
16392 	if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) &&
16393 	    rdata->type != dns_rdatatype_nsec3)
16394 		return (ISC_R_SUCCESS);
16395 
16396 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) ||
16397 	    rdata->type == dns_rdatatype_nsec3) {
16398 		level = ISC_LOG_ERROR;
16399 		fail = ISC_TRUE;
16400 	}
16401 
16402 	ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
16403 	if (!ok) {
16404 		dns_name_format(name, namebuf, sizeof(namebuf));
16405 		dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
16406 		dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
16407 			     dns_result_totext(DNS_R_BADOWNERNAME));
16408 		if (fail)
16409 			return (DNS_R_BADOWNERNAME);
16410 	}
16411 
16412 	dns_name_init(&bad, NULL);
16413 	ok = dns_rdata_checknames(rdata, name, &bad);
16414 	if (!ok) {
16415 		dns_name_format(name, namebuf, sizeof(namebuf));
16416 		dns_name_format(&bad, namebuf2, sizeof(namebuf2));
16417 		dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
16418 		dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
16419 			     namebuf2, dns_result_totext(DNS_R_BADNAME));
16420 		if (fail)
16421 			return (DNS_R_BADNAME);
16422 	}
16423 
16424 	return (ISC_R_SUCCESS);
16425 }
16426 
16427 void
dns_zone_setcheckmx(dns_zone_t * zone,dns_checkmxfunc_t checkmx)16428 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
16429 	REQUIRE(DNS_ZONE_VALID(zone));
16430 	zone->checkmx = checkmx;
16431 }
16432 
16433 void
dns_zone_setchecksrv(dns_zone_t * zone,dns_checksrvfunc_t checksrv)16434 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
16435 	REQUIRE(DNS_ZONE_VALID(zone));
16436 	zone->checksrv = checksrv;
16437 }
16438 
16439 void
dns_zone_setcheckns(dns_zone_t * zone,dns_checknsfunc_t checkns)16440 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
16441 	REQUIRE(DNS_ZONE_VALID(zone));
16442 	zone->checkns = checkns;
16443 }
16444 
16445 void
dns_zone_setisself(dns_zone_t * zone,dns_isselffunc_t isself,void * arg)16446 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
16447 	REQUIRE(DNS_ZONE_VALID(zone));
16448 
16449 	LOCK_ZONE(zone);
16450 	zone->isself = isself;
16451 	zone->isselfarg = arg;
16452 	UNLOCK_ZONE(zone);
16453 }
16454 
16455 void
dns_zone_setnotifydelay(dns_zone_t * zone,isc_uint32_t delay)16456 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
16457 	REQUIRE(DNS_ZONE_VALID(zone));
16458 
16459 	LOCK_ZONE(zone);
16460 	zone->notifydelay = delay;
16461 	UNLOCK_ZONE(zone);
16462 }
16463 
16464 isc_uint32_t
dns_zone_getnotifydelay(dns_zone_t * zone)16465 dns_zone_getnotifydelay(dns_zone_t *zone) {
16466 	REQUIRE(DNS_ZONE_VALID(zone));
16467 
16468 	return (zone->notifydelay);
16469 }
16470 
16471 isc_result_t
dns_zone_signwithkey(dns_zone_t * zone,dns_secalg_t algorithm,isc_uint16_t keyid,isc_boolean_t delete)16472 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
16473 		     isc_uint16_t keyid, isc_boolean_t delete)
16474 {
16475 	isc_result_t result;
16476 	REQUIRE(DNS_ZONE_VALID(zone));
16477 
16478 	dns_zone_log(zone, ISC_LOG_NOTICE,
16479 		     "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
16480 		     algorithm, keyid);
16481 	LOCK_ZONE(zone);
16482 	result = zone_signwithkey(zone, algorithm, keyid, delete);
16483 	UNLOCK_ZONE(zone);
16484 
16485 	return (result);
16486 }
16487 
16488 static const char *hex = "0123456789ABCDEF";
16489 
16490 isc_result_t
dns_zone_addnsec3chain(dns_zone_t * zone,dns_rdata_nsec3param_t * nsec3param)16491 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
16492 	isc_result_t result;
16493 	char salt[255*2+1];
16494 	unsigned int i, j;
16495 
16496 	REQUIRE(DNS_ZONE_VALID(zone));
16497 
16498 	if (nsec3param->salt_length != 0) {
16499 		INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
16500 		for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
16501 			salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
16502 			salt[j++] = hex[nsec3param->salt[i] & 0xf];
16503 		}
16504 		salt[j] = '\0';
16505 	} else
16506 		strcpy(salt, "-");
16507 	dns_zone_log(zone, ISC_LOG_NOTICE,
16508 		     "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
16509 		     nsec3param->hash, nsec3param->iterations,
16510 		     salt);
16511 	LOCK_ZONE(zone);
16512 	result = zone_addnsec3chain(zone, nsec3param);
16513 	UNLOCK_ZONE(zone);
16514 
16515 	return (result);
16516 }
16517 
16518 void
dns_zone_setnodes(dns_zone_t * zone,isc_uint32_t nodes)16519 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
16520 	REQUIRE(DNS_ZONE_VALID(zone));
16521 
16522 	if (nodes == 0)
16523 		nodes = 1;
16524 	zone->nodes = nodes;
16525 }
16526 
16527 void
dns_zone_setsignatures(dns_zone_t * zone,isc_uint32_t signatures)16528 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
16529 	REQUIRE(DNS_ZONE_VALID(zone));
16530 
16531 	/*
16532 	 * We treat signatures as a signed value so explicitly
16533 	 * limit its range here.
16534 	 */
16535 	if (signatures > ISC_INT32_MAX)
16536 		signatures = ISC_INT32_MAX;
16537 	else if (signatures == 0)
16538 		signatures = 1;
16539 	zone->signatures = signatures;
16540 }
16541 
16542 void
dns_zone_setprivatetype(dns_zone_t * zone,dns_rdatatype_t type)16543 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
16544 	REQUIRE(DNS_ZONE_VALID(zone));
16545 	zone->privatetype = type;
16546 }
16547 
16548 dns_rdatatype_t
dns_zone_getprivatetype(dns_zone_t * zone)16549 dns_zone_getprivatetype(dns_zone_t *zone) {
16550 	REQUIRE(DNS_ZONE_VALID(zone));
16551 	return (zone->privatetype);
16552 }
16553 
16554 static isc_result_t
zone_signwithkey(dns_zone_t * zone,dns_secalg_t algorithm,isc_uint16_t keyid,isc_boolean_t delete)16555 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
16556 		 isc_boolean_t delete)
16557 {
16558 	dns_signing_t *signing;
16559 	dns_signing_t *current;
16560 	isc_result_t result = ISC_R_SUCCESS;
16561 	isc_time_t now;
16562 	dns_db_t *db = NULL;
16563 
16564 	signing = isc_mem_get(zone->mctx, sizeof *signing);
16565 	if (signing == NULL)
16566 		return (ISC_R_NOMEMORY);
16567 
16568 	signing->magic = 0;
16569 	signing->db  = NULL;
16570 	signing->dbiterator = NULL;
16571 	signing->algorithm = algorithm;
16572 	signing->keyid = keyid;
16573 	signing->delete = delete;
16574 	signing->done = ISC_FALSE;
16575 
16576 	TIME_NOW(&now);
16577 
16578 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
16579 	if (zone->db != NULL)
16580 		dns_db_attach(zone->db, &db);
16581 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
16582 
16583 	if (db == NULL) {
16584 		result = ISC_R_NOTFOUND;
16585 		goto cleanup;
16586 	}
16587 
16588 	dns_db_attach(db, &signing->db);
16589 
16590 	for (current = ISC_LIST_HEAD(zone->signing);
16591 	     current != NULL;
16592 	     current = ISC_LIST_NEXT(current, link)) {
16593 		if (current->db == signing->db &&
16594 		    current->algorithm == signing->algorithm &&
16595 		    current->keyid == signing->keyid) {
16596 			if (current->delete != signing->delete)
16597 				current->done = ISC_TRUE;
16598 			else
16599 				goto cleanup;
16600 		}
16601 	}
16602 
16603 	result = dns_db_createiterator(signing->db, 0,
16604 				       &signing->dbiterator);
16605 
16606 	if (result == ISC_R_SUCCESS)
16607 		result = dns_dbiterator_first(signing->dbiterator);
16608 	if (result == ISC_R_SUCCESS) {
16609 		dns_dbiterator_pause(signing->dbiterator);
16610 		ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
16611 		signing = NULL;
16612 		if (isc_time_isepoch(&zone->signingtime)) {
16613 			zone->signingtime = now;
16614 			if (zone->task != NULL)
16615 				zone_settimer(zone, &now);
16616 		}
16617 	}
16618 
16619  cleanup:
16620 	if (signing != NULL) {
16621 		if (signing->db != NULL)
16622 			dns_db_detach(&signing->db);
16623 		if (signing->dbiterator != NULL)
16624 			dns_dbiterator_destroy(&signing->dbiterator);
16625 		isc_mem_put(zone->mctx, signing, sizeof *signing);
16626 	}
16627 	if (db != NULL)
16628 		dns_db_detach(&db);
16629 	return (result);
16630 }
16631 
16632 static void
logmsg(const char * format,...)16633 logmsg(const char *format, ...) {
16634 	va_list args;
16635 	va_start(args, format);
16636 	isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
16637 		       ISC_LOG_DEBUG(1), format, args);
16638 	va_end(args);
16639 }
16640 
16641 static void
clear_keylist(dns_dnsseckeylist_t * list,isc_mem_t * mctx)16642 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
16643 	dns_dnsseckey_t *key;
16644 	while (!ISC_LIST_EMPTY(*list)) {
16645 		key = ISC_LIST_HEAD(*list);
16646 		ISC_LIST_UNLINK(*list, key, link);
16647 		dns_dnsseckey_destroy(mctx, &key);
16648 	}
16649 }
16650 
16651 /* Called once; *timep should be set to the current time. */
16652 static isc_result_t
next_keyevent(dst_key_t * key,isc_stdtime_t * timep)16653 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
16654 	isc_result_t result;
16655 	isc_stdtime_t now, then = 0, event;
16656 	int i;
16657 
16658 	now = *timep;
16659 
16660 	for (i = 0; i <= DST_MAX_TIMES; i++) {
16661 		result = dst_key_gettime(key, i, &event);
16662 		if (result == ISC_R_SUCCESS && event > now &&
16663 		    (then == 0 || event < then))
16664 			then = event;
16665 	}
16666 
16667 	if (then != 0) {
16668 		*timep = then;
16669 		return (ISC_R_SUCCESS);
16670 	}
16671 
16672 	return (ISC_R_NOTFOUND);
16673 }
16674 
16675 static isc_result_t
rr_exists(dns_db_t * db,dns_dbversion_t * ver,dns_name_t * name,const dns_rdata_t * rdata,isc_boolean_t * flag)16676 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
16677 	  const dns_rdata_t *rdata, isc_boolean_t *flag)
16678 {
16679 	dns_rdataset_t rdataset;
16680 	dns_dbnode_t *node = NULL;
16681 	isc_result_t result;
16682 
16683 	dns_rdataset_init(&rdataset);
16684 	if (rdata->type == dns_rdatatype_nsec3)
16685 		CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
16686 	else
16687 		CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
16688 	result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
16689 				     (isc_stdtime_t) 0, &rdataset, NULL);
16690 	if (result == ISC_R_NOTFOUND) {
16691 		*flag = ISC_FALSE;
16692 		result = ISC_R_SUCCESS;
16693 		goto failure;
16694 	}
16695 
16696 	for (result = dns_rdataset_first(&rdataset);
16697 	     result == ISC_R_SUCCESS;
16698 	     result = dns_rdataset_next(&rdataset)) {
16699 		dns_rdata_t myrdata = DNS_RDATA_INIT;
16700 		dns_rdataset_current(&rdataset, &myrdata);
16701 		if (!dns_rdata_compare(&myrdata, rdata))
16702 			break;
16703 	}
16704 	dns_rdataset_disassociate(&rdataset);
16705 	if (result == ISC_R_SUCCESS) {
16706 		*flag = ISC_TRUE;
16707 	} else if (result == ISC_R_NOMORE) {
16708 		*flag = ISC_FALSE;
16709 		result = ISC_R_SUCCESS;
16710 	}
16711 
16712  failure:
16713 	if (node != NULL)
16714 		dns_db_detachnode(db, &node);
16715 	return (result);
16716 }
16717 
16718 /*
16719  * Add records to signal the state of signing or of key removal.
16720  */
16721 static isc_result_t
add_signing_records(dns_db_t * db,dns_rdatatype_t privatetype,dns_dbversion_t * ver,dns_diff_t * diff,isc_boolean_t sign_all)16722 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
16723 		    dns_dbversion_t *ver, dns_diff_t *diff,
16724 		    isc_boolean_t sign_all)
16725 {
16726 	dns_difftuple_t *tuple, *newtuple = NULL;
16727 	dns_rdata_dnskey_t dnskey;
16728 	dns_rdata_t rdata = DNS_RDATA_INIT;
16729 	isc_boolean_t flag;
16730 	isc_region_t r;
16731 	isc_result_t result = ISC_R_SUCCESS;
16732 	isc_uint16_t keyid;
16733 	unsigned char buf[5];
16734 	dns_name_t *name = dns_db_origin(db);
16735 
16736 	for (tuple = ISC_LIST_HEAD(diff->tuples);
16737 	     tuple != NULL;
16738 	     tuple = ISC_LIST_NEXT(tuple, link)) {
16739 		if (tuple->rdata.type != dns_rdatatype_dnskey)
16740 			continue;
16741 
16742 		result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
16743 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
16744 		if ((dnskey.flags &
16745 		     (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
16746 			 != DNS_KEYOWNER_ZONE)
16747 			continue;
16748 
16749 		dns_rdata_toregion(&tuple->rdata, &r);
16750 
16751 		keyid = dst_region_computeid(&r, dnskey.algorithm);
16752 
16753 		buf[0] = dnskey.algorithm;
16754 		buf[1] = (keyid & 0xff00) >> 8;
16755 		buf[2] = (keyid & 0xff);
16756 		buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
16757 		buf[4] = 0;
16758 		rdata.data = buf;
16759 		rdata.length = sizeof(buf);
16760 		rdata.type = privatetype;
16761 		rdata.rdclass = tuple->rdata.rdclass;
16762 
16763 		if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
16764 			CHECK(rr_exists(db, ver, name, &rdata, &flag));
16765 			if (flag)
16766 				continue;
16767 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
16768 						   name, 0, &rdata, &newtuple));
16769 			CHECK(do_one_tuple(&newtuple, db, ver, diff));
16770 			INSIST(newtuple == NULL);
16771 		}
16772 
16773 		/*
16774 		 * Remove any record which says this operation has already
16775 		 * completed.
16776 		 */
16777 		buf[4] = 1;
16778 		CHECK(rr_exists(db, ver, name, &rdata, &flag));
16779 		if (flag) {
16780 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
16781 						   name, 0, &rdata, &newtuple));
16782 			CHECK(do_one_tuple(&newtuple, db, ver, diff));
16783 			INSIST(newtuple == NULL);
16784 		}
16785 	}
16786  failure:
16787 	return (result);
16788 }
16789 
16790 static isc_result_t
sign_apex(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff,zonediff_t * zonediff)16791 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16792 	  dns_diff_t *diff, zonediff_t *zonediff)
16793 {
16794 	isc_result_t result;
16795 	isc_stdtime_t now, inception, soaexpire;
16796 	isc_boolean_t check_ksk, keyset_kskonly;
16797 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
16798 	unsigned int nkeys = 0, i;
16799 	dns_difftuple_t *tuple;
16800 
16801 	result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS,
16802 				zone_keys, &nkeys);
16803 	if (result != ISC_R_SUCCESS) {
16804 		dns_zone_log(zone, ISC_LOG_ERROR,
16805 			     "sign_apex:find_zone_keys -> %s",
16806 			     dns_result_totext(result));
16807 		return (result);
16808 	}
16809 
16810 	isc_stdtime_get(&now);
16811 	inception = now - 3600;	/* Allow for clock skew. */
16812 	soaexpire = now + dns_zone_getsigvalidityinterval(zone);
16813 
16814 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
16815 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
16816 
16817 	/*
16818 	 * See if update_sigs will update DNSKEY signature and if not
16819 	 * cause them to sign so that so that newly activated keys
16820 	 * are used.
16821 	 */
16822 	for (tuple = ISC_LIST_HEAD(diff->tuples);
16823 	     tuple != NULL;
16824 	     tuple = ISC_LIST_NEXT(tuple, link)) {
16825 		if (tuple->rdata.type == dns_rdatatype_dnskey &&
16826 		    dns_name_equal(&tuple->name, &zone->origin))
16827 			break;
16828 	}
16829 
16830 	if (tuple == NULL) {
16831 		result = del_sigs(zone, db, ver, &zone->origin,
16832 				  dns_rdatatype_dnskey, zonediff,
16833 				  zone_keys, nkeys, now, ISC_FALSE);
16834 		if (result != ISC_R_SUCCESS) {
16835 			dns_zone_log(zone, ISC_LOG_ERROR,
16836 				     "sign_apex:del_sigs -> %s",
16837 				     dns_result_totext(result));
16838 			goto failure;
16839 		}
16840 		result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
16841 				  zonediff->diff, zone_keys, nkeys, zone->mctx,
16842 				  inception, soaexpire, check_ksk,
16843 				  keyset_kskonly);
16844 		if (result != ISC_R_SUCCESS) {
16845 			dns_zone_log(zone, ISC_LOG_ERROR,
16846 				     "sign_apex:add_sigs -> %s",
16847 				     dns_result_totext(result));
16848 			goto failure;
16849 		}
16850 	}
16851 
16852 	result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
16853 			     inception, soaexpire, now, check_ksk,
16854 			     keyset_kskonly, zonediff);
16855 
16856 	if (result != ISC_R_SUCCESS) {
16857 		dns_zone_log(zone, ISC_LOG_ERROR,
16858 			     "sign_apex:update_sigs -> %s",
16859 			     dns_result_totext(result));
16860 		goto failure;
16861 	}
16862 
16863  failure:
16864 	for (i = 0; i < nkeys; i++)
16865 		dst_key_free(&zone_keys[i]);
16866 	return (result);
16867 }
16868 
16869 /*
16870  * Prevent the zone entering a inconsistent state where
16871  * NSEC only DNSKEYs are present with NSEC3 chains.
16872  * See update.c:check_dnssec()
16873  */
16874 static isc_boolean_t
dnskey_sane(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff)16875 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16876 	    dns_diff_t *diff)
16877 {
16878 	isc_result_t result;
16879 	dns_difftuple_t *tuple;
16880 	isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
16881 	dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
16882 
16883 	/* Scan the tuples for an NSEC-only DNSKEY */
16884 	for (tuple = ISC_LIST_HEAD(diff->tuples);
16885 	     tuple != NULL;
16886 	     tuple = ISC_LIST_NEXT(tuple, link)) {
16887 		isc_uint8_t alg;
16888 		if (tuple->rdata.type != dns_rdatatype_dnskey ||
16889 		    tuple->op != DNS_DIFFOP_ADD)
16890 			continue;
16891 
16892 		alg = tuple->rdata.data[3];
16893 		if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
16894 		    alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
16895 			nseconly = ISC_TRUE;
16896 			break;
16897 		}
16898 	}
16899 
16900 	/* Check existing DB for NSEC-only DNSKEY */
16901 	if (!nseconly) {
16902 		result = dns_nsec_nseconly(db, ver, &nseconly);
16903 		if (result == ISC_R_NOTFOUND)
16904 			result = ISC_R_SUCCESS;
16905 		CHECK(result);
16906 	}
16907 
16908 	/* Check existing DB for NSEC3 */
16909 	if (!nsec3)
16910 		CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
16911 					privatetype, &nsec3));
16912 
16913 	/* Refuse to allow NSEC3 with NSEC-only keys */
16914 	if (nseconly && nsec3) {
16915 		dns_zone_log(zone, ISC_LOG_ERROR,
16916 			   "NSEC only DNSKEYs and NSEC3 chains not allowed");
16917 		goto failure;
16918 	}
16919 
16920 	return (ISC_TRUE);
16921 
16922  failure:
16923 	return (ISC_FALSE);
16924 }
16925 
16926 static isc_result_t
clean_nsec3param(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff)16927 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16928 		 dns_diff_t *diff)
16929 {
16930 	isc_result_t result;
16931 	dns_dbnode_t *node = NULL;
16932 	dns_rdataset_t rdataset;
16933 
16934 	dns_rdataset_init(&rdataset);
16935 	CHECK(dns_db_getoriginnode(db, &node));
16936 
16937 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
16938 				     dns_rdatatype_none, 0, &rdataset, NULL);
16939 	if (dns_rdataset_isassociated(&rdataset))
16940 		dns_rdataset_disassociate(&rdataset);
16941 	if (result != ISC_R_NOTFOUND)
16942 		goto failure;
16943 
16944 	result = dns_nsec3param_deletechains(db, ver, zone, ISC_TRUE, diff);
16945 
16946  failure:
16947 	if (node != NULL)
16948 		dns_db_detachnode(db, &node);
16949 	return (result);
16950 }
16951 
16952 /*
16953  * Given an RRSIG rdataset and an algorithm, determine whether there
16954  * are any signatures using that algorithm.
16955  */
16956 static isc_boolean_t
signed_with_alg(dns_rdataset_t * rdataset,dns_secalg_t alg)16957 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
16958 	dns_rdata_t rdata = DNS_RDATA_INIT;
16959 	dns_rdata_rrsig_t rrsig;
16960 	isc_result_t result;
16961 
16962 	REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
16963 	if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
16964 		return (ISC_FALSE);
16965 	}
16966 
16967 	for (result = dns_rdataset_first(rdataset);
16968 	     result == ISC_R_SUCCESS;
16969 	     result = dns_rdataset_next(rdataset))
16970 	{
16971 		dns_rdataset_current(rdataset, &rdata);
16972 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
16973 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
16974 		dns_rdata_reset(&rdata);
16975 		if (rrsig.algorithm == alg)
16976 			return (ISC_TRUE);
16977 	}
16978 
16979 	return (ISC_FALSE);
16980 }
16981 
16982 static isc_result_t
add_chains(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * ver,dns_diff_t * diff)16983 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
16984 	   dns_diff_t *diff)
16985 {
16986 	dns_name_t *origin;
16987 	isc_boolean_t build_nsec3;
16988 	isc_result_t result;
16989 
16990 	origin = dns_db_origin(db);
16991 	CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
16992 				 &build_nsec3));
16993 	if (build_nsec3)
16994 		CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
16995 					   ISC_FALSE, zone->privatetype, diff));
16996 	CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff));
16997 
16998  failure:
16999 	return (result);
17000 }
17001 
17002 static void
zone_rekey(dns_zone_t * zone)17003 zone_rekey(dns_zone_t *zone) {
17004 	isc_result_t result;
17005 	dns_db_t *db = NULL;
17006 	dns_dbnode_t *node = NULL;
17007 	dns_dbversion_t *ver = NULL;
17008 	dns_rdataset_t soaset, soasigs, keyset, keysigs;
17009 	dns_dnsseckeylist_t dnskeys, keys, rmkeys;
17010 	dns_dnsseckey_t *key;
17011 	dns_diff_t diff, _sig_diff;
17012 	zonediff_t zonediff;
17013 	isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
17014 	isc_boolean_t newalg = ISC_FALSE;
17015 	isc_boolean_t fullsign;
17016 	dns_ttl_t ttl = 3600;
17017 	const char *dir;
17018 	isc_mem_t *mctx;
17019 	isc_stdtime_t now;
17020 	isc_time_t timenow;
17021 	isc_interval_t ival;
17022 	char timebuf[80];
17023 
17024 	REQUIRE(DNS_ZONE_VALID(zone));
17025 
17026 	ISC_LIST_INIT(dnskeys);
17027 	ISC_LIST_INIT(keys);
17028 	ISC_LIST_INIT(rmkeys);
17029 	dns_rdataset_init(&soaset);
17030 	dns_rdataset_init(&soasigs);
17031 	dns_rdataset_init(&keyset);
17032 	dns_rdataset_init(&keysigs);
17033 	dir = dns_zone_getkeydirectory(zone);
17034 	mctx = zone->mctx;
17035 	dns_diff_init(mctx, &diff);
17036 	dns_diff_init(mctx, &_sig_diff);
17037 	zonediff_init(&zonediff, &_sig_diff);
17038 
17039 	CHECK(dns_zone_getdb(zone, &db));
17040 	CHECK(dns_db_newversion(db, &ver));
17041 	CHECK(dns_db_getoriginnode(db, &node));
17042 
17043 	TIME_NOW(&timenow);
17044 	now = isc_time_seconds(&timenow);
17045 
17046 	dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
17047 
17048 	/* Get the SOA record's TTL */
17049 	CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
17050 				  dns_rdatatype_none, 0, &soaset, &soasigs));
17051 	ttl = soaset.ttl;
17052 	dns_rdataset_disassociate(&soaset);
17053 
17054 	/* Get the DNSKEY rdataset */
17055 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
17056 				     dns_rdatatype_none, 0, &keyset, &keysigs);
17057 	if (result == ISC_R_SUCCESS) {
17058 		ttl = keyset.ttl;
17059 		CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir,
17060 						     mctx, &keyset,
17061 						     &keysigs, &soasigs,
17062 						     ISC_FALSE, ISC_FALSE,
17063 						     &dnskeys));
17064 	} else if (result != ISC_R_NOTFOUND)
17065 		goto failure;
17066 
17067 	/*
17068 	 * True when called from "rndc sign".  Indicates the zone should be
17069 	 * fully signed now.
17070 	 */
17071 	fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0);
17072 
17073 	result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys);
17074 	if (result == ISC_R_SUCCESS) {
17075 		isc_boolean_t check_ksk;
17076 		check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
17077 
17078 		result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
17079 					       &zone->origin, ttl, &diff,
17080 					       ISC_TF(!check_ksk),
17081 					       mctx, logmsg);
17082 
17083 		/* Keys couldn't be updated for some reason;
17084 		 * try again later. */
17085 		if (result != ISC_R_SUCCESS) {
17086 			dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
17087 				     "couldn't update zone keys: %s",
17088 				     isc_result_totext(result));
17089 			goto failure;
17090 		}
17091 
17092 		/*
17093 		 * See if any pre-existing keys have newly become active;
17094 		 * also, see if any new key is for a new algorithm, as in that
17095 		 * event, we need to sign the zone fully.  (If there's a new
17096 		 * key, but it's for an already-existing algorithm, then
17097 		 * the zone signing can be handled incrementally.)
17098 		 */
17099 		for (key = ISC_LIST_HEAD(dnskeys);
17100 		     key != NULL;
17101 		     key = ISC_LIST_NEXT(key, link)) {
17102 			if (!key->first_sign)
17103 				continue;
17104 
17105 			newactive = ISC_TRUE;
17106 
17107 			if (!dns_rdataset_isassociated(&keysigs)) {
17108 				newalg = ISC_TRUE;
17109 				break;
17110 			}
17111 
17112 			if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
17113 				/*
17114 				 * This isn't a new algorithm; clear
17115 				 * first_sign so we won't sign the
17116 				 * whole zone with this key later
17117 				 */
17118 				key->first_sign = ISC_FALSE;
17119 			} else {
17120 				newalg = ISC_TRUE;
17121 				break;
17122 			}
17123 		}
17124 
17125 		if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
17126 		    dnskey_sane(zone, db, ver, &diff)) {
17127 			CHECK(dns_diff_apply(&diff, db, ver));
17128 			CHECK(clean_nsec3param(zone, db, ver, &diff));
17129 			CHECK(add_signing_records(db, zone->privatetype,
17130 						  ver, &diff,
17131 						  ISC_TF(newalg || fullsign)));
17132 			CHECK(update_soa_serial(db, ver, &diff, mctx,
17133 						zone->updatemethod));
17134 			CHECK(add_chains(zone, db, ver, &diff));
17135 			CHECK(sign_apex(zone, db, ver, &diff, &zonediff));
17136 			CHECK(zone_journal(zone, zonediff.diff, NULL,
17137 					   "zone_rekey"));
17138 			commit = ISC_TRUE;
17139 		}
17140 	}
17141 
17142 	dns_db_closeversion(db, &ver, ISC_TRUE);
17143 
17144 	if (commit) {
17145 		dns_difftuple_t *tuple;
17146 
17147 		LOCK_ZONE(zone);
17148 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
17149 
17150 		zone_needdump(zone, DNS_DUMP_DELAY);
17151 
17152 		zone_settimer(zone, &timenow);
17153 
17154 		/* Remove any signatures from removed keys.  */
17155 		if (!ISC_LIST_EMPTY(rmkeys)) {
17156 			for (key = ISC_LIST_HEAD(rmkeys);
17157 			     key != NULL;
17158 			     key = ISC_LIST_NEXT(key, link)) {
17159 				result = zone_signwithkey(zone,
17160 							  dst_key_alg(key->key),
17161 							  dst_key_id(key->key),
17162 							  ISC_TRUE);
17163 				if (result != ISC_R_SUCCESS) {
17164 					dns_zone_log(zone, ISC_LOG_ERROR,
17165 					     "zone_signwithkey failed: %s",
17166 					     dns_result_totext(result));
17167 				}
17168 			}
17169 		}
17170 
17171 		if (fullsign) {
17172 			/*
17173 			 * "rndc sign" was called, so we now sign the zone
17174 			 * with all active keys, whether they're new or not.
17175 			 */
17176 			for (key = ISC_LIST_HEAD(dnskeys);
17177 			     key != NULL;
17178 			     key = ISC_LIST_NEXT(key, link)) {
17179 				if (!key->force_sign && !key->hint_sign)
17180 					continue;
17181 
17182 				result = zone_signwithkey(zone,
17183 							  dst_key_alg(key->key),
17184 							  dst_key_id(key->key),
17185 							  ISC_FALSE);
17186 				if (result != ISC_R_SUCCESS) {
17187 					dns_zone_log(zone, ISC_LOG_ERROR,
17188 					     "zone_signwithkey failed: %s",
17189 					     dns_result_totext(result));
17190 				}
17191 			}
17192 		} else if (newalg) {
17193 			/*
17194 			 * We haven't been told to sign fully, but a new
17195 			 * algorithm was added to the DNSKEY.  We sign
17196 			 * the full zone, but only with newly active
17197 			 * keys.
17198 			 */
17199 			for (key = ISC_LIST_HEAD(dnskeys);
17200 			     key != NULL;
17201 			     key = ISC_LIST_NEXT(key, link)) {
17202 				if (!key->first_sign)
17203 					continue;
17204 
17205 				result = zone_signwithkey(zone,
17206 							  dst_key_alg(key->key),
17207 							  dst_key_id(key->key),
17208 							  ISC_FALSE);
17209 				if (result != ISC_R_SUCCESS) {
17210 					dns_zone_log(zone, ISC_LOG_ERROR,
17211 					     "zone_signwithkey failed: %s",
17212 					     dns_result_totext(result));
17213 				}
17214 			}
17215 		}
17216 
17217 		/*
17218 		 * Clear fullsign flag, if it was set, so we don't do
17219 		 * another full signing next time
17220 		 */
17221 		zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
17222 
17223 		/*
17224 		 * Cause the zone to add/delete NSEC3 chains for the
17225 		 * deferred NSEC3PARAM changes.
17226 		 */
17227 		for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
17228 		     tuple != NULL;
17229 		     tuple = ISC_LIST_NEXT(tuple, link)) {
17230 			unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
17231 			dns_rdata_t rdata = DNS_RDATA_INIT;
17232 			dns_rdata_nsec3param_t nsec3param;
17233 
17234 			if (tuple->rdata.type != zone->privatetype ||
17235 			    tuple->op != DNS_DIFFOP_ADD)
17236 				continue;
17237 
17238 			if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
17239 							buf, sizeof(buf)))
17240 				continue;
17241 			result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
17242 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
17243 			if (nsec3param.flags == 0)
17244 				continue;
17245 
17246 			result = zone_addnsec3chain(zone, &nsec3param);
17247 			if (result != ISC_R_SUCCESS) {
17248 				dns_zone_log(zone, ISC_LOG_ERROR,
17249 					     "zone_addnsec3chain failed: %s",
17250 					     dns_result_totext(result));
17251 			}
17252 		}
17253 
17254 		/*
17255 		 * Activate any NSEC3 chain updates that may have
17256 		 * been scheduled before this rekey.
17257 		 */
17258 		if (fullsign || newalg)
17259 			resume_addnsec3chain(zone);
17260 
17261 		/*
17262 		 * Schedule the next resigning event
17263 		 */
17264 		set_resigntime(zone);
17265 		UNLOCK_ZONE(zone);
17266 	}
17267 
17268 	isc_time_settoepoch(&zone->refreshkeytime);
17269 
17270 	/*
17271 	 * If we're doing key maintenance, set the key refresh timer to
17272 	 * the next scheduled key event or to 'dnssec-loadkeys-interval'
17273 	 * seconds in the future, whichever is sooner.
17274 	 */
17275 	if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
17276 		isc_time_t timethen;
17277 		isc_stdtime_t then;
17278 
17279 		LOCK_ZONE(zone);
17280 		DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
17281 				  &timethen);
17282 		zone->refreshkeytime = timethen;
17283 		UNLOCK_ZONE(zone);
17284 
17285 		for (key = ISC_LIST_HEAD(dnskeys);
17286 		     key != NULL;
17287 		     key = ISC_LIST_NEXT(key, link)) {
17288 			then = now;
17289 			result = next_keyevent(key->key, &then);
17290 			if (result != ISC_R_SUCCESS)
17291 				continue;
17292 
17293 			DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
17294 			LOCK_ZONE(zone);
17295 			if (isc_time_compare(&timethen,
17296 					     &zone->refreshkeytime) < 0) {
17297 				zone->refreshkeytime = timethen;
17298 			}
17299 			UNLOCK_ZONE(zone);
17300 		}
17301 
17302 		zone_settimer(zone, &timenow);
17303 
17304 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
17305 		dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
17306 	}
17307 
17308  done:
17309 	dns_diff_clear(&diff);
17310 	dns_diff_clear(&_sig_diff);
17311 
17312 	clear_keylist(&dnskeys, mctx);
17313 	clear_keylist(&keys, mctx);
17314 	clear_keylist(&rmkeys, mctx);
17315 
17316 	if (ver != NULL)
17317 		dns_db_closeversion(db, &ver, ISC_FALSE);
17318 	if (dns_rdataset_isassociated(&keyset))
17319 		dns_rdataset_disassociate(&keyset);
17320 	if (dns_rdataset_isassociated(&keysigs))
17321 		dns_rdataset_disassociate(&keysigs);
17322 	if (dns_rdataset_isassociated(&soasigs))
17323 		dns_rdataset_disassociate(&soasigs);
17324 	if (node != NULL)
17325 		dns_db_detachnode(db, &node);
17326 	if (db != NULL)
17327 		dns_db_detach(&db);
17328 
17329 	INSIST(ver == NULL);
17330 	return;
17331 
17332  failure:
17333 	/*
17334 	 * Something went wrong; try again in ten minutes or
17335 	 * after a key refresh interval, whichever is shorter.
17336 	 */
17337 	isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 0);
17338 	isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
17339 	goto done;
17340 }
17341 
17342 void
dns_zone_rekey(dns_zone_t * zone,isc_boolean_t fullsign)17343 dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) {
17344 	isc_time_t now;
17345 
17346 	if (zone->type == dns_zone_master && zone->task != NULL) {
17347 		LOCK_ZONE(zone);
17348 
17349 		if (fullsign)
17350 			zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
17351 
17352 		TIME_NOW(&now);
17353 		zone->refreshkeytime = now;
17354 		zone_settimer(zone, &now);
17355 
17356 		UNLOCK_ZONE(zone);
17357 	}
17358 }
17359 
17360 isc_result_t
dns_zone_nscheck(dns_zone_t * zone,dns_db_t * db,dns_dbversion_t * version,unsigned int * errors)17361 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
17362 		 unsigned int *errors)
17363 {
17364 	isc_result_t result;
17365 	dns_dbnode_t *node = NULL;
17366 
17367 	REQUIRE(DNS_ZONE_VALID(zone));
17368 	REQUIRE(errors != NULL);
17369 
17370 	result = dns_db_getoriginnode(db, &node);
17371 	if (result != ISC_R_SUCCESS)
17372 		return (result);
17373 	result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
17374 				  ISC_FALSE);
17375 	dns_db_detachnode(db, &node);
17376 	return (result);
17377 }
17378 
17379 void
dns_zone_setadded(dns_zone_t * zone,isc_boolean_t added)17380 dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) {
17381 	REQUIRE(DNS_ZONE_VALID(zone));
17382 
17383 	LOCK_ZONE(zone);
17384 	zone->added = added;
17385 	UNLOCK_ZONE(zone);
17386 }
17387 
17388 isc_boolean_t
dns_zone_getadded(dns_zone_t * zone)17389 dns_zone_getadded(dns_zone_t *zone) {
17390 	REQUIRE(DNS_ZONE_VALID(zone));
17391 	return (zone->added);
17392 }
17393 
17394 isc_result_t
dns_zone_dlzpostload(dns_zone_t * zone,dns_db_t * db)17395 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
17396 {
17397 	isc_time_t loadtime;
17398 	isc_result_t result;
17399 	dns_zone_t *secure = NULL;
17400 
17401 	TIME_NOW(&loadtime);
17402 
17403 	/*
17404 	 * Lock hierarchy: zmgr, zone, raw.
17405 	 */
17406  again:
17407 	LOCK_ZONE(zone);
17408 	INSIST(zone != zone->raw);
17409 	if (inline_secure(zone))
17410 		LOCK_ZONE(zone->raw);
17411 	else if (inline_raw(zone)) {
17412 		secure = zone->secure;
17413 		TRYLOCK_ZONE(result, secure);
17414 		if (result != ISC_R_SUCCESS) {
17415 			UNLOCK_ZONE(zone);
17416 			secure = NULL;
17417 #if ISC_PLATFORM_USETHREADS
17418 			isc_thread_yield();
17419 #endif
17420 			goto again;
17421 		}
17422 	}
17423 	result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
17424 	if (inline_secure(zone))
17425 		UNLOCK_ZONE(zone->raw);
17426 	else if (secure != NULL)
17427 		UNLOCK_ZONE(secure);
17428 	UNLOCK_ZONE(zone);
17429 	return result;
17430 }
17431 
17432 isc_result_t
dns_zone_setrefreshkeyinterval(dns_zone_t * zone,isc_uint32_t interval)17433 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval) {
17434 	REQUIRE(DNS_ZONE_VALID(zone));
17435 	if (interval == 0)
17436 		return (ISC_R_RANGE);
17437 	/* Maximum value: 24 hours (3600 minutes) */
17438 	if (interval > (24 * 60))
17439 		interval = (24 * 60);
17440 	/* Multiply by 60 for seconds */
17441 	zone->refreshkeyinterval = interval * 60;
17442 	return (ISC_R_SUCCESS);
17443 }
17444 
17445 void
dns_zone_setrequestixfr(dns_zone_t * zone,isc_boolean_t flag)17446 dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t flag) {
17447 	REQUIRE(DNS_ZONE_VALID(zone));
17448 	zone->requestixfr = flag;
17449 }
17450 
17451 isc_boolean_t
dns_zone_getrequestixfr(dns_zone_t * zone)17452 dns_zone_getrequestixfr(dns_zone_t *zone) {
17453 	REQUIRE(DNS_ZONE_VALID(zone));
17454 	return (zone->requestixfr);
17455 }
17456 
17457 void
dns_zone_setserialupdatemethod(dns_zone_t * zone,dns_updatemethod_t method)17458 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
17459 	REQUIRE(DNS_ZONE_VALID(zone));
17460 	zone->updatemethod = method;
17461 }
17462 
17463 dns_updatemethod_t
dns_zone_getserialupdatemethod(dns_zone_t * zone)17464 dns_zone_getserialupdatemethod(dns_zone_t *zone) {
17465 	REQUIRE(DNS_ZONE_VALID(zone));
17466 	return(zone->updatemethod);
17467 }
17468 
17469 /*
17470  * Lock hierarchy: zmgr, zone, raw.
17471  */
17472 isc_result_t
dns_zone_link(dns_zone_t * zone,dns_zone_t * raw)17473 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
17474 	isc_result_t result;
17475 	dns_zonemgr_t *zmgr;
17476 
17477 	REQUIRE(DNS_ZONE_VALID(zone));
17478 	REQUIRE(zone->zmgr != NULL);
17479 	REQUIRE(zone->task != NULL);
17480 	REQUIRE(zone->loadtask != NULL);
17481 	REQUIRE(zone->raw == NULL);
17482 
17483 	REQUIRE(DNS_ZONE_VALID(raw));
17484 	REQUIRE(raw->zmgr == NULL);
17485 	REQUIRE(raw->task == NULL);
17486 	REQUIRE(raw->loadtask == NULL);
17487 	REQUIRE(raw->secure == NULL);
17488 
17489 	REQUIRE(zone != raw);
17490 
17491 	/*
17492 	 * Lock hierarchy: zmgr, zone, raw.
17493 	 */
17494 	zmgr = zone->zmgr;
17495 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
17496 	LOCK_ZONE(zone);
17497 	LOCK_ZONE(raw);
17498 
17499 	result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
17500 				  NULL, NULL, zone->task, zone_timer, raw,
17501 				  &raw->timer);
17502 	if (result != ISC_R_SUCCESS)
17503 		goto unlock;
17504 
17505 	/*
17506 	 * The timer "holds" a iref.
17507 	 */
17508 	raw->irefs++;
17509 	INSIST(raw->irefs != 0);
17510 
17511 
17512 	/* dns_zone_attach(raw, &zone->raw); */
17513 	isc_refcount_increment(&raw->erefs, NULL);
17514 	zone->raw = raw;
17515 
17516 	/* dns_zone_iattach(zone,  &raw->secure); */
17517 	zone_iattach(zone, &raw->secure);
17518 
17519 	isc_task_attach(zone->task, &raw->task);
17520 	isc_task_attach(zone->loadtask, &raw->loadtask);
17521 
17522 	ISC_LIST_APPEND(zmgr->zones, raw, link);
17523 	raw->zmgr = zmgr;
17524 	zmgr->refs++;
17525 
17526  unlock:
17527 	UNLOCK_ZONE(raw);
17528 	UNLOCK_ZONE(zone);
17529 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
17530 	return (result);
17531 }
17532 
17533 void
dns_zone_getraw(dns_zone_t * zone,dns_zone_t ** raw)17534 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
17535 	REQUIRE(DNS_ZONE_VALID(zone));
17536 	REQUIRE(raw != NULL && *raw == NULL);
17537 
17538 	LOCK(&zone->lock);
17539 	INSIST(zone != zone->raw);
17540 	if (zone->raw != NULL)
17541 		dns_zone_attach(zone->raw, raw);
17542 	UNLOCK(&zone->lock);
17543 }
17544 
17545 struct keydone {
17546 	isc_event_t event;
17547 	isc_boolean_t all;
17548 	unsigned char data[5];
17549 };
17550 
17551 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL)
17552 
17553 static void
keydone(isc_task_t * task,isc_event_t * event)17554 keydone(isc_task_t *task, isc_event_t *event) {
17555 	const char *me = "keydone";
17556 	isc_boolean_t commit = ISC_FALSE;
17557 	isc_result_t result;
17558 	dns_rdata_t rdata = DNS_RDATA_INIT;
17559 	dns_dbversion_t *oldver = NULL, *newver = NULL;
17560 	dns_zone_t *zone;
17561 	dns_db_t *db = NULL;
17562 	dns_dbnode_t *node = NULL;
17563 	dns_rdataset_t rdataset;
17564 	dns_diff_t diff;
17565 	struct keydone *keydone = (struct keydone *)event;
17566 	dns_update_log_t log = { update_log_cb, NULL };
17567 	isc_boolean_t clear_pending = ISC_FALSE;
17568 
17569 	UNUSED(task);
17570 
17571 	zone = event->ev_arg;
17572 	INSIST(DNS_ZONE_VALID(zone));
17573 
17574 	ENTER;
17575 
17576 	dns_rdataset_init(&rdataset);
17577 	dns_diff_init(zone->mctx, &diff);
17578 
17579 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
17580 	if (zone->db != NULL) {
17581 		dns_db_attach(zone->db, &db);
17582 		dns_db_currentversion(db, &oldver);
17583 		result = dns_db_newversion(db, &newver);
17584 		if (result != ISC_R_SUCCESS) {
17585 			dns_zone_log(zone, ISC_LOG_ERROR,
17586 				     "keydone:dns_db_newversion -> %s",
17587 				     dns_result_totext(result));
17588 			goto failure;
17589 		}
17590 	}
17591 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
17592 	if (db == NULL)
17593 		goto failure;
17594 
17595 	result = dns_db_getoriginnode(db, &node);
17596 	if (result != ISC_R_SUCCESS)
17597 		goto failure;
17598 
17599 	result = dns_db_findrdataset(db, node, newver, zone->privatetype,
17600 				     dns_rdatatype_none, 0, &rdataset, NULL);
17601 	if (result == ISC_R_NOTFOUND) {
17602 		INSIST(!dns_rdataset_isassociated(&rdataset));
17603 		goto failure;
17604 	}
17605 	if (result != ISC_R_SUCCESS) {
17606 		INSIST(!dns_rdataset_isassociated(&rdataset));
17607 		goto failure;
17608 	}
17609 
17610 	for (result = dns_rdataset_first(&rdataset);
17611 	     result == ISC_R_SUCCESS;
17612 	     result = dns_rdataset_next(&rdataset)) {
17613 		isc_boolean_t found = ISC_FALSE;
17614 
17615 		dns_rdataset_current(&rdataset, &rdata);
17616 
17617 		if (keydone->all) {
17618 			if (rdata.length == 5 && rdata.data[0] != 0 &&
17619 			       rdata.data[3] == 0 && rdata.data[4] == 1)
17620 				found = ISC_TRUE;
17621 			else if (rdata.data[0] == 0 &&
17622 				 (rdata.data[2] & PENDINGFLAGS) != 0) {
17623 				found = ISC_TRUE;
17624 				clear_pending = ISC_TRUE;
17625 			}
17626 		} else if (rdata.length == 5 &&
17627 			   memcmp(rdata.data, keydone->data, 5) == 0)
17628 			found = ISC_TRUE;
17629 
17630 		if (found)
17631 			CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL,
17632 					    &zone->origin, rdataset.ttl,
17633 					    &rdata));
17634 		dns_rdata_reset(&rdata);
17635 	}
17636 
17637 	if (!ISC_LIST_EMPTY(diff.tuples)) {
17638 		/* Write changes to journal file. */
17639 		CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
17640 					zone->updatemethod));
17641 
17642 		result = dns_update_signatures(&log, zone, db,
17643 					       oldver, newver, &diff,
17644 					       zone->sigvalidityinterval);
17645 		if (!clear_pending)
17646 			CHECK(result);
17647 
17648 		CHECK(zone_journal(zone, &diff, NULL, "keydone"));
17649 		commit = ISC_TRUE;
17650 
17651 		LOCK_ZONE(zone);
17652 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
17653 		zone_needdump(zone, 30);
17654 		UNLOCK_ZONE(zone);
17655 	}
17656 
17657  failure:
17658 	if (dns_rdataset_isassociated(&rdataset))
17659 		dns_rdataset_disassociate(&rdataset);
17660 	if (db != NULL) {
17661 		if (node != NULL)
17662 			dns_db_detachnode(db, &node);
17663 		if (oldver != NULL)
17664 			dns_db_closeversion(db, &oldver, ISC_FALSE);
17665 		if (newver != NULL)
17666 			dns_db_closeversion(db, &newver, commit);
17667 		dns_db_detach(&db);
17668 	}
17669 	dns_diff_clear(&diff);
17670 	isc_event_free(&event);
17671 	dns_zone_idetach(&zone);
17672 
17673 	INSIST(oldver == NULL);
17674 	INSIST(newver == NULL);
17675 }
17676 
17677 isc_result_t
dns_zone_keydone(dns_zone_t * zone,const char * keystr)17678 dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
17679 	isc_result_t result = ISC_R_SUCCESS;
17680 	isc_event_t *e;
17681 	isc_buffer_t b;
17682 	dns_zone_t *dummy = NULL;
17683 	struct keydone *kd;
17684 
17685 	REQUIRE(DNS_ZONE_VALID(zone));
17686 
17687 	LOCK_ZONE(zone);
17688 
17689 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone,
17690 			       zone, sizeof(struct keydone));
17691 	if (e == NULL) {
17692 		result = ISC_R_NOMEMORY;
17693 		goto failure;
17694 	}
17695 
17696 	kd = (struct keydone *) e;
17697 	if (strcasecmp(keystr, "all") == 0)
17698 		kd->all = ISC_TRUE;
17699 	else {
17700 		isc_textregion_t r;
17701 		char *algstr;
17702 		dns_keytag_t keyid;
17703 		dns_secalg_t alg;
17704 		size_t n;
17705 
17706 		kd->all = ISC_FALSE;
17707 
17708 		n = sscanf(keystr, "%hd/", &keyid);
17709 		if (n == 0U)
17710 			CHECK(ISC_R_FAILURE);
17711 
17712 		algstr = strchr(keystr, '/');
17713 		if (algstr != NULL)
17714 			algstr++;
17715 		else
17716 			CHECK(ISC_R_FAILURE);
17717 
17718 		n = sscanf(algstr, "%hhd", &alg);
17719 		if (n == 0U) {
17720 			DE_CONST(algstr, r.base);
17721 			r.length = strlen(algstr);
17722 			CHECK(dns_secalg_fromtext(&alg, &r));
17723 		}
17724 
17725 		/* construct a private-type rdata */
17726 		isc_buffer_init(&b, kd->data, sizeof(kd->data));
17727 		isc_buffer_putuint8(&b, alg);
17728 		isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8);
17729 		isc_buffer_putuint8(&b, (keyid & 0xff));
17730 		isc_buffer_putuint8(&b, 0);
17731 		isc_buffer_putuint8(&b, 1);
17732 	}
17733 
17734 	zone_iattach(zone, &dummy);
17735 	isc_task_send(zone->task, &e);
17736 
17737  failure:
17738 	if (e != NULL)
17739 		isc_event_free(&e);
17740 	UNLOCK_ZONE(zone);
17741 	return (result);
17742 }
17743 
17744 static void
setnsec3param(isc_task_t * task,isc_event_t * event)17745 setnsec3param(isc_task_t *task, isc_event_t *event) {
17746 	const char *me = "setnsec3param";
17747 	isc_boolean_t commit = ISC_FALSE;
17748 	isc_result_t result;
17749 	dns_dbversion_t *oldver = NULL, *newver = NULL;
17750 	dns_zone_t *zone;
17751 	dns_db_t *db = NULL;
17752 	dns_dbnode_t *node = NULL;
17753 	dns_rdataset_t prdataset, nrdataset;
17754 	dns_diff_t diff;
17755 	struct np3event *npe = (struct np3event *)event;
17756 	nsec3param_t *np;
17757 	dns_update_log_t log = { update_log_cb, NULL };
17758 	dns_rdata_t rdata;
17759 	isc_boolean_t nseconly;
17760 	isc_boolean_t exists = ISC_FALSE;
17761 
17762 	UNUSED(task);
17763 
17764 	zone = event->ev_arg;
17765 	INSIST(DNS_ZONE_VALID(zone));
17766 
17767 	ENTER;
17768 
17769 	np = &npe->params;
17770 
17771 	dns_rdataset_init(&prdataset);
17772 	dns_rdataset_init(&nrdataset);
17773 	dns_diff_init(zone->mctx, &diff);
17774 
17775 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
17776 	if (zone->db != NULL) {
17777 		dns_db_attach(zone->db, &db);
17778 		dns_db_currentversion(db, &oldver);
17779 		result = dns_db_newversion(db, &newver);
17780 		if (result != ISC_R_SUCCESS) {
17781 			dns_zone_log(zone, ISC_LOG_ERROR,
17782 				     "setnsec3param:dns_db_newversion -> %s",
17783 				     dns_result_totext(result));
17784 			goto failure;
17785 		}
17786 	}
17787 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
17788 	if (db == NULL)
17789 		goto failure;
17790 
17791 	CHECK(dns_db_getoriginnode(db, &node));
17792 
17793 	/*
17794 	 * Does a private-type record already exist for this chain?
17795 	 */
17796 	result = dns_db_findrdataset(db, node, newver, zone->privatetype,
17797 				     dns_rdatatype_none, 0, &prdataset, NULL);
17798 	if (result == ISC_R_SUCCESS) {
17799 		for (result = dns_rdataset_first(&prdataset);
17800 		     result == ISC_R_SUCCESS;
17801 		     result = dns_rdataset_next(&prdataset)) {
17802 			dns_rdata_init(&rdata);
17803 			dns_rdataset_current(&prdataset, &rdata);
17804 
17805 			if (np->length == rdata.length &&
17806 			    memcmp(rdata.data, np->data, np->length) == 0) {
17807 				exists = ISC_TRUE;
17808 				break;
17809 			}
17810 		}
17811 	} else if (result != ISC_R_NOTFOUND) {
17812 		INSIST(!dns_rdataset_isassociated(&prdataset));
17813 		goto failure;
17814 	}
17815 
17816 	/*
17817 	 * Does the chain already exist?
17818 	 */
17819 	result = dns_db_findrdataset(db, node, newver,
17820 				     dns_rdatatype_nsec3param,
17821 				     dns_rdatatype_none, 0, &nrdataset, NULL);
17822 	if (result == ISC_R_SUCCESS) {
17823 		for (result = dns_rdataset_first(&nrdataset);
17824 		     result == ISC_R_SUCCESS;
17825 		     result = dns_rdataset_next(&nrdataset)) {
17826 			dns_rdata_init(&rdata);
17827 			dns_rdataset_current(&nrdataset, &rdata);
17828 
17829 			if (np->length == (rdata.length + 1) &&
17830 			    memcmp(rdata.data, np->data + 1,
17831 				   np->length - 1) == 0)
17832 			{
17833 				exists = ISC_TRUE;
17834 				break;
17835 			}
17836 		}
17837 	} else if (result != ISC_R_NOTFOUND) {
17838 		INSIST(!dns_rdataset_isassociated(&nrdataset));
17839 		goto failure;
17840 	}
17841 
17842 
17843 	/*
17844 	 * We need to remove any existing NSEC3 chains.
17845 	 */
17846 	if (!exists && np->replace && (np->length != 0 || np->nsec))
17847 		CHECK(dns_nsec3param_deletechains(db, newver, zone,
17848 						  !np->nsec, &diff));
17849 
17850 	if (!exists && np->length != 0) {
17851 		/*
17852 		 * We're creating an NSEC3 chain.
17853 		 *
17854 		 * If the zone is not currently capable of supporting
17855 		 * an NSEC3 chain, add the INITIAL flag, so these
17856 		 * parameters can be used later when NSEC3 becomes
17857 		 * available.
17858 		 */
17859 		dns_rdata_init(&rdata);
17860 
17861 		np->data[2] |= DNS_NSEC3FLAG_CREATE;
17862 		result = dns_nsec_nseconly(db, newver, &nseconly);
17863 		if (result == ISC_R_NOTFOUND || nseconly)
17864 			np->data[2] |= DNS_NSEC3FLAG_INITIAL;
17865 
17866 		rdata.length = np->length;
17867 		rdata.data = np->data;
17868 		rdata.type = zone->privatetype;
17869 		rdata.rdclass = zone->rdclass;
17870 		CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD,
17871 				    &zone->origin, 0, &rdata));
17872 	}
17873 
17874 	if (!ISC_LIST_EMPTY(diff.tuples)) {
17875 		/* Write changes to journal file. */
17876 		CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
17877 					zone->updatemethod));
17878 		result = dns_update_signatures(&log, zone, db,
17879 					       oldver, newver, &diff,
17880 					       zone->sigvalidityinterval);
17881 		if (result != ISC_R_NOTFOUND)
17882 			CHECK(result);
17883 		CHECK(zone_journal(zone, &diff, NULL, "setnsec3param"));
17884 		commit = ISC_TRUE;
17885 
17886 		LOCK_ZONE(zone);
17887 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
17888 		zone_needdump(zone, 30);
17889 		UNLOCK_ZONE(zone);
17890 	}
17891 
17892  failure:
17893 	if (dns_rdataset_isassociated(&prdataset))
17894 		dns_rdataset_disassociate(&prdataset);
17895 	if (dns_rdataset_isassociated(&nrdataset))
17896 		dns_rdataset_disassociate(&nrdataset);
17897 	if (node != NULL)
17898 		dns_db_detachnode(db, &node);
17899 	if (oldver != NULL)
17900 		dns_db_closeversion(db, &oldver, ISC_FALSE);
17901 	if (newver != NULL)
17902 		dns_db_closeversion(db, &newver, commit);
17903 	if (db != NULL)
17904 		dns_db_detach(&db);
17905 	if (commit)
17906 		resume_addnsec3chain(zone);
17907 	dns_diff_clear(&diff);
17908 	isc_event_free(&event);
17909 	dns_zone_idetach(&zone);
17910 
17911 	INSIST(oldver == NULL);
17912 	INSIST(newver == NULL);
17913 }
17914 
17915 isc_result_t
dns_zone_setnsec3param(dns_zone_t * zone,isc_uint8_t hash,isc_uint8_t flags,isc_uint16_t iter,isc_uint8_t saltlen,unsigned char * salt,isc_boolean_t replace)17916 dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags,
17917 		       isc_uint16_t iter, isc_uint8_t saltlen,
17918 		       unsigned char *salt, isc_boolean_t replace)
17919 {
17920 	isc_result_t result = ISC_R_SUCCESS;
17921 	dns_rdata_nsec3param_t param;
17922 	dns_rdata_t nrdata = DNS_RDATA_INIT;
17923 	dns_rdata_t prdata = DNS_RDATA_INIT;
17924 	unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
17925 	struct np3event *npe;
17926 	nsec3param_t *np;
17927 	dns_zone_t *dummy = NULL;
17928 	isc_buffer_t b;
17929 	isc_event_t *e;
17930 
17931 	REQUIRE(DNS_ZONE_VALID(zone));
17932 	REQUIRE(salt != NULL);
17933 
17934 	LOCK_ZONE(zone);
17935 
17936 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM,
17937 			       setnsec3param, zone, sizeof(struct np3event));
17938 	if (e == NULL) {
17939 		result = ISC_R_NOMEMORY;
17940 		goto failure;
17941 	}
17942 
17943 	npe = (struct np3event *) e;
17944 	np = &npe->params;
17945 
17946 	np->replace = replace;
17947 	if (hash == 0) {
17948 		np->length = 0;
17949 		np->nsec = ISC_TRUE;
17950 	} else {
17951 		param.common.rdclass = zone->rdclass;
17952 		param.common.rdtype = dns_rdatatype_nsec3param;
17953 		ISC_LINK_INIT(&param.common, link);
17954 		param.mctx = NULL;
17955 		param.hash = hash;
17956 		param.flags = flags;
17957 		param.iterations = iter;
17958 		param.salt_length = saltlen;
17959 		param.salt = salt;
17960 		isc_buffer_init(&b, nbuf, sizeof(nbuf));
17961 		CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
17962 					   dns_rdatatype_nsec3param,
17963 					   &param, &b));
17964 		dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype,
17965 					 np->data, sizeof(np->data));
17966 		np->length = prdata.length;
17967 	}
17968 
17969 	zone_iattach(zone, &dummy);
17970 	isc_task_send(zone->task, &e);
17971 
17972  failure:
17973 	if (e != NULL)
17974 		isc_event_free(&e);
17975 	UNLOCK_ZONE(zone);
17976 	return (result);
17977 }
17978 
17979 isc_result_t
dns_zone_getloadtime(dns_zone_t * zone,isc_time_t * loadtime)17980 dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) {
17981 	REQUIRE(DNS_ZONE_VALID(zone));
17982 	REQUIRE(loadtime != NULL);
17983 
17984 	LOCK_ZONE(zone);
17985 	*loadtime = zone->loadtime;
17986 	UNLOCK_ZONE(zone);
17987 	return (ISC_R_SUCCESS);
17988 }
17989 
17990 isc_result_t
dns_zone_getexpiretime(dns_zone_t * zone,isc_time_t * expiretime)17991 dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) {
17992 	REQUIRE(DNS_ZONE_VALID(zone));
17993 	REQUIRE(expiretime != NULL);
17994 
17995 	LOCK_ZONE(zone);
17996 	*expiretime = zone->expiretime;
17997 	UNLOCK_ZONE(zone);
17998 	return (ISC_R_SUCCESS);
17999 }
18000 
18001 isc_result_t
dns_zone_getrefreshtime(dns_zone_t * zone,isc_time_t * refreshtime)18002 dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) {
18003 	REQUIRE(DNS_ZONE_VALID(zone));
18004 	REQUIRE(refreshtime != NULL);
18005 
18006 	LOCK_ZONE(zone);
18007 	*refreshtime = zone->refreshtime;
18008 	UNLOCK_ZONE(zone);
18009 	return (ISC_R_SUCCESS);
18010 }
18011 
18012 isc_result_t
dns_zone_getrefreshkeytime(dns_zone_t * zone,isc_time_t * refreshkeytime)18013 dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) {
18014 	REQUIRE(DNS_ZONE_VALID(zone));
18015 	REQUIRE(refreshkeytime != NULL);
18016 
18017 	LOCK_ZONE(zone);
18018 	*refreshkeytime = zone->refreshkeytime;
18019 	UNLOCK_ZONE(zone);
18020 	return (ISC_R_SUCCESS);
18021 }
18022 
18023 unsigned int
dns_zone_getincludes(dns_zone_t * zone,char *** includesp)18024 dns_zone_getincludes(dns_zone_t *zone, char ***includesp) {
18025 	dns_include_t *include;
18026 	char **array = NULL;
18027 	unsigned int n = 0;
18028 
18029 	REQUIRE(DNS_ZONE_VALID(zone));
18030 	REQUIRE(includesp != NULL && *includesp == NULL);
18031 
18032 	LOCK_ZONE(zone);
18033 	if (zone->nincludes == 0)
18034 		goto done;
18035 
18036 	array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes);
18037 	if (array == NULL)
18038 		goto done;
18039 	for (include = ISC_LIST_HEAD(zone->includes);
18040 	     include != NULL;
18041 	     include = ISC_LIST_NEXT(include, link)) {
18042 		INSIST(n < zone->nincludes);
18043 		array[n++] = isc_mem_strdup(zone->mctx, include->name);
18044 	}
18045 	INSIST(n == zone->nincludes);
18046 	*includesp = array;
18047 
18048  done:
18049 	UNLOCK_ZONE(zone);
18050 	return (n);
18051 }
18052 
18053 void
dns_zone_setstatlevel(dns_zone_t * zone,dns_zonestat_level_t level)18054 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
18055 	REQUIRE(DNS_ZONE_VALID(zone));
18056 
18057 	zone->statlevel = level;
18058 }
18059 
18060 dns_zonestat_level_t
dns_zone_getstatlevel(dns_zone_t * zone)18061 dns_zone_getstatlevel(dns_zone_t *zone) {
18062 	REQUIRE(DNS_ZONE_VALID(zone));
18063 
18064 	return (zone->statlevel);
18065 }
18066