zone.c revision 1.1.1.2 1 /* $NetBSD: zone.c,v 1.1.1.2 2019/01/09 16:48:20 christos Exp $ */
2
3 /*
4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 *
10 * See the COPYRIGHT file distributed with this work for additional
11 * information regarding copyright ownership.
12 */
13
14 /*! \file */
15
16 #include <config.h>
17
18 #include <errno.h>
19 #include <inttypes.h>
20 #include <stdbool.h>
21
22 #include <isc/file.h>
23 #include <isc/hex.h>
24 #include <isc/mutex.h>
25 #include <isc/pool.h>
26 #include <isc/print.h>
27 #include <isc/random.h>
28 #include <isc/ratelimiter.h>
29 #include <isc/refcount.h>
30 #include <isc/rwlock.h>
31 #include <isc/serial.h>
32 #include <isc/stats.h>
33 #include <isc/stdtime.h>
34 #include <isc/strerr.h>
35 #include <isc/string.h>
36 #include <isc/taskpool.h>
37 #include <isc/thread.h>
38 #include <isc/timer.h>
39 #include <isc/util.h>
40
41 #include <dns/acl.h>
42 #include <dns/adb.h>
43 #include <dns/callbacks.h>
44 #include <dns/catz.h>
45 #include <dns/db.h>
46 #include <dns/dbiterator.h>
47 #include <dns/dlz.h>
48 #include <dns/dnssec.h>
49 #include <dns/events.h>
50 #include <dns/journal.h>
51 #include <dns/keydata.h>
52 #include <dns/keytable.h>
53 #include <dns/keyvalues.h>
54 #include <dns/log.h>
55 #include <dns/master.h>
56 #include <dns/masterdump.h>
57 #include <dns/message.h>
58 #include <dns/name.h>
59 #include <dns/nsec.h>
60 #include <dns/nsec3.h>
61 #include <dns/peer.h>
62 #include <dns/private.h>
63 #include <dns/rcode.h>
64 #include <dns/rdata.h>
65 #include <dns/rdataclass.h>
66 #include <dns/rdatalist.h>
67 #include <dns/rdataset.h>
68 #include <dns/rdatasetiter.h>
69 #include <dns/rdatastruct.h>
70 #include <dns/rdatatype.h>
71 #include <dns/request.h>
72 #include <dns/resolver.h>
73 #include <dns/result.h>
74 #include <dns/rriterator.h>
75 #include <dns/soa.h>
76 #include <dns/ssu.h>
77 #include <dns/stats.h>
78 #include <dns/time.h>
79 #include <dns/tsig.h>
80 #include <dns/update.h>
81 #include <dns/xfrin.h>
82 #include <dns/zone.h>
83 #include <dns/zoneverify.h>
84 #include <dns/zt.h>
85
86 #include <dst/dst.h>
87
88 #include "zone_p.h"
89
90 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
91 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
92
93 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
94 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
95
96 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
97 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
98
99 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
100 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
101
102 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
103 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
104
105 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
106 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
107
108 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
109 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
110
111 /*%
112 * Ensure 'a' is at least 'min' but not more than 'max'.
113 */
114 #define RANGE(a, min, max) \
115 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
116
117 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
118
119 /*%
120 * Key flags
121 */
122 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
123 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
124 #define ALG(x) dst_key_alg(x)
125
126 /*
127 * Default values.
128 */
129 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
130 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
131 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
132 #define RESIGN_DELAY 3600 /*%< 1 hour */
133
134 #ifndef DNS_MAX_EXPIRE
135 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
136 #endif
137
138 #ifndef DNS_DUMP_DELAY
139 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
140 #endif
141
142 typedef struct dns_notify dns_notify_t;
143 typedef struct dns_stub dns_stub_t;
144 typedef struct dns_load dns_load_t;
145 typedef struct dns_forward dns_forward_t;
146 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
147 typedef struct dns_io dns_io_t;
148 typedef ISC_LIST(dns_io_t) dns_iolist_t;
149 typedef struct dns_signing dns_signing_t;
150 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
151 typedef struct dns_nsec3chain dns_nsec3chain_t;
152 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
153 typedef struct dns_keyfetch dns_keyfetch_t;
154 typedef struct dns_asyncload dns_asyncload_t;
155 typedef struct dns_include dns_include_t;
156
157 #define DNS_ZONE_CHECKLOCK
158 #ifdef DNS_ZONE_CHECKLOCK
159 #define LOCK_ZONE(z) \
160 do { LOCK(&(z)->lock); \
161 INSIST((z)->locked == false); \
162 (z)->locked = true; \
163 } while (0)
164 #define UNLOCK_ZONE(z) \
165 do { (z)->locked = false; UNLOCK(&(z)->lock); } while (0)
166 #define LOCKED_ZONE(z) ((z)->locked)
167 #define TRYLOCK_ZONE(result, z) \
168 do { \
169 result = isc_mutex_trylock(&(z)->lock); \
170 if (result == ISC_R_SUCCESS) { \
171 INSIST((z)->locked == false); \
172 (z)->locked = true; \
173 } \
174 } while (0)
175 #else
176 #define LOCK_ZONE(z) LOCK(&(z)->lock)
177 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
178 #define LOCKED_ZONE(z) true
179 #define TRYLOCK_ZONE(result, z) \
180 do { result = isc_mutex_trylock(&(z)->lock); } while (0)
181 #endif
182
183 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
184 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
185 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
186 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
187
188 #ifdef ENABLE_AFL
189 extern bool dns_fuzzing_resolver;
190 #endif
191
192 struct dns_zone {
193 /* Unlocked */
194 unsigned int magic;
195 isc_mutex_t lock;
196 #ifdef DNS_ZONE_CHECKLOCK
197 bool locked;
198 #endif
199 isc_mem_t *mctx;
200 isc_refcount_t erefs;
201
202 isc_rwlock_t dblock;
203 dns_db_t *db; /* Locked by dblock */
204
205 /* Locked */
206 dns_zonemgr_t *zmgr;
207 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
208 isc_timer_t *timer;
209 unsigned int irefs;
210 dns_name_t origin;
211 char *masterfile;
212 ISC_LIST(dns_include_t) includes; /* Include files */
213 ISC_LIST(dns_include_t) newincludes; /* Loading */
214 unsigned int nincludes;
215 dns_masterformat_t masterformat;
216 const dns_master_style_t *masterstyle;
217 char *journal;
218 int32_t journalsize;
219 dns_rdataclass_t rdclass;
220 dns_zonetype_t type;
221 unsigned int flags;
222 dns_zoneopt_t options;
223 unsigned int db_argc;
224 char **db_argv;
225 isc_time_t expiretime;
226 isc_time_t refreshtime;
227 isc_time_t dumptime;
228 isc_time_t loadtime;
229 isc_time_t notifytime;
230 isc_time_t resigntime;
231 isc_time_t keywarntime;
232 isc_time_t signingtime;
233 isc_time_t nsec3chaintime;
234 isc_time_t refreshkeytime;
235 uint32_t refreshkeyinterval;
236 uint32_t refreshkeycount;
237 uint32_t refresh;
238 uint32_t retry;
239 uint32_t expire;
240 uint32_t minimum;
241 isc_stdtime_t key_expiry;
242 isc_stdtime_t log_key_expired_timer;
243 char *keydirectory;
244
245 uint32_t maxrefresh;
246 uint32_t minrefresh;
247 uint32_t maxretry;
248 uint32_t minretry;
249
250 uint32_t maxrecords;
251
252 isc_sockaddr_t *masters;
253 isc_dscp_t *masterdscps;
254 dns_name_t **masterkeynames;
255 bool *mastersok;
256 unsigned int masterscnt;
257 unsigned int curmaster;
258 isc_sockaddr_t masteraddr;
259 dns_notifytype_t notifytype;
260 isc_sockaddr_t *notify;
261 dns_name_t **notifykeynames;
262 isc_dscp_t *notifydscp;
263 unsigned int notifycnt;
264 isc_sockaddr_t notifyfrom;
265 isc_task_t *task;
266 isc_task_t *loadtask;
267 isc_sockaddr_t notifysrc4;
268 isc_sockaddr_t notifysrc6;
269 isc_sockaddr_t xfrsource4;
270 isc_sockaddr_t xfrsource6;
271 isc_sockaddr_t altxfrsource4;
272 isc_sockaddr_t altxfrsource6;
273 isc_sockaddr_t sourceaddr;
274 isc_dscp_t notifysrc4dscp;
275 isc_dscp_t notifysrc6dscp;
276 isc_dscp_t xfrsource4dscp;
277 isc_dscp_t xfrsource6dscp;
278 isc_dscp_t altxfrsource4dscp;
279 isc_dscp_t altxfrsource6dscp;
280 dns_xfrin_ctx_t *xfr; /* task locked */
281 dns_tsigkey_t *tsigkey; /* key used for xfr */
282 /* Access Control Lists */
283 dns_acl_t *update_acl;
284 dns_acl_t *forward_acl;
285 dns_acl_t *notify_acl;
286 dns_acl_t *query_acl;
287 dns_acl_t *queryon_acl;
288 dns_acl_t *xfr_acl;
289 bool update_disabled;
290 bool zero_no_soa_ttl;
291 dns_severity_t check_names;
292 ISC_LIST(dns_notify_t) notifies;
293 dns_request_t *request;
294 dns_loadctx_t *lctx;
295 dns_io_t *readio;
296 dns_dumpctx_t *dctx;
297 dns_io_t *writeio;
298 uint32_t maxxfrin;
299 uint32_t maxxfrout;
300 uint32_t idlein;
301 uint32_t idleout;
302 isc_event_t ctlevent;
303 dns_ssutable_t *ssutable;
304 uint32_t sigvalidityinterval;
305 uint32_t keyvalidityinterval;
306 uint32_t sigresigninginterval;
307 dns_view_t *view;
308 dns_view_t *prev_view;
309 dns_checkmxfunc_t checkmx;
310 dns_checksrvfunc_t checksrv;
311 dns_checknsfunc_t checkns;
312 /*%
313 * Zones in certain states such as "waiting for zone transfer"
314 * or "zone transfer in progress" are kept on per-state linked lists
315 * in the zone manager using the 'statelink' field. The 'statelist'
316 * field points at the list the zone is currently on. It the zone
317 * is not on any such list, statelist is NULL.
318 */
319 ISC_LINK(dns_zone_t) statelink;
320 dns_zonelist_t *statelist;
321 /*%
322 * Statistics counters about zone management.
323 */
324 isc_stats_t *stats;
325 /*%
326 * Optional per-zone statistics counters. Counted outside of this
327 * module.
328 */
329 dns_zonestat_level_t statlevel;
330 bool requeststats_on;
331 isc_stats_t *requeststats;
332 dns_stats_t *rcvquerystats;
333 uint32_t notifydelay;
334 dns_isselffunc_t isself;
335 void *isselfarg;
336
337 char * strnamerd;
338 char * strname;
339 char * strrdclass;
340 char * strviewname;
341
342 /*%
343 * Serial number for deferred journal compaction.
344 */
345 uint32_t compact_serial;
346 /*%
347 * Keys that are signing the zone for the first time.
348 */
349 dns_signinglist_t signing;
350 dns_nsec3chainlist_t nsec3chain;
351 /*%
352 * List of outstanding NSEC3PARAM change requests.
353 */
354 isc_eventlist_t setnsec3param_queue;
355 /*%
356 * Signing / re-signing quantum stopping parameters.
357 */
358 uint32_t signatures;
359 uint32_t nodes;
360 dns_rdatatype_t privatetype;
361
362 /*%
363 * Autosigning/key-maintenance options
364 */
365 uint32_t keyopts;
366
367 /*%
368 * True if added by "rndc addzone"
369 */
370 bool added;
371
372 /*%
373 * True if added by automatically by named.
374 */
375 bool automatic;
376
377 /*%
378 * response policy data to be relayed to the database
379 */
380 dns_rpz_zones_t *rpzs;
381 dns_rpz_num_t rpz_num;
382
383 /*%
384 * catalog zone data
385 */
386 dns_catz_zones_t *catzs;
387
388 /*%
389 * parent catalog zone
390 */
391 dns_catz_zone_t *parentcatz;
392
393 /*%
394 * Serial number update method.
395 */
396 dns_updatemethod_t updatemethod;
397
398 /*%
399 * whether ixfr is requested
400 */
401 bool requestixfr;
402
403 /*%
404 * whether EDNS EXPIRE is requested
405 */
406 bool requestexpire;
407
408 /*%
409 * Outstanding forwarded UPDATE requests.
410 */
411 dns_forwardlist_t forwards;
412
413 dns_zone_t *raw;
414 dns_zone_t *secure;
415
416 bool sourceserialset;
417 uint32_t sourceserial;
418
419 /*%
420 * maximum zone ttl
421 */
422 dns_ttl_t maxttl;
423
424 /*
425 * Inline zone signing state.
426 */
427 dns_diff_t rss_diff;
428 isc_eventlist_t rss_events;
429 dns_dbversion_t *rss_newver;
430 dns_dbversion_t *rss_oldver;
431 dns_db_t *rss_db;
432 dns_zone_t *rss_raw;
433 isc_event_t *rss_event;
434 dns_update_state_t *rss_state;
435
436 isc_stats_t *gluecachestats;
437 };
438
439 #define zonediff_init(z, d) \
440 do { \
441 dns__zonediff_t *_z = (z); \
442 (_z)->diff = (d); \
443 (_z)->offline = false; \
444 } while (0)
445
446 #define DNS_ZONE_FLAG(z,f) ((z)->flags & (f))
447 #define DNS_ZONE_SETFLAG(z,f) do { \
448 INSIST(LOCKED_ZONE(z)); \
449 (z)->flags |= (f); \
450 } while (0)
451 #define DNS_ZONE_CLRFLAG(z,f) do { \
452 INSIST(LOCKED_ZONE(z)); \
453 (z)->flags &= ~(f); \
454 } while (0)
455 /* XXX MPA these may need to go back into zone.h */
456 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
457 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
458 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
459 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
460 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
461 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
462 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
463 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
464 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
465 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
466 * uptodate */
467 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
468 * messages */
469 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
470 * reload */
471 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
472 * zone with no masters
473 * occurred */
474 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
475 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
476 * from SOA (if not set, we
477 * are still using
478 * default timer values) */
479 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
480 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
481 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
482 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
483 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
484 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
485 #define DNS_ZONEFLG_FLUSH 0x00200000U
486 #define DNS_ZONEFLG_NOEDNS 0x00400000U
487 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
488 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
489 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
490 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
491 #define DNS_ZONEFLG_THAW 0x08000000U
492 #define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */
493 #define DNS_ZONEFLG_NODELAY 0x20000000U
494 #define DNS_ZONEFLG_SENDSECURE 0x40000000U
495 #define DNS_ZONEFLG_NEEDSTARTUPNOTIFY 0x80000000U /*%< need to send out notify
496 * due to the zone just
497 * being loaded for the
498 * first time. */
499
500 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
501 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
502
503 /* Flags for zone_load() */
504 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
505 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
506 load. */
507
508 #define UNREACH_CHACHE_SIZE 10U
509 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
510
511 #define CHECK(op) \
512 do { result = (op); \
513 if (result != ISC_R_SUCCESS) goto failure; \
514 } while (0)
515
516 struct dns_unreachable {
517 isc_sockaddr_t remote;
518 isc_sockaddr_t local;
519 uint32_t expire;
520 uint32_t last;
521 uint32_t count;
522 };
523
524 struct dns_zonemgr {
525 unsigned int magic;
526 isc_mem_t * mctx;
527 int refs; /* Locked by rwlock */
528 isc_taskmgr_t * taskmgr;
529 isc_timermgr_t * timermgr;
530 isc_socketmgr_t * socketmgr;
531 isc_taskpool_t * zonetasks;
532 isc_taskpool_t * loadtasks;
533 isc_task_t * task;
534 isc_pool_t * mctxpool;
535 isc_ratelimiter_t * notifyrl;
536 isc_ratelimiter_t * refreshrl;
537 isc_ratelimiter_t * startupnotifyrl;
538 isc_ratelimiter_t * startuprefreshrl;
539 isc_rwlock_t rwlock;
540 isc_mutex_t iolock;
541 isc_rwlock_t urlock;
542
543 /* Locked by rwlock. */
544 dns_zonelist_t zones;
545 dns_zonelist_t waiting_for_xfrin;
546 dns_zonelist_t xfrin_in_progress;
547
548 /* Configuration data. */
549 uint32_t transfersin;
550 uint32_t transfersperns;
551 unsigned int notifyrate;
552 unsigned int startupnotifyrate;
553 unsigned int serialqueryrate;
554 unsigned int startupserialqueryrate;
555
556 /* Locked by iolock */
557 uint32_t iolimit;
558 uint32_t ioactive;
559 dns_iolist_t high;
560 dns_iolist_t low;
561
562 /* Locked by urlock. */
563 /* LRU cache */
564 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
565 };
566
567 /*%
568 * Hold notify state.
569 */
570 struct dns_notify {
571 unsigned int magic;
572 unsigned int flags;
573 isc_mem_t *mctx;
574 dns_zone_t *zone;
575 dns_adbfind_t *find;
576 dns_request_t *request;
577 dns_name_t ns;
578 isc_sockaddr_t dst;
579 dns_tsigkey_t *key;
580 isc_dscp_t dscp;
581 ISC_LINK(dns_notify_t) link;
582 isc_event_t *event;
583 };
584
585 #define DNS_NOTIFY_NOSOA 0x0001U
586 #define DNS_NOTIFY_STARTUP 0x0002U
587
588 /*%
589 * dns_stub holds state while performing a 'stub' transfer.
590 * 'db' is the zone's 'db' or a new one if this is the initial
591 * transfer.
592 */
593
594 struct dns_stub {
595 unsigned int magic;
596 isc_mem_t *mctx;
597 dns_zone_t *zone;
598 dns_db_t *db;
599 dns_dbversion_t *version;
600 };
601
602 /*%
603 * Hold load state.
604 */
605 struct dns_load {
606 unsigned int magic;
607 isc_mem_t *mctx;
608 dns_zone_t *zone;
609 dns_db_t *db;
610 isc_time_t loadtime;
611 dns_rdatacallbacks_t callbacks;
612 };
613
614 /*%
615 * Hold forward state.
616 */
617 struct dns_forward {
618 unsigned int magic;
619 isc_mem_t *mctx;
620 dns_zone_t *zone;
621 isc_buffer_t *msgbuf;
622 dns_request_t *request;
623 uint32_t which;
624 isc_sockaddr_t addr;
625 dns_updatecallback_t callback;
626 void *callback_arg;
627 unsigned int options;
628 ISC_LINK(dns_forward_t) link;
629 };
630
631 /*%
632 * Hold IO request state.
633 */
634 struct dns_io {
635 unsigned int magic;
636 dns_zonemgr_t *zmgr;
637 bool high;
638 isc_task_t *task;
639 ISC_LINK(dns_io_t) link;
640 isc_event_t *event;
641 };
642
643 /*%
644 * Hold state for when we are signing a zone with a new
645 * DNSKEY as result of an update.
646 */
647 struct dns_signing {
648 unsigned int magic;
649 dns_db_t *db;
650 dns_dbiterator_t *dbiterator;
651 dns_secalg_t algorithm;
652 uint16_t keyid;
653 bool deleteit;
654 bool done;
655 ISC_LINK(dns_signing_t) link;
656 };
657
658 struct dns_nsec3chain {
659 unsigned int magic;
660 dns_db_t *db;
661 dns_dbiterator_t *dbiterator;
662 dns_rdata_nsec3param_t nsec3param;
663 unsigned char salt[255];
664 bool done;
665 bool seen_nsec;
666 bool delete_nsec;
667 bool save_delete_nsec;
668 ISC_LINK(dns_nsec3chain_t) link;
669 };
670 /*%<
671 * 'dbiterator' contains a iterator for the database. If we are creating
672 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
673 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
674 * iterated.
675 *
676 * 'nsec3param' contains the parameters of the NSEC3 chain being created
677 * or removed.
678 *
679 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
680 *
681 * 'seen_nsec' will be set to true if, while iterating the zone to create a
682 * NSEC3 chain, a NSEC record is seen.
683 *
684 * 'delete_nsec' will be set to true if, at the completion of the creation
685 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
686 * are in the process of deleting the NSEC chain.
687 *
688 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
689 * so it can be recovered in the event of a error.
690 */
691
692 struct dns_keyfetch {
693 dns_fixedname_t name;
694 dns_rdataset_t keydataset;
695 dns_rdataset_t dnskeyset;
696 dns_rdataset_t dnskeysigset;
697 dns_zone_t *zone;
698 dns_db_t *db;
699 dns_fetch_t *fetch;
700 };
701
702 /*%
703 * Hold state for an asynchronous load
704 */
705 struct dns_asyncload {
706 dns_zone_t *zone;
707 unsigned int flags;
708 dns_zt_zoneloaded_t loaded;
709 void *loaded_arg;
710 };
711
712 /*%
713 * Reference to an include file encountered during loading
714 */
715 struct dns_include {
716 char *name;
717 isc_time_t filetime;
718 ISC_LINK(dns_include_t) link;
719 };
720
721 /*
722 * These can be overridden by the -T mkeytimers option on the command
723 * line, so that we can test with shorter periods than specified in
724 * RFC 5011.
725 */
726 #define HOUR 3600
727 #define DAY (24*HOUR)
728 #define MONTH (30*DAY)
729 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_hour = HOUR;
730 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_day = DAY;
731 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_month = MONTH;
732
733 #define SEND_BUFFER_SIZE 2048
734
735 static void zone_settimer(dns_zone_t *, isc_time_t *);
736 static void cancel_refresh(dns_zone_t *);
737 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
738 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
739 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
740 ISC_FORMAT_PRINTF(3, 4);
741 static void queue_xfrin(dns_zone_t *zone);
742 static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
743 dns_diff_t *diff, dns_diffop_t op,
744 dns_name_t *name, dns_ttl_t ttl,
745 dns_rdata_t *rdata);
746 static void zone_unload(dns_zone_t *zone);
747 static void zone_expire(dns_zone_t *zone);
748 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
749 static void zone_idetach(dns_zone_t **zonep);
750 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
751 bool dump);
752 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
753 static inline void zone_detachdb(dns_zone_t *zone);
754 static isc_result_t default_journal(dns_zone_t *zone);
755 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
756 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
757 isc_time_t loadtime, isc_result_t result);
758 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
759 static void zone_shutdown(isc_task_t *, isc_event_t *);
760 static void zone_loaddone(void *arg, isc_result_t result);
761 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
762 isc_time_t loadtime);
763 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
764 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
765 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
766 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
767 static isc_result_t zone_send_secureserial(dns_zone_t *zone,
768 uint32_t serial);
769 static void refresh_callback(isc_task_t *, isc_event_t *);
770 static void stub_callback(isc_task_t *, isc_event_t *);
771 static void queue_soa_query(dns_zone_t *zone);
772 static void soa_query(isc_task_t *, isc_event_t *);
773 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
774 dns_stub_t *stub);
775 static int message_count(dns_message_t *msg, dns_section_t section,
776 dns_rdatatype_t type);
777 static void notify_cancel(dns_zone_t *zone);
778 static void notify_find_address(dns_notify_t *notify);
779 static void notify_send(dns_notify_t *notify);
780 static isc_result_t notify_createmessage(dns_zone_t *zone,
781 unsigned int flags,
782 dns_message_t **messagep);
783 static void notify_done(isc_task_t *task, isc_event_t *event);
784 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
785 static isc_result_t zone_dump(dns_zone_t *, bool);
786 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
787 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
788 dns_zone_t *zone);
789 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi);
790 static void zonemgr_free(dns_zonemgr_t *zmgr);
791 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, bool high,
792 isc_task_t *task, isc_taskaction_t action,
793 void *arg, dns_io_t **iop);
794 static void zonemgr_putio(dns_io_t **iop);
795 static void zonemgr_cancelio(dns_io_t *io);
796
797 static isc_result_t
798 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
799 unsigned int *soacount, uint32_t *serial,
800 uint32_t *refresh, uint32_t *retry,
801 uint32_t *expire, uint32_t *minimum,
802 unsigned int *errors);
803
804 static void zone_freedbargs(dns_zone_t *zone);
805 static void forward_callback(isc_task_t *task, isc_event_t *event);
806 static void zone_saveunique(dns_zone_t *zone, const char *path,
807 const char *templat);
808 static void zone_maintenance(dns_zone_t *zone);
809 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
810 static void dump_done(void *arg, isc_result_t result);
811 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
812 uint16_t keyid,
813 bool deleteit);
814 static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
815 dns_dbnode_t *node, dns_name_t *name,
816 dns_diff_t *diff);
817 static void zone_rekey(dns_zone_t *zone);
818 static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db);
819 static void setrl(isc_ratelimiter_t *rl, unsigned int *rate,
820 unsigned int value);
821
822 #define ENTER zone_debuglog(zone, me, 1, "enter")
823
824 static const unsigned int dbargc_default = 1;
825 static const char *dbargv_default[] = { "rbt" };
826
827 #define DNS_ZONE_JITTER_ADD(a, b, c) \
828 do { \
829 isc_interval_t _i; \
830 uint32_t _j; \
831 _j = (b) - isc_random_uniform((b)/4); \
832 isc_interval_set(&_i, _j, 0); \
833 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
834 dns_zone_log(zone, ISC_LOG_WARNING, \
835 "epoch approaching: upgrade required: " \
836 "now + %s failed", #b); \
837 isc_interval_set(&_i, _j/2, 0); \
838 (void)isc_time_add((a), &_i, (c)); \
839 } \
840 } while (0)
841
842 #define DNS_ZONE_TIME_ADD(a, b, c) \
843 do { \
844 isc_interval_t _i; \
845 isc_interval_set(&_i, (b), 0); \
846 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
847 dns_zone_log(zone, ISC_LOG_WARNING, \
848 "epoch approaching: upgrade required: " \
849 "now + %s failed", #b); \
850 isc_interval_set(&_i, (b)/2, 0); \
851 (void)isc_time_add((a), &_i, (c)); \
852 } \
853 } while (0)
854
855 typedef struct nsec3param nsec3param_t;
856 struct nsec3param {
857 unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
858 unsigned int length;
859 bool nsec;
860 bool replace;
861 ISC_LINK(nsec3param_t) link;
862 };
863 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t;
864 struct np3event {
865 isc_event_t event;
866 nsec3param_t params;
867 };
868
869 struct ssevent {
870 isc_event_t event;
871 uint32_t serial;
872 };
873
874 /*%
875 * Increment resolver-related statistics counters. Zone must be locked.
876 */
877 static inline void
878 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
879 if (zone->stats != NULL)
880 isc_stats_increment(zone->stats, counter);
881 }
882
883 /***
884 *** Public functions.
885 ***/
886
887 isc_result_t
888 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
889 isc_result_t result;
890 dns_zone_t *zone;
891 isc_time_t now;
892
893 REQUIRE(zonep != NULL && *zonep == NULL);
894 REQUIRE(mctx != NULL);
895
896 TIME_NOW(&now);
897 zone = isc_mem_get(mctx, sizeof(*zone));
898 if (zone == NULL) {
899 return (ISC_R_NOMEMORY);
900 }
901
902 zone->mctx = NULL;
903 isc_mem_attach(mctx, &zone->mctx);
904
905 isc_mutex_init(&zone->lock);
906
907 result = ZONEDB_INITLOCK(&zone->dblock);
908 if (result != ISC_R_SUCCESS) {
909 goto free_mutex;
910 }
911
912 /* XXX MPA check that all elements are initialised */
913 #ifdef DNS_ZONE_CHECKLOCK
914 zone->locked = false;
915 #endif
916 zone->db = NULL;
917 zone->zmgr = NULL;
918 ISC_LINK_INIT(zone, link);
919 isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
920 zone->irefs = 0;
921 dns_name_init(&zone->origin, NULL);
922 zone->strnamerd = NULL;
923 zone->strname = NULL;
924 zone->strrdclass = NULL;
925 zone->strviewname = NULL;
926 zone->masterfile = NULL;
927 ISC_LIST_INIT(zone->includes);
928 ISC_LIST_INIT(zone->newincludes);
929 zone->nincludes = 0;
930 zone->masterformat = dns_masterformat_none;
931 zone->masterstyle = NULL;
932 zone->keydirectory = NULL;
933 zone->journalsize = -1;
934 zone->journal = NULL;
935 zone->rdclass = dns_rdataclass_none;
936 zone->type = dns_zone_none;
937 zone->flags = 0;
938 zone->options = 0;
939 zone->keyopts = 0;
940 zone->db_argc = 0;
941 zone->db_argv = NULL;
942 isc_time_settoepoch(&zone->expiretime);
943 isc_time_settoepoch(&zone->refreshtime);
944 isc_time_settoepoch(&zone->dumptime);
945 isc_time_settoepoch(&zone->loadtime);
946 zone->notifytime = now;
947 isc_time_settoepoch(&zone->resigntime);
948 isc_time_settoepoch(&zone->keywarntime);
949 isc_time_settoepoch(&zone->signingtime);
950 isc_time_settoepoch(&zone->nsec3chaintime);
951 isc_time_settoepoch(&zone->refreshkeytime);
952 zone->refreshkeyinterval = 0;
953 zone->refreshkeycount = 0;
954 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
955 zone->retry = DNS_ZONE_DEFAULTRETRY;
956 zone->expire = 0;
957 zone->minimum = 0;
958 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
959 zone->minrefresh = DNS_ZONE_MINREFRESH;
960 zone->maxretry = DNS_ZONE_MAXRETRY;
961 zone->minretry = DNS_ZONE_MINRETRY;
962 zone->masters = NULL;
963 zone->masterdscps = NULL;
964 zone->masterkeynames = NULL;
965 zone->mastersok = NULL;
966 zone->masterscnt = 0;
967 zone->curmaster = 0;
968 zone->maxttl = 0;
969 zone->notify = NULL;
970 zone->notifykeynames = NULL;
971 zone->notifydscp = NULL;
972 zone->notifytype = dns_notifytype_yes;
973 zone->notifycnt = 0;
974 zone->task = NULL;
975 zone->loadtask = NULL;
976 zone->update_acl = NULL;
977 zone->forward_acl = NULL;
978 zone->notify_acl = NULL;
979 zone->query_acl = NULL;
980 zone->queryon_acl = NULL;
981 zone->xfr_acl = NULL;
982 zone->update_disabled = false;
983 zone->zero_no_soa_ttl = true;
984 zone->check_names = dns_severity_ignore;
985 zone->request = NULL;
986 zone->lctx = NULL;
987 zone->readio = NULL;
988 zone->dctx = NULL;
989 zone->writeio = NULL;
990 zone->timer = NULL;
991 zone->idlein = DNS_DEFAULT_IDLEIN;
992 zone->idleout = DNS_DEFAULT_IDLEOUT;
993 zone->log_key_expired_timer = 0;
994 ISC_LIST_INIT(zone->notifies);
995 isc_sockaddr_any(&zone->notifysrc4);
996 isc_sockaddr_any6(&zone->notifysrc6);
997 isc_sockaddr_any(&zone->xfrsource4);
998 isc_sockaddr_any6(&zone->xfrsource6);
999 isc_sockaddr_any(&zone->altxfrsource4);
1000 isc_sockaddr_any6(&zone->altxfrsource6);
1001 zone->notifysrc4dscp = -1;
1002 zone->notifysrc6dscp = -1;
1003 zone->xfrsource4dscp = -1;
1004 zone->xfrsource6dscp = -1;
1005 zone->altxfrsource4dscp = -1;
1006 zone->altxfrsource6dscp = -1;
1007 zone->xfr = NULL;
1008 zone->tsigkey = NULL;
1009 zone->maxxfrin = MAX_XFER_TIME;
1010 zone->maxxfrout = MAX_XFER_TIME;
1011 zone->ssutable = NULL;
1012 zone->sigvalidityinterval = 30 * 24 * 3600;
1013 zone->keyvalidityinterval = 0;
1014 zone->sigresigninginterval = 7 * 24 * 3600;
1015 zone->view = NULL;
1016 zone->prev_view = NULL;
1017 zone->checkmx = NULL;
1018 zone->checksrv = NULL;
1019 zone->checkns = NULL;
1020 ISC_LINK_INIT(zone, statelink);
1021 zone->statelist = NULL;
1022 zone->stats = NULL;
1023 zone->requeststats_on = false;
1024 zone->statlevel = dns_zonestat_none;
1025 zone->requeststats = NULL;
1026 zone->rcvquerystats = NULL;
1027 zone->notifydelay = 5;
1028 zone->isself = NULL;
1029 zone->isselfarg = NULL;
1030 ISC_LIST_INIT(zone->signing);
1031 ISC_LIST_INIT(zone->nsec3chain);
1032 ISC_LIST_INIT(zone->setnsec3param_queue);
1033 zone->signatures = 10;
1034 zone->nodes = 100;
1035 zone->privatetype = (dns_rdatatype_t)0xffffU;
1036 zone->added = false;
1037 zone->automatic = false;
1038 zone->rpzs = NULL;
1039 zone->rpz_num = DNS_RPZ_INVALID_NUM;
1040
1041 zone->catzs = NULL;
1042 zone->parentcatz = NULL;
1043
1044 ISC_LIST_INIT(zone->forwards);
1045 zone->raw = NULL;
1046 zone->secure = NULL;
1047 zone->sourceserial = 0;
1048 zone->sourceserialset = false;
1049 zone->requestixfr = true;
1050 zone->requestexpire = true;
1051 ISC_LIST_INIT(zone->rss_events);
1052 zone->rss_db = NULL;
1053 zone->rss_raw = NULL;
1054 zone->rss_newver = NULL;
1055 zone->rss_oldver = NULL;
1056 zone->rss_event = NULL;
1057 zone->rss_state = NULL;
1058 zone->updatemethod = dns_updatemethod_increment;
1059 zone->maxrecords = 0U;
1060
1061 zone->magic = ZONE_MAGIC;
1062
1063 zone->gluecachestats = NULL;
1064 result = isc_stats_create(mctx, &zone->gluecachestats,
1065 dns_gluecachestatscounter_max);
1066 if (result != ISC_R_SUCCESS) {
1067 goto free_erefs;
1068 }
1069
1070 /* Must be after magic is set. */
1071 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
1072 if (result != ISC_R_SUCCESS) {
1073 goto free_stats;
1074 }
1075
1076 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
1077 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
1078 NULL, NULL);
1079 *zonep = zone;
1080 return (ISC_R_SUCCESS);
1081
1082 free_stats:
1083 if (zone->gluecachestats != NULL)
1084 isc_stats_detach(&zone->gluecachestats);
1085
1086 free_erefs:
1087 INSIST(isc_refcount_decrement(&zone->erefs) > 0);
1088 isc_refcount_destroy(&zone->erefs);
1089
1090 ZONEDB_DESTROYLOCK(&zone->dblock);
1091
1092 free_mutex:
1093 isc_mutex_destroy(&zone->lock);
1094
1095 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
1096 return (result);
1097 }
1098
1099 /*
1100 * Free a zone. Because we require that there be no more
1101 * outstanding events or references, no locking is necessary.
1102 */
1103 static void
1104 zone_free(dns_zone_t *zone) {
1105 isc_mem_t *mctx = NULL;
1106 dns_signing_t *signing;
1107 dns_nsec3chain_t *nsec3chain;
1108 isc_event_t *setnsec3param_event;
1109 dns_include_t *include;
1110
1111 REQUIRE(DNS_ZONE_VALID(zone));
1112 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
1113 REQUIRE(zone->irefs == 0);
1114 REQUIRE(!LOCKED_ZONE(zone));
1115 REQUIRE(zone->timer == NULL);
1116 REQUIRE(zone->zmgr == NULL);
1117
1118 /*
1119 * Managed objects. Order is important.
1120 */
1121 if (zone->request != NULL) {
1122 dns_request_destroy(&zone->request); /* XXXMPA */
1123 }
1124 INSIST(zone->readio == NULL);
1125 INSIST(zone->statelist == NULL);
1126 INSIST(zone->writeio == NULL);
1127
1128 if (zone->task != NULL) {
1129 isc_task_detach(&zone->task);
1130 }
1131 if (zone->loadtask != NULL) {
1132 isc_task_detach(&zone->loadtask);
1133 }
1134 if (zone->view != NULL) {
1135 dns_view_weakdetach(&zone->view);
1136 }
1137 if (zone->prev_view != NULL) {
1138 dns_view_weakdetach(&zone->prev_view);
1139 }
1140
1141 /* Unmanaged objects */
1142 while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
1143 setnsec3param_event = ISC_LIST_HEAD(zone->setnsec3param_queue);
1144 ISC_LIST_UNLINK(zone->setnsec3param_queue, setnsec3param_event,
1145 ev_link);
1146 isc_event_free(&setnsec3param_event);
1147 }
1148 for (signing = ISC_LIST_HEAD(zone->signing);
1149 signing != NULL;
1150 signing = ISC_LIST_HEAD(zone->signing)) {
1151 ISC_LIST_UNLINK(zone->signing, signing, link);
1152 dns_db_detach(&signing->db);
1153 dns_dbiterator_destroy(&signing->dbiterator);
1154 isc_mem_put(zone->mctx, signing, sizeof *signing);
1155 }
1156 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
1157 nsec3chain != NULL;
1158 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
1159 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
1160 dns_db_detach(&nsec3chain->db);
1161 dns_dbiterator_destroy(&nsec3chain->dbiterator);
1162 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
1163 }
1164 for (include = ISC_LIST_HEAD(zone->includes);
1165 include != NULL;
1166 include = ISC_LIST_HEAD(zone->includes)) {
1167 ISC_LIST_UNLINK(zone->includes, include, link);
1168 isc_mem_free(zone->mctx, include->name);
1169 isc_mem_put(zone->mctx, include, sizeof *include);
1170 }
1171 for (include = ISC_LIST_HEAD(zone->newincludes);
1172 include != NULL;
1173 include = ISC_LIST_HEAD(zone->newincludes)) {
1174 ISC_LIST_UNLINK(zone->newincludes, include, link);
1175 isc_mem_free(zone->mctx, include->name);
1176 isc_mem_put(zone->mctx, include, sizeof *include);
1177 }
1178 if (zone->masterfile != NULL) {
1179 isc_mem_free(zone->mctx, zone->masterfile);
1180 }
1181 zone->masterfile = NULL;
1182 if (zone->keydirectory != NULL) {
1183 isc_mem_free(zone->mctx, zone->keydirectory);
1184 }
1185 zone->keydirectory = NULL;
1186 zone->journalsize = -1;
1187 if (zone->journal != NULL) {
1188 isc_mem_free(zone->mctx, zone->journal);
1189 }
1190 zone->journal = NULL;
1191 if (zone->stats != NULL) {
1192 isc_stats_detach(&zone->stats);
1193 }
1194 if (zone->requeststats != NULL) {
1195 isc_stats_detach(&zone->requeststats);
1196 }
1197 if (zone->rcvquerystats != NULL){
1198 dns_stats_detach(&zone->rcvquerystats);
1199 }
1200 if (zone->db != NULL) {
1201 zone_detachdb(zone);
1202 }
1203 if (zone->rpzs != NULL) {
1204 REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones);
1205 dns_rpz_detach_rpzs(&zone->rpzs);
1206 zone->rpz_num = DNS_RPZ_INVALID_NUM;
1207 }
1208 if (zone->catzs != NULL) {
1209 dns_catz_catzs_detach(&zone->catzs);
1210 }
1211 zone_freedbargs(zone);
1212 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL,
1213 NULL, 0) == ISC_R_SUCCESS);
1214 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) == ISC_R_SUCCESS);
1215 zone->check_names = dns_severity_ignore;
1216 if (zone->update_acl != NULL) {
1217 dns_acl_detach(&zone->update_acl);
1218 }
1219 if (zone->forward_acl != NULL) {
1220 dns_acl_detach(&zone->forward_acl);
1221 }
1222 if (zone->notify_acl != NULL) {
1223 dns_acl_detach(&zone->notify_acl);
1224 }
1225 if (zone->query_acl != NULL) {
1226 dns_acl_detach(&zone->query_acl);
1227 }
1228 if (zone->queryon_acl != NULL) {
1229 dns_acl_detach(&zone->queryon_acl);
1230 }
1231 if (zone->xfr_acl != NULL) {
1232 dns_acl_detach(&zone->xfr_acl);
1233 }
1234 if (dns_name_dynamic(&zone->origin)) {
1235 dns_name_free(&zone->origin, zone->mctx);
1236 }
1237 if (zone->strnamerd != NULL) {
1238 isc_mem_free(zone->mctx, zone->strnamerd);
1239 }
1240 if (zone->strname != NULL) {
1241 isc_mem_free(zone->mctx, zone->strname);
1242 }
1243 if (zone->strrdclass != NULL) {
1244 isc_mem_free(zone->mctx, zone->strrdclass);
1245 }
1246 if (zone->strviewname != NULL) {
1247 isc_mem_free(zone->mctx, zone->strviewname);
1248 }
1249 if (zone->ssutable != NULL) {
1250 dns_ssutable_detach(&zone->ssutable);
1251 }
1252 if (zone->gluecachestats != NULL) {
1253 isc_stats_detach(&zone->gluecachestats);
1254 }
1255
1256 /* last stuff */
1257 ZONEDB_DESTROYLOCK(&zone->dblock);
1258 isc_mutex_destroy(&zone->lock);
1259 zone->magic = 0;
1260 mctx = zone->mctx;
1261 isc_mem_put(mctx, zone, sizeof(*zone));
1262 isc_mem_detach(&mctx);
1263 }
1264
1265 /*
1266 * Returns true iff this the signed side of an inline-signing zone.
1267 * Caller should hold zone lock.
1268 */
1269 static inline bool
1270 inline_secure(dns_zone_t *zone) {
1271 REQUIRE(DNS_ZONE_VALID(zone));
1272 if (zone->raw != NULL)
1273 return (true);
1274 return (false);
1275 }
1276
1277 /*
1278 * Returns true iff this the unsigned side of an inline-signing zone
1279 * Caller should hold zone lock.
1280 */
1281 static inline bool
1282 inline_raw(dns_zone_t *zone) {
1283 REQUIRE(DNS_ZONE_VALID(zone));
1284 if (zone->secure != NULL)
1285 return (true);
1286 return (false);
1287 }
1288
1289 /*
1290 * Single shot.
1291 */
1292 void
1293 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
1294 char namebuf[1024];
1295
1296 REQUIRE(DNS_ZONE_VALID(zone));
1297 REQUIRE(rdclass != dns_rdataclass_none);
1298
1299 /*
1300 * Test and set.
1301 */
1302 LOCK_ZONE(zone);
1303 INSIST(zone != zone->raw);
1304 REQUIRE(zone->rdclass == dns_rdataclass_none ||
1305 zone->rdclass == rdclass);
1306 zone->rdclass = rdclass;
1307
1308 if (zone->strnamerd != NULL)
1309 isc_mem_free(zone->mctx, zone->strnamerd);
1310 if (zone->strrdclass != NULL)
1311 isc_mem_free(zone->mctx, zone->strrdclass);
1312
1313 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1314 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1315 zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
1316 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
1317
1318 if (inline_secure(zone))
1319 dns_zone_setclass(zone->raw, rdclass);
1320 UNLOCK_ZONE(zone);
1321 }
1322
1323 dns_rdataclass_t
1324 dns_zone_getclass(dns_zone_t *zone) {
1325 REQUIRE(DNS_ZONE_VALID(zone));
1326
1327 return (zone->rdclass);
1328 }
1329
1330 void
1331 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
1332 REQUIRE(DNS_ZONE_VALID(zone));
1333
1334 LOCK_ZONE(zone);
1335 zone->notifytype = notifytype;
1336 UNLOCK_ZONE(zone);
1337 }
1338
1339 isc_result_t
1340 dns_zone_getserial(dns_zone_t *zone, uint32_t *serialp) {
1341 isc_result_t result;
1342 unsigned int soacount;
1343
1344 REQUIRE(DNS_ZONE_VALID(zone));
1345 REQUIRE(serialp != NULL);
1346
1347 LOCK_ZONE(zone);
1348 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1349 if (zone->db != NULL) {
1350 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
1351 serialp, NULL, NULL, NULL, NULL,
1352 NULL);
1353 if (result == ISC_R_SUCCESS && soacount == 0)
1354 result = ISC_R_FAILURE;
1355 } else
1356 result = DNS_R_NOTLOADED;
1357 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1358 UNLOCK_ZONE(zone);
1359
1360 return (result);
1361 }
1362
1363 /*
1364 * Single shot.
1365 */
1366 void
1367 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
1368 char namebuf[1024];
1369
1370 REQUIRE(DNS_ZONE_VALID(zone));
1371 REQUIRE(type != dns_zone_none);
1372
1373 /*
1374 * Test and set.
1375 */
1376 LOCK_ZONE(zone);
1377 REQUIRE(zone->type == dns_zone_none || zone->type == type);
1378 zone->type = type;
1379
1380 if (zone->strnamerd != NULL)
1381 isc_mem_free(zone->mctx, zone->strnamerd);
1382
1383 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1384 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1385 UNLOCK_ZONE(zone);
1386 }
1387
1388 static void
1389 zone_freedbargs(dns_zone_t *zone) {
1390 unsigned int i;
1391
1392 /* Free the old database argument list. */
1393 if (zone->db_argv != NULL) {
1394 for (i = 0; i < zone->db_argc; i++)
1395 isc_mem_free(zone->mctx, zone->db_argv[i]);
1396 isc_mem_put(zone->mctx, zone->db_argv,
1397 zone->db_argc * sizeof(*zone->db_argv));
1398 }
1399 zone->db_argc = 0;
1400 zone->db_argv = NULL;
1401 }
1402
1403 isc_result_t
1404 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1405 size_t size = 0;
1406 unsigned int i;
1407 isc_result_t result = ISC_R_SUCCESS;
1408 void *mem;
1409 char **tmp, *tmp2, *base;
1410
1411 REQUIRE(DNS_ZONE_VALID(zone));
1412 REQUIRE(argv != NULL && *argv == NULL);
1413
1414 LOCK_ZONE(zone);
1415 size = (zone->db_argc + 1) * sizeof(char *);
1416 for (i = 0; i < zone->db_argc; i++)
1417 size += strlen(zone->db_argv[i]) + 1;
1418 mem = isc_mem_allocate(mctx, size);
1419 if (mem != NULL) {
1420 tmp = mem;
1421 tmp2 = mem;
1422 base = mem;
1423 tmp2 += (zone->db_argc + 1) * sizeof(char *);
1424 for (i = 0; i < zone->db_argc; i++) {
1425 *tmp++ = tmp2;
1426 strlcpy(tmp2, zone->db_argv[i], size - (tmp2 - base));
1427 tmp2 += strlen(tmp2) + 1;
1428 }
1429 *tmp = NULL;
1430 } else
1431 result = ISC_R_NOMEMORY;
1432 UNLOCK_ZONE(zone);
1433 *argv = mem;
1434 return (result);
1435 }
1436
1437 isc_result_t
1438 dns_zone_setdbtype(dns_zone_t *zone,
1439 unsigned int dbargc, const char * const *dbargv)
1440 {
1441 isc_result_t result = ISC_R_SUCCESS;
1442 char **argv = NULL;
1443 unsigned int i;
1444
1445 REQUIRE(DNS_ZONE_VALID(zone));
1446 REQUIRE(dbargc >= 1);
1447 REQUIRE(dbargv != NULL);
1448
1449 LOCK_ZONE(zone);
1450
1451 /* Set up a new database argument list. */
1452 argv = isc_mem_get(zone->mctx, dbargc * sizeof(*argv));
1453 if (argv == NULL) {
1454 goto nomem;
1455 }
1456 for (i = 0; i < dbargc; i++) {
1457 argv[i] = NULL;
1458 }
1459 for (i = 0; i < dbargc; i++) {
1460 argv[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1461 if (argv[i] == NULL)
1462 goto nomem;
1463 }
1464
1465 /* Free the old list. */
1466 zone_freedbargs(zone);
1467
1468 zone->db_argc = dbargc;
1469 zone->db_argv = argv;
1470 result = ISC_R_SUCCESS;
1471 goto unlock;
1472
1473 nomem:
1474 if (argv != NULL) {
1475 for (i = 0; i < dbargc; i++) {
1476 if (argv[i] != NULL) {
1477 isc_mem_free(zone->mctx, argv[i]);
1478 }
1479 }
1480 isc_mem_put(zone->mctx, argv, dbargc * sizeof(*argv));
1481 }
1482 result = ISC_R_NOMEMORY;
1483
1484 unlock:
1485 UNLOCK_ZONE(zone);
1486 return (result);
1487 }
1488
1489 static void
1490 dns_zone_setview_helper(dns_zone_t *zone, dns_view_t *view) {
1491 char namebuf[1024];
1492
1493 if (zone->prev_view == NULL && zone->view != NULL) {
1494 dns_view_weakattach(zone->view, &zone->prev_view);
1495 }
1496
1497 INSIST(zone != zone->raw);
1498 if (zone->view != NULL) {
1499 dns_view_weakdetach(&zone->view);
1500 }
1501 dns_view_weakattach(view, &zone->view);
1502
1503 if (zone->strviewname != NULL) {
1504 isc_mem_free(zone->mctx, zone->strviewname);
1505 }
1506 if (zone->strnamerd != NULL) {
1507 isc_mem_free(zone->mctx, zone->strnamerd);
1508 }
1509
1510 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1511 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1512 zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1513 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1514
1515 if (inline_secure(zone)) {
1516 dns_zone_setview(zone->raw, view);
1517 }
1518 }
1519
1520 void
1521 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1522 REQUIRE(DNS_ZONE_VALID(zone));
1523
1524 LOCK_ZONE(zone);
1525 dns_zone_setview_helper(zone, view);
1526 UNLOCK_ZONE(zone);
1527 }
1528
1529 dns_view_t *
1530 dns_zone_getview(dns_zone_t *zone) {
1531 REQUIRE(DNS_ZONE_VALID(zone));
1532
1533 return (zone->view);
1534 }
1535
1536 void
1537 dns_zone_setviewcommit(dns_zone_t *zone) {
1538 REQUIRE(DNS_ZONE_VALID(zone));
1539
1540 LOCK_ZONE(zone);
1541 if (zone->prev_view != NULL)
1542 dns_view_weakdetach(&zone->prev_view);
1543 UNLOCK_ZONE(zone);
1544 }
1545
1546 void
1547 dns_zone_setviewrevert(dns_zone_t *zone) {
1548 REQUIRE(DNS_ZONE_VALID(zone));
1549
1550 LOCK_ZONE(zone);
1551 if (zone->prev_view != NULL) {
1552 dns_zone_setview_helper(zone, zone->prev_view);
1553 dns_view_weakdetach(&zone->prev_view);
1554 }
1555 UNLOCK_ZONE(zone);
1556 }
1557
1558 isc_result_t
1559 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1560 isc_result_t result;
1561 char namebuf[1024];
1562
1563 REQUIRE(DNS_ZONE_VALID(zone));
1564 REQUIRE(origin != NULL);
1565
1566 LOCK_ZONE(zone);
1567 INSIST(zone != zone->raw);
1568 if (dns_name_dynamic(&zone->origin)) {
1569 dns_name_free(&zone->origin, zone->mctx);
1570 dns_name_init(&zone->origin, NULL);
1571 }
1572 result = dns_name_dup(origin, zone->mctx, &zone->origin);
1573
1574 if (zone->strnamerd != NULL)
1575 isc_mem_free(zone->mctx, zone->strnamerd);
1576 if (zone->strname != NULL)
1577 isc_mem_free(zone->mctx, zone->strname);
1578
1579 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1580 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1581 zone_name_tostr(zone, namebuf, sizeof namebuf);
1582 zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1583
1584 if (result == ISC_R_SUCCESS && inline_secure(zone))
1585 result = dns_zone_setorigin(zone->raw, origin);
1586 UNLOCK_ZONE(zone);
1587 return (result);
1588 }
1589
1590 static isc_result_t
1591 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1592 char *copy;
1593
1594 if (value != NULL) {
1595 copy = isc_mem_strdup(zone->mctx, value);
1596 if (copy == NULL)
1597 return (ISC_R_NOMEMORY);
1598 } else {
1599 copy = NULL;
1600 }
1601
1602 if (*field != NULL)
1603 isc_mem_free(zone->mctx, *field);
1604
1605 *field = copy;
1606 return (ISC_R_SUCCESS);
1607 }
1608
1609 isc_result_t
1610 dns_zone_setfile(dns_zone_t *zone, const char *file,
1611 dns_masterformat_t format,
1612 const dns_master_style_t *style)
1613 {
1614 isc_result_t result = ISC_R_SUCCESS;
1615
1616 REQUIRE(DNS_ZONE_VALID(zone));
1617
1618 LOCK_ZONE(zone);
1619 result = dns_zone_setstring(zone, &zone->masterfile, file);
1620 if (result == ISC_R_SUCCESS) {
1621 zone->masterformat = format;
1622 if (format == dns_masterformat_text)
1623 zone->masterstyle = style;
1624 result = default_journal(zone);
1625 }
1626 UNLOCK_ZONE(zone);
1627
1628 return (result);
1629 }
1630
1631 const char *
1632 dns_zone_getfile(dns_zone_t *zone) {
1633 REQUIRE(DNS_ZONE_VALID(zone));
1634
1635 return (zone->masterfile);
1636 }
1637
1638 dns_ttl_t
1639 dns_zone_getmaxttl(dns_zone_t *zone) {
1640 REQUIRE(DNS_ZONE_VALID(zone));
1641
1642 return (zone->maxttl);
1643 }
1644
1645 void
1646 dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) {
1647 REQUIRE(DNS_ZONE_VALID(zone));
1648
1649 LOCK_ZONE(zone);
1650 if (maxttl != 0)
1651 zone->options |= DNS_ZONEOPT_CHECKTTL;
1652 else
1653 zone->options &= ~DNS_ZONEOPT_CHECKTTL;
1654 zone->maxttl = maxttl;
1655 UNLOCK_ZONE(zone);
1656
1657 return;
1658 }
1659
1660 static isc_result_t
1661 default_journal(dns_zone_t *zone) {
1662 isc_result_t result;
1663 char *journal;
1664
1665 REQUIRE(DNS_ZONE_VALID(zone));
1666 REQUIRE(LOCKED_ZONE(zone));
1667
1668 if (zone->masterfile != NULL) {
1669 /* Calculate string length including '\0'. */
1670 int len = strlen(zone->masterfile) + sizeof(".jnl");
1671 journal = isc_mem_allocate(zone->mctx, len);
1672 if (journal == NULL)
1673 return (ISC_R_NOMEMORY);
1674 strlcpy(journal, zone->masterfile, len);
1675 strlcat(journal, ".jnl", len);
1676 } else {
1677 journal = NULL;
1678 }
1679 result = dns_zone_setstring(zone, &zone->journal, journal);
1680 if (journal != NULL)
1681 isc_mem_free(zone->mctx, journal);
1682 return (result);
1683 }
1684
1685 isc_result_t
1686 dns_zone_setjournal(dns_zone_t *zone, const char *myjournal) {
1687 isc_result_t result = ISC_R_SUCCESS;
1688
1689 REQUIRE(DNS_ZONE_VALID(zone));
1690
1691 LOCK_ZONE(zone);
1692 result = dns_zone_setstring(zone, &zone->journal, myjournal);
1693 UNLOCK_ZONE(zone);
1694
1695 return (result);
1696 }
1697
1698 char *
1699 dns_zone_getjournal(dns_zone_t *zone) {
1700 REQUIRE(DNS_ZONE_VALID(zone));
1701
1702 return (zone->journal);
1703 }
1704
1705 /*
1706 * Return true iff the zone is "dynamic", in the sense that the zone's
1707 * master file (if any) is written by the server, rather than being
1708 * updated manually and read by the server.
1709 *
1710 * This is true for slave zones, mirror zones, stub zones, key zones,
1711 * and zones that allow dynamic updates either by having an update
1712 * policy ("ssutable") or an "allow-update" ACL with a value other than
1713 * exactly "{ none; }".
1714 */
1715 bool
1716 dns_zone_isdynamic(dns_zone_t *zone, bool ignore_freeze) {
1717 REQUIRE(DNS_ZONE_VALID(zone));
1718
1719 if (zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
1720 zone->type == dns_zone_stub || zone->type == dns_zone_key ||
1721 (zone->type == dns_zone_redirect && zone->masters != NULL))
1722 return (true);
1723
1724 /* Inline zones are always dynamic. */
1725 if (zone->type == dns_zone_master && zone->raw != NULL)
1726 return (true);
1727
1728 /* If !ignore_freeze, we need check whether updates are disabled. */
1729 if (zone->type == dns_zone_master &&
1730 (!zone->update_disabled || ignore_freeze) &&
1731 ((zone->ssutable != NULL) ||
1732 (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl))))
1733 return (true);
1734
1735 return (false);
1736
1737 }
1738
1739 /*
1740 * Set the response policy index and information for a zone.
1741 */
1742 isc_result_t
1743 dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs,
1744 dns_rpz_num_t rpz_num)
1745 {
1746 /*
1747 * Only RBTDB zones can be used for response policy zones,
1748 * because only they have the code to load the create the summary data.
1749 * Only zones that are loaded instead of mmap()ed create the
1750 * summary data and so can be policy zones.
1751 */
1752 if (strcmp(zone->db_argv[0], "rbt") != 0 &&
1753 strcmp(zone->db_argv[0], "rbt64") != 0)
1754 return (ISC_R_NOTIMPLEMENTED);
1755 if (zone->masterformat == dns_masterformat_map)
1756 return (ISC_R_NOTIMPLEMENTED);
1757
1758 /*
1759 * This must happen only once or be redundant.
1760 */
1761 LOCK_ZONE(zone);
1762 if (zone->rpzs != NULL) {
1763 REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num);
1764 } else {
1765 REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM);
1766 dns_rpz_attach_rpzs(rpzs, &zone->rpzs);
1767 zone->rpz_num = rpz_num;
1768 }
1769 rpzs->defined |= DNS_RPZ_ZBIT(rpz_num);
1770 UNLOCK_ZONE(zone);
1771
1772 return (ISC_R_SUCCESS);
1773 }
1774
1775 dns_rpz_num_t
1776 dns_zone_get_rpz_num(dns_zone_t *zone) {
1777 return (zone->rpz_num);
1778 }
1779
1780 /*
1781 * If a zone is a response policy zone, mark its new database.
1782 */
1783 void
1784 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) {
1785 isc_result_t result;
1786 if (zone->rpz_num == DNS_RPZ_INVALID_NUM)
1787 return;
1788 REQUIRE(zone->rpzs != NULL);
1789 zone->rpzs->zones[zone->rpz_num]->db_registered = true;
1790 result = dns_db_updatenotify_register(db,
1791 dns_rpz_dbupdate_callback,
1792 zone->rpzs->zones[zone->rpz_num]);
1793 REQUIRE(result == ISC_R_SUCCESS);
1794 }
1795
1796 void
1797 dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) {
1798 REQUIRE(DNS_ZONE_VALID(zone));
1799 REQUIRE(catzs != NULL);
1800
1801 LOCK_ZONE(zone);
1802 INSIST(zone->catzs == NULL || zone->catzs == catzs);
1803 dns_catz_catzs_set_view(catzs, zone->view);
1804 if (zone->catzs == NULL)
1805 dns_catz_catzs_attach(catzs, &zone->catzs);
1806 UNLOCK_ZONE(zone);
1807 }
1808
1809 /*
1810 * If a zone is a catalog zone, attach it to update notification in database.
1811 */
1812 void
1813 dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) {
1814 REQUIRE(DNS_ZONE_VALID(zone));
1815 REQUIRE(db != NULL);
1816
1817 if (zone->catzs != NULL) {
1818 dns_db_updatenotify_register(db, dns_catz_dbupdate_callback,
1819 zone->catzs);
1820 }
1821 }
1822
1823 /*
1824 * Set catalog zone ownership of the zone
1825 */
1826 void
1827 dns_zone_set_parentcatz(dns_zone_t *zone, dns_catz_zone_t *catz) {
1828 REQUIRE(DNS_ZONE_VALID(zone));
1829 REQUIRE(catz != NULL);
1830 LOCK_ZONE(zone);
1831 INSIST(zone->parentcatz == NULL || zone->parentcatz == catz);
1832 zone->parentcatz = catz;
1833 UNLOCK_ZONE(zone);
1834 }
1835
1836 dns_catz_zone_t *
1837 dns_zone_get_parentcatz(const dns_zone_t *zone) {
1838 REQUIRE(DNS_ZONE_VALID(zone));
1839 return (zone->parentcatz);
1840 }
1841
1842
1843 static bool
1844 zone_touched(dns_zone_t *zone) {
1845 isc_result_t result;
1846 isc_time_t modtime;
1847 dns_include_t *include;
1848
1849 REQUIRE(DNS_ZONE_VALID(zone));
1850
1851 result = isc_file_getmodtime(zone->masterfile, &modtime);
1852 if (result != ISC_R_SUCCESS ||
1853 isc_time_compare(&modtime, &zone->loadtime) > 0)
1854 return (true);
1855
1856 for (include = ISC_LIST_HEAD(zone->includes);
1857 include != NULL;
1858 include = ISC_LIST_NEXT(include, link))
1859 {
1860 result = isc_file_getmodtime(include->name, &modtime);
1861 if (result != ISC_R_SUCCESS ||
1862 isc_time_compare(&modtime, &include->filetime) > 0)
1863 return (true);
1864 }
1865
1866 return (false);
1867 }
1868
1869 /*
1870 * Note: when dealing with inline-signed zones, external callers will always
1871 * call zone_load() for the secure zone; zone_load() calls itself recursively
1872 * in order to load the raw zone.
1873 */
1874 static isc_result_t
1875 zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
1876 isc_result_t result;
1877 isc_time_t now;
1878 isc_time_t loadtime;
1879 dns_db_t *db = NULL;
1880 bool rbt, hasraw;
1881
1882 REQUIRE(DNS_ZONE_VALID(zone));
1883
1884 if (!locked)
1885 LOCK_ZONE(zone);
1886
1887 INSIST(zone != zone->raw);
1888 hasraw = inline_secure(zone);
1889 if (hasraw) {
1890 /*
1891 * We are trying to load an inline-signed zone. First call
1892 * self recursively to try loading the raw version of the zone.
1893 * Assuming the raw zone file is readable, there are two
1894 * possibilities:
1895 *
1896 * a) the raw zone was not yet loaded and thus it will be
1897 * loaded now, synchronously; if this succeeds, a
1898 * subsequent attempt to load the signed zone file will
1899 * take place and thus zone_postload() will be called
1900 * twice: first for the raw zone and then for the secure
1901 * zone; the latter call will take care of syncing the raw
1902 * version with the secure version,
1903 *
1904 * b) the raw zone was already loaded and we are trying to
1905 * reload it, which will happen asynchronously; this means
1906 * zone_postload() will only be called for the raw zone
1907 * because "result" returned by the zone_load() call below
1908 * will not be ISC_R_SUCCESS but rather DNS_R_CONTINUE;
1909 * zone_postload() called for the raw zone will take care
1910 * of syncing the raw version with the secure version.
1911 */
1912 result = zone_load(zone->raw, flags, false);
1913 if (result != ISC_R_SUCCESS) {
1914 if (!locked)
1915 UNLOCK_ZONE(zone);
1916 return(result);
1917 }
1918 LOCK_ZONE(zone->raw);
1919 }
1920
1921 TIME_NOW(&now);
1922
1923 INSIST(zone->type != dns_zone_none);
1924
1925 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1926 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1927 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1928 result = DNS_R_CONTINUE;
1929 goto cleanup;
1930 }
1931
1932 INSIST(zone->db_argc >= 1);
1933
1934 rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
1935 strcmp(zone->db_argv[0], "rbt64") == 0;
1936
1937 if (zone->db != NULL && zone->masterfile == NULL && rbt) {
1938 /*
1939 * The zone has no master file configured.
1940 */
1941 result = ISC_R_SUCCESS;
1942 goto cleanup;
1943 }
1944
1945 if (zone->db != NULL && dns_zone_isdynamic(zone, false)) {
1946 /*
1947 * This is a slave, stub, or dynamically updated
1948 * zone being reloaded. Do nothing - the database
1949 * we already have is guaranteed to be up-to-date.
1950 */
1951 if (zone->type == dns_zone_master && !hasraw)
1952 result = DNS_R_DYNAMIC;
1953 else
1954 result = ISC_R_SUCCESS;
1955 goto cleanup;
1956 }
1957
1958 /*
1959 * Store the current time before the zone is loaded, so that if the
1960 * file changes between the time of the load and the time that
1961 * zone->loadtime is set, then the file will still be reloaded
1962 * the next time dns_zone_load is called.
1963 */
1964 TIME_NOW(&loadtime);
1965
1966 /*
1967 * Don't do the load if the file that stores the zone is older
1968 * than the last time the zone was loaded. If the zone has not
1969 * been loaded yet, zone->loadtime will be the epoch.
1970 */
1971 if (zone->masterfile != NULL) {
1972 isc_time_t filetime;
1973
1974 /*
1975 * The file is already loaded. If we are just doing a
1976 * "rndc reconfig", we are done.
1977 */
1978 if (!isc_time_isepoch(&zone->loadtime) &&
1979 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
1980 result = ISC_R_SUCCESS;
1981 goto cleanup;
1982 }
1983
1984 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1985 !zone_touched(zone))
1986 {
1987 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
1988 ISC_LOG_DEBUG(1),
1989 "skipping load: master file "
1990 "older than last load");
1991 result = DNS_R_UPTODATE;
1992 goto cleanup;
1993 }
1994
1995 /*
1996 * If the file modification time is in the past
1997 * set loadtime to that value.
1998 */
1999 result = isc_file_getmodtime(zone->masterfile, &filetime);
2000 if (result == ISC_R_SUCCESS &&
2001 isc_time_compare(&loadtime, &filetime) > 0)
2002 loadtime = filetime;
2003 }
2004
2005 /*
2006 * Built in zones (with the exception of empty zones) don't need
2007 * to be reloaded.
2008 */
2009 if (zone->type == dns_zone_master &&
2010 strcmp(zone->db_argv[0], "_builtin") == 0 &&
2011 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
2012 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
2013 result = ISC_R_SUCCESS;
2014 goto cleanup;
2015 }
2016
2017 /*
2018 * Zones associated with a DLZ don't need to be loaded either,
2019 * but we need to associate the database with the zone object.
2020 */
2021 if (strcmp(zone->db_argv[0], "dlz") == 0) {
2022 dns_dlzdb_t *dlzdb;
2023 dns_dlzfindzone_t findzone;
2024
2025 for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched);
2026 dlzdb != NULL;
2027 dlzdb = ISC_LIST_NEXT(dlzdb, link))
2028 {
2029 INSIST(DNS_DLZ_VALID(dlzdb));
2030 if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0)
2031 break;
2032 }
2033
2034 if (dlzdb == NULL) {
2035 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
2036 ISC_LOG_ERROR,
2037 "DLZ %s does not exist or is set "
2038 "to 'search yes;'", zone->db_argv[1]);
2039 result = ISC_R_NOTFOUND;
2040 goto cleanup;
2041 }
2042
2043 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
2044 /* ask SDLZ driver if the zone is supported */
2045 findzone = dlzdb->implementation->methods->findzone;
2046 result = (*findzone)(dlzdb->implementation->driverarg,
2047 dlzdb->dbdata, dlzdb->mctx,
2048 zone->view->rdclass, &zone->origin,
2049 NULL, NULL, &db);
2050 if (result != ISC_R_NOTFOUND) {
2051 if (zone->db != NULL)
2052 zone_detachdb(zone);
2053 zone_attachdb(zone, db);
2054 dns_db_detach(&db);
2055 result = ISC_R_SUCCESS;
2056 }
2057 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2058
2059 if (result == ISC_R_SUCCESS) {
2060 if (dlzdb->configure_callback == NULL)
2061 goto cleanup;
2062
2063 result = (*dlzdb->configure_callback)(zone->view,
2064 dlzdb, zone);
2065 if (result != ISC_R_SUCCESS)
2066 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
2067 ISC_LOG_ERROR,
2068 "DLZ configuration callback: %s",
2069 isc_result_totext(result));
2070 }
2071 goto cleanup;
2072 }
2073
2074 if ((zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
2075 zone->type == dns_zone_stub ||
2076 (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
2077 rbt) {
2078 if (zone->masterfile == NULL ||
2079 !isc_file_exists(zone->masterfile)) {
2080 if (zone->masterfile != NULL) {
2081 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
2082 ISC_LOG_DEBUG(1),
2083 "no master file");
2084 }
2085 zone->refreshtime = now;
2086 if (zone->task != NULL)
2087 zone_settimer(zone, &now);
2088 result = ISC_R_SUCCESS;
2089 goto cleanup;
2090 }
2091 }
2092
2093 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
2094 ISC_LOG_DEBUG(1), "starting load");
2095
2096 result = dns_db_create(zone->mctx, zone->db_argv[0],
2097 &zone->origin, (zone->type == dns_zone_stub) ?
2098 dns_dbtype_stub : dns_dbtype_zone,
2099 zone->rdclass,
2100 zone->db_argc - 1, zone->db_argv + 1,
2101 &db);
2102
2103 if (result != ISC_R_SUCCESS) {
2104 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
2105 "loading zone: creating database: %s",
2106 isc_result_totext(result));
2107 goto cleanup;
2108 }
2109 dns_db_settask(db, zone->task);
2110
2111 if (zone->type == dns_zone_master || zone->type == dns_zone_slave ||
2112 zone->type == dns_zone_mirror)
2113 {
2114 result = dns_db_setgluecachestats(db, zone->gluecachestats);
2115 if (result == ISC_R_NOTIMPLEMENTED) {
2116 result = ISC_R_SUCCESS;
2117 }
2118 if (result != ISC_R_SUCCESS) {
2119 goto cleanup;
2120 }
2121 }
2122
2123 if (! dns_db_ispersistent(db)) {
2124 if (zone->masterfile != NULL) {
2125 result = zone_startload(db, zone, loadtime);
2126 } else {
2127 result = DNS_R_NOMASTERFILE;
2128 if (zone->type == dns_zone_master ||
2129 (zone->type == dns_zone_redirect &&
2130 zone->masters == NULL)) {
2131 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
2132 ISC_LOG_ERROR,
2133 "loading zone: "
2134 "no master file configured");
2135 goto cleanup;
2136 }
2137 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
2138 ISC_LOG_INFO, "loading zone: "
2139 "no master file configured: continuing");
2140 }
2141 }
2142
2143 if (result == DNS_R_CONTINUE) {
2144 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
2145 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
2146 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
2147 goto cleanup;
2148 }
2149
2150 result = zone_postload(zone, db, loadtime, result);
2151
2152 cleanup:
2153 if (hasraw)
2154 UNLOCK_ZONE(zone->raw);
2155 if (!locked)
2156 UNLOCK_ZONE(zone);
2157 if (db != NULL)
2158 dns_db_detach(&db);
2159 return (result);
2160 }
2161
2162 isc_result_t
2163 dns_zone_load(dns_zone_t *zone, bool newonly) {
2164 return (zone_load(zone, newonly ? DNS_ZONELOADFLAG_NOSTAT : 0, false));
2165 }
2166
2167 static void
2168 zone_asyncload(isc_task_t *task, isc_event_t *event) {
2169 dns_asyncload_t *asl = event->ev_arg;
2170 dns_zone_t *zone = asl->zone;
2171 isc_result_t result;
2172
2173 UNUSED(task);
2174
2175 REQUIRE(DNS_ZONE_VALID(zone));
2176
2177 isc_event_free(&event);
2178
2179 LOCK_ZONE(zone);
2180 result = zone_load(zone, asl->flags, true);
2181 if (result != DNS_R_CONTINUE) {
2182 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
2183 }
2184 UNLOCK_ZONE(zone);
2185
2186 /* Inform the zone table we've finished loading */
2187 if (asl->loaded != NULL)
2188 (asl->loaded)(asl->loaded_arg, zone, task);
2189
2190 isc_mem_put(zone->mctx, asl, sizeof (*asl));
2191 dns_zone_idetach(&zone);
2192 }
2193
2194 isc_result_t
2195 dns_zone_asyncload(dns_zone_t *zone, bool newonly,
2196 dns_zt_zoneloaded_t done, void *arg)
2197 {
2198 isc_event_t *e;
2199 dns_asyncload_t *asl = NULL;
2200 isc_result_t result = ISC_R_SUCCESS;
2201
2202 REQUIRE(DNS_ZONE_VALID(zone));
2203
2204 if (zone->zmgr == NULL)
2205 return (ISC_R_FAILURE);
2206
2207 /* If we already have a load pending, stop now */
2208 LOCK_ZONE(zone);
2209 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) {
2210 UNLOCK_ZONE(zone);
2211 return (ISC_R_ALREADYRUNNING);
2212 }
2213
2214 asl = isc_mem_get(zone->mctx, sizeof (*asl));
2215 if (asl == NULL)
2216 CHECK(ISC_R_NOMEMORY);
2217
2218 asl->zone = NULL;
2219 asl->flags = newonly ? DNS_ZONELOADFLAG_NOSTAT : 0;
2220 asl->loaded = done;
2221 asl->loaded_arg = arg;
2222
2223 e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr,
2224 DNS_EVENT_ZONELOAD,
2225 zone_asyncload, asl,
2226 sizeof(isc_event_t));
2227 if (e == NULL)
2228 CHECK(ISC_R_NOMEMORY);
2229
2230 zone_iattach(zone, &asl->zone);
2231 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING);
2232 isc_task_send(zone->loadtask, &e);
2233 UNLOCK_ZONE(zone);
2234
2235 return (ISC_R_SUCCESS);
2236
2237 failure:
2238 if (asl != NULL)
2239 isc_mem_put(zone->mctx, asl, sizeof (*asl));
2240 UNLOCK_ZONE(zone);
2241 return (result);
2242 }
2243
2244 bool
2245 dns__zone_loadpending(dns_zone_t *zone) {
2246 REQUIRE(DNS_ZONE_VALID(zone));
2247
2248 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING));
2249 }
2250
2251 isc_result_t
2252 dns_zone_loadandthaw(dns_zone_t *zone) {
2253 isc_result_t result;
2254
2255 if (inline_raw(zone))
2256 result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW,
2257 false);
2258 else
2259 result = zone_load(zone, DNS_ZONELOADFLAG_THAW, false);
2260
2261 switch (result) {
2262 case DNS_R_CONTINUE:
2263 /* Deferred thaw. */
2264 break;
2265 case DNS_R_UPTODATE:
2266 case ISC_R_SUCCESS:
2267 case DNS_R_SEENINCLUDE:
2268 zone->update_disabled = false;
2269 break;
2270 case DNS_R_NOMASTERFILE:
2271 zone->update_disabled = false;
2272 break;
2273 default:
2274 /* Error, remain in disabled state. */
2275 break;
2276 }
2277 return (result);
2278 }
2279
2280 static unsigned int
2281 get_master_options(dns_zone_t *zone) {
2282 unsigned int options;
2283
2284 options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN;
2285 if (zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
2286 (zone->type == dns_zone_redirect && zone->masters == NULL))
2287 {
2288 options |= DNS_MASTER_SLAVE;
2289 }
2290 if (zone->type == dns_zone_key) {
2291 options |= DNS_MASTER_KEY;
2292 }
2293 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) {
2294 options |= DNS_MASTER_CHECKNS;
2295 }
2296 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) {
2297 options |= DNS_MASTER_FATALNS;
2298 }
2299 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) {
2300 options |= DNS_MASTER_CHECKNAMES;
2301 }
2302 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
2303 options |= DNS_MASTER_CHECKNAMESFAIL;
2304 }
2305 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) {
2306 options |= DNS_MASTER_CHECKMX;
2307 }
2308 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) {
2309 options |= DNS_MASTER_CHECKMXFAIL;
2310 }
2311 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) {
2312 options |= DNS_MASTER_CHECKWILDCARD;
2313 }
2314 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKTTL)) {
2315 options |= DNS_MASTER_CHECKTTL;
2316 }
2317
2318 return (options);
2319 }
2320
2321 static void
2322 zone_registerinclude(const char *filename, void *arg) {
2323 isc_result_t result;
2324 dns_zone_t *zone = (dns_zone_t *) arg;
2325 dns_include_t *inc = NULL;
2326
2327 REQUIRE(DNS_ZONE_VALID(zone));
2328
2329 if (filename == NULL)
2330 return;
2331
2332 /*
2333 * Suppress duplicates.
2334 */
2335 for (inc = ISC_LIST_HEAD(zone->newincludes);
2336 inc != NULL;
2337 inc = ISC_LIST_NEXT(inc, link))
2338 if (strcmp(filename, inc->name) == 0)
2339 return;
2340
2341 inc = isc_mem_get(zone->mctx, sizeof(dns_include_t));
2342 if (inc == NULL)
2343 return;
2344 inc->name = isc_mem_strdup(zone->mctx, filename);
2345 if (inc->name == NULL) {
2346 isc_mem_put(zone->mctx, inc, sizeof(dns_include_t));
2347 return;
2348 }
2349 ISC_LINK_INIT(inc, link);
2350
2351 result = isc_file_getmodtime(filename, &inc->filetime);
2352 if (result != ISC_R_SUCCESS)
2353 isc_time_settoepoch(&inc->filetime);
2354
2355 ISC_LIST_APPEND(zone->newincludes, inc, link);
2356 }
2357
2358 static void
2359 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
2360 dns_load_t *load = event->ev_arg;
2361 isc_result_t result = ISC_R_SUCCESS;
2362 unsigned int options;
2363
2364 REQUIRE(DNS_LOAD_VALID(load));
2365
2366 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
2367 result = ISC_R_CANCELED;
2368 isc_event_free(&event);
2369 if (result == ISC_R_CANCELED)
2370 goto fail;
2371
2372 options = get_master_options(load->zone);
2373
2374 result = dns_master_loadfileinc(load->zone->masterfile,
2375 dns_db_origin(load->db),
2376 dns_db_origin(load->db),
2377 load->zone->rdclass, options, 0,
2378 &load->callbacks, task,
2379 zone_loaddone, load,
2380 &load->zone->lctx,
2381 zone_registerinclude,
2382 load->zone, load->zone->mctx,
2383 load->zone->masterformat,
2384 load->zone->maxttl);
2385 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
2386 result != DNS_R_SEENINCLUDE)
2387 goto fail;
2388 return;
2389
2390 fail:
2391 zone_loaddone(load, result);
2392 }
2393
2394 static void
2395 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
2396 isc_result_t result;
2397 unsigned int soacount;
2398
2399 LOCK(&raw->lock);
2400 if (raw->db != NULL) {
2401 result = zone_get_from_db(raw, raw->db, NULL, &soacount,
2402 &rawdata->sourceserial,
2403 NULL, NULL, NULL, NULL,
2404 NULL);
2405 if (result == ISC_R_SUCCESS && soacount > 0U)
2406 rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
2407 }
2408 UNLOCK(&raw->lock);
2409 }
2410
2411 static void
2412 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
2413 const char me[] = "zone_gotwritehandle";
2414 dns_zone_t *zone = event->ev_arg;
2415 isc_result_t result = ISC_R_SUCCESS;
2416 dns_dbversion_t *version = NULL;
2417 dns_masterrawheader_t rawdata;
2418
2419 REQUIRE(DNS_ZONE_VALID(zone));
2420 INSIST(task == zone->task);
2421 ENTER;
2422
2423 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
2424 result = ISC_R_CANCELED;
2425 isc_event_free(&event);
2426 if (result == ISC_R_CANCELED)
2427 goto fail;
2428
2429 LOCK_ZONE(zone);
2430 INSIST(zone != zone->raw);
2431 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2432 if (zone->db != NULL) {
2433 const dns_master_style_t *output_style;
2434
2435 dns_db_currentversion(zone->db, &version);
2436 dns_master_initrawheader(&rawdata);
2437 if (inline_secure(zone))
2438 get_raw_serial(zone->raw, &rawdata);
2439 if (zone->type == dns_zone_key)
2440 output_style = &dns_master_style_keyzone;
2441 else if (zone->masterstyle != NULL)
2442 output_style = zone->masterstyle;
2443 else
2444 output_style = &dns_master_style_default;
2445 result = dns_master_dumpinc(zone->mctx, zone->db, version,
2446 output_style, zone->masterfile,
2447 zone->task, dump_done, zone,
2448 &zone->dctx, zone->masterformat,
2449 &rawdata);
2450 dns_db_closeversion(zone->db, &version, false);
2451 } else
2452 result = ISC_R_CANCELED;
2453 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2454 UNLOCK_ZONE(zone);
2455 if (result != DNS_R_CONTINUE)
2456 goto fail;
2457 return;
2458
2459 fail:
2460 dump_done(zone, result);
2461 }
2462
2463 /*
2464 * Save the raw serial number for inline-signing zones.
2465 * (XXX: Other information from the header will be used
2466 * for other purposes in the future, but for now this is
2467 * all we're interested in.)
2468 */
2469 static void
2470 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
2471 if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0)
2472 return;
2473
2474 zone->sourceserial = header->sourceserial;
2475 zone->sourceserialset = true;
2476 }
2477
2478 void
2479 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
2480 if (zone == NULL)
2481 return;
2482
2483 LOCK_ZONE(zone);
2484 zone_setrawdata(zone, header);
2485 UNLOCK_ZONE(zone);
2486 }
2487
2488 static isc_result_t
2489 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
2490 dns_load_t *load;
2491 isc_result_t result;
2492 isc_result_t tresult;
2493 unsigned int options;
2494
2495 dns_zone_rpz_enable_db(zone, db);
2496 dns_zone_catz_enable_db(zone, db);
2497 options = get_master_options(zone);
2498 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
2499 options |= DNS_MASTER_MANYERRORS;
2500
2501 if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) {
2502 load = isc_mem_get(zone->mctx, sizeof(*load));
2503 if (load == NULL)
2504 return (ISC_R_NOMEMORY);
2505
2506 load->mctx = NULL;
2507 load->zone = NULL;
2508 load->db = NULL;
2509 load->loadtime = loadtime;
2510 load->magic = LOAD_MAGIC;
2511
2512 isc_mem_attach(zone->mctx, &load->mctx);
2513 zone_iattach(zone, &load->zone);
2514 dns_db_attach(db, &load->db);
2515 dns_rdatacallbacks_init(&load->callbacks);
2516 load->callbacks.rawdata = zone_setrawdata;
2517 zone_iattach(zone, &load->callbacks.zone);
2518 result = dns_db_beginload(db, &load->callbacks);
2519 if (result != ISC_R_SUCCESS)
2520 goto cleanup;
2521 result = zonemgr_getio(zone->zmgr, true, zone->loadtask,
2522 zone_gotreadhandle, load,
2523 &zone->readio);
2524 if (result != ISC_R_SUCCESS) {
2525 /*
2526 * We can't report multiple errors so ignore
2527 * the result of dns_db_endload().
2528 */
2529 (void)dns_db_endload(load->db, &load->callbacks);
2530 goto cleanup;
2531 } else
2532 result = DNS_R_CONTINUE;
2533 } else {
2534 dns_rdatacallbacks_t callbacks;
2535
2536 dns_rdatacallbacks_init(&callbacks);
2537 callbacks.rawdata = zone_setrawdata;
2538 zone_iattach(zone, &callbacks.zone);
2539 result = dns_db_beginload(db, &callbacks);
2540 if (result != ISC_R_SUCCESS) {
2541 zone_idetach(&callbacks.zone);
2542 return (result);
2543 }
2544 result = dns_master_loadfile(zone->masterfile,
2545 &zone->origin, &zone->origin,
2546 zone->rdclass, options, 0,
2547 &callbacks,
2548 zone_registerinclude,
2549 zone, zone->mctx,
2550 zone->masterformat,
2551 zone->maxttl);
2552 tresult = dns_db_endload(db, &callbacks);
2553 if (result == ISC_R_SUCCESS)
2554 result = tresult;
2555 zone_idetach(&callbacks.zone);
2556 }
2557
2558 return (result);
2559
2560 cleanup:
2561 load->magic = 0;
2562 dns_db_detach(&load->db);
2563 zone_idetach(&load->zone);
2564 zone_idetach(&load->callbacks.zone);
2565 isc_mem_detach(&load->mctx);
2566 isc_mem_put(zone->mctx, load, sizeof(*load));
2567 return (result);
2568 }
2569
2570 static bool
2571 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2572 dns_name_t *owner)
2573 {
2574 isc_result_t result;
2575 char ownerbuf[DNS_NAME_FORMATSIZE];
2576 char namebuf[DNS_NAME_FORMATSIZE];
2577 char altbuf[DNS_NAME_FORMATSIZE];
2578 dns_fixedname_t fixed;
2579 dns_name_t *foundname;
2580 int level;
2581
2582 /*
2583 * "." means the services does not exist.
2584 */
2585 if (dns_name_equal(name, dns_rootname))
2586 return (true);
2587
2588 /*
2589 * Outside of zone.
2590 */
2591 if (!dns_name_issubdomain(name, &zone->origin)) {
2592 if (zone->checkmx != NULL)
2593 return ((zone->checkmx)(zone, name, owner));
2594 return (true);
2595 }
2596
2597 if (zone->type == dns_zone_master)
2598 level = ISC_LOG_ERROR;
2599 else
2600 level = ISC_LOG_WARNING;
2601
2602 foundname = dns_fixedname_initname(&fixed);
2603
2604 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2605 0, 0, NULL, foundname, NULL, NULL);
2606 if (result == ISC_R_SUCCESS)
2607 return (true);
2608
2609 if (result == DNS_R_NXRRSET) {
2610 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2611 0, 0, NULL, foundname, NULL, NULL);
2612 if (result == ISC_R_SUCCESS)
2613 return (true);
2614 }
2615
2616 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2617 dns_name_format(name, namebuf, sizeof namebuf);
2618 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2619 result == DNS_R_EMPTYNAME) {
2620 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
2621 level = ISC_LOG_WARNING;
2622 dns_zone_log(zone, level,
2623 "%s/MX '%s' has no address records (A or AAAA)",
2624 ownerbuf, namebuf);
2625 return ((level == ISC_LOG_WARNING) ? true : false);
2626 }
2627
2628 if (result == DNS_R_CNAME) {
2629 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
2630 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2631 level = ISC_LOG_WARNING;
2632 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2633 dns_zone_log(zone, level,
2634 "%s/MX '%s' is a CNAME (illegal)",
2635 ownerbuf, namebuf);
2636 return ((level == ISC_LOG_WARNING) ? true : false);
2637 }
2638
2639 if (result == DNS_R_DNAME) {
2640 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
2641 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2642 level = ISC_LOG_WARNING;
2643 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
2644 dns_name_format(foundname, altbuf, sizeof altbuf);
2645 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
2646 " '%s' (illegal)", ownerbuf, namebuf,
2647 altbuf);
2648 }
2649 return ((level == ISC_LOG_WARNING) ? true : false);
2650 }
2651
2652 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
2653 return ((zone->checkmx)(zone, name, owner));
2654
2655 return (true);
2656 }
2657
2658 static bool
2659 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2660 dns_name_t *owner)
2661 {
2662 isc_result_t result;
2663 char ownerbuf[DNS_NAME_FORMATSIZE];
2664 char namebuf[DNS_NAME_FORMATSIZE];
2665 char altbuf[DNS_NAME_FORMATSIZE];
2666 dns_fixedname_t fixed;
2667 dns_name_t *foundname;
2668 int level;
2669
2670 /*
2671 * "." means the services does not exist.
2672 */
2673 if (dns_name_equal(name, dns_rootname))
2674 return (true);
2675
2676 /*
2677 * Outside of zone.
2678 */
2679 if (!dns_name_issubdomain(name, &zone->origin)) {
2680 if (zone->checksrv != NULL)
2681 return ((zone->checksrv)(zone, name, owner));
2682 return (true);
2683 }
2684
2685 if (zone->type == dns_zone_master)
2686 level = ISC_LOG_ERROR;
2687 else
2688 level = ISC_LOG_WARNING;
2689
2690 foundname = dns_fixedname_initname(&fixed);
2691
2692 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2693 0, 0, NULL, foundname, NULL, NULL);
2694 if (result == ISC_R_SUCCESS)
2695 return (true);
2696
2697 if (result == DNS_R_NXRRSET) {
2698 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2699 0, 0, NULL, foundname, NULL, NULL);
2700 if (result == ISC_R_SUCCESS)
2701 return (true);
2702 }
2703
2704 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2705 dns_name_format(name, namebuf, sizeof namebuf);
2706 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2707 result == DNS_R_EMPTYNAME) {
2708 dns_zone_log(zone, level,
2709 "%s/SRV '%s' has no address records (A or AAAA)",
2710 ownerbuf, namebuf);
2711 /* XXX950 make fatal for 9.5.0. */
2712 return (true);
2713 }
2714
2715 if (result == DNS_R_CNAME) {
2716 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
2717 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2718 level = ISC_LOG_WARNING;
2719 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2720 dns_zone_log(zone, level,
2721 "%s/SRV '%s' is a CNAME (illegal)",
2722 ownerbuf, namebuf);
2723 return ((level == ISC_LOG_WARNING) ? true : false);
2724 }
2725
2726 if (result == DNS_R_DNAME) {
2727 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
2728 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2729 level = ISC_LOG_WARNING;
2730 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
2731 dns_name_format(foundname, altbuf, sizeof altbuf);
2732 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
2733 "DNAME '%s' (illegal)", ownerbuf, namebuf,
2734 altbuf);
2735 }
2736 return ((level == ISC_LOG_WARNING) ? true : false);
2737 }
2738
2739 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
2740 return ((zone->checksrv)(zone, name, owner));
2741
2742 return (true);
2743 }
2744
2745 static bool
2746 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2747 dns_name_t *owner)
2748 {
2749 bool answer = true;
2750 isc_result_t result, tresult;
2751 char ownerbuf[DNS_NAME_FORMATSIZE];
2752 char namebuf[DNS_NAME_FORMATSIZE];
2753 char altbuf[DNS_NAME_FORMATSIZE];
2754 dns_fixedname_t fixed;
2755 dns_name_t *foundname;
2756 dns_rdataset_t a;
2757 dns_rdataset_t aaaa;
2758 int level;
2759
2760 /*
2761 * Outside of zone.
2762 */
2763 if (!dns_name_issubdomain(name, &zone->origin)) {
2764 if (zone->checkns != NULL)
2765 return ((zone->checkns)(zone, name, owner, NULL, NULL));
2766 return (true);
2767 }
2768
2769 if (zone->type == dns_zone_master)
2770 level = ISC_LOG_ERROR;
2771 else
2772 level = ISC_LOG_WARNING;
2773
2774 foundname = dns_fixedname_initname(&fixed);
2775 dns_rdataset_init(&a);
2776 dns_rdataset_init(&aaaa);
2777
2778 /*
2779 * Perform a regular lookup to catch DNAME records then look
2780 * for glue.
2781 */
2782 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2783 0, 0, NULL, foundname, &a, NULL);
2784 switch (result) {
2785 case ISC_R_SUCCESS:
2786 case DNS_R_DNAME:
2787 case DNS_R_CNAME:
2788 break;
2789 default:
2790 if (dns_rdataset_isassociated(&a))
2791 dns_rdataset_disassociate(&a);
2792 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2793 DNS_DBFIND_GLUEOK, 0, NULL,
2794 foundname, &a, NULL);
2795 }
2796 if (result == ISC_R_SUCCESS) {
2797 dns_rdataset_disassociate(&a);
2798 return (true);
2799 } else if (result == DNS_R_DELEGATION)
2800 dns_rdataset_disassociate(&a);
2801
2802 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
2803 result == DNS_R_GLUE) {
2804 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2805 DNS_DBFIND_GLUEOK, 0, NULL,
2806 foundname, &aaaa, NULL);
2807 if (tresult == ISC_R_SUCCESS) {
2808 if (dns_rdataset_isassociated(&a))
2809 dns_rdataset_disassociate(&a);
2810 dns_rdataset_disassociate(&aaaa);
2811 return (true);
2812 }
2813 if (tresult == DNS_R_DELEGATION || tresult == DNS_R_DNAME)
2814 dns_rdataset_disassociate(&aaaa);
2815 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
2816 /*
2817 * Check glue against child zone.
2818 */
2819 if (zone->checkns != NULL)
2820 answer = (zone->checkns)(zone, name, owner,
2821 &a, &aaaa);
2822 if (dns_rdataset_isassociated(&a))
2823 dns_rdataset_disassociate(&a);
2824 if (dns_rdataset_isassociated(&aaaa))
2825 dns_rdataset_disassociate(&aaaa);
2826 return (answer);
2827 }
2828 }
2829
2830 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2831 dns_name_format(name, namebuf, sizeof namebuf);
2832 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2833 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
2834 const char *what;
2835 bool required = false;
2836 if (dns_name_issubdomain(name, owner)) {
2837 what = "REQUIRED GLUE ";
2838 required = true;
2839 } else if (result == DNS_R_DELEGATION)
2840 what = "SIBLING GLUE ";
2841 else
2842 what = "";
2843
2844 if (result != DNS_R_DELEGATION || required ||
2845 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
2846 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
2847 "address records (A or AAAA)",
2848 ownerbuf, namebuf, what);
2849 /*
2850 * Log missing address record.
2851 */
2852 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
2853 (void)(zone->checkns)(zone, name, owner,
2854 &a, &aaaa);
2855 /* XXX950 make fatal for 9.5.0. */
2856 /* answer = false; */
2857 }
2858 } else if (result == DNS_R_CNAME) {
2859 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
2860 ownerbuf, namebuf);
2861 /* XXX950 make fatal for 9.5.0. */
2862 /* answer = false; */
2863 } else if (result == DNS_R_DNAME) {
2864 dns_name_format(foundname, altbuf, sizeof altbuf);
2865 dns_zone_log(zone, level,
2866 "%s/NS '%s' is below a DNAME '%s' (illegal)",
2867 ownerbuf, namebuf, altbuf);
2868 /* XXX950 make fatal for 9.5.0. */
2869 /* answer = false; */
2870 }
2871
2872 if (dns_rdataset_isassociated(&a))
2873 dns_rdataset_disassociate(&a);
2874 if (dns_rdataset_isassociated(&aaaa))
2875 dns_rdataset_disassociate(&aaaa);
2876 return (answer);
2877 }
2878
2879 static bool
2880 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
2881 dns_rdataset_t *rdataset)
2882 {
2883 dns_rdataset_t tmprdataset;
2884 isc_result_t result;
2885 bool answer = true;
2886 bool format = true;
2887 int level = ISC_LOG_WARNING;
2888 char ownerbuf[DNS_NAME_FORMATSIZE];
2889 char typebuf[DNS_RDATATYPE_FORMATSIZE];
2890 unsigned int count1 = 0;
2891
2892 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL))
2893 level = ISC_LOG_ERROR;
2894
2895 dns_rdataset_init(&tmprdataset);
2896 for (result = dns_rdataset_first(rdataset);
2897 result == ISC_R_SUCCESS;
2898 result = dns_rdataset_next(rdataset)) {
2899 dns_rdata_t rdata1 = DNS_RDATA_INIT;
2900 unsigned int count2 = 0;
2901
2902 count1++;
2903 dns_rdataset_current(rdataset, &rdata1);
2904 dns_rdataset_clone(rdataset, &tmprdataset);
2905 for (result = dns_rdataset_first(&tmprdataset);
2906 result == ISC_R_SUCCESS;
2907 result = dns_rdataset_next(&tmprdataset)) {
2908 dns_rdata_t rdata2 = DNS_RDATA_INIT;
2909 count2++;
2910 if (count1 >= count2)
2911 continue;
2912 dns_rdataset_current(&tmprdataset, &rdata2);
2913 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
2914 if (format) {
2915 dns_name_format(owner, ownerbuf,
2916 sizeof ownerbuf);
2917 dns_rdatatype_format(rdata1.type,
2918 typebuf,
2919 sizeof(typebuf));
2920 format = false;
2921 }
2922 dns_zone_log(zone, level, "%s/%s has "
2923 "semantically identical records",
2924 ownerbuf, typebuf);
2925 if (level == ISC_LOG_ERROR)
2926 answer = false;
2927 break;
2928 }
2929 }
2930 dns_rdataset_disassociate(&tmprdataset);
2931 if (!format)
2932 break;
2933 }
2934 return (answer);
2935 }
2936
2937 static bool
2938 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
2939 dns_dbiterator_t *dbiterator = NULL;
2940 dns_dbnode_t *node = NULL;
2941 dns_fixedname_t fixed;
2942 dns_name_t *name;
2943 dns_rdataset_t rdataset;
2944 dns_rdatasetiter_t *rdsit = NULL;
2945 bool ok = true;
2946 isc_result_t result;
2947
2948 name = dns_fixedname_initname(&fixed);
2949 dns_rdataset_init(&rdataset);
2950
2951 result = dns_db_createiterator(db, 0, &dbiterator);
2952 if (result != ISC_R_SUCCESS)
2953 return (true);
2954
2955 for (result = dns_dbiterator_first(dbiterator);
2956 result == ISC_R_SUCCESS;
2957 result = dns_dbiterator_next(dbiterator)) {
2958 result = dns_dbiterator_current(dbiterator, &node, name);
2959 if (result != ISC_R_SUCCESS)
2960 continue;
2961
2962 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
2963 if (result != ISC_R_SUCCESS)
2964 continue;
2965
2966 for (result = dns_rdatasetiter_first(rdsit);
2967 result == ISC_R_SUCCESS;
2968 result = dns_rdatasetiter_next(rdsit)) {
2969 dns_rdatasetiter_current(rdsit, &rdataset);
2970 if (!zone_rrset_check_dup(zone, name, &rdataset))
2971 ok = false;
2972 dns_rdataset_disassociate(&rdataset);
2973 }
2974 dns_rdatasetiter_destroy(&rdsit);
2975 dns_db_detachnode(db, &node);
2976 }
2977
2978 if (node != NULL)
2979 dns_db_detachnode(db, &node);
2980 dns_dbiterator_destroy(&dbiterator);
2981
2982 return (ok);
2983 }
2984
2985 static bool
2986 isspf(const dns_rdata_t *rdata) {
2987 char buf[1024];
2988 const unsigned char *data = rdata->data;
2989 unsigned int rdl = rdata->length, i = 0, tl, len;
2990
2991 while (rdl > 0U) {
2992 len = tl = *data;
2993 ++data;
2994 --rdl;
2995 INSIST(tl <= rdl);
2996 if (len > sizeof(buf) - i - 1)
2997 len = sizeof(buf) - i - 1;
2998 memmove(buf + i, data, len);
2999 i += len;
3000 data += tl;
3001 rdl -= tl;
3002 }
3003
3004 if (i < 6U)
3005 return(false);
3006
3007 buf[i] = 0;
3008 if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' '))
3009 return (true);
3010 return (false);
3011 }
3012
3013 static bool
3014 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
3015 dns_dbiterator_t *dbiterator = NULL;
3016 dns_dbnode_t *node = NULL;
3017 dns_rdataset_t rdataset;
3018 dns_fixedname_t fixed;
3019 dns_fixedname_t fixedbottom;
3020 dns_rdata_mx_t mx;
3021 dns_rdata_ns_t ns;
3022 dns_rdata_in_srv_t srv;
3023 dns_rdata_t rdata;
3024 dns_name_t *name;
3025 dns_name_t *bottom;
3026 isc_result_t result;
3027 bool ok = true, have_spf, have_txt;
3028
3029 name = dns_fixedname_initname(&fixed);
3030 bottom = dns_fixedname_initname(&fixedbottom);
3031 dns_rdataset_init(&rdataset);
3032 dns_rdata_init(&rdata);
3033
3034 result = dns_db_createiterator(db, 0, &dbiterator);
3035 if (result != ISC_R_SUCCESS)
3036 return (true);
3037
3038 result = dns_dbiterator_first(dbiterator);
3039 while (result == ISC_R_SUCCESS) {
3040 result = dns_dbiterator_current(dbiterator, &node, name);
3041 if (result != ISC_R_SUCCESS)
3042 goto cleanup;
3043
3044 /*
3045 * Is this name visible in the zone?
3046 */
3047 if (!dns_name_issubdomain(name, &zone->origin) ||
3048 (dns_name_countlabels(bottom) > 0 &&
3049 dns_name_issubdomain(name, bottom)))
3050 goto next;
3051
3052 /*
3053 * Don't check the NS records at the origin.
3054 */
3055 if (dns_name_equal(name, &zone->origin))
3056 goto checkfordname;
3057
3058 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
3059 0, 0, &rdataset, NULL);
3060 if (result != ISC_R_SUCCESS)
3061 goto checkfordname;
3062 /*
3063 * Remember bottom of zone due to NS.
3064 */
3065 dns_name_copy(name, bottom, NULL);
3066
3067 result = dns_rdataset_first(&rdataset);
3068 while (result == ISC_R_SUCCESS) {
3069 dns_rdataset_current(&rdataset, &rdata);
3070 result = dns_rdata_tostruct(&rdata, &ns, NULL);
3071 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3072 if (!zone_check_glue(zone, db, &ns.name, name))
3073 ok = false;
3074 dns_rdata_reset(&rdata);
3075 result = dns_rdataset_next(&rdataset);
3076 }
3077 dns_rdataset_disassociate(&rdataset);
3078 goto next;
3079
3080 checkfordname:
3081 result = dns_db_findrdataset(db, node, NULL,
3082 dns_rdatatype_dname, 0, 0,
3083 &rdataset, NULL);
3084 if (result == ISC_R_SUCCESS) {
3085 /*
3086 * Remember bottom of zone due to DNAME.
3087 */
3088 dns_name_copy(name, bottom, NULL);
3089 dns_rdataset_disassociate(&rdataset);
3090 }
3091
3092 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
3093 0, 0, &rdataset, NULL);
3094 if (result != ISC_R_SUCCESS)
3095 goto checksrv;
3096 result = dns_rdataset_first(&rdataset);
3097 while (result == ISC_R_SUCCESS) {
3098 dns_rdataset_current(&rdataset, &rdata);
3099 result = dns_rdata_tostruct(&rdata, &mx, NULL);
3100 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3101 if (!zone_check_mx(zone, db, &mx.mx, name))
3102 ok = false;
3103 dns_rdata_reset(&rdata);
3104 result = dns_rdataset_next(&rdataset);
3105 }
3106 dns_rdataset_disassociate(&rdataset);
3107
3108 checksrv:
3109 if (zone->rdclass != dns_rdataclass_in)
3110 goto next;
3111 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
3112 0, 0, &rdataset, NULL);
3113 if (result != ISC_R_SUCCESS)
3114 goto checkspf;
3115 result = dns_rdataset_first(&rdataset);
3116 while (result == ISC_R_SUCCESS) {
3117 dns_rdataset_current(&rdataset, &rdata);
3118 result = dns_rdata_tostruct(&rdata, &srv, NULL);
3119 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3120 if (!zone_check_srv(zone, db, &srv.target, name))
3121 ok = false;
3122 dns_rdata_reset(&rdata);
3123 result = dns_rdataset_next(&rdataset);
3124 }
3125 dns_rdataset_disassociate(&rdataset);
3126
3127 checkspf:
3128 /*
3129 * Check if there is a type SPF record without an
3130 * SPF-formatted type TXT record also being present.
3131 */
3132 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF))
3133 goto next;
3134 if (zone->rdclass != dns_rdataclass_in)
3135 goto next;
3136 have_spf = have_txt = false;
3137 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
3138 0, 0, &rdataset, NULL);
3139 if (result == ISC_R_SUCCESS) {
3140 dns_rdataset_disassociate(&rdataset);
3141 have_spf = true;
3142 }
3143 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
3144 0, 0, &rdataset, NULL);
3145 if (result != ISC_R_SUCCESS)
3146 goto notxt;
3147 result = dns_rdataset_first(&rdataset);
3148 while (result == ISC_R_SUCCESS) {
3149 dns_rdataset_current(&rdataset, &rdata);
3150 have_txt = isspf(&rdata);
3151 dns_rdata_reset(&rdata);
3152 if (have_txt)
3153 break;
3154 result = dns_rdataset_next(&rdataset);
3155 }
3156 dns_rdataset_disassociate(&rdataset);
3157
3158 notxt:
3159 if (have_spf && !have_txt) {
3160 char namebuf[DNS_NAME_FORMATSIZE];
3161
3162 dns_name_format(name, namebuf, sizeof(namebuf));
3163 dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found type "
3164 "SPF record but no SPF TXT record found, "
3165 "add matching type TXT record", namebuf);
3166 }
3167
3168 next:
3169 dns_db_detachnode(db, &node);
3170 result = dns_dbiterator_next(dbiterator);
3171 }
3172
3173 cleanup:
3174 if (node != NULL)
3175 dns_db_detachnode(db, &node);
3176 dns_dbiterator_destroy(&dbiterator);
3177
3178 return (ok);
3179 }
3180
3181 /*
3182 * OpenSSL verification of RSA keys with exponent 3 is known to be
3183 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
3184 * if they are in use.
3185 */
3186 static void
3187 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
3188 dns_dbnode_t *node = NULL;
3189 dns_dbversion_t *version = NULL;
3190 dns_rdata_dnskey_t dnskey;
3191 dns_rdata_t rdata = DNS_RDATA_INIT;
3192 dns_rdataset_t rdataset;
3193 isc_result_t result;
3194 bool logit, foundrsa = false, foundmd5 = false;
3195 const char *algorithm;
3196
3197 result = dns_db_findnode(db, &zone->origin, false, &node);
3198 if (result != ISC_R_SUCCESS)
3199 goto cleanup;
3200
3201 dns_db_currentversion(db, &version);
3202 dns_rdataset_init(&rdataset);
3203 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
3204 dns_rdatatype_none, 0, &rdataset, NULL);
3205 if (result != ISC_R_SUCCESS)
3206 goto cleanup;
3207
3208 for (result = dns_rdataset_first(&rdataset);
3209 result == ISC_R_SUCCESS;
3210 result = dns_rdataset_next(&rdataset))
3211 {
3212 dns_rdataset_current(&rdataset, &rdata);
3213 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
3214 INSIST(result == ISC_R_SUCCESS);
3215
3216 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
3217 dnskey.algorithm == DST_ALG_RSAMD5) &&
3218 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
3219 dnskey.data[1] == 3)
3220 {
3221 if (dnskey.algorithm == DST_ALG_RSASHA1) {
3222 logit = !foundrsa;
3223 foundrsa = true;
3224 algorithm = "RSASHA1";
3225 } else {
3226 logit = !foundmd5;
3227 foundmd5 = true;
3228 algorithm = "RSAMD5";
3229 }
3230 if (logit)
3231 dns_zone_log(zone, ISC_LOG_WARNING,
3232 "weak %s (%u) key found "
3233 "(exponent=3)", algorithm,
3234 dnskey.algorithm);
3235 if (foundrsa && foundmd5)
3236 break;
3237 }
3238 dns_rdata_reset(&rdata);
3239 }
3240 dns_rdataset_disassociate(&rdataset);
3241
3242 cleanup:
3243 if (node != NULL)
3244 dns_db_detachnode(db, &node);
3245 if (version != NULL)
3246 dns_db_closeversion(db, &version, false);
3247 }
3248
3249 static void
3250 resume_signingwithkey(dns_zone_t *zone) {
3251 dns_dbnode_t *node = NULL;
3252 dns_dbversion_t *version = NULL;
3253 dns_rdata_t rdata = DNS_RDATA_INIT;
3254 dns_rdataset_t rdataset;
3255 isc_result_t result;
3256 dns_db_t *db = NULL;
3257
3258 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3259 if (zone->db != NULL)
3260 dns_db_attach(zone->db, &db);
3261 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3262 if (db == NULL)
3263 goto cleanup;
3264
3265 result = dns_db_findnode(db, &zone->origin, false, &node);
3266 if (result != ISC_R_SUCCESS)
3267 goto cleanup;
3268
3269 dns_db_currentversion(db, &version);
3270 dns_rdataset_init(&rdataset);
3271 result = dns_db_findrdataset(db, node, version,
3272 zone->privatetype,
3273 dns_rdatatype_none, 0,
3274 &rdataset, NULL);
3275 if (result != ISC_R_SUCCESS) {
3276 INSIST(!dns_rdataset_isassociated(&rdataset));
3277 goto cleanup;
3278 }
3279
3280 for (result = dns_rdataset_first(&rdataset);
3281 result == ISC_R_SUCCESS;
3282 result = dns_rdataset_next(&rdataset))
3283 {
3284 dns_rdataset_current(&rdataset, &rdata);
3285 if (rdata.length != 5 ||
3286 rdata.data[0] == 0 || rdata.data[4] != 0) {
3287 dns_rdata_reset(&rdata);
3288 continue;
3289 }
3290
3291 result = zone_signwithkey(zone, rdata.data[0],
3292 (rdata.data[1] << 8) | rdata.data[2],
3293 rdata.data[3]);
3294 if (result != ISC_R_SUCCESS) {
3295 dns_zone_log(zone, ISC_LOG_ERROR,
3296 "zone_signwithkey failed: %s",
3297 dns_result_totext(result));
3298 }
3299 dns_rdata_reset(&rdata);
3300 }
3301 dns_rdataset_disassociate(&rdataset);
3302
3303 cleanup:
3304 if (db != NULL) {
3305 if (node != NULL)
3306 dns_db_detachnode(db, &node);
3307 if (version != NULL)
3308 dns_db_closeversion(db, &version, false);
3309 dns_db_detach(&db);
3310 }
3311 }
3312
3313 /*
3314 * Initiate adding/removing NSEC3 records belonging to the chain defined by the
3315 * supplied NSEC3PARAM RDATA.
3316 *
3317 * Zone must be locked by caller.
3318 */
3319 static isc_result_t
3320 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
3321 dns_nsec3chain_t *nsec3chain, *current;
3322 dns_dbversion_t *version = NULL;
3323 bool nseconly = false, nsec3ok = false;
3324 isc_result_t result;
3325 isc_time_t now;
3326 unsigned int options = 0;
3327 char saltbuf[255*2+1];
3328 char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
3329 dns_db_t *db = NULL;
3330
3331 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3332 if (zone->db != NULL)
3333 dns_db_attach(zone->db, &db);
3334 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3335
3336 if (db == NULL) {
3337 result = ISC_R_SUCCESS;
3338 goto cleanup;
3339 }
3340
3341 /*
3342 * If this zone is not NSEC3-capable, attempting to remove any NSEC3
3343 * chain from it is pointless as it would not be possible for the
3344 * latter to exist in the first place.
3345 */
3346 dns_db_currentversion(db, &version);
3347 result = dns_nsec_nseconly(db, version, &nseconly);
3348 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
3349 dns_db_closeversion(db, &version, false);
3350 if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) {
3351 result = ISC_R_SUCCESS;
3352 goto cleanup;
3353 }
3354
3355 /*
3356 * Allocate and initialize structure preserving state of
3357 * adding/removing records belonging to this NSEC3 chain between
3358 * separate zone_nsec3chain() calls.
3359 */
3360 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
3361 if (nsec3chain == NULL) {
3362 result = ISC_R_NOMEMORY;
3363 goto cleanup;
3364 }
3365
3366 nsec3chain->magic = 0;
3367 nsec3chain->done = false;
3368 nsec3chain->db = NULL;
3369 nsec3chain->dbiterator = NULL;
3370 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
3371 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
3372 nsec3chain->nsec3param.hash = nsec3param->hash;
3373 nsec3chain->nsec3param.iterations = nsec3param->iterations;
3374 nsec3chain->nsec3param.flags = nsec3param->flags;
3375 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
3376 memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
3377 nsec3chain->nsec3param.salt = nsec3chain->salt;
3378 nsec3chain->seen_nsec = false;
3379 nsec3chain->delete_nsec = false;
3380 nsec3chain->save_delete_nsec = false;
3381
3382 /*
3383 * Log NSEC3 parameters defined by supplied NSEC3PARAM RDATA.
3384 */
3385 if (nsec3param->flags == 0)
3386 strlcpy(flags, "NONE", sizeof(flags));
3387 else {
3388 flags[0] = '\0';
3389 if ((nsec3param->flags & DNS_NSEC3FLAG_REMOVE) != 0) {
3390 strlcat(flags, "REMOVE", sizeof(flags));
3391 }
3392 if ((nsec3param->flags & DNS_NSEC3FLAG_INITIAL) != 0) {
3393 if (flags[0] == '\0')
3394 strlcpy(flags, "INITIAL", sizeof(flags));
3395 else
3396 strlcat(flags, "|INITIAL", sizeof(flags));
3397 }
3398 if ((nsec3param->flags & DNS_NSEC3FLAG_CREATE) != 0) {
3399 if (flags[0] == '\0')
3400 strlcpy(flags, "CREATE", sizeof(flags));
3401 else
3402 strlcat(flags, "|CREATE", sizeof(flags));
3403 }
3404 if ((nsec3param->flags & DNS_NSEC3FLAG_NONSEC) != 0) {
3405 if (flags[0] == '\0')
3406 strlcpy(flags, "NONSEC", sizeof(flags));
3407 else
3408 strlcat(flags, "|NONSEC", sizeof(flags));
3409 }
3410 if ((nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) != 0) {
3411 if (flags[0] == '\0')
3412 strlcpy(flags, "OPTOUT", sizeof(flags));
3413 else
3414 strlcat(flags, "|OPTOUT", sizeof(flags));
3415 }
3416 }
3417 result = dns_nsec3param_salttotext(nsec3param, saltbuf,
3418 sizeof(saltbuf));
3419 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3420 dns_zone_log(zone, ISC_LOG_INFO,
3421 "zone_addnsec3chain(%u,%s,%u,%s)",
3422 nsec3param->hash, flags, nsec3param->iterations,
3423 saltbuf);
3424
3425 /*
3426 * If the NSEC3 chain defined by the supplied NSEC3PARAM RDATA is
3427 * currently being processed, interrupt its processing to avoid
3428 * simultaneously adding and removing records for the same NSEC3 chain.
3429 */
3430 for (current = ISC_LIST_HEAD(zone->nsec3chain);
3431 current != NULL;
3432 current = ISC_LIST_NEXT(current, link)) {
3433 if (current->db == db &&
3434 current->nsec3param.hash == nsec3param->hash &&
3435 current->nsec3param.iterations == nsec3param->iterations &&
3436 current->nsec3param.salt_length == nsec3param->salt_length
3437 && !memcmp(current->nsec3param.salt, nsec3param->salt,
3438 nsec3param->salt_length))
3439 current->done = true;
3440 }
3441
3442 /*
3443 * Attach zone database to the structure initialized above and create
3444 * an iterator for it with appropriate options in order to avoid
3445 * creating NSEC3 records for NSEC3 records.
3446 */
3447 dns_db_attach(db, &nsec3chain->db);
3448 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
3449 options = DNS_DB_NONSEC3;
3450 result = dns_db_createiterator(nsec3chain->db, options,
3451 &nsec3chain->dbiterator);
3452 if (result == ISC_R_SUCCESS)
3453 result = dns_dbiterator_first(nsec3chain->dbiterator);
3454 if (result == ISC_R_SUCCESS) {
3455 /*
3456 * Database iterator initialization succeeded. We are now
3457 * ready to kick off adding/removing records belonging to this
3458 * NSEC3 chain. Append the structure initialized above to the
3459 * "nsec3chain" list for the zone and set the appropriate zone
3460 * timer so that zone_nsec3chain() is called as soon as
3461 * possible.
3462 */
3463 dns_dbiterator_pause(nsec3chain->dbiterator);
3464 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
3465 nsec3chain, link);
3466 nsec3chain = NULL;
3467 if (isc_time_isepoch(&zone->nsec3chaintime)) {
3468 TIME_NOW(&now);
3469 zone->nsec3chaintime = now;
3470 if (zone->task != NULL)
3471 zone_settimer(zone, &now);
3472 }
3473 }
3474
3475 if (nsec3chain != NULL) {
3476 if (nsec3chain->db != NULL)
3477 dns_db_detach(&nsec3chain->db);
3478 if (nsec3chain->dbiterator != NULL)
3479 dns_dbiterator_destroy(&nsec3chain->dbiterator);
3480 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
3481 }
3482
3483 cleanup:
3484 if (db != NULL)
3485 dns_db_detach(&db);
3486 return (result);
3487 }
3488
3489 /*
3490 * Find private-type records at the zone apex which signal that an NSEC3 chain
3491 * should be added or removed. For each such record, extract NSEC3PARAM RDATA
3492 * and pass it to zone_addnsec3chain().
3493 *
3494 * Zone must be locked by caller.
3495 */
3496 static void
3497 resume_addnsec3chain(dns_zone_t *zone) {
3498 dns_dbnode_t *node = NULL;
3499 dns_dbversion_t *version = NULL;
3500 dns_rdataset_t rdataset;
3501 isc_result_t result;
3502 dns_rdata_nsec3param_t nsec3param;
3503 bool nseconly = false, nsec3ok = false;
3504 dns_db_t *db = NULL;
3505
3506 INSIST(LOCKED_ZONE(zone));
3507
3508 if (zone->privatetype == 0)
3509 return;
3510
3511 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3512 if (zone->db != NULL)
3513 dns_db_attach(zone->db, &db);
3514 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3515 if (db == NULL)
3516 goto cleanup;
3517
3518 result = dns_db_findnode(db, &zone->origin, false, &node);
3519 if (result != ISC_R_SUCCESS)
3520 goto cleanup;
3521
3522 dns_db_currentversion(db, &version);
3523
3524 /*
3525 * In order to create NSEC3 chains we need the DNSKEY RRset at zone
3526 * apex to exist and contain no keys using NSEC-only algorithms.
3527 */
3528 result = dns_nsec_nseconly(db, version, &nseconly);
3529 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
3530
3531 /*
3532 * Get the RRset containing all private-type records at the zone apex.
3533 */
3534 dns_rdataset_init(&rdataset);
3535 result = dns_db_findrdataset(db, node, version,
3536 zone->privatetype, dns_rdatatype_none,
3537 0, &rdataset, NULL);
3538 if (result != ISC_R_SUCCESS) {
3539 INSIST(!dns_rdataset_isassociated(&rdataset));
3540 goto cleanup;
3541 }
3542
3543 for (result = dns_rdataset_first(&rdataset);
3544 result == ISC_R_SUCCESS;
3545 result = dns_rdataset_next(&rdataset))
3546 {
3547 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
3548 dns_rdata_t rdata = DNS_RDATA_INIT;
3549 dns_rdata_t private = DNS_RDATA_INIT;
3550
3551 dns_rdataset_current(&rdataset, &private);
3552 /*
3553 * Try extracting NSEC3PARAM RDATA from this private-type
3554 * record. Failure means this private-type record does not
3555 * represent an NSEC3PARAM record, so skip it.
3556 */
3557 if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
3558 sizeof(buf)))
3559 continue;
3560 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
3561 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3562 if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) ||
3563 ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok))
3564 {
3565 /*
3566 * Pass the NSEC3PARAM RDATA contained in this
3567 * private-type record to zone_addnsec3chain() so that
3568 * it can kick off adding or removing NSEC3 records.
3569 */
3570 result = zone_addnsec3chain(zone, &nsec3param);
3571 if (result != ISC_R_SUCCESS) {
3572 dns_zone_log(zone, ISC_LOG_ERROR,
3573 "zone_addnsec3chain failed: %s",
3574 dns_result_totext(result));
3575 }
3576 }
3577 }
3578 dns_rdataset_disassociate(&rdataset);
3579 cleanup:
3580 if (db != NULL) {
3581 if (node != NULL)
3582 dns_db_detachnode(db, &node);
3583 if (version != NULL)
3584 dns_db_closeversion(db, &version, false);
3585 dns_db_detach(&db);
3586 }
3587 }
3588
3589 static void
3590 set_resigntime(dns_zone_t *zone) {
3591 dns_rdataset_t rdataset;
3592 dns_fixedname_t fixed;
3593 unsigned int resign;
3594 isc_result_t result;
3595 uint32_t nanosecs;
3596 dns_db_t *db = NULL;
3597
3598 /* We only re-sign zones that can be dynamically updated */
3599 if (zone->update_disabled)
3600 return;
3601
3602 if (!inline_secure(zone) && (zone->type != dns_zone_master ||
3603 (zone->ssutable == NULL &&
3604 (zone->update_acl == NULL || dns_acl_isnone(zone->update_acl)))))
3605 return;
3606
3607 dns_rdataset_init(&rdataset);
3608 dns_fixedname_init(&fixed);
3609
3610 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3611 if (zone->db != NULL)
3612 dns_db_attach(zone->db, &db);
3613 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3614 if (db == NULL) {
3615 isc_time_settoepoch(&zone->resigntime);
3616 return;
3617 }
3618
3619 result = dns_db_getsigningtime(db, &rdataset,
3620 dns_fixedname_name(&fixed));
3621 if (result != ISC_R_SUCCESS) {
3622 isc_time_settoepoch(&zone->resigntime);
3623 goto cleanup;
3624 }
3625
3626 resign = rdataset.resign - zone->sigresigninginterval;
3627 dns_rdataset_disassociate(&rdataset);
3628 nanosecs = isc_random_uniform(1000000000);
3629 isc_time_set(&zone->resigntime, resign, nanosecs);
3630 cleanup:
3631 dns_db_detach(&db);
3632 return;
3633 }
3634
3635 static isc_result_t
3636 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
3637 dns_dbnode_t *node = NULL;
3638 dns_rdataset_t rdataset;
3639 dns_dbversion_t *version = NULL;
3640 dns_rdata_nsec3param_t nsec3param;
3641 bool ok = false;
3642 isc_result_t result;
3643 dns_rdata_t rdata = DNS_RDATA_INIT;
3644 bool dynamic = (zone->type == dns_zone_master) ?
3645 dns_zone_isdynamic(zone, false) : false;
3646
3647 dns_rdataset_init(&rdataset);
3648 result = dns_db_findnode(db, &zone->origin, false, &node);
3649 if (result != ISC_R_SUCCESS) {
3650 dns_zone_log(zone, ISC_LOG_ERROR,
3651 "nsec3param lookup failure: %s",
3652 dns_result_totext(result));
3653 return (result);
3654 }
3655 dns_db_currentversion(db, &version);
3656
3657 result = dns_db_findrdataset(db, node, version,
3658 dns_rdatatype_nsec3param,
3659 dns_rdatatype_none, 0, &rdataset, NULL);
3660 if (result == ISC_R_NOTFOUND) {
3661 INSIST(!dns_rdataset_isassociated(&rdataset));
3662 result = ISC_R_SUCCESS;
3663 goto cleanup;
3664 }
3665 if (result != ISC_R_SUCCESS) {
3666 INSIST(!dns_rdataset_isassociated(&rdataset));
3667 dns_zone_log(zone, ISC_LOG_ERROR,
3668 "nsec3param lookup failure: %s",
3669 dns_result_totext(result));
3670 goto cleanup;
3671 }
3672
3673 /*
3674 * For dynamic zones we must support every algorithm so we can
3675 * regenerate all the NSEC3 chains.
3676 * For non-dynamic zones we only need to find a supported algorithm.
3677 */
3678 for (result = dns_rdataset_first(&rdataset);
3679 result == ISC_R_SUCCESS;
3680 result = dns_rdataset_next(&rdataset))
3681 {
3682 dns_rdataset_current(&rdataset, &rdata);
3683 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
3684 dns_rdata_reset(&rdata);
3685 INSIST(result == ISC_R_SUCCESS);
3686 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
3687 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
3688 {
3689 dns_zone_log(zone, ISC_LOG_WARNING,
3690 "nsec3 test \"unknown\" hash algorithm found: %u",
3691 nsec3param.hash);
3692 ok = true;
3693 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
3694 if (dynamic) {
3695 dns_zone_log(zone, ISC_LOG_ERROR,
3696 "unsupported nsec3 hash algorithm"
3697 " in dynamic zone: %u",
3698 nsec3param.hash);
3699 result = DNS_R_BADZONE;
3700 /* Stop second error message. */
3701 ok = true;
3702 break;
3703 } else
3704 dns_zone_log(zone, ISC_LOG_WARNING,
3705 "unsupported nsec3 hash algorithm: %u",
3706 nsec3param.hash);
3707 } else
3708 ok = true;
3709 }
3710 if (result == ISC_R_NOMORE)
3711 result = ISC_R_SUCCESS;
3712
3713 if (!ok) {
3714 result = DNS_R_BADZONE;
3715 dns_zone_log(zone, ISC_LOG_ERROR,
3716 "no supported nsec3 hash algorithm");
3717 }
3718
3719 cleanup:
3720 if (dns_rdataset_isassociated(&rdataset))
3721 dns_rdataset_disassociate(&rdataset);
3722 dns_db_closeversion(db, &version, false);
3723 dns_db_detachnode(db, &node);
3724 return (result);
3725 }
3726
3727 /*
3728 * Set the timer for refreshing the key zone to the soonest future time
3729 * of the set (current timer, keydata->refresh, keydata->addhd,
3730 * keydata->removehd).
3731 */
3732 static void
3733 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
3734 isc_stdtime_t now, bool force)
3735 {
3736 const char me[] = "set_refreshkeytimer";
3737 isc_stdtime_t then;
3738 isc_time_t timenow, timethen;
3739 char timebuf[80];
3740
3741 ENTER;
3742 then = key->refresh;
3743 if (force)
3744 then = now;
3745 if (key->addhd > now && key->addhd < then)
3746 then = key->addhd;
3747 if (key->removehd > now && key->removehd < then)
3748 then = key->removehd;
3749
3750 TIME_NOW(&timenow);
3751 if (then > now)
3752 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
3753 else
3754 timethen = timenow;
3755 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
3756 isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
3757 zone->refreshkeytime = timethen;
3758
3759 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
3760 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
3761 zone_settimer(zone, &timenow);
3762 }
3763
3764 /*
3765 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
3766 * If the key zone is changed, set '*changed' to true.
3767 */
3768 static isc_result_t
3769 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
3770 dns_diff_t *diff, dns_keytable_t *keytable,
3771 dns_keynode_t **keynodep, bool *changed)
3772 {
3773 const char me[] = "create_keydata";
3774 isc_result_t result = ISC_R_SUCCESS;
3775 isc_buffer_t keyb, dstb;
3776 unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
3777 dns_rdata_keydata_t keydata;
3778 dns_rdata_dnskey_t dnskey;
3779 dns_rdata_t rdata = DNS_RDATA_INIT;
3780 dns_keynode_t *keynode;
3781 isc_stdtime_t now;
3782 isc_region_t r;
3783 dst_key_t *key;
3784
3785 REQUIRE(keynodep != NULL);
3786 keynode = *keynodep;
3787
3788 ENTER;
3789 isc_stdtime_get(&now);
3790
3791 /* Loop in case there's more than one key. */
3792 while (result == ISC_R_SUCCESS) {
3793 dns_keynode_t *nextnode = NULL;
3794
3795 key = dns_keynode_key(keynode);
3796 if (key == NULL)
3797 goto skip;
3798
3799 isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
3800 CHECK(dst_key_todns(key, &dstb));
3801
3802 /* Convert DST key to DNSKEY. */
3803 dns_rdata_reset(&rdata);
3804 isc_buffer_usedregion(&dstb, &r);
3805 dns_rdata_fromregion(&rdata, dst_key_class(key),
3806 dns_rdatatype_dnskey, &r);
3807
3808 /* DSTKEY to KEYDATA. */
3809 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
3810 CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
3811 NULL));
3812
3813 /* KEYDATA to rdata. */
3814 dns_rdata_reset(&rdata);
3815 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
3816 CHECK(dns_rdata_fromstruct(&rdata,
3817 zone->rdclass, dns_rdatatype_keydata,
3818 &keydata, &keyb));
3819
3820 /* Add rdata to zone. */
3821 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
3822 dst_key_name(key), 0, &rdata));
3823 *changed = true;
3824
3825 /* Refresh new keys from the zone apex as soon as possible. */
3826 set_refreshkeytimer(zone, &keydata, now, true);
3827
3828 skip:
3829 result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
3830 if (result != ISC_R_NOTFOUND) {
3831 dns_keytable_detachkeynode(keytable, &keynode);
3832 keynode = nextnode;
3833 }
3834 }
3835
3836 if (keynode != NULL)
3837 dns_keytable_detachkeynode(keytable, &keynode);
3838 *keynodep = NULL;
3839
3840 return (ISC_R_SUCCESS);
3841
3842 failure:
3843 return (result);
3844 }
3845
3846 /*
3847 * Remove from the key zone all the KEYDATA records found in rdataset.
3848 */
3849 static isc_result_t
3850 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3851 dns_name_t *name, dns_rdataset_t *rdataset)
3852 {
3853 dns_rdata_t rdata = DNS_RDATA_INIT;
3854 isc_result_t result, uresult;
3855
3856 for (result = dns_rdataset_first(rdataset);
3857 result == ISC_R_SUCCESS;
3858 result = dns_rdataset_next(rdataset)) {
3859 dns_rdata_reset(&rdata);
3860 dns_rdataset_current(rdataset, &rdata);
3861 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
3862 name, 0, &rdata);
3863 if (uresult != ISC_R_SUCCESS)
3864 return (uresult);
3865 }
3866 if (result == ISC_R_NOMORE)
3867 result = ISC_R_SUCCESS;
3868 return (result);
3869 }
3870
3871 /*
3872 * Compute the DNSSEC key ID for a DNSKEY record.
3873 */
3874 static isc_result_t
3875 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
3876 dns_keytag_t *tag)
3877 {
3878 isc_result_t result;
3879 dns_rdata_t rdata = DNS_RDATA_INIT;
3880 unsigned char data[4096];
3881 isc_buffer_t buffer;
3882 dst_key_t *dstkey = NULL;
3883
3884 isc_buffer_init(&buffer, data, sizeof(data));
3885 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
3886 dns_rdatatype_dnskey, dnskey, &buffer);
3887
3888 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
3889 if (result == ISC_R_SUCCESS)
3890 *tag = dst_key_id(dstkey);
3891 dst_key_free(&dstkey);
3892
3893 return (result);
3894 }
3895
3896 /*
3897 * Add key to the security roots.
3898 */
3899 static void
3900 trust_key(dns_zone_t *zone, dns_name_t *keyname,
3901 dns_rdata_dnskey_t *dnskey, bool initial,
3902 isc_mem_t *mctx)
3903 {
3904 isc_result_t result;
3905 dns_rdata_t rdata = DNS_RDATA_INIT;
3906 unsigned char data[4096];
3907 isc_buffer_t buffer;
3908 dns_keytable_t *sr = NULL;
3909 dst_key_t *dstkey = NULL;
3910
3911 /* Convert dnskey to DST key. */
3912 isc_buffer_init(&buffer, data, sizeof(data));
3913 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
3914 dns_rdatatype_dnskey, dnskey, &buffer);
3915
3916 result = dns_view_getsecroots(zone->view, &sr);
3917 if (result != ISC_R_SUCCESS)
3918 goto failure;
3919
3920 CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
3921 CHECK(dns_keytable_add(sr, true, initial, &dstkey));
3922 dns_keytable_detach(&sr);
3923
3924 failure:
3925 if (dstkey != NULL)
3926 dst_key_free(&dstkey);
3927 if (sr != NULL)
3928 dns_keytable_detach(&sr);
3929 return;
3930 }
3931
3932 /*
3933 * Add a null key to the security roots for so that all queries
3934 * to the zone will fail.
3935 */
3936 static void
3937 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
3938 isc_result_t result;
3939 dns_keytable_t *sr = NULL;
3940
3941 result = dns_view_getsecroots(zone->view, &sr);
3942 if (result == ISC_R_SUCCESS) {
3943 dns_keytable_marksecure(sr, keyname);
3944 dns_keytable_detach(&sr);
3945 }
3946 }
3947
3948 /*
3949 * Scan a set of KEYDATA records from the key zone. The ones that are
3950 * valid (i.e., the add holddown timer has expired) become trusted keys.
3951 */
3952 static void
3953 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
3954 isc_result_t result;
3955 dns_rdata_t rdata = DNS_RDATA_INIT;
3956 dns_rdata_keydata_t keydata;
3957 dns_rdata_dnskey_t dnskey;
3958 isc_mem_t *mctx = zone->mctx;
3959 int trusted = 0, revoked = 0, pending = 0;
3960 isc_stdtime_t now;
3961 dns_keytable_t *sr = NULL;
3962
3963 isc_stdtime_get(&now);
3964
3965 result = dns_view_getsecroots(zone->view, &sr);
3966 if (result == ISC_R_SUCCESS) {
3967 dns_keytable_delete(sr, name);
3968 dns_keytable_detach(&sr);
3969 }
3970
3971 /* Now insert all the accepted trust anchors from this keydata set. */
3972 for (result = dns_rdataset_first(rdataset);
3973 result == ISC_R_SUCCESS;
3974 result = dns_rdataset_next(rdataset)) {
3975 dns_rdata_reset(&rdata);
3976 dns_rdataset_current(rdataset, &rdata);
3977
3978 /* Convert rdata to keydata. */
3979 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
3980 if (result == ISC_R_UNEXPECTEDEND)
3981 continue;
3982 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3983
3984 /* Set the key refresh timer to force a fast refresh. */
3985 set_refreshkeytimer(zone, &keydata, now, true);
3986
3987 /* If the removal timer is nonzero, this key was revoked. */
3988 if (keydata.removehd != 0) {
3989 revoked++;
3990 continue;
3991 }
3992
3993 /*
3994 * If the add timer is still pending, this key is not
3995 * trusted yet.
3996 */
3997 if (now < keydata.addhd) {
3998 pending++;
3999 continue;
4000 }
4001
4002 /* Convert keydata to dnskey. */
4003 dns_keydata_todnskey(&keydata, &dnskey, NULL);
4004
4005 /* Add to keytables. */
4006 trusted++;
4007 trust_key(zone, name, &dnskey,
4008 (keydata.addhd == 0), mctx);
4009 }
4010
4011 if (trusted == 0 && pending != 0) {
4012 char namebuf[DNS_NAME_FORMATSIZE];
4013 dns_name_format(name, namebuf, sizeof namebuf);
4014 dns_zone_log(zone, ISC_LOG_ERROR,
4015 "No valid trust anchors for '%s'!", namebuf);
4016 dns_zone_log(zone, ISC_LOG_ERROR,
4017 "%d key(s) revoked, %d still pending",
4018 revoked, pending);
4019 dns_zone_log(zone, ISC_LOG_ERROR,
4020 "All queries to '%s' will fail", namebuf);
4021 fail_secure(zone, name);
4022 }
4023 }
4024
4025 static isc_result_t
4026 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
4027 dns_diff_t *diff)
4028 {
4029 dns_diff_t temp_diff;
4030 isc_result_t result;
4031
4032 /*
4033 * Create a singleton diff.
4034 */
4035 dns_diff_init(diff->mctx, &temp_diff);
4036 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
4037
4038 /*
4039 * Apply it to the database.
4040 */
4041 result = dns_diff_apply(&temp_diff, db, ver);
4042 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
4043 if (result != ISC_R_SUCCESS) {
4044 dns_difftuple_free(tuple);
4045 return (result);
4046 }
4047
4048 /*
4049 * Merge it into the current pending journal entry.
4050 */
4051 dns_diff_appendminimal(diff, tuple);
4052
4053 /*
4054 * Do not clear temp_diff.
4055 */
4056 return (ISC_R_SUCCESS);
4057 }
4058
4059 static isc_result_t
4060 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
4061 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
4062 dns_rdata_t *rdata)
4063 {
4064 dns_difftuple_t *tuple = NULL;
4065 isc_result_t result;
4066 result = dns_difftuple_create(diff->mctx, op,
4067 name, ttl, rdata, &tuple);
4068 if (result != ISC_R_SUCCESS)
4069 return (result);
4070 return (do_one_tuple(&tuple, db, ver, diff));
4071 }
4072
4073 static isc_result_t
4074 update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
4075 isc_mem_t *mctx, dns_updatemethod_t method) {
4076 dns_difftuple_t *deltuple = NULL;
4077 dns_difftuple_t *addtuple = NULL;
4078 uint32_t serial;
4079 isc_result_t result;
4080
4081 INSIST(method != dns_updatemethod_none);
4082
4083 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
4084 CHECK(dns_difftuple_copy(deltuple, &addtuple));
4085 addtuple->op = DNS_DIFFOP_ADD;
4086
4087 serial = dns_soa_getserial(&addtuple->rdata);
4088 serial = dns_update_soaserial(serial, method);
4089 dns_soa_setserial(serial, &addtuple->rdata);
4090 CHECK(do_one_tuple(&deltuple, db, ver, diff));
4091 CHECK(do_one_tuple(&addtuple, db, ver, diff));
4092 result = ISC_R_SUCCESS;
4093
4094 failure:
4095 if (addtuple != NULL)
4096 dns_difftuple_free(&addtuple);
4097 if (deltuple != NULL)
4098 dns_difftuple_free(&deltuple);
4099 return (result);
4100 }
4101
4102 /*
4103 * Write all transactions in 'diff' to the zone journal file.
4104 */
4105 static isc_result_t
4106 zone_journal(dns_zone_t *zone, dns_diff_t *diff, uint32_t *sourceserial,
4107 const char *caller)
4108 {
4109 const char me[] = "zone_journal";
4110 const char *journalfile;
4111 isc_result_t result = ISC_R_SUCCESS;
4112 dns_journal_t *journal = NULL;
4113 unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE;
4114
4115 ENTER;
4116 journalfile = dns_zone_getjournal(zone);
4117 if (journalfile != NULL) {
4118 result = dns_journal_open(zone->mctx, journalfile, mode,
4119 &journal);
4120 if (result != ISC_R_SUCCESS) {
4121 dns_zone_log(zone, ISC_LOG_ERROR,
4122 "%s:dns_journal_open -> %s",
4123 caller, dns_result_totext(result));
4124 return (result);
4125 }
4126
4127 if (sourceserial != NULL)
4128 dns_journal_set_sourceserial(journal, *sourceserial);
4129
4130 result = dns_journal_write_transaction(journal, diff);
4131 if (result != ISC_R_SUCCESS) {
4132 dns_zone_log(zone, ISC_LOG_ERROR,
4133 "%s:dns_journal_write_transaction -> %s",
4134 caller, dns_result_totext(result));
4135 }
4136 dns_journal_destroy(&journal);
4137 }
4138
4139 return (result);
4140 }
4141
4142 /*
4143 * Create an SOA record for a newly-created zone
4144 */
4145 static isc_result_t
4146 add_soa(dns_zone_t *zone, dns_db_t *db) {
4147 isc_result_t result;
4148 dns_rdata_t rdata = DNS_RDATA_INIT;
4149 unsigned char buf[DNS_SOA_BUFFERSIZE];
4150 dns_dbversion_t *ver = NULL;
4151 dns_diff_t diff;
4152
4153 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
4154
4155 dns_diff_init(zone->mctx, &diff);
4156 result = dns_db_newversion(db, &ver);
4157 if (result != ISC_R_SUCCESS) {
4158 dns_zone_log(zone, ISC_LOG_ERROR,
4159 "add_soa:dns_db_newversion -> %s",
4160 dns_result_totext(result));
4161 goto failure;
4162 }
4163
4164 /* Build SOA record */
4165 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
4166 0, 0, 0, 0, 0, buf, &rdata);
4167 if (result != ISC_R_SUCCESS) {
4168 dns_zone_log(zone, ISC_LOG_ERROR,
4169 "add_soa:dns_soa_buildrdata -> %s",
4170 dns_result_totext(result));
4171 goto failure;
4172 }
4173
4174 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
4175 &zone->origin, 0, &rdata);
4176
4177 failure:
4178 dns_diff_clear(&diff);
4179 if (ver != NULL)
4180 dns_db_closeversion(db, &ver, (result == ISC_R_SUCCESS));
4181
4182 INSIST(ver == NULL);
4183
4184 return (result);
4185 }
4186
4187 struct addifmissing_arg {
4188 dns_db_t *db;
4189 dns_dbversion_t *ver;
4190 dns_diff_t *diff;
4191 dns_zone_t *zone;
4192 bool *changed;
4193 isc_result_t result;
4194 };
4195
4196 static void
4197 addifmissing(dns_keytable_t *keytable, dns_keynode_t *keynode, void *arg) {
4198 dns_db_t *db = ((struct addifmissing_arg *)arg)->db;
4199 dns_dbversion_t *ver = ((struct addifmissing_arg *)arg)->ver;
4200 dns_diff_t *diff = ((struct addifmissing_arg *)arg)->diff;
4201 dns_zone_t *zone = ((struct addifmissing_arg *)arg)->zone;
4202 bool *changed = ((struct addifmissing_arg *)arg)->changed;
4203 isc_result_t result;
4204 dns_keynode_t *dummy = NULL;
4205
4206 if (((struct addifmissing_arg *)arg)->result != ISC_R_SUCCESS)
4207 return;
4208
4209 if (dns_keynode_managed(keynode)) {
4210 dns_fixedname_t fname;
4211 dns_name_t *keyname;
4212 dst_key_t *key;
4213
4214 key = dns_keynode_key(keynode);
4215 if (key == NULL)
4216 return;
4217 dns_fixedname_init(&fname);
4218
4219 keyname = dst_key_name(key);
4220 result = dns_db_find(db, keyname, ver,
4221 dns_rdatatype_keydata,
4222 DNS_DBFIND_NOWILD, 0, NULL,
4223 dns_fixedname_name(&fname),
4224 NULL, NULL);
4225 if (result == ISC_R_SUCCESS)
4226 return;
4227 dns_keytable_attachkeynode(keytable, keynode, &dummy);
4228 result = create_keydata(zone, db, ver, diff, keytable,
4229 &dummy, changed);
4230 if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE)
4231 ((struct addifmissing_arg *)arg)->result = result;
4232 }
4233 };
4234
4235 /*
4236 * Synchronize the set of initializing keys found in managed-keys {}
4237 * statements with the set of trust anchors found in the managed-keys.bind
4238 * zone. If a domain is no longer named in managed-keys, delete all keys
4239 * from that domain from the key zone. If a domain is mentioned in in
4240 * managed-keys but there are no references to it in the key zone, load
4241 * the key zone with the initializing key(s) for that domain.
4242 */
4243 static isc_result_t
4244 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
4245 isc_result_t result = ISC_R_SUCCESS;
4246 bool changed = false;
4247 bool commit = false;
4248 dns_keynode_t *keynode = NULL;
4249 dns_view_t *view = zone->view;
4250 dns_keytable_t *sr = NULL;
4251 dns_dbversion_t *ver = NULL;
4252 dns_diff_t diff;
4253 dns_rriterator_t rrit;
4254 struct addifmissing_arg arg;
4255
4256 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
4257
4258 dns_diff_init(zone->mctx, &diff);
4259
4260 CHECK(dns_view_getsecroots(view, &sr));
4261
4262 result = dns_db_newversion(db, &ver);
4263 if (result != ISC_R_SUCCESS) {
4264 dns_zone_log(zone, ISC_LOG_ERROR,
4265 "sync_keyzone:dns_db_newversion -> %s",
4266 dns_result_totext(result));
4267 goto failure;
4268 }
4269
4270 /*
4271 * Walk the zone DB. If we find any keys whose names are no longer
4272 * in managed-keys (or *are* in trusted-keys, meaning they are
4273 * permanent and not RFC5011-maintained), delete them from the
4274 * zone. Otherwise call load_secroots(), which loads keys into
4275 * secroots as appropriate.
4276 */
4277 dns_rriterator_init(&rrit, db, ver, 0);
4278 for (result = dns_rriterator_first(&rrit);
4279 result == ISC_R_SUCCESS;
4280 result = dns_rriterator_nextrrset(&rrit)) {
4281 dns_rdataset_t *rdataset = NULL;
4282 dns_name_t *rrname = NULL;
4283 uint32_t ttl;
4284
4285 dns_rriterator_current(&rrit, &rrname, &ttl, &rdataset, NULL);
4286 if (!dns_rdataset_isassociated(rdataset)) {
4287 dns_rriterator_destroy(&rrit);
4288 goto failure;
4289 }
4290
4291 if (rdataset->type != dns_rdatatype_keydata)
4292 continue;
4293
4294 result = dns_keytable_find(sr, rrname, &keynode);
4295 if ((result != ISC_R_SUCCESS &&
4296 result != DNS_R_PARTIALMATCH) ||
4297 dns_keynode_managed(keynode) == false)
4298 {
4299 CHECK(delete_keydata(db, ver, &diff,
4300 rrname, rdataset));
4301 changed = true;
4302 } else {
4303 load_secroots(zone, rrname, rdataset);
4304 }
4305
4306 if (keynode != NULL)
4307 dns_keytable_detachkeynode(sr, &keynode);
4308 }
4309 dns_rriterator_destroy(&rrit);
4310
4311 /*
4312 * Now walk secroots to find any managed keys that aren't
4313 * in the zone. If we find any, we add them to the zone.
4314 */
4315 arg.db = db;
4316 arg.ver = ver;
4317 arg.result = ISC_R_SUCCESS;
4318 arg.diff = &diff;
4319 arg.zone = zone;
4320 arg.changed = &changed;
4321 dns_keytable_forall(sr, addifmissing, &arg);
4322 result = arg.result;
4323 if (changed) {
4324 /* Write changes to journal file. */
4325 CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
4326 zone->updatemethod));
4327 CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone"));
4328
4329 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
4330 zone_needdump(zone, 30);
4331 commit = true;
4332 }
4333
4334 failure:
4335 if (result != ISC_R_SUCCESS &&
4336 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
4337 dns_zone_log(zone, ISC_LOG_ERROR,
4338 "unable to synchronize managed keys: %s",
4339 dns_result_totext(result));
4340 isc_time_settoepoch(&zone->refreshkeytime);
4341 }
4342 if (keynode != NULL)
4343 dns_keytable_detachkeynode(sr, &keynode);
4344 if (sr != NULL)
4345 dns_keytable_detach(&sr);
4346 if (ver != NULL)
4347 dns_db_closeversion(db, &ver, commit);
4348 dns_diff_clear(&diff);
4349
4350 INSIST(ver == NULL);
4351
4352 return (result);
4353 }
4354
4355 isc_result_t
4356 dns_zone_synckeyzone(dns_zone_t *zone) {
4357 isc_result_t result;
4358 dns_db_t *db = NULL;
4359
4360 if (zone->type != dns_zone_key)
4361 return (DNS_R_BADZONE);
4362
4363 CHECK(dns_zone_getdb(zone, &db));
4364
4365 LOCK_ZONE(zone);
4366 result = sync_keyzone(zone, db);
4367 UNLOCK_ZONE(zone);
4368
4369 failure:
4370 if (db != NULL)
4371 dns_db_detach(&db);
4372 return (result);
4373 }
4374
4375 static void
4376 maybe_send_secure(dns_zone_t *zone) {
4377 isc_result_t result;
4378
4379 /*
4380 * We've finished loading, or else failed to load, an inline-signing
4381 * 'secure' zone. We now need information about the status of the
4382 * 'raw' zone. If we failed to load, then we need it to send a
4383 * copy of its database; if we succeeded, we need it to send its
4384 * serial number so that we can sync with it. If it has not yet
4385 * loaded, we set a flag so that it will send the necessary
4386 * information when it has finished loading.
4387 */
4388 if (zone->raw->db != NULL) {
4389 if (zone->db != NULL) {
4390 uint32_t serial;
4391 unsigned int soacount;
4392
4393 result = zone_get_from_db(zone->raw, zone->raw->db,
4394 NULL, &soacount, &serial, NULL,
4395 NULL, NULL, NULL, NULL);
4396 if (result == ISC_R_SUCCESS && soacount > 0U)
4397 zone_send_secureserial(zone->raw, serial);
4398 } else
4399 zone_send_securedb(zone->raw, zone->raw->db);
4400
4401 } else
4402 DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
4403 }
4404
4405 static bool
4406 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
4407 isc_result_t result;
4408 bool answer = false;
4409 dns_diff_t diff;
4410
4411 dns_diff_init(mctx, &diff);
4412 result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
4413 if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples))
4414 answer = true;
4415 dns_diff_clear(&diff);
4416 return (answer);
4417 }
4418
4419 /*
4420 * The zone is presumed to be locked.
4421 * If this is a inline_raw zone the secure version is also locked.
4422 */
4423 static isc_result_t
4424 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
4425 isc_result_t result)
4426 {
4427 unsigned int soacount = 0;
4428 unsigned int nscount = 0;
4429 unsigned int errors = 0;
4430 uint32_t serial, oldserial, refresh, retry, expire, minimum;
4431 isc_time_t now;
4432 bool needdump = false;
4433 bool hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
4434 bool nomaster = false;
4435 unsigned int options;
4436 dns_include_t *inc;
4437
4438 INSIST(LOCKED_ZONE(zone));
4439 if (inline_raw(zone))
4440 INSIST(LOCKED_ZONE(zone->secure));
4441
4442 TIME_NOW(&now);
4443
4444 /*
4445 * Initiate zone transfer? We may need a error code that
4446 * indicates that the "permanent" form does not exist.
4447 * XXX better error feedback to log.
4448 */
4449 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
4450 if (zone->type == dns_zone_slave ||
4451 zone->type == dns_zone_mirror ||
4452 zone->type == dns_zone_stub ||
4453 (zone->type == dns_zone_redirect &&
4454 zone->masters == NULL)) {
4455 if (result == ISC_R_FILENOTFOUND)
4456 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4457 ISC_LOG_DEBUG(1),
4458 "no master file");
4459 else if (result != DNS_R_NOMASTERFILE)
4460 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4461 ISC_LOG_ERROR,
4462 "loading from master file %s "
4463 "failed: %s",
4464 zone->masterfile,
4465 dns_result_totext(result));
4466 } else if (zone->type == dns_zone_master &&
4467 inline_secure(zone) && result == ISC_R_FILENOTFOUND)
4468 {
4469 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4470 ISC_LOG_DEBUG(1),
4471 "no master file, requesting db");
4472 maybe_send_secure(zone);
4473 } else {
4474 int level = ISC_LOG_ERROR;
4475 if (zone->type == dns_zone_key &&
4476 result == ISC_R_FILENOTFOUND)
4477 level = ISC_LOG_DEBUG(1);
4478 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, level,
4479 "loading from master file %s failed: %s",
4480 zone->masterfile,
4481 dns_result_totext(result));
4482 nomaster = true;
4483 }
4484
4485 if (zone->type != dns_zone_key)
4486 goto cleanup;
4487 }
4488
4489 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(2),
4490 "number of nodes in database: %u",
4491 dns_db_nodecount(db));
4492
4493 if (result == DNS_R_SEENINCLUDE)
4494 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
4495 else
4496 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
4497
4498 /*
4499 * If there's no master file for a key zone, then the zone is new:
4500 * create an SOA record. (We do this now, instead of later, so that
4501 * if there happens to be a journal file, we can roll forward from
4502 * a sane starting point.)
4503 */
4504 if (nomaster && zone->type == dns_zone_key) {
4505 result = add_soa(zone, db);
4506 if (result != ISC_R_SUCCESS)
4507 goto cleanup;
4508 }
4509
4510 /*
4511 * Apply update log, if any, on initial load.
4512 */
4513 if (zone->journal != NULL &&
4514 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
4515 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
4516 {
4517 if (zone->type == dns_zone_master && (inline_secure(zone) ||
4518 (zone->update_acl != NULL || zone->ssutable != NULL)))
4519 {
4520 options = DNS_JOURNALOPT_RESIGN;
4521 } else {
4522 options = 0;
4523 }
4524 result = dns_journal_rollforward(zone->mctx, db, options,
4525 zone->journal);
4526 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
4527 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
4528 result != ISC_R_RANGE)
4529 {
4530 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4531 ISC_LOG_ERROR,
4532 "journal rollforward failed: %s",
4533 dns_result_totext(result));
4534 goto cleanup;
4535
4536
4537 }
4538 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
4539 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4540 ISC_LOG_ERROR,
4541 "journal rollforward failed: "
4542 "journal out of sync with zone");
4543 goto cleanup;
4544 }
4545 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
4546 "journal rollforward completed "
4547 "successfully: %s",
4548 dns_result_totext(result));
4549 if (result == ISC_R_SUCCESS)
4550 needdump = true;
4551 }
4552
4553 /*
4554 * Obtain ns, soa and cname counts for top of zone.
4555 */
4556 INSIST(db != NULL);
4557 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
4558 &refresh, &retry, &expire, &minimum,
4559 &errors);
4560 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
4561 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
4562 "could not find NS and/or SOA records");
4563 }
4564
4565 /*
4566 * Check to make sure the journal is up to date, and remove the
4567 * journal file if it isn't, as we wouldn't be able to apply
4568 * updates otherwise.
4569 */
4570 if (zone->journal != NULL && dns_zone_isdynamic(zone, true) &&
4571 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
4572 uint32_t jserial;
4573 dns_journal_t *journal = NULL;
4574 bool empty = false;
4575
4576 result = dns_journal_open(zone->mctx, zone->journal,
4577 DNS_JOURNAL_READ, &journal);
4578 if (result == ISC_R_SUCCESS) {
4579 jserial = dns_journal_last_serial(journal);
4580 empty = dns_journal_empty(journal);
4581 dns_journal_destroy(&journal);
4582 } else {
4583 jserial = serial;
4584 result = ISC_R_SUCCESS;
4585 }
4586
4587 if (jserial != serial) {
4588 if (!empty)
4589 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4590 ISC_LOG_INFO,
4591 "journal file is out of date: "
4592 "removing journal file");
4593 if (remove(zone->journal) < 0 && errno != ENOENT) {
4594 char strbuf[ISC_STRERRORSIZE];
4595 strerror_r(errno, strbuf, sizeof(strbuf));
4596 isc_log_write(dns_lctx,
4597 DNS_LOGCATEGORY_GENERAL,
4598 DNS_LOGMODULE_ZONE,
4599 ISC_LOG_WARNING,
4600 "unable to remove journal "
4601 "'%s': '%s'",
4602 zone->journal, strbuf);
4603 }
4604 }
4605 }
4606
4607 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
4608 "loaded; checking validity");
4609
4610 /*
4611 * Master / Slave / Mirror / Stub zones require both NS and SOA records
4612 * at the top of the zone.
4613 */
4614
4615 switch (zone->type) {
4616 case dns_zone_dlz:
4617 case dns_zone_master:
4618 case dns_zone_slave:
4619 case dns_zone_mirror:
4620 case dns_zone_stub:
4621 case dns_zone_redirect:
4622 if (soacount != 1) {
4623 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4624 ISC_LOG_ERROR,
4625 "has %d SOA records", soacount);
4626 result = DNS_R_BADZONE;
4627 }
4628 if (nscount == 0) {
4629 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4630 ISC_LOG_ERROR,
4631 "has no NS records");
4632 result = DNS_R_BADZONE;
4633 }
4634 if (result != ISC_R_SUCCESS)
4635 goto cleanup;
4636 if (zone->type == dns_zone_master && errors != 0) {
4637 result = DNS_R_BADZONE;
4638 goto cleanup;
4639 }
4640 if (zone->type != dns_zone_stub &&
4641 zone->type != dns_zone_redirect) {
4642 result = check_nsec3param(zone, db);
4643 if (result != ISC_R_SUCCESS)
4644 goto cleanup;
4645 }
4646 if (zone->type == dns_zone_master &&
4647 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
4648 !integrity_checks(zone, db)) {
4649 result = DNS_R_BADZONE;
4650 goto cleanup;
4651 }
4652 if (zone->type == dns_zone_master &&
4653 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
4654 !zone_check_dup(zone, db)) {
4655 result = DNS_R_BADZONE;
4656 goto cleanup;
4657 }
4658
4659 result = dns_zone_verifydb(zone, db, NULL);
4660 if (result != ISC_R_SUCCESS) {
4661 goto cleanup;
4662 }
4663
4664 if (zone->db != NULL) {
4665 unsigned int oldsoacount;
4666
4667 /*
4668 * This is checked in zone_replacedb() for slave zones
4669 * as they don't reload from disk.
4670 */
4671 result = zone_get_from_db(zone, zone->db, NULL,
4672 &oldsoacount, &oldserial,
4673 NULL, NULL, NULL, NULL,
4674 NULL);
4675 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4676 RUNTIME_CHECK(soacount > 0U);
4677 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
4678 !isc_serial_gt(serial, oldserial)) {
4679 uint32_t serialmin, serialmax;
4680
4681 INSIST(zone->type == dns_zone_master);
4682 INSIST(zone->raw == NULL);
4683
4684 if (serial == oldserial &&
4685 zone_unchanged(zone->db, db, zone->mctx)) {
4686 dns_zone_logc(zone,
4687 DNS_LOGCATEGORY_ZONELOAD,
4688 ISC_LOG_INFO,
4689 "ixfr-from-differences: "
4690 "unchanged");
4691 goto done;
4692 }
4693
4694 serialmin = (oldserial + 1) & 0xffffffffU;
4695 serialmax = (oldserial + 0x7fffffffU) &
4696 0xffffffffU;
4697 dns_zone_logc(zone,
4698 DNS_LOGCATEGORY_ZONELOAD,
4699 ISC_LOG_ERROR,
4700 "ixfr-from-differences: "
4701 "new serial (%u) out of range "
4702 "[%u - %u]", serial, serialmin,
4703 serialmax);
4704 result = DNS_R_BADZONE;
4705 goto cleanup;
4706 } else if (!isc_serial_ge(serial, oldserial))
4707 dns_zone_logc(zone,
4708 DNS_LOGCATEGORY_ZONELOAD,
4709 ISC_LOG_ERROR,
4710 "zone serial (%u/%u) has gone "
4711 "backwards", serial, oldserial);
4712 else if (serial == oldserial && !hasinclude &&
4713 strcmp(zone->db_argv[0], "_builtin") != 0)
4714 dns_zone_logc(zone,
4715 DNS_LOGCATEGORY_ZONELOAD,
4716 ISC_LOG_ERROR,
4717 "zone serial (%u) unchanged. "
4718 "zone may fail to transfer "
4719 "to slaves.", serial);
4720 }
4721
4722 if (zone->type == dns_zone_master &&
4723 (zone->update_acl != NULL || zone->ssutable != NULL) &&
4724 zone->sigresigninginterval < (3 * refresh) &&
4725 dns_db_issecure(db))
4726 {
4727 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4728 ISC_LOG_WARNING,
4729 "sig-re-signing-interval less than "
4730 "3 * refresh.");
4731 }
4732
4733 zone->refresh = RANGE(refresh,
4734 zone->minrefresh, zone->maxrefresh);
4735 zone->retry = RANGE(retry,
4736 zone->minretry, zone->maxretry);
4737 zone->expire = RANGE(expire, zone->refresh + zone->retry,
4738 DNS_MAX_EXPIRE);
4739 zone->minimum = minimum;
4740 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
4741
4742 if (zone->type == dns_zone_slave ||
4743 zone->type == dns_zone_mirror ||
4744 zone->type == dns_zone_stub ||
4745 (zone->type == dns_zone_redirect &&
4746 zone->masters != NULL)) {
4747 isc_time_t t;
4748 uint32_t delay;
4749
4750 result = isc_file_getmodtime(zone->journal, &t);
4751 if (result != ISC_R_SUCCESS)
4752 result = isc_file_getmodtime(zone->masterfile,
4753 &t);
4754 if (result == ISC_R_SUCCESS)
4755 DNS_ZONE_TIME_ADD(&t, zone->expire,
4756 &zone->expiretime);
4757 else
4758 DNS_ZONE_TIME_ADD(&now, zone->retry,
4759 &zone->expiretime);
4760
4761 delay = zone->retry - isc_random_uniform((zone->retry * 3) / 4);
4762 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
4763 if (isc_time_compare(&zone->refreshtime,
4764 &zone->expiretime) >= 0)
4765 zone->refreshtime = now;
4766 }
4767
4768 break;
4769
4770 case dns_zone_key:
4771 result = sync_keyzone(zone, db);
4772 if (result != ISC_R_SUCCESS) {
4773 goto cleanup;
4774 }
4775 break;
4776
4777 default:
4778 UNEXPECTED_ERROR(__FILE__, __LINE__,
4779 "unexpected zone type %d", zone->type);
4780 result = ISC_R_UNEXPECTED;
4781 goto cleanup;
4782 }
4783
4784 /*
4785 * Check for weak DNSKEY's.
4786 */
4787 if (zone->type == dns_zone_master)
4788 zone_check_dnskeys(zone, db);
4789
4790 /*
4791 * Schedule DNSSEC key refresh.
4792 */
4793 if (zone->type == dns_zone_master &&
4794 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
4795 zone->refreshkeytime = now;
4796
4797 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
4798 if (zone->db != NULL) {
4799 result = zone_replacedb(zone, db, false);
4800 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4801 if (result != ISC_R_SUCCESS)
4802 goto cleanup;
4803 } else {
4804 zone_attachdb(zone, db);
4805 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4806 DNS_ZONE_SETFLAG(zone,
4807 DNS_ZONEFLG_LOADED|
4808 DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
4809 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
4810 inline_raw(zone))
4811 {
4812 if (zone->secure->db == NULL)
4813 zone_send_securedb(zone, db);
4814 else
4815 zone_send_secureserial(zone, serial);
4816 }
4817 }
4818
4819 /*
4820 * Finished loading inline-signing zone; need to get status
4821 * from the raw side now.
4822 */
4823 if (zone->type == dns_zone_master && inline_secure(zone))
4824 maybe_send_secure(zone);
4825
4826
4827 result = ISC_R_SUCCESS;
4828
4829 if (needdump) {
4830 if (zone->type == dns_zone_key)
4831 zone_needdump(zone, 30);
4832 else
4833 zone_needdump(zone, DNS_DUMP_DELAY);
4834 }
4835
4836 if (zone->task != NULL) {
4837 if (zone->type == dns_zone_master) {
4838 set_resigntime(zone);
4839 resume_signingwithkey(zone);
4840 resume_addnsec3chain(zone);
4841 }
4842
4843 if (zone->type == dns_zone_master &&
4844 !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
4845 dns_zone_isdynamic(zone, false) &&
4846 dns_db_issecure(db)) {
4847 dns_name_t *name;
4848 dns_fixedname_t fixed;
4849 dns_rdataset_t next;
4850
4851 dns_rdataset_init(&next);
4852 name = dns_fixedname_initname(&fixed);
4853
4854 result = dns_db_getsigningtime(db, &next, name);
4855 if (result == ISC_R_SUCCESS) {
4856 isc_stdtime_t timenow;
4857 char namebuf[DNS_NAME_FORMATSIZE];
4858 char typebuf[DNS_RDATATYPE_FORMATSIZE];
4859
4860 isc_stdtime_get(&timenow);
4861 dns_name_format(name, namebuf, sizeof(namebuf));
4862 dns_rdatatype_format(next.covers,
4863 typebuf, sizeof(typebuf));
4864 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4865 ISC_LOG_DEBUG(3),
4866 "next resign: %s/%s "
4867 "in %d seconds", namebuf, typebuf,
4868 next.resign - timenow -
4869 zone->sigresigninginterval);
4870 dns_rdataset_disassociate(&next);
4871 } else
4872 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4873 ISC_LOG_WARNING,
4874 "signed dynamic zone has no "
4875 "resign event scheduled");
4876 }
4877
4878 zone_settimer(zone, &now);
4879 }
4880
4881 /*
4882 * Clear old include list.
4883 */
4884 for (inc = ISC_LIST_HEAD(zone->includes);
4885 inc != NULL;
4886 inc = ISC_LIST_HEAD(zone->includes)) {
4887 ISC_LIST_UNLINK(zone->includes, inc, link);
4888 isc_mem_free(zone->mctx, inc->name);
4889 isc_mem_put(zone->mctx, inc, sizeof(*inc));
4890 }
4891 zone->nincludes = 0;
4892
4893 /*
4894 * Transfer new include list.
4895 */
4896 for (inc = ISC_LIST_HEAD(zone->newincludes);
4897 inc != NULL;
4898 inc = ISC_LIST_HEAD(zone->newincludes)) {
4899 ISC_LIST_UNLINK(zone->newincludes, inc, link);
4900 ISC_LIST_APPEND(zone->includes, inc, link);
4901 zone->nincludes++;
4902 }
4903
4904 if (! dns_db_ispersistent(db)) {
4905 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4906 ISC_LOG_INFO, "loaded serial %u%s", serial,
4907 dns_db_issecure(db) ? " (DNSSEC signed)" : "");
4908 }
4909
4910 zone->loadtime = loadtime;
4911 goto done;
4912
4913 cleanup:
4914 if (zone->type == dns_zone_key && result != ISC_R_SUCCESS) {
4915 dns_zone_log(zone, ISC_LOG_ERROR,
4916 "failed to initialize managed-keys (%s): "
4917 "DNSSEC validation is at risk",
4918 isc_result_totext(result));
4919 }
4920
4921 for (inc = ISC_LIST_HEAD(zone->newincludes);
4922 inc != NULL;
4923 inc = ISC_LIST_HEAD(zone->newincludes))
4924 {
4925 ISC_LIST_UNLINK(zone->newincludes, inc, link);
4926 isc_mem_free(zone->mctx, inc->name);
4927 isc_mem_put(zone->mctx, inc, sizeof(*inc));
4928 }
4929 if (zone->type == dns_zone_slave ||
4930 zone->type == dns_zone_mirror ||
4931 zone->type == dns_zone_stub ||
4932 zone->type == dns_zone_key ||
4933 (zone->type == dns_zone_redirect && zone->masters != NULL)) {
4934 if (result != ISC_R_NOMEMORY) {
4935 if (zone->journal != NULL)
4936 zone_saveunique(zone, zone->journal,
4937 "jn-XXXXXXXX");
4938 if (zone->masterfile != NULL)
4939 zone_saveunique(zone, zone->masterfile,
4940 "db-XXXXXXXX");
4941 }
4942
4943 /* Mark the zone for immediate refresh. */
4944 zone->refreshtime = now;
4945 if (zone->task != NULL)
4946 zone_settimer(zone, &now);
4947 result = ISC_R_SUCCESS;
4948 } else if (zone->type == dns_zone_master ||
4949 zone->type == dns_zone_redirect) {
4950 if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND))
4951 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4952 ISC_LOG_ERROR,
4953 "not loaded due to errors.");
4954 else if (zone->type == dns_zone_master)
4955 result = ISC_R_SUCCESS;
4956 }
4957
4958 done:
4959 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
4960 /*
4961 * If this is an inline-signed zone and we were called for the raw
4962 * zone, we need to clear DNS_ZONEFLG_LOADPENDING for the secure zone
4963 * as well, but only if this is a reload, not an initial zone load: in
4964 * the former case, zone_postload() will not be run for the secure
4965 * zone; in the latter case, it will be. Check which case we are
4966 * dealing with by consulting the DNS_ZONEFLG_LOADED flag for the
4967 * secure zone: if it is set, this must be a reload.
4968 */
4969 if (inline_raw(zone) &&
4970 DNS_ZONE_FLAG(zone->secure, DNS_ZONEFLG_LOADED))
4971 {
4972 DNS_ZONE_CLRFLAG(zone->secure, DNS_ZONEFLG_LOADPENDING);
4973 }
4974
4975 return (result);
4976 }
4977
4978 static bool
4979 exit_check(dns_zone_t *zone) {
4980 REQUIRE(LOCKED_ZONE(zone));
4981
4982 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->irefs == 0) {
4983 /*
4984 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
4985 */
4986 INSIST(isc_refcount_current(&zone->erefs) == 0);
4987 return (true);
4988 }
4989 return (false);
4990 }
4991
4992 static bool
4993 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
4994 dns_name_t *name, bool logit)
4995 {
4996 isc_result_t result;
4997 char namebuf[DNS_NAME_FORMATSIZE];
4998 char altbuf[DNS_NAME_FORMATSIZE];
4999 dns_fixedname_t fixed;
5000 dns_name_t *foundname;
5001 int level;
5002
5003 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
5004 return (true);
5005
5006 if (zone->type == dns_zone_master)
5007 level = ISC_LOG_ERROR;
5008 else
5009 level = ISC_LOG_WARNING;
5010
5011 foundname = dns_fixedname_initname(&fixed);
5012
5013 result = dns_db_find(db, name, version, dns_rdatatype_a,
5014 0, 0, NULL, foundname, NULL, NULL);
5015 if (result == ISC_R_SUCCESS)
5016 return (true);
5017
5018 if (result == DNS_R_NXRRSET) {
5019 result = dns_db_find(db, name, version, dns_rdatatype_aaaa,
5020 0, 0, NULL, foundname, NULL, NULL);
5021 if (result == ISC_R_SUCCESS)
5022 return (true);
5023 }
5024
5025 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
5026 result == DNS_R_EMPTYNAME) {
5027 if (logit) {
5028 dns_name_format(name, namebuf, sizeof namebuf);
5029 dns_zone_log(zone, level, "NS '%s' has no address "
5030 "records (A or AAAA)", namebuf);
5031 }
5032 return (false);
5033 }
5034
5035 if (result == DNS_R_CNAME) {
5036 if (logit) {
5037 dns_name_format(name, namebuf, sizeof namebuf);
5038 dns_zone_log(zone, level, "NS '%s' is a CNAME "
5039 "(illegal)", namebuf);
5040 }
5041 return (false);
5042 }
5043
5044 if (result == DNS_R_DNAME) {
5045 if (logit) {
5046 dns_name_format(name, namebuf, sizeof namebuf);
5047 dns_name_format(foundname, altbuf, sizeof altbuf);
5048 dns_zone_log(zone, level, "NS '%s' is below a DNAME "
5049 "'%s' (illegal)", namebuf, altbuf);
5050 }
5051 return (false);
5052 }
5053
5054 return (true);
5055 }
5056
5057 static isc_result_t
5058 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
5059 dns_dbversion_t *version, unsigned int *nscount,
5060 unsigned int *errors, bool logit)
5061 {
5062 isc_result_t result;
5063 unsigned int count = 0;
5064 unsigned int ecount = 0;
5065 dns_rdataset_t rdataset;
5066 dns_rdata_t rdata;
5067 dns_rdata_ns_t ns;
5068
5069 dns_rdataset_init(&rdataset);
5070 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
5071 dns_rdatatype_none, 0, &rdataset, NULL);
5072 if (result == ISC_R_NOTFOUND) {
5073 INSIST(!dns_rdataset_isassociated(&rdataset));
5074 goto success;
5075 }
5076 if (result != ISC_R_SUCCESS) {
5077 INSIST(!dns_rdataset_isassociated(&rdataset));
5078 goto invalidate_rdataset;
5079 }
5080
5081 result = dns_rdataset_first(&rdataset);
5082 while (result == ISC_R_SUCCESS) {
5083 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
5084 (zone->type == dns_zone_master ||
5085 zone->type == dns_zone_slave ||
5086 zone->type == dns_zone_mirror))
5087 {
5088 dns_rdata_init(&rdata);
5089 dns_rdataset_current(&rdataset, &rdata);
5090 result = dns_rdata_tostruct(&rdata, &ns, NULL);
5091 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5092 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
5093 !zone_check_ns(zone, db, version, &ns.name, logit))
5094 ecount++;
5095 }
5096 count++;
5097 result = dns_rdataset_next(&rdataset);
5098 }
5099 dns_rdataset_disassociate(&rdataset);
5100
5101 success:
5102 if (nscount != NULL)
5103 *nscount = count;
5104 if (errors != NULL)
5105 *errors = ecount;
5106
5107 result = ISC_R_SUCCESS;
5108
5109 invalidate_rdataset:
5110 dns_rdataset_invalidate(&rdataset);
5111
5112 return (result);
5113 }
5114
5115 static isc_result_t
5116 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
5117 unsigned int *soacount,
5118 uint32_t *serial, uint32_t *refresh,
5119 uint32_t *retry, uint32_t *expire,
5120 uint32_t *minimum)
5121 {
5122 isc_result_t result;
5123 unsigned int count;
5124 dns_rdataset_t rdataset;
5125 dns_rdata_t rdata = DNS_RDATA_INIT;
5126 dns_rdata_soa_t soa;
5127
5128 dns_rdataset_init(&rdataset);
5129 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
5130 dns_rdatatype_none, 0, &rdataset, NULL);
5131 if (result == ISC_R_NOTFOUND) {
5132 INSIST(!dns_rdataset_isassociated(&rdataset));
5133 if (soacount != NULL)
5134 *soacount = 0;
5135 if (serial != NULL)
5136 *serial = 0;
5137 if (refresh != NULL)
5138 *refresh = 0;
5139 if (retry != NULL)
5140 *retry = 0;
5141 if (expire != NULL)
5142 *expire = 0;
5143 if (minimum != NULL)
5144 *minimum = 0;
5145 result = ISC_R_SUCCESS;
5146 goto invalidate_rdataset;
5147 }
5148 if (result != ISC_R_SUCCESS) {
5149 INSIST(!dns_rdataset_isassociated(&rdataset));
5150 goto invalidate_rdataset;
5151 }
5152
5153 count = 0;
5154 result = dns_rdataset_first(&rdataset);
5155 while (result == ISC_R_SUCCESS) {
5156 dns_rdata_init(&rdata);
5157 dns_rdataset_current(&rdataset, &rdata);
5158 count++;
5159 if (count == 1) {
5160 result = dns_rdata_tostruct(&rdata, &soa, NULL);
5161 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5162 }
5163
5164 result = dns_rdataset_next(&rdataset);
5165 dns_rdata_reset(&rdata);
5166 }
5167 dns_rdataset_disassociate(&rdataset);
5168
5169 if (soacount != NULL)
5170 *soacount = count;
5171
5172 if (count > 0) {
5173 if (serial != NULL)
5174 *serial = soa.serial;
5175 if (refresh != NULL)
5176 *refresh = soa.refresh;
5177 if (retry != NULL)
5178 *retry = soa.retry;
5179 if (expire != NULL)
5180 *expire = soa.expire;
5181 if (minimum != NULL)
5182 *minimum = soa.minimum;
5183 } else {
5184 if (soacount != NULL)
5185 *soacount = 0;
5186 if (serial != NULL)
5187 *serial = 0;
5188 if (refresh != NULL)
5189 *refresh = 0;
5190 if (retry != NULL)
5191 *retry = 0;
5192 if (expire != NULL)
5193 *expire = 0;
5194 if (minimum != NULL)
5195 *minimum = 0;
5196 }
5197
5198 result = ISC_R_SUCCESS;
5199
5200 invalidate_rdataset:
5201 dns_rdataset_invalidate(&rdataset);
5202
5203 return (result);
5204 }
5205
5206 /*
5207 * zone must be locked.
5208 */
5209 static isc_result_t
5210 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
5211 unsigned int *soacount, uint32_t *serial,
5212 uint32_t *refresh, uint32_t *retry,
5213 uint32_t *expire, uint32_t *minimum,
5214 unsigned int *errors)
5215 {
5216 isc_result_t result;
5217 isc_result_t answer = ISC_R_SUCCESS;
5218 dns_dbversion_t *version = NULL;
5219 dns_dbnode_t *node;
5220
5221 REQUIRE(db != NULL);
5222 REQUIRE(zone != NULL);
5223
5224 dns_db_currentversion(db, &version);
5225
5226 if (nscount != NULL)
5227 *nscount = 0;
5228 if (soacount != NULL)
5229 *soacount = 0;
5230 if (serial != NULL)
5231 *serial = 0;
5232 if (refresh != NULL)
5233 *refresh = 0;
5234 if (retry != NULL)
5235 *retry = 0;
5236 if (expire != NULL)
5237 *expire = 0;
5238 if (errors != NULL)
5239 *errors = 0;
5240
5241 node = NULL;
5242 result = dns_db_findnode(db, &zone->origin, false, &node);
5243 if (result != ISC_R_SUCCESS) {
5244 answer = result;
5245 goto closeversion;
5246 }
5247
5248 if (nscount != NULL || errors != NULL) {
5249 result = zone_count_ns_rr(zone, db, node, version,
5250 nscount, errors, true);
5251 if (result != ISC_R_SUCCESS)
5252 answer = result;
5253 }
5254
5255 if (soacount != NULL || serial != NULL || refresh != NULL
5256 || retry != NULL || expire != NULL || minimum != NULL) {
5257 result = zone_load_soa_rr(db, node, version, soacount,
5258 serial, refresh, retry, expire,
5259 minimum);
5260 if (result != ISC_R_SUCCESS)
5261 answer = result;
5262 }
5263
5264 dns_db_detachnode(db, &node);
5265 closeversion:
5266 dns_db_closeversion(db, &version, false);
5267
5268 return (answer);
5269 }
5270
5271 void
5272 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
5273 REQUIRE(DNS_ZONE_VALID(source));
5274 REQUIRE(target != NULL && *target == NULL);
5275 isc_refcount_increment(&source->erefs);
5276 *target = source;
5277 }
5278
5279 void
5280 dns_zone_detach(dns_zone_t **zonep) {
5281 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
5282 dns_zone_t *zone = *zonep;
5283 *zonep = NULL;
5284
5285 bool free_now = false;
5286 dns_zone_t *raw = NULL;
5287 dns_zone_t *secure = NULL;
5288 if (isc_refcount_decrement(&zone->erefs) == 1) {
5289 isc_refcount_destroy(&zone->erefs);
5290
5291 LOCK_ZONE(zone);
5292 INSIST(zone != zone->raw);
5293 /*
5294 * We just detached the last external reference.
5295 */
5296 if (zone->task != NULL) {
5297 /*
5298 * This zone is being managed. Post
5299 * its control event and let it clean
5300 * up synchronously in the context of
5301 * its task.
5302 */
5303 isc_event_t *ev = &zone->ctlevent;
5304 isc_task_send(zone->task, &ev);
5305 } else {
5306 /*
5307 * This zone is not being managed; it has
5308 * no task and can have no outstanding
5309 * events. Free it immediately.
5310 */
5311 /*
5312 * Unmanaged zones should not have non-null views;
5313 * we have no way of detaching from the view here
5314 * without causing deadlock because this code is called
5315 * with the view already locked.
5316 */
5317 INSIST(zone->view == NULL);
5318 free_now = true;
5319 raw = zone->raw;
5320 zone->raw = NULL;
5321 secure = zone->secure;
5322 zone->secure = NULL;
5323 }
5324 UNLOCK_ZONE(zone);
5325 }
5326 if (free_now) {
5327 if (raw != NULL) {
5328 dns_zone_detach(&raw);
5329 }
5330 if (secure != NULL) {
5331 dns_zone_idetach(&secure);
5332 }
5333 zone_free(zone);
5334 }
5335 }
5336
5337 void
5338 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
5339 REQUIRE(DNS_ZONE_VALID(source));
5340 REQUIRE(target != NULL && *target == NULL);
5341 LOCK_ZONE(source);
5342 zone_iattach(source, target);
5343 UNLOCK_ZONE(source);
5344 }
5345
5346 static void
5347 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
5348
5349 /*
5350 * 'source' locked by caller.
5351 */
5352 REQUIRE(LOCKED_ZONE(source));
5353 REQUIRE(DNS_ZONE_VALID(source));
5354 REQUIRE(target != NULL && *target == NULL);
5355 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
5356 source->irefs++;
5357 INSIST(source->irefs != 0);
5358 *target = source;
5359 }
5360
5361 static void
5362 zone_idetach(dns_zone_t **zonep) {
5363 dns_zone_t *zone;
5364
5365 /*
5366 * 'zone' locked by caller.
5367 */
5368 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
5369 zone = *zonep;
5370 REQUIRE(LOCKED_ZONE(*zonep));
5371 *zonep = NULL;
5372
5373 INSIST(zone->irefs > 0);
5374 zone->irefs--;
5375 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
5376 }
5377
5378 void
5379 dns_zone_idetach(dns_zone_t **zonep) {
5380 dns_zone_t *zone;
5381 bool free_needed;
5382
5383 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
5384 zone = *zonep;
5385 *zonep = NULL;
5386
5387 LOCK_ZONE(zone);
5388 INSIST(zone->irefs > 0);
5389 zone->irefs--;
5390 free_needed = exit_check(zone);
5391 UNLOCK_ZONE(zone);
5392 if (free_needed)
5393 zone_free(zone);
5394 }
5395
5396 isc_mem_t *
5397 dns_zone_getmctx(dns_zone_t *zone) {
5398 REQUIRE(DNS_ZONE_VALID(zone));
5399
5400 return (zone->mctx);
5401 }
5402
5403 dns_zonemgr_t *
5404 dns_zone_getmgr(dns_zone_t *zone) {
5405 REQUIRE(DNS_ZONE_VALID(zone));
5406
5407 return (zone->zmgr);
5408 }
5409
5410 void
5411 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, bool value) {
5412 REQUIRE(DNS_ZONE_VALID(zone));
5413
5414 LOCK_ZONE(zone);
5415 if (value)
5416 DNS_ZONE_SETFLAG(zone, flags);
5417 else
5418 DNS_ZONE_CLRFLAG(zone, flags);
5419 UNLOCK_ZONE(zone);
5420 }
5421
5422 void
5423 dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option,
5424 bool value)
5425 {
5426 REQUIRE(DNS_ZONE_VALID(zone));
5427
5428 LOCK_ZONE(zone);
5429 if (value)
5430 zone->options |= option;
5431 else
5432 zone->options &= ~option;
5433 UNLOCK_ZONE(zone);
5434 }
5435
5436 dns_zoneopt_t
5437 dns_zone_getoptions(dns_zone_t *zone) {
5438 REQUIRE(DNS_ZONE_VALID(zone));
5439
5440 return (zone->options);
5441 }
5442
5443 void
5444 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, bool value)
5445 {
5446 REQUIRE(DNS_ZONE_VALID(zone));
5447
5448 LOCK_ZONE(zone);
5449 if (value)
5450 zone->keyopts |= keyopt;
5451 else
5452 zone->keyopts &= ~keyopt;
5453 UNLOCK_ZONE(zone);
5454 }
5455
5456 unsigned int
5457 dns_zone_getkeyopts(dns_zone_t *zone) {
5458
5459 REQUIRE(DNS_ZONE_VALID(zone));
5460
5461 return (zone->keyopts);
5462 }
5463
5464 isc_result_t
5465 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
5466 REQUIRE(DNS_ZONE_VALID(zone));
5467
5468 LOCK_ZONE(zone);
5469 zone->xfrsource4 = *xfrsource;
5470 UNLOCK_ZONE(zone);
5471
5472 return (ISC_R_SUCCESS);
5473 }
5474
5475 isc_sockaddr_t *
5476 dns_zone_getxfrsource4(dns_zone_t *zone) {
5477 REQUIRE(DNS_ZONE_VALID(zone));
5478 return (&zone->xfrsource4);
5479 }
5480
5481 isc_result_t
5482 dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5483 REQUIRE(DNS_ZONE_VALID(zone));
5484
5485 LOCK_ZONE(zone);
5486 zone->xfrsource4dscp = dscp;
5487 UNLOCK_ZONE(zone);
5488
5489 return (ISC_R_SUCCESS);
5490 }
5491
5492 isc_dscp_t
5493 dns_zone_getxfrsource4dscp(dns_zone_t *zone) {
5494 REQUIRE(DNS_ZONE_VALID(zone));
5495 return (zone->xfrsource4dscp);
5496 }
5497
5498 isc_result_t
5499 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
5500 REQUIRE(DNS_ZONE_VALID(zone));
5501
5502 LOCK_ZONE(zone);
5503 zone->xfrsource6 = *xfrsource;
5504 UNLOCK_ZONE(zone);
5505
5506 return (ISC_R_SUCCESS);
5507 }
5508
5509 isc_sockaddr_t *
5510 dns_zone_getxfrsource6(dns_zone_t *zone) {
5511 REQUIRE(DNS_ZONE_VALID(zone));
5512 return (&zone->xfrsource6);
5513 }
5514
5515 isc_dscp_t
5516 dns_zone_getxfrsource6dscp(dns_zone_t *zone) {
5517 REQUIRE(DNS_ZONE_VALID(zone));
5518 return (zone->xfrsource6dscp);
5519 }
5520
5521 isc_result_t
5522 dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5523 REQUIRE(DNS_ZONE_VALID(zone));
5524
5525 LOCK_ZONE(zone);
5526 zone->xfrsource6dscp = dscp;
5527 UNLOCK_ZONE(zone);
5528
5529 return (ISC_R_SUCCESS);
5530 }
5531
5532 isc_result_t
5533 dns_zone_setaltxfrsource4(dns_zone_t *zone,
5534 const isc_sockaddr_t *altxfrsource)
5535 {
5536 REQUIRE(DNS_ZONE_VALID(zone));
5537
5538 LOCK_ZONE(zone);
5539 zone->altxfrsource4 = *altxfrsource;
5540 UNLOCK_ZONE(zone);
5541
5542 return (ISC_R_SUCCESS);
5543 }
5544
5545 isc_sockaddr_t *
5546 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
5547 REQUIRE(DNS_ZONE_VALID(zone));
5548 return (&zone->altxfrsource4);
5549 }
5550
5551 isc_result_t
5552 dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5553 REQUIRE(DNS_ZONE_VALID(zone));
5554
5555 LOCK_ZONE(zone);
5556 zone->altxfrsource4dscp = dscp;
5557 UNLOCK_ZONE(zone);
5558
5559 return (ISC_R_SUCCESS);
5560 }
5561
5562 isc_dscp_t
5563 dns_zone_getaltxfrsource4dscp(dns_zone_t *zone) {
5564 REQUIRE(DNS_ZONE_VALID(zone));
5565 return (zone->altxfrsource4dscp);
5566 }
5567
5568 isc_result_t
5569 dns_zone_setaltxfrsource6(dns_zone_t *zone,
5570 const isc_sockaddr_t *altxfrsource)
5571 {
5572 REQUIRE(DNS_ZONE_VALID(zone));
5573
5574 LOCK_ZONE(zone);
5575 zone->altxfrsource6 = *altxfrsource;
5576 UNLOCK_ZONE(zone);
5577
5578 return (ISC_R_SUCCESS);
5579 }
5580
5581 isc_sockaddr_t *
5582 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
5583 REQUIRE(DNS_ZONE_VALID(zone));
5584 return (&zone->altxfrsource6);
5585 }
5586
5587 isc_result_t
5588 dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5589 REQUIRE(DNS_ZONE_VALID(zone));
5590
5591 LOCK_ZONE(zone);
5592 zone->altxfrsource6dscp = dscp;
5593 UNLOCK_ZONE(zone);
5594
5595 return (ISC_R_SUCCESS);
5596 }
5597
5598 isc_dscp_t
5599 dns_zone_getaltxfrsource6dscp(dns_zone_t *zone) {
5600 REQUIRE(DNS_ZONE_VALID(zone));
5601 return (zone->altxfrsource6dscp);
5602 }
5603
5604 isc_result_t
5605 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
5606 REQUIRE(DNS_ZONE_VALID(zone));
5607
5608 LOCK_ZONE(zone);
5609 zone->notifysrc4 = *notifysrc;
5610 UNLOCK_ZONE(zone);
5611
5612 return (ISC_R_SUCCESS);
5613 }
5614
5615 isc_sockaddr_t *
5616 dns_zone_getnotifysrc4(dns_zone_t *zone) {
5617 REQUIRE(DNS_ZONE_VALID(zone));
5618 return (&zone->notifysrc4);
5619 }
5620
5621 isc_result_t
5622 dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5623 REQUIRE(DNS_ZONE_VALID(zone));
5624
5625 LOCK_ZONE(zone);
5626 zone->notifysrc4dscp = dscp;
5627 UNLOCK_ZONE(zone);
5628
5629 return (ISC_R_SUCCESS);
5630 }
5631
5632 isc_dscp_t
5633 dns_zone_getnotifysrc4dscp(dns_zone_t *zone) {
5634 REQUIRE(DNS_ZONE_VALID(zone));
5635 return (zone->notifysrc4dscp);
5636 }
5637
5638 isc_result_t
5639 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
5640 REQUIRE(DNS_ZONE_VALID(zone));
5641
5642 LOCK_ZONE(zone);
5643 zone->notifysrc6 = *notifysrc;
5644 UNLOCK_ZONE(zone);
5645
5646 return (ISC_R_SUCCESS);
5647 }
5648
5649 isc_sockaddr_t *
5650 dns_zone_getnotifysrc6(dns_zone_t *zone) {
5651 REQUIRE(DNS_ZONE_VALID(zone));
5652 return (&zone->notifysrc6);
5653 }
5654
5655 static bool
5656 same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist,
5657 uint32_t count)
5658 {
5659 unsigned int i;
5660
5661 for (i = 0; i < count; i++)
5662 if (!isc_sockaddr_equal(&oldlist[i], &newlist[i]))
5663 return (false);
5664 return (true);
5665 }
5666
5667 static bool
5668 same_keynames(dns_name_t * const *oldlist, dns_name_t * const *newlist,
5669 uint32_t count)
5670 {
5671 unsigned int i;
5672
5673 if (oldlist == NULL && newlist == NULL)
5674 return (true);
5675 if (oldlist == NULL || newlist == NULL)
5676 return (false);
5677
5678 for (i = 0; i < count; i++) {
5679 if (oldlist[i] == NULL && newlist[i] == NULL)
5680 continue;
5681 if (oldlist[i] == NULL || newlist[i] == NULL ||
5682 !dns_name_equal(oldlist[i], newlist[i]))
5683 return (false);
5684 }
5685 return (true);
5686 }
5687
5688 static void
5689 clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
5690 dns_name_t ***keynamesp, unsigned int *countp,
5691 isc_mem_t *mctx)
5692 {
5693 unsigned int count;
5694 isc_sockaddr_t *addrs;
5695 isc_dscp_t *dscps;
5696 dns_name_t **keynames;
5697
5698 REQUIRE(countp != NULL && addrsp != NULL && dscpsp != NULL &&
5699 keynamesp != NULL);
5700
5701 count = *countp;
5702 *countp = 0;
5703 addrs = *addrsp;
5704 *addrsp = NULL;
5705 dscps = *dscpsp;
5706 *dscpsp = NULL;
5707 keynames = *keynamesp;
5708 *keynamesp = NULL;
5709
5710 if (addrs != NULL)
5711 isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
5712
5713 if (dscps != NULL)
5714 isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t));
5715
5716 if (keynames != NULL) {
5717 unsigned int i;
5718 for (i = 0; i < count; i++) {
5719 if (keynames[i] != NULL) {
5720 dns_name_free(keynames[i], mctx);
5721 isc_mem_put(mctx, keynames[i],
5722 sizeof(dns_name_t));
5723 keynames[i] = NULL;
5724 }
5725 }
5726 isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
5727 }
5728 }
5729
5730 static isc_result_t
5731 set_addrkeylist(unsigned int count,
5732 const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp,
5733 const isc_dscp_t *dscp, isc_dscp_t **newdscpp,
5734 dns_name_t **names, dns_name_t ***newnamesp,
5735 isc_mem_t *mctx)
5736 {
5737 isc_result_t result;
5738 isc_sockaddr_t *newaddrs = NULL;
5739 isc_dscp_t *newdscp = NULL;
5740 dns_name_t **newnames = NULL;
5741 unsigned int i;
5742
5743 REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
5744 REQUIRE(newdscpp != NULL && *newdscpp == NULL);
5745 REQUIRE(newnamesp != NULL && *newnamesp == NULL);
5746
5747 newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
5748 if (newaddrs == NULL)
5749 return (ISC_R_NOMEMORY);
5750 memmove(newaddrs, addrs, count * sizeof(*newaddrs));
5751
5752 if (dscp != NULL) {
5753 newdscp = isc_mem_get(mctx, count * sizeof(*newdscp));
5754 if (newdscp == NULL) {
5755 isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
5756 return (ISC_R_NOMEMORY);
5757 }
5758 memmove(newdscp, dscp, count * sizeof(*newdscp));
5759 } else
5760 newdscp = NULL;
5761
5762 if (names != NULL) {
5763 newnames = isc_mem_get(mctx, count * sizeof(*newnames));
5764 if (newnames == NULL) {
5765 if (newdscp != NULL)
5766 isc_mem_put(mctx, newdscp,
5767 count * sizeof(*newdscp));
5768 isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
5769 return (ISC_R_NOMEMORY);
5770 }
5771 for (i = 0; i < count; i++)
5772 newnames[i] = NULL;
5773 for (i = 0; i < count; i++) {
5774 if (names[i] != NULL) {
5775 newnames[i] = isc_mem_get(mctx,
5776 sizeof(dns_name_t));
5777 if (newnames[i] == NULL)
5778 goto allocfail;
5779 dns_name_init(newnames[i], NULL);
5780 result = dns_name_dup(names[i], mctx,
5781 newnames[i]);
5782 if (result != ISC_R_SUCCESS) {
5783 allocfail:
5784 for (i = 0; i < count; i++)
5785 if (newnames[i] != NULL)
5786 dns_name_free(
5787 newnames[i],
5788 mctx);
5789 isc_mem_put(mctx, newaddrs,
5790 count * sizeof(*newaddrs));
5791 isc_mem_put(mctx, newdscp,
5792 count * sizeof(*newdscp));
5793 isc_mem_put(mctx, newnames,
5794 count * sizeof(*newnames));
5795 return (ISC_R_NOMEMORY);
5796 }
5797 }
5798 }
5799 } else
5800 newnames = NULL;
5801
5802 *newdscpp = newdscp;
5803 *newaddrsp = newaddrs;
5804 *newnamesp = newnames;
5805 return (ISC_R_SUCCESS);
5806 }
5807
5808 isc_result_t
5809 dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5810 REQUIRE(DNS_ZONE_VALID(zone));
5811
5812 LOCK_ZONE(zone);
5813 zone->notifysrc6dscp = dscp;
5814 UNLOCK_ZONE(zone);
5815
5816 return (ISC_R_SUCCESS);
5817 }
5818
5819 isc_dscp_t
5820 dns_zone_getnotifysrc6dscp(dns_zone_t *zone) {
5821 REQUIRE(DNS_ZONE_VALID(zone));
5822 return (zone->notifysrc6dscp);
5823 }
5824
5825 isc_result_t
5826 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
5827 uint32_t count)
5828 {
5829 return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, NULL,
5830 count));
5831 }
5832
5833 isc_result_t
5834 dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
5835 dns_name_t **keynames, uint32_t count)
5836 {
5837 return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, keynames,
5838 count));
5839 }
5840
5841 isc_result_t
5842 dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
5843 const isc_dscp_t *dscps, dns_name_t **keynames,
5844 uint32_t count)
5845 {
5846 isc_result_t result;
5847 isc_sockaddr_t *newaddrs = NULL;
5848 isc_dscp_t *newdscps = NULL;
5849 dns_name_t **newnames = NULL;
5850
5851 REQUIRE(DNS_ZONE_VALID(zone));
5852 REQUIRE(count == 0 || notify != NULL);
5853 if (keynames != NULL)
5854 REQUIRE(count != 0);
5855
5856 LOCK_ZONE(zone);
5857
5858 if (count == zone->notifycnt &&
5859 same_addrs(zone->notify, notify, count) &&
5860 same_keynames(zone->notifykeynames, keynames, count))
5861 goto unlock;
5862
5863 clear_addresskeylist(&zone->notify, &zone->notifydscp,
5864 &zone->notifykeynames, &zone->notifycnt,
5865 zone->mctx);
5866
5867 if (count == 0)
5868 goto unlock;
5869
5870 /*
5871 * Set up the notify and notifykey lists
5872 */
5873 result = set_addrkeylist(count, notify, &newaddrs, dscps, &newdscps,
5874 keynames, &newnames, zone->mctx);
5875 if (result != ISC_R_SUCCESS)
5876 goto unlock;
5877
5878 /*
5879 * Everything is ok so attach to the zone.
5880 */
5881 zone->notify = newaddrs;
5882 zone->notifydscp = newdscps;
5883 zone->notifykeynames = newnames;
5884 zone->notifycnt = count;
5885 unlock:
5886 UNLOCK_ZONE(zone);
5887 return (ISC_R_SUCCESS);
5888 }
5889
5890 isc_result_t
5891 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
5892 uint32_t count)
5893 {
5894 isc_result_t result;
5895
5896 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
5897 return (result);
5898 }
5899
5900 isc_result_t
5901 dns_zone_setmasterswithkeys(dns_zone_t *zone,
5902 const isc_sockaddr_t *masters,
5903 dns_name_t **keynames,
5904 uint32_t count)
5905 {
5906 isc_result_t result = ISC_R_SUCCESS;
5907 isc_sockaddr_t *newaddrs = NULL;
5908 isc_dscp_t *newdscps = NULL;
5909 dns_name_t **newnames = NULL;
5910 bool *newok;
5911 unsigned int i;
5912
5913 REQUIRE(DNS_ZONE_VALID(zone));
5914 REQUIRE(count == 0 || masters != NULL);
5915 if (keynames != NULL) {
5916 REQUIRE(count != 0);
5917 }
5918
5919 LOCK_ZONE(zone);
5920 /*
5921 * The refresh code assumes that 'masters' wouldn't change under it.
5922 * If it will change then kill off any current refresh in progress
5923 * and update the masters info. If it won't change then we can just
5924 * unlock and exit.
5925 */
5926 if (count != zone->masterscnt ||
5927 !same_addrs(zone->masters, masters, count) ||
5928 !same_keynames(zone->masterkeynames, keynames, count)) {
5929 if (zone->request != NULL)
5930 dns_request_cancel(zone->request);
5931 } else
5932 goto unlock;
5933
5934 /*
5935 * This needs to happen before clear_addresskeylist() sets
5936 * zone->masterscnt to 0:
5937 */
5938 if (zone->mastersok != NULL) {
5939 isc_mem_put(zone->mctx, zone->mastersok,
5940 zone->masterscnt * sizeof(bool));
5941 zone->mastersok = NULL;
5942 }
5943 clear_addresskeylist(&zone->masters, &zone->masterdscps,
5944 &zone->masterkeynames, &zone->masterscnt,
5945 zone->mctx);
5946 /*
5947 * If count == 0, don't allocate any space for masters, mastersok or
5948 * keynames so internally, those pointers are NULL if count == 0
5949 */
5950 if (count == 0)
5951 goto unlock;
5952
5953 /*
5954 * mastersok must contain count elements
5955 */
5956 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
5957 if (newok == NULL) {
5958 result = ISC_R_NOMEMORY;
5959 isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs));
5960 goto unlock;
5961 };
5962 for (i = 0; i < count; i++)
5963 newok[i] = false;
5964
5965 /*
5966 * Now set up the masters and masterkey lists
5967 */
5968 result = set_addrkeylist(count, masters, &newaddrs, NULL, &newdscps,
5969 keynames, &newnames, zone->mctx);
5970 INSIST(newdscps == NULL);
5971 if (result != ISC_R_SUCCESS) {
5972 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
5973 goto unlock;
5974 }
5975
5976 /*
5977 * Everything is ok so attach to the zone.
5978 */
5979 zone->curmaster = 0;
5980 zone->mastersok = newok;
5981 zone->masters = newaddrs;
5982 zone->masterdscps = newdscps;
5983 zone->masterkeynames = newnames;
5984 zone->masterscnt = count;
5985 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
5986
5987 unlock:
5988 UNLOCK_ZONE(zone);
5989 return (result);
5990 }
5991
5992 isc_result_t
5993 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
5994 isc_result_t result = ISC_R_SUCCESS;
5995
5996 REQUIRE(DNS_ZONE_VALID(zone));
5997
5998 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5999 if (zone->db == NULL)
6000 result = DNS_R_NOTLOADED;
6001 else
6002 dns_db_attach(zone->db, dpb);
6003 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6004
6005 return (result);
6006 }
6007
6008 void
6009 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
6010 REQUIRE(DNS_ZONE_VALID(zone));
6011 REQUIRE(zone->type == dns_zone_staticstub);
6012
6013 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
6014 REQUIRE(zone->db == NULL);
6015 dns_db_attach(db, &zone->db);
6016 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
6017 }
6018
6019 /*
6020 * Co-ordinates the starting of routine jobs.
6021 */
6022 void
6023 dns_zone_maintenance(dns_zone_t *zone) {
6024 const char me[] = "dns_zone_maintenance";
6025 isc_time_t now;
6026
6027 REQUIRE(DNS_ZONE_VALID(zone));
6028 ENTER;
6029
6030 LOCK_ZONE(zone);
6031 TIME_NOW(&now);
6032 zone_settimer(zone, &now);
6033 UNLOCK_ZONE(zone);
6034 }
6035
6036 static inline bool
6037 was_dumping(dns_zone_t *zone) {
6038 bool dumping;
6039
6040 REQUIRE(LOCKED_ZONE(zone));
6041
6042 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
6043 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
6044 if (!dumping) {
6045 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6046 isc_time_settoepoch(&zone->dumptime);
6047 }
6048 return (dumping);
6049 }
6050
6051 /*%
6052 * Find up to 'maxkeys' DNSSEC keys used for signing version 'ver' of database
6053 * 'db' for zone 'zone' in its key directory, then load these keys into 'keys'.
6054 * Only load the public part of a given key if it is not active at timestamp
6055 * 'now'. Store the number of keys found in 'nkeys'.
6056 */
6057 isc_result_t
6058 dns__zone_findkeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
6059 isc_stdtime_t now, isc_mem_t *mctx, unsigned int maxkeys,
6060 dst_key_t **keys, unsigned int *nkeys)
6061 {
6062 isc_result_t result;
6063 dns_dbnode_t *node = NULL;
6064 const char *directory = dns_zone_getkeydirectory(zone);
6065
6066 CHECK(dns_db_findnode(db, dns_db_origin(db), false, &node));
6067 memset(keys, 0, sizeof(*keys) * maxkeys);
6068 result = dns_dnssec_findzonekeys(db, ver, node, dns_db_origin(db),
6069 directory, now, mctx, maxkeys, keys,
6070 nkeys);
6071 if (result == ISC_R_NOTFOUND)
6072 result = ISC_R_SUCCESS;
6073 failure:
6074 if (node != NULL)
6075 dns_db_detachnode(db, &node);
6076 return (result);
6077 }
6078
6079 static isc_result_t
6080 offline(dns_db_t *db, dns_dbversion_t *ver, dns__zonediff_t *zonediff,
6081 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
6082 {
6083 isc_result_t result;
6084
6085 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
6086 return (ISC_R_SUCCESS);
6087 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
6088 name, ttl, rdata);
6089 if (result != ISC_R_SUCCESS)
6090 return (result);
6091 rdata->flags |= DNS_RDATA_OFFLINE;
6092 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
6093 name, ttl, rdata);
6094 zonediff->offline = true;
6095 return (result);
6096 }
6097
6098 static void
6099 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
6100 {
6101 unsigned int delta;
6102 char timebuf[80];
6103
6104 zone->key_expiry = when;
6105 if (when <= now) {
6106 dns_zone_log(zone, ISC_LOG_ERROR,
6107 "DNSKEY RRSIG(s) have expired");
6108 isc_time_settoepoch(&zone->keywarntime);
6109 } else if (when < now + 7 * 24 * 3600) {
6110 isc_time_t t;
6111 isc_time_set(&t, when, 0);
6112 isc_time_formattimestamp(&t, timebuf, 80);
6113 dns_zone_log(zone, ISC_LOG_WARNING,
6114 "DNSKEY RRSIG(s) will expire within 7 days: %s",
6115 timebuf);
6116 delta = when - now;
6117 delta--; /* loop prevention */
6118 delta /= 24 * 3600; /* to whole days */
6119 delta *= 24 * 3600; /* to seconds */
6120 isc_time_set(&zone->keywarntime, when - delta, 0);
6121 } else {
6122 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
6123 isc_time_formattimestamp(&zone->keywarntime, timebuf, 80);
6124 dns_zone_log(zone, ISC_LOG_NOTICE,
6125 "setting keywarntime to %s", timebuf);
6126 }
6127 }
6128
6129 /*
6130 * Helper function to del_sigs(). We don't want to delete RRSIGs that
6131 * have no new key.
6132 */
6133 static bool
6134 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
6135 bool *warn)
6136 {
6137 unsigned int i = 0;
6138 bool have_ksk = false, have_zsk = false;
6139 bool have_pksk = false, have_pzsk = false;
6140
6141 for (i = 0; i < nkeys; i++) {
6142 if (rrsig_ptr->algorithm != dst_key_alg(keys[i]))
6143 continue;
6144 if (dst_key_isprivate(keys[i])) {
6145 if (KSK(keys[i]))
6146 have_ksk = have_pksk = true;
6147 else
6148 have_zsk = have_pzsk = true;
6149 } else {
6150 if (KSK(keys[i]))
6151 have_ksk = true;
6152 else
6153 have_zsk = true;
6154 }
6155 }
6156
6157 if (have_zsk && have_ksk && !have_pzsk)
6158 *warn = true;
6159
6160 /*
6161 * It's okay to delete a signature if there is an active key
6162 * with the same algorithm to replace it.
6163 */
6164 if (have_pksk || have_pzsk)
6165 return (true);
6166
6167 /*
6168 * Failing that, it is *not* okay to delete a signature
6169 * if the associated public key is still in the DNSKEY RRset
6170 */
6171 for (i = 0; i < nkeys; i++) {
6172 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
6173 (rrsig_ptr->keyid == dst_key_id(keys[i])))
6174 return (false);
6175 }
6176
6177 /*
6178 * But if the key is gone, then go ahead.
6179 */
6180 return (true);
6181 }
6182
6183 /*
6184 * Delete expired RRsigs and any RRsigs we are about to re-sign.
6185 * See also update.c:del_keysigs().
6186 */
6187 static isc_result_t
6188 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
6189 dns_rdatatype_t type, dns__zonediff_t *zonediff, dst_key_t **keys,
6190 unsigned int nkeys, isc_stdtime_t now, bool incremental)
6191 {
6192 isc_result_t result;
6193 dns_dbnode_t *node = NULL;
6194 dns_rdataset_t rdataset;
6195 unsigned int i;
6196 dns_rdata_rrsig_t rrsig;
6197 bool found;
6198 int64_t timewarn = 0, timemaybe = 0;
6199
6200 dns_rdataset_init(&rdataset);
6201
6202 if (type == dns_rdatatype_nsec3)
6203 result = dns_db_findnsec3node(db, name, false, &node);
6204 else
6205 result = dns_db_findnode(db, name, false, &node);
6206 if (result == ISC_R_NOTFOUND)
6207 return (ISC_R_SUCCESS);
6208 if (result != ISC_R_SUCCESS)
6209 goto failure;
6210 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
6211 (isc_stdtime_t) 0, &rdataset, NULL);
6212 dns_db_detachnode(db, &node);
6213
6214 if (result == ISC_R_NOTFOUND) {
6215 INSIST(!dns_rdataset_isassociated(&rdataset));
6216 return (ISC_R_SUCCESS);
6217 }
6218 if (result != ISC_R_SUCCESS) {
6219 INSIST(!dns_rdataset_isassociated(&rdataset));
6220 goto failure;
6221 }
6222
6223 for (result = dns_rdataset_first(&rdataset);
6224 result == ISC_R_SUCCESS;
6225 result = dns_rdataset_next(&rdataset)) {
6226 dns_rdata_t rdata = DNS_RDATA_INIT;
6227
6228 dns_rdataset_current(&rdataset, &rdata);
6229 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
6230 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6231
6232 if (type != dns_rdatatype_dnskey) {
6233 bool warn = false, deleted = false;
6234 if (delsig_ok(&rrsig, keys, nkeys, &warn)) {
6235 result = update_one_rr(db, ver, zonediff->diff,
6236 DNS_DIFFOP_DELRESIGN, name,
6237 rdataset.ttl, &rdata);
6238 if (result != ISC_R_SUCCESS)
6239 break;
6240 deleted = true;
6241 }
6242 if (warn) {
6243 /*
6244 * At this point, we've got an RRSIG,
6245 * which is signed by an inactive key.
6246 * An administrator needs to provide a new
6247 * key/alg, but until that time, we want to
6248 * keep the old RRSIG. Marking the key as
6249 * offline will prevent us spinning waiting
6250 * for the private part.
6251 */
6252 if (incremental && !deleted) {
6253 result = offline(db, ver, zonediff,
6254 name, rdataset.ttl,
6255 &rdata);
6256 if (result != ISC_R_SUCCESS)
6257 break;
6258 }
6259
6260 /*
6261 * Log the key id and algorithm of
6262 * the inactive key with no replacement
6263 */
6264 if (zone->log_key_expired_timer <= now) {
6265 char origin[DNS_NAME_FORMATSIZE];
6266 char algbuf[DNS_NAME_FORMATSIZE];
6267 dns_name_format(&zone->origin, origin,
6268 sizeof(origin));
6269 dns_secalg_format(rrsig.algorithm,
6270 algbuf,
6271 sizeof(algbuf));
6272 dns_zone_log(zone, ISC_LOG_WARNING,
6273 "Key %s/%s/%d "
6274 "missing or inactive "
6275 "and has no replacement: "
6276 "retaining signatures.",
6277 origin, algbuf,
6278 rrsig.keyid);
6279 zone->log_key_expired_timer = now +
6280 3600;
6281 }
6282 }
6283 continue;
6284 }
6285
6286 /*
6287 * RRSIG(DNSKEY) requires special processing.
6288 */
6289 found = false;
6290 for (i = 0; i < nkeys; i++) {
6291 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
6292 rrsig.keyid == dst_key_id(keys[i])) {
6293 found = true;
6294 /*
6295 * Mark offline RRSIG(DNSKEY).
6296 * We want the earliest offline expire time
6297 * iff there is a new offline signature.
6298 */
6299 if (!dst_key_inactive(keys[i]) &&
6300 !dst_key_isprivate(keys[i]))
6301 {
6302 int64_t timeexpire =
6303 dns_time64_from32(rrsig.timeexpire);
6304 if (timewarn != 0 &&
6305 timewarn > timeexpire)
6306 timewarn = timeexpire;
6307 if (rdata.flags & DNS_RDATA_OFFLINE) {
6308 if (timemaybe == 0 ||
6309 timemaybe > timeexpire)
6310 timemaybe = timeexpire;
6311 break;
6312 }
6313 if (timewarn == 0)
6314 timewarn = timemaybe;
6315 if (timewarn == 0 ||
6316 timewarn > timeexpire)
6317 timewarn = timeexpire;
6318 result = offline(db, ver, zonediff,
6319 name, rdataset.ttl,
6320 &rdata);
6321 break;
6322 }
6323 result = update_one_rr(db, ver, zonediff->diff,
6324 DNS_DIFFOP_DELRESIGN,
6325 name, rdataset.ttl,
6326 &rdata);
6327 break;
6328 }
6329 }
6330
6331 /*
6332 * If there is not a matching DNSKEY then
6333 * delete the RRSIG.
6334 */
6335 if (!found)
6336 result = update_one_rr(db, ver, zonediff->diff,
6337 DNS_DIFFOP_DELRESIGN, name,
6338 rdataset.ttl, &rdata);
6339 if (result != ISC_R_SUCCESS)
6340 break;
6341 }
6342
6343 dns_rdataset_disassociate(&rdataset);
6344 if (result == ISC_R_NOMORE)
6345 result = ISC_R_SUCCESS;
6346 if (timewarn > 0) {
6347 isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn;
6348 if (timewarn == stdwarn) {
6349 set_key_expiry_warning(zone, (isc_stdtime_t)timewarn,
6350 now);
6351 } else {
6352 dns_zone_log(zone, ISC_LOG_ERROR,
6353 "key expiry warning time out of range");
6354 }
6355 }
6356 failure:
6357 if (node != NULL)
6358 dns_db_detachnode(db, &node);
6359 return (result);
6360 }
6361
6362 static isc_result_t
6363 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
6364 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
6365 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
6366 isc_stdtime_t expire, bool check_ksk,
6367 bool keyset_kskonly)
6368 {
6369 isc_result_t result;
6370 dns_dbnode_t *node = NULL;
6371 dns_rdataset_t rdataset;
6372 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
6373 unsigned char data[1024]; /* XXX */
6374 isc_buffer_t buffer;
6375 unsigned int i, j;
6376
6377 dns_rdataset_init(&rdataset);
6378 isc_buffer_init(&buffer, data, sizeof(data));
6379
6380 if (type == dns_rdatatype_nsec3)
6381 result = dns_db_findnsec3node(db, name, false, &node);
6382 else
6383 result = dns_db_findnode(db, name, false, &node);
6384 if (result == ISC_R_NOTFOUND)
6385 return (ISC_R_SUCCESS);
6386 if (result != ISC_R_SUCCESS)
6387 goto failure;
6388 result = dns_db_findrdataset(db, node, ver, type, 0,
6389 (isc_stdtime_t) 0, &rdataset, NULL);
6390 dns_db_detachnode(db, &node);
6391 if (result == ISC_R_NOTFOUND) {
6392 INSIST(!dns_rdataset_isassociated(&rdataset));
6393 return (ISC_R_SUCCESS);
6394 }
6395 if (result != ISC_R_SUCCESS) {
6396 INSIST(!dns_rdataset_isassociated(&rdataset));
6397 goto failure;
6398 }
6399
6400 for (i = 0; i < nkeys; i++) {
6401 bool both = false;
6402
6403 if (!dst_key_isprivate(keys[i]))
6404 continue;
6405 if (dst_key_inactive(keys[i])) /* Should be redundant. */
6406 continue;
6407
6408 if (check_ksk && !REVOKE(keys[i])) {
6409 bool have_ksk, have_nonksk;
6410 if (KSK(keys[i])) {
6411 have_ksk = true;
6412 have_nonksk = false;
6413 } else {
6414 have_ksk = false;
6415 have_nonksk = true;
6416 }
6417 for (j = 0; j < nkeys; j++) {
6418 if (j == i || ALG(keys[i]) != ALG(keys[j]))
6419 continue;
6420 if (!dst_key_isprivate(keys[j]))
6421 continue;
6422 if (dst_key_inactive(keys[j])) /* SBR */
6423 continue;
6424 if (REVOKE(keys[j]))
6425 continue;
6426 if (KSK(keys[j]))
6427 have_ksk = true;
6428 else
6429 have_nonksk = true;
6430 both = have_ksk && have_nonksk;
6431 if (both)
6432 break;
6433 }
6434 }
6435 if (both) {
6436 /*
6437 * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1).
6438 */
6439 if (type == dns_rdatatype_dnskey ||
6440 type == dns_rdatatype_cdnskey ||
6441 type == dns_rdatatype_cds)
6442 {
6443 if (!KSK(keys[i]) && keyset_kskonly)
6444 continue;
6445 } else if (KSK(keys[i])) {
6446 continue;
6447 }
6448 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) {
6449 continue;
6450 }
6451
6452 /* Calculate the signature, creating a RRSIG RDATA. */
6453 isc_buffer_clear(&buffer);
6454 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
6455 &inception, &expire,
6456 mctx, &buffer, &sig_rdata));
6457 /* Update the database and journal with the RRSIG. */
6458 /* XXX inefficient - will cause dataset merging */
6459 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
6460 name, rdataset.ttl, &sig_rdata));
6461 dns_rdata_reset(&sig_rdata);
6462 isc_buffer_init(&buffer, data, sizeof(data));
6463 }
6464
6465 failure:
6466 if (dns_rdataset_isassociated(&rdataset))
6467 dns_rdataset_disassociate(&rdataset);
6468 if (node != NULL)
6469 dns_db_detachnode(db, &node);
6470 return (result);
6471 }
6472
6473 static void
6474 zone_resigninc(dns_zone_t *zone) {
6475 const char *me = "zone_resigninc";
6476 dns_db_t *db = NULL;
6477 dns_dbversion_t *version = NULL;
6478 dns_diff_t _sig_diff;
6479 dns__zonediff_t zonediff;
6480 dns_fixedname_t fixed;
6481 dns_name_t *name;
6482 dns_rdataset_t rdataset;
6483 dns_rdatatype_t covers;
6484 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
6485 bool check_ksk, keyset_kskonly = false;
6486 isc_result_t result;
6487 isc_stdtime_t now, inception, soaexpire, expire, stop;
6488 uint32_t jitter, sigvalidityinterval;
6489 unsigned int i;
6490 unsigned int nkeys = 0;
6491 unsigned int resign;
6492
6493 ENTER;
6494
6495 dns_rdataset_init(&rdataset);
6496 dns_diff_init(zone->mctx, &_sig_diff);
6497 zonediff_init(&zonediff, &_sig_diff);
6498
6499 /*
6500 * Zone is frozen or automatic resigning is disabled.
6501 * Pause for 5 minutes.
6502 */
6503 if (zone->update_disabled ||
6504 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN))
6505 {
6506 result = ISC_R_FAILURE;
6507 goto failure;
6508 }
6509
6510 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6511 dns_db_attach(zone->db, &db);
6512 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6513
6514 result = dns_db_newversion(db, &version);
6515 if (result != ISC_R_SUCCESS) {
6516 dns_zone_log(zone, ISC_LOG_ERROR,
6517 "zone_resigninc:dns_db_newversion -> %s",
6518 dns_result_totext(result));
6519 goto failure;
6520 }
6521
6522 isc_stdtime_get(&now);
6523
6524 result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
6525 DNS_MAXZONEKEYS, zone_keys, &nkeys);
6526 if (result != ISC_R_SUCCESS) {
6527 dns_zone_log(zone, ISC_LOG_ERROR,
6528 "zone_resigninc:dns__zone_findkeys -> %s",
6529 dns_result_totext(result));
6530 goto failure;
6531 }
6532
6533 sigvalidityinterval = zone->sigvalidityinterval;
6534 inception = now - 3600; /* Allow for clock skew. */
6535 soaexpire = now + sigvalidityinterval;
6536 /*
6537 * Spread out signatures over time if they happen to be
6538 * clumped. We don't do this for each add_sigs() call as
6539 * we still want some clustering to occur.
6540 */
6541 if (sigvalidityinterval >= 3600U) {
6542 if (sigvalidityinterval > 7200U) {
6543 jitter = isc_random_uniform(3600);
6544 } else {
6545 jitter = isc_random_uniform(1200);
6546 }
6547 expire = soaexpire - jitter - 1;
6548 } else {
6549 expire = soaexpire - 1;
6550 }
6551 stop = now + 5;
6552
6553 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
6554 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
6555
6556 name = dns_fixedname_initname(&fixed);
6557 result = dns_db_getsigningtime(db, &rdataset, name);
6558 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
6559 dns_zone_log(zone, ISC_LOG_ERROR,
6560 "zone_resigninc:dns_db_getsigningtime -> %s",
6561 dns_result_totext(result));
6562 }
6563
6564 i = 0;
6565 while (result == ISC_R_SUCCESS) {
6566 resign = rdataset.resign - zone->sigresigninginterval;
6567 covers = rdataset.covers;
6568 dns_rdataset_disassociate(&rdataset);
6569
6570 /*
6571 * Stop if we hit the SOA as that means we have walked the
6572 * entire zone. The SOA record should always be the most
6573 * recent signature.
6574 */
6575 /* XXXMPA increase number of RRsets signed pre call */
6576 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
6577 resign > stop)
6578 break;
6579
6580 result = del_sigs(zone, db, version, name, covers, &zonediff,
6581 zone_keys, nkeys, now, true);
6582 if (result != ISC_R_SUCCESS) {
6583 dns_zone_log(zone, ISC_LOG_ERROR,
6584 "zone_resigninc:del_sigs -> %s",
6585 dns_result_totext(result));
6586 break;
6587 }
6588
6589 result = add_sigs(db, version, name, covers, zonediff.diff,
6590 zone_keys, nkeys, zone->mctx, inception,
6591 expire, check_ksk, keyset_kskonly);
6592 if (result != ISC_R_SUCCESS) {
6593 dns_zone_log(zone, ISC_LOG_ERROR,
6594 "zone_resigninc:add_sigs -> %s",
6595 dns_result_totext(result));
6596 break;
6597 }
6598 result = dns_db_getsigningtime(db, &rdataset, name);
6599 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
6600 result = ISC_R_SUCCESS;
6601 break;
6602 }
6603 if (result != ISC_R_SUCCESS)
6604 dns_zone_log(zone, ISC_LOG_ERROR,
6605 "zone_resigninc:dns_db_getsigningtime -> %s",
6606 dns_result_totext(result));
6607 }
6608
6609 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
6610 goto failure;
6611
6612 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
6613 &zonediff, zone_keys, nkeys, now, true);
6614 if (result != ISC_R_SUCCESS) {
6615 dns_zone_log(zone, ISC_LOG_ERROR,
6616 "zone_resigninc:del_sigs -> %s",
6617 dns_result_totext(result));
6618 goto failure;
6619 }
6620
6621 /*
6622 * Did we change anything in the zone?
6623 */
6624 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
6625 /*
6626 * Commit the changes if any key has been marked as offline.
6627 */
6628 if (zonediff.offline)
6629 dns_db_closeversion(db, &version, true);
6630 goto failure;
6631 }
6632
6633 /* Increment SOA serial if we have made changes */
6634 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
6635 zone->updatemethod);
6636 if (result != ISC_R_SUCCESS) {
6637 dns_zone_log(zone, ISC_LOG_ERROR,
6638 "zone_resigninc:update_soa_serial -> %s",
6639 dns_result_totext(result));
6640 goto failure;
6641 }
6642
6643 /*
6644 * Generate maximum life time signatures so that the above loop
6645 * termination is sensible.
6646 */
6647 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
6648 zonediff.diff, zone_keys, nkeys, zone->mctx,
6649 inception, soaexpire, check_ksk, keyset_kskonly);
6650 if (result != ISC_R_SUCCESS) {
6651 dns_zone_log(zone, ISC_LOG_ERROR,
6652 "zone_resigninc:add_sigs -> %s",
6653 dns_result_totext(result));
6654 goto failure;
6655 }
6656
6657 /* Write changes to journal file. */
6658 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc"));
6659
6660 /* Everything has succeeded. Commit the changes. */
6661 dns_db_closeversion(db, &version, true);
6662
6663 failure:
6664 dns_diff_clear(&_sig_diff);
6665 for (i = 0; i < nkeys; i++)
6666 dst_key_free(&zone_keys[i]);
6667 if (version != NULL) {
6668 dns_db_closeversion(db, &version, false);
6669 dns_db_detach(&db);
6670 } else if (db != NULL)
6671 dns_db_detach(&db);
6672 if (result == ISC_R_SUCCESS) {
6673 set_resigntime(zone);
6674 LOCK_ZONE(zone);
6675 zone_needdump(zone, DNS_DUMP_DELAY);
6676 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6677 UNLOCK_ZONE(zone);
6678 } else {
6679 /*
6680 * Something failed. Retry in 5 minutes.
6681 */
6682 isc_interval_t ival;
6683 isc_interval_set(&ival, 300, 0);
6684 isc_time_nowplusinterval(&zone->resigntime, &ival);
6685 }
6686
6687 INSIST(version == NULL);
6688 }
6689
6690 static isc_result_t
6691 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
6692 dns_name_t *newname, bool bottom)
6693 {
6694 isc_result_t result;
6695 dns_dbiterator_t *dbit = NULL;
6696 dns_rdatasetiter_t *rdsit = NULL;
6697 dns_dbnode_t *node = NULL;
6698
6699 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
6700 CHECK(dns_dbiterator_seek(dbit, oldname));
6701 do {
6702 result = dns_dbiterator_next(dbit);
6703 if (result == ISC_R_NOMORE)
6704 CHECK(dns_dbiterator_first(dbit));
6705 CHECK(dns_dbiterator_current(dbit, &node, newname));
6706 if (bottom && dns_name_issubdomain(newname, oldname) &&
6707 !dns_name_equal(newname, oldname)) {
6708 dns_db_detachnode(db, &node);
6709 continue;
6710 }
6711 /*
6712 * Is this node empty?
6713 */
6714 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
6715 result = dns_rdatasetiter_first(rdsit);
6716 dns_db_detachnode(db, &node);
6717 dns_rdatasetiter_destroy(&rdsit);
6718 if (result != ISC_R_NOMORE)
6719 break;
6720 } while (1);
6721 failure:
6722 if (node != NULL)
6723 dns_db_detachnode(db, &node);
6724 if (dbit != NULL)
6725 dns_dbiterator_destroy(&dbit);
6726 return (result);
6727 }
6728
6729 static bool
6730 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
6731 dns_rdatatype_t type, dst_key_t *key)
6732 {
6733 isc_result_t result;
6734 dns_rdataset_t rdataset;
6735 dns_rdata_t rdata = DNS_RDATA_INIT;
6736 dns_rdata_rrsig_t rrsig;
6737
6738 dns_rdataset_init(&rdataset);
6739 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
6740 type, 0, &rdataset, NULL);
6741 if (result != ISC_R_SUCCESS) {
6742 INSIST(!dns_rdataset_isassociated(&rdataset));
6743 return (false);
6744 }
6745 for (result = dns_rdataset_first(&rdataset);
6746 result == ISC_R_SUCCESS;
6747 result = dns_rdataset_next(&rdataset)) {
6748 dns_rdataset_current(&rdataset, &rdata);
6749 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
6750 INSIST(result == ISC_R_SUCCESS);
6751 if (rrsig.algorithm == dst_key_alg(key) &&
6752 rrsig.keyid == dst_key_id(key)) {
6753 dns_rdataset_disassociate(&rdataset);
6754 return (true);
6755 }
6756 dns_rdata_reset(&rdata);
6757 }
6758 dns_rdataset_disassociate(&rdataset);
6759 return (false);
6760 }
6761
6762 static isc_result_t
6763 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
6764 dns_dbnode_t *node, dns_ttl_t ttl, bool bottom,
6765 dns_diff_t *diff)
6766 {
6767 dns_fixedname_t fixed;
6768 dns_name_t *next;
6769 dns_rdata_t rdata = DNS_RDATA_INIT;
6770 isc_result_t result;
6771 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
6772
6773 next = dns_fixedname_initname(&fixed);
6774
6775 CHECK(next_active(db, version, name, next, bottom));
6776 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
6777 &rdata));
6778 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
6779 &rdata));
6780 failure:
6781 return (result);
6782 }
6783
6784 static isc_result_t
6785 check_if_bottom_of_zone(dns_db_t *db, dns_dbnode_t *node,
6786 dns_dbversion_t *version, bool *is_bottom_of_zone)
6787 {
6788 isc_result_t result;
6789 dns_rdatasetiter_t *iterator = NULL;
6790 dns_rdataset_t rdataset;
6791 bool seen_soa = false, seen_ns = false, seen_dname = false;
6792
6793 REQUIRE(is_bottom_of_zone != NULL);
6794
6795 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6796 if (result != ISC_R_SUCCESS) {
6797 if (result == ISC_R_NOTFOUND) {
6798 result = ISC_R_SUCCESS;
6799 }
6800 return (result);
6801 }
6802
6803 dns_rdataset_init(&rdataset);
6804 for (result = dns_rdatasetiter_first(iterator);
6805 result == ISC_R_SUCCESS;
6806 result = dns_rdatasetiter_next(iterator)) {
6807 dns_rdatasetiter_current(iterator, &rdataset);
6808 switch (rdataset.type) {
6809 case dns_rdatatype_soa:
6810 seen_soa = true;
6811 break;
6812 case dns_rdatatype_ns:
6813 seen_ns = true;
6814 break;
6815 case dns_rdatatype_dname:
6816 seen_dname = true;
6817 break;
6818 }
6819 dns_rdataset_disassociate(&rdataset);
6820 }
6821 if (result != ISC_R_NOMORE) {
6822 goto failure;
6823 }
6824 if ((seen_ns && !seen_soa) || seen_dname) {
6825 *is_bottom_of_zone = true;
6826 }
6827 result = ISC_R_SUCCESS;
6828
6829 failure:
6830 dns_rdatasetiter_destroy(&iterator);
6831
6832 return (result);
6833 }
6834
6835 static isc_result_t
6836 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
6837 dns_dbversion_t *version, bool build_nsec3,
6838 bool build_nsec, dst_key_t *key,
6839 isc_stdtime_t inception, isc_stdtime_t expire,
6840 unsigned int minimum, bool is_ksk,
6841 bool keyset_kskonly, bool is_bottom_of_zone,
6842 dns_diff_t *diff, int32_t *signatures, isc_mem_t *mctx)
6843 {
6844 isc_result_t result;
6845 dns_rdatasetiter_t *iterator = NULL;
6846 dns_rdataset_t rdataset;
6847 dns_rdata_t rdata = DNS_RDATA_INIT;
6848 isc_buffer_t buffer;
6849 unsigned char data[1024];
6850 bool seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
6851 seen_nsec3, seen_ds;
6852
6853 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6854 if (result != ISC_R_SUCCESS) {
6855 if (result == ISC_R_NOTFOUND)
6856 result = ISC_R_SUCCESS;
6857 return (result);
6858 }
6859
6860 dns_rdataset_init(&rdataset);
6861 isc_buffer_init(&buffer, data, sizeof(data));
6862 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
6863 seen_nsec3 = seen_ds = false;
6864 for (result = dns_rdatasetiter_first(iterator);
6865 result == ISC_R_SUCCESS;
6866 result = dns_rdatasetiter_next(iterator)) {
6867 dns_rdatasetiter_current(iterator, &rdataset);
6868 if (rdataset.type == dns_rdatatype_soa)
6869 seen_soa = true;
6870 else if (rdataset.type == dns_rdatatype_ns)
6871 seen_ns = true;
6872 else if (rdataset.type == dns_rdatatype_ds)
6873 seen_ds = true;
6874 else if (rdataset.type == dns_rdatatype_dname)
6875 seen_dname = true;
6876 else if (rdataset.type == dns_rdatatype_nsec)
6877 seen_nsec = true;
6878 else if (rdataset.type == dns_rdatatype_nsec3)
6879 seen_nsec3 = true;
6880 if (rdataset.type != dns_rdatatype_rrsig)
6881 seen_rr = true;
6882 dns_rdataset_disassociate(&rdataset);
6883 }
6884 if (result != ISC_R_NOMORE)
6885 goto failure;
6886 /*
6887 * Going from insecure to NSEC3.
6888 * Don't generate NSEC3 records for NSEC3 records.
6889 */
6890 if (build_nsec3 && !seen_nsec3 && seen_rr) {
6891 bool unsecure = !seen_ds && seen_ns && !seen_soa;
6892 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
6893 unsecure, diff));
6894 (*signatures)--;
6895 }
6896 /*
6897 * Going from insecure to NSEC.
6898 * Don't generate NSEC records for NSEC3 records.
6899 */
6900 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
6901 /*
6902 * Build a NSEC record except at the origin.
6903 */
6904 if (!dns_name_equal(name, dns_db_origin(db))) {
6905 CHECK(add_nsec(db, version, name, node, minimum,
6906 is_bottom_of_zone, diff));
6907 /* Count a NSEC generation as a signature generation. */
6908 (*signatures)--;
6909 }
6910 }
6911 result = dns_rdatasetiter_first(iterator);
6912 while (result == ISC_R_SUCCESS) {
6913 dns_rdatasetiter_current(iterator, &rdataset);
6914 if (rdataset.type == dns_rdatatype_soa ||
6915 rdataset.type == dns_rdatatype_rrsig)
6916 {
6917 goto next_rdataset;
6918 }
6919 if (rdataset.type == dns_rdatatype_dnskey ||
6920 rdataset.type == dns_rdatatype_cdnskey ||
6921 rdataset.type == dns_rdatatype_cds)
6922 {
6923 /*
6924 * CDS and CDNSKEY are signed with KSK like DNSKEY.
6925 * (RFC 7344, section 4.1 specifies that they must
6926 * be signed with a key in the current DS RRset,
6927 * which would only include KSK's.)
6928 */
6929 if (!is_ksk && keyset_kskonly) {
6930 goto next_rdataset;
6931 }
6932 } else if (is_ksk) {
6933 goto next_rdataset;
6934 }
6935 if (seen_ns && !seen_soa &&
6936 rdataset.type != dns_rdatatype_ds &&
6937 rdataset.type != dns_rdatatype_nsec)
6938 {
6939 goto next_rdataset;
6940 }
6941 if (signed_with_key(db, node, version, rdataset.type, key)) {
6942 goto next_rdataset;
6943 }
6944 /* Calculate the signature, creating a RRSIG RDATA. */
6945 isc_buffer_clear(&buffer);
6946 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
6947 &expire, mctx, &buffer, &rdata));
6948 /* Update the database and journal with the RRSIG. */
6949 /* XXX inefficient - will cause dataset merging */
6950 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
6951 name, rdataset.ttl, &rdata));
6952 dns_rdata_reset(&rdata);
6953 (*signatures)--;
6954 next_rdataset:
6955 dns_rdataset_disassociate(&rdataset);
6956 result = dns_rdatasetiter_next(iterator);
6957 }
6958 if (result == ISC_R_NOMORE)
6959 result = ISC_R_SUCCESS;
6960 failure:
6961 if (dns_rdataset_isassociated(&rdataset))
6962 dns_rdataset_disassociate(&rdataset);
6963 if (iterator != NULL)
6964 dns_rdatasetiter_destroy(&iterator);
6965 return (result);
6966 }
6967
6968 /*
6969 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
6970 */
6971 static isc_result_t
6972 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
6973 dns_ttl_t minimum, bool update_only, dns_diff_t *diff)
6974 {
6975 isc_result_t result;
6976 dns_rdataset_t rdataset;
6977 dns_dbnode_t *node = NULL;
6978
6979 CHECK(dns_db_getoriginnode(db, &node));
6980 if (update_only) {
6981 dns_rdataset_init(&rdataset);
6982 result = dns_db_findrdataset(db, node, version,
6983 dns_rdatatype_nsec,
6984 dns_rdatatype_none,
6985 0, &rdataset, NULL);
6986 if (dns_rdataset_isassociated(&rdataset))
6987 dns_rdataset_disassociate(&rdataset);
6988 if (result == ISC_R_NOTFOUND)
6989 goto success;
6990 if (result != ISC_R_SUCCESS)
6991 goto failure;
6992 }
6993 CHECK(delete_nsec(db, version, node, name, diff));
6994 CHECK(add_nsec(db, version, name, node, minimum, false, diff));
6995 success:
6996 result = ISC_R_SUCCESS;
6997 failure:
6998 if (node != NULL)
6999 dns_db_detachnode(db, &node);
7000 return (result);
7001 }
7002
7003 static isc_result_t
7004 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
7005 dns_dbversion_t *version, bool build_nsec3,
7006 dns_ttl_t minimum, dns_diff_t *diff)
7007 {
7008 isc_result_t result;
7009 dns_dbnode_t *node = NULL;
7010 dns_rdataset_t rdataset;
7011 dns_rdata_t rdata = DNS_RDATA_INIT;
7012 unsigned char data[5];
7013 bool seen_done = false;
7014 bool have_rr = false;
7015
7016 dns_rdataset_init(&rdataset);
7017 result = dns_db_getoriginnode(signing->db, &node);
7018 if (result != ISC_R_SUCCESS)
7019 goto failure;
7020
7021 result = dns_db_findrdataset(signing->db, node, version,
7022 zone->privatetype, dns_rdatatype_none,
7023 0, &rdataset, NULL);
7024 if (result == ISC_R_NOTFOUND) {
7025 INSIST(!dns_rdataset_isassociated(&rdataset));
7026 result = ISC_R_SUCCESS;
7027 goto failure;
7028 }
7029 if (result != ISC_R_SUCCESS) {
7030 INSIST(!dns_rdataset_isassociated(&rdataset));
7031 goto failure;
7032 }
7033 for (result = dns_rdataset_first(&rdataset);
7034 result == ISC_R_SUCCESS;
7035 result = dns_rdataset_next(&rdataset)) {
7036 dns_rdataset_current(&rdataset, &rdata);
7037 /*
7038 * If we don't match the algorithm or keyid skip the record.
7039 */
7040 if (rdata.length != 5 ||
7041 rdata.data[0] != signing->algorithm ||
7042 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
7043 rdata.data[2] != (signing->keyid & 0xff)) {
7044 have_rr = true;
7045 dns_rdata_reset(&rdata);
7046 continue;
7047 }
7048 /*
7049 * We have a match. If we were signing (!signing->deleteit)
7050 * and we already have a record indicating that we have
7051 * finished signing (rdata.data[4] != 0) then keep it.
7052 * Otherwise it needs to be deleted as we have removed all
7053 * the signatures (signing->deleteit), so any record indicating
7054 * completion is now out of date, or we have finished signing
7055 * with the new record so we no longer need to remember that
7056 * we need to sign the zone with the matching key across a
7057 * nameserver re-start.
7058 */
7059 if (!signing->deleteit && rdata.data[4] != 0) {
7060 seen_done = true;
7061 have_rr = true;
7062 } else
7063 CHECK(update_one_rr(signing->db, version, diff,
7064 DNS_DIFFOP_DEL, &zone->origin,
7065 rdataset.ttl, &rdata));
7066 dns_rdata_reset(&rdata);
7067 }
7068 if (result == ISC_R_NOMORE)
7069 result = ISC_R_SUCCESS;
7070 if (!signing->deleteit && !seen_done) {
7071 /*
7072 * If we were signing then we need to indicate that we have
7073 * finished signing the zone with this key. If it is already
7074 * there we don't need to add it a second time.
7075 */
7076 data[0] = signing->algorithm;
7077 data[1] = (signing->keyid >> 8) & 0xff;
7078 data[2] = signing->keyid & 0xff;
7079 data[3] = 0;
7080 data[4] = 1;
7081 rdata.length = sizeof(data);
7082 rdata.data = data;
7083 rdata.type = zone->privatetype;
7084 rdata.rdclass = dns_db_class(signing->db);
7085 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
7086 &zone->origin, rdataset.ttl, &rdata));
7087 } else if (!have_rr) {
7088 dns_name_t *origin = dns_db_origin(signing->db);
7089 /*
7090 * Rebuild the NSEC/NSEC3 record for the origin as we no
7091 * longer have any private records.
7092 */
7093 if (build_nsec3)
7094 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
7095 minimum, false, diff));
7096 CHECK(updatesecure(signing->db, version, origin, minimum,
7097 true, diff));
7098 }
7099
7100 failure:
7101 if (dns_rdataset_isassociated(&rdataset))
7102 dns_rdataset_disassociate(&rdataset);
7103 if (node != NULL)
7104 dns_db_detachnode(signing->db, &node);
7105 return (result);
7106 }
7107
7108 /*
7109 * Called from zone_nsec3chain() in order to update zone records indicating
7110 * processing status of given NSEC3 chain:
7111 *
7112 * - If the supplied dns_nsec3chain_t structure has been fully processed
7113 * (which is indicated by "active" being set to false):
7114 *
7115 * - remove all NSEC3PARAM records matching the relevant NSEC3 chain,
7116 *
7117 * - remove all private-type records containing NSEC3PARAM RDATA matching
7118 * the relevant NSEC3 chain.
7119 *
7120 * - If the supplied dns_nsec3chain_t structure has not been fully processed
7121 * (which is indicated by "active" being set to true), only remove the
7122 * NSEC3PARAM record which matches the relevant NSEC3 chain and has the
7123 * "flags" field set to 0.
7124 *
7125 * - If given NSEC3 chain is being added, add an NSEC3PARAM record contained
7126 * in the relevant private-type record, but with the "flags" field set to
7127 * 0, indicating that this NSEC3 chain is now complete for this zone.
7128 *
7129 * Note that this function is called at different processing stages for NSEC3
7130 * chain additions vs. removals and needs to handle all cases properly.
7131 */
7132 static isc_result_t
7133 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
7134 bool active, dns_rdatatype_t privatetype,
7135 dns_diff_t *diff)
7136 {
7137 dns_dbnode_t *node = NULL;
7138 dns_name_t *name = dns_db_origin(db);
7139 dns_rdata_t rdata = DNS_RDATA_INIT;
7140 dns_rdataset_t rdataset;
7141 dns_rdata_nsec3param_t nsec3param;
7142 isc_result_t result;
7143 isc_buffer_t buffer;
7144 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
7145 dns_ttl_t ttl = 0;
7146 bool nseconly = false, nsec3ok = false;
7147
7148 dns_rdataset_init(&rdataset);
7149
7150 result = dns_db_getoriginnode(db, &node);
7151 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7152 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
7153 0, 0, &rdataset, NULL);
7154 if (result == ISC_R_NOTFOUND)
7155 goto try_private;
7156 if (result != ISC_R_SUCCESS)
7157 goto failure;
7158
7159 /*
7160 * Preserve the existing ttl.
7161 */
7162 ttl = rdataset.ttl;
7163
7164 /*
7165 * Delete all NSEC3PARAM records which match that in nsec3chain.
7166 */
7167 for (result = dns_rdataset_first(&rdataset);
7168 result == ISC_R_SUCCESS;
7169 result = dns_rdataset_next(&rdataset)) {
7170
7171 dns_rdataset_current(&rdataset, &rdata);
7172 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
7173
7174 if (nsec3param.hash != chain->nsec3param.hash ||
7175 (active && nsec3param.flags != 0) ||
7176 nsec3param.iterations != chain->nsec3param.iterations ||
7177 nsec3param.salt_length != chain->nsec3param.salt_length ||
7178 memcmp(nsec3param.salt, chain->nsec3param.salt,
7179 nsec3param.salt_length)) {
7180 dns_rdata_reset(&rdata);
7181 continue;
7182 }
7183
7184 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
7185 name, rdataset.ttl, &rdata));
7186 dns_rdata_reset(&rdata);
7187 }
7188 if (result != ISC_R_NOMORE)
7189 goto failure;
7190
7191 dns_rdataset_disassociate(&rdataset);
7192
7193 try_private:
7194
7195 if (active)
7196 goto add;
7197
7198 result = dns_nsec_nseconly(db, ver, &nseconly);
7199 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
7200
7201 /*
7202 * Delete all private records which match that in nsec3chain.
7203 */
7204 result = dns_db_findrdataset(db, node, ver, privatetype,
7205 0, 0, &rdataset, NULL);
7206 if (result == ISC_R_NOTFOUND)
7207 goto add;
7208 if (result != ISC_R_SUCCESS)
7209 goto failure;
7210
7211 for (result = dns_rdataset_first(&rdataset);
7212 result == ISC_R_SUCCESS;
7213 result = dns_rdataset_next(&rdataset)) {
7214 dns_rdata_t private = DNS_RDATA_INIT;
7215 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
7216
7217 dns_rdataset_current(&rdataset, &private);
7218 if (!dns_nsec3param_fromprivate(&private, &rdata,
7219 buf, sizeof(buf)))
7220 continue;
7221 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
7222
7223 if ((!nsec3ok &&
7224 (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) ||
7225 nsec3param.hash != chain->nsec3param.hash ||
7226 nsec3param.iterations != chain->nsec3param.iterations ||
7227 nsec3param.salt_length != chain->nsec3param.salt_length ||
7228 memcmp(nsec3param.salt, chain->nsec3param.salt,
7229 nsec3param.salt_length)) {
7230 dns_rdata_reset(&rdata);
7231 continue;
7232 }
7233
7234 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
7235 name, rdataset.ttl, &private));
7236 dns_rdata_reset(&rdata);
7237 }
7238 if (result != ISC_R_NOMORE)
7239 goto failure;
7240
7241 add:
7242 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
7243 result = ISC_R_SUCCESS;
7244 goto failure;
7245 }
7246
7247 /*
7248 * Add a NSEC3PARAM record which matches that in nsec3chain but
7249 * with all flags bits cleared.
7250 *
7251 * Note: we do not clear chain->nsec3param.flags as this change
7252 * may be reversed.
7253 */
7254 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
7255 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
7256 dns_rdatatype_nsec3param,
7257 &chain->nsec3param, &buffer));
7258 rdata.data[1] = 0; /* Clear flag bits. */
7259 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
7260
7261 failure:
7262 dns_db_detachnode(db, &node);
7263 if (dns_rdataset_isassociated(&rdataset))
7264 dns_rdataset_disassociate(&rdataset);
7265 return (result);
7266 }
7267
7268 static isc_result_t
7269 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
7270 dns_name_t *name, dns_diff_t *diff)
7271 {
7272 dns_rdataset_t rdataset;
7273 isc_result_t result;
7274
7275 dns_rdataset_init(&rdataset);
7276
7277 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
7278 0, 0, &rdataset, NULL);
7279 if (result == ISC_R_NOTFOUND)
7280 return (ISC_R_SUCCESS);
7281 if (result != ISC_R_SUCCESS)
7282 return (result);
7283 for (result = dns_rdataset_first(&rdataset);
7284 result == ISC_R_SUCCESS;
7285 result = dns_rdataset_next(&rdataset)) {
7286 dns_rdata_t rdata = DNS_RDATA_INIT;
7287
7288 dns_rdataset_current(&rdataset, &rdata);
7289 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
7290 rdataset.ttl, &rdata));
7291 }
7292 if (result == ISC_R_NOMORE)
7293 result = ISC_R_SUCCESS;
7294 failure:
7295 dns_rdataset_disassociate(&rdataset);
7296 return (result);
7297 }
7298
7299 static isc_result_t
7300 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
7301 dns_name_t *name, const dns_rdata_nsec3param_t *param,
7302 dns_diff_t *diff)
7303 {
7304 dns_rdataset_t rdataset;
7305 dns_rdata_nsec3_t nsec3;
7306 isc_result_t result;
7307
7308 dns_rdataset_init(&rdataset);
7309 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
7310 0, 0, &rdataset, NULL);
7311 if (result == ISC_R_NOTFOUND)
7312 return (ISC_R_SUCCESS);
7313 if (result != ISC_R_SUCCESS)
7314 return (result);
7315
7316 for (result = dns_rdataset_first(&rdataset);
7317 result == ISC_R_SUCCESS;
7318 result = dns_rdataset_next(&rdataset)) {
7319 dns_rdata_t rdata = DNS_RDATA_INIT;
7320
7321 dns_rdataset_current(&rdataset, &rdata);
7322 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
7323 if (nsec3.hash != param->hash ||
7324 nsec3.iterations != param->iterations ||
7325 nsec3.salt_length != param->salt_length ||
7326 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
7327 continue;
7328 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
7329 rdataset.ttl, &rdata));
7330 }
7331 if (result == ISC_R_NOMORE)
7332 result = ISC_R_SUCCESS;
7333 failure:
7334 dns_rdataset_disassociate(&rdataset);
7335 return (result);
7336 }
7337
7338 static isc_result_t
7339 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
7340 const dns_rdata_nsec3param_t *param,
7341 bool *answer)
7342 {
7343 dns_dbnode_t *node = NULL;
7344 dns_rdata_t rdata = DNS_RDATA_INIT;
7345 dns_rdata_nsec3param_t myparam;
7346 dns_rdataset_t rdataset;
7347 isc_result_t result;
7348
7349 *answer = false;
7350
7351 result = dns_db_getoriginnode(db, &node);
7352 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7353
7354 dns_rdataset_init(&rdataset);
7355
7356 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
7357 0, 0, &rdataset, NULL);
7358 if (result == ISC_R_SUCCESS) {
7359 dns_rdataset_disassociate(&rdataset);
7360 dns_db_detachnode(db, &node);
7361 return (result);
7362 }
7363 if (result != ISC_R_NOTFOUND) {
7364 dns_db_detachnode(db, &node);
7365 return (result);
7366 }
7367
7368 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
7369 0, 0, &rdataset, NULL);
7370 if (result == ISC_R_NOTFOUND) {
7371 *answer = true;
7372 dns_db_detachnode(db, &node);
7373 return (ISC_R_SUCCESS);
7374 }
7375 if (result != ISC_R_SUCCESS) {
7376 dns_db_detachnode(db, &node);
7377 return (result);
7378 }
7379
7380 for (result = dns_rdataset_first(&rdataset);
7381 result == ISC_R_SUCCESS;
7382 result = dns_rdataset_next(&rdataset)) {
7383 dns_rdataset_current(&rdataset, &rdata);
7384 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
7385 dns_rdata_reset(&rdata);
7386 /*
7387 * Ignore any NSEC3PARAM removals.
7388 */
7389 if (NSEC3REMOVE(myparam.flags))
7390 continue;
7391 /*
7392 * Ignore the chain that we are in the process of deleting.
7393 */
7394 if (myparam.hash == param->hash &&
7395 myparam.iterations == param->iterations &&
7396 myparam.salt_length == param->salt_length &&
7397 !memcmp(myparam.salt, param->salt, myparam.salt_length))
7398 continue;
7399 /*
7400 * Found an active NSEC3 chain.
7401 */
7402 break;
7403 }
7404 if (result == ISC_R_NOMORE) {
7405 *answer = true;
7406 result = ISC_R_SUCCESS;
7407 }
7408
7409 failure:
7410 if (dns_rdataset_isassociated(&rdataset))
7411 dns_rdataset_disassociate(&rdataset);
7412 dns_db_detachnode(db, &node);
7413 return (result);
7414 }
7415
7416 /*%
7417 * Given a tuple which is part of a diff, return a pointer to the next tuple in
7418 * that diff which has the same name and type (or NULL if no such tuple is
7419 * found).
7420 */
7421 static dns_difftuple_t *
7422 find_next_matching_tuple(dns_difftuple_t *cur) {
7423 dns_difftuple_t *next = cur;
7424
7425 while ((next = ISC_LIST_NEXT(next, link)) != NULL) {
7426 if (cur->rdata.type == next->rdata.type &&
7427 dns_name_equal(&cur->name, &next->name))
7428 {
7429 return (next);
7430 }
7431 }
7432
7433 return (NULL);
7434 }
7435
7436 /*%
7437 * Remove all tuples with the same name and type as 'cur' from 'src' and append
7438 * them to 'dst'.
7439 */
7440 static void
7441 move_matching_tuples(dns_difftuple_t *cur, dns_diff_t *src, dns_diff_t *dst) {
7442 do {
7443 dns_difftuple_t *next = find_next_matching_tuple(cur);
7444 ISC_LIST_UNLINK(src->tuples, cur, link);
7445 dns_diff_appendminimal(dst, &cur);
7446 cur = next;
7447 } while (cur != NULL);
7448 }
7449
7450 /*%
7451 * Add/remove DNSSEC signatures for the list of "raw" zone changes supplied in
7452 * 'diff'. Gradually remove tuples from 'diff' and append them to 'zonediff'
7453 * along with tuples representing relevant signature changes.
7454 */
7455 isc_result_t
7456 dns__zone_updatesigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
7457 dst_key_t *zone_keys[], unsigned int nkeys,
7458 dns_zone_t *zone, isc_stdtime_t inception,
7459 isc_stdtime_t expire, isc_stdtime_t keyexpire,
7460 isc_stdtime_t now, bool check_ksk,
7461 bool keyset_kskonly, dns__zonediff_t *zonediff)
7462 {
7463 dns_difftuple_t *tuple;
7464 isc_result_t result;
7465
7466 while ((tuple = ISC_LIST_HEAD(diff->tuples)) != NULL) {
7467 isc_stdtime_t exp = expire;
7468
7469 if (keyexpire != 0 &&
7470 (tuple->rdata.type == dns_rdatatype_dnskey ||
7471 tuple->rdata.type == dns_rdatatype_cdnskey ||
7472 tuple->rdata.type == dns_rdatatype_cds))
7473 {
7474 exp = keyexpire;
7475 }
7476
7477 result = del_sigs(zone, db, version, &tuple->name,
7478 tuple->rdata.type, zonediff,
7479 zone_keys, nkeys, now, false);
7480 if (result != ISC_R_SUCCESS) {
7481 dns_zone_log(zone, ISC_LOG_ERROR,
7482 "dns__zone_updatesigs:del_sigs -> %s",
7483 dns_result_totext(result));
7484 return (result);
7485 }
7486 result = add_sigs(db, version, &tuple->name,
7487 tuple->rdata.type, zonediff->diff,
7488 zone_keys, nkeys, zone->mctx, inception,
7489 exp, check_ksk, keyset_kskonly);
7490 if (result != ISC_R_SUCCESS) {
7491 dns_zone_log(zone, ISC_LOG_ERROR,
7492 "dns__zone_updatesigs:add_sigs -> %s",
7493 dns_result_totext(result));
7494 return (result);
7495 }
7496
7497 /*
7498 * Signature changes for all RRs with name tuple->name and type
7499 * tuple->rdata.type were appended to zonediff->diff. Now we
7500 * remove all the "raw" changes with the same name and type
7501 * from diff (so that they are not processed by this loop
7502 * again) and append them to zonediff so that they get applied.
7503 */
7504 move_matching_tuples(tuple, diff, zonediff->diff);
7505 }
7506 return (ISC_R_SUCCESS);
7507 }
7508
7509 /*
7510 * Incrementally build and sign a new NSEC3 chain using the parameters
7511 * requested.
7512 */
7513 static void
7514 zone_nsec3chain(dns_zone_t *zone) {
7515 const char *me = "zone_nsec3chain";
7516 dns_db_t *db = NULL;
7517 dns_dbnode_t *node = NULL;
7518 dns_dbversion_t *version = NULL;
7519 dns_diff_t _sig_diff;
7520 dns_diff_t nsec_diff;
7521 dns_diff_t nsec3_diff;
7522 dns_diff_t param_diff;
7523 dns__zonediff_t zonediff;
7524 dns_fixedname_t fixed;
7525 dns_fixedname_t nextfixed;
7526 dns_name_t *name, *nextname;
7527 dns_rdataset_t rdataset;
7528 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
7529 dns_nsec3chainlist_t cleanup;
7530 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
7531 int32_t signatures;
7532 bool check_ksk, keyset_kskonly;
7533 bool delegation;
7534 bool first;
7535 isc_result_t result;
7536 isc_stdtime_t now, inception, soaexpire, expire;
7537 uint32_t jitter, sigvalidityinterval;
7538 unsigned int i;
7539 unsigned int nkeys = 0;
7540 uint32_t nodes;
7541 bool unsecure = false;
7542 bool seen_soa, seen_ns, seen_dname, seen_ds;
7543 bool seen_nsec, seen_nsec3, seen_rr;
7544 dns_rdatasetiter_t *iterator = NULL;
7545 bool buildnsecchain;
7546 bool updatensec = false;
7547 dns_rdatatype_t privatetype = zone->privatetype;
7548
7549 ENTER;
7550
7551 dns_rdataset_init(&rdataset);
7552 name = dns_fixedname_initname(&fixed);
7553 nextname = dns_fixedname_initname(&nextfixed);
7554 dns_diff_init(zone->mctx, ¶m_diff);
7555 dns_diff_init(zone->mctx, &nsec3_diff);
7556 dns_diff_init(zone->mctx, &nsec_diff);
7557 dns_diff_init(zone->mctx, &_sig_diff);
7558 zonediff_init(&zonediff, &_sig_diff);
7559 ISC_LIST_INIT(cleanup);
7560
7561 /*
7562 * Updates are disabled. Pause for 5 minutes.
7563 */
7564 if (zone->update_disabled) {
7565 result = ISC_R_FAILURE;
7566 goto failure;
7567 }
7568
7569 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7570 /*
7571 * This function is called when zone timer fires, after the latter gets
7572 * set by zone_addnsec3chain(). If the action triggering the call to
7573 * zone_addnsec3chain() is closely followed by a zone deletion request,
7574 * it might turn out that the timer thread will not be woken up until
7575 * after the zone is deleted by rmzone(), which calls dns_db_detach()
7576 * for zone->db, causing the latter to become NULL. Return immediately
7577 * if that happens.
7578 */
7579 if (zone->db != NULL) {
7580 dns_db_attach(zone->db, &db);
7581 }
7582 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7583 if (db == NULL) {
7584 return;
7585 }
7586
7587 result = dns_db_newversion(db, &version);
7588 if (result != ISC_R_SUCCESS) {
7589 dns_zone_log(zone, ISC_LOG_ERROR,
7590 "zone_nsec3chain:dns_db_newversion -> %s",
7591 dns_result_totext(result));
7592 goto failure;
7593 }
7594
7595 isc_stdtime_get(&now);
7596
7597 result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
7598 DNS_MAXZONEKEYS, zone_keys, &nkeys);
7599 if (result != ISC_R_SUCCESS) {
7600 dns_zone_log(zone, ISC_LOG_ERROR,
7601 "zone_nsec3chain:dns__zone_findkeys -> %s",
7602 dns_result_totext(result));
7603 goto failure;
7604 }
7605
7606 sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
7607 inception = now - 3600; /* Allow for clock skew. */
7608 soaexpire = now + sigvalidityinterval;
7609
7610 /*
7611 * Spread out signatures over time if they happen to be
7612 * clumped. We don't do this for each add_sigs() call as
7613 * we still want some clustering to occur.
7614 */
7615 if (sigvalidityinterval >= 3600U) {
7616 if (sigvalidityinterval > 7200U) {
7617 jitter = isc_random_uniform(3600);
7618 } else {
7619 jitter = isc_random_uniform(1200);
7620 }
7621 expire = soaexpire - jitter - 1;
7622 } else {
7623 expire = soaexpire - 1;
7624 }
7625
7626 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
7627 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
7628
7629 /*
7630 * We keep pulling nodes off each iterator in turn until
7631 * we have no more nodes to pull off or we reach the limits
7632 * for this quantum.
7633 */
7634 nodes = zone->nodes;
7635 signatures = zone->signatures;
7636 LOCK_ZONE(zone);
7637 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7638 UNLOCK_ZONE(zone);
7639 first = true;
7640
7641 if (nsec3chain != NULL)
7642 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
7643 /*
7644 * Generate new NSEC3 chains first.
7645 *
7646 * The following while loop iterates over nodes in the zone database,
7647 * updating the NSEC3 chain by calling dns_nsec3_addnsec3() for each of
7648 * them. Once all nodes are processed, the "delete_nsec" field is
7649 * consulted to check whether we are supposed to remove NSEC records
7650 * from the zone database; if so, the database iterator is reset to
7651 * point to the first node and the loop traverses all of them again,
7652 * this time removing NSEC records. If we hit a node which is obscured
7653 * by a delegation or a DNAME, nodes are skipped over until we find one
7654 * that is not obscured by the same obscuring name and then normal
7655 * processing is resumed.
7656 *
7657 * The above is repeated until all requested NSEC3 chain changes are
7658 * applied or when we reach the limits for this quantum, whichever
7659 * happens first.
7660 *
7661 * Note that the "signatures" variable is only used here to limit the
7662 * amount of work performed. Actual DNSSEC signatures are only
7663 * generated by dns__zone_updatesigs() calls later in this function.
7664 */
7665 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
7666 LOCK_ZONE(zone);
7667 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
7668
7669 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7670 if (nsec3chain->done || nsec3chain->db != zone->db) {
7671 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
7672 ISC_LIST_APPEND(cleanup, nsec3chain, link);
7673 }
7674 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7675 UNLOCK_ZONE(zone);
7676 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
7677 goto next_addchain;
7678
7679 /*
7680 * Possible future db.
7681 */
7682 if (nsec3chain->db != db) {
7683 goto next_addchain;
7684 }
7685
7686 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
7687 goto next_addchain;
7688
7689 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
7690
7691 if (nsec3chain->delete_nsec) {
7692 delegation = false;
7693 dns_dbiterator_pause(nsec3chain->dbiterator);
7694 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
7695 goto next_addnode;
7696 }
7697 /*
7698 * On the first pass we need to check if the current node
7699 * has not been obscured.
7700 */
7701 delegation = false;
7702 unsecure = false;
7703 if (first) {
7704 dns_fixedname_t ffound;
7705 dns_name_t *found;
7706 found = dns_fixedname_initname(&ffound);
7707 result = dns_db_find(db, name, version,
7708 dns_rdatatype_soa,
7709 DNS_DBFIND_NOWILD, 0, NULL, found,
7710 NULL, NULL);
7711 if ((result == DNS_R_DELEGATION ||
7712 result == DNS_R_DNAME) &&
7713 !dns_name_equal(name, found)) {
7714 /*
7715 * Remember the obscuring name so that
7716 * we skip all obscured names.
7717 */
7718 dns_name_copy(found, name, NULL);
7719 delegation = true;
7720 goto next_addnode;
7721 }
7722 }
7723
7724 /*
7725 * Check to see if this is a bottom of zone node.
7726 */
7727 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7728 if (result == ISC_R_NOTFOUND) /* Empty node? */
7729 goto next_addnode;
7730 if (result != ISC_R_SUCCESS)
7731 goto failure;
7732
7733 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
7734 false;
7735 for (result = dns_rdatasetiter_first(iterator);
7736 result == ISC_R_SUCCESS;
7737 result = dns_rdatasetiter_next(iterator)) {
7738 dns_rdatasetiter_current(iterator, &rdataset);
7739 INSIST(rdataset.type != dns_rdatatype_nsec3);
7740 if (rdataset.type == dns_rdatatype_soa)
7741 seen_soa = true;
7742 else if (rdataset.type == dns_rdatatype_ns)
7743 seen_ns = true;
7744 else if (rdataset.type == dns_rdatatype_dname)
7745 seen_dname = true;
7746 else if (rdataset.type == dns_rdatatype_ds)
7747 seen_ds = true;
7748 else if (rdataset.type == dns_rdatatype_nsec)
7749 seen_nsec = true;
7750 dns_rdataset_disassociate(&rdataset);
7751 }
7752 dns_rdatasetiter_destroy(&iterator);
7753 /*
7754 * Is there a NSEC chain than needs to be cleaned up?
7755 */
7756 if (seen_nsec)
7757 nsec3chain->seen_nsec = true;
7758 if (seen_ns && !seen_soa && !seen_ds)
7759 unsecure = true;
7760 if ((seen_ns && !seen_soa) || seen_dname)
7761 delegation = true;
7762
7763 /*
7764 * Process one node.
7765 */
7766 dns_dbiterator_pause(nsec3chain->dbiterator);
7767 result = dns_nsec3_addnsec3(db, version, name,
7768 &nsec3chain->nsec3param,
7769 zone->minimum, unsecure,
7770 &nsec3_diff);
7771 if (result != ISC_R_SUCCESS) {
7772 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7773 "dns_nsec3_addnsec3 -> %s",
7774 dns_result_totext(result));
7775 goto failure;
7776 }
7777
7778 /*
7779 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
7780 * two signatures. Additionally there will, in general, be
7781 * two signature generated below.
7782 *
7783 * If we are only changing the optout flag the cost is half
7784 * that of the cost of generating a completely new chain.
7785 */
7786 signatures -= 4;
7787
7788 /*
7789 * Go onto next node.
7790 */
7791 next_addnode:
7792 first = false;
7793 dns_db_detachnode(db, &node);
7794 do {
7795 result = dns_dbiterator_next(nsec3chain->dbiterator);
7796
7797 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
7798 dns_dbiterator_pause(nsec3chain->dbiterator);
7799 CHECK(fixup_nsec3param(db, version, nsec3chain,
7800 false, privatetype,
7801 ¶m_diff));
7802 LOCK_ZONE(zone);
7803 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
7804 link);
7805 UNLOCK_ZONE(zone);
7806 ISC_LIST_APPEND(cleanup, nsec3chain, link);
7807 goto next_addchain;
7808 }
7809 if (result == ISC_R_NOMORE) {
7810 dns_dbiterator_pause(nsec3chain->dbiterator);
7811 if (nsec3chain->seen_nsec) {
7812 CHECK(fixup_nsec3param(db, version,
7813 nsec3chain,
7814 true,
7815 privatetype,
7816 ¶m_diff));
7817 nsec3chain->delete_nsec = true;
7818 goto same_addchain;
7819 }
7820 CHECK(fixup_nsec3param(db, version, nsec3chain,
7821 false, privatetype,
7822 ¶m_diff));
7823 LOCK_ZONE(zone);
7824 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
7825 link);
7826 UNLOCK_ZONE(zone);
7827 ISC_LIST_APPEND(cleanup, nsec3chain, link);
7828 goto next_addchain;
7829 } else if (result != ISC_R_SUCCESS) {
7830 dns_zone_log(zone, ISC_LOG_ERROR,
7831 "zone_nsec3chain:"
7832 "dns_dbiterator_next -> %s",
7833 dns_result_totext(result));
7834 goto failure;
7835 } else if (delegation) {
7836 dns_dbiterator_current(nsec3chain->dbiterator,
7837 &node, nextname);
7838 dns_db_detachnode(db, &node);
7839 if (!dns_name_issubdomain(nextname, name))
7840 break;
7841 } else
7842 break;
7843 } while (1);
7844 continue;
7845
7846 same_addchain:
7847 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
7848 first = true;
7849 continue;
7850
7851 next_addchain:
7852 dns_dbiterator_pause(nsec3chain->dbiterator);
7853 nsec3chain = nextnsec3chain;
7854 first = true;
7855 if (nsec3chain != NULL)
7856 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
7857 }
7858
7859 if (nsec3chain != NULL)
7860 goto skip_removals;
7861
7862 /*
7863 * Process removals.
7864 *
7865 * This is a counterpart of the above while loop which takes care of
7866 * removing an NSEC3 chain. It starts with determining whether the
7867 * zone needs to switch from NSEC3 to NSEC; if so, it first builds an
7868 * NSEC chain by iterating over all nodes in the zone database and only
7869 * then goes on to remove NSEC3 records be iterating over all nodes
7870 * again and calling deletematchingnsec3() for each of them; otherwise,
7871 * it starts removing NSEC3 records immediately. Rules for processing
7872 * obscured nodes and interrupting work are the same as for the while
7873 * loop above.
7874 */
7875 LOCK_ZONE(zone);
7876 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7877 UNLOCK_ZONE(zone);
7878 first = true;
7879 buildnsecchain = false;
7880 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
7881 LOCK_ZONE(zone);
7882 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
7883 UNLOCK_ZONE(zone);
7884
7885 if (nsec3chain->db != db)
7886 goto next_removechain;
7887
7888 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
7889 goto next_removechain;
7890
7891 /*
7892 * Work out if we need to build a NSEC chain as a consequence
7893 * of removing this NSEC3 chain.
7894 */
7895 if (first && !updatensec &&
7896 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
7897 {
7898 result = need_nsec_chain(db, version,
7899 &nsec3chain->nsec3param,
7900 &buildnsecchain);
7901 if (result != ISC_R_SUCCESS) {
7902 dns_zone_log(zone, ISC_LOG_ERROR,
7903 "zone_nsec3chain:"
7904 "need_nsec_chain -> %s",
7905 dns_result_totext(result));
7906 goto failure;
7907 }
7908 }
7909
7910 if (first)
7911 dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:"
7912 "buildnsecchain = %u\n", buildnsecchain);
7913
7914 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
7915 delegation = false;
7916
7917 if (!buildnsecchain) {
7918 /*
7919 * Delete the NSEC3PARAM record matching this chain.
7920 */
7921 if (first) {
7922 result = fixup_nsec3param(db, version,
7923 nsec3chain,
7924 true, privatetype,
7925 ¶m_diff);
7926 if (result != ISC_R_SUCCESS) {
7927 dns_zone_log(zone, ISC_LOG_ERROR,
7928 "zone_nsec3chain:"
7929 "fixup_nsec3param -> %s",
7930 dns_result_totext(result));
7931 goto failure;
7932 }
7933 }
7934
7935 /*
7936 * Delete the NSEC3 records.
7937 */
7938 result = deletematchingnsec3(db, version, node, name,
7939 &nsec3chain->nsec3param,
7940 &nsec3_diff);
7941 if (result != ISC_R_SUCCESS) {
7942 dns_zone_log(zone, ISC_LOG_ERROR,
7943 "zone_nsec3chain:"
7944 "deletematchingnsec3 -> %s",
7945 dns_result_totext(result));
7946 goto failure;
7947 }
7948 goto next_removenode;
7949 }
7950
7951 if (first) {
7952 dns_fixedname_t ffound;
7953 dns_name_t *found;
7954 found = dns_fixedname_initname(&ffound);
7955 result = dns_db_find(db, name, version,
7956 dns_rdatatype_soa,
7957 DNS_DBFIND_NOWILD, 0, NULL, found,
7958 NULL, NULL);
7959 if ((result == DNS_R_DELEGATION ||
7960 result == DNS_R_DNAME) &&
7961 !dns_name_equal(name, found)) {
7962 /*
7963 * Remember the obscuring name so that
7964 * we skip all obscured names.
7965 */
7966 dns_name_copy(found, name, NULL);
7967 delegation = true;
7968 goto next_removenode;
7969 }
7970 }
7971
7972 /*
7973 * Check to see if this is a bottom of zone node.
7974 */
7975 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7976 if (result == ISC_R_NOTFOUND) /* Empty node? */
7977 goto next_removenode;
7978 if (result != ISC_R_SUCCESS)
7979 goto failure;
7980
7981 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
7982 seen_rr = false;
7983 for (result = dns_rdatasetiter_first(iterator);
7984 result == ISC_R_SUCCESS;
7985 result = dns_rdatasetiter_next(iterator)) {
7986 dns_rdatasetiter_current(iterator, &rdataset);
7987 if (rdataset.type == dns_rdatatype_soa)
7988 seen_soa = true;
7989 else if (rdataset.type == dns_rdatatype_ns)
7990 seen_ns = true;
7991 else if (rdataset.type == dns_rdatatype_dname)
7992 seen_dname = true;
7993 else if (rdataset.type == dns_rdatatype_nsec)
7994 seen_nsec = true;
7995 else if (rdataset.type == dns_rdatatype_nsec3)
7996 seen_nsec3 = true;
7997 if (rdataset.type != dns_rdatatype_rrsig)
7998 seen_rr = true;
7999 dns_rdataset_disassociate(&rdataset);
8000 }
8001 dns_rdatasetiter_destroy(&iterator);
8002
8003 if (!seen_rr || seen_nsec3 || seen_nsec)
8004 goto next_removenode;
8005 if ((seen_ns && !seen_soa) || seen_dname)
8006 delegation = true;
8007
8008 /*
8009 * Add a NSEC record except at the origin.
8010 */
8011 if (!dns_name_equal(name, dns_db_origin(db))) {
8012 dns_dbiterator_pause(nsec3chain->dbiterator);
8013 CHECK(add_nsec(db, version, name, node, zone->minimum,
8014 delegation, &nsec_diff));
8015 signatures--;
8016 }
8017
8018 next_removenode:
8019 first = false;
8020 dns_db_detachnode(db, &node);
8021 do {
8022 result = dns_dbiterator_next(nsec3chain->dbiterator);
8023 if (result == ISC_R_NOMORE && buildnsecchain) {
8024 /*
8025 * The NSEC chain should now be built.
8026 * We can now remove the NSEC3 chain.
8027 */
8028 updatensec = true;
8029 goto same_removechain;
8030 }
8031 if (result == ISC_R_NOMORE) {
8032 LOCK_ZONE(zone);
8033 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
8034 link);
8035 UNLOCK_ZONE(zone);
8036 ISC_LIST_APPEND(cleanup, nsec3chain, link);
8037 dns_dbiterator_pause(nsec3chain->dbiterator);
8038 result = fixup_nsec3param(db, version,
8039 nsec3chain, false,
8040 privatetype,
8041 ¶m_diff);
8042 if (result != ISC_R_SUCCESS) {
8043 dns_zone_log(zone, ISC_LOG_ERROR,
8044 "zone_nsec3chain:"
8045 "fixup_nsec3param -> %s",
8046 dns_result_totext(result));
8047 goto failure;
8048 }
8049 goto next_removechain;
8050 } else if (result != ISC_R_SUCCESS) {
8051 dns_zone_log(zone, ISC_LOG_ERROR,
8052 "zone_nsec3chain:"
8053 "dns_dbiterator_next -> %s",
8054 dns_result_totext(result));
8055 goto failure;
8056 } else if (delegation) {
8057 dns_dbiterator_current(nsec3chain->dbiterator,
8058 &node, nextname);
8059 dns_db_detachnode(db, &node);
8060 if (!dns_name_issubdomain(nextname, name))
8061 break;
8062 } else
8063 break;
8064 } while (1);
8065 continue;
8066
8067 same_removechain:
8068 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
8069 buildnsecchain = false;
8070 first = true;
8071 continue;
8072
8073 next_removechain:
8074 dns_dbiterator_pause(nsec3chain->dbiterator);
8075 nsec3chain = nextnsec3chain;
8076 first = true;
8077 }
8078
8079 skip_removals:
8080 /*
8081 * We may need to update the NSEC/NSEC3 records for the zone apex.
8082 */
8083 if (!ISC_LIST_EMPTY(param_diff.tuples)) {
8084 bool rebuild_nsec = false,
8085 rebuild_nsec3 = false;
8086 result = dns_db_getoriginnode(db, &node);
8087 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8088 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
8089 if (result != ISC_R_SUCCESS) {
8090 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
8091 "dns_db_allrdatasets -> %s",
8092 dns_result_totext(result));
8093 goto failure;
8094 }
8095 for (result = dns_rdatasetiter_first(iterator);
8096 result == ISC_R_SUCCESS;
8097 result = dns_rdatasetiter_next(iterator)) {
8098 dns_rdatasetiter_current(iterator, &rdataset);
8099 if (rdataset.type == dns_rdatatype_nsec)
8100 rebuild_nsec = true;
8101 if (rdataset.type == dns_rdatatype_nsec3param)
8102 rebuild_nsec3 = true;
8103 dns_rdataset_disassociate(&rdataset);
8104 }
8105 dns_rdatasetiter_destroy(&iterator);
8106 dns_db_detachnode(db, &node);
8107
8108 if (rebuild_nsec) {
8109 if (nsec3chain != NULL)
8110 dns_dbiterator_pause(nsec3chain->dbiterator);
8111
8112 result = updatesecure(db, version, &zone->origin,
8113 zone->minimum, true,
8114 &nsec_diff);
8115 if (result != ISC_R_SUCCESS) {
8116 dns_zone_log(zone, ISC_LOG_ERROR,
8117 "zone_nsec3chain:"
8118 "updatesecure -> %s",
8119 dns_result_totext(result));
8120 goto failure;
8121 }
8122 }
8123
8124 if (rebuild_nsec3) {
8125 if (nsec3chain != NULL)
8126 dns_dbiterator_pause(nsec3chain->dbiterator);
8127
8128 result = dns_nsec3_addnsec3s(db, version,
8129 dns_db_origin(db),
8130 zone->minimum, false,
8131 &nsec3_diff);
8132 if (result != ISC_R_SUCCESS) {
8133 dns_zone_log(zone, ISC_LOG_ERROR,
8134 "zone_nsec3chain:"
8135 "dns_nsec3_addnsec3s -> %s",
8136 dns_result_totext(result));
8137 goto failure;
8138 }
8139 }
8140 }
8141
8142 /*
8143 * Add / update signatures for the NSEC3 records.
8144 */
8145 if (nsec3chain != NULL)
8146 dns_dbiterator_pause(nsec3chain->dbiterator);
8147 result = dns__zone_updatesigs(&nsec3_diff, db, version, zone_keys,
8148 nkeys, zone, inception, expire, 0, now,
8149 check_ksk, keyset_kskonly, &zonediff);
8150 if (result != ISC_R_SUCCESS) {
8151 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
8152 "dns__zone_updatesigs -> %s",
8153 dns_result_totext(result));
8154 goto failure;
8155 }
8156
8157 /*
8158 * We have changed the NSEC3PARAM or private RRsets
8159 * above so we need to update the signatures.
8160 */
8161 result = dns__zone_updatesigs(¶m_diff, db, version, zone_keys,
8162 nkeys, zone, inception, expire, 0, now,
8163 check_ksk, keyset_kskonly, &zonediff);
8164 if (result != ISC_R_SUCCESS) {
8165 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
8166 "dns__zone_updatesigs -> %s",
8167 dns_result_totext(result));
8168 goto failure;
8169 }
8170
8171 if (updatensec) {
8172 result = updatesecure(db, version, &zone->origin,
8173 zone->minimum, false, &nsec_diff);
8174 if (result != ISC_R_SUCCESS) {
8175 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
8176 "updatesecure -> %s",
8177 dns_result_totext(result));
8178 goto failure;
8179 }
8180 }
8181
8182 result = dns__zone_updatesigs(&nsec_diff, db, version, zone_keys,
8183 nkeys, zone, inception, expire, 0, now,
8184 check_ksk, keyset_kskonly, &zonediff);
8185 if (result != ISC_R_SUCCESS) {
8186 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
8187 "dns__zone_updatesigs -> %s",
8188 dns_result_totext(result));
8189 goto failure;
8190 }
8191
8192 /*
8193 * If we made no effective changes to the zone then we can just
8194 * cleanup otherwise we need to increment the serial.
8195 */
8196 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
8197 /*
8198 * No need to call dns_db_closeversion() here as it is
8199 * called with commit = true below.
8200 */
8201 goto done;
8202 }
8203
8204 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
8205 &zonediff, zone_keys, nkeys, now, false);
8206 if (result != ISC_R_SUCCESS) {
8207 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
8208 "del_sigs -> %s", dns_result_totext(result));
8209 goto failure;
8210 }
8211
8212 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
8213 zone->updatemethod);
8214 if (result != ISC_R_SUCCESS) {
8215 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
8216 "update_soa_serial -> %s",
8217 dns_result_totext(result));
8218 goto failure;
8219 }
8220
8221 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
8222 zonediff.diff, zone_keys, nkeys, zone->mctx,
8223 inception, soaexpire, check_ksk, keyset_kskonly);
8224 if (result != ISC_R_SUCCESS) {
8225 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
8226 "add_sigs -> %s", dns_result_totext(result));
8227 goto failure;
8228 }
8229
8230 /* Write changes to journal file. */
8231 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain"));
8232
8233 LOCK_ZONE(zone);
8234 zone_needdump(zone, DNS_DUMP_DELAY);
8235 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
8236 UNLOCK_ZONE(zone);
8237
8238 done:
8239 /*
8240 * Pause all iterators so that dns_db_closeversion() can succeed.
8241 */
8242 LOCK_ZONE(zone);
8243 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
8244 nsec3chain != NULL;
8245 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
8246 dns_dbiterator_pause(nsec3chain->dbiterator);
8247 UNLOCK_ZONE(zone);
8248
8249 /*
8250 * Everything has succeeded. Commit the changes.
8251 * Unconditionally commit as zonediff.offline not checked above.
8252 */
8253 dns_db_closeversion(db, &version, true);
8254
8255 /*
8256 * Everything succeeded so we can clean these up now.
8257 */
8258 nsec3chain = ISC_LIST_HEAD(cleanup);
8259 while (nsec3chain != NULL) {
8260 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
8261 dns_db_detach(&nsec3chain->db);
8262 dns_dbiterator_destroy(&nsec3chain->dbiterator);
8263 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
8264 nsec3chain = ISC_LIST_HEAD(cleanup);
8265 }
8266
8267 set_resigntime(zone);
8268
8269 failure:
8270 if (result != ISC_R_SUCCESS)
8271 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
8272 dns_result_totext(result));
8273 /*
8274 * On error roll back the current nsec3chain.
8275 */
8276 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
8277 if (nsec3chain->done) {
8278 dns_db_detach(&nsec3chain->db);
8279 dns_dbiterator_destroy(&nsec3chain->dbiterator);
8280 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
8281 } else {
8282 result = dns_dbiterator_first(nsec3chain->dbiterator);
8283 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8284 dns_dbiterator_pause(nsec3chain->dbiterator);
8285 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
8286 }
8287 }
8288
8289 /*
8290 * Rollback the cleanup list.
8291 */
8292 nsec3chain = ISC_LIST_TAIL(cleanup);
8293 while (nsec3chain != NULL) {
8294 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
8295 if (nsec3chain->done) {
8296 dns_db_detach(&nsec3chain->db);
8297 dns_dbiterator_destroy(&nsec3chain->dbiterator);
8298 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
8299 } else {
8300 LOCK_ZONE(zone);
8301 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
8302 UNLOCK_ZONE(zone);
8303 result = dns_dbiterator_first(nsec3chain->dbiterator);
8304 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8305 dns_dbiterator_pause(nsec3chain->dbiterator);
8306 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
8307 }
8308 nsec3chain = ISC_LIST_TAIL(cleanup);
8309 }
8310
8311 LOCK_ZONE(zone);
8312 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
8313 nsec3chain != NULL;
8314 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
8315 dns_dbiterator_pause(nsec3chain->dbiterator);
8316 UNLOCK_ZONE(zone);
8317
8318 dns_diff_clear(¶m_diff);
8319 dns_diff_clear(&nsec3_diff);
8320 dns_diff_clear(&nsec_diff);
8321 dns_diff_clear(&_sig_diff);
8322
8323 if (iterator != NULL)
8324 dns_rdatasetiter_destroy(&iterator);
8325
8326 for (i = 0; i < nkeys; i++)
8327 dst_key_free(&zone_keys[i]);
8328
8329 if (node != NULL)
8330 dns_db_detachnode(db, &node);
8331 if (version != NULL) {
8332 dns_db_closeversion(db, &version, false);
8333 dns_db_detach(&db);
8334 } else if (db != NULL)
8335 dns_db_detach(&db);
8336
8337 LOCK_ZONE(zone);
8338 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
8339 isc_interval_t interval;
8340 if (zone->update_disabled || result != ISC_R_SUCCESS)
8341 isc_interval_set(&interval, 60, 0); /* 1 minute */
8342 else
8343 isc_interval_set(&interval, 0, 10000000); /* 10 ms */
8344 isc_time_nowplusinterval(&zone->nsec3chaintime, &interval);
8345 } else
8346 isc_time_settoepoch(&zone->nsec3chaintime);
8347 UNLOCK_ZONE(zone);
8348
8349 INSIST(version == NULL);
8350 }
8351
8352 /*%
8353 * Delete all RRSIG records with the given algorithm and keyid.
8354 * Remove the NSEC record and RRSIGs if nkeys is zero.
8355 * If all remaining RRsets are signed with the given algorithm
8356 * set *has_algp to true.
8357 */
8358 static isc_result_t
8359 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
8360 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
8361 uint16_t keyid, bool *has_algp, dns_diff_t *diff)
8362 {
8363 dns_rdata_rrsig_t rrsig;
8364 dns_rdataset_t rdataset;
8365 dns_rdatasetiter_t *iterator = NULL;
8366 isc_result_t result;
8367 bool alg_missed = false;
8368 bool alg_found = false;
8369
8370 char namebuf[DNS_NAME_FORMATSIZE];
8371 dns_name_format(name, namebuf, sizeof(namebuf));
8372
8373 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
8374 if (result != ISC_R_SUCCESS) {
8375 if (result == ISC_R_NOTFOUND)
8376 result = ISC_R_SUCCESS;
8377 return (result);
8378 }
8379
8380 dns_rdataset_init(&rdataset);
8381 for (result = dns_rdatasetiter_first(iterator);
8382 result == ISC_R_SUCCESS;
8383 result = dns_rdatasetiter_next(iterator)) {
8384 bool has_alg = false;
8385 dns_rdatasetiter_current(iterator, &rdataset);
8386 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
8387 for (result = dns_rdataset_first(&rdataset);
8388 result == ISC_R_SUCCESS;
8389 result = dns_rdataset_next(&rdataset)) {
8390 dns_rdata_t rdata = DNS_RDATA_INIT;
8391 dns_rdataset_current(&rdataset, &rdata);
8392 CHECK(update_one_rr(db, version, diff,
8393 DNS_DIFFOP_DEL, name,
8394 rdataset.ttl, &rdata));
8395 }
8396 if (result != ISC_R_NOMORE)
8397 goto failure;
8398 dns_rdataset_disassociate(&rdataset);
8399 continue;
8400 }
8401 if (rdataset.type != dns_rdatatype_rrsig) {
8402 dns_rdataset_disassociate(&rdataset);
8403 continue;
8404 }
8405 for (result = dns_rdataset_first(&rdataset);
8406 result == ISC_R_SUCCESS;
8407 result = dns_rdataset_next(&rdataset))
8408 {
8409 dns_rdata_t rdata = DNS_RDATA_INIT;
8410 dns_rdataset_current(&rdataset, &rdata);
8411 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
8412 if (nkeys != 0 &&
8413 (rrsig.algorithm != algorithm ||
8414 rrsig.keyid != keyid))
8415 {
8416 if (rrsig.algorithm == algorithm) {
8417 has_alg = true;
8418 }
8419 continue;
8420 }
8421 CHECK(update_one_rr(db, version, diff,
8422 DNS_DIFFOP_DELRESIGN, name,
8423 rdataset.ttl, &rdata));
8424 }
8425 dns_rdataset_disassociate(&rdataset);
8426 if (result != ISC_R_NOMORE)
8427 break;
8428
8429 /*
8430 * After deleting, if there's still a signature for
8431 * 'algorithm', set alg_found; if not, set alg_missed.
8432 */
8433 if (has_alg) {
8434 alg_found = true;
8435 } else {
8436 alg_missed = true;
8437 }
8438 }
8439 if (result == ISC_R_NOMORE)
8440 result = ISC_R_SUCCESS;
8441
8442 /*
8443 * Set `has_algp` if the algorithm was found in every RRset:
8444 * i.e., found in at least one, and not missing from any.
8445 */
8446 *has_algp = (alg_found && !alg_missed);
8447 failure:
8448 if (dns_rdataset_isassociated(&rdataset))
8449 dns_rdataset_disassociate(&rdataset);
8450 dns_rdatasetiter_destroy(&iterator);
8451 return (result);
8452 }
8453
8454 /*
8455 * Incrementally sign the zone using the keys requested.
8456 * Builds the NSEC chain if required.
8457 */
8458 static void
8459 zone_sign(dns_zone_t *zone) {
8460 const char *me = "zone_sign";
8461 dns_db_t *db = NULL;
8462 dns_dbnode_t *node = NULL;
8463 dns_dbversion_t *version = NULL;
8464 dns_diff_t _sig_diff;
8465 dns_diff_t post_diff;
8466 dns__zonediff_t zonediff;
8467 dns_fixedname_t fixed;
8468 dns_fixedname_t nextfixed;
8469 dns_name_t *name, *nextname;
8470 dns_rdataset_t rdataset;
8471 dns_signing_t *signing, *nextsigning;
8472 dns_signinglist_t cleanup;
8473 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
8474 int32_t signatures;
8475 bool check_ksk, keyset_kskonly, is_ksk;
8476 bool with_ksk, with_zsk;
8477 bool commit = false;
8478 bool is_bottom_of_zone;
8479 bool build_nsec = false;
8480 bool build_nsec3 = false;
8481 bool first;
8482 isc_result_t result;
8483 isc_stdtime_t now, inception, soaexpire, expire;
8484 uint32_t jitter, sigvalidityinterval, expiryinterval;
8485 unsigned int i, j;
8486 unsigned int nkeys = 0;
8487 uint32_t nodes;
8488
8489 ENTER;
8490
8491 dns_rdataset_init(&rdataset);
8492 name = dns_fixedname_initname(&fixed);
8493 nextname = dns_fixedname_initname(&nextfixed);
8494 dns_diff_init(zone->mctx, &_sig_diff);
8495 dns_diff_init(zone->mctx, &post_diff);
8496 zonediff_init(&zonediff, &_sig_diff);
8497 ISC_LIST_INIT(cleanup);
8498
8499 /*
8500 * Updates are disabled. Pause for 5 minutes.
8501 */
8502 if (zone->update_disabled) {
8503 result = ISC_R_FAILURE;
8504 goto failure;
8505 }
8506
8507 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8508 if (zone->db != NULL)
8509 dns_db_attach(zone->db, &db);
8510 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8511 if (db == NULL) {
8512 result = ISC_R_FAILURE;
8513 goto failure;
8514 }
8515
8516 result = dns_db_newversion(db, &version);
8517 if (result != ISC_R_SUCCESS) {
8518 dns_zone_log(zone, ISC_LOG_ERROR,
8519 "zone_sign:dns_db_newversion -> %s",
8520 dns_result_totext(result));
8521 goto failure;
8522 }
8523
8524 isc_stdtime_get(&now);
8525
8526 result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
8527 DNS_MAXZONEKEYS, zone_keys, &nkeys);
8528 if (result != ISC_R_SUCCESS) {
8529 dns_zone_log(zone, ISC_LOG_ERROR,
8530 "zone_sign:dns__zone_findkeys -> %s",
8531 dns_result_totext(result));
8532 goto failure;
8533 }
8534
8535 sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
8536 inception = now - 3600; /* Allow for clock skew. */
8537 soaexpire = now + sigvalidityinterval;
8538 expiryinterval = dns_zone_getsigresigninginterval(zone);
8539 if (expiryinterval > sigvalidityinterval) {
8540 expiryinterval = sigvalidityinterval;
8541 } else {
8542 expiryinterval = sigvalidityinterval - expiryinterval;
8543 }
8544
8545 /*
8546 * Spread out signatures over time if they happen to be
8547 * clumped. We don't do this for each add_sigs() call as
8548 * we still want some clustering to occur.
8549 */
8550 if (sigvalidityinterval >= 3600U) {
8551 if (sigvalidityinterval > 7200U) {
8552 jitter = isc_random_uniform(expiryinterval);
8553 } else {
8554 jitter = isc_random_uniform(1200);
8555 }
8556 expire = soaexpire - jitter - 1;
8557 } else {
8558 expire = soaexpire - 1;
8559 }
8560
8561 /*
8562 * We keep pulling nodes off each iterator in turn until
8563 * we have no more nodes to pull off or we reach the limits
8564 * for this quantum.
8565 */
8566 nodes = zone->nodes;
8567 signatures = zone->signatures;
8568 signing = ISC_LIST_HEAD(zone->signing);
8569 first = true;
8570
8571 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
8572 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
8573
8574 /* Determine which type of chain to build */
8575 CHECK(dns_private_chains(db, version, zone->privatetype,
8576 &build_nsec, &build_nsec3));
8577
8578 /* If neither chain is found, default to NSEC */
8579 if (!build_nsec && !build_nsec3)
8580 build_nsec = true;
8581
8582 while (signing != NULL && nodes-- > 0 && signatures > 0) {
8583 bool has_alg = false;
8584 nextsigning = ISC_LIST_NEXT(signing, link);
8585
8586 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8587 if (signing->done || signing->db != zone->db) {
8588 /*
8589 * The zone has been reloaded. We will have
8590 * created new signings as part of the reload
8591 * process so we can destroy this one.
8592 */
8593 ISC_LIST_UNLINK(zone->signing, signing, link);
8594 ISC_LIST_APPEND(cleanup, signing, link);
8595 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8596 goto next_signing;
8597 }
8598 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8599
8600 if (signing->db != db)
8601 goto next_signing;
8602
8603 is_bottom_of_zone = false;
8604
8605 if (first && signing->deleteit) {
8606 /*
8607 * Remove the key we are deleting from consideration.
8608 */
8609 for (i = 0, j = 0; i < nkeys; i++) {
8610 /*
8611 * Find the key we want to remove.
8612 */
8613 if (ALG(zone_keys[i]) == signing->algorithm &&
8614 dst_key_id(zone_keys[i]) == signing->keyid)
8615 {
8616 if (KSK(zone_keys[i]))
8617 dst_key_free(&zone_keys[i]);
8618 continue;
8619 }
8620 zone_keys[j] = zone_keys[i];
8621 j++;
8622 }
8623 for (i = j; i < nkeys; i++) {
8624 zone_keys[i] = NULL;
8625 }
8626 nkeys = j;
8627 }
8628
8629 dns_dbiterator_current(signing->dbiterator, &node, name);
8630
8631 if (signing->deleteit) {
8632 dns_dbiterator_pause(signing->dbiterator);
8633 CHECK(del_sig(db, version, name, node, nkeys,
8634 signing->algorithm, signing->keyid,
8635 &has_alg, zonediff.diff));
8636 }
8637
8638 /*
8639 * On the first pass we need to check if the current node
8640 * has not been obscured.
8641 */
8642 if (first) {
8643 dns_fixedname_t ffound;
8644 dns_name_t *found;
8645 found = dns_fixedname_initname(&ffound);
8646 result = dns_db_find(db, name, version,
8647 dns_rdatatype_soa,
8648 DNS_DBFIND_NOWILD, 0, NULL, found,
8649 NULL, NULL);
8650 if ((result == DNS_R_DELEGATION ||
8651 result == DNS_R_DNAME) &&
8652 !dns_name_equal(name, found)) {
8653 /*
8654 * Remember the obscuring name so that
8655 * we skip all obscured names.
8656 */
8657 dns_name_copy(found, name, NULL);
8658 is_bottom_of_zone = true;
8659 goto next_node;
8660 }
8661 }
8662
8663 /*
8664 * Process one node.
8665 */
8666 with_ksk = false;
8667 with_zsk = false;
8668 dns_dbiterator_pause(signing->dbiterator);
8669
8670 CHECK(check_if_bottom_of_zone(db, node, version,
8671 &is_bottom_of_zone));
8672
8673 for (i = 0; !has_alg && i < nkeys; i++) {
8674 bool both = false;
8675
8676 /*
8677 * Find the keys we want to sign with.
8678 */
8679 if (!dst_key_isprivate(zone_keys[i]))
8680 continue;
8681 /*
8682 * Should be redundant.
8683 */
8684 if (dst_key_inactive(zone_keys[i]))
8685 continue;
8686
8687 /*
8688 * When adding look for the specific key.
8689 */
8690 if (!signing->deleteit &&
8691 (dst_key_alg(zone_keys[i]) != signing->algorithm ||
8692 dst_key_id(zone_keys[i]) != signing->keyid))
8693 continue;
8694
8695 /*
8696 * When deleting make sure we are properly signed
8697 * with the algorithm that was being removed.
8698 */
8699 if (signing->deleteit &&
8700 ALG(zone_keys[i]) != signing->algorithm)
8701 continue;
8702
8703 /*
8704 * Do we do KSK processing?
8705 */
8706 if (check_ksk && !REVOKE(zone_keys[i])) {
8707 bool have_ksk, have_nonksk;
8708 if (KSK(zone_keys[i])) {
8709 have_ksk = true;
8710 have_nonksk = false;
8711 } else {
8712 have_ksk = false;
8713 have_nonksk = true;
8714 }
8715 for (j = 0; j < nkeys; j++) {
8716 if (j == i ||
8717 ALG(zone_keys[i]) !=
8718 ALG(zone_keys[j]))
8719 continue;
8720 if (!dst_key_isprivate(zone_keys[j]))
8721 continue;
8722 /*
8723 * Should be redundant.
8724 */
8725 if (dst_key_inactive(zone_keys[j]))
8726 continue;
8727 if (REVOKE(zone_keys[j]))
8728 continue;
8729 if (KSK(zone_keys[j]))
8730 have_ksk = true;
8731 else
8732 have_nonksk = true;
8733 both = have_ksk && have_nonksk;
8734 if (both)
8735 break;
8736 }
8737 }
8738 if (both || REVOKE(zone_keys[i]))
8739 is_ksk = KSK(zone_keys[i]);
8740 else
8741 is_ksk = false;
8742
8743 /*
8744 * If deleting signatures, we need to ensure that
8745 * the RRset is still signed at least once by a
8746 * KSK and a ZSK.
8747 */
8748 if (signing->deleteit && !is_ksk && with_zsk) {
8749 continue;
8750 }
8751
8752 if (signing->deleteit && is_ksk && with_ksk) {
8753 continue;
8754 }
8755
8756 CHECK(sign_a_node(db, name, node, version, build_nsec3,
8757 build_nsec, zone_keys[i], inception,
8758 expire, zone->minimum, is_ksk,
8759 (both && keyset_kskonly),
8760 is_bottom_of_zone, zonediff.diff,
8761 &signatures, zone->mctx));
8762 /*
8763 * If we are adding we are done. Look for other keys
8764 * of the same algorithm if deleting.
8765 */
8766 if (!signing->deleteit) {
8767 break;
8768 }
8769 if (!is_ksk) {
8770 with_zsk = true;
8771 }
8772 if (KSK(zone_keys[i])) {
8773 with_ksk = true;
8774 }
8775 }
8776
8777 /*
8778 * Go onto next node.
8779 */
8780 next_node:
8781 first = false;
8782 dns_db_detachnode(db, &node);
8783 do {
8784 result = dns_dbiterator_next(signing->dbiterator);
8785 if (result == ISC_R_NOMORE) {
8786 ISC_LIST_UNLINK(zone->signing, signing, link);
8787 ISC_LIST_APPEND(cleanup, signing, link);
8788 dns_dbiterator_pause(signing->dbiterator);
8789 if (nkeys != 0 && build_nsec) {
8790 /*
8791 * We have finished regenerating the
8792 * zone with a zone signing key.
8793 * The NSEC chain is now complete and
8794 * there is a full set of signatures
8795 * for the zone. We can now clear the
8796 * OPT bit from the NSEC record.
8797 */
8798 result = updatesecure(db, version,
8799 &zone->origin,
8800 zone->minimum,
8801 false,
8802 &post_diff);
8803 if (result != ISC_R_SUCCESS) {
8804 dns_zone_log(zone,
8805 ISC_LOG_ERROR,
8806 "updatesecure -> %s",
8807 dns_result_totext(result));
8808 goto failure;
8809 }
8810 }
8811 result = updatesignwithkey(zone, signing,
8812 version,
8813 build_nsec3,
8814 zone->minimum,
8815 &post_diff);
8816 if (result != ISC_R_SUCCESS) {
8817 dns_zone_log(zone, ISC_LOG_ERROR,
8818 "updatesignwithkey -> %s",
8819 dns_result_totext(result));
8820 goto failure;
8821 }
8822 build_nsec = false;
8823 goto next_signing;
8824 } else if (result != ISC_R_SUCCESS) {
8825 dns_zone_log(zone, ISC_LOG_ERROR,
8826 "zone_sign:dns_dbiterator_next -> %s",
8827 dns_result_totext(result));
8828 goto failure;
8829 } else if (is_bottom_of_zone) {
8830 dns_dbiterator_current(signing->dbiterator,
8831 &node, nextname);
8832 dns_db_detachnode(db, &node);
8833 if (!dns_name_issubdomain(nextname, name))
8834 break;
8835 } else
8836 break;
8837 } while (1);
8838 continue;
8839
8840 next_signing:
8841 dns_dbiterator_pause(signing->dbiterator);
8842 signing = nextsigning;
8843 first = true;
8844 }
8845
8846 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
8847 result = dns__zone_updatesigs(&post_diff, db, version,
8848 zone_keys, nkeys, zone,
8849 inception, expire, 0, now,
8850 check_ksk, keyset_kskonly,
8851 &zonediff);
8852 if (result != ISC_R_SUCCESS) {
8853 dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
8854 "dns__zone_updatesigs -> %s",
8855 dns_result_totext(result));
8856 goto failure;
8857 }
8858 }
8859
8860 /*
8861 * Have we changed anything?
8862 */
8863 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
8864 if (zonediff.offline)
8865 commit = true;
8866 result = ISC_R_SUCCESS;
8867 goto pauseall;
8868 }
8869
8870 commit = true;
8871
8872 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
8873 &zonediff, zone_keys, nkeys, now, false);
8874 if (result != ISC_R_SUCCESS) {
8875 dns_zone_log(zone, ISC_LOG_ERROR,
8876 "zone_sign:del_sigs -> %s",
8877 dns_result_totext(result));
8878 goto failure;
8879 }
8880
8881 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
8882 zone->updatemethod);
8883 if (result != ISC_R_SUCCESS) {
8884 dns_zone_log(zone, ISC_LOG_ERROR,
8885 "zone_sign:update_soa_serial -> %s",
8886 dns_result_totext(result));
8887 goto failure;
8888 }
8889
8890 /*
8891 * Generate maximum life time signatures so that the above loop
8892 * termination is sensible.
8893 */
8894 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
8895 zonediff.diff, zone_keys, nkeys, zone->mctx,
8896 inception, soaexpire, check_ksk, keyset_kskonly);
8897 if (result != ISC_R_SUCCESS) {
8898 dns_zone_log(zone, ISC_LOG_ERROR,
8899 "zone_sign:add_sigs -> %s",
8900 dns_result_totext(result));
8901 goto failure;
8902 }
8903
8904 /*
8905 * Write changes to journal file.
8906 */
8907 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign"));
8908
8909 pauseall:
8910 /*
8911 * Pause all iterators so that dns_db_closeversion() can succeed.
8912 */
8913 for (signing = ISC_LIST_HEAD(zone->signing);
8914 signing != NULL;
8915 signing = ISC_LIST_NEXT(signing, link))
8916 dns_dbiterator_pause(signing->dbiterator);
8917
8918 for (signing = ISC_LIST_HEAD(cleanup);
8919 signing != NULL;
8920 signing = ISC_LIST_NEXT(signing, link))
8921 dns_dbiterator_pause(signing->dbiterator);
8922
8923 /*
8924 * Everything has succeeded. Commit the changes.
8925 */
8926 dns_db_closeversion(db, &version, commit);
8927
8928 /*
8929 * Everything succeeded so we can clean these up now.
8930 */
8931 signing = ISC_LIST_HEAD(cleanup);
8932 while (signing != NULL) {
8933 ISC_LIST_UNLINK(cleanup, signing, link);
8934 dns_db_detach(&signing->db);
8935 dns_dbiterator_destroy(&signing->dbiterator);
8936 isc_mem_put(zone->mctx, signing, sizeof *signing);
8937 signing = ISC_LIST_HEAD(cleanup);
8938 }
8939
8940 set_resigntime(zone);
8941
8942 if (commit) {
8943 LOCK_ZONE(zone);
8944 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
8945 zone_needdump(zone, DNS_DUMP_DELAY);
8946 UNLOCK_ZONE(zone);
8947 }
8948
8949 failure:
8950 /*
8951 * Pause all dbiterators.
8952 */
8953 for (signing = ISC_LIST_HEAD(zone->signing);
8954 signing != NULL;
8955 signing = ISC_LIST_NEXT(signing, link))
8956 dns_dbiterator_pause(signing->dbiterator);
8957
8958 /*
8959 * Rollback the cleanup list.
8960 */
8961 signing = ISC_LIST_HEAD(cleanup);
8962 while (signing != NULL) {
8963 ISC_LIST_UNLINK(cleanup, signing, link);
8964 ISC_LIST_PREPEND(zone->signing, signing, link);
8965 dns_dbiterator_first(signing->dbiterator);
8966 dns_dbiterator_pause(signing->dbiterator);
8967 signing = ISC_LIST_HEAD(cleanup);
8968 }
8969
8970 dns_diff_clear(&_sig_diff);
8971
8972 for (i = 0; i < nkeys; i++)
8973 dst_key_free(&zone_keys[i]);
8974
8975 if (node != NULL)
8976 dns_db_detachnode(db, &node);
8977
8978 if (version != NULL) {
8979 dns_db_closeversion(db, &version, false);
8980 dns_db_detach(&db);
8981 } else if (db != NULL)
8982 dns_db_detach(&db);
8983
8984 if (ISC_LIST_HEAD(zone->signing) != NULL) {
8985 isc_interval_t interval;
8986 if (zone->update_disabled || result != ISC_R_SUCCESS)
8987 isc_interval_set(&interval, 60, 0); /* 1 minute */
8988 else
8989 isc_interval_set(&interval, 0, 10000000); /* 10 ms */
8990 isc_time_nowplusinterval(&zone->signingtime, &interval);
8991 } else
8992 isc_time_settoepoch(&zone->signingtime);
8993
8994 INSIST(version == NULL);
8995 }
8996
8997 static isc_result_t
8998 normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
8999 unsigned char *data, int size)
9000 {
9001 dns_rdata_dnskey_t dnskey;
9002 dns_rdata_keydata_t keydata;
9003 isc_buffer_t buf;
9004 isc_result_t result;
9005
9006 dns_rdata_reset(target);
9007 isc_buffer_init(&buf, data, size);
9008
9009 switch (rr->type) {
9010 case dns_rdatatype_dnskey:
9011 result = dns_rdata_tostruct(rr, &dnskey, NULL);
9012 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9013 dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
9014 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
9015 &dnskey, &buf);
9016 break;
9017 case dns_rdatatype_keydata:
9018 result = dns_rdata_tostruct(rr, &keydata, NULL);
9019 if (result == ISC_R_UNEXPECTEDEND)
9020 return (result);
9021 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9022 dns_keydata_todnskey(&keydata, &dnskey, NULL);
9023 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
9024 &dnskey, &buf);
9025 break;
9026 default:
9027 INSIST(0);
9028 ISC_UNREACHABLE();
9029 }
9030 return (ISC_R_SUCCESS);
9031 }
9032
9033 /*
9034 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
9035 * a KEYDATA rdataset from the key zone.
9036 *
9037 * 'rr' contains either a DNSKEY record, or a KEYDATA record
9038 *
9039 * After normalizing keys to the same format (DNSKEY, with revoke bit
9040 * cleared), return true if a key that matches 'rr' is found in
9041 * 'rdset', or false if not.
9042 */
9043
9044 static bool
9045 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
9046 unsigned char data1[4096], data2[4096];
9047 dns_rdata_t rdata, rdata1, rdata2;
9048 isc_result_t result;
9049
9050 dns_rdata_init(&rdata);
9051 dns_rdata_init(&rdata1);
9052 dns_rdata_init(&rdata2);
9053
9054 result = normalize_key(rr, &rdata1, data1, sizeof(data1));
9055 if (result != ISC_R_SUCCESS)
9056 return (false);
9057
9058 for (result = dns_rdataset_first(rdset);
9059 result == ISC_R_SUCCESS;
9060 result = dns_rdataset_next(rdset)) {
9061 dns_rdata_reset(&rdata);
9062 dns_rdataset_current(rdset, &rdata);
9063 result = normalize_key(&rdata, &rdata2, data2, sizeof(data2));
9064 if (result != ISC_R_SUCCESS)
9065 continue;
9066 if (dns_rdata_compare(&rdata1, &rdata2) == 0)
9067 return (true);
9068 }
9069
9070 return (false);
9071 }
9072
9073 /*
9074 * Calculate the refresh interval for a keydata zone, per
9075 * RFC5011: MAX(1 hr,
9076 * MIN(15 days,
9077 * 1/2 * OrigTTL,
9078 * 1/2 * RRSigExpirationInterval))
9079 * or for retries: MAX(1 hr,
9080 * MIN(1 day,
9081 * 1/10 * OrigTTL,
9082 * 1/10 * RRSigExpirationInterval))
9083 */
9084 static inline isc_stdtime_t
9085 refresh_time(dns_keyfetch_t *kfetch, bool retry) {
9086 isc_result_t result;
9087 uint32_t t;
9088 dns_rdataset_t *rdset;
9089 dns_rdata_t sigrr = DNS_RDATA_INIT;
9090 dns_rdata_sig_t sig;
9091 isc_stdtime_t now;
9092
9093 isc_stdtime_get(&now);
9094
9095 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
9096 rdset = &kfetch->dnskeysigset;
9097 else
9098 return (now + dns_zone_mkey_hour);
9099
9100 result = dns_rdataset_first(rdset);
9101 if (result != ISC_R_SUCCESS)
9102 return (now + dns_zone_mkey_hour);
9103
9104 dns_rdataset_current(rdset, &sigrr);
9105 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
9106 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9107
9108 if (!retry) {
9109 t = sig.originalttl / 2;
9110
9111 if (isc_serial_gt(sig.timeexpire, now)) {
9112 uint32_t exp = (sig.timeexpire - now) / 2;
9113 if (t > exp)
9114 t = exp;
9115 }
9116
9117 if (t > (15 * dns_zone_mkey_day))
9118 t = (15 * dns_zone_mkey_day);
9119
9120 if (t < dns_zone_mkey_hour)
9121 t = dns_zone_mkey_hour;
9122 } else {
9123 t = sig.originalttl / 10;
9124
9125 if (isc_serial_gt(sig.timeexpire, now)) {
9126 uint32_t exp = (sig.timeexpire - now) / 10;
9127 if (t > exp)
9128 t = exp;
9129 }
9130
9131 if (t > dns_zone_mkey_day)
9132 t = dns_zone_mkey_day;
9133
9134 if (t < dns_zone_mkey_hour)
9135 t = dns_zone_mkey_hour;
9136 }
9137
9138 return (now + t);
9139 }
9140
9141 /*
9142 * This routine is called when no changes are needed in a KEYDATA
9143 * record except to simply update the refresh timer. Caller should
9144 * hold zone lock.
9145 */
9146 static isc_result_t
9147 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
9148 {
9149 isc_result_t result;
9150 isc_buffer_t keyb;
9151 unsigned char key_buf[4096];
9152 dns_rdata_t rdata = DNS_RDATA_INIT;
9153 dns_rdata_keydata_t keydata;
9154 dns_name_t *name;
9155 dns_zone_t *zone = kfetch->zone;
9156 isc_stdtime_t now;
9157
9158 name = dns_fixedname_name(&kfetch->name);
9159 isc_stdtime_get(&now);
9160
9161 for (result = dns_rdataset_first(&kfetch->keydataset);
9162 result == ISC_R_SUCCESS;
9163 result = dns_rdataset_next(&kfetch->keydataset)) {
9164 dns_rdata_reset(&rdata);
9165 dns_rdataset_current(&kfetch->keydataset, &rdata);
9166
9167 /* Delete old version */
9168 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
9169 name, 0, &rdata));
9170
9171 /* Update refresh timer */
9172 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
9173 if (result == ISC_R_UNEXPECTEDEND)
9174 continue;
9175 if (result != ISC_R_SUCCESS)
9176 goto failure;
9177 keydata.refresh = refresh_time(kfetch, true);
9178 set_refreshkeytimer(zone, &keydata, now, false);
9179
9180 dns_rdata_reset(&rdata);
9181 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
9182 CHECK(dns_rdata_fromstruct(&rdata,
9183 zone->rdclass, dns_rdatatype_keydata,
9184 &keydata, &keyb));
9185
9186 /* Insert updated version */
9187 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
9188 name, 0, &rdata));
9189 }
9190 result = ISC_R_SUCCESS;
9191 failure:
9192 return (result);
9193 }
9194
9195 /*
9196 * Verify that DNSKEY set is signed by the key specified in 'keydata'.
9197 */
9198 static bool
9199 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
9200 isc_result_t result;
9201 dns_name_t *keyname;
9202 isc_mem_t *mctx;
9203 dns_rdata_t sigrr = DNS_RDATA_INIT;
9204 dns_rdata_t rr = DNS_RDATA_INIT;
9205 dns_rdata_rrsig_t sig;
9206 dns_rdata_dnskey_t dnskey;
9207 dst_key_t *dstkey = NULL;
9208 unsigned char key_buf[4096];
9209 isc_buffer_t keyb;
9210 bool answer = false;
9211
9212 REQUIRE(kfetch != NULL && keydata != NULL);
9213 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
9214
9215 keyname = dns_fixedname_name(&kfetch->name);
9216 mctx = kfetch->zone->view->mctx;
9217
9218 /* Generate a key from keydata */
9219 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
9220 dns_keydata_todnskey(keydata, &dnskey, NULL);
9221 dns_rdata_fromstruct(&rr, keydata->common.rdclass,
9222 dns_rdatatype_dnskey, &dnskey, &keyb);
9223 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
9224 if (result != ISC_R_SUCCESS)
9225 return (false);
9226
9227 /* See if that key generated any of the signatures */
9228 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
9229 result == ISC_R_SUCCESS;
9230 result = dns_rdataset_next(&kfetch->dnskeysigset))
9231 {
9232 dns_fixedname_t fixed;
9233 dns_fixedname_init(&fixed);
9234
9235 dns_rdata_reset(&sigrr);
9236 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
9237 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
9238 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9239
9240 if (dst_key_alg(dstkey) == sig.algorithm &&
9241 dst_key_rid(dstkey) == sig.keyid)
9242 {
9243 result = dns_dnssec_verify(keyname,
9244 &kfetch->dnskeyset,
9245 dstkey, false, 0, mctx,
9246 &sigrr,
9247 dns_fixedname_name(&fixed));
9248
9249 dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3),
9250 "Confirm revoked DNSKEY is self-signed: "
9251 "%s", dns_result_totext(result));
9252
9253 if (result == ISC_R_SUCCESS) {
9254 answer = true;
9255 break;
9256 }
9257 }
9258 }
9259
9260 dst_key_free(&dstkey);
9261 return (answer);
9262 }
9263
9264 /*
9265 * A DNSKEY set has been fetched from the zone apex of a zone whose trust
9266 * anchors are being managed; scan the keyset, and update the key zone and the
9267 * local trust anchors according to RFC5011.
9268 */
9269 static void
9270 keyfetch_done(isc_task_t *task, isc_event_t *event) {
9271 isc_result_t result, eresult;
9272 dns_fetchevent_t *devent;
9273 dns_keyfetch_t *kfetch;
9274 dns_zone_t *zone;
9275 isc_mem_t *mctx = NULL;
9276 dns_keytable_t *secroots = NULL;
9277 dns_dbversion_t *ver = NULL;
9278 dns_diff_t diff;
9279 bool alldone = false;
9280 bool commit = false;
9281 dns_name_t *keyname;
9282 dns_rdata_t sigrr = DNS_RDATA_INIT;
9283 dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
9284 dns_rdata_t keydatarr = DNS_RDATA_INIT;
9285 dns_rdata_rrsig_t sig;
9286 dns_rdata_dnskey_t dnskey;
9287 dns_rdata_keydata_t keydata;
9288 bool initializing;
9289 char namebuf[DNS_NAME_FORMATSIZE];
9290 unsigned char key_buf[4096];
9291 isc_buffer_t keyb;
9292 dst_key_t *dstkey;
9293 isc_stdtime_t now;
9294 int pending = 0;
9295 bool secure = false, initial = false;
9296 bool free_needed;
9297
9298 UNUSED(task);
9299 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
9300 INSIST(event->ev_arg != NULL);
9301
9302 kfetch = event->ev_arg;
9303 zone = kfetch->zone;
9304 isc_mem_attach(zone->mctx, &mctx);
9305 keyname = dns_fixedname_name(&kfetch->name);
9306
9307 devent = (dns_fetchevent_t *) event;
9308 eresult = devent->result;
9309
9310 /* Free resources which are not of interest */
9311 if (devent->node != NULL)
9312 dns_db_detachnode(devent->db, &devent->node);
9313 if (devent->db != NULL)
9314 dns_db_detach(&devent->db);
9315 isc_event_free(&event);
9316 dns_resolver_destroyfetch(&kfetch->fetch);
9317
9318 LOCK_ZONE(zone);
9319 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL)
9320 goto cleanup;
9321
9322 isc_stdtime_get(&now);
9323 dns_name_format(keyname, namebuf, sizeof(namebuf));
9324
9325 result = dns_view_getsecroots(zone->view, &secroots);
9326 INSIST(result == ISC_R_SUCCESS);
9327
9328 dns_diff_init(mctx, &diff);
9329
9330 CHECK(dns_db_newversion(kfetch->db, &ver));
9331
9332 zone->refreshkeycount--;
9333 alldone = (zone->refreshkeycount == 0);
9334
9335 if (alldone)
9336 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
9337
9338 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9339 "Returned from key fetch in keyfetch_done() for "
9340 "'%s': %s", namebuf, dns_result_totext(eresult));
9341
9342 /* Fetch failed */
9343 if (eresult != ISC_R_SUCCESS ||
9344 !dns_rdataset_isassociated(&kfetch->dnskeyset)) {
9345 dns_zone_log(zone, ISC_LOG_WARNING,
9346 "Unable to fetch DNSKEY set "
9347 "'%s': %s", namebuf, dns_result_totext(eresult));
9348 CHECK(minimal_update(kfetch, ver, &diff));
9349 goto done;
9350 }
9351
9352 /* No RRSIGs found */
9353 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
9354 dns_zone_log(zone, ISC_LOG_WARNING,
9355 "No DNSKEY RRSIGs found for "
9356 "'%s': %s", namebuf, dns_result_totext(eresult));
9357 CHECK(minimal_update(kfetch, ver, &diff));
9358 goto done;
9359 }
9360
9361 /*
9362 * Clear any cached trust level, as we need to run validation
9363 * over again; trusted keys might have changed.
9364 */
9365 kfetch->dnskeyset.trust = kfetch->dnskeysigset.trust = dns_trust_none;
9366
9367 /*
9368 * Validate the dnskeyset against the current trusted keys.
9369 */
9370 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
9371 result == ISC_R_SUCCESS;
9372 result = dns_rdataset_next(&kfetch->dnskeysigset))
9373 {
9374 dns_keynode_t *keynode = NULL;
9375
9376 dns_rdata_reset(&sigrr);
9377 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
9378 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
9379 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9380
9381 result = dns_keytable_find(secroots, keyname, &keynode);
9382 while (result == ISC_R_SUCCESS) {
9383 dns_keynode_t *nextnode = NULL;
9384 dns_fixedname_t fixed;
9385 dns_fixedname_init(&fixed);
9386
9387 dstkey = dns_keynode_key(keynode);
9388 if (dstkey == NULL) /* fail_secure() was called */
9389 break;
9390
9391 if (dst_key_alg(dstkey) == sig.algorithm &&
9392 dst_key_id(dstkey) == sig.keyid)
9393 {
9394 result = dns_dnssec_verify(keyname,
9395 &kfetch->dnskeyset,
9396 dstkey, false,
9397 0,
9398 zone->view->mctx,
9399 &sigrr,
9400 dns_fixedname_name(
9401 &fixed));
9402
9403 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9404 "Verifying DNSKEY set for zone "
9405 "'%s' using key %d/%d: %s",
9406 namebuf, sig.keyid, sig.algorithm,
9407 dns_result_totext(result));
9408
9409 if (result == ISC_R_SUCCESS) {
9410 kfetch->dnskeyset.trust =
9411 dns_trust_secure;
9412 kfetch->dnskeysigset.trust =
9413 dns_trust_secure;
9414 secure = true;
9415 initial = dns_keynode_initial(keynode);
9416 dns_keynode_trust(keynode);
9417 break;
9418 }
9419 }
9420
9421 result = dns_keytable_nextkeynode(secroots,
9422 keynode, &nextnode);
9423 dns_keytable_detachkeynode(secroots, &keynode);
9424 keynode = nextnode;
9425 }
9426
9427 if (keynode != NULL) {
9428 dns_keytable_detachkeynode(secroots, &keynode);
9429 }
9430
9431 if (secure) {
9432 break;
9433 }
9434 }
9435
9436 /*
9437 * If we were not able to verify the answer using the current
9438 * trusted keys then all we can do is look at any revoked keys.
9439 */
9440 if (!secure) {
9441 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9442 "DNSKEY set for zone '%s' could not be verified "
9443 "with current keys", namebuf);
9444 }
9445
9446 /*
9447 * First scan keydataset to find keys that are not in dnskeyset
9448 * - Missing keys which are not scheduled for removal,
9449 * log a warning
9450 * - Missing keys which are scheduled for removal and
9451 * the remove hold-down timer has completed should
9452 * be removed from the key zone
9453 * - Missing keys whose acceptance timers have not yet
9454 * completed, log a warning and reset the acceptance
9455 * timer to 30 days in the future
9456 * - All keys not being removed have their refresh timers
9457 * updated
9458 */
9459 initializing = true;
9460 for (result = dns_rdataset_first(&kfetch->keydataset);
9461 result == ISC_R_SUCCESS;
9462 result = dns_rdataset_next(&kfetch->keydataset))
9463 {
9464 dns_keytag_t keytag;
9465
9466 dns_rdata_reset(&keydatarr);
9467 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
9468 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
9469 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9470
9471 dns_keydata_todnskey(&keydata, &dnskey, NULL);
9472 result = compute_tag(keyname, &dnskey, mctx, &keytag);
9473 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9474
9475 /*
9476 * If any keydata record has a nonzero add holddown, then
9477 * there was a pre-existing trust anchor for this domain;
9478 * that means we are *not* initializing it and shouldn't
9479 * automatically trust all the keys we find at the zone apex.
9480 */
9481 initializing = initializing && (keydata.addhd == 0);
9482
9483 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
9484 bool deletekey = false;
9485
9486 if (!secure) {
9487 if (keydata.removehd != 0 &&
9488 keydata.removehd <= now) {
9489 deletekey = true;
9490 }
9491 } else if (keydata.addhd == 0) {
9492 deletekey = true;
9493 } else if (keydata.addhd > now) {
9494 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9495 "Pending key %d for zone %s "
9496 "unexpectedly missing "
9497 "restarting 30-day acceptance "
9498 "timer", keytag, namebuf);
9499 if (keydata.addhd < now + dns_zone_mkey_month)
9500 keydata.addhd =
9501 now + dns_zone_mkey_month;
9502 keydata.refresh = refresh_time(kfetch,
9503 false);
9504 } else if (keydata.removehd == 0) {
9505 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9506 "Active key %d for zone %s "
9507 "unexpectedly missing",
9508 keytag, namebuf);
9509 keydata.refresh = now + dns_zone_mkey_hour;
9510 } else if (keydata.removehd <= now) {
9511 deletekey = true;
9512 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9513 "Revoked key %d for zone %s "
9514 "missing: deleting from "
9515 "managed keys database",
9516 keytag, namebuf);
9517 } else {
9518 keydata.refresh = refresh_time(kfetch,
9519 false);
9520 }
9521
9522 if (secure || deletekey) {
9523 /* Delete old version */
9524 CHECK(update_one_rr(kfetch->db, ver, &diff,
9525 DNS_DIFFOP_DEL, keyname, 0,
9526 &keydatarr));
9527 }
9528
9529 if (!secure || deletekey)
9530 continue;
9531
9532 dns_rdata_reset(&keydatarr);
9533 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
9534 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
9535 dns_rdatatype_keydata,
9536 &keydata, &keyb);
9537
9538 /* Insert updated version */
9539 CHECK(update_one_rr(kfetch->db, ver, &diff,
9540 DNS_DIFFOP_ADD, keyname, 0,
9541 &keydatarr));
9542
9543 set_refreshkeytimer(zone, &keydata, now, false);
9544 }
9545 }
9546
9547 /*
9548 * Next scan dnskeyset:
9549 * - If new keys are found (i.e., lacking a match in keydataset)
9550 * add them to the key zone and set the acceptance timer
9551 * to 30 days in the future (or to immediately if we've
9552 * determined that we're initializing the zone for the
9553 * first time)
9554 * - Previously-known keys that have been revoked
9555 * must be scheduled for removal from the key zone (or,
9556 * if they hadn't been accepted as trust anchors yet
9557 * anyway, removed at once)
9558 * - Previously-known unrevoked keys whose acceptance timers
9559 * have completed are promoted to trust anchors
9560 * - All keys not being removed have their refresh
9561 * timers updated
9562 */
9563 for (result = dns_rdataset_first(&kfetch->dnskeyset);
9564 result == ISC_R_SUCCESS;
9565 result = dns_rdataset_next(&kfetch->dnskeyset))
9566 {
9567 bool revoked = false;
9568 bool newkey = false;
9569 bool updatekey = false;
9570 bool deletekey = false;
9571 bool trustkey = false;
9572 dns_keytag_t keytag;
9573
9574 dns_rdata_reset(&dnskeyrr);
9575 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
9576 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
9577 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9578
9579 /* Skip ZSK's */
9580 if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) {
9581 continue;
9582 }
9583
9584 result = compute_tag(keyname, &dnskey, mctx, &keytag);
9585 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9586
9587 revoked = ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0);
9588
9589 if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
9590 dns_rdata_reset(&keydatarr);
9591 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
9592 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
9593 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9594
9595 if (revoked && revocable(kfetch, &keydata)) {
9596 if (keydata.addhd > now) {
9597 /*
9598 * Key wasn't trusted yet, and now
9599 * it's been revoked? Just remove it
9600 */
9601 deletekey = true;
9602 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9603 "Pending key %d "
9604 "for zone %s is now "
9605 "revoked: "
9606 "deleting from the "
9607 "managed keys database",
9608 keytag, namebuf);
9609 } else if (keydata.removehd == 0) {
9610 /*
9611 * Remove key from secroots.
9612 */
9613 dns_view_untrust(zone->view, keyname,
9614 &dnskey, mctx);
9615
9616 /* If initializing, delete now */
9617 if (keydata.addhd == 0)
9618 deletekey = true;
9619 else {
9620 keydata.removehd = now +
9621 dns_zone_mkey_month;
9622 keydata.flags |=
9623 DNS_KEYFLAG_REVOKE;
9624 }
9625
9626 dns_zone_log(zone, ISC_LOG_INFO,
9627 "Trusted key %d "
9628 "for zone %s is now "
9629 "revoked",
9630 keytag, namebuf);
9631 } else if (keydata.removehd < now) {
9632 /* Scheduled for removal */
9633 deletekey = true;
9634
9635 dns_zone_log(zone, ISC_LOG_INFO,
9636 "Revoked key %d "
9637 "for zone %s removal "
9638 "timer complete: "
9639 "deleting from the "
9640 "managed keys database",
9641 keytag, namebuf);
9642 }
9643 } else if (revoked && keydata.removehd == 0) {
9644 dns_zone_log(zone, ISC_LOG_WARNING,
9645 "Active key %d for zone "
9646 "%s is revoked but "
9647 "did not self-sign; "
9648 "ignoring", keytag, namebuf);
9649 continue;
9650 } else if (secure) {
9651 if (keydata.removehd != 0) {
9652 /*
9653 * Key isn't revoked--but it
9654 * seems it used to be.
9655 * Remove it now and add it
9656 * back as if it were a fresh key,
9657 * with a 30-day acceptance timer.
9658 */
9659 deletekey = true;
9660 newkey = true;
9661 keydata.removehd = 0;
9662 keydata.addhd =
9663 now + dns_zone_mkey_month;
9664
9665 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9666 "Revoked key %d "
9667 "for zone %s "
9668 "has returned: starting "
9669 "30-day acceptance timer",
9670 keytag, namebuf);
9671 } else if (keydata.addhd > now)
9672 pending++;
9673 else if (keydata.addhd == 0)
9674 keydata.addhd = now;
9675
9676 if (keydata.addhd <= now) {
9677 trustkey = true;
9678 dns_zone_log(zone, ISC_LOG_INFO,
9679 "Key %d for zone %s "
9680 "is now trusted (%s)",
9681 keytag, namebuf,
9682 initial
9683 ? "initializing key "
9684 "verified"
9685 : "acceptance timer "
9686 "complete");
9687 }
9688 } else if (keydata.addhd > now) {
9689 /*
9690 * Not secure, and key is pending:
9691 * reset the acceptance timer
9692 */
9693 pending++;
9694 keydata.addhd = now + dns_zone_mkey_month;
9695 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9696 "Pending key %d "
9697 "for zone %s was "
9698 "not validated: restarting "
9699 "30-day acceptance timer",
9700 keytag, namebuf);
9701 }
9702
9703 if (!deletekey && !newkey)
9704 updatekey = true;
9705 } else if (secure) {
9706 /*
9707 * Key wasn't in the key zone but it's
9708 * revoked now anyway, so just skip it
9709 */
9710 if (revoked)
9711 continue;
9712
9713 /* Key wasn't in the key zone: add it */
9714 newkey = true;
9715
9716 if (initializing) {
9717 dns_zone_log(zone, ISC_LOG_WARNING,
9718 "Initializing automatic trust "
9719 "anchor management for zone '%s'; "
9720 "DNSKEY ID %d is now trusted, "
9721 "waiving the normal 30-day "
9722 "waiting period.",
9723 namebuf, keytag);
9724 trustkey = true;
9725 } else {
9726 dns_zone_log(zone, ISC_LOG_INFO,
9727 "New key %d observed "
9728 "for zone '%s': "
9729 "starting 30-day "
9730 "acceptance timer",
9731 keytag, namebuf);
9732 }
9733 } else {
9734 /*
9735 * No previously known key, and the key is not
9736 * secure, so skip it.
9737 */
9738 continue;
9739 }
9740
9741 /* Delete old version */
9742 if (deletekey || !newkey)
9743 CHECK(update_one_rr(kfetch->db, ver, &diff,
9744 DNS_DIFFOP_DEL, keyname, 0,
9745 &keydatarr));
9746
9747 if (updatekey) {
9748 /* Set refresh timer */
9749 keydata.refresh = refresh_time(kfetch, false);
9750 dns_rdata_reset(&keydatarr);
9751 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
9752 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
9753 dns_rdatatype_keydata,
9754 &keydata, &keyb);
9755
9756 /* Insert updated version */
9757 CHECK(update_one_rr(kfetch->db, ver, &diff,
9758 DNS_DIFFOP_ADD, keyname, 0,
9759 &keydatarr));
9760 } else if (newkey) {
9761 /* Convert DNSKEY to KEYDATA */
9762 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
9763 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9764 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
9765 NULL);
9766 keydata.addhd = initializing
9767 ? now : now + dns_zone_mkey_month;
9768 keydata.refresh = refresh_time(kfetch, false);
9769 dns_rdata_reset(&keydatarr);
9770 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
9771 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
9772 dns_rdatatype_keydata,
9773 &keydata, &keyb);
9774
9775 /* Insert into key zone */
9776 CHECK(update_one_rr(kfetch->db, ver, &diff,
9777 DNS_DIFFOP_ADD, keyname, 0,
9778 &keydatarr));
9779 }
9780
9781 if (trustkey) {
9782 /* Trust this key. */
9783 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
9784 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9785 trust_key(zone, keyname, &dnskey, false, mctx);
9786 }
9787
9788 if (secure && !deletekey) {
9789 INSIST(newkey || updatekey);
9790 set_refreshkeytimer(zone, &keydata, now, false);
9791 }
9792 }
9793
9794 /*
9795 * RFC5011 says, "A trust point that has all of its trust anchors
9796 * revoked is considered deleted and is treated as if the trust
9797 * point was never configured." But if someone revoked their
9798 * active key before the standby was trusted, that would mean the
9799 * zone would suddenly be nonsecured. We avoid this by checking to
9800 * see if there's pending keydata. If so, we put a null key in
9801 * the security roots; then all queries to the zone will fail.
9802 */
9803 if (pending != 0)
9804 fail_secure(zone, keyname);
9805
9806 done:
9807 if (!ISC_LIST_EMPTY(diff.tuples)) {
9808 /* Write changes to journal file. */
9809 CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx,
9810 zone->updatemethod));
9811 CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done"));
9812 commit = true;
9813
9814 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
9815 zone_needdump(zone, 30);
9816 } else if (result == ISC_R_NOMORE) {
9817 /*
9818 * If "updatekey" was true for all keys found in the DNSKEY
9819 * response and the previous update of those keys happened
9820 * during the same second (only possible if a key refresh was
9821 * externally triggered), it may happen that all relevant
9822 * update_one_rr() calls will return ISC_R_SUCCESS, but
9823 * diff.tuples will remain empty. Reset result to
9824 * ISC_R_SUCCESS to prevent a bogus warning from being logged.
9825 */
9826 result = ISC_R_SUCCESS;
9827 }
9828
9829 failure:
9830 if (result != ISC_R_SUCCESS) {
9831 dns_zone_log(zone, ISC_LOG_ERROR,
9832 "error during managed-keys processing (%s): "
9833 "DNSSEC validation may be at risk",
9834 isc_result_totext(result));
9835 }
9836 dns_diff_clear(&diff);
9837 if (ver != NULL)
9838 dns_db_closeversion(kfetch->db, &ver, commit);
9839
9840 cleanup:
9841 dns_db_detach(&kfetch->db);
9842
9843 INSIST(zone->irefs > 0);
9844 zone->irefs--;
9845 kfetch->zone = NULL;
9846
9847 if (dns_rdataset_isassociated(&kfetch->keydataset))
9848 dns_rdataset_disassociate(&kfetch->keydataset);
9849 if (dns_rdataset_isassociated(&kfetch->dnskeyset))
9850 dns_rdataset_disassociate(&kfetch->dnskeyset);
9851 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
9852 dns_rdataset_disassociate(&kfetch->dnskeysigset);
9853
9854 dns_name_free(keyname, mctx);
9855 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
9856 isc_mem_detach(&mctx);
9857
9858 if (secroots != NULL)
9859 dns_keytable_detach(&secroots);
9860
9861 free_needed = exit_check(zone);
9862 UNLOCK_ZONE(zone);
9863 if (free_needed)
9864 zone_free(zone);
9865
9866 INSIST(ver == NULL);
9867 }
9868
9869 /*
9870 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
9871 * records from the zone apex.
9872 */
9873 static void
9874 zone_refreshkeys(dns_zone_t *zone) {
9875 const char me[] = "zone_refreshkeys";
9876 isc_result_t result;
9877 dns_rriterator_t rrit;
9878 dns_db_t *db = NULL;
9879 dns_dbversion_t *ver = NULL;
9880 dns_diff_t diff;
9881 dns_rdata_t rdata = DNS_RDATA_INIT;
9882 dns_rdata_keydata_t kd;
9883 isc_stdtime_t now;
9884 bool commit = false;
9885 bool fetching = false, fetch_err = false;
9886
9887 ENTER;
9888 REQUIRE(zone->db != NULL);
9889
9890 isc_stdtime_get(&now);
9891
9892 LOCK_ZONE(zone);
9893 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
9894 isc_time_settoepoch(&zone->refreshkeytime);
9895 UNLOCK_ZONE(zone);
9896 return;
9897 }
9898
9899 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9900 dns_db_attach(zone->db, &db);
9901 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9902
9903 dns_diff_init(zone->mctx, &diff);
9904
9905 CHECK(dns_db_newversion(db, &ver));
9906
9907 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
9908
9909 dns_rriterator_init(&rrit, db, ver, 0);
9910 for (result = dns_rriterator_first(&rrit);
9911 result == ISC_R_SUCCESS;
9912 result = dns_rriterator_nextrrset(&rrit)) {
9913 isc_stdtime_t timer = 0xffffffff;
9914 dns_name_t *name = NULL, *kname = NULL;
9915 dns_rdataset_t *kdset = NULL;
9916 dns_keyfetch_t *kfetch;
9917 uint32_t ttl;
9918
9919 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
9920 if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
9921 !dns_rdataset_isassociated(kdset))
9922 continue;
9923
9924 /*
9925 * Scan the stored keys looking for ones that need
9926 * removal or refreshing
9927 */
9928 for (result = dns_rdataset_first(kdset);
9929 result == ISC_R_SUCCESS;
9930 result = dns_rdataset_next(kdset)) {
9931 dns_rdata_reset(&rdata);
9932 dns_rdataset_current(kdset, &rdata);
9933 result = dns_rdata_tostruct(&rdata, &kd, NULL);
9934 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9935
9936 /* Removal timer expired? */
9937 if (kd.removehd != 0 && kd.removehd < now) {
9938 CHECK(update_one_rr(db, ver, &diff,
9939 DNS_DIFFOP_DEL, name, ttl,
9940 &rdata));
9941 continue;
9942 }
9943
9944 /* Acceptance timer expired? */
9945 if (kd.addhd <= now)
9946 timer = kd.addhd;
9947
9948 /* Or do we just need to refresh the keyset? */
9949 if (timer > kd.refresh)
9950 timer = kd.refresh;
9951 }
9952
9953 if (timer > now)
9954 continue;
9955
9956 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
9957 if (kfetch == NULL) {
9958 fetch_err = true;
9959 goto failure;
9960 }
9961
9962 zone->refreshkeycount++;
9963 kfetch->zone = zone;
9964 zone->irefs++;
9965 INSIST(zone->irefs != 0);
9966 kname = dns_fixedname_initname(&kfetch->name);
9967 dns_name_dup(name, zone->mctx, kname);
9968 dns_rdataset_init(&kfetch->dnskeyset);
9969 dns_rdataset_init(&kfetch->dnskeysigset);
9970 dns_rdataset_init(&kfetch->keydataset);
9971 dns_rdataset_clone(kdset, &kfetch->keydataset);
9972 kfetch->db = NULL;
9973 dns_db_attach(db, &kfetch->db);
9974 kfetch->fetch = NULL;
9975
9976 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
9977 char namebuf[DNS_NAME_FORMATSIZE];
9978 dns_name_format(kname, namebuf,
9979 sizeof(namebuf));
9980 dns_zone_log(zone, ISC_LOG_DEBUG(3),
9981 "Creating key fetch in "
9982 "zone_refreshkeys() for '%s'",
9983 namebuf);
9984 }
9985
9986 /*
9987 * Use of DNS_FETCHOPT_NOCACHED is essential here. If it is
9988 * not set and the cache still holds a non-expired, validated
9989 * version of the RRset being queried for by the time the
9990 * response is received, the cached RRset will be passed to
9991 * keyfetch_done() instead of the one received in the response
9992 * as the latter will have a lower trust level due to not being
9993 * validated until keyfetch_done() is called.
9994 */
9995
9996 #ifdef ENABLE_AFL
9997 if (dns_fuzzing_resolver == false) {
9998 #endif
9999 result = dns_resolver_createfetch(zone->view->resolver,
10000 kname, dns_rdatatype_dnskey,
10001 NULL, NULL, NULL, NULL, 0,
10002 DNS_FETCHOPT_NOVALIDATE |
10003 DNS_FETCHOPT_UNSHARED |
10004 DNS_FETCHOPT_NOCACHED,
10005 0, NULL, zone->task,
10006 keyfetch_done, kfetch,
10007 &kfetch->dnskeyset,
10008 &kfetch->dnskeysigset,
10009 &kfetch->fetch);
10010 #ifdef ENABLE_AFL
10011 } else {
10012 result = ISC_R_FAILURE;
10013 }
10014 #endif
10015 if (result == ISC_R_SUCCESS)
10016 fetching = true;
10017 else {
10018 zone->refreshkeycount--;
10019 zone->irefs--;
10020 dns_db_detach(&kfetch->db);
10021 dns_rdataset_disassociate(&kfetch->keydataset);
10022 dns_name_free(kname, zone->mctx);
10023 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
10024 dns_zone_log(zone, ISC_LOG_WARNING,
10025 "Failed to create fetch for "
10026 "DNSKEY update");
10027 fetch_err = true;
10028 }
10029 }
10030 if (!ISC_LIST_EMPTY(diff.tuples)) {
10031 CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
10032 zone->updatemethod));
10033 CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys"));
10034 commit = true;
10035 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
10036 zone_needdump(zone, 30);
10037 }
10038
10039 failure:
10040 if (fetch_err) {
10041 /*
10042 * Error during a key fetch; retry in an hour.
10043 */
10044 isc_time_t timenow, timethen;
10045 char timebuf[80];
10046
10047 TIME_NOW(&timenow);
10048 DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen);
10049 zone->refreshkeytime = timethen;
10050 zone_settimer(zone, &timenow);
10051
10052 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
10053 dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
10054 timebuf);
10055 }
10056
10057 if (!fetching)
10058 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
10059
10060 dns_diff_clear(&diff);
10061 if (ver != NULL) {
10062 dns_rriterator_destroy(&rrit);
10063 dns_db_closeversion(db, &ver, commit);
10064 }
10065 dns_db_detach(&db);
10066
10067 UNLOCK_ZONE(zone);
10068
10069 INSIST(ver == NULL);
10070 }
10071
10072 static void
10073 zone_maintenance(dns_zone_t *zone) {
10074 const char me[] = "zone_maintenance";
10075 isc_time_t now;
10076 isc_result_t result;
10077 bool dumping, load_pending;
10078
10079 REQUIRE(DNS_ZONE_VALID(zone));
10080 ENTER;
10081
10082 /*
10083 * Are we pending load/reload?
10084 */
10085 LOCK_ZONE(zone);
10086 load_pending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING);
10087 UNLOCK_ZONE(zone);
10088
10089 if (load_pending) {
10090 return;
10091 }
10092
10093 /*
10094 * Configuring the view of this zone may have
10095 * failed, for example because the config file
10096 * had a syntax error. In that case, the view
10097 * adb or resolver will be NULL, and we had better not try
10098 * to do further maintenance on it.
10099 */
10100 if (zone->view == NULL || zone->view->adb == NULL)
10101 return;
10102
10103 TIME_NOW(&now);
10104
10105 /*
10106 * Expire check.
10107 */
10108 switch (zone->type) {
10109 case dns_zone_redirect:
10110 if (zone->masters == NULL)
10111 break;
10112 /* FALLTHROUGH */
10113 case dns_zone_slave:
10114 case dns_zone_mirror:
10115 case dns_zone_stub:
10116 LOCK_ZONE(zone);
10117 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
10118 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
10119 zone_expire(zone);
10120 zone->refreshtime = now;
10121 }
10122 UNLOCK_ZONE(zone);
10123 break;
10124 default:
10125 break;
10126 }
10127
10128 /*
10129 * Up to date check.
10130 */
10131 switch (zone->type) {
10132 case dns_zone_redirect:
10133 if (zone->masters == NULL)
10134 break;
10135 /* FALLTHROUGH */
10136 case dns_zone_slave:
10137 case dns_zone_mirror:
10138 case dns_zone_stub:
10139 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
10140 isc_time_compare(&now, &zone->refreshtime) >= 0)
10141 dns_zone_refresh(zone);
10142 break;
10143 default:
10144 break;
10145 }
10146
10147 /*
10148 * Slaves send notifies before backing up to disk, masters after.
10149 */
10150 if ((zone->type == dns_zone_slave || zone->type == dns_zone_mirror) &&
10151 (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
10152 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
10153 isc_time_compare(&now, &zone->notifytime) >= 0)
10154 zone_notify(zone, &now);
10155
10156 /*
10157 * Do we need to consolidate the backing store?
10158 */
10159 switch (zone->type) {
10160 case dns_zone_master:
10161 case dns_zone_slave:
10162 case dns_zone_mirror:
10163 case dns_zone_key:
10164 case dns_zone_redirect:
10165 case dns_zone_stub:
10166 LOCK_ZONE(zone);
10167 if (zone->masterfile != NULL &&
10168 isc_time_compare(&now, &zone->dumptime) >= 0 &&
10169 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
10170 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
10171 dumping = was_dumping(zone);
10172 } else
10173 dumping = true;
10174 UNLOCK_ZONE(zone);
10175 if (!dumping) {
10176 result = zone_dump(zone, true); /* task locked */
10177 if (result != ISC_R_SUCCESS)
10178 dns_zone_log(zone, ISC_LOG_WARNING,
10179 "dump failed: %s",
10180 dns_result_totext(result));
10181 }
10182 break;
10183 default:
10184 break;
10185 }
10186
10187 /*
10188 * Master/redirect zones send notifies now, if needed
10189 */
10190 switch (zone->type) {
10191 case dns_zone_master:
10192 case dns_zone_redirect:
10193 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
10194 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))&&
10195 isc_time_compare(&now, &zone->notifytime) >= 0)
10196 zone_notify(zone, &now);
10197 default:
10198 break;
10199 }
10200
10201 /*
10202 * Do we need to refresh keys?
10203 */
10204 switch (zone->type) {
10205 case dns_zone_key:
10206 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
10207 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
10208 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
10209 zone_refreshkeys(zone);
10210 }
10211 }
10212 break;
10213 case dns_zone_master:
10214 if (!isc_time_isepoch(&zone->refreshkeytime) &&
10215 isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
10216 zone->rss_event == NULL)
10217 zone_rekey(zone);
10218 default:
10219 break;
10220 }
10221
10222 switch (zone->type) {
10223 case dns_zone_master:
10224 case dns_zone_redirect:
10225 case dns_zone_slave:
10226 /*
10227 * Do we need to sign/resign some RRsets?
10228 */
10229 if (zone->rss_event != NULL)
10230 break;
10231 if (!isc_time_isepoch(&zone->signingtime) &&
10232 isc_time_compare(&now, &zone->signingtime) >= 0)
10233 zone_sign(zone);
10234 else if (!isc_time_isepoch(&zone->resigntime) &&
10235 isc_time_compare(&now, &zone->resigntime) >= 0)
10236 zone_resigninc(zone);
10237 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
10238 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
10239 zone_nsec3chain(zone);
10240 /*
10241 * Do we need to issue a key expiry warning?
10242 */
10243 if (!isc_time_isepoch(&zone->keywarntime) &&
10244 isc_time_compare(&now, &zone->keywarntime) >= 0)
10245 set_key_expiry_warning(zone, zone->key_expiry,
10246 isc_time_seconds(&now));
10247 break;
10248
10249 default:
10250 break;
10251 }
10252 zone_settimer(zone, &now);
10253 }
10254
10255 void
10256 dns_zone_markdirty(dns_zone_t *zone) {
10257 uint32_t serial;
10258 isc_result_t result = ISC_R_SUCCESS;
10259 dns_zone_t *secure = NULL;
10260
10261 /*
10262 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
10263 * could result in a deadlock due to a LOR so we will spin if we
10264 * can't obtain the both locks.
10265 */
10266 again:
10267 LOCK_ZONE(zone);
10268 if (zone->type == dns_zone_master) {
10269 if (inline_raw(zone)) {
10270 unsigned int soacount;
10271 secure = zone->secure;
10272 INSIST(secure != zone);
10273 TRYLOCK_ZONE(result, secure);
10274 if (result != ISC_R_SUCCESS) {
10275 UNLOCK_ZONE(zone);
10276 secure = NULL;
10277 isc_thread_yield();
10278 goto again;
10279 }
10280
10281 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10282 if (zone->db != NULL) {
10283 result = zone_get_from_db(zone, zone->db, NULL,
10284 &soacount, &serial,
10285 NULL, NULL, NULL,
10286 NULL, NULL);
10287 } else
10288 result = DNS_R_NOTLOADED;
10289 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10290 if (result == ISC_R_SUCCESS && soacount > 0U)
10291 zone_send_secureserial(zone, serial);
10292 }
10293
10294 /* XXXMPA make separate call back */
10295 if (result == ISC_R_SUCCESS)
10296 set_resigntime(zone);
10297 }
10298 if (secure != NULL)
10299 UNLOCK_ZONE(secure);
10300 zone_needdump(zone, DNS_DUMP_DELAY);
10301 UNLOCK_ZONE(zone);
10302 }
10303
10304 void
10305 dns_zone_expire(dns_zone_t *zone) {
10306 REQUIRE(DNS_ZONE_VALID(zone));
10307
10308 LOCK_ZONE(zone);
10309 zone_expire(zone);
10310 UNLOCK_ZONE(zone);
10311 }
10312
10313 static void
10314 zone_expire(dns_zone_t *zone) {
10315 /*
10316 * 'zone' locked by caller.
10317 */
10318
10319 REQUIRE(LOCKED_ZONE(zone));
10320
10321 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
10322
10323 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
10324 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
10325 zone->retry = DNS_ZONE_DEFAULTRETRY;
10326 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
10327 zone_unload(zone);
10328 }
10329
10330 void
10331 dns_zone_refresh(dns_zone_t *zone) {
10332 isc_interval_t i;
10333 uint32_t oldflags;
10334 unsigned int j;
10335 isc_result_t result;
10336
10337 REQUIRE(DNS_ZONE_VALID(zone));
10338
10339 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
10340 return;
10341
10342 /*
10343 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
10344 * in progress at a time.
10345 */
10346
10347 LOCK_ZONE(zone);
10348 oldflags = zone->flags;
10349 if (zone->masterscnt == 0) {
10350 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
10351 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
10352 dns_zone_log(zone, ISC_LOG_ERROR,
10353 "cannot refresh: no masters");
10354 goto unlock;
10355 }
10356 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
10357 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
10358 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
10359 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
10360 goto unlock;
10361
10362 /*
10363 * Set the next refresh time as if refresh check has failed.
10364 * Setting this to the retry time will do that. XXXMLG
10365 * If we are successful it will be reset using zone->refresh.
10366 */
10367 isc_interval_set(&i, zone->retry - isc_random_uniform(zone->retry / 4),
10368 0);
10369 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
10370 if (result != ISC_R_SUCCESS)
10371 dns_zone_log(zone, ISC_LOG_WARNING,
10372 "isc_time_nowplusinterval() failed: %s",
10373 dns_result_totext(result));
10374
10375 /*
10376 * When lacking user-specified timer values from the SOA,
10377 * do exponential backoff of the retry time up to a
10378 * maximum of six hours.
10379 */
10380 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
10381 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
10382
10383 zone->curmaster = 0;
10384 for (j = 0; j < zone->masterscnt; j++)
10385 zone->mastersok[j] = false;
10386 /* initiate soa query */
10387 queue_soa_query(zone);
10388 unlock:
10389 UNLOCK_ZONE(zone);
10390 }
10391
10392 static void
10393 zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial) {
10394 isc_result_t result;
10395 int32_t journalsize;
10396 dns_dbversion_t *ver = NULL;
10397 uint64_t dbsize;
10398
10399 INSIST(LOCKED_ZONE(zone));
10400 if (inline_raw(zone))
10401 INSIST(LOCKED_ZONE(zone->secure));
10402
10403 journalsize = zone->journalsize;
10404 if (journalsize == -1) {
10405 journalsize = DNS_JOURNAL_SIZE_MAX;
10406 dns_db_currentversion(db, &ver);
10407 result = dns_db_getsize(db, ver, NULL, &dbsize);
10408 dns_db_closeversion(db, &ver, false);
10409 if (result != ISC_R_SUCCESS) {
10410 dns_zone_log(zone, ISC_LOG_ERROR,
10411 "zone_journal_compact: "
10412 "could not get zone size: %s",
10413 isc_result_totext(result));
10414 } else if (dbsize < DNS_JOURNAL_SIZE_MAX / 2) {
10415 journalsize = (int32_t)dbsize * 2;
10416 }
10417 }
10418 zone_debuglog(zone, "zone_journal_compact", 1,
10419 "target journal size %d", journalsize);
10420 result = dns_journal_compact(zone->mctx, zone->journal,
10421 serial, journalsize);
10422 switch (result) {
10423 case ISC_R_SUCCESS:
10424 case ISC_R_NOSPACE:
10425 case ISC_R_NOTFOUND:
10426 dns_zone_log(zone, ISC_LOG_DEBUG(3),
10427 "dns_journal_compact: %s",
10428 dns_result_totext(result));
10429 break;
10430 default:
10431 dns_zone_log(zone, ISC_LOG_ERROR,
10432 "dns_journal_compact failed: %s",
10433 dns_result_totext(result));
10434 break;
10435 }
10436 }
10437
10438 isc_result_t
10439 dns_zone_flush(dns_zone_t *zone) {
10440 isc_result_t result = ISC_R_SUCCESS;
10441 bool dumping;
10442
10443 REQUIRE(DNS_ZONE_VALID(zone));
10444
10445 LOCK_ZONE(zone);
10446 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
10447 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10448 zone->masterfile != NULL) {
10449 result = ISC_R_ALREADYRUNNING;
10450 dumping = was_dumping(zone);
10451 } else
10452 dumping = true;
10453 UNLOCK_ZONE(zone);
10454 if (!dumping)
10455 result = zone_dump(zone, true); /* Unknown task. */
10456 return (result);
10457 }
10458
10459 isc_result_t
10460 dns_zone_dump(dns_zone_t *zone) {
10461 isc_result_t result = ISC_R_ALREADYRUNNING;
10462 bool dumping;
10463
10464 REQUIRE(DNS_ZONE_VALID(zone));
10465
10466 LOCK_ZONE(zone);
10467 dumping = was_dumping(zone);
10468 UNLOCK_ZONE(zone);
10469 if (!dumping)
10470 result = zone_dump(zone, false); /* Unknown task. */
10471 return (result);
10472 }
10473
10474 static void
10475 zone_needdump(dns_zone_t *zone, unsigned int delay) {
10476 const char me[] = "zone_needdump";
10477 isc_time_t dumptime;
10478 isc_time_t now;
10479
10480 /*
10481 * 'zone' locked by caller
10482 */
10483
10484 REQUIRE(DNS_ZONE_VALID(zone));
10485 REQUIRE(LOCKED_ZONE(zone));
10486 ENTER;
10487
10488 /*
10489 * Do we have a place to dump to and are we loaded?
10490 */
10491 if (zone->masterfile == NULL ||
10492 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
10493 return;
10494
10495 TIME_NOW(&now);
10496 /* add some noise */
10497 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
10498
10499 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
10500 if (isc_time_isepoch(&zone->dumptime) ||
10501 isc_time_compare(&zone->dumptime, &dumptime) > 0)
10502 zone->dumptime = dumptime;
10503 if (zone->task != NULL)
10504 zone_settimer(zone, &now);
10505 }
10506
10507 static void
10508 dump_done(void *arg, isc_result_t result) {
10509 const char me[] = "dump_done";
10510 dns_zone_t *zone = arg;
10511 dns_zone_t *secure = NULL;
10512 dns_db_t *db;
10513 dns_dbversion_t *version;
10514 bool again = false;
10515 bool compact = false;
10516 uint32_t serial;
10517 isc_result_t tresult;
10518
10519 REQUIRE(DNS_ZONE_VALID(zone));
10520
10521 ENTER;
10522
10523 if (result == ISC_R_SUCCESS && zone->journal != NULL) {
10524 /*
10525 * We don't own these, zone->dctx must stay valid.
10526 */
10527 db = dns_dumpctx_db(zone->dctx);
10528 version = dns_dumpctx_version(zone->dctx);
10529 tresult = dns_db_getsoaserial(db, version, &serial);
10530
10531 /*
10532 * Handle lock order inversion.
10533 */
10534 again:
10535 LOCK_ZONE(zone);
10536 if (inline_raw(zone)) {
10537 secure = zone->secure;
10538 INSIST(secure != zone);
10539 TRYLOCK_ZONE(result, secure);
10540 if (result != ISC_R_SUCCESS) {
10541 UNLOCK_ZONE(zone);
10542 secure = NULL;
10543 isc_thread_yield();
10544 goto again;
10545 }
10546 }
10547
10548 /*
10549 * If there is a secure version of this zone
10550 * use its serial if it is less than ours.
10551 */
10552 if (tresult == ISC_R_SUCCESS && secure != NULL) {
10553 uint32_t sserial;
10554 isc_result_t mresult;
10555
10556 ZONEDB_LOCK(&secure->dblock, isc_rwlocktype_read);
10557 if (secure->db != NULL) {
10558 mresult = dns_db_getsoaserial(zone->secure->db,
10559 NULL, &sserial);
10560 if (mresult == ISC_R_SUCCESS &&
10561 isc_serial_lt(sserial, serial))
10562 serial = sserial;
10563 }
10564 ZONEDB_UNLOCK(&secure->dblock, isc_rwlocktype_read);
10565 }
10566 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
10567 dns_db_t *zdb = NULL;
10568 if (dns_zone_getdb(zone, &zdb) == ISC_R_SUCCESS) {
10569 zone_journal_compact(zone, zdb, serial);
10570 dns_db_detach(&zdb);
10571 }
10572 } else if (tresult == ISC_R_SUCCESS) {
10573 compact = true;
10574 zone->compact_serial = serial;
10575 }
10576 if (secure != NULL)
10577 UNLOCK_ZONE(secure);
10578 UNLOCK_ZONE(zone);
10579 }
10580
10581 LOCK_ZONE(zone);
10582 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
10583 if (compact)
10584 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
10585 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
10586 /*
10587 * Try again in a short while.
10588 */
10589 zone_needdump(zone, DNS_DUMP_DELAY);
10590 } else if (result == ISC_R_SUCCESS &&
10591 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
10592 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10593 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
10594 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
10595 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
10596 isc_time_settoepoch(&zone->dumptime);
10597 again = true;
10598 } else if (result == ISC_R_SUCCESS)
10599 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
10600
10601 if (zone->dctx != NULL)
10602 dns_dumpctx_detach(&zone->dctx);
10603 zonemgr_putio(&zone->writeio);
10604 UNLOCK_ZONE(zone);
10605 if (again)
10606 (void)zone_dump(zone, false);
10607 dns_zone_idetach(&zone);
10608 }
10609
10610 static isc_result_t
10611 zone_dump(dns_zone_t *zone, bool compact) {
10612 const char me[] = "zone_dump";
10613 isc_result_t result;
10614 dns_dbversion_t *version = NULL;
10615 bool again;
10616 dns_db_t *db = NULL;
10617 char *masterfile = NULL;
10618 dns_masterformat_t masterformat = dns_masterformat_none;
10619
10620 /*
10621 * 'compact' MUST only be set if we are task locked.
10622 */
10623
10624 REQUIRE(DNS_ZONE_VALID(zone));
10625 ENTER;
10626
10627 redo:
10628 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10629 if (zone->db != NULL)
10630 dns_db_attach(zone->db, &db);
10631 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10632 LOCK_ZONE(zone);
10633 if (zone->masterfile != NULL) {
10634 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
10635 masterformat = zone->masterformat;
10636 }
10637 UNLOCK_ZONE(zone);
10638 if (db == NULL) {
10639 result = DNS_R_NOTLOADED;
10640 goto fail;
10641 }
10642 if (masterfile == NULL) {
10643 result = DNS_R_NOMASTERFILE;
10644 goto fail;
10645 }
10646
10647 if (compact && zone->type != dns_zone_stub) {
10648 dns_zone_t *dummy = NULL;
10649 LOCK_ZONE(zone);
10650 zone_iattach(zone, &dummy);
10651 result = zonemgr_getio(zone->zmgr, false, zone->task,
10652 zone_gotwritehandle, zone,
10653 &zone->writeio);
10654 if (result != ISC_R_SUCCESS)
10655 zone_idetach(&dummy);
10656 else
10657 result = DNS_R_CONTINUE;
10658 UNLOCK_ZONE(zone);
10659 } else {
10660 const dns_master_style_t *output_style;
10661
10662 dns_masterrawheader_t rawdata;
10663 dns_db_currentversion(db, &version);
10664 dns_master_initrawheader(&rawdata);
10665 if (inline_secure(zone))
10666 get_raw_serial(zone->raw, &rawdata);
10667 if (zone->type == dns_zone_key)
10668 output_style = &dns_master_style_keyzone;
10669 else
10670 output_style = &dns_master_style_default;
10671 result = dns_master_dump(zone->mctx, db, version,
10672 output_style, masterfile,
10673 masterformat, &rawdata);
10674 dns_db_closeversion(db, &version, false);
10675 }
10676 fail:
10677 if (db != NULL)
10678 dns_db_detach(&db);
10679 if (masterfile != NULL)
10680 isc_mem_free(zone->mctx, masterfile);
10681 masterfile = NULL;
10682
10683 if (result == DNS_R_CONTINUE)
10684 return (ISC_R_SUCCESS); /* XXXMPA */
10685
10686 again = false;
10687 LOCK_ZONE(zone);
10688 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
10689 if (result != ISC_R_SUCCESS) {
10690 /*
10691 * Try again in a short while.
10692 */
10693 zone_needdump(zone, DNS_DUMP_DELAY);
10694 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
10695 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10696 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
10697 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
10698 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
10699 isc_time_settoepoch(&zone->dumptime);
10700 again = true;
10701 } else
10702 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
10703 UNLOCK_ZONE(zone);
10704 if (again)
10705 goto redo;
10706
10707 return (result);
10708 }
10709
10710 static isc_result_t
10711 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
10712 dns_masterformat_t format, const uint32_t rawversion)
10713 {
10714 isc_result_t result;
10715 dns_dbversion_t *version = NULL;
10716 dns_db_t *db = NULL;
10717 dns_masterrawheader_t rawdata;
10718
10719 REQUIRE(DNS_ZONE_VALID(zone));
10720
10721 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10722 if (zone->db != NULL)
10723 dns_db_attach(zone->db, &db);
10724 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10725 if (db == NULL)
10726 return (DNS_R_NOTLOADED);
10727
10728 dns_db_currentversion(db, &version);
10729 dns_master_initrawheader(&rawdata);
10730 if (rawversion == 0)
10731 rawdata.flags |= DNS_MASTERRAW_COMPAT;
10732 else if (inline_secure(zone))
10733 get_raw_serial(zone->raw, &rawdata);
10734 else if (zone->sourceserialset) {
10735 rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
10736 rawdata.sourceserial = zone->sourceserial;
10737 }
10738 result = dns_master_dumptostream(zone->mctx, db, version, style,
10739 format, &rawdata, fd);
10740 dns_db_closeversion(db, &version, false);
10741 dns_db_detach(&db);
10742 return (result);
10743 }
10744
10745 isc_result_t
10746 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
10747 const dns_master_style_t *style,
10748 const uint32_t rawversion)
10749 {
10750 return (dumptostream(zone, fd, style, format, rawversion));
10751 }
10752
10753 void
10754 dns_zone_unload(dns_zone_t *zone) {
10755 REQUIRE(DNS_ZONE_VALID(zone));
10756
10757 LOCK_ZONE(zone);
10758 zone_unload(zone);
10759 UNLOCK_ZONE(zone);
10760 }
10761
10762 static void
10763 notify_cancel(dns_zone_t *zone) {
10764 dns_notify_t *notify;
10765
10766 /*
10767 * 'zone' locked by caller.
10768 */
10769
10770 REQUIRE(LOCKED_ZONE(zone));
10771
10772 for (notify = ISC_LIST_HEAD(zone->notifies);
10773 notify != NULL;
10774 notify = ISC_LIST_NEXT(notify, link)) {
10775 if (notify->find != NULL)
10776 dns_adb_cancelfind(notify->find);
10777 if (notify->request != NULL)
10778 dns_request_cancel(notify->request);
10779 }
10780 }
10781
10782 static void
10783 forward_cancel(dns_zone_t *zone) {
10784 dns_forward_t *forward;
10785
10786 /*
10787 * 'zone' locked by caller.
10788 */
10789
10790 REQUIRE(LOCKED_ZONE(zone));
10791
10792 for (forward = ISC_LIST_HEAD(zone->forwards);
10793 forward != NULL;
10794 forward = ISC_LIST_NEXT(forward, link)) {
10795 if (forward->request != NULL)
10796 dns_request_cancel(forward->request);
10797 }
10798 }
10799
10800 static void
10801 zone_unload(dns_zone_t *zone) {
10802 /*
10803 * 'zone' locked by caller.
10804 */
10805
10806 REQUIRE(LOCKED_ZONE(zone));
10807
10808 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
10809 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10810 if (zone->writeio != NULL)
10811 zonemgr_cancelio(zone->writeio);
10812
10813 if (zone->dctx != NULL)
10814 dns_dumpctx_cancel(zone->dctx);
10815 }
10816 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
10817 zone_detachdb(zone);
10818 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
10819 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
10820 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
10821 }
10822
10823 void
10824 dns_zone_setminrefreshtime(dns_zone_t *zone, uint32_t val) {
10825 REQUIRE(DNS_ZONE_VALID(zone));
10826 REQUIRE(val > 0);
10827
10828 zone->minrefresh = val;
10829 }
10830
10831 void
10832 dns_zone_setmaxrefreshtime(dns_zone_t *zone, uint32_t val) {
10833 REQUIRE(DNS_ZONE_VALID(zone));
10834 REQUIRE(val > 0);
10835
10836 zone->maxrefresh = val;
10837 }
10838
10839 void
10840 dns_zone_setminretrytime(dns_zone_t *zone, uint32_t val) {
10841 REQUIRE(DNS_ZONE_VALID(zone));
10842 REQUIRE(val > 0);
10843
10844 zone->minretry = val;
10845 }
10846
10847 void
10848 dns_zone_setmaxretrytime(dns_zone_t *zone, uint32_t val) {
10849 REQUIRE(DNS_ZONE_VALID(zone));
10850 REQUIRE(val > 0);
10851
10852 zone->maxretry = val;
10853 }
10854
10855 uint32_t
10856 dns_zone_getmaxrecords(dns_zone_t *zone) {
10857 REQUIRE(DNS_ZONE_VALID(zone));
10858
10859 return (zone->maxrecords);
10860 }
10861
10862 void
10863 dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) {
10864 REQUIRE(DNS_ZONE_VALID(zone));
10865
10866 zone->maxrecords = val;
10867 }
10868
10869 static bool
10870 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
10871 isc_sockaddr_t *addr, dns_tsigkey_t *key)
10872 {
10873 dns_notify_t *notify;
10874 dns_zonemgr_t *zmgr;
10875 isc_result_t result;
10876
10877 for (notify = ISC_LIST_HEAD(zone->notifies);
10878 notify != NULL;
10879 notify = ISC_LIST_NEXT(notify, link)) {
10880 if (notify->request != NULL)
10881 continue;
10882 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
10883 dns_name_equal(name, ¬ify->ns))
10884 goto requeue;
10885 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst) &&
10886 notify->key == key)
10887 goto requeue;
10888 }
10889 return (false);
10890
10891 requeue:
10892 /*
10893 * If we are enqueued on the startup ratelimiter and this is
10894 * not a startup notify, re-enqueue on the normal notify
10895 * ratelimiter.
10896 */
10897 if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0 &&
10898 (notify->flags & DNS_NOTIFY_STARTUP) != 0) {
10899 zmgr = notify->zone->zmgr;
10900 result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl,
10901 notify->event);
10902 if (result != ISC_R_SUCCESS)
10903 return (true);
10904
10905 notify->flags &= ~DNS_NOTIFY_STARTUP;
10906 result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
10907 notify->zone->task,
10908 ¬ify->event);
10909 if (result != ISC_R_SUCCESS) {
10910 isc_event_free(¬ify->event);
10911 return (false);
10912 }
10913 }
10914
10915 return (true);
10916 }
10917
10918 static bool
10919 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
10920 dns_tsigkey_t *key = NULL;
10921 isc_sockaddr_t src;
10922 isc_sockaddr_t any;
10923 bool isself;
10924 isc_netaddr_t dstaddr;
10925 isc_result_t result;
10926
10927 if (zone->view == NULL || zone->isself == NULL)
10928 return (false);
10929
10930 switch (isc_sockaddr_pf(dst)) {
10931 case PF_INET:
10932 src = zone->notifysrc4;
10933 isc_sockaddr_any(&any);
10934 break;
10935 case PF_INET6:
10936 src = zone->notifysrc6;
10937 isc_sockaddr_any6(&any);
10938 break;
10939 default:
10940 return (false);
10941 }
10942
10943 /*
10944 * When sending from any the kernel will assign a source address
10945 * that matches the destination address.
10946 */
10947 if (isc_sockaddr_eqaddr(&any, &src))
10948 src = *dst;
10949
10950 isc_netaddr_fromsockaddr(&dstaddr, dst);
10951 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
10952 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
10953 return (false);
10954 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
10955 zone->isselfarg);
10956 if (key != NULL)
10957 dns_tsigkey_detach(&key);
10958 return (isself);
10959 }
10960
10961 static void
10962 notify_destroy(dns_notify_t *notify, bool locked) {
10963 isc_mem_t *mctx;
10964
10965 REQUIRE(DNS_NOTIFY_VALID(notify));
10966
10967 if (notify->zone != NULL) {
10968 if (!locked)
10969 LOCK_ZONE(notify->zone);
10970 REQUIRE(LOCKED_ZONE(notify->zone));
10971 if (ISC_LINK_LINKED(notify, link))
10972 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
10973 if (!locked)
10974 UNLOCK_ZONE(notify->zone);
10975 if (locked)
10976 zone_idetach(¬ify->zone);
10977 else
10978 dns_zone_idetach(¬ify->zone);
10979 }
10980 if (notify->find != NULL)
10981 dns_adb_destroyfind(¬ify->find);
10982 if (notify->request != NULL)
10983 dns_request_destroy(¬ify->request);
10984 if (dns_name_dynamic(¬ify->ns))
10985 dns_name_free(¬ify->ns, notify->mctx);
10986 if (notify->key != NULL)
10987 dns_tsigkey_detach(¬ify->key);
10988 mctx = notify->mctx;
10989 isc_mem_put(notify->mctx, notify, sizeof(*notify));
10990 isc_mem_detach(&mctx);
10991 }
10992
10993 static isc_result_t
10994 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
10995 dns_notify_t *notify;
10996
10997 REQUIRE(notifyp != NULL && *notifyp == NULL);
10998
10999 notify = isc_mem_get(mctx, sizeof(*notify));
11000 if (notify == NULL)
11001 return (ISC_R_NOMEMORY);
11002
11003 notify->mctx = NULL;
11004 isc_mem_attach(mctx, ¬ify->mctx);
11005 notify->flags = flags;
11006 notify->zone = NULL;
11007 notify->find = NULL;
11008 notify->request = NULL;
11009 notify->key = NULL;
11010 notify->event = NULL;
11011 isc_sockaddr_any(¬ify->dst);
11012 dns_name_init(¬ify->ns, NULL);
11013 ISC_LINK_INIT(notify, link);
11014 notify->magic = NOTIFY_MAGIC;
11015 *notifyp = notify;
11016 return (ISC_R_SUCCESS);
11017 }
11018
11019 /*
11020 * XXXAG should check for DNS_ZONEFLG_EXITING
11021 */
11022 static void
11023 process_adb_event(isc_task_t *task, isc_event_t *ev) {
11024 dns_notify_t *notify;
11025 isc_eventtype_t result;
11026
11027 UNUSED(task);
11028
11029 notify = ev->ev_arg;
11030 REQUIRE(DNS_NOTIFY_VALID(notify));
11031 INSIST(task == notify->zone->task);
11032 result = ev->ev_type;
11033 isc_event_free(&ev);
11034 if (result == DNS_EVENT_ADBMOREADDRESSES) {
11035 dns_adb_destroyfind(¬ify->find);
11036 notify_find_address(notify);
11037 return;
11038 }
11039 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
11040 LOCK_ZONE(notify->zone);
11041 notify_send(notify);
11042 UNLOCK_ZONE(notify->zone);
11043 }
11044 notify_destroy(notify, false);
11045 }
11046
11047 static void
11048 notify_find_address(dns_notify_t *notify) {
11049 isc_result_t result;
11050 unsigned int options;
11051
11052 REQUIRE(DNS_NOTIFY_VALID(notify));
11053 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
11054 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
11055
11056 if (notify->zone->view->adb == NULL)
11057 goto destroy;
11058
11059 result = dns_adb_createfind(notify->zone->view->adb,
11060 notify->zone->task,
11061 process_adb_event, notify,
11062 ¬ify->ns, dns_rootname, 0,
11063 options, 0, NULL,
11064 notify->zone->view->dstport,
11065 0, NULL, ¬ify->find);
11066
11067 /* Something failed? */
11068 if (result != ISC_R_SUCCESS)
11069 goto destroy;
11070
11071 /* More addresses pending? */
11072 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
11073 return;
11074
11075 /* We have as many addresses as we can get. */
11076 LOCK_ZONE(notify->zone);
11077 notify_send(notify);
11078 UNLOCK_ZONE(notify->zone);
11079
11080 destroy:
11081 notify_destroy(notify, false);
11082 }
11083
11084
11085 static isc_result_t
11086 notify_send_queue(dns_notify_t *notify, bool startup) {
11087 isc_event_t *e;
11088 isc_result_t result;
11089
11090 INSIST(notify->event == NULL);
11091 e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR,
11092 notify_send_toaddr, notify, sizeof(isc_event_t));
11093 if (e == NULL)
11094 return (ISC_R_NOMEMORY);
11095 if (startup)
11096 notify->event = e;
11097 e->ev_arg = notify;
11098 e->ev_sender = NULL;
11099 result = isc_ratelimiter_enqueue(startup
11100 ? notify->zone->zmgr->startupnotifyrl
11101 : notify->zone->zmgr->notifyrl,
11102 notify->zone->task, &e);
11103 if (result != ISC_R_SUCCESS) {
11104 isc_event_free(&e);
11105 notify->event = NULL;
11106 }
11107 return (result);
11108 }
11109
11110 static void
11111 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
11112 dns_notify_t *notify;
11113 isc_result_t result;
11114 dns_message_t *message = NULL;
11115 isc_netaddr_t dstip;
11116 dns_tsigkey_t *key = NULL;
11117 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
11118 isc_sockaddr_t src;
11119 unsigned int options, timeout;
11120 bool have_notifysource = false;
11121 bool have_notifydscp = false;
11122 isc_dscp_t dscp = -1;
11123
11124 notify = event->ev_arg;
11125 REQUIRE(DNS_NOTIFY_VALID(notify));
11126
11127 UNUSED(task);
11128
11129 LOCK_ZONE(notify->zone);
11130
11131 notify->event = NULL;
11132
11133 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
11134 result = ISC_R_CANCELED;
11135 goto cleanup;
11136 }
11137
11138 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
11139 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
11140 notify->zone->view->requestmgr == NULL ||
11141 notify->zone->db == NULL) {
11142 result = ISC_R_CANCELED;
11143 goto cleanup;
11144 }
11145
11146 /*
11147 * The raw IPv4 address should also exist. Don't send to the
11148 * mapped form.
11149 */
11150 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
11151 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
11152 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
11153 notify_log(notify->zone, ISC_LOG_DEBUG(3),
11154 "notify: ignoring IPv6 mapped IPV4 address: %s",
11155 addrbuf);
11156 result = ISC_R_CANCELED;
11157 goto cleanup;
11158 }
11159
11160 result = notify_createmessage(notify->zone, notify->flags, &message);
11161 if (result != ISC_R_SUCCESS)
11162 goto cleanup;
11163
11164 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
11165 if (notify->key != NULL) {
11166 /* Transfer ownership of key */
11167 key = notify->key;
11168 notify->key = NULL;
11169 } else {
11170 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
11171 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
11172 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
11173 notify_log(notify->zone, ISC_LOG_ERROR,
11174 "NOTIFY to %s not sent. "
11175 "Peer TSIG key lookup failure.", addrbuf);
11176 goto cleanup_message;
11177 }
11178 }
11179
11180 /* XXX: should we log the tsig key too? */
11181 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
11182 addrbuf);
11183 options = 0;
11184 if (notify->zone->view->peers != NULL) {
11185 dns_peer_t *peer = NULL;
11186 bool usetcp = false;
11187 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
11188 &dstip, &peer);
11189 if (result == ISC_R_SUCCESS) {
11190 result = dns_peer_getnotifysource(peer, &src);
11191 if (result == ISC_R_SUCCESS)
11192 have_notifysource = true;
11193 dns_peer_getnotifydscp(peer, &dscp);
11194 if (dscp != -1)
11195 have_notifydscp = true;
11196 result = dns_peer_getforcetcp(peer, &usetcp);
11197 if (result == ISC_R_SUCCESS && usetcp)
11198 options |= DNS_FETCHOPT_TCP;
11199 }
11200 }
11201 switch (isc_sockaddr_pf(¬ify->dst)) {
11202 case PF_INET:
11203 if (!have_notifysource)
11204 src = notify->zone->notifysrc4;
11205 if (!have_notifydscp)
11206 dscp = notify->zone->notifysrc4dscp;
11207 break;
11208 case PF_INET6:
11209 if (!have_notifysource)
11210 src = notify->zone->notifysrc6;
11211 if (!have_notifydscp)
11212 dscp = notify->zone->notifysrc6dscp;
11213 break;
11214 default:
11215 result = ISC_R_NOTIMPLEMENTED;
11216 goto cleanup_key;
11217 }
11218 timeout = 15;
11219 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
11220 timeout = 30;
11221 result = dns_request_createvia(notify->zone->view->requestmgr,
11222 message, &src, ¬ify->dst, dscp,
11223 options, key, timeout * 3, timeout,
11224 0, notify->zone->task, notify_done,
11225 notify, ¬ify->request);
11226 if (result == ISC_R_SUCCESS) {
11227 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
11228 inc_stats(notify->zone,
11229 dns_zonestatscounter_notifyoutv4);
11230 } else {
11231 inc_stats(notify->zone,
11232 dns_zonestatscounter_notifyoutv6);
11233 }
11234 }
11235
11236 cleanup_key:
11237 if (key != NULL)
11238 dns_tsigkey_detach(&key);
11239 cleanup_message:
11240 dns_message_destroy(&message);
11241 cleanup:
11242 UNLOCK_ZONE(notify->zone);
11243 isc_event_free(&event);
11244 if (result != ISC_R_SUCCESS)
11245 notify_destroy(notify, false);
11246 }
11247
11248 static void
11249 notify_send(dns_notify_t *notify) {
11250 dns_adbaddrinfo_t *ai;
11251 isc_sockaddr_t dst;
11252 isc_result_t result;
11253 dns_notify_t *newnotify = NULL;
11254 unsigned int flags;
11255 bool startup;
11256
11257 /*
11258 * Zone lock held by caller.
11259 */
11260 REQUIRE(DNS_NOTIFY_VALID(notify));
11261 REQUIRE(LOCKED_ZONE(notify->zone));
11262
11263 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING))
11264 return;
11265
11266 for (ai = ISC_LIST_HEAD(notify->find->list);
11267 ai != NULL;
11268 ai = ISC_LIST_NEXT(ai, publink)) {
11269 dst = ai->sockaddr;
11270 if (notify_isqueued(notify->zone, notify->flags, NULL, &dst,
11271 NULL))
11272 continue;
11273 if (notify_isself(notify->zone, &dst))
11274 continue;
11275 newnotify = NULL;
11276 flags = notify->flags & DNS_NOTIFY_NOSOA;
11277 result = notify_create(notify->mctx, flags, &newnotify);
11278 if (result != ISC_R_SUCCESS)
11279 goto cleanup;
11280 zone_iattach(notify->zone, &newnotify->zone);
11281 ISC_LIST_APPEND(newnotify->zone->notifies, newnotify, link);
11282 newnotify->dst = dst;
11283 startup = ((notify->flags & DNS_NOTIFY_STARTUP) != 0);
11284 result = notify_send_queue(newnotify, startup);
11285 if (result != ISC_R_SUCCESS)
11286 goto cleanup;
11287 newnotify = NULL;
11288 }
11289
11290 cleanup:
11291 if (newnotify != NULL)
11292 notify_destroy(newnotify, true);
11293 }
11294
11295 void
11296 dns_zone_notify(dns_zone_t *zone) {
11297 isc_time_t now;
11298
11299 REQUIRE(DNS_ZONE_VALID(zone));
11300
11301 LOCK_ZONE(zone);
11302 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
11303
11304 TIME_NOW(&now);
11305 zone_settimer(zone, &now);
11306 UNLOCK_ZONE(zone);
11307 }
11308
11309 static void
11310 zone_notify(dns_zone_t *zone, isc_time_t *now) {
11311 dns_dbnode_t *node = NULL;
11312 dns_db_t *zonedb = NULL;
11313 dns_dbversion_t *version = NULL;
11314 dns_name_t *origin = NULL;
11315 dns_name_t master;
11316 dns_rdata_ns_t ns;
11317 dns_rdata_soa_t soa;
11318 uint32_t serial;
11319 dns_rdata_t rdata = DNS_RDATA_INIT;
11320 dns_rdataset_t nsrdset;
11321 dns_rdataset_t soardset;
11322 isc_result_t result;
11323 unsigned int i;
11324 isc_sockaddr_t dst;
11325 bool isqueued;
11326 dns_notifytype_t notifytype;
11327 unsigned int flags = 0;
11328 bool loggednotify = false;
11329 bool startup;
11330
11331 REQUIRE(DNS_ZONE_VALID(zone));
11332
11333 LOCK_ZONE(zone);
11334 startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
11335 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
11336 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
11337 notifytype = zone->notifytype;
11338 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
11339 UNLOCK_ZONE(zone);
11340
11341 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
11342 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
11343 return;
11344
11345 if (notifytype == dns_notifytype_no)
11346 return;
11347
11348 if (notifytype == dns_notifytype_masteronly &&
11349 zone->type != dns_zone_master)
11350 return;
11351
11352 origin = &zone->origin;
11353
11354 /*
11355 * If the zone is dialup we are done as we don't want to send
11356 * the current soa so as to force a refresh query.
11357 */
11358 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
11359 flags |= DNS_NOTIFY_NOSOA;
11360
11361 /*
11362 * Record that this was a notify due to starting up.
11363 */
11364 if (startup)
11365 flags |= DNS_NOTIFY_STARTUP;
11366
11367 /*
11368 * Get SOA RRset.
11369 */
11370 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11371 if (zone->db != NULL)
11372 dns_db_attach(zone->db, &zonedb);
11373 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11374 if (zonedb == NULL)
11375 return;
11376 dns_db_currentversion(zonedb, &version);
11377 result = dns_db_findnode(zonedb, origin, false, &node);
11378 if (result != ISC_R_SUCCESS)
11379 goto cleanup1;
11380
11381 dns_rdataset_init(&soardset);
11382 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
11383 dns_rdatatype_none, 0, &soardset, NULL);
11384 if (result != ISC_R_SUCCESS)
11385 goto cleanup2;
11386
11387 /*
11388 * Find serial and master server's name.
11389 */
11390 dns_name_init(&master, NULL);
11391 result = dns_rdataset_first(&soardset);
11392 if (result != ISC_R_SUCCESS)
11393 goto cleanup3;
11394 dns_rdataset_current(&soardset, &rdata);
11395 result = dns_rdata_tostruct(&rdata, &soa, NULL);
11396 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11397 dns_rdata_reset(&rdata);
11398 result = dns_name_dup(&soa.origin, zone->mctx, &master);
11399 serial = soa.serial;
11400 dns_rdataset_disassociate(&soardset);
11401 if (result != ISC_R_SUCCESS)
11402 goto cleanup3;
11403
11404 /*
11405 * Enqueue notify requests for 'also-notify' servers.
11406 */
11407 LOCK_ZONE(zone);
11408 for (i = 0; i < zone->notifycnt; i++) {
11409 dns_tsigkey_t *key = NULL;
11410 dns_notify_t *notify = NULL;
11411
11412 if ((zone->notifykeynames != NULL) &&
11413 (zone->notifykeynames[i] != NULL)) {
11414 dns_view_t *view = dns_zone_getview(zone);
11415 dns_name_t *keyname = zone->notifykeynames[i];
11416 (void)dns_view_gettsig(view, keyname, &key);
11417 }
11418
11419 dst = zone->notify[i];
11420 if (notify_isqueued(zone, flags, NULL, &dst, key)) {
11421 if (key != NULL)
11422 dns_tsigkey_detach(&key);
11423 continue;
11424 }
11425
11426 result = notify_create(zone->mctx, flags, ¬ify);
11427 if (result != ISC_R_SUCCESS) {
11428 if (key != NULL)
11429 dns_tsigkey_detach(&key);
11430 continue;
11431 }
11432
11433 zone_iattach(zone, ¬ify->zone);
11434 notify->dst = dst;
11435
11436 INSIST(notify->key == NULL);
11437
11438 if (key != NULL) {
11439 notify->key = key;
11440 key = NULL;
11441 }
11442
11443 ISC_LIST_APPEND(zone->notifies, notify, link);
11444 result = notify_send_queue(notify, startup);
11445 if (result != ISC_R_SUCCESS)
11446 notify_destroy(notify, true);
11447 if (!loggednotify) {
11448 notify_log(zone, ISC_LOG_INFO,
11449 "sending notifies (serial %u)",
11450 serial);
11451 loggednotify = true;
11452 }
11453 }
11454 UNLOCK_ZONE(zone);
11455
11456 if (notifytype == dns_notifytype_explicit)
11457 goto cleanup3;
11458
11459 /*
11460 * Process NS RRset to generate notifies.
11461 */
11462
11463 dns_rdataset_init(&nsrdset);
11464 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
11465 dns_rdatatype_none, 0, &nsrdset, NULL);
11466 if (result != ISC_R_SUCCESS)
11467 goto cleanup3;
11468
11469 result = dns_rdataset_first(&nsrdset);
11470 while (result == ISC_R_SUCCESS) {
11471 dns_notify_t *notify = NULL;
11472
11473 dns_rdataset_current(&nsrdset, &rdata);
11474 result = dns_rdata_tostruct(&rdata, &ns, NULL);
11475 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11476 dns_rdata_reset(&rdata);
11477 /*
11478 * Don't notify the master server unless explicitly
11479 * configured to do so.
11480 */
11481 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
11482 dns_name_compare(&master, &ns.name) == 0) {
11483 result = dns_rdataset_next(&nsrdset);
11484 continue;
11485 }
11486
11487 if (!loggednotify) {
11488 notify_log(zone, ISC_LOG_INFO,
11489 "sending notifies (serial %u)",
11490 serial);
11491 loggednotify = true;
11492 }
11493
11494 LOCK_ZONE(zone);
11495 isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL);
11496 UNLOCK_ZONE(zone);
11497 if (isqueued) {
11498 result = dns_rdataset_next(&nsrdset);
11499 continue;
11500 }
11501 result = notify_create(zone->mctx, flags, ¬ify);
11502 if (result != ISC_R_SUCCESS)
11503 continue;
11504 dns_zone_iattach(zone, ¬ify->zone);
11505 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
11506 if (result != ISC_R_SUCCESS) {
11507 LOCK_ZONE(zone);
11508 notify_destroy(notify, true);
11509 UNLOCK_ZONE(zone);
11510 continue;
11511 }
11512 LOCK_ZONE(zone);
11513 ISC_LIST_APPEND(zone->notifies, notify, link);
11514 UNLOCK_ZONE(zone);
11515 notify_find_address(notify);
11516 result = dns_rdataset_next(&nsrdset);
11517 }
11518 dns_rdataset_disassociate(&nsrdset);
11519
11520 cleanup3:
11521 if (dns_name_dynamic(&master))
11522 dns_name_free(&master, zone->mctx);
11523 cleanup2:
11524 dns_db_detachnode(zonedb, &node);
11525 cleanup1:
11526 dns_db_closeversion(zonedb, &version, false);
11527 dns_db_detach(&zonedb);
11528 }
11529
11530 /***
11531 *** Private
11532 ***/
11533
11534 static inline isc_result_t
11535 save_nsrrset(dns_message_t *message, dns_name_t *name,
11536 dns_db_t *db, dns_dbversion_t *version)
11537 {
11538 dns_rdataset_t *nsrdataset = NULL;
11539 dns_rdataset_t *rdataset = NULL;
11540 dns_dbnode_t *node = NULL;
11541 dns_rdata_ns_t ns;
11542 isc_result_t result;
11543 dns_rdata_t rdata = DNS_RDATA_INIT;
11544
11545 /*
11546 * Extract NS RRset from message.
11547 */
11548 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
11549 dns_rdatatype_ns, dns_rdatatype_none,
11550 NULL, &nsrdataset);
11551 if (result != ISC_R_SUCCESS)
11552 goto fail;
11553
11554 /*
11555 * Add NS rdataset.
11556 */
11557 result = dns_db_findnode(db, name, true, &node);
11558 if (result != ISC_R_SUCCESS)
11559 goto fail;
11560 result = dns_db_addrdataset(db, node, version, 0,
11561 nsrdataset, 0, NULL);
11562 dns_db_detachnode(db, &node);
11563 if (result != ISC_R_SUCCESS)
11564 goto fail;
11565 /*
11566 * Add glue rdatasets.
11567 */
11568 for (result = dns_rdataset_first(nsrdataset);
11569 result == ISC_R_SUCCESS;
11570 result = dns_rdataset_next(nsrdataset)) {
11571 dns_rdataset_current(nsrdataset, &rdata);
11572 result = dns_rdata_tostruct(&rdata, &ns, NULL);
11573 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11574 dns_rdata_reset(&rdata);
11575 if (!dns_name_issubdomain(&ns.name, name))
11576 continue;
11577 rdataset = NULL;
11578 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
11579 &ns.name, dns_rdatatype_aaaa,
11580 dns_rdatatype_none, NULL,
11581 &rdataset);
11582 if (result == ISC_R_SUCCESS) {
11583 result = dns_db_findnode(db, &ns.name,
11584 true, &node);
11585 if (result != ISC_R_SUCCESS)
11586 goto fail;
11587 result = dns_db_addrdataset(db, node, version, 0,
11588 rdataset, 0, NULL);
11589 dns_db_detachnode(db, &node);
11590 if (result != ISC_R_SUCCESS)
11591 goto fail;
11592 }
11593 rdataset = NULL;
11594 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
11595 &ns.name, dns_rdatatype_a,
11596 dns_rdatatype_none, NULL,
11597 &rdataset);
11598 if (result == ISC_R_SUCCESS) {
11599 result = dns_db_findnode(db, &ns.name,
11600 true, &node);
11601 if (result != ISC_R_SUCCESS)
11602 goto fail;
11603 result = dns_db_addrdataset(db, node, version, 0,
11604 rdataset, 0, NULL);
11605 dns_db_detachnode(db, &node);
11606 if (result != ISC_R_SUCCESS)
11607 goto fail;
11608 }
11609 }
11610 if (result != ISC_R_NOMORE)
11611 goto fail;
11612
11613 return (ISC_R_SUCCESS);
11614
11615 fail:
11616 return (result);
11617 }
11618
11619 static void
11620 stub_callback(isc_task_t *task, isc_event_t *event) {
11621 const char me[] = "stub_callback";
11622 dns_requestevent_t *revent = (dns_requestevent_t *)event;
11623 dns_stub_t *stub = NULL;
11624 dns_message_t *msg = NULL;
11625 dns_zone_t *zone = NULL;
11626 char master[ISC_SOCKADDR_FORMATSIZE];
11627 char source[ISC_SOCKADDR_FORMATSIZE];
11628 uint32_t nscnt, cnamecnt, refresh, retry, expire;
11629 isc_result_t result;
11630 isc_time_t now;
11631 bool exiting = false;
11632 isc_interval_t i;
11633 unsigned int j, soacount;
11634
11635 stub = revent->ev_arg;
11636 INSIST(DNS_STUB_VALID(stub));
11637
11638 UNUSED(task);
11639
11640 zone = stub->zone;
11641
11642 ENTER;
11643
11644 TIME_NOW(&now);
11645
11646 LOCK_ZONE(zone);
11647
11648 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
11649 zone_debuglog(zone, me, 1, "exiting");
11650 exiting = true;
11651 goto next_master;
11652 }
11653
11654 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
11655 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
11656
11657 if (revent->result != ISC_R_SUCCESS) {
11658 if (revent->result == ISC_R_TIMEDOUT &&
11659 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
11660 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11661 dns_zone_log(zone, ISC_LOG_DEBUG(1),
11662 "refreshing stub: timeout retrying "
11663 " without EDNS master %s (source %s)",
11664 master, source);
11665 goto same_master;
11666 }
11667 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
11668 &zone->sourceaddr, &now);
11669 dns_zone_log(zone, ISC_LOG_INFO,
11670 "could not refresh stub from master %s"
11671 " (source %s): %s", master, source,
11672 dns_result_totext(revent->result));
11673 goto next_master;
11674 }
11675
11676 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
11677 if (result != ISC_R_SUCCESS)
11678 goto next_master;
11679
11680 result = dns_request_getresponse(revent->request, msg, 0);
11681 if (result != ISC_R_SUCCESS)
11682 goto next_master;
11683
11684 /*
11685 * Unexpected rcode.
11686 */
11687 if (msg->rcode != dns_rcode_noerror) {
11688 char rcode[128];
11689 isc_buffer_t rb;
11690
11691 isc_buffer_init(&rb, rcode, sizeof(rcode));
11692 (void)dns_rcode_totext(msg->rcode, &rb);
11693
11694 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
11695 (msg->rcode == dns_rcode_servfail ||
11696 msg->rcode == dns_rcode_notimp ||
11697 msg->rcode == dns_rcode_formerr)) {
11698 dns_zone_log(zone, ISC_LOG_DEBUG(1),
11699 "refreshing stub: rcode (%.*s) retrying "
11700 "without EDNS master %s (source %s)",
11701 (int)rb.used, rcode, master, source);
11702 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
11703 goto same_master;
11704 }
11705
11706 dns_zone_log(zone, ISC_LOG_INFO,
11707 "refreshing stub: "
11708 "unexpected rcode (%.*s) from %s (source %s)",
11709 (int)rb.used, rcode, master, source);
11710 goto next_master;
11711 }
11712
11713 /*
11714 * We need complete messages.
11715 */
11716 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
11717 if (dns_request_usedtcp(revent->request)) {
11718 dns_zone_log(zone, ISC_LOG_INFO,
11719 "refreshing stub: truncated TCP "
11720 "response from master %s (source %s)",
11721 master, source);
11722 goto next_master;
11723 }
11724 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
11725 goto same_master;
11726 }
11727
11728 /*
11729 * If non-auth log and next master.
11730 */
11731 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
11732 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
11733 "non-authoritative answer from "
11734 "master %s (source %s)", master, source);
11735 goto next_master;
11736 }
11737
11738 /*
11739 * Sanity checks.
11740 */
11741 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
11742 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
11743
11744 if (cnamecnt != 0) {
11745 dns_zone_log(zone, ISC_LOG_INFO,
11746 "refreshing stub: unexpected CNAME response "
11747 "from master %s (source %s)", master, source);
11748 goto next_master;
11749 }
11750
11751 if (nscnt == 0) {
11752 dns_zone_log(zone, ISC_LOG_INFO,
11753 "refreshing stub: no NS records in response "
11754 "from master %s (source %s)", master, source);
11755 goto next_master;
11756 }
11757
11758 /*
11759 * Save answer.
11760 */
11761 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
11762 if (result != ISC_R_SUCCESS) {
11763 dns_zone_log(zone, ISC_LOG_INFO,
11764 "refreshing stub: unable to save NS records "
11765 "from master %s (source %s)", master, source);
11766 goto next_master;
11767 }
11768
11769 /*
11770 * Tidy up.
11771 */
11772 dns_db_closeversion(stub->db, &stub->version, true);
11773 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
11774 if (zone->db == NULL)
11775 zone_attachdb(zone, stub->db);
11776 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
11777 &refresh, &retry, &expire, NULL, NULL);
11778 if (result == ISC_R_SUCCESS && soacount > 0U) {
11779 zone->refresh = RANGE(refresh, zone->minrefresh,
11780 zone->maxrefresh);
11781 zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
11782 zone->expire = RANGE(expire, zone->refresh + zone->retry,
11783 DNS_MAX_EXPIRE);
11784 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
11785 }
11786 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
11787 dns_db_detach(&stub->db);
11788
11789 dns_message_destroy(&msg);
11790 isc_event_free(&event);
11791 dns_request_destroy(&zone->request);
11792
11793 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11794 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
11795 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
11796 isc_interval_set(&i, zone->expire, 0);
11797 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
11798
11799 if (zone->masterfile != NULL)
11800 zone_needdump(zone, 0);
11801
11802 zone_settimer(zone, &now);
11803 goto free_stub;
11804
11805 next_master:
11806 if (stub->version != NULL)
11807 dns_db_closeversion(stub->db, &stub->version, false);
11808 if (stub->db != NULL)
11809 dns_db_detach(&stub->db);
11810 if (msg != NULL)
11811 dns_message_destroy(&msg);
11812 isc_event_free(&event);
11813 dns_request_destroy(&zone->request);
11814 /*
11815 * Skip to next failed / untried master.
11816 */
11817 do {
11818 zone->curmaster++;
11819 } while (zone->curmaster < zone->masterscnt &&
11820 zone->mastersok[zone->curmaster]);
11821 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
11822 if (exiting || zone->curmaster >= zone->masterscnt) {
11823 bool done = true;
11824 if (!exiting &&
11825 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
11826 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11827 /*
11828 * Did we get a good answer from all the masters?
11829 */
11830 for (j = 0; j < zone->masterscnt; j++)
11831 if (zone->mastersok[j] == false) {
11832 done = false;
11833 break;
11834 }
11835 } else
11836 done = true;
11837 if (!done) {
11838 zone->curmaster = 0;
11839 /*
11840 * Find the next failed master.
11841 */
11842 while (zone->curmaster < zone->masterscnt &&
11843 zone->mastersok[zone->curmaster])
11844 zone->curmaster++;
11845 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11846 } else {
11847 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11848
11849 zone_settimer(zone, &now);
11850 goto free_stub;
11851 }
11852 }
11853 queue_soa_query(zone);
11854 goto free_stub;
11855
11856 same_master:
11857 if (msg != NULL)
11858 dns_message_destroy(&msg);
11859 isc_event_free(&event);
11860 dns_request_destroy(&zone->request);
11861 ns_query(zone, NULL, stub);
11862 UNLOCK_ZONE(zone);
11863 goto done;
11864
11865 free_stub:
11866 UNLOCK_ZONE(zone);
11867 stub->magic = 0;
11868 dns_zone_idetach(&stub->zone);
11869 INSIST(stub->db == NULL);
11870 INSIST(stub->version == NULL);
11871 isc_mem_put(stub->mctx, stub, sizeof(*stub));
11872
11873 done:
11874 INSIST(event == NULL);
11875 return;
11876 }
11877
11878 /*
11879 * Get the EDNS EXPIRE option from the response and if it exists trim
11880 * expire to be not more than it.
11881 */
11882 static void
11883 get_edns_expire(dns_zone_t * zone, dns_message_t *message,
11884 uint32_t *expirep)
11885 {
11886 isc_result_t result;
11887 uint32_t expire;
11888 dns_rdata_t rdata = DNS_RDATA_INIT;
11889 isc_buffer_t optbuf;
11890 uint16_t optcode;
11891 uint16_t optlen;
11892
11893 REQUIRE(expirep != NULL);
11894 REQUIRE(message != NULL);
11895
11896 if (message->opt == NULL)
11897 return;
11898
11899 result = dns_rdataset_first(message->opt);
11900 if (result == ISC_R_SUCCESS) {
11901 dns_rdataset_current(message->opt, &rdata);
11902 isc_buffer_init(&optbuf, rdata.data, rdata.length);
11903 isc_buffer_add(&optbuf, rdata.length);
11904 while (isc_buffer_remaininglength(&optbuf) >= 4) {
11905 optcode = isc_buffer_getuint16(&optbuf);
11906 optlen = isc_buffer_getuint16(&optbuf);
11907 /*
11908 * A EDNS EXPIRE response has a length of 4.
11909 */
11910 if (optcode != DNS_OPT_EXPIRE || optlen != 4) {
11911 isc_buffer_forward(&optbuf, optlen);
11912 continue;
11913 }
11914 expire = isc_buffer_getuint32(&optbuf);
11915 dns_zone_log(zone, ISC_LOG_DEBUG(1),
11916 "got EDNS EXPIRE of %u", expire);
11917 /*
11918 * Trim *expirep?
11919 */
11920 if (expire < *expirep)
11921 *expirep = expire;
11922 break;
11923 }
11924 }
11925 }
11926
11927 /*
11928 * Set the file modification time zone->expire seconds before expiretime.
11929 */
11930 static void
11931 setmodtime(dns_zone_t *zone, isc_time_t *expiretime) {
11932 isc_result_t result;
11933 isc_time_t when;
11934 isc_interval_t i;
11935
11936 isc_interval_set(&i, zone->expire, 0);
11937 result = isc_time_subtract(expiretime, &i, &when);
11938 if (result != ISC_R_SUCCESS)
11939 return;
11940
11941 result = ISC_R_FAILURE;
11942 if (zone->journal != NULL)
11943 result = isc_file_settime(zone->journal, &when);
11944 if (result == ISC_R_SUCCESS &&
11945 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11946 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP))
11947 result = isc_file_settime(zone->masterfile, &when);
11948 else if (result != ISC_R_SUCCESS)
11949 result = isc_file_settime(zone->masterfile, &when);
11950
11951 /*
11952 * Someone removed the file from underneath us!
11953 */
11954 if (result == ISC_R_FILENOTFOUND) {
11955 zone_needdump(zone, DNS_DUMP_DELAY);
11956 } else if (result != ISC_R_SUCCESS)
11957 dns_zone_log(zone, ISC_LOG_ERROR, "refresh: could not set "
11958 "file modification time of '%s': %s",
11959 zone->masterfile, dns_result_totext(result));
11960 }
11961
11962 /*
11963 * An SOA query has finished (successfully or not).
11964 */
11965 static void
11966 refresh_callback(isc_task_t *task, isc_event_t *event) {
11967 const char me[] = "refresh_callback";
11968 dns_requestevent_t *revent = (dns_requestevent_t *)event;
11969 dns_zone_t *zone;
11970 dns_message_t *msg = NULL;
11971 uint32_t soacnt, cnamecnt, soacount, nscount;
11972 isc_time_t now;
11973 char master[ISC_SOCKADDR_FORMATSIZE];
11974 char source[ISC_SOCKADDR_FORMATSIZE];
11975 dns_rdataset_t *rdataset = NULL;
11976 dns_rdata_t rdata = DNS_RDATA_INIT;
11977 dns_rdata_soa_t soa;
11978 isc_result_t result;
11979 uint32_t serial, oldserial = 0;
11980 unsigned int j;
11981 bool do_queue_xfrin = false;
11982
11983 zone = revent->ev_arg;
11984 INSIST(DNS_ZONE_VALID(zone));
11985
11986 UNUSED(task);
11987
11988 ENTER;
11989
11990 TIME_NOW(&now);
11991
11992 LOCK_ZONE(zone);
11993
11994 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
11995 isc_event_free(&event);
11996 dns_request_destroy(&zone->request);
11997 goto detach;
11998 }
11999
12000 /*
12001 * if timeout log and next master;
12002 */
12003
12004 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
12005 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
12006
12007 if (revent->result != ISC_R_SUCCESS) {
12008 if (revent->result == ISC_R_TIMEDOUT &&
12009 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
12010 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
12011 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12012 "refresh: timeout retrying without EDNS "
12013 "master %s (source %s)", master, source);
12014 goto same_master;
12015 }
12016 if (revent->result == ISC_R_TIMEDOUT &&
12017 !dns_request_usedtcp(revent->request)) {
12018 dns_zone_log(zone, ISC_LOG_INFO,
12019 "refresh: retry limit for "
12020 "master %s exceeded (source %s)",
12021 master, source);
12022 /* Try with slave with TCP. */
12023 if ((zone->type == dns_zone_slave ||
12024 zone->type == dns_zone_mirror ||
12025 zone->type == dns_zone_redirect) &&
12026 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH))
12027 {
12028 if (!dns_zonemgr_unreachable(zone->zmgr,
12029 &zone->masteraddr,
12030 &zone->sourceaddr,
12031 &now))
12032 {
12033 DNS_ZONE_SETFLAG(zone,
12034 DNS_ZONEFLG_SOABEFOREAXFR);
12035 goto tcp_transfer;
12036 }
12037 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12038 "refresh: skipped tcp fallback "
12039 "as master %s (source %s) is "
12040 "unreachable (cached)",
12041 master, source);
12042 }
12043 } else
12044 dns_zone_log(zone, ISC_LOG_INFO,
12045 "refresh: failure trying master "
12046 "%s (source %s): %s", master, source,
12047 dns_result_totext(revent->result));
12048 goto next_master;
12049 }
12050
12051 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
12052 if (result != ISC_R_SUCCESS)
12053 goto next_master;
12054 result = dns_request_getresponse(revent->request, msg, 0);
12055 if (result != ISC_R_SUCCESS) {
12056 dns_zone_log(zone, ISC_LOG_INFO,
12057 "refresh: failure trying master "
12058 "%s (source %s): %s", master, source,
12059 dns_result_totext(result));
12060 goto next_master;
12061 }
12062
12063 /*
12064 * Unexpected rcode.
12065 */
12066 if (msg->rcode != dns_rcode_noerror) {
12067 char rcode[128];
12068 isc_buffer_t rb;
12069
12070 isc_buffer_init(&rb, rcode, sizeof(rcode));
12071 (void)dns_rcode_totext(msg->rcode, &rb);
12072
12073 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
12074 (msg->rcode == dns_rcode_servfail ||
12075 msg->rcode == dns_rcode_notimp ||
12076 msg->rcode == dns_rcode_formerr)) {
12077 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12078 "refresh: rcode (%.*s) retrying without "
12079 "EDNS master %s (source %s)",
12080 (int)rb.used, rcode, master, source);
12081 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
12082 goto same_master;
12083 }
12084 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
12085 msg->rcode == dns_rcode_badvers) {
12086 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12087 "refresh: rcode (%.*s) retrying without "
12088 "EDNS EXPIRE OPTION master %s (source %s)",
12089 (int)rb.used, rcode, master, source);
12090 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
12091 goto same_master;
12092 }
12093 dns_zone_log(zone, ISC_LOG_INFO,
12094 "refresh: unexpected rcode (%.*s) from "
12095 "master %s (source %s)", (int)rb.used, rcode,
12096 master, source);
12097 /*
12098 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
12099 */
12100 if (msg->rcode == dns_rcode_refused &&
12101 (zone->type == dns_zone_slave ||
12102 zone->type == dns_zone_mirror ||
12103 zone->type == dns_zone_redirect))
12104 {
12105 goto tcp_transfer;
12106 }
12107 goto next_master;
12108 }
12109
12110 /*
12111 * If truncated punt to zone transfer which will query again.
12112 */
12113 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
12114 if (zone->type == dns_zone_slave ||
12115 zone->type == dns_zone_mirror ||
12116 zone->type == dns_zone_redirect)
12117 {
12118 dns_zone_log(zone, ISC_LOG_INFO,
12119 "refresh: truncated UDP answer, "
12120 "initiating TCP zone xfer "
12121 "for master %s (source %s)",
12122 master, source);
12123 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
12124 goto tcp_transfer;
12125 } else {
12126 INSIST(zone->type == dns_zone_stub);
12127 if (dns_request_usedtcp(revent->request)) {
12128 dns_zone_log(zone, ISC_LOG_INFO,
12129 "refresh: truncated TCP response "
12130 "from master %s (source %s)",
12131 master, source);
12132 goto next_master;
12133 }
12134 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
12135 goto same_master;
12136 }
12137 }
12138
12139 /*
12140 * if non-auth log and next master;
12141 */
12142 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
12143 dns_zone_log(zone, ISC_LOG_INFO,
12144 "refresh: non-authoritative answer from "
12145 "master %s (source %s)", master, source);
12146 goto next_master;
12147 }
12148
12149 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
12150 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
12151 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
12152 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
12153 dns_rdatatype_soa);
12154
12155 /*
12156 * There should not be a CNAME record at top of zone.
12157 */
12158 if (cnamecnt != 0) {
12159 dns_zone_log(zone, ISC_LOG_INFO,
12160 "refresh: CNAME at top of zone "
12161 "in master %s (source %s)", master, source);
12162 goto next_master;
12163 }
12164
12165 /*
12166 * if referral log and next master;
12167 */
12168 if (soacnt == 0 && soacount == 0 && nscount != 0) {
12169 dns_zone_log(zone, ISC_LOG_INFO,
12170 "refresh: referral response "
12171 "from master %s (source %s)", master, source);
12172 goto next_master;
12173 }
12174
12175 /*
12176 * if nodata log and next master;
12177 */
12178 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
12179 dns_zone_log(zone, ISC_LOG_INFO,
12180 "refresh: NODATA response "
12181 "from master %s (source %s)", master, source);
12182 goto next_master;
12183 }
12184
12185 /*
12186 * Only one soa at top of zone.
12187 */
12188 if (soacnt != 1) {
12189 dns_zone_log(zone, ISC_LOG_INFO,
12190 "refresh: answer SOA count (%d) != 1 "
12191 "from master %s (source %s)",
12192 soacnt, master, source);
12193 goto next_master;
12194 }
12195
12196 /*
12197 * Extract serial
12198 */
12199 rdataset = NULL;
12200 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
12201 dns_rdatatype_soa, dns_rdatatype_none,
12202 NULL, &rdataset);
12203 if (result != ISC_R_SUCCESS) {
12204 dns_zone_log(zone, ISC_LOG_INFO,
12205 "refresh: unable to get SOA record "
12206 "from master %s (source %s)", master, source);
12207 goto next_master;
12208 }
12209
12210 result = dns_rdataset_first(rdataset);
12211 if (result != ISC_R_SUCCESS) {
12212 dns_zone_log(zone, ISC_LOG_INFO,
12213 "refresh: dns_rdataset_first() failed");
12214 goto next_master;
12215 }
12216
12217 dns_rdataset_current(rdataset, &rdata);
12218 result = dns_rdata_tostruct(&rdata, &soa, NULL);
12219 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12220
12221 serial = soa.serial;
12222 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
12223 unsigned int dbsoacount;
12224 result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount,
12225 &oldserial, NULL, NULL, NULL, NULL,
12226 NULL);
12227 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12228 RUNTIME_CHECK(dbsoacount > 0U);
12229 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
12230 serial, oldserial);
12231 } else
12232 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
12233 serial);
12234
12235 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
12236 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
12237 isc_serial_gt(serial, oldserial)) {
12238 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
12239 &zone->sourceaddr, &now))
12240 {
12241 dns_zone_log(zone, ISC_LOG_INFO,
12242 "refresh: skipping %s as master %s "
12243 "(source %s) is unreachable (cached)",
12244 (zone->type == dns_zone_slave ||
12245 zone->type == dns_zone_mirror ||
12246 zone->type == dns_zone_redirect) ?
12247 "zone transfer" : "NS query",
12248 master, source);
12249 goto next_master;
12250 }
12251 tcp_transfer:
12252 isc_event_free(&event);
12253 dns_request_destroy(&zone->request);
12254 if (zone->type == dns_zone_slave ||
12255 zone->type == dns_zone_mirror ||
12256 zone->type == dns_zone_redirect)
12257 {
12258 do_queue_xfrin = true;
12259 } else {
12260 INSIST(zone->type == dns_zone_stub);
12261 ns_query(zone, rdataset, NULL);
12262 }
12263 if (msg != NULL)
12264 dns_message_destroy(&msg);
12265 } else if (isc_serial_eq(soa.serial, oldserial)) {
12266 isc_time_t expiretime;
12267 uint32_t expire;
12268
12269 /*
12270 * Compute the new expire time based on this response.
12271 */
12272 expire = zone->expire;
12273 get_edns_expire(zone, msg, &expire);
12274 DNS_ZONE_TIME_ADD(&now, expire, &expiretime);
12275
12276 /*
12277 * Has the expire time improved?
12278 */
12279 if (isc_time_compare(&expiretime, &zone->expiretime) > 0) {
12280 zone->expiretime = expiretime;
12281 if (zone->masterfile != NULL)
12282 setmodtime(zone, &expiretime);
12283 }
12284
12285 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
12286 zone->mastersok[zone->curmaster] = true;
12287 goto next_master;
12288 } else {
12289 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
12290 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
12291 "received from master %s < ours (%u)",
12292 soa.serial, master, oldserial);
12293 else
12294 zone_debuglog(zone, me, 1, "ahead");
12295 zone->mastersok[zone->curmaster] = true;
12296 goto next_master;
12297 }
12298 if (msg != NULL)
12299 dns_message_destroy(&msg);
12300 goto detach;
12301
12302 next_master:
12303 if (msg != NULL)
12304 dns_message_destroy(&msg);
12305 isc_event_free(&event);
12306 dns_request_destroy(&zone->request);
12307 /*
12308 * Skip to next failed / untried master.
12309 */
12310 do {
12311 zone->curmaster++;
12312 } while (zone->curmaster < zone->masterscnt &&
12313 zone->mastersok[zone->curmaster]);
12314 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
12315 if (zone->curmaster >= zone->masterscnt) {
12316 bool done = true;
12317 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
12318 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
12319 /*
12320 * Did we get a good answer from all the masters?
12321 */
12322 for (j = 0; j < zone->masterscnt; j++)
12323 if (zone->mastersok[j] == false) {
12324 done = false;
12325 break;
12326 }
12327 } else
12328 done = true;
12329 if (!done) {
12330 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
12331 zone->curmaster = 0;
12332 /*
12333 * Find the next failed master.
12334 */
12335 while (zone->curmaster < zone->masterscnt &&
12336 zone->mastersok[zone->curmaster])
12337 zone->curmaster++;
12338 goto requeue;
12339 }
12340 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
12341 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
12342 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
12343 zone->refreshtime = now;
12344 }
12345 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
12346 zone_settimer(zone, &now);
12347 goto detach;
12348 }
12349
12350 requeue:
12351 queue_soa_query(zone);
12352 goto detach;
12353
12354 same_master:
12355 if (msg != NULL)
12356 dns_message_destroy(&msg);
12357 isc_event_free(&event);
12358 dns_request_destroy(&zone->request);
12359 queue_soa_query(zone);
12360
12361 detach:
12362 UNLOCK_ZONE(zone);
12363 if (do_queue_xfrin)
12364 queue_xfrin(zone);
12365 dns_zone_idetach(&zone);
12366 return;
12367 }
12368
12369 static void
12370 queue_soa_query(dns_zone_t *zone) {
12371 const char me[] = "queue_soa_query";
12372 isc_event_t *e;
12373 dns_zone_t *dummy = NULL;
12374 isc_result_t result;
12375
12376 ENTER;
12377 /*
12378 * Locked by caller
12379 */
12380 REQUIRE(LOCKED_ZONE(zone));
12381
12382 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
12383 cancel_refresh(zone);
12384 return;
12385 }
12386
12387 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
12388 soa_query, zone, sizeof(isc_event_t));
12389 if (e == NULL) {
12390 cancel_refresh(zone);
12391 return;
12392 }
12393
12394 /*
12395 * Attach so that we won't clean up
12396 * until the event is delivered.
12397 */
12398 zone_iattach(zone, &dummy);
12399
12400 e->ev_arg = zone;
12401 e->ev_sender = NULL;
12402 result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e);
12403 if (result != ISC_R_SUCCESS) {
12404 zone_idetach(&dummy);
12405 isc_event_free(&e);
12406 cancel_refresh(zone);
12407 }
12408 }
12409
12410 static inline isc_result_t
12411 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
12412 dns_message_t **messagep)
12413 {
12414 dns_message_t *message = NULL;
12415 dns_name_t *qname = NULL;
12416 dns_rdataset_t *qrdataset = NULL;
12417 isc_result_t result;
12418
12419 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
12420 &message);
12421 if (result != ISC_R_SUCCESS)
12422 goto cleanup;
12423
12424 message->opcode = dns_opcode_query;
12425 message->rdclass = zone->rdclass;
12426
12427 result = dns_message_gettempname(message, &qname);
12428 if (result != ISC_R_SUCCESS)
12429 goto cleanup;
12430
12431 result = dns_message_gettemprdataset(message, &qrdataset);
12432 if (result != ISC_R_SUCCESS)
12433 goto cleanup;
12434
12435 /*
12436 * Make question.
12437 */
12438 dns_name_init(qname, NULL);
12439 dns_name_clone(&zone->origin, qname);
12440 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
12441 ISC_LIST_APPEND(qname->list, qrdataset, link);
12442 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
12443
12444 *messagep = message;
12445 return (ISC_R_SUCCESS);
12446
12447 cleanup:
12448 if (qname != NULL)
12449 dns_message_puttempname(message, &qname);
12450 if (qrdataset != NULL)
12451 dns_message_puttemprdataset(message, &qrdataset);
12452 if (message != NULL)
12453 dns_message_destroy(&message);
12454 return (result);
12455 }
12456
12457 static isc_result_t
12458 add_opt(dns_message_t *message, uint16_t udpsize, bool reqnsid,
12459 bool reqexpire)
12460 {
12461 isc_result_t result;
12462 dns_rdataset_t *rdataset = NULL;
12463 dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
12464 int count = 0;
12465
12466 /* Set EDNS options if applicable */
12467 if (reqnsid) {
12468 INSIST(count < DNS_EDNSOPTIONS);
12469 ednsopts[count].code = DNS_OPT_NSID;
12470 ednsopts[count].length = 0;
12471 ednsopts[count].value = NULL;
12472 count++;
12473 }
12474 if (reqexpire) {
12475 INSIST(count < DNS_EDNSOPTIONS);
12476 ednsopts[count].code = DNS_OPT_EXPIRE;
12477 ednsopts[count].length = 0;
12478 ednsopts[count].value = NULL;
12479 count++;
12480 }
12481 result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0,
12482 ednsopts, count);
12483 if (result != ISC_R_SUCCESS)
12484 return (result);
12485
12486 return (dns_message_setopt(message, rdataset));
12487 }
12488
12489 static void
12490 soa_query(isc_task_t *task, isc_event_t *event) {
12491 const char me[] = "soa_query";
12492 isc_result_t result = ISC_R_FAILURE;
12493 dns_message_t *message = NULL;
12494 dns_zone_t *zone = event->ev_arg;
12495 dns_zone_t *dummy = NULL;
12496 isc_netaddr_t masterip;
12497 dns_tsigkey_t *key = NULL;
12498 uint32_t options;
12499 bool cancel = true;
12500 int timeout;
12501 bool have_xfrsource, have_xfrdscp, reqnsid, reqexpire;
12502 uint16_t udpsize = SEND_BUFFER_SIZE;
12503 isc_dscp_t dscp = -1;
12504
12505 REQUIRE(DNS_ZONE_VALID(zone));
12506
12507 UNUSED(task);
12508
12509 ENTER;
12510
12511 LOCK_ZONE(zone);
12512 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
12513 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
12514 zone->view->requestmgr == NULL) {
12515 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
12516 cancel = false;
12517 goto cleanup;
12518 }
12519
12520 again:
12521 result = create_query(zone, dns_rdatatype_soa, &message);
12522 if (result != ISC_R_SUCCESS)
12523 goto cleanup;
12524
12525 INSIST(zone->masterscnt > 0);
12526 INSIST(zone->curmaster < zone->masterscnt);
12527
12528 zone->masteraddr = zone->masters[zone->curmaster];
12529
12530 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
12531 /*
12532 * First, look for a tsig key in the master statement, then
12533 * try for a server key.
12534 */
12535 if ((zone->masterkeynames != NULL) &&
12536 (zone->masterkeynames[zone->curmaster] != NULL)) {
12537 dns_view_t *view = dns_zone_getview(zone);
12538 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
12539 result = dns_view_gettsig(view, keyname, &key);
12540 if (result != ISC_R_SUCCESS) {
12541 char namebuf[DNS_NAME_FORMATSIZE];
12542 dns_name_format(keyname, namebuf, sizeof(namebuf));
12543 dns_zone_log(zone, ISC_LOG_ERROR,
12544 "unable to find key: %s", namebuf);
12545 goto skip_master;
12546 }
12547 }
12548 if (key == NULL) {
12549 result = dns_view_getpeertsig(zone->view, &masterip, &key);
12550 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
12551 char addrbuf[ISC_NETADDR_FORMATSIZE];
12552 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
12553 dns_zone_log(zone, ISC_LOG_ERROR,
12554 "unable to find TSIG key for %s", addrbuf);
12555 goto skip_master;
12556 }
12557 }
12558
12559 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
12560 DNS_REQUESTOPT_TCP : 0;
12561 have_xfrsource = have_xfrdscp = false;
12562 reqnsid = zone->view->requestnsid;
12563 reqexpire = zone->requestexpire;
12564 if (zone->view->peers != NULL) {
12565 dns_peer_t *peer = NULL;
12566 bool edns, usetcp;
12567 result = dns_peerlist_peerbyaddr(zone->view->peers,
12568 &masterip, &peer);
12569 if (result == ISC_R_SUCCESS) {
12570 result = dns_peer_getsupportedns(peer, &edns);
12571 if (result == ISC_R_SUCCESS && !edns)
12572 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
12573 result = dns_peer_gettransfersource(peer,
12574 &zone->sourceaddr);
12575 if (result == ISC_R_SUCCESS)
12576 have_xfrsource = true;
12577 (void)dns_peer_gettransferdscp(peer, &dscp);
12578 if (dscp != -1)
12579 have_xfrdscp = true;
12580 if (zone->view->resolver != NULL)
12581 udpsize =
12582 dns_resolver_getudpsize(zone->view->resolver);
12583 (void)dns_peer_getudpsize(peer, &udpsize);
12584 (void)dns_peer_getrequestnsid(peer, &reqnsid);
12585 (void)dns_peer_getrequestexpire(peer, &reqexpire);
12586 result = dns_peer_getforcetcp(peer, &usetcp);
12587 if (result == ISC_R_SUCCESS && usetcp)
12588 options |= DNS_REQUESTOPT_TCP;
12589 }
12590 }
12591
12592 switch (isc_sockaddr_pf(&zone->masteraddr)) {
12593 case PF_INET:
12594 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
12595 if (isc_sockaddr_equal(&zone->altxfrsource4,
12596 &zone->xfrsource4))
12597 goto skip_master;
12598 zone->sourceaddr = zone->altxfrsource4;
12599 if (!have_xfrdscp)
12600 dscp = zone->altxfrsource4dscp;
12601 } else if (!have_xfrsource) {
12602 zone->sourceaddr = zone->xfrsource4;
12603 if (!have_xfrdscp)
12604 dscp = zone->xfrsource4dscp;
12605 }
12606 break;
12607 case PF_INET6:
12608 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
12609 if (isc_sockaddr_equal(&zone->altxfrsource6,
12610 &zone->xfrsource6))
12611 goto skip_master;
12612 zone->sourceaddr = zone->altxfrsource6;
12613 if (!have_xfrdscp)
12614 dscp = zone->altxfrsource6dscp;
12615 } else if (!have_xfrsource) {
12616 zone->sourceaddr = zone->xfrsource6;
12617 if (!have_xfrdscp)
12618 dscp = zone->xfrsource6dscp;
12619 }
12620 break;
12621 default:
12622 result = ISC_R_NOTIMPLEMENTED;
12623 goto cleanup;
12624 }
12625
12626 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
12627 result = add_opt(message, udpsize, reqnsid, reqexpire);
12628 if (result != ISC_R_SUCCESS)
12629 zone_debuglog(zone, me, 1,
12630 "unable to add opt record: %s",
12631 dns_result_totext(result));
12632 }
12633
12634 zone_iattach(zone, &dummy);
12635 timeout = 15;
12636 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
12637 timeout = 30;
12638 result = dns_request_createvia(zone->view->requestmgr, message,
12639 &zone->sourceaddr, &zone->masteraddr,
12640 dscp, options, key, timeout * 3,
12641 timeout, 0, zone->task,
12642 refresh_callback, zone, &zone->request);
12643 if (result != ISC_R_SUCCESS) {
12644 zone_idetach(&dummy);
12645 zone_debuglog(zone, me, 1,
12646 "dns_request_createvia4() failed: %s",
12647 dns_result_totext(result));
12648 goto skip_master;
12649 } else {
12650 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
12651 inc_stats(zone, dns_zonestatscounter_soaoutv4);
12652 else
12653 inc_stats(zone, dns_zonestatscounter_soaoutv6);
12654 }
12655 cancel = false;
12656
12657 cleanup:
12658 if (key != NULL)
12659 dns_tsigkey_detach(&key);
12660 if (result != ISC_R_SUCCESS)
12661 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
12662 if (message != NULL)
12663 dns_message_destroy(&message);
12664 if (cancel)
12665 cancel_refresh(zone);
12666 isc_event_free(&event);
12667 UNLOCK_ZONE(zone);
12668 dns_zone_idetach(&zone);
12669 return;
12670
12671 skip_master:
12672 if (key != NULL)
12673 dns_tsigkey_detach(&key);
12674 dns_message_destroy(&message);
12675 /*
12676 * Skip to next failed / untried master.
12677 */
12678 do {
12679 zone->curmaster++;
12680 } while (zone->curmaster < zone->masterscnt &&
12681 zone->mastersok[zone->curmaster]);
12682 if (zone->curmaster < zone->masterscnt)
12683 goto again;
12684 zone->curmaster = 0;
12685 goto cleanup;
12686 }
12687
12688 static void
12689 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
12690 const char me[] = "ns_query";
12691 isc_result_t result;
12692 dns_message_t *message = NULL;
12693 isc_netaddr_t masterip;
12694 dns_tsigkey_t *key = NULL;
12695 dns_dbnode_t *node = NULL;
12696 int timeout;
12697 bool have_xfrsource = false, have_xfrdscp = false;
12698 bool reqnsid;
12699 uint16_t udpsize = SEND_BUFFER_SIZE;
12700 isc_dscp_t dscp = -1;
12701
12702 REQUIRE(DNS_ZONE_VALID(zone));
12703 REQUIRE(LOCKED_ZONE(zone));
12704 REQUIRE((soardataset != NULL && stub == NULL) ||
12705 (soardataset == NULL && stub != NULL));
12706 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
12707
12708 ENTER;
12709
12710 if (stub == NULL) {
12711 stub = isc_mem_get(zone->mctx, sizeof(*stub));
12712 if (stub == NULL)
12713 goto cleanup;
12714 stub->magic = STUB_MAGIC;
12715 stub->mctx = zone->mctx;
12716 stub->zone = NULL;
12717 stub->db = NULL;
12718 stub->version = NULL;
12719
12720 /*
12721 * Attach so that the zone won't disappear from under us.
12722 */
12723 zone_iattach(zone, &stub->zone);
12724
12725 /*
12726 * If a db exists we will update it, otherwise we create a
12727 * new one and attach it to the zone once we have the NS
12728 * RRset and glue.
12729 */
12730 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
12731 if (zone->db != NULL) {
12732 dns_db_attach(zone->db, &stub->db);
12733 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
12734 } else {
12735 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
12736
12737 INSIST(zone->db_argc >= 1);
12738 result = dns_db_create(zone->mctx, zone->db_argv[0],
12739 &zone->origin, dns_dbtype_stub,
12740 zone->rdclass,
12741 zone->db_argc - 1,
12742 zone->db_argv + 1,
12743 &stub->db);
12744 if (result != ISC_R_SUCCESS) {
12745 dns_zone_log(zone, ISC_LOG_ERROR,
12746 "refreshing stub: "
12747 "could not create "
12748 "database: %s",
12749 dns_result_totext(result));
12750 goto cleanup;
12751 }
12752 dns_db_settask(stub->db, zone->task);
12753 }
12754
12755 result = dns_db_newversion(stub->db, &stub->version);
12756 if (result != ISC_R_SUCCESS) {
12757 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
12758 "dns_db_newversion() failed: %s",
12759 dns_result_totext(result));
12760 goto cleanup;
12761 }
12762
12763 /*
12764 * Update SOA record.
12765 */
12766 result = dns_db_findnode(stub->db, &zone->origin, true,
12767 &node);
12768 if (result != ISC_R_SUCCESS) {
12769 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
12770 "dns_db_findnode() failed: %s",
12771 dns_result_totext(result));
12772 goto cleanup;
12773 }
12774
12775 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
12776 soardataset, 0, NULL);
12777 dns_db_detachnode(stub->db, &node);
12778 if (result != ISC_R_SUCCESS) {
12779 dns_zone_log(zone, ISC_LOG_INFO,
12780 "refreshing stub: "
12781 "dns_db_addrdataset() failed: %s",
12782 dns_result_totext(result));
12783 goto cleanup;
12784 }
12785 }
12786
12787 /*
12788 * XXX Optimisation: Create message when zone is setup and reuse.
12789 */
12790 result = create_query(zone, dns_rdatatype_ns, &message);
12791 INSIST(result == ISC_R_SUCCESS);
12792
12793 INSIST(zone->masterscnt > 0);
12794 INSIST(zone->curmaster < zone->masterscnt);
12795 zone->masteraddr = zone->masters[zone->curmaster];
12796
12797 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
12798 /*
12799 * First, look for a tsig key in the master statement, then
12800 * try for a server key.
12801 */
12802 if ((zone->masterkeynames != NULL) &&
12803 (zone->masterkeynames[zone->curmaster] != NULL)) {
12804 dns_view_t *view = dns_zone_getview(zone);
12805 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
12806 result = dns_view_gettsig(view, keyname, &key);
12807 if (result != ISC_R_SUCCESS) {
12808 char namebuf[DNS_NAME_FORMATSIZE];
12809 dns_name_format(keyname, namebuf, sizeof(namebuf));
12810 dns_zone_log(zone, ISC_LOG_ERROR,
12811 "unable to find key: %s", namebuf);
12812 }
12813 }
12814 if (key == NULL)
12815 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
12816
12817 reqnsid = zone->view->requestnsid;
12818 if (zone->view->peers != NULL) {
12819 dns_peer_t *peer = NULL;
12820 bool edns;
12821 result = dns_peerlist_peerbyaddr(zone->view->peers,
12822 &masterip, &peer);
12823 if (result == ISC_R_SUCCESS) {
12824 result = dns_peer_getsupportedns(peer, &edns);
12825 if (result == ISC_R_SUCCESS && !edns)
12826 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
12827 result = dns_peer_gettransfersource(peer,
12828 &zone->sourceaddr);
12829 if (result == ISC_R_SUCCESS)
12830 have_xfrsource = true;
12831 result = dns_peer_gettransferdscp(peer, &dscp);
12832 if (result == ISC_R_SUCCESS && dscp != -1)
12833 have_xfrdscp = true;
12834 if (zone->view->resolver != NULL)
12835 udpsize =
12836 dns_resolver_getudpsize(zone->view->resolver);
12837 (void)dns_peer_getudpsize(peer, &udpsize);
12838 (void)dns_peer_getrequestnsid(peer, &reqnsid);
12839 }
12840
12841 }
12842 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
12843 result = add_opt(message, udpsize, reqnsid, false);
12844 if (result != ISC_R_SUCCESS)
12845 zone_debuglog(zone, me, 1,
12846 "unable to add opt record: %s",
12847 dns_result_totext(result));
12848 }
12849
12850 /*
12851 * Always use TCP so that we shouldn't truncate in additional section.
12852 */
12853 switch (isc_sockaddr_pf(&zone->masteraddr)) {
12854 case PF_INET:
12855 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
12856 zone->sourceaddr = zone->altxfrsource4;
12857 if (!have_xfrdscp)
12858 dscp = zone->altxfrsource4dscp;
12859 } else if (!have_xfrsource) {
12860 zone->sourceaddr = zone->xfrsource4;
12861 if (!have_xfrdscp)
12862 dscp = zone->xfrsource4dscp;
12863 }
12864 break;
12865 case PF_INET6:
12866 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
12867 zone->sourceaddr = zone->altxfrsource6;
12868 if (!have_xfrdscp)
12869 dscp = zone->altxfrsource6dscp;
12870 } else if (!have_xfrsource) {
12871 zone->sourceaddr = zone->xfrsource6;
12872 if (!have_xfrdscp)
12873 dscp = zone->xfrsource6dscp;
12874 }
12875 break;
12876 default:
12877 result = ISC_R_NOTIMPLEMENTED;
12878 POST(result);
12879 goto cleanup;
12880 }
12881 timeout = 15;
12882 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
12883 timeout = 30;
12884 result = dns_request_createvia(zone->view->requestmgr, message,
12885 &zone->sourceaddr, &zone->masteraddr,
12886 dscp, DNS_REQUESTOPT_TCP, key,
12887 timeout * 3, timeout, 0, zone->task,
12888 stub_callback, stub, &zone->request);
12889 if (result != ISC_R_SUCCESS) {
12890 zone_debuglog(zone, me, 1,
12891 "dns_request_createvia() failed: %s",
12892 dns_result_totext(result));
12893 goto cleanup;
12894 }
12895 dns_message_destroy(&message);
12896 goto unlock;
12897
12898 cleanup:
12899 cancel_refresh(zone);
12900 if (stub != NULL) {
12901 stub->magic = 0;
12902 if (stub->version != NULL)
12903 dns_db_closeversion(stub->db, &stub->version,
12904 false);
12905 if (stub->db != NULL)
12906 dns_db_detach(&stub->db);
12907 if (stub->zone != NULL)
12908 zone_idetach(&stub->zone);
12909 isc_mem_put(stub->mctx, stub, sizeof(*stub));
12910 }
12911 if (message != NULL)
12912 dns_message_destroy(&message);
12913 unlock:
12914 if (key != NULL)
12915 dns_tsigkey_detach(&key);
12916 return;
12917 }
12918
12919 /*
12920 * Handle the control event. Note that although this event causes the zone
12921 * to shut down, it is not a shutdown event in the sense of the task library.
12922 */
12923 static void
12924 zone_shutdown(isc_task_t *task, isc_event_t *event) {
12925 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
12926 bool free_needed, linked = false;
12927 dns_zone_t *raw = NULL, *secure = NULL;
12928
12929 UNUSED(task);
12930 REQUIRE(DNS_ZONE_VALID(zone));
12931 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
12932 INSIST(isc_refcount_current(&zone->erefs) == 0);
12933
12934 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
12935
12936 /*
12937 * Stop things being restarted after we cancel them below.
12938 */
12939 LOCK_ZONE(zone);
12940 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
12941 UNLOCK_ZONE(zone);
12942
12943 /*
12944 * If we were waiting for xfrin quota, step out of
12945 * the queue.
12946 * If there's no zone manager, we can't be waiting for the
12947 * xfrin quota
12948 */
12949 if (zone->zmgr != NULL) {
12950 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
12951 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
12952 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
12953 statelink);
12954 linked = true;
12955 zone->statelist = NULL;
12956 }
12957 if (zone->statelist == &zone->zmgr->xfrin_in_progress) {
12958 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone,
12959 statelink);
12960 zone->statelist = NULL;
12961 zmgr_resume_xfrs(zone->zmgr, false);
12962 }
12963 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
12964 }
12965
12966 /*
12967 * In task context, no locking required. See zone_xfrdone().
12968 */
12969 if (zone->xfr != NULL)
12970 dns_xfrin_shutdown(zone->xfr);
12971
12972 /* Safe to release the zone now */
12973 if (zone->zmgr != NULL)
12974 dns_zonemgr_releasezone(zone->zmgr, zone);
12975
12976 LOCK_ZONE(zone);
12977 INSIST(zone != zone->raw);
12978 if (linked) {
12979 INSIST(zone->irefs > 0);
12980 zone->irefs--;
12981 }
12982 if (zone->request != NULL) {
12983 dns_request_cancel(zone->request);
12984 }
12985
12986 if (zone->readio != NULL)
12987 zonemgr_cancelio(zone->readio);
12988
12989 if (zone->lctx != NULL)
12990 dns_loadctx_cancel(zone->lctx);
12991
12992 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
12993 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
12994 if (zone->writeio != NULL)
12995 zonemgr_cancelio(zone->writeio);
12996
12997 if (zone->dctx != NULL)
12998 dns_dumpctx_cancel(zone->dctx);
12999 }
13000
13001 notify_cancel(zone);
13002
13003 forward_cancel(zone);
13004
13005 if (zone->timer != NULL) {
13006 isc_timer_detach(&zone->timer);
13007 INSIST(zone->irefs > 0);
13008 zone->irefs--;
13009 }
13010
13011 /*
13012 * We have now canceled everything set the flag to allow exit_check()
13013 * to succeed. We must not unlock between setting this flag and
13014 * calling exit_check().
13015 */
13016 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
13017 free_needed = exit_check(zone);
13018 if (inline_secure(zone)) {
13019 raw = zone->raw;
13020 zone->raw = NULL;
13021 }
13022 if (inline_raw(zone)) {
13023 secure = zone->secure;
13024 zone->secure = NULL;
13025 }
13026 UNLOCK_ZONE(zone);
13027 if (raw != NULL)
13028 dns_zone_detach(&raw);
13029 if (secure != NULL)
13030 dns_zone_idetach(&secure);
13031 if (free_needed)
13032 zone_free(zone);
13033 }
13034
13035 static void
13036 zone_timer(isc_task_t *task, isc_event_t *event) {
13037 const char me[] = "zone_timer";
13038 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
13039
13040 UNUSED(task);
13041 REQUIRE(DNS_ZONE_VALID(zone));
13042
13043 ENTER;
13044
13045 zone_maintenance(zone);
13046
13047 isc_event_free(&event);
13048 }
13049
13050 static void
13051 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
13052 const char me[] = "zone_settimer";
13053 isc_time_t next;
13054 isc_result_t result;
13055
13056 REQUIRE(DNS_ZONE_VALID(zone));
13057 ENTER;
13058
13059 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
13060 return;
13061
13062 isc_time_settoepoch(&next);
13063
13064 switch (zone->type) {
13065 case dns_zone_redirect:
13066 if (zone->masters != NULL)
13067 goto treat_as_slave;
13068 /* FALLTHROUGH */
13069
13070 case dns_zone_master:
13071 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
13072 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
13073 next = zone->notifytime;
13074 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
13075 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
13076 INSIST(!isc_time_isepoch(&zone->dumptime));
13077 if (isc_time_isepoch(&next) ||
13078 isc_time_compare(&zone->dumptime, &next) < 0)
13079 next = zone->dumptime;
13080 }
13081 if (zone->type == dns_zone_redirect)
13082 break;
13083 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
13084 !isc_time_isepoch(&zone->refreshkeytime)) {
13085 if (isc_time_isepoch(&next) ||
13086 isc_time_compare(&zone->refreshkeytime, &next) < 0)
13087 next = zone->refreshkeytime;
13088 }
13089 if (!isc_time_isepoch(&zone->resigntime)) {
13090 if (isc_time_isepoch(&next) ||
13091 isc_time_compare(&zone->resigntime, &next) < 0)
13092 next = zone->resigntime;
13093 }
13094 if (!isc_time_isepoch(&zone->keywarntime)) {
13095 if (isc_time_isepoch(&next) ||
13096 isc_time_compare(&zone->keywarntime, &next) < 0)
13097 next = zone->keywarntime;
13098 }
13099 if (!isc_time_isepoch(&zone->signingtime)) {
13100 if (isc_time_isepoch(&next) ||
13101 isc_time_compare(&zone->signingtime, &next) < 0)
13102 next = zone->signingtime;
13103 }
13104 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
13105 if (isc_time_isepoch(&next) ||
13106 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
13107 next = zone->nsec3chaintime;
13108 }
13109 break;
13110
13111 case dns_zone_slave:
13112 case dns_zone_mirror:
13113 treat_as_slave:
13114 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
13115 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
13116 next = zone->notifytime;
13117 /* FALLTHROUGH */
13118
13119 case dns_zone_stub:
13120 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
13121 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
13122 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
13123 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) &&
13124 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) &&
13125 !isc_time_isepoch(&zone->refreshtime) &&
13126 (isc_time_isepoch(&next) ||
13127 isc_time_compare(&zone->refreshtime, &next) < 0))
13128 next = zone->refreshtime;
13129 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
13130 !isc_time_isepoch(&zone->expiretime)) {
13131 if (isc_time_isepoch(&next) ||
13132 isc_time_compare(&zone->expiretime, &next) < 0)
13133 next = zone->expiretime;
13134 }
13135 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
13136 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
13137 INSIST(!isc_time_isepoch(&zone->dumptime));
13138 if (isc_time_isepoch(&next) ||
13139 isc_time_compare(&zone->dumptime, &next) < 0)
13140 next = zone->dumptime;
13141 }
13142 break;
13143
13144 case dns_zone_key:
13145 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
13146 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
13147 INSIST(!isc_time_isepoch(&zone->dumptime));
13148 if (isc_time_isepoch(&next) ||
13149 isc_time_compare(&zone->dumptime, &next) < 0)
13150 next = zone->dumptime;
13151 }
13152 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
13153 if (isc_time_isepoch(&next) ||
13154 (!isc_time_isepoch(&zone->refreshkeytime) &&
13155 isc_time_compare(&zone->refreshkeytime, &next) < 0))
13156 next = zone->refreshkeytime;
13157 }
13158 break;
13159
13160 default:
13161 break;
13162 }
13163
13164 if (isc_time_isepoch(&next)) {
13165 zone_debuglog(zone, me, 10, "settimer inactive");
13166 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
13167 NULL, NULL, true);
13168 if (result != ISC_R_SUCCESS)
13169 dns_zone_log(zone, ISC_LOG_ERROR,
13170 "could not deactivate zone timer: %s",
13171 isc_result_totext(result));
13172 } else {
13173 if (isc_time_compare(&next, now) <= 0)
13174 next = *now;
13175 result = isc_timer_reset(zone->timer, isc_timertype_once,
13176 &next, NULL, true);
13177 if (result != ISC_R_SUCCESS)
13178 dns_zone_log(zone, ISC_LOG_ERROR,
13179 "could not reset zone timer: %s",
13180 isc_result_totext(result));
13181 }
13182 }
13183
13184 static void
13185 cancel_refresh(dns_zone_t *zone) {
13186 const char me[] = "cancel_refresh";
13187 isc_time_t now;
13188
13189 /*
13190 * 'zone' locked by caller.
13191 */
13192
13193 REQUIRE(DNS_ZONE_VALID(zone));
13194 REQUIRE(LOCKED_ZONE(zone));
13195
13196 ENTER;
13197
13198 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
13199 TIME_NOW(&now);
13200 zone_settimer(zone, &now);
13201 }
13202
13203 static isc_result_t
13204 notify_createmessage(dns_zone_t *zone, unsigned int flags,
13205 dns_message_t **messagep)
13206 {
13207 dns_db_t *zonedb = NULL;
13208 dns_dbnode_t *node = NULL;
13209 dns_dbversion_t *version = NULL;
13210 dns_message_t *message = NULL;
13211 dns_rdataset_t rdataset;
13212 dns_rdata_t rdata = DNS_RDATA_INIT;
13213
13214 dns_name_t *tempname = NULL;
13215 dns_rdata_t *temprdata = NULL;
13216 dns_rdatalist_t *temprdatalist = NULL;
13217 dns_rdataset_t *temprdataset = NULL;
13218
13219 isc_result_t result;
13220 isc_region_t r;
13221 isc_buffer_t *b = NULL;
13222
13223 REQUIRE(DNS_ZONE_VALID(zone));
13224 REQUIRE(messagep != NULL && *messagep == NULL);
13225
13226 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
13227 &message);
13228 if (result != ISC_R_SUCCESS)
13229 return (result);
13230
13231 message->opcode = dns_opcode_notify;
13232 message->flags |= DNS_MESSAGEFLAG_AA;
13233 message->rdclass = zone->rdclass;
13234
13235 result = dns_message_gettempname(message, &tempname);
13236 if (result != ISC_R_SUCCESS)
13237 goto cleanup;
13238
13239 result = dns_message_gettemprdataset(message, &temprdataset);
13240 if (result != ISC_R_SUCCESS)
13241 goto cleanup;
13242
13243 /*
13244 * Make question.
13245 */
13246 dns_name_init(tempname, NULL);
13247 dns_name_clone(&zone->origin, tempname);
13248 dns_rdataset_makequestion(temprdataset, zone->rdclass,
13249 dns_rdatatype_soa);
13250 ISC_LIST_APPEND(tempname->list, temprdataset, link);
13251 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
13252 tempname = NULL;
13253 temprdataset = NULL;
13254
13255 if ((flags & DNS_NOTIFY_NOSOA) != 0)
13256 goto done;
13257
13258 result = dns_message_gettempname(message, &tempname);
13259 if (result != ISC_R_SUCCESS)
13260 goto soa_cleanup;
13261 result = dns_message_gettemprdata(message, &temprdata);
13262 if (result != ISC_R_SUCCESS)
13263 goto soa_cleanup;
13264 result = dns_message_gettemprdataset(message, &temprdataset);
13265 if (result != ISC_R_SUCCESS)
13266 goto soa_cleanup;
13267 result = dns_message_gettemprdatalist(message, &temprdatalist);
13268 if (result != ISC_R_SUCCESS)
13269 goto soa_cleanup;
13270
13271 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13272 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
13273 dns_db_attach(zone->db, &zonedb);
13274 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13275
13276 dns_name_init(tempname, NULL);
13277 dns_name_clone(&zone->origin, tempname);
13278 dns_db_currentversion(zonedb, &version);
13279 result = dns_db_findnode(zonedb, tempname, false, &node);
13280 if (result != ISC_R_SUCCESS)
13281 goto soa_cleanup;
13282
13283 dns_rdataset_init(&rdataset);
13284 result = dns_db_findrdataset(zonedb, node, version,
13285 dns_rdatatype_soa,
13286 dns_rdatatype_none, 0, &rdataset,
13287 NULL);
13288 if (result != ISC_R_SUCCESS)
13289 goto soa_cleanup;
13290 result = dns_rdataset_first(&rdataset);
13291 if (result != ISC_R_SUCCESS)
13292 goto soa_cleanup;
13293 dns_rdataset_current(&rdataset, &rdata);
13294 dns_rdata_toregion(&rdata, &r);
13295 result = isc_buffer_allocate(zone->mctx, &b, r.length);
13296 if (result != ISC_R_SUCCESS)
13297 goto soa_cleanup;
13298 isc_buffer_putmem(b, r.base, r.length);
13299 isc_buffer_usedregion(b, &r);
13300 dns_rdata_init(temprdata);
13301 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
13302 dns_message_takebuffer(message, &b);
13303 result = dns_rdataset_next(&rdataset);
13304 dns_rdataset_disassociate(&rdataset);
13305 if (result != ISC_R_NOMORE)
13306 goto soa_cleanup;
13307 temprdatalist->rdclass = rdata.rdclass;
13308 temprdatalist->type = rdata.type;
13309 temprdatalist->ttl = rdataset.ttl;
13310 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
13311
13312 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
13313 if (result != ISC_R_SUCCESS)
13314 goto soa_cleanup;
13315
13316 ISC_LIST_APPEND(tempname->list, temprdataset, link);
13317 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
13318 temprdatalist = NULL;
13319 temprdataset = NULL;
13320 temprdata = NULL;
13321 tempname = NULL;
13322
13323 soa_cleanup:
13324 if (node != NULL)
13325 dns_db_detachnode(zonedb, &node);
13326 if (version != NULL)
13327 dns_db_closeversion(zonedb, &version, false);
13328 if (zonedb != NULL)
13329 dns_db_detach(&zonedb);
13330 if (tempname != NULL)
13331 dns_message_puttempname(message, &tempname);
13332 if (temprdata != NULL)
13333 dns_message_puttemprdata(message, &temprdata);
13334 if (temprdataset != NULL)
13335 dns_message_puttemprdataset(message, &temprdataset);
13336 if (temprdatalist != NULL)
13337 dns_message_puttemprdatalist(message, &temprdatalist);
13338
13339 done:
13340 *messagep = message;
13341 return (ISC_R_SUCCESS);
13342
13343 cleanup:
13344 if (tempname != NULL)
13345 dns_message_puttempname(message, &tempname);
13346 if (temprdataset != NULL)
13347 dns_message_puttemprdataset(message, &temprdataset);
13348 dns_message_destroy(&message);
13349 return (result);
13350 }
13351
13352 isc_result_t
13353 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
13354 isc_sockaddr_t *to, dns_message_t *msg)
13355 {
13356 unsigned int i;
13357 dns_rdata_soa_t soa;
13358 dns_rdataset_t *rdataset = NULL;
13359 dns_rdata_t rdata = DNS_RDATA_INIT;
13360 isc_result_t result;
13361 char fromtext[ISC_SOCKADDR_FORMATSIZE];
13362 int match = 0;
13363 isc_netaddr_t netaddr;
13364 uint32_t serial = 0;
13365 bool have_serial = false;
13366 dns_tsigkey_t *tsigkey;
13367 dns_name_t *tsig;
13368
13369 REQUIRE(DNS_ZONE_VALID(zone));
13370
13371 /*
13372 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
13373 * ROLLOVER.
13374 *
13375 * SOA: RFC1996
13376 * Check that 'from' is a valid notify source, (zone->masters).
13377 * Return DNS_R_REFUSED if not.
13378 *
13379 * If the notify message contains a serial number check it
13380 * against the zones serial and return if <= current serial
13381 *
13382 * If a refresh check is progress, if so just record the
13383 * fact we received a NOTIFY and from where and return.
13384 * We will perform a new refresh check when the current one
13385 * completes. Return ISC_R_SUCCESS.
13386 *
13387 * Otherwise initiate a refresh check using 'from' as the
13388 * first address to check. Return ISC_R_SUCCESS.
13389 */
13390
13391 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
13392
13393 /*
13394 * Notify messages are processed by the raw zone.
13395 */
13396 LOCK_ZONE(zone);
13397 INSIST(zone != zone->raw);
13398 if (inline_secure(zone)) {
13399 result = dns_zone_notifyreceive(zone->raw, from, to, msg);
13400 UNLOCK_ZONE(zone);
13401 return (result);
13402 }
13403 /*
13404 * We only handle NOTIFY (SOA) at the present.
13405 */
13406 if (isc_sockaddr_pf(from) == PF_INET)
13407 inc_stats(zone, dns_zonestatscounter_notifyinv4);
13408 else
13409 inc_stats(zone, dns_zonestatscounter_notifyinv6);
13410 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
13411 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
13412 dns_rdatatype_soa, dns_rdatatype_none,
13413 NULL, NULL) != ISC_R_SUCCESS) {
13414 UNLOCK_ZONE(zone);
13415 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
13416 dns_zone_log(zone, ISC_LOG_NOTICE,
13417 "NOTIFY with no "
13418 "question section from: %s", fromtext);
13419 return (DNS_R_FORMERR);
13420 }
13421 dns_zone_log(zone, ISC_LOG_NOTICE,
13422 "NOTIFY zone does not match");
13423 return (DNS_R_NOTIMP);
13424 }
13425
13426 /*
13427 * If we are a master zone just succeed.
13428 */
13429 if (zone->type == dns_zone_master) {
13430 UNLOCK_ZONE(zone);
13431 return (ISC_R_SUCCESS);
13432 }
13433
13434 isc_netaddr_fromsockaddr(&netaddr, from);
13435 for (i = 0; i < zone->masterscnt; i++) {
13436 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
13437 break;
13438 if (zone->view->aclenv.match_mapped &&
13439 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
13440 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
13441 isc_netaddr_t na1, na2;
13442 isc_netaddr_fromv4mapped(&na1, &netaddr);
13443 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
13444 if (isc_netaddr_equal(&na1, &na2))
13445 break;
13446 }
13447 }
13448
13449 /*
13450 * Accept notify requests from non masters if they are on
13451 * 'zone->notify_acl'.
13452 */
13453 tsigkey = dns_message_gettsigkey(msg);
13454 tsig = dns_tsigkey_identity(tsigkey);
13455 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
13456 (dns_acl_match(&netaddr, tsig, zone->notify_acl,
13457 &zone->view->aclenv, &match,
13458 NULL) == ISC_R_SUCCESS) &&
13459 match > 0)
13460 {
13461 /* Accept notify. */
13462 } else if (i >= zone->masterscnt) {
13463 UNLOCK_ZONE(zone);
13464 dns_zone_log(zone, ISC_LOG_INFO,
13465 "refused notify from non-master: %s", fromtext);
13466 inc_stats(zone, dns_zonestatscounter_notifyrej);
13467 return (DNS_R_REFUSED);
13468 }
13469
13470 /*
13471 * If the zone is loaded and there are answers check the serial
13472 * to see if we need to do a refresh. Do not worry about this
13473 * check if we are a dialup zone as we use the notify request
13474 * to trigger a refresh check.
13475 */
13476 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
13477 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
13478 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
13479 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
13480 &zone->origin,
13481 dns_rdatatype_soa,
13482 dns_rdatatype_none, NULL,
13483 &rdataset);
13484 if (result == ISC_R_SUCCESS)
13485 result = dns_rdataset_first(rdataset);
13486 if (result == ISC_R_SUCCESS) {
13487 uint32_t oldserial;
13488 unsigned int soacount;
13489
13490 dns_rdataset_current(rdataset, &rdata);
13491 result = dns_rdata_tostruct(&rdata, &soa, NULL);
13492 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13493 serial = soa.serial;
13494 have_serial = true;
13495 /*
13496 * The following should safely be performed without DB
13497 * lock and succeed in this context.
13498 */
13499 result = zone_get_from_db(zone, zone->db, NULL,
13500 &soacount, &oldserial, NULL,
13501 NULL, NULL, NULL, NULL);
13502 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13503 RUNTIME_CHECK(soacount > 0U);
13504 if (isc_serial_le(serial, oldserial)) {
13505 dns_zone_log(zone,
13506 ISC_LOG_INFO,
13507 "notify from %s: "
13508 "zone is up to date",
13509 fromtext);
13510 UNLOCK_ZONE(zone);
13511 return (ISC_R_SUCCESS);
13512 }
13513 }
13514 }
13515
13516 /*
13517 * If we got this far and there was a refresh in progress just
13518 * let it complete. Record where we got the notify from so we
13519 * can perform a refresh check when the current one completes
13520 */
13521 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
13522 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
13523 zone->notifyfrom = *from;
13524 UNLOCK_ZONE(zone);
13525 if (have_serial)
13526 dns_zone_log(zone, ISC_LOG_INFO,
13527 "notify from %s: serial %u: refresh in "
13528 "progress, refresh check queued",
13529 fromtext, serial);
13530 else
13531 dns_zone_log(zone, ISC_LOG_INFO,
13532 "notify from %s: refresh in progress, "
13533 "refresh check queued", fromtext);
13534 return (ISC_R_SUCCESS);
13535 }
13536 if (have_serial)
13537 dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: serial %u",
13538 fromtext, serial);
13539 else
13540 dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: no serial",
13541 fromtext);
13542 zone->notifyfrom = *from;
13543 UNLOCK_ZONE(zone);
13544
13545 if (to != NULL) {
13546 dns_zonemgr_unreachabledel(zone->zmgr, from, to);
13547 }
13548 dns_zone_refresh(zone);
13549 return (ISC_R_SUCCESS);
13550 }
13551
13552 void
13553 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
13554
13555 REQUIRE(DNS_ZONE_VALID(zone));
13556
13557 LOCK_ZONE(zone);
13558 if (zone->notify_acl != NULL)
13559 dns_acl_detach(&zone->notify_acl);
13560 dns_acl_attach(acl, &zone->notify_acl);
13561 UNLOCK_ZONE(zone);
13562 }
13563
13564 void
13565 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
13566
13567 REQUIRE(DNS_ZONE_VALID(zone));
13568
13569 LOCK_ZONE(zone);
13570 if (zone->query_acl != NULL)
13571 dns_acl_detach(&zone->query_acl);
13572 dns_acl_attach(acl, &zone->query_acl);
13573 UNLOCK_ZONE(zone);
13574 }
13575
13576 void
13577 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
13578
13579 REQUIRE(DNS_ZONE_VALID(zone));
13580
13581 LOCK_ZONE(zone);
13582 if (zone->queryon_acl != NULL)
13583 dns_acl_detach(&zone->queryon_acl);
13584 dns_acl_attach(acl, &zone->queryon_acl);
13585 UNLOCK_ZONE(zone);
13586 }
13587
13588 void
13589 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
13590
13591 REQUIRE(DNS_ZONE_VALID(zone));
13592
13593 LOCK_ZONE(zone);
13594 if (zone->update_acl != NULL)
13595 dns_acl_detach(&zone->update_acl);
13596 dns_acl_attach(acl, &zone->update_acl);
13597 UNLOCK_ZONE(zone);
13598 }
13599
13600 void
13601 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
13602
13603 REQUIRE(DNS_ZONE_VALID(zone));
13604
13605 LOCK_ZONE(zone);
13606 if (zone->forward_acl != NULL)
13607 dns_acl_detach(&zone->forward_acl);
13608 dns_acl_attach(acl, &zone->forward_acl);
13609 UNLOCK_ZONE(zone);
13610 }
13611
13612 void
13613 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
13614
13615 REQUIRE(DNS_ZONE_VALID(zone));
13616
13617 LOCK_ZONE(zone);
13618 if (zone->xfr_acl != NULL)
13619 dns_acl_detach(&zone->xfr_acl);
13620 dns_acl_attach(acl, &zone->xfr_acl);
13621 UNLOCK_ZONE(zone);
13622 }
13623
13624 dns_acl_t *
13625 dns_zone_getnotifyacl(dns_zone_t *zone) {
13626
13627 REQUIRE(DNS_ZONE_VALID(zone));
13628
13629 return (zone->notify_acl);
13630 }
13631
13632 dns_acl_t *
13633 dns_zone_getqueryacl(dns_zone_t *zone) {
13634
13635 REQUIRE(DNS_ZONE_VALID(zone));
13636
13637 return (zone->query_acl);
13638 }
13639
13640 dns_acl_t *
13641 dns_zone_getqueryonacl(dns_zone_t *zone) {
13642
13643 REQUIRE(DNS_ZONE_VALID(zone));
13644
13645 return (zone->queryon_acl);
13646 }
13647
13648 dns_acl_t *
13649 dns_zone_getupdateacl(dns_zone_t *zone) {
13650
13651 REQUIRE(DNS_ZONE_VALID(zone));
13652
13653 return (zone->update_acl);
13654 }
13655
13656 dns_acl_t *
13657 dns_zone_getforwardacl(dns_zone_t *zone) {
13658
13659 REQUIRE(DNS_ZONE_VALID(zone));
13660
13661 return (zone->forward_acl);
13662 }
13663
13664 dns_acl_t *
13665 dns_zone_getxfracl(dns_zone_t *zone) {
13666
13667 REQUIRE(DNS_ZONE_VALID(zone));
13668
13669 return (zone->xfr_acl);
13670 }
13671
13672 void
13673 dns_zone_clearupdateacl(dns_zone_t *zone) {
13674
13675 REQUIRE(DNS_ZONE_VALID(zone));
13676
13677 LOCK_ZONE(zone);
13678 if (zone->update_acl != NULL)
13679 dns_acl_detach(&zone->update_acl);
13680 UNLOCK_ZONE(zone);
13681 }
13682
13683 void
13684 dns_zone_clearforwardacl(dns_zone_t *zone) {
13685
13686 REQUIRE(DNS_ZONE_VALID(zone));
13687
13688 LOCK_ZONE(zone);
13689 if (zone->forward_acl != NULL)
13690 dns_acl_detach(&zone->forward_acl);
13691 UNLOCK_ZONE(zone);
13692 }
13693
13694 void
13695 dns_zone_clearnotifyacl(dns_zone_t *zone) {
13696
13697 REQUIRE(DNS_ZONE_VALID(zone));
13698
13699 LOCK_ZONE(zone);
13700 if (zone->notify_acl != NULL)
13701 dns_acl_detach(&zone->notify_acl);
13702 UNLOCK_ZONE(zone);
13703 }
13704
13705 void
13706 dns_zone_clearqueryacl(dns_zone_t *zone) {
13707
13708 REQUIRE(DNS_ZONE_VALID(zone));
13709
13710 LOCK_ZONE(zone);
13711 if (zone->query_acl != NULL)
13712 dns_acl_detach(&zone->query_acl);
13713 UNLOCK_ZONE(zone);
13714 }
13715
13716 void
13717 dns_zone_clearqueryonacl(dns_zone_t *zone) {
13718
13719 REQUIRE(DNS_ZONE_VALID(zone));
13720
13721 LOCK_ZONE(zone);
13722 if (zone->queryon_acl != NULL)
13723 dns_acl_detach(&zone->queryon_acl);
13724 UNLOCK_ZONE(zone);
13725 }
13726
13727 void
13728 dns_zone_clearxfracl(dns_zone_t *zone) {
13729
13730 REQUIRE(DNS_ZONE_VALID(zone));
13731
13732 LOCK_ZONE(zone);
13733 if (zone->xfr_acl != NULL)
13734 dns_acl_detach(&zone->xfr_acl);
13735 UNLOCK_ZONE(zone);
13736 }
13737
13738 bool
13739 dns_zone_getupdatedisabled(dns_zone_t *zone) {
13740 REQUIRE(DNS_ZONE_VALID(zone));
13741 return (zone->update_disabled);
13742
13743 }
13744
13745 void
13746 dns_zone_setupdatedisabled(dns_zone_t *zone, bool state) {
13747 REQUIRE(DNS_ZONE_VALID(zone));
13748 zone->update_disabled = state;
13749 }
13750
13751 bool
13752 dns_zone_getzeronosoattl(dns_zone_t *zone) {
13753 REQUIRE(DNS_ZONE_VALID(zone));
13754 return (zone->zero_no_soa_ttl);
13755
13756 }
13757
13758 void
13759 dns_zone_setzeronosoattl(dns_zone_t *zone, bool state) {
13760 REQUIRE(DNS_ZONE_VALID(zone));
13761 zone->zero_no_soa_ttl = state;
13762 }
13763
13764 void
13765 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
13766 REQUIRE(DNS_ZONE_VALID(zone));
13767
13768 zone->check_names = severity;
13769 }
13770
13771 dns_severity_t
13772 dns_zone_getchecknames(dns_zone_t *zone) {
13773 REQUIRE(DNS_ZONE_VALID(zone));
13774
13775 return (zone->check_names);
13776 }
13777
13778 void
13779 dns_zone_setjournalsize(dns_zone_t *zone, int32_t size) {
13780 REQUIRE(DNS_ZONE_VALID(zone));
13781
13782 zone->journalsize = size;
13783 }
13784
13785 int32_t
13786 dns_zone_getjournalsize(dns_zone_t *zone) {
13787 REQUIRE(DNS_ZONE_VALID(zone));
13788
13789 return (zone->journalsize);
13790 }
13791
13792 static void
13793 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
13794 isc_result_t result = ISC_R_FAILURE;
13795 isc_buffer_t buffer;
13796
13797 REQUIRE(buf != NULL);
13798 REQUIRE(length > 1U);
13799
13800 /*
13801 * Leave space for terminating '\0'.
13802 */
13803 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
13804 if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
13805 if (dns_name_dynamic(&zone->origin))
13806 result = dns_name_totext(&zone->origin, true, &buffer);
13807 if (result != ISC_R_SUCCESS &&
13808 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
13809 isc_buffer_putstr(&buffer, "<UNKNOWN>");
13810
13811 if (isc_buffer_availablelength(&buffer) > 0)
13812 isc_buffer_putstr(&buffer, "/");
13813 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
13814 }
13815
13816 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
13817 strcmp(zone->view->name, "_default") != 0 &&
13818 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
13819 isc_buffer_putstr(&buffer, "/");
13820 isc_buffer_putstr(&buffer, zone->view->name);
13821 }
13822 if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer))
13823 isc_buffer_putstr(&buffer, " (signed)");
13824 if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer))
13825 isc_buffer_putstr(&buffer, " (unsigned)");
13826
13827 buf[isc_buffer_usedlength(&buffer)] = '\0';
13828 }
13829
13830 static void
13831 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
13832 isc_result_t result = ISC_R_FAILURE;
13833 isc_buffer_t buffer;
13834
13835 REQUIRE(buf != NULL);
13836 REQUIRE(length > 1U);
13837
13838 /*
13839 * Leave space for terminating '\0'.
13840 */
13841 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
13842 if (dns_name_dynamic(&zone->origin))
13843 result = dns_name_totext(&zone->origin, true, &buffer);
13844 if (result != ISC_R_SUCCESS &&
13845 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
13846 isc_buffer_putstr(&buffer, "<UNKNOWN>");
13847
13848 buf[isc_buffer_usedlength(&buffer)] = '\0';
13849 }
13850
13851 static void
13852 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
13853 isc_buffer_t buffer;
13854
13855 REQUIRE(buf != NULL);
13856 REQUIRE(length > 1U);
13857
13858 /*
13859 * Leave space for terminating '\0'.
13860 */
13861 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
13862 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
13863
13864 buf[isc_buffer_usedlength(&buffer)] = '\0';
13865 }
13866
13867 static void
13868 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
13869 isc_buffer_t buffer;
13870
13871 REQUIRE(buf != NULL);
13872 REQUIRE(length > 1U);
13873
13874
13875 /*
13876 * Leave space for terminating '\0'.
13877 */
13878 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
13879
13880 if (zone->view == NULL) {
13881 isc_buffer_putstr(&buffer, "_none");
13882 } else if (strlen(zone->view->name)
13883 < isc_buffer_availablelength(&buffer)) {
13884 isc_buffer_putstr(&buffer, zone->view->name);
13885 } else {
13886 isc_buffer_putstr(&buffer, "_toolong");
13887 }
13888
13889 buf[isc_buffer_usedlength(&buffer)] = '\0';
13890 }
13891
13892 void
13893 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
13894 REQUIRE(DNS_ZONE_VALID(zone));
13895 REQUIRE(buf != NULL);
13896 zone_namerd_tostr(zone, buf, length);
13897 }
13898
13899 void
13900 dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) {
13901 REQUIRE(DNS_ZONE_VALID(zone));
13902 REQUIRE(buf != NULL);
13903 zone_name_tostr(zone, buf, length);
13904 }
13905
13906 void
13907 dns_zone_logv(dns_zone_t *zone, isc_logcategory_t *category, int level,
13908 const char *prefix, const char *fmt, va_list ap)
13909 {
13910 char message[4096];
13911 const char *zstr;
13912
13913 if (!isc_log_wouldlog(dns_lctx, level)) {
13914 return;
13915 }
13916
13917 vsnprintf(message, sizeof(message), fmt, ap);
13918
13919 switch (zone->type) {
13920 case dns_zone_key:
13921 zstr = "managed-keys-zone";
13922 break;
13923 case dns_zone_redirect:
13924 zstr = "redirect-zone";
13925 break;
13926 default:
13927 zstr = "zone ";
13928 }
13929
13930 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, level,
13931 "%s%s%s%s: %s",
13932 (prefix != NULL ? prefix : ""),
13933 (prefix != NULL ? ": " : ""),
13934 zstr, zone->strnamerd, message);
13935 }
13936
13937 static void
13938 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
13939 va_list ap;
13940
13941 va_start(ap, fmt);
13942 dns_zone_logv(zone, DNS_LOGCATEGORY_NOTIFY, level, NULL, fmt, ap);
13943 va_end(ap);
13944 }
13945
13946 void
13947 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
13948 int level, const char *fmt, ...)
13949 {
13950 va_list ap;
13951
13952 va_start(ap, fmt);
13953 dns_zone_logv(zone, category, level, NULL, fmt, ap);
13954 va_end(ap);
13955 }
13956
13957 void
13958 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
13959 va_list ap;
13960
13961 va_start(ap, fmt);
13962 dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, NULL, fmt, ap);
13963 va_end(ap);
13964 }
13965
13966 static void
13967 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
13968 const char *fmt, ...)
13969 {
13970 int level = ISC_LOG_DEBUG(debuglevel);
13971 va_list ap;
13972
13973 va_start(ap, fmt);
13974 dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, me, fmt, ap);
13975 va_end(ap);
13976 }
13977
13978 static int
13979 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
13980 {
13981 isc_result_t result;
13982 dns_name_t *name;
13983 dns_rdataset_t *curr;
13984 int count = 0;
13985
13986 result = dns_message_firstname(msg, section);
13987 while (result == ISC_R_SUCCESS) {
13988 name = NULL;
13989 dns_message_currentname(msg, section, &name);
13990
13991 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
13992 curr = ISC_LIST_PREV(curr, link)) {
13993 if (curr->type == type)
13994 count++;
13995 }
13996 result = dns_message_nextname(msg, section);
13997 }
13998
13999 return (count);
14000 }
14001
14002 void
14003 dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin) {
14004 REQUIRE(DNS_ZONE_VALID(zone));
14005
14006 zone->maxxfrin = maxxfrin;
14007 }
14008
14009 uint32_t
14010 dns_zone_getmaxxfrin(dns_zone_t *zone) {
14011 REQUIRE(DNS_ZONE_VALID(zone));
14012
14013 return (zone->maxxfrin);
14014 }
14015
14016 void
14017 dns_zone_setmaxxfrout(dns_zone_t *zone, uint32_t maxxfrout) {
14018 REQUIRE(DNS_ZONE_VALID(zone));
14019 zone->maxxfrout = maxxfrout;
14020 }
14021
14022 uint32_t
14023 dns_zone_getmaxxfrout(dns_zone_t *zone) {
14024 REQUIRE(DNS_ZONE_VALID(zone));
14025
14026 return (zone->maxxfrout);
14027 }
14028
14029 dns_zonetype_t
14030 dns_zone_gettype(dns_zone_t *zone) {
14031 REQUIRE(DNS_ZONE_VALID(zone));
14032
14033 return (zone->type);
14034 }
14035
14036 dns_zonetype_t
14037 dns_zone_getredirecttype(dns_zone_t *zone) {
14038 REQUIRE(DNS_ZONE_VALID(zone));
14039 REQUIRE(zone->type == dns_zone_redirect);
14040
14041 return (zone->masters == NULL ? dns_zone_master : dns_zone_slave);
14042 }
14043
14044 dns_name_t *
14045 dns_zone_getorigin(dns_zone_t *zone) {
14046 REQUIRE(DNS_ZONE_VALID(zone));
14047
14048 return (&zone->origin);
14049 }
14050
14051 void
14052 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
14053 REQUIRE(DNS_ZONE_VALID(zone));
14054
14055 LOCK_ZONE(zone);
14056 if (zone->task != NULL)
14057 isc_task_detach(&zone->task);
14058 isc_task_attach(task, &zone->task);
14059 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
14060 if (zone->db != NULL)
14061 dns_db_settask(zone->db, zone->task);
14062 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14063 UNLOCK_ZONE(zone);
14064 }
14065
14066 void
14067 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
14068 REQUIRE(DNS_ZONE_VALID(zone));
14069 isc_task_attach(zone->task, target);
14070 }
14071
14072 void
14073 dns_zone_setidlein(dns_zone_t *zone, uint32_t idlein) {
14074 REQUIRE(DNS_ZONE_VALID(zone));
14075
14076 if (idlein == 0)
14077 idlein = DNS_DEFAULT_IDLEIN;
14078 zone->idlein = idlein;
14079 }
14080
14081 uint32_t
14082 dns_zone_getidlein(dns_zone_t *zone) {
14083 REQUIRE(DNS_ZONE_VALID(zone));
14084
14085 return (zone->idlein);
14086 }
14087
14088 void
14089 dns_zone_setidleout(dns_zone_t *zone, uint32_t idleout) {
14090 REQUIRE(DNS_ZONE_VALID(zone));
14091
14092 zone->idleout = idleout;
14093 }
14094
14095 uint32_t
14096 dns_zone_getidleout(dns_zone_t *zone) {
14097 REQUIRE(DNS_ZONE_VALID(zone));
14098
14099 return (zone->idleout);
14100 }
14101
14102 static void
14103 notify_done(isc_task_t *task, isc_event_t *event) {
14104 dns_requestevent_t *revent = (dns_requestevent_t *)event;
14105 dns_notify_t *notify;
14106 isc_result_t result;
14107 dns_message_t *message = NULL;
14108 isc_buffer_t buf;
14109 char rcode[128];
14110 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
14111
14112 UNUSED(task);
14113
14114 notify = event->ev_arg;
14115 REQUIRE(DNS_NOTIFY_VALID(notify));
14116 INSIST(task == notify->zone->task);
14117
14118 isc_buffer_init(&buf, rcode, sizeof(rcode));
14119 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
14120
14121 result = revent->result;
14122 if (result == ISC_R_SUCCESS)
14123 result = dns_message_create(notify->zone->mctx,
14124 DNS_MESSAGE_INTENTPARSE, &message);
14125 if (result == ISC_R_SUCCESS)
14126 result = dns_request_getresponse(revent->request, message,
14127 DNS_MESSAGEPARSE_PRESERVEORDER);
14128 if (result == ISC_R_SUCCESS)
14129 result = dns_rcode_totext(message->rcode, &buf);
14130 if (result == ISC_R_SUCCESS)
14131 notify_log(notify->zone, ISC_LOG_DEBUG(3),
14132 "notify response from %s: %.*s",
14133 addrbuf, (int)buf.used, rcode);
14134 else
14135 notify_log(notify->zone, ISC_LOG_DEBUG(2),
14136 "notify to %s failed: %s", addrbuf,
14137 dns_result_totext(result));
14138
14139 /*
14140 * Old bind's return formerr if they see a soa record. Retry w/o
14141 * the soa if we see a formerr and had sent a SOA.
14142 */
14143 isc_event_free(&event);
14144 if (message != NULL && message->rcode == dns_rcode_formerr &&
14145 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
14146 bool startup;
14147
14148 notify->flags |= DNS_NOTIFY_NOSOA;
14149 dns_request_destroy(¬ify->request);
14150 startup = (notify->flags & DNS_NOTIFY_STARTUP);
14151 result = notify_send_queue(notify, startup);
14152 if (result != ISC_R_SUCCESS)
14153 notify_destroy(notify, false);
14154 } else {
14155 if (result == ISC_R_TIMEDOUT)
14156 notify_log(notify->zone, ISC_LOG_DEBUG(1),
14157 "notify to %s: retries exceeded", addrbuf);
14158 notify_destroy(notify, false);
14159 }
14160 if (message != NULL)
14161 dns_message_destroy(&message);
14162 }
14163
14164 struct secure_event {
14165 isc_event_t e;
14166 dns_db_t *db;
14167 uint32_t serial;
14168 };
14169
14170 static void
14171 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
14172 UNUSED(arg);
14173 dns_zone_log(zone, level, "%s", message);
14174 }
14175
14176 static isc_result_t
14177 sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
14178 uint32_t start, uint32_t end,
14179 dns_difftuple_t **soatuplep, dns_diff_t *diff)
14180 {
14181 isc_result_t result;
14182 dns_difftuple_t *tuple = NULL;
14183 dns_diffop_t op = DNS_DIFFOP_ADD;
14184 int n_soa = 0;
14185
14186 REQUIRE(soatuplep != NULL);
14187
14188 if (start == end)
14189 return (DNS_R_UNCHANGED);
14190
14191 CHECK(dns_journal_iter_init(journal, start, end));
14192 for (result = dns_journal_first_rr(journal);
14193 result == ISC_R_SUCCESS;
14194 result = dns_journal_next_rr(journal))
14195 {
14196 dns_name_t *name = NULL;
14197 uint32_t ttl;
14198 dns_rdata_t *rdata = NULL;
14199 dns_journal_current_rr(journal, &name, &ttl, &rdata);
14200
14201 if (rdata->type == dns_rdatatype_soa) {
14202 n_soa++;
14203 if (n_soa == 2) {
14204 /*
14205 * Save the latest raw SOA record.
14206 */
14207 if (*soatuplep != NULL)
14208 dns_difftuple_free(soatuplep);
14209 CHECK(dns_difftuple_create(diff->mctx,
14210 DNS_DIFFOP_ADD,
14211 name, ttl, rdata,
14212 soatuplep));
14213 }
14214 if (n_soa == 3)
14215 n_soa = 1;
14216 continue;
14217 }
14218
14219 /* Sanity. */
14220 if (n_soa == 0) {
14221 dns_zone_log(raw, ISC_LOG_ERROR,
14222 "corrupt journal file: '%s'\n",
14223 raw->journal);
14224 return (ISC_R_FAILURE);
14225 }
14226
14227 if (zone->privatetype != 0 &&
14228 rdata->type == zone->privatetype)
14229 continue;
14230
14231 if (rdata->type == dns_rdatatype_nsec ||
14232 rdata->type == dns_rdatatype_rrsig ||
14233 rdata->type == dns_rdatatype_nsec3 ||
14234 rdata->type == dns_rdatatype_dnskey ||
14235 rdata->type == dns_rdatatype_nsec3param)
14236 continue;
14237
14238 op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
14239
14240 CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
14241 &tuple));
14242 dns_diff_appendminimal(diff, &tuple);
14243 }
14244 if (result == ISC_R_NOMORE)
14245 result = ISC_R_SUCCESS;
14246
14247 failure:
14248 return(result);
14249 }
14250
14251 static isc_result_t
14252 sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb,
14253 dns_dbversion_t *secver, dns_difftuple_t **soatuple,
14254 dns_diff_t *diff)
14255 {
14256 isc_result_t result;
14257 dns_db_t *rawdb = NULL;
14258 dns_dbversion_t *rawver = NULL;
14259 dns_difftuple_t *tuple = NULL, *next;
14260 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
14261 dns_rdata_soa_t oldsoa, newsoa;
14262
14263 REQUIRE(DNS_ZONE_VALID(seczone));
14264 REQUIRE(soatuple != NULL && *soatuple == NULL);
14265
14266 if (!seczone->sourceserialset)
14267 return (DNS_R_UNCHANGED);
14268
14269 dns_db_attach(raw->db, &rawdb);
14270 dns_db_currentversion(rawdb, &rawver);
14271 result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
14272 dns_db_closeversion(rawdb, &rawver, false);
14273 dns_db_detach(&rawdb);
14274
14275 if (result != ISC_R_SUCCESS)
14276 return (result);
14277
14278 for (tuple = ISC_LIST_HEAD(diff->tuples);
14279 tuple != NULL;
14280 tuple = next)
14281 {
14282 next = ISC_LIST_NEXT(tuple, link);
14283 if (tuple->rdata.type == dns_rdatatype_nsec ||
14284 tuple->rdata.type == dns_rdatatype_rrsig ||
14285 tuple->rdata.type == dns_rdatatype_dnskey ||
14286 tuple->rdata.type == dns_rdatatype_nsec3 ||
14287 tuple->rdata.type == dns_rdatatype_nsec3param)
14288 {
14289 ISC_LIST_UNLINK(diff->tuples, tuple, link);
14290 dns_difftuple_free(&tuple);
14291 continue;
14292 }
14293 if (tuple->rdata.type == dns_rdatatype_soa) {
14294 if (tuple->op == DNS_DIFFOP_DEL) {
14295 INSIST(oldtuple == NULL);
14296 oldtuple = tuple;
14297 }
14298 if (tuple->op == DNS_DIFFOP_ADD) {
14299 INSIST(newtuple == NULL);
14300 newtuple = tuple;
14301 }
14302 }
14303 }
14304
14305 if (oldtuple != NULL && newtuple != NULL) {
14306
14307 result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL);
14308 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14309
14310 result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL);
14311 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14312
14313 /*
14314 * If the SOA records are the same except for the serial
14315 * remove them from the diff.
14316 */
14317 if (oldsoa.refresh == newsoa.refresh &&
14318 oldsoa.retry == newsoa.retry &&
14319 oldsoa.minimum == newsoa.minimum &&
14320 oldsoa.expire == newsoa.expire &&
14321 dns_name_equal(&oldsoa.origin, &newsoa.origin) &&
14322 dns_name_equal(&oldsoa.contact, &newsoa.contact)) {
14323 ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
14324 dns_difftuple_free(&oldtuple);
14325 ISC_LIST_UNLINK(diff->tuples, newtuple, link);
14326 dns_difftuple_free(&newtuple);
14327 }
14328 }
14329
14330 if (ISC_LIST_EMPTY(diff->tuples))
14331 return (DNS_R_UNCHANGED);
14332
14333 /*
14334 * If there are still SOA records in the diff they can now be removed
14335 * saving the new SOA record.
14336 */
14337 if (oldtuple != NULL) {
14338 ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
14339 dns_difftuple_free(&oldtuple);
14340 }
14341
14342 if (newtuple != NULL) {
14343 ISC_LIST_UNLINK(diff->tuples, newtuple, link);
14344 *soatuple = newtuple;
14345 }
14346
14347 return (ISC_R_SUCCESS);
14348 }
14349
14350 static void
14351 receive_secure_serial(isc_task_t *task, isc_event_t *event) {
14352 static char me[] = "receive_secure_serial";
14353 isc_result_t result = ISC_R_SUCCESS;
14354 dns_journal_t *rjournal = NULL;
14355 dns_journal_t *sjournal = NULL;
14356 uint32_t start, end;
14357 dns_zone_t *zone;
14358 dns_difftuple_t *tuple = NULL, *soatuple = NULL;
14359 dns_update_log_t log = { update_log_cb, NULL };
14360 uint32_t newserial = 0, desired = 0;
14361 isc_time_t timenow;
14362
14363 UNUSED(task);
14364
14365 zone = event->ev_arg;
14366 end = ((struct secure_event *)event)->serial;
14367
14368 ENTER;
14369
14370 LOCK_ZONE(zone);
14371
14372 /*
14373 * If we are already processing a receive secure serial event
14374 * for the zone, just queue the new one and exit.
14375 */
14376 if (zone->rss_event != NULL && zone->rss_event != event) {
14377 ISC_LIST_APPEND(zone->rss_events, event, ev_link);
14378 UNLOCK_ZONE(zone);
14379 return;
14380 }
14381
14382 nextevent:
14383 if (zone->rss_event != NULL) {
14384 INSIST(zone->rss_event == event);
14385 UNLOCK_ZONE(zone);
14386 } else {
14387 zone->rss_event = event;
14388 dns_diff_init(zone->mctx, &zone->rss_diff);
14389
14390 /*
14391 * zone->db may be NULL, if the load from disk failed.
14392 */
14393 result = ISC_R_SUCCESS;
14394 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
14395 if (zone->db != NULL)
14396 dns_db_attach(zone->db, &zone->rss_db);
14397 else
14398 result = ISC_R_FAILURE;
14399 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14400
14401 if (result == ISC_R_SUCCESS && zone->raw != NULL)
14402 dns_zone_attach(zone->raw, &zone->rss_raw);
14403 else
14404 result = ISC_R_FAILURE;
14405
14406 UNLOCK_ZONE(zone);
14407
14408 CHECK(result);
14409
14410 /*
14411 * We first attempt to sync the raw zone to the secure zone
14412 * by using the raw zone's journal, applying all the deltas
14413 * from the latest source-serial of the secure zone up to
14414 * the current serial number of the raw zone.
14415 *
14416 * If that fails, then we'll fall back to a direct comparison
14417 * between raw and secure zones.
14418 */
14419 CHECK(dns_journal_open(zone->rss_raw->mctx,
14420 zone->rss_raw->journal,
14421 DNS_JOURNAL_WRITE, &rjournal));
14422
14423 result = dns_journal_open(zone->mctx, zone->journal,
14424 DNS_JOURNAL_READ, &sjournal);
14425 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
14426 goto failure;
14427
14428 if (!dns_journal_get_sourceserial(rjournal, &start)) {
14429 start = dns_journal_first_serial(rjournal);
14430 dns_journal_set_sourceserial(rjournal, start);
14431 }
14432 if (sjournal != NULL) {
14433 uint32_t serial;
14434 /*
14435 * We read the secure journal first, if that
14436 * exists use its value provided it is greater
14437 * that from the raw journal.
14438 */
14439 if (dns_journal_get_sourceserial(sjournal, &serial)) {
14440 if (isc_serial_gt(serial, start))
14441 start = serial;
14442 }
14443 dns_journal_destroy(&sjournal);
14444 }
14445
14446 dns_db_currentversion(zone->rss_db, &zone->rss_oldver);
14447 CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver));
14448
14449 /*
14450 * Try to apply diffs from the raw zone's journal to the secure
14451 * zone. If that fails, we recover by syncing up the databases
14452 * directly.
14453 */
14454 result = sync_secure_journal(zone, zone->rss_raw, rjournal,
14455 start, end, &soatuple,
14456 &zone->rss_diff);
14457 if (result == DNS_R_UNCHANGED)
14458 goto failure;
14459 else if (result != ISC_R_SUCCESS)
14460 CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db,
14461 zone->rss_oldver, &soatuple,
14462 &zone->rss_diff));
14463
14464 CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db,
14465 zone->rss_newver));
14466
14467 if (soatuple != NULL) {
14468 uint32_t oldserial;
14469
14470 CHECK(dns_db_createsoatuple(zone->rss_db,
14471 zone->rss_oldver,
14472 zone->rss_diff.mctx,
14473 DNS_DIFFOP_DEL, &tuple));
14474 oldserial = dns_soa_getserial(&tuple->rdata);
14475 newserial = desired =
14476 dns_soa_getserial(&soatuple->rdata);
14477 if (!isc_serial_gt(newserial, oldserial)) {
14478 newserial = oldserial + 1;
14479 if (newserial == 0)
14480 newserial++;
14481 dns_soa_setserial(newserial, &soatuple->rdata);
14482 }
14483 CHECK(do_one_tuple(&tuple, zone->rss_db,
14484 zone->rss_newver, &zone->rss_diff));
14485 CHECK(do_one_tuple(&soatuple, zone->rss_db,
14486 zone->rss_newver, &zone->rss_diff));
14487 } else
14488 CHECK(update_soa_serial(zone->rss_db, zone->rss_newver,
14489 &zone->rss_diff, zone->mctx,
14490 zone->updatemethod));
14491
14492 }
14493 result = dns_update_signaturesinc(&log, zone, zone->rss_db,
14494 zone->rss_oldver, zone->rss_newver,
14495 &zone->rss_diff,
14496 zone->sigvalidityinterval,
14497 &zone->rss_state);
14498 if (result == DNS_R_CONTINUE) {
14499 if (rjournal != NULL)
14500 dns_journal_destroy(&rjournal);
14501 isc_task_send(task, &event);
14502 fprintf(stderr, "looping on dns_update_signaturesinc\n");
14503 return;
14504 }
14505 /*
14506 * If something went wrong while trying to update the secure zone and
14507 * the latter was already signed before, do not apply raw zone deltas
14508 * to it as that would break existing DNSSEC signatures. However, if
14509 * the secure zone was not yet signed (e.g. because no signing keys
14510 * were created for it), commence applying raw zone deltas to it so
14511 * that contents of the raw zone and the secure zone are kept in sync.
14512 */
14513 if (result != ISC_R_SUCCESS && dns_db_issecure(zone->rss_db)) {
14514 goto failure;
14515 }
14516
14517 if (rjournal == NULL)
14518 CHECK(dns_journal_open(zone->rss_raw->mctx,
14519 zone->rss_raw->journal,
14520 DNS_JOURNAL_WRITE, &rjournal));
14521 CHECK(zone_journal(zone, &zone->rss_diff, &end,
14522 "receive_secure_serial"));
14523
14524 dns_journal_set_sourceserial(rjournal, end);
14525 dns_journal_commit(rjournal);
14526
14527 LOCK_ZONE(zone);
14528 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
14529
14530 zone->sourceserial = end;
14531 zone->sourceserialset = true;
14532 zone_needdump(zone, DNS_DUMP_DELAY);
14533
14534 TIME_NOW(&timenow);
14535 zone_settimer(zone, &timenow);
14536 UNLOCK_ZONE(zone);
14537
14538 dns_db_closeversion(zone->rss_db, &zone->rss_oldver, false);
14539 dns_db_closeversion(zone->rss_db, &zone->rss_newver, true);
14540
14541 if (newserial != 0) {
14542 dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)",
14543 newserial, desired);
14544 }
14545
14546 failure:
14547 isc_event_free(&zone->rss_event);
14548 event = ISC_LIST_HEAD(zone->rss_events);
14549
14550 if (zone->rss_raw != NULL)
14551 dns_zone_detach(&zone->rss_raw);
14552 if (result != ISC_R_SUCCESS)
14553 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s",
14554 dns_result_totext(result));
14555 if (tuple != NULL)
14556 dns_difftuple_free(&tuple);
14557 if (soatuple != NULL)
14558 dns_difftuple_free(&soatuple);
14559 if (zone->rss_db != NULL) {
14560 if (zone->rss_oldver != NULL)
14561 dns_db_closeversion(zone->rss_db, &zone->rss_oldver,
14562 false);
14563 if (zone->rss_newver != NULL)
14564 dns_db_closeversion(zone->rss_db, &zone->rss_newver,
14565 false);
14566 dns_db_detach(&zone->rss_db);
14567 }
14568 INSIST(zone->rss_oldver == NULL);
14569 INSIST(zone->rss_newver == NULL);
14570 if (rjournal != NULL)
14571 dns_journal_destroy(&rjournal);
14572 dns_diff_clear(&zone->rss_diff);
14573
14574 if (event != NULL) {
14575 LOCK_ZONE(zone);
14576 INSIST(zone->irefs > 1);
14577 zone->irefs--;
14578 ISC_LIST_UNLINK(zone->rss_events, event, ev_link);
14579 goto nextevent;
14580 }
14581 dns_zone_idetach(&zone);
14582 }
14583
14584 static isc_result_t
14585 zone_send_secureserial(dns_zone_t *zone, uint32_t serial) {
14586 isc_event_t *e;
14587 dns_zone_t *dummy = NULL;
14588
14589 e = isc_event_allocate(zone->secure->mctx, zone,
14590 DNS_EVENT_ZONESECURESERIAL,
14591 receive_secure_serial, zone->secure,
14592 sizeof(struct secure_event));
14593 if (e == NULL)
14594 return (ISC_R_NOMEMORY);
14595 ((struct secure_event *)e)->serial = serial;
14596 INSIST(LOCKED_ZONE(zone->secure));
14597 zone_iattach(zone->secure, &dummy);
14598 isc_task_send(zone->secure->task, &e);
14599
14600 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
14601 return (ISC_R_SUCCESS);
14602 }
14603
14604 static isc_result_t
14605 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
14606 dns_rdataset_t *rdataset, uint32_t oldserial)
14607 {
14608 dns_rdata_soa_t soa;
14609 dns_rdata_t rdata = DNS_RDATA_INIT;
14610 dns_rdatalist_t temprdatalist;
14611 dns_rdataset_t temprdataset;
14612 isc_buffer_t b;
14613 isc_result_t result;
14614 unsigned char buf[DNS_SOA_BUFFERSIZE];
14615 dns_fixedname_t fixed;
14616 dns_name_t *name;
14617
14618 result = dns_rdataset_first(rdataset);
14619 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14620 dns_rdataset_current(rdataset, &rdata);
14621 result = dns_rdata_tostruct(&rdata, &soa, NULL);
14622 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14623
14624 if (isc_serial_gt(soa.serial, oldserial))
14625 return (dns_db_addrdataset(db, node, version, 0, rdataset, 0,
14626 NULL));
14627 /*
14628 * Always bump the serial.
14629 */
14630 oldserial++;
14631 if (oldserial == 0)
14632 oldserial++;
14633 soa.serial = oldserial;
14634
14635 /*
14636 * Construct a replacement rdataset.
14637 */
14638 dns_rdata_reset(&rdata);
14639 isc_buffer_init(&b, buf, sizeof(buf));
14640 result = dns_rdata_fromstruct(&rdata, rdataset->rdclass,
14641 dns_rdatatype_soa, &soa, &b);
14642 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14643 dns_rdatalist_init(&temprdatalist);
14644 temprdatalist.rdclass = rdata.rdclass;
14645 temprdatalist.type = rdata.type;
14646 temprdatalist.ttl = rdataset->ttl;
14647 ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link);
14648
14649 dns_rdataset_init(&temprdataset);
14650 result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
14651 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14652
14653 name = dns_fixedname_initname(&fixed);
14654 result = dns_db_nodefullname(db, node, name);
14655 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14656 dns_rdataset_getownercase(rdataset, name);
14657 dns_rdataset_setownercase(&temprdataset, name);
14658 return (dns_db_addrdataset(db, node, version, 0, &temprdataset,
14659 0, NULL));
14660 }
14661
14662 /*
14663 * This function should populate an nsec3paramlist_t with the
14664 * nsecparam_t data from a zone.
14665 */
14666 static isc_result_t
14667 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
14668 isc_result_t result;
14669 dns_dbnode_t *node = NULL;
14670 dns_rdataset_t rdataset, prdataset;
14671 dns_dbversion_t *version = NULL;
14672 nsec3param_t *nsec3param = NULL;
14673 nsec3param_t *nsec3p = NULL;
14674 nsec3param_t *next;
14675 dns_db_t *db = NULL;
14676 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
14677
14678 REQUIRE(DNS_ZONE_VALID(zone));
14679 REQUIRE(nsec3list != NULL);
14680 REQUIRE(ISC_LIST_EMPTY(*nsec3list));
14681
14682 dns_rdataset_init(&rdataset);
14683 dns_rdataset_init(&prdataset);
14684
14685 dns_db_attach(zone->db, &db);
14686 CHECK(dns_db_getoriginnode(db, &node));
14687
14688 dns_db_currentversion(db, &version);
14689 result = dns_db_findrdataset(db, node, version,
14690 dns_rdatatype_nsec3param,
14691 dns_rdatatype_none, 0, &rdataset, NULL);
14692
14693 if (result != ISC_R_SUCCESS)
14694 goto getprivate;
14695
14696 /*
14697 * walk nsec3param rdataset making a list of parameters (note that
14698 * multiple simultaneous nsec3 chains are annoyingly legal -- this
14699 * is why we use an nsec3list, even tho we will usually only have
14700 * one)
14701 */
14702 for (result = dns_rdataset_first(&rdataset);
14703 result == ISC_R_SUCCESS;
14704 result = dns_rdataset_next(&rdataset))
14705 {
14706 dns_rdata_t rdata = DNS_RDATA_INIT;
14707 dns_rdata_t private = DNS_RDATA_INIT;
14708
14709 dns_rdataset_current(&rdataset, &rdata);
14710 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
14711 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
14712 "looping through nsec3param data");
14713 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
14714 if (nsec3param == NULL)
14715 CHECK(ISC_R_NOMEMORY);
14716 ISC_LINK_INIT(nsec3param, link);
14717
14718 /*
14719 * now transfer the data from the rdata to
14720 * the nsec3param
14721 */
14722 dns_nsec3param_toprivate(&rdata, &private,
14723 zone->privatetype, nsec3param->data,
14724 sizeof(nsec3param->data));
14725 nsec3param->length = private.length;
14726 ISC_LIST_APPEND(*nsec3list, nsec3param, link);
14727 }
14728
14729 getprivate:
14730 result = dns_db_findrdataset(db, node, version, zone->privatetype,
14731 dns_rdatatype_none, 0, &prdataset, NULL);
14732 if (result != ISC_R_SUCCESS)
14733 goto done;
14734
14735 /*
14736 * walk private type records, converting them to nsec3 parameters
14737 * using dns_nsec3param_fromprivate(), do the right thing based on
14738 * CREATE and REMOVE flags
14739 */
14740 for (result = dns_rdataset_first(&prdataset);
14741 result == ISC_R_SUCCESS;
14742 result = dns_rdataset_next(&prdataset))
14743 {
14744 dns_rdata_t rdata = DNS_RDATA_INIT;
14745 dns_rdata_t private = DNS_RDATA_INIT;
14746
14747 dns_rdataset_current(&prdataset, &private);
14748 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
14749 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
14750 "looping through nsec3param private data");
14751
14752 /*
14753 * Do we have a valid private record?
14754 */
14755 if (!dns_nsec3param_fromprivate(&private, &rdata,
14756 buf, sizeof(buf)))
14757 continue;
14758
14759 /*
14760 * Remove any NSEC3PARAM records scheduled to be removed.
14761 */
14762 if (NSEC3REMOVE(rdata.data[1])) {
14763 /*
14764 * Zero out the flags.
14765 */
14766 rdata.data[1] = 0;
14767
14768 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
14769 nsec3p != NULL;
14770 nsec3p = next)
14771 {
14772 next = ISC_LIST_NEXT(nsec3p, link);
14773
14774 if (nsec3p->length == rdata.length + 1 &&
14775 memcmp(rdata.data, nsec3p->data + 1,
14776 nsec3p->length - 1) == 0) {
14777 ISC_LIST_UNLINK(*nsec3list,
14778 nsec3p, link);
14779 isc_mem_put(zone->mctx, nsec3p,
14780 sizeof(nsec3param_t));
14781 }
14782 }
14783 continue;
14784 }
14785
14786 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
14787 if (nsec3param == NULL)
14788 CHECK(ISC_R_NOMEMORY);
14789 ISC_LINK_INIT(nsec3param, link);
14790
14791 /*
14792 * Copy the remaining private records so the nsec/nsec3
14793 * chain gets created.
14794 */
14795 INSIST(private.length <= sizeof(nsec3param->data));
14796 memmove(nsec3param->data, private.data, private.length);
14797 nsec3param->length = private.length;
14798 ISC_LIST_APPEND(*nsec3list, nsec3param, link);
14799 }
14800
14801 done:
14802 if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND)
14803 result = ISC_R_SUCCESS;
14804
14805 failure:
14806 if (node != NULL)
14807 dns_db_detachnode(db, &node);
14808 if (version != NULL)
14809 dns_db_closeversion(db, &version, false);
14810 if (db != NULL)
14811 dns_db_detach(&db);
14812 if (dns_rdataset_isassociated(&rdataset))
14813 dns_rdataset_disassociate(&rdataset);
14814 if (dns_rdataset_isassociated(&prdataset))
14815 dns_rdataset_disassociate(&prdataset);
14816 return (result);
14817 }
14818
14819 /*
14820 * Populate new zone db with private type records found by save_nsec3param().
14821 */
14822 static isc_result_t
14823 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
14824 nsec3paramlist_t *nsec3list)
14825 {
14826 isc_result_t result;
14827 dns_diff_t diff;
14828 dns_rdata_t rdata;
14829 nsec3param_t *nsec3p = NULL;
14830 nsec3param_t *next;
14831
14832 REQUIRE(DNS_ZONE_VALID(zone));
14833 REQUIRE(!ISC_LIST_EMPTY(*nsec3list));
14834
14835 dns_diff_init(zone->mctx, &diff);
14836
14837 /*
14838 * Loop through the list of private-type records, set the INITIAL
14839 * and CREATE flags, and the add the record to the apex of the tree
14840 * in db.
14841 */
14842 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
14843 nsec3p != NULL;
14844 nsec3p = next)
14845 {
14846 next = ISC_LIST_NEXT(nsec3p, link);
14847 dns_rdata_init(&rdata);
14848 nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL;
14849 rdata.length = nsec3p->length;
14850 rdata.data = nsec3p->data;
14851 rdata.type = zone->privatetype;
14852 rdata.rdclass = zone->rdclass;
14853 result = update_one_rr(db, version, &diff, DNS_DIFFOP_ADD,
14854 &zone->origin, 0, &rdata);
14855 if (result != ISC_R_SUCCESS) {
14856 break;
14857 }
14858 }
14859
14860 dns_diff_clear(&diff);
14861 return (result);
14862 }
14863
14864 static void
14865 receive_secure_db(isc_task_t *task, isc_event_t *event) {
14866 isc_result_t result;
14867 dns_zone_t *zone;
14868 dns_db_t *rawdb, *db = NULL;
14869 dns_dbnode_t *rawnode = NULL, *node = NULL;
14870 dns_fixedname_t fname;
14871 dns_name_t *name;
14872 dns_dbiterator_t *dbiterator = NULL;
14873 dns_rdatasetiter_t *rdsit = NULL;
14874 dns_rdataset_t rdataset;
14875 dns_dbversion_t *version = NULL;
14876 isc_time_t loadtime;
14877 unsigned int oldserial = 0;
14878 bool have_oldserial = false;
14879 nsec3paramlist_t nsec3list;
14880 isc_event_t *setnsec3param_event;
14881 dns_zone_t *dummy;
14882
14883 UNUSED(task);
14884
14885 ISC_LIST_INIT(nsec3list);
14886
14887 zone = event->ev_arg;
14888 rawdb = ((struct secure_event *)event)->db;
14889 isc_event_free(&event);
14890
14891 name = dns_fixedname_initname(&fname);
14892 dns_rdataset_init(&rdataset);
14893
14894 LOCK_ZONE(zone);
14895 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) {
14896 result = ISC_R_SHUTTINGDOWN;
14897 goto failure;
14898 }
14899
14900 TIME_NOW(&loadtime);
14901 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
14902 if (zone->db != NULL) {
14903 result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
14904 if (result == ISC_R_SUCCESS)
14905 have_oldserial = true;
14906
14907 /*
14908 * assemble nsec3parameters from the old zone, and set a flag
14909 * if any are found
14910 */
14911 result = save_nsec3param(zone, &nsec3list);
14912 if (result != ISC_R_SUCCESS) {
14913 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14914 goto failure;
14915 }
14916 }
14917 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14918
14919 result = dns_db_create(zone->mctx, zone->db_argv[0],
14920 &zone->origin, dns_dbtype_zone, zone->rdclass,
14921 zone->db_argc - 1, zone->db_argv + 1, &db);
14922 if (result != ISC_R_SUCCESS)
14923 goto failure;
14924
14925 result = dns_db_setgluecachestats(db, zone->gluecachestats);
14926 if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
14927 goto failure;
14928 }
14929
14930 result = dns_db_newversion(db, &version);
14931 if (result != ISC_R_SUCCESS)
14932 goto failure;
14933
14934 result = dns_db_createiterator(rawdb, 0, &dbiterator);
14935 if (result != ISC_R_SUCCESS)
14936 goto failure;
14937
14938 for (result = dns_dbiterator_first(dbiterator);
14939 result == ISC_R_SUCCESS;
14940 result = dns_dbiterator_next(dbiterator)) {
14941 result = dns_dbiterator_current(dbiterator, &rawnode, name);
14942 if (result != ISC_R_SUCCESS)
14943 continue;
14944
14945 result = dns_db_findnode(db, name, true, &node);
14946 if (result != ISC_R_SUCCESS)
14947 goto failure;
14948
14949 result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit);
14950 if (result != ISC_R_SUCCESS)
14951 goto failure;
14952
14953 for (result = dns_rdatasetiter_first(rdsit);
14954 result == ISC_R_SUCCESS;
14955 result = dns_rdatasetiter_next(rdsit)) {
14956 dns_rdatasetiter_current(rdsit, &rdataset);
14957 if (rdataset.type == dns_rdatatype_nsec ||
14958 rdataset.type == dns_rdatatype_rrsig ||
14959 rdataset.type == dns_rdatatype_nsec3 ||
14960 rdataset.type == dns_rdatatype_dnskey ||
14961 rdataset.type == dns_rdatatype_nsec3param) {
14962 dns_rdataset_disassociate(&rdataset);
14963 continue;
14964 }
14965 if (rdataset.type == dns_rdatatype_soa &&
14966 have_oldserial) {
14967 result = checkandaddsoa(db, node, version,
14968 &rdataset, oldserial);
14969 } else
14970 result = dns_db_addrdataset(db, node, version,
14971 0, &rdataset, 0,
14972 NULL);
14973 if (result != ISC_R_SUCCESS)
14974 goto failure;
14975
14976 dns_rdataset_disassociate(&rdataset);
14977 }
14978 dns_rdatasetiter_destroy(&rdsit);
14979 dns_db_detachnode(rawdb, &rawnode);
14980 dns_db_detachnode(db, &node);
14981 }
14982
14983 /*
14984 * Call restore_nsec3param() to create private-type records from
14985 * the old nsec3 parameters and insert them into db
14986 */
14987 if (!ISC_LIST_EMPTY(nsec3list)) {
14988 result = restore_nsec3param(zone, db, version, &nsec3list);
14989 if (result != ISC_R_SUCCESS) {
14990 goto failure;
14991 }
14992 }
14993
14994 dns_db_closeversion(db, &version, true);
14995
14996 /*
14997 * Lock hierarchy: zmgr, zone, raw.
14998 */
14999 INSIST(zone != zone->raw);
15000 LOCK_ZONE(zone->raw);
15001 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
15002 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
15003 zone_needdump(zone, 0); /* XXXMPA */
15004 UNLOCK_ZONE(zone->raw);
15005
15006 /*
15007 * Process any queued NSEC3PARAM change requests.
15008 */
15009 while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
15010 setnsec3param_event = ISC_LIST_HEAD(zone->setnsec3param_queue);
15011 ISC_LIST_UNLINK(zone->setnsec3param_queue, setnsec3param_event,
15012 ev_link);
15013 dummy = NULL;
15014 zone_iattach(zone, &dummy);
15015 isc_task_send(zone->task, &setnsec3param_event);
15016 }
15017
15018 failure:
15019 UNLOCK_ZONE(zone);
15020 if (result != ISC_R_SUCCESS)
15021 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
15022 dns_result_totext(result));
15023
15024 while (!ISC_LIST_EMPTY(nsec3list)) {
15025 nsec3param_t *nsec3p;
15026 nsec3p = ISC_LIST_HEAD(nsec3list);
15027 ISC_LIST_UNLINK(nsec3list, nsec3p, link);
15028 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
15029 }
15030 if (dns_rdataset_isassociated(&rdataset))
15031 dns_rdataset_disassociate(&rdataset);
15032 if (db != NULL) {
15033 if (node != NULL)
15034 dns_db_detachnode(db, &node);
15035 if (version != NULL)
15036 dns_db_closeversion(db, &version, false);
15037 dns_db_detach(&db);
15038 }
15039 if (rawnode != NULL)
15040 dns_db_detachnode(rawdb, &rawnode);
15041 dns_db_detach(&rawdb);
15042 if (dbiterator != NULL)
15043 dns_dbiterator_destroy(&dbiterator);
15044 dns_zone_idetach(&zone);
15045
15046 INSIST(version == NULL);
15047 }
15048
15049 static isc_result_t
15050 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) {
15051 isc_event_t *e;
15052 dns_db_t *dummy = NULL;
15053 dns_zone_t *secure = NULL;
15054
15055 e = isc_event_allocate(zone->secure->mctx, zone,
15056 DNS_EVENT_ZONESECUREDB,
15057 receive_secure_db, zone->secure,
15058 sizeof(struct secure_event));
15059 if (e == NULL)
15060 return (ISC_R_NOMEMORY);
15061 dns_db_attach(db, &dummy);
15062 ((struct secure_event *)e)->db = dummy;
15063 INSIST(LOCKED_ZONE(zone->secure));
15064 zone_iattach(zone->secure, &secure);
15065 isc_task_send(zone->secure->task, &e);
15066 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
15067 return (ISC_R_SUCCESS);
15068 }
15069
15070 isc_result_t
15071 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
15072 isc_result_t result;
15073 dns_zone_t *secure = NULL;
15074
15075 REQUIRE(DNS_ZONE_VALID(zone));
15076 again:
15077 LOCK_ZONE(zone);
15078 if (inline_raw(zone)) {
15079 secure = zone->secure;
15080 INSIST(secure != zone);
15081 TRYLOCK_ZONE(result, secure);
15082 if (result != ISC_R_SUCCESS) {
15083 UNLOCK_ZONE(zone);
15084 secure = NULL;
15085 isc_thread_yield();
15086 goto again;
15087 }
15088 }
15089 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
15090 result = zone_replacedb(zone, db, dump);
15091 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
15092 if (secure != NULL)
15093 UNLOCK_ZONE(secure);
15094 UNLOCK_ZONE(zone);
15095 return (result);
15096 }
15097
15098 static isc_result_t
15099 zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
15100 dns_dbversion_t *ver;
15101 isc_result_t result;
15102 unsigned int soacount = 0;
15103 unsigned int nscount = 0;
15104
15105 /*
15106 * 'zone' and 'zone->db' locked by caller.
15107 */
15108 REQUIRE(DNS_ZONE_VALID(zone));
15109 REQUIRE(LOCKED_ZONE(zone));
15110 if (inline_raw(zone))
15111 REQUIRE(LOCKED_ZONE(zone->secure));
15112
15113 result = zone_get_from_db(zone, db, &nscount, &soacount,
15114 NULL, NULL, NULL, NULL, NULL, NULL);
15115 if (result == ISC_R_SUCCESS) {
15116 if (soacount != 1) {
15117 dns_zone_log(zone, ISC_LOG_ERROR,
15118 "has %d SOA records", soacount);
15119 result = DNS_R_BADZONE;
15120 }
15121 if (nscount == 0 && zone->type != dns_zone_key) {
15122 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
15123 result = DNS_R_BADZONE;
15124 }
15125 if (result != ISC_R_SUCCESS)
15126 return (result);
15127 } else {
15128 dns_zone_log(zone, ISC_LOG_ERROR,
15129 "retrieving SOA and NS records failed: %s",
15130 dns_result_totext(result));
15131 return (result);
15132 }
15133
15134 result = check_nsec3param(zone, db);
15135 if (result != ISC_R_SUCCESS)
15136 return (result);
15137
15138 ver = NULL;
15139 dns_db_currentversion(db, &ver);
15140
15141 /*
15142 * The initial version of a slave zone is always dumped;
15143 * subsequent versions may be journaled instead if this
15144 * is enabled in the configuration.
15145 */
15146 if (zone->db != NULL && zone->journal != NULL &&
15147 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
15148 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
15149 {
15150 uint32_t serial, oldserial;
15151
15152 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
15153
15154 result = dns_db_getsoaserial(db, ver, &serial);
15155 if (result != ISC_R_SUCCESS) {
15156 dns_zone_log(zone, ISC_LOG_ERROR,
15157 "ixfr-from-differences: unable to get "
15158 "new serial");
15159 goto fail;
15160 }
15161
15162 /*
15163 * This is checked in zone_postload() for master zones.
15164 */
15165 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
15166 &oldserial, NULL, NULL, NULL, NULL,
15167 NULL);
15168 RUNTIME_CHECK(result == ISC_R_SUCCESS);
15169 RUNTIME_CHECK(soacount > 0U);
15170 if ((zone->type == dns_zone_slave ||
15171 (zone->type == dns_zone_redirect &&
15172 zone->masters != NULL))
15173 && !isc_serial_gt(serial, oldserial)) {
15174 uint32_t serialmin, serialmax;
15175 serialmin = (oldserial + 1) & 0xffffffffU;
15176 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
15177 dns_zone_log(zone, ISC_LOG_ERROR,
15178 "ixfr-from-differences: failed: "
15179 "new serial (%u) out of range [%u - %u]",
15180 serial, serialmin, serialmax);
15181 result = ISC_R_RANGE;
15182 goto fail;
15183 }
15184
15185 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
15186 zone->journal);
15187 if (result != ISC_R_SUCCESS) {
15188 char strbuf[ISC_STRERRORSIZE];
15189 strerror_r(errno, strbuf, sizeof(strbuf));
15190 dns_zone_log(zone, ISC_LOG_ERROR,
15191 "ixfr-from-differences: failed: "
15192 "%s", strbuf);
15193 goto fallback;
15194 }
15195 if (dump)
15196 zone_needdump(zone, DNS_DUMP_DELAY);
15197 else
15198 zone_journal_compact(zone, zone->db, serial);
15199 if (zone->type == dns_zone_master && inline_raw(zone))
15200 zone_send_secureserial(zone, serial);
15201 } else {
15202 fallback:
15203 if (dump && zone->masterfile != NULL) {
15204 /*
15205 * If DNS_ZONEFLG_FORCEXFER was set we don't want
15206 * to keep the old masterfile.
15207 */
15208 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
15209 remove(zone->masterfile) < 0 && errno != ENOENT) {
15210 char strbuf[ISC_STRERRORSIZE];
15211 strerror_r(errno, strbuf, sizeof(strbuf));
15212 isc_log_write(dns_lctx,
15213 DNS_LOGCATEGORY_GENERAL,
15214 DNS_LOGMODULE_ZONE,
15215 ISC_LOG_WARNING,
15216 "unable to remove masterfile "
15217 "'%s': '%s'",
15218 zone->masterfile, strbuf);
15219 }
15220 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
15221 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
15222 else
15223 zone_needdump(zone, 0);
15224 }
15225 if (dump && zone->journal != NULL) {
15226 /*
15227 * The in-memory database just changed, and
15228 * because 'dump' is set, it didn't change by
15229 * being loaded from disk. Also, we have not
15230 * journaled diffs for this change.
15231 * Therefore, the on-disk journal is missing
15232 * the deltas for this change. Since it can
15233 * no longer be used to bring the zone
15234 * up-to-date, it is useless and should be
15235 * removed.
15236 */
15237 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
15238 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
15239 "removing journal file");
15240 if (remove(zone->journal) < 0 && errno != ENOENT) {
15241 char strbuf[ISC_STRERRORSIZE];
15242 strerror_r(errno, strbuf, sizeof(strbuf));
15243 isc_log_write(dns_lctx,
15244 DNS_LOGCATEGORY_GENERAL,
15245 DNS_LOGMODULE_ZONE,
15246 ISC_LOG_WARNING,
15247 "unable to remove journal "
15248 "'%s': '%s'",
15249 zone->journal, strbuf);
15250 }
15251 }
15252
15253 if (inline_raw(zone))
15254 zone_send_securedb(zone, db);
15255 }
15256
15257 dns_db_closeversion(db, &ver, false);
15258
15259 dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database");
15260
15261 if (zone->db != NULL)
15262 zone_detachdb(zone);
15263 zone_attachdb(zone, db);
15264 dns_db_settask(zone->db, zone->task);
15265 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
15266 return (ISC_R_SUCCESS);
15267
15268 fail:
15269 dns_db_closeversion(db, &ver, false);
15270 return (result);
15271 }
15272
15273 /* The caller must hold the dblock as a writer. */
15274 static inline void
15275 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
15276 REQUIRE(zone->db == NULL && db != NULL);
15277
15278 dns_db_attach(db, &zone->db);
15279 }
15280
15281 /* The caller must hold the dblock as a writer. */
15282 static inline void
15283 zone_detachdb(dns_zone_t *zone) {
15284 REQUIRE(zone->db != NULL);
15285
15286 dns_db_detach(&zone->db);
15287 }
15288
15289 static void
15290 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
15291 isc_time_t now;
15292 bool again = false;
15293 unsigned int soacount;
15294 unsigned int nscount;
15295 uint32_t serial, refresh, retry, expire, minimum;
15296 isc_result_t xfrresult = result;
15297 bool free_needed;
15298 dns_zone_t *secure = NULL;
15299
15300 REQUIRE(DNS_ZONE_VALID(zone));
15301
15302 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15303 "zone transfer finished: %s", dns_result_totext(result));
15304
15305 /*
15306 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
15307 * could result in a deadlock due to a LOR so we will spin if we
15308 * can't obtain the both locks.
15309 */
15310 again:
15311 LOCK_ZONE(zone);
15312 if (inline_raw(zone)) {
15313 secure = zone->secure;
15314 INSIST(secure != zone);
15315 TRYLOCK_ZONE(result, secure);
15316 if (result != ISC_R_SUCCESS) {
15317 UNLOCK_ZONE(zone);
15318 secure = NULL;
15319 isc_thread_yield();
15320 goto again;
15321 }
15322 }
15323
15324 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
15325 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
15326 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
15327
15328 TIME_NOW(&now);
15329 switch (xfrresult) {
15330 case ISC_R_SUCCESS:
15331 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
15332 /* FALLTHROUGH */
15333 case DNS_R_UPTODATE:
15334 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
15335 /*
15336 * Has the zone expired underneath us?
15337 */
15338 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
15339 if (zone->db == NULL) {
15340 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
15341 goto same_master;
15342 }
15343
15344 /*
15345 * Update the zone structure's data from the actual
15346 * SOA received.
15347 */
15348 nscount = 0;
15349 soacount = 0;
15350 INSIST(zone->db != NULL);
15351 result = zone_get_from_db(zone, zone->db, &nscount,
15352 &soacount, &serial, &refresh,
15353 &retry, &expire, &minimum, NULL);
15354 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
15355 if (result == ISC_R_SUCCESS) {
15356 if (soacount != 1)
15357 dns_zone_log(zone, ISC_LOG_ERROR,
15358 "transferred zone "
15359 "has %d SOA record%s", soacount,
15360 (soacount != 0) ? "s" : "");
15361 if (nscount == 0) {
15362 dns_zone_log(zone, ISC_LOG_ERROR,
15363 "transferred zone "
15364 "has no NS records");
15365 if (DNS_ZONE_FLAG(zone,
15366 DNS_ZONEFLG_HAVETIMERS)) {
15367 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
15368 zone->retry = DNS_ZONE_DEFAULTRETRY;
15369 }
15370 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
15371 zone_unload(zone);
15372 goto next_master;
15373 }
15374 zone->refresh = RANGE(refresh, zone->minrefresh,
15375 zone->maxrefresh);
15376 zone->retry = RANGE(retry, zone->minretry,
15377 zone->maxretry);
15378 zone->expire = RANGE(expire,
15379 zone->refresh + zone->retry,
15380 DNS_MAX_EXPIRE);
15381 zone->minimum = minimum;
15382 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
15383 }
15384
15385 /*
15386 * Set our next update/expire times.
15387 */
15388 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
15389 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
15390 zone->refreshtime = now;
15391 DNS_ZONE_TIME_ADD(&now, zone->expire,
15392 &zone->expiretime);
15393 } else {
15394 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
15395 &zone->refreshtime);
15396 DNS_ZONE_TIME_ADD(&now, zone->expire,
15397 &zone->expiretime);
15398 }
15399 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
15400 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
15401 if (zone->tsigkey != NULL) {
15402 char namebuf[DNS_NAME_FORMATSIZE];
15403 dns_name_format(&zone->tsigkey->name, namebuf,
15404 sizeof(namebuf));
15405 snprintf(buf, sizeof(buf), ": TSIG '%s'",
15406 namebuf);
15407 } else
15408 buf[0] = '\0';
15409 dns_zone_log(zone, ISC_LOG_INFO,
15410 "transferred serial %u%s",
15411 serial, buf);
15412 if (inline_raw(zone))
15413 zone_send_secureserial(zone, serial);
15414 }
15415
15416 /*
15417 * This is not necessary if we just performed a AXFR
15418 * however it is necessary for an IXFR / UPTODATE and
15419 * won't hurt with an AXFR.
15420 */
15421 if (zone->masterfile != NULL || zone->journal != NULL) {
15422 unsigned int delay = DNS_DUMP_DELAY;
15423
15424 result = ISC_R_FAILURE;
15425 if (zone->journal != NULL)
15426 result = isc_file_settime(zone->journal, &now);
15427 if (result != ISC_R_SUCCESS &&
15428 zone->masterfile != NULL)
15429 result = isc_file_settime(zone->masterfile,
15430 &now);
15431
15432 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
15433 result == ISC_R_FILENOTFOUND)
15434 delay = 0;
15435
15436 if ((result == ISC_R_SUCCESS ||
15437 result == ISC_R_FILENOTFOUND) &&
15438 zone->masterfile != NULL)
15439 zone_needdump(zone, delay);
15440 else if (result != ISC_R_SUCCESS)
15441 dns_zone_log(zone, ISC_LOG_ERROR,
15442 "transfer: could not set file "
15443 "modification time of '%s': %s",
15444 zone->masterfile,
15445 dns_result_totext(result));
15446 }
15447 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
15448 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
15449 break;
15450
15451 case DNS_R_BADIXFR:
15452 /* Force retry with AXFR. */
15453 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
15454 goto same_master;
15455
15456 case DNS_R_TOOMANYRECORDS:
15457 case DNS_R_VERIFYFAILURE:
15458 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
15459 inc_stats(zone, dns_zonestatscounter_xfrfail);
15460 break;
15461
15462 default:
15463 next_master:
15464 /*
15465 * Skip to next failed / untried master.
15466 */
15467 do {
15468 zone->curmaster++;
15469 } while (zone->curmaster < zone->masterscnt &&
15470 zone->mastersok[zone->curmaster]);
15471 /* FALLTHROUGH */
15472 same_master:
15473 if (zone->curmaster >= zone->masterscnt) {
15474 zone->curmaster = 0;
15475 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
15476 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
15477 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
15478 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
15479 while (zone->curmaster < zone->masterscnt &&
15480 zone->mastersok[zone->curmaster])
15481 zone->curmaster++;
15482 again = true;
15483 } else
15484 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
15485 } else {
15486 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
15487 again = true;
15488 }
15489 inc_stats(zone, dns_zonestatscounter_xfrfail);
15490 break;
15491 }
15492 zone_settimer(zone, &now);
15493
15494 /*
15495 * If creating the transfer object failed, zone->xfr is NULL.
15496 * Otherwise, we are called as the done callback of a zone
15497 * transfer object that just entered its shutting-down
15498 * state. Since we are no longer responsible for shutting
15499 * it down, we can detach our reference.
15500 */
15501 if (zone->xfr != NULL)
15502 dns_xfrin_detach(&zone->xfr);
15503
15504 if (zone->tsigkey != NULL)
15505 dns_tsigkey_detach(&zone->tsigkey);
15506
15507 /*
15508 * Handle any deferred journal compaction.
15509 */
15510 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
15511 dns_db_t *db = NULL;
15512 if (dns_zone_getdb(zone, &db) == ISC_R_SUCCESS) {
15513 zone_journal_compact(zone, db, zone->compact_serial);
15514 dns_db_detach(&db);
15515 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
15516 }
15517 }
15518
15519 if (secure != NULL)
15520 UNLOCK_ZONE(secure);
15521 /*
15522 * This transfer finishing freed up a transfer quota slot.
15523 * Let any other zones waiting for quota have it.
15524 */
15525 if (zone->zmgr != NULL &&
15526 zone->statelist == &zone->zmgr->xfrin_in_progress) {
15527 UNLOCK_ZONE(zone);
15528 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
15529 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
15530 zone->statelist = NULL;
15531 zmgr_resume_xfrs(zone->zmgr, false);
15532 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
15533 LOCK_ZONE(zone);
15534 }
15535
15536 /*
15537 * Retry with a different server if necessary.
15538 */
15539 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
15540 queue_soa_query(zone);
15541
15542 INSIST(zone->irefs > 0);
15543 zone->irefs--;
15544 free_needed = exit_check(zone);
15545 UNLOCK_ZONE(zone);
15546 if (free_needed)
15547 zone_free(zone);
15548 }
15549
15550 static void
15551 zone_loaddone(void *arg, isc_result_t result) {
15552 static char me[] = "zone_loaddone";
15553 dns_load_t *load = arg;
15554 dns_zone_t *zone;
15555 isc_result_t tresult;
15556 dns_zone_t *secure = NULL;
15557
15558 REQUIRE(DNS_LOAD_VALID(load));
15559 zone = load->zone;
15560
15561 ENTER;
15562
15563 tresult = dns_db_endload(load->db, &load->callbacks);
15564 if (tresult != ISC_R_SUCCESS &&
15565 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
15566 result = tresult;
15567
15568 /*
15569 * Lock hierarchy: zmgr, zone, raw.
15570 */
15571 again:
15572 LOCK_ZONE(zone);
15573 INSIST(zone != zone->raw);
15574 if (inline_secure(zone))
15575 LOCK_ZONE(zone->raw);
15576 else if (inline_raw(zone)) {
15577 secure = zone->secure;
15578 TRYLOCK_ZONE(result, secure);
15579 if (result != ISC_R_SUCCESS) {
15580 UNLOCK_ZONE(zone);
15581 secure = NULL;
15582 isc_thread_yield();
15583 goto again;
15584 }
15585 }
15586 (void)zone_postload(zone, load->db, load->loadtime, result);
15587 zonemgr_putio(&zone->readio);
15588 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING);
15589 zone_idetach(&load->callbacks.zone);
15590 /*
15591 * Leave the zone frozen if the reload fails.
15592 */
15593 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
15594 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW))
15595 zone->update_disabled = false;
15596 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW);
15597 if (inline_secure(zone))
15598 UNLOCK_ZONE(zone->raw);
15599 else if (secure != NULL)
15600 UNLOCK_ZONE(secure);
15601 UNLOCK_ZONE(zone);
15602
15603 load->magic = 0;
15604 dns_db_detach(&load->db);
15605 if (load->zone->lctx != NULL)
15606 dns_loadctx_detach(&load->zone->lctx);
15607 dns_zone_idetach(&load->zone);
15608 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
15609 }
15610
15611 void
15612 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
15613 REQUIRE(DNS_ZONE_VALID(zone));
15614 REQUIRE(table != NULL);
15615 REQUIRE(*table == NULL);
15616
15617 LOCK_ZONE(zone);
15618 if (zone->ssutable != NULL)
15619 dns_ssutable_attach(zone->ssutable, table);
15620 UNLOCK_ZONE(zone);
15621 }
15622
15623 void
15624 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
15625 REQUIRE(DNS_ZONE_VALID(zone));
15626
15627 LOCK_ZONE(zone);
15628 if (zone->ssutable != NULL)
15629 dns_ssutable_detach(&zone->ssutable);
15630 if (table != NULL)
15631 dns_ssutable_attach(table, &zone->ssutable);
15632 UNLOCK_ZONE(zone);
15633 }
15634
15635 void
15636 dns_zone_setsigvalidityinterval(dns_zone_t *zone, uint32_t interval) {
15637 REQUIRE(DNS_ZONE_VALID(zone));
15638
15639 zone->sigvalidityinterval = interval;
15640 }
15641
15642 uint32_t
15643 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
15644 REQUIRE(DNS_ZONE_VALID(zone));
15645
15646 return (zone->sigvalidityinterval);
15647 }
15648
15649 void
15650 dns_zone_setkeyvalidityinterval(dns_zone_t *zone, uint32_t interval) {
15651 REQUIRE(DNS_ZONE_VALID(zone));
15652
15653 zone->keyvalidityinterval = interval;
15654 }
15655
15656 uint32_t
15657 dns_zone_getkeyvalidityinterval(dns_zone_t *zone) {
15658 REQUIRE(DNS_ZONE_VALID(zone));
15659
15660 return (zone->keyvalidityinterval);
15661 }
15662
15663 void
15664 dns_zone_setsigresigninginterval(dns_zone_t *zone, uint32_t interval) {
15665 isc_time_t now;
15666
15667 REQUIRE(DNS_ZONE_VALID(zone));
15668
15669 LOCK_ZONE(zone);
15670 zone->sigresigninginterval = interval;
15671 set_resigntime(zone);
15672 if (zone->task != NULL) {
15673 TIME_NOW(&now);
15674 zone_settimer(zone, &now);
15675 }
15676 UNLOCK_ZONE(zone);
15677 }
15678
15679 uint32_t
15680 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
15681 REQUIRE(DNS_ZONE_VALID(zone));
15682
15683 return (zone->sigresigninginterval);
15684 }
15685
15686 static void
15687 queue_xfrin(dns_zone_t *zone) {
15688 const char me[] = "queue_xfrin";
15689 isc_result_t result;
15690 dns_zonemgr_t *zmgr = zone->zmgr;
15691
15692 ENTER;
15693
15694 INSIST(zone->statelist == NULL);
15695
15696 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15697 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
15698 LOCK_ZONE(zone);
15699 zone->irefs++;
15700 UNLOCK_ZONE(zone);
15701 zone->statelist = &zmgr->waiting_for_xfrin;
15702 result = zmgr_start_xfrin_ifquota(zmgr, zone);
15703 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
15704
15705 if (result == ISC_R_QUOTA) {
15706 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
15707 "zone transfer deferred due to quota");
15708 } else if (result != ISC_R_SUCCESS) {
15709 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
15710 "starting zone transfer: %s",
15711 isc_result_totext(result));
15712 }
15713 }
15714
15715 /*
15716 * This event callback is called when a zone has received
15717 * any necessary zone transfer quota. This is the time
15718 * to go ahead and start the transfer.
15719 */
15720 static void
15721 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
15722 isc_result_t result = ISC_R_SUCCESS;
15723 dns_peer_t *peer = NULL;
15724 char master[ISC_SOCKADDR_FORMATSIZE];
15725 char source[ISC_SOCKADDR_FORMATSIZE];
15726 dns_rdatatype_t xfrtype;
15727 dns_zone_t *zone = event->ev_arg;
15728 isc_netaddr_t masterip;
15729 isc_sockaddr_t sourceaddr;
15730 isc_sockaddr_t masteraddr;
15731 isc_time_t now;
15732 const char *soa_before = "";
15733 isc_dscp_t dscp = -1;
15734 bool loaded;
15735
15736 UNUSED(task);
15737
15738 INSIST(task == zone->task);
15739
15740 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
15741 result = ISC_R_CANCELED;
15742 goto cleanup;
15743 }
15744
15745 TIME_NOW(&now);
15746
15747 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
15748 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
15749 &zone->sourceaddr, &now))
15750 {
15751 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
15752 dns_zone_log(zone, ISC_LOG_INFO,
15753 "got_transfer_quota: skipping zone transfer as "
15754 "master %s (source %s) is unreachable (cached)",
15755 master, source);
15756 result = ISC_R_CANCELED;
15757 goto cleanup;
15758 }
15759
15760 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
15761 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
15762
15763 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
15764 soa_before = "SOA before ";
15765 /*
15766 * Decide whether we should request IXFR or AXFR.
15767 */
15768 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
15769 loaded = (zone->db != NULL);
15770 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
15771
15772 if (!loaded) {
15773 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15774 "no database exists yet, requesting AXFR of "
15775 "initial version from %s", master);
15776 xfrtype = dns_rdatatype_axfr;
15777 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
15778 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15779 "forced reload, requesting AXFR of "
15780 "initial version from %s", master);
15781 xfrtype = dns_rdatatype_axfr;
15782 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
15783 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15784 "retrying with AXFR from %s due to "
15785 "previous IXFR failure", master);
15786 xfrtype = dns_rdatatype_axfr;
15787 LOCK_ZONE(zone);
15788 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
15789 UNLOCK_ZONE(zone);
15790 } else {
15791 bool use_ixfr = true;
15792 if (peer != NULL)
15793 result = dns_peer_getrequestixfr(peer, &use_ixfr);
15794 if (peer == NULL || result != ISC_R_SUCCESS)
15795 use_ixfr = zone->requestixfr;
15796 if (use_ixfr == false) {
15797 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15798 "IXFR disabled, requesting %sAXFR from %s",
15799 soa_before, master);
15800 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
15801 xfrtype = dns_rdatatype_soa;
15802 else
15803 xfrtype = dns_rdatatype_axfr;
15804 } else {
15805 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15806 "requesting IXFR from %s", master);
15807 xfrtype = dns_rdatatype_ixfr;
15808 }
15809 }
15810
15811 /*
15812 * Determine if we should attempt to sign the request with TSIG.
15813 */
15814 result = ISC_R_NOTFOUND;
15815
15816 /*
15817 * First, look for a tsig key in the master statement, then
15818 * try for a server key.
15819 */
15820 if ((zone->masterkeynames != NULL) &&
15821 (zone->masterkeynames[zone->curmaster] != NULL)) {
15822 dns_view_t *view = dns_zone_getview(zone);
15823 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
15824 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
15825 }
15826 if (zone->tsigkey == NULL)
15827 result = dns_view_getpeertsig(zone->view, &masterip,
15828 &zone->tsigkey);
15829
15830 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
15831 dns_zone_log(zone, ISC_LOG_ERROR,
15832 "could not get TSIG key for zone transfer: %s",
15833 isc_result_totext(result));
15834 }
15835
15836 if (zone->masterdscps != NULL)
15837 dscp = zone->masterdscps[zone->curmaster];
15838
15839 LOCK_ZONE(zone);
15840 masteraddr = zone->masteraddr;
15841 sourceaddr = zone->sourceaddr;
15842 switch (isc_sockaddr_pf(&masteraddr)) {
15843 case PF_INET:
15844 if (dscp == -1)
15845 dscp = zone->xfrsource4dscp;
15846 break;
15847 case PF_INET6:
15848 if (dscp == -1)
15849 dscp = zone->xfrsource6dscp;
15850 break;
15851 default:
15852 INSIST(0);
15853 ISC_UNREACHABLE();
15854 }
15855 UNLOCK_ZONE(zone);
15856 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
15857 result = dns_xfrin_create(zone, xfrtype, &masteraddr, &sourceaddr,
15858 dscp, zone->tsigkey, zone->mctx,
15859 zone->zmgr->timermgr, zone->zmgr->socketmgr,
15860 zone->task, zone_xfrdone, &zone->xfr);
15861 if (result == ISC_R_SUCCESS) {
15862 LOCK_ZONE(zone);
15863 if (xfrtype == dns_rdatatype_axfr) {
15864 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
15865 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
15866 else
15867 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
15868 } else if (xfrtype == dns_rdatatype_ixfr) {
15869 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
15870 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
15871 else
15872 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
15873 }
15874 UNLOCK_ZONE(zone);
15875 }
15876 cleanup:
15877 /*
15878 * Any failure in this function is handled like a failed
15879 * zone transfer. This ensures that we get removed from
15880 * zmgr->xfrin_in_progress.
15881 */
15882 if (result != ISC_R_SUCCESS)
15883 zone_xfrdone(zone, result);
15884
15885 isc_event_free(&event);
15886 }
15887
15888 /*
15889 * Update forwarding support.
15890 */
15891
15892 static void
15893 forward_destroy(dns_forward_t *forward) {
15894
15895 forward->magic = 0;
15896 if (forward->request != NULL)
15897 dns_request_destroy(&forward->request);
15898 if (forward->msgbuf != NULL)
15899 isc_buffer_free(&forward->msgbuf);
15900 if (forward->zone != NULL) {
15901 LOCK(&forward->zone->lock);
15902 if (ISC_LINK_LINKED(forward, link))
15903 ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
15904 UNLOCK(&forward->zone->lock);
15905 dns_zone_idetach(&forward->zone);
15906 }
15907 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
15908 }
15909
15910 static isc_result_t
15911 sendtomaster(dns_forward_t *forward) {
15912 isc_result_t result;
15913 isc_sockaddr_t src;
15914 isc_dscp_t dscp = -1;
15915
15916 LOCK_ZONE(forward->zone);
15917
15918 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
15919 UNLOCK_ZONE(forward->zone);
15920 return (ISC_R_CANCELED);
15921 }
15922
15923 if (forward->which >= forward->zone->masterscnt) {
15924 UNLOCK_ZONE(forward->zone);
15925 return (ISC_R_NOMORE);
15926 }
15927
15928 forward->addr = forward->zone->masters[forward->which];
15929 /*
15930 * Always use TCP regardless of whether the original update
15931 * used TCP.
15932 * XXX The timeout may but a bit small if we are far down a
15933 * transfer graph and the master has to try several masters.
15934 */
15935 switch (isc_sockaddr_pf(&forward->addr)) {
15936 case PF_INET:
15937 src = forward->zone->xfrsource4;
15938 dscp = forward->zone->xfrsource4dscp;
15939 break;
15940 case PF_INET6:
15941 src = forward->zone->xfrsource6;
15942 dscp = forward->zone->xfrsource6dscp;
15943 break;
15944 default:
15945 result = ISC_R_NOTIMPLEMENTED;
15946 goto unlock;
15947 }
15948 result = dns_request_createraw(forward->zone->view->requestmgr,
15949 forward->msgbuf,
15950 &src, &forward->addr, dscp,
15951 forward->options, 15 /* XXX */,
15952 0, 0, forward->zone->task,
15953 forward_callback, forward,
15954 &forward->request);
15955 if (result == ISC_R_SUCCESS) {
15956 if (!ISC_LINK_LINKED(forward, link))
15957 ISC_LIST_APPEND(forward->zone->forwards, forward, link);
15958 }
15959
15960 unlock:
15961 UNLOCK_ZONE(forward->zone);
15962 return (result);
15963 }
15964
15965 static void
15966 forward_callback(isc_task_t *task, isc_event_t *event) {
15967 const char me[] = "forward_callback";
15968 dns_requestevent_t *revent = (dns_requestevent_t *)event;
15969 dns_message_t *msg = NULL;
15970 char master[ISC_SOCKADDR_FORMATSIZE];
15971 isc_result_t result;
15972 dns_forward_t *forward;
15973 dns_zone_t *zone;
15974
15975 UNUSED(task);
15976
15977 forward = revent->ev_arg;
15978 INSIST(DNS_FORWARD_VALID(forward));
15979 zone = forward->zone;
15980 INSIST(DNS_ZONE_VALID(zone));
15981
15982 ENTER;
15983
15984 isc_sockaddr_format(&forward->addr, master, sizeof(master));
15985
15986 if (revent->result != ISC_R_SUCCESS) {
15987 dns_zone_log(zone, ISC_LOG_INFO,
15988 "could not forward dynamic update to %s: %s",
15989 master, dns_result_totext(revent->result));
15990 goto next_master;
15991 }
15992
15993 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
15994 if (result != ISC_R_SUCCESS)
15995 goto next_master;
15996
15997 result = dns_request_getresponse(revent->request, msg,
15998 DNS_MESSAGEPARSE_PRESERVEORDER |
15999 DNS_MESSAGEPARSE_CLONEBUFFER);
16000 if (result != ISC_R_SUCCESS)
16001 goto next_master;
16002
16003 switch (msg->rcode) {
16004 /*
16005 * Pass these rcodes back to client.
16006 */
16007 case dns_rcode_noerror:
16008 case dns_rcode_yxdomain:
16009 case dns_rcode_yxrrset:
16010 case dns_rcode_nxrrset:
16011 case dns_rcode_refused:
16012 case dns_rcode_nxdomain: {
16013 char rcode[128];
16014 isc_buffer_t rb;
16015
16016 isc_buffer_init(&rb, rcode, sizeof(rcode));
16017 (void)dns_rcode_totext(msg->rcode, &rb);
16018 dns_zone_log(zone, ISC_LOG_INFO,
16019 "forwarded dynamic update: "
16020 "master %s returned: %.*s",
16021 master, (int)rb.used, rcode);
16022 break;
16023 }
16024
16025 /* These should not occur if the masters/zone are valid. */
16026 case dns_rcode_notzone:
16027 case dns_rcode_notauth: {
16028 char rcode[128];
16029 isc_buffer_t rb;
16030
16031 isc_buffer_init(&rb, rcode, sizeof(rcode));
16032 (void)dns_rcode_totext(msg->rcode, &rb);
16033 dns_zone_log(zone, ISC_LOG_WARNING,
16034 "forwarding dynamic update: "
16035 "unexpected response: master %s returned: %.*s",
16036 master, (int)rb.used, rcode);
16037 goto next_master;
16038 }
16039
16040 /* Try another server for these rcodes. */
16041 case dns_rcode_formerr:
16042 case dns_rcode_servfail:
16043 case dns_rcode_notimp:
16044 case dns_rcode_badvers:
16045 default:
16046 goto next_master;
16047 }
16048
16049 /* call callback */
16050 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
16051 msg = NULL;
16052 dns_request_destroy(&forward->request);
16053 forward_destroy(forward);
16054 isc_event_free(&event);
16055 return;
16056
16057 next_master:
16058 if (msg != NULL)
16059 dns_message_destroy(&msg);
16060 isc_event_free(&event);
16061 forward->which++;
16062 dns_request_destroy(&forward->request);
16063 result = sendtomaster(forward);
16064 if (result != ISC_R_SUCCESS) {
16065 /* call callback */
16066 dns_zone_log(zone, ISC_LOG_DEBUG(3),
16067 "exhausted dynamic update forwarder list");
16068 (forward->callback)(forward->callback_arg, result, NULL);
16069 forward_destroy(forward);
16070 }
16071 }
16072
16073 isc_result_t
16074 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
16075 dns_updatecallback_t callback, void *callback_arg)
16076 {
16077 dns_forward_t *forward;
16078 isc_result_t result;
16079 isc_region_t *mr;
16080
16081 REQUIRE(DNS_ZONE_VALID(zone));
16082 REQUIRE(msg != NULL);
16083 REQUIRE(callback != NULL);
16084
16085 forward = isc_mem_get(zone->mctx, sizeof(*forward));
16086 if (forward == NULL)
16087 return (ISC_R_NOMEMORY);
16088
16089 forward->request = NULL;
16090 forward->zone = NULL;
16091 forward->msgbuf = NULL;
16092 forward->which = 0;
16093 forward->mctx = 0;
16094 forward->callback = callback;
16095 forward->callback_arg = callback_arg;
16096 ISC_LINK_INIT(forward, link);
16097 forward->magic = FORWARD_MAGIC;
16098 forward->options = DNS_REQUESTOPT_TCP;
16099 /*
16100 * If we have a SIG(0) signed message we need to preserve the
16101 * query id as that is included in the SIG(0) computation.
16102 */
16103 if (msg->sig0 != NULL)
16104 forward->options |= DNS_REQUESTOPT_FIXEDID;
16105
16106 mr = dns_message_getrawmessage(msg);
16107 if (mr == NULL) {
16108 result = ISC_R_UNEXPECTEDEND;
16109 goto cleanup;
16110 }
16111
16112 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
16113 if (result != ISC_R_SUCCESS)
16114 goto cleanup;
16115 result = isc_buffer_copyregion(forward->msgbuf, mr);
16116 if (result != ISC_R_SUCCESS)
16117 goto cleanup;
16118
16119 isc_mem_attach(zone->mctx, &forward->mctx);
16120 dns_zone_iattach(zone, &forward->zone);
16121 result = sendtomaster(forward);
16122
16123 cleanup:
16124 if (result != ISC_R_SUCCESS) {
16125 forward_destroy(forward);
16126 }
16127 return (result);
16128 }
16129
16130 isc_result_t
16131 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
16132 REQUIRE(DNS_ZONE_VALID(zone));
16133 REQUIRE(next != NULL && *next == NULL);
16134
16135 *next = ISC_LIST_NEXT(zone, link);
16136 if (*next == NULL)
16137 return (ISC_R_NOMORE);
16138 else
16139 return (ISC_R_SUCCESS);
16140 }
16141
16142 isc_result_t
16143 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
16144 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16145 REQUIRE(first != NULL && *first == NULL);
16146
16147 *first = ISC_LIST_HEAD(zmgr->zones);
16148 if (*first == NULL)
16149 return (ISC_R_NOMORE);
16150 else
16151 return (ISC_R_SUCCESS);
16152 }
16153
16154 /***
16155 *** Zone manager.
16156 ***/
16157
16158 isc_result_t
16159 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
16160 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
16161 dns_zonemgr_t **zmgrp)
16162 {
16163 dns_zonemgr_t *zmgr;
16164 isc_result_t result;
16165
16166 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
16167 if (zmgr == NULL)
16168 return (ISC_R_NOMEMORY);
16169 zmgr->mctx = NULL;
16170 zmgr->refs = 1;
16171 isc_mem_attach(mctx, &zmgr->mctx);
16172 zmgr->taskmgr = taskmgr;
16173 zmgr->timermgr = timermgr;
16174 zmgr->socketmgr = socketmgr;
16175 zmgr->zonetasks = NULL;
16176 zmgr->loadtasks = NULL;
16177 zmgr->mctxpool = NULL;
16178 zmgr->task = NULL;
16179 zmgr->notifyrl = NULL;
16180 zmgr->refreshrl = NULL;
16181 zmgr->startupnotifyrl = NULL;
16182 zmgr->startuprefreshrl = NULL;
16183 ISC_LIST_INIT(zmgr->zones);
16184 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
16185 ISC_LIST_INIT(zmgr->xfrin_in_progress);
16186 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
16187 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
16188 if (result != ISC_R_SUCCESS)
16189 goto free_mem;
16190
16191 zmgr->transfersin = 10;
16192 zmgr->transfersperns = 2;
16193
16194 /* Unreachable lock. */
16195 result = isc_rwlock_init(&zmgr->urlock, 0, 0);
16196 if (result != ISC_R_SUCCESS)
16197 goto free_rwlock;
16198
16199 /* Create a single task for queueing of SOA queries. */
16200 result = isc_task_create(taskmgr, 1, &zmgr->task);
16201 if (result != ISC_R_SUCCESS)
16202 goto free_urlock;
16203
16204 isc_task_setname(zmgr->task, "zmgr", zmgr);
16205 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
16206 &zmgr->notifyrl);
16207 if (result != ISC_R_SUCCESS)
16208 goto free_task;
16209
16210 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
16211 &zmgr->refreshrl);
16212 if (result != ISC_R_SUCCESS)
16213 goto free_notifyrl;
16214
16215 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
16216 &zmgr->startupnotifyrl);
16217 if (result != ISC_R_SUCCESS)
16218 goto free_refreshrl;
16219
16220 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
16221 &zmgr->startuprefreshrl);
16222 if (result != ISC_R_SUCCESS)
16223 goto free_startupnotifyrl;
16224
16225 /* default to 20 refresh queries / notifies per second. */
16226 setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
16227 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
16228 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20);
16229 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20);
16230 isc_ratelimiter_setpushpop(zmgr->startupnotifyrl, true);
16231 isc_ratelimiter_setpushpop(zmgr->startuprefreshrl, true);
16232
16233 zmgr->iolimit = 1;
16234 zmgr->ioactive = 0;
16235 ISC_LIST_INIT(zmgr->high);
16236 ISC_LIST_INIT(zmgr->low);
16237
16238 isc_mutex_init(&zmgr->iolock);
16239
16240 zmgr->magic = ZONEMGR_MAGIC;
16241
16242 *zmgrp = zmgr;
16243 return (ISC_R_SUCCESS);
16244
16245 #if 0
16246 free_iolock:
16247 isc_mutex_destroy(&zmgr->iolock);
16248 #endif
16249 free_startupnotifyrl:
16250 isc_ratelimiter_detach(&zmgr->startupnotifyrl);
16251 free_refreshrl:
16252 isc_ratelimiter_detach(&zmgr->refreshrl);
16253 free_notifyrl:
16254 isc_ratelimiter_detach(&zmgr->notifyrl);
16255 free_task:
16256 isc_task_detach(&zmgr->task);
16257 free_urlock:
16258 isc_rwlock_destroy(&zmgr->urlock);
16259 free_rwlock:
16260 isc_rwlock_destroy(&zmgr->rwlock);
16261 free_mem:
16262 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
16263 isc_mem_detach(&mctx);
16264 return (result);
16265 }
16266
16267 isc_result_t
16268 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
16269 isc_result_t result;
16270 isc_mem_t *mctx = NULL;
16271 dns_zone_t *zone = NULL;
16272 void *item;
16273
16274 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16275 REQUIRE(zonep != NULL && *zonep == NULL);
16276
16277 if (zmgr->mctxpool == NULL)
16278 return (ISC_R_FAILURE);
16279
16280 item = isc_pool_get(zmgr->mctxpool);
16281 if (item == NULL)
16282 return (ISC_R_FAILURE);
16283
16284 isc_mem_attach((isc_mem_t *) item, &mctx);
16285 result = dns_zone_create(&zone, mctx);
16286 isc_mem_detach(&mctx);
16287
16288 if (result == ISC_R_SUCCESS)
16289 *zonep = zone;
16290
16291 return (result);
16292 }
16293
16294 isc_result_t
16295 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
16296 isc_result_t result;
16297
16298 REQUIRE(DNS_ZONE_VALID(zone));
16299 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16300
16301 if (zmgr->zonetasks == NULL)
16302 return (ISC_R_FAILURE);
16303
16304 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16305 LOCK_ZONE(zone);
16306 REQUIRE(zone->task == NULL);
16307 REQUIRE(zone->timer == NULL);
16308 REQUIRE(zone->zmgr == NULL);
16309
16310 isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
16311 isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
16312
16313 /*
16314 * Set the task name. The tag will arbitrarily point to one
16315 * of the zones sharing the task (in practice, the one
16316 * to be managed last).
16317 */
16318 isc_task_setname(zone->task, "zone", zone);
16319 isc_task_setname(zone->loadtask, "loadzone", zone);
16320
16321 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
16322 NULL, NULL,
16323 zone->task, zone_timer, zone,
16324 &zone->timer);
16325
16326 if (result != ISC_R_SUCCESS)
16327 goto cleanup_tasks;
16328
16329 /*
16330 * The timer "holds" a iref.
16331 */
16332 zone->irefs++;
16333 INSIST(zone->irefs != 0);
16334
16335 ISC_LIST_APPEND(zmgr->zones, zone, link);
16336 zone->zmgr = zmgr;
16337 zmgr->refs++;
16338
16339 goto unlock;
16340
16341 cleanup_tasks:
16342 isc_task_detach(&zone->loadtask);
16343 isc_task_detach(&zone->task);
16344
16345 unlock:
16346 UNLOCK_ZONE(zone);
16347 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16348 return (result);
16349 }
16350
16351 void
16352 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
16353 bool free_now = false;
16354
16355 REQUIRE(DNS_ZONE_VALID(zone));
16356 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16357 REQUIRE(zone->zmgr == zmgr);
16358
16359 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16360 LOCK_ZONE(zone);
16361
16362 ISC_LIST_UNLINK(zmgr->zones, zone, link);
16363 zone->zmgr = NULL;
16364 zmgr->refs--;
16365 if (zmgr->refs == 0)
16366 free_now = true;
16367
16368 UNLOCK_ZONE(zone);
16369 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16370
16371 if (free_now)
16372 zonemgr_free(zmgr);
16373 ENSURE(zone->zmgr == NULL);
16374 }
16375
16376 void
16377 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
16378 REQUIRE(DNS_ZONEMGR_VALID(source));
16379 REQUIRE(target != NULL && *target == NULL);
16380
16381 RWLOCK(&source->rwlock, isc_rwlocktype_write);
16382 REQUIRE(source->refs > 0);
16383 source->refs++;
16384 INSIST(source->refs > 0);
16385 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
16386 *target = source;
16387 }
16388
16389 void
16390 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
16391 dns_zonemgr_t *zmgr;
16392 bool free_now = false;
16393
16394 REQUIRE(zmgrp != NULL);
16395 zmgr = *zmgrp;
16396 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16397
16398 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16399 zmgr->refs--;
16400 if (zmgr->refs == 0)
16401 free_now = true;
16402 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16403
16404 if (free_now)
16405 zonemgr_free(zmgr);
16406 *zmgrp = NULL;
16407 }
16408
16409 isc_result_t
16410 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
16411 dns_zone_t *p;
16412
16413 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16414
16415 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
16416 for (p = ISC_LIST_HEAD(zmgr->zones);
16417 p != NULL;
16418 p = ISC_LIST_NEXT(p, link))
16419 {
16420 dns_zone_maintenance(p);
16421 }
16422 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
16423
16424 /*
16425 * Recent configuration changes may have increased the
16426 * amount of available transfers quota. Make sure any
16427 * transfers currently blocked on quota get started if
16428 * possible.
16429 */
16430 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16431 zmgr_resume_xfrs(zmgr, true);
16432 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16433 return (ISC_R_SUCCESS);
16434 }
16435
16436 void
16437 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
16438
16439 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16440
16441 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16442 zmgr_resume_xfrs(zmgr, true);
16443 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16444 }
16445
16446 void
16447 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
16448 dns_zone_t *zone;
16449
16450 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16451
16452 isc_ratelimiter_shutdown(zmgr->notifyrl);
16453 isc_ratelimiter_shutdown(zmgr->refreshrl);
16454 isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
16455 isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
16456
16457 if (zmgr->task != NULL)
16458 isc_task_destroy(&zmgr->task);
16459 if (zmgr->zonetasks != NULL)
16460 isc_taskpool_destroy(&zmgr->zonetasks);
16461 if (zmgr->loadtasks != NULL)
16462 isc_taskpool_destroy(&zmgr->loadtasks);
16463 if (zmgr->mctxpool != NULL)
16464 isc_pool_destroy(&zmgr->mctxpool);
16465
16466 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
16467 for (zone = ISC_LIST_HEAD(zmgr->zones);
16468 zone != NULL;
16469 zone = ISC_LIST_NEXT(zone, link))
16470 {
16471 LOCK_ZONE(zone);
16472 forward_cancel(zone);
16473 UNLOCK_ZONE(zone);
16474 }
16475 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
16476 }
16477
16478 static isc_result_t
16479 mctxinit(void **target, void *arg) {
16480 isc_result_t result;
16481 isc_mem_t *mctx = NULL;
16482
16483 UNUSED(arg);
16484
16485 REQUIRE(target != NULL && *target == NULL);
16486
16487 result = isc_mem_create(0, 0, &mctx);
16488 if (result != ISC_R_SUCCESS)
16489 return (result);
16490 isc_mem_setname(mctx, "zonemgr-pool", NULL);
16491
16492 *target = mctx;
16493 return (ISC_R_SUCCESS);
16494 }
16495
16496 static void
16497 mctxfree(void **target) {
16498 isc_mem_t *mctx = *(isc_mem_t **) target;
16499 isc_mem_detach(&mctx);
16500 *target = NULL;
16501 }
16502
16503 #define ZONES_PER_TASK 100
16504 #define ZONES_PER_MCTX 1000
16505
16506 isc_result_t
16507 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
16508 isc_result_t result;
16509 int ntasks = num_zones / ZONES_PER_TASK;
16510 int nmctx = num_zones / ZONES_PER_MCTX;
16511 isc_taskpool_t *pool = NULL;
16512 isc_pool_t *mctxpool = NULL;
16513
16514 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16515
16516 /*
16517 * For anything fewer than 1000 zones we use 10 tasks in
16518 * the task pools. More than that, and we'll scale at one
16519 * task per 100 zones. Similarly, for anything smaller than
16520 * 2000 zones we use 2 memory contexts, then scale at 1:1000.
16521 */
16522 if (ntasks < 10)
16523 ntasks = 10;
16524 if (nmctx < 2)
16525 nmctx = 2;
16526
16527 /* Create or resize the zone task pools. */
16528 if (zmgr->zonetasks == NULL)
16529 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
16530 ntasks, 2, &pool);
16531 else
16532 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
16533
16534 if (result == ISC_R_SUCCESS)
16535 zmgr->zonetasks = pool;
16536
16537 pool = NULL;
16538 if (zmgr->loadtasks == NULL)
16539 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
16540 ntasks, 2, &pool);
16541 else
16542 result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool);
16543
16544 if (result == ISC_R_SUCCESS)
16545 zmgr->loadtasks = pool;
16546
16547 /*
16548 * We always set all tasks in the zone-load task pool to
16549 * privileged. This prevents other tasks in the system from
16550 * running while the server task manager is in privileged
16551 * mode.
16552 *
16553 * NOTE: If we start using task privileges for any other
16554 * part of the system than zone tasks, then this will need to be
16555 * revisted. In that case we'd want to turn on privileges for
16556 * zone tasks only when we were loading, and turn them off the
16557 * rest of the time. For now, however, it's okay to just
16558 * set it and forget it.
16559 */
16560 isc_taskpool_setprivilege(zmgr->loadtasks, true);
16561
16562 /* Create or resize the zone memory context pool. */
16563 if (zmgr->mctxpool == NULL)
16564 result = isc_pool_create(zmgr->mctx, nmctx, mctxfree,
16565 mctxinit, NULL, &mctxpool);
16566 else
16567 result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
16568
16569 if (result == ISC_R_SUCCESS)
16570 zmgr->mctxpool = mctxpool;
16571
16572 return (result);
16573 }
16574
16575 static void
16576 zonemgr_free(dns_zonemgr_t *zmgr) {
16577 isc_mem_t *mctx;
16578
16579 INSIST(zmgr->refs == 0);
16580 INSIST(ISC_LIST_EMPTY(zmgr->zones));
16581
16582 zmgr->magic = 0;
16583
16584 isc_mutex_destroy(&zmgr->iolock);
16585 isc_ratelimiter_detach(&zmgr->notifyrl);
16586 isc_ratelimiter_detach(&zmgr->refreshrl);
16587 isc_ratelimiter_detach(&zmgr->startupnotifyrl);
16588 isc_ratelimiter_detach(&zmgr->startuprefreshrl);
16589
16590 isc_rwlock_destroy(&zmgr->urlock);
16591 isc_rwlock_destroy(&zmgr->rwlock);
16592 mctx = zmgr->mctx;
16593 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
16594 isc_mem_detach(&mctx);
16595 }
16596
16597 void
16598 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value) {
16599 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16600
16601 zmgr->transfersin = value;
16602 }
16603
16604 uint32_t
16605 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
16606 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16607
16608 return (zmgr->transfersin);
16609 }
16610
16611 void
16612 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, uint32_t value) {
16613 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16614
16615 zmgr->transfersperns = value;
16616 }
16617
16618 uint32_t
16619 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
16620 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16621
16622 return (zmgr->transfersperns);
16623 }
16624
16625 /*
16626 * Try to start a new incoming zone transfer to fill a quota
16627 * slot that was just vacated.
16628 *
16629 * Requires:
16630 * The zone manager is locked by the caller.
16631 */
16632 static void
16633 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi) {
16634 dns_zone_t *zone;
16635 dns_zone_t *next;
16636
16637 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
16638 zone != NULL;
16639 zone = next)
16640 {
16641 isc_result_t result;
16642 next = ISC_LIST_NEXT(zone, statelink);
16643 result = zmgr_start_xfrin_ifquota(zmgr, zone);
16644 if (result == ISC_R_SUCCESS) {
16645 if (multi)
16646 continue;
16647 /*
16648 * We successfully filled the slot. We're done.
16649 */
16650 break;
16651 } else if (result == ISC_R_QUOTA) {
16652 /*
16653 * Not enough quota. This is probably the per-server
16654 * quota, because we usually get called when a unit of
16655 * global quota has just been freed. Try the next
16656 * zone, it may succeed if it uses another master.
16657 */
16658 continue;
16659 } else {
16660 dns_zone_log(zone, ISC_LOG_DEBUG(1),
16661 "starting zone transfer: %s",
16662 isc_result_totext(result));
16663 break;
16664 }
16665 }
16666 }
16667
16668 /*
16669 * Try to start an incoming zone transfer for 'zone', quota permitting.
16670 *
16671 * Requires:
16672 * The zone manager is locked by the caller.
16673 *
16674 * Returns:
16675 * ISC_R_SUCCESS There was enough quota and we attempted to
16676 * start a transfer. zone_xfrdone() has been or will
16677 * be called.
16678 * ISC_R_QUOTA Not enough quota.
16679 * Others Failure.
16680 */
16681 static isc_result_t
16682 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
16683 dns_peer_t *peer = NULL;
16684 isc_netaddr_t masterip;
16685 uint32_t nxfrsin, nxfrsperns;
16686 dns_zone_t *x;
16687 uint32_t maxtransfersin, maxtransfersperns;
16688 isc_event_t *e;
16689
16690 /*
16691 * If we are exiting just pretend we got quota so the zone will
16692 * be cleaned up in the zone's task context.
16693 */
16694 LOCK_ZONE(zone);
16695 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
16696 UNLOCK_ZONE(zone);
16697 goto gotquota;
16698 }
16699
16700 /*
16701 * Find any configured information about the server we'd
16702 * like to transfer this zone from.
16703 */
16704 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
16705 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
16706 UNLOCK_ZONE(zone);
16707
16708 /*
16709 * Determine the total maximum number of simultaneous
16710 * transfers allowed, and the maximum for this specific
16711 * master.
16712 */
16713 maxtransfersin = zmgr->transfersin;
16714 maxtransfersperns = zmgr->transfersperns;
16715 if (peer != NULL)
16716 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
16717
16718 /*
16719 * Count the total number of transfers that are in progress,
16720 * and the number of transfers in progress from this master.
16721 * We linearly scan a list of all transfers; if this turns
16722 * out to be too slow, we could hash on the master address.
16723 */
16724 nxfrsin = nxfrsperns = 0;
16725 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
16726 x != NULL;
16727 x = ISC_LIST_NEXT(x, statelink))
16728 {
16729 isc_netaddr_t xip;
16730
16731 LOCK_ZONE(x);
16732 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
16733 UNLOCK_ZONE(x);
16734
16735 nxfrsin++;
16736 if (isc_netaddr_equal(&xip, &masterip))
16737 nxfrsperns++;
16738 }
16739
16740 /* Enforce quota. */
16741 if (nxfrsin >= maxtransfersin)
16742 return (ISC_R_QUOTA);
16743
16744 if (nxfrsperns >= maxtransfersperns)
16745 return (ISC_R_QUOTA);
16746
16747 gotquota:
16748 /*
16749 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
16750 * list and send it an event to let it start the actual transfer in the
16751 * context of its own task.
16752 */
16753 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
16754 got_transfer_quota, zone, sizeof(isc_event_t));
16755 if (e == NULL)
16756 return (ISC_R_NOMEMORY);
16757
16758 LOCK_ZONE(zone);
16759 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
16760 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
16761 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
16762 zone->statelist = &zmgr->xfrin_in_progress;
16763 isc_task_send(zone->task, &e);
16764 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
16765 UNLOCK_ZONE(zone);
16766
16767 return (ISC_R_SUCCESS);
16768 }
16769
16770 void
16771 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, uint32_t iolimit) {
16772
16773 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16774 REQUIRE(iolimit > 0);
16775
16776 zmgr->iolimit = iolimit;
16777 }
16778
16779 uint32_t
16780 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
16781
16782 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16783
16784 return (zmgr->iolimit);
16785 }
16786
16787 /*
16788 * Get permission to request a file handle from the OS.
16789 * An event will be sent to action when one is available.
16790 * There are two queues available (high and low), the high
16791 * queue will be serviced before the low one.
16792 *
16793 * zonemgr_putio() must be called after the event is delivered to
16794 * 'action'.
16795 */
16796
16797 static isc_result_t
16798 zonemgr_getio(dns_zonemgr_t *zmgr, bool high,
16799 isc_task_t *task, isc_taskaction_t action, void *arg,
16800 dns_io_t **iop)
16801 {
16802 dns_io_t *io;
16803 bool queue;
16804
16805 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16806 REQUIRE(iop != NULL && *iop == NULL);
16807
16808 io = isc_mem_get(zmgr->mctx, sizeof(*io));
16809 if (io == NULL)
16810 return (ISC_R_NOMEMORY);
16811
16812 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
16813 action, arg, sizeof(*io->event));
16814 if (io->event == NULL) {
16815 isc_mem_put(zmgr->mctx, io, sizeof(*io));
16816 return (ISC_R_NOMEMORY);
16817 }
16818
16819 io->zmgr = zmgr;
16820 io->high = high;
16821 io->task = NULL;
16822 isc_task_attach(task, &io->task);
16823 ISC_LINK_INIT(io, link);
16824 io->magic = IO_MAGIC;
16825
16826 LOCK(&zmgr->iolock);
16827 zmgr->ioactive++;
16828 queue = (zmgr->ioactive > zmgr->iolimit);
16829 if (queue) {
16830 if (io->high)
16831 ISC_LIST_APPEND(zmgr->high, io, link);
16832 else
16833 ISC_LIST_APPEND(zmgr->low, io, link);
16834 }
16835 UNLOCK(&zmgr->iolock);
16836 *iop = io;
16837
16838 if (!queue)
16839 isc_task_send(io->task, &io->event);
16840 return (ISC_R_SUCCESS);
16841 }
16842
16843 static void
16844 zonemgr_putio(dns_io_t **iop) {
16845 dns_io_t *io;
16846 dns_io_t *next;
16847 dns_zonemgr_t *zmgr;
16848
16849 REQUIRE(iop != NULL);
16850 io = *iop;
16851 REQUIRE(DNS_IO_VALID(io));
16852
16853 *iop = NULL;
16854
16855 INSIST(!ISC_LINK_LINKED(io, link));
16856 INSIST(io->event == NULL);
16857
16858 zmgr = io->zmgr;
16859 isc_task_detach(&io->task);
16860 io->magic = 0;
16861 isc_mem_put(zmgr->mctx, io, sizeof(*io));
16862
16863 LOCK(&zmgr->iolock);
16864 INSIST(zmgr->ioactive > 0);
16865 zmgr->ioactive--;
16866 next = HEAD(zmgr->high);
16867 if (next == NULL)
16868 next = HEAD(zmgr->low);
16869 if (next != NULL) {
16870 if (next->high)
16871 ISC_LIST_UNLINK(zmgr->high, next, link);
16872 else
16873 ISC_LIST_UNLINK(zmgr->low, next, link);
16874 INSIST(next->event != NULL);
16875 }
16876 UNLOCK(&zmgr->iolock);
16877 if (next != NULL)
16878 isc_task_send(next->task, &next->event);
16879 }
16880
16881 static void
16882 zonemgr_cancelio(dns_io_t *io) {
16883 bool send_event = false;
16884
16885 REQUIRE(DNS_IO_VALID(io));
16886
16887 /*
16888 * If we are queued to be run then dequeue.
16889 */
16890 LOCK(&io->zmgr->iolock);
16891 if (ISC_LINK_LINKED(io, link)) {
16892 if (io->high)
16893 ISC_LIST_UNLINK(io->zmgr->high, io, link);
16894 else
16895 ISC_LIST_UNLINK(io->zmgr->low, io, link);
16896
16897 send_event = true;
16898 INSIST(io->event != NULL);
16899 }
16900 UNLOCK(&io->zmgr->iolock);
16901 if (send_event) {
16902 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
16903 isc_task_send(io->task, &io->event);
16904 }
16905 }
16906
16907 static void
16908 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
16909 char *buf;
16910 int buflen;
16911 isc_result_t result;
16912
16913 buflen = strlen(path) + strlen(templat) + 2;
16914
16915 buf = isc_mem_get(zone->mctx, buflen);
16916 if (buf == NULL)
16917 return;
16918
16919 result = isc_file_template(path, templat, buf, buflen);
16920 if (result != ISC_R_SUCCESS)
16921 goto cleanup;
16922
16923 result = isc_file_renameunique(path, buf);
16924 if (result != ISC_R_SUCCESS)
16925 goto cleanup;
16926
16927 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
16928 "renaming file to '%s' for failure analysis and "
16929 "retransferring.", path, buf);
16930
16931 cleanup:
16932 isc_mem_put(zone->mctx, buf, buflen);
16933 }
16934
16935 static void
16936 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
16937 isc_interval_t interval;
16938 uint32_t s, ns;
16939 uint32_t pertic;
16940 isc_result_t result;
16941
16942 if (value == 0)
16943 value = 1;
16944
16945 if (value == 1) {
16946 s = 1;
16947 ns = 0;
16948 pertic = 1;
16949 } else if (value <= 10) {
16950 s = 0;
16951 ns = 1000000000 / value;
16952 pertic = 1;
16953 } else {
16954 s = 0;
16955 ns = (1000000000 / value) * 10;
16956 pertic = 10;
16957 }
16958
16959 isc_interval_set(&interval, s, ns);
16960
16961 result = isc_ratelimiter_setinterval(rl, &interval);
16962 RUNTIME_CHECK(result == ISC_R_SUCCESS);
16963 isc_ratelimiter_setpertic(rl, pertic);
16964
16965 *rate = value;
16966 }
16967
16968 void
16969 dns_zonemgr_setnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
16970
16971 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16972
16973 setrl(zmgr->notifyrl, &zmgr->notifyrate, value);
16974 }
16975
16976 void
16977 dns_zonemgr_setstartupnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
16978
16979 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16980
16981 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value);
16982 }
16983
16984 void
16985 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
16986
16987 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16988
16989 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value);
16990 /* XXXMPA seperate out once we have the code to support this. */
16991 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value);
16992 }
16993
16994 unsigned int
16995 dns_zonemgr_getnotifyrate(dns_zonemgr_t *zmgr) {
16996 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16997
16998 return (zmgr->notifyrate);
16999 }
17000
17001 unsigned int
17002 dns_zonemgr_getstartupnotifyrate(dns_zonemgr_t *zmgr) {
17003 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17004
17005 return (zmgr->startupnotifyrate);
17006 }
17007
17008 unsigned int
17009 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
17010 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17011
17012 return (zmgr->serialqueryrate);
17013 }
17014
17015 bool
17016 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
17017 isc_sockaddr_t *local, isc_time_t *now)
17018 {
17019 unsigned int i;
17020 isc_rwlocktype_t locktype;
17021 isc_result_t result;
17022 uint32_t seconds = isc_time_seconds(now);
17023 uint32_t count = 0;
17024
17025 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17026
17027 locktype = isc_rwlocktype_read;
17028 RWLOCK(&zmgr->urlock, locktype);
17029 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
17030 if (zmgr->unreachable[i].expire >= seconds &&
17031 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
17032 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
17033 result = isc_rwlock_tryupgrade(&zmgr->urlock);
17034 if (result == ISC_R_SUCCESS) {
17035 locktype = isc_rwlocktype_write;
17036 zmgr->unreachable[i].last = seconds;
17037 count = zmgr->unreachable[i].count;
17038 }
17039 break;
17040 }
17041 }
17042 RWUNLOCK(&zmgr->urlock, locktype);
17043 return (i < UNREACH_CHACHE_SIZE && count > 1U);
17044 }
17045
17046 void
17047 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
17048 isc_sockaddr_t *local)
17049 {
17050 unsigned int i;
17051 isc_rwlocktype_t locktype;
17052 isc_result_t result;
17053
17054 char master[ISC_SOCKADDR_FORMATSIZE];
17055 char source[ISC_SOCKADDR_FORMATSIZE];
17056
17057 isc_sockaddr_format(remote, master, sizeof(master));
17058 isc_sockaddr_format(local, source, sizeof(source));
17059
17060 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17061
17062 locktype = isc_rwlocktype_read;
17063 RWLOCK(&zmgr->urlock, locktype);
17064 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
17065 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
17066 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
17067 if (zmgr->unreachable[i].expire == 0)
17068 break;
17069 result = isc_rwlock_tryupgrade(&zmgr->urlock);
17070 if (result == ISC_R_SUCCESS) {
17071 locktype = isc_rwlocktype_write;
17072 zmgr->unreachable[i].expire = 0;
17073 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
17074 DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
17075 "master %s (source %s) deleted "
17076 "from unreachable cache",
17077 master, source);
17078 }
17079 break;
17080 }
17081 }
17082 RWUNLOCK(&zmgr->urlock, locktype);
17083 }
17084
17085 void
17086 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
17087 isc_sockaddr_t *local, isc_time_t *now)
17088 {
17089 uint32_t seconds = isc_time_seconds(now);
17090 uint32_t last = seconds;
17091 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
17092
17093 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17094
17095 RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
17096 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
17097 /* Existing entry? */
17098 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
17099 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
17100 break;
17101 /* Empty slot? */
17102 if (zmgr->unreachable[i].expire < seconds)
17103 slot = i;
17104 /* Least recently used slot? */
17105 if (zmgr->unreachable[i].last < last) {
17106 last = zmgr->unreachable[i].last;
17107 oldest = i;
17108 }
17109 }
17110 if (i < UNREACH_CHACHE_SIZE) {
17111 /*
17112 * Found a existing entry. Update the expire timer and
17113 * last usage timestamps.
17114 */
17115 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
17116 zmgr->unreachable[i].last = seconds;
17117 if (zmgr->unreachable[i].expire < seconds)
17118 zmgr->unreachable[i].count = 1;
17119 else
17120 zmgr->unreachable[i].count++;
17121 } else if (slot != UNREACH_CHACHE_SIZE) {
17122 /*
17123 * Found a empty slot. Add a new entry to the cache.
17124 */
17125 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
17126 zmgr->unreachable[slot].last = seconds;
17127 zmgr->unreachable[slot].remote = *remote;
17128 zmgr->unreachable[slot].local = *local;
17129 zmgr->unreachable[slot].count = 1;
17130 } else {
17131 /*
17132 * Replace the least recently used entry in the cache.
17133 */
17134 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
17135 zmgr->unreachable[oldest].last = seconds;
17136 zmgr->unreachable[oldest].remote = *remote;
17137 zmgr->unreachable[oldest].local = *local;
17138 zmgr->unreachable[oldest].count = 1;
17139 }
17140 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
17141 }
17142
17143 void
17144 dns_zone_forcereload(dns_zone_t *zone) {
17145 REQUIRE(DNS_ZONE_VALID(zone));
17146
17147 if (zone->type == dns_zone_master ||
17148 (zone->type == dns_zone_redirect && zone->masters == NULL))
17149 return;
17150
17151 LOCK_ZONE(zone);
17152 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
17153 UNLOCK_ZONE(zone);
17154 dns_zone_refresh(zone);
17155 }
17156
17157 bool
17158 dns_zone_isforced(dns_zone_t *zone) {
17159 REQUIRE(DNS_ZONE_VALID(zone));
17160
17161 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
17162 }
17163
17164 isc_result_t
17165 dns_zone_setstatistics(dns_zone_t *zone, bool on) {
17166 /*
17167 * This function is obsoleted.
17168 */
17169 UNUSED(zone);
17170 UNUSED(on);
17171 return (ISC_R_NOTIMPLEMENTED);
17172 }
17173
17174 uint64_t *
17175 dns_zone_getstatscounters(dns_zone_t *zone) {
17176 /*
17177 * This function is obsoleted.
17178 */
17179 UNUSED(zone);
17180 return (NULL);
17181 }
17182
17183 void
17184 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
17185 REQUIRE(DNS_ZONE_VALID(zone));
17186 REQUIRE(zone->stats == NULL);
17187
17188 LOCK_ZONE(zone);
17189 zone->stats = NULL;
17190 isc_stats_attach(stats, &zone->stats);
17191 UNLOCK_ZONE(zone);
17192 }
17193
17194 void
17195 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
17196
17197 REQUIRE(DNS_ZONE_VALID(zone));
17198
17199 LOCK_ZONE(zone);
17200 if (zone->requeststats_on && stats == NULL)
17201 zone->requeststats_on = false;
17202 else if (!zone->requeststats_on && stats != NULL) {
17203 if (zone->requeststats == NULL) {
17204 isc_stats_attach(stats, &zone->requeststats);
17205 zone->requeststats_on = true;
17206 }
17207 }
17208 UNLOCK_ZONE(zone);
17209 }
17210
17211 void
17212 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
17213
17214 REQUIRE(DNS_ZONE_VALID(zone));
17215
17216 LOCK_ZONE(zone);
17217 if (zone->requeststats_on && stats != NULL) {
17218 if (zone->rcvquerystats == NULL) {
17219 dns_stats_attach(stats, &zone->rcvquerystats);
17220 zone->requeststats_on = true;
17221 }
17222 }
17223 UNLOCK_ZONE(zone);
17224 }
17225
17226 isc_stats_t *
17227 dns_zone_getrequeststats(dns_zone_t *zone) {
17228 /*
17229 * We don't lock zone for efficiency reason. This is not catastrophic
17230 * because requeststats must always be valid when requeststats_on is
17231 * true.
17232 * Some counters may be incremented while requeststats_on is becoming
17233 * false, or some cannot be incremented just after the statistics are
17234 * installed, but it shouldn't matter much in practice.
17235 */
17236 if (zone->requeststats_on)
17237 return (zone->requeststats);
17238 else
17239 return (NULL);
17240 }
17241
17242 /*
17243 * Return the received query stats bucket
17244 * see note from dns_zone_getrequeststats()
17245 */
17246 dns_stats_t *
17247 dns_zone_getrcvquerystats(dns_zone_t *zone) {
17248 if (zone->requeststats_on)
17249 return (zone->rcvquerystats);
17250 else
17251 return (NULL);
17252 }
17253
17254 void
17255 dns_zone_dialup(dns_zone_t *zone) {
17256
17257 REQUIRE(DNS_ZONE_VALID(zone));
17258
17259 zone_debuglog(zone, "dns_zone_dialup", 3,
17260 "notify = %d, refresh = %d",
17261 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
17262 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
17263
17264 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
17265 dns_zone_notify(zone);
17266 if (zone->type != dns_zone_master && zone->masters != NULL &&
17267 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
17268 dns_zone_refresh(zone);
17269 }
17270
17271 void
17272 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
17273 REQUIRE(DNS_ZONE_VALID(zone));
17274
17275 LOCK_ZONE(zone);
17276 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
17277 DNS_ZONEFLG_DIALREFRESH |
17278 DNS_ZONEFLG_NOREFRESH);
17279 switch (dialup) {
17280 case dns_dialuptype_no:
17281 break;
17282 case dns_dialuptype_yes:
17283 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
17284 DNS_ZONEFLG_DIALREFRESH |
17285 DNS_ZONEFLG_NOREFRESH));
17286 break;
17287 case dns_dialuptype_notify:
17288 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
17289 break;
17290 case dns_dialuptype_notifypassive:
17291 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
17292 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
17293 break;
17294 case dns_dialuptype_refresh:
17295 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
17296 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
17297 break;
17298 case dns_dialuptype_passive:
17299 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
17300 break;
17301 default:
17302 INSIST(0);
17303 ISC_UNREACHABLE();
17304 }
17305 UNLOCK_ZONE(zone);
17306 }
17307
17308 isc_result_t
17309 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
17310 isc_result_t result = ISC_R_SUCCESS;
17311
17312 REQUIRE(DNS_ZONE_VALID(zone));
17313
17314 LOCK_ZONE(zone);
17315 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
17316 UNLOCK_ZONE(zone);
17317
17318 return (result);
17319 }
17320
17321 const char *
17322 dns_zone_getkeydirectory(dns_zone_t *zone) {
17323 REQUIRE(DNS_ZONE_VALID(zone));
17324
17325 return (zone->keydirectory);
17326 }
17327
17328 unsigned int
17329 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
17330 dns_zone_t *zone;
17331 unsigned int count = 0;
17332
17333 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17334
17335 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
17336 switch (state) {
17337 case DNS_ZONESTATE_XFERRUNNING:
17338 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
17339 zone != NULL;
17340 zone = ISC_LIST_NEXT(zone, statelink))
17341 count++;
17342 break;
17343 case DNS_ZONESTATE_XFERDEFERRED:
17344 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
17345 zone != NULL;
17346 zone = ISC_LIST_NEXT(zone, statelink))
17347 count++;
17348 break;
17349 case DNS_ZONESTATE_SOAQUERY:
17350 for (zone = ISC_LIST_HEAD(zmgr->zones);
17351 zone != NULL;
17352 zone = ISC_LIST_NEXT(zone, link))
17353 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
17354 count++;
17355 break;
17356 case DNS_ZONESTATE_ANY:
17357 for (zone = ISC_LIST_HEAD(zmgr->zones);
17358 zone != NULL;
17359 zone = ISC_LIST_NEXT(zone, link)) {
17360 dns_view_t *view = zone->view;
17361 if (view != NULL && strcmp(view->name, "_bind") == 0)
17362 continue;
17363 count++;
17364 }
17365 break;
17366 case DNS_ZONESTATE_AUTOMATIC:
17367 for (zone = ISC_LIST_HEAD(zmgr->zones);
17368 zone != NULL;
17369 zone = ISC_LIST_NEXT(zone, link)) {
17370 dns_view_t *view = zone->view;
17371 if (view != NULL && strcmp(view->name, "_bind") == 0)
17372 continue;
17373 if (zone->automatic)
17374 count++;
17375 }
17376 break;
17377 default:
17378 INSIST(0);
17379 ISC_UNREACHABLE();
17380 }
17381
17382 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
17383
17384 return (count);
17385 }
17386
17387 isc_result_t
17388 dns_zone_checknames(dns_zone_t *zone, const dns_name_t *name,
17389 dns_rdata_t *rdata)
17390 {
17391 bool ok = true;
17392 bool fail = false;
17393 char namebuf[DNS_NAME_FORMATSIZE];
17394 char namebuf2[DNS_NAME_FORMATSIZE];
17395 char typebuf[DNS_RDATATYPE_FORMATSIZE];
17396 int level = ISC_LOG_WARNING;
17397 dns_name_t bad;
17398
17399 REQUIRE(DNS_ZONE_VALID(zone));
17400
17401 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) &&
17402 rdata->type != dns_rdatatype_nsec3)
17403 return (ISC_R_SUCCESS);
17404
17405 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) ||
17406 rdata->type == dns_rdatatype_nsec3) {
17407 level = ISC_LOG_ERROR;
17408 fail = true;
17409 }
17410
17411 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, true);
17412 if (!ok) {
17413 dns_name_format(name, namebuf, sizeof(namebuf));
17414 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
17415 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
17416 dns_result_totext(DNS_R_BADOWNERNAME));
17417 if (fail)
17418 return (DNS_R_BADOWNERNAME);
17419 }
17420
17421 dns_name_init(&bad, NULL);
17422 ok = dns_rdata_checknames(rdata, name, &bad);
17423 if (!ok) {
17424 dns_name_format(name, namebuf, sizeof(namebuf));
17425 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
17426 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
17427 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
17428 namebuf2, dns_result_totext(DNS_R_BADNAME));
17429 if (fail)
17430 return (DNS_R_BADNAME);
17431 }
17432
17433 return (ISC_R_SUCCESS);
17434 }
17435
17436 void
17437 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
17438 REQUIRE(DNS_ZONE_VALID(zone));
17439 zone->checkmx = checkmx;
17440 }
17441
17442 void
17443 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
17444 REQUIRE(DNS_ZONE_VALID(zone));
17445 zone->checksrv = checksrv;
17446 }
17447
17448 void
17449 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
17450 REQUIRE(DNS_ZONE_VALID(zone));
17451 zone->checkns = checkns;
17452 }
17453
17454 void
17455 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
17456 REQUIRE(DNS_ZONE_VALID(zone));
17457
17458 LOCK_ZONE(zone);
17459 zone->isself = isself;
17460 zone->isselfarg = arg;
17461 UNLOCK_ZONE(zone);
17462 }
17463
17464 void
17465 dns_zone_setnotifydelay(dns_zone_t *zone, uint32_t delay) {
17466 REQUIRE(DNS_ZONE_VALID(zone));
17467
17468 LOCK_ZONE(zone);
17469 zone->notifydelay = delay;
17470 UNLOCK_ZONE(zone);
17471 }
17472
17473 uint32_t
17474 dns_zone_getnotifydelay(dns_zone_t *zone) {
17475 REQUIRE(DNS_ZONE_VALID(zone));
17476
17477 return (zone->notifydelay);
17478 }
17479
17480 isc_result_t
17481 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
17482 uint16_t keyid, bool deleteit)
17483 {
17484 isc_result_t result;
17485 REQUIRE(DNS_ZONE_VALID(zone));
17486
17487 dns_zone_log(zone, ISC_LOG_NOTICE,
17488 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
17489 algorithm, keyid);
17490 LOCK_ZONE(zone);
17491 result = zone_signwithkey(zone, algorithm, keyid, deleteit);
17492 UNLOCK_ZONE(zone);
17493
17494 return (result);
17495 }
17496
17497 /*
17498 * Called when a dynamic update for an NSEC3PARAM record is received.
17499 *
17500 * If set, transform the NSEC3 salt into human-readable form so that it can be
17501 * logged. Then call zone_addnsec3chain(), passing NSEC3PARAM RDATA to it.
17502 */
17503 isc_result_t
17504 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
17505 isc_result_t result;
17506 char salt[255*2+1];
17507
17508 REQUIRE(DNS_ZONE_VALID(zone));
17509
17510 result = dns_nsec3param_salttotext(nsec3param, salt, sizeof(salt));
17511 RUNTIME_CHECK(result == ISC_R_SUCCESS);
17512 dns_zone_log(zone, ISC_LOG_NOTICE,
17513 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
17514 nsec3param->hash, nsec3param->iterations,
17515 salt);
17516 LOCK_ZONE(zone);
17517 result = zone_addnsec3chain(zone, nsec3param);
17518 UNLOCK_ZONE(zone);
17519
17520 return (result);
17521 }
17522
17523 void
17524 dns_zone_setnodes(dns_zone_t *zone, uint32_t nodes) {
17525 REQUIRE(DNS_ZONE_VALID(zone));
17526
17527 if (nodes == 0)
17528 nodes = 1;
17529 zone->nodes = nodes;
17530 }
17531
17532 void
17533 dns_zone_setsignatures(dns_zone_t *zone, uint32_t signatures) {
17534 REQUIRE(DNS_ZONE_VALID(zone));
17535
17536 /*
17537 * We treat signatures as a signed value so explicitly
17538 * limit its range here.
17539 */
17540 if (signatures > INT32_MAX)
17541 signatures = INT32_MAX;
17542 else if (signatures == 0)
17543 signatures = 1;
17544 zone->signatures = signatures;
17545 }
17546
17547 uint32_t
17548 dns_zone_getsignatures(dns_zone_t *zone) {
17549 REQUIRE(DNS_ZONE_VALID(zone));
17550 return (zone->signatures);
17551 }
17552
17553 void
17554 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
17555 REQUIRE(DNS_ZONE_VALID(zone));
17556 zone->privatetype = type;
17557 }
17558
17559 dns_rdatatype_t
17560 dns_zone_getprivatetype(dns_zone_t *zone) {
17561 REQUIRE(DNS_ZONE_VALID(zone));
17562 return (zone->privatetype);
17563 }
17564
17565 static isc_result_t
17566 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid,
17567 bool deleteit)
17568 {
17569 dns_signing_t *signing;
17570 dns_signing_t *current;
17571 isc_result_t result = ISC_R_SUCCESS;
17572 isc_time_t now;
17573 dns_db_t *db = NULL;
17574
17575 signing = isc_mem_get(zone->mctx, sizeof *signing);
17576 if (signing == NULL)
17577 return (ISC_R_NOMEMORY);
17578
17579 signing->magic = 0;
17580 signing->db = NULL;
17581 signing->dbiterator = NULL;
17582 signing->algorithm = algorithm;
17583 signing->keyid = keyid;
17584 signing->deleteit = deleteit;
17585 signing->done = false;
17586
17587 TIME_NOW(&now);
17588
17589 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
17590 if (zone->db != NULL)
17591 dns_db_attach(zone->db, &db);
17592 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
17593
17594 if (db == NULL) {
17595 result = ISC_R_NOTFOUND;
17596 goto cleanup;
17597 }
17598
17599 dns_db_attach(db, &signing->db);
17600
17601 for (current = ISC_LIST_HEAD(zone->signing);
17602 current != NULL;
17603 current = ISC_LIST_NEXT(current, link)) {
17604 if (current->db == signing->db &&
17605 current->algorithm == signing->algorithm &&
17606 current->keyid == signing->keyid) {
17607 if (current->deleteit != signing->deleteit)
17608 current->done = true;
17609 else
17610 goto cleanup;
17611 }
17612 }
17613
17614 result = dns_db_createiterator(signing->db, 0,
17615 &signing->dbiterator);
17616
17617 if (result == ISC_R_SUCCESS)
17618 result = dns_dbiterator_first(signing->dbiterator);
17619 if (result == ISC_R_SUCCESS) {
17620 dns_dbiterator_pause(signing->dbiterator);
17621 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
17622 signing = NULL;
17623 if (isc_time_isepoch(&zone->signingtime)) {
17624 zone->signingtime = now;
17625 if (zone->task != NULL)
17626 zone_settimer(zone, &now);
17627 }
17628 }
17629
17630 cleanup:
17631 if (signing != NULL) {
17632 if (signing->db != NULL)
17633 dns_db_detach(&signing->db);
17634 if (signing->dbiterator != NULL)
17635 dns_dbiterator_destroy(&signing->dbiterator);
17636 isc_mem_put(zone->mctx, signing, sizeof *signing);
17637 }
17638 if (db != NULL)
17639 dns_db_detach(&db);
17640 return (result);
17641 }
17642
17643 static void
17644 logmsg(const char *format, ...) {
17645 va_list args;
17646 va_start(args, format);
17647 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
17648 ISC_LOG_DEBUG(1), format, args);
17649 va_end(args);
17650 }
17651
17652 static void
17653 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
17654 dns_dnsseckey_t *key;
17655 while (!ISC_LIST_EMPTY(*list)) {
17656 key = ISC_LIST_HEAD(*list);
17657 ISC_LIST_UNLINK(*list, key, link);
17658 dns_dnsseckey_destroy(mctx, &key);
17659 }
17660 }
17661
17662 /* Called once; *timep should be set to the current time. */
17663 static isc_result_t
17664 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
17665 isc_result_t result;
17666 isc_stdtime_t now, then = 0, event;
17667 int i;
17668
17669 now = *timep;
17670
17671 for (i = 0; i <= DST_MAX_TIMES; i++) {
17672 result = dst_key_gettime(key, i, &event);
17673 if (result == ISC_R_SUCCESS && event > now &&
17674 (then == 0 || event < then))
17675 then = event;
17676 }
17677
17678 if (then != 0) {
17679 *timep = then;
17680 return (ISC_R_SUCCESS);
17681 }
17682
17683 return (ISC_R_NOTFOUND);
17684 }
17685
17686 static isc_result_t
17687 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
17688 const dns_rdata_t *rdata, bool *flag)
17689 {
17690 dns_rdataset_t rdataset;
17691 dns_dbnode_t *node = NULL;
17692 isc_result_t result;
17693
17694 dns_rdataset_init(&rdataset);
17695 if (rdata->type == dns_rdatatype_nsec3)
17696 CHECK(dns_db_findnsec3node(db, name, false, &node));
17697 else
17698 CHECK(dns_db_findnode(db, name, false, &node));
17699 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
17700 (isc_stdtime_t) 0, &rdataset, NULL);
17701 if (result == ISC_R_NOTFOUND) {
17702 *flag = false;
17703 result = ISC_R_SUCCESS;
17704 goto failure;
17705 }
17706
17707 for (result = dns_rdataset_first(&rdataset);
17708 result == ISC_R_SUCCESS;
17709 result = dns_rdataset_next(&rdataset)) {
17710 dns_rdata_t myrdata = DNS_RDATA_INIT;
17711 dns_rdataset_current(&rdataset, &myrdata);
17712 if (!dns_rdata_compare(&myrdata, rdata))
17713 break;
17714 }
17715 dns_rdataset_disassociate(&rdataset);
17716 if (result == ISC_R_SUCCESS) {
17717 *flag = true;
17718 } else if (result == ISC_R_NOMORE) {
17719 *flag = false;
17720 result = ISC_R_SUCCESS;
17721 }
17722
17723 failure:
17724 if (node != NULL)
17725 dns_db_detachnode(db, &node);
17726 return (result);
17727 }
17728
17729 /*
17730 * Add records to signal the state of signing or of key removal.
17731 */
17732 static isc_result_t
17733 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
17734 dns_dbversion_t *ver, dns_diff_t *diff,
17735 bool sign_all)
17736 {
17737 dns_difftuple_t *tuple, *newtuple = NULL;
17738 dns_rdata_dnskey_t dnskey;
17739 dns_rdata_t rdata = DNS_RDATA_INIT;
17740 bool flag;
17741 isc_region_t r;
17742 isc_result_t result = ISC_R_SUCCESS;
17743 uint16_t keyid;
17744 unsigned char buf[5];
17745 dns_name_t *name = dns_db_origin(db);
17746
17747 for (tuple = ISC_LIST_HEAD(diff->tuples);
17748 tuple != NULL;
17749 tuple = ISC_LIST_NEXT(tuple, link)) {
17750 if (tuple->rdata.type != dns_rdatatype_dnskey)
17751 continue;
17752
17753 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
17754 RUNTIME_CHECK(result == ISC_R_SUCCESS);
17755 if ((dnskey.flags &
17756 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
17757 != DNS_KEYOWNER_ZONE)
17758 continue;
17759
17760 dns_rdata_toregion(&tuple->rdata, &r);
17761
17762 keyid = dst_region_computeid(&r, dnskey.algorithm);
17763
17764 buf[0] = dnskey.algorithm;
17765 buf[1] = (keyid & 0xff00) >> 8;
17766 buf[2] = (keyid & 0xff);
17767 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
17768 buf[4] = 0;
17769 rdata.data = buf;
17770 rdata.length = sizeof(buf);
17771 rdata.type = privatetype;
17772 rdata.rdclass = tuple->rdata.rdclass;
17773
17774 if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
17775 CHECK(rr_exists(db, ver, name, &rdata, &flag));
17776 if (flag)
17777 continue;
17778 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
17779 name, 0, &rdata, &newtuple));
17780 CHECK(do_one_tuple(&newtuple, db, ver, diff));
17781 INSIST(newtuple == NULL);
17782 }
17783
17784 /*
17785 * Remove any record which says this operation has already
17786 * completed.
17787 */
17788 buf[4] = 1;
17789 CHECK(rr_exists(db, ver, name, &rdata, &flag));
17790 if (flag) {
17791 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
17792 name, 0, &rdata, &newtuple));
17793 CHECK(do_one_tuple(&newtuple, db, ver, diff));
17794 INSIST(newtuple == NULL);
17795 }
17796 }
17797 failure:
17798 return (result);
17799 }
17800
17801 static isc_result_t
17802 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
17803 isc_stdtime_t now, dns_diff_t *diff, dns__zonediff_t *zonediff)
17804 {
17805 isc_result_t result;
17806 isc_stdtime_t inception, soaexpire, keyexpire;
17807 bool check_ksk, keyset_kskonly;
17808 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
17809 unsigned int nkeys = 0, i;
17810 dns_difftuple_t *tuple;
17811
17812 result = dns__zone_findkeys(zone, db, ver, now, zone->mctx,
17813 DNS_MAXZONEKEYS, zone_keys, &nkeys);
17814 if (result != ISC_R_SUCCESS) {
17815 dns_zone_log(zone, ISC_LOG_ERROR,
17816 "sign_apex:dns__zone_findkeys -> %s",
17817 dns_result_totext(result));
17818 return (result);
17819 }
17820
17821 inception = now - 3600; /* Allow for clock skew. */
17822 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
17823
17824 keyexpire = dns_zone_getkeyvalidityinterval(zone);
17825 if (keyexpire == 0) {
17826 keyexpire = soaexpire - 1;
17827 } else {
17828 keyexpire += now;
17829 }
17830
17831 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
17832 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
17833
17834 /*
17835 * See if dns__zone_updatesigs() will update DNSKEY signature and if
17836 * not cause them to sign so that newly activated keys are used.
17837 */
17838 for (tuple = ISC_LIST_HEAD(diff->tuples);
17839 tuple != NULL;
17840 tuple = ISC_LIST_NEXT(tuple, link)) {
17841 if (tuple->rdata.type == dns_rdatatype_dnskey &&
17842 dns_name_equal(&tuple->name, &zone->origin))
17843 break;
17844 }
17845
17846 if (tuple == NULL) {
17847 result = del_sigs(zone, db, ver, &zone->origin,
17848 dns_rdatatype_dnskey, zonediff,
17849 zone_keys, nkeys, now, false);
17850 if (result != ISC_R_SUCCESS) {
17851 dns_zone_log(zone, ISC_LOG_ERROR,
17852 "sign_apex:del_sigs -> %s",
17853 dns_result_totext(result));
17854 goto failure;
17855 }
17856 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
17857 zonediff->diff, zone_keys, nkeys, zone->mctx,
17858 inception, keyexpire, check_ksk,
17859 keyset_kskonly);
17860 if (result != ISC_R_SUCCESS) {
17861 dns_zone_log(zone, ISC_LOG_ERROR,
17862 "sign_apex:add_sigs -> %s",
17863 dns_result_totext(result));
17864 goto failure;
17865 }
17866 }
17867
17868 result = dns__zone_updatesigs(diff, db, ver, zone_keys, nkeys, zone,
17869 inception, soaexpire, keyexpire, now,
17870 check_ksk, keyset_kskonly, zonediff);
17871
17872 if (result != ISC_R_SUCCESS) {
17873 dns_zone_log(zone, ISC_LOG_ERROR,
17874 "sign_apex:dns__zone_updatesigs -> %s",
17875 dns_result_totext(result));
17876 goto failure;
17877 }
17878
17879 failure:
17880 for (i = 0; i < nkeys; i++)
17881 dst_key_free(&zone_keys[i]);
17882 return (result);
17883 }
17884
17885 /*
17886 * Prevent the zone entering a inconsistent state where
17887 * NSEC only DNSKEYs are present with NSEC3 chains.
17888 * See update.c:check_dnssec()
17889 */
17890 static bool
17891 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
17892 dns_diff_t *diff)
17893 {
17894 isc_result_t result;
17895 dns_difftuple_t *tuple;
17896 bool nseconly = false, nsec3 = false;
17897 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
17898
17899 /* Scan the tuples for an NSEC-only DNSKEY */
17900 for (tuple = ISC_LIST_HEAD(diff->tuples);
17901 tuple != NULL;
17902 tuple = ISC_LIST_NEXT(tuple, link)) {
17903 uint8_t alg;
17904 if (tuple->rdata.type != dns_rdatatype_dnskey ||
17905 tuple->op != DNS_DIFFOP_ADD)
17906 continue;
17907
17908 alg = tuple->rdata.data[3];
17909 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1) {
17910 nseconly = true;
17911 break;
17912 }
17913 }
17914
17915 /* Check existing DB for NSEC-only DNSKEY */
17916 if (!nseconly) {
17917 result = dns_nsec_nseconly(db, ver, &nseconly);
17918 if (result == ISC_R_NOTFOUND)
17919 result = ISC_R_SUCCESS;
17920 CHECK(result);
17921 }
17922
17923 /* Check existing DB for NSEC3 */
17924 if (!nsec3)
17925 CHECK(dns_nsec3_activex(db, ver, false,
17926 privatetype, &nsec3));
17927
17928 /* Refuse to allow NSEC3 with NSEC-only keys */
17929 if (nseconly && nsec3) {
17930 dns_zone_log(zone, ISC_LOG_ERROR,
17931 "NSEC only DNSKEYs and NSEC3 chains not allowed");
17932 goto failure;
17933 }
17934
17935 return (true);
17936
17937 failure:
17938 return (false);
17939 }
17940
17941 static isc_result_t
17942 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
17943 dns_diff_t *diff)
17944 {
17945 isc_result_t result;
17946 dns_dbnode_t *node = NULL;
17947 dns_rdataset_t rdataset;
17948
17949 dns_rdataset_init(&rdataset);
17950 CHECK(dns_db_getoriginnode(db, &node));
17951
17952 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
17953 dns_rdatatype_none, 0, &rdataset, NULL);
17954 if (dns_rdataset_isassociated(&rdataset))
17955 dns_rdataset_disassociate(&rdataset);
17956 if (result != ISC_R_NOTFOUND)
17957 goto failure;
17958
17959 result = dns_nsec3param_deletechains(db, ver, zone, true, diff);
17960
17961 failure:
17962 if (node != NULL)
17963 dns_db_detachnode(db, &node);
17964 return (result);
17965 }
17966
17967 /*
17968 * Given an RRSIG rdataset and an algorithm, determine whether there
17969 * are any signatures using that algorithm.
17970 */
17971 static bool
17972 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
17973 dns_rdata_t rdata = DNS_RDATA_INIT;
17974 dns_rdata_rrsig_t rrsig;
17975 isc_result_t result;
17976
17977 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
17978 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
17979 return (false);
17980 }
17981
17982 for (result = dns_rdataset_first(rdataset);
17983 result == ISC_R_SUCCESS;
17984 result = dns_rdataset_next(rdataset))
17985 {
17986 dns_rdataset_current(rdataset, &rdata);
17987 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
17988 RUNTIME_CHECK(result == ISC_R_SUCCESS);
17989 dns_rdata_reset(&rdata);
17990 if (rrsig.algorithm == alg)
17991 return (true);
17992 }
17993
17994 return (false);
17995 }
17996
17997 static isc_result_t
17998 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
17999 dns_diff_t *diff)
18000 {
18001 dns_name_t *origin;
18002 bool build_nsec3;
18003 isc_result_t result;
18004
18005 origin = dns_db_origin(db);
18006 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
18007 &build_nsec3));
18008 if (build_nsec3)
18009 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
18010 false, zone->privatetype, diff));
18011 CHECK(updatesecure(db, ver, origin, zone->minimum, true, diff));
18012
18013 failure:
18014 return (result);
18015 }
18016
18017 static void
18018 zone_rekey(dns_zone_t *zone) {
18019 isc_result_t result;
18020 dns_db_t *db = NULL;
18021 dns_dbnode_t *node = NULL;
18022 dns_dbversion_t *ver = NULL;
18023 dns_rdataset_t cdsset, soaset, soasigs, keyset, keysigs, cdnskeyset;
18024 dns_dnsseckeylist_t dnskeys, keys, rmkeys;
18025 dns_dnsseckey_t *key;
18026 dns_diff_t diff, _sig_diff;
18027 dns__zonediff_t zonediff;
18028 bool commit = false, newactive = false;
18029 bool newalg = false;
18030 bool fullsign;
18031 dns_ttl_t ttl = 3600;
18032 const char *dir;
18033 isc_mem_t *mctx;
18034 isc_stdtime_t now;
18035 isc_time_t timenow;
18036 isc_interval_t ival;
18037 char timebuf[80];
18038
18039 REQUIRE(DNS_ZONE_VALID(zone));
18040
18041 ISC_LIST_INIT(dnskeys);
18042 ISC_LIST_INIT(keys);
18043 ISC_LIST_INIT(rmkeys);
18044 dns_rdataset_init(&soaset);
18045 dns_rdataset_init(&soasigs);
18046 dns_rdataset_init(&keyset);
18047 dns_rdataset_init(&keysigs);
18048 dns_rdataset_init(&cdsset);
18049 dns_rdataset_init(&cdnskeyset);
18050 dir = dns_zone_getkeydirectory(zone);
18051 mctx = zone->mctx;
18052 dns_diff_init(mctx, &diff);
18053 dns_diff_init(mctx, &_sig_diff);
18054 zonediff_init(&zonediff, &_sig_diff);
18055
18056 CHECK(dns_zone_getdb(zone, &db));
18057 CHECK(dns_db_newversion(db, &ver));
18058 CHECK(dns_db_getoriginnode(db, &node));
18059
18060 TIME_NOW(&timenow);
18061 now = isc_time_seconds(&timenow);
18062
18063 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
18064
18065 /* Get the SOA record's TTL */
18066 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
18067 dns_rdatatype_none, 0, &soaset, &soasigs));
18068 ttl = soaset.ttl;
18069 dns_rdataset_disassociate(&soaset);
18070
18071 /* Get the DNSKEY rdataset */
18072 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
18073 dns_rdatatype_none, 0, &keyset, &keysigs);
18074 if (result == ISC_R_SUCCESS) {
18075 ttl = keyset.ttl;
18076 CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir,
18077 mctx, &keyset,
18078 &keysigs, &soasigs,
18079 false, false,
18080 &dnskeys));
18081 } else if (result != ISC_R_NOTFOUND)
18082 goto failure;
18083
18084
18085 /* Get the CDS rdataset */
18086 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cds,
18087 dns_rdatatype_none, 0, &cdsset, NULL);
18088 if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdsset))
18089 dns_rdataset_disassociate(&cdsset);
18090
18091 /* Get the CDNSKEY rdataset */
18092 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cdnskey,
18093 dns_rdatatype_none, 0, &cdnskeyset, NULL);
18094 if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdnskeyset))
18095 dns_rdataset_disassociate(&cdnskeyset);
18096
18097 /*
18098 * True when called from "rndc sign". Indicates the zone should be
18099 * fully signed now.
18100 */
18101 fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN);
18102
18103 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, now, mctx,
18104 &keys);
18105 if (result == ISC_R_SUCCESS) {
18106 bool check_ksk;
18107 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
18108
18109 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
18110 &zone->origin, ttl, &diff,
18111 !check_ksk,
18112 mctx, logmsg);
18113 /*
18114 * Keys couldn't be updated for some reason;
18115 * try again later.
18116 */
18117 if (result != ISC_R_SUCCESS) {
18118 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
18119 "couldn't update zone keys: %s",
18120 isc_result_totext(result));
18121 goto failure;
18122 }
18123
18124 /*
18125 * Update CDS / CDNSKEY records.
18126 */
18127 result = dns_dnssec_syncupdate(&dnskeys, &rmkeys, &cdsset,
18128 &cdnskeyset, now, ttl,
18129 &diff, mctx);
18130 if (result != ISC_R_SUCCESS) {
18131 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
18132 "couldn't update CDS/CDNSKEY: %s",
18133 isc_result_totext(result));
18134 goto failure;
18135 }
18136
18137 /*
18138 * See if any pre-existing keys have newly become active;
18139 * also, see if any new key is for a new algorithm, as in that
18140 * event, we need to sign the zone fully. (If there's a new
18141 * key, but it's for an already-existing algorithm, then
18142 * the zone signing can be handled incrementally.)
18143 */
18144 for (key = ISC_LIST_HEAD(dnskeys);
18145 key != NULL;
18146 key = ISC_LIST_NEXT(key, link)) {
18147 if (!key->first_sign)
18148 continue;
18149
18150 newactive = true;
18151
18152 if (!dns_rdataset_isassociated(&keysigs)) {
18153 newalg = true;
18154 break;
18155 }
18156
18157 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
18158 /*
18159 * This isn't a new algorithm; clear
18160 * first_sign so we won't sign the
18161 * whole zone with this key later
18162 */
18163 key->first_sign = false;
18164 } else {
18165 newalg = true;
18166 break;
18167 }
18168 }
18169
18170 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
18171 dnskey_sane(zone, db, ver, &diff)) {
18172 CHECK(dns_diff_apply(&diff, db, ver));
18173 CHECK(clean_nsec3param(zone, db, ver, &diff));
18174 CHECK(add_signing_records(db, zone->privatetype,
18175 ver, &diff,
18176 (newalg || fullsign)));
18177 CHECK(update_soa_serial(db, ver, &diff, mctx,
18178 zone->updatemethod));
18179 CHECK(add_chains(zone, db, ver, &diff));
18180 CHECK(sign_apex(zone, db, ver, now, &diff, &zonediff));
18181 CHECK(zone_journal(zone, zonediff.diff, NULL,
18182 "zone_rekey"));
18183 commit = true;
18184 }
18185 }
18186
18187 dns_db_closeversion(db, &ver, true);
18188
18189 if (commit) {
18190 dns_difftuple_t *tuple;
18191
18192 LOCK_ZONE(zone);
18193 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
18194
18195 zone_needdump(zone, DNS_DUMP_DELAY);
18196
18197 zone_settimer(zone, &timenow);
18198
18199 /* Remove any signatures from removed keys. */
18200 if (!ISC_LIST_EMPTY(rmkeys)) {
18201 for (key = ISC_LIST_HEAD(rmkeys);
18202 key != NULL;
18203 key = ISC_LIST_NEXT(key, link)) {
18204 result = zone_signwithkey(zone,
18205 dst_key_alg(key->key),
18206 dst_key_id(key->key),
18207 true);
18208 if (result != ISC_R_SUCCESS) {
18209 dns_zone_log(zone, ISC_LOG_ERROR,
18210 "zone_signwithkey failed: %s",
18211 dns_result_totext(result));
18212 }
18213 }
18214 }
18215
18216 if (fullsign) {
18217 /*
18218 * "rndc sign" was called, so we now sign the zone
18219 * with all active keys, whether they're new or not.
18220 */
18221 for (key = ISC_LIST_HEAD(dnskeys);
18222 key != NULL;
18223 key = ISC_LIST_NEXT(key, link)) {
18224 if (!key->force_sign && !key->hint_sign)
18225 continue;
18226
18227 result = zone_signwithkey(zone,
18228 dst_key_alg(key->key),
18229 dst_key_id(key->key),
18230 false);
18231 if (result != ISC_R_SUCCESS) {
18232 dns_zone_log(zone, ISC_LOG_ERROR,
18233 "zone_signwithkey failed: %s",
18234 dns_result_totext(result));
18235 }
18236 }
18237 } else if (newalg) {
18238 /*
18239 * We haven't been told to sign fully, but a new
18240 * algorithm was added to the DNSKEY. We sign
18241 * the full zone, but only with newly active
18242 * keys.
18243 */
18244 for (key = ISC_LIST_HEAD(dnskeys);
18245 key != NULL;
18246 key = ISC_LIST_NEXT(key, link)) {
18247 if (!key->first_sign)
18248 continue;
18249
18250 result = zone_signwithkey(zone,
18251 dst_key_alg(key->key),
18252 dst_key_id(key->key),
18253 false);
18254 if (result != ISC_R_SUCCESS) {
18255 dns_zone_log(zone, ISC_LOG_ERROR,
18256 "zone_signwithkey failed: %s",
18257 dns_result_totext(result));
18258 }
18259 }
18260 }
18261
18262 /*
18263 * Clear fullsign flag, if it was set, so we don't do
18264 * another full signing next time
18265 */
18266 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
18267
18268 /*
18269 * Cause the zone to add/delete NSEC3 chains for the
18270 * deferred NSEC3PARAM changes.
18271 */
18272 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
18273 tuple != NULL;
18274 tuple = ISC_LIST_NEXT(tuple, link)) {
18275 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
18276 dns_rdata_t rdata = DNS_RDATA_INIT;
18277 dns_rdata_nsec3param_t nsec3param;
18278
18279 if (tuple->rdata.type != zone->privatetype ||
18280 tuple->op != DNS_DIFFOP_ADD)
18281 continue;
18282
18283 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
18284 buf, sizeof(buf)))
18285 continue;
18286 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
18287 RUNTIME_CHECK(result == ISC_R_SUCCESS);
18288 if (nsec3param.flags == 0)
18289 continue;
18290
18291 result = zone_addnsec3chain(zone, &nsec3param);
18292 if (result != ISC_R_SUCCESS) {
18293 dns_zone_log(zone, ISC_LOG_ERROR,
18294 "zone_addnsec3chain failed: %s",
18295 dns_result_totext(result));
18296 }
18297 }
18298
18299 /*
18300 * Activate any NSEC3 chain updates that may have
18301 * been scheduled before this rekey.
18302 */
18303 if (fullsign || newalg)
18304 resume_addnsec3chain(zone);
18305
18306 /*
18307 * Schedule the next resigning event
18308 */
18309 set_resigntime(zone);
18310 UNLOCK_ZONE(zone);
18311 }
18312
18313 isc_time_settoepoch(&zone->refreshkeytime);
18314
18315 /*
18316 * If we're doing key maintenance, set the key refresh timer to
18317 * the next scheduled key event or to 'dnssec-loadkeys-interval'
18318 * seconds in the future, whichever is sooner.
18319 */
18320 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
18321 isc_time_t timethen;
18322 isc_stdtime_t then;
18323
18324 LOCK_ZONE(zone);
18325 DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
18326 &timethen);
18327 zone->refreshkeytime = timethen;
18328 UNLOCK_ZONE(zone);
18329
18330 for (key = ISC_LIST_HEAD(dnskeys);
18331 key != NULL;
18332 key = ISC_LIST_NEXT(key, link)) {
18333 then = now;
18334 result = next_keyevent(key->key, &then);
18335 if (result != ISC_R_SUCCESS)
18336 continue;
18337
18338 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
18339 LOCK_ZONE(zone);
18340 if (isc_time_compare(&timethen,
18341 &zone->refreshkeytime) < 0) {
18342 zone->refreshkeytime = timethen;
18343 }
18344 UNLOCK_ZONE(zone);
18345 }
18346
18347 zone_settimer(zone, &timenow);
18348
18349 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
18350 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
18351 }
18352
18353 done:
18354 dns_diff_clear(&diff);
18355 dns_diff_clear(&_sig_diff);
18356
18357 clear_keylist(&dnskeys, mctx);
18358 clear_keylist(&keys, mctx);
18359 clear_keylist(&rmkeys, mctx);
18360
18361 if (ver != NULL)
18362 dns_db_closeversion(db, &ver, false);
18363 if (dns_rdataset_isassociated(&cdsset))
18364 dns_rdataset_disassociate(&cdsset);
18365 if (dns_rdataset_isassociated(&keyset))
18366 dns_rdataset_disassociate(&keyset);
18367 if (dns_rdataset_isassociated(&keysigs))
18368 dns_rdataset_disassociate(&keysigs);
18369 if (dns_rdataset_isassociated(&soasigs))
18370 dns_rdataset_disassociate(&soasigs);
18371 if (dns_rdataset_isassociated(&cdnskeyset))
18372 dns_rdataset_disassociate(&cdnskeyset);
18373 if (node != NULL)
18374 dns_db_detachnode(db, &node);
18375 if (db != NULL)
18376 dns_db_detach(&db);
18377
18378 INSIST(ver == NULL);
18379 return;
18380
18381 failure:
18382 /*
18383 * Something went wrong; try again in ten minutes or
18384 * after a key refresh interval, whichever is shorter.
18385 */
18386 isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 0);
18387 isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
18388 goto done;
18389 }
18390
18391 void
18392 dns_zone_rekey(dns_zone_t *zone, bool fullsign) {
18393 isc_time_t now;
18394
18395 if (zone->type == dns_zone_master && zone->task != NULL) {
18396 LOCK_ZONE(zone);
18397
18398 if (fullsign)
18399 zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
18400
18401 TIME_NOW(&now);
18402 zone->refreshkeytime = now;
18403 zone_settimer(zone, &now);
18404
18405 UNLOCK_ZONE(zone);
18406 }
18407 }
18408
18409 isc_result_t
18410 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
18411 unsigned int *errors)
18412 {
18413 isc_result_t result;
18414 dns_dbnode_t *node = NULL;
18415
18416 REQUIRE(DNS_ZONE_VALID(zone));
18417 REQUIRE(errors != NULL);
18418
18419 result = dns_db_getoriginnode(db, &node);
18420 if (result != ISC_R_SUCCESS)
18421 return (result);
18422 result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
18423 false);
18424 dns_db_detachnode(db, &node);
18425 return (result);
18426 }
18427
18428 isc_result_t
18429 dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) {
18430 isc_result_t result;
18431 dns_dbnode_t *node = NULL;
18432 dns_rdataset_t dnskey, cds, cdnskey;
18433 unsigned char buffer[DNS_DS_BUFFERSIZE];
18434 unsigned char algorithms[256];
18435 unsigned int i;
18436
18437 REQUIRE(DNS_ZONE_VALID(zone));
18438
18439 result = dns_db_getoriginnode(db, &node);
18440 if (result != ISC_R_SUCCESS)
18441 return (result);
18442
18443 dns_rdataset_init(&cds);
18444 dns_rdataset_init(&dnskey);
18445 dns_rdataset_init(&cdnskey);
18446
18447 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds,
18448 dns_rdatatype_none, 0, &cds, NULL);
18449 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
18450 goto failure;
18451
18452 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey,
18453 dns_rdatatype_none, 0, &cdnskey, NULL);
18454 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
18455 goto failure;
18456
18457 if (!dns_rdataset_isassociated(&cds) &&
18458 !dns_rdataset_isassociated(&cdnskey)) {
18459 result = ISC_R_SUCCESS;
18460 goto failure;
18461 }
18462
18463 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
18464 dns_rdatatype_none, 0, &dnskey, NULL);
18465 if (result == ISC_R_NOTFOUND) {
18466 if (dns_rdataset_isassociated(&cds))
18467 result = DNS_R_BADCDS;
18468 else
18469 result = DNS_R_BADCDNSKEY;
18470 goto failure;
18471 }
18472 if (result != ISC_R_SUCCESS)
18473 goto failure;
18474
18475 /*
18476 * For each DNSSEC algorithm in the CDS RRset there must be
18477 * a matching DNSKEY record.
18478 */
18479 if (dns_rdataset_isassociated(&cds)) {
18480 memset(algorithms, 0, sizeof(algorithms));
18481 for (result = dns_rdataset_first(&cds);
18482 result == ISC_R_SUCCESS;
18483 result = dns_rdataset_next(&cds)) {
18484 dns_rdata_t crdata = DNS_RDATA_INIT;
18485 dns_rdata_cds_t structcds;
18486
18487 dns_rdataset_current(&cds, &crdata);
18488 CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL));
18489 if (algorithms[structcds.algorithm] == 0)
18490 algorithms[structcds.algorithm] = 1;
18491 for (result = dns_rdataset_first(&dnskey);
18492 result == ISC_R_SUCCESS;
18493 result = dns_rdataset_next(&dnskey)) {
18494 dns_rdata_t rdata = DNS_RDATA_INIT;
18495 dns_rdata_t dsrdata = DNS_RDATA_INIT;
18496
18497 dns_rdataset_current(&dnskey, &rdata);
18498 CHECK(dns_ds_buildrdata(&zone->origin, &rdata,
18499 structcds.digest_type,
18500 buffer, &dsrdata));
18501 if (crdata.length == dsrdata.length &&
18502 memcmp(crdata.data, dsrdata.data,
18503 dsrdata.length) == 0) {
18504 algorithms[structcds.algorithm] = 2;
18505 }
18506 }
18507 if (result != ISC_R_NOMORE)
18508 goto failure;
18509 }
18510 for (i = 0; i < sizeof(algorithms); i++) {
18511 if (algorithms[i] == 1) {
18512 result = DNS_R_BADCDNSKEY;
18513 goto failure;
18514 }
18515 }
18516 }
18517
18518 /*
18519 * For each DNSSEC algorithm in the CDNSKEY RRset there must be
18520 * a matching DNSKEY record.
18521 */
18522 if (dns_rdataset_isassociated(&cdnskey)) {
18523 memset(algorithms, 0, sizeof(algorithms));
18524 for (result = dns_rdataset_first(&cdnskey);
18525 result == ISC_R_SUCCESS;
18526 result = dns_rdataset_next(&cdnskey)) {
18527 dns_rdata_t crdata = DNS_RDATA_INIT;
18528 dns_rdata_cdnskey_t structcdnskey;
18529
18530 dns_rdataset_current(&cdnskey, &crdata);
18531 CHECK(dns_rdata_tostruct(&crdata, &structcdnskey,
18532 NULL));
18533 if (algorithms[structcdnskey.algorithm] == 0)
18534 algorithms[structcdnskey.algorithm] = 1;
18535 for (result = dns_rdataset_first(&dnskey);
18536 result == ISC_R_SUCCESS;
18537 result = dns_rdataset_next(&dnskey)) {
18538 dns_rdata_t rdata = DNS_RDATA_INIT;
18539
18540 dns_rdataset_current(&dnskey, &rdata);
18541 if (crdata.length == rdata.length &&
18542 memcmp(crdata.data, rdata.data,
18543 rdata.length) == 0) {
18544 algorithms[structcdnskey.algorithm] = 2;
18545 }
18546 }
18547 if (result != ISC_R_NOMORE)
18548 goto failure;
18549 }
18550 for (i = 0; i < sizeof(algorithms); i++) {
18551 if (algorithms[i] == 1) {
18552 result = DNS_R_BADCDS;
18553 goto failure;
18554 }
18555 }
18556 }
18557 result = ISC_R_SUCCESS;
18558
18559 failure:
18560 if (dns_rdataset_isassociated(&cds))
18561 dns_rdataset_disassociate(&cds);
18562 if (dns_rdataset_isassociated(&dnskey))
18563 dns_rdataset_disassociate(&dnskey);
18564 if (dns_rdataset_isassociated(&cdnskey))
18565 dns_rdataset_disassociate(&cdnskey);
18566 dns_db_detachnode(db, &node);
18567 return (result);
18568 }
18569
18570 void
18571 dns_zone_setautomatic(dns_zone_t *zone, bool automatic) {
18572 REQUIRE(DNS_ZONE_VALID(zone));
18573
18574 LOCK_ZONE(zone);
18575 zone->automatic = automatic;
18576 UNLOCK_ZONE(zone);
18577 }
18578
18579 bool
18580 dns_zone_getautomatic(dns_zone_t *zone) {
18581 REQUIRE(DNS_ZONE_VALID(zone));
18582 return (zone->automatic);
18583 }
18584
18585 void
18586 dns_zone_setadded(dns_zone_t *zone, bool added) {
18587 REQUIRE(DNS_ZONE_VALID(zone));
18588
18589 LOCK_ZONE(zone);
18590 zone->added = added;
18591 UNLOCK_ZONE(zone);
18592 }
18593
18594 bool
18595 dns_zone_getadded(dns_zone_t *zone) {
18596 REQUIRE(DNS_ZONE_VALID(zone));
18597 return (zone->added);
18598 }
18599
18600 isc_result_t
18601 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
18602 {
18603 isc_time_t loadtime;
18604 isc_result_t result;
18605 dns_zone_t *secure = NULL;
18606
18607 TIME_NOW(&loadtime);
18608
18609 /*
18610 * Lock hierarchy: zmgr, zone, raw.
18611 */
18612 again:
18613 LOCK_ZONE(zone);
18614 INSIST(zone != zone->raw);
18615 if (inline_secure(zone))
18616 LOCK_ZONE(zone->raw);
18617 else if (inline_raw(zone)) {
18618 secure = zone->secure;
18619 TRYLOCK_ZONE(result, secure);
18620 if (result != ISC_R_SUCCESS) {
18621 UNLOCK_ZONE(zone);
18622 secure = NULL;
18623 isc_thread_yield();
18624 goto again;
18625 }
18626 }
18627 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
18628 if (inline_secure(zone))
18629 UNLOCK_ZONE(zone->raw);
18630 else if (secure != NULL)
18631 UNLOCK_ZONE(secure);
18632 UNLOCK_ZONE(zone);
18633 return result;
18634 }
18635
18636 isc_result_t
18637 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, uint32_t interval) {
18638 REQUIRE(DNS_ZONE_VALID(zone));
18639 if (interval == 0)
18640 return (ISC_R_RANGE);
18641 /* Maximum value: 24 hours (3600 minutes) */
18642 if (interval > (24 * 60))
18643 interval = (24 * 60);
18644 /* Multiply by 60 for seconds */
18645 zone->refreshkeyinterval = interval * 60;
18646 return (ISC_R_SUCCESS);
18647 }
18648
18649 void
18650 dns_zone_setrequestixfr(dns_zone_t *zone, bool flag) {
18651 REQUIRE(DNS_ZONE_VALID(zone));
18652 zone->requestixfr = flag;
18653 }
18654
18655 bool
18656 dns_zone_getrequestixfr(dns_zone_t *zone) {
18657 REQUIRE(DNS_ZONE_VALID(zone));
18658 return (zone->requestixfr);
18659 }
18660
18661 void
18662 dns_zone_setrequestexpire(dns_zone_t *zone, bool flag) {
18663 REQUIRE(DNS_ZONE_VALID(zone));
18664 zone->requestexpire = flag;
18665 }
18666
18667 bool
18668 dns_zone_getrequestexpire(dns_zone_t *zone) {
18669 REQUIRE(DNS_ZONE_VALID(zone));
18670 return (zone->requestexpire);
18671 }
18672
18673 void
18674 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
18675 REQUIRE(DNS_ZONE_VALID(zone));
18676 zone->updatemethod = method;
18677 }
18678
18679 dns_updatemethod_t
18680 dns_zone_getserialupdatemethod(dns_zone_t *zone) {
18681 REQUIRE(DNS_ZONE_VALID(zone));
18682 return(zone->updatemethod);
18683 }
18684
18685 /*
18686 * Lock hierarchy: zmgr, zone, raw.
18687 */
18688 isc_result_t
18689 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
18690 isc_result_t result;
18691 dns_zonemgr_t *zmgr;
18692
18693 REQUIRE(DNS_ZONE_VALID(zone));
18694 REQUIRE(zone->zmgr != NULL);
18695 REQUIRE(zone->task != NULL);
18696 REQUIRE(zone->loadtask != NULL);
18697 REQUIRE(zone->raw == NULL);
18698
18699 REQUIRE(DNS_ZONE_VALID(raw));
18700 REQUIRE(raw->zmgr == NULL);
18701 REQUIRE(raw->task == NULL);
18702 REQUIRE(raw->loadtask == NULL);
18703 REQUIRE(raw->secure == NULL);
18704
18705 REQUIRE(zone != raw);
18706
18707 /*
18708 * Lock hierarchy: zmgr, zone, raw.
18709 */
18710 zmgr = zone->zmgr;
18711 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
18712 LOCK_ZONE(zone);
18713 LOCK_ZONE(raw);
18714
18715 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
18716 NULL, NULL, zone->task, zone_timer, raw,
18717 &raw->timer);
18718 if (result != ISC_R_SUCCESS)
18719 goto unlock;
18720
18721 /*
18722 * The timer "holds" a iref.
18723 */
18724 raw->irefs++;
18725 INSIST(raw->irefs != 0);
18726
18727
18728 /* dns_zone_attach(raw, &zone->raw); */
18729 isc_refcount_increment(&raw->erefs);
18730 zone->raw = raw;
18731
18732 /* dns_zone_iattach(zone, &raw->secure); */
18733 zone_iattach(zone, &raw->secure);
18734
18735 isc_task_attach(zone->task, &raw->task);
18736 isc_task_attach(zone->loadtask, &raw->loadtask);
18737
18738 ISC_LIST_APPEND(zmgr->zones, raw, link);
18739 raw->zmgr = zmgr;
18740 zmgr->refs++;
18741
18742 unlock:
18743 UNLOCK_ZONE(raw);
18744 UNLOCK_ZONE(zone);
18745 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
18746 return (result);
18747 }
18748
18749 void
18750 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
18751 REQUIRE(DNS_ZONE_VALID(zone));
18752 REQUIRE(raw != NULL && *raw == NULL);
18753
18754 LOCK(&zone->lock);
18755 INSIST(zone != zone->raw);
18756 if (zone->raw != NULL)
18757 dns_zone_attach(zone->raw, raw);
18758 UNLOCK(&zone->lock);
18759 }
18760
18761 struct keydone {
18762 isc_event_t event;
18763 bool all;
18764 unsigned char data[5];
18765 };
18766
18767 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL)
18768
18769 static void
18770 keydone(isc_task_t *task, isc_event_t *event) {
18771 const char *me = "keydone";
18772 bool commit = false;
18773 isc_result_t result;
18774 dns_rdata_t rdata = DNS_RDATA_INIT;
18775 dns_dbversion_t *oldver = NULL, *newver = NULL;
18776 dns_zone_t *zone;
18777 dns_db_t *db = NULL;
18778 dns_dbnode_t *node = NULL;
18779 dns_rdataset_t rdataset;
18780 dns_diff_t diff;
18781 struct keydone *kd = (struct keydone *)event;
18782 dns_update_log_t log = { update_log_cb, NULL };
18783 bool clear_pending = false;
18784
18785 UNUSED(task);
18786
18787 zone = event->ev_arg;
18788 INSIST(DNS_ZONE_VALID(zone));
18789
18790 ENTER;
18791
18792 dns_rdataset_init(&rdataset);
18793 dns_diff_init(zone->mctx, &diff);
18794
18795 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
18796 if (zone->db != NULL)
18797 dns_db_attach(zone->db, &db);
18798 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
18799 if (db == NULL)
18800 goto failure;
18801
18802 dns_db_currentversion(db, &oldver);
18803 result = dns_db_newversion(db, &newver);
18804 if (result != ISC_R_SUCCESS) {
18805 dns_zone_log(zone, ISC_LOG_ERROR,
18806 "keydone:dns_db_newversion -> %s",
18807 dns_result_totext(result));
18808 goto failure;
18809 }
18810
18811 result = dns_db_getoriginnode(db, &node);
18812 if (result != ISC_R_SUCCESS)
18813 goto failure;
18814
18815 result = dns_db_findrdataset(db, node, newver, zone->privatetype,
18816 dns_rdatatype_none, 0, &rdataset, NULL);
18817 if (result == ISC_R_NOTFOUND) {
18818 INSIST(!dns_rdataset_isassociated(&rdataset));
18819 goto failure;
18820 }
18821 if (result != ISC_R_SUCCESS) {
18822 INSIST(!dns_rdataset_isassociated(&rdataset));
18823 goto failure;
18824 }
18825
18826 for (result = dns_rdataset_first(&rdataset);
18827 result == ISC_R_SUCCESS;
18828 result = dns_rdataset_next(&rdataset)) {
18829 bool found = false;
18830
18831 dns_rdataset_current(&rdataset, &rdata);
18832
18833 if (kd->all) {
18834 if (rdata.length == 5 && rdata.data[0] != 0 &&
18835 rdata.data[3] == 0 && rdata.data[4] == 1)
18836 found = true;
18837 else if (rdata.data[0] == 0 &&
18838 (rdata.data[2] & PENDINGFLAGS) != 0) {
18839 found = true;
18840 clear_pending = true;
18841 }
18842 } else if (rdata.length == 5 &&
18843 memcmp(rdata.data, kd->data, 5) == 0)
18844 found = true;
18845
18846 if (found)
18847 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL,
18848 &zone->origin, rdataset.ttl,
18849 &rdata));
18850 dns_rdata_reset(&rdata);
18851 }
18852
18853 if (!ISC_LIST_EMPTY(diff.tuples)) {
18854 /* Write changes to journal file. */
18855 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
18856 zone->updatemethod));
18857
18858 result = dns_update_signatures(&log, zone, db,
18859 oldver, newver, &diff,
18860 zone->sigvalidityinterval);
18861 if (!clear_pending)
18862 CHECK(result);
18863
18864 CHECK(zone_journal(zone, &diff, NULL, "keydone"));
18865 commit = true;
18866
18867 LOCK_ZONE(zone);
18868 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
18869 zone_needdump(zone, 30);
18870 UNLOCK_ZONE(zone);
18871 }
18872
18873 failure:
18874 if (dns_rdataset_isassociated(&rdataset))
18875 dns_rdataset_disassociate(&rdataset);
18876 if (db != NULL) {
18877 if (node != NULL)
18878 dns_db_detachnode(db, &node);
18879 if (oldver != NULL)
18880 dns_db_closeversion(db, &oldver, false);
18881 if (newver != NULL)
18882 dns_db_closeversion(db, &newver, commit);
18883 dns_db_detach(&db);
18884 }
18885 dns_diff_clear(&diff);
18886 isc_event_free(&event);
18887 dns_zone_idetach(&zone);
18888
18889 INSIST(oldver == NULL);
18890 INSIST(newver == NULL);
18891 }
18892
18893 isc_result_t
18894 dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
18895 isc_result_t result = ISC_R_SUCCESS;
18896 isc_event_t *e;
18897 isc_buffer_t b;
18898 dns_zone_t *dummy = NULL;
18899 struct keydone *kd;
18900
18901 REQUIRE(DNS_ZONE_VALID(zone));
18902
18903 LOCK_ZONE(zone);
18904
18905 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone,
18906 zone, sizeof(struct keydone));
18907 if (e == NULL) {
18908 result = ISC_R_NOMEMORY;
18909 goto failure;
18910 }
18911
18912 kd = (struct keydone *) e;
18913 if (strcasecmp(keystr, "all") == 0)
18914 kd->all = true;
18915 else {
18916 isc_textregion_t r;
18917 const char *algstr;
18918 dns_keytag_t keyid;
18919 dns_secalg_t alg;
18920 size_t n;
18921
18922 kd->all = false;
18923
18924 n = sscanf(keystr, "%hu/", &keyid);
18925 if (n == 0U)
18926 CHECK(ISC_R_FAILURE);
18927
18928 algstr = strchr(keystr, '/');
18929 if (algstr != NULL)
18930 algstr++;
18931 else
18932 CHECK(ISC_R_FAILURE);
18933
18934 n = sscanf(algstr, "%hhu", &alg);
18935 if (n == 0U) {
18936 DE_CONST(algstr, r.base);
18937 r.length = strlen(algstr);
18938 CHECK(dns_secalg_fromtext(&alg, &r));
18939 }
18940
18941 /* construct a private-type rdata */
18942 isc_buffer_init(&b, kd->data, sizeof(kd->data));
18943 isc_buffer_putuint8(&b, alg);
18944 isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8);
18945 isc_buffer_putuint8(&b, (keyid & 0xff));
18946 isc_buffer_putuint8(&b, 0);
18947 isc_buffer_putuint8(&b, 1);
18948 }
18949
18950 zone_iattach(zone, &dummy);
18951 isc_task_send(zone->task, &e);
18952
18953 failure:
18954 if (e != NULL)
18955 isc_event_free(&e);
18956 UNLOCK_ZONE(zone);
18957 return (result);
18958 }
18959
18960 /*
18961 * Called from the zone task's queue after the relevant event is posted by
18962 * dns_zone_setnsec3param().
18963 *
18964 * Check whether NSEC3 chain addition or removal specified by the private-type
18965 * record passed with the event was already queued (or even fully performed).
18966 * If not, modify the relevant private-type records at the zone apex and call
18967 * resume_addnsec3chain().
18968 */
18969 static void
18970 setnsec3param(isc_task_t *task, isc_event_t *event) {
18971 const char *me = "setnsec3param";
18972 bool commit = false;
18973 isc_result_t result;
18974 dns_dbversion_t *oldver = NULL, *newver = NULL;
18975 dns_zone_t *zone;
18976 dns_db_t *db = NULL;
18977 dns_dbnode_t *node = NULL;
18978 dns_rdataset_t prdataset, nrdataset;
18979 dns_diff_t diff;
18980 struct np3event *npe = (struct np3event *)event;
18981 nsec3param_t *np;
18982 dns_update_log_t log = { update_log_cb, NULL };
18983 dns_rdata_t rdata;
18984 bool nseconly;
18985 bool exists = false;
18986
18987 UNUSED(task);
18988
18989 zone = event->ev_arg;
18990 INSIST(DNS_ZONE_VALID(zone));
18991
18992 ENTER;
18993
18994 np = &npe->params;
18995
18996 dns_rdataset_init(&prdataset);
18997 dns_rdataset_init(&nrdataset);
18998 dns_diff_init(zone->mctx, &diff);
18999
19000 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
19001 if (zone->db != NULL)
19002 dns_db_attach(zone->db, &db);
19003 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
19004 if (db == NULL)
19005 goto failure;
19006
19007 dns_db_currentversion(db, &oldver);
19008 result = dns_db_newversion(db, &newver);
19009 if (result != ISC_R_SUCCESS) {
19010 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
19011 dns_zone_log(zone, ISC_LOG_ERROR,
19012 "setnsec3param:dns_db_newversion -> %s",
19013 dns_result_totext(result));
19014 goto failure;
19015 }
19016
19017 CHECK(dns_db_getoriginnode(db, &node));
19018
19019 /*
19020 * Does a private-type record already exist for this chain?
19021 */
19022 result = dns_db_findrdataset(db, node, newver, zone->privatetype,
19023 dns_rdatatype_none, 0, &prdataset, NULL);
19024 if (result == ISC_R_SUCCESS) {
19025 for (result = dns_rdataset_first(&prdataset);
19026 result == ISC_R_SUCCESS;
19027 result = dns_rdataset_next(&prdataset)) {
19028 dns_rdata_init(&rdata);
19029 dns_rdataset_current(&prdataset, &rdata);
19030
19031 if (np->length == rdata.length &&
19032 memcmp(rdata.data, np->data, np->length) == 0) {
19033 exists = true;
19034 break;
19035 }
19036 }
19037 } else if (result != ISC_R_NOTFOUND) {
19038 INSIST(!dns_rdataset_isassociated(&prdataset));
19039 goto failure;
19040 }
19041
19042 /*
19043 * Does the chain already exist?
19044 */
19045 result = dns_db_findrdataset(db, node, newver,
19046 dns_rdatatype_nsec3param,
19047 dns_rdatatype_none, 0, &nrdataset, NULL);
19048 if (result == ISC_R_SUCCESS) {
19049 for (result = dns_rdataset_first(&nrdataset);
19050 result == ISC_R_SUCCESS;
19051 result = dns_rdataset_next(&nrdataset)) {
19052 dns_rdata_init(&rdata);
19053 dns_rdataset_current(&nrdataset, &rdata);
19054
19055 if (np->length == (rdata.length + 1) &&
19056 memcmp(rdata.data, np->data + 1,
19057 np->length - 1) == 0)
19058 {
19059 exists = true;
19060 break;
19061 }
19062 }
19063 } else if (result != ISC_R_NOTFOUND) {
19064 INSIST(!dns_rdataset_isassociated(&nrdataset));
19065 goto failure;
19066 }
19067
19068
19069 /*
19070 * We need to remove any existing NSEC3 chains if the supplied NSEC3
19071 * parameters are supposed to replace the current ones or if we are
19072 * switching to NSEC.
19073 */
19074 if (!exists && np->replace && (np->length != 0 || np->nsec))
19075 CHECK(dns_nsec3param_deletechains(db, newver, zone,
19076 !np->nsec, &diff));
19077
19078 if (!exists && np->length != 0) {
19079 /*
19080 * We're creating an NSEC3 chain. Add the private-type record
19081 * passed in the event handler's argument to the zone apex.
19082 *
19083 * If the zone is not currently capable of supporting an NSEC3
19084 * chain (due to the DNSKEY RRset at the zone apex not existing
19085 * or containing at least one key using an NSEC-only
19086 * algorithm), add the INITIAL flag, so these parameters can be
19087 * used later when NSEC3 becomes available.
19088 */
19089 dns_rdata_init(&rdata);
19090
19091 np->data[2] |= DNS_NSEC3FLAG_CREATE;
19092 result = dns_nsec_nseconly(db, newver, &nseconly);
19093 if (result == ISC_R_NOTFOUND || nseconly)
19094 np->data[2] |= DNS_NSEC3FLAG_INITIAL;
19095
19096 rdata.length = np->length;
19097 rdata.data = np->data;
19098 rdata.type = zone->privatetype;
19099 rdata.rdclass = zone->rdclass;
19100 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD,
19101 &zone->origin, 0, &rdata));
19102 }
19103
19104 /*
19105 * If we changed anything in the zone, write changes to journal file
19106 * and set commit to true so that resume_addnsec3chain() will be
19107 * called below in order to kick off adding/removing relevant NSEC3
19108 * records.
19109 */
19110 if (!ISC_LIST_EMPTY(diff.tuples)) {
19111 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
19112 zone->updatemethod));
19113 result = dns_update_signatures(&log, zone, db,
19114 oldver, newver, &diff,
19115 zone->sigvalidityinterval);
19116 if (result != ISC_R_NOTFOUND)
19117 CHECK(result);
19118 CHECK(zone_journal(zone, &diff, NULL, "setnsec3param"));
19119 commit = true;
19120
19121 LOCK_ZONE(zone);
19122 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
19123 zone_needdump(zone, 30);
19124 UNLOCK_ZONE(zone);
19125 }
19126
19127 failure:
19128 if (dns_rdataset_isassociated(&prdataset))
19129 dns_rdataset_disassociate(&prdataset);
19130 if (dns_rdataset_isassociated(&nrdataset))
19131 dns_rdataset_disassociate(&nrdataset);
19132 if (node != NULL)
19133 dns_db_detachnode(db, &node);
19134 if (oldver != NULL)
19135 dns_db_closeversion(db, &oldver, false);
19136 if (newver != NULL)
19137 dns_db_closeversion(db, &newver, commit);
19138 if (db != NULL)
19139 dns_db_detach(&db);
19140 if (commit) {
19141 LOCK_ZONE(zone);
19142 resume_addnsec3chain(zone);
19143 UNLOCK_ZONE(zone);
19144 }
19145 dns_diff_clear(&diff);
19146 isc_event_free(&event);
19147 dns_zone_idetach(&zone);
19148
19149 INSIST(oldver == NULL);
19150 INSIST(newver == NULL);
19151 }
19152
19153 /*
19154 * Called when an "rndc signing -nsec3param ..." command is received.
19155 *
19156 * Allocate and prepare an nsec3param_t structure which holds information about
19157 * the NSEC3 changes requested for the zone:
19158 *
19159 * - if NSEC3 is to be disabled ("-nsec3param none"), only set the "nsec"
19160 * field of the structure to true and the "replace" field to the value
19161 * of the "replace" argument, leaving other fields initialized to zeros, to
19162 * signal that the zone should be signed using NSEC instead of NSEC3,
19163 *
19164 * - otherwise, prepare NSEC3PARAM RDATA that will eventually be inserted at
19165 * the zone apex, convert it to a private-type record and store the latter
19166 * in the "data" field of the nsec3param_t structure.
19167 *
19168 * Once the nsec3param_t structure is prepared, post an event to the zone's
19169 * task which will cause setnsec3param() to be called with the prepared
19170 * structure passed as an argument.
19171 */
19172 isc_result_t
19173 dns_zone_setnsec3param(dns_zone_t *zone, uint8_t hash, uint8_t flags,
19174 uint16_t iter, uint8_t saltlen,
19175 unsigned char *salt, bool replace)
19176 {
19177 isc_result_t result = ISC_R_SUCCESS;
19178 dns_rdata_nsec3param_t param;
19179 dns_rdata_t nrdata = DNS_RDATA_INIT;
19180 dns_rdata_t prdata = DNS_RDATA_INIT;
19181 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
19182 struct np3event *npe;
19183 nsec3param_t *np;
19184 dns_zone_t *dummy = NULL;
19185 isc_buffer_t b;
19186 isc_event_t *e;
19187
19188 REQUIRE(DNS_ZONE_VALID(zone));
19189 REQUIRE(salt != NULL);
19190
19191 LOCK_ZONE(zone);
19192
19193 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM,
19194 setnsec3param, zone, sizeof(struct np3event));
19195 if (e == NULL) {
19196 result = ISC_R_NOMEMORY;
19197 goto failure;
19198 }
19199
19200 npe = (struct np3event *) e;
19201 np = &npe->params;
19202
19203 np->replace = replace;
19204 if (hash == 0) {
19205 np->length = 0;
19206 np->nsec = true;
19207 } else {
19208 param.common.rdclass = zone->rdclass;
19209 param.common.rdtype = dns_rdatatype_nsec3param;
19210 ISC_LINK_INIT(¶m.common, link);
19211 param.mctx = NULL;
19212 param.hash = hash;
19213 param.flags = flags;
19214 param.iterations = iter;
19215 param.salt_length = saltlen;
19216 param.salt = salt;
19217 isc_buffer_init(&b, nbuf, sizeof(nbuf));
19218 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
19219 dns_rdatatype_nsec3param,
19220 ¶m, &b));
19221 dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype,
19222 np->data, sizeof(np->data));
19223 np->length = prdata.length;
19224 np->nsec = false;
19225 }
19226
19227 /*
19228 * setnsec3param() will silently return early if the zone does not yet
19229 * have a database. Prevent that by queueing the event up if zone->db
19230 * is NULL. All events queued here are subsequently processed by
19231 * receive_secure_db() if it ever gets called or simply freed by
19232 * zone_free() otherwise.
19233 */
19234 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
19235 if (zone->db != NULL) {
19236 zone_iattach(zone, &dummy);
19237 isc_task_send(zone->task, &e);
19238 } else {
19239 ISC_LIST_APPEND(zone->setnsec3param_queue, e, ev_link);
19240 e = NULL;
19241 }
19242 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
19243
19244 failure:
19245 if (e != NULL)
19246 isc_event_free(&e);
19247 UNLOCK_ZONE(zone);
19248 return (result);
19249 }
19250
19251 isc_result_t
19252 dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) {
19253 REQUIRE(DNS_ZONE_VALID(zone));
19254 REQUIRE(loadtime != NULL);
19255
19256 LOCK_ZONE(zone);
19257 *loadtime = zone->loadtime;
19258 UNLOCK_ZONE(zone);
19259 return (ISC_R_SUCCESS);
19260 }
19261
19262 isc_result_t
19263 dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) {
19264 REQUIRE(DNS_ZONE_VALID(zone));
19265 REQUIRE(expiretime != NULL);
19266
19267 LOCK_ZONE(zone);
19268 *expiretime = zone->expiretime;
19269 UNLOCK_ZONE(zone);
19270 return (ISC_R_SUCCESS);
19271 }
19272
19273 isc_result_t
19274 dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) {
19275 REQUIRE(DNS_ZONE_VALID(zone));
19276 REQUIRE(refreshtime != NULL);
19277
19278 LOCK_ZONE(zone);
19279 *refreshtime = zone->refreshtime;
19280 UNLOCK_ZONE(zone);
19281 return (ISC_R_SUCCESS);
19282 }
19283
19284 isc_result_t
19285 dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) {
19286 REQUIRE(DNS_ZONE_VALID(zone));
19287 REQUIRE(refreshkeytime != NULL);
19288
19289 LOCK_ZONE(zone);
19290 *refreshkeytime = zone->refreshkeytime;
19291 UNLOCK_ZONE(zone);
19292 return (ISC_R_SUCCESS);
19293 }
19294
19295 unsigned int
19296 dns_zone_getincludes(dns_zone_t *zone, char ***includesp) {
19297 dns_include_t *include;
19298 char **array = NULL;
19299 unsigned int n = 0;
19300
19301 REQUIRE(DNS_ZONE_VALID(zone));
19302 REQUIRE(includesp != NULL && *includesp == NULL);
19303
19304 LOCK_ZONE(zone);
19305 if (zone->nincludes == 0)
19306 goto done;
19307
19308 array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes);
19309 if (array == NULL)
19310 goto done;
19311 for (include = ISC_LIST_HEAD(zone->includes);
19312 include != NULL;
19313 include = ISC_LIST_NEXT(include, link)) {
19314 INSIST(n < zone->nincludes);
19315 array[n++] = isc_mem_strdup(zone->mctx, include->name);
19316 }
19317 INSIST(n == zone->nincludes);
19318 *includesp = array;
19319
19320 done:
19321 UNLOCK_ZONE(zone);
19322 return (n);
19323 }
19324
19325 void
19326 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
19327 REQUIRE(DNS_ZONE_VALID(zone));
19328
19329 zone->statlevel = level;
19330 }
19331
19332 dns_zonestat_level_t
19333 dns_zone_getstatlevel(dns_zone_t *zone) {
19334 REQUIRE(DNS_ZONE_VALID(zone));
19335
19336 return (zone->statlevel);
19337 }
19338
19339 static void
19340 setserial(isc_task_t *task, isc_event_t *event) {
19341 uint32_t oldserial, desired;
19342 const char *me = "setserial";
19343 bool commit = false;
19344 isc_result_t result;
19345 dns_dbversion_t *oldver = NULL, *newver = NULL;
19346 dns_zone_t *zone;
19347 dns_db_t *db = NULL;
19348 dns_diff_t diff;
19349 struct ssevent *sse = (struct ssevent *)event;
19350 dns_update_log_t log = { update_log_cb, NULL };
19351 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
19352
19353 UNUSED(task);
19354
19355 zone = event->ev_arg;
19356 INSIST(DNS_ZONE_VALID(zone));
19357
19358 ENTER;
19359
19360 if (zone->update_disabled)
19361 goto failure;
19362
19363 desired = sse->serial;
19364
19365 dns_diff_init(zone->mctx, &diff);
19366
19367 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
19368 if (zone->db != NULL)
19369 dns_db_attach(zone->db, &db);
19370 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
19371 if (db == NULL)
19372 goto failure;
19373
19374 dns_db_currentversion(db, &oldver);
19375 result = dns_db_newversion(db, &newver);
19376 if (result != ISC_R_SUCCESS) {
19377 dns_zone_log(zone, ISC_LOG_ERROR,
19378 "setserial:dns_db_newversion -> %s",
19379 dns_result_totext(result));
19380 goto failure;
19381 }
19382
19383 CHECK(dns_db_createsoatuple(db, oldver, diff.mctx,
19384 DNS_DIFFOP_DEL, &oldtuple));
19385 CHECK(dns_difftuple_copy(oldtuple, &newtuple));
19386 newtuple->op = DNS_DIFFOP_ADD;
19387
19388 oldserial = dns_soa_getserial(&oldtuple->rdata);
19389 if (desired == 0U)
19390 desired = 1;
19391 if (!isc_serial_gt(desired, oldserial)) {
19392 if (desired != oldserial)
19393 dns_zone_log(zone, ISC_LOG_INFO,
19394 "setserial: desired serial (%u) "
19395 "out of range (%u-%u)", desired,
19396 oldserial + 1, (oldserial + 0x7fffffff));
19397 goto failure;
19398 }
19399
19400 dns_soa_setserial(desired, &newtuple->rdata);
19401 CHECK(do_one_tuple(&oldtuple, db, newver, &diff));
19402 CHECK(do_one_tuple(&newtuple, db, newver, &diff));
19403 result = dns_update_signatures(&log, zone, db,
19404 oldver, newver, &diff,
19405 zone->sigvalidityinterval);
19406 if (result != ISC_R_NOTFOUND)
19407 CHECK(result);
19408
19409 /* Write changes to journal file. */
19410 CHECK(zone_journal(zone, &diff, NULL, "setserial"));
19411 commit = true;
19412
19413 LOCK_ZONE(zone);
19414 zone_needdump(zone, 30);
19415 UNLOCK_ZONE(zone);
19416
19417 failure:
19418 if (oldtuple != NULL)
19419 dns_difftuple_free(&oldtuple);
19420 if (newtuple != NULL)
19421 dns_difftuple_free(&newtuple);
19422 if (oldver != NULL)
19423 dns_db_closeversion(db, &oldver, false);
19424 if (newver != NULL)
19425 dns_db_closeversion(db, &newver, commit);
19426 if (db != NULL)
19427 dns_db_detach(&db);
19428 dns_diff_clear(&diff);
19429 isc_event_free(&event);
19430 dns_zone_idetach(&zone);
19431
19432 INSIST(oldver == NULL);
19433 INSIST(newver == NULL);
19434 }
19435
19436 isc_result_t
19437 dns_zone_setserial(dns_zone_t *zone, uint32_t serial) {
19438 isc_result_t result = ISC_R_SUCCESS;
19439 dns_zone_t *dummy = NULL;
19440 isc_event_t *e = NULL;
19441 struct ssevent *sse;
19442
19443 REQUIRE(DNS_ZONE_VALID(zone));
19444
19445 LOCK_ZONE(zone);
19446
19447 if (!inline_secure(zone)) {
19448 if (!dns_zone_isdynamic(zone, true)) {
19449 result = DNS_R_NOTDYNAMIC;
19450 goto failure;
19451 }
19452 }
19453
19454 if (zone->update_disabled) {
19455 result = DNS_R_FROZEN;
19456 goto failure;
19457 }
19458
19459 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETSERIAL,
19460 setserial, zone, sizeof(struct ssevent));
19461 if (e == NULL) {
19462 result = ISC_R_NOMEMORY;
19463 goto failure;
19464 }
19465
19466 sse = (struct ssevent *)e;
19467 sse->serial = serial;
19468
19469 zone_iattach(zone, &dummy);
19470 isc_task_send(zone->task, &e);
19471
19472 failure:
19473 if (e != NULL)
19474 isc_event_free(&e);
19475 UNLOCK_ZONE(zone);
19476 return (result);
19477 }
19478
19479 isc_stats_t *
19480 dns_zone_getgluecachestats(dns_zone_t *zone) {
19481 REQUIRE(DNS_ZONE_VALID(zone));
19482
19483 return (zone->gluecachestats);
19484 }
19485
19486 bool
19487 dns_zone_isloaded(const dns_zone_t *zone) {
19488 REQUIRE(DNS_ZONE_VALID(zone));
19489
19490 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED));
19491 }
19492
19493 isc_result_t
19494 dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver) {
19495 dns_dbversion_t *version = NULL;
19496 dns_keytable_t *secroots = NULL;
19497 isc_result_t result;
19498 dns_name_t *origin;
19499
19500 const char me[] = "dns_zone_verifydb";
19501 ENTER;
19502
19503 REQUIRE(DNS_ZONE_VALID(zone));
19504 REQUIRE(db != NULL);
19505
19506 if (dns_zone_gettype(zone) != dns_zone_mirror) {
19507 return (ISC_R_SUCCESS);
19508 }
19509
19510 if (ver == NULL) {
19511 dns_db_currentversion(db, &version);
19512 } else {
19513 version = ver;
19514 }
19515
19516 if (zone->view != NULL) {
19517 result = dns_view_getsecroots(zone->view, &secroots);
19518 if (result != ISC_R_SUCCESS) {
19519 goto done;
19520 }
19521 }
19522
19523 origin = dns_db_origin(db);
19524 result = dns_zoneverify_dnssec(zone, db, version, origin, secroots,
19525 zone->mctx, false, false);
19526
19527 done:
19528 if (secroots != NULL) {
19529 dns_keytable_detach(&secroots);
19530 }
19531
19532 if (ver == NULL) {
19533 dns_db_closeversion(db, &version, false);
19534 }
19535
19536 if (result != ISC_R_SUCCESS) {
19537 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
19538 "zone verification failed: %s",
19539 isc_result_totext(result));
19540 result = DNS_R_VERIFYFAILURE;
19541 }
19542
19543 return (result);
19544 }
19545