zone.c revision 1.7 1 /* $NetBSD: zone.c,v 1.7 2019/10/17 16:47:00 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 (/*CONSTCOND*/0)
164 #define UNLOCK_ZONE(z) \
165 do { (z)->locked = false; UNLOCK(&(z)->lock); } while (/*CONSTCON*/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 (/*CONSTCOND*/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 (/*CONSTCOND*/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 dns_stats_t *dnssecsignstats;
334 dns_stats_t *dnssecrefreshstats;
335 uint32_t notifydelay;
336 dns_isselffunc_t isself;
337 void *isselfarg;
338
339 char * strnamerd;
340 char * strname;
341 char * strrdclass;
342 char * strviewname;
343
344 /*%
345 * Serial number for deferred journal compaction.
346 */
347 uint32_t compact_serial;
348 /*%
349 * Keys that are signing the zone for the first time.
350 */
351 dns_signinglist_t signing;
352 dns_nsec3chainlist_t nsec3chain;
353 /*%
354 * List of outstanding NSEC3PARAM change requests.
355 */
356 isc_eventlist_t setnsec3param_queue;
357 /*%
358 * Signing / re-signing quantum stopping parameters.
359 */
360 uint32_t signatures;
361 uint32_t nodes;
362 dns_rdatatype_t privatetype;
363
364 /*%
365 * Autosigning/key-maintenance options
366 */
367 uint32_t keyopts;
368
369 /*%
370 * True if added by "rndc addzone"
371 */
372 bool added;
373
374 /*%
375 * True if added by automatically by named.
376 */
377 bool automatic;
378
379 /*%
380 * response policy data to be relayed to the database
381 */
382 dns_rpz_zones_t *rpzs;
383 dns_rpz_num_t rpz_num;
384
385 /*%
386 * catalog zone data
387 */
388 dns_catz_zones_t *catzs;
389
390 /*%
391 * parent catalog zone
392 */
393 dns_catz_zone_t *parentcatz;
394
395 /*%
396 * Serial number update method.
397 */
398 dns_updatemethod_t updatemethod;
399
400 /*%
401 * whether ixfr is requested
402 */
403 bool requestixfr;
404
405 /*%
406 * whether EDNS EXPIRE is requested
407 */
408 bool requestexpire;
409
410 /*%
411 * Outstanding forwarded UPDATE requests.
412 */
413 dns_forwardlist_t forwards;
414
415 dns_zone_t *raw;
416 dns_zone_t *secure;
417
418 bool sourceserialset;
419 uint32_t sourceserial;
420
421 /*%
422 * maximum zone ttl
423 */
424 dns_ttl_t maxttl;
425
426 /*
427 * Inline zone signing state.
428 */
429 dns_diff_t rss_diff;
430 isc_eventlist_t rss_events;
431 isc_eventlist_t rss_post;
432 dns_dbversion_t *rss_newver;
433 dns_dbversion_t *rss_oldver;
434 dns_db_t *rss_db;
435 dns_zone_t *rss_raw;
436 isc_event_t *rss_event;
437 dns_update_state_t *rss_state;
438
439 isc_stats_t *gluecachestats;
440 };
441
442 #define zonediff_init(z, d) \
443 do { \
444 dns__zonediff_t *_z = (z); \
445 (_z)->diff = (d); \
446 (_z)->offline = false; \
447 } while (/*CONSTCOND*/0)
448
449 #define DNS_ZONE_FLAG(z,f) ((z)->flags & (f))
450 #define DNS_ZONE_SETFLAG(z,f) do { \
451 INSIST(LOCKED_ZONE(z)); \
452 (z)->flags |= (f); \
453 } while (/*CONSTCOND*/0)
454 #define DNS_ZONE_CLRFLAG(z,f) do { \
455 INSIST(LOCKED_ZONE(z)); \
456 (z)->flags &= ~(f); \
457 } while (/*CONSTCOND*/0)
458 /* XXX MPA these may need to go back into zone.h */
459 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
460 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
461 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
462 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
463 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
464 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
465 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
466 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
467 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
468 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
469 * uptodate */
470 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
471 * messages */
472 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
473 * reload */
474 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
475 * zone with no masters
476 * occurred */
477 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
478 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
479 * from SOA (if not set, we
480 * are still using
481 * default timer values) */
482 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
483 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
484 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
485 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
486 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
487 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
488 #define DNS_ZONEFLG_FLUSH 0x00200000U
489 #define DNS_ZONEFLG_NOEDNS 0x00400000U
490 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
491 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
492 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
493 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
494 #define DNS_ZONEFLG_THAW 0x08000000U
495 #define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */
496 #define DNS_ZONEFLG_NODELAY 0x20000000U
497 #define DNS_ZONEFLG_SENDSECURE 0x40000000U
498 #define DNS_ZONEFLG_NEEDSTARTUPNOTIFY 0x80000000U /*%< need to send out notify
499 * due to the zone just
500 * being loaded for the
501 * first time. */
502
503 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
504 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
505
506 /* Flags for zone_load() */
507 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
508 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
509 load. */
510
511 #define UNREACH_CHACHE_SIZE 10U
512 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
513
514 #define CHECK(op) \
515 do { result = (op); \
516 if (result != ISC_R_SUCCESS) goto failure; \
517 } while (/*CONSTCOND*/0)
518
519 struct dns_unreachable {
520 isc_sockaddr_t remote;
521 isc_sockaddr_t local;
522 uint32_t expire;
523 uint32_t last;
524 uint32_t count;
525 };
526
527 struct dns_zonemgr {
528 unsigned int magic;
529 isc_mem_t * mctx;
530 int refs; /* Locked by rwlock */
531 isc_taskmgr_t * taskmgr;
532 isc_timermgr_t * timermgr;
533 isc_socketmgr_t * socketmgr;
534 isc_taskpool_t * zonetasks;
535 isc_taskpool_t * loadtasks;
536 isc_task_t * task;
537 isc_pool_t * mctxpool;
538 isc_ratelimiter_t * notifyrl;
539 isc_ratelimiter_t * refreshrl;
540 isc_ratelimiter_t * startupnotifyrl;
541 isc_ratelimiter_t * startuprefreshrl;
542 isc_rwlock_t rwlock;
543 isc_mutex_t iolock;
544 isc_rwlock_t urlock;
545
546 /* Locked by rwlock. */
547 dns_zonelist_t zones;
548 dns_zonelist_t waiting_for_xfrin;
549 dns_zonelist_t xfrin_in_progress;
550
551 /* Configuration data. */
552 uint32_t transfersin;
553 uint32_t transfersperns;
554 unsigned int notifyrate;
555 unsigned int startupnotifyrate;
556 unsigned int serialqueryrate;
557 unsigned int startupserialqueryrate;
558
559 /* Locked by iolock */
560 uint32_t iolimit;
561 uint32_t ioactive;
562 dns_iolist_t high;
563 dns_iolist_t low;
564
565 /* Locked by urlock. */
566 /* LRU cache */
567 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
568 };
569
570 /*%
571 * Hold notify state.
572 */
573 struct dns_notify {
574 unsigned int magic;
575 unsigned int flags;
576 isc_mem_t *mctx;
577 dns_zone_t *zone;
578 dns_adbfind_t *find;
579 dns_request_t *request;
580 dns_name_t ns;
581 isc_sockaddr_t dst;
582 dns_tsigkey_t *key;
583 isc_dscp_t dscp;
584 ISC_LINK(dns_notify_t) link;
585 isc_event_t *event;
586 };
587
588 #define DNS_NOTIFY_NOSOA 0x0001U
589 #define DNS_NOTIFY_STARTUP 0x0002U
590
591 /*%
592 * dns_stub holds state while performing a 'stub' transfer.
593 * 'db' is the zone's 'db' or a new one if this is the initial
594 * transfer.
595 */
596
597 struct dns_stub {
598 unsigned int magic;
599 isc_mem_t *mctx;
600 dns_zone_t *zone;
601 dns_db_t *db;
602 dns_dbversion_t *version;
603 };
604
605 /*%
606 * Hold load state.
607 */
608 struct dns_load {
609 unsigned int magic;
610 isc_mem_t *mctx;
611 dns_zone_t *zone;
612 dns_db_t *db;
613 isc_time_t loadtime;
614 dns_rdatacallbacks_t callbacks;
615 };
616
617 /*%
618 * Hold forward state.
619 */
620 struct dns_forward {
621 unsigned int magic;
622 isc_mem_t *mctx;
623 dns_zone_t *zone;
624 isc_buffer_t *msgbuf;
625 dns_request_t *request;
626 uint32_t which;
627 isc_sockaddr_t addr;
628 dns_updatecallback_t callback;
629 void *callback_arg;
630 unsigned int options;
631 ISC_LINK(dns_forward_t) link;
632 };
633
634 /*%
635 * Hold IO request state.
636 */
637 struct dns_io {
638 unsigned int magic;
639 dns_zonemgr_t *zmgr;
640 bool high;
641 isc_task_t *task;
642 ISC_LINK(dns_io_t) link;
643 isc_event_t *event;
644 };
645
646 /*%
647 * Hold state for when we are signing a zone with a new
648 * DNSKEY as result of an update.
649 */
650 struct dns_signing {
651 unsigned int magic;
652 dns_db_t *db;
653 dns_dbiterator_t *dbiterator;
654 dns_secalg_t algorithm;
655 uint16_t keyid;
656 bool deleteit;
657 bool done;
658 ISC_LINK(dns_signing_t) link;
659 };
660
661 struct dns_nsec3chain {
662 unsigned int magic;
663 dns_db_t *db;
664 dns_dbiterator_t *dbiterator;
665 dns_rdata_nsec3param_t nsec3param;
666 unsigned char salt[255];
667 bool done;
668 bool seen_nsec;
669 bool delete_nsec;
670 bool save_delete_nsec;
671 ISC_LINK(dns_nsec3chain_t) link;
672 };
673 /*%<
674 * 'dbiterator' contains a iterator for the database. If we are creating
675 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
676 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
677 * iterated.
678 *
679 * 'nsec3param' contains the parameters of the NSEC3 chain being created
680 * or removed.
681 *
682 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
683 *
684 * 'seen_nsec' will be set to true if, while iterating the zone to create a
685 * NSEC3 chain, a NSEC record is seen.
686 *
687 * 'delete_nsec' will be set to true if, at the completion of the creation
688 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
689 * are in the process of deleting the NSEC chain.
690 *
691 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
692 * so it can be recovered in the event of a error.
693 */
694
695 struct dns_keyfetch {
696 dns_fixedname_t name;
697 dns_rdataset_t keydataset;
698 dns_rdataset_t dnskeyset;
699 dns_rdataset_t dnskeysigset;
700 dns_zone_t *zone;
701 dns_db_t *db;
702 dns_fetch_t *fetch;
703 };
704
705 /*%
706 * Hold state for an asynchronous load
707 */
708 struct dns_asyncload {
709 dns_zone_t *zone;
710 unsigned int flags;
711 dns_zt_zoneloaded_t loaded;
712 void *loaded_arg;
713 };
714
715 /*%
716 * Reference to an include file encountered during loading
717 */
718 struct dns_include {
719 char *name;
720 isc_time_t filetime;
721 ISC_LINK(dns_include_t) link;
722 };
723
724 /*
725 * These can be overridden by the -T mkeytimers option on the command
726 * line, so that we can test with shorter periods than specified in
727 * RFC 5011.
728 */
729 #define HOUR 3600
730 #define DAY (24*HOUR)
731 #define MONTH (30*DAY)
732 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_hour = HOUR;
733 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_day = DAY;
734 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_month = MONTH;
735
736 #define SEND_BUFFER_SIZE 2048
737
738 static void zone_settimer(dns_zone_t *, isc_time_t *);
739 static void cancel_refresh(dns_zone_t *);
740 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
741 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
742 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
743 ISC_FORMAT_PRINTF(3, 4);
744 static void dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...)
745 ISC_FORMAT_PRINTF(3, 4);
746 static void queue_xfrin(dns_zone_t *zone);
747 static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
748 dns_diff_t *diff, dns_diffop_t op,
749 dns_name_t *name, dns_ttl_t ttl,
750 dns_rdata_t *rdata);
751 static void zone_unload(dns_zone_t *zone);
752 static void zone_expire(dns_zone_t *zone);
753 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
754 static void zone_idetach(dns_zone_t **zonep);
755 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
756 bool dump);
757 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
758 static inline void zone_detachdb(dns_zone_t *zone);
759 static isc_result_t default_journal(dns_zone_t *zone);
760 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
761 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
762 isc_time_t loadtime, isc_result_t result);
763 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
764 static void zone_shutdown(isc_task_t *, isc_event_t *);
765 static void zone_loaddone(void *arg, isc_result_t result);
766 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
767 isc_time_t loadtime);
768 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
769 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
770 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
771 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
772 static isc_result_t zone_send_secureserial(dns_zone_t *zone,
773 uint32_t serial);
774 static void refresh_callback(isc_task_t *, isc_event_t *);
775 static void stub_callback(isc_task_t *, isc_event_t *);
776 static void queue_soa_query(dns_zone_t *zone);
777 static void soa_query(isc_task_t *, isc_event_t *);
778 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
779 dns_stub_t *stub);
780 static int message_count(dns_message_t *msg, dns_section_t section,
781 dns_rdatatype_t type);
782 static void notify_cancel(dns_zone_t *zone);
783 static void notify_find_address(dns_notify_t *notify);
784 static void notify_send(dns_notify_t *notify);
785 static isc_result_t notify_createmessage(dns_zone_t *zone,
786 unsigned int flags,
787 dns_message_t **messagep);
788 static void notify_done(isc_task_t *task, isc_event_t *event);
789 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
790 static isc_result_t zone_dump(dns_zone_t *, bool);
791 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
792 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
793 dns_zone_t *zone);
794 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi);
795 static void zonemgr_free(dns_zonemgr_t *zmgr);
796 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, bool high,
797 isc_task_t *task, isc_taskaction_t action,
798 void *arg, dns_io_t **iop);
799 static void zonemgr_putio(dns_io_t **iop);
800 static void zonemgr_cancelio(dns_io_t *io);
801 static void rss_post(dns_zone_t *, isc_event_t *);
802
803 static isc_result_t
804 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
805 unsigned int *soacount, uint32_t *serial,
806 uint32_t *refresh, uint32_t *retry,
807 uint32_t *expire, uint32_t *minimum,
808 unsigned int *errors);
809
810 static void zone_freedbargs(dns_zone_t *zone);
811 static void forward_callback(isc_task_t *task, isc_event_t *event);
812 static void zone_saveunique(dns_zone_t *zone, const char *path,
813 const char *templat);
814 static void zone_maintenance(dns_zone_t *zone);
815 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
816 static void dump_done(void *arg, isc_result_t result);
817 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
818 uint16_t keyid,
819 bool deleteit);
820 static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
821 dns_dbnode_t *node, dns_name_t *name,
822 dns_diff_t *diff);
823 static void zone_rekey(dns_zone_t *zone);
824 static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db);
825 static void setrl(isc_ratelimiter_t *rl, unsigned int *rate,
826 unsigned int value);
827
828 #define ENTER zone_debuglog(zone, me, 1, "enter")
829
830 static const unsigned int dbargc_default = 1;
831 static const char *dbargv_default[] = { "rbt" };
832
833 #define DNS_ZONE_JITTER_ADD(a, b, c) \
834 do { \
835 isc_interval_t _i; \
836 uint32_t _j; \
837 _j = (b) - isc_random_uniform((b)/4); \
838 isc_interval_set(&_i, _j, 0); \
839 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
840 dns_zone_log(zone, ISC_LOG_WARNING, \
841 "epoch approaching: upgrade required: " \
842 "now + %s failed", #b); \
843 isc_interval_set(&_i, _j/2, 0); \
844 (void)isc_time_add((a), &_i, (c)); \
845 } \
846 } while (/*CONSTCOND*/0)
847
848 #define DNS_ZONE_TIME_ADD(a, b, c) \
849 do { \
850 isc_interval_t _i; \
851 isc_interval_set(&_i, (b), 0); \
852 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
853 dns_zone_log(zone, ISC_LOG_WARNING, \
854 "epoch approaching: upgrade required: " \
855 "now + %s failed", #b); \
856 isc_interval_set(&_i, (b)/2, 0); \
857 (void)isc_time_add((a), &_i, (c)); \
858 } \
859 } while (/*CONSTCOND*/0)
860
861 typedef struct nsec3param nsec3param_t;
862 struct nsec3param {
863 unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
864 unsigned int length;
865 bool nsec;
866 bool replace;
867 ISC_LINK(nsec3param_t) link;
868 };
869 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t;
870 struct np3event {
871 isc_event_t event;
872 nsec3param_t params;
873 };
874
875 struct ssevent {
876 isc_event_t event;
877 uint32_t serial;
878 };
879
880 /*%
881 * Increment resolver-related statistics counters. Zone must be locked.
882 */
883 static inline void
884 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
885 if (zone->stats != NULL)
886 isc_stats_increment(zone->stats, counter);
887 }
888
889 /***
890 *** Public functions.
891 ***/
892
893 isc_result_t
894 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
895 isc_result_t result;
896 dns_zone_t *zone;
897 isc_time_t now;
898
899 REQUIRE(zonep != NULL && *zonep == NULL);
900 REQUIRE(mctx != NULL);
901
902 TIME_NOW(&now);
903 zone = isc_mem_get(mctx, sizeof(*zone));
904 if (zone == NULL) {
905 return (ISC_R_NOMEMORY);
906 }
907
908 zone->mctx = NULL;
909 isc_mem_attach(mctx, &zone->mctx);
910
911 isc_mutex_init(&zone->lock);
912
913 result = ZONEDB_INITLOCK(&zone->dblock);
914 if (result != ISC_R_SUCCESS) {
915 goto free_mutex;
916 }
917
918 /* XXX MPA check that all elements are initialised */
919 #ifdef DNS_ZONE_CHECKLOCK
920 zone->locked = false;
921 #endif
922 zone->db = NULL;
923 zone->zmgr = NULL;
924 ISC_LINK_INIT(zone, link);
925 isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
926 zone->irefs = 0;
927 dns_name_init(&zone->origin, NULL);
928 zone->strnamerd = NULL;
929 zone->strname = NULL;
930 zone->strrdclass = NULL;
931 zone->strviewname = NULL;
932 zone->masterfile = NULL;
933 ISC_LIST_INIT(zone->includes);
934 ISC_LIST_INIT(zone->newincludes);
935 zone->nincludes = 0;
936 zone->masterformat = dns_masterformat_none;
937 zone->masterstyle = NULL;
938 zone->keydirectory = NULL;
939 zone->journalsize = -1;
940 zone->journal = NULL;
941 zone->rdclass = dns_rdataclass_none;
942 zone->type = dns_zone_none;
943 zone->flags = 0;
944 zone->options = 0;
945 zone->keyopts = 0;
946 zone->db_argc = 0;
947 zone->db_argv = NULL;
948 isc_time_settoepoch(&zone->expiretime);
949 isc_time_settoepoch(&zone->refreshtime);
950 isc_time_settoepoch(&zone->dumptime);
951 isc_time_settoepoch(&zone->loadtime);
952 zone->notifytime = now;
953 isc_time_settoepoch(&zone->resigntime);
954 isc_time_settoepoch(&zone->keywarntime);
955 isc_time_settoepoch(&zone->signingtime);
956 isc_time_settoepoch(&zone->nsec3chaintime);
957 isc_time_settoepoch(&zone->refreshkeytime);
958 zone->refreshkeyinterval = 0;
959 zone->refreshkeycount = 0;
960 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
961 zone->retry = DNS_ZONE_DEFAULTRETRY;
962 zone->expire = 0;
963 zone->minimum = 0;
964 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
965 zone->minrefresh = DNS_ZONE_MINREFRESH;
966 zone->maxretry = DNS_ZONE_MAXRETRY;
967 zone->minretry = DNS_ZONE_MINRETRY;
968 zone->masters = NULL;
969 zone->masterdscps = NULL;
970 zone->masterkeynames = NULL;
971 zone->mastersok = NULL;
972 zone->masterscnt = 0;
973 zone->curmaster = 0;
974 zone->maxttl = 0;
975 zone->notify = NULL;
976 zone->notifykeynames = NULL;
977 zone->notifydscp = NULL;
978 zone->notifytype = dns_notifytype_yes;
979 zone->notifycnt = 0;
980 zone->task = NULL;
981 zone->loadtask = NULL;
982 zone->update_acl = NULL;
983 zone->forward_acl = NULL;
984 zone->notify_acl = NULL;
985 zone->query_acl = NULL;
986 zone->queryon_acl = NULL;
987 zone->xfr_acl = NULL;
988 zone->update_disabled = false;
989 zone->zero_no_soa_ttl = true;
990 zone->check_names = dns_severity_ignore;
991 zone->request = NULL;
992 zone->lctx = NULL;
993 zone->readio = NULL;
994 zone->dctx = NULL;
995 zone->writeio = NULL;
996 zone->timer = NULL;
997 zone->idlein = DNS_DEFAULT_IDLEIN;
998 zone->idleout = DNS_DEFAULT_IDLEOUT;
999 zone->log_key_expired_timer = 0;
1000 ISC_LIST_INIT(zone->notifies);
1001 isc_sockaddr_any(&zone->notifysrc4);
1002 isc_sockaddr_any6(&zone->notifysrc6);
1003 isc_sockaddr_any(&zone->xfrsource4);
1004 isc_sockaddr_any6(&zone->xfrsource6);
1005 isc_sockaddr_any(&zone->altxfrsource4);
1006 isc_sockaddr_any6(&zone->altxfrsource6);
1007 zone->notifysrc4dscp = -1;
1008 zone->notifysrc6dscp = -1;
1009 zone->xfrsource4dscp = -1;
1010 zone->xfrsource6dscp = -1;
1011 zone->altxfrsource4dscp = -1;
1012 zone->altxfrsource6dscp = -1;
1013 zone->xfr = NULL;
1014 zone->tsigkey = NULL;
1015 zone->maxxfrin = MAX_XFER_TIME;
1016 zone->maxxfrout = MAX_XFER_TIME;
1017 zone->ssutable = NULL;
1018 zone->sigvalidityinterval = 30 * 24 * 3600;
1019 zone->keyvalidityinterval = 0;
1020 zone->sigresigninginterval = 7 * 24 * 3600;
1021 zone->view = NULL;
1022 zone->prev_view = NULL;
1023 zone->checkmx = NULL;
1024 zone->checksrv = NULL;
1025 zone->checkns = NULL;
1026 ISC_LINK_INIT(zone, statelink);
1027 zone->statelist = NULL;
1028 zone->stats = NULL;
1029 zone->requeststats_on = false;
1030 zone->statlevel = dns_zonestat_none;
1031 zone->requeststats = NULL;
1032 zone->rcvquerystats = NULL;
1033 zone->dnssecsignstats = NULL;
1034 zone->dnssecrefreshstats = NULL;
1035 zone->notifydelay = 5;
1036 zone->isself = NULL;
1037 zone->isselfarg = NULL;
1038 ISC_LIST_INIT(zone->signing);
1039 ISC_LIST_INIT(zone->nsec3chain);
1040 ISC_LIST_INIT(zone->setnsec3param_queue);
1041 zone->signatures = 10;
1042 zone->nodes = 100;
1043 zone->privatetype = (dns_rdatatype_t)0xffffU;
1044 zone->added = false;
1045 zone->automatic = false;
1046 zone->rpzs = NULL;
1047 zone->rpz_num = DNS_RPZ_INVALID_NUM;
1048
1049 zone->catzs = NULL;
1050 zone->parentcatz = NULL;
1051
1052 ISC_LIST_INIT(zone->forwards);
1053 zone->raw = NULL;
1054 zone->secure = NULL;
1055 zone->sourceserial = 0;
1056 zone->sourceserialset = false;
1057 zone->requestixfr = true;
1058 zone->requestexpire = true;
1059 ISC_LIST_INIT(zone->rss_events);
1060 ISC_LIST_INIT(zone->rss_post);
1061 zone->rss_db = NULL;
1062 zone->rss_raw = NULL;
1063 zone->rss_newver = NULL;
1064 zone->rss_oldver = NULL;
1065 zone->rss_event = NULL;
1066 zone->rss_state = NULL;
1067 zone->updatemethod = dns_updatemethod_increment;
1068 zone->maxrecords = 0U;
1069
1070 zone->magic = ZONE_MAGIC;
1071
1072 zone->gluecachestats = NULL;
1073 result = isc_stats_create(mctx, &zone->gluecachestats,
1074 dns_gluecachestatscounter_max);
1075 if (result != ISC_R_SUCCESS) {
1076 goto free_erefs;
1077 }
1078
1079 /* Must be after magic is set. */
1080 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
1081 if (result != ISC_R_SUCCESS) {
1082 goto free_stats;
1083 }
1084
1085 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
1086 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
1087 NULL, NULL);
1088 *zonep = zone;
1089 return (ISC_R_SUCCESS);
1090
1091 free_stats:
1092 if (zone->gluecachestats != NULL)
1093 isc_stats_detach(&zone->gluecachestats);
1094
1095 free_erefs:
1096 INSIST(isc_refcount_decrement(&zone->erefs) > 0);
1097 isc_refcount_destroy(&zone->erefs);
1098
1099 ZONEDB_DESTROYLOCK(&zone->dblock);
1100
1101 free_mutex:
1102 isc_mutex_destroy(&zone->lock);
1103
1104 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
1105 return (result);
1106 }
1107
1108 /*
1109 * Free a zone. Because we require that there be no more
1110 * outstanding events or references, no locking is necessary.
1111 */
1112 static void
1113 zone_free(dns_zone_t *zone) {
1114 isc_mem_t *mctx = NULL;
1115 dns_signing_t *signing;
1116 dns_nsec3chain_t *nsec3chain;
1117 isc_event_t *event;
1118 dns_include_t *include;
1119
1120 REQUIRE(DNS_ZONE_VALID(zone));
1121 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
1122 REQUIRE(zone->irefs == 0);
1123 REQUIRE(!LOCKED_ZONE(zone));
1124 REQUIRE(zone->timer == NULL);
1125 REQUIRE(zone->zmgr == NULL);
1126
1127 /*
1128 * Managed objects. Order is important.
1129 */
1130 if (zone->request != NULL) {
1131 dns_request_destroy(&zone->request); /* XXXMPA */
1132 }
1133 INSIST(zone->readio == NULL);
1134 INSIST(zone->statelist == NULL);
1135 INSIST(zone->writeio == NULL);
1136
1137 if (zone->task != NULL) {
1138 isc_task_detach(&zone->task);
1139 }
1140 if (zone->loadtask != NULL) {
1141 isc_task_detach(&zone->loadtask);
1142 }
1143 if (zone->view != NULL) {
1144 dns_view_weakdetach(&zone->view);
1145 }
1146 if (zone->prev_view != NULL) {
1147 dns_view_weakdetach(&zone->prev_view);
1148 }
1149
1150 /* Unmanaged objects */
1151 while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
1152 event = ISC_LIST_HEAD(zone->setnsec3param_queue);
1153 ISC_LIST_UNLINK(zone->setnsec3param_queue, event, ev_link);
1154 isc_event_free(&event);
1155 }
1156 while (!ISC_LIST_EMPTY(zone->rss_post)) {
1157 event = ISC_LIST_HEAD(zone->rss_post);
1158 ISC_LIST_UNLINK(zone->rss_post, event, ev_link);
1159 isc_event_free(&event);
1160 }
1161 for (signing = ISC_LIST_HEAD(zone->signing);
1162 signing != NULL;
1163 signing = ISC_LIST_HEAD(zone->signing)) {
1164 ISC_LIST_UNLINK(zone->signing, signing, link);
1165 dns_db_detach(&signing->db);
1166 dns_dbiterator_destroy(&signing->dbiterator);
1167 isc_mem_put(zone->mctx, signing, sizeof *signing);
1168 }
1169 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
1170 nsec3chain != NULL;
1171 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
1172 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
1173 dns_db_detach(&nsec3chain->db);
1174 dns_dbiterator_destroy(&nsec3chain->dbiterator);
1175 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
1176 }
1177 for (include = ISC_LIST_HEAD(zone->includes);
1178 include != NULL;
1179 include = ISC_LIST_HEAD(zone->includes)) {
1180 ISC_LIST_UNLINK(zone->includes, include, link);
1181 isc_mem_free(zone->mctx, include->name);
1182 isc_mem_put(zone->mctx, include, sizeof *include);
1183 }
1184 for (include = ISC_LIST_HEAD(zone->newincludes);
1185 include != NULL;
1186 include = ISC_LIST_HEAD(zone->newincludes)) {
1187 ISC_LIST_UNLINK(zone->newincludes, include, link);
1188 isc_mem_free(zone->mctx, include->name);
1189 isc_mem_put(zone->mctx, include, sizeof *include);
1190 }
1191 if (zone->masterfile != NULL) {
1192 isc_mem_free(zone->mctx, zone->masterfile);
1193 }
1194 zone->masterfile = NULL;
1195 if (zone->keydirectory != NULL) {
1196 isc_mem_free(zone->mctx, zone->keydirectory);
1197 }
1198 zone->keydirectory = NULL;
1199 zone->journalsize = -1;
1200 if (zone->journal != NULL) {
1201 isc_mem_free(zone->mctx, zone->journal);
1202 }
1203 zone->journal = NULL;
1204 if (zone->stats != NULL) {
1205 isc_stats_detach(&zone->stats);
1206 }
1207 if (zone->requeststats != NULL) {
1208 isc_stats_detach(&zone->requeststats);
1209 }
1210 if (zone->rcvquerystats != NULL){
1211 dns_stats_detach(&zone->rcvquerystats);
1212 }
1213 if (zone->dnssecsignstats != NULL){
1214 dns_stats_detach(&zone->dnssecsignstats);
1215 }
1216 if (zone->dnssecrefreshstats != NULL){
1217 dns_stats_detach(&zone->dnssecrefreshstats);
1218 }
1219 if (zone->db != NULL) {
1220 zone_detachdb(zone);
1221 }
1222 if (zone->rpzs != NULL) {
1223 REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones);
1224 dns_rpz_detach_rpzs(&zone->rpzs);
1225 zone->rpz_num = DNS_RPZ_INVALID_NUM;
1226 }
1227 if (zone->catzs != NULL) {
1228 dns_catz_catzs_detach(&zone->catzs);
1229 }
1230 zone_freedbargs(zone);
1231 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL,
1232 NULL, 0) == ISC_R_SUCCESS);
1233 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) == ISC_R_SUCCESS);
1234 zone->check_names = dns_severity_ignore;
1235 if (zone->update_acl != NULL) {
1236 dns_acl_detach(&zone->update_acl);
1237 }
1238 if (zone->forward_acl != NULL) {
1239 dns_acl_detach(&zone->forward_acl);
1240 }
1241 if (zone->notify_acl != NULL) {
1242 dns_acl_detach(&zone->notify_acl);
1243 }
1244 if (zone->query_acl != NULL) {
1245 dns_acl_detach(&zone->query_acl);
1246 }
1247 if (zone->queryon_acl != NULL) {
1248 dns_acl_detach(&zone->queryon_acl);
1249 }
1250 if (zone->xfr_acl != NULL) {
1251 dns_acl_detach(&zone->xfr_acl);
1252 }
1253 if (dns_name_dynamic(&zone->origin)) {
1254 dns_name_free(&zone->origin, zone->mctx);
1255 }
1256 if (zone->strnamerd != NULL) {
1257 isc_mem_free(zone->mctx, zone->strnamerd);
1258 }
1259 if (zone->strname != NULL) {
1260 isc_mem_free(zone->mctx, zone->strname);
1261 }
1262 if (zone->strrdclass != NULL) {
1263 isc_mem_free(zone->mctx, zone->strrdclass);
1264 }
1265 if (zone->strviewname != NULL) {
1266 isc_mem_free(zone->mctx, zone->strviewname);
1267 }
1268 if (zone->ssutable != NULL) {
1269 dns_ssutable_detach(&zone->ssutable);
1270 }
1271 if (zone->gluecachestats != NULL) {
1272 isc_stats_detach(&zone->gluecachestats);
1273 }
1274
1275 /* last stuff */
1276 ZONEDB_DESTROYLOCK(&zone->dblock);
1277 isc_mutex_destroy(&zone->lock);
1278 zone->magic = 0;
1279 mctx = zone->mctx;
1280 isc_mem_put(mctx, zone, sizeof(*zone));
1281 isc_mem_detach(&mctx);
1282 }
1283
1284 /*
1285 * Returns true iff this the signed side of an inline-signing zone.
1286 * Caller should hold zone lock.
1287 */
1288 static inline bool
1289 inline_secure(dns_zone_t *zone) {
1290 REQUIRE(DNS_ZONE_VALID(zone));
1291 if (zone->raw != NULL)
1292 return (true);
1293 return (false);
1294 }
1295
1296 /*
1297 * Returns true iff this the unsigned side of an inline-signing zone
1298 * Caller should hold zone lock.
1299 */
1300 static inline bool
1301 inline_raw(dns_zone_t *zone) {
1302 REQUIRE(DNS_ZONE_VALID(zone));
1303 if (zone->secure != NULL)
1304 return (true);
1305 return (false);
1306 }
1307
1308 /*
1309 * Single shot.
1310 */
1311 void
1312 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
1313 char namebuf[1024];
1314
1315 REQUIRE(DNS_ZONE_VALID(zone));
1316 REQUIRE(rdclass != dns_rdataclass_none);
1317
1318 /*
1319 * Test and set.
1320 */
1321 LOCK_ZONE(zone);
1322 INSIST(zone != zone->raw);
1323 REQUIRE(zone->rdclass == dns_rdataclass_none ||
1324 zone->rdclass == rdclass);
1325 zone->rdclass = rdclass;
1326
1327 if (zone->strnamerd != NULL)
1328 isc_mem_free(zone->mctx, zone->strnamerd);
1329 if (zone->strrdclass != NULL)
1330 isc_mem_free(zone->mctx, zone->strrdclass);
1331
1332 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1333 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1334 zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
1335 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
1336
1337 if (inline_secure(zone))
1338 dns_zone_setclass(zone->raw, rdclass);
1339 UNLOCK_ZONE(zone);
1340 }
1341
1342 dns_rdataclass_t
1343 dns_zone_getclass(dns_zone_t *zone) {
1344 REQUIRE(DNS_ZONE_VALID(zone));
1345
1346 return (zone->rdclass);
1347 }
1348
1349 void
1350 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
1351 REQUIRE(DNS_ZONE_VALID(zone));
1352
1353 LOCK_ZONE(zone);
1354 zone->notifytype = notifytype;
1355 UNLOCK_ZONE(zone);
1356 }
1357
1358 isc_result_t
1359 dns_zone_getserial(dns_zone_t *zone, uint32_t *serialp) {
1360 isc_result_t result;
1361 unsigned int soacount;
1362
1363 REQUIRE(DNS_ZONE_VALID(zone));
1364 REQUIRE(serialp != NULL);
1365
1366 LOCK_ZONE(zone);
1367 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1368 if (zone->db != NULL) {
1369 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
1370 serialp, NULL, NULL, NULL, NULL,
1371 NULL);
1372 if (result == ISC_R_SUCCESS && soacount == 0)
1373 result = ISC_R_FAILURE;
1374 } else
1375 result = DNS_R_NOTLOADED;
1376 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1377 UNLOCK_ZONE(zone);
1378
1379 return (result);
1380 }
1381
1382 /*
1383 * Single shot.
1384 */
1385 void
1386 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
1387 char namebuf[1024];
1388
1389 REQUIRE(DNS_ZONE_VALID(zone));
1390 REQUIRE(type != dns_zone_none);
1391
1392 /*
1393 * Test and set.
1394 */
1395 LOCK_ZONE(zone);
1396 REQUIRE(zone->type == dns_zone_none || zone->type == type);
1397 zone->type = type;
1398
1399 if (zone->strnamerd != NULL)
1400 isc_mem_free(zone->mctx, zone->strnamerd);
1401
1402 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1403 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1404 UNLOCK_ZONE(zone);
1405 }
1406
1407 static void
1408 zone_freedbargs(dns_zone_t *zone) {
1409 unsigned int i;
1410
1411 /* Free the old database argument list. */
1412 if (zone->db_argv != NULL) {
1413 for (i = 0; i < zone->db_argc; i++)
1414 isc_mem_free(zone->mctx, zone->db_argv[i]);
1415 isc_mem_put(zone->mctx, zone->db_argv,
1416 zone->db_argc * sizeof(*zone->db_argv));
1417 }
1418 zone->db_argc = 0;
1419 zone->db_argv = NULL;
1420 }
1421
1422 isc_result_t
1423 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1424 size_t size = 0;
1425 unsigned int i;
1426 isc_result_t result = ISC_R_SUCCESS;
1427 void *mem;
1428 char **tmp, *tmp2, *base;
1429
1430 REQUIRE(DNS_ZONE_VALID(zone));
1431 REQUIRE(argv != NULL && *argv == NULL);
1432
1433 LOCK_ZONE(zone);
1434 size = (zone->db_argc + 1) * sizeof(char *);
1435 for (i = 0; i < zone->db_argc; i++)
1436 size += strlen(zone->db_argv[i]) + 1;
1437 mem = isc_mem_allocate(mctx, size);
1438 if (mem != NULL) {
1439 tmp = mem;
1440 tmp2 = mem;
1441 base = mem;
1442 tmp2 += (zone->db_argc + 1) * sizeof(char *);
1443 for (i = 0; i < zone->db_argc; i++) {
1444 *tmp++ = tmp2;
1445 strlcpy(tmp2, zone->db_argv[i], size - (tmp2 - base));
1446 tmp2 += strlen(tmp2) + 1;
1447 }
1448 *tmp = NULL;
1449 } else
1450 result = ISC_R_NOMEMORY;
1451 UNLOCK_ZONE(zone);
1452 *argv = mem;
1453 return (result);
1454 }
1455
1456 isc_result_t
1457 dns_zone_setdbtype(dns_zone_t *zone,
1458 unsigned int dbargc, const char * const *dbargv)
1459 {
1460 isc_result_t result = ISC_R_SUCCESS;
1461 char **argv = NULL;
1462 unsigned int i;
1463
1464 REQUIRE(DNS_ZONE_VALID(zone));
1465 REQUIRE(dbargc >= 1);
1466 REQUIRE(dbargv != NULL);
1467
1468 LOCK_ZONE(zone);
1469
1470 /* Set up a new database argument list. */
1471 argv = isc_mem_get(zone->mctx, dbargc * sizeof(*argv));
1472 if (argv == NULL) {
1473 goto nomem;
1474 }
1475 for (i = 0; i < dbargc; i++) {
1476 argv[i] = NULL;
1477 }
1478 for (i = 0; i < dbargc; i++) {
1479 argv[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1480 if (argv[i] == NULL)
1481 goto nomem;
1482 }
1483
1484 /* Free the old list. */
1485 zone_freedbargs(zone);
1486
1487 zone->db_argc = dbargc;
1488 zone->db_argv = argv;
1489 result = ISC_R_SUCCESS;
1490 goto unlock;
1491
1492 nomem:
1493 if (argv != NULL) {
1494 for (i = 0; i < dbargc; i++) {
1495 if (argv[i] != NULL) {
1496 isc_mem_free(zone->mctx, argv[i]);
1497 }
1498 }
1499 isc_mem_put(zone->mctx, argv, dbargc * sizeof(*argv));
1500 }
1501 result = ISC_R_NOMEMORY;
1502
1503 unlock:
1504 UNLOCK_ZONE(zone);
1505 return (result);
1506 }
1507
1508 static void
1509 dns_zone_setview_helper(dns_zone_t *zone, dns_view_t *view) {
1510 char namebuf[1024];
1511
1512 if (zone->prev_view == NULL && zone->view != NULL) {
1513 dns_view_weakattach(zone->view, &zone->prev_view);
1514 }
1515
1516 INSIST(zone != zone->raw);
1517 if (zone->view != NULL) {
1518 dns_view_weakdetach(&zone->view);
1519 }
1520 dns_view_weakattach(view, &zone->view);
1521
1522 if (zone->strviewname != NULL) {
1523 isc_mem_free(zone->mctx, zone->strviewname);
1524 }
1525 if (zone->strnamerd != NULL) {
1526 isc_mem_free(zone->mctx, zone->strnamerd);
1527 }
1528
1529 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1530 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1531 zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1532 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1533
1534 if (inline_secure(zone)) {
1535 dns_zone_setview(zone->raw, view);
1536 }
1537 }
1538
1539 void
1540 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1541 REQUIRE(DNS_ZONE_VALID(zone));
1542
1543 LOCK_ZONE(zone);
1544 dns_zone_setview_helper(zone, view);
1545 UNLOCK_ZONE(zone);
1546 }
1547
1548 dns_view_t *
1549 dns_zone_getview(dns_zone_t *zone) {
1550 REQUIRE(DNS_ZONE_VALID(zone));
1551
1552 return (zone->view);
1553 }
1554
1555 void
1556 dns_zone_setviewcommit(dns_zone_t *zone) {
1557 REQUIRE(DNS_ZONE_VALID(zone));
1558
1559 LOCK_ZONE(zone);
1560 if (zone->prev_view != NULL)
1561 dns_view_weakdetach(&zone->prev_view);
1562 UNLOCK_ZONE(zone);
1563 }
1564
1565 void
1566 dns_zone_setviewrevert(dns_zone_t *zone) {
1567 REQUIRE(DNS_ZONE_VALID(zone));
1568
1569 LOCK_ZONE(zone);
1570 if (zone->prev_view != NULL) {
1571 dns_zone_setview_helper(zone, zone->prev_view);
1572 dns_view_weakdetach(&zone->prev_view);
1573 }
1574 UNLOCK_ZONE(zone);
1575 }
1576
1577 isc_result_t
1578 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1579 isc_result_t result;
1580 char namebuf[1024];
1581
1582 REQUIRE(DNS_ZONE_VALID(zone));
1583 REQUIRE(origin != NULL);
1584
1585 LOCK_ZONE(zone);
1586 INSIST(zone != zone->raw);
1587 if (dns_name_dynamic(&zone->origin)) {
1588 dns_name_free(&zone->origin, zone->mctx);
1589 dns_name_init(&zone->origin, NULL);
1590 }
1591 result = dns_name_dup(origin, zone->mctx, &zone->origin);
1592
1593 if (zone->strnamerd != NULL)
1594 isc_mem_free(zone->mctx, zone->strnamerd);
1595 if (zone->strname != NULL)
1596 isc_mem_free(zone->mctx, zone->strname);
1597
1598 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1599 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1600 zone_name_tostr(zone, namebuf, sizeof namebuf);
1601 zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1602
1603 if (result == ISC_R_SUCCESS && inline_secure(zone))
1604 result = dns_zone_setorigin(zone->raw, origin);
1605 UNLOCK_ZONE(zone);
1606 return (result);
1607 }
1608
1609 static isc_result_t
1610 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1611 char *copy;
1612
1613 if (value != NULL) {
1614 copy = isc_mem_strdup(zone->mctx, value);
1615 if (copy == NULL)
1616 return (ISC_R_NOMEMORY);
1617 } else {
1618 copy = NULL;
1619 }
1620
1621 if (*field != NULL)
1622 isc_mem_free(zone->mctx, *field);
1623
1624 *field = copy;
1625 return (ISC_R_SUCCESS);
1626 }
1627
1628 isc_result_t
1629 dns_zone_setfile(dns_zone_t *zone, const char *file,
1630 dns_masterformat_t format,
1631 const dns_master_style_t *style)
1632 {
1633 isc_result_t result = ISC_R_SUCCESS;
1634
1635 REQUIRE(DNS_ZONE_VALID(zone));
1636
1637 LOCK_ZONE(zone);
1638 result = dns_zone_setstring(zone, &zone->masterfile, file);
1639 if (result == ISC_R_SUCCESS) {
1640 zone->masterformat = format;
1641 if (format == dns_masterformat_text)
1642 zone->masterstyle = style;
1643 result = default_journal(zone);
1644 }
1645 UNLOCK_ZONE(zone);
1646
1647 return (result);
1648 }
1649
1650 const char *
1651 dns_zone_getfile(dns_zone_t *zone) {
1652 REQUIRE(DNS_ZONE_VALID(zone));
1653
1654 return (zone->masterfile);
1655 }
1656
1657 dns_ttl_t
1658 dns_zone_getmaxttl(dns_zone_t *zone) {
1659 REQUIRE(DNS_ZONE_VALID(zone));
1660
1661 return (zone->maxttl);
1662 }
1663
1664 void
1665 dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) {
1666 REQUIRE(DNS_ZONE_VALID(zone));
1667
1668 LOCK_ZONE(zone);
1669 if (maxttl != 0)
1670 zone->options |= DNS_ZONEOPT_CHECKTTL;
1671 else
1672 zone->options &= ~DNS_ZONEOPT_CHECKTTL;
1673 zone->maxttl = maxttl;
1674 UNLOCK_ZONE(zone);
1675
1676 return;
1677 }
1678
1679 static isc_result_t
1680 default_journal(dns_zone_t *zone) {
1681 isc_result_t result;
1682 char *journal;
1683
1684 REQUIRE(DNS_ZONE_VALID(zone));
1685 REQUIRE(LOCKED_ZONE(zone));
1686
1687 if (zone->masterfile != NULL) {
1688 /* Calculate string length including '\0'. */
1689 int len = strlen(zone->masterfile) + sizeof(".jnl");
1690 journal = isc_mem_allocate(zone->mctx, len);
1691 if (journal == NULL)
1692 return (ISC_R_NOMEMORY);
1693 strlcpy(journal, zone->masterfile, len);
1694 strlcat(journal, ".jnl", len);
1695 } else {
1696 journal = NULL;
1697 }
1698 result = dns_zone_setstring(zone, &zone->journal, journal);
1699 if (journal != NULL)
1700 isc_mem_free(zone->mctx, journal);
1701 return (result);
1702 }
1703
1704 isc_result_t
1705 dns_zone_setjournal(dns_zone_t *zone, const char *myjournal) {
1706 isc_result_t result = ISC_R_SUCCESS;
1707
1708 REQUIRE(DNS_ZONE_VALID(zone));
1709
1710 LOCK_ZONE(zone);
1711 result = dns_zone_setstring(zone, &zone->journal, myjournal);
1712 UNLOCK_ZONE(zone);
1713
1714 return (result);
1715 }
1716
1717 char *
1718 dns_zone_getjournal(dns_zone_t *zone) {
1719 REQUIRE(DNS_ZONE_VALID(zone));
1720
1721 return (zone->journal);
1722 }
1723
1724 /*
1725 * Return true iff the zone is "dynamic", in the sense that the zone's
1726 * master file (if any) is written by the server, rather than being
1727 * updated manually and read by the server.
1728 *
1729 * This is true for slave zones, mirror zones, stub zones, key zones,
1730 * and zones that allow dynamic updates either by having an update
1731 * policy ("ssutable") or an "allow-update" ACL with a value other than
1732 * exactly "{ none; }".
1733 */
1734 bool
1735 dns_zone_isdynamic(dns_zone_t *zone, bool ignore_freeze) {
1736 REQUIRE(DNS_ZONE_VALID(zone));
1737
1738 if (zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
1739 zone->type == dns_zone_stub || zone->type == dns_zone_key ||
1740 (zone->type == dns_zone_redirect && zone->masters != NULL))
1741 return (true);
1742
1743 /* Inline zones are always dynamic. */
1744 if (zone->type == dns_zone_master && zone->raw != NULL)
1745 return (true);
1746
1747 /* If !ignore_freeze, we need check whether updates are disabled. */
1748 if (zone->type == dns_zone_master &&
1749 (!zone->update_disabled || ignore_freeze) &&
1750 ((zone->ssutable != NULL) ||
1751 (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl))))
1752 return (true);
1753
1754 return (false);
1755
1756 }
1757
1758 /*
1759 * Set the response policy index and information for a zone.
1760 */
1761 isc_result_t
1762 dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs,
1763 dns_rpz_num_t rpz_num)
1764 {
1765 /*
1766 * Only RBTDB zones can be used for response policy zones,
1767 * because only they have the code to create the summary data.
1768 * Only zones that are loaded instead of mmap()ed create the
1769 * summary data and so can be policy zones.
1770 */
1771 if (strcmp(zone->db_argv[0], "rbt") != 0 &&
1772 strcmp(zone->db_argv[0], "rbt64") != 0)
1773 return (ISC_R_NOTIMPLEMENTED);
1774 if (zone->masterformat == dns_masterformat_map)
1775 return (ISC_R_NOTIMPLEMENTED);
1776
1777 /*
1778 * This must happen only once or be redundant.
1779 */
1780 LOCK_ZONE(zone);
1781 if (zone->rpzs != NULL) {
1782 REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num);
1783 } else {
1784 REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM);
1785 dns_rpz_attach_rpzs(rpzs, &zone->rpzs);
1786 zone->rpz_num = rpz_num;
1787 }
1788 rpzs->defined |= DNS_RPZ_ZBIT(rpz_num);
1789 UNLOCK_ZONE(zone);
1790
1791 return (ISC_R_SUCCESS);
1792 }
1793
1794 dns_rpz_num_t
1795 dns_zone_get_rpz_num(dns_zone_t *zone) {
1796 return (zone->rpz_num);
1797 }
1798
1799 /*
1800 * If a zone is a response policy zone, mark its new database.
1801 */
1802 void
1803 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) {
1804 isc_result_t result;
1805 if (zone->rpz_num == DNS_RPZ_INVALID_NUM) {
1806 return;
1807 }
1808 REQUIRE(zone->rpzs != NULL);
1809 result = dns_db_updatenotify_register(db,
1810 dns_rpz_dbupdate_callback,
1811 zone->rpzs->zones[zone->rpz_num]);
1812 REQUIRE(result == ISC_R_SUCCESS);
1813 }
1814
1815 static void
1816 dns_zone_rpz_disable_db(dns_zone_t *zone, dns_db_t *db) {
1817 if (zone->rpz_num == DNS_RPZ_INVALID_NUM) {
1818 return;
1819 }
1820 REQUIRE(zone->rpzs != NULL);
1821 (void) dns_db_updatenotify_unregister(db,
1822 dns_rpz_dbupdate_callback,
1823 zone->rpzs->zones[zone->rpz_num]);
1824 }
1825
1826 void
1827 dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) {
1828 REQUIRE(DNS_ZONE_VALID(zone));
1829 REQUIRE(catzs != NULL);
1830
1831 LOCK_ZONE(zone);
1832 INSIST(zone->catzs == NULL || zone->catzs == catzs);
1833 dns_catz_catzs_set_view(catzs, zone->view);
1834 if (zone->catzs == NULL) {
1835 dns_catz_catzs_attach(catzs, &zone->catzs);
1836 }
1837 UNLOCK_ZONE(zone);
1838 }
1839
1840 /*
1841 * If a zone is a catalog zone, attach it to update notification in database.
1842 */
1843 void
1844 dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) {
1845 REQUIRE(DNS_ZONE_VALID(zone));
1846 REQUIRE(db != NULL);
1847
1848 if (zone->catzs != NULL) {
1849 dns_db_updatenotify_register(db, dns_catz_dbupdate_callback,
1850 zone->catzs);
1851 }
1852 }
1853
1854 static void
1855 dns_zone_catz_disable_db(dns_zone_t *zone, dns_db_t *db) {
1856 REQUIRE(DNS_ZONE_VALID(zone));
1857 REQUIRE(db != NULL);
1858
1859 if (zone->catzs != NULL) {
1860 dns_db_updatenotify_unregister(db, dns_catz_dbupdate_callback,
1861 zone->catzs);
1862 }
1863 }
1864
1865 /*
1866 * Set catalog zone ownership of the zone
1867 */
1868 void
1869 dns_zone_set_parentcatz(dns_zone_t *zone, dns_catz_zone_t *catz) {
1870 REQUIRE(DNS_ZONE_VALID(zone));
1871 REQUIRE(catz != NULL);
1872 LOCK_ZONE(zone);
1873 INSIST(zone->parentcatz == NULL || zone->parentcatz == catz);
1874 zone->parentcatz = catz;
1875 UNLOCK_ZONE(zone);
1876 }
1877
1878 dns_catz_zone_t *
1879 dns_zone_get_parentcatz(const dns_zone_t *zone) {
1880 REQUIRE(DNS_ZONE_VALID(zone));
1881 return (zone->parentcatz);
1882 }
1883
1884
1885 static bool
1886 zone_touched(dns_zone_t *zone) {
1887 isc_result_t result;
1888 isc_time_t modtime;
1889 dns_include_t *include;
1890
1891 REQUIRE(DNS_ZONE_VALID(zone));
1892
1893 result = isc_file_getmodtime(zone->masterfile, &modtime);
1894 if (result != ISC_R_SUCCESS ||
1895 isc_time_compare(&modtime, &zone->loadtime) > 0)
1896 return (true);
1897
1898 for (include = ISC_LIST_HEAD(zone->includes);
1899 include != NULL;
1900 include = ISC_LIST_NEXT(include, link))
1901 {
1902 result = isc_file_getmodtime(include->name, &modtime);
1903 if (result != ISC_R_SUCCESS ||
1904 isc_time_compare(&modtime, &include->filetime) > 0)
1905 return (true);
1906 }
1907
1908 return (false);
1909 }
1910
1911 /*
1912 * Note: when dealing with inline-signed zones, external callers will always
1913 * call zone_load() for the secure zone; zone_load() calls itself recursively
1914 * in order to load the raw zone.
1915 */
1916 static isc_result_t
1917 zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
1918 isc_result_t result;
1919 isc_time_t now;
1920 isc_time_t loadtime;
1921 dns_db_t *db = NULL;
1922 bool rbt, hasraw;
1923
1924 REQUIRE(DNS_ZONE_VALID(zone));
1925
1926 if (!locked)
1927 LOCK_ZONE(zone);
1928
1929 INSIST(zone != zone->raw);
1930 hasraw = inline_secure(zone);
1931 if (hasraw) {
1932 /*
1933 * We are trying to load an inline-signed zone. First call
1934 * self recursively to try loading the raw version of the zone.
1935 * Assuming the raw zone file is readable, there are two
1936 * possibilities:
1937 *
1938 * a) the raw zone was not yet loaded and thus it will be
1939 * loaded now, synchronously; if this succeeds, a
1940 * subsequent attempt to load the signed zone file will
1941 * take place and thus zone_postload() will be called
1942 * twice: first for the raw zone and then for the secure
1943 * zone; the latter call will take care of syncing the raw
1944 * version with the secure version,
1945 *
1946 * b) the raw zone was already loaded and we are trying to
1947 * reload it, which will happen asynchronously; this means
1948 * zone_postload() will only be called for the raw zone
1949 * because "result" returned by the zone_load() call below
1950 * will not be ISC_R_SUCCESS but rather DNS_R_CONTINUE;
1951 * zone_postload() called for the raw zone will take care
1952 * of syncing the raw version with the secure version.
1953 */
1954 result = zone_load(zone->raw, flags, false);
1955 if (result != ISC_R_SUCCESS) {
1956 if (!locked)
1957 UNLOCK_ZONE(zone);
1958 return(result);
1959 }
1960 LOCK_ZONE(zone->raw);
1961 }
1962
1963 TIME_NOW(&now);
1964
1965 INSIST(zone->type != dns_zone_none);
1966
1967 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1968 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1969 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1970 result = DNS_R_CONTINUE;
1971 goto cleanup;
1972 }
1973
1974 INSIST(zone->db_argc >= 1);
1975
1976 rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
1977 strcmp(zone->db_argv[0], "rbt64") == 0;
1978
1979 if (zone->db != NULL && zone->masterfile == NULL && rbt) {
1980 /*
1981 * The zone has no master file configured.
1982 */
1983 result = ISC_R_SUCCESS;
1984 goto cleanup;
1985 }
1986
1987 if (zone->db != NULL && dns_zone_isdynamic(zone, false)) {
1988 /*
1989 * This is a slave, stub, or dynamically updated
1990 * zone being reloaded. Do nothing - the database
1991 * we already have is guaranteed to be up-to-date.
1992 */
1993 if (zone->type == dns_zone_master && !hasraw)
1994 result = DNS_R_DYNAMIC;
1995 else
1996 result = ISC_R_SUCCESS;
1997 goto cleanup;
1998 }
1999
2000 /*
2001 * Store the current time before the zone is loaded, so that if the
2002 * file changes between the time of the load and the time that
2003 * zone->loadtime is set, then the file will still be reloaded
2004 * the next time dns_zone_load is called.
2005 */
2006 TIME_NOW(&loadtime);
2007
2008 /*
2009 * Don't do the load if the file that stores the zone is older
2010 * than the last time the zone was loaded. If the zone has not
2011 * been loaded yet, zone->loadtime will be the epoch.
2012 */
2013 if (zone->masterfile != NULL) {
2014 isc_time_t filetime;
2015
2016 /*
2017 * The file is already loaded. If we are just doing a
2018 * "rndc reconfig", we are done.
2019 */
2020 if (!isc_time_isepoch(&zone->loadtime) &&
2021 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
2022 result = ISC_R_SUCCESS;
2023 goto cleanup;
2024 }
2025
2026 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
2027 !zone_touched(zone))
2028 {
2029 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
2030 ISC_LOG_DEBUG(1),
2031 "skipping load: master file "
2032 "older than last load");
2033 result = DNS_R_UPTODATE;
2034 goto cleanup;
2035 }
2036
2037 /*
2038 * If the file modification time is in the past
2039 * set loadtime to that value.
2040 */
2041 result = isc_file_getmodtime(zone->masterfile, &filetime);
2042 if (result == ISC_R_SUCCESS &&
2043 isc_time_compare(&loadtime, &filetime) > 0)
2044 loadtime = filetime;
2045 }
2046
2047 /*
2048 * Built in zones (with the exception of empty zones) don't need
2049 * to be reloaded.
2050 */
2051 if (zone->type == dns_zone_master &&
2052 strcmp(zone->db_argv[0], "_builtin") == 0 &&
2053 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
2054 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
2055 result = ISC_R_SUCCESS;
2056 goto cleanup;
2057 }
2058
2059 /*
2060 * Zones associated with a DLZ don't need to be loaded either,
2061 * but we need to associate the database with the zone object.
2062 */
2063 if (strcmp(zone->db_argv[0], "dlz") == 0) {
2064 dns_dlzdb_t *dlzdb;
2065 dns_dlzfindzone_t findzone;
2066
2067 for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched);
2068 dlzdb != NULL;
2069 dlzdb = ISC_LIST_NEXT(dlzdb, link))
2070 {
2071 INSIST(DNS_DLZ_VALID(dlzdb));
2072 if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0)
2073 break;
2074 }
2075
2076 if (dlzdb == NULL) {
2077 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
2078 ISC_LOG_ERROR,
2079 "DLZ %s does not exist or is set "
2080 "to 'search yes;'", zone->db_argv[1]);
2081 result = ISC_R_NOTFOUND;
2082 goto cleanup;
2083 }
2084
2085 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
2086 /* ask SDLZ driver if the zone is supported */
2087 findzone = dlzdb->implementation->methods->findzone;
2088 result = (*findzone)(dlzdb->implementation->driverarg,
2089 dlzdb->dbdata, dlzdb->mctx,
2090 zone->view->rdclass, &zone->origin,
2091 NULL, NULL, &db);
2092 if (result != ISC_R_NOTFOUND) {
2093 if (zone->db != NULL)
2094 zone_detachdb(zone);
2095 zone_attachdb(zone, db);
2096 dns_db_detach(&db);
2097 result = ISC_R_SUCCESS;
2098 }
2099 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
2100
2101 if (result == ISC_R_SUCCESS) {
2102 if (dlzdb->configure_callback == NULL)
2103 goto cleanup;
2104
2105 result = (*dlzdb->configure_callback)(zone->view,
2106 dlzdb, zone);
2107 if (result != ISC_R_SUCCESS)
2108 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
2109 ISC_LOG_ERROR,
2110 "DLZ configuration callback: %s",
2111 isc_result_totext(result));
2112 }
2113 goto cleanup;
2114 }
2115
2116 if ((zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
2117 zone->type == dns_zone_stub ||
2118 (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
2119 rbt) {
2120 if (zone->masterfile == NULL ||
2121 !isc_file_exists(zone->masterfile)) {
2122 if (zone->masterfile != NULL) {
2123 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
2124 ISC_LOG_DEBUG(1),
2125 "no master file");
2126 }
2127 zone->refreshtime = now;
2128 if (zone->task != NULL)
2129 zone_settimer(zone, &now);
2130 result = ISC_R_SUCCESS;
2131 goto cleanup;
2132 }
2133 }
2134
2135 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
2136 ISC_LOG_DEBUG(1), "starting load");
2137
2138 result = dns_db_create(zone->mctx, zone->db_argv[0],
2139 &zone->origin, (zone->type == dns_zone_stub) ?
2140 dns_dbtype_stub : dns_dbtype_zone,
2141 zone->rdclass,
2142 zone->db_argc - 1, zone->db_argv + 1,
2143 &db);
2144
2145 if (result != ISC_R_SUCCESS) {
2146 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
2147 "loading zone: creating database: %s",
2148 isc_result_totext(result));
2149 goto cleanup;
2150 }
2151 dns_db_settask(db, zone->task);
2152
2153 if (zone->type == dns_zone_master || zone->type == dns_zone_slave ||
2154 zone->type == dns_zone_mirror)
2155 {
2156 result = dns_db_setgluecachestats(db, zone->gluecachestats);
2157 if (result == ISC_R_NOTIMPLEMENTED) {
2158 result = ISC_R_SUCCESS;
2159 }
2160 if (result != ISC_R_SUCCESS) {
2161 goto cleanup;
2162 }
2163 }
2164
2165 if (!dns_db_ispersistent(db)) {
2166 if (zone->masterfile != NULL) {
2167 result = zone_startload(db, zone, loadtime);
2168 } else {
2169 result = DNS_R_NOMASTERFILE;
2170 if (zone->type == dns_zone_master ||
2171 (zone->type == dns_zone_redirect &&
2172 zone->masters == NULL)) {
2173 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
2174 ISC_LOG_ERROR,
2175 "loading zone: "
2176 "no master file configured");
2177 goto cleanup;
2178 }
2179 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
2180 ISC_LOG_INFO, "loading zone: "
2181 "no master file configured: continuing");
2182 }
2183 }
2184
2185 if (result == DNS_R_CONTINUE) {
2186 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
2187 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
2188 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
2189 goto cleanup;
2190 }
2191
2192 result = zone_postload(zone, db, loadtime, result);
2193
2194 cleanup:
2195 if (hasraw)
2196 UNLOCK_ZONE(zone->raw);
2197 if (!locked)
2198 UNLOCK_ZONE(zone);
2199 if (db != NULL)
2200 dns_db_detach(&db);
2201 return (result);
2202 }
2203
2204 isc_result_t
2205 dns_zone_load(dns_zone_t *zone, bool newonly) {
2206 return (zone_load(zone, newonly ? DNS_ZONELOADFLAG_NOSTAT : 0, false));
2207 }
2208
2209 static void
2210 zone_asyncload(isc_task_t *task, isc_event_t *event) {
2211 dns_asyncload_t *asl = event->ev_arg;
2212 dns_zone_t *zone = asl->zone;
2213 isc_result_t result;
2214
2215 UNUSED(task);
2216
2217 REQUIRE(DNS_ZONE_VALID(zone));
2218
2219 isc_event_free(&event);
2220
2221 LOCK_ZONE(zone);
2222 result = zone_load(zone, asl->flags, true);
2223 if (result != DNS_R_CONTINUE) {
2224 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
2225 }
2226 UNLOCK_ZONE(zone);
2227
2228 /* Inform the zone table we've finished loading */
2229 if (asl->loaded != NULL)
2230 (asl->loaded)(asl->loaded_arg, zone, task);
2231
2232 isc_mem_put(zone->mctx, asl, sizeof (*asl));
2233 dns_zone_idetach(&zone);
2234 }
2235
2236 isc_result_t
2237 dns_zone_asyncload(dns_zone_t *zone, bool newonly,
2238 dns_zt_zoneloaded_t done, void *arg)
2239 {
2240 isc_event_t *e;
2241 dns_asyncload_t *asl = NULL;
2242 isc_result_t result = ISC_R_SUCCESS;
2243
2244 REQUIRE(DNS_ZONE_VALID(zone));
2245
2246 if (zone->zmgr == NULL)
2247 return (ISC_R_FAILURE);
2248
2249 /* If we already have a load pending, stop now */
2250 LOCK_ZONE(zone);
2251 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) {
2252 UNLOCK_ZONE(zone);
2253 return (ISC_R_ALREADYRUNNING);
2254 }
2255
2256 asl = isc_mem_get(zone->mctx, sizeof (*asl));
2257 if (asl == NULL)
2258 CHECK(ISC_R_NOMEMORY);
2259
2260 asl->zone = NULL;
2261 asl->flags = newonly ? DNS_ZONELOADFLAG_NOSTAT : 0;
2262 asl->loaded = done;
2263 asl->loaded_arg = arg;
2264
2265 e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr,
2266 DNS_EVENT_ZONELOAD,
2267 zone_asyncload, asl,
2268 sizeof(isc_event_t));
2269 if (e == NULL)
2270 CHECK(ISC_R_NOMEMORY);
2271
2272 zone_iattach(zone, &asl->zone);
2273 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING);
2274 isc_task_send(zone->loadtask, &e);
2275 UNLOCK_ZONE(zone);
2276
2277 return (ISC_R_SUCCESS);
2278
2279 failure:
2280 if (asl != NULL)
2281 isc_mem_put(zone->mctx, asl, sizeof (*asl));
2282 UNLOCK_ZONE(zone);
2283 return (result);
2284 }
2285
2286 bool
2287 dns__zone_loadpending(dns_zone_t *zone) {
2288 REQUIRE(DNS_ZONE_VALID(zone));
2289
2290 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING));
2291 }
2292
2293 isc_result_t
2294 dns_zone_loadandthaw(dns_zone_t *zone) {
2295 isc_result_t result;
2296
2297 if (inline_raw(zone))
2298 result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW,
2299 false);
2300 else
2301 result = zone_load(zone, DNS_ZONELOADFLAG_THAW, false);
2302
2303 switch (result) {
2304 case DNS_R_CONTINUE:
2305 /* Deferred thaw. */
2306 break;
2307 case DNS_R_UPTODATE:
2308 case ISC_R_SUCCESS:
2309 case DNS_R_SEENINCLUDE:
2310 zone->update_disabled = false;
2311 break;
2312 case DNS_R_NOMASTERFILE:
2313 zone->update_disabled = false;
2314 break;
2315 default:
2316 /* Error, remain in disabled state. */
2317 break;
2318 }
2319 return (result);
2320 }
2321
2322 static unsigned int
2323 get_master_options(dns_zone_t *zone) {
2324 unsigned int options;
2325
2326 options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN;
2327 if (zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
2328 (zone->type == dns_zone_redirect && zone->masters == NULL))
2329 {
2330 options |= DNS_MASTER_SLAVE;
2331 }
2332 if (zone->type == dns_zone_key) {
2333 options |= DNS_MASTER_KEY;
2334 }
2335 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) {
2336 options |= DNS_MASTER_CHECKNS;
2337 }
2338 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) {
2339 options |= DNS_MASTER_FATALNS;
2340 }
2341 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) {
2342 options |= DNS_MASTER_CHECKNAMES;
2343 }
2344 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
2345 options |= DNS_MASTER_CHECKNAMESFAIL;
2346 }
2347 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) {
2348 options |= DNS_MASTER_CHECKMX;
2349 }
2350 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) {
2351 options |= DNS_MASTER_CHECKMXFAIL;
2352 }
2353 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) {
2354 options |= DNS_MASTER_CHECKWILDCARD;
2355 }
2356 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKTTL)) {
2357 options |= DNS_MASTER_CHECKTTL;
2358 }
2359
2360 return (options);
2361 }
2362
2363 static void
2364 zone_registerinclude(const char *filename, void *arg) {
2365 isc_result_t result;
2366 dns_zone_t *zone = (dns_zone_t *) arg;
2367 dns_include_t *inc = NULL;
2368
2369 REQUIRE(DNS_ZONE_VALID(zone));
2370
2371 if (filename == NULL)
2372 return;
2373
2374 /*
2375 * Suppress duplicates.
2376 */
2377 for (inc = ISC_LIST_HEAD(zone->newincludes);
2378 inc != NULL;
2379 inc = ISC_LIST_NEXT(inc, link))
2380 if (strcmp(filename, inc->name) == 0)
2381 return;
2382
2383 inc = isc_mem_get(zone->mctx, sizeof(dns_include_t));
2384 if (inc == NULL)
2385 return;
2386 inc->name = isc_mem_strdup(zone->mctx, filename);
2387 if (inc->name == NULL) {
2388 isc_mem_put(zone->mctx, inc, sizeof(dns_include_t));
2389 return;
2390 }
2391 ISC_LINK_INIT(inc, link);
2392
2393 result = isc_file_getmodtime(filename, &inc->filetime);
2394 if (result != ISC_R_SUCCESS)
2395 isc_time_settoepoch(&inc->filetime);
2396
2397 ISC_LIST_APPEND(zone->newincludes, inc, link);
2398 }
2399
2400 static void
2401 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
2402 dns_load_t *load = event->ev_arg;
2403 isc_result_t result = ISC_R_SUCCESS;
2404 unsigned int options;
2405
2406 REQUIRE(DNS_LOAD_VALID(load));
2407
2408 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
2409 result = ISC_R_CANCELED;
2410 isc_event_free(&event);
2411 if (result == ISC_R_CANCELED)
2412 goto fail;
2413
2414 options = get_master_options(load->zone);
2415
2416 result = dns_master_loadfileinc(load->zone->masterfile,
2417 dns_db_origin(load->db),
2418 dns_db_origin(load->db),
2419 load->zone->rdclass, options, 0,
2420 &load->callbacks, task,
2421 zone_loaddone, load,
2422 &load->zone->lctx,
2423 zone_registerinclude,
2424 load->zone, load->zone->mctx,
2425 load->zone->masterformat,
2426 load->zone->maxttl);
2427 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
2428 result != DNS_R_SEENINCLUDE)
2429 goto fail;
2430 return;
2431
2432 fail:
2433 zone_loaddone(load, result);
2434 }
2435
2436 static void
2437 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
2438 isc_result_t result;
2439 unsigned int soacount;
2440
2441 LOCK(&raw->lock);
2442 if (raw->db != NULL) {
2443 result = zone_get_from_db(raw, raw->db, NULL, &soacount,
2444 &rawdata->sourceserial,
2445 NULL, NULL, NULL, NULL,
2446 NULL);
2447 if (result == ISC_R_SUCCESS && soacount > 0U)
2448 rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
2449 }
2450 UNLOCK(&raw->lock);
2451 }
2452
2453 static void
2454 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
2455 const char me[] = "zone_gotwritehandle";
2456 dns_zone_t *zone = event->ev_arg;
2457 isc_result_t result = ISC_R_SUCCESS;
2458 dns_dbversion_t *version = NULL;
2459 dns_masterrawheader_t rawdata;
2460
2461 REQUIRE(DNS_ZONE_VALID(zone));
2462 INSIST(task == zone->task);
2463 ENTER;
2464
2465 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
2466 result = ISC_R_CANCELED;
2467 isc_event_free(&event);
2468 if (result == ISC_R_CANCELED)
2469 goto fail;
2470
2471 LOCK_ZONE(zone);
2472 INSIST(zone != zone->raw);
2473 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2474 if (zone->db != NULL) {
2475 const dns_master_style_t *output_style;
2476
2477 dns_db_currentversion(zone->db, &version);
2478 dns_master_initrawheader(&rawdata);
2479 if (inline_secure(zone))
2480 get_raw_serial(zone->raw, &rawdata);
2481 if (zone->type == dns_zone_key)
2482 output_style = &dns_master_style_keyzone;
2483 else if (zone->masterstyle != NULL)
2484 output_style = zone->masterstyle;
2485 else
2486 output_style = &dns_master_style_default;
2487 result = dns_master_dumpinc(zone->mctx, zone->db, version,
2488 output_style, zone->masterfile,
2489 zone->task, dump_done, zone,
2490 &zone->dctx, zone->masterformat,
2491 &rawdata);
2492 dns_db_closeversion(zone->db, &version, false);
2493 } else
2494 result = ISC_R_CANCELED;
2495 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2496 UNLOCK_ZONE(zone);
2497 if (result != DNS_R_CONTINUE)
2498 goto fail;
2499 return;
2500
2501 fail:
2502 dump_done(zone, result);
2503 }
2504
2505 /*
2506 * Save the raw serial number for inline-signing zones.
2507 * (XXX: Other information from the header will be used
2508 * for other purposes in the future, but for now this is
2509 * all we're interested in.)
2510 */
2511 static void
2512 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
2513 if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0)
2514 return;
2515
2516 zone->sourceserial = header->sourceserial;
2517 zone->sourceserialset = true;
2518 }
2519
2520 void
2521 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
2522 if (zone == NULL)
2523 return;
2524
2525 LOCK_ZONE(zone);
2526 zone_setrawdata(zone, header);
2527 UNLOCK_ZONE(zone);
2528 }
2529
2530 static isc_result_t
2531 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
2532 const char me[] = "zone_startload";
2533 dns_load_t *load;
2534 isc_result_t result;
2535 isc_result_t tresult;
2536 unsigned int options;
2537
2538 ENTER;
2539
2540 dns_zone_rpz_enable_db(zone, db);
2541 dns_zone_catz_enable_db(zone, db);
2542
2543 options = get_master_options(zone);
2544 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) {
2545 options |= DNS_MASTER_MANYERRORS;
2546 }
2547
2548 if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) {
2549 load = isc_mem_get(zone->mctx, sizeof(*load));
2550 if (load == NULL)
2551 return (ISC_R_NOMEMORY);
2552
2553 load->mctx = NULL;
2554 load->zone = NULL;
2555 load->db = NULL;
2556 load->loadtime = loadtime;
2557 load->magic = LOAD_MAGIC;
2558
2559 isc_mem_attach(zone->mctx, &load->mctx);
2560 zone_iattach(zone, &load->zone);
2561 dns_db_attach(db, &load->db);
2562 dns_rdatacallbacks_init(&load->callbacks);
2563 load->callbacks.rawdata = zone_setrawdata;
2564 zone_iattach(zone, &load->callbacks.zone);
2565 result = dns_db_beginload(db, &load->callbacks);
2566 if (result != ISC_R_SUCCESS) {
2567 goto cleanup;
2568 }
2569 result = zonemgr_getio(zone->zmgr, true, zone->loadtask,
2570 zone_gotreadhandle, load,
2571 &zone->readio);
2572 if (result != ISC_R_SUCCESS) {
2573 /*
2574 * We can't report multiple errors so ignore
2575 * the result of dns_db_endload().
2576 */
2577 (void)dns_db_endload(load->db, &load->callbacks);
2578 goto cleanup;
2579 } else {
2580 result = DNS_R_CONTINUE;
2581 }
2582 } else {
2583 dns_rdatacallbacks_t callbacks;
2584
2585 dns_rdatacallbacks_init(&callbacks);
2586 callbacks.rawdata = zone_setrawdata;
2587 zone_iattach(zone, &callbacks.zone);
2588 result = dns_db_beginload(db, &callbacks);
2589 if (result != ISC_R_SUCCESS) {
2590 zone_idetach(&callbacks.zone);
2591 return (result);
2592 }
2593 result = dns_master_loadfile(zone->masterfile,
2594 &zone->origin, &zone->origin,
2595 zone->rdclass, options, 0,
2596 &callbacks,
2597 zone_registerinclude,
2598 zone, zone->mctx,
2599 zone->masterformat,
2600 zone->maxttl);
2601 tresult = dns_db_endload(db, &callbacks);
2602 if (result == ISC_R_SUCCESS) {
2603 result = tresult;
2604 }
2605 zone_idetach(&callbacks.zone);
2606 }
2607
2608 return (result);
2609
2610 cleanup:
2611 load->magic = 0;
2612 dns_db_detach(&load->db);
2613 zone_idetach(&load->zone);
2614 zone_idetach(&load->callbacks.zone);
2615 isc_mem_detach(&load->mctx);
2616 isc_mem_put(zone->mctx, load, sizeof(*load));
2617 return (result);
2618 }
2619
2620 static bool
2621 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2622 dns_name_t *owner)
2623 {
2624 isc_result_t result;
2625 char ownerbuf[DNS_NAME_FORMATSIZE];
2626 char namebuf[DNS_NAME_FORMATSIZE];
2627 char altbuf[DNS_NAME_FORMATSIZE];
2628 dns_fixedname_t fixed;
2629 dns_name_t *foundname;
2630 int level;
2631
2632 /*
2633 * "." means the services does not exist.
2634 */
2635 if (dns_name_equal(name, dns_rootname))
2636 return (true);
2637
2638 /*
2639 * Outside of zone.
2640 */
2641 if (!dns_name_issubdomain(name, &zone->origin)) {
2642 if (zone->checkmx != NULL)
2643 return ((zone->checkmx)(zone, name, owner));
2644 return (true);
2645 }
2646
2647 if (zone->type == dns_zone_master)
2648 level = ISC_LOG_ERROR;
2649 else
2650 level = ISC_LOG_WARNING;
2651
2652 foundname = dns_fixedname_initname(&fixed);
2653
2654 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2655 0, 0, NULL, foundname, NULL, NULL);
2656 if (result == ISC_R_SUCCESS)
2657 return (true);
2658
2659 if (result == DNS_R_NXRRSET) {
2660 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2661 0, 0, NULL, foundname, NULL, NULL);
2662 if (result == ISC_R_SUCCESS)
2663 return (true);
2664 }
2665
2666 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2667 dns_name_format(name, namebuf, sizeof namebuf);
2668 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2669 result == DNS_R_EMPTYNAME) {
2670 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
2671 level = ISC_LOG_WARNING;
2672 dns_zone_log(zone, level,
2673 "%s/MX '%s' has no address records (A or AAAA)",
2674 ownerbuf, namebuf);
2675 return ((level == ISC_LOG_WARNING) ? true : false);
2676 }
2677
2678 if (result == DNS_R_CNAME) {
2679 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
2680 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2681 level = ISC_LOG_WARNING;
2682 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2683 dns_zone_log(zone, level,
2684 "%s/MX '%s' is a CNAME (illegal)",
2685 ownerbuf, namebuf);
2686 return ((level == ISC_LOG_WARNING) ? true : false);
2687 }
2688
2689 if (result == DNS_R_DNAME) {
2690 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
2691 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
2692 level = ISC_LOG_WARNING;
2693 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
2694 dns_name_format(foundname, altbuf, sizeof altbuf);
2695 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
2696 " '%s' (illegal)", ownerbuf, namebuf,
2697 altbuf);
2698 }
2699 return ((level == ISC_LOG_WARNING) ? true : false);
2700 }
2701
2702 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
2703 return ((zone->checkmx)(zone, name, owner));
2704
2705 return (true);
2706 }
2707
2708 static bool
2709 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2710 dns_name_t *owner)
2711 {
2712 isc_result_t result;
2713 char ownerbuf[DNS_NAME_FORMATSIZE];
2714 char namebuf[DNS_NAME_FORMATSIZE];
2715 char altbuf[DNS_NAME_FORMATSIZE];
2716 dns_fixedname_t fixed;
2717 dns_name_t *foundname;
2718 int level;
2719
2720 /*
2721 * "." means the services does not exist.
2722 */
2723 if (dns_name_equal(name, dns_rootname))
2724 return (true);
2725
2726 /*
2727 * Outside of zone.
2728 */
2729 if (!dns_name_issubdomain(name, &zone->origin)) {
2730 if (zone->checksrv != NULL)
2731 return ((zone->checksrv)(zone, name, owner));
2732 return (true);
2733 }
2734
2735 if (zone->type == dns_zone_master)
2736 level = ISC_LOG_ERROR;
2737 else
2738 level = ISC_LOG_WARNING;
2739
2740 foundname = dns_fixedname_initname(&fixed);
2741
2742 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2743 0, 0, NULL, foundname, NULL, NULL);
2744 if (result == ISC_R_SUCCESS)
2745 return (true);
2746
2747 if (result == DNS_R_NXRRSET) {
2748 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2749 0, 0, NULL, foundname, NULL, NULL);
2750 if (result == ISC_R_SUCCESS)
2751 return (true);
2752 }
2753
2754 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2755 dns_name_format(name, namebuf, sizeof namebuf);
2756 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2757 result == DNS_R_EMPTYNAME) {
2758 dns_zone_log(zone, level,
2759 "%s/SRV '%s' has no address records (A or AAAA)",
2760 ownerbuf, namebuf);
2761 /* XXX950 make fatal for 9.5.0. */
2762 return (true);
2763 }
2764
2765 if (result == DNS_R_CNAME) {
2766 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
2767 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2768 level = ISC_LOG_WARNING;
2769 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2770 dns_zone_log(zone, level,
2771 "%s/SRV '%s' is a CNAME (illegal)",
2772 ownerbuf, namebuf);
2773 return ((level == ISC_LOG_WARNING) ? true : false);
2774 }
2775
2776 if (result == DNS_R_DNAME) {
2777 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
2778 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
2779 level = ISC_LOG_WARNING;
2780 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
2781 dns_name_format(foundname, altbuf, sizeof altbuf);
2782 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
2783 "DNAME '%s' (illegal)", ownerbuf, namebuf,
2784 altbuf);
2785 }
2786 return ((level == ISC_LOG_WARNING) ? true : false);
2787 }
2788
2789 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
2790 return ((zone->checksrv)(zone, name, owner));
2791
2792 return (true);
2793 }
2794
2795 static bool
2796 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2797 dns_name_t *owner)
2798 {
2799 bool answer = true;
2800 isc_result_t result, tresult;
2801 char ownerbuf[DNS_NAME_FORMATSIZE];
2802 char namebuf[DNS_NAME_FORMATSIZE];
2803 char altbuf[DNS_NAME_FORMATSIZE];
2804 dns_fixedname_t fixed;
2805 dns_name_t *foundname;
2806 dns_rdataset_t a;
2807 dns_rdataset_t aaaa;
2808 int level;
2809
2810 /*
2811 * Outside of zone.
2812 */
2813 if (!dns_name_issubdomain(name, &zone->origin)) {
2814 if (zone->checkns != NULL)
2815 return ((zone->checkns)(zone, name, owner, NULL, NULL));
2816 return (true);
2817 }
2818
2819 if (zone->type == dns_zone_master)
2820 level = ISC_LOG_ERROR;
2821 else
2822 level = ISC_LOG_WARNING;
2823
2824 foundname = dns_fixedname_initname(&fixed);
2825 dns_rdataset_init(&a);
2826 dns_rdataset_init(&aaaa);
2827
2828 /*
2829 * Perform a regular lookup to catch DNAME records then look
2830 * for glue.
2831 */
2832 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2833 0, 0, NULL, foundname, &a, NULL);
2834 switch (result) {
2835 case ISC_R_SUCCESS:
2836 case DNS_R_DNAME:
2837 case DNS_R_CNAME:
2838 break;
2839 default:
2840 if (dns_rdataset_isassociated(&a))
2841 dns_rdataset_disassociate(&a);
2842 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2843 DNS_DBFIND_GLUEOK, 0, NULL,
2844 foundname, &a, NULL);
2845 }
2846 if (result == ISC_R_SUCCESS) {
2847 dns_rdataset_disassociate(&a);
2848 return (true);
2849 } else if (result == DNS_R_DELEGATION)
2850 dns_rdataset_disassociate(&a);
2851
2852 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
2853 result == DNS_R_GLUE) {
2854 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2855 DNS_DBFIND_GLUEOK, 0, NULL,
2856 foundname, &aaaa, NULL);
2857 if (tresult == ISC_R_SUCCESS) {
2858 if (dns_rdataset_isassociated(&a))
2859 dns_rdataset_disassociate(&a);
2860 dns_rdataset_disassociate(&aaaa);
2861 return (true);
2862 }
2863 if (tresult == DNS_R_DELEGATION || tresult == DNS_R_DNAME)
2864 dns_rdataset_disassociate(&aaaa);
2865 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
2866 /*
2867 * Check glue against child zone.
2868 */
2869 if (zone->checkns != NULL)
2870 answer = (zone->checkns)(zone, name, owner,
2871 &a, &aaaa);
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
2880 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2881 dns_name_format(name, namebuf, sizeof namebuf);
2882 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2883 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
2884 const char *what;
2885 bool required = false;
2886 if (dns_name_issubdomain(name, owner)) {
2887 what = "REQUIRED GLUE ";
2888 required = true;
2889 } else if (result == DNS_R_DELEGATION)
2890 what = "SIBLING GLUE ";
2891 else
2892 what = "";
2893
2894 if (result != DNS_R_DELEGATION || required ||
2895 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
2896 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
2897 "address records (A or AAAA)",
2898 ownerbuf, namebuf, what);
2899 /*
2900 * Log missing address record.
2901 */
2902 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
2903 (void)(zone->checkns)(zone, name, owner,
2904 &a, &aaaa);
2905 /* XXX950 make fatal for 9.5.0. */
2906 /* answer = false; */
2907 }
2908 } else if (result == DNS_R_CNAME) {
2909 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
2910 ownerbuf, namebuf);
2911 /* XXX950 make fatal for 9.5.0. */
2912 /* answer = false; */
2913 } else if (result == DNS_R_DNAME) {
2914 dns_name_format(foundname, altbuf, sizeof altbuf);
2915 dns_zone_log(zone, level,
2916 "%s/NS '%s' is below a DNAME '%s' (illegal)",
2917 ownerbuf, namebuf, altbuf);
2918 /* XXX950 make fatal for 9.5.0. */
2919 /* answer = false; */
2920 }
2921
2922 if (dns_rdataset_isassociated(&a))
2923 dns_rdataset_disassociate(&a);
2924 if (dns_rdataset_isassociated(&aaaa))
2925 dns_rdataset_disassociate(&aaaa);
2926 return (answer);
2927 }
2928
2929 static bool
2930 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
2931 dns_rdataset_t *rdataset)
2932 {
2933 dns_rdataset_t tmprdataset;
2934 isc_result_t result;
2935 bool answer = true;
2936 bool format = true;
2937 int level = ISC_LOG_WARNING;
2938 char ownerbuf[DNS_NAME_FORMATSIZE];
2939 char typebuf[DNS_RDATATYPE_FORMATSIZE];
2940 unsigned int count1 = 0;
2941
2942 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL))
2943 level = ISC_LOG_ERROR;
2944
2945 dns_rdataset_init(&tmprdataset);
2946 for (result = dns_rdataset_first(rdataset);
2947 result == ISC_R_SUCCESS;
2948 result = dns_rdataset_next(rdataset)) {
2949 dns_rdata_t rdata1 = DNS_RDATA_INIT;
2950 unsigned int count2 = 0;
2951
2952 count1++;
2953 dns_rdataset_current(rdataset, &rdata1);
2954 dns_rdataset_clone(rdataset, &tmprdataset);
2955 for (result = dns_rdataset_first(&tmprdataset);
2956 result == ISC_R_SUCCESS;
2957 result = dns_rdataset_next(&tmprdataset)) {
2958 dns_rdata_t rdata2 = DNS_RDATA_INIT;
2959 count2++;
2960 if (count1 >= count2)
2961 continue;
2962 dns_rdataset_current(&tmprdataset, &rdata2);
2963 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
2964 if (format) {
2965 dns_name_format(owner, ownerbuf,
2966 sizeof ownerbuf);
2967 dns_rdatatype_format(rdata1.type,
2968 typebuf,
2969 sizeof(typebuf));
2970 format = false;
2971 }
2972 dns_zone_log(zone, level, "%s/%s has "
2973 "semantically identical records",
2974 ownerbuf, typebuf);
2975 if (level == ISC_LOG_ERROR)
2976 answer = false;
2977 break;
2978 }
2979 }
2980 dns_rdataset_disassociate(&tmprdataset);
2981 if (!format)
2982 break;
2983 }
2984 return (answer);
2985 }
2986
2987 static bool
2988 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
2989 dns_dbiterator_t *dbiterator = NULL;
2990 dns_dbnode_t *node = NULL;
2991 dns_fixedname_t fixed;
2992 dns_name_t *name;
2993 dns_rdataset_t rdataset;
2994 dns_rdatasetiter_t *rdsit = NULL;
2995 bool ok = true;
2996 isc_result_t result;
2997
2998 name = dns_fixedname_initname(&fixed);
2999 dns_rdataset_init(&rdataset);
3000
3001 result = dns_db_createiterator(db, 0, &dbiterator);
3002 if (result != ISC_R_SUCCESS)
3003 return (true);
3004
3005 for (result = dns_dbiterator_first(dbiterator);
3006 result == ISC_R_SUCCESS;
3007 result = dns_dbiterator_next(dbiterator)) {
3008 result = dns_dbiterator_current(dbiterator, &node, name);
3009 if (result != ISC_R_SUCCESS)
3010 continue;
3011
3012 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
3013 if (result != ISC_R_SUCCESS)
3014 continue;
3015
3016 for (result = dns_rdatasetiter_first(rdsit);
3017 result == ISC_R_SUCCESS;
3018 result = dns_rdatasetiter_next(rdsit)) {
3019 dns_rdatasetiter_current(rdsit, &rdataset);
3020 if (!zone_rrset_check_dup(zone, name, &rdataset))
3021 ok = false;
3022 dns_rdataset_disassociate(&rdataset);
3023 }
3024 dns_rdatasetiter_destroy(&rdsit);
3025 dns_db_detachnode(db, &node);
3026 }
3027
3028 if (node != NULL)
3029 dns_db_detachnode(db, &node);
3030 dns_dbiterator_destroy(&dbiterator);
3031
3032 return (ok);
3033 }
3034
3035 static bool
3036 isspf(const dns_rdata_t *rdata) {
3037 char buf[1024];
3038 const unsigned char *data = rdata->data;
3039 unsigned int rdl = rdata->length, i = 0, tl, len;
3040
3041 while (rdl > 0U) {
3042 len = tl = *data;
3043 ++data;
3044 --rdl;
3045 INSIST(tl <= rdl);
3046 if (len > sizeof(buf) - i - 1)
3047 len = sizeof(buf) - i - 1;
3048 memmove(buf + i, data, len);
3049 i += len;
3050 data += tl;
3051 rdl -= tl;
3052 }
3053
3054 if (i < 6U)
3055 return(false);
3056
3057 buf[i] = 0;
3058 if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' '))
3059 return (true);
3060 return (false);
3061 }
3062
3063 static bool
3064 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
3065 dns_dbiterator_t *dbiterator = NULL;
3066 dns_dbnode_t *node = NULL;
3067 dns_rdataset_t rdataset;
3068 dns_fixedname_t fixed;
3069 dns_fixedname_t fixedbottom;
3070 dns_rdata_mx_t mx;
3071 dns_rdata_ns_t ns;
3072 dns_rdata_in_srv_t srv;
3073 dns_rdata_t rdata;
3074 dns_name_t *name;
3075 dns_name_t *bottom;
3076 isc_result_t result;
3077 bool ok = true, have_spf, have_txt;
3078
3079 name = dns_fixedname_initname(&fixed);
3080 bottom = dns_fixedname_initname(&fixedbottom);
3081 dns_rdataset_init(&rdataset);
3082 dns_rdata_init(&rdata);
3083
3084 result = dns_db_createiterator(db, 0, &dbiterator);
3085 if (result != ISC_R_SUCCESS)
3086 return (true);
3087
3088 result = dns_dbiterator_first(dbiterator);
3089 while (result == ISC_R_SUCCESS) {
3090 result = dns_dbiterator_current(dbiterator, &node, name);
3091 if (result != ISC_R_SUCCESS)
3092 goto cleanup;
3093
3094 /*
3095 * Is this name visible in the zone?
3096 */
3097 if (!dns_name_issubdomain(name, &zone->origin) ||
3098 (dns_name_countlabels(bottom) > 0 &&
3099 dns_name_issubdomain(name, bottom)))
3100 goto next;
3101
3102 /*
3103 * Don't check the NS records at the origin.
3104 */
3105 if (dns_name_equal(name, &zone->origin))
3106 goto checkfordname;
3107
3108 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
3109 0, 0, &rdataset, NULL);
3110 if (result != ISC_R_SUCCESS)
3111 goto checkfordname;
3112 /*
3113 * Remember bottom of zone due to NS.
3114 */
3115 dns_name_copy(name, bottom, NULL);
3116
3117 result = dns_rdataset_first(&rdataset);
3118 while (result == ISC_R_SUCCESS) {
3119 dns_rdataset_current(&rdataset, &rdata);
3120 result = dns_rdata_tostruct(&rdata, &ns, NULL);
3121 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3122 if (!zone_check_glue(zone, db, &ns.name, name))
3123 ok = false;
3124 dns_rdata_reset(&rdata);
3125 result = dns_rdataset_next(&rdataset);
3126 }
3127 dns_rdataset_disassociate(&rdataset);
3128 goto next;
3129
3130 checkfordname:
3131 result = dns_db_findrdataset(db, node, NULL,
3132 dns_rdatatype_dname, 0, 0,
3133 &rdataset, NULL);
3134 if (result == ISC_R_SUCCESS) {
3135 /*
3136 * Remember bottom of zone due to DNAME.
3137 */
3138 dns_name_copy(name, bottom, NULL);
3139 dns_rdataset_disassociate(&rdataset);
3140 }
3141
3142 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
3143 0, 0, &rdataset, NULL);
3144 if (result != ISC_R_SUCCESS)
3145 goto checksrv;
3146 result = dns_rdataset_first(&rdataset);
3147 while (result == ISC_R_SUCCESS) {
3148 dns_rdataset_current(&rdataset, &rdata);
3149 result = dns_rdata_tostruct(&rdata, &mx, NULL);
3150 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3151 if (!zone_check_mx(zone, db, &mx.mx, name))
3152 ok = false;
3153 dns_rdata_reset(&rdata);
3154 result = dns_rdataset_next(&rdataset);
3155 }
3156 dns_rdataset_disassociate(&rdataset);
3157
3158 checksrv:
3159 if (zone->rdclass != dns_rdataclass_in)
3160 goto next;
3161 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
3162 0, 0, &rdataset, NULL);
3163 if (result != ISC_R_SUCCESS)
3164 goto checkspf;
3165 result = dns_rdataset_first(&rdataset);
3166 while (result == ISC_R_SUCCESS) {
3167 dns_rdataset_current(&rdataset, &rdata);
3168 result = dns_rdata_tostruct(&rdata, &srv, NULL);
3169 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3170 if (!zone_check_srv(zone, db, &srv.target, name))
3171 ok = false;
3172 dns_rdata_reset(&rdata);
3173 result = dns_rdataset_next(&rdataset);
3174 }
3175 dns_rdataset_disassociate(&rdataset);
3176
3177 checkspf:
3178 /*
3179 * Check if there is a type SPF record without an
3180 * SPF-formatted type TXT record also being present.
3181 */
3182 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF))
3183 goto next;
3184 if (zone->rdclass != dns_rdataclass_in)
3185 goto next;
3186 have_spf = have_txt = false;
3187 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
3188 0, 0, &rdataset, NULL);
3189 if (result == ISC_R_SUCCESS) {
3190 dns_rdataset_disassociate(&rdataset);
3191 have_spf = true;
3192 }
3193 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
3194 0, 0, &rdataset, NULL);
3195 if (result != ISC_R_SUCCESS)
3196 goto notxt;
3197 result = dns_rdataset_first(&rdataset);
3198 while (result == ISC_R_SUCCESS) {
3199 dns_rdataset_current(&rdataset, &rdata);
3200 have_txt = isspf(&rdata);
3201 dns_rdata_reset(&rdata);
3202 if (have_txt)
3203 break;
3204 result = dns_rdataset_next(&rdataset);
3205 }
3206 dns_rdataset_disassociate(&rdataset);
3207
3208 notxt:
3209 if (have_spf && !have_txt) {
3210 char namebuf[DNS_NAME_FORMATSIZE];
3211
3212 dns_name_format(name, namebuf, sizeof(namebuf));
3213 dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found type "
3214 "SPF record but no SPF TXT record found, "
3215 "add matching type TXT record", namebuf);
3216 }
3217
3218 next:
3219 dns_db_detachnode(db, &node);
3220 result = dns_dbiterator_next(dbiterator);
3221 }
3222
3223 cleanup:
3224 if (node != NULL)
3225 dns_db_detachnode(db, &node);
3226 dns_dbiterator_destroy(&dbiterator);
3227
3228 return (ok);
3229 }
3230
3231 /*
3232 * OpenSSL verification of RSA keys with exponent 3 is known to be
3233 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
3234 * if they are in use.
3235 */
3236 static void
3237 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
3238 dns_dbnode_t *node = NULL;
3239 dns_dbversion_t *version = NULL;
3240 dns_rdata_dnskey_t dnskey;
3241 dns_rdata_t rdata = DNS_RDATA_INIT;
3242 dns_rdataset_t rdataset;
3243 isc_result_t result;
3244 bool logit, foundrsa = false;
3245 const char *algorithm;
3246
3247 result = dns_db_findnode(db, &zone->origin, false, &node);
3248 if (result != ISC_R_SUCCESS) {
3249 goto cleanup;
3250 }
3251
3252 dns_db_currentversion(db, &version);
3253 dns_rdataset_init(&rdataset);
3254 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
3255 dns_rdatatype_none, 0, &rdataset, NULL);
3256 if (result != ISC_R_SUCCESS) {
3257 goto cleanup;
3258 }
3259
3260 for (result = dns_rdataset_first(&rdataset);
3261 result == ISC_R_SUCCESS;
3262 result = dns_rdataset_next(&rdataset))
3263 {
3264 dns_rdataset_current(&rdataset, &rdata);
3265 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
3266 INSIST(result == ISC_R_SUCCESS);
3267
3268 /* RFC 3110, section 4: Performance Considerations:
3269 *
3270 * A public exponent of 3 minimizes the effort needed to verify
3271 * a signature. Use of 3 as the public exponent is weak for
3272 * confidentiality uses since, if the same data can be collected
3273 * encrypted under three different keys with an exponent of 3
3274 * then, using the Chinese Remainder Theorem [NETSEC], the
3275 * original plain text can be easily recovered. If a key is
3276 * known to be used only for authentication, as is the case with
3277 * DNSSEC, then an exponent of 3 is acceptable. However other
3278 * applications in the future may wish to leverage DNS
3279 * distributed keys for applications that do require
3280 * confidentiality. For keys which might have such other uses,
3281 * a more conservative choice would be 65537 (F4, the fourth
3282 * fermat number).
3283 */
3284 if (dnskey.algorithm == DST_ALG_RSASHA1 &&
3285 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
3286 dnskey.data[1] == 3)
3287 {
3288 if (dnskey.algorithm == DST_ALG_RSASHA1) {
3289 logit = !foundrsa;
3290 foundrsa = true;
3291 algorithm = "RSASHA1";
3292 }
3293 if (logit) {
3294 dnssec_log(zone, ISC_LOG_WARNING,
3295 "weak %s (%u) key found "
3296 "(exponent=3)", algorithm,
3297 dnskey.algorithm);
3298 }
3299 }
3300 dns_rdata_reset(&rdata);
3301 }
3302 dns_rdataset_disassociate(&rdataset);
3303
3304 cleanup:
3305 if (node != NULL) {
3306 dns_db_detachnode(db, &node);
3307 }
3308 if (version != NULL) {
3309 dns_db_closeversion(db, &version, false);
3310 }
3311 }
3312
3313 static void
3314 resume_signingwithkey(dns_zone_t *zone) {
3315 dns_dbnode_t *node = NULL;
3316 dns_dbversion_t *version = NULL;
3317 dns_rdata_t rdata = DNS_RDATA_INIT;
3318 dns_rdataset_t rdataset;
3319 isc_result_t result;
3320 dns_db_t *db = NULL;
3321
3322 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3323 if (zone->db != NULL) {
3324 dns_db_attach(zone->db, &db);
3325 }
3326 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3327 if (db == NULL) {
3328 goto cleanup;
3329 }
3330
3331 result = dns_db_findnode(db, &zone->origin, false, &node);
3332 if (result != ISC_R_SUCCESS) {
3333 goto cleanup;
3334 }
3335
3336 dns_db_currentversion(db, &version);
3337 dns_rdataset_init(&rdataset);
3338 result = dns_db_findrdataset(db, node, version,
3339 zone->privatetype,
3340 dns_rdatatype_none, 0,
3341 &rdataset, NULL);
3342 if (result != ISC_R_SUCCESS) {
3343 INSIST(!dns_rdataset_isassociated(&rdataset));
3344 goto cleanup;
3345 }
3346
3347 for (result = dns_rdataset_first(&rdataset);
3348 result == ISC_R_SUCCESS;
3349 result = dns_rdataset_next(&rdataset))
3350 {
3351 dns_rdataset_current(&rdataset, &rdata);
3352 if (rdata.length != 5 ||
3353 rdata.data[0] == 0 || rdata.data[4] != 0)
3354 {
3355 dns_rdata_reset(&rdata);
3356 continue;
3357 }
3358
3359 result = zone_signwithkey(zone, rdata.data[0],
3360 (rdata.data[1] << 8) | rdata.data[2],
3361 rdata.data[3]);
3362 if (result != ISC_R_SUCCESS) {
3363 dnssec_log(zone, ISC_LOG_ERROR,
3364 "zone_signwithkey failed: %s",
3365 dns_result_totext(result));
3366 }
3367 dns_rdata_reset(&rdata);
3368 }
3369 dns_rdataset_disassociate(&rdataset);
3370
3371 cleanup:
3372 if (db != NULL) {
3373 if (node != NULL) {
3374 dns_db_detachnode(db, &node);
3375 }
3376 if (version != NULL) {
3377 dns_db_closeversion(db, &version, false);
3378 }
3379 dns_db_detach(&db);
3380 }
3381 }
3382
3383 /*
3384 * Initiate adding/removing NSEC3 records belonging to the chain defined by the
3385 * supplied NSEC3PARAM RDATA.
3386 *
3387 * Zone must be locked by caller.
3388 */
3389 static isc_result_t
3390 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
3391 dns_nsec3chain_t *nsec3chain, *current;
3392 dns_dbversion_t *version = NULL;
3393 bool nseconly = false, nsec3ok = false;
3394 isc_result_t result;
3395 isc_time_t now;
3396 unsigned int options = 0;
3397 char saltbuf[255*2+1];
3398 char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
3399 dns_db_t *db = NULL;
3400
3401 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3402 if (zone->db != NULL) {
3403 dns_db_attach(zone->db, &db);
3404 }
3405 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3406
3407 if (db == NULL) {
3408 result = ISC_R_SUCCESS;
3409 goto cleanup;
3410 }
3411
3412 /*
3413 * If this zone is not NSEC3-capable, attempting to remove any NSEC3
3414 * chain from it is pointless as it would not be possible for the
3415 * latter to exist in the first place.
3416 */
3417 dns_db_currentversion(db, &version);
3418 result = dns_nsec_nseconly(db, version, &nseconly);
3419 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
3420 dns_db_closeversion(db, &version, false);
3421 if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) {
3422 result = ISC_R_SUCCESS;
3423 goto cleanup;
3424 }
3425
3426 /*
3427 * Allocate and initialize structure preserving state of
3428 * adding/removing records belonging to this NSEC3 chain between
3429 * separate zone_nsec3chain() calls.
3430 */
3431 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
3432 if (nsec3chain == NULL) {
3433 result = ISC_R_NOMEMORY;
3434 goto cleanup;
3435 }
3436
3437 nsec3chain->magic = 0;
3438 nsec3chain->done = false;
3439 nsec3chain->db = NULL;
3440 nsec3chain->dbiterator = NULL;
3441 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
3442 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
3443 nsec3chain->nsec3param.hash = nsec3param->hash;
3444 nsec3chain->nsec3param.iterations = nsec3param->iterations;
3445 nsec3chain->nsec3param.flags = nsec3param->flags;
3446 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
3447 memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
3448 nsec3chain->nsec3param.salt = nsec3chain->salt;
3449 nsec3chain->seen_nsec = false;
3450 nsec3chain->delete_nsec = false;
3451 nsec3chain->save_delete_nsec = false;
3452
3453 /*
3454 * Log NSEC3 parameters defined by supplied NSEC3PARAM RDATA.
3455 */
3456 if (nsec3param->flags == 0) {
3457 strlcpy(flags, "NONE", sizeof(flags));
3458 } else {
3459 flags[0] = '\0';
3460 if ((nsec3param->flags & DNS_NSEC3FLAG_REMOVE) != 0) {
3461 strlcat(flags, "REMOVE", sizeof(flags));
3462 }
3463 if ((nsec3param->flags & DNS_NSEC3FLAG_INITIAL) != 0) {
3464 if (flags[0] == '\0') {
3465 strlcpy(flags, "INITIAL", sizeof(flags));
3466 } else {
3467 strlcat(flags, "|INITIAL", sizeof(flags));
3468 }
3469 }
3470 if ((nsec3param->flags & DNS_NSEC3FLAG_CREATE) != 0) {
3471 if (flags[0] == '\0') {
3472 strlcpy(flags, "CREATE", sizeof(flags));
3473 } else {
3474 strlcat(flags, "|CREATE", sizeof(flags));
3475 }
3476 }
3477 if ((nsec3param->flags & DNS_NSEC3FLAG_NONSEC) != 0) {
3478 if (flags[0] == '\0') {
3479 strlcpy(flags, "NONSEC", sizeof(flags));
3480 } else {
3481 strlcat(flags, "|NONSEC", sizeof(flags));
3482 }
3483 }
3484 if ((nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) != 0) {
3485 if (flags[0] == '\0') {
3486 strlcpy(flags, "OPTOUT", sizeof(flags));
3487 } else {
3488 strlcat(flags, "|OPTOUT", sizeof(flags));
3489 }
3490 }
3491 }
3492 result = dns_nsec3param_salttotext(nsec3param, saltbuf,
3493 sizeof(saltbuf));
3494 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3495 dnssec_log(zone, ISC_LOG_INFO, "zone_addnsec3chain(%u,%s,%u,%s)",
3496 nsec3param->hash, flags, nsec3param->iterations, saltbuf);
3497
3498 /*
3499 * If the NSEC3 chain defined by the supplied NSEC3PARAM RDATA is
3500 * currently being processed, interrupt its processing to avoid
3501 * simultaneously adding and removing records for the same NSEC3 chain.
3502 */
3503 for (current = ISC_LIST_HEAD(zone->nsec3chain);
3504 current != NULL;
3505 current = ISC_LIST_NEXT(current, link))
3506 {
3507 if ((current->db == db) &&
3508 (current->nsec3param.hash == nsec3param->hash) &&
3509 (current->nsec3param.iterations ==
3510 nsec3param->iterations) &&
3511 (current->nsec3param.salt_length ==
3512 nsec3param->salt_length) &&
3513 memcmp(current->nsec3param.salt, nsec3param->salt,
3514 nsec3param->salt_length) == 0)
3515 {
3516 current->done = true;
3517 }
3518 }
3519
3520 /*
3521 * Attach zone database to the structure initialized above and create
3522 * an iterator for it with appropriate options in order to avoid
3523 * creating NSEC3 records for NSEC3 records.
3524 */
3525 dns_db_attach(db, &nsec3chain->db);
3526 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) {
3527 options = DNS_DB_NONSEC3;
3528 }
3529 result = dns_db_createiterator(nsec3chain->db, options,
3530 &nsec3chain->dbiterator);
3531 if (result == ISC_R_SUCCESS) {
3532 result = dns_dbiterator_first(nsec3chain->dbiterator);
3533 }
3534 if (result == ISC_R_SUCCESS) {
3535 /*
3536 * Database iterator initialization succeeded. We are now
3537 * ready to kick off adding/removing records belonging to this
3538 * NSEC3 chain. Append the structure initialized above to the
3539 * "nsec3chain" list for the zone and set the appropriate zone
3540 * timer so that zone_nsec3chain() is called as soon as
3541 * possible.
3542 */
3543 dns_dbiterator_pause(nsec3chain->dbiterator);
3544 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
3545 nsec3chain, link);
3546 nsec3chain = NULL;
3547 if (isc_time_isepoch(&zone->nsec3chaintime)) {
3548 TIME_NOW(&now);
3549 zone->nsec3chaintime = now;
3550 if (zone->task != NULL) {
3551 zone_settimer(zone, &now);
3552 }
3553 }
3554 }
3555
3556 if (nsec3chain != NULL) {
3557 if (nsec3chain->db != NULL) {
3558 dns_db_detach(&nsec3chain->db);
3559 }
3560 if (nsec3chain->dbiterator != NULL) {
3561 dns_dbiterator_destroy(&nsec3chain->dbiterator);
3562 }
3563 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
3564 }
3565
3566 cleanup:
3567 if (db != NULL) {
3568 dns_db_detach(&db);
3569 }
3570 return (result);
3571 }
3572
3573 /*
3574 * Find private-type records at the zone apex which signal that an NSEC3 chain
3575 * should be added or removed. For each such record, extract NSEC3PARAM RDATA
3576 * and pass it to zone_addnsec3chain().
3577 *
3578 * Zone must be locked by caller.
3579 */
3580 static void
3581 resume_addnsec3chain(dns_zone_t *zone) {
3582 dns_dbnode_t *node = NULL;
3583 dns_dbversion_t *version = NULL;
3584 dns_rdataset_t rdataset;
3585 isc_result_t result;
3586 dns_rdata_nsec3param_t nsec3param;
3587 bool nseconly = false, nsec3ok = false;
3588 dns_db_t *db = NULL;
3589
3590 INSIST(LOCKED_ZONE(zone));
3591
3592 if (zone->privatetype == 0)
3593 return;
3594
3595 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3596 if (zone->db != NULL) {
3597 dns_db_attach(zone->db, &db);
3598 }
3599 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3600 if (db == NULL) {
3601 goto cleanup;
3602 }
3603
3604 result = dns_db_findnode(db, &zone->origin, false, &node);
3605 if (result != ISC_R_SUCCESS) {
3606 goto cleanup;
3607 }
3608
3609 dns_db_currentversion(db, &version);
3610
3611 /*
3612 * In order to create NSEC3 chains we need the DNSKEY RRset at zone
3613 * apex to exist and contain no keys using NSEC-only algorithms.
3614 */
3615 result = dns_nsec_nseconly(db, version, &nseconly);
3616 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
3617
3618 /*
3619 * Get the RRset containing all private-type records at the zone apex.
3620 */
3621 dns_rdataset_init(&rdataset);
3622 result = dns_db_findrdataset(db, node, version,
3623 zone->privatetype, dns_rdatatype_none,
3624 0, &rdataset, NULL);
3625 if (result != ISC_R_SUCCESS) {
3626 INSIST(!dns_rdataset_isassociated(&rdataset));
3627 goto cleanup;
3628 }
3629
3630 for (result = dns_rdataset_first(&rdataset);
3631 result == ISC_R_SUCCESS;
3632 result = dns_rdataset_next(&rdataset))
3633 {
3634 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
3635 dns_rdata_t rdata = DNS_RDATA_INIT;
3636 dns_rdata_t private = DNS_RDATA_INIT;
3637
3638 dns_rdataset_current(&rdataset, &private);
3639 /*
3640 * Try extracting NSEC3PARAM RDATA from this private-type
3641 * record. Failure means this private-type record does not
3642 * represent an NSEC3PARAM record, so skip it.
3643 */
3644 if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
3645 sizeof(buf)))
3646 {
3647 continue;
3648 }
3649 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
3650 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3651 if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) ||
3652 ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok))
3653 {
3654 /*
3655 * Pass the NSEC3PARAM RDATA contained in this
3656 * private-type record to zone_addnsec3chain() so that
3657 * it can kick off adding or removing NSEC3 records.
3658 */
3659 result = zone_addnsec3chain(zone, &nsec3param);
3660 if (result != ISC_R_SUCCESS) {
3661 dnssec_log(zone, ISC_LOG_ERROR,
3662 "zone_addnsec3chain failed: %s",
3663 dns_result_totext(result));
3664 }
3665 }
3666 }
3667 dns_rdataset_disassociate(&rdataset);
3668
3669 cleanup:
3670 if (db != NULL) {
3671 if (node != NULL) {
3672 dns_db_detachnode(db, &node);
3673 }
3674 if (version != NULL) {
3675 dns_db_closeversion(db, &version, false);
3676 }
3677 dns_db_detach(&db);
3678 }
3679 }
3680
3681 static void
3682 set_resigntime(dns_zone_t *zone) {
3683 dns_rdataset_t rdataset;
3684 dns_fixedname_t fixed;
3685 unsigned int resign;
3686 isc_result_t result;
3687 uint32_t nanosecs;
3688 dns_db_t *db = NULL;
3689
3690 /* We only re-sign zones that can be dynamically updated */
3691 if (zone->update_disabled)
3692 return;
3693
3694 if (!inline_secure(zone) && (zone->type != dns_zone_master ||
3695 (zone->ssutable == NULL &&
3696 (zone->update_acl == NULL || dns_acl_isnone(zone->update_acl)))))
3697 return;
3698
3699 dns_rdataset_init(&rdataset);
3700 dns_fixedname_init(&fixed);
3701
3702 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
3703 if (zone->db != NULL)
3704 dns_db_attach(zone->db, &db);
3705 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
3706 if (db == NULL) {
3707 isc_time_settoepoch(&zone->resigntime);
3708 return;
3709 }
3710
3711 result = dns_db_getsigningtime(db, &rdataset,
3712 dns_fixedname_name(&fixed));
3713 if (result != ISC_R_SUCCESS) {
3714 isc_time_settoepoch(&zone->resigntime);
3715 goto cleanup;
3716 }
3717
3718 resign = rdataset.resign - zone->sigresigninginterval;
3719 dns_rdataset_disassociate(&rdataset);
3720 nanosecs = isc_random_uniform(1000000000);
3721 isc_time_set(&zone->resigntime, resign, nanosecs);
3722 cleanup:
3723 dns_db_detach(&db);
3724 return;
3725 }
3726
3727 static isc_result_t
3728 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
3729 dns_dbnode_t *node = NULL;
3730 dns_rdataset_t rdataset;
3731 dns_dbversion_t *version = NULL;
3732 dns_rdata_nsec3param_t nsec3param;
3733 bool ok = false;
3734 isc_result_t result;
3735 dns_rdata_t rdata = DNS_RDATA_INIT;
3736 bool dynamic = (zone->type == dns_zone_master)
3737 ? dns_zone_isdynamic(zone, false) : false;
3738
3739 dns_rdataset_init(&rdataset);
3740 result = dns_db_findnode(db, &zone->origin, false, &node);
3741 if (result != ISC_R_SUCCESS) {
3742 dns_zone_log(zone, ISC_LOG_ERROR,
3743 "nsec3param lookup failure: %s",
3744 dns_result_totext(result));
3745 return (result);
3746 }
3747 dns_db_currentversion(db, &version);
3748
3749 result = dns_db_findrdataset(db, node, version,
3750 dns_rdatatype_nsec3param,
3751 dns_rdatatype_none, 0, &rdataset, NULL);
3752 if (result == ISC_R_NOTFOUND) {
3753 INSIST(!dns_rdataset_isassociated(&rdataset));
3754 result = ISC_R_SUCCESS;
3755 goto cleanup;
3756 }
3757 if (result != ISC_R_SUCCESS) {
3758 INSIST(!dns_rdataset_isassociated(&rdataset));
3759 dns_zone_log(zone, ISC_LOG_ERROR,
3760 "nsec3param lookup failure: %s",
3761 dns_result_totext(result));
3762 goto cleanup;
3763 }
3764
3765 /*
3766 * For dynamic zones we must support every algorithm so we can
3767 * regenerate all the NSEC3 chains.
3768 * For non-dynamic zones we only need to find a supported algorithm.
3769 */
3770 for (result = dns_rdataset_first(&rdataset);
3771 result == ISC_R_SUCCESS;
3772 result = dns_rdataset_next(&rdataset))
3773 {
3774 dns_rdataset_current(&rdataset, &rdata);
3775 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
3776 dns_rdata_reset(&rdata);
3777 INSIST(result == ISC_R_SUCCESS);
3778 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
3779 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
3780 {
3781 dns_zone_log(zone, ISC_LOG_WARNING,
3782 "nsec3 test \"unknown\" hash algorithm found: %u",
3783 nsec3param.hash);
3784 ok = true;
3785 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
3786 if (dynamic) {
3787 dns_zone_log(zone, ISC_LOG_ERROR,
3788 "unsupported nsec3 hash algorithm"
3789 " in dynamic zone: %u",
3790 nsec3param.hash);
3791 result = DNS_R_BADZONE;
3792 /* Stop second error message. */
3793 ok = true;
3794 break;
3795 } else
3796 dns_zone_log(zone, ISC_LOG_WARNING,
3797 "unsupported nsec3 hash algorithm: %u",
3798 nsec3param.hash);
3799 } else {
3800 ok = true;
3801 }
3802 }
3803 if (result == ISC_R_NOMORE) {
3804 result = ISC_R_SUCCESS;
3805 }
3806
3807 if (!ok) {
3808 result = DNS_R_BADZONE;
3809 dns_zone_log(zone, ISC_LOG_ERROR,
3810 "no supported nsec3 hash algorithm");
3811 }
3812
3813 cleanup:
3814 if (dns_rdataset_isassociated(&rdataset)) {
3815 dns_rdataset_disassociate(&rdataset);
3816 }
3817 dns_db_closeversion(db, &version, false);
3818 dns_db_detachnode(db, &node);
3819 return (result);
3820 }
3821
3822 /*
3823 * Set the timer for refreshing the key zone to the soonest future time
3824 * of the set (current timer, keydata->refresh, keydata->addhd,
3825 * keydata->removehd).
3826 */
3827 static void
3828 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
3829 isc_stdtime_t now, bool force)
3830 {
3831 const char me[] = "set_refreshkeytimer";
3832 isc_stdtime_t then;
3833 isc_time_t timenow, timethen;
3834 char timebuf[80];
3835
3836 ENTER;
3837 then = key->refresh;
3838 if (force)
3839 then = now;
3840 if (key->addhd > now && key->addhd < then)
3841 then = key->addhd;
3842 if (key->removehd > now && key->removehd < then)
3843 then = key->removehd;
3844
3845 TIME_NOW(&timenow);
3846 if (then > now)
3847 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
3848 else
3849 timethen = timenow;
3850 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
3851 isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
3852 zone->refreshkeytime = timethen;
3853
3854 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
3855 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
3856 zone_settimer(zone, &timenow);
3857 }
3858
3859 /*
3860 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
3861 * If the key zone is changed, set '*changed' to true.
3862 */
3863 static isc_result_t
3864 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
3865 dns_diff_t *diff, dns_keytable_t *keytable,
3866 dns_keynode_t **keynodep, bool *changed)
3867 {
3868 const char me[] = "create_keydata";
3869 isc_result_t result = ISC_R_SUCCESS;
3870 isc_buffer_t keyb, dstb;
3871 unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
3872 dns_rdata_keydata_t keydata;
3873 dns_rdata_dnskey_t dnskey;
3874 dns_rdata_t rdata = DNS_RDATA_INIT;
3875 dns_keynode_t *keynode;
3876 isc_stdtime_t now;
3877 isc_region_t r;
3878 dst_key_t *key;
3879
3880 REQUIRE(keynodep != NULL);
3881 keynode = *keynodep;
3882
3883 ENTER;
3884 isc_stdtime_get(&now);
3885
3886 /* Loop in case there's more than one key. */
3887 while (result == ISC_R_SUCCESS) {
3888 dns_keynode_t *nextnode = NULL;
3889
3890 key = dns_keynode_key(keynode);
3891 if (key == NULL)
3892 goto skip;
3893
3894 isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
3895 CHECK(dst_key_todns(key, &dstb));
3896
3897 /* Convert DST key to DNSKEY. */
3898 dns_rdata_reset(&rdata);
3899 isc_buffer_usedregion(&dstb, &r);
3900 dns_rdata_fromregion(&rdata, dst_key_class(key),
3901 dns_rdatatype_dnskey, &r);
3902
3903 /* DSTKEY to KEYDATA. */
3904 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
3905 CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
3906 NULL));
3907
3908 /* KEYDATA to rdata. */
3909 dns_rdata_reset(&rdata);
3910 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
3911 CHECK(dns_rdata_fromstruct(&rdata,
3912 zone->rdclass, dns_rdatatype_keydata,
3913 &keydata, &keyb));
3914
3915 /* Add rdata to zone. */
3916 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
3917 dst_key_name(key), 0, &rdata));
3918 *changed = true;
3919
3920 /* Refresh new keys from the zone apex as soon as possible. */
3921 set_refreshkeytimer(zone, &keydata, now, true);
3922
3923 skip:
3924 result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
3925 if (result != ISC_R_NOTFOUND) {
3926 dns_keytable_detachkeynode(keytable, &keynode);
3927 keynode = nextnode;
3928 }
3929 }
3930
3931 if (keynode != NULL)
3932 dns_keytable_detachkeynode(keytable, &keynode);
3933 *keynodep = NULL;
3934
3935 return (ISC_R_SUCCESS);
3936
3937 failure:
3938 return (result);
3939 }
3940
3941 /*
3942 * Remove from the key zone all the KEYDATA records found in rdataset.
3943 */
3944 static isc_result_t
3945 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3946 dns_name_t *name, dns_rdataset_t *rdataset)
3947 {
3948 dns_rdata_t rdata = DNS_RDATA_INIT;
3949 isc_result_t result, uresult;
3950
3951 for (result = dns_rdataset_first(rdataset);
3952 result == ISC_R_SUCCESS;
3953 result = dns_rdataset_next(rdataset)) {
3954 dns_rdata_reset(&rdata);
3955 dns_rdataset_current(rdataset, &rdata);
3956 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
3957 name, 0, &rdata);
3958 if (uresult != ISC_R_SUCCESS)
3959 return (uresult);
3960 }
3961 if (result == ISC_R_NOMORE)
3962 result = ISC_R_SUCCESS;
3963 return (result);
3964 }
3965
3966 /*
3967 * Compute the DNSSEC key ID for a DNSKEY record.
3968 */
3969 static isc_result_t
3970 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
3971 dns_keytag_t *tag)
3972 {
3973 isc_result_t result;
3974 dns_rdata_t rdata = DNS_RDATA_INIT;
3975 unsigned char data[4096];
3976 isc_buffer_t buffer;
3977 dst_key_t *dstkey = NULL;
3978
3979 isc_buffer_init(&buffer, data, sizeof(data));
3980 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
3981 dns_rdatatype_dnskey, dnskey, &buffer);
3982
3983 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
3984 if (result == ISC_R_SUCCESS) {
3985 *tag = dst_key_id(dstkey);
3986 dst_key_free(&dstkey);
3987 }
3988
3989 return (result);
3990 }
3991
3992 /*
3993 * Add key to the security roots.
3994 */
3995 static void
3996 trust_key(dns_zone_t *zone, dns_name_t *keyname,
3997 dns_rdata_dnskey_t *dnskey, bool initial,
3998 isc_mem_t *mctx)
3999 {
4000 isc_result_t result;
4001 dns_rdata_t rdata = DNS_RDATA_INIT;
4002 unsigned char data[4096];
4003 isc_buffer_t buffer;
4004 dns_keytable_t *sr = NULL;
4005 dst_key_t *dstkey = NULL;
4006
4007 /* Convert dnskey to DST key. */
4008 isc_buffer_init(&buffer, data, sizeof(data));
4009 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
4010 dns_rdatatype_dnskey, dnskey, &buffer);
4011
4012 result = dns_view_getsecroots(zone->view, &sr);
4013 if (result != ISC_R_SUCCESS)
4014 goto failure;
4015
4016 CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
4017 CHECK(dns_keytable_add(sr, true, initial, &dstkey));
4018 dns_keytable_detach(&sr);
4019
4020 failure:
4021 if (dstkey != NULL)
4022 dst_key_free(&dstkey);
4023 if (sr != NULL)
4024 dns_keytable_detach(&sr);
4025 return;
4026 }
4027
4028 /*
4029 * Add a null key to the security roots for so that all queries
4030 * to the zone will fail.
4031 */
4032 static void
4033 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
4034 isc_result_t result;
4035 dns_keytable_t *sr = NULL;
4036
4037 result = dns_view_getsecroots(zone->view, &sr);
4038 if (result == ISC_R_SUCCESS) {
4039 dns_keytable_marksecure(sr, keyname);
4040 dns_keytable_detach(&sr);
4041 }
4042 }
4043
4044 /*
4045 * Scan a set of KEYDATA records from the key zone. The ones that are
4046 * valid (i.e., the add holddown timer has expired) become trusted keys.
4047 */
4048 static void
4049 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
4050 isc_result_t result;
4051 dns_rdata_t rdata = DNS_RDATA_INIT;
4052 dns_rdata_keydata_t keydata;
4053 dns_rdata_dnskey_t dnskey;
4054 isc_mem_t *mctx = zone->mctx;
4055 int trusted = 0, revoked = 0, pending = 0;
4056 isc_stdtime_t now;
4057 dns_keytable_t *sr = NULL;
4058
4059 isc_stdtime_get(&now);
4060
4061 result = dns_view_getsecroots(zone->view, &sr);
4062 if (result == ISC_R_SUCCESS) {
4063 dns_keytable_delete(sr, name);
4064 dns_keytable_detach(&sr);
4065 }
4066
4067 /* Now insert all the accepted trust anchors from this keydata set. */
4068 for (result = dns_rdataset_first(rdataset);
4069 result == ISC_R_SUCCESS;
4070 result = dns_rdataset_next(rdataset))
4071 {
4072 dns_rdata_reset(&rdata);
4073 dns_rdataset_current(rdataset, &rdata);
4074
4075 /* Convert rdata to keydata. */
4076 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
4077 if (result == ISC_R_UNEXPECTEDEND) {
4078 continue;
4079 }
4080 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4081
4082 /* Set the key refresh timer to force a fast refresh. */
4083 set_refreshkeytimer(zone, &keydata, now, true);
4084
4085 /* If the removal timer is nonzero, this key was revoked. */
4086 if (keydata.removehd != 0) {
4087 revoked++;
4088 continue;
4089 }
4090
4091 /*
4092 * If the add timer is still pending, this key is not
4093 * trusted yet.
4094 */
4095 if (now < keydata.addhd) {
4096 pending++;
4097 continue;
4098 }
4099
4100 /* Convert keydata to dnskey. */
4101 dns_keydata_todnskey(&keydata, &dnskey, NULL);
4102
4103 /* Add to keytables. */
4104 trusted++;
4105 trust_key(zone, name, &dnskey, (keydata.addhd == 0), mctx);
4106 }
4107
4108 if (trusted == 0 && pending != 0) {
4109 char namebuf[DNS_NAME_FORMATSIZE];
4110 dns_name_format(name, namebuf, sizeof namebuf);
4111 dnssec_log(zone, ISC_LOG_ERROR,
4112 "No valid trust anchors for '%s'!", namebuf);
4113 dnssec_log(zone, ISC_LOG_ERROR,
4114 "%d key(s) revoked, %d still pending",
4115 revoked, pending);
4116 dnssec_log(zone, ISC_LOG_ERROR,
4117 "All queries to '%s' will fail", namebuf);
4118 fail_secure(zone, name);
4119 }
4120 }
4121
4122 static isc_result_t
4123 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
4124 dns_diff_t *diff)
4125 {
4126 dns_diff_t temp_diff;
4127 isc_result_t result;
4128
4129 /*
4130 * Create a singleton diff.
4131 */
4132 dns_diff_init(diff->mctx, &temp_diff);
4133 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
4134
4135 /*
4136 * Apply it to the database.
4137 */
4138 result = dns_diff_apply(&temp_diff, db, ver);
4139 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
4140 if (result != ISC_R_SUCCESS) {
4141 dns_difftuple_free(tuple);
4142 return (result);
4143 }
4144
4145 /*
4146 * Merge it into the current pending journal entry.
4147 */
4148 dns_diff_appendminimal(diff, tuple);
4149
4150 /*
4151 * Do not clear temp_diff.
4152 */
4153 return (ISC_R_SUCCESS);
4154 }
4155
4156 static isc_result_t
4157 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
4158 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
4159 dns_rdata_t *rdata)
4160 {
4161 dns_difftuple_t *tuple = NULL;
4162 isc_result_t result;
4163 result = dns_difftuple_create(diff->mctx, op,
4164 name, ttl, rdata, &tuple);
4165 if (result != ISC_R_SUCCESS)
4166 return (result);
4167 return (do_one_tuple(&tuple, db, ver, diff));
4168 }
4169
4170 static isc_result_t
4171 update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
4172 isc_mem_t *mctx, dns_updatemethod_t method) {
4173 dns_difftuple_t *deltuple = NULL;
4174 dns_difftuple_t *addtuple = NULL;
4175 uint32_t serial;
4176 isc_result_t result;
4177
4178 INSIST(method != dns_updatemethod_none);
4179
4180 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
4181 CHECK(dns_difftuple_copy(deltuple, &addtuple));
4182 addtuple->op = DNS_DIFFOP_ADD;
4183
4184 serial = dns_soa_getserial(&addtuple->rdata);
4185 serial = dns_update_soaserial(serial, method);
4186 dns_soa_setserial(serial, &addtuple->rdata);
4187 CHECK(do_one_tuple(&deltuple, db, ver, diff));
4188 CHECK(do_one_tuple(&addtuple, db, ver, diff));
4189 result = ISC_R_SUCCESS;
4190
4191 failure:
4192 if (addtuple != NULL)
4193 dns_difftuple_free(&addtuple);
4194 if (deltuple != NULL)
4195 dns_difftuple_free(&deltuple);
4196 return (result);
4197 }
4198
4199 /*
4200 * Write all transactions in 'diff' to the zone journal file.
4201 */
4202 static isc_result_t
4203 zone_journal(dns_zone_t *zone, dns_diff_t *diff, uint32_t *sourceserial,
4204 const char *caller)
4205 {
4206 const char me[] = "zone_journal";
4207 const char *journalfile;
4208 isc_result_t result = ISC_R_SUCCESS;
4209 dns_journal_t *journal = NULL;
4210 unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE;
4211
4212 ENTER;
4213 journalfile = dns_zone_getjournal(zone);
4214 if (journalfile != NULL) {
4215 result = dns_journal_open(zone->mctx, journalfile, mode,
4216 &journal);
4217 if (result != ISC_R_SUCCESS) {
4218 dns_zone_log(zone, ISC_LOG_ERROR,
4219 "%s:dns_journal_open -> %s",
4220 caller, dns_result_totext(result));
4221 return (result);
4222 }
4223
4224 if (sourceserial != NULL)
4225 dns_journal_set_sourceserial(journal, *sourceserial);
4226
4227 result = dns_journal_write_transaction(journal, diff);
4228 if (result != ISC_R_SUCCESS) {
4229 dns_zone_log(zone, ISC_LOG_ERROR,
4230 "%s:dns_journal_write_transaction -> %s",
4231 caller, dns_result_totext(result));
4232 }
4233 dns_journal_destroy(&journal);
4234 }
4235
4236 return (result);
4237 }
4238
4239 /*
4240 * Create an SOA record for a newly-created zone
4241 */
4242 static isc_result_t
4243 add_soa(dns_zone_t *zone, dns_db_t *db) {
4244 isc_result_t result;
4245 dns_rdata_t rdata = DNS_RDATA_INIT;
4246 unsigned char buf[DNS_SOA_BUFFERSIZE];
4247 dns_dbversion_t *ver = NULL;
4248 dns_diff_t diff;
4249
4250 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
4251
4252 dns_diff_init(zone->mctx, &diff);
4253 result = dns_db_newversion(db, &ver);
4254 if (result != ISC_R_SUCCESS) {
4255 dns_zone_log(zone, ISC_LOG_ERROR,
4256 "add_soa:dns_db_newversion -> %s",
4257 dns_result_totext(result));
4258 goto failure;
4259 }
4260
4261 /* Build SOA record */
4262 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
4263 0, 0, 0, 0, 0, buf, &rdata);
4264 if (result != ISC_R_SUCCESS) {
4265 dns_zone_log(zone, ISC_LOG_ERROR,
4266 "add_soa:dns_soa_buildrdata -> %s",
4267 dns_result_totext(result));
4268 goto failure;
4269 }
4270
4271 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
4272 &zone->origin, 0, &rdata);
4273
4274 failure:
4275 dns_diff_clear(&diff);
4276 if (ver != NULL)
4277 dns_db_closeversion(db, &ver, (result == ISC_R_SUCCESS));
4278
4279 INSIST(ver == NULL);
4280
4281 return (result);
4282 }
4283
4284 struct addifmissing_arg {
4285 dns_db_t *db;
4286 dns_dbversion_t *ver;
4287 dns_diff_t *diff;
4288 dns_zone_t *zone;
4289 bool *changed;
4290 isc_result_t result;
4291 };
4292
4293 static void
4294 addifmissing(dns_keytable_t *keytable, dns_keynode_t *keynode, void *arg) {
4295 dns_db_t *db = ((struct addifmissing_arg *)arg)->db;
4296 dns_dbversion_t *ver = ((struct addifmissing_arg *)arg)->ver;
4297 dns_diff_t *diff = ((struct addifmissing_arg *)arg)->diff;
4298 dns_zone_t *zone = ((struct addifmissing_arg *)arg)->zone;
4299 bool *changed = ((struct addifmissing_arg *)arg)->changed;
4300 isc_result_t result;
4301 dns_keynode_t *dummy = NULL;
4302
4303 if (((struct addifmissing_arg *)arg)->result != ISC_R_SUCCESS)
4304 return;
4305
4306 if (dns_keynode_managed(keynode)) {
4307 dns_fixedname_t fname;
4308 dns_name_t *keyname;
4309 dst_key_t *key;
4310
4311 key = dns_keynode_key(keynode);
4312 if (key == NULL)
4313 return;
4314 dns_fixedname_init(&fname);
4315
4316 keyname = dst_key_name(key);
4317 result = dns_db_find(db, keyname, ver,
4318 dns_rdatatype_keydata,
4319 DNS_DBFIND_NOWILD, 0, NULL,
4320 dns_fixedname_name(&fname),
4321 NULL, NULL);
4322 if (result == ISC_R_SUCCESS)
4323 return;
4324 dns_keytable_attachkeynode(keytable, keynode, &dummy);
4325 result = create_keydata(zone, db, ver, diff, keytable,
4326 &dummy, changed);
4327 if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE)
4328 ((struct addifmissing_arg *)arg)->result = result;
4329 }
4330 };
4331
4332 /*
4333 * Synchronize the set of initializing keys found in managed-keys {}
4334 * statements with the set of trust anchors found in the managed-keys.bind
4335 * zone. If a domain is no longer named in managed-keys, delete all keys
4336 * from that domain from the key zone. If a domain is mentioned in in
4337 * managed-keys but there are no references to it in the key zone, load
4338 * the key zone with the initializing key(s) for that domain.
4339 */
4340 static isc_result_t
4341 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
4342 isc_result_t result = ISC_R_SUCCESS;
4343 bool changed = false;
4344 bool commit = false;
4345 dns_keynode_t *keynode = NULL;
4346 dns_view_t *view = zone->view;
4347 dns_keytable_t *sr = NULL;
4348 dns_dbversion_t *ver = NULL;
4349 dns_diff_t diff;
4350 dns_rriterator_t rrit;
4351 struct addifmissing_arg arg;
4352
4353 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
4354
4355 dns_diff_init(zone->mctx, &diff);
4356
4357 CHECK(dns_view_getsecroots(view, &sr));
4358
4359 result = dns_db_newversion(db, &ver);
4360 if (result != ISC_R_SUCCESS) {
4361 dnssec_log(zone, ISC_LOG_ERROR,
4362 "sync_keyzone:dns_db_newversion -> %s",
4363 dns_result_totext(result));
4364 goto failure;
4365 }
4366
4367 /*
4368 * Walk the zone DB. If we find any keys whose names are no longer
4369 * in managed-keys (or *are* in trusted-keys, meaning they are
4370 * permanent and not RFC5011-maintained), delete them from the
4371 * zone. Otherwise call load_secroots(), which loads keys into
4372 * secroots as appropriate.
4373 */
4374 dns_rriterator_init(&rrit, db, ver, 0);
4375 for (result = dns_rriterator_first(&rrit);
4376 result == ISC_R_SUCCESS;
4377 result = dns_rriterator_nextrrset(&rrit))
4378 {
4379 dns_rdataset_t *rdataset = NULL;
4380 dns_name_t *rrname = NULL;
4381 uint32_t ttl;
4382
4383 dns_rriterator_current(&rrit, &rrname, &ttl, &rdataset, NULL);
4384 if (!dns_rdataset_isassociated(rdataset)) {
4385 dns_rriterator_destroy(&rrit);
4386 goto failure;
4387 }
4388
4389 if (rdataset->type != dns_rdatatype_keydata) {
4390 continue;
4391 }
4392
4393 result = dns_keytable_find(sr, rrname, &keynode);
4394 if ((result != ISC_R_SUCCESS &&
4395 result != DNS_R_PARTIALMATCH) ||
4396 dns_keynode_managed(keynode) == false)
4397 {
4398 CHECK(delete_keydata(db, ver, &diff,
4399 rrname, rdataset));
4400 changed = true;
4401 } else {
4402 load_secroots(zone, rrname, rdataset);
4403 }
4404
4405 if (keynode != NULL) {
4406 dns_keytable_detachkeynode(sr, &keynode);
4407 }
4408 }
4409 dns_rriterator_destroy(&rrit);
4410
4411 /*
4412 * Now walk secroots to find any managed keys that aren't
4413 * in the zone. If we find any, we add them to the zone.
4414 */
4415 arg.db = db;
4416 arg.ver = ver;
4417 arg.result = ISC_R_SUCCESS;
4418 arg.diff = &diff;
4419 arg.zone = zone;
4420 arg.changed = &changed;
4421 dns_keytable_forall(sr, addifmissing, &arg);
4422 result = arg.result;
4423 if (changed) {
4424 /* Write changes to journal file. */
4425 CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
4426 zone->updatemethod));
4427 CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone"));
4428
4429 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
4430 zone_needdump(zone, 30);
4431 commit = true;
4432 }
4433
4434 failure:
4435 if (result != ISC_R_SUCCESS &&
4436 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
4437 {
4438 dnssec_log(zone, ISC_LOG_ERROR,
4439 "unable to synchronize managed keys: %s",
4440 dns_result_totext(result));
4441 isc_time_settoepoch(&zone->refreshkeytime);
4442 }
4443 if (keynode != NULL) {
4444 dns_keytable_detachkeynode(sr, &keynode);
4445 }
4446 if (sr != NULL) {
4447 dns_keytable_detach(&sr);
4448 }
4449 if (ver != NULL) {
4450 dns_db_closeversion(db, &ver, commit);
4451 }
4452 dns_diff_clear(&diff);
4453
4454 INSIST(ver == NULL);
4455
4456 return (result);
4457 }
4458
4459 isc_result_t
4460 dns_zone_synckeyzone(dns_zone_t *zone) {
4461 isc_result_t result;
4462 dns_db_t *db = NULL;
4463
4464 if (zone->type != dns_zone_key) {
4465 return (DNS_R_BADZONE);
4466 }
4467
4468 CHECK(dns_zone_getdb(zone, &db));
4469
4470 LOCK_ZONE(zone);
4471 result = sync_keyzone(zone, db);
4472 UNLOCK_ZONE(zone);
4473
4474 failure:
4475 if (db != NULL) {
4476 dns_db_detach(&db);
4477 }
4478 return (result);
4479 }
4480
4481 static void
4482 maybe_send_secure(dns_zone_t *zone) {
4483 isc_result_t result;
4484
4485 /*
4486 * We've finished loading, or else failed to load, an inline-signing
4487 * 'secure' zone. We now need information about the status of the
4488 * 'raw' zone. If we failed to load, then we need it to send a
4489 * copy of its database; if we succeeded, we need it to send its
4490 * serial number so that we can sync with it. If it has not yet
4491 * loaded, we set a flag so that it will send the necessary
4492 * information when it has finished loading.
4493 */
4494 if (zone->raw->db != NULL) {
4495 if (zone->db != NULL) {
4496 uint32_t serial;
4497 unsigned int soacount;
4498
4499 result = zone_get_from_db(zone->raw, zone->raw->db,
4500 NULL, &soacount, &serial,
4501 NULL, NULL, NULL, NULL, NULL);
4502 if (result == ISC_R_SUCCESS && soacount > 0U)
4503 zone_send_secureserial(zone->raw, serial);
4504 } else
4505 zone_send_securedb(zone->raw, zone->raw->db);
4506
4507 } else
4508 DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
4509 }
4510
4511 static bool
4512 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
4513 isc_result_t result;
4514 bool answer = false;
4515 dns_diff_t diff;
4516
4517 dns_diff_init(mctx, &diff);
4518 result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
4519 if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples))
4520 answer = true;
4521 dns_diff_clear(&diff);
4522 return (answer);
4523 }
4524
4525 /*
4526 * The zone is presumed to be locked.
4527 * If this is a inline_raw zone the secure version is also locked.
4528 */
4529 static isc_result_t
4530 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
4531 isc_result_t result)
4532 {
4533 unsigned int soacount = 0;
4534 unsigned int nscount = 0;
4535 unsigned int errors = 0;
4536 uint32_t serial, oldserial, refresh, retry, expire, minimum;
4537 isc_time_t now;
4538 bool needdump = false;
4539 bool hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
4540 bool nomaster = false;
4541 bool had_db = false;
4542 unsigned int options;
4543 dns_include_t *inc;
4544
4545 INSIST(LOCKED_ZONE(zone));
4546 if (inline_raw(zone)) {
4547 INSIST(LOCKED_ZONE(zone->secure));
4548 }
4549
4550 TIME_NOW(&now);
4551
4552 /*
4553 * Initiate zone transfer? We may need a error code that
4554 * indicates that the "permanent" form does not exist.
4555 * XXX better error feedback to log.
4556 */
4557 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
4558 if (zone->type == dns_zone_slave ||
4559 zone->type == dns_zone_mirror ||
4560 zone->type == dns_zone_stub ||
4561 (zone->type == dns_zone_redirect &&
4562 zone->masters == NULL))
4563 {
4564 if (result == ISC_R_FILENOTFOUND) {
4565 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4566 ISC_LOG_DEBUG(1),
4567 "no master file");
4568 } else if (result != DNS_R_NOMASTERFILE) {
4569 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4570 ISC_LOG_ERROR,
4571 "loading from master file %s "
4572 "failed: %s",
4573 zone->masterfile,
4574 dns_result_totext(result));
4575 }
4576 } else if (zone->type == dns_zone_master &&
4577 inline_secure(zone) && result == ISC_R_FILENOTFOUND)
4578 {
4579 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4580 ISC_LOG_DEBUG(1),
4581 "no master file, requesting db");
4582 maybe_send_secure(zone);
4583 } else {
4584 int level = ISC_LOG_ERROR;
4585 if (zone->type == dns_zone_key &&
4586 result == ISC_R_FILENOTFOUND)
4587 level = ISC_LOG_DEBUG(1);
4588 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, level,
4589 "loading from master file %s failed: %s",
4590 zone->masterfile,
4591 dns_result_totext(result));
4592 nomaster = true;
4593 }
4594
4595 if (zone->type != dns_zone_key) {
4596 goto cleanup;
4597 }
4598 }
4599
4600 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(2),
4601 "number of nodes in database: %u",
4602 dns_db_nodecount(db));
4603
4604 if (result == DNS_R_SEENINCLUDE) {
4605 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
4606 } else {
4607 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
4608 }
4609
4610 /*
4611 * If there's no master file for a key zone, then the zone is new:
4612 * create an SOA record. (We do this now, instead of later, so that
4613 * if there happens to be a journal file, we can roll forward from
4614 * a sane starting point.)
4615 */
4616 if (nomaster && zone->type == dns_zone_key) {
4617 result = add_soa(zone, db);
4618 if (result != ISC_R_SUCCESS) {
4619 goto cleanup;
4620 }
4621 }
4622
4623 /*
4624 * Apply update log, if any, on initial load.
4625 */
4626 if (zone->journal != NULL &&
4627 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
4628 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
4629 {
4630 if (zone->type == dns_zone_master && (inline_secure(zone) ||
4631 (zone->update_acl != NULL || zone->ssutable != NULL)))
4632 {
4633 options = DNS_JOURNALOPT_RESIGN;
4634 } else {
4635 options = 0;
4636 }
4637 result = dns_journal_rollforward(zone->mctx, db, options,
4638 zone->journal);
4639 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
4640 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
4641 result != ISC_R_RANGE)
4642 {
4643 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4644 ISC_LOG_ERROR,
4645 "journal rollforward failed: %s",
4646 dns_result_totext(result));
4647 goto cleanup;
4648
4649
4650 }
4651 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
4652 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4653 ISC_LOG_ERROR,
4654 "journal rollforward failed: "
4655 "journal out of sync with zone");
4656 goto cleanup;
4657 }
4658 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
4659 "journal rollforward completed "
4660 "successfully: %s",
4661 dns_result_totext(result));
4662 if (result == ISC_R_SUCCESS) {
4663 needdump = true;
4664 }
4665 }
4666
4667 /*
4668 * Obtain ns, soa and cname counts for top of zone.
4669 */
4670 INSIST(db != NULL);
4671 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
4672 &refresh, &retry, &expire, &minimum,
4673 &errors);
4674 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
4675 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
4676 "could not find NS and/or SOA records");
4677 }
4678
4679 /*
4680 * Check to make sure the journal is up to date, and remove the
4681 * journal file if it isn't, as we wouldn't be able to apply
4682 * updates otherwise.
4683 */
4684 if (zone->journal != NULL && dns_zone_isdynamic(zone, true) &&
4685 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS))
4686 {
4687 uint32_t jserial;
4688 dns_journal_t *journal = NULL;
4689 bool empty = false;
4690
4691 result = dns_journal_open(zone->mctx, zone->journal,
4692 DNS_JOURNAL_READ, &journal);
4693 if (result == ISC_R_SUCCESS) {
4694 jserial = dns_journal_last_serial(journal);
4695 empty = dns_journal_empty(journal);
4696 dns_journal_destroy(&journal);
4697 } else {
4698 jserial = serial;
4699 result = ISC_R_SUCCESS;
4700 }
4701
4702 if (jserial != serial) {
4703 if (!empty) {
4704 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4705 ISC_LOG_INFO,
4706 "journal file is out of date: "
4707 "removing journal file");
4708 }
4709 if (remove(zone->journal) < 0 && errno != ENOENT) {
4710 char strbuf[ISC_STRERRORSIZE];
4711 strerror_r(errno, strbuf, sizeof(strbuf));
4712 isc_log_write(dns_lctx,
4713 DNS_LOGCATEGORY_GENERAL,
4714 DNS_LOGMODULE_ZONE,
4715 ISC_LOG_WARNING,
4716 "unable to remove journal "
4717 "'%s': '%s'",
4718 zone->journal, strbuf);
4719 }
4720 }
4721 }
4722
4723 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
4724 "loaded; checking validity");
4725
4726 /*
4727 * Master / Slave / Mirror / Stub zones require both NS and SOA records
4728 * at the top of the zone.
4729 */
4730
4731 switch (zone->type) {
4732 case dns_zone_dlz:
4733 case dns_zone_master:
4734 case dns_zone_slave:
4735 case dns_zone_mirror:
4736 case dns_zone_stub:
4737 case dns_zone_redirect:
4738 if (soacount != 1) {
4739 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4740 ISC_LOG_ERROR,
4741 "has %d SOA records", soacount);
4742 result = DNS_R_BADZONE;
4743 }
4744 if (nscount == 0) {
4745 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4746 ISC_LOG_ERROR,
4747 "has no NS records");
4748 result = DNS_R_BADZONE;
4749 }
4750 if (result != ISC_R_SUCCESS) {
4751 goto cleanup;
4752 }
4753 if (zone->type == dns_zone_master && errors != 0) {
4754 result = DNS_R_BADZONE;
4755 goto cleanup;
4756 }
4757 if (zone->type != dns_zone_stub &&
4758 zone->type != dns_zone_redirect)
4759 {
4760 result = check_nsec3param(zone, db);
4761 if (result != ISC_R_SUCCESS)
4762 goto cleanup;
4763 }
4764 if (zone->type == dns_zone_master &&
4765 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
4766 !integrity_checks(zone, db))
4767 {
4768 result = DNS_R_BADZONE;
4769 goto cleanup;
4770 }
4771 if (zone->type == dns_zone_master &&
4772 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
4773 !zone_check_dup(zone, db))
4774 {
4775 result = DNS_R_BADZONE;
4776 goto cleanup;
4777 }
4778
4779 if (zone->type == dns_zone_master) {
4780 result = dns_zone_cdscheck(zone, db, NULL);
4781 if (result != ISC_R_SUCCESS) {
4782 dns_zone_log(zone, ISC_LOG_ERROR,
4783 "CDS/CDNSKEY consistency checks "
4784 "failed");
4785 goto cleanup;
4786 }
4787 }
4788
4789 result = dns_zone_verifydb(zone, db, NULL);
4790 if (result != ISC_R_SUCCESS) {
4791 goto cleanup;
4792 }
4793
4794 if (zone->db != NULL) {
4795 unsigned int oldsoacount;
4796
4797 /*
4798 * This is checked in zone_replacedb() for slave zones
4799 * as they don't reload from disk.
4800 */
4801 result = zone_get_from_db(zone, zone->db, NULL,
4802 &oldsoacount, &oldserial,
4803 NULL, NULL, NULL, NULL,
4804 NULL);
4805 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4806 RUNTIME_CHECK(soacount > 0U);
4807 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
4808 !isc_serial_gt(serial, oldserial)) {
4809 uint32_t serialmin, serialmax;
4810
4811 INSIST(zone->type == dns_zone_master);
4812 INSIST(zone->raw == NULL);
4813
4814 if (serial == oldserial &&
4815 zone_unchanged(zone->db, db, zone->mctx)) {
4816 dns_zone_logc(zone,
4817 DNS_LOGCATEGORY_ZONELOAD,
4818 ISC_LOG_INFO,
4819 "ixfr-from-differences: "
4820 "unchanged");
4821 goto done;
4822 }
4823
4824 serialmin = (oldserial + 1) & 0xffffffffU;
4825 serialmax = (oldserial + 0x7fffffffU) &
4826 0xffffffffU;
4827 dns_zone_logc(zone,
4828 DNS_LOGCATEGORY_ZONELOAD,
4829 ISC_LOG_ERROR,
4830 "ixfr-from-differences: "
4831 "new serial (%u) out of range "
4832 "[%u - %u]", serial, serialmin,
4833 serialmax);
4834 result = DNS_R_BADZONE;
4835 goto cleanup;
4836 } else if (!isc_serial_ge(serial, oldserial)) {
4837 dns_zone_logc(zone,
4838 DNS_LOGCATEGORY_ZONELOAD,
4839 ISC_LOG_ERROR,
4840 "zone serial (%u/%u) has gone "
4841 "backwards", serial, oldserial);
4842 } else if (serial == oldserial && !hasinclude &&
4843 strcmp(zone->db_argv[0], "_builtin") != 0)
4844 {
4845 dns_zone_logc(zone,
4846 DNS_LOGCATEGORY_ZONELOAD,
4847 ISC_LOG_ERROR,
4848 "zone serial (%u) unchanged. "
4849 "zone may fail to transfer "
4850 "to slaves.", serial);
4851 }
4852 }
4853
4854 if (zone->type == dns_zone_master &&
4855 (zone->update_acl != NULL || zone->ssutable != NULL) &&
4856 zone->sigresigninginterval < (3 * refresh) &&
4857 dns_db_issecure(db))
4858 {
4859 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
4860 ISC_LOG_WARNING,
4861 "sig-re-signing-interval less than "
4862 "3 * refresh.");
4863 }
4864
4865 zone->refresh = RANGE(refresh,
4866 zone->minrefresh, zone->maxrefresh);
4867 zone->retry = RANGE(retry,
4868 zone->minretry, zone->maxretry);
4869 zone->expire = RANGE(expire, zone->refresh + zone->retry,
4870 DNS_MAX_EXPIRE);
4871 zone->minimum = minimum;
4872 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
4873
4874 if (zone->type == dns_zone_slave ||
4875 zone->type == dns_zone_mirror ||
4876 zone->type == dns_zone_stub ||
4877 (zone->type == dns_zone_redirect &&
4878 zone->masters != NULL))
4879 {
4880 isc_time_t t;
4881 uint32_t delay;
4882
4883 result = isc_file_getmodtime(zone->journal, &t);
4884 if (result != ISC_R_SUCCESS) {
4885 result = isc_file_getmodtime(zone->masterfile,
4886 &t);
4887 }
4888 if (result == ISC_R_SUCCESS) {
4889 DNS_ZONE_TIME_ADD(&t, zone->expire,
4890 &zone->expiretime);
4891 } else {
4892 DNS_ZONE_TIME_ADD(&now, zone->retry,
4893 &zone->expiretime);
4894 }
4895
4896 delay = (zone->retry -
4897 isc_random_uniform((zone->retry * 3) / 4));
4898 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
4899 if (isc_time_compare(&zone->refreshtime,
4900 &zone->expiretime) >= 0)
4901 {
4902 zone->refreshtime = now;
4903 }
4904 }
4905
4906 break;
4907
4908 case dns_zone_key:
4909 result = sync_keyzone(zone, db);
4910 if (result != ISC_R_SUCCESS) {
4911 goto cleanup;
4912 }
4913 break;
4914
4915 default:
4916 UNEXPECTED_ERROR(__FILE__, __LINE__,
4917 "unexpected zone type %d", zone->type);
4918 result = ISC_R_UNEXPECTED;
4919 goto cleanup;
4920 }
4921
4922 /*
4923 * Check for weak DNSKEY's.
4924 */
4925 if (zone->type == dns_zone_master) {
4926 zone_check_dnskeys(zone, db);
4927 }
4928
4929 /*
4930 * Schedule DNSSEC key refresh.
4931 */
4932 if (zone->type == dns_zone_master &&
4933 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
4934 {
4935 zone->refreshkeytime = now;
4936 }
4937
4938 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
4939 if (zone->db != NULL) {
4940 had_db = true;
4941 result = zone_replacedb(zone, db, false);
4942 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4943 if (result != ISC_R_SUCCESS) {
4944 goto cleanup;
4945 }
4946 } else {
4947 zone_attachdb(zone, db);
4948 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4949 DNS_ZONE_SETFLAG(zone,
4950 DNS_ZONEFLG_LOADED|
4951 DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
4952 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
4953 inline_raw(zone))
4954 {
4955 if (zone->secure->db == NULL) {
4956 zone_send_securedb(zone, db);
4957 } else {
4958 zone_send_secureserial(zone, serial);
4959 }
4960 }
4961 }
4962
4963 /*
4964 * Finished loading inline-signing zone; need to get status
4965 * from the raw side now.
4966 */
4967 if (zone->type == dns_zone_master && inline_secure(zone)) {
4968 maybe_send_secure(zone);
4969 }
4970
4971 result = ISC_R_SUCCESS;
4972
4973 if (needdump) {
4974 if (zone->type == dns_zone_key) {
4975 zone_needdump(zone, 30);
4976 } else {
4977 zone_needdump(zone, DNS_DUMP_DELAY);
4978 }
4979 }
4980
4981 if (zone->task != NULL) {
4982 if (zone->type == dns_zone_master) {
4983 set_resigntime(zone);
4984 resume_signingwithkey(zone);
4985 resume_addnsec3chain(zone);
4986 }
4987
4988 if (zone->type == dns_zone_master &&
4989 !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
4990 dns_zone_isdynamic(zone, false) &&
4991 dns_db_issecure(db))
4992 {
4993 dns_name_t *name;
4994 dns_fixedname_t fixed;
4995 dns_rdataset_t next;
4996
4997 dns_rdataset_init(&next);
4998 name = dns_fixedname_initname(&fixed);
4999
5000 result = dns_db_getsigningtime(db, &next, name);
5001 if (result == ISC_R_SUCCESS) {
5002 isc_stdtime_t timenow;
5003 char namebuf[DNS_NAME_FORMATSIZE];
5004 char typebuf[DNS_RDATATYPE_FORMATSIZE];
5005
5006 isc_stdtime_get(&timenow);
5007 dns_name_format(name, namebuf, sizeof(namebuf));
5008 dns_rdatatype_format(next.covers,
5009 typebuf, sizeof(typebuf));
5010 dnssec_log(zone, ISC_LOG_DEBUG(3),
5011 "next resign: %s/%s "
5012 "in %d seconds", namebuf, typebuf,
5013 next.resign - timenow -
5014 zone->sigresigninginterval);
5015 dns_rdataset_disassociate(&next);
5016 } else {
5017 dnssec_log(zone, ISC_LOG_WARNING,
5018 "signed dynamic zone has no "
5019 "resign event scheduled");
5020 }
5021 }
5022
5023 zone_settimer(zone, &now);
5024 }
5025
5026 /*
5027 * Clear old include list.
5028 */
5029 for (inc = ISC_LIST_HEAD(zone->includes);
5030 inc != NULL;
5031 inc = ISC_LIST_HEAD(zone->includes))
5032 {
5033 ISC_LIST_UNLINK(zone->includes, inc, link);
5034 isc_mem_free(zone->mctx, inc->name);
5035 isc_mem_put(zone->mctx, inc, sizeof(*inc));
5036 }
5037 zone->nincludes = 0;
5038
5039 /*
5040 * Transfer new include list.
5041 */
5042 for (inc = ISC_LIST_HEAD(zone->newincludes);
5043 inc != NULL;
5044 inc = ISC_LIST_HEAD(zone->newincludes))
5045 {
5046 ISC_LIST_UNLINK(zone->newincludes, inc, link);
5047 ISC_LIST_APPEND(zone->includes, inc, link);
5048 zone->nincludes++;
5049 }
5050
5051 if (! dns_db_ispersistent(db)) {
5052 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
5053 ISC_LOG_INFO, "loaded serial %u%s", serial,
5054 dns_db_issecure(db) ? " (DNSSEC signed)" : "");
5055 }
5056
5057 if (!had_db && zone->type == dns_zone_mirror) {
5058 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO,
5059 "mirror zone is now in use");
5060 }
5061
5062 zone->loadtime = loadtime;
5063 goto done;
5064
5065 cleanup:
5066 if (zone->type == dns_zone_key && result != ISC_R_SUCCESS) {
5067 dnssec_log(zone, ISC_LOG_ERROR,
5068 "failed to initialize managed-keys (%s): "
5069 "DNSSEC validation is at risk",
5070 isc_result_totext(result));
5071 }
5072
5073 for (inc = ISC_LIST_HEAD(zone->newincludes);
5074 inc != NULL;
5075 inc = ISC_LIST_HEAD(zone->newincludes))
5076 {
5077 ISC_LIST_UNLINK(zone->newincludes, inc, link);
5078 isc_mem_free(zone->mctx, inc->name);
5079 isc_mem_put(zone->mctx, inc, sizeof(*inc));
5080 }
5081 if (zone->type == dns_zone_slave ||
5082 zone->type == dns_zone_mirror ||
5083 zone->type == dns_zone_stub ||
5084 zone->type == dns_zone_key ||
5085 (zone->type == dns_zone_redirect && zone->masters != NULL))
5086 {
5087 if (result != ISC_R_NOMEMORY) {
5088 if (zone->journal != NULL) {
5089 zone_saveunique(zone, zone->journal,
5090 "jn-XXXXXXXX");
5091 }
5092 if (zone->masterfile != NULL) {
5093 zone_saveunique(zone, zone->masterfile,
5094 "db-XXXXXXXX");
5095 }
5096 }
5097
5098 /* Mark the zone for immediate refresh. */
5099 zone->refreshtime = now;
5100 if (zone->task != NULL) {
5101 zone_settimer(zone, &now);
5102 }
5103 result = ISC_R_SUCCESS;
5104 } else if (zone->type == dns_zone_master ||
5105 zone->type == dns_zone_redirect)
5106 {
5107 if (! (inline_secure(zone) && result == ISC_R_FILENOTFOUND)) {
5108 dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
5109 ISC_LOG_ERROR,
5110 "not loaded due to errors.");
5111 } else if (zone->type == dns_zone_master) {
5112 result = ISC_R_SUCCESS;
5113 }
5114 }
5115
5116 done:
5117 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
5118 /*
5119 * If this is an inline-signed zone and we were called for the raw
5120 * zone, we need to clear DNS_ZONEFLG_LOADPENDING for the secure zone
5121 * as well, but only if this is a reload, not an initial zone load: in
5122 * the former case, zone_postload() will not be run for the secure
5123 * zone; in the latter case, it will be. Check which case we are
5124 * dealing with by consulting the DNS_ZONEFLG_LOADED flag for the
5125 * secure zone: if it is set, this must be a reload.
5126 */
5127 if (inline_raw(zone) &&
5128 DNS_ZONE_FLAG(zone->secure, DNS_ZONEFLG_LOADED))
5129 {
5130 DNS_ZONE_CLRFLAG(zone->secure, DNS_ZONEFLG_LOADPENDING);
5131 }
5132
5133 zone_debuglog(zone, "zone_postload", 99, "done");
5134
5135 return (result);
5136 }
5137
5138 static bool
5139 exit_check(dns_zone_t *zone) {
5140 REQUIRE(LOCKED_ZONE(zone));
5141
5142 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->irefs == 0) {
5143 /*
5144 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
5145 */
5146 INSIST(isc_refcount_current(&zone->erefs) == 0);
5147 return (true);
5148 }
5149 return (false);
5150 }
5151
5152 static bool
5153 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
5154 dns_name_t *name, bool logit)
5155 {
5156 isc_result_t result;
5157 char namebuf[DNS_NAME_FORMATSIZE];
5158 char altbuf[DNS_NAME_FORMATSIZE];
5159 dns_fixedname_t fixed;
5160 dns_name_t *foundname;
5161 int level;
5162
5163 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
5164 return (true);
5165
5166 if (zone->type == dns_zone_master)
5167 level = ISC_LOG_ERROR;
5168 else
5169 level = ISC_LOG_WARNING;
5170
5171 foundname = dns_fixedname_initname(&fixed);
5172
5173 result = dns_db_find(db, name, version, dns_rdatatype_a,
5174 0, 0, NULL, foundname, NULL, NULL);
5175 if (result == ISC_R_SUCCESS)
5176 return (true);
5177
5178 if (result == DNS_R_NXRRSET) {
5179 result = dns_db_find(db, name, version, dns_rdatatype_aaaa,
5180 0, 0, NULL, foundname, NULL, NULL);
5181 if (result == ISC_R_SUCCESS)
5182 return (true);
5183 }
5184
5185 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
5186 result == DNS_R_EMPTYNAME) {
5187 if (logit) {
5188 dns_name_format(name, namebuf, sizeof namebuf);
5189 dns_zone_log(zone, level, "NS '%s' has no address "
5190 "records (A or AAAA)", namebuf);
5191 }
5192 return (false);
5193 }
5194
5195 if (result == DNS_R_CNAME) {
5196 if (logit) {
5197 dns_name_format(name, namebuf, sizeof namebuf);
5198 dns_zone_log(zone, level, "NS '%s' is a CNAME "
5199 "(illegal)", namebuf);
5200 }
5201 return (false);
5202 }
5203
5204 if (result == DNS_R_DNAME) {
5205 if (logit) {
5206 dns_name_format(name, namebuf, sizeof namebuf);
5207 dns_name_format(foundname, altbuf, sizeof altbuf);
5208 dns_zone_log(zone, level, "NS '%s' is below a DNAME "
5209 "'%s' (illegal)", namebuf, altbuf);
5210 }
5211 return (false);
5212 }
5213
5214 return (true);
5215 }
5216
5217 static isc_result_t
5218 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
5219 dns_dbversion_t *version, unsigned int *nscount,
5220 unsigned int *errors, bool logit)
5221 {
5222 isc_result_t result;
5223 unsigned int count = 0;
5224 unsigned int ecount = 0;
5225 dns_rdataset_t rdataset;
5226 dns_rdata_t rdata;
5227 dns_rdata_ns_t ns;
5228
5229 dns_rdataset_init(&rdataset);
5230 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
5231 dns_rdatatype_none, 0, &rdataset, NULL);
5232 if (result == ISC_R_NOTFOUND) {
5233 INSIST(!dns_rdataset_isassociated(&rdataset));
5234 goto success;
5235 }
5236 if (result != ISC_R_SUCCESS) {
5237 INSIST(!dns_rdataset_isassociated(&rdataset));
5238 goto invalidate_rdataset;
5239 }
5240
5241 result = dns_rdataset_first(&rdataset);
5242 while (result == ISC_R_SUCCESS) {
5243 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
5244 (zone->type == dns_zone_master ||
5245 zone->type == dns_zone_slave ||
5246 zone->type == dns_zone_mirror))
5247 {
5248 dns_rdata_init(&rdata);
5249 dns_rdataset_current(&rdataset, &rdata);
5250 result = dns_rdata_tostruct(&rdata, &ns, NULL);
5251 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5252 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
5253 !zone_check_ns(zone, db, version, &ns.name, logit))
5254 ecount++;
5255 }
5256 count++;
5257 result = dns_rdataset_next(&rdataset);
5258 }
5259 dns_rdataset_disassociate(&rdataset);
5260
5261 success:
5262 if (nscount != NULL)
5263 *nscount = count;
5264 if (errors != NULL)
5265 *errors = ecount;
5266
5267 result = ISC_R_SUCCESS;
5268
5269 invalidate_rdataset:
5270 dns_rdataset_invalidate(&rdataset);
5271
5272 return (result);
5273 }
5274
5275 static isc_result_t
5276 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
5277 unsigned int *soacount,
5278 uint32_t *serial, uint32_t *refresh,
5279 uint32_t *retry, uint32_t *expire,
5280 uint32_t *minimum)
5281 {
5282 isc_result_t result;
5283 unsigned int count;
5284 dns_rdataset_t rdataset;
5285 dns_rdata_t rdata = DNS_RDATA_INIT;
5286 dns_rdata_soa_t soa;
5287
5288 dns_rdataset_init(&rdataset);
5289 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
5290 dns_rdatatype_none, 0, &rdataset, NULL);
5291 if (result == ISC_R_NOTFOUND) {
5292 INSIST(!dns_rdataset_isassociated(&rdataset));
5293 if (soacount != NULL)
5294 *soacount = 0;
5295 if (serial != NULL)
5296 *serial = 0;
5297 if (refresh != NULL)
5298 *refresh = 0;
5299 if (retry != NULL)
5300 *retry = 0;
5301 if (expire != NULL)
5302 *expire = 0;
5303 if (minimum != NULL)
5304 *minimum = 0;
5305 result = ISC_R_SUCCESS;
5306 goto invalidate_rdataset;
5307 }
5308 if (result != ISC_R_SUCCESS) {
5309 INSIST(!dns_rdataset_isassociated(&rdataset));
5310 goto invalidate_rdataset;
5311 }
5312
5313 count = 0;
5314 result = dns_rdataset_first(&rdataset);
5315 while (result == ISC_R_SUCCESS) {
5316 dns_rdata_init(&rdata);
5317 dns_rdataset_current(&rdataset, &rdata);
5318 count++;
5319 if (count == 1) {
5320 result = dns_rdata_tostruct(&rdata, &soa, NULL);
5321 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5322 }
5323
5324 result = dns_rdataset_next(&rdataset);
5325 dns_rdata_reset(&rdata);
5326 }
5327 dns_rdataset_disassociate(&rdataset);
5328
5329 if (soacount != NULL)
5330 *soacount = count;
5331
5332 if (count > 0) {
5333 if (serial != NULL)
5334 *serial = soa.serial;
5335 if (refresh != NULL)
5336 *refresh = soa.refresh;
5337 if (retry != NULL)
5338 *retry = soa.retry;
5339 if (expire != NULL)
5340 *expire = soa.expire;
5341 if (minimum != NULL)
5342 *minimum = soa.minimum;
5343 } else {
5344 if (soacount != NULL)
5345 *soacount = 0;
5346 if (serial != NULL)
5347 *serial = 0;
5348 if (refresh != NULL)
5349 *refresh = 0;
5350 if (retry != NULL)
5351 *retry = 0;
5352 if (expire != NULL)
5353 *expire = 0;
5354 if (minimum != NULL)
5355 *minimum = 0;
5356 }
5357
5358 result = ISC_R_SUCCESS;
5359
5360 invalidate_rdataset:
5361 dns_rdataset_invalidate(&rdataset);
5362
5363 return (result);
5364 }
5365
5366 /*
5367 * zone must be locked.
5368 */
5369 static isc_result_t
5370 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
5371 unsigned int *soacount, uint32_t *serial,
5372 uint32_t *refresh, uint32_t *retry,
5373 uint32_t *expire, uint32_t *minimum,
5374 unsigned int *errors)
5375 {
5376 isc_result_t result;
5377 isc_result_t answer = ISC_R_SUCCESS;
5378 dns_dbversion_t *version = NULL;
5379 dns_dbnode_t *node;
5380
5381 REQUIRE(db != NULL);
5382 REQUIRE(zone != NULL);
5383
5384 dns_db_currentversion(db, &version);
5385
5386 if (nscount != NULL)
5387 *nscount = 0;
5388 if (soacount != NULL)
5389 *soacount = 0;
5390 if (serial != NULL)
5391 *serial = 0;
5392 if (refresh != NULL)
5393 *refresh = 0;
5394 if (retry != NULL)
5395 *retry = 0;
5396 if (expire != NULL)
5397 *expire = 0;
5398 if (errors != NULL)
5399 *errors = 0;
5400
5401 node = NULL;
5402 result = dns_db_findnode(db, &zone->origin, false, &node);
5403 if (result != ISC_R_SUCCESS) {
5404 answer = result;
5405 goto closeversion;
5406 }
5407
5408 if (nscount != NULL || errors != NULL) {
5409 result = zone_count_ns_rr(zone, db, node, version,
5410 nscount, errors, true);
5411 if (result != ISC_R_SUCCESS)
5412 answer = result;
5413 }
5414
5415 if (soacount != NULL || serial != NULL || refresh != NULL
5416 || retry != NULL || expire != NULL || minimum != NULL) {
5417 result = zone_load_soa_rr(db, node, version, soacount,
5418 serial, refresh, retry, expire,
5419 minimum);
5420 if (result != ISC_R_SUCCESS)
5421 answer = result;
5422 }
5423
5424 dns_db_detachnode(db, &node);
5425 closeversion:
5426 dns_db_closeversion(db, &version, false);
5427
5428 return (answer);
5429 }
5430
5431 void
5432 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
5433 REQUIRE(DNS_ZONE_VALID(source));
5434 REQUIRE(target != NULL && *target == NULL);
5435 isc_refcount_increment(&source->erefs);
5436 *target = source;
5437 }
5438
5439 void
5440 dns_zone_detach(dns_zone_t **zonep) {
5441 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
5442 dns_zone_t *zone = *zonep;
5443 *zonep = NULL;
5444
5445 bool free_now = false;
5446 dns_zone_t *raw = NULL;
5447 dns_zone_t *secure = NULL;
5448 if (isc_refcount_decrement(&zone->erefs) == 1) {
5449 isc_refcount_destroy(&zone->erefs);
5450
5451 LOCK_ZONE(zone);
5452 INSIST(zone != zone->raw);
5453 /*
5454 * We just detached the last external reference.
5455 */
5456 if (zone->task != NULL) {
5457 /*
5458 * This zone is being managed. Post
5459 * its control event and let it clean
5460 * up synchronously in the context of
5461 * its task.
5462 */
5463 isc_event_t *ev = &zone->ctlevent;
5464 isc_task_send(zone->task, &ev);
5465 } else {
5466 /*
5467 * This zone is not being managed; it has
5468 * no task and can have no outstanding
5469 * events. Free it immediately.
5470 */
5471 /*
5472 * Unmanaged zones should not have non-null views;
5473 * we have no way of detaching from the view here
5474 * without causing deadlock because this code is called
5475 * with the view already locked.
5476 */
5477 INSIST(zone->view == NULL);
5478 free_now = true;
5479 raw = zone->raw;
5480 zone->raw = NULL;
5481 secure = zone->secure;
5482 zone->secure = NULL;
5483 }
5484 UNLOCK_ZONE(zone);
5485 }
5486 if (free_now) {
5487 if (raw != NULL) {
5488 dns_zone_detach(&raw);
5489 }
5490 if (secure != NULL) {
5491 dns_zone_idetach(&secure);
5492 }
5493 zone_free(zone);
5494 }
5495 }
5496
5497 void
5498 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
5499 REQUIRE(DNS_ZONE_VALID(source));
5500 REQUIRE(target != NULL && *target == NULL);
5501 LOCK_ZONE(source);
5502 zone_iattach(source, target);
5503 UNLOCK_ZONE(source);
5504 }
5505
5506 static void
5507 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
5508
5509 /*
5510 * 'source' locked by caller.
5511 */
5512 REQUIRE(LOCKED_ZONE(source));
5513 REQUIRE(DNS_ZONE_VALID(source));
5514 REQUIRE(target != NULL && *target == NULL);
5515 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
5516 source->irefs++;
5517 INSIST(source->irefs != 0);
5518 *target = source;
5519 }
5520
5521 static void
5522 zone_idetach(dns_zone_t **zonep) {
5523 dns_zone_t *zone;
5524
5525 /*
5526 * 'zone' locked by caller.
5527 */
5528 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
5529 zone = *zonep;
5530 REQUIRE(LOCKED_ZONE(*zonep));
5531 *zonep = NULL;
5532
5533 INSIST(zone->irefs > 0);
5534 zone->irefs--;
5535 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
5536 }
5537
5538 void
5539 dns_zone_idetach(dns_zone_t **zonep) {
5540 dns_zone_t *zone;
5541 bool free_needed;
5542
5543 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
5544 zone = *zonep;
5545 *zonep = NULL;
5546
5547 LOCK_ZONE(zone);
5548 INSIST(zone->irefs > 0);
5549 zone->irefs--;
5550 free_needed = exit_check(zone);
5551 UNLOCK_ZONE(zone);
5552 if (free_needed)
5553 zone_free(zone);
5554 }
5555
5556 isc_mem_t *
5557 dns_zone_getmctx(dns_zone_t *zone) {
5558 REQUIRE(DNS_ZONE_VALID(zone));
5559
5560 return (zone->mctx);
5561 }
5562
5563 dns_zonemgr_t *
5564 dns_zone_getmgr(dns_zone_t *zone) {
5565 REQUIRE(DNS_ZONE_VALID(zone));
5566
5567 return (zone->zmgr);
5568 }
5569
5570 void
5571 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, bool value) {
5572 REQUIRE(DNS_ZONE_VALID(zone));
5573
5574 LOCK_ZONE(zone);
5575 if (value)
5576 DNS_ZONE_SETFLAG(zone, flags);
5577 else
5578 DNS_ZONE_CLRFLAG(zone, flags);
5579 UNLOCK_ZONE(zone);
5580 }
5581
5582 void
5583 dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option,
5584 bool value)
5585 {
5586 REQUIRE(DNS_ZONE_VALID(zone));
5587
5588 LOCK_ZONE(zone);
5589 if (value)
5590 zone->options |= option;
5591 else
5592 zone->options &= ~option;
5593 UNLOCK_ZONE(zone);
5594 }
5595
5596 dns_zoneopt_t
5597 dns_zone_getoptions(dns_zone_t *zone) {
5598 REQUIRE(DNS_ZONE_VALID(zone));
5599
5600 return (zone->options);
5601 }
5602
5603 void
5604 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, bool value)
5605 {
5606 REQUIRE(DNS_ZONE_VALID(zone));
5607
5608 LOCK_ZONE(zone);
5609 if (value)
5610 zone->keyopts |= keyopt;
5611 else
5612 zone->keyopts &= ~keyopt;
5613 UNLOCK_ZONE(zone);
5614 }
5615
5616 unsigned int
5617 dns_zone_getkeyopts(dns_zone_t *zone) {
5618
5619 REQUIRE(DNS_ZONE_VALID(zone));
5620
5621 return (zone->keyopts);
5622 }
5623
5624 isc_result_t
5625 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
5626 REQUIRE(DNS_ZONE_VALID(zone));
5627
5628 LOCK_ZONE(zone);
5629 zone->xfrsource4 = *xfrsource;
5630 UNLOCK_ZONE(zone);
5631
5632 return (ISC_R_SUCCESS);
5633 }
5634
5635 isc_sockaddr_t *
5636 dns_zone_getxfrsource4(dns_zone_t *zone) {
5637 REQUIRE(DNS_ZONE_VALID(zone));
5638 return (&zone->xfrsource4);
5639 }
5640
5641 isc_result_t
5642 dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5643 REQUIRE(DNS_ZONE_VALID(zone));
5644
5645 LOCK_ZONE(zone);
5646 zone->xfrsource4dscp = dscp;
5647 UNLOCK_ZONE(zone);
5648
5649 return (ISC_R_SUCCESS);
5650 }
5651
5652 isc_dscp_t
5653 dns_zone_getxfrsource4dscp(dns_zone_t *zone) {
5654 REQUIRE(DNS_ZONE_VALID(zone));
5655 return (zone->xfrsource4dscp);
5656 }
5657
5658 isc_result_t
5659 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
5660 REQUIRE(DNS_ZONE_VALID(zone));
5661
5662 LOCK_ZONE(zone);
5663 zone->xfrsource6 = *xfrsource;
5664 UNLOCK_ZONE(zone);
5665
5666 return (ISC_R_SUCCESS);
5667 }
5668
5669 isc_sockaddr_t *
5670 dns_zone_getxfrsource6(dns_zone_t *zone) {
5671 REQUIRE(DNS_ZONE_VALID(zone));
5672 return (&zone->xfrsource6);
5673 }
5674
5675 isc_dscp_t
5676 dns_zone_getxfrsource6dscp(dns_zone_t *zone) {
5677 REQUIRE(DNS_ZONE_VALID(zone));
5678 return (zone->xfrsource6dscp);
5679 }
5680
5681 isc_result_t
5682 dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5683 REQUIRE(DNS_ZONE_VALID(zone));
5684
5685 LOCK_ZONE(zone);
5686 zone->xfrsource6dscp = dscp;
5687 UNLOCK_ZONE(zone);
5688
5689 return (ISC_R_SUCCESS);
5690 }
5691
5692 isc_result_t
5693 dns_zone_setaltxfrsource4(dns_zone_t *zone,
5694 const isc_sockaddr_t *altxfrsource)
5695 {
5696 REQUIRE(DNS_ZONE_VALID(zone));
5697
5698 LOCK_ZONE(zone);
5699 zone->altxfrsource4 = *altxfrsource;
5700 UNLOCK_ZONE(zone);
5701
5702 return (ISC_R_SUCCESS);
5703 }
5704
5705 isc_sockaddr_t *
5706 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
5707 REQUIRE(DNS_ZONE_VALID(zone));
5708 return (&zone->altxfrsource4);
5709 }
5710
5711 isc_result_t
5712 dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5713 REQUIRE(DNS_ZONE_VALID(zone));
5714
5715 LOCK_ZONE(zone);
5716 zone->altxfrsource4dscp = dscp;
5717 UNLOCK_ZONE(zone);
5718
5719 return (ISC_R_SUCCESS);
5720 }
5721
5722 isc_dscp_t
5723 dns_zone_getaltxfrsource4dscp(dns_zone_t *zone) {
5724 REQUIRE(DNS_ZONE_VALID(zone));
5725 return (zone->altxfrsource4dscp);
5726 }
5727
5728 isc_result_t
5729 dns_zone_setaltxfrsource6(dns_zone_t *zone,
5730 const isc_sockaddr_t *altxfrsource)
5731 {
5732 REQUIRE(DNS_ZONE_VALID(zone));
5733
5734 LOCK_ZONE(zone);
5735 zone->altxfrsource6 = *altxfrsource;
5736 UNLOCK_ZONE(zone);
5737
5738 return (ISC_R_SUCCESS);
5739 }
5740
5741 isc_sockaddr_t *
5742 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
5743 REQUIRE(DNS_ZONE_VALID(zone));
5744 return (&zone->altxfrsource6);
5745 }
5746
5747 isc_result_t
5748 dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5749 REQUIRE(DNS_ZONE_VALID(zone));
5750
5751 LOCK_ZONE(zone);
5752 zone->altxfrsource6dscp = dscp;
5753 UNLOCK_ZONE(zone);
5754
5755 return (ISC_R_SUCCESS);
5756 }
5757
5758 isc_dscp_t
5759 dns_zone_getaltxfrsource6dscp(dns_zone_t *zone) {
5760 REQUIRE(DNS_ZONE_VALID(zone));
5761 return (zone->altxfrsource6dscp);
5762 }
5763
5764 isc_result_t
5765 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
5766 REQUIRE(DNS_ZONE_VALID(zone));
5767
5768 LOCK_ZONE(zone);
5769 zone->notifysrc4 = *notifysrc;
5770 UNLOCK_ZONE(zone);
5771
5772 return (ISC_R_SUCCESS);
5773 }
5774
5775 isc_sockaddr_t *
5776 dns_zone_getnotifysrc4(dns_zone_t *zone) {
5777 REQUIRE(DNS_ZONE_VALID(zone));
5778 return (&zone->notifysrc4);
5779 }
5780
5781 isc_result_t
5782 dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5783 REQUIRE(DNS_ZONE_VALID(zone));
5784
5785 LOCK_ZONE(zone);
5786 zone->notifysrc4dscp = dscp;
5787 UNLOCK_ZONE(zone);
5788
5789 return (ISC_R_SUCCESS);
5790 }
5791
5792 isc_dscp_t
5793 dns_zone_getnotifysrc4dscp(dns_zone_t *zone) {
5794 REQUIRE(DNS_ZONE_VALID(zone));
5795 return (zone->notifysrc4dscp);
5796 }
5797
5798 isc_result_t
5799 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
5800 REQUIRE(DNS_ZONE_VALID(zone));
5801
5802 LOCK_ZONE(zone);
5803 zone->notifysrc6 = *notifysrc;
5804 UNLOCK_ZONE(zone);
5805
5806 return (ISC_R_SUCCESS);
5807 }
5808
5809 isc_sockaddr_t *
5810 dns_zone_getnotifysrc6(dns_zone_t *zone) {
5811 REQUIRE(DNS_ZONE_VALID(zone));
5812 return (&zone->notifysrc6);
5813 }
5814
5815 static bool
5816 same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist,
5817 uint32_t count)
5818 {
5819 unsigned int i;
5820
5821 for (i = 0; i < count; i++)
5822 if (!isc_sockaddr_equal(&oldlist[i], &newlist[i]))
5823 return (false);
5824 return (true);
5825 }
5826
5827 static bool
5828 same_keynames(dns_name_t * const *oldlist, dns_name_t * const *newlist,
5829 uint32_t count)
5830 {
5831 unsigned int i;
5832
5833 if (oldlist == NULL && newlist == NULL)
5834 return (true);
5835 if (oldlist == NULL || newlist == NULL)
5836 return (false);
5837
5838 for (i = 0; i < count; i++) {
5839 if (oldlist[i] == NULL && newlist[i] == NULL)
5840 continue;
5841 if (oldlist[i] == NULL || newlist[i] == NULL ||
5842 !dns_name_equal(oldlist[i], newlist[i]))
5843 return (false);
5844 }
5845 return (true);
5846 }
5847
5848 static void
5849 clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
5850 dns_name_t ***keynamesp, unsigned int *countp,
5851 isc_mem_t *mctx)
5852 {
5853 unsigned int count;
5854 isc_sockaddr_t *addrs;
5855 isc_dscp_t *dscps;
5856 dns_name_t **keynames;
5857
5858 REQUIRE(countp != NULL && addrsp != NULL && dscpsp != NULL &&
5859 keynamesp != NULL);
5860
5861 count = *countp;
5862 *countp = 0;
5863 addrs = *addrsp;
5864 *addrsp = NULL;
5865 dscps = *dscpsp;
5866 *dscpsp = NULL;
5867 keynames = *keynamesp;
5868 *keynamesp = NULL;
5869
5870 if (addrs != NULL)
5871 isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
5872
5873 if (dscps != NULL)
5874 isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t));
5875
5876 if (keynames != NULL) {
5877 unsigned int i;
5878 for (i = 0; i < count; i++) {
5879 if (keynames[i] != NULL) {
5880 dns_name_free(keynames[i], mctx);
5881 isc_mem_put(mctx, keynames[i],
5882 sizeof(dns_name_t));
5883 keynames[i] = NULL;
5884 }
5885 }
5886 isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
5887 }
5888 }
5889
5890 static isc_result_t
5891 set_addrkeylist(unsigned int count,
5892 const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp,
5893 const isc_dscp_t *dscp, isc_dscp_t **newdscpp,
5894 dns_name_t **names, dns_name_t ***newnamesp,
5895 isc_mem_t *mctx)
5896 {
5897 isc_result_t result;
5898 isc_sockaddr_t *newaddrs = NULL;
5899 isc_dscp_t *newdscp = NULL;
5900 dns_name_t **newnames = NULL;
5901 unsigned int i;
5902
5903 REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
5904 REQUIRE(newdscpp != NULL && *newdscpp == NULL);
5905 REQUIRE(newnamesp != NULL && *newnamesp == NULL);
5906
5907 newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
5908 if (newaddrs == NULL)
5909 return (ISC_R_NOMEMORY);
5910 memmove(newaddrs, addrs, count * sizeof(*newaddrs));
5911
5912 if (dscp != NULL) {
5913 newdscp = isc_mem_get(mctx, count * sizeof(*newdscp));
5914 if (newdscp == NULL) {
5915 isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
5916 return (ISC_R_NOMEMORY);
5917 }
5918 memmove(newdscp, dscp, count * sizeof(*newdscp));
5919 } else
5920 newdscp = NULL;
5921
5922 if (names != NULL) {
5923 newnames = isc_mem_get(mctx, count * sizeof(*newnames));
5924 if (newnames == NULL) {
5925 if (newdscp != NULL)
5926 isc_mem_put(mctx, newdscp,
5927 count * sizeof(*newdscp));
5928 isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
5929 return (ISC_R_NOMEMORY);
5930 }
5931 for (i = 0; i < count; i++)
5932 newnames[i] = NULL;
5933 for (i = 0; i < count; i++) {
5934 if (names[i] != NULL) {
5935 newnames[i] = isc_mem_get(mctx,
5936 sizeof(dns_name_t));
5937 if (newnames[i] == NULL)
5938 goto allocfail;
5939 dns_name_init(newnames[i], NULL);
5940 result = dns_name_dup(names[i], mctx,
5941 newnames[i]);
5942 if (result != ISC_R_SUCCESS) {
5943 allocfail:
5944 for (i = 0; i < count; i++)
5945 if (newnames[i] != NULL)
5946 dns_name_free(
5947 newnames[i],
5948 mctx);
5949 isc_mem_put(mctx, newaddrs,
5950 count * sizeof(*newaddrs));
5951 isc_mem_put(mctx, newdscp,
5952 count * sizeof(*newdscp));
5953 isc_mem_put(mctx, newnames,
5954 count * sizeof(*newnames));
5955 return (ISC_R_NOMEMORY);
5956 }
5957 }
5958 }
5959 } else
5960 newnames = NULL;
5961
5962 *newdscpp = newdscp;
5963 *newaddrsp = newaddrs;
5964 *newnamesp = newnames;
5965 return (ISC_R_SUCCESS);
5966 }
5967
5968 isc_result_t
5969 dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
5970 REQUIRE(DNS_ZONE_VALID(zone));
5971
5972 LOCK_ZONE(zone);
5973 zone->notifysrc6dscp = dscp;
5974 UNLOCK_ZONE(zone);
5975
5976 return (ISC_R_SUCCESS);
5977 }
5978
5979 isc_dscp_t
5980 dns_zone_getnotifysrc6dscp(dns_zone_t *zone) {
5981 REQUIRE(DNS_ZONE_VALID(zone));
5982 return (zone->notifysrc6dscp);
5983 }
5984
5985 isc_result_t
5986 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
5987 uint32_t count)
5988 {
5989 return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, NULL,
5990 count));
5991 }
5992
5993 isc_result_t
5994 dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
5995 dns_name_t **keynames, uint32_t count)
5996 {
5997 return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, keynames,
5998 count));
5999 }
6000
6001 isc_result_t
6002 dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
6003 const isc_dscp_t *dscps, dns_name_t **keynames,
6004 uint32_t count)
6005 {
6006 isc_result_t result;
6007 isc_sockaddr_t *newaddrs = NULL;
6008 isc_dscp_t *newdscps = NULL;
6009 dns_name_t **newnames = NULL;
6010
6011 REQUIRE(DNS_ZONE_VALID(zone));
6012 REQUIRE(count == 0 || notify != NULL);
6013 if (keynames != NULL)
6014 REQUIRE(count != 0);
6015
6016 LOCK_ZONE(zone);
6017
6018 if (count == zone->notifycnt &&
6019 same_addrs(zone->notify, notify, count) &&
6020 same_keynames(zone->notifykeynames, keynames, count))
6021 goto unlock;
6022
6023 clear_addresskeylist(&zone->notify, &zone->notifydscp,
6024 &zone->notifykeynames, &zone->notifycnt,
6025 zone->mctx);
6026
6027 if (count == 0)
6028 goto unlock;
6029
6030 /*
6031 * Set up the notify and notifykey lists
6032 */
6033 result = set_addrkeylist(count, notify, &newaddrs, dscps, &newdscps,
6034 keynames, &newnames, zone->mctx);
6035 if (result != ISC_R_SUCCESS)
6036 goto unlock;
6037
6038 /*
6039 * Everything is ok so attach to the zone.
6040 */
6041 zone->notify = newaddrs;
6042 zone->notifydscp = newdscps;
6043 zone->notifykeynames = newnames;
6044 zone->notifycnt = count;
6045 unlock:
6046 UNLOCK_ZONE(zone);
6047 return (ISC_R_SUCCESS);
6048 }
6049
6050 isc_result_t
6051 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
6052 uint32_t count)
6053 {
6054 isc_result_t result;
6055
6056 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
6057 return (result);
6058 }
6059
6060 isc_result_t
6061 dns_zone_setmasterswithkeys(dns_zone_t *zone,
6062 const isc_sockaddr_t *masters,
6063 dns_name_t **keynames,
6064 uint32_t count)
6065 {
6066 isc_result_t result = ISC_R_SUCCESS;
6067 isc_sockaddr_t *newaddrs = NULL;
6068 isc_dscp_t *newdscps = NULL;
6069 dns_name_t **newnames = NULL;
6070 bool *newok;
6071 unsigned int i;
6072
6073 REQUIRE(DNS_ZONE_VALID(zone));
6074 REQUIRE(count == 0 || masters != NULL);
6075 if (keynames != NULL) {
6076 REQUIRE(count != 0);
6077 }
6078
6079 LOCK_ZONE(zone);
6080 /*
6081 * The refresh code assumes that 'masters' wouldn't change under it.
6082 * If it will change then kill off any current refresh in progress
6083 * and update the masters info. If it won't change then we can just
6084 * unlock and exit.
6085 */
6086 if (count != zone->masterscnt ||
6087 !same_addrs(zone->masters, masters, count) ||
6088 !same_keynames(zone->masterkeynames, keynames, count)) {
6089 if (zone->request != NULL)
6090 dns_request_cancel(zone->request);
6091 } else
6092 goto unlock;
6093
6094 /*
6095 * This needs to happen before clear_addresskeylist() sets
6096 * zone->masterscnt to 0:
6097 */
6098 if (zone->mastersok != NULL) {
6099 isc_mem_put(zone->mctx, zone->mastersok,
6100 zone->masterscnt * sizeof(bool));
6101 zone->mastersok = NULL;
6102 }
6103 clear_addresskeylist(&zone->masters, &zone->masterdscps,
6104 &zone->masterkeynames, &zone->masterscnt,
6105 zone->mctx);
6106 /*
6107 * If count == 0, don't allocate any space for masters, mastersok or
6108 * keynames so internally, those pointers are NULL if count == 0
6109 */
6110 if (count == 0)
6111 goto unlock;
6112
6113 /*
6114 * mastersok must contain count elements
6115 */
6116 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
6117 if (newok == NULL) {
6118 result = ISC_R_NOMEMORY;
6119 isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs));
6120 goto unlock;
6121 };
6122 for (i = 0; i < count; i++)
6123 newok[i] = false;
6124
6125 /*
6126 * Now set up the masters and masterkey lists
6127 */
6128 result = set_addrkeylist(count, masters, &newaddrs, NULL, &newdscps,
6129 keynames, &newnames, zone->mctx);
6130 INSIST(newdscps == NULL);
6131 if (result != ISC_R_SUCCESS) {
6132 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
6133 goto unlock;
6134 }
6135
6136 /*
6137 * Everything is ok so attach to the zone.
6138 */
6139 zone->curmaster = 0;
6140 zone->mastersok = newok;
6141 zone->masters = newaddrs;
6142 zone->masterdscps = newdscps;
6143 zone->masterkeynames = newnames;
6144 zone->masterscnt = count;
6145 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
6146
6147 unlock:
6148 UNLOCK_ZONE(zone);
6149 return (result);
6150 }
6151
6152 isc_result_t
6153 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
6154 isc_result_t result = ISC_R_SUCCESS;
6155
6156 REQUIRE(DNS_ZONE_VALID(zone));
6157
6158 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6159 if (zone->db == NULL)
6160 result = DNS_R_NOTLOADED;
6161 else
6162 dns_db_attach(zone->db, dpb);
6163 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6164
6165 return (result);
6166 }
6167
6168 void
6169 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
6170 REQUIRE(DNS_ZONE_VALID(zone));
6171 REQUIRE(zone->type == dns_zone_staticstub);
6172
6173 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
6174 REQUIRE(zone->db == NULL);
6175 dns_db_attach(db, &zone->db);
6176 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
6177 }
6178
6179 /*
6180 * Co-ordinates the starting of routine jobs.
6181 */
6182 void
6183 dns_zone_maintenance(dns_zone_t *zone) {
6184 const char me[] = "dns_zone_maintenance";
6185 isc_time_t now;
6186
6187 REQUIRE(DNS_ZONE_VALID(zone));
6188 ENTER;
6189
6190 LOCK_ZONE(zone);
6191 TIME_NOW(&now);
6192 zone_settimer(zone, &now);
6193 UNLOCK_ZONE(zone);
6194 }
6195
6196 static inline bool
6197 was_dumping(dns_zone_t *zone) {
6198
6199 REQUIRE(LOCKED_ZONE(zone));
6200
6201 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
6202 return (true);
6203 }
6204
6205 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
6206 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
6207 isc_time_settoepoch(&zone->dumptime);
6208 return (false);
6209 }
6210
6211 /*%
6212 * Find up to 'maxkeys' DNSSEC keys used for signing version 'ver' of database
6213 * 'db' for zone 'zone' in its key directory, then load these keys into 'keys'.
6214 * Only load the public part of a given key if it is not active at timestamp
6215 * 'now'. Store the number of keys found in 'nkeys'.
6216 */
6217 isc_result_t
6218 dns__zone_findkeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
6219 isc_stdtime_t now, isc_mem_t *mctx, unsigned int maxkeys,
6220 dst_key_t **keys, unsigned int *nkeys)
6221 {
6222 isc_result_t result;
6223 dns_dbnode_t *node = NULL;
6224 const char *directory = dns_zone_getkeydirectory(zone);
6225
6226 CHECK(dns_db_findnode(db, dns_db_origin(db), false, &node));
6227 memset(keys, 0, sizeof(*keys) * maxkeys);
6228 result = dns_dnssec_findzonekeys(db, ver, node, dns_db_origin(db),
6229 directory, now, mctx, maxkeys, keys,
6230 nkeys);
6231 if (result == ISC_R_NOTFOUND)
6232 result = ISC_R_SUCCESS;
6233 failure:
6234 if (node != NULL)
6235 dns_db_detachnode(db, &node);
6236 return (result);
6237 }
6238
6239 static isc_result_t
6240 offline(dns_db_t *db, dns_dbversion_t *ver, dns__zonediff_t *zonediff,
6241 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
6242 {
6243 isc_result_t result;
6244
6245 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
6246 return (ISC_R_SUCCESS);
6247 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
6248 name, ttl, rdata);
6249 if (result != ISC_R_SUCCESS)
6250 return (result);
6251 rdata->flags |= DNS_RDATA_OFFLINE;
6252 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
6253 name, ttl, rdata);
6254 zonediff->offline = true;
6255 return (result);
6256 }
6257
6258 static void
6259 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
6260 {
6261 unsigned int delta;
6262 char timebuf[80];
6263
6264 zone->key_expiry = when;
6265 if (when <= now) {
6266 dns_zone_log(zone, ISC_LOG_ERROR,
6267 "DNSKEY RRSIG(s) have expired");
6268 isc_time_settoepoch(&zone->keywarntime);
6269 } else if (when < now + 7 * 24 * 3600) {
6270 isc_time_t t;
6271 isc_time_set(&t, when, 0);
6272 isc_time_formattimestamp(&t, timebuf, 80);
6273 dns_zone_log(zone, ISC_LOG_WARNING,
6274 "DNSKEY RRSIG(s) will expire within 7 days: %s",
6275 timebuf);
6276 delta = when - now;
6277 delta--; /* loop prevention */
6278 delta /= 24 * 3600; /* to whole days */
6279 delta *= 24 * 3600; /* to seconds */
6280 isc_time_set(&zone->keywarntime, when - delta, 0);
6281 } else {
6282 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
6283 isc_time_formattimestamp(&zone->keywarntime, timebuf, 80);
6284 dns_zone_log(zone, ISC_LOG_NOTICE,
6285 "setting keywarntime to %s", timebuf);
6286 }
6287 }
6288
6289 /*
6290 * Helper function to del_sigs(). We don't want to delete RRSIGs that
6291 * have no new key.
6292 */
6293 static bool
6294 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
6295 bool *warn)
6296 {
6297 unsigned int i = 0;
6298 bool have_ksk = false, have_zsk = false;
6299 bool have_pksk = false, have_pzsk = false;
6300
6301 for (i = 0; i < nkeys; i++) {
6302 if (rrsig_ptr->algorithm != dst_key_alg(keys[i]))
6303 continue;
6304 if (dst_key_isprivate(keys[i])) {
6305 if (KSK(keys[i]))
6306 have_ksk = have_pksk = true;
6307 else
6308 have_zsk = have_pzsk = true;
6309 } else {
6310 if (KSK(keys[i]))
6311 have_ksk = true;
6312 else
6313 have_zsk = true;
6314 }
6315 }
6316
6317 if (have_zsk && have_ksk && !have_pzsk)
6318 *warn = true;
6319
6320 /*
6321 * It's okay to delete a signature if there is an active key
6322 * with the same algorithm to replace it.
6323 */
6324 if (have_pksk || have_pzsk)
6325 return (true);
6326
6327 /*
6328 * Failing that, it is *not* okay to delete a signature
6329 * if the associated public key is still in the DNSKEY RRset
6330 */
6331 for (i = 0; i < nkeys; i++) {
6332 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
6333 (rrsig_ptr->keyid == dst_key_id(keys[i])))
6334 return (false);
6335 }
6336
6337 /*
6338 * But if the key is gone, then go ahead.
6339 */
6340 return (true);
6341 }
6342
6343 /*
6344 * Delete expired RRsigs and any RRsigs we are about to re-sign.
6345 * See also update.c:del_keysigs().
6346 */
6347 static isc_result_t
6348 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
6349 dns_rdatatype_t type, dns__zonediff_t *zonediff, dst_key_t **keys,
6350 unsigned int nkeys, isc_stdtime_t now, bool incremental)
6351 {
6352 isc_result_t result;
6353 dns_dbnode_t *node = NULL;
6354 dns_rdataset_t rdataset;
6355 unsigned int i;
6356 dns_rdata_rrsig_t rrsig;
6357 bool found;
6358 int64_t timewarn = 0, timemaybe = 0;
6359
6360 dns_rdataset_init(&rdataset);
6361
6362 if (type == dns_rdatatype_nsec3)
6363 result = dns_db_findnsec3node(db, name, false, &node);
6364 else
6365 result = dns_db_findnode(db, name, false, &node);
6366 if (result == ISC_R_NOTFOUND)
6367 return (ISC_R_SUCCESS);
6368 if (result != ISC_R_SUCCESS)
6369 goto failure;
6370 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
6371 (isc_stdtime_t) 0, &rdataset, NULL);
6372 dns_db_detachnode(db, &node);
6373
6374 if (result == ISC_R_NOTFOUND) {
6375 INSIST(!dns_rdataset_isassociated(&rdataset));
6376 return (ISC_R_SUCCESS);
6377 }
6378 if (result != ISC_R_SUCCESS) {
6379 INSIST(!dns_rdataset_isassociated(&rdataset));
6380 goto failure;
6381 }
6382
6383 for (result = dns_rdataset_first(&rdataset);
6384 result == ISC_R_SUCCESS;
6385 result = dns_rdataset_next(&rdataset)) {
6386 dns_rdata_t rdata = DNS_RDATA_INIT;
6387
6388 dns_rdataset_current(&rdataset, &rdata);
6389 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
6390 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6391
6392 if (type != dns_rdatatype_dnskey) {
6393 bool warn = false, deleted = false;
6394 if (delsig_ok(&rrsig, keys, nkeys, &warn)) {
6395 result = update_one_rr(db, ver, zonediff->diff,
6396 DNS_DIFFOP_DELRESIGN, name,
6397 rdataset.ttl, &rdata);
6398 if (result != ISC_R_SUCCESS)
6399 break;
6400 deleted = true;
6401 }
6402 if (warn) {
6403 /*
6404 * At this point, we've got an RRSIG,
6405 * which is signed by an inactive key.
6406 * An administrator needs to provide a new
6407 * key/alg, but until that time, we want to
6408 * keep the old RRSIG. Marking the key as
6409 * offline will prevent us spinning waiting
6410 * for the private part.
6411 */
6412 if (incremental && !deleted) {
6413 result = offline(db, ver, zonediff,
6414 name, rdataset.ttl,
6415 &rdata);
6416 if (result != ISC_R_SUCCESS)
6417 break;
6418 }
6419
6420 /*
6421 * Log the key id and algorithm of
6422 * the inactive key with no replacement
6423 */
6424 if (zone->log_key_expired_timer <= now) {
6425 char origin[DNS_NAME_FORMATSIZE];
6426 char algbuf[DNS_NAME_FORMATSIZE];
6427 dns_name_format(&zone->origin, origin,
6428 sizeof(origin));
6429 dns_secalg_format(rrsig.algorithm,
6430 algbuf,
6431 sizeof(algbuf));
6432 dns_zone_log(zone, ISC_LOG_WARNING,
6433 "Key %s/%s/%d "
6434 "missing or inactive "
6435 "and has no replacement: "
6436 "retaining signatures.",
6437 origin, algbuf,
6438 rrsig.keyid);
6439 zone->log_key_expired_timer = now +
6440 3600;
6441 }
6442 }
6443 continue;
6444 }
6445
6446 /*
6447 * RRSIG(DNSKEY) requires special processing.
6448 */
6449 found = false;
6450 for (i = 0; i < nkeys; i++) {
6451 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
6452 rrsig.keyid == dst_key_id(keys[i])) {
6453 found = true;
6454 /*
6455 * Mark offline RRSIG(DNSKEY).
6456 * We want the earliest offline expire time
6457 * iff there is a new offline signature.
6458 */
6459 if (!dst_key_inactive(keys[i]) &&
6460 !dst_key_isprivate(keys[i]))
6461 {
6462 int64_t timeexpire =
6463 dns_time64_from32(rrsig.timeexpire);
6464 if (timewarn != 0 &&
6465 timewarn > timeexpire)
6466 timewarn = timeexpire;
6467 if (rdata.flags & DNS_RDATA_OFFLINE) {
6468 if (timemaybe == 0 ||
6469 timemaybe > timeexpire)
6470 timemaybe = timeexpire;
6471 break;
6472 }
6473 if (timewarn == 0)
6474 timewarn = timemaybe;
6475 if (timewarn == 0 ||
6476 timewarn > timeexpire)
6477 timewarn = timeexpire;
6478 result = offline(db, ver, zonediff,
6479 name, rdataset.ttl,
6480 &rdata);
6481 break;
6482 }
6483 result = update_one_rr(db, ver, zonediff->diff,
6484 DNS_DIFFOP_DELRESIGN,
6485 name, rdataset.ttl,
6486 &rdata);
6487 break;
6488 }
6489 }
6490
6491 /*
6492 * If there is not a matching DNSKEY then
6493 * delete the RRSIG.
6494 */
6495 if (!found) {
6496 result = update_one_rr(db, ver, zonediff->diff,
6497 DNS_DIFFOP_DELRESIGN, name,
6498 rdataset.ttl, &rdata);
6499 }
6500 if (result != ISC_R_SUCCESS)
6501 break;
6502 }
6503
6504 dns_rdataset_disassociate(&rdataset);
6505 if (result == ISC_R_NOMORE)
6506 result = ISC_R_SUCCESS;
6507 if (timewarn > 0) {
6508 isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn;
6509 if (timewarn == stdwarn) {
6510 set_key_expiry_warning(zone, (isc_stdtime_t)timewarn,
6511 now);
6512 } else {
6513 dns_zone_log(zone, ISC_LOG_ERROR,
6514 "key expiry warning time out of range");
6515 }
6516 }
6517 failure:
6518 if (node != NULL)
6519 dns_db_detachnode(db, &node);
6520 return (result);
6521 }
6522
6523 static isc_result_t
6524 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
6525 dns_zone_t* zone, dns_rdatatype_t type, dns_diff_t *diff,
6526 dst_key_t **keys, unsigned int nkeys, isc_mem_t *mctx,
6527 isc_stdtime_t inception, isc_stdtime_t expire,
6528 bool check_ksk, bool keyset_kskonly)
6529 {
6530 isc_result_t result;
6531 dns_dbnode_t *node = NULL;
6532 dns_stats_t* dnssecsignstats;
6533 dns_stats_t* dnssecrefreshstats;
6534 dns_rdataset_t rdataset;
6535 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
6536 unsigned char data[1024]; /* XXX */
6537 isc_buffer_t buffer;
6538 unsigned int i, j;
6539
6540 dns_rdataset_init(&rdataset);
6541 isc_buffer_init(&buffer, data, sizeof(data));
6542
6543 if (type == dns_rdatatype_nsec3)
6544 result = dns_db_findnsec3node(db, name, false, &node);
6545 else
6546 result = dns_db_findnode(db, name, false, &node);
6547 if (result == ISC_R_NOTFOUND)
6548 return (ISC_R_SUCCESS);
6549 if (result != ISC_R_SUCCESS)
6550 goto failure;
6551 result = dns_db_findrdataset(db, node, ver, type, 0,
6552 (isc_stdtime_t) 0, &rdataset, NULL);
6553 dns_db_detachnode(db, &node);
6554 if (result == ISC_R_NOTFOUND) {
6555 INSIST(!dns_rdataset_isassociated(&rdataset));
6556 return (ISC_R_SUCCESS);
6557 }
6558 if (result != ISC_R_SUCCESS) {
6559 INSIST(!dns_rdataset_isassociated(&rdataset));
6560 goto failure;
6561 }
6562
6563 for (i = 0; i < nkeys; i++) {
6564 bool both = false;
6565
6566 /* Don't add signatures for offline or inactive keys */
6567 if (!dst_key_isprivate(keys[i])) {
6568 continue;
6569 }
6570 if (dst_key_inactive(keys[i])) {
6571 continue;
6572 }
6573
6574 if (check_ksk && !REVOKE(keys[i])) {
6575 bool have_ksk, have_nonksk;
6576 if (KSK(keys[i])) {
6577 have_ksk = true;
6578 have_nonksk = false;
6579 } else {
6580 have_ksk = false;
6581 have_nonksk = true;
6582 }
6583
6584 for (j = 0; j < nkeys; j++) {
6585 if (j == i || ALG(keys[i]) != ALG(keys[j])) {
6586 continue;
6587 }
6588
6589 /* Don't consider inactive keys, however
6590 * the key may be temporary offline, so do
6591 * consider keys which private key files are
6592 * unavailable.
6593 */
6594 if (dst_key_inactive(keys[j])) {
6595 continue;
6596 }
6597
6598 if (REVOKE(keys[j])) {
6599 continue;
6600 }
6601 if (KSK(keys[j])) {
6602 have_ksk = true;
6603 } else {
6604 have_nonksk = true;
6605 }
6606 both = have_ksk && have_nonksk;
6607 if (both) {
6608 break;
6609 }
6610 }
6611 }
6612
6613 if (both) {
6614 /*
6615 * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1).
6616 */
6617 if (type == dns_rdatatype_dnskey ||
6618 type == dns_rdatatype_cdnskey ||
6619 type == dns_rdatatype_cds)
6620 {
6621 if (!KSK(keys[i]) && keyset_kskonly)
6622 continue;
6623 } else if (KSK(keys[i])) {
6624 continue;
6625 }
6626 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) {
6627 continue;
6628 }
6629
6630 /* Calculate the signature, creating a RRSIG RDATA. */
6631 isc_buffer_clear(&buffer);
6632 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
6633 &inception, &expire,
6634 mctx, &buffer, &sig_rdata));
6635
6636 /* Update the database and journal with the RRSIG. */
6637 /* XXX inefficient - will cause dataset merging */
6638 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
6639 name, rdataset.ttl, &sig_rdata));
6640 dns_rdata_reset(&sig_rdata);
6641 isc_buffer_init(&buffer, data, sizeof(data));
6642
6643 /* Update DNSSEC sign statistics. */
6644 dnssecsignstats = dns_zone_getdnssecsignstats(zone);
6645 dnssecrefreshstats = dns_zone_getdnssecrefreshstats(zone);
6646 if (dnssecsignstats != NULL) {
6647 dns_dnssecsignstats_increment(
6648 dns_zone_getdnssecsignstats(zone),
6649 dst_key_id(keys[i]));
6650 }
6651 if (dnssecrefreshstats != NULL) {
6652 dns_dnssecsignstats_increment(
6653 dns_zone_getdnssecrefreshstats(zone),
6654 dst_key_id(keys[i]));
6655 }
6656 }
6657
6658 failure:
6659 if (dns_rdataset_isassociated(&rdataset))
6660 dns_rdataset_disassociate(&rdataset);
6661 if (node != NULL)
6662 dns_db_detachnode(db, &node);
6663 return (result);
6664 }
6665
6666 static void
6667 zone_resigninc(dns_zone_t *zone) {
6668 const char *me = "zone_resigninc";
6669 dns_db_t *db = NULL;
6670 dns_dbversion_t *version = NULL;
6671 dns_diff_t _sig_diff;
6672 dns__zonediff_t zonediff;
6673 dns_fixedname_t fixed;
6674 dns_name_t *name;
6675 dns_rdataset_t rdataset;
6676 dns_rdatatype_t covers;
6677 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
6678 bool check_ksk, keyset_kskonly = false;
6679 isc_result_t result;
6680 isc_stdtime_t now, inception, soaexpire, expire, stop;
6681 uint32_t jitter, sigvalidityinterval;
6682 unsigned int i;
6683 unsigned int nkeys = 0;
6684 unsigned int resign;
6685
6686 ENTER;
6687
6688 dns_rdataset_init(&rdataset);
6689 dns_diff_init(zone->mctx, &_sig_diff);
6690 zonediff_init(&zonediff, &_sig_diff);
6691
6692 /*
6693 * Zone is frozen or automatic resigning is disabled.
6694 * Pause for 5 minutes.
6695 */
6696 if (zone->update_disabled ||
6697 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN))
6698 {
6699 result = ISC_R_FAILURE;
6700 goto failure;
6701 }
6702
6703 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6704 dns_db_attach(zone->db, &db);
6705 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6706
6707 result = dns_db_newversion(db, &version);
6708 if (result != ISC_R_SUCCESS) {
6709 dns_zone_log(zone, ISC_LOG_ERROR,
6710 "zone_resigninc:dns_db_newversion -> %s",
6711 dns_result_totext(result));
6712 goto failure;
6713 }
6714
6715 isc_stdtime_get(&now);
6716
6717 result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
6718 DNS_MAXZONEKEYS, zone_keys, &nkeys);
6719 if (result != ISC_R_SUCCESS) {
6720 dns_zone_log(zone, ISC_LOG_ERROR,
6721 "zone_resigninc:dns__zone_findkeys -> %s",
6722 dns_result_totext(result));
6723 goto failure;
6724 }
6725
6726 sigvalidityinterval = zone->sigvalidityinterval;
6727 inception = now - 3600; /* Allow for clock skew. */
6728 soaexpire = now + sigvalidityinterval;
6729 /*
6730 * Spread out signatures over time if they happen to be
6731 * clumped. We don't do this for each add_sigs() call as
6732 * we still want some clustering to occur.
6733 */
6734 if (sigvalidityinterval >= 3600U) {
6735 if (sigvalidityinterval > 7200U) {
6736 jitter = isc_random_uniform(3600);
6737 } else {
6738 jitter = isc_random_uniform(1200);
6739 }
6740 expire = soaexpire - jitter - 1;
6741 } else {
6742 expire = soaexpire - 1;
6743 }
6744 stop = now + 5;
6745
6746 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
6747 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
6748
6749 name = dns_fixedname_initname(&fixed);
6750 result = dns_db_getsigningtime(db, &rdataset, name);
6751 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
6752 dns_zone_log(zone, ISC_LOG_ERROR,
6753 "zone_resigninc:dns_db_getsigningtime -> %s",
6754 dns_result_totext(result));
6755 }
6756
6757 i = 0;
6758 while (result == ISC_R_SUCCESS) {
6759 resign = rdataset.resign - zone->sigresigninginterval;
6760 covers = rdataset.covers;
6761 dns_rdataset_disassociate(&rdataset);
6762
6763 /*
6764 * Stop if we hit the SOA as that means we have walked the
6765 * entire zone. The SOA record should always be the most
6766 * recent signature.
6767 */
6768 /* XXXMPA increase number of RRsets signed pre call */
6769 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
6770 resign > stop)
6771 break;
6772
6773 result = del_sigs(zone, db, version, name, covers, &zonediff,
6774 zone_keys, nkeys, now, true);
6775 if (result != ISC_R_SUCCESS) {
6776 dns_zone_log(zone, ISC_LOG_ERROR,
6777 "zone_resigninc:del_sigs -> %s",
6778 dns_result_totext(result));
6779 break;
6780 }
6781
6782 result = add_sigs(db, version, name, zone, covers,
6783 zonediff.diff, zone_keys, nkeys, zone->mctx,
6784 inception, expire, check_ksk, keyset_kskonly);
6785 if (result != ISC_R_SUCCESS) {
6786 dns_zone_log(zone, ISC_LOG_ERROR,
6787 "zone_resigninc:add_sigs -> %s",
6788 dns_result_totext(result));
6789 break;
6790 }
6791 result = dns_db_getsigningtime(db, &rdataset, name);
6792 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
6793 result = ISC_R_SUCCESS;
6794 break;
6795 }
6796 if (result != ISC_R_SUCCESS)
6797 dns_zone_log(zone, ISC_LOG_ERROR,
6798 "zone_resigninc:dns_db_getsigningtime -> %s",
6799 dns_result_totext(result));
6800 }
6801
6802 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
6803 goto failure;
6804
6805 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
6806 &zonediff, zone_keys, nkeys, now, true);
6807 if (result != ISC_R_SUCCESS) {
6808 dns_zone_log(zone, ISC_LOG_ERROR,
6809 "zone_resigninc:del_sigs -> %s",
6810 dns_result_totext(result));
6811 goto failure;
6812 }
6813
6814 /*
6815 * Did we change anything in the zone?
6816 */
6817 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
6818 /*
6819 * Commit the changes if any key has been marked as offline.
6820 */
6821 if (zonediff.offline)
6822 dns_db_closeversion(db, &version, true);
6823 goto failure;
6824 }
6825
6826 /* Increment SOA serial if we have made changes */
6827 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
6828 zone->updatemethod);
6829 if (result != ISC_R_SUCCESS) {
6830 dns_zone_log(zone, ISC_LOG_ERROR,
6831 "zone_resigninc:update_soa_serial -> %s",
6832 dns_result_totext(result));
6833 goto failure;
6834 }
6835
6836 /*
6837 * Generate maximum life time signatures so that the above loop
6838 * termination is sensible.
6839 */
6840 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
6841 zonediff.diff, zone_keys, nkeys, zone->mctx,
6842 inception, soaexpire, check_ksk, keyset_kskonly);
6843 if (result != ISC_R_SUCCESS) {
6844 dns_zone_log(zone, ISC_LOG_ERROR,
6845 "zone_resigninc:add_sigs -> %s",
6846 dns_result_totext(result));
6847 goto failure;
6848 }
6849
6850 /* Write changes to journal file. */
6851 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc"));
6852
6853 /* Everything has succeeded. Commit the changes. */
6854 dns_db_closeversion(db, &version, true);
6855
6856 failure:
6857 dns_diff_clear(&_sig_diff);
6858 for (i = 0; i < nkeys; i++)
6859 dst_key_free(&zone_keys[i]);
6860 if (version != NULL) {
6861 dns_db_closeversion(db, &version, false);
6862 dns_db_detach(&db);
6863 } else if (db != NULL)
6864 dns_db_detach(&db);
6865 if (result == ISC_R_SUCCESS) {
6866 set_resigntime(zone);
6867 LOCK_ZONE(zone);
6868 zone_needdump(zone, DNS_DUMP_DELAY);
6869 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6870 UNLOCK_ZONE(zone);
6871 } else {
6872 /*
6873 * Something failed. Retry in 5 minutes.
6874 */
6875 isc_interval_t ival;
6876 isc_interval_set(&ival, 300, 0);
6877 isc_time_nowplusinterval(&zone->resigntime, &ival);
6878 }
6879
6880 INSIST(version == NULL);
6881 }
6882
6883 static isc_result_t
6884 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
6885 dns_name_t *newname, bool bottom)
6886 {
6887 isc_result_t result;
6888 dns_dbiterator_t *dbit = NULL;
6889 dns_rdatasetiter_t *rdsit = NULL;
6890 dns_dbnode_t *node = NULL;
6891
6892 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
6893 CHECK(dns_dbiterator_seek(dbit, oldname));
6894 do {
6895 result = dns_dbiterator_next(dbit);
6896 if (result == ISC_R_NOMORE)
6897 CHECK(dns_dbiterator_first(dbit));
6898 CHECK(dns_dbiterator_current(dbit, &node, newname));
6899 if (bottom && dns_name_issubdomain(newname, oldname) &&
6900 !dns_name_equal(newname, oldname)) {
6901 dns_db_detachnode(db, &node);
6902 continue;
6903 }
6904 /*
6905 * Is this node empty?
6906 */
6907 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
6908 result = dns_rdatasetiter_first(rdsit);
6909 dns_db_detachnode(db, &node);
6910 dns_rdatasetiter_destroy(&rdsit);
6911 if (result != ISC_R_NOMORE)
6912 break;
6913 } while (1);
6914 failure:
6915 if (node != NULL)
6916 dns_db_detachnode(db, &node);
6917 if (dbit != NULL)
6918 dns_dbiterator_destroy(&dbit);
6919 return (result);
6920 }
6921
6922 static bool
6923 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
6924 dns_rdatatype_t type, dst_key_t *key)
6925 {
6926 isc_result_t result;
6927 dns_rdataset_t rdataset;
6928 dns_rdata_t rdata = DNS_RDATA_INIT;
6929 dns_rdata_rrsig_t rrsig;
6930
6931 dns_rdataset_init(&rdataset);
6932 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
6933 type, 0, &rdataset, NULL);
6934 if (result != ISC_R_SUCCESS) {
6935 INSIST(!dns_rdataset_isassociated(&rdataset));
6936 return (false);
6937 }
6938 for (result = dns_rdataset_first(&rdataset);
6939 result == ISC_R_SUCCESS;
6940 result = dns_rdataset_next(&rdataset)) {
6941 dns_rdataset_current(&rdataset, &rdata);
6942 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
6943 INSIST(result == ISC_R_SUCCESS);
6944 if (rrsig.algorithm == dst_key_alg(key) &&
6945 rrsig.keyid == dst_key_id(key)) {
6946 dns_rdataset_disassociate(&rdataset);
6947 return (true);
6948 }
6949 dns_rdata_reset(&rdata);
6950 }
6951 dns_rdataset_disassociate(&rdataset);
6952 return (false);
6953 }
6954
6955 static isc_result_t
6956 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
6957 dns_dbnode_t *node, dns_ttl_t ttl, bool bottom,
6958 dns_diff_t *diff)
6959 {
6960 dns_fixedname_t fixed;
6961 dns_name_t *next;
6962 dns_rdata_t rdata = DNS_RDATA_INIT;
6963 isc_result_t result;
6964 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
6965
6966 next = dns_fixedname_initname(&fixed);
6967
6968 CHECK(next_active(db, version, name, next, bottom));
6969 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
6970 &rdata));
6971 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
6972 &rdata));
6973 failure:
6974 return (result);
6975 }
6976
6977 static isc_result_t
6978 check_if_bottom_of_zone(dns_db_t *db, dns_dbnode_t *node,
6979 dns_dbversion_t *version, bool *is_bottom_of_zone)
6980 {
6981 isc_result_t result;
6982 dns_rdatasetiter_t *iterator = NULL;
6983 dns_rdataset_t rdataset;
6984 bool seen_soa = false, seen_ns = false, seen_dname = false;
6985
6986 REQUIRE(is_bottom_of_zone != NULL);
6987
6988 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6989 if (result != ISC_R_SUCCESS) {
6990 if (result == ISC_R_NOTFOUND) {
6991 result = ISC_R_SUCCESS;
6992 }
6993 return (result);
6994 }
6995
6996 dns_rdataset_init(&rdataset);
6997 for (result = dns_rdatasetiter_first(iterator);
6998 result == ISC_R_SUCCESS;
6999 result = dns_rdatasetiter_next(iterator)) {
7000 dns_rdatasetiter_current(iterator, &rdataset);
7001 switch (rdataset.type) {
7002 case dns_rdatatype_soa:
7003 seen_soa = true;
7004 break;
7005 case dns_rdatatype_ns:
7006 seen_ns = true;
7007 break;
7008 case dns_rdatatype_dname:
7009 seen_dname = true;
7010 break;
7011 }
7012 dns_rdataset_disassociate(&rdataset);
7013 }
7014 if (result != ISC_R_NOMORE) {
7015 goto failure;
7016 }
7017 if ((seen_ns && !seen_soa) || seen_dname) {
7018 *is_bottom_of_zone = true;
7019 }
7020 result = ISC_R_SUCCESS;
7021
7022 failure:
7023 dns_rdatasetiter_destroy(&iterator);
7024
7025 return (result);
7026 }
7027
7028 static isc_result_t
7029 sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
7030 dns_dbnode_t *node, dns_dbversion_t *version,
7031 bool build_nsec3, bool build_nsec, dst_key_t *key,
7032 isc_stdtime_t inception, isc_stdtime_t expire,
7033 unsigned int minimum, bool is_ksk,
7034 bool keyset_kskonly, bool is_bottom_of_zone,
7035 dns_diff_t *diff, int32_t *signatures, isc_mem_t *mctx)
7036 {
7037 isc_result_t result;
7038 dns_rdatasetiter_t *iterator = NULL;
7039 dns_rdataset_t rdataset;
7040 dns_rdata_t rdata = DNS_RDATA_INIT;
7041 dns_stats_t* dnssecsignstats;
7042 dns_stats_t* dnssecrefreshstats;
7043
7044 isc_buffer_t buffer;
7045 unsigned char data[1024];
7046 bool seen_soa, seen_ns, seen_rr, seen_nsec, seen_nsec3, seen_ds;
7047
7048 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7049 if (result != ISC_R_SUCCESS) {
7050 if (result == ISC_R_NOTFOUND)
7051 result = ISC_R_SUCCESS;
7052 return (result);
7053 }
7054
7055 dns_rdataset_init(&rdataset);
7056 isc_buffer_init(&buffer, data, sizeof(data));
7057 seen_rr = seen_soa = seen_ns = seen_nsec = seen_nsec3 = seen_ds = false;
7058 for (result = dns_rdatasetiter_first(iterator);
7059 result == ISC_R_SUCCESS;
7060 result = dns_rdatasetiter_next(iterator)) {
7061 dns_rdatasetiter_current(iterator, &rdataset);
7062 if (rdataset.type == dns_rdatatype_soa)
7063 seen_soa = true;
7064 else if (rdataset.type == dns_rdatatype_ns)
7065 seen_ns = true;
7066 else if (rdataset.type == dns_rdatatype_ds)
7067 seen_ds = true;
7068 else if (rdataset.type == dns_rdatatype_nsec)
7069 seen_nsec = true;
7070 else if (rdataset.type == dns_rdatatype_nsec3)
7071 seen_nsec3 = true;
7072 if (rdataset.type != dns_rdatatype_rrsig)
7073 seen_rr = true;
7074 dns_rdataset_disassociate(&rdataset);
7075 }
7076 if (result != ISC_R_NOMORE)
7077 goto failure;
7078 /*
7079 * Going from insecure to NSEC3.
7080 * Don't generate NSEC3 records for NSEC3 records.
7081 */
7082 if (build_nsec3 && !seen_nsec3 && seen_rr) {
7083 bool unsecure = !seen_ds && seen_ns && !seen_soa;
7084 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
7085 unsecure, diff));
7086 (*signatures)--;
7087 }
7088 /*
7089 * Going from insecure to NSEC.
7090 * Don't generate NSEC records for NSEC3 records.
7091 */
7092 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
7093 /*
7094 * Build a NSEC record except at the origin.
7095 */
7096 if (!dns_name_equal(name, dns_db_origin(db))) {
7097 CHECK(add_nsec(db, version, name, node, minimum,
7098 is_bottom_of_zone, diff));
7099 /* Count a NSEC generation as a signature generation. */
7100 (*signatures)--;
7101 }
7102 }
7103 result = dns_rdatasetiter_first(iterator);
7104 while (result == ISC_R_SUCCESS) {
7105 dns_rdatasetiter_current(iterator, &rdataset);
7106 if (rdataset.type == dns_rdatatype_soa ||
7107 rdataset.type == dns_rdatatype_rrsig)
7108 {
7109 goto next_rdataset;
7110 }
7111 if (rdataset.type == dns_rdatatype_dnskey ||
7112 rdataset.type == dns_rdatatype_cdnskey ||
7113 rdataset.type == dns_rdatatype_cds)
7114 {
7115 /*
7116 * CDS and CDNSKEY are signed with KSK like DNSKEY.
7117 * (RFC 7344, section 4.1 specifies that they must
7118 * be signed with a key in the current DS RRset,
7119 * which would only include KSK's.)
7120 */
7121 if (!is_ksk && keyset_kskonly) {
7122 goto next_rdataset;
7123 }
7124 } else if (is_ksk) {
7125 goto next_rdataset;
7126 }
7127 if (seen_ns && !seen_soa &&
7128 rdataset.type != dns_rdatatype_ds &&
7129 rdataset.type != dns_rdatatype_nsec)
7130 {
7131 goto next_rdataset;
7132 }
7133 if (signed_with_key(db, node, version, rdataset.type, key)) {
7134 goto next_rdataset;
7135 }
7136 /* Calculate the signature, creating a RRSIG RDATA. */
7137 isc_buffer_clear(&buffer);
7138 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
7139 &expire, mctx, &buffer, &rdata));
7140 /* Update the database and journal with the RRSIG. */
7141 /* XXX inefficient - will cause dataset merging */
7142 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
7143 name, rdataset.ttl, &rdata));
7144 dns_rdata_reset(&rdata);
7145
7146 /* Update DNSSEC sign statistics. */
7147 dnssecsignstats = dns_zone_getdnssecsignstats(zone);
7148 dnssecrefreshstats = dns_zone_getdnssecrefreshstats(zone);
7149 if (dnssecsignstats != NULL) {
7150 dns_dnssecsignstats_increment(
7151 dns_zone_getdnssecsignstats(zone),
7152 dst_key_id(key));
7153 }
7154 if (dnssecrefreshstats != NULL) {
7155 dns_dnssecsignstats_increment(
7156 dns_zone_getdnssecrefreshstats(zone),
7157 dst_key_id(key));
7158 }
7159
7160 (*signatures)--;
7161 next_rdataset:
7162 dns_rdataset_disassociate(&rdataset);
7163 result = dns_rdatasetiter_next(iterator);
7164 }
7165 if (result == ISC_R_NOMORE)
7166 result = ISC_R_SUCCESS;
7167 failure:
7168 if (dns_rdataset_isassociated(&rdataset))
7169 dns_rdataset_disassociate(&rdataset);
7170 if (iterator != NULL)
7171 dns_rdatasetiter_destroy(&iterator);
7172 return (result);
7173 }
7174
7175 /*
7176 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
7177 */
7178 static isc_result_t
7179 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
7180 dns_ttl_t minimum, bool update_only, dns_diff_t *diff)
7181 {
7182 isc_result_t result;
7183 dns_rdataset_t rdataset;
7184 dns_dbnode_t *node = NULL;
7185
7186 CHECK(dns_db_getoriginnode(db, &node));
7187 if (update_only) {
7188 dns_rdataset_init(&rdataset);
7189 result = dns_db_findrdataset(db, node, version,
7190 dns_rdatatype_nsec,
7191 dns_rdatatype_none,
7192 0, &rdataset, NULL);
7193 if (dns_rdataset_isassociated(&rdataset))
7194 dns_rdataset_disassociate(&rdataset);
7195 if (result == ISC_R_NOTFOUND)
7196 goto success;
7197 if (result != ISC_R_SUCCESS)
7198 goto failure;
7199 }
7200 CHECK(delete_nsec(db, version, node, name, diff));
7201 CHECK(add_nsec(db, version, name, node, minimum, false, diff));
7202 success:
7203 result = ISC_R_SUCCESS;
7204 failure:
7205 if (node != NULL)
7206 dns_db_detachnode(db, &node);
7207 return (result);
7208 }
7209
7210 static isc_result_t
7211 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
7212 dns_dbversion_t *version, bool build_nsec3,
7213 dns_ttl_t minimum, dns_diff_t *diff)
7214 {
7215 isc_result_t result;
7216 dns_dbnode_t *node = NULL;
7217 dns_rdataset_t rdataset;
7218 dns_rdata_t rdata = DNS_RDATA_INIT;
7219 unsigned char data[5];
7220 bool seen_done = false;
7221 bool have_rr = false;
7222
7223 dns_rdataset_init(&rdataset);
7224 result = dns_db_getoriginnode(signing->db, &node);
7225 if (result != ISC_R_SUCCESS)
7226 goto failure;
7227
7228 result = dns_db_findrdataset(signing->db, node, version,
7229 zone->privatetype, dns_rdatatype_none,
7230 0, &rdataset, NULL);
7231 if (result == ISC_R_NOTFOUND) {
7232 INSIST(!dns_rdataset_isassociated(&rdataset));
7233 result = ISC_R_SUCCESS;
7234 goto failure;
7235 }
7236 if (result != ISC_R_SUCCESS) {
7237 INSIST(!dns_rdataset_isassociated(&rdataset));
7238 goto failure;
7239 }
7240 for (result = dns_rdataset_first(&rdataset);
7241 result == ISC_R_SUCCESS;
7242 result = dns_rdataset_next(&rdataset)) {
7243 dns_rdataset_current(&rdataset, &rdata);
7244 /*
7245 * If we don't match the algorithm or keyid skip the record.
7246 */
7247 if (rdata.length != 5 ||
7248 rdata.data[0] != signing->algorithm ||
7249 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
7250 rdata.data[2] != (signing->keyid & 0xff)) {
7251 have_rr = true;
7252 dns_rdata_reset(&rdata);
7253 continue;
7254 }
7255 /*
7256 * We have a match. If we were signing (!signing->deleteit)
7257 * and we already have a record indicating that we have
7258 * finished signing (rdata.data[4] != 0) then keep it.
7259 * Otherwise it needs to be deleted as we have removed all
7260 * the signatures (signing->deleteit), so any record indicating
7261 * completion is now out of date, or we have finished signing
7262 * with the new record so we no longer need to remember that
7263 * we need to sign the zone with the matching key across a
7264 * nameserver re-start.
7265 */
7266 if (!signing->deleteit && rdata.data[4] != 0) {
7267 seen_done = true;
7268 have_rr = true;
7269 } else
7270 CHECK(update_one_rr(signing->db, version, diff,
7271 DNS_DIFFOP_DEL, &zone->origin,
7272 rdataset.ttl, &rdata));
7273 dns_rdata_reset(&rdata);
7274 }
7275 if (result == ISC_R_NOMORE)
7276 result = ISC_R_SUCCESS;
7277 if (!signing->deleteit && !seen_done) {
7278 /*
7279 * If we were signing then we need to indicate that we have
7280 * finished signing the zone with this key. If it is already
7281 * there we don't need to add it a second time.
7282 */
7283 data[0] = signing->algorithm;
7284 data[1] = (signing->keyid >> 8) & 0xff;
7285 data[2] = signing->keyid & 0xff;
7286 data[3] = 0;
7287 data[4] = 1;
7288 rdata.length = sizeof(data);
7289 rdata.data = data;
7290 rdata.type = zone->privatetype;
7291 rdata.rdclass = dns_db_class(signing->db);
7292 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
7293 &zone->origin, rdataset.ttl, &rdata));
7294 } else if (!have_rr) {
7295 dns_name_t *origin = dns_db_origin(signing->db);
7296 /*
7297 * Rebuild the NSEC/NSEC3 record for the origin as we no
7298 * longer have any private records.
7299 */
7300 if (build_nsec3)
7301 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
7302 minimum, false, diff));
7303 CHECK(updatesecure(signing->db, version, origin, minimum,
7304 true, diff));
7305 }
7306
7307 failure:
7308 if (dns_rdataset_isassociated(&rdataset))
7309 dns_rdataset_disassociate(&rdataset);
7310 if (node != NULL)
7311 dns_db_detachnode(signing->db, &node);
7312 return (result);
7313 }
7314
7315 /*
7316 * Called from zone_nsec3chain() in order to update zone records indicating
7317 * processing status of given NSEC3 chain:
7318 *
7319 * - If the supplied dns_nsec3chain_t structure has been fully processed
7320 * (which is indicated by "active" being set to false):
7321 *
7322 * - remove all NSEC3PARAM records matching the relevant NSEC3 chain,
7323 *
7324 * - remove all private-type records containing NSEC3PARAM RDATA matching
7325 * the relevant NSEC3 chain.
7326 *
7327 * - If the supplied dns_nsec3chain_t structure has not been fully processed
7328 * (which is indicated by "active" being set to true), only remove the
7329 * NSEC3PARAM record which matches the relevant NSEC3 chain and has the
7330 * "flags" field set to 0.
7331 *
7332 * - If given NSEC3 chain is being added, add an NSEC3PARAM record contained
7333 * in the relevant private-type record, but with the "flags" field set to
7334 * 0, indicating that this NSEC3 chain is now complete for this zone.
7335 *
7336 * Note that this function is called at different processing stages for NSEC3
7337 * chain additions vs. removals and needs to handle all cases properly.
7338 */
7339 static isc_result_t
7340 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
7341 bool active, dns_rdatatype_t privatetype,
7342 dns_diff_t *diff)
7343 {
7344 dns_dbnode_t *node = NULL;
7345 dns_name_t *name = dns_db_origin(db);
7346 dns_rdata_t rdata = DNS_RDATA_INIT;
7347 dns_rdataset_t rdataset;
7348 dns_rdata_nsec3param_t nsec3param;
7349 isc_result_t result;
7350 isc_buffer_t buffer;
7351 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
7352 dns_ttl_t ttl = 0;
7353 bool nseconly = false, nsec3ok = false;
7354
7355 dns_rdataset_init(&rdataset);
7356
7357 result = dns_db_getoriginnode(db, &node);
7358 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7359 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
7360 0, 0, &rdataset, NULL);
7361 if (result == ISC_R_NOTFOUND)
7362 goto try_private;
7363 if (result != ISC_R_SUCCESS)
7364 goto failure;
7365
7366 /*
7367 * Preserve the existing ttl.
7368 */
7369 ttl = rdataset.ttl;
7370
7371 /*
7372 * Delete all NSEC3PARAM records which match that in nsec3chain.
7373 */
7374 for (result = dns_rdataset_first(&rdataset);
7375 result == ISC_R_SUCCESS;
7376 result = dns_rdataset_next(&rdataset)) {
7377
7378 dns_rdataset_current(&rdataset, &rdata);
7379 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
7380
7381 if (nsec3param.hash != chain->nsec3param.hash ||
7382 (active && nsec3param.flags != 0) ||
7383 nsec3param.iterations != chain->nsec3param.iterations ||
7384 nsec3param.salt_length != chain->nsec3param.salt_length ||
7385 memcmp(nsec3param.salt, chain->nsec3param.salt,
7386 nsec3param.salt_length)) {
7387 dns_rdata_reset(&rdata);
7388 continue;
7389 }
7390
7391 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
7392 name, rdataset.ttl, &rdata));
7393 dns_rdata_reset(&rdata);
7394 }
7395 if (result != ISC_R_NOMORE)
7396 goto failure;
7397
7398 dns_rdataset_disassociate(&rdataset);
7399
7400 try_private:
7401
7402 if (active)
7403 goto add;
7404
7405 result = dns_nsec_nseconly(db, ver, &nseconly);
7406 nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
7407
7408 /*
7409 * Delete all private records which match that in nsec3chain.
7410 */
7411 result = dns_db_findrdataset(db, node, ver, privatetype,
7412 0, 0, &rdataset, NULL);
7413 if (result == ISC_R_NOTFOUND)
7414 goto add;
7415 if (result != ISC_R_SUCCESS)
7416 goto failure;
7417
7418 for (result = dns_rdataset_first(&rdataset);
7419 result == ISC_R_SUCCESS;
7420 result = dns_rdataset_next(&rdataset)) {
7421 dns_rdata_t private = DNS_RDATA_INIT;
7422 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
7423
7424 dns_rdataset_current(&rdataset, &private);
7425 if (!dns_nsec3param_fromprivate(&private, &rdata,
7426 buf, sizeof(buf)))
7427 continue;
7428 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
7429
7430 if ((!nsec3ok &&
7431 (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) ||
7432 nsec3param.hash != chain->nsec3param.hash ||
7433 nsec3param.iterations != chain->nsec3param.iterations ||
7434 nsec3param.salt_length != chain->nsec3param.salt_length ||
7435 memcmp(nsec3param.salt, chain->nsec3param.salt,
7436 nsec3param.salt_length)) {
7437 dns_rdata_reset(&rdata);
7438 continue;
7439 }
7440
7441 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
7442 name, rdataset.ttl, &private));
7443 dns_rdata_reset(&rdata);
7444 }
7445 if (result != ISC_R_NOMORE)
7446 goto failure;
7447
7448 add:
7449 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
7450 result = ISC_R_SUCCESS;
7451 goto failure;
7452 }
7453
7454 /*
7455 * Add a NSEC3PARAM record which matches that in nsec3chain but
7456 * with all flags bits cleared.
7457 *
7458 * Note: we do not clear chain->nsec3param.flags as this change
7459 * may be reversed.
7460 */
7461 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
7462 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
7463 dns_rdatatype_nsec3param,
7464 &chain->nsec3param, &buffer));
7465 rdata.data[1] = 0; /* Clear flag bits. */
7466 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
7467
7468 failure:
7469 dns_db_detachnode(db, &node);
7470 if (dns_rdataset_isassociated(&rdataset))
7471 dns_rdataset_disassociate(&rdataset);
7472 return (result);
7473 }
7474
7475 static isc_result_t
7476 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
7477 dns_name_t *name, dns_diff_t *diff)
7478 {
7479 dns_rdataset_t rdataset;
7480 isc_result_t result;
7481
7482 dns_rdataset_init(&rdataset);
7483
7484 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
7485 0, 0, &rdataset, NULL);
7486 if (result == ISC_R_NOTFOUND)
7487 return (ISC_R_SUCCESS);
7488 if (result != ISC_R_SUCCESS)
7489 return (result);
7490 for (result = dns_rdataset_first(&rdataset);
7491 result == ISC_R_SUCCESS;
7492 result = dns_rdataset_next(&rdataset)) {
7493 dns_rdata_t rdata = DNS_RDATA_INIT;
7494
7495 dns_rdataset_current(&rdataset, &rdata);
7496 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
7497 rdataset.ttl, &rdata));
7498 }
7499 if (result == ISC_R_NOMORE)
7500 result = ISC_R_SUCCESS;
7501 failure:
7502 dns_rdataset_disassociate(&rdataset);
7503 return (result);
7504 }
7505
7506 static isc_result_t
7507 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
7508 dns_name_t *name, const dns_rdata_nsec3param_t *param,
7509 dns_diff_t *diff)
7510 {
7511 dns_rdataset_t rdataset;
7512 dns_rdata_nsec3_t nsec3;
7513 isc_result_t result;
7514
7515 dns_rdataset_init(&rdataset);
7516 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
7517 0, 0, &rdataset, NULL);
7518 if (result == ISC_R_NOTFOUND)
7519 return (ISC_R_SUCCESS);
7520 if (result != ISC_R_SUCCESS)
7521 return (result);
7522
7523 for (result = dns_rdataset_first(&rdataset);
7524 result == ISC_R_SUCCESS;
7525 result = dns_rdataset_next(&rdataset)) {
7526 dns_rdata_t rdata = DNS_RDATA_INIT;
7527
7528 dns_rdataset_current(&rdataset, &rdata);
7529 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
7530 if (nsec3.hash != param->hash ||
7531 nsec3.iterations != param->iterations ||
7532 nsec3.salt_length != param->salt_length ||
7533 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
7534 continue;
7535 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
7536 rdataset.ttl, &rdata));
7537 }
7538 if (result == ISC_R_NOMORE)
7539 result = ISC_R_SUCCESS;
7540 failure:
7541 dns_rdataset_disassociate(&rdataset);
7542 return (result);
7543 }
7544
7545 static isc_result_t
7546 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
7547 const dns_rdata_nsec3param_t *param,
7548 bool *answer)
7549 {
7550 dns_dbnode_t *node = NULL;
7551 dns_rdata_t rdata = DNS_RDATA_INIT;
7552 dns_rdata_nsec3param_t myparam;
7553 dns_rdataset_t rdataset;
7554 isc_result_t result;
7555
7556 *answer = false;
7557
7558 result = dns_db_getoriginnode(db, &node);
7559 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7560
7561 dns_rdataset_init(&rdataset);
7562
7563 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
7564 0, 0, &rdataset, NULL);
7565 if (result == ISC_R_SUCCESS) {
7566 dns_rdataset_disassociate(&rdataset);
7567 dns_db_detachnode(db, &node);
7568 return (result);
7569 }
7570 if (result != ISC_R_NOTFOUND) {
7571 dns_db_detachnode(db, &node);
7572 return (result);
7573 }
7574
7575 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
7576 0, 0, &rdataset, NULL);
7577 if (result == ISC_R_NOTFOUND) {
7578 *answer = true;
7579 dns_db_detachnode(db, &node);
7580 return (ISC_R_SUCCESS);
7581 }
7582 if (result != ISC_R_SUCCESS) {
7583 dns_db_detachnode(db, &node);
7584 return (result);
7585 }
7586
7587 for (result = dns_rdataset_first(&rdataset);
7588 result == ISC_R_SUCCESS;
7589 result = dns_rdataset_next(&rdataset)) {
7590 dns_rdataset_current(&rdataset, &rdata);
7591 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
7592 dns_rdata_reset(&rdata);
7593 /*
7594 * Ignore any NSEC3PARAM removals.
7595 */
7596 if (NSEC3REMOVE(myparam.flags))
7597 continue;
7598 /*
7599 * Ignore the chain that we are in the process of deleting.
7600 */
7601 if (myparam.hash == param->hash &&
7602 myparam.iterations == param->iterations &&
7603 myparam.salt_length == param->salt_length &&
7604 !memcmp(myparam.salt, param->salt, myparam.salt_length))
7605 continue;
7606 /*
7607 * Found an active NSEC3 chain.
7608 */
7609 break;
7610 }
7611 if (result == ISC_R_NOMORE) {
7612 *answer = true;
7613 result = ISC_R_SUCCESS;
7614 }
7615
7616 failure:
7617 if (dns_rdataset_isassociated(&rdataset))
7618 dns_rdataset_disassociate(&rdataset);
7619 dns_db_detachnode(db, &node);
7620 return (result);
7621 }
7622
7623 /*%
7624 * Given a tuple which is part of a diff, return a pointer to the next tuple in
7625 * that diff which has the same name and type (or NULL if no such tuple is
7626 * found).
7627 */
7628 static dns_difftuple_t *
7629 find_next_matching_tuple(dns_difftuple_t *cur) {
7630 dns_difftuple_t *next = cur;
7631
7632 while ((next = ISC_LIST_NEXT(next, link)) != NULL) {
7633 if (cur->rdata.type == next->rdata.type &&
7634 dns_name_equal(&cur->name, &next->name))
7635 {
7636 return (next);
7637 }
7638 }
7639
7640 return (NULL);
7641 }
7642
7643 /*%
7644 * Remove all tuples with the same name and type as 'cur' from 'src' and append
7645 * them to 'dst'.
7646 */
7647 static void
7648 move_matching_tuples(dns_difftuple_t *cur, dns_diff_t *src, dns_diff_t *dst) {
7649 do {
7650 dns_difftuple_t *next = find_next_matching_tuple(cur);
7651 ISC_LIST_UNLINK(src->tuples, cur, link);
7652 dns_diff_appendminimal(dst, &cur);
7653 cur = next;
7654 } while (cur != NULL);
7655 }
7656
7657 /*%
7658 * Add/remove DNSSEC signatures for the list of "raw" zone changes supplied in
7659 * 'diff'. Gradually remove tuples from 'diff' and append them to 'zonediff'
7660 * along with tuples representing relevant signature changes.
7661 */
7662 isc_result_t
7663 dns__zone_updatesigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
7664 dst_key_t *zone_keys[], unsigned int nkeys,
7665 dns_zone_t *zone, isc_stdtime_t inception,
7666 isc_stdtime_t expire, isc_stdtime_t keyexpire,
7667 isc_stdtime_t now, bool check_ksk,
7668 bool keyset_kskonly, dns__zonediff_t *zonediff)
7669 {
7670 dns_difftuple_t *tuple;
7671 isc_result_t result;
7672
7673 while ((tuple = ISC_LIST_HEAD(diff->tuples)) != NULL) {
7674 isc_stdtime_t exp = expire;
7675
7676 if (keyexpire != 0 &&
7677 (tuple->rdata.type == dns_rdatatype_dnskey ||
7678 tuple->rdata.type == dns_rdatatype_cdnskey ||
7679 tuple->rdata.type == dns_rdatatype_cds))
7680 {
7681 exp = keyexpire;
7682 }
7683
7684 result = del_sigs(zone, db, version, &tuple->name,
7685 tuple->rdata.type, zonediff,
7686 zone_keys, nkeys, now, false);
7687 if (result != ISC_R_SUCCESS) {
7688 dns_zone_log(zone, ISC_LOG_ERROR,
7689 "dns__zone_updatesigs:del_sigs -> %s",
7690 dns_result_totext(result));
7691 return (result);
7692 }
7693 result = add_sigs(db, version, &tuple->name, zone,
7694 tuple->rdata.type, zonediff->diff,
7695 zone_keys, nkeys, zone->mctx, inception,
7696 exp, check_ksk, keyset_kskonly);
7697 if (result != ISC_R_SUCCESS) {
7698 dns_zone_log(zone, ISC_LOG_ERROR,
7699 "dns__zone_updatesigs:add_sigs -> %s",
7700 dns_result_totext(result));
7701 return (result);
7702 }
7703
7704 /*
7705 * Signature changes for all RRs with name tuple->name and type
7706 * tuple->rdata.type were appended to zonediff->diff. Now we
7707 * remove all the "raw" changes with the same name and type
7708 * from diff (so that they are not processed by this loop
7709 * again) and append them to zonediff so that they get applied.
7710 */
7711 move_matching_tuples(tuple, diff, zonediff->diff);
7712 }
7713 return (ISC_R_SUCCESS);
7714 }
7715
7716 /*
7717 * Incrementally build and sign a new NSEC3 chain using the parameters
7718 * requested.
7719 */
7720 static void
7721 zone_nsec3chain(dns_zone_t *zone) {
7722 const char *me = "zone_nsec3chain";
7723 dns_db_t *db = NULL;
7724 dns_dbnode_t *node = NULL;
7725 dns_dbversion_t *version = NULL;
7726 dns_diff_t _sig_diff;
7727 dns_diff_t nsec_diff;
7728 dns_diff_t nsec3_diff;
7729 dns_diff_t param_diff;
7730 dns__zonediff_t zonediff;
7731 dns_fixedname_t fixed;
7732 dns_fixedname_t nextfixed;
7733 dns_name_t *name, *nextname;
7734 dns_rdataset_t rdataset;
7735 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
7736 dns_nsec3chainlist_t cleanup;
7737 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
7738 int32_t signatures;
7739 bool check_ksk, keyset_kskonly;
7740 bool delegation;
7741 bool first;
7742 isc_result_t result;
7743 isc_stdtime_t now, inception, soaexpire, expire;
7744 uint32_t jitter, sigvalidityinterval;
7745 unsigned int i;
7746 unsigned int nkeys = 0;
7747 uint32_t nodes;
7748 bool unsecure = false;
7749 bool seen_soa, seen_ns, seen_dname, seen_ds;
7750 bool seen_nsec, seen_nsec3, seen_rr;
7751 dns_rdatasetiter_t *iterator = NULL;
7752 bool buildnsecchain;
7753 bool updatensec = false;
7754 dns_rdatatype_t privatetype = zone->privatetype;
7755
7756 ENTER;
7757
7758 dns_rdataset_init(&rdataset);
7759 name = dns_fixedname_initname(&fixed);
7760 nextname = dns_fixedname_initname(&nextfixed);
7761 dns_diff_init(zone->mctx, ¶m_diff);
7762 dns_diff_init(zone->mctx, &nsec3_diff);
7763 dns_diff_init(zone->mctx, &nsec_diff);
7764 dns_diff_init(zone->mctx, &_sig_diff);
7765 zonediff_init(&zonediff, &_sig_diff);
7766 ISC_LIST_INIT(cleanup);
7767
7768 /*
7769 * Updates are disabled. Pause for 5 minutes.
7770 */
7771 if (zone->update_disabled) {
7772 result = ISC_R_FAILURE;
7773 goto failure;
7774 }
7775
7776 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7777 /*
7778 * This function is called when zone timer fires, after the latter gets
7779 * set by zone_addnsec3chain(). If the action triggering the call to
7780 * zone_addnsec3chain() is closely followed by a zone deletion request,
7781 * it might turn out that the timer thread will not be woken up until
7782 * after the zone is deleted by rmzone(), which calls dns_db_detach()
7783 * for zone->db, causing the latter to become NULL. Return immediately
7784 * if that happens.
7785 */
7786 if (zone->db != NULL) {
7787 dns_db_attach(zone->db, &db);
7788 }
7789 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7790 if (db == NULL) {
7791 return;
7792 }
7793
7794 result = dns_db_newversion(db, &version);
7795 if (result != ISC_R_SUCCESS) {
7796 dnssec_log(zone, ISC_LOG_ERROR,
7797 "zone_nsec3chain:dns_db_newversion -> %s",
7798 dns_result_totext(result));
7799 goto failure;
7800 }
7801
7802 isc_stdtime_get(&now);
7803
7804 result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
7805 DNS_MAXZONEKEYS, zone_keys, &nkeys);
7806 if (result != ISC_R_SUCCESS) {
7807 dnssec_log(zone, ISC_LOG_ERROR,
7808 "zone_nsec3chain:dns__zone_findkeys -> %s",
7809 dns_result_totext(result));
7810 goto failure;
7811 }
7812
7813 sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
7814 inception = now - 3600; /* Allow for clock skew. */
7815 soaexpire = now + sigvalidityinterval;
7816
7817 /*
7818 * Spread out signatures over time if they happen to be
7819 * clumped. We don't do this for each add_sigs() call as
7820 * we still want some clustering to occur.
7821 */
7822 if (sigvalidityinterval >= 3600U) {
7823 if (sigvalidityinterval > 7200U) {
7824 jitter = isc_random_uniform(3600);
7825 } else {
7826 jitter = isc_random_uniform(1200);
7827 }
7828 expire = soaexpire - jitter - 1;
7829 } else {
7830 expire = soaexpire - 1;
7831 }
7832
7833 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
7834 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
7835
7836 /*
7837 * We keep pulling nodes off each iterator in turn until
7838 * we have no more nodes to pull off or we reach the limits
7839 * for this quantum.
7840 */
7841 nodes = zone->nodes;
7842 signatures = zone->signatures;
7843 LOCK_ZONE(zone);
7844 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
7845 UNLOCK_ZONE(zone);
7846 first = true;
7847
7848 if (nsec3chain != NULL) {
7849 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
7850 }
7851 /*
7852 * Generate new NSEC3 chains first.
7853 *
7854 * The following while loop iterates over nodes in the zone database,
7855 * updating the NSEC3 chain by calling dns_nsec3_addnsec3() for each of
7856 * them. Once all nodes are processed, the "delete_nsec" field is
7857 * consulted to check whether we are supposed to remove NSEC records
7858 * from the zone database; if so, the database iterator is reset to
7859 * point to the first node and the loop traverses all of them again,
7860 * this time removing NSEC records. If we hit a node which is obscured
7861 * by a delegation or a DNAME, nodes are skipped over until we find one
7862 * that is not obscured by the same obscuring name and then normal
7863 * processing is resumed.
7864 *
7865 * The above is repeated until all requested NSEC3 chain changes are
7866 * applied or when we reach the limits for this quantum, whichever
7867 * happens first.
7868 *
7869 * Note that the "signatures" variable is only used here to limit the
7870 * amount of work performed. Actual DNSSEC signatures are only
7871 * generated by dns__zone_updatesigs() calls later in this function.
7872 */
7873 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
7874 LOCK_ZONE(zone);
7875 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
7876
7877 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7878 if (nsec3chain->done || nsec3chain->db != zone->db) {
7879 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
7880 ISC_LIST_APPEND(cleanup, nsec3chain, link);
7881 }
7882 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7883 UNLOCK_ZONE(zone);
7884 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
7885 goto next_addchain;
7886
7887 /*
7888 * Possible future db.
7889 */
7890 if (nsec3chain->db != db) {
7891 goto next_addchain;
7892 }
7893
7894 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
7895 goto next_addchain;
7896
7897 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
7898
7899 if (nsec3chain->delete_nsec) {
7900 delegation = false;
7901 dns_dbiterator_pause(nsec3chain->dbiterator);
7902 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
7903 goto next_addnode;
7904 }
7905 /*
7906 * On the first pass we need to check if the current node
7907 * has not been obscured.
7908 */
7909 delegation = false;
7910 unsecure = false;
7911 if (first) {
7912 dns_fixedname_t ffound;
7913 dns_name_t *found;
7914 found = dns_fixedname_initname(&ffound);
7915 result = dns_db_find(db, name, version,
7916 dns_rdatatype_soa,
7917 DNS_DBFIND_NOWILD, 0, NULL, found,
7918 NULL, NULL);
7919 if ((result == DNS_R_DELEGATION ||
7920 result == DNS_R_DNAME) &&
7921 !dns_name_equal(name, found)) {
7922 /*
7923 * Remember the obscuring name so that
7924 * we skip all obscured names.
7925 */
7926 dns_name_copy(found, name, NULL);
7927 delegation = true;
7928 goto next_addnode;
7929 }
7930 }
7931
7932 /*
7933 * Check to see if this is a bottom of zone node.
7934 */
7935 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
7936 if (result == ISC_R_NOTFOUND) {
7937 /* Empty node? */
7938 goto next_addnode;
7939 }
7940 if (result != ISC_R_SUCCESS) {
7941 goto failure;
7942 }
7943
7944 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = false;
7945 for (result = dns_rdatasetiter_first(iterator);
7946 result == ISC_R_SUCCESS;
7947 result = dns_rdatasetiter_next(iterator))
7948 {
7949 dns_rdatasetiter_current(iterator, &rdataset);
7950 INSIST(rdataset.type != dns_rdatatype_nsec3);
7951 if (rdataset.type == dns_rdatatype_soa) {
7952 seen_soa = true;
7953 } else if (rdataset.type == dns_rdatatype_ns) {
7954 seen_ns = true;
7955 } else if (rdataset.type == dns_rdatatype_dname) {
7956 seen_dname = true;
7957 } else if (rdataset.type == dns_rdatatype_ds) {
7958 seen_ds = true;
7959 } else if (rdataset.type == dns_rdatatype_nsec) {
7960 seen_nsec = true;
7961 }
7962 dns_rdataset_disassociate(&rdataset);
7963 }
7964 dns_rdatasetiter_destroy(&iterator);
7965 /*
7966 * Is there a NSEC chain than needs to be cleaned up?
7967 */
7968 if (seen_nsec) {
7969 nsec3chain->seen_nsec = true;
7970 }
7971 if (seen_ns && !seen_soa && !seen_ds) {
7972 unsecure = true;
7973 }
7974 if ((seen_ns && !seen_soa) || seen_dname) {
7975 delegation = true;
7976 }
7977
7978 /*
7979 * Process one node.
7980 */
7981 dns_dbiterator_pause(nsec3chain->dbiterator);
7982 result = dns_nsec3_addnsec3(db, version, name,
7983 &nsec3chain->nsec3param,
7984 zone->minimum, unsecure,
7985 &nsec3_diff);
7986 if (result != ISC_R_SUCCESS) {
7987 dnssec_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
7988 "dns_nsec3_addnsec3 -> %s",
7989 dns_result_totext(result));
7990 goto failure;
7991 }
7992
7993 /*
7994 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
7995 * two signatures. Additionally there will, in general, be
7996 * two signature generated below.
7997 *
7998 * If we are only changing the optout flag the cost is half
7999 * that of the cost of generating a completely new chain.
8000 */
8001 signatures -= 4;
8002
8003 /*
8004 * Go onto next node.
8005 */
8006 next_addnode:
8007 first = false;
8008 dns_db_detachnode(db, &node);
8009 do {
8010 result = dns_dbiterator_next(nsec3chain->dbiterator);
8011
8012 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
8013 dns_dbiterator_pause(nsec3chain->dbiterator);
8014 CHECK(fixup_nsec3param(db, version, nsec3chain,
8015 false, privatetype,
8016 ¶m_diff));
8017 LOCK_ZONE(zone);
8018 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
8019 link);
8020 UNLOCK_ZONE(zone);
8021 ISC_LIST_APPEND(cleanup, nsec3chain, link);
8022 goto next_addchain;
8023 }
8024 if (result == ISC_R_NOMORE) {
8025 dns_dbiterator_pause(nsec3chain->dbiterator);
8026 if (nsec3chain->seen_nsec) {
8027 CHECK(fixup_nsec3param(db, version,
8028 nsec3chain,
8029 true,
8030 privatetype,
8031 ¶m_diff));
8032 nsec3chain->delete_nsec = true;
8033 goto same_addchain;
8034 }
8035 CHECK(fixup_nsec3param(db, version, nsec3chain,
8036 false, privatetype,
8037 ¶m_diff));
8038 LOCK_ZONE(zone);
8039 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
8040 link);
8041 UNLOCK_ZONE(zone);
8042 ISC_LIST_APPEND(cleanup, nsec3chain, link);
8043 goto next_addchain;
8044 } else if (result != ISC_R_SUCCESS) {
8045 dnssec_log(zone, ISC_LOG_ERROR,
8046 "zone_nsec3chain:"
8047 "dns_dbiterator_next -> %s",
8048 dns_result_totext(result));
8049 goto failure;
8050 } else if (delegation) {
8051 dns_dbiterator_current(nsec3chain->dbiterator,
8052 &node, nextname);
8053 dns_db_detachnode(db, &node);
8054 if (!dns_name_issubdomain(nextname, name))
8055 break;
8056 } else {
8057 break;
8058 }
8059 } while (1);
8060 continue;
8061
8062 same_addchain:
8063 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
8064 first = true;
8065 continue;
8066
8067 next_addchain:
8068 dns_dbiterator_pause(nsec3chain->dbiterator);
8069 nsec3chain = nextnsec3chain;
8070 first = true;
8071 if (nsec3chain != NULL) {
8072 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
8073 }
8074 }
8075
8076 if (nsec3chain != NULL) {
8077 goto skip_removals;
8078 }
8079
8080 /*
8081 * Process removals.
8082 *
8083 * This is a counterpart of the above while loop which takes care of
8084 * removing an NSEC3 chain. It starts with determining whether the
8085 * zone needs to switch from NSEC3 to NSEC; if so, it first builds an
8086 * NSEC chain by iterating over all nodes in the zone database and only
8087 * then goes on to remove NSEC3 records be iterating over all nodes
8088 * again and calling deletematchingnsec3() for each of them; otherwise,
8089 * it starts removing NSEC3 records immediately. Rules for processing
8090 * obscured nodes and interrupting work are the same as for the while
8091 * loop above.
8092 */
8093 LOCK_ZONE(zone);
8094 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
8095 UNLOCK_ZONE(zone);
8096 first = true;
8097 buildnsecchain = false;
8098 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
8099 LOCK_ZONE(zone);
8100 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
8101 UNLOCK_ZONE(zone);
8102
8103 if (nsec3chain->db != db) {
8104 goto next_removechain;
8105 }
8106
8107 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) {
8108 goto next_removechain;
8109 }
8110
8111 /*
8112 * Work out if we need to build a NSEC chain as a consequence
8113 * of removing this NSEC3 chain.
8114 */
8115 if (first && !updatensec &&
8116 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
8117 {
8118 result = need_nsec_chain(db, version,
8119 &nsec3chain->nsec3param,
8120 &buildnsecchain);
8121 if (result != ISC_R_SUCCESS) {
8122 dnssec_log(zone, ISC_LOG_ERROR,
8123 "zone_nsec3chain:"
8124 "need_nsec_chain -> %s",
8125 dns_result_totext(result));
8126 goto failure;
8127 }
8128 }
8129
8130 if (first) {
8131 dnssec_log(zone, ISC_LOG_DEBUG(3),
8132 "zone_nsec3chain:buildnsecchain = %u\n",
8133 buildnsecchain);
8134 }
8135
8136 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
8137 delegation = false;
8138
8139 if (!buildnsecchain) {
8140 /*
8141 * Delete the NSEC3PARAM record matching this chain.
8142 */
8143 if (first) {
8144 result = fixup_nsec3param(db, version,
8145 nsec3chain,
8146 true, privatetype,
8147 ¶m_diff);
8148 if (result != ISC_R_SUCCESS) {
8149 dnssec_log(zone, ISC_LOG_ERROR,
8150 "zone_nsec3chain:"
8151 "fixup_nsec3param -> %s",
8152 dns_result_totext(result));
8153 goto failure;
8154 }
8155 }
8156
8157 /*
8158 * Delete the NSEC3 records.
8159 */
8160 result = deletematchingnsec3(db, version, node, name,
8161 &nsec3chain->nsec3param,
8162 &nsec3_diff);
8163 if (result != ISC_R_SUCCESS) {
8164 dnssec_log(zone, ISC_LOG_ERROR,
8165 "zone_nsec3chain:"
8166 "deletematchingnsec3 -> %s",
8167 dns_result_totext(result));
8168 goto failure;
8169 }
8170 goto next_removenode;
8171 }
8172
8173 if (first) {
8174 dns_fixedname_t ffound;
8175 dns_name_t *found;
8176 found = dns_fixedname_initname(&ffound);
8177 result = dns_db_find(db, name, version,
8178 dns_rdatatype_soa,
8179 DNS_DBFIND_NOWILD, 0, NULL, found,
8180 NULL, NULL);
8181 if ((result == DNS_R_DELEGATION ||
8182 result == DNS_R_DNAME) &&
8183 !dns_name_equal(name, found))
8184 {
8185 /*
8186 * Remember the obscuring name so that
8187 * we skip all obscured names.
8188 */
8189 dns_name_copy(found, name, NULL);
8190 delegation = true;
8191 goto next_removenode;
8192 }
8193 }
8194
8195 /*
8196 * Check to see if this is a bottom of zone node.
8197 */
8198 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
8199 if (result == ISC_R_NOTFOUND) {
8200 /* Empty node? */
8201 goto next_removenode;
8202 }
8203 if (result != ISC_R_SUCCESS) {
8204 goto failure;
8205 }
8206
8207 seen_soa = seen_ns = seen_dname = seen_nsec3 =
8208 seen_nsec = seen_rr = false;
8209 for (result = dns_rdatasetiter_first(iterator);
8210 result == ISC_R_SUCCESS;
8211 result = dns_rdatasetiter_next(iterator))
8212 {
8213 dns_rdatasetiter_current(iterator, &rdataset);
8214 if (rdataset.type == dns_rdatatype_soa) {
8215 seen_soa = true;
8216 } else if (rdataset.type == dns_rdatatype_ns) {
8217 seen_ns = true;
8218 } else if (rdataset.type == dns_rdatatype_dname) {
8219 seen_dname = true;
8220 } else if (rdataset.type == dns_rdatatype_nsec) {
8221 seen_nsec = true;
8222 } else if (rdataset.type == dns_rdatatype_nsec3) {
8223 seen_nsec3 = true;
8224 } else if (rdataset.type != dns_rdatatype_rrsig) {
8225 seen_rr = true;
8226 }
8227 dns_rdataset_disassociate(&rdataset);
8228 }
8229 dns_rdatasetiter_destroy(&iterator);
8230
8231 if (!seen_rr || seen_nsec3 || seen_nsec) {
8232 goto next_removenode;
8233 }
8234 if ((seen_ns && !seen_soa) || seen_dname) {
8235 delegation = true;
8236 }
8237
8238 /*
8239 * Add a NSEC record except at the origin.
8240 */
8241 if (!dns_name_equal(name, dns_db_origin(db))) {
8242 dns_dbiterator_pause(nsec3chain->dbiterator);
8243 CHECK(add_nsec(db, version, name, node, zone->minimum,
8244 delegation, &nsec_diff));
8245 signatures--;
8246 }
8247
8248 next_removenode:
8249 first = false;
8250 dns_db_detachnode(db, &node);
8251 do {
8252 result = dns_dbiterator_next(nsec3chain->dbiterator);
8253 if (result == ISC_R_NOMORE && buildnsecchain) {
8254 /*
8255 * The NSEC chain should now be built.
8256 * We can now remove the NSEC3 chain.
8257 */
8258 updatensec = true;
8259 goto same_removechain;
8260 }
8261 if (result == ISC_R_NOMORE) {
8262 LOCK_ZONE(zone);
8263 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
8264 link);
8265 UNLOCK_ZONE(zone);
8266 ISC_LIST_APPEND(cleanup, nsec3chain, link);
8267 dns_dbiterator_pause(nsec3chain->dbiterator);
8268 result = fixup_nsec3param(db, version,
8269 nsec3chain, false,
8270 privatetype,
8271 ¶m_diff);
8272 if (result != ISC_R_SUCCESS) {
8273 dnssec_log(zone, ISC_LOG_ERROR,
8274 "zone_nsec3chain:"
8275 "fixup_nsec3param -> %s",
8276 dns_result_totext(result));
8277 goto failure;
8278 }
8279 goto next_removechain;
8280 } else if (result != ISC_R_SUCCESS) {
8281 dnssec_log(zone, ISC_LOG_ERROR,
8282 "zone_nsec3chain:"
8283 "dns_dbiterator_next -> %s",
8284 dns_result_totext(result));
8285 goto failure;
8286 } else if (delegation) {
8287 dns_dbiterator_current(nsec3chain->dbiterator,
8288 &node, nextname);
8289 dns_db_detachnode(db, &node);
8290 if (!dns_name_issubdomain(nextname, name)) {
8291 break;
8292 }
8293 } else {
8294 break;
8295 }
8296 } while (1);
8297 continue;
8298
8299 same_removechain:
8300 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
8301 buildnsecchain = false;
8302 first = true;
8303 continue;
8304
8305 next_removechain:
8306 dns_dbiterator_pause(nsec3chain->dbiterator);
8307 nsec3chain = nextnsec3chain;
8308 first = true;
8309 }
8310
8311 skip_removals:
8312 /*
8313 * We may need to update the NSEC/NSEC3 records for the zone apex.
8314 */
8315 if (!ISC_LIST_EMPTY(param_diff.tuples)) {
8316 bool rebuild_nsec = false,
8317 rebuild_nsec3 = false;
8318 result = dns_db_getoriginnode(db, &node);
8319 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8320 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
8321 if (result != ISC_R_SUCCESS) {
8322 dnssec_log(zone, ISC_LOG_ERROR,
8323 "zone_nsec3chain:dns_db_allrdatasets -> %s",
8324 dns_result_totext(result));
8325 goto failure;
8326 }
8327 for (result = dns_rdatasetiter_first(iterator);
8328 result == ISC_R_SUCCESS;
8329 result = dns_rdatasetiter_next(iterator))
8330 {
8331 dns_rdatasetiter_current(iterator, &rdataset);
8332 if (rdataset.type == dns_rdatatype_nsec) {
8333 rebuild_nsec = true;
8334 } else if (rdataset.type == dns_rdatatype_nsec3param) {
8335 rebuild_nsec3 = true;
8336 }
8337 dns_rdataset_disassociate(&rdataset);
8338 }
8339 dns_rdatasetiter_destroy(&iterator);
8340 dns_db_detachnode(db, &node);
8341
8342 if (rebuild_nsec) {
8343 if (nsec3chain != NULL) {
8344 dns_dbiterator_pause(nsec3chain->dbiterator);
8345 }
8346
8347 result = updatesecure(db, version, &zone->origin,
8348 zone->minimum, true,
8349 &nsec_diff);
8350 if (result != ISC_R_SUCCESS) {
8351 dnssec_log(zone, ISC_LOG_ERROR,
8352 "zone_nsec3chain:updatesecure -> %s",
8353 dns_result_totext(result));
8354 goto failure;
8355 }
8356 }
8357
8358 if (rebuild_nsec3) {
8359 if (nsec3chain != NULL) {
8360 dns_dbiterator_pause(nsec3chain->dbiterator);
8361 }
8362
8363 result = dns_nsec3_addnsec3s(db, version,
8364 dns_db_origin(db),
8365 zone->minimum, false,
8366 &nsec3_diff);
8367 if (result != ISC_R_SUCCESS) {
8368 dnssec_log(zone, ISC_LOG_ERROR,
8369 "zone_nsec3chain:"
8370 "dns_nsec3_addnsec3s -> %s",
8371 dns_result_totext(result));
8372 goto failure;
8373 }
8374 }
8375 }
8376
8377 /*
8378 * Add / update signatures for the NSEC3 records.
8379 */
8380 if (nsec3chain != NULL) {
8381 dns_dbiterator_pause(nsec3chain->dbiterator);
8382 }
8383 result = dns__zone_updatesigs(&nsec3_diff, db, version, zone_keys,
8384 nkeys, zone, inception, expire, 0, now,
8385 check_ksk, keyset_kskonly, &zonediff);
8386 if (result != ISC_R_SUCCESS) {
8387 dnssec_log(zone, ISC_LOG_ERROR,
8388 "zone_nsec3chain:dns__zone_updatesigs -> %s",
8389 dns_result_totext(result));
8390 goto failure;
8391 }
8392
8393 /*
8394 * We have changed the NSEC3PARAM or private RRsets
8395 * above so we need to update the signatures.
8396 */
8397 result = dns__zone_updatesigs(¶m_diff, db, version, zone_keys,
8398 nkeys, zone, inception, expire, 0, now,
8399 check_ksk, keyset_kskonly, &zonediff);
8400 if (result != ISC_R_SUCCESS) {
8401 dnssec_log(zone, ISC_LOG_ERROR,
8402 "zone_nsec3chain:dns__zone_updatesigs -> %s",
8403 dns_result_totext(result));
8404 goto failure;
8405 }
8406
8407 if (updatensec) {
8408 result = updatesecure(db, version, &zone->origin,
8409 zone->minimum, false, &nsec_diff);
8410 if (result != ISC_R_SUCCESS) {
8411 dnssec_log(zone, ISC_LOG_ERROR,
8412 "zone_nsec3chain:updatesecure -> %s",
8413 dns_result_totext(result));
8414 goto failure;
8415 }
8416 }
8417
8418 result = dns__zone_updatesigs(&nsec_diff, db, version, zone_keys,
8419 nkeys, zone, inception, expire, 0, now,
8420 check_ksk, keyset_kskonly, &zonediff);
8421 if (result != ISC_R_SUCCESS) {
8422 dnssec_log(zone, ISC_LOG_ERROR,
8423 "zone_nsec3chain:dns__zone_updatesigs -> %s",
8424 dns_result_totext(result));
8425 goto failure;
8426 }
8427
8428 /*
8429 * If we made no effective changes to the zone then we can just
8430 * cleanup otherwise we need to increment the serial.
8431 */
8432 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
8433 /*
8434 * No need to call dns_db_closeversion() here as it is
8435 * called with commit = true below.
8436 */
8437 goto done;
8438 }
8439
8440 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
8441 &zonediff, zone_keys, nkeys, now, false);
8442 if (result != ISC_R_SUCCESS) {
8443 dnssec_log(zone, ISC_LOG_ERROR,
8444 "zone_nsec3chain:del_sigs -> %s",
8445 dns_result_totext(result));
8446 goto failure;
8447 }
8448
8449 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
8450 zone->updatemethod);
8451 if (result != ISC_R_SUCCESS) {
8452 dnssec_log(zone, ISC_LOG_ERROR,
8453 "zone_nsec3chain:update_soa_serial -> %s",
8454 dns_result_totext(result));
8455 goto failure;
8456 }
8457
8458 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
8459 zonediff.diff, zone_keys, nkeys, zone->mctx,
8460 inception, soaexpire, check_ksk, keyset_kskonly);
8461 if (result != ISC_R_SUCCESS) {
8462 dnssec_log(zone, ISC_LOG_ERROR,
8463 "zone_nsec3chain:add_sigs -> %s",
8464 dns_result_totext(result));
8465 goto failure;
8466 }
8467
8468 /* Write changes to journal file. */
8469 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain"));
8470
8471 LOCK_ZONE(zone);
8472 zone_needdump(zone, DNS_DUMP_DELAY);
8473 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
8474 UNLOCK_ZONE(zone);
8475
8476 done:
8477 /*
8478 * Pause all iterators so that dns_db_closeversion() can succeed.
8479 */
8480 LOCK_ZONE(zone);
8481 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
8482 nsec3chain != NULL;
8483 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
8484 {
8485 dns_dbiterator_pause(nsec3chain->dbiterator);
8486 }
8487 UNLOCK_ZONE(zone);
8488
8489 /*
8490 * Everything has succeeded. Commit the changes.
8491 * Unconditionally commit as zonediff.offline not checked above.
8492 */
8493 dns_db_closeversion(db, &version, true);
8494
8495 /*
8496 * Everything succeeded so we can clean these up now.
8497 */
8498 nsec3chain = ISC_LIST_HEAD(cleanup);
8499 while (nsec3chain != NULL) {
8500 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
8501 dns_db_detach(&nsec3chain->db);
8502 dns_dbiterator_destroy(&nsec3chain->dbiterator);
8503 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
8504 nsec3chain = ISC_LIST_HEAD(cleanup);
8505 }
8506
8507 set_resigntime(zone);
8508
8509 failure:
8510 if (result != ISC_R_SUCCESS) {
8511 dnssec_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
8512 dns_result_totext(result));
8513 }
8514
8515 /*
8516 * On error roll back the current nsec3chain.
8517 */
8518 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
8519 if (nsec3chain->done) {
8520 dns_db_detach(&nsec3chain->db);
8521 dns_dbiterator_destroy(&nsec3chain->dbiterator);
8522 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
8523 } else {
8524 result = dns_dbiterator_first(nsec3chain->dbiterator);
8525 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8526 dns_dbiterator_pause(nsec3chain->dbiterator);
8527 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
8528 }
8529 }
8530
8531 /*
8532 * Rollback the cleanup list.
8533 */
8534 nsec3chain = ISC_LIST_TAIL(cleanup);
8535 while (nsec3chain != NULL) {
8536 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
8537 if (nsec3chain->done) {
8538 dns_db_detach(&nsec3chain->db);
8539 dns_dbiterator_destroy(&nsec3chain->dbiterator);
8540 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
8541 } else {
8542 LOCK_ZONE(zone);
8543 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
8544 UNLOCK_ZONE(zone);
8545 result = dns_dbiterator_first(nsec3chain->dbiterator);
8546 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8547 dns_dbiterator_pause(nsec3chain->dbiterator);
8548 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
8549 }
8550 nsec3chain = ISC_LIST_TAIL(cleanup);
8551 }
8552
8553 LOCK_ZONE(zone);
8554 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
8555 nsec3chain != NULL;
8556 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
8557 {
8558 dns_dbiterator_pause(nsec3chain->dbiterator);
8559 }
8560 UNLOCK_ZONE(zone);
8561
8562 dns_diff_clear(¶m_diff);
8563 dns_diff_clear(&nsec3_diff);
8564 dns_diff_clear(&nsec_diff);
8565 dns_diff_clear(&_sig_diff);
8566
8567 if (iterator != NULL) {
8568 dns_rdatasetiter_destroy(&iterator);
8569 }
8570
8571 for (i = 0; i < nkeys; i++) {
8572 dst_key_free(&zone_keys[i]);
8573 }
8574
8575 if (node != NULL) {
8576 dns_db_detachnode(db, &node);
8577 }
8578 if (version != NULL) {
8579 dns_db_closeversion(db, &version, false);
8580 dns_db_detach(&db);
8581 } else if (db != NULL) {
8582 dns_db_detach(&db);
8583 }
8584
8585 LOCK_ZONE(zone);
8586 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
8587 isc_interval_t interval;
8588 if (zone->update_disabled || result != ISC_R_SUCCESS) {
8589 isc_interval_set(&interval, 60, 0); /* 1 minute */
8590 } else {
8591 isc_interval_set(&interval, 0, 10000000); /* 10 ms */
8592 }
8593 isc_time_nowplusinterval(&zone->nsec3chaintime, &interval);
8594 } else {
8595 isc_time_settoepoch(&zone->nsec3chaintime);
8596 }
8597 UNLOCK_ZONE(zone);
8598
8599 INSIST(version == NULL);
8600 }
8601
8602 /*%
8603 * Delete all RRSIG records with the given algorithm and keyid.
8604 * Remove the NSEC record and RRSIGs if nkeys is zero.
8605 * If all remaining RRsets are signed with the given algorithm
8606 * set *has_algp to true.
8607 */
8608 static isc_result_t
8609 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
8610 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
8611 uint16_t keyid, bool *has_algp, dns_diff_t *diff)
8612 {
8613 dns_rdata_rrsig_t rrsig;
8614 dns_rdataset_t rdataset;
8615 dns_rdatasetiter_t *iterator = NULL;
8616 isc_result_t result;
8617 bool alg_missed = false;
8618 bool alg_found = false;
8619
8620 char namebuf[DNS_NAME_FORMATSIZE];
8621 dns_name_format(name, namebuf, sizeof(namebuf));
8622
8623 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
8624 if (result != ISC_R_SUCCESS) {
8625 if (result == ISC_R_NOTFOUND)
8626 result = ISC_R_SUCCESS;
8627 return (result);
8628 }
8629
8630 dns_rdataset_init(&rdataset);
8631 for (result = dns_rdatasetiter_first(iterator);
8632 result == ISC_R_SUCCESS;
8633 result = dns_rdatasetiter_next(iterator)) {
8634 bool has_alg = false;
8635 dns_rdatasetiter_current(iterator, &rdataset);
8636 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
8637 for (result = dns_rdataset_first(&rdataset);
8638 result == ISC_R_SUCCESS;
8639 result = dns_rdataset_next(&rdataset)) {
8640 dns_rdata_t rdata = DNS_RDATA_INIT;
8641 dns_rdataset_current(&rdataset, &rdata);
8642 CHECK(update_one_rr(db, version, diff,
8643 DNS_DIFFOP_DEL, name,
8644 rdataset.ttl, &rdata));
8645 }
8646 if (result != ISC_R_NOMORE)
8647 goto failure;
8648 dns_rdataset_disassociate(&rdataset);
8649 continue;
8650 }
8651 if (rdataset.type != dns_rdatatype_rrsig) {
8652 dns_rdataset_disassociate(&rdataset);
8653 continue;
8654 }
8655 for (result = dns_rdataset_first(&rdataset);
8656 result == ISC_R_SUCCESS;
8657 result = dns_rdataset_next(&rdataset))
8658 {
8659 dns_rdata_t rdata = DNS_RDATA_INIT;
8660 dns_rdataset_current(&rdataset, &rdata);
8661 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
8662 if (nkeys != 0 &&
8663 (rrsig.algorithm != algorithm ||
8664 rrsig.keyid != keyid))
8665 {
8666 if (rrsig.algorithm == algorithm) {
8667 has_alg = true;
8668 }
8669 continue;
8670 }
8671 CHECK(update_one_rr(db, version, diff,
8672 DNS_DIFFOP_DELRESIGN, name,
8673 rdataset.ttl, &rdata));
8674 }
8675 dns_rdataset_disassociate(&rdataset);
8676 if (result != ISC_R_NOMORE)
8677 break;
8678
8679 /*
8680 * After deleting, if there's still a signature for
8681 * 'algorithm', set alg_found; if not, set alg_missed.
8682 */
8683 if (has_alg) {
8684 alg_found = true;
8685 } else {
8686 alg_missed = true;
8687 }
8688 }
8689 if (result == ISC_R_NOMORE)
8690 result = ISC_R_SUCCESS;
8691
8692 /*
8693 * Set `has_algp` if the algorithm was found in every RRset:
8694 * i.e., found in at least one, and not missing from any.
8695 */
8696 *has_algp = (alg_found && !alg_missed);
8697 failure:
8698 if (dns_rdataset_isassociated(&rdataset))
8699 dns_rdataset_disassociate(&rdataset);
8700 dns_rdatasetiter_destroy(&iterator);
8701 return (result);
8702 }
8703
8704 /*
8705 * Incrementally sign the zone using the keys requested.
8706 * Builds the NSEC chain if required.
8707 */
8708 static void
8709 zone_sign(dns_zone_t *zone) {
8710 const char *me = "zone_sign";
8711 dns_db_t *db = NULL;
8712 dns_dbnode_t *node = NULL;
8713 dns_dbversion_t *version = NULL;
8714 dns_diff_t _sig_diff;
8715 dns_diff_t post_diff;
8716 dns__zonediff_t zonediff;
8717 dns_fixedname_t fixed;
8718 dns_fixedname_t nextfixed;
8719 dns_name_t *name, *nextname;
8720 dns_rdataset_t rdataset;
8721 dns_signing_t *signing, *nextsigning;
8722 dns_signinglist_t cleanup;
8723 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
8724 int32_t signatures;
8725 bool check_ksk, keyset_kskonly, is_ksk;
8726 bool with_ksk, with_zsk;
8727 bool commit = false;
8728 bool is_bottom_of_zone;
8729 bool build_nsec = false;
8730 bool build_nsec3 = false;
8731 bool first;
8732 isc_result_t result;
8733 isc_stdtime_t now, inception, soaexpire, expire;
8734 uint32_t jitter, sigvalidityinterval, expiryinterval;
8735 unsigned int i, j;
8736 unsigned int nkeys = 0;
8737 uint32_t nodes;
8738
8739 ENTER;
8740
8741 dns_rdataset_init(&rdataset);
8742 name = dns_fixedname_initname(&fixed);
8743 nextname = dns_fixedname_initname(&nextfixed);
8744 dns_diff_init(zone->mctx, &_sig_diff);
8745 dns_diff_init(zone->mctx, &post_diff);
8746 zonediff_init(&zonediff, &_sig_diff);
8747 ISC_LIST_INIT(cleanup);
8748
8749 /*
8750 * Updates are disabled. Pause for 1 minute.
8751 */
8752 if (zone->update_disabled) {
8753 result = ISC_R_FAILURE;
8754 goto cleanup;
8755 }
8756
8757 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8758 if (zone->db != NULL) {
8759 dns_db_attach(zone->db, &db);
8760 }
8761 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8762 if (db == NULL) {
8763 result = ISC_R_FAILURE;
8764 goto cleanup;
8765 }
8766
8767 result = dns_db_newversion(db, &version);
8768 if (result != ISC_R_SUCCESS) {
8769 dnssec_log(zone, ISC_LOG_ERROR,
8770 "zone_sign:dns_db_newversion -> %s",
8771 dns_result_totext(result));
8772 goto cleanup;
8773 }
8774
8775 isc_stdtime_get(&now);
8776
8777 result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
8778 DNS_MAXZONEKEYS, zone_keys, &nkeys);
8779 if (result != ISC_R_SUCCESS) {
8780 dnssec_log(zone, ISC_LOG_ERROR,
8781 "zone_sign:dns__zone_findkeys -> %s",
8782 dns_result_totext(result));
8783 goto cleanup;
8784 }
8785
8786 sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
8787 inception = now - 3600; /* Allow for clock skew. */
8788 soaexpire = now + sigvalidityinterval;
8789 expiryinterval = dns_zone_getsigresigninginterval(zone);
8790 if (expiryinterval > sigvalidityinterval) {
8791 expiryinterval = sigvalidityinterval;
8792 } else {
8793 expiryinterval = sigvalidityinterval - expiryinterval;
8794 }
8795
8796 /*
8797 * Spread out signatures over time if they happen to be
8798 * clumped. We don't do this for each add_sigs() call as
8799 * we still want some clustering to occur.
8800 */
8801 if (sigvalidityinterval >= 3600U) {
8802 if (sigvalidityinterval > 7200U) {
8803 jitter = isc_random_uniform(expiryinterval);
8804 } else {
8805 jitter = isc_random_uniform(1200);
8806 }
8807 expire = soaexpire - jitter - 1;
8808 } else {
8809 expire = soaexpire - 1;
8810 }
8811
8812 /*
8813 * We keep pulling nodes off each iterator in turn until
8814 * we have no more nodes to pull off or we reach the limits
8815 * for this quantum.
8816 */
8817 nodes = zone->nodes;
8818 signatures = zone->signatures;
8819 signing = ISC_LIST_HEAD(zone->signing);
8820 first = true;
8821
8822 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
8823 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
8824
8825 /* Determine which type of chain to build */
8826 CHECK(dns_private_chains(db, version, zone->privatetype,
8827 &build_nsec, &build_nsec3));
8828
8829 /* If neither chain is found, default to NSEC */
8830 if (!build_nsec && !build_nsec3) {
8831 build_nsec = true;
8832 }
8833
8834 while (signing != NULL && nodes-- > 0 && signatures > 0) {
8835 bool has_alg = false;
8836 nextsigning = ISC_LIST_NEXT(signing, link);
8837
8838 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8839 if (signing->done || signing->db != zone->db) {
8840 /*
8841 * The zone has been reloaded. We will have
8842 * created new signings as part of the reload
8843 * process so we can destroy this one.
8844 */
8845 ISC_LIST_UNLINK(zone->signing, signing, link);
8846 ISC_LIST_APPEND(cleanup, signing, link);
8847 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8848 goto next_signing;
8849 }
8850 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8851
8852 if (signing->db != db) {
8853 goto next_signing;
8854 }
8855
8856 is_bottom_of_zone = false;
8857
8858 if (first && signing->deleteit) {
8859 /*
8860 * Remove the key we are deleting from consideration.
8861 */
8862 for (i = 0, j = 0; i < nkeys; i++) {
8863 /*
8864 * Find the key we want to remove.
8865 */
8866 if (ALG(zone_keys[i]) == signing->algorithm &&
8867 dst_key_id(zone_keys[i]) == signing->keyid)
8868 {
8869 if (KSK(zone_keys[i]))
8870 dst_key_free(&zone_keys[i]);
8871 continue;
8872 }
8873 zone_keys[j] = zone_keys[i];
8874 j++;
8875 }
8876 for (i = j; i < nkeys; i++) {
8877 zone_keys[i] = NULL;
8878 }
8879 nkeys = j;
8880 }
8881
8882 dns_dbiterator_current(signing->dbiterator, &node, name);
8883
8884 if (signing->deleteit) {
8885 dns_dbiterator_pause(signing->dbiterator);
8886 CHECK(del_sig(db, version, name, node, nkeys,
8887 signing->algorithm, signing->keyid,
8888 &has_alg, zonediff.diff));
8889 }
8890
8891 /*
8892 * On the first pass we need to check if the current node
8893 * has not been obscured.
8894 */
8895 if (first) {
8896 dns_fixedname_t ffound;
8897 dns_name_t *found;
8898 found = dns_fixedname_initname(&ffound);
8899 result = dns_db_find(db, name, version,
8900 dns_rdatatype_soa,
8901 DNS_DBFIND_NOWILD, 0, NULL, found,
8902 NULL, NULL);
8903 if ((result == DNS_R_DELEGATION ||
8904 result == DNS_R_DNAME) &&
8905 !dns_name_equal(name, found))
8906 {
8907 /*
8908 * Remember the obscuring name so that
8909 * we skip all obscured names.
8910 */
8911 dns_name_copy(found, name, NULL);
8912 is_bottom_of_zone = true;
8913 goto next_node;
8914 }
8915 }
8916
8917 /*
8918 * Process one node.
8919 */
8920 with_ksk = false;
8921 with_zsk = false;
8922 dns_dbiterator_pause(signing->dbiterator);
8923
8924 CHECK(check_if_bottom_of_zone(db, node, version,
8925 &is_bottom_of_zone));
8926
8927 for (i = 0; !has_alg && i < nkeys; i++) {
8928 bool both = false;
8929
8930 /*
8931 * Find the keys we want to sign with.
8932 */
8933 if (!dst_key_isprivate(zone_keys[i])) {
8934 continue;
8935 }
8936 if (dst_key_inactive(zone_keys[i])) {
8937 continue;
8938 }
8939
8940 /*
8941 * When adding look for the specific key.
8942 */
8943 if (!signing->deleteit &&
8944 (dst_key_alg(zone_keys[i]) != signing->algorithm ||
8945 dst_key_id(zone_keys[i]) != signing->keyid))
8946 {
8947 continue;
8948 }
8949
8950 /*
8951 * When deleting make sure we are properly signed
8952 * with the algorithm that was being removed.
8953 */
8954 if (signing->deleteit &&
8955 ALG(zone_keys[i]) != signing->algorithm)
8956 {
8957 continue;
8958 }
8959
8960 /*
8961 * Do we do KSK processing?
8962 */
8963 if (check_ksk && !REVOKE(zone_keys[i])) {
8964 bool have_ksk, have_nonksk;
8965 if (KSK(zone_keys[i])) {
8966 have_ksk = true;
8967 have_nonksk = false;
8968 } else {
8969 have_ksk = false;
8970 have_nonksk = true;
8971 }
8972 for (j = 0; j < nkeys; j++) {
8973 if (j == i ||
8974 (ALG(zone_keys[i]) !=
8975 ALG(zone_keys[j])))
8976 {
8977 continue;
8978 }
8979 /* Don't consider inactive keys, however
8980 * the key may be temporary offline, so do
8981 * consider keys which private key files are
8982 * unavailable.
8983 */
8984 if (dst_key_inactive(zone_keys[j])) {
8985 continue;
8986 }
8987 if (REVOKE(zone_keys[j])) {
8988 continue;
8989 }
8990 if (KSK(zone_keys[j])) {
8991 have_ksk = true;
8992 } else {
8993 have_nonksk = true;
8994 }
8995 both = have_ksk && have_nonksk;
8996 if (both) {
8997 break;
8998 }
8999 }
9000 }
9001 if (both || REVOKE(zone_keys[i])) {
9002 is_ksk = KSK(zone_keys[i]);
9003 } else {
9004 is_ksk = false;
9005 }
9006
9007 /*
9008 * If deleting signatures, we need to ensure that
9009 * the RRset is still signed at least once by a
9010 * KSK and a ZSK.
9011 */
9012 if (signing->deleteit && !is_ksk && with_zsk) {
9013 continue;
9014 }
9015
9016 if (signing->deleteit && is_ksk && with_ksk) {
9017 continue;
9018 }
9019
9020 CHECK(sign_a_node(db, zone, name, node, version,
9021 build_nsec3, build_nsec,
9022 zone_keys[i], inception, expire,
9023 zone->minimum, is_ksk,
9024 (both && keyset_kskonly),
9025 is_bottom_of_zone, zonediff.diff,
9026 &signatures, zone->mctx));
9027 /*
9028 * If we are adding we are done. Look for other keys
9029 * of the same algorithm if deleting.
9030 */
9031 if (!signing->deleteit) {
9032 break;
9033 }
9034 if (!is_ksk) {
9035 with_zsk = true;
9036 }
9037 if (KSK(zone_keys[i])) {
9038 with_ksk = true;
9039 }
9040 }
9041
9042 /*
9043 * Go onto next node.
9044 */
9045 next_node:
9046 first = false;
9047 dns_db_detachnode(db, &node);
9048 do {
9049 result = dns_dbiterator_next(signing->dbiterator);
9050 if (result == ISC_R_NOMORE) {
9051 ISC_LIST_UNLINK(zone->signing, signing, link);
9052 ISC_LIST_APPEND(cleanup, signing, link);
9053 dns_dbiterator_pause(signing->dbiterator);
9054 if (nkeys != 0 && build_nsec) {
9055 /*
9056 * We have finished regenerating the
9057 * zone with a zone signing key.
9058 * The NSEC chain is now complete and
9059 * there is a full set of signatures
9060 * for the zone. We can now clear the
9061 * OPT bit from the NSEC record.
9062 */
9063 result = updatesecure(db, version,
9064 &zone->origin,
9065 zone->minimum,
9066 false,
9067 &post_diff);
9068 if (result != ISC_R_SUCCESS) {
9069 dnssec_log(zone, ISC_LOG_ERROR,
9070 "updatesecure -> %s",
9071 dns_result_totext(result));
9072 goto cleanup;
9073 }
9074 }
9075 result = updatesignwithkey(zone, signing,
9076 version,
9077 build_nsec3,
9078 zone->minimum,
9079 &post_diff);
9080 if (result != ISC_R_SUCCESS) {
9081 dnssec_log(zone, ISC_LOG_ERROR,
9082 "updatesignwithkey -> %s",
9083 dns_result_totext(result));
9084 goto cleanup;
9085 }
9086 build_nsec = false;
9087 goto next_signing;
9088 } else if (result != ISC_R_SUCCESS) {
9089 dnssec_log(zone, ISC_LOG_ERROR,
9090 "zone_sign:"
9091 "dns_dbiterator_next -> %s",
9092 dns_result_totext(result));
9093 goto cleanup;
9094 } else if (is_bottom_of_zone) {
9095 dns_dbiterator_current(signing->dbiterator,
9096 &node, nextname);
9097 dns_db_detachnode(db, &node);
9098 if (!dns_name_issubdomain(nextname, name)) {
9099 break;
9100 }
9101 } else {
9102 break;
9103 }
9104 } while (1);
9105 continue;
9106
9107 next_signing:
9108 dns_dbiterator_pause(signing->dbiterator);
9109 signing = nextsigning;
9110 first = true;
9111 }
9112
9113 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
9114 result = dns__zone_updatesigs(&post_diff, db, version,
9115 zone_keys, nkeys, zone,
9116 inception, expire, 0, now,
9117 check_ksk, keyset_kskonly,
9118 &zonediff);
9119 if (result != ISC_R_SUCCESS) {
9120 dnssec_log(zone, ISC_LOG_ERROR,
9121 "zone_sign:dns__zone_updatesigs -> %s",
9122 dns_result_totext(result));
9123 goto cleanup;
9124 }
9125 }
9126
9127 /*
9128 * Have we changed anything?
9129 */
9130 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
9131 if (zonediff.offline) {
9132 commit = true;
9133 }
9134 result = ISC_R_SUCCESS;
9135 goto pauseall;
9136 }
9137
9138 commit = true;
9139
9140 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
9141 &zonediff, zone_keys, nkeys, now, false);
9142 if (result != ISC_R_SUCCESS) {
9143 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:del_sigs -> %s",
9144 dns_result_totext(result));
9145 goto cleanup;
9146 }
9147
9148 result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
9149 zone->updatemethod);
9150 if (result != ISC_R_SUCCESS) {
9151 dnssec_log(zone, ISC_LOG_ERROR,
9152 "zone_sign:update_soa_serial -> %s",
9153 dns_result_totext(result));
9154 goto cleanup;
9155 }
9156
9157 /*
9158 * Generate maximum life time signatures so that the above loop
9159 * termination is sensible.
9160 */
9161 result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
9162 zonediff.diff, zone_keys, nkeys, zone->mctx,
9163 inception, soaexpire, check_ksk, keyset_kskonly);
9164 if (result != ISC_R_SUCCESS) {
9165 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:add_sigs -> %s",
9166 dns_result_totext(result));
9167 goto cleanup;
9168 }
9169
9170 /*
9171 * Write changes to journal file.
9172 */
9173 CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign"));
9174
9175 pauseall:
9176 /*
9177 * Pause all iterators so that dns_db_closeversion() can succeed.
9178 */
9179 for (signing = ISC_LIST_HEAD(zone->signing);
9180 signing != NULL;
9181 signing = ISC_LIST_NEXT(signing, link))
9182 {
9183 dns_dbiterator_pause(signing->dbiterator);
9184 }
9185
9186 for (signing = ISC_LIST_HEAD(cleanup);
9187 signing != NULL;
9188 signing = ISC_LIST_NEXT(signing, link))
9189 {
9190 dns_dbiterator_pause(signing->dbiterator);
9191 }
9192
9193 /*
9194 * Everything has succeeded. Commit the changes.
9195 */
9196 dns_db_closeversion(db, &version, commit);
9197
9198 /*
9199 * Everything succeeded so we can clean these up now.
9200 */
9201 signing = ISC_LIST_HEAD(cleanup);
9202 while (signing != NULL) {
9203 ISC_LIST_UNLINK(cleanup, signing, link);
9204 dns_db_detach(&signing->db);
9205 dns_dbiterator_destroy(&signing->dbiterator);
9206 isc_mem_put(zone->mctx, signing, sizeof *signing);
9207 signing = ISC_LIST_HEAD(cleanup);
9208 }
9209
9210 set_resigntime(zone);
9211
9212 if (commit) {
9213 LOCK_ZONE(zone);
9214 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
9215 zone_needdump(zone, DNS_DUMP_DELAY);
9216 UNLOCK_ZONE(zone);
9217 }
9218
9219 failure:
9220 if (result != ISC_R_SUCCESS) {
9221 dnssec_log(zone, ISC_LOG_ERROR, "zone_sign: failed: %s",
9222 dns_result_totext(result));
9223 }
9224
9225 cleanup:
9226 /*
9227 * Pause all dbiterators.
9228 */
9229 for (signing = ISC_LIST_HEAD(zone->signing);
9230 signing != NULL;
9231 signing = ISC_LIST_NEXT(signing, link))
9232 {
9233 dns_dbiterator_pause(signing->dbiterator);
9234 }
9235
9236 /*
9237 * Rollback the cleanup list.
9238 */
9239 signing = ISC_LIST_HEAD(cleanup);
9240 while (signing != NULL) {
9241 ISC_LIST_UNLINK(cleanup, signing, link);
9242 ISC_LIST_PREPEND(zone->signing, signing, link);
9243 dns_dbiterator_first(signing->dbiterator);
9244 dns_dbiterator_pause(signing->dbiterator);
9245 signing = ISC_LIST_HEAD(cleanup);
9246 }
9247
9248 dns_diff_clear(&_sig_diff);
9249
9250 for (i = 0; i < nkeys; i++) {
9251 dst_key_free(&zone_keys[i]);
9252 }
9253
9254 if (node != NULL) {
9255 dns_db_detachnode(db, &node);
9256 }
9257
9258 if (version != NULL) {
9259 dns_db_closeversion(db, &version, false);
9260 dns_db_detach(&db);
9261 } else if (db != NULL) {
9262 dns_db_detach(&db);
9263 }
9264
9265 if (ISC_LIST_HEAD(zone->signing) != NULL) {
9266 isc_interval_t interval;
9267 if (zone->update_disabled || result != ISC_R_SUCCESS) {
9268 isc_interval_set(&interval, 60, 0); /* 1 minute */
9269 } else {
9270 isc_interval_set(&interval, 0, 10000000); /* 10 ms */
9271 }
9272 isc_time_nowplusinterval(&zone->signingtime, &interval);
9273 } else {
9274 isc_time_settoepoch(&zone->signingtime);
9275 }
9276
9277 INSIST(version == NULL);
9278 }
9279
9280 static isc_result_t
9281 normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
9282 unsigned char *data, int size)
9283 {
9284 dns_rdata_dnskey_t dnskey;
9285 dns_rdata_keydata_t keydata;
9286 isc_buffer_t buf;
9287 isc_result_t result;
9288
9289 dns_rdata_reset(target);
9290 isc_buffer_init(&buf, data, size);
9291
9292 switch (rr->type) {
9293 case dns_rdatatype_dnskey:
9294 result = dns_rdata_tostruct(rr, &dnskey, NULL);
9295 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9296 dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
9297 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
9298 &dnskey, &buf);
9299 break;
9300 case dns_rdatatype_keydata:
9301 result = dns_rdata_tostruct(rr, &keydata, NULL);
9302 if (result == ISC_R_UNEXPECTEDEND)
9303 return (result);
9304 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9305 dns_keydata_todnskey(&keydata, &dnskey, NULL);
9306 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
9307 &dnskey, &buf);
9308 break;
9309 default:
9310 INSIST(0);
9311 ISC_UNREACHABLE();
9312 }
9313 return (ISC_R_SUCCESS);
9314 }
9315
9316 /*
9317 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
9318 * a KEYDATA rdataset from the key zone.
9319 *
9320 * 'rr' contains either a DNSKEY record, or a KEYDATA record
9321 *
9322 * After normalizing keys to the same format (DNSKEY, with revoke bit
9323 * cleared), return true if a key that matches 'rr' is found in
9324 * 'rdset', or false if not.
9325 */
9326
9327 static bool
9328 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
9329 unsigned char data1[4096], data2[4096];
9330 dns_rdata_t rdata, rdata1, rdata2;
9331 isc_result_t result;
9332
9333 dns_rdata_init(&rdata);
9334 dns_rdata_init(&rdata1);
9335 dns_rdata_init(&rdata2);
9336
9337 result = normalize_key(rr, &rdata1, data1, sizeof(data1));
9338 if (result != ISC_R_SUCCESS)
9339 return (false);
9340
9341 for (result = dns_rdataset_first(rdset);
9342 result == ISC_R_SUCCESS;
9343 result = dns_rdataset_next(rdset)) {
9344 dns_rdata_reset(&rdata);
9345 dns_rdataset_current(rdset, &rdata);
9346 result = normalize_key(&rdata, &rdata2, data2, sizeof(data2));
9347 if (result != ISC_R_SUCCESS)
9348 continue;
9349 if (dns_rdata_compare(&rdata1, &rdata2) == 0)
9350 return (true);
9351 }
9352
9353 return (false);
9354 }
9355
9356 /*
9357 * Calculate the refresh interval for a keydata zone, per
9358 * RFC5011: MAX(1 hr,
9359 * MIN(15 days,
9360 * 1/2 * OrigTTL,
9361 * 1/2 * RRSigExpirationInterval))
9362 * or for retries: MAX(1 hr,
9363 * MIN(1 day,
9364 * 1/10 * OrigTTL,
9365 * 1/10 * RRSigExpirationInterval))
9366 */
9367 static inline isc_stdtime_t
9368 refresh_time(dns_keyfetch_t *kfetch, bool retry) {
9369 isc_result_t result;
9370 uint32_t t;
9371 dns_rdataset_t *rdset;
9372 dns_rdata_t sigrr = DNS_RDATA_INIT;
9373 dns_rdata_sig_t sig;
9374 isc_stdtime_t now;
9375
9376 isc_stdtime_get(&now);
9377
9378 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
9379 rdset = &kfetch->dnskeysigset;
9380 else
9381 return (now + dns_zone_mkey_hour);
9382
9383 result = dns_rdataset_first(rdset);
9384 if (result != ISC_R_SUCCESS)
9385 return (now + dns_zone_mkey_hour);
9386
9387 dns_rdataset_current(rdset, &sigrr);
9388 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
9389 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9390
9391 if (!retry) {
9392 t = sig.originalttl / 2;
9393
9394 if (isc_serial_gt(sig.timeexpire, now)) {
9395 uint32_t exp = (sig.timeexpire - now) / 2;
9396 if (t > exp)
9397 t = exp;
9398 }
9399
9400 if (t > (15 * dns_zone_mkey_day))
9401 t = (15 * dns_zone_mkey_day);
9402
9403 if (t < dns_zone_mkey_hour)
9404 t = dns_zone_mkey_hour;
9405 } else {
9406 t = sig.originalttl / 10;
9407
9408 if (isc_serial_gt(sig.timeexpire, now)) {
9409 uint32_t exp = (sig.timeexpire - now) / 10;
9410 if (t > exp)
9411 t = exp;
9412 }
9413
9414 if (t > dns_zone_mkey_day)
9415 t = dns_zone_mkey_day;
9416
9417 if (t < dns_zone_mkey_hour)
9418 t = dns_zone_mkey_hour;
9419 }
9420
9421 return (now + t);
9422 }
9423
9424 /*
9425 * This routine is called when no changes are needed in a KEYDATA
9426 * record except to simply update the refresh timer. Caller should
9427 * hold zone lock.
9428 */
9429 static isc_result_t
9430 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
9431 {
9432 isc_result_t result;
9433 isc_buffer_t keyb;
9434 unsigned char key_buf[4096];
9435 dns_rdata_t rdata = DNS_RDATA_INIT;
9436 dns_rdata_keydata_t keydata;
9437 dns_name_t *name;
9438 dns_zone_t *zone = kfetch->zone;
9439 isc_stdtime_t now;
9440
9441 name = dns_fixedname_name(&kfetch->name);
9442 isc_stdtime_get(&now);
9443
9444 for (result = dns_rdataset_first(&kfetch->keydataset);
9445 result == ISC_R_SUCCESS;
9446 result = dns_rdataset_next(&kfetch->keydataset)) {
9447 dns_rdata_reset(&rdata);
9448 dns_rdataset_current(&kfetch->keydataset, &rdata);
9449
9450 /* Delete old version */
9451 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
9452 name, 0, &rdata));
9453
9454 /* Update refresh timer */
9455 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
9456 if (result == ISC_R_UNEXPECTEDEND)
9457 continue;
9458 if (result != ISC_R_SUCCESS)
9459 goto failure;
9460 keydata.refresh = refresh_time(kfetch, true);
9461 set_refreshkeytimer(zone, &keydata, now, false);
9462
9463 dns_rdata_reset(&rdata);
9464 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
9465 CHECK(dns_rdata_fromstruct(&rdata,
9466 zone->rdclass, dns_rdatatype_keydata,
9467 &keydata, &keyb));
9468
9469 /* Insert updated version */
9470 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
9471 name, 0, &rdata));
9472 }
9473 result = ISC_R_SUCCESS;
9474 failure:
9475 return (result);
9476 }
9477
9478 /*
9479 * Verify that DNSKEY set is signed by the key specified in 'keydata'.
9480 */
9481 static bool
9482 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
9483 isc_result_t result;
9484 dns_name_t *keyname;
9485 isc_mem_t *mctx;
9486 dns_rdata_t sigrr = DNS_RDATA_INIT;
9487 dns_rdata_t rr = DNS_RDATA_INIT;
9488 dns_rdata_rrsig_t sig;
9489 dns_rdata_dnskey_t dnskey;
9490 dst_key_t *dstkey = NULL;
9491 unsigned char key_buf[4096];
9492 isc_buffer_t keyb;
9493 bool answer = false;
9494
9495 REQUIRE(kfetch != NULL && keydata != NULL);
9496 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
9497
9498 keyname = dns_fixedname_name(&kfetch->name);
9499 mctx = kfetch->zone->view->mctx;
9500
9501 /* Generate a key from keydata */
9502 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
9503 dns_keydata_todnskey(keydata, &dnskey, NULL);
9504 dns_rdata_fromstruct(&rr, keydata->common.rdclass,
9505 dns_rdatatype_dnskey, &dnskey, &keyb);
9506 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
9507 if (result != ISC_R_SUCCESS) {
9508 return (false);
9509 }
9510
9511 /* See if that key generated any of the signatures */
9512 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
9513 result == ISC_R_SUCCESS;
9514 result = dns_rdataset_next(&kfetch->dnskeysigset))
9515 {
9516 dns_fixedname_t fixed;
9517 dns_fixedname_init(&fixed);
9518
9519 dns_rdata_reset(&sigrr);
9520 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
9521 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
9522 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9523
9524 if (dst_key_alg(dstkey) == sig.algorithm &&
9525 dst_key_rid(dstkey) == sig.keyid)
9526 {
9527 result = dns_dnssec_verify(keyname,
9528 &kfetch->dnskeyset,
9529 dstkey, false, 0, mctx,
9530 &sigrr,
9531 dns_fixedname_name(&fixed));
9532
9533 dnssec_log(kfetch->zone, ISC_LOG_DEBUG(3),
9534 "Confirm revoked DNSKEY is self-signed: %s",
9535 dns_result_totext(result));
9536
9537 if (result == ISC_R_SUCCESS) {
9538 answer = true;
9539 break;
9540 }
9541 }
9542 }
9543
9544 dst_key_free(&dstkey);
9545 return (answer);
9546 }
9547
9548 /*
9549 * A DNSKEY set has been fetched from the zone apex of a zone whose trust
9550 * anchors are being managed; scan the keyset, and update the key zone and the
9551 * local trust anchors according to RFC5011.
9552 */
9553 static void
9554 keyfetch_done(isc_task_t *task, isc_event_t *event) {
9555 isc_result_t result, eresult;
9556 dns_fetchevent_t *devent;
9557 dns_keyfetch_t *kfetch;
9558 dns_zone_t *zone;
9559 isc_mem_t *mctx = NULL;
9560 dns_keytable_t *secroots = NULL;
9561 dns_dbversion_t *ver = NULL;
9562 dns_diff_t diff;
9563 bool alldone = false;
9564 bool commit = false;
9565 dns_name_t *keyname;
9566 dns_rdata_t sigrr = DNS_RDATA_INIT;
9567 dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
9568 dns_rdata_t keydatarr = DNS_RDATA_INIT;
9569 dns_rdata_rrsig_t sig;
9570 dns_rdata_dnskey_t dnskey;
9571 dns_rdata_keydata_t keydata;
9572 bool initializing;
9573 char namebuf[DNS_NAME_FORMATSIZE];
9574 unsigned char key_buf[4096];
9575 isc_buffer_t keyb;
9576 dst_key_t *dstkey;
9577 isc_stdtime_t now;
9578 int pending = 0;
9579 bool secure = false, initial = false;
9580 bool free_needed;
9581
9582 UNUSED(task);
9583 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
9584 INSIST(event->ev_arg != NULL);
9585
9586 kfetch = event->ev_arg;
9587 zone = kfetch->zone;
9588 isc_mem_attach(zone->mctx, &mctx);
9589 keyname = dns_fixedname_name(&kfetch->name);
9590
9591 devent = (dns_fetchevent_t *) event;
9592 eresult = devent->result;
9593
9594 /* Free resources which are not of interest */
9595 if (devent->node != NULL) {
9596 dns_db_detachnode(devent->db, &devent->node);
9597 }
9598 if (devent->db != NULL) {
9599 dns_db_detach(&devent->db);
9600 }
9601 isc_event_free(&event);
9602 dns_resolver_destroyfetch(&kfetch->fetch);
9603
9604 LOCK_ZONE(zone);
9605 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) {
9606 goto cleanup;
9607 }
9608
9609 isc_stdtime_get(&now);
9610 dns_name_format(keyname, namebuf, sizeof(namebuf));
9611
9612 result = dns_view_getsecroots(zone->view, &secroots);
9613 INSIST(result == ISC_R_SUCCESS);
9614
9615 dns_diff_init(mctx, &diff);
9616
9617 CHECK(dns_db_newversion(kfetch->db, &ver));
9618
9619 zone->refreshkeycount--;
9620 alldone = (zone->refreshkeycount == 0);
9621
9622 if (alldone) {
9623 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
9624 }
9625
9626 dnssec_log(zone, ISC_LOG_DEBUG(3),
9627 "Returned from key fetch in keyfetch_done() for '%s': %s",
9628 namebuf, dns_result_totext(eresult));
9629
9630 /* Fetch failed */
9631 if (eresult != ISC_R_SUCCESS ||
9632 !dns_rdataset_isassociated(&kfetch->dnskeyset))
9633 {
9634 dnssec_log(zone, ISC_LOG_WARNING,
9635 "Unable to fetch DNSKEY set '%s': %s",
9636 namebuf, dns_result_totext(eresult));
9637 CHECK(minimal_update(kfetch, ver, &diff));
9638 goto done;
9639 }
9640
9641 /* No RRSIGs found */
9642 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
9643 dnssec_log(zone, ISC_LOG_WARNING,
9644 "No DNSKEY RRSIGs found for '%s': %s",
9645 namebuf, dns_result_totext(eresult));
9646 CHECK(minimal_update(kfetch, ver, &diff));
9647 goto done;
9648 }
9649
9650 /*
9651 * Clear any cached trust level, as we need to run validation
9652 * over again; trusted keys might have changed.
9653 */
9654 kfetch->dnskeyset.trust = kfetch->dnskeysigset.trust = dns_trust_none;
9655
9656 /*
9657 * Validate the dnskeyset against the current trusted keys.
9658 */
9659 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
9660 result == ISC_R_SUCCESS;
9661 result = dns_rdataset_next(&kfetch->dnskeysigset))
9662 {
9663 dns_keynode_t *keynode = NULL;
9664
9665 dns_rdata_reset(&sigrr);
9666 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
9667 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
9668 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9669
9670 result = dns_keytable_find(secroots, keyname, &keynode);
9671 while (result == ISC_R_SUCCESS) {
9672 dns_keynode_t *nextnode = NULL;
9673 dns_fixedname_t fixed;
9674 dns_fixedname_init(&fixed);
9675
9676 dstkey = dns_keynode_key(keynode);
9677 if (dstkey == NULL) {
9678 /* fail_secure() was called */
9679 break;
9680 }
9681
9682 if (dst_key_alg(dstkey) == sig.algorithm &&
9683 dst_key_id(dstkey) == sig.keyid)
9684 {
9685 result = dns_dnssec_verify(keyname,
9686 &kfetch->dnskeyset,
9687 dstkey, false,
9688 0,
9689 zone->view->mctx,
9690 &sigrr,
9691 dns_fixedname_name(
9692 &fixed));
9693
9694 dnssec_log(zone, ISC_LOG_DEBUG(3),
9695 "Verifying DNSKEY set for zone "
9696 "'%s' using key %d/%d: %s",
9697 namebuf, sig.keyid, sig.algorithm,
9698 dns_result_totext(result));
9699
9700 if (result == ISC_R_SUCCESS) {
9701 kfetch->dnskeyset.trust =
9702 dns_trust_secure;
9703 kfetch->dnskeysigset.trust =
9704 dns_trust_secure;
9705 secure = true;
9706 initial = dns_keynode_initial(keynode);
9707 dns_keynode_trust(keynode);
9708 break;
9709 }
9710 }
9711
9712 result = dns_keytable_nextkeynode(secroots,
9713 keynode, &nextnode);
9714 dns_keytable_detachkeynode(secroots, &keynode);
9715 keynode = nextnode;
9716 }
9717
9718 if (keynode != NULL) {
9719 dns_keytable_detachkeynode(secroots, &keynode);
9720 }
9721
9722 if (secure) {
9723 break;
9724 }
9725 }
9726
9727 /*
9728 * If we were not able to verify the answer using the current
9729 * trusted keys then all we can do is look at any revoked keys.
9730 */
9731 if (!secure) {
9732 dnssec_log(zone, ISC_LOG_INFO,
9733 "DNSKEY set for zone '%s' could not be verified "
9734 "with current keys", namebuf);
9735 }
9736
9737 /*
9738 * First scan keydataset to find keys that are not in dnskeyset
9739 * - Missing keys which are not scheduled for removal,
9740 * log a warning
9741 * - Missing keys which are scheduled for removal and
9742 * the remove hold-down timer has completed should
9743 * be removed from the key zone
9744 * - Missing keys whose acceptance timers have not yet
9745 * completed, log a warning and reset the acceptance
9746 * timer to 30 days in the future
9747 * - All keys not being removed have their refresh timers
9748 * updated
9749 */
9750 initializing = true;
9751 for (result = dns_rdataset_first(&kfetch->keydataset);
9752 result == ISC_R_SUCCESS;
9753 result = dns_rdataset_next(&kfetch->keydataset))
9754 {
9755 dns_keytag_t keytag;
9756
9757 dns_rdata_reset(&keydatarr);
9758 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
9759 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
9760 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9761
9762 dns_keydata_todnskey(&keydata, &dnskey, NULL);
9763 result = compute_tag(keyname, &dnskey, mctx, &keytag);
9764 if (result != ISC_R_SUCCESS) {
9765 /*
9766 * Skip if we cannot compute the key tag.
9767 * This may happen if the algorithm is unsupported
9768 */
9769 dns_zone_log(zone, ISC_LOG_ERROR,
9770 "Cannot compute tag for key in zone %s: %s "
9771 "(skipping)",
9772 namebuf, dns_result_totext(result));
9773 continue;
9774 }
9775 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9776
9777 /*
9778 * If any keydata record has a nonzero add holddown, then
9779 * there was a pre-existing trust anchor for this domain;
9780 * that means we are *not* initializing it and shouldn't
9781 * automatically trust all the keys we find at the zone apex.
9782 */
9783 initializing = initializing && (keydata.addhd == 0);
9784
9785 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
9786 bool deletekey = false;
9787
9788 if (!secure) {
9789 if (keydata.removehd != 0 &&
9790 keydata.removehd <= now)
9791 {
9792 deletekey = true;
9793 }
9794 } else if (keydata.addhd == 0) {
9795 deletekey = true;
9796 } else if (keydata.addhd > now) {
9797 dnssec_log(zone, ISC_LOG_INFO,
9798 "Pending key %d for zone %s "
9799 "unexpectedly missing "
9800 "restarting 30-day acceptance "
9801 "timer", keytag, namebuf);
9802 if (keydata.addhd < now + dns_zone_mkey_month) {
9803 keydata.addhd =
9804 now + dns_zone_mkey_month;
9805 }
9806 keydata.refresh = refresh_time(kfetch, false);
9807 } else if (keydata.removehd == 0) {
9808 dnssec_log(zone, ISC_LOG_INFO,
9809 "Active key %d for zone %s "
9810 "unexpectedly missing",
9811 keytag, namebuf);
9812 keydata.refresh = now + dns_zone_mkey_hour;
9813 } else if (keydata.removehd <= now) {
9814 deletekey = true;
9815 dnssec_log(zone, ISC_LOG_INFO,
9816 "Revoked key %d for zone %s "
9817 "missing: deleting from "
9818 "managed keys database",
9819 keytag, namebuf);
9820 } else {
9821 keydata.refresh = refresh_time(kfetch, false);
9822 }
9823
9824 if (secure || deletekey) {
9825 /* Delete old version */
9826 CHECK(update_one_rr(kfetch->db, ver, &diff,
9827 DNS_DIFFOP_DEL, keyname, 0,
9828 &keydatarr));
9829 }
9830
9831 if (!secure || deletekey) {
9832 continue;
9833 }
9834
9835 dns_rdata_reset(&keydatarr);
9836 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
9837 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
9838 dns_rdatatype_keydata,
9839 &keydata, &keyb);
9840
9841 /* Insert updated version */
9842 CHECK(update_one_rr(kfetch->db, ver, &diff,
9843 DNS_DIFFOP_ADD, keyname, 0,
9844 &keydatarr));
9845
9846 set_refreshkeytimer(zone, &keydata, now, false);
9847 }
9848 }
9849
9850 /*
9851 * Next scan dnskeyset:
9852 * - If new keys are found (i.e., lacking a match in keydataset)
9853 * add them to the key zone and set the acceptance timer
9854 * to 30 days in the future (or to immediately if we've
9855 * determined that we're initializing the zone for the
9856 * first time)
9857 * - Previously-known keys that have been revoked
9858 * must be scheduled for removal from the key zone (or,
9859 * if they hadn't been accepted as trust anchors yet
9860 * anyway, removed at once)
9861 * - Previously-known unrevoked keys whose acceptance timers
9862 * have completed are promoted to trust anchors
9863 * - All keys not being removed have their refresh
9864 * timers updated
9865 */
9866 for (result = dns_rdataset_first(&kfetch->dnskeyset);
9867 result == ISC_R_SUCCESS;
9868 result = dns_rdataset_next(&kfetch->dnskeyset))
9869 {
9870 bool revoked = false;
9871 bool newkey = false;
9872 bool updatekey = false;
9873 bool deletekey = false;
9874 bool trustkey = false;
9875 dns_keytag_t keytag;
9876
9877 dns_rdata_reset(&dnskeyrr);
9878 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
9879 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
9880 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9881
9882 /* Skip ZSK's */
9883 if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) {
9884 continue;
9885 }
9886
9887 result = compute_tag(keyname, &dnskey, mctx, &keytag);
9888 if (result != ISC_R_SUCCESS) {
9889 /*
9890 * Skip if we cannot compute the key tag.
9891 * This may happen if the algorithm is unsupported
9892 */
9893 dns_zone_log(zone, ISC_LOG_ERROR,
9894 "Cannot compute tag for key in zone %s: %s "
9895 "(skipping)",
9896 namebuf, dns_result_totext(result));
9897 continue;
9898 }
9899 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9900
9901 revoked = ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0);
9902
9903 if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
9904 dns_rdata_reset(&keydatarr);
9905 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
9906 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
9907 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9908
9909 if (revoked && revocable(kfetch, &keydata)) {
9910 if (keydata.addhd > now) {
9911 /*
9912 * Key wasn't trusted yet, and now
9913 * it's been revoked? Just remove it
9914 */
9915 deletekey = true;
9916 dnssec_log(zone, ISC_LOG_INFO,
9917 "Pending key %d for "
9918 "zone %s is now revoked: "
9919 "deleting from the "
9920 "managed keys database",
9921 keytag, namebuf);
9922 } else if (keydata.removehd == 0) {
9923 /*
9924 * Remove key from secroots.
9925 */
9926 dns_view_untrust(zone->view, keyname,
9927 &dnskey, mctx);
9928
9929 /* If initializing, delete now */
9930 if (keydata.addhd == 0) {
9931 deletekey = true;
9932 } else {
9933 keydata.removehd = now +
9934 dns_zone_mkey_month;
9935 keydata.flags |=
9936 DNS_KEYFLAG_REVOKE;
9937 }
9938
9939 dnssec_log(zone, ISC_LOG_INFO,
9940 "Trusted key %d for "
9941 "zone %s is now revoked",
9942 keytag, namebuf);
9943 } else if (keydata.removehd < now) {
9944 /* Scheduled for removal */
9945 deletekey = true;
9946
9947 dnssec_log(zone, ISC_LOG_INFO,
9948 "Revoked key %d for "
9949 "zone %s removal timer "
9950 "complete: deleting from "
9951 "the managed keys database",
9952 keytag, namebuf);
9953 }
9954 } else if (revoked && keydata.removehd == 0) {
9955 dnssec_log(zone, ISC_LOG_WARNING,
9956 "Active key %d for zone "
9957 "%s is revoked but "
9958 "did not self-sign; "
9959 "ignoring", keytag, namebuf);
9960 continue;
9961 } else if (secure) {
9962 if (keydata.removehd != 0) {
9963 /*
9964 * Key isn't revoked--but it
9965 * seems it used to be.
9966 * Remove it now and add it
9967 * back as if it were a fresh key,
9968 * with a 30-day acceptance timer.
9969 */
9970 deletekey = true;
9971 newkey = true;
9972 keydata.removehd = 0;
9973 keydata.addhd =
9974 now + dns_zone_mkey_month;
9975
9976 dnssec_log(zone, ISC_LOG_INFO,
9977 "Revoked key %d for "
9978 "zone %s has returned: "
9979 "starting 30-day "
9980 "acceptance timer",
9981 keytag, namebuf);
9982 } else if (keydata.addhd > now) {
9983 pending++;
9984 } else if (keydata.addhd == 0) {
9985 keydata.addhd = now;
9986 }
9987
9988 if (keydata.addhd <= now) {
9989 trustkey = true;
9990 dnssec_log(zone, ISC_LOG_INFO,
9991 "Key %d for zone %s "
9992 "is now trusted (%s)",
9993 keytag, namebuf,
9994 initial
9995 ? "initializing key "
9996 "verified"
9997 : "acceptance timer "
9998 "complete");
9999 }
10000 } else if (keydata.addhd > now) {
10001 /*
10002 * Not secure, and key is pending:
10003 * reset the acceptance timer
10004 */
10005 pending++;
10006 keydata.addhd = now + dns_zone_mkey_month;
10007 dnssec_log(zone, ISC_LOG_INFO,
10008 "Pending key %d "
10009 "for zone %s was "
10010 "not validated: restarting "
10011 "30-day acceptance timer",
10012 keytag, namebuf);
10013 }
10014
10015 if (!deletekey && !newkey) {
10016 updatekey = true;
10017 }
10018 } else if (secure) {
10019 /*
10020 * Key wasn't in the key zone but it's
10021 * revoked now anyway, so just skip it
10022 */
10023 if (revoked) {
10024 continue;
10025 }
10026
10027 /* Key wasn't in the key zone: add it */
10028 newkey = true;
10029
10030 if (initializing) {
10031 dnssec_log(zone, ISC_LOG_WARNING,
10032 "Initializing automatic trust "
10033 "anchor management for zone '%s'; "
10034 "DNSKEY ID %d is now trusted, "
10035 "waiving the normal 30-day "
10036 "waiting period.",
10037 namebuf, keytag);
10038 trustkey = true;
10039 } else {
10040 dnssec_log(zone, ISC_LOG_INFO,
10041 "New key %d observed "
10042 "for zone '%s': "
10043 "starting 30-day "
10044 "acceptance timer",
10045 keytag, namebuf);
10046 }
10047 } else {
10048 /*
10049 * No previously known key, and the key is not
10050 * secure, so skip it.
10051 */
10052 continue;
10053 }
10054
10055 /* Delete old version */
10056 if (deletekey || !newkey) {
10057 CHECK(update_one_rr(kfetch->db, ver, &diff,
10058 DNS_DIFFOP_DEL, keyname, 0,
10059 &keydatarr));
10060 }
10061
10062 if (updatekey) {
10063 /* Set refresh timer */
10064 keydata.refresh = refresh_time(kfetch, false);
10065 dns_rdata_reset(&keydatarr);
10066 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
10067 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
10068 dns_rdatatype_keydata,
10069 &keydata, &keyb);
10070
10071 /* Insert updated version */
10072 CHECK(update_one_rr(kfetch->db, ver, &diff,
10073 DNS_DIFFOP_ADD, keyname, 0,
10074 &keydatarr));
10075 } else if (newkey) {
10076 /* Convert DNSKEY to KEYDATA */
10077 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
10078 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10079 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
10080 NULL);
10081 keydata.addhd = initializing
10082 ? now : now + dns_zone_mkey_month;
10083 keydata.refresh = refresh_time(kfetch, false);
10084 dns_rdata_reset(&keydatarr);
10085 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
10086 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
10087 dns_rdatatype_keydata,
10088 &keydata, &keyb);
10089
10090 /* Insert into key zone */
10091 CHECK(update_one_rr(kfetch->db, ver, &diff,
10092 DNS_DIFFOP_ADD, keyname, 0,
10093 &keydatarr));
10094 }
10095
10096 if (trustkey) {
10097 /* Trust this key. */
10098 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
10099 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10100 trust_key(zone, keyname, &dnskey, false, mctx);
10101 }
10102
10103 if (secure && !deletekey) {
10104 INSIST(newkey || updatekey);
10105 set_refreshkeytimer(zone, &keydata, now, false);
10106 }
10107 }
10108
10109 /*
10110 * RFC5011 says, "A trust point that has all of its trust anchors
10111 * revoked is considered deleted and is treated as if the trust
10112 * point was never configured." But if someone revoked their
10113 * active key before the standby was trusted, that would mean the
10114 * zone would suddenly be nonsecured. We avoid this by checking to
10115 * see if there's pending keydata. If so, we put a null key in
10116 * the security roots; then all queries to the zone will fail.
10117 */
10118 if (pending != 0) {
10119 fail_secure(zone, keyname);
10120 }
10121
10122 done:
10123 if (!ISC_LIST_EMPTY(diff.tuples)) {
10124 /* Write changes to journal file. */
10125 CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx,
10126 zone->updatemethod));
10127 CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done"));
10128 commit = true;
10129
10130 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
10131 zone_needdump(zone, 30);
10132 } else if (result == ISC_R_NOMORE) {
10133 /*
10134 * If "updatekey" was true for all keys found in the DNSKEY
10135 * response and the previous update of those keys happened
10136 * during the same second (only possible if a key refresh was
10137 * externally triggered), it may happen that all relevant
10138 * update_one_rr() calls will return ISC_R_SUCCESS, but
10139 * diff.tuples will remain empty. Reset result to
10140 * ISC_R_SUCCESS to prevent a bogus warning from being logged.
10141 */
10142 result = ISC_R_SUCCESS;
10143 }
10144
10145 failure:
10146 if (result != ISC_R_SUCCESS) {
10147 dnssec_log(zone, ISC_LOG_ERROR,
10148 "error during managed-keys processing (%s): "
10149 "DNSSEC validation may be at risk",
10150 isc_result_totext(result));
10151 }
10152 dns_diff_clear(&diff);
10153 if (ver != NULL) {
10154 dns_db_closeversion(kfetch->db, &ver, commit);
10155 }
10156
10157 cleanup:
10158 dns_db_detach(&kfetch->db);
10159
10160 INSIST(zone->irefs > 0);
10161 zone->irefs--;
10162 kfetch->zone = NULL;
10163
10164 if (dns_rdataset_isassociated(&kfetch->keydataset)) {
10165 dns_rdataset_disassociate(&kfetch->keydataset);
10166 }
10167 if (dns_rdataset_isassociated(&kfetch->dnskeyset)) {
10168 dns_rdataset_disassociate(&kfetch->dnskeyset);
10169 }
10170 if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
10171 dns_rdataset_disassociate(&kfetch->dnskeysigset);
10172 }
10173
10174 dns_name_free(keyname, mctx);
10175 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
10176 isc_mem_detach(&mctx);
10177
10178 if (secroots != NULL) {
10179 dns_keytable_detach(&secroots);
10180 }
10181
10182 free_needed = exit_check(zone);
10183 UNLOCK_ZONE(zone);
10184 if (free_needed) {
10185 zone_free(zone);
10186 }
10187
10188 INSIST(ver == NULL);
10189 }
10190
10191 /*
10192 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
10193 * records from the zone apex.
10194 */
10195 static void
10196 zone_refreshkeys(dns_zone_t *zone) {
10197 const char me[] = "zone_refreshkeys";
10198 isc_result_t result;
10199 dns_rriterator_t rrit;
10200 dns_db_t *db = NULL;
10201 dns_dbversion_t *ver = NULL;
10202 dns_diff_t diff;
10203 dns_rdata_t rdata = DNS_RDATA_INIT;
10204 dns_rdata_keydata_t kd;
10205 isc_stdtime_t now;
10206 bool commit = false;
10207 bool fetching = false, fetch_err = false;
10208 bool timerset = false;
10209
10210 ENTER;
10211 REQUIRE(zone->db != NULL);
10212
10213 isc_stdtime_get(&now);
10214
10215 LOCK_ZONE(zone);
10216 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10217 isc_time_settoepoch(&zone->refreshkeytime);
10218 UNLOCK_ZONE(zone);
10219 return;
10220 }
10221
10222 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10223 dns_db_attach(zone->db, &db);
10224 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10225
10226 dns_diff_init(zone->mctx, &diff);
10227
10228 CHECK(dns_db_newversion(db, &ver));
10229
10230 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
10231
10232 dns_rriterator_init(&rrit, db, ver, 0);
10233 for (result = dns_rriterator_first(&rrit);
10234 result == ISC_R_SUCCESS;
10235 result = dns_rriterator_nextrrset(&rrit))
10236 {
10237 isc_stdtime_t timer = 0xffffffff;
10238 dns_name_t *name = NULL, *kname = NULL;
10239 dns_rdataset_t *kdset = NULL;
10240 dns_keyfetch_t *kfetch;
10241 uint32_t ttl;
10242
10243 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
10244 if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
10245 !dns_rdataset_isassociated(kdset))
10246 {
10247 continue;
10248 }
10249
10250 /*
10251 * Scan the stored keys looking for ones that need
10252 * removal or refreshing
10253 */
10254 for (result = dns_rdataset_first(kdset);
10255 result == ISC_R_SUCCESS;
10256 result = dns_rdataset_next(kdset))
10257 {
10258 dns_rdata_reset(&rdata);
10259 dns_rdataset_current(kdset, &rdata);
10260 result = dns_rdata_tostruct(&rdata, &kd, NULL);
10261 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10262
10263 /* Removal timer expired? */
10264 if (kd.removehd != 0 && kd.removehd < now) {
10265 CHECK(update_one_rr(db, ver, &diff,
10266 DNS_DIFFOP_DEL, name, ttl,
10267 &rdata));
10268 continue;
10269 }
10270
10271 /* Acceptance timer expired? */
10272 if (kd.addhd <= now) {
10273 timer = kd.addhd;
10274 }
10275
10276 /* Or do we just need to refresh the keyset? */
10277 if (timer > kd.refresh) {
10278 timer = kd.refresh;
10279 }
10280
10281 set_refreshkeytimer(zone, &kd, now, false);
10282 timerset = true;
10283 }
10284
10285 if (timer > now) {
10286 continue;
10287 }
10288
10289 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
10290 if (kfetch == NULL) {
10291 fetch_err = true;
10292 goto failure;
10293 }
10294
10295 zone->refreshkeycount++;
10296 kfetch->zone = zone;
10297 zone->irefs++;
10298 INSIST(zone->irefs != 0);
10299 kname = dns_fixedname_initname(&kfetch->name);
10300 dns_name_dup(name, zone->mctx, kname);
10301 dns_rdataset_init(&kfetch->dnskeyset);
10302 dns_rdataset_init(&kfetch->dnskeysigset);
10303 dns_rdataset_init(&kfetch->keydataset);
10304 dns_rdataset_clone(kdset, &kfetch->keydataset);
10305 kfetch->db = NULL;
10306 dns_db_attach(db, &kfetch->db);
10307 kfetch->fetch = NULL;
10308
10309 if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
10310 char namebuf[DNS_NAME_FORMATSIZE];
10311 dns_name_format(kname, namebuf,
10312 sizeof(namebuf));
10313 dnssec_log(zone, ISC_LOG_DEBUG(3),
10314 "Creating key fetch in "
10315 "zone_refreshkeys() for '%s'",
10316 namebuf);
10317 }
10318
10319 /*
10320 * Use of DNS_FETCHOPT_NOCACHED is essential here. If it is
10321 * not set and the cache still holds a non-expired, validated
10322 * version of the RRset being queried for by the time the
10323 * response is received, the cached RRset will be passed to
10324 * keyfetch_done() instead of the one received in the response
10325 * as the latter will have a lower trust level due to not being
10326 * validated until keyfetch_done() is called.
10327 */
10328
10329 #ifdef ENABLE_AFL
10330 if (dns_fuzzing_resolver == false) {
10331 #endif
10332 result = dns_resolver_createfetch(zone->view->resolver,
10333 kname, dns_rdatatype_dnskey,
10334 NULL, NULL, NULL, NULL, 0,
10335 DNS_FETCHOPT_NOVALIDATE |
10336 DNS_FETCHOPT_UNSHARED |
10337 DNS_FETCHOPT_NOCACHED,
10338 0, NULL, zone->task,
10339 keyfetch_done, kfetch,
10340 &kfetch->dnskeyset,
10341 &kfetch->dnskeysigset,
10342 &kfetch->fetch);
10343 #ifdef ENABLE_AFL
10344 } else {
10345 result = ISC_R_FAILURE;
10346 }
10347 #endif
10348 if (result == ISC_R_SUCCESS) {
10349 fetching = true;
10350 } else {
10351 zone->refreshkeycount--;
10352 zone->irefs--;
10353 dns_db_detach(&kfetch->db);
10354 dns_rdataset_disassociate(&kfetch->keydataset);
10355 dns_name_free(kname, zone->mctx);
10356 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
10357 dnssec_log(zone, ISC_LOG_WARNING,
10358 "Failed to create fetch for DNSKEY update");
10359 fetch_err = true;
10360 }
10361 }
10362 if (!ISC_LIST_EMPTY(diff.tuples)) {
10363 CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
10364 zone->updatemethod));
10365 CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys"));
10366 commit = true;
10367 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
10368 zone_needdump(zone, 30);
10369 }
10370
10371 failure:
10372 if (fetch_err) {
10373 /*
10374 * Error during a key fetch; retry in an hour.
10375 */
10376 isc_time_t timenow, timethen;
10377 char timebuf[80];
10378
10379 TIME_NOW(&timenow);
10380 DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen);
10381 zone->refreshkeytime = timethen;
10382 zone_settimer(zone, &timenow);
10383
10384 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
10385 dnssec_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
10386 timebuf);
10387 } else if (!timerset) {
10388 isc_time_settoepoch(&zone->refreshkeytime);
10389 }
10390
10391 if (!fetching) {
10392 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
10393 }
10394
10395 dns_diff_clear(&diff);
10396 if (ver != NULL) {
10397 dns_rriterator_destroy(&rrit);
10398 dns_db_closeversion(db, &ver, commit);
10399 }
10400 dns_db_detach(&db);
10401
10402 UNLOCK_ZONE(zone);
10403
10404 INSIST(ver == NULL);
10405 }
10406
10407 static void
10408 zone_maintenance(dns_zone_t *zone) {
10409 const char me[] = "zone_maintenance";
10410 isc_time_t now;
10411 isc_result_t result;
10412 bool dumping, load_pending;
10413
10414 REQUIRE(DNS_ZONE_VALID(zone));
10415 ENTER;
10416
10417 /*
10418 * Are we pending load/reload?
10419 */
10420 LOCK_ZONE(zone);
10421 load_pending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING);
10422 UNLOCK_ZONE(zone);
10423
10424 if (load_pending) {
10425 return;
10426 }
10427
10428 /*
10429 * Configuring the view of this zone may have
10430 * failed, for example because the config file
10431 * had a syntax error. In that case, the view
10432 * adb or resolver will be NULL, and we had better not try
10433 * to do further maintenance on it.
10434 */
10435 if (zone->view == NULL || zone->view->adb == NULL)
10436 return;
10437
10438 TIME_NOW(&now);
10439
10440 /*
10441 * Expire check.
10442 */
10443 switch (zone->type) {
10444 case dns_zone_redirect:
10445 if (zone->masters == NULL)
10446 break;
10447 /* FALLTHROUGH */
10448 case dns_zone_slave:
10449 case dns_zone_mirror:
10450 case dns_zone_stub:
10451 LOCK_ZONE(zone);
10452 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
10453 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
10454 zone_expire(zone);
10455 zone->refreshtime = now;
10456 }
10457 UNLOCK_ZONE(zone);
10458 break;
10459 default:
10460 break;
10461 }
10462
10463 /*
10464 * Up to date check.
10465 */
10466 switch (zone->type) {
10467 case dns_zone_redirect:
10468 if (zone->masters == NULL)
10469 break;
10470 /* FALLTHROUGH */
10471 case dns_zone_slave:
10472 case dns_zone_mirror:
10473 case dns_zone_stub:
10474 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
10475 isc_time_compare(&now, &zone->refreshtime) >= 0)
10476 dns_zone_refresh(zone);
10477 break;
10478 default:
10479 break;
10480 }
10481
10482 /*
10483 * Slaves send notifies before backing up to disk, masters after.
10484 */
10485 if ((zone->type == dns_zone_slave || zone->type == dns_zone_mirror) &&
10486 (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
10487 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
10488 isc_time_compare(&now, &zone->notifytime) >= 0)
10489 zone_notify(zone, &now);
10490
10491 /*
10492 * Do we need to consolidate the backing store?
10493 */
10494 switch (zone->type) {
10495 case dns_zone_master:
10496 case dns_zone_slave:
10497 case dns_zone_mirror:
10498 case dns_zone_key:
10499 case dns_zone_redirect:
10500 case dns_zone_stub:
10501 LOCK_ZONE(zone);
10502 if (zone->masterfile != NULL &&
10503 isc_time_compare(&now, &zone->dumptime) >= 0 &&
10504 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
10505 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
10506 dumping = was_dumping(zone);
10507 } else
10508 dumping = true;
10509 UNLOCK_ZONE(zone);
10510 if (!dumping) {
10511 result = zone_dump(zone, true); /* task locked */
10512 if (result != ISC_R_SUCCESS)
10513 dns_zone_log(zone, ISC_LOG_WARNING,
10514 "dump failed: %s",
10515 dns_result_totext(result));
10516 }
10517 break;
10518 default:
10519 break;
10520 }
10521
10522 /*
10523 * Master/redirect zones send notifies now, if needed
10524 */
10525 switch (zone->type) {
10526 case dns_zone_master:
10527 case dns_zone_redirect:
10528 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
10529 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))&&
10530 isc_time_compare(&now, &zone->notifytime) >= 0)
10531 zone_notify(zone, &now);
10532 default:
10533 break;
10534 }
10535
10536 /*
10537 * Do we need to refresh keys?
10538 */
10539 switch (zone->type) {
10540 case dns_zone_key:
10541 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
10542 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
10543 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
10544 zone_refreshkeys(zone);
10545 }
10546 }
10547 break;
10548 case dns_zone_master:
10549 if (!isc_time_isepoch(&zone->refreshkeytime) &&
10550 isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
10551 zone->rss_event == NULL)
10552 zone_rekey(zone);
10553 default:
10554 break;
10555 }
10556
10557 switch (zone->type) {
10558 case dns_zone_master:
10559 case dns_zone_redirect:
10560 case dns_zone_slave:
10561 /*
10562 * Do we need to sign/resign some RRsets?
10563 */
10564 if (zone->rss_event != NULL)
10565 break;
10566 if (!isc_time_isepoch(&zone->signingtime) &&
10567 isc_time_compare(&now, &zone->signingtime) >= 0) {
10568 zone_sign(zone);
10569 }
10570 else if (!isc_time_isepoch(&zone->resigntime) &&
10571 isc_time_compare(&now, &zone->resigntime) >= 0) {
10572 zone_resigninc(zone);
10573 }
10574 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
10575 isc_time_compare(&now, &zone->nsec3chaintime) >= 0) {
10576 zone_nsec3chain(zone);
10577 }
10578 /*
10579 * Do we need to issue a key expiry warning?
10580 */
10581 if (!isc_time_isepoch(&zone->keywarntime) &&
10582 isc_time_compare(&now, &zone->keywarntime) >= 0)
10583 set_key_expiry_warning(zone, zone->key_expiry,
10584 isc_time_seconds(&now));
10585 break;
10586
10587 default:
10588 break;
10589 }
10590 zone_settimer(zone, &now);
10591 }
10592
10593 void
10594 dns_zone_markdirty(dns_zone_t *zone) {
10595 uint32_t serial;
10596 isc_result_t result = ISC_R_SUCCESS;
10597 dns_zone_t *secure = NULL;
10598
10599 /*
10600 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
10601 * could result in a deadlock due to a LOR so we will spin if we
10602 * can't obtain the both locks.
10603 */
10604 again:
10605 LOCK_ZONE(zone);
10606 if (zone->type == dns_zone_master) {
10607 if (inline_raw(zone)) {
10608 unsigned int soacount;
10609 secure = zone->secure;
10610 INSIST(secure != zone);
10611 TRYLOCK_ZONE(result, secure);
10612 if (result != ISC_R_SUCCESS) {
10613 UNLOCK_ZONE(zone);
10614 secure = NULL;
10615 isc_thread_yield();
10616 goto again;
10617 }
10618
10619 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10620 if (zone->db != NULL) {
10621 result = zone_get_from_db(zone, zone->db, NULL,
10622 &soacount, &serial,
10623 NULL, NULL, NULL,
10624 NULL, NULL);
10625 } else
10626 result = DNS_R_NOTLOADED;
10627 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10628 if (result == ISC_R_SUCCESS && soacount > 0U)
10629 zone_send_secureserial(zone, serial);
10630 }
10631
10632 /* XXXMPA make separate call back */
10633 if (result == ISC_R_SUCCESS)
10634 set_resigntime(zone);
10635 }
10636 if (secure != NULL)
10637 UNLOCK_ZONE(secure);
10638 zone_needdump(zone, DNS_DUMP_DELAY);
10639 UNLOCK_ZONE(zone);
10640 }
10641
10642 void
10643 dns_zone_expire(dns_zone_t *zone) {
10644 REQUIRE(DNS_ZONE_VALID(zone));
10645
10646 LOCK_ZONE(zone);
10647 zone_expire(zone);
10648 UNLOCK_ZONE(zone);
10649 }
10650
10651 static void
10652 zone_expire(dns_zone_t *zone) {
10653 dns_db_t *db = NULL;
10654
10655 /*
10656 * 'zone' locked by caller.
10657 */
10658
10659 REQUIRE(LOCKED_ZONE(zone));
10660
10661 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
10662
10663 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
10664 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
10665 zone->retry = DNS_ZONE_DEFAULTRETRY;
10666 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
10667
10668 /*
10669 * An RPZ zone has expired; before unloading it, we must
10670 * first remove it from the RPZ summary database. The
10671 * easiest way to do this is "update" it with an empty
10672 * database so that the update callback synchonizes
10673 * the diff automatically.
10674 */
10675 if (zone->rpzs != NULL && zone->rpz_num != DNS_RPZ_INVALID_NUM) {
10676 isc_result_t result;
10677 dns_rpz_zone_t *rpz = zone->rpzs->zones[zone->rpz_num];
10678
10679 CHECK(dns_db_create(zone->mctx, "rbt", &zone->origin,
10680 dns_dbtype_zone, zone->rdclass,
10681 0, NULL, &db));
10682 CHECK(dns_rpz_dbupdate_callback(db, rpz));
10683 dns_zone_log(zone, ISC_LOG_WARNING,
10684 "response-policy zone expired; "
10685 "policies unloaded");
10686 }
10687
10688 failure:
10689 if (db != NULL) {
10690 dns_db_detach(&db);
10691 }
10692
10693 zone_unload(zone);
10694 }
10695
10696 void
10697 dns_zone_refresh(dns_zone_t *zone) {
10698 isc_interval_t i;
10699 uint32_t oldflags;
10700 unsigned int j;
10701 isc_result_t result;
10702
10703 REQUIRE(DNS_ZONE_VALID(zone));
10704
10705 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
10706 return;
10707
10708 /*
10709 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
10710 * in progress at a time.
10711 */
10712
10713 LOCK_ZONE(zone);
10714 oldflags = zone->flags;
10715 if (zone->masterscnt == 0) {
10716 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
10717 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
10718 dns_zone_log(zone, ISC_LOG_ERROR,
10719 "cannot refresh: no masters");
10720 goto unlock;
10721 }
10722 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
10723 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
10724 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
10725 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
10726 goto unlock;
10727
10728 /*
10729 * Set the next refresh time as if refresh check has failed.
10730 * Setting this to the retry time will do that. XXXMLG
10731 * If we are successful it will be reset using zone->refresh.
10732 */
10733 isc_interval_set(&i, zone->retry - isc_random_uniform(zone->retry / 4),
10734 0);
10735 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
10736 if (result != ISC_R_SUCCESS)
10737 dns_zone_log(zone, ISC_LOG_WARNING,
10738 "isc_time_nowplusinterval() failed: %s",
10739 dns_result_totext(result));
10740
10741 /*
10742 * When lacking user-specified timer values from the SOA,
10743 * do exponential backoff of the retry time up to a
10744 * maximum of six hours.
10745 */
10746 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
10747 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
10748
10749 zone->curmaster = 0;
10750 for (j = 0; j < zone->masterscnt; j++)
10751 zone->mastersok[j] = false;
10752 /* initiate soa query */
10753 queue_soa_query(zone);
10754 unlock:
10755 UNLOCK_ZONE(zone);
10756 }
10757
10758 static void
10759 zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial) {
10760 isc_result_t result;
10761 int32_t journalsize;
10762 dns_dbversion_t *ver = NULL;
10763 uint64_t dbsize;
10764
10765 INSIST(LOCKED_ZONE(zone));
10766 if (inline_raw(zone))
10767 INSIST(LOCKED_ZONE(zone->secure));
10768
10769 journalsize = zone->journalsize;
10770 if (journalsize == -1) {
10771 journalsize = DNS_JOURNAL_SIZE_MAX;
10772 dns_db_currentversion(db, &ver);
10773 result = dns_db_getsize(db, ver, NULL, &dbsize);
10774 dns_db_closeversion(db, &ver, false);
10775 if (result != ISC_R_SUCCESS) {
10776 dns_zone_log(zone, ISC_LOG_ERROR,
10777 "zone_journal_compact: "
10778 "could not get zone size: %s",
10779 isc_result_totext(result));
10780 } else if (dbsize < DNS_JOURNAL_SIZE_MAX / 2) {
10781 journalsize = (int32_t)dbsize * 2;
10782 }
10783 }
10784 zone_debuglog(zone, "zone_journal_compact", 1,
10785 "target journal size %d", journalsize);
10786 result = dns_journal_compact(zone->mctx, zone->journal,
10787 serial, journalsize);
10788 switch (result) {
10789 case ISC_R_SUCCESS:
10790 case ISC_R_NOSPACE:
10791 case ISC_R_NOTFOUND:
10792 dns_zone_log(zone, ISC_LOG_DEBUG(3),
10793 "dns_journal_compact: %s",
10794 dns_result_totext(result));
10795 break;
10796 default:
10797 dns_zone_log(zone, ISC_LOG_ERROR,
10798 "dns_journal_compact failed: %s",
10799 dns_result_totext(result));
10800 break;
10801 }
10802 }
10803
10804 isc_result_t
10805 dns_zone_flush(dns_zone_t *zone) {
10806 isc_result_t result = ISC_R_SUCCESS;
10807 bool dumping;
10808
10809 REQUIRE(DNS_ZONE_VALID(zone));
10810
10811 LOCK_ZONE(zone);
10812 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
10813 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10814 zone->masterfile != NULL) {
10815 result = ISC_R_ALREADYRUNNING;
10816 dumping = was_dumping(zone);
10817 } else
10818 dumping = true;
10819 UNLOCK_ZONE(zone);
10820 if (!dumping)
10821 result = zone_dump(zone, true); /* Unknown task. */
10822 return (result);
10823 }
10824
10825 isc_result_t
10826 dns_zone_dump(dns_zone_t *zone) {
10827 isc_result_t result = ISC_R_ALREADYRUNNING;
10828 bool dumping;
10829
10830 REQUIRE(DNS_ZONE_VALID(zone));
10831
10832 LOCK_ZONE(zone);
10833 dumping = was_dumping(zone);
10834 UNLOCK_ZONE(zone);
10835 if (!dumping)
10836 result = zone_dump(zone, false); /* Unknown task. */
10837 return (result);
10838 }
10839
10840 static void
10841 zone_needdump(dns_zone_t *zone, unsigned int delay) {
10842 const char me[] = "zone_needdump";
10843 isc_time_t dumptime;
10844 isc_time_t now;
10845
10846 /*
10847 * 'zone' locked by caller
10848 */
10849
10850 REQUIRE(DNS_ZONE_VALID(zone));
10851 REQUIRE(LOCKED_ZONE(zone));
10852 ENTER;
10853
10854 /*
10855 * Do we have a place to dump to and are we loaded?
10856 */
10857 if (zone->masterfile == NULL ||
10858 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
10859 return;
10860
10861 TIME_NOW(&now);
10862 /* add some noise */
10863 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
10864
10865 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
10866 if (isc_time_isepoch(&zone->dumptime) ||
10867 isc_time_compare(&zone->dumptime, &dumptime) > 0)
10868 zone->dumptime = dumptime;
10869 if (zone->task != NULL)
10870 zone_settimer(zone, &now);
10871 }
10872
10873 static void
10874 dump_done(void *arg, isc_result_t result) {
10875 const char me[] = "dump_done";
10876 dns_zone_t *zone = arg;
10877 dns_zone_t *secure = NULL;
10878 dns_db_t *db;
10879 dns_dbversion_t *version;
10880 bool again = false;
10881 bool compact = false;
10882 uint32_t serial;
10883 isc_result_t tresult;
10884
10885 REQUIRE(DNS_ZONE_VALID(zone));
10886
10887 ENTER;
10888
10889 if (result == ISC_R_SUCCESS && zone->journal != NULL) {
10890 /*
10891 * We don't own these, zone->dctx must stay valid.
10892 */
10893 db = dns_dumpctx_db(zone->dctx);
10894 version = dns_dumpctx_version(zone->dctx);
10895 tresult = dns_db_getsoaserial(db, version, &serial);
10896
10897 /*
10898 * Handle lock order inversion.
10899 */
10900 again:
10901 LOCK_ZONE(zone);
10902 if (inline_raw(zone)) {
10903 secure = zone->secure;
10904 INSIST(secure != zone);
10905 TRYLOCK_ZONE(result, secure);
10906 if (result != ISC_R_SUCCESS) {
10907 UNLOCK_ZONE(zone);
10908 secure = NULL;
10909 isc_thread_yield();
10910 goto again;
10911 }
10912 }
10913
10914 /*
10915 * If there is a secure version of this zone
10916 * use its serial if it is less than ours.
10917 */
10918 if (tresult == ISC_R_SUCCESS && secure != NULL) {
10919 uint32_t sserial;
10920 isc_result_t mresult;
10921
10922 ZONEDB_LOCK(&secure->dblock, isc_rwlocktype_read);
10923 if (secure->db != NULL) {
10924 mresult = dns_db_getsoaserial(zone->secure->db,
10925 NULL, &sserial);
10926 if (mresult == ISC_R_SUCCESS &&
10927 isc_serial_lt(sserial, serial))
10928 serial = sserial;
10929 }
10930 ZONEDB_UNLOCK(&secure->dblock, isc_rwlocktype_read);
10931 }
10932 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
10933 dns_db_t *zdb = NULL;
10934 if (dns_zone_getdb(zone, &zdb) == ISC_R_SUCCESS) {
10935 zone_journal_compact(zone, zdb, serial);
10936 dns_db_detach(&zdb);
10937 }
10938 } else if (tresult == ISC_R_SUCCESS) {
10939 compact = true;
10940 zone->compact_serial = serial;
10941 }
10942 if (secure != NULL)
10943 UNLOCK_ZONE(secure);
10944 UNLOCK_ZONE(zone);
10945 }
10946
10947 LOCK_ZONE(zone);
10948 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
10949 if (compact)
10950 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
10951 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
10952 /*
10953 * Try again in a short while.
10954 */
10955 zone_needdump(zone, DNS_DUMP_DELAY);
10956 } else if (result == ISC_R_SUCCESS &&
10957 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
10958 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10959 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
10960 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
10961 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
10962 isc_time_settoepoch(&zone->dumptime);
10963 again = true;
10964 } else if (result == ISC_R_SUCCESS)
10965 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
10966
10967 if (zone->dctx != NULL)
10968 dns_dumpctx_detach(&zone->dctx);
10969 zonemgr_putio(&zone->writeio);
10970 UNLOCK_ZONE(zone);
10971 if (again)
10972 (void)zone_dump(zone, false);
10973 dns_zone_idetach(&zone);
10974 }
10975
10976 static isc_result_t
10977 zone_dump(dns_zone_t *zone, bool compact) {
10978 const char me[] = "zone_dump";
10979 isc_result_t result;
10980 dns_dbversion_t *version = NULL;
10981 bool again;
10982 dns_db_t *db = NULL;
10983 char *masterfile = NULL;
10984 dns_masterformat_t masterformat = dns_masterformat_none;
10985
10986 /*
10987 * 'compact' MUST only be set if we are task locked.
10988 */
10989
10990 REQUIRE(DNS_ZONE_VALID(zone));
10991 ENTER;
10992
10993 redo:
10994 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10995 if (zone->db != NULL)
10996 dns_db_attach(zone->db, &db);
10997 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10998 LOCK_ZONE(zone);
10999 if (zone->masterfile != NULL) {
11000 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
11001 masterformat = zone->masterformat;
11002 }
11003 UNLOCK_ZONE(zone);
11004 if (db == NULL) {
11005 result = DNS_R_NOTLOADED;
11006 goto fail;
11007 }
11008 if (masterfile == NULL) {
11009 result = DNS_R_NOMASTERFILE;
11010 goto fail;
11011 }
11012
11013 if (compact && zone->type != dns_zone_stub) {
11014 dns_zone_t *dummy = NULL;
11015 LOCK_ZONE(zone);
11016 zone_iattach(zone, &dummy);
11017 result = zonemgr_getio(zone->zmgr, false, zone->task,
11018 zone_gotwritehandle, zone,
11019 &zone->writeio);
11020 if (result != ISC_R_SUCCESS)
11021 zone_idetach(&dummy);
11022 else
11023 result = DNS_R_CONTINUE;
11024 UNLOCK_ZONE(zone);
11025 } else {
11026 const dns_master_style_t *output_style;
11027
11028 dns_masterrawheader_t rawdata;
11029 dns_db_currentversion(db, &version);
11030 dns_master_initrawheader(&rawdata);
11031 if (inline_secure(zone))
11032 get_raw_serial(zone->raw, &rawdata);
11033 if (zone->type == dns_zone_key)
11034 output_style = &dns_master_style_keyzone;
11035 else
11036 output_style = &dns_master_style_default;
11037 result = dns_master_dump(zone->mctx, db, version,
11038 output_style, masterfile,
11039 masterformat, &rawdata);
11040 dns_db_closeversion(db, &version, false);
11041 }
11042 fail:
11043 if (db != NULL)
11044 dns_db_detach(&db);
11045 if (masterfile != NULL)
11046 isc_mem_free(zone->mctx, masterfile);
11047 masterfile = NULL;
11048
11049 if (result == DNS_R_CONTINUE)
11050 return (ISC_R_SUCCESS); /* XXXMPA */
11051
11052 again = false;
11053 LOCK_ZONE(zone);
11054 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
11055 if (result != ISC_R_SUCCESS) {
11056 /*
11057 * Try again in a short while.
11058 */
11059 zone_needdump(zone, DNS_DUMP_DELAY);
11060 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
11061 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
11062 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
11063 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
11064 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
11065 isc_time_settoepoch(&zone->dumptime);
11066 again = true;
11067 } else
11068 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
11069 UNLOCK_ZONE(zone);
11070 if (again)
11071 goto redo;
11072
11073 return (result);
11074 }
11075
11076 static isc_result_t
11077 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
11078 dns_masterformat_t format, const uint32_t rawversion)
11079 {
11080 isc_result_t result;
11081 dns_dbversion_t *version = NULL;
11082 dns_db_t *db = NULL;
11083 dns_masterrawheader_t rawdata;
11084
11085 REQUIRE(DNS_ZONE_VALID(zone));
11086
11087 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11088 if (zone->db != NULL)
11089 dns_db_attach(zone->db, &db);
11090 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11091 if (db == NULL)
11092 return (DNS_R_NOTLOADED);
11093
11094 dns_db_currentversion(db, &version);
11095 dns_master_initrawheader(&rawdata);
11096 if (rawversion == 0)
11097 rawdata.flags |= DNS_MASTERRAW_COMPAT;
11098 else if (inline_secure(zone))
11099 get_raw_serial(zone->raw, &rawdata);
11100 else if (zone->sourceserialset) {
11101 rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
11102 rawdata.sourceserial = zone->sourceserial;
11103 }
11104 result = dns_master_dumptostream(zone->mctx, db, version, style,
11105 format, &rawdata, fd);
11106 dns_db_closeversion(db, &version, false);
11107 dns_db_detach(&db);
11108 return (result);
11109 }
11110
11111 isc_result_t
11112 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
11113 const dns_master_style_t *style,
11114 const uint32_t rawversion)
11115 {
11116 return (dumptostream(zone, fd, style, format, rawversion));
11117 }
11118
11119 void
11120 dns_zone_unload(dns_zone_t *zone) {
11121 REQUIRE(DNS_ZONE_VALID(zone));
11122
11123 LOCK_ZONE(zone);
11124 zone_unload(zone);
11125 UNLOCK_ZONE(zone);
11126 }
11127
11128 static void
11129 notify_cancel(dns_zone_t *zone) {
11130 dns_notify_t *notify;
11131
11132 /*
11133 * 'zone' locked by caller.
11134 */
11135
11136 REQUIRE(LOCKED_ZONE(zone));
11137
11138 for (notify = ISC_LIST_HEAD(zone->notifies);
11139 notify != NULL;
11140 notify = ISC_LIST_NEXT(notify, link)) {
11141 if (notify->find != NULL)
11142 dns_adb_cancelfind(notify->find);
11143 if (notify->request != NULL)
11144 dns_request_cancel(notify->request);
11145 }
11146 }
11147
11148 static void
11149 forward_cancel(dns_zone_t *zone) {
11150 dns_forward_t *forward;
11151
11152 /*
11153 * 'zone' locked by caller.
11154 */
11155
11156 REQUIRE(LOCKED_ZONE(zone));
11157
11158 for (forward = ISC_LIST_HEAD(zone->forwards);
11159 forward != NULL;
11160 forward = ISC_LIST_NEXT(forward, link)) {
11161 if (forward->request != NULL)
11162 dns_request_cancel(forward->request);
11163 }
11164 }
11165
11166 static void
11167 zone_unload(dns_zone_t *zone) {
11168 /*
11169 * 'zone' locked by caller.
11170 */
11171
11172 REQUIRE(LOCKED_ZONE(zone));
11173
11174 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
11175 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
11176 if (zone->writeio != NULL)
11177 zonemgr_cancelio(zone->writeio);
11178
11179 if (zone->dctx != NULL)
11180 dns_dumpctx_cancel(zone->dctx);
11181 }
11182 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
11183 zone_detachdb(zone);
11184 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
11185 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
11186 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
11187
11188 if (zone->type == dns_zone_mirror) {
11189 dns_zone_log(zone, ISC_LOG_INFO,
11190 "mirror zone is no longer in use; "
11191 "reverting to normal recursion");
11192 }
11193 }
11194
11195 void
11196 dns_zone_setminrefreshtime(dns_zone_t *zone, uint32_t val) {
11197 REQUIRE(DNS_ZONE_VALID(zone));
11198 REQUIRE(val > 0);
11199
11200 zone->minrefresh = val;
11201 }
11202
11203 void
11204 dns_zone_setmaxrefreshtime(dns_zone_t *zone, uint32_t val) {
11205 REQUIRE(DNS_ZONE_VALID(zone));
11206 REQUIRE(val > 0);
11207
11208 zone->maxrefresh = val;
11209 }
11210
11211 void
11212 dns_zone_setminretrytime(dns_zone_t *zone, uint32_t val) {
11213 REQUIRE(DNS_ZONE_VALID(zone));
11214 REQUIRE(val > 0);
11215
11216 zone->minretry = val;
11217 }
11218
11219 void
11220 dns_zone_setmaxretrytime(dns_zone_t *zone, uint32_t val) {
11221 REQUIRE(DNS_ZONE_VALID(zone));
11222 REQUIRE(val > 0);
11223
11224 zone->maxretry = val;
11225 }
11226
11227 uint32_t
11228 dns_zone_getmaxrecords(dns_zone_t *zone) {
11229 REQUIRE(DNS_ZONE_VALID(zone));
11230
11231 return (zone->maxrecords);
11232 }
11233
11234 void
11235 dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) {
11236 REQUIRE(DNS_ZONE_VALID(zone));
11237
11238 zone->maxrecords = val;
11239 }
11240
11241 static bool
11242 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
11243 isc_sockaddr_t *addr, dns_tsigkey_t *key)
11244 {
11245 dns_notify_t *notify;
11246 dns_zonemgr_t *zmgr;
11247 isc_result_t result;
11248
11249 for (notify = ISC_LIST_HEAD(zone->notifies);
11250 notify != NULL;
11251 notify = ISC_LIST_NEXT(notify, link)) {
11252 if (notify->request != NULL)
11253 continue;
11254 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
11255 dns_name_equal(name, ¬ify->ns))
11256 goto requeue;
11257 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst) &&
11258 notify->key == key)
11259 goto requeue;
11260 }
11261 return (false);
11262
11263 requeue:
11264 /*
11265 * If we are enqueued on the startup ratelimiter and this is
11266 * not a startup notify, re-enqueue on the normal notify
11267 * ratelimiter.
11268 */
11269 if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0 &&
11270 (notify->flags & DNS_NOTIFY_STARTUP) != 0) {
11271 zmgr = notify->zone->zmgr;
11272 result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl,
11273 notify->event);
11274 if (result != ISC_R_SUCCESS)
11275 return (true);
11276
11277 notify->flags &= ~DNS_NOTIFY_STARTUP;
11278 result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
11279 notify->zone->task,
11280 ¬ify->event);
11281 if (result != ISC_R_SUCCESS) {
11282 isc_event_free(¬ify->event);
11283 return (false);
11284 }
11285 }
11286
11287 return (true);
11288 }
11289
11290 static bool
11291 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
11292 dns_tsigkey_t *key = NULL;
11293 isc_sockaddr_t src;
11294 isc_sockaddr_t any;
11295 bool isself;
11296 isc_netaddr_t dstaddr;
11297 isc_result_t result;
11298
11299 if (zone->view == NULL || zone->isself == NULL)
11300 return (false);
11301
11302 switch (isc_sockaddr_pf(dst)) {
11303 case PF_INET:
11304 src = zone->notifysrc4;
11305 isc_sockaddr_any(&any);
11306 break;
11307 case PF_INET6:
11308 src = zone->notifysrc6;
11309 isc_sockaddr_any6(&any);
11310 break;
11311 default:
11312 return (false);
11313 }
11314
11315 /*
11316 * When sending from any the kernel will assign a source address
11317 * that matches the destination address.
11318 */
11319 if (isc_sockaddr_eqaddr(&any, &src))
11320 src = *dst;
11321
11322 isc_netaddr_fromsockaddr(&dstaddr, dst);
11323 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
11324 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
11325 return (false);
11326 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
11327 zone->isselfarg);
11328 if (key != NULL)
11329 dns_tsigkey_detach(&key);
11330 return (isself);
11331 }
11332
11333 static void
11334 notify_destroy(dns_notify_t *notify, bool locked) {
11335 isc_mem_t *mctx;
11336
11337 REQUIRE(DNS_NOTIFY_VALID(notify));
11338
11339 if (notify->zone != NULL) {
11340 if (!locked)
11341 LOCK_ZONE(notify->zone);
11342 REQUIRE(LOCKED_ZONE(notify->zone));
11343 if (ISC_LINK_LINKED(notify, link))
11344 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
11345 if (!locked)
11346 UNLOCK_ZONE(notify->zone);
11347 if (locked)
11348 zone_idetach(¬ify->zone);
11349 else
11350 dns_zone_idetach(¬ify->zone);
11351 }
11352 if (notify->find != NULL)
11353 dns_adb_destroyfind(¬ify->find);
11354 if (notify->request != NULL)
11355 dns_request_destroy(¬ify->request);
11356 if (dns_name_dynamic(¬ify->ns))
11357 dns_name_free(¬ify->ns, notify->mctx);
11358 if (notify->key != NULL)
11359 dns_tsigkey_detach(¬ify->key);
11360 mctx = notify->mctx;
11361 isc_mem_put(notify->mctx, notify, sizeof(*notify));
11362 isc_mem_detach(&mctx);
11363 }
11364
11365 static isc_result_t
11366 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
11367 dns_notify_t *notify;
11368
11369 REQUIRE(notifyp != NULL && *notifyp == NULL);
11370
11371 notify = isc_mem_get(mctx, sizeof(*notify));
11372 if (notify == NULL)
11373 return (ISC_R_NOMEMORY);
11374
11375 notify->mctx = NULL;
11376 isc_mem_attach(mctx, ¬ify->mctx);
11377 notify->flags = flags;
11378 notify->zone = NULL;
11379 notify->find = NULL;
11380 notify->request = NULL;
11381 notify->key = NULL;
11382 notify->event = NULL;
11383 isc_sockaddr_any(¬ify->dst);
11384 dns_name_init(¬ify->ns, NULL);
11385 ISC_LINK_INIT(notify, link);
11386 notify->magic = NOTIFY_MAGIC;
11387 *notifyp = notify;
11388 return (ISC_R_SUCCESS);
11389 }
11390
11391 /*
11392 * XXXAG should check for DNS_ZONEFLG_EXITING
11393 */
11394 static void
11395 process_adb_event(isc_task_t *task, isc_event_t *ev) {
11396 dns_notify_t *notify;
11397 isc_eventtype_t result;
11398
11399 UNUSED(task);
11400
11401 notify = ev->ev_arg;
11402 REQUIRE(DNS_NOTIFY_VALID(notify));
11403 INSIST(task == notify->zone->task);
11404 result = ev->ev_type;
11405 isc_event_free(&ev);
11406 if (result == DNS_EVENT_ADBMOREADDRESSES) {
11407 dns_adb_destroyfind(¬ify->find);
11408 notify_find_address(notify);
11409 return;
11410 }
11411 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
11412 LOCK_ZONE(notify->zone);
11413 notify_send(notify);
11414 UNLOCK_ZONE(notify->zone);
11415 }
11416 notify_destroy(notify, false);
11417 }
11418
11419 static void
11420 notify_find_address(dns_notify_t *notify) {
11421 isc_result_t result;
11422 unsigned int options;
11423
11424 REQUIRE(DNS_NOTIFY_VALID(notify));
11425 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
11426 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
11427
11428 if (notify->zone->view->adb == NULL)
11429 goto destroy;
11430
11431 result = dns_adb_createfind(notify->zone->view->adb,
11432 notify->zone->task,
11433 process_adb_event, notify,
11434 ¬ify->ns, dns_rootname, 0,
11435 options, 0, NULL,
11436 notify->zone->view->dstport,
11437 0, NULL, ¬ify->find);
11438
11439 /* Something failed? */
11440 if (result != ISC_R_SUCCESS)
11441 goto destroy;
11442
11443 /* More addresses pending? */
11444 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
11445 return;
11446
11447 /* We have as many addresses as we can get. */
11448 LOCK_ZONE(notify->zone);
11449 notify_send(notify);
11450 UNLOCK_ZONE(notify->zone);
11451
11452 destroy:
11453 notify_destroy(notify, false);
11454 }
11455
11456
11457 static isc_result_t
11458 notify_send_queue(dns_notify_t *notify, bool startup) {
11459 isc_event_t *e;
11460 isc_result_t result;
11461
11462 INSIST(notify->event == NULL);
11463 e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR,
11464 notify_send_toaddr, notify, sizeof(isc_event_t));
11465 if (e == NULL)
11466 return (ISC_R_NOMEMORY);
11467 if (startup)
11468 notify->event = e;
11469 e->ev_arg = notify;
11470 e->ev_sender = NULL;
11471 result = isc_ratelimiter_enqueue(startup
11472 ? notify->zone->zmgr->startupnotifyrl
11473 : notify->zone->zmgr->notifyrl,
11474 notify->zone->task, &e);
11475 if (result != ISC_R_SUCCESS) {
11476 isc_event_free(&e);
11477 notify->event = NULL;
11478 }
11479 return (result);
11480 }
11481
11482 static void
11483 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
11484 dns_notify_t *notify;
11485 isc_result_t result;
11486 dns_message_t *message = NULL;
11487 isc_netaddr_t dstip;
11488 dns_tsigkey_t *key = NULL;
11489 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
11490 isc_sockaddr_t src;
11491 unsigned int options, timeout;
11492 bool have_notifysource = false;
11493 bool have_notifydscp = false;
11494 isc_dscp_t dscp = -1;
11495
11496 notify = event->ev_arg;
11497 REQUIRE(DNS_NOTIFY_VALID(notify));
11498
11499 UNUSED(task);
11500
11501 LOCK_ZONE(notify->zone);
11502
11503 notify->event = NULL;
11504
11505 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
11506 result = ISC_R_CANCELED;
11507 goto cleanup;
11508 }
11509
11510 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
11511 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
11512 notify->zone->view->requestmgr == NULL ||
11513 notify->zone->db == NULL) {
11514 result = ISC_R_CANCELED;
11515 goto cleanup;
11516 }
11517
11518 /*
11519 * The raw IPv4 address should also exist. Don't send to the
11520 * mapped form.
11521 */
11522 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
11523 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
11524 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
11525 notify_log(notify->zone, ISC_LOG_DEBUG(3),
11526 "notify: ignoring IPv6 mapped IPV4 address: %s",
11527 addrbuf);
11528 result = ISC_R_CANCELED;
11529 goto cleanup;
11530 }
11531
11532 result = notify_createmessage(notify->zone, notify->flags, &message);
11533 if (result != ISC_R_SUCCESS)
11534 goto cleanup;
11535
11536 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
11537 if (notify->key != NULL) {
11538 /* Transfer ownership of key */
11539 key = notify->key;
11540 notify->key = NULL;
11541 } else {
11542 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
11543 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
11544 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
11545 notify_log(notify->zone, ISC_LOG_ERROR,
11546 "NOTIFY to %s not sent. "
11547 "Peer TSIG key lookup failure.", addrbuf);
11548 goto cleanup_message;
11549 }
11550 }
11551
11552 /* XXX: should we log the tsig key too? */
11553 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
11554 addrbuf);
11555 options = 0;
11556 if (notify->zone->view->peers != NULL) {
11557 dns_peer_t *peer = NULL;
11558 bool usetcp = false;
11559 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
11560 &dstip, &peer);
11561 if (result == ISC_R_SUCCESS) {
11562 result = dns_peer_getnotifysource(peer, &src);
11563 if (result == ISC_R_SUCCESS)
11564 have_notifysource = true;
11565 dns_peer_getnotifydscp(peer, &dscp);
11566 if (dscp != -1)
11567 have_notifydscp = true;
11568 result = dns_peer_getforcetcp(peer, &usetcp);
11569 if (result == ISC_R_SUCCESS && usetcp)
11570 options |= DNS_FETCHOPT_TCP;
11571 }
11572 }
11573 switch (isc_sockaddr_pf(¬ify->dst)) {
11574 case PF_INET:
11575 if (!have_notifysource)
11576 src = notify->zone->notifysrc4;
11577 if (!have_notifydscp)
11578 dscp = notify->zone->notifysrc4dscp;
11579 break;
11580 case PF_INET6:
11581 if (!have_notifysource)
11582 src = notify->zone->notifysrc6;
11583 if (!have_notifydscp)
11584 dscp = notify->zone->notifysrc6dscp;
11585 break;
11586 default:
11587 result = ISC_R_NOTIMPLEMENTED;
11588 goto cleanup_key;
11589 }
11590 timeout = 15;
11591 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
11592 timeout = 30;
11593 result = dns_request_createvia(notify->zone->view->requestmgr,
11594 message, &src, ¬ify->dst, dscp,
11595 options, key, timeout * 3, timeout,
11596 0, notify->zone->task, notify_done,
11597 notify, ¬ify->request);
11598 if (result == ISC_R_SUCCESS) {
11599 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
11600 inc_stats(notify->zone,
11601 dns_zonestatscounter_notifyoutv4);
11602 } else {
11603 inc_stats(notify->zone,
11604 dns_zonestatscounter_notifyoutv6);
11605 }
11606 }
11607
11608 cleanup_key:
11609 if (key != NULL)
11610 dns_tsigkey_detach(&key);
11611 cleanup_message:
11612 dns_message_destroy(&message);
11613 cleanup:
11614 UNLOCK_ZONE(notify->zone);
11615 isc_event_free(&event);
11616 if (result != ISC_R_SUCCESS)
11617 notify_destroy(notify, false);
11618 }
11619
11620 static void
11621 notify_send(dns_notify_t *notify) {
11622 dns_adbaddrinfo_t *ai;
11623 isc_sockaddr_t dst;
11624 isc_result_t result;
11625 dns_notify_t *newnotify = NULL;
11626 unsigned int flags;
11627 bool startup;
11628
11629 /*
11630 * Zone lock held by caller.
11631 */
11632 REQUIRE(DNS_NOTIFY_VALID(notify));
11633 REQUIRE(LOCKED_ZONE(notify->zone));
11634
11635 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING))
11636 return;
11637
11638 for (ai = ISC_LIST_HEAD(notify->find->list);
11639 ai != NULL;
11640 ai = ISC_LIST_NEXT(ai, publink)) {
11641 dst = ai->sockaddr;
11642 if (notify_isqueued(notify->zone, notify->flags, NULL, &dst,
11643 NULL))
11644 continue;
11645 if (notify_isself(notify->zone, &dst))
11646 continue;
11647 newnotify = NULL;
11648 flags = notify->flags & DNS_NOTIFY_NOSOA;
11649 result = notify_create(notify->mctx, flags, &newnotify);
11650 if (result != ISC_R_SUCCESS)
11651 goto cleanup;
11652 zone_iattach(notify->zone, &newnotify->zone);
11653 ISC_LIST_APPEND(newnotify->zone->notifies, newnotify, link);
11654 newnotify->dst = dst;
11655 startup = ((notify->flags & DNS_NOTIFY_STARTUP) != 0);
11656 result = notify_send_queue(newnotify, startup);
11657 if (result != ISC_R_SUCCESS)
11658 goto cleanup;
11659 newnotify = NULL;
11660 }
11661
11662 cleanup:
11663 if (newnotify != NULL)
11664 notify_destroy(newnotify, true);
11665 }
11666
11667 void
11668 dns_zone_notify(dns_zone_t *zone) {
11669 isc_time_t now;
11670
11671 REQUIRE(DNS_ZONE_VALID(zone));
11672
11673 LOCK_ZONE(zone);
11674 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
11675
11676 TIME_NOW(&now);
11677 zone_settimer(zone, &now);
11678 UNLOCK_ZONE(zone);
11679 }
11680
11681 static void
11682 zone_notify(dns_zone_t *zone, isc_time_t *now) {
11683 dns_dbnode_t *node = NULL;
11684 dns_db_t *zonedb = NULL;
11685 dns_dbversion_t *version = NULL;
11686 dns_name_t *origin = NULL;
11687 dns_name_t master;
11688 dns_rdata_ns_t ns;
11689 dns_rdata_soa_t soa;
11690 uint32_t serial;
11691 dns_rdata_t rdata = DNS_RDATA_INIT;
11692 dns_rdataset_t nsrdset;
11693 dns_rdataset_t soardset;
11694 isc_result_t result;
11695 unsigned int i;
11696 isc_sockaddr_t dst;
11697 bool isqueued;
11698 dns_notifytype_t notifytype;
11699 unsigned int flags = 0;
11700 bool loggednotify = false;
11701 bool startup;
11702
11703 REQUIRE(DNS_ZONE_VALID(zone));
11704
11705 LOCK_ZONE(zone);
11706 startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
11707 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
11708 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
11709 notifytype = zone->notifytype;
11710 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
11711 UNLOCK_ZONE(zone);
11712
11713 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
11714 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
11715 return;
11716
11717 if (notifytype == dns_notifytype_no)
11718 return;
11719
11720 if (notifytype == dns_notifytype_masteronly &&
11721 zone->type != dns_zone_master)
11722 return;
11723
11724 origin = &zone->origin;
11725
11726 /*
11727 * If the zone is dialup we are done as we don't want to send
11728 * the current soa so as to force a refresh query.
11729 */
11730 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
11731 flags |= DNS_NOTIFY_NOSOA;
11732
11733 /*
11734 * Record that this was a notify due to starting up.
11735 */
11736 if (startup)
11737 flags |= DNS_NOTIFY_STARTUP;
11738
11739 /*
11740 * Get SOA RRset.
11741 */
11742 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11743 if (zone->db != NULL)
11744 dns_db_attach(zone->db, &zonedb);
11745 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11746 if (zonedb == NULL)
11747 return;
11748 dns_db_currentversion(zonedb, &version);
11749 result = dns_db_findnode(zonedb, origin, false, &node);
11750 if (result != ISC_R_SUCCESS)
11751 goto cleanup1;
11752
11753 dns_rdataset_init(&soardset);
11754 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
11755 dns_rdatatype_none, 0, &soardset, NULL);
11756 if (result != ISC_R_SUCCESS)
11757 goto cleanup2;
11758
11759 /*
11760 * Find serial and master server's name.
11761 */
11762 dns_name_init(&master, NULL);
11763 result = dns_rdataset_first(&soardset);
11764 if (result != ISC_R_SUCCESS)
11765 goto cleanup3;
11766 dns_rdataset_current(&soardset, &rdata);
11767 result = dns_rdata_tostruct(&rdata, &soa, NULL);
11768 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11769 dns_rdata_reset(&rdata);
11770 result = dns_name_dup(&soa.origin, zone->mctx, &master);
11771 serial = soa.serial;
11772 dns_rdataset_disassociate(&soardset);
11773 if (result != ISC_R_SUCCESS)
11774 goto cleanup3;
11775
11776 /*
11777 * Enqueue notify requests for 'also-notify' servers.
11778 */
11779 LOCK_ZONE(zone);
11780 for (i = 0; i < zone->notifycnt; i++) {
11781 dns_tsigkey_t *key = NULL;
11782 dns_notify_t *notify = NULL;
11783
11784 if ((zone->notifykeynames != NULL) &&
11785 (zone->notifykeynames[i] != NULL)) {
11786 dns_view_t *view = dns_zone_getview(zone);
11787 dns_name_t *keyname = zone->notifykeynames[i];
11788 (void)dns_view_gettsig(view, keyname, &key);
11789 }
11790
11791 dst = zone->notify[i];
11792 if (notify_isqueued(zone, flags, NULL, &dst, key)) {
11793 if (key != NULL)
11794 dns_tsigkey_detach(&key);
11795 continue;
11796 }
11797
11798 result = notify_create(zone->mctx, flags, ¬ify);
11799 if (result != ISC_R_SUCCESS) {
11800 if (key != NULL)
11801 dns_tsigkey_detach(&key);
11802 continue;
11803 }
11804
11805 zone_iattach(zone, ¬ify->zone);
11806 notify->dst = dst;
11807
11808 INSIST(notify->key == NULL);
11809
11810 if (key != NULL) {
11811 notify->key = key;
11812 key = NULL;
11813 }
11814
11815 ISC_LIST_APPEND(zone->notifies, notify, link);
11816 result = notify_send_queue(notify, startup);
11817 if (result != ISC_R_SUCCESS)
11818 notify_destroy(notify, true);
11819 if (!loggednotify) {
11820 notify_log(zone, ISC_LOG_INFO,
11821 "sending notifies (serial %u)",
11822 serial);
11823 loggednotify = true;
11824 }
11825 }
11826 UNLOCK_ZONE(zone);
11827
11828 if (notifytype == dns_notifytype_explicit)
11829 goto cleanup3;
11830
11831 /*
11832 * Process NS RRset to generate notifies.
11833 */
11834
11835 dns_rdataset_init(&nsrdset);
11836 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
11837 dns_rdatatype_none, 0, &nsrdset, NULL);
11838 if (result != ISC_R_SUCCESS)
11839 goto cleanup3;
11840
11841 result = dns_rdataset_first(&nsrdset);
11842 while (result == ISC_R_SUCCESS) {
11843 dns_notify_t *notify = NULL;
11844
11845 dns_rdataset_current(&nsrdset, &rdata);
11846 result = dns_rdata_tostruct(&rdata, &ns, NULL);
11847 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11848 dns_rdata_reset(&rdata);
11849 /*
11850 * Don't notify the master server unless explicitly
11851 * configured to do so.
11852 */
11853 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
11854 dns_name_compare(&master, &ns.name) == 0) {
11855 result = dns_rdataset_next(&nsrdset);
11856 continue;
11857 }
11858
11859 if (!loggednotify) {
11860 notify_log(zone, ISC_LOG_INFO,
11861 "sending notifies (serial %u)",
11862 serial);
11863 loggednotify = true;
11864 }
11865
11866 LOCK_ZONE(zone);
11867 isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL);
11868 UNLOCK_ZONE(zone);
11869 if (isqueued) {
11870 result = dns_rdataset_next(&nsrdset);
11871 continue;
11872 }
11873 result = notify_create(zone->mctx, flags, ¬ify);
11874 if (result != ISC_R_SUCCESS)
11875 continue;
11876 dns_zone_iattach(zone, ¬ify->zone);
11877 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
11878 if (result != ISC_R_SUCCESS) {
11879 LOCK_ZONE(zone);
11880 notify_destroy(notify, true);
11881 UNLOCK_ZONE(zone);
11882 continue;
11883 }
11884 LOCK_ZONE(zone);
11885 ISC_LIST_APPEND(zone->notifies, notify, link);
11886 UNLOCK_ZONE(zone);
11887 notify_find_address(notify);
11888 result = dns_rdataset_next(&nsrdset);
11889 }
11890 dns_rdataset_disassociate(&nsrdset);
11891
11892 cleanup3:
11893 if (dns_name_dynamic(&master))
11894 dns_name_free(&master, zone->mctx);
11895 cleanup2:
11896 dns_db_detachnode(zonedb, &node);
11897 cleanup1:
11898 dns_db_closeversion(zonedb, &version, false);
11899 dns_db_detach(&zonedb);
11900 }
11901
11902 /***
11903 *** Private
11904 ***/
11905
11906 static inline isc_result_t
11907 save_nsrrset(dns_message_t *message, dns_name_t *name,
11908 dns_db_t *db, dns_dbversion_t *version)
11909 {
11910 dns_rdataset_t *nsrdataset = NULL;
11911 dns_rdataset_t *rdataset = NULL;
11912 dns_dbnode_t *node = NULL;
11913 dns_rdata_ns_t ns;
11914 isc_result_t result;
11915 dns_rdata_t rdata = DNS_RDATA_INIT;
11916
11917 /*
11918 * Extract NS RRset from message.
11919 */
11920 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
11921 dns_rdatatype_ns, dns_rdatatype_none,
11922 NULL, &nsrdataset);
11923 if (result != ISC_R_SUCCESS)
11924 goto fail;
11925
11926 /*
11927 * Add NS rdataset.
11928 */
11929 result = dns_db_findnode(db, name, true, &node);
11930 if (result != ISC_R_SUCCESS)
11931 goto fail;
11932 result = dns_db_addrdataset(db, node, version, 0,
11933 nsrdataset, 0, NULL);
11934 dns_db_detachnode(db, &node);
11935 if (result != ISC_R_SUCCESS)
11936 goto fail;
11937 /*
11938 * Add glue rdatasets.
11939 */
11940 for (result = dns_rdataset_first(nsrdataset);
11941 result == ISC_R_SUCCESS;
11942 result = dns_rdataset_next(nsrdataset)) {
11943 dns_rdataset_current(nsrdataset, &rdata);
11944 result = dns_rdata_tostruct(&rdata, &ns, NULL);
11945 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11946 dns_rdata_reset(&rdata);
11947 if (!dns_name_issubdomain(&ns.name, name))
11948 continue;
11949 rdataset = NULL;
11950 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
11951 &ns.name, dns_rdatatype_aaaa,
11952 dns_rdatatype_none, NULL,
11953 &rdataset);
11954 if (result == ISC_R_SUCCESS) {
11955 result = dns_db_findnode(db, &ns.name,
11956 true, &node);
11957 if (result != ISC_R_SUCCESS)
11958 goto fail;
11959 result = dns_db_addrdataset(db, node, version, 0,
11960 rdataset, 0, NULL);
11961 dns_db_detachnode(db, &node);
11962 if (result != ISC_R_SUCCESS)
11963 goto fail;
11964 }
11965 rdataset = NULL;
11966 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
11967 &ns.name, dns_rdatatype_a,
11968 dns_rdatatype_none, NULL,
11969 &rdataset);
11970 if (result == ISC_R_SUCCESS) {
11971 result = dns_db_findnode(db, &ns.name,
11972 true, &node);
11973 if (result != ISC_R_SUCCESS)
11974 goto fail;
11975 result = dns_db_addrdataset(db, node, version, 0,
11976 rdataset, 0, NULL);
11977 dns_db_detachnode(db, &node);
11978 if (result != ISC_R_SUCCESS)
11979 goto fail;
11980 }
11981 }
11982 if (result != ISC_R_NOMORE)
11983 goto fail;
11984
11985 return (ISC_R_SUCCESS);
11986
11987 fail:
11988 return (result);
11989 }
11990
11991 static void
11992 stub_callback(isc_task_t *task, isc_event_t *event) {
11993 const char me[] = "stub_callback";
11994 dns_requestevent_t *revent = (dns_requestevent_t *)event;
11995 dns_stub_t *stub = NULL;
11996 dns_message_t *msg = NULL;
11997 dns_zone_t *zone = NULL;
11998 char master[ISC_SOCKADDR_FORMATSIZE];
11999 char source[ISC_SOCKADDR_FORMATSIZE];
12000 uint32_t nscnt, cnamecnt, refresh, retry, expire;
12001 isc_result_t result;
12002 isc_time_t now;
12003 bool exiting = false;
12004 isc_interval_t i;
12005 unsigned int j, soacount;
12006
12007 stub = revent->ev_arg;
12008 INSIST(DNS_STUB_VALID(stub));
12009
12010 UNUSED(task);
12011
12012 zone = stub->zone;
12013
12014 ENTER;
12015
12016 TIME_NOW(&now);
12017
12018 LOCK_ZONE(zone);
12019
12020 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
12021 zone_debuglog(zone, me, 1, "exiting");
12022 exiting = true;
12023 goto next_master;
12024 }
12025
12026 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
12027 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
12028
12029 if (revent->result != ISC_R_SUCCESS) {
12030 if (revent->result == ISC_R_TIMEDOUT &&
12031 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
12032 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
12033 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12034 "refreshing stub: timeout retrying "
12035 " without EDNS master %s (source %s)",
12036 master, source);
12037 goto same_master;
12038 }
12039 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
12040 &zone->sourceaddr, &now);
12041 dns_zone_log(zone, ISC_LOG_INFO,
12042 "could not refresh stub from master %s"
12043 " (source %s): %s", master, source,
12044 dns_result_totext(revent->result));
12045 goto next_master;
12046 }
12047
12048 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
12049 if (result != ISC_R_SUCCESS)
12050 goto next_master;
12051
12052 result = dns_request_getresponse(revent->request, msg, 0);
12053 if (result != ISC_R_SUCCESS)
12054 goto next_master;
12055
12056 /*
12057 * Unexpected rcode.
12058 */
12059 if (msg->rcode != dns_rcode_noerror) {
12060 char rcode[128];
12061 isc_buffer_t rb;
12062
12063 isc_buffer_init(&rb, rcode, sizeof(rcode));
12064 (void)dns_rcode_totext(msg->rcode, &rb);
12065
12066 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
12067 (msg->rcode == dns_rcode_servfail ||
12068 msg->rcode == dns_rcode_notimp ||
12069 msg->rcode == dns_rcode_formerr)) {
12070 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12071 "refreshing stub: rcode (%.*s) retrying "
12072 "without EDNS master %s (source %s)",
12073 (int)rb.used, rcode, master, source);
12074 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
12075 goto same_master;
12076 }
12077
12078 dns_zone_log(zone, ISC_LOG_INFO,
12079 "refreshing stub: "
12080 "unexpected rcode (%.*s) from %s (source %s)",
12081 (int)rb.used, rcode, master, source);
12082 goto next_master;
12083 }
12084
12085 /*
12086 * We need complete messages.
12087 */
12088 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
12089 if (dns_request_usedtcp(revent->request)) {
12090 dns_zone_log(zone, ISC_LOG_INFO,
12091 "refreshing stub: truncated TCP "
12092 "response from master %s (source %s)",
12093 master, source);
12094 goto next_master;
12095 }
12096 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
12097 goto same_master;
12098 }
12099
12100 /*
12101 * If non-auth log and next master.
12102 */
12103 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
12104 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
12105 "non-authoritative answer from "
12106 "master %s (source %s)", master, source);
12107 goto next_master;
12108 }
12109
12110 /*
12111 * Sanity checks.
12112 */
12113 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
12114 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
12115
12116 if (cnamecnt != 0) {
12117 dns_zone_log(zone, ISC_LOG_INFO,
12118 "refreshing stub: unexpected CNAME response "
12119 "from master %s (source %s)", master, source);
12120 goto next_master;
12121 }
12122
12123 if (nscnt == 0) {
12124 dns_zone_log(zone, ISC_LOG_INFO,
12125 "refreshing stub: no NS records in response "
12126 "from master %s (source %s)", master, source);
12127 goto next_master;
12128 }
12129
12130 /*
12131 * Save answer.
12132 */
12133 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
12134 if (result != ISC_R_SUCCESS) {
12135 dns_zone_log(zone, ISC_LOG_INFO,
12136 "refreshing stub: unable to save NS records "
12137 "from master %s (source %s)", master, source);
12138 goto next_master;
12139 }
12140
12141 /*
12142 * Tidy up.
12143 */
12144 dns_db_closeversion(stub->db, &stub->version, true);
12145 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
12146 if (zone->db == NULL)
12147 zone_attachdb(zone, stub->db);
12148 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
12149 &refresh, &retry, &expire, NULL, NULL);
12150 if (result == ISC_R_SUCCESS && soacount > 0U) {
12151 zone->refresh = RANGE(refresh, zone->minrefresh,
12152 zone->maxrefresh);
12153 zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
12154 zone->expire = RANGE(expire, zone->refresh + zone->retry,
12155 DNS_MAX_EXPIRE);
12156 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
12157 }
12158 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
12159 dns_db_detach(&stub->db);
12160
12161 dns_message_destroy(&msg);
12162 isc_event_free(&event);
12163 dns_request_destroy(&zone->request);
12164
12165 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
12166 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
12167 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
12168 isc_interval_set(&i, zone->expire, 0);
12169 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
12170
12171 if (zone->masterfile != NULL)
12172 zone_needdump(zone, 0);
12173
12174 zone_settimer(zone, &now);
12175 goto free_stub;
12176
12177 next_master:
12178 if (stub->version != NULL)
12179 dns_db_closeversion(stub->db, &stub->version, false);
12180 if (stub->db != NULL)
12181 dns_db_detach(&stub->db);
12182 if (msg != NULL)
12183 dns_message_destroy(&msg);
12184 isc_event_free(&event);
12185 dns_request_destroy(&zone->request);
12186 /*
12187 * Skip to next failed / untried master.
12188 */
12189 do {
12190 zone->curmaster++;
12191 } while (zone->curmaster < zone->masterscnt &&
12192 zone->mastersok[zone->curmaster]);
12193 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
12194 if (exiting || zone->curmaster >= zone->masterscnt) {
12195 bool done = true;
12196 if (!exiting &&
12197 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
12198 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
12199 /*
12200 * Did we get a good answer from all the masters?
12201 */
12202 for (j = 0; j < zone->masterscnt; j++)
12203 if (zone->mastersok[j] == false) {
12204 done = false;
12205 break;
12206 }
12207 } else
12208 done = true;
12209 if (!done) {
12210 zone->curmaster = 0;
12211 /*
12212 * Find the next failed master.
12213 */
12214 while (zone->curmaster < zone->masterscnt &&
12215 zone->mastersok[zone->curmaster])
12216 zone->curmaster++;
12217 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
12218 } else {
12219 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
12220
12221 zone_settimer(zone, &now);
12222 goto free_stub;
12223 }
12224 }
12225 queue_soa_query(zone);
12226 goto free_stub;
12227
12228 same_master:
12229 if (msg != NULL)
12230 dns_message_destroy(&msg);
12231 isc_event_free(&event);
12232 dns_request_destroy(&zone->request);
12233 ns_query(zone, NULL, stub);
12234 UNLOCK_ZONE(zone);
12235 goto done;
12236
12237 free_stub:
12238 UNLOCK_ZONE(zone);
12239 stub->magic = 0;
12240 dns_zone_idetach(&stub->zone);
12241 INSIST(stub->db == NULL);
12242 INSIST(stub->version == NULL);
12243 isc_mem_put(stub->mctx, stub, sizeof(*stub));
12244
12245 done:
12246 INSIST(event == NULL);
12247 return;
12248 }
12249
12250 /*
12251 * Get the EDNS EXPIRE option from the response and if it exists trim
12252 * expire to be not more than it.
12253 */
12254 static void
12255 get_edns_expire(dns_zone_t * zone, dns_message_t *message,
12256 uint32_t *expirep)
12257 {
12258 isc_result_t result;
12259 uint32_t expire;
12260 dns_rdata_t rdata = DNS_RDATA_INIT;
12261 isc_buffer_t optbuf;
12262 uint16_t optcode;
12263 uint16_t optlen;
12264
12265 REQUIRE(expirep != NULL);
12266 REQUIRE(message != NULL);
12267
12268 if (message->opt == NULL)
12269 return;
12270
12271 result = dns_rdataset_first(message->opt);
12272 if (result == ISC_R_SUCCESS) {
12273 dns_rdataset_current(message->opt, &rdata);
12274 isc_buffer_init(&optbuf, rdata.data, rdata.length);
12275 isc_buffer_add(&optbuf, rdata.length);
12276 while (isc_buffer_remaininglength(&optbuf) >= 4) {
12277 optcode = isc_buffer_getuint16(&optbuf);
12278 optlen = isc_buffer_getuint16(&optbuf);
12279 /*
12280 * A EDNS EXPIRE response has a length of 4.
12281 */
12282 if (optcode != DNS_OPT_EXPIRE || optlen != 4) {
12283 isc_buffer_forward(&optbuf, optlen);
12284 continue;
12285 }
12286 expire = isc_buffer_getuint32(&optbuf);
12287 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12288 "got EDNS EXPIRE of %u", expire);
12289 /*
12290 * Trim *expirep?
12291 */
12292 if (expire < *expirep)
12293 *expirep = expire;
12294 break;
12295 }
12296 }
12297 }
12298
12299 /*
12300 * Set the file modification time zone->expire seconds before expiretime.
12301 */
12302 static void
12303 setmodtime(dns_zone_t *zone, isc_time_t *expiretime) {
12304 isc_result_t result;
12305 isc_time_t when;
12306 isc_interval_t i;
12307
12308 isc_interval_set(&i, zone->expire, 0);
12309 result = isc_time_subtract(expiretime, &i, &when);
12310 if (result != ISC_R_SUCCESS)
12311 return;
12312
12313 result = ISC_R_FAILURE;
12314 if (zone->journal != NULL)
12315 result = isc_file_settime(zone->journal, &when);
12316 if (result == ISC_R_SUCCESS &&
12317 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
12318 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP))
12319 result = isc_file_settime(zone->masterfile, &when);
12320 else if (result != ISC_R_SUCCESS)
12321 result = isc_file_settime(zone->masterfile, &when);
12322
12323 /*
12324 * Someone removed the file from underneath us!
12325 */
12326 if (result == ISC_R_FILENOTFOUND) {
12327 zone_needdump(zone, DNS_DUMP_DELAY);
12328 } else if (result != ISC_R_SUCCESS)
12329 dns_zone_log(zone, ISC_LOG_ERROR, "refresh: could not set "
12330 "file modification time of '%s': %s",
12331 zone->masterfile, dns_result_totext(result));
12332 }
12333
12334 /*
12335 * An SOA query has finished (successfully or not).
12336 */
12337 static void
12338 refresh_callback(isc_task_t *task, isc_event_t *event) {
12339 const char me[] = "refresh_callback";
12340 dns_requestevent_t *revent = (dns_requestevent_t *)event;
12341 dns_zone_t *zone;
12342 dns_message_t *msg = NULL;
12343 uint32_t soacnt, cnamecnt, soacount, nscount;
12344 isc_time_t now;
12345 char master[ISC_SOCKADDR_FORMATSIZE];
12346 char source[ISC_SOCKADDR_FORMATSIZE];
12347 dns_rdataset_t *rdataset = NULL;
12348 dns_rdata_t rdata = DNS_RDATA_INIT;
12349 dns_rdata_soa_t soa;
12350 isc_result_t result;
12351 uint32_t serial, oldserial = 0;
12352 unsigned int j;
12353 bool do_queue_xfrin = false;
12354
12355 zone = revent->ev_arg;
12356 INSIST(DNS_ZONE_VALID(zone));
12357
12358 UNUSED(task);
12359
12360 ENTER;
12361
12362 TIME_NOW(&now);
12363
12364 LOCK_ZONE(zone);
12365
12366 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
12367 isc_event_free(&event);
12368 dns_request_destroy(&zone->request);
12369 goto detach;
12370 }
12371
12372 /*
12373 * if timeout log and next master;
12374 */
12375
12376 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
12377 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
12378
12379 if (revent->result != ISC_R_SUCCESS) {
12380 if (revent->result == ISC_R_TIMEDOUT &&
12381 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
12382 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
12383 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12384 "refresh: timeout retrying without EDNS "
12385 "master %s (source %s)", master, source);
12386 goto same_master;
12387 }
12388 if (revent->result == ISC_R_TIMEDOUT &&
12389 !dns_request_usedtcp(revent->request)) {
12390 dns_zone_log(zone, ISC_LOG_INFO,
12391 "refresh: retry limit for "
12392 "master %s exceeded (source %s)",
12393 master, source);
12394 /* Try with slave with TCP. */
12395 if ((zone->type == dns_zone_slave ||
12396 zone->type == dns_zone_mirror ||
12397 zone->type == dns_zone_redirect) &&
12398 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH))
12399 {
12400 if (!dns_zonemgr_unreachable(zone->zmgr,
12401 &zone->masteraddr,
12402 &zone->sourceaddr,
12403 &now))
12404 {
12405 DNS_ZONE_SETFLAG(zone,
12406 DNS_ZONEFLG_SOABEFOREAXFR);
12407 goto tcp_transfer;
12408 }
12409 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12410 "refresh: skipped tcp fallback "
12411 "as master %s (source %s) is "
12412 "unreachable (cached)",
12413 master, source);
12414 }
12415 } else
12416 dns_zone_log(zone, ISC_LOG_INFO,
12417 "refresh: failure trying master "
12418 "%s (source %s): %s", master, source,
12419 dns_result_totext(revent->result));
12420 goto next_master;
12421 }
12422
12423 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
12424 if (result != ISC_R_SUCCESS)
12425 goto next_master;
12426 result = dns_request_getresponse(revent->request, msg, 0);
12427 if (result != ISC_R_SUCCESS) {
12428 dns_zone_log(zone, ISC_LOG_INFO,
12429 "refresh: failure trying master "
12430 "%s (source %s): %s", master, source,
12431 dns_result_totext(result));
12432 goto next_master;
12433 }
12434
12435 /*
12436 * Unexpected rcode.
12437 */
12438 if (msg->rcode != dns_rcode_noerror) {
12439 char rcode[128];
12440 isc_buffer_t rb;
12441
12442 isc_buffer_init(&rb, rcode, sizeof(rcode));
12443 (void)dns_rcode_totext(msg->rcode, &rb);
12444
12445 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
12446 (msg->rcode == dns_rcode_servfail ||
12447 msg->rcode == dns_rcode_notimp ||
12448 msg->rcode == dns_rcode_formerr)) {
12449 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12450 "refresh: rcode (%.*s) retrying without "
12451 "EDNS master %s (source %s)",
12452 (int)rb.used, rcode, master, source);
12453 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
12454 goto same_master;
12455 }
12456 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
12457 msg->rcode == dns_rcode_badvers) {
12458 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12459 "refresh: rcode (%.*s) retrying without "
12460 "EDNS EXPIRE OPTION master %s (source %s)",
12461 (int)rb.used, rcode, master, source);
12462 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
12463 goto same_master;
12464 }
12465 dns_zone_log(zone, ISC_LOG_INFO,
12466 "refresh: unexpected rcode (%.*s) from "
12467 "master %s (source %s)", (int)rb.used, rcode,
12468 master, source);
12469 /*
12470 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
12471 */
12472 if (msg->rcode == dns_rcode_refused &&
12473 (zone->type == dns_zone_slave ||
12474 zone->type == dns_zone_mirror ||
12475 zone->type == dns_zone_redirect))
12476 {
12477 goto tcp_transfer;
12478 }
12479 goto next_master;
12480 }
12481
12482 /*
12483 * If truncated punt to zone transfer which will query again.
12484 */
12485 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
12486 if (zone->type == dns_zone_slave ||
12487 zone->type == dns_zone_mirror ||
12488 zone->type == dns_zone_redirect)
12489 {
12490 dns_zone_log(zone, ISC_LOG_INFO,
12491 "refresh: truncated UDP answer, "
12492 "initiating TCP zone xfer "
12493 "for master %s (source %s)",
12494 master, source);
12495 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
12496 goto tcp_transfer;
12497 } else {
12498 INSIST(zone->type == dns_zone_stub);
12499 if (dns_request_usedtcp(revent->request)) {
12500 dns_zone_log(zone, ISC_LOG_INFO,
12501 "refresh: truncated TCP response "
12502 "from master %s (source %s)",
12503 master, source);
12504 goto next_master;
12505 }
12506 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
12507 goto same_master;
12508 }
12509 }
12510
12511 /*
12512 * if non-auth log and next master;
12513 */
12514 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
12515 dns_zone_log(zone, ISC_LOG_INFO,
12516 "refresh: non-authoritative answer from "
12517 "master %s (source %s)", master, source);
12518 goto next_master;
12519 }
12520
12521 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
12522 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
12523 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
12524 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
12525 dns_rdatatype_soa);
12526
12527 /*
12528 * There should not be a CNAME record at top of zone.
12529 */
12530 if (cnamecnt != 0) {
12531 dns_zone_log(zone, ISC_LOG_INFO,
12532 "refresh: CNAME at top of zone "
12533 "in master %s (source %s)", master, source);
12534 goto next_master;
12535 }
12536
12537 /*
12538 * if referral log and next master;
12539 */
12540 if (soacnt == 0 && soacount == 0 && nscount != 0) {
12541 dns_zone_log(zone, ISC_LOG_INFO,
12542 "refresh: referral response "
12543 "from master %s (source %s)", master, source);
12544 goto next_master;
12545 }
12546
12547 /*
12548 * if nodata log and next master;
12549 */
12550 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
12551 dns_zone_log(zone, ISC_LOG_INFO,
12552 "refresh: NODATA response "
12553 "from master %s (source %s)", master, source);
12554 goto next_master;
12555 }
12556
12557 /*
12558 * Only one soa at top of zone.
12559 */
12560 if (soacnt != 1) {
12561 dns_zone_log(zone, ISC_LOG_INFO,
12562 "refresh: answer SOA count (%d) != 1 "
12563 "from master %s (source %s)",
12564 soacnt, master, source);
12565 goto next_master;
12566 }
12567
12568 /*
12569 * Extract serial
12570 */
12571 rdataset = NULL;
12572 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
12573 dns_rdatatype_soa, dns_rdatatype_none,
12574 NULL, &rdataset);
12575 if (result != ISC_R_SUCCESS) {
12576 dns_zone_log(zone, ISC_LOG_INFO,
12577 "refresh: unable to get SOA record "
12578 "from master %s (source %s)", master, source);
12579 goto next_master;
12580 }
12581
12582 result = dns_rdataset_first(rdataset);
12583 if (result != ISC_R_SUCCESS) {
12584 dns_zone_log(zone, ISC_LOG_INFO,
12585 "refresh: dns_rdataset_first() failed");
12586 goto next_master;
12587 }
12588
12589 dns_rdataset_current(rdataset, &rdata);
12590 result = dns_rdata_tostruct(&rdata, &soa, NULL);
12591 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12592
12593 serial = soa.serial;
12594 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
12595 unsigned int dbsoacount;
12596 result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount,
12597 &oldserial, NULL, NULL, NULL, NULL,
12598 NULL);
12599 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12600 RUNTIME_CHECK(dbsoacount > 0U);
12601 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
12602 serial, oldserial);
12603 } else
12604 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
12605 serial);
12606
12607 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
12608 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
12609 isc_serial_gt(serial, oldserial)) {
12610 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
12611 &zone->sourceaddr, &now))
12612 {
12613 dns_zone_log(zone, ISC_LOG_INFO,
12614 "refresh: skipping %s as master %s "
12615 "(source %s) is unreachable (cached)",
12616 (zone->type == dns_zone_slave ||
12617 zone->type == dns_zone_mirror ||
12618 zone->type == dns_zone_redirect) ?
12619 "zone transfer" : "NS query",
12620 master, source);
12621 goto next_master;
12622 }
12623 tcp_transfer:
12624 isc_event_free(&event);
12625 dns_request_destroy(&zone->request);
12626 if (zone->type == dns_zone_slave ||
12627 zone->type == dns_zone_mirror ||
12628 zone->type == dns_zone_redirect)
12629 {
12630 do_queue_xfrin = true;
12631 } else {
12632 INSIST(zone->type == dns_zone_stub);
12633 ns_query(zone, rdataset, NULL);
12634 }
12635 if (msg != NULL)
12636 dns_message_destroy(&msg);
12637 } else if (isc_serial_eq(soa.serial, oldserial)) {
12638 isc_time_t expiretime;
12639 uint32_t expire;
12640
12641 /*
12642 * Compute the new expire time based on this response.
12643 */
12644 expire = zone->expire;
12645 get_edns_expire(zone, msg, &expire);
12646 DNS_ZONE_TIME_ADD(&now, expire, &expiretime);
12647
12648 /*
12649 * Has the expire time improved?
12650 */
12651 if (isc_time_compare(&expiretime, &zone->expiretime) > 0) {
12652 zone->expiretime = expiretime;
12653 if (zone->masterfile != NULL)
12654 setmodtime(zone, &expiretime);
12655 }
12656
12657 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
12658 zone->mastersok[zone->curmaster] = true;
12659 goto next_master;
12660 } else {
12661 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
12662 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
12663 "received from master %s < ours (%u)",
12664 soa.serial, master, oldserial);
12665 else
12666 zone_debuglog(zone, me, 1, "ahead");
12667 zone->mastersok[zone->curmaster] = true;
12668 goto next_master;
12669 }
12670 if (msg != NULL)
12671 dns_message_destroy(&msg);
12672 goto detach;
12673
12674 next_master:
12675 if (msg != NULL)
12676 dns_message_destroy(&msg);
12677 isc_event_free(&event);
12678 dns_request_destroy(&zone->request);
12679 /*
12680 * Skip to next failed / untried master.
12681 */
12682 do {
12683 zone->curmaster++;
12684 } while (zone->curmaster < zone->masterscnt &&
12685 zone->mastersok[zone->curmaster]);
12686 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
12687 if (zone->curmaster >= zone->masterscnt) {
12688 bool done = true;
12689 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
12690 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
12691 /*
12692 * Did we get a good answer from all the masters?
12693 */
12694 for (j = 0; j < zone->masterscnt; j++)
12695 if (zone->mastersok[j] == false) {
12696 done = false;
12697 break;
12698 }
12699 } else
12700 done = true;
12701 if (!done) {
12702 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
12703 zone->curmaster = 0;
12704 /*
12705 * Find the next failed master.
12706 */
12707 while (zone->curmaster < zone->masterscnt &&
12708 zone->mastersok[zone->curmaster])
12709 zone->curmaster++;
12710 goto requeue;
12711 }
12712 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
12713 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
12714 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
12715 zone->refreshtime = now;
12716 }
12717 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
12718 zone_settimer(zone, &now);
12719 goto detach;
12720 }
12721
12722 requeue:
12723 queue_soa_query(zone);
12724 goto detach;
12725
12726 same_master:
12727 if (msg != NULL)
12728 dns_message_destroy(&msg);
12729 isc_event_free(&event);
12730 dns_request_destroy(&zone->request);
12731 queue_soa_query(zone);
12732
12733 detach:
12734 UNLOCK_ZONE(zone);
12735 if (do_queue_xfrin)
12736 queue_xfrin(zone);
12737 dns_zone_idetach(&zone);
12738 return;
12739 }
12740
12741 static void
12742 queue_soa_query(dns_zone_t *zone) {
12743 const char me[] = "queue_soa_query";
12744 isc_event_t *e;
12745 dns_zone_t *dummy = NULL;
12746 isc_result_t result;
12747
12748 ENTER;
12749 /*
12750 * Locked by caller
12751 */
12752 REQUIRE(LOCKED_ZONE(zone));
12753
12754 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
12755 cancel_refresh(zone);
12756 return;
12757 }
12758
12759 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
12760 soa_query, zone, sizeof(isc_event_t));
12761 if (e == NULL) {
12762 cancel_refresh(zone);
12763 return;
12764 }
12765
12766 /*
12767 * Attach so that we won't clean up
12768 * until the event is delivered.
12769 */
12770 zone_iattach(zone, &dummy);
12771
12772 e->ev_arg = zone;
12773 e->ev_sender = NULL;
12774 result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e);
12775 if (result != ISC_R_SUCCESS) {
12776 zone_idetach(&dummy);
12777 isc_event_free(&e);
12778 cancel_refresh(zone);
12779 }
12780 }
12781
12782 static inline isc_result_t
12783 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
12784 dns_message_t **messagep)
12785 {
12786 dns_message_t *message = NULL;
12787 dns_name_t *qname = NULL;
12788 dns_rdataset_t *qrdataset = NULL;
12789 isc_result_t result;
12790
12791 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
12792 &message);
12793 if (result != ISC_R_SUCCESS)
12794 goto cleanup;
12795
12796 message->opcode = dns_opcode_query;
12797 message->rdclass = zone->rdclass;
12798
12799 result = dns_message_gettempname(message, &qname);
12800 if (result != ISC_R_SUCCESS)
12801 goto cleanup;
12802
12803 result = dns_message_gettemprdataset(message, &qrdataset);
12804 if (result != ISC_R_SUCCESS)
12805 goto cleanup;
12806
12807 /*
12808 * Make question.
12809 */
12810 dns_name_init(qname, NULL);
12811 dns_name_clone(&zone->origin, qname);
12812 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
12813 ISC_LIST_APPEND(qname->list, qrdataset, link);
12814 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
12815
12816 *messagep = message;
12817 return (ISC_R_SUCCESS);
12818
12819 cleanup:
12820 if (qname != NULL)
12821 dns_message_puttempname(message, &qname);
12822 if (qrdataset != NULL)
12823 dns_message_puttemprdataset(message, &qrdataset);
12824 if (message != NULL)
12825 dns_message_destroy(&message);
12826 return (result);
12827 }
12828
12829 static isc_result_t
12830 add_opt(dns_message_t *message, uint16_t udpsize, bool reqnsid,
12831 bool reqexpire)
12832 {
12833 isc_result_t result;
12834 dns_rdataset_t *rdataset = NULL;
12835 dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
12836 int count = 0;
12837
12838 /* Set EDNS options if applicable */
12839 if (reqnsid) {
12840 INSIST(count < DNS_EDNSOPTIONS);
12841 ednsopts[count].code = DNS_OPT_NSID;
12842 ednsopts[count].length = 0;
12843 ednsopts[count].value = NULL;
12844 count++;
12845 }
12846 if (reqexpire) {
12847 INSIST(count < DNS_EDNSOPTIONS);
12848 ednsopts[count].code = DNS_OPT_EXPIRE;
12849 ednsopts[count].length = 0;
12850 ednsopts[count].value = NULL;
12851 count++;
12852 }
12853 result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0,
12854 ednsopts, count);
12855 if (result != ISC_R_SUCCESS)
12856 return (result);
12857
12858 return (dns_message_setopt(message, rdataset));
12859 }
12860
12861 static void
12862 soa_query(isc_task_t *task, isc_event_t *event) {
12863 const char me[] = "soa_query";
12864 isc_result_t result = ISC_R_FAILURE;
12865 dns_message_t *message = NULL;
12866 dns_zone_t *zone = event->ev_arg;
12867 dns_zone_t *dummy = NULL;
12868 isc_netaddr_t masterip;
12869 dns_tsigkey_t *key = NULL;
12870 uint32_t options;
12871 bool cancel = true;
12872 int timeout;
12873 bool have_xfrsource, have_xfrdscp, reqnsid, reqexpire;
12874 uint16_t udpsize = SEND_BUFFER_SIZE;
12875 isc_dscp_t dscp = -1;
12876
12877 REQUIRE(DNS_ZONE_VALID(zone));
12878
12879 UNUSED(task);
12880
12881 ENTER;
12882
12883 LOCK_ZONE(zone);
12884 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
12885 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
12886 zone->view->requestmgr == NULL) {
12887 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
12888 cancel = false;
12889 goto cleanup;
12890 }
12891
12892 again:
12893 result = create_query(zone, dns_rdatatype_soa, &message);
12894 if (result != ISC_R_SUCCESS)
12895 goto cleanup;
12896
12897 INSIST(zone->masterscnt > 0);
12898 INSIST(zone->curmaster < zone->masterscnt);
12899
12900 zone->masteraddr = zone->masters[zone->curmaster];
12901
12902 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
12903 /*
12904 * First, look for a tsig key in the master statement, then
12905 * try for a server key.
12906 */
12907 if ((zone->masterkeynames != NULL) &&
12908 (zone->masterkeynames[zone->curmaster] != NULL)) {
12909 dns_view_t *view = dns_zone_getview(zone);
12910 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
12911 result = dns_view_gettsig(view, keyname, &key);
12912 if (result != ISC_R_SUCCESS) {
12913 char namebuf[DNS_NAME_FORMATSIZE];
12914 dns_name_format(keyname, namebuf, sizeof(namebuf));
12915 dns_zone_log(zone, ISC_LOG_ERROR,
12916 "unable to find key: %s", namebuf);
12917 goto skip_master;
12918 }
12919 }
12920 if (key == NULL) {
12921 result = dns_view_getpeertsig(zone->view, &masterip, &key);
12922 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
12923 char addrbuf[ISC_NETADDR_FORMATSIZE];
12924 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
12925 dns_zone_log(zone, ISC_LOG_ERROR,
12926 "unable to find TSIG key for %s", addrbuf);
12927 goto skip_master;
12928 }
12929 }
12930
12931 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
12932 DNS_REQUESTOPT_TCP : 0;
12933 have_xfrsource = have_xfrdscp = false;
12934 reqnsid = zone->view->requestnsid;
12935 reqexpire = zone->requestexpire;
12936 if (zone->view->peers != NULL) {
12937 dns_peer_t *peer = NULL;
12938 bool edns, usetcp;
12939 result = dns_peerlist_peerbyaddr(zone->view->peers,
12940 &masterip, &peer);
12941 if (result == ISC_R_SUCCESS) {
12942 result = dns_peer_getsupportedns(peer, &edns);
12943 if (result == ISC_R_SUCCESS && !edns)
12944 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
12945 result = dns_peer_gettransfersource(peer,
12946 &zone->sourceaddr);
12947 if (result == ISC_R_SUCCESS)
12948 have_xfrsource = true;
12949 (void)dns_peer_gettransferdscp(peer, &dscp);
12950 if (dscp != -1)
12951 have_xfrdscp = true;
12952 if (zone->view->resolver != NULL)
12953 udpsize =
12954 dns_resolver_getudpsize(zone->view->resolver);
12955 (void)dns_peer_getudpsize(peer, &udpsize);
12956 (void)dns_peer_getrequestnsid(peer, &reqnsid);
12957 (void)dns_peer_getrequestexpire(peer, &reqexpire);
12958 result = dns_peer_getforcetcp(peer, &usetcp);
12959 if (result == ISC_R_SUCCESS && usetcp)
12960 options |= DNS_REQUESTOPT_TCP;
12961 }
12962 }
12963
12964 switch (isc_sockaddr_pf(&zone->masteraddr)) {
12965 case PF_INET:
12966 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
12967 if (isc_sockaddr_equal(&zone->altxfrsource4,
12968 &zone->xfrsource4))
12969 goto skip_master;
12970 zone->sourceaddr = zone->altxfrsource4;
12971 if (!have_xfrdscp)
12972 dscp = zone->altxfrsource4dscp;
12973 } else if (!have_xfrsource) {
12974 zone->sourceaddr = zone->xfrsource4;
12975 if (!have_xfrdscp)
12976 dscp = zone->xfrsource4dscp;
12977 }
12978 break;
12979 case PF_INET6:
12980 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
12981 if (isc_sockaddr_equal(&zone->altxfrsource6,
12982 &zone->xfrsource6))
12983 goto skip_master;
12984 zone->sourceaddr = zone->altxfrsource6;
12985 if (!have_xfrdscp)
12986 dscp = zone->altxfrsource6dscp;
12987 } else if (!have_xfrsource) {
12988 zone->sourceaddr = zone->xfrsource6;
12989 if (!have_xfrdscp)
12990 dscp = zone->xfrsource6dscp;
12991 }
12992 break;
12993 default:
12994 result = ISC_R_NOTIMPLEMENTED;
12995 goto cleanup;
12996 }
12997
12998 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
12999 result = add_opt(message, udpsize, reqnsid, reqexpire);
13000 if (result != ISC_R_SUCCESS)
13001 zone_debuglog(zone, me, 1,
13002 "unable to add opt record: %s",
13003 dns_result_totext(result));
13004 }
13005
13006 zone_iattach(zone, &dummy);
13007 timeout = 15;
13008 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
13009 timeout = 30;
13010 result = dns_request_createvia(zone->view->requestmgr, message,
13011 &zone->sourceaddr, &zone->masteraddr,
13012 dscp, options, key, timeout * 3,
13013 timeout, 0, zone->task,
13014 refresh_callback, zone, &zone->request);
13015 if (result != ISC_R_SUCCESS) {
13016 zone_idetach(&dummy);
13017 zone_debuglog(zone, me, 1,
13018 "dns_request_createvia4() failed: %s",
13019 dns_result_totext(result));
13020 goto skip_master;
13021 } else {
13022 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
13023 inc_stats(zone, dns_zonestatscounter_soaoutv4);
13024 else
13025 inc_stats(zone, dns_zonestatscounter_soaoutv6);
13026 }
13027 cancel = false;
13028
13029 cleanup:
13030 if (key != NULL)
13031 dns_tsigkey_detach(&key);
13032 if (result != ISC_R_SUCCESS)
13033 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
13034 if (message != NULL)
13035 dns_message_destroy(&message);
13036 if (cancel)
13037 cancel_refresh(zone);
13038 isc_event_free(&event);
13039 UNLOCK_ZONE(zone);
13040 dns_zone_idetach(&zone);
13041 return;
13042
13043 skip_master:
13044 if (key != NULL)
13045 dns_tsigkey_detach(&key);
13046 dns_message_destroy(&message);
13047 /*
13048 * Skip to next failed / untried master.
13049 */
13050 do {
13051 zone->curmaster++;
13052 } while (zone->curmaster < zone->masterscnt &&
13053 zone->mastersok[zone->curmaster]);
13054 if (zone->curmaster < zone->masterscnt)
13055 goto again;
13056 zone->curmaster = 0;
13057 goto cleanup;
13058 }
13059
13060 static void
13061 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
13062 const char me[] = "ns_query";
13063 isc_result_t result;
13064 dns_message_t *message = NULL;
13065 isc_netaddr_t masterip;
13066 dns_tsigkey_t *key = NULL;
13067 dns_dbnode_t *node = NULL;
13068 int timeout;
13069 bool have_xfrsource = false, have_xfrdscp = false;
13070 bool reqnsid;
13071 uint16_t udpsize = SEND_BUFFER_SIZE;
13072 isc_dscp_t dscp = -1;
13073
13074 REQUIRE(DNS_ZONE_VALID(zone));
13075 REQUIRE(LOCKED_ZONE(zone));
13076 REQUIRE((soardataset != NULL && stub == NULL) ||
13077 (soardataset == NULL && stub != NULL));
13078 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
13079
13080 ENTER;
13081
13082 if (stub == NULL) {
13083 stub = isc_mem_get(zone->mctx, sizeof(*stub));
13084 if (stub == NULL)
13085 goto cleanup;
13086 stub->magic = STUB_MAGIC;
13087 stub->mctx = zone->mctx;
13088 stub->zone = NULL;
13089 stub->db = NULL;
13090 stub->version = NULL;
13091
13092 /*
13093 * Attach so that the zone won't disappear from under us.
13094 */
13095 zone_iattach(zone, &stub->zone);
13096
13097 /*
13098 * If a db exists we will update it, otherwise we create a
13099 * new one and attach it to the zone once we have the NS
13100 * RRset and glue.
13101 */
13102 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13103 if (zone->db != NULL) {
13104 dns_db_attach(zone->db, &stub->db);
13105 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13106 } else {
13107 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13108
13109 INSIST(zone->db_argc >= 1);
13110 result = dns_db_create(zone->mctx, zone->db_argv[0],
13111 &zone->origin, dns_dbtype_stub,
13112 zone->rdclass,
13113 zone->db_argc - 1,
13114 zone->db_argv + 1,
13115 &stub->db);
13116 if (result != ISC_R_SUCCESS) {
13117 dns_zone_log(zone, ISC_LOG_ERROR,
13118 "refreshing stub: "
13119 "could not create "
13120 "database: %s",
13121 dns_result_totext(result));
13122 goto cleanup;
13123 }
13124 dns_db_settask(stub->db, zone->task);
13125 }
13126
13127 result = dns_db_newversion(stub->db, &stub->version);
13128 if (result != ISC_R_SUCCESS) {
13129 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
13130 "dns_db_newversion() failed: %s",
13131 dns_result_totext(result));
13132 goto cleanup;
13133 }
13134
13135 /*
13136 * Update SOA record.
13137 */
13138 result = dns_db_findnode(stub->db, &zone->origin, true,
13139 &node);
13140 if (result != ISC_R_SUCCESS) {
13141 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
13142 "dns_db_findnode() failed: %s",
13143 dns_result_totext(result));
13144 goto cleanup;
13145 }
13146
13147 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
13148 soardataset, 0, NULL);
13149 dns_db_detachnode(stub->db, &node);
13150 if (result != ISC_R_SUCCESS) {
13151 dns_zone_log(zone, ISC_LOG_INFO,
13152 "refreshing stub: "
13153 "dns_db_addrdataset() failed: %s",
13154 dns_result_totext(result));
13155 goto cleanup;
13156 }
13157 }
13158
13159 /*
13160 * XXX Optimisation: Create message when zone is setup and reuse.
13161 */
13162 result = create_query(zone, dns_rdatatype_ns, &message);
13163 INSIST(result == ISC_R_SUCCESS);
13164
13165 INSIST(zone->masterscnt > 0);
13166 INSIST(zone->curmaster < zone->masterscnt);
13167 zone->masteraddr = zone->masters[zone->curmaster];
13168
13169 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
13170 /*
13171 * First, look for a tsig key in the master statement, then
13172 * try for a server key.
13173 */
13174 if ((zone->masterkeynames != NULL) &&
13175 (zone->masterkeynames[zone->curmaster] != NULL)) {
13176 dns_view_t *view = dns_zone_getview(zone);
13177 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
13178 result = dns_view_gettsig(view, keyname, &key);
13179 if (result != ISC_R_SUCCESS) {
13180 char namebuf[DNS_NAME_FORMATSIZE];
13181 dns_name_format(keyname, namebuf, sizeof(namebuf));
13182 dns_zone_log(zone, ISC_LOG_ERROR,
13183 "unable to find key: %s", namebuf);
13184 }
13185 }
13186 if (key == NULL)
13187 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
13188
13189 reqnsid = zone->view->requestnsid;
13190 if (zone->view->peers != NULL) {
13191 dns_peer_t *peer = NULL;
13192 bool edns;
13193 result = dns_peerlist_peerbyaddr(zone->view->peers,
13194 &masterip, &peer);
13195 if (result == ISC_R_SUCCESS) {
13196 result = dns_peer_getsupportedns(peer, &edns);
13197 if (result == ISC_R_SUCCESS && !edns)
13198 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
13199 result = dns_peer_gettransfersource(peer,
13200 &zone->sourceaddr);
13201 if (result == ISC_R_SUCCESS)
13202 have_xfrsource = true;
13203 result = dns_peer_gettransferdscp(peer, &dscp);
13204 if (result == ISC_R_SUCCESS && dscp != -1)
13205 have_xfrdscp = true;
13206 if (zone->view->resolver != NULL)
13207 udpsize =
13208 dns_resolver_getudpsize(zone->view->resolver);
13209 (void)dns_peer_getudpsize(peer, &udpsize);
13210 (void)dns_peer_getrequestnsid(peer, &reqnsid);
13211 }
13212
13213 }
13214 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
13215 result = add_opt(message, udpsize, reqnsid, false);
13216 if (result != ISC_R_SUCCESS)
13217 zone_debuglog(zone, me, 1,
13218 "unable to add opt record: %s",
13219 dns_result_totext(result));
13220 }
13221
13222 /*
13223 * Always use TCP so that we shouldn't truncate in additional section.
13224 */
13225 switch (isc_sockaddr_pf(&zone->masteraddr)) {
13226 case PF_INET:
13227 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
13228 zone->sourceaddr = zone->altxfrsource4;
13229 if (!have_xfrdscp)
13230 dscp = zone->altxfrsource4dscp;
13231 } else if (!have_xfrsource) {
13232 zone->sourceaddr = zone->xfrsource4;
13233 if (!have_xfrdscp)
13234 dscp = zone->xfrsource4dscp;
13235 }
13236 break;
13237 case PF_INET6:
13238 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
13239 zone->sourceaddr = zone->altxfrsource6;
13240 if (!have_xfrdscp)
13241 dscp = zone->altxfrsource6dscp;
13242 } else if (!have_xfrsource) {
13243 zone->sourceaddr = zone->xfrsource6;
13244 if (!have_xfrdscp)
13245 dscp = zone->xfrsource6dscp;
13246 }
13247 break;
13248 default:
13249 result = ISC_R_NOTIMPLEMENTED;
13250 POST(result);
13251 goto cleanup;
13252 }
13253 timeout = 15;
13254 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
13255 timeout = 30;
13256 result = dns_request_createvia(zone->view->requestmgr, message,
13257 &zone->sourceaddr, &zone->masteraddr,
13258 dscp, DNS_REQUESTOPT_TCP, key,
13259 timeout * 3, timeout, 0, zone->task,
13260 stub_callback, stub, &zone->request);
13261 if (result != ISC_R_SUCCESS) {
13262 zone_debuglog(zone, me, 1,
13263 "dns_request_createvia() failed: %s",
13264 dns_result_totext(result));
13265 goto cleanup;
13266 }
13267 dns_message_destroy(&message);
13268 goto unlock;
13269
13270 cleanup:
13271 cancel_refresh(zone);
13272 if (stub != NULL) {
13273 stub->magic = 0;
13274 if (stub->version != NULL)
13275 dns_db_closeversion(stub->db, &stub->version,
13276 false);
13277 if (stub->db != NULL)
13278 dns_db_detach(&stub->db);
13279 if (stub->zone != NULL)
13280 zone_idetach(&stub->zone);
13281 isc_mem_put(stub->mctx, stub, sizeof(*stub));
13282 }
13283 if (message != NULL)
13284 dns_message_destroy(&message);
13285 unlock:
13286 if (key != NULL)
13287 dns_tsigkey_detach(&key);
13288 return;
13289 }
13290
13291 /*
13292 * Handle the control event. Note that although this event causes the zone
13293 * to shut down, it is not a shutdown event in the sense of the task library.
13294 */
13295 static void
13296 zone_shutdown(isc_task_t *task, isc_event_t *event) {
13297 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
13298 bool free_needed, linked = false;
13299 dns_zone_t *raw = NULL, *secure = NULL;
13300
13301 UNUSED(task);
13302 REQUIRE(DNS_ZONE_VALID(zone));
13303 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
13304 INSIST(isc_refcount_current(&zone->erefs) == 0);
13305
13306 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
13307
13308 /*
13309 * Stop things being restarted after we cancel them below.
13310 */
13311 LOCK_ZONE(zone);
13312 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
13313 UNLOCK_ZONE(zone);
13314
13315 /*
13316 * If we were waiting for xfrin quota, step out of
13317 * the queue.
13318 * If there's no zone manager, we can't be waiting for the
13319 * xfrin quota
13320 */
13321 if (zone->zmgr != NULL) {
13322 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
13323 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
13324 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
13325 statelink);
13326 linked = true;
13327 zone->statelist = NULL;
13328 }
13329 if (zone->statelist == &zone->zmgr->xfrin_in_progress) {
13330 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone,
13331 statelink);
13332 zone->statelist = NULL;
13333 zmgr_resume_xfrs(zone->zmgr, false);
13334 }
13335 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
13336 }
13337
13338 /*
13339 * In task context, no locking required. See zone_xfrdone().
13340 */
13341 if (zone->xfr != NULL)
13342 dns_xfrin_shutdown(zone->xfr);
13343
13344 /* Safe to release the zone now */
13345 if (zone->zmgr != NULL)
13346 dns_zonemgr_releasezone(zone->zmgr, zone);
13347
13348 LOCK_ZONE(zone);
13349 INSIST(zone != zone->raw);
13350 if (linked) {
13351 INSIST(zone->irefs > 0);
13352 zone->irefs--;
13353 }
13354 if (zone->request != NULL) {
13355 dns_request_cancel(zone->request);
13356 }
13357
13358 if (zone->readio != NULL)
13359 zonemgr_cancelio(zone->readio);
13360
13361 if (zone->lctx != NULL)
13362 dns_loadctx_cancel(zone->lctx);
13363
13364 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
13365 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
13366 if (zone->writeio != NULL)
13367 zonemgr_cancelio(zone->writeio);
13368
13369 if (zone->dctx != NULL)
13370 dns_dumpctx_cancel(zone->dctx);
13371 }
13372
13373 notify_cancel(zone);
13374
13375 forward_cancel(zone);
13376
13377 if (zone->timer != NULL) {
13378 isc_timer_detach(&zone->timer);
13379 INSIST(zone->irefs > 0);
13380 zone->irefs--;
13381 }
13382
13383 /*
13384 * We have now canceled everything set the flag to allow exit_check()
13385 * to succeed. We must not unlock between setting this flag and
13386 * calling exit_check().
13387 */
13388 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
13389 free_needed = exit_check(zone);
13390 if (inline_secure(zone)) {
13391 raw = zone->raw;
13392 zone->raw = NULL;
13393 }
13394 if (inline_raw(zone)) {
13395 secure = zone->secure;
13396 zone->secure = NULL;
13397 }
13398 UNLOCK_ZONE(zone);
13399 if (raw != NULL)
13400 dns_zone_detach(&raw);
13401 if (secure != NULL)
13402 dns_zone_idetach(&secure);
13403 if (free_needed)
13404 zone_free(zone);
13405 }
13406
13407 static void
13408 zone_timer(isc_task_t *task, isc_event_t *event) {
13409 const char me[] = "zone_timer";
13410 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
13411
13412 UNUSED(task);
13413 REQUIRE(DNS_ZONE_VALID(zone));
13414
13415 ENTER;
13416
13417 zone_maintenance(zone);
13418
13419 isc_event_free(&event);
13420 }
13421
13422 static void
13423 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
13424 const char me[] = "zone_settimer";
13425 isc_time_t next;
13426 isc_result_t result;
13427
13428 REQUIRE(DNS_ZONE_VALID(zone));
13429 ENTER;
13430
13431 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
13432 return;
13433
13434 isc_time_settoepoch(&next);
13435
13436 switch (zone->type) {
13437 case dns_zone_redirect:
13438 if (zone->masters != NULL)
13439 goto treat_as_slave;
13440 /* FALLTHROUGH */
13441
13442 case dns_zone_master:
13443 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
13444 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
13445 next = zone->notifytime;
13446 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
13447 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
13448 INSIST(!isc_time_isepoch(&zone->dumptime));
13449 if (isc_time_isepoch(&next) ||
13450 isc_time_compare(&zone->dumptime, &next) < 0)
13451 next = zone->dumptime;
13452 }
13453 if (zone->type == dns_zone_redirect)
13454 break;
13455 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
13456 !isc_time_isepoch(&zone->refreshkeytime)) {
13457 if (isc_time_isepoch(&next) ||
13458 isc_time_compare(&zone->refreshkeytime, &next) < 0)
13459 next = zone->refreshkeytime;
13460 }
13461 if (!isc_time_isepoch(&zone->resigntime)) {
13462 if (isc_time_isepoch(&next) ||
13463 isc_time_compare(&zone->resigntime, &next) < 0)
13464 next = zone->resigntime;
13465 }
13466 if (!isc_time_isepoch(&zone->keywarntime)) {
13467 if (isc_time_isepoch(&next) ||
13468 isc_time_compare(&zone->keywarntime, &next) < 0)
13469 next = zone->keywarntime;
13470 }
13471 if (!isc_time_isepoch(&zone->signingtime)) {
13472 if (isc_time_isepoch(&next) ||
13473 isc_time_compare(&zone->signingtime, &next) < 0)
13474 next = zone->signingtime;
13475 }
13476 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
13477 if (isc_time_isepoch(&next) ||
13478 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
13479 next = zone->nsec3chaintime;
13480 }
13481 break;
13482
13483 case dns_zone_slave:
13484 case dns_zone_mirror:
13485 treat_as_slave:
13486 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
13487 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
13488 next = zone->notifytime;
13489 /* FALLTHROUGH */
13490
13491 case dns_zone_stub:
13492 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
13493 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
13494 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
13495 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) &&
13496 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) &&
13497 !isc_time_isepoch(&zone->refreshtime) &&
13498 (isc_time_isepoch(&next) ||
13499 isc_time_compare(&zone->refreshtime, &next) < 0))
13500 next = zone->refreshtime;
13501 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
13502 !isc_time_isepoch(&zone->expiretime)) {
13503 if (isc_time_isepoch(&next) ||
13504 isc_time_compare(&zone->expiretime, &next) < 0)
13505 next = zone->expiretime;
13506 }
13507 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
13508 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
13509 INSIST(!isc_time_isepoch(&zone->dumptime));
13510 if (isc_time_isepoch(&next) ||
13511 isc_time_compare(&zone->dumptime, &next) < 0)
13512 next = zone->dumptime;
13513 }
13514 break;
13515
13516 case dns_zone_key:
13517 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
13518 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
13519 INSIST(!isc_time_isepoch(&zone->dumptime));
13520 if (isc_time_isepoch(&next) ||
13521 isc_time_compare(&zone->dumptime, &next) < 0)
13522 next = zone->dumptime;
13523 }
13524 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
13525 if (isc_time_isepoch(&next) ||
13526 (!isc_time_isepoch(&zone->refreshkeytime) &&
13527 isc_time_compare(&zone->refreshkeytime, &next) < 0))
13528 next = zone->refreshkeytime;
13529 }
13530 break;
13531
13532 default:
13533 break;
13534 }
13535
13536 if (isc_time_isepoch(&next)) {
13537 zone_debuglog(zone, me, 10, "settimer inactive");
13538 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
13539 NULL, NULL, true);
13540 if (result != ISC_R_SUCCESS)
13541 dns_zone_log(zone, ISC_LOG_ERROR,
13542 "could not deactivate zone timer: %s",
13543 isc_result_totext(result));
13544 } else {
13545 if (isc_time_compare(&next, now) <= 0)
13546 next = *now;
13547 result = isc_timer_reset(zone->timer, isc_timertype_once,
13548 &next, NULL, true);
13549 if (result != ISC_R_SUCCESS)
13550 dns_zone_log(zone, ISC_LOG_ERROR,
13551 "could not reset zone timer: %s",
13552 isc_result_totext(result));
13553 }
13554 }
13555
13556 static void
13557 cancel_refresh(dns_zone_t *zone) {
13558 const char me[] = "cancel_refresh";
13559 isc_time_t now;
13560
13561 /*
13562 * 'zone' locked by caller.
13563 */
13564
13565 REQUIRE(DNS_ZONE_VALID(zone));
13566 REQUIRE(LOCKED_ZONE(zone));
13567
13568 ENTER;
13569
13570 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
13571 TIME_NOW(&now);
13572 zone_settimer(zone, &now);
13573 }
13574
13575 static isc_result_t
13576 notify_createmessage(dns_zone_t *zone, unsigned int flags,
13577 dns_message_t **messagep)
13578 {
13579 dns_db_t *zonedb = NULL;
13580 dns_dbnode_t *node = NULL;
13581 dns_dbversion_t *version = NULL;
13582 dns_message_t *message = NULL;
13583 dns_rdataset_t rdataset;
13584 dns_rdata_t rdata = DNS_RDATA_INIT;
13585
13586 dns_name_t *tempname = NULL;
13587 dns_rdata_t *temprdata = NULL;
13588 dns_rdatalist_t *temprdatalist = NULL;
13589 dns_rdataset_t *temprdataset = NULL;
13590
13591 isc_result_t result;
13592 isc_region_t r;
13593 isc_buffer_t *b = NULL;
13594
13595 REQUIRE(DNS_ZONE_VALID(zone));
13596 REQUIRE(messagep != NULL && *messagep == NULL);
13597
13598 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
13599 &message);
13600 if (result != ISC_R_SUCCESS)
13601 return (result);
13602
13603 message->opcode = dns_opcode_notify;
13604 message->flags |= DNS_MESSAGEFLAG_AA;
13605 message->rdclass = zone->rdclass;
13606
13607 result = dns_message_gettempname(message, &tempname);
13608 if (result != ISC_R_SUCCESS)
13609 goto cleanup;
13610
13611 result = dns_message_gettemprdataset(message, &temprdataset);
13612 if (result != ISC_R_SUCCESS)
13613 goto cleanup;
13614
13615 /*
13616 * Make question.
13617 */
13618 dns_name_init(tempname, NULL);
13619 dns_name_clone(&zone->origin, tempname);
13620 dns_rdataset_makequestion(temprdataset, zone->rdclass,
13621 dns_rdatatype_soa);
13622 ISC_LIST_APPEND(tempname->list, temprdataset, link);
13623 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
13624 tempname = NULL;
13625 temprdataset = NULL;
13626
13627 if ((flags & DNS_NOTIFY_NOSOA) != 0)
13628 goto done;
13629
13630 result = dns_message_gettempname(message, &tempname);
13631 if (result != ISC_R_SUCCESS)
13632 goto soa_cleanup;
13633 result = dns_message_gettemprdata(message, &temprdata);
13634 if (result != ISC_R_SUCCESS)
13635 goto soa_cleanup;
13636 result = dns_message_gettemprdataset(message, &temprdataset);
13637 if (result != ISC_R_SUCCESS)
13638 goto soa_cleanup;
13639 result = dns_message_gettemprdatalist(message, &temprdatalist);
13640 if (result != ISC_R_SUCCESS)
13641 goto soa_cleanup;
13642
13643 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
13644 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
13645 dns_db_attach(zone->db, &zonedb);
13646 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
13647
13648 dns_name_init(tempname, NULL);
13649 dns_name_clone(&zone->origin, tempname);
13650 dns_db_currentversion(zonedb, &version);
13651 result = dns_db_findnode(zonedb, tempname, false, &node);
13652 if (result != ISC_R_SUCCESS)
13653 goto soa_cleanup;
13654
13655 dns_rdataset_init(&rdataset);
13656 result = dns_db_findrdataset(zonedb, node, version,
13657 dns_rdatatype_soa,
13658 dns_rdatatype_none, 0, &rdataset,
13659 NULL);
13660 if (result != ISC_R_SUCCESS)
13661 goto soa_cleanup;
13662 result = dns_rdataset_first(&rdataset);
13663 if (result != ISC_R_SUCCESS)
13664 goto soa_cleanup;
13665 dns_rdataset_current(&rdataset, &rdata);
13666 dns_rdata_toregion(&rdata, &r);
13667 result = isc_buffer_allocate(zone->mctx, &b, r.length);
13668 if (result != ISC_R_SUCCESS)
13669 goto soa_cleanup;
13670 isc_buffer_putmem(b, r.base, r.length);
13671 isc_buffer_usedregion(b, &r);
13672 dns_rdata_init(temprdata);
13673 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
13674 dns_message_takebuffer(message, &b);
13675 result = dns_rdataset_next(&rdataset);
13676 dns_rdataset_disassociate(&rdataset);
13677 if (result != ISC_R_NOMORE)
13678 goto soa_cleanup;
13679 temprdatalist->rdclass = rdata.rdclass;
13680 temprdatalist->type = rdata.type;
13681 temprdatalist->ttl = rdataset.ttl;
13682 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
13683
13684 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
13685 if (result != ISC_R_SUCCESS)
13686 goto soa_cleanup;
13687
13688 ISC_LIST_APPEND(tempname->list, temprdataset, link);
13689 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
13690 temprdatalist = NULL;
13691 temprdataset = NULL;
13692 temprdata = NULL;
13693 tempname = NULL;
13694
13695 soa_cleanup:
13696 if (node != NULL)
13697 dns_db_detachnode(zonedb, &node);
13698 if (version != NULL)
13699 dns_db_closeversion(zonedb, &version, false);
13700 if (zonedb != NULL)
13701 dns_db_detach(&zonedb);
13702 if (tempname != NULL)
13703 dns_message_puttempname(message, &tempname);
13704 if (temprdata != NULL)
13705 dns_message_puttemprdata(message, &temprdata);
13706 if (temprdataset != NULL)
13707 dns_message_puttemprdataset(message, &temprdataset);
13708 if (temprdatalist != NULL)
13709 dns_message_puttemprdatalist(message, &temprdatalist);
13710
13711 done:
13712 *messagep = message;
13713 return (ISC_R_SUCCESS);
13714
13715 cleanup:
13716 if (tempname != NULL)
13717 dns_message_puttempname(message, &tempname);
13718 if (temprdataset != NULL)
13719 dns_message_puttemprdataset(message, &temprdataset);
13720 dns_message_destroy(&message);
13721 return (result);
13722 }
13723
13724 isc_result_t
13725 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
13726 isc_sockaddr_t *to, dns_message_t *msg)
13727 {
13728 unsigned int i;
13729 dns_rdata_soa_t soa;
13730 dns_rdataset_t *rdataset = NULL;
13731 dns_rdata_t rdata = DNS_RDATA_INIT;
13732 isc_result_t result;
13733 char fromtext[ISC_SOCKADDR_FORMATSIZE];
13734 int match = 0;
13735 isc_netaddr_t netaddr;
13736 uint32_t serial = 0;
13737 bool have_serial = false;
13738 dns_tsigkey_t *tsigkey;
13739 dns_name_t *tsig;
13740
13741 REQUIRE(DNS_ZONE_VALID(zone));
13742
13743 /*
13744 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
13745 * ROLLOVER.
13746 *
13747 * SOA: RFC1996
13748 * Check that 'from' is a valid notify source, (zone->masters).
13749 * Return DNS_R_REFUSED if not.
13750 *
13751 * If the notify message contains a serial number check it
13752 * against the zones serial and return if <= current serial
13753 *
13754 * If a refresh check is progress, if so just record the
13755 * fact we received a NOTIFY and from where and return.
13756 * We will perform a new refresh check when the current one
13757 * completes. Return ISC_R_SUCCESS.
13758 *
13759 * Otherwise initiate a refresh check using 'from' as the
13760 * first address to check. Return ISC_R_SUCCESS.
13761 */
13762
13763 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
13764
13765 /*
13766 * Notify messages are processed by the raw zone.
13767 */
13768 LOCK_ZONE(zone);
13769 INSIST(zone != zone->raw);
13770 if (inline_secure(zone)) {
13771 result = dns_zone_notifyreceive(zone->raw, from, to, msg);
13772 UNLOCK_ZONE(zone);
13773 return (result);
13774 }
13775 /*
13776 * We only handle NOTIFY (SOA) at the present.
13777 */
13778 if (isc_sockaddr_pf(from) == PF_INET)
13779 inc_stats(zone, dns_zonestatscounter_notifyinv4);
13780 else
13781 inc_stats(zone, dns_zonestatscounter_notifyinv6);
13782 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
13783 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
13784 dns_rdatatype_soa, dns_rdatatype_none,
13785 NULL, NULL) != ISC_R_SUCCESS) {
13786 UNLOCK_ZONE(zone);
13787 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
13788 dns_zone_log(zone, ISC_LOG_NOTICE,
13789 "NOTIFY with no "
13790 "question section from: %s", fromtext);
13791 return (DNS_R_FORMERR);
13792 }
13793 dns_zone_log(zone, ISC_LOG_NOTICE,
13794 "NOTIFY zone does not match");
13795 return (DNS_R_NOTIMP);
13796 }
13797
13798 /*
13799 * If we are a master zone just succeed.
13800 */
13801 if (zone->type == dns_zone_master) {
13802 UNLOCK_ZONE(zone);
13803 return (ISC_R_SUCCESS);
13804 }
13805
13806 isc_netaddr_fromsockaddr(&netaddr, from);
13807 for (i = 0; i < zone->masterscnt; i++) {
13808 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
13809 break;
13810 if (zone->view->aclenv.match_mapped &&
13811 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
13812 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
13813 isc_netaddr_t na1, na2;
13814 isc_netaddr_fromv4mapped(&na1, &netaddr);
13815 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
13816 if (isc_netaddr_equal(&na1, &na2))
13817 break;
13818 }
13819 }
13820
13821 /*
13822 * Accept notify requests from non masters if they are on
13823 * 'zone->notify_acl'.
13824 */
13825 tsigkey = dns_message_gettsigkey(msg);
13826 tsig = dns_tsigkey_identity(tsigkey);
13827 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
13828 (dns_acl_match(&netaddr, tsig, zone->notify_acl,
13829 &zone->view->aclenv, &match,
13830 NULL) == ISC_R_SUCCESS) &&
13831 match > 0)
13832 {
13833 /* Accept notify. */
13834 } else if (i >= zone->masterscnt) {
13835 UNLOCK_ZONE(zone);
13836 dns_zone_log(zone, ISC_LOG_INFO,
13837 "refused notify from non-master: %s", fromtext);
13838 inc_stats(zone, dns_zonestatscounter_notifyrej);
13839 return (DNS_R_REFUSED);
13840 }
13841
13842 /*
13843 * If the zone is loaded and there are answers check the serial
13844 * to see if we need to do a refresh. Do not worry about this
13845 * check if we are a dialup zone as we use the notify request
13846 * to trigger a refresh check.
13847 */
13848 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
13849 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
13850 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
13851 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
13852 &zone->origin,
13853 dns_rdatatype_soa,
13854 dns_rdatatype_none, NULL,
13855 &rdataset);
13856 if (result == ISC_R_SUCCESS)
13857 result = dns_rdataset_first(rdataset);
13858 if (result == ISC_R_SUCCESS) {
13859 uint32_t oldserial;
13860 unsigned int soacount;
13861
13862 dns_rdataset_current(rdataset, &rdata);
13863 result = dns_rdata_tostruct(&rdata, &soa, NULL);
13864 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13865 serial = soa.serial;
13866 have_serial = true;
13867 /*
13868 * The following should safely be performed without DB
13869 * lock and succeed in this context.
13870 */
13871 result = zone_get_from_db(zone, zone->db, NULL,
13872 &soacount, &oldserial, NULL,
13873 NULL, NULL, NULL, NULL);
13874 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13875 RUNTIME_CHECK(soacount > 0U);
13876 if (isc_serial_le(serial, oldserial)) {
13877 dns_zone_log(zone,
13878 ISC_LOG_INFO,
13879 "notify from %s: "
13880 "zone is up to date",
13881 fromtext);
13882 UNLOCK_ZONE(zone);
13883 return (ISC_R_SUCCESS);
13884 }
13885 }
13886 }
13887
13888 /*
13889 * If we got this far and there was a refresh in progress just
13890 * let it complete. Record where we got the notify from so we
13891 * can perform a refresh check when the current one completes
13892 */
13893 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
13894 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
13895 zone->notifyfrom = *from;
13896 UNLOCK_ZONE(zone);
13897 if (have_serial)
13898 dns_zone_log(zone, ISC_LOG_INFO,
13899 "notify from %s: serial %u: refresh in "
13900 "progress, refresh check queued",
13901 fromtext, serial);
13902 else
13903 dns_zone_log(zone, ISC_LOG_INFO,
13904 "notify from %s: refresh in progress, "
13905 "refresh check queued", fromtext);
13906 return (ISC_R_SUCCESS);
13907 }
13908 if (have_serial)
13909 dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: serial %u",
13910 fromtext, serial);
13911 else
13912 dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: no serial",
13913 fromtext);
13914 zone->notifyfrom = *from;
13915 UNLOCK_ZONE(zone);
13916
13917 if (to != NULL) {
13918 dns_zonemgr_unreachabledel(zone->zmgr, from, to);
13919 }
13920 dns_zone_refresh(zone);
13921 return (ISC_R_SUCCESS);
13922 }
13923
13924 void
13925 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
13926
13927 REQUIRE(DNS_ZONE_VALID(zone));
13928
13929 LOCK_ZONE(zone);
13930 if (zone->notify_acl != NULL)
13931 dns_acl_detach(&zone->notify_acl);
13932 dns_acl_attach(acl, &zone->notify_acl);
13933 UNLOCK_ZONE(zone);
13934 }
13935
13936 void
13937 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
13938
13939 REQUIRE(DNS_ZONE_VALID(zone));
13940
13941 LOCK_ZONE(zone);
13942 if (zone->query_acl != NULL)
13943 dns_acl_detach(&zone->query_acl);
13944 dns_acl_attach(acl, &zone->query_acl);
13945 UNLOCK_ZONE(zone);
13946 }
13947
13948 void
13949 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
13950
13951 REQUIRE(DNS_ZONE_VALID(zone));
13952
13953 LOCK_ZONE(zone);
13954 if (zone->queryon_acl != NULL)
13955 dns_acl_detach(&zone->queryon_acl);
13956 dns_acl_attach(acl, &zone->queryon_acl);
13957 UNLOCK_ZONE(zone);
13958 }
13959
13960 void
13961 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
13962
13963 REQUIRE(DNS_ZONE_VALID(zone));
13964
13965 LOCK_ZONE(zone);
13966 if (zone->update_acl != NULL)
13967 dns_acl_detach(&zone->update_acl);
13968 dns_acl_attach(acl, &zone->update_acl);
13969 UNLOCK_ZONE(zone);
13970 }
13971
13972 void
13973 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
13974
13975 REQUIRE(DNS_ZONE_VALID(zone));
13976
13977 LOCK_ZONE(zone);
13978 if (zone->forward_acl != NULL)
13979 dns_acl_detach(&zone->forward_acl);
13980 dns_acl_attach(acl, &zone->forward_acl);
13981 UNLOCK_ZONE(zone);
13982 }
13983
13984 void
13985 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
13986
13987 REQUIRE(DNS_ZONE_VALID(zone));
13988
13989 LOCK_ZONE(zone);
13990 if (zone->xfr_acl != NULL)
13991 dns_acl_detach(&zone->xfr_acl);
13992 dns_acl_attach(acl, &zone->xfr_acl);
13993 UNLOCK_ZONE(zone);
13994 }
13995
13996 dns_acl_t *
13997 dns_zone_getnotifyacl(dns_zone_t *zone) {
13998
13999 REQUIRE(DNS_ZONE_VALID(zone));
14000
14001 return (zone->notify_acl);
14002 }
14003
14004 dns_acl_t *
14005 dns_zone_getqueryacl(dns_zone_t *zone) {
14006
14007 REQUIRE(DNS_ZONE_VALID(zone));
14008
14009 return (zone->query_acl);
14010 }
14011
14012 dns_acl_t *
14013 dns_zone_getqueryonacl(dns_zone_t *zone) {
14014
14015 REQUIRE(DNS_ZONE_VALID(zone));
14016
14017 return (zone->queryon_acl);
14018 }
14019
14020 dns_acl_t *
14021 dns_zone_getupdateacl(dns_zone_t *zone) {
14022
14023 REQUIRE(DNS_ZONE_VALID(zone));
14024
14025 return (zone->update_acl);
14026 }
14027
14028 dns_acl_t *
14029 dns_zone_getforwardacl(dns_zone_t *zone) {
14030
14031 REQUIRE(DNS_ZONE_VALID(zone));
14032
14033 return (zone->forward_acl);
14034 }
14035
14036 dns_acl_t *
14037 dns_zone_getxfracl(dns_zone_t *zone) {
14038
14039 REQUIRE(DNS_ZONE_VALID(zone));
14040
14041 return (zone->xfr_acl);
14042 }
14043
14044 void
14045 dns_zone_clearupdateacl(dns_zone_t *zone) {
14046
14047 REQUIRE(DNS_ZONE_VALID(zone));
14048
14049 LOCK_ZONE(zone);
14050 if (zone->update_acl != NULL)
14051 dns_acl_detach(&zone->update_acl);
14052 UNLOCK_ZONE(zone);
14053 }
14054
14055 void
14056 dns_zone_clearforwardacl(dns_zone_t *zone) {
14057
14058 REQUIRE(DNS_ZONE_VALID(zone));
14059
14060 LOCK_ZONE(zone);
14061 if (zone->forward_acl != NULL)
14062 dns_acl_detach(&zone->forward_acl);
14063 UNLOCK_ZONE(zone);
14064 }
14065
14066 void
14067 dns_zone_clearnotifyacl(dns_zone_t *zone) {
14068
14069 REQUIRE(DNS_ZONE_VALID(zone));
14070
14071 LOCK_ZONE(zone);
14072 if (zone->notify_acl != NULL)
14073 dns_acl_detach(&zone->notify_acl);
14074 UNLOCK_ZONE(zone);
14075 }
14076
14077 void
14078 dns_zone_clearqueryacl(dns_zone_t *zone) {
14079
14080 REQUIRE(DNS_ZONE_VALID(zone));
14081
14082 LOCK_ZONE(zone);
14083 if (zone->query_acl != NULL)
14084 dns_acl_detach(&zone->query_acl);
14085 UNLOCK_ZONE(zone);
14086 }
14087
14088 void
14089 dns_zone_clearqueryonacl(dns_zone_t *zone) {
14090
14091 REQUIRE(DNS_ZONE_VALID(zone));
14092
14093 LOCK_ZONE(zone);
14094 if (zone->queryon_acl != NULL)
14095 dns_acl_detach(&zone->queryon_acl);
14096 UNLOCK_ZONE(zone);
14097 }
14098
14099 void
14100 dns_zone_clearxfracl(dns_zone_t *zone) {
14101
14102 REQUIRE(DNS_ZONE_VALID(zone));
14103
14104 LOCK_ZONE(zone);
14105 if (zone->xfr_acl != NULL)
14106 dns_acl_detach(&zone->xfr_acl);
14107 UNLOCK_ZONE(zone);
14108 }
14109
14110 bool
14111 dns_zone_getupdatedisabled(dns_zone_t *zone) {
14112 REQUIRE(DNS_ZONE_VALID(zone));
14113 return (zone->update_disabled);
14114
14115 }
14116
14117 void
14118 dns_zone_setupdatedisabled(dns_zone_t *zone, bool state) {
14119 REQUIRE(DNS_ZONE_VALID(zone));
14120 zone->update_disabled = state;
14121 }
14122
14123 bool
14124 dns_zone_getzeronosoattl(dns_zone_t *zone) {
14125 REQUIRE(DNS_ZONE_VALID(zone));
14126 return (zone->zero_no_soa_ttl);
14127
14128 }
14129
14130 void
14131 dns_zone_setzeronosoattl(dns_zone_t *zone, bool state) {
14132 REQUIRE(DNS_ZONE_VALID(zone));
14133 zone->zero_no_soa_ttl = state;
14134 }
14135
14136 void
14137 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
14138 REQUIRE(DNS_ZONE_VALID(zone));
14139
14140 zone->check_names = severity;
14141 }
14142
14143 dns_severity_t
14144 dns_zone_getchecknames(dns_zone_t *zone) {
14145 REQUIRE(DNS_ZONE_VALID(zone));
14146
14147 return (zone->check_names);
14148 }
14149
14150 void
14151 dns_zone_setjournalsize(dns_zone_t *zone, int32_t size) {
14152 REQUIRE(DNS_ZONE_VALID(zone));
14153
14154 zone->journalsize = size;
14155 }
14156
14157 int32_t
14158 dns_zone_getjournalsize(dns_zone_t *zone) {
14159 REQUIRE(DNS_ZONE_VALID(zone));
14160
14161 return (zone->journalsize);
14162 }
14163
14164 static void
14165 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
14166 isc_result_t result = ISC_R_FAILURE;
14167 isc_buffer_t buffer;
14168
14169 REQUIRE(buf != NULL);
14170 REQUIRE(length > 1U);
14171
14172 /*
14173 * Leave space for terminating '\0'.
14174 */
14175 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
14176 if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
14177 if (dns_name_dynamic(&zone->origin))
14178 result = dns_name_totext(&zone->origin, true, &buffer);
14179 if (result != ISC_R_SUCCESS &&
14180 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
14181 isc_buffer_putstr(&buffer, "<UNKNOWN>");
14182
14183 if (isc_buffer_availablelength(&buffer) > 0)
14184 isc_buffer_putstr(&buffer, "/");
14185 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
14186 }
14187
14188 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
14189 strcmp(zone->view->name, "_default") != 0 &&
14190 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
14191 isc_buffer_putstr(&buffer, "/");
14192 isc_buffer_putstr(&buffer, zone->view->name);
14193 }
14194 if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer))
14195 isc_buffer_putstr(&buffer, " (signed)");
14196 if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer))
14197 isc_buffer_putstr(&buffer, " (unsigned)");
14198
14199 buf[isc_buffer_usedlength(&buffer)] = '\0';
14200 }
14201
14202 static void
14203 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
14204 isc_result_t result = ISC_R_FAILURE;
14205 isc_buffer_t buffer;
14206
14207 REQUIRE(buf != NULL);
14208 REQUIRE(length > 1U);
14209
14210 /*
14211 * Leave space for terminating '\0'.
14212 */
14213 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
14214 if (dns_name_dynamic(&zone->origin))
14215 result = dns_name_totext(&zone->origin, true, &buffer);
14216 if (result != ISC_R_SUCCESS &&
14217 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
14218 isc_buffer_putstr(&buffer, "<UNKNOWN>");
14219
14220 buf[isc_buffer_usedlength(&buffer)] = '\0';
14221 }
14222
14223 static void
14224 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
14225 isc_buffer_t buffer;
14226
14227 REQUIRE(buf != NULL);
14228 REQUIRE(length > 1U);
14229
14230 /*
14231 * Leave space for terminating '\0'.
14232 */
14233 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
14234 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
14235
14236 buf[isc_buffer_usedlength(&buffer)] = '\0';
14237 }
14238
14239 static void
14240 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
14241 isc_buffer_t buffer;
14242
14243 REQUIRE(buf != NULL);
14244 REQUIRE(length > 1U);
14245
14246
14247 /*
14248 * Leave space for terminating '\0'.
14249 */
14250 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
14251
14252 if (zone->view == NULL) {
14253 isc_buffer_putstr(&buffer, "_none");
14254 } else if (strlen(zone->view->name)
14255 < isc_buffer_availablelength(&buffer)) {
14256 isc_buffer_putstr(&buffer, zone->view->name);
14257 } else {
14258 isc_buffer_putstr(&buffer, "_toolong");
14259 }
14260
14261 buf[isc_buffer_usedlength(&buffer)] = '\0';
14262 }
14263
14264 void
14265 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
14266 REQUIRE(DNS_ZONE_VALID(zone));
14267 REQUIRE(buf != NULL);
14268 zone_namerd_tostr(zone, buf, length);
14269 }
14270
14271 void
14272 dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) {
14273 REQUIRE(DNS_ZONE_VALID(zone));
14274 REQUIRE(buf != NULL);
14275 zone_name_tostr(zone, buf, length);
14276 }
14277
14278 void
14279 dns_zone_logv(dns_zone_t *zone, isc_logcategory_t *category, int level,
14280 const char *prefix, const char *fmt, va_list ap)
14281 {
14282 char message[4096];
14283 const char *zstr;
14284
14285 if (!isc_log_wouldlog(dns_lctx, level)) {
14286 return;
14287 }
14288
14289 vsnprintf(message, sizeof(message), fmt, ap);
14290
14291 switch (zone->type) {
14292 case dns_zone_key:
14293 zstr = "managed-keys-zone";
14294 break;
14295 case dns_zone_redirect:
14296 zstr = "redirect-zone";
14297 break;
14298 default:
14299 zstr = "zone ";
14300 }
14301
14302 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, level,
14303 "%s%s%s%s: %s",
14304 (prefix != NULL ? prefix : ""),
14305 (prefix != NULL ? ": " : ""),
14306 zstr, zone->strnamerd, message);
14307 }
14308
14309 static void
14310 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
14311 va_list ap;
14312
14313 va_start(ap, fmt);
14314 dns_zone_logv(zone, DNS_LOGCATEGORY_NOTIFY, level, NULL, fmt, ap);
14315 va_end(ap);
14316 }
14317
14318 void
14319 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
14320 int level, const char *fmt, ...)
14321 {
14322 va_list ap;
14323
14324 va_start(ap, fmt);
14325 dns_zone_logv(zone, category, level, NULL, fmt, ap);
14326 va_end(ap);
14327 }
14328
14329 void
14330 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
14331 va_list ap;
14332
14333 va_start(ap, fmt);
14334 dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, NULL, fmt, ap);
14335 va_end(ap);
14336 }
14337
14338 static void
14339 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
14340 const char *fmt, ...)
14341 {
14342 int level = ISC_LOG_DEBUG(debuglevel);
14343 va_list ap;
14344
14345 va_start(ap, fmt);
14346 dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, me, fmt, ap);
14347 va_end(ap);
14348 }
14349
14350 static void
14351 dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...) {
14352 va_list ap;
14353
14354 va_start(ap, fmt);
14355 dns_zone_logv(zone, DNS_LOGCATEGORY_DNSSEC, level, NULL, fmt, ap);
14356 va_end(ap);
14357 }
14358
14359 static int
14360 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
14361 {
14362 isc_result_t result;
14363 dns_name_t *name;
14364 dns_rdataset_t *curr;
14365 int count = 0;
14366
14367 result = dns_message_firstname(msg, section);
14368 while (result == ISC_R_SUCCESS) {
14369 name = NULL;
14370 dns_message_currentname(msg, section, &name);
14371
14372 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
14373 curr = ISC_LIST_PREV(curr, link)) {
14374 if (curr->type == type)
14375 count++;
14376 }
14377 result = dns_message_nextname(msg, section);
14378 }
14379
14380 return (count);
14381 }
14382
14383 void
14384 dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin) {
14385 REQUIRE(DNS_ZONE_VALID(zone));
14386
14387 zone->maxxfrin = maxxfrin;
14388 }
14389
14390 uint32_t
14391 dns_zone_getmaxxfrin(dns_zone_t *zone) {
14392 REQUIRE(DNS_ZONE_VALID(zone));
14393
14394 return (zone->maxxfrin);
14395 }
14396
14397 void
14398 dns_zone_setmaxxfrout(dns_zone_t *zone, uint32_t maxxfrout) {
14399 REQUIRE(DNS_ZONE_VALID(zone));
14400 zone->maxxfrout = maxxfrout;
14401 }
14402
14403 uint32_t
14404 dns_zone_getmaxxfrout(dns_zone_t *zone) {
14405 REQUIRE(DNS_ZONE_VALID(zone));
14406
14407 return (zone->maxxfrout);
14408 }
14409
14410 dns_zonetype_t
14411 dns_zone_gettype(dns_zone_t *zone) {
14412 REQUIRE(DNS_ZONE_VALID(zone));
14413
14414 return (zone->type);
14415 }
14416
14417 dns_zonetype_t
14418 dns_zone_getredirecttype(dns_zone_t *zone) {
14419 REQUIRE(DNS_ZONE_VALID(zone));
14420 REQUIRE(zone->type == dns_zone_redirect);
14421
14422 return (zone->masters == NULL ? dns_zone_master : dns_zone_slave);
14423 }
14424
14425 dns_name_t *
14426 dns_zone_getorigin(dns_zone_t *zone) {
14427 REQUIRE(DNS_ZONE_VALID(zone));
14428
14429 return (&zone->origin);
14430 }
14431
14432 void
14433 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
14434 REQUIRE(DNS_ZONE_VALID(zone));
14435
14436 LOCK_ZONE(zone);
14437 if (zone->task != NULL)
14438 isc_task_detach(&zone->task);
14439 isc_task_attach(task, &zone->task);
14440 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
14441 if (zone->db != NULL)
14442 dns_db_settask(zone->db, zone->task);
14443 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14444 UNLOCK_ZONE(zone);
14445 }
14446
14447 void
14448 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
14449 REQUIRE(DNS_ZONE_VALID(zone));
14450 isc_task_attach(zone->task, target);
14451 }
14452
14453 void
14454 dns_zone_setidlein(dns_zone_t *zone, uint32_t idlein) {
14455 REQUIRE(DNS_ZONE_VALID(zone));
14456
14457 if (idlein == 0)
14458 idlein = DNS_DEFAULT_IDLEIN;
14459 zone->idlein = idlein;
14460 }
14461
14462 uint32_t
14463 dns_zone_getidlein(dns_zone_t *zone) {
14464 REQUIRE(DNS_ZONE_VALID(zone));
14465
14466 return (zone->idlein);
14467 }
14468
14469 void
14470 dns_zone_setidleout(dns_zone_t *zone, uint32_t idleout) {
14471 REQUIRE(DNS_ZONE_VALID(zone));
14472
14473 zone->idleout = idleout;
14474 }
14475
14476 uint32_t
14477 dns_zone_getidleout(dns_zone_t *zone) {
14478 REQUIRE(DNS_ZONE_VALID(zone));
14479
14480 return (zone->idleout);
14481 }
14482
14483 static void
14484 notify_done(isc_task_t *task, isc_event_t *event) {
14485 dns_requestevent_t *revent = (dns_requestevent_t *)event;
14486 dns_notify_t *notify;
14487 isc_result_t result;
14488 dns_message_t *message = NULL;
14489 isc_buffer_t buf;
14490 char rcode[128];
14491 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
14492
14493 UNUSED(task);
14494
14495 notify = event->ev_arg;
14496 REQUIRE(DNS_NOTIFY_VALID(notify));
14497 INSIST(task == notify->zone->task);
14498
14499 isc_buffer_init(&buf, rcode, sizeof(rcode));
14500 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
14501
14502 result = revent->result;
14503 if (result == ISC_R_SUCCESS)
14504 result = dns_message_create(notify->zone->mctx,
14505 DNS_MESSAGE_INTENTPARSE, &message);
14506 if (result == ISC_R_SUCCESS)
14507 result = dns_request_getresponse(revent->request, message,
14508 DNS_MESSAGEPARSE_PRESERVEORDER);
14509 if (result == ISC_R_SUCCESS)
14510 result = dns_rcode_totext(message->rcode, &buf);
14511 if (result == ISC_R_SUCCESS)
14512 notify_log(notify->zone, ISC_LOG_DEBUG(3),
14513 "notify response from %s: %.*s",
14514 addrbuf, (int)buf.used, rcode);
14515 else
14516 notify_log(notify->zone, ISC_LOG_DEBUG(2),
14517 "notify to %s failed: %s", addrbuf,
14518 dns_result_totext(result));
14519
14520 /*
14521 * Old bind's return formerr if they see a soa record. Retry w/o
14522 * the soa if we see a formerr and had sent a SOA.
14523 */
14524 isc_event_free(&event);
14525 if (message != NULL && message->rcode == dns_rcode_formerr &&
14526 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
14527 bool startup;
14528
14529 notify->flags |= DNS_NOTIFY_NOSOA;
14530 dns_request_destroy(¬ify->request);
14531 startup = (notify->flags & DNS_NOTIFY_STARTUP);
14532 result = notify_send_queue(notify, startup);
14533 if (result != ISC_R_SUCCESS)
14534 notify_destroy(notify, false);
14535 } else {
14536 if (result == ISC_R_TIMEDOUT)
14537 notify_log(notify->zone, ISC_LOG_DEBUG(1),
14538 "notify to %s: retries exceeded", addrbuf);
14539 notify_destroy(notify, false);
14540 }
14541 if (message != NULL)
14542 dns_message_destroy(&message);
14543 }
14544
14545 struct secure_event {
14546 isc_event_t e;
14547 dns_db_t *db;
14548 uint32_t serial;
14549 };
14550
14551 static void
14552 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
14553 UNUSED(arg);
14554 dns_zone_log(zone, level, "%s", message);
14555 }
14556
14557 static isc_result_t
14558 sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
14559 uint32_t start, uint32_t end,
14560 dns_difftuple_t **soatuplep, dns_diff_t *diff)
14561 {
14562 isc_result_t result;
14563 dns_difftuple_t *tuple = NULL;
14564 dns_diffop_t op = DNS_DIFFOP_ADD;
14565 int n_soa = 0;
14566
14567 REQUIRE(soatuplep != NULL);
14568
14569 if (start == end)
14570 return (DNS_R_UNCHANGED);
14571
14572 CHECK(dns_journal_iter_init(journal, start, end));
14573 for (result = dns_journal_first_rr(journal);
14574 result == ISC_R_SUCCESS;
14575 result = dns_journal_next_rr(journal))
14576 {
14577 dns_name_t *name = NULL;
14578 uint32_t ttl;
14579 dns_rdata_t *rdata = NULL;
14580 dns_journal_current_rr(journal, &name, &ttl, &rdata);
14581
14582 if (rdata->type == dns_rdatatype_soa) {
14583 n_soa++;
14584 if (n_soa == 2) {
14585 /*
14586 * Save the latest raw SOA record.
14587 */
14588 if (*soatuplep != NULL)
14589 dns_difftuple_free(soatuplep);
14590 CHECK(dns_difftuple_create(diff->mctx,
14591 DNS_DIFFOP_ADD,
14592 name, ttl, rdata,
14593 soatuplep));
14594 }
14595 if (n_soa == 3)
14596 n_soa = 1;
14597 continue;
14598 }
14599
14600 /* Sanity. */
14601 if (n_soa == 0) {
14602 dns_zone_log(raw, ISC_LOG_ERROR,
14603 "corrupt journal file: '%s'\n",
14604 raw->journal);
14605 return (ISC_R_FAILURE);
14606 }
14607
14608 if (zone->privatetype != 0 &&
14609 rdata->type == zone->privatetype)
14610 continue;
14611
14612 if (rdata->type == dns_rdatatype_nsec ||
14613 rdata->type == dns_rdatatype_rrsig ||
14614 rdata->type == dns_rdatatype_nsec3 ||
14615 rdata->type == dns_rdatatype_dnskey ||
14616 rdata->type == dns_rdatatype_nsec3param)
14617 continue;
14618
14619 op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
14620
14621 CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
14622 &tuple));
14623 dns_diff_appendminimal(diff, &tuple);
14624 }
14625 if (result == ISC_R_NOMORE)
14626 result = ISC_R_SUCCESS;
14627
14628 failure:
14629 return(result);
14630 }
14631
14632 static isc_result_t
14633 sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb,
14634 dns_dbversion_t *secver, dns_difftuple_t **soatuple,
14635 dns_diff_t *diff)
14636 {
14637 isc_result_t result;
14638 dns_db_t *rawdb = NULL;
14639 dns_dbversion_t *rawver = NULL;
14640 dns_difftuple_t *tuple = NULL, *next;
14641 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
14642 dns_rdata_soa_t oldsoa, newsoa;
14643
14644 REQUIRE(DNS_ZONE_VALID(seczone));
14645 REQUIRE(soatuple != NULL && *soatuple == NULL);
14646
14647 if (!seczone->sourceserialset)
14648 return (DNS_R_UNCHANGED);
14649
14650 dns_db_attach(raw->db, &rawdb);
14651 dns_db_currentversion(rawdb, &rawver);
14652 result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
14653 dns_db_closeversion(rawdb, &rawver, false);
14654 dns_db_detach(&rawdb);
14655
14656 if (result != ISC_R_SUCCESS)
14657 return (result);
14658
14659 for (tuple = ISC_LIST_HEAD(diff->tuples);
14660 tuple != NULL;
14661 tuple = next)
14662 {
14663 next = ISC_LIST_NEXT(tuple, link);
14664 if (tuple->rdata.type == dns_rdatatype_nsec ||
14665 tuple->rdata.type == dns_rdatatype_rrsig ||
14666 tuple->rdata.type == dns_rdatatype_dnskey ||
14667 tuple->rdata.type == dns_rdatatype_nsec3 ||
14668 tuple->rdata.type == dns_rdatatype_nsec3param)
14669 {
14670 ISC_LIST_UNLINK(diff->tuples, tuple, link);
14671 dns_difftuple_free(&tuple);
14672 continue;
14673 }
14674 if (tuple->rdata.type == dns_rdatatype_soa) {
14675 if (tuple->op == DNS_DIFFOP_DEL) {
14676 INSIST(oldtuple == NULL);
14677 oldtuple = tuple;
14678 }
14679 if (tuple->op == DNS_DIFFOP_ADD) {
14680 INSIST(newtuple == NULL);
14681 newtuple = tuple;
14682 }
14683 }
14684 }
14685
14686 if (oldtuple != NULL && newtuple != NULL) {
14687
14688 result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL);
14689 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14690
14691 result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL);
14692 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14693
14694 /*
14695 * If the SOA records are the same except for the serial
14696 * remove them from the diff.
14697 */
14698 if (oldsoa.refresh == newsoa.refresh &&
14699 oldsoa.retry == newsoa.retry &&
14700 oldsoa.minimum == newsoa.minimum &&
14701 oldsoa.expire == newsoa.expire &&
14702 dns_name_equal(&oldsoa.origin, &newsoa.origin) &&
14703 dns_name_equal(&oldsoa.contact, &newsoa.contact)) {
14704 ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
14705 dns_difftuple_free(&oldtuple);
14706 ISC_LIST_UNLINK(diff->tuples, newtuple, link);
14707 dns_difftuple_free(&newtuple);
14708 }
14709 }
14710
14711 if (ISC_LIST_EMPTY(diff->tuples))
14712 return (DNS_R_UNCHANGED);
14713
14714 /*
14715 * If there are still SOA records in the diff they can now be removed
14716 * saving the new SOA record.
14717 */
14718 if (oldtuple != NULL) {
14719 ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
14720 dns_difftuple_free(&oldtuple);
14721 }
14722
14723 if (newtuple != NULL) {
14724 ISC_LIST_UNLINK(diff->tuples, newtuple, link);
14725 *soatuple = newtuple;
14726 }
14727
14728 return (ISC_R_SUCCESS);
14729 }
14730
14731 static void
14732 receive_secure_serial(isc_task_t *task, isc_event_t *event) {
14733 static char me[] = "receive_secure_serial";
14734 isc_result_t result = ISC_R_SUCCESS;
14735 dns_journal_t *rjournal = NULL;
14736 dns_journal_t *sjournal = NULL;
14737 uint32_t start, end;
14738 dns_zone_t *zone;
14739 dns_difftuple_t *tuple = NULL, *soatuple = NULL;
14740 dns_update_log_t log = { update_log_cb, NULL };
14741 uint32_t newserial = 0, desired = 0;
14742 isc_time_t timenow;
14743
14744 UNUSED(task);
14745
14746 zone = event->ev_arg;
14747 end = ((struct secure_event *)event)->serial;
14748
14749 ENTER;
14750
14751 LOCK_ZONE(zone);
14752
14753 /*
14754 * If we are already processing a receive secure serial event
14755 * for the zone, just queue the new one and exit.
14756 */
14757 if (zone->rss_event != NULL && zone->rss_event != event) {
14758 ISC_LIST_APPEND(zone->rss_events, event, ev_link);
14759 UNLOCK_ZONE(zone);
14760 return;
14761 }
14762
14763 nextevent:
14764 if (zone->rss_event != NULL) {
14765 INSIST(zone->rss_event == event);
14766 UNLOCK_ZONE(zone);
14767 } else {
14768 zone->rss_event = event;
14769 dns_diff_init(zone->mctx, &zone->rss_diff);
14770
14771 /*
14772 * zone->db may be NULL, if the load from disk failed.
14773 */
14774 result = ISC_R_SUCCESS;
14775 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
14776 if (zone->db != NULL)
14777 dns_db_attach(zone->db, &zone->rss_db);
14778 else
14779 result = ISC_R_FAILURE;
14780 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
14781
14782 if (result == ISC_R_SUCCESS && zone->raw != NULL)
14783 dns_zone_attach(zone->raw, &zone->rss_raw);
14784 else
14785 result = ISC_R_FAILURE;
14786
14787 UNLOCK_ZONE(zone);
14788
14789 CHECK(result);
14790
14791 /*
14792 * We first attempt to sync the raw zone to the secure zone
14793 * by using the raw zone's journal, applying all the deltas
14794 * from the latest source-serial of the secure zone up to
14795 * the current serial number of the raw zone.
14796 *
14797 * If that fails, then we'll fall back to a direct comparison
14798 * between raw and secure zones.
14799 */
14800 CHECK(dns_journal_open(zone->rss_raw->mctx,
14801 zone->rss_raw->journal,
14802 DNS_JOURNAL_WRITE, &rjournal));
14803
14804 result = dns_journal_open(zone->mctx, zone->journal,
14805 DNS_JOURNAL_READ, &sjournal);
14806 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
14807 goto failure;
14808
14809 if (!dns_journal_get_sourceserial(rjournal, &start)) {
14810 start = dns_journal_first_serial(rjournal);
14811 dns_journal_set_sourceserial(rjournal, start);
14812 }
14813 if (sjournal != NULL) {
14814 uint32_t serial;
14815 /*
14816 * We read the secure journal first, if that
14817 * exists use its value provided it is greater
14818 * that from the raw journal.
14819 */
14820 if (dns_journal_get_sourceserial(sjournal, &serial)) {
14821 if (isc_serial_gt(serial, start))
14822 start = serial;
14823 }
14824 dns_journal_destroy(&sjournal);
14825 }
14826
14827 dns_db_currentversion(zone->rss_db, &zone->rss_oldver);
14828 CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver));
14829
14830 /*
14831 * Try to apply diffs from the raw zone's journal to the secure
14832 * zone. If that fails, we recover by syncing up the databases
14833 * directly.
14834 */
14835 result = sync_secure_journal(zone, zone->rss_raw, rjournal,
14836 start, end, &soatuple,
14837 &zone->rss_diff);
14838 if (result == DNS_R_UNCHANGED)
14839 goto failure;
14840 else if (result != ISC_R_SUCCESS)
14841 CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db,
14842 zone->rss_oldver, &soatuple,
14843 &zone->rss_diff));
14844
14845 CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db,
14846 zone->rss_newver));
14847
14848 if (soatuple != NULL) {
14849 uint32_t oldserial;
14850
14851 CHECK(dns_db_createsoatuple(zone->rss_db,
14852 zone->rss_oldver,
14853 zone->rss_diff.mctx,
14854 DNS_DIFFOP_DEL, &tuple));
14855 oldserial = dns_soa_getserial(&tuple->rdata);
14856 newserial = desired =
14857 dns_soa_getserial(&soatuple->rdata);
14858 if (!isc_serial_gt(newserial, oldserial)) {
14859 newserial = oldserial + 1;
14860 if (newserial == 0)
14861 newserial++;
14862 dns_soa_setserial(newserial, &soatuple->rdata);
14863 }
14864 CHECK(do_one_tuple(&tuple, zone->rss_db,
14865 zone->rss_newver, &zone->rss_diff));
14866 CHECK(do_one_tuple(&soatuple, zone->rss_db,
14867 zone->rss_newver, &zone->rss_diff));
14868 } else
14869 CHECK(update_soa_serial(zone->rss_db, zone->rss_newver,
14870 &zone->rss_diff, zone->mctx,
14871 zone->updatemethod));
14872
14873 }
14874 result = dns_update_signaturesinc(&log, zone, zone->rss_db,
14875 zone->rss_oldver, zone->rss_newver,
14876 &zone->rss_diff,
14877 zone->sigvalidityinterval,
14878 &zone->rss_state);
14879 if (result == DNS_R_CONTINUE) {
14880 if (rjournal != NULL)
14881 dns_journal_destroy(&rjournal);
14882 isc_task_send(task, &event);
14883 return;
14884 }
14885 /*
14886 * If something went wrong while trying to update the secure zone and
14887 * the latter was already signed before, do not apply raw zone deltas
14888 * to it as that would break existing DNSSEC signatures. However, if
14889 * the secure zone was not yet signed (e.g. because no signing keys
14890 * were created for it), commence applying raw zone deltas to it so
14891 * that contents of the raw zone and the secure zone are kept in sync.
14892 */
14893 if (result != ISC_R_SUCCESS && dns_db_issecure(zone->rss_db)) {
14894 goto failure;
14895 }
14896
14897 if (rjournal == NULL)
14898 CHECK(dns_journal_open(zone->rss_raw->mctx,
14899 zone->rss_raw->journal,
14900 DNS_JOURNAL_WRITE, &rjournal));
14901 CHECK(zone_journal(zone, &zone->rss_diff, &end,
14902 "receive_secure_serial"));
14903
14904 dns_journal_set_sourceserial(rjournal, end);
14905 dns_journal_commit(rjournal);
14906
14907 LOCK_ZONE(zone);
14908 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
14909
14910 zone->sourceserial = end;
14911 zone->sourceserialset = true;
14912 zone_needdump(zone, DNS_DUMP_DELAY);
14913
14914 TIME_NOW(&timenow);
14915 zone_settimer(zone, &timenow);
14916 UNLOCK_ZONE(zone);
14917
14918 dns_db_closeversion(zone->rss_db, &zone->rss_oldver, false);
14919 dns_db_closeversion(zone->rss_db, &zone->rss_newver, true);
14920
14921 if (newserial != 0) {
14922 dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)",
14923 newserial, desired);
14924 }
14925
14926 failure:
14927 isc_event_free(&zone->rss_event);
14928 event = ISC_LIST_HEAD(zone->rss_events);
14929
14930 if (zone->rss_raw != NULL)
14931 dns_zone_detach(&zone->rss_raw);
14932 if (result != ISC_R_SUCCESS)
14933 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s",
14934 dns_result_totext(result));
14935 if (tuple != NULL)
14936 dns_difftuple_free(&tuple);
14937 if (soatuple != NULL)
14938 dns_difftuple_free(&soatuple);
14939 if (zone->rss_db != NULL) {
14940 if (zone->rss_oldver != NULL)
14941 dns_db_closeversion(zone->rss_db, &zone->rss_oldver,
14942 false);
14943 if (zone->rss_newver != NULL)
14944 dns_db_closeversion(zone->rss_db, &zone->rss_newver,
14945 false);
14946 dns_db_detach(&zone->rss_db);
14947 }
14948 INSIST(zone->rss_oldver == NULL);
14949 INSIST(zone->rss_newver == NULL);
14950 if (rjournal != NULL)
14951 dns_journal_destroy(&rjournal);
14952 dns_diff_clear(&zone->rss_diff);
14953
14954 if (event != NULL) {
14955 LOCK_ZONE(zone);
14956 INSIST(zone->irefs > 1);
14957 zone->irefs--;
14958 ISC_LIST_UNLINK(zone->rss_events, event, ev_link);
14959 goto nextevent;
14960 }
14961
14962 event = ISC_LIST_HEAD(zone->rss_post);
14963 while (event != NULL) {
14964 ISC_LIST_UNLINK(zone->rss_post, event, ev_link);
14965 rss_post(zone, event);
14966 event = ISC_LIST_HEAD(zone->rss_post);
14967 }
14968
14969 dns_zone_idetach(&zone);
14970 }
14971
14972 static isc_result_t
14973 zone_send_secureserial(dns_zone_t *zone, uint32_t serial) {
14974 isc_event_t *e;
14975 dns_zone_t *dummy = NULL;
14976
14977 e = isc_event_allocate(zone->secure->mctx, zone,
14978 DNS_EVENT_ZONESECURESERIAL,
14979 receive_secure_serial, zone->secure,
14980 sizeof(struct secure_event));
14981 if (e == NULL)
14982 return (ISC_R_NOMEMORY);
14983 ((struct secure_event *)e)->serial = serial;
14984 INSIST(LOCKED_ZONE(zone->secure));
14985 zone_iattach(zone->secure, &dummy);
14986 isc_task_send(zone->secure->task, &e);
14987
14988 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
14989 return (ISC_R_SUCCESS);
14990 }
14991
14992 static isc_result_t
14993 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
14994 dns_rdataset_t *rdataset, uint32_t oldserial)
14995 {
14996 dns_rdata_soa_t soa;
14997 dns_rdata_t rdata = DNS_RDATA_INIT;
14998 dns_rdatalist_t temprdatalist;
14999 dns_rdataset_t temprdataset;
15000 isc_buffer_t b;
15001 isc_result_t result;
15002 unsigned char buf[DNS_SOA_BUFFERSIZE];
15003 dns_fixedname_t fixed;
15004 dns_name_t *name;
15005
15006 result = dns_rdataset_first(rdataset);
15007 RUNTIME_CHECK(result == ISC_R_SUCCESS);
15008 dns_rdataset_current(rdataset, &rdata);
15009 result = dns_rdata_tostruct(&rdata, &soa, NULL);
15010 RUNTIME_CHECK(result == ISC_R_SUCCESS);
15011
15012 if (isc_serial_gt(soa.serial, oldserial))
15013 return (dns_db_addrdataset(db, node, version, 0, rdataset, 0,
15014 NULL));
15015 /*
15016 * Always bump the serial.
15017 */
15018 oldserial++;
15019 if (oldserial == 0)
15020 oldserial++;
15021 soa.serial = oldserial;
15022
15023 /*
15024 * Construct a replacement rdataset.
15025 */
15026 dns_rdata_reset(&rdata);
15027 isc_buffer_init(&b, buf, sizeof(buf));
15028 result = dns_rdata_fromstruct(&rdata, rdataset->rdclass,
15029 dns_rdatatype_soa, &soa, &b);
15030 RUNTIME_CHECK(result == ISC_R_SUCCESS);
15031 dns_rdatalist_init(&temprdatalist);
15032 temprdatalist.rdclass = rdata.rdclass;
15033 temprdatalist.type = rdata.type;
15034 temprdatalist.ttl = rdataset->ttl;
15035 ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link);
15036
15037 dns_rdataset_init(&temprdataset);
15038 result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
15039 RUNTIME_CHECK(result == ISC_R_SUCCESS);
15040
15041 name = dns_fixedname_initname(&fixed);
15042 result = dns_db_nodefullname(db, node, name);
15043 RUNTIME_CHECK(result == ISC_R_SUCCESS);
15044 dns_rdataset_getownercase(rdataset, name);
15045 dns_rdataset_setownercase(&temprdataset, name);
15046 return (dns_db_addrdataset(db, node, version, 0, &temprdataset,
15047 0, NULL));
15048 }
15049
15050 /*
15051 * This function should populate an nsec3paramlist_t with the
15052 * nsecparam_t data from a zone.
15053 */
15054 static isc_result_t
15055 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
15056 isc_result_t result;
15057 dns_dbnode_t *node = NULL;
15058 dns_rdataset_t rdataset, prdataset;
15059 dns_dbversion_t *version = NULL;
15060 nsec3param_t *nsec3param = NULL;
15061 nsec3param_t *nsec3p = NULL;
15062 nsec3param_t *next;
15063 dns_db_t *db = NULL;
15064 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
15065
15066 REQUIRE(DNS_ZONE_VALID(zone));
15067 REQUIRE(nsec3list != NULL);
15068 REQUIRE(ISC_LIST_EMPTY(*nsec3list));
15069
15070 dns_rdataset_init(&rdataset);
15071 dns_rdataset_init(&prdataset);
15072
15073 dns_db_attach(zone->db, &db);
15074 CHECK(dns_db_getoriginnode(db, &node));
15075
15076 dns_db_currentversion(db, &version);
15077 result = dns_db_findrdataset(db, node, version,
15078 dns_rdatatype_nsec3param,
15079 dns_rdatatype_none, 0, &rdataset, NULL);
15080
15081 if (result != ISC_R_SUCCESS)
15082 goto getprivate;
15083
15084 /*
15085 * walk nsec3param rdataset making a list of parameters (note that
15086 * multiple simultaneous nsec3 chains are annoyingly legal -- this
15087 * is why we use an nsec3list, even tho we will usually only have
15088 * one)
15089 */
15090 for (result = dns_rdataset_first(&rdataset);
15091 result == ISC_R_SUCCESS;
15092 result = dns_rdataset_next(&rdataset))
15093 {
15094 dns_rdata_t rdata = DNS_RDATA_INIT;
15095 dns_rdata_t private = DNS_RDATA_INIT;
15096
15097 dns_rdataset_current(&rdataset, &rdata);
15098 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
15099 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
15100 "looping through nsec3param data");
15101 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
15102 if (nsec3param == NULL)
15103 CHECK(ISC_R_NOMEMORY);
15104 ISC_LINK_INIT(nsec3param, link);
15105
15106 /*
15107 * now transfer the data from the rdata to
15108 * the nsec3param
15109 */
15110 dns_nsec3param_toprivate(&rdata, &private,
15111 zone->privatetype, nsec3param->data,
15112 sizeof(nsec3param->data));
15113 nsec3param->length = private.length;
15114 ISC_LIST_APPEND(*nsec3list, nsec3param, link);
15115 }
15116
15117 getprivate:
15118 result = dns_db_findrdataset(db, node, version, zone->privatetype,
15119 dns_rdatatype_none, 0, &prdataset, NULL);
15120 if (result != ISC_R_SUCCESS)
15121 goto done;
15122
15123 /*
15124 * walk private type records, converting them to nsec3 parameters
15125 * using dns_nsec3param_fromprivate(), do the right thing based on
15126 * CREATE and REMOVE flags
15127 */
15128 for (result = dns_rdataset_first(&prdataset);
15129 result == ISC_R_SUCCESS;
15130 result = dns_rdataset_next(&prdataset))
15131 {
15132 dns_rdata_t rdata = DNS_RDATA_INIT;
15133 dns_rdata_t private = DNS_RDATA_INIT;
15134
15135 dns_rdataset_current(&prdataset, &private);
15136 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
15137 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
15138 "looping through nsec3param private data");
15139
15140 /*
15141 * Do we have a valid private record?
15142 */
15143 if (!dns_nsec3param_fromprivate(&private, &rdata,
15144 buf, sizeof(buf)))
15145 continue;
15146
15147 /*
15148 * Remove any NSEC3PARAM records scheduled to be removed.
15149 */
15150 if (NSEC3REMOVE(rdata.data[1])) {
15151 /*
15152 * Zero out the flags.
15153 */
15154 rdata.data[1] = 0;
15155
15156 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
15157 nsec3p != NULL;
15158 nsec3p = next)
15159 {
15160 next = ISC_LIST_NEXT(nsec3p, link);
15161
15162 if (nsec3p->length == rdata.length + 1 &&
15163 memcmp(rdata.data, nsec3p->data + 1,
15164 nsec3p->length - 1) == 0) {
15165 ISC_LIST_UNLINK(*nsec3list,
15166 nsec3p, link);
15167 isc_mem_put(zone->mctx, nsec3p,
15168 sizeof(nsec3param_t));
15169 }
15170 }
15171 continue;
15172 }
15173
15174 nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
15175 if (nsec3param == NULL)
15176 CHECK(ISC_R_NOMEMORY);
15177 ISC_LINK_INIT(nsec3param, link);
15178
15179 /*
15180 * Copy the remaining private records so the nsec/nsec3
15181 * chain gets created.
15182 */
15183 INSIST(private.length <= sizeof(nsec3param->data));
15184 memmove(nsec3param->data, private.data, private.length);
15185 nsec3param->length = private.length;
15186 ISC_LIST_APPEND(*nsec3list, nsec3param, link);
15187 }
15188
15189 done:
15190 if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND)
15191 result = ISC_R_SUCCESS;
15192
15193 failure:
15194 if (node != NULL)
15195 dns_db_detachnode(db, &node);
15196 if (version != NULL)
15197 dns_db_closeversion(db, &version, false);
15198 if (db != NULL)
15199 dns_db_detach(&db);
15200 if (dns_rdataset_isassociated(&rdataset))
15201 dns_rdataset_disassociate(&rdataset);
15202 if (dns_rdataset_isassociated(&prdataset))
15203 dns_rdataset_disassociate(&prdataset);
15204 return (result);
15205 }
15206
15207 /*
15208 * Populate new zone db with private type records found by save_nsec3param().
15209 */
15210 static isc_result_t
15211 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
15212 nsec3paramlist_t *nsec3list)
15213 {
15214 isc_result_t result = ISC_R_SUCCESS;
15215 dns_diff_t diff;
15216 dns_rdata_t rdata;
15217 nsec3param_t *nsec3p = NULL;
15218 nsec3param_t *next;
15219
15220 REQUIRE(DNS_ZONE_VALID(zone));
15221 REQUIRE(!ISC_LIST_EMPTY(*nsec3list));
15222
15223 dns_diff_init(zone->mctx, &diff);
15224
15225 /*
15226 * Loop through the list of private-type records, set the INITIAL
15227 * and CREATE flags, and the add the record to the apex of the tree
15228 * in db.
15229 */
15230 for (nsec3p = ISC_LIST_HEAD(*nsec3list);
15231 nsec3p != NULL;
15232 nsec3p = next)
15233 {
15234 next = ISC_LIST_NEXT(nsec3p, link);
15235 dns_rdata_init(&rdata);
15236 nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL;
15237 rdata.length = nsec3p->length;
15238 rdata.data = nsec3p->data;
15239 rdata.type = zone->privatetype;
15240 rdata.rdclass = zone->rdclass;
15241 result = update_one_rr(db, version, &diff, DNS_DIFFOP_ADD,
15242 &zone->origin, 0, &rdata);
15243 if (result != ISC_R_SUCCESS) {
15244 break;
15245 }
15246 }
15247
15248 dns_diff_clear(&diff);
15249 return (result);
15250 }
15251
15252 static void
15253 receive_secure_db(isc_task_t *task, isc_event_t *event) {
15254 isc_result_t result;
15255 dns_zone_t *zone;
15256 dns_db_t *rawdb, *db = NULL;
15257 dns_dbnode_t *rawnode = NULL, *node = NULL;
15258 dns_fixedname_t fname;
15259 dns_name_t *name;
15260 dns_dbiterator_t *dbiterator = NULL;
15261 dns_rdatasetiter_t *rdsit = NULL;
15262 dns_rdataset_t rdataset;
15263 dns_dbversion_t *version = NULL;
15264 isc_time_t loadtime;
15265 unsigned int oldserial = 0;
15266 bool have_oldserial = false;
15267 nsec3paramlist_t nsec3list;
15268 isc_event_t *setnsec3param_event;
15269 dns_zone_t *dummy;
15270
15271 UNUSED(task);
15272
15273 ISC_LIST_INIT(nsec3list);
15274
15275 zone = event->ev_arg;
15276 rawdb = ((struct secure_event *)event)->db;
15277 isc_event_free(&event);
15278
15279 name = dns_fixedname_initname(&fname);
15280 dns_rdataset_init(&rdataset);
15281
15282 LOCK_ZONE(zone);
15283 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) {
15284 result = ISC_R_SHUTTINGDOWN;
15285 goto failure;
15286 }
15287
15288 TIME_NOW(&loadtime);
15289 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
15290 if (zone->db != NULL) {
15291 result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
15292 if (result == ISC_R_SUCCESS)
15293 have_oldserial = true;
15294
15295 /*
15296 * assemble nsec3parameters from the old zone, and set a flag
15297 * if any are found
15298 */
15299 result = save_nsec3param(zone, &nsec3list);
15300 if (result != ISC_R_SUCCESS) {
15301 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
15302 goto failure;
15303 }
15304 }
15305 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
15306
15307 result = dns_db_create(zone->mctx, zone->db_argv[0],
15308 &zone->origin, dns_dbtype_zone, zone->rdclass,
15309 zone->db_argc - 1, zone->db_argv + 1, &db);
15310 if (result != ISC_R_SUCCESS)
15311 goto failure;
15312
15313 result = dns_db_setgluecachestats(db, zone->gluecachestats);
15314 if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
15315 goto failure;
15316 }
15317
15318 result = dns_db_newversion(db, &version);
15319 if (result != ISC_R_SUCCESS)
15320 goto failure;
15321
15322 result = dns_db_createiterator(rawdb, 0, &dbiterator);
15323 if (result != ISC_R_SUCCESS)
15324 goto failure;
15325
15326 for (result = dns_dbiterator_first(dbiterator);
15327 result == ISC_R_SUCCESS;
15328 result = dns_dbiterator_next(dbiterator)) {
15329 result = dns_dbiterator_current(dbiterator, &rawnode, name);
15330 if (result != ISC_R_SUCCESS)
15331 continue;
15332
15333 result = dns_db_findnode(db, name, true, &node);
15334 if (result != ISC_R_SUCCESS)
15335 goto failure;
15336
15337 result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit);
15338 if (result != ISC_R_SUCCESS)
15339 goto failure;
15340
15341 for (result = dns_rdatasetiter_first(rdsit);
15342 result == ISC_R_SUCCESS;
15343 result = dns_rdatasetiter_next(rdsit)) {
15344 dns_rdatasetiter_current(rdsit, &rdataset);
15345 if (rdataset.type == dns_rdatatype_nsec ||
15346 rdataset.type == dns_rdatatype_rrsig ||
15347 rdataset.type == dns_rdatatype_nsec3 ||
15348 rdataset.type == dns_rdatatype_dnskey ||
15349 rdataset.type == dns_rdatatype_nsec3param) {
15350 dns_rdataset_disassociate(&rdataset);
15351 continue;
15352 }
15353 if (rdataset.type == dns_rdatatype_soa &&
15354 have_oldserial) {
15355 result = checkandaddsoa(db, node, version,
15356 &rdataset, oldserial);
15357 } else
15358 result = dns_db_addrdataset(db, node, version,
15359 0, &rdataset, 0,
15360 NULL);
15361 if (result != ISC_R_SUCCESS)
15362 goto failure;
15363
15364 dns_rdataset_disassociate(&rdataset);
15365 }
15366 dns_rdatasetiter_destroy(&rdsit);
15367 dns_db_detachnode(rawdb, &rawnode);
15368 dns_db_detachnode(db, &node);
15369 }
15370
15371 /*
15372 * Call restore_nsec3param() to create private-type records from
15373 * the old nsec3 parameters and insert them into db
15374 */
15375 if (!ISC_LIST_EMPTY(nsec3list)) {
15376 result = restore_nsec3param(zone, db, version, &nsec3list);
15377 if (result != ISC_R_SUCCESS) {
15378 goto failure;
15379 }
15380 }
15381
15382 dns_db_closeversion(db, &version, true);
15383
15384 /*
15385 * Lock hierarchy: zmgr, zone, raw.
15386 */
15387 INSIST(zone != zone->raw);
15388 LOCK_ZONE(zone->raw);
15389 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
15390 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
15391 zone_needdump(zone, 0); /* XXXMPA */
15392 UNLOCK_ZONE(zone->raw);
15393
15394 /*
15395 * Process any queued NSEC3PARAM change requests.
15396 */
15397 while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
15398 setnsec3param_event = ISC_LIST_HEAD(zone->setnsec3param_queue);
15399 ISC_LIST_UNLINK(zone->setnsec3param_queue, setnsec3param_event,
15400 ev_link);
15401 dummy = NULL;
15402 zone_iattach(zone, &dummy);
15403 isc_task_send(zone->task, &setnsec3param_event);
15404 }
15405
15406 failure:
15407 UNLOCK_ZONE(zone);
15408 if (result != ISC_R_SUCCESS)
15409 dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
15410 dns_result_totext(result));
15411
15412 while (!ISC_LIST_EMPTY(nsec3list)) {
15413 nsec3param_t *nsec3p;
15414 nsec3p = ISC_LIST_HEAD(nsec3list);
15415 ISC_LIST_UNLINK(nsec3list, nsec3p, link);
15416 isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
15417 }
15418 if (dns_rdataset_isassociated(&rdataset))
15419 dns_rdataset_disassociate(&rdataset);
15420 if (db != NULL) {
15421 if (node != NULL)
15422 dns_db_detachnode(db, &node);
15423 if (version != NULL)
15424 dns_db_closeversion(db, &version, false);
15425 dns_db_detach(&db);
15426 }
15427 if (rawnode != NULL)
15428 dns_db_detachnode(rawdb, &rawnode);
15429 dns_db_detach(&rawdb);
15430 if (dbiterator != NULL)
15431 dns_dbiterator_destroy(&dbiterator);
15432 dns_zone_idetach(&zone);
15433
15434 INSIST(version == NULL);
15435 }
15436
15437 static isc_result_t
15438 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) {
15439 isc_event_t *e;
15440 dns_db_t *dummy = NULL;
15441 dns_zone_t *secure = NULL;
15442
15443 e = isc_event_allocate(zone->secure->mctx, zone,
15444 DNS_EVENT_ZONESECUREDB,
15445 receive_secure_db, zone->secure,
15446 sizeof(struct secure_event));
15447 if (e == NULL)
15448 return (ISC_R_NOMEMORY);
15449 dns_db_attach(db, &dummy);
15450 ((struct secure_event *)e)->db = dummy;
15451 INSIST(LOCKED_ZONE(zone->secure));
15452 zone_iattach(zone->secure, &secure);
15453 isc_task_send(zone->secure->task, &e);
15454 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
15455 return (ISC_R_SUCCESS);
15456 }
15457
15458 isc_result_t
15459 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
15460 isc_result_t result;
15461 dns_zone_t *secure = NULL;
15462
15463 REQUIRE(DNS_ZONE_VALID(zone));
15464 again:
15465 LOCK_ZONE(zone);
15466 if (inline_raw(zone)) {
15467 secure = zone->secure;
15468 INSIST(secure != zone);
15469 TRYLOCK_ZONE(result, secure);
15470 if (result != ISC_R_SUCCESS) {
15471 UNLOCK_ZONE(zone);
15472 secure = NULL;
15473 isc_thread_yield();
15474 goto again;
15475 }
15476 }
15477 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
15478 result = zone_replacedb(zone, db, dump);
15479 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
15480 if (secure != NULL)
15481 UNLOCK_ZONE(secure);
15482 UNLOCK_ZONE(zone);
15483 return (result);
15484 }
15485
15486 static isc_result_t
15487 zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
15488 dns_dbversion_t *ver;
15489 isc_result_t result;
15490 unsigned int soacount = 0;
15491 unsigned int nscount = 0;
15492
15493 /*
15494 * 'zone' and 'zone->db' locked by caller.
15495 */
15496 REQUIRE(DNS_ZONE_VALID(zone));
15497 REQUIRE(LOCKED_ZONE(zone));
15498 if (inline_raw(zone))
15499 REQUIRE(LOCKED_ZONE(zone->secure));
15500
15501 result = zone_get_from_db(zone, db, &nscount, &soacount,
15502 NULL, NULL, NULL, NULL, NULL, NULL);
15503 if (result == ISC_R_SUCCESS) {
15504 if (soacount != 1) {
15505 dns_zone_log(zone, ISC_LOG_ERROR,
15506 "has %d SOA records", soacount);
15507 result = DNS_R_BADZONE;
15508 }
15509 if (nscount == 0 && zone->type != dns_zone_key) {
15510 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
15511 result = DNS_R_BADZONE;
15512 }
15513 if (result != ISC_R_SUCCESS)
15514 return (result);
15515 } else {
15516 dns_zone_log(zone, ISC_LOG_ERROR,
15517 "retrieving SOA and NS records failed: %s",
15518 dns_result_totext(result));
15519 return (result);
15520 }
15521
15522 result = check_nsec3param(zone, db);
15523 if (result != ISC_R_SUCCESS)
15524 return (result);
15525
15526 ver = NULL;
15527 dns_db_currentversion(db, &ver);
15528
15529 /*
15530 * The initial version of a slave zone is always dumped;
15531 * subsequent versions may be journaled instead if this
15532 * is enabled in the configuration.
15533 */
15534 if (zone->db != NULL && zone->journal != NULL &&
15535 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
15536 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
15537 {
15538 uint32_t serial, oldserial;
15539
15540 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
15541
15542 result = dns_db_getsoaserial(db, ver, &serial);
15543 if (result != ISC_R_SUCCESS) {
15544 dns_zone_log(zone, ISC_LOG_ERROR,
15545 "ixfr-from-differences: unable to get "
15546 "new serial");
15547 goto fail;
15548 }
15549
15550 /*
15551 * This is checked in zone_postload() for master zones.
15552 */
15553 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
15554 &oldserial, NULL, NULL, NULL, NULL,
15555 NULL);
15556 RUNTIME_CHECK(result == ISC_R_SUCCESS);
15557 RUNTIME_CHECK(soacount > 0U);
15558 if ((zone->type == dns_zone_slave ||
15559 (zone->type == dns_zone_redirect &&
15560 zone->masters != NULL))
15561 && !isc_serial_gt(serial, oldserial)) {
15562 uint32_t serialmin, serialmax;
15563 serialmin = (oldserial + 1) & 0xffffffffU;
15564 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
15565 dns_zone_log(zone, ISC_LOG_ERROR,
15566 "ixfr-from-differences: failed: "
15567 "new serial (%u) out of range [%u - %u]",
15568 serial, serialmin, serialmax);
15569 result = ISC_R_RANGE;
15570 goto fail;
15571 }
15572
15573 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
15574 zone->journal);
15575 if (result != ISC_R_SUCCESS) {
15576 char strbuf[ISC_STRERRORSIZE];
15577 strerror_r(errno, strbuf, sizeof(strbuf));
15578 dns_zone_log(zone, ISC_LOG_ERROR,
15579 "ixfr-from-differences: failed: "
15580 "%s", strbuf);
15581 goto fallback;
15582 }
15583 if (dump)
15584 zone_needdump(zone, DNS_DUMP_DELAY);
15585 else
15586 zone_journal_compact(zone, zone->db, serial);
15587 if (zone->type == dns_zone_master && inline_raw(zone))
15588 zone_send_secureserial(zone, serial);
15589 } else {
15590 fallback:
15591 if (dump && zone->masterfile != NULL) {
15592 /*
15593 * If DNS_ZONEFLG_FORCEXFER was set we don't want
15594 * to keep the old masterfile.
15595 */
15596 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
15597 remove(zone->masterfile) < 0 && errno != ENOENT) {
15598 char strbuf[ISC_STRERRORSIZE];
15599 strerror_r(errno, strbuf, sizeof(strbuf));
15600 isc_log_write(dns_lctx,
15601 DNS_LOGCATEGORY_GENERAL,
15602 DNS_LOGMODULE_ZONE,
15603 ISC_LOG_WARNING,
15604 "unable to remove masterfile "
15605 "'%s': '%s'",
15606 zone->masterfile, strbuf);
15607 }
15608 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
15609 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
15610 else
15611 zone_needdump(zone, 0);
15612 }
15613 if (dump && zone->journal != NULL) {
15614 /*
15615 * The in-memory database just changed, and
15616 * because 'dump' is set, it didn't change by
15617 * being loaded from disk. Also, we have not
15618 * journaled diffs for this change.
15619 * Therefore, the on-disk journal is missing
15620 * the deltas for this change. Since it can
15621 * no longer be used to bring the zone
15622 * up-to-date, it is useless and should be
15623 * removed.
15624 */
15625 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
15626 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
15627 "removing journal file");
15628 if (remove(zone->journal) < 0 && errno != ENOENT) {
15629 char strbuf[ISC_STRERRORSIZE];
15630 strerror_r(errno, strbuf, sizeof(strbuf));
15631 isc_log_write(dns_lctx,
15632 DNS_LOGCATEGORY_GENERAL,
15633 DNS_LOGMODULE_ZONE,
15634 ISC_LOG_WARNING,
15635 "unable to remove journal "
15636 "'%s': '%s'",
15637 zone->journal, strbuf);
15638 }
15639 }
15640
15641 if (inline_raw(zone))
15642 zone_send_securedb(zone, db);
15643 }
15644
15645 dns_db_closeversion(db, &ver, false);
15646
15647 dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database");
15648
15649 if (zone->db != NULL)
15650 zone_detachdb(zone);
15651 zone_attachdb(zone, db);
15652 dns_db_settask(zone->db, zone->task);
15653 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
15654 return (ISC_R_SUCCESS);
15655
15656 fail:
15657 dns_db_closeversion(db, &ver, false);
15658 return (result);
15659 }
15660
15661 /* The caller must hold the dblock as a writer. */
15662 static inline void
15663 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
15664 REQUIRE(zone->db == NULL && db != NULL);
15665
15666 dns_db_attach(db, &zone->db);
15667 }
15668
15669 /* The caller must hold the dblock as a writer. */
15670 static inline void
15671 zone_detachdb(dns_zone_t *zone) {
15672 REQUIRE(zone->db != NULL);
15673
15674 dns_db_detach(&zone->db);
15675 }
15676
15677 static void
15678 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
15679 isc_time_t now;
15680 bool again = false;
15681 unsigned int soacount;
15682 unsigned int nscount;
15683 uint32_t serial, refresh, retry, expire, minimum;
15684 isc_result_t xfrresult = result;
15685 bool free_needed;
15686 dns_zone_t *secure = NULL;
15687
15688 REQUIRE(DNS_ZONE_VALID(zone));
15689
15690 dns_zone_log(zone, ISC_LOG_DEBUG(1),
15691 "zone transfer finished: %s", dns_result_totext(result));
15692
15693 /*
15694 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
15695 * could result in a deadlock due to a LOR so we will spin if we
15696 * can't obtain the both locks.
15697 */
15698 again:
15699 LOCK_ZONE(zone);
15700 if (inline_raw(zone)) {
15701 secure = zone->secure;
15702 INSIST(secure != zone);
15703 TRYLOCK_ZONE(result, secure);
15704 if (result != ISC_R_SUCCESS) {
15705 UNLOCK_ZONE(zone);
15706 secure = NULL;
15707 isc_thread_yield();
15708 goto again;
15709 }
15710 }
15711
15712 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
15713 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
15714 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
15715
15716 TIME_NOW(&now);
15717 switch (xfrresult) {
15718 case ISC_R_SUCCESS:
15719 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
15720 /* FALLTHROUGH */
15721 case DNS_R_UPTODATE:
15722 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
15723 /*
15724 * Has the zone expired underneath us?
15725 */
15726 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
15727 if (zone->db == NULL) {
15728 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
15729 goto same_master;
15730 }
15731
15732 /*
15733 * Update the zone structure's data from the actual
15734 * SOA received.
15735 */
15736 nscount = 0;
15737 soacount = 0;
15738 INSIST(zone->db != NULL);
15739 result = zone_get_from_db(zone, zone->db, &nscount,
15740 &soacount, &serial, &refresh,
15741 &retry, &expire, &minimum, NULL);
15742 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
15743 if (result == ISC_R_SUCCESS) {
15744 if (soacount != 1)
15745 dns_zone_log(zone, ISC_LOG_ERROR,
15746 "transferred zone "
15747 "has %d SOA record%s", soacount,
15748 (soacount != 0) ? "s" : "");
15749 if (nscount == 0) {
15750 dns_zone_log(zone, ISC_LOG_ERROR,
15751 "transferred zone "
15752 "has no NS records");
15753 if (DNS_ZONE_FLAG(zone,
15754 DNS_ZONEFLG_HAVETIMERS)) {
15755 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
15756 zone->retry = DNS_ZONE_DEFAULTRETRY;
15757 }
15758 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
15759 zone_unload(zone);
15760 goto next_master;
15761 }
15762 zone->refresh = RANGE(refresh, zone->minrefresh,
15763 zone->maxrefresh);
15764 zone->retry = RANGE(retry, zone->minretry,
15765 zone->maxretry);
15766 zone->expire = RANGE(expire,
15767 zone->refresh + zone->retry,
15768 DNS_MAX_EXPIRE);
15769 zone->minimum = minimum;
15770 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
15771 }
15772
15773 /*
15774 * Set our next update/expire times.
15775 */
15776 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
15777 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
15778 zone->refreshtime = now;
15779 DNS_ZONE_TIME_ADD(&now, zone->expire,
15780 &zone->expiretime);
15781 } else {
15782 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
15783 &zone->refreshtime);
15784 DNS_ZONE_TIME_ADD(&now, zone->expire,
15785 &zone->expiretime);
15786 }
15787 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
15788 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
15789 if (zone->tsigkey != NULL) {
15790 char namebuf[DNS_NAME_FORMATSIZE];
15791 dns_name_format(&zone->tsigkey->name, namebuf,
15792 sizeof(namebuf));
15793 snprintf(buf, sizeof(buf), ": TSIG '%s'",
15794 namebuf);
15795 } else
15796 buf[0] = '\0';
15797 dns_zone_log(zone, ISC_LOG_INFO,
15798 "transferred serial %u%s",
15799 serial, buf);
15800 if (inline_raw(zone))
15801 zone_send_secureserial(zone, serial);
15802 }
15803
15804 /*
15805 * This is not necessary if we just performed a AXFR
15806 * however it is necessary for an IXFR / UPTODATE and
15807 * won't hurt with an AXFR.
15808 */
15809 if (zone->masterfile != NULL || zone->journal != NULL) {
15810 unsigned int delay = DNS_DUMP_DELAY;
15811
15812 result = ISC_R_FAILURE;
15813 if (zone->journal != NULL)
15814 result = isc_file_settime(zone->journal, &now);
15815 if (result != ISC_R_SUCCESS &&
15816 zone->masterfile != NULL)
15817 result = isc_file_settime(zone->masterfile,
15818 &now);
15819
15820 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
15821 result == ISC_R_FILENOTFOUND)
15822 delay = 0;
15823
15824 if ((result == ISC_R_SUCCESS ||
15825 result == ISC_R_FILENOTFOUND) &&
15826 zone->masterfile != NULL)
15827 zone_needdump(zone, delay);
15828 else if (result != ISC_R_SUCCESS)
15829 dns_zone_log(zone, ISC_LOG_ERROR,
15830 "transfer: could not set file "
15831 "modification time of '%s': %s",
15832 zone->masterfile,
15833 dns_result_totext(result));
15834 }
15835 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
15836 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
15837 break;
15838
15839 case DNS_R_BADIXFR:
15840 /* Force retry with AXFR. */
15841 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
15842 goto same_master;
15843
15844 case DNS_R_TOOMANYRECORDS:
15845 case DNS_R_VERIFYFAILURE:
15846 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
15847 inc_stats(zone, dns_zonestatscounter_xfrfail);
15848 break;
15849
15850 default:
15851 next_master:
15852 /*
15853 * Skip to next failed / untried master.
15854 */
15855 do {
15856 zone->curmaster++;
15857 } while (zone->curmaster < zone->masterscnt &&
15858 zone->mastersok[zone->curmaster]);
15859 /* FALLTHROUGH */
15860 same_master:
15861 if (zone->curmaster >= zone->masterscnt) {
15862 zone->curmaster = 0;
15863 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
15864 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
15865 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
15866 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
15867 while (zone->curmaster < zone->masterscnt &&
15868 zone->mastersok[zone->curmaster])
15869 zone->curmaster++;
15870 again = true;
15871 } else
15872 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
15873 } else {
15874 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
15875 again = true;
15876 }
15877 inc_stats(zone, dns_zonestatscounter_xfrfail);
15878 break;
15879 }
15880 zone_settimer(zone, &now);
15881
15882 /*
15883 * If creating the transfer object failed, zone->xfr is NULL.
15884 * Otherwise, we are called as the done callback of a zone
15885 * transfer object that just entered its shutting-down
15886 * state. Since we are no longer responsible for shutting
15887 * it down, we can detach our reference.
15888 */
15889 if (zone->xfr != NULL)
15890 dns_xfrin_detach(&zone->xfr);
15891
15892 if (zone->tsigkey != NULL)
15893 dns_tsigkey_detach(&zone->tsigkey);
15894
15895 /*
15896 * Handle any deferred journal compaction.
15897 */
15898 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
15899 dns_db_t *db = NULL;
15900 if (dns_zone_getdb(zone, &db) == ISC_R_SUCCESS) {
15901 zone_journal_compact(zone, db, zone->compact_serial);
15902 dns_db_detach(&db);
15903 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
15904 }
15905 }
15906
15907 if (secure != NULL)
15908 UNLOCK_ZONE(secure);
15909 /*
15910 * This transfer finishing freed up a transfer quota slot.
15911 * Let any other zones waiting for quota have it.
15912 */
15913 if (zone->zmgr != NULL &&
15914 zone->statelist == &zone->zmgr->xfrin_in_progress) {
15915 UNLOCK_ZONE(zone);
15916 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
15917 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
15918 zone->statelist = NULL;
15919 zmgr_resume_xfrs(zone->zmgr, false);
15920 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
15921 LOCK_ZONE(zone);
15922 }
15923
15924 /*
15925 * Retry with a different server if necessary.
15926 */
15927 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
15928 queue_soa_query(zone);
15929
15930 INSIST(zone->irefs > 0);
15931 zone->irefs--;
15932 free_needed = exit_check(zone);
15933 UNLOCK_ZONE(zone);
15934 if (free_needed)
15935 zone_free(zone);
15936 }
15937
15938 static void
15939 zone_loaddone(void *arg, isc_result_t result) {
15940 static char me[] = "zone_loaddone";
15941 dns_load_t *load = arg;
15942 dns_zone_t *zone;
15943 isc_result_t tresult;
15944 dns_zone_t *secure = NULL;
15945
15946 REQUIRE(DNS_LOAD_VALID(load));
15947 zone = load->zone;
15948
15949 ENTER;
15950
15951 /*
15952 * If zone loading failed, remove the update db callbacks prior
15953 * to calling the list of callbacks in the zone load structure.
15954 */
15955 if (result != ISC_R_SUCCESS) {
15956 dns_zone_rpz_disable_db(zone, load->db);
15957 dns_zone_catz_disable_db(zone, load->db);
15958 }
15959
15960 tresult = dns_db_endload(load->db, &load->callbacks);
15961 if (tresult != ISC_R_SUCCESS &&
15962 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
15963 result = tresult;
15964
15965 /*
15966 * Lock hierarchy: zmgr, zone, raw.
15967 */
15968 again:
15969 LOCK_ZONE(zone);
15970 INSIST(zone != zone->raw);
15971 if (inline_secure(zone))
15972 LOCK_ZONE(zone->raw);
15973 else if (inline_raw(zone)) {
15974 secure = zone->secure;
15975 TRYLOCK_ZONE(tresult, secure);
15976 if (tresult != ISC_R_SUCCESS) {
15977 UNLOCK_ZONE(zone);
15978 secure = NULL;
15979 isc_thread_yield();
15980 goto again;
15981 }
15982 }
15983 (void)zone_postload(zone, load->db, load->loadtime, result);
15984 zonemgr_putio(&zone->readio);
15985 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING);
15986 zone_idetach(&load->callbacks.zone);
15987 /*
15988 * Leave the zone frozen if the reload fails.
15989 */
15990 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
15991 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW))
15992 zone->update_disabled = false;
15993 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW);
15994 if (inline_secure(zone))
15995 UNLOCK_ZONE(zone->raw);
15996 else if (secure != NULL)
15997 UNLOCK_ZONE(secure);
15998 UNLOCK_ZONE(zone);
15999
16000 load->magic = 0;
16001 dns_db_detach(&load->db);
16002 if (load->zone->lctx != NULL)
16003 dns_loadctx_detach(&load->zone->lctx);
16004 dns_zone_idetach(&load->zone);
16005 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
16006 }
16007
16008 void
16009 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
16010 REQUIRE(DNS_ZONE_VALID(zone));
16011 REQUIRE(table != NULL);
16012 REQUIRE(*table == NULL);
16013
16014 LOCK_ZONE(zone);
16015 if (zone->ssutable != NULL)
16016 dns_ssutable_attach(zone->ssutable, table);
16017 UNLOCK_ZONE(zone);
16018 }
16019
16020 void
16021 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
16022 REQUIRE(DNS_ZONE_VALID(zone));
16023
16024 LOCK_ZONE(zone);
16025 if (zone->ssutable != NULL)
16026 dns_ssutable_detach(&zone->ssutable);
16027 if (table != NULL)
16028 dns_ssutable_attach(table, &zone->ssutable);
16029 UNLOCK_ZONE(zone);
16030 }
16031
16032 void
16033 dns_zone_setsigvalidityinterval(dns_zone_t *zone, uint32_t interval) {
16034 REQUIRE(DNS_ZONE_VALID(zone));
16035
16036 zone->sigvalidityinterval = interval;
16037 }
16038
16039 uint32_t
16040 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
16041 REQUIRE(DNS_ZONE_VALID(zone));
16042
16043 return (zone->sigvalidityinterval);
16044 }
16045
16046 void
16047 dns_zone_setkeyvalidityinterval(dns_zone_t *zone, uint32_t interval) {
16048 REQUIRE(DNS_ZONE_VALID(zone));
16049
16050 zone->keyvalidityinterval = interval;
16051 }
16052
16053 uint32_t
16054 dns_zone_getkeyvalidityinterval(dns_zone_t *zone) {
16055 REQUIRE(DNS_ZONE_VALID(zone));
16056
16057 return (zone->keyvalidityinterval);
16058 }
16059
16060 void
16061 dns_zone_setsigresigninginterval(dns_zone_t *zone, uint32_t interval) {
16062 isc_time_t now;
16063
16064 REQUIRE(DNS_ZONE_VALID(zone));
16065
16066 LOCK_ZONE(zone);
16067 zone->sigresigninginterval = interval;
16068 set_resigntime(zone);
16069 if (zone->task != NULL) {
16070 TIME_NOW(&now);
16071 zone_settimer(zone, &now);
16072 }
16073 UNLOCK_ZONE(zone);
16074 }
16075
16076 uint32_t
16077 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
16078 REQUIRE(DNS_ZONE_VALID(zone));
16079
16080 return (zone->sigresigninginterval);
16081 }
16082
16083 static void
16084 queue_xfrin(dns_zone_t *zone) {
16085 const char me[] = "queue_xfrin";
16086 isc_result_t result;
16087 dns_zonemgr_t *zmgr = zone->zmgr;
16088
16089 ENTER;
16090
16091 INSIST(zone->statelist == NULL);
16092
16093 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16094 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
16095 LOCK_ZONE(zone);
16096 zone->irefs++;
16097 UNLOCK_ZONE(zone);
16098 zone->statelist = &zmgr->waiting_for_xfrin;
16099 result = zmgr_start_xfrin_ifquota(zmgr, zone);
16100 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16101
16102 if (result == ISC_R_QUOTA) {
16103 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
16104 "zone transfer deferred due to quota");
16105 } else if (result != ISC_R_SUCCESS) {
16106 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
16107 "starting zone transfer: %s",
16108 isc_result_totext(result));
16109 }
16110 }
16111
16112 /*
16113 * This event callback is called when a zone has received
16114 * any necessary zone transfer quota. This is the time
16115 * to go ahead and start the transfer.
16116 */
16117 static void
16118 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
16119 isc_result_t result = ISC_R_SUCCESS;
16120 dns_peer_t *peer = NULL;
16121 char master[ISC_SOCKADDR_FORMATSIZE];
16122 char source[ISC_SOCKADDR_FORMATSIZE];
16123 dns_rdatatype_t xfrtype;
16124 dns_zone_t *zone = event->ev_arg;
16125 isc_netaddr_t masterip;
16126 isc_sockaddr_t sourceaddr;
16127 isc_sockaddr_t masteraddr;
16128 isc_time_t now;
16129 const char *soa_before = "";
16130 isc_dscp_t dscp = -1;
16131 bool loaded;
16132
16133 UNUSED(task);
16134
16135 INSIST(task == zone->task);
16136
16137 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
16138 result = ISC_R_CANCELED;
16139 goto cleanup;
16140 }
16141
16142 TIME_NOW(&now);
16143
16144 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
16145 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
16146 &zone->sourceaddr, &now))
16147 {
16148 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
16149 dns_zone_log(zone, ISC_LOG_INFO,
16150 "got_transfer_quota: skipping zone transfer as "
16151 "master %s (source %s) is unreachable (cached)",
16152 master, source);
16153 result = ISC_R_CANCELED;
16154 goto cleanup;
16155 }
16156
16157 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
16158 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
16159
16160 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
16161 soa_before = "SOA before ";
16162 /*
16163 * Decide whether we should request IXFR or AXFR.
16164 */
16165 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
16166 loaded = (zone->db != NULL);
16167 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
16168
16169 if (!loaded) {
16170 dns_zone_log(zone, ISC_LOG_DEBUG(1),
16171 "no database exists yet, requesting AXFR of "
16172 "initial version from %s", master);
16173 xfrtype = dns_rdatatype_axfr;
16174 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
16175 dns_zone_log(zone, ISC_LOG_DEBUG(1),
16176 "forced reload, requesting AXFR of "
16177 "initial version from %s", master);
16178 xfrtype = dns_rdatatype_axfr;
16179 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
16180 dns_zone_log(zone, ISC_LOG_DEBUG(1),
16181 "retrying with AXFR from %s due to "
16182 "previous IXFR failure", master);
16183 xfrtype = dns_rdatatype_axfr;
16184 LOCK_ZONE(zone);
16185 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
16186 UNLOCK_ZONE(zone);
16187 } else {
16188 bool use_ixfr = true;
16189 if (peer != NULL)
16190 result = dns_peer_getrequestixfr(peer, &use_ixfr);
16191 if (peer == NULL || result != ISC_R_SUCCESS)
16192 use_ixfr = zone->requestixfr;
16193 if (use_ixfr == false) {
16194 dns_zone_log(zone, ISC_LOG_DEBUG(1),
16195 "IXFR disabled, requesting %sAXFR from %s",
16196 soa_before, master);
16197 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
16198 xfrtype = dns_rdatatype_soa;
16199 else
16200 xfrtype = dns_rdatatype_axfr;
16201 } else {
16202 dns_zone_log(zone, ISC_LOG_DEBUG(1),
16203 "requesting IXFR from %s", master);
16204 xfrtype = dns_rdatatype_ixfr;
16205 }
16206 }
16207
16208 /*
16209 * Determine if we should attempt to sign the request with TSIG.
16210 */
16211 result = ISC_R_NOTFOUND;
16212
16213 /*
16214 * First, look for a tsig key in the master statement, then
16215 * try for a server key.
16216 */
16217 if ((zone->masterkeynames != NULL) &&
16218 (zone->masterkeynames[zone->curmaster] != NULL)) {
16219 dns_view_t *view = dns_zone_getview(zone);
16220 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
16221 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
16222 }
16223 if (zone->tsigkey == NULL)
16224 result = dns_view_getpeertsig(zone->view, &masterip,
16225 &zone->tsigkey);
16226
16227 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
16228 dns_zone_log(zone, ISC_LOG_ERROR,
16229 "could not get TSIG key for zone transfer: %s",
16230 isc_result_totext(result));
16231 }
16232
16233 if (zone->masterdscps != NULL)
16234 dscp = zone->masterdscps[zone->curmaster];
16235
16236 LOCK_ZONE(zone);
16237 masteraddr = zone->masteraddr;
16238 sourceaddr = zone->sourceaddr;
16239 switch (isc_sockaddr_pf(&masteraddr)) {
16240 case PF_INET:
16241 if (dscp == -1)
16242 dscp = zone->xfrsource4dscp;
16243 break;
16244 case PF_INET6:
16245 if (dscp == -1)
16246 dscp = zone->xfrsource6dscp;
16247 break;
16248 default:
16249 INSIST(0);
16250 ISC_UNREACHABLE();
16251 }
16252 UNLOCK_ZONE(zone);
16253 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
16254 result = dns_xfrin_create(zone, xfrtype, &masteraddr, &sourceaddr,
16255 dscp, zone->tsigkey, zone->mctx,
16256 zone->zmgr->timermgr, zone->zmgr->socketmgr,
16257 zone->task, zone_xfrdone, &zone->xfr);
16258 if (result == ISC_R_SUCCESS) {
16259 LOCK_ZONE(zone);
16260 if (xfrtype == dns_rdatatype_axfr) {
16261 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
16262 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
16263 else
16264 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
16265 } else if (xfrtype == dns_rdatatype_ixfr) {
16266 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
16267 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
16268 else
16269 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
16270 }
16271 UNLOCK_ZONE(zone);
16272 }
16273 cleanup:
16274 /*
16275 * Any failure in this function is handled like a failed
16276 * zone transfer. This ensures that we get removed from
16277 * zmgr->xfrin_in_progress.
16278 */
16279 if (result != ISC_R_SUCCESS)
16280 zone_xfrdone(zone, result);
16281
16282 isc_event_free(&event);
16283 }
16284
16285 /*
16286 * Update forwarding support.
16287 */
16288
16289 static void
16290 forward_destroy(dns_forward_t *forward) {
16291
16292 forward->magic = 0;
16293 if (forward->request != NULL)
16294 dns_request_destroy(&forward->request);
16295 if (forward->msgbuf != NULL)
16296 isc_buffer_free(&forward->msgbuf);
16297 if (forward->zone != NULL) {
16298 LOCK(&forward->zone->lock);
16299 if (ISC_LINK_LINKED(forward, link))
16300 ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
16301 UNLOCK(&forward->zone->lock);
16302 dns_zone_idetach(&forward->zone);
16303 }
16304 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
16305 }
16306
16307 static isc_result_t
16308 sendtomaster(dns_forward_t *forward) {
16309 isc_result_t result;
16310 isc_sockaddr_t src;
16311 isc_dscp_t dscp = -1;
16312
16313 LOCK_ZONE(forward->zone);
16314
16315 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
16316 UNLOCK_ZONE(forward->zone);
16317 return (ISC_R_CANCELED);
16318 }
16319
16320 if (forward->which >= forward->zone->masterscnt) {
16321 UNLOCK_ZONE(forward->zone);
16322 return (ISC_R_NOMORE);
16323 }
16324
16325 forward->addr = forward->zone->masters[forward->which];
16326 /*
16327 * Always use TCP regardless of whether the original update
16328 * used TCP.
16329 * XXX The timeout may but a bit small if we are far down a
16330 * transfer graph and the master has to try several masters.
16331 */
16332 switch (isc_sockaddr_pf(&forward->addr)) {
16333 case PF_INET:
16334 src = forward->zone->xfrsource4;
16335 dscp = forward->zone->xfrsource4dscp;
16336 break;
16337 case PF_INET6:
16338 src = forward->zone->xfrsource6;
16339 dscp = forward->zone->xfrsource6dscp;
16340 break;
16341 default:
16342 result = ISC_R_NOTIMPLEMENTED;
16343 goto unlock;
16344 }
16345 result = dns_request_createraw(forward->zone->view->requestmgr,
16346 forward->msgbuf,
16347 &src, &forward->addr, dscp,
16348 forward->options, 15 /* XXX */,
16349 0, 0, forward->zone->task,
16350 forward_callback, forward,
16351 &forward->request);
16352 if (result == ISC_R_SUCCESS) {
16353 if (!ISC_LINK_LINKED(forward, link))
16354 ISC_LIST_APPEND(forward->zone->forwards, forward, link);
16355 }
16356
16357 unlock:
16358 UNLOCK_ZONE(forward->zone);
16359 return (result);
16360 }
16361
16362 static void
16363 forward_callback(isc_task_t *task, isc_event_t *event) {
16364 const char me[] = "forward_callback";
16365 dns_requestevent_t *revent = (dns_requestevent_t *)event;
16366 dns_message_t *msg = NULL;
16367 char master[ISC_SOCKADDR_FORMATSIZE];
16368 isc_result_t result;
16369 dns_forward_t *forward;
16370 dns_zone_t *zone;
16371
16372 UNUSED(task);
16373
16374 forward = revent->ev_arg;
16375 INSIST(DNS_FORWARD_VALID(forward));
16376 zone = forward->zone;
16377 INSIST(DNS_ZONE_VALID(zone));
16378
16379 ENTER;
16380
16381 isc_sockaddr_format(&forward->addr, master, sizeof(master));
16382
16383 if (revent->result != ISC_R_SUCCESS) {
16384 dns_zone_log(zone, ISC_LOG_INFO,
16385 "could not forward dynamic update to %s: %s",
16386 master, dns_result_totext(revent->result));
16387 goto next_master;
16388 }
16389
16390 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
16391 if (result != ISC_R_SUCCESS)
16392 goto next_master;
16393
16394 result = dns_request_getresponse(revent->request, msg,
16395 DNS_MESSAGEPARSE_PRESERVEORDER |
16396 DNS_MESSAGEPARSE_CLONEBUFFER);
16397 if (result != ISC_R_SUCCESS)
16398 goto next_master;
16399
16400 switch (msg->rcode) {
16401 /*
16402 * Pass these rcodes back to client.
16403 */
16404 case dns_rcode_noerror:
16405 case dns_rcode_yxdomain:
16406 case dns_rcode_yxrrset:
16407 case dns_rcode_nxrrset:
16408 case dns_rcode_refused:
16409 case dns_rcode_nxdomain: {
16410 char rcode[128];
16411 isc_buffer_t rb;
16412
16413 isc_buffer_init(&rb, rcode, sizeof(rcode));
16414 (void)dns_rcode_totext(msg->rcode, &rb);
16415 dns_zone_log(zone, ISC_LOG_INFO,
16416 "forwarded dynamic update: "
16417 "master %s returned: %.*s",
16418 master, (int)rb.used, rcode);
16419 break;
16420 }
16421
16422 /* These should not occur if the masters/zone are valid. */
16423 case dns_rcode_notzone:
16424 case dns_rcode_notauth: {
16425 char rcode[128];
16426 isc_buffer_t rb;
16427
16428 isc_buffer_init(&rb, rcode, sizeof(rcode));
16429 (void)dns_rcode_totext(msg->rcode, &rb);
16430 dns_zone_log(zone, ISC_LOG_WARNING,
16431 "forwarding dynamic update: "
16432 "unexpected response: master %s returned: %.*s",
16433 master, (int)rb.used, rcode);
16434 goto next_master;
16435 }
16436
16437 /* Try another server for these rcodes. */
16438 case dns_rcode_formerr:
16439 case dns_rcode_servfail:
16440 case dns_rcode_notimp:
16441 case dns_rcode_badvers:
16442 default:
16443 goto next_master;
16444 }
16445
16446 /* call callback */
16447 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
16448 msg = NULL;
16449 dns_request_destroy(&forward->request);
16450 forward_destroy(forward);
16451 isc_event_free(&event);
16452 return;
16453
16454 next_master:
16455 if (msg != NULL)
16456 dns_message_destroy(&msg);
16457 isc_event_free(&event);
16458 forward->which++;
16459 dns_request_destroy(&forward->request);
16460 result = sendtomaster(forward);
16461 if (result != ISC_R_SUCCESS) {
16462 /* call callback */
16463 dns_zone_log(zone, ISC_LOG_DEBUG(3),
16464 "exhausted dynamic update forwarder list");
16465 (forward->callback)(forward->callback_arg, result, NULL);
16466 forward_destroy(forward);
16467 }
16468 }
16469
16470 isc_result_t
16471 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
16472 dns_updatecallback_t callback, void *callback_arg)
16473 {
16474 dns_forward_t *forward;
16475 isc_result_t result;
16476 isc_region_t *mr;
16477
16478 REQUIRE(DNS_ZONE_VALID(zone));
16479 REQUIRE(msg != NULL);
16480 REQUIRE(callback != NULL);
16481
16482 forward = isc_mem_get(zone->mctx, sizeof(*forward));
16483 if (forward == NULL)
16484 return (ISC_R_NOMEMORY);
16485
16486 forward->request = NULL;
16487 forward->zone = NULL;
16488 forward->msgbuf = NULL;
16489 forward->which = 0;
16490 forward->mctx = 0;
16491 forward->callback = callback;
16492 forward->callback_arg = callback_arg;
16493 ISC_LINK_INIT(forward, link);
16494 forward->magic = FORWARD_MAGIC;
16495 forward->options = DNS_REQUESTOPT_TCP;
16496 /*
16497 * If we have a SIG(0) signed message we need to preserve the
16498 * query id as that is included in the SIG(0) computation.
16499 */
16500 if (msg->sig0 != NULL)
16501 forward->options |= DNS_REQUESTOPT_FIXEDID;
16502
16503 mr = dns_message_getrawmessage(msg);
16504 if (mr == NULL) {
16505 result = ISC_R_UNEXPECTEDEND;
16506 goto cleanup;
16507 }
16508
16509 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
16510 if (result != ISC_R_SUCCESS)
16511 goto cleanup;
16512 result = isc_buffer_copyregion(forward->msgbuf, mr);
16513 if (result != ISC_R_SUCCESS)
16514 goto cleanup;
16515
16516 isc_mem_attach(zone->mctx, &forward->mctx);
16517 dns_zone_iattach(zone, &forward->zone);
16518 result = sendtomaster(forward);
16519
16520 cleanup:
16521 if (result != ISC_R_SUCCESS) {
16522 forward_destroy(forward);
16523 }
16524 return (result);
16525 }
16526
16527 isc_result_t
16528 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
16529 REQUIRE(DNS_ZONE_VALID(zone));
16530 REQUIRE(next != NULL && *next == NULL);
16531
16532 *next = ISC_LIST_NEXT(zone, link);
16533 if (*next == NULL)
16534 return (ISC_R_NOMORE);
16535 else
16536 return (ISC_R_SUCCESS);
16537 }
16538
16539 isc_result_t
16540 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
16541 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16542 REQUIRE(first != NULL && *first == NULL);
16543
16544 *first = ISC_LIST_HEAD(zmgr->zones);
16545 if (*first == NULL)
16546 return (ISC_R_NOMORE);
16547 else
16548 return (ISC_R_SUCCESS);
16549 }
16550
16551 /***
16552 *** Zone manager.
16553 ***/
16554
16555 isc_result_t
16556 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
16557 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
16558 dns_zonemgr_t **zmgrp)
16559 {
16560 dns_zonemgr_t *zmgr;
16561 isc_result_t result;
16562
16563 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
16564 if (zmgr == NULL)
16565 return (ISC_R_NOMEMORY);
16566 zmgr->mctx = NULL;
16567 zmgr->refs = 1;
16568 isc_mem_attach(mctx, &zmgr->mctx);
16569 zmgr->taskmgr = taskmgr;
16570 zmgr->timermgr = timermgr;
16571 zmgr->socketmgr = socketmgr;
16572 zmgr->zonetasks = NULL;
16573 zmgr->loadtasks = NULL;
16574 zmgr->mctxpool = NULL;
16575 zmgr->task = NULL;
16576 zmgr->notifyrl = NULL;
16577 zmgr->refreshrl = NULL;
16578 zmgr->startupnotifyrl = NULL;
16579 zmgr->startuprefreshrl = NULL;
16580 ISC_LIST_INIT(zmgr->zones);
16581 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
16582 ISC_LIST_INIT(zmgr->xfrin_in_progress);
16583 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
16584 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
16585 if (result != ISC_R_SUCCESS)
16586 goto free_mem;
16587
16588 zmgr->transfersin = 10;
16589 zmgr->transfersperns = 2;
16590
16591 /* Unreachable lock. */
16592 result = isc_rwlock_init(&zmgr->urlock, 0, 0);
16593 if (result != ISC_R_SUCCESS)
16594 goto free_rwlock;
16595
16596 /* Create a single task for queueing of SOA queries. */
16597 result = isc_task_create(taskmgr, 1, &zmgr->task);
16598 if (result != ISC_R_SUCCESS)
16599 goto free_urlock;
16600
16601 isc_task_setname(zmgr->task, "zmgr", zmgr);
16602 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
16603 &zmgr->notifyrl);
16604 if (result != ISC_R_SUCCESS)
16605 goto free_task;
16606
16607 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
16608 &zmgr->refreshrl);
16609 if (result != ISC_R_SUCCESS)
16610 goto free_notifyrl;
16611
16612 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
16613 &zmgr->startupnotifyrl);
16614 if (result != ISC_R_SUCCESS)
16615 goto free_refreshrl;
16616
16617 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
16618 &zmgr->startuprefreshrl);
16619 if (result != ISC_R_SUCCESS)
16620 goto free_startupnotifyrl;
16621
16622 /* default to 20 refresh queries / notifies per second. */
16623 setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
16624 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
16625 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20);
16626 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20);
16627 isc_ratelimiter_setpushpop(zmgr->startupnotifyrl, true);
16628 isc_ratelimiter_setpushpop(zmgr->startuprefreshrl, true);
16629
16630 zmgr->iolimit = 1;
16631 zmgr->ioactive = 0;
16632 ISC_LIST_INIT(zmgr->high);
16633 ISC_LIST_INIT(zmgr->low);
16634
16635 isc_mutex_init(&zmgr->iolock);
16636
16637 zmgr->magic = ZONEMGR_MAGIC;
16638
16639 *zmgrp = zmgr;
16640 return (ISC_R_SUCCESS);
16641
16642 #if 0
16643 free_iolock:
16644 isc_mutex_destroy(&zmgr->iolock);
16645 #endif
16646 free_startupnotifyrl:
16647 isc_ratelimiter_detach(&zmgr->startupnotifyrl);
16648 free_refreshrl:
16649 isc_ratelimiter_detach(&zmgr->refreshrl);
16650 free_notifyrl:
16651 isc_ratelimiter_detach(&zmgr->notifyrl);
16652 free_task:
16653 isc_task_detach(&zmgr->task);
16654 free_urlock:
16655 isc_rwlock_destroy(&zmgr->urlock);
16656 free_rwlock:
16657 isc_rwlock_destroy(&zmgr->rwlock);
16658 free_mem:
16659 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
16660 isc_mem_detach(&mctx);
16661 return (result);
16662 }
16663
16664 isc_result_t
16665 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
16666 isc_result_t result;
16667 isc_mem_t *mctx = NULL;
16668 dns_zone_t *zone = NULL;
16669 void *item;
16670
16671 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16672 REQUIRE(zonep != NULL && *zonep == NULL);
16673
16674 if (zmgr->mctxpool == NULL)
16675 return (ISC_R_FAILURE);
16676
16677 item = isc_pool_get(zmgr->mctxpool);
16678 if (item == NULL)
16679 return (ISC_R_FAILURE);
16680
16681 isc_mem_attach((isc_mem_t *) item, &mctx);
16682 result = dns_zone_create(&zone, mctx);
16683 isc_mem_detach(&mctx);
16684
16685 if (result == ISC_R_SUCCESS)
16686 *zonep = zone;
16687
16688 return (result);
16689 }
16690
16691 isc_result_t
16692 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
16693 isc_result_t result;
16694
16695 REQUIRE(DNS_ZONE_VALID(zone));
16696 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16697
16698 if (zmgr->zonetasks == NULL)
16699 return (ISC_R_FAILURE);
16700
16701 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16702 LOCK_ZONE(zone);
16703 REQUIRE(zone->task == NULL);
16704 REQUIRE(zone->timer == NULL);
16705 REQUIRE(zone->zmgr == NULL);
16706
16707 isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
16708 isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
16709
16710 /*
16711 * Set the task name. The tag will arbitrarily point to one
16712 * of the zones sharing the task (in practice, the one
16713 * to be managed last).
16714 */
16715 isc_task_setname(zone->task, "zone", zone);
16716 isc_task_setname(zone->loadtask, "loadzone", zone);
16717
16718 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
16719 NULL, NULL,
16720 zone->task, zone_timer, zone,
16721 &zone->timer);
16722
16723 if (result != ISC_R_SUCCESS)
16724 goto cleanup_tasks;
16725
16726 /*
16727 * The timer "holds" a iref.
16728 */
16729 zone->irefs++;
16730 INSIST(zone->irefs != 0);
16731
16732 ISC_LIST_APPEND(zmgr->zones, zone, link);
16733 zone->zmgr = zmgr;
16734 zmgr->refs++;
16735
16736 goto unlock;
16737
16738 cleanup_tasks:
16739 isc_task_detach(&zone->loadtask);
16740 isc_task_detach(&zone->task);
16741
16742 unlock:
16743 UNLOCK_ZONE(zone);
16744 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16745 return (result);
16746 }
16747
16748 void
16749 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
16750 bool free_now = false;
16751
16752 REQUIRE(DNS_ZONE_VALID(zone));
16753 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16754 REQUIRE(zone->zmgr == zmgr);
16755
16756 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16757 LOCK_ZONE(zone);
16758
16759 ISC_LIST_UNLINK(zmgr->zones, zone, link);
16760 zone->zmgr = NULL;
16761 zmgr->refs--;
16762 if (zmgr->refs == 0)
16763 free_now = true;
16764
16765 UNLOCK_ZONE(zone);
16766 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16767
16768 if (free_now)
16769 zonemgr_free(zmgr);
16770 ENSURE(zone->zmgr == NULL);
16771 }
16772
16773 void
16774 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
16775 REQUIRE(DNS_ZONEMGR_VALID(source));
16776 REQUIRE(target != NULL && *target == NULL);
16777
16778 RWLOCK(&source->rwlock, isc_rwlocktype_write);
16779 REQUIRE(source->refs > 0);
16780 source->refs++;
16781 INSIST(source->refs > 0);
16782 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
16783 *target = source;
16784 }
16785
16786 void
16787 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
16788 dns_zonemgr_t *zmgr;
16789 bool free_now = false;
16790
16791 REQUIRE(zmgrp != NULL);
16792 zmgr = *zmgrp;
16793 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16794
16795 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16796 zmgr->refs--;
16797 if (zmgr->refs == 0)
16798 free_now = true;
16799 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16800
16801 if (free_now)
16802 zonemgr_free(zmgr);
16803 *zmgrp = NULL;
16804 }
16805
16806 isc_result_t
16807 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
16808 dns_zone_t *p;
16809
16810 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16811
16812 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
16813 for (p = ISC_LIST_HEAD(zmgr->zones);
16814 p != NULL;
16815 p = ISC_LIST_NEXT(p, link))
16816 {
16817 dns_zone_maintenance(p);
16818 }
16819 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
16820
16821 /*
16822 * Recent configuration changes may have increased the
16823 * amount of available transfers quota. Make sure any
16824 * transfers currently blocked on quota get started if
16825 * possible.
16826 */
16827 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16828 zmgr_resume_xfrs(zmgr, true);
16829 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16830 return (ISC_R_SUCCESS);
16831 }
16832
16833 void
16834 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
16835
16836 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16837
16838 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16839 zmgr_resume_xfrs(zmgr, true);
16840 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
16841 }
16842
16843 void
16844 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
16845 dns_zone_t *zone;
16846
16847 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16848
16849 isc_ratelimiter_shutdown(zmgr->notifyrl);
16850 isc_ratelimiter_shutdown(zmgr->refreshrl);
16851 isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
16852 isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
16853
16854 if (zmgr->task != NULL)
16855 isc_task_destroy(&zmgr->task);
16856 if (zmgr->zonetasks != NULL)
16857 isc_taskpool_destroy(&zmgr->zonetasks);
16858 if (zmgr->loadtasks != NULL)
16859 isc_taskpool_destroy(&zmgr->loadtasks);
16860 if (zmgr->mctxpool != NULL)
16861 isc_pool_destroy(&zmgr->mctxpool);
16862
16863 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
16864 for (zone = ISC_LIST_HEAD(zmgr->zones);
16865 zone != NULL;
16866 zone = ISC_LIST_NEXT(zone, link))
16867 {
16868 LOCK_ZONE(zone);
16869 forward_cancel(zone);
16870 UNLOCK_ZONE(zone);
16871 }
16872 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
16873 }
16874
16875 static isc_result_t
16876 mctxinit(void **target, void *arg) {
16877 isc_result_t result;
16878 isc_mem_t *mctx = NULL;
16879
16880 UNUSED(arg);
16881
16882 REQUIRE(target != NULL && *target == NULL);
16883
16884 result = isc_mem_create(0, 0, &mctx);
16885 if (result != ISC_R_SUCCESS)
16886 return (result);
16887 isc_mem_setname(mctx, "zonemgr-pool", NULL);
16888
16889 *target = mctx;
16890 return (ISC_R_SUCCESS);
16891 }
16892
16893 static void
16894 mctxfree(void **target) {
16895 isc_mem_t *mctx = *(isc_mem_t **) target;
16896 isc_mem_detach(&mctx);
16897 *target = NULL;
16898 }
16899
16900 #define ZONES_PER_TASK 100
16901 #define ZONES_PER_MCTX 1000
16902
16903 isc_result_t
16904 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
16905 isc_result_t result;
16906 int ntasks = num_zones / ZONES_PER_TASK;
16907 int nmctx = num_zones / ZONES_PER_MCTX;
16908 isc_taskpool_t *pool = NULL;
16909 isc_pool_t *mctxpool = NULL;
16910
16911 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16912
16913 /*
16914 * For anything fewer than 1000 zones we use 10 tasks in
16915 * the task pools. More than that, and we'll scale at one
16916 * task per 100 zones. Similarly, for anything smaller than
16917 * 2000 zones we use 2 memory contexts, then scale at 1:1000.
16918 */
16919 if (ntasks < 10)
16920 ntasks = 10;
16921 if (nmctx < 2)
16922 nmctx = 2;
16923
16924 /* Create or resize the zone task pools. */
16925 if (zmgr->zonetasks == NULL)
16926 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
16927 ntasks, 2, &pool);
16928 else
16929 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
16930
16931 if (result == ISC_R_SUCCESS)
16932 zmgr->zonetasks = pool;
16933
16934 pool = NULL;
16935 if (zmgr->loadtasks == NULL)
16936 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
16937 ntasks, 2, &pool);
16938 else
16939 result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool);
16940
16941 if (result == ISC_R_SUCCESS)
16942 zmgr->loadtasks = pool;
16943
16944 /*
16945 * We always set all tasks in the zone-load task pool to
16946 * privileged. This prevents other tasks in the system from
16947 * running while the server task manager is in privileged
16948 * mode.
16949 *
16950 * NOTE: If we start using task privileges for any other
16951 * part of the system than zone tasks, then this will need to be
16952 * revisted. In that case we'd want to turn on privileges for
16953 * zone tasks only when we were loading, and turn them off the
16954 * rest of the time. For now, however, it's okay to just
16955 * set it and forget it.
16956 */
16957 isc_taskpool_setprivilege(zmgr->loadtasks, true);
16958
16959 /* Create or resize the zone memory context pool. */
16960 if (zmgr->mctxpool == NULL)
16961 result = isc_pool_create(zmgr->mctx, nmctx, mctxfree,
16962 mctxinit, NULL, &mctxpool);
16963 else
16964 result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
16965
16966 if (result == ISC_R_SUCCESS)
16967 zmgr->mctxpool = mctxpool;
16968
16969 return (result);
16970 }
16971
16972 static void
16973 zonemgr_free(dns_zonemgr_t *zmgr) {
16974 isc_mem_t *mctx;
16975
16976 INSIST(zmgr->refs == 0);
16977 INSIST(ISC_LIST_EMPTY(zmgr->zones));
16978
16979 zmgr->magic = 0;
16980
16981 isc_mutex_destroy(&zmgr->iolock);
16982 isc_ratelimiter_detach(&zmgr->notifyrl);
16983 isc_ratelimiter_detach(&zmgr->refreshrl);
16984 isc_ratelimiter_detach(&zmgr->startupnotifyrl);
16985 isc_ratelimiter_detach(&zmgr->startuprefreshrl);
16986
16987 isc_rwlock_destroy(&zmgr->urlock);
16988 isc_rwlock_destroy(&zmgr->rwlock);
16989 mctx = zmgr->mctx;
16990 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
16991 isc_mem_detach(&mctx);
16992 }
16993
16994 void
16995 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value) {
16996 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
16997
16998 zmgr->transfersin = value;
16999 }
17000
17001 uint32_t
17002 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
17003 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17004
17005 return (zmgr->transfersin);
17006 }
17007
17008 void
17009 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, uint32_t value) {
17010 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17011
17012 zmgr->transfersperns = value;
17013 }
17014
17015 uint32_t
17016 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
17017 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17018
17019 return (zmgr->transfersperns);
17020 }
17021
17022 /*
17023 * Try to start a new incoming zone transfer to fill a quota
17024 * slot that was just vacated.
17025 *
17026 * Requires:
17027 * The zone manager is locked by the caller.
17028 */
17029 static void
17030 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi) {
17031 dns_zone_t *zone;
17032 dns_zone_t *next;
17033
17034 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
17035 zone != NULL;
17036 zone = next)
17037 {
17038 isc_result_t result;
17039 next = ISC_LIST_NEXT(zone, statelink);
17040 result = zmgr_start_xfrin_ifquota(zmgr, zone);
17041 if (result == ISC_R_SUCCESS) {
17042 if (multi)
17043 continue;
17044 /*
17045 * We successfully filled the slot. We're done.
17046 */
17047 break;
17048 } else if (result == ISC_R_QUOTA) {
17049 /*
17050 * Not enough quota. This is probably the per-server
17051 * quota, because we usually get called when a unit of
17052 * global quota has just been freed. Try the next
17053 * zone, it may succeed if it uses another master.
17054 */
17055 continue;
17056 } else {
17057 dns_zone_log(zone, ISC_LOG_DEBUG(1),
17058 "starting zone transfer: %s",
17059 isc_result_totext(result));
17060 break;
17061 }
17062 }
17063 }
17064
17065 /*
17066 * Try to start an incoming zone transfer for 'zone', quota permitting.
17067 *
17068 * Requires:
17069 * The zone manager is locked by the caller.
17070 *
17071 * Returns:
17072 * ISC_R_SUCCESS There was enough quota and we attempted to
17073 * start a transfer. zone_xfrdone() has been or will
17074 * be called.
17075 * ISC_R_QUOTA Not enough quota.
17076 * Others Failure.
17077 */
17078 static isc_result_t
17079 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
17080 dns_peer_t *peer = NULL;
17081 isc_netaddr_t masterip;
17082 uint32_t nxfrsin, nxfrsperns;
17083 dns_zone_t *x;
17084 uint32_t maxtransfersin, maxtransfersperns;
17085 isc_event_t *e;
17086
17087 /*
17088 * If we are exiting just pretend we got quota so the zone will
17089 * be cleaned up in the zone's task context.
17090 */
17091 LOCK_ZONE(zone);
17092 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
17093 UNLOCK_ZONE(zone);
17094 goto gotquota;
17095 }
17096
17097 /*
17098 * Find any configured information about the server we'd
17099 * like to transfer this zone from.
17100 */
17101 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
17102 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
17103 UNLOCK_ZONE(zone);
17104
17105 /*
17106 * Determine the total maximum number of simultaneous
17107 * transfers allowed, and the maximum for this specific
17108 * master.
17109 */
17110 maxtransfersin = zmgr->transfersin;
17111 maxtransfersperns = zmgr->transfersperns;
17112 if (peer != NULL)
17113 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
17114
17115 /*
17116 * Count the total number of transfers that are in progress,
17117 * and the number of transfers in progress from this master.
17118 * We linearly scan a list of all transfers; if this turns
17119 * out to be too slow, we could hash on the master address.
17120 */
17121 nxfrsin = nxfrsperns = 0;
17122 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
17123 x != NULL;
17124 x = ISC_LIST_NEXT(x, statelink))
17125 {
17126 isc_netaddr_t xip;
17127
17128 LOCK_ZONE(x);
17129 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
17130 UNLOCK_ZONE(x);
17131
17132 nxfrsin++;
17133 if (isc_netaddr_equal(&xip, &masterip))
17134 nxfrsperns++;
17135 }
17136
17137 /* Enforce quota. */
17138 if (nxfrsin >= maxtransfersin)
17139 return (ISC_R_QUOTA);
17140
17141 if (nxfrsperns >= maxtransfersperns)
17142 return (ISC_R_QUOTA);
17143
17144 gotquota:
17145 /*
17146 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
17147 * list and send it an event to let it start the actual transfer in the
17148 * context of its own task.
17149 */
17150 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
17151 got_transfer_quota, zone, sizeof(isc_event_t));
17152 if (e == NULL)
17153 return (ISC_R_NOMEMORY);
17154
17155 LOCK_ZONE(zone);
17156 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
17157 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
17158 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
17159 zone->statelist = &zmgr->xfrin_in_progress;
17160 isc_task_send(zone->task, &e);
17161 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
17162 UNLOCK_ZONE(zone);
17163
17164 return (ISC_R_SUCCESS);
17165 }
17166
17167 void
17168 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, uint32_t iolimit) {
17169
17170 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17171 REQUIRE(iolimit > 0);
17172
17173 zmgr->iolimit = iolimit;
17174 }
17175
17176 uint32_t
17177 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
17178
17179 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17180
17181 return (zmgr->iolimit);
17182 }
17183
17184 /*
17185 * Get permission to request a file handle from the OS.
17186 * An event will be sent to action when one is available.
17187 * There are two queues available (high and low), the high
17188 * queue will be serviced before the low one.
17189 *
17190 * zonemgr_putio() must be called after the event is delivered to
17191 * 'action'.
17192 */
17193
17194 static isc_result_t
17195 zonemgr_getio(dns_zonemgr_t *zmgr, bool high,
17196 isc_task_t *task, isc_taskaction_t action, void *arg,
17197 dns_io_t **iop)
17198 {
17199 dns_io_t *io;
17200 bool queue;
17201
17202 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17203 REQUIRE(iop != NULL && *iop == NULL);
17204
17205 io = isc_mem_get(zmgr->mctx, sizeof(*io));
17206 if (io == NULL)
17207 return (ISC_R_NOMEMORY);
17208
17209 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
17210 action, arg, sizeof(*io->event));
17211 if (io->event == NULL) {
17212 isc_mem_put(zmgr->mctx, io, sizeof(*io));
17213 return (ISC_R_NOMEMORY);
17214 }
17215
17216 io->zmgr = zmgr;
17217 io->high = high;
17218 io->task = NULL;
17219 isc_task_attach(task, &io->task);
17220 ISC_LINK_INIT(io, link);
17221 io->magic = IO_MAGIC;
17222
17223 LOCK(&zmgr->iolock);
17224 zmgr->ioactive++;
17225 queue = (zmgr->ioactive > zmgr->iolimit);
17226 if (queue) {
17227 if (io->high)
17228 ISC_LIST_APPEND(zmgr->high, io, link);
17229 else
17230 ISC_LIST_APPEND(zmgr->low, io, link);
17231 }
17232 UNLOCK(&zmgr->iolock);
17233 *iop = io;
17234
17235 if (!queue)
17236 isc_task_send(io->task, &io->event);
17237 return (ISC_R_SUCCESS);
17238 }
17239
17240 static void
17241 zonemgr_putio(dns_io_t **iop) {
17242 dns_io_t *io;
17243 dns_io_t *next;
17244 dns_zonemgr_t *zmgr;
17245
17246 REQUIRE(iop != NULL);
17247 io = *iop;
17248 REQUIRE(DNS_IO_VALID(io));
17249
17250 *iop = NULL;
17251
17252 INSIST(!ISC_LINK_LINKED(io, link));
17253 INSIST(io->event == NULL);
17254
17255 zmgr = io->zmgr;
17256 isc_task_detach(&io->task);
17257 io->magic = 0;
17258 isc_mem_put(zmgr->mctx, io, sizeof(*io));
17259
17260 LOCK(&zmgr->iolock);
17261 INSIST(zmgr->ioactive > 0);
17262 zmgr->ioactive--;
17263 next = HEAD(zmgr->high);
17264 if (next == NULL)
17265 next = HEAD(zmgr->low);
17266 if (next != NULL) {
17267 if (next->high)
17268 ISC_LIST_UNLINK(zmgr->high, next, link);
17269 else
17270 ISC_LIST_UNLINK(zmgr->low, next, link);
17271 INSIST(next->event != NULL);
17272 }
17273 UNLOCK(&zmgr->iolock);
17274 if (next != NULL)
17275 isc_task_send(next->task, &next->event);
17276 }
17277
17278 static void
17279 zonemgr_cancelio(dns_io_t *io) {
17280 bool send_event = false;
17281
17282 REQUIRE(DNS_IO_VALID(io));
17283
17284 /*
17285 * If we are queued to be run then dequeue.
17286 */
17287 LOCK(&io->zmgr->iolock);
17288 if (ISC_LINK_LINKED(io, link)) {
17289 if (io->high)
17290 ISC_LIST_UNLINK(io->zmgr->high, io, link);
17291 else
17292 ISC_LIST_UNLINK(io->zmgr->low, io, link);
17293
17294 send_event = true;
17295 INSIST(io->event != NULL);
17296 }
17297 UNLOCK(&io->zmgr->iolock);
17298 if (send_event) {
17299 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
17300 isc_task_send(io->task, &io->event);
17301 }
17302 }
17303
17304 static void
17305 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
17306 char *buf;
17307 int buflen;
17308 isc_result_t result;
17309
17310 buflen = strlen(path) + strlen(templat) + 2;
17311
17312 buf = isc_mem_get(zone->mctx, buflen);
17313 if (buf == NULL)
17314 return;
17315
17316 result = isc_file_template(path, templat, buf, buflen);
17317 if (result != ISC_R_SUCCESS)
17318 goto cleanup;
17319
17320 result = isc_file_renameunique(path, buf);
17321 if (result != ISC_R_SUCCESS)
17322 goto cleanup;
17323
17324 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
17325 "renaming file to '%s' for failure analysis and "
17326 "retransferring.", path, buf);
17327
17328 cleanup:
17329 isc_mem_put(zone->mctx, buf, buflen);
17330 }
17331
17332 static void
17333 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
17334 isc_interval_t interval;
17335 uint32_t s, ns;
17336 uint32_t pertic;
17337 isc_result_t result;
17338
17339 if (value == 0)
17340 value = 1;
17341
17342 if (value == 1) {
17343 s = 1;
17344 ns = 0;
17345 pertic = 1;
17346 } else if (value <= 10) {
17347 s = 0;
17348 ns = 1000000000 / value;
17349 pertic = 1;
17350 } else {
17351 s = 0;
17352 ns = (1000000000 / value) * 10;
17353 pertic = 10;
17354 }
17355
17356 isc_interval_set(&interval, s, ns);
17357
17358 result = isc_ratelimiter_setinterval(rl, &interval);
17359 RUNTIME_CHECK(result == ISC_R_SUCCESS);
17360 isc_ratelimiter_setpertic(rl, pertic);
17361
17362 *rate = value;
17363 }
17364
17365 void
17366 dns_zonemgr_setnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
17367
17368 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17369
17370 setrl(zmgr->notifyrl, &zmgr->notifyrate, value);
17371 }
17372
17373 void
17374 dns_zonemgr_setstartupnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
17375
17376 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17377
17378 setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value);
17379 }
17380
17381 void
17382 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
17383
17384 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17385
17386 setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value);
17387 /* XXXMPA seperate out once we have the code to support this. */
17388 setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value);
17389 }
17390
17391 unsigned int
17392 dns_zonemgr_getnotifyrate(dns_zonemgr_t *zmgr) {
17393 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17394
17395 return (zmgr->notifyrate);
17396 }
17397
17398 unsigned int
17399 dns_zonemgr_getstartupnotifyrate(dns_zonemgr_t *zmgr) {
17400 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17401
17402 return (zmgr->startupnotifyrate);
17403 }
17404
17405 unsigned int
17406 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
17407 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17408
17409 return (zmgr->serialqueryrate);
17410 }
17411
17412 bool
17413 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
17414 isc_sockaddr_t *local, isc_time_t *now)
17415 {
17416 unsigned int i;
17417 isc_rwlocktype_t locktype;
17418 isc_result_t result;
17419 uint32_t seconds = isc_time_seconds(now);
17420 uint32_t count = 0;
17421
17422 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17423
17424 locktype = isc_rwlocktype_read;
17425 RWLOCK(&zmgr->urlock, locktype);
17426 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
17427 if (zmgr->unreachable[i].expire >= seconds &&
17428 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
17429 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
17430 result = isc_rwlock_tryupgrade(&zmgr->urlock);
17431 if (result == ISC_R_SUCCESS) {
17432 locktype = isc_rwlocktype_write;
17433 zmgr->unreachable[i].last = seconds;
17434 count = zmgr->unreachable[i].count;
17435 }
17436 break;
17437 }
17438 }
17439 RWUNLOCK(&zmgr->urlock, locktype);
17440 return (i < UNREACH_CHACHE_SIZE && count > 1U);
17441 }
17442
17443 void
17444 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
17445 isc_sockaddr_t *local)
17446 {
17447 unsigned int i;
17448 isc_rwlocktype_t locktype;
17449 isc_result_t result;
17450
17451 char master[ISC_SOCKADDR_FORMATSIZE];
17452 char source[ISC_SOCKADDR_FORMATSIZE];
17453
17454 isc_sockaddr_format(remote, master, sizeof(master));
17455 isc_sockaddr_format(local, source, sizeof(source));
17456
17457 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17458
17459 locktype = isc_rwlocktype_read;
17460 RWLOCK(&zmgr->urlock, locktype);
17461 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
17462 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
17463 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
17464 if (zmgr->unreachable[i].expire == 0)
17465 break;
17466 result = isc_rwlock_tryupgrade(&zmgr->urlock);
17467 if (result == ISC_R_SUCCESS) {
17468 locktype = isc_rwlocktype_write;
17469 zmgr->unreachable[i].expire = 0;
17470 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
17471 DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
17472 "master %s (source %s) deleted "
17473 "from unreachable cache",
17474 master, source);
17475 }
17476 break;
17477 }
17478 }
17479 RWUNLOCK(&zmgr->urlock, locktype);
17480 }
17481
17482 void
17483 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
17484 isc_sockaddr_t *local, isc_time_t *now)
17485 {
17486 uint32_t seconds = isc_time_seconds(now);
17487 uint32_t last = seconds;
17488 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
17489
17490 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17491
17492 RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
17493 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
17494 /* Existing entry? */
17495 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
17496 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
17497 break;
17498 /* Empty slot? */
17499 if (zmgr->unreachable[i].expire < seconds)
17500 slot = i;
17501 /* Least recently used slot? */
17502 if (zmgr->unreachable[i].last < last) {
17503 last = zmgr->unreachable[i].last;
17504 oldest = i;
17505 }
17506 }
17507 if (i < UNREACH_CHACHE_SIZE) {
17508 /*
17509 * Found a existing entry. Update the expire timer and
17510 * last usage timestamps.
17511 */
17512 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
17513 zmgr->unreachable[i].last = seconds;
17514 if (zmgr->unreachable[i].expire < seconds)
17515 zmgr->unreachable[i].count = 1;
17516 else
17517 zmgr->unreachable[i].count++;
17518 } else if (slot != UNREACH_CHACHE_SIZE) {
17519 /*
17520 * Found a empty slot. Add a new entry to the cache.
17521 */
17522 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
17523 zmgr->unreachable[slot].last = seconds;
17524 zmgr->unreachable[slot].remote = *remote;
17525 zmgr->unreachable[slot].local = *local;
17526 zmgr->unreachable[slot].count = 1;
17527 } else {
17528 /*
17529 * Replace the least recently used entry in the cache.
17530 */
17531 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
17532 zmgr->unreachable[oldest].last = seconds;
17533 zmgr->unreachable[oldest].remote = *remote;
17534 zmgr->unreachable[oldest].local = *local;
17535 zmgr->unreachable[oldest].count = 1;
17536 }
17537 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
17538 }
17539
17540 void
17541 dns_zone_forcereload(dns_zone_t *zone) {
17542 REQUIRE(DNS_ZONE_VALID(zone));
17543
17544 if (zone->type == dns_zone_master ||
17545 (zone->type == dns_zone_redirect && zone->masters == NULL))
17546 return;
17547
17548 LOCK_ZONE(zone);
17549 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
17550 UNLOCK_ZONE(zone);
17551 dns_zone_refresh(zone);
17552 }
17553
17554 bool
17555 dns_zone_isforced(dns_zone_t *zone) {
17556 REQUIRE(DNS_ZONE_VALID(zone));
17557
17558 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
17559 }
17560
17561 isc_result_t
17562 dns_zone_setstatistics(dns_zone_t *zone, bool on) {
17563 /*
17564 * This function is obsoleted.
17565 */
17566 UNUSED(zone);
17567 UNUSED(on);
17568 return (ISC_R_NOTIMPLEMENTED);
17569 }
17570
17571 uint64_t *
17572 dns_zone_getstatscounters(dns_zone_t *zone) {
17573 /*
17574 * This function is obsoleted.
17575 */
17576 UNUSED(zone);
17577 return (NULL);
17578 }
17579
17580 void
17581 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
17582 REQUIRE(DNS_ZONE_VALID(zone));
17583 REQUIRE(zone->stats == NULL);
17584
17585 LOCK_ZONE(zone);
17586 zone->stats = NULL;
17587 isc_stats_attach(stats, &zone->stats);
17588 UNLOCK_ZONE(zone);
17589 }
17590
17591 void
17592 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
17593
17594 REQUIRE(DNS_ZONE_VALID(zone));
17595
17596 LOCK_ZONE(zone);
17597 if (zone->requeststats_on && stats == NULL)
17598 zone->requeststats_on = false;
17599 else if (!zone->requeststats_on && stats != NULL) {
17600 if (zone->requeststats == NULL) {
17601 isc_stats_attach(stats, &zone->requeststats);
17602 zone->requeststats_on = true;
17603 }
17604 }
17605 UNLOCK_ZONE(zone);
17606 }
17607
17608 void
17609 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
17610
17611 REQUIRE(DNS_ZONE_VALID(zone));
17612
17613 LOCK_ZONE(zone);
17614 if (zone->requeststats_on && stats != NULL) {
17615 if (zone->rcvquerystats == NULL) {
17616 dns_stats_attach(stats, &zone->rcvquerystats);
17617 zone->requeststats_on = true;
17618 }
17619 }
17620 UNLOCK_ZONE(zone);
17621 }
17622
17623 void
17624 dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats) {
17625 REQUIRE(DNS_ZONE_VALID(zone));
17626
17627 LOCK_ZONE(zone);
17628 if (stats != NULL && zone->dnssecsignstats == NULL) {
17629 dns_stats_attach(stats, &zone->dnssecsignstats);
17630 }
17631 UNLOCK_ZONE(zone);
17632 }
17633
17634 void
17635 dns_zone_setdnssecrefreshstats(dns_zone_t *zone, dns_stats_t *stats) {
17636 REQUIRE(DNS_ZONE_VALID(zone));
17637
17638 LOCK_ZONE(zone);
17639 if (stats != NULL && zone->dnssecrefreshstats == NULL) {
17640 dns_stats_attach(stats, &zone->dnssecrefreshstats);
17641 }
17642 UNLOCK_ZONE(zone);
17643 }
17644
17645 dns_stats_t*
17646 dns_zone_getdnssecsignstats(dns_zone_t *zone) {
17647 REQUIRE(DNS_ZONE_VALID(zone));
17648
17649 return (zone->dnssecsignstats);
17650 }
17651
17652 dns_stats_t*
17653 dns_zone_getdnssecrefreshstats(dns_zone_t *zone) {
17654 REQUIRE(DNS_ZONE_VALID(zone));
17655
17656 return (zone->dnssecrefreshstats);
17657 }
17658
17659 isc_stats_t *
17660 dns_zone_getrequeststats(dns_zone_t *zone) {
17661 /*
17662 * We don't lock zone for efficiency reason. This is not catastrophic
17663 * because requeststats must always be valid when requeststats_on is
17664 * true.
17665 * Some counters may be incremented while requeststats_on is becoming
17666 * false, or some cannot be incremented just after the statistics are
17667 * installed, but it shouldn't matter much in practice.
17668 */
17669 if (zone->requeststats_on)
17670 return (zone->requeststats);
17671 else
17672 return (NULL);
17673 }
17674
17675 /*
17676 * Return the received query stats bucket
17677 * see note from dns_zone_getrequeststats()
17678 */
17679 dns_stats_t *
17680 dns_zone_getrcvquerystats(dns_zone_t *zone) {
17681 if (zone->requeststats_on)
17682 return (zone->rcvquerystats);
17683 else
17684 return (NULL);
17685 }
17686
17687 void
17688 dns_zone_dialup(dns_zone_t *zone) {
17689
17690 REQUIRE(DNS_ZONE_VALID(zone));
17691
17692 zone_debuglog(zone, "dns_zone_dialup", 3,
17693 "notify = %d, refresh = %d",
17694 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
17695 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
17696
17697 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
17698 dns_zone_notify(zone);
17699 if (zone->type != dns_zone_master && zone->masters != NULL &&
17700 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
17701 dns_zone_refresh(zone);
17702 }
17703
17704 void
17705 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
17706 REQUIRE(DNS_ZONE_VALID(zone));
17707
17708 LOCK_ZONE(zone);
17709 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
17710 DNS_ZONEFLG_DIALREFRESH |
17711 DNS_ZONEFLG_NOREFRESH);
17712 switch (dialup) {
17713 case dns_dialuptype_no:
17714 break;
17715 case dns_dialuptype_yes:
17716 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
17717 DNS_ZONEFLG_DIALREFRESH |
17718 DNS_ZONEFLG_NOREFRESH));
17719 break;
17720 case dns_dialuptype_notify:
17721 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
17722 break;
17723 case dns_dialuptype_notifypassive:
17724 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
17725 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
17726 break;
17727 case dns_dialuptype_refresh:
17728 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
17729 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
17730 break;
17731 case dns_dialuptype_passive:
17732 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
17733 break;
17734 default:
17735 INSIST(0);
17736 ISC_UNREACHABLE();
17737 }
17738 UNLOCK_ZONE(zone);
17739 }
17740
17741 isc_result_t
17742 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
17743 isc_result_t result = ISC_R_SUCCESS;
17744
17745 REQUIRE(DNS_ZONE_VALID(zone));
17746
17747 LOCK_ZONE(zone);
17748 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
17749 UNLOCK_ZONE(zone);
17750
17751 return (result);
17752 }
17753
17754 const char *
17755 dns_zone_getkeydirectory(dns_zone_t *zone) {
17756 REQUIRE(DNS_ZONE_VALID(zone));
17757
17758 return (zone->keydirectory);
17759 }
17760
17761 unsigned int
17762 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
17763 dns_zone_t *zone;
17764 unsigned int count = 0;
17765
17766 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
17767
17768 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
17769 switch (state) {
17770 case DNS_ZONESTATE_XFERRUNNING:
17771 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
17772 zone != NULL;
17773 zone = ISC_LIST_NEXT(zone, statelink))
17774 count++;
17775 break;
17776 case DNS_ZONESTATE_XFERDEFERRED:
17777 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
17778 zone != NULL;
17779 zone = ISC_LIST_NEXT(zone, statelink))
17780 count++;
17781 break;
17782 case DNS_ZONESTATE_SOAQUERY:
17783 for (zone = ISC_LIST_HEAD(zmgr->zones);
17784 zone != NULL;
17785 zone = ISC_LIST_NEXT(zone, link))
17786 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
17787 count++;
17788 break;
17789 case DNS_ZONESTATE_ANY:
17790 for (zone = ISC_LIST_HEAD(zmgr->zones);
17791 zone != NULL;
17792 zone = ISC_LIST_NEXT(zone, link)) {
17793 dns_view_t *view = zone->view;
17794 if (view != NULL && strcmp(view->name, "_bind") == 0)
17795 continue;
17796 count++;
17797 }
17798 break;
17799 case DNS_ZONESTATE_AUTOMATIC:
17800 for (zone = ISC_LIST_HEAD(zmgr->zones);
17801 zone != NULL;
17802 zone = ISC_LIST_NEXT(zone, link)) {
17803 dns_view_t *view = zone->view;
17804 if (view != NULL && strcmp(view->name, "_bind") == 0)
17805 continue;
17806 if (zone->automatic)
17807 count++;
17808 }
17809 break;
17810 default:
17811 INSIST(0);
17812 ISC_UNREACHABLE();
17813 }
17814
17815 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
17816
17817 return (count);
17818 }
17819
17820 isc_result_t
17821 dns_zone_checknames(dns_zone_t *zone, const dns_name_t *name,
17822 dns_rdata_t *rdata)
17823 {
17824 bool ok = true;
17825 bool fail = false;
17826 char namebuf[DNS_NAME_FORMATSIZE];
17827 char namebuf2[DNS_NAME_FORMATSIZE];
17828 char typebuf[DNS_RDATATYPE_FORMATSIZE];
17829 int level = ISC_LOG_WARNING;
17830 dns_name_t bad;
17831
17832 REQUIRE(DNS_ZONE_VALID(zone));
17833
17834 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) &&
17835 rdata->type != dns_rdatatype_nsec3)
17836 return (ISC_R_SUCCESS);
17837
17838 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) ||
17839 rdata->type == dns_rdatatype_nsec3) {
17840 level = ISC_LOG_ERROR;
17841 fail = true;
17842 }
17843
17844 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, true);
17845 if (!ok) {
17846 dns_name_format(name, namebuf, sizeof(namebuf));
17847 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
17848 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
17849 dns_result_totext(DNS_R_BADOWNERNAME));
17850 if (fail)
17851 return (DNS_R_BADOWNERNAME);
17852 }
17853
17854 dns_name_init(&bad, NULL);
17855 ok = dns_rdata_checknames(rdata, name, &bad);
17856 if (!ok) {
17857 dns_name_format(name, namebuf, sizeof(namebuf));
17858 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
17859 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
17860 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
17861 namebuf2, dns_result_totext(DNS_R_BADNAME));
17862 if (fail)
17863 return (DNS_R_BADNAME);
17864 }
17865
17866 return (ISC_R_SUCCESS);
17867 }
17868
17869 void
17870 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
17871 REQUIRE(DNS_ZONE_VALID(zone));
17872 zone->checkmx = checkmx;
17873 }
17874
17875 void
17876 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
17877 REQUIRE(DNS_ZONE_VALID(zone));
17878 zone->checksrv = checksrv;
17879 }
17880
17881 void
17882 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
17883 REQUIRE(DNS_ZONE_VALID(zone));
17884 zone->checkns = checkns;
17885 }
17886
17887 void
17888 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
17889 REQUIRE(DNS_ZONE_VALID(zone));
17890
17891 LOCK_ZONE(zone);
17892 zone->isself = isself;
17893 zone->isselfarg = arg;
17894 UNLOCK_ZONE(zone);
17895 }
17896
17897 void
17898 dns_zone_setnotifydelay(dns_zone_t *zone, uint32_t delay) {
17899 REQUIRE(DNS_ZONE_VALID(zone));
17900
17901 LOCK_ZONE(zone);
17902 zone->notifydelay = delay;
17903 UNLOCK_ZONE(zone);
17904 }
17905
17906 uint32_t
17907 dns_zone_getnotifydelay(dns_zone_t *zone) {
17908 REQUIRE(DNS_ZONE_VALID(zone));
17909
17910 return (zone->notifydelay);
17911 }
17912
17913 isc_result_t
17914 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
17915 uint16_t keyid, bool deleteit)
17916 {
17917 isc_result_t result;
17918 REQUIRE(DNS_ZONE_VALID(zone));
17919
17920 dnssec_log(zone, ISC_LOG_NOTICE,
17921 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
17922 algorithm, keyid);
17923 LOCK_ZONE(zone);
17924 result = zone_signwithkey(zone, algorithm, keyid, deleteit);
17925 UNLOCK_ZONE(zone);
17926
17927 return (result);
17928 }
17929
17930 /*
17931 * Called when a dynamic update for an NSEC3PARAM record is received.
17932 *
17933 * If set, transform the NSEC3 salt into human-readable form so that it can be
17934 * logged. Then call zone_addnsec3chain(), passing NSEC3PARAM RDATA to it.
17935 */
17936 isc_result_t
17937 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
17938 isc_result_t result;
17939 char salt[255*2+1];
17940
17941 REQUIRE(DNS_ZONE_VALID(zone));
17942
17943 result = dns_nsec3param_salttotext(nsec3param, salt, sizeof(salt));
17944 RUNTIME_CHECK(result == ISC_R_SUCCESS);
17945 dnssec_log(zone, ISC_LOG_NOTICE,
17946 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
17947 nsec3param->hash, nsec3param->iterations, salt);
17948 LOCK_ZONE(zone);
17949 result = zone_addnsec3chain(zone, nsec3param);
17950 UNLOCK_ZONE(zone);
17951
17952 return (result);
17953 }
17954
17955 void
17956 dns_zone_setnodes(dns_zone_t *zone, uint32_t nodes) {
17957 REQUIRE(DNS_ZONE_VALID(zone));
17958
17959 if (nodes == 0)
17960 nodes = 1;
17961 zone->nodes = nodes;
17962 }
17963
17964 void
17965 dns_zone_setsignatures(dns_zone_t *zone, uint32_t signatures) {
17966 REQUIRE(DNS_ZONE_VALID(zone));
17967
17968 /*
17969 * We treat signatures as a signed value so explicitly
17970 * limit its range here.
17971 */
17972 if (signatures > INT32_MAX)
17973 signatures = INT32_MAX;
17974 else if (signatures == 0)
17975 signatures = 1;
17976 zone->signatures = signatures;
17977 }
17978
17979 uint32_t
17980 dns_zone_getsignatures(dns_zone_t *zone) {
17981 REQUIRE(DNS_ZONE_VALID(zone));
17982 return (zone->signatures);
17983 }
17984
17985 void
17986 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
17987 REQUIRE(DNS_ZONE_VALID(zone));
17988 zone->privatetype = type;
17989 }
17990
17991 dns_rdatatype_t
17992 dns_zone_getprivatetype(dns_zone_t *zone) {
17993 REQUIRE(DNS_ZONE_VALID(zone));
17994 return (zone->privatetype);
17995 }
17996
17997 static isc_result_t
17998 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid,
17999 bool deleteit)
18000 {
18001 dns_signing_t *signing;
18002 dns_signing_t *current;
18003 isc_result_t result = ISC_R_SUCCESS;
18004 isc_time_t now;
18005 dns_db_t *db = NULL;
18006
18007 signing = isc_mem_get(zone->mctx, sizeof *signing);
18008 if (signing == NULL)
18009 return (ISC_R_NOMEMORY);
18010
18011 signing->magic = 0;
18012 signing->db = NULL;
18013 signing->dbiterator = NULL;
18014 signing->algorithm = algorithm;
18015 signing->keyid = keyid;
18016 signing->deleteit = deleteit;
18017 signing->done = false;
18018
18019 TIME_NOW(&now);
18020
18021 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
18022 if (zone->db != NULL)
18023 dns_db_attach(zone->db, &db);
18024 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
18025
18026 if (db == NULL) {
18027 result = ISC_R_NOTFOUND;
18028 goto cleanup;
18029 }
18030
18031 dns_db_attach(db, &signing->db);
18032
18033 for (current = ISC_LIST_HEAD(zone->signing);
18034 current != NULL;
18035 current = ISC_LIST_NEXT(current, link)) {
18036 if (current->db == signing->db &&
18037 current->algorithm == signing->algorithm &&
18038 current->keyid == signing->keyid) {
18039 if (current->deleteit != signing->deleteit)
18040 current->done = true;
18041 else
18042 goto cleanup;
18043 }
18044 }
18045
18046 result = dns_db_createiterator(signing->db, 0,
18047 &signing->dbiterator);
18048
18049 if (result == ISC_R_SUCCESS)
18050 result = dns_dbiterator_first(signing->dbiterator);
18051 if (result == ISC_R_SUCCESS) {
18052 dns_dbiterator_pause(signing->dbiterator);
18053 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
18054 signing = NULL;
18055 if (isc_time_isepoch(&zone->signingtime)) {
18056 zone->signingtime = now;
18057 if (zone->task != NULL)
18058 zone_settimer(zone, &now);
18059 }
18060 }
18061
18062 cleanup:
18063 if (signing != NULL) {
18064 if (signing->db != NULL)
18065 dns_db_detach(&signing->db);
18066 if (signing->dbiterator != NULL)
18067 dns_dbiterator_destroy(&signing->dbiterator);
18068 isc_mem_put(zone->mctx, signing, sizeof *signing);
18069 }
18070 if (db != NULL)
18071 dns_db_detach(&db);
18072 return (result);
18073 }
18074
18075 static void
18076 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
18077 dns_dnsseckey_t *key;
18078 while (!ISC_LIST_EMPTY(*list)) {
18079 key = ISC_LIST_HEAD(*list);
18080 ISC_LIST_UNLINK(*list, key, link);
18081 dns_dnsseckey_destroy(mctx, &key);
18082 }
18083 }
18084
18085 /* Called once; *timep should be set to the current time. */
18086 static isc_result_t
18087 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
18088 isc_result_t result;
18089 isc_stdtime_t now, then = 0, event;
18090 int i;
18091
18092 now = *timep;
18093
18094 for (i = 0; i <= DST_MAX_TIMES; i++) {
18095 result = dst_key_gettime(key, i, &event);
18096 if (result == ISC_R_SUCCESS && event > now &&
18097 (then == 0 || event < then))
18098 then = event;
18099 }
18100
18101 if (then != 0) {
18102 *timep = then;
18103 return (ISC_R_SUCCESS);
18104 }
18105
18106 return (ISC_R_NOTFOUND);
18107 }
18108
18109 static isc_result_t
18110 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
18111 const dns_rdata_t *rdata, bool *flag)
18112 {
18113 dns_rdataset_t rdataset;
18114 dns_dbnode_t *node = NULL;
18115 isc_result_t result;
18116
18117 dns_rdataset_init(&rdataset);
18118 if (rdata->type == dns_rdatatype_nsec3)
18119 CHECK(dns_db_findnsec3node(db, name, false, &node));
18120 else
18121 CHECK(dns_db_findnode(db, name, false, &node));
18122 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
18123 (isc_stdtime_t) 0, &rdataset, NULL);
18124 if (result == ISC_R_NOTFOUND) {
18125 *flag = false;
18126 result = ISC_R_SUCCESS;
18127 goto failure;
18128 }
18129
18130 for (result = dns_rdataset_first(&rdataset);
18131 result == ISC_R_SUCCESS;
18132 result = dns_rdataset_next(&rdataset)) {
18133 dns_rdata_t myrdata = DNS_RDATA_INIT;
18134 dns_rdataset_current(&rdataset, &myrdata);
18135 if (!dns_rdata_compare(&myrdata, rdata))
18136 break;
18137 }
18138 dns_rdataset_disassociate(&rdataset);
18139 if (result == ISC_R_SUCCESS) {
18140 *flag = true;
18141 } else if (result == ISC_R_NOMORE) {
18142 *flag = false;
18143 result = ISC_R_SUCCESS;
18144 }
18145
18146 failure:
18147 if (node != NULL)
18148 dns_db_detachnode(db, &node);
18149 return (result);
18150 }
18151
18152 /*
18153 * Add records to signal the state of signing or of key removal.
18154 */
18155 static isc_result_t
18156 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
18157 dns_dbversion_t *ver, dns_diff_t *diff, bool sign_all)
18158 {
18159 dns_difftuple_t *tuple, *newtuple = NULL;
18160 dns_rdata_dnskey_t dnskey;
18161 dns_rdata_t rdata = DNS_RDATA_INIT;
18162 bool flag;
18163 isc_region_t r;
18164 isc_result_t result = ISC_R_SUCCESS;
18165 uint16_t keyid;
18166 unsigned char buf[5];
18167 dns_name_t *name = dns_db_origin(db);
18168
18169 for (tuple = ISC_LIST_HEAD(diff->tuples);
18170 tuple != NULL;
18171 tuple = ISC_LIST_NEXT(tuple, link)) {
18172 if (tuple->rdata.type != dns_rdatatype_dnskey) {
18173 continue;
18174 }
18175
18176 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
18177 RUNTIME_CHECK(result == ISC_R_SUCCESS);
18178 if ((dnskey.flags &
18179 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
18180 != DNS_KEYOWNER_ZONE)
18181 {
18182 continue;
18183 }
18184
18185 dns_rdata_toregion(&tuple->rdata, &r);
18186
18187 keyid = dst_region_computeid(&r);
18188
18189 buf[0] = dnskey.algorithm;
18190 buf[1] = (keyid & 0xff00) >> 8;
18191 buf[2] = (keyid & 0xff);
18192 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
18193 buf[4] = 0;
18194 rdata.data = buf;
18195 rdata.length = sizeof(buf);
18196 rdata.type = privatetype;
18197 rdata.rdclass = tuple->rdata.rdclass;
18198
18199 if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
18200 CHECK(rr_exists(db, ver, name, &rdata, &flag));
18201 if (flag) {
18202 continue;
18203 }
18204
18205 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
18206 name, 0, &rdata, &newtuple));
18207 CHECK(do_one_tuple(&newtuple, db, ver, diff));
18208 INSIST(newtuple == NULL);
18209 }
18210
18211 /*
18212 * Remove any record which says this operation has already
18213 * completed.
18214 */
18215 buf[4] = 1;
18216 CHECK(rr_exists(db, ver, name, &rdata, &flag));
18217 if (flag) {
18218 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
18219 name, 0, &rdata, &newtuple));
18220 CHECK(do_one_tuple(&newtuple, db, ver, diff));
18221 INSIST(newtuple == NULL);
18222 }
18223 }
18224 failure:
18225 return (result);
18226 }
18227
18228 static isc_result_t
18229 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
18230 isc_stdtime_t now, dns_diff_t *diff, dns__zonediff_t *zonediff)
18231 {
18232 isc_result_t result;
18233 isc_stdtime_t inception, soaexpire, keyexpire;
18234 bool check_ksk, keyset_kskonly;
18235 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
18236 unsigned int nkeys = 0, i;
18237 dns_difftuple_t *tuple;
18238
18239 result = dns__zone_findkeys(zone, db, ver, now, zone->mctx,
18240 DNS_MAXZONEKEYS, zone_keys, &nkeys);
18241 if (result != ISC_R_SUCCESS) {
18242 dnssec_log(zone, ISC_LOG_ERROR,
18243 "sign_apex:dns__zone_findkeys -> %s",
18244 dns_result_totext(result));
18245 return (result);
18246 }
18247
18248 inception = now - 3600; /* Allow for clock skew. */
18249 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
18250
18251 keyexpire = dns_zone_getkeyvalidityinterval(zone);
18252 if (keyexpire == 0) {
18253 keyexpire = soaexpire - 1;
18254 } else {
18255 keyexpire += now;
18256 }
18257
18258 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
18259 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
18260
18261 /*
18262 * See if dns__zone_updatesigs() will update DNSKEY signature and if
18263 * not cause them to sign so that newly activated keys are used.
18264 */
18265 for (tuple = ISC_LIST_HEAD(diff->tuples);
18266 tuple != NULL;
18267 tuple = ISC_LIST_NEXT(tuple, link))
18268 {
18269 if (tuple->rdata.type == dns_rdatatype_dnskey &&
18270 dns_name_equal(&tuple->name, &zone->origin))
18271 {
18272 break;
18273 }
18274 }
18275
18276 if (tuple == NULL) {
18277 result = del_sigs(zone, db, ver, &zone->origin,
18278 dns_rdatatype_dnskey, zonediff,
18279 zone_keys, nkeys, now, false);
18280 if (result != ISC_R_SUCCESS) {
18281 dnssec_log(zone, ISC_LOG_ERROR,
18282 "sign_apex:del_sigs -> %s",
18283 dns_result_totext(result));
18284 goto failure;
18285 }
18286 result = add_sigs(db, ver, &zone->origin, zone,
18287 dns_rdatatype_dnskey, zonediff->diff,
18288 zone_keys, nkeys, zone->mctx, inception,
18289 keyexpire, check_ksk, keyset_kskonly);
18290 if (result != ISC_R_SUCCESS) {
18291 dnssec_log(zone, ISC_LOG_ERROR,
18292 "sign_apex:add_sigs -> %s",
18293 dns_result_totext(result));
18294 goto failure;
18295 }
18296 }
18297
18298 result = dns__zone_updatesigs(diff, db, ver, zone_keys, nkeys, zone,
18299 inception, soaexpire, keyexpire, now,
18300 check_ksk, keyset_kskonly, zonediff);
18301
18302 if (result != ISC_R_SUCCESS) {
18303 dnssec_log(zone, ISC_LOG_ERROR,
18304 "sign_apex:dns__zone_updatesigs -> %s",
18305 dns_result_totext(result));
18306 goto failure;
18307 }
18308
18309 failure:
18310 for (i = 0; i < nkeys; i++) {
18311 dst_key_free(&zone_keys[i]);
18312 }
18313 return (result);
18314 }
18315
18316 /*
18317 * Prevent the zone entering a inconsistent state where
18318 * NSEC only DNSKEYs are present with NSEC3 chains.
18319 * See update.c:check_dnssec()
18320 */
18321 static bool
18322 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
18323 dns_diff_t *diff)
18324 {
18325 isc_result_t result;
18326 dns_difftuple_t *tuple;
18327 bool nseconly = false, nsec3 = false;
18328 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
18329
18330 /* Scan the tuples for an NSEC-only DNSKEY */
18331 for (tuple = ISC_LIST_HEAD(diff->tuples);
18332 tuple != NULL;
18333 tuple = ISC_LIST_NEXT(tuple, link))
18334 {
18335 uint8_t alg;
18336 if (tuple->rdata.type != dns_rdatatype_dnskey ||
18337 tuple->op != DNS_DIFFOP_ADD)
18338 {
18339 continue;
18340 }
18341
18342 alg = tuple->rdata.data[3];
18343 if (alg == DST_ALG_RSASHA1) {
18344 nseconly = true;
18345 break;
18346 }
18347 }
18348
18349 /* Check existing DB for NSEC-only DNSKEY */
18350 if (!nseconly) {
18351 result = dns_nsec_nseconly(db, ver, &nseconly);
18352 if (result == ISC_R_NOTFOUND) {
18353 result = ISC_R_SUCCESS;
18354 }
18355 CHECK(result);
18356 }
18357
18358 /* Check existing DB for NSEC3 */
18359 if (!nsec3) {
18360 CHECK(dns_nsec3_activex(db, ver, false,
18361 privatetype, &nsec3));
18362 }
18363
18364 /* Refuse to allow NSEC3 with NSEC-only keys */
18365 if (nseconly && nsec3) {
18366 dnssec_log(zone, ISC_LOG_ERROR,
18367 "NSEC only DNSKEYs and NSEC3 chains not allowed");
18368 goto failure;
18369 }
18370
18371 return (true);
18372
18373 failure:
18374 return (false);
18375 }
18376
18377 static isc_result_t
18378 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
18379 dns_diff_t *diff)
18380 {
18381 isc_result_t result;
18382 dns_dbnode_t *node = NULL;
18383 dns_rdataset_t rdataset;
18384
18385 dns_rdataset_init(&rdataset);
18386 CHECK(dns_db_getoriginnode(db, &node));
18387
18388 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
18389 dns_rdatatype_none, 0, &rdataset, NULL);
18390 if (dns_rdataset_isassociated(&rdataset))
18391 dns_rdataset_disassociate(&rdataset);
18392 if (result != ISC_R_NOTFOUND)
18393 goto failure;
18394
18395 result = dns_nsec3param_deletechains(db, ver, zone, true, diff);
18396
18397 failure:
18398 if (node != NULL)
18399 dns_db_detachnode(db, &node);
18400 return (result);
18401 }
18402
18403 /*
18404 * Given an RRSIG rdataset and an algorithm, determine whether there
18405 * are any signatures using that algorithm.
18406 */
18407 static bool
18408 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
18409 dns_rdata_t rdata = DNS_RDATA_INIT;
18410 dns_rdata_rrsig_t rrsig;
18411 isc_result_t result;
18412
18413 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
18414 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
18415 return (false);
18416 }
18417
18418 for (result = dns_rdataset_first(rdataset);
18419 result == ISC_R_SUCCESS;
18420 result = dns_rdataset_next(rdataset))
18421 {
18422 dns_rdataset_current(rdataset, &rdata);
18423 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
18424 RUNTIME_CHECK(result == ISC_R_SUCCESS);
18425 dns_rdata_reset(&rdata);
18426 if (rrsig.algorithm == alg)
18427 return (true);
18428 }
18429
18430 return (false);
18431 }
18432
18433 static isc_result_t
18434 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
18435 dns_diff_t *diff)
18436 {
18437 dns_name_t *origin;
18438 bool build_nsec3;
18439 isc_result_t result;
18440
18441 origin = dns_db_origin(db);
18442 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
18443 &build_nsec3));
18444 if (build_nsec3)
18445 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
18446 false, zone->privatetype, diff));
18447 CHECK(updatesecure(db, ver, origin, zone->minimum, true, diff));
18448
18449 failure:
18450 return (result);
18451 }
18452
18453 static void
18454 dnssec_report(const char *format, ...) {
18455 va_list args;
18456 va_start(args, format);
18457 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_ZONE,
18458 ISC_LOG_INFO, format, args);
18459 va_end(args);
18460 }
18461
18462 static void
18463 zone_rekey(dns_zone_t *zone) {
18464 isc_result_t result;
18465 dns_db_t *db = NULL;
18466 dns_dbnode_t *node = NULL;
18467 dns_dbversion_t *ver = NULL;
18468 dns_rdataset_t cdsset, soaset, soasigs, keyset, keysigs, cdnskeyset;
18469 dns_dnsseckeylist_t dnskeys, keys, rmkeys;
18470 dns_dnsseckey_t *key = NULL;
18471 dns_diff_t diff, _sig_diff;
18472 dns__zonediff_t zonediff;
18473 bool commit = false, newactive = false;
18474 bool newalg = false;
18475 bool fullsign;
18476 dns_ttl_t ttl = 3600;
18477 const char *dir = NULL;
18478 isc_mem_t *mctx = NULL;
18479 isc_stdtime_t now;
18480 isc_time_t timenow;
18481 isc_interval_t ival;
18482 char timebuf[80];
18483
18484 REQUIRE(DNS_ZONE_VALID(zone));
18485
18486 ISC_LIST_INIT(dnskeys);
18487 ISC_LIST_INIT(keys);
18488 ISC_LIST_INIT(rmkeys);
18489 dns_rdataset_init(&soaset);
18490 dns_rdataset_init(&soasigs);
18491 dns_rdataset_init(&keyset);
18492 dns_rdataset_init(&keysigs);
18493 dns_rdataset_init(&cdsset);
18494 dns_rdataset_init(&cdnskeyset);
18495 dir = dns_zone_getkeydirectory(zone);
18496 mctx = zone->mctx;
18497 dns_diff_init(mctx, &diff);
18498 dns_diff_init(mctx, &_sig_diff);
18499 zonediff_init(&zonediff, &_sig_diff);
18500
18501 CHECK(dns_zone_getdb(zone, &db));
18502 CHECK(dns_db_newversion(db, &ver));
18503 CHECK(dns_db_getoriginnode(db, &node));
18504
18505 TIME_NOW(&timenow);
18506 now = isc_time_seconds(&timenow);
18507
18508 dnssec_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
18509
18510 /* Get the SOA record's TTL */
18511 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
18512 dns_rdatatype_none, 0, &soaset, &soasigs));
18513 ttl = soaset.ttl;
18514 dns_rdataset_disassociate(&soaset);
18515
18516 /* Get the DNSKEY rdataset */
18517 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
18518 dns_rdatatype_none, 0, &keyset, &keysigs);
18519 if (result == ISC_R_SUCCESS) {
18520 ttl = keyset.ttl;
18521 CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir,
18522 mctx, &keyset,
18523 &keysigs, &soasigs,
18524 false, false,
18525 &dnskeys));
18526 } else if (result != ISC_R_NOTFOUND) {
18527 goto failure;
18528 }
18529
18530 /* Get the CDS rdataset */
18531 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cds,
18532 dns_rdatatype_none, 0, &cdsset, NULL);
18533 if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdsset))
18534 dns_rdataset_disassociate(&cdsset);
18535
18536 /* Get the CDNSKEY rdataset */
18537 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cdnskey,
18538 dns_rdatatype_none, 0, &cdnskeyset, NULL);
18539 if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdnskeyset))
18540 {
18541 dns_rdataset_disassociate(&cdnskeyset);
18542 }
18543
18544 /*
18545 * True when called from "rndc sign". Indicates the zone should be
18546 * fully signed now.
18547 */
18548 fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN);
18549
18550 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, now, mctx,
18551 &keys);
18552 if (result == ISC_R_SUCCESS) {
18553 bool check_ksk;
18554 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
18555 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
18556 &zone->origin, ttl, &diff,
18557 !check_ksk, mctx,
18558 dnssec_report);
18559 /*
18560 * Keys couldn't be updated for some reason;
18561 * try again later.
18562 */
18563 if (result != ISC_R_SUCCESS) {
18564 dnssec_log(zone, ISC_LOG_ERROR,
18565 "zone_rekey:couldn't update zone keys: %s",
18566 isc_result_totext(result));
18567 goto failure;
18568 }
18569
18570 /*
18571 * Update CDS / CDNSKEY records.
18572 */
18573 result = dns_dnssec_syncupdate(&dnskeys, &rmkeys, &cdsset,
18574 &cdnskeyset, now, ttl,
18575 &diff, mctx);
18576 if (result != ISC_R_SUCCESS) {
18577 dnssec_log(zone, ISC_LOG_ERROR,
18578 "zone_rekey:couldn't update CDS/CDNSKEY: %s",
18579 isc_result_totext(result));
18580 goto failure;
18581 }
18582
18583 /*
18584 * See if any pre-existing keys have newly become active;
18585 * also, see if any new key is for a new algorithm, as in that
18586 * event, we need to sign the zone fully. (If there's a new
18587 * key, but it's for an already-existing algorithm, then
18588 * the zone signing can be handled incrementally.)
18589 */
18590 for (key = ISC_LIST_HEAD(dnskeys);
18591 key != NULL;
18592 key = ISC_LIST_NEXT(key, link))
18593 {
18594 if (!key->first_sign) {
18595 continue;
18596 }
18597
18598 newactive = true;
18599
18600 if (!dns_rdataset_isassociated(&keysigs)) {
18601 newalg = true;
18602 break;
18603 }
18604
18605 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
18606 /*
18607 * This isn't a new algorithm; clear
18608 * first_sign so we won't sign the
18609 * whole zone with this key later
18610 */
18611 key->first_sign = false;
18612 } else {
18613 newalg = true;
18614 break;
18615 }
18616 }
18617
18618 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
18619 dnskey_sane(zone, db, ver, &diff))
18620 {
18621 CHECK(dns_diff_apply(&diff, db, ver));
18622 CHECK(clean_nsec3param(zone, db, ver, &diff));
18623 CHECK(add_signing_records(db, zone->privatetype, ver,
18624 &diff, (newalg || fullsign)));
18625 CHECK(update_soa_serial(db, ver, &diff, mctx,
18626 zone->updatemethod));
18627 CHECK(add_chains(zone, db, ver, &diff));
18628 CHECK(sign_apex(zone, db, ver, now, &diff, &zonediff));
18629 CHECK(zone_journal(zone, zonediff.diff, NULL,
18630 "zone_rekey"));
18631 commit = true;
18632 }
18633 }
18634
18635 dns_db_closeversion(db, &ver, true);
18636
18637 if (commit) {
18638 dns_difftuple_t *tuple;
18639
18640 LOCK_ZONE(zone);
18641 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
18642
18643 zone_needdump(zone, DNS_DUMP_DELAY);
18644
18645 zone_settimer(zone, &timenow);
18646
18647 /* Remove any signatures from removed keys. */
18648 if (!ISC_LIST_EMPTY(rmkeys)) {
18649 for (key = ISC_LIST_HEAD(rmkeys);
18650 key != NULL;
18651 key = ISC_LIST_NEXT(key, link))
18652 {
18653 result = zone_signwithkey(zone,
18654 dst_key_alg(key->key),
18655 dst_key_id(key->key),
18656 true);
18657 if (result != ISC_R_SUCCESS) {
18658 dnssec_log(zone, ISC_LOG_ERROR,
18659 "zone_signwithkey failed: %s",
18660 dns_result_totext(result));
18661 }
18662 }
18663 }
18664
18665 if (fullsign) {
18666 /*
18667 * "rndc sign" was called, so we now sign the zone
18668 * with all active keys, whether they're new or not.
18669 */
18670 for (key = ISC_LIST_HEAD(dnskeys);
18671 key != NULL;
18672 key = ISC_LIST_NEXT(key, link))
18673 {
18674 if (!key->force_sign && !key->hint_sign) {
18675 continue;
18676 }
18677
18678 result = zone_signwithkey(zone,
18679 dst_key_alg(key->key),
18680 dst_key_id(key->key),
18681 false);
18682 if (result != ISC_R_SUCCESS) {
18683 dnssec_log(zone, ISC_LOG_ERROR,
18684 "zone_signwithkey failed: %s",
18685 dns_result_totext(result));
18686 }
18687 }
18688 } else if (newalg) {
18689 /*
18690 * We haven't been told to sign fully, but a new
18691 * algorithm was added to the DNSKEY. We sign
18692 * the full zone, but only with newly active
18693 * keys.
18694 */
18695 for (key = ISC_LIST_HEAD(dnskeys);
18696 key != NULL;
18697 key = ISC_LIST_NEXT(key, link))
18698 {
18699 if (!key->first_sign) {
18700 continue;
18701 }
18702
18703 result = zone_signwithkey(zone,
18704 dst_key_alg(key->key),
18705 dst_key_id(key->key),
18706 false);
18707 if (result != ISC_R_SUCCESS) {
18708 dnssec_log(zone, ISC_LOG_ERROR,
18709 "zone_signwithkey failed: %s",
18710 dns_result_totext(result));
18711 }
18712 }
18713 }
18714
18715 /*
18716 * Clear fullsign flag, if it was set, so we don't do
18717 * another full signing next time
18718 */
18719 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
18720
18721 /*
18722 * Cause the zone to add/delete NSEC3 chains for the
18723 * deferred NSEC3PARAM changes.
18724 */
18725 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
18726 tuple != NULL;
18727 tuple = ISC_LIST_NEXT(tuple, link))
18728 {
18729 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
18730 dns_rdata_t rdata = DNS_RDATA_INIT;
18731 dns_rdata_nsec3param_t nsec3param;
18732
18733 if (tuple->rdata.type != zone->privatetype ||
18734 tuple->op != DNS_DIFFOP_ADD)
18735 {
18736 continue;
18737 }
18738
18739 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
18740 buf, sizeof(buf)))
18741 {
18742 continue;
18743 }
18744
18745 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
18746 RUNTIME_CHECK(result == ISC_R_SUCCESS);
18747 if (nsec3param.flags == 0) {
18748 continue;
18749 }
18750
18751 result = zone_addnsec3chain(zone, &nsec3param);
18752 if (result != ISC_R_SUCCESS) {
18753 dnssec_log(zone, ISC_LOG_ERROR,
18754 "zone_addnsec3chain failed: %s",
18755 dns_result_totext(result));
18756 }
18757 }
18758
18759 /*
18760 * Activate any NSEC3 chain updates that may have
18761 * been scheduled before this rekey.
18762 */
18763 if (fullsign || newalg) {
18764 resume_addnsec3chain(zone);
18765 }
18766
18767 /*
18768 * Schedule the next resigning event
18769 */
18770 set_resigntime(zone);
18771 UNLOCK_ZONE(zone);
18772 }
18773
18774 isc_time_settoepoch(&zone->refreshkeytime);
18775
18776 /*
18777 * If we're doing key maintenance, set the key refresh timer to
18778 * the next scheduled key event or to 'dnssec-loadkeys-interval'
18779 * seconds in the future, whichever is sooner.
18780 */
18781 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
18782 isc_time_t timethen;
18783 isc_stdtime_t then;
18784
18785 LOCK_ZONE(zone);
18786 DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
18787 &timethen);
18788 zone->refreshkeytime = timethen;
18789 UNLOCK_ZONE(zone);
18790
18791 for (key = ISC_LIST_HEAD(dnskeys);
18792 key != NULL;
18793 key = ISC_LIST_NEXT(key, link))
18794 {
18795 then = now;
18796 result = next_keyevent(key->key, &then);
18797 if (result != ISC_R_SUCCESS) {
18798 continue;
18799 }
18800
18801 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
18802 LOCK_ZONE(zone);
18803 if (isc_time_compare(&timethen,
18804 &zone->refreshkeytime) < 0)
18805 {
18806 zone->refreshkeytime = timethen;
18807 }
18808 UNLOCK_ZONE(zone);
18809 }
18810
18811 zone_settimer(zone, &timenow);
18812
18813 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
18814 dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
18815 }
18816
18817 result = ISC_R_SUCCESS;
18818
18819 failure:
18820 if (result != ISC_R_SUCCESS) {
18821 /*
18822 * Something went wrong; try again in ten minutes or
18823 * after a key refresh interval, whichever is shorter.
18824 */
18825 isc_interval_set(&ival,
18826 ISC_MIN(zone->refreshkeyinterval, 600), 0);
18827 isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
18828 }
18829
18830 dns_diff_clear(&diff);
18831 dns_diff_clear(&_sig_diff);
18832
18833 clear_keylist(&dnskeys, mctx);
18834 clear_keylist(&keys, mctx);
18835 clear_keylist(&rmkeys, mctx);
18836
18837 if (ver != NULL) {
18838 dns_db_closeversion(db, &ver, false);
18839 }
18840 if (dns_rdataset_isassociated(&cdsset)) {
18841 dns_rdataset_disassociate(&cdsset);
18842 }
18843 if (dns_rdataset_isassociated(&keyset)) {
18844 dns_rdataset_disassociate(&keyset);
18845 }
18846 if (dns_rdataset_isassociated(&keysigs)) {
18847 dns_rdataset_disassociate(&keysigs);
18848 }
18849 if (dns_rdataset_isassociated(&soasigs)) {
18850 dns_rdataset_disassociate(&soasigs);
18851 }
18852 if (dns_rdataset_isassociated(&cdnskeyset)) {
18853 dns_rdataset_disassociate(&cdnskeyset);
18854 }
18855 if (node != NULL) {
18856 dns_db_detachnode(db, &node);
18857 }
18858 if (db != NULL) {
18859 dns_db_detach(&db);
18860 }
18861
18862 INSIST(ver == NULL);
18863 }
18864
18865 void
18866 dns_zone_rekey(dns_zone_t *zone, bool fullsign) {
18867 isc_time_t now;
18868
18869 if (zone->type == dns_zone_master && zone->task != NULL) {
18870 LOCK_ZONE(zone);
18871
18872 if (fullsign)
18873 zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
18874
18875 TIME_NOW(&now);
18876 zone->refreshkeytime = now;
18877 zone_settimer(zone, &now);
18878
18879 UNLOCK_ZONE(zone);
18880 }
18881 }
18882
18883 isc_result_t
18884 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
18885 unsigned int *errors)
18886 {
18887 isc_result_t result;
18888 dns_dbnode_t *node = NULL;
18889
18890 REQUIRE(DNS_ZONE_VALID(zone));
18891 REQUIRE(errors != NULL);
18892
18893 result = dns_db_getoriginnode(db, &node);
18894 if (result != ISC_R_SUCCESS)
18895 return (result);
18896 result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
18897 false);
18898 dns_db_detachnode(db, &node);
18899 return (result);
18900 }
18901
18902 isc_result_t
18903 dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) {
18904 isc_result_t result;
18905 dns_dbnode_t *node = NULL;
18906 dns_rdataset_t dnskey, cds, cdnskey;
18907 unsigned char buffer[DNS_DS_BUFFERSIZE];
18908 unsigned char algorithms[256];
18909 unsigned int i;
18910
18911 REQUIRE(DNS_ZONE_VALID(zone));
18912
18913 result = dns_db_getoriginnode(db, &node);
18914 if (result != ISC_R_SUCCESS)
18915 return (result);
18916
18917 dns_rdataset_init(&cds);
18918 dns_rdataset_init(&dnskey);
18919 dns_rdataset_init(&cdnskey);
18920
18921 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds,
18922 dns_rdatatype_none, 0, &cds, NULL);
18923 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
18924 goto failure;
18925
18926 result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey,
18927 dns_rdatatype_none, 0, &cdnskey, NULL);
18928 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
18929 goto failure;
18930
18931 if (!dns_rdataset_isassociated(&cds) &&
18932 !dns_rdataset_isassociated(&cdnskey)) {
18933 result = ISC_R_SUCCESS;
18934 goto failure;
18935 }
18936
18937 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
18938 dns_rdatatype_none, 0, &dnskey, NULL);
18939 if (result == ISC_R_NOTFOUND) {
18940 if (dns_rdataset_isassociated(&cds))
18941 result = DNS_R_BADCDS;
18942 else
18943 result = DNS_R_BADCDNSKEY;
18944 goto failure;
18945 }
18946 if (result != ISC_R_SUCCESS)
18947 goto failure;
18948
18949 /*
18950 * For each DNSSEC algorithm in the CDS RRset there must be
18951 * a matching DNSKEY record.
18952 */
18953 if (dns_rdataset_isassociated(&cds)) {
18954 memset(algorithms, 0, sizeof(algorithms));
18955 for (result = dns_rdataset_first(&cds);
18956 result == ISC_R_SUCCESS;
18957 result = dns_rdataset_next(&cds)) {
18958 dns_rdata_t crdata = DNS_RDATA_INIT;
18959 dns_rdata_cds_t structcds;
18960
18961 dns_rdataset_current(&cds, &crdata);
18962 CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL));
18963 if (algorithms[structcds.algorithm] == 0)
18964 algorithms[structcds.algorithm] = 1;
18965 for (result = dns_rdataset_first(&dnskey);
18966 result == ISC_R_SUCCESS;
18967 result = dns_rdataset_next(&dnskey)) {
18968 dns_rdata_t rdata = DNS_RDATA_INIT;
18969 dns_rdata_t dsrdata = DNS_RDATA_INIT;
18970
18971 dns_rdataset_current(&dnskey, &rdata);
18972 CHECK(dns_ds_buildrdata(&zone->origin, &rdata,
18973 structcds.digest_type,
18974 buffer, &dsrdata));
18975 if (crdata.length == dsrdata.length &&
18976 memcmp(crdata.data, dsrdata.data,
18977 dsrdata.length) == 0) {
18978 algorithms[structcds.algorithm] = 2;
18979 }
18980 }
18981 if (result != ISC_R_NOMORE)
18982 goto failure;
18983 }
18984 for (i = 0; i < sizeof(algorithms); i++) {
18985 if (algorithms[i] == 1) {
18986 result = DNS_R_BADCDNSKEY;
18987 goto failure;
18988 }
18989 }
18990 }
18991
18992 /*
18993 * For each DNSSEC algorithm in the CDNSKEY RRset there must be
18994 * a matching DNSKEY record.
18995 */
18996 if (dns_rdataset_isassociated(&cdnskey)) {
18997 memset(algorithms, 0, sizeof(algorithms));
18998 for (result = dns_rdataset_first(&cdnskey);
18999 result == ISC_R_SUCCESS;
19000 result = dns_rdataset_next(&cdnskey)) {
19001 dns_rdata_t crdata = DNS_RDATA_INIT;
19002 dns_rdata_cdnskey_t structcdnskey;
19003
19004 dns_rdataset_current(&cdnskey, &crdata);
19005 CHECK(dns_rdata_tostruct(&crdata, &structcdnskey,
19006 NULL));
19007 if (algorithms[structcdnskey.algorithm] == 0)
19008 algorithms[structcdnskey.algorithm] = 1;
19009 for (result = dns_rdataset_first(&dnskey);
19010 result == ISC_R_SUCCESS;
19011 result = dns_rdataset_next(&dnskey)) {
19012 dns_rdata_t rdata = DNS_RDATA_INIT;
19013
19014 dns_rdataset_current(&dnskey, &rdata);
19015 if (crdata.length == rdata.length &&
19016 memcmp(crdata.data, rdata.data,
19017 rdata.length) == 0) {
19018 algorithms[structcdnskey.algorithm] = 2;
19019 }
19020 }
19021 if (result != ISC_R_NOMORE)
19022 goto failure;
19023 }
19024 for (i = 0; i < sizeof(algorithms); i++) {
19025 if (algorithms[i] == 1) {
19026 result = DNS_R_BADCDS;
19027 goto failure;
19028 }
19029 }
19030 }
19031 result = ISC_R_SUCCESS;
19032
19033 failure:
19034 if (dns_rdataset_isassociated(&cds))
19035 dns_rdataset_disassociate(&cds);
19036 if (dns_rdataset_isassociated(&dnskey))
19037 dns_rdataset_disassociate(&dnskey);
19038 if (dns_rdataset_isassociated(&cdnskey))
19039 dns_rdataset_disassociate(&cdnskey);
19040 dns_db_detachnode(db, &node);
19041 return (result);
19042 }
19043
19044 void
19045 dns_zone_setautomatic(dns_zone_t *zone, bool automatic) {
19046 REQUIRE(DNS_ZONE_VALID(zone));
19047
19048 LOCK_ZONE(zone);
19049 zone->automatic = automatic;
19050 UNLOCK_ZONE(zone);
19051 }
19052
19053 bool
19054 dns_zone_getautomatic(dns_zone_t *zone) {
19055 REQUIRE(DNS_ZONE_VALID(zone));
19056 return (zone->automatic);
19057 }
19058
19059 void
19060 dns_zone_setadded(dns_zone_t *zone, bool added) {
19061 REQUIRE(DNS_ZONE_VALID(zone));
19062
19063 LOCK_ZONE(zone);
19064 zone->added = added;
19065 UNLOCK_ZONE(zone);
19066 }
19067
19068 bool
19069 dns_zone_getadded(dns_zone_t *zone) {
19070 REQUIRE(DNS_ZONE_VALID(zone));
19071 return (zone->added);
19072 }
19073
19074 isc_result_t
19075 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
19076 {
19077 isc_time_t loadtime;
19078 isc_result_t result;
19079 dns_zone_t *secure = NULL;
19080
19081 TIME_NOW(&loadtime);
19082
19083 /*
19084 * Lock hierarchy: zmgr, zone, raw.
19085 */
19086 again:
19087 LOCK_ZONE(zone);
19088 INSIST(zone != zone->raw);
19089 if (inline_secure(zone))
19090 LOCK_ZONE(zone->raw);
19091 else if (inline_raw(zone)) {
19092 secure = zone->secure;
19093 TRYLOCK_ZONE(result, secure);
19094 if (result != ISC_R_SUCCESS) {
19095 UNLOCK_ZONE(zone);
19096 secure = NULL;
19097 isc_thread_yield();
19098 goto again;
19099 }
19100 }
19101 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
19102 if (inline_secure(zone))
19103 UNLOCK_ZONE(zone->raw);
19104 else if (secure != NULL)
19105 UNLOCK_ZONE(secure);
19106 UNLOCK_ZONE(zone);
19107 return result;
19108 }
19109
19110 isc_result_t
19111 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, uint32_t interval) {
19112 REQUIRE(DNS_ZONE_VALID(zone));
19113 if (interval == 0)
19114 return (ISC_R_RANGE);
19115 /* Maximum value: 24 hours (3600 minutes) */
19116 if (interval > (24 * 60))
19117 interval = (24 * 60);
19118 /* Multiply by 60 for seconds */
19119 zone->refreshkeyinterval = interval * 60;
19120 return (ISC_R_SUCCESS);
19121 }
19122
19123 void
19124 dns_zone_setrequestixfr(dns_zone_t *zone, bool flag) {
19125 REQUIRE(DNS_ZONE_VALID(zone));
19126 zone->requestixfr = flag;
19127 }
19128
19129 bool
19130 dns_zone_getrequestixfr(dns_zone_t *zone) {
19131 REQUIRE(DNS_ZONE_VALID(zone));
19132 return (zone->requestixfr);
19133 }
19134
19135 void
19136 dns_zone_setrequestexpire(dns_zone_t *zone, bool flag) {
19137 REQUIRE(DNS_ZONE_VALID(zone));
19138 zone->requestexpire = flag;
19139 }
19140
19141 bool
19142 dns_zone_getrequestexpire(dns_zone_t *zone) {
19143 REQUIRE(DNS_ZONE_VALID(zone));
19144 return (zone->requestexpire);
19145 }
19146
19147 void
19148 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
19149 REQUIRE(DNS_ZONE_VALID(zone));
19150 zone->updatemethod = method;
19151 }
19152
19153 dns_updatemethod_t
19154 dns_zone_getserialupdatemethod(dns_zone_t *zone) {
19155 REQUIRE(DNS_ZONE_VALID(zone));
19156 return(zone->updatemethod);
19157 }
19158
19159 /*
19160 * Lock hierarchy: zmgr, zone, raw.
19161 */
19162 isc_result_t
19163 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
19164 isc_result_t result;
19165 dns_zonemgr_t *zmgr;
19166
19167 REQUIRE(DNS_ZONE_VALID(zone));
19168 REQUIRE(zone->zmgr != NULL);
19169 REQUIRE(zone->task != NULL);
19170 REQUIRE(zone->loadtask != NULL);
19171 REQUIRE(zone->raw == NULL);
19172
19173 REQUIRE(DNS_ZONE_VALID(raw));
19174 REQUIRE(raw->zmgr == NULL);
19175 REQUIRE(raw->task == NULL);
19176 REQUIRE(raw->loadtask == NULL);
19177 REQUIRE(raw->secure == NULL);
19178
19179 REQUIRE(zone != raw);
19180
19181 /*
19182 * Lock hierarchy: zmgr, zone, raw.
19183 */
19184 zmgr = zone->zmgr;
19185 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
19186 LOCK_ZONE(zone);
19187 LOCK_ZONE(raw);
19188
19189 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
19190 NULL, NULL, zone->task, zone_timer, raw,
19191 &raw->timer);
19192 if (result != ISC_R_SUCCESS)
19193 goto unlock;
19194
19195 /*
19196 * The timer "holds" a iref.
19197 */
19198 raw->irefs++;
19199 INSIST(raw->irefs != 0);
19200
19201
19202 /* dns_zone_attach(raw, &zone->raw); */
19203 isc_refcount_increment(&raw->erefs);
19204 zone->raw = raw;
19205
19206 /* dns_zone_iattach(zone, &raw->secure); */
19207 zone_iattach(zone, &raw->secure);
19208
19209 isc_task_attach(zone->task, &raw->task);
19210 isc_task_attach(zone->loadtask, &raw->loadtask);
19211
19212 ISC_LIST_APPEND(zmgr->zones, raw, link);
19213 raw->zmgr = zmgr;
19214 zmgr->refs++;
19215
19216 unlock:
19217 UNLOCK_ZONE(raw);
19218 UNLOCK_ZONE(zone);
19219 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
19220 return (result);
19221 }
19222
19223 void
19224 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
19225 REQUIRE(DNS_ZONE_VALID(zone));
19226 REQUIRE(raw != NULL && *raw == NULL);
19227
19228 LOCK(&zone->lock);
19229 INSIST(zone != zone->raw);
19230 if (zone->raw != NULL)
19231 dns_zone_attach(zone->raw, raw);
19232 UNLOCK(&zone->lock);
19233 }
19234
19235 struct keydone {
19236 isc_event_t event;
19237 bool all;
19238 unsigned char data[5];
19239 };
19240
19241 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL)
19242
19243 static void
19244 keydone(isc_task_t *task, isc_event_t *event) {
19245 const char *me = "keydone";
19246 bool commit = false;
19247 isc_result_t result;
19248 dns_rdata_t rdata = DNS_RDATA_INIT;
19249 dns_dbversion_t *oldver = NULL, *newver = NULL;
19250 dns_zone_t *zone;
19251 dns_db_t *db = NULL;
19252 dns_dbnode_t *node = NULL;
19253 dns_rdataset_t rdataset;
19254 dns_diff_t diff;
19255 struct keydone *kd = (struct keydone *)event;
19256 dns_update_log_t log = { update_log_cb, NULL };
19257 bool clear_pending = false;
19258
19259 UNUSED(task);
19260
19261 zone = event->ev_arg;
19262 INSIST(DNS_ZONE_VALID(zone));
19263
19264 ENTER;
19265
19266 dns_rdataset_init(&rdataset);
19267 dns_diff_init(zone->mctx, &diff);
19268
19269 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
19270 if (zone->db != NULL) {
19271 dns_db_attach(zone->db, &db);
19272 }
19273 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
19274 if (db == NULL) {
19275 goto failure;
19276 }
19277
19278 dns_db_currentversion(db, &oldver);
19279 result = dns_db_newversion(db, &newver);
19280 if (result != ISC_R_SUCCESS) {
19281 dnssec_log(zone, ISC_LOG_ERROR,
19282 "keydone:dns_db_newversion -> %s",
19283 dns_result_totext(result));
19284 goto failure;
19285 }
19286
19287 result = dns_db_getoriginnode(db, &node);
19288 if (result != ISC_R_SUCCESS) {
19289 goto failure;
19290 }
19291
19292 result = dns_db_findrdataset(db, node, newver, zone->privatetype,
19293 dns_rdatatype_none, 0, &rdataset, NULL);
19294 if (result == ISC_R_NOTFOUND) {
19295 INSIST(!dns_rdataset_isassociated(&rdataset));
19296 goto failure;
19297 }
19298 if (result != ISC_R_SUCCESS) {
19299 INSIST(!dns_rdataset_isassociated(&rdataset));
19300 goto failure;
19301 }
19302
19303 for (result = dns_rdataset_first(&rdataset);
19304 result == ISC_R_SUCCESS;
19305 result = dns_rdataset_next(&rdataset))
19306 {
19307 bool found = false;
19308
19309 dns_rdataset_current(&rdataset, &rdata);
19310
19311 if (kd->all) {
19312 if (rdata.length == 5 && rdata.data[0] != 0 &&
19313 rdata.data[3] == 0 && rdata.data[4] == 1)
19314 {
19315 found = true;
19316 } else if (rdata.data[0] == 0 &&
19317 (rdata.data[2] & PENDINGFLAGS) != 0)
19318 {
19319 found = true;
19320 clear_pending = true;
19321 }
19322 } else if (rdata.length == 5 &&
19323 memcmp(rdata.data, kd->data, 5) == 0)
19324 {
19325 found = true;
19326 }
19327
19328 if (found) {
19329 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL,
19330 &zone->origin, rdataset.ttl,
19331 &rdata));
19332 }
19333 dns_rdata_reset(&rdata);
19334 }
19335
19336 if (!ISC_LIST_EMPTY(diff.tuples)) {
19337 /* Write changes to journal file. */
19338 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
19339 zone->updatemethod));
19340
19341 result = dns_update_signatures(&log, zone, db,
19342 oldver, newver, &diff,
19343 zone->sigvalidityinterval);
19344 if (!clear_pending) {
19345 CHECK(result);
19346 }
19347
19348 CHECK(zone_journal(zone, &diff, NULL, "keydone"));
19349 commit = true;
19350
19351 LOCK_ZONE(zone);
19352 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
19353 zone_needdump(zone, 30);
19354 UNLOCK_ZONE(zone);
19355 }
19356
19357 failure:
19358 if (dns_rdataset_isassociated(&rdataset)) {
19359 dns_rdataset_disassociate(&rdataset);
19360 }
19361 if (db != NULL) {
19362 if (node != NULL) {
19363 dns_db_detachnode(db, &node);
19364 }
19365 if (oldver != NULL) {
19366 dns_db_closeversion(db, &oldver, false);
19367 }
19368 if (newver != NULL) {
19369 dns_db_closeversion(db, &newver, commit);
19370 }
19371 dns_db_detach(&db);
19372 }
19373 dns_diff_clear(&diff);
19374 isc_event_free(&event);
19375 dns_zone_idetach(&zone);
19376
19377 INSIST(oldver == NULL);
19378 INSIST(newver == NULL);
19379 }
19380
19381 isc_result_t
19382 dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
19383 isc_result_t result = ISC_R_SUCCESS;
19384 isc_event_t *e;
19385 isc_buffer_t b;
19386 dns_zone_t *dummy = NULL;
19387 struct keydone *kd;
19388
19389 REQUIRE(DNS_ZONE_VALID(zone));
19390
19391 LOCK_ZONE(zone);
19392
19393 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone,
19394 zone, sizeof(struct keydone));
19395 if (e == NULL) {
19396 result = ISC_R_NOMEMORY;
19397 goto failure;
19398 }
19399
19400 kd = (struct keydone *) e;
19401 if (strcasecmp(keystr, "all") == 0) {
19402 kd->all = true;
19403 } else {
19404 isc_textregion_t r;
19405 const char *algstr;
19406 dns_keytag_t keyid;
19407 dns_secalg_t alg;
19408 size_t n;
19409
19410 kd->all = false;
19411
19412 n = sscanf(keystr, "%hu/", &keyid);
19413 if (n == 0U) {
19414 CHECK(ISC_R_FAILURE);
19415 }
19416
19417 algstr = strchr(keystr, '/');
19418 if (algstr != NULL) {
19419 algstr++;
19420 } else {
19421 CHECK(ISC_R_FAILURE);
19422 }
19423
19424 n = sscanf(algstr, "%hhu", &alg);
19425 if (n == 0U) {
19426 DE_CONST(algstr, r.base);
19427 r.length = strlen(algstr);
19428 CHECK(dns_secalg_fromtext(&alg, &r));
19429 }
19430
19431 /* construct a private-type rdata */
19432 isc_buffer_init(&b, kd->data, sizeof(kd->data));
19433 isc_buffer_putuint8(&b, alg);
19434 isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8);
19435 isc_buffer_putuint8(&b, (keyid & 0xff));
19436 isc_buffer_putuint8(&b, 0);
19437 isc_buffer_putuint8(&b, 1);
19438 }
19439
19440 zone_iattach(zone, &dummy);
19441 isc_task_send(zone->task, &e);
19442
19443 failure:
19444 if (e != NULL) {
19445 isc_event_free(&e);
19446 }
19447 UNLOCK_ZONE(zone);
19448 return (result);
19449 }
19450
19451 /*
19452 * Called from the zone task's queue after the relevant event is posted by
19453 * dns_zone_setnsec3param().
19454 */
19455 static void
19456 setnsec3param(isc_task_t *task, isc_event_t *event) {
19457 const char *me = "setnsec3param";
19458 dns_zone_t *zone = event->ev_arg;
19459
19460 INSIST(DNS_ZONE_VALID(zone));
19461
19462 UNUSED(task);
19463
19464 ENTER;
19465
19466 /*
19467 * If receive_secure_serial is still processing or we have a
19468 * queued event append rss_post queue.
19469 */
19470 if (zone->rss_newver != NULL ||
19471 ISC_LIST_HEAD(zone->rss_post) != NULL)
19472 {
19473 /*
19474 * Wait for receive_secure_serial() to finish processing.
19475 */
19476 ISC_LIST_APPEND(zone->rss_post, event, ev_link);
19477 } else {
19478 rss_post(zone, event);
19479 }
19480 dns_zone_idetach(&zone);
19481 }
19482
19483 /*
19484 * Check whether NSEC3 chain addition or removal specified by the private-type
19485 * record passed with the event was already queued (or even fully performed).
19486 * If not, modify the relevant private-type records at the zone apex and call
19487 * resume_addnsec3chain().
19488 */
19489 static void
19490 rss_post(dns_zone_t *zone, isc_event_t *event) {
19491 const char *me = "rss_post";
19492 bool commit = false;
19493 isc_result_t result;
19494 dns_dbversion_t *oldver = NULL, *newver = NULL;
19495 dns_db_t *db = NULL;
19496 dns_dbnode_t *node = NULL;
19497 dns_rdataset_t prdataset, nrdataset;
19498 dns_diff_t diff;
19499 struct np3event *npe = (struct np3event *)event;
19500 nsec3param_t *np;
19501 dns_update_log_t log = { update_log_cb, NULL };
19502 dns_rdata_t rdata;
19503 bool nseconly;
19504 bool exists = false;
19505
19506 ENTER;
19507
19508 np = &npe->params;
19509
19510 dns_rdataset_init(&prdataset);
19511 dns_rdataset_init(&nrdataset);
19512 dns_diff_init(zone->mctx, &diff);
19513
19514 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
19515 if (zone->db != NULL) {
19516 dns_db_attach(zone->db, &db);
19517 }
19518 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
19519 if (db == NULL) {
19520 goto failure;
19521 }
19522
19523 dns_db_currentversion(db, &oldver);
19524 result = dns_db_newversion(db, &newver);
19525 if (result != ISC_R_SUCCESS) {
19526 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
19527 dnssec_log(zone, ISC_LOG_ERROR,
19528 "setnsec3param:dns_db_newversion -> %s",
19529 dns_result_totext(result));
19530 goto failure;
19531 }
19532
19533 CHECK(dns_db_getoriginnode(db, &node));
19534
19535 /*
19536 * Does a private-type record already exist for this chain?
19537 */
19538 result = dns_db_findrdataset(db, node, newver, zone->privatetype,
19539 dns_rdatatype_none, 0, &prdataset, NULL);
19540 if (result == ISC_R_SUCCESS) {
19541 for (result = dns_rdataset_first(&prdataset);
19542 result == ISC_R_SUCCESS;
19543 result = dns_rdataset_next(&prdataset))
19544 {
19545 dns_rdata_init(&rdata);
19546 dns_rdataset_current(&prdataset, &rdata);
19547
19548 if (np->length == rdata.length &&
19549 memcmp(rdata.data, np->data, np->length) == 0)
19550 {
19551 exists = true;
19552 break;
19553 }
19554 }
19555 } else if (result != ISC_R_NOTFOUND) {
19556 INSIST(!dns_rdataset_isassociated(&prdataset));
19557 goto failure;
19558 }
19559
19560 /*
19561 * Does the chain already exist?
19562 */
19563 result = dns_db_findrdataset(db, node, newver,
19564 dns_rdatatype_nsec3param,
19565 dns_rdatatype_none, 0, &nrdataset, NULL);
19566 if (result == ISC_R_SUCCESS) {
19567 for (result = dns_rdataset_first(&nrdataset);
19568 result == ISC_R_SUCCESS;
19569 result = dns_rdataset_next(&nrdataset))
19570 {
19571 dns_rdata_init(&rdata);
19572 dns_rdataset_current(&nrdataset, &rdata);
19573
19574 if (np->length == (rdata.length + 1) &&
19575 memcmp(rdata.data, np->data + 1,
19576 np->length - 1) == 0)
19577 {
19578 exists = true;
19579 break;
19580 }
19581 }
19582 } else if (result != ISC_R_NOTFOUND) {
19583 INSIST(!dns_rdataset_isassociated(&nrdataset));
19584 goto failure;
19585 }
19586
19587
19588 /*
19589 * We need to remove any existing NSEC3 chains if the supplied NSEC3
19590 * parameters are supposed to replace the current ones or if we are
19591 * switching to NSEC.
19592 */
19593 if (!exists && np->replace && (np->length != 0 || np->nsec)) {
19594 CHECK(dns_nsec3param_deletechains(db, newver, zone,
19595 !np->nsec, &diff));
19596 }
19597
19598 if (!exists && np->length != 0) {
19599 /*
19600 * We're creating an NSEC3 chain. Add the private-type record
19601 * passed in the event handler's argument to the zone apex.
19602 *
19603 * If the zone is not currently capable of supporting an NSEC3
19604 * chain (due to the DNSKEY RRset at the zone apex not existing
19605 * or containing at least one key using an NSEC-only
19606 * algorithm), add the INITIAL flag, so these parameters can be
19607 * used later when NSEC3 becomes available.
19608 */
19609 dns_rdata_init(&rdata);
19610
19611 np->data[2] |= DNS_NSEC3FLAG_CREATE;
19612 result = dns_nsec_nseconly(db, newver, &nseconly);
19613 if (result == ISC_R_NOTFOUND || nseconly) {
19614 np->data[2] |= DNS_NSEC3FLAG_INITIAL;
19615 }
19616
19617 rdata.length = np->length;
19618 rdata.data = np->data;
19619 rdata.type = zone->privatetype;
19620 rdata.rdclass = zone->rdclass;
19621 CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD,
19622 &zone->origin, 0, &rdata));
19623 }
19624
19625 /*
19626 * If we changed anything in the zone, write changes to journal file
19627 * and set commit to true so that resume_addnsec3chain() will be
19628 * called below in order to kick off adding/removing relevant NSEC3
19629 * records.
19630 */
19631 if (!ISC_LIST_EMPTY(diff.tuples)) {
19632 CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
19633 zone->updatemethod));
19634 result = dns_update_signatures(&log, zone, db,
19635 oldver, newver, &diff,
19636 zone->sigvalidityinterval);
19637 if (result != ISC_R_NOTFOUND) {
19638 CHECK(result);
19639 }
19640 CHECK(zone_journal(zone, &diff, NULL, "setnsec3param"));
19641 commit = true;
19642
19643 LOCK_ZONE(zone);
19644 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
19645 zone_needdump(zone, 30);
19646 UNLOCK_ZONE(zone);
19647 }
19648
19649 failure:
19650 if (dns_rdataset_isassociated(&prdataset)) {
19651 dns_rdataset_disassociate(&prdataset);
19652 }
19653 if (dns_rdataset_isassociated(&nrdataset)) {
19654 dns_rdataset_disassociate(&nrdataset);
19655 }
19656 if (node != NULL) {
19657 dns_db_detachnode(db, &node);
19658 }
19659 if (oldver != NULL) {
19660 dns_db_closeversion(db, &oldver, false);
19661 }
19662 if (newver != NULL) {
19663 dns_db_closeversion(db, &newver, commit);
19664 }
19665 if (db != NULL) {
19666 dns_db_detach(&db);
19667 }
19668 if (commit) {
19669 LOCK_ZONE(zone);
19670 resume_addnsec3chain(zone);
19671 UNLOCK_ZONE(zone);
19672 }
19673 dns_diff_clear(&diff);
19674 isc_event_free(&event);
19675
19676 INSIST(oldver == NULL);
19677 INSIST(newver == NULL);
19678 }
19679
19680 /*
19681 * Called when an "rndc signing -nsec3param ..." command is received.
19682 *
19683 * Allocate and prepare an nsec3param_t structure which holds information about
19684 * the NSEC3 changes requested for the zone:
19685 *
19686 * - if NSEC3 is to be disabled ("-nsec3param none"), only set the "nsec"
19687 * field of the structure to true and the "replace" field to the value
19688 * of the "replace" argument, leaving other fields initialized to zeros, to
19689 * signal that the zone should be signed using NSEC instead of NSEC3,
19690 *
19691 * - otherwise, prepare NSEC3PARAM RDATA that will eventually be inserted at
19692 * the zone apex, convert it to a private-type record and store the latter
19693 * in the "data" field of the nsec3param_t structure.
19694 *
19695 * Once the nsec3param_t structure is prepared, post an event to the zone's
19696 * task which will cause setnsec3param() to be called with the prepared
19697 * structure passed as an argument.
19698 */
19699 isc_result_t
19700 dns_zone_setnsec3param(dns_zone_t *zone, uint8_t hash, uint8_t flags,
19701 uint16_t iter, uint8_t saltlen,
19702 unsigned char *salt, bool replace)
19703 {
19704 isc_result_t result = ISC_R_SUCCESS;
19705 dns_rdata_nsec3param_t param;
19706 dns_rdata_t nrdata = DNS_RDATA_INIT;
19707 dns_rdata_t prdata = DNS_RDATA_INIT;
19708 unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
19709 struct np3event *npe;
19710 nsec3param_t *np;
19711 dns_zone_t *dummy = NULL;
19712 isc_buffer_t b;
19713 isc_event_t *e;
19714
19715 REQUIRE(DNS_ZONE_VALID(zone));
19716 REQUIRE(salt != NULL);
19717
19718 LOCK_ZONE(zone);
19719
19720 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM,
19721 setnsec3param, zone, sizeof(struct np3event));
19722 if (e == NULL) {
19723 result = ISC_R_NOMEMORY;
19724 goto failure;
19725 }
19726
19727 npe = (struct np3event *) e;
19728 np = &npe->params;
19729
19730 np->replace = replace;
19731 if (hash == 0) {
19732 np->length = 0;
19733 np->nsec = true;
19734 } else {
19735 param.common.rdclass = zone->rdclass;
19736 param.common.rdtype = dns_rdatatype_nsec3param;
19737 ISC_LINK_INIT(¶m.common, link);
19738 param.mctx = NULL;
19739 param.hash = hash;
19740 param.flags = flags;
19741 param.iterations = iter;
19742 param.salt_length = saltlen;
19743 param.salt = salt;
19744 isc_buffer_init(&b, nbuf, sizeof(nbuf));
19745 CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
19746 dns_rdatatype_nsec3param,
19747 ¶m, &b));
19748 dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype,
19749 np->data, sizeof(np->data));
19750 np->length = prdata.length;
19751 np->nsec = false;
19752 }
19753
19754 /*
19755 * setnsec3param() will silently return early if the zone does not yet
19756 * have a database. Prevent that by queueing the event up if zone->db
19757 * is NULL. All events queued here are subsequently processed by
19758 * receive_secure_db() if it ever gets called or simply freed by
19759 * zone_free() otherwise.
19760 */
19761 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
19762 if (zone->db != NULL) {
19763 zone_iattach(zone, &dummy);
19764 isc_task_send(zone->task, &e);
19765 } else {
19766 ISC_LIST_APPEND(zone->setnsec3param_queue, e, ev_link);
19767 e = NULL;
19768 }
19769 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
19770
19771 failure:
19772 if (e != NULL) {
19773 isc_event_free(&e);
19774 }
19775 UNLOCK_ZONE(zone);
19776 return (result);
19777 }
19778
19779 isc_result_t
19780 dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) {
19781 REQUIRE(DNS_ZONE_VALID(zone));
19782 REQUIRE(loadtime != NULL);
19783
19784 LOCK_ZONE(zone);
19785 *loadtime = zone->loadtime;
19786 UNLOCK_ZONE(zone);
19787 return (ISC_R_SUCCESS);
19788 }
19789
19790 isc_result_t
19791 dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) {
19792 REQUIRE(DNS_ZONE_VALID(zone));
19793 REQUIRE(expiretime != NULL);
19794
19795 LOCK_ZONE(zone);
19796 *expiretime = zone->expiretime;
19797 UNLOCK_ZONE(zone);
19798 return (ISC_R_SUCCESS);
19799 }
19800
19801 isc_result_t
19802 dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) {
19803 REQUIRE(DNS_ZONE_VALID(zone));
19804 REQUIRE(refreshtime != NULL);
19805
19806 LOCK_ZONE(zone);
19807 *refreshtime = zone->refreshtime;
19808 UNLOCK_ZONE(zone);
19809 return (ISC_R_SUCCESS);
19810 }
19811
19812 isc_result_t
19813 dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) {
19814 REQUIRE(DNS_ZONE_VALID(zone));
19815 REQUIRE(refreshkeytime != NULL);
19816
19817 LOCK_ZONE(zone);
19818 *refreshkeytime = zone->refreshkeytime;
19819 UNLOCK_ZONE(zone);
19820 return (ISC_R_SUCCESS);
19821 }
19822
19823 unsigned int
19824 dns_zone_getincludes(dns_zone_t *zone, char ***includesp) {
19825 dns_include_t *include;
19826 char **array = NULL;
19827 unsigned int n = 0;
19828
19829 REQUIRE(DNS_ZONE_VALID(zone));
19830 REQUIRE(includesp != NULL && *includesp == NULL);
19831
19832 LOCK_ZONE(zone);
19833 if (zone->nincludes == 0)
19834 goto done;
19835
19836 array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes);
19837 if (array == NULL)
19838 goto done;
19839 for (include = ISC_LIST_HEAD(zone->includes);
19840 include != NULL;
19841 include = ISC_LIST_NEXT(include, link)) {
19842 INSIST(n < zone->nincludes);
19843 array[n++] = isc_mem_strdup(zone->mctx, include->name);
19844 }
19845 INSIST(n == zone->nincludes);
19846 *includesp = array;
19847
19848 done:
19849 UNLOCK_ZONE(zone);
19850 return (n);
19851 }
19852
19853 void
19854 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
19855 REQUIRE(DNS_ZONE_VALID(zone));
19856
19857 zone->statlevel = level;
19858 }
19859
19860 dns_zonestat_level_t
19861 dns_zone_getstatlevel(dns_zone_t *zone) {
19862 REQUIRE(DNS_ZONE_VALID(zone));
19863
19864 return (zone->statlevel);
19865 }
19866
19867 static void
19868 setserial(isc_task_t *task, isc_event_t *event) {
19869 uint32_t oldserial, desired;
19870 const char *me = "setserial";
19871 bool commit = false;
19872 isc_result_t result;
19873 dns_dbversion_t *oldver = NULL, *newver = NULL;
19874 dns_zone_t *zone;
19875 dns_db_t *db = NULL;
19876 dns_diff_t diff;
19877 struct ssevent *sse = (struct ssevent *)event;
19878 dns_update_log_t log = { update_log_cb, NULL };
19879 dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
19880
19881 UNUSED(task);
19882
19883 zone = event->ev_arg;
19884 INSIST(DNS_ZONE_VALID(zone));
19885
19886 ENTER;
19887
19888 if (zone->update_disabled)
19889 goto failure;
19890
19891 desired = sse->serial;
19892
19893 dns_diff_init(zone->mctx, &diff);
19894
19895 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
19896 if (zone->db != NULL)
19897 dns_db_attach(zone->db, &db);
19898 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
19899 if (db == NULL)
19900 goto failure;
19901
19902 dns_db_currentversion(db, &oldver);
19903 result = dns_db_newversion(db, &newver);
19904 if (result != ISC_R_SUCCESS) {
19905 dns_zone_log(zone, ISC_LOG_ERROR,
19906 "setserial:dns_db_newversion -> %s",
19907 dns_result_totext(result));
19908 goto failure;
19909 }
19910
19911 CHECK(dns_db_createsoatuple(db, oldver, diff.mctx,
19912 DNS_DIFFOP_DEL, &oldtuple));
19913 CHECK(dns_difftuple_copy(oldtuple, &newtuple));
19914 newtuple->op = DNS_DIFFOP_ADD;
19915
19916 oldserial = dns_soa_getserial(&oldtuple->rdata);
19917 if (desired == 0U)
19918 desired = 1;
19919 if (!isc_serial_gt(desired, oldserial)) {
19920 if (desired != oldserial)
19921 dns_zone_log(zone, ISC_LOG_INFO,
19922 "setserial: desired serial (%u) "
19923 "out of range (%u-%u)", desired,
19924 oldserial + 1, (oldserial + 0x7fffffff));
19925 goto failure;
19926 }
19927
19928 dns_soa_setserial(desired, &newtuple->rdata);
19929 CHECK(do_one_tuple(&oldtuple, db, newver, &diff));
19930 CHECK(do_one_tuple(&newtuple, db, newver, &diff));
19931 result = dns_update_signatures(&log, zone, db,
19932 oldver, newver, &diff,
19933 zone->sigvalidityinterval);
19934 if (result != ISC_R_NOTFOUND)
19935 CHECK(result);
19936
19937 /* Write changes to journal file. */
19938 CHECK(zone_journal(zone, &diff, NULL, "setserial"));
19939 commit = true;
19940
19941 LOCK_ZONE(zone);
19942 zone_needdump(zone, 30);
19943 UNLOCK_ZONE(zone);
19944
19945 failure:
19946 if (oldtuple != NULL)
19947 dns_difftuple_free(&oldtuple);
19948 if (newtuple != NULL)
19949 dns_difftuple_free(&newtuple);
19950 if (oldver != NULL)
19951 dns_db_closeversion(db, &oldver, false);
19952 if (newver != NULL)
19953 dns_db_closeversion(db, &newver, commit);
19954 if (db != NULL)
19955 dns_db_detach(&db);
19956 dns_diff_clear(&diff);
19957 isc_event_free(&event);
19958 dns_zone_idetach(&zone);
19959
19960 INSIST(oldver == NULL);
19961 INSIST(newver == NULL);
19962 }
19963
19964 isc_result_t
19965 dns_zone_setserial(dns_zone_t *zone, uint32_t serial) {
19966 isc_result_t result = ISC_R_SUCCESS;
19967 dns_zone_t *dummy = NULL;
19968 isc_event_t *e = NULL;
19969 struct ssevent *sse;
19970
19971 REQUIRE(DNS_ZONE_VALID(zone));
19972
19973 LOCK_ZONE(zone);
19974
19975 if (!inline_secure(zone)) {
19976 if (!dns_zone_isdynamic(zone, true)) {
19977 result = DNS_R_NOTDYNAMIC;
19978 goto failure;
19979 }
19980 }
19981
19982 if (zone->update_disabled) {
19983 result = DNS_R_FROZEN;
19984 goto failure;
19985 }
19986
19987 e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETSERIAL,
19988 setserial, zone, sizeof(struct ssevent));
19989 if (e == NULL) {
19990 result = ISC_R_NOMEMORY;
19991 goto failure;
19992 }
19993
19994 sse = (struct ssevent *)e;
19995 sse->serial = serial;
19996
19997 zone_iattach(zone, &dummy);
19998 isc_task_send(zone->task, &e);
19999
20000 failure:
20001 if (e != NULL)
20002 isc_event_free(&e);
20003 UNLOCK_ZONE(zone);
20004 return (result);
20005 }
20006
20007 isc_stats_t *
20008 dns_zone_getgluecachestats(dns_zone_t *zone) {
20009 REQUIRE(DNS_ZONE_VALID(zone));
20010
20011 return (zone->gluecachestats);
20012 }
20013
20014 bool
20015 dns_zone_isloaded(const dns_zone_t *zone) {
20016 REQUIRE(DNS_ZONE_VALID(zone));
20017
20018 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED));
20019 }
20020
20021 isc_result_t
20022 dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver) {
20023 dns_dbversion_t *version = NULL;
20024 dns_keytable_t *secroots = NULL;
20025 isc_result_t result;
20026 dns_name_t *origin;
20027
20028 const char me[] = "dns_zone_verifydb";
20029 ENTER;
20030
20031 REQUIRE(DNS_ZONE_VALID(zone));
20032 REQUIRE(db != NULL);
20033
20034 if (dns_zone_gettype(zone) != dns_zone_mirror) {
20035 return (ISC_R_SUCCESS);
20036 }
20037
20038 if (ver == NULL) {
20039 dns_db_currentversion(db, &version);
20040 } else {
20041 version = ver;
20042 }
20043
20044 if (zone->view != NULL) {
20045 result = dns_view_getsecroots(zone->view, &secroots);
20046 if (result != ISC_R_SUCCESS) {
20047 goto done;
20048 }
20049 }
20050
20051 origin = dns_db_origin(db);
20052 result = dns_zoneverify_dnssec(zone, db, version, origin, secroots,
20053 zone->mctx, true, false);
20054
20055 done:
20056 if (secroots != NULL) {
20057 dns_keytable_detach(&secroots);
20058 }
20059
20060 if (ver == NULL) {
20061 dns_db_closeversion(db, &version, false);
20062 }
20063
20064 if (result != ISC_R_SUCCESS) {
20065 dnssec_log(zone, ISC_LOG_ERROR, "zone verification failed: %s",
20066 isc_result_totext(result));
20067 result = DNS_R_VERIFYFAILURE;
20068 }
20069
20070 return (result);
20071 }
20072